@dataworkz/crystal 0.1.0-beta.0 → 0.1.0-beta.10

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.
Files changed (43) hide show
  1. package/CHANGELOG.md +151 -13
  2. package/README.md +6 -0
  3. package/fesm2022/dataworkz-crystal-icons.mjs +32 -322
  4. package/fesm2022/dataworkz-crystal-icons.mjs.map +1 -1
  5. package/fesm2022/dataworkz-crystal-markdown.mjs +1 -1
  6. package/fesm2022/dataworkz-crystal-markdown.mjs.map +1 -1
  7. package/fesm2022/dataworkz-crystal-primeng.mjs +31 -5
  8. package/fesm2022/dataworkz-crystal-primeng.mjs.map +1 -1
  9. package/fesm2022/dataworkz-crystal.mjs +2635 -257
  10. package/fesm2022/dataworkz-crystal.mjs.map +1 -1
  11. package/icons/index.d.ts +33 -97
  12. package/icons/svg/files/csv.svg +0 -1
  13. package/icons/svg/files/generic.svg +0 -1
  14. package/icons/svg/files/multimedia.svg +0 -1
  15. package/icons/svg/glyphs/agentBuilder.svg +1 -1
  16. package/icons/svg/glyphs/notesPad.svg +1 -1
  17. package/icons/svg/glyphs/panelCollapse.svg +1 -1
  18. package/icons/svg/glyphs/panelExpand.svg +1 -1
  19. package/icons/svg/glyphs/play.svg +1 -1
  20. package/icons/svg/glyphs/robot.svg +1 -1
  21. package/icons/svg/glyphs/sidebarCollapse.svg +1 -1
  22. package/icons/svg/glyphs/sidebarExpand.svg +1 -1
  23. package/icons/svg/glyphs/tagFilled.svg +1 -1
  24. package/icons/svg/glyphs/testShield.svg +1 -1
  25. package/icons/svg/storage/generic.svg +0 -1
  26. package/icons/svg/storage/legacy/microsoft-mail.svg +0 -1
  27. package/icons/svg/storage/local/microsoft-mail.svg +0 -1
  28. package/index.d.ts +1207 -68
  29. package/package.json +5 -7
  30. package/primeng/index.d.ts +45 -5
  31. package/styles/base.css +4 -4
  32. package/styles/components/button.css +3 -0
  33. package/styles/components/content.css +89 -91
  34. package/styles/components/data.css +24 -1
  35. package/styles/components/form.css +116 -13
  36. package/styles/components/navigation.css +31 -1
  37. package/styles/components/overlay.css +16 -1
  38. package/styles/components/surface.css +38 -2
  39. package/styles/components/toast.css +1 -1
  40. package/styles/crystal-no-fonts.css +3 -2
  41. package/styles/icons.css +6 -0
  42. package/styles/tokens/primitives.css +1 -3
  43. package/styles/tokens/semantic-dark.css +1 -1
package/index.d.ts CHANGED
@@ -1,12 +1,15 @@
1
1
  import * as _angular_core from '@angular/core';
2
- import { OnDestroy, TemplateRef, EnvironmentProviders, InjectionToken } from '@angular/core';
3
- import { StorageIconSet } from '@dataworkz/crystal/icons';
4
- export { DW_ICON_NAMES, DW_ICON_PREFIX, DwIconName, IconName, dwIconName, icon } from '@dataworkz/crystal/icons';
2
+ import { InjectionToken, EnvironmentProviders, OnDestroy, TemplateRef, OnInit, OutputEmitterRef } from '@angular/core';
3
+ import { StorageIconSet, DwPrimeIcon } from '@dataworkz/crystal/icons';
4
+ export { DW_ICON_NAMES, DW_ICON_PREFIX, DwIconName, DwPrimeIcon, IconName, dwIconName, icon } from '@dataworkz/crystal/icons';
5
5
  import { ValidationErrors, AbstractControl, NgModel, NgControl, ControlValueAccessor } from '@angular/forms';
6
- import { MenuItem, SortMeta, SortEvent } from 'primeng/api';
6
+ import { MenuItem } from 'primeng/api';
7
7
  import { UrlTree } from '@angular/router';
8
8
  import { CdkDragDrop } from '@angular/cdk/drag-drop';
9
9
  import { Observable } from 'rxjs';
10
+ import * as i1 from 'primeng/tooltip';
11
+ import * as i1$1 from 'primeng/inputtext';
12
+ import * as i2 from 'primeng/textarea';
10
13
  import { TablePageEvent, Table } from 'primeng/table';
11
14
  import { SafeHtml } from '@angular/platform-browser';
12
15
 
@@ -187,7 +190,7 @@ type DwBadgeKind = 'count' | 'label';
187
190
  * <dw-badge value="Required" tone="accent" kind="label" />
188
191
  * <dw-badge value="admin" [bordered]="true" /> <!-- hairline outline, e.g. role pills -->
189
192
  * <dw-badge value="1 ms" kind="label" size="md" /> <!-- 12px, in detail headers -->
190
- * <dw-badge value="Jira" icon="assets/icons/jira.svg" /> <!-- image path icons work too -->
193
+ * <dw-badge value="Docs" [icon]="logoUrl" /> <!-- an image URL works too -->
191
194
  * ```
192
195
  */
193
196
  declare class DwBadgeComponent {
@@ -434,12 +437,12 @@ declare function initialsOf(name: string | null | undefined, strategy?: DwInitia
434
437
  /** A stable colour per name, for callers that opt in with `[tint]="tintFor(name)"`. */
435
438
  declare function tintFor(name: string | null | undefined): DwAvatarTint;
436
439
  /**
437
- * User / tenant avatar: image or initials on a bordered rounded square, neutral
440
+ * User / account avatar: image or initials on a bordered rounded square, neutral
438
441
  * grey unless a `tint` is given (the backend has no avatar colours).
439
442
  *
440
443
  * ```html
441
444
  * <dw-avatar [name]="user.fullName" size="sm" />
442
- * <dw-avatar [name]="tenant.accountName" initials="split" [presence]="tenant.active" />
445
+ * <dw-avatar [name]="account.name" initials="split" [presence]="account.online" />
443
446
  * ```
444
447
  */
445
448
  declare class DwAvatarComponent {
@@ -451,7 +454,7 @@ declare class DwAvatarComponent {
451
454
  readonly tint: _angular_core.InputSignal<DwAvatarTint>;
452
455
  readonly presence: _angular_core.InputSignal<boolean | null>;
453
456
  readonly tooltip: _angular_core.InputSignal<string>;
454
- /** Darkens the tile's border while its parent button is hovered or open (account menus). */
457
+ /** Darkens the tile's border while its parent button is hovered or open (e.g. an account menu). */
455
458
  readonly ring: _angular_core.InputSignal<boolean>;
456
459
  readonly imageFailed: _angular_core.WritableSignal<boolean>;
457
460
  readonly text: _angular_core.Signal<string>;
@@ -463,12 +466,13 @@ declare class DwAvatarComponent {
463
466
  type DwEntityKind = 'tool' | 'storage' | 'file' | 'image' | 'icon';
464
467
  type DwEntityTint = 'none' | 'neutral' | 'accent' | 'workflow' | 'reasoning' | 'orange' | 'cyan' | 'pink' | 'danger';
465
468
  /**
466
- * Entity / type icon. Resolves artwork through the shared icon utilities so
467
- * every screen picks the same asset for the same type.
469
+ * Entity / type icon: a tool, storage or file-type logo (inlined), an image, or an icon in a tinted tile.
470
+ * For `tool` / `storage`, `type` is a crystal icon key (`snowflake`, `s3`), or your own type value when the app maps
471
+ * it with `provideCrystalIconResolvers()`.
468
472
  *
469
473
  * ```html
470
- * <dw-entity-icon kind="tool" [type]="tool.typeId" [toolId]="tool.id" />
471
- * <dw-entity-icon kind="storage" [type]="conn.storageType" size="lg" [framed]="true" />
474
+ * <dw-entity-icon kind="tool" type="snowflake" />
475
+ * <dw-entity-icon kind="storage" type="s3" size="lg" [framed]="true" />
472
476
  * <dw-entity-icon kind="file" type="pdf" size="sm" />
473
477
  * <dw-entity-icon kind="icon" type="pi pi-sitemap" tint="accent" [framed]="true" />
474
478
  * <dw-entity-icon kind="icon" type="dwi-robot" tint="accent" [framed]="true" /> <!-- a dw-icon glyph, in the tint colour -->
@@ -476,8 +480,9 @@ type DwEntityTint = 'none' | 'neutral' | 'accent' | 'workflow' | 'reasoning' | '
476
480
  */
