@egose/shadcn-theme-ng-tw 0.1.0 → 0.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +1 -1
- package/accordion/README.md +405 -2
- package/alert/README.md +372 -2
- package/alert-dialog/README.md +471 -5
- package/aspect-ratio/README.md +272 -5
- package/autocomplete/README.md +502 -2
- package/avatar/README.md +357 -5
- package/badge/README.md +318 -2
- package/basic-alert/README.md +353 -2
- package/breadcrumb/README.md +406 -5
- package/button/README.md +482 -2
- package/button/fesm2022/button.mjs +85 -107
- package/button/types/button.d.ts +5 -8
- package/button-group/README.md +318 -5
- package/button-group/fesm2022/button-group.mjs +1 -1
- package/calendar/README.md +357 -2
- package/card/README.md +331 -5
- package/carousel/README.md +333 -5
- package/carousel/fesm2022/carousel.mjs +4 -1
- package/checkbox/README.md +320 -2
- package/collapsible/README.md +332 -5
- package/combobox/README.md +507 -5
- package/combobox/fesm2022/combobox.mjs +4 -1
- package/command/README.md +435 -5
- package/confirmation-dialog/README.md +301 -2
- package/context-menu/README.md +366 -5
- package/date-picker/README.md +465 -2
- package/date-picker/fesm2022/date-picker.mjs +2 -2
- package/dialog/README.md +448 -2
- package/drawer/README.md +395 -5
- package/dropdown-menu/README.md +417 -5
- package/empty/README.md +329 -5
- package/field/README.md +385 -5
- package/form-checkbox/README.md +312 -2
- package/form-date-picker/README.md +322 -2
- package/form-field/README.md +356 -2
- package/form-field-simple/README.md +340 -2
- package/form-searchable-multiselect/README.md +361 -2
- package/form-select/README.md +350 -2
- package/form-text-input/README.md +371 -2
- package/form-textarea/README.md +347 -2
- package/hover-card/README.md +256 -5
- package/icon/README.md +239 -2
- package/input/README.md +269 -2
- package/input-group/README.md +335 -5
- package/input-group/fesm2022/input-group.mjs +3 -3
- package/input-otp/README.md +375 -5
- package/item/README.md +385 -5
- package/item/fesm2022/item.mjs +3 -3
- package/kbd/README.md +291 -5
- package/label/README.md +272 -2
- package/layout-simple/README.md +193 -2
- package/layout-simple/fesm2022/layout-simple.mjs +877 -409
- package/layout-simple/types/layout-simple.d.ts +174 -137
- package/menu/README.md +417 -2
- package/menubar/README.md +343 -5
- package/native-select/README.md +323 -5
- package/navigation-menu/README.md +369 -5
- package/package.json +1 -1
- package/pagination/README.md +388 -5
- package/popover/README.md +331 -2
- package/progress/README.md +311 -5
- package/radio-group/README.md +364 -2
- package/radio-group/fesm2022/radio-group.mjs +5 -1
- package/resizable/README.md +269 -5
- package/scroll-area/README.md +233 -5
- package/searchable-multiselect/README.md +323 -2
- package/select/README.md +437 -2
- package/separator/README.md +222 -2
- package/sheet/README.md +311 -2
- package/sidebar/README.md +457 -5
- package/skeleton/README.md +217 -5
- package/slider/README.md +273 -5
- package/slider/fesm2022/slider.mjs +17 -13
- package/sonner/README.md +346 -2
- package/spinner/README.md +284 -2
- package/switch/README.md +310 -2
- package/table/README.md +423 -5
- package/tabs/README.md +411 -2
- package/tabs/fesm2022/tabs.mjs +12 -2
- package/textarea/README.md +282 -5
- package/toggle/README.md +270 -5
- package/toggle-group/README.md +340 -5
- package/tooltip/README.md +269 -2
- package/typography/README.md +271 -5
- package/utils/README.md +303 -2
package/dialog/README.md
CHANGED
|
@@ -1,3 +1,449 @@
|
|
|
1
|
-
# Dialog
|
|
1
|
+
# Dialog (`@egose/shadcn-theme-ng/dialog`)
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
A modal dialog in the shadcn/ui Dialog style: an overlay + centered content panel with title, description, header/footer layout slots, and declarative or programmatic opening. Equivalent to shadcn/ui `Dialog`.
|
|
4
|
+
|
|
5
|
+
The Angular implementation is a thin styling layer over the headless
|
|
6
|
+
[`BrnDialog*` primitives from `@spartan-ng/brain/dialog`](https://www.spartan-ng.com/):
|
|
7
|
+
`HlmDialog` extends `BrnDialog`, trigger/close/title/description/overlay directives compose their
|
|
8
|
+
`Brn*` counterparts via `hostDirectives`, and `HlmDialogService` wraps `BrnDialogService` with
|
|
9
|
+
shadcn overlay classes. Styling is applied with `hlm()` / `classes()` from
|
|
10
|
+
`@egose/shadcn-theme-ng/utils`.
|
|
11
|
+
|
|
12
|
+
> **Ships as:** `@egose/shadcn-theme-ng/dialog` and `@egose/shadcn-theme-ng-tw/dialog`
|
|
13
|
+
> (the `tw:`-prefixed Tailwind variant). Both expose the identical TypeScript surface; only the
|
|
14
|
+
> emitted Tailwind class strings differ. See the [package README](../../README.md) for install
|
|
15
|
+
> steps, peer dependencies, and Tailwind setup. Do not publish this project directory independently.
|
|
16
|
+
|
|
17
|
+
## Installation
|
|
18
|
+
|
|
19
|
+
```bash
|
|
20
|
+
# Plain Tailwind (no prefix)
|
|
21
|
+
npm install @egose/shadcn-theme-ng
|
|
22
|
+
|
|
23
|
+
# tw:-prefixed Tailwind variant
|
|
24
|
+
npm install @egose/shadcn-theme-ng-tw
|
|
25
|
+
```
|
|
26
|
+
|
|
27
|
+
Peer dependencies (Angular, `@spartan-ng/brain`, `@ng-icons/*`, `rxjs`, …) are documented in the
|
|
28
|
+
[package README](../../README.md#peer-dependencies). This subpath additionally relies at runtime on
|
|
29
|
+
`@egose/shadcn-theme-ng/button` (close button), `@egose/shadcn-theme-ng/utils`, and
|
|
30
|
+
`@ng-icons/lucide` (`lucideX`).
|
|
31
|
+
|
|
32
|
+
## Imports
|
|
33
|
+
|
|
34
|
+
All symbols are exported from the subpath root (`projects/dialog/src/public-api.ts`):
|
|
35
|
+
|
|
36
|
+
```ts
|
|
37
|
+
import {
|
|
38
|
+
HlmDialog,
|
|
39
|
+
HlmDialogContent,
|
|
40
|
+
HlmDialogTrigger,
|
|
41
|
+
HlmDialogClose,
|
|
42
|
+
HlmDialogOverlay,
|
|
43
|
+
HlmDialogPortal,
|
|
44
|
+
HlmDialogTitle,
|
|
45
|
+
HlmDialogDescription,
|
|
46
|
+
HlmDialogHeader,
|
|
47
|
+
HlmDialogFooter,
|
|
48
|
+
HlmDialogService,
|
|
49
|
+
HlmDialogImports,
|
|
50
|
+
HlmDialogModule,
|
|
51
|
+
hlmDialogOverlayClass,
|
|
52
|
+
} from '@egose/shadcn-theme-ng/dialog';
|
|
53
|
+
// tw variant: replace with '@egose/shadcn-theme-ng-tw/dialog'
|
|
54
|
+
```
|
|
55
|
+
|
|
56
|
+
Standalone component — spread the `*Imports` array:
|
|
57
|
+
|
|
58
|
+
```ts
|
|
59
|
+
import { Component } from '@angular/core';
|
|
60
|
+
import { HlmDialogImports } from '@egose/shadcn-theme-ng/dialog';
|
|
61
|
+
|
|
62
|
+
@Component({
|
|
63
|
+
selector: 'app-demo',
|
|
64
|
+
standalone: true,
|
|
65
|
+
imports: [...HlmDialogImports],
|
|
66
|
+
template: `...`,
|
|
67
|
+
})
|
|
68
|
+
export class DemoComponent {}
|
|
69
|
+
```
|
|
70
|
+
|
|
71
|
+
NgModule-based consumer — import the module:
|
|
72
|
+
|
|
73
|
+
```ts
|
|
74
|
+
import { NgModule } from '@angular/core';
|
|
75
|
+
import { HlmDialogModule } from '@egose/shadcn-theme-ng/dialog';
|
|
76
|
+
|
|
77
|
+
@NgModule({ imports: [HlmDialogModule] })
|
|
78
|
+
export class DemoModule {}
|
|
79
|
+
```
|
|
80
|
+
|
|
81
|
+
`HlmDialogService` is `providedIn: 'root'` — just inject it, no module setup needed.
|
|
82
|
+
|
|
83
|
+
## Anatomy / Structure
|
|
84
|
+
|
|
85
|
+
```html
|
|
86
|
+
<hlm-dialog>
|
|
87
|
+
<button hlmBtn hlmDialogTrigger>Edit profile</button>
|
|
88
|
+
|
|
89
|
+
<hlm-dialog-content>
|
|
90
|
+
<div hlmDialogHeader>
|
|
91
|
+
<h2 hlmDialogTitle>Edit profile</h2>
|
|
92
|
+
<p hlmDialogDescription>Make changes here. Click save when done.</p>
|
|
93
|
+
</div>
|
|
94
|
+
|
|
95
|
+
<p>Dialog body…</p>
|
|
96
|
+
|
|
97
|
+
<div hlmDialogFooter>
|
|
98
|
+
<button hlmBtn variant="outline" hlmDialogClose>Cancel</button>
|
|
99
|
+
<button hlmBtn type="submit">Save</button>
|
|
100
|
+
</div>
|
|
101
|
+
</hlm-dialog-content>
|
|
102
|
+
</hlm-dialog>
|
|
103
|
+
```
|
|
104
|
+
|
|
105
|
+
Real selectors (from source):
|
|
106
|
+
|
|
107
|
+
| Class | Selector(s) | Kind |
|
|
108
|
+
| ---------------------- | ------------------------------------------------------- | ------------------------------- |
|
|
109
|
+
| `HlmDialog` | `hlm-dialog` | Component (extends `BrnDialog`) |
|
|
110
|
+
| `HlmDialogContent` | `hlm-dialog-content` | Component |
|
|
111
|
+
| `HlmDialogTrigger` | `button[hlmDialogTrigger], button[hlmDialogTriggerFor]` | Directive (thin wrapper) |
|
|
112
|
+
| `HlmDialogClose` | `button[hlmDialogClose]` | Directive (thin wrapper) |
|
|
113
|
+
| `HlmDialogOverlay` | `[hlmDialogOverlay], hlm-dialog-overlay` | Directive |
|
|
114
|
+
| `HlmDialogPortal` | `[hlmDialogPortal]` | Directive |
|
|
115
|
+
| `HlmDialogTitle` | `[hlmDialogTitle]` | Directive |
|
|
116
|
+
| `HlmDialogDescription` | `[hlmDialogDescription]` | Directive |
|
|
117
|
+
| `HlmDialogHeader` | `[hlmDialogHeader], hlm-dialog-header` | Directive |
|
|
118
|
+
| `HlmDialogFooter` | `[hlmDialogFooter], hlm-dialog-footer` | Directive |
|
|
119
|
+
|
|
120
|
+
## API reference
|
|
121
|
+
|
|
122
|
+
### `HlmDialog` — `hlm-dialog`
|
|
123
|
+
|
|
124
|
+
Root dialog state host. Extends `BrnDialog` (inherits its open/close state, ids, and context). Renders `<hlm-dialog-overlay />` plus projected content. `exportAs: 'hlmDialog'`.
|
|
125
|
+
|
|
126
|
+
No new inputs/outputs — configure via `BrnDialog` API and `provideBrnDialogDefaultOptions`.
|
|
127
|
+
|
|
128
|
+
### `HlmDialogContent` — `hlm-dialog-content`
|
|
129
|
+
|
|
130
|
+
The centered panel. Renders either a dynamically-opened component (`HlmDialogService`) or projected content, plus an optional built-in close button.
|
|
131
|
+
|
|
132
|
+
| Input | Type | Default | Description |
|
|
133
|
+
| ----------------- | --------- | ------------------------------------ | ------------------------------------------------ |
|
|
134
|
+
| `showCloseButton` | `boolean` | context `$showCloseButton` ?? `true` | Show the top-right ghost `lucideX` close button. |
|
|
135
|
+
|
|
136
|
+
| Member | Description |
|
|
137
|
+
| ----------- | ------------------------------------------------------------------------------------ |
|
|
138
|
+
| `state` | `computed` — current dialog state (`'open' \| 'closed'`, from `BrnDialogRef`). |
|
|
139
|
+
| `component` | Dynamically rendered component when opened via `HlmDialogService`, else `undefined`. |
|
|
140
|
+
|
|
141
|
+
Host sets `data-slot="dialog-content"` and `data-state`.
|
|
142
|
+
|
|
143
|
+
### `HlmDialogTrigger` — `button[hlmDialogTrigger], button[hlmDialogTriggerFor]`
|
|
144
|
+
|
|
145
|
+
Thin directive wrapper. Forwards via `hostDirectives`: `id`, `brnDialogTriggerFor: hlmDialogTriggerFor`, `type` to `BrnDialogTrigger`. Use `hlmDialogTriggerFor` to target an explicit dialog template/context.
|
|
146
|
+
|
|
147
|
+
### `HlmDialogClose` — `button[hlmDialogClose]`
|
|
148
|
+
|
|
149
|
+
Thin directive wrapper around `BrnDialogClose`. Place on any `<button>` inside the dialog to close it.
|
|
150
|
+
|
|
151
|
+
### `HlmDialogOverlay` — `[hlmDialogOverlay], hlm-dialog-overlay`
|
|
152
|
+
|
|
153
|
+
Overlay backdrop. Wraps `BrnDialogOverlay`; merges `class` via `hlm()`.
|
|
154
|
+
|
|
155
|
+
| Input | Type | Default | Description |
|
|
156
|
+
| ------- | ------------ | ------- | -------------------------------------------------- |
|
|
157
|
+
| `class` | `ClassValue` | `''` | Extra classes merged over `hlmDialogOverlayClass`. |
|
|
158
|
+
|
|
159
|
+
Exported const `hlmDialogOverlayClass` holds the base overlay classes (also reused by `HlmDialogService` for programmatic dialogs).
|
|
160
|
+
|
|
161
|
+
### `HlmDialogPortal` — `[hlmDialogPortal]`
|
|
162
|
+
|
|
163
|
+
Thin wrapper forwarding `context` and `class` inputs to `BrnDialogContent` for portal-based content.
|
|
164
|
+
|
|
165
|
+
### `HlmDialogTitle` — `[hlmDialogTitle]`
|
|
166
|
+
|
|
167
|
+
Title text. Wraps `BrnDialogTitle` (accessible labelling) + shadcn typography. No inputs.
|
|
168
|
+
|
|
169
|
+
### `HlmDialogDescription` — `[hlmDialogDescription]`
|
|
170
|
+
|
|
171
|
+
Description text. Wraps `BrnDialogDescription` (accessible description) + muted styling. No inputs.
|
|
172
|
+
|
|
173
|
+
### `HlmDialogHeader` / `HlmDialogFooter`
|
|
174
|
+
|
|
175
|
+
Pure layout directives, no inputs. Header: vertical stack; footer: reversed column on mobile, right-aligned row on `sm+`.
|
|
176
|
+
|
|
177
|
+
### `HlmDialogService`
|
|
178
|
+
|
|
179
|
+
```ts
|
|
180
|
+
export type HlmDialogOptions<DialogContext = unknown> = BrnDialogOptions & {
|
|
181
|
+
contentClass?: string;
|
|
182
|
+
showCloseButton?: boolean;
|
|
183
|
+
context?: DialogContext;
|
|
184
|
+
};
|
|
185
|
+
|
|
186
|
+
open<TResult = unknown, TContext = unknown>(
|
|
187
|
+
component: ComponentType<unknown> | TemplateRef<unknown>,
|
|
188
|
+
options?: Partial<HlmDialogOptions<TContext>>,
|
|
189
|
+
): BrnDialogRef<TResult>
|
|
190
|
+
```
|
|
191
|
+
|
|
192
|
+
Merges `backdropClass` with `hlmDialogOverlayClass`, forwards `contentClass` as `$dynamicComponentClass` and `showCloseButton` / custom `context` into `HlmDialogContent`, then delegates to `BrnDialogService.open`.
|
|
193
|
+
|
|
194
|
+
## Examples
|
|
195
|
+
|
|
196
|
+
### 1. Basic declarative dialog
|
|
197
|
+
|
|
198
|
+
```ts
|
|
199
|
+
import { Component } from '@angular/core';
|
|
200
|
+
import { HlmDialogImports } from '@egose/shadcn-theme-ng/dialog';
|
|
201
|
+
import { HlmButton } from '@egose/shadcn-theme-ng/button';
|
|
202
|
+
|
|
203
|
+
@Component({
|
|
204
|
+
selector: 'app-basic-dialog',
|
|
205
|
+
standalone: true,
|
|
206
|
+
imports: [...HlmDialogImports, HlmButton],
|
|
207
|
+
template: `
|
|
208
|
+
<hlm-dialog>
|
|
209
|
+
<button hlmBtn variant="outline" hlmDialogTrigger>Open dialog</button>
|
|
210
|
+
<hlm-dialog-content>
|
|
211
|
+
<div hlmDialogHeader>
|
|
212
|
+
<h2 hlmDialogTitle>Are you sure?</h2>
|
|
213
|
+
<p hlmDialogDescription>This action cannot be undone.</p>
|
|
214
|
+
</div>
|
|
215
|
+
<div hlmDialogFooter>
|
|
216
|
+
<button hlmBtn variant="outline" hlmDialogClose>Cancel</button>
|
|
217
|
+
<button hlmBtn (click)="confirm()">Continue</button>
|
|
218
|
+
</div>
|
|
219
|
+
</hlm-dialog-content>
|
|
220
|
+
</hlm-dialog>
|
|
221
|
+
`,
|
|
222
|
+
})
|
|
223
|
+
export class BasicDialogComponent {
|
|
224
|
+
confirm() {
|
|
225
|
+
console.log('confirmed');
|
|
226
|
+
}
|
|
227
|
+
}
|
|
228
|
+
```
|
|
229
|
+
|
|
230
|
+
### 2. Form dialog with header/footer layout
|
|
231
|
+
|
|
232
|
+
```ts
|
|
233
|
+
import { Component, inject } from '@angular/core';
|
|
234
|
+
import { FormBuilder, ReactiveFormsModule, Validators } from '@angular/forms';
|
|
235
|
+
import { HlmDialogImports } from '@egose/shadcn-theme-ng/dialog';
|
|
236
|
+
import { HlmButton } from '@egose/shadcn-theme-ng/button';
|
|
237
|
+
import { HlmLabel } from '@egose/shadcn-theme-ng/label';
|
|
238
|
+
import { HlmInput } from '@egose/shadcn-theme-ng/input';
|
|
239
|
+
|
|
240
|
+
@Component({
|
|
241
|
+
selector: 'app-form-dialog',
|
|
242
|
+
standalone: true,
|
|
243
|
+
imports: [ReactiveFormsModule, HlmLabel, HlmInput, HlmButton, ...HlmDialogImports],
|
|
244
|
+
template: `
|
|
245
|
+
<hlm-dialog>
|
|
246
|
+
<button hlmBtn hlmDialogTrigger>Edit profile</button>
|
|
247
|
+
<hlm-dialog-content>
|
|
248
|
+
<div hlmDialogHeader>
|
|
249
|
+
<h2 hlmDialogTitle>Edit profile</h2>
|
|
250
|
+
<p hlmDialogDescription>Make changes to your profile here.</p>
|
|
251
|
+
</div>
|
|
252
|
+
<form [formGroup]="form" class="tw:grid tw:gap-4">
|
|
253
|
+
<label hlmLabel for="name">Name</label>
|
|
254
|
+
<input hlmInput id="name" formControlName="name" />
|
|
255
|
+
</form>
|
|
256
|
+
<div hlmDialogFooter>
|
|
257
|
+
<button hlmBtn variant="outline" hlmDialogClose>Cancel</button>
|
|
258
|
+
<button hlmBtn hlmDialogClose [disabled]="form.invalid" (click)="save()">Save</button>
|
|
259
|
+
</div>
|
|
260
|
+
</hlm-dialog-content>
|
|
261
|
+
</hlm-dialog>
|
|
262
|
+
`,
|
|
263
|
+
})
|
|
264
|
+
export class FormDialogComponent {
|
|
265
|
+
private readonly fb = inject(FormBuilder);
|
|
266
|
+
readonly form = this.fb.group({ name: ['', Validators.required] });
|
|
267
|
+
save() {
|
|
268
|
+
console.log(this.form.value);
|
|
269
|
+
}
|
|
270
|
+
}
|
|
271
|
+
```
|
|
272
|
+
|
|
273
|
+
### 3. Programmatic dialog via `HlmDialogService`
|
|
274
|
+
|
|
275
|
+
```ts
|
|
276
|
+
import { Component, inject } from '@angular/core';
|
|
277
|
+
import { HlmDialogService } from '@egose/shadcn-theme-ng/dialog';
|
|
278
|
+
import { HlmButton } from '@egose/shadcn-theme-ng/button';
|
|
279
|
+
import { ConfirmDialogComponent } from './confirm-dialog.component';
|
|
280
|
+
|
|
281
|
+
@Component({
|
|
282
|
+
selector: 'app-service-dialog',
|
|
283
|
+
standalone: true,
|
|
284
|
+
imports: [HlmButton],
|
|
285
|
+
template: `<button hlmBtn variant="destructive" (click)="open()">Delete item</button>`,
|
|
286
|
+
})
|
|
287
|
+
export class ServiceDialogComponent {
|
|
288
|
+
private readonly dialogs = inject(HlmDialogService);
|
|
289
|
+
|
|
290
|
+
open() {
|
|
291
|
+
const ref = this.dialogs.open(ConfirmDialogComponent, {
|
|
292
|
+
contentClass: 'tw:max-w-sm',
|
|
293
|
+
showCloseButton: true,
|
|
294
|
+
context: { itemName: 'Report.pdf' },
|
|
295
|
+
});
|
|
296
|
+
ref.closed$.subscribe((result) => console.log('dialog closed with', result));
|
|
297
|
+
}
|
|
298
|
+
}
|
|
299
|
+
```
|
|
300
|
+
|
|
301
|
+
```ts
|
|
302
|
+
// confirm-dialog.component.ts — rendered inside hlm-dialog-content
|
|
303
|
+
import { Component, inject } from '@angular/core';
|
|
304
|
+
import { BrnDialogRef, injectBrnDialogContext } from '@spartan-ng/brain/dialog';
|
|
305
|
+
import { HlmButton } from '@egose/shadcn-theme-ng/button';
|
|
306
|
+
import { HlmDialogClose } from '@egose/shadcn-theme-ng/dialog';
|
|
307
|
+
|
|
308
|
+
@Component({
|
|
309
|
+
selector: 'app-confirm-dialog',
|
|
310
|
+
standalone: true,
|
|
311
|
+
imports: [HlmButton, HlmDialogClose],
|
|
312
|
+
template: `
|
|
313
|
+
<h2 class="tw:font-medium">Delete {{ ctx?.itemName }}?</h2>
|
|
314
|
+
<p class="tw:text-muted-foreground tw:text-sm">This cannot be undone.</p>
|
|
315
|
+
<div class="tw:flex tw:justify-end tw:gap-2">
|
|
316
|
+
<button hlmBtn variant="outline" hlmDialogClose>Cancel</button>
|
|
317
|
+
<button hlmBtn variant="destructive" (click)="confirm()">Delete</button>
|
|
318
|
+
</div>
|
|
319
|
+
`,
|
|
320
|
+
})
|
|
321
|
+
export class ConfirmDialogComponent {
|
|
322
|
+
private readonly ref = inject(BrnDialogRef);
|
|
323
|
+
readonly ctx = injectBrnDialogContext<{ itemName?: string }>().itemName
|
|
324
|
+
? injectBrnDialogContext<{ itemName?: string }>()
|
|
325
|
+
: null;
|
|
326
|
+
confirm() {
|
|
327
|
+
this.ref.close('confirmed');
|
|
328
|
+
}
|
|
329
|
+
}
|
|
330
|
+
```
|
|
331
|
+
|
|
332
|
+
### 4. Template-driven programmatic dialog
|
|
333
|
+
|
|
334
|
+
```ts
|
|
335
|
+
import { Component, inject, TemplateRef, viewChild } from '@angular/core';
|
|
336
|
+
import { HlmDialogService } from '@egose/shadcn-theme-ng/dialog';
|
|
337
|
+
import { HlmButton } from '@egose/shadcn-theme-ng/button';
|
|
338
|
+
|
|
339
|
+
@Component({
|
|
340
|
+
selector: 'app-template-dialog',
|
|
341
|
+
standalone: true,
|
|
342
|
+
imports: [HlmButton],
|
|
343
|
+
template: `
|
|
344
|
+
<button hlmBtn variant="outline" (click)="open()">Show details</button>
|
|
345
|
+
<ng-template #details>
|
|
346
|
+
<h2 class="tw:font-medium">Order #1234</h2>
|
|
347
|
+
<p class="tw:text-muted-foreground tw:text-sm">Ships tomorrow.</p>
|
|
348
|
+
</ng-template>
|
|
349
|
+
`,
|
|
350
|
+
})
|
|
351
|
+
export class TemplateDialogComponent {
|
|
352
|
+
private readonly dialogs = inject(HlmDialogService);
|
|
353
|
+
readonly tpl = viewChild.required('details', { read: TemplateRef });
|
|
354
|
+
open() {
|
|
355
|
+
this.dialogs.open(this.tpl(), { showCloseButton: false });
|
|
356
|
+
}
|
|
357
|
+
}
|
|
358
|
+
```
|
|
359
|
+
|
|
360
|
+
### 5. No close button + custom overlay styling
|
|
361
|
+
|
|
362
|
+
```ts
|
|
363
|
+
import { Component } from '@angular/core';
|
|
364
|
+
import { HlmDialogImports } from '@egose/shadcn-theme-ng/dialog';
|
|
365
|
+
import { HlmButton } from '@egose/shadcn-theme-ng/button';
|
|
366
|
+
|
|
367
|
+
@Component({
|
|
368
|
+
selector: 'app-custom-dialog',
|
|
369
|
+
standalone: true,
|
|
370
|
+
imports: [...HlmDialogImports, HlmButton],
|
|
371
|
+
template: `
|
|
372
|
+
<hlm-dialog>
|
|
373
|
+
<button hlmBtn hlmDialogTrigger>Onboarding</button>
|
|
374
|
+
<hlm-dialog-content [showCloseButton]="false" class="tw:max-w-lg">
|
|
375
|
+
<div hlmDialogHeader>
|
|
376
|
+
<h2 hlmDialogTitle>Welcome!</h2>
|
|
377
|
+
<p hlmDialogDescription>You must accept to continue.</p>
|
|
378
|
+
</div>
|
|
379
|
+
<div hlmDialogFooter>
|
|
380
|
+
<button hlmBtn hlmDialogClose>Accept</button>
|
|
381
|
+
</div>
|
|
382
|
+
</hlm-dialog-content>
|
|
383
|
+
</hlm-dialog>
|
|
384
|
+
`,
|
|
385
|
+
})
|
|
386
|
+
export class CustomDialogComponent {}
|
|
387
|
+
```
|
|
388
|
+
|
|
389
|
+
### 6. Async delete with loading state
|
|
390
|
+
|
|
391
|
+
```ts
|
|
392
|
+
import { Component, inject, signal } from '@angular/core';
|
|
393
|
+
import { HlmDialogImports, HlmDialogService } from '@egose/shadcn-theme-ng/dialog';
|
|
394
|
+
import { HlmButton } from '@egose/shadcn-theme-ng/button';
|
|
395
|
+
import { HlmSpinner } from '@egose/shadcn-theme-ng/spinner';
|
|
396
|
+
|
|
397
|
+
@Component({
|
|
398
|
+
selector: 'app-async-dialog',
|
|
399
|
+
standalone: true,
|
|
400
|
+
imports: [...HlmDialogImports, HlmButton, HlmSpinner],
|
|
401
|
+
template: `
|
|
402
|
+
<hlm-dialog>
|
|
403
|
+
<button hlmBtn variant="destructive" hlmDialogTrigger>Delete project</button>
|
|
404
|
+
<hlm-dialog-content>
|
|
405
|
+
<div hlmDialogHeader>
|
|
406
|
+
<h2 hlmDialogTitle>Delete project?</h2>
|
|
407
|
+
<p hlmDialogDescription>Type DELETE is not needed — just confirm.</p>
|
|
408
|
+
</div>
|
|
409
|
+
<div hlmDialogFooter>
|
|
410
|
+
<button hlmBtn variant="outline" hlmDialogClose [disabled]="busy()">Cancel</button>
|
|
411
|
+
<button hlmBtn variant="destructive" [disabled]="busy()" (click)="remove()">
|
|
412
|
+
@if (busy()) {
|
|
413
|
+
<hlm-spinner class="tw:size-4" />
|
|
414
|
+
}
|
|
415
|
+
Delete
|
|
416
|
+
</button>
|
|
417
|
+
</div>
|
|
418
|
+
</hlm-dialog-content>
|
|
419
|
+
</hlm-dialog>
|
|
420
|
+
`,
|
|
421
|
+
})
|
|
422
|
+
export class AsyncDialogComponent {
|
|
423
|
+
readonly busy = signal(false);
|
|
424
|
+
async remove() {
|
|
425
|
+
this.busy.set(true);
|
|
426
|
+
await new Promise((r) => setTimeout(r, 1000));
|
|
427
|
+
this.busy.set(false);
|
|
428
|
+
console.log('deleted');
|
|
429
|
+
}
|
|
430
|
+
}
|
|
431
|
+
```
|
|
432
|
+
|
|
433
|
+
## Accessibility notes
|
|
434
|
+
|
|
435
|
+
- `hlmDialogTitle` maps to `BrnDialogTitle` and `hlmDialogDescription` to `BrnDialogDescription`, wiring `aria-labelledby` / `aria-describedby` on the dialog — always include both.
|
|
436
|
+
- Focus is trapped inside the open dialog and restored to the trigger on close (brain behavior); escape closes by default.
|
|
437
|
+
- The built-in close button includes a visually-hidden `"close"` label plus the `lucideX` icon; keep `showCloseButton` unless you provide an equivalent labelled close control.
|
|
438
|
+
- The overlay is a separate `BrnDialogOverlay` element; screen-reader users hear the dialog role and label, not the backdrop.
|
|
439
|
+
|
|
440
|
+
## Theming / CSS variables
|
|
441
|
+
|
|
442
|
+
No component-specific CSS variables. The panel, overlay (`hlmDialogOverlayClass`), and `data-state` animations derive from global shadcn tokens (`--popover`, `--muted`, `--ring`, …). Extend via the `class` input on `hlm-dialog-content` / overlay or `contentClass` in `HlmDialogService.open`.
|
|
443
|
+
|
|
444
|
+
## Related subpaths
|
|
445
|
+
|
|
446
|
+
- `@egose/shadcn-theme-ng/alert-dialog` — blocking confirmation variant with explicit action/cancel slots.
|
|
447
|
+
- `@egose/shadcn-theme-ng/sheet` — side-anchored dialog alternative.
|
|
448
|
+
- `@egose/shadcn-theme-ng/drawer` — bottom/side swipeable panel built on the same brain dialog core.
|
|
449
|
+
- `@egose/shadcn-theme-ng/button` — `hlmBtn` triggers and footer actions.
|