or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

async-data.mdcore-components.mdcustomization.mdhooks-state.mdindex.mdtypes-interfaces.md

types-interfaces.mddocs/

0

# Types and Interfaces

1

2

React-Select provides comprehensive TypeScript support with generic types, interfaces, and utility types that ensure type safety throughout the component system. All interfaces support generic Option and Group types for maximum flexibility.

3

4

## Capabilities

5

6

### Core Data Types

7

8

Fundamental type definitions for options, values, and data structures.

9

10

```typescript { .api }

11

/**

12

* Base interface for option groups containing multiple options

13

* @template Option - The option data type

14

*/

15

interface GroupBase<Option> {

16

/** Array of options within this group */

17

readonly options: readonly Option[];

18

/** Optional label for the group header */

19

readonly label?: string;

20

}

21

22

/**

23

* Union type for arrays containing options or groups

24

* @template Option - The option data type

25

* @template Group - The group data type extending GroupBase<Option>

26

*/

27

type OptionsOrGroups<Option, Group extends GroupBase<Option>> = readonly (Option | Group)[];

28

29

/**

30

* Simple array of options without grouping

31

* @template Option - The option data type

32

*/

33

type Options<Option> = readonly Option[];

34

35

/**

36

* Single value type - an option or null for no selection

37

* @template Option - The option data type

38

*/

39

type SingleValue<Option> = Option | null;

40

41

/**

42

* Multi-value type - readonly array of selected options

43

* @template Option - The option data type

44

*/

45

type MultiValue<Option> = readonly Option[];

46

47

/**

48

* Union type for any value prop - single or multi

49

* @template Option - The option data type

50

*/

51

type PropsValue<Option> = MultiValue<Option> | SingleValue<Option>;

52

53

/**

54

* Conditional type for onChange values based on isMulti flag

55

* @template Option - The option data type

56

* @template IsMulti - Boolean flag indicating multi-select mode

57

*/

58

type OnChangeValue<Option, IsMulti extends boolean> =

59

IsMulti extends true ? MultiValue<Option> : SingleValue<Option>;

60

```

61

62

**Usage Examples:**

63

64

```typescript

65

// Basic option type

66

interface ColorOption {

67

value: string;

68

label: string;

69

color: string;

70

}

71

72

// Grouped options

73

interface ColorGroup extends GroupBase<ColorOption> {

74

label: string;

75

options: readonly ColorOption[];

76

}

77

78

const colorGroups: OptionsOrGroups<ColorOption, ColorGroup> = [

79

{

80

label: "Primary Colors",

81

options: [

82

{ value: "red", label: "Red", color: "#ff0000" },

83

{ value: "blue", label: "Blue", color: "#0000ff" },

84

{ value: "yellow", label: "Yellow", color: "#ffff00" },

85

],

86

},

87

{

88

label: "Secondary Colors",

89

options: [

90

{ value: "green", label: "Green", color: "#00ff00" },

91

{ value: "orange", label: "Orange", color: "#ffa500" },

92

{ value: "purple", label: "Purple", color: "#800080" },

93

],

94

},

95

];

96

97

// Typed select usage

98

const TypedSelect = () => {

99

const [value, setValue] = useState<SingleValue<ColorOption>>(null);

100

101

return (

102

<Select<ColorOption, false, ColorGroup>

103

value={value}

104

onChange={setValue}

105

options={colorGroups}

106

/>

107

);

108

};

109

```

110

111

### Action and Meta Types

112

113

Types for handling change events and understanding what triggered them.

114

115

