or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

core-system.mddata-display.mddate-time.mdfeedback.mdforms.mdindex.mdinputs.mdinteractions.mdlayout.mdnavigation.mdoverlays.mdutilities.md

overlays.mddocs/

0

# Overlay Components

1

2

NextUI provides comprehensive overlay components for creating modal dialogs, popovers, dropdowns, and drawers with advanced positioning, animation, and interaction capabilities.

3

4

## Capabilities

5

6

### Modal

7

8

A flexible modal dialog component with customizable backdrop, scrolling behavior, and animations for displaying content above the main interface.

9

10

```typescript { .api }

11

interface ModalProps {

12

/** Modal content */

13

children: React.ReactNode;

14

/** Modal size */

15

size?: "xs" | "sm" | "md" | "lg" | "xl" | "2xl" | "3xl" | "4xl" | "5xl" | "full";

16

/** Border radius */

17

radius?: "none" | "sm" | "md" | "lg";

18

/** Shadow intensity */

19

shadow?: "sm" | "md" | "lg";

20

/** Backdrop style */

21

backdrop?: "transparent" | "opaque" | "blur";

22

/** Scrolling behavior */

23

scrollBehavior?: "inside" | "outside";

24

/** Modal placement */

25

placement?: "auto" | "top" | "center" | "bottom";

26

/** Whether modal is open */

27

isOpen?: boolean;

28

/** Default open state */

29

defaultOpen?: boolean;

30

/** Whether modal can be dismissed */

31

isDismissable?: boolean;

32

/** Whether keyboard dismiss is disabled */

33

isKeyboardDismissDisabled?: boolean;

34

/** Hide close button */

35

hideCloseButton?: boolean;

36

/** Block scroll on body */

37

shouldBlockScroll?: boolean;

38

/** Portal container */

39

portalContainer?: Element;

40

/** Disable animations */

41

disableAnimation?: boolean;

42

/** Motion configuration */

43

motionProps?: MotionProps;

44

/** Custom CSS class */

45

className?: string;

46

/** Slot-based styling */

47

classNames?: SlotsToClasses<ModalSlots>;

48

/** Open change handler */

49

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

50

/** Close handler */

51

onClose?: () => void;

52

}

53

54

type ModalSlots =

55

| "wrapper" | "backdrop" | "base" | "header" | "body"

56

| "footer" | "closeButton";

57

58

function Modal(props: ModalProps): JSX.Element;

59

60

/**

61

* Hook for Modal state management

62

*/

63

function useModal(props: ModalProps): {

64

Component: React.ElementType;

65

slots: Record<ModalSlots, string>;

66

classNames: SlotsToClasses<ModalSlots>;

67

isOpen: boolean;

68

onClose: () => void;

69

getModalProps: () => any;

70

getBackdropProps: () => any;

71

getDialogProps: () => any;

72

};

73

```

74

75

### Modal Structure Components

76

77

Components for organizing modal content with proper accessibility and styling.

78

79

```typescript { .api }

80

interface ModalContentProps {

81

/** Modal content sections */

82

children?: React.ReactNode;

83

/** Custom CSS class */

84

className?: string;

85

}

86

87

interface ModalHeaderProps {

88

/** Header content */

89

children?: React.ReactNode;

90

/** Custom CSS class */

91

className?: string;

92

}

93

94

interface ModalBodyProps {

95

/** Body content */

96

children?: React.ReactNode;

97

/** Custom CSS class */

98

className?: string;

99

}

100

101

interface ModalFooterProps {

102

/** Footer content */

103

children?: React.ReactNode;

104

/** Custom CSS class */

105

className?: string;

106

}

107

108

function ModalContent(props: ModalContentProps): JSX.Element;

109

function ModalHeader(props: ModalHeaderProps): JSX.Element;

110

function ModalBody(props: ModalBodyProps): JSX.Element;

111

function ModalFooter(props: ModalFooterProps): JSX.Element;

112

```

113

114

**Modal Usage Example:**

115

116

