or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

components.mdcomposables.mddata-display.mddirectives.mdfeedback.mdforms.mdframework-core.mdicons.mdindex.mdinternationalization.mdlab-components.mdnavigation.mdtheming.mdtransitions.mdutilities.md

feedback.mddocs/

0

# Feedback

1

2

Components for providing user feedback, displaying status, and handling user interactions through alerts, notifications, progress indicators, and modal dialogs.

3

4

## Capabilities

5

6

### VAlert

7

8

Alert component for displaying important messages and notifications with various severity levels.

9

10

```typescript { .api }

11

/**

12

* Alert component for notifications and messages

13

*/

14

const VAlert: Component;

15

16

interface AlertProps {

17

/** Alert message text */

18

text?: string;

19

/** Alert title */

20

title?: string;

21

/** Alert type/color */

22

type?: 'success' | 'info' | 'warning' | 'error';

23

/** Alert color */

24

color?: string;

25

/** Alert variant */

26

variant?: 'flat' | 'elevated' | 'tonal' | 'outlined' | 'text' | 'plain';

27

/** Alert density */

28

density?: 'default' | 'comfortable' | 'compact';

29

/** Closable alert */

30

closable?: boolean;

31

/** Close icon */

32

closeIcon?: string;

33

/** Close label for accessibility */

34

closeLabel?: string;

35

/** Prepend icon */

36

prependIcon?: string;

37

/** Append icon */

38

appendIcon?: string;

39

/** Icon for the alert type */

40

icon?: string | boolean;

41

/** Border location */

42

border?: boolean | 'top' | 'end' | 'bottom' | 'start';

43

/** Prominent style */

44

prominent?: boolean;

45

/** Alert width */

46

width?: string | number;

47

/** Maximum width */

48

maxWidth?: string | number;

49

/** Minimum width */

50

minWidth?: string | number;

51

/** Alert height */

52

height?: string | number;

53

/** Maximum height */

54

maxHeight?: string | number;

55

/** Minimum height */

56

minHeight?: string | number;

57

/** Elevation level */

58

elevation?: number | string;

59

/** Rounded corners */

60

rounded?: boolean | string | number;

61

/** Tile style (no border radius) */

62

tile?: boolean;

63

}

64

65

// Events

66

interface AlertEvents {

67

'click:close': (event: MouseEvent) => void;

68

'click:prepend': (event: MouseEvent) => void;

69

'click:append': (event: MouseEvent) => void;

70

}

71

```

72

73

**Usage Examples:**

74

75

```vue

76

<template>

77

<!-- Basic alerts -->

78

<v-alert type="success" text="Operation completed successfully!" />

79

80

<v-alert type="warning" title="Warning" text="Please review your settings." />

81

82

<v-alert type="error" closable @click:close="handleClose">

83

<v-alert-title>Error occurred</v-alert-title>

84

Unable to save changes. Please try again.

85

</v-alert>

86

87

<!-- Custom styled alert -->

88

<v-alert

89

color="purple"

90

variant="tonal"

91

prominent

92

border="start"

93

icon="mdi-information"

94

>

95

<strong>Pro Tip:</strong> You can customize alerts with different variants and borders.

96

</v-alert>

97

98

<!-- Alert with actions -->

99

<v-alert type="info" closable>

100

<div class="d-flex align-center">

101

<div class="flex-grow-1">New update available</div>

102

<v-btn size="small" variant="outlined">Update</v-btn>

103

</div>

104

</v-alert>

105

</template>

106

107

<script setup>

108

const handleClose = () => {

109

console.log('Alert closed');

110

};

111

</script>

112

```

113

114

### VSnackbar

115

116

Toast notification component for displaying temporary messages with optional actions.

117

118

