Package Exports
- @accessible/drawer
- @accessible/drawer/package.json
Readme
<Drawer>
npm i @accessible/drawer
An accessible and versatile drawer component for React. This drawer is just a few new styles on top of @accessible/collapse so when using both, the drawer costs you nothing.
Features
- Style-agnostic You can use this component with the styling library of your choice. It
works with CSS-in-JS, SASS, plain CSS, plain
styleobjects, anything! - Portal-friendly The drawer target will render into React portals of your choice when configured to do so.
- a11y/aria-compliant This component works with screen readers out of the box and manages focus for you.
Quick Start
Check out the example on CodeSandbox
import {Drawer, Target, Trigger, Close} from '@accessible/drawer'
const Component = () => (
<Drawer>
<Target>
<div className="my-drawer">
<Close>
<button>Close me</button>
</Close>
</div>
</Target>
<Trigger>
<button>Open me</button>
</Trigger>
</Drawer>
)API
Components
| Component | Description |
|---|---|
<Drawer> |
This component creates the context for your drawer target and trigger and contains some configuration options. |
<Target> |
This component wraps any React element and turns it into a drawer target. |
<Trigger> |
This component wraps any React element and turns it into a drawer trigger. |
<Close> |
This is a convenience component that wraps any React element and adds an onClick handler to close the drawer. |
Hooks
| Hook | Description |
|---|---|
useDrawer() |
This hook provides the value of the drawer's DrawerContextValue object. |
useControls() |
This hook provides access to the drawer's open, close, and toggle functions. |
useIsOpen() |
This hook provides access to the drawer's isOpen value. |
<Drawer>
This component creates the context for your drawer target and trigger and contains some configuration options.
Props
| Prop | Type | Default | Required? | Description |
|---|---|---|---|---|
| defaultOpen | boolean |
false |
No | This sets the default open state of the drawer. By default the drawer is closed. |
| open | boolean |
undefined |
No | You can control the open/closed state of the drawer with this prop. When it isn't undefined, this value will take precedence over any calls to open(), close(), or toggle(). |
| onChange | (open: boolean) => void |
undefined |
No | This callback is invoked any time the open state of the disclosure changes. |
| id | string |
undefined |
No | By default this component creates a unique id for you, as it is required for certain aria attributes. Supplying an id here overrides the auto id feature. |
| children | React.ReactNode | React.ReactNode[] | JSX.Element | ((context: DrawerContextValue) => React.ReactNode) |
undefined |
No | Your drawer targets and any other children. |
<Target>
This component wraps any React element and turns it into a drawer target.
Props
| Prop | Type | Default | Required? | Description |
|---|---|---|---|---|
| placement | "top" | "right" | "bottom" | "left" |
"left" |
No | Sets the edge of the window you want your drawer target to render on. |
| portal | boolean | string |
false |
No | When true this will render the drawer into a React portal with the id #portals. You can render it into any portal by providing its query selector here, e.g. #foobar, [data-portal=true], or .foobar. |
| closeOnEscape | boolean |
true |
No | By default the drawer will close when the Escape key is pressed. You can turn this off by providing false here. |
| closedClass | string |
undefined |
No | This class name will be applied to the child element when the drawer is closed. |
| openClass | string |
undefined |
No | This class name will be applied to the child element when the drawer is open. |
| closedStyle | React.CSSProperties |
undefined |
No | These styles will be applied to the child element when the drawer is closed in addition to the default styles that set the target's visibility. |
| openStyle | React.CSSProperties |
undefined |
No | These styles name will be applied to the child element when the drawer is open in addition to the default styles that set the target's visibility. |
| preventScroll | boolean |
false |
No | When true this will prevent your browser from scrolling the document to bring the newly-focused tab into view. |
| children | React.ReactElement |
undefined |
Yes | The child is cloned by this component and has aria attributes injected into its props as well as the events defined above. |
Example
<Target>
<div className="alert">Alert</div>
</Target>
// <div
// class="alert"
// aria-hidden="true"
// id="collapse--12"
// style="visibility: hidden; position: fixed; margin: auto; left: 0px; right: 0px; top: 50%; transform: translateY(-50%); z-index: 1;"
// >
// Alert
// </div><Trigger>
This component wraps any React element and adds an onClick handler which toggles the open state
of the drawer target.
Props
| Prop | Type | Default | Required? | Description |
|---|---|---|---|---|
| closedClass | string |
undefined |
No | This class name will be applied to the child element when the drawer is closed. |
| openClass | string |
undefined |
No | This class name will be applied to the child element when the drawer is open. |
| closedStyle | React.CSSProperties |
undefined |
No | These styles will be applied to the child element when the drawer is closed. |
| openStyle | React.CSSProperties |
undefined |
No | These styles name will be applied to the child element when the drawer is open. |
| children | React.ReactElement |
undefined |
Yes | The child is cloned by this component and has aria attributes injected into its props as well as the events defined above. |
<Trigger on="click">
<button className="my-button">Open me!</button>
</Trigger>
// <button
// class="my-button"
// aria-controls="collapse--12"
// aria-expanded="false"
// >
// Open me!
// </button><Close>
This is a convenience component that wraps any React element and adds an onClick handler which closes the drawer.
Props
| Prop | Type | Default | Required? | Description |
|---|---|---|---|---|
| children | React.ReactElement |
undefined |
Yes | The child is cloned by this component and has aria attributes injected into its props as well as the events defined above. |
<Close>
<button className="my-button">Close me</button>
</Close>
// <button
// class="my-button"
// aria-controls="collapse--12"
// aria-expanded="false"
// >
// Close me
// </button>useDrawer()
This hook provides the value of the drawer's DrawerContextValue object
Example
const Component = () => {
const {open, close, toggle, isOpen} = useDrawer()
return <button onClick={toggle}>Toggle the drawer</button>
}DrawerContextValue
interface DrawerContextValue {
isOpen: boolean
open: () => void
close: () => void
toggle: () => void
id: string
}useControls()
This hook provides access to the drawer's open, close, and toggle functions
Example
const Component = () => {
const {open, close, toggle} = useControls()
return (
<Target>
<div className="my-drawer">
<button onClick={close}>Close me</button>
</div>
</Target>
)
}useIsOpen()
This hook provides access to the drawer's isOpen value
Example
const Component = () => {
const isOpen = useIsOpen()
return (
<Target>
<div className="my-drawer">Am I open? {isOpen ? 'Yes' : 'No'}</div>
</Target>
)
}LICENSE
MIT