```typescript { .api }

116

/**

117

* Action metadata provided to onChange handlers

118

* @template Option - The option data type

119

*/

120

interface ActionMeta<Option> {

121

/** The action that triggered the change */

122

action:

123

| 'select-option' // Option was selected

124

| 'deselect-option' // Option was deselected (multi-select)

125

| 'remove-value' // Value was removed (multi-select)

126

| 'pop-value' // Last value was removed via backspace

127

| 'set-value' // Value was set programmatically

128

| 'clear' // All values were cleared

129

| 'create-option'; // New option was created (CreatableSelect)

130

131

/** Form field name if provided */

132

name?: string;

133

134

/** The option involved in the action (for select/deselect/create) */

135

option?: Option;

136

137

/** Single removed value (for remove-value action) */

138

removedValue?: Option;

139

140

/** Multiple removed values (for clear action) */

141

removedValues?: Option[];

142

}

143

144

/**

145

* Input change action metadata

146

*/

147

interface InputActionMeta {

148

/** The action that triggered the input change */

149

action:

150

| 'set-value' // Input value set programmatically

151

| 'input-change' // User typed in input

152

| 'input-blur' // Input lost focus

153

| 'menu-close'; // Menu was closed

154

155

/** Previous input value */

156

prevInputValue: string;

157

}

158

159

/**

160

* Focus direction for keyboard navigation

161

*/

162

type FocusDirection = 'up' | 'down' | 'pageup' | 'pagedown' | 'first' | 'last';

163

164

/**

165

* Menu placement options

166

*/

167

type MenuPlacement = 'auto' | 'bottom' | 'top';

168

169

/**

170

* Menu CSS position

171

*/

172

type MenuPosition = 'absolute' | 'fixed';

173

174

/**

175

* Set value action type for programmatic changes

176

*/

177

type SetValueAction = 'set-value';

178

```

179

180

**Usage Examples:**

181

182

```typescript

183

// Handling different action types

184

const handleChange = (

185

newValue: OnChangeValue<Option, false>,

186

actionMeta: ActionMeta<Option>

187

) => {

188

console.log(`Action: ${actionMeta.action}`);

189

190

switch (actionMeta.action) {

191

case 'select-option':

192

console.log('Selected:', actionMeta.option);

193

break;

194

case 'clear':

195

console.log('Cleared all values:', actionMeta.removedValues);

196

break;

197

case 'remove-value':

198

console.log('Removed:', actionMeta.removedValue);

199

break;

200

case 'create-option':

201

console.log('Created new option:', actionMeta.option);

202

// Save to database or update options list

203

break;

204

}

205

206

setValue(newValue);

207

};

208

209

// Input change handling

210

const handleInputChange = (

211

inputValue: string,

212

actionMeta: InputActionMeta

213

) => {

214

if (actionMeta.action === 'input-change') {

215

// Handle user typing

216

setInputValue(inputValue);

217

}

218

};

219

```

220

221

### Component Props Types

222

223

Complete type definitions for all component props interfaces.

224

225

