Sheet
A dialog that slides in from an edge of the screen.
import { … } from '@inlaylab/ivorie/sheet'import { ChangeDetectionStrategy, Component } from '@angular/core';
import { IvButton } from '@inlaylab/ivorie/button';
import { IV_INPUT_IMPORTS } from '@inlaylab/ivorie/input';
import { IV_SHEET_IMPORTS } from '@inlaylab/ivorie/sheet';
@Component({
selector: 'demo-sheet',
imports: [IV_SHEET_IMPORTS, IV_INPUT_IMPORTS, IvButton],
changeDetection: ChangeDetectionStrategy.OnPush,
template: `
<button ivButton variant="outline" [ivSheetTrigger]="sheet">Open</button>
<ng-template #sheet>
<iv-sheet-header>
<iv-sheet-title>Edit profile</iv-sheet-title>
<iv-sheet-description>Make changes to your profile here. Click save when you're done.</iv-sheet-description>
</iv-sheet-header>
<div class="grid gap-4 px-6">
<div class="grid gap-2">
<label ivLabel for="sheet-name">Name</label>
<input ivInput id="sheet-name" value="Ada Lovelace" />
</div>
<div class="grid gap-2">
<label ivLabel for="sheet-user">Username</label>
<input ivInput id="sheet-user" value="@ada" />
</div>
</div>
<iv-sheet-footer>
<button ivButton ivSheetClose="saved">Save changes</button>
<button ivButton variant="outline" ivSheetClose>Cancel</button>
</iv-sheet-footer>
</ng-template>
`,
})
export default class SheetDemo {}
Installation
npx ivorie add sheetimport { … } from '@inlaylab/ivorie/sheet'A sheet is a Dialog docked to an edge. It uses the same service, close reasons and focus rules.
Usage
import { IV_SHEET_IMPORTS } from '@inlaylab/ivorie/sheet';<button ivButton [ivSheetTrigger]="sheet" [ivSheetConfig]="{ side: 'left' }">Open</button>
<ng-template #sheet>
<iv-sheet-header>
<iv-sheet-title>Title</iv-sheet-title>
</iv-sheet-header>
</ng-template>Or open it from code: inject(IvSheet).open(MyComponent, { side: 'bottom' }). It returns an IvDialogRef.
Examples
Side
import { ChangeDetectionStrategy, Component } from '@angular/core';
import { IvButton } from '@inlaylab/ivorie/button';
import { IV_SHEET_IMPORTS } from '@inlaylab/ivorie/sheet';
@Component({
selector: 'demo-sheet-side',
imports: [IV_SHEET_IMPORTS, IvButton],
changeDetection: ChangeDetectionStrategy.OnPush,
template: `
<div class="grid grid-cols-2 gap-2">
@for (side of sides; track side) {
<button ivButton variant="outline" class="capitalize" [ivSheetTrigger]="sheet" [ivSheetConfig]="{ side }">{{ side }}</button>
}
</div>
<ng-template #sheet>
<iv-sheet-header>
<iv-sheet-title>Notifications</iv-sheet-title>
<iv-sheet-description>You have no new notifications.</iv-sheet-description>
</iv-sheet-header>
</ng-template>
`,
})
export default class SheetSideDemo {
protected readonly sides = ['top', 'right', 'bottom', 'left'] as const;
}
API
Every part also accepts class.
SheetConfig
All Dialog config options except size and height, plus:
| Name | Type | Default | Description |
|---|---|---|---|
side |
'top' | 'right' | 'bottom' | 'left' |
'right' |
Edge the sheet docks to. |
[ivSheetTrigger]
| Name | Type | Default | Description |
|---|---|---|---|
ivSheetTrigger |
TemplateRef | Type |
required | Content to show. |
ivSheetConfig |
SheetConfig |
{} |
Options. |
Outputs: opened (IvDialogRef), closed (DialogCloseEvent).
Other parts
iv-sheet-header,iv-sheet-title,iv-sheet-description,iv-sheet-footer.
[ivSheetClose]
| Name | Type | Default | Description |
|---|---|---|---|
ivSheetClose |
unknown |
undefined |
Result passed to afterClosed. |
reason |
DialogCloseReason |
'close-button' |
Close reason. |
Accessibility
Same as Dialog: role="dialog" with aria-modal, labelled by the title, focus trapped inside, Escape closes, focus returns to the opener.