Components Manifest

Badge

design-system-components-badge-choosing-intent · ../packages/ui/src/badge/stories/choosing-intent.story.tsx
A badge component for displaying labels with semantic intent.
Prop types 5 prop types
Component: ../packages/ui/src/badge/badge.tsx::Badge
Props:
/**
 * The text to display in the badge.
 */
children: string

/**
 * CSS class name to apply to the element.
 */
className?: string

/**
 * The semantic intent of the badge, communicating its meaning through color.
 * 
 * @default "none"
 */
intent?: | 'high'
| 'medium'
| 'low'
| 'stable'
| 'informational'
| 'draft'
| 'none' = 'none'

/**
 * Replaces the component's default HTML element using a given React
 * element, or a function that returns a React element.
 */
render?: | ComponentRenderFn< HTMLAttributesWithRef >
| React.ReactElement< Record< string, unknown > >

/**
 * CSS style to apply to the element.
 */
style?: React.CSSProperties
Imports
import { Badge, Stack } from "@wordpress/ui";
All Intents story ok
const AllIntents = () => (
    <>
        <Badge intent="high">high</Badge>
        <Badge intent="medium">medium</Badge>
        <Badge intent="low">low</Badge>
        <Badge intent="stable">stable</Badge>
        <Badge intent="informational">informational</Badge>
        <Badge intent="draft">draft</Badge>
        <Badge intent="none">none</Badge>
    </>
);
High story ok
const High = () => (
    <>
        <Badge intent="high">Payment declined</Badge>
        <Badge intent="high">Security issue</Badge>
    </>
);
Medium story ok
const Medium = () => (
    <>
        <Badge intent="medium">Approval required</Badge>
        <Badge intent="medium">Review needed</Badge>
    </>
);
Low story ok
const Low = () => (
    <>
        <Badge intent="low">Pending</Badge>
        <Badge intent="low">Queued</Badge>
    </>
);
Informational story ok
const Informational = () => (
    <>
        <Badge intent="informational">Scheduled</Badge>
        <Badge intent="informational">Beta</Badge>
    </>
);
Draft story ok
const Draft = () => (
    <>
        <Badge intent="draft">Draft</Badge>
        <Badge intent="draft">Unpublished</Badge>
    </>
);
Stable story ok
const Stable = () => (
    <>
        <Badge intent="stable">Healthy</Badge>
        <Badge intent="stable">Active</Badge>
    </>
);
None story ok
const None = () => (
    <>
        <Badge intent="none">Inactive</Badge>
        <Badge intent="none">Expired</Badge>
    </>
);
Comment Status story ok
const CommentStatus = () => (
    <>
        <Badge intent="none">Approved</Badge>
        <Badge intent="medium">Approval required</Badge>
    </>
);
Page Status story ok
const PageStatus = () => (
    <>
        <Badge intent="none">Published</Badge>
        <Badge intent="low">Pending</Badge>
        <Badge intent="draft">Draft</Badge>
        <Badge intent="informational">Scheduled</Badge>
        <Badge intent="informational">Private</Badge>
    </>
);
Plugin Status story ok
const PluginStatus = () => (
    <>
        <Badge intent="stable">Active</Badge>
        <Badge intent="none">Inactive</Badge>
    </>
);

Badge

design-system-components-badge · ../packages/ui/src/badge/stories/index.story.tsx
A badge component for displaying labels with semantic intent.
Prop types 5 prop types
Component: ../packages/ui/src/badge/badge.tsx::Badge
Props:
/**
 * The text to display in the badge.
 */
children: string

/**
 * CSS class name to apply to the element.
 */
className?: string

/**
 * The semantic intent of the badge, communicating its meaning through color.
 * 
 * @default "none"
 */
intent?: | 'high'
| 'medium'
| 'low'
| 'stable'
| 'informational'
| 'draft'
| 'none' = 'none'

/**
 * Replaces the component's default HTML element using a given React
 * element, or a function that returns a React element.
 */
render?: | ComponentRenderFn< HTMLAttributesWithRef >
| React.ReactElement< Record< string, unknown > >

/**
 * CSS style to apply to the element.
 */
style?: React.CSSProperties
Imports
import { Badge } from "@wordpress/ui";
import { Fragment } from "@wordpress/element";
Default story ok
const Default = () => <Badge>Badge</Badge>;
High story ok
const High = () => <Badge intent="high" />;
Medium story ok
const Medium = () => <Badge intent="medium" />;
Low story ok
const Low = () => <Badge intent="low" />;
Stable story ok
const Stable = () => <Badge intent="stable" />;
Informational story ok
const Informational = () => <Badge intent="informational" />;
Draft story ok
const Draft = () => <Badge intent="draft" />;
None story ok
const None = () => <Badge intent="none" />;
All Intents story ok
const AllIntents = ( args ) => (
    <div
        style={ {
            display: 'grid',
            gridTemplateColumns: 'max-content min-content',
            gap: '1rem',
            color: 'var(--wpds-color-fg-content-neutral)',
        } }
    >
        { (
            [
                'high',
                'medium',
                'low',
                'stable',
                'informational',
                'draft',
                'none',
            ] as const
         ).map( ( intent ) => (
            <Fragment key={ intent }>
                <div
                    style={ {
                        paddingInlineEnd: '1rem',
                        display: 'flex',
                        alignItems: 'center',
                    } }
                >
                    { intent }
                </div>
                <div
                    style={ {
                        padding: '0.5rem 1rem',
                        display: 'flex',
                        alignItems: 'center',
                    } }
                >
                    <Badge { ...args } intent={ intent } />
                </div>
            </Fragment>
        ) ) }
    </div>
);

BaseControl

components-basecontrol · ../packages/components/src/base-control/stories/index.story.tsx
Info
No description found. Write a jsdoc comment such as /** Component description */.
Imports
import { BaseControl, Button } from "@wordpress/components";
Default story ok
const Default = ( props ) => {
	const { baseControlProps, controlProps } = useBaseControlProps( props );

	return (
		<BaseControl { ...baseControlProps }>
			<textarea style={ { display: 'block' } } { ...controlProps } />
		</BaseControl>
	);
};
With Help Text story ok
const WithHelpText = ( props ) => {
	const { baseControlProps, controlProps } = useBaseControlProps( props );

	return (
		<BaseControl { ...baseControlProps }>
			<textarea style={ { display: 'block' } } { ...controlProps } />
		</BaseControl>
	);
};
With Visual Label story ok
`BaseControl.VisualLabel` is used to render a purely visual label inside a `BaseControl` component. It should only be used in cases where the children being rendered inside `BaseControl` are already accessibly labeled, e.g., a button, but we want an additional visual label for that section equivalent to the labels `BaseControl` would otherwise use if the `label` prop was passed.
const WithVisualLabel = ( props ) => {
	BaseControl.VisualLabel.displayName = 'BaseControl.VisualLabel';

	return (
		<BaseControl { ...props }>
			<BaseControl.VisualLabel>Visual label</BaseControl.VisualLabel>
			<div>
				<Button __next40pxDefaultSize variant="secondary">
					Select an author
				</Button>
			</div>
		</BaseControl>
	);
};

Button

components-button · ../packages/components/src/button/stories/index.story.tsx
Lets users take actions and make choices with a single click or tap. ```jsx import { Button } from '@wordpress/components'; const Mybutton = () => ( <Button variant="primary" onClick={ handleClick } > Click here </Button> ); ```
Prop types 8 prop types
Component: ../packages/components/src/button/index.tsx::Button
Props:
/**
 * Whether to keep the button focusable when disabled.
 * 
 * @default false
 * @deprecated Use the `accessibleWhenDisabled` prop instead.
 * @ignore
 */
__experimentalIsFocusable?: boolean

/**
 * A visually hidden accessible description for the button.
 * 
 * @deprecated Use the `description` prop instead.
 * @ignore
 */
describedBy?: string

/**
 * Gives the button a default style.
 * 
 * @deprecated Use the `'secondary'` value on the `variant` prop instead.
 * @ignore
 */
isDefault?: boolean

/**
 * Gives the button a link style.
 * 
 * @deprecated Use the `'link'` value on the `variant` prop instead.
 * @ignore
 */
isLink?: boolean

/**
 * Gives the button a primary style.
 * 
 * @deprecated Use the `'primary'` value on the `variant` prop instead.
 * @ignore
 */
isPrimary?: boolean

/**
 * Gives the button a default style.
 * 
 * @deprecated Use the `'secondary'` value on the `variant` prop instead.
 * @ignore
 */
isSecondary?: boolean

/**
 * Decreases the size of the button.
 * 
 * @deprecated Use the `'small'` value on the `size` prop instead.
 * @ignore
 */
isSmall?: boolean

/**
 * Gives the button a text-based style.
 * 
 * @deprecated Use the `'tertiary'` value on the `variant` prop instead.
 * @ignore
 */
isTertiary?: boolean
Imports
import { Button } from "@wordpress/components";
Default story ok
const Default = ( props ) => {
	return <Button __next40pxDefaultSize { ...props }></Button>;
};
Primary story ok
Primary buttons stand out with bold color fills, making them distinct from the background. Since they naturally draw attention, each layout should contain only one primary button to guide users toward the most important action.
const Primary = ( props ) => {
	return <Button __next40pxDefaultSize { ...props }></Button>;
};
Secondary story ok
Secondary buttons complement primary buttons. Use them for standard actions that may appear alongside a primary action.
const Secondary = ( props ) => {
	return <Button __next40pxDefaultSize { ...props }></Button>;
};
Tertiary story ok
Tertiary buttons have minimal emphasis. Use them sparingly to subtly highlight an action.
const Tertiary = ( props ) => {
	return <Button __next40pxDefaultSize { ...props }></Button>;
};
Link story ok
Link buttons have low emphasis and blend into the page, making them suitable for supplementary actions, especially those involving navigation away from the current view.
const Link = ( props ) => {
	return <Button __next40pxDefaultSize { ...props }></Button>;
};
Is Destructive story ok
Use this variant for irreversible actions. Apply sparingly and only for actions with significant impact.
const IsDestructive = ( props ) => {
	return <Button __next40pxDefaultSize { ...props }></Button>;
};
Icon story ok
const Icon = ( props ) => {
	return <Button __next40pxDefaultSize { ...props }></Button>;
};
Grouped Icons story ok
function GroupedIcons() {
	return (
		<GroupContainer>
			<Button __next40pxDefaultSize icon={ formatBold } label="Bold" />
			<Button
				__next40pxDefaultSize
				icon={ formatItalic }
				label="Italic"
			/>
			<Button __next40pxDefaultSize icon={ link } label="Link" />
		</GroupContainer>
	);
}

Card.Root

design-system-components-card · ../packages/ui/src/card/stories/index.story.tsx
A visually contained surface that groups related content and actions. ```jsx import { Card } from '@wordpress/ui'; function MyComponent() { return ( <Card.Root> <Card.Header> <Card.Title>Heading</Card.Title> </Card.Header> <Card.Content> <p>Main content here.</p> </Card.Content> </Card.Root> ); } ```
Prop types 4 prop types
Component: ../packages/ui/src/card/root.tsx::Root
Props:
/**
 * The content to be rendered inside the card.
 */
children?: ReactNode

/**
 * CSS class name to apply to the element.
 */
className?: string

/**
 * Replaces the component's default HTML element using a given React
 * element, or a function that returns a React element.
 */
render?: | ComponentRenderFn< HTMLAttributesWithRef >
| React.ReactElement< Record< string, unknown > >

/**
 * CSS style to apply to the element.
 */
style?: React.CSSProperties
Imports
import { Content, FullBleed, Header, Root, Title, Stack } from "@wordpress/ui";
Default story ok
const Default = () => <Card.Root>(<>
        <Card.Header>
            <Card.Title>Card title</Card.Title>
        </Card.Header>
        <Card.Content>
            <Text>
                This is the main content area. It can contain any
                elements. This is the main content area. It can contain
                any elements. This is the main content area. It can
                contain any elements. This is the main content area. It
                can contain any elements. This is the main content area.
                It can contain any elements. This is the main content
                area. It can contain any elements.
            </Text>
            <Text>
                This is the main content area. It can contain any
                elements.
            </Text>
        </Card.Content>
    </>)</Card.Root>;
Full Bleed Cover Only story ok
`Card.FullBleed` as the sole child of `Card.Content` spans edge-to-edge with no padding around it.
const FullBleedCoverOnly = () => <Card.Root>(<Card.Content>
        <Card.FullBleed>
            <div
                style={ {
                    height: 180,
                    background:
                        'linear-gradient(135deg, #f093fb 0%, #f5576c 100%)',
                } }
            />
        </Card.FullBleed>
    </Card.Content>)</Card.Root>;
Full Bleed Cover With Header story ok
When `Card.FullBleed` is the sole child of `Card.Content` and a `Card.Header` sits above it, the image bumps against the card's side and bottom edges while the header retains its normal padding.
const FullBleedCoverWithHeader = () => <Card.Root>(<>
        <Card.Header>
            <Card.Title>Card title</Card.Title>
        </Card.Header>
        <Card.Content>
            <Card.FullBleed>
                <div
                    style={ {
                        height: 180,
                        background:
                            'linear-gradient(135deg, #f093fb 0%, #f5576c 100%)',
                    } }
                />
            </Card.FullBleed>
        </Card.Content>
    </>)</Card.Root>;
With Full Bleed story ok
`Card.FullBleed` breaks out of the card's padding to span edge-to-edge. Useful for images, dividers, or embedded content.
const WithFullBleed = () => <Card.Root>(<>
        <Card.Header>
            <Card.Title>Featured image</Card.Title>
        </Card.Header>
        <Card.Content render={ <Stack direction="column" gap="lg" /> }>
            <Card.FullBleed>
                <div
                    style={ {
                        height: 160,
                        background:
                            'linear-gradient(135deg, #667eea 0%, #764ba2 100%)',
                    } }
                />
            </Card.FullBleed>
            <Text>Content below the full-bleed area.</Text>
        </Card.Content>
    </>)</Card.Root>;
Header Only story ok
A minimal card with only a header.
const HeaderOnly = () => <Card.Root>(<Card.Header>
        <Card.Title>Simple card</Card.Title>
    </Card.Header>)</Card.Root>;
Full Bleed Hero With Title story ok
When `Card.FullBleed` is the **first child** of `Card.Header`, it extends flush to the card's top and side edges — ideal for hero images. Content that follows inside the header is padded normally.
const FullBleedHeroWithTitle = () => <Card.Root>(<>
        <Card.Header render={ <Stack direction="column" gap="lg" /> }>
            <Card.FullBleed>
                <div
                    style={ {
                        height: 180,
                        background:
                            'linear-gradient(135deg, #f093fb 0%, #f5576c 100%)',
                    } }
                />
            </Card.FullBleed>
            <Card.Title>Hero image card</Card.Title>
        </Card.Header>
        <Card.Content>
            <Text>
                The image above bleeds to the card&apos;s top and side
                edges.
            </Text>
        </Card.Content>
    </>)</Card.Root>;
Full Bleed Hero Only story ok
When `Card.FullBleed` is the **only child** of `Card.Header`, it fills the header entirely — top and sides flush to the card edges, no extra padding below.
const FullBleedHeroOnly = () => <Card.Root>(<>
        <Card.Header>
            <Card.FullBleed>
                <div
                    style={ {
                        height: 180,
                        background:
                            'linear-gradient(135deg, #f093fb 0%, #f5576c 100%)',
                    } }
                />
            </Card.FullBleed>
        </Card.Header>
        <Card.Content>
            <Text>
                The image above bleeds to the card&apos;s top and side
                edges.
            </Text>
        </Card.Content>
    </>)</Card.Root>;
Custom Semantics story ok
Use the `render` prop to change the underlying HTML elements for better semantics. Here, `Card.Root` renders as a `<section>` and `Card.Title` renders as an `<h2>`.
const CustomSemantics = () => <Card.Root render={<section />}>(<>
        <Card.Header>
            <Card.Title render={ <h2 /> }>Section heading</Card.Title>
        </Card.Header>
        <Card.Content>
            <Text>Semantically meaningful card content.</Text>
        </Card.Content>
    </>)</Card.Root>;

CheckboxControl

components-checkboxcontrol · ../packages/components/src/checkbox-control/stories/index.story.tsx
Checkboxes allow the user to select one or more items from a set. ```jsx import { CheckboxControl } from '@wordpress/components'; import { useState } from '@wordpress/element'; const MyCheckboxControl = () => { const [ isChecked, setChecked ] = useState( true ); return ( <CheckboxControl label="Is author" help="Is the user a author or not?" checked={ isChecked } onChange={ setChecked } /> ); }; ```
Imports
import { CheckboxControl, HStack, VStack } from "@wordpress/components";
Default story ok
const Default = () => {
    const [ isChecked, setChecked ] = useState( true );

    return (
        <CheckboxControl
            label="Is author"
            help="Is the user an author or not?"
            checked={ isChecked }
            onChange={ ( v ) => {
				setChecked( v );
				onChange( v );
			} } />
    );
};
Indeterminate story ok
const Indeterminate = () => {
    const [ fruits, setFruits ] = useState( { apple: false, orange: false } );

    const isAllChecked = Object.values( fruits ).every( Boolean );
    const isIndeterminate =
		Object.values( fruits ).some( Boolean ) && ! isAllChecked;

    return (
        <VStack>
            <CheckboxControl
                label="Select all"
                checked={ isAllChecked }
                indeterminate={ isIndeterminate }
                onChange={ ( v ) => {
					setFruits( {
						apple: v,
						orange: v,
					} );
					onChange( v );
				} } />
            <CheckboxControl
                label="Apple"
                checked={ fruits.apple }
                onChange={ ( apple ) =>
					setFruits( ( prevState ) => ( {
						...prevState,
						apple,
					} ) )
				} />
            <CheckboxControl
                label="Orange"
                checked={ fruits.orange }
                onChange={ ( orange ) =>
					setFruits( ( prevState ) => ( {
						...prevState,
						orange,
					} ) )
				} />
        </VStack>
    );
};
With Custom Label story ok
For more complex designs, a custom `<label>` element can be associated with the checkbox by leaving the `label` prop undefined and using the `id` and `htmlFor` props instead. Because the label element also functions as a click target for the checkbox, [do not place interactive elements](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/label#interactive_content) such as links or buttons inside the `<label>` node. Similarly, a custom description can be added by omitting the `help` prop and using the `aria-describedby` prop instead.
const WithCustomLabel = () => {
    const [ isChecked, setChecked ] = useState( true );

    return (
        <HStack justify="flex-start" alignment="top" spacing={ 0 }>
            <CheckboxControl
                checked={ isChecked }
                onChange={ ( v ) => {
					setChecked( v );
					onChange( v );
				} }
                // Disable reason: For simplicity of the code snippet.
                // eslint-disable-next-line no-restricted-syntax
                id="my-checkbox-with-custom-label"
                aria-describedby="my-custom-description" />
            <VStack>
                <label htmlFor="my-checkbox-with-custom-label">My custom label
                                    </label>
                { /* eslint-disable-next-line no-restricted-syntax */ }
                <div id="my-custom-description" style={ { fontSize: 13 } }>A custom description.
                                    </div>
            </VStack>
        </HStack>
    );
};

Collapsible.Root

design-system-components-collapsible · ../packages/ui/src/collapsible/stories/index.story.tsx
Groups all parts of the collapsible. `Collapsible` is a collection of React components that combine to render a collapsible panel controlled by a button.
Prop types 4 prop types
Component: ../packages/ui/src/collapsible/root.tsx::Root
Props:
/**
 * The content to be rendered inside the component.
 */
children?: ReactNode

/**
 * CSS class name to apply to the element.
 */
className?: string

/**
 * Replaces the component's default HTML element using a given React
 * element, or a function that returns a React element.
 */
render?: | ComponentRenderFn< HTMLAttributesWithRef >
| React.ReactElement< Record< string, unknown > >

/**
 * CSS style to apply to the element.
 */
style?: React.CSSProperties
Imports
import { Panel, Root, Trigger } from "@wordpress/ui";
Default story ok
const Default = () => <Collapsible.Root>(<>
        <Collapsible.Trigger>Toggle</Collapsible.Trigger>
        <Collapsible.Panel>
            <p>Collapsible content here.</p>
        </Collapsible.Panel>
    </>)</Collapsible.Root>;
Default Open story ok
const DefaultOpen = () => <Collapsible.Root defaultOpen>(<>
        <Collapsible.Trigger>Toggle</Collapsible.Trigger>
        <Collapsible.Panel>
            <p>This panel is open by default.</p>
        </Collapsible.Panel>
    </>)</Collapsible.Root>;
Disabled story ok
const Disabled = () => <Collapsible.Root disabled>(<>
        <Collapsible.Trigger>Toggle (disabled)</Collapsible.Trigger>
        <Collapsible.Panel>
            <p>This content cannot be toggled.</p>
        </Collapsible.Panel>
    </>)</Collapsible.Root>;
Hidden Until Found story ok
When `hiddenUntilFound` is set on `Collapsible.Panel`, the collapsed content remains in the DOM using the `hidden="until-found"` HTML attribute instead of being removed entirely. This lets the browser's native page search (Ctrl/Cmd+F) find text inside collapsed panels and automatically expand them to reveal the match — improving discoverability without sacrificing the collapsed layout.
const HiddenUntilFound = function HiddenUntilFound() {
    return (
        <div>
            <p>
                Use the browser&apos;s find-in-page (Ctrl/Cmd+F) to search
                for &quot;hidden treasure&quot;. The collapsed panel will
                automatically expand to reveal the match.
            </p>
            <Collapsible.Root>
                <Collapsible.Trigger>Expand to reveal</Collapsible.Trigger>
                <Collapsible.Panel hiddenUntilFound>
                    <p>
                        This is the hidden treasure that can be found via
                        the browser&apos;s built-in page search even while
                        the panel is collapsed.
                    </p>
                </Collapsible.Panel>
            </Collapsible.Root>
        </div>
    );
};
Controlled story ok
const Controlled = function Controlled() {
    const [ open, setOpen ] = useState( false );
    return (
        <Collapsible.Root open={ open } onOpenChange={ setOpen }>
            <Collapsible.Trigger>
                { open ? 'Close' : 'Open' }
            </Collapsible.Trigger>
            <Collapsible.Panel>
                <p>Controlled collapsible panel.</p>
            </Collapsible.Panel>
        </Collapsible.Root>
    );
};

CollapsibleCard.Root

design-system-components-collapsiblecard · ../packages/ui/src/collapsible-card/stories/index.story.tsx
A card that can be expanded and collapsed. When collapsed, only the header is visible. ```jsx import { CollapsibleCard, Card } from '@wordpress/ui'; function MyComponent() { return ( <CollapsibleCard.Root defaultOpen> <CollapsibleCard.Header> <Card.Title>Heading</Card.Title> </CollapsibleCard.Header> <CollapsibleCard.Content> <p>Collapsible content here.</p> </CollapsibleCard.Content> </CollapsibleCard.Root> ); } ```
Prop types 8 prop types
Component: ../packages/ui/src/collapsible-card/root.tsx::Root
Props:
/**
 * The content to be rendered inside the collapsible card.
 * Should include `CollapsibleCard.Header` and `CollapsibleCard.Content`.
 */
children?: ReactNode

/**
 * CSS class name to apply to the element.
 */
className?: string

/**
 * Whether the collapsible panel is initially open (uncontrolled).
 * @default false
 */
defaultOpen?: boolean

/**
 * Whether the component should ignore user interaction.
 * @default false
 */
disabled?: boolean

/**
 * Event handler called when the panel is opened or closed.
 */
onOpenChange?: ( open: boolean ) => void

/**
 * Whether the collapsible panel is currently open (controlled).
 * 
 * To render an uncontrolled collapsible card, use `defaultOpen` instead.
 */
open?: boolean

/**
 * Replaces the component's default HTML element using a given React
 * element, or a function that returns a React element.
 */
render?: | ComponentRenderFn< HTMLAttributesWithRef >
| React.ReactElement< Record< string, unknown > >

/**
 * CSS style to apply to the element.
 */
style?: React.CSSProperties
Imports
import { Content, FullBleed, Header, Root, Title, HeaderDescription, Stack } from "@wordpress/ui";
Default story ok
A collapsible card that is open by default.
const Default = () => <CollapsibleCard.Root>(<>
        <CollapsibleCard.Header>
            <Card.Title>
                Collapsible card (closed by default)
            </Card.Title>
        </CollapsibleCard.Header>
        <CollapsibleCard.Content>
            <Text>
                This is the collapsible content area. It can contain any
                elements, just like a regular Card.Content.
            </Text>
            <Text>
                When collapsed, only the header and chevron are visible.
            </Text>
        </CollapsibleCard.Content>
    </>)</CollapsibleCard.Root>;
Initially Opened story ok
A collapsible card that starts collapsed.
const InitiallyOpened = () => <CollapsibleCard.Root defaultOpen>(<>
        <CollapsibleCard.Header>
            <Card.Title>Collapsed by default</Card.Title>
        </CollapsibleCard.Header>
        <CollapsibleCard.Content>
            <Text>This content was hidden until you expanded it.</Text>
        </CollapsibleCard.Content>
    </>)</CollapsibleCard.Root>;
Disabled story ok
A disabled collapsible card cannot be toggled by the user.
const Disabled = () => <CollapsibleCard.Root disabled>(<>
        <CollapsibleCard.Header>
            <Card.Title>Disabled card</Card.Title>
        </CollapsibleCard.Header>
        <CollapsibleCard.Content>
            <Text>The header is not interactive when disabled.</Text>
        </CollapsibleCard.Content>
    </>)</CollapsibleCard.Root>;
Stacked story ok
Multiple collapsible cards stacked vertically, simulating a typical settings-panel or FAQ-style layout.
const Stacked = () => (
    <div
        style={ {
            display: 'flex',
            flexDirection: 'column',
            gap: 'var(--wpds-dimension-gap-lg)',
        } }
    >
        { [
            'General',
            'Advanced',
            'Accessibility',
            'Performance',
            'Privacy',
            'Notifications',
        ].map( ( title ) => (
            <CollapsibleCard.Root key={ title }>
                <CollapsibleCard.Header>
                    <Card.Title>{ title }</Card.Title>
                </CollapsibleCard.Header>
                <CollapsibleCard.Content>
                    <Text>
                        Configure all { title.toLowerCase() } settings for
                        your site. Changes here affect how your site behaves
                        across all pages and posts.
                    </Text>
                    <Text>
                        Review each option carefully before saving. Some
                        changes may require a page reload to take effect.
                        Hover over individual options for more details about
                        what they control.
                    </Text>
                    <Text>
                        If you&apos;re unsure about a setting, you can
                        always reset to defaults using the button at the
                        bottom of this section. Your previous configuration
                        will be saved as a backup.
                    </Text>
                </CollapsibleCard.Content>
            </CollapsibleCard.Root>
        ) ) }
    </div>
);
With Heading Element story ok
`CollapsibleCard.Header` renders a `<div>` wrapper by default. Pass an `<h1>`–`<h6>` React element to the `render` prop to wrap the trigger in a heading and contribute to the document outline. The right level depends on the surrounding outline, so the consumer is expected to opt in.
const WithHeadingElement = () => (
    <div
        style={ {
            display: 'flex',
            flexDirection: 'column',
            gap: 'var(--wpds-dimension-gap-lg)',
        } }
    >
        <CollapsibleCard.Root>
            <CollapsibleCard.Header render={ <h2 /> }>
                <Card.Title>Heading level 2</Card.Title>
            </CollapsibleCard.Header>
            <CollapsibleCard.Content>
                <Text>
                    The wrapper renders as an h2 element when the consumer
                    passes an h2 React element to the render prop.
                </Text>
            </CollapsibleCard.Content>
        </CollapsibleCard.Root>
        <CollapsibleCard.Root>
            <CollapsibleCard.Header render={ <h3 /> }>
                <Card.Title>Heading level 3</Card.Title>
            </CollapsibleCard.Header>
            <CollapsibleCard.Content>
                <Text>
                    Pass any of h1–h6 to choose the level that fits the
                    surrounding document outline.
                </Text>
            </CollapsibleCard.Content>
        </CollapsibleCard.Root>
        <CollapsibleCard.Root>
            <CollapsibleCard.Header>
                <Card.Title>No heading (default)</Card.Title>
            </CollapsibleCard.Header>
            <CollapsibleCard.Content>
                <Text>
                    Without a render prop, the header wraps the trigger in a
                    plain div and does not contribute to the document
                    outline.
                </Text>
            </CollapsibleCard.Content>
        </CollapsibleCard.Root>
    </div>
);
With Header Description story ok
A collapsible card with a `HeaderDescription` that provides supplementary information (e.g. status, summary) as an `aria-describedby` relationship.
const WithHeaderDescription = ( { open, defaultOpen, onOpenChange, disabled, ...restArgs } ) => (
    <CollapsibleCard.Root
        open={ open }
        defaultOpen={ defaultOpen }
        onOpenChange={ onOpenChange }
        disabled={ disabled }
        { ...restArgs }
    >
        <CollapsibleCard.Header>
            <Stack justify="space-between">
                <Card.Title>Settings</Card.Title>
                <CollapsibleCard.HeaderDescription>
                    <span
                        style={ {
                            fontSize: 'var(--wpds-typography-font-size-sm)',
                            color: 'var(--wpds-color-fg-content-neutral-weak)',
                        } }
                    >
                        3 items configured
                    </span>
                </CollapsibleCard.HeaderDescription>
            </Stack>
        </CollapsibleCard.Header>
        <CollapsibleCard.Content>
            <Text>
                The header description provides supplementary context to the
                trigger button. Assistive technologies will announce the
                description alongside the button label.
            </Text>
        </CollapsibleCard.Content>
    </CollapsibleCard.Root>
);
Compared To Card story ok
Visual comparison: a `CollapsibleCard` (open) next to a regular `Card` to verify identical spacing and layout.
const ComparedToCard = ( { open, defaultOpen, onOpenChange, disabled, ...restArgs } ) => (
    <div
        style={ {
            display: 'flex',
            flexDirection: 'column',
            gap: 'var( --wpds-dimension-gap-lg )',
        } }
    >
        <CollapsibleCard.Root
            open={ open }
            defaultOpen={ defaultOpen }
            onOpenChange={ onOpenChange }
            disabled={ disabled }
            { ...restArgs }
        >
            <CollapsibleCard.Header>
                <Card.Title>CollapsibleCard (open)</Card.Title>
            </CollapsibleCard.Header>
            <CollapsibleCard.Content>
                <Text>
                    Content should align with the regular card below.
                </Text>
            </CollapsibleCard.Content>
        </CollapsibleCard.Root>
        <Card.Root { ...restArgs }>
            <Card.Header>
                <Card.Title>Regular Card</Card.Title>
            </Card.Header>
            <Card.Content>
                <Text>
                    Content should align with the collapsible card above.
                </Text>
            </Card.Content>
        </Card.Root>
    </div>
);
Full Bleed Cover With Header story ok
When `Card.FullBleed` is the sole child of `CollapsibleCard.Content` and a header sits above it, the media bumps against the card&apos;s side and bottom edges while the header retains its normal padding. (Unlike a plain `Card`, a header is always required here for the collapse trigger — see `Card` stories for a body-only `FullBleedCoverOnly` example.)
const FullBleedCoverWithHeader = () => <CollapsibleCard.Root defaultOpen>(<>
        <CollapsibleCard.Header>
            <Card.Title>Card title</Card.Title>
        </CollapsibleCard.Header>
        <CollapsibleCard.Content>
            <Card.FullBleed>
                <div
                    style={ {
                        height: 180,
                        background:
                            'linear-gradient(135deg, #f093fb 0%, #f5576c 100%)',
                    } }
                />
            </Card.FullBleed>
        </CollapsibleCard.Content>
    </>)</CollapsibleCard.Root>;
With Full Bleed story ok
`Card.FullBleed` breaks out of the content padding to span edge-to-edge. Useful for images, dividers, or embedded content inside the collapsible region.
const WithFullBleed = () => <CollapsibleCard.Root defaultOpen>(<>
        <CollapsibleCard.Header>
            <Card.Title>Featured image</Card.Title>
        </CollapsibleCard.Header>
        <CollapsibleCard.Content
            render={ <Stack direction="column" gap="lg" /> }
        >
            <Card.FullBleed>
                <div
                    style={ {
                        height: 160,
                        background:
                            'linear-gradient(135deg, #667eea 0%, #764ba2 100%)',
                    } }
                />
            </Card.FullBleed>
            <Text>Content below the full-bleed area.</Text>
        </CollapsibleCard.Content>
    </>)</CollapsibleCard.Root>;

ColorIndicator

components-colorindicator · ../packages/components/src/color-indicator/stories/index.story.tsx
ColorIndicator is a React component that renders a specific color in a circle. It's often used to summarize a collection of used colors in a child component. ```jsx import { ColorIndicator } from '@wordpress/components'; const MyColorIndicator = () => <ColorIndicator colorValue="#0073aa" />; ```
Imports
import { ColorIndicator } from "@wordpress/components";
Default story ok
const Default = () => <ColorIndicator colorValue="#0073aa" />;

ColorPalette

components-colorpalette · ../packages/components/src/color-palette/stories/index.story.tsx
Allows the user to pick a color from a list of pre-defined color entries. ```jsx import { ColorPalette } from '@wordpress/components'; import { useState } from '@wordpress/element'; const MyColorPalette = () => { const [ color, setColor ] = useState ( '#f00' ) const colors = [ { name: 'red', color: '#f00' }, { name: 'white', color: '#fff' }, { name: 'blue', color: '#00f' }, ]; return ( <ColorPalette colors={ colors } value={ color } onChange={ ( color ) => setColor( color ) } /> ); } ); ```
Imports
import { ColorPalette } from "@wordpress/components";
Default story ok
const Default = () => {
    const [ color, setColor ] = useState< string | undefined >( value );
    const [ slug, setSlug ] = useState< string | undefined >( selectedSlug );

    return (
        <ColorPalette
            colors={[
                { name: 'Red', color: '#f00' },
                { name: 'White', color: '#fff' },
                { name: 'Blue', color: '#00f' },
            ]}
            value={ color }
            selectedSlug={ slug }
            onChange={ ( newColor, index, newSlug ) => {
				setColor( newColor );
				setSlug( newSlug );
				onChange?.( newColor, index, newSlug );
			} } />
    );
};
Initial Value story ok
const InitialValue = () => {
    const [ color, setColor ] = useState< string | undefined >( value );
    const [ slug, setSlug ] = useState< string | undefined >( selectedSlug );

    return (
        <ColorPalette
            colors={[
                { name: 'Red', color: '#f00' },
                { name: 'White', color: '#fff' },
                { name: 'Blue', color: '#00f' },
            ]}
            value={ color }
            selectedSlug={ slug }
            onChange={ ( newColor, index, newSlug ) => {
				setColor( newColor );
				setSlug( newSlug );
				onChange?.( newColor, index, newSlug );
			} } />
    );
};
Multiple Origins story ok
const MultipleOrigins = () => {
    const [ color, setColor ] = useState< string | undefined >( value );
    const [ slug, setSlug ] = useState< string | undefined >( selectedSlug );

    return (
        <ColorPalette
            colors={[
                {
                    name: 'Primary colors',
                    colors: [
                        { name: 'Red', color: '#f00' },
                        { name: 'Yellow', color: '#ff0' },
                        { name: 'Blue', color: '#00f' },
                    ],
                },
                {
                    name: 'Secondary colors',
                    colors: [
                        { name: 'Orange', color: '#f60' },
                        { name: 'Green', color: '#0f0' },
                        { name: 'Purple', color: '#60f' },
                    ],
                },
            ]}
            value={ color }
            selectedSlug={ slug }
            onChange={ ( newColor, index, newSlug ) => {
				setColor( newColor );
				setSlug( newSlug );
				onChange?.( newColor, index, newSlug );
			} } />
    );
};
Duplicate Colors story ok
const DuplicateColors = () => {
    const [ color, setColor ] = useState< string | undefined >( value );
    const [ slug, setSlug ] = useState< string | undefined >( selectedSlug );

    return (
        <ColorPalette
            colors={[
                { name: 'Dark Background', slug: 'dark-background', color: '#000' },
                { name: 'Dark Text', slug: 'dark-text', color: '#000' },
                { name: 'Brand', slug: 'brand', color: '#0073aa' },
            ]}
            value={ color }
            selectedSlug={ slug }
            onChange={ ( newColor, index, newSlug ) => {
				setColor( newColor );
				setSlug( newSlug );
				onChange?.( newColor, index, newSlug );
			} } />
    );
};
CSS Variables story ok
const CSSVariables = () => <div
    style={ {
        '--red': '#f00',
        '--yellow': '#ff0',
        '--blue': '#00f',
    } }>
    <Template
        colors={[
			{ name: 'Red', color: 'var(--red)' },
			{ name: 'Yellow', color: 'var(--yellow)' },
			{ name: 'Blue', color: 'var(--blue)' },
		]} />
</div>;

ColorPicker

components-colorpicker · ../packages/components/src/color-picker/stories/index.story.tsx
Info
No description found. Write a jsdoc comment such as /** Component description */.
Imports
import { ColorPicker } from "@wordpress/components";
Default story ok
const Default = () => <ColorPicker onChange={fn()} />;

ComboboxControl

components-comboboxcontrol · ../packages/components/src/combobox-control/stories/index.story.tsx
`ComboboxControl` is an enhanced version of a [`SelectControl`](../select-control/README.md) with the addition of being able to search for options using a search input. ```jsx import { ComboboxControl } from '@wordpress/components'; import { useState } from '@wordpress/element'; const options = [ { value: 'small', label: 'Small', }, { value: 'normal', label: 'Normal', disabled: true, }, { value: 'large', label: 'Large', disabled: false, }, ]; function MyComboboxControl() { const [ fontSize, setFontSize ] = useState(); const [ filteredOptions, setFilteredOptions ] = useState( options ); return ( <ComboboxControl __next40pxDefaultSize label="Font Size" value={ fontSize } onChange={ setFontSize } options={ filteredOptions } onFilterValueChange={ ( inputValue ) => setFilteredOptions( options.filter( ( option ) => option.label .toLowerCase() .startsWith( inputValue.toLowerCase() ) ) ) } /> ); } ```
Prop types 12 prop types
Component: ../packages/components/src/combobox-control/index.tsx::default
Props:
/**
 * Custom renderer invoked for each option in the suggestion list.
 * The render prop receives as its argument an object containing, under the `item` key,
 * the single option's data (directly from the array of data passed to the `options` prop).
 */
__experimentalRenderItem?: ( args: {
	item: ComboboxControlOption;
} ) => React.ReactNode

/**
 * Deprecated. Use `__next40pxDefaultSize` instead.
 * 
 * @default false
 * @deprecated
 * @ignore
 */
__next36pxDefaultSize?: boolean

/**
 * Start opting into the larger default height that will become the default size in a future version.
 * 
 * @default false
 */
__next40pxDefaultSize?: boolean

/**
 * Show a reset button to clear the input.
 * 
 * @default true
 */
allowReset?: boolean

/**
 * Automatically expand the dropdown when the control is focused.
 * If the control is clicked, the dropdown will expand regardless of this prop.
 * 
 * @default true
 */
expandOnFocus?: boolean

/**
 * Show a spinner (and hide the suggestions dropdown) while data
 * about the matching suggestions (ie the `options` prop) is loading
 * 
 * @default false
 */
isLoading?: boolean

/**
 * Customizable UI messages.
 */
messages?: {
	/**
	 * The message to announce to screen readers when a suggestion is selected.
	 *
	 * @default `__( 'Item selected.' )`
	 */
	selected: string;
}

/**
 * Function called with the selected value changes.
 */
onChange?: ( value: ComboboxControlProps[ 'value' ] ) => void

/**
 * Function called when the control's search input value changes. The argument contains the next input value.
 * 
 * @default noop
 */
onFilterValueChange?: ( value: string ) => void

/**
 * The options that can be chosen from.
 */
options: ComboboxControlOption[]

/**
 * If passed, the combobox input will show a placeholder string if no values are present.
 */
placeholder?: string

/**
 * The current value of the control.
 */
value?: string | null
Imports
import { ComboboxControl } from "@wordpress/components";
Default story ok
const Default = () => {
    const [ value, setValue ] =
		useState< ComboboxControlProps[ 'value' ] >( null );

    return (
        <>
            <ComboboxControl
                __next40pxDefaultSize
                onFilterValueChange={fn()}
                label="Country"
                options={countryOptions}
                help="Help text to describe the control."
                value={ value }
                onChange={ ( ...changeArgs ) => {
					setValue( ...changeArgs );
					onChange?.( ...changeArgs );
				} } />
        </>
    );
};
With Custom Render Item story ok
The rendered output of each suggestion can be customized by passing a render function to the `__experimentalRenderItem` prop. (This is still an experimental feature and is subject to change.)
const WithCustomRenderItem = () => {
    const [ value, setValue ] =
		useState< ComboboxControlProps[ 'value' ] >( null );

    return (
        <>
            <ComboboxControl
                __next40pxDefaultSize
                onFilterValueChange={fn()}
                label="Author"
                options={[
                    {
                        value: 'parsley',
                        label: 'Parsley Montana',
                        age: 48,
                        country: 'Germany',
                    },
                    {
                        value: 'cabbage',
                        label: 'Cabbage New York',
                        age: 44,
                        country: 'France',
                    },
                    {
                        value: 'jake',
                        label: 'Jake Weary',
                        age: 41,
                        country: 'United Kingdom',
                    },
                ]}
                __experimentalRenderItem={( { item } ) => {
                    const { label, age, country } = item;
                    return (
                        <div>
                            <div style={ { marginBottom: '0.2rem' } }>{ label }</div>
                            <small>
                                Age: { age }, Country: { country }
                            </small>
                        </div>
                    );
                }}
                value={ value }
                onChange={ ( ...changeArgs ) => {
					setValue( ...changeArgs );
					onChange?.( ...changeArgs );
				} } />
        </>
    );
};
With Disabled Options story ok
You can disable options in the list by setting the `disabled` property to true for individual items in the option object.
const WithDisabledOptions = () => {
    const [ value, setValue ] =
		useState< ComboboxControlProps[ 'value' ] >( null );

    return (
        <>
            <ComboboxControl
                __next40pxDefaultSize
                onFilterValueChange={fn()}
                options={optionsWithDisabledOptions}
                value={ value }
                onChange={ ( ...changeArgs ) => {
					setValue( ...changeArgs );
					onChange?.( ...changeArgs );
				} } />
        </>
    );
};
Not Expand On Focus story ok
By default, the combobox expands when focused. You can disable this behavior by setting the `expandOnFocus` prop to `false`. This is useful when you want to show the suggestions only when the user interacts with the input.
const NotExpandOnFocus = () => {
    const [ value, setValue ] =
		useState< ComboboxControlProps[ 'value' ] >( null );

    return (
        <>
            <ComboboxControl
                __next40pxDefaultSize
                onFilterValueChange={fn()}
                options={countryOptions}
                expandOnFocus={false}
                value={ value }
                onChange={ ( ...changeArgs ) => {
					setValue( ...changeArgs );
					onChange?.( ...changeArgs );
				} } />
        </>
    );
};

Composite

components-composite · ../packages/components/src/composite/stories/index.story.tsx
Renders a widget based on the WAI-ARIA [`composite`](https://w3c.github.io/aria/#composite) role, which provides a single tab stop on the page and arrow key navigation through the focusable descendants.
example: ```jsx import { Composite } from '@wordpress/components'; <Composite> <Composite.Item>Item 1</Composite.Item> <Composite.Item>Item 2</Composite.Item> </Composite> ```
Prop types 7 prop types
Component: ../packages/components/src/composite/index.tsx::Composite
Props:
disabled?: any = false

focusLoop?: any = false

focusShift?: any = false

focusWrap?: any = false

orientation?: any = 'both'

rtl?: any = isRTL()

virtualFocus?: any = false
Imports
import { Composite, Provider as SlotFillProvider, Tooltip } from "@wordpress/components";
Default story ok
const Default = () => <Composite>(<>
        <Composite.Item>Item one</Composite.Item>
        <Composite.Item>Item two</Composite.Item>
        <Composite.Item>Item three</Composite.Item>
    </>)</Composite>;
Groups story ok
const Groups = () => <Composite>(<>
        <Composite.Group>
            <Composite.GroupLabel>Group one</Composite.GroupLabel>
            <Composite.Item>Item 1.1</Composite.Item>
            <Composite.Item>Item 1.2</Composite.Item>
        </Composite.Group>
        <Composite.Group>
            <Composite.GroupLabel>Group two</Composite.GroupLabel>
            <Composite.Item>Item 2.1</Composite.Item>
            <Composite.Item>Item 2.1</Composite.Item>
        </Composite.Group>
    </>)</Composite>;
Grid story ok
const Grid = () => <Composite role="grid" aria-label="Composite">(<>
        <Composite.Row role="row">
            <Composite.Item role="gridcell">Item A1</Composite.Item>
            <Composite.Item role="gridcell">Item A2</Composite.Item>
            <Composite.Item role="gridcell">Item A3</Composite.Item>
        </Composite.Row>
        <Composite.Row role="row">
            <Composite.Item role="gridcell">Item B1</Composite.Item>
            <Composite.Item role="gridcell">Item B2</Composite.Item>
            <Composite.Item role="gridcell">Item B3</Composite.Item>
        </Composite.Row>
        <Composite.Row role="row">
            <Composite.Item role="gridcell">Item C1</Composite.Item>
            <Composite.Item role="gridcell">Item C2</Composite.Item>
            <Composite.Item role="gridcell">Item C3</Composite.Item>
        </Composite.Row>
    </>)</Composite>;
Hover story ok
const Hover = () => <Composite>(<>
        <Composite.Hover render={ <Composite.Item /> }>
            Hover item one
        </Composite.Hover>
        <Composite.Hover render={ <Composite.Item /> }>
            Hover item two
        </Composite.Hover>
        <Composite.Hover render={ <Composite.Item /> }>
            Hover item three
        </Composite.Hover>
    </>)</Composite>;
Typeahead story ok
const Typeahead = () => <Composite render={<Composite.Typeahead />}>(<>
        <Composite.Item>Apple</Composite.Item>
        <Composite.Item>Banana</Composite.Item>
        <Composite.Item>Peach</Composite.Item>
    </>)</Composite>;
With Slot Fill story ok
const WithSlotFill = () => <Composite>(<>
        <Composite.Item>Item one (direct child)</Composite.Item>
        <Slot />
        <Composite.Item>Item four (direct child)</Composite.Item>
    </>)</Composite>;
With Tooltips story ok
Combining the `Tooltip` and `Composite` component has a few caveats. And while there are a few ways to compose these two components, our recommendation is to render `Composite.Item` as a child of `Tooltip`. ```jsx // 🔴 Does not work <Composite.Item render={ <Tooltip text="Tooltip"> <button>Item</button> </Tooltip> } /> // 🟢 Good <Tooltip text="Tooltip one"> <Composite.Item> Item one </Composite.Item> </Tooltip> ```
const WithTooltips = () => <Composite>(<>
        <Tooltip text="Tooltip one">
            <Composite.Item>Item one</Composite.Item>
        </Tooltip>
        <Tooltip text="Tooltip two">
            <Composite.Item>Item two</Composite.Item>
        </Tooltip>
        <Tooltip text="Tooltip three">
            <Composite.Item>Item three</Composite.Item>
        </Tooltip>
    </>)</Composite>;

ConfirmDialog

components-confirmdialog · ../packages/components/src/confirm-dialog/stories/index.story.tsx
Info
No description found. Write a jsdoc comment such as /** Component description */.
Imports
import { Button, ConfirmDialog } from "@wordpress/components";
Default story ok
const Default = () => {
    const [ isOpen, setIsOpen ] = useState( false );

    const handleConfirm: typeof onConfirm = ( confirmArgs ) => {
		onConfirm( confirmArgs );
		setIsOpen( false );
	};

    const handleCancel: typeof onCancel = ( cancelArgs ) => {
		onCancel?.( cancelArgs );
		setIsOpen( false );
	};

    return (
        <>
            <Button
                __next40pxDefaultSize
                variant="primary"
                onClick={ () => setIsOpen( true ) }>Open ConfirmDialog
                            </Button>
            <ConfirmDialog isOpen={ isOpen } onConfirm={ handleConfirm } onCancel={ handleCancel }>
                Would you like to privately publish the post now?
            </ConfirmDialog>
        </>
    );
};
With Custom Button Labels story ok
const WithCustomButtonLabels = () => {
    const [ isOpen, setIsOpen ] = useState( false );

    const handleConfirm: typeof onConfirm = ( confirmArgs ) => {
		onConfirm( confirmArgs );
		setIsOpen( false );
	};

    const handleCancel: typeof onCancel = ( cancelArgs ) => {
		onCancel?.( cancelArgs );
		setIsOpen( false );
	};

    return (
        <>
            <Button
                __next40pxDefaultSize
                variant="primary"
                onClick={ () => setIsOpen( true ) }>Open ConfirmDialog
                            </Button>
            <ConfirmDialog
                cancelButtonText="No thanks"
                confirmButtonText="Yes please!"
                isOpen={ isOpen }
                onConfirm={ handleConfirm }
                onCancel={ handleCancel }>
                { args.children }
            </ConfirmDialog>
        </>
    );
};

CustomSelectControl

components-customselectcontrol · ../packages/components/src/custom-select-control/stories/index.story.tsx
Info
No description found. Write a jsdoc comment such as /** Component description */.
Prop types 17 prop types
Component: ../packages/components/src/custom-select-control/index.tsx::default
Props:
/**
 * Use the `showSelectedHint` property instead.
 * @deprecated
 * @ignore
 */
__experimentalShowSelectedHint?: boolean

/**
 * Start opting into the larger default height that will become the default size in a future version.
 * 
 * @default false
 */
__next40pxDefaultSize?: boolean

/**
 * Opt-in prop for an unconstrained width style which became the default in
 * WordPress 6.5. The prop is no longer needed and can be safely removed.
 * 
 * @deprecated
 * @ignore
 */
__nextUnconstrainedWidth?: boolean

/**
 * Do not throw a warning for the deprecated 36px default size.
 * For internal components of other components that already throw the warning.
 * 
 * @ignore
 */
__shouldNotWarnDeprecated36pxSize?: boolean

/**
 * Optional classname for the component.
 */
className?: string

/**
 * Description for the select trigger button used by assistive technology.
 * If no value is passed, the text "Currently selected: selectedItem.name"
 * will be used fully translated.
 */
describedBy?: string

/**
 * Hide the label visually, while keeping available to assistive technology.
 */
hideLabelFromVision?: boolean

/**
 * Label for the control.
 */
label: string

/**
 * A handler for `blur` events on the trigger button.
 * 
 * @ignore
 */
onBlur?: FocusEventHandler< HTMLButtonElement >

/**
 * Function called with the control's internal state changes. The `selectedItem`
 * property contains the next selected item.
 */
onChange?: ( newValue: CustomSelectChangeObject< NoInfer< T > > ) => void

/**
 * A handler for `focus` events on the trigger button.
 * 
 * @ignore
 */
onFocus?: FocusEventHandler< HTMLButtonElement >

/**
 * A handler for `mouseout` events on the trigger button.
 * 
 * @ignore
 */
onMouseOut?: MouseEventHandler< HTMLButtonElement >

/**
 * A handler for `mouseover` events on the trigger button.
 * 
 * @ignore
 */
onMouseOver?: MouseEventHandler< HTMLButtonElement >

/**
 * The list of options that can be chosen from.
 */
options: ReadonlyArray< T >

/**
 * Show the hint of the selected item in the trigger button.
 * 
 * @default false
 */
showSelectedHint?: boolean

/**
 * The size of the control.
 * 
 * @default 'default'
 */
size?: 'default' | 'small' | '__unstable-large'

/**
 * Can be used to externally control the value of the control.
 */
value?: NoInfer< T >
Imports
import { CustomSelectControl } from "@wordpress/components";
Default story ok
const Default = ( props ) => {
	const [ value, setValue ] = useState( props.options[ 0 ] );

	const onChange: React.ComponentProps<
		typeof CustomSelectControl
	>[ 'onChange' ] = ( changeObject ) => {
		setValue( changeObject.selectedItem );
		props.onChange?.( changeObject );
	};

	return (
		<CustomSelectControl
			__next40pxDefaultSize
			{ ...props }
			onChange={ onChange }
			value={ value }
		/>
	);
};
With Long Labels story ok
const WithLongLabels = ( props ) => {
	const [ value, setValue ] = useState( props.options[ 0 ] );

	const onChange: React.ComponentProps<
		typeof CustomSelectControl
	>[ 'onChange' ] = ( changeObject ) => {
		setValue( changeObject.selectedItem );
		props.onChange?.( changeObject );
	};

	return (
		<CustomSelectControl
			__next40pxDefaultSize
			{ ...props }
			onChange={ onChange }
			value={ value }
		/>
	);
};
With Hints story ok
const WithHints = ( props ) => {
	const [ value, setValue ] = useState( props.options[ 0 ] );

	const onChange: React.ComponentProps<
		typeof CustomSelectControl
	>[ 'onChange' ] = ( changeObject ) => {
		setValue( changeObject.selectedItem );
		props.onChange?.( changeObject );
	};

	return (
		<CustomSelectControl
			__next40pxDefaultSize
			{ ...props }
			onChange={ onChange }
			value={ value }
		/>
	);
};

Disabled

components-disabled · ../packages/components/src/disabled/stories/index.story.tsx
`Disabled` is a component which disables descendant tabbable elements and prevents pointer interaction. _Note: this component may not behave as expected in browsers that don't support the `inert` HTML attribute. We recommend adding the official WICG polyfill when using this component in your project._
see: https://developer.mozilla.org/en-US/docs/Web/API/HTMLElement/inert ```jsx import { Button, Disabled, TextControl } from '@wordpress/components'; import { useState } from '@wordpress/element'; const MyDisabled = () => { const [ isDisabled, setIsDisabled ] = useState( true ); let input = ( <TextControl __next40pxDefaultSize label="Input" onChange={ () => {} } /> ); if ( isDisabled ) { input = <Disabled>{ input }</Disabled>; } const toggleDisabled = () => { setIsDisabled( ( state ) => ! state ); }; return ( <div> { input } <Button variant="primary" onClick={ toggleDisabled }> Toggle Disabled </Button> </div> ); }; ```
Prop types 1 prop type
Component: ../packages/components/src/disabled/index.tsx::default
Props:
isDisabled?: any = true
Imports
import { Disabled, SelectControl, TextareaControl, TextControl, VStack } from "@wordpress/components";
Default story ok
const Default = () => {
    return (
        <Disabled isDisabled>
            <Form />
        </Disabled>
    );
};
Content Editable story ok
const ContentEditable = () => {
    return (
        <Disabled isDisabled>
            <div contentEditable tabIndex={ 0 } suppressContentEditableWarning>contentEditable
                            </div>
        </Disabled>
    );
};

Dropdown

components-dropdown · ../packages/components/src/dropdown/stories/index.story.tsx
Info
No description found. Write a jsdoc comment such as /** Component description */.
Prop types 14 prop types
Component: ../packages/components/src/dropdown/index.tsx
Props:
/**
 * The className of the global container.
 */
className?: string

/**
 * If you want to target the dropdown menu for styling purposes,
 * you need to provide a contentClassName because it's not being rendered
 * as a child of the container node.
 */
contentClassName?: string

/**
 * The open state of the dropdown when initially rendered.
 * Use when you do not need to control its open state. It will be overridden
 * by the `open` prop if it is specified on the component's first render.
 */
defaultOpen?: boolean

/**
 * Opt-in prop to show popovers fullscreen on mobile.
 * 
 * @default false
 */
expandOnMobile?: boolean

/**
 * Determines focus behavior when the dialog mounts.
 * 
 * - `"firstElement"` focuses the first tabbable element within.
 * - `"firstInputElement"` focuses the first value control within.
 * - `true` focuses the element itself.
 * - `false` does nothing and _should not be used unless an accessible
 *    substitute behavior is implemented_.
 * 
 * @default 'firstElement'
 */
focusOnMount?: useFocusOnMount.Mode

/**
 * Set this to customize the text that is shown in the dropdown's header
 * when it is fullscreen on mobile.
 */
headerTitle?: string

/**
 * A callback invoked when the popover should be closed.
 */
onClose?: () => void

/**
 * A callback invoked when the state of the dropdown changes
 * from open to closed and vice versa.
 */
onToggle?: ( willOpen: boolean ) => void

/**
 * The controlled open state of the dropdown.
 * Must be used in conjunction with `onToggle`.
 */
open?: boolean

/**
 * Properties of popoverProps object will be passed as props
 * to the Popover component.
 * Use this object to access properties/features
 * of the Popover component that are not already exposed
 * in the Dropdown component,
 * e.g.: the ability to have the popover without an arrow.
 */
popoverProps?: Omit<
	ComponentPropsWithoutRef< typeof Popover >,
	'children'
>

/**
 * Legacy way to specify the popover's position with respect to its anchor.
 * For details about the possible values, see the `Popover` component's docs.
 * _Note: this prop is deprecated. Use the `popoverProps.placement` prop
 * instead._
 * 
 * @deprecated
 */
position?: PopoverProps[ 'position' ]

/**
 * A callback invoked to render the content of the dropdown menu.
 * Its first argument is the same as the renderToggle prop.
 */
renderContent: ( props: CallbackProps ) => ReactNode

/**
 * A callback invoked to render the Dropdown Toggle Button.
 * 
 * The first argument of the callback is an object
 * containing the following properties:
 * 
 * - isOpen: whether the dropdown menu is opened or not
 * - onToggle: A function switching the dropdown menu's state
 * from open to closed and vice versa
 * - onClose: A function that closes the menu if invoked
 */
renderToggle: ( props: CallbackProps ) => ReactNode

/**
 * The style of the global container.
 */
style?: CSSProperties
Imports
import { Button, Dropdown, DropdownContentWrapper, MenuGroup, MenuItem } from "@wordpress/components";
Default story ok
const Default = () => <Dropdown
    onClose={fn()}
    onToggle={fn()}
    renderToggle={( { isOpen, onToggle } ) => (
        <Button
            __next40pxDefaultSize
            onClick={ onToggle }
            aria-expanded={ isOpen }
            variant="primary"
        >
            Open dropdown
        </Button>
    )}
    renderContent={() => <div>This is the dropdown content.</div>} />;
With More Padding story ok
To apply more padding to the dropdown content, use the provided `<DropdownContentWrapper>` convenience wrapper. A `paddingSize` of `"medium"` is suitable for relatively larger dropdowns (default is `"small"`).
const WithMorePadding = () => <Dropdown
    onClose={fn()}
    onToggle={fn()}
    renderContent={() => (
        <DropdownContentWrapper paddingSize="medium">
            { /* eslint-disable react/no-unescaped-entities */ }
            Content wrapped with <code>paddingSize="medium"</code>.
            { /* eslint-enable react/no-unescaped-entities */ }
        </DropdownContentWrapper>
    )} />;
With No Padding story ok
The `<DropdownContentWrapper>` convenience wrapper can also be used to remove padding entirely, with a `paddingSize` of `"none"`. This can also serve as a clean foundation to add arbitrary paddings, for example when child components already have padding on their own.
const WithNoPadding = () => <Dropdown
    onClose={fn()}
    onToggle={fn()}
    renderContent={() => (
        <DropdownContentWrapper paddingSize="none">
            { /* eslint-disable react/no-unescaped-entities */ }
            Content wrapped with <code>paddingSize="none"</code>.
            { /* eslint-enable react/no-unescaped-entities */ }
        </DropdownContentWrapper>
    )} />;
With Menu Items story ok
const WithMenuItems = () => <Dropdown
    onClose={fn()}
    onToggle={fn()}
    renderContent={() => (
        <>
            <MenuItem>Standalone Item</MenuItem>
            <MenuGroup label="Group 1">
                <MenuItem>Item 1</MenuItem>
                <MenuItem>Item 2</MenuItem>
            </MenuGroup>
            <MenuGroup label="Group 2">
                <MenuItem>Item 1</MenuItem>
                <MenuItem>Item 2</MenuItem>
            </MenuGroup>
        </>
    )} />;

DropZone

components-dropzone · ../packages/components/src/drop-zone/stories/index.story.tsx
`DropZone` is a component creating a drop zone area taking the full size of its parent element. It supports dropping files, HTML content or any other HTML drop event. ```jsx import { DropZone } from '@wordpress/components'; import { useState } from '@wordpress/element'; const MyDropZone = () => { const [ hasDropped, setHasDropped ] = useState( false ); return ( <div> { hasDropped ? 'Dropped!' : 'Drop something here' } <DropZone onFilesDrop={ () => setHasDropped( true ) } onHTMLDrop={ () => setHasDropped( true ) } onDrop={ () => setHasDropped( true ) } /> </div> ); } ```
Prop types 2 prop types
Component: ../packages/components/src/drop-zone/index.tsx::DropZoneComponent
Props:
icon?: any = jsx(SVG, { xmlns: "http://www.w3.org/2000/svg", viewBox: "0 0 24 24", children: /* @__PURE__ */ jsx(Path, { d: "M18.5 15v3.5H13V6.7l4.5 4.1 1-1.1-6.2-5.8-5.8 5.8 1 1.1 4-4v11.7h-6V15H4v5h16v-5z" }) })

isEligible?: any = () => true
Imports
import { DropZone } from "@wordpress/components";
Default story ok
const Default = ( props ) => {
	return (
		<div
			style={ {
				background: 'lightgray',
				padding: 32,
				position: 'relative',
			} }
		>
			Drop something here
			<DropZone { ...props } />
		</div>
	);
};

EmptyState.Root

design-system-components-emptystate · ../packages/ui/src/empty-state/stories/index.story.tsx
The root container for an empty state component.
Prop types 4 prop types
Component: ../packages/ui/src/empty-state/root.tsx::Root
Props:
/**
 * The content to be rendered inside the component.
 */
children?: ReactNode

/**
 * CSS class name to apply to the element.
 */
className?: string

/**
 * Replaces the component's default HTML element using a given React
 * element, or a function that returns a React element.
 */
render?: | ComponentRenderFn< HTMLAttributesWithRef >
| React.ReactElement< Record< string, unknown > >

/**
 * CSS style to apply to the element.
 */
style?: React.CSSProperties
Imports
import { Button, Actions, Description, Icon, Root, Title, Visual } from "@wordpress/ui";
Default story ok
const Default = () => <EmptyState.Root>(<>
        <EmptyState.Icon icon={ search } />
        <EmptyState.Title>No results found</EmptyState.Title>
        <EmptyState.Description>
            Try adjusting your search or filter to find what you&apos;re
            looking for.
        </EmptyState.Description>
        <EmptyState.Actions>
            <Button variant="outline">Clear filters</Button>
            <Button>Add item</Button>
        </EmptyState.Actions>
    </>)</EmptyState.Root>;
With Custom Visual story ok
const WithCustomVisual = () => <EmptyState.Root>(<>
        <EmptyState.Visual>
            <svg
                width="50"
                height="50"
                viewBox="0 0 50 50"
                fill="none"
                xmlns="http://www.w3.org/2000/svg"
            >
                <circle cx="25" cy="25" r="25" fill="currentColor" />
            </svg>
        </EmptyState.Visual>
        <EmptyState.Title>All caught up!</EmptyState.Title>
        <EmptyState.Description>
            You&apos;ve completed all your tasks. Great work!
        </EmptyState.Description>
        <EmptyState.Actions>
            <Button>Create new task</Button>
        </EmptyState.Actions>
    </>)</EmptyState.Root>;

FormFileUpload

components-formfileupload · ../packages/components/src/form-file-upload/stories/index.story.tsx
FormFileUpload allows users to select files from their local device. ```jsx import { FormFileUpload } from '@wordpress/components'; const MyFormFileUpload = () => ( <FormFileUpload __next40pxDefaultSize accept="image/*" onChange={ ( event ) => console.log( event.currentTarget.files ) } > Upload </FormFileUpload> ); ```
Prop types 1 prop type
Component: ../packages/components/src/form-file-upload/index.tsx::FormFileUpload
Props:
multiple?: any = false
Imports
import { FormFileUpload } from "@wordpress/components";
Default story ok
const Default = ( props ) => {
	return <FormFileUpload __next40pxDefaultSize { ...props } />;
};
Restrict File Types story ok
const RestrictFileTypes = ( props ) => {
	return <FormFileUpload __next40pxDefaultSize { ...props } />;
};
Allow Multiple Files story ok
const AllowMultipleFiles = ( props ) => {
	return <FormFileUpload __next40pxDefaultSize { ...props } />;
};
With Icon story ok
const WithIcon = ( props ) => {
	return <FormFileUpload __next40pxDefaultSize { ...props } />;
};
With Custom Render story ok
Render a custom trigger button by passing a render function to the `render` prop. ```jsx ( { openFileDialog } ) => <button onClick={ openFileDialog }>Custom Upload Button</button> ```
const WithCustomRender = ( props ) => {
	return <FormFileUpload __next40pxDefaultSize { ...props } />;
};

FormToggle

components-formtoggle · ../packages/components/src/form-toggle/stories/index.story.tsx
FormToggle switches a single setting on or off. ```jsx import { FormToggle } from '@wordpress/components'; import { useState } from '@wordpress/element'; const MyFormToggle = () => { const [ isChecked, setChecked ] = useState( true ); return ( <FormToggle checked={ isChecked } onChange={ () => setChecked( ( state ) => ! state ) } /> ); }; ```
Imports
import { FormToggle } from "@wordpress/components";
Default story ok
const Default = () => {
    const [ isChecked, setChecked ] = useState( true );

    return (
        <FormToggle
            checked={ isChecked }
            onChange={ ( e ) => {
				setChecked( ( state ) => ! state );
				onChange( e );
			} } />
    );
};

FormTokenField

components-formtokenfield · ../packages/components/src/form-token-field/stories/index.story.tsx
A `FormTokenField` is a field similar to the tags and categories fields in the interim editor chrome, or the "to" field in Mail on OS X. Tokens can be entered by typing them or selecting them from a list of suggested tokens. Up to one hundred suggestions that match what the user has typed so far will be shown from which the user can pick from (auto-complete). Tokens are separated by the "," character. Suggestions can be selected with the up or down arrows and added with the tab or enter key. The `value` property is handled in a manner similar to controlled form components. See [Forms](https://react.dev/reference/react-dom/components#form-components) in the React Documentation for more information.
Prop types 25 prop types
Component: ../packages/components/src/form-token-field/index.tsx::FormTokenField
Props:
/**
 * If true, the select the first matching suggestion when the user presses
 * the Enter key (or space when tokenizeOnSpace is true).
 * 
 * @default false
 */
__experimentalAutoSelectFirstMatch?: boolean

/**
 * If true, the suggestions list will be always expanded when the input field has the focus.
 */
__experimentalExpandOnFocus?: boolean

/**
 * Custom renderer for suggestions.
 */
__experimentalRenderItem?: ( args: { item: string } ) => ReactNode

/**
 * Use the `help` prop instead. The `help` prop now defaults to the previous
 * how-to text; if you were passing `__experimentalShowHowTo={ false }` to
 * hide it, pass an empty string to `help` instead.
 * 
 * @deprecated Use the `help` prop instead.
 * @ignore
 */
__experimentalShowHowTo?: boolean

/**
 * If passed, all introduced values will be validated before being added as tokens.
 * 
 * @default () => true
 */
__experimentalValidateInput?: ( token: string ) => boolean

/**
 * Deprecated. Use `__next40pxDefaultSize` instead.
 * 
 * @default false
 * @deprecated
 * @ignore
 */
__next36pxDefaultSize?: boolean

/**
 * Start opting into the larger default height that will become the
 * default size in a future version.
 * 
 * @default false
 */
__next40pxDefaultSize?: boolean

/**
 * Start opting into the new margin-free styles that will become the default in a future version.
 * 
 * @deprecated Default behavior since WP 7.0. Prop can be safely removed.
 * @ignore
 * 
 * @default false
 */
__nextHasNoMarginBottom?: boolean

/**
 * When true, tokens are not able to be added or removed.
 */
disabled?: boolean

/**
 * Function to call to transform tokens for display.
 * (In the editor, this is needed to decode HTML entities embedded in tags
 * - otherwise entities like `&` in tag names are double-encoded like `&amp;`,
 * once by the REST API and once by React).
 */
displayTransform?: ( token: string ) => string

/**
 * Additional description for the control.
 * 
 * Only use for meaningful description or instructions for the control. An
 * element containing the description will be programmatically associated to
 * the `FormTokenField` via `aria-describedby`.
 * 
 * Defaults to a how-to message (e.g. _Separate with commas or the Enter key._);
 * pass an empty string to hide it.
 */
help?: ReactNode

/**
 * When true, renders tokens as without a background.
 */
isBorderless?: boolean

label?: string

/**
 * If passed, `TokenField` will disable ability to add new tokens once number of tokens is greater than or equal to `maxLength`.
 */
maxLength?: number

/**
 * The maximum number of suggestions to display at a time.
 * 
 * @default 100
 */
maxSuggestions?: number

/**
 * Allows customizing the messages presented by screen readers in different occasions:
 * 
 * -   `added`: The user added a new token.
 * -   `removed`: The user removed an existing token.
 * -   `remove` : The user focused the button to remove the token.
 * -   `__experimentalInvalid`: The user tried to add a token that didn't pass the validation.
 */
messages?: {
	/**
	 * The user added a new token.
	 */
	added: string;
	/**
	 * The user removed an existing token.
	 */
	removed: string;
	/**
	 * The user focused the button to remove the token.
	 */
	remove: string;
	/**
	 * The user tried to add a token that didn't pass the validation.
	 */
	__experimentalInvalid: string;
}

/**
 * Function to call when the tokens have changed. An array of new tokens is passed to the callback.
 */
onChange?: ( tokens: ( string | TokenItem )[] ) => void

/**
 * Function to call when the TokenField has been focused on. The event is passed to the callback. Useful for analytics.
 */
onFocus?: ( event: FocusEvent ) => void

/**
 * Function to call when the users types in the input field. It can be used to trigger autocomplete requests.
 */
onInputChange?: ( input: string ) => void

/**
 * If passed, the `TokenField` input will show a placeholder string if no value tokens are present.
 */
placeholder?: string

/**
 * Function to call to transform tokens for saving. The default is to trim the token value.
 * This function is also applied when matching suggestions against the current value
 * so that matching works correctly with leading or trailing spaces. (In the editor,
 * this is needed to remove leading and trailing spaces from tag names, like wp-admin does.
 * Otherwise the REST API won't save them.)
 * 
 * @default ( token: string ) => token.trim()
 */
saveTransform?: ( token: string ) => string

/**
 * An array of strings to present to the user as suggested tokens.
 */
suggestions?: string[]

/**
 * If true, add any incompleteTokenValue as a new token when the field loses focus.
 * 
 * @default false
 */
tokenizeOnBlur?: boolean

/**
 * If true, will add a token when `TokenField` is focused and `space` is pressed.
 */
tokenizeOnSpace?: boolean

/**
 * An array of strings or objects to display as tokens in the field.
 * If objects are present in the array, they **must** have a property of `value`.
 */
value?: ( string | TokenItem )[]
Imports
import { FormTokenField } from "@wordpress/components";
Default story ok
const Default = () => {
    const [ selectedContinents, setSelectedContinents ] = useState<
		ComponentProps< typeof FormTokenField >[ 'value' ]
	>( [] );

    return (
        <FormTokenField
            __next40pxDefaultSize
            label="Type a continent"
            suggestions={continents}
            value={ selectedContinents }
            onChange={ ( tokens ) => setSelectedContinents( tokens ) } />
    );
};
Async story ok
const Async = () => {
    const [ selectedContinents, setSelectedContinents ] = useState<
		ComponentProps< typeof FormTokenField >[ 'value' ]
	>( [] );
    const [ availableContinents, setAvailableContinents ] = useState<
		string[]
	>( [] );

    const searchContinents = ( input: string ) => {
		const timeout = setTimeout( () => {
			const available = ( suggestions || [] ).filter( ( continent ) =>
				continent.toLowerCase().includes( input.toLowerCase() )
			);
			setAvailableContinents( available );
		}, 1000 );

		return () => clearTimeout( timeout );
	};

    return (
        <FormTokenField
            __next40pxDefaultSize
            label="Type a continent"
            value={ selectedContinents }
            suggestions={ availableContinents }
            onChange={ ( tokens ) => setSelectedContinents( tokens ) }
            onInputChange={ searchContinents } />
    );
};
Dropdown Selector story ok
const DropdownSelector = () => {
    const [ selectedContinents, setSelectedContinents ] = useState<
		ComponentProps< typeof FormTokenField >[ 'value' ]
	>( [] );

    return (
        <FormTokenField
            __next40pxDefaultSize
            __experimentalExpandOnFocus
            __experimentalAutoSelectFirstMatch
            value={ selectedContinents }
            onChange={ ( tokens ) => setSelectedContinents( tokens ) } />
    );
};
With Custom Rendered Items story ok
The rendered content of each token can be customized by passing a render function to the `displayTransform` prop. Similarly, each suggestion can be customized by passing a render function to the `__experimentalRenderItem` prop. (This is still an experimental feature and is subject to change.)
const WithCustomRenderedItems = () => {
    const [ selectedContinents, setSelectedContinents ] = useState<
		ComponentProps< typeof FormTokenField >[ 'value' ]
	>( [] );

    return (
        <FormTokenField
            __next40pxDefaultSize
            displayTransform={( token ) => `📍 ${ token }`}
            __experimentalRenderItem={( { item } ) => (
                <div>{ `${ item } — a nice place to visit` }</div>
            )}
            __experimentalExpandOnFocus
            value={ selectedContinents }
            onChange={ ( tokens ) => setSelectedContinents( tokens ) } />
    );
};
Validate New Tokens story ok
Only values for which the `__experimentalValidateInput` function returns `true` will be tokenized. (This is still an experimental feature and is subject to change.) In this example, the user can only add tokens that are already in the list.
const ValidateNewTokens = () => {
    const [ selectedContinents, setSelectedContinents ] = useState<
		ComponentProps< typeof FormTokenField >[ 'value' ]
	>( [] );

    return (
        <FormTokenField
            __next40pxDefaultSize
            __experimentalValidateInput={( input: string ) =>
                continents.includes( input )}
            __experimentalExpandOnFocus
            value={ selectedContinents }
            onChange={ ( tokens ) => setSelectedContinents( tokens ) } />
    );
};

GradientPicker

components-gradientpicker · ../packages/components/src/gradient-picker/stories/index.story.tsx
GradientPicker is a React component that renders a color gradient picker to define a multi step gradient. There's either a _linear_ or a _radial_ type available. ```jsx import { useState } from 'react'; import { GradientPicker } from '@wordpress/components'; const MyGradientPicker = () => { const [ gradient, setGradient ] = useState( null ); return ( <GradientPicker value={ gradient } onChange={ ( currentGradient ) => setGradient( currentGradient ) } gradients={ [ { name: 'JShine', gradient: 'linear-gradient(135deg,#12c2e9 0%,#c471ed 50%,#f64f59 100%)', slug: 'jshine', }, { name: 'Moonlit Asteroid', gradient: 'linear-gradient(135deg,#0F2027 0%, #203A43 0%, #2c5364 100%)', slug: 'moonlit-asteroid', }, { name: 'Rastafarie', gradient: 'linear-gradient(135deg,#1E9600 0%, #FFF200 0%, #FF0000 100%)', slug: 'rastafari', }, ] } /> ); }; ```
Prop types 12 prop types
Component: ../packages/components/src/gradient-picker/index.tsx::GradientPicker
Props:
/**
 * Whether this is rendered in the sidebar.
 * 
 * @default false
 */
__experimentalIsRenderedInSidebar?: boolean

/**
 * Start opting in to the new margin-free styles that will become the default
 * in a future version, currently scheduled to be WordPress 6.4. (The prop
 * can be safely removed once this happens.)
 * 
 * @default false
 * @deprecated Default behavior since WP 6.5. Prop can be safely removed.
 * @ignore
 */
__nextHasNoMargin?: boolean

/**
 * Whether the control should present as a set of buttons,
 * each with its own tab stop.
 * 
 * @default false
 */
asButtons?: boolean

/**
 * The class name added to the wrapper.
 */
className?: string

/**
 * Whether the palette should have a clearing button or not.
 * 
 * @default true
 */
clearable?: boolean = true

/**
 * If true, the gradient picker will not be displayed and only defined
 * gradients from `gradients` will be shown.
 * 
 * @default false
 */
disableCustomGradients?: boolean = false

/**
 * Whether to enable alpha transparency options in the picker.
 * 
 * @default true
 */
enableAlpha?: boolean = true

/**
 * An array of objects as predefined gradients displayed above the gradient
 * selector. Alternatively, if there are multiple sets (or 'origins') of
 * gradients, you can pass an array of objects each with a `name` and a
 * `gradients` array which will in turn contain the predefined gradient objects.
 * 
 * @default []
 */
gradients?: GradientObject[] | OriginObject[] = []

/**
 * The heading level. Only applies in cases where gradients are provided
 * from multiple origins (i.e. when the array passed as the `gradients` prop
 * contains two or more items).
 * 
 * @default 2
 */
headingLevel?: | 1
| 2
| 3
| 4
| 5
| 6
| '1'
| '2'
| '3'
| '4'
| '5'
| '6' = 2

/**
 * Prevents keyboard interaction from wrapping around.
 * Only used when `asButtons` is not true.
 * 
 * @default true
 */
loop?: boolean

/**
 * The function called when a new gradient has been defined. It is passed to
 * the `currentGradient` as an argument.
 */
onChange: ( currentGradient: string | undefined ) => void

/**
 * The current value of the gradient. Pass a css gradient string (See default value for example).
 * Optionally pass in a `null` value to specify no gradient is currently selected.
 * 
 * @default 'linear-gradient(135deg,rgba(6,147,227,1) 0%,rgb(155,81,224) 100%)'
 */
value?: GradientObject[ 'gradient' ] | null
Imports
import { GradientPicker } from "@wordpress/components";
Default story ok
const Default = ( {
	onChange,
	...props
}: React.ComponentProps< typeof GradientPicker > ) => {
	const [ gradient, setGradient ] =
		useState< ( typeof props )[ 'value' ] >( null );
	return (
		<GradientPicker
			{ ...props }
			value={ gradient }
			onChange={ ( ...changeArgs ) => {
				setGradient( ...changeArgs );
				onChange?.( ...changeArgs );
			} }
		/>
	);
};
With No Existing Gradients story ok
const WithNoExistingGradients = ( {
	onChange,
	...props
}: React.ComponentProps< typeof GradientPicker > ) => {
	const [ gradient, setGradient ] =
		useState< ( typeof props )[ 'value' ] >( null );
	return (
		<GradientPicker
			{ ...props }
			value={ gradient }
			onChange={ ( ...changeArgs ) => {
				setGradient( ...changeArgs );
				onChange?.( ...changeArgs );
			} }
		/>
	);
};
Multiple Origins story ok
const MultipleOrigins = ( {
	onChange,
	...props
}: React.ComponentProps< typeof GradientPicker > ) => {
	const [ gradient, setGradient ] =
		useState< ( typeof props )[ 'value' ] >( null );
	return (
		<GradientPicker
			{ ...props }
			value={ gradient }
			onChange={ ( ...changeArgs ) => {
				setGradient( ...changeArgs );
				onChange?.( ...changeArgs );
			} }
		/>
	);
};
CSS Variables story ok
const CSSVariables = () => <div
    style={ {
        '--red': '#f00',
        '--yellow': '#ff0',
        '--blue': '#00f',
    } }>
    <Template
        onChange={fn()}
        gradients={[
			{
				name: 'Red to Yellow',
				gradient:
					'linear-gradient(135deg,var(--red) 0%,var(--yellow) 100%)',
				slug: 'red-to-yellow',
			},
			{
				name: 'Yellow to Blue',
				gradient:
					'linear-gradient(135deg,var(--yellow) 0%,var(--blue) 100%)',
				slug: 'yellow-to-blue',
			},
			{
				name: 'Blue to Red',
				gradient:
					'linear-gradient(135deg,var(--blue) 0%,var(--red) 100%)',
				slug: 'blue-to-red',
			},
		]} />
</div>;

Icon

design-system-components-icon · ../packages/ui/src/icon/stories/index.story.tsx
Renders an SVG icon with a 24px default size. If no `fill` colors are explicitly set on the icon itself, it will be rendered with a `currentColor` fill. ```jsx import { wordpress } from '@wordpress/icons'; <Icon icon={ wordpress } /> ```
Prop types 2 prop types
Component: ../packages/ui/src/icon/icon.tsx::Icon
Props:
/**
 * The icon to render, which must be an svg element or an `SVG` from `@wordpress/primitives`.
 * 
 * In most cases, you should use an icon from
 * [the `@wordpress/icons` package](https://wordpress.github.io/gutenberg/?path=/story/icons-icon--library).
 */
icon: React.ReactElement< React.ComponentProps< 'svg' > >

/**
 * The size (width and height) of the icon.
 * @default 24
 */
size?: number = 24
Imports
import { Icon } from "@wordpress/ui";
Default story ok
const Default = () => <Icon icon={wordpress} />;
With Intrinsic Fill Color story ok
Explicit `fill` colors in the icon will be preserved.
const WithIntrinsicFillColor = () => <Icon
    icon={(<svg
        xmlns="http://www.w3.org/2000/svg"
        viewBox="0 0 24 24"
        fill="blue"
    >
        <rect x="0" y="0" width="24" height="24" />
    </svg>)} />;

InputControl

components-inputcontrol · ../packages/components/src/input-control/stories/index.story.tsx
InputControl components let users enter and edit text. This is an experimental component intended to (in time) merge with or replace `TextControl`. ```jsx import { __experimentalInputControl as InputControl } from '@wordpress/components'; import { useState } from 'react'; const Example = () => { const [ value, setValue ] = useState( '' ); return ( <InputControl __next40pxDefaultSize value={ value } onChange={ ( nextValue ) => setValue( nextValue ?? '' ) } /> ); }; ```
Prop types 1 prop type
Component: ../packages/components/src/input-control/index.tsx::InputControl
Props:
__unstableStateReducer?: InputFieldProps[ 'stateReducer' ]
Imports
import { Button, InputControl, InputControlPrefixWrapper, InputControlSuffixWrapper } from "@wordpress/components";
import { Icon } from "@wordpress/icons";
Default story ok
const Default = () => <InputControl
    __next40pxDefaultSize
    onChange={fn()}
    onValidate={fn()}
    onKeyDown={fn()}
    label="Value"
    placeholder="Placeholder" />;
With Help Text story ok
const WithHelpText = () => <InputControl
    __next40pxDefaultSize
    onChange={fn()}
    onValidate={fn()}
    onKeyDown={fn()}
    help="Help text to describe the control." />;
With Prefix story ok
A `prefix` can be inserted before the input. By default, the prefix is aligned with the edge of the input border, with no padding. If you want to apply standard padding in accordance with the size variant, use the provided `<InputControlPrefixWrapper>` convenience wrapper.
const WithPrefix = () => <InputControl
    __next40pxDefaultSize
    onChange={fn()}
    onValidate={fn()}
    onKeyDown={fn()}
    prefix={<InputControlPrefixWrapper>@</InputControlPrefixWrapper>} />;
With Suffix story ok
A `suffix` can be inserted after the input. By default, the suffix is aligned with the edge of the input border, with no padding. If you want to apply standard padding in accordance with the size variant, use the provided `<InputControlSuffixWrapper>` convenience wrapper.
const WithSuffix = () => <InputControl
    __next40pxDefaultSize
    onChange={fn()}
    onValidate={fn()}
    onKeyDown={fn()}
    suffix={<InputControlSuffixWrapper>%</InputControlSuffixWrapper>} />;
With Icon Or Control story ok
`<InputControlPrefixWrapper>` and `<InputControlSuffixWrapper>` have a `variant` prop that can be used to adjust the wrapper based on the prefix or suffix content. - `'default'`: Standard padding for text content. - `'icon'`: For icons. - `'control'`: For controls, like buttons or selects.
const WithIconOrControl = () => <InputControl
    __next40pxDefaultSize
    onChange={fn()}
    onValidate={fn()}
    onKeyDown={fn()}
    prefix={(<InputControlPrefixWrapper variant="icon">
        <Icon icon={ link } />
    </InputControlPrefixWrapper>)}
    suffix={(<InputControlSuffixWrapper variant="control">
        <Button icon={ closeSmall } size="small" label="Clear" />
    </InputControlSuffixWrapper>)} />;
With Side Label story ok
const WithSideLabel = () => <InputControl
    __next40pxDefaultSize
    onChange={fn()}
    onValidate={fn()}
    onKeyDown={fn()}
    labelPosition="side" />;
With Edge Label story ok
const WithEdgeLabel = () => <InputControl
    __next40pxDefaultSize
    onChange={fn()}
    onValidate={fn()}
    onKeyDown={fn()}
    __unstableInputWidth="20em"
    labelPosition="edge" />;
Show Password story ok
const ShowPassword = () => {
    const [ visible, setVisible ] = useState( false );

    return (
        <InputControl
            __next40pxDefaultSize
            type={ visible ? 'text' : 'password' }
            suffix={
				<InputControlSuffixWrapper variant="control">
					<Button
						size="small"
						icon={ visible ? unseen : seen }
						onClick={ () => setVisible( ( value ) => ! value ) }
						label={ visible ? 'Hide password' : 'Show password' }
					/>
				</InputControlSuffixWrapper>
			}
            onChange={fn()}
            onValidate={fn()}
            onKeyDown={fn()}
            label="Password"
            placeholder={undefined} />
    );
};

ItemGroup

components-itemgroup · ../packages/components/src/item-group/stories/index.story.tsx
Info
No description found. Write a jsdoc comment such as /** Component description */.
Imports
import { Item, ItemGroup } from "@wordpress/components";
Default story ok
const Default = ( props ) => (
	<ItemGroup { ...props } />
);
Non Clickable Items story ok
const NonClickableItems = ( props ) => (
	<ItemGroup { ...props } />
);
Custom Item Size story ok
const CustomItemSize = ( props ) => (
	<ItemGroup { ...props } />
);
Without Border story ok
const WithoutBorder = ( props ) => (
	<ItemGroup { ...props } />
);

KeyboardShortcuts

components-keyboardshortcuts · ../packages/components/src/keyboard-shortcuts/stories/index.story.tsx
`KeyboardShortcuts` is a component which handles keyboard sequences during the lifetime of the rendering element. When passed children, it will capture key events which occur on or within the children. If no children are passed, events are captured on the document. It uses the [Mousetrap](https://craig.is/killing/mice) library to implement keyboard sequence bindings. ```jsx import { KeyboardShortcuts } from '@wordpress/components'; import { useState } from '@wordpress/element'; const MyKeyboardShortcuts = () => { const [ isAllSelected, setIsAllSelected ] = useState( false ); const selectAll = () => { setIsAllSelected( true ); }; return ( <div> <KeyboardShortcuts shortcuts={ { 'mod+a': selectAll, } } /> [cmd/ctrl + A] Combination pressed? { isAllSelected ? 'Yes' : 'No' } </div> ); }; ```
Prop types 4 prop types
Component: ../packages/components/src/keyboard-shortcuts/index.tsx::default
Props:
/**
 * By default, a callback will not be invoked if the key combination occurs in an editable field.
 * Pass `bindGlobal` as `true` if the key events should be observed globally, including within editable fields.
 * 
 * Tip: If you need some but not all keyboard events to be observed globally,
 * simply render two distinct `KeyboardShortcuts` elements, one with and one without the `bindGlobal` prop.
 */
bindGlobal?: KeyboardShortcutProps[ 'bindGlobal' ]

/**
 * Elements to render, upon whom key events are to be monitored.
 */
children?: React.ReactNode

/**
 * By default, a callback is invoked in response to the `keydown` event.
 * To override this, pass `eventName` with the name of a specific keyboard event.
 */
eventName?: KeyboardShortcutProps[ 'eventName' ]

/**
 * An object of shortcut bindings, where each key is a keyboard combination,
 * the value of which is the callback to be invoked when the key combination is pressed.
 * 
 * The value of each shortcut should be a consistent function reference, not an anonymous function.
 * Otherwise, the callback will not be correctly unbound when the component unmounts.
 * 
 * The `KeyboardShortcuts` component will not update to reflect a changed `shortcuts` prop.
 * If you need to change shortcuts, mount a separate `KeyboardShortcuts` element,
 * which can be achieved by assigning a unique `key` prop.
 * 
 * @see {@link https://craig.is/killing/mice Mousetrap documentation}
 */
shortcuts: Record< string, KeyboardShortcutProps[ 'callback' ] >
Imports
import { KeyboardShortcuts } from "@wordpress/components";
Default story ok
const Default = ( props ) => (
	<KeyboardShortcuts { ...props } />
);

Link

design-system-components-link · ../packages/ui/src/link/stories/index.story.tsx
A styled anchor element with support for semantic color tones and an unstyled escape hatch.
Prop types 4 prop types
Component: ../packages/ui/src/link/link.tsx::Link
Props:
/**
 * The content to be rendered inside the component.
 */
children?: ReactNode

/**
 * Whether to open the link in a new browser tab.
 * When true, sets `target="_blank"` and appends a visual arrow indicator.
 * 
 * @default false
 */
openInNewTab?: boolean = false

/**
 * The tone of the link. Tone describes a semantic color intent.
 * Only applies when `variant` is `default`.
 * 
 * @default "brand"
 */
tone?: 'brand' | 'neutral' = 'brand'

/**
 * The visual treatment of the link.
 * 
 * - `default`: Applies tone-based color and underline styles.
 * - `unstyled`: Strips all visual styles so consumers can bring their own.
 * 
 * @default "default"
 */
variant?: 'default' | 'unstyled' = 'default'
Imports
import { Link, Stack, Text } from "@wordpress/ui";
Default story ok
const Default = () => <Link href="#">Learn more</Link>;
All Tones And Variants story ok
Note: `tone` has no effect on `unstyled` variant
const AllTonesAndVariants = ( args ) => (
    <Stack direction="column" gap="lg">
        { ( [ 'brand', 'neutral' ] as const ).map( ( tone ) =>
            ( [ 'default', 'unstyled' ] as const ).map( ( variant ) => (
                <Stack
                    direction="column"
                    gap="xs"
                    key={ `${ tone }-${ variant }` }
                >
                    <Text variant="heading-sm">
                        { tone } tone, { variant } variant
                    </Text>
                    <Link { ...args } tone={ tone } variant={ variant } />
                </Stack>
            ) )
        ) }
    </Stack>
);
Inline story ok
const Inline = () => <Text variant="body-md" render={ <p /> }>This is a paragraph with an <Link>inline link</Link>that inherits its
                typography from the parent Text component.
            </Text>;
Standalone story ok
When composing `Text` and `Link` via the `render` prop, keep `Text` as the host and pass `Link` via `render` so the resulting element stays an `<a>`.
const Standalone = ( args ) => (
    <Text variant="body-md" render={ <Link { ...args } /> }>
        A standalone link with body-md typography
    </Text>
);

MenuGroup

components-menugroup · ../packages/components/src/menu-group/stories/index.story.tsx
`MenuGroup` wraps a series of related `MenuItem` components into a common section. ```jsx import { MenuGroup, MenuItem } from '@wordpress/components'; const MyMenuGroup = () => ( <MenuGroup label="Settings"> <MenuItem>Setting 1</MenuItem> <MenuItem>Setting 2</MenuItem> </MenuGroup> ); ```
Prop types 4 prop types
Component: ../packages/components/src/menu-group/index.tsx::MenuGroup
Props:
/**
 * The children elements.
 */
children?: ReactNode

/**
 * A CSS `class` to give to the container element.
 */
className?: string

/**
 * Hide the top border on the container.
 */
hideSeparator?: boolean

/**
 * Text to be displayed as the menu group header.
 */
label?: string
Imports
import { MenuGroup, MenuItem, MenuItemsChoice } from "@wordpress/components";
Default story ok
const Default = () => {
    return (
        <MenuGroup>
            <MenuItem>Menu Item 1</MenuItem>
            <MenuItem>Menu Item 2</MenuItem>
        </MenuGroup>
    );
};
With Separator story ok
When other menu items exist above or below a MenuGroup, the group should have a divider line between it and the adjacent item.
const WithSeparator = () => {
    const [ mode, setMode ] = useState( 'visual' );
    const choices = [
		{
			value: 'visual',
			label: 'Visual editor',
		},
		{
			value: 'text',
			label: 'Code editor',
		},
	];

    return (
        <>
            <MenuGroup label="View">
                <MenuItem>Top Toolbar</MenuItem>
                <MenuItem>Spotlight Mode</MenuItem>
                <MenuItem>Distraction Free</MenuItem>
            </MenuGroup>
            <MenuGroup hideSeparator={false} label="Editor">
                <MenuItemsChoice
                    choices={ choices }
                    value={ mode }
                    onSelect={ ( newMode: string ) => setMode( newMode ) }
                    onHover={ () => {} } />
            </MenuGroup>
        </>
    );
};

MenuItem

components-menuitem · ../packages/components/src/menu-item/stories/index.story.tsx
MenuItem is a component which renders a button intended to be used in combination with the `DropdownMenu` component. ```jsx import { MenuItem } from '@wordpress/components'; import { useState } from '@wordpress/element'; const MyMenuItem = () => { const [ isActive, setIsActive ] = useState( true ); return ( <MenuItem icon={ isActive ? 'yes' : 'no' } isSelected={ isActive } role="menuitemcheckbox" onClick={ () => setIsActive( ( state ) => ! state ) } > Toggle </MenuItem> ); }; ```
Imports
import { MenuGroup, MenuItem, Shortcut } from "@wordpress/components";
Default story ok
const Default = ( props ) => {
	return (
		<MenuGroup>
			<MenuItem { ...props }>Menu Item 1</MenuItem>
		</MenuGroup>
	);
};
Is Selected story ok
When the `role` prop is either `"menuitemcheckbox"` or `"menuitemradio"`, the `isSelected` prop should be used so screen readers can tell which item is currently selected.
const IsSelected = ( props ) => {
	return (
		<MenuGroup>
			<MenuItem { ...props }>Menu Item 1</MenuItem>
		</MenuGroup>
	);
};
With Icon story ok
const WithIcon = ( props ) => {
	return (
		<MenuGroup>
			<MenuItem { ...props }>Menu Item 1</MenuItem>
		</MenuGroup>
	);
};
With Info story ok
const WithInfo = ( props ) => {
	return (
		<MenuGroup>
			<MenuItem { ...props }>Menu Item 1</MenuItem>
		</MenuGroup>
	);
};
With Suffix story ok
const WithSuffix = ( props ) => {
	return (
		<MenuGroup>
			<MenuItem { ...props }>Menu Item 1</MenuItem>
		</MenuGroup>
	);
};

MenuItemsChoice

components-menuitemschoice · ../packages/components/src/menu-items-choice/stories/index.story.tsx
`MenuItemsChoice` functions similarly to a set of `MenuItem`s, but allows the user to select one option from a set of multiple choices. ```jsx import { MenuGroup, MenuItemsChoice } from '@wordpress/components'; import { useState } from '@wordpress/element'; const MyMenuItemsChoice = () => { const [ mode, setMode ] = useState( 'visual' ); const choices = [ { value: 'visual', label: 'Visual editor', }, { value: 'text', label: 'Code editor', }, ]; return ( <MenuGroup label="Editor"> <MenuItemsChoice choices={ choices } value={ mode } onSelect={ ( newMode ) => setMode( newMode ) } /> </MenuGroup> ); }; ```
Prop types 4 prop types
Component: ../packages/components/src/menu-items-choice/index.tsx::default
Props:
/**
 * Array of choices.
 * 
 * @default []
 */
choices?: unknown = []

/**
 * Callback function to be called with a choice when user
 * hovers over a new choice (will be empty on mouse leave).
 * 
 * @default noop
 */
onHover?: ( value: string | null ) => void = () => {}

/**
 * Callback function to be called with the selected choice when user
 * selects a new choice.
 */
onSelect: ( value: string ) => void

/**
 * Value of currently selected choice (should match a `value` property
 * from a choice in `choices`).
 */
value: string
Imports
import { MenuGroup, MenuItemsChoice } from "@wordpress/components";
Default story ok
const Default = ( {
	onHover,
	onSelect,
	choices,
} ) => {
	const [ choice, setChoice ] = useState( choices[ 0 ]?.value ?? '' );

	return (
		<MenuGroup label="Editor">
			<MenuItemsChoice
				choices={ choices }
				value={ choice }
				onSelect={ ( ...selectArgs ) => {
					onSelect( ...selectArgs );
					setChoice( ...selectArgs );
				} }
				onHover={ onHover }
			/>
		</MenuGroup>
	);
};

Modal

components-modal · ../packages/components/src/modal/stories/index.story.tsx
Modals give users information and choices related to a task they’re trying to accomplish. They can contain critical information, require decisions, or involve multiple tasks. ```jsx import { Button, Modal } from '@wordpress/components'; import { useState } from '@wordpress/element'; const MyModal = () => { const [ isOpen, setOpen ] = useState( false ); const openModal = () => setOpen( true ); const closeModal = () => setOpen( false ); return ( <> <Button variant="secondary" onClick={ openModal }> Open Modal </Button> { isOpen && ( <Modal title="This is my modal" onRequestClose={ closeModal }> <Button variant="secondary" onClick={ closeModal }> My custom close button </Button> </Modal> ) } </> ); }; ```
Prop types 21 prop types
Component: ../packages/components/src/modal/index.tsx::Modal
Props:
/**
 * When set to `true`, the Modal's header (including the icon, title and
 * close button) will not be rendered.
 * 
 * _Warning_: This property is still experimental. “Experimental” means this
 * is an early implementation subject to drastic and breaking changes.
 * 
 * @default false
 */
__experimentalHideHeader?: boolean

aria?: {
	/**
	 * If this property is added, it will be added to the modal content
	 * `div` as `aria-describedby`.
	 */
	describedby?: string;
	/**
	 * If this property is added, it will be added to the modal content
	 * `div` as `aria-labelledby`. Use this when you are rendering the title
	 * yourself within the modal's content area instead of using the `title`
	 * prop. This ensures the title is usable by assistive technology.
	 *
	 * Titles are required for accessibility reasons, see `contentLabel` and
	 * `title` for other ways to provide a title.
	 */
	labelledby?: string;
}

/**
 * Class name added to the body element when the modal is open.
 * 
 * @default 'modal-open'
 */
bodyOpenClassName?: string

/**
 * The children elements.
 */
children: React.ReactNode

/**
 * If this property is added, it will an additional class name to the modal
 * content `div`.
 */
className?: string

/**
 * Label on the close button.
 * 
 * @default `__( 'Close' )`
 */
closeButtonLabel?: string

/**
 * If this property is added, it will be added to the modal content `div` as
 * `aria-label`.
 * 
 * Titles are required for accessibility reasons, see `aria.labelledby` and
 * `title` for other ways to provide a title.
 */
contentLabel?: string

/**
 * Determines focus behavior when the modal opens.
 * 
 * - `"firstElement"` focuses the first tabbable element within.
 * - `"firstInputElement"` focuses the first value control within.
 * - `"firstContentElement"` focuses the first tabbable element within the modal’s content element.
 * - `true` focuses the element itself.
 * - `false` does nothing and _should not be used unless an accessible
 *    substitute behavior is implemented_.
 * 
 * @default true
 */
focusOnMount?: useFocusOnMount.Mode | 'firstContentElement'

/**
 * Elements that are injected into the modal header to the left of the close button (if rendered).
 * Hidden if `__experimentalHideHeader` is `true`.
 * 
 * @default null
 */
headerActions?: React.ReactNode

/**
 * If this property is added, an icon will be added before the title.
 */
icon?: React.JSX.Element

/**
 * If this property is set to false, the modal will not display a close icon
 * and cannot be dismissed.
 * 
 * @default true
 */
isDismissible?: boolean

/**
 * This property when set to `true` will render a full screen modal.
 * 
 * @default false
 */
isFullScreen?: boolean

/**
 * Handle the key down on the modal frame `div`.
 */
onKeyDown?: React.KeyboardEventHandler< HTMLDivElement >

/**
 * This function is called to indicate that the modal should be closed.
 */
onRequestClose: (
	event?: React.KeyboardEvent< HTMLDivElement > | React.SyntheticEvent
) => void

/**
 * If this property is added, it will an additional class name to the modal
 * overlay `div`.
 */
overlayClassName?: string

/**
 * If this property is added, it will override the default role of the
 * modal.
 * 
 * @default 'dialog'
 */
role?: React.AriaRole

/**
 * If this property is added, it will determine whether the modal requests
 * to close when a mouse click occurs outside of the modal content.
 * 
 * @default true
 */
shouldCloseOnClickOutside?: boolean

/**
 * If this property is added, it will determine whether the modal requests
 * to close when the escape key is pressed.
 * 
 * @default true
 */
shouldCloseOnEsc?: boolean

/**
 * If this property is added it will cause the modal to render at a preset
 * width, or expand to fill the screen. This prop will be ignored if
 * `isFullScreen` is set to `true`.
 * 
 * Note: `Modal`'s width can also be controlled by adjusting the width of the
 * modal's contents, or via CSS using the `style` prop.
 */
size?: 'small' | 'medium' | 'large' | 'fill'

/**
 * If this property is added, it will be added to the modal frame `div`.
 */
style?: React.CSSProperties

/**
 * This property is used as the modal header's title.
 * 
 * Titles are required for accessibility reasons, see `aria.labelledby` and
 * `contentLabel` for other ways to provide a title.
 */
title?: string
Imports
import { Button, InputControl, Modal } from "@wordpress/components";
Default story ok
const Default = ( { onRequestClose, ...args } ) => {
	const [ isOpen, setOpen ] = useState( false );
	const openModal = () => setOpen( true );
	const closeModal: ModalProps[ 'onRequestClose' ] = ( event ) => {
		setOpen( false );
		onRequestClose( event );
	};

	return (
		<>
			<Button
				__next40pxDefaultSize
				variant="secondary"
				onClick={ openModal }
			>
				Open Modal
			</Button>
			{ isOpen && (
				<Modal onRequestClose={ closeModal } { ...args }>
					<p>
						Lorem ipsum dolor sit amet, consectetur adipiscing elit,
						sed do eiusmod tempor incididunt ut labore et magna
						aliqua. Ut enim ad minim veniam, quis nostrud
						exercitation ullamco laboris nisi ut aliquip ex ea ea
						commodo consequat. Duis aute irure dolor in
						reprehenderit in voluptate velit esse cillum dolore eu
						fugiat nulla pariatur. Excepteur sint occaecat cupidatat
						non proident, sunt in culpa qui officia deserunt mollit
						anim id est laborum.
					</p>

					<InputControl
						__next40pxDefaultSize
						style={ { marginBottom: '20px' } }
					/>

					<Button
						__next40pxDefaultSize
						variant="secondary"
						onClick={ closeModal }
					>
						Close Modal
					</Button>
				</Modal>
			) }
		</>
	);
};
With size: small story ok
const WithsizeSmall = ( { onRequestClose, ...args } ) => {
	const [ isOpen, setOpen ] = useState( false );
	const openModal = () => setOpen( true );
	const closeModal: ModalProps[ 'onRequestClose' ] = ( event ) => {
		setOpen( false );
		onRequestClose( event );
	};

	return (
		<>
			<Button
				__next40pxDefaultSize
				variant="secondary"
				onClick={ openModal }
			>
				Open Modal
			</Button>
			{ isOpen && (
				<Modal onRequestClose={ closeModal } { ...args }>
					<p>
						Lorem ipsum dolor sit amet, consectetur adipiscing elit,
						sed do eiusmod tempor incididunt ut labore et magna
						aliqua. Ut enim ad minim veniam, quis nostrud
						exercitation ullamco laboris nisi ut aliquip ex ea ea
						commodo consequat. Duis aute irure dolor in
						reprehenderit in voluptate velit esse cillum dolore eu
						fugiat nulla pariatur. Excepteur sint occaecat cupidatat
						non proident, sunt in culpa qui officia deserunt mollit
						anim id est laborum.
					</p>

					<InputControl
						__next40pxDefaultSize
						style={ { marginBottom: '20px' } }
					/>

					<Button
						__next40pxDefaultSize
						variant="secondary"
						onClick={ closeModal }
					>
						Close Modal
					</Button>
				</Modal>
			) }
		</>
	);
};
With Header Actions story ok
The `headerActions` prop can be used to add auxiliary actions to the header, for example a fullscreen mode toggle.
const WithHeaderActions = ( { onRequestClose, ...args } ) => {
	const [ isOpen, setOpen ] = useState( false );
	const openModal = () => setOpen( true );
	const closeModal: ModalProps[ 'onRequestClose' ] = ( event ) => {
		setOpen( false );
		onRequestClose( event );
	};

	return (
		<>
			<Button
				__next40pxDefaultSize
				variant="secondary"
				onClick={ openModal }
			>
				Open Modal
			</Button>
			{ isOpen && (
				<Modal onRequestClose={ closeModal } { ...args }>
					<p>
						Lorem ipsum dolor sit amet, consectetur adipiscing elit,
						sed do eiusmod tempor incididunt ut labore et magna
						aliqua. Ut enim ad minim veniam, quis nostrud
						exercitation ullamco laboris nisi ut aliquip ex ea ea
						commodo consequat. Duis aute irure dolor in
						reprehenderit in voluptate velit esse cillum dolore eu
						fugiat nulla pariatur. Excepteur sint occaecat cupidatat
						non proident, sunt in culpa qui officia deserunt mollit
						anim id est laborum.
					</p>

					<InputControl
						__next40pxDefaultSize
						style={ { marginBottom: '20px' } }
					/>

					<Button
						__next40pxDefaultSize
						variant="secondary"
						onClick={ closeModal }
					>
						Close Modal
					</Button>
				</Modal>
			) }
		</>
	);
};

Navigator

components-navigator · ../packages/components/src/navigator/stories/index.story.tsx
Info
No description found. Write a jsdoc comment such as /** Component description */.
Imports
import { Button, HStack, Navigator, VStack } from "@wordpress/components";
Default story ok
const Default = () => <Navigator initialPath="/">(<>
        <Navigator.Screen path="/">
            <h2>This is the home screen.</h2>

            <VStack alignment="left">
                <Navigator.Button variant="primary" path="/child">
                    Go to child screen.
                </Navigator.Button>

                <Navigator.Button variant="primary" path="/product/1">
                    Go to dynamic path screen with id 1.
                </Navigator.Button>

                <Navigator.Button variant="primary" path="/product/2">
                    Go to dynamic path screen with id 2.
                </Navigator.Button>
            </VStack>
        </Navigator.Screen>
        <Navigator.Screen path="/child">
            <h2>This is the child screen.</h2>
            <HStack spacing={ 2 } alignment="left">
                <Navigator.BackButton variant="secondary">
                    Go back
                </Navigator.BackButton>

                <Navigator.Button
                    variant="primary"
                    path="/child/grandchild"
                >
                    Go to grand child screen.
                </Navigator.Button>
            </HStack>
        </Navigator.Screen>
        <Navigator.Screen path="/child/grandchild">
            <h2>This is the grand child screen.</h2>
            <Navigator.BackButton variant="secondary">
                Go back
            </Navigator.BackButton>
        </Navigator.Screen>
        <Navigator.Screen path="/product/:id">
            <DynamicScreen />
        </Navigator.Screen>
    </>)</Navigator>;
With Nested Initial Path story ok
const WithNestedInitialPath = () => <Navigator initialPath="/child/grandchild" />;
Skip Focus story ok
const SkipFocus = () => <Navigator initialPath="/">(<>
        <div
            style={ {
                height: 150,
                outline: '1px solid black',
                outlineOffset: '-1px',
                marginBlockEnd: '1rem',
                display: 'contents',
            } }
        >
            <Navigator.Screen path="/">
                <h2>Home screen</h2>
                <Navigator.Button variant="primary" path="/child">
                    Go to child screen.
                </Navigator.Button>
            </Navigator.Screen>

            <Navigator.Screen path="/child">
                <h2>Child screen</h2>
                <Navigator.BackButton variant="secondary">
                    Go back to home screen
                </Navigator.BackButton>
            </Navigator.Screen>
        </div>
        <NavigatorButtonWithSkipFocus path="/child">
            Go to child screen, but keep focus on this button
        </NavigatorButtonWithSkipFocus>
    </>)</Navigator>;

Notice

components-notice · ../packages/components/src/notice/stories/index.story.tsx
`Notice` is a component used to communicate feedback to the user. ```jsx import { Notice } from `@wordpress/components`; const MyNotice = () => ( <Notice status="error">An unknown error occurred.</Notice> ); ```
Prop types 10 prop types
Component: ../packages/components/src/notice/index.tsx::default
Props:
/**
 * Determines whether or not the message should be parsed as custom HTML
 * instead of a string.
 */
__unstableHTML?: boolean

/**
 * An array of action objects. Each member object should contain:
 * 
 * - `label`: `string` containing the text of the button/link
 * - `url`: `string` OR `onClick`: `( event: SyntheticEvent ) => void` to specify
 *    what the action does.
 * - `className`: `string` (optional) to add custom classes to the button styles.
 * - `noDefaultClasses`: `boolean` (optional) A value of `true` will remove all
 *    default styling.
 * - `variant`: `'primary' | 'secondary' | 'link'` (optional) You can denote a
 *    primary button action for a notice by passing a value of `primary`.
 * 
 * The default appearance of an action button is inferred based on whether
 * `url` or `onClick` are provided, rendering the button as a link if
 * appropriate. If both props are provided, `url` takes precedence, and the
 * action button will render as an anchor tag.
 * 
 * @default []
 */
actions?: Array< NoticeAction > = []

/**
 * The displayed message of a notice. Also used as the spoken message for
 * assistive technology, unless `spokenMessage` is provided as an alternative message.
 */
children: ReactNode

/**
 * A CSS `class` to give to the wrapper element.
 */
className?: string

/**
 * Whether the notice should be dismissible or not
 * 
 * @default true
 */
isDismissible?: boolean = true

/**
 * A deprecated alternative to `onRemove`. This prop is kept for
 * compatibility reasons but should be avoided.
 * 
 * @default noop
 */
onDismiss?: () => void = () => {}

/**
 * Function called when dismissing the notice
 * 
 * @default noop
 */
onRemove?: () => void = () => {}

/**
 * A politeness level for the notice's spoken message. Should be provided as
 * one of the valid options for an `aria-live` attribute value.
 * 
 * A value of `'assertive'` is to be used for important, and usually
 * time-sensitive, information. It will interrupt anything else the screen
 * reader is announcing in that moment.
 * A value of `'polite'` is to be used for advisory information. It should
 * not interrupt what the screen reader is announcing in that moment
 * (the "speech queue") or interrupt the current task.
 * 
 * Note that this value should be considered a suggestion; assistive
 * technologies may override it based on internal heuristics.
 * 
 * @see https://www.w3.org/TR/wai-aria-1.1/#aria-live
 * 
 * @default 'assertive' for 'error' status, 'polite' for all other statuses
 */
politeness?: 'polite' | 'assertive' = getDefaultPoliteness( status )

/**
 * Used to provide a custom spoken message in place of the `children` default.
 * 
 * @default `children`
 */
spokenMessage?: ReactNode = children

/**
 * Determines the color of the notice: `warning` (yellow),
 * `success` (green), `error` (red), or `'info'`.
 * By default `'info'` will be blue.
 * 
 * @default 'info'
 */
status?: 'warning' | 'success' | 'error' | 'info' = 'info'
Imports
import { Button, Notice, NoticeList } from "@wordpress/components";
Default story ok
const Default = ( props ) => {
	return <Notice { ...props } />;
};
With Custom Spoken Message story ok
const WithCustomSpokenMessage = ( props ) => {
	return <Notice { ...props } />;
};
With JSX Children story ok
const WithJSXChildren = ( props ) => {
	return <Notice { ...props } />;
};
With Actions story ok
const WithActions = ( props ) => {
	return <Notice { ...props } />;
};
NoticeList Subcomponent story ok
const NoticeListSubcomponent = () => {
	const exampleNotices: NoticeListProps[ 'notices' ] = [
		{
			id: 'second-notice',
			content: 'second notice content',
		},
		{
			id: 'first-notice',
			content: 'first notice content',
			actions: [
				{
					label: 'Click me!',
					onClick: () => {},
					variant: 'primary',
				},
				{
					label: 'Or click me instead!',
					onClick: () => {},
				},
				{
					label: 'Or visit a link for more info',
					url: 'https://wordpress.org',
					variant: 'link',
				},
			],
		},
	];
	const [ notices, setNotices ] = useState( exampleNotices );

	const removeNotice = (
		id: NoticeListProps[ 'notices' ][ number ][ 'id' ]
	) => {
		setNotices( notices.filter( ( notice ) => notice.id !== id ) );
	};

	const resetNotices = () => {
		setNotices( exampleNotices );
	};

	return (
		<>
			<NoticeList notices={ notices } onRemove={ removeNotice } />
			<Button
				__next40pxDefaultSize
				variant="primary"
				onClick={ resetNotices }
			>
				Reset Notices
			</Button>
		</>
	);
};
With Disabled Action story ok
Action buttons can be disabled.
const WithDisabledAction = ( props ) => {
	return <Notice { ...props } />;
};

NumberControl

components-numbercontrol · ../packages/components/src/number-control/stories/index.story.tsx
Info
No description found. Write a jsdoc comment such as /** Component description */.
Imports
import { NumberControl } from "@wordpress/components";
Default story ok
const Default = ( {
	onChange,
	...props
} ) => {
	const [ value, setValue ] = useState< string | undefined >( '0' );
	const [ isValidValue, setIsValidValue ] = useState( true );

	return (
		<>
			<NumberControl
				__next40pxDefaultSize
				{ ...props }
				value={ value }
				onChange={ ( v, extra ) => {
					setValue( v );
					setIsValidValue(
						( extra.event.target as HTMLInputElement ).validity
							.valid
					);
					onChange?.( v, extra );
				} }
			/>
			<p>Is valid? { isValidValue ? 'Yes' : 'No' }</p>
		</>
	);
};

Panel

components-panel · ../packages/components/src/panel/stories/index.story.tsx
`Panel` expands and collapses multiple sections of content. ```jsx import { Panel, PanelBody, PanelRow } from '@wordpress/components'; import { more } from '@wordpress/icons'; const MyPanel = () => ( <Panel header="My Panel"> <PanelBody title="My Block Settings" icon={ more } initialOpen={ true }> <PanelRow>My Panel Inputs and Labels</PanelRow> </PanelBody> </Panel> ); ```
Prop types 3 prop types
Component: ../packages/components/src/panel/index.tsx::Panel
Props:
/**
 * The content to display within the panel.
 */
children: React.ReactNode

/**
 * The CSS class to apply to the wrapper element.
 */
className?: string

/**
 * The text that will be rendered as the title of the panel.
 * Text will be rendered inside an `<h2>` tag.
 */
header?: PanelHeaderProps[ 'label' ]
Imports
import { InputControl, Panel, PanelBody, PanelRow } from "@wordpress/components";
Default story ok
const Default = ( props ) => <Panel { ...props } />;
Panel Row story ok
`PanelRow` is a generic container for rows within a `PanelBody`. It is a flex container with a top margin for spacing.
const _PanelRow = ( props ) => <Panel { ...props } />;
Disabled Section story ok
const DisabledSection = ( props ) => <Panel { ...props } />;
With Icon story ok
const WithIcon = ( props ) => <Panel { ...props } />;

Popover

components-popover · ../packages/components/src/popover/stories/index.story.tsx
Info
No description found. Write a jsdoc comment such as /** Component description */.
Prop types 1 prop type
Component: ../packages/components/src/popover/index.tsx::PopoverSlot
Props:
/**
 * The name of the Slot in which the popover should be rendered. It should
 * be also passed to the corresponding `PopoverSlot` component.
 * 
 * @default 'Popover'
 */
name?: string = 'Popover'
Imports
import { Button, Popover, PopoverInsideIframeRenderedInExternalSlot } from "@wordpress/components";
Default story ok
const Default = () => <Popover>(<div style={ { width: '280px', whiteSpace: 'normal' } }>Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do
                        eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut
                        enim ad minim veniam, quis nostrud exercitation ullamco laboris
                        nisi ut aliquip ex ea commodo consequat.
                    </div>)</Popover>;
Unstyled story ok
const Unstyled = () => <Popover variant="unstyled" />;
All Placements story ok
const AllPlacements = ( { children, ...args } ) => (
    <div
        style={ {
            minWidth: '600px',
            marginLeft: 'auto',
            marginRight: 'auto',
        } }
    >
        <h2>
            Resize / scroll the viewport to test the behavior of the
            popovers when they reach the viewport boundaries.
        </h2>
        <div>
            { AVAILABLE_PLACEMENTS.map( ( p ) => (
                <PopoverWithAnchor
                    key={ p }
                    placement={ p }
                    { ...args }
                    resize={ p === 'overlay' ? true : args.resize }
                >
                    { children }
                    <div>
                        <small>(placement: { p })</small>
                    </div>
                </PopoverWithAnchor>
            ) ) }
        </div>
    </div>
);
Dynamic Height story ok
const DynamicHeight = () => <Popover>(<div
        style={ {
            height: 'var(--dynamic-height)',
            background: '#eee',
            padding: '20px',
        } }
    >Content with dynamic height
                    </div>)</Popover>;
With Slot Outside Iframe story ok
const WithSlotOutsideIframe = () => <PopoverInsideIframeRenderedInExternalSlot />;
With Close Handlers story ok
const WithCloseHandlers = function WithCloseHandlersStory( args ) {
    const [ isVisible, setIsVisible ] = useState( false );
    const buttonRef = useRef< HTMLButtonElement >( null );

    const toggleVisible = ( event: React.MouseEvent ) => {
        if ( buttonRef.current && event.target !== buttonRef.current ) {
            return;
        }
        setIsVisible( ( prev ) => ! prev );
    };

    const handleClose = () => {
        args.onClose?.();
        setIsVisible( false );
    };

    const handleFocusOutside = ( e: React.SyntheticEvent ) => {
        args.onFocusOutside?.( e );
        setIsVisible( false );
    };

    useEffect( () => {
        buttonRef.current?.scrollIntoView( {
            block: 'center',
            inline: 'center',
        } );
    }, [] );

    return (
        <div
            style={ {
                width: '300vw',
                height: '300vh',
                display: 'flex',
                alignItems: 'center',
                justifyContent: 'center',
            } }
        >
            <Button
                __next40pxDefaultSize
                variant="secondary"
                onClick={ toggleVisible }
                ref={ buttonRef }
            >
                Toggle Popover
                { isVisible && (
                    <Popover
                        { ...args }
                        onClose={ handleClose }
                        onFocusOutside={ handleFocusOutside }
                    >
                        { args.children }
                    </Popover>
                ) }
            </Button>
        </div>
    );
};

ProgressBar

components-progressbar · ../packages/components/src/progress-bar/stories/index.story.tsx
A simple horizontal progress bar component. Supports two modes: determinate and indeterminate. A progress bar is determinate when a specific progress value has been specified (from 0 to 100), and indeterminate when a value hasn't been specified. ```jsx import { ProgressBar } from '@wordpress/components'; const MyLoadingComponent = () => { return <ProgressBar />; }; ```
Imports
import { ProgressBar } from "@wordpress/components";
Default story ok
const Default = () => {
    return <ProgressBar />;
};
With Custom Width story ok
A progress bar with a custom width. You can override the default `width` by passing a custom CSS class via the `className` prop. This example shows a progress bar with an overridden `width` of `100%` which makes it fit all available horizontal space of the parent element. The CSS class looks like this: ```css .custom-progress-bar { width: 100%; } ```
const WithCustomWidth = () => {
    return <ProgressBar className="custom-progress-bar" />;
};

RadioControl

components-radiocontrol · ../packages/components/src/radio-control/stories/index.story.tsx
Render a user interface to select the user type using radio inputs. ```jsx import { RadioControl } from '@wordpress/components'; import { useState } from '@wordpress/element'; const MyRadioControl = () => { const [ option, setOption ] = useState( 'a' ); return ( <RadioControl label="User type" help="The type of the current user" selected={ option } options={ [ { label: 'Author', value: 'a' }, { label: 'Editor', value: 'e' }, ] } onChange={ ( value ) => setOption( value ) } /> ); }; ```
Imports
import { RadioControl } from "@wordpress/components";
Default story ok
const Default = () => {
    const [ value, setValue ] = useState( options?.[ 0 ]?.value );

    return (
        <RadioControl
            label="Post visibility"
            selected={ value }
            options={ options }
            onChange={ ( v ) => {
				setValue( v );
				onChange( v );
			} } />
    );
};
With Option Descriptions story ok
const WithOptionDescriptions = () => {
    const [ value, setValue ] = useState( options?.[ 0 ]?.value );

    return (
        <RadioControl
            selected={ value }
            options={ options }
            onChange={ ( v ) => {
				setValue( v );
				onChange( v );
			} } />
    );
};

RangeControl

components-rangecontrol · ../packages/components/src/range-control/stories/index.story.tsx
RangeControls are used to make selections from a range of incremental values. ```jsx import { RangeControl } from '@wordpress/components'; import { useState } from '@wordpress/element'; const MyRangeControl = () => { const [ value, setValue ] = useState(); return ( <RangeControl __next40pxDefaultSize help="Please select how transparent you would like this." initialPosition={ 50 } label="Opacity" max={ 100 } min={ 0 } value={ value } onChange={ setValue } /> ); }; ```
Imports
import { RangeControl } from "@wordpress/components";
Default story ok
const Default = () => {
    const [ value, setValue ] = useState< number >();

    return (
        <RangeControl
            __next40pxDefaultSize
            onBlur={fn()}
            onFocus={fn()}
            onMouseLeave={fn()}
            onMouseMove={fn()}
            help="Please select how transparent you would like this."
            initialPosition={50}
            label="Opacity"
            max={100}
            min={0}
            value={ value }
            onChange={ ( v ) => {
				setValue( v );
				onChange?.( v );
			} } />
    );
};
With Any Step story ok
Setting the `step` prop to `"any"` will allow users to select non-integer values. This also overrides both `withInputField` and `showTooltip` props to `false`.
const WithAnyStep = () => {
    const [ value, setValue ] = useState< number >();

    return (
        <>
            <RangeControl
                __next40pxDefaultSize
                onBlur={fn()}
                onFocus={fn()}
                onMouseLeave={fn()}
                onMouseMove={fn()}
                label="Brightness"
                step="any"
                value={ value }
                onChange={ ( v ) => {
					setValue( v );
					onChange?.( v );
				} } />
            <hr style={ { marginTop: '5em' } } />
            <p>Current value: { value }</p>
        </>
    );
};
With Integer Step And Marks story ok
Use `marks` to render a visual representation of `step` ticks. Marks may be automatically generated or custom mark indicators can be provided by an `Array`.
const WithIntegerStepAndMarks = () => {
    const [ automaticValue, setAutomaticValue ] = useState< number >();
    const [ customValue, setCustomValue ] = useState< number >();

    return (
        <>
            <h2>{ label }</h2>
            <RangeControl
                __next40pxDefaultSize
                onBlur={fn()}
                onFocus={fn()}
                onMouseLeave={fn()}
                onMouseMove={fn()}
                max={10}
                min={0}
                step={1}
                label="Automatic marks"
                marks
                onChange={ ( v ) => {
					setAutomaticValue( v );
					onChange?.( v );
				} }
                value={ automaticValue } />
            <RangeControl
                __next40pxDefaultSize
                onBlur={fn()}
                onFocus={fn()}
                onMouseLeave={fn()}
                onMouseMove={fn()}
                marks={marksBase}
                max={10}
                min={0}
                step={1}
                label="Custom marks"
                onChange={ ( v ) => {
					setCustomValue( v );
					onChange?.( v );
				} }
                value={ customValue } />
        </>
    );
};
With Decimal Step And Marks story ok
Decimal values may be used for `marks` rendered as a visual representation of `step` ticks. Marks may be automatically generated or custom mark indicators can be provided by an `Array`.
const WithDecimalStepAndMarks = () => {
    const [ automaticValue, setAutomaticValue ] = useState< number >();
    const [ customValue, setCustomValue ] = useState< number >();

    return (
        <>
            <h2>{ label }</h2>
            <RangeControl
                __next40pxDefaultSize
                onBlur={fn()}
                onFocus={fn()}
                onMouseLeave={fn()}
                onMouseMove={fn()}
                max={10}
                min={0}
                step={0.1}
                label="Automatic marks"
                marks
                onChange={ ( v ) => {
					setAutomaticValue( v );
					onChange?.( v );
				} }
                value={ automaticValue } />
            <RangeControl
                __next40pxDefaultSize
                onBlur={fn()}
                onFocus={fn()}
                onMouseLeave={fn()}
                onMouseMove={fn()}
                marks={[
                    ...marksBase,
                    { value: 3.5, label: '3.5' },
                    { value: 5.8, label: '5.8' },
                ]}
                max={10}
                min={0}
                step={0.1}
                label="Custom marks"
                onChange={ ( v ) => {
					setCustomValue( v );
					onChange?.( v );
				} }
                value={ customValue } />
        </>
    );
};
With Negative Minimum And Marks story ok
A negative `min` value can be used to constrain `RangeControl` values. Mark indicators can represent negative values as well. Marks may be automatically generated or custom mark indicators can be provided by an `Array`.
const WithNegativeMinimumAndMarks = () => {
    const [ automaticValue, setAutomaticValue ] = useState< number >();
    const [ customValue, setCustomValue ] = useState< number >();

    return (
        <>
            <h2>{ label }</h2>
            <RangeControl
                __next40pxDefaultSize
                onBlur={fn()}
                onFocus={fn()}
                onMouseLeave={fn()}
                onMouseMove={fn()}
                max={10}
                min={-10}
                step={1}
                label="Automatic marks"
                marks
                onChange={ ( v ) => {
					setAutomaticValue( v );
					onChange?.( v );
				} }
                value={ automaticValue } />
            <RangeControl
                __next40pxDefaultSize
                onBlur={fn()}
                onFocus={fn()}
                onMouseLeave={fn()}
                onMouseMove={fn()}
                marks={marksWithNegatives}
                max={10}
                min={-10}
                step={1}
                label="Custom marks"
                onChange={ ( v ) => {
					setCustomValue( v );
					onChange?.( v );
				} }
                value={ customValue } />
        </>
    );
};
With Negative Range And Marks story ok
The entire range of valid values for a `RangeControl` may be negative. Mark indicators can represent negative values as well. Marks may be automatically generated or custom mark indicators can be provided by an `Array`.
const WithNegativeRangeAndMarks = () => {
    const [ automaticValue, setAutomaticValue ] = useState< number >();
    const [ customValue, setCustomValue ] = useState< number >();

    return (
        <>
            <h2>{ label }</h2>
            <RangeControl
                __next40pxDefaultSize
                onBlur={fn()}
                onFocus={fn()}
                onMouseLeave={fn()}
                onMouseMove={fn()}
                max={-1}
                min={-10}
                step={1}
                label="Automatic marks"
                marks
                onChange={ ( v ) => {
					setAutomaticValue( v );
					onChange?.( v );
				} }
                value={ automaticValue } />
            <RangeControl
                __next40pxDefaultSize
                onBlur={fn()}
                onFocus={fn()}
                onMouseLeave={fn()}
                onMouseMove={fn()}
                marks={marksWithNegatives}
                max={-1}
                min={-10}
                step={1}
                label="Custom marks"
                onChange={ ( v ) => {
					setCustomValue( v );
					onChange?.( v );
				} }
                value={ customValue } />
        </>
    );
};
With Any Step And Marks story ok
When a `RangeControl` has a `step` value of `any` a user may select non-integer values. This may still be used in conjunction with `marks` rendering a visual representation of `step` ticks.
const WithAnyStepAndMarks = () => {
    const [ automaticValue, setAutomaticValue ] = useState< number >();
    const [ customValue, setCustomValue ] = useState< number >();

    return (
        <>
            <h2>{ label }</h2>
            <RangeControl
                __next40pxDefaultSize
                onBlur={fn()}
                onFocus={fn()}
                onMouseLeave={fn()}
                onMouseMove={fn()}
                max={10}
                min={0}
                step="any"
                label="Automatic marks"
                marks
                onChange={ ( v ) => {
					setAutomaticValue( v );
					onChange?.( v );
				} }
                value={ automaticValue } />
            <RangeControl
                __next40pxDefaultSize
                onBlur={fn()}
                onFocus={fn()}
                onMouseLeave={fn()}
                onMouseMove={fn()}
                marks={marksBase}
                max={10}
                min={0}
                step="any"
                label="Custom marks"
                onChange={ ( v ) => {
					setCustomValue( v );
					onChange?.( v );
				} }
                value={ customValue } />
        </>
    );
};

ResizableBox

components-resizablebox · ../packages/components/src/resizable-box/stories/index.story.tsx
Info
No description found. Write a jsdoc comment such as /** Component description */.
Prop types 4 prop types
Component: ../packages/components/src/resizable-box/index.tsx::ResizableBox
Props:
__experimentalShowTooltip?: boolean = false

__experimentalTooltipProps?: Parameters< typeof ResizeTooltip >[ 0 ] = {}

children: ReactNode

showHandle?: boolean = true
Imports
import { ResizableBox } from "@wordpress/components";
Default story ok
const Default = ( {
	onResizeStop,
	...props
} ) => {
	const [ { height, width }, setAttributes ] = useState( {
		height: 200,
		width: 400,
	} );

	return (
		<ResizableBox
			{ ...props }
			size={ {
				height,
				width,
			} }
			onResizeStop={ ( event, direction, elt, delta ) => {
				onResizeStop?.( event, direction, elt, delta );
				setAttributes( {
					height: height + delta.height,
					width: width + delta.width,
				} );
			} }
		/>
	);
};
Disabled Directions story ok
The `enable` prop can be used to disable resizing in specific directions.
const DisabledDirections = ( {
	onResizeStop,
	...props
} ) => {
	const [ { height, width }, setAttributes ] = useState( {
		height: 200,
		width: 400,
	} );

	return (
		<ResizableBox
			{ ...props }
			size={ {
				height,
				width,
			} }
			onResizeStop={ ( event, direction, elt, delta ) => {
				onResizeStop?.( event, direction, elt, delta );
				setAttributes( {
					height: height + delta.height,
					width: width + delta.width,
				} );
			} }
		/>
	);
};

SandBox

components-sandbox · ../packages/components/src/sandbox/stories/index.story.tsx
This component provides an isolated environment for arbitrary HTML via iframes. ```jsx import { SandBox } from '@wordpress/components'; const MySandBox = () => ( <SandBox html="<p>Content</p>" title="SandBox" type="embed" /> ); ```
Prop types 8 prop types
Component: ../packages/components/src/sandbox/index.tsx::default
Props:
/**
 * Whether to include `allow-same-origin` in the iframe's sandbox
 * attribute. When true, nested iframes (such as third-party embeds)
 * can access their own origin's cookies and storage.
 * 
 * Only enable this for content that is NOT directly user-controlled,
 * such as server-fetched oEmbed previews.
 * 
 * @default false
 */
allowSameOrigin?: boolean = false

/**
 * The HTML to render in the body of the iframe document.
 * 
 * @default ''
 */
html?: string

/**
 * The `onFocus` callback for the iframe.
 */
onFocus?: React.DOMAttributes< HTMLIFrameElement >[ 'onFocus' ]

/**
 * An array of script URLs to inject as `<script>` tags into the bottom of the `<body>` of the iframe document.
 * 
 * @default []
 */
scripts?: string[]

/**
 * An array of CSS strings to inject into the `<head>` of the iframe document.
 * 
 * @default []
 */
styles?: string[]

/**
 * The `tabindex` the iframe should receive.
 * 
 * @default 0
 */
tabIndex?: HTMLElement[ 'tabIndex' ]

/**
 * The `<title>` of the iframe document.
 * 
 * @default ''
 */
title?: string

/**
 * The CSS class name to apply to the `<html>` and `<body>` elements of the iframe.
 */
type?: string
Imports
import { SandBox } from "@wordpress/components";
Default story ok
const Default = () => <SandBox onFocus={fn()} html="<p>Arbitrary HTML content</p>" />;

ScrollLock

components-scrolllock · ../packages/components/src/scroll-lock/stories/index.story.tsx
Prop type error
File: /home/runner/work/gutenberg/gutenberg/packages/components/src/scroll-lock/index.tsx
Error:
No suitable component definition found.
You can debug your component file in this playground: https://react-docgen.dev/playground
Code:
/**
 * WordPress dependencies
 */
import { useEffect } from '@wordpress/element';

/*
 * Setting `overflow: hidden` on html and body elements resets body scroll in iOS.
 * Save scroll top so we can restore it after locking scroll.
 *
 * NOTE: It would be cleaner and possibly safer to find a localized solution such
 * as preventing default on certain touchmove events.
 */
let previousScrollTop = 0;

function setLocked( locked: boolean ) {
	const scrollingElement = document.scrollingElement || document.body;

	if ( locked ) {
		previousScrollTop = scrollingElement.scrollTop;
	}

	const methodName = locked ? 'add' : 'remove';
	scrollingElement.classList[ methodName ]( 'lockscroll' );

	// Adding the class to the document element seems to be necessary in iOS.
	document.documentElement.classList[ methodName ]( 'lockscroll' );

	if ( ! locked ) {
		scrollingElement.scrollTop = previousScrollTop;
	}
}

let lockCounter = 0;

/**
 * ScrollLock is a content-free React component for declaratively preventing
 * scroll bleed from modal UI to the page body. This component applies a
 * `lockscroll` class to the `document.documentElement` and
 * `document.scrollingElement` elements to stop the body from scrolling. When it
 * is present, the lock is applied.
 *
 * ```jsx
 * import { ScrollLock, Button } from '@wordpress/components';
 * import { useState } from '@wordpress/element';
 *
 * const MyScrollLock = () => {
 *   const [ isScrollLocked, setIsScrollLocked ] = useState( false );
 *
 *   const toggleLock = () => {
 *     setIsScrollLocked( ( locked ) => ! locked ) );
 *   };
 *
 *   return (
 *     <div>
 *       <Button variant="secondary" onClick={ toggleLock }>
 *         Toggle scroll lock
 *       </Button>
 *       { isScrollLocked && <ScrollLock /> }
 *       <p>
 *         Scroll locked:
 *         <strong>{ isScrollLocked ? 'Yes' : 'No' }</strong>
 *       </p>
 *     </div>
 *   );
 * };
 * ```
 */
export function ScrollLock(): null {
	useEffect( () => {
		if ( lockCounter === 0 ) {
			setLocked( true );
		}

		++lockCounter;

		return () => {
			if ( lockCounter === 1 ) {
				setLocked( false );
			}

			--lockCounter;
		};
	}, [] );

	return null;
}

export default ScrollLock;
Info
No description found. Write a jsdoc comment such as /** Component description */.
Imports
import { Button, ScrollLock } from "@wordpress/components";
Default story ok
const Default = () => {
	const [ isScrollLocked, setScrollLocked ] = useState( false );
	const toggleLock = () => setScrollLocked( ! isScrollLocked );

	return (
		<div style={ { height: 1000 } }>
			<div
				style={ {
					overflow: 'auto',
					height: 240,
					border: '1px solid lightgray',
				} }
			>
				<StripedBackground>
					<div>
						Start scrolling down. Once you scroll to the end of this
						container with the stripes, the rest of the page will
						continue scrolling. <code>ScrollLock</code> prevents
						this &quot;scroll bleed&quot; from happening.
					</div>
					<ToggleContainer>
						<Button
							__next40pxDefaultSize
							variant="primary"
							onClick={ toggleLock }
						>
							Toggle Scroll Lock
						</Button>
						{ isScrollLocked && <ScrollLock /> }
						<p>
							Scroll locked:{ ' ' }
							<strong>{ isScrollLocked ? 'Yes' : 'No' }</strong>
						</p>
					</ToggleContainer>
				</StripedBackground>
			</div>
		</div>
	);
};

SearchControl

components-searchcontrol · ../packages/components/src/search-control/stories/index.story.tsx
SearchControl components let users display a search control. ```jsx import { SearchControl } from '@wordpress/components'; import { useState } from '@wordpress/element'; function MySearchControl( { className, setState } ) { const [ searchInput, setSearchInput ] = useState( '' ); return ( <SearchControl value={ searchInput } onChange={ setSearchInput } /> ); } ```
Prop types 4 prop types
Component: ../packages/components/src/search-control/index.tsx::SearchControl
Props:
hideLabelFromVision?: any = true

label?: any = __( 'Search' )

placeholder?: any = __( 'Search' )

size?: any = 'default'
Imports
import { SearchControl } from "@wordpress/components";
Default story ok
const Default = ( {
	onChange,
	...props
} ) => {
	const [ value, setValue ] = useState< string >();

	return (
		<SearchControl
			{ ...props }
			value={ value }
			onChange={ ( ...changeArgs ) => {
				setValue( ...changeArgs );
				onChange( ...changeArgs );
			} }
		/>
	);
};

SelectControl

components-selectcontrol · ../packages/components/src/select-control/stories/index.story.tsx
`SelectControl` allows users to select from a single or multiple option menu. It functions as a wrapper around the browser's native `<select>` element. ```jsx import { SelectControl } from '@wordpress/components'; import { useState } from '@wordpress/element'; const MySelectControl = () => { const [ size, setSize ] = useState( '50%' ); return ( <SelectControl __next40pxDefaultSize label="Size" value={ size } options={ [ { label: 'Big', value: '100%' }, { label: 'Medium', value: '50%' }, { label: 'Small', value: '25%' }, ] } onChange={ setSize } /> ); }; ```
Imports
import { InputControlPrefixWrapper, SelectControl } from "@wordpress/components";
Default story ok
const Default = ( props ) => {
	const [ selection, setSelection ] = useState< string[] >();

	if ( props.multiple ) {
		return (
			<SelectControl
				__next40pxDefaultSize
				{ ...props }
				multiple
				value={ selection }
				onChange={ ( value ) => {
					setSelection( value );
					props.onChange?.( value );
				} }
			/>
		);
	}

	return (
		<SelectControl
			__next40pxDefaultSize
			{ ...props }
			multiple={ false }
			value={ selection?.[ 0 ] }
			onChange={ ( value ) => {
				setSelection( [ value ] );
				props.onChange?.( value );
			} }
		/>
	);
};
With Label And Help Text story ok
const WithLabelAndHelpText = ( props ) => {
	const [ selection, setSelection ] = useState< string[] >();

	if ( props.multiple ) {
		return (
			<SelectControl
				__next40pxDefaultSize
				{ ...props }
				multiple
				value={ selection }
				onChange={ ( value ) => {
					setSelection( value );
					props.onChange?.( value );
				} }
			/>
		);
	}

	return (
		<SelectControl
			__next40pxDefaultSize
			{ ...props }
			multiple={ false }
			value={ selection?.[ 0 ] }
			onChange={ ( value ) => {
				setSelection( [ value ] );
				props.onChange?.( value );
			} }
		/>
	);
};
With Custom Children story ok
As an alternative to the `options` prop, `optgroup`s and `options` can be passed in as `children` for more customizeability.
const WithCustomChildren = ( props ) => {
	const [ selection, setSelection ] = useState< string[] >();

	if ( props.multiple ) {
		return (
			<SelectControl
				__next40pxDefaultSize
				{ ...props }
				multiple
				value={ selection }
				onChange={ ( value ) => {
					setSelection( value );
					props.onChange?.( value );
				} }
			/>
		);
	}

	return (
		<SelectControl
			__next40pxDefaultSize
			{ ...props }
			multiple={ false }
			value={ selection?.[ 0 ] }
			onChange={ ( value ) => {
				setSelection( [ value ] );
				props.onChange?.( value );
			} }
		/>
	);
};
With Prefix story ok
By default, the prefix is aligned with the edge of the input border, with no padding. If you want to apply standard padding in accordance with the size variant, wrap the element in the `<InputControlPrefixWrapper>` component.
const WithPrefix = ( props ) => {
	const [ selection, setSelection ] = useState< string[] >();

	if ( props.multiple ) {
		return (
			<SelectControl
				__next40pxDefaultSize
				{ ...props }
				multiple
				value={ selection }
				onChange={ ( value ) => {
					setSelection( value );
					props.onChange?.( value );
				} }
			/>
		);
	}

	return (
		<SelectControl
			__next40pxDefaultSize
			{ ...props }
			multiple={ false }
			value={ selection?.[ 0 ] }
			onChange={ ( value ) => {
				setSelection( [ value ] );
				props.onChange?.( value );
			} }
		/>
	);
};
Minimal story ok
const Minimal = ( props ) => {
	const [ selection, setSelection ] = useState< string[] >();

	if ( props.multiple ) {
		return (
			<SelectControl
				__next40pxDefaultSize
				{ ...props }
				multiple
				value={ selection }
				onChange={ ( value ) => {
					setSelection( value );
					props.onChange?.( value );
				} }
			/>
		);
	}

	return (
		<SelectControl
			__next40pxDefaultSize
			{ ...props }
			multiple={ false }
			value={ selection?.[ 0 ] }
			onChange={ ( value ) => {
				setSelection( [ value ] );
				props.onChange?.( value );
			} }
		/>
	);
};

Shortcut

components-shortcut · ../packages/components/src/shortcut/stories/index.story.tsx
Shortcut component is used to display keyboard shortcuts, and it can be customized with a custom display and aria label if needed. ```jsx import { Shortcut } from '@wordpress/components'; const MyShortcut = () => { return ( <Shortcut shortcut={{ display: 'Ctrl + S', ariaLabel: 'Save' }} /> ); }; ```
Prop types 2 prop types
Component: ../packages/components/src/shortcut/index.tsx::default
Props:
/**
 * Classname to apply to the shortcut.
 */
className?: string

/**
 * Shortcut configuration
 */
shortcut?: string | { display: string; ariaLabel: string }
Imports
import { Shortcut } from "@wordpress/components";
Default story ok
const Default = ( props ) => {
	return <Shortcut shortcut="Ctrl + S" { ...props } />;
};
With Aria Label story ok
const WithAriaLabel = ( props ) => {
	return <Shortcut shortcut="Ctrl + S" { ...props } />;
};

Slot

components-slotfill · ../packages/components/src/slot-fill/stories/index.story.tsx
Info
No description found. Write a jsdoc comment such as /** Component description */.
Imports
import { Fill, Slot, Provider as SlotFillProvider } from "@wordpress/components";
Default story ok
const Default = ( props ) => {
	return (
		<SlotFillProvider>
			<h2>Profile</h2>
			<p>
				Name: <Slot { ...props } name="name" />
			</p>
			<p>
				Age: <Slot { ...props } name="age" />
			</p>
			<Fill name="name">Grace</Fill>
			<Fill name="age">33</Fill>
		</SlotFillProvider>
	);
};
With Fill Props story ok
const WithFillProps = ( props ) => {
	return (
		<SlotFillProvider>
			<h2>Profile</h2>
			<p>
				Name:{ ' ' }
				<Slot
					{ ...props }
					name="name"
					fillProps={ { name: 'Grace' } }
				/>
			</p>
			<p>
				Age: <Slot { ...props } name="age" fillProps={ { age: 33 } } />
			</p>

			<Fill name="name">{ ( fillProps ) => fillProps.name }</Fill>
			<Fill name="age">{ ( fillProps ) => fillProps.age }</Fill>
		</SlotFillProvider>
	);
};
With Slot Children story ok
const WithSlotChildren = ( props ) => {
	return (
		<SlotFillProvider>
			<h2>Profile</h2>
			<p>
				Name:
				{ /* @ts-expect-error Not supported children for `<Slot />` when `bubblesVirtually` is true. */ }
				<Slot { ...props } name="name">
					{ ( fills ) => {
						return (
							<span style={ { color: 'red' } }>{ fills }</span>
						);
					} }
				</Slot>
			</p>
			<p>
				Age:
				{ /* @ts-expect-error Not support children for `<Slot />` when `bubblesVirtually` is true. */ }
				<Slot { ...props } name="age">
					{ ( fills ) => {
						return (
							<span style={ { color: 'red' } }>{ fills }</span>
						);
					} }
				</Slot>
			</p>
			<Fill name="name">Alice</Fill>
			<Fill name="age">18</Fill>
		</SlotFillProvider>
	);
};
With Context story ok
const WithContext = ( props ) => {
	const Context = createContext< string | number >( '' );
	const ContextFill = ( { name }: { name: string } ) => {
		const value = useContext( Context );
		return <Fill name={ name }>{ value }</Fill>;
	};
	return (
		<SlotFillProvider>
			<h2>Profile</h2>
			<p>
				Name: <Slot { ...props } name="name" />
			</p>
			<p>
				Age: <Slot { ...props } name="age" />
			</p>
			<Context.Provider value="Grace">
				<ContextFill name="name" />
			</Context.Provider>
			<Context.Provider value={ 33 }>
				<ContextFill name="age" />
			</Context.Provider>
		</SlotFillProvider>
	);
};

Snackbar

components-snackbar · ../packages/components/src/snackbar/stories/index.story.tsx
A Snackbar displays a succinct message that is cleared out after a small delay. It can also offer the user options, like viewing a published post. But these options should also be available elsewhere in the UI. ```jsx const MySnackbarNotice = () => ( <Snackbar>Post published successfully.</Snackbar> ); ```
Prop types 5 prop types
Component: ../packages/components/src/snackbar/index.tsx::Snackbar
Props:
actions?: any = []

explicitDismiss?: any = false

icon?: any = null

politeness?: any = 'polite'

spokenMessage?: any = children
Imports
import { Icon, Snackbar } from "@wordpress/components";
Default story ok
const Default = ( {
	children,
	...props
} ) => {
	return <Snackbar { ...props }>{ children }</Snackbar>;
};
With Actions story ok
const WithActions = ( {
	children,
	...props
} ) => {
	return <Snackbar { ...props }>{ children }</Snackbar>;
};
With Icon story ok
const WithIcon = ( {
	children,
	...props
} ) => {
	return <Snackbar { ...props }>{ children }</Snackbar>;
};
With Explicit Dismiss story ok
const WithExplicitDismiss = ( {
	children,
	...props
} ) => {
	return <Snackbar { ...props }>{ children }</Snackbar>;
};
With Action And Explicit Dismiss story ok
const WithActionAndExplicitDismiss = ( {
	children,
	...props
} ) => {
	return <Snackbar { ...props }>{ children }</Snackbar>;
};

Spinner

components-spinner · ../packages/components/src/spinner/stories/index.story.tsx
`Spinner` is a component used to notify users that their action is being processed. ```jsx import { Spinner } from '@wordpress/components'; function Example() { return <Spinner />; } ```
Imports
import { Spinner } from "@wordpress/components";
Default story ok
const Default = () => {
    return <Spinner />;
};
Custom Size story ok
const CustomSize = () => {
    return <Spinner style={{ width: space( 20 ), height: space( 20 ) }} />;
};

Stack

design-system-components-stack · ../packages/ui/src/stack/stories/index.story.tsx
A flexible layout component using CSS Flexbox for consistent spacing and alignment. Built on design tokens for predictable spacing values.
Prop types 9 prop types
Component: ../packages/ui/src/stack/stack.tsx::Stack
Props:
/**
 * The alignment of the stack items along the cross axis.
 * 
 * @default 'initial'
 */
align?: React.CSSProperties[ 'alignItems' ]

/**
 * The content to be rendered inside the component.
 */
children?: React.ReactNode

/**
 * CSS class name to apply to the element.
 */
className?: string

/**
 * The direction of the stack.
 */
direction?: Exclude<
	React.CSSProperties[ 'flexDirection' ],
	'row-reverse' | 'column-reverse'
>

/**
 * The amount of space between each child element using design system tokens.
 * 
 * @default undefined
 */
gap?: GapSize

/**
 * The alignment of the stack items along the main axis.
 * 
 * @default 'initial'
 */
justify?: React.CSSProperties[ 'justifyContent' ]

/**
 * Replaces the component's default HTML element using a given React
 * element, or a function that returns a React element.
 */
render?: | ComponentRenderFn< HTMLAttributesWithRef >
| React.ReactElement< Record< string, unknown > >

/**
 * CSS style to apply to the element.
 */
style?: React.CSSProperties

/**
 * Whether the stack items should wrap to the next line.
 */
wrap?: Exclude< React.CSSProperties[ 'flexWrap' ], 'wrap-reverse' >
Imports
import { Stack } from "@wordpress/ui";
Default story ok
const Default = () => <Stack gap="md">(<>
        <DemoBox />
        <DemoBox variant="lg" />
        <DemoBox />
        <DemoBox />
        <DemoBox variant="lg" />
        <DemoBox />
    </>)</Stack>;
Nested story ok
const Nested = () => <Stack align="center" justify="center">(<>
        <DemoBox variant="lg" />
        <Stack gap="lg">
            <DemoBox />
            <DemoBox />
        </Stack>
        <DemoBox variant="lg" />
        <Stack direction="column">
            <DemoBox />
            <DemoBox />
        </Stack>
        <DemoBox variant="lg" />
    </>)</Stack>;

Tabs.Root

design-system-components-tabs · ../packages/ui/src/tabs/stories/index.story.tsx
Groups the tabs and the corresponding panels. `Tabs` is a collection of React components that combine to render an [ARIA-compliant tabs pattern](https://www.w3.org/WAI/ARIA/apg/patterns/tabs/).
Prop types 4 prop types
Component: ../packages/ui/src/tabs/root.tsx::Root
Props:
/**
 * The content to be rendered inside the component.
 */
children?: ReactNode

/**
 * CSS class name to apply to the element.
 */
className?: string

/**
 * Replaces the component's default HTML element using a given React
 * element, or a function that returns a React element.
 */
render?: | ComponentRenderFn< HTMLAttributesWithRef >
| React.ReactElement< Record< string, unknown > >

/**
 * CSS style to apply to the element.
 */
style?: React.CSSProperties
Imports
import { List, Panel, Root, Tab, Popup, Positioner, Trigger } from "@wordpress/ui";
Default story ok
const Default = () => <Tabs.Root defaultValue="tab1">(<>
        <Tabs.List>
            <Tabs.Tab value="tab1">Tab 1</Tabs.Tab>
            <Tabs.Tab value="tab2">Tab 2</Tabs.Tab>
            <Tabs.Tab value="tab3">Tab 3</Tabs.Tab>
        </Tabs.List>
        <Tabs.Panel value="tab1">
            <ThemedParagraph>Selected tab: Tab 1</ThemedParagraph>
        </Tabs.Panel>
        <Tabs.Panel value="tab2">
            <ThemedParagraph>Selected tab: Tab 2</ThemedParagraph>
        </Tabs.Panel>
        <Tabs.Panel value="tab3">
            <ThemedParagraph>Selected tab: Tab 3</ThemedParagraph>
        </Tabs.Panel>
    </>)</Tabs.Root>;
Minimal story ok
const Minimal = () => <Tabs.Root>(<>
        <Tabs.List variant="minimal">
            <Tabs.Tab value="tab1">Tab 1</Tabs.Tab>
            <Tabs.Tab value="tab2">Tab 2</Tabs.Tab>
            <Tabs.Tab value="tab3">Tab 3</Tabs.Tab>
        </Tabs.List>
        <Tabs.Panel value="tab1">
            <ThemedParagraph>Selected tab: Tab 1</ThemedParagraph>
        </Tabs.Panel>
        <Tabs.Panel value="tab2">
            <ThemedParagraph>Selected tab: Tab 2</ThemedParagraph>
        </Tabs.Panel>
        <Tabs.Panel value="tab3">
            <ThemedParagraph>Selected tab: Tab 3</ThemedParagraph>
        </Tabs.Panel>
    </>)</Tabs.Root>;
Size And Overflow Playground story ok
const SizeAndOverflowPlayground = function SizeAndOverflowPlayground( props ) {
    const [ fullWidth, setFullWidth ] = useState( false );
    return (
        <div>
            <div
                style={ {
                    maxWidth: '40rem',
                    marginBottom: '1rem',
                    color: 'var( --wpds-color-fg-content-neutral )',
                } }
            >
                <p>
                    This story helps understand how the TabList component
                    behaves under different conditions. The container below
                    (with the dotted red border) can be horizontally
                    resized, and it has a bit of padding to be out of the
                    way of the TabList.
                </p>
                <p>
                    The button will toggle between full width (adding{ ' ' }
                    <code>width: 100%</code>) and the default width.
                </p>
                <p>Try the following:</p>
                <ul>
                    <li>
                        <strong>Small container</strong> that causes tabs to
                        overflow with scroll.
                    </li>
                    <li>
                        <strong>Large container</strong> that exceeds the
                        normal width of the tabs.
                        <ul>
                            <li>
                                <strong>
                                    With <code>width: 100%</code>
                                </strong>{ ' ' }
                                set on the TabList (tabs fill up the space).
                            </li>
                            <li>
                                <strong>
                                    Without <code>width: 100%</code>
                                </strong>{ ' ' }
                                (defaults to <code>auto</code>) set on the
                                TabList (tabs take up space proportional to
                                their content).
                            </li>
                        </ul>
                    </li>
                </ul>
            </div>
            <button
                style={ { marginBottom: '1rem' } }
                onClick={ () => setFullWidth( ! fullWidth ) }
            >
                { fullWidth
                    ? 'Remove width: 100% from TabList'
                    : 'Set width: 100% in TabList' }
            </button>
            <Tabs.Root
                { ...props }
                style={ {
                    ...props.style,
                    width: '20rem',
                    border: '2px dotted red',
                    padding: '1rem',
                    resize: 'horizontal',
                    overflow: 'auto',
                } }
            >
                <Tabs.List
                    style={ {
                        maxWidth: '100%',
                        width: fullWidth ? '100%' : undefined,
                    } }
                >
                    <Tabs.Tab value="tab1">
                        Label with multiple words
                    </Tabs.Tab>
                    <Tabs.Tab value="tab2">Short</Tabs.Tab>
                    <Tabs.Tab value="tab3">
                        Hippopotomonstrosesquippedaliophobia
                    </Tabs.Tab>
                    <Tabs.Tab value="tab4">Tab 4</Tabs.Tab>
                    <Tabs.Tab value="tab5">Tab 5</Tabs.Tab>
                </Tabs.List>

                <Tabs.Panel value="tab1">
                    <ThemedParagraph>Selected tab: Tab 1</ThemedParagraph>
                    <ThemedParagraph>
                        (Label with multiple words)
                    </ThemedParagraph>
                </Tabs.Panel>
                <Tabs.Panel value="tab2">
                    <ThemedParagraph>Selected tab: Tab 2</ThemedParagraph>
                    <ThemedParagraph>(Short)</ThemedParagraph>
                </Tabs.Panel>
                <Tabs.Panel value="tab3">
                    <ThemedParagraph>Selected tab: Tab 3</ThemedParagraph>
                    <ThemedParagraph>
                        (Hippopotomonstrosesquippedaliophobia)
                    </ThemedParagraph>
                </Tabs.Panel>
                <Tabs.Panel value="tab4">
                    <ThemedParagraph>Selected tab: Tab 4</ThemedParagraph>
                </Tabs.Panel>
                <Tabs.Panel value="tab5">
                    <ThemedParagraph>Selected tab: Tab 5</ThemedParagraph>
                </Tabs.Panel>
            </Tabs.Root>
        </div>
    );
};
Vertical story ok
const Vertical = () => <Tabs.Root
    orientation="vertical"
    style={{
        minWidth: '320px',
        display: 'grid',
        gridTemplateColumns: '120px 1fr',
        gap: '24px',
    }} />;
With Disabled Tab story ok
const WithDisabledTab = () => <Tabs.Root defaultValue="tab3">(<>
        <Tabs.List>
            <Tabs.Tab value="tab1" disabled>
                Tab 1
            </Tabs.Tab>
            <Tabs.Tab value="tab2">Tab 2</Tabs.Tab>
            <Tabs.Tab value="tab3">Tab 3</Tabs.Tab>
        </Tabs.List>
        <Tabs.Panel value="tab1">
            <ThemedParagraph>Selected tab: Tab 1</ThemedParagraph>
        </Tabs.Panel>
        <Tabs.Panel value="tab2">
            <ThemedParagraph>Selected tab: Tab 2</ThemedParagraph>
        </Tabs.Panel>
        <Tabs.Panel value="tab3">
            <ThemedParagraph>Selected tab: Tab 3</ThemedParagraph>
        </Tabs.Panel>
    </>)</Tabs.Root>;
With Tab Icons And Tooltips story ok
const WithTabIconsAndTooltips = () => <Tabs.Root>(<>
        <Tabs.List>
            { tabWithIconsData.map(
                ( { value, label, icon: Icon } ) => (
                    <Tooltip.Root key={ value }>
                        <Tooltip.Trigger
                            aria-label={ label }
                            render={ <Tabs.Tab value={ value } /> }
                        >
                            { /* TODO: potentially refactor with new Icon component */ }
                            <Icon
                                style={ {
                                    width: '20px',
                                    height: '20px',
                                } }
                            />
                        </Tooltip.Trigger>
                        <Tooltip.Popup
                            positioner={
                                <Tooltip.Positioner
                                    align="center"
                                    side="top"
                                />
                            }
                        >
                            { label }
                        </Tooltip.Popup>
                    </Tooltip.Root>
                )
            ) }
        </Tabs.List>
        { tabWithIconsData.map( ( { value, label } ) => (
            <Tabs.Panel value={ value } key={ value }>
                <ThemedParagraph>
                    Selected tab: { label }
                </ThemedParagraph>
            </Tabs.Panel>
        ) ) }
    </>)</Tabs.Root>;
With Panels Always Mounted story ok
const WithPanelsAlwaysMounted = () => <Tabs.Root>(<>
        <Tabs.List>
            <Tabs.Tab value="tab1">Tab 1</Tabs.Tab>
            <Tabs.Tab value="tab2">Tab 2</Tabs.Tab>
            <Tabs.Tab value="tab3">Tab 3</Tabs.Tab>
        </Tabs.List>
        <Tabs.Panel value="tab1" keepMounted>
            <ThemedParagraph>Selected tab: Tab 1</ThemedParagraph>
        </Tabs.Panel>
        <Tabs.Panel value="tab2" keepMounted>
            <ThemedParagraph>Selected tab: Tab 2</ThemedParagraph>
        </Tabs.Panel>
        <Tabs.Panel value="tab3" keepMounted>
            <ThemedParagraph>Selected tab: Tab 3</ThemedParagraph>
        </Tabs.Panel>
    </>)</Tabs.Root>;
With Non Focusable Panels story ok
const WithNonFocusablePanels = () => <Tabs.Root>(<>
        <Tabs.List>
            <Tabs.Tab value="tab1">Tab 1</Tabs.Tab>
            <Tabs.Tab value="tab2">Tab 2</Tabs.Tab>
            <Tabs.Tab value="tab3">Tab 3</Tabs.Tab>
        </Tabs.List>
        <Tabs.Panel value="tab1" tabIndex={ -1 }>
            <ThemedParagraph>Selected tab: Tab 1</ThemedParagraph>
            <ThemedParagraph>
                This tabpanel is not focusable, therefore tabbing into
                it will focus its first tabbable child.
            </ThemedParagraph>
            <button>Focus me</button>
        </Tabs.Panel>
        <Tabs.Panel value="tab2" tabIndex={ -1 }>
            <ThemedParagraph>Selected tab: Tab 2</ThemedParagraph>
            <ThemedParagraph>
                This tabpanel is not focusable, therefore tabbing into
                it will focus its first tabbable child.
            </ThemedParagraph>
            <button>Focus me</button>
        </Tabs.Panel>
        <Tabs.Panel value="tab3" tabIndex={ -1 }>
            <ThemedParagraph>Selected tab: Tab 3</ThemedParagraph>
            <ThemedParagraph>
                This tabpanel is not focusable, therefore tabbing into
                it will focus its first tabbable child.
            </ThemedParagraph>
            <button>Focus me</button>
        </Tabs.Panel>
    </>)</Tabs.Root>;

Text

design-system-components-text · ../packages/ui/src/text/stories/index.story.tsx
A text component for rendering content with predefined typographic variants. Built on design tokens for consistent typography across the UI.
Prop types 5 prop types
Component: ../packages/ui/src/text/text.tsx::Text
Props:
/**
 * The content to be rendered inside the component.
 */
children?: React.ReactNode

/**
 * CSS class name to apply to the element.
 */
className?: string

/**
 * Replaces the component's default HTML element using a given React
 * element, or a function that returns a React element.
 */
render?: | ComponentRenderFn< HTMLAttributesWithRef >
| React.ReactElement< Record< string, unknown > >

/**
 * CSS style to apply to the element.
 */
style?: React.CSSProperties

/**
 * The typographic variant to apply, controlling font family, size,
 * line height, and weight.
 * 
 * @default "body-md"
 */
variant?: | 'heading-2xl'
| 'heading-xl'
| 'heading-lg'
| 'heading-md'
| 'heading-sm'
| 'body-xl'
| 'body-lg'
| 'body-md'
| 'body-sm' = 'body-md'
Imports
import { Stack, Text } from "@wordpress/ui";
Default story ok
const Default = () => <Text variant="body-md">The quick brown fox jumps over the lazy dog.</Text>;
All Variants story ok
Important: Setting the `variant` prop to a `heading` variant will not automatically render a heading element. Use the `render` prop to render a heading element with the appropriate level.
const AllVariants = () => (
    <Stack
        direction="column"
        gap="lg"
        style={ { color: 'var(--wpds-color-fg-content-neutral)' } }
    >
        { (
            [
                'heading-2xl',
                'heading-xl',
                'heading-lg',
                'heading-md',
                'heading-sm',
                'body-xl',
                'body-lg',
                'body-md',
                'body-sm',
            ] as const
         ).map( ( variant ) => (
            <Stack key={ variant } direction="column" gap="xs">
                <Text variant="heading-sm">{ variant }</Text>
                <Text variant={ variant }>
                    The quick brown fox jumps over the lazy dog.
                </Text>
            </Stack>
        ) ) }
    </Stack>
);
With Render Prop story ok
const WithRenderProp = () => (
    <Stack direction="column" gap="md">
        <Text variant="heading-2xl" render={ <h1 /> }>
            Page Title
        </Text>
        <Text variant="heading-xl" render={ <h2 /> }>
            Section Heading
        </Text>
        <Text variant="body-md" render={ <p /> }>
            A paragraph of body text rendered as a semantic paragraph
            element.
        </Text>
    </Stack>
);

TextareaControl

components-textareacontrol · ../packages/components/src/textarea-control/stories/index.story.tsx
TextareaControls are TextControls that allow for multiple lines of text, and wrap overflow text onto a new line. They are a fixed height and scroll vertically when the cursor reaches the bottom of the field. ```jsx import { TextareaControl } from '@wordpress/components'; import { useState } from '@wordpress/element'; const MyTextareaControl = () => { const [ text, setText ] = useState( '' ); return ( <TextareaControl label="Text" help="Enter some text" value={ text } onChange={ ( value ) => setText( value ) } /> ); }; ```
Imports
import { TextareaControl } from "@wordpress/components";
Default story ok
const Default = () => {
    const [ value, setValue ] = useState( '' );

    return (
        <TextareaControl
            label="Text"
            help="Enter some text"
            placeholder="Placeholder"
            value={ value }
            onChange={ ( v ) => {
				setValue( v );
				onChange( v );
			} } />
    );
};

TextControl

components-textcontrol · ../packages/components/src/text-control/stories/index.story.tsx
TextControl components let users enter and edit text. ```jsx import { TextControl } from '@wordpress/components'; import { useState } from '@wordpress/element'; const MyTextControl = () => { const [ className, setClassName ] = useState( '' ); return ( <TextControl __next40pxDefaultSize label="Additional CSS Class" value={ className } onChange={ ( value ) => setClassName( value ) } /> ); }; ```
Imports
import { TextControl } from "@wordpress/components";
Default story ok
const Default = () => {
    const [ value, setValue ] = useState( '' );

    return (
        <TextControl
            __next40pxDefaultSize
            placeholder="Placeholder"
            value={ value }
            onChange={ ( v ) => {
				setValue( v );
				onChange( v );
			} } />
    );
};
With Label And Help Text story ok
const WithLabelAndHelpText = () => {
    const [ value, setValue ] = useState( '' );

    return (
        <TextControl
            __next40pxDefaultSize
            label="Label Text"
            help="Help text to explain the input."
            value={ value }
            onChange={ ( v ) => {
				setValue( v );
				onChange( v );
			} } />
    );
};

TextHighlight

components-texthighlight · ../packages/components/src/text-highlight/stories/index.story.tsx
Highlights occurrences of a given string within another string of text. Wraps each match with a `<mark>` tag which provides browser default styling. ```jsx import { TextHighlight } from '@wordpress/components'; const MyTextHighlight = () => ( <TextHighlight text="Why do we like Gutenberg? Because Gutenberg is the best!" highlight="Gutenberg" /> ); ```
Prop types 2 prop types
Component: ../packages/components/src/text-highlight/index.tsx::TextHighlight
Props:
/**
 * The string to search for and highlight within the `text`. Case
 * insensitive. Multiple matches.
 * 
 * @default ''
 */
highlight: string

/**
 * The string of text to be tested for occurrences of then given
 * `highlight`.
 * 
 * @default ''
 */
text: string
Imports
import { TextHighlight } from "@wordpress/components";
Default story ok
const Default = () => {
    return (
        <TextHighlight
            text="We call the new editor Gutenberg. The entire editing experience has been rebuilt for media rich pages and posts."
            highlight="Gutenberg" />
    );
};

ToggleControl

components-togglecontrol · ../packages/components/src/toggle-control/stories/index.story.tsx
ToggleControl is used to generate a toggle user interface. ```jsx import { ToggleControl } from '@wordpress/components'; import { useState } from '@wordpress/element'; const MyToggleControl = () => { const [ value, setValue ] = useState( false ); return ( <ToggleControl label="Fixed Background" checked={ value } onChange={ () => setValue( ( state ) => ! state ) } /> ); }; ```
Imports
import { ToggleControl } from "@wordpress/components";
Default story ok
const Default = ( {
	onChange,
	...props
} ) => {
	const [ checked, setChecked ] = useState( true );
	return (
		<ToggleControl
			{ ...props }
			checked={ checked }
			onChange={ ( ...changeArgs ) => {
				setChecked( ...changeArgs );
				onChange( ...changeArgs );
			} }
		/>
	);
};
With Help Text story ok
const WithHelpText = ( {
	onChange,
	...props
} ) => {
	const [ checked, setChecked ] = useState( true );
	return (
		<ToggleControl
			{ ...props }
			checked={ checked }
			onChange={ ( ...changeArgs ) => {
				setChecked( ...changeArgs );
				onChange( ...changeArgs );
			} }
		/>
	);
};

ToggleGroupControl

components-togglegroupcontrol · ../packages/components/src/toggle-group-control/stories/index.story.tsx
Info
No description found. Write a jsdoc comment such as /** Component description */.
Imports
import { ToggleGroupControl, ToggleGroupControlOption, ToggleGroupControlOptionIcon } from "@wordpress/components";
Default story ok
const Default = ( {
	onChange,
	...props
} ) => {
	const [ value, setValue ] =
		useState< ToggleGroupControlProps[ 'value' ] >();

	return (
		<ToggleGroupControl
			__next40pxDefaultSize
			{ ...props }
			onChange={ ( ...changeArgs ) => {
				setValue( ...changeArgs );
				onChange?.( ...changeArgs );
			} }
			value={ value }
		/>
	);
};
With Tooltip story ok
A tooltip can be shown for each option by enabling the `showTooltip` prop. The `aria-label` will be used in the tooltip if provided. Otherwise, the `label` will be used.
const WithTooltip = ( {
	onChange,
	...props
} ) => {
	const [ value, setValue ] =
		useState< ToggleGroupControlProps[ 'value' ] >();

	return (
		<ToggleGroupControl
			__next40pxDefaultSize
			{ ...props }
			onChange={ ( ...changeArgs ) => {
				setValue( ...changeArgs );
				onChange?.( ...changeArgs );
			} }
			value={ value }
		/>
	);
};
With Icons story ok
The `ToggleGroupControlOptionIcon` component can be used for icon options. A `label` is required on each option for accessibility, which will be shown in a tooltip.
const WithIcons = ( {
	onChange,
	...props
} ) => {
	const [ value, setValue ] =
		useState< ToggleGroupControlProps[ 'value' ] >();

	return (
		<ToggleGroupControl
			__next40pxDefaultSize
			{ ...props }
			onChange={ ( ...changeArgs ) => {
				setValue( ...changeArgs );
				onChange?.( ...changeArgs );
			} }
			value={ value }
		/>
	);
};
Deselectable story ok
When the `isDeselectable` prop is true, the option can be deselected by clicking on it again.
const Deselectable = ( {
	onChange,
	...props
} ) => {
	const [ value, setValue ] =
		useState< ToggleGroupControlProps[ 'value' ] >();

	return (
		<ToggleGroupControl
			__next40pxDefaultSize
			{ ...props }
			onChange={ ( ...changeArgs ) => {
				setValue( ...changeArgs );
				onChange?.( ...changeArgs );
			} }
			value={ value }
		/>
	);
};

Tooltip

components-tooltip · ../packages/components/src/tooltip/stories/index.story.tsx
Info
No description found. Write a jsdoc comment such as /** Component description */.
Prop types 8 prop types
Component: ../packages/components/src/tooltip/index.tsx::Tooltip
Props:
/**
 * The anchor for the tooltip.
 * 
 * **Note**: Accepts only one child element.
 */
children: React.ReactElement

/**
 * Custom class name for the tooltip.
 */
className?: string

/**
 * The amount of time in milliseconds to wait before showing the tooltip.
 * 
 * @default 700
 */
delay?: number

/**
 * Option to hide the tooltip when the anchor is clicked.
 * 
 * @default true
 */
hideOnClick?: boolean

/**
 * Where the tooltip should be positioned relative to its parent.
 * 
 * @default top
 */
placement?: Placement

/**
 * _Note: this prop is deprecated. Please use the `placement` prop instead._
 * 
 * Legacy way of specifying the tooltip's position relative to its parent.
 * 
 * Specify y- and x-axis as a space-separated string. Supports `"top"`,
 * `"bottom"` y axis, and `"left"`, `"center"`, `"right"` x axis.
 * 
 * @deprecated
 * @default top
 */
position?: PopoverProps[ 'position' ]

/**
 * An option for adding accessible keyboard shortcuts.
 * 
 * If shortcut is a string, it is expecting the display text. If shortcut is an
 * object, it will accept the properties of `display` (string) and `ariaLabel`
 * (string).
 */
shortcut?: ShortcutProps[ 'shortcut' ]

/**
 * The text shown in the tooltip when anchor element is focused or hovered.
 */
text?: string
Imports
import { Button, Tooltip } from "@wordpress/components";
Default story ok
const Default = ( props ) => (
	<Tooltip { ...props } />
);
Keyboard Shortcut story ok
const KeyboardShortcut = ( props ) => (
	<Tooltip { ...props } />
);
Nested story ok
In case one or more `Tooltip` components are rendered inside another `Tooltip` component, only the tooltip associated to the outermost `Tooltip` component will be rendered in the browser and shown to the user appropriately. The rest of the nested `Tooltip` components will simply no-op and pass-through their anchor.
const Nested = ( props ) => (
	<Tooltip { ...props } />
);

TreeGrid

components-treegrid · ../packages/components/src/tree-grid/stories/index.story.tsx
`TreeGrid` is used to create a tree hierarchy. It is not a visually styled component, but instead helps with adding keyboard navigation and roving tab index behaviors to tree grid structures. A tree grid is a hierarchical 2 dimensional UI component, for example it could be used to implement a file system browser. A tree grid allows the user to navigate using arrow keys. Up/down to navigate vertically across rows, and left/right to navigate horizontally between focusables in a row. The `TreeGrid` renders both a `table` and `tbody` element, and is intended to be used with `TreeGridRow` (`tr`) and `TreeGridCell` (`td`) to build out a grid. ```jsx function TreeMenu() { return ( <TreeGrid> <TreeGridRow level={ 1 } positionInSet={ 1 } setSize={ 2 }> <TreeGridCell> { ( props ) => ( <Button onClick={ onSelect } { ...props }>Select</Button> ) } </TreeGridCell> <TreeGridCell> { ( props ) => ( <Button onClick={ onMove } { ...props }>Move</Button> ) } </TreeGridCell> </TreeGridRow> <TreeGridRow level={ 1 } positionInSet={ 2 } setSize={ 2 }> <TreeGridCell> { ( props ) => ( <Button onClick={ onSelect } { ...props }>Select</Button> ) } </TreeGridCell> <TreeGridCell> { ( props ) => ( <Button onClick={ onMove } { ...props }>Move</Button> ) } </TreeGridCell> </TreeGridRow> <TreeGridRow level={ 2 } positionInSet={ 1 } setSize={ 1 }> <TreeGridCell> { ( props ) => ( <Button onClick={ onSelect } { ...props }>Select</Button> ) } </TreeGridCell> <TreeGridCell> { ( props ) => ( <Button onClick={ onMove } { ...props }>Move</Button> ) } </TreeGridCell> </TreeGridRow> </TreeGrid> ); } ```
see: {@link https://www.w3.org/TR/wai-aria-practices/examples/treegrid/treegrid-1.html}
Prop types 3 prop types
Component: ../packages/components/src/tree-grid/index.tsx::TreeGrid
Props:
onCollapseRow?: any = () => {}

onExpandRow?: any = () => {}

onFocusRow?: any = () => {}
Imports
import { Button, InputControl, TreeGrid, TreeGridCell, TreeGridRow } from "@wordpress/components";
import { Fragment } from "@wordpress/element";
Default story ok
const Default = () => <TreeGrid onExpandRow={fn()} onCollapseRow={fn()} onFocusRow={fn()}><Rows items={ groceries } /></TreeGrid>;

TreeSelect

components-treeselect · ../packages/components/src/tree-select/stories/index.story.tsx
Generates a hierarchical select input. ```jsx import { useState } from 'react'; import { TreeSelect } from '@wordpress/components'; const MyTreeSelect = () => { const [ page, setPage ] = useState( 'p21' ); return ( <TreeSelect __next40pxDefaultSize label="Parent page" noOptionLabel="No parent page" onChange={ ( newPage ) => setPage( newPage ) } selectedId={ page } tree={ [ { name: 'Page 1', id: 'p1', children: [ { name: 'Descend 1 of page 1', id: 'p11' }, { name: 'Descend 2 of page 1', id: 'p12' }, ], }, { name: 'Page 2', id: 'p2', children: [ { name: 'Descend 1 of page 2', id: 'p21', children: [ { name: 'Descend 1 of Descend 1 of page 2', id: 'p211', }, ], }, ], }, ] } /> ); } ```
Prop types 4 prop types
Component: ../packages/components/src/tree-select/index.tsx::TreeSelect
Props:
/**
 * If this property is added, an option will be added with this label to represent empty selection.
 */
noOptionLabel?: string

/**
 * A function that receives the value of the new option that is being selected as input.
 */
onChange?: SelectControlSingleSelectionProps[ 'onChange' ]

/**
 * The id of the currently selected node.
 */
selectedId?: SelectControlSingleSelectionProps[ 'value' ]

/**
 * An array containing the tree objects with the possible nodes the user can select.
 */
tree?: Tree[]
Imports
import { TreeSelect } from "@wordpress/components";
Default story ok
const Default = ( props ) => {
	const [ selection, setSelection ] =
		useState< ComponentProps< typeof TreeSelect >[ 'selectedId' ] >();

	return (
		<TreeSelect
			__next40pxDefaultSize
			{ ...props }
			onChange={ setSelection }
			selectedId={ selection }
		/>
	);
};

Truncate

components-truncate · ../packages/components/src/truncate/stories/index.story.tsx
Info
No description found. Write a jsdoc comment such as /** Component description */.
Imports
import { Truncate } from "@wordpress/components";
Default story ok
const Default = () => {
    return <Truncate numberOfLines={2}>{defaultText}</Truncate>;
};
Truncate by character count story ok
const CharacterCount = () => {
    return <Truncate limit={23} ellipsizeMode="tail" ellipsis="[---]">{defaultText}</Truncate>;
};

UnitControl

components-unitcontrol · ../packages/components/src/unit-control/stories/index.story.tsx
`UnitControl` allows the user to set a numeric quantity as well as a unit (e.g. `px`). ```jsx import { __experimentalUnitControl as UnitControl } from '@wordpress/components'; import { useState } from '@wordpress/element'; const Example = () => { const [ value, setValue ] = useState( '10px' ); return <UnitControl __next40pxDefaultSize onChange={ setValue } value={ value } />; }; ```
Imports
import { UnitControl } from "@wordpress/components";
Default story ok
const Default = () => {
    const [ value, setValue ] = useState< string | undefined >( '10px' );

    return (
        <UnitControl
            __next40pxDefaultSize
            onUnitChange={fn()}
            onFocus={fn()}
            onBlur={fn()}
            label="Label"
            value={ value }
            onChange={ ( v, extra ) => {
				setValue( v );
				onChange?.( v, extra );
			} } />
    );
};
Press Enter To Change story ok
If the `isPressEnterToChange` prop is set to `true`, the `onChange` callback will not fire while a new value is typed in the input field (you can verify this behavior by inspecting the console's output).
const PressEnterToChange = () => {
    const [ value, setValue ] = useState< string | undefined >( '10px' );

    return (
        <UnitControl
            __next40pxDefaultSize
            onUnitChange={fn()}
            onFocus={fn()}
            onBlur={fn()}
            isPressEnterToChange
            value={ value }
            onChange={ ( v, extra ) => {
				setValue( v );
				onChange?.( v, extra );
			} } />
    );
};
Tweaking The Number Input story ok
Most of `NumberControl`'s props can be passed to `UnitControl`, and they will affect its numeric input field.
const TweakingTheNumberInput = () => {
    const [ value, setValue ] = useState< string | undefined >( '10px' );

    return (
        <UnitControl
            __next40pxDefaultSize
            onUnitChange={fn()}
            onFocus={fn()}
            onBlur={fn()}
            min={0}
            max={100}
            step="any"
            label="Custom label"
            value={ value }
            onChange={ ( v, extra ) => {
				setValue( v );
				onChange?.( v, extra );
			} } />
    );
};
With Single Unit story ok
When only one unit is available, the unit selection dropdown becomes static text.
const WithSingleUnit = () => {
    const [ value, setValue ] = useState< string | undefined >( '10px' );

    return (
        <UnitControl
            __next40pxDefaultSize
            onUnitChange={fn()}
            onFocus={fn()}
            onBlur={fn()}
            units={CSS_UNITS.slice( 0, 1 )}
            value={ value }
            onChange={ ( v, extra ) => {
				setValue( v );
				onChange?.( v, extra );
			} } />
    );
};
With Custom Units story ok
It is possible to pass a custom list of units. Every time the unit changes, if the `isResetValueOnUnitChange` is set to `true`, the input's quantity is reset to the new unit's default value.
const WithCustomUnits = () => {
    const [ value, setValue ] = useState< string | undefined >( '80km' );

    return (
        <UnitControl
            __next40pxDefaultSize
            onUnitChange={fn()}
            onFocus={fn()}
            onBlur={fn()}
            isResetValueOnUnitChange
            min={0}
            units={[
                {
                    value: 'km',
                    label: 'km',
                    default: 1,
                },
                {
                    value: 'mi',
                    label: 'mi',
                    default: 1,
                },
                {
                    value: 'm',
                    label: 'm',
                    default: 1000,
                },
                {
                    value: 'yd',
                    label: 'yd',
                    default: 1760,
                },
            ]}
            value={ value }
            onChange={ ( v, extra ) => {
				setValue( v );
				onChange?.( v, extra );
			} } />
    );
};

VisuallyHidden

design-system-components-visuallyhidden · ../packages/ui/src/visually-hidden/stories/index.story.tsx
Visually hides content while keeping it accessible to screen readers. Useful when providing context that's only meaningful to assistive technology. Renders a `<div>` by default. Use the `render` prop to swap the underlying element while preserving the visually-hidden behavior. ## Composing with other components When composing with another component that uses the `render` prop pattern, keep `VisuallyHidden` as the **host** (outer component) and pass the other component via `render`. This keeps the other component's HTML element and semantics intact, while `VisuallyHidden` only adds its hiding styles: ```jsx // OtherComponent keeps its semantic element (e.g. <h2>). <VisuallyHidden render={ <OtherComponent /> }> Accessible text </VisuallyHidden> ```
Prop types 4 prop types
Component: ../packages/ui/src/visually-hidden/visually-hidden.tsx::VisuallyHidden
Props:
/**
 * The content to be rendered inside the component.
 */
children?: React.ReactNode

/**
 * CSS class name to apply to the element.
 */
className?: string

/**
 * Replaces the component's default HTML element using a given React
 * element, or a function that returns a React element.
 */
render?: | ComponentRenderFn< HTMLAttributesWithRef >
| React.ReactElement< Record< string, unknown > >

/**
 * CSS style to apply to the element.
 */
style?: React.CSSProperties
Imports
import { VisuallyHidden } from "@wordpress/ui";
Default story ok
const Default = () => (
    <>
        <VisuallyHidden>This should not show.</VisuallyHidden>
        <div>
            This text will <VisuallyHidden>but not inline </VisuallyHidden>
            always show.
        </div>
    </>
);
With Custom Element story ok
Use the `render` prop to change the underlying HTML element. By default, `VisuallyHidden` renders a `<div>`. Here it renders a `<label>` instead, keeping the native label–input association while hiding the label text visually.
const WithCustomElement = function WithCustomElementStory() {
    const inputId = useId();
    return (
        <>
            { /* eslint-disable-next-line jsx-a11y/label-has-associated-control */ }
            <VisuallyHidden render={ <label htmlFor={ inputId } /> }>
                Accessible label
            </VisuallyHidden>
            <input
                id={ inputId }
                placeholder="This input has a visually hidden label"
            />
        </>
    );
};

ScrollLock

components-scrolllock · ../packages/components/src/scroll-lock/stories/index.story.tsx
Prop type error
File: /home/runner/work/gutenberg/gutenberg/packages/components/src/scroll-lock/index.tsx
Error:
No suitable component definition found.
You can debug your component file in this playground: https://react-docgen.dev/playground
Code:
/**
 * WordPress dependencies
 */
import { useEffect } from '@wordpress/element';

/*
 * Setting `overflow: hidden` on html and body elements resets body scroll in iOS.
 * Save scroll top so we can restore it after locking scroll.
 *
 * NOTE: It would be cleaner and possibly safer to find a localized solution such
 * as preventing default on certain touchmove events.
 */
let previousScrollTop = 0;

function setLocked( locked: boolean ) {
	const scrollingElement = document.scrollingElement || document.body;

	if ( locked ) {
		previousScrollTop = scrollingElement.scrollTop;
	}

	const methodName = locked ? 'add' : 'remove';
	scrollingElement.classList[ methodName ]( 'lockscroll' );

	// Adding the class to the document element seems to be necessary in iOS.
	document.documentElement.classList[ methodName ]( 'lockscroll' );

	if ( ! locked ) {
		scrollingElement.scrollTop = previousScrollTop;
	}
}

let lockCounter = 0;

/**
 * ScrollLock is a content-free React component for declaratively preventing
 * scroll bleed from modal UI to the page body. This component applies a
 * `lockscroll` class to the `document.documentElement` and
 * `document.scrollingElement` elements to stop the body from scrolling. When it
 * is present, the lock is applied.
 *
 * ```jsx
 * import { ScrollLock, Button } from '@wordpress/components';
 * import { useState } from '@wordpress/element';
 *
 * const MyScrollLock = () => {
 *   const [ isScrollLocked, setIsScrollLocked ] = useState( false );
 *
 *   const toggleLock = () => {
 *     setIsScrollLocked( ( locked ) => ! locked ) );
 *   };
 *
 *   return (
 *     <div>
 *       <Button variant="secondary" onClick={ toggleLock }>
 *         Toggle scroll lock
 *       </Button>
 *       { isScrollLocked && <ScrollLock /> }
 *       <p>
 *         Scroll locked:
 *         <strong>{ isScrollLocked ? 'Yes' : 'No' }</strong>
 *       </p>
 *     </div>
 *   );
 * };
 * ```
 */
export function ScrollLock(): null {
	useEffect( () => {
		if ( lockCounter === 0 ) {
			setLocked( true );
		}

		++lockCounter;

		return () => {
			if ( lockCounter === 1 ) {
				setLocked( false );
			}

			--lockCounter;
		};
	}, [] );

	return null;
}

export default ScrollLock;
Info
No description found. Write a jsdoc comment such as /** Component description */.
Imports
import { Button, ScrollLock } from "@wordpress/components";
Default story ok
const Default = () => {
	const [ isScrollLocked, setScrollLocked ] = useState( false );
	const toggleLock = () => setScrollLocked( ! isScrollLocked );

	return (
		<div style={ { height: 1000 } }>
			<div
				style={ {
					overflow: 'auto',
					height: 240,
					border: '1px solid lightgray',
				} }
			>
				<StripedBackground>
					<div>
						Start scrolling down. Once you scroll to the end of this
						container with the stripes, the rest of the page will
						continue scrolling. <code>ScrollLock</code> prevents
						this &quot;scroll bleed&quot; from happening.
					</div>
					<ToggleContainer>
						<Button
							__next40pxDefaultSize
							variant="primary"
							onClick={ toggleLock }
						>
							Toggle Scroll Lock
						</Button>
						{ isScrollLocked && <ScrollLock /> }
						<p>
							Scroll locked:{ ' ' }
							<strong>{ isScrollLocked ? 'Yes' : 'No' }</strong>
						</p>
					</ToggleContainer>
				</StripedBackground>
			</div>
		</div>
	);
};