```typescript { .api }

226

/**

227

* Props for the main Control component

228

* @template Option - The option data type

229

* @template IsMulti - Boolean flag for multi-select

230

* @template Group - The group data type

231

*/

232

interface ControlProps<Option, IsMulti extends boolean, Group extends GroupBase<Option>>

233

extends CommonPropsAndClassName<Option, IsMulti, Group> {

234

/** Whether the control is focused */

235

isFocused: boolean;

236

/** Whether the control is disabled */

237

isDisabled: boolean;

238

/** Child elements (ValueContainer, IndicatorsContainer) */

239

children: ReactNode;

240

/** Additional inner props passed to the control element */

241

innerProps: JSX.IntrinsicElements['div'];

242

}

243

244

/**

245

* Props for individual Option components

246

* @template Option - The option data type

247

* @template IsMulti - Boolean flag for multi-select

248

* @template Group - The group data type

249

*/

250

interface OptionProps<Option, IsMulti extends boolean, Group extends GroupBase<Option>>

251

extends CommonPropsAndClassName<Option, IsMulti, Group> {

252

/** The option data */

253

data: Option;

254

/** Whether this option is disabled */

255

isDisabled: boolean;

256

/** Whether this option is focused */

257

isFocused: boolean;

258

/** Whether this option is selected */

259

isSelected: boolean;

260

/** Child content (usually the option label) */

261

children: ReactNode;

262

/** Additional inner props passed to the option element */

263

innerProps: JSX.IntrinsicElements['div'];

264

}

265

266

/**

267

* Props for Menu component

268

* @template Option - The option data type

269

* @template IsMulti - Boolean flag for multi-select

270

* @template Group - The group data type

271

*/

272

interface MenuProps<Option, IsMulti extends boolean, Group extends GroupBase<Option>>

273

extends CommonPropsAndClassName<Option, IsMulti, Group> {

274

/** Child elements (MenuList) */

275

children: ReactNode;

276

/** Additional inner props passed to the menu element */

277

innerProps: JSX.IntrinsicElements['div'];

278

/** Menu placement */

279

placement: MenuPlacement;

280

}

281

282

/**

283

* Props for MultiValue components

284

* @template Option - The option data type

285

* @template IsMulti - Boolean flag for multi-select

286

* @template Group - The group data type

287

*/

288

interface MultiValueProps<Option, IsMulti extends boolean, Group extends GroupBase<Option>>

289

extends CommonPropsAndClassName<Option, IsMulti, Group> {

290

/** The option data for this multi-value */

291

data: Option;

292

/** Child elements (MultiValueContainer) */

293

children: ReactNode;

294

/** Index of this value in the values array */

295

index: number;

296

/** Whether this multi-value is disabled */

297

isDisabled: boolean;

298

/** Function to remove this value */

299

removeProps: {

300

onClick: MouseEventHandler<HTMLDivElement>;

301

onTouchEnd: TouchEventHandler<HTMLDivElement>;

302

onMouseDown: MouseEventHandler<HTMLDivElement>;

303

};

304

}

305

306

/**

307

* Props for SingleValue component

308

* @template Option - The option data type

309

* @template IsMulti - Boolean flag for multi-select

310

* @template Group - The group data type

311

*/

312

interface SingleValueProps<Option, IsMulti extends boolean, Group extends GroupBase<Option>>

313

extends CommonPropsAndClassName<Option, IsMulti, Group> {

314

/** The selected option data */

315

data: Option;

316

/** Whether the value is disabled */

317

isDisabled: boolean;

318

/** Child content (usually the option label) */

319

children: ReactNode;

320

}

321

322

/**

323

* Props for Input component

324

* @template Option - The option data type

325

* @template IsMulti - Boolean flag for multi-select

326

* @template Group - The group data type

327

*/

328

interface InputProps<Option, IsMulti extends boolean, Group extends GroupBase<Option>>

329

extends CommonPropsAndClassName<Option, IsMulti, Group> {

330

/** Current input value */

331

value: string;

332

/** Auto-complete attribute */

333

autoComplete: string;

334

/** Input ID */

335

id: string;

336

/** Whether the input is disabled */

337

isDisabled: boolean;

338

/** Whether the input is hidden */

339

isHidden: boolean;

340

/** Additional props passed to the input element */

341

innerProps?: JSX.IntrinsicElements['input'];

342

}

343

```

344

345

### Accessibility Types

346

347

Types for ARIA support and accessibility features.

348

349

