or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

data-display.mdform-controls.mdhooks-utilities.mdindex.mdlayout-positioning.mdselection-navigation.md

hooks-utilities.mddocs/

0

# Hooks & Utilities

1

2

React hooks and utility functions for building custom components with MUI Base behavior, including CSS class generation, prop merging, and component state management.

3

4

## Capabilities

5

6

### Component Behavior Hooks

7

8

#### useButton Hook

9

10

Provides button behavior including focus management, accessibility, and event handling.

11

12

```typescript { .api }

13

/**

14

* Button behavior hook with accessibility and focus management

15

* @param parameters - Button configuration including disabled state and element type

16

* @returns Props getters and state for button functionality

17

*/

18

function useButton(parameters: UseButtonParameters): UseButtonReturnValue;

19

20

interface UseButtonParameters {

21

/** Whether button is disabled */

22

disabled?: boolean;

23

/** Whether button is focusable when disabled */

24

focusableWhenDisabled?: boolean;

25

/** Href for link-style buttons */

26

href?: string;

27

/** Ref for root element */

28

rootRef?: React.Ref<Element>;

29

/** Tab index override */

30

tabIndex?: number;

31

/** Router link destination */

32

to?: string;

33

/** Button type attribute */

34

type?: React.ButtonHTMLAttributes<HTMLButtonElement>['type'];

35

/** Root element name for polymorphic behavior */

36

rootElementName?: string;

37

}

38

39

interface UseButtonReturnValue {

40

/** Props getter for root button element */

41

getRootProps: <ExternalProps extends Record<string, any> = {}>(

42

externalProps?: ExternalProps

43

) => UseButtonRootSlotProps<ExternalProps>;

44

/** Ref callback for root element */

45

rootRef: React.RefCallback<Element>;

46

/** Whether button is currently active (pressed) */

47

active: boolean;

48

/** Whether button has visible focus indicator */

49

focusVisible: boolean;

50

/** Whether button is disabled */

51

disabled: boolean;

52

}

53

54

interface UseButtonRootSlotProps<ExternalProps = {}> extends ExternalProps {

55

'aria-disabled'?: boolean;

56

'aria-pressed'?: boolean;

57

disabled?: boolean;

58

href?: string;

59

role?: React.AriaRole;

60

tabIndex?: number;

61

type?: React.ButtonHTMLAttributes<HTMLButtonElement>['type'];

62

onBlur: React.FocusEventHandler;

63

onClick: React.MouseEventHandler;

64

onFocus: React.FocusEventHandler;

65

onKeyDown: React.KeyboardEventHandler;

66

onKeyUp: React.KeyboardEventHandler;

67

onMouseDown: React.MouseEventHandler;

68

onMouseLeave: React.MouseEventHandler;

69

}

70

```

71

72

#### useInput Hook

73

74

Manages input state and integrates with FormControl context.

75

76

```typescript { .api }

77

/**

78

* Input state management hook with form control integration

79

* @param parameters - Input configuration including value and validation

80

* @returns Props getters and state for input functionality

81

*/

82

function useInput(parameters: UseInputParameters): UseInputReturnValue;

83

84

interface UseInputParameters {

85

/** Default input value */

86

defaultValue?: unknown;

87

/** Whether input is disabled */

88

disabled?: boolean;

89

/** Whether input has validation error */

90

error?: boolean;

91

/** Change event handler */

92

onChange?: React.ChangeEventHandler<HTMLInputElement>;

93

/** Whether input is required */

94

required?: boolean;

95

/** Current input value */

96

value?: unknown;

97

}

98

99

interface UseInputReturnValue {

100

/** Props getter for root container */

101

getRootProps: () => UseInputRootSlotProps;

102

/** Props getter for input element */

103

getInputProps: () => UseInputInputSlotProps;

104

/** Whether input is currently focused */

105

focused: boolean;

106

/** Form control context state */

107

formControlContext: FormControlState | undefined;

108

/** Whether input has error */

109

error: boolean;

110

/** Whether input is disabled */

111

disabled: boolean;

112

/** Whether input is required */

113

required: boolean;

114

/** Current input value */

115

value: unknown;

116

}

117

118

interface UseInputRootSlotProps {

119

onClick: React.MouseEventHandler;

120

}

121

122

interface UseInputInputSlotProps {

123

'aria-describedby'?: string;

124

'aria-invalid'?: boolean;

125

'aria-required'?: boolean;

126

disabled?: boolean;

127

value?: unknown;

128

onBlur: React.FocusEventHandler<HTMLInputElement>;

129

onChange: React.ChangeEventHandler<HTMLInputElement>;

130

onFocus: React.FocusEventHandler<HTMLInputElement>;

131

}

132

```

