@area8975/ui 0.1.1-dev.8 → 0.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -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,14 +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>;
2005
+ readonly iconPosition: import("@angular/core").InputSignal<"right" | "left">;
1767
2006
  static ɵfac: i0.ɵɵFactoryDeclaration<UiKpiComponent, never>;
1768
2007
  static ɵcmp: i0.ɵɵComponentDeclaration<UiKpiComponent, "ui-kpi", never, {
1769
- "title": {
1770
- "alias": "title";
2008
+ "label": {
2009
+ "alias": "label";
1771
2010
  "required": false;
1772
2011
  "isSignal": true;
1773
2012
  };
@@ -1786,6 +2025,11 @@ export declare class UiKpiComponent {
1786
2025
  "required": false;
1787
2026
  "isSignal": true;
1788
2027
  };
2028
+ "iconPosition": {
2029
+ "alias": "iconPosition";
2030
+ "required": false;
2031
+ "isSignal": true;
2032
+ };
1789
2033
  }, {}, never, ["[kpi-value]", "[kpi-badge]"], true, never>;
1790
2034
  }
1791
2035
  export declare class UiLoadingComponent {
@@ -1849,18 +2093,25 @@ export declare class UiModalComponent {
1849
2093
  * Formats a money value, e.g. -42.1 as "-£42.10".
1850
2094
  */
1851
2095
  export declare class UiMoneyComponent {
2096
+ private readonly defaults;
2097
+ private readonly privacy;
1852
2098
  readonly value: import("@angular/core").InputSignal<number | null>;
2099
+ /** Defaults to the currency from `provideUiFormat`. */
1853
2100
  readonly currency: import("@angular/core").InputSignal<string>;
2101
+ /** Defaults to the locale from `provideUiFormat`. */
1854
2102
  readonly locale: import("@angular/core").InputSignal<string>;
1855
2103
  readonly signDisplay: import("@angular/core").InputSignal<"auto" | "always" | "exceptZero" | "never">;
1856
2104
  /** Green for money in, red for money out. */
1857
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>;
1858
2108
  /** Short form like "£12K", the full amount goes in the title. */
1859
2109
  readonly compact: import("@angular/core").InputSignalWithTransform<boolean, unknown>;
1860
2110
  /** Shown when there's no value. */
1861
2111
  readonly placeholder: import("@angular/core").InputSignal<string>;
1862
- readonly classes: import("@angular/core").InputSignal<string>;
1863
2112
  private readonly amount;
2113
+ protected readonly masked: import("@angular/core").Signal<boolean>;
2114
+ protected readonly mask: import("@angular/core").Signal<string>;
1864
2115
  protected readonly formatted: import("@angular/core").Signal<string>;
1865
2116
  protected readonly title: import("@angular/core").Signal<string | null>;
1866
2117
  readonly generatedClasses: import("@angular/core").Signal<string>;
@@ -1893,6 +2144,11 @@ export declare class UiMoneyComponent {
1893
2144
  "required": false;
1894
2145
  "isSignal": true;
1895
2146
  };
2147
+ "wholeUnits": {
2148
+ "alias": "wholeUnits";
2149
+ "required": false;
2150
+ "isSignal": true;
2151
+ };
1896
2152
  "compact": {
1897
2153
  "alias": "compact";
1898
2154
  "required": false;
@@ -1903,11 +2159,6 @@ export declare class UiMoneyComponent {
1903
2159
  "required": false;
1904
2160
  "isSignal": true;
1905
2161
  };
1906
- "classes": {
1907
- "alias": "classes";
1908
- "required": false;
1909
- "isSignal": true;
1910
- };
1911
2162
  }, {}, never, never, true, never>;
1912
2163
  }
1913
2164
  /** Intl signDisplay values, controls when a + or - is shown. */
@@ -1919,8 +2170,6 @@ export type PaginationItem = number | 'ellipsis';
1919
2170
  export declare class UiPaginationComponent {
1920
2171
  readonly page: import("@angular/core").ModelSignal<number>;
1921
2172
  readonly totalPages: import("@angular/core").InputSignal<number>;
1922
- readonly classes: import("@angular/core").InputSignal<string>;
1923
- readonly generatedClasses: import("@angular/core").Signal<string>;
1924
2173
  readonly isFirstPage: import("@angular/core").Signal<boolean>;
1925
2174
  readonly isLastPage: import("@angular/core").Signal<boolean>;
1926
2175
  readonly items: import("@angular/core").Signal<PaginationItem[]>;
@@ -1938,15 +2187,29 @@ export declare class UiPaginationComponent {
1938
2187
  "required": true;
1939
2188
  "isSignal": true;
1940
2189
  };
1941
- "classes": {
1942
- "alias": "classes";
1943
- "required": false;
1944
- "isSignal": true;
1945
- };
1946
2190
  }, {
1947
2191
  "page": "pageChange";
1948
2192
  }, never, never, true, never>;
1949
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
+ }
1950
2213
  /** Same names as badges, so a status reads the same wherever it shows. */
1951
2214
  export declare const ProgressIntents: readonly ["primary", "secondary", "success", "warning", "danger"];
1952
2215
  /** @see {@link ProgressIntents} */
@@ -1989,7 +2252,7 @@ export declare class UiProgressComponent {
1989
2252
  readonly shape: import("@angular/core").InputSignal<"square" | "straight" | "rounded">;
1990
2253
  readonly orientation: import("@angular/core").InputSignal<"vertical" | "horizontal">;
1991
2254
  readonly title: import("@angular/core").InputSignal<string>;
1992
- readonly labelPosition: import("@angular/core").InputSignal<"top" | "none" | "end" | "floating" | "inside">;
2255
+ readonly labelPosition: import("@angular/core").InputSignal<"none" | "top" | "end" | "floating" | "inside">;
1993
2256
  readonly labelWith: import("@angular/core").InputSignal<(value: number, max: number) => string>;
1994
2257
  /** Splits the bar into this many blocks. */
1995
2258
  readonly steps: import("@angular/core").InputSignal<number | null>;
@@ -2073,6 +2336,46 @@ export declare class UiProgressComponent {
2073
2336
  };
2074
2337
  }, {}, never, never, true, never>;
2075
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
+ }
2076
2379
  /**
2077
2380
  * A placeholder shown while content loads. Size it with classes on the
2078
2381
  * element, e.g. `class="w-48"` for text or `class="size-12"` for a circle.
@@ -2082,7 +2385,6 @@ export declare class UiSkeletonComponent {
2082
2385
  readonly animated: import("@angular/core").InputSignalWithTransform<boolean, unknown>;
2083
2386
  /** Text only, stacks this many lines with a shorter last one. */