```typescript { .api }

350

/**

351

* Configuration for ARIA live region messages

352

* @template Option - The option data type

353

* @template IsMulti - Boolean flag for multi-select

354

* @template Group - The group data type

355

*/

356

interface AriaLiveMessages<Option, IsMulti extends boolean, Group extends GroupBase<Option>> {

357

/** Message when guidance should be provided */

358

guidance?: (props: AriaGuidanceProps) => string;

359

/** Message when selection changes */

360

onChange?: (props: AriaOnChangeProps<Option, IsMulti>) => string;

361

/** Message when options are filtered */

362

onFilter?: (props: AriaOnFilterProps<Option>) => string;

363

/** Message when focus changes */

364

onFocus?: (props: AriaOnFocusProps<Option>) => string;

365

}

366

367

/**

368

* Props for guidance messages

369

*/

370

interface AriaGuidanceProps {

371

/** Whether the component is searchable */

372

isSearchable: boolean;

373

/** Whether multiple selection is enabled */

374

isMulti: boolean;

375

/** Current selection count */

376

selectionCount: number;

377

/** Tab index value */

378

tabSelectsValue: boolean;

379

}

380

381

/**

382

* Props for change announcement messages

383

* @template Option - The option data type

384

* @template IsMulti - Boolean flag for multi-select

385

*/

386

interface AriaOnChangeProps<Option, IsMulti extends boolean> {

387

/** The action that occurred */

388

action: ActionMeta<Option>['action'];

389

/** Label of affected option */

390

label?: string;

391

/** Labels of all affected options */

392

labels?: string[];

393

/** Current value after change */

394

value: string;

395

}

396

397

/**

398

* Props for focus announcement messages

399

* @template Option - The option data type

400

*/

401

interface AriaOnFocusProps<Option> {

402

/** Currently focused option */

403

focused: Option;

404

/** Label of focused option */

405

label: string;

406

/** Whether the option is selected */

407

isSelected: boolean;

408

/** Whether the option is disabled */

409

isDisabled: boolean;

410

}

411

412

/**

413

* Props for filter announcement messages

414

* @template Option - The option data type

415

*/

416

interface AriaOnFilterProps<Option> {

417

/** Current input value */

418

inputValue: string;

419

/** Array of filtered results */

420

resultsMessage: string;

421

}

422

```

423

424

### Utility Types

425

426

Helper types for advanced use cases and type manipulation.

427

428

```typescript { .api }

429

/**

430

* Extract the Option type from a Select component type

431

*/

432

type OptionTypeBase = {

433

label: ReactNode;

434

value: string | number;

435

isDisabled?: boolean;

436

};

437

438

/**

439

* Common props shared across all components

440

* @template Option - The option data type

441

* @template IsMulti - Boolean flag for multi-select

442

* @template Group - The group data type

443

*/

444

interface CommonPropsAndClassName<Option, IsMulti extends boolean, Group extends GroupBase<Option>> {

445

/** Additional CSS class name */

446

className?: string;

447

/** CSS class name prefix for BEM-style naming */

448

classNamePrefix?: string;

449

/** Component configuration */

450

selectProps: Props<Option, IsMulti, Group>;

451

}

452

453

/**

454

* Function type for getting option labels

455

* @template Option - The option data type

456

*/

457

type GetOptionLabel<Option> = (option: Option) => string;

458

459

/**

460

* Function type for getting option values

461

* @template Option - The option data type

462

*/

463

type GetOptionValue<Option> = (option: Option) => string;

464

465

/**

466

* Function type for checking if option is disabled

467

* @template Option - The option data type

468

*/

469

type IsOptionDisabled<Option> = (option: Option, selectValue: Options<Option>) => boolean;

470

471

/**

472

* Filter option with additional metadata

473

* @template Option - The option data type

474

*/

475

interface FilterOptionOption<Option> {

476

label: string;

477

value: string;

478

data: Option;

479

}

480

481

/**

482

* Function type for custom filtering

483

* @template Option - The option data type

484

*/

485

type FilterOptionFunction<Option> = (

486

option: FilterOptionOption<Option>,

487

inputValue: string

488

) => boolean;

489

```

490

491

**Usage Examples:**

492

493

```typescript

494

// Custom option type with additional metadata

495

interface UserOption extends OptionTypeBase {

496

value: string;

497

label: string;

498

email: string;

499

avatar: string;

500

role: 'admin' | 'user' | 'guest';

501

isDisabled?: boolean;

502

}

503

504

// Utility functions with proper typing

505

const getUserLabel: GetOptionLabel<UserOption> = (user) => user.label;

506

const getUserValue: GetOptionValue<UserOption> = (user) => user.value;

507

const isUserDisabled: IsOptionDisabled<UserOption> = (user) => user.role === 'guest';

508

509

// Custom component with proper typing

510

const UserOption: React.FC<OptionProps<UserOption, false, GroupBase<UserOption>>> = ({

511

data,

512

children,

513

isSelected,

514

isFocused,

515

...props

516

}) => (

517

<components.Option {...props} data={data} isSelected={isSelected} isFocused={isFocused}>

518

<div className="user-option">

519

<img src={data.avatar} alt="" className="avatar" />

520

<div>

521

<div className="name">{children}</div>

522

<div className="email">{data.email}</div>

523

<div className="role">{data.role}</div>

524

</div>

525

</div>

526

</components.Option>

527

);

528

529

// Typed select with custom option

530

const UserSelect = () => (

531

<Select<UserOption, false, GroupBase<UserOption>>

532

options={users}

533

getOptionLabel={getUserLabel}

534

getOptionValue={getUserValue}

535

isOptionDisabled={isUserDisabled}

536

components={{ Option: UserOption }}

537

/>

538

);

539

```

