🅰 An accessible and versatile drawer component for React
npm install @accessible/drawernpm i @accessible/drawer
An accessible and versatile drawer component for React
- [x] Style-agnostic You can use this component with the styling library of your choice. It
works with CSS-in-JS, SASS, plain CSS, plain style objects, anything!
- [x] Portal-friendly The drawer target will render into React portals of your choice when configured
to do so.
- [x] a11y/aria-compliant This component works with screen readers out of the box and manages
focus for you.
Check out the example on CodeSandbox
``jsx harmony
import * as React from 'react'
import * as Drawer from '@accessible/drawer'
const Component = () => (
I've been revealed!
)
`
| Component | Description |
| ------------------------------- | -------------------------------------------------------------------------------------------------------------- |
|
|
|
|
| Hook | Description |
| ----------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| useDrawer() | This hook provides the value of the drawer's DrawerContextValue object. |
| useA11yTarget() | A React hook for creating a headless drawer target to WAI-ARIA authoring practices. |
| useA11yTrigger() | A React hook for creating a headless drawer trigger to WAI-ARIA authoring practices. |
| useA11yCloseButton() | A React hook for creating a headless close button to WAI-ARIA authoring practices. |
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. |boolean
| open | | undefined | No | This creates a controlled drawer component where the open state of the drawer is controlled by this property. |(open: boolean) => void
| onChange | | undefined | No | This callback is invoked any time the open state of the drawer changes. |string
| id | | 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. |React.ReactNode
| children | | undefined | No | Your drawer contents and any other children. |
A React hook for creating a headless drawer target to WAI-ARIA authoring practices.
#### Arguments
| Argument | Type | Required? | Description |
| -------- | -------------------------------------------------- | --------- | --------------------------- |
| target | React.RefObject<T> \| T \| null | Yes | A React ref or HTML element |
| options | UseA11yTargetOptions | No | Configuration options |
#### UseA11yTargetOptions
`tswindow
export interface UseA11yTargetOptions {
/**
* Sets the placement of the drawer menu
* @default "left"
*/
placement?: 'top' | 'right' | 'bottom' | 'left'
/**
* Adds this class name to props when the drawer is open
*/
openClass?: string
/**
* Adds this class name to props when the drawer is closed
*/
closedClass?: string
/**
* Adds this style to props when the drawer is open
*/
openStyle?: React.CSSProperties
/**
* Adds this style to props when the drawer is closed
*/
closedStyle?: React.CSSProperties
/**
* Prevents the from scrolling when the target istrue
* focused after opening.
*/
preventScroll?: boolean
/**
* When , this closes the target element when the Escape`
* key is pressed.
* @default true
*/
closeOnEscape?: boolean
}
#### Returns
`ts`
type A11yProps = {
readonly 'aria-hidden': boolean
readonly id: string | undefined
readonly className: string | undefined
readonly style: {
readonly visibility: 'hidden' | 'visible'
} & React.CSSProperties
} & {
readonly style:
| ({
readonly visibility: 'hidden' | 'visible'
} & React.CSSProperties & {
readonly position: 'fixed'
readonly top: 0
readonly right: 0
readonly bottom: 'auto'
readonly left: 0
readonly transform: 'translate3d(0, -100%, 0)'
})
| ({
readonly visibility: 'hidden' | 'visible'
} & React.CSSProperties & {
readonly position: 'fixed'
readonly top: 0
readonly right: 0
readonly bottom: 0
readonly left: 'auto'
readonly transform: 'translate3d(100%, 0, 0)'
})
| ({
readonly visibility: 'hidden' | 'visible'
} & React.CSSProperties & {
readonly position: 'fixed'
readonly top: 'auto'
readonly right: 0
readonly bottom: 0
readonly left: 0
readonly transform: 'translate3d(0, 100%, 0)'
})
| ({
readonly visibility: 'hidden' | 'visible'
} & React.CSSProperties & {
readonly position: 'fixed'
readonly top: 0
readonly right: 'auto'
readonly bottom: 0
readonly left: 0
readonly transform: 'translate3d(-100%, 0, 0)'
})
}
#### Example
`jsx harmony
import * as React from 'react'
import {useA11yTarget} from '@accessible/drawer'
const MyTarget = () => {
const ref = React.useRef(null)
const a11yProps = useA11yTarget(ref, {preventScroll: true})
return (
$3
This component wraps any React element and turns it into a drawer target.
#### Props
| Prop | Type | Default | Required? | Description |
| ------------- | ---------------------------------------- | ----------- | --------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| placement |
"top" \| "right" \| "bottom" \| "left" | 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. |
| portal | boolean \| string \| PortalizeProps | 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
`jsx harmony
Alert
//
// class="alert"
// aria-hidden="true"
// id="🅰12"
// style="visibility: hidden;"
// >
// Alert
// $3
A React hook for creating a headless drawer trigger to WAI-ARIA authoring practices.
In addition to providing accessibility props to your component, this hook will add events
for interoperability between actual