Base UI is a library of headless React components and low-level hooks for building accessible, customizable user interfaces.
npx @tessl/cli install tessl/npm-base-ui-components--react@1.0.0Base UI is a comprehensive library of headless ('unstyled') React components and low-level hooks. You gain complete control over your app's CSS and accessibility features while maintaining full keyboard navigation and screen reader support.
npm install @base-ui-components/reactimport {
AccordionRoot,
DialogRoot,
MenuRoot,
FieldRoot,
AlertDialogRoot,
ToastProvider,
SliderRoot,
// ... other components
} from "@base-ui-components/react";Individual component imports:
import { AccordionRoot, AccordionItem } from "@base-ui-components/react/accordion";
import { DialogRoot, DialogTrigger } from "@base-ui-components/react/dialog";
import { MenuRoot, MenuItem } from "@base-ui-components/react/menu";
import { AlertDialogRoot, AlertDialogTrigger } from "@base-ui-components/react/alert-dialog";
import { ToastProvider, ToastRoot } from "@base-ui-components/react/toast";For CommonJS:
const { AccordionRoot, DialogRoot, MenuRoot } = require("@base-ui-components/react");import {
AccordionRoot,
AccordionItem,
AccordionHeader,
AccordionTrigger,
AccordionPanel
} from "@base-ui-components/react/accordion";
function MyAccordion() {
return (
<AccordionRoot defaultValue={['item-1']}>
<AccordionItem value="item-1">
<AccordionHeader>
<AccordionTrigger>Section 1</AccordionTrigger>
</AccordionHeader>
<AccordionPanel>Content for section 1</AccordionPanel>
</AccordionItem>
<AccordionItem value="item-2">
<AccordionHeader>
<AccordionTrigger>Section 2</AccordionTrigger>
</AccordionHeader>
<AccordionPanel>Content for section 2</AccordionPanel>
</AccordionItem>
</AccordionRoot>
);
}Base UI follows a headless component pattern with several key architectural principles:
DialogRoot, DialogTrigger, DialogPopup)Foundation components for organizing content and creating collapsible sections.
// Accordion - Collapsible content sections
interface AccordionRootProps {
value?: AccordionValue;
defaultValue?: AccordionValue;
disabled?: boolean;
hiddenUntilFound?: boolean;
keepMounted?: boolean;
loop?: boolean;
openMultiple?: boolean;
orientation?: 'horizontal' | 'vertical';
onValueChange?: (value: AccordionValue, details: AccordionRoot.ChangeEventDetails) => void;
}
type AccordionValue = (string | number | null)[];
// Collapsible - Simple show/hide content
interface CollapsibleRootProps {
open?: boolean;
defaultOpen?: boolean;
onOpenChange?: (open: boolean, details: CollapsibleOpenChangeDetails) => void;
}
// Tabs - Tab navigation
interface TabsRootProps {
value?: string;
defaultValue?: string;
orientation?: 'horizontal' | 'vertical';
onValueChange?: (value: string, details: TabsValueChangeDetails) => void;
}
// Separator - Visual divider
interface SeparatorProps {
orientation?: 'horizontal' | 'vertical';
}Modal and non-modal overlay components for focused interactions and contextual information.
// Dialog - Modal dialog
interface DialogRootProps {
open?: boolean;
defaultOpen?: boolean;
modal?: boolean;
dismissible?: boolean;
onOpenChange?: (open: boolean, details: DialogOpenChangeDetails) => void;
}
// Alert Dialog - Confirmation dialog
interface AlertDialogRootProps {
open?: boolean;
defaultOpen?: boolean;
onOpenChange?: (open: boolean, details: AlertDialogRoot.ChangeEventDetails) => void;
onOpenChangeComplete?: (open: boolean) => void;
actionsRef?: React.RefObject<AlertDialogRoot.Actions>;
}
// Popover - Non-modal overlay
interface PopoverRootProps {
open?: boolean;
defaultOpen?: boolean;
onOpenChange?: (open: boolean, details: PopoverOpenChangeDetails) => void;
}
// Tooltip - Informational tooltip
interface TooltipRootProps {
open?: boolean;
defaultOpen?: boolean;
delay?: number;
closeDelay?: number;
onOpenChange?: (open: boolean, details: TooltipOpenChangeDetails) => void;
}
// Preview Card - Hover card with content preview
interface PreviewCardRootProps {
open?: boolean;
defaultOpen?: boolean;
openDelay?: number;
closeDelay?: number;
onOpenChange?: (open: boolean, details: PreviewCardOpenChangeDetails) => void;
}
// Toast - Notification messages
interface ToastRootProps {
toast: ToastRoot.ToastObject;
swipeDirection?: 'up' | 'down' | 'left' | 'right' | ('up' | 'down' | 'left' | 'right')[];
}
interface ToastProviderProps {
limit?: number;
gap?: number;
duration?: number;
pauseOnHover?: boolean;
pauseOnFocus?: boolean;
}Menu systems and navigation components with full keyboard support and ARIA compliance.
// Menu - Dropdown menu
interface MenuRootProps {
open?: boolean;
defaultOpen?: boolean;
onOpenChange?: (open: boolean, details: MenuOpenChangeDetails) => void;
}
// Navigation Menu - Hierarchical navigation
interface NavigationMenuRootProps {
value?: string;
defaultValue?: string;
onValueChange?: (value: string, details: NavigationMenuValueChangeDetails) => void;
}
// Context Menu - Right-click menu
interface ContextMenuRootProps {
open?: boolean;
defaultOpen?: boolean;
onOpenChange?: (open: boolean, details: ContextMenuOpenChangeDetails) => void;
}
// Menubar - Menu bar navigation
interface MenubarRootProps {
disabled?: boolean;
orientation?: 'horizontal' | 'vertical';
}
// Toolbar - Tool/button bar
interface ToolbarRootProps {
disabled?: boolean;
orientation?: 'horizontal' | 'vertical';
}Form controls with validation, labeling, and accessibility features built-in.
// Field - Form field wrapper
interface FieldRootProps {
name?: string;
invalid?: boolean;
required?: boolean;
disabled?: boolean;
}
// Fieldset - Form field grouping
interface FieldsetRootProps {
disabled?: boolean;
}
// Form - Form validation and submission
interface FormProps {
errors?: FormContext['errors'];
onClearErrors?: (errors: FormContext['errors']) => void;
}
// Input - Text input
interface InputProps {
value?: string;
defaultValue?: string;
placeholder?: string;
required?: boolean;
disabled?: boolean;
readOnly?: boolean;
onValueChange?: (value: string, details: InputValueChangeDetails) => void;
}
// Number Field - Numeric input with increment/decrement
interface NumberFieldRootProps {
value?: number | null;
defaultValue?: number;
min?: number;
max?: number;
step?: number;
largeStep?: number;
smallStep?: number;
required?: boolean;
disabled?: boolean;
readOnly?: boolean;
allowWheelScrub?: boolean;
snapOnStep?: boolean;
format?: Intl.NumberFormatOptions;
locale?: Intl.LocalesArgument;
onValueChange?: (value: number | null, details: NumberFieldRoot.ChangeEventDetails) => void;
}
// Select - Selection dropdown
interface SelectRootProps<T> {
value?: T;
defaultValue?: T;
multiple?: boolean;
placeholder?: string;
onValueChange?: (value: T, details: SelectValueChangeDetails<T>) => void;
}
// Combobox - Combined input and listbox
interface ComboboxRootProps<ItemValue> {
items?: ItemValue[] | Group<ItemValue>[];
value?: ItemValue;
defaultValue?: ItemValue;
multiple?: boolean;
itemToStringLabel?: (itemValue: ItemValue) => string;
itemToStringValue?: (itemValue: ItemValue) => string;
onValueChange?: (value: ItemValue, details: ComboboxRoot.ChangeEventDetails) => void;
filter?: ((itemValue: ItemValue, query: string, itemToStringLabel?: (itemValue: ItemValue) => string) => boolean) | null;
virtualized?: boolean;
modal?: boolean;
limit?: number;
}
// Autocomplete - Typeahead functionality
interface AutocompleteRootProps<ItemValue> {
mode?: 'list' | 'both' | 'inline' | 'none';
value?: string;
defaultValue?: string;
items?: ItemValue[] | Group<ItemValue>[];
itemToStringValue?: (itemValue: ItemValue) => string;
onValueChange?: (value: string, details: AutocompleteRoot.ChangeEventDetails) => void;
filter?: ((itemValue: ItemValue, query: string, itemToStringLabel?: (itemValue: ItemValue) => string) => boolean) | null;
autoHighlight?: boolean;
openOnInputClick?: boolean;
}Button-like components for user interactions and selections.
// Toggle - Toggle button
interface ToggleRootProps {
pressed?: boolean;
defaultPressed?: boolean;
disabled?: boolean;
onPressedChange?: (pressed: boolean, details: TogglePressedChangeDetails) => void;
}
// Toggle Group - Group of toggle buttons
interface ToggleGroupProps {
value?: string[];
defaultValue?: string[];
toggleMultiple?: boolean;
disabled?: boolean;
orientation?: 'horizontal' | 'vertical';
loop?: boolean;
onValueChange?: (value: string[], details: ToggleGroup.ChangeEventDetails) => void;
}
// Switch - Toggle switch
interface SwitchRootProps {
checked?: boolean;
defaultChecked?: boolean;
disabled?: boolean;
required?: boolean;
onCheckedChange?: (checked: boolean, details: SwitchCheckedChangeDetails) => void;
}
// Checkbox - Checkbox input
interface CheckboxRootProps {
checked?: boolean | 'indeterminate';
defaultChecked?: boolean;
disabled?: boolean;
required?: boolean;
onCheckedChange?: (checked: boolean | 'indeterminate', details: CheckboxCheckedChangeDetails) => void;
}
// Checkbox Group - Group of checkboxes
interface CheckboxGroupProps {
value?: string[];
defaultValue?: string[];
disabled?: boolean;
onValueChange?: (value: string[], details: CheckboxGroupChangeDetails) => void;
}
// Radio - Radio button
interface RadioRootProps {
value?: any;
disabled?: boolean;
required?: boolean;
readOnly?: boolean;
}
// Radio Group - Group of radio buttons
interface RadioGroupProps {
value?: any;
defaultValue?: any;
disabled?: boolean;
required?: boolean;
readOnly?: boolean;
name?: string;
onValueChange?: (value: any, details: RadioGroup.ChangeEventDetails) => void;
}Components for displaying progress, measurements, and user information.
// Progress - Progress indicator
interface ProgressRootProps {
value?: number;
max?: number;
getValueLabel?: (value: number, max: number) => string;
}
// Meter - Measurement display
interface MeterRootProps {
value: number;
min?: number;
max?: number;
optimum?: number;
low?: number;
high?: number;
getValueLabel?: (value: number, min: number, max: number) => string;
}
// Avatar - User avatar display
interface AvatarRootProps {
src?: string;
alt?: string;
fallback?: string;
}
// Slider - Range/value slider
interface SliderRootProps<Value extends number | readonly number[] = number | readonly number[]> {
value?: Value;
defaultValue?: Value;
min?: number;
max?: number;
step?: number;
largeStep?: number;
minStepsBetweenValues?: number;
disabled?: boolean;
orientation?: 'horizontal' | 'vertical';
format?: Intl.NumberFormatOptions;
locale?: Intl.LocalesArgument;
onValueChange?: (value: Value extends number ? number : Value, details: SliderRoot.ChangeEventDetails, activeThumbIndex: number) => void;
onValueCommitted?: (value: Value extends number ? number : Value, details: SliderRoot.ChangeEventDetails) => void;
}
// Scroll Area - Custom scrollable areas
interface ScrollAreaRootProps {
children?: React.ReactNode;
}
interface ScrollAreaViewportProps {
children?: React.ReactNode;
}
interface ScrollAreaScrollbarProps {
orientation: 'horizontal' | 'vertical';
}Utility functions and hooks for advanced component composition and customization.
// Merge Props - Combine props objects
function mergeProps<T extends Record<string, any>>(...sources: T[]): T;
// Use Render - Custom render prop hook
function useRender<T>(render?: RenderProp<T>): (props: T) => React.ReactNode;
// Direction Provider - RTL/LTR context
interface DirectionProviderProps {
direction?: 'ltr' | 'rtl';
}
// Media Query - Responsive hook (unstable)
function useMediaQuery(query: string): boolean;
// No SSR - Prevent server-side rendering (unstable)
interface NoSsrProps {
children?: React.ReactNode;
defer?: boolean;
fallback?: React.ReactNode;
}// Common event detail types
interface BaseUIEventDetails<T> {
reason: T;
nativeEvent: Event | null;
isCanceled: boolean;
}
interface OpenChangeDetails {
open: boolean;
}
interface ValueChangeDetails<T> {
value: T;
}
// Render prop types
type RenderProp<T> = (props: T) => React.ReactNode;
// Orientation type
type Orientation = 'horizontal' | 'vertical';
// Direction type
type Direction = 'ltr' | 'rtl';
// Transition status type
type TransitionStatus = 'starting' | 'ending' | undefined;
// Common change event reasons
type BaseUIChangeEventReason =
| 'trigger-press'
| 'trigger-hover'
| 'trigger-focus'
| 'focus-out'
| 'escape-key'
| 'outside-press'
| 'list-navigation'
| 'item-press'
| 'cancel-open'
| 'none';
// Form context type
interface FormContext {
errors: Record<string, string[]>;
}
// Group type for select/combobox items
interface Group<T> {
label: string;
items: T[];
}
// Component render function type
type ComponentRenderFn<TProps, TState> = (
props: TProps,
state: TState
) => React.ReactElement | null;
// Base component props interface
interface BaseUIComponentProps<ElementType extends React.ElementType, State> {
className?: string | ((state: State) => string);
render?: ComponentRenderFn<React.ComponentProps<ElementType>, State> | React.ReactElement<Record<string, unknown>>;
}