```typescript { .api }

119

/**

120

* Snackbar toast notification component

121

*/

122

const VSnackbar: Component;

123

124

interface SnackbarProps {

125

/** Snackbar visibility */

126

modelValue?: boolean;

127

/** Snackbar text content */

128

text?: string;

129

/** Display timeout in milliseconds */

130

timeout?: number | string;

131

/** Multi-line layout */

132

multiLine?: boolean;

133

/** Vertical positioning */

134

vertical?: boolean;

135

/** Snackbar location */

136

location?:

137

| 'top' | 'bottom' | 'left' | 'right' | 'center'

138

| 'top left' | 'top right' | 'bottom left' | 'bottom right'

139

| 'top center' | 'bottom center' | 'center left' | 'center right';

140

/** Snackbar color */

141

color?: string;

142

/** Snackbar variant */

143

variant?: 'flat' | 'elevated' | 'tonal' | 'outlined' | 'text' | 'plain';

144

/** Rounded corners */

145

rounded?: boolean | string | number;

146

/** Tile style */

147

tile?: boolean;

148

/** Elevation level */

149

elevation?: number | string;

150

/** Minimum width */

151

minWidth?: string | number;

152

/** Maximum width */

153

maxWidth?: string | number;

154

/** Width */

155

width?: string | number;

156

/** Height */

157

height?: string | number;

158

/** Z-index */

159

zIndex?: number | string;

160

/** Close on content click */

161

closeOnContentClick?: boolean;

162

/** Close on back navigation */

163

closeOnBack?: boolean;

164

}

165

166

// Events

167

interface SnackbarEvents {

168

'update:modelValue': (visible: boolean) => void;

169

}

170

```

171

172

**Usage Examples:**

173

174

```vue

175

<template>

176

<!-- Basic snackbar -->

177

<v-snackbar

178

v-model="snackbar"

179

:timeout="3000"

180

>

181

{{ snackbarText }}

182

<template #actions>

183

<v-btn color="pink" variant="text" @click="snackbar = false">

184

Close

185

</v-btn>

186

</template>

187

</v-snackbar>

188

189

<!-- Multi-line snackbar -->

190

<v-snackbar

191

v-model="multiLineSnackbar"

192

multi-line

193

location="top"

194

>

195

This is a multi-line snackbar message that can contain longer text content.

196

<template #actions>

197

<v-btn color="primary" variant="text" @click="handleAction">

198

Action

199

</v-btn>

200

<v-btn variant="text" @click="multiLineSnackbar = false">

201

Dismiss

202

</v-btn>

203

</template>

204

</v-snackbar>

205

206

<!-- Vertical snackbar -->

207

<v-snackbar

208

v-model="verticalSnackbar"

209

vertical

210

location="top right"

211

>

212

<div class="text-subtitle-1 pb-2">Notification</div>

213

<p>Your changes have been saved successfully.</p>

214

215

<template #actions>

216

<v-btn color="success" variant="text" @click="verticalSnackbar = false">

217

OK

218

</v-btn>

219

</template>

220

</v-snackbar>

221

</template>

222

223

<script setup>

224

const snackbar = ref(false);

225

const snackbarText = ref('Operation completed');

226

const multiLineSnackbar = ref(false);

227

const verticalSnackbar = ref(false);

228

229

const showSnackbar = (message) => {

230

snackbarText.value = message;

231

snackbar.value = true;

232

};

233

</script>

234

```

235

236

### VProgressLinear

237

238

Linear progress indicator for showing task completion or loading states.

239

240

```typescript { .api }

241

/**

242

* Linear progress indicator component

243

*/

244

const VProgressLinear: Component;

245

246

interface ProgressLinearProps {

247

/** Progress value (0-100) */

248

modelValue?: number | string;

249

/** Buffer value for buffered progress */

250

buffer?: number | string;

251

/** Indeterminate progress animation */

252

indeterminate?: boolean;

253

/** Reverse progress direction */

254

reverse?: boolean;

255

/** Stream animation */

256

stream?: boolean;

257

/** Progress bar color */

258

color?: string;

259

/** Background color */

260

bgColor?: string;

261

/** Buffer color */

262

bufferColor?: string;

263

/** Progress bar height */

264

height?: number | string;

265

/** Rounded ends */

266

rounded?: boolean;

267

/** Striped pattern */

268

striped?: boolean;

269

/** Location on page */

270

location?: 'top' | 'bottom';

271

/** Absolute positioning */

272

absolute?: boolean;

273

/** Active state */

274

active?: boolean;

275

}

276

277

// Events

278

interface ProgressLinearEvents {

279

'update:modelValue': (value: number) => void;

280

}

281

```

282

283

**Usage Examples:**

284

285

