Disclosure Primitive
An accessible disclosure primitive for controlling the visibility of a content section.
function BasicExample() {const disclosure = useDisclosurePrimitiveState({ visible: true });return (<><DisclosurePrimitive {...disclosure}>Toggle</DisclosurePrimitive><DisclosurePrimitiveContent {...disclosure}>Content</DisclosurePrimitiveContent></>);}
The Disclosure primitive is an unstyled, functional version of a Disclosure. It can be used to build a component following the WAI-ARIA Disclosure pattern. Our Disclosure component is built on top of this primitive.
These unstyled primitives are to be used when the styled Disclosure provided by Paste doesn’t meet the requirements needed to solve a unique customer problem. At that point, you are welcome to fallback to this functional primitive to roll your own styled disclosure while still providing a functional and accessible experience to your customers.
This primitive should be used to compose all custom Disclosures to ensure accessibility and upgrade paths.
Warning
We strongly suggest that all components built on top of this primitive get reviewed by the Design Systems team and goes through the UX Review process to ensure an excellent experience for our customers.
This package is a wrapper around Reakit's Disclosure. If you’re wondering why we wrapped that package into our own, we reasoned that it would be best for our consumers’ developer experience. For example:
- We can control which APIs we expose and how to expose them. For example, in this package we rename and export only some of the source package's exports.
- If we want to migrate the underlying nuts and bolts in the future, Twilio products that
depend on this primitive would need to replace all occurrences of
import … from ‘@reach/dialog’
toimport … from ‘@some-new/package’
. By wrapping it in@twilio-paste/disclosure-primitive
, this refactor can be avoided. The only change would be a version bump in the package.json file. - We can more strictly enforce semver and backwards compatibility than some of our dependencies.
- We can control when to provide an update and which versions we allow, to help reduce potential bugs our consumers may face.
This package is available individually or as part of @twilio-paste/core
.
yarn add @twilio-paste/disclosure-primitive - or - yarn add @twilio-paste/core
function BasicExample() {const disclosure = useDisclosurePrimitiveState({ visible: true });return (<><DisclosurePrimitive {...disclosure}>Toggle</DisclosurePrimitive><DisclosurePrimitiveContent {...disclosure}>Content</DisclosurePrimitiveContent></>);}
You shouldn't conditionally render the DisclosurePrimitiveContent component as this will make some Reakit features not work. Instead, you can use render props and conditionally render the underneath element:
function ConditionallyRenderingExample() {const disclosure = useDisclosurePrimitiveState();return (<><DisclosurePrimitive {...disclosure}>Toggle</DisclosurePrimitive>{/* instead of {disclosure.visible && <DisclosureContent {...disclosure}>Content</DisclosureContent>} */}<DisclosurePrimitiveContent {...disclosure}>{props => disclosure.visible && <div {...props}>Content</div>}</DisclosurePrimitiveContent></>);};
Each DisclosurePrimitiveContent component should have its own useDisclosureState
.
This is also true for derivative modules like Dialog, Popover, Menu, Tooltip etc.
If you want to have only one DisclosurePrimitive element controling multiple DisclosurePrimitiveContent
components, you can use render props to apply the same state to different
Disclosures that will result in a single element.
function MultipleExample() {const disclosure1 = useDisclosurePrimitiveState();const disclosure2 = useDisclosurePrimitiveState();return (<><DisclosurePrimitive {...disclosure1}>{props => (<DisclosurePrimitive {...props} {...disclosure2}>Toggle All</DisclosurePrimitive>)}</DisclosurePrimitive><DisclosurePrimitiveContent {...disclosure1}>Content 1</DisclosurePrimitiveContent><DisclosurePrimitiveContent {...disclosure2}>Content 2</DisclosurePrimitiveContent></>);};
Much of the following is copied directly from Reakit's docs. Because we may update at a different cadence, we're duplicating the docs here to prevent information fragmentation.
All the regular HTML attributes (role
, aria-*
, type
, and so on) including the following custom props:
Prop | Type | Default |
---|---|---|
baseId? | string | |
visible? | bool | |
animated? | number or boolean |
baseId
prop
ID that will serve as a base for all the items IDs.
visible
prop
Whether it's visible or not.
animated
prop
If true, animating will be set to true when visible is updated. It'll wait for stopAnimation to be called or a CSS transition ends. If animated is set to a number, stopAnimation will be called only after the same number of milliseconds have passed.
All the regular HTML attributes (role
, aria-*
, type
, and so on) including the following custom props:
Prop | Type | Default |
---|---|---|
disabled? | boolean | |
focusable? | boolean |
disabled
prop
Same as the HTML attribute.
focusable
prop
When an element is disabled
, it may still be focusable
. It works
similarly to readOnly
on form elements. In this case, only
aria-disabled
will be set.
State props
These props are returned by the state hook. You can spread them into this component (...state) or pass them separately. You can also provide these props from your own state logic.
Prop | Type | Default |
---|---|---|
visible | boolean | |
baseId | boolean | |
toggle | () => void |
baseId
prop
ID that will serve as a base for all the items IDs.
visible
prop
Whether it's visible or not.
toggle
prop
Toggles the visible state
State props
These props are returned by the state hook. You can spread them into this component (...state) or pass them separately. You can also provide these props from your own state logic.
Prop | Type | Default |
---|---|---|
visible | boolean | |
baseId | boolean | |
animated | number or boolean | |
animating | boolean | |
stopAnimation | () => void |
baseId
prop
ID that will serve as a base for all the items IDs.
visible
prop
Whether it's visible or not.
animated
prop
If true, animating will be set to true when visible is updated. It'll wait for stopAnimation to be called or a CSS transition ends. If animated is set to a number, stopAnimation will be called only after the same number of milliseconds have passed.
animating
prop
Whether it's animating or not.
stopAnimation
prop
Stops animation. It's called automatically if there's a CSS transition.
Changelog
e238ce11a
#3618 Thanks @SiTaggart! - [Disclosure primitive] Updated dev depenedencies to include typescript and tsx for running build scripts
b8d79200b
#3442 Thanks @TheSisb! - Removed all run-time prop-type checkingfrom Paste components. Paste now ships with only TypeScript types.ACTION NEEDED: None. This should be 100% backwards compatible.
733709127
#3395 Thanks @SiTaggart! - Modified the compile target of our JavaScript bundles fromnode
tobrowser
to minimize the risk of clashing with RequireJS. This is marked as a major out of an abundance of caution. You shouldn't need to do anything but we wanted you to be aware of the change on the off chance it has unintended consequences
- Updated dependencies [
733709127
]:- @twilio-paste/reakit-library@2.0.0
- Updated dependencies [
3c89fd83d
]:- @twilio-paste/reakit-library@1.0.0
a4c9e70b0
#2763 Thanks @shleewhite! - Update ESLint rules, which changed some formatting.
ae9dd50f
#2466 Thanks @TheSisb! - [All packages] Update our ESBuild version and remove minification of identifiers in our production builds.
12a5e83e
#2449 Thanks @shleewhite! - Made a slight improvement to the TypeScript typings of several packages for better interoperability.
73c596919
#2269 Thanks @SiTaggart! - Fixed a regression with the compilation script that caused incompatible ESM module importing of JSON files.
c867e3f48
#2237 Thanks @SiTaggart! - Updated a build dependency (esbuild) which changes the output of our builds slightly, without materially changing anything about the code.
b7675915
#1985 Thanks @TheSisb! - For debugging purposes we now ship afilename.debug.js
unminified version of each component or library in Paste.
ed5c0a49c
#1965 Thanks @shleewhite! - Upgrade Paste to use React 17 by default, but maintain React 16 support for consumers.
0eded1fd
#1319 Thanks @SiTaggart! - Change internal dependencies to have minor range matching on version numbers
ac38757f
#1228 Thanks @SiTaggart! - Bump status of the component to production
a12acb61
#1158 Thanks @richbachman! - Pinned all twilio-paste package versions in order to keep them in sync with core when they are updated by changesets.
All notable changes to this project will be documented in this file. See Conventional Commits for commit guidelines.
0.3.1 (2021-01-25)
Note: Version bump only for package @twilio-paste/disclosure-primitive
0.2.8 (2021-01-15)
Note: Version bump only for package @twilio-paste/disclosure-primitive
0.2.7 (2021-01-14)
Note: Version bump only for package @twilio-paste/disclosure-primitive
0.2.6 (2020-10-23)
Note: Version bump only for package @twilio-paste/disclosure-primitive
0.2.5 (2020-10-13)
Note: Version bump only for package @twilio-paste/disclosure-primitive
0.2.4 (2020-09-22)
Note: Version bump only for package @twilio-paste/disclosure-primitive
0.2.3 (2020-09-15)
Note: Version bump only for package @twilio-paste/disclosure-primitive
0.2.2 (2020-09-03)
Note: Version bump only for package @twilio-paste/disclosure-primitive
0.2.1 (2020-07-01)
Note: Version bump only for package @twilio-paste/disclosure-primitive
- disclosure-primitive: export state props (3299ad6)
0.1.7 (2020-06-25)
Note: Version bump only for package @twilio-paste/disclosure-primitive
0.1.6 (2020-06-18)
Note: Version bump only for package @twilio-paste/disclosure-primitive
0.1.5 (2020-06-16)
Note: Version bump only for package @twilio-paste/disclosure-primitive
0.1.4 (2020-06-10)
Note: Version bump only for package @twilio-paste/disclosure-primitive
0.1.3 (2020-06-09)
Note: Version bump only for package @twilio-paste/disclosure-primitive
0.1.2 (2020-06-01)
Note: Version bump only for package @twilio-paste/disclosure-primitive
0.1.1 (2020-05-20)
Note: Version bump only for package @twilio-paste/disclosure-primitive
- add disclosure primitive package (250ce2e)