477
481
  declare class DwEntityIconComponent {
478
482
  readonly kind: _angular_core.InputSignal<DwEntityKind>;
479
- /** Tool typeId, storage type, file extension, image src, or icon class / `dwi-<name>` (per `kind`). */
483
+ /** Tool or storage icon key (or your type, see provideCrystalIconResolvers), file extension, image src, or icon class / `dwi-<name>` (per `kind`). */
480
484
  readonly type: _angular_core.InputSignal<string | null>;
485
+ /** Passed to your tool resolver (provideCrystalIconResolvers), for mappings that depend on the tool's id. */
481
486
  readonly toolId: _angular_core.InputSignal<string | null>;
482
487
  readonly src: _angular_core.InputSignal<string | null>;
483
488
  readonly fallback: _angular_core.InputSignal<string | undefined>;
@@ -488,6 +493,7 @@ declare class DwEntityIconComponent {
488
493
  readonly alt: _angular_core.InputSignal<string>;
489
494
  readonly failed: _angular_core.WritableSignal<boolean>;
490
495
  private readonly icons;
496
+ private readonly resolvers;
491
497
  /** kind `icon` with a `dwi-<name>` glyph or a registered icon name: drawn by dw-icon, in the tile's colour. */
492
498
  readonly svgIcon: _angular_core.Signal<string | null>;
493
499
  readonly iconClass: _angular_core.Signal<string>;
@@ -497,6 +503,31 @@ declare class DwEntityIconComponent {
497
503
  static ɵcmp: _angular_core.ɵɵComponentDeclaration<DwEntityIconComponent, "dw-entity-icon", never, { "kind": { "alias": "kind"; "required": false; "isSignal": true; }; "type": { "alias": "type"; "required": false; "isSignal": true; }; "toolId": { "alias": "toolId"; "required": false; "isSignal": true; }; "src": { "alias": "src"; "required": false; "isSignal": true; }; "fallback": { "alias": "fallback"; "required": false; "isSignal": true; }; "storageSet": { "alias": "storageSet"; "required": false; "isSignal": true; }; "size": { "alias": "size"; "required": false; "isSignal": true; }; "framed": { "alias": "framed"; "required": false; "isSignal": true; }; "tint": { "alias": "tint"; "required": false; "isSignal": true; }; "alt": { "alias": "alt"; "required": false; "isSignal": true; }; }, {}, never, never, true, never>;
498
504
  }
499
505
 
506
+ /**
507
+ * Maps an app's own type values to crystal's icon keys, for `dw-entity-icon kind="tool" | "storage"`. Crystal knows only
508
+ * its artwork names (`snowflake`, `s3`…); an app whose data says e.g. `RELATIONAL_POSTGRES` tells it which icon that is.
509
+ * Return `null` / `undefined` for "no artwork" (the generic or fallback icon shows).
510
+ */
511
+ interface DwIconResolvers {
512
+ /** Your tool `type` → a tool icon key. `toolId` is the element's `toolId` input, if your mapping needs it. */
513
+ tool?: (type: string, context: {
514
+ toolId: string | null;
515
+ }) => string | null | undefined;
516
+ /** Your storage `type` → a storage icon key. */
517
+ storage?: (type: string) => string | null | undefined;
518
+ }
519
+ /** The resolvers given to `provideCrystalIconResolvers()`; none by default (`type` is then the icon key itself). */
520
+ declare const DW_ICON_RESOLVERS: InjectionToken<DwIconResolvers>;
521
+ /**
522
+ * Lets `dw-entity-icon` take your own type values:
523
+ *
524
+ * ```ts
525
+ * providers: [provideCrystalIconResolvers({ tool: (typeId) => myToolIconKey(typeId), storage: (t) => myStorageKey(t) })]
526
+ * // <dw-entity-icon kind="tool" [type]="tool.typeId" />
527
+ * ```
528
+ */
529
+ declare function provideCrystalIconResolvers(resolvers: DwIconResolvers): EnvironmentProviders;
530
+
500
531
  /**
501
532
  * The one spinner. Replaces `fa-spinner fa-spin`, ad-hoc `pi-spin`,
502
533
  * cosmetic `p-progressSpinner`, `.loading-state` and `.loading-overlay`.
@@ -568,7 +599,7 @@ declare class DwMeterComponent {
568
599
  * "Show deprecated" beside a list's search, "Tree view" beside a tree's. Controlled: it shows
569
600
  * `checked` and emits the flipped value; the host decides.
570
601
  *
571
- * A button with role="checkbox" rather than a <label>-wrapped <input>: a label-wrapped input
602
+ * A button with role="checkbox" rather than a `<label>`-wrapped `<input>`: a label-wrapped input
572
603
  * forwards a synthetic click to the input, which bubbles back to the label and double-fires.
573
604
  *
574
605
  * ```html
@@ -811,7 +842,7 @@ declare class DwResizerComponent {
811
842
  }
812
843
 
813
844
  /**
814
- * Overlay anchors: a bar (e.g. the app header) marked `data-dw-overlay-anchor` makes every
845
+ * Overlay anchors: a bar (e.g. a fixed page header) marked `data-dw-overlay-anchor` makes every
815
846
  * dw-menu / dw-popover opened from inside it start just below the bar, rather than below
816
847
  * the individual trigger — so menus from a short avatar button and a full-height nav tab
817
848
  * line up on the same edge.
@@ -855,7 +886,7 @@ declare class DwCopyButtonComponent implements OnDestroy {
855
886
  }
856
887
 
857
888
  /**
858
- * The app-wide entity ID badge: a muted monospace ID (truncated to
889
+ * Entity ID badge: a muted monospace ID (truncated to
859
890
  * `first8...last4` by default) that reveals a copy icon on hover and copies
860
891
  * the full ID on click, flashing a "Copied!" confirmation.
861
892
  *
@@ -875,18 +906,28 @@ declare class IdBlockComponent implements OnDestroy {
875
906
  static ɵcmp: _angular_core.ɵɵComponentDeclaration<IdBlockComponent, "app-id-block, dw-id-block", never, { "value": { "alias": "value"; "required": false; "isSignal": true; }; "truncate": { "alias": "truncate"; "required": false; "isSignal": true; }; }, {}, never, never, true, never>;
876
907
  }
877
908
 
878
- type MessageFn = (error: unknown, label: string) => string;
909
+ /** A message, or a function building one from the validator's error value and the field's label. */
910
+ type DwFieldMessage = string | ((error: unknown, label: string) => string);
879
911
  /**
880
- * Default validation messages, keyed by validator error key. Screens can
881
- * override any of them per field through `dw-field [errors]`.
912
+ * Default validation messages for Angular's built-in validators, keyed by error key. An app adds messages for its own
913
+ * validators with `provideCrystalFieldMessages()`; a single field can override any of them through `dw-field [errors]`.
882
914
  */
883
- declare const DW_FIELD_MESSAGES: Readonly<Record<string, string | MessageFn>>;
915
+ declare const DW_FIELD_MESSAGES: Readonly<Record<string, DwFieldMessage>>;
916
+ /** The app's own validator messages (provideCrystalFieldMessages), merged over the defaults; none by default. */
917
+ declare const DW_APP_FIELD_MESSAGES: InjectionToken<Readonly<Record<string, DwFieldMessage>>>;
884
918
  /**
885
- * First matching message for a control's errors. Override map wins, then a
886
- * string error value (validators that return their own message), then the
887
- * defaults, then a generic fallback.
919
+ * Messages for the app's own validators (and replacements for the defaults), used by every dw-field:
920
+ *
921
+ * ```ts
922
+ * providers: [provideCrystalFieldMessages({ phone: 'Enter a phone number', duplicate: 'This name already exists' })]
923
+ * ```
924
+ */
925
+ declare function provideCrystalFieldMessages(messages: Readonly<Record<string, DwFieldMessage>>): EnvironmentProviders;
926
+ /**
927
+ * First matching message for a control's errors. Override map wins, then a string error value (validators that
928
+ * return their own message), then the app's messages, then the defaults, then a generic fallback.
888
929
  */
889
- declare function fieldErrorMessage(errors: ValidationErrors | null | undefined, overrides?: Readonly<Record<string, string>> | null, label?: string): string;
930
+ declare function fieldErrorMessage(errors: ValidationErrors | null | undefined, overrides?: Readonly<Record<string, string>> | null, label?: string, appMessages?: Readonly<Record<string, DwFieldMessage>>): string;
890
931
 
891
932
  type DwShowErrorsWhen = 'touched' | 'dirty' | 'touchedOrDirty' | 'always';
892
933
  /**
@@ -897,12 +938,12 @@ type DwShowErrorsWhen = 'touched' | 'dirty' | 'touchedOrDirty' | 'always';
897
938
  *
898
939
  * ```html
899
940
  * <dw-field label="Name" [control]="form.controls.name" help="Shown to end users" [maxLength]="100">
900
- * <input pInputText formControlName="name" />
941
+ * <input dwInput formControlName="name" />
901
942
  * </dw-field>
902
943
  *
903
944
  * <dw-field label="Prompt" layout="inline" info="Supports {{ '{{' }}variables}}">
904
945
  * <a dwFieldActions class="dw-link" (click)="generate()">Generate with AI</a>
905
- * <textarea pTextarea [(ngModel)]="prompt" #p="ngModel" required></textarea>
946
+ * <textarea dwInput [(ngModel)]="prompt" #p="ngModel" required></textarea>
906
947
  * </dw-field>
907
948
  *
908
949
  * <dw-field label="Region" [error]="regionError">…</dw-field> <!-- template-driven / manual -->
@@ -911,6 +952,7 @@ type DwShowErrorsWhen = 'touched' | 'dirty' | 'touchedOrDirty' | 'always';
911
952
  declare class DwFieldComponent {
912
953
  private readonly host;
913
954
  private readonly destroyRef;
955
+ private readonly appMessages;
914
956
  readonly label: _angular_core.InputSignal<string>;
915
957
  /** Explicit control id; generated when omitted. */
916
958
  readonly for: _angular_core.InputSignal<string | null>;
@@ -1156,6 +1198,10 @@ declare const DW_MENU_PLAIN_GROUP = "dw-menu-plain-group";
1156
1198
  * <!-- external trigger -->
1157
1199
  * <dw-button label="Create" trailingIcon="pi pi-chevron-down" (clicked)="createMenu.toggle($event)" />
1158
1200
  * <dw-menu #createMenu [items]="createItems" trigger="none" />
1201
+ *
1202
+ * <!-- context menu: opens at the pointer; commands get what was right-clicked -->
1203
+ * <div (contextmenu)="rowMenu.openAt($event, row)">…</div>
1204
+ * <dw-menu #rowMenu [items]="rowItems" trigger="none" />
1159
1205
  * ```
1160
1206
  * Items with `danger: true` are styled red and separated from the rest.
1161
1207
  *
@@ -1182,6 +1228,8 @@ declare class DwMenuComponent<T = unknown> {
1182
1228
  readonly closed: _angular_core.OutputEmitterRef<void>;
1183
1229
  readonly itemClick: _angular_core.OutputEmitterRef<DwMenuItem<T>>;
1184
1230
  readonly open: _angular_core.WritableSignal<boolean>;
1231
+ /** Set by `openAt`: where the panel goes and the context its commands get, until opened another way. */
1232
+ private readonly atPoint;
1185
1233
  readonly header: _angular_core.Signal<DwMenuHeaderDirective | undefined>;
1186
1234
  private readonly listMenu;
1187
1235
  private readonly tieredMenu;
@@ -1189,6 +1237,12 @@ declare class DwMenuComponent<T = unknown> {
1189
1237
  readonly model: _angular_core.Signal<MenuItem[]>;
1190
1238
  toggle(event: Event): void;
1191
1239
  show(event: Event): void;
1240
+ /**
1241
+ * Opens the menu as a context menu: at the pointer (kept inside the viewport) instead of under a trigger, without the
1242
+ * browser's own menu. Commands receive `context` (what was right-clicked) instead of the `context` input. Opening
1243
+ * it again while it is open moves it.
1244
+ */
1245
+ openAt(event: MouseEvent, context?: T | null): void;
1192
1246
  hide(): void;
1193
1247
  onShow(): void;
1194
1248
  onHide(): void;
@@ -1201,6 +1255,8 @@ declare class DwMenuComponent<T = unknown> {
1201
1255
  private groupLooseItems;
1202
1256
  private toMenuItems;
1203
1257
  private toMenuItem;
1258
+ /** Puts the panel's corner at the pointer, flipping left / up where it would leave the viewport. */
1259
+ private placeAtPoint;
1204
1260
  static ɵfac: _angular_core.ɵɵFactoryDeclaration<DwMenuComponent<any>, never>;
1205
1261
  static ɵcmp: _angular_core.ɵɵComponentDeclaration<DwMenuComponent<any>, "dw-menu", never, { "items": { "alias": "items"; "required": false; "isSignal": true; }; "context": { "alias": "context"; "required": false; "isSignal": true; }; "trigger": { "alias": "trigger"; "required": false; "isSignal": true; }; "triggerIcon": { "alias": "triggerIcon"; "required": false; "isSignal": true; }; "ariaLabel": { "alias": "ariaLabel"; "required": false; "isSignal": true; }; "size": { "alias": "size"; "required": false; "isSignal": true; }; "triggerVariant": { "alias": "triggerVariant"; "required": false; "isSignal": true; }; "disabled": { "alias": "disabled"; "required": false; "isSignal": true; }; "appendTo": { "alias": "appendTo"; "required": false; "isSignal": true; }; "styleClass": { "alias": "styleClass"; "required": false; "isSignal": true; }; "testId": { "alias": "testId"; "required": false; "isSignal": true; }; "mode": { "alias": "mode"; "required": false; "isSignal": true; }; }, { "opened": "opened"; "closed": "closed"; "itemClick": "itemClick"; }, ["header"], never, true, never>;
1206
1262
  }
@@ -1233,7 +1289,7 @@ type DwCardTint = 'neutral' | 'accent' | 'workflow' | 'reasoning' | 'orange' | '
1233
1289
  * <dw-card variant="stat" label="Runs" [value]="1204" [interactive]="true" [selected]="filter === 'runs'" />
1234
1290
  *
1235
1291
  * <!-- Stat with the info icon and an expand chevron at the end of the label row, a muted suffix -->
1236
- * <dw-card variant="stat" label="Invoices" [value]="'1,341'" valueSuffix="/ 1,500" tooltip="…" infoPosition="end">
1292
+ * <dw-card variant="stat" label="Orders" [value]="'1,341'" valueSuffix="/ 1,500" tooltip="…" infoPosition="end">
1237
1293
  * <i dwStatLabelEnd class="pi pi-chevron-down"></i>
1238
1294
  * </dw-card>
1239
1295
  *
@@ -1286,7 +1342,7 @@ declare class DwCardComponent {
1286
1342
  static ɵcmp: _angular_core.ɵɵComponentDeclaration<DwCardComponent, "dw-card", never, { "variant": { "alias": "variant"; "required": false; "isSignal": true; }; "size": { "alias": "size"; "required": false; "isSignal": true; }; "title": { "alias": "title"; "required": false; "isSignal": true; }; "subtitle": { "alias": "subtitle"; "required": false; "isSignal": true; }; "description": { "alias": "description"; "required": false; "isSignal": true; }; "clampLines": { "alias": "clampLines"; "required": false; "isSignal": true; }; "icon": { "alias": "icon"; "required": false; "isSignal": true; }; "iconTint": { "alias": "iconTint"; "required": false; "isSignal": true; }; "badge": { "alias": "badge"; "required": false; "isSignal": true; }; "badgeTone": { "alias": "badgeTone"; "required": false; "isSignal": true; }; "tooltip": { "alias": "tooltip"; "required": false; "isSignal": true; }; "interactive": { "alias": "interactive"; "required": false; "isSignal": true; }; "selected": { "alias": "selected"; "required": false; "isSignal": true; }; "disabled": { "alias": "disabled"; "required": false; "isSignal": true; }; "disabledReason": { "alias": "disabledReason"; "required": false; "isSignal": true; }; "loading": { "alias": "loading"; "required": false; "isSignal": true; }; "menuItems": { "alias": "menuItems"; "required": false; "isSignal": true; }; "menuContext": { "alias": "menuContext"; "required": false; "isSignal": true; }; "label": { "alias": "label"; "required": false; "isSignal": true; }; "labelStyle": { "alias": "labelStyle"; "required": false; "isSignal": true; }; "value": { "alias": "value"; "required": false; "isSignal": true; }; "valueSuffix": { "alias": "valueSuffix"; "required": false; "isSignal": true; }; "infoPosition": { "alias": "infoPosition"; "required": false; "isSignal": true; }; "appearance": { "alias": "appearance"; "required": false; "isSignal": true; }; "hasBody": { "alias": "hasBody"; "required": false; "isSignal": true; }; "testId": { "alias": "testId"; "required": false; "isSignal": true; }; }, { "activate": "activate"; }, never, ["*", "[dwStatLabelEnd]", "[dwCardHeaderEnd]", "[dwCardTags]", "[dwCardFooter]"], true, never>;
1287
1343
  }
1288
1344
 
1289
- /** Marks the switch (usually `<p-toggleswitch formControlName=…>`) shown at the card's leading edge. */
1345
+ /** Marks the switch (usually `<dw-switch formControlName=…>`) shown at the card's leading edge. */
1290
1346
  declare class DwToggleCardControlDirective {
1291
1347
  static ɵfac: _angular_core.ɵɵFactoryDeclaration<DwToggleCardControlDirective, never>;
1292
1348
  static ɵdir: _angular_core.ɵɵDirectiveDeclaration<DwToggleCardControlDirective, "[dwToggleCardControl]", never, {}, {}, never, never, true, never>;
@@ -1307,9 +1363,9 @@ declare class DwToggleCardBodyDirective {
1307
1363
  *
1308
1364
  * ```html
1309
1365
  * <dw-toggle-card title="Full Text Search Index" description="Enable full text search"
1310
- * icon="assets/images/svgIcon/text-search.svg" [expanded]="form.value.fullTextSearchIndex"
1366
+ * icon="pi pi-search" [expanded]="form.value.fullTextSearchIndex"
1311
1367
  * [disabledReason]="graphDbOn ? '' : 'Requires Graph Database Storage to be enabled'">
1312
- * <p-toggleswitch dwToggleCardControl formControlName="fullTextSearchIndex" />
1368
+ * <dw-switch dwToggleCardControl formControlName="fullTextSearchIndex" />
1313
1369
  * <ng-template dwToggleCardBody>…configuration fields…</ng-template>
1314
1370
  * </dw-toggle-card>
1315
1371
  * ```
@@ -1340,7 +1396,7 @@ declare const DW_TOGGLE_CARD: readonly [typeof DwToggleCardComponent, typeof DwT
1340
1396
  *
1341
1397
  * ```html
1342
1398
  * <div class="dw-tile-grid">
1343
- * <dw-tile label="Snowflake" icon="assets/snowflake.svg" [count]="3" (activate)="open('snowflake')" />
1399
+ * <dw-tile label="Snowflake" icon="pi pi-database" [count]="3" (activate)="open('snowflake')" />
1344
1400
  * <dw-tile label="Slack" icon="pi pi-slack" badge="Coming soon" [disabled]="true" />
1345
1401
  * </div>
1346
1402
  * ```
@@ -1561,14 +1617,14 @@ declare class DwBreadcrumbComponent {
1561
1617
  * subtitle, count, deprecated badge, meta row and right-side actions.
1562
1618
  *
1563
1619
  * ```html
1564
- * <dw-page-header title="My agents" [count]="total">
1620
+ * <dw-page-header title="Projects" [count]="total">
1565
1621
  * <dw-button dwPageHeaderActions label="Create" icon="pi pi-plus" (clicked)="create()" />
1566
1622
  * </dw-page-header>
1567
1623
  *
1568
- * <dw-page-header [breadcrumbs]="[{label:'LLM Configuration', action: back}, {label: cfg.name}]"
1569
- * icon="assets/images/svgIcon/llm.svg" variant="panel" [showClose]="true" (close)="close()" />
1624
+ * <dw-page-header [breadcrumbs]="[{label:'Settings', action: back}, {label: item.name}]"
1625
+ * icon="pi pi-cog" variant="panel" [showClose]="true" (close)="close()" />
1570
1626
  *
1571
- * <dw-page-header variant="list" [flush]="true" title="Tenant Analytics" /> <!-- on the content edge -->
1627
+ * <dw-page-header variant="list" [flush]="true" title="Analytics" /> <!-- on the content edge -->
1572
1628
  *
1573
1629
  * <dw-page-header [title]="agent.name" [editableTitle]="true" (titleChange)="rename($event)"
1574
1630
  * [showBack]="true" (back)="goBack()">
@@ -1782,8 +1838,8 @@ declare class DwNavListComponent {
1782
1838
  /** Nested items hang off guide lines instead of plain indentation (reference trees). */
1783
1839
  readonly treeLines: _angular_core.InputSignal<boolean>;
1784
1840
  /**
1785
- * The accent left border on the selected item. Only the agents list page's sidebar uses it;
1786
- * everywhere else a selection is the plain selected fill.
1841
+ * The accent left border on the selected item, for a sidebar that wants a stronger marker;
1842
+ * otherwise a selection is the plain selected fill.
1787
1843
  */
1788
1844
  readonly marker: _angular_core.InputSignal<boolean>;
1789
1845
  /** Where item tooltips open: beside a sidebar (right, the default) or above, e.g. in a wide panel. */
@@ -1934,10 +1990,10 @@ interface DwConfirmSummaryRow {
1934
1990
  * copied `.delete-modal-*` markup.
1935
1991
  *
1936
1992
  * ```html
1937
- * <dw-confirm-dialog [(visible)]="confirmOpen" header="Delete workspace"
1938
- * [message]="'Delete “' + ws.name + '”? This cannot be undone.'"
1993
+ * <dw-confirm-dialog [(visible)]="confirmOpen" header="Delete project"
1994
+ * [message]="'Delete “' + project.name + '”? This cannot be undone.'"
1939
1995
  * acceptLabel="Delete" loadingLabel="Deleting…" [loading]="deleting"
1940
- * [warning]="{ title: 'In use', text: '3 collections use this workspace' }"
1996
+ * [warning]="{ title: 'In use', text: '3 reports use this project' }"
1941
1997
  * (accept)="delete()" />
1942
1998
  * ```
1943
1999
  * Project extra body content (radio options, dependency lists) as children.
@@ -2087,7 +2143,7 @@ declare class DwDrawerComponent {
2087
2143
  readonly breadcrumbs: _angular_core.InputSignal<readonly DwBreadcrumb[]>;
2088
2144
  readonly showBack: _angular_core.InputSignal<boolean>;
2089
2145
  readonly showCloseIcon: _angular_core.InputSignal<boolean>;
2090
- /** False when the body brings its own header and close control (e.g. the probe view). */
2146
+ /** False when the body brings its own header and close control. */
2091
2147
  readonly showHeader: _angular_core.InputSignal<boolean>;
2092
2148
  readonly modal: _angular_core.InputSignal<boolean>;
2093
2149
  /** Close on mask click. */
@@ -2154,8 +2210,8 @@ declare class DwPopoverFooterDirective {
2154
2210
  * and footer actions.
2155
2211
  *
2156
2212
  * ```html
2157
- * <dw-button label="New tenant" (clicked)="pop.toggle($event)" />
2158
- * <dw-popover #pop header="Create tenant" width="320px">
2213
+ * <dw-button label="New project" (clicked)="pop.toggle($event)" />
2214
+ * <dw-popover #pop header="Create project" width="320px">
2159
2215
  * <input pInputText [(ngModel)]="name" />
2160
2216
  * <div dwPopoverFooter>
2161
2217
  * <dw-button label="Cancel" variant="secondary" appearance="text" (clicked)="pop.hide()" />
@@ -2234,7 +2290,7 @@ interface DwToast {
2234
2290
  *
2235
2291
  * ```ts
2236
2292
  * this.toast.success('Agent saved');
2237
- * this.toast.error('Could not delete workspace', { sticky: true });
2293
+ * this.toast.error('Could not delete the project', { sticky: true });
2238
2294
  * ```
2239
2295
  */
2240
2296
  declare class DwToastService implements OnDestroy {
@@ -2261,7 +2317,7 @@ declare class DwToastService implements OnDestroy {
2261
2317
  type DwToastPosition = 'top-center' | 'top-right' | 'bottom-center' | 'bottom-right';
2262
2318
  /**
2263
2319
  * Renders the DwToastService stack. Place it once, in the app's root component; every screen pushes toasts through
2264
- * DwToastService and they all show here, with one position and one look (dataworkz-ui's toasts as they look today).
2320
+ * DwToastService and they all show here, with one position and one look.
2265
2321
  *
2266
2322
  * ```html
2267
2323
  * <router-outlet />
@@ -2270,7 +2326,7 @@ type DwToastPosition = 'top-center' | 'top-right' | 'bottom-center' | 'bottom-ri
2270
2326
  */
2271
2327
  declare class DwToastHostComponent {
2272
2328
  private readonly toasts;
2273
- /** Where the stack sits. Default: centred under the top edge, as in dataworkz-ui today. */
2329
+ /** Where the stack sits. Default: centred under the top edge. */
2274
2330
  readonly position: _angular_core.InputSignal<DwToastPosition>;
2275
2331
  /** Most toasts shown at once; the newest win, older ones wait until these go. */
2276
2332
  readonly max: _angular_core.InputSignal<number>;
@@ -2305,6 +2361,1043 @@ declare class DwTooltipIfTruncatedDirective {
2305
2361
  static ɵdir: _angular_core.ɵɵDirectiveDeclaration<DwTooltipIfTruncatedDirective, "[dwTooltipIfTruncated]", never, { "truncationTarget": { "alias": "truncationTarget"; "required": false; "isSignal": true; }; }, {}, never, never, true, never>;
2306
2362
  }
2307
2363
 
2364
+ type DwTooltipPosition = 'top' | 'bottom' | 'left' | 'right';
2365
+ /**
2366
+ * `multiline` keeps line breaks (up to 360px), `code` monospace, `error` danger red, `toolbar` a slate chip, `preview`
2367
+ * a long value shown whole (up to 720 × 340px, then scrolled; pair it with `dwTooltipInteractive`).
2368
+ */
2369
+ type DwTooltipVariant = 'default' | 'multiline' | 'code' | 'error' | 'toolbar' | 'preview';
2370
+ /**
2371
+ * A tooltip on any element, in crystal's look (PrimeNG's Tooltip underneath, which the app never imports). It opens
2372
+ * on hover and focus, above the element unless told otherwise, appended to `<body>` so nothing clips it.
2373
+ *
2374
+ * ```html
2375
+ * <button dwTooltip="Refresh">…</button>
2376
+ * <span [dwTooltip]="fullName" dwTooltipPosition="bottom" [dwTooltipDelay]="300">{{ shortName }}</span>
2377
+ * <i dwTooltip="Line one&#10;line two" dwTooltipVariant="multiline"></i>
2378
+ * <span [dwTooltip]="token" [dwTooltipInteractive]="true">Token</span> <!-- hover into it to copy -->
2379
+ * ```
2380
+ */
2381
+ declare class DwTooltipDirective {
2382
+ private readonly prime;
2383
+ readonly dwTooltipPosition: _angular_core.InputSignal<DwTooltipPosition>;
2384
+ /** Milliseconds before it opens. */
2385
+ readonly dwTooltipDelay: _angular_core.InputSignal<number>;
2386
+ readonly dwTooltipVariant: _angular_core.InputSignal<DwTooltipVariant>;
2387
+ /** Stays open while the pointer moves onto it, so its text can be selected and copied. */
2388
+ readonly dwTooltipInteractive: _angular_core.InputSignal<boolean>;
2389
+ constructor();
2390
+ static ɵfac: _angular_core.ɵɵFactoryDeclaration<DwTooltipDirective, never>;
2391
+ static ɵdir: _angular_core.ɵɵDirectiveDeclaration<DwTooltipDirective, "[dwTooltip]", never, { "dwTooltipPosition": { "alias": "dwTooltipPosition"; "required": false; "isSignal": true; }; "dwTooltipDelay": { "alias": "dwTooltipDelay"; "required": false; "isSignal": true; }; "dwTooltipVariant": { "alias": "dwTooltipVariant"; "required": false; "isSignal": true; }; "dwTooltipInteractive": { "alias": "dwTooltipInteractive"; "required": false; "isSignal": true; }; }, {}, never, never, true, [{ directive: typeof i1.Tooltip; inputs: { "pTooltip": "dwTooltip"; "tooltipDisabled": "dwTooltipDisabled"; }; outputs: {}; }]>;
2392
+ }
2393
+
2394
+ type DwInputSize = 'sm' | 'md' | 'lg';
2395
+ /**
2396
+ * Crystal's text input: a native `<input>` in crystal's look (PrimeNG's InputText underneath, which the app never
2397
+ * imports). Works with ngModel and reactive forms, and inside `dw-field`, which wires its label and error.
2398
+ *
2399
+ * ```html
2400
+ * <input dwInput placeholder="Name" [(ngModel)]="name" />
2401
+ * <input dwInput size="sm" type="number" formControlName="limit" />
2402
+ * <input dwInput [fluid]="true" [invalid]="!!serverError" />
2403
+ * ```
2404
+ */
2405
+ declare class DwInputDirective {
2406
+ private readonly prime;
2407
+ /** `md` by default; `sm` matches small buttons (28px). Shadows the native character-count `size` attribute. */
2408
+ set size(size: DwInputSize | null | undefined);
2409
+ static ɵfac: _angular_core.ɵɵFactoryDeclaration<DwInputDirective, never>;
2410
+ static ɵdir: _angular_core.ɵɵDirectiveDeclaration<DwInputDirective, "input[dwInput]", never, { "size": { "alias": "size"; "required": false; }; }, {}, never, never, true, [{ directive: typeof i1$1.InputText; inputs: { "fluid": "fluid"; "invalid": "invalid"; }; outputs: {}; }]>;
2411
+ }
2412
+ /**
2413
+ * Crystal's multi-line text input: a native `<textarea>` in crystal's look (PrimeNG's Textarea underneath).
2414
+ * `autoResize` grows it with its content.
2415
+ *
2416
+ * ```html
2417
+ * <textarea dwInput rows="3" [(ngModel)]="prompt"></textarea>
2418
+ * <textarea dwInput [autoResize]="true" formControlName="notes"></textarea>
2419
+ * ```
2420
+ */
2421
+ declare class DwTextareaDirective {
2422
+ private readonly prime;
2423
+ /** `md` by default; `sm` uses the 12px type. */
2424
+ set size(size: DwInputSize | null | undefined);
2425
+ static ɵfac: _angular_core.ɵɵFactoryDeclaration<DwTextareaDirective, never>;
2426
+ static ɵdir: _angular_core.ɵɵDirectiveDeclaration<DwTextareaDirective, "textarea[dwInput]", never, { "size": { "alias": "size"; "required": false; }; }, {}, never, never, true, [{ directive: typeof i2.Textarea; inputs: { "autoResize": "autoResize"; "fluid": "fluid"; "invalid": "invalid"; }; outputs: {}; }]>;
2427
+ }
2428
+ /** Both: `imports: [DW_INPUT]` covers `<input dwInput>` and `<textarea dwInput>`. */
2429
+ declare const DW_INPUT: readonly [typeof DwInputDirective, typeof DwTextareaDirective];
2430
+
2431
+ /**
2432
+ * What every crystal form control shares (dw-select, dw-checkbox, dw-switch…): it works with ngModel, formControlName
2433
+ * and formControl, or on its own through `[(value)]`; it is disabled by the form or by `disabled`; and it shows
2434
+ * itself invalid once its control is invalid and touched or dirty (as crystal's inputs do), or when `invalid` says so.
2435
+ *
2436
+ * A subclass renders its PrimeNG control from `isDisabled()` and `showInvalid()` and hands it to `drive()`, which keeps
2437
+ * it in step with `value()`; or it calls `commit(value)` itself when the user changes the value, and `markTouched()`
2438
+ * when the control loses focus.
2439
+ */
2440
+ declare abstract class DwFormControl<T> implements ControlValueAccessor, OnInit {
2441
+ private readonly ngControl;
2442
+ private readonly destroyRef;
2443
+ /** The value, for use without forms: `[(value)]`. With forms, bind ngModel / formControlName instead. */
2444
+ readonly value: _angular_core.ModelSignal<T | null>;
2445
+ readonly disabled: _angular_core.InputSignalWithTransform<boolean, unknown>;
2446
+ /** Shows the invalid state whatever the form says (e.g. a server error). */
2447
+ readonly invalid: _angular_core.InputSignalWithTransform<boolean, unknown>;
2448
+ /** The user changed the value (not emitted when the form or `[value]` sets one). */
2449
+ readonly changed: _angular_core.OutputEmitterRef<T | null>;
2450
+ private readonly formDisabled;
2451
+ /** Bumped on every status / value / touched event of the bound control, so `showInvalid` re-evaluates. */
2452
+ private readonly controlEvents;
2453
+ readonly isDisabled: _angular_core.Signal<boolean>;
2454
+ readonly showInvalid: _angular_core.Signal<boolean>;
2455
+ private onChange;
2456
+ private onTouched;
2457
+ constructor();
2458
+ ngOnInit(): void;
2459
+ writeValue(value: T | null | undefined): void;
2460
+ registerOnChange(fn: (value: T | null) => void): void;
2461
+ registerOnTouched(fn: () => void): void;
2462
+ setDisabledState(disabled: boolean): void;
2463
+ /** The user changed the value. */
2464
+ protected commit(value: T | null): void;
2465
+ /**
2466
+ * Keeps a PrimeNG control (its own value accessor) in step with this one, synchronously: the value goes in through
2467
+ * its `writeValue`, the user's changes and blurs come back. Call from the constructor with the control's viewChild.
2468
+ * (A second ngModel on the PrimeNG control would write a microtask after the app's, one render behind.)
2469
+ * `prepare` runs just before each write, for inputs the control reads while writing (a radio's own value).
2470
+ * Only this control's value and what `prepare` reads are tracked: PrimeNG's own signals, which `writeValue` reads and
2471
+ * sets, are not, or a write that changes one would run the effect again, without end.
2472
+ * The user's own change is not written back (as with ngModel): the control has it already, and some redraw on a
2473
+ * write (a date picker turns its calendar to the written date's month).
2474
+ */
2475
+ protected drive<C extends DwPrimeValueAccessor<T>>(prime: () => C | undefined, prepare?: (control: C) => void): void;
2476
+ /** The control lost focus. */
2477
+ protected markTouched(): void;
2478
+ static ɵfac: _angular_core.ɵɵFactoryDeclaration<DwFormControl<any>, never>;
2479
+ static ɵdir: _angular_core.ɵɵDirectiveDeclaration<DwFormControl<any>, never, never, { "value": { "alias": "value"; "required": false; "isSignal": true; }; "disabled": { "alias": "disabled"; "required": false; "isSignal": true; }; "invalid": { "alias": "invalid"; "required": false; "isSignal": true; }; }, { "value": "valueChange"; "changed": "changed"; }, never, never, true, never>;
2480
+ }
2481
+ /** The part of a PrimeNG form control that `drive()` uses: Angular's value accessor. */
2482
+ interface DwPrimeValueAccessor<T> {
2483
+ writeValue(value: T | null): void;
2484
+ registerOnChange(fn: (value: T | null) => void): void;
2485
+ registerOnTouched(fn: () => void): void;
2486
+ }
2487
+ type DwControlSize = 'sm' | 'md' | 'lg';
2488
+ /** Crystal's control sizes in PrimeNG's words: `md` is PrimeNG's default. */
2489
+ declare function primeSize(size: DwControlSize): 'small' | 'large' | undefined;
2490
+
2491
+ /** Context of an option template: the option itself. */
2492
+ interface DwSelectOptionContext<T = unknown> {
2493
+ $implicit: T;
2494
+ }
2495
+ /**
2496
+ * How each option of a dw-select / dw-multiselect is drawn in its list.
2497
+ *
2498
+ * ```html
2499
+ * <dw-select [options]="llms" optionLabel="name" optionValue="id" [(ngModel)]="llmId">
2500
+ * <ng-template dwSelectOption let-llm><dw-entity-icon kind="llm" [type]="llm.provider" /> {{ llm.name }}</ng-template>
2501
+ * </dw-select>
2502
+ * ```
2503
+ */
2504
+ declare class DwSelectOptionDirective<T = unknown> {
2505
+ readonly template: TemplateRef<DwSelectOptionContext<T>>;
2506
+ static ɵfac: _angular_core.ɵɵFactoryDeclaration<DwSelectOptionDirective<any>, never>;
2507
+ static ɵdir: _angular_core.ɵɵDirectiveDeclaration<DwSelectOptionDirective<any>, "ng-template[dwSelectOption]", never, {}, {}, never, never, true, never>;
2508
+ }
2509
+ /** How a dw-select draws its selected option in the closed control (defaults to the option template's look). */
2510
+ declare class DwSelectValueDirective<T = unknown> {
2511
+ readonly template: TemplateRef<DwSelectOptionContext<T>>;
2512
+ static ɵfac: _angular_core.ɵɵFactoryDeclaration<DwSelectValueDirective<any>, never>;
2513
+ static ɵdir: _angular_core.ɵɵDirectiveDeclaration<DwSelectValueDirective<any>, "ng-template[dwSelectValue]", never, {}, {}, never, never, true, never>;
2514
+ }
2515
+ /** Content under the option list (e.g. a "Create new" action). */
2516
+ declare class DwSelectFooterDirective {
2517
+ readonly template: TemplateRef<void>;
2518
+ static ɵfac: _angular_core.ɵɵFactoryDeclaration<DwSelectFooterDirective, never>;
2519
+ static ɵdir: _angular_core.ɵɵDirectiveDeclaration<DwSelectFooterDirective, "ng-template[dwSelectFooter]", never, {}, {}, never, never, true, never>;
2520
+ }
2521
+
2522
+ /**
2523
+ * Crystal's single select (PrimeNG's Select underneath, which the app never imports). The option list is appended to
2524
+ * `<body>`, as wide as the control; long options end in an ellipsis. Works with ngModel and reactive forms, inside
2525
+ * `dw-field`, or on its own with `[(value)]`.
2526
+ *
2527
+ * ```html
2528
+ * <dw-select [options]="regions" optionLabel="name" optionValue="id" placeholder="Region" formControlName="region" />
2529
+ * <dw-select size="sm" [options]="llms" [(ngModel)]="llm" [filter]="true" filterBy="name" (changed)="save($event)">
2530
+ * <ng-template dwSelectOption let-llm>{{ llm.name }}</ng-template>
2531
+ * </dw-select>
2532
+ * <dw-select [options]="providers" [readonly]="true" [(value)]="provider" />
2533
+ * ```
2534
+ */
2535
+ declare class DwSelectComponent<T = unknown> extends DwFormControl<T> {
2536
+ readonly options: _angular_core.InputSignal<unknown[] | null | undefined>;
2537
+ /** The option field to show; options are shown as they are when omitted (strings, numbers). */
2538
+ readonly optionLabel: _angular_core.InputSignal<string | undefined>;
2539
+ /** The option field to bind; the whole option is the value when omitted. */
2540
+ readonly optionValue: _angular_core.InputSignal<string | undefined>;
2541
+ /** The option field that disables an option. */
2542
+ readonly optionDisabled: _angular_core.InputSignal<string | undefined>;
2543
+ /** The field that identifies an option when the value is an object. */
2544
+ readonly dataKey: _angular_core.InputSignal<string | undefined>;
2545
+ readonly placeholder: _angular_core.InputSignal<string | undefined>;
2546
+ /** A search box at the top of the list. */
2547
+ readonly filter: _angular_core.InputSignalWithTransform<boolean, unknown>;
2548
+ /** Fields to search, comma-separated; the label by default. */
2549
+ readonly filterBy: _angular_core.InputSignal<string | undefined>;
2550
+ readonly filterPlaceholder: _angular_core.InputSignal<string | undefined>;
2551
+ readonly emptyMessage: _angular_core.InputSignal<string>;
2552
+ readonly emptyFilterMessage: _angular_core.InputSignal<string>;
2553
+ readonly loading: _angular_core.InputSignalWithTransform<boolean, unknown>;
2554
+ /** A clear (×) button once something is selected. */
2555
+ readonly showClear: _angular_core.InputSignalWithTransform<boolean, unknown>;
2556
+ /** Lets the user type a value of their own. */
2557
+ readonly editable: _angular_core.InputSignalWithTransform<boolean, unknown>;
2558
+ /** Height of the list before it scrolls. */
2559
+ readonly scrollHeight: _angular_core.InputSignal<string>;
2560
+ readonly autofocus: _angular_core.InputSignalWithTransform<boolean, unknown>;
2561
+ readonly ariaLabel: _angular_core.InputSignal<string | undefined>;
2562
+ /** Id of the focusable element, for a `<label for>` outside dw-field. */
2563
+ readonly inputId: _angular_core.InputSignal<string | undefined>;
2564
+ readonly size: _angular_core.InputSignal<DwControlSize>;
2565
+ /** Fills the width of its container. */
2566
+ readonly fluid: _angular_core.InputSignalWithTransform<boolean, unknown>;
2567
+ /** Stacks the list above this z-index (as dw-dialog / dw-drawer / dw-popover's `baseZIndex`), for a select inside a
2568
+ * layer that sets its own z-index, e.g. a page that hosts crystal in a high layer. 0 = PrimeNG's own stacking. */
2569
+ readonly baseZIndex: _angular_core.InputSignal<number>;
2570
+ /** Reads as a fixed value, not a control: no arrow, the value in body text. */
2571
+ readonly readonly: _angular_core.InputSignalWithTransform<boolean, unknown>;
2572
+ readonly opened: _angular_core.OutputEmitterRef<void>;
2573
+ readonly closed: _angular_core.OutputEmitterRef<void>;
2574
+ readonly focused: _angular_core.OutputEmitterRef<void>;
2575
+ readonly blurred: _angular_core.OutputEmitterRef<void>;
2576
+ protected readonly optionTemplate: _angular_core.Signal<DwSelectOptionDirective<any> | undefined>;
2577
+ protected readonly valueTemplate: _angular_core.Signal<DwSelectValueDirective<any> | undefined>;
2578
+ protected readonly footerTemplate: _angular_core.Signal<DwSelectFooterDirective | undefined>;
2579
+ protected readonly primeSize: _angular_core.Signal<"small" | "large" | undefined>;
2580
+ protected readonly overlayOptions: _angular_core.Signal<{
2581
+ baseZIndex: number;
2582
+ } | undefined>;
2583
+ private readonly prime;
2584
+ constructor();
2585
+ /** Opens the list (e.g. when an editable select's text is clicked). */
2586
+ open(): void;
2587
+ close(): void;
2588
+ static ɵfac: _angular_core.ɵɵFactoryDeclaration<DwSelectComponent<any>, never>;
2589
+ static ɵcmp: _angular_core.ɵɵComponentDeclaration<DwSelectComponent<any>, "dw-select", never, { "options": { "alias": "options"; "required": false; "isSignal": true; }; "optionLabel": { "alias": "optionLabel"; "required": false; "isSignal": true; }; "optionValue": { "alias": "optionValue"; "required": false; "isSignal": true; }; "optionDisabled": { "alias": "optionDisabled"; "required": false; "isSignal": true; }; "dataKey": { "alias": "dataKey"; "required": false; "isSignal": true; }; "placeholder": { "alias": "placeholder"; "required": false; "isSignal": true; }; "filter": { "alias": "filter"; "required": false; "isSignal": true; }; "filterBy": { "alias": "filterBy"; "required": false; "isSignal": true; }; "filterPlaceholder": { "alias": "filterPlaceholder"; "required": false; "isSignal": true; }; "emptyMessage": { "alias": "emptyMessage"; "required": false; "isSignal": true; }; "emptyFilterMessage": { "alias": "emptyFilterMessage"; "required": false; "isSignal": true; }; "loading": { "alias": "loading"; "required": false; "isSignal": true; }; "showClear": { "alias": "showClear"; "required": false; "isSignal": true; }; "editable": { "alias": "editable"; "required": false; "isSignal": true; }; "scrollHeight": { "alias": "scrollHeight"; "required": false; "isSignal": true; }; "autofocus": { "alias": "autofocus"; "required": false; "isSignal": true; }; "ariaLabel": { "alias": "ariaLabel"; "required": false; "isSignal": true; }; "inputId": { "alias": "inputId"; "required": false; "isSignal": true; }; "size": { "alias": "size"; "required": false; "isSignal": true; }; "fluid": { "alias": "fluid"; "required": false; "isSignal": true; }; "baseZIndex": { "alias": "baseZIndex"; "required": false; "isSignal": true; }; "readonly": { "alias": "readonly"; "required": false; "isSignal": true; }; }, { "opened": "opened"; "closed": "closed"; "focused": "focused"; "blurred": "blurred"; }, ["optionTemplate", "valueTemplate", "footerTemplate"], never, true, never>;
2590
+ }
2591
+
2592
+ /**
2593
+ * Crystal's multiple select (PrimeNG's MultiSelect underneath, which the app never imports): a checkbox per option,
2594
+ * a search box and "select all" by default, the picks shown as a comma list (or chips) up to `maxSelectedLabels`.
2595
+ * The list is appended to `<body>`. Its value is an array.
2596
+ *
2597
+ * ```html
2598
+ * <dw-multiselect [options]="tags" optionLabel="name" optionValue="id" placeholder="Tags" formControlName="tags" />
2599
+ * <dw-multiselect [options]="columns" [(ngModel)]="shown" display="chip" [filter]="false" />
2600
+ * ```
2601
+ */
2602
+ declare class DwMultiselectComponent<T = unknown> extends DwFormControl<T[]> {
2603
+ readonly options: _angular_core.InputSignal<unknown[] | undefined>;
2604
+ readonly optionLabel: _angular_core.InputSignal<string | undefined>;
2605
+ readonly optionValue: _angular_core.InputSignal<string | undefined>;
2606
+ readonly optionDisabled: _angular_core.InputSignal<string | undefined>;
2607
+ readonly dataKey: _angular_core.InputSignal<string | undefined>;
2608
+ readonly placeholder: _angular_core.InputSignal<string | undefined>;
2609
+ /** A search box at the top of the list (on by default, as in PrimeNG). */
2610
+ readonly filter: _angular_core.InputSignalWithTransform<boolean, unknown>;
2611
+ readonly filterBy: _angular_core.InputSignal<string | undefined>;
2612
+ readonly filterPlaceholder: _angular_core.InputSignal<string | undefined>;
2613
+ readonly emptyMessage: _angular_core.InputSignal<string>;
2614
+ readonly emptyFilterMessage: _angular_core.InputSignal<string>;
2615
+ /** A "select all" checkbox above the options. */
2616
+ readonly showToggleAll: _angular_core.InputSignalWithTransform<boolean, unknown>;
2617
+ /** How many picks are listed before it says "{0} items selected"; `null` lists them all. */
2618
+ readonly maxSelectedLabels: _angular_core.InputSignal<number | null>;
2619
+ /** The summary past `maxSelectedLabels`; `{0}` is the count. */
2620
+ readonly selectedItemsLabel: _angular_core.InputSignal<string | undefined>;
2621
+ readonly display: _angular_core.InputSignal<"comma" | "chip">;
2622
+ readonly loading: _angular_core.InputSignalWithTransform<boolean, unknown>;
2623
+ readonly showClear: _angular_core.InputSignalWithTransform<boolean, unknown>;
2624
+ readonly scrollHeight: _angular_core.InputSignal<string>;
2625
+ readonly ariaLabel: _angular_core.InputSignal<string | undefined>;
2626
+ readonly inputId: _angular_core.InputSignal<string | undefined>;
2627
+ readonly size: _angular_core.InputSignal<DwControlSize>;
2628
+ readonly fluid: _angular_core.InputSignalWithTransform<boolean, unknown>;
2629
+ /** Stacks the list above this z-index (as dw-dialog / dw-drawer / dw-popover's `baseZIndex`), for a select inside a
2630
+ * layer that sets its own z-index, e.g. a page that hosts crystal in a high layer. 0 = PrimeNG's own stacking. */
2631
+ readonly baseZIndex: _angular_core.InputSignal<number>;
2632
+ readonly opened: _angular_core.OutputEmitterRef<void>;
2633
+ readonly closed: _angular_core.OutputEmitterRef<void>;
2634
+ readonly focused: _angular_core.OutputEmitterRef<void>;
2635
+ readonly blurred: _angular_core.OutputEmitterRef<void>;
2636
+ protected readonly optionTemplate: _angular_core.Signal<DwSelectOptionDirective<any> | undefined>;
2637
+ protected readonly footerTemplate: _angular_core.Signal<DwSelectFooterDirective | undefined>;
2638
+ protected readonly primeSize: _angular_core.Signal<"small" | "large" | undefined>;
2639
+ protected readonly overlayOptions: _angular_core.Signal<{
2640
+ baseZIndex: number;
2641
+ } | undefined>;
2642
+ /** PrimeNG reads a null maxSelectedLabels as 0 (summarise everything), so "list them all" is a ceiling no list reaches. */
2643
+ protected readonly listAll: number;
2644
+ private readonly prime;
2645
+ constructor();
2646
+ /** Opens the list from code. */
2647
+ open(): void;
2648
+ close(): void;
2649
+ static ɵfac: _angular_core.ɵɵFactoryDeclaration<DwMultiselectComponent<any>, never>;
2650
+ static ɵcmp: _angular_core.ɵɵComponentDeclaration<DwMultiselectComponent<any>, "dw-multiselect", never, { "options": { "alias": "options"; "required": false; "isSignal": true; }; "optionLabel": { "alias": "optionLabel"; "required": false; "isSignal": true; }; "optionValue": { "alias": "optionValue"; "required": false; "isSignal": true; }; "optionDisabled": { "alias": "optionDisabled"; "required": false; "isSignal": true; }; "dataKey": { "alias": "dataKey"; "required": false; "isSignal": true; }; "placeholder": { "alias": "placeholder"; "required": false; "isSignal": true; }; "filter": { "alias": "filter"; "required": false; "isSignal": true; }; "filterBy": { "alias": "filterBy"; "required": false; "isSignal": true; }; "filterPlaceholder": { "alias": "filterPlaceholder"; "required": false; "isSignal": true; }; "emptyMessage": { "alias": "emptyMessage"; "required": false; "isSignal": true; }; "emptyFilterMessage": { "alias": "emptyFilterMessage"; "required": false; "isSignal": true; }; "showToggleAll": { "alias": "showToggleAll"; "required": false; "isSignal": true; }; "maxSelectedLabels": { "alias": "maxSelectedLabels"; "required": false; "isSignal": true; }; "selectedItemsLabel": { "alias": "selectedItemsLabel"; "required": false; "isSignal": true; }; "display": { "alias": "display"; "required": false; "isSignal": true; }; "loading": { "alias": "loading"; "required": false; "isSignal": true; }; "showClear": { "alias": "showClear"; "required": false; "isSignal": true; }; "scrollHeight": { "alias": "scrollHeight"; "required": false; "isSignal": true; }; "ariaLabel": { "alias": "ariaLabel"; "required": false; "isSignal": true; }; "inputId": { "alias": "inputId"; "required": false; "isSignal": true; }; "size": { "alias": "size"; "required": false; "isSignal": true; }; "fluid": { "alias": "fluid"; "required": false; "isSignal": true; }; "baseZIndex": { "alias": "baseZIndex"; "required": false; "isSignal": true; }; }, { "opened": "opened"; "closed": "closed"; "focused": "focused"; "blurred": "blurred"; }, ["optionTemplate", "footerTemplate"], never, true, never>;
2651
+ }
2652
+
2653
+ /**
2654
+ * Crystal's checkbox (PrimeNG's Checkbox underneath, which the app never imports). On its own it is on/off: its value
2655
+ * is a boolean. With an `option`, it is one box of a set that fills one array: ticked while the array holds the option,
2656
+ * and clicking adds or removes it (as dw-radio's `option`, for many picks). With a `label` (or projected content) the
2657
+ * label sits beside it on one line and toggles it too.
2658
+ *
2659
+ * ```html
2660
+ * <dw-checkbox label="Remember me" [(ngModel)]="remember" />
2661
+ * @for (f of filters; track f.name) {
2662
+ * <dw-checkbox [option]="f.name" [label]="f.name" [(ngModel)]="selectedFilterNames" />
2663
+ * }
2664
+ * <dw-checkbox formControlName="agree">I accept the <a href="/terms">terms</a></dw-checkbox>
2665
+ * <dw-checkbox ariaLabel="Select row" [indeterminate]="some" [(value)]="all" />
2666
+ * ```
2667
+ */
2668
+ declare class DwCheckboxComponent<T = boolean> extends DwFormControl<T> {
2669
+ /** Makes this box one of a set: the value is an array, and this box stands for this entry of it. */
2670
+ readonly option: _angular_core.InputSignal<unknown>;
2671
+ readonly label: _angular_core.InputSignal<string>;
2672
+ /** For a checkbox with no visible label. */
2673
+ readonly ariaLabel: _angular_core.InputSignal<string | undefined>;
2674
+ /** Id of the native checkbox; generated when omitted. */
2675
+ readonly inputId: _angular_core.InputSignal<string | undefined>;
2676
+ /** The "some, not all" state of a select-all checkbox. */
2677
+ readonly indeterminate: _angular_core.InputSignalWithTransform<boolean, unknown>;
2678
+ readonly size: _angular_core.InputSignal<DwControlSize>;
2679
+ readonly focused: _angular_core.OutputEmitterRef<void>;
2680
+ readonly blurred: _angular_core.OutputEmitterRef<void>;
2681
+ private readonly generatedId;
2682
+ protected readonly id: _angular_core.Signal<string>;
2683
+ protected readonly primeSize: _angular_core.Signal<"small" | "large" | undefined>;
2684
+ private readonly prime;
2685
+ constructor();
2686
+ static ɵfac: _angular_core.ɵɵFactoryDeclaration<DwCheckboxComponent<any>, never>;
2687
+ static ɵcmp: _angular_core.ɵɵComponentDeclaration<DwCheckboxComponent<any>, "dw-checkbox", never, { "option": { "alias": "option"; "required": false; "isSignal": true; }; "label": { "alias": "label"; "required": false; "isSignal": true; }; "ariaLabel": { "alias": "ariaLabel"; "required": false; "isSignal": true; }; "inputId": { "alias": "inputId"; "required": false; "isSignal": true; }; "indeterminate": { "alias": "indeterminate"; "required": false; "isSignal": true; }; "size": { "alias": "size"; "required": false; "isSignal": true; }; }, { "focused": "focused"; "blurred": "blurred"; }, never, ["*"], true, never>;
2688
+ }
2689
+
2690
+ /**
2691
+ * One radio button of a choice (PrimeNG's RadioButton underneath, which the app never imports). Every radio of the
2692
+ * choice binds the same model and `name`; each has its own `option`, and is checked while the model equals it.
2693
+ *
2694
+ * ```html
2695
+ * <dw-radio name="schedule" option="daily" label="Daily" [(ngModel)]="schedule" />
2696
+ * <dw-radio name="schedule" option="weekly" label="Weekly" [(ngModel)]="schedule" />
2697
+ * ```
2698
+ */
2699
+ declare class DwRadioComponent<T = unknown> extends DwFormControl<T> {
2700
+ /** The value this radio stands for: the model takes it when the radio is picked. */
2701
+ readonly option: _angular_core.InputSignal<T>;
2702
+ /** Groups the radios of one choice (keyboard arrows move between them). */
2703
+ readonly name: _angular_core.InputSignal<string | undefined>;
2704
+ readonly label: _angular_core.InputSignal<string>;
2705
+ readonly ariaLabel: _angular_core.InputSignal<string | undefined>;
2706
+ readonly inputId: _angular_core.InputSignal<string | undefined>;
2707
+ readonly size: _angular_core.InputSignal<DwControlSize>;
2708
+ readonly focused: _angular_core.OutputEmitterRef<void>;
2709
+ readonly blurred: _angular_core.OutputEmitterRef<void>;
2710
+ private readonly generatedId;
2711
+ protected readonly id: _angular_core.Signal<string>;
2712
+ protected readonly primeSize: _angular_core.Signal<"small" | "large" | undefined>;
2713
+ private readonly prime;
2714
+ constructor();
2715
+ static ɵfac: _angular_core.ɵɵFactoryDeclaration<DwRadioComponent<any>, never>;
2716
+ static ɵcmp: _angular_core.ɵɵComponentDeclaration<DwRadioComponent<any>, "dw-radio", never, { "option": { "alias": "option"; "required": true; "isSignal": true; }; "name": { "alias": "name"; "required": false; "isSignal": true; }; "label": { "alias": "label"; "required": false; "isSignal": true; }; "ariaLabel": { "alias": "ariaLabel"; "required": false; "isSignal": true; }; "inputId": { "alias": "inputId"; "required": false; "isSignal": true; }; "size": { "alias": "size"; "required": false; "isSignal": true; }; }, { "focused": "focused"; "blurred": "blurred"; }, never, ["*"], true, never>;
2717
+ }
2718
+
2719
+ type DwSwitchSize = 'xs' | 'sm' | 'md';
2720
+ /**
2721
+ * Crystal's on/off switch (PrimeNG's ToggleSwitch underneath, which the app never imports); its value is a boolean.
2722
+ * `sm` sits beside small buttons in a toolbar, `xs` in dense settings rows.
2723
+ *
2724
+ * ```html
2725
+ * <dw-switch label="Enabled" formControlName="enabled" />
2726
+ * <dw-switch size="xs" ariaLabel="Stream responses" [(ngModel)]="stream" (changed)="save()" />
2727
+ * ```
2728
+ */
2729
+ declare class DwSwitchComponent extends DwFormControl<boolean> {
2730
+ readonly label: _angular_core.InputSignal<string>;
2731
+ readonly ariaLabel: _angular_core.InputSignal<string | undefined>;
2732
+ readonly inputId: _angular_core.InputSignal<string | undefined>;
2733
+ readonly size: _angular_core.InputSignal<DwSwitchSize>;
2734
+ /** Shows the state without letting the user change it. */
2735
+ readonly readonly: _angular_core.InputSignalWithTransform<boolean, unknown>;
2736
+ readonly blurred: _angular_core.OutputEmitterRef<void>;
2737
+ private readonly generatedId;
2738
+ protected readonly id: _angular_core.Signal<string>;
2739
+ private readonly prime;
2740
+ constructor();
2741
+ static ɵfac: _angular_core.ɵɵFactoryDeclaration<DwSwitchComponent, never>;
2742
+ static ɵcmp: _angular_core.ɵɵComponentDeclaration<DwSwitchComponent, "dw-switch", never, { "label": { "alias": "label"; "required": false; "isSignal": true; }; "ariaLabel": { "alias": "ariaLabel"; "required": false; "isSignal": true; }; "inputId": { "alias": "inputId"; "required": false; "isSignal": true; }; "size": { "alias": "size"; "required": false; "isSignal": true; }; "readonly": { "alias": "readonly"; "required": false; "isSignal": true; }; }, { "blurred": "blurred"; }, never, never, true, never>;
2743
+ }
2744
+
2745
+ /**
2746
+ * Crystal's number input (PrimeNG's InputNumber underneath, which the app never imports): typed digits only, kept
2747
+ * within `min` / `max`, with optional prefix / suffix text, fraction digits and +/− buttons. Its value is a number.
2748
+ *
2749
+ * ```html
2750
+ * <dw-number-input [min]="1" [max]="100" suffix=" %" formControlName="threshold" />
2751
+ * <dw-number-input size="sm" [showButtons]="true" buttonLayout="horizontal" [(ngModel)]="retries" />
2752
+ * ```
2753
+ */
2754
+ declare class DwNumberInputComponent extends DwFormControl<number> {
2755
+ readonly min: _angular_core.InputSignal<number | null | undefined>;
2756
+ readonly max: _angular_core.InputSignal<number | null | undefined>;
2757
+ /** How far the buttons and arrow keys move it. */
2758
+ readonly step: _angular_core.InputSignal<number>;
2759
+ readonly prefix: _angular_core.InputSignal<string | undefined>;
2760
+ readonly suffix: _angular_core.InputSignal<string | undefined>;
2761
+ readonly minFractionDigits: _angular_core.InputSignal<number | undefined>;
2762
+ readonly maxFractionDigits: _angular_core.InputSignal<number | undefined>;
2763
+ /** Thousands separators (on by default, as in PrimeNG). */
2764
+ readonly useGrouping: _angular_core.InputSignalWithTransform<boolean, unknown>;
2765
+ /** +/− buttons: stacked arrows on the right, or − and + on either side (`horizontal`). */
2766
+ readonly showButtons: _angular_core.InputSignalWithTransform<boolean, unknown>;
2767
+ readonly buttonLayout: _angular_core.InputSignal<"horizontal" | "stacked">;
2768
+ readonly placeholder: _angular_core.InputSignal<string | undefined>;
2769
+ readonly inputId: _angular_core.InputSignal<string | undefined>;
2770
+ readonly ariaLabel: _angular_core.InputSignal<string | undefined>;
2771
+ readonly readonly: _angular_core.InputSignalWithTransform<boolean, unknown>;
2772
+ readonly size: _angular_core.InputSignal<DwControlSize>;
2773
+ readonly fluid: _angular_core.InputSignalWithTransform<boolean, unknown>;
2774
+ readonly focused: _angular_core.OutputEmitterRef<void>;
2775
+ readonly blurred: _angular_core.OutputEmitterRef<void>;
2776
+ protected readonly primeSize: _angular_core.Signal<"small" | "large" | undefined>;
2777
+ private readonly prime;
2778
+ constructor();
2779
+ static ɵfac: _angular_core.ɵɵFactoryDeclaration<DwNumberInputComponent, never>;
2780
+ static ɵcmp: _angular_core.ɵɵComponentDeclaration<DwNumberInputComponent, "dw-number-input", never, { "min": { "alias": "min"; "required": false; "isSignal": true; }; "max": { "alias": "max"; "required": false; "isSignal": true; }; "step": { "alias": "step"; "required": false; "isSignal": true; }; "prefix": { "alias": "prefix"; "required": false; "isSignal": true; }; "suffix": { "alias": "suffix"; "required": false; "isSignal": true; }; "minFractionDigits": { "alias": "minFractionDigits"; "required": false; "isSignal": true; }; "maxFractionDigits": { "alias": "maxFractionDigits"; "required": false; "isSignal": true; }; "useGrouping": { "alias": "useGrouping"; "required": false; "isSignal": true; }; "showButtons": { "alias": "showButtons"; "required": false; "isSignal": true; }; "buttonLayout": { "alias": "buttonLayout"; "required": false; "isSignal": true; }; "placeholder": { "alias": "placeholder"; "required": false; "isSignal": true; }; "inputId": { "alias": "inputId"; "required": false; "isSignal": true; }; "ariaLabel": { "alias": "ariaLabel"; "required": false; "isSignal": true; }; "readonly": { "alias": "readonly"; "required": false; "isSignal": true; }; "size": { "alias": "size"; "required": false; "isSignal": true; }; "fluid": { "alias": "fluid"; "required": false; "isSignal": true; }; }, { "focused": "focused"; "blurred": "blurred"; }, never, never, true, never>;
2781
+ }
2782
+
2783
+ /** What a date picker holds: one date, or a list of them for `selectionMode="range"` (start, end) and `"multiple"`. */
2784
+ type DwDateValue = Date | (Date | null)[];
2785
+ /**
2786
+ * Crystal's date (and time) picker, PrimeNG's DatePicker underneath, which the app never imports. A text field that
2787
+ * opens a calendar appended to `<body>`, or the calendar alone with `inline`. It picks one date, a range or several
2788
+ * dates, optionally with a time. Works with ngModel and reactive forms, inside `dw-field`, or on its own with
2789
+ * `[(value)]`.
2790
+ *
2791
+ * `dateFormat` uses PrimeNG's tokens: `yy` is the four-digit year, `mm` / `M` the month as a number / short name and
2792
+ * `dd` the day, so `"yy-mm-dd"` shows 2026-03-14 and `"M dd, yy"` shows Mar 14, 2026.
2793
+ *
2794
+ * ```html
2795
+ * <dw-date-picker dateFormat="yy-mm-dd" [maxDate]="today" placeholder="Start date" formControlName="start" />
2796
+ * <dw-date-picker [showTime]="true" [showSeconds]="true" [showIcon]="true" [(ngModel)]="runAt" (changed)="save()" />
2797
+ * <dw-date-picker [inline]="true" selectionMode="range" [numberOfMonths]="2" [compact]="true" [(value)]="range" />
2798
+ * <dw-date-picker [inline]="true" [flush]="true" [fluid]="true" [(ngModel)]="expiry" />
2799
+ * ```
2800
+ */
2801
+ declare class DwDatePickerComponent<T extends DwDateValue = Date> extends DwFormControl<T> {
2802
+ readonly placeholder: _angular_core.InputSignal<string | undefined>;
2803
+ /** How the field shows the date, in PrimeNG's tokens (see above); PrimeNG's locale format (`mm/dd/yy`) when omitted. */
2804
+ readonly dateFormat: _angular_core.InputSignal<string | undefined>;
2805
+ /** Picks a time as well as a date. */
2806
+ readonly showTime: _angular_core.InputSignalWithTransform<boolean, unknown>;
2807
+ readonly showSeconds: _angular_core.InputSignalWithTransform<boolean, unknown>;
2808
+ readonly hourFormat: _angular_core.InputSignal<"12" | "24">;
2809
+ /** The earliest and latest dates that can be picked. */
2810
+ readonly minDate: _angular_core.InputSignal<Date | null | undefined>;
2811
+ readonly maxDate: _angular_core.InputSignal<Date | null | undefined>;
2812
+ /** One date, a start and an end (`range`), or any number of dates (`multiple`). */
2813
+ readonly selectionMode: _angular_core.InputSignal<"single" | "range" | "multiple">;
2814
+ /** Shows the calendar itself, always open, instead of a field. */
2815
+ readonly inline: _angular_core.InputSignalWithTransform<boolean, unknown>;
2816
+ readonly numberOfMonths: _angular_core.InputSignalWithTransform<number, unknown>;
2817
+ /** Shows the days of the months before and after, greyed. */
2818
+ readonly showOtherMonths: _angular_core.InputSignalWithTransform<boolean, unknown>;
2819
+ /** A calendar icon: a button beside the field, or drawn inside it (`iconDisplay="input"`). */
2820
+ readonly showIcon: _angular_core.InputSignalWithTransform<boolean, unknown>;
2821
+ readonly iconDisplay: _angular_core.InputSignal<"button" | "input">;
2822
+ /** An × in the field that clears it. */
2823
+ readonly showClear: _angular_core.InputSignalWithTransform<boolean, unknown>;
2824
+ /** Smaller day cells, type and time picker, for a calendar inside a popover or a narrow panel. */
2825
+ readonly compact: _angular_core.InputSignalWithTransform<boolean, unknown>;
2826
+ /**
2827
+ * An inline calendar without a box of its own (border, fill, radius, padding): it sits on its container's surface,
2828
+ * a popover's or a panel's, which pads it. Inline only.
2829
+ */
2830
+ readonly flush: _angular_core.InputSignalWithTransform<boolean, unknown>;
2831
+ /** The calendar's z-index floor, for a picker inside an overlay that sits above crystal's own layers. */
2832
+ readonly baseZIndex: _angular_core.InputSignalWithTransform<number, unknown>;
2833
+ readonly inputId: _angular_core.InputSignal<string | undefined>;
2834
+ readonly ariaLabel: _angular_core.InputSignal<string | undefined>;
2835
+ readonly size: _angular_core.InputSignal<DwControlSize>;
2836
+ /** Fills its container: the field, or the inline calendar. */
2837
+ readonly fluid: _angular_core.InputSignalWithTransform<boolean, unknown>;
2838
+ /** A day (or time) was picked in the calendar; `changed` also follows typing. */
2839
+ readonly selected: _angular_core.OutputEmitterRef<Date>;
2840
+ readonly focused: _angular_core.OutputEmitterRef<void>;
2841
+ readonly blurred: _angular_core.OutputEmitterRef<void>;
2842
+ readonly opened: _angular_core.OutputEmitterRef<void>;
2843
+ readonly closed: _angular_core.OutputEmitterRef<void>;
2844
+ protected readonly primeSize: _angular_core.Signal<"small" | "large" | undefined>;
2845
+ private readonly prime;
2846
+ constructor();
2847
+ static ɵfac: _angular_core.ɵɵFactoryDeclaration<DwDatePickerComponent<any>, never>;
2848
+ static ɵcmp: _angular_core.ɵɵComponentDeclaration<DwDatePickerComponent<any>, "dw-date-picker", never, { "placeholder": { "alias": "placeholder"; "required": false; "isSignal": true; }; "dateFormat": { "alias": "dateFormat"; "required": false; "isSignal": true; }; "showTime": { "alias": "showTime"; "required": false; "isSignal": true; }; "showSeconds": { "alias": "showSeconds"; "required": false; "isSignal": true; }; "hourFormat": { "alias": "hourFormat"; "required": false; "isSignal": true; }; "minDate": { "alias": "minDate"; "required": false; "isSignal": true; }; "maxDate": { "alias": "maxDate"; "required": false; "isSignal": true; }; "selectionMode": { "alias": "selectionMode"; "required": false; "isSignal": true; }; "inline": { "alias": "inline"; "required": false; "isSignal": true; }; "numberOfMonths": { "alias": "numberOfMonths"; "required": false; "isSignal": true; }; "showOtherMonths": { "alias": "showOtherMonths"; "required": false; "isSignal": true; }; "showIcon": { "alias": "showIcon"; "required": false; "isSignal": true; }; "iconDisplay": { "alias": "iconDisplay"; "required": false; "isSignal": true; }; "showClear": { "alias": "showClear"; "required": false; "isSignal": true; }; "compact": { "alias": "compact"; "required": false; "isSignal": true; }; "flush": { "alias": "flush"; "required": false; "isSignal": true; }; "baseZIndex": { "alias": "baseZIndex"; "required": false; "isSignal": true; }; "inputId": { "alias": "inputId"; "required": false; "isSignal": true; }; "ariaLabel": { "alias": "ariaLabel"; "required": false; "isSignal": true; }; "size": { "alias": "size"; "required": false; "isSignal": true; }; "fluid": { "alias": "fluid"; "required": false; "isSignal": true; }; }, { "selected": "selected"; "focused": "focused"; "blurred": "blurred"; "opened": "opened"; "closed": "closed"; }, never, never, true, never>;
2849
+ }
2850
+
2851
+ type DwChartType = 'line' | 'bar' | 'doughnut' | 'pie' | 'polarArea' | 'radar' | 'scatter' | 'bubble';
2852
+ /** A click on a bar, point or slice: the chart.js element and its dataset. */
2853
+ interface DwChartSelectEvent {
2854
+ originalEvent: Event;
2855
+ element: {
2856
+ datasetIndex: number;
2857
+ index: number;
2858
+ };
2859
+ dataset: unknown[];
2860
+ }
2861
+ /**
2862
+ * Crystal's chart: a chart.js canvas (through PrimeNG's Chart, which the app never imports; chart.js comes with
2863
+ * crystal). `data` and `options` are chart.js's own; a new object for either redraws the chart, and so does a new
2864
+ * `type`, size or `plugins`. A canvas cannot read CSS variables, so resolve colours from the tokens first: `cssVar()` and
2865
+ * `chartPalette()` from `@dataworkz/crystal/tokens`.
2866
+ *
2867
+ * The chart fills its container's width and keeps chart.js's aspect ratio, unless it is given a `height` (or the
2868
+ * options say `maintainAspectRatio: false` and the container has one).
2869
+ *
2870
+ * ```html
2871
+ * <dw-chart type="line" [data]="requests()" [options]="lineOptions" />
2872
+ * <dw-chart [type]="kind()" [data]="series()" [options]="options()" height="240px" (dataSelect)="drill($event)" />
2873
+ * ```
2874
+ */
2875
+ declare class DwChartComponent {
2876
+ readonly type: _angular_core.InputSignal<DwChartType>;
2877
+ /** chart.js data: `{ labels, datasets }`. */
2878
+ readonly data: _angular_core.InputSignal<object | null | undefined>;
2879
+ /** chart.js options. */
2880
+ readonly options: _angular_core.InputSignal<object | null | undefined>;
2881
+ /** chart.js plugins for this chart only. */
2882
+ readonly plugins: _angular_core.InputSignal<unknown[]>;
2883
+ /** A CSS width / height for the canvas box (`240px`, `100%`); chart.js sizes it when omitted. */
2884
+ readonly width: _angular_core.InputSignal<string | undefined>;
2885
+ readonly height: _angular_core.InputSignal<string | undefined>;
2886
+ /** Redraws the chart when its container resizes. */
2887
+ readonly responsive: _angular_core.InputSignalWithTransform<boolean, unknown>;
2888
+ readonly ariaLabel: _angular_core.InputSignal<string | undefined>;
2889
+ /** A bar, point or slice was clicked. */
2890
+ readonly dataSelect: _angular_core.OutputEmitterRef<DwChartSelectEvent>;
2891
+ private readonly prime;
2892
+ constructor();
2893
+ /** Redraws the chart in place (animating), after the app changed `data` or `options` without a new object. */
2894
+ refresh(): void;
2895
+ static ɵfac: _angular_core.ɵɵFactoryDeclaration<DwChartComponent, never>;
2896
+ static ɵcmp: _angular_core.ɵɵComponentDeclaration<DwChartComponent, "dw-chart", never, { "type": { "alias": "type"; "required": true; "isSignal": true; }; "data": { "alias": "data"; "required": false; "isSignal": true; }; "options": { "alias": "options"; "required": false; "isSignal": true; }; "plugins": { "alias": "plugins"; "required": false; "isSignal": true; }; "width": { "alias": "width"; "required": false; "isSignal": true; }; "height": { "alias": "height"; "required": false; "isSignal": true; }; "responsive": { "alias": "responsive"; "required": false; "isSignal": true; }; "ariaLabel": { "alias": "ariaLabel"; "required": false; "isSignal": true; }; }, { "dataSelect": "dataSelect"; }, never, never, true, never>;
2897
+ }
2898
+
2899
+ /**
2900
+ * A node of a `dw-tree`. `children` are its sub-nodes; a node with `leaf: false` and no children yet shows an expand
2901
+ * toggle, for children loaded when it opens (`nodeExpand`). The tree sets `expanded`, `parent` and, for checkboxes,
2902
+ * `partialSelected` as the user works it.
2903
+ */
2904
+ interface DwTreeNode<T = unknown> {
2905
+ /** Unique among the tree's nodes; selection and re-renders match nodes by it. */
2906
+ key?: string;
2907
+ label?: string;
2908
+ data?: T;
2909
+ /** A `pi pi-…` icon before the label; `expandedIcon` / `collapsedIcon` swap it as the node opens. */
2910
+ icon?: string;
2911
+ expandedIcon?: string;
2912
+ collapsedIcon?: string;
2913
+ children?: DwTreeNode<T>[];
2914
+ /** `false`: can be expanded although it has no children yet. */
2915
+ leaf?: boolean;
2916
+ expanded?: boolean;
2917
+ /** `false`: shown, but cannot be selected. */
2918
+ selectable?: boolean;
2919
+ /** Shows a spinner in place of the toggle while its children load. */
2920
+ loading?: boolean;
2921
+ partialSelected?: boolean;
2922
+ parent?: DwTreeNode<T>;
2923
+ /** A class on the node's row, for the screen's own layout of its content. */
2924
+ styleClass?: string;
2925
+ }
2926
+ /** The node a `dw-tree` event is about, with the browser event that caused it. */
2927
+ interface DwTreeNodeEvent<T = unknown> {
2928
+ originalEvent: Event;
2929
+ node: DwTreeNode<T>;
2930
+ }
2931
+ /** What a tree selects: one node (`single`), or a list of them (`multiple`, `checkbox`). */
2932
+ type DwTreeSelection<T = unknown> = DwTreeNode<T> | DwTreeNode<T>[] | null;
2933
+ /**
2934
+ * A node's content, instead of its label: `<ng-template dwTreeNode let-node>…</ng-template>`. `node` is the
2935
+ * `DwTreeNode`, untyped in the template (as in PrimeNG's own), so it can read the screen's own `data`.
2936
+ */
2937
+ declare class DwTreeNodeDirective {
2938
+ readonly template: TemplateRef<{
2939
+ $implicit: DwTreeNode;
2940
+ }>;
2941
+ static ɵfac: _angular_core.ɵɵFactoryDeclaration<DwTreeNodeDirective, never>;
2942
+ static ɵdir: _angular_core.ɵɵDirectiveDeclaration<DwTreeNodeDirective, "ng-template[dwTreeNode]", never, {}, {}, never, never, true, never>;
2943
+ }
2944
+ /**
2945
+ * Crystal's tree, PrimeNG's Tree underneath, which the app never imports. Nodes open and close with their toggle or the
2946
+ * arrow keys; a tree can select one node, several (with modifier keys), or check them (`checkbox`, where checking a
2947
+ * parent checks its children and a parent of partly checked children shows a dash).
2948
+ *
2949
+ * Children can load when a node opens: give it `leaf: false`, then fill `children` in `nodeExpand` (set `loading` on
2950
+ * the node meanwhile). `contextMenu` takes a `dw-menu` (`trigger="none"`) that opens at the pointer on right-click, its
2951
+ * commands receiving the node.
2952
+ *
2953
+ * The tree has no box of its own and sits on its container; `framed` gives it a border and padding, and
2954
+ * `scrollHeight` a height after which it scrolls. `size="sm"` makes rows compact (a smaller toggle and type), for a
2955
+ * sidebar or a narrow panel; `marker` adds an accent bar to the selected row, as on `dw-nav-list`. `.dw-tree` (no `-view`) is the markup-only guide-line tree for
2956
+ * hand-built lists.
2957
+ *
2958
+ * ```html
2959
+ * <dw-tree [value]="folders" selectionMode="single" [(selection)]="folder" (nodeExpand)="loadChildren($event.node)" />
2960
+ * <dw-tree [value]="privileges" selectionMode="checkbox" [(selection)]="granted" scrollHeight="320px" [framed]="true" />
2961
+ * <dw-tree [value]="dirs" [contextMenu]="dirMenu" ariaLabel="Directories">
2962
+ * <ng-template dwTreeNode let-node><span class="dw-truncate">{{ node.label }}</span></ng-template>
2963
+ * </dw-tree>
2964
+ * <dw-menu #dirMenu [items]="dirActions" trigger="none" />
2965
+ * ```
2966
+ */
2967
+ declare class DwTreeComponent<T = unknown> {
2968
+ readonly value: _angular_core.InputSignal<DwTreeNode<T>[] | null | undefined>;
2969
+ /** No selection (`null`), one node, several with Ctrl / Cmd and Shift (`multiple`), or checkboxes. */
2970
+ readonly selectionMode: _angular_core.InputSignal<"single" | "multiple" | "checkbox" | null>;
2971
+ /** The selected node, or nodes (`multiple`, `checkbox`). */
2972
+ readonly selection: _angular_core.ModelSignal<DwTreeSelection<T>>;
2973
+ /** Checkboxes: checking a node checks its children, and its parent once all of them are. */
2974
+ readonly propagateSelection: _angular_core.InputSignalWithTransform<boolean, unknown>;
2975
+ /** A loading state for the whole tree, its nodes dimmed under a spinner (`mask`), or a spinner beside them (`icon`). */
2976
+ readonly loading: _angular_core.InputSignalWithTransform<boolean, unknown>;
2977
+ readonly loadingMode: _angular_core.InputSignal<"mask" | "icon">;
2978
+ /** A CSS height after which the tree scrolls (`320px`, `calc(100vh - 250px)`); it grows with its nodes when omitted. */
2979
+ readonly scrollHeight: _angular_core.InputSignal<string | undefined>;
2980
+ /** Shown when there are no nodes. */
2981
+ readonly emptyMessage: _angular_core.InputSignal<string>;
2982
+ readonly ariaLabel: _angular_core.InputSignal<string | undefined>;
2983
+ /** A border, radius and padding around the tree, for one that is not already inside a framed surface. */
2984
+ readonly framed: _angular_core.InputSignalWithTransform<boolean, unknown>;
2985
+ /** `sm`: compact rows (smaller toggle, padding and type), for a sidebar or a narrow panel. */
2986
+ readonly size: _angular_core.InputSignal<"sm" | "md">;
2987
+ /** An accent bar at the start of the selected row (or rows), as `dw-nav-list`'s `marker`. */
2988
+ readonly marker: _angular_core.InputSignalWithTransform<boolean, unknown>;
2989
+ /** A `dw-menu` (`trigger="none"`) opened at the pointer when a node is right-clicked; its commands get the node. */
2990
+ readonly contextMenu: _angular_core.InputSignal<DwMenuComponent<DwTreeNode<T>> | undefined>;
2991
+ readonly nodeSelect: _angular_core.OutputEmitterRef<DwTreeNodeEvent<T>>;
2992
+ readonly nodeUnselect: _angular_core.OutputEmitterRef<DwTreeNodeEvent<T>>;
2993
+ /** A node opened: the moment to load its children. */
2994
+ readonly nodeExpand: _angular_core.OutputEmitterRef<DwTreeNodeEvent<T>>;
2995
+ readonly nodeCollapse: _angular_core.OutputEmitterRef<DwTreeNodeEvent<T>>;
2996
+ /** A node was right-clicked, with `contextMenu` set; the menu is opening. */
2997
+ readonly nodeContextMenu: _angular_core.OutputEmitterRef<DwTreeNodeEvent<T>>;
2998
+ protected readonly nodeTemplate: _angular_core.Signal<DwTreeNodeDirective | undefined>;
2999
+ /**
3000
+ * PrimeNG shows its context menu itself, before saying which node it is for; it gets this stand-in, and the
3001
+ * `dw-menu` opens once the node is known (`openMenu`).
3002
+ */
3003
+ protected readonly menuBridge: _angular_core.Signal<{
3004
+ show: () => undefined;
3005
+ hide: () => void | undefined;
3006
+ } | undefined>;
3007
+ protected openMenu(event: DwTreeNodeEvent<T>): void;
3008
+ static ɵfac: _angular_core.ɵɵFactoryDeclaration<DwTreeComponent<any>, never>;
3009
+ static ɵcmp: _angular_core.ɵɵComponentDeclaration<DwTreeComponent<any>, "dw-tree", never, { "value": { "alias": "value"; "required": false; "isSignal": true; }; "selectionMode": { "alias": "selectionMode"; "required": false; "isSignal": true; }; "selection": { "alias": "selection"; "required": false; "isSignal": true; }; "propagateSelection": { "alias": "propagateSelection"; "required": false; "isSignal": true; }; "loading": { "alias": "loading"; "required": false; "isSignal": true; }; "loadingMode": { "alias": "loadingMode"; "required": false; "isSignal": true; }; "scrollHeight": { "alias": "scrollHeight"; "required": false; "isSignal": true; }; "emptyMessage": { "alias": "emptyMessage"; "required": false; "isSignal": true; }; "ariaLabel": { "alias": "ariaLabel"; "required": false; "isSignal": true; }; "framed": { "alias": "framed"; "required": false; "isSignal": true; }; "size": { "alias": "size"; "required": false; "isSignal": true; }; "marker": { "alias": "marker"; "required": false; "isSignal": true; }; "contextMenu": { "alias": "contextMenu"; "required": false; "isSignal": true; }; }, { "selection": "selectionChange"; "nodeSelect": "nodeSelect"; "nodeUnselect": "nodeUnselect"; "nodeExpand": "nodeExpand"; "nodeCollapse": "nodeCollapse"; "nodeContextMenu": "nodeContextMenu"; }, ["nodeTemplate"], never, true, never>;
3010
+ }
3011
+
3012
+ /** `flush`: rows on their container with a divider between panels; `card`: each panel its own bordered card. */
3013
+ /** What PrimeNG's Accordion and its panels take as a value. */
3014
+ type PrimeAccordionValue = string | number | string[] | number[] | null | undefined;
3015
+ type DwAccordionVariant = 'flush' | 'card';
3016
+ /** What a `dw-accordion` holds open: one panel's value, or a list of them (`multiple`); `null` when none. */
3017
+ type DwAccordionValue<V = unknown> = V | V[] | null;
3018
+ /** A panel the user opened or closed: its `value` (its index when it has none) and its index among the panels. */
3019
+ interface DwAccordionToggleEvent<V = unknown> {
3020
+ value: V;
3021
+ index: number;
3022
+ }
3023
+ /** What a header template gets: `let-active` (or `let-open`, the implicit value) is whether the panel is open. */
3024
+ interface DwAccordionHeaderContext {
3025
+ $implicit: boolean;
3026
+ active: boolean;
3027
+ }
3028
+ /**
3029
+ * A panel's header row, instead of its `header` text: `<ng-template dwAccordionHeader let-open>…</ng-template>`.
3030
+ * Clicking the row toggles the panel; mark controls inside it with `dwAccordionHeaderAction` so they don't.
3031
+ */
3032
+ declare class DwAccordionHeaderDirective {
3033
+ readonly template: TemplateRef<DwAccordionHeaderContext>;
3034
+ static ɵfac: _angular_core.ɵɵFactoryDeclaration<DwAccordionHeaderDirective, never>;
3035
+ static ɵdir: _angular_core.ɵɵDirectiveDeclaration<DwAccordionHeaderDirective, "ng-template[dwAccordionHeader]", never, {}, {}, never, never, true, never>;
3036
+ }
3037
+ /**
3038
+ * A panel's content, created the first time the panel opens (and kept, so a form in it keeps its state):
3039
+ * `<ng-template dwAccordionContent>…</ng-template>`. Content placed directly in the panel is created up front.
3040
+ */
3041
+ declare class DwAccordionContentDirective {
3042
+ readonly template: TemplateRef<unknown>;
3043
+ static ɵfac: _angular_core.ɵɵFactoryDeclaration<DwAccordionContentDirective, never>;
3044
+ static ɵdir: _angular_core.ɵɵDirectiveDeclaration<DwAccordionContentDirective, "ng-template[dwAccordionContent]", never, {}, {}, never, never, true, never>;
3045
+ }
3046
+ /**
3047
+ * Marks a control inside a panel's header (a menu button, an editable title, a switch) whose clicks and keys belong to
3048
+ * it: they don't toggle the panel, and the header's own keys (Enter, Space, the arrows) don't reach the panel.
3049
+ */
3050
+ declare class DwAccordionHeaderActionDirective {
3051
+ protected stop(event: Event): void;
3052
+ static ɵfac: _angular_core.ɵɵFactoryDeclaration<DwAccordionHeaderActionDirective, never>;
3053
+ static ɵdir: _angular_core.ɵɵDirectiveDeclaration<DwAccordionHeaderActionDirective, "[dwAccordionHeaderAction]", never, {}, {}, never, never, true, never>;
3054
+ }
3055
+ /**
3056
+ * One panel of a `dw-accordion`: a header row (`header` text, or a `dwAccordionHeader` template) over its content.
3057
+ * The accordion renders it; the panel element itself is not placed in the page, so style its content, not the tag.
3058
+ */
3059
+ declare class DwAccordionPanelComponent<V = unknown> {
3060
+ /** What `value` of the accordion holds while this panel is open; its index among the panels when omitted. */
3061
+ readonly value: _angular_core.InputSignal<V | undefined>;
3062
+ /** The header's text, when there is no `dwAccordionHeader` template. */
3063
+ readonly header: _angular_core.InputSignal<string>;
3064
+ /** Shown, but cannot be opened or closed. */
3065
+ readonly disabled: _angular_core.InputSignalWithTransform<boolean, unknown>;
3066
+ readonly testId: _angular_core.InputSignal<string | null>;
3067
+ readonly headerTemplate: _angular_core.Signal<DwAccordionHeaderDirective | undefined>;
3068
+ readonly lazyContent: _angular_core.Signal<DwAccordionContentDirective | undefined>;
3069
+ readonly body: _angular_core.Signal<TemplateRef<unknown>>;
3070
+ /** Whether the panel has been open once, so its lazy content stays created. */
3071
+ readonly loaded: _angular_core.WritableSignal<boolean>;
3072
+ static ɵfac: _angular_core.ɵɵFactoryDeclaration<DwAccordionPanelComponent<any>, never>;
3073
+ static ɵcmp: _angular_core.ɵɵComponentDeclaration<DwAccordionPanelComponent<any>, "dw-accordion-panel", never, { "value": { "alias": "value"; "required": false; "isSignal": true; }; "header": { "alias": "header"; "required": false; "isSignal": true; }; "disabled": { "alias": "disabled"; "required": false; "isSignal": true; }; "testId": { "alias": "testId"; "required": false; "isSignal": true; }; }, {}, ["headerTemplate", "lazyContent"], ["*"], true, never>;
3074
+ }
3075
+ /**
3076
+ * Crystal's accordion, PrimeNG's Accordion underneath, which the app never imports: panels that open and close under
3077
+ * their header row, one at a time or several (`multiple`). `[(value)]` is what is open, by each panel's `value` (its
3078
+ * index when it has none). `opened` / `closed` say which panel the user opened or closed, once its animation is done,
3079
+ * so content that measures itself (an editor, a chart) can refresh then.
3080
+ *
3081
+ * Headers are buttons (Enter or Space toggles, the arrow keys, Home and End move between them), each controlling its
3082
+ * region. A header template can hold controls of its own: mark them `dwAccordionHeaderAction` (or stop the event's
3083
+ * propagation) so using them doesn't toggle the panel. `dwAccordionContent` creates a panel's content the first time
3084
+ * it opens.
3085
+ *
3086
+ * `variant="flush"` (default) lays the panels on their container with a divider between them; `card` makes each one
3087
+ * a bordered card, the list spaced, a divider under the header while it is open.
3088
+ *
3089
+ * ```html
3090
+ * <dw-accordion [multiple]="true" [(value)]="open" variant="card" (opened)="load($event.value)">
3091
+ * @for (tool of tools; track tool.id) {
3092
+ * <dw-accordion-panel [value]="tool.id">
3093
+ * <ng-template dwAccordionHeader>
3094
+ * <span class="dw-truncate">{{ tool.name }}</span>
3095
+ * <dw-icon-button dwAccordionHeaderAction icon="pi pi-ellipsis-v" ariaLabel="More" (clicked)="menu.toggle($event)" />
3096
+ * </ng-template>
3097
+ * <ng-template dwAccordionContent><app-tool-form [tool]="tool" /></ng-template>
3098
+ * </dw-accordion-panel>
3099
+ * }
3100
+ * </dw-accordion>
3101
+ * ```
3102
+ */
3103
+ declare class DwAccordionComponent<V = unknown> {
3104
+ /** Several panels open at once; `value` is then a list. */
3105
+ readonly multiple: _angular_core.InputSignalWithTransform<boolean, unknown>;
3106
+ /** The open panel's value (a list of them with `multiple`); `null` when none is open. */
3107
+ readonly value: _angular_core.ModelSignal<DwAccordionValue<V>>;
3108
+ readonly variant: _angular_core.InputSignal<DwAccordionVariant>;
3109
+ /** The user opened a panel; emitted once it has finished opening. */
3110
+ readonly opened: OutputEmitterRef<DwAccordionToggleEvent<V>>;
3111
+ /** The user closed a panel; emitted once it has finished closing. */
3112
+ readonly closed: OutputEmitterRef<DwAccordionToggleEvent<V>>;
3113
+ protected readonly panels: _angular_core.Signal<readonly DwAccordionPanelComponent<V>[]>;
3114
+ /** Crystal's motion (`--dw-dur-pop`, `--dw-ease`) for the open and close animation. */
3115
+ protected readonly transition = "240ms cubic-bezier(0.2, 0.6, 0.2, 1)";
3116
+ private readonly host;
3117
+ private readonly injector;
3118
+ private destroyed;
3119
+ constructor();
3120
+ /** PrimeNG types panel values as strings and numbers; it only compares them, so the panels' own values pass through. */
3121
+ protected readonly primeValue: _angular_core.Signal<PrimeAccordionValue>;
3122
+ protected primeKey(panel: DwAccordionPanelComponent<V>, index: number): string | number;
3123
+ protected onPrimeValueChange(next: PrimeAccordionValue): void;
3124
+ protected keyOf(panel: DwAccordionPanelComponent<V>, index: number): V;
3125
+ protected isOpen(key: V): boolean;
3126
+ /** PrimeNG changed what is open (a header clicked, or Enter / Space on it): say which panels opened and closed. */
3127
+ protected onValueChange(next: DwAccordionValue<V> | undefined): void;
3128
+ private openKeys;
3129
+ /** Emits once the panel's open / close animation (if any) has finished. */
3130
+ private emitWhenSettled;
3131
+ static ɵfac: _angular_core.ɵɵFactoryDeclaration<DwAccordionComponent<any>, never>;
3132
+ static ɵcmp: _angular_core.ɵɵComponentDeclaration<DwAccordionComponent<any>, "dw-accordion", never, { "multiple": { "alias": "multiple"; "required": false; "isSignal": true; }; "value": { "alias": "value"; "required": false; "isSignal": true; }; "variant": { "alias": "variant"; "required": false; "isSignal": true; }; }, { "value": "valueChange"; "opened": "opened"; "closed": "closed"; }, ["panels"], never, true, never>;
3133
+ }
3134
+ /** Everything an accordion is built from: `imports: [...DW_ACCORDION]`. */
3135
+ declare const DW_ACCORDION: readonly [typeof DwAccordionComponent, typeof DwAccordionPanelComponent, typeof DwAccordionHeaderDirective, typeof DwAccordionContentDirective, typeof DwAccordionHeaderActionDirective];
3136
+
3137
+ type DwStepValue = string | number;
3138
+ interface DwStep<V extends DwStepValue = DwStepValue> {
3139
+ value: V;
3140
+ label: string;
3141
+ /** Can't be chosen, whatever `linear` says. */
3142
+ disabled?: boolean;
3143
+ }
3144
+ /**
3145
+ * Step indicator for a wizard: numbered steps joined by connector lines, each step done (before the
3146
+ * current one), current (`aria-current="step"`) or upcoming. A done step stays clickable, to go back.
3147
+ * It draws the step list only; the wizard shows its own panels for `value`.
3148
+ *
3149
+ * - `linear`: the steps after the current one can't be chosen (the wizard moves forward with its own Next).
3150
+ * - Arrow keys, Home and End move focus between the steps that can be chosen; Enter or Space chooses one.
3151
+ * - `framed` adds the sub-header strip (padding and a bottom rule) for a drawer or panel top.
3152
+ *
3153
+ * ```html
3154
+ * <dw-stepper [steps]="[{ value: 1, label: 'Source' }, { value: 2, label: 'Target' }]" [(value)]="step" [linear]="true" />
3155
+ * <dw-stepper dwDrawerSubheader [steps]="steps" [value]="step" size="sm" [framed]="true" doneIcon="check" />
3156
+ * ```
3157
+ */
3158
+ declare class DwStepperComponent {
3159
+ readonly steps: _angular_core.InputSignal<readonly DwStep<DwStepValue>[]>;
3160
+ /** The current step's value. Two-way: `[(value)]`, or `[value]` + `(valueChange)`. */
3161
+ readonly value: _angular_core.ModelSignal<DwStepValue | null>;
3162
+ /** Only the current step and the ones before it can be chosen. */
3163
+ readonly linear: _angular_core.InputSignal<boolean>;
3164
+ /** Every step is locked (a wizard that is saving). */
3165
+ readonly disabled: _angular_core.InputSignal<boolean>;
3166
+ /** `md` (32px numbers, a wizard header) or `sm` (24px, a drawer sub-header). */
3167
+ readonly size: _angular_core.InputSignal<"sm" | "md">;
3168
+ /** Sub-header strip: padding and a bottom rule around the steps. */
3169
+ readonly framed: _angular_core.InputSignal<boolean>;
3170
+ /** PrimeIcons name (`check`) shown in place of the number of a done step. */
3171
+ readonly doneIcon: _angular_core.InputSignal<"" | DwPrimeIcon>;
3172
+ readonly ariaLabel: _angular_core.InputSignal<string>;
3173
+ private readonly buttons;
3174
+ readonly activeIndex: _angular_core.Signal<number>;
3175
+ readonly listClass: _angular_core.Signal<string>;
3176
+ /** Locked by its own `disabled` or the stepper's (drawn faded), as opposed to an upcoming step of a linear stepper. */
3177
+ isBlocked(index: number): boolean;
3178
+ isStepDisabled(index: number): boolean;
3179
+ select(index: number): void;
3180
+ onKeydown(event: KeyboardEvent, index: number): void;
3181
+ static ɵfac: _angular_core.ɵɵFactoryDeclaration<DwStepperComponent, never>;
3182
+ static ɵcmp: _angular_core.ɵɵComponentDeclaration<DwStepperComponent, "dw-stepper", never, { "steps": { "alias": "steps"; "required": false; "isSignal": true; }; "value": { "alias": "value"; "required": false; "isSignal": true; }; "linear": { "alias": "linear"; "required": false; "isSignal": true; }; "disabled": { "alias": "disabled"; "required": false; "isSignal": true; }; "size": { "alias": "size"; "required": false; "isSignal": true; }; "framed": { "alias": "framed"; "required": false; "isSignal": true; }; "doneIcon": { "alias": "doneIcon"; "required": false; "isSignal": true; }; "ariaLabel": { "alias": "ariaLabel"; "required": false; "isSignal": true; }; }, { "value": "valueChange"; }, never, never, true, never>;
3183
+ }
3184
+
3185
+ /** What the user typed, sent when the suggestions should be (re)computed. `query` is `''` from the dropdown button. */
3186
+ interface DwAutocompleteSearchEvent {
3187
+ query: string;
3188
+ originalEvent: Event;
3189
+ }
3190
+ /**
3191
+ * How the suggestion list is sized: as wide as the field, long suggestions ending in an ellipsis (`field`, crystal's
3192
+ * select rule), or at least as wide as the field and wider for long suggestions (`auto`).
3193
+ */
3194
+ type DwAutocompletePanelWidth = 'field' | 'auto';
3195
+ /**
3196
+ * A suggestion's content, instead of its label: `<ng-template dwAutocompleteItem let-item>…</ng-template>`. `item` is
3197
+ * the suggestion, untyped in the template (as in PrimeNG's own), so it can read the screen's own fields.
3198
+ */
3199
+ declare class DwAutocompleteItemDirective {
3200
+ readonly template: TemplateRef<{
3201
+ $implicit: unknown;
3202
+ index: number;
3203
+ }>;
3204
+ static ɵfac: _angular_core.ɵɵFactoryDeclaration<DwAutocompleteItemDirective, never>;
3205
+ static ɵdir: _angular_core.ɵɵDirectiveDeclaration<DwAutocompleteItemDirective, "ng-template[dwAutocompleteItem]", never, {}, {}, never, never, true, never>;
3206
+ }
3207
+ /**
3208
+ * Crystal's autocomplete, PrimeNG's AutoComplete underneath, which the app never imports. A text field that suggests
3209
+ * as the user types: on `search` the screen filters its own list and passes the matches back as `suggestions`, shown
3210
+ * in a list appended to `<body>`. The value is what the user typed, or the suggestion they picked (its `value` field
3211
+ * when it has one, else the suggestion itself); `forceSelection` clears typed text that matches no suggestion. Works
3212
+ * with ngModel and reactive forms, inside `dw-field`, or on its own with `[(value)]`.
3213
+ *
3214
+ * `size="sm"` gives the list the small select rows too, and `panelWidth="field"` (the default) keeps it exactly as wide
3215
+ * as the field. `testId` lands on the text input.
3216
+ *
3217
+ * ```html
3218
+ * <dw-autocomplete formControlName="mimeType" [suggestions]="mimeMatches" [dropdown]="true" (search)="filter($event.query)"
3219
+ * placeholder="Search or add…" testId="mime-type-autocomplete" [fluid]="true" />
3220
+ * <dw-autocomplete #tags size="sm" [(ngModel)]="text" [suggestions]="tagMatches" optionLabel="name" [dropdown]="true"
3221
+ * [showEmptyMessage]="false" (search)="searchTags($event)" (selected)="pick($event)" (keydown.esc)="tags.hide()">
3222
+ * <ng-template dwAutocompleteItem let-tag><dw-tag [label]="tag.name" [color]="tag.color" /></ng-template>
3223
+ * </dw-autocomplete>
3224
+ * ```
3225
+ */
3226
+ declare class DwAutocompleteComponent<T = unknown> extends DwFormControl<T | string> {
3227
+ /** The suggestions to show for the last `search`: strings, or objects shown by `optionLabel` (or their `label`). */
3228
+ readonly suggestions: _angular_core.InputSignal<T[] | null | undefined>;
3229
+ /** The suggestion field to show; a suggestion's `label`, or the suggestion itself, when omitted. */
3230
+ readonly optionLabel: _angular_core.InputSignal<string | undefined>;
3231
+ /** A button beside the field that shows every suggestion (a `search` with an empty query). */
3232
+ readonly dropdown: _angular_core.InputSignalWithTransform<boolean, unknown>;
3233
+ /** Only a picked suggestion is a value: typed text that matches none is cleared when the field loses focus. */
3234
+ readonly forceSelection: _angular_core.InputSignalWithTransform<boolean, unknown>;
3235
+ /** Shows `emptyMessage` when a search finds nothing; off, the list just stays closed. */
3236
+ readonly showEmptyMessage: _angular_core.InputSignalWithTransform<boolean, unknown>;
3237
+ /** PrimeNG's locale text ("No results found") when omitted. */
3238
+ readonly emptyMessage: _angular_core.InputSignal<string | undefined>;
3239
+ readonly placeholder: _angular_core.InputSignal<string | undefined>;
3240
+ readonly ariaLabel: _angular_core.InputSignal<string | undefined>;
3241
+ /** Id of the text input, for a `<label for>` outside dw-field. */
3242
+ readonly inputId: _angular_core.InputSignal<string | undefined>;
3243
+ /** Milliseconds after the last keystroke before `search` is sent. */
3244
+ readonly delay: _angular_core.InputSignalWithTransform<number, unknown>;
3245
+ /** Characters typed before a `search` is sent. */
3246
+ readonly minLength: _angular_core.InputSignalWithTransform<number, unknown>;
3247
+ readonly size: _angular_core.InputSignal<DwControlSize>;
3248
+ /** Fills the width of its container. */
3249
+ readonly fluid: _angular_core.InputSignalWithTransform<boolean, unknown>;
3250
+ readonly panelWidth: _angular_core.InputSignal<DwAutocompletePanelWidth>;
3251
+ /** Stacks the list above this z-index, for a field inside a layer that sets its own (as dw-select's). */
3252
+ readonly baseZIndex: _angular_core.InputSignalWithTransform<number, unknown>;
3253
+ /** `data-testid` on the text input. */
3254
+ readonly testId: _angular_core.InputSignal<string | null | undefined>;
3255
+ /** The suggestions are wanted for this query: set `suggestions` in reply. */
3256
+ readonly search: _angular_core.OutputEmitterRef<DwAutocompleteSearchEvent>;
3257
+ /** A suggestion was picked from the list; `changed` also follows typing. */
3258
+ readonly selected: _angular_core.OutputEmitterRef<T>;
3259
+ /** A key went down in the text input, before the autocomplete handles it. */
3260
+ readonly inputKeydown: _angular_core.OutputEmitterRef<KeyboardEvent>;
3261
+ readonly focused: _angular_core.OutputEmitterRef<void>;
3262
+ readonly blurred: _angular_core.OutputEmitterRef<void>;
3263
+ readonly opened: _angular_core.OutputEmitterRef<void>;
3264
+ readonly closed: _angular_core.OutputEmitterRef<void>;
3265
+ protected readonly itemTemplate: _angular_core.Signal<DwAutocompleteItemDirective | undefined>;
3266
+ protected readonly primeSize: _angular_core.Signal<"small" | "large" | undefined>;
3267
+ protected readonly overlayOptions: _angular_core.Signal<{
3268
+ baseZIndex: number;
3269
+ } | undefined>;
3270
+ protected readonly panelClass: _angular_core.Signal<string>;
3271
+ private readonly prime;
3272
+ private readonly host;
3273
+ constructor();
3274
+ /** Opens the suggestion list (with the suggestions it has). */
3275
+ show(): void;
3276
+ /** Closes the suggestion list. */
3277
+ hide(): void;
3278
+ static ɵfac: _angular_core.ɵɵFactoryDeclaration<DwAutocompleteComponent<any>, never>;
3279
+ static ɵcmp: _angular_core.ɵɵComponentDeclaration<DwAutocompleteComponent<any>, "dw-autocomplete", never, { "suggestions": { "alias": "suggestions"; "required": false; "isSignal": true; }; "optionLabel": { "alias": "optionLabel"; "required": false; "isSignal": true; }; "dropdown": { "alias": "dropdown"; "required": false; "isSignal": true; }; "forceSelection": { "alias": "forceSelection"; "required": false; "isSignal": true; }; "showEmptyMessage": { "alias": "showEmptyMessage"; "required": false; "isSignal": true; }; "emptyMessage": { "alias": "emptyMessage"; "required": false; "isSignal": true; }; "placeholder": { "alias": "placeholder"; "required": false; "isSignal": true; }; "ariaLabel": { "alias": "ariaLabel"; "required": false; "isSignal": true; }; "inputId": { "alias": "inputId"; "required": false; "isSignal": true; }; "delay": { "alias": "delay"; "required": false; "isSignal": true; }; "minLength": { "alias": "minLength"; "required": false; "isSignal": true; }; "size": { "alias": "size"; "required": false; "isSignal": true; }; "fluid": { "alias": "fluid"; "required": false; "isSignal": true; }; "panelWidth": { "alias": "panelWidth"; "required": false; "isSignal": true; }; "baseZIndex": { "alias": "baseZIndex"; "required": false; "isSignal": true; }; "testId": { "alias": "testId"; "required": false; "isSignal": true; }; }, { "search": "search"; "selected": "selected"; "inputKeydown": "inputKeydown"; "focused": "focused"; "blurred": "blurred"; "opened": "opened"; "closed": "closed"; }, ["itemTemplate"], never, true, never>;
3280
+ }
3281
+
3282
+ /**
3283
+ * Crystal's slider, PrimeNG's Slider underneath, which the app never imports: a track with a handle that picks a number
3284
+ * between `min` and `max`, in `step`s, by dragging, clicking the track or the arrow / Page / Home / End keys. Its value is
3285
+ * a number. Works with ngModel and reactive forms, inside `dw-field`, or on its own with `[(value)]`.
3286
+ *
3287
+ * The slider fills its container's width (or, `vertical`, a height the screen gives it, 100px at least). It draws no
3288
+ * value of its own: the screen shows it where it reads best, e.g. a `dw-badge` beside its label. `changed` follows
3289
+ * every step of a drag; `slideEnd` fires once the handle is let go, for work too heavy to do on every step.
3290
+ *
3291
+ * ```html
3292
+ * <dw-slider [min]="1" [max]="20" ariaLabel="Simultaneous OCR page reads" formControlName="ocrParallel" />
3293
+ * <dw-slider [min]="0" [max]="1" [step]="0.1" [(ngModel)]="temperature" (slideEnd)="save($event)" />
3294
+ * ```
3295
+ */
3296
+ declare class DwSliderComponent extends DwFormControl<number> {
3297
+ readonly min: _angular_core.InputSignalWithTransform<number, unknown>;
3298
+ readonly max: _angular_core.InputSignalWithTransform<number, unknown>;
3299
+ /**
3300
+ * The increment a drag snaps to and a key press moves by (fractions allowed: `0.1`). Omitted, a drag picks whole
3301
+ * numbers and the arrow keys move by 1, Page Up / Down by 10.
3302
+ */
3303
+ readonly step: _angular_core.InputSignal<number | undefined>;
3304
+ readonly orientation: _angular_core.InputSignal<"horizontal" | "vertical">;
3305
+ /** The handle's accessible name, when no `ariaLabelledBy` names it. */
3306
+ readonly ariaLabel: _angular_core.InputSignal<string | undefined>;
3307
+ /** Id of the element that names the handle (a label beside it). */
3308
+ readonly ariaLabelledBy: _angular_core.InputSignal<string | undefined>;
3309
+ /** The handle was let go (or the track clicked), with the value it ended on. */
3310
+ readonly slideEnd: _angular_core.OutputEmitterRef<number | null>;
3311
+ private readonly prime;
3312
+ constructor();
3313
+ static ɵfac: _angular_core.ɵɵFactoryDeclaration<DwSliderComponent, never>;
3314
+ static ɵcmp: _angular_core.ɵɵComponentDeclaration<DwSliderComponent, "dw-slider", never, { "min": { "alias": "min"; "required": false; "isSignal": true; }; "max": { "alias": "max"; "required": false; "isSignal": true; }; "step": { "alias": "step"; "required": false; "isSignal": true; }; "orientation": { "alias": "orientation"; "required": false; "isSignal": true; }; "ariaLabel": { "alias": "ariaLabel"; "required": false; "isSignal": true; }; "ariaLabelledBy": { "alias": "ariaLabelledBy"; "required": false; "isSignal": true; }; }, { "slideEnd": "slideEnd"; }, never, never, true, never>;
3315
+ }
3316
+
3317
+ /** The pane sizes a `dw-splitter` reports, in % of the space the panes share (they add up to 100). */
3318
+ interface DwSplitterResizeEvent {
3319
+ sizes: number[];
3320
+ }
3321
+ /** A pane of a `dw-splitter`, in order: `<ng-template dwSplitterPanel>…</ng-template>`. */
3322
+ declare class DwSplitterPanelDirective {
3323
+ readonly template: TemplateRef<void>;
3324
+ static ɵfac: _angular_core.ɵɵFactoryDeclaration<DwSplitterPanelDirective, never>;
3325
+ static ɵdir: _angular_core.ɵɵDirectiveDeclaration<DwSplitterPanelDirective, "ng-template[dwSplitterPanel]", never, {}, {}, never, never, true, never>;
3326
+ }
3327
+ /**
3328
+ * Two or more panes side by side (`layout="horizontal"`) or stacked (`vertical`), with a `dw-resizer` between each pair
3329
+ * that drags their shared edge. `panelSizes` are the starting sizes in % (a missing one takes an equal share);
3330
+ * `minSizes` are the smallest each pane may get, in %.
3331
+ *
3332
+ * `stateKey` remembers the sizes in `localStorage` (or `sessionStorage`, with `stateStorage="session"`) under that key,
3333
+ * as a JSON array of percentages, the format PrimeNG's Splitter used, so widths saved by a `p-splitter` with the same
3334
+ * key carry over. Once the user has resized (or a saved state was restored), their sizes win over `panelSizes`.
3335
+ *
3336
+ * The panes are flat: a hairline between them turns accent while hovered, focused or dragged. `variant="rail-start"`
3337
+ * is for a grey list rail beside its detail: the rail's grey runs up to the hairline. Each pane is a flex box whose
3338
+ * child fills it, so a pane's content sets its own scrolling.
3339
+ *
3340
+ * Keyboard: focus a gutter, then ←/→ (↑/↓ when vertical) move it 16px (64 with Shift), Home / End to the limits.
3341
+ *
3342
+ * ```html
3343
+ * <dw-splitter [panelSizes]="[22, 78]" [minSizes]="[15, 40]" stateKey="dw.agentEdit.scenariosSplit" variant="rail-start">
3344
+ * <ng-template dwSplitterPanel><app-scenario-list /></ng-template>
3345
+ * <ng-template dwSplitterPanel><app-scenario-detail /></ng-template>
3346
+ * </dw-splitter>
3347
+ * ```
3348
+ */
3349
+ declare class DwSplitterComponent implements OnInit {
3350
+ /** `horizontal`: panes side by side, resized by width; `vertical`: stacked, resized by height. */
3351
+ readonly layout: _angular_core.InputSignal<"horizontal" | "vertical">;
3352
+ /** Starting size of each pane, in %; a missing one takes an equal share. Scaled to add up to 100. */
3353
+ readonly panelSizes: _angular_core.InputSignal<readonly number[]>;
3354
+ /** Smallest size of each pane, in %; a missing one is 0. */
3355
+ readonly minSizes: _angular_core.InputSignal<readonly number[]>;
3356
+ /** Thickness of each gutter, in px. */
3357
+ readonly gutterSize: _angular_core.InputSignalWithTransform<number, unknown>;
3358
+ /** Remembers the sizes under this key (a JSON array of %, as PrimeNG's Splitter stored them). */
3359
+ readonly stateKey: _angular_core.InputSignal<string | null | undefined>;
3360
+ /** Where `stateKey` keeps the sizes. */
3361
+ readonly stateStorage: _angular_core.InputSignal<"local" | "session">;
3362
+ /** `rail-start`: the first pane is a grey rail (a list beside its detail); its grey runs up to the hairline. */
3363
+ readonly variant: _angular_core.InputSignal<"default" | "rail-start">;
3364
+ /** Accessible name of each gutter. */
3365
+ readonly gutterAriaLabel: _angular_core.InputSignal<string>;
3366
+ /** A drag or a keyboard move ended, with the new sizes (already saved under `stateKey`). */
3367
+ readonly resizeEnd: _angular_core.OutputEmitterRef<DwSplitterResizeEvent>;
3368
+ protected readonly panels: _angular_core.Signal<readonly DwSplitterPanelDirective[]>;
3369
+ /** Sizes the user set by resizing, or restored from `stateKey`; `null` while `panelSizes` rules. */
3370
+ private readonly userSizes;
3371
+ /** The current size of each pane, in % (adds up to 100). */
3372
+ readonly sizes: _angular_core.Signal<number[]>;
3373
+ /** Index of the gutter being dragged. */
3374
+ protected readonly dragging: _angular_core.WritableSignal<number | null>;
3375
+ protected readonly horizontal: _angular_core.Signal<boolean>;
3376
+ private readonly host;
3377
+ private readonly document;
3378
+ private drag;
3379
+ ngOnInit(): void;
3380
+ protected round(value: number): number;
3381
+ /** Smallest size the pane before gutter `i` can take. */
3382
+ protected minOf(i: number): number;
3383
+ /** Largest size the pane before gutter `i` can take: what the pair has, less the next pane's minimum. */
3384
+ protected maxOf(i: number): number;
3385
+ protected onDragStart(i: number): void;
3386
+ protected onDrag(i: number, event: DwResizerDrag): void;
3387
+ protected onDragEnd(): void;
3388
+ /** A keyboard move of `px` (negative: towards the start), or ±Infinity to a limit. */
3389
+ protected onNudge(i: number, px: number): void;
3390
+ /** Moves gutter `i` by `delta` % from `from`, keeping both its panes at or above their minimum. */
3391
+ private resize;
3392
+ private commit;
3393
+ private isRtl;
3394
+ private storage;
3395
+ private readState;
3396
+ private writeState;
3397
+ static ɵfac: _angular_core.ɵɵFactoryDeclaration<DwSplitterComponent, never>;
3398
+ static ɵcmp: _angular_core.ɵɵComponentDeclaration<DwSplitterComponent, "dw-splitter", never, { "layout": { "alias": "layout"; "required": false; "isSignal": true; }; "panelSizes": { "alias": "panelSizes"; "required": false; "isSignal": true; }; "minSizes": { "alias": "minSizes"; "required": false; "isSignal": true; }; "gutterSize": { "alias": "gutterSize"; "required": false; "isSignal": true; }; "stateKey": { "alias": "stateKey"; "required": false; "isSignal": true; }; "stateStorage": { "alias": "stateStorage"; "required": false; "isSignal": true; }; "variant": { "alias": "variant"; "required": false; "isSignal": true; }; "gutterAriaLabel": { "alias": "gutterAriaLabel"; "required": false; "isSignal": true; }; }, { "resizeEnd": "resizeEnd"; }, ["panels"], never, true, never>;
3399
+ }
3400
+
2308
3401
  /**
2309
3402
  * Backend timestamp normalization.
2310
3403
  *
@@ -2348,6 +3441,32 @@ type BackendTimestamp = string | number | null | undefined;
2348
3441
 
2349
3442
  type DateLike = BackendTimestamp | Date;
2350
3443
 
3444
+ /** One sorted column: its field, and the direction (`1` ascending, `-1` descending). */
3445
+ interface DwSortMeta {
3446
+ field: string;
3447
+ order: number;
3448
+ }
3449
+ /**
3450
+ * What `sortFunction` hands a screen that sorts its own rows (`customSort`): the rows to sort in place, and how —
3451
+ * one column (`field`, `order`) or several (`multiSortMeta`, `mode: 'multiple'`).
3452
+ */
3453
+ interface DwSortEvent<T = unknown> {
3454
+ data?: T[];
3455
+ mode?: 'single' | 'multiple';
3456
+ field?: string;
3457
+ order?: number;
3458
+ multiSortMeta?: DwSortMeta[];
3459
+ }
3460
+ /**
3461
+ * What `sortChange` reports: the sorted column (`{ field, order }`), every sorted column (`{ multisortmeta }`, with
3462
+ * `multiSortMeta`), or `{ field: null, order: 0 }` / `{ multisortmeta: [] }` once a third click clears the sort.
3463
+ */
3464
+ type DwSortChange = DwSortMeta | {
3465
+ field: null;
3466
+ order: 0;
3467
+ } | {
3468
+ multisortmeta: DwSortMeta[];
3469
+ };
2351
3470
  interface DwColumn<T = any> {
2352
3471
  field: string;
2353
3472
  header: string;
@@ -2475,7 +3594,7 @@ declare class DwTableComponent<T = any> {
2475
3594
  readonly totalRecords: _angular_core.InputSignal<number | null>;
2476
3595
  readonly sortField: _angular_core.InputSignal<string | null>;
2477
3596
  readonly sortOrder: _angular_core.InputSignal<1 | -1>;
2478
- readonly multiSortMeta: _angular_core.InputSignal<SortMeta[] | null>;
3597
+ readonly multiSortMeta: _angular_core.InputSignal<DwSortMeta[] | null>;
2479
3598
  /**
2480
3599
  * A third click on a sorted column clears its sort (asc → desc → unsorted) and
2481
3600
  * the rows fall back to the order `value` arrived in. `sortChange` then emits
@@ -2502,7 +3621,7 @@ declare class DwTableComponent<T = any> {
2502
3621
  readonly rowClass: _angular_core.InputSignal<((row: T) => string | string[] | Record<string, boolean> | null) | null>;
2503
3622
  readonly actionsHeader: _angular_core.InputSignal<string>;
2504
3623
  readonly actionsWidth: _angular_core.InputSignal<string>;
2505
- /** `start`: the actions column comes right after the first column, frozen left (agents list). */
3624
+ /** `start`: the actions column comes right after the first column, frozen left. */
2506
3625
  readonly actionsPlacement: _angular_core.InputSignal<"start" | "end">;
2507
3626
  /** A row's menu (Edit, Delete…): the actions column gets a ⋮ that opens it. */
2508
3627
  readonly rowMenuItems: _angular_core.InputSignal<((row: T) => DwMenuItem<T>[]) | null>;
@@ -2533,8 +3652,8 @@ declare class DwTableComponent<T = any> {
2533
3652
  readonly rowEnter: _angular_core.OutputEmitterRef<T>;
2534
3653
  readonly rowLeave: _angular_core.OutputEmitterRef<T>;
2535
3654
  readonly pageChange: _angular_core.OutputEmitterRef<TablePageEvent>;
2536
- readonly sortChange: _angular_core.OutputEmitterRef<unknown>;
2537
- readonly sortFunction: _angular_core.OutputEmitterRef<SortEvent>;
3655
+ readonly sortChange: _angular_core.OutputEmitterRef<DwSortChange>;
3656
+ readonly sortFunction: _angular_core.OutputEmitterRef<DwSortEvent<T>>;
2538
3657
  readonly table: _angular_core.Signal<Table<any> | undefined>;
2539
3658
  /** Every frozen header / body cell (PrimeNG's pFrozenColumn). */
2540
3659
  private readonly frozenCells;
@@ -2595,8 +3714,16 @@ declare class DwTableComponent<T = any> {
2595
3714
  dateTooltip(row: T, col: DwColumn<T>): string;
2596
3715
  textStyleClass(col: DwColumn<T>): string;
2597
3716
  onPage(event: TablePageEvent): void;
2598
- onSort(event: SortMeta | {
2599
- multisortmeta?: SortMeta[];
3717
+ /** PrimeNG types the sort mode as any string; it is only ever `single` or `multiple` (the table's `sortMode`). */
3718
+ emitSortFunction(event: {
3719
+ data?: T[];
3720
+ mode?: string;
3721
+ field?: string;
3722
+ order?: number;
3723
+ multiSortMeta?: DwSortMeta[];
3724
+ }): void;
3725
+ onSort(event: DwSortMeta | {
3726
+ multisortmeta?: DwSortMeta[];
2600
3727
  }): void;
2601
3728
  onRowClick(row: T, event: MouseEvent): void;
2602
3729
  onRowKey(row: T, event: Event): void;
@@ -2634,13 +3761,18 @@ declare class DwColumnPickerComponent<T = any> {
2634
3761
  }
2635
3762
 
2636
3763
  /**
2637
- * One of crystal's SVG glyphs (icons/svg/glyphs), or an icon the app registered with provideCrystalIcons(), drawn at
2638
- * 1em so it follows the font size of its context; glyphs draw in `currentColor`, so they take its colour too.
3764
+ * One icon, drawn at 1em so it follows the font size of its context, in `currentColor`:
3765
+ * - `name`: one of crystal's SVG glyphs (icons/svg/glyphs), or an icon the app registered with provideCrystalIcons();
3766
+ * - `pi`: a PrimeIcons glyph, by its name without `pi-` (crystal ships the icon font, so an app never loads it).
3767
+ *
3768
+ * Give it one of the two. It is decorative (hidden from assistive tech) unless it has a `label`.
2639
3769
  *
2640
3770
  * ```html
2641
3771
  * <dw-icon name="hand" />
2642
3772
  * <dw-icon name="workflow" size="16px" class="dw-text-accent" />
2643
3773
  * <dw-icon name="rocket" /> <!-- registered by the app -->
3774
+ * <dw-icon pi="trash" />
3775
+ * <dw-icon pi="spinner" [spin]="true" label="Loading" />
2644
3776
  * ```
2645
3777
  */
2646
3778
  declare class DwIconComponent {
@@ -2648,14 +3780,21 @@ declare class DwIconComponent {
2648
3780
  private readonly registry;
2649
3781
  /** A crystal glyph name, or a name registered with provideCrystalIcons(). */
2650
3782
  readonly name: _angular_core.InputSignal<"link" | "reset" | "code" | "search" | "info" | "workflow" | "agent" | "agentBuilder" | "alertError" | "alertWarn" | "attach" | "autoplay" | "back" | "bell" | "bolt" | "book" | "brain" | "bulb" | "chart" | "check" | "chevDown" | "chevLeft" | "chevRight" | "chevUp" | "close" | "cog" | "collapse" | "comment" | "comments" | "copy" | "cpu" | "expand" | "file" | "gear" | "hand" | "home" | "kebab" | "layers" | "notesPad" | "panelCollapse" | "panelExpand" | "paperclip" | "parse" | "pencil" | "play" | "plus" | "reference" | "refresh" | "robot" | "send" | "sidebarCollapse" | "sidebarExpand" | "sparkle" | "tag" | "tagFilled" | "testShield" | "trash" | "users" | "wrench" | (string & {})>;
3783
+ /** A PrimeIcons name without `pi-` (`trash`, `check-circle`…), checked against the installed font. */
3784
+ readonly pi: _angular_core.InputSignal<"" | DwPrimeIcon>;
2651
3785
  /** CSS length; defaults to the surrounding font size. */
2652
3786
  readonly size: _angular_core.InputSignal<string>;
3787
+ /** Spins the icon (a loader). */
3788
+ readonly spin: _angular_core.InputSignal<boolean>;
3789
+ /** Makes the icon meaningful: read out as an image with this text. */
3790
+ readonly label: _angular_core.InputSignal<string>;
3791
+ readonly hostClass: _angular_core.Signal<string>;
2653
3792
  readonly svg: _angular_core.Signal<SafeHtml>;
2654
3793
  static ɵfac: _angular_core.ɵɵFactoryDeclaration<DwIconComponent, never>;
2655
- static ɵcmp: _angular_core.ɵɵComponentDeclaration<DwIconComponent, "dw-icon", never, { "name": { "alias": "name"; "required": true; "isSignal": true; }; "size": { "alias": "size"; "required": false; "isSignal": true; }; }, {}, never, never, true, never>;
3794
+ static ɵcmp: _angular_core.ɵɵComponentDeclaration<DwIconComponent, "dw-icon", never, { "name": { "alias": "name"; "required": false; "isSignal": true; }; "pi": { "alias": "pi"; "required": false; "isSignal": true; }; "size": { "alias": "size"; "required": false; "isSignal": true; }; "spin": { "alias": "spin"; "required": false; "isSignal": true; }; "label": { "alias": "label"; "required": false; "isSignal": true; }; }, {}, never, never, true, never>;
2656
3795
  }
2657
3796
 
2658
- /** Icon names starting with this (any case) are crystal's: `dw…` and `dwi-…` (MIGRATION-PLAN D16). */
3797
+ /** Icon names starting with this (any case) are crystal's: `dw…` and `dwi-…`. */
2659
3798
  declare const DW_RESERVED_ICON_PREFIX = "dw";
2660
3799
  /**
2661
3800
  * The consumer's own SVG icons, by name. A consumer registers markup under any name that doesn't start with `dw`, and
@@ -2764,16 +3903,16 @@ type DwTheme = 'light' | 'dark';
2764
3903
  declare const DW_THEME_STORAGE_KEY = "dw-theme";
2765
3904
  interface CrystalThemeConfig {
2766
3905
  /**
2767
- * Set `data-theme` on <html> at start-up and on every switch. `false` for federated elements: the host page owns
2768
- * its <html>. Default true.
3906
+ * Set `data-theme` on `<html>` at start-up and on every switch. `false` for federated elements: the host page owns
3907
+ * its `<html>`. Default true.
2769
3908
  */
2770
3909
  apply?: boolean;
2771
3910
  /** Theme used until the viewer picks one. Default 'light'. */
2772
3911
  initial?: DwTheme;
2773
- /** localStorage key for the viewer's choice. Default 'dw-theme' (dataworkz-ui's key, so stored choices survive). */
3912
+ /** localStorage key for the viewer's choice. Default 'dw-theme' (kept stable, so stored choices survive upgrades). */
2774
3913
  storageKey?: string;
2775
3914
  }
2776
- /** What `provideCrystal()` configures. Theme only (MIGRATION-PLAN §3.2). */
3915
+ /** What `provideCrystal()` configures: the theme. */
2777
3916
  interface CrystalConfig {
2778
3917
  theme?: CrystalThemeConfig;
2779
3918
  }
@@ -2781,13 +3920,13 @@ interface CrystalConfig {
2781
3920
  declare const DW_CRYSTAL_CONFIG: InjectionToken<CrystalConfig>;
2782
3921
  /**
2783
3922
  * Light / dark theme switch. The theme is the `data-theme` attribute on
2784
- * <html>: semantic-dark.css re-points the --dw-* tokens under
3923
+ * `<html>`: semantic-dark.css re-points the --dw-* tokens under
2785
3924
  * [data-theme="dark"] and PrimeNG's darkModeSelector follows the same
2786
3925
  * attribute. The choice is remembered per browser (light until chosen).
2787
3926
  *
2788
3927
  * `provideCrystal()` applies it once at start-up so a stored dark choice
2789
3928
  * doesn't flash light. With `theme.apply: false` (federated elements on a
2790
- * legacy host page) it never touches <html>.
3929
+ * page crystal doesn't own) it never touches `<html>`.
2791
3930
  */
2792
3931
  declare class ThemeService {
2793
3932
  private readonly document;
@@ -2795,7 +3934,7 @@ declare class ThemeService {
2795
3934
  private readonly storageKey;
2796
3935
  private readonly applies;
2797
3936
  readonly theme: _angular_core.WritableSignal<DwTheme>;
2798
- /** Puts the current theme on <html> (unless `theme.apply` is false). */
3937
+ /** Puts the current theme on `<html>` (unless `theme.apply` is false). */
2799
3938
  init(): void;
2800
3939
  setTheme(theme: DwTheme): void;
2801
3940
  toggle(): void;
@@ -2806,8 +3945,8 @@ declare class ThemeService {
2806
3945
  }
2807
3946
 
2808
3947
  /**
2809
- * Crystal's app-level setup: the theme (MIGRATION-PLAN §3.2). With `theme.apply` (the default) it puts the stored or
2810
- * initial theme on <html> before the first render, so a dark choice doesn't flash light.
3948
+ * Crystal's app-level setup: the theme. With `theme.apply` (the default) it puts the stored or
3949
+ * initial theme on `<html>` before the first render, so a dark choice doesn't flash light.
2811
3950
  *
2812
3951
  * ```ts
2813
3952
  * providers: [provideCrystal(), provideCrystalPrimeNG()] // an app
@@ -2823,7 +3962,7 @@ interface CrystalHostThemeOptions {
2823
3962
  fonts?: boolean;
2824
3963
  }
2825
3964
  /**
2826
- * Themes a page crystal doesn't own: for components delivered as federated custom elements (MIGRATION-PLAN §3.5).
3965
+ * Themes a page crystal doesn't own: for components delivered as federated custom elements.
2827
3966
  * Prepends one `<style data-dw-crystal-theme>` ahead of the host's stylesheets (so the host wins equal-specificity
2828
3967
  * ties) holding the host-safe theme: tokens incl. dark, the element base, component CSS and utilities, no resets and
2829
3968
  * no html / body rules. Fonts are embedded, since relative URLs can't resolve from an injected `<style>`.
@@ -2840,5 +3979,5 @@ declare function installCrystalHostTheme({ fonts }?: CrystalHostThemeOptions): v
2840
3979
  /** Removes the host theme again (e.g. a host that unloads crystal, or a test). */
2841
3980
  declare function removeCrystalHostTheme(): void;
2842
3981
 
2843
- export { DW_CLOCK_TICK_MS, DW_CRYSTAL_CONFIG, DW_DIALOG, DW_DRAWER, DW_FIELD_MESSAGES, DW_HOST_THEME_ATTR, DW_IN_PROGRESS_STATUSES, DW_LAYOUT, DW_MENU_PLAIN_GROUP, DW_OVERLAY_ANCHOR_ATTR, DW_OVERLAY_ANCHOR_GAP, DW_POPOVER, DW_RESERVED_ICON_PREFIX, DW_STATUS_TONES, DW_TABLE, DW_TAG_PALETTE, DW_THEME_STORAGE_KEY, DW_TOGGLE_CARD, DwActionBarComponent, DwAvatarComponent, DwBadgeComponent, DwBannerComponent, DwBoxComponent, DwBreadcrumbComponent, DwButtonComponent, DwCardComponent, DwCellDirective, DwCheckToggleComponent, DwChipComponent, DwClockService, DwColumnPickerComponent, DwConfirmDialogComponent, DwConfirmHostComponent, DwConfirmService, DwCopyButtonComponent, DwDialogComponent, DwDialogFooterDirective, DwDialogHeaderDirective, DwDialogTitleSuffixDirective, DwDividerComponent, DwDrawerComponent, DwDrawerFooterDirective, DwDrawerHeaderDirective, DwDrawerSubheaderDirective, DwEmptyStateComponent, DwEntityIconComponent, DwFieldComponent, DwFileDropzoneComponent, DwFileListComponent, DwFormSectionHeaderComponent, DwGridDirective, DwHeaderDirective, DwHstackDirective, DwIconButtonComponent, DwIconComponent, DwIconRegistry, IdBlockComponent as DwIdBlockComponent, DwMenuComponent, DwMenuHeaderDirective, DwMeterComponent, DwNavItemActionsDirective, DwNavItemExtraDirective, DwNavListComponent, DwPageHeaderComponent, DwPopoverComponent, DwPopoverFooterDirective, DwRailTabsComponent, DwResizerComponent, DwRowActionsDirective, DwRowExpansionDirective, DwSearchInputComponent, DwSectionComponent, DwSkeletonComponent, DwSpinnerComponent, DwStackDirective, DwStatusPillComponent, DwTabPanelDirective, DwTableComponent, DwTableEmptyComponent, DwTabsComponent, DwTagColorButtonComponent, DwTagColorPickerComponent, DwTagComponent, DwTagListComponent, DwTileComponent, DwTimestampComponent, DwToastHostComponent, DwToastService, DwToggleCardBodyDirective, DwToggleCardComponent, DwToggleCardControlDirective, DwTooltipIfTruncatedDirective, ThemeService, alignUnderOverlayAnchor, extensionOf, fieldErrorMessage, formatBytes, gapToken, hashTagIndex, humanizeStatus, initialsOf, installCrystalHostTheme, isImageIcon, isTruncated, normalizeStatus, provideCrystal, provideCrystalIcons, removeCrystalHostTheme, tagColorVar, tintFor, toneForStatus };
2844
- export type { CrystalConfig, CrystalHostThemeOptions, CrystalThemeConfig, DwAlign, DwAvatarTint, DwBadgeKind, DwBadgeTone, DwBreadcrumb, DwButtonAppearance, DwButtonSize, DwButtonVariant, DwCanClose, DwCardTint, DwCardVariant, DwColumn, DwConfirmOptions, DwConfirmSeverity, DwConfirmSummaryRow, DwConfirmWarning, DwDialogSize, DwDividerOrientation, DwDividerSpacing, DwDrawerAction, DwDrawerSize, DwEntityKind, DwEntityTint, DwFileItem, DwFileRejectReason, DwFileRejection, DwFileStatus, DwGap, DwIconButtonVariant, DwInitialsStrategy, DwJustify, DwMenuItem, DwNavGroup, DwNavItem, DwNavItemDot, DwNavReorder, DwRailTab, DwResizerDrag, DwRowClickEvent, DwSeverity, DwShowErrorsWhen, DwSkeletonPreset, DwSupportedType, DwTabOption, DwTabValue, DwTagItem, DwTheme, DwToast, DwToastOptions, DwToastPosition, DwToastSeverity, DwTone };
3982
+ export { DW_ACCORDION, DW_APP_FIELD_MESSAGES, DW_CLOCK_TICK_MS, DW_CRYSTAL_CONFIG, DW_DIALOG, DW_DRAWER, DW_FIELD_MESSAGES, DW_HOST_THEME_ATTR, DW_ICON_RESOLVERS, DW_INPUT, DW_IN_PROGRESS_STATUSES, DW_LAYOUT, DW_MENU_PLAIN_GROUP, DW_OVERLAY_ANCHOR_ATTR, DW_OVERLAY_ANCHOR_GAP, DW_POPOVER, DW_RESERVED_ICON_PREFIX, DW_STATUS_TONES, DW_TABLE, DW_TAG_PALETTE, DW_THEME_STORAGE_KEY, DW_TOGGLE_CARD, DwAccordionComponent, DwAccordionContentDirective, DwAccordionHeaderActionDirective, DwAccordionHeaderDirective, DwAccordionPanelComponent, DwActionBarComponent, DwAutocompleteComponent, DwAutocompleteItemDirective, DwAvatarComponent, DwBadgeComponent, DwBannerComponent, DwBoxComponent, DwBreadcrumbComponent, DwButtonComponent, DwCardComponent, DwCellDirective, DwChartComponent, DwCheckToggleComponent, DwCheckboxComponent, DwChipComponent, DwClockService, DwColumnPickerComponent, DwConfirmDialogComponent, DwConfirmHostComponent, DwConfirmService, DwCopyButtonComponent, DwDatePickerComponent, DwDialogComponent, DwDialogFooterDirective, DwDialogHeaderDirective, DwDialogTitleSuffixDirective, DwDividerComponent, DwDrawerComponent, DwDrawerFooterDirective, DwDrawerHeaderDirective, DwDrawerSubheaderDirective, DwEmptyStateComponent, DwEntityIconComponent, DwFieldComponent, DwFileDropzoneComponent, DwFileListComponent, DwFormControl, DwFormSectionHeaderComponent, DwGridDirective, DwHeaderDirective, DwHstackDirective, DwIconButtonComponent, DwIconComponent, DwIconRegistry, IdBlockComponent as DwIdBlockComponent, DwInputDirective, DwMenuComponent, DwMenuHeaderDirective, DwMeterComponent, DwMultiselectComponent, DwNavItemActionsDirective, DwNavItemExtraDirective, DwNavListComponent, DwNumberInputComponent, DwPageHeaderComponent, DwPopoverComponent, DwPopoverFooterDirective, DwRadioComponent, DwRailTabsComponent, DwResizerComponent, DwRowActionsDirective, DwRowExpansionDirective, DwSearchInputComponent, DwSectionComponent, DwSelectComponent, DwSelectFooterDirective, DwSelectOptionDirective, DwSelectValueDirective, DwSkeletonComponent, DwSliderComponent, DwSpinnerComponent, DwSplitterComponent, DwSplitterPanelDirective, DwStackDirective, DwStatusPillComponent, DwStepperComponent, DwSwitchComponent, DwTabPanelDirective, DwTableComponent, DwTableEmptyComponent, DwTabsComponent, DwTagColorButtonComponent, DwTagColorPickerComponent, DwTagComponent, DwTagListComponent, DwTextareaDirective, DwTileComponent, DwTimestampComponent, DwToastHostComponent, DwToastService, DwToggleCardBodyDirective, DwToggleCardComponent, DwToggleCardControlDirective, DwTooltipDirective, DwTooltipIfTruncatedDirective, DwTreeComponent, DwTreeNodeDirective, ThemeService, alignUnderOverlayAnchor, extensionOf, fieldErrorMessage, formatBytes, gapToken, hashTagIndex, humanizeStatus, initialsOf, installCrystalHostTheme, isImageIcon, isTruncated, normalizeStatus, primeSize, provideCrystal, provideCrystalFieldMessages, provideCrystalIconResolvers, provideCrystalIcons, removeCrystalHostTheme, tagColorVar, tintFor, toneForStatus };
3983
+ export type { CrystalConfig, CrystalHostThemeOptions, CrystalThemeConfig, DwAccordionHeaderContext, DwAccordionToggleEvent, DwAccordionValue, DwAccordionVariant, DwAlign, DwAutocompletePanelWidth, DwAutocompleteSearchEvent, DwAvatarTint, DwBadgeKind, DwBadgeTone, DwBreadcrumb, DwButtonAppearance, DwButtonSize, DwButtonVariant, DwCanClose, DwCardTint, DwCardVariant, DwChartSelectEvent, DwChartType, DwColumn, DwConfirmOptions, DwConfirmSeverity, DwConfirmSummaryRow, DwConfirmWarning, DwControlSize, DwDateValue, DwDialogSize, DwDividerOrientation, DwDividerSpacing, DwDrawerAction, DwDrawerSize, DwEntityKind, DwEntityTint, DwFieldMessage, DwFileItem, DwFileRejectReason, DwFileRejection, DwFileStatus, DwGap, DwIconButtonVariant, DwIconResolvers, DwInitialsStrategy, DwInputSize, DwJustify, DwMenuItem, DwNavGroup, DwNavItem, DwNavItemDot, DwNavReorder, DwPrimeValueAccessor, DwRailTab, DwResizerDrag, DwRowClickEvent, DwSelectOptionContext, DwSeverity, DwShowErrorsWhen, DwSkeletonPreset, DwSortChange, DwSortEvent, DwSortMeta, DwSplitterResizeEvent, DwStep, DwStepValue, DwSupportedType, DwSwitchSize, DwTabOption, DwTabValue, DwTagItem, DwTheme, DwToast, DwToastOptions, DwToastPosition, DwToastSeverity, DwTone, DwTooltipPosition, DwTooltipVariant, DwTreeNode, DwTreeNodeEvent, DwTreeSelection };