133

134

#### useAutocomplete Hook

135

136

Comprehensive autocomplete functionality with filtering, selection, and keyboard navigation.

137

138

```typescript { .api }

139

/**

140

* Complete autocomplete/combobox functionality hook

141

* @param props - Autocomplete configuration including options and behavior

142

* @returns State and props getters for autocomplete functionality

143

*/

144

function useAutocomplete<Value, Multiple, DisableClearable, FreeSolo>(

145

props: UseAutocompleteProps<Value, Multiple, DisableClearable, FreeSolo>

146

): UseAutocompleteReturnValue<Value, Multiple, DisableClearable, FreeSolo>;

147

148

interface UseAutocompleteProps<Value, Multiple, DisableClearable, FreeSolo> {

149

/** Available options */

150

options: Value[];

151

/** Whether multiple selection is allowed */

152

multiple?: Multiple;

153

/** Current value */

154

value?: AutocompleteValue<Value, Multiple, DisableClearable, FreeSolo>;

155

/** Default value */

156

defaultValue?: AutocompleteValue<Value, Multiple, DisableClearable, FreeSolo>;

157

/** Value change handler */

158

onChange?: (event: React.SyntheticEvent, value: AutocompleteValue<Value, Multiple, DisableClearable, FreeSolo>, reason: AutocompleteChangeReason, details?: AutocompleteChangeDetails<Value>) => void;

159

/** Input value for filtering */

160

inputValue?: string;

161

/** Input value change handler */

162

onInputChange?: (event: React.SyntheticEvent, value: string, reason: AutocompleteInputChangeReason) => void;

163

/** Function to get option label */

164

getOptionLabel?: (option: Value) => string;

165

/** Function to get option key */

166

getOptionKey?: (option: Value) => string | number;

167

/** Function to compare option equality */

168

isOptionEqualToValue?: (option: Value, value: Value) => boolean;

169

/** Function to filter options */

170

filterOptions?: (options: Value[], state: FilterOptionsState<Value>) => Value[];

171

/** Whether to auto-complete on input */

172

autoComplete?: boolean;

173

/** Whether to auto-highlight first option */

174

autoHighlight?: boolean;

175

/** Whether to auto-select highlighted option */

176

autoSelect?: boolean;

177

/** When to trigger blur on selection */

178

blurOnSelect?: 'touch' | 'mouse' | true | false;

179

/** Whether to clear input on blur */

180

clearOnBlur?: boolean;

181

/** Whether to clear input on escape */

182

clearOnEscape?: boolean;

183

/** Whether clear button is disabled */

184

disableClearable?: DisableClearable;

185

/** Whether to close on selection */

186

disableCloseOnSelect?: boolean;

187

/** Whether autocomplete is disabled */

188

disabled?: boolean;

189

/** Whether disabled items are focusable */

190

disabledItemsFocusable?: boolean;

191

/** Whether list wrapping is disabled */

192

disableListWrap?: boolean;

193

/** Whether to filter selected options from list */

194

filterSelectedOptions?: boolean;

195

/** Whether free text input is allowed */

196

freeSolo?: FreeSolo;

197

/** Whether to handle home/end keys */

198

handleHomeEndKeys?: boolean;

199

/** Whether to include input in list navigation */

200

includeInputInList?: boolean;

201

/** Whether to open on focus */

202

openOnFocus?: boolean;

203

/** Whether autocomplete is read-only */

204

readOnly?: boolean;

205

/** Whether to select text on focus */

206

selectOnFocus?: boolean;

207

}

208

209

interface UseAutocompleteReturnValue<Value, Multiple, DisableClearable, FreeSolo> {

210

/** Props getter for root container */

211

getRootProps: () => object;

212

/** Props getter for input element */

213

getInputProps: () => object;

214

/** Props getter for input label */

215

getInputLabelProps: () => object;

216

/** Props getter for clear button */

217

getClearProps: () => object;

218

/** Props getter for popup indicator */

219

getPopupIndicatorProps: () => object;

220

/** Props getter for tag elements */

221

getTagProps: (params: { index: number }) => object;

222

/** Props getter for listbox container */

223

getListboxProps: () => object;

224

/** Props getter for option elements */

225

getOptionProps: (params: { option: Value; index: number }) => object;

226

/** Current autocomplete value */

227

value: AutocompleteValue<Value, Multiple, DisableClearable, FreeSolo>;

228

/** Whether input has been modified */

229

dirty: boolean;

230

/** Whether popup is expanded */

231

expanded: boolean;

232

/** Autocomplete ID */

233

id: string;

234

/** Current input value */

235

inputValue: string;

236

/** Whether input is focused */

237

focused: boolean;

238

/** Index of focused tag (-1 if none) */

239

focusedTag: number;

240

/** Anchor element for popup */

241

anchorEl: null | HTMLElement;

242

/** Function to set anchor element */

243

setAncherEl: () => void;

244

/** Options grouped for display */

245

groupedOptions: Array<Value | AutocompleteGroupedOption<Value>>;

246

/** Whether popup is open */

247

popupOpen: boolean;

248

}

249

250

type AutocompleteValue<Value, Multiple, DisableClearable, FreeSolo> =

251

Multiple extends true

252

? Value[]

253

: DisableClearable extends true

254

? Value

255

: Value | null;

256

257

type AutocompleteChangeReason = 'createOption' | 'selectOption' | 'removeOption' | 'blur' | 'clear';

258

type AutocompleteInputChangeReason = 'input' | 'reset' | 'clear';

259

260

interface AutocompleteChangeDetails<Value> {

261

option: Value;

262

}

263

264

interface FilterOptionsState<Value> {

265

inputValue: string;

266

getOptionLabel: (option: Value) => string;

267

}

268

269

interface AutocompleteGroupedOption<Value> {

270

key: string;

271

index: number;

272

group: string;

273

options: Value[];

274

}

275

```

