or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

date-time.mddrag-drop.mdfocus-management.mdform-controls.mdindex.mdinteractions.mdinternationalization.mdlayout-navigation.mdoverlays-modals.mdselection-controls.mdtags.mdtoast-notifications.mdutilities.md

overlays-modals.mddocs/

0

# Overlays and Modals

1

2

Overlay components including dialogs, popovers, tooltips, and modals with proper focus management, positioning, and accessibility. All overlays handle escape key, click outside, and focus restoration.

3

4

## Capabilities

5

6

### Dialog

7

8

Provides modal dialog behavior with focus containment and accessibility.

9

10

```typescript { .api }

11

/**

12

* Provides dialog behavior and accessibility

13

* @param props - Dialog configuration

14

* @param ref - Ref to the dialog element

15

* @returns Dialog props

16

*/

17

function useDialog(props: AriaDialogProps, ref: RefObject<Element>): DialogAria;

18

19

interface AriaDialogProps {

20

/** Role of the dialog */

21

role?: 'dialog' | 'alertdialog';

22

/** ID of the dialog */

23

id?: string;

24

/** Accessible name for the dialog */

25

'aria-label'?: string;

26

/** ID of element that labels the dialog */

27

'aria-labelledby'?: string;

28

/** ID of element that describes the dialog */

29

'aria-describedby'?: string;

30

}

31

32

interface DialogAria {

33

/** Props for the dialog element */

34

dialogProps: DOMAttributes<Element>;

35

/** Props for the dialog title element */

36

titleProps: DOMAttributes<Element>;

37

}

38

```

39

40

### Disclosure

41

42

Provides disclosure behavior for expandable/collapsible content sections.

43

44

```typescript { .api }

45

/**

46

* Provides disclosure behavior and accessibility

47

* @param props - Disclosure configuration

48

* @param ref - Ref to the disclosure element

49

* @returns Disclosure props and state

50

*/

51

function useDisclosure(props: AriaDisclosureProps, ref: RefObject<Element>): DisclosureAria;

52

53

interface AriaDisclosureProps {

54

/** Whether the disclosure is expanded */

55

isExpanded?: boolean;

56

/** Default expanded state (uncontrolled) */

57

defaultExpanded?: boolean;

58

/** Handler called when expansion changes */

59

onExpandedChange?: (isExpanded: boolean) => void;

60

/** Whether the disclosure is disabled */

61

isDisabled?: boolean;

62

}

63

64

interface DisclosureAria {

65

/** Props for the disclosure button */

66

buttonProps: ButtonHTMLAttributes<HTMLButtonElement>;

67

/** Props for the disclosure panel */

68

panelProps: DOMAttributes<Element>;

69

/** Whether the disclosure is expanded */

70

isExpanded: boolean;

71

}

72

```

73

74

### Modal

75

76

Provides modal overlay behavior with backdrop and focus management.

77

78

```typescript { .api }

79

/**

80

* Provides modal behavior and accessibility

81

* @param options - Modal configuration options

82

* @returns Modal props and state

83

*/

84

function useModal(options?: AriaModalOptions): ModalAria;

85

86

/**

87

* Provides modal overlay behavior

88

* @param props - Modal overlay configuration

89

* @param state - Modal state

90

* @param ref - Ref to the overlay element

91

* @returns Modal overlay props

92

*/

93

function useModalOverlay(props: AriaModalOverlayProps, state: OverlayTriggerState, ref: RefObject<Element>): ModalOverlayAria;

94

95

/**

96

* Provides modal provider context

97

* @param props - Modal provider configuration

98

* @returns Modal provider props and state

99

*/

100

function useModalProvider(props: ModalProviderProps): ModalProviderAria;

101

102

interface AriaModalOptions {

103

/** Whether the modal is open */

104

isOpen?: boolean;

105

/** Handler called when the modal should close */

106

onClose?: () => void;

107

/** Whether the modal is keyboard modal */

108

isKeyboardDismissDisabled?: boolean;

109

/** Whether to disable outside clicks */

110

isDismissable?: boolean;

111

}

112

113

interface ModalAria {

114

/** Props for the modal element */

115

modalProps: DOMAttributes<Element>;

116

/** Props for the underlay element */

117

underlayProps: DOMAttributes<Element>;

118

}

119

120

interface AriaModalOverlayProps {

121

/** Whether the overlay is open */

122

isOpen?: boolean;

123

/** Handler called when the overlay should close */

124

onClose?: () => void;

125

/** Whether the overlay is dismissable */

126

isDismissable?: boolean;

127

/** Whether keyboard dismissal is disabled */

128

isKeyboardDismissDisabled?: boolean;

129

/** Whether to prevent scrolling */

130

shouldCloseOnBlur?: boolean;

131

}

132

133

interface ModalOverlayAria {

134

/** Props for the modal overlay element */

135

modalProps: DOMAttributes<Element>;

136

/** Props for the underlay element */

137

underlayProps: DOMAttributes<Element>;

138

}

139

```

