Disclosure
Disclosure is an optionally controlled component used to put long sections of information under content blocks that users can expand or collapse by pressing an activator. The activator can be specified as children using an action component (Button
, Link
or Pressable
) or Checkbox
component. The content blocks can be specified as children inside a structure component (View
, ,
,
Grid
, etc.).
The library takes care of applying the WAI-ARIA Accordion pattern automatically for the activator and the toggled content.
Anchor to disclosurepropsDisclosureProps
- Anchor to defaultOpendefaultOpen< | undefined>
For uncontrolled disclosure components, the default
open
state on the initial render.It's possible to specify a boolean value, a string value, or an array of string values:
true
will expand all contentfalse
will collapse all contentstring
will expand the content with the matchingid
string[]
will expand the content with the matchingid
s
- Anchor to openopen
For controlled disclosure components, the open state. The
open
prop should be used along withto create a controlled disclosure component.
- Anchor to onToggleonToggle(open: string[]) => void
Callback fired when the open state of the disclosure changes.
- Anchor to transitiontransition"none"
Set to 'none' to disable the default transition animation.
DisclosureProps
- defaultOpen
For uncontrolled disclosure components, the default `open` state on the initial render. It's possible to specify a boolean value, a string value, or an array of string values: - `true` will expand all content - `false` will collapse all content - `string` will expand the content with the matching `id` - `string[]` will expand the content with the matching `id`s
MaybeResponsiveConditionalStyle<DisclosureOpen | undefined>
- open
For controlled disclosure components, the open state. The `open` prop should be used along with `onToggle` to create a controlled disclosure component.
DisclosureOpen
- onToggle
Callback fired when the open state of the disclosure changes.
(open: string[]) => void
- transition
Set to 'none' to disable the default transition animation.
"none"
export interface DisclosureProps {
/**
* For uncontrolled disclosure components, the default `open` state on the initial render.
*
* It's possible to specify a boolean value, a string value, or an array of string values:
*
* - `true` will expand all content
* - `false` will collapse all content
* - `string` will expand the content with the matching `id`
* - `string[]` will expand the content with the matching `id`s
*/
defaultOpen?: MaybeResponsiveConditionalStyle<DisclosureOpen | undefined>;
/**
* For controlled disclosure components, the open state. The `open` prop should be used
* along with `onToggle` to create a controlled disclosure component.
*/
open?: DisclosureOpen;
/**
* Callback fired when the open state of the disclosure changes.
*/
onToggle?(open: string[]): void;
/**
* Set to 'none' to disable the default transition animation.
*/
transition?: 'none';
}
MaybeResponsiveConditionalStyle
A type that represents a value that can be a conditional style. The conditions are based on the viewport size. We highly recommend using the `Style` helper which simplifies the creation of conditional styles. To learn more check out the [conditional styles](/api/checkout-ui-extensions/components/utilities/stylehelper) documentation.
T | ConditionalStyle<T, ViewportSizeCondition>
ConditionalStyle
- default
The default value applied when none of the conditional values specified in `conditionals` are met.
T
- conditionals
An array of conditional values.
ConditionalValue<T, AcceptedConditions>[]
export interface ConditionalStyle<
T,
AcceptedConditions extends BaseConditions = Conditions,
> {
/**
* The default value applied when none of the conditional values
* specified in `conditionals` are met.
*/
default?: T;
/**
* An array of conditional values.
*/
conditionals: ConditionalValue<T, AcceptedConditions>[];
}
ConditionalValue
- conditions
The conditions that must be met for the value to be applied. At least one condition must be specified.
AcceptedConditions
- value
The value that will be applied if the conditions are met.
T
export interface ConditionalValue<
T,
AcceptedConditions extends BaseConditions = Conditions,
> {
/**
* The conditions that must be met for the value to be applied. At least one
* condition must be specified.
*/
conditions: AcceptedConditions;
/**
* The value that will be applied if the conditions are met.
*/
value: T;
}
ViewportSizeCondition
- viewportInlineSize
{ min: ViewportInlineSize; }
export interface ViewportSizeCondition {
viewportInlineSize: {min: ViewportInlineSize};
}
ViewportInlineSize
'small' | 'medium' | 'large'
DisclosureOpen
boolean | string | string[]
Basic Disclosure
examples
Basic Disclosure
React
import { reactExtension, Disclosure, Button, View, } from '@shopify/ui-extensions-react/checkout'; export default reactExtension( 'purchase.checkout.block.render', () => <Extension />, ); function Extension() { return ( <Disclosure> <Button toggles="one">Toggle</Button> <View id="one">Content</View> </Disclosure> ); }
JS
import { extension, Button, View, Disclosure, } from '@shopify/ui-extensions/checkout'; export default extension('purchase.checkout.block.render', (root) => { const disclosure = root.createComponent(Disclosure, {}, [ root.createComponent(Button, {toggles: 'one'}, 'Toggle'), root.createComponent( View, {border: 'base', padding: 'base', id: 'one'}, 'Content', ), ]); root.appendChild(disclosure); });
Preview