```vue

286

<template>

287

<!-- Basic progress bar -->

288

<v-progress-linear

289

v-model="progress"

290

color="primary"

291

height="8"

292

/>

293

294

<!-- Indeterminate progress -->

295

<v-progress-linear

296

indeterminate

297

color="cyan"

298

/>

299

300

<!-- Buffered progress -->

301

<v-progress-linear

302

v-model="downloadProgress"

303

:buffer="bufferProgress"

304

color="success"

305

height="6"

306

/>

307

308

<!-- Striped progress -->

309

<v-progress-linear

310

v-model="uploadProgress"

311

striped

312

color="warning"

313

height="10"

314

/>

315

316

<!-- Top page loading indicator -->

317

<v-progress-linear

318

:model-value="pageLoadProgress"

319

location="top"

320

color="primary"

321

:active="loading"

322

/>

323

</template>

324

325

<script setup>

326

const progress = ref(75);

327

const downloadProgress = ref(65);

328

const bufferProgress = ref(85);

329

const uploadProgress = ref(40);

330

const pageLoadProgress = ref(0);

331

const loading = ref(false);

332

333

// Simulate loading

334

const simulateProgress = () => {

335

loading.value = true;

336

pageLoadProgress.value = 0;

337

338

const interval = setInterval(() => {

339

pageLoadProgress.value += 10;

340

if (pageLoadProgress.value >= 100) {

341

clearInterval(interval);

342

loading.value = false;

343

}

344

}, 100);

345

};

346

</script>

347

```

348

349

### VProgressCircular

350

351

Circular progress indicator for loading states and progress visualization.

352

353

```typescript { .api }

354

/**

355

* Circular progress indicator component

356

*/

357

const VProgressCircular: Component;

358

359

interface ProgressCircularProps {

360

/** Progress value (0-100) */

361

modelValue?: number | string;

362

/** Indeterminate progress animation */

363

indeterminate?: boolean;

364

/** Progress circle color */

365

color?: string;

366

/** Background color */

367

bgColor?: string;

368

/** Circle size */

369

size?: number | string;

370

/** Stroke width */

371

width?: number | string;

372

/** Rotate angle */

373

rotate?: number | string;

374

}

375

376

// Events

377

interface ProgressCircularEvents {

378

'update:modelValue': (value: number) => void;

379

}

380

```

381

382

**Usage Examples:**

383

384

```vue

385

<template>

386

<!-- Basic circular progress -->

387

<v-progress-circular

388

v-model="circularProgress"

389

color="primary"

390

/>

391

392

<!-- Indeterminate spinner -->

393

<v-progress-circular

394

indeterminate

395

color="purple"

396

:size="64"

397

:width="6"

398

/>

399

400

<!-- Large progress with custom styling -->

401

<v-progress-circular

402

v-model="taskProgress"

403

:size="120"

404

:width="8"

405

color="success"

406

>

407

{{ Math.ceil(taskProgress) }}%

408

</v-progress-circular>

409

410

<!-- Small loading spinner -->

411

<v-progress-circular

412

indeterminate

413

:size="20"

414

:width="2"

415

color="grey"

416

/>

417

</template>

418

419

<script setup>

420

const circularProgress = ref(45);

421

const taskProgress = ref(78.5);

422

</script>

423

```

424

425

### VSkeletonLoader

426

427

Skeleton loader for displaying placeholder content while data is loading.

428

429

```typescript { .api }

430

/**

431

* Skeleton loader for content placeholders

432

*/

433

const VSkeletonLoader: Component;

434

435

interface SkeletonLoaderProps {

436

/** Loading state */

437

loading?: boolean;

438

/** Skeleton type/template */

439

type?: string | string[];

440

/** Boilerplate mode */

441

boilerplate?: boolean;

442

/** Skeleton color */

443

color?: string;

444

/** Skeleton width */

445

width?: string | number;

446

/** Skeleton height */

447

height?: string | number;

448

/** Maximum width */

449

maxWidth?: string | number;

450

/** Maximum height */

451

maxHeight?: string | number;

452

/** Minimum width */

453

minWidth?: string | number;

454

/** Minimum height */

455

minHeight?: string | number;

456

/** Elevation level */

457

elevation?: number | string;

458

/** Rounded corners */

459

rounded?: boolean | string | number;

460

}

461

462

// Built-in skeleton types

463

type SkeletonType =

464

| 'text' | 'sentences' | 'paragraph'

465

| 'heading' | 'subtitle' | 'chip'

466

| 'button' | 'avatar' | 'thumbnail'

467

| 'image' | 'card' | 'card-avatar'

468

| 'article' | 'table' | 'table-heading'

469

| 'table-tbody' | 'table-tfoot' | 'table-row-divider'

470

| 'list-item' | 'list-item-avatar' | 'list-item-two-line'

471

| 'list-item-avatar-two-line' | 'list-item-three-line'

472

| 'list-item-avatar-three-line' | 'divider'

473

| 'card-heading' | 'card-text' | 'card-actions';

474

```