```typescript

117

import {

118

Modal, ModalContent, ModalHeader, ModalBody, ModalFooter,

119

Button, Input, Checkbox, Link

120

} from "@nextui-org/react";

121

import { useDisclosure } from "@nextui-org/react";

122

123

function ModalExample() {

124

const { isOpen, onOpen, onOpenChange } = useDisclosure();

125

126

return (

127

<>

128

<Button onPress={onOpen} color="primary">

129

Open Modal

130

</Button>

131

<Modal

132

isOpen={isOpen}

133

onOpenChange={onOpenChange}

134

placement="top-center"

135

backdrop="blur"

136

>

137

<ModalContent>

138

{(onClose) => (

139

<>

140

<ModalHeader className="flex flex-col gap-1">

141

Log in

142

</ModalHeader>

143

<ModalBody>

144

<Input

145

autoFocus

146

label="Email"

147

placeholder="Enter your email"

148

variant="bordered"

149

/>

150

<Input

151

label="Password"

152

placeholder="Enter your password"

153

type="password"

154

variant="bordered"

155

/>

156

<div className="flex py-2 px-1 justify-between">

157

<Checkbox

158

classNames={{

159

label: "text-small",

160

}}

161

>

162

Remember me

163

</Checkbox>

164

<Link color="primary" href="#" size="sm">

165

Forgot password?

166

</Link>

167

</div>

168

</ModalBody>

169

<ModalFooter>

170

<Button color="danger" variant="flat" onPress={onClose}>

171

Close

172

</Button>

173

<Button color="primary" onPress={onClose}>

174

Sign in

175

</Button>

176

</ModalFooter>

177

</>

178

)}

179

</ModalContent>

180

</Modal>

181

</>

182

);

183

}

184

```

185

186

### Modal Context

187

188

Context system for sharing modal state across modal components.

189

190

```typescript { .api }

191

interface ModalProviderProps {

192

children: React.ReactNode;

193

value: ModalContextValue;

194

}

195

196

interface ModalContextValue {

197

slots: Record<ModalSlots, string>;

198

classNames?: SlotsToClasses<ModalSlots>;

199

isOpen?: boolean;

200

backdrop?: string;

201

hideCloseButton?: boolean;

202

motionProps?: MotionProps;

203

onClose?: () => void;

204

}

205

206

const ModalProvider: React.FC<ModalProviderProps>;

207

208

/**

209

* Hook to access modal context

210

* @throws Error if used outside ModalProvider

211

*/

212

function useModalContext(): ModalContextValue;

213

```

214

215

### Popover

216

217

A floating content container that appears relative to a trigger element with flexible positioning and content options.

218

219

```typescript { .api }

220

interface PopoverProps {

221

/** Popover content including trigger and content */

222

children: React.ReactNode;

223

/** Popover size */

224

size?: "sm" | "md" | "lg";

225

/** Color theme */

226

color?: "default" | "foreground" | "primary" | "secondary" | "success" | "warning" | "danger";

227

/** Border radius */

228

radius?: "none" | "sm" | "md" | "lg" | "full";

229

/** Shadow intensity */

230

shadow?: "sm" | "md" | "lg";

231

/** Backdrop style */

232

backdrop?: "transparent" | "opaque" | "blur";

233

/** Popover placement */

234

placement?: Placement;

235

/** Whether popover is open */

236

isOpen?: boolean;

237

/** Default open state */

238

defaultOpen?: boolean;

239

/** Whether popover should flip to fit */

240

shouldFlip?: boolean;

241

/** Whether to update position on scroll */

242

shouldUpdatePosition?: boolean;

243

/** Block scroll on body */

244

shouldBlockScroll?: boolean;

245

/** Whether popover can be dismissed */

246

isDismissable?: boolean;

247

/** Whether to close on blur */

248

shouldCloseOnBlur?: boolean;

249

/** Custom interact outside handler */

250

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

251

/** Whether keyboard dismiss is disabled */

252

isKeyboardDismissDisabled?: boolean;

253

/** Show arrow pointer */

254

showArrow?: boolean;

255

/** Offset from target */

256

offset?: number;

257

/** Cross-axis offset */

258

crossOffset?: number;

259

/** Container padding for flip calculations */

260

containerPadding?: number;

261

/** Trigger element ref */

262

triggerRef?: React.RefObject<Element>;

263

/** Scroll container ref */

264

scrollRef?: React.RefObject<Element>;

265

/** Portal container */

266

portalContainer?: Element;

267

/** Disable animations */

268

disableAnimation?: boolean;

269

/** Motion configuration */

270

motionProps?: MotionProps;

271

/** Custom CSS class */

272

className?: string;

273

/** Slot-based styling */

274

classNames?: SlotsToClasses<PopoverSlots>;

275

/** Open change handler */

276

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

277

}

278

279

type PopoverSlots = "base" | "trigger" | "backdrop" | "arrow" | "content";

280

281

function Popover(props: PopoverProps): JSX.Element;

282

283

/**

284

* Hook for Popover state management

285

*/

286

function usePopover(props: PopoverProps): {

287

Component: React.ElementType;

288

state: OverlayTriggerState;

289

slots: Record<PopoverSlots, string>;

290

classNames: SlotsToClasses<PopoverSlots>;

291

isOpen: boolean;

292

getPopoverProps: () => any;

293

getTriggerProps: () => any;

294

getContentProps: () => any;

295

};

296

```