2084
2387
  readonly lines: import("@angular/core").InputSignalWithTransform<number, unknown>;
2085
- readonly classes: import("@angular/core").InputSignal<string>;
2086
2388
  protected readonly lineIndexes: import("@angular/core").Signal<number[]>;
2087
2389
  readonly generatedClasses: import("@angular/core").Signal<string>;
2088
2390
  static ɵfac: i0.ɵɵFactoryDeclaration<UiSkeletonComponent, never>;
@@ -2102,20 +2404,27 @@ export declare class UiSkeletonComponent {
2102
2404
  "required": false;
2103
2405
  "isSignal": true;
2104
2406
  };
2105
- "classes": {
2106
- "alias": "classes";
2107
- "required": false;
2108
- "isSignal": true;
2109
- };
2110
2407
  }, {}, never, never, true, never>;
2111
2408
  }
2112
2409
  /** What a skeleton stands in for, lines of text, an avatar or a block. */
2113
2410
  export declare const SkeletonShapes: readonly ["text", "circle", "rect"];
2114
2411
  /** @see {@link SkeletonShapes} */
2115
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
+ }
2116
2425
  export declare class UiTabDirective {
2117
2426
  label: import("@angular/core").InputSignal<string>;
2118
- disabled: import("@angular/core").InputSignal<boolean>;
2427
+ disabled: import("@angular/core").InputSignalWithTransform<boolean, unknown>;
2119
2428
  active: import("@angular/core").ModelSignal<boolean>;
2120
2429
  static ɵfac: i0.ɵɵFactoryDeclaration<UiTabDirective, never>;
2121
2430
  static ɵdir: i0.ɵɵDirectiveDeclaration<UiTabDirective, "[uiTab]", never, {
@@ -2174,8 +2483,10 @@ export interface TableColumn<Row> {
2174
2483
  accessor: (row: Row) => unknown;
2175
2484
  /** how the cell value is formatted for display, defaults to plain text */
2176
2485
  displayType?: TableColumnDisplayType;
2177
- /** ISO currency code, used when displayType is 'currency' */
2486
+ /** ISO currency code, used when displayType is 'currency'. Defaults to the currency from `provideUiFormat`. */
2178
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;
2179
2490
  sortable?: boolean;
2180
2491
  filterable?: boolean;
2181
2492
  /** when set, the filter renders as a select instead of a free-text contains filter */
@@ -2237,6 +2548,8 @@ interface ColumnDragPreview {
2237
2548
  }
2238
2549
  export declare class UiTableComponent<Row = unknown> implements OnInit, OnDestroy {
2239
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>;
2240
2553
  readonly columns: import("@angular/core").InputSignal<TableColumn<Row>[]>;
2241
2554
  readonly dataSource: import("@angular/core").InputSignal<TableDataSource<Row>>;
2242
2555
  readonly emptyMessage: import("@angular/core").InputSignal<string>;
@@ -2282,6 +2595,8 @@ export declare class UiTableComponent<Row = unknown> implements OnInit, OnDestro
2282
2595
  protected readonly hasFilterableColumns: import("@angular/core").Signal<boolean>;
2283
2596
  protected readonly activeFilterCount: import("@angular/core").Signal<number>;
2284
2597
  protected readonly hasActions: import("@angular/core").Signal<boolean>;
2598
+ private readonly hasSensitiveColumns;
2599
+ protected readonly fixedWidth: import("@angular/core").Signal<number | null>;
2285
2600
  protected readonly actionsColumnWidth: import("@angular/core").Signal<number>;
2286
2601
  protected readonly totalPages: import("@angular/core").Signal<number>;
2287
2602
  protected readonly resultsLabel: import("@angular/core").Signal<string>;
@@ -2292,6 +2607,11 @@ export declare class UiTableComponent<Row = unknown> implements OnInit, OnDestro
2292
2607
  private readonly load$;
2293
2608
  private readonly destroyRef;
2294
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;
2295
2615
  private resizeState;
2296
2616
  private columnDragState;
2297
2617
  private readonly filterDataSources;
@@ -2301,6 +2621,7 @@ export declare class UiTableComponent<Row = unknown> implements OnInit, OnDestro
2301
2621
  reload(): void;
2302
2622
  protected cellValue(column: TableColumn<Row>, row: Row): unknown;
2303
2623
  protected cellIconValue(column: TableColumn<Row>, row: Row): string;
2624
+ protected moneyCellValue(column: TableColumn<Row>, row: Row): number | null;
2304
2625
  protected formattedCellValue(column: TableColumn<Row>, row: Row): string;
2305
2626
  protected onQueryChange(value: string): void;
2306
2627
  protected filterValue(columnId: string): string;
@@ -2308,6 +2629,7 @@ export declare class UiTableComponent<Row = unknown> implements OnInit, OnDestro
2308
2629
  protected filterDataSource(column: TableColumn<Row>): SelectDataSource<TableColumnFilterOption>;
2309
2630
  protected selectedFilterOption(column: TableColumn<Row>): TableColumnFilterOption | null;
2310
2631
  protected filterOptionLabel(option: TableColumnFilterOption): string;
2632
+ protected readonly sensitiveFilterOptionLabel: (option: TableColumnFilterOption) => string;
2311
2633
  protected onFilterSelect(columnId: string, option: TableColumnFilterOption | null): void;
2312
2634
  protected clearFilters(): void;
2313
2635
  protected toggleSort(column: TableColumn<Row>): void;
@@ -2344,6 +2666,11 @@ export declare class UiTableComponent<Row = unknown> implements OnInit, OnDestro
2344
2666
  "required": false;
2345
2667
  "isSignal": true;
2346
2668
  };
2669
+ "tableId": {
2670
+ "alias": "tableId";
2671
+ "required": false;
2672
+ "isSignal": true;
2673
+ };
2347
2674
  "columns": {
2348
2675
  "alias": "columns";
2349
2676
  "required": true;
@@ -2436,6 +2763,18 @@ export declare class UiTableComponent<Row = unknown> implements OnInit, OnDestro
2436
2763
  "rowsReordered": "rowsReordered";
2437
2764
  }, never, never, true, never>;
2438
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
+ }
2439
2778
  export declare class UiToastComponent {
2440
2779
  readonly intent: import("@angular/core").InputSignal<"success" | "warning" | "danger" | "info">;
2441
2780
  readonly classes: import("@angular/core").InputSignal<string>;
@@ -2443,7 +2782,7 @@ export declare class UiToastComponent {
2443
2782
  /** ms before the toast dismisses itself, paused while hovered or focused. null never times out. */
2444
2783
  readonly timeoutMs: import("@angular/core").InputSignal<number | null>;
2445
2784
  readonly dismissed: import("@angular/core").OutputEmitterRef<void>;
2446
- protected readonly icon: import("@angular/core").Signal<string>;
2785
+ protected readonly icon: import("@angular/core").Signal<IconType>;
2447
2786
  protected readonly iconColour: import("@angular/core").Signal<string>;
2448
2787
  protected readonly role: import("@angular/core").Signal<"alert" | "status">;
2449
2788
  private hovered;
@@ -2642,6 +2981,7 @@ export declare class UiOverlayComponent implements UiOverlayStackEntry {
2642
2981
  }
2643
2982
  export declare class UiSidebarComponent {
2644
2983
  readonly isOpen: import("@angular/core").ModelSignal<boolean>;
2984
+ readonly isCollapsed: import("@angular/core").Signal<boolean>;
2645
2985
  readonly toggle: () => void;
2646
2986
  static ɵfac: i0.ɵɵFactoryDeclaration<UiSidebarComponent, never>;
2647
2987
  static ɵcmp: i0.ɵɵComponentDeclaration<UiSidebarComponent, "ui-sidebar", ["uiSidebar"], {
@@ -2652,7 +2992,21 @@ export declare class UiSidebarComponent {
2652
2992
  };
2653
2993
  }, {
2654
2994
  "isOpen": "isOpenChange";
2655
- }, 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>;
2656
3010
  }
2657
3011
  export declare class UiSidebarItemComponent {
2658
3012
  private readonly sidebar;
@@ -2996,7 +3350,7 @@ export declare class UiDatepickerComponent {
2996
3350
  }
2997
3351
  export declare class UiDropdownButtonComponent {
2998
3352
  readonly intent: import("@angular/core").InputSignal<"none" | "primary" | "secondary" | "success" | "warning" | "danger">;
2999
- 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">;
3000
3354
  readonly icon: import("@angular/core").InputSignal<string>;
3001
3355
  readonly isOpen: import("@angular/core").ModelSignal<boolean>;
3002
3356
  static ɵfac: i0.ɵɵFactoryDeclaration<UiDropdownButtonComponent, never>;
@@ -3119,6 +3473,61 @@ export declare class UiFileInputComponent {
3119
3473
  "rejected": "rejected";
3120
3474
  }, never, never, true, never>;
3121
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
+ }
3122
3531
  export declare class UiSwitchComponent {
3123
3532
  readonly value: import("@angular/core").ModelSignal<boolean>;
3124
3533
  readonly id: import("@angular/core").InputSignal<string>;
@@ -3150,6 +3559,104 @@ export declare class UiSwitchComponent {
3150
3559
  "value": "valueChange";
3151
3560
  }, never, ["*"], true, never>;
3152
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
+ }
3153
3660
  export declare class UiTimeSelectComponent {
3154
3661
  /** 24 hour "HH:mm" string. */
3155
3662
  readonly value: import("@angular/core").ModelSignal<string>;
@@ -3182,4 +3689,93 @@ export declare class UiTimeSelectComponent {
3182
3689
  }, {
3183
3690
  "value": "valueChange";
3184
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>;
3185
3781
  }