276

277

### Utility Functions

278

279

#### CSS Class Generation

280

281

```typescript { .api }

282

/**

283

* Generates CSS class names following Base UI conventions

284

* @param componentName - Name of the component (e.g., 'Button')

285

* @param slot - Name of the slot (e.g., 'root', 'thumb')

286

* @returns Formatted CSS class name

287

*/

288

function generateUtilityClass(componentName: string, slot: string): string;

289

290

/**

291

* Generates object mapping slot names to CSS classes

292

* @param componentName - Name of the component

293

* @param slots - Array of slot names

294

* @returns Object with slot names as keys and CSS classes as values

295

*/

296

function generateUtilityClasses<T extends string>(

297

componentName: string,

298

slots: T[]

299

): Record<T, string>;

300

301

/**

302

* Checks if slot name represents a global state

303

* @param slot - Slot name to check

304

* @returns Whether slot represents global state (e.g., 'focused', 'disabled')

305

*/

306

function isGlobalState(slot: string): boolean;

307

```

308

309

**Usage Examples:**

310

311

```typescript

312

// Generate single class

313

const buttonRootClass = generateUtilityClass('Button', 'root');

314

// Result: 'base-Button-root'

315

316

// Generate multiple classes

317

const sliderClasses = generateUtilityClasses('Slider', [

318

'root', 'rail', 'track', 'thumb', 'mark'

319

]);

320

// Result: { root: 'base-Slider-root', rail: 'base-Slider-rail', ... }

321

322

// Check global state

323

isGlobalState('focused'); // true

324

isGlobalState('disabled'); // true

325

isGlobalState('root'); // false

326

```

327

328

#### Prop Utilities

329

330

