@area8975/ui 0.1.1-dev.9 → 0.2.1-dev.28

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.
@@ -1,37 +1,64 @@
1
- import ApexCharts$1 from "apexcharts";
2
1
  import * as i0 from "@angular/core";
3
- import { ElementRef, OnDestroy, OnInit, TemplateRef, WritableSignal } from "@angular/core";
2
+ import { ElementRef, EnvironmentProviders, InjectionToken, OnDestroy, OnInit, Provider, Signal, TemplateRef, WritableSignal } from "@angular/core";
3
+ import ApexCharts$1 from "apexcharts";
4
4
  import { Placement } from "@floating-ui/dom";
5
5
  import { Observable } from "rxjs";
6
+ import { IconType } from "@ng-icons/core";
7
+ /** One entry in a legend, the colour ties it to its marks. */
8
+ export interface ChartLegendItem {
9
+ name: string;
10
+ colour: string;
11
+ /** Shows the key as a dashed line, for series told apart by line style. */
12
+ dashed?: boolean;
13
+ /** Text to show instead of `name`. `name` still ties the item to its series. */
14
+ label?: string;
15
+ }
16
+ /** Anything a legend can be linked to with `for`, every chart is one. */
17
+ export interface ChartLegendSource {
18
+ readonly legendItems: Signal<ChartLegendItem[]>;
19
+ readonly legendNote: Signal<string>;
20
+ /** Series switched off from the legend. */
21
+ readonly hiddenSeries: WritableSignal<string[]>;
22
+ /** The series the legend is pointing at, the others fade while it's set. */
23
+ readonly emphasis: WritableSignal<string | null>;
24
+ }
25
+ /** Where a chart draws its own legend, `none` when one is linked elsewhere. */
26
+ export type ChartLegendPosition = 'auto' | 'none';
6
27
  /**
7
28
  * Categorical colours for chart series, in a fixed order that was checked for
8
29
  * colour blindness (adjacent pairs stay apart for protan, deutan and tritan).
9
30
  * Keep the order, a series takes the next slot, never a generated colour.
10
31
  */
11
- declare const CHART_PALETTE: readonly ["#2a78d6", "#eb6834", "#1baf7a", "#eda100", "#e87ba4", "#008300", "#4a3aa7", "#e34948"];
32
+ export declare const CHART_PALETTE: readonly ["#2a78d6", "#eb6834", "#1baf7a", "#eda100", "#e87ba4", "#008300", "#4a3aa7", "#e34948"];
33
+ /** Violet and green are lightened to keep 3:1 contrast on a dark card. */
34
+ export declare const CHART_PALETTE_DARK: readonly ["#2a78d6", "#eb6834", "#1baf7a", "#eda100", "#e87ba4", "#2e9e2e", "#8a7cf0", "#e34948"];
12
35
  /** Past eight series, fold the rest into "Other" instead of reusing a colour. */
13
- declare const CHART_MAX_SERIES: 8;
36
+ export declare const CHART_MAX_SERIES: 8;
14
37
  /** Lines can go to sixteen, the second eight reuse the colours dashed. */