Anchor to best-practicesBest Practices
Disclosures should be initiated by the buyer.
Use disclosures to hide content until they are relevant to the buyer.
Avoid hiding critical information that buyers need to complete their checkout.
Keep content inside disclosures concise.
Avoid nesting of disclosures.
Keep the activator and the content it toggles in close proximity to each other.
Anchor to examplesExamples
Anchor to example-strategies-for-simplifying-layout-and-aligning-content-using-disclosure-and-inline/block-layout-components.Strategies for simplifying layout and aligning content using Disclosure and Inline/Block Layout components.
Use the Disclosure component to simplify the user experience and reveal interfaces only when the customer requests it. It also demonstrates how a combination of inline and block layout components can improve the readability of information. By employing these strategies, users can easily scan and comprehend the content, making for a better user experience overall.
Strategies for simplifying layout and aligning content using Disclosure and Inline/Block Layout components.
examples
Strategies for simplifying layout and aligning content using Disclosure and Inline/Block Layout components.
description
Use the Disclosure component to simplify the user experience and reveal interfaces only when the customer requests it. It also demonstrates how a combination of inline and block layout components can improve the readability of information. By employing these strategies, users can easily scan and comprehend the content, making for a better user experience overall.
React
import { reactExtension, View, Image, Icon, Pressable, Disclosure, InlineLayout, BlockStack, Text, Form, TextField, Button, Divider, InlineStack, } from '@shopify/ui-extensions-react/checkout'; export default reactExtension( 'purchase.checkout.block.render', () => <DisclosureAndAlignment />, ); export const DisclosureAndAlignment = () => { const openIds = ['one']; return ( <View maxInlineSize={400} cornerRadius="large" border="base" > <BlockStack spacing="none"> <Disclosure defaultOpen="one" onToggle={(open) => console.log('onToggle event', open) } > <Pressable toggles="one" padding="base"> <InlineLayout blockAlignment="center" spacing="base" columns={['auto', 'fill', 'auto']} > <Icon source="gift" appearance="subdued" /> Gift message <Icon source={ openIds.includes('one') ? 'chevronUp' : 'chevronDown' } appearance="subdued" /> </InlineLayout> </Pressable> <View id="one" padding={[ 'none', 'base', 'base', 'base', ]} > <Form onSubmit={() => console.log('onSubmit event') } > <BlockStack> <InlineLayout columns={['fill', 'fill']} spacing="base" > <TextField label="From" name="from0" id="from0" /> <TextField label="To" name="to0" id="to0" /> </InlineLayout> <TextField label="Message" name="message0" id="message0" /> <View> <Button accessibilityRole="submit" kind="secondary" > Save </Button> </View> </BlockStack> </Form> </View> </Disclosure> <Divider /> <InlineLayout blockAlignment="baseline" spacing="base" columns={['auto', 'fill', 'auto']} padding="base" > <Icon source="profile" appearance="subdued" /> <BlockStack spacing="none"> <InlineStack blockAlignment="center"> <Text>Verify with</Text> <Image source="https://via.placeholder.com/50x15" /> </InlineStack> <Text appearance="subdued" size="small" > 15% savings for students and military </Text> </BlockStack> <Pressable to="https://www.shopify.com"> <Icon source="external" appearance="subdued" /> </Pressable> </InlineLayout> </BlockStack> </View> ); };
JavaScript
import { extension, BlockStack, View, InlineLayout, InlineStack, Image, Pressable, Icon, Text, TextField, Form, Button, Disclosure, Divider, } from '@shopify/ui-extensions/checkout'; export default extension( 'purchase.checkout.block.render', (root) => { const openIds = ['one']; const pressable = root.createComponent( Pressable, { toggles: 'one', padding: 'base', }, [ root.createComponent( InlineLayout, { blockAlignment: 'center', spacing: 'base', columns: ['auto', 'fill', 'auto'], }, [ root.createComponent(Icon, { source: 'gift', appearance: 'subdued', }), 'Gift message', root.createComponent(Icon, { source: openIds.includes('one') ? 'chevronUp' : 'chevronDown', size: 'small', }), ], ), ], ); const disclosureView = root.createComponent( View, { id: 'one', padding: ['none', 'base', 'base', 'base'], }, [ root.createComponent( Form, { onSubmit: () => console.log('onSubmit event'), }, [ root.createComponent(BlockStack, {}, [ root.createComponent( InlineLayout, { columns: ['fill', 'fill'], spacing: 'base', }, [ root.createComponent( TextField, { label: 'From', name: 'from0', id: 'from0', }, ), root.createComponent( TextField, { label: 'To', name: 'to0', id: 'to0', }, ), ], ), root.createComponent(TextField, { label: 'Message', name: 'message0', id: 'message0', }), root.createComponent(View, {}, [ root.createComponent( Button, { accessibilityRole: 'submit', kind: 'secondary', }, 'Save', ), ]), ]), ], ), ], ); const disclosure = root.createComponent( Disclosure, { defaultOpen: 'one', onToggle: (open) => console.log('onToggle event', open), }, [pressable, disclosureView], ); const inlineLayout = root.createComponent( InlineLayout, { blockAlignment: 'baseline', spacing: 'base', columns: ['auto', 'fill', 'auto'], padding: 'base', }, [ root.createComponent(Icon, { source: 'profile', appearance: 'subdued', }), root.createComponent( BlockStack, { spacing: 'none', }, [ root.createComponent( InlineStack, { blockAlignment: 'center', }, [ root.createComponent( Text, {}, 'Verify with', ), root.createComponent(Image, { source: 'https://via.placeholder.com/50x15', }), ], ), root.createComponent( Text, { appearance: 'subdued', size: 'small', }, '15% savings for students and military', ), ], ), root.createComponent( Pressable, { to: 'https://www.shopify.com', }, [ root.createComponent(Icon, { source: 'external', appearance: 'subdued', }), ], ), ], ); const view = root.createComponent( View, { maxInlineSize: 400, cornerRadius: 'large', border: 'base', }, [ root.createComponent( BlockStack, { spacing: 'none', }, [ disclosure, root.createComponent(Divider), inlineLayout, ], ), ], ); root.appendChild(view); }, );
Preview