```typescript { .api }

331

/**

332

* Merges slot props with event handler support and owner state

333

* @param parameters - Slot props merging parameters

334

* @returns Merged props and internal ref

335

*/

336

function mergeSlotProps<SlotProps>(

337

parameters: MergeSlotPropsParameters<SlotProps>

338

): MergeSlotPropsResult<SlotProps>;

339

340

interface MergeSlotPropsParameters<SlotProps> {

341

/** Function to get internal slot props */

342

getSlotProps?: (otherHandlers: EventHandlers) => SlotProps;

343

/** External props passed to slot */

344

externalSlotProps?: SlotProps;

345

/** External props passed to component */

346

externalForwardedProps?: Record<string, any>;

347

/** Additional props to merge */

348

additionalProps?: Record<string, any>;

349

/** CSS class name */

350

className?: string;

351

}

352

353

interface MergeSlotPropsResult<SlotProps> {

354

/** Merged props */

355

props: SlotProps;

356

/** Internal ref callback */

357

internalRef: React.Ref<any>;

358

}

359

360

/**

361

* Hook for merging slot props with owner state support

362

* @param parameters - Slot props parameters including owner state

363

* @returns Merged slot props

364

*/

365

function useSlotProps<ElementType extends React.ElementType>(

366

parameters: UseSlotPropsParameters<ElementType>

367

): UseSlotPropsResult<ElementType>;

368

369

interface UseSlotPropsParameters<ElementType extends React.ElementType> {

370

/** Element type for the slot */

371

elementType?: ElementType;

372

/** External props for the slot */

373

externalSlotProps?: Record<string, any>;

374

/** Owner state to append to props */

375

ownerState?: Record<string, any>;

376

/** Whether to skip appending owner state */

377

skipResolvingSlotProps?: boolean;

378

}

379

380

type UseSlotPropsResult<ElementType extends React.ElementType> =

381

React.ComponentPropsWithRef<ElementType>;

382

```

383

384

#### Component Utilities

385

386

```typescript { .api }

387

/**

388

* Determines if element type is a host component (string) vs React component

389

* @param elementType - Element type to check

390

* @returns Whether element type is host component

391

*/

392

function isHostComponent(elementType: React.ElementType): elementType is keyof JSX.IntrinsicElements;

393

394

/**

395

* Prepares component for use as a slot

396

* @param Component - Component to prepare

397

* @returns Prepared component for slot usage

398

*/

399

function prepareForSlot<Props>(

400

Component: React.ComponentType<Props>

401

): React.ComponentType<Props>;

402

403

/**

404

* Resolves component props based on owner state

405

* @param componentProps - Component props (can be function)

406

* @param ownerState - Current owner state

407

* @returns Resolved props object

408

*/

409

function resolveComponentProps<Props, OwnerState>(

410

componentProps: Props | ((ownerState: OwnerState) => Props),

411

ownerState: OwnerState

412

): Props;

413

```

414

415

#### Array & Comparison Utilities

416

417

```typescript { .api }

418

/**

419

* Deep equality comparison for arrays with custom item comparer

420

* @param array1 - First array to compare

421

* @param array2 - Second array to compare

422

* @param itemComparer - Optional custom comparison function

423

* @returns Whether arrays are equal

424

*/

425

function areArraysEqual<Item>(

426

array1: ReadonlyArray<Item>,

427

array2: ReadonlyArray<Item>,

428

itemComparer?: ItemComparer<Item>

429

): boolean;

430

431

type ItemComparer<Item> = (a: Item, b: Item) => boolean;

432

```

433

434

### Advanced Hooks

435

436

#### useSlider Hook

437

438

Complete slider functionality with value management and keyboard navigation.

439

440

