Overlays
Drawer A panel that slides in from an edge of the viewport, used for navigation or supplementary content.
npm pnpm yarn bun
npm install @morphos/overlays pnpm add @morphos/overlays yarn add @morphos/overlays bun add @morphos/overlays
import {
Drawer,
DrawerTrigger,
DrawerContent,
DrawerTitle,
DrawerDescription,
DrawerClose,
} from '@morphos/overlays'
@ Component ()
class MyComponent extends StatefulComponent {
@ State () drawer = new Drawer ({ side: 'right' })
render () {
return (
<>
< DrawerTrigger drawer = { this .drawer}>
Open drawer
</ DrawerTrigger >
< DrawerContent drawer = { this .drawer} aria-labelledby = "drawer-title" >
< DrawerTitle id = "drawer-title" >Settings</ DrawerTitle >
< DrawerDescription >Adjust your preferences below.</ DrawerDescription >
< p >Drawer body content.</ p >
< DrawerClose drawer = { this .drawer}>Close</ DrawerClose >
</ DrawerContent >
</>
)
}
}
Component Description DrawerRoot state manager. Owns open state and the side the panel slides from. Exposes openDrawer() / closeDrawer() / toggle(). DrawerTrigger<button> that opens the drawer. Sets aria-haspopup="dialog", aria-expanded, and data-open.DrawerContentRenders into a Portal with a sibling backdrop <div data-morphos-backdrop>. Sets role="dialog", aria-modal="true", and data-side. Applies focus trap and scroll lock while open. DrawerTitleRenders as <h2> by default (configurable via as). DrawerDescriptionRenders as <p>. DrawerClose<button> that calls closeDrawer().
type DrawerSide = "top" | "right" | "bottom" | "left"
Controls which edge of the viewport DrawerContent slides in from, via the side prop on
Drawer. The current value is reflected on DrawerContent as data-side so it can drive
directional CSS animations.
Prop Type Default Description openboolean— Controlled open state. When set, the consumer owns the state. defaultOpenbooleanfalseInitial open state in uncontrolled mode. onOpenChange(open: boolean) => void— Called when the open state changes. closeOnEscapebooleantrueWhether pressing Escape closes the drawer. closeOnBackdropClickbooleantrueWhether clicking the backdrop closes the drawer. sideDrawerSide"right"Which edge of the viewport the drawer slides from. childrenChildren— Content — typically DrawerTrigger and DrawerContent.
Method Description openDrawer()Opens the drawer. Emits onOpenChange(true). closeDrawer()Closes the drawer. Emits onOpenChange(false). toggle()Toggles the open state. Emits onOpenChange.
Prop Type Default Description drawerDrawer— The Drawer instance this trigger controls. childrenChildren— The trigger element content. classstring— CSS class. idstring— HTML id.
Prop Type Default Description drawerDrawer— The Drawer instance this content belongs to. childrenChildren— Drawer body content. classstring— CSS class. idstring— HTML id. Falls back to an auto-generated id. aria-labelstring— Accessible label for the drawer. aria-labelledbystring— ID of the element that labels the drawer (e.g. a DrawerTitle). aria-describedbystring— ID of the element that describes the drawer (e.g. a DrawerDescription).
Prop Type Default Description as"h1" | "h2" | "h3" | "h4" | "h5" | "h6""h2"The HTML heading element to render. childrenChildren— Title text. classstring— CSS class. idstring— HTML id.
Prop Type Default Description childrenChildren— Description text. classstring— CSS class. idstring— HTML id.
Prop Type Default Description drawerDrawer— The Drawer instance this close button controls. childrenChildren— Button content. classstring— CSS class. idstring— HTML id.
Attribute Element When present data-openDrawerTriggerDrawer is open data-openDrawerContent rootDrawer is open data-sideDrawerContent rootAlways — reflects the side prop value ("top", "right", "bottom", or "left")
Use the data-side attribute on DrawerContent to apply directional slide-in animations via
CSS. For example, [data-side="right"] slides in from the right.
DrawerContent calls trapFocus() and lockScroll() from @morphos/core while open, the
same way Dialog does.
.morphos-drawer-content {
position : fixed ;
display : flex ;
flex-direction : column ;
padding : var ( --morphos-space-4 );
}
.morphos-drawer-content [ data-side = "right" ] {
top : 0 ;
right : 0 ;
bottom : 0 ;
width : min ( 24 rem , 100 vw );
animation : morphos-slide-in-right var ( --morphos-transition-medium );
}
@keyframes morphos-slide-in-right {
from { transform : translateX ( 100 % ); }
to { transform : translateX ( 0 ); }
}