Library of headless React components and low-level hooks for building accessible user interfaces
—
Pending
Does it follow best practices?
Impact
Pending
No eval scenarios have been run
Pending
The risk profile of this skill
React hooks and utility functions for building custom components with MUI Base behavior, including CSS class generation, prop merging, and component state management.
Provides button behavior including focus management, accessibility, and event handling.
/**
* Button behavior hook with accessibility and focus management
* @param parameters - Button configuration including disabled state and element type
* @returns Props getters and state for button functionality
*/
function useButton(parameters: UseButtonParameters): UseButtonReturnValue;
interface UseButtonParameters {
/** Whether button is disabled */
disabled?: boolean;
/** Whether button is focusable when disabled */
focusableWhenDisabled?: boolean;
/** Href for link-style buttons */
href?: string;
/** Ref for root element */
rootRef?: React.Ref<Element>;
/** Tab index override */
tabIndex?: number;
/** Router link destination */
to?: string;
/** Button type attribute */
type?: React.ButtonHTMLAttributes<HTMLButtonElement>['type'];
/** Root element name for polymorphic behavior */
rootElementName?: string;
}
interface UseButtonReturnValue {
/** Props getter for root button element */
getRootProps: <ExternalProps extends Record<string, any> = {}>(
externalProps?: ExternalProps
) => UseButtonRootSlotProps<ExternalProps>;
/** Ref callback for root element */
rootRef: React.RefCallback<Element>;
/** Whether button is currently active (pressed) */
active: boolean;
/** Whether button has visible focus indicator */
focusVisible: boolean;
/** Whether button is disabled */
disabled: boolean;
}
interface UseButtonRootSlotProps<ExternalProps = {}> extends ExternalProps {
'aria-disabled'?: boolean;
'aria-pressed'?: boolean;
disabled?: boolean;
href?: string;
role?: React.AriaRole;
tabIndex?: number;
type?: React.ButtonHTMLAttributes<HTMLButtonElement>['type'];
onBlur: React.FocusEventHandler;
onClick: React.MouseEventHandler;
onFocus: React.FocusEventHandler;
onKeyDown: React.KeyboardEventHandler;
onKeyUp: React.KeyboardEventHandler;
onMouseDown: React.MouseEventHandler;
onMouseLeave: React.MouseEventHandler;
}Manages input state and integrates with FormControl context.
/**
* Input state management hook with form control integration
* @param parameters - Input configuration including value and validation
* @returns Props getters and state for input functionality
*/
function useInput(parameters: UseInputParameters): UseInputReturnValue;
interface UseInputParameters {
/** Default input value */
defaultValue?: unknown;
/** Whether input is disabled */
disabled?: boolean;
/** Whether input has validation error */
error?: boolean;
/** Change event handler */
onChange?: React.ChangeEventHandler<HTMLInputElement>;
/** Whether input is required */
required?: boolean;
/** Current input value */
value?: unknown;
}
interface UseInputReturnValue {
/** Props getter for root container */
getRootProps: () => UseInputRootSlotProps;
/** Props getter for input element */
getInputProps: () => UseInputInputSlotProps;
/** Whether input is currently focused */
focused: boolean;
/** Form control context state */
formControlContext: FormControlState | undefined;
/** Whether input has error */
error: boolean;
/** Whether input is disabled */
disabled: boolean;
/** Whether input is required */
required: boolean;
/** Current input value */
value: unknown;
}
interface UseInputRootSlotProps {
onClick: React.MouseEventHandler;
}
interface UseInputInputSlotProps {
'aria-describedby'?: string;
'aria-invalid'?: boolean;
'aria-required'?: boolean;
disabled?: boolean;
value?: unknown;
onBlur: React.FocusEventHandler<HTMLInputElement>;
onChange: React.ChangeEventHandler<HTMLInputElement>;
onFocus: React.FocusEventHandler<HTMLInputElement>;
}Comprehensive autocomplete functionality with filtering, selection, and keyboard navigation.
/**
* Complete autocomplete/combobox functionality hook
* @param props - Autocomplete configuration including options and behavior
* @returns State and props getters for autocomplete functionality
*/
function useAutocomplete<Value, Multiple, DisableClearable, FreeSolo>(
props: UseAutocompleteProps<Value, Multiple, DisableClearable, FreeSolo>
): UseAutocompleteReturnValue<Value, Multiple, DisableClearable, FreeSolo>;
interface UseAutocompleteProps<Value, Multiple, DisableClearable, FreeSolo> {
/** Available options */
options: Value[];
/** Whether multiple selection is allowed */
multiple?: Multiple;
/** Current value */
value?: AutocompleteValue<Value, Multiple, DisableClearable, FreeSolo>;
/** Default value */
defaultValue?: AutocompleteValue<Value, Multiple, DisableClearable, FreeSolo>;
/** Value change handler */
onChange?: (event: React.SyntheticEvent, value: AutocompleteValue<Value, Multiple, DisableClearable, FreeSolo>, reason: AutocompleteChangeReason, details?: AutocompleteChangeDetails<Value>) => void;
/** Input value for filtering */
inputValue?: string;
/** Input value change handler */
onInputChange?: (event: React.SyntheticEvent, value: string, reason: AutocompleteInputChangeReason) => void;
/** Function to get option label */
getOptionLabel?: (option: Value) => string;
/** Function to get option key */
getOptionKey?: (option: Value) => string | number;
/** Function to compare option equality */
isOptionEqualToValue?: (option: Value, value: Value) => boolean;
/** Function to filter options */
filterOptions?: (options: Value[], state: FilterOptionsState<Value>) => Value[];
/** Whether to auto-complete on input */
autoComplete?: boolean;
/** Whether to auto-highlight first option */
autoHighlight?: boolean;
/** Whether to auto-select highlighted option */
autoSelect?: boolean;
/** When to trigger blur on selection */
blurOnSelect?: 'touch' | 'mouse' | true | false;
/** Whether to clear input on blur */
clearOnBlur?: boolean;
/** Whether to clear input on escape */
clearOnEscape?: boolean;
/** Whether clear button is disabled */
disableClearable?: DisableClearable;
/** Whether to close on selection */
disableCloseOnSelect?: boolean;
/** Whether autocomplete is disabled */
disabled?: boolean;
/** Whether disabled items are focusable */
disabledItemsFocusable?: boolean;
/** Whether list wrapping is disabled */
disableListWrap?: boolean;
/** Whether to filter selected options from list */
filterSelectedOptions?: boolean;
/** Whether free text input is allowed */
freeSolo?: FreeSolo;
/** Whether to handle home/end keys */
handleHomeEndKeys?: boolean;
/** Whether to include input in list navigation */
includeInputInList?: boolean;
/** Whether to open on focus */
openOnFocus?: boolean;
/** Whether autocomplete is read-only */
readOnly?: boolean;
/** Whether to select text on focus */
selectOnFocus?: boolean;
}
interface UseAutocompleteReturnValue<Value, Multiple, DisableClearable, FreeSolo> {
/** Props getter for root container */
getRootProps: () => object;
/** Props getter for input element */
getInputProps: () => object;
/** Props getter for input label */
getInputLabelProps: () => object;
/** Props getter for clear button */
getClearProps: () => object;
/** Props getter for popup indicator */
getPopupIndicatorProps: () => object;
/** Props getter for tag elements */
getTagProps: (params: { index: number }) => object;
/** Props getter for listbox container */
getListboxProps: () => object;
/** Props getter for option elements */
getOptionProps: (params: { option: Value; index: number }) => object;
/** Current autocomplete value */
value: AutocompleteValue<Value, Multiple, DisableClearable, FreeSolo>;
/** Whether input has been modified */
dirty: boolean;
/** Whether popup is expanded */
expanded: boolean;
/** Autocomplete ID */
id: string;
/** Current input value */
inputValue: string;
/** Whether input is focused */
focused: boolean;
/** Index of focused tag (-1 if none) */
focusedTag: number;
/** Anchor element for popup */
anchorEl: null | HTMLElement;
/** Function to set anchor element */
setAncherEl: () => void;
/** Options grouped for display */
groupedOptions: Array<Value | AutocompleteGroupedOption<Value>>;
/** Whether popup is open */
popupOpen: boolean;
}
type AutocompleteValue<Value, Multiple, DisableClearable, FreeSolo> =
Multiple extends true
? Value[]
: DisableClearable extends true
? Value
: Value | null;
type AutocompleteChangeReason = 'createOption' | 'selectOption' | 'removeOption' | 'blur' | 'clear';
type AutocompleteInputChangeReason = 'input' | 'reset' | 'clear';
interface AutocompleteChangeDetails<Value> {
option: Value;
}
interface FilterOptionsState<Value> {
inputValue: string;
getOptionLabel: (option: Value) => string;
}
interface AutocompleteGroupedOption<Value> {
key: string;
index: number;
group: string;
options: Value[];
}/**
* Generates CSS class names following Base UI conventions
* @param componentName - Name of the component (e.g., 'Button')
* @param slot - Name of the slot (e.g., 'root', 'thumb')
* @returns Formatted CSS class name
*/
function generateUtilityClass(componentName: string, slot: string): string;
/**
* Generates object mapping slot names to CSS classes
* @param componentName - Name of the component
* @param slots - Array of slot names
* @returns Object with slot names as keys and CSS classes as values
*/
function generateUtilityClasses<T extends string>(
componentName: string,
slots: T[]
): Record<T, string>;
/**
* Checks if slot name represents a global state
* @param slot - Slot name to check
* @returns Whether slot represents global state (e.g., 'focused', 'disabled')
*/
function isGlobalState(slot: string): boolean;Usage Examples:
// Generate single class
const buttonRootClass = generateUtilityClass('Button', 'root');
// Result: 'base-Button-root'
// Generate multiple classes
const sliderClasses = generateUtilityClasses('Slider', [
'root', 'rail', 'track', 'thumb', 'mark'
]);
// Result: { root: 'base-Slider-root', rail: 'base-Slider-rail', ... }
// Check global state
isGlobalState('focused'); // true
isGlobalState('disabled'); // true
isGlobalState('root'); // false/**
* Merges slot props with event handler support and owner state
* @param parameters - Slot props merging parameters
* @returns Merged props and internal ref
*/
function mergeSlotProps<SlotProps>(
parameters: MergeSlotPropsParameters<SlotProps>
): MergeSlotPropsResult<SlotProps>;
interface MergeSlotPropsParameters<SlotProps> {
/** Function to get internal slot props */
getSlotProps?: (otherHandlers: EventHandlers) => SlotProps;
/** External props passed to slot */
externalSlotProps?: SlotProps;
/** External props passed to component */
externalForwardedProps?: Record<string, any>;
/** Additional props to merge */
additionalProps?: Record<string, any>;
/** CSS class name */
className?: string;
}
interface MergeSlotPropsResult<SlotProps> {
/** Merged props */
props: SlotProps;
/** Internal ref callback */
internalRef: React.Ref<any>;
}
/**
* Hook for merging slot props with owner state support
* @param parameters - Slot props parameters including owner state
* @returns Merged slot props
*/
function useSlotProps<ElementType extends React.ElementType>(
parameters: UseSlotPropsParameters<ElementType>
): UseSlotPropsResult<ElementType>;
interface UseSlotPropsParameters<ElementType extends React.ElementType> {
/** Element type for the slot */
elementType?: ElementType;
/** External props for the slot */
externalSlotProps?: Record<string, any>;
/** Owner state to append to props */
ownerState?: Record<string, any>;
/** Whether to skip appending owner state */
skipResolvingSlotProps?: boolean;
}
type UseSlotPropsResult<ElementType extends React.ElementType> =
React.ComponentPropsWithRef<ElementType>;/**
* Determines if element type is a host component (string) vs React component
* @param elementType - Element type to check
* @returns Whether element type is host component
*/
function isHostComponent(elementType: React.ElementType): elementType is keyof JSX.IntrinsicElements;
/**
* Prepares component for use as a slot
* @param Component - Component to prepare
* @returns Prepared component for slot usage
*/
function prepareForSlot<Props>(
Component: React.ComponentType<Props>
): React.ComponentType<Props>;
/**
* Resolves component props based on owner state
* @param componentProps - Component props (can be function)
* @param ownerState - Current owner state
* @returns Resolved props object
*/
function resolveComponentProps<Props, OwnerState>(
componentProps: Props | ((ownerState: OwnerState) => Props),
ownerState: OwnerState
): Props;/**
* Deep equality comparison for arrays with custom item comparer
* @param array1 - First array to compare
* @param array2 - Second array to compare
* @param itemComparer - Optional custom comparison function
* @returns Whether arrays are equal
*/
function areArraysEqual<Item>(
array1: ReadonlyArray<Item>,
array2: ReadonlyArray<Item>,
itemComparer?: ItemComparer<Item>
): boolean;
type ItemComparer<Item> = (a: Item, b: Item) => boolean;Complete slider functionality with value management and keyboard navigation.
/**
* Slider behavior hook with range support and accessibility
* @param parameters - Slider configuration including value range and marks
* @returns Props getters and state for all slider functionality
*/
function useSlider(parameters: UseSliderParameters): UseSliderReturnValue;
interface UseSliderParameters {
/** Current slider value or array of values */
value?: number | number[];
/** Default slider value */
defaultValue?: number | number[];
/** Minimum slider value */
min?: number;
/** Maximum slider value */
max?: number;
/** Step increment */
step?: number | null;
/** Whether slider is disabled */
disabled?: boolean;
/** Marks on the slider */
marks?: boolean | SliderMark[];
/** Change event handler */
onChange?: (event: Event, value: number | number[]) => void;
/** Change committed event handler */
onChangeCommitted?: (event: React.SyntheticEvent | Event, value: number | number[]) => void;
/** Ref for root element */
rootRef?: React.Ref<Element>;
/** Text direction */
direction?: 'ltr' | 'rtl';
/** Slider orientation */
orientation?: 'horizontal' | 'vertical';
/** Scale function for value display */
scale?: (value: number) => number;
/** Tab index for slider */
tabIndex?: number;
/** Name attribute for form submission */
name?: string;
}
interface UseSliderReturnValue {
/** Props getter for root element */
getRootProps: () => UseSliderRootSlotProps;
/** Props getter for rail element */
getRailProps: () => UseSliderRailSlotProps;
/** Props getter for track element */
getTrackProps: () => UseSliderTrackSlotProps;
/** Props getter for thumb elements */
getThumbProps: (index: number) => UseSliderThumbSlotProps;
/** Props getter for mark elements */
getMarkProps: (index: number) => UseSliderMarkSlotProps;
/** Props getter for mark label elements */
getMarkLabelProps: (index: number) => UseSliderMarkLabelSlotProps;
/** Props getter for value label elements */
getValueLabelProps: (index: number) => UseSliderValueLabelSlotProps;
/** Props getter for input elements */
getInputProps: (index: number) => UseSliderInputSlotProps;
/** Current slider value(s) */
value: number | number[];
/** Whether any thumb has focus visible */
focusVisible: boolean;
/** Index of currently active thumb */
active: number;
/** Whether slider is disabled */
disabled: boolean;
/** Whether slider is in dragging state */
dragging: boolean;
/** Array of mark data */
marks: SliderMark[];
/** Slider orientation */
orientation: 'horizontal' | 'vertical';
/** Root ref callback */
rootRef: React.RefCallback<Element>;
}
interface SliderMark {
value: number;
label?: React.ReactNode;
}Select dropdown behavior with single and multiple selection support.
/**
* Select dropdown behavior hook with option management
* @param props - Select configuration including options and selection
* @returns State and props getters for select functionality
*/
function useSelect<OptionValue, Multiple extends boolean = false>(
props: UseSelectParameters<OptionValue, Multiple>
): UseSelectReturnValue<OptionValue, Multiple>;
interface UseSelectParameters<OptionValue, Multiple extends boolean> {
/** Function to compare option equality */
areOptionsEqual?: (a: OptionValue, b: OptionValue) => boolean;
/** Whether to auto-focus on mount */
autoFocus?: boolean;
/** Button element ID */
buttonId?: string;
/** Default dropdown open state */
defaultListboxOpen?: boolean;
/** Default selected value(s) */
defaultValue?: SelectValue<OptionValue, Multiple>;
/** Whether select is disabled */
disabled?: boolean;
/** Function to serialize option values */
getSerializedValue?: (option: string | OptionValue) => string;
/** Listbox element ID */
listboxId?: string;
/** Controlled dropdown open state */
listboxOpen?: boolean;
/** Whether multiple selection is allowed */
multiple?: Multiple;
/** Form input name */
name?: string;
/** Value change handler */
onChange?: (event: React.MouseEvent | React.KeyboardEvent | React.FocusEvent | null, value: SelectValue<OptionValue, Multiple>) => void;
/** Dropdown open state change handler */
onListboxOpenChange?: (isOpen: boolean) => void;
/** Whether select is required */
required?: boolean;
/** Current selected value(s) */
value?: SelectValue<OptionValue, Multiple>;
}
interface UseSelectReturnValue<OptionValue, Multiple extends boolean> {
/** Whether button is active (pressed) */
buttonActive: boolean;
/** Whether button has visible focus */
buttonFocusVisible: boolean;
/** Whether select is disabled */
disabled: boolean;
/** Dispatch function for list actions */
dispatch: (action: ListAction<OptionValue>) => void;
/** Props getter for button element */
getButtonProps: <ExternalProps extends Record<string, any> = {}>(
externalProps?: ExternalProps
) => UseSelectButtonSlotProps<ExternalProps>;
/** Props getter for listbox element */
getListboxProps: <ExternalProps extends Record<string, any> = {}>(
externalProps?: ExternalProps
) => UseSelectListboxSlotProps<ExternalProps>;
/** Function to get option metadata */
getOptionMetadata: (optionValue: OptionValue) => OptionMetadata<OptionValue> | undefined;
/** Whether listbox is open */
listboxOpen: boolean;
/** Array of available options */
options: OptionValue[];
/** Current selected value(s) */
value: SelectValue<OptionValue, Multiple>;
/** Context value for Select provider */
contextValue: SelectProviderValue<OptionValue>;
}
type SelectValue<OptionValue, Multiple extends boolean> =
Multiple extends true ? OptionValue[] : OptionValue | null;
interface OptionMetadata<OptionValue> {
disabled: boolean;
index: number;
label?: string;
value: OptionValue;
}
interface ListAction<OptionValue> {
type: string;
event: React.SyntheticEvent;
item?: OptionValue;
}
interface SelectProviderValue<OptionValue> {
dispatch: (action: ListAction<OptionValue>) => void;
getOptionMetadata: (optionValue: OptionValue) => OptionMetadata<OptionValue> | undefined;
listboxRef: React.RefObject<HTMLElement>;
}/**
* Context provider for disabling default CSS classes globally
* @param props - Configuration props including disable flag
* @returns Context provider for class name configuration
*/
function ClassNameConfigurator(props: ClassNameConfiguratorProps): JSX.Element;
interface ClassNameConfiguratorProps {
/** Whether to disable default CSS classes */
disableDefaultClasses?: boolean;
/** Children components */
children?: React.ReactNode;
}
/**
* Hook to access class name override configuration
* @returns Object with class name generation functions
*/
function useClassNamesOverride(): {
/** Function to generate utility class */
generateUtilityClass: (componentName: string, slot: string) => string;
/** Function to generate utility classes */
generateUtilityClasses: <T extends string>(componentName: string, slots: T[]) => Record<T, string>;
};Usage Examples:
// Disable default classes globally
<ClassNameConfigurator disableDefaultClasses>
<App />
</ClassNameConfigurator>
// Use class name override in custom component
function CustomButton() {
const { generateUtilityClass } = useClassNamesOverride();
const buttonClass = generateUtilityClass('Button', 'root');
return <button className={buttonClass}>Custom Button</button>;
}Advanced utilities for managing slot-based component architecture.
/**
* Merges slot component internal props with externally provided ones
* @param parameters - Merge configuration including internal and external props
* @returns Merged props object with proper precedence handling
*/
function mergeSlotProps<
SlotProps,
ExternalForwardedProps extends Record<string, unknown>,
ExternalSlotProps extends Record<string, unknown>,
AdditionalProps,
>(
parameters: MergeSlotPropsParameters<
SlotProps,
ExternalForwardedProps,
ExternalSlotProps,
AdditionalProps
>
): MergeSlotPropsResult<SlotProps, ExternalForwardedProps, ExternalSlotProps, AdditionalProps>;
interface MergeSlotPropsParameters<
SlotProps,
ExternalForwardedProps,
ExternalSlotProps,
AdditionalProps,
> {
/** Function that returns internal props of the component */
getSlotProps?: (other: EventHandlers) => WithCommonProps<SlotProps>;
/** Props provided to slotProps.* of the Base UI component */
externalSlotProps?: WithCommonProps<ExternalSlotProps>;
/** Extra props placed on the Base UI component for forwarding */
externalForwardedProps?: WithCommonProps<ExternalForwardedProps>;
/** Additional props to be placed on the slot */
additionalProps?: WithCommonProps<AdditionalProps>;
/** Extra class names to be placed on the slot */
className?: ClassValue | ClassValue[];
}
/**
* Hook for managing slot props with event handler extraction
* @param parameters - Slot props configuration
* @returns Props object for slot element
*/
function useSlotProps<ElementType extends React.ElementType>(
parameters: UseSlotPropsParameters<ElementType>
): UseSlotPropsReturnValue<ElementType>;
/**
* Prepares a component for use as a slot by ensuring proper prop forwarding
* @param Component - React component to prepare for slot usage
* @returns Component with proper slot behavior
*/
function prepareForSlot<Props extends Record<string, any>>(
Component: React.ComponentType<Props>
): React.ComponentType<Props>;
/**
* Resolves component props based on owner state for conditional styling
* @param props - Component props to resolve
* @param ownerState - Current owner state of the component
* @returns Resolved props with owner state applied
*/
function resolveComponentProps<Props, OwnerState>(
props: Props | ((ownerState: OwnerState) => Props) | undefined,
ownerState: OwnerState
): Props | undefined;/**
* Composes CSS classes with proper precedence handling
* @param slots - Slot definitions for the component
* @param getUtilityClass - Function to generate utility classes
* @param classes - External class overrides
* @returns Composed class names object
*/
declare const unstable_composeClasses: <T extends string>(
slots: Record<T, readonly string[]>,
getUtilityClass: (slot: string) => string,
classes?: Partial<Record<T, string>>
) => Record<T, string>;
/**
* Appends owner state to component props for conditional styling
* @param elementType - Target element type
* @param otherProps - Other props to merge with owner state
* @param ownerState - Owner state to append
* @returns Props with owner state appended
*/
function appendOwnerState<
ElementType extends React.ElementType,
OtherProps,
OwnerState
>(
elementType: ElementType,
otherProps: OtherProps,
ownerState: OwnerState
): OtherProps & (OwnerState extends Record<string, any> ? { ownerState: OwnerState } : {});
/**
* Checks if a component is a host (DOM) component rather than React component
* @param element - Element type to check
* @returns True if element is a host component
*/
function isHostComponent(element: React.ElementType): boolean;
/**
* Extracts event handlers from props object
* @param object - Props object to extract handlers from
* @returns Object containing only event handler props
*/
function extractEventHandlers(object: Record<string, any>): EventHandlers;
/**
* Utility for comparing array equality with shallow comparison
* @param a - First array to compare
* @param b - Second array to compare
* @returns True if arrays are shallowly equal
*/
function areArraysEqual<T>(a: T[], b: T[]): boolean;
/**
* Hook to get the root element name for polymorphic components
* @param rootElementName - Override root element name
* @param componentName - Name of the component
* @returns Resolved root element name
*/
function useRootElementName<T extends React.ElementType>(
rootElementName: T | undefined,
componentName: string
): T;// Common props interface for slot components
interface WithCommonProps<OtherProps> extends OtherProps {
className?: string;
style?: React.CSSProperties;
ref?: React.Ref<any>;
}
// Event handlers type for component integration
interface EventHandlers {
[key: string]: React.EventHandler<any>;
}
// Class value type for className composition
type ClassValue = string | number | boolean | undefined | null | ClassArray | ClassDictionary;
interface ClassArray extends Array<ClassValue> {}
interface ClassDictionary {
[id: string]: any;
}