<Disclosure>
npm i @accessible/disclosure
An accessible and versatile disclosure component for React
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
style
objects, anything! - Portal-friendly The disclosure 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 {Disclosure, Target, Trigger, Close} from '@accessible/disclosure'
const Component = () => (
<Disclosure>
<Trigger>
<button>Open me</button>
</Trigger>
<Target>
<div className="my-disclosure">
<Close>
<button>Close me</button>
</Close>
</div>
</Target>
</Disclosure>
)
API
Components
Component | Description |
---|
<Disclosure> | This component creates the context for your disclosure target and trigger and contains some configuration options. |
<Target> | This component wraps any React element and turns it into a disclosure target. |
<Trigger> | This component wraps any React element and turns it into a disclosure trigger. |
<Close> | This is a convenience component that wraps any React element and adds an onClick handler to close the disclosure. |
Hooks
<Disclosure>
This component creates the context for your disclosure 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 disclosure. By default the disclosure is closed. |
open | boolean | undefined | No | You can control the open/closed state of the disclosure 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: DisclosureContextValue) => React.ReactNode) | undefined | No | Your disclosure contents and any other children. |
<Target>
This component wraps any React element and turns it into a disclosure target.
Props
Prop | Type | Default | Required? | Description |
---|
portal | boolean | string | false | No | When true this will render the disclosure 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 disclosure 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 disclosure is closed . |
openClass | string | "disclosure--open" | No | This class name will be applied to the child element when the disclosure is open . |
closedStyle | React.CSSProperties | undefined | No | These styles will be applied to the child element when the disclosure 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 disclosure 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>
<Trigger>
This component wraps any React element and adds an onClick
handler which toggles the open state
of the disclosure target.
Props
Prop | Type | Default | Required? | Description |
---|
closedClass | string | undefined | No | This class name will be applied to the child element when the disclosure is closed . |
openClass | string | undefined | No | This class name will be applied to the child element when the disclosure is open . |
closedStyle | React.CSSProperties | undefined | No | These styles will be applied to the child element when the disclosure is closed . |
openStyle | React.CSSProperties | undefined | No | These styles name will be applied to the child element when the disclosure 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>
<Close>
This is a convenience component that wraps any React element and adds an onClick handler which closes the disclosure.
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>
useDisclosure()
This hook provides the value of the disclosure's DisclosureContextValue object
Example
const Component = () => {
const {open, close, toggle, isOpen} = useDisclosure()
return <button onClick={toggle}>Toggle the disclosure</button>
}
DisclosureContextValue
interface DisclosureContextValue {
isOpen: boolean
open: () => void
close: () => void
toggle: () => void
id: string
}
useControls()
This hook provides access to the disclosure's open
, close
, and toggle
functions
Example
const Component = () => {
const {open, close, toggle} = useControls()
return (
<Target>
<div className="my-disclosure">
<button onClick={close}>Close me</button>
</div>
</Target>
)
}
useIsOpen()
This hook provides access to the disclosure's isOpen
value
Example
const Component = () => {
const isOpen = useIsOpen()
return (
<Target>
<div className="my-disclosure">Am I open? {isOpen ? 'Yes' : 'No'}</div>
</Target>
)
}
LICENSE
MIT