```typescript { .api }

441

/**

442

* Slider behavior hook with range support and accessibility

443

* @param parameters - Slider configuration including value range and marks

444

* @returns Props getters and state for all slider functionality

445

*/

446

function useSlider(parameters: UseSliderParameters): UseSliderReturnValue;

447

448

interface UseSliderParameters {

449

/** Current slider value or array of values */

450

value?: number | number[];

451

/** Default slider value */

452

defaultValue?: number | number[];

453

/** Minimum slider value */

454

min?: number;

455

/** Maximum slider value */

456

max?: number;

457

/** Step increment */

458

step?: number | null;

459

/** Whether slider is disabled */

460

disabled?: boolean;

461

/** Marks on the slider */

462

marks?: boolean | SliderMark[];

463

/** Change event handler */

464

onChange?: (event: Event, value: number | number[]) => void;

465

/** Change committed event handler */

466

onChangeCommitted?: (event: React.SyntheticEvent | Event, value: number | number[]) => void;

467

/** Ref for root element */

468

rootRef?: React.Ref<Element>;

469

/** Text direction */

470

direction?: 'ltr' | 'rtl';

471

/** Slider orientation */

472

orientation?: 'horizontal' | 'vertical';

473

/** Scale function for value display */

474

scale?: (value: number) => number;

475

/** Tab index for slider */

476

tabIndex?: number;

477

/** Name attribute for form submission */

478

name?: string;

479

}

480

481

interface UseSliderReturnValue {

482

/** Props getter for root element */

483

getRootProps: () => UseSliderRootSlotProps;

484

/** Props getter for rail element */

485

getRailProps: () => UseSliderRailSlotProps;

486

/** Props getter for track element */

487

getTrackProps: () => UseSliderTrackSlotProps;

488

/** Props getter for thumb elements */

489

getThumbProps: (index: number) => UseSliderThumbSlotProps;

490

/** Props getter for mark elements */

491

getMarkProps: (index: number) => UseSliderMarkSlotProps;

492

/** Props getter for mark label elements */

493

getMarkLabelProps: (index: number) => UseSliderMarkLabelSlotProps;

494

/** Props getter for value label elements */

495

getValueLabelProps: (index: number) => UseSliderValueLabelSlotProps;

496

/** Props getter for input elements */

497

getInputProps: (index: number) => UseSliderInputSlotProps;

498

/** Current slider value(s) */

499

value: number | number[];

500

/** Whether any thumb has focus visible */

501

focusVisible: boolean;

502

/** Index of currently active thumb */

503

active: number;

504

/** Whether slider is disabled */

505

disabled: boolean;

506

/** Whether slider is in dragging state */

507

dragging: boolean;

508

/** Array of mark data */

509

marks: SliderMark[];

510

/** Slider orientation */

511

orientation: 'horizontal' | 'vertical';

512

/** Root ref callback */

513

rootRef: React.RefCallback<Element>;

514

}

515

516

interface SliderMark {

517

value: number;

518

label?: React.ReactNode;

519

}

520

```

521

522

#### useSelect Hook

523

524

Select dropdown behavior with single and multiple selection support.

525

526

```typescript { .api }

527

/**

528

* Select dropdown behavior hook with option management

529

* @param props - Select configuration including options and selection

530

* @returns State and props getters for select functionality

531

*/

532

function useSelect<OptionValue, Multiple extends boolean = false>(

533

props: UseSelectParameters<OptionValue, Multiple>

534

): UseSelectReturnValue<OptionValue, Multiple>;

535

536

interface UseSelectParameters<OptionValue, Multiple extends boolean> {

537

/** Function to compare option equality */

538

areOptionsEqual?: (a: OptionValue, b: OptionValue) => boolean;

539

/** Whether to auto-focus on mount */

540

autoFocus?: boolean;

541

/** Button element ID */

542

buttonId?: string;

543

/** Default dropdown open state */

544

defaultListboxOpen?: boolean;

545

/** Default selected value(s) */

546

defaultValue?: SelectValue<OptionValue, Multiple>;

547

/** Whether select is disabled */

548

disabled?: boolean;

549

/** Function to serialize option values */

550

getSerializedValue?: (option: string | OptionValue) => string;

551

/** Listbox element ID */

552

listboxId?: string;

553

/** Controlled dropdown open state */

554

listboxOpen?: boolean;

555

/** Whether multiple selection is allowed */

556

multiple?: Multiple;

557

/** Form input name */

558

name?: string;

559

/** Value change handler */

560

onChange?: (event: React.MouseEvent | React.KeyboardEvent | React.FocusEvent | null, value: SelectValue<OptionValue, Multiple>) => void;

561

/** Dropdown open state change handler */

562

onListboxOpenChange?: (isOpen: boolean) => void;

563

/** Whether select is required */

564

required?: boolean;

565

/** Current selected value(s) */

566

value?: SelectValue<OptionValue, Multiple>;

567

}

568

569

interface UseSelectReturnValue<OptionValue, Multiple extends boolean> {

570

/** Whether button is active (pressed) */

571

buttonActive: boolean;

572

/** Whether button has visible focus */

573

buttonFocusVisible: boolean;

574

/** Whether select is disabled */

575

disabled: boolean;

576

/** Dispatch function for list actions */

577

dispatch: (action: ListAction<OptionValue>) => void;

578

/** Props getter for button element */

579

getButtonProps: <ExternalProps extends Record<string, any> = {}>(

580

externalProps?: ExternalProps

581

) => UseSelectButtonSlotProps<ExternalProps>;

582

/** Props getter for listbox element */

583

getListboxProps: <ExternalProps extends Record<string, any> = {}>(

584

externalProps?: ExternalProps

585

) => UseSelectListboxSlotProps<ExternalProps>;

586

/** Function to get option metadata */

587

getOptionMetadata: (optionValue: OptionValue) => OptionMetadata<OptionValue> | undefined;

588

/** Whether listbox is open */

589

listboxOpen: boolean;

590

/** Array of available options */

591

options: OptionValue[];

592

/** Current selected value(s) */

593

value: SelectValue<OptionValue, Multiple>;

594

/** Context value for Select provider */

595

contextValue: SelectProviderValue<OptionValue>;

596

}

597

598

type SelectValue<OptionValue, Multiple extends boolean> =

599

Multiple extends true ? OptionValue[] : OptionValue | null;

600

601

interface OptionMetadata<OptionValue> {

602

disabled: boolean;

603

index: number;

604

label?: string;

605

value: OptionValue;

606

}

607

608

interface ListAction<OptionValue> {

609

type: string;

610

event: React.SyntheticEvent;

611

item?: OptionValue;

612

}

613

614

interface SelectProviderValue<OptionValue> {

615

dispatch: (action: ListAction<OptionValue>) => void;

616

getOptionMetadata: (optionValue: OptionValue) => OptionMetadata<OptionValue> | undefined;

617

listboxRef: React.RefObject<HTMLElement>;

618

}

619

```

