Package: @accelint/design-toolkit@9.10.0 (Drawer / DrawerLayout)
Two related, sibling issues with the same component — filing together so they can be triaged in one place.
1. size prop is locked to three pixel values
Drawer.size is typed as 'small' | 'medium' | 'large', and styles.module.css hardcodes the three widths:
--drawer-size-small: 100px;
--drawer-size-medium: 200px;
--drawer-size-large: 400px;
Tablet-class consumers (~280–320px target) have no path. Today the only options are:
- CSS-module shadow override that targets
[data-component=drawer][data-size=...] selectors — couples to internal data-attribute naming, brittle.
patches/ entry per consumer — duplicates fixes across forks.
Asks (either is sufficient):
- Widen the
size prop type to accept number or a token reference (e.g. --spacing-…) alongside the three named variants.
- OR add
'tablet-medium' / 'tablet-large' to the variant set with corresponding CSS custom properties so consumers can theme them.
2. Closed-state panels still allocate their grid column
<DrawerLayout> uses grid-template-columns: auto 1fr auto to host left / main / right panels. Closed panels translate off-screen via transform: translateX(100%) (or equivalent for top/bottom/left). transform is paint-only — the grid column still allocates the panel's intrinsic content width.
Concrete impact: consumers using push='left right' see the main column visually shifted inward by ~400px (the closed large drawer's content width) even when no drawer is open. Visually this looks like "the layout treats the drawer as if it's always open."
Reproducer:
<DrawerLayout push='left right'> with a single right-side <Drawer size='large'> whose open is false.
- Place a footer or any content at the bottom of the main column.
- Observe the footer is offset inboard by ~400px when the drawer is closed.
Suggested fix (CSS sketch — not yet validated in storybook): add width: 0; overflow: hidden to the closed state, transition width with a delay equal to --animation-duration-slow so the column collapses after the slide-out animation finishes (otherwise close looks like a jarring shrink before slide):
.drawer {
@apply bg-surface-default text-body-m pointer-events-none relative flex flex-col;
@variant motion-safe {
transition:
transform var(--animation-duration-slow) var(--animation-easing-standard),
width 0ms linear var(--animation-duration-slow);
}
@variant open {
transition:
transform var(--animation-duration-slow) var(--animation-easing-standard),
width 0ms linear;
}
@variant placement-right {
@apply col-start-3 col-end-4 row-span-full;
transform: translateX(100%);
width: 0;
overflow: hidden;
@variant open {
transform: translateX(0);
width: auto;
overflow: visible;
}
}
}
Mirror the same pattern for placement-left (width: 0), placement-top / placement-bottom (height: 0).
Validation suggestions:
- Existing
Drawer.stories.tsx with an open/closed toggle: verify open → closed → open cycle has no flicker, no content overlap during transition frames, and that sibling content reclaims the column on close.
- Test all four placements.
- Test with
push='left right' consumer wiring — that's the configuration that surfaces the issue most clearly.
Happy to validate / PR either piece if useful — let me know which direction makes sense for the API.
Versions
- Next.js 16.1.6 (App Router)
- React 19.1.0 with
reactStrictMode: true
- Turbopack dev mode
- pnpm 10.9 hoisted node_modules
Package:
@accelint/design-toolkit@9.10.0(Drawer / DrawerLayout)Two related, sibling issues with the same component — filing together so they can be triaged in one place.
1.
sizeprop is locked to three pixel valuesDrawer.sizeis typed as'small' | 'medium' | 'large', andstyles.module.csshardcodes the three widths:Tablet-class consumers (~280–320px target) have no path. Today the only options are:
[data-component=drawer][data-size=...]selectors — couples to internal data-attribute naming, brittle.patches/entry per consumer — duplicates fixes across forks.Asks (either is sufficient):
sizeprop type to acceptnumberor a token reference (e.g.--spacing-…) alongside the three named variants.'tablet-medium'/'tablet-large'to the variant set with corresponding CSS custom properties so consumers can theme them.2. Closed-state panels still allocate their grid column
<DrawerLayout>usesgrid-template-columns: auto 1fr autoto host left / main / right panels. Closed panels translate off-screen viatransform: translateX(100%)(or equivalent for top/bottom/left).transformis paint-only — the grid column still allocates the panel's intrinsic content width.Concrete impact: consumers using
push='left right'see the main column visually shifted inward by ~400px (the closedlargedrawer's content width) even when no drawer is open. Visually this looks like "the layout treats the drawer as if it's always open."Reproducer:
<DrawerLayout push='left right'>with a single right-side<Drawer size='large'>whoseopenisfalse.Suggested fix (CSS sketch — not yet validated in storybook): add
width: 0; overflow: hiddento the closed state, transitionwidthwith a delay equal to--animation-duration-slowso the column collapses after the slide-out animation finishes (otherwise close looks like a jarring shrink before slide):Mirror the same pattern for
placement-left(width: 0),placement-top/placement-bottom(height: 0).Validation suggestions:
Drawer.stories.tsxwith an open/closed toggle: verify open → closed → open cycle has no flicker, no content overlap during transition frames, and that sibling content reclaims the column on close.push='left right'consumer wiring — that's the configuration that surfaces the issue most clearly.Happy to validate / PR either piece if useful — let me know which direction makes sense for the API.
Versions
reactStrictMode: true