297

298

### Popover Structure Components

299

300

Components for organizing popover content and trigger elements.

301

302

```typescript { .api }

303

interface PopoverTriggerProps {

304

/** Trigger element */

305

children: React.ReactElement;

306

}

307

308

interface PopoverContentProps {

309

/** Popover content */

310

children?: React.ReactNode;

311

/** Custom CSS class */

312

className?: string;

313

}

314

315

function PopoverTrigger(props: PopoverTriggerProps): JSX.Element;

316

function PopoverContent(props: PopoverContentProps): JSX.Element;

317

```

318

319

**Popover Usage Examples:**

320

321

```typescript

322

import {

323

Popover, PopoverTrigger, PopoverContent,

324

Button, Input, Card, CardBody, CardHeader

325

} from "@nextui-org/react";

326

327

function PopoverExamples() {

328

return (

329

<div className="space-y-4">

330

{/* Basic popover */}

331

<Popover placement="bottom" showArrow={true}>

332

<PopoverTrigger>

333

<Button>Open Popover</Button>

334

</PopoverTrigger>

335

<PopoverContent>

336

<div className="px-1 py-2">

337

<div className="text-small font-bold">Popover Content</div>

338

<div className="text-tiny">This is the popover content</div>

339

</div>

340

</PopoverContent>

341

</Popover>

342

343

{/* Form in popover */}

344

<Popover placement="bottom" backdrop="blur">

345

<PopoverTrigger>

346

<Button color="primary">Quick Action</Button>

347

</PopoverTrigger>

348

<PopoverContent className="w-[240px]">

349

{(titleProps) => (

350

<div className="px-1 py-2 w-full">

351

<p className="text-small font-bold text-foreground" {...titleProps}>

352

Quick Settings

353

</p>

354

<div className="mt-2 flex flex-col gap-2 w-full">

355

<Input label="Name" size="sm" variant="bordered" />

356

<Input label="Email" size="sm" variant="bordered" />

357

<Button size="sm" color="primary">

358

Save

359

</Button>

360

</div>

361

</div>

362

)}

363

</PopoverContent>

364

</Popover>

365

366

{/* Card in popover */}

367

<Popover>

368

<PopoverTrigger>

369

<Button variant="bordered">Show Details</Button>

370

</PopoverTrigger>

371

<PopoverContent className="p-0">

372

<Card shadow="none" className="max-w-[300px] border-none bg-transparent">

373

<CardHeader className="pb-0 pt-2 px-4 flex-col items-start">

374

<p className="text-tiny uppercase font-bold">Daily Mix</p>

375

<small className="text-default-500">12 Tracks</small>

376

<h4 className="font-bold text-large">Frontend Radio</h4>

377

</CardHeader>

378

<CardBody className="overflow-visible py-2">

379

<p className="text-small text-default-500">

380

The latest tracks from your favorite artists.

381

</p>

382

</CardBody>

383

</Card>

384

</PopoverContent>

385

</Popover>

386

</div>

387

);

388

}

389

```