475

476

**Usage Examples:**

477

478

```vue

479

<template>

480

<!-- Basic skeleton loader -->

481

<v-skeleton-loader

482

:loading="loading"

483

type="card"

484

>

485

<v-card>

486

<v-card-title>{{ data.title }}</v-card-title>

487

<v-card-text>{{ data.content }}</v-card-text>

488

</v-card>

489

</v-skeleton-loader>

490

491

<!-- Multiple skeleton types -->

492

<v-skeleton-loader

493

:loading="loading"

494

type="card-avatar, article, actions"

495

>

496

<div>

497

<!-- Actual content when loaded -->

498

<div class="d-flex align-center mb-4">

499

<v-avatar>{{ user.initials }}</v-avatar>

500

<div class="ml-3">

501

<div class="text-h6">{{ user.name }}</div>

502

<div class="text-caption">{{ user.role }}</div>

503

</div>

504

</div>

505

<p>{{ article.content }}</p>

506

<v-btn>Read More</v-btn>

507

</div>

508

</v-skeleton-loader>

509

510

<!-- Custom skeleton -->

511

<v-skeleton-loader

512

:loading="loading"

513

boilerplate

514

type="heading, paragraph"

515

width="300"

516

>

517

<div>

518

<h2>{{ post.title }}</h2>

519

<p>{{ post.excerpt }}</p>

520

</div>

521

</v-skeleton-loader>

522

523

<!-- List skeleton -->

524

<v-skeleton-loader

525

:loading="loadingUsers"

526

type="list-item-avatar-two-line"

527

v-for="n in 5"

528

:key="n"

529

>

530

<v-list-item

531

v-for="user in users"

532

:key="user.id"

533

:prepend-avatar="user.avatar"

534

:title="user.name"

535

:subtitle="user.email"

536

/>

537

</v-skeleton-loader>

538

</template>

539

540

<script setup>

541

const loading = ref(true);

542

const loadingUsers = ref(true);

543

const data = ref({});

544

const users = ref([]);

545

546

onMounted(async () => {

547

// Simulate data loading

548

await new Promise(resolve => setTimeout(resolve, 2000));

549

loading.value = false;

550

loadingUsers.value = false;

551

552

data.value = {

553

title: 'Loaded Content',

554

content: 'This content was loaded after the skeleton.'

555

};

556

});

557

</script>

558

```

559

560

### VTooltip

561

562

Tooltip component for displaying contextual information on hover or focus.

563

564

```typescript { .api }

565

/**

566

* Tooltip overlay component

567

*/

568

const VTooltip: Component;

569

570

interface TooltipProps {

571

/** Tooltip visibility */

572

modelValue?: boolean;

573

/** Tooltip text content */

574

text?: string;

575

/** Tooltip location relative to activator */

576

location?:

577

| 'top' | 'bottom' | 'left' | 'right' | 'center'

578

| 'top start' | 'top end' | 'bottom start' | 'bottom end'

579

| 'left start' | 'left end' | 'right start' | 'right end';

580

/** Tooltip offset from activator */

581

offset?: number | string | number[];

582

/** Disabled state */

583

disabled?: boolean;

584

/** Show delay in milliseconds */

585

openDelay?: number | string;

586

/** Hide delay in milliseconds */

587

closeDelay?: number | string;

588

/** Tooltip content width */

589

width?: string | number;

590

/** Maximum width */

591

maxWidth?: string | number;

592

/** Minimum width */

593

minWidth?: string | number;

594

/** Tooltip height */

595

height?: string | number;

596

/** Maximum height */

597

maxHeight?: string | number;

598

/** Minimum height */

599

minHeight?: string | number;

600

/** Z-index */

601

zIndex?: number | string;

602

/** Activator element */

603

activator?: string | Element;

604

/** Tooltip content color */

605

contentColor?: string;

606

}

607

608

// Events

609

interface TooltipEvents {

610

'update:modelValue': (visible: boolean) => void;

611

}

612

```