140

141

### Popover

142

143

Provides popover behavior with positioning and trigger management.

144

145

```typescript { .api }

146

/**

147

* Provides popover behavior and accessibility

148

* @param props - Popover configuration

149

* @param state - Popover state

150

* @param ref - Ref to the popover element

151

* @returns Popover props

152

*/

153

function usePopover(props: AriaPopoverProps, state: PopoverState, ref: RefObject<Element>): PopoverAria;

154

155

interface AriaPopoverProps {

156

/** Type of popover */

157

triggerRef: RefObject<Element>;

158

/** Whether the popover is non-modal */

159

isNonModal?: boolean;

160

/** Trigger source for the popover */

161

triggerSource?: string;

162

/** Whether keyboard dismissal is disabled */

163

isKeyboardDismissDisabled?: boolean;

164

/** Whether the popover should close on blur */

165

shouldCloseOnBlur?: boolean;

166

/** Whether to flip placement when space is limited */

167

shouldFlip?: boolean;

168

/** Boundary element for flipping */

169

boundaryElement?: Element;

170

/** Scroll ref for repositioning */

171

scrollRef?: RefObject<Element>;

172

/** Whether the popover should update position */

173

shouldUpdatePosition?: boolean;

174

/** Arrow boundary offset */

175

arrowBoundaryOffset?: number;

176

/** Placement of the popover */

177

placement?: Placement;

178

/** Container padding */

179

containerPadding?: number;

180

/** Offset from trigger */

181

offset?: number;

182

/** Cross offset */

183

crossOffset?: number;

184

/** Whether the popover should close on interact outside */

185

shouldCloseOnInteractOutside?: (element: Element) => boolean;

186

/** Max height of the popover */

187

maxHeight?: number;

188

/** Arrow size */

189

arrowSize?: number;

190

/** Arrow boundary offset */

191

arrowBoundaryOffset?: number;

192

}

193

194

interface PopoverAria {

195

/** Props for the popover element */

196

popoverProps: DOMAttributes<Element>;

197

/** Props for the arrow element */

198

arrowProps: DOMAttributes<Element>;

199

/** Placement that was actually used */

200

placement: PlacementAxis;

201

/** Arrow props */

202

arrowProps: DOMAttributes<Element>;

203

/** Props for the underlay element */

204

underlayProps: DOMAttributes<Element>;

205

}

206

```

207

208

### Overlay

209

210

Provides base overlay behavior and positioning.

211

212