620

621

### Class Name Configuration

622

623

```typescript { .api }

624

/**

625

* Context provider for disabling default CSS classes globally

626

* @param props - Configuration props including disable flag

627

* @returns Context provider for class name configuration

628

*/

629

function ClassNameConfigurator(props: ClassNameConfiguratorProps): JSX.Element;

630

631

interface ClassNameConfiguratorProps {

632

/** Whether to disable default CSS classes */

633

disableDefaultClasses?: boolean;

634

/** Children components */

635

children?: React.ReactNode;

636

}

637

638

/**

639

* Hook to access class name override configuration

640

* @returns Object with class name generation functions

641

*/

642

function useClassNamesOverride(): {

643

/** Function to generate utility class */

644

generateUtilityClass: (componentName: string, slot: string) => string;

645

/** Function to generate utility classes */

646

generateUtilityClasses: <T extends string>(componentName: string, slots: T[]) => Record<T, string>;

647

};

648

```

649

650

**Usage Examples:**

651

652

```typescript

653

// Disable default classes globally

654

<ClassNameConfigurator disableDefaultClasses>

655

<App />

656

</ClassNameConfigurator>

657

658

// Use class name override in custom component

659

function CustomButton() {

660

const { generateUtilityClass } = useClassNamesOverride();

661

const buttonClass = generateUtilityClass('Button', 'root');

662

663

return <button className={buttonClass}>Custom Button</button>;

664

}

665

```

666

667

### Slot Management Utilities

668

669

Advanced utilities for managing slot-based component architecture.

670

671