613

614

**Usage Examples:**

615

616

```vue

617

<template>

618

<!-- Basic tooltip -->

619

<v-tooltip text="This is a helpful tooltip">

620

<template #activator="{ props }">

621

<v-btn v-bind="props">Hover me</v-btn>

622

</template>

623

</v-tooltip>

624

625

<!-- Custom positioned tooltip -->

626

<v-tooltip

627

location="bottom"

628

:open-delay="500"

629

:close-delay="200"

630

>

631

<template #activator="{ props }">

632

<v-icon v-bind="props">mdi-help-circle</v-icon>

633

</template>

634

<span>This tooltip appears below with a delay</span>

635

</v-tooltip>

636

637

<!-- Rich content tooltip -->

638

<v-tooltip max-width="300">

639

<template #activator="{ props }">

640

<v-chip v-bind="props" color="primary">

641

Rich Tooltip

642

</v-chip>

643

</template>

644

<div>

645

<strong>Advanced Tooltip</strong>

646

<br>

647

<em>This tooltip contains multiple lines and rich formatting.</em>

648

<v-divider class="my-2" />

649

<small>Click for more details</small>

650

</div>

651

</v-tooltip>

652

653

<!-- Programmatic tooltip -->

654

<v-tooltip

655

v-model="tooltipVisible"

656

location="top"

657

activator="#target-element"

658

>

659

Programmatically controlled tooltip

660

</v-tooltip>

661

</template>

662

663

<script setup>

664

const tooltipVisible = ref(false);

665

666

const showTooltip = () => {

667

tooltipVisible.value = true;

668

setTimeout(() => {

669

tooltipVisible.value = false;

670

}, 3000);

671

};

672

</script>

673

```

674

675

### VDialog

676

677

Modal dialog component for displaying content in an overlay window.

678

679

```typescript { .api }

680

/**

681

* Modal dialog overlay component

682

*/

683

const VDialog: Component;

684

685

interface DialogProps {

686

/** Dialog visibility */

687

modelValue?: boolean;

688

/** Dialog width */

689

width?: string | number;

690

/** Maximum width */

691

maxWidth?: string | number;

692

/** Minimum width */

693

minWidth?: string | number;

694

/** Dialog height */

695

height?: string | number;

696

/** Maximum height */

697

maxHeight?: string | number;

698

/** Minimum height */

699

minHeight?: string | number;

700

/** Fullscreen mode */

701

fullscreen?: boolean;

702

/** Persistent dialog (no outside click close) */

703

persistent?: boolean;

704

/** No click animation */

705

noClickAnimation?: boolean;

706

/** Scrollable content */

707

scrollable?: boolean;

708

/** Scrim (backdrop) color */

709

scrim?: boolean | string;

710

/** Z-index */

711

zIndex?: number | string;

712

/** Activator element */

713

activator?: string | Element;

714

/** Attach to element */

715

attach?: boolean | string | Element;

716

/** Close on back navigation */

717

closeOnBack?: boolean;

718

/** Close on escape key */

719

closeOnEscape?: boolean;

720

/** Eager mounting */

721

eager?: boolean;

722

/** Location strategy */

723

locationStrategy?: 'static' | 'connected';

724

/** Scroll strategy */

725

scrollStrategy?: 'block' | 'close' | 'reposition' | 'none';

726

/** Transition name */

727

transition?: string | boolean | object;

728

/** Opacity */

729

opacity?: number | string;

730

}

731

732

// Events

733

interface DialogEvents {

734

'update:modelValue': (visible: boolean) => void;

735

'click:outside': (event: Event) => void;

736

'keydown': (event: KeyboardEvent) => void;

737

'after-enter': () => void;

738

'after-leave': () => void;

739

}

740

```

741

742

**Usage Examples:**

743

744

