Disclosure
A Disclosure is a collapsible accordion that gives hierarchy to a page.
<Disclosure><DisclosureHeading as="h2" variant="heading30">Between the World and Me by Ta-Nehisi Coates</DisclosureHeading><DisclosureContent>But race is the child of racism, not the father. And the process of naming “the people” has never been a matter of genealogy and physiognomy so much as one of hierarchy. Difference in hue and hair is old. But the belief in the preeminence of hue and hair, the notion that these factors can correctly organize a society and that they signify deeper attributes, which are indelible—this is the new idea at the heart of these new people who have been brought up hopelessly, tragically, deceitfully, to believe that they are white.</DisclosureContent></Disclosure>
The Disclosure is used to create accessible, hierarchical, and collapsible structure to your pages. It uses the Paste Heading component to create consistency across pages and content hierarchy.
You must not nest focusable or actionable elements inside the DisclosureHeading
. Nested actionable elements are difficult to discover for users of assistive technology as their existence is often not announced.
The default variant of a Disclosure is a composition of the Paste Heading and a chevron button icon as the "trigger" for the disclosure. This trigger controls the appearance of content that is below it.
The DisclosureHeading
takes the same props as the Heading component so you can control the semantic heading level and it's visual appearance through variants.
<Stack orientation="vertical" spacing="space70"><Disclosure><DisclosureHeading as="h2" variant="heading30">Between the World and Me by Ta-Nehisi Coates</DisclosureHeading><DisclosureContent>But race is the child of racism, not the father. And the process of naming “the people” has never been a matter of genealogy and physiognomy so much as one of hierarchy. Difference in hue and hair is old. But the belief in the preeminence of hue and hair, the notion that these factors can correctly organize a society and that they signify deeper attributes, which are indelible—this is the new idea at the heart of these new people who have been brought up hopelessly, tragically, deceitfully, to believe that they are white.</DisclosureContent></Disclosure><Disclosure><DisclosureHeading as="h2" variant="heading10">Disclosure Heading</DisclosureHeading><DisclosureContent>Content</DisclosureContent></Disclosure><Disclosure><DisclosureHeading as="h2" variant="heading20">Disclosure Heading</DisclosureHeading><DisclosureContent>Content</DisclosureContent></Disclosure><Disclosure><DisclosureHeading as="h2" variant="heading30">Disclosure Heading</DisclosureHeading><DisclosureContent>Content</DisclosureContent></Disclosure><Disclosure><DisclosureHeading as="h2" variant="heading40">Disclosure Heading</DisclosureHeading><DisclosureContent>Content</DisclosureContent></Disclosure><Disclosure><DisclosureHeading as="h2" variant="heading50">Disclosure Heading</DisclosureHeading><DisclosureContent>Content</DisclosureContent></Disclosure><Disclosure><DisclosureHeading as="h2" variant="heading60">Disclosure Heading</DisclosureHeading><DisclosureContent>Content</DisclosureContent></Disclosure></Stack>
The contained
variant of the Disclosure takes the default composition and wraps it in the Paste Card component. In this instance we do not expose the props used by Card, but all previously mentioned Disclosure props behave in the same way as the default variant.
<Stack orientation="vertical" spacing="space70"><Disclosure variant="contained"><DisclosureHeading as="h2" variant="heading10">Disclosure Heading</DisclosureHeading><DisclosureContent>Content</DisclosureContent></Disclosure><Disclosure variant="contained"><DisclosureHeading as="h2" variant="heading20">Disclosure Heading</DisclosureHeading><DisclosureContent>Content</DisclosureContent></Disclosure><Disclosure variant="contained"><DisclosureHeading as="h2" variant="heading30">Disclosure Heading</DisclosureHeading><DisclosureContent>Content</DisclosureContent></Disclosure><Disclosure variant="contained"><DisclosureHeading as="h2" variant="heading40">Disclosure Heading</DisclosureHeading><DisclosureContent>Content</DisclosureContent></Disclosure><Disclosure variant="contained"><DisclosureHeading as="h2" variant="heading50">Disclosure Heading</DisclosureHeading><DisclosureContent>Content</DisclosureContent></Disclosure><Disclosure variant="contained"><DisclosureHeading as="h2" variant="heading60">Disclosure Heading</DisclosureHeading><DisclosureContent>Content</DisclosureContent></Disclosure></Stack>
You can control the initial state of the disclosure to be expanded or collapsed by setting the visible
prop.
<Disclosure visible><DisclosureHeading as="h2" variant="heading30">Disclosure Heading</DisclosureHeading><DisclosureContent>Content</DisclosureContent></Disclosure>
Disclosure comes with the option of "hooking" into the internal state by using the state hook originally provided by Reakit.
The state
prop allows you to hook into, and keep in sync the state of the Disclosure and the state of your application.
This will allow you to set initial state and merge the returned state from the hook with the application state, and keep it in sync with user interactions.
It should be noted that when doing so, the state prop takes precident over the other properties that affect the state or initial state of the Disclosure. They will be ignored in favour of them being provided as arguments to the useDisclosureState hook.
For full details on how to use the state hook, and what props to provide it, follow the Disclosure Primitive documentation. It's the same hook, just renamed.
You could use this if you need to wait for a response from an API before opening the Disclosure content. In the example below, we're simulating the response time by adding a delay.
const useDelayedDisclosureState = ({delay, ...initialState}) => {const disclosure = useDisclosureState(initialState);const [transitioning, setTransitioning] = React.useState(false);return {...disclosure,transitioning,toggle: () => {setTransitioning(true);setTimeout(() => {disclosure.toggle();setTransitioning(false);}, delay);},};};const StateHookDisclosure = () => {const {transitioning, ...disclosure} = useDelayedDisclosureState({delay: 500,});const clickableHeading = disclosure.visible ? 'Hide with delay' : 'Show with delay';return (<><Disclosure variant="contained" state={disclosure}><DisclosureHeading as="h2" variant="heading20">{transitioning ? 'Please wait...' : clickableHeading}</DisclosureHeading><DisclosureContent>Disclosure content</DisclosureContent></Disclosure></>);};render(<StateHookDisclosure />)
Another usecase of this might be programmatically opening/closing a Disclosure. In the example below we are using a separate button to toggle the visibilty of the disclosure content.
const StateHookToggleDisclosure = () => {const [show, setShow] = React.useState(false);const disclosure = useDisclosureState();const toggleDisclosure = () => setShow(state => !state);const customDisclosureState = {...disclosure,toggle: toggleDisclosure,visible: show};return (<><Disclosure variant="contained" state={customDisclosureState}><DisclosureHeading as="h2" variant="heading20">Disclosure Heading</DisclosureHeading><DisclosureContent>Disclosure content</DisclosureContent></Disclosure><Box marginTop="space60"><Button onClick={toggleDisclosure} variant="primary">Toggle Disclosure</Button></Box></>);};render(<StateHookToggleDisclosure />)
Each Disclosure can be disabled by setting the disabled
prop on the DisclosureHeading
<Disclosure visible><DisclosureHeading as="h2" disabled variant="heading30">Disclosure Heading</DisclosureHeading><DisclosureContent>Content</DisclosureContent></Disclosure>
Both DisclosureHeading
and DisclosureContent
accept any child component. However, avoid placing a focusable element inside the DisclosureHeading
.
<Disclosure><DisclosureHeading as="h2" variant="heading30"><Flex vAlignContent="center">Disclosure Heading<Text as="span" color="colorTextWeak" fontSize="fontSize50" marginLeft="space20">(3 new items)</Text></Flex></DisclosureHeading><DisclosureContent>Content</DisclosureContent></Disclosure>
Disclosure headers should be short, no more than 1 line, and prioritize the user goal. Use sentence case for the headers.
Any content contained within a disclosure can be formatted into multiple paragraphs with sub-headers, if needed.
Disclosures with an error icon in the header must include additional information on the nature of the error and how the user can fix it within the disclosure content. For additional guidance on how to compose error messages, refer to the error state pattern.
<Disclosure variant="contained" visible><DisclosureHeading as="h2" variant="heading30"><MediaObject verticalAlign="center"><MediaBody>Message details <Text color="colorTextWeak" fontSize="fontSize50" marginRight="space30" as="span">- Request timeout</Text></MediaBody><MediaFigure><ErrorIcon color="colorTextError" decorative={false} title="Error" /></MediaFigure></MediaObject></DisclosureHeading><DisclosureContent>Server connection failed. Try again later.</DisclosureContent></Disclosure>
<Disclosure variant="contained" visible><DisclosureHeading as="h2" variant="heading30"><MediaObject verticalAlign="center"><MediaBody>Message details <Text color="colorTextWeak" fontSize="fontSize50" marginRight="space30" as="span">- Successful send</Text></MediaBody><MediaFigure><SuccessIcon color="colorTextSuccess" decorative={false} title="Success" /></MediaFigure></MediaObject></DisclosureHeading><DisclosureContent>Your message was sent successfully.</DisclosureContent></Disclosure>