```typescript { .api }

672

/**

673

* Merges slot component internal props with externally provided ones

674

* @param parameters - Merge configuration including internal and external props

675

* @returns Merged props object with proper precedence handling

676

*/

677

function mergeSlotProps<

678

SlotProps,

679

ExternalForwardedProps extends Record<string, unknown>,

680

ExternalSlotProps extends Record<string, unknown>,

681

AdditionalProps,

682

>(

683

parameters: MergeSlotPropsParameters<

684

SlotProps,

685

ExternalForwardedProps,

686

ExternalSlotProps,

687

AdditionalProps

688

>

689

): MergeSlotPropsResult<SlotProps, ExternalForwardedProps, ExternalSlotProps, AdditionalProps>;

690

691

interface MergeSlotPropsParameters<

692

SlotProps,

693

ExternalForwardedProps,

694

ExternalSlotProps,

695

AdditionalProps,

696

> {

697

/** Function that returns internal props of the component */

698

getSlotProps?: (other: EventHandlers) => WithCommonProps<SlotProps>;

699

/** Props provided to slotProps.* of the Base UI component */

700

externalSlotProps?: WithCommonProps<ExternalSlotProps>;

701

/** Extra props placed on the Base UI component for forwarding */

702

externalForwardedProps?: WithCommonProps<ExternalForwardedProps>;

703

/** Additional props to be placed on the slot */

704

additionalProps?: WithCommonProps<AdditionalProps>;

705

/** Extra class names to be placed on the slot */

706

className?: ClassValue | ClassValue[];

707

}

708

709

/**

710

* Hook for managing slot props with event handler extraction

711

* @param parameters - Slot props configuration

712

* @returns Props object for slot element

713

*/

714

function useSlotProps<ElementType extends React.ElementType>(

715

parameters: UseSlotPropsParameters<ElementType>

716

): UseSlotPropsReturnValue<ElementType>;

717

718

/**

719

* Prepares a component for use as a slot by ensuring proper prop forwarding

720

* @param Component - React component to prepare for slot usage

721

* @returns Component with proper slot behavior

722

*/

723

function prepareForSlot<Props extends Record<string, any>>(

724

Component: React.ComponentType<Props>

725

): React.ComponentType<Props>;

726

727

/**

728

* Resolves component props based on owner state for conditional styling

729

* @param props - Component props to resolve

730

* @param ownerState - Current owner state of the component

731

* @returns Resolved props with owner state applied

732

*/

733

function resolveComponentProps<Props, OwnerState>(

734

props: Props | ((ownerState: OwnerState) => Props) | undefined,

735

ownerState: OwnerState

736

): Props | undefined;

737

```

738

739

### Component Composition Utilities

740

741

```typescript { .api }

742

/**

743

* Composes CSS classes with proper precedence handling

744

* @param slots - Slot definitions for the component

745

* @param getUtilityClass - Function to generate utility classes

746

* @param classes - External class overrides

747

* @returns Composed class names object

748

*/

749

declare const unstable_composeClasses: <T extends string>(

750

slots: Record<T, readonly string[]>,

751

getUtilityClass: (slot: string) => string,

752

classes?: Partial<Record<T, string>>

753

) => Record<T, string>;

754

755

/**

756

* Appends owner state to component props for conditional styling

757

* @param elementType - Target element type

758

* @param otherProps - Other props to merge with owner state

759

* @param ownerState - Owner state to append

760

* @returns Props with owner state appended

761

*/

762

function appendOwnerState<

763

ElementType extends React.ElementType,

764

OtherProps,

765

OwnerState

766

>(

767

elementType: ElementType,

768

otherProps: OtherProps,

769

ownerState: OwnerState

770

): OtherProps & (OwnerState extends Record<string, any> ? { ownerState: OwnerState } : {});

771

772

/**

773

* Checks if a component is a host (DOM) component rather than React component

774

* @param element - Element type to check

775

* @returns True if element is a host component

776

*/

777

function isHostComponent(element: React.ElementType): boolean;

778

779

/**

780

* Extracts event handlers from props object

781

* @param object - Props object to extract handlers from

782

* @returns Object containing only event handler props

783

*/

784

function extractEventHandlers(object: Record<string, any>): EventHandlers;

785

786

/**

787

* Utility for comparing array equality with shallow comparison

788

* @param a - First array to compare

789

* @param b - Second array to compare

790

* @returns True if arrays are shallowly equal

791

*/

792

function areArraysEqual<T>(a: T[], b: T[]): boolean;

793

794

/**

795

* Hook to get the root element name for polymorphic components

796

* @param rootElementName - Override root element name

797

* @param componentName - Name of the component

798

* @returns Resolved root element name

799

*/

800

function useRootElementName<T extends React.ElementType>(

801

rootElementName: T | undefined,

802

componentName: string

803

): T;

804

```

805

806

### Type Utilities

807

808

```typescript { .api }

809

// Common props interface for slot components

810

interface WithCommonProps<OtherProps> extends OtherProps {

811

className?: string;

812

style?: React.CSSProperties;

813

ref?: React.Ref<any>;

814

}

815

816

// Event handlers type for component integration

817

interface EventHandlers {

818

[key: string]: React.EventHandler<any>;

819

}

820

821

// Class value type for className composition

822

type ClassValue = string | number | boolean | undefined | null | ClassArray | ClassDictionary;

823

interface ClassArray extends Array<ClassValue> {}

824

interface ClassDictionary {

825

[id: string]: any;

826

}

827

```