390

391

### Free Solo Popover

392

393

A standalone popover component that doesn't require a trigger wrapper.

394

395

```typescript { .api }

396

interface FreeSoloPopoverProps {

397

/** Popover content */

398

children: React.ReactNode;

399

/** Target element to position relative to */

400

triggerRef: React.RefObject<Element>;

401

/** Whether popover is open */

402

isOpen?: boolean;

403

/** Popover placement */

404

placement?: Placement;

405

/** Show arrow pointer */

406

showArrow?: boolean;

407

/** Offset from target */

408

offset?: number;

409

/** Custom CSS class */

410

className?: string;

411

/** Slot-based styling */

412

classNames?: SlotsToClasses<PopoverSlots>;

413

/** Open change handler */

414

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

415

}

416

417

function FreeSoloPopover(props: FreeSoloPopoverProps): JSX.Element;

418

```

419

420

### Popover Context

421

422

Context system for sharing popover state across popover components.

423

424

```typescript { .api }

425

interface PopoverProviderProps {

426

children: React.ReactNode;

427

value: PopoverContextValue;

428

}

429

430

interface PopoverContextValue {

431

state: OverlayTriggerState;

432

slots: Record<PopoverSlots, string>;

433

classNames?: SlotsToClasses<PopoverSlots>;

434

showArrow?: boolean;

435

backdrop?: string;

436

motionProps?: MotionProps;

437

}

438

439

const PopoverProvider: React.FC<PopoverProviderProps>;

440

441

/**

442

* Hook to access popover context

443

* @throws Error if used outside PopoverProvider

444

*/

445

function usePopoverContext(): PopoverContextValue;

446

```

447

448

### Dropdown

449

450

A composite component combining popover functionality with menu items for creating dropdown menus.

451

452

```typescript { .api }

453

interface DropdownProps {

454

/** Dropdown content including trigger and menu */

455

children: React.ReactNode;

456

/** Dropdown type */

457

type?: "menu" | "listbox";

458

/** Trigger action */

459

trigger?: "press" | "longPress";

460

/** Whether dropdown is disabled */

461

isDisabled?: boolean;

462

/** Close on select */

463

closeOnSelect?: boolean;

464

/** Whether dropdown should flip to fit */

465

shouldFlip?: boolean;

466

/** Block scroll on body */

467

shouldBlockScroll?: boolean;

468

/** Show arrow pointer */

469

showArrow?: boolean;

470

/** Portal container */

471

portalContainer?: Element;

472

/** Disable animations */

473

disableAnimation?: boolean;

474

/** Custom CSS class */

475

className?: string;

476

/** Slot-based styling */

477

classNames?: SlotsToClasses<DropdownSlots>;

478

}

479

480

type DropdownSlots = "base" | "trigger" | "backdrop" | "arrow" | "content";

481

482

function Dropdown(props: DropdownProps): JSX.Element;

483

484

/**

485

* Hook for Dropdown state management

486

*/

487

function useDropdown(props: DropdownProps): {

488

Component: React.ElementType;

489

state: MenuTriggerState;

490

slots: Record<DropdownSlots, string>;

491

classNames: SlotsToClasses<DropdownSlots>;

492

getDropdownProps: () => any;

493

};

494

```

495

496

### Dropdown Structure Components

497

498

Components for organizing dropdown content with trigger and menu items.

499

500

