@theredhead/lucid-blocks 0.1.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.
@@ -0,0 +1,2393 @@
1
+ import * as _angular_core from '@angular/core';
2
+ import { TemplateRef, OnInit, InjectionToken, AfterViewInit } from '@angular/core';
3
+ import * as i1 from '@theredhead/lucid-foundation';
4
+ import { IDatasource, Predicate } from '@theredhead/lucid-foundation';
5
+ import { ITreeDatasource, FilterFieldDefinition, SplitCollapseTarget, SplitPanelConstraints, FilterDescriptor, UITableViewColumn, TreeNodeContext, SelectionModel, TreeNode, FilterExpression, DrawerPosition, BreadcrumbVariant, UISidebarItem, BreadcrumbItem, PageChangeEvent, SelectOption } from '@theredhead/lucid-kit';
6
+ import { CdkDragDrop } from '@angular/cdk/drag-drop';
7
+
8
+ /**
9
+ * Context provided to the detail template.
10
+ *
11
+ * @typeParam T - The row object type.
12
+ */
13
+ interface MasterDetailContext<T> {
14
+ /** The selected item (also available as `let-object`). */
15
+ $implicit: T;
16
+ }
17
+ /**
18
+ * A master-detail layout that shows a list of items in a
19
+ * {@link UITableView} and renders a detail template for the
20
+ * currently selected item.
21
+ *
22
+ * ### Basic usage (table mode)
23
+ * ```html
24
+ * <ui-master-detail-view [datasource]="adapter" title="People">
25
+ * <ui-text-column key="name" headerText="Name" />
26
+ * <ui-text-column key="email" headerText="Email" />
27
+ *
28
+ * <ng-template #detail let-object>
29
+ * <h3>{{ object.name }}</h3>
30
+ * <p>{{ object.email }}</p>
31
+ * </ng-template>
32
+ * </ui-master-detail-view>
33
+ * ```
34
+ *
35
+ * ### Tree mode
36
+ * ```html
37
+ * <ui-master-detail-view [datasource]="treeDs" [treeDisplayWith]="labelFn">
38
+ * <ng-template #detail let-object>
39
+ * <h3>{{ object.name }}</h3>
40
+ * </ng-template>
41
+ * </ui-master-detail-view>
42
+ * ```
43
+ *
44
+ * ### With filter
45
+ * ```html
46
+ * <!-- Auto-inferred fields from columns + data types -->
47
+ * <ui-master-detail-view [datasource]="adapter" [showFilter]="true">
48
+ * <ui-text-column key="name" headerText="Name" />
49
+ * <ui-text-column key="email" headerText="Email" />
50
+ * <ng-template #detail let-object>…</ng-template>
51
+ * </ui-master-detail-view>
52
+ * ```
53
+ *
54
+ * ### With custom filter template (override)
55
+ * ```html
56
+ * <ui-master-detail-view [datasource]="adapter" [showFilter]="true">
57
+ * <ng-template #filter>
58
+ * <ui-filter [fields]="fields" [(value)]="descriptor"
59
+ * (expressionChange)="ds.filterBy($event)" />
60
+ * </ng-template>
61
+ * <!-- columns and detail template -->
62
+ * </ui-master-detail-view>
63
+ * ```
64
+ */
65
+ declare class UIMasterDetailView<T = unknown> {
66
+ /** Title displayed above the list panel. */
67
+ readonly title: _angular_core.InputSignal<string>;
68
+ /**
69
+ * The datasource powering the master list.
70
+ *
71
+ * Accepts any {@link IDatasource} (for flat table mode)
72
+ * or an {@link ITreeDatasource} (for hierarchical tree mode).
73
+ * The component detects the type at runtime and renders the
74
+ * appropriate view.
75
+ */
76
+ readonly datasource: _angular_core.InputSignal<IDatasource<T> | ITreeDatasource<T> | undefined>;
77
+ /**
78
+ * Function that returns a display string for tree node data.
79
+ * Only used in tree mode when no `#nodeTemplate` is projected.
80
+ * Defaults to `String(data)`.
81
+ */
82
+ readonly treeDisplayWith: _angular_core.InputSignal<(data: T) => string>;
83
+ /** Placeholder text shown when no item is selected. */
84
+ readonly placeholder: _angular_core.InputSignal<string>;
85
+ /**
86
+ * Whether the filter section is visible.
87
+ *
88
+ * - `true` — always show the filter.
89
+ * - `false` — never show the filter.
90
+ * - `undefined` (default) — auto-detect: show the filter when the
91
+ * resolved datasource is a {@link FilterableArrayDatasource}.
92
+ *
93
+ * When shown without a projected `#filter` template, the component
94
+ * embeds a `<ui-filter>` internally using auto-inferred field
95
+ * definitions.
96
+ */
97
+ readonly showFilter: _angular_core.InputSignal<boolean | undefined>;
98
+ /** Whether the filter section starts expanded. */
99
+ readonly filterExpanded: _angular_core.InputSignal<boolean>;
100
+ /**
101
+ * Whether the filter toggle button is hidden.
102
+ *
103
+ * When `true`, the toggle is removed and the filter section stays
104
+ * permanently in whatever state `filterExpanded` dictates:
105
+ * - `filterExpanded: true` + `filterModeLocked: true` → filter is
106
+ * always visible, cannot be collapsed.
107
+ * - `filterExpanded: false` + `filterModeLocked: true` → filter bar
108
+ * is completely hidden (equivalent to `showFilter: false`).
109
+ *
110
+ * This value is also forwarded to the embedded `<ui-filter>` as
111
+ * `[modeLocked]`, preventing the user from toggling between
112
+ * simple and advanced filter modes.
113
+ */
114
+ readonly filterModeLocked: _angular_core.InputSignal<boolean>;
115
+ /**
116
+ * Explicit filter field definitions.
117
+ *
118
+ * When provided these override the auto-inferred fields.
119
+ * Only relevant when no `#filter` template is projected.
120
+ */
121
+ readonly filterFields: _angular_core.InputSignal<FilterFieldDefinition<T>[] | undefined>;
122
+ /**
123
+ * Initial split sizes as a `[list, detail]` percentage tuple.
124
+ * Must sum to 100. Defaults to `[33, 67]`.
125
+ */
126
+ readonly splitSizes: _angular_core.InputSignal<readonly [number, number]>;
127
+ /**
128
+ * Optional localStorage key for persisting the split panel sizes.
129
+ * When set the user's last divider position is restored on init.
130
+ */
131
+ readonly splitName: _angular_core.InputSignal<string | undefined>;
132
+ /**
133
+ * Which panel to collapse when the divider is double-clicked.
134
+ * Defaults to `'first'` so the list panel can be collapsed.
135
+ */
136
+ readonly splitCollapseTarget: _angular_core.InputSignal<SplitCollapseTarget>;
137
+ /**
138
+ * Size constraints for the list (first) panel in pixels.
139
+ * Defaults to `{ min: 200 }`.
140
+ */
141
+ readonly listConstraints: _angular_core.InputSignal<SplitPanelConstraints>;
142
+ /** Whether the embedded table view is disabled. */
143
+ readonly disabled: _angular_core.InputSignal<boolean>;
144
+ /**
145
+ * Page size for the embedded table view's paginator.
146
+ * Leave `undefined` to use the table's default.
147
+ */
148
+ readonly pageSize: _angular_core.InputSignal<number | undefined>;
149
+ /**
150
+ * External page index (zero-based) for the embedded table view.
151
+ * Leave `undefined` to let the built-in paginator manage it.
152
+ */
153
+ readonly pageIndex: _angular_core.InputSignal<number | undefined>;
154
+ /**
155
+ * Whether to show the table's built-in paginator.
156
+ * Defaults to `false`.
157
+ */
158
+ readonly showBuiltInPaginator: _angular_core.InputSignal<boolean>;
159
+ /** Accessible caption for the embedded table. */
160
+ readonly caption: _angular_core.InputSignal<string>;
161
+ /** Whether to show row-index numbers in the table. */
162
+ readonly showRowIndexIndicator: _angular_core.InputSignal<boolean>;
163
+ /** Header text for the row-index column. Defaults to `"#"`. */
164
+ readonly rowIndexHeaderText: _angular_core.InputSignal<string>;
165
+ /**
166
+ * Unique table identifier used for persisting column widths.
167
+ * When set, column widths are stored in localStorage.
168
+ */
169
+ readonly tableId: _angular_core.InputSignal<string>;
170
+ /**
171
+ * Whether table columns can be resized by dragging header borders.
172
+ * Defaults to `true`.
173
+ */
174
+ readonly resizable: _angular_core.InputSignal<boolean>;
175
+ /**
176
+ * Row height in pixels for the internal table-view.
177
+ * Forwarded to `<ui-table-view [rowHeight]>`.
178
+ * Defaults to 36 px.
179
+ */
180
+ readonly rowHeight: _angular_core.InputSignal<number>;
181
+ /** Emits whenever the selection changes. Carries the selected item or `undefined`. */
182
+ readonly selectedChange: _angular_core.OutputEmitterRef<T | undefined>;
183
+ /**
184
+ * Emits the {@link FilterExpression} every time the filter rules
185
+ * change. Emits an empty array when no valid rules remain.
186
+ *
187
+ * For {@link FilterableArrayDatasource} instances the expression is
188
+ * applied automatically — this output is for consumers who use a
189
+ * custom datasource and need to handle filtering manually.
190
+ */
191
+ readonly expressionChange: _angular_core.OutputEmitterRef<FilterDescriptor<T>>;
192
+ /**
193
+ * The filter descriptor state (two-way bindable).
194
+ *
195
+ * Provides full read/write access to the filter's rule set and
196
+ * junction mode. Defaults to an empty AND descriptor.
197
+ */
198
+ readonly filterDescriptor: _angular_core.ModelSignal<FilterDescriptor<T>>;
199
+ /**
200
+ * Projected table-view columns.
201
+ * These are forwarded to the internal `<ui-table-view>`.
202
+ */
203
+ readonly columns: _angular_core.Signal<readonly UITableViewColumn[]>;
204
+ /** Detail template — rendered when an item is selected. */
205
+ readonly detailTemplate: _angular_core.Signal<TemplateRef<MasterDetailContext<T>> | undefined>;
206
+ /** Optional filter template — shown in the collapsible filter area. */
207
+ readonly filterTemplate: _angular_core.Signal<TemplateRef<unknown> | undefined>;
208
+ /**
209
+ * Optional tree-node template — forwarded to `<ui-tree-view>`.
210
+ * Receives {@link TreeNodeContext} as its context.
211
+ */
212
+ readonly treeNodeTemplate: _angular_core.Signal<TemplateRef<TreeNodeContext<T>> | undefined>;
213
+ /** @internal — the internal table view instance (table mode). */
214
+ private readonly tableViewChild;
215
+ /**
216
+ * Whether the component is in tree mode.
217
+ * `true` when the `datasource` input is an `ITreeDatasource`. @internal
218
+ */
219
+ protected readonly isTreeMode: _angular_core.Signal<boolean>;
220
+ /**
221
+ * The tree datasource, extracted from the unified `datasource`
222
+ * input. Returns `undefined` when not in tree mode.
223
+ * @internal
224
+ */
225
+ protected readonly resolvedTreeDatasource: _angular_core.Signal<ITreeDatasource<T> | undefined>;
226
+ /**
227
+ * The currently selected item, derived from the table selection
228
+ * model or the tree selection signal. @internal
229
+ */
230
+ protected readonly selectedItem: _angular_core.Signal<T | undefined>;
231
+ /** Context for the detail template outlet. @internal */
232
+ protected readonly detailContext: _angular_core.Signal<MasterDetailContext<T> | undefined>;
233
+ /**
234
+ * The resolved flat-table datasource.
235
+ *
236
+ * Returns the `datasource` input when it is a flat
237
+ * {@link IDatasource} (not a tree). Falls back to an empty
238
+ * {@link FilterableArrayDatasource} when no datasource is set or
239
+ * when the input is a tree datasource.
240
+ * @internal
241
+ */
242
+ protected readonly resolvedTableDatasource: _angular_core.Signal<IDatasource<T>>;
243
+ /**
244
+ * Whether the filter section should be displayed.
245
+ *
246
+ * - Explicit `showFilter` input wins when not `undefined`.
247
+ * - Otherwise auto-detects: `true` when the underlying raw
248
+ * datasource is a {@link FilterableArrayDatasource}.
249
+ * @internal
250
+ */
251
+ protected readonly resolvedShowFilter: _angular_core.Signal<boolean>;
252
+ /**
253
+ * The filter field definitions used by the embedded `<ui-filter>`.
254
+ *
255
+ * Priority: explicit `filterFields` input → inferred from projected
256
+ * columns and the first data row.
257
+ * @internal
258
+ */
259
+ protected readonly resolvedFilterFields: _angular_core.Signal<FilterFieldDefinition<T>[]>;
260
+ /**
261
+ * The raw data array for the embedded filter (used to derive
262
+ * distinct values for autocomplete / select).
263
+ * @internal
264
+ */
265
+ protected readonly resolvedFilterData: _angular_core.Signal<readonly T[]>;
266
+ /** Selection model for the table-view (single mode). */
267
+ readonly selectionModel: SelectionModel<T>;
268
+ /** @internal — currently selected tree nodes (tree mode). */
269
+ protected readonly selectedTreeNodes: _angular_core.WritableSignal<readonly TreeNode<T>[]>;
270
+ /** @internal — whether the filter section is collapsed. */
271
+ protected readonly filterCollapsed: _angular_core.WritableSignal<boolean>;
272
+ /**
273
+ * The current filter predicate for tree mode.
274
+ * Forwarded to the `<ui-tree-view>` `filterPredicate` input.
275
+ * @internal
276
+ */
277
+ protected readonly treeFilterPredicate: _angular_core.WritableSignal<Predicate<T> | undefined>;
278
+ /** @internal */
279
+ protected readonly chevronDown: "<path d=\"m6 9 6 6 6-6\" />";
280
+ /** @internal */
281
+ protected readonly chevronRight: "<path d=\"m9 18 6-6-6-6\" />";
282
+ constructor();
283
+ /**
284
+ * Called by the embedded `<ui-filter>` when the expression changes.
285
+ *
286
+ * - For {@link FilterableArrayDatasource} the expression is applied
287
+ * via `filterBy()` and the adapter is refreshed.
288
+ * - For tree mode the expression is compiled into a predicate for
289
+ * the tree-view's `filterPredicate` input.
290
+ * - Always emits via {@link expressionChange} so consumers with
291
+ * custom datasources can react.
292
+ */
293
+ onFilterExpressionChange(expression: FilterExpression<T>): void;
294
+ /** @internal — toggle filter visibility. */
295
+ protected toggleFilter(): void;
296
+ /**
297
+ * Recursively collects the `data` payloads from every node in the
298
+ * tree datasource into a flat array. Used to infer filter fields
299
+ * and provide distinct values in tree mode.
300
+ */
301
+ private collectTreeData;
302
+ static ɵfac: _angular_core.ɵɵFactoryDeclaration<UIMasterDetailView<any>, never>;
303
+ static ɵcmp: _angular_core.ɵɵComponentDeclaration<UIMasterDetailView<any>, "ui-master-detail-view", never, { "title": { "alias": "title"; "required": false; "isSignal": true; }; "datasource": { "alias": "datasource"; "required": false; "isSignal": true; }; "treeDisplayWith": { "alias": "treeDisplayWith"; "required": false; "isSignal": true; }; "placeholder": { "alias": "placeholder"; "required": false; "isSignal": true; }; "showFilter": { "alias": "showFilter"; "required": false; "isSignal": true; }; "filterExpanded": { "alias": "filterExpanded"; "required": false; "isSignal": true; }; "filterModeLocked": { "alias": "filterModeLocked"; "required": false; "isSignal": true; }; "filterFields": { "alias": "filterFields"; "required": false; "isSignal": true; }; "splitSizes": { "alias": "splitSizes"; "required": false; "isSignal": true; }; "splitName": { "alias": "splitName"; "required": false; "isSignal": true; }; "splitCollapseTarget": { "alias": "splitCollapseTarget"; "required": false; "isSignal": true; }; "listConstraints": { "alias": "listConstraints"; "required": false; "isSignal": true; }; "disabled": { "alias": "disabled"; "required": false; "isSignal": true; }; "pageSize": { "alias": "pageSize"; "required": false; "isSignal": true; }; "pageIndex": { "alias": "pageIndex"; "required": false; "isSignal": true; }; "showBuiltInPaginator": { "alias": "showBuiltInPaginator"; "required": false; "isSignal": true; }; "caption": { "alias": "caption"; "required": false; "isSignal": true; }; "showRowIndexIndicator": { "alias": "showRowIndexIndicator"; "required": false; "isSignal": true; }; "rowIndexHeaderText": { "alias": "rowIndexHeaderText"; "required": false; "isSignal": true; }; "tableId": { "alias": "tableId"; "required": false; "isSignal": true; }; "resizable": { "alias": "resizable"; "required": false; "isSignal": true; }; "rowHeight": { "alias": "rowHeight"; "required": false; "isSignal": true; }; "filterDescriptor": { "alias": "filterDescriptor"; "required": false; "isSignal": true; }; }, { "selectedChange": "selectedChange"; "expressionChange": "expressionChange"; "filterDescriptor": "filterDescriptorChange"; }, ["columns", "detailTemplate", "filterTemplate", "treeNodeTemplate"], ["*"], true, [{ directive: typeof i1.UISurface; inputs: { "surfaceType": "surfaceType"; }; outputs: {}; }]>;
304
+ }
305
+
306
+ /**
307
+ * Types and interfaces for the dashboard host component.
308
+ *
309
+ * A dashboard lays out a set of **panels** on a CSS grid.
310
+ * Each panel declares its grid placement (column/row span)
311
+ * and optional metadata (title, collapsible, removable).
312
+ */
313
+ /**
314
+ * Grid placement descriptor for a single dashboard panel.
315
+ *
316
+ * Values map directly to CSS `grid-column` / `grid-row` span units.
317
+ * All values default to `1` when omitted.
318
+ */
319
+ interface DashboardGridPlacement {
320
+ /** Number of columns the panel spans. */
321
+ readonly colSpan?: number;
322
+ /** Number of rows the panel spans. */
323
+ readonly rowSpan?: number;
324
+ }
325
+ /**
326
+ * Static configuration for a single dashboard panel.
327
+ *
328
+ * Passed as the `[config]` input to `<ui-dashboard-panel>`.
329
+ */
330
+ interface DashboardPanelConfig {
331
+ /** Unique identifier for this panel. */
332
+ readonly id: string;
333
+ /** Display title rendered in the panel header. */
334
+ readonly title: string;
335
+ /**
336
+ * SVG icon content for the panel header and dock chip.
337
+ * Pass an SVG inner-content string (e.g. from `UIIcons.Lucide.*`).
338
+ * Falls back to the dashboard's `defaultDockIcon` when omitted.
339
+ */
340
+ readonly icon?: string;
341
+ /** Grid placement (column / row span). */
342
+ readonly placement?: DashboardGridPlacement;
343
+ /**
344
+ * Whether the panel body can be collapsed by the user.
345
+ * Defaults to `false`.
346
+ */
347
+ readonly collapsible?: boolean;
348
+ /**
349
+ * Whether the panel can be removed (hidden) by the user.
350
+ * Defaults to `false`.
351
+ */
352
+ readonly removable?: boolean;
353
+ }
354
+ /**
355
+ * Predefined column count aliases for common dashboard layouts.
356
+ *
357
+ * - `'auto'` — responsive auto-fill with `minmax(280px, 1fr)`
358
+ * - A number — explicit fixed column count
359
+ */
360
+ type DashboardColumns = "auto" | number;
361
+ /**
362
+ * Where the collapsed-panel dock is rendered relative to the grid.
363
+ *
364
+ * - `'top'` — above the grid
365
+ * - `'bottom'` — below the grid (default)
366
+ */
367
+ type DashboardDockPosition = "top" | "bottom";
368
+
369
+ /**
370
+ * A single panel inside a {@link UIDashboard}.
371
+ *
372
+ * The panel renders a header bar (title + optional collapse / remove
373
+ * controls) and projects arbitrary content via `<ng-content>`.
374
+ *
375
+ * @example
376
+ * ```html
377
+ * <ui-dashboard-panel [config]="{ id: 'sales', title: 'Sales KPI', collapsible: true }">
378
+ * <p>Revenue chart goes here</p>
379
+ * </ui-dashboard-panel>
380
+ * ```
381
+ */
382
+ declare class UIDashboardPanel {
383
+ /** Panel configuration (id, title, grid placement, flags). */
384
+ readonly config: _angular_core.InputSignal<DashboardPanelConfig>;
385
+ /** Emitted when the user removes (hides) this panel. */
386
+ readonly panelRemoved: _angular_core.OutputEmitterRef<string>;
387
+ /** Emitted when the collapsed state changes. */
388
+ readonly collapsedChange: _angular_core.OutputEmitterRef<boolean>;
389
+ /** CSS `grid-column` value derived from placement config. */
390
+ protected readonly gridColumn: _angular_core.Signal<string | undefined>;
391
+ /** CSS `grid-row` value derived from placement config. */
392
+ protected readonly gridRow: _angular_core.Signal<string | undefined>;
393
+ /** Whether the panel header shows a collapse toggle. */
394
+ protected readonly isCollapsible: _angular_core.Signal<boolean>;
395
+ /** Whether the panel header shows a remove button. */
396
+ protected readonly isRemovable: _angular_core.Signal<boolean>;
397
+ /** SVG icon for the collapse toggle button. */
398
+ protected readonly collapseIcon: _angular_core.Signal<"<path d=\"m6 9 6 6 6-6\" />" | "<path d=\"m9 18 6-6-6-6\" />">;
399
+ /** SVG icon for the remove button. */
400
+ protected readonly removeIcon: "<path d=\"M18 6 6 18\" /><path d=\"m6 6 12 12\" />";
401
+ /** Whether the panel body is currently collapsed. */
402
+ readonly collapsed: _angular_core.WritableSignal<boolean>;
403
+ /** Whether the panel has been removed (hidden) by the user. */
404
+ readonly removed: _angular_core.WritableSignal<boolean>;
405
+ /** Whether the panel currently has an active notification. */
406
+ readonly notified: _angular_core.WritableSignal<boolean>;
407
+ private readonly log;
408
+ private readonly destroyRef;
409
+ private notificationTimer;
410
+ constructor();
411
+ /**
412
+ * Activate a notification on this panel.
413
+ *
414
+ * The notification accent remains visible until the panel is
415
+ * focused (expanded) or the optional `timeoutMs` elapses.
416
+ *
417
+ * @param timeoutMs - Auto-clear delay in milliseconds. When `0`
418
+ * or omitted the notification persists until manually cleared.
419
+ */
420
+ notify(timeoutMs?: number): void;
421
+ /** Clear the active notification. */
422
+ clearNotification(): void;
423
+ /** Toggle the collapsed state. */
424
+ toggleCollapse(): void;
425
+ /** Remove (hide) the panel. */
426
+ remove(): void;
427
+ /** Restore a previously removed panel. */
428
+ restore(): void;
429
+ private clearNotificationTimer;
430
+ static ɵfac: _angular_core.ɵɵFactoryDeclaration<UIDashboardPanel, never>;
431
+ static ɵcmp: _angular_core.ɵɵComponentDeclaration<UIDashboardPanel, "ui-dashboard-panel", never, { "config": { "alias": "config"; "required": true; "isSignal": true; }; }, { "panelRemoved": "panelRemoved"; "collapsedChange": "collapsedChange"; }, never, ["*"], true, [{ directive: typeof i1.UISurface; inputs: { "surfaceType": "surfaceType"; }; outputs: {}; }]>;
432
+ }
433
+
434
+ /**
435
+ * Dashboard host component.
436
+ *
437
+ * Lays out projected {@link UIDashboardPanel} children on a CSS grid.
438
+ * The grid column count is configurable via the `columns` input — either
439
+ * a fixed number or `'auto'` for responsive auto-fill.
440
+ *
441
+ * Panels declare their own grid span via their `config.placement`
442
+ * property. The host is intentionally *content-agnostic*: it provides
443
+ * the grid shell and panel management (collapse, remove, restore)
444
+ * while consumers project whatever widgets they need.
445
+ *
446
+ * @example
447
+ * ```html
448
+ * <ui-dashboard [columns]="3" [gap]="16">
449
+ * <ui-dashboard-panel [config]="{ id: 'kpi', title: 'KPI', placement: { colSpan: 2 } }">
450
+ * <my-kpi-widget />
451
+ * </ui-dashboard-panel>
452
+ *
453
+ * <ui-dashboard-panel [config]="{ id: 'chart', title: 'Revenue' }">
454
+ * <my-chart />
455
+ * </ui-dashboard-panel>
456
+ *
457
+ * <ui-dashboard-panel [config]="{ id: 'feed', title: 'Activity', placement: { colSpan: 3 } }">
458
+ * <my-activity-feed />
459
+ * </ui-dashboard-panel>
460
+ * </ui-dashboard>
461
+ * ```
462
+ */
463
+ declare class UIDashboard {
464
+ /**
465
+ * Number of grid columns.
466
+ *
467
+ * - A number (e.g. `3`) creates a fixed column layout.
468
+ * - `'auto'` uses responsive `auto-fill` with `minmax(280px, 1fr)`.
469
+ *
470
+ * Defaults to `'auto'`.
471
+ */
472
+ readonly columns: _angular_core.InputSignal<DashboardColumns>;
473
+ /**
474
+ * Gap between grid cells in pixels.
475
+ * Defaults to `16`.
476
+ */
477
+ readonly gap: _angular_core.InputSignal<number>;
478
+ /**
479
+ * Minimum column width in pixels (only used when `columns` is `'auto'`).
480
+ * Defaults to `280`.
481
+ */
482
+ readonly minColumnWidth: _angular_core.InputSignal<number>;
483
+ /** Accessible label for the dashboard region. */
484
+ readonly ariaLabel: _angular_core.InputSignal<string>;
485
+ /**
486
+ * Where the collapsed-panel dock is rendered.
487
+ * Defaults to `'bottom'`.
488
+ */
489
+ readonly dockPosition: _angular_core.InputSignal<DashboardDockPosition>;
490
+ /**
491
+ * Whether dock chips show the panel title alongside the icon.
492
+ * Defaults to `false` (icon-only with title in tooltip).
493
+ */
494
+ readonly dockShowTitles: _angular_core.InputSignal<boolean>;
495
+ /**
496
+ * Default SVG icon for panels that don't declare their own `icon`.
497
+ * Defaults to the Lucide `LayoutDashboard` icon.
498
+ */
499
+ readonly defaultDockIcon: _angular_core.InputSignal<string>;
500
+ /**
501
+ * SVG icon for the optional dock menu button.
502
+ * When set, a menu button is rendered at the leading edge of the dock.
503
+ * When omitted (`undefined`), no menu button is shown.
504
+ */
505
+ readonly dockMenuIcon: _angular_core.InputSignal<string | undefined>;
506
+ /** Emitted when any panel is removed by the user. */
507
+ readonly panelRemoved: _angular_core.OutputEmitterRef<string>;
508
+ /** Emitted when the dock menu button is clicked. */
509
+ readonly dockMenuClicked: _angular_core.OutputEmitterRef<void>;
510
+ /** All projected dashboard panels. */
511
+ readonly panels: _angular_core.Signal<readonly UIDashboardPanel[]>;
512
+ /** CSS value for `grid-template-columns`. */
513
+ protected readonly gridTemplateColumns: _angular_core.Signal<string>;
514
+ /** CSS value for `gap`. */
515
+ protected readonly gridGap: _angular_core.Signal<string>;
516
+ /** Panels that have been removed by the user. */
517
+ readonly removedPanelIds: _angular_core.Signal<string[]>;
518
+ /** Panels that are currently collapsed (shown in the dock). */
519
+ readonly collapsedPanels: _angular_core.Signal<UIDashboardPanel[]>;
520
+ /** Whether the dock panel-picker menu is open. */
521
+ readonly dockMenuOpen: _angular_core.WritableSignal<boolean>;
522
+ private readonly log;
523
+ private readonly destroyRef;
524
+ private readonly elRef;
525
+ /** Subscriptions to panel `panelRemoved` outputs. */
526
+ private panelSubs;
527
+ constructor();
528
+ /**
529
+ * Restore a previously removed panel by its id.
530
+ *
531
+ * @param panelId - The `config.id` of the panel to restore.
532
+ * @returns `true` if the panel was found and restored.
533
+ */
534
+ restorePanel(panelId: string): boolean;
535
+ /**
536
+ * Restore all removed panels.
537
+ */
538
+ restoreAll(): void;
539
+ /**
540
+ * Resolve the icon SVG for a panel, falling back to the default.
541
+ *
542
+ * @param panelIcon - The panel's own icon, if any.
543
+ * @returns SVG inner-content string.
544
+ */
545
+ protected resolveIcon(panelIcon: string | undefined): string;
546
+ /** Toggle the dock panel-picker menu. */
547
+ toggleDockMenu(): void;
548
+ /** Close the dock panel-picker menu. */
549
+ closeDockMenu(): void;
550
+ /**
551
+ * Toggle a panel's collapsed state from the menu.
552
+ * If removed, restore it first.
553
+ */
554
+ protected menuTogglePanel(panel: UIDashboardPanel): void;
555
+ static ɵfac: _angular_core.ɵɵFactoryDeclaration<UIDashboard, never>;
556
+ static ɵcmp: _angular_core.ɵɵComponentDeclaration<UIDashboard, "ui-dashboard", never, { "columns": { "alias": "columns"; "required": false; "isSignal": true; }; "gap": { "alias": "gap"; "required": false; "isSignal": true; }; "minColumnWidth": { "alias": "minColumnWidth"; "required": false; "isSignal": true; }; "ariaLabel": { "alias": "ariaLabel"; "required": false; "isSignal": true; }; "dockPosition": { "alias": "dockPosition"; "required": false; "isSignal": true; }; "dockShowTitles": { "alias": "dockShowTitles"; "required": false; "isSignal": true; }; "defaultDockIcon": { "alias": "defaultDockIcon"; "required": false; "isSignal": true; }; "dockMenuIcon": { "alias": "dockMenuIcon"; "required": false; "isSignal": true; }; }, { "panelRemoved": "panelRemoved"; "dockMenuClicked": "dockMenuClicked"; }, ["panels"], ["[dockMenuItem]", "*", "[dockMenuItem]"], true, [{ directive: typeof i1.UISurface; inputs: { "surfaceType": "surfaceType"; }; outputs: {}; }]>;
557
+ }
558
+
559
+ /**
560
+ * Convenience type alias for a navigation tree node.
561
+ *
562
+ * A `NavigationNode` is a {@link TreeNode} whose data payload is
563
+ * {@link NavigationNodeData}. Leaf nodes render as sidebar items;
564
+ * nodes with `children` render as collapsible sidebar groups.
565
+ */
566
+ type NavigationNode = TreeNode<NavigationNodeData>;
567
+ /**
568
+ * Creates a leaf navigation node (sidebar item).
569
+ *
570
+ * @param id - Unique identifier (also used as the active-page key).
571
+ * @param label - Display text in the sidebar and breadcrumb.
572
+ * @param options - Optional icon, badge, route, and disabled state.
573
+ * @returns A {@link NavigationNode} without children.
574
+ *
575
+ * @example
576
+ * ```ts
577
+ * navItem('dashboard', 'Dashboard', {
578
+ * icon: UIIcons.Lucide.Layout.LayoutDashboard,
579
+ * badge: '3',
580
+ * })
581
+ * ```
582
+ */
583
+ declare function navItem(id: string, label: string, options?: {
584
+ readonly icon?: string;
585
+ readonly badge?: string;
586
+ readonly route?: string;
587
+ readonly disabled?: boolean;
588
+ }): NavigationNode;
589
+ /**
590
+ * Creates a group navigation node (collapsible sidebar group).
591
+ *
592
+ * @param id - Unique identifier for the group.
593
+ * @param label - Display text for the group header.
594
+ * @param children - Child navigation nodes rendered inside the group.
595
+ * @param options - Optional icon and expanded state.
596
+ * @returns A {@link NavigationNode} with children.
597
+ *
598
+ * @example
599
+ * ```ts
600
+ * navGroup('settings', 'Settings', [
601
+ * navItem('general', 'General'),
602
+ * navItem('security', 'Security'),
603
+ * ], { icon: UIIcons.Lucide.Account.Settings })
604
+ * ```
605
+ */
606
+ declare function navGroup(id: string, label: string, children: readonly NavigationNode[], options?: {
607
+ readonly icon?: string;
608
+ readonly expanded?: boolean;
609
+ }): NavigationNode;
610
+ /**
611
+ * Shape of a route entry compatible with Angular's `Route` type.
612
+ *
613
+ * This is intentionally a structural type so consumers can pass
614
+ * `inject(Router).config` directly without the library depending
615
+ * on `@angular/router`.
616
+ *
617
+ * Routes are only included in the output when they carry
618
+ * `data.navLabel`. Additional metadata keys:
619
+ *
620
+ * | Key | Type | Maps to |
621
+ * |-----------------|-----------|------------------------------|
622
+ * | `navLabel` | `string` | `data.label` |
623
+ * | `navIcon` | `string` | `node.icon` |
624
+ * | `navBadge` | `string` | `data.badge` |
625
+ * | `navDisabled` | `boolean` | `node.disabled` |
626
+ * | `navExpanded` | `boolean` | `node.expanded` (for groups) |
627
+ */
628
+ interface NavigationRouteConfig {
629
+ readonly path?: string;
630
+ readonly data?: Readonly<Record<string, unknown>>;
631
+ readonly children?: readonly NavigationRouteConfig[];
632
+ }
633
+ /**
634
+ * Converts an Angular-Router-compatible route config array into
635
+ * {@link NavigationNode NavigationNode[]} for use with
636
+ * {@link UINavigationPage}.
637
+ *
638
+ * Only routes that include `data: { navLabel: '…' }` are emitted.
639
+ * Child routes are recursively processed, producing group nodes
640
+ * when a parent has navigable children.
641
+ *
642
+ * @param routes - The route configuration (e.g. `inject(Router).config`).
643
+ * @param parentPath - Internal: accumulated path prefix for nested routes.
644
+ * @returns An array of navigation tree nodes.
645
+ *
646
+ * @example
647
+ * ```ts
648
+ * // In your app component:
649
+ * private readonly router = inject(Router);
650
+ * readonly navItems = routesToNavigation(this.router.config);
651
+ * ```
652
+ */
653
+ declare function routesToNavigation(routes: readonly NavigationRouteConfig[], parentPath?: string): NavigationNode[];
654
+
655
+ /**
656
+ * Data payload carried by each node in the navigation tree.
657
+ *
658
+ * The structural properties (`id`, `icon`, `disabled`, `expanded`,
659
+ * `children`) live on the {@link TreeNode} wrapper; this interface
660
+ * holds the domain-specific fields.
661
+ */
662
+ interface NavigationNodeData {
663
+ /** Display label shown in the sidebar and breadcrumb trail. */
664
+ readonly label: string;
665
+ /**
666
+ * Optional trailing badge text (e.g. an unread count).
667
+ * Forwarded to the sidebar item's `[badge]` input.
668
+ */
669
+ readonly badge?: string;
670
+ /**
671
+ * Optional route path for Angular Router integration.
672
+ *
673
+ * When items are produced by `routesToNavigation()`, this is set
674
+ * to the full resolved path segment. Consumers can use it in the
675
+ * `(navigated)` handler to call `router.navigate()`.
676
+ */
677
+ readonly route?: string;
678
+ }
679
+ /** Template context for the projected content template. */
680
+ interface NavigationPageContext {
681
+ /** The currently active navigation node. */
682
+ readonly $implicit: NavigationNode;
683
+ /** The currently active navigation node (named binding). */
684
+ readonly page: NavigationNode;
685
+ }
686
+ /**
687
+ * A full-page navigation layout that combines a {@link UIDrawer},
688
+ * a {@link UISidebarNav} with configurable items, a {@link UIBreadcrumb}
689
+ * path, and a main content area.
690
+ *
691
+ * Navigation items are provided as a tree — either via an
692
+ * {@link ITreeDatasource} for dynamic data, or via a convenience
693
+ * `items` input accepting `NavigationNode[]`.
694
+ *
695
+ * Tree nodes with **children** are rendered as collapsible
696
+ * `<ui-sidebar-group>` elements; leaf nodes render as
697
+ * `<ui-sidebar-item>` entries. The breadcrumb trail is built
698
+ * automatically from the node hierarchy.
699
+ *
700
+ * ### Data sources
701
+ *
702
+ * | Input | Type | Use case |
703
+ * |--------------|------------------------------------------|------------------------------|
704
+ * | `datasource` | `ITreeDatasource<NavigationNodeData>` | Dynamic / async data |
705
+ * | `items` | `NavigationNode[]` | Static in-memory tree |
706
+ *
707
+ * When both are set, `datasource` takes precedence.
708
+ *
709
+ * Use the `navItem()` and `navGroup()` factory functions (or
710
+ * `routesToNavigation()` for Angular Router integration) to build
711
+ * the node array ergonomically.
712
+ *
713
+ * @example
714
+ * ```html
715
+ * <ui-navigation-page
716
+ * [items]="navItems"
717
+ * [(activePage)]="currentPage"
718
+ * (navigated)="onNavigate($event)"
719
+ * >
720
+ * <ng-template #content let-node>
721
+ * <h2>{{ node.data.label }}</h2>
722
+ * </ng-template>
723
+ * </ui-navigation-page>
724
+ * ```
725
+ */
726
+ declare class UINavigationPage implements OnInit {
727
+ /**
728
+ * Tree datasource providing navigation nodes.
729
+ *
730
+ * Accepts any {@link ITreeDatasource} whose data payload is
731
+ * {@link NavigationNodeData}. Root nodes with `children` render as
732
+ * collapsible groups; leaf nodes render as sidebar items.
733
+ *
734
+ * Takes precedence over the `items` convenience input.
735
+ */
736
+ readonly datasource: _angular_core.InputSignal<ITreeDatasource<NavigationNodeData> | undefined>;
737
+ /**
738
+ * Convenience: static array of navigation tree nodes.
739
+ *
740
+ * When set (and no `datasource` is provided), an internal
741
+ * `ArrayTreeDatasource` is created automatically.
742
+ *
743
+ * Build nodes with the `navItem()` / `navGroup()` factories
744
+ * or the `routesToNavigation()` utility.
745
+ */
746
+ readonly items: _angular_core.InputSignal<readonly NavigationNode[]>;
747
+ /**
748
+ * Root breadcrumb label displayed as the first item in the trail.
749
+ * Clicking it navigates to the first leaf node.
750
+ */
751
+ readonly rootLabel: _angular_core.InputSignal<string>;
752
+ /** Side the drawer slides in from. */
753
+ readonly drawerPosition: _angular_core.InputSignal<DrawerPosition>;
754
+ /** Width of the drawer panel. */
755
+ readonly drawerWidth: _angular_core.InputSignal<string>;
756
+ /** Visual style for the breadcrumb trail. */
757
+ readonly breadcrumbVariant: _angular_core.InputSignal<BreadcrumbVariant>;
758
+ /** Accessible label for the navigation landmark. */
759
+ readonly ariaLabel: _angular_core.InputSignal<string>;
760
+ /** Whether the drawer should always be visible (desktop layout). */
761
+ readonly sidebarPinned: _angular_core.InputSignal<boolean>;
762
+ /** Whether to show the sidebar toggle button before the breadcrumb. */
763
+ readonly showSidebarToggle: _angular_core.InputSignal<boolean>;
764
+ /**
765
+ * Optional localStorage key for persisting the sidebar open/closed state.
766
+ *
767
+ * When set, the component reads the stored value on creation and
768
+ * writes back whenever `sidebarVisible` changes. Leave empty
769
+ * (the default) to disable persistence.
770
+ */
771
+ readonly storageKey: _angular_core.InputSignal<string>;
772
+ /** The currently active node id. Supports two-way binding. */
773
+ readonly activePage: _angular_core.ModelSignal<string>;
774
+ /** Whether the drawer is open (when not pinned). Supports two-way binding. */
775
+ readonly drawerOpen: _angular_core.ModelSignal<boolean>;
776
+ /** Whether the sidebar panel is visible. Supports two-way binding. Defaults to shown. */
777
+ readonly sidebarVisible: _angular_core.ModelSignal<boolean>;
778
+ /** Emitted when the user navigates to a node. */
779
+ readonly navigated: _angular_core.OutputEmitterRef<NavigationNode>;
780
+ /**
781
+ * Projected template for the main content area.
782
+ * Receives the current {@link NavigationNode} as the implicit context.
783
+ *
784
+ * ```html
785
+ * <ng-template #content let-node>
786
+ * <h2>{{ node.data.label }}</h2>
787
+ * </ng-template>
788
+ * ```
789
+ */
790
+ readonly contentTemplate: _angular_core.Signal<TemplateRef<NavigationPageContext> | undefined>;
791
+ /** Projected sidebar items for custom content above the generated items. */
792
+ readonly projectedItems: _angular_core.Signal<readonly UISidebarItem[]>;
793
+ /** Icon for the sidebar toggle button. @internal */
794
+ protected readonly sidebarToggleIcon: _angular_core.Signal<"<rect width=\"18\" height=\"18\" x=\"3\" y=\"3\" rx=\"2\" /><path d=\"M9 3v18\" /><path d=\"m16 15-3-3 3-3\" />" | "<rect width=\"18\" height=\"18\" x=\"3\" y=\"3\" rx=\"2\" /><path d=\"M9 3v18\" /><path d=\"m14 9 3 3-3 3\" />">;
795
+ private readonly storage;
796
+ ngOnInit(): void;
797
+ /** Toggle the sidebar and persist the new state to storage. */
798
+ toggleSidebar(): void;
799
+ /** Resolved datasource — from the input or auto-created from items. */
800
+ protected readonly resolvedDatasource: _angular_core.Signal<ITreeDatasource<NavigationNodeData>>;
801
+ /** Root nodes from the resolved datasource. */
802
+ protected readonly rootNodes: _angular_core.Signal<readonly NavigationNode[]>;
803
+ /** The currently active navigation node. */
804
+ readonly currentPage: _angular_core.Signal<NavigationNode | undefined>;
805
+ /** Breadcrumb trail derived from the active node and its ancestors. */
806
+ protected readonly breadcrumbItems: _angular_core.Signal<readonly BreadcrumbItem[]>;
807
+ /** Navigate to a node by its tree-node reference. */
808
+ navigate(node: NavigationNode): void;
809
+ /** Navigate to the first leaf node (root breadcrumb click handler). */
810
+ navigateToRoot(): void;
811
+ /** @internal Handle breadcrumb item clicks. */
812
+ protected onBreadcrumbClick(item: BreadcrumbItem): void;
813
+ /**
814
+ * Finds a node by `id` anywhere in the tree (depth-first).
815
+ * @internal
816
+ */
817
+ private findNodeById;
818
+ /**
819
+ * Finds a node by `data.label` anywhere in the tree (depth-first).
820
+ * @internal
821
+ */
822
+ private findNodeByLabel;
823
+ /**
824
+ * Finds the parent node of a given child `id`.
825
+ * @internal
826
+ */
827
+ private findParent;
828
+ /**
829
+ * Returns the first leaf node (no children) in the tree.
830
+ * @internal
831
+ */
832
+ private firstLeaf;
833
+ static ɵfac: _angular_core.ɵɵFactoryDeclaration<UINavigationPage, never>;
834
+ static ɵcmp: _angular_core.ɵɵComponentDeclaration<UINavigationPage, "ui-navigation-page", never, { "datasource": { "alias": "datasource"; "required": false; "isSignal": true; }; "items": { "alias": "items"; "required": false; "isSignal": true; }; "rootLabel": { "alias": "rootLabel"; "required": false; "isSignal": true; }; "drawerPosition": { "alias": "drawerPosition"; "required": false; "isSignal": true; }; "drawerWidth": { "alias": "drawerWidth"; "required": false; "isSignal": true; }; "breadcrumbVariant": { "alias": "breadcrumbVariant"; "required": false; "isSignal": true; }; "ariaLabel": { "alias": "ariaLabel"; "required": false; "isSignal": true; }; "sidebarPinned": { "alias": "sidebarPinned"; "required": false; "isSignal": true; }; "showSidebarToggle": { "alias": "showSidebarToggle"; "required": false; "isSignal": true; }; "storageKey": { "alias": "storageKey"; "required": false; "isSignal": true; }; "activePage": { "alias": "activePage"; "required": false; "isSignal": true; }; "drawerOpen": { "alias": "drawerOpen"; "required": false; "isSignal": true; }; "sidebarVisible": { "alias": "sidebarVisible"; "required": false; "isSignal": true; }; }, { "activePage": "activePageChange"; "drawerOpen": "drawerOpenChange"; "sidebarVisible": "sidebarVisibleChange"; "navigated": "navigated"; }, ["contentTemplate", "projectedItems"], ["[uiSidebarHeader]", "ui-sidebar-item", "[uiSidebarFooter]", "[uiSidebarHeader]", "ui-sidebar-item", "[uiSidebarFooter]", "*"], true, [{ directive: typeof i1.UISurface; inputs: { "surfaceType": "surfaceType"; }; outputs: {}; }]>;
835
+ }
836
+
837
+ /**
838
+ * A named, serialisable saved search — stores the filter state so it
839
+ * can be recalled later.
840
+ *
841
+ * @typeParam T - The row object type (carried through for
842
+ * {@link FilterDescriptor} typing).
843
+ */
844
+ interface SavedSearch<T = unknown> {
845
+ /** Unique identifier (UUID). */
846
+ readonly id: string;
847
+ /** Human-readable display name chosen by the user. */
848
+ readonly name: string;
849
+ /** The persisted filter descriptor (junction + rules). */
850
+ readonly descriptor: FilterDescriptor<T>;
851
+ /** ISO-8601 timestamp of when the search was saved. */
852
+ readonly savedAt: string;
853
+ }
854
+
855
+ /**
856
+ * Layout mode for the search-view results area.
857
+ *
858
+ * - `'table'` — renders an internal `<ui-table-view>` using projected columns.
859
+ * - `'custom'` — renders the projected `#results` template, giving the
860
+ * consumer full control over the results layout.
861
+ */
862
+ type SearchViewLayout = "table" | "custom";
863
+ /**
864
+ * Context object provided to the projected `#results` template.
865
+ *
866
+ * @typeParam T - The row object type.
867
+ */
868
+ interface SearchViewResultsContext<T> {
869
+ /** The current slice of items (also available as `let-items`). */
870
+ $implicit: readonly T[];
871
+ }
872
+ /**
873
+ * Context object provided to the projected `#empty` template.
874
+ */
875
+ interface SearchViewEmptyContext {
876
+ /** The current search/filter state produced zero results. */
877
+ $implicit: true;
878
+ }
879
+
880
+ /**
881
+ * A unified browse-and-filter layout that composes {@link UIFilter},
882
+ * {@link UITableView} (or a custom results template), and
883
+ * {@link UIPagination} into a single search screen.
884
+ *
885
+ * ### Table mode (default)
886
+ * ```html
887
+ * <ui-search-view [datasource]="ds" title="Users">
888
+ * <ui-text-column key="name" headerText="Name" />
889
+ * <ui-text-column key="email" headerText="Email" />
890
+ * </ui-search-view>
891
+ * ```
892
+ *
893
+ * ### Custom results template
894
+ * ```html
895
+ * <ui-search-view [datasource]="ds" layout="custom" [filterFields]="fields">
896
+ * <ng-template #results let-items>
897
+ * @for (item of items; track item.id) {
898
+ * <app-card [data]="item" />
899
+ * }
900
+ * </ng-template>
901
+ * </ui-search-view>
902
+ * ```
903
+ *
904
+ * ### With custom filter template
905
+ * ```html
906
+ * <ui-search-view [datasource]="ds">
907
+ * <ng-template #filter>
908
+ * <my-custom-filter (change)="applyFilter($event)" />
909
+ * </ng-template>
910
+ * <ui-text-column key="name" headerText="Name" />
911
+ * </ui-search-view>
912
+ * ```
913
+ */
914
+ declare class UISearchView<T = unknown> {
915
+ /** Title displayed in the header area. */
916
+ readonly title: _angular_core.InputSignal<string>;
917
+ /**
918
+ * The datasource powering the search results.
919
+ *
920
+ * Accepts any {@link IDatasource}. When the datasource is a
921
+ * {@link FilterableArrayDatasource} the component automatically
922
+ * applies filter expressions from the embedded filter.
923
+ */
924
+ readonly datasource: _angular_core.InputSignal<IDatasource<T> | undefined>;
925
+ /**
926
+ * Results layout mode.
927
+ *
928
+ * - `'table'` (default) — uses `<ui-table-view>` with projected columns.
929
+ * - `'custom'` — renders the projected `#results` template.
930
+ */
931
+ readonly layout: _angular_core.InputSignal<SearchViewLayout>;
932
+ /**
933
+ * Explicit filter field definitions.
934
+ *
935
+ * When provided these override the auto-inferred fields derived
936
+ * from projected columns and sample data.
937
+ */
938
+ readonly filterFields: _angular_core.InputSignal<FilterFieldDefinition<T>[] | undefined>;
939
+ /**
940
+ * Whether the filter section is visible.
941
+ *
942
+ * - `true` — always show the filter.
943
+ * - `false` — never show the filter.
944
+ * - `undefined` (default) — auto-detect: show when the datasource
945
+ * is a {@link FilterableArrayDatasource}.
946
+ */
947
+ readonly showFilter: _angular_core.InputSignal<boolean | undefined>;
948
+ /** Whether the filter section starts expanded. */
949
+ readonly filterExpanded: _angular_core.InputSignal<boolean>;
950
+ /** Whether the filter toggle button is hidden. */
951
+ readonly filterModeLocked: _angular_core.InputSignal<boolean>;
952
+ /** Whether to show the pagination footer. */
953
+ readonly showPagination: _angular_core.InputSignal<boolean>;
954
+ /** Items per page. */
955
+ readonly pageSize: _angular_core.InputSignal<number>;
956
+ /** Available page-size options in the pagination selector. */
957
+ readonly pageSizeOptions: _angular_core.InputSignal<readonly number[]>;
958
+ /** Placeholder text shown when there are no results. */
959
+ readonly placeholder: _angular_core.InputSignal<string>;
960
+ /** Accessible label for the component. */
961
+ readonly ariaLabel: _angular_core.InputSignal<string>;
962
+ /**
963
+ * Storage key that enables the saved-searches feature.
964
+ *
965
+ * When set, a toolbar strip is shown allowing users to save, load,
966
+ * and delete named filter states. The key is used to namespace the
967
+ * persisted data in the underlying {@link StorageService}.
968
+ *
969
+ * Leave `undefined` (default) to disable saved searches.
970
+ */
971
+ readonly storageKey: _angular_core.InputSignal<string | undefined>;
972
+ /**
973
+ * Emits the {@link FilterExpression} every time the filter rules change.
974
+ */
975
+ readonly expressionChange: _angular_core.OutputEmitterRef<FilterDescriptor<T>>;
976
+ /** Emits when the page changes. */
977
+ readonly pageChange: _angular_core.OutputEmitterRef<PageChangeEvent>;
978
+ /** Emits when a saved search is loaded, saved, or deleted. */
979
+ readonly savedSearchChange: _angular_core.OutputEmitterRef<SavedSearch<unknown> | null>;
980
+ /** The filter descriptor state (two-way bindable). */
981
+ readonly filterDescriptor: _angular_core.ModelSignal<FilterDescriptor<T>>;
982
+ /** Current page index (two-way bindable, zero-based). */
983
+ readonly pageIndex: _angular_core.ModelSignal<number>;
984
+ /** Projected table-view columns (used in table layout mode). */
985
+ readonly columns: _angular_core.Signal<readonly UITableViewColumn[]>;
986
+ /** Optional custom results template (used in custom layout mode). */
987
+ readonly resultsTemplate: _angular_core.Signal<TemplateRef<SearchViewResultsContext<T>> | undefined>;
988
+ /** Optional custom filter template. */
989
+ readonly filterTemplate: _angular_core.Signal<TemplateRef<unknown> | undefined>;
990
+ /** Optional empty-state template. */
991
+ readonly emptyTemplate: _angular_core.Signal<TemplateRef<unknown> | undefined>;
992
+ /** @internal — reference to the embedded table-view (when in table layout). */
993
+ private readonly tableView;
994
+ /** @internal */
995
+ protected readonly chevronRight: "<path d=\"m9 18 6-6-6-6\" />";
996
+ /** @internal */
997
+ protected readonly chevronDown: "<path d=\"m6 9 6 6 6-6\" />";
998
+ /** @internal — whether the filter panel is collapsed. */
999
+ protected readonly filterCollapsed: _angular_core.WritableSignal<boolean>;
1000
+ /** @internal — total item count from the datasource. */
1001
+ protected readonly totalItems: _angular_core.WritableSignal<number>;
1002
+ /** @internal */
1003
+ protected readonly resolvedShowFilter: _angular_core.Signal<boolean>;
1004
+ /** @internal — auto-inferred or explicit filter fields. */
1005
+ protected readonly resolvedFilterFields: _angular_core.Signal<FilterFieldDefinition<T>[]>;
1006
+ /** @internal — sample data for filter value suggestions. */
1007
+ protected readonly resolvedFilterData: _angular_core.Signal<readonly T[]>;
1008
+ /** @internal — whether the saved-searches feature is enabled. */
1009
+ protected readonly savedSearchesEnabled: _angular_core.Signal<boolean>;
1010
+ /** @internal — list of persisted saved searches. */
1011
+ protected readonly savedSearches: _angular_core.WritableSignal<readonly SavedSearch<unknown>[]>;
1012
+ /** @internal — ID of the currently selected saved search (empty = none). */
1013
+ protected readonly selectedSearchId: _angular_core.WritableSignal<string>;
1014
+ /** @internal — name input value when saving a filter. */
1015
+ protected readonly searchName: _angular_core.WritableSignal<string>;
1016
+ /** @internal — whether the save-filter dialog is open. */
1017
+ protected readonly saveDialogOpen: _angular_core.WritableSignal<boolean>;
1018
+ /** @internal — index of the chip being dragged (−1 = none). */
1019
+ private dragSourceIndex;
1020
+ /**
1021
+ * @internal — bumped after every `filterBy` call so computeds
1022
+ * that depend on the datasource's filtered state re-evaluate.
1023
+ */
1024
+ private readonly _filterVersion;
1025
+ /**
1026
+ * @internal — the rows for the current page (filtered + paged).
1027
+ * Used only for custom layout mode where the table is not
1028
+ * available to handle paging internally.
1029
+ */
1030
+ protected readonly pagedRows: _angular_core.Signal<readonly T[]>;
1031
+ private readonly savedSearchService;
1032
+ constructor();
1033
+ /** Toggle the filter panel open/closed. */
1034
+ toggleFilter(): void;
1035
+ /**
1036
+ * Load a saved search by its ID, applying its filter descriptor
1037
+ * to the search view.
1038
+ */
1039
+ loadSavedSearch(searchId: string): void;
1040
+ /**
1041
+ * Save the current filter state as a new named search.
1042
+ */
1043
+ saveNewSearch(name: string): void;
1044
+ /**
1045
+ * Delete a saved search by its ID.
1046
+ */
1047
+ deleteSavedSearch(searchId: string): void;
1048
+ /** @internal */
1049
+ protected readonly saveIcon: "<path d=\"M15.2 3a2 2 0 0 1 1.4.6l3.8 3.8a2 2 0 0 1 .6 1.4V19a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2z\" /><path d=\"M17 21v-7a1 1 0 0 0-1-1H8a1 1 0 0 0-1 1v7\" /><path d=\"M7 3v4a1 1 0 0 0 1 1h7\" />";
1050
+ /** @internal */
1051
+ protected readonly xIcon: "<path d=\"M18 6 6 18\" /><path d=\"m6 6 12 12\" />";
1052
+ /** @internal */
1053
+ protected onLoadSearch(searchId: string): void;
1054
+ /** @internal */
1055
+ protected onDeleteSearch(event: Event, searchId: string): void;
1056
+ /** @internal — opens the save-filter dialog. */
1057
+ protected onSaveFilterClick(): void;
1058
+ /** @internal */
1059
+ protected onConfirmSave(): void;
1060
+ /** @internal */
1061
+ protected onCancelSave(): void;
1062
+ /** @internal */
1063
+ protected onChipDragStart(event: DragEvent, index: number): void;
1064
+ /** @internal */
1065
+ protected onChipDragOver(event: DragEvent): void;
1066
+ /** @internal */
1067
+ protected onChipDrop(event: DragEvent, targetIndex: number): void;
1068
+ /** @internal */
1069
+ protected onChipDragEnd(): void;
1070
+ /** @internal */
1071
+ protected onFilterExpressionChange(expression: FilterExpression<T>): void;
1072
+ /** @internal */
1073
+ protected onPageChange(event: PageChangeEvent): void;
1074
+ static ɵfac: _angular_core.ɵɵFactoryDeclaration<UISearchView<any>, never>;
1075
+ static ɵcmp: _angular_core.ɵɵComponentDeclaration<UISearchView<any>, "ui-search-view", never, { "title": { "alias": "title"; "required": false; "isSignal": true; }; "datasource": { "alias": "datasource"; "required": false; "isSignal": true; }; "layout": { "alias": "layout"; "required": false; "isSignal": true; }; "filterFields": { "alias": "filterFields"; "required": false; "isSignal": true; }; "showFilter": { "alias": "showFilter"; "required": false; "isSignal": true; }; "filterExpanded": { "alias": "filterExpanded"; "required": false; "isSignal": true; }; "filterModeLocked": { "alias": "filterModeLocked"; "required": false; "isSignal": true; }; "showPagination": { "alias": "showPagination"; "required": false; "isSignal": true; }; "pageSize": { "alias": "pageSize"; "required": false; "isSignal": true; }; "pageSizeOptions": { "alias": "pageSizeOptions"; "required": false; "isSignal": true; }; "placeholder": { "alias": "placeholder"; "required": false; "isSignal": true; }; "ariaLabel": { "alias": "ariaLabel"; "required": false; "isSignal": true; }; "storageKey": { "alias": "storageKey"; "required": false; "isSignal": true; }; "filterDescriptor": { "alias": "filterDescriptor"; "required": false; "isSignal": true; }; "pageIndex": { "alias": "pageIndex"; "required": false; "isSignal": true; }; }, { "expressionChange": "expressionChange"; "pageChange": "pageChange"; "savedSearchChange": "savedSearchChange"; "filterDescriptor": "filterDescriptorChange"; "pageIndex": "pageIndexChange"; }, ["columns", "resultsTemplate", "filterTemplate", "emptyTemplate"], ["*"], true, [{ directive: typeof i1.UISurface; inputs: { "surfaceType": "surfaceType"; }; outputs: {}; }]>;
1076
+ }
1077
+
1078
+ /**
1079
+ * Manages persisted saved searches through the application-wide
1080
+ * {@link StorageService} (which defaults to `localStorage` via
1081
+ * the `STORAGE_STRATEGY` injection token).
1082
+ *
1083
+ * Searches are stored as a JSON array under a key derived from the
1084
+ * caller-supplied `storageKey`. Multiple independent search views can
1085
+ * coexist by using different storage keys.
1086
+ *
1087
+ * ### Usage
1088
+ *
1089
+ * ```ts
1090
+ * private readonly savedSearchService = inject(SavedSearchService);
1091
+ *
1092
+ * // list
1093
+ * const searches = this.savedSearchService.list('my-view');
1094
+ *
1095
+ * // save
1096
+ * this.savedSearchService.save('my-view', {
1097
+ * id: crypto.randomUUID(),
1098
+ * name: 'Active users',
1099
+ * descriptor: { junction: 'and', rules: [...] },
1100
+ * savedAt: new Date().toISOString(),
1101
+ * });
1102
+ *
1103
+ * // delete
1104
+ * this.savedSearchService.remove('my-view', searchId);
1105
+ * ```
1106
+ *
1107
+ * ### Swapping the storage backend
1108
+ *
1109
+ * Override the `STORAGE_STRATEGY` token from `@theredhead/lucid-foundation`:
1110
+ *
1111
+ * ```ts
1112
+ * providers: [
1113
+ * { provide: STORAGE_STRATEGY, useClass: MyIndexedDbStrategy },
1114
+ * ]
1115
+ * ```
1116
+ */
1117
+ declare class SavedSearchService {
1118
+ private readonly storage;
1119
+ /**
1120
+ * Retrieve all saved searches for the given storage key.
1121
+ *
1122
+ * Returns an empty array when nothing is stored or when the stored
1123
+ * value cannot be parsed.
1124
+ */
1125
+ list(storageKey: string): SavedSearch[];
1126
+ /**
1127
+ * Persist a saved search. If a search with the same `id` already
1128
+ * exists it is replaced; otherwise the new search is appended.
1129
+ */
1130
+ save(storageKey: string, search: SavedSearch): void;
1131
+ /**
1132
+ * Remove a saved search by its `id`.
1133
+ *
1134
+ * No-op if the id does not exist.
1135
+ */
1136
+ remove(storageKey: string, searchId: string): void;
1137
+ /**
1138
+ * Persist a new ordering of saved searches.
1139
+ *
1140
+ * Accepts an array of IDs in the desired order. Searches whose
1141
+ * IDs are not in the list are dropped.
1142
+ */
1143
+ reorder(storageKey: string, orderedIds: readonly string[]): void;
1144
+ /**
1145
+ * Remove all saved searches for a given storage key.
1146
+ */
1147
+ clear(storageKey: string): void;
1148
+ private prefixedKey;
1149
+ private persist;
1150
+ static ɵfac: _angular_core.ɵɵFactoryDeclaration<SavedSearchService, never>;
1151
+ static ɵprov: _angular_core.ɵɵInjectableDeclaration<SavedSearchService>;
1152
+ }
1153
+
1154
+ /**
1155
+ * Supported field types for a property sheet row.
1156
+ *
1157
+ * Each type maps to a specific editor widget:
1158
+ * - `'string'` → `<ui-input type="text">`
1159
+ * - `'number'` → `<ui-input type="number">`
1160
+ * - `'boolean'` → `<ui-checkbox>`
1161
+ * - `'select'` → `<ui-select>`
1162
+ * - `'color'` → `<ui-color-picker>`
1163
+ * - `'slider'` → `<ui-slider>`
1164
+ */
1165
+ type PropertyFieldType = "string" | "number" | "boolean" | "select" | "color" | "slider";
1166
+ /**
1167
+ * Definition for a single property field in a {@link UIPropertySheet}.
1168
+ *
1169
+ * @typeParam T - The data object type.
1170
+ */
1171
+ interface PropertyFieldDefinition<T = Record<string, unknown>> {
1172
+ /** The key on the data object this field reads/writes. */
1173
+ readonly key: string & keyof T;
1174
+ /** Human-readable label. */
1175
+ readonly label: string;
1176
+ /** Editor type. */
1177
+ readonly type: PropertyFieldType;
1178
+ /**
1179
+ * Category/group name. Fields with the same group are rendered
1180
+ * together under a shared heading.
1181
+ */
1182
+ readonly group?: string;
1183
+ /** Placeholder text (string / number fields). */
1184
+ readonly placeholder?: string;
1185
+ /** Whether this field is read-only. */
1186
+ readonly readonly?: boolean;
1187
+ /** Options for `'select'` fields. */
1188
+ readonly options?: readonly SelectOption[];
1189
+ /** Minimum value for `'number'` / `'slider'` fields. */
1190
+ readonly min?: number;
1191
+ /** Maximum value for `'number'` / `'slider'` fields. */
1192
+ readonly max?: number;
1193
+ /** Step for `'number'` / `'slider'` fields. */
1194
+ readonly step?: number;
1195
+ }
1196
+ /**
1197
+ * Event emitted when a property value changes.
1198
+ *
1199
+ * @typeParam T - The data object type.
1200
+ */
1201
+ interface PropertyChangeEvent<T = Record<string, unknown>> {
1202
+ /** The field key that changed. */
1203
+ readonly key: string & keyof T;
1204
+ /** The new value. */
1205
+ readonly value: unknown;
1206
+ /** The complete, updated data object. */
1207
+ readonly data: T;
1208
+ }
1209
+
1210
+ /**
1211
+ * Grouped field set used internally to organise fields by group.
1212
+ * @internal
1213
+ */
1214
+ interface FieldGroup<T> {
1215
+ readonly name: string;
1216
+ readonly fields: readonly PropertyFieldDefinition<T>[];
1217
+ }
1218
+ /**
1219
+ * A key-value inspector panel that renders a schema of typed fields
1220
+ * against a data object.
1221
+ *
1222
+ * Each field definition maps to an appropriate editor widget
1223
+ * (`UIInput`, `UISelect`, `UICheckbox`, `UIColorPicker`, or
1224
+ * `UISlider`). Changes are emitted per-field via
1225
+ * {@link propertyChange} and the data model is updated in-place.
1226
+ *
1227
+ * ### Basic usage
1228
+ * ```html
1229
+ * <ui-property-sheet
1230
+ * [fields]="fields"
1231
+ * [(data)]="config"
1232
+ * (propertyChange)="onChanged($event)"
1233
+ * />
1234
+ * ```
1235
+ *
1236
+ * ### Grouped fields
1237
+ * ```ts
1238
+ * const fields: PropertyFieldDefinition<Config>[] = [
1239
+ * { key: 'name', label: 'Name', type: 'string', group: 'General' },
1240
+ * { key: 'color', label: 'Color', type: 'color', group: 'Appearance' },
1241
+ * ];
1242
+ * ```
1243
+ */
1244
+ declare class UIPropertySheet<T extends Record<string, unknown> = Record<string, unknown>> {
1245
+ /** Field definitions describing the properties to edit. */
1246
+ readonly fields: _angular_core.InputSignal<readonly PropertyFieldDefinition<T>[]>;
1247
+ /** Accessible label for the sheet. */
1248
+ readonly ariaLabel: _angular_core.InputSignal<string>;
1249
+ /** The data object being inspected/edited (two-way bindable). */
1250
+ readonly data: _angular_core.ModelSignal<T>;
1251
+ /** Emits when any property value changes. */
1252
+ readonly propertyChange: _angular_core.OutputEmitterRef<PropertyChangeEvent<T>>;
1253
+ /** @internal — fields organised into named groups. */
1254
+ protected readonly groups: _angular_core.Signal<readonly FieldGroup<T>[]>;
1255
+ /** @internal — read a field value from the data object. */
1256
+ protected getValue(key: string): unknown;
1257
+ /** @internal — update a field and emit. */
1258
+ protected onValueChange(key: string & keyof T, value: unknown): void;
1259
+ static ɵfac: _angular_core.ɵɵFactoryDeclaration<UIPropertySheet<any>, never>;
1260
+ static ɵcmp: _angular_core.ɵɵComponentDeclaration<UIPropertySheet<any>, "ui-property-sheet", never, { "fields": { "alias": "fields"; "required": true; "isSignal": true; }; "ariaLabel": { "alias": "ariaLabel"; "required": false; "isSignal": true; }; "data": { "alias": "data"; "required": false; "isSignal": true; }; }, { "data": "dataChange"; "propertyChange": "propertyChange"; }, never, never, true, [{ directive: typeof i1.UISurface; inputs: { "surfaceType": "surfaceType"; }; outputs: {}; }]>;
1261
+ }
1262
+
1263
+ /**
1264
+ * A single action that can be executed from the command palette.
1265
+ *
1266
+ * @typeParam C - Optional context type carried on the command.
1267
+ */
1268
+ interface CommandPaletteItem<C = unknown> {
1269
+ /** Unique identifier for this command. */
1270
+ readonly id: string;
1271
+ /** Display label shown in the palette list. */
1272
+ readonly label: string;
1273
+ /**
1274
+ * Optional group name. Commands with the same group are rendered
1275
+ * under a shared heading.
1276
+ */
1277
+ readonly group?: string;
1278
+ /**
1279
+ * Optional keyboard shortcut hint displayed on the right side
1280
+ * (e.g. `"Cmd+S"`, `"Ctrl+Shift+P"`). Purely cosmetic — the
1281
+ * palette does not bind these shortcuts.
1282
+ */
1283
+ readonly shortcut?: string;
1284
+ /** Optional SVG icon content (inner `<path>` string for a 24×24 grid). */
1285
+ readonly icon?: string;
1286
+ /** Whether this command is currently disabled. */
1287
+ readonly disabled?: boolean;
1288
+ /**
1289
+ * Optional keywords that improve search matching beyond the
1290
+ * label text.
1291
+ */
1292
+ readonly keywords?: readonly string[];
1293
+ /** Optional arbitrary context payload. */
1294
+ readonly context?: C;
1295
+ }
1296
+ /**
1297
+ * Event emitted when a command is executed from the palette.
1298
+ *
1299
+ * @typeParam C - Optional context type carried on the command.
1300
+ */
1301
+ interface CommandExecuteEvent<C = unknown> {
1302
+ /** The command that was executed. */
1303
+ readonly command: CommandPaletteItem<C>;
1304
+ /** ISO-8601 timestamp of when the command was executed. */
1305
+ readonly executedAt: string;
1306
+ }
1307
+ /**
1308
+ * Grouped commands used internally to organise items by group.
1309
+ * @internal
1310
+ */
1311
+ interface CommandGroup<C = unknown> {
1312
+ readonly name: string;
1313
+ readonly items: readonly CommandPaletteItem<C>[];
1314
+ }
1315
+
1316
+ /**
1317
+ * A keyboard-triggered command palette that provides quick access
1318
+ * to application actions through a searchable, grouped list.
1319
+ *
1320
+ * Open with `Cmd+K` / `Ctrl+K` (when {@link globalShortcut} is
1321
+ * enabled) or by setting the `open` model to `true`.
1322
+ *
1323
+ * ### Basic usage
1324
+ * ```html
1325
+ * <ui-command-palette
1326
+ * [commands]="commands"
1327
+ * [(open)]="paletteOpen"
1328
+ * (execute)="onExecute($event)"
1329
+ * />
1330
+ * ```
1331
+ *
1332
+ * ### With recent items
1333
+ * ```html
1334
+ * <ui-command-palette
1335
+ * [commands]="commands"
1336
+ * [maxRecent]="5"
1337
+ * [(open)]="paletteOpen"
1338
+ * (execute)="onExecute($event)"
1339
+ * />
1340
+ * ```
1341
+ */
1342
+ declare class UICommandPalette<C = unknown> {
1343
+ /** The full list of available commands. */
1344
+ readonly commands: _angular_core.InputSignal<readonly CommandPaletteItem<C>[]>;
1345
+ /** Placeholder text for the search input. */
1346
+ readonly placeholder: _angular_core.InputSignal<string>;
1347
+ /** Accessible label for the palette. */
1348
+ readonly ariaLabel: _angular_core.InputSignal<string>;
1349
+ /**
1350
+ * Whether the global `Cmd+K` / `Ctrl+K` keyboard shortcut is
1351
+ * active. Defaults to `true`.
1352
+ */
1353
+ readonly globalShortcut: _angular_core.InputSignal<boolean>;
1354
+ /**
1355
+ * Maximum number of recent commands to track. Set to `0` to
1356
+ * disable the recent-items section. Defaults to `5`.
1357
+ */
1358
+ readonly maxRecent: _angular_core.InputSignal<number>;
1359
+ /** Whether the palette is open (two-way bindable). */
1360
+ readonly open: _angular_core.ModelSignal<boolean>;
1361
+ /** Emitted when a command is executed. */
1362
+ readonly execute: _angular_core.OutputEmitterRef<CommandExecuteEvent<C>>;
1363
+ /** @internal */
1364
+ private readonly searchInputRef;
1365
+ /** @internal — current search query. */
1366
+ protected readonly query: _angular_core.WritableSignal<string>;
1367
+ /** @internal — index of the active (highlighted) item. */
1368
+ protected readonly activeIndex: _angular_core.WritableSignal<number>;
1369
+ /** @internal — IDs of recently executed commands (most recent first). */
1370
+ protected readonly recentIds: _angular_core.WritableSignal<readonly string[]>;
1371
+ /** @internal */
1372
+ protected readonly searchIcon: "<path d=\"m21 21-4.34-4.34\" /><circle cx=\"11\" cy=\"11\" r=\"8\" />";
1373
+ /** @internal */
1374
+ protected readonly returnIcon: "<path d=\"M20 4v7a4 4 0 0 1-4 4H4\" /><path d=\"m9 10-5 5 5 5\" />";
1375
+ /** @internal */
1376
+ protected readonly arrowUpIcon: "<path d=\"m5 12 7-7 7 7\" /><path d=\"M12 19V5\" />";
1377
+ /** @internal */
1378
+ protected readonly arrowDownIcon: "<path d=\"M12 5v14\" /><path d=\"m19 12-7 7-7-7\" />";
1379
+ /** @internal — filtered and grouped commands based on the query. */
1380
+ protected readonly filteredGroups: _angular_core.Signal<readonly CommandGroup<C>[]>;
1381
+ /** @internal — recent commands that are still in the full commands list. */
1382
+ protected readonly recentCommands: _angular_core.Signal<readonly CommandPaletteItem<C>[]>;
1383
+ /** @internal — whether to show the recent section. */
1384
+ protected readonly showRecent: _angular_core.Signal<boolean>;
1385
+ /** @internal — flat list of all currently visible items for keyboard nav. */
1386
+ protected readonly flatItems: _angular_core.Signal<readonly CommandPaletteItem<C>[]>;
1387
+ constructor();
1388
+ /** Programmatically open the palette. */
1389
+ show(): void;
1390
+ /** Programmatically close the palette. */
1391
+ close(): void;
1392
+ /** @internal */
1393
+ protected onSearchInput(event: Event): void;
1394
+ /** @internal */
1395
+ protected onKeydown(event: KeyboardEvent): void;
1396
+ /** @internal */
1397
+ protected onItemClick(item: CommandPaletteItem<C>): void;
1398
+ /** @internal */
1399
+ protected onBackdropClick(): void;
1400
+ /** @internal — compute the flat index for a group item. */
1401
+ protected getFlatIndex(groupIndex: number, itemIndex: number): number;
1402
+ /** @internal — compute the flat index for a recent item. */
1403
+ protected getRecentFlatIndex(index: number): number;
1404
+ private executeCommand;
1405
+ private addToRecent;
1406
+ private groupCommands;
1407
+ private scrollActiveIntoView;
1408
+ static ɵfac: _angular_core.ɵɵFactoryDeclaration<UICommandPalette<any>, never>;
1409
+ static ɵcmp: _angular_core.ɵɵComponentDeclaration<UICommandPalette<any>, "ui-command-palette", never, { "commands": { "alias": "commands"; "required": true; "isSignal": true; }; "placeholder": { "alias": "placeholder"; "required": false; "isSignal": true; }; "ariaLabel": { "alias": "ariaLabel"; "required": false; "isSignal": true; }; "globalShortcut": { "alias": "globalShortcut"; "required": false; "isSignal": true; }; "maxRecent": { "alias": "maxRecent"; "required": false; "isSignal": true; }; "open": { "alias": "open"; "required": false; "isSignal": true; }; }, { "open": "openChange"; "execute": "execute"; }, never, never, true, [{ directive: typeof i1.UISurface; inputs: { "surfaceType": "surfaceType"; }; outputs: {}; }]>;
1410
+ }
1411
+
1412
+ /**
1413
+ * View modes supported by the file browser contents panel.
1414
+ *
1415
+ * - `list` — Default row-per-entry list (original behaviour).
1416
+ * - `icons` — Grid of large icons with name labels.
1417
+ * - `detail` — Table with sortable columns (name, size, date, type).
1418
+ * - `tree` — Flat tree view showing nested hierarchy inline.
1419
+ * - `column` — NeXTSTEP / macOS Finder column view: one column per
1420
+ * traversed directory level with horizontal scrolling.
1421
+ */
1422
+ type FileBrowserViewMode = "list" | "icons" | "detail" | "tree" | "column";
1423
+ /**
1424
+ * Maps file extensions (without leading dot, lower-case) to SVG icon
1425
+ * strings. Consumers provide this via DI to customise the icon view.
1426
+ *
1427
+ * @example
1428
+ * ```ts
1429
+ * const MY_ICONS: FileIconRegistry = {
1430
+ * ts: UIIcons.Lucide.Files.FileCode,
1431
+ * json: UIIcons.Lucide.Files.FileJson,
1432
+ * md: UIIcons.Lucide.Files.FileText,
1433
+ * };
1434
+ *
1435
+ * providers: [{ provide: FILE_ICON_REGISTRY, useValue: MY_ICONS }]
1436
+ * ```
1437
+ */
1438
+ type FileIconRegistry = Record<string, string>;
1439
+ /**
1440
+ * DI token for the customisable file-icon registry.
1441
+ *
1442
+ * When provided, the icon view resolves icons by looking up the
1443
+ * file's extension (lower-case, without the leading dot) in the
1444
+ * registry. Falls back to the default file/folder icon.
1445
+ */
1446
+ declare const FILE_ICON_REGISTRY: InjectionToken<FileIconRegistry>;
1447
+ /**
1448
+ * A key-value metadata pair displayed in the details pane.
1449
+ */
1450
+ interface MetadataField {
1451
+ /** Human-readable label for the field. */
1452
+ readonly label: string;
1453
+ /** Displayable value. */
1454
+ readonly value: string | number | boolean;
1455
+ }
1456
+ /**
1457
+ * Callback that extracts displayable metadata fields from an entry.
1458
+ * Provided via the `[metadataProvider]` input on the file browser.
1459
+ */
1460
+ type MetadataProvider<M = unknown> = (entry: FileBrowserEntry<M>) => MetadataField[];
1461
+ /**
1462
+ * A single entry in a file browser — either a file or a directory.
1463
+ *
1464
+ * @typeParam M - Optional metadata type for extra fields
1465
+ * (size, modified date, permissions, etc.).
1466
+ */
1467
+ interface FileBrowserEntry<M = unknown> {
1468
+ /** Unique identifier for the entry. */
1469
+ readonly id: string;
1470
+ /** Display name of the file or directory. */
1471
+ readonly name: string;
1472
+ /** Whether this entry is a directory (`true`) or a file (`false`). */
1473
+ readonly isDirectory: boolean;
1474
+ /**
1475
+ * Optional SVG icon override. When omitted, the file browser
1476
+ * uses default folder/file icons.
1477
+ */
1478
+ readonly icon?: string;
1479
+ /** Optional arbitrary metadata (size, date, MIME type, etc.). */
1480
+ readonly meta?: M;
1481
+ }
1482
+ /**
1483
+ * Datasource contract for the file browser.
1484
+ *
1485
+ * Implementations may back this with an in-memory tree, a REST API,
1486
+ * IndexedDB, or any other storage mechanism. All methods may return
1487
+ * either a synchronous value or a `Promise`.
1488
+ *
1489
+ * @typeParam M - Optional metadata type carried on each entry.
1490
+ */
1491
+ interface FileBrowserDatasource<M = unknown> {
1492
+ /**
1493
+ * Returns the entries (files and directories) inside the given
1494
+ * directory node. For the root directory, `parent` is `null`.
1495
+ */
1496
+ getChildren(parent: FileBrowserEntry<M> | null): FileBrowserEntry<M>[] | Promise<FileBrowserEntry<M>[]>;
1497
+ /**
1498
+ * Returns `true` if the given entry is a directory that can
1499
+ * contain children (even if currently empty).
1500
+ */
1501
+ isDirectory(entry: FileBrowserEntry<M>): boolean;
1502
+ }
1503
+ /**
1504
+ * Event emitted when a file (non-directory) entry is activated
1505
+ * (double-clicked or pressed Enter).
1506
+ *
1507
+ * @typeParam M - Optional metadata type.
1508
+ */
1509
+ interface FileActivateEvent<M = unknown> {
1510
+ /** The activated file entry. */
1511
+ readonly entry: FileBrowserEntry<M>;
1512
+ /** ISO-8601 timestamp of the activation. */
1513
+ readonly activatedAt: string;
1514
+ }
1515
+ /**
1516
+ * Event emitted when the current directory changes (user navigates
1517
+ * into a folder).
1518
+ *
1519
+ * @typeParam M - Optional metadata type.
1520
+ */
1521
+ interface DirectoryChangeEvent<M = unknown> {
1522
+ /** The directory the user navigated to (`null` for root). */
1523
+ readonly directory: FileBrowserEntry<M> | null;
1524
+ /** The breadcrumb path from root to the current directory. */
1525
+ readonly path: readonly FileBrowserEntry<M>[];
1526
+ }
1527
+
1528
+ /**
1529
+ * Context provided to a custom entry template.
1530
+ *
1531
+ * @typeParam M - Metadata type carried on each entry.
1532
+ */
1533
+ interface EntryTemplateContext<M = unknown> {
1534
+ /** The entry (also available as the implicit `let-entry`). */
1535
+ $implicit: FileBrowserEntry<M>;
1536
+ }
1537
+ /**
1538
+ * A two-panel file browser block composing {@link UITreeView},
1539
+ * {@link UIBreadcrumb}, and a contents list.
1540
+ *
1541
+ * The tree sidebar shows the folder hierarchy. Selecting a folder
1542
+ * displays its contents (files and sub-folders) in the main panel.
1543
+ * A breadcrumb bar shows the current path and allows quick
1544
+ * navigation to ancestor folders.
1545
+ *
1546
+ * ### Basic usage
1547
+ * ```html
1548
+ * <ui-file-browser [datasource]="ds" (fileActivated)="open($event)" />
1549
+ * ```
1550
+ *
1551
+ * ### With custom entry template
1552
+ * ```html
1553
+ * <ui-file-browser [datasource]="ds">
1554
+ * <ng-template #entryTemplate let-entry>
1555
+ * <span>{{ entry.name }} — {{ entry.meta?.size }}</span>
1556
+ * </ng-template>
1557
+ * </ui-file-browser>
1558
+ * ```
1559
+ */
1560
+ declare class UIFileBrowser<M = unknown> implements AfterViewInit {
1561
+ /** The datasource providing the file/directory structure. */
1562
+ readonly datasource: _angular_core.InputSignal<FileBrowserDatasource<M>>;
1563
+ /** Accessible label for the file browser. */
1564
+ readonly ariaLabel: _angular_core.InputSignal<string>;
1565
+ /** Whether to show the sidebar tree panel. */
1566
+ readonly showSidebar: _angular_core.InputSignal<boolean>;
1567
+ /** Label for the root breadcrumb item. */
1568
+ readonly rootLabel: _angular_core.InputSignal<string>;
1569
+ /** Active view mode for the contents panel. */
1570
+ readonly viewMode: _angular_core.InputSignal<FileBrowserViewMode>;
1571
+ /** Whether to show the details pane for the selected entry. */
1572
+ readonly showDetails: _angular_core.InputSignal<boolean>;
1573
+ /**
1574
+ * Optional persistence key. When set, sidebar and details panel widths
1575
+ * are saved to and restored from storage.
1576
+ */
1577
+ readonly name: _angular_core.InputSignal<string | undefined>;
1578
+ /**
1579
+ * Callback that extracts metadata fields from a selected entry.
1580
+ * Required for the details pane to display meaningful data.
1581
+ */
1582
+ readonly metadataProvider: _angular_core.InputSignal<MetadataProvider<M> | null>;
1583
+ /** The currently selected entry (two-way bindable). */
1584
+ readonly selectedEntry: _angular_core.ModelSignal<FileBrowserEntry<M> | null>;
1585
+ /** Emitted when a file (non-directory) is activated (double-click / Enter). */
1586
+ readonly fileActivated: _angular_core.OutputEmitterRef<FileActivateEvent<M>>;
1587
+ /** Emitted when the current directory changes. */
1588
+ readonly directoryChange: _angular_core.OutputEmitterRef<DirectoryChangeEvent<M>>;
1589
+ /** Optional custom template for rendering each entry in the contents panel. */
1590
+ readonly entryTemplate: _angular_core.Signal<TemplateRef<EntryTemplateContext<M>> | undefined>;
1591
+ /** @internal */
1592
+ private readonly treeViewRef;
1593
+ /** @internal — the breadcrumb path from root to the current directory. */
1594
+ protected readonly path: _angular_core.WritableSignal<readonly FileBrowserEntry<M>[]>;
1595
+ /** @internal — the current directory (`null` = root). */
1596
+ protected readonly currentDirectory: _angular_core.WritableSignal<FileBrowserEntry<M> | null>;
1597
+ /** @internal — contents of the current directory. */
1598
+ protected readonly contents: _angular_core.WritableSignal<readonly FileBrowserEntry<M>[]>;
1599
+ /** @internal — tree selection for one-way binding. */
1600
+ protected readonly treeSelected: _angular_core.WritableSignal<readonly TreeNode<FileBrowserEntry<M>>[]>;
1601
+ /** @internal — tree datasource adapter. */
1602
+ protected readonly treeDatasource: _angular_core.Signal<ITreeDatasource<FileBrowserEntry<M>>>;
1603
+ /** @internal — display function for tree nodes. */
1604
+ protected readonly displayNodeLabel: (entry: FileBrowserEntry<M>) => string;
1605
+ /** @internal */
1606
+ protected readonly icons: {
1607
+ readonly folder: "<path d=\"M20 20a2 2 0 0 0 2-2V8a2 2 0 0 0-2-2h-7.9a2 2 0 0 1-1.69-.9L9.6 3.9A2 2 0 0 0 7.93 3H4a2 2 0 0 0-2 2v13a2 2 0 0 0 2 2Z\" />";
1608
+ readonly folderOpen: "<path d=\"m6 14 1.5-2.9A2 2 0 0 1 9.24 10H20a2 2 0 0 1 1.94 2.5l-1.54 6a2 2 0 0 1-1.95 1.5H4a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2h3.9a2 2 0 0 1 1.69.9l.81 1.2a2 2 0 0 0 1.67.9H18a2 2 0 0 1 2 2v2\" />";
1609
+ readonly file: "<path d=\"M6 22a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h8a2.4 2.4 0 0 1 1.704.706l3.588 3.588A2.4 2.4 0 0 1 20 8v12a2 2 0 0 1-2 2z\" /><path d=\"M14 2v5a1 1 0 0 0 1 1h5\" />";
1610
+ readonly fileText: "<path d=\"M6 22a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h8a2.4 2.4 0 0 1 1.704.706l3.588 3.588A2.4 2.4 0 0 1 20 8v12a2 2 0 0 1-2 2z\" /><path d=\"M14 2v5a1 1 0 0 0 1 1h5\" /><path d=\"M10 9H8\" /><path d=\"M16 13H8\" /><path d=\"M16 17H8\" />";
1611
+ readonly chevronRight: "<path d=\"m9 18 6-6-6-6\" />";
1612
+ };
1613
+ /** @internal — optional icon registry supplied via DI. */
1614
+ private readonly iconRegistry;
1615
+ /** @internal */
1616
+ private readonly elRef;
1617
+ /** @internal */
1618
+ private readonly injector;
1619
+ /** @internal */
1620
+ private readonly storage;
1621
+ /** @internal — current sidebar width in pixels. */
1622
+ protected readonly sidebarWidthPx: _angular_core.WritableSignal<number>;
1623
+ /** @internal — current details panel width in pixels. */
1624
+ protected readonly detailsWidthPx: _angular_core.WritableSignal<number>;
1625
+ /** @internal — which panel divider is actively being dragged. */
1626
+ protected readonly draggingPanel: _angular_core.WritableSignal<"details" | "sidebar" | null>;
1627
+ /** @internal — collapsed state for sidebar. */
1628
+ protected readonly sidebarCollapsed: _angular_core.WritableSignal<boolean>;
1629
+ /** @internal — collapsed state for details panel. */
1630
+ protected readonly detailsCollapsed: _angular_core.WritableSignal<boolean>;
1631
+ /** @internal — width before sidebar collapse for restore. */
1632
+ private preSidebarCollapseWidth;
1633
+ /** @internal — width before details collapse for restore. */
1634
+ private preDetailsCollapseWidth;
1635
+ /**
1636
+ * @internal — each element represents one column in the column view.
1637
+ * Index 0 = root, subsequent = each directory navigated into.
1638
+ */
1639
+ protected readonly columnPanes: _angular_core.WritableSignal<readonly {
1640
+ directory: FileBrowserEntry<M> | null;
1641
+ entries: readonly FileBrowserEntry<M>[];
1642
+ }[]>;
1643
+ /**
1644
+ * @internal — the entry selected in each column pane (by pane index).
1645
+ */
1646
+ protected readonly columnSelections: _angular_core.WritableSignal<readonly (FileBrowserEntry<M> | null)[]>;
1647
+ /** @internal — breadcrumb items built from the current path. */
1648
+ protected readonly breadcrumbItems: _angular_core.Signal<readonly BreadcrumbItem[]>;
1649
+ /** @internal — whether an entry is selected in the contents panel. */
1650
+ protected readonly hasSelection: _angular_core.Signal<boolean>;
1651
+ /** @internal — metadata fields for the selected entry (details pane). */
1652
+ protected readonly detailFields: _angular_core.Signal<readonly MetadataField[]>;
1653
+ constructor();
1654
+ ngAfterViewInit(): void;
1655
+ /** Navigate to the root directory. */
1656
+ navigateToRoot(): void;
1657
+ /** Navigate to a specific directory entry. */
1658
+ navigateToDirectory(entry: FileBrowserEntry<M>): void;
1659
+ /** @internal — starts pointer-based divider dragging for a panel. */
1660
+ protected onDividerPointerDown(event: PointerEvent, panel: "sidebar" | "details"): void;
1661
+ /** @internal — double-click on a divider toggles panel collapse. */
1662
+ protected onDividerDblClick(panel: "sidebar" | "details"): void;
1663
+ /** @internal */
1664
+ protected onBreadcrumbClick(item: BreadcrumbItem): void;
1665
+ /** @internal */
1666
+ protected onTreeNodeSelected(selected: readonly TreeNode<FileBrowserEntry<M>>[]): void;
1667
+ /** @internal */
1668
+ protected onTreeNodeActivated(node: TreeNode<FileBrowserEntry<M>>): void;
1669
+ /** @internal */
1670
+ protected onEntryClick(entry: FileBrowserEntry<M>): void;
1671
+ /** @internal */
1672
+ protected onEntryDblClick(entry: FileBrowserEntry<M>): void;
1673
+ /** @internal */
1674
+ protected onEntryKeydown(event: KeyboardEvent, entry: FileBrowserEntry<M>): void;
1675
+ /** @internal */
1676
+ protected getEntryIcon(entry: FileBrowserEntry<M>): string;
1677
+ /** @internal */
1678
+ protected isEntrySelected(entry: FileBrowserEntry<M>): boolean;
1679
+ private navigateTo;
1680
+ private loadContents;
1681
+ private createTreeDatasource;
1682
+ private buildPathToNode;
1683
+ private findNodePath;
1684
+ private expandTreeToPath;
1685
+ /** @internal — handle click on an entry inside a column pane. */
1686
+ protected onColumnEntryClick(paneIndex: number, entry: FileBrowserEntry<M>): Promise<void>;
1687
+ /** @internal — double-click in column view activates a file. */
1688
+ protected onColumnEntryDblClick(entry: FileBrowserEntry<M>): void;
1689
+ /** @internal — check if entry is selected in a column pane. */
1690
+ protected isColumnEntrySelected(paneIndex: number, entry: FileBrowserEntry<M>): boolean;
1691
+ private initColumnView;
1692
+ private extractExtension;
1693
+ /** @internal — scroll the rightmost column pane into view after DOM update. */
1694
+ private scrollLastColumnPaneIntoView;
1695
+ private static readonly STORAGE_PREFIX;
1696
+ private savePanelWidths;
1697
+ private loadPanelWidths;
1698
+ static ɵfac: _angular_core.ɵɵFactoryDeclaration<UIFileBrowser<any>, never>;
1699
+ static ɵcmp: _angular_core.ɵɵComponentDeclaration<UIFileBrowser<any>, "ui-file-browser", never, { "datasource": { "alias": "datasource"; "required": true; "isSignal": true; }; "ariaLabel": { "alias": "ariaLabel"; "required": false; "isSignal": true; }; "showSidebar": { "alias": "showSidebar"; "required": false; "isSignal": true; }; "rootLabel": { "alias": "rootLabel"; "required": false; "isSignal": true; }; "viewMode": { "alias": "viewMode"; "required": false; "isSignal": true; }; "showDetails": { "alias": "showDetails"; "required": false; "isSignal": true; }; "name": { "alias": "name"; "required": false; "isSignal": true; }; "metadataProvider": { "alias": "metadataProvider"; "required": false; "isSignal": true; }; "selectedEntry": { "alias": "selectedEntry"; "required": false; "isSignal": true; }; }, { "selectedEntry": "selectedEntryChange"; "fileActivated": "fileActivated"; "directoryChange": "directoryChange"; }, ["entryTemplate"], never, true, [{ directive: typeof i1.UISurface; inputs: { "surfaceType": "surfaceType"; }; outputs: {}; }]>;
1700
+ }
1701
+
1702
+ /** Visual style of a chat message. */
1703
+ type ChatMessageType = "text" | "rich-text" | "system";
1704
+ /** Mode for the message composer. */
1705
+ type ChatComposerMode = "text" | "rich-text";
1706
+ /**
1707
+ * A chat participant (user, bot, or system).
1708
+ */
1709
+ interface ChatParticipant {
1710
+ /** Unique identifier for this participant. */
1711
+ readonly id: string;
1712
+ /** Display name. */
1713
+ readonly name: string;
1714
+ /** Optional avatar image URL. */
1715
+ readonly avatarSrc?: string;
1716
+ /** Optional email for Gravatar lookup. */
1717
+ readonly avatarEmail?: string;
1718
+ }
1719
+ /**
1720
+ * A single chat message.
1721
+ *
1722
+ * @typeParam M — Extra metadata attached to each message.
1723
+ */
1724
+ interface ChatMessage<M = unknown> {
1725
+ /** Unique message identifier. */
1726
+ readonly id: string;
1727
+ /** Message content (plain text or HTML depending on {@link type}). */
1728
+ readonly content: string;
1729
+ /** When the message was sent. */
1730
+ readonly timestamp: Date;
1731
+ /** Who sent the message. */
1732
+ readonly sender: ChatParticipant;
1733
+ /** Content interpretation. Defaults to `'text'`. */
1734
+ readonly type?: ChatMessageType;
1735
+ /** Optional metadata. */
1736
+ readonly meta?: M;
1737
+ }
1738
+ /**
1739
+ * Emitted when the user sends a message via the composer.
1740
+ */
1741
+ interface MessageSendEvent {
1742
+ /** The composed message content. */
1743
+ readonly content: string;
1744
+ }
1745
+ /**
1746
+ * A group of messages under a date label.
1747
+ * @internal
1748
+ */
1749
+ interface MessageDateGroup<M = unknown> {
1750
+ /** ISO date string key. */
1751
+ readonly date: string;
1752
+ /** Human-readable label (e.g. "Today", "Yesterday", or a date). */
1753
+ readonly label: string;
1754
+ /** Messages in chronological order. */
1755
+ readonly messages: readonly ChatMessage<M>[];
1756
+ }
1757
+ /**
1758
+ * Template context for custom message rendering via
1759
+ * `#messageTemplate`.
1760
+ *
1761
+ * @typeParam M — Extra metadata type.
1762
+ */
1763
+ interface MessageTemplateContext<M = unknown> {
1764
+ /** The message (also available as `$implicit`). */
1765
+ readonly $implicit: ChatMessage<M>;
1766
+ /** The message. */
1767
+ readonly message: ChatMessage<M>;
1768
+ /** Whether this message was sent by the current user. */
1769
+ readonly isMine: boolean;
1770
+ }
1771
+
1772
+ /**
1773
+ * A chat / messaging view composing UIAvatar, UIRichTextEditor,
1774
+ * and a scrollable message list with a composer bar.
1775
+ *
1776
+ * Messages are supplied via the `messages` input. The component
1777
+ * groups them by date and renders each with sender avatar, bubble,
1778
+ * and timestamp. The current user's messages are right-aligned.
1779
+ *
1780
+ * The composer bar supports both plain-text (`textarea`) and
1781
+ * rich-text (`UIRichTextEditor`) modes via the `composerMode`
1782
+ * input.
1783
+ *
1784
+ * Custom message templates can be projected using a
1785
+ * `#messageTemplate` content child.
1786
+ *
1787
+ * ### Basic usage
1788
+ * ```html
1789
+ * <ui-chat-view
1790
+ * [messages]="messages"
1791
+ * [currentUser]="me"
1792
+ * (messageSend)="onSend($event)"
1793
+ * />
1794
+ * ```
1795
+ *
1796
+ * ### Rich-text composer
1797
+ * ```html
1798
+ * <ui-chat-view
1799
+ * [messages]="messages"
1800
+ * [currentUser]="me"
1801
+ * composerMode="rich-text"
1802
+ * (messageSend)="onSend($event)"
1803
+ * />
1804
+ * ```
1805
+ */
1806
+ declare class UIChatView<M = unknown> implements AfterViewInit {
1807
+ /** The list of messages to display. */
1808
+ readonly messages: _angular_core.InputSignal<readonly ChatMessage<M>[]>;
1809
+ /** The current user (their messages are right-aligned). */
1810
+ readonly currentUser: _angular_core.InputSignal<ChatParticipant>;
1811
+ /** Composer input mode. */
1812
+ readonly composerMode: _angular_core.InputSignal<ChatComposerMode>;
1813
+ /** Placeholder text for the composer. */
1814
+ readonly placeholder: _angular_core.InputSignal<string>;
1815
+ /** Accessible label for the chat view. */
1816
+ readonly ariaLabel: _angular_core.InputSignal<string>;
1817
+ /**
1818
+ * Optional custom template for rendering individual messages.
1819
+ * Receives a {@link MessageTemplateContext}.
1820
+ */
1821
+ readonly messageTemplate: _angular_core.Signal<TemplateRef<MessageTemplateContext<M>> | undefined>;
1822
+ /** Emitted when the user sends a message. */
1823
+ readonly messageSend: _angular_core.OutputEmitterRef<MessageSendEvent>;
1824
+ /** @internal */
1825
+ private readonly messageListRef;
1826
+ /** @internal */
1827
+ private readonly composerInputRef;
1828
+ /** @internal — current text in the composer. */
1829
+ protected readonly composerValue: _angular_core.WritableSignal<string>;
1830
+ /** @internal */
1831
+ protected readonly sendIcon: "<path d=\"M3.714 3.048a.498.498 0 0 0-.683.627l2.843 7.627a2 2 0 0 1 0 1.396l-2.842 7.627a.498.498 0 0 0 .682.627l18-8.5a.5.5 0 0 0 0-.904z\" /><path d=\"M6 12h16\" />";
1832
+ /** @internal — messages grouped by date. */
1833
+ protected readonly groupedMessages: _angular_core.Signal<readonly MessageDateGroup<M>[]>;
1834
+ /** @internal — whether the send button should be enabled. */
1835
+ protected readonly canSend: _angular_core.Signal<boolean>;
1836
+ constructor();
1837
+ ngAfterViewInit(): void;
1838
+ /** Scroll the message list to the bottom. */
1839
+ scrollToBottom(): void;
1840
+ /** @internal — determine if a message was sent by the current user. */
1841
+ protected isMine(message: ChatMessage<M>): boolean;
1842
+ /** @internal — send the composed message. */
1843
+ protected send(): void;
1844
+ /** @internal — handle Enter key in the text composer. */
1845
+ protected onComposerKeydown(event: KeyboardEvent): void;
1846
+ /** @internal — handle input events on the textarea. */
1847
+ protected onComposerInput(event: Event): void;
1848
+ /** Group messages by date, producing human-readable labels. */
1849
+ private groupByDate;
1850
+ /** Convert a Date to a YYYY-MM-DD key. */
1851
+ private toDateKey;
1852
+ static ɵfac: _angular_core.ɵɵFactoryDeclaration<UIChatView<any>, never>;
1853
+ static ɵcmp: _angular_core.ɵɵComponentDeclaration<UIChatView<any>, "ui-chat-view", never, { "messages": { "alias": "messages"; "required": false; "isSignal": true; }; "currentUser": { "alias": "currentUser"; "required": true; "isSignal": true; }; "composerMode": { "alias": "composerMode"; "required": false; "isSignal": true; }; "placeholder": { "alias": "placeholder"; "required": false; "isSignal": true; }; "ariaLabel": { "alias": "ariaLabel"; "required": false; "isSignal": true; }; }, { "messageSend": "messageSend"; }, ["messageTemplate"], never, true, [{ directive: typeof i1.UISurface; inputs: { "surfaceType": "surfaceType"; }; outputs: {}; }]>;
1854
+ }
1855
+
1856
+ /**
1857
+ * A single chat message bubble with optional avatar, sender name,
1858
+ * content, and timestamp.
1859
+ *
1860
+ * The bubble adjusts its visual alignment and styling based on the
1861
+ * `isMine` input — right-aligned with accent colour for the
1862
+ * current user, left-aligned with a neutral surface for others.
1863
+ *
1864
+ * ### Usage
1865
+ * ```html
1866
+ * <ui-message-bubble [message]="msg" [isMine]="false" />
1867
+ * ```
1868
+ */
1869
+ declare class UIMessageBubble<M = unknown> {
1870
+ /** The message to render. */
1871
+ readonly message: _angular_core.InputSignal<ChatMessage<M>>;
1872
+ /** Whether this message belongs to the current user. */
1873
+ readonly isMine: _angular_core.InputSignal<boolean>;
1874
+ /** @internal — whether content should be rendered as HTML. */
1875
+ protected readonly isRichText: _angular_core.Signal<boolean>;
1876
+ /** @internal — formatted short time string. */
1877
+ protected readonly timeString: _angular_core.Signal<string>;
1878
+ static ɵfac: _angular_core.ɵɵFactoryDeclaration<UIMessageBubble<any>, never>;
1879
+ static ɵcmp: _angular_core.ɵɵComponentDeclaration<UIMessageBubble<any>, "ui-message-bubble", never, { "message": { "alias": "message"; "required": true; "isSignal": true; }; "isMine": { "alias": "isMine"; "required": false; "isSignal": true; }; }, {}, never, never, true, never>;
1880
+ }
1881
+
1882
+ /**
1883
+ * A single step inside a {@link UIWizard}.
1884
+ *
1885
+ * Wrap each piece of wizard content in this component and project
1886
+ * it into `<ui-wizard>`.
1887
+ *
1888
+ * ### Usage
1889
+ * ```html
1890
+ * <ui-wizard>
1891
+ * <ui-wizard-step label="Account">…</ui-wizard-step>
1892
+ * <ui-wizard-step label="Profile">…</ui-wizard-step>
1893
+ * <ui-wizard-step label="Confirm">…</ui-wizard-step>
1894
+ * </ui-wizard>
1895
+ * ```
1896
+ */
1897
+ declare class UIWizardStep {
1898
+ /** Label shown in the step indicator. */
1899
+ readonly label: _angular_core.InputSignal<string>;
1900
+ /** Whether this step is optional (shown as hint text). */
1901
+ readonly optional: _angular_core.InputSignal<boolean>;
1902
+ /**
1903
+ * Whether the user can advance past this step. Bind a
1904
+ * signal expression to create a validation gate.
1905
+ *
1906
+ * @default true
1907
+ */
1908
+ readonly canAdvance: _angular_core.InputSignal<boolean>;
1909
+ /** @internal — template holding the step's projected content. */
1910
+ readonly contentTemplate: _angular_core.Signal<TemplateRef<unknown>>;
1911
+ static ɵfac: _angular_core.ɵɵFactoryDeclaration<UIWizardStep, never>;
1912
+ static ɵcmp: _angular_core.ɵɵComponentDeclaration<UIWizardStep, "ui-wizard-step", never, { "label": { "alias": "label"; "required": true; "isSignal": true; }; "optional": { "alias": "optional"; "required": false; "isSignal": true; }; "canAdvance": { "alias": "canAdvance"; "required": false; "isSignal": true; }; }, {}, never, ["*"], true, [{ directive: typeof i1.UISurface; inputs: { "surfaceType": "surfaceType"; }; outputs: {}; }]>;
1913
+ }
1914
+
1915
+ /**
1916
+ * Emitted when the active step changes.
1917
+ */
1918
+ interface StepChangeEvent {
1919
+ /** Index of the step being left. */
1920
+ readonly previousIndex: number;
1921
+ /** Index of the step being entered. */
1922
+ readonly currentIndex: number;
1923
+ }
1924
+
1925
+ /**
1926
+ * A multi-step workflow shell with a step indicator, navigation
1927
+ * buttons, and optional validation gates.
1928
+ *
1929
+ * Steps are defined by projecting `<ui-wizard-step>` children.
1930
+ * The wizard discovers them via content queries and renders only
1931
+ * the active step.
1932
+ *
1933
+ * ### Basic usage
1934
+ * ```html
1935
+ * <ui-wizard (complete)="onFinish()">
1936
+ * <ui-wizard-step label="Account">…</ui-wizard-step>
1937
+ * <ui-wizard-step label="Profile">…</ui-wizard-step>
1938
+ * <ui-wizard-step label="Confirm">…</ui-wizard-step>
1939
+ * </ui-wizard>
1940
+ * ```
1941
+ *
1942
+ * ### With validation gates
1943
+ * ```html
1944
+ * <ui-wizard linear>
1945
+ * <ui-wizard-step label="Details" [canAdvance]="formValid()">
1946
+ * …
1947
+ * </ui-wizard-step>
1948
+ * <ui-wizard-step label="Review">…</ui-wizard-step>
1949
+ * </ui-wizard>
1950
+ * ```
1951
+ */
1952
+ declare class UIWizard {
1953
+ /**
1954
+ * When `true`, the user must complete steps in order and
1955
+ * cannot click ahead on the step indicator.
1956
+ */
1957
+ readonly linear: _angular_core.InputSignal<boolean>;
1958
+ /** Whether to show the step indicator bar. */
1959
+ readonly showStepIndicator: _angular_core.InputSignal<boolean>;
1960
+ /** Label for the Back button. */
1961
+ readonly backLabel: _angular_core.InputSignal<string>;
1962
+ /** Label for the Next button. */
1963
+ readonly nextLabel: _angular_core.InputSignal<string>;
1964
+ /** Label for the Finish button (shown on the last step). */
1965
+ readonly finishLabel: _angular_core.InputSignal<string>;
1966
+ /** Accessible label for the wizard. */
1967
+ readonly ariaLabel: _angular_core.InputSignal<string>;
1968
+ /** Zero-based index of the active step (two-way bindable). */
1969
+ readonly activeIndex: _angular_core.ModelSignal<number>;
1970
+ /** @internal — discovered wizard steps. */
1971
+ readonly steps: _angular_core.Signal<readonly UIWizardStep[]>;
1972
+ /** Emitted when the active step changes. */
1973
+ readonly stepChange: _angular_core.OutputEmitterRef<StepChangeEvent>;
1974
+ /** Emitted when the user clicks Finish on the last step. */
1975
+ readonly complete: _angular_core.OutputEmitterRef<void>;
1976
+ /** @internal */
1977
+ protected readonly checkIcon: "<path d=\"M20 6 9 17l-5-5\" />";
1978
+ /** @internal — the currently active step. */
1979
+ protected readonly activeStep: _angular_core.Signal<UIWizardStep | undefined>;
1980
+ /** @internal */
1981
+ protected readonly isFirstStep: _angular_core.Signal<boolean>;
1982
+ /** @internal */
1983
+ protected readonly isLastStep: _angular_core.Signal<boolean>;
1984
+ /** @internal — whether the current step allows advancing. */
1985
+ protected readonly canGoNext: _angular_core.Signal<boolean>;
1986
+ /** Advance to the next step (respects validation). */
1987
+ next(): void;
1988
+ /** Go back to the previous step. */
1989
+ previous(): void;
1990
+ /** Navigate to a specific step by index. */
1991
+ goToStep(index: number): void;
1992
+ /** Complete the wizard (only works on the last step). */
1993
+ finish(): void;
1994
+ /** @internal — handle step indicator click. */
1995
+ protected onStepClick(index: number): void;
1996
+ /** @internal — whether a step indicator is clickable. */
1997
+ protected isStepClickable(index: number): boolean;
1998
+ static ɵfac: _angular_core.ɵɵFactoryDeclaration<UIWizard, never>;
1999
+ static ɵcmp: _angular_core.ɵɵComponentDeclaration<UIWizard, "ui-wizard", never, { "linear": { "alias": "linear"; "required": false; "isSignal": true; }; "showStepIndicator": { "alias": "showStepIndicator"; "required": false; "isSignal": true; }; "backLabel": { "alias": "backLabel"; "required": false; "isSignal": true; }; "nextLabel": { "alias": "nextLabel"; "required": false; "isSignal": true; }; "finishLabel": { "alias": "finishLabel"; "required": false; "isSignal": true; }; "ariaLabel": { "alias": "ariaLabel"; "required": false; "isSignal": true; }; "activeIndex": { "alias": "activeIndex"; "required": false; "isSignal": true; }; }, { "activeIndex": "activeIndexChange"; "stepChange": "stepChange"; "complete": "complete"; }, ["steps"], never, true, [{ directive: typeof i1.UISurface; inputs: { "surfaceType": "surfaceType"; }; outputs: {}; }]>;
2000
+ }
2001
+
2002
+ /**
2003
+ * Represents a column (lane) in the kanban board.
2004
+ *
2005
+ * @template T The shape of the card payload.
2006
+ */
2007
+ interface KanbanColumn<T = unknown> {
2008
+ /** Unique column identifier. */
2009
+ readonly id: string;
2010
+ /** Display title for the column header. */
2011
+ readonly title: string;
2012
+ /** Ordered list of cards in this column (mutated during drag operations). */
2013
+ cards: KanbanCard<T>[];
2014
+ /** Optional accent colour rendered as a top-border stripe. */
2015
+ readonly color?: string;
2016
+ }
2017
+ /**
2018
+ * Represents a single card on the kanban board.
2019
+ *
2020
+ * @template T The shape of the card payload.
2021
+ */
2022
+ interface KanbanCard<T = unknown> {
2023
+ /** Unique card identifier. */
2024
+ readonly id: string;
2025
+ /** Consumer-supplied payload rendered via the card template. */
2026
+ readonly data: T;
2027
+ }
2028
+ /**
2029
+ * Emitted when a card is moved between columns or reordered
2030
+ * within the same column.
2031
+ *
2032
+ * @template T The shape of the card payload.
2033
+ */
2034
+ interface KanbanCardMoveEvent<T = unknown> {
2035
+ /** The card that was moved. */
2036
+ readonly card: KanbanCard<T>;
2037
+ /** Column the card came from. */
2038
+ readonly previousColumnId: string;
2039
+ /** Column the card was dropped into. */
2040
+ readonly currentColumnId: string;
2041
+ /** Previous index within the source column. */
2042
+ readonly previousIndex: number;
2043
+ /** New index within the target column. */
2044
+ readonly currentIndex: number;
2045
+ }
2046
+ /**
2047
+ * Template context exposed to the projected card template.
2048
+ *
2049
+ * @template T The shape of the card payload.
2050
+ */
2051
+ interface KanbanCardContext<T = unknown> {
2052
+ /** The card instance (also available via `let-card`). */
2053
+ readonly $implicit: KanbanCard<T>;
2054
+ /** The column the card belongs to. */
2055
+ readonly column: KanbanColumn<T>;
2056
+ }
2057
+
2058
+ /**
2059
+ * Column-based kanban board with drag-and-drop card reordering.
2060
+ *
2061
+ * Cards can be moved within a column (reorder) or across columns
2062
+ * (transfer). Columns and cards are provided via a two-way `columns`
2063
+ * model. Project an `<ng-template>` to customise card rendering.
2064
+ *
2065
+ * ### Basic usage
2066
+ * ```html
2067
+ * <ui-kanban-board [(columns)]="columns">
2068
+ * <ng-template let-card let-column="column">
2069
+ * <h4>{{ card.data.title }}</h4>
2070
+ * <p>{{ card.data.description }}</p>
2071
+ * </ng-template>
2072
+ * </ui-kanban-board>
2073
+ * ```
2074
+ */
2075
+ declare class UIKanbanBoard<T = unknown> {
2076
+ /** Column data (two-way bindable). Mutated in-place during drag operations. */
2077
+ readonly columns: _angular_core.ModelSignal<KanbanColumn<T>[]>;
2078
+ /** Accessible label for the board region. */
2079
+ readonly ariaLabel: _angular_core.InputSignal<string>;
2080
+ /** Optional projected template for card rendering. */
2081
+ readonly cardTemplate: _angular_core.Signal<TemplateRef<KanbanCardContext<T>> | undefined>;
2082
+ /** Emitted after a card is moved (reorder or transfer). */
2083
+ readonly cardMoved: _angular_core.OutputEmitterRef<KanbanCardMoveEvent<T>>;
2084
+ /** Emitted when a card is clicked. */
2085
+ readonly cardClicked: _angular_core.OutputEmitterRef<KanbanCard<T>>;
2086
+ /** @internal — handle CDK drop event. */
2087
+ protected onDrop(event: CdkDragDrop<KanbanCard<T>[]>): void;
2088
+ /** @internal — handle card click. */
2089
+ protected onCardClick(card: KanbanCard<T>): void;
2090
+ static ɵfac: _angular_core.ɵɵFactoryDeclaration<UIKanbanBoard<any>, never>;
2091
+ static ɵcmp: _angular_core.ɵɵComponentDeclaration<UIKanbanBoard<any>, "ui-kanban-board", never, { "columns": { "alias": "columns"; "required": true; "isSignal": true; }; "ariaLabel": { "alias": "ariaLabel"; "required": false; "isSignal": true; }; }, { "columns": "columnsChange"; "cardMoved": "cardMoved"; "cardClicked": "cardClicked"; }, ["cardTemplate"], never, true, [{ directive: typeof i1.UISurface; inputs: { "surfaceType": "surfaceType"; }; outputs: {}; }]>;
2092
+ }
2093
+
2094
+ /** Variant for the confirm dialog's primary action button. */
2095
+ type ConfirmVariant = "primary" | "danger" | "warning";
2096
+ /** Options for {@link CommonDialogService.alert}. */
2097
+ interface AlertOptions {
2098
+ /** Dialog title. */
2099
+ readonly title: string;
2100
+ /** Message body (plain text or a single paragraph). */
2101
+ readonly message: string;
2102
+ /** Label for the dismiss button. Defaults to `"OK"`. */
2103
+ readonly buttonLabel?: string;
2104
+ /** Accessible label for the dialog element. */
2105
+ readonly ariaLabel?: string;
2106
+ }
2107
+ /** Options for {@link CommonDialogService.confirm}. */
2108
+ interface ConfirmOptions {
2109
+ /** Dialog title. */
2110
+ readonly title: string;
2111
+ /** Message body. */
2112
+ readonly message: string;
2113
+ /** Label for the confirm button. Defaults to `"OK"`. */
2114
+ readonly confirmLabel?: string;
2115
+ /** Label for the cancel button. Defaults to `"Cancel"`. */
2116
+ readonly cancelLabel?: string;
2117
+ /** Visual variant of the confirm button. Defaults to `"primary"`. */
2118
+ readonly variant?: ConfirmVariant;
2119
+ /** Accessible label for the dialog element. */
2120
+ readonly ariaLabel?: string;
2121
+ }
2122
+ /** Options for {@link CommonDialogService.prompt}. */
2123
+ interface PromptOptions {
2124
+ /** Dialog title. */
2125
+ readonly title: string;
2126
+ /** Message body displayed above the input. */
2127
+ readonly message: string;
2128
+ /** Default value pre-filled in the input. */
2129
+ readonly defaultValue?: string;
2130
+ /** Placeholder text for the input. */
2131
+ readonly placeholder?: string;
2132
+ /** Label for the OK button. Defaults to `"OK"`. */
2133
+ readonly okLabel?: string;
2134
+ /** Label for the cancel button. Defaults to `"Cancel"`. */
2135
+ readonly cancelLabel?: string;
2136
+ /** Accessible label for the dialog element. */
2137
+ readonly ariaLabel?: string;
2138
+ }
2139
+ /** Options for {@link CommonDialogService.openFile}. */
2140
+ interface OpenFileOptions<M = unknown> {
2141
+ /** Datasource powering the file browser. */
2142
+ readonly datasource: FileBrowserDatasource<M>;
2143
+ /** Dialog title. Defaults to `"Open File"`. */
2144
+ readonly title?: string;
2145
+ /** Whether the user may select multiple files. */
2146
+ readonly allowMultiple?: boolean;
2147
+ /** Label for the open button. Defaults to `"Open"`. */
2148
+ readonly openLabel?: string;
2149
+ /** Accessible label for the dialog element. */
2150
+ readonly ariaLabel?: string;
2151
+ }
2152
+ /** Result returned by {@link CommonDialogService.openFile}. */
2153
+ interface OpenFileResult<M = unknown> {
2154
+ /** The selected file(s). */
2155
+ readonly files: readonly FileBrowserEntry<M>[];
2156
+ }
2157
+ /** Options for {@link CommonDialogService.saveFile}. */
2158
+ interface SaveFileOptions<M = unknown> {
2159
+ /** Datasource powering the file browser. */
2160
+ readonly datasource: FileBrowserDatasource<M>;
2161
+ /** Dialog title. Defaults to `"Save File"`. */
2162
+ readonly title?: string;
2163
+ /** Pre-filled file name. */
2164
+ readonly defaultName?: string;
2165
+ /** Label for the save button. Defaults to `"Save"`. */
2166
+ readonly saveLabel?: string;
2167
+ /** Accessible label for the dialog element. */
2168
+ readonly ariaLabel?: string;
2169
+ }
2170
+ /** Result returned by {@link CommonDialogService.saveFile}. */
2171
+ interface SaveFileResult<M = unknown> {
2172
+ /** The directory path the user is currently browsing. */
2173
+ readonly directory: FileBrowserEntry<M> | null;
2174
+ /** The file name entered by the user. */
2175
+ readonly name: string;
2176
+ }
2177
+ /** Options for {@link CommonDialogService.about}. */
2178
+ interface AboutOptions {
2179
+ /** Application name. */
2180
+ readonly appName: string;
2181
+ /** Version string (e.g. `"1.2.3"`). */
2182
+ readonly version?: string;
2183
+ /** Short description or tagline. */
2184
+ readonly description?: string;
2185
+ /** URL or data-URI for a logo image. */
2186
+ readonly logoUrl?: string;
2187
+ /** Copyright notice (e.g. `"© 2026 Acme Corp"`). */
2188
+ readonly copyright?: string;
2189
+ /** Credits / acknowledgements — rendered as a list. */
2190
+ readonly credits?: readonly string[];
2191
+ /** Accessible label for the dialog element. */
2192
+ readonly ariaLabel?: string;
2193
+ }
2194
+
2195
+ /**
2196
+ * Service for showing common application dialogs — alert, confirm,
2197
+ * prompt, open-file, save-file, and about.
2198
+ *
2199
+ * Each method opens a modal dialog and returns a `Promise` that
2200
+ * resolves when the user closes it. The service delegates to
2201
+ * {@link ModalService} for the underlying dialog lifecycle.
2202
+ *
2203
+ * @example
2204
+ * ```ts
2205
+ * const confirmed = await this.dialogs.confirm({
2206
+ * title: 'Delete item?',
2207
+ * message: 'This action cannot be undone.',
2208
+ * variant: 'danger',
2209
+ * });
2210
+ *
2211
+ * if (confirmed) { ... }
2212
+ * ```
2213
+ */
2214
+ declare class CommonDialogService {
2215
+ private readonly modal;
2216
+ /**
2217
+ * Show a simple informational alert with a dismiss button.
2218
+ *
2219
+ * @returns Resolves when the user dismisses the dialog.
2220
+ */
2221
+ alert(options: AlertOptions): Promise<void>;
2222
+ /**
2223
+ * Show a confirmation dialog with confirm and cancel buttons.
2224
+ *
2225
+ * @returns `true` if the user confirmed, `false` otherwise.
2226
+ */
2227
+ confirm(options: ConfirmOptions): Promise<boolean>;
2228
+ /**
2229
+ * Show a prompt dialog with a text input.
2230
+ *
2231
+ * @returns The entered string, or `null` if cancelled.
2232
+ */
2233
+ prompt(options: PromptOptions): Promise<string | null>;
2234
+ /**
2235
+ * Show an open-file dialog powered by {@link UIFileBrowser}.
2236
+ *
2237
+ * @returns The selected file(s), or `null` if cancelled.
2238
+ */
2239
+ openFile<M = unknown>(options: OpenFileOptions<M>): Promise<OpenFileResult<M> | null>;
2240
+ /**
2241
+ * Show a save-file dialog powered by {@link UIFileBrowser} with a
2242
+ * file-name input.
2243
+ *
2244
+ * @returns The directory and file name, or `null` if cancelled.
2245
+ */
2246
+ saveFile<M = unknown>(options: SaveFileOptions<M>): Promise<SaveFileResult<M> | null>;
2247
+ /**
2248
+ * Show an "About" dialog with application information.
2249
+ *
2250
+ * @returns Resolves when the user closes the dialog.
2251
+ */
2252
+ about(options: AboutOptions): Promise<void>;
2253
+ static ɵfac: _angular_core.ɵɵFactoryDeclaration<CommonDialogService, never>;
2254
+ static ɵprov: _angular_core.ɵɵInjectableDeclaration<CommonDialogService>;
2255
+ }
2256
+
2257
+ /**
2258
+ * Content component for a simple alert dialog.
2259
+ *
2260
+ * Displayed by {@link CommonDialogService.alert}. Shows a title,
2261
+ * message, and a single dismiss button.
2262
+ *
2263
+ * @internal — not intended for direct use; use the service instead.
2264
+ */
2265
+ declare class UIAlertDialog {
2266
+ readonly title: _angular_core.InputSignal<string>;
2267
+ readonly message: _angular_core.InputSignal<string>;
2268
+ readonly buttonLabel: _angular_core.InputSignal<string>;
2269
+ private readonly modalRef;
2270
+ dismiss(): void;
2271
+ static ɵfac: _angular_core.ɵɵFactoryDeclaration<UIAlertDialog, never>;
2272
+ static ɵcmp: _angular_core.ɵɵComponentDeclaration<UIAlertDialog, "ui-alert-dialog", never, { "title": { "alias": "title"; "required": false; "isSignal": true; }; "message": { "alias": "message"; "required": false; "isSignal": true; }; "buttonLabel": { "alias": "buttonLabel"; "required": false; "isSignal": true; }; }, {}, never, never, true, [{ directive: typeof i1.UISurface; inputs: { "surfaceType": "surfaceType"; }; outputs: {}; }]>;
2273
+ }
2274
+
2275
+ /**
2276
+ * Content component for a confirm dialog.
2277
+ *
2278
+ * Displayed by {@link CommonDialogService.confirm}. Shows a title,
2279
+ * message, and confirm / cancel buttons. Resolves to `true` (confirm)
2280
+ * or `false` (cancel / dismiss).
2281
+ *
2282
+ * @internal — not intended for direct use; use the service instead.
2283
+ */
2284
+ declare class UIConfirmDialog {
2285
+ readonly title: _angular_core.InputSignal<string>;
2286
+ readonly message: _angular_core.InputSignal<string>;
2287
+ readonly confirmLabel: _angular_core.InputSignal<string>;
2288
+ readonly cancelLabel: _angular_core.InputSignal<string>;
2289
+ readonly variant: _angular_core.InputSignal<ConfirmVariant>;
2290
+ private readonly modalRef;
2291
+ confirm(): void;
2292
+ cancel(): void;
2293
+ static ɵfac: _angular_core.ɵɵFactoryDeclaration<UIConfirmDialog, never>;
2294
+ static ɵcmp: _angular_core.ɵɵComponentDeclaration<UIConfirmDialog, "ui-confirm-dialog", never, { "title": { "alias": "title"; "required": false; "isSignal": true; }; "message": { "alias": "message"; "required": false; "isSignal": true; }; "confirmLabel": { "alias": "confirmLabel"; "required": false; "isSignal": true; }; "cancelLabel": { "alias": "cancelLabel"; "required": false; "isSignal": true; }; "variant": { "alias": "variant"; "required": false; "isSignal": true; }; }, {}, never, never, true, [{ directive: typeof i1.UISurface; inputs: { "surfaceType": "surfaceType"; }; outputs: {}; }]>;
2295
+ }
2296
+
2297
+ /**
2298
+ * Content component for a prompt dialog.
2299
+ *
2300
+ * Displayed by {@link CommonDialogService.prompt}. Shows a title,
2301
+ * message, a text input, and OK / Cancel buttons. Resolves to the
2302
+ * entered string or `null` if cancelled.
2303
+ *
2304
+ * @internal — not intended for direct use; use the service instead.
2305
+ */
2306
+ declare class UIPromptDialog implements OnInit {
2307
+ readonly title: _angular_core.InputSignal<string>;
2308
+ readonly message: _angular_core.InputSignal<string>;
2309
+ readonly defaultValue: _angular_core.InputSignal<string>;
2310
+ readonly placeholder: _angular_core.InputSignal<string>;
2311
+ readonly okLabel: _angular_core.InputSignal<string>;
2312
+ readonly cancelLabel: _angular_core.InputSignal<string>;
2313
+ protected readonly inputValue: _angular_core.WritableSignal<string>;
2314
+ private readonly modalRef;
2315
+ ngOnInit(): void;
2316
+ ok(): void;
2317
+ cancel(): void;
2318
+ static ɵfac: _angular_core.ɵɵFactoryDeclaration<UIPromptDialog, never>;
2319
+ static ɵcmp: _angular_core.ɵɵComponentDeclaration<UIPromptDialog, "ui-prompt-dialog", never, { "title": { "alias": "title"; "required": false; "isSignal": true; }; "message": { "alias": "message"; "required": false; "isSignal": true; }; "defaultValue": { "alias": "defaultValue"; "required": false; "isSignal": true; }; "placeholder": { "alias": "placeholder"; "required": false; "isSignal": true; }; "okLabel": { "alias": "okLabel"; "required": false; "isSignal": true; }; "cancelLabel": { "alias": "cancelLabel"; "required": false; "isSignal": true; }; }, {}, never, never, true, [{ directive: typeof i1.UISurface; inputs: { "surfaceType": "surfaceType"; }; outputs: {}; }]>;
2320
+ }
2321
+
2322
+ /**
2323
+ * Content component for an open-file dialog.
2324
+ *
2325
+ * Displayed by {@link CommonDialogService.openFile}. Embeds a
2326
+ * {@link UIFileBrowser} and resolves to the selected file(s) or
2327
+ * `null` if cancelled.
2328
+ *
2329
+ * @internal — not intended for direct use; use the service instead.
2330
+ */
2331
+ declare class UIOpenFileDialog<M = unknown> {
2332
+ readonly title: _angular_core.InputSignal<string>;
2333
+ readonly openLabel: _angular_core.InputSignal<string>;
2334
+ readonly datasource: _angular_core.InputSignal<FileBrowserDatasource<M>>;
2335
+ protected readonly selectedFile: _angular_core.WritableSignal<FileBrowserEntry<M> | null>;
2336
+ private readonly modalRef;
2337
+ protected onFileActivated(_event: FileActivateEvent<M>): void;
2338
+ open(): void;
2339
+ cancel(): void;
2340
+ static ɵfac: _angular_core.ɵɵFactoryDeclaration<UIOpenFileDialog<any>, never>;
2341
+ static ɵcmp: _angular_core.ɵɵComponentDeclaration<UIOpenFileDialog<any>, "ui-open-file-dialog", never, { "title": { "alias": "title"; "required": false; "isSignal": true; }; "openLabel": { "alias": "openLabel"; "required": false; "isSignal": true; }; "datasource": { "alias": "datasource"; "required": true; "isSignal": true; }; }, {}, never, never, true, [{ directive: typeof i1.UISurface; inputs: { "surfaceType": "surfaceType"; }; outputs: {}; }]>;
2342
+ }
2343
+
2344
+ /**
2345
+ * Content component for a save-file dialog.
2346
+ *
2347
+ * Displayed by {@link CommonDialogService.saveFile}. Embeds a
2348
+ * {@link UIFileBrowser} for directory navigation plus a file-name
2349
+ * input. Resolves to a directory + file name, or `null` if cancelled.
2350
+ *
2351
+ * @internal — not intended for direct use; use the service instead.
2352
+ */
2353
+ declare class UISaveFileDialog<M = unknown> implements OnInit {
2354
+ readonly title: _angular_core.InputSignal<string>;
2355
+ readonly saveLabel: _angular_core.InputSignal<string>;
2356
+ readonly defaultName: _angular_core.InputSignal<string>;
2357
+ readonly datasource: _angular_core.InputSignal<FileBrowserDatasource<M>>;
2358
+ protected readonly fileName: _angular_core.WritableSignal<string>;
2359
+ protected readonly currentDir: _angular_core.WritableSignal<FileBrowserEntry<M> | null>;
2360
+ private readonly modalRef;
2361
+ ngOnInit(): void;
2362
+ protected onDirectoryChange(event: DirectoryChangeEvent<M>): void;
2363
+ save(): void;
2364
+ cancel(): void;
2365
+ static ɵfac: _angular_core.ɵɵFactoryDeclaration<UISaveFileDialog<any>, never>;
2366
+ static ɵcmp: _angular_core.ɵɵComponentDeclaration<UISaveFileDialog<any>, "ui-save-file-dialog", never, { "title": { "alias": "title"; "required": false; "isSignal": true; }; "saveLabel": { "alias": "saveLabel"; "required": false; "isSignal": true; }; "defaultName": { "alias": "defaultName"; "required": false; "isSignal": true; }; "datasource": { "alias": "datasource"; "required": true; "isSignal": true; }; }, {}, never, never, true, [{ directive: typeof i1.UISurface; inputs: { "surfaceType": "surfaceType"; }; outputs: {}; }]>;
2367
+ }
2368
+
2369
+ /**
2370
+ * Content component for an "About" dialog.
2371
+ *
2372
+ * Displayed by {@link CommonDialogService.about}. Shows the
2373
+ * application name, version, description, optional logo, copyright
2374
+ * notice, and credits.
2375
+ *
2376
+ * @internal — not intended for direct use; use the service instead.
2377
+ */
2378
+ declare class UIAboutDialog {
2379
+ readonly appName: _angular_core.InputSignal<string>;
2380
+ readonly version: _angular_core.InputSignal<string>;
2381
+ readonly description: _angular_core.InputSignal<string>;
2382
+ readonly logoUrl: _angular_core.InputSignal<string>;
2383
+ readonly copyright: _angular_core.InputSignal<string>;
2384
+ readonly credits: _angular_core.InputSignal<readonly string[]>;
2385
+ private readonly modalRef;
2386
+ dismiss(): void;
2387
+ static ɵfac: _angular_core.ɵɵFactoryDeclaration<UIAboutDialog, never>;
2388
+ static ɵcmp: _angular_core.ɵɵComponentDeclaration<UIAboutDialog, "ui-about-dialog", never, { "appName": { "alias": "appName"; "required": false; "isSignal": true; }; "version": { "alias": "version"; "required": false; "isSignal": true; }; "description": { "alias": "description"; "required": false; "isSignal": true; }; "logoUrl": { "alias": "logoUrl"; "required": false; "isSignal": true; }; "copyright": { "alias": "copyright"; "required": false; "isSignal": true; }; "credits": { "alias": "credits"; "required": false; "isSignal": true; }; }, {}, never, never, true, [{ directive: typeof i1.UISurface; inputs: { "surfaceType": "surfaceType"; }; outputs: {}; }]>;
2389
+ }
2390
+
2391
+ export { CommonDialogService, FILE_ICON_REGISTRY, SavedSearchService, UIAboutDialog, UIAlertDialog, UIChatView, UICommandPalette, UIConfirmDialog, UIDashboard, UIDashboardPanel, UIFileBrowser, UIKanbanBoard, UIMasterDetailView, UIMessageBubble, UINavigationPage, UIOpenFileDialog, UIPromptDialog, UIPropertySheet, UISaveFileDialog, UISearchView, UIWizard, UIWizardStep, navGroup, navItem, routesToNavigation };
2392
+ export type { AboutOptions, AlertOptions, ChatComposerMode, ChatMessage, ChatMessageType, ChatParticipant, CommandExecuteEvent, CommandPaletteItem, ConfirmOptions, ConfirmVariant, DashboardColumns, DashboardDockPosition, DashboardGridPlacement, DashboardPanelConfig, DirectoryChangeEvent, EntryTemplateContext, FileActivateEvent, FileBrowserDatasource, FileBrowserEntry, FileBrowserViewMode, FileIconRegistry, KanbanCard, KanbanCardContext, KanbanCardMoveEvent, KanbanColumn, MasterDetailContext, MessageDateGroup, MessageSendEvent, MessageTemplateContext, MetadataField, MetadataProvider, NavigationNode, NavigationNodeData, NavigationPageContext, NavigationRouteConfig, OpenFileOptions, OpenFileResult, PromptOptions, PropertyChangeEvent, PropertyFieldDefinition, PropertyFieldType, SaveFileOptions, SaveFileResult, SavedSearch, SearchViewEmptyContext, SearchViewLayout, SearchViewResultsContext, StepChangeEvent };
2393
+ //# sourceMappingURL=theredhead-lucid-blocks.d.ts.map