```typescript { .api }

213

/**

214

* Provides overlay behavior and accessibility

215

* @param props - Overlay configuration

216

* @param ref - Ref to the overlay element

217

* @returns Overlay props

218

*/

219

function useOverlay(props: AriaOverlayProps, ref: RefObject<Element>): OverlayAria;

220

221

/**

222

* Provides overlay positioning behavior

223

* @param props - Position configuration

224

* @param ref - Ref to the overlay element

225

* @returns Position props and placement

226

*/

227

function useOverlayPosition(props: AriaPositionProps, ref: RefObject<Element>): PositionAria;

228

229

/**

230

* Provides overlay trigger behavior

231

* @param props - Overlay trigger configuration

232

* @param state - Overlay trigger state

233

* @param ref - Ref to the trigger element

234

* @returns Overlay trigger props

235

*/

236

function useOverlayTrigger(props: OverlayTriggerProps, state: OverlayTriggerState, ref?: RefObject<Element>): OverlayTriggerAria;

237

238

interface AriaOverlayProps {

239

/** Whether the overlay is open */

240

isOpen?: boolean;

241

/** Handler called when the overlay should close */

242

onClose?: () => void;

243

/** Whether the overlay should close on blur */

244

shouldCloseOnBlur?: boolean;

245

/** Whether the overlay is dismissable */

246

isDismissable?: boolean;

247

/** Whether keyboard dismissal is disabled */

248

isKeyboardDismissDisabled?: boolean;

249

/** Whether to prevent scrolling */

250

shouldCloseOnInteractOutside?: (element: Element) => boolean;

251

}

252

253

interface OverlayAria {

254

/** Props for the overlay element */

255

overlayProps: DOMAttributes<Element>;

256

/** Props for the underlay element */

257

underlayProps: DOMAttributes<Element>;

258

}

259

260

interface AriaPositionProps extends PositionProps {

261

/** Element to position relative to */

262

targetRef: RefObject<Element>;

263

/** Element to position */

264

overlayRef: RefObject<Element>;

265

/** Scroll refs for repositioning */

266

scrollRef?: RefObject<Element>;

267

/** Placement preference */

268

placement?: Placement;

269

/** Container padding */

270

containerPadding?: number;

271

/** Offset from target */

272

offset?: number;

273

/** Cross-axis offset */

274

crossOffset?: number;

275

/** Whether to flip when space is limited */

276

shouldFlip?: boolean;

277

/** Boundary element */

278

boundaryElement?: Element;

279

/** Whether position should update */

280

shouldUpdatePosition?: boolean;

281

/** Whether the overlay is open */

282

isOpen?: boolean;

283

/** Handler called when the overlay should close */

284

onClose?: () => void;

285

/** Max height */

286

maxHeight?: number;

287

/** Arrow size for popover arrows */

288

arrowSize?: number;

289

/** Arrow boundary offset */

290

arrowBoundaryOffset?: number;

291

}

292

293

interface PositionAria {

294

/** Props for the overlay element */

295

overlayProps: DOMAttributes<Element>;

296

/** Props for the arrow element */

297

arrowProps: DOMAttributes<Element>;

298

/** Placement that was used */

299

placement: PlacementAxis;

300

/** Update position manually */

301

updatePosition(): void;

302

}

303

304

interface OverlayTriggerProps {

305

/** Type of overlay */

306

type: 'dialog' | 'menu' | 'listbox' | 'tree' | 'grid';

307

/** Whether the overlay is open */

308

isOpen?: boolean;

309

/** Default open state (uncontrolled) */

310

defaultOpen?: boolean;

311

/** Handler called when open state changes */

312

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

313

}

314

315

interface OverlayTriggerAria {

316

/** Props for the trigger element */

317

triggerProps: ButtonHTMLAttributes<HTMLButtonElement>;

318

/** Props for the overlay element */

319

overlayProps: DOMAttributes<Element>;

320

}

321

```

322

323

### Tooltip

324

325

Provides tooltip behavior with hover and focus triggers.

326

327