15
- declare const CHART_MAX_LINE_SERIES: number;
16
- declare const CHART_INK: {
17
- readonly text: "#1e2939";
18
- readonly muted: "#6a7282";
19
- readonly grid: "#e5e7eb";
20
- readonly surface: "#ffffff";
21
- readonly context: "#d1d5dc";
22
- };
23
- interface ChartSeriesStyle {
38
+ export declare const CHART_MAX_LINE_SERIES: number;
39
+ /** Chart chrome, apex needs real colours so these can't be CSS variables. */
40
+ export interface ChartInk {
41
+ text: string;
42
+ muted: string;
43
+ grid: string;
44
+ surface: string;
45
+ context: string;
46
+ }
47
+ export declare const CHART_INK: ChartInk;
48
+ export declare const CHART_INK_DARK: ChartInk;
49
+ export declare function chartInk(dark: boolean): ChartInk;
50
+ export interface ChartSeriesStyle {
24
51
  colour: string;
25
52
  dashed: boolean;
26
53
  }
27
54
  /** Past the eighth slot a series goes grey, reusing a colour would make two series look the same. */
28
- declare function chartColour(index: number): string;
55
+ export declare function chartColour(index: number, dark?: boolean): string;
29
56
  /**
30
57
  * Colour plus line style for a slot. With `dashes` the ninth to sixteenth
31
58
  * slots reuse the colours as dashed lines, colour and dash together keep
32
59
  * them apart. Anything past that is grey.
33
60
  */
34
- declare function chartSeriesStyle(index: number, dashes: boolean): ChartSeriesStyle;
61
+ export declare function chartSeriesStyle(index: number, dashes: boolean, dark?: boolean): ChartSeriesStyle;
35
62
  export type ChartOptions = ApexCharts$1.ApexOptions;
36
63
  /** One named set of values, one per category. */
37
64
  export interface ChartSeries {
@@ -39,18 +66,28 @@ export interface ChartSeries {
39
66
  data: (number | null)[];
40
67
  /** Overrides the palette slot, keep it for when a series must match something else. */
41
68
  colour?: string;
69
+ /** Draws the line dashed, e.g. to set projected figures apart from actual ones. Bars ignore it. */
70
+ dashed?: boolean;
42
71
  }
72
+ /** `fill` takes the host's height, which has to come from layout. */
73
+ export type ChartHeight = number | 'fill';
43
74
  /** Turns a raw value into what the axis, tooltip and table show, e.g. money. */
44
75
  export type ChartValueFormatter = (value: number) => string;
45
76
  /** Inputs every chart with categories along one axis and values up the other shares. */
46
- declare abstract class UiAxisChartBase {
77
+ declare abstract class UiAxisChartBase implements ChartLegendSource {
78
+ protected readonly uiFormat: import("@area8975/ui").UiFormat;
79
+ private readonly privacy;
80
+ protected readonly dark: import("@angular/core").WritableSignal<boolean>;
81
+ protected readonly ink: import("@angular/core").Signal<import("@area8975/ui").ChartInk>;
47
82
  readonly series: import("@angular/core").InputSignal<ChartSeries[]>;
48
83
  readonly categories: import("@angular/core").InputSignal<string[]>;
49
84
  /** Says what the chart shows, e.g. "Spending by month". */
50
85
  readonly ariaLabel: import("@angular/core").InputSignal<string>;
51
- readonly height: import("@angular/core").InputSignal<number>;
86
+ readonly height: import("@angular/core").InputSignal<ChartHeight>;
52
87
  /** Used on the value axis, the tooltip and the table, e.g. to show money. */
53
88
  readonly valueFormatter: import("@angular/core").InputSignal<ChartValueFormatter>;
89
+ /** Masks the values in privacy mode. Defaults to whether `valueFormatter` came from `injectMoneyFormatter`. */
90
+ readonly sensitive: import("@angular/core").InputSignalWithTransform<boolean | undefined, unknown>;
54
91
  /** Heading for the category column in the data table. */
55
92
  readonly categoryLabel: import("@angular/core").InputSignal<string>;
56
93
  readonly loading: import("@angular/core").InputSignalWithTransform<boolean, unknown>;
@@ -64,22 +101,30 @@ declare abstract class UiAxisChartBase {
64
101
  * matter stand out. The way to show more series than there are colours.
65
102
  */
66
103
  readonly highlight: import("@angular/core").InputSignal<string[] | null>;
104
+ readonly highlightKeepsColours: import("@angular/core").InputSignalWithTransform<boolean, unknown>;
105
+ /** `none` leaves the legend out, for when a `ui-chart-legend` is linked with `for`. */
106
+ readonly legend: import("@angular/core").InputSignal<ChartLegendPosition>;
67
107
  /** Series switched off in the legend. */
68
- protected readonly hiddenSeries: import("@angular/core").WritableSignal<string[]>;
108
+ readonly hiddenSeries: import("@angular/core").WritableSignal<string[]>;
109
+ /** The series the legend is pointing at, the others fade while it's set. */
110
+ readonly emphasis: import("@angular/core").WritableSignal<string | null>;
69
111
  /** Charts that draw lines can tell series apart by dashes too, bars can't. */
70
112
  protected readonly supportsDashes: boolean;
113
+ private readonly money;
114
+ protected readonly privacyMode: import("@angular/core").Signal<"visible" | "discreet" | "hidden">;
115
+ protected readonly masked: import("@angular/core").Signal<boolean>;
116
+ protected readonly concealed: import("@angular/core").Signal<boolean>;
117
+ protected readonly displayFormatter: import("@angular/core").Signal<ChartValueFormatter>;
118
+ protected readonly apexHeight: import("@angular/core").Signal<number | "100%">;
71
119
  protected readonly isEmpty: import("@angular/core").Signal<boolean>;
72
120
  protected readonly isMuted: import("@angular/core").Signal<boolean[]>;
121
+ private readonly colourOrder;
73
122
  protected readonly styles: import("@angular/core").Signal<ChartSeriesStyle[]>;
74
123
  protected readonly colours: import("@angular/core").Signal<string[]>;
75
124
  protected readonly dashed: import("@angular/core").Signal<boolean[]>;
76
125
  /** Grey context series stay out of the legend, the note says how many there are. */
77
- protected readonly legendItems: import("@angular/core").Signal<{
78
- colour: string;
79
- dashed: boolean;
80
- name: string;
81
- }[]>;
82
- protected readonly legendNote: import("@angular/core").Signal<string>;
126
+ readonly legendItems: import("@angular/core").Signal<ChartLegendItem[]>;
127
+ readonly legendNote: import("@angular/core").Signal<string>;
83
128
  protected formatValue(value: number | null | undefined): string;
84
129
  static ɵfac: i0.ɵɵFactoryDeclaration<UiAxisChartBase, never>;
85
130
  static ɵdir: i0.ɵɵDirectiveDeclaration<UiAxisChartBase, never, never, {
@@ -108,6 +153,11 @@ declare abstract class UiAxisChartBase {
108
153
  "required": false;
109
154
  "isSignal": true;
110
155
  };
156
+ "sensitive": {
157
+ "alias": "sensitive";
158
+ "required": false;
159
+ "isSignal": true;
160
+ };
111
161
  "categoryLabel": {
112
162
  "alias": "categoryLabel";
113
163
  "required": false;
@@ -138,6 +188,16 @@ declare abstract class UiAxisChartBase {
138
188
  "required": false;
139
189
  "isSignal": true;
140
190
  };
191
+ "highlightKeepsColours": {
192
+ "alias": "highlightKeepsColours";
193
+ "required": false;
194
+ "isSignal": true;
195
+ };
196
+ "legend": {
197
+ "alias": "legend";
198
+ "required": false;
199
+ "isSignal": true;
200
+ };
141
201
  }, {}, never, never, true, never>;
142
202
  }
143
203
  /**
@@ -147,6 +207,8 @@ declare abstract class UiAxisChartBase {
147
207
  export declare class UiBarChartComponent extends UiAxisChartBase {
148
208
  readonly orientation: import("@angular/core").InputSignal<"vertical" | "horizontal">;
149
209
  readonly stacked: import("@angular/core").InputSignalWithTransform<boolean, unknown>;
210
+ /** Picks out one category, e.g. the month a page is showing, and fades the rest. */
211
+ readonly highlightCategory: import("@angular/core").InputSignal<string | null>;
150
212
  protected readonly chartOptions: import("@angular/core").Signal<ApexCharts.ApexOptions>;
151
213
  static ɵfac: i0.ɵɵFactoryDeclaration<UiBarChartComponent, never>;
152
214
  static ɵcmp: i0.ɵɵComponentDeclaration<UiBarChartComponent, "ui-bar-chart", never, {
@@ -160,6 +222,11 @@ export declare class UiBarChartComponent extends UiAxisChartBase {
160
222
  "required": false;
161
223
  "isSignal": true;
162
224
  };
225
+ "highlightCategory": {
226
+ "alias": "highlightCategory";
227
+ "required": false;
228
+ "isSignal": true;
229
+ };
163
230
  }, {}, never, never, true, never>;
164
231
  }
165
232
  /** vertical draws columns rising from the bottom, horizontal draws bars from the left. */
@@ -181,6 +248,7 @@ export declare class UiChartComponent {
181
248
  private readonly canvas;
182
249
  private readonly chart;
183
250
  private destroyed;
251
+ private drawnNames;
184
252
  constructor();
185
253
  private applyHidden;
186
254
  private applyEmphasis;
@@ -209,13 +277,6 @@ export declare class UiChartComponent {
209
277
  };
210
278
  }, {}, never, never, true, never>;
211
279
  }
212
- /** One entry in a legend, the colour ties it to its marks. */
213
- export interface ChartLegendItem {
214
- name: string;
215
- colour: string;
216
- /** Shows the key as a dashed line, for series told apart by line style. */
217
- dashed?: boolean;
218
- }
219
280
  /** The loading, empty and data table states around a chart, shared by every chart type. */
220
281
  export declare class UiChartFrameComponent {
221
282
  readonly options: import("@angular/core").InputSignal<ApexCharts.ApexOptions>;
@@ -227,13 +288,17 @@ export declare class UiChartFrameComponent {
227
288
  readonly hiddenSeries: import("@angular/core").ModelSignal<string[]>;
228
289
  readonly valueFormatter: import("@angular/core").InputSignal<ChartValueFormatter>;
229
290
  readonly categoryLabel: import("@angular/core").InputSignal<string>;
230
- readonly height: import("@angular/core").InputSignal<number>;
291
+ readonly height: import("@angular/core").InputSignal<ChartHeight>;
231
292
  readonly emptyText: import("@angular/core").InputSignal<string>;
232
293
  readonly loading: import("@angular/core").InputSignalWithTransform<boolean, unknown>;
233
294
  readonly empty: import("@angular/core").InputSignalWithTransform<boolean, unknown>;
234
295
  readonly showTable: import("@angular/core").InputSignalWithTransform<boolean, unknown>;
296
+ readonly masked: import("@angular/core").InputSignalWithTransform<boolean, unknown>;
297
+ readonly showLegend: import("@angular/core").InputSignalWithTransform<boolean, unknown>;
235
298
  /** The series the legend is pointing at, the others fade while it's set. */
236
- protected readonly emphasis: import("@angular/core").WritableSignal<string | null>;
299
+ readonly emphasis: import("@angular/core").ModelSignal<string | null>;
300
+ protected readonly fill: import("@angular/core").Signal<boolean>;
301
+ protected readonly fixedHeight: import("@angular/core").Signal<number | null>;
237
302
  static ɵfac: i0.ɵɵFactoryDeclaration<UiChartFrameComponent, never>;
238
303
  static ɵcmp: i0.ɵɵComponentDeclaration<UiChartFrameComponent, "ui-chart-frame", never, {
239
304
  "options": {
@@ -306,8 +371,24 @@ export declare class UiChartFrameComponent {
306
371
  "required": false;
307
372
  "isSignal": true;
308
373
  };
374
+ "masked": {
375
+ "alias": "masked";
376
+ "required": false;
377
+ "isSignal": true;
378
+ };
379
+ "showLegend": {
380
+ "alias": "showLegend";
381
+ "required": false;
382
+ "isSignal": true;
383
+ };
384
+ "emphasis": {
385
+ "alias": "emphasis";
386
+ "required": false;
387
+ "isSignal": true;
388
+ };
309
389
  }, {
310
390
  "hiddenSeries": "hiddenSeriesChange";
391
+ "emphasis": "emphasisChange";
311
392
  }, never, never, true, never>;
312
393
  }
313
394
  /**
@@ -321,6 +402,9 @@ export declare class UiChartTableComponent {
321
402
  readonly valueFormatter: import("@angular/core").InputSignal<ChartValueFormatter>;
322
403
  readonly categoryLabel: import("@angular/core").InputSignal<string>;
323
404
  readonly visible: import("@angular/core").InputSignalWithTransform<boolean, unknown>;
405
+ /** Values are masks, screen readers hear "amount hidden" instead. */
406
+ readonly masked: import("@angular/core").InputSignalWithTransform<boolean, unknown>;
407
+ protected isValue(value: number | null | undefined): value is number;
324
408
  protected format(value: number | null | undefined): string;
325
409
  static ɵfac: i0.ɵɵFactoryDeclaration<UiChartTableComponent, never>;
326
410
  static ɵcmp: i0.ɵɵComponentDeclaration<UiChartTableComponent, "ui-chart-table", never, {
@@ -354,14 +438,25 @@ export declare class UiChartTableComponent {
354
438
  "required": false;
355
439
  "isSignal": true;
356
440
  };
441
+ "masked": {
442
+ "alias": "masked";
443
+ "required": false;
444
+ "isSignal": true;
445
+ };
357
446
  }, {}, never, never, true, never>;
358
447
  }
359
448
  /**
360
- * A row of colour keys naming what each colour means. Charts use it above
361
- * the plot, but it works next to anything coloured by series.
449
+ * A row of colour keys naming what each colour means. Link it to a chart
450
+ * with `for`, or pass `items` to use it next to anything coloured by series.
362
451
  */
363
452
  export declare class UiChartLegendComponent {
364
453
  readonly items: import("@angular/core").InputSignal<ChartLegendItem[]>;
454
+ /** Small text after the items, e.g. how many series aren't listed. */
455
+ readonly note: import("@angular/core").InputSignal<string>;
456
+ /** A chart to take items from and hide or fade series on, set its `legend` to `none`. */
457
+ readonly for: import("@angular/core").InputSignal<ChartLegendSource | null>;
458
+ /** Adjusts the linked chart's items, e.g. to relabel them. Keep each `name`. */
459
+ readonly itemsWith: import("@angular/core").InputSignal<((items: ChartLegendItem[]) => ChartLegendItem[]) | null>;
365
460
  /** Names of items switched off, bound two-way when `toggleable`. */
366
461
  readonly hidden: import("@angular/core").ModelSignal<string[]>;
367
462
  /** Lets each item be clicked to hide or show its series. */
@@ -371,6 +466,9 @@ export declare class UiChartLegendComponent {
371
466
  private readonly hovered;
372
467
  private readonly focused;
373
468
  private readonly pointedAt;
469
+ protected readonly shownItems: import("@angular/core").Signal<ChartLegendItem[]>;
470
+ protected readonly shownNote: import("@angular/core").Signal<string>;
471
+ private readonly hiddenNames;
374
472
  protected readonly visibleCount: import("@angular/core").Signal<number>;
375
473
  constructor();
376
474
  protected hover(name: string | null): void;
@@ -382,7 +480,22 @@ export declare class UiChartLegendComponent {
382
480
  static ɵcmp: i0.ɵɵComponentDeclaration<UiChartLegendComponent, "ui-chart-legend", never, {
383
481
  "items": {
384
482
  "alias": "items";
385
- "required": true;
483
+ "required": false;
484
+ "isSignal": true;
485
+ };
486
+ "note": {
487
+ "alias": "note";
488
+ "required": false;
489
+ "isSignal": true;
490
+ };
491
+ "for": {
492
+ "alias": "for";
493
+ "required": false;
494
+ "isSignal": true;
495
+ };
496
+ "itemsWith": {
497
+ "alias": "itemsWith";
498
+ "required": false;
386
499
  "isSignal": true;
387
500
  };
388
501
  "hidden": {
@@ -409,6 +522,10 @@ export declare class UiLineChartComponent extends UiAxisChartBase {
409
522
  readonly curve: import("@angular/core").InputSignal<"straight" | "smooth" | "stepline">;
410
523
  /** Draws a dot on every point, not just the hovered one. Handy with few points. */
411
524
  readonly showPoints: import("@angular/core").InputSignalWithTransform<boolean, unknown>;
525
+ /** Shades this category and everything after it as a forecast. */
526
+ readonly projectedFrom: import("@angular/core").InputSignal<string | null>;
527
+ readonly projectedLabel: import("@angular/core").InputSignal<string>;
528
+ private readonly projectedAnnotations;
412
529
  protected readonly chartOptions: import("@angular/core").Signal<ApexCharts.ApexOptions>;
413
530
  private tooltipOrder;
414
531
  static ɵfac: i0.ɵɵFactoryDeclaration<UiLineChartComponent, never>;
@@ -423,6 +540,16 @@ export declare class UiLineChartComponent extends UiAxisChartBase {
423
540
  "required": false;
424
541
  "isSignal": true;
425
542
  };
543
+ "projectedFrom": {
544
+ "alias": "projectedFrom";
545
+ "required": false;
546
+ "isSignal": true;
547
+ };
548
+ "projectedLabel": {
549
+ "alias": "projectedLabel";
550
+ "required": false;
551
+ "isSignal": true;
552
+ };
426
553
  }, {}, never, never, true, never>;
427
554
  }
428
555
  /** How points are joined, straight segments, a smooth curve, or steps. */
@@ -436,13 +563,14 @@ export type LineChartCurve = typeof LineChartCurves[number];
436
563
  */
437
564
  export declare class UiPieChartComponent extends UiAxisChartBase {
438
565
  readonly variant: import("@angular/core").InputSignal<"pie" | "donut">;
566
+ private readonly percentFormatter;
439
567
  /** Shown above the total in the middle of a donut. */
440
568
  readonly totalLabel: import("@angular/core").InputSignal<string>;
441
569
  protected readonly values: import("@angular/core").Signal<(number | null)[]>;
442
570
  protected readonly isEmpty: import("@angular/core").Signal<boolean>;
443
571
  protected readonly isMuted: import("@angular/core").Signal<boolean[]>;
444
572
  protected readonly styles: import("@angular/core").Signal<ChartSeriesStyle[]>;
445
- protected readonly legendItems: import("@angular/core").Signal<{
573
+ readonly legendItems: import("@angular/core").Signal<{
446
574
  colour: string;
447
575
  dashed: boolean;
448
576
  name: string;
@@ -467,6 +595,42 @@ export declare class UiPieChartComponent extends UiAxisChartBase {
467
595
  export declare const PieChartVariants: readonly ["pie", "donut"];
468
596
  /** @see {@link PieChartVariants} */
469
597
  export type PieChartVariant = typeof PieChartVariants[number];
598
+ export interface UiFormat {
599
+ /** ISO 4217 code, e.g. "GBP". */
600
+ currency: string;
601
+ /** BCP 47 tag, e.g. "en-GB". */
602
+ locale: string;
603
+ }
604
+ export declare const UI_FORMAT_DEFAULTS: UiFormat;
605
+ export declare const UI_FORMAT: InjectionToken<UiFormat>;
606
+ export declare function provideUiFormat(format: Partial<UiFormat>): Provider;
607
+ export interface MoneyFormatterParts {
608
+ format: (value: number) => string;
609
+ mask: string;
610
+ }
611
+ /** The unmasked formatter and mask behind a formatter from `injectMoneyFormatter`, null for any other function. */
612
+ export declare function moneyFormatterParts(formatter: (value: number) => string): MoneyFormatterParts | null;
613
+ /** Needs an injection context. Reads `UI_PRIVACY` on every call, so a template or computed calling it follows the mode. */
614
+ export declare function injectMoneyFormatter(options?: Intl.NumberFormatOptions): (value: number) => string;
615
+ export declare const UiPrivacies: readonly ["visible", "discreet", "hidden"];
616
+ /** Discreet hides amounts but keeps their shape, hidden hides everything about them. */
617
+ export type UiPrivacy = typeof UiPrivacies[number];
618
+ export declare const UI_PRIVACY: InjectionToken<Signal<"visible" | "discreet" | "hidden">>;
619
+ /** The factory runs in an injection context, so it can return a signal from an app service. */
620
+ export declare function provideUiPrivacy(privacy: () => Signal<UiPrivacy>): Provider;
621
+ /** The fixed mask for private text, e.g. a transaction's description. */
622
+ export declare const PRIVATE_TEXT_MASK = "- - -";
623
+ /** What screen readers hear in place of private text. */
624
+ export declare const PRIVATE_TEXT_LABEL = "text hidden";
625
+ export declare function maskMoney(currency: string, locale: string): string;
626
+ export interface PrivateTextFormatter {
627
+ /** The text, or `PRIVATE_TEXT_MASK`. For visible attributes like `title`. */
628
+ (text: string | null | undefined): string;
629
+ /** The text, or `PRIVATE_TEXT_LABEL`. For `aria-*`, so screen readers don't read out dashes. */
630
+ label: (text: string | null | undefined) => string;
631
+ }
632
+ /** Needs an injection context. Reads `UI_PRIVACY` on every call, so a template or computed calling it follows the mode. */
633
+ export declare function injectPrivateText(): PrivateTextFormatter;
470
634
  /** Native type values ui-input supports. File/checkbox/radio/range need their own components. */
471
635
  export declare const InputTypes: readonly ["text", "email", "tel", "url", "search", "password", "number", "date", "time", "datetime-local", "month", "week", "color"];
472
636
  /** @see {@link InputTypes} */
@@ -568,7 +732,7 @@ export declare class UiDropzoneComponent {
568
732
  readonly maxSize: import("@angular/core").InputSignal<number | null>;
569
733
  readonly title: import("@angular/core").InputSignal<string>;
570
734
  readonly hint: import("@angular/core").InputSignal<string>;
571
- readonly icon: import("@angular/core").InputSignal<string>;
735
+ readonly icon: import("@angular/core").InputSignal<keyof import("@ng-icons/core").NgIconNameMap>;
572
736
  readonly rejected: import("@angular/core").OutputEmitterRef<FileRejection[]>;
573
737
  private readonly picker;
574
738
  private dragDepth;
@@ -714,7 +878,7 @@ export declare class UiInputComponent<ValueType = string> {
714
878
  readonly name: import("@angular/core").InputSignal<string>;
715
879
  readonly placeholder: import("@angular/core").InputSignal<string>;
716
880
  readonly autocomplete: import("@angular/core").InputSignal<string>;
717
- readonly inputmode: import("@angular/core").InputSignal<"" | "none" | "text" | "search" | "numeric" | "decimal" | "email" | "tel" | "url">;
881
+ readonly inputmode: import("@angular/core").InputSignal<"" | "decimal" | "none" | "text" | "search" | "numeric" | "email" | "tel" | "url">;
718
882
  readonly required: import("@angular/core").InputSignalWithTransform<boolean, unknown>;
719
883
  readonly disabled: import("@angular/core").InputSignalWithTransform<boolean, unknown>;
720
884
  readonly readonly: import("@angular/core").InputSignalWithTransform<boolean, unknown>;
@@ -728,6 +892,8 @@ export declare class UiInputComponent<ValueType = string> {
728
892
  readonly maxlength: import("@angular/core").InputSignal<number | null>;
729
893
  readonly autofocus: import("@angular/core").InputSignalWithTransform<boolean, unknown>;
730
894
  readonly spellcheck: import("@angular/core").InputSignalWithTransform<boolean, unknown>;
895
+ /** With `type="password"`, adds a button to show and hide what's been typed. */
896
+ readonly revealable: import("@angular/core").InputSignalWithTransform<boolean, unknown>;
731
897
  readonly list: import("@angular/core").InputSignal<string>;
732
898
  readonly ariaLabel: import("@angular/core").InputSignal<string>;
733
899
  readonly describedBy: import("@angular/core").InputSignal<string>;
@@ -741,6 +907,9 @@ export declare class UiInputComponent<ValueType = string> {
741
907
  readonly blurred: import("@angular/core").OutputEmitterRef<FocusEvent>;
742
908
  readonly leadingElement: import("@angular/core").Signal<TemplateRef<unknown> | undefined>;
743
909
  readonly trailingElement: import("@angular/core").Signal<TemplateRef<unknown> | undefined>;
910
+ protected readonly revealed: import("@angular/core").WritableSignal<boolean>;
911
+ protected readonly canReveal: import("@angular/core").Signal<boolean>;
912
+ protected readonly shownType: import("@angular/core").Signal<"number" | "color" | "text" | "search" | "time" | "email" | "tel" | "url" | "password" | "date" | "datetime-local" | "month" | "week">;
744
913
  readonly generatedClasses: import("@angular/core").Signal<string>;
745
914
  protected handleInput(event: Event): void;
746
915
  protected handleFocus(event: FocusEvent): void;
@@ -848,6 +1017,11 @@ export declare class UiInputComponent<ValueType = string> {
848
1017
  "required": false;
849
1018
  "isSignal": true;
850
1019
  };
1020
+ "revealable": {
1021
+ "alias": "revealable";
1022
+ "required": false;
1023
+ "isSignal": true;
1024
+ };
851
1025
  "list": {
852
1026
  "alias": "list";
853
1027
  "required": false;
@@ -1069,7 +1243,7 @@ export declare class UiSelectComponent<Model = unknown> {
1069
1243
  readonly searchMode: import("@angular/core").InputSignal<SearchMode>;
1070
1244
  readonly disabled: import("@angular/core").InputSignalWithTransform<boolean, unknown>;
1071
1245
  readonly validationState: import("@angular/core").ModelSignal<InputValidation>;
1072
- readonly clearable: import("@angular/core").InputSignal<boolean>;
1246
+ readonly clearable: import("@angular/core").InputSignalWithTransform<boolean, unknown>;
1073
1247
  readonly clearLabel: import("@angular/core").InputSignal<string>;
1074
1248
  /**
1075
1249
  * Offers a "Create" row when a search matches nothing. Needs a
@@ -1104,6 +1278,7 @@ export declare class UiSelectComponent<Model = unknown> {
1104
1278
  readonly listId: string;
1105
1279
  readonly hasSelection: import("@angular/core").Signal<boolean>;
1106
1280
  readonly triggerLabel: import("@angular/core").Signal<string>;
1281
+ readonly isEmpty: import("@angular/core").Signal<boolean>;
1107
1282
  /** Tags only replace the trigger text when there's no inline search box. */
1108
1283
  readonly showTags: import("@angular/core").Signal<boolean>;
1109
1284
  /** The text to create from, or null when there's nothing to offer. */
@@ -1400,7 +1575,6 @@ export declare class UiTextareaComponent {
1400
1575
  export declare class UiAlertComponent {
1401
1576
  readonly appearance: import("@angular/core").InputSignal<"soft" | "bordered">;
1402
1577
  readonly intent: import("@angular/core").InputSignal<string>;
1403
- readonly classes: import("@angular/core").InputSignal<string>;
1404
1578
  readonly icon: import("@angular/core").Signal<TemplateRef<unknown> | undefined>;
1405
1579
  readonly generatedClasses: import("@angular/core").Signal<string>;
1406
1580
  static ɵfac: i0.ɵɵFactoryDeclaration<UiAlertComponent, never>;
@@ -1415,22 +1589,47 @@ export declare class UiAlertComponent {
1415
1589
  "required": false;
1416
1590
  "isSignal": true;
1417
1591
  };
1418
- "classes": {
1419
- "alias": "classes";
1420
- "required": false;
1421
- "isSignal": true;
1422
- };
1423
1592
  }, {}, ["icon"], ["*"], true, never>;
1424
1593
  }
1425
1594
  export declare const AlertIntents: string[];
1426
1595
  export declare const AlertAppearances: readonly ["soft", "bordered"];
1427
1596
  export type AlertIntent = typeof AlertIntents[number];
1428
1597
  export type AlertAppearance = typeof AlertAppearances[number];
1598
+ export declare class UiAvatarComponent {
1599
+ readonly name: import("@angular/core").InputSignal<string>;
1600
+ readonly src: import("@angular/core").InputSignal<string | null>;
1601
+ readonly size: import("@angular/core").InputSignal<"sm" | "md" | "lg">;
1602
+ private readonly failedSrc;
1603
+ protected readonly showImage: import("@angular/core").Signal<boolean>;
1604
+ protected readonly initials: import("@angular/core").Signal<string>;
1605
+ readonly generatedClasses: import("@angular/core").Signal<string>;
1606
+ protected imageFailed(): void;
1607
+ static ɵfac: i0.ɵɵFactoryDeclaration<UiAvatarComponent, never>;
1608
+ static ɵcmp: i0.ɵɵComponentDeclaration<UiAvatarComponent, "ui-avatar", never, {
1609
+ "name": {
1610
+ "alias": "name";
1611
+ "required": true;
1612
+ "isSignal": true;
1613
+ };
1614
+ "src": {
1615
+ "alias": "src";
1616
+ "required": false;
1617
+ "isSignal": true;
1618
+ };
1619
+ "size": {
1620
+ "alias": "size";
1621
+ "required": false;
1622
+ "isSignal": true;
1623
+ };
1624
+ }, {}, never, never, true, never>;
1625
+ }
1626
+ export declare const AvatarSizes: readonly ["sm", "md", "lg"];
1627
+ /** @see {@link AvatarSizes} */
1628
+ export type AvatarSize = typeof AvatarSizes[number];
1429
1629
  export declare class UiBadgeComponent {
1430
1630
  readonly appearance: import("@angular/core").InputSignal<"solid" | "outline" | "soft">;
1431
1631
  readonly intent: import("@angular/core").InputSignal<"primary" | "secondary" | "success" | "warning" | "danger">;
1432
1632
  readonly size: import("@angular/core").InputSignal<"xs" | "sm" | "md" | "lg">;
1433
- readonly classes: import("@angular/core").InputSignal<string>;
1434
1633
  readonly generatedClasses: import("@angular/core").Signal<string>;
1435
1634
  static ɵfac: i0.ɵɵFactoryDeclaration<UiBadgeComponent, never>;
1436
1635
  static ɵcmp: i0.ɵɵComponentDeclaration<UiBadgeComponent, "ui-badge", never, {
@@ -1449,11 +1648,6 @@ export declare class UiBadgeComponent {
1449
1648
  "required": false;
1450
1649
  "isSignal": true;
1451
1650
  };
1452
- "classes": {
1453
- "alias": "classes";
1454
- "required": false;
1455
- "isSignal": true;
1456
- };
1457
1651
  }, {}, never, ["*"], true, never>;
1458
1652
  }
1459
1653
  export declare const BadgeIntents: readonly ["primary", "secondary", "success", "warning", "danger"];
@@ -1466,14 +1660,14 @@ export type BadgeSize = typeof BadgeSizes[number];
1466
1660
  * A general-purpose button.
1467
1661
  */
1468
1662
  export declare class UiButtonComponent {
1469
- readonly appearance: import("@angular/core").InputSignal<"solid" | "none" | "link" | "outline" | "ghost" | "white">;
1663
+ readonly appearance: import("@angular/core").InputSignal<"none" | "solid" | "link" | "outline" | "ghost" | "white">;
1470
1664
  readonly intent: import("@angular/core").InputSignal<"none" | "primary" | "secondary" | "success" | "warning" | "danger">;
1471
1665
  readonly size: import("@angular/core").InputSignal<"sm" | "md" | "lg">;
1472
1666
  readonly classes: import("@angular/core").InputSignal<string>;
1473
1667
  readonly type: import("@angular/core").InputSignal<"button" | "reset" | "submit">;
1474
1668
  readonly ariaLabel: import("@angular/core").InputSignal<string>;
1475
- readonly disabled: import("@angular/core").InputSignal<boolean>;
1476
- readonly loading: import("@angular/core").InputSignal<boolean>;
1669
+ readonly disabled: import("@angular/core").InputSignalWithTransform<boolean, unknown>;
1670
+ readonly loading: import("@angular/core").InputSignalWithTransform<boolean, unknown>;
1477
1671
  /**
1478
1672
  * Whether the underlying `<button>` element should be disabled - true when
1479
1673
  * `disabled` is set explicitly, or implicitly while `loading` is true.
@@ -1678,13 +1872,57 @@ export declare class UiCalendarComponent {
1678
1872
  "range": "rangeChange";
1679
1873
  }, never, never, true, never>;
1680
1874
  }
1875
+ export declare class UiCardComponent {
1876
+ readonly radius: import("@angular/core").InputSignal<"none" | "sm" | "md" | "lg" | "xl">;
1877
+ readonly generatedClasses: import("@angular/core").Signal<string>;
1878
+ static ɵfac: i0.ɵɵFactoryDeclaration<UiCardComponent, never>;
1879
+ static ɵcmp: i0.ɵɵComponentDeclaration<UiCardComponent, "ui-card", never, {
1880
+ "radius": {
1881
+ "alias": "radius";
1882
+ "required": false;
1883
+ "isSignal": true;
1884
+ };
1885
+ }, {}, never, ["*"], true, never>;
1886
+ }
1887
+ /** The radius that a card can hold. Maps directly to tailwindcss' rounded classes. */
1888
+ export declare const CardRadii: readonly ["none", "sm", "md", "lg", "xl"];
1889
+ /** @see {@link CardRadii} */
1890
+ export type CardRadius = typeof CardRadii[number];
1891
+ export declare const radiusClasses: Record<CardRadius, string>;
1892
+ export declare class UiCardHeaderComponent {
1893
+ readonly heading: import("@angular/core").InputSignal<string>;
1894
+ readonly subtitle: import("@angular/core").InputSignal<string>;
1895
+ /** Pick the level that fits the page's outline, it doesn't change the look. */
1896
+ readonly headingLevel: import("@angular/core").InputSignal<3 | 2 | 4>;
1897
+ static ɵfac: i0.ɵɵFactoryDeclaration<UiCardHeaderComponent, never>;
1898
+ static ɵcmp: i0.ɵɵComponentDeclaration<UiCardHeaderComponent, "ui-card-header", never, {
1899
+ "heading": {
1900
+ "alias": "heading";
1901
+ "required": true;
1902
+ "isSignal": true;
1903
+ };
1904
+ "subtitle": {
1905
+ "alias": "subtitle";
1906
+ "required": false;
1907
+ "isSignal": true;
1908
+ };
1909
+ "headingLevel": {
1910
+ "alias": "headingLevel";
1911
+ "required": false;
1912
+ "isSignal": true;
1913
+ };
1914
+ }, {}, never, ["*"], true, never>;
1915
+ }
1916
+ export declare const CardHeadingLevels: readonly [2, 3, 4];
1917
+ /** @see {@link CardHeadingLevels} */
1918
+ export type CardHeadingLevel = typeof CardHeadingLevels[number];
1681
1919
  export declare class UiContainerComponent {
1682
1920
  static ɵfac: i0.ɵɵFactoryDeclaration<UiContainerComponent, never>;
1683
1921
  static ɵcmp: i0.ɵɵComponentDeclaration<UiContainerComponent, "ui-container", never, {}, {}, never, ["*"], true, never>;
1684
1922
  }
1685
1923
  export declare class UiDrawerComponent {
1686
1924
  readonly isOpen: import("@angular/core").WritableSignal<boolean>;
1687
- readonly enableBackdrop: import("@angular/core").InputSignal<boolean>;
1925
+ readonly enableBackdrop: import("@angular/core").InputSignalWithTransform<boolean, unknown>;
1688
1926
  readonly label: import("@angular/core").InputSignal<string>;
1689
1927
  readonly subLabel: import("@angular/core").InputSignal<string>;
1690
1928
  static ɵfac: i0.ɵɵFactoryDeclaration<UiDrawerComponent, never>;
@@ -1704,7 +1942,7 @@ export declare class UiDrawerComponent {
1704
1942
  "required": false;
1705
1943
  "isSignal": true;
1706
1944
  };
1707
- }, {}, never, never, true, never>;
1945
+ }, {}, never, ["[drawer-actions]", "*"], true, never>;
1708
1946
  }
1709
1947
  export declare class UiDropdownDirective {
1710
1948
  readonly element: ElementRef<any>;
@@ -1760,15 +1998,15 @@ export declare class UiDropdownComponent {
1760
1998
  }, {}, ["content"], ["*"], true, never>;
1761
1999
  }
1762
2000
  export declare class UiKpiComponent {
1763
- readonly title: import("@angular/core").InputSignal<string>;
2001
+ readonly label: import("@angular/core").InputSignal<string>;
1764
2002
  readonly value: import("@angular/core").InputSignal<string>;
1765
2003
  readonly hint: import("@angular/core").InputSignal<string>;
1766
- readonly icon: import("@angular/core").InputSignal<string | undefined>;
2004
+ readonly icon: import("@angular/core").InputSignal<keyof import("@ng-icons/core").NgIconNameMap | undefined>;
1767
2005
  readonly iconPosition: import("@angular/core").InputSignal<"right" | "left">;
1768
2006
  static ɵfac: i0.ɵɵFactoryDeclaration<UiKpiComponent, never>;
1769
2007
  static ɵcmp: i0.ɵɵComponentDeclaration<UiKpiComponent, "ui-kpi", never, {
1770
- "title": {
1771
- "alias": "title";
2008
+ "label": {
2009
+ "alias": "label";
1772
2010
  "required": false;
1773
2011
  "isSignal": true;
1774
2012
  };
@@ -1855,18 +2093,25 @@ export declare class UiModalComponent {
1855
2093
  * Formats a money value, e.g. -42.1 as "-£42.10".
1856
2094
  */
1857
2095
  export declare class UiMoneyComponent {
2096
+ private readonly defaults;
2097
+ private readonly privacy;
1858
2098
  readonly value: import("@angular/core").InputSignal<number | null>;
2099
+ /** Defaults to the currency from `provideUiFormat`. */
1859
2100
  readonly currency: import("@angular/core").InputSignal<string>;
2101
+ /** Defaults to the locale from `provideUiFormat`. */
1860
2102
  readonly locale: import("@angular/core").InputSignal<string>;
1861
2103
  readonly signDisplay: import("@angular/core").InputSignal<"auto" | "always" | "exceptZero" | "never">;
1862
2104
  /** Green for money in, red for money out. */
1863
2105
  readonly colourBySign: import("@angular/core").InputSignalWithTransform<boolean, unknown>;
2106
+ /** Rounds to whole units, e.g. "£2,235" for headline figures where pence are noise. */
2107
+ readonly wholeUnits: import("@angular/core").InputSignalWithTransform<boolean, unknown>;
1864
2108
  /** Short form like "£12K", the full amount goes in the title. */
1865
2109
  readonly compact: import("@angular/core").InputSignalWithTransform<boolean, unknown>;
1866
2110
  /** Shown when there's no value. */
1867
2111
  readonly placeholder: import("@angular/core").InputSignal<string>;
1868
- readonly classes: import("@angular/core").InputSignal<string>;
1869
2112
  private readonly amount;
2113
+ protected readonly masked: import("@angular/core").Signal<boolean>;
2114
+ protected readonly mask: import("@angular/core").Signal<string>;
1870
2115
  protected readonly formatted: import("@angular/core").Signal<string>;
1871
2116
  protected readonly title: import("@angular/core").Signal<string | null>;
1872
2117
  readonly generatedClasses: import("@angular/core").Signal<string>;
@@ -1899,6 +2144,11 @@ export declare class UiMoneyComponent {
1899
2144
  "required": false;
1900
2145
  "isSignal": true;
1901
2146
  };
2147
+ "wholeUnits": {
2148
+ "alias": "wholeUnits";
2149
+ "required": false;
2150
+ "isSignal": true;
2151
+ };
1902
2152
  "compact": {
1903
2153
  "alias": "compact";
1904
2154
  "required": false;
@@ -1909,11 +2159,6 @@ export declare class UiMoneyComponent {
1909
2159
  "required": false;
1910
2160
  "isSignal": true;
1911
2161
  };
1912
- "classes": {
1913
- "alias": "classes";
1914
- "required": false;
1915
- "isSignal": true;
1916
- };
1917
2162
  }, {}, never, never, true, never>;
1918
2163
  }
1919
2164
  /** Intl signDisplay values, controls when a + or - is shown. */
@@ -1925,8 +2170,6 @@ export type PaginationItem = number | 'ellipsis';
1925
2170
  export declare class UiPaginationComponent {
1926
2171
  readonly page: import("@angular/core").ModelSignal<number>;
1927
2172
  readonly totalPages: import("@angular/core").InputSignal<number>;
1928
- readonly classes: import("@angular/core").InputSignal<string>;
1929
- readonly generatedClasses: import("@angular/core").Signal<string>;
1930
2173
  readonly isFirstPage: import("@angular/core").Signal<boolean>;
1931
2174
  readonly isLastPage: import("@angular/core").Signal<boolean>;
1932
2175
  readonly items: import("@angular/core").Signal<PaginationItem[]>;
@@ -1944,15 +2187,29 @@ export declare class UiPaginationComponent {
1944
2187
  "required": true;
1945
2188
  "isSignal": true;
1946
2189
  };
1947
- "classes": {
1948
- "alias": "classes";
1949
- "required": false;
1950
- "isSignal": true;
1951
- };
1952
2190
  }, {
1953
2191
  "page": "pageChange";
1954
2192
  }, never, never, true, never>;
1955
2193
  }
2194
+ /**
2195
+ * Text that privacy mode masks, e.g. a transaction's description.
2196
+ */
2197
+ export declare class UiPrivateComponent {
2198
+ private readonly privacy;
2199
+ readonly text: import("@angular/core").InputSignal<string | null | undefined>;
2200
+ protected readonly mask = "- - -";
2201
+ protected readonly label = "text hidden";
2202
+ protected readonly masked: import("@angular/core").Signal<boolean>;
2203
+ readonly generatedClasses: import("@angular/core").Signal<string>;
2204
+ static ɵfac: i0.ɵɵFactoryDeclaration<UiPrivateComponent, never>;
2205
+ static ɵcmp: i0.ɵɵComponentDeclaration<UiPrivateComponent, "ui-private", never, {
2206
+ "text": {
2207
+ "alias": "text";
2208
+ "required": true;
2209
+ "isSignal": true;
2210
+ };
2211
+ }, {}, never, never, true, never>;
2212
+ }
1956
2213
  /** Same names as badges, so a status reads the same wherever it shows. */
1957
2214
  export declare const ProgressIntents: readonly ["primary", "secondary", "success", "warning", "danger"];
1958
2215
  /** @see {@link ProgressIntents} */
@@ -1995,7 +2252,7 @@ export declare class UiProgressComponent {
1995
2252
  readonly shape: import("@angular/core").InputSignal<"square" | "straight" | "rounded">;
1996
2253
  readonly orientation: import("@angular/core").InputSignal<"vertical" | "horizontal">;
1997
2254
  readonly title: import("@angular/core").InputSignal<string>;
1998
- readonly labelPosition: import("@angular/core").InputSignal<"top" | "none" | "end" | "floating" | "inside">;
2255
+ readonly labelPosition: import("@angular/core").InputSignal<"none" | "top" | "end" | "floating" | "inside">;
1999
2256
  readonly labelWith: import("@angular/core").InputSignal<(value: number, max: number) => string>;
2000
2257
  /** Splits the bar into this many blocks. */
2001
2258
  readonly steps: import("@angular/core").InputSignal<number | null>;
@@ -2079,6 +2336,46 @@ export declare class UiProgressComponent {
2079
2336
  };
2080
2337
  }, {}, never, never, true, never>;
2081
2338
  }
2339
+ export interface SegmentedOption<T> {
2340
+ value: T;
2341
+ label: string;
2342
+ /** Read out instead of `label`, for when the label is abbreviated, e.g. "6M". */
2343
+ ariaLabel?: string;
2344
+ }
2345
+ export declare class UiSegmentedComponent<T> {
2346
+ readonly options: import("@angular/core").InputSignal<SegmentedOption<T>[]>;
2347
+ readonly value: import("@angular/core").ModelSignal<T>;
2348
+ /** What the options choose between, e.g. "How far back the charts go". */
2349
+ readonly ariaLabel: import("@angular/core").InputSignal<string>;
2350
+ /** Stretches to the container's width with the options sharing it evenly. */
2351
+ readonly fill: import("@angular/core").InputSignalWithTransform<boolean, unknown>;
2352
+ protected readonly name: string;
2353
+ static ɵfac: i0.ɵɵFactoryDeclaration<UiSegmentedComponent<any>, never>;
2354
+ static ɵcmp: i0.ɵɵComponentDeclaration<UiSegmentedComponent<any>, "ui-segmented", never, {
2355
+ "options": {
2356
+ "alias": "options";
2357
+ "required": true;
2358
+ "isSignal": true;
2359
+ };
2360
+ "value": {
2361
+ "alias": "value";
2362
+ "required": true;
2363
+ "isSignal": true;
2364
+ };
2365
+ "ariaLabel": {
2366
+ "alias": "ariaLabel";
2367
+ "required": true;
2368
+ "isSignal": true;
2369
+ };
2370
+ "fill": {
2371
+ "alias": "fill";
2372
+ "required": false;
2373
+ "isSignal": true;
2374
+ };
2375
+ }, {
2376
+ "value": "valueChange";
2377
+ }, never, never, true, never>;
2378
+ }
2082
2379
  /**
2083
2380
  * A placeholder shown while content loads. Size it with classes on the
2084
2381
  * element, e.g. `class="w-48"` for text or `class="size-12"` for a circle.
@@ -2088,7 +2385,6 @@ export declare class UiSkeletonComponent {
2088
2385
  readonly animated: import("@angular/core").InputSignalWithTransform<boolean, unknown>;
2089
2386
  /** Text only, stacks this many lines with a shorter last one. */
2090
2387
  readonly lines: import("@angular/core").InputSignalWithTransform<number, unknown>;
2091
- readonly classes: import("@angular/core").InputSignal<string>;
2092
2388
  protected readonly lineIndexes: import("@angular/core").Signal<number[]>;
2093
2389
  readonly generatedClasses: import("@angular/core").Signal<string>;
2094
2390
  static ɵfac: i0.ɵɵFactoryDeclaration<UiSkeletonComponent, never>;
@@ -2108,20 +2404,27 @@ export declare class UiSkeletonComponent {
2108
2404
  "required": false;
2109
2405
  "isSignal": true;
2110
2406
  };
2111
- "classes": {
2112
- "alias": "classes";
2113
- "required": false;
2114
- "isSignal": true;
2115
- };
2116
2407
  }, {}, never, never, true, never>;
2117
2408
  }
2118
2409
  /** What a skeleton stands in for, lines of text, an avatar or a block. */
2119
2410
  export declare const SkeletonShapes: readonly ["text", "circle", "rect"];
2120
2411
  /** @see {@link SkeletonShapes} */
2121
2412
  export type SkeletonShape = typeof SkeletonShapes[number];
2413
+ /** Each stat is its own `dl`, so wrap a row of them in a plain div. */
2414
+ export declare class UiStatComponent {
2415
+ readonly label: import("@angular/core").InputSignal<string>;
2416
+ static ɵfac: i0.ɵɵFactoryDeclaration<UiStatComponent, never>;
2417
+ static ɵcmp: i0.ɵɵComponentDeclaration<UiStatComponent, "ui-stat", never, {
2418
+ "label": {
2419
+ "alias": "label";
2420
+ "required": true;
2421
+ "isSignal": true;
2422
+ };
2423
+ }, {}, never, ["*", "[stat-change]", "[stat-note]"], true, never>;
2424
+ }
2122
2425
  export declare class UiTabDirective {
2123
2426
  label: import("@angular/core").InputSignal<string>;
2124
- disabled: import("@angular/core").InputSignal<boolean>;
2427
+ disabled: import("@angular/core").InputSignalWithTransform<boolean, unknown>;
2125
2428
  active: import("@angular/core").ModelSignal<boolean>;
2126
2429
  static ɵfac: i0.ɵɵFactoryDeclaration<UiTabDirective, never>;
2127
2430
  static ɵdir: i0.ɵɵDirectiveDeclaration<UiTabDirective, "[uiTab]", never, {
@@ -2180,8 +2483,10 @@ export interface TableColumn<Row> {
2180
2483
  accessor: (row: Row) => unknown;
2181
2484
  /** how the cell value is formatted for display, defaults to plain text */
2182
2485
  displayType?: TableColumnDisplayType;
2183
- /** ISO currency code, used when displayType is 'currency' */
2486
+ /** ISO currency code, used when displayType is 'currency'. Defaults to the currency from `provideUiFormat`. */
2184
2487
  currency?: string;
2488
+ /** Masks the cell in privacy mode, e.g. a transaction's description. Currency cells are already masked, icon cells have no text. */
2489
+ sensitive?: boolean;
2185
2490
  sortable?: boolean;
2186
2491
  filterable?: boolean;
2187
2492
  /** when set, the filter renders as a select instead of a free-text contains filter */
@@ -2243,6 +2548,8 @@ interface ColumnDragPreview {
2243
2548
  }
2244
2549
  export declare class UiTableComponent<Row = unknown> implements OnInit, OnDestroy {
2245
2550
  readonly classes: import("@angular/core").InputSignal<string>;
2551
+ /** Lets controls elsewhere on the page link to this table, e.g. `<ui-search [table]="'transactions'">`. */
2552
+ readonly tableId: import("@angular/core").InputSignal<string | null>;
2246
2553
  readonly columns: import("@angular/core").InputSignal<TableColumn<Row>[]>;
2247
2554
  readonly dataSource: import("@angular/core").InputSignal<TableDataSource<Row>>;
2248
2555
  readonly emptyMessage: import("@angular/core").InputSignal<string>;
@@ -2288,6 +2595,8 @@ export declare class UiTableComponent<Row = unknown> implements OnInit, OnDestro
2288
2595
  protected readonly hasFilterableColumns: import("@angular/core").Signal<boolean>;
2289
2596
  protected readonly activeFilterCount: import("@angular/core").Signal<number>;
2290
2597
  protected readonly hasActions: import("@angular/core").Signal<boolean>;
2598
+ private readonly hasSensitiveColumns;
2599
+ protected readonly fixedWidth: import("@angular/core").Signal<number | null>;
2291
2600
  protected readonly actionsColumnWidth: import("@angular/core").Signal<number>;
2292
2601
  protected readonly totalPages: import("@angular/core").Signal<number>;
2293
2602
  protected readonly resultsLabel: import("@angular/core").Signal<string>;
@@ -2298,6 +2607,11 @@ export declare class UiTableComponent<Row = unknown> implements OnInit, OnDestro
2298
2607
  private readonly load$;
2299
2608
  private readonly destroyRef;
2300
2609
  private readonly cdr;
2610
+ private readonly registry;
2611
+ protected readonly uiFormat: import("@area8975/ui").UiFormat;
2612
+ private readonly privateText;
2613
+ private loadedQuery;
2614
+ private loadedFilters;
2301
2615
  private resizeState;
2302
2616
  private columnDragState;
2303
2617
  private readonly filterDataSources;
@@ -2307,6 +2621,7 @@ export declare class UiTableComponent<Row = unknown> implements OnInit, OnDestro
2307
2621
  reload(): void;
2308
2622
  protected cellValue(column: TableColumn<Row>, row: Row): unknown;
2309
2623
  protected cellIconValue(column: TableColumn<Row>, row: Row): string;
2624
+ protected moneyCellValue(column: TableColumn<Row>, row: Row): number | null;
2310
2625
  protected formattedCellValue(column: TableColumn<Row>, row: Row): string;
2311
2626
  protected onQueryChange(value: string): void;
2312
2627
  protected filterValue(columnId: string): string;
@@ -2314,6 +2629,7 @@ export declare class UiTableComponent<Row = unknown> implements OnInit, OnDestro
2314
2629
  protected filterDataSource(column: TableColumn<Row>): SelectDataSource<TableColumnFilterOption>;
2315
2630
  protected selectedFilterOption(column: TableColumn<Row>): TableColumnFilterOption | null;
2316
2631
  protected filterOptionLabel(option: TableColumnFilterOption): string;
2632
+ protected readonly sensitiveFilterOptionLabel: (option: TableColumnFilterOption) => string;
2317
2633
  protected onFilterSelect(columnId: string, option: TableColumnFilterOption | null): void;
2318
2634
  protected clearFilters(): void;
2319
2635
  protected toggleSort(column: TableColumn<Row>): void;
@@ -2350,6 +2666,11 @@ export declare class UiTableComponent<Row = unknown> implements OnInit, OnDestro
2350
2666
  "required": false;
2351
2667
  "isSignal": true;
2352
2668
  };
2669
+ "tableId": {
2670
+ "alias": "tableId";
2671
+ "required": false;
2672
+ "isSignal": true;
2673
+ };
2353
2674
  "columns": {
2354
2675
  "alias": "columns";
2355
2676
  "required": true;
@@ -2442,6 +2763,18 @@ export declare class UiTableComponent<Row = unknown> implements OnInit, OnDestro
2442
2763
  "rowsReordered": "rowsReordered";
2443
2764
  }, never, never, true, never>;
2444
2765
  }
2766
+ export interface UiLinkedTable {
2767
+ readonly query: WritableSignal<string>;
2768
+ readonly filters: WritableSignal<Record<string, unknown>>;
2769
+ }
2770
+ export declare class UiTableRegistry {
2771
+ private readonly tables;
2772
+ get(id: string): UiLinkedTable | null;
2773
+ register(id: string, table: UiLinkedTable): void;
2774
+ unregister(id: string, table: UiLinkedTable): void;
2775
+ static ɵfac: i0.ɵɵFactoryDeclaration<UiTableRegistry, never>;
2776
+ static ɵprov: i0.ɵɵInjectableDeclaration<any>;
2777
+ }
2445
2778
  export declare class UiToastComponent {
2446
2779
  readonly intent: import("@angular/core").InputSignal<"success" | "warning" | "danger" | "info">;
2447
2780
  readonly classes: import("@angular/core").InputSignal<string>;
@@ -2449,7 +2782,7 @@ export declare class UiToastComponent {
2449
2782
  /** ms before the toast dismisses itself, paused while hovered or focused. null never times out. */
2450
2783
  readonly timeoutMs: import("@angular/core").InputSignal<number | null>;
2451
2784
  readonly dismissed: import("@angular/core").OutputEmitterRef<void>;
2452
- protected readonly icon: import("@angular/core").Signal<string>;
2785
+ protected readonly icon: import("@angular/core").Signal<IconType>;
2453
2786
  protected readonly iconColour: import("@angular/core").Signal<string>;
2454
2787
  protected readonly role: import("@angular/core").Signal<"alert" | "status">;
2455
2788
  private hovered;
@@ -2648,6 +2981,7 @@ export declare class UiOverlayComponent implements UiOverlayStackEntry {
2648
2981
  }
2649
2982
  export declare class UiSidebarComponent {
2650
2983
  readonly isOpen: import("@angular/core").ModelSignal<boolean>;
2984
+ readonly isCollapsed: import("@angular/core").Signal<boolean>;
2651
2985
  readonly toggle: () => void;
2652
2986
  static ɵfac: i0.ɵɵFactoryDeclaration<UiSidebarComponent, never>;
2653
2987
  static ɵcmp: i0.ɵɵComponentDeclaration<UiSidebarComponent, "ui-sidebar", ["uiSidebar"], {
@@ -2658,7 +2992,21 @@ export declare class UiSidebarComponent {
2658
2992
  };
2659
2993
  }, {
2660
2994
  "isOpen": "isOpenChange";
2661
- }, never, ["*"], true, never>;
2995
+ }, never, ["*", "[sidebar-footer]"], true, never>;
2996
+ }
2997
+ export declare class UiSidebarGroupComponent {
2998
+ private readonly sidebar;
2999
+ readonly label: import("@angular/core").InputSignal<string>;
3000
+ protected readonly labelId: string;
3001
+ readonly isCollapsed: import("@angular/core").Signal<boolean>;
3002
+ static ɵfac: i0.ɵɵFactoryDeclaration<UiSidebarGroupComponent, never>;
3003
+ static ɵcmp: i0.ɵɵComponentDeclaration<UiSidebarGroupComponent, "ui-sidebar-group", never, {
3004
+ "label": {
3005
+ "alias": "label";
3006
+ "required": true;
3007
+ "isSignal": true;
3008
+ };
3009
+ }, {}, never, ["*"], true, never>;
2662
3010
  }
2663
3011
  export declare class UiSidebarItemComponent {
2664
3012
  private readonly sidebar;
@@ -3002,7 +3350,7 @@ export declare class UiDatepickerComponent {
3002
3350
  }
3003
3351
  export declare class UiDropdownButtonComponent {
3004
3352
  readonly intent: import("@angular/core").InputSignal<"none" | "primary" | "secondary" | "success" | "warning" | "danger">;
3005
- readonly appearance: import("@angular/core").InputSignal<"solid" | "none" | "link" | "outline" | "ghost" | "white">;
3353
+ readonly appearance: import("@angular/core").InputSignal<"none" | "solid" | "link" | "outline" | "ghost" | "white">;
3006
3354
  readonly icon: import("@angular/core").InputSignal<string>;
3007
3355
  readonly isOpen: import("@angular/core").ModelSignal<boolean>;
3008
3356
  static ɵfac: i0.ɵɵFactoryDeclaration<UiDropdownButtonComponent, never>;
@@ -3125,6 +3473,61 @@ export declare class UiFileInputComponent {
3125
3473
  "rejected": "rejected";
3126
3474
  }, never, never, true, never>;
3127
3475
  }
3476
+ export declare class UiSearchComponent {
3477
+ private readonly host;
3478
+ private readonly registry;
3479
+ readonly value: import("@angular/core").ModelSignal<string>;
3480
+ readonly placeholder: import("@angular/core").InputSignal<string>;
3481
+ readonly ariaLabel: import("@angular/core").InputSignal<string>;
3482
+ readonly disabled: import("@angular/core").InputSignalWithTransform<boolean, unknown>;
3483
+ /** How long typing has to pause before `searched` fires, in milliseconds. */
3484
+ readonly debounce: import("@angular/core").InputSignalWithTransform<number, unknown>;
3485
+ /** The `tableId` of a ui-table to search, it can render before or after this. */
3486
+ readonly table: import("@angular/core").InputSignal<string | null>;
3487
+ /** The value once typing pauses, for running a search. Clearing fires straight away. */
3488
+ readonly searched: import("@angular/core").OutputEmitterRef<string>;
3489
+ private readonly linked;
3490
+ private timer;
3491
+ constructor();
3492
+ protected onInput(value: string): void;
3493
+ protected clear(): void;
3494
+ static ɵfac: i0.ɵɵFactoryDeclaration<UiSearchComponent, never>;
3495
+ static ɵcmp: i0.ɵɵComponentDeclaration<UiSearchComponent, "ui-search", never, {
3496
+ "value": {
3497
+ "alias": "value";
3498
+ "required": false;
3499
+ "isSignal": true;
3500
+ };
3501
+ "placeholder": {
3502
+ "alias": "placeholder";
3503
+ "required": false;
3504
+ "isSignal": true;
3505
+ };
3506
+ "ariaLabel": {
3507
+ "alias": "ariaLabel";
3508
+ "required": false;
3509
+ "isSignal": true;
3510
+ };
3511
+ "disabled": {
3512
+ "alias": "disabled";
3513
+ "required": false;
3514
+ "isSignal": true;
3515
+ };
3516
+ "debounce": {
3517
+ "alias": "debounce";
3518
+ "required": false;
3519
+ "isSignal": true;
3520
+ };
3521
+ "table": {
3522
+ "alias": "table";
3523
+ "required": false;
3524
+ "isSignal": true;
3525
+ };
3526
+ }, {
3527
+ "value": "valueChange";
3528
+ "searched": "searched";
3529
+ }, never, never, true, never>;
3530
+ }
3128
3531
  export declare class UiSwitchComponent {
3129
3532
  readonly value: import("@angular/core").ModelSignal<boolean>;
3130
3533
  readonly id: import("@angular/core").InputSignal<string>;
@@ -3156,6 +3559,104 @@ export declare class UiSwitchComponent {
3156
3559
  "value": "valueChange";
3157
3560
  }, never, ["*"], true, never>;
3158
3561
  }
3562
+ export declare const TableFiltersBreakpoints: {
3563
+ readonly sm: "40rem";
3564
+ readonly md: "48rem";
3565
+ readonly lg: "64rem";
3566
+ readonly xl: "80rem";
3567
+ readonly '2xl': "96rem";
3568
+ };
3569
+ /** @see {@link TableFiltersBreakpoints} */
3570
+ export type TableFiltersBreakpoint = keyof typeof TableFiltersBreakpoints;
3571
+ export interface TableFacetOption {
3572
+ value: unknown;
3573
+ label: string;
3574
+ }
3575
+ /** Writes the picked value, or an array when `multiple`, under `id`. */
3576
+ export interface TableOptionsFacet {
3577
+ id: string;
3578
+ label: string;
3579
+ kind: 'options';
3580
+ options: TableFacetOption[];
3581
+ multiple?: boolean;
3582
+ }
3583
+ /** Writes `{ start, end }` ISO dates under `id`. */
3584
+ export interface TableDateRangeFacet {
3585
+ id: string;
3586
+ label: string;
3587
+ kind: 'dateRange';
3588
+ /** Quick picks, see date-range-presets.ts for ready made ones. */
3589
+ presets?: DateRangePreset[];
3590
+ placeholder?: string;
3591
+ min?: IsoDate | null;
3592
+ max?: IsoDate | null;
3593
+ }
3594
+ export type TableFacet = TableOptionsFacet | TableDateRangeFacet;
3595
+ export type TableFacetDateRange = DateRange;
3596
+ type Filters = Record<string, unknown>;
3597
+ type DateMode = 'any' | 'custom' | number;
3598
+ export declare class UiTableFiltersComponent {
3599
+ private readonly registry;
3600
+ readonly facets: import("@angular/core").InputSignal<TableFacet[]>;
3601
+ /** The `tableId` of a ui-table to filter, it can render before or after this. */
3602
+ readonly table: import("@angular/core").InputSignal<string | null>;
3603
+ readonly value: import("@angular/core").ModelSignal<Filters>;
3604
+ /** Below this breakpoint the panel becomes a Filters button and a drawer. */
3605
+ readonly collapseBelow: import("@angular/core").InputSignal<"sm" | "md" | "lg" | "xl" | "2xl">;
3606
+ protected readonly idPrefix: string;
3607
+ protected readonly anyDate: DateMode;
3608
+ protected readonly customDate: DateMode;
3609
+ private readonly customDates;
3610
+ private readonly linked;
3611
+ protected readonly appliedCount: import("@angular/core").Signal<number>;
3612
+ protected readonly anyApplied: import("@angular/core").Signal<boolean>;
3613
+ private readonly window;
3614
+ protected readonly wide: import("@angular/core").WritableSignal<boolean>;
3615
+ constructor();
3616
+ protected groupName(facet: TableFacet): string;
3617
+ protected choiceId(facet: TableFacet, choice: number | string): string;
3618
+ protected picked(facet: TableOptionsFacet): unknown;
3619
+ protected pick(facet: TableOptionsFacet, value: unknown): void;
3620
+ protected isChecked(facet: TableOptionsFacet, option: TableFacetOption): boolean;
3621
+ protected check(facet: TableOptionsFacet, option: TableFacetOption, checked: boolean): void;
3622
+ protected range(facet: TableDateRangeFacet): DateRange;
3623
+ protected dateMode(facet: TableDateRangeFacet): DateMode;
3624
+ protected pickDate(facet: TableDateRangeFacet, mode: DateMode): void;
3625
+ protected setRange(facet: TableDateRangeFacet, range: DateRange): void;
3626
+ protected clearAll(): void;
3627
+ private setCustom;
3628
+ private apply;
3629
+ private write;
3630
+ private currentFilters;
3631
+ private ownFilters;
3632
+ private withoutOwn;
3633
+ private hasAny;
3634
+ static ɵfac: i0.ɵɵFactoryDeclaration<UiTableFiltersComponent, never>;
3635
+ static ɵcmp: i0.ɵɵComponentDeclaration<UiTableFiltersComponent, "ui-table-filters", never, {
3636
+ "facets": {
3637
+ "alias": "facets";
3638
+ "required": true;
3639
+ "isSignal": true;
3640
+ };
3641
+ "table": {
3642
+ "alias": "table";
3643
+ "required": false;
3644
+ "isSignal": true;
3645
+ };
3646
+ "value": {
3647
+ "alias": "value";
3648
+ "required": false;
3649
+ "isSignal": true;
3650
+ };
3651
+ "collapseBelow": {
3652
+ "alias": "collapseBelow";
3653
+ "required": false;
3654
+ "isSignal": true;
3655
+ };
3656
+ }, {
3657
+ "value": "valueChange";
3658
+ }, never, never, true, never>;
3659
+ }
3159
3660
  export declare class UiTimeSelectComponent {
3160
3661
  /** 24 hour "HH:mm" string. */
3161
3662
  readonly value: import("@angular/core").ModelSignal<string>;
@@ -3188,4 +3689,93 @@ export declare class UiTimeSelectComponent {
3188
3689
  }, {
3189
3690
  "value": "valueChange";
3190
3691
  }, never, never, true, never>;
3692
+ }
3693
+ /** Give the dropdown it sits in `closeBehaviour="whenClickOutside"`. */
3694
+ export declare class UiUserMenuComponent {
3695
+ private readonly dropdown;
3696
+ readonly name: import("@angular/core").InputSignal<string>;
3697
+ /** A second line under the name, e.g. an email address. */
3698
+ readonly detail: import("@angular/core").InputSignal<string>;
3699
+ readonly src: import("@angular/core").InputSignal<string | null>;
3700
+ readonly items: import("@angular/core").InputSignal<DropdownMenuItem[]>;
3701
+ protected readonly menuItems: import("@angular/core").Signal<DropdownMenuItem[]>;
3702
+ protected isDivider(item: DropdownMenuItem): boolean;
3703
+ protected group(item: DropdownMenuItem): DropdownMenuCategory | null;
3704
+ protected button(item: DropdownMenuItem): DropdownMenuButton | null;
3705
+ private closing;
3706
+ static ɵfac: i0.ɵɵFactoryDeclaration<UiUserMenuComponent, never>;
3707
+ static ɵcmp: i0.ɵɵComponentDeclaration<UiUserMenuComponent, "ui-user-menu", never, {
3708
+ "name": {
3709
+ "alias": "name";
3710
+ "required": true;
3711
+ "isSignal": true;
3712
+ };
3713
+ "detail": {
3714
+ "alias": "detail";
3715
+ "required": false;
3716
+ "isSignal": true;
3717
+ };
3718
+ "src": {
3719
+ "alias": "src";
3720
+ "required": false;
3721
+ "isSignal": true;
3722
+ };
3723
+ "items": {
3724
+ "alias": "items";
3725
+ "required": false;
3726
+ "isSignal": true;
3727
+ };
3728
+ }, {}, never, ["*"], true, never>;
3729
+ }
3730
+ /** What the user picked, `system` follows the OS setting. */
3731
+ export type UiThemePreference = 'system' | 'light' | 'dark';
3732
+ export interface UiThemeConfig {
3733
+ storageKey: string;
3734
+ }
3735
+ export declare const UI_THEME_CONFIG: InjectionToken<UiThemeConfig>;
3736
+ /**
3737
+ * Add this to `index.html`'s `<head>` so the stored theme applies before boot:
3738
+ *
3739
+ * ```html
3740
+ * <script>
3741
+ * try {
3742
+ * const preference = localStorage.getItem('ui-theme') ?? 'system';
3743
+ * const dark = preference === 'dark' ||
3744
+ * (preference === 'system' && matchMedia('(prefers-color-scheme: dark)').matches);
3745
+ * document.documentElement.classList.toggle('dark', dark);
3746
+ * } catch {}
3747
+ * </script>
3748
+ * ```
3749
+ */
3750
+ export declare class UiThemeService {
3751
+ private readonly document;
3752
+ private readonly storageKey;
3753
+ private readonly media;
3754
+ readonly preference: import("@angular/core").WritableSignal<UiThemePreference>;
3755
+ private readonly systemDark;
3756
+ readonly isDark: import("@angular/core").Signal<boolean>;
3757
+ constructor();
3758
+ private stored;
3759
+ static ɵfac: i0.ɵɵFactoryDeclaration<UiThemeService, never>;
3760
+ static ɵprov: i0.ɵɵInjectableDeclaration<any>;
3761
+ }
3762
+ export declare function provideUiTheme(config?: Partial<UiThemeConfig>): EnvironmentProviders;
3763
+ export declare class UiThemeSwitchComponent {
3764
+ protected readonly theme: UiThemeService;
3765
+ readonly ariaLabel: import("@angular/core").InputSignal<string>;
3766
+ readonly fill: import("@angular/core").InputSignalWithTransform<boolean, unknown>;
3767
+ protected readonly options: SegmentedOption<UiThemePreference>[];
3768
+ static ɵfac: i0.ɵɵFactoryDeclaration<UiThemeSwitchComponent, never>;
3769
+ static ɵcmp: i0.ɵɵComponentDeclaration<UiThemeSwitchComponent, "ui-theme-switch", never, {
3770
+ "ariaLabel": {
3771
+ "alias": "ariaLabel";
3772
+ "required": false;
3773
+ "isSignal": true;
3774
+ };
3775
+ "fill": {
3776
+ "alias": "fill";
3777
+ "required": false;
3778
+ "isSignal": true;
3779
+ };
3780
+ }, {}, never, never, true, never>;
3191
3781
  }