Skip to contentSkip to navigationSkip to topbar
Figma
Star

Disclosure

Peer review pending

A Disclosure is a collapsible accordion that gives hierarchy to a page.

Version 12.1.0
Github
Component preview theme
<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>

Guidelines

Guidelines page anchor

About Disclosure

About Disclosure page anchor

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.

Component preview theme
<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.

Component preview theme
<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>

Controlling initial state

Controlling initial state page anchor

You can control the initial state of the disclosure to be expanded or collapsed by setting the visible prop.

Component preview theme
<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(link takes you to an external page).

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.

Component preview theme
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.

Component preview theme
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

Component preview theme
<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.

Component preview theme
<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.

Component preview theme
<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>
Component preview theme
<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>