```typescript { .api }

328

/**

329

* Provides tooltip behavior and accessibility

330

* @param props - Tooltip configuration

331

* @param state - Tooltip trigger state

332

* @returns Tooltip props

333

*/

334

function useTooltip(props: AriaTooltipProps, state: TooltipTriggerState): TooltipAria;

335

336

/**

337

* Provides tooltip trigger behavior

338

* @param props - Tooltip trigger configuration

339

* @param state - Tooltip trigger state

340

* @param ref - Ref to the trigger element

341

* @returns Tooltip trigger props

342

*/

343

function useTooltipTrigger(props: TooltipTriggerProps, state: TooltipTriggerState, ref?: RefObject<Element>): TooltipTriggerAria;

344

345

interface AriaTooltipProps {

346

/** Whether the tooltip is open */

347

isOpen?: boolean;

348

/** ID for the tooltip */

349

id?: string;

350

}

351

352

interface TooltipAria {

353

/** Props for the tooltip element */

354

tooltipProps: DOMAttributes<Element>;

355

}

356

357

interface TooltipTriggerProps {

358

/** Whether the tooltip is disabled */

359

isDisabled?: boolean;

360

/** Delay before showing tooltip */

361

delay?: number;

362

/** Close delay */

363

closeDelay?: number;

364

/** Trigger events */

365

trigger?: 'focus' | 'focus+hover';

366

/** Whether the tooltip is open */

367

isOpen?: boolean;

368

/** Default open state (uncontrolled) */

369

defaultOpen?: boolean;

370

/** Handler called when open state changes */

371

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

372

}

373

374

interface TooltipTriggerAria {

375

/** Props for the trigger element */

376

triggerProps: DOMAttributes<Element>;

377

/** Props for the tooltip element */

378

tooltipProps: DOMAttributes<Element>;

379

}

380

```

381

382

### Toast

383

384

Provides toast notification behavior with timeout and positioning.

385

386

```typescript { .api }

387

/**

388

* Provides toast behavior and accessibility

389

* @param props - Toast configuration

390

* @param state - Toast state

391

* @param ref - Ref to the toast element

392

* @returns Toast props

393

*/

394

function useToast(props: AriaToastProps, state: ToastState, ref: RefObject<Element>): ToastAria;

395

396

/**

397

* Provides toast region behavior for managing multiple toasts

398

* @param props - Toast region configuration

399

* @param state - Toast region state

400

* @param ref - Ref to the toast region element

401

* @returns Toast region props

402

*/

403

function useToastRegion(props: AriaToastRegionProps, state: ToastRegionState, ref: RefObject<Element>): ToastRegionAria;

404

405

interface AriaToastProps {

406

/** Toast priority level */

407

priority?: 'low' | 'normal' | 'high';

408

/** Whether the toast should auto-dismiss */

409

shouldCloseOnAction?: boolean;

410

/** Handler called when the toast is closed */

411

onClose?: () => void;

412

}

413

414

interface ToastAria {

415

/** Props for the toast element */

416

toastProps: DOMAttributes<Element>;

417

/** Props for the title element */

418

titleProps: DOMAttributes<Element>;

419

/** Props for the description element */

420

descriptionProps: DOMAttributes<Element>;

421

/** Props for the close button */

422

closeButtonProps: ButtonHTMLAttributes<HTMLButtonElement>;

423

}

424

425

interface AriaToastRegionProps {

426

/** Accessible label for the toast region */

427

'aria-label'?: string;

428

/** ID of element that labels the toast region */

429

'aria-labelledby'?: string;

430

}

431

432

interface ToastRegionAria {

433

/** Props for the toast region element */

434

regionProps: DOMAttributes<Element>;

435

}

436

```

437

438

### Prevent Scroll

439

440

Provides scroll prevention behavior for modal overlays.

441

442

```typescript { .api }

443

/**

444

* Provides scroll prevention behavior

445

* @param options - Scroll prevention options

446

* @returns Scroll prevention state

447

*/

448

function usePreventScroll(options?: { isDisabled?: boolean }): void;

449

```

450

451

### Overlay Components

452

453

```typescript { .api }

454

/**

455

* Button for dismissing overlays

456

*/

457

function DismissButton(props: DismissButtonProps): JSX.Element;

458

459

/**

460

* Provider for modal context

461

*/

462

function ModalProvider(props: { children: ReactNode }): JSX.Element;

463

464

/**

465

* Base overlay component

466

*/

467

function Overlay(props: OverlayProps): JSX.Element;

468

469

/**

470

* Container for overlay portals

471

*/

472

function OverlayContainer(props: OverlayContainerProps): JSX.Element;

473

474

/**

475

* Provider for overlay context

476

*/

477

function OverlayProvider(props: { children: ReactNode }): JSX.Element;

478

479

/**

480

* Portal provider (marked as unsafe)

481

*/

482

function UNSAFE_PortalProvider(props: { children: ReactNode; getContainer?: () => Element }): JSX.Element;

483

484

interface DismissButtonProps {

485

/** Handler called when button is pressed */

486

onDismiss?: () => void;

487

}

488

489

interface OverlayProps {

490

/** Children to render in overlay */

491

children: ReactNode;

492

/** Whether the overlay is open */

493

isOpen?: boolean;

494

/** Container to render overlay in */

495

container?: Element;

496

/** Handler called when overlay should close */

497

onClose?: () => void;

498

}

499

500

interface OverlayContainerProps {

501

/** Container element to render portals in */

502

portalContainer?: Element;

503

/** Children to render */

504

children: ReactNode;

505

}

506

```

507

508

## Types

509

510

```typescript { .api }

511

type Placement =

512

| 'bottom'

513

| 'bottom left'

514

| 'bottom right'

515

| 'bottom start'

516

| 'bottom end'

517

| 'top'

518

| 'top left'

519

| 'top right'

520

| 'top start'

521

| 'top end'

522

| 'left'

523

| 'left top'

524

| 'left bottom'

525

| 'start'

526

| 'start top'

527

| 'start bottom'

528

| 'right'

529

| 'right top'

530

| 'right bottom'

531

| 'end'

532

| 'end top'

533

| 'end bottom';

534

535

type PlacementAxis = 'top' | 'bottom' | 'left' | 'right' | 'center';

536

537

interface OverlayTriggerState {

538

/** Whether the overlay is open */

539

isOpen: boolean;

540

/** Set the open state */

541

setOpen(isOpen: boolean): void;

542

/** Open the overlay */

543

open(): void;

544

/** Close the overlay */

545

close(): void;

546

/** Toggle the overlay */

547

toggle(): void;

548

}

549

550

interface PopoverState extends OverlayTriggerState {

551

/** Trigger source */

552

triggerSource?: string;

553

/** Set trigger source */

554

setTriggerSource(source: string): void;

555

}

556

557

interface TooltipTriggerState extends OverlayTriggerState {

558

/** Whether the tooltip is immediately open */

559

isWarmupFinished: boolean;

560

/** Warm up the tooltip globally */

561

warmUp(): void;

562

/** Cool down the tooltip globally */

563

coolDown(): void;

564

}

565

566

interface ToastState {

567

/** Whether the toast is visible */

568

isVisible: boolean;

569

/** Whether the toast is paused */

570

isPaused: boolean;

571

/** Remaining time before auto-dismiss */

572

remainingTime: number;

573

/** Pause the toast */

574

pause(): void;

575

/** Resume the toast */

576

resume(): void;

577

/** Close the toast */

578

close(): void;

579

}

580

581

interface ToastRegionState {

582

/** List of toasts in the region */

583

toasts: Toast[];

584

/** Add a toast */

585

add(toast: Toast): void;

586

/** Remove a toast */

587

remove(key: string): void;

588

/** Pause all toasts */

589

pauseAll(): void;

590

/** Resume all toasts */

591

resumeAll(): void;

592

}

593

594

interface Toast {

595

/** Unique key for the toast */

596

key: string;

597

/** Toast content */

598

content: ReactNode;

599

/** Toast priority */

600

priority?: 'low' | 'normal' | 'high';

601

/** Auto-dismiss timeout */

602

timeout?: number;

603

/** Handler called when closed */

604

onClose?: () => void;

605

}

606

607

interface PositionProps {

608

/** Container padding */

609

containerPadding?: number;

610

/** Offset from target */

611

offset?: number;

612

/** Cross-axis offset */

613

crossOffset?: number;

614

/** Whether to flip placement */

615

shouldFlip?: boolean;

616

/** Boundary element */

617

boundaryElement?: Element;

618

/** Max height */

619

maxHeight?: number;

620

}

621

```