540

541

### Advanced Generic Types

542

543

Complex type utilities for advanced customization scenarios.

544

545

```typescript { .api }

546

/**

547

* Extract component props type from SelectComponentsConfig

548

* @template K - The component key

549

* @template Option - The option data type

550

* @template IsMulti - Boolean flag for multi-select

551

* @template Group - The group data type

552

*/

553

type ComponentProps<

554

K extends keyof SelectComponentsConfig<any, any, any>,

555

Option,

556

IsMulti extends boolean,

557

Group extends GroupBase<Option>

558

> = SelectComponentsConfig<Option, IsMulti, Group>[K] extends ComponentType<infer P> ? P : never;

559

560

/**

561

* Utility type for creating themed style functions

562

* @template T - The component props type

563

*/

564

type ThemedStyleFunction<T> = (base: CSSObject, state: T, theme: Theme) => CSSObject;

565

566

/**

567

* Helper type for creating strongly-typed component factories

568

* @template Option - The option data type

569

* @template IsMulti - Boolean flag for multi-select

570

* @template Group - The group data type

571

*/

572

type SelectComponentFactory<Option, IsMulti extends boolean, Group extends GroupBase<Option>> = {

573

[K in keyof SelectComponentsConfig<Option, IsMulti, Group>]: ComponentType<

574

ComponentProps<K, Option, IsMulti, Group>

575

>;

576

};

577

578

/**

579

* Utility type for partial component configurations

580

* @template Option - The option data type

581

* @template IsMulti - Boolean flag for multi-select

582

* @template Group - The group data type

583

*/

584

type PartialSelectComponents<Option, IsMulti extends boolean, Group extends GroupBase<Option>> =

585

Partial<SelectComponentsConfig<Option, IsMulti, Group>>;

586

```

587

588

**Usage Examples:**

589

590

```typescript

591

// Strongly-typed component factory

592

const createComponents = <Option, IsMulti extends boolean, Group extends GroupBase<Option>>():

593

SelectComponentFactory<Option, IsMulti, Group> => ({

594

Option: (props: ComponentProps<'Option', Option, IsMulti, Group>) => (

595

<div {...props.innerProps}>

596

{props.children}

597

</div>

598

),

599

Control: (props: ComponentProps<'Control', Option, IsMulti, Group>) => (

600

<div {...props.innerProps}>

601

{props.children}

602

</div>

603

),

604

// ... other components

605

});

606

607

// Themed style utilities

608

const createThemedStyles = <Option, IsMulti extends boolean, Group extends GroupBase<Option>>() => ({

609

control: ((base, state, theme) => ({

610

...base,

611

borderColor: state.isFocused ? theme.colors.primary : theme.colors.neutral20,

612

boxShadow: state.isFocused ? `0 0 0 1px ${theme.colors.primary}` : 'none',

613

})) as ThemedStyleFunction<ControlProps<Option, IsMulti, Group>>,

614

615

option: ((base, state, theme) => ({

616

...base,

617

backgroundColor: state.isSelected

618

? theme.colors.primary

619

: state.isFocused

620

? theme.colors.primary25

621

: 'transparent',

622

color: state.isSelected ? 'white' : theme.colors.neutral80,

623

})) as ThemedStyleFunction<OptionProps<Option, IsMulti, Group>>,

624

});

625

```