```typescript { .api }

501

interface DropdownTriggerProps {

502

/** Trigger element */

503

children: React.ReactElement;

504

}

505

506

interface DropdownMenuProps {

507

/** Menu items */

508

children?: React.ReactNode;

509

/** Menu variant */

510

variant?: "solid" | "bordered" | "light" | "flat" | "faded" | "shadow";

511

/** Menu color theme */

512

color?: "default" | "primary" | "secondary" | "success" | "warning" | "danger";

513

/** Selection mode */

514

selectionMode?: "none" | "single" | "multiple";

515

/** Currently selected keys */

516

selectedKeys?: Selection;

517

/** Default selected keys */

518

defaultSelectedKeys?: Selection;

519

/** Prevent empty selection */

520

disallowEmptySelection?: boolean;

521

/** Close on select */

522

closeOnSelect?: boolean;

523

/** Custom CSS class */

524

className?: string;

525

/** Slot-based styling */

526

classNames?: SlotsToClasses<MenuSlots>;

527

/** Selection change handler */

528

onSelectionChange?: (keys: Selection) => void;

529

/** Action handler */

530

onAction?: (key: React.Key) => void;

531

/** Close handler */

532

onClose?: () => void;

533

}

534

535

// DropdownItem and DropdownSection are aliases for MenuItem and MenuSection

536

interface DropdownItemProps {

537

/** Item key identifier */

538

key?: React.Key;

539

/** Item content */

540

children?: React.ReactNode;

541

/** Item text value */

542

textValue?: string;

543

/** Item description */

544

description?: React.ReactNode;

545

/** Item shortcut */

546

shortcut?: React.ReactNode;

547

/** Start content (icon, etc.) */

548

startContent?: React.ReactNode;

549

/** End content (icon, badge, etc.) */

550

endContent?: React.ReactNode;

551

/** Whether item is disabled */

552

isDisabled?: boolean;

553

/** Whether to show divider after item */

554

showDivider?: boolean;

555

/** Custom CSS class */

556

className?: string;

557

/** Slot-based styling */

558

classNames?: SlotsToClasses<MenuItemSlots>;

559

}

560

561

interface DropdownSectionProps {

562

/** Section title */

563

title?: React.ReactNode;

564

/** Section items */

565

children?: React.ReactNode;

566

/** Whether to hide divider */

567

hideDivider?: boolean;

568

/** Whether to show divider */

569

showDivider?: boolean;

570

/** Custom CSS class */

571

className?: string;

572

/** Slot-based styling */

573

classNames?: SlotsToClasses<MenuSectionSlots>;

574

}

575

576

function DropdownTrigger(props: DropdownTriggerProps): JSX.Element;

577

function DropdownMenu(props: DropdownMenuProps): JSX.Element;

578

const DropdownItem: React.FC<DropdownItemProps>;

579

const DropdownSection: React.FC<DropdownSectionProps>;

580

```

581

582

**Dropdown Usage Examples:**

583

584