```vue

745

<template>

746

<!-- Basic dialog -->

747

<v-dialog v-model="dialog" max-width="500">

748

<template #activator="{ props }">

749

<v-btn v-bind="props">Open Dialog</v-btn>

750

</template>

751

752

<v-card>

753

<v-card-title>Dialog Title</v-card-title>

754

<v-card-text>

755

This is the dialog content. You can put any content here.

756

</v-card-text>

757

<v-card-actions>

758

<v-spacer />

759

<v-btn @click="dialog = false">Cancel</v-btn>

760

<v-btn color="primary" @click="handleConfirm">Confirm</v-btn>

761

</v-card-actions>

762

</v-card>

763

</v-dialog>

764

765

<!-- Fullscreen dialog -->

766

<v-dialog v-model="fullscreenDialog" fullscreen>

767

<template #activator="{ props }">

768

<v-btn v-bind="props">Fullscreen</v-btn>

769

</template>

770

771

<v-card>

772

<v-toolbar color="primary">

773

<v-toolbar-title>Fullscreen Dialog</v-toolbar-title>

774

<v-spacer />

775

<v-btn icon @click="fullscreenDialog = false">

776

<v-icon>mdi-close</v-icon>

777

</v-btn>

778

</v-toolbar>

779

780

<v-card-text>

781

<div style="height: 1000px;">

782

Large scrollable content goes here...

783

</div>

784

</v-card-text>

785

</v-card>

786

</v-dialog>

787

788

<!-- Persistent dialog -->

789

<v-dialog v-model="persistentDialog" persistent max-width="400">

790

<v-card>

791

<v-card-title>Confirm Action</v-card-title>

792

<v-card-text>

793

This action cannot be undone. Are you sure you want to proceed?

794

</v-card-text>

795

<v-card-actions>

796

<v-btn @click="persistentDialog = false">Cancel</v-btn>

797

<v-btn color="error" @click="handleDelete">Delete</v-btn>

798

</v-card-actions>

799

</v-card>

800

</v-dialog>

801

802

<!-- Scrollable dialog -->

803

<v-dialog v-model="scrollableDialog" scrollable max-width="500" max-height="400">

804

<v-card>

805

<v-card-title>Terms of Service</v-card-title>

806

<v-divider />

807

<v-card-text>

808

<div v-for="n in 50" :key="n">

809

Line {{ n }}: Lorem ipsum dolor sit amet consectetur...

810

</div>

811

</v-card-text>

812

<v-divider />

813

<v-card-actions>

814

<v-btn @click="scrollableDialog = false">Disagree</v-btn>

815

<v-btn color="primary" @click="acceptTerms">Agree</v-btn>

816

</v-card-actions>

817

</v-card>

818

</v-dialog>

819

</template>

820

821

<script setup>

822

const dialog = ref(false);

823

const fullscreenDialog = ref(false);

824

const persistentDialog = ref(false);

825

const scrollableDialog = ref(false);

826

827

const handleConfirm = () => {

828

console.log('Confirmed');

829

dialog.value = false;

830

};

831

832

const handleDelete = () => {

833

console.log('Deleted');

834

persistentDialog.value = false;

835

};

836

837

const acceptTerms = () => {

838

console.log('Terms accepted');

839

scrollableDialog.value = false;

840

};

841

</script>

842

```

843

844

### VBottomSheet

845

846

Bottom sheet modal component that slides up from the bottom of the screen.

847

848

```typescript { .api }

849

/**

850

* Bottom sheet modal component

851

*/

852

const VBottomSheet: Component;

853

854

interface BottomSheetProps {

855

/** Bottom sheet visibility */

856

modelValue?: boolean;

857

/** Inset mode (doesn't cover full width) */

858

inset?: boolean;

859

/** Maximum width */

860

maxWidth?: string | number;

861

/** Maximum height */

862

maxHeight?: string | number;

863

/** Sheet width */

864

width?: string | number;

865

/** Sheet height */

866

height?: string | number;

867

/** Persistent sheet (no outside click close) */

868

persistent?: boolean;

869

/** No click animation */

870

noClickAnimation?: boolean;

871

/** Scrollable content */

872

scrollable?: boolean;

873

/** Scrim (backdrop) */

874

scrim?: boolean | string;

875

/** Z-index */

876

zIndex?: number | string;

877

/** Attach to element */

878

attach?: boolean | string | Element;

879

/** Close on back navigation */

880

closeOnBack?: boolean;

881

/** Close on escape key */

882

closeOnEscape?: boolean;

883

/** Eager mounting */

884

eager?: boolean;

885

/** Transition name */

886

transition?: string | boolean | object;

887

}

888

889

// Events

890

interface BottomSheetEvents {

891

'update:modelValue': (visible: boolean) => void;

892

'click:outside': (event: Event) => void;

893

'keydown': (event: KeyboardEvent) => void;

894

}

895

```

