Skip to content
Merged
Show file tree
Hide file tree
Changes from 28 commits
Commits
Show all changes
29 commits
Select commit Hold shift + click to select a range
b275d8a
feat(web): add opt-in panel animations
maria-rcks Aug 30, 2026
3042663
fix(web): retain panels through exit animations
maria-rcks Aug 31, 2026
7842dff
fix(web): stabilize animated panels
maria-rcks Aug 31, 2026
08947f8
fix(web): keep panel resizing responsive
maria-rcks Aug 31, 2026
3db5612
fix(web): preserve sheet titlebar ownership
maria-rcks Aug 31, 2026
2666045
fix(web): restore controls during sheet exit
maria-rcks Aug 31, 2026
6f06e10
feat(web): add panel animation speed control
maria-rcks Aug 31, 2026
b1ce462
fix(web): clip animated panel contents
maria-rcks Aug 31, 2026
d16afce
fix(web): apply sidebar animation duration locally
maria-rcks Aug 31, 2026
db55dc5
fix(web): animate maximized panel close
maria-rcks Aug 31, 2026
5f9aa9a
fix(web): retain panel terminal shortcut target
maria-rcks Aug 31, 2026
6e2acb0
fix(web): retain right panel exit state
maria-rcks Aug 31, 2026
156b441
fix(web): skip transitions for panel clamps
maria-rcks Aug 31, 2026
b729de2
fix(web): hold panel clamp through paint
maria-rcks Aug 31, 2026
6e287e0
fix(web): synchronize panel header reserve
maria-rcks Aug 31, 2026
7d7896f
fix(web): cancel collapsed header gap
maria-rcks Aug 31, 2026
1af18dd
fix(web): preserve mobile drawer motion
maria-rcks Aug 31, 2026
8200766
feat(web): unify panel motion duration
maria-rcks Sep 1, 2026
dd63525
fix(web): preserve panel interaction semantics
maria-rcks Sep 1, 2026
1218d22
chore: resolve main conflicts
maria-rcks Sep 2, 2026
bd3041d
fix(web): preserve native controls during panel motion
maria-rcks Sep 2, 2026
8728a87
fix(web): refine panel motion settings layout
maria-rcks Sep 2, 2026
4b53946
fix(web): compact panel motion settings row
maria-rcks Sep 2, 2026
af9b69a
fix(web): wait for panel settings hydration
maria-rcks Sep 2, 2026
5ace05d
fix(web): restore disabled slider styling
maria-rcks Sep 2, 2026
2e99c2d
fix(web): compact panel animation setting
maria-rcks Sep 2, 2026
c3c5b7f
fix(web): smooth responsive panel motion
maria-rcks Sep 2, 2026
b43b45b
fix(web): harden responsive panel controls
maria-rcks Sep 2, 2026
68a55c6
refactor(web): simplify panel animations
maria-rcks Sep 2, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions apps/desktop/src/settings/DesktopClientSettings.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ const clientSettings: ClientSettings = {
fontSizeTerminal: 12,
fontSmoothing: true,
glassOpacity: 80,
panelAnimationDurationMs: 0,
planModeEnabled: false,
showSkillsInSlashMenu: false,
providerModelPreferences: {},
Expand Down
13 changes: 12 additions & 1 deletion apps/web/src/components/AppSidebarLayout.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ import { resolveShortcutCommand, shortcutLabelForCommand } from "../keybindings"
import { cn, isMacPlatform } from "../lib/utils";
import { primaryServerKeybindingsAtom } from "../state/server";
import { useEnvironmentIdentificationMode, useLegacySidebarEnabled } from "../hooks/useSettings";
import { usePanelAnimationSettings } from "../panelAnimations";
import LegacyThreadSidebar from "./LegacySidebar";
import ThreadSidebar from "./Sidebar";
import { SidebarChromeHeader } from "./sidebar/SidebarChrome";
Expand Down Expand Up @@ -148,6 +149,8 @@ function ProjectProjectionRetention() {
export function AppSidebarLayout({ children }: { children: ReactNode }) {
const navigate = useNavigate();
const legacySidebarEnabled = useLegacySidebarEnabled();
const { active: panelAnimationsActive, durationMs: panelAnimationDurationMs } =
usePanelAnimationSettings();
// Settings routes show the settings nav in place of whichever thread
// sidebar is active.
const pathname = useLocation({ select: (location) => location.pathname });
Expand Down Expand Up @@ -175,6 +178,7 @@ export function AppSidebarLayout({ children }: { children: ReactNode }) {
});
const sidebarProviderStyle = {
"--sidebar-width": `${sidebarWidth}px`,
"--panel-animation-duration": `${panelAnimationDurationMs}ms`,
...(isMacosDesktop && !isWindowFullscreen
? { "--workspace-controls-left": MACOS_TRAFFIC_LIGHTS_LEFT_INSET }
: {}),
Expand Down Expand Up @@ -218,9 +222,16 @@ export function AppSidebarLayout({ children }: { children: ReactNode }) {
}, [navigate, pathname]);

return (
<SidebarProvider className="h-dvh! min-h-0!" defaultOpen style={sidebarProviderStyle}>
<SidebarProvider
className="h-dvh! min-h-0!"
data-panel-animations={panelAnimationsActive ? "true" : "false"}
defaultOpen
style={sidebarProviderStyle}
>
<ProjectProjectionRetention />
<Sidebar
animated={panelAnimationsActive}
animationDurationMs={panelAnimationDurationMs}
side="left"
collapsible="offcanvas"
data-app-sidebar=""
Expand Down
242 changes: 166 additions & 76 deletions apps/web/src/components/ChatView.tsx

Large diffs are not rendered by default.

6 changes: 3 additions & 3 deletions apps/web/src/components/GitActionsControl.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -1719,7 +1719,7 @@ export default function GitActionsControl({
quickAction={quickAction}
SourceControlIcon={SourceControlIcon}
/>
<span className="sr-only @3xl/header-actions:not-sr-only @3xl/header-actions:ml-0.5">
<span className="sr-only @min-[48rem]/header-actions:not-sr-only @min-[48rem]/header-actions:ml-0.5">
{quickAction.label}
</span>
</PopoverTrigger>
Expand All @@ -1736,12 +1736,12 @@ export default function GitActionsControl({
onClick={runQuickAction}
>
<GitQuickActionIcon quickAction={quickAction} SourceControlIcon={SourceControlIcon} />
<span className="sr-only @3xl/header-actions:not-sr-only @3xl/header-actions:ml-0.5">
<span className="sr-only @min-[48rem]/header-actions:not-sr-only @min-[48rem]/header-actions:ml-0.5">
{quickAction.label}
</span>
</Button>
)}
<GroupSeparator className="hidden @3xl/header-actions:block" />
<GroupSeparator className="hidden @min-[48rem]/header-actions:block" />
<Menu
onOpenChange={(open) => {
if (open) {
Expand Down
8 changes: 4 additions & 4 deletions apps/web/src/components/ProjectScriptsControl.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -40,8 +40,8 @@ function expectResponsiveXsControl(markup: string | undefined) {
expect(markup).toContain("w-7");
expect(markup).toContain("px-0");
expect(markup).toContain("sm:w-6");
expect(markup).toContain("@3xl/header-actions:w-auto!");
expect(markup).toContain("@3xl/header-actions:px-[calc(--spacing(2)-1px)]");
expect(markup).toContain("@min-[48rem]/header-actions:w-auto!");
expect(markup).toContain("@min-[48rem]/header-actions:px-[calc(--spacing(2)-1px)]");
}

describe("ProjectScriptsControl compact controls", () => {
Expand All @@ -50,7 +50,7 @@ describe("ProjectScriptsControl compact controls", () => {

expectResponsiveXsControl(buttonTag(html, "Run Dev"));
expect(html).toContain(
'class="sr-only @3xl/header-actions:not-sr-only @3xl/header-actions:ml-0.5"',
'class="sr-only @min-[48rem]/header-actions:not-sr-only @min-[48rem]/header-actions:ml-0.5"',
);
});

Expand All @@ -59,7 +59,7 @@ describe("ProjectScriptsControl compact controls", () => {

expectResponsiveXsControl(buttonTag(html, "Add action"));
expect(html).toContain(
'class="sr-only @3xl/header-actions:not-sr-only @3xl/header-actions:ml-0.5"',
'class="sr-only @min-[48rem]/header-actions:not-sr-only @min-[48rem]/header-actions:ml-0.5"',
);
});
});
12 changes: 6 additions & 6 deletions apps/web/src/components/ProjectScriptsControl.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -162,7 +162,7 @@ export default function ProjectScriptsControl({
<Button
size="xs"
variant="outline"
className="w-7 px-0 sm:w-6 @3xl/header-actions:w-auto! @3xl/header-actions:px-[calc(--spacing(2)-1px)]"
className="w-7 px-0 sm:w-6 @min-[48rem]/header-actions:w-auto! @min-[48rem]/header-actions:px-[calc(--spacing(2)-1px)]"
aria-label={`Run ${primaryScript.name}`}
// The tooltip wrapper replaces data-slot="button", so themed
// toolbar styling needs its own hook.
Expand All @@ -172,13 +172,13 @@ export default function ProjectScriptsControl({
}
>
<ScriptIcon icon={primaryScript.icon} />
<span className="sr-only @3xl/header-actions:not-sr-only @3xl/header-actions:ml-0.5">
<span className="sr-only @min-[48rem]/header-actions:not-sr-only @min-[48rem]/header-actions:ml-0.5">
{primaryScript.name}
</span>
</TooltipTrigger>
<TooltipPopup side="top">Run {primaryScript.name}</TooltipPopup>
</Tooltip>
<GroupSeparator className="hidden @3xl/header-actions:block" />
<GroupSeparator className="hidden @min-[48rem]/header-actions:block" />
<Menu
highlightItemOnHover={false}
open={actionsMenuOpen.scripts}
Expand Down Expand Up @@ -249,7 +249,7 @@ export default function ProjectScriptsControl({
>
<MenuTrigger render={<Button size="xs" variant="outline" aria-label="Project actions" />}>
<PlusIcon className="size-3.5" />
<span className="sr-only @3xl/header-actions:not-sr-only @3xl/header-actions:ml-0.5">
<span className="sr-only @min-[48rem]/header-actions:not-sr-only @min-[48rem]/header-actions:ml-0.5">
Add action
</span>
<ChevronDownIcon className="size-3.5" />
Expand All @@ -269,7 +269,7 @@ export default function ProjectScriptsControl({
<Button
size="xs"
variant="outline"
className="w-7 px-0 sm:w-6 @3xl/header-actions:w-auto! @3xl/header-actions:px-[calc(--spacing(2)-1px)]"
className="w-7 px-0 sm:w-6 @min-[48rem]/header-actions:w-auto! @min-[48rem]/header-actions:px-[calc(--spacing(2)-1px)]"
aria-label="Add action"
// The tooltip wrapper replaces data-slot="button", so themed
// toolbar styling needs its own hook.
Expand All @@ -279,7 +279,7 @@ export default function ProjectScriptsControl({
}
>
<PlusIcon className="size-3.5" />
<span className="sr-only @3xl/header-actions:not-sr-only @3xl/header-actions:ml-0.5">
<span className="sr-only @min-[48rem]/header-actions:not-sr-only @min-[48rem]/header-actions:ml-0.5">
Add action
</span>
</TooltipTrigger>
Expand Down
4 changes: 4 additions & 0 deletions apps/web/src/components/RightPanelSheet.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@ import { RIGHT_PANEL_SHEET_CLASS_NAME } from "../rightPanelLayout";
import { Sheet, SheetPopup } from "./ui/sheet";

export function RightPanelSheet(props: {
animated: boolean;
animationDurationMs: number;
children: ReactNode;
open: boolean;
onClose: () => void;
Expand All @@ -18,6 +20,8 @@ export function RightPanelSheet(props: {
}}
>
<SheetPopup
animated={props.animated}
transitionDurationMs={props.animationDurationMs}
side="right"
showCloseButton={false}
keepMounted
Expand Down
8 changes: 8 additions & 0 deletions apps/web/src/components/RightPanelTabs.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,9 @@ import { PierreEntryIcon } from "./chat/PierreEntryIcon";
interface RightPanelTabsProps {
mode: PreviewPanelMode;
maximized?: boolean;
animated?: boolean;
animationDurationMs?: number;
open?: boolean;
/** Forwarded to PreviewPanelShell so this surface persists its own width. */
widthStorageKey?: string;
/** Forwarded to PreviewPanelShell as the initial width before a user resize. */
Expand Down Expand Up @@ -775,6 +778,11 @@ export function RightPanelTabs(props: RightPanelTabsProps) {
<PreviewPanelShell
mode={props.mode}
{...(props.maximized !== undefined ? { maximized: props.maximized } : {})}
{...(props.animated !== undefined ? { animated: props.animated } : {})}
{...(props.animationDurationMs !== undefined
? { animationDurationMs: props.animationDurationMs }
: {})}
{...(props.open !== undefined ? { open: props.open } : {})}
{...(props.widthStorageKey !== undefined ? { widthStorageKey: props.widthStorageKey } : {})}
{...(props.defaultWidth !== undefined ? { defaultWidth: props.defaultWidth } : {})}
>
Expand Down
2 changes: 1 addition & 1 deletion apps/web/src/components/WorkspacePageHeader.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ export function WorkspacePageHeader({
return (
<header
className={cn(
"flex h-[var(--workspace-topbar-height)] min-h-[var(--workspace-topbar-height)] shrink-0 items-center gap-3 pl-[calc(env(safe-area-inset-left)+0.75rem)] pr-[calc(env(safe-area-inset-right)+0.75rem)] transition-[padding-left] duration-200 ease-linear motion-reduce:transition-none sm:pl-[calc(env(safe-area-inset-left)+1.25rem)] sm:pr-[calc(env(safe-area-inset-right)+1.25rem)]",
"flex h-[var(--workspace-topbar-height)] min-h-[var(--workspace-topbar-height)] shrink-0 items-center gap-3 pl-[calc(env(safe-area-inset-left)+0.75rem)] pr-[calc(env(safe-area-inset-right)+0.75rem)] [[data-panel-animations=true]_&]:motion-safe:transition-[padding-left,padding-right] [[data-panel-animations=true]_&]:motion-safe:[transition-duration:var(--panel-animation-duration)] [[data-panel-animations=true]_&]:motion-safe:ease-out sm:pl-[calc(env(safe-area-inset-left)+1.25rem)] sm:pr-[calc(env(safe-area-inset-right)+1.25rem)]",
electron && "drag-region",
reserveNativeControls && "wco:pr-[var(--workspace-native-controls-inset)]",
COLLAPSED_SIDEBAR_TITLEBAR_INSET_CLASS,
Expand Down
38 changes: 36 additions & 2 deletions apps/web/src/components/chat/ChatComposer.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -135,9 +135,12 @@ import { ComposerPendingElementContexts } from "./ComposerPendingElementContexts
import { ComposerPendingReviewComments } from "./ComposerPendingReviewComments";
import { ComposerPreviewAnnotationCards } from "./ComposerPreviewAnnotationCards";
import {
COMPOSER_FOOTER_COMPACT_BREAKPOINT_PX,
COMPOSER_FOOTER_WIDE_ACTIONS_COMPACT_BREAKPOINT_PX,
shouldUseCompactComposerPrimaryActions,
shouldUseCompactComposerFooter,
} from "../composerFooterLayout";
import { observeResponsiveBreakpointFade, usePanelAnimationSettings } from "../../panelAnimations";
import { type ComposerPromptEditorHandle, ComposerPromptEditor } from "../ComposerPromptEditor";
import { ProviderModelPicker } from "./ProviderModelPicker";
import { type ComposerCommandItem, ComposerCommandMenu } from "./ComposerCommandMenu";
Expand Down Expand Up @@ -1227,6 +1230,8 @@ export const ChatComposer = memo(function ChatComposer(props: ChatComposerProps)
active: false,
});
const isMobileViewport = useMediaQuery("max-sm");
const { active: panelAnimationsActive, durationMs: panelAnimationDurationMs } =
usePanelAnimationSettings();
const isComposerCollapsedMobile =
isMobileViewport && !forceExpandedOnMobile && !isComposerFocused;

Expand All @@ -1236,6 +1241,7 @@ export const ChatComposer = memo(function ChatComposer(props: ChatComposerProps)
const composerEditorRef = useRef<ComposerPromptEditorHandle>(null);
const attachmentInputRef = useRef<HTMLInputElement>(null);
const composerFormRef = useRef<HTMLFormElement>(null);
const composerFooterControlsRef = useRef<HTMLDivElement>(null);
const composerSurfaceRef = useRef<HTMLDivElement>(null);
const providerInputRejectedRef = useRef(false);
const composerSelectLockRef = useRef(false);
Expand Down Expand Up @@ -1773,6 +1779,21 @@ export const ChatComposer = memo(function ChatComposer(props: ChatComposerProps)
setIsComposerPrimaryActionsCompact(initialCompactness.primaryActionsCompact);
setIsComposerFooterCompact(initialCompactness.footerCompact);
if (typeof ResizeObserver === "undefined") return;
const footerControls = composerFooterControlsRef.current;
const stopFooterControlsFade = footerControls
? observeResponsiveBreakpointFade({
target: footerControls,
container: composerForm,
active: panelAnimationsActive,
durationMs: panelAnimationDurationMs,
breakpoint: {
value: composerFooterHasWideActions
? COMPOSER_FOOTER_WIDE_ACTIONS_COMPACT_BREAKPOINT_PX
: COMPOSER_FOOTER_COMPACT_BREAKPOINT_PX,
unit: "px",
},
})
: undefined;
Comment thread
macroscopeapp[bot] marked this conversation as resolved.

const observer = new ResizeObserver(() => {
const nextCompactness = measureFooterCompactness();
Expand All @@ -1789,8 +1810,17 @@ export const ChatComposer = memo(function ChatComposer(props: ChatComposerProps)
observer.observe(composerForm);
return () => {
observer.disconnect();
stopFooterControlsFade?.();
Comment thread
cursor[bot] marked this conversation as resolved.
};
}, [activeThreadId, composerFooterActionLayoutKey, composerFooterHasWideActions]);
}, [
activeThreadId,
composerFooterActionLayoutKey,
composerFooterHasWideActions,
isComposerApprovalState,
isComposerCollapsedMobile,
panelAnimationDurationMs,
panelAnimationsActive,
]);

// ------------------------------------------------------------------
// Image persist effect
Expand Down Expand Up @@ -4167,7 +4197,11 @@ export const ChatComposer = memo(function ChatComposer(props: ChatComposerProps)
showMobilePendingAnswerActions && "hidden sm:flex",
)}
>
<div className="-m-1 -ms-3.5 flex min-w-0 flex-1 items-center gap-1 overflow-x-auto p-1 ps-3.5 [scrollbar-width:none] [&::-webkit-scrollbar]:hidden">
<div
ref={composerFooterControlsRef}
data-chat-composer-footer-controls="true"
className="-m-1 -ms-3.5 flex min-w-0 flex-1 items-center gap-1 overflow-x-auto p-1 ps-3.5 [scrollbar-width:none] [&::-webkit-scrollbar]:hidden"
>
{noProviderAvailable ? (
<Button
type="button"
Expand Down
22 changes: 21 additions & 1 deletion apps/web/src/components/chat/ChatHeader.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ import { useT3ProjectFileScripts } from "~/hooks/useT3ProjectFileScripts";
import { useThreadActionMenu } from "~/hooks/useThreadActionMenu";
import { threadEnvironment } from "../../state/threads";
import { useAtomCommand } from "../../state/use-atom-command";
import { observeResponsiveBreakpointFade, usePanelAnimationSettings } from "../../panelAnimations";
import { ProjectFavicon } from "../ProjectFavicon";
import {
WorkspaceBreadcrumb,
Expand Down Expand Up @@ -94,6 +95,8 @@ export function resolveRenameCommit(input: {
// events (the second click dismisses it and dblclick still fires), so it
// opens immediately.
const TITLE_MENU_OPEN_DELAY_MS = 500;
// Matches the explicit @min-[48rem]/header-actions variants owned by this header.
const HEADER_ACTIONS_EXPANDED_BREAKPOINT_REM = 48;

export function shouldShowOpenInPicker(input: {
readonly activeProjectName: string | undefined;
Expand Down Expand Up @@ -137,6 +140,21 @@ export const ChatHeader = memo(function ChatHeader({
onUpdateProjectScript,
onDeleteProjectScript,
}: ChatHeaderProps) {
const { active: panelAnimationsActive, durationMs: panelAnimationDurationMs } =
usePanelAnimationSettings();
const headerActionsRef = useRef<HTMLDivElement | null>(null);
useEffect(() => {
const actions = headerActionsRef.current;
const container = actions?.parentElement;
if (!actions || !container) return;
return observeResponsiveBreakpointFade({
target: actions,
container,
active: panelAnimationsActive,
durationMs: panelAnimationDurationMs,
breakpoint: { value: HEADER_ACTIONS_EXPANDED_BREAKPOINT_REM, unit: "rem" },
});
}, [panelAnimationDurationMs, panelAnimationsActive]);
const primaryEnvironmentId = usePrimaryEnvironmentId();
const fileScripts = useT3ProjectFileScripts(
activeThreadEnvironmentId,
Expand Down Expand Up @@ -372,10 +390,12 @@ export const ChatHeader = memo(function ChatHeader({
</WorkspaceBreadcrumbItem>
</WorkspaceBreadcrumb>
<div
ref={headerActionsRef}
data-chat-header-actions
className={cn(
"flex shrink-0 items-center justify-end gap-2 @3xl/header-actions:gap-3",
"flex shrink-0 items-center justify-end gap-2 @min-[48rem]/header-actions:gap-3",
rightPanelOpen ? "pr-0" : "pr-16",
"[[data-panel-animations=true]_&]:motion-safe:transition-[padding-right] [[data-panel-animations=true]_&]:motion-safe:[transition-duration:var(--panel-animation-duration)] [[data-panel-animations=true]_&]:motion-safe:ease-out",
)}
>
{activeProjectScripts && (
Expand Down
6 changes: 4 additions & 2 deletions apps/web/src/components/chat/OpenInPicker.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -285,13 +285,15 @@ export const OpenInPicker = memo(function OpenInPicker({
className={
compact
? "sr-only"
: "sr-only @3xl/header-actions:not-sr-only @3xl/header-actions:ml-0.5"
: "sr-only @min-[48rem]/header-actions:not-sr-only @min-[48rem]/header-actions:ml-0.5"
}
>
Open
</span>
</Button>
<GroupSeparator {...(!compact ? { className: "hidden @3xl/header-actions:block" } : {})} />
<GroupSeparator
{...(!compact ? { className: "hidden @min-[48rem]/header-actions:block" } : {})}
/>
<Menu>
<MenuTrigger
render={
Expand Down
20 changes: 19 additions & 1 deletion apps/web/src/components/preview/PreviewPanelShell.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,11 @@ import { jsx } from "react/jsx-runtime";
import { renderToStaticMarkup } from "react-dom/server";
import { describe, expect, it } from "vite-plus/test";

import { getPreviewPanelMaxWidth, PreviewPanelShell } from "./PreviewPanelShell";
import {
getPreviewPanelMaxWidth,
PreviewPanelShell,
shouldSuppressPanelWidthTransition,
} from "./PreviewPanelShell";

describe("getPreviewPanelMaxWidth", () => {
it("allows the panel to use 70% of an ultra-wide viewport without a pixel ceiling", () => {
Expand Down Expand Up @@ -47,3 +51,17 @@ describe("getPreviewPanelMaxWidth", () => {
expect(getPreviewPanelMaxWidth(1_512, 300)).toBe(360);
});
});

describe("shouldSuppressPanelWidthTransition", () => {
it("suppresses clamp and resize changes while visibility is stable", () => {
expect(
shouldSuppressPanelWidthTransition({ open: true, width: 540 }, { open: true, width: 480 }),
).toBe(true);
});

it("keeps transitions for visibility changes", () => {
expect(
shouldSuppressPanelWidthTransition({ open: true, width: 540 }, { open: false, width: 540 }),
).toBe(false);
});
});
Loading
Loading