```typescript

585

import {

586

Dropdown, DropdownTrigger, DropdownMenu, DropdownItem, DropdownSection,

587

Button, Avatar, User

588

} from "@nextui-org/react";

589

import { PlusIcon, CopyIcon, EditIcon, DeleteIcon } from "@heroicons/react/24/solid";

590

591

function DropdownExamples() {

592

return (

593

<div className="flex gap-4">

594

{/* Basic dropdown */}

595

<Dropdown>

596

<DropdownTrigger>

597

<Button variant="bordered">Actions</Button>

598

</DropdownTrigger>

599

<DropdownMenu aria-label="Static Actions">

600

<DropdownItem key="new">New file</DropdownItem>

601

<DropdownItem key="copy">Copy link</DropdownItem>

602

<DropdownItem key="edit">Edit file</DropdownItem>

603

<DropdownItem key="delete" className="text-danger" color="danger">

604

Delete file

605

</DropdownItem>

606

</DropdownMenu>

607

</Dropdown>

608

609

{/* Dropdown with icons */}

610

<Dropdown>

611

<DropdownTrigger>

612

<Button isIconOnly variant="light">

613

<PlusIcon className="w-4 h-4" />

614

</Button>

615

</DropdownTrigger>

616

<DropdownMenu variant="faded" aria-label="Dropdown menu with icons">

617

<DropdownItem

618

key="new"

619

shortcut="⌘N"

620

startContent={<PlusIcon className="w-4 h-4" />}

621

>

622

New File

623

</DropdownItem>

624

<DropdownItem

625

key="copy"

626

shortcut="⌘C"

627

startContent={<CopyIcon className="w-4 h-4" />}

628

>

629

Copy Link

630

</DropdownItem>

631

<DropdownItem

632

key="edit"

633

shortcut="⌘⇧E"

634

startContent={<EditIcon className="w-4 h-4" />}

635

>

636

Edit File

637

</DropdownItem>

638

<DropdownItem

639

key="delete"

640

className="text-danger"

641

color="danger"

642

shortcut="⌘⇧D"

643

startContent={<DeleteIcon className="w-4 h-4" />}

644

>

645

Delete File

646

</DropdownItem>

647

</DropdownMenu>

648

</Dropdown>

649

650

{/* User dropdown with sections */}

651

<Dropdown placement="bottom-start">

652

<DropdownTrigger>

653

<User

654

as="button"

655

avatarProps={{

656

isBordered: true,

657

src: "https://i.pravatar.cc/150?u=a042581f4e29026024d",

658

}}

659

className="transition-transform"

660

description="@tonyreichert"

661

name="Tony Reichert"

662

/>

663

</DropdownTrigger>

664

<DropdownMenu aria-label="User Actions" variant="flat">

665

<DropdownItem key="profile" className="h-14 gap-2">

666

<p className="font-bold">Signed in as</p>

667

<p className="font-bold">@tonyreichert</p>

668

</DropdownItem>

669

<DropdownItem key="settings">My Settings</DropdownItem>

670

<DropdownItem key="team_settings">Team Settings</DropdownItem>

671

<DropdownItem key="analytics">Analytics</DropdownItem>

672

<DropdownItem key="system">System</DropdownItem>

673

<DropdownItem key="configurations">Configurations</DropdownItem>

674

<DropdownItem key="help_and_feedback">Help & Feedback</DropdownItem>

675

<DropdownItem key="logout" color="danger">

676

Log Out

677

</DropdownItem>

678

</DropdownMenu>

679

</Dropdown>

680

</div>

681

);

682

}

683

```

684

685

### Drawer

686

687

A slide-out panel component that extends modal functionality for creating side navigation and content panels.

688

689

```typescript { .api }

690

interface DrawerProps extends Omit<ModalProps, 'placement' | 'size'> {

691

/** Drawer placement */

692

placement?: "top" | "bottom" | "left" | "right";

693

/** Drawer size */

694

size?: "xs" | "sm" | "md" | "lg" | "xl" | "2xl" | "3xl" | "4xl" | "5xl" | "full";

695

/** Hide overlay backdrop */

696

hideOverlay?: boolean;

697

}

698

699

function Drawer(props: DrawerProps): JSX.Element;

700

701

/**

702

* Hook for Drawer state management

703

*/

704

function useDrawer(props: DrawerProps): {

705

Component: React.ElementType;

706

slots: Record<ModalSlots, string>;

707

classNames: SlotsToClasses<ModalSlots>;

708

isOpen: boolean;

709

onClose: () => void;

710

getDrawerProps: () => any;

711

};

712

713

// Drawer structure components are aliases for Modal components

714

const DrawerContent: React.FC<ModalContentProps>;

715

const DrawerHeader: React.FC<ModalHeaderProps>;

716

const DrawerBody: React.FC<ModalBodyProps>;

717

const DrawerFooter: React.FC<ModalFooterProps>;

718

```

719

720

**Drawer Usage Example:**

721

722