896

897

**Usage Examples:**

898

899

```vue

900

<template>

901

<!-- Basic bottom sheet -->

902

<v-bottom-sheet v-model="bottomSheet">

903

<template #activator="{ props }">

904

<v-btn v-bind="props">Open Bottom Sheet</v-btn>

905

</template>

906

907

<v-card>

908

<v-card-title>Bottom Sheet</v-card-title>

909

<v-card-text>

910

This content slides up from the bottom of the screen.

911

</v-card-text>

912

<v-card-actions>

913

<v-spacer />

914

<v-btn @click="bottomSheet = false">Close</v-btn>

915

</v-card-actions>

916

</v-card>

917

</v-bottom-sheet>

918

919

<!-- Inset bottom sheet -->

920

<v-bottom-sheet v-model="insetBottomSheet" inset>

921

<v-card class="text-center">

922

<v-card-text>

923

<v-avatar size="80" color="primary">

924

<v-icon size="40">mdi-account</v-icon>

925

</v-avatar>

926

<div class="text-h6 mt-4">User Profile</div>

927

<p class="text-body-2">Quick actions for user account</p>

928

</v-card-text>

929

<v-card-actions class="justify-center">

930

<v-btn prepend-icon="mdi-pencil">Edit</v-btn>

931

<v-btn prepend-icon="mdi-cog">Settings</v-btn>

932

</v-card-actions>

933

</v-card>

934

</v-bottom-sheet>

935

936

<!-- Scrollable bottom sheet -->

937

<v-bottom-sheet v-model="scrollableBottomSheet" scrollable>

938

<v-card>

939

<v-card-title>Menu Options</v-card-title>

940

<v-divider />

941

<v-card-text style="height: 300px;">

942

<v-list>

943

<v-list-item

944

v-for="item in menuItems"

945

:key="item.id"

946

:prepend-icon="item.icon"

947

:title="item.title"

948

@click="selectMenuItem(item)"

949

/>

950

</v-list>

951

</v-card-text>

952

</v-card>

953

</v-bottom-sheet>

954

</template>

955

956

<script setup>

957

const bottomSheet = ref(false);

958

const insetBottomSheet = ref(false);

959

const scrollableBottomSheet = ref(false);

960

961

const menuItems = [

962

{ id: 1, title: 'Profile', icon: 'mdi-account' },

963

{ id: 2, title: 'Settings', icon: 'mdi-cog' },

964

{ id: 3, title: 'Help', icon: 'mdi-help-circle' },

965

{ id: 4, title: 'About', icon: 'mdi-information' },

966

// ... more items

967

];

968

969

const selectMenuItem = (item) => {

970

console.log('Selected:', item.title);

971

scrollableBottomSheet.value = false;

972

};

973

</script>

974

```

975

976

## Types

977

978

```typescript { .api }

979

// Location types for positioning

980

type Location =

981

| 'top' | 'bottom' | 'left' | 'right' | 'center'

982

| 'top start' | 'top end' | 'bottom start' | 'bottom end'

983

| 'left start' | 'left end' | 'right start' | 'right end'

984

| 'top left' | 'top right' | 'bottom left' | 'bottom right'

985

| 'top center' | 'bottom center' | 'center left' | 'center right';

986

987

// Alert and notification types

988

type AlertType = 'success' | 'info' | 'warning' | 'error';

989

990

// Component variants

991

type ComponentVariant = 'flat' | 'elevated' | 'tonal' | 'outlined' | 'text' | 'plain';

992

993

// Density options

994

type Density = 'default' | 'comfortable' | 'compact';

995

996

// Border positions

997

type BorderPosition = 'top' | 'end' | 'bottom' | 'start';

998

999

// Progress value type

1000

type ProgressValue = number | string;

1001

1002

// Overlay strategies

1003

type LocationStrategy = 'static' | 'connected';

1004

type ScrollStrategy = 'block' | 'close' | 'reposition' | 'none';

1005

```