Skip to content

Design System: Molecule - Panel (responsive bottom sheet / dialog) #331

@DigiBanks99

Description

@DigiBanks99

Parent PRD

#320

What to build

Build the <mnl-panel> molecule — the most architecturally complex component in the design system. It's a responsive overlay that automatically adapts its presentation based on viewport:

Mobile (< lg): Bottom Sheet

  • Slides up from the bottom of the viewport
  • Has a drag handle at the top (visual affordance, optional drag-to-dismiss)
  • Backdrop overlay (semi-transparent)
  • Transitions: transform: translateY(100%)translateY(0) with duration-300 ease-out
  • Dismiss: tap backdrop, swipe down (optional), or explicit close button

Desktop (lg+): Centered Dialog

  • Fades in at center of viewport with subtle scale transition
  • Backdrop overlay
  • Transitions: opacity-0 scale-95opacity-100 scale-100 with duration-300
  • Dismiss: click backdrop, Escape key, or explicit close button
  • Max-width constrained (e.g., max-w-lg)

Shared API

  • Signal inputs: open (boolean), mode ('auto' | 'sheet' | 'dialog' — default 'auto' which uses viewport)
  • Output: closed (emits when panel is dismissed by any method)
  • Content projection: header slot ([mnlPanelHeader]) + body (default <ng-content>)
  • Traps focus when open (focus trap for accessibility)
  • Escape key closes the panel
  • aria-modal="true", role="dialog", aria-labelledby linked to header

Implementation approach

  • Uses matchMedia('(min-width: 1024px)') listener to determine mode when set to 'auto'
  • CSS transitions only — no Angular animations module
  • Focus trap via a lightweight directive or manual keydown handler
  • Body scroll lock when panel is open (prevent background scrolling)

Storybook: Stories under Molecules/Panel showing sheet mode, dialog mode, and auto mode at different viewports. Include a story with a form inside to demonstrate real usage.

Acceptance criteria

  • Panel renders as bottom sheet on mobile viewports (< 1024px)
  • Panel renders as centered dialog on desktop viewports (>= 1024px)
  • mode="sheet" forces bottom sheet regardless of viewport
  • mode="dialog" forces dialog regardless of viewport
  • Panel opens with smooth CSS transition
  • Backdrop click dismisses and emits closed
  • Escape key dismisses and emits closed
  • Focus is trapped within the panel when open
  • aria-modal="true" and role="dialog" present
  • Background scroll is locked when panel is open
  • Transitions respect prefers-reduced-motion
  • Works correctly in both light and dark mode
  • Unit tests: open/close state, escape key, backdrop click, focus trap, ARIA attributes
  • Storybook stories show both modes with form content

Blocked by

User stories addressed

  • User story 20: Responsive panel (sheet on mobile, dialog on desktop)
  • User story 30: Smooth transitions
  • User story 35: Budget forms in panel

Metadata

Metadata

Assignees

No one assigned

    Labels

    design-systemDesign system components and tokens

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions