W↓
All docs
🔑
Sign Up/Sign In
base-ui.com/react/
Public Link
Jun 18, 2025, 8:27:02 AM - complete - 299.1 kB
Created by:
****ad@vlad.studio
Starting URLs:
https://base-ui.com/react/overview/quick-start
CSS Selector:
main
Crawl Prefixes:
https://base-ui.com/react/
Exclude Patterns:
https://base-ui.com/react/overview/accessibility
https://base-ui.com/react/overview/releases
https://base-ui.com/react/utils/direction-provider
## Page: https://base-ui.com/react/overview/quick-start Quick start * (Top) * Install the library * Set up portals * Assemble a component * Next steps # Quick start A quick guide to getting started with Base UI. ## Install the library Install Base UI using a package manager. Terminal Copy npm i @base-ui-components/react All components are included in a single package. Base UI is tree-shakeable, so your app bundle will contain only the components that you actually use. ## Set up portals Base UI uses portals for components that render popups, such as Dialog and Popover. To make portalled components always appear on top of the entire page, add the following style to your application layout root: layout.tsx Copy <body> <div className="root"> {children} </div> </body> styles.css Copy .root { isolation: isolate; } This style creates a separate stacking context for your application’s `.root` element. This way, popups will always appear above the page contents, and any `z-index` property in your styles won’t interfere with them. ## Assemble a component This demo shows you how to import a Popover component, assemble its parts, and apply styles. There are examples for both Tailwind and CSS Modules below, but since Base UI is unstyled, you can use CSS-in-JS, plain CSS, or any other styling solution you prefer. index.tsxindex.module.csstheme.css CSS Modules CodeSandboxCopy import * as React from 'react'; import { Popover } from '@base-ui-components/react/popover'; import styles from './index.module.css'; export default function ExamplePopover() { return ( <Popover.Root> <Popover.Trigger className={styles.IconButton}> <BellIcon aria-label="Notifications" className={styles.Icon} /> </Popover.Trigger> <Popover.Portal> <Popover.Positioner sideOffset={8}> <Popover.Popup className={styles.Popup}> <Popover.Arrow className={styles.Arrow}> <ArrowSvg /> </Popover.Arrow> <Popover.Title className={styles.Title}>Notifications</Popover.Title> <Popover.Description className={styles.Description}> You are all caught up. Good job! </Popover.Description> </Popover.Popup> </Popover.Positioner> </Popover.Portal> </Popover.Root> ); } function ArrowSvg(props: React.ComponentProps<'svg'>) { return ( <svg width="20" height="10" viewBox="0 0 20 10" fill="none" {...props}> <path d="M9.66437 2.60207L4.80758 6.97318C4.07308 7.63423 3.11989 8 2.13172 8H0V10H20V8H18.5349C17.5468 8 16.5936 7.63423 15.8591 6.97318L11.0023 2.60207C10.622 2.2598 10.0447 2.25979 9.66437 2.60207Z" className={styles.ArrowFill} /> <path d="M8.99542 1.85876C9.75604 1.17425 10.9106 1.17422 11.6713 1.85878L16.5281 6.22989C17.0789 6.72568 17.7938 7.00001 18.5349 7.00001L15.89 7L11.0023 2.60207C10.622 2.2598 10.0447 2.2598 9.66436 2.60207L4.77734 7L2.13171 7.00001C2.87284 7.00001 3.58774 6.72568 4.13861 6.22989L8.99542 1.85876Z" className={styles.ArrowOuterStroke} /> <path d="M10.3333 3.34539L5.47654 7.71648C4.55842 8.54279 3.36693 9 2.13172 9H0V8H2.13172C3.11989 8 4.07308 7.63423 4.80758 6.97318L9.66437 2.60207C10.0447 2.25979 10.622 2.2598 11.0023 2.60207L15.8591 6.97318C16.5936 7.63423 17.5468 8 18.5349 8H20V9H18.5349C17.2998 9 16.1083 8.54278 15.1901 7.71648L10.3333 3.34539Z" className={styles.ArrowInnerStroke} /> </svg> ); } function BellIcon(props: React.ComponentProps<'svg'>) { return ( <svg fill="currentcolor" width="20" height="20" viewBox="0 0 16 16" {...props}> <path d="M 8 1 C 7.453125 1 7 1.453125 7 2 L 7 3.140625 C 5.28125 3.589844 4 5.144531 4 7 L 4 10.984375 C 4 10.984375 3.984375 11.261719 3.851563 11.519531 C 3.71875 11.78125 3.558594 12 3 12 L 3 13 L 13 13 L 13 12 C 12.40625 12 12.253906 11.78125 12.128906 11.53125 C 12.003906 11.277344 12 11.003906 12 11.003906 L 12 7 C 12 5.144531 10.71875 3.589844 9 3.140625 L 9 2 C 9 1.453125 8.546875 1 8 1 Z M 8 13 C 7.449219 13 7 13.449219 7 14 C 7 14.550781 7.449219 15 8 15 C 8.550781 15 9 14.550781 9 14 C 9 13.449219 8.550781 13 8 13 Z M 8 4 C 9.664063 4 11 5.335938 11 7 L 11 10.996094 C 11 10.996094 10.988281 11.472656 11.234375 11.96875 C 11.238281 11.980469 11.246094 11.988281 11.25 12 L 4.726563 12 C 4.730469 11.992188 4.738281 11.984375 4.742188 11.980469 C 4.992188 11.488281 5 11.015625 5 11.015625 L 5 7 C 5 5.335938 6.335938 4 8 4 Z" /> </svg> ); } Show code ## Next steps This walkthrough outlines the basics of putting together a Base UI component. Browse the rest of the documentation to see what components are available in the library and how to use them. --- ## Page: https://base-ui.com/react/overview/about About Base UI * (Top) * Features * Headless * Accessible * Composable * Team * Community * GitHub * Discord * X * Bluesky # About Base UI An open-source React component library for building accessible user interfaces. From the creators of Radix, Material UI, and Floating UI, Base UI is an unstyled React component library for building accessible user interfaces. Our focus is on accessibility, performance, and developer experience. Our goal is to provide a complete set of open-source UI components, with a delightful developer experience, in a sustainable way. ## Features ### Headless Base UI components are unstyled, don’t bundle CSS, and don’t prescribe a styling solution. You retain complete control over your application’s CSS layer. Base UI is compatible with Tailwind, CSS Modules, plain CSS, CSS-in-JS, or any other styling engine you prefer. ### Accessible Poor accessibility can make your application difficult to navigate for all users, not just for users with disabilities. Accessibility is our primary focus. Base UI components adhere to WAI-ARIA design patterns and are tested on a wide range of platforms, devices, browsers, screen readers, and other environments. ### Composable Component APIs are fully open, so you have direct access to each node, you can easily add or remove parts, and you can wrap them however you prefer. ## Team * **Colm Tuite** (Radix) @colmtuite * **Vlad Moroz** (Radix) @vladyslavmoroz * **James Nelson** (Floating UI) @atomiksdev * **Michał Dudak** (Material UI) @michaldudak * **Marija Najdova** (Material UI + Fluent UI) @marijanajdova * **Albert Yu** (Material UI) @mj12albert ## Community ### GitHub Base UI is an open-source project. If you want to file a bug report or contribute, visit our GitHub. ### Discord For community support, questions, and tips, join our Discord. ### X The best way to stay up-to-date on new releases and announcements is by following Base UI on X. ### Bluesky We’re also on Bluesky. --- ## Page: https://base-ui.com/react/handbook/styling Styling * (Top) * Style hooks * CSS classes * Data attributes * CSS variables * Tailwind CSS * CSS Modules * CSS-in-JS # Styling A guide to styling Base UI components with your preferred styling engine. Base UI components are unstyled, don’t bundle CSS, and are compatible with Tailwind, CSS Modules, CSS-in-JS, or any other styling solution you prefer. You retain total control of your styling layer. ## Style hooks ### CSS classes Components that render an HTML element accept a `className` prop to style the element with CSS classes. switch.tsx Copy <Switch.Thumb className="SwitchThumb" /> The prop can also be passed a function that takes the component’s state as an argument. switch.tsx Copy <Switch.Thumb className={(state) => (state.checked ? 'checked' : 'unchecked')} /> ### Data attributes Components provide data attributes designed for styling their states. For example, Switch can be styled using its `[data-checked]` and `[data-unchecked]` attributes, among others. switch.css Copy .SwitchThumb[data-checked] { background-color: green; } ### CSS variables Components expose CSS variables to aid in styling, often containing dynamic numeric values to be used in sizing or transform calculations. For example, Popover exposes CSS variables on its `Popup` component like `--available-height` and `--anchor-width`. popover.css Copy .Popup { max-height: var(--available-height); } Check out each component’s API reference for a complete list of available data attributes and CSS variables. ## Tailwind CSS Apply Tailwind classes to each part via the `className` prop. menu.tsx Copy import * as React from 'react'; import { Menu } from '@base-ui-components/react/menu'; export default function ExampleMenu() { return ( <Menu.Root> <Menu.Trigger className="flex h-10 items-center justify-center gap-1.5 rounded-md border border-gray-200 bg-gray-50 px-3.5 text-base font-medium text-gray-900 select-none hover:bg-gray-100 focus-visible:outline focus-visible:outline-2 focus-visible:-outline-offset-1 focus-visible:outline-blue-800 active:bg-gray-100 data-[popup-open]:bg-gray-100"> Song </Menu.Trigger> <Menu.Portal> <Menu.Positioner className="outline-none" sideOffset={8}> <Menu.Popup className="origin-[var(--transform-origin)] rounded-md bg-[canvas] py-1 text-gray-900 shadow-lg shadow-gray-200 outline outline-1 outline-gray-200 transition-[transform,scale,opacity] data-[ending-style]:scale-90 data-[ending-style]:opacity-0 data-[starting-style]:scale-90 data-[starting-style]:opacity-0 dark:shadow-none dark:-outline-offset-1 dark:outline-gray-300"> <Menu.Item className="flex cursor-default py-2 pr-8 pl-4 text-sm leading-4 outline-none select-none data-[highlighted]:relative data-[highlighted]:z-0 data-[highlighted]:text-gray-50 data-[highlighted]:before:absolute data-[highlighted]:before:inset-x-1 data-[highlighted]:before:inset-y-0 data-[highlighted]:before:z-[-1] data-[highlighted]:before:rounded-sm data-[highlighted]:before:bg-gray-900"> Add to Library </Menu.Item> <Menu.Item className="flex cursor-default py-2 pr-8 pl-4 text-sm leading-4 outline-none select-none data-[highlighted]:relative data-[highlighted]:z-0 data-[highlighted]:text-gray-50 data-[highlighted]:before:absolute data-[highlighted]:before:inset-x-1 data-[highlighted]:before:inset-y-0 data-[highlighted]:before:z-[-1] data-[highlighted]:before:rounded-sm data-[highlighted]:before:bg-gray-900"> Add to Playlist </Menu.Item> </Menu.Popup> </Menu.Positioner> </Menu.Portal> </Menu.Root> ); } ## CSS Modules Apply custom CSS classes to each part via the `className` prop. Then style those classes in a CSS Modules file. menu.tsx Copy import * as React from 'react'; import { Menu } from '@base-ui-components/react/menu'; import styles from './menu.module.css'; export default function ExampleMenu() { return ( <Menu.Root> <Menu.Trigger className={styles.Button}>Song</Menu.Trigger> <Menu.Portal> <Menu.Positioner className={styles.Positioner} sideOffset={8}> <Menu.Popup className={styles.Popup}> <Menu.Item className={styles.Item}>Add to Library</Menu.Item> <Menu.Item className={styles.Item}>Add to Playlist</Menu.Item> </Menu.Popup> </Menu.Positioner> </Menu.Portal> </Menu.Root> ); } ## CSS-in-JS Wrap each component part and apply styles, then assemble your styled components. menu.tsx Copy import * as React from 'react'; import { Menu } from '@base-ui-components/react/menu'; import styled from '@emotion/styled'; const StyledMenuTrigger = styled(Menu.Trigger)` // Button styles `; const StyledMenuPositioner = styled(Menu.Positioner)` // Positioner styles `; const StyledMenuPopup = styled(Menu.Popup)` // Popup styles `; const StyledMenuItem = styled(Menu.Item)` // Menu item styles `; const MenuExample = () => ( <Menu.Root> <StyledMenuTrigger>Song</StyledMenuTrigger> <Menu.Portal> <StyledMenuPositioner> <StyledMenuPopup> <StyledMenuItem>Add to Library</StyledMenuItem> <StyledMenuItem>Add to Playlist</StyledMenuItem> </Menu.Portal> </StyledMenuPositioner> </StyledMenuPopup> </Menu.Root> ); export default MenuExample; --- ## Page: https://base-ui.com/react/handbook/animation Animation * (Top) * CSS transitions * CSS animations * JavaScript animations * Elements removed from the DOM when closed * Elements kept in the DOM when closed * Manual unmounting # Animation A guide to animating Base UI components. Base UI components can be animated using CSS transitions, CSS animations, or JavaScript animation libraries. Each component provides a number of data attributes to target its states, as well as a few attributes specifically for animation. ## CSS transitions Use the following Base UI attributes for creating transitions when a component becomes visible or hidden: * `[data-starting-style]` corresponds to the initial style to transition from. * `[data-ending-style]` corresponds to the final style to transition to. Transitions are recommended over CSS animations, because a transition can be smoothly cancelled midway. For example, if the user closes a popup before it finishes opening, with CSS transitions it will smoothly animate to its closed state without any abrupt changes. popover.css Copy .Popup { box-sizing: border-box; padding: 1rem 1.5rem; background-color: canvas; transform-origin: var(--transform-origin); transition: transform 150ms, opacity 150ms; &[data-starting-style], &[data-ending-style] { opacity: 0; transform: scale(0.9); } } ## CSS animations Use the following Base UI attributes for creating CSS animations when a component becomes visible or hidden: * `[data-open]` corresponds to the style applied when a component becomes visible. * `[data-closed]` corresponds to the style applied before a component becomes hidden. popover.css Copy @keyframes scaleIn { from { opacity: 0; transform: scale(0.9); } to { opacity: 1; transform: scale(1); } } @keyframes scaleOut { from { opacity: 1; transform: scale(1); } to { opacity: 0; transform: scale(0.9); } } .Popup[data-open] { animation: scaleIn 250ms ease-out; } .Popup[data-closed] { animation: scaleOut 250ms ease-in; } ## JavaScript animations JavaScript animation libraries such as Motion require control of the mounting and unmounting lifecycle of components in order for exit animations to play. Base UI relies on `element.getAnimations()` to detect if animations have finished on an element. When using Motion, the `opacity` property lets this detection work easily, so always animating `opacity` to a new value for exit animations will work. If it shouldn’t be animated, you can use a value close to `1`, such as `opacity: 0.9999`. ### Elements removed from the DOM when closed Most components like Popover are unmounted from the DOM when they are closed. To animate them: * Make the component controlled with the `open` prop so `AnimatePresence` can see the state as a child * Specify `keepMounted` on the `Portal` part * Use the `render` prop to compose the `Popup` with `motion.div` animated-popover.tsx Copy function App() { const [open, setOpen] = React.useState(false); return ( <Popover.Root open={open} onOpenChange={setOpen}> <Popover.Trigger>Trigger</Popover.Trigger> <AnimatePresence> {open && ( <Popover.Portal keepMounted> <Popover.Positioner> <Popover.Popup render={ <motion.div initial={{ opacity: 0, scale: 0.8 }} animate={{ opacity: 1, scale: 1 }} exit={{ opacity: 0, scale: 0.8 }} /> } > Popup </Popover.Popup> </Popover.Positioner> </Popover.Portal> )} </AnimatePresence> </Popover.Root> ); } ### Elements kept in the DOM when closed The `Select` component must be kept mounted in the DOM even when closed. In this case, a different approach is needed to animate it with Motion. * Make the component controlled with the `open` prop * Use the `render` prop to compose the `Popup` with `motion.div` * Animate the properties based on the `open` state, avoiding `AnimatePresence` animated-select.tsx Copy function App() { const [open, setOpen] = React.useState(false); return ( <Select.Root open={open} onOpenChange={setOpen}> <Select.Trigger> <Select.Value placeholder="Value" /> </Select.Trigger> <Select.Portal> <Select.Positioner> <Select.Popup render={ <motion.div initial={false} animate={{ opacity: open ? 1 : 0, scale: open ? 1 : 0.8, }} /> } > Popup </Select.Popup> </Select.Positioner> </Select.Portal> </Select.Root> ); } ### Manual unmounting For full control, you can manually unmount the component when it’s closed once animations have finished using an `actionsRef` passed to the `Root`: manual-unmount.tsx Copy function App() { const [open, setOpen] = React.useState(false); const actionsRef = React.useRef({ unmount: () => {} }); return ( <Popover.Root open={open} onOpenChange={setOpen} actionsRef={actionsRef}> <Popover.Trigger>Trigger</Popover.Trigger> <AnimatePresence> {open && ( <Popover.Portal keepMounted> <Popover.Positioner> <Popover.Popup render={ <motion.div initial={{ scale: 0 }} animate={{ scale: 1 }} exit={{ scale: 0 }} onAnimationComplete={() => { if (!open) { actionsRef.current.unmount(); } }} /> } > Popup </Popover.Popup> </Popover.Positioner> </Popover.Portal> )} </AnimatePresence> </Popover.Root> ); } --- ## Page: https://base-ui.com/react/handbook/composition Composition * (Top) * Composing custom React components * Composing multiple components * Changing the default rendered element * Render function # Composition A guide to composing Base UI components with your own React components. ## Composing custom React components Use the `render` prop to compose a Base UI part with your own React components. For example, most triggers render a `<button>` by default. The code snippet below shows how to use a custom button instead. index.tsx Copy <Menu.Trigger render={<MyButton size="md" />}> Open menu </Menu.Trigger> The custom component must forward the `ref`, and spread all the received props on its underlying DOM node. ## Composing multiple components In situations where you need to compose multiple Base UI components with custom React components, `render` props can be nested as deeply as necessary. Working with Tooltip is a common example. index.tsx Copy <Dialog.Root> <Tooltip.Root> <Tooltip.Trigger render={ <Dialog.Trigger render={ <Menu.Trigger render={<MyButton size="md" />}> Open menu </Menu.Trigger> } /> } /> <Tooltip.Portal>...</Tooltip.Portal> </Tooltip.Root> <Dialog.Portal>...</Dialog.Portal> </Dialog.Root> ## Changing the default rendered element You can also use the `render` prop to override the rendered element of the component. For example, `Menu.Item` renders a `<div>` by default. The code snippet below shows how to render it as an `<a>` element so that it works like a link. index.tsx Copy import * as React from 'react'; import { Menu } from '@base-ui-components/react/menu'; export default () => ( <Menu.Root> <Menu.Trigger>Song</Menu.Trigger> <Menu.Portal> <Menu.Positioner> <Menu.Popup> <Menu.Item render={<a href="base-ui.com" />}> Add to Library </Menu.Item> </Menu.Popup> </Menu.Positioner> </Menu.Portal> </Menu.Root> ); Each Base UI component renders the most appropriate element by default, and in most cases, rendering a different element is recommended only on a case-by-case basis. ## Render function If you are working in an extremely performance-sensitive application, you might want to pass a function to the `render` prop instead of a React element. switch.tsx Copy <Switch.Thumb render={(props, state) => <span {...props}> {state.checked ? <CheckedIcon /> : <UncheckedIcon />} </span> } /> Using a function gives you complete control over spreading props and also allows you to render different content based on the component’s state. --- ## Page: https://base-ui.com/react/components/accordion Accordion * (Top) * Anatomy * API reference * Root * Item * Header * Trigger * Panel # Accordion A set of collapsible panels with headings. ### What is Base UI? ### How do I get started? ### Can I use it for my project? index.tsxindex.module.csstheme.css CSS Modules CodeSandboxCopy import * as React from 'react'; import { Accordion } from '@base-ui-components/react/accordion'; import styles from './index.module.css'; export default function ExampleAccordion() { return ( <Accordion.Root className={styles.Accordion}> <Accordion.Item className={styles.Item}> <Accordion.Header className={styles.Header}> <Accordion.Trigger className={styles.Trigger}> What is Base UI? <PlusIcon className={styles.TriggerIcon} /> </Accordion.Trigger> </Accordion.Header> <Accordion.Panel className={styles.Panel}> <div className={styles.Content}> Base UI is a library of high-quality unstyled React components for design systems and web apps. </div> </Accordion.Panel> </Accordion.Item> <Accordion.Item className={styles.Item}> <Accordion.Header className={styles.Header}> <Accordion.Trigger className={styles.Trigger}> How do I get started? <PlusIcon className={styles.TriggerIcon} /> </Accordion.Trigger> </Accordion.Header> <Accordion.Panel className={styles.Panel}> <div className={styles.Content}> Head to the “Quick start” guide in the docs. If you’ve used unstyled libraries before, you’ll feel at home. </div> </Accordion.Panel> </Accordion.Item> <Accordion.Item className={styles.Item}> <Accordion.Header className={styles.Header}> <Accordion.Trigger className={styles.Trigger}> Can I use it for my project? <PlusIcon className={styles.TriggerIcon} /> </Accordion.Trigger> </Accordion.Header> <Accordion.Panel className={styles.Panel}> <div className={styles.Content}> Of course! Base UI is free and open source. </div> </Accordion.Panel> </Accordion.Item> </Accordion.Root> ); } function PlusIcon(props: React.ComponentProps<'svg'>) { return ( <svg viewBox="0 0 12 12" fill="currentcolor" {...props}> <path d="M6.75 0H5.25V5.25H0V6.75L5.25 6.75V12H6.75V6.75L12 6.75V5.25H6.75V0Z" /> </svg> ); } Show code ## Anatomy Import the component and assemble its parts: Anatomy Copy import { Accordion } from '@base-ui-components/react/accordion'; <Accordion.Root> <Accordion.Item> <Accordion.Header> <Accordion.Trigger /> </Accordion.Header> <Accordion.Panel /> </Accordion.Item> </Accordion.Root> ## API reference ### Root Groups all parts of the accordion. Renders a `<div>` element. | Prop | Type | Default | | | --- | --- | --- | --- | | `defaultValue` | `any[]` | `undefined` | | | `value` | `any[]` | `undefined` | | | `onValueChange` | `((value: any[]) => void)` | `undefined` | | | `hiddenUntilFound` | `boolean` | `false` | | | `openMultiple` | `boolean` | `true` | | | `disabled` | `boolean` | `false` | | | `loop` | `boolean` | `true` | | | `orientation` | `Orientation` | `'vertical'` | | | `className` | `| string | ((state: Accordion.Root.State) => string)` | `undefined` | | | `keepMounted` | `boolean` | `false` | | | `render` | `| ReactElement | ((props: HTMLProps, state: Accordion.Root.State) => ReactElement)` | `undefined` | | | Attribute | Description | | | --- | --- | --- | | `data-orientation` | Indicates the orientation of the accordion. | | `data-disabled` | Present when the accordion is disabled. | ### Item Groups an accordion header with the corresponding panel. Renders a `<div>` element. | Prop | Type | Default | | | --- | --- | --- | --- | | `value` | `any` | `undefined` | | | `onOpenChange` | `((open: boolean) => void)` | `undefined` | | | `disabled` | `boolean` | `false` | | | `className` | `| string | ((state: Accordion.Item.State) => string)` | `undefined` | | | `render` | `| ReactElement | ((props: HTMLProps, state: Accordion.Item.State) => ReactElement)` | `undefined` | | | Attribute | Description | | | --- | --- | --- | | `data-open` | Present when the accordion item is open. | | `data-disabled` | Present when the accordion item is disabled. | | `data-index` | Indicates the index of the accordion item. | ### Header A heading that labels the corresponding panel. Renders an `<h3>` element. | Prop | Type | Default | | | --- | --- | --- | --- | | `className` | `| string | ((state: Accordion.Item.State) => string)` | `undefined` | | | `render` | `| ReactElement | ((props: HTMLProps, state: Accordion.Item.State) => ReactElement)` | `undefined` | | | Attribute | Description | | | --- | --- | --- | | `data-open` | Present when the accordion item is open. | | `data-disabled` | Present when the accordion item is disabled. | | `data-index` | Indicates the index of the accordion item. | ### Trigger A button that opens and closes the corresponding panel. Renders a `<button>` element. | Prop | Type | Default | | | --- | --- | --- | --- | | `className` | `| string | ((state: Accordion.Item.State) => string)` | `undefined` | | | `render` | `| ReactElement | ((props: HTMLProps, state: Accordion.Item.State) => ReactElement)` | `undefined` | | | Attribute | Description | | | --- | --- | --- | | `data-panel-open` | Present when the accordion panel is open. | | `data-disabled` | Present when the accordion item is disabled. | ### Panel A collapsible panel with the accordion item contents. Renders a `<div>` element. | Prop | Type | Default | | | --- | --- | --- | --- | | `hiddenUntilFound` | `boolean` | `false` | | | `className` | `| string | ((state: Accordion.Item.State) => string)` | `undefined` | | | `keepMounted` | `boolean` | `false` | | | `render` | `| ReactElement | ((props: HTMLProps, state: Accordion.Item.State) => ReactElement)` | `undefined` | | | Attribute | Description | | | --- | --- | --- | | `data-open` | Present when the accordion panel is open. | | `data-orientation` | Indicates the orientation of the accordion. | | `data-disabled` | Present when the accordion item is disabled. | | `data-index` | Indicates the index of the accordion item. | | `data-starting-style` | Present when the panel is animating in. | | `data-ending-style` | Present when the panel is animating out. | | CSS Variable | Description | | | --- | --- | --- | | `--accordion-panel-height` | The accordion panel's height. | | `--accordion-panel-width` | The accordion panel's width. | --- ## Page: https://base-ui.com/react/components/alert-dialog Alert Dialog * (Top) * Anatomy * API reference * Root * Trigger * Portal * Backdrop * Popup * Title * Description * Close * Examples * Open from a menu * Close confirmation # Alert Dialog A dialog that requires user response to proceed. Discard draft index.tsxindex.module.csstheme.css CSS Modules CodeSandboxCopy import * as React from 'react'; import { AlertDialog } from '@base-ui-components/react/alert-dialog'; import styles from './index.module.css'; export default function ExampleAlertDialog() { return ( <AlertDialog.Root> <AlertDialog.Trigger data-color="red" className={styles.Button}> Discard draft </AlertDialog.Trigger> <AlertDialog.Portal> <AlertDialog.Backdrop className={styles.Backdrop} /> <AlertDialog.Popup className={styles.Popup}> <AlertDialog.Title className={styles.Title}> Discard draft? </AlertDialog.Title> <AlertDialog.Description className={styles.Description}> You can't undo this action. </AlertDialog.Description> <div className={styles.Actions}> <AlertDialog.Close className={styles.Button}>Cancel</AlertDialog.Close> <AlertDialog.Close data-color="red" className={styles.Button}> Discard </AlertDialog.Close> </div> </AlertDialog.Popup> </AlertDialog.Portal> </AlertDialog.Root> ); } Show code ## Anatomy Import the component and assemble its parts: Anatomy Copy import { AlertDialog } from '@base-ui-components/react/alert-dialog'; <AlertDialog.Root> <AlertDialog.Trigger /> <AlertDialog.Portal> <AlertDialog.Backdrop /> <AlertDialog.Popup> <AlertDialog.Title /> <AlertDialog.Description /> <AlertDialog.Close /> </AlertDialog.Popup> </AlertDialog.Portal> </AlertDialog.Root> ## API reference ### Root Groups all parts of the alert dialog. Doesn’t render its own HTML element. | Prop | Type | Default | | | --- | --- | --- | --- | | `defaultOpen` | `boolean` | `false` | | | `open` | `boolean` | `undefined` | | | `onOpenChange` | `(open: boolean, event?: Event, reason?: AlertDialog.Root.OpenChangeReason) => void` | `undefined` | | | `actionsRef` | `RefObject<{ unmount: () => void; }>` | `undefined` | | | `onOpenChangeComplete` | `((open: boolean) => void)` | `undefined` | | | `children` | `ReactNode` | `undefined` | | ### Trigger A button that opens the alert dialog. Renders a `<button>` element. | Prop | Type | Default | | | --- | --- | --- | --- | | `className` | `| string | ((state: AlertDialog.Trigger.State) => string)` | `undefined` | | | `render` | `| ReactElement | ((props: HTMLProps, state: AlertDialog.Trigger.State) => ReactElement)` | `undefined` | | | Attribute | Description | | | --- | --- | --- | | `data-popup-open` | Present when the corresponding dialog is open. | | `data-disabled` | Present when the trigger is disabled. | ### Portal A portal element that moves the popup to a different part of the DOM. By default, the portal element is appended to `<body>`. | Prop | Type | Default | | | --- | --- | --- | --- | | `container` | `| HTMLElement | RefObject<HTMLElement | null> | null` | `undefined` | | | `children` | `ReactNode` | `undefined` | | | `keepMounted` | `boolean` | `false` | | ### Backdrop An overlay displayed beneath the popup. Renders a `<div>` element. | Prop | Type | Default | | | --- | --- | --- | --- | | `className` | `| string | ((state: AlertDialog.Backdrop.State) => string)` | `undefined` | | | `render` | `| ReactElement | ((props: HTMLProps, state: AlertDialog.Backdrop.State) => ReactElement)` | `undefined` | | | Attribute | Description | | | --- | --- | --- | | `data-open` | Present when the dialog is open. | | `data-closed` | Present when the dialog is closed. | | `data-starting-style` | Present when the dialog is animating in. | | `data-ending-style` | Present when the dialog is animating out. | ### Popup A container for the alert dialog contents. Renders a `<div>` element. | Prop | Type | Default | | | --- | --- | --- | --- | | `initialFocus` | `| RefObject<HTMLElement | null> | ((interactionType: InteractionType) => RefObject<HTMLElement | null>)` | `undefined` | | | `finalFocus` | `RefObject<HTMLElement | null>` | `undefined` | | | `className` | `| string | ((state: AlertDialog.Popup.State) => string)` | `undefined` | | | `render` | `| ReactElement | ((props: HTMLProps, state: AlertDialog.Popup.State) => ReactElement)` | `undefined` | | | Attribute | Description | | | --- | --- | --- | | `data-open` | Present when the dialog is open. | | `data-closed` | Present when the dialog is closed. | | `data-nested` | Present when the dialog is nested within another dialog. | | `data-nested-dialog-open` | Present when the dialog has other open dialogs nested within it. | | `data-starting-style` | Present when the dialog is animating in. | | `data-ending-style` | Present when the dialog is animating out. | ### Title A heading that labels the dialog. Renders an `<h2>` element. | Prop | Type | Default | | | --- | --- | --- | --- | | `className` | `| string | ((state: AlertDialog.Title.State) => string)` | `undefined` | | | `render` | `| ReactElement | ((props: HTMLProps, state: AlertDialog.Title.State) => ReactElement)` | `undefined` | | ### Description A paragraph with additional information about the alert dialog. Renders a `<p>` element. | Prop | Type | Default | | | --- | --- | --- | --- | | `className` | `| string | ((state: AlertDialog.Description.State) => string)` | `undefined` | | | `render` | `| ReactElement | ((props: HTMLProps, state: AlertDialog.Description.State) => ReactElement)` | `undefined` | | ### Close A button that closes the alert dialog. Renders a `<button>` element. | Prop | Type | Default | | | --- | --- | --- | --- | | `className` | `| string | ((state: AlertDialog.Close.State) => string)` | `undefined` | | | `render` | `| ReactElement | ((props: HTMLProps, state: AlertDialog.Close.State) => ReactElement)` | `undefined` | | | Attribute | Description | | | --- | --- | --- | | `data-disabled` | Present when the button is disabled. | ## Examples ### Open from a menu In order to open a dialog using a menu, control the dialog state and open it imperatively using the `onClick` handler on the menu item. Make sure to also use the dialog’s `finalFocus` prop to return focus back to the menu trigger. Connecting a dialog to a menu Copy import * as React from 'react'; import { AlertDialog } from '@base-ui/components/alert-dialog'; import { Menu } from '@base-ui/components/menu'; function ExampleMenu() { const menuTriggerRef = React.useRef<HTMLButtonElement>(null); const [dialogOpen, setDialogOpen] = React.useState(false); return ( <React.Fragment> <Menu.Root> {/* Set the trigger ref */} <Menu.Trigger ref={menuTriggerRef}>Open menu</Menu.Trigger> <Menu.Portal> <Menu.Positioner> <Menu.Popup> {/* Open the dialog when the menu item is clicked */} <Menu.Item onClick={() => setDialogOpen(true)}>Open dialog</Menu.Item> </Menu.Popup> </Menu.Positioner> </Menu.Portal> </Menu.Root> {/* Control the dialog state */} <AlertDialog.Root open={dialogOpen} onOpenChange={setDialogOpen}> <AlertDialog.Portal> <AlertDialog.Backdrop /> {/* Return focus to the menu trigger when the dialog is closed */} <AlertDialog.Popup finalFocus={menuTriggerRef}> {/* Rest of the dialog */} </AlertDialog.Popup> </AlertDialog.Portal> </AlertDialog.Root> </React.Fragment> ); } ### Close confirmation This example shows a nested confirmation dialog that opens if the text entered in the parent dialog is going to be discarded. To implement this, both dialogs should be controlled. The confirmation dialog may be opened when `onOpenChange` callback of the parent dialog receives a request to close. This way, the confirmation is automatically shown when the user clicks the backdrop, presses the Esc key, or clicks a close button. Use the `[data-nested-dialog-open]` selector and the `var(--nested-dialogs)` CSS variable to customize the styling of the parent dialog. Backdrops of the child dialogs won’t be rendered so that you can present the parent dialog in a clean way behind the one on top of it. Tweet Show code --- ## Page: https://base-ui.com/react/components/avatar Avatar * (Top) * Anatomy * API reference * Root * Image * Fallback # Avatar An easily stylable avatar component. LT index.tsxindex.module.csstheme.css CSS Modules CodeSandboxCopy import * as React from 'react'; import { Avatar } from '@base-ui-components/react/avatar'; import styles from './index.module.css'; export default function ExampleAvatar() { return ( <div style={{ display: 'flex', gap: 20 }}> <Avatar.Root className={styles.Root}> <Avatar.Image src="https://images.unsplash.com/photo-1543610892-0b1f7e6d8ac1?w=128&h=128&dpr=2&q=80" width="48" height="48" className={styles.Image} /> <Avatar.Fallback className={styles.Fallback}>LT</Avatar.Fallback> </Avatar.Root> <Avatar.Root className={styles.Root}>LT</Avatar.Root> </div> ); } Show code ## Anatomy Import the component and assemble its parts: Anatomy Copy import { Avatar } from '@base-ui-components/react/avatar'; <Avatar.Root> <Avatar.Image src="" /> <Avatar.Fallback>LT</Avatar.Fallback> </Avatar.Root> ## API reference ### Root Displays a user's profile picture, initials, or fallback icon. Renders a `<span>` element. | Prop | Type | Default | | | --- | --- | --- | --- | | `className` | `| string | ((state: Avatar.Root.State) => string)` | `undefined` | | | `render` | `| ReactElement | ((props: HTMLProps, state: Avatar.Root.State) => ReactElement)` | `undefined` | | ### Image The image to be displayed in the avatar. Renders an `<img>` element. | Prop | Type | Default | | | --- | --- | --- | --- | | `onLoadingStatusChange` | `((status: ImageLoadingStatus) => void)` | `undefined` | | | `className` | `| string | ((state: Avatar.Root.State) => string)` | `undefined` | | | `render` | `| ReactElement | ((props: HTMLProps, state: Avatar.Root.State) => ReactElement)` | `undefined` | | ### Fallback Rendered when the image fails to load or when no image is provided. Renders a `<span>` element. | Prop | Type | Default | | | --- | --- | --- | --- | | `delay` | `number` | `undefined` | | | `className` | `| string | ((state: Avatar.Root.State) => string)` | `undefined` | | | `render` | `| ReactElement | ((props: HTMLProps, state: Avatar.Root.State) => ReactElement)` | `undefined` | | --- ## Page: https://base-ui.com/react/components/checkbox Checkbox * (Top) * Anatomy * API reference * Root * Indicator # Checkbox An easily stylable checkbox component. Enable notifications index.tsxindex.module.csstheme.css CSS Modules CodeSandboxCopy import * as React from 'react'; import { Checkbox } from '@base-ui-components/react/checkbox'; import styles from './index.module.css'; export default function ExampleCheckbox() { return ( <label className={styles.Label}> <Checkbox.Root defaultChecked className={styles.Checkbox}> <Checkbox.Indicator className={styles.Indicator}> <CheckIcon className={styles.Icon} /> </Checkbox.Indicator> </Checkbox.Root> Enable notifications </label> ); } function CheckIcon(props: React.ComponentProps<'svg'>) { return ( <svg fill="currentcolor" width="10" height="10" viewBox="0 0 10 10" {...props}> <path d="M9.1603 1.12218C9.50684 1.34873 9.60427 1.81354 9.37792 2.16038L5.13603 8.66012C5.01614 8.8438 4.82192 8.96576 4.60451 8.99384C4.3871 9.02194 4.1683 8.95335 4.00574 8.80615L1.24664 6.30769C0.939709 6.02975 0.916013 5.55541 1.19372 5.24822C1.47142 4.94102 1.94536 4.91731 2.2523 5.19524L4.36085 7.10461L8.12299 1.33999C8.34934 0.993152 8.81376 0.895638 9.1603 1.12218Z" /> </svg> ); } Show code ## Anatomy Import the component and assemble its parts: Anatomy Copy import { Checkbox } from '@base-ui-components/react/checkbox'; <Checkbox.Root> <Checkbox.Indicator /> </Checkbox.Root> ## API reference ### Root Represents the checkbox itself. Renders a `<button>` element and a hidden `<input>` beside. | Prop | Type | Default | | | --- | --- | --- | --- | | `name` | `string` | `undefined` | | | `defaultChecked` | `boolean` | `false` | | | `checked` | `boolean` | `undefined` | | | `onCheckedChange` | `((checked: boolean, event: Event) => void)` | `undefined` | | | `indeterminate` | `boolean` | `false` | | | `value` | `string` | `undefined` | | | `parent` | `boolean` | `false` | | | `disabled` | `boolean` | `false` | | | `readOnly` | `boolean` | `false` | | | `required` | `boolean` | `false` | | | `inputRef` | `Ref<HTMLInputElement>` | `undefined` | | | `id` | `string` | `undefined` | | | `className` | `| string | ((state: Checkbox.Root.State) => string)` | `undefined` | | | `render` | `| ReactElement | ((props: HTMLProps, state: Checkbox.Root.State) => ReactElement)` | `undefined` | | | Attribute | Description | | | --- | --- | --- | | `data-checked` | Present when the checkbox is checked. | | `data-unchecked` | Present when the checkbox is not checked. | | `data-disabled` | Present when the checkbox is disabled. | | `data-readonly` | Present when the checkbox is readonly. | | `data-required` | Present when the checkbox is required. | | `data-valid` | Present when the checkbox is in valid state (when wrapped in Field.Root). | | `data-invalid` | Present when the checkbox is in invalid state (when wrapped in Field.Root). | | `data-dirty` | Present when the checkbox's value has changed (when wrapped in Field.Root). | | `data-touched` | Present when the checkbox has been touched (when wrapped in Field.Root). | | `data-filled` | Present when the checkbox is checked (when wrapped in Field.Root). | | `data-focused` | Present when the checkbox is focused (when wrapped in Field.Root). | ### Indicator Indicates whether the checkbox is ticked. Renders a `<span>` element. | Prop | Type | Default | | | --- | --- | --- | --- | | `className` | `| string | ((state: Checkbox.Indicator.State) => string)` | `undefined` | | | `keepMounted` | `boolean` | `false` | | | `render` | `| ReactElement | ((props: HTMLProps, state: Checkbox.Indicator.State) => ReactElement)` | `undefined` | | | Attribute | Description | | | --- | --- | --- | | `data-checked` | Present when the checkbox is checked. | | `data-unchecked` | Present when the checkbox is not checked. | | `data-disabled` | Present when the checkbox is disabled. | | `data-readonly` | Present when the checkbox is readonly. | | `data-required` | Present when the checkbox is required. | | `data-valid` | Present when the checkbox is in valid state (when wrapped in Field.Root). | | `data-invalid` | Present when the checkbox is in invalid state (when wrapped in Field.Root). | | `data-dirty` | Present when the checkbox's value has changed (when wrapped in Field.Root). | | `data-touched` | Present when the checkbox has been touched (when wrapped in Field.Root). | | `data-filled` | Present when the checkbox is checked (when wrapped in Field.Root). | | `data-focused` | Present when the checkbox is focused (when wrapped in Field.Root). | | `data-starting-style` | Present when the checkbox indicator is animating in. | | `data-ending-style` | Present when the checkbox indicator is animating out. | --- ## Page: https://base-ui.com/react/components/checkbox-group Checkbox Group * (Top) * Anatomy * API reference * Examples * Parent checkbox * Nested parent checkbox * Form integration # Checkbox Group Provides shared state to a series of checkboxes. Apples FujiGalaGranny Smith index.tsxindex.module.csstheme.css CSS Modules CodeSandboxCopy import * as React from 'react'; import { Checkbox } from '@base-ui-components/react/checkbox'; import { CheckboxGroup } from '@base-ui-components/react/checkbox-group'; import styles from './index.module.css'; export default function ExampleCheckboxGroup() { return ( <CheckboxGroup aria-labelledby="apples-caption" defaultValue={['fuji-apple']} className={styles.CheckboxGroup} > <div className={styles.Caption} id="apples-caption"> Apples </div> <label className={styles.Item}> <Checkbox.Root name="apple" value="fuji-apple" className={styles.Checkbox}> <Checkbox.Indicator className={styles.Indicator}> <CheckIcon className={styles.Icon} /> </Checkbox.Indicator> </Checkbox.Root> Fuji </label> <label className={styles.Item}> <Checkbox.Root name="apple" value="gala-apple" className={styles.Checkbox}> <Checkbox.Indicator className={styles.Indicator}> <CheckIcon className={styles.Icon} /> </Checkbox.Indicator> </Checkbox.Root> Gala </label> <label className={styles.Item}> <Checkbox.Root name="apple" value="granny-smith-apple" className={styles.Checkbox} > <Checkbox.Indicator className={styles.Indicator}> <CheckIcon className={styles.Icon} /> </Checkbox.Indicator> </Checkbox.Root> Granny Smith </label> </CheckboxGroup> ); } function CheckIcon(props: React.ComponentProps<'svg'>) { return ( <svg fill="currentcolor" width="10" height="10" viewBox="0 0 10 10" {...props}> <path d="M9.1603 1.12218C9.50684 1.34873 9.60427 1.81354 9.37792 2.16038L5.13603 8.66012C5.01614 8.8438 4.82192 8.96576 4.60451 8.99384C4.3871 9.02194 4.1683 8.95335 4.00574 8.80615L1.24664 6.30769C0.939709 6.02975 0.916013 5.55541 1.19372 5.24822C1.47142 4.94102 1.94536 4.91731 2.2523 5.19524L4.36085 7.10461L8.12299 1.33999C8.34934 0.993152 8.81376 0.895638 9.1603 1.12218Z" /> </svg> ); } Show code ## Anatomy Checkbox Group is composed together with Checkbox. Import the components and place them together: Anatomy Copy import { Checkbox } from '@base-ui-components/react/checkbox'; import { CheckboxGroup } from '@base-ui-components/react/checkbox-group'; <CheckboxGroup> <Checkbox.Root /> </CheckboxGroup> ## API reference | Prop | Type | Default | | | --- | --- | --- | --- | | `defaultValue` | `string[]` | `undefined` | | | `value` | `string[]` | `undefined` | | | `onValueChange` | `((value: string[], event: Event) => void)` | `undefined` | | | `allValues` | `string[]` | `undefined` | | | `disabled` | `boolean` | `false` | | | `className` | `| string | ((state: Checkbox.Group.State) => string)` | `undefined` | | | `render` | `| ReactElement | ((props: HTMLProps, state: Checkbox.Group.State) => ReactElement)` | `undefined` | | | Attribute | Description | | | --- | --- | --- | | `data-disabled` | Present when the checkbox group is disabled. | ## Examples ### Parent checkbox A checkbox that controls other checkboxes within a `CheckboxGroup` can be created: 1. Make `CheckboxGroup` a controlled component 2. Pass an array of all the child checkbox `value`s to the `CheckboxGroup`’s `allValues` prop 3. Add the `parent` boolean prop to the parent `Checkbox` ApplesFujiGalaGranny Smith index.tsxindex.module.csstheme.css CodeSandboxCopy import * as React from 'react'; import { Checkbox } from '@base-ui-components/react/checkbox'; import { CheckboxGroup } from '@base-ui-components/react/checkbox-group'; import styles from './index.module.css'; const fruits = ['fuji-apple', 'gala-apple', 'granny-smith-apple']; export default function ExampleCheckboxGroup() { const [value, setValue] = React.useState<string[]>([]); return ( <CheckboxGroup aria-labelledby="apples-caption" value={value} onValueChange={setValue} allValues={fruits} className={styles.CheckboxGroup} style={{ marginLeft: '1rem' }} > <label className={styles.Item} id="apples-caption" style={{ marginLeft: '-1rem' }} > <Checkbox.Root className={styles.Checkbox} name="apples" parent> <Checkbox.Indicator className={styles.Indicator} render={(props, state) => ( <span {...props}> {state.indeterminate ? ( <HorizontalRuleIcon className={styles.Icon} /> ) : ( <CheckIcon className={styles.Icon} /> )} </span> )} /> </Checkbox.Root> Apples </label> <label className={styles.Item}> <Checkbox.Root value="fuji-apple" className={styles.Checkbox}> <Checkbox.Indicator className={styles.Indicator}> <CheckIcon className={styles.Icon} /> </Checkbox.Indicator> </Checkbox.Root> Fuji </label> <label className={styles.Item}> <Checkbox.Root value="gala-apple" className={styles.Checkbox}> <Checkbox.Indicator className={styles.Indicator}> <CheckIcon className={styles.Icon} /> </Checkbox.Indicator> </Checkbox.Root> Gala </label> <label className={styles.Item}> <Checkbox.Root value="granny-smith-apple" className={styles.Checkbox}> <Checkbox.Indicator className={styles.Indicator}> <CheckIcon className={styles.Icon} /> </Checkbox.Indicator> </Checkbox.Root> Granny Smith </label> </CheckboxGroup> ); } function CheckIcon(props: React.ComponentProps<'svg'>) { return ( <svg fill="currentcolor" width="10" height="10" viewBox="0 0 10 10" {...props}> <path d="M9.1603 1.12218C9.50684 1.34873 9.60427 1.81354 9.37792 2.16038L5.13603 8.66012C5.01614 8.8438 4.82192 8.96576 4.60451 8.99384C4.3871 9.02194 4.1683 8.95335 4.00574 8.80615L1.24664 6.30769C0.939709 6.02975 0.916013 5.55541 1.19372 5.24822C1.47142 4.94102 1.94536 4.91731 2.2523 5.19524L4.36085 7.10461L8.12299 1.33999C8.34934 0.993152 8.81376 0.895638 9.1603 1.12218Z" /> </svg> ); } function HorizontalRuleIcon(props: React.ComponentProps<'svg'>) { return ( <svg width="10" height="10" viewBox="0 0 24 24" fill="currentcolor" xmlns="http://www.w3.org/2000/svg" {...props} > <line x1="3" y1="12" x2="21" y2="12" stroke="currentColor" strokeWidth={3} strokeLinecap="round" /> </svg> ); } Show code ### Nested parent checkbox User PermissionsView DashboardAccess Reports Manage UsersCreate UserEdit UserDelete UserAssign Roles Show code ### Form integration To use checkbox group in a form, pass the checkbox group’s `name` to a `Field`, then use the `render` prop to render the field as a `Fieldset` in order to label the group. Using CheckboxGroup in a form Copy <Form> <Field.Root name="toppings" render={<Fieldset.Root />}> <Fieldset.Legend>Toppings</Fieldset.Legend> <CheckboxGroup> <Checkbox.Root value="anchovies" /> <Checkbox.Root value="olives" /> <CheckboxGroup> </Field.Root> </Form> Extra toppings AnchoviesOlivesJalapeños Add Show code --- ## Page: https://base-ui.com/react/components/collapsible Collapsible * (Top) * Anatomy * API reference * Root * Trigger * Panel # Collapsible A collapsible panel controlled by a button. Recovery keys index.tsxindex.module.csstheme.css CSS Modules CodeSandboxCopy import * as React from 'react'; import { Collapsible } from '@base-ui-components/react/collapsible'; import styles from './index.module.css'; export default function ExampleCollapsible() { return ( <Collapsible.Root className={styles.Collapsible}> <Collapsible.Trigger className={styles.Trigger}> <ChevronIcon className={styles.Icon} /> Recovery keys </Collapsible.Trigger> <Collapsible.Panel className={styles.Panel}> <div className={styles.Content}> <div>alien-bean-pasta</div> <div>wild-irish-burrito</div> <div>horse-battery-staple</div> </div> </Collapsible.Panel> </Collapsible.Root> ); } export function ChevronIcon(props: React.ComponentProps<'svg'>) { return ( <svg width="10" height="10" viewBox="0 0 10 10" fill="none" {...props}> <path d="M3.5 9L7.5 5L3.5 1" stroke="currentcolor" /> </svg> ); } Show code ## Anatomy Import the component and assemble its parts: Anatomy Copy import { Collapsible } from '@base-ui-components/react/collapsible'; <Collapsible.Root> <Collapsible.Trigger /> <Collapsible.Panel /> </Collapsible.Root> ## API reference ### Root Groups all parts of the collapsible. Renders a `<div>` element. | Prop | Type | Default | | | --- | --- | --- | --- | | `defaultOpen` | `boolean` | `false` | | | `open` | `boolean` | `undefined` | | | `onOpenChange` | `((open: boolean) => void)` | `undefined` | | | `disabled` | `boolean` | `false` | | | `className` | `| string | ((state: Collapsible.Root.State) => string)` | `undefined` | | | `render` | `| ReactElement | ((props: HTMLProps, state: Collapsible.Root.State) => ReactElement) | null` | `undefined` | | ### Trigger A button that opens and closes the collapsible panel. Renders a `<button>` element. | Prop | Type | Default | | | --- | --- | --- | --- | | `className` | `| string | ((state: Collapsible.Root.State) => string)` | `undefined` | | | `render` | `| ReactElement | ((props: HTMLProps, state: Collapsible.Root.State) => ReactElement)` | `undefined` | | | Attribute | Description | | | --- | --- | --- | | `data-panel-open` | Present when the collapsible panel is open. | ### Panel A panel with the collapsible contents. Renders a `<div>` element. | Prop | Type | Default | | | --- | --- | --- | --- | | `hiddenUntilFound` | `boolean` | `false` | | | `className` | `| string | ((state: Collapsible.Root.State) => string)` | `undefined` | | | `keepMounted` | `boolean` | `false` | | | `render` | `| ReactElement | ((props: HTMLProps, state: Collapsible.Root.State) => ReactElement)` | `undefined` | | | Attribute | Description | | | --- | --- | --- | | `data-open` | Present when the collapsible panel is open. | | `data-closed` | Present when the collapsible panel is closed. | | `data-starting-style` | Present when the panel is animating in. | | `data-ending-style` | Present when the panel is animating out. | | CSS Variable | Description | | | --- | --- | --- | | `--collapsible-panel-height` | The collapsible panel's height. | | `--collapsible-panel-width` | The collapsible panel's width. | --- ## Page: https://base-ui.com/react/components/context-menu Context Menu * (Top) * Anatomy * API reference * Root * Trigger * Portal * Positioner * Popup * Arrow * Item * Group * GroupLabel * RadioGroup * RadioItem * RadioItemIndicator * CheckboxItem * CheckboxItemIndicator * Separator * Examples * Nested menu # Context Menu A menu that appears at the pointer on right click or long press. Right click here index.tsxindex.module.csstheme.css CSS Modules CodeSandboxCopy import * as React from 'react'; import { ContextMenu } from '@base-ui-components/react/context-menu'; import styles from './index.module.css'; export default function ExampleMenu() { return ( <ContextMenu.Root> <ContextMenu.Trigger className={styles.Trigger}> Right click here </ContextMenu.Trigger> <ContextMenu.Portal> <ContextMenu.Positioner className={styles.Positioner}> <ContextMenu.Popup className={styles.Popup}> <ContextMenu.Item className={styles.Item}> Add to Library </ContextMenu.Item> <ContextMenu.Item className={styles.Item}> Add to Playlist </ContextMenu.Item> <ContextMenu.Separator className={styles.Separator} /> <ContextMenu.Item className={styles.Item}>Play Next</ContextMenu.Item> <ContextMenu.Item className={styles.Item}>Play Last</ContextMenu.Item> <ContextMenu.Separator className={styles.Separator} /> <ContextMenu.Item className={styles.Item}>Favorite</ContextMenu.Item> <ContextMenu.Item className={styles.Item}>Share</ContextMenu.Item> </ContextMenu.Popup> </ContextMenu.Positioner> </ContextMenu.Portal> </ContextMenu.Root> ); } Show code ## Anatomy Import the components and place them together: Anatomy Copy import { ContextMenu } from '@base-ui-components/react/context-menu'; <ContextMenu.Root> <ContextMenu.Trigger /> <ContextMenu.Portal> <ContextMenu.Backdrop /> <ContextMenu.Positioner> <ContextMenu.Popup> <ContextMenu.Arrow /> <ContextMenu.Item /> <ContextMenu.Separator /> <ContextMenu.Group> <ContextMenu.GroupLabel /> </ContextMenu.Group> <ContextMenu.RadioGroup> <ContextMenu.RadioItem /> </ContextMenu.RadioGroup> <ContextMenu.CheckboxItem /> </ContextMenu.Popup> </ContextMenu.Positioner> </ContextMenu.Portal> </ContextMenu.Root> ## API reference ### Root A component that creates a context menu activated by right clicking or long pressing. Doesn’t render its own HTML element. | Prop | Type | Default | | | --- | --- | --- | --- | | `defaultOpen` | `boolean` | `false` | | | `open` | `boolean` | `undefined` | | | `onOpenChange` | `(open: boolean, event?: Event, reason?: Menu.Root.OpenChangeReason) => void` | `undefined` | | | `actionsRef` | `RefObject<Actions>` | `undefined` | | | `closeParentOnEsc` | `boolean` | `true` | | | `onOpenChangeComplete` | `((open: boolean) => void)` | `undefined` | | | `disabled` | `boolean` | `false` | | | `loop` | `boolean` | `true` | | | `orientation` | `Menu.Root.Orientation` | `'vertical'` | | | `children*` | `ReactNode` | `—` | | ### Trigger An area that opens the menu on right click or long press. Renders a `<div>` element. | Prop | Type | Default | | | --- | --- | --- | --- | | `className` | `| string | ((state: ContextMenu.Trigger.State) => string)` | `undefined` | | | `render` | `| ReactElement | ((props: HTMLProps, state: ContextMenu.Trigger.State) => ReactElement)` | `undefined` | | ### Portal A portal element that moves the popup to a different part of the DOM. By default, the portal element is appended to `<body>`. | Prop | Type | Default | | | --- | --- | --- | --- | | `container` | `| HTMLElement | RefObject<HTMLElement | null> | null` | `undefined` | | | `children` | `ReactNode` | `undefined` | | | `keepMounted` | `boolean` | `false` | | ### Positioner Positions the menu popup against the trigger. Renders a `<div>` element. | Prop | Type | Default | | | --- | --- | --- | --- | | `collisionAvoidance` | `CollisionAvoidance` | `undefined` | | | `align` | `'center' | 'start' | 'end'` | `'center'` | | | `alignOffset` | `number | OffsetFunction` | `0` | | | `side` | `Side` | `'bottom'` | | | `sideOffset` | `number | OffsetFunction` | `0` | | | `arrowPadding` | `number` | `5` | | | `anchor` | `| Element | RefObject<Element | null> | VirtualElement | (() => Element | VirtualElement | null) | null` | `undefined` | | | `collisionBoundary` | `Boundary` | `'clipping-ancestors'` | | | `collisionPadding` | `Padding` | `5` | | | `sticky` | `boolean` | `false` | | | `positionMethod` | `'fixed' | 'absolute'` | `'absolute'` | | | `trackAnchor` | `boolean` | `true` | | | `className` | `| string | ((state: Menu.Positioner.State) => string)` | `undefined` | | | `render` | `| ReactElement | ((props: HTMLProps, state: Menu.Positioner.State) => ReactElement)` | `undefined` | | | Attribute | Description | | | --- | --- | --- | | `data-open` | Present when the menu popup is open. | | `data-closed` | Present when the menu popup is closed. | | `data-anchor-hidden` | Present when the anchor is hidden. | | `data-align` | Indicates how the popup is aligned relative to specified side. | | `data-side` | Indicates which side the popup is positioned relative to the trigger. | | CSS Variable | Description | | | --- | --- | --- | | `--anchor-height` | The anchor's height. | | `--anchor-width` | The anchor's width. | | `--available-height` | The available height between the trigger and the edge of the viewport. | | `--available-width` | The available width between the trigger and the edge of the viewport. | | `--transform-origin` | The coordinates that this element is anchored to. Used for animations and transitions. | ### Popup A container for the menu items. Renders a `<div>` element. | Prop | Type | Default | | | --- | --- | --- | --- | | `finalFocus` | `RefObject<HTMLElement | null>` | `undefined` | | | `id` | `string` | `undefined` | | | `children` | `ReactNode` | `undefined` | | | `className` | `| string | ((state: Menu.Popup.State) => string)` | `undefined` | | | `render` | `| ReactElement | ((props: HTMLProps, state: Menu.Popup.State) => ReactElement)` | `undefined` | | | Attribute | Description | | | --- | --- | --- | | `data-open` | Present when the menu is open. | | `data-closed` | Present when the menu is closed. | | `data-align` | Indicates how the popup is aligned relative to specified side. | | `data-instant` | Present if animations should be instant. | | `data-side` | Indicates which side the popup is positioned relative to the trigger. | | `data-starting-style` | Present when the menu is animating in. | | `data-ending-style` | Present when the menu is animating out. | ### Arrow Displays an element positioned against the menu anchor. Renders a `<div>` element. | Prop | Type | Default | | | --- | --- | --- | --- | | `className` | `| string | ((state: Menu.Arrow.State) => string)` | `undefined` | | | `render` | `| ReactElement | ((props: HTMLProps, state: Menu.Arrow.State) => ReactElement)` | `undefined` | | | Attribute | Description | | | --- | --- | --- | | `data-open` | Present when the menu popup is open. | | `data-closed` | Present when the menu popup is closed. | | `data-uncentered` | Present when the menu arrow is uncentered. | | `data-anchor-hidden` | Present when the anchor is hidden. | | `data-align` | Indicates how the popup is aligned relative to specified side. | | `data-side` | Indicates which side the popup is positioned relative to the trigger. | ### Item An individual interactive item in the menu. Renders a `<div>` element. | Prop | Type | Default | | | --- | --- | --- | --- | | `label` | `string` | `undefined` | | | `onClick` | `MouseEventHandler<HTMLElement>` | `undefined` | | | `closeOnClick` | `boolean` | `true` | | | `disabled` | `boolean` | `false` | | | `id` | `string` | `undefined` | | | `children` | `ReactNode` | `undefined` | | | `className` | `| string | ((state: Menu.Item.State) => string)` | `undefined` | | | `render` | `| ReactElement | ((props: HTMLProps, state: Menu.Item.State) => ReactElement)` | `undefined` | | | Attribute | Description | | | --- | --- | --- | | `data-highlighted` | Present when the menu item is highlighted. | | `data-disabled` | Present when the menu item is disabled. | ### Group Groups related menu items with the corresponding label. Renders a `<div>` element. | Prop | Type | Default | | | --- | --- | --- | --- | | `children` | `ReactNode` | `undefined` | | | `className` | `| string | ((state: Menu.Group.State) => string)` | `undefined` | | | `render` | `| ReactElement | ((props: HTMLProps, state: Menu.Group.State) => ReactElement)` | `undefined` | | ### GroupLabel An accessible label that is automatically associated with its parent group. Renders a `<div>` element. | Prop | Type | Default | | | --- | --- | --- | --- | | `className` | `| string | ((state: Menu.GroupLabel.State) => string)` | `undefined` | | | `render` | `| ReactElement | ((props: HTMLProps, state: Menu.GroupLabel.State) => ReactElement)` | `undefined` | | ### RadioGroup Groups related radio items. Renders a `<div>` element. | Prop | Type | Default | | | --- | --- | --- | --- | | `defaultValue` | `any` | `undefined` | | | `value` | `any` | `undefined` | | | `onValueChange` | `((value: any, event: Event) => void)` | `() => {}` | | | `disabled` | `boolean` | `false` | | | `children` | `ReactNode` | `undefined` | | | `className` | `| string | ((state: Menu.RadioGroup.State) => string)` | `undefined` | | | `render` | `| ReactElement | ((props: HTMLProps, state: Menu.RadioGroup.State) => ReactElement)` | `undefined` | | ### RadioItem A menu item that works like a radio button in a given group. Renders a `<div>` element. | Prop | Type | Default | | | --- | --- | --- | --- | | `label` | `string` | `undefined` | | | `value*` | `any` | `—` | | | `onClick` | `MouseEventHandler<HTMLElement>` | `undefined` | | | `closeOnClick` | `boolean` | `false` | | | `disabled` | `boolean` | `false` | | | `id` | `string` | `undefined` | | | `children` | `ReactNode` | `undefined` | | | `className` | `| string | ((state: Menu.RadioItem.State) => string)` | `undefined` | | | `render` | `| ReactElement | ((props: HTMLProps, state: Menu.RadioItem.State) => ReactElement)` | `undefined` | | | Attribute | Description | | | --- | --- | --- | | `data-checked` | Present when the menu radio item is selected. | | `data-unchecked` | Present when the menu radio item is not selected. | | `data-highlighted` | Present when the menu radio item is highlighted. | | `data-disabled` | Present when the menu radio item is disabled. | ### RadioItemIndicator Indicates whether the radio item is selected. Renders a `<div>` element. | Prop | Type | Default | | | --- | --- | --- | --- | | `className` | `| string | ((state: Menu.RadioItemIndicator.State) => string)` | `undefined` | | | `keepMounted` | `boolean` | `false` | | | `render` | `| ReactElement | ((props: HTMLProps, state: Menu.RadioItemIndicator.State) => ReactElement)` | `undefined` | | | Attribute | Description | | | --- | --- | --- | | `data-checked` | Present when the menu radio item is selected. | | `data-unchecked` | Present when the menu radio item is not selected. | | `data-disabled` | Present when the menu radio item is disabled. | | `data-starting-style` | Present when the radio indicator is animating in. | | `data-ending-style` | Present when the radio indicator is animating out. | ### CheckboxItem A menu item that toggles a setting on or off. Renders a `<div>` element. | Prop | Type | Default | | | --- | --- | --- | --- | | `label` | `string` | `undefined` | | | `defaultChecked` | `boolean` | `false` | | | `checked` | `boolean` | `undefined` | | | `onCheckedChange` | `((checked: boolean, event: Event) => void)` | `undefined` | | | `onClick` | `MouseEventHandler<HTMLElement>` | `undefined` | | | `closeOnClick` | `boolean` | `false` | | | `disabled` | `boolean` | `false` | | | `id` | `string` | `undefined` | | | `children` | `ReactNode` | `undefined` | | | `className` | `| string | ((state: Menu.CheckboxItem.State) => string)` | `undefined` | | | `render` | `| ReactElement | ((props: HTMLProps, state: Menu.CheckboxItem.State) => ReactElement)` | `undefined` | | | Attribute | Description | | | --- | --- | --- | | `data-checked` | Present when the menu checkbox item is checked. | | `data-unchecked` | Present when the menu checkbox item is not checked. | | `data-highlighted` | Present when the menu checkbox item is highlighted. | | `data-disabled` | Present when the menu checkbox item is disabled. | ### CheckboxItemIndicator Indicates whether the checkbox item is ticked. Renders a `<div>` element. | Prop | Type | Default | | | --- | --- | --- | --- | | `className` | `| string | ((state: Menu.CheckboxItemIndicator.State) => string)` | `undefined` | | | `keepMounted` | `boolean` | `false` | | | `render` | `| ReactElement | ((props: HTMLProps, state: Menu.CheckboxItemIndicator.State) => ReactElement)` | `undefined` | | | Attribute | Description | | | --- | --- | --- | | `data-checked` | Present when the menu checkbox item is checked. | | `data-unchecked` | Present when the menu checkbox item is not checked. | | `data-disabled` | Present when the menu checkbox item is disabled. | | `data-starting-style` | Present when the indicator is animating in. | | `data-ending-style` | Present when the indicator is animating out. | ### Separator A separator element accessible to screen readers. Renders a `<div>` element. | Prop | Type | Default | | | --- | --- | --- | --- | | `orientation` | `Orientation` | `'horizontal'` | | | `className` | `| string | ((state: Separator.State) => string)` | `undefined` | | | `render` | `| ReactElement | ((props: HTMLProps, state: Separator.State) => ReactElement)` | `undefined` | | ## Examples Menu displays additional demos, many of which apply to the context menu as well. ### Nested menu To create a submenu, nest Menu inside the parent context menu. Use the `<Menu.SubmenuTrigger>` part for the menu item that opens the nested menu. Right click here index.tsxindex.module.csstheme.css CSS Modules CodeSandboxCopy import * as React from 'react'; import { ContextMenu } from '@base-ui-components/react/context-menu'; import { Menu } from '@base-ui-components/react/menu'; import styles from './index.module.css'; export default function ExampleContextMenu() { return ( <ContextMenu.Root> <ContextMenu.Trigger className={styles.Trigger}> Right click here </ContextMenu.Trigger> <ContextMenu.Portal> <ContextMenu.Positioner className={styles.Positioner}> <ContextMenu.Popup className={styles.Popup}> <ContextMenu.Item className={styles.Item}> Add to Library </ContextMenu.Item> <Menu.Root> <Menu.SubmenuTrigger className={styles.SubmenuTrigger}> Add to Playlist <ChevronRightIcon /> </Menu.SubmenuTrigger> <Menu.Portal> <Menu.Positioner className={styles.Positioner} alignOffset={-4} sideOffset={-4} > <Menu.Popup className={styles.SubmenuPopup}> <Menu.Item className={styles.Item}>Get Up!</Menu.Item> <Menu.Item className={styles.Item}>Inside Out</Menu.Item> <Menu.Item className={styles.Item}>Night Beats</Menu.Item> <Menu.Separator className={styles.Separator} /> <Menu.Item className={styles.Item}>New playlist…</Menu.Item> </Menu.Popup> </Menu.Positioner> </Menu.Portal> </Menu.Root> <ContextMenu.Separator className={styles.Separator} /> <ContextMenu.Item className={styles.Item}>Play Next</ContextMenu.Item> <ContextMenu.Item className={styles.Item}>Play Last</ContextMenu.Item> <ContextMenu.Separator className={styles.Separator} /> <ContextMenu.Item className={styles.Item}>Favorite</ContextMenu.Item> <ContextMenu.Item className={styles.Item}>Share</ContextMenu.Item> </ContextMenu.Popup> </ContextMenu.Positioner> </ContextMenu.Portal> </ContextMenu.Root> ); } function ChevronRightIcon(props: React.ComponentProps<'svg'>) { return ( <svg width="10" height="10" viewBox="0 0 10 10" fill="none" {...props}> <path d="M3.5 9L7.5 5L3.5 1" stroke="currentcolor" strokeWidth="1.5" /> </svg> ); } Show code --- ## Page: https://base-ui.com/react/components/dialog Dialog * (Top) * Anatomy * API reference * Root * Trigger * Portal * Backdrop * Popup * Title * Description * Close * Examples * State * Open from a menu * Nested dialogs * Close confirmation # Dialog A popup that opens on top of the entire page. View notifications index.tsxindex.module.csstheme.css CSS Modules CodeSandboxCopy import * as React from 'react'; import { Dialog } from '@base-ui-components/react/dialog'; import styles from './index.module.css'; export default function ExampleDialog() { return ( <Dialog.Root> <Dialog.Trigger className={styles.Button}>View notifications</Dialog.Trigger> <Dialog.Portal> <Dialog.Backdrop className={styles.Backdrop} /> <Dialog.Popup className={styles.Popup}> <Dialog.Title className={styles.Title}>Notifications</Dialog.Title> <Dialog.Description className={styles.Description}> You are all caught up. Good job! </Dialog.Description> <div className={styles.Actions}> <Dialog.Close className={styles.Button}>Close</Dialog.Close> </div> </Dialog.Popup> </Dialog.Portal> </Dialog.Root> ); } Show code ## Anatomy Import the component and assemble its parts: Anatomy Copy import { Dialog } from '@base-ui-components/react/dialog'; <Dialog.Root> <Dialog.Trigger /> <Dialog.Portal> <Dialog.Backdrop /> <Dialog.Popup> <Dialog.Title /> <Dialog.Description /> <Dialog.Close /> </Dialog.Popup> </Dialog.Portal> </Dialog.Root> ## API reference ### Root Groups all parts of the dialog. Doesn’t render its own HTML element. | Prop | Type | Default | | | --- | --- | --- | --- | | `defaultOpen` | `boolean` | `false` | | | `open` | `boolean` | `undefined` | | | `onOpenChange` | `(open: boolean, event?: Event, reason?: Dialog.Root.OpenChangeReason) => void` | `undefined` | | | `actionsRef` | `RefObject<{ unmount: () => void; }>` | `undefined` | | | `dismissible` | `boolean` | `true` | | | `modal` | `boolean | 'trap-focus'` | `true` | | | `onOpenChangeComplete` | `((open: boolean) => void)` | `undefined` | | | `children` | `ReactNode` | `undefined` | | ### Trigger A button that opens the dialog. Renders a `<button>` element. | Prop | Type | Default | | | --- | --- | --- | --- | | `className` | `| string | ((state: Dialog.Trigger.State) => string)` | `undefined` | | | `render` | `| ReactElement | ((props: HTMLProps, state: Dialog.Trigger.State) => ReactElement)` | `undefined` | | | Attribute | Description | | | --- | --- | --- | | `data-popup-open` | Present when the corresponding dialog is open. | | `data-disabled` | Present when the trigger is disabled. | ### Portal A portal element that moves the popup to a different part of the DOM. By default, the portal element is appended to `<body>`. | Prop | Type | Default | | | --- | --- | --- | --- | | `container` | `| HTMLElement | RefObject<HTMLElement | null> | null` | `undefined` | | | `children` | `ReactNode` | `undefined` | | | `keepMounted` | `boolean` | `false` | | ### Backdrop An overlay displayed beneath the popup. Renders a `<div>` element. | Prop | Type | Default | | | --- | --- | --- | --- | | `className` | `| string | ((state: Dialog.Backdrop.State) => string)` | `undefined` | | | `render` | `| ReactElement | ((props: HTMLProps, state: Dialog.Backdrop.State) => ReactElement)` | `undefined` | | | Attribute | Description | | | --- | --- | --- | | `data-open` | Present when the dialog is open. | | `data-closed` | Present when the dialog is closed. | | `data-starting-style` | Present when the dialog is animating in. | | `data-ending-style` | Present when the dialog is animating out. | ### Popup A container for the dialog contents. Renders a `<div>` element. | Prop | Type | Default | | | --- | --- | --- | --- | | `initialFocus` | `| RefObject<HTMLElement | null> | ((interactionType: InteractionType) => RefObject<HTMLElement | null>)` | `undefined` | | | `finalFocus` | `RefObject<HTMLElement | null>` | `undefined` | | | `className` | `| string | ((state: Dialog.Popup.State) => string)` | `undefined` | | | `render` | `| ReactElement | ((props: HTMLProps, state: Dialog.Popup.State) => ReactElement)` | `undefined` | | | Attribute | Description | | | --- | --- | --- | | `data-open` | Present when the dialog is open. | | `data-closed` | Present when the dialog is closed. | | `data-nested` | Present when the dialog is nested within another dialog. | | `data-nested-dialog-open` | Present when the dialog has other open dialogs nested within it. | | `data-starting-style` | Present when the dialog is animating in. | | `data-ending-style` | Present when the dialog is animating out. | | CSS Variable | Description | | | --- | --- | --- | | `--nested-dialogs` | Indicates how many dialogs are nested within. | ### Title A heading that labels the dialog. Renders an `<h2>` element. | Prop | Type | Default | | | --- | --- | --- | --- | | `className` | `| string | ((state: Dialog.Title.State) => string)` | `undefined` | | | `render` | `| ReactElement | ((props: HTMLProps, state: Dialog.Title.State) => ReactElement)` | `undefined` | | ### Description A paragraph with additional information about the dialog. Renders a `<p>` element. | Prop | Type | Default | | | --- | --- | --- | --- | | `className` | `| string | ((state: Dialog.Description.State) => string)` | `undefined` | | | `render` | `| ReactElement | ((props: HTMLProps, state: Dialog.Description.State) => ReactElement)` | `undefined` | | ### Close A button that closes the dialog. Renders a `<button>` element. | Prop | Type | Default | | | --- | --- | --- | --- | | `className` | `| string | ((state: Dialog.Close.State) => string)` | `undefined` | | | `render` | `| ReactElement | ((props: HTMLProps, state: Dialog.Close.State) => ReactElement)` | `undefined` | | | Attribute | Description | | | --- | --- | --- | | `data-disabled` | Present when the button is disabled. | ## Examples ### State By default, Dialog is an uncontrolled component that manages its own state. Uncontrolled dialog Copy <Dialog.Root> <Dialog.Trigger>Open</Dialog.Trigger> <Dialog.Portal> <Dialog.Popup> <Dialog.Title>Example dialog</Dialog.Title> <Dialog.Close>Close</Dialog.Close> </Dialog.Popup> </Dialog.Portal> </Dialog.Root> Use `open` and `onOpenChange` props if you need to access or control the state of the dialog. For example, you can control the dialog state in order to open it imperatively from another place in your app. Controlled dialog Copy const [open, setOpen] = React.useState(false); return ( <Dialog.Root open={open} onOpenChange={setOpen}> <Dialog.Trigger>Open</Dialog.Trigger> <Dialog.Portal> <Dialog.Popup> <form // Close the dialog once the form data is submitted onSubmit={async () => { await submitData(); setOpen(false); }} > ... </form> </Dialog.Popup> </Dialog.Portal> </Dialog.Root> ); It’s also common to use `onOpenChange` if your app needs to do something when the dialog is closed or opened. This is recommended over `React.useEffect` when reacting to state changes. Running code when dialog state changes Copy <Dialog.Root open={open} onOpenChange={(open) => { // Do stuff when the dialog is closed if (!open) { doStuff(); } // Set the new state setOpen(open); }} > ### Open from a menu In order to open a dialog using a menu, control the dialog state and open it imperatively using the `onClick` handler on the menu item. Make sure to also use the dialog’s `finalFocus` prop to return focus back to the menu trigger. Connecting a dialog to a menu Copy import * as React from 'react'; import { Dialog } from '@base-ui/components/dialog'; import { Menu } from '@base-ui/components/menu'; function ExampleMenu() { const menuTriggerRef = React.useRef<HTMLButtonElement>(null); const [dialogOpen, setDialogOpen] = React.useState(false); return ( <React.Fragment> <Menu.Root> {/* Set the trigger ref */} <Menu.Trigger ref={menuTriggerRef}>Open menu</Menu.Trigger> <Menu.Portal> <Menu.Positioner> <Menu.Popup> {/* Open the dialog when the menu item is clicked */} <Menu.Item onClick={() => setDialogOpen(true)}>Open dialog</Menu.Item> </Menu.Popup> </Menu.Positioner> </Menu.Portal> </Menu.Root> {/* Control the dialog state */} <Dialog.Root open={dialogOpen} onOpenChange={setDialogOpen}> <Dialog.Portal> <Dialog.Backdrop /> {/* Return focus to the menu trigger when the dialog is closed */} <Dialog.Popup finalFocus={menuTriggerRef}> {/* Rest of the dialog */} </Dialog.Popup> </Dialog.Portal> </Dialog.Root> </React.Fragment> ); } ### Nested dialogs You can nest dialogs within one another normally. Use the `[data-nested-dialog-open]` selector and the `var(--nested-dialogs)` CSS variable to customize the styling of the parent dialog. Backdrops of the child dialogs won’t be rendered so that you can present the parent dialog in a clean way behind the one on top of it. View notifications Show code ### Close confirmation This example shows a nested confirmation dialog that opens if the text entered in the parent dialog is going to be discarded. To implement this, both dialogs should be controlled. The confirmation dialog may be opened when `onOpenChange` callback of the parent dialog receives a request to close. This way, the confirmation is automatically shown when the user clicks the backdrop, presses the Esc key, or clicks a close button. Tweet Show code --- ## Page: https://base-ui.com/react/components/field Field * (Top) * Anatomy * API reference * Root * Label * Control * Description * Error * Validity # Field A component that provides labelling and validation for form controls. Name Visible on your profile index.tsxindex.module.csstheme.css CSS Modules CodeSandboxCopy import * as React from 'react'; import { Field } from '@base-ui-components/react/field'; import styles from './index.module.css'; export default function ExampleField() { return ( <Field.Root className={styles.Field}> <Field.Label className={styles.Label}>Name</Field.Label> <Field.Control required placeholder="Required" className={styles.Input} /> <Field.Error className={styles.Error} match="valueMissing"> Please enter your name </Field.Error> <Field.Description className={styles.Description}> Visible on your profile </Field.Description> </Field.Root> ); } Show code ## Anatomy Import the component and assemble its parts: Anatomy Copy import { Field } from '@base-ui-components/react/field'; <Field.Root> <Field.Label /> <Field.Control /> <Field.Description /> <Field.Error /> <Field.Validity /> </Field.Root> ## API reference ### Root Groups all parts of the field. Renders a `<div>` element. | Prop | Type | Default | | | --- | --- | --- | --- | | `name` | `string` | `undefined` | | | `disabled` | `boolean` | `false` | | | `invalid` | `boolean` | `undefined` | | | `validate` | `((value: unknown) => string | string[] | Promise<string | string[] | null> | null)` | `undefined` | | | `validationMode` | `'onBlur' | 'onChange'` | `'onBlur'` | | | `validationDebounceTime` | `number` | `0` | | | `className` | `| string | ((state: Field.Root.State) => string)` | `undefined` | | | `render` | `| ReactElement | ((props: HTMLProps, state: Field.Root.State) => ReactElement)` | `undefined` | | | Attribute | Description | | | --- | --- | --- | | `data-disabled` | Present when the field is disabled. | | `data-valid` | Present when the field is valid. | | `data-invalid` | Present when the field is invalid. | | `data-dirty` | Present when the field's value has changed. | | `data-touched` | Present when the field has been touched. | | `data-filled` | Present when the field is filled. | | `data-focused` | Present when the field control is focused. | ### Label An accessible label that is automatically associated with the field control. Renders a `<label>` element. | Prop | Type | Default | | | --- | --- | --- | --- | | `className` | `| string | ((state: Field.Root.State) => string)` | `undefined` | | | `render` | `| ReactElement | ((props: HTMLProps, state: Field.Root.State) => ReactElement)` | `undefined` | | | Attribute | Description | | | --- | --- | --- | | `data-disabled` | Present when the field is disabled. | | `data-valid` | Present when the field is in valid state. | | `data-invalid` | Present when the field is in invalid state. | | `data-dirty` | Present when the field's value has changed. | | `data-touched` | Present when the field has been touched. | | `data-filled` | Present when the field is filled. | | `data-focused` | Present when the field control is focused. | ### Control The form control to label and validate. Renders an `<input>` element. You can omit this part and use any Base UI input component instead. For example, Input, Checkbox, or Select, among others, will work with Field out of the box. | Prop | Type | Default | | | --- | --- | --- | --- | | `defaultValue` | `string | number | string[]` | `undefined` | | | `onValueChange` | `((value: string | number | string[] | undefined, event: Event) => void)` | `undefined` | | | `className` | `| string | ((state: Field.Root.State) => string)` | `undefined` | | | `render` | `| ReactElement | ((props: HTMLProps, state: Field.Root.State) => ReactElement)` | `undefined` | | | Attribute | Description | | | --- | --- | --- | | `data-disabled` | Present when the field is disabled. | | `data-valid` | Present when the field is in valid state. | | `data-invalid` | Present when the field is in invalid state. | | `data-dirty` | Present when the field's value has changed. | | `data-touched` | Present when the field has been touched. | | `data-filled` | Present when the field is filled. | | `data-focused` | Present when the field control is focused. | ### Description A paragraph with additional information about the field. Renders a `<p>` element. | Prop | Type | Default | | | --- | --- | --- | --- | | `className` | `| string | ((state: Field.Root.State) => string)` | `undefined` | | | `render` | `| ReactElement | ((props: HTMLProps, state: Field.Root.State) => ReactElement)` | `undefined` | | | Attribute | Description | | | --- | --- | --- | | `data-disabled` | Present when the field is disabled. | | `data-valid` | Present when the field is in valid state. | | `data-invalid` | Present when the field is in invalid state. | | `data-dirty` | Present when the field's value has changed. | | `data-touched` | Present when the field has been touched. | | `data-filled` | Present when the field is filled. | | `data-focused` | Present when the field control is focused. | ### Error An error message displayed if the field control fails validation. Renders a `<div>` element. | Prop | Type | Default | | | --- | --- | --- | --- | | `match` | `| boolean | 'valid' | 'badInput' | 'customError' | 'patternMismatch' | 'rangeOverflow' | 'rangeUnderflow' | 'stepMismatch' | 'tooLong' | 'tooShort' | 'typeMismatch' | 'valueMissing'` | `undefined` | | | `className` | `| string | ((state: Field.Root.State) => string)` | `undefined` | | | `render` | `| ReactElement | ((props: HTMLProps, state: Field.Root.State) => ReactElement)` | `undefined` | | | Attribute | Description | | | --- | --- | --- | | `data-disabled` | Present when the field is disabled. | | `data-valid` | Present when the field is in valid state. | | `data-invalid` | Present when the field is in invalid state. | | `data-dirty` | Present when the field's value has changed. | | `data-touched` | Present when the field has been touched. | | `data-filled` | Present when the field is filled. | | `data-focused` | Present when the field control is focused. | ### Validity Used to display a custom message based on the field’s validity. Requires `children` to be a function that accepts field validity state as an argument. | Prop | Type | Default | | | --- | --- | --- | --- | | `children*` | `((state: FieldValidityState) => ReactNode)` | `—` | | --- ## Page: https://base-ui.com/react/components/fieldset Fieldset * (Top) * Anatomy * API reference * Root * Legend # Fieldset A native fieldset element with an easily stylable legend. Billing details Company Tax ID index.tsxindex.module.csstheme.css CSS Modules CodeSandboxCopy import * as React from 'react'; import { Field } from '@base-ui-components/react/field'; import { Fieldset } from '@base-ui-components/react/fieldset'; import styles from './index.module.css'; export default function ExampleField() { return ( <Fieldset.Root className={styles.Fieldset}> <Fieldset.Legend className={styles.Legend}>Billing details</Fieldset.Legend> <Field.Root className={styles.Field}> <Field.Label className={styles.Label}>Company</Field.Label> <Field.Control placeholder="Enter company name" className={styles.Input} /> </Field.Root> <Field.Root className={styles.Field}> <Field.Label className={styles.Label}>Tax ID</Field.Label> <Field.Control placeholder="Enter fiscal number" className={styles.Input} /> </Field.Root> </Fieldset.Root> ); } Show code ## Anatomy Import the component and assemble its parts: Anatomy Copy import { Fieldset } from '@base-ui-components/react/fieldset'; <Fieldset.Root> <Fieldset.Legend /> </Fieldset.Root> ## API reference ### Root Groups the fieldset legend and the associated fields. Renders a `<fieldset>` element. | Prop | Type | Default | | | --- | --- | --- | --- | | `className` | `| string | ((state: Fieldset.Root.State) => string)` | `undefined` | | | `render` | `| ReactElement | ((props: HTMLProps, state: Fieldset.Root.State) => ReactElement)` | `undefined` | | ### Legend An accessible label that is automatically associated with the fieldset. Renders a `<div>` element. | Prop | Type | Default | | | --- | --- | --- | --- | | `className` | `| string | ((state: Fieldset.Legend.State) => string)` | `undefined` | | | `render` | `| ReactElement | ((props: HTMLProps, state: Fieldset.Legend.State) => ReactElement)` | `undefined` | | --- ## Page: https://base-ui.com/react/components/form Form * (Top) * Anatomy * API reference * Examples * Using with Zod # Form A native form element with consolidated error handling. Homepage Submit index.tsxindex.module.csstheme.css CSS Modules CodeSandboxCopy import * as React from 'react'; import { Field } from '@base-ui-components/react/field'; import { Form } from '@base-ui-components/react/form'; import styles from './index.module.css'; export default function ExampleForm() { const [errors, setErrors] = React.useState({}); const [loading, setLoading] = React.useState(false); return ( <Form className={styles.Form} errors={errors} onClearErrors={setErrors} onSubmit={async (event) => { event.preventDefault(); const formData = new FormData(event.currentTarget); const value = formData.get('url') as string; setLoading(true); const response = await submitForm(value); const serverErrors = { url: response.error, }; setErrors(serverErrors); setLoading(false); }} > <Field.Root name="url" className={styles.Field}> <Field.Label className={styles.Label}>Homepage</Field.Label> <Field.Control type="url" required defaultValue="https://example.com" placeholder="https://example.com" pattern="https?://.*" className={styles.Input} /> <Field.Error className={styles.Error} /> </Field.Root> <button disabled={loading} type="submit" className={styles.Button}> Submit </button> </Form> ); } async function submitForm(value: string) { // Mimic a server response await new Promise((resolve) => { setTimeout(resolve, 1000); }); try { const url = new URL(value); if (url.hostname.endsWith('example.com')) { return { error: 'The example domain is not allowed' }; } } catch { return { error: 'This is not a valid URL' }; } return { success: true }; } Show code ## Anatomy Form is composed together with Field. Import the components and place them together: Anatomy Copy import { Field } from '@base-ui-components/react/field'; import { Form } from '@base-ui-components/react/form'; <Form> <Field.Root> <Field.Label /> <Field.Control /> <Field.Error /> </Field.Root> </Form> ## API reference | Prop | Type | Default | | | --- | --- | --- | --- | | `errors` | `Errors` | `undefined` | | | `onClearErrors` | `((errors: Errors) => void)` | `undefined` | | | `className` | `string | ((state: Form.State) => string)` | `undefined` | | | `render` | `| ReactElement | ((props: HTMLProps, state: Form.State) => ReactElement)` | `undefined` | | ## Examples ### Using with Zod When parsing the schema using `schema.safeParse()`, the `result.error.flatten().fieldErrors` data can be used to map the errors to each field’s `name`. Name Age Submit index.tsxindex.module.csstheme.css CSS Modules CodeSandboxCopy import * as React from 'react'; import { z } from 'zod'; import { Field } from '@base-ui-components/react/field'; import { Form } from '@base-ui-components/react/form'; import styles from './index.module.css'; const schema = z.object({ name: z.string().min(1), age: z.coerce.number().positive(), }); async function submitForm(event: React.FormEvent<HTMLFormElement>) { event.preventDefault(); const formData = new FormData(event.currentTarget); const result = schema.safeParse(Object.fromEntries(formData as any)); if (!result.success) { return { errors: result.error.flatten().fieldErrors, }; } return { errors: {}, }; } export default function Page() { const [errors, setErrors] = React.useState({}); return ( <Form className={styles.Form} errors={errors} onClearErrors={setErrors} onSubmit={async (event) => { const response = await submitForm(event); setErrors(response.errors); }} > <Field.Root name="name" className={styles.Field}> <Field.Label className={styles.Label}>Name</Field.Label> <Field.Control placeholder="Enter name" className={styles.Input} /> <Field.Error className={styles.Error} /> </Field.Root> <Field.Root name="age" className={styles.Field}> <Field.Label className={styles.Label}>Age</Field.Label> <Field.Control placeholder="Enter age" className={styles.Input} /> <Field.Error className={styles.Error} /> </Field.Root> <button type="submit" className={styles.Button}> Submit </button> </Form> ); } Show code --- ## Page: https://base-ui.com/react/components/input Input * (Top) * Anatomy * API reference # Input A native input element that automatically works with Field. index.tsxindex.module.csstheme.css CSS Modules CodeSandboxCopy import * as React from 'react'; import { Input } from '@base-ui-components/react/input'; import styles from './index.module.css'; export default function ExampleInput() { return <Input placeholder="Name" className={styles.Input} />; } ## Anatomy Import the component and use it as a single part: Anatomy Copy import { Input } from '@base-ui-components/react/input'; <Input /> ## API reference | Prop | Type | Default | | | --- | --- | --- | --- | | `defaultValue` | `string | number | string[]` | `undefined` | | | `onValueChange` | `((value: string | number | string[] | undefined, event: Event) => void)` | `undefined` | | | `className` | `| string | ((state: Input.State) => string)` | `undefined` | | | `render` | `| ReactElement | ((props: HTMLProps, state: Input.State) => ReactElement)` | `undefined` | | | Attribute | Description | | | --- | --- | --- | | `data-disabled` | Present when the input is disabled. | | `data-valid` | Present when the input is in valid state. | | `data-invalid` | Present when the input is in invalid state. | | `data-dirty` | Present when the input's value has changed. | | `data-touched` | Present when the input has been touched. | | `data-filled` | Present when the input is filled. | | `data-focused` | Present when the input is focused. | --- ## Page: https://base-ui.com/react/components/menu Menu * (Top) * Anatomy * API reference * Root * Trigger * Portal * Positioner * Popup * Arrow * Item * Group * GroupLabel * RadioGroup * RadioItem * RadioItemIndicator * CheckboxItem * CheckboxItemIndicator * SubmenuTrigger * Separator * Examples * Open on hover * Checkbox items * Radio items * Close on click * Group labels * Nested menu * Navigate to another page * Open a dialog # Menu A list of actions in a dropdown, enhanced with keyboard navigation. Song index.tsxindex.module.csstheme.css CSS Modules CodeSandboxCopy import * as React from 'react'; import { Menu } from '@base-ui-components/react/menu'; import styles from './index.module.css'; export default function ExampleMenu() { return ( <Menu.Root> <Menu.Trigger className={styles.Button}> Song <ChevronDownIcon className={styles.ButtonIcon} /> </Menu.Trigger> <Menu.Portal> <Menu.Positioner className={styles.Positioner} sideOffset={8}> <Menu.Popup className={styles.Popup}> <Menu.Arrow className={styles.Arrow}> <ArrowSvg /> </Menu.Arrow> <Menu.Item className={styles.Item}>Add to Library</Menu.Item> <Menu.Item className={styles.Item}>Add to Playlist</Menu.Item> <Menu.Separator className={styles.Separator} /> <Menu.Item className={styles.Item}>Play Next</Menu.Item> <Menu.Item className={styles.Item}>Play Last</Menu.Item> <Menu.Separator className={styles.Separator} /> <Menu.Item className={styles.Item}>Favorite</Menu.Item> <Menu.Item className={styles.Item}>Share</Menu.Item> </Menu.Popup> </Menu.Positioner> </Menu.Portal> </Menu.Root> ); } function ArrowSvg(props: React.ComponentProps<'svg'>) { return ( <svg width="20" height="10" viewBox="0 0 20 10" fill="none" {...props}> <path d="M9.66437 2.60207L4.80758 6.97318C4.07308 7.63423 3.11989 8 2.13172 8H0V10H20V8H18.5349C17.5468 8 16.5936 7.63423 15.8591 6.97318L11.0023 2.60207C10.622 2.2598 10.0447 2.25979 9.66437 2.60207Z" className={styles.ArrowFill} /> <path d="M8.99542 1.85876C9.75604 1.17425 10.9106 1.17422 11.6713 1.85878L16.5281 6.22989C17.0789 6.72568 17.7938 7.00001 18.5349 7.00001L15.89 7L11.0023 2.60207C10.622 2.2598 10.0447 2.2598 9.66436 2.60207L4.77734 7L2.13171 7.00001C2.87284 7.00001 3.58774 6.72568 4.13861 6.22989L8.99542 1.85876Z" className={styles.ArrowOuterStroke} /> <path d="M10.3333 3.34539L5.47654 7.71648C4.55842 8.54279 3.36693 9 2.13172 9H0V8H2.13172C3.11989 8 4.07308 7.63423 4.80758 6.97318L9.66437 2.60207C10.0447 2.25979 10.622 2.2598 11.0023 2.60207L15.8591 6.97318C16.5936 7.63423 17.5468 8 18.5349 8H20V9H18.5349C17.2998 9 16.1083 8.54278 15.1901 7.71648L10.3333 3.34539Z" className={styles.ArrowInnerStroke} /> </svg> ); } function ChevronDownIcon(props: React.ComponentProps<'svg'>) { return ( <svg width="10" height="10" viewBox="0 0 10 10" fill="none" {...props}> <path d="M1 3.5L5 7.5L9 3.5" stroke="currentcolor" strokeWidth="1.5" /> </svg> ); } Show code ## Anatomy Import the component and assemble its parts: Anatomy Copy import { Menu } from '@base-ui-components/react/menu'; <Menu.Root> <Menu.Trigger /> <Menu.Portal> <Menu.Backdrop /> <Menu.Positioner> <Menu.Popup> <Menu.Arrow /> <Menu.Item /> <Menu.Separator /> <Menu.Group> <Menu.GroupLabel /> </Menu.Group> <Menu.RadioGroup> <Menu.RadioItem /> </Menu.RadioGroup> <Menu.CheckboxItem /> </Menu.Popup> </Menu.Positioner> </Menu.Portal> </Menu.Root> ## API reference ### Root Groups all parts of the menu. Doesn’t render its own HTML element. | Prop | Type | Default | | | --- | --- | --- | --- | | `defaultOpen` | `boolean` | `false` | | | `open` | `boolean` | `undefined` | | | `onOpenChange` | `(open: boolean, event?: Event, reason?: Menu.Root.OpenChangeReason) => void` | `undefined` | | | `actionsRef` | `RefObject<Actions>` | `undefined` | | | `closeParentOnEsc` | `boolean` | `true` | | | `modal` | `boolean` | `true` | | | `onOpenChangeComplete` | `((open: boolean) => void)` | `undefined` | | | `disabled` | `boolean` | `false` | | | `openOnHover` | `boolean` | `undefined` | | | `delay` | `number` | `100` | | | `closeDelay` | `number` | `0` | | | `loop` | `boolean` | `true` | | | `orientation` | `Menu.Root.Orientation` | `'vertical'` | | | `children*` | `ReactNode` | `—` | | ### Trigger A button that opens the menu. Renders a `<button>` element. | Prop | Type | Default | | | --- | --- | --- | --- | | `disabled` | `boolean` | `false` | | | `children` | `ReactNode` | `undefined` | | | `className` | `| string | ((state: Menu.Trigger.State) => string)` | `undefined` | | | `render` | `| ReactElement | ((props: HTMLProps, state: Menu.Trigger.State) => ReactElement)` | `undefined` | | | Attribute | Description | | | --- | --- | --- | | `data-popup-open` | Present when the corresponding menu is open. | | `data-pressed` | Present when the trigger is pressed. | ### Portal A portal element that moves the popup to a different part of the DOM. By default, the portal element is appended to `<body>`. | Prop | Type | Default | | | --- | --- | --- | --- | | `container` | `| HTMLElement | RefObject<HTMLElement | null> | null` | `undefined` | | | `children` | `ReactNode` | `undefined` | | | `keepMounted` | `boolean` | `false` | | ### Positioner Positions the menu popup against the trigger. Renders a `<div>` element. | Prop | Type | Default | | | --- | --- | --- | --- | | `collisionAvoidance` | `CollisionAvoidance` | `undefined` | | | `align` | `'center' | 'start' | 'end'` | `'center'` | | | `alignOffset` | `number | OffsetFunction` | `0` | | | `side` | `Side` | `'bottom'` | | | `sideOffset` | `number | OffsetFunction` | `0` | | | `arrowPadding` | `number` | `5` | | | `anchor` | `| Element | RefObject<Element | null> | VirtualElement | (() => Element | VirtualElement | null) | null` | `undefined` | | | `collisionBoundary` | `Boundary` | `'clipping-ancestors'` | | | `collisionPadding` | `Padding` | `5` | | | `sticky` | `boolean` | `false` | | | `positionMethod` | `'fixed' | 'absolute'` | `'absolute'` | | | `trackAnchor` | `boolean` | `true` | | | `className` | `| string | ((state: Menu.Positioner.State) => string)` | `undefined` | | | `render` | `| ReactElement | ((props: HTMLProps, state: Menu.Positioner.State) => ReactElement)` | `undefined` | | | Attribute | Description | | | --- | --- | --- | | `data-open` | Present when the menu popup is open. | | `data-closed` | Present when the menu popup is closed. | | `data-anchor-hidden` | Present when the anchor is hidden. | | `data-align` | Indicates how the popup is aligned relative to specified side. | | `data-side` | Indicates which side the popup is positioned relative to the trigger. | | CSS Variable | Description | | | --- | --- | --- | | `--anchor-height` | The anchor's height. | | `--anchor-width` | The anchor's width. | | `--available-height` | The available height between the trigger and the edge of the viewport. | | `--available-width` | The available width between the trigger and the edge of the viewport. | | `--transform-origin` | The coordinates that this element is anchored to. Used for animations and transitions. | ### Popup A container for the menu items. Renders a `<div>` element. | Prop | Type | Default | | | --- | --- | --- | --- | | `finalFocus` | `RefObject<HTMLElement | null>` | `undefined` | | | `id` | `string` | `undefined` | | | `children` | `ReactNode` | `undefined` | | | `className` | `| string | ((state: Menu.Popup.State) => string)` | `undefined` | | | `render` | `| ReactElement | ((props: HTMLProps, state: Menu.Popup.State) => ReactElement)` | `undefined` | | | Attribute | Description | | | --- | --- | --- | | `data-open` | Present when the menu is open. | | `data-closed` | Present when the menu is closed. | | `data-align` | Indicates how the popup is aligned relative to specified side. | | `data-instant` | Present if animations should be instant. | | `data-side` | Indicates which side the popup is positioned relative to the trigger. | | `data-starting-style` | Present when the menu is animating in. | | `data-ending-style` | Present when the menu is animating out. | ### Arrow Displays an element positioned against the menu anchor. Renders a `<div>` element. | Prop | Type | Default | | | --- | --- | --- | --- | | `className` | `| string | ((state: Menu.Arrow.State) => string)` | `undefined` | | | `render` | `| ReactElement | ((props: HTMLProps, state: Menu.Arrow.State) => ReactElement)` | `undefined` | | | Attribute | Description | | | --- | --- | --- | | `data-open` | Present when the menu popup is open. | | `data-closed` | Present when the menu popup is closed. | | `data-uncentered` | Present when the menu arrow is uncentered. | | `data-anchor-hidden` | Present when the anchor is hidden. | | `data-align` | Indicates how the popup is aligned relative to specified side. | | `data-side` | Indicates which side the popup is positioned relative to the trigger. | ### Item An individual interactive item in the menu. Renders a `<div>` element. | Prop | Type | Default | | | --- | --- | --- | --- | | `label` | `string` | `undefined` | | | `onClick` | `MouseEventHandler<HTMLElement>` | `undefined` | | | `closeOnClick` | `boolean` | `true` | | | `disabled` | `boolean` | `false` | | | `id` | `string` | `undefined` | | | `children` | `ReactNode` | `undefined` | | | `className` | `| string | ((state: Menu.Item.State) => string)` | `undefined` | | | `render` | `| ReactElement | ((props: HTMLProps, state: Menu.Item.State) => ReactElement)` | `undefined` | | | Attribute | Description | | | --- | --- | --- | | `data-highlighted` | Present when the menu item is highlighted. | | `data-disabled` | Present when the menu item is disabled. | ### Group Groups related menu items with the corresponding label. Renders a `<div>` element. | Prop | Type | Default | | | --- | --- | --- | --- | | `children` | `ReactNode` | `undefined` | | | `className` | `| string | ((state: Menu.Group.State) => string)` | `undefined` | | | `render` | `| ReactElement | ((props: HTMLProps, state: Menu.Group.State) => ReactElement)` | `undefined` | | ### GroupLabel An accessible label that is automatically associated with its parent group. Renders a `<div>` element. | Prop | Type | Default | | | --- | --- | --- | --- | | `className` | `| string | ((state: Menu.GroupLabel.State) => string)` | `undefined` | | | `render` | `| ReactElement | ((props: HTMLProps, state: Menu.GroupLabel.State) => ReactElement)` | `undefined` | | ### RadioGroup Groups related radio items. Renders a `<div>` element. | Prop | Type | Default | | | --- | --- | --- | --- | | `defaultValue` | `any` | `undefined` | | | `value` | `any` | `undefined` | | | `onValueChange` | `((value: any, event: Event) => void)` | `() => {}` | | | `disabled` | `boolean` | `false` | | | `children` | `ReactNode` | `undefined` | | | `className` | `| string | ((state: Menu.RadioGroup.State) => string)` | `undefined` | | | `render` | `| ReactElement | ((props: HTMLProps, state: Menu.RadioGroup.State) => ReactElement)` | `undefined` | | ### RadioItem A menu item that works like a radio button in a given group. Renders a `<div>` element. | Prop | Type | Default | | | --- | --- | --- | --- | | `label` | `string` | `undefined` | | | `value*` | `any` | `—` | | | `onClick` | `MouseEventHandler<HTMLElement>` | `undefined` | | | `closeOnClick` | `boolean` | `false` | | | `disabled` | `boolean` | `false` | | | `id` | `string` | `undefined` | | | `children` | `ReactNode` | `undefined` | | | `className` | `| string | ((state: Menu.RadioItem.State) => string)` | `undefined` | | | `render` | `| ReactElement | ((props: HTMLProps, state: Menu.RadioItem.State) => ReactElement)` | `undefined` | | | Attribute | Description | | | --- | --- | --- | | `data-checked` | Present when the menu radio item is selected. | | `data-unchecked` | Present when the menu radio item is not selected. | | `data-highlighted` | Present when the menu radio item is highlighted. | | `data-disabled` | Present when the menu radio item is disabled. | ### RadioItemIndicator Indicates whether the radio item is selected. Renders a `<div>` element. | Prop | Type | Default | | | --- | --- | --- | --- | | `className` | `| string | ((state: Menu.RadioItemIndicator.State) => string)` | `undefined` | | | `keepMounted` | `boolean` | `false` | | | `render` | `| ReactElement | ((props: HTMLProps, state: Menu.RadioItemIndicator.State) => ReactElement)` | `undefined` | | | Attribute | Description | | | --- | --- | --- | | `data-checked` | Present when the menu radio item is selected. | | `data-unchecked` | Present when the menu radio item is not selected. | | `data-disabled` | Present when the menu radio item is disabled. | | `data-starting-style` | Present when the radio indicator is animating in. | | `data-ending-style` | Present when the radio indicator is animating out. | ### CheckboxItem A menu item that toggles a setting on or off. Renders a `<div>` element. | Prop | Type | Default | | | --- | --- | --- | --- | | `label` | `string` | `undefined` | | | `defaultChecked` | `boolean` | `false` | | | `checked` | `boolean` | `undefined` | | | `onCheckedChange` | `((checked: boolean, event: Event) => void)` | `undefined` | | | `onClick` | `MouseEventHandler<HTMLElement>` | `undefined` | | | `closeOnClick` | `boolean` | `false` | | | `disabled` | `boolean` | `false` | | | `id` | `string` | `undefined` | | | `children` | `ReactNode` | `undefined` | | | `className` | `| string | ((state: Menu.CheckboxItem.State) => string)` | `undefined` | | | `render` | `| ReactElement | ((props: HTMLProps, state: Menu.CheckboxItem.State) => ReactElement)` | `undefined` | | | Attribute | Description | | | --- | --- | --- | | `data-checked` | Present when the menu checkbox item is checked. | | `data-unchecked` | Present when the menu checkbox item is not checked. | | `data-highlighted` | Present when the menu checkbox item is highlighted. | | `data-disabled` | Present when the menu checkbox item is disabled. | ### CheckboxItemIndicator Indicates whether the checkbox item is ticked. Renders a `<div>` element. | Prop | Type | Default | | | --- | --- | --- | --- | | `className` | `| string | ((state: Menu.CheckboxItemIndicator.State) => string)` | `undefined` | | | `keepMounted` | `boolean` | `false` | | | `render` | `| ReactElement | ((props: HTMLProps, state: Menu.CheckboxItemIndicator.State) => ReactElement)` | `undefined` | | | Attribute | Description | | | --- | --- | --- | | `data-checked` | Present when the menu checkbox item is checked. | | `data-unchecked` | Present when the menu checkbox item is not checked. | | `data-disabled` | Present when the menu checkbox item is disabled. | | `data-starting-style` | Present when the indicator is animating in. | | `data-ending-style` | Present when the indicator is animating out. | ### SubmenuTrigger A menu item that opens a submenu. Renders a `<div>` element. | Prop | Type | Default | | | --- | --- | --- | --- | | `label` | `string` | `undefined` | | | `onClick` | `MouseEventHandler<HTMLElement>` | `undefined` | | | `id` | `string` | `undefined` | | | `children` | `ReactNode` | `undefined` | | | `className` | `| string | ((state: Menu.SubmenuTrigger.State) => string)` | `undefined` | | | `render` | `| ReactElement | ((props: HTMLProps, state: Menu.SubmenuTrigger.State) => ReactElement)` | `undefined` | | | Attribute | Description | | | --- | --- | --- | | `data-popup-open` | Present when the corresponding submenu is open. | ### Separator A separator element accessible to screen readers. Renders a `<div>` element. | Prop | Type | Default | | | --- | --- | --- | --- | | `orientation` | `Orientation` | `'horizontal'` | | | `className` | `| string | ((state: Separator.State) => string)` | `undefined` | | | `render` | `| ReactElement | ((props: HTMLProps, state: Separator.State) => ReactElement)` | `undefined` | | ## Examples ### Open on hover To create a menu that opens on hover, add the `openOnHover` prop to the Root part. You can additionally configure how quickly the menu opens on hover using the `delay` prop. Add to playlist Show code ### Checkbox items Use the `<Menu.CheckboxItem>` part to create a menu item that can toggle a setting on or off. Workspace Show code ### Radio items Use the `<Menu.RadioGroup>` and `<Menu.RadioItem>` parts to create menu items that work like radio buttons. Sort Show code ### Close on click Use the `closeOnClick` prop to change whether the menu closes when an item is clicked. Control whether the menu closes on click Copy // Close the menu when a checkbox item is clicked <Menu.CheckboxItem closeOnClick /> // Keep the menu open when an item is clicked <Menu.Item closeOnClick={false} /> ### Group labels Use the `<Menu.GroupLabel>` part to add a label to a `<Menu.Group>` View Show code ### Nested menu To create a submenu, nest another menu inside the parent menu. Use the `<Menu.SubmenuTrigger>` part for the menu item that opens the nested menu. Adding a submenu Copy <Menu.Root> <Menu.Trigger /> <Menu.Portal> <Menu.Backdrop /> <Menu.Positioner> <Menu.Popup> <Menu.Arrow /> <Menu.Item /> {/* Submenu */} <Menu.Root> <Menu.SubmenuTrigger /> <Menu.Portal> <Menu.Positioner> <Menu.Popup> {/* Submenu items */} </Menu.Popup> </Menu.Positioner> </Menu.Portal> </Menu.Root> </Menu.Popup> </Menu.Positioner> </Menu.Portal> </Menu.Root> Song Show code ### Navigate to another page Use the `render` prop to compose a menu item with an anchor element. A menu item that opens a link Copy <Menu.Item render={<a href="/projects">Go to Projects</a>} /> ### Open a dialog In order to open a dialog using a menu, control the dialog state and open it imperatively using the `onClick` handler on the menu item. Make sure to also use the dialog’s `finalFocus` prop to return focus back to the menu trigger. Connecting a dialog to a menu Copy import * as React from 'react'; import { Dialog } from '@base-ui/components/dialog'; import { Menu } from '@base-ui/components/menu'; function ExampleMenu() { const menuTriggerRef = React.useRef<HTMLButtonElement>(null); const [dialogOpen, setDialogOpen] = React.useState(false); return ( <React.Fragment> <Menu.Root> {/* Set the trigger ref */} <Menu.Trigger ref={menuTriggerRef}>Open menu</Menu.Trigger> <Menu.Portal> <Menu.Positioner> <Menu.Popup> {/* Open the dialog when the menu item is clicked */} <Menu.Item onClick={() => setDialogOpen(true)}>Open dialog</Menu.Item> </Menu.Popup> </Menu.Positioner> </Menu.Portal> </Menu.Root> {/* Control the dialog state */} <Dialog.Root open={dialogOpen} onOpenChange={setDialogOpen}> <Dialog.Portal> <Dialog.Backdrop /> {/* Return focus to the menu trigger when the dialog is closed */} <Dialog.Popup finalFocus={menuTriggerRef}> {/* Rest of the dialog */} </Dialog.Popup> </Dialog.Portal> </Dialog.Root> </React.Fragment> ); } --- ## Page: https://base-ui.com/react/components/menubar Menubar * (Top) * Anatomy * API reference # Menubar A menu bar providing commands and options for your application. FileEditViewHelp index.tsxindex.module.csstheme.css CSS Modules CodeSandboxCopy import * as React from 'react'; import { Menubar } from '@base-ui-components/react/menubar'; import { Menu } from '@base-ui-components/react/menu'; import styles from './index.module.css'; export default function ExampleMenubar() { return ( <Menubar className={styles.Menubar}> <Menu.Root> <Menu.Trigger className={styles.MenuTrigger}>File</Menu.Trigger> <Menu.Portal> <Menu.Positioner className={styles.MenuPositioner} sideOffset={6} alignOffset={-2} > <Menu.Popup className={styles.MenuPopup}> <Menu.Item className={styles.MenuItem} onClick={handleClick}> New </Menu.Item> <Menu.Item className={styles.MenuItem} onClick={handleClick}> Open </Menu.Item> <Menu.Item className={styles.MenuItem} onClick={handleClick}> Save </Menu.Item> <Menu.Root> <Menu.SubmenuTrigger className={styles.MenuItem}> Export <ChevronRightIcon /> </Menu.SubmenuTrigger> <Menu.Portal> <Menu.Positioner alignOffset={-4}> <Menu.Popup className={styles.MenuPopup}> <Menu.Item className={styles.MenuItem} onClick={handleClick}> PDF </Menu.Item> <Menu.Item className={styles.MenuItem} onClick={handleClick}> PNG </Menu.Item> <Menu.Item className={styles.MenuItem} onClick={handleClick}> SVG </Menu.Item> </Menu.Popup> </Menu.Positioner> </Menu.Portal> </Menu.Root> <Menu.Separator className={styles.MenuSeparator} /> <Menu.Item className={styles.MenuItem} onClick={handleClick}> Print </Menu.Item> </Menu.Popup> </Menu.Positioner> </Menu.Portal> </Menu.Root> <Menu.Root> <Menu.Trigger className={styles.MenuTrigger}>Edit</Menu.Trigger> <Menu.Portal> <Menu.Positioner className={styles.MenuPositioner} sideOffset={6}> <Menu.Popup className={styles.MenuPopup}> <Menu.Item className={styles.MenuItem} onClick={handleClick}> Cut </Menu.Item> <Menu.Item className={styles.MenuItem} onClick={handleClick}> Copy </Menu.Item> <Menu.Item className={styles.MenuItem} onClick={handleClick}> Paste </Menu.Item> </Menu.Popup> </Menu.Positioner> </Menu.Portal> </Menu.Root> <Menu.Root> <Menu.Trigger className={styles.MenuTrigger}>View</Menu.Trigger> <Menu.Portal> <Menu.Positioner className={styles.MenuPositioner} sideOffset={6}> <Menu.Popup className={styles.MenuPopup}> <Menu.Item className={styles.MenuItem} onClick={handleClick}> Zoom In </Menu.Item> <Menu.Item className={styles.MenuItem} onClick={handleClick}> Zoom Out </Menu.Item> <Menu.Root> <Menu.SubmenuTrigger className={styles.MenuItem}> Layout <ChevronRightIcon /> </Menu.SubmenuTrigger> <Menu.Portal> <Menu.Positioner alignOffset={-4}> <Menu.Popup className={styles.MenuPopup}> <Menu.Item className={styles.MenuItem} onClick={handleClick}> Single Page </Menu.Item> <Menu.Item className={styles.MenuItem} onClick={handleClick}> Two Pages </Menu.Item> <Menu.Item className={styles.MenuItem} onClick={handleClick}> Continuous </Menu.Item> </Menu.Popup> </Menu.Positioner> </Menu.Portal> </Menu.Root> <Menu.Separator className={styles.MenuSeparator} /> <Menu.Item className={styles.MenuItem} onClick={handleClick}> Full Screen </Menu.Item> </Menu.Popup> </Menu.Positioner> </Menu.Portal> </Menu.Root> <Menu.Root disabled> <Menu.Trigger className={styles.MenuTrigger}>Help</Menu.Trigger> </Menu.Root> </Menubar> ); } function handleClick(event: React.MouseEvent<HTMLElement>) { // eslint-disable-next-line no-console console.log(`${event.currentTarget.textContent} clicked`); } function ChevronRightIcon(props: React.ComponentProps<'svg'>) { return ( <svg width="16" height="16" viewBox="0 0 16 16" fill="none" {...props}> <path d="M6 12L10 8L6 4" stroke="currentColor" strokeWidth="1.5" strokeLinecap="round" strokeLinejoin="round" /> </svg> ); } Show code ## Anatomy Import the component and assemble its parts: Anatomy Copy import { Menubar } from '@base-ui-components/react/menubar'; import { Menu } from '@base-ui-components/react/menu'; <Menubar> <Menu.Root> <Menu.Trigger /> <Menu.Portal> <Menu.Backdrop /> <Menu.Positioner> <Menu.Popup> <Menu.Arrow /> <Menu.Item /> <Menu.Separator /> <Menu.Group> <Menu.GroupLabel /> </Menu.Group> <Menu.RadioGroup> <Menu.RadioItem /> </Menu.RadioGroup> <Menu.CheckboxItem /> </Menu.Popup> </Menu.Positioner> </Menu.Portal> </Menu.Root> </Menubar> ## API reference | Prop | Type | Default | | | --- | --- | --- | --- | | `modal` | `boolean` | `true` | | | `disabled` | `boolean` | `false` | | | `loop` | `boolean` | `true` | | | `orientation` | `Menu.Root.Orientation` | `'horizontal'` | | | `className` | `| string | ((state: Menubar.State) => string)` | `undefined` | | | `render` | `| ReactElement | ((props: HTMLProps, state: Menubar.State) => ReactElement)` | `undefined` | | --- ## Page: https://base-ui.com/react/components/meter Meter * (Top) * Anatomy * API reference * Root * Track * Indicator * Value * Label # Meter A graphical display of a numeric value within a range. Storage Used24% index.tsxindex.module.csstheme.css CSS Modules CodeSandboxCopy import * as React from 'react'; import { Meter } from '@base-ui-components/react/meter'; import styles from './index.module.css'; export default function ExampleMeter() { return ( <Meter.Root className={styles.Meter} value={24}> <Meter.Label className={styles.Label}>Storage Used</Meter.Label> <Meter.Value className={styles.Value} /> <Meter.Track className={styles.Track}> <Meter.Indicator className={styles.Indicator} /> </Meter.Track> </Meter.Root> ); } Show code ## Anatomy Import the component and assemble its parts: Anatomy Copy import { Meter } from '@base-ui-components/react/meter'; <Meter.Root> <Meter.Label /> <Meter.Track> <Meter.Indicator /> </Meter.Track> <Meter.Value /> </Meter.Root> ## API reference ### Root Groups all parts of the meter and provides the value for screen readers. Renders a `<div>` element. | Prop | Type | Default | | | --- | --- | --- | --- | | `value*` | `number` | `—` | | | `getAriaValueText` | `((formattedValue: string, value: number) => string)` | `undefined` | | | `locale` | `LocalesArgument` | `undefined` | | | `min` | `number` | `0` | | | `max` | `number` | `100` | | | `format` | `NumberFormatOptions` | `undefined` | | | `className` | `| string | ((state: Meter.Root.State) => string)` | `undefined` | | | `render` | `| ReactElement | ((props: HTMLProps, state: Meter.Root.State) => ReactElement)` | `undefined` | | ### Track Contains the meter indicator and represents the entire range of the meter. Renders a `<div>` element. | Prop | Type | Default | | | --- | --- | --- | --- | | `className` | `| string | ((state: Meter.Root.State) => string)` | `undefined` | | | `render` | `| ReactElement | ((props: HTMLProps, state: Meter.Root.State) => ReactElement)` | `undefined` | | ### Indicator Visualizes the position of the value along the range. Renders a `<div>` element. | Prop | Type | Default | | | --- | --- | --- | --- | | `className` | `| string | ((state: Meter.Root.State) => string)` | `undefined` | | | `render` | `| ReactElement | ((props: HTMLProps, state: Meter.Root.State) => ReactElement)` | `undefined` | | ### Value A text element displaying the current value. Renders a `<span>` element. | Prop | Type | Default | | | --- | --- | --- | --- | | `children` | `| ((formattedValue: string, value: number) => ReactNode) | null` | `undefined` | | | `className` | `| string | ((state: Meter.Root.State) => string)` | `undefined` | | | `render` | `| ReactElement | ((props: HTMLProps, state: Meter.Root.State) => ReactElement)` | `undefined` | | ### Label An accessible label for the meter. Renders a `<span>` element. | Prop | Type | Default | | | --- | --- | --- | --- | | `className` | `| string | ((state: Meter.Root.State) => string)` | `undefined` | | | `render` | `| ReactElement | ((props: HTMLProps, state: Meter.Root.State) => ReactElement)` | `undefined` | | --- ## Page: https://base-ui.com/react/components/navigation-menu Navigation Menu * (Top) * Anatomy * API reference * Root * List * Item * Trigger * Icon * Content * Link * Backdrop * Portal * Positioner * Popup * Viewport * Arrow * Examples * Nested submenus * Custom links * Large menus # Navigation Menu A collection of links and menus for website navigation. Overview Handbook GitHub index.tsxindex.module.csstheme.css CSS Modules CodeSandboxCopy import * as React from 'react'; import { NavigationMenu } from '@base-ui-components/react/navigation-menu'; import styles from './index.module.css'; export default function ExampleNavigationMenu() { return ( <NavigationMenu.Root className={styles.Root}> <NavigationMenu.List className={styles.List}> <NavigationMenu.Item> <NavigationMenu.Trigger className={styles.Trigger}> Overview <NavigationMenu.Icon className={styles.Icon}> <ChevronDownIcon /> </NavigationMenu.Icon> </NavigationMenu.Trigger> <NavigationMenu.Content className={styles.Content}> <ul className={styles.GridLinkList}> {overviewLinks.map((item) => ( <li key={item.href}> <Link className={styles.LinkCard} href={item.href}> <h3 className={styles.LinkTitle}>{item.title}</h3> <p className={styles.LinkDescription}>{item.description}</p> </Link> </li> ))} </ul> </NavigationMenu.Content> </NavigationMenu.Item> <NavigationMenu.Item> <NavigationMenu.Trigger className={styles.Trigger}> Handbook <NavigationMenu.Icon className={styles.Icon}> <ChevronDownIcon /> </NavigationMenu.Icon> </NavigationMenu.Trigger> <NavigationMenu.Content className={styles.Content}> <ul className={styles.FlexLinkList}> {handbookLinks.map((item) => ( <li key={item.href}> <Link className={styles.LinkCard} href={item.href}> <h3 className={styles.LinkTitle}>{item.title}</h3> <p className={styles.LinkDescription}>{item.description}</p> </Link> </li> ))} </ul> </NavigationMenu.Content> </NavigationMenu.Item> <NavigationMenu.Item> <Link className={styles.Trigger} href="https://github.com/mui/base-ui"> GitHub </Link> </NavigationMenu.Item> </NavigationMenu.List> <NavigationMenu.Portal> <NavigationMenu.Positioner className={styles.Positioner} sideOffset={10} collisionPadding={{ top: 5, bottom: 5, left: 20, right: 20 }} > <NavigationMenu.Popup className={styles.Popup}> <NavigationMenu.Arrow className={styles.Arrow}> <ArrowSvg /> </NavigationMenu.Arrow> <NavigationMenu.Viewport className={styles.Viewport} /> </NavigationMenu.Popup> </NavigationMenu.Positioner> </NavigationMenu.Portal> </NavigationMenu.Root> ); } function Link(props: NavigationMenu.Link.Props) { return ( <NavigationMenu.Link render={ // Use the `render` prop to render your framework's Link component // for client-side routing. // e.g. `<NextLink href={props.href} />` instead of `<a />`. <a /> } {...props} /> ); } function ChevronDownIcon(props: React.ComponentProps<'svg'>) { return ( <svg width="10" height="10" viewBox="0 0 10 10" fill="none" {...props}> <path d="M1 3.5L5 7.5L9 3.5" stroke="currentcolor" strokeWidth="1.5" /> </svg> ); } function ArrowSvg(props: React.ComponentProps<'svg'>) { return ( <svg width="20" height="10" viewBox="0 0 20 10" fill="none" {...props}> <path d="M9.66437 2.60207L4.80758 6.97318C4.07308 7.63423 3.11989 8 2.13172 8H0V10H20V8H18.5349C17.5468 8 16.5936 7.63423 15.8591 6.97318L11.0023 2.60207C10.622 2.2598 10.0447 2.25979 9.66437 2.60207Z" className={styles.ArrowFill} /> <path d="M8.99542 1.85876C9.75604 1.17425 10.9106 1.17422 11.6713 1.85878L16.5281 6.22989C17.0789 6.72568 17.7938 7.00001 18.5349 7.00001L15.89 7L11.0023 2.60207C10.622 2.2598 10.0447 2.2598 9.66436 2.60207L4.77734 7L2.13171 7.00001C2.87284 7.00001 3.58774 6.72568 4.13861 6.22989L8.99542 1.85876Z" className={styles.ArrowOuterStroke} /> <path d="M10.3333 3.34539L5.47654 7.71648C4.55842 8.54279 3.36693 9 2.13172 9H0V8H2.13172C3.11989 8 4.07308 7.63423 4.80758 6.97318L9.66437 2.60207C10.0447 2.25979 10.622 2.2598 11.0023 2.60207L15.8591 6.97318C16.5936 7.63423 17.5468 8 18.5349 8H20V9H18.5349C17.2998 9 16.1083 8.54278 15.1901 7.71648L10.3333 3.34539Z" className={styles.ArrowInnerStroke} /> </svg> ); } const overviewLinks = [ { href: '/react/overview/quick-start', title: 'Quick Start', description: 'Install and assemble your first component.', }, { href: '/react/overview/accessibility', title: 'Accessibility', description: 'Learn how we build accessible components.', }, { href: '/react/overview/releases', title: 'Releases', description: 'See what’s new in the latest Base UI versions.', }, { href: '/react/overview/about', title: 'About', description: 'Learn more about Base UI and our mission.', }, ] as const; const handbookLinks = [ { href: '/react/handbook/styling', title: 'Styling', description: 'Base UI components can be styled with plain CSS, Tailwind CSS, CSS-in-JS, or CSS Modules.', }, { href: '/react/handbook/animation', title: 'Animation', description: 'Base UI components can be animated with CSS transitions, CSS animations, or JavaScript libraries.', }, { href: '/react/handbook/composition', title: 'Composition', description: 'Base UI components can be replaced and composed with your own existing components.', }, ] as const; Show code ## Anatomy Import the component and assemble its parts: Anatomy Copy import { NavigationMenu } from '@base-ui-components/react/navigation-menu'; <NavigationMenu.Root> <NavigationMenu.List> <NavigationMenu.Item> <NavigationMenu.Trigger> <NavigationMenu.Icon /> </NavigationMenu.Trigger> <NavigationMenu.Content> <NavigationMenu.Link /> </NavigationMenu.Content> </NavigationMenu.Item> </NavigationMenu.List> <NavigationMenu.Portal> <NavigationMenu.Backdrop /> <NavigationMenu.Positioner> <NavigationMenu.Popup> <NavigationMenu.Arrow /> <NavigationMenu.Viewport /> </NavigationMenu.Popup> </NavigationMenu.Positioner> </NavigationMenu.Portal> </NavigationMenu.Root> ## API reference ### Root Groups all parts of the navigation menu. Renders a `<nav>` element at the root, or `<div>` element when nested. | Prop | Type | Default | | | --- | --- | --- | --- | | `defaultValue` | `any` | `null` | | | `value` | `any` | `null` | | | `onValueChange` | `((value: any, event: Event | undefined, reason: BaseOpenChangeReason | undefined) => void)` | `undefined` | | | `actionsRef` | `RefObject<{ unmount: () => void; }>` | `undefined` | | | `onOpenChangeComplete` | `((open: boolean) => void)` | `undefined` | | | `delay` | `number` | `50` | | | `closeDelay` | `number` | `50` | | | `orientation` | `'horizontal' | 'vertical'` | `'horizontal'` | | | `className` | `| string | ((state: NavigationMenu.Root.State) => string)` | `undefined` | | | `render` | `| ReactElement | ((props: HTMLProps, state: NavigationMenu.Root.State) => ReactElement)` | `undefined` | | ### List Contains a list of navigation menu items. Renders a `<div>` element. | Prop | Type | Default | | | --- | --- | --- | --- | | `className` | `| string | ((state: NavigationMenu.List.State) => string)` | `undefined` | | | `render` | `| ReactElement | ((props: HTMLProps, state: NavigationMenu.List.State) => ReactElement)` | `undefined` | | ### Item An individual navigation menu item. Renders a `<div>` element. | Prop | Type | Default | | | --- | --- | --- | --- | | `value` | `any` | `undefined` | | | `className` | `| string | ((state: NavigationMenu.Item.State) => string)` | `undefined` | | | `render` | `| ReactElement | ((props: HTMLProps, state: NavigationMenu.Item.State) => ReactElement)` | `undefined` | | ### Trigger Opens the navigation menu popup when hovered or clicked, revealing the associated content. Renders a `<button>` element. | Prop | Type | Default | | | --- | --- | --- | --- | | `className` | `| string | ((state: NavigationMenu.Trigger.State) => string)` | `undefined` | | | `render` | `| ReactElement | ((props: HTMLProps, state: NavigationMenu.Trigger.State) => ReactElement)` | `undefined` | | | Attribute | Description | | | --- | --- | --- | | `data-popup-open` | Present when the corresponding navigation menu is open. | | `data-pressed` | Present when the trigger is pressed. | ### Icon An icon that indicates that the trigger button opens a menu. | Prop | Type | Default | | | --- | --- | --- | --- | | `className` | `| string | ((state: NavigationMenu.Icon.State) => string)` | `undefined` | | | `render` | `| ReactElement | ((props: HTMLProps, state: NavigationMenu.Icon.State) => ReactElement)` | `undefined` | | ### Content A container for the content of the navigation menu item that is moved into the popup when the item is active. Renders a `<div>` element. | Prop | Type | Default | | | --- | --- | --- | --- | | `className` | `| string | ((state: NavigationMenu.Content.State) => string)` | `undefined` | | | `render` | `| ReactElement | ((props: HTMLProps, state: NavigationMenu.Content.State) => ReactElement)` | `undefined` | | | Attribute | Description | | | --- | --- | --- | | `data-open` | Present when the popup is open. | | `data-closed` | Present when the popup is closed. | | `data-activation-direction` | Which direction another trigger was activated from. | | `data-starting-style` | Present when the content is animating in. | | `data-ending-style` | Present when the content is animating out. | ### Link A link in the navigation menu that can be used to navigate to a different page or section. Renders an `<a>` element. | Prop | Type | Default | | | --- | --- | --- | --- | | `className` | `| string | ((state: NavigationMenu.Link.State) => string)` | `undefined` | | | `render` | `| ReactElement | ((props: HTMLProps, state: NavigationMenu.Link.State) => ReactElement)` | `undefined` | | ### Backdrop A backdrop for the navigation menu popup. Renders a `<div>` element. | Prop | Type | Default | | | --- | --- | --- | --- | | `className` | `| string | ((state: NavigationMenu.Backdrop.State) => string)` | `undefined` | | | `render` | `| ReactElement | ((props: HTMLProps, state: NavigationMenu.Backdrop.State) => ReactElement)` | `undefined` | | | Attribute | Description | | | --- | --- | --- | | `data-open` | Present when the popup is open. | | `data-closed` | Present when the popup is closed. | | `data-starting-style` | Present when the popup is animating in. | | `data-ending-style` | Present when the popup is animating out. | ### Portal A portal element that moves the popup to a different part of the DOM. By default, the portal element is appended to `<body>`. | Prop | Type | Default | | | --- | --- | --- | --- | | `container` | `| HTMLElement | RefObject<HTMLElement | null> | null` | `undefined` | | | `children` | `ReactNode` | `undefined` | | | `keepMounted` | `boolean` | `false` | | ### Positioner Positions the navigation menu against the currently active trigger. Renders a `<div>` element. | Prop | Type | Default | | | --- | --- | --- | --- | | `collisionAvoidance` | `CollisionAvoidance` | `undefined` | | | `align` | `'center' | 'start' | 'end'` | `'center'` | | | `alignOffset` | `number | OffsetFunction` | `0` | | | `side` | `Side` | `'bottom'` | | | `sideOffset` | `number | OffsetFunction` | `0` | | | `arrowPadding` | `number` | `5` | | | `anchor` | `| Element | RefObject<Element | null> | VirtualElement | (() => Element | VirtualElement | null) | null` | `undefined` | | | `collisionBoundary` | `Boundary` | `'clipping-ancestors'` | | | `collisionPadding` | `Padding` | `5` | | | `sticky` | `boolean` | `false` | | | `positionMethod` | `'fixed' | 'absolute'` | `'absolute'` | | | `trackAnchor` | `boolean` | `true` | | | `className` | `| string | ((state: NavigationMenu.Positioner.State) => string)` | `undefined` | | | `render` | `| ReactElement | ((props: HTMLProps, state: NavigationMenu.Positioner.State) => ReactElement)` | `undefined` | | | Attribute | Description | | | --- | --- | --- | | `data-open` | Present when the popup is open. | | `data-closed` | Present when the popup is closed. | | `data-anchor-hidden` | Present when the anchor is hidden. | | `data-align` | Indicates how the popup is aligned relative to the specified side. | | `data-instant` | Present if animations should be instant. | | `data-side` | Indicates which side the popup is positioned relative to the trigger. | | CSS Variable | Description | | | --- | --- | --- | | `--anchor-height` | The anchor's height. | | `--anchor-width` | The anchor's width. | | `--available-height` | The available height between the trigger and the edge of the viewport. | | `--available-width` | The available width between the trigger and the edge of the viewport. | | `--positioner-height` | The fixed height of the positioner element. | | `--positioner-width` | The fixed width of the positioner element. | | `--transform-origin` | The coordinates that this element is anchored to. Used for animations and transitions. | ### Popup A container for the navigation menu contents. Renders a `<nav>` element. | Prop | Type | Default | | | --- | --- | --- | --- | | `className` | `| string | ((state: NavigationMenu.Popup.State) => string)` | `undefined` | | | `render` | `| ReactElement | ((props: HTMLProps, state: NavigationMenu.Popup.State) => ReactElement)` | `undefined` | | | Attribute | Description | | | --- | --- | --- | | `data-open` | Present when the popup is open. | | `data-closed` | Present when the popup is closed. | | `data-align` | Indicates how the popup is aligned relative to the specified side. | | `data-side` | Indicates which side the popup is positioned relative to the trigger. | | `data-starting-style` | Present when the popup is animating in. | | `data-ending-style` | Present when the popup is animating out. | | CSS Variable | Description | | | --- | --- | --- | | `--popup-height` | The fixed height of the popup element. | | `--popup-width` | The fixed width of the popup element. | ### Viewport The clipping viewport of the navigation menu's current content. Renders a `<div>` element. | Prop | Type | Default | | | --- | --- | --- | --- | | `className` | `| string | ((state: NavigationMenu.Viewport.State) => string)` | `undefined` | | | `render` | `| ReactElement | ((props: HTMLProps, state: NavigationMenu.Viewport.State) => ReactElement)` | `undefined` | | ### Arrow Displays an element pointing toward the navigation menu's current anchor. Renders a `<div>` element. | Prop | Type | Default | | | --- | --- | --- | --- | | `className` | `| string | ((state: NavigationMenu.Arrow.State) => string)` | `undefined` | | | `render` | `| ReactElement | ((props: HTMLProps, state: NavigationMenu.Arrow.State) => ReactElement)` | `undefined` | | | Attribute | Description | | | --- | --- | --- | | `data-open` | Present when the popup is open. | | `data-closed` | Present when the popup is closed. | | `data-uncentered` | Present when the popup arrow is uncentered. | | `data-align` | Indicates how the popup is aligned relative to specified side. | | `data-side` | Indicates which side the popup is positioned relative to the trigger. | ## Examples ### Nested submenus A `NavigationMenu.Root` component can be nested within a higher-level `NavigationMenu.Content` part to create a multi-level navigation menu. Overview Show code ### Custom links The `NavigationMenu.Link` part can be customized to render the link from your framework using the `render` prop to enable client-side routing. Next.js example Copy import NextLink from 'next/link'; import { NavigationMenu } from '@base-ui-components/react/navigation-menu'; function Link(props: NavigationMenu.Link.Props) { return ( <NavigationMenu.Link render={<NextLink href={props.href} />} {...props} /> ); } ### Large menus When you have large menu content that doesn’t fit in the viewport in some cases, you usually have two choices: 1. Compress the navigation menu content You can change the layout of the navigation menu to render less content or be more compact by reducing the space it takes up. If your content is flexible, you can use the `max-height` property on `Popup` to limit the height of the navigation menu to let it compress itself while preventing overflow. Compact layout Copy .Popup { max-height: var(--available-height); } 2. Make the navigation menu scrollable Scrollable layout Copy .Popup { max-height var(--available-height); } .Content { overflow-y: auto; } Native scrollbars will be visible while transitioning content, so we recommend using our Scroll Area component instead of native scrollbars to keep them hidden, which will also allow the `Arrow` to be centered correctly. --- ## Page: https://base-ui.com/react/components/number-field Number Field * (Top) * Anatomy * API reference * Root * ScrubArea * ScrubAreaCursor * Group * Decrement * Input * Increment # Number Field A numeric input element with increment and decrement buttons, and a scrub area. Amount index.tsxindex.module.csstheme.css CSS Modules CodeSandboxCopy import * as React from 'react'; import { NumberField } from '@base-ui-components/react/number-field'; import styles from './index.module.css'; export default function ExampleNumberField() { const id = React.useId(); return ( <NumberField.Root id={id} defaultValue={100} className={styles.Field}> <NumberField.ScrubArea className={styles.ScrubArea}> <label htmlFor={id} className={styles.Label}> Amount </label> <NumberField.ScrubAreaCursor className={styles.ScrubAreaCursor}> <CursorGrowIcon /> </NumberField.ScrubAreaCursor> </NumberField.ScrubArea> <NumberField.Group className={styles.Group}> <NumberField.Decrement className={styles.Decrement}> <MinusIcon /> </NumberField.Decrement> <NumberField.Input className={styles.Input} /> <NumberField.Increment className={styles.Increment}> <PlusIcon /> </NumberField.Increment> </NumberField.Group> </NumberField.Root> ); } function CursorGrowIcon(props: React.ComponentProps<'svg'>) { return ( <svg width="26" height="14" viewBox="0 0 24 14" fill="black" stroke="white" xmlns="http://www.w3.org/2000/svg" {...props} > <path d="M19.5 5.5L6.49737 5.51844V2L1 6.9999L6.5 12L6.49737 8.5L19.5 8.5V12L25 6.9999L19.5 2V5.5Z" /> </svg> ); } function PlusIcon(props: React.ComponentProps<'svg'>) { return ( <svg width="10" height="10" viewBox="0 0 10 10" fill="none" stroke="currentcolor" strokeWidth="1.6" xmlns="http://www.w3.org/2000/svg" {...props} > <path d="M0 5H5M10 5H5M5 5V0M5 5V10" /> </svg> ); } function MinusIcon(props: React.ComponentProps<'svg'>) { return ( <svg width="10" height="10" viewBox="0 0 10 10" fill="none" stroke="currentcolor" strokeWidth="1.6" xmlns="http://www.w3.org/2000/svg" {...props} > <path d="M0 5H10" /> </svg> ); } Show code ## Anatomy Import the component and assemble its parts: Anatomy Copy import { NumberField } from '@base-ui-components/react/number-field'; <NumberField.Root> <NumberField.ScrubArea> <NumberField.ScrubAreaCursor /> </NumberField.ScrubArea> <NumberField.Group> <NumberField.Decrement /> <NumberField.Input /> <NumberField.Increment /> </NumberField.Group> </NumberField.Root> ## API reference ### Root Groups all parts of the number field and manages its state. Renders a `<div>` element. | Prop | Type | Default | | | --- | --- | --- | --- | | `name` | `string` | `undefined` | | | `defaultValue` | `number` | `undefined` | | | `value` | `number | null` | `undefined` | | | `onValueChange` | `((value: number | null, event: Event | undefined) => void)` | `undefined` | | | `locale` | `LocalesArgument` | `undefined` | | | `snapOnStep` | `boolean` | `false` | | | `step` | `number` | `1` | | | `smallStep` | `number` | `0.1` | | | `largeStep` | `number` | `10` | | | `min` | `number` | `undefined` | | | `max` | `number` | `undefined` | | | `allowWheelScrub` | `boolean` | `false` | | | `format` | `NumberFormatOptions` | `undefined` | | | `disabled` | `boolean` | `false` | | | `readOnly` | `boolean` | `false` | | | `required` | `boolean` | `false` | | | `invalid` | `boolean` | `false` | | | `inputRef` | `Ref<HTMLInputElement>` | `undefined` | | | `id` | `string` | `undefined` | | | `className` | `| string | ((state: NumberField.Root.State) => string)` | `undefined` | | | `render` | `| ReactElement | ((props: HTMLProps, state: NumberField.Root.State) => ReactElement)` | `undefined` | | | Attribute | Description | | | --- | --- | --- | | `data-disabled` | Present when the number field is disabled. | | `data-readonly` | Present when the number field is readonly. | | `data-required` | Present when the number field is required. | | `data-valid` | Present when the number field is in valid state (when wrapped in Field.Root). | | `data-invalid` | Present when the number field is in invalid state (when wrapped in Field.Root). | | `data-dirty` | Present when the number field's value has changed (when wrapped in Field.Root). | | `data-touched` | Present when the number field has been touched (when wrapped in Field.Root). | | `data-filled` | Present when the number field is filled (when wrapped in Field.Root). | | `data-focused` | Present when the number field is focused (when wrapped in Field.Root). | | `data-scrubbing` | Present while scrubbing. | ### ScrubArea An interactive area where the user can click and drag to change the field value. Renders a `<span>` element. | Prop | Type | Default | | | --- | --- | --- | --- | | `direction` | `'horizontal' | 'vertical'` | `'horizontal'` | | | `pixelSensitivity` | `number` | `2` | | | `teleportDistance` | `number` | `undefined` | | | `className` | `| string | ((state: NumberField.ScrubArea.State) => string)` | `undefined` | | | `render` | `| ReactElement | ((props: HTMLProps, state: NumberField.ScrubArea.State) => ReactElement)` | `undefined` | | | Attribute | Description | | | --- | --- | --- | | `data-disabled` | Present when the number field is disabled. | | `data-readonly` | Present when the number field is readonly. | | `data-required` | Present when the number field is required. | | `data-valid` | Present when the number field is in valid state (when wrapped in Field.Root). | | `data-invalid` | Present when the number field is in invalid state (when wrapped in Field.Root). | | `data-dirty` | Present when the number field's value has changed (when wrapped in Field.Root). | | `data-touched` | Present when the number field has been touched (when wrapped in Field.Root). | | `data-filled` | Present when the number field is filled (when wrapped in Field.Root). | | `data-focused` | Present when the number field is focused (when wrapped in Field.Root). | | `data-scrubbing` | Present while scrubbing. | ### ScrubAreaCursor A custom element to display instead of the native cursor while using the scrub area. Renders a `<span>` element. This component uses the Pointer Lock API, which may prompt the browser to display a related notification. It is disabled in Safari to avoid a layout shift that this notification causes there. | Prop | Type | Default | | | --- | --- | --- | --- | | `className` | `| string | ((state: NumberField.ScrubAreaCursor.State) => string)` | `undefined` | | | `render` | `| ReactElement | ((props: HTMLProps, state: NumberField.ScrubAreaCursor.State) => ReactElement)` | `undefined` | | | Attribute | Description | | | --- | --- | --- | | `data-disabled` | Present when the number field is disabled. | | `data-readonly` | Present when the number field is readonly. | | `data-required` | Present when the number field is required. | | `data-valid` | Present when the number field is in valid state (when wrapped in Field.Root). | | `data-invalid` | Present when the number field is in invalid state (when wrapped in Field.Root). | | `data-dirty` | Present when the number field's value has changed (when wrapped in Field.Root). | | `data-touched` | Present when the number field has been touched (when wrapped in Field.Root). | | `data-filled` | Present when the number field is filled (when wrapped in Field.Root). | | `data-focused` | Present when the number field is focused (when wrapped in Field.Root). | | `data-scrubbing` | Present while scrubbing. | ### Group Groups the input with the increment and decrement buttons. Renders a `<div>` element. | Prop | Type | Default | | | --- | --- | --- | --- | | `className` | `| string | ((state: NumberField.Group.State) => string)` | `undefined` | | | `render` | `| ReactElement | ((props: HTMLProps, state: NumberField.Group.State) => ReactElement)` | `undefined` | | | Attribute | Description | | | --- | --- | --- | | `data-disabled` | Present when the number field is disabled. | | `data-readonly` | Present when the number field is readonly. | | `data-required` | Present when the number field is required. | | `data-valid` | Present when the number field is in valid state (when wrapped in Field.Root). | | `data-invalid` | Present when the number field is in invalid state (when wrapped in Field.Root). | | `data-dirty` | Present when the number field's value has changed (when wrapped in Field.Root). | | `data-touched` | Present when the number field has been touched (when wrapped in Field.Root). | | `data-filled` | Present when the number field is filled (when wrapped in Field.Root). | | `data-focused` | Present when the number field is focused (when wrapped in Field.Root). | | `data-scrubbing` | Present while scrubbing. | ### Decrement A stepper button that decreases the field value when clicked. Renders an `<button>` element. | Prop | Type | Default | | | --- | --- | --- | --- | | `className` | `| string | ((state: NumberField.Decrement.State) => string)` | `undefined` | | | `render` | `| ReactElement | ((props: HTMLProps, state: NumberField.Decrement.State) => ReactElement)` | `undefined` | | | Attribute | Description | | | --- | --- | --- | | `data-disabled` | Present when the number field is disabled. | | `data-readonly` | Present when the number field is readonly. | | `data-required` | Present when the number field is required. | | `data-valid` | Present when the number field is in valid state (when wrapped in Field.Root). | | `data-invalid` | Present when the number field is in invalid state (when wrapped in Field.Root). | | `data-dirty` | Present when the number field's value has changed (when wrapped in Field.Root). | | `data-touched` | Present when the number field has been touched (when wrapped in Field.Root). | | `data-filled` | Present when the number field is filled (when wrapped in Field.Root). | | `data-focused` | Present when the number field is focused (when wrapped in Field.Root). | | `data-scrubbing` | Present while scrubbing. | ### Input The native input control in the number field. Renders an `<input>` element. | Prop | Type | Default | | | --- | --- | --- | --- | | `className` | `| string | ((state: NumberField.Input.State) => string)` | `undefined` | | | `render` | `| ReactElement | ((props: HTMLProps, state: NumberField.Input.State) => ReactElement)` | `undefined` | | | Attribute | Description | | | --- | --- | --- | | `data-disabled` | Present when the number field is disabled. | | `data-readonly` | Present when the number field is readonly. | | `data-required` | Present when the number field is required. | | `data-valid` | Present when the number field is in valid state (when wrapped in Field.Root). | | `data-invalid` | Present when the number field is in invalid state (when wrapped in Field.Root). | | `data-dirty` | Present when the number field's value has changed (when wrapped in Field.Root). | | `data-touched` | Present when the number field has been touched (when wrapped in Field.Root). | | `data-filled` | Present when the number field is filled (when wrapped in Field.Root). | | `data-focused` | Present when the number field is focused (when wrapped in Field.Root). | | `data-scrubbing` | Present while scrubbing. | ### Increment A stepper button that increases the field value when clicked. Renders an `<button>` element. | Prop | Type | Default | | | --- | --- | --- | --- | | `className` | `| string | ((state: NumberField.Increment.State) => string)` | `undefined` | | | `render` | `| ReactElement | ((props: HTMLProps, state: NumberField.Increment.State) => ReactElement)` | `undefined` | | | Attribute | Description | | | --- | --- | --- | | `data-disabled` | Present when the number field is disabled. | | `data-readonly` | Present when the number field is readonly. | | `data-required` | Present when the number field is required. | | `data-valid` | Present when the number field is in valid state (when wrapped in Field.Root). | | `data-invalid` | Present when the number field is in invalid state (when wrapped in Field.Root). | | `data-dirty` | Present when the number field's value has changed (when wrapped in Field.Root). | | `data-touched` | Present when the number field has been touched (when wrapped in Field.Root). | | `data-filled` | Present when the number field is filled (when wrapped in Field.Root). | | `data-focused` | Present when the number field is focused (when wrapped in Field.Root). | | `data-scrubbing` | Present while scrubbing. | --- ## Page: https://base-ui.com/react/components/popover Popover * (Top) * Anatomy * API reference * Root * Trigger * Backdrop * Portal * Positioner * Popup * Arrow * Title * Description * Close # Popover An accessible popup anchored to a button. index.tsxindex.module.csstheme.css CSS Modules CodeSandboxCopy import * as React from 'react'; import { Popover } from '@base-ui-components/react/popover'; import styles from './index.module.css'; export default function ExamplePopover() { return ( <Popover.Root> <Popover.Trigger className={styles.IconButton}> <BellIcon aria-label="Notifications" className={styles.Icon} /> </Popover.Trigger> <Popover.Portal> <Popover.Positioner sideOffset={8}> <Popover.Popup className={styles.Popup}> <Popover.Arrow className={styles.Arrow}> <ArrowSvg /> </Popover.Arrow> <Popover.Title className={styles.Title}>Notifications</Popover.Title> <Popover.Description className={styles.Description}> You are all caught up. Good job! </Popover.Description> </Popover.Popup> </Popover.Positioner> </Popover.Portal> </Popover.Root> ); } function ArrowSvg(props: React.ComponentProps<'svg'>) { return ( <svg width="20" height="10" viewBox="0 0 20 10" fill="none" {...props}> <path d="M9.66437 2.60207L4.80758 6.97318C4.07308 7.63423 3.11989 8 2.13172 8H0V10H20V8H18.5349C17.5468 8 16.5936 7.63423 15.8591 6.97318L11.0023 2.60207C10.622 2.2598 10.0447 2.25979 9.66437 2.60207Z" className={styles.ArrowFill} /> <path d="M8.99542 1.85876C9.75604 1.17425 10.9106 1.17422 11.6713 1.85878L16.5281 6.22989C17.0789 6.72568 17.7938 7.00001 18.5349 7.00001L15.89 7L11.0023 2.60207C10.622 2.2598 10.0447 2.2598 9.66436 2.60207L4.77734 7L2.13171 7.00001C2.87284 7.00001 3.58774 6.72568 4.13861 6.22989L8.99542 1.85876Z" className={styles.ArrowOuterStroke} /> <path d="M10.3333 3.34539L5.47654 7.71648C4.55842 8.54279 3.36693 9 2.13172 9H0V8H2.13172C3.11989 8 4.07308 7.63423 4.80758 6.97318L9.66437 2.60207C10.0447 2.25979 10.622 2.2598 11.0023 2.60207L15.8591 6.97318C16.5936 7.63423 17.5468 8 18.5349 8H20V9H18.5349C17.2998 9 16.1083 8.54278 15.1901 7.71648L10.3333 3.34539Z" className={styles.ArrowInnerStroke} /> </svg> ); } function BellIcon(props: React.ComponentProps<'svg'>) { return ( <svg fill="currentcolor" width="20" height="20" viewBox="0 0 16 16" {...props}> <path d="M 8 1 C 7.453125 1 7 1.453125 7 2 L 7 3.140625 C 5.28125 3.589844 4 5.144531 4 7 L 4 10.984375 C 4 10.984375 3.984375 11.261719 3.851563 11.519531 C 3.71875 11.78125 3.558594 12 3 12 L 3 13 L 13 13 L 13 12 C 12.40625 12 12.253906 11.78125 12.128906 11.53125 C 12.003906 11.277344 12 11.003906 12 11.003906 L 12 7 C 12 5.144531 10.71875 3.589844 9 3.140625 L 9 2 C 9 1.453125 8.546875 1 8 1 Z M 8 13 C 7.449219 13 7 13.449219 7 14 C 7 14.550781 7.449219 15 8 15 C 8.550781 15 9 14.550781 9 14 C 9 13.449219 8.550781 13 8 13 Z M 8 4 C 9.664063 4 11 5.335938 11 7 L 11 10.996094 C 11 10.996094 10.988281 11.472656 11.234375 11.96875 C 11.238281 11.980469 11.246094 11.988281 11.25 12 L 4.726563 12 C 4.730469 11.992188 4.738281 11.984375 4.742188 11.980469 C 4.992188 11.488281 5 11.015625 5 11.015625 L 5 7 C 5 5.335938 6.335938 4 8 4 Z" /> </svg> ); } Show code ## Anatomy Import the component and assemble its parts: Anatomy Copy import { Popover } from '@base-ui-components/react/popover'; <Popover.Root> <Popover.Trigger /> <Popover.Portal> <Popover.Backdrop /> <Popover.Positioner> <Popover.Popup> <Popover.Arrow /> <Popover.Title /> <Popover.Description /> <Popover.Close /> </Popover.Popup> </Popover.Positioner> </Popover.Portal> </Popover.Root> ## API reference ### Root Groups all parts of the popover. Doesn’t render its own HTML element. | Prop | Type | Default | | | --- | --- | --- | --- | | `defaultOpen` | `boolean` | `false` | | | `open` | `boolean` | `undefined` | | | `onOpenChange` | `(open: boolean, event?: Event, reason?: Popover.Root.OpenChangeReason) => void` | `undefined` | | | `actionsRef` | `RefObject<Actions>` | `undefined` | | | `modal` | `boolean | 'trap-focus'` | `false` | | | `onOpenChangeComplete` | `((open: boolean) => void)` | `undefined` | | | `openOnHover` | `boolean` | `false` | | | `delay` | `number` | `300` | | | `closeDelay` | `number` | `0` | | | `children` | `ReactNode` | `undefined` | | ### Trigger A button that opens the popover. Renders a `<button>` element. | Prop | Type | Default | | | --- | --- | --- | --- | | `className` | `| string | ((state: Popover.Trigger.State) => string)` | `undefined` | | | `render` | `| ReactElement | ((props: HTMLProps, state: Popover.Trigger.State) => ReactElement)` | `undefined` | | | Attribute | Description | | | --- | --- | --- | | `data-popup-open` | Present when the corresponding popover is open. | | `data-pressed` | Present when the trigger is pressed. | ### Backdrop An overlay displayed beneath the popover. Renders a `<div>` element. | Prop | Type | Default | | | --- | --- | --- | --- | | `className` | `| string | ((state: Popover.Backdrop.State) => string)` | `undefined` | | | `render` | `| ReactElement | ((props: HTMLProps, state: Popover.Backdrop.State) => ReactElement)` | `undefined` | | | Attribute | Description | | | --- | --- | --- | | `data-open` | Present when the popup is open. | | `data-closed` | Present when the popup is closed. | | `data-starting-style` | Present when the popup is animating in. | | `data-ending-style` | Present when the popup is animating out. | ### Portal A portal element that moves the popup to a different part of the DOM. By default, the portal element is appended to `<body>`. | Prop | Type | Default | | | --- | --- | --- | --- | | `container` | `| HTMLElement | RefObject<HTMLElement | null> | null` | `undefined` | | | `children` | `ReactNode` | `undefined` | | | `keepMounted` | `boolean` | `false` | | ### Positioner Positions the popover against the trigger. Renders a `<div>` element. | Prop | Type | Default | | | --- | --- | --- | --- | | `collisionAvoidance` | `CollisionAvoidance` | `undefined` | | | `align` | `'center' | 'start' | 'end'` | `'center'` | | | `alignOffset` | `number | OffsetFunction` | `0` | | | `side` | `Side` | `'bottom'` | | | `sideOffset` | `number | OffsetFunction` | `0` | | | `arrowPadding` | `number` | `5` | | | `anchor` | `| Element | RefObject<Element | null> | VirtualElement | (() => Element | VirtualElement | null) | null` | `undefined` | | | `collisionBoundary` | `Boundary` | `'clipping-ancestors'` | | | `collisionPadding` | `Padding` | `5` | | | `sticky` | `boolean` | `false` | | | `positionMethod` | `'fixed' | 'absolute'` | `'absolute'` | | | `trackAnchor` | `boolean` | `true` | | | `className` | `| string | ((state: Popover.Positioner.State) => string)` | `undefined` | | | `render` | `| ReactElement | ((props: HTMLProps, state: Popover.Positioner.State) => ReactElement)` | `undefined` | | | Attribute | Description | | | --- | --- | --- | | `data-open` | Present when the popup is open. | | `data-closed` | Present when the popup is closed. | | `data-anchor-hidden` | Present when the anchor is hidden. | | `data-align` | Indicates how the popup is aligned relative to specified side. | | `data-side` | Indicates which side the popup is positioned relative to the trigger. | | CSS Variable | Description | | | --- | --- | --- | | `--anchor-height` | The anchor's height. | | `--anchor-width` | The anchor's width. | | `--available-height` | The available height between the trigger and the edge of the viewport. | | `--available-width` | The available width between the trigger and the edge of the viewport. | | `--transform-origin` | The coordinates that this element is anchored to. Used for animations and transitions. | ### Popup A container for the popover contents. Renders a `<div>` element. | Prop | Type | Default | | | --- | --- | --- | --- | | `initialFocus` | `| RefObject<HTMLElement | null> | ((interactionType: InteractionType) => RefObject<HTMLElement | null>)` | `undefined` | | | `finalFocus` | `RefObject<HTMLElement | null>` | `undefined` | | | `className` | `| string | ((state: Popover.Popup.State) => string)` | `undefined` | | | `render` | `| ReactElement | ((props: HTMLProps, state: Popover.Popup.State) => ReactElement)` | `undefined` | | | Attribute | Description | | | --- | --- | --- | | `data-open` | Present when the popup is open. | | `data-closed` | Present when the popup is closed. | | `data-align` | Indicates how the popup is aligned relative to specified side. | | `data-instant` | Present if animations should be instant. | | `data-side` | Indicates which side the popup is positioned relative to the trigger. | | `data-starting-style` | Present when the popup is animating in. | | `data-ending-style` | Present when the popup is animating out. | ### Arrow Displays an element positioned against the popover anchor. Renders a `<div>` element. | Prop | Type | Default | | | --- | --- | --- | --- | | `className` | `| string | ((state: Popover.Arrow.State) => string)` | `undefined` | | | `render` | `| ReactElement | ((props: HTMLProps, state: Popover.Arrow.State) => ReactElement)` | `undefined` | | | Attribute | Description | | | --- | --- | --- | | `data-open` | Present when the popup is open. | | `data-closed` | Present when the popup is closed. | | `data-uncentered` | Present when the popover arrow is uncentered. | | `data-anchor-hidden` | Present when the anchor is hidden. | | `data-align` | Indicates how the popup is aligned relative to specified side. | | `data-side` | Indicates which side the popup is positioned relative to the trigger. | ### Title A heading that labels the popover. Renders an `<h2>` element. | Prop | Type | Default | | | --- | --- | --- | --- | | `className` | `| string | ((state: Popover.Title.State) => string)` | `undefined` | | | `render` | `| ReactElement | ((props: HTMLProps, state: Popover.Title.State) => ReactElement)` | `undefined` | | ### Description A paragraph with additional information about the popover. Renders a `<p>` element. | Prop | Type | Default | | | --- | --- | --- | --- | | `className` | `| string | ((state: Popover.Description.State) => string)` | `undefined` | | | `render` | `| ReactElement | ((props: HTMLProps, state: Popover.Description.State) => ReactElement)` | `undefined` | | ### Close A button that closes the popover. Renders a `<button>` element. | Prop | Type | Default | | | --- | --- | --- | --- | | `className` | `| string | ((state: Popover.Close.State) => string)` | `undefined` | | | `render` | `| ReactElement | ((props: HTMLProps, state: Popover.Close.State) => ReactElement)` | `undefined` | | --- ## Page: https://base-ui.com/react/components/preview-card Preview Card * (Top) * Anatomy * API reference * Root * Trigger * Portal * Backdrop * Positioner * Popup * Arrow # Preview Card A popup that appears when a link is hovered, showing a preview for sighted users. The principles of good typography remain into the digital age. index.tsxindex.module.csstheme.css CSS Modules CodeSandboxCopy import * as React from 'react'; import { PreviewCard } from '@base-ui-components/react/preview-card'; import styles from './index.module.css'; export default function ExamplePreviewCard() { return ( <PreviewCard.Root> <p className={styles.Paragraph}> The principles of good{' '} <PreviewCard.Trigger className={styles.Link} href="https://en.wikipedia.org/wiki/Typography" > typography </PreviewCard.Trigger>{' '} remain into the digital age. </p> <PreviewCard.Portal> <PreviewCard.Positioner sideOffset={8}> <PreviewCard.Popup className={styles.Popup}> <PreviewCard.Arrow className={styles.Arrow}> <ArrowSvg /> </PreviewCard.Arrow> <img width="448" height="300" className={styles.Image} src="https://images.unsplash.com/photo-1619615391095-dfa29e1672ef?q=80&w=448&h=300" alt="Station Hofplein signage in Rotterdam, Netherlands" /> <p className={styles.Summary}> <strong>Typography</strong> is the art and science of arranging type to make written language clear, visually appealing, and effective in communication. </p> </PreviewCard.Popup> </PreviewCard.Positioner> </PreviewCard.Portal> </PreviewCard.Root> ); } function ArrowSvg(props: React.ComponentProps<'svg'>) { return ( <svg width="20" height="10" viewBox="0 0 20 10" fill="none" {...props}> <path d="M9.66437 2.60207L4.80758 6.97318C4.07308 7.63423 3.11989 8 2.13172 8H0V10H20V8H18.5349C17.5468 8 16.5936 7.63423 15.8591 6.97318L11.0023 2.60207C10.622 2.2598 10.0447 2.25979 9.66437 2.60207Z" className={styles.ArrowFill} /> <path d="M8.99542 1.85876C9.75604 1.17425 10.9106 1.17422 11.6713 1.85878L16.5281 6.22989C17.0789 6.72568 17.7938 7.00001 18.5349 7.00001L15.89 7L11.0023 2.60207C10.622 2.2598 10.0447 2.2598 9.66436 2.60207L4.77734 7L2.13171 7.00001C2.87284 7.00001 3.58774 6.72568 4.13861 6.22989L8.99542 1.85876Z" className={styles.ArrowOuterStroke} /> <path d="M10.3333 3.34539L5.47654 7.71648C4.55842 8.54279 3.36693 9 2.13172 9H0V8H2.13172C3.11989 8 4.07308 7.63423 4.80758 6.97318L9.66437 2.60207C10.0447 2.25979 10.622 2.2598 11.0023 2.60207L15.8591 6.97318C16.5936 7.63423 17.5468 8 18.5349 8H20V9H18.5349C17.2998 9 16.1083 8.54278 15.1901 7.71648L10.3333 3.34539Z" className={styles.ArrowInnerStroke} /> </svg> ); } Show code ## Anatomy Import the component and assemble its parts: Anatomy Copy import { PreviewCard } from '@base-ui-components/react/previewCard'; <PreviewCard.Root> <PreviewCard.Trigger /> <PreviewCard.Portal> <PreviewCard.Backdrop /> <PreviewCard.Positioner> <PreviewCard.Popup> <PreviewCard.Arrow /> </PreviewCard.Popup> </PreviewCard.Positioner> </PreviewCard.Portal> </PreviewCard.Root> ## API reference ### Root Groups all parts of the preview card. Doesn’t render its own HTML element. | Prop | Type | Default | | | --- | --- | --- | --- | | `defaultOpen` | `boolean` | `false` | | | `open` | `boolean` | `undefined` | | | `onOpenChange` | `(open: boolean, event?: Event, reason?: PreviewCard.Root.OpenChangeReason) => void` | `undefined` | | | `actionsRef` | `RefObject<Actions>` | `undefined` | | | `onOpenChangeComplete` | `((open: boolean) => void)` | `undefined` | | | `delay` | `number` | `600` | | | `closeDelay` | `number` | `300` | | | `children` | `ReactNode` | `undefined` | | ### Trigger A link that opens the preview card. Renders an `<a>` element. | Prop | Type | Default | | | --- | --- | --- | --- | | `className` | `| string | ((state: PreviewCard.Trigger.State) => string)` | `undefined` | | | `render` | `| ReactElement | ((props: HTMLProps, state: PreviewCard.Trigger.State) => ReactElement)` | `undefined` | | | Attribute | Description | | | --- | --- | --- | | `data-popup-open` | Present when the corresponding preview card is open. | ### Portal A portal element that moves the popup to a different part of the DOM. By default, the portal element is appended to `<body>`. | Prop | Type | Default | | | --- | --- | --- | --- | | `container` | `| HTMLElement | RefObject<HTMLElement | null> | null` | `undefined` | | | `children` | `ReactNode` | `undefined` | | | `keepMounted` | `boolean` | `false` | | ### Backdrop An overlay displayed beneath the popup. Renders a `<div>` element. | Prop | Type | Default | | | --- | --- | --- | --- | | `className` | `| string | ((state: PreviewCard.Backdrop.State) => string)` | `undefined` | | | `render` | `| ReactElement | ((props: HTMLProps, state: PreviewCard.Backdrop.State) => ReactElement)` | `undefined` | | | Attribute | Description | | | --- | --- | --- | | `data-open` | Present when the preview card is open. | | `data-closed` | Present when the preview card is closed. | | `data-starting-style` | Present when the preview card is animating in. | | `data-ending-style` | Present when the preview card is animating out. | ### Positioner Positions the popup against the trigger. Renders a `<div>` element. | Prop | Type | Default | | | --- | --- | --- | --- | | `collisionAvoidance` | `CollisionAvoidance` | `undefined` | | | `align` | `'center' | 'start' | 'end'` | `'center'` | | | `alignOffset` | `number | OffsetFunction` | `0` | | | `side` | `Side` | `'bottom'` | | | `sideOffset` | `number | OffsetFunction` | `0` | | | `arrowPadding` | `number` | `5` | | | `anchor` | `| Element | RefObject<Element | null> | VirtualElement | (() => Element | VirtualElement | null) | null` | `undefined` | | | `collisionBoundary` | `Boundary` | `'clipping-ancestors'` | | | `collisionPadding` | `Padding` | `5` | | | `sticky` | `boolean` | `false` | | | `positionMethod` | `'fixed' | 'absolute'` | `'absolute'` | | | `trackAnchor` | `boolean` | `true` | | | `className` | `| string | ((state: PreviewCard.Positioner.State) => string)` | `undefined` | | | `render` | `| ReactElement | ((props: HTMLProps, state: PreviewCard.Positioner.State) => ReactElement)` | `undefined` | | | Attribute | Description | | | --- | --- | --- | | `data-open` | Present when the preview card is open. | | `data-closed` | Present when the preview card is closed. | | `data-anchor-hidden` | Present when the anchor is hidden. | | `data-align` | Indicates how the popup is aligned relative to specified side. | | `data-side` | Indicates which side the popup is positioned relative to the trigger. | | CSS Variable | Description | | | --- | --- | --- | | `--anchor-height` | The anchor's height. | | `--anchor-width` | The anchor's width. | | `--available-height` | The available height between the trigger and the edge of the viewport. | | `--available-width` | The available width between the trigger and the edge of the viewport. | | `--transform-origin` | The coordinates that this element is anchored to. Used for animations and transitions. | ### Popup A container for the preview card contents. Renders a `<div>` element. | Prop | Type | Default | | | --- | --- | --- | --- | | `className` | `| string | ((state: PreviewCard.Popup.State) => string)` | `undefined` | | | `render` | `| ReactElement | ((props: HTMLProps, state: PreviewCard.Popup.State) => ReactElement)` | `undefined` | | | Attribute | Description | | | --- | --- | --- | | `data-open` | Present when the preview card is open. | | `data-closed` | Present when the preview card is closed. | | `data-align` | Indicates how the popup is aligned relative to specified side. | | `data-side` | Indicates which side the popup is positioned relative to the trigger. | | `data-starting-style` | Present when the preview card is animating in. | | `data-ending-style` | Present when the preview card is animating out. | ### Arrow Displays an element positioned against the preview card anchor. Renders a `<div>` element. | Prop | Type | Default | | | --- | --- | --- | --- | | `className` | `| string | ((state: PreviewCard.Arrow.State) => string)` | `undefined` | | | `render` | `| ReactElement | ((props: HTMLProps, state: PreviewCard.Arrow.State) => ReactElement)` | `undefined` | | | Attribute | Description | | | --- | --- | --- | | `data-open` | Present when the preview card is open. | | `data-closed` | Present when the preview card is closed. | | `data-uncentered` | Present when the preview card arrow is uncentered. | | `data-anchor-hidden` | Present when the anchor is hidden. | | `data-align` | Indicates how the popup is aligned relative to specified side. | | `data-side` | Indicates which side the popup is positioned relative to the trigger. | --- ## Page: https://base-ui.com/react/components/progress Progress * (Top) * Anatomy * API reference * Root * Track * Indicator * Value * Label # Progress Displays the status of a task that takes a long time. Export data100% index.tsxindex.module.csstheme.css CSS Modules CodeSandboxCopy import * as React from 'react'; import { Progress } from '@base-ui-components/react/progress'; import styles from './index.module.css'; export default function ExampleProgress() { const [value, setValue] = React.useState(20); // Simulate changes React.useEffect(() => { const interval = window.setInterval(() => { setValue((current) => Math.min(100, Math.round(current + Math.random() * 25))); }, 1000); return () => clearInterval(interval); }, []); return ( <Progress.Root className={styles.Progress} value={value}> <Progress.Label className={styles.Label}>Export data</Progress.Label> <Progress.Value className={styles.Value} /> <Progress.Track className={styles.Track}> <Progress.Indicator className={styles.Indicator} /> </Progress.Track> </Progress.Root> ); } Show code ## Anatomy Import the component and assemble its parts: Anatomy Copy import { Progress } from '@base-ui-components/react/progress'; <Progress.Root> <Progress.Label /> <Progress.Track> <Progress.Indicator /> </Progress.Track> <Progress.Value /> </Progress.Root> ## API reference ### Root Groups all parts of the progress bar and provides the task completion status to screen readers. Renders a `<div>` element. | Prop | Type | Default | | | --- | --- | --- | --- | | `value*` | `number | null` | `—` | | | `getAriaValueText` | `((formattedValue: string | null, value: number | null) => string)` | `undefined` | | | `locale` | `LocalesArgument` | `undefined` | | | `min` | `number` | `0` | | | `max` | `number` | `100` | | | `format` | `NumberFormatOptions` | `undefined` | | | `className` | `| string | ((state: Progress.Root.State) => string)` | `undefined` | | | `render` | `| ReactElement | ((props: HTMLProps, state: Progress.Root.State) => ReactElement)` | `undefined` | | | Attribute | Description | | | --- | --- | --- | | `data-complete` | Present when the progress has completed. | | `data-indeterminate` | Present when the progress is in interminate state. | | `data-progressing` | Present while the progress is progressing. | ### Track Contains the progress bar indicator. Renders a `<div>` element. | Prop | Type | Default | | | --- | --- | --- | --- | | `className` | `| string | ((state: Progress.Root.State) => string)` | `undefined` | | | `render` | `| ReactElement | ((props: HTMLProps, state: Progress.Root.State) => ReactElement)` | `undefined` | | | Attribute | Description | | | --- | --- | --- | | `data-complete` | Present when the progress has completed. | | `data-indeterminate` | Present when the progress is in interminate state. | | `data-progressing` | Present while the progress is progressing. | ### Indicator Visualizes the completion status of the task. Renders a `<div>` element. | Prop | Type | Default | | | --- | --- | --- | --- | | `className` | `| string | ((state: Progress.Root.State) => string)` | `undefined` | | | `render` | `| ReactElement | ((props: HTMLProps, state: Progress.Root.State) => ReactElement)` | `undefined` | | | Attribute | Description | | | --- | --- | --- | | `data-complete` | Present when the progress has completed. | | `data-indeterminate` | Present when the progress is in interminate state. | | `data-progressing` | Present while the progress is progressing. | ### Value A text label displaying the current value. Renders a `<span>` element. | Prop | Type | Default | | | --- | --- | --- | --- | | `children` | `| ((formattedValue: string | null, value: number | null) => ReactNode) | null` | `undefined` | | | `className` | `| string | ((state: Progress.Root.State) => string)` | `undefined` | | | `render` | `| ReactElement | ((props: HTMLProps, state: Progress.Root.State) => ReactElement)` | `undefined` | | | Attribute | Description | | | --- | --- | --- | | `data-complete` | Present when the progress has completed. | | `data-indeterminate` | Present when the progress is in interminate state. | | `data-progressing` | Present while the progress is progressing. | ### Label An accessible label for the progress bar. Renders a `<span>` element. | Prop | Type | Default | | | --- | --- | --- | --- | | `className` | `| string | ((state: Progress.Root.State) => string)` | `undefined` | | | `render` | `| ReactElement | ((props: HTMLProps, state: Progress.Root.State) => ReactElement)` | `undefined` | | | Attribute | Description | | | --- | --- | --- | | `data-complete` | Present when the progress has completed. | | `data-indeterminate` | Present when the progress is in interminate state. | | `data-progressing` | Present while the progress is progressing. | --- ## Page: https://base-ui.com/react/components/radio Radio * (Top) * Anatomy * API reference * Root * Indicator # Radio An easily stylable radio button component. Best apple FujiGalaGranny Smith index.tsxindex.module.csstheme.css CSS Modules CodeSandboxCopy import * as React from 'react'; import { Radio } from '@base-ui-components/react/radio'; import { RadioGroup } from '@base-ui-components/react/radio-group'; import styles from './index.module.css'; export default function ExampleRadioGroup() { return ( <RadioGroup aria-labelledby="apples-caption" defaultValue="fuji-apple" className={styles.RadioGroup} > <div className={styles.Caption} id="apples-caption"> Best apple </div> <label className={styles.Item}> <Radio.Root value="fuji-apple" className={styles.Radio}> <Radio.Indicator className={styles.Indicator} /> </Radio.Root> Fuji </label> <label className={styles.Item}> <Radio.Root value="gala-apple" className={styles.Radio}> <Radio.Indicator className={styles.Indicator} /> </Radio.Root> Gala </label> <label className={styles.Item}> <Radio.Root value="granny-smith-apple" className={styles.Radio}> <Radio.Indicator className={styles.Indicator} /> </Radio.Root> Granny Smith </label> </RadioGroup> ); } Show code ## Anatomy Radio is always placed within Radio Group. Import the components and place them together: Anatomy Copy import { Radio } from '@base-ui-components/react/radio'; import { RadioGroup } from '@base-ui-components/react/radio-group'; <RadioGroup> <Radio.Root> <Radio.Indicator /> </Radio.Root> </RadioGroup> ## API reference | Prop | Type | Default | | | --- | --- | --- | --- | | `name` | `string` | `undefined` | | | `defaultValue` | `any` | `undefined` | | | `value` | `any` | `undefined` | | | `onValueChange` | `((value: unknown, event: Event) => void)` | `undefined` | | | `disabled` | `boolean` | `false` | | | `readOnly` | `boolean` | `false` | | | `required` | `boolean` | `false` | | | `inputRef` | `Ref<HTMLInputElement>` | `undefined` | | | `className` | `| string | ((state: Radio.Group.State) => string)` | `undefined` | | | `render` | `| ReactElement | ((props: HTMLProps, state: Radio.Group.State) => ReactElement)` | `undefined` | | | Attribute | Description | | | --- | --- | --- | | `data-disabled` | Present when the radio group is disabled. | ### Root Represents the radio button itself. Renders a `<button>` element and a hidden `<input>` beside. | Prop | Type | Default | | | --- | --- | --- | --- | | `value*` | `any` | `—` | | | `disabled` | `boolean` | `false` | | | `readOnly` | `boolean` | `false` | | | `required` | `boolean` | `false` | | | `inputRef` | `Ref<HTMLInputElement>` | `undefined` | | | `className` | `| string | ((state: Radio.Root.State) => string)` | `undefined` | | | `render` | `| ReactElement | ((props: HTMLProps, state: Radio.Root.State) => ReactElement)` | `undefined` | | | Attribute | Description | | | --- | --- | --- | | `data-checked` | Present when the radio is checked. | | `data-unchecked` | Present when the radio is not checked. | | `data-disabled` | Present when the radio is disabled. | | `data-readonly` | Present when the radio is readonly. | | `data-required` | Present when the radio is required. | | `data-valid` | Present when the radio is in valid state (when wrapped in Field.Root). | | `data-invalid` | Present when the radio is in invalid state (when wrapped in Field.Root). | | `data-dirty` | Present when the radio's value has changed (when wrapped in Field.Root). | | `data-touched` | Present when the radio has been touched (when wrapped in Field.Root). | | `data-filled` | Present when the radio is checked (when wrapped in Field.Root). | | `data-focused` | Present when the radio is focused (when wrapped in Field.Root). | ### Indicator Indicates whether the radio button is selected. Renders a `<span>` element. | Prop | Type | Default | | | --- | --- | --- | --- | | `className` | `| string | ((state: Radio.Indicator.State) => string)` | `undefined` | | | `keepMounted` | `boolean` | `false` | | | `render` | `| ReactElement | ((props: HTMLProps, state: Radio.Indicator.State) => ReactElement)` | `undefined` | | | Attribute | Description | | | --- | --- | --- | | `data-checked` | Present when the radio is checked. | | `data-unchecked` | Present when the radio is not checked. | | `data-disabled` | Present when the radio is disabled. | | `data-readonly` | Present when the radio is readonly. | | `data-required` | Present when the radio is required. | | `data-valid` | Present when the radio is in valid state (when wrapped in Field.Root). | | `data-invalid` | Present when the radio is in invalid state (when wrapped in Field.Root). | | `data-dirty` | Present when the radio's value has changed (when wrapped in Field.Root). | | `data-touched` | Present when the radio has been touched (when wrapped in Field.Root). | | `data-filled` | Present when the radio is checked (when wrapped in Field.Root). | | `data-focused` | Present when the radio is focused (when wrapped in Field.Root). | --- ## Page: https://base-ui.com/react/components/scroll-area Scroll Area * (Top) * Anatomy * API reference * Root * Viewport * Content * Scrollbar * Thumb * Corner # Scroll Area A native scroll container with custom scrollbars. Vernacular architecture is building done outside any academic tradition, and without professional guidance. It is not a particular architectural movement or style, but rather a broad category, encompassing a wide range and variety of building types, with differing methods of construction, from around the world, both historical and extant and classical and modern. Vernacular architecture constitutes 95% of the world's built environment, as estimated in 1995 by Amos Rapoport, as measured against the small percentage of new buildings every year designed by architects and built by engineers. This type of architecture usually serves immediate, local needs, is constrained by the materials available in its particular region and reflects local traditions and cultural practices. The study of vernacular architecture does not examine formally schooled architects, but instead that of the design skills and tradition of local builders, who were rarely given any attribution for the work. More recently, vernacular architecture has been examined by designers and the building industry in an effort to be more energy conscious with contemporary design and construction—part of a broader interest in sustainable design. index.tsxindex.module.csstheme.css CSS Modules CodeSandboxCopy import * as React from 'react'; import { ScrollArea } from '@base-ui-components/react/scroll-area'; import styles from './index.module.css'; export default function ExampleScrollArea() { return ( <ScrollArea.Root className={styles.ScrollArea}> <ScrollArea.Viewport className={styles.Viewport}> <ScrollArea.Content className={styles.Content}> <p className={styles.Paragraph}> Vernacular architecture is building done outside any academic tradition, and without professional guidance. It is not a particular architectural movement or style, but rather a broad category, encompassing a wide range and variety of building types, with differing methods of construction, from around the world, both historical and extant and classical and modern. Vernacular architecture constitutes 95% of the world's built environment, as estimated in 1995 by Amos Rapoport, as measured against the small percentage of new buildings every year designed by architects and built by engineers. </p> <p className={styles.Paragraph}> This type of architecture usually serves immediate, local needs, is constrained by the materials available in its particular region and reflects local traditions and cultural practices. The study of vernacular architecture does not examine formally schooled architects, but instead that of the design skills and tradition of local builders, who were rarely given any attribution for the work. More recently, vernacular architecture has been examined by designers and the building industry in an effort to be more energy conscious with contemporary design and construction—part of a broader interest in sustainable design. </p> </ScrollArea.Content> </ScrollArea.Viewport> <ScrollArea.Scrollbar className={styles.Scrollbar}> <ScrollArea.Thumb className={styles.Thumb} /> </ScrollArea.Scrollbar> </ScrollArea.Root> ); } Show code ## Anatomy Import the component and assemble its parts: Anatomy Copy import { ScrollArea } from '@base-ui-components/react/scroll-area'; <ScrollArea.Root> <ScrollArea.Viewport /> <ScrollArea.Scrollbar> <ScrollArea.Thumb /> </ScrollArea.Scrollbar> <ScrollArea.Corner /> </ScrollArea.Root> ## API reference ### Root Groups all parts of the scroll area. Renders a `<div>` element. | Prop | Type | Default | | | --- | --- | --- | --- | | `className` | `| string | ((state: ScrollArea.Root.State) => string)` | `undefined` | | | `render` | `| ReactElement | ((props: HTMLProps, state: ScrollArea.Root.State) => ReactElement)` | `undefined` | | | CSS Variable | Description | | | --- | --- | --- | | `--scroll-area-corner-height` | The scroll area's corner height. | | `--scroll-area-corner-width` | The scroll area's corner width. | ### Viewport The actual scrollable container of the scroll area. Renders a `<div>` element. | Prop | Type | Default | | | --- | --- | --- | --- | | `className` | `| string | ((state: ScrollArea.Viewport.State) => string)` | `undefined` | | | `render` | `| ReactElement | ((props: HTMLProps, state: ScrollArea.Viewport.State) => ReactElement)` | `undefined` | | ### Content A container for the content of the scroll area. Renders a `<div>` element. | Prop | Type | Default | | | --- | --- | --- | --- | | `className` | `| string | ((state: ScrollArea.Content.State) => string)` | `undefined` | | | `render` | `| ReactElement | ((props: HTMLProps, state: ScrollArea.Content.State) => ReactElement)` | `undefined` | | ### Scrollbar A vertical or horizontal scrollbar for the scroll area. Renders a `<div>` element. | Prop | Type | Default | | | --- | --- | --- | --- | | `orientation` | `'horizontal' | 'vertical'` | `'vertical'` | | | `className` | `| string | ((state: ScrollArea.Scrollbar.State) => string)` | `undefined` | | | `keepMounted` | `boolean` | `false` | | | `render` | `| ReactElement | ((props: HTMLProps, state: ScrollArea.Scrollbar.State) => ReactElement)` | `undefined` | | | Attribute | Description | | | --- | --- | --- | | `data-orientation` | Indicates the orientation of the scrollbar. | | `data-hovering` | Present when the pointer is over the scroll area. | | `data-scrolling` | Present when the users scrolls inside the scroll area. | | CSS Variable | Description | | | --- | --- | --- | | `--scroll-area-thumb-height` | The scroll area thumb's height. | | `--scroll-area-thumb-width` | The scroll area thumb's width. | ### Thumb The draggable part of the the scrollbar that indicates the current scroll position. Renders a `<div>` element. | Prop | Type | Default | | | --- | --- | --- | --- | | `className` | `| string | ((state: ScrollArea.Thumb.State) => string)` | `undefined` | | | `render` | `| ReactElement | ((props: HTMLProps, state: ScrollArea.Thumb.State) => ReactElement)` | `undefined` | | | Attribute | Description | | | --- | --- | --- | | `data-orientation` | Indicates the orientation of the scrollbar. | ### Corner A small rectangular area that appears at the intersection of horizontal and vertical scrollbars. Renders a `<div>` element. | Prop | Type | Default | | | --- | --- | --- | --- | | `className` | `| string | ((state: ScrollArea.Corner.State) => string)` | `undefined` | | | `render` | `| ReactElement | ((props: HTMLProps, state: ScrollArea.Corner.State) => ReactElement)` | `undefined` | | --- ## Page: https://base-ui.com/react/components/select Select * (Top) * Anatomy * API reference * Root * Trigger * Value * Icon * Backdrop * Portal * Positioner * Popup * Arrow * Item * ItemText * ItemIndicator * Group * GroupLabel * ScrollUpArrow * ScrollDownArrow * Separator # Select A common form component for choosing a predefined value in a dropdown menu. Sans-serif index.tsxindex.module.csstheme.css CSS Modules CodeSandboxCopy import * as React from 'react'; import { Select } from '@base-ui-components/react/select'; import styles from './index.module.css'; export default function ExampleSelect() { return ( <Select.Root defaultValue="sans"> <Select.Trigger className={styles.Select}> <Select.Value placeholder="Sans-serif" /> <Select.Icon className={styles.SelectIcon}> <ChevronUpDownIcon /> </Select.Icon> </Select.Trigger> <Select.Portal> <Select.Positioner className={styles.Positioner} sideOffset={8}> <Select.ScrollUpArrow className={styles.ScrollArrow} /> <Select.Popup className={styles.Popup}> <Select.Item className={styles.Item} value="sans"> <Select.ItemIndicator className={styles.ItemIndicator}> <CheckIcon className={styles.ItemIndicatorIcon} /> </Select.ItemIndicator> <Select.ItemText className={styles.ItemText}> Sans-serif </Select.ItemText> </Select.Item> <Select.Item className={styles.Item} value="serif"> <Select.ItemIndicator className={styles.ItemIndicator}> <CheckIcon className={styles.ItemIndicatorIcon} /> </Select.ItemIndicator> <Select.ItemText className={styles.ItemText}>Serif</Select.ItemText> </Select.Item> <Select.Item className={styles.Item} value="mono"> <Select.ItemIndicator className={styles.ItemIndicator}> <CheckIcon className={styles.ItemIndicatorIcon} /> </Select.ItemIndicator> <Select.ItemText className={styles.ItemText}> Monospace </Select.ItemText> </Select.Item> <Select.Item className={styles.Item} value="cursive"> <Select.ItemIndicator className={styles.ItemIndicator}> <CheckIcon className={styles.ItemIndicatorIcon} /> </Select.ItemIndicator> <Select.ItemText className={styles.ItemText}>Cursive</Select.ItemText> </Select.Item> </Select.Popup> <Select.ScrollDownArrow className={styles.ScrollArrow} /> </Select.Positioner> </Select.Portal> </Select.Root> ); } function ChevronUpDownIcon(props: React.ComponentProps<'svg'>) { return ( <svg width="8" height="12" viewBox="0 0 8 12" fill="none" stroke="currentcolor" strokeWidth="1.5" {...props} > <path d="M0.5 4.5L4 1.5L7.5 4.5" /> <path d="M0.5 7.5L4 10.5L7.5 7.5" /> </svg> ); } function CheckIcon(props: React.ComponentProps<'svg'>) { return ( <svg fill="currentcolor" width="10" height="10" viewBox="0 0 10 10" {...props}> <path d="M9.1603 1.12218C9.50684 1.34873 9.60427 1.81354 9.37792 2.16038L5.13603 8.66012C5.01614 8.8438 4.82192 8.96576 4.60451 8.99384C4.3871 9.02194 4.1683 8.95335 4.00574 8.80615L1.24664 6.30769C0.939709 6.02975 0.916013 5.55541 1.19372 5.24822C1.47142 4.94102 1.94536 4.91731 2.2523 5.19524L4.36085 7.10461L8.12299 1.33999C8.34934 0.993152 8.81376 0.895638 9.1603 1.12218Z" /> </svg> ); } Show code ## Anatomy Import the component and assemble its parts: Anatomy Copy import { Select } from '@base-ui-components/react/select'; <Select.Root> <Select.Trigger> <Select.Value /> <Select.Icon /> </Select.Trigger> <Select.Portal> <Select.Backdrop /> <Select.Positioner> <Select.ScrollUpArrow /> <Select.Popup> <Select.Arrow /> <Select.Item> <Select.ItemText /> <Select.ItemIndicator /> </Select.Item> <Select.Separator /> <Select.Group> <Select.GroupLabel /> </Select.Group> </Select.Popup> <Select.ScrollDownArrow /> </Select.Positioner> </Select.Portal> </Select.Root> ## API reference ### Root Groups all parts of the select. Doesn’t render its own HTML element. | Prop | Type | Default | | | --- | --- | --- | --- | | `name` | `string` | `undefined` | | | `defaultValue` | `Value | null` | `null` | | | `value` | `Value | null` | `undefined` | | | `onValueChange` | `((value: Value, event: Event | undefined) => void)` | `undefined` | | | `defaultOpen` | `boolean` | `false` | | | `open` | `boolean` | `undefined` | | | `onOpenChange` | `(open: boolean, event?: Event, reason?: Select.Root.OpenChangeReason) => void` | `undefined` | | | `actionsRef` | `RefObject<Actions>` | `undefined` | | | `modal` | `boolean` | `true` | | | `onOpenChangeComplete` | `((open: boolean) => void)` | `undefined` | | | `disabled` | `boolean` | `false` | | | `readOnly` | `boolean` | `false` | | | `required` | `boolean` | `false` | | | `inputRef` | `Ref<HTMLInputElement>` | `undefined` | | | `id` | `string` | `undefined` | | | `children` | `ReactNode` | `undefined` | | ### Trigger A button that opens the select menu. Renders a `<div>` element. | Prop | Type | Default | | | --- | --- | --- | --- | | `disabled` | `boolean` | `false` | | | `children` | `ReactNode` | `undefined` | | | `className` | `| string | ((state: Select.Trigger.State) => string)` | `undefined` | | | `render` | `| ReactElement | ((props: HTMLProps, state: Select.Trigger.State) => ReactElement)` | `undefined` | | | Attribute | Description | | | --- | --- | --- | | `data-popup-open` | Present when the corresponding select is open. | | `data-pressed` | Present when the trigger is pressed. | | `data-disabled` | Present when the select is disabled. | | `data-readonly` | Present when the select is readonly. | | `data-required` | Present when the select is required. | | `data-valid` | Present when the select is in valid state (when wrapped in Field.Root). | | `data-invalid` | Present when the select is in invalid state (when wrapped in Field.Root). | | `data-dirty` | Present when the select's value has changed (when wrapped in Field.Root). | | `data-touched` | Present when the select has been touched (when wrapped in Field.Root). | | `data-filled` | Present when the select has a value (when wrapped in Field.Root). | | `data-focused` | Present when the select trigger is focused (when wrapped in Field.Root). | ### Value A text label of the currently selected item. Renders a `<span>` element. | Prop | Type | Default | | | --- | --- | --- | --- | | `placeholder*` | `ReactNode` | `—` | | | `children` | `| ((label: ReactNode, value: any) => ReactNode) | null` | `undefined` | | | `className` | `| string | ((state: Select.Value.State) => string)` | `undefined` | | | `render` | `| ReactElement | ((props: HTMLProps, state: Select.Value.State) => ReactElement)` | `undefined` | | ### Icon An icon that indicates that the trigger button opens a select menu. Renders a `<span>` element. | Prop | Type | Default | | | --- | --- | --- | --- | | `className` | `| string | ((state: Select.Icon.State) => string)` | `undefined` | | | `render` | `| ReactElement | ((props: HTMLProps, state: Select.Icon.State) => ReactElement)` | `undefined` | | ### Backdrop An overlay displayed beneath the menu popup. Renders a `<div>` element. | Prop | Type | Default | | | --- | --- | --- | --- | | `className` | `| string | ((state: Select.Backdrop.State) => string)` | `undefined` | | | `render` | `| ReactElement | ((props: HTMLProps, state: Select.Backdrop.State) => ReactElement)` | `undefined` | | | Attribute | Description | | | --- | --- | --- | | `data-open` | Present when the select is open. | | `data-closed` | Present when the select is closed. | | `data-starting-style` | Present when the select is animating in. | | `data-ending-style` | Present when the select is animating out. | ### Portal A portal element that moves the popup to a different part of the DOM. By default, the portal element is appended to `<body>`. | Prop | Type | Default | | | --- | --- | --- | --- | | `container` | `| HTMLElement | RefObject<HTMLElement | null> | null` | `undefined` | | | `children` | `ReactNode` | `undefined` | | ### Positioner Positions the select menu popup. Renders a `<div>` element. | Prop | Type | Default | | | --- | --- | --- | --- | | `alignItemWithTrigger` | `boolean` | `true` | | | `collisionAvoidance` | `CollisionAvoidance` | `undefined` | | | `align` | `'center' | 'start' | 'end'` | `'center'` | | | `alignOffset` | `number | OffsetFunction` | `0` | | | `side` | `Side` | `'bottom'` | | | `sideOffset` | `number | OffsetFunction` | `0` | | | `arrowPadding` | `number` | `5` | | | `anchor` | `| Element | RefObject<Element | null> | VirtualElement | (() => Element | VirtualElement | null) | null` | `undefined` | | | `collisionBoundary` | `Boundary` | `'clipping-ancestors'` | | | `collisionPadding` | `Padding` | `5` | | | `sticky` | `boolean` | `false` | | | `positionMethod` | `'fixed' | 'absolute'` | `'absolute'` | | | `trackAnchor` | `boolean` | `true` | | | `className` | `| string | ((state: Select.Positioner.State) => string)` | `undefined` | | | `render` | `| ReactElement | ((props: HTMLProps, state: Select.Positioner.State) => ReactElement)` | `undefined` | | | Attribute | Description | | | --- | --- | --- | | `data-open` | Present when the select popup is open. | | `data-closed` | Present when the select popup is closed. | | `data-anchor-hidden` | Present when the anchor is hidden. | | `data-align` | Indicates how the popup is aligned relative to specified side. | | `data-side` | Indicates which side the popup is positioned relative to the trigger. | | CSS Variable | Description | | | --- | --- | --- | | `--anchor-height` | The anchor's height. | | `--anchor-width` | The anchor's width. | | `--available-height` | The available height between the trigger and the edge of the viewport. | | `--available-width` | The available width between the trigger and the edge of the viewport. | | `--transform-origin` | The coordinates that this element is anchored to. Used for animations and transitions. | ### Popup A container for the select items. Renders a `<div>` element. | Prop | Type | Default | | | --- | --- | --- | --- | | `id` | `string` | `undefined` | | | `children` | `ReactNode` | `undefined` | | | `className` | `| string | ((state: Select.Popup.State) => string)` | `undefined` | | | `render` | `| ReactElement | ((props: HTMLProps, state: Select.Popup.State) => ReactElement)` | `undefined` | | | Attribute | Description | | | --- | --- | --- | | `data-open` | Present when the select is open. | | `data-closed` | Present when the select is closed. | | `data-align` | Indicates how the popup is aligned relative to specified side. | | `data-side` | Indicates which side the popup is positioned relative to the trigger. | | `data-starting-style` | Present when the select is animating in. | | `data-ending-style` | Present when the select is animating out. | ### Arrow Displays an element positioned against the select menu anchor. Renders a `<div>` element. | Prop | Type | Default | | | --- | --- | --- | --- | | `className` | `| string | ((state: Select.Arrow.State) => string)` | `undefined` | | | `render` | `| ReactElement | ((props: HTMLProps, state: Select.Arrow.State) => ReactElement)` | `undefined` | | | Attribute | Description | | | --- | --- | --- | | `data-open` | Present when the select popup is open. | | `data-closed` | Present when the select popup is closed. | | `data-uncentered` | Present when the select arrow is uncentered. | | `data-anchor-hidden` | Present when the anchor is hidden. | | `data-align` | Indicates how the popup is aligned relative to specified side. | | `data-side` | Indicates which side the popup is positioned relative to the trigger. | ### Item An individual option in the select menu. Renders a `<div>` element. | Prop | Type | Default | | | --- | --- | --- | --- | | `label` | `string` | `undefined` | | | `value` | `any` | `null` | | | `disabled` | `boolean` | `false` | | | `children` | `ReactNode` | `undefined` | | | `className` | `| string | ((state: Select.Item.State) => string)` | `undefined` | | | `render` | `| ReactElement | ((props: HTMLProps, state: Select.Item.State) => ReactElement)` | `undefined` | | | Attribute | Description | | | --- | --- | --- | | `data-selected` | Present when the select item is selected. | | `data-highlighted` | Present when the select item is highlighted. | | `data-disabled` | Present when the select item is disabled. | ### ItemText A text label of the select item. Renders a `<div>` element. | Prop | Type | Default | | | --- | --- | --- | --- | | `className` | `| string | ((state: Select.ItemText.State) => string)` | `undefined` | | | `render` | `| ReactElement | ((props: HTMLProps, state: Select.ItemText.State) => ReactElement)` | `undefined` | | ### ItemIndicator Indicates whether the select item is selected. Renders a `<span>` element. | Prop | Type | Default | | | --- | --- | --- | --- | | `children` | `ReactNode` | `undefined` | | | `className` | `| string | ((state: Select.ItemIndicator.State) => string)` | `undefined` | | | `keepMounted` | `boolean` | `false` | | | `render` | `| ReactElement | ((props: HTMLProps, state: Select.ItemIndicator.State) => ReactElement)` | `undefined` | | ### Group Groups related select items with the corresponding label. Renders a `<div>` element. | Prop | Type | Default | | | --- | --- | --- | --- | | `className` | `| string | ((state: Select.Group.State) => string)` | `undefined` | | | `render` | `| ReactElement | ((props: HTMLProps, state: Select.Group.State) => ReactElement)` | `undefined` | | ### GroupLabel An accessible label that is automatically associated with its parent group. Renders a `<div>` element. | Prop | Type | Default | | | --- | --- | --- | --- | | `className` | `| string | ((state: Select.GroupLabel.State) => string)` | `undefined` | | | `render` | `| ReactElement | ((props: HTMLProps, state: Select.GroupLabel.State) => ReactElement)` | `undefined` | | ### ScrollUpArrow An element that scrolls the select menu up when hovered. Renders a `<div>` element. | Prop | Type | Default | | | --- | --- | --- | --- | | `className` | `| string | ((state: Select.ScrollUpArrow.State) => string)` | `undefined` | | | `keepMounted` | `boolean` | `false` | | | `render` | `| ReactElement | ((props: HTMLProps, state: Select.ScrollUpArrow.State) => ReactElement)` | `undefined` | | | Attribute | Description | | | --- | --- | --- | | `data-direction` | Indicates the direction of the scroll arrow. | | `data-side` | Indicates which side the popup is positioned relative to the trigger. | | `data-visible` | Present when the scroll arrow is visible. | | `data-starting-style` | Present when the scroll arrow is animating in. | | `data-ending-style` | Present when the scroll arrow is animating out. | ### ScrollDownArrow An element that scrolls the select menu down when hovered. Renders a `<div>` element. | Prop | Type | Default | | | --- | --- | --- | --- | | `className` | `| string | ((state: Select.ScrollDownArrow.State) => string)` | `undefined` | | | `keepMounted` | `boolean` | `false` | | | `render` | `| ReactElement | ((props: HTMLProps, state: Select.ScrollDownArrow.State) => ReactElement)` | `undefined` | | | Attribute | Description | | | --- | --- | --- | | `data-direction` | Indicates the direction of the scroll arrow. | | `data-side` | Indicates which side the popup is positioned relative to the trigger. | | `data-visible` | Present when the scroll arrow is visible. | | `data-starting-style` | Present when the scroll arrow is animating in. | | `data-ending-style` | Present when the scroll arrow is animating out. | ### Separator A separator element accessible to screen readers. Renders a `<div>` element. | Prop | Type | Default | | | --- | --- | --- | --- | | `orientation` | `Orientation` | `'horizontal'` | | | `className` | `| string | ((state: Separator.State) => string)` | `undefined` | | | `render` | `| ReactElement | ((props: HTMLProps, state: Separator.State) => ReactElement)` | `undefined` | | --- ## Page: https://base-ui.com/react/components/separator Separator * (Top) * Anatomy * API reference # Separator A separator element accessible to screen readers. HomePricingBlogSupport Log inSign up index.tsxindex.module.csstheme.css CSS Modules CodeSandboxCopy import * as React from 'react'; import { Separator } from '@base-ui-components/react/separator'; import styles from './index.module.css'; export default function ExampleSeparator() { return ( <div className={styles.Container}> <a href="#" className={styles.Link}> Home </a> <a href="#" className={styles.Link}> Pricing </a> <a href="#" className={styles.Link}> Blog </a> <a href="#" className={styles.Link}> Support </a> <Separator orientation="vertical" className={styles.Separator} /> <a href="#" className={styles.Link}> Log in </a> <a href="#" className={styles.Link}> Sign up </a> </div> ); } Show code ## Anatomy Import the component and use it as a single part: Anatomy Copy import { Separator } from '@base-ui-components/react/separator'; <Separator /> ## API reference | Prop | Type | Default | | | --- | --- | --- | --- | | `orientation` | `Orientation` | `'horizontal'` | | | `className` | `| string | ((state: Separator.State) => string)` | `undefined` | | | `render` | `| ReactElement | ((props: HTMLProps, state: Separator.State) => ReactElement)` | `undefined` | | --- ## Page: https://base-ui.com/react/components/slider Slider * (Top) * Anatomy * API reference * Root * Value * Control * Track * Indicator * Thumb * Examples * Range slider # Slider An easily stylable range input. index.tsxindex.module.csstheme.css CSS Modules CodeSandboxCopy import * as React from 'react'; import { Slider } from '@base-ui-components/react/slider'; import styles from './index.module.css'; export default function ExampleSlider() { return ( <Slider.Root defaultValue={25}> <Slider.Control className={styles.Control}> <Slider.Track className={styles.Track}> <Slider.Indicator className={styles.Indicator} /> <Slider.Thumb className={styles.Thumb} /> </Slider.Track> </Slider.Control> </Slider.Root> ); } Show code ## Anatomy Import the component and assemble its parts: Anatomy Copy import { Slider } from '@base-ui-components/react/slider'; <Slider.Root> <Slider.Value /> <Slider.Control> <Slider.Track> <Slider.Indicator /> <Slider.Thumb /> </Slider.Track> </Slider.Control> </Slider.Root> ## API reference ### Root Groups all parts of the slider. Renders a `<div>` element. | Prop | Type | Default | | | --- | --- | --- | --- | | `name` | `string` | `undefined` | | | `defaultValue` | `number | readonly number[]` | `undefined` | | | `value` | `number | readonly number[]` | `undefined` | | | `onValueChange` | `((value: (number | number[]), event: Event, activeThumbIndex: number) => void)` | `undefined` | | | `onValueCommitted` | `((value: (number | number[]), event: Event) => void)` | `undefined` | | | `locale` | `LocalesArgument` | `undefined` | | | `ref` | `RefObject<HTMLDivElement>` | `undefined` | | | `tabIndex` | `number` | `undefined` | | | `step` | `number` | `1` | | | `largeStep` | `number` | `10` | | | `minStepsBetweenValues` | `number` | `0` | | | `min` | `number` | `0` | | | `max` | `number` | `100` | | | `format` | `NumberFormatOptions` | `undefined` | | | `disabled` | `boolean` | `false` | | | `orientation` | `Orientation` | `'horizontal'` | | | `inputRef` | `Ref<HTMLInputElement>` | `undefined` | | | `className` | `| string | ((state: Slider.Root.State) => string)` | `undefined` | | | `render` | `| ReactElement | ((props: HTMLProps, state: Slider.Root.State) => ReactElement)` | `undefined` | | | Attribute | Description | | | --- | --- | --- | | `data-dragging` | Present while the user is dragging. | | `data-orientation` | Indicates the orientation of the slider. | | `data-disabled` | Present when the slider is disabled. | | `data-readonly` | Present when the slider is readonly. | | `data-required` | Present when the slider is required. | | `data-valid` | Present when the slider is in valid state (when wrapped in Field.Root). | | `data-invalid` | Present when the slider is in invalid state (when wrapped in Field.Root). | | `data-dirty` | Present when the slider's value has changed (when wrapped in Field.Root). | | `data-touched` | Present when the slider has been touched (when wrapped in Field.Root). | | `data-focused` | Present when the slider is focused (when wrapped in Field.Root). | ### Value Displays the current value of the slider as text. Renders an `<output>` element. | Prop | Type | Default | | | --- | --- | --- | --- | | `children` | `| ((formattedValues: string[], values: number[]) => ReactNode) | null` | `undefined` | | | `className` | `| string | ((state: Slider.Root.State) => string)` | `undefined` | | | `render` | `| ReactElement | ((props: HTMLProps, state: Slider.Root.State) => ReactElement)` | `undefined` | | | Attribute | Description | | | --- | --- | --- | | `data-dragging` | Present while the user is dragging. | | `data-orientation` | Indicates the orientation of the slider. | | `data-disabled` | Present when the slider is disabled. | | `data-readonly` | Present when the slider is readonly. | | `data-required` | Present when the slider is required. | | `data-valid` | Present when the slider is in valid state (when wrapped in Field.Root). | | `data-invalid` | Present when the slider is in invalid state (when wrapped in Field.Root). | | `data-dirty` | Present when the slider's value has changed (when wrapped in Field.Root). | | `data-touched` | Present when the slider has been touched (when wrapped in Field.Root). | | `data-focused` | Present when the slider is focused (when wrapped in Field.Root). | ### Control The clickable, interactive part of the slider. Renders a `<div>` element. | Prop | Type | Default | | | --- | --- | --- | --- | | `className` | `| string | ((state: Slider.Root.State) => string)` | `undefined` | | | `render` | `| ReactElement | ((props: HTMLProps, state: Slider.Root.State) => ReactElement)` | `undefined` | | | Attribute | Description | | | --- | --- | --- | | `data-dragging` | Present while the user is dragging. | | `data-orientation` | Indicates the orientation of the slider. | | `data-disabled` | Present when the slider is disabled. | | `data-readonly` | Present when the slider is readonly. | | `data-required` | Present when the slider is required. | | `data-valid` | Present when the slider is in valid state (when wrapped in Field.Root). | | `data-invalid` | Present when the slider is in invalid state (when wrapped in Field.Root). | | `data-dirty` | Present when the slider's value has changed (when wrapped in Field.Root). | | `data-touched` | Present when the slider has been touched (when wrapped in Field.Root). | | `data-focused` | Present when the slider is focused (when wrapped in Field.Root). | ### Track Contains the slider indicator and represents the entire range of the slider. Renders a `<div>` element. | Prop | Type | Default | | | --- | --- | --- | --- | | `className` | `| string | ((state: Slider.Root.State) => string)` | `undefined` | | | `render` | `| ReactElement | ((props: HTMLProps, state: Slider.Root.State) => ReactElement)` | `undefined` | | | Attribute | Description | | | --- | --- | --- | | `data-dragging` | Present while the user is dragging. | | `data-orientation` | Indicates the orientation of the slider. | | `data-disabled` | Present when the slider is disabled. | | `data-readonly` | Present when the slider is readonly. | | `data-required` | Present when the slider is required. | | `data-valid` | Present when the slider is in valid state (when wrapped in Field.Root). | | `data-invalid` | Present when the slider is in invalid state (when wrapped in Field.Root). | | `data-dirty` | Present when the slider's value has changed (when wrapped in Field.Root). | | `data-touched` | Present when the slider has been touched (when wrapped in Field.Root). | | `data-focused` | Present when the slider is focused (when wrapped in Field.Root). | ### Indicator Visualizes the current value of the slider. Renders a `<div>` element. | Prop | Type | Default | | | --- | --- | --- | --- | | `className` | `| string | ((state: Slider.Root.State) => string)` | `undefined` | | | `render` | `| ReactElement | ((props: HTMLProps, state: Slider.Root.State) => ReactElement)` | `undefined` | | | Attribute | Description | | | --- | --- | --- | | `data-dragging` | Present while the user is dragging. | | `data-orientation` | Indicates the orientation of the slider. | | `data-disabled` | Present when the slider is disabled. | | `data-readonly` | Present when the slider is readonly. | | `data-required` | Present when the slider is required. | | `data-valid` | Present when the slider is in valid state (when wrapped in Field.Root). | | `data-invalid` | Present when the slider is in invalid state (when wrapped in Field.Root). | | `data-dirty` | Present when the slider's value has changed (when wrapped in Field.Root). | | `data-touched` | Present when the slider has been touched (when wrapped in Field.Root). | | `data-focused` | Present when the slider is focused (when wrapped in Field.Root). | ### Thumb The draggable part of the the slider at the tip of the indicator. Renders a `<div>` element. | Prop | Type | Default | | | --- | --- | --- | --- | | `getAriaLabel` | `((index: number) => string) | null` | `undefined` | | | `getAriaValueText` | `| ((formattedValue: string, value: number, index: number) => string) | null` | `undefined` | | | `disabled` | `boolean` | `false` | | | `className` | `| string | ((state: Slider.Thumb.State) => string)` | `undefined` | | | `render` | `| ((props: DetailedHTMLProps<HTMLAttributes<HTMLDivElement>, HTMLDivElement>, inputProps: DetailedHTMLProps<InputHTMLAttributes<HTMLInputElement>, HTMLInputElement>, state: Slider.Thumb.State) => ReactElement) | ReactElement & { ref: Ref<Element> }` | `undefined` | | | Attribute | Description | | | --- | --- | --- | | `data-dragging` | Present while the user is dragging. | | `data-orientation` | Indicates the orientation of the slider. | | `data-disabled` | Present when the slider is disabled. | | `data-readonly` | Present when the slider is readonly. | | `data-required` | Present when the slider is required. | | `data-valid` | Present when the slider is in valid state (when wrapped in Field.Root). | | `data-invalid` | Present when the slider is in invalid state (when wrapped in Field.Root). | | `data-dirty` | Present when the slider's value has changed (when wrapped in Field.Root). | | `data-touched` | Present when the slider has been touched (when wrapped in Field.Root). | | `data-focused` | Present when the slider is focused (when wrapped in Field.Root). | | `data-index` | Indicates the index of the thumb in range sliders. | ## Examples ### Range slider To create a range slider, provide an array of values with corresponding thumbs: Show code --- ## Page: https://base-ui.com/react/components/switch Switch * (Top) * Anatomy * API reference * Root * Thumb # Switch A control that indicates whether a setting is on or off. index.tsxindex.module.csstheme.css CSS Modules CodeSandboxCopy import * as React from 'react'; import { Switch } from '@base-ui-components/react/switch'; import styles from './index.module.css'; export default function ExampleSwitch() { return ( <Switch.Root defaultChecked className={styles.Switch}> <Switch.Thumb className={styles.Thumb} /> </Switch.Root> ); } ## Anatomy Import the component and assemble its parts: Anatomy Copy import { Switch } from '@base-ui-components/react/switch'; <Switch.Root> <Switch.Thumb /> </Switch.Root> ## API reference ### Root Represents the switch itself. Renders a `<button>` element and a hidden `<input>` beside. | Prop | Type | Default | | | --- | --- | --- | --- | | `name` | `string` | `undefined` | | | `defaultChecked` | `boolean` | `false` | | | `checked` | `boolean` | `undefined` | | | `onCheckedChange` | `((checked: boolean, event: Event) => void)` | `undefined` | | | `disabled` | `boolean` | `false` | | | `readOnly` | `boolean` | `false` | | | `required` | `boolean` | `false` | | | `inputRef` | `Ref<HTMLInputElement>` | `undefined` | | | `id` | `string` | `undefined` | | | `className` | `| string | ((state: Switch.Root.State) => string)` | `undefined` | | | `render` | `| ReactElement | ((props: HTMLProps, state: Switch.Root.State) => ReactElement)` | `undefined` | | | Attribute | Description | | | --- | --- | --- | | `data-checked` | Present when the switch is checked. | | `data-unchecked` | Present when the switch is not checked. | | `data-disabled` | Present when the switch is disabled. | | `data-readonly` | Present when the switch is readonly. | | `data-required` | Present when the switch is required. | | `data-valid` | Present when the switch is in valid state (when wrapped in Field.Root). | | `data-invalid` | Present when the switch is in invalid state (when wrapped in Field.Root). | | `data-dirty` | Present when the switch's value has changed (when wrapped in Field.Root). | | `data-touched` | Present when the switch has been touched (when wrapped in Field.Root). | | `data-filled` | Present when the switch is active (when wrapped in Field.Root). | | `data-focused` | Present when the switch is focused (when wrapped in Field.Root). | ### Thumb The movable part of the switch that indicates whether the switch is on or off. Renders a `<span>`. | Prop | Type | Default | | | --- | --- | --- | --- | | `className` | `| string | ((state: Switch.Thumb.State) => string)` | `undefined` | | | `render` | `| ReactElement | ((props: HTMLProps, state: Switch.Thumb.State) => ReactElement)` | `undefined` | | | Attribute | Description | | | --- | --- | --- | | `data-checked` | Present when the switch is checked. | | `data-unchecked` | Present when the switch is not checked. | | `data-disabled` | Present when the switch is disabled. | | `data-readonly` | Present when the switch is readonly. | | `data-required` | Present when the switch is required. | | `data-valid` | Present when the switch is in valid state (when wrapped in Field.Root). | | `data-invalid` | Present when the switch is in invalid state (when wrapped in Field.Root). | | `data-dirty` | Present when the switch's value has changed (when wrapped in Field.Root). | | `data-touched` | Present when the switch has been touched (when wrapped in Field.Root). | | `data-filled` | Present when the switch is active (when wrapped in Field.Root). | | `data-focused` | Present when the switch is focused (when wrapped in Field.Root). | --- ## Page: https://base-ui.com/react/components/tabs Tabs * (Top) * Anatomy * API reference * Root * List * Tab * Indicator * Panel # Tabs A component for toggling between related panels on the same page. OverviewProjectsAccount index.tsxindex.module.csstheme.css CSS Modules CodeSandboxCopy import * as React from 'react'; import { Tabs } from '@base-ui-components/react/tabs'; import styles from './index.module.css'; export default function ExampleTabs() { return ( <Tabs.Root className={styles.Tabs} defaultValue="overview"> <Tabs.List className={styles.List}> <Tabs.Tab className={styles.Tab} value="overview"> Overview </Tabs.Tab> <Tabs.Tab className={styles.Tab} value="projects"> Projects </Tabs.Tab> <Tabs.Tab className={styles.Tab} value="account"> Account </Tabs.Tab> <Tabs.Indicator className={styles.Indicator} /> </Tabs.List> <Tabs.Panel className={styles.Panel} value="overview"> <OverviewIcon className={styles.Icon} /> </Tabs.Panel> <Tabs.Panel className={styles.Panel} value="projects"> <ProjectIcon className={styles.Icon} /> </Tabs.Panel> <Tabs.Panel className={styles.Panel} value="account"> <PersonIcon className={styles.Icon} /> </Tabs.Panel> </Tabs.Root> ); } function OverviewIcon(props: React.ComponentProps<'svg'>) { return ( <svg width="40" height="40" viewBox="0 0 30 30" fill="currentcolor" {...props}> <path d="M 6 4 C 4.895 4 4 4.895 4 6 L 4 12 C 4 13.105 4.895 14 6 14 L 12 14 C 13.105 14 14 13.105 14 12 L 14 6 C 14 4.895 13.105 4 12 4 L 6 4 z M 18 4 C 16.895 4 16 4.895 16 6 L 16 12 C 16 13.105 16.895 14 18 14 L 24 14 C 25.105 14 26 13.105 26 12 L 26 6 C 26 4.895 25.105 4 24 4 L 18 4 z M 9 6 C 10.657 6 12 7.343 12 9 C 12 10.657 10.657 12 9 12 C 7.343 12 6 10.657 6 9 C 6 7.343 7.343 6 9 6 z M 18 6 L 24 6 L 24 12 L 18 12 L 18 6 z M 6 16 C 4.895 16 4 16.895 4 18 L 4 24 C 4 25.105 4.895 26 6 26 L 12 26 C 13.105 26 14 25.105 14 24 L 14 18 C 14 16.895 13.105 16 12 16 L 6 16 z M 18 16 C 16.895 16 16 16.895 16 18 L 16 24 C 16 25.105 16.895 26 18 26 L 24 26 C 25.105 26 26 25.105 26 24 L 26 18 C 26 16.895 25.105 16 24 16 L 18 16 z M 21 17.5 L 24.5 21 L 21 24.5 L 17.5 21 L 21 17.5 z M 9 18 L 11.886719 23 L 6.1132812 23 L 9 18 z" /> </svg> ); } function ProjectIcon(props: React.ComponentProps<'svg'>) { return ( <svg width="40" height="40" viewBox="0 0 30 30" fill="currentcolor" {...props}> <path d="M 14.984375 1.9863281 A 1.0001 1.0001 0 0 0 14 3 L 14 4 L 5 4 L 4 4 A 1.0001 1.0001 0 1 0 3.9804688 6 C 3.9348612 9.0608831 3.6893807 11.887023 3.1523438 14.142578 C 2.5565033 16.645108 1.6039585 18.395538 0.4453125 19.167969 A 1.0001 1.0001 0 0 0 1 21 L 4 21 C 4 22.105 4.895 23 6 23 L 11.787109 23 L 10.148438 26.042969 A 1.5 1.5 0 0 0 9 27.5 A 1.5 1.5 0 0 0 10.5 29 A 1.5 1.5 0 0 0 12 27.5 A 1.5 1.5 0 0 0 11.910156 26.992188 L 14.060547 23 L 15.939453 23 L 18.089844 26.992188 A 1.5 1.5 0 0 0 18 27.5 A 1.5 1.5 0 0 0 19.5 29 A 1.5 1.5 0 0 0 21 27.5 A 1.5 1.5 0 0 0 19.851562 26.042969 L 18.212891 23 L 24 23 C 25.105 23 26 22.105 26 21 L 26 6 A 1.0001 1.0001 0 1 0 26 4 L 25 4 L 16 4 L 16 3 A 1.0001 1.0001 0 0 0 14.984375 1.9863281 z M 5.9589844 6 L 14.832031 6 A 1.0001 1.0001 0 0 0 15.158203 6 L 23.958984 6 C 23.912194 9.0500505 23.687726 11.893974 23.152344 14.142578 C 22.583328 16.532444 21.674397 18.178754 20.585938 19 L 3.1523438 19 C 3.9976592 17.786874 4.6791735 16.365049 5.0976562 14.607422 C 5.6877248 12.129135 5.9137751 9.1554725 5.9589844 6 z" /> </svg> ); } function PersonIcon(props: React.ComponentProps<'svg'>) { return ( <svg width="40" height="40" viewBox="0 0 30 30" fill="currentcolor" {...props}> <path d="M15,3C8.373,3,3,8.373,3,15c0,6.627,5.373,12,12,12s12-5.373,12-12C27,8.373,21.627,3,15,3z M8,22.141 c1.167-3.5,4.667-2.134,5.25-4.03v-1.264c-0.262-0.141-1.013-1.109-1.092-1.865c-0.207-0.018-0.531-0.223-0.627-1.034 c-0.051-0.435,0.153-0.68,0.276-0.757c0,0-0.308-0.702-0.308-1.399C11.5,9.72,12.526,8,15,8c1.336,0,1.75,0.947,1.75,0.947 c1.194,0,1.75,1.309,1.75,2.844c0,0.765-0.308,1.399-0.308,1.399c0.124,0.077,0.328,0.322,0.277,0.757 c-0.096,0.811-0.42,1.016-0.627,1.034c-0.079,0.756-0.829,1.724-1.092,1.865v1.264c0.583,1.897,4.083,0.531,5.25,4.031 c0,0-2.618,2.859-7,2.859C10.593,25,8,22.141,8,22.141z" /> </svg> ); } Show code ## Anatomy Import the component and assemble its parts: Anatomy Copy import { Tabs } from '@base-ui-components/react/tabs'; <Tabs.Root> <Tabs.List> <Tabs.Tab /> <Tabs.Indicator /> </Tabs.List> <Tabs.Panel /> </Tabs.Root> ## API reference ### Root Groups the tabs and the corresponding panels. Renders a `<div>` element. | Prop | Type | Default | | | --- | --- | --- | --- | | `defaultValue` | `Tabs.Tab.Value` | `0` | | | `value` | `Tabs.Tab.Value` | `undefined` | | | `onValueChange` | `((value: any, event: Event | undefined) => void)` | `undefined` | | | `orientation` | `Tabs.Root.Orientation` | `'horizontal'` | | | `className` | `| string | ((state: Tabs.Root.State) => string)` | `undefined` | | | `render` | `| ReactElement | ((props: HTMLProps, state: Tabs.Root.State) => ReactElement)` | `undefined` | | | Attribute | Description | | | --- | --- | --- | | `data-orientation` | Indicates the orientation of the tabs. | | `data-activation-direction` | Indicates the direction of the activation (based on the previous selected tab). | ### List Groups the individual tab buttons. Renders a `<div>` element. | Prop | Type | Default | | | --- | --- | --- | --- | | `activateOnFocus` | `boolean` | `true` | | | `loop` | `boolean` | `true` | | | `className` | `| string | ((state: Tabs.List.State) => string)` | `undefined` | | | `render` | `| ReactElement | ((props: HTMLProps, state: Tabs.List.State) => ReactElement)` | `undefined` | | | Attribute | Description | | | --- | --- | --- | | `data-orientation` | Indicates the orientation of the tabs. | | `data-activation-direction` | Indicates the direction of the activation (based on the previous selected tab). | ### Tab An individual interactive tab button that toggles the corresponding panel. Renders a `<button>` element. | Prop | Type | Default | | | --- | --- | --- | --- | | `value` | `Tabs.Tab.Value` | `undefined` | | | `className` | `| string | ((state: Tabs.Tab.State) => string)` | `undefined` | | | `render` | `| ReactElement | ((props: HTMLProps, state: Tabs.Tab.State) => ReactElement)` | `undefined` | | | Attribute | Description | | | --- | --- | --- | | `data-selected` | Present when the tab is selected. | | `data-highlighted` | Present when the tab is highlighted. | | `data-orientation` | Indicates the orientation of the tabs. | | `data-disabled` | Present when the tab is disabled. | | `data-activation-direction` | Indicates the direction of the activation (based on the previous selected tab). | ### Indicator A visual indicator that can be styled to match the position of the currently active tab. Renders a `<span>` element. | Prop | Type | Default | | | --- | --- | --- | --- | | `renderBeforeHydration` | `boolean` | `false` | | | `className` | `| string | ((state: Tabs.Indicator.State) => string)` | `undefined` | | | `render` | `| ReactElement | ((props: HTMLProps, state: Tabs.Indicator.State) => ReactElement)` | `undefined` | | | Attribute | Description | | | --- | --- | --- | | `data-orientation` | Indicates the orientation of the tabs. | | `data-activation-direction` | Indicates the direction of the activation (based on the previous selected tab). | | CSS Variable | Description | | | --- | --- | --- | | `--active-tab-bottom` | Indicates the distance on the bottom side from the parent's container if the tab is active. | | `--active-tab-height` | Indicates the width of the tab if it is active. | | `--active-tab-left` | Indicates the distance on the left side from the parent's container if the tab is active. | | `--active-tab-right` | Indicates the distance on the right side from the parent's container if the tab is active. | | `--active-tab-top` | Indicates the distance on the top side from the parent's container if the tab is active. | | `--active-tab-width` | Indicates the width of the tab if it is active. | ### Panel A panel displayed when the corresponding tab is active. Renders a `<div>` element. | Prop | Type | Default | | | --- | --- | --- | --- | | `value` | `Tabs.Tab.Value` | `undefined` | | | `className` | `| string | ((state: Tabs.Panel.State) => string)` | `undefined` | | | `keepMounted` | `boolean` | `false` | | | `render` | `| ReactElement | ((props: HTMLProps, state: Tabs.Panel.State) => ReactElement)` | `undefined` | | | Attribute | Description | | | --- | --- | --- | | `data-orientation` | Indicates the orientation of the tabs. | | `data-activation-direction` | Indicates the direction of the activation (based on the previous selected tab). | | `data-hidden` | Present when the panel is hidden. | | `data-index` | Indicates the index of the tab panel. | --- ## Page: https://base-ui.com/react/components/toast Toast * (Top) * Usage * Anatomy * API reference * Provider * Viewport * Portal * Root * Title * Description * Action * Close * useToastManager * Return value * Method options * add method * update method * close method * promise method * Global manager * Stacking and animations * Examples * Custom position * Undo action * Promise * Custom # Toast Generates toast notifications. Create toast index.tsxindex.module.csstheme.css CSS Modules CodeSandboxCopy 'use client'; import * as React from 'react'; import { Toast } from '@base-ui-components/react/toast'; import styles from './index.module.css'; export default function ExampleToast() { return ( <Toast.Provider> <ToastButton /> <Toast.Portal> <Toast.Viewport className={styles.Viewport}> <ToastList /> </Toast.Viewport> </Toast.Portal> </Toast.Provider> ); } function ToastButton() { const toastManager = Toast.useToastManager(); const [count, setCount] = React.useState(0); function createToast() { setCount((prev) => prev + 1); toastManager.add({ title: `Toast ${count + 1} created`, description: 'This is a toast notification.', }); } return ( <button type="button" className={styles.Button} onClick={createToast}> Create toast </button> ); } function ToastList() { const { toasts } = Toast.useToastManager(); return toasts.map((toast) => ( <Toast.Root key={toast.id} toast={toast} className={styles.Toast}> <Toast.Title className={styles.Title} /> <Toast.Description className={styles.Description} /> <Toast.Close className={styles.Close} aria-label="Close"> <XIcon className={styles.Icon} /> </Toast.Close> </Toast.Root> )); } function XIcon(props: React.ComponentProps<'svg'>) { return ( <svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round" {...props} > <path d="M18 6 6 18" /> <path d="m6 6 12 12" /> </svg> ); } Show code ## Usage * `<Toast.Provider>` can be wrapped around your entire app, ensuring all toasts are rendered in the same viewport. * F6 lets users jump into the toast viewport landmark region to navigate toasts with keyboard focus. ## Anatomy Import the component and assemble its parts: Anatomy Copy import { Toast } from '@base-ui-components/react/toast'; <Toast.Provider> <Toast.Portal> <Toast.Viewport> <Toast.Root> <Toast.Title /> <Toast.Description /> <Toast.Action /> <Toast.Close /> </Toast.Root> </Toast.Viewport> </Toast.Portal> </Toast.Provider> ## API reference ### Provider Provides a context for creating and managing toasts. | Prop | Type | Default | | | --- | --- | --- | --- | | `limit` | `number` | `3` | | | `toastManager` | `createToastManager.ToastManager` | `undefined` | | | `timeout` | `number` | `5000` | | | `children` | `ReactNode` | `undefined` | | ### Viewport A container viewport for toasts. Renders a `<div>` element. | Prop | Type | Default | | | --- | --- | --- | --- | | `className` | `| string | ((state: Toast.Viewport.State) => string)` | `undefined` | | | `render` | `| ReactElement | ((props: HTMLProps, state: Toast.Viewport.State) => ReactElement)` | `undefined` | | | Attribute | Description | | | --- | --- | --- | | `data-expanded` | Indicates toasts are expanded in the viewport. | ### Portal A portal element that moves the viewport to a different part of the DOM. By default, the portal element is appended to `<body>`. | Prop | Type | Default | | | --- | --- | --- | --- | | `container` | `| HTMLElement | RefObject<HTMLElement | null> | null` | `undefined` | | | `children` | `ReactNode` | `undefined` | | ### Root Groups all parts of an individual toast. Renders a `<div>` element. | Prop | Type | Default | | | --- | --- | --- | --- | | `swipeDirection` | `| 'left' | 'right' | 'up' | 'down' | ('left' | 'right' | 'up' | 'down')[]` | `['down', 'right']` | | | `toast*` | `Toast.Root.ToastObject` | `—` | | | `className` | `| string | ((state: Toast.Root.State) => string)` | `undefined` | | | `render` | `| ReactElement | ((props: HTMLProps, state: Toast.Root.State) => ReactElement)` | `undefined` | | | Attribute | Description | | | --- | --- | --- | | `data-expanded` | Present when the toast is expanded in the viewport. | | `data-limited` | Present when the toast was removed due to exceeding the limit. | | `data-swipe-direction` | The direction the toast was swiped. | | `data-swiping` | Present when the toast is being swiped. | | `data-type` | The type of the toast. | | `data-starting-style` | Present when the toast is animating in. | | `data-ending-style` | Present when the toast is animating out. | | CSS Variable | Description | | | --- | --- | --- | | `--toast-index` | Indicates the index of the toast in the list. | | `--toast-offset-y` | Indicates the vertical pixels offset of the toast in the list when expanded. | | `--toast-swipe-movement-x` | Indicates the horizontal swipe movement of the toast. | | `--toast-swipe-movement-y` | Indicates the vertical swipe movement of the toast. | ### Title A title that labels the toast. Renders an `<h2>` element. | Prop | Type | Default | | | --- | --- | --- | --- | | `className` | `| string | ((state: Toast.Title.State) => string)` | `undefined` | | | `render` | `| ReactElement | ((props: HTMLProps, state: Toast.Title.State) => ReactElement)` | `undefined` | | | Attribute | Description | | | --- | --- | --- | | `data-type` | The type of the toast. | ### Description A description that describes the toast. Can be used as the default message for the toast when no title is provided. Renders a `<p>` element. | Prop | Type | Default | | | --- | --- | --- | --- | | `className` | `| string | ((state: Toast.Description.State) => string)` | `undefined` | | | `render` | `| ReactElement | ((props: HTMLProps, state: Toast.Description.State) => ReactElement)` | `undefined` | | | Attribute | Description | | | --- | --- | --- | | `data-type` | The type of the toast. | ### Action Performs an action when clicked. Renders a `<button>` element. | Prop | Type | Default | | | --- | --- | --- | --- | | `className` | `| string | ((state: Toast.Action.State) => string)` | `undefined` | | | `render` | `| ReactElement | ((props: HTMLProps, state: Toast.Action.State) => ReactElement)` | `undefined` | | | Attribute | Description | | | --- | --- | --- | | `data-type` | The type of the toast. | ### Close Closes the toast when clicked. Renders a `<button>` element. | Prop | Type | Default | | | --- | --- | --- | --- | | `className` | `| string | ((state: Toast.Close.State) => string)` | `undefined` | | | `render` | `| ReactElement | ((props: HTMLProps, state: Toast.Close.State) => ReactElement)` | `undefined` | | | Attribute | Description | | | --- | --- | --- | | `data-type` | The type of the toast. | ## useToastManager Manages toasts, called inside of a `Toast.Provider`. Usage Copy const toastManager = Toast.useToastManager(); ### Return value | Prop | Type | | | --- | --- | --- | | `toasts` | `Toast.Root.ToastObject[]` | | | `add` | `(options: useToast.AddOptions) => string` | | | `close` | `(toastId: string) => void` | | | `update` | `(toastId: string, options: useToast.UpdateOptions) => void` | | | `promise` | `<Value>(promise: Promise<Value>, options: useToast.PromiseOptions) => Promise<Value>` | | ### Method options | Prop | Type | Default | | | --- | --- | --- | --- | | `title` | `string` | `undefined` | | | `description` | `string` | `undefined` | | | `type` | `string` | `undefined` | | | `timeout` | `number` | `undefined` | | | `priority` | `'low' | 'high'` | `'low'` | | | `onClose` | `() => void` | `undefined` | | | `onRemove` | `() => void` | `undefined` | | | `actionProps` | `React.ComponentPropsWithRef<'button'>` | `undefined` | | | `data` | `Record<string, unknown>` | `undefined` | | ### `add` method Creates a toast by adding it to the toast list. Returns a `toastId` that can be used to update or close the toast later. Usage Copy const toastId = toastManager.add({ description: 'Hello, world!', }); Example Copy function App() { const toastManager = Toast.useToastManager(); return ( <button type="button" onClick={() => { toastManager.add({ description: 'Hello, world!', }); }} > Add toast </button> ); } The `title` and `description` strings are what are used to announce the toast to screen readers. Screen readers do not announce any extra content rendered inside `Toast.Root`, including the `Toast.Title` or `Toast.Description` components. ### `update` method Updates the toast with new options. Usage Copy toastManager.update(toastId, { description: 'New description', }); ### `close` method Closes the toast, removing it from the toast list after any animations complete. Usage Copy toastManager.close(toastId); ### `promise` method Creates an asynchronous toast with three possible states: `loading`, `success`, and `error`. Description configuration Copy const toastId = toastManager.promise( new Promise((resolve) => { setTimeout(() => resolve('world!'), 1000); }), { // Each are a shortcut for the `description` option loading: 'Loading...', success: (data) => `Hello ${data}`, error: (err) => `Error: ${err}`, }, ); Each state also accepts the method options object to granularly control the toast for each state: Method options configuration Copy const toastId = toastManager.promise( new Promise((resolve) => { setTimeout(() => resolve('world!'), 1000); }), { loading: { title: 'Loading...', description: 'The promise is loading.', }, success: { title: 'Success', description: 'The promise resolved successfully.', }, error: { title: 'Error', description: 'The promise rejected.', actionProps: { children: 'Contact support', onClick() { // Redirect to support page }, }, }, }, ); ## Global manager A global toast manager can be created by passing the `toastManager` prop to the `Toast.Provider`. This enables you to queue a toast from anywhere in the app (such as in functions outside the React tree) while still using the same toast renderer. The created `toastManager` object has the same properties and methods as the `Toast.useToastManager()` hook. Creating a manager instance Copy const toastManager = Toast.createToastManager(); Using the instance Copy <Toast.Provider toastManager={toastManager}> ## Stacking and animations The `--toast-index` CSS variable can be used to determine the stacking order of the toasts. The 0th index toast appears at the front. .Toast { z-index: calc(1000 - var(--toast-index)); transform: scale(1 - calc(0.1 * var(--toast-index))); } The `--toast-offset-y` CSS variable can be used to determine the vertical offset of the toasts when positioned absolutely with a translation offset — this is usually used with the `data-expanded` attribute, present when the toast viewport is being hovered or has focus. .Toast[data-expanded] { transform: translateY(var(--toast-offset-y)); } The `--toast-swipe-movement-x` and `--toast-swipe-movement-y` CSS variables are used to determine the swipe movement of the toasts in order to add a translation offset. .Toast { transform: scale(1 - calc(0.1 * var(--toast-index))) + translateX(var(--toast-swipe-movement-x)) + translateY(calc(var(--toast-swipe-movement-y) + (var(--toast-index) * -20%))); } The `data-swipe-direction` attribute can be used to determine the swipe direction of the toasts to add a translation offset upon dismissal. &[data-ending-style] { opacity: 0; &[data-swipe-direction='up'] { transform: translateY(calc(var(--toast-swipe-movement-y) - 150%)); } &[data-swipe-direction='down'] { transform: translateY(calc(var(--toast-swipe-movement-y) + 150%)); } &[data-swipe-direction='left'] { transform: translateX(calc(var(--toast-swipe-movement-x) - 150%)) translateY(var(--offset-y)); } &[data-swipe-direction='right'] { transform: translateX(calc(var(--toast-swipe-movement-x) + 150%)) translateY(var(--offset-y)); } } The `data-limited` attribute indicates that the toast was removed from the list due to exceeding the `limit` option. This is useful for animating the toast differently when it is removed from the list. ## Examples ### Custom position The position of the toasts is controlled by your own CSS. To change the toasts’ position, you can modify the `Viewport` and `Root` styles. A more general component could accept a `data-position` attribute, which the CSS handles for each variation. The following shows a top-center position: Create toast index.tsxindex.module.csstheme.css CSS Modules CodeSandboxCopy 'use client'; import * as React from 'react'; import { Toast } from '@base-ui-components/react/toast'; import styles from './index.module.css'; export default function ExampleToast() { return ( <Toast.Provider> <ToastButton /> <Toast.Portal> <Toast.Viewport className={styles.Viewport}> <ToastList /> </Toast.Viewport> </Toast.Portal> </Toast.Provider> ); } function ToastButton() { const toastManager = Toast.useToastManager(); const [count, setCount] = React.useState(0); function createToast() { setCount((prev) => prev + 1); toastManager.add({ title: `Toast ${count + 1} created`, description: 'This is a toast notification.', }); } return ( <button type="button" className={styles.Button} onClick={createToast}> Create toast </button> ); } function ToastList() { const { toasts } = Toast.useToastManager(); return toasts.map((toast) => ( <Toast.Root key={toast.id} toast={toast} swipeDirection="up" className={styles.Toast} > <Toast.Title className={styles.Title} /> <Toast.Description className={styles.Description} /> <Toast.Close className={styles.Close} aria-label="Close"> <XIcon className={styles.Icon} /> </Toast.Close> </Toast.Root> )); } function XIcon(props: React.ComponentProps<'svg'>) { return ( <svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round" {...props} > <path d="M18 6 6 18" /> <path d="m6 6 12 12" /> </svg> ); } Show code ### Undo action When adding a toast, the `actionProps` option can be used to define props for an action button inside of it—this enables the ability to undo an action associated with the toast. Perform action index.tsxindex.module.csstheme.css CodeSandboxCopy 'use client'; import * as React from 'react'; import { Toast } from '@base-ui-components/react/toast'; import styles from './index.module.css'; export default function UndoToastExample() { return ( <Toast.Provider> <Form /> <Toast.Portal> <Toast.Viewport className={styles.Viewport}> <ToastList /> </Toast.Viewport> </Toast.Portal> </Toast.Provider> ); } function Form() { const toastManager = Toast.useToastManager(); function action() { const id = toastManager.add({ title: 'Action performed', description: 'You can undo this action.', type: 'success', actionProps: { children: 'Undo', onClick() { toastManager.close(id); toastManager.add({ title: 'Action undone', }); }, }, }); } return ( <button type="button" onClick={action} className={styles.Button}> Perform action </button> ); } function ToastList() { const { toasts } = Toast.useToastManager(); return toasts.map((toast) => ( <Toast.Root key={toast.id} toast={toast} className={styles.Toast}> <Toast.Title className={styles.Title} /> <Toast.Description className={styles.Description} /> <Toast.Action className={styles.UndoButton} /> <Toast.Close className={styles.Close} aria-label="Close"> <XIcon className={styles.Icon} /> </Toast.Close> </Toast.Root> )); } function XIcon(props: React.ComponentProps<'svg'>) { return ( <svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round" {...props} > <path d="M18 6 6 18" /> <path d="m6 6 12 12" /> </svg> ); } Show code ### Promise An asynchronous toast can be created with three possible states: `loading`, `success`, and `error`. The `type` string matches these states to change the styling. Each of the states also accepts the method options object for more granular control. Run promise index.tsxindex.module.csstheme.css CodeSandboxCopy 'use client'; import * as React from 'react'; import { Toast } from '@base-ui-components/react/toast'; import styles from './index.module.css'; export default function PromiseToastExample() { return ( <Toast.Provider> <PromiseDemo /> <Toast.Portal> <Toast.Viewport className={styles.Viewport}> <ToastList /> </Toast.Viewport> </Toast.Portal> </Toast.Provider> ); } function PromiseDemo() { const toastManager = Toast.useToastManager(); function runPromise() { toastManager.promise( // Simulate an API request with a promise that resolves after 2 seconds new Promise<string>((resolve, reject) => { const shouldSucceed = Math.random() > 0.3; // 70% success rate setTimeout(() => { if (shouldSucceed) { resolve('operation completed'); } else { reject(new Error('operation failed')); } }, 2000); }), { loading: 'Loading data...', success: (data: string) => `Success: ${data}`, error: (err: Error) => `Error: ${err.message}`, }, ); } return ( <button type="button" onClick={runPromise} className={styles.Button}> Run promise </button> ); } function ToastList() { const { toasts } = Toast.useToastManager(); return toasts.map((toast) => ( <Toast.Root key={toast.id} toast={toast} className={styles.Toast}> <Toast.Title className={styles.Title} /> <Toast.Description className={styles.Description} /> <Toast.Close className={styles.Close} aria-label="Close"> <XIcon className={styles.Icon} /> </Toast.Close> </Toast.Root> )); } function XIcon(props: React.ComponentProps<'svg'>) { return ( <svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round" {...props} > <path d="M18 6 6 18" /> <path d="m6 6 12 12" /> </svg> ); } Show code ### Custom A toast with custom data can be created by passing any typed object interface to the `data` option. This enables you to pass any data (including functions) you need to the toast and access it in the toast’s rendering logic. Create custom toast index.tsxindex.module.csstheme.css CodeSandboxCopy 'use client'; import * as React from 'react'; import { Toast } from '@base-ui-components/react/toast'; import styles from './index.module.css'; interface CustomToastData { userId: string; } function isCustomToast( toast: Toast.Root.ToastObject, ): toast is Toast.Root.ToastObject<CustomToastData> { return toast.data?.userId !== undefined; } export default function CustomToastExample() { return ( <Toast.Provider> <CustomToast /> <Toast.Portal> <Toast.Viewport className={styles.Viewport}> <ToastList /> </Toast.Viewport> </Toast.Portal> </Toast.Provider> ); } function CustomToast() { const toastManager = Toast.useToastManager(); function action() { const data: CustomToastData = { userId: '123', }; toastManager.add({ title: 'Toast with custom data', data, }); } return ( <button type="button" onClick={action} className={styles.Button}> Create custom toast </button> ); } function ToastList() { const { toasts } = Toast.useToastManager(); return toasts.map((toast) => ( <Toast.Root key={toast.id} toast={toast} className={styles.Toast}> <Toast.Title className={styles.Title}>{toast.title}</Toast.Title> {isCustomToast(toast) && toast.data ? ( <Toast.Description>`data.userId` is {toast.data.userId}</Toast.Description> ) : ( <Toast.Description /> )} <Toast.Close className={styles.Close} aria-label="Close"> <XIcon className={styles.Icon} /> </Toast.Close> </Toast.Root> )); } function XIcon(props: React.ComponentProps<'svg'>) { return ( <svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round" {...props} > <path d="M18 6 6 18" /> <path d="m6 6 12 12" /> </svg> ); } Show code --- ## Page: https://base-ui.com/react/components/toggle Toggle * (Top) * Anatomy * API reference # Toggle A two-state button that can be on or off. index.tsxindex.module.csstheme.css CSS Modules CodeSandboxCopy import * as React from 'react'; import { Toggle } from '@base-ui-components/react/toggle'; import styles from './index.module.css'; export default function ExampleToggle() { return ( <div className={styles.Panel}> <Toggle aria-label="Favorite" className={styles.Button} render={(props, state) => { if (state.pressed) { return ( <button type="button" {...props}> <HeartFilledIcon className={styles.Icon} /> </button> ); } return ( <button type="button" {...props}> <HeartOutlineIcon className={styles.Icon} /> </button> ); }} /> </div> ); } function HeartFilledIcon(props: React.ComponentProps<'svg'>) { return ( <svg width="16" height="16" viewBox="0 0 16 16" fill="currentcolor" {...props}> <path d="M7.99961 13.8667C7.88761 13.8667 7.77561 13.8315 7.68121 13.7611C7.43321 13.5766 1.59961 9.1963 1.59961 5.8667C1.59961 3.80856 3.27481 2.13336 5.33294 2.13336C6.59054 2.13336 7.49934 2.81176 7.99961 3.3131C8.49988 2.81176 9.40868 2.13336 10.6663 2.13336C12.7244 2.13336 14.3996 3.80803 14.3996 5.8667C14.3996 9.1963 8.56601 13.5766 8.31801 13.7616C8.22361 13.8315 8.11161 13.8667 7.99961 13.8667Z" /> </svg> ); } function HeartOutlineIcon(props: React.ComponentProps<'svg'>) { return ( <svg width="16" height="16" viewBox="0 0 16 16" fill="currentcolor" {...props}> <path fillRule="evenodd" clipRule="evenodd" d="M7.99961 4.8232L7.24456 4.06654C6.84123 3.66235 6.18866 3.20003 5.33294 3.20003C3.86391 3.20003 2.66628 4.39767 2.66628 5.8667C2.66628 6.4079 2.91276 7.1023 3.41967 7.91383C3.91548 8.70759 4.59649 9.51244 5.31278 10.2503C6.38267 11.3525 7.47318 12.2465 7.99983 12.6605C8.52734 12.2456 9.61718 11.352 10.6864 10.2504C11.4027 9.51248 12.0837 8.70762 12.5796 7.91384C13.0865 7.1023 13.3329 6.4079 13.3329 5.8667C13.3329 4.39723 12.1354 3.20003 10.6663 3.20003C9.81056 3.20003 9.15799 3.66235 8.75466 4.06654L7.99961 4.8232ZM7.98574 3.29926C7.48264 2.79938 6.57901 2.13336 5.33294 2.13336C3.27481 2.13336 1.59961 3.80856 1.59961 5.8667C1.59961 9.1963 7.43321 13.5766 7.68121 13.7611C7.77561 13.8315 7.88761 13.8667 7.99961 13.8667C8.11161 13.8667 8.22361 13.8315 8.31801 13.7616C8.56601 13.5766 14.3996 9.1963 14.3996 5.8667C14.3996 3.80803 12.7244 2.13336 10.6663 2.13336C9.42013 2.13336 8.51645 2.79947 8.01337 3.29936C8.00877 3.30393 8.00421 3.30849 7.99967 3.31303C7.99965 3.31305 7.99963 3.31307 7.99961 3.3131C7.99502 3.3085 7.9904 3.30389 7.98574 3.29926Z" /> </svg> ); } Show code ## Anatomy Import the component and use it as a single part: Anatomy Copy import { Toggle } from '@base-ui-components/react/toggle'; <Toggle /> ## API reference | Prop | Type | Default | | | --- | --- | --- | --- | | `value` | `string` | `undefined` | | | `defaultPressed` | `boolean` | `false` | | | `pressed` | `boolean` | `undefined` | | | `onPressedChange` | `((pressed: boolean, event: Event) => void)` | `undefined` | | | `disabled` | `boolean` | `false` | | | `className` | `| string | ((state: Toggle.State) => string)` | `undefined` | | | `render` | `| ReactElement | ((props: HTMLProps, state: Toggle.State) => ReactElement)` | `undefined` | | | Attribute | Description | | | --- | --- | --- | | `data-pressed` | Present when the toggle button is pressed. | --- ## Page: https://base-ui.com/react/components/toggle-group Toggle Group * (Top) * Anatomy * API reference # Toggle Group Provides a shared state to a series of toggle buttons. index.tsxindex.module.csstheme.css CSS Modules CodeSandboxCopy import * as React from 'react'; import { Toggle } from '@base-ui-components/react/toggle'; import { ToggleGroup } from '@base-ui-components/react/toggle-group'; import styles from './index.module.css'; export default function ExampleToggleGroup() { return ( <ToggleGroup defaultValue={['left']} className={styles.Panel}> <Toggle aria-label="Align left" value="left" className={styles.Button}> <AlignLeftIcon className={styles.Icon} /> </Toggle> <Toggle aria-label="Align center" value="center" className={styles.Button}> <AlignCenterIcon className={styles.Icon} /> </Toggle> <Toggle aria-label="Align right" value="right" className={styles.Button}> <AlignRightIcon className={styles.Icon} /> </Toggle> </ToggleGroup> ); } function AlignLeftIcon(props: React.ComponentProps<'svg'>) { return ( <svg width="16" height="16" viewBox="0 0 16 16" stroke="currentcolor" strokeLinecap="round" {...props} > <path d="M2.5 3.5H13.5" /> <path d="M2.5 9.5H13.5" /> <path d="M2.5 6.5H10.5" /> <path d="M2.5 12.5H10.5" /> </svg> ); } function AlignCenterIcon(props: React.ComponentProps<'svg'>) { return ( <svg width="16" height="16" viewBox="0 0 16 16" stroke="currentcolor" strokeLinecap="round" {...props} > <path d="M3 3.5H14" /> <path d="M3 9.5H14" /> <path d="M4.5 6.5H12.5" /> <path d="M4.5 12.5H12.5" /> </svg> ); } function AlignRightIcon(props: React.ComponentProps<'svg'>) { return ( <svg width="16" height="16" viewBox="0 0 16 16" stroke="currentcolor" strokeLinecap="round" {...props} > <path d="M2.5 3.5H13.5" /> <path d="M2.5 9.5H13.5" /> <path d="M5.5 6.5H13.5" /> <path d="M5.5 12.5H13.5" /> </svg> ); } Show code ## Anatomy Import the component and use it as a single part: Anatomy Copy import { ToggleGroup } from '@base-ui-components/react/toggle-group'; <ToggleGroup /> ## API reference | Prop | Type | Default | | | --- | --- | --- | --- | | `defaultValue` | `any[]` | `undefined` | | | `value` | `any[]` | `undefined` | | | `onValueChange` | `((groupValue: any[], event: Event) => void)` | `undefined` | | | `toggleMultiple` | `boolean` | `false` | | | `disabled` | `boolean` | `false` | | | `loop` | `boolean` | `true` | | | `orientation` | `Orientation` | `'horizontal'` | | | `className` | `| string | ((state: Toggle.Group.State) => string)` | `undefined` | | | `render` | `| ReactElement | ((props: HTMLProps, state: Toggle.Group.State) => ReactElement)` | `undefined` | | | Attribute | Description | | | --- | --- | --- | | `data-orientation` | Indicates the orientation of the toggle group. | | `data-disabled` | Present when the toggle group is disabled. | | `data-multiple` | Present when the toggle group allows multiple buttons to be in the pressed state at the same time. | --- ## Page: https://base-ui.com/react/components/toolbar Toolbar * (Top) * Accessibility guidelines * Anatomy * API reference * Root * Button * Link * Input * Group * Separator * Examples * Using with Menu * Using with Tooltip * Using with NumberField # Toolbar A container for grouping a set of buttons and controls. Align LeftAlign Right $% Helvetica Edited 51m ago index.tsxindex.module.csstheme.css CSS Modules CodeSandboxCopy import * as React from 'react'; import { Toolbar } from '@base-ui-components/react/toolbar'; import { ToggleGroup } from '@base-ui-components/react/toggle-group'; import { Toggle } from '@base-ui-components/react/toggle'; import { Select } from '@base-ui-components/react/select'; import styles from './index.module.css'; export default function ExampleToolbar() { return ( <Toolbar.Root className={styles.Toolbar}> <ToggleGroup className={styles.Group} aria-label="Alignment"> <Toolbar.Button render={<Toggle />} aria-label="Align left" value="align-left" className={styles.Button} > Align Left </Toolbar.Button> <Toolbar.Button render={<Toggle />} aria-label="Align right" value="align-right" className={styles.Button} > Align Right </Toolbar.Button> </ToggleGroup> <Toolbar.Separator className={styles.Separator} /> <Toolbar.Group className={styles.Group} aria-label="Numerical format"> <Toolbar.Button className={styles.Button} aria-label="Format as currency"> $ </Toolbar.Button> <Toolbar.Button className={styles.Button} aria-label="Format as percent"> % </Toolbar.Button> </Toolbar.Group> <Toolbar.Separator className={styles.Separator} /> <Select.Root defaultValue="helvetica"> <Toolbar.Button render={<Select.Trigger />} className={styles.Button}> <Select.Value placeholder="Helvetica" /> <Select.Icon> <ChevronUpDownIcon /> </Select.Icon> </Toolbar.Button> <Select.Portal> <Select.Positioner className={styles.Positioner} sideOffset={8}> <Select.Popup className={styles.Popup}> <Select.Arrow className={styles.Arrow}> <ArrowSvg /> </Select.Arrow> <Select.Item className={styles.Item} value="helvetica"> <Select.ItemIndicator className={styles.ItemIndicator}> <CheckIcon className={styles.ItemIndicatorIcon} /> </Select.ItemIndicator> <Select.ItemText className={styles.ItemText}> Helvetica </Select.ItemText> </Select.Item> <Select.Item className={styles.Item} value="arial"> <Select.ItemIndicator className={styles.ItemIndicator}> <CheckIcon className={styles.ItemIndicatorIcon} /> </Select.ItemIndicator> <Select.ItemText className={styles.ItemText}>Arial</Select.ItemText> </Select.Item> </Select.Popup> </Select.Positioner> </Select.Portal> </Select.Root> <Toolbar.Separator className={styles.Separator} /> <Toolbar.Link className={styles.Link} href="#"> Edited 51m ago </Toolbar.Link> </Toolbar.Root> ); } function ArrowSvg(props: React.ComponentProps<'svg'>) { return ( <svg width="20" height="10" viewBox="0 0 20 10" fill="none" {...props}> <path d="M9.66437 2.60207L4.80758 6.97318C4.07308 7.63423 3.11989 8 2.13172 8H0V10H20V8H18.5349C17.5468 8 16.5936 7.63423 15.8591 6.97318L11.0023 2.60207C10.622 2.2598 10.0447 2.25979 9.66437 2.60207Z" className={styles.ArrowFill} /> <path d="M8.99542 1.85876C9.75604 1.17425 10.9106 1.17422 11.6713 1.85878L16.5281 6.22989C17.0789 6.72568 17.7938 7.00001 18.5349 7.00001L15.89 7L11.0023 2.60207C10.622 2.2598 10.0447 2.2598 9.66436 2.60207L4.77734 7L2.13171 7.00001C2.87284 7.00001 3.58774 6.72568 4.13861 6.22989L8.99542 1.85876Z" className={styles.ArrowOuterStroke} /> <path d="M10.3333 3.34539L5.47654 7.71648C4.55842 8.54279 3.36693 9 2.13172 9H0V8H2.13172C3.11989 8 4.07308 7.63423 4.80758 6.97318L9.66437 2.60207C10.0447 2.25979 10.622 2.2598 11.0023 2.60207L15.8591 6.97318C16.5936 7.63423 17.5468 8 18.5349 8H20V9H18.5349C17.2998 9 16.1083 8.54278 15.1901 7.71648L10.3333 3.34539Z" className={styles.ArrowInnerStroke} /> </svg> ); } function ChevronUpDownIcon(props: React.ComponentProps<'svg'>) { return ( <svg width="8" height="12" viewBox="0 0 8 12" fill="none" stroke="currentcolor" strokeWidth="1.5" {...props} > <path d="M0.5 4.5L4 1.5L7.5 4.5" /> <path d="M0.5 7.5L4 10.5L7.5 7.5" /> </svg> ); } function CheckIcon(props: React.ComponentProps<'svg'>) { return ( <svg fill="currentcolor" width="10" height="10" viewBox="0 0 10 10" {...props}> <path d="M9.1603 1.12218C9.50684 1.34873 9.60427 1.81354 9.37792 2.16038L5.13603 8.66012C5.01614 8.8438 4.82192 8.96576 4.60451 8.99384C4.3871 9.02194 4.1683 8.95335 4.00574 8.80615L1.24664 6.30769C0.939709 6.02975 0.916013 5.55541 1.19372 5.24822C1.47142 4.94102 1.94536 4.91731 2.2523 5.19524L4.36085 7.10461L8.12299 1.33999C8.34934 0.993152 8.81376 0.895638 9.1603 1.12218Z" /> </svg> ); } Show code ## Accessibility guidelines To ensure that toolbars are accessible and helpful, follow these guidelines: * **Use inputs sparingly**: Left and right arrow keys are used to both move the text insertion cursor in an input, and to navigate among controls in horizontal toolbars. When using an input in a horizontal toolbar, use only one and place it as the last element of the toolbar. ## Anatomy Import the component and assemble its parts: Anatomy Copy import { Toolbar } from '@base-ui-components/react/toolbar'; <Toolbar.Root> <Toolbar.Button /> <Toolbar.Link /> <Toolbar.Separator /> <Toolbar.Group> <Toolbar.Button /> <Toolbar.Button /> <Toolbar.Group /> <Toolbar.Input /> </Toolbar.Root> ## API reference ### Root A container for grouping a set of controls, such as buttons, toggle groups, or menus. Renders a `<div>` element. | Prop | Type | Default | | | --- | --- | --- | --- | | `cols` | `number` | `1` | | | `disabled` | `boolean` | `undefined` | | | `loop` | `boolean` | `true` | | | `orientation` | `Orientation` | `'horizontal'` | | | `className` | `| string | ((state: Toolbar.Root.State) => string)` | `undefined` | | | `render` | `| ReactElement | ((props: HTMLProps, state: Toolbar.Root.State) => ReactElement)` | `undefined` | | | Attribute | Description | | | --- | --- | --- | | `data-orientation` | Indicates the orientation of the toolbar. | | `data-disabled` | Present when the toolbar is disabled. | ### Button A button that can be used as-is or as a trigger for other components. Renders a `<button>` element. | Prop | Type | Default | | | --- | --- | --- | --- | | `focusableWhenDisabled` | `boolean` | `true` | | | `disabled` | `boolean` | `false` | | | `className` | `| string | ((state: Toolbar.Root.State) => string)` | `undefined` | | | `render` | `| ReactElement | ((props: HTMLProps, state: Toolbar.Root.State) => ReactElement)` | `undefined` | | | Attribute | Description | | | --- | --- | --- | | `data-highlighted` | Present when the button is the active item in the toolbar. | | `data-orientation` | Indicates the orientation of the toolbar. | | `data-disabled` | Present when the button is disabled. | | `data-focusable` | Present when the button remains focusable when disabled. | ### Link A link component. Renders an `<a>` element. | Prop | Type | Default | | | --- | --- | --- | --- | | `className` | `| string | ((state: Toolbar.Link.State) => string)` | `undefined` | | | `render` | `| ReactElement | ((props: HTMLProps, state: Toolbar.Link.State) => ReactElement)` | `undefined` | | | Attribute | Description | | | --- | --- | --- | | `data-highlighted` | Present when the link is the active item in the toolbar. | | `data-orientation` | Indicates the orientation of the toolbar. | ### Input A native input element that integrates with Toolbar keyboard navigation. Renders an `<input>` element. | Prop | Type | Default | | | --- | --- | --- | --- | | `defaultValue` | `string | number | string[]` | `undefined` | | | `focusableWhenDisabled` | `boolean` | `true` | | | `disabled` | `boolean` | `false` | | | `className` | `| string | ((state: Toolbar.Root.State) => string)` | `undefined` | | | `render` | `| ReactElement | ((props: HTMLProps, state: Toolbar.Root.State) => ReactElement)` | `undefined` | | | Attribute | Description | | | --- | --- | --- | | `data-highlighted` | Present when the input is the active item in the toolbar. | | `data-orientation` | Indicates the orientation of the toolbar. | | `data-disabled` | Present when the input is disabled. | | `data-focusable` | Present when the input remains focusable when disabled. | ### Group Groups several toolbar items or toggles. Renders a `<div>` element. | Prop | Type | Default | | | --- | --- | --- | --- | | `disabled` | `boolean` | `false` | | | `className` | `| string | ((state: Toolbar.Root.State) => string)` | `undefined` | | | `render` | `| ReactElement | ((props: HTMLProps, state: Toolbar.Root.State) => ReactElement)` | `undefined` | | | Attribute | Description | | | --- | --- | --- | | `data-orientation` | Indicates the orientation of the toolbar. | | `data-disabled` | Present when the group is disabled. | ### Separator A separator element accessible to screen readers. Renders a `<div>` element. | Prop | Type | Default | | | --- | --- | --- | --- | | `orientation` | `Orientation` | `'horizontal'` | | | `className` | `| string | ((state: Separator.State) => string)` | `undefined` | | | `render` | `| ReactElement | ((props: HTMLProps, state: Separator.State) => ReactElement)` | `undefined` | | | Attribute | Description | | | --- | --- | --- | | `data-orientation` | Indicates the orientation of the toolbar. | ## Examples ### Using with Menu All Base UI popup components that provide a `Trigger` component can be integrated with a toolbar by passing the trigger to `Toolbar.Button` with the `render` prop: Using popups with toolbar Copy return ( <Toolbar.Root> <Menu.Root> <Toolbar.Button render={<Menu.Trigger />} /> <Menu.Portal> {/* Compose the rest of the menu */} </Menu.Portal> </Menu.Root> </Toolbar.Root> ) This applies to `AlertDialog`, `Dialog`, `Menu`, `Popover` and `Select`. ### Using with Tooltip Unlike other popups, the toolbar item should be passed to the `render` prop of `Tooltip.Trigger`: Using popups with toolbar Copy return ( <Toolbar.Root> <Tooltip.Root> <Tooltip.Trigger render={<Toolbar.Button />} /> <Tooltip.Portal> {/* Compose the rest of the tooltip */} </Tooltip.Portal> </Tooltip.Root> </Toolbar.Root> ) ### Using with NumberField To use a NumberField in the toolbar, pass `NumberField.Input` to `Toolbar.Input` using the `render` prop: Using NumberField with toolbar Copy return ( <Toolbar.Root> <NumberField.Root> <NumberField.Group> <NumberField.Decrement /> <Toolbar.Input render={<NumberField.Input />} /> <NumberField.Increment /> </NumberField.Group> </NumberField.Root> </Toolbar.Root> ) --- ## Page: https://base-ui.com/react/components/tooltip Tooltip * (Top) * Accessibility guidelines * Anatomy * API reference * Provider * Root * Trigger * Portal * Positioner * Popup * Arrow # Tooltip A popup that appears when an element is hovered or focused, showing a hint for sighted users. index.tsxindex.module.csstheme.css CSS Modules CodeSandboxCopy import * as React from 'react'; import { Tooltip } from '@base-ui-components/react/tooltip'; import styles from './index.module.css'; export default function ExampleTooltip() { return ( <Tooltip.Provider> <div className={styles.Panel}> <Tooltip.Root> <Tooltip.Trigger aria-label="Bold" className={styles.Button}> <BoldIcon className={styles.Icon} /> </Tooltip.Trigger> <Tooltip.Portal> <Tooltip.Positioner sideOffset={10}> <Tooltip.Popup className={styles.Popup}> <Tooltip.Arrow className={styles.Arrow}> <ArrowSvg /> </Tooltip.Arrow> Bold </Tooltip.Popup> </Tooltip.Positioner> </Tooltip.Portal> </Tooltip.Root> <Tooltip.Root> <Tooltip.Trigger aria-label="Italic" className={styles.Button}> <ItalicIcon className={styles.Icon} /> </Tooltip.Trigger> <Tooltip.Portal> <Tooltip.Positioner sideOffset={10}> <Tooltip.Popup className={styles.Popup}> <Tooltip.Arrow className={styles.Arrow}> <ArrowSvg /> </Tooltip.Arrow> Italic </Tooltip.Popup> </Tooltip.Positioner> </Tooltip.Portal> </Tooltip.Root> <Tooltip.Root> <Tooltip.Trigger aria-label="Underline" className={styles.Button}> <UnderlineIcon className={styles.Icon} /> </Tooltip.Trigger> <Tooltip.Portal> <Tooltip.Positioner sideOffset={10}> <Tooltip.Popup className={styles.Popup}> <Tooltip.Arrow className={styles.Arrow}> <ArrowSvg /> </Tooltip.Arrow> Underline </Tooltip.Popup> </Tooltip.Positioner> </Tooltip.Portal> </Tooltip.Root> </div> </Tooltip.Provider> ); } function ArrowSvg(props: React.ComponentProps<'svg'>) { return ( <svg width="20" height="10" viewBox="0 0 20 10" fill="none" {...props}> <path d="M9.66437 2.60207L4.80758 6.97318C4.07308 7.63423 3.11989 8 2.13172 8H0V10H20V8H18.5349C17.5468 8 16.5936 7.63423 15.8591 6.97318L11.0023 2.60207C10.622 2.2598 10.0447 2.25979 9.66437 2.60207Z" className={styles.ArrowFill} /> <path d="M8.99542 1.85876C9.75604 1.17425 10.9106 1.17422 11.6713 1.85878L16.5281 6.22989C17.0789 6.72568 17.7938 7.00001 18.5349 7.00001L15.89 7L11.0023 2.60207C10.622 2.2598 10.0447 2.2598 9.66436 2.60207L4.77734 7L2.13171 7.00001C2.87284 7.00001 3.58774 6.72568 4.13861 6.22989L8.99542 1.85876Z" className={styles.ArrowOuterStroke} /> <path d="M10.3333 3.34539L5.47654 7.71648C4.55842 8.54279 3.36693 9 2.13172 9H0V8H2.13172C3.11989 8 4.07308 7.63423 4.80758 6.97318L9.66437 2.60207C10.0447 2.25979 10.622 2.2598 11.0023 2.60207L15.8591 6.97318C16.5936 7.63423 17.5468 8 18.5349 8H20V9H18.5349C17.2998 9 16.1083 8.54278 15.1901 7.71648L10.3333 3.34539Z" className={styles.ArrowInnerStroke} /> </svg> ); } function BoldIcon(props: React.ComponentProps<'svg'>) { return ( <svg width="16" height="16" viewBox="0 0 16 16" fill="currentcolor" {...props}> <path d="M3.73353 2.13333C3.4386 2.13333 3.2002 2.37226 3.2002 2.66666C3.2002 2.96106 3.4386 3.2 3.73353 3.2H4.26686V12.8H3.73353C3.4386 12.8 3.2002 13.0389 3.2002 13.3333C3.2002 13.6277 3.4386 13.8667 3.73353 13.8667H9.86686C11.7783 13.8667 13.3335 12.3115 13.3335 10.4C13.3335 8.9968 12.4945 7.78881 11.2929 7.24375C11.8897 6.70615 12.2669 5.93066 12.2669 5.06666C12.2669 3.44906 10.9506 2.13333 9.33353 2.13333H3.73353ZM6.93353 3.2H8.26686C9.29619 3.2 10.1335 4.03733 10.1335 5.06666C10.1335 6.096 9.29619 6.93333 8.26686 6.93333H6.93353V3.2ZM6.93353 8H7.73353H8.26686C9.59006 8 10.6669 9.0768 10.6669 10.4C10.6669 11.7232 9.59006 12.8 8.26686 12.8H6.93353V8Z" /> </svg> ); } function ItalicIcon(props: React.ComponentProps<'svg'>) { return ( <svg width="16" height="16" viewBox="0 0 16 16" fill="currentcolor" {...props}> <path d="M8.52599 2.12186C8.48583 2.12267 8.44578 2.1265 8.4062 2.13332H6.93328C6.86261 2.13232 6.79244 2.14538 6.72686 2.17173C6.66127 2.19808 6.60158 2.23721 6.55125 2.28683C6.50092 2.33646 6.46096 2.39559 6.43368 2.46079C6.4064 2.526 6.39235 2.59597 6.39235 2.66665C6.39235 2.73733 6.4064 2.80731 6.43368 2.87251C6.46096 2.93772 6.50092 2.99685 6.55125 3.04647C6.60158 3.0961 6.66127 3.13522 6.72686 3.16157C6.79244 3.18793 6.86261 3.20099 6.93328 3.19999H7.70099L6.69057 12.8H5.86661C5.79594 12.799 5.72577 12.812 5.66019 12.8384C5.59461 12.8648 5.53492 12.9039 5.48459 12.9535C5.43425 13.0031 5.39429 13.0623 5.36701 13.1275C5.33973 13.1927 5.32568 13.2626 5.32568 13.3333C5.32568 13.404 5.33973 13.474 5.36701 13.5392C5.39429 13.6044 5.43425 13.6635 5.48459 13.7131C5.53492 13.7628 5.59461 13.8019 5.66019 13.8282C5.72577 13.8546 5.79594 13.8677 5.86661 13.8667H9.06661C9.13729 13.8677 9.20745 13.8546 9.27304 13.8282C9.33862 13.8019 9.39831 13.7628 9.44864 13.7131C9.49897 13.6635 9.53894 13.6044 9.56622 13.5392C9.5935 13.474 9.60754 13.404 9.60754 13.3333C9.60754 13.2626 9.5935 13.1927 9.56622 13.1275C9.53894 13.0623 9.49897 13.0031 9.44864 12.9535C9.39831 12.9039 9.33862 12.8648 9.27304 12.8384C9.20745 12.812 9.13729 12.799 9.06661 12.8H8.2989L9.30932 3.19999H10.1333C10.204 3.20099 10.2741 3.18793 10.3397 3.16157C10.4053 3.13522 10.465 3.0961 10.5153 3.04647C10.5656 2.99685 10.6056 2.93772 10.6329 2.87251C10.6602 2.80731 10.6742 2.73733 10.6742 2.66665C10.6742 2.59597 10.6602 2.526 10.6329 2.46079C10.6056 2.39559 10.5656 2.33646 10.5153 2.28683C10.465 2.23721 10.4053 2.19808 10.3397 2.17173C10.2741 2.14538 10.204 2.13232 10.1333 2.13332H8.66349C8.61807 2.12555 8.57207 2.12171 8.52599 2.12186Z" /> </svg> ); } function UnderlineIcon(props: React.ComponentProps<'svg'>) { return ( <svg width="16" height="16" viewBox="0 0 16 16" fill="currentcolor" {...props}> <path d="M3.73331 2.13332C3.66264 2.13232 3.59247 2.14538 3.52689 2.17173C3.46131 2.19809 3.40161 2.23721 3.35128 2.28684C3.30095 2.33646 3.26099 2.39559 3.23371 2.4608C3.20643 2.526 3.19238 2.59598 3.19238 2.66666C3.19238 2.73734 3.20643 2.80731 3.23371 2.87252C3.26099 2.93772 3.30095 2.99685 3.35128 3.04648C3.40161 3.0961 3.46131 3.13523 3.52689 3.16158C3.59247 3.18793 3.66264 3.20099 3.73331 3.19999V7.99999C3.73331 10.224 5.55144 12.2667 7.99998 12.2667C10.4485 12.2667 12.2666 10.224 12.2666 7.99999V3.19999C12.3373 3.20099 12.4075 3.18793 12.4731 3.16158C12.5386 3.13523 12.5983 3.0961 12.6487 3.04648C12.699 2.99685 12.739 2.93772 12.7662 2.87252C12.7935 2.80731 12.8076 2.73734 12.8076 2.66666C12.8076 2.59598 12.7935 2.526 12.7662 2.4608C12.739 2.39559 12.699 2.33646 12.6487 2.28684C12.5983 2.23721 12.5386 2.19809 12.4731 2.17173C12.4075 2.14538 12.3373 2.13232 12.2666 2.13332H10.1333C10.0626 2.13232 9.99247 2.14538 9.92689 2.17173C9.8613 2.19809 9.80161 2.23721 9.75128 2.28684C9.70095 2.33646 9.66099 2.39559 9.63371 2.4608C9.60643 2.526 9.59238 2.59598 9.59238 2.66666C9.59238 2.73734 9.60643 2.80731 9.63371 2.87252C9.66099 2.93772 9.70095 2.99685 9.75128 3.04648C9.80161 3.0961 9.8613 3.13523 9.92689 3.16158C9.99247 3.18793 10.0626 3.20099 10.1333 3.19999V8.97187C10.1333 10.0855 9.32179 11.0818 8.21352 11.1896C6.94152 11.3138 5.86665 10.3136 5.86665 9.06666V3.19999C5.93732 3.20099 6.00748 3.18793 6.07307 3.16158C6.13865 3.13523 6.19834 3.0961 6.24867 3.04648C6.299 2.99685 6.33897 2.93772 6.36625 2.87252C6.39353 2.80731 6.40757 2.73734 6.40757 2.66666C6.40757 2.59598 6.39353 2.526 6.36625 2.4608C6.33897 2.39559 6.299 2.33646 6.24867 2.28684C6.19834 2.23721 6.13865 2.19809 6.07307 2.17173C6.00748 2.14538 5.93732 2.13232 5.86665 2.13332H3.73331ZM3.73331 13.3333C3.66264 13.3323 3.59247 13.3454 3.52689 13.3717C3.46131 13.3981 3.40161 13.4372 3.35128 13.4868C3.30095 13.5365 3.26099 13.5956 3.23371 13.6608C3.20643 13.726 3.19238 13.796 3.19238 13.8667C3.19238 13.9373 3.20643 14.0073 3.23371 14.0725C3.26099 14.1377 3.30095 14.1969 3.35128 14.2465C3.40161 14.2961 3.46131 14.3352 3.52689 14.3616C3.59247 14.3879 3.66264 14.401 3.73331 14.4H12.2666C12.3373 14.401 12.4075 14.3879 12.4731 14.3616C12.5386 14.3352 12.5983 14.2961 12.6487 14.2465C12.699 14.1969 12.739 14.1377 12.7662 14.0725C12.7935 14.0073 12.8076 13.9373 12.8076 13.8667C12.8076 13.796 12.7935 13.726 12.7662 13.6608C12.739 13.5956 12.699 13.5365 12.6487 13.4868C12.5983 13.4372 12.5386 13.3981 12.4731 13.3717C12.4075 13.3454 12.3373 13.3323 12.2666 13.3333H3.73331Z" /> </svg> ); } Show code ## Accessibility guidelines To ensure that tooltips are accessible and helpful, follow these guidelines: * **Provide an accessible name for the trigger**: The tooltip’s trigger must have a meaningful label. This can be its visible text or an `aria-label`/`aria-labelledby` attribute. The label should closely match the tooltip’s content to ensure consistency for screen reader users. * **Avoid tooltips for critical information**: Tooltips work well for enhancing UI clarity (like labeling icon buttons) but should not be the sole means of conveying important information. Since tooltips do not appear on touch devices, consider using a Popover for essential content. * **Avoid tooltips for “infotips”**: If your tooltip is attached to an “info icon” button whose only purpose is to show the tooltip, opt for Popover and add the `openOnHover` prop instead. Tooltips should describe an element that performs an action separate from opening the tooltip itself. ## Anatomy Import the component and assemble its parts: Anatomy Copy import { Tooltip } from '@base-ui-components/react/tooltip'; <Tooltip.Provider> <Tooltip.Root> <Tooltip.Trigger /> <Tooltip.Portal> <Tooltip.Positioner> <Tooltip.Popup> <Tooltip.Arrow /> </Tooltip.Popup> </Tooltip.Positioner> </Tooltip.Portal> </Tooltip.Root> </Tooltip.Provider> ## API reference ### Provider Provides a shared delay for multiple tooltips. The grouping logic ensures that once a tooltip becomes visible, the adjacent tooltips will be shown instantly. | Prop | Type | Default | | | --- | --- | --- | --- | | `delay` | `number` | `undefined` | | | `closeDelay` | `number` | `undefined` | | | `timeout` | `number` | `400` | | | `children` | `ReactNode` | `undefined` | | ### Root Groups all parts of the tooltip. Doesn’t render its own HTML element. | Prop | Type | Default | | | --- | --- | --- | --- | | `defaultOpen` | `boolean` | `false` | | | `open` | `boolean` | `undefined` | | | `onOpenChange` | `(open: boolean, event?: Event, reason?: Tooltip.Root.OpenChangeReason) => void` | `undefined` | | | `actionsRef` | `RefObject<Actions>` | `undefined` | | | `onOpenChangeComplete` | `((open: boolean) => void)` | `undefined` | | | `trackCursorAxis` | `'none' | 'both' | 'x' | 'y'` | `'none'` | | | `disabled` | `boolean` | `false` | | | `delay` | `number` | `600` | | | `closeDelay` | `number` | `0` | | | `hoverable` | `boolean` | `true` | | | `children` | `ReactNode` | `undefined` | | ### Trigger An element to attach the tooltip to. Renders a `<button>` element. | Prop | Type | Default | | | --- | --- | --- | --- | | `className` | `| string | ((state: Tooltip.Trigger.State) => string)` | `undefined` | | | `render` | `| ReactElement | ((props: HTMLProps, state: Tooltip.Trigger.State) => ReactElement)` | `undefined` | | | Attribute | Description | | | --- | --- | --- | | `data-popup-open` | Present when the corresponding tooltip is open. | ### Portal A portal element that moves the popup to a different part of the DOM. By default, the portal element is appended to `<body>`. | Prop | Type | Default | | | --- | --- | --- | --- | | `container` | `| HTMLElement | RefObject<HTMLElement | null> | null` | `undefined` | | | `children` | `ReactNode` | `undefined` | | | `keepMounted` | `boolean` | `false` | | ### Positioner Positions the tooltip against the trigger. Renders a `<div>` element. | Prop | Type | Default | | | --- | --- | --- | --- | | `collisionAvoidance` | `CollisionAvoidance` | `undefined` | | | `align` | `'center' | 'start' | 'end'` | `'center'` | | | `alignOffset` | `number | OffsetFunction` | `0` | | | `side` | `Side` | `'top'` | | | `sideOffset` | `number | OffsetFunction` | `0` | | | `arrowPadding` | `number` | `5` | | | `anchor` | `| Element | RefObject<Element | null> | VirtualElement | (() => Element | VirtualElement | null) | null` | `undefined` | | | `collisionBoundary` | `Boundary` | `'clipping-ancestors'` | | | `collisionPadding` | `Padding` | `5` | | | `sticky` | `boolean` | `false` | | | `positionMethod` | `'fixed' | 'absolute'` | `'absolute'` | | | `trackAnchor` | `boolean` | `true` | | | `className` | `| string | ((state: Tooltip.Positioner.State) => string)` | `undefined` | | | `render` | `| ReactElement | ((props: HTMLProps, state: Tooltip.Positioner.State) => ReactElement)` | `undefined` | | | Attribute | Description | | | --- | --- | --- | | `data-open` | Present when the tooltip is open. | | `data-closed` | Present when the tooltip is closed. | | `data-anchor-hidden` | Present when the anchor is hidden. | | `data-align` | Indicates how the popup is aligned relative to specified side. | | `data-side` | Indicates which side the popup is positioned relative to the trigger. | | CSS Variable | Description | | | --- | --- | --- | | `--anchor-height` | The anchor's height. | | `--anchor-width` | The anchor's width. | | `--available-height` | The available height between the trigger and the edge of the viewport. | | `--available-width` | The available width between the trigger and the edge of the viewport. | | `--transform-origin` | The coordinates that this element is anchored to. Used for animations and transitions. | ### Popup A container for the tooltip contents. Renders a `<div>` element. | Prop | Type | Default | | | --- | --- | --- | --- | | `className` | `| string | ((state: Tooltip.Popup.State) => string)` | `undefined` | | | `render` | `| ReactElement | ((props: HTMLProps, state: Tooltip.Popup.State) => ReactElement)` | `undefined` | | | Attribute | Description | | | --- | --- | --- | | `data-open` | Present when the tooltip is open. | | `data-closed` | Present when the tooltip is closed. | | `data-align` | Indicates how the popup is aligned relative to specified side. | | `data-instant` | Present if animations should be instant. | | `data-side` | Indicates which side the popup is positioned relative to the trigger. | | `data-starting-style` | Present when the tooltip is animating in. | | `data-ending-style` | Present when the tooltip is animating out. | ### Arrow Displays an element positioned against the tooltip anchor. Renders a `<div>` element. | Prop | Type | Default | | | --- | --- | --- | --- | | `className` | `| string | ((state: Tooltip.Arrow.State) => string)` | `undefined` | | | `render` | `| ReactElement | ((props: HTMLProps, state: Tooltip.Arrow.State) => ReactElement)` | `undefined` | | | Attribute | Description | | | --- | --- | --- | | `data-open` | Present when the tooltip is open. | | `data-closed` | Present when the tooltip is closed. | | `data-uncentered` | Present when the tooltip arrow is uncentered. | | `data-anchor-hidden` | Present when the anchor is hidden. | | `data-align` | Indicates how the popup is aligned relative to specified side. | | `data-side` | Indicates which side the popup is positioned relative to the trigger. | --- ## Page: https://base-ui.com/react/utils/use-render useRender * (Top) * API reference * Input parameters * Return value * Examples * Merging props * Merging refs * TypeScript * Migrating from Radix UI # useRender Hook for enabling a render prop in custom components. The `useRender` hook lets you build custom components that provide a `render` prop to override the default rendered element. ## API reference ### Input parameters | Prop | Type | Default | | | --- | --- | --- | --- | | `render` | `RenderProp<State>` | `undefined` | | | `props` | `Record<string, unknown>` | `undefined` | | | `ref` | `| React.Ref<RenderedElementType> | React.Ref<RenderedElementType>[]` | `undefined` | | | `state` | `State` | `undefined` | | ### Return value | Prop | Type | | | --- | --- | --- | | `element` | `React.ReactElement` | | Usage Copy const element = useRender({ // Input parameters }); ## Examples A `render` prop for a custom Text component lets consumers use it to replace the default rendered `p` element with a different tag or component. Text component rendered as a paragraph tag **Text component rendered as a strong tag** index.tsxindex.module.csstheme.css CodeSandboxCopy 'use client'; import * as React from 'react'; import { useRender } from '@base-ui-components/react/use-render'; import { mergeProps } from '@base-ui-components/react/merge-props'; import styles from './index.module.css'; interface TextProps extends useRender.ComponentProps<'p'> {} function Text(props: TextProps) { const { render = <p />, ...otherProps } = props; const element = useRender({ render, props: mergeProps<'p'>({ className: styles.Text }, otherProps), }); return element; } export default function ExampleText() { return ( <div> <Text>Text component rendered as a paragraph tag</Text> <Text render={<strong />}>Text component rendered as a strong tag</Text> </div> ); } Show code The callback version of the `render` prop enables more control of how props are spread, and also passes the internal `state` of a component. Counter: 0👍 index.tsxindex.module.csstheme.css CodeSandboxCopy 'use client'; import * as React from 'react'; import { useRender } from '@base-ui-components/react/use-render'; import { mergeProps } from '@base-ui-components/react/merge-props'; import styles from './index.module.css'; interface CounterState { odd: boolean; } interface CounterProps extends useRender.ComponentProps<'button', CounterState> {} function Counter(props: CounterProps) { const { render = <button />, ...otherProps } = props; const [count, setCount] = React.useState(0); const odd = count % 2 === 1; const state = React.useMemo(() => ({ odd }), [odd]); const defaultProps: useRender.ElementProps<'button'> = { className: styles.Button, type: 'button', children: ( <React.Fragment> Counter: <span>{count}</span> </React.Fragment> ), onClick() { setCount((prev) => prev + 1); }, 'aria-label': `Count is ${count}, click to increase.`, }; const element = useRender({ render, state, props: mergeProps<'button'>(defaultProps, otherProps), }); return element; } export default function ExampleCounter() { return ( <Counter render={(props, state) => ( <button {...props}> {props.children} <span className={styles.suffix}>{state.odd ? '👎' : '👍'}</span> </button> )} /> ); } Show code ## Merging props The `mergeProps` function merges two or more sets of React props together. It safely merges three types of props: 1. Event handlers, so that all are invoked 2. `className` strings 3. `style` properties `mergeProps` merges objects from left to right, so that subsequent objects’ properties in the arguments overwrite previous ones. Merging props is useful when creating custom components, as well as inside the callback version of the `render` prop for any Base UI component. Using mergeProps in the render callback Copy import { mergeProps } from '@base-ui-components/react/merge-props'; import styles from './index.module.css'; function Button() { return ( <Component render={(props, state) => ( <button {...mergeProps<'button'>(props, { className: styles.Button, })} /> )} /> ); } ## Merging refs When building custom components, you often need to control a ref internally while still letting external consumers pass their own—merging refs lets both parties have access to the underlying DOM element. The `ref` option in `useRender` enables this, which holds an array of refs to be merged together. In React 19, `React.forwardRef()` is not needed when building primitive components, as the external ref prop is already contained inside `props`. Your internal ref can be passed to `ref` to be merged with `props.ref`: React 19 Copy function Text({ render = <p />, ...props }: TextProps) { const internalRef = React.useRef<HTMLElement | null>(null); const element = useRender({ ref: internalRef, props, render, }); return element; } In older versions of React, you need to use `React.forwardRef()` and add the forwarded ref to the `ref` array along with your own internal ref. The examples above assume React 19, and should be modified to use `React.forwardRef()` to support React 18 and 17. React 18 and 17 Copy const Text = React.forwardRef(function Text( { render = <p />, ...props }: TextProps, forwardedRef: React.ForwardedRef<HTMLElement>, ) { const internalRef = React.useRef<HTMLElement | null>(null); const element = useRender({ ref: [forwardedRef, internalRef], props, render, }); return element; }); ## TypeScript To type props, there are two interfaces: * `useRender.ComponentProps` for a component’s external (public) props. It types the `render` prop and HTML attributes. * `useRender.ElementProps` for the element’s internal (private) props. It types HTML attributes alone. Typing props Copy interface ButtonProps extends useRender.ComponentProps<'button'> {} function Button({ render = <button />, ...props }: ButtonProps) { const defaultProps: useRender.ElementProps<'button'> = { className: styles.Button, type: 'button', children: 'Click me', }; const element = useRender({ render, props: mergeProps<'button'>(defaultProps, props), }); return element; } ## Migrating from Radix UI Radix UI uses an `asChild` prop, while Base UI uses a `render` prop. Learn more about how composition works in Base UI in the composition guide. In Radix UI, the `Slot` component lets you implement an `asChild` prop. Radix UI Slot component Copy import { Slot } from 'radix-ui'; function Button({ asChild, ...props }) { const Comp = asChild ? Slot.Root : 'button'; return <Comp {...props} />; } // Usage <Button asChild> <a href="/contact">Contact</a> </Button> In Base UI, `useRender` lets you implement a `render` prop. The example below is the equivalent implementation to the Radix example above. Base UI render prop Copy import { useRender } from '@base-ui-components/react/use-render'; function Button({ render = <button />, ...props }) { return useRender({ render, props }); } // Usage <Button render={<a href="/contact">Contact</a>} />