```typescript

723

import {

724

Drawer, DrawerContent, DrawerHeader, DrawerBody, DrawerFooter,

725

Button, Link, Listbox, ListboxItem

726

} from "@nextui-org/react";

727

import { useDisclosure } from "@nextui-org/react";

728

729

function DrawerExample() {

730

const { isOpen, onOpen, onOpenChange } = useDisclosure();

731

732

const menuItems = [

733

{ key: "dashboard", label: "Dashboard" },

734

{ key: "projects", label: "Projects" },

735

{ key: "team", label: "Team" },

736

{ key: "settings", label: "Settings" },

737

];

738

739

return (

740

<>

741

<Button onPress={onOpen}>Open Drawer</Button>

742

<Drawer

743

isOpen={isOpen}

744

onOpenChange={onOpenChange}

745

placement="left"

746

size="md"

747

>

748

<DrawerContent>

749

{(onClose) => (

750

<>

751

<DrawerHeader className="flex flex-col gap-1">

752

Navigation

753

</DrawerHeader>

754

<DrawerBody>

755

<Listbox

756

aria-label="Navigation menu"

757

onAction={(key) => {

758

console.log(`Navigate to ${key}`);

759

onClose();

760

}}

761

>

762

{menuItems.map((item) => (

763

<ListboxItem key={item.key}>

764

{item.label}

765

</ListboxItem>

766

))}

767

</Listbox>

768

</DrawerBody>

769

<DrawerFooter>

770

<Button color="danger" variant="light" onPress={onClose}>

771

Close

772

</Button>

773

<Link href="/settings" onClick={onClose}>

774

Settings

775

</Link>

776

</DrawerFooter>

777

</>

778

)}

779

</DrawerContent>

780

</Drawer>

781

</>

782

);

783

}

784

```

785

786

## Overlay Component Types

787

788

```typescript { .api }

789

// Common overlay types

790

type OverlaySize = "xs" | "sm" | "md" | "lg" | "xl" | "2xl" | "3xl" | "4xl" | "5xl" | "full";

791

type OverlayRadius = "none" | "sm" | "md" | "lg";

792

type OverlayColor = "default" | "foreground" | "primary" | "secondary" | "success" | "warning" | "danger";

793

type BackdropType = "transparent" | "opaque" | "blur";

794

795

// Placement for popovers and dropdowns

796

type PlacementAxis = "top" | "bottom" | "left" | "right";

797

type PlacementAlign = "start" | "end";

798

type Placement = PlacementAxis | `${PlacementAxis}-${PlacementAlign}`;

799

800

// Modal types

801

interface ModalState {

802

isOpen: boolean;

803

size: OverlaySize;

804

placement: "auto" | "top" | "center" | "bottom";

805

backdrop: BackdropType;

806

scrollBehavior: "inside" | "outside";

807

isDismissable: boolean;

808

}

809

810

// Popover types

811

interface PopoverState {

812

isOpen: boolean;

813

placement: Placement;

814

showArrow: boolean;

815

backdrop?: BackdropType;

816

shouldFlip: boolean;

817

isDismissable: boolean;

818

}

819

820

// Dropdown types

821

interface DropdownState extends PopoverState {

822

selectionMode: "none" | "single" | "multiple";

823

selectedKeys: Selection;

824

closeOnSelect: boolean;

825

}

826

827

// Overlay trigger states

828

interface OverlayTriggerState {

829

readonly isOpen: boolean;

830

setOpen(isOpen: boolean): void;

831

open(): void;

832

close(): void;

833

toggle(): void;

834

}

835

836

interface MenuTriggerState extends OverlayTriggerState {

837

focusStrategy?: FocusStrategy | null;

838

}

839

840

// Motion configuration for overlay animations

841

interface MotionProps {

842

initial?: any;

843

animate?: any;

844

exit?: any;

845

transition?: any;

846

variants?: any;

847

whileHover?: any;

848

whileTap?: any;

849

whileFocus?: any;

850

whileInView?: any;

851

}

852

853

// Focus management

854

type FocusStrategy = "first" | "last";

855

856

// Selection types for dropdowns

857

type Selection = "all" | Set<React.Key>;

858

```

859

860

## Integration Examples

861

862

### Disclosure Hook Usage

863

864

The `useDisclosure` hook provides a convenient way to manage open/closed state for overlay components.

865

866

```typescript { .api }

867

interface UseDisclosureProps {

868

/** Whether overlay is open */

869

isOpen?: boolean;

870

/** Default open state */

871

defaultOpen?: boolean;

872

/** Close handler */

873

onClose?: () => void;

874

/** Open change handler */

875

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

876

/** Disclosure ID */

877

id?: string;

878

}

879

880

interface UseDisclosureReturn {

881

/** Whether overlay is open */

882

isOpen: boolean;

883

/** Open the overlay */

884

onOpen: () => void;

885

/** Close the overlay */

886

onClose: () => void;

887

/** Toggle overlay state */

888

onOpenChange: (isOpen: boolean) => void;

889

/** Whether state is controlled */

890

isControlled: boolean;

891

/** Props for trigger button */

892

getButtonProps: (props?: any) => any;

893

/** Props for disclosure content */

894

getDisclosureProps: (props?: any) => any;

895

}

896

897

function useDisclosure(props?: UseDisclosureProps): UseDisclosureReturn;

898

```

899

900

### Draggable Modal

901

902

Advanced modal functionality with drag support.

903

904

```typescript { .api }

905

interface UseDraggableProps {

906

/** Whether dragging is disabled */

907

isDisabled?: boolean;

908

/** Target element ref */

909

targetRef?: React.RefObject<HTMLElement>;

910

/** Body element ref */

911

bodyRef?: React.RefObject<HTMLElement>;

912

/** Drag constraints */

913

dragConstraints?: any;

914

/** Drag elastic behavior */

915

dragElastic?: boolean;

916

}

917

918

interface UseDraggableReturn {

919

/** Motion props for draggable element */

920

dragProps: any;

921

/** Drag controls */

922

dragControls: any;

923

}

924

925

function useDraggable(props: UseDraggableProps): UseDraggableReturn;

926

```

927

928

### Complex Overlay Composition

929

930

```typescript

931

import {

932

Modal, ModalContent, ModalHeader, ModalBody, ModalFooter,

933

Popover, PopoverTrigger, PopoverContent,

934

Dropdown, DropdownTrigger, DropdownMenu, DropdownItem,

935

Button, Input, useDisclosure

936

} from "@nextui-org/react";

937

938

function ComplexOverlayExample() {

939

const modal = useDisclosure();

940

const [selectedAction, setSelectedAction] = useState<string>("");

941

942

return (

943

<div className="space-y-4">

944

{/* Main trigger */}

945

<Button onPress={modal.onOpen} color="primary">

946

Open Complex Dialog

947

</Button>

948

949

{/* Modal with nested overlays */}

950

<Modal

951

isOpen={modal.isOpen}

952

onOpenChange={modal.onOpenChange}

953

size="lg"

954

>

955

<ModalContent>

956

{(onClose) => (

957

<>

958

<ModalHeader>Project Settings</ModalHeader>

959

<ModalBody className="space-y-4">

960

<Input label="Project Name" placeholder="Enter project name" />

961

962

<div className="flex gap-2">

963

{/* Popover for additional info */}

964

<Popover>

965

<PopoverTrigger>

966

<Button variant="bordered" size="sm">

967

Help

968

</Button>

969

</PopoverTrigger>

970

<PopoverContent>

971

<div className="p-2 max-w-[200px]">

972

<p className="text-sm">

973

Choose a descriptive name for your project that will help you identify it later.

974

</p>

975

</div>

976

</PopoverContent>

977

</Popover>

978

979

{/* Dropdown for actions */}

980

<Dropdown>

981

<DropdownTrigger>

982

<Button variant="bordered" size="sm">

983

Actions

984

</Button>

985

</DropdownTrigger>

986

<DropdownMenu

987

onAction={(key) => setSelectedAction(key as string)}

988

>

989

<DropdownItem key="duplicate">Duplicate</DropdownItem>

990

<DropdownItem key="export">Export</DropdownItem>

991

<DropdownItem key="archive">Archive</DropdownItem>

992

<DropdownItem key="delete" color="danger">

993

Delete

994

</DropdownItem>

995

</DropdownMenu>

996

</Dropdown>

997

</div>

998

999

{selectedAction && (

1000

<div className="p-2 bg-default-100 rounded">

1001

Selected action: {selectedAction}

1002

</div>

1003

)}

1004

</ModalBody>

1005

<ModalFooter>

1006

<Button color="danger" variant="flat" onPress={onClose}>

1007

Cancel

1008

</Button>

1009

<Button color="primary" onPress={onClose}>

1010

Save Changes

1011

</Button>

1012

</ModalFooter>

1013

</>

1014

)}

1015

</ModalContent>

1016

</Modal>

1017

</div>

1018

);

1019

}

1020

```