Skip to content

Align drawer to architecture goals: expose side as required prop#197

Merged
lifeiscontent merged 2 commits into
mainfrom
align/drawer
Jun 24, 2026
Merged

Align drawer to architecture goals: expose side as required prop#197
lifeiscontent merged 2 commits into
mainfrom
align/drawer

Conversation

@lifeiscontent

Copy link
Copy Markdown
Collaborator

Closes #127

What the spec says

From the designer's review:

Always the same — backdrop overlay, focus trap, Escape key close, shadow/elevation on the leading edge, full viewport height, slide animation direction matching the anchor side, z-index stacking.

Depends (adjustable) — anchor side (left or right), width, title text, body content, footer actions, whether the close X button is shown, whether the backdrop dismisses.

What changed

The key adjustable axis that was missing was anchor side. The popup previously hardcoded right-edge positioning (inset-e-0, translate-x-full) with no way to get a left-edge drawer without reaching around the component.

Architecture changes

  • variants.tsdrawerPopupVariants gains a side cva variant ("start" | "end"). Side-specific classes (edge pinning, leading-edge border, slide animation direction) move into the variant; side-agnostic chrome (z-index, height, background, shadow, animation timing) stays in the base. No defaultVariants — callers are explicit.

    • end: inset-e-0, border-s-sm (left border = leading edge for a right drawer), data-starting-style:translate-x-full
    • start: inset-s-0, border-e-sm (right border = leading edge for a left drawer), data-starting-style:-translate-x-full
  • DrawerPopupside: DrawerPopupSide added as a required prop; passed to drawerPopupVariants({ side }).

  • DrawerPanel — inherits side via DrawerPopupProps and forwards it to DrawerPopup. No additional boilerplate needed.

  • index.tsx — exports DrawerPopupSide type for consumers who want to type their own wrappers.

  • Stories — existing stories updated to pass side="end" (equivalent to the previous hardcoded behaviour); a new StartSide story added to the components tier to show a left-anchored drawer.

Needs design approval before merge

Per repo convention, please tag @bhaveshraja for design sign-off before merging.

@github-actions

Copy link
Copy Markdown

📚 Storybook preview: https://pr-197-propel-storybook.vamsi-906.workers.dev

The DrawerPopup (and DrawerPanel) now accept a required `side` prop
("start" | "end") that drives both the viewport edge the panel pins to
and the direction of the slide animation.  Previously the popup hardcoded
right-edge positioning and translate-x-full for the enter/exit transform.

As per issue #127, anchor side is explicitly an adjustable axis; making it
a required cva variant (no defaultVariants) forces callers to be
intentional about which edge they want.

The leading-edge shadow border also follows side: `border-s-sm` for end
drawers (left border), `border-e-sm` for start drawers (right border).
All other chrome (backdrop, z-index, height, animation timing) stays baked
in as always-the-same values from the spec.

Stories updated to pass side="end" and a new StartSide story added to the
components tier to show a left-anchored drawer.
The drawer ui tier was missing the header/body/footer layout regions the
Figma spec lists as always-the-same structure, so both the ui and
components stories were hand-rolling them with raw <div className=...>
wrappers (a flex-col header group, an items-start/justify-between title
row, and a secondary-text body). That pushed layout styling into the
composition tiers, where no className should live.

Extract those regions into four new single-element ui parts, each with
its own cva in variants.ts:

- DrawerHeader: the top region, title/description block at the
  inline-start with a corner close at the inline-end on one baseline.
- DrawerHeaderContent: the stacked title + description inside the header.
- DrawerBody: the main content region that grows and scrolls.
- DrawerFooter: the footer actions region, actions at the inline-end.

Export them from the ui barrel, re-export from the components barrel, and
update both stories to compose the parts (registering them in
subcomponents) instead of inline className wrappers. The components tier
now carries no layout styling at all.
@lifeiscontent lifeiscontent merged commit 861e232 into main Jun 24, 2026
2 checks passed
@lifeiscontent lifeiscontent deleted the align/drawer branch June 24, 2026 10:42
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Drawer: what should always look the same, and what should be adjustable?

1 participant