@joanroucoux/cairn-ui 0.5.1 → 0.6.1

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,6 +1,39 @@
1
1
  import * as _angular_core from '@angular/core';
2
2
  import { InjectionToken, Signal, ElementRef } from '@angular/core';
3
3
 
4
+ /**
5
+ * Bar of actions fixed above the tab bar on iPhone: the primary actions of a detail screen, within
6
+ * thumb reach. It sits 52px plus the safe area above the bottom edge, so it clears `ui-tab-bar`, and
7
+ * it is hidden from `64rem`, where the same actions live in the page itself. Its children share the
8
+ * width equally.
9
+ *
10
+ * @example
11
+ * <ui-action-bar>
12
+ * <button ui-button variant="outline" size="tall">Sell</button>
13
+ * <button ui-button size="tall">Buy</button>
14
+ * </ui-action-bar>
15
+ */
16
+ declare class UiActionBar {
17
+ static ɵfac: _angular_core.ɵɵFactoryDeclaration<UiActionBar, never>;
18
+ static ɵcmp: _angular_core.ɵɵComponentDeclaration<UiActionBar, "ui-action-bar", never, {}, {}, never, ["*"], true, never>;
19
+ }
20
+
21
+ declare const ALERT_VARIANTS: readonly ["error", "warning"];
22
+ type AlertVariant = (typeof ALERT_VARIANTS)[number];
23
+ /**
24
+ * Inline message explaining a failure or a consequence: an icon, an optional heading and a text.
25
+ *
26
+ * @example
27
+ * <ui-alert heading="Sign-in failed">Try again.</ui-alert>
28
+ */
29
+ declare class UiAlert {
30
+ readonly variant: _angular_core.InputSignal<"error" | "warning">;
31
+ readonly heading: _angular_core.InputSignal<string | undefined>;
32
+ protected readonly classes: _angular_core.Signal<string>;
33
+ static ɵfac: _angular_core.ɵɵFactoryDeclaration<UiAlert, never>;
34
+ static ɵcmp: _angular_core.ɵɵComponentDeclaration<UiAlert, "ui-alert", never, { "variant": { "alias": "variant"; "required": false; "isSignal": true; }; "heading": { "alias": "heading"; "required": false; "isSignal": true; }; }, {}, never, ["*"], true, never>;
35
+ }
36
+
4
37
  /** App-wide "amounts are hidden" state. Defaults to never masked; the app overrides it. */
5
38
  declare const UI_AMOUNT_MASKED: InjectionToken<Signal<boolean>>;
6
39
  /** Available figure styles. `AmountNumeric` is derived from this tuple. */
@@ -44,6 +77,12 @@ declare function formatAmount(value: number | null | undefined, options: AmountF
44
77
  /** Available async block states. `AsyncState` is derived from this tuple. */
45
78
  declare const ASYNC_STATES: readonly ["loading", "error", "empty", "ready"];
46
79
  type AsyncState = (typeof ASYNC_STATES)[number];
80
+ /** Looks of the error block. `AsyncVariant` is derived from this tuple. */
81
+ declare const ASYNC_VARIANTS: readonly ["elevated", "plain", "emphasis", "inline"];
82
+ type AsyncVariant = (typeof ASYNC_VARIANTS)[number];
83
+ /** Alignments of the error block; `auto` is centred from 64rem. `AsyncAlign` is derived from this tuple. */
84
+ declare const ASYNC_ALIGNS: readonly ["start", "center", "auto"];
85
+ type AsyncAlign = (typeof ASYNC_ALIGNS)[number];
47
86
  /**
48
87
  * The three states of a block that depends on a service call, next to the ready content.
49
88
  *
@@ -55,18 +94,28 @@ type AsyncState = (typeof ASYNC_STATES)[number];
55
94
  * </ui-async>
56
95
  */
57
96
  declare class UiAsync {
58
- readonly state: _angular_core.InputSignal<"loading" | "error" | "empty" | "ready">;
97
+ #private;
98
+ readonly state: _angular_core.InputSignal<"error" | "loading" | "empty" | "ready">;
59
99
  readonly errorTitle: _angular_core.InputSignal<string | undefined>;
60
100
  readonly errorMessage: _angular_core.InputSignal<string | undefined>;
61
101
  readonly retryLabel: _angular_core.InputSignal<string | undefined>;
102
+ readonly variant: _angular_core.InputSignal<"elevated" | "plain" | "emphasis" | "inline">;
103
+ readonly align: _angular_core.InputSignal<"start" | "center" | "auto">;
104
+ readonly card: _angular_core.InputSignalWithTransform<boolean, unknown>;
105
+ readonly fill: _angular_core.InputSignalWithTransform<boolean, unknown>;
62
106
  readonly retry: _angular_core.OutputEmitterRef<void>;
63
- protected readonly retryButtonClasses = "mt-2 relative inline-flex items-center justify-center gap-2 rounded-control font-medium whitespace-nowrap cursor-pointer select-none touch-manipulation transition-[transform,background-color,opacity] duration-(--duration-press) ease-out active:scale-(--press-scale) focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-(--ring) min-h-(--row-min) px-4 text-label bg-(--card) text-(--foreground) shadow-[inset_0_0_0_1px_var(--border)] hover:bg-(--glow)";
107
+ protected readonly filling: _angular_core.Signal<boolean>;
108
+ protected readonly iconSize: _angular_core.Signal<16 | 18>;
109
+ protected readonly boxClasses: _angular_core.Signal<string>;
110
+ protected readonly titleClasses: _angular_core.Signal<string>;
111
+ protected readonly messageClasses: _angular_core.Signal<string>;
112
+ protected readonly retryButtonClasses: _angular_core.Signal<string>;
64
113
  static ɵfac: _angular_core.ɵɵFactoryDeclaration<UiAsync, never>;
65
- static ɵcmp: _angular_core.ɵɵComponentDeclaration<UiAsync, "ui-async", never, { "state": { "alias": "state"; "required": true; "isSignal": true; }; "errorTitle": { "alias": "errorTitle"; "required": false; "isSignal": true; }; "errorMessage": { "alias": "errorMessage"; "required": false; "isSignal": true; }; "retryLabel": { "alias": "retryLabel"; "required": false; "isSignal": true; }; }, { "retry": "retry"; }, never, ["[asyncLoading]", "[asyncEmpty]", "*"], true, never>;
114
+ static ɵcmp: _angular_core.ɵɵComponentDeclaration<UiAsync, "ui-async", never, { "state": { "alias": "state"; "required": true; "isSignal": true; }; "errorTitle": { "alias": "errorTitle"; "required": false; "isSignal": true; }; "errorMessage": { "alias": "errorMessage"; "required": false; "isSignal": true; }; "retryLabel": { "alias": "retryLabel"; "required": false; "isSignal": true; }; "variant": { "alias": "variant"; "required": false; "isSignal": true; }; "align": { "alias": "align"; "required": false; "isSignal": true; }; "card": { "alias": "card"; "required": false; "isSignal": true; }; "fill": { "alias": "fill"; "required": false; "isSignal": true; }; }, { "retry": "retry"; }, never, ["[asyncLoading]", "[asyncEmpty]", "*"], true, never>;
66
115
  }
67
116
 
68
117
  /** Available avatar sizes. `AvatarSize` is derived from this tuple. */
69
- declare const AVATAR_SIZES: readonly ["sm", "md"];
118
+ declare const AVATAR_SIZES: readonly ["sm", "md", "lg", "auto"];
70
119
  type AvatarSize = (typeof AVATAR_SIZES)[number];
71
120
  /**
72
121
  * Initials in a disc, standing in for a person. Single-user application: there is exactly one.
@@ -77,15 +126,45 @@ type AvatarSize = (typeof AVATAR_SIZES)[number];
77
126
  declare class UiAvatar {
78
127
  readonly initials: _angular_core.InputSignal<string>;
79
128
  readonly label: _angular_core.InputSignal<string>;
80
- readonly size: _angular_core.InputSignal<"sm" | "md">;
129
+ readonly size: _angular_core.InputSignal<"auto" | "sm" | "md" | "lg">;
81
130
  protected readonly classes: _angular_core.Signal<string>;
82
131
  static ɵfac: _angular_core.ɵɵFactoryDeclaration<UiAvatar, never>;
83
132
  static ɵcmp: _angular_core.ɵɵComponentDeclaration<UiAvatar, "ui-avatar", never, { "initials": { "alias": "initials"; "required": true; "isSignal": true; }; "label": { "alias": "label"; "required": true; "isSignal": true; }; "size": { "alias": "size"; "required": false; "isSignal": true; }; }, {}, never, never, true, never>;
84
133
  }
134
+ /**
135
+ * Round hit area around a `ui-avatar` that links somewhere: 44px on touch, 40px from 64rem, with a
136
+ * glow on hover and the press scale. The avatar itself keeps its own size.
137
+ *
138
+ * @example
139
+ * <a uiAvatarLink routerLink="/profile"><ui-avatar initials="JR" label="Profile" size="auto" /></a>
140
+ */
141
+ declare class UiAvatarLink {
142
+ static ɵfac: _angular_core.ɵɵFactoryDeclaration<UiAvatarLink, never>;
143
+ static ɵdir: _angular_core.ɵɵDirectiveDeclaration<UiAvatarLink, "a[uiAvatarLink], button[uiAvatarLink]", never, {}, {}, never, never, true, never>;
144
+ }
145
+
146
+ /** Available back link sizes. `BackLinkSize` is derived from this tuple. */
147
+ declare const BACK_LINK_SIZES: readonly ["md", "sm", "header"];
148
+ type BackLinkSize = (typeof BACK_LINK_SIZES)[number];
149
+ /**
150
+ * Link back to the parent screen: a chevron and the name of the destination.
151
+ *
152
+ * @example
153
+ * <a ui-back-link routerLink="/accounts">Accounts</a>
154
+ */
155
+ declare class UiBackLink {
156
+ readonly size: _angular_core.InputSignal<"sm" | "md" | "header">;
157
+ protected readonly chevron: _angular_core.Signal<number>;
158
+ protected readonly classes: _angular_core.Signal<string>;
159
+ static ɵfac: _angular_core.ɵɵFactoryDeclaration<UiBackLink, never>;
160
+ static ɵcmp: _angular_core.ɵɵComponentDeclaration<UiBackLink, "a[ui-back-link]", never, { "size": { "alias": "size"; "required": false; "isSignal": true; }; }, {}, never, ["*"], true, never>;
161
+ }
85
162
 
86
163
  /** Available badge variants. `BadgeVariant` is derived from this tuple. */
87
164
  declare const BADGE_VARIANTS: readonly ["neutral", "outline"];
88
165
  type BadgeVariant = (typeof BADGE_VARIANTS)[number];
166
+ declare const BADGE_SIZES: readonly ["md", "sm"];
167
+ type BadgeSize = (typeof BADGE_SIZES)[number];
89
168
  /**
90
169
  * Small status descriptor for counts, states or labels, such as an instrument's asset class.
91
170
  *
@@ -94,16 +173,17 @@ type BadgeVariant = (typeof BADGE_VARIANTS)[number];
94
173
  */
95
174
  declare class UiBadge {
96
175
  readonly variant: _angular_core.InputSignal<"neutral" | "outline">;
176
+ readonly size: _angular_core.InputSignal<"sm" | "md">;
97
177
  protected readonly classes: _angular_core.Signal<string>;
98
178
  static ɵfac: _angular_core.ɵɵFactoryDeclaration<UiBadge, never>;
99
- static ɵcmp: _angular_core.ɵɵComponentDeclaration<UiBadge, "ui-badge", never, { "variant": { "alias": "variant"; "required": false; "isSignal": true; }; }, {}, never, ["*"], true, never>;
179
+ static ɵcmp: _angular_core.ɵɵComponentDeclaration<UiBadge, "ui-badge", never, { "variant": { "alias": "variant"; "required": false; "isSignal": true; }; "size": { "alias": "size"; "required": false; "isSignal": true; }; }, {}, never, ["*"], true, never>;
100
180
  }
101
181
 
102
182
  /** Available button variants. `ButtonVariant` is derived from this tuple. */
103
- declare const BUTTON_VARIANTS: readonly ["primary", "outline", "ghost", "destructive"];
183
+ declare const BUTTON_VARIANTS: readonly ["primary", "outline", "ghost", "destructive", "quiet", "quiet-destructive", "outline-destructive", "quiet-glow", "tonal"];
104
184
  type ButtonVariant = (typeof BUTTON_VARIANTS)[number];
105
- /** Available button sizes. `md` is the touch target Cairn asks for everywhere. */
106
- declare const BUTTON_SIZES: readonly ["md", "lg", "xl", "icon"];
185
+ /** Available button sizes. */
186
+ declare const BUTTON_SIZES: readonly ["compact", "slim", "xs", "sm", "md", "lg", "xl", "xxl", "tall", "block", "icon", "icon-sm"];
107
187
  type ButtonSize = (typeof BUTTON_SIZES)[number];
108
188
  /**
109
189
  * Styled native button or anchor, applied as an attribute so the host keeps every native behavior.
@@ -113,33 +193,42 @@ type ButtonSize = (typeof BUTTON_SIZES)[number];
113
193
  * <button ui-button size="icon" variant="ghost" aria-label="More actions">...</button>
114
194
  */
115
195
  declare class UiButton {
116
- readonly variant: _angular_core.InputSignal<"outline" | "primary" | "ghost" | "destructive">;
117
- readonly size: _angular_core.InputSignal<"md" | "lg" | "xl" | "icon">;
196
+ readonly variant: _angular_core.InputSignal<"outline" | "primary" | "ghost" | "destructive" | "quiet" | "quiet-destructive" | "outline-destructive" | "quiet-glow" | "tonal">;
197
+ readonly size: _angular_core.InputSignal<"compact" | "sm" | "md" | "lg" | "slim" | "xs" | "xl" | "xxl" | "tall" | "block" | "icon" | "icon-sm">;
118
198
  readonly loading: _angular_core.InputSignalWithTransform<boolean, unknown>;
199
+ readonly busy: _angular_core.InputSignalWithTransform<boolean, unknown>;
200
+ protected readonly inactive: _angular_core.Signal<boolean>;
119
201
  protected readonly classes: _angular_core.Signal<string>;
120
202
  constructor();
121
203
  static ɵfac: _angular_core.ɵɵFactoryDeclaration<UiButton, never>;
122
- static ɵcmp: _angular_core.ɵɵComponentDeclaration<UiButton, "button[ui-button], a[ui-button]", never, { "variant": { "alias": "variant"; "required": false; "isSignal": true; }; "size": { "alias": "size"; "required": false; "isSignal": true; }; "loading": { "alias": "loading"; "required": false; "isSignal": true; }; }, {}, never, ["*"], true, never>;
204
+ static ɵcmp: _angular_core.ɵɵComponentDeclaration<UiButton, "button[ui-button], a[ui-button]", never, { "variant": { "alias": "variant"; "required": false; "isSignal": true; }; "size": { "alias": "size"; "required": false; "isSignal": true; }; "loading": { "alias": "loading"; "required": false; "isSignal": true; }; "busy": { "alias": "busy"; "required": false; "isSignal": true; }; }, {}, never, ["*"], true, never>;
123
205
  }
124
206
 
125
207
  /** Available card variants. `CardVariant` is derived from this tuple. */
126
208
  declare const CARD_VARIANTS: readonly ["default", "elevated"];
127
209
  type CardVariant = (typeof CARD_VARIANTS)[number];
128
210
  /** Available card paddings. `CardPadding` is derived from this tuple. */
129
- declare const CARD_PADDINGS: readonly ["none", "sm", "md"];
211
+ declare const CARD_PADDINGS: readonly ["none", "sm", "md", "list", "rows"];
130
212
  type CardPadding = (typeof CARD_PADDINGS)[number];
213
+ /** Where the card surface (fill, border, radius) and its padding apply. `CardSurface` is derived from this tuple. */
214
+ declare const CARD_SURFACES: readonly ["always", "lg", "max-lg"];
215
+ type CardSurface = (typeof CARD_SURFACES)[number];
131
216
  /**
132
- * Surface that groups related content: a summary block, a table, a side panel.
217
+ * Surface that groups related content: a summary block, a table, a side panel. `surface` limits the
218
+ * fill, border, radius and padding to one side of `64rem`, for a block that is a card on a desktop and
219
+ * plain on an iPhone, or the reverse.
133
220
  *
134
221
  * @example
135
222
  * <ui-card variant="elevated" padding="sm">Total</ui-card>
223
+ * <ui-card surface="max-lg">Card on an iPhone, plain on a desktop</ui-card>
136
224
  */
137
225
  declare class UiCard {
138
- readonly variant: _angular_core.InputSignal<"default" | "elevated">;
139
- readonly padding: _angular_core.InputSignal<"sm" | "md" | "none">;
226
+ readonly variant: _angular_core.InputSignal<"elevated" | "default">;
227
+ readonly padding: _angular_core.InputSignal<"sm" | "md" | "none" | "list" | "rows">;
228
+ readonly surface: _angular_core.InputSignal<"lg" | "always" | "max-lg">;
140
229
  protected readonly classes: _angular_core.Signal<string>;
141
230
  static ɵfac: _angular_core.ɵɵFactoryDeclaration<UiCard, never>;
142
- static ɵcmp: _angular_core.ɵɵComponentDeclaration<UiCard, "ui-card", never, { "variant": { "alias": "variant"; "required": false; "isSignal": true; }; "padding": { "alias": "padding"; "required": false; "isSignal": true; }; }, {}, never, ["*"], true, never>;
231
+ static ɵcmp: _angular_core.ɵɵComponentDeclaration<UiCard, "ui-card", never, { "variant": { "alias": "variant"; "required": false; "isSignal": true; }; "padding": { "alias": "padding"; "required": false; "isSignal": true; }; "surface": { "alias": "surface"; "required": false; "isSignal": true; }; }, {}, never, ["*"], true, never>;
143
232
  }
144
233
 
145
234
  /**
@@ -156,9 +245,55 @@ type UiControl = {
156
245
  readonly touched: Signal<boolean>;
157
246
  };
158
247
 
248
+ type ChoiceChipOption = {
249
+ value: string;
250
+ label: string;
251
+ };
252
+ /**
253
+ * Exclusive choice among a handful of named options, shown as wrapping pills: an account envelope,
254
+ * a category, a frequency. Binds to Signal Forms with `[formField]`.
255
+ *
256
+ * @example
257
+ * <ui-choice-chips label="Envelope" [options]="envelopes" [(value)]="envelope" />
258
+ *
259
+ * @example
260
+ * <ui-choice-chips label="Envelope" [options]="envelopes" [formField]="form.envelope" />
261
+ */
262
+ declare class UiChoiceChips implements UiControl {
263
+ #private;
264
+ readonly options: _angular_core.InputSignal<ChoiceChipOption[]>;
265
+ readonly value: _angular_core.ModelSignal<string>;
266
+ readonly label: _angular_core.InputSignal<string | undefined>;
267
+ readonly ariaLabel: _angular_core.InputSignal<string | undefined>;
268
+ readonly ariaLabelledby: _angular_core.InputSignal<string | undefined>;
269
+ readonly surface: _angular_core.InputSignal<"background" | "card">;
270
+ readonly disabled: _angular_core.InputSignalWithTransform<boolean, unknown>;
271
+ readonly errors: _angular_core.InputSignal<readonly UiControlError[]>;
272
+ readonly invalid: _angular_core.InputSignalWithTransform<boolean, unknown>;
273
+ readonly required: _angular_core.InputSignalWithTransform<boolean, unknown>;
274
+ readonly touched: _angular_core.InputSignal<boolean>;
275
+ readonly touch: _angular_core.OutputEmitterRef<void>;
276
+ protected readonly labelId: string;
277
+ protected readonly radios: _angular_core.Signal<readonly ElementRef<HTMLButtonElement>[]>;
278
+ protected readonly labelledBy: _angular_core.Signal<string | null>;
279
+ protected chipClasses(optionValue: string): string;
280
+ protected tabIndexFor(optionValue: string): number;
281
+ protected select(optionValue: string): void;
282
+ protected onFocusOut(event: FocusEvent): void;
283
+ protected onKeydown(event: KeyboardEvent, index: number): void;
284
+ static ɵfac: _angular_core.ɵɵFactoryDeclaration<UiChoiceChips, never>;
285
+ static ɵcmp: _angular_core.ɵɵComponentDeclaration<UiChoiceChips, "ui-choice-chips", never, { "options": { "alias": "options"; "required": true; "isSignal": true; }; "value": { "alias": "value"; "required": true; "isSignal": true; }; "label": { "alias": "label"; "required": false; "isSignal": true; }; "ariaLabel": { "alias": "ariaLabel"; "required": false; "isSignal": true; }; "ariaLabelledby": { "alias": "ariaLabelledby"; "required": false; "isSignal": true; }; "surface": { "alias": "surface"; "required": false; "isSignal": true; }; "disabled": { "alias": "disabled"; "required": false; "isSignal": true; }; "errors": { "alias": "errors"; "required": false; "isSignal": true; }; "invalid": { "alias": "invalid"; "required": false; "isSignal": true; }; "required": { "alias": "required"; "required": false; "isSignal": true; }; "touched": { "alias": "touched"; "required": false; "isSignal": true; }; }, { "value": "valueChange"; "touch": "touch"; }, never, never, true, never>;
286
+ }
287
+
159
288
  /** Available delta emphases. `DeltaEmphasis` is derived from this tuple. */
160
289
  declare const DELTA_EMPHASES: readonly ["text", "pill"];
161
290
  type DeltaEmphasis = (typeof DELTA_EMPHASES)[number];
291
+ /** Type sizes. `DeltaSize` is derived from this tuple. */
292
+ declare const DELTA_SIZES: readonly ["label", "inherit"];
293
+ type DeltaSize = (typeof DELTA_SIZES)[number];
294
+ /** Font weights. `DeltaWeight` is derived from this tuple. */
295
+ declare const DELTA_WEIGHTS: readonly ["medium", "regular"];
296
+ type DeltaWeight = (typeof DELTA_WEIGHTS)[number];
162
297
  type Sign = 'positive' | 'negative' | 'neutral' | 'unknown';
163
298
  /**
164
299
  * Signed amount whose sign carries meaning: a gain, a loss, or an unknown.
@@ -176,39 +311,69 @@ declare class UiDelta {
176
311
  readonly value: _angular_core.InputSignal<number | null | undefined>;
177
312
  readonly unknownLabel: _angular_core.InputSignal<string>;
178
313
  readonly emphasis: _angular_core.InputSignal<"text" | "pill">;
314
+ readonly size: _angular_core.InputSignal<"label" | "inherit">;
315
+ readonly weight: _angular_core.InputSignal<"medium" | "regular">;
179
316
  protected readonly sign: _angular_core.Signal<Sign>;
180
317
  protected readonly classes: _angular_core.Signal<string>;
181
318
  static ɵfac: _angular_core.ɵɵFactoryDeclaration<UiDelta, never>;
182
- static ɵcmp: _angular_core.ɵɵComponentDeclaration<UiDelta, "ui-delta", never, { "value": { "alias": "value"; "required": true; "isSignal": true; }; "unknownLabel": { "alias": "unknownLabel"; "required": true; "isSignal": true; }; "emphasis": { "alias": "emphasis"; "required": false; "isSignal": true; }; }, {}, never, ["*"], true, never>;
319
+ static ɵcmp: _angular_core.ɵɵComponentDeclaration<UiDelta, "ui-delta", never, { "value": { "alias": "value"; "required": true; "isSignal": true; }; "unknownLabel": { "alias": "unknownLabel"; "required": true; "isSignal": true; }; "emphasis": { "alias": "emphasis"; "required": false; "isSignal": true; }; "size": { "alias": "size"; "required": false; "isSignal": true; }; "weight": { "alias": "weight"; "required": false; "isSignal": true; }; }, {}, never, ["*"], true, never>;
183
320
  }
184
321
 
185
- /** Available dialog widths. `DialogWidth` is derived from this tuple. */
322
+ /** Named dialog widths; any other CSS length is accepted as is. `DialogWidth` is derived from this tuple. */
186
323
  declare const DIALOG_WIDTHS: readonly ["md", "lg"];
187
324
  type DialogWidth = (typeof DIALOG_WIDTHS)[number];
325
+ /** Spacing presets. `DialogLayout` is derived from this tuple. */
326
+ declare const DIALOG_LAYOUTS: readonly ["trade", "form", "list", "confirm"];
327
+ type DialogLayout = (typeof DIALOG_LAYOUTS)[number];
328
+ type LayoutClasses = {
329
+ dialog: string;
330
+ header: string;
331
+ title: string;
332
+ cross: string;
333
+ icon: string;
334
+ handle: string;
335
+ body: string;
336
+ footer: string;
337
+ };
188
338
  /**
189
- * Modal dialog on the native <dialog>: a sheet rising from the bottom under `64rem`, centered
190
- * above it. Two projection slots - the body, and [dialogActions] for the footer.
339
+ * Modal dialog on the native <dialog>: a bottom sheet under `64rem`, centered above it.
191
340
  *
192
341
  * @example
193
- * <ui-dialog heading="Delete this holding?" [open]="confirming()" (dismissed)="confirming.set(false)">
194
- * <p>This cannot be undone.</p>
195
- * <button dialogActions ui-button variant="outline" (click)="confirming.set(false)">Cancel</button>
342
+ * <ui-dialog heading="Buy" description="Ferrari" closeLabel="Close" width="528px" [open]="buying()" (dismissed)="buying.set(false)">
343
+ * <p>Body</p>
344
+ * <button dialogActions ui-button variant="outline" class="max-lg:hidden" (click)="buying.set(false)">Cancel</button>
345
+ * <button dialogActions ui-button>Buy 40 shares</button>
196
346
  * </ui-dialog>
197
347
  */
198
348
  declare class UiDialog {
199
349
  #private;
200
350
  readonly heading: _angular_core.InputSignal<string>;
201
351
  readonly description: _angular_core.InputSignal<string | undefined>;
202
- readonly width: _angular_core.InputSignal<"md" | "lg">;
352
+ readonly closeLabel: _angular_core.InputSignal<string | undefined>;
353
+ readonly layout: _angular_core.InputSignal<"list" | "trade" | "form" | "confirm">;
354
+ readonly truncateDescription: _angular_core.InputSignalWithTransform<boolean, unknown>;
355
+ readonly width: _angular_core.InputSignal<"md" | "lg" | (string & {})>;
203
356
  readonly open: _angular_core.InputSignalWithTransform<boolean, unknown>;
204
357
  readonly dismissed: _angular_core.OutputEmitterRef<void>;
205
358
  protected readonly headingId: string;
206
359
  protected readonly descriptionId: string;
360
+ protected readonly bodyId: string;
361
+ protected readonly scrollable: _angular_core.WritableSignal<boolean>;
362
+ protected readonly describedBy: _angular_core.Signal<string | null>;
363
+ protected readonly widthValue: _angular_core.Signal<string>;
364
+ protected readonly spec: _angular_core.Signal<LayoutClasses>;
365
+ protected readonly headerClasses: _angular_core.Signal<string>;
366
+ protected readonly titleClasses: _angular_core.Signal<string>;
367
+ protected readonly crossClasses: _angular_core.Signal<string>;
368
+ protected readonly iconClasses: _angular_core.Signal<string>;
369
+ protected readonly footerClasses: _angular_core.Signal<string>;
207
370
  protected readonly classes: _angular_core.Signal<string>;
208
371
  constructor();
372
+ protected onPointerDown(event: MouseEvent): void;
373
+ protected onClick(event: MouseEvent): void;
209
374
  protected onNativeClose(): void;
210
375
  static ɵfac: _angular_core.ɵɵFactoryDeclaration<UiDialog, never>;
211
- static ɵcmp: _angular_core.ɵɵComponentDeclaration<UiDialog, "ui-dialog", never, { "heading": { "alias": "heading"; "required": true; "isSignal": true; }; "description": { "alias": "description"; "required": false; "isSignal": true; }; "width": { "alias": "width"; "required": false; "isSignal": true; }; "open": { "alias": "open"; "required": false; "isSignal": true; }; }, { "dismissed": "dismissed"; }, never, ["*", "[dialogActions]"], true, never>;
376
+ static ɵcmp: _angular_core.ɵɵComponentDeclaration<UiDialog, "ui-dialog", never, { "heading": { "alias": "heading"; "required": true; "isSignal": true; }; "description": { "alias": "description"; "required": false; "isSignal": true; }; "closeLabel": { "alias": "closeLabel"; "required": false; "isSignal": true; }; "layout": { "alias": "layout"; "required": false; "isSignal": true; }; "truncateDescription": { "alias": "truncateDescription"; "required": false; "isSignal": true; }; "width": { "alias": "width"; "required": false; "isSignal": true; }; "open": { "alias": "open"; "required": false; "isSignal": true; }; }, { "dismissed": "dismissed"; }, never, ["*", "[dialogActions]"], true, never>;
212
377
  }
213
378
 
214
379
  type DonutSlice = {
@@ -225,7 +390,8 @@ type RankedSlice = DonutSlice & {
225
390
  };
226
391
 
227
392
  type PositionedSlice = RankedSlice & {
228
- path: string;
393
+ dash: string;
394
+ offset: string;
229
395
  };
230
396
 
231
397
  /**
@@ -241,25 +407,114 @@ declare class UiDonut {
241
407
  readonly othersLabel: _angular_core.InputSignal<string>;
242
408
  readonly valueFormat: _angular_core.InputSignal<(value: number) => string>;
243
409
  readonly shareFormat: _angular_core.InputSignal<(share: number) => string>;
410
+ readonly legendHref: _angular_core.InputSignal<((id: string) => string | null) | undefined>;
244
411
  readonly sliceSelect: _angular_core.OutputEmitterRef<string>;
245
412
  protected readonly activeId: _angular_core.WritableSignal<string | null>;
246
413
  protected readonly ranked: _angular_core.Signal<RankedSlice[]>;
247
414
  protected readonly positioned: _angular_core.Signal<PositionedSlice[]>;
248
415
  protected readonly active: _angular_core.Signal<RankedSlice | null>;
249
416
  protected readonly ariaLabel: _angular_core.Signal<string>;
250
- protected pathClasses(slice: RankedSlice): string;
417
+ protected readonly radius = 78;
418
+ protected readonly ringWidth = 30;
419
+ protected strokeColor(slice: RankedSlice): string;
420
+ protected strokeWidth(slice: RankedSlice): number;
251
421
  protected dotClasses(slice: RankedSlice): string;
252
422
  protected rowClasses(slice: RankedSlice): string;
253
423
  protected subLabel(slice: RankedSlice): string;
254
- protected arcTransform(slice: RankedSlice): string;
255
424
  protected isActive(slice: RankedSlice): boolean;
256
425
  protected highlight(id: string): void;
257
426
  protected clearHighlight(id: string): void;
427
+ protected hrefFor(id: string): string | null;
428
+ protected follow(event: MouseEvent, slice: RankedSlice): void;
258
429
  protected select(slice: RankedSlice): void;
259
430
  static ɵfac: _angular_core.ɵɵFactoryDeclaration<UiDonut, never>;
260
- static ɵcmp: _angular_core.ɵɵComponentDeclaration<UiDonut, "ui-donut", never, { "slices": { "alias": "slices"; "required": true; "isSignal": true; }; "label": { "alias": "label"; "required": true; "isSignal": true; }; "othersLabel": { "alias": "othersLabel"; "required": true; "isSignal": true; }; "valueFormat": { "alias": "valueFormat"; "required": false; "isSignal": true; }; "shareFormat": { "alias": "shareFormat"; "required": false; "isSignal": true; }; }, { "sliceSelect": "sliceSelect"; }, never, never, true, never>;
431
+ static ɵcmp: _angular_core.ɵɵComponentDeclaration<UiDonut, "ui-donut", never, { "slices": { "alias": "slices"; "required": true; "isSignal": true; }; "label": { "alias": "label"; "required": true; "isSignal": true; }; "othersLabel": { "alias": "othersLabel"; "required": true; "isSignal": true; }; "valueFormat": { "alias": "valueFormat"; "required": false; "isSignal": true; }; "shareFormat": { "alias": "shareFormat"; "required": false; "isSignal": true; }; "legendHref": { "alias": "legendHref"; "required": false; "isSignal": true; }; }, { "sliceSelect": "sliceSelect"; }, never, never, true, never>;
432
+ }
433
+
434
+ /**
435
+ * Link to another site: the label followed by an external-link icon. A 44px target on touch,
436
+ * an underline on hover with a mouse.
437
+ *
438
+ * @example
439
+ * <a ui-external-link href="https://example.com" target="_blank" rel="noopener">Page on example.com</a>
440
+ */
441
+ declare class UiExternalLink {
442
+ static ɵfac: _angular_core.ɵɵFactoryDeclaration<UiExternalLink, never>;
443
+ static ɵcmp: _angular_core.ɵɵComponentDeclaration<UiExternalLink, "a[ui-external-link]", never, {}, {}, never, ["*"], true, never>;
444
+ }
445
+
446
+ /** Available fact row sizes. `FactSize` is derived from this tuple. */
447
+ declare const FACT_SIZES: readonly ["md", "sm", "auto"];
448
+ type FactSize = (typeof FACT_SIZES)[number];
449
+ /** Colour of the line under a fact value. `stale` flags an out-of-date figure. */
450
+ declare const FACT_SUB_TONES: readonly ["subtle", "stale"];
451
+ type FactSubTone = (typeof FACT_SUB_TONES)[number];
452
+ /**
453
+ * The list that holds `div[ui-fact]` rows, as a native description list.
454
+ *
455
+ * @example
456
+ * <dl uiFacts>
457
+ * <div ui-fact label="Quantity">500</div>
458
+ * <div ui-fact label="Price" sub="24/09 · Yahoo">28,64 €</div>
459
+ * </dl>
460
+ */
461
+ declare class UiFacts {
462
+ readonly ruled: _angular_core.InputSignalWithTransform<boolean, unknown>;
463
+ protected readonly classes: _angular_core.Signal<string>;
464
+ static ɵfac: _angular_core.ɵɵFactoryDeclaration<UiFacts, never>;
465
+ static ɵdir: _angular_core.ɵɵDirectiveDeclaration<UiFacts, "dl[uiFacts]", never, { "ruled": { "alias": "ruled"; "required": false; "isSignal": true; }; }, {}, never, never, true, never>;
466
+ }
467
+ /**
468
+ * One fact of a `dl[uiFacts]`: a label on the left, its value on the right, an optional sub-line
469
+ * under the value, and a hairline above every row but the first at the `md` size (the `sm` desktop list is separated by space only). The projected content is the value.
470
+ *
471
+ * @example
472
+ * <div ui-fact label="Price" sub="24/09 · Yahoo" subTone="stale">28,64 €</div>
473
+ */
474
+ declare class UiFact {
475
+ readonly label: _angular_core.InputSignal<string>;
476
+ readonly sub: _angular_core.InputSignal<string | undefined>;
477
+ readonly subTone: _angular_core.InputSignal<"subtle" | "stale">;
478
+ readonly size: _angular_core.InputSignal<"auto" | "sm" | "md">;
479
+ protected readonly classes: _angular_core.Signal<string>;
480
+ protected readonly valueClasses: _angular_core.Signal<string>;
481
+ protected readonly subClasses: _angular_core.Signal<string>;
482
+ static ɵfac: _angular_core.ɵɵFactoryDeclaration<UiFact, never>;
483
+ static ɵcmp: _angular_core.ɵɵComponentDeclaration<UiFact, "div[ui-fact]", never, { "label": { "alias": "label"; "required": true; "isSignal": true; }; "sub": { "alias": "sub"; "required": false; "isSignal": true; }; "subTone": { "alias": "subTone"; "required": false; "isSignal": true; }; "size": { "alias": "size"; "required": false; "isSignal": true; }; }, {}, never, ["*"], true, never>;
261
484
  }
262
485
 
486
+ /**
487
+ * Marks an element, typically an 18px svg icon, as the leading content of a `ui-field`: it sits
488
+ * inside the control's left edge and the control's text is inset to clear it. Decorative, so hidden
489
+ * from assistive technologies.
490
+ *
491
+ * @example
492
+ * <ui-field label="Search" labelHidden>
493
+ * <svg uiFieldLeading width="18" height="18" viewBox="0 0 24 24">...</svg>
494
+ * <input uiInput type="search" />
495
+ * </ui-field>
496
+ */
497
+ declare class UiFieldLeading {
498
+ static ɵfac: _angular_core.ɵɵFactoryDeclaration<UiFieldLeading, never>;
499
+ static ɵdir: _angular_core.ɵɵDirectiveDeclaration<UiFieldLeading, "[uiFieldLeading]", never, {}, {}, never, never, true, never>;
500
+ }
501
+ /**
502
+ * Marks an element, typically an icon button, as the trailing action of a `ui-field`: it sits on the
503
+ * control's right edge, square to the control's height, and the control's text is padded to clear it.
504
+ *
505
+ * @example
506
+ * <ui-field label="Password">
507
+ * <input uiInput type="password" size="xl" />
508
+ * <button uiFieldTrailing type="button" aria-label="Show the password" [attr.aria-pressed]="shown()">...</button>
509
+ * </ui-field>
510
+ *
511
+ * A toggle such as this one should carry `aria-pressed`. The slot shares the right edge with `unit`:
512
+ * set one or the other, not both.
513
+ */
514
+ declare class UiFieldTrailing {
515
+ static ɵfac: _angular_core.ɵɵFactoryDeclaration<UiFieldTrailing, never>;
516
+ static ɵdir: _angular_core.ɵɵDirectiveDeclaration<UiFieldTrailing, "[uiFieldTrailing]", never, {}, {}, never, never, true, never>;
517
+ }
263
518
  /**
264
519
  * Label, control, hint and error as one unit. The control stays a plain native element:
265
520
  * the field finds it in its own projected content and wires the ARIA attributes onto it.
@@ -289,10 +544,15 @@ declare class UiField {
289
544
  readonly hint: _angular_core.InputSignal<string | undefined>;
290
545
  readonly error: _angular_core.InputSignal<string | undefined>;
291
546
  readonly unit: _angular_core.InputSignal<string | undefined>;
547
+ readonly optional: _angular_core.InputSignal<string | undefined>;
548
+ readonly invalid: _angular_core.InputSignalWithTransform<boolean, unknown>;
292
549
  protected readonly hintId: string;
293
550
  protected readonly errorId: string;
294
551
  protected readonly control: _angular_core.Signal<UiControl | undefined>;
295
- protected readonly labelClasses: _angular_core.Signal<"sr-only" | "text-label font-medium text-(--muted-foreground)">;
552
+ protected readonly leading: _angular_core.Signal<UiFieldLeading | undefined>;
553
+ protected readonly trailing: _angular_core.Signal<UiFieldTrailing | undefined>;
554
+ protected readonly rowClasses: _angular_core.Signal<string>;
555
+ protected readonly labelClasses: _angular_core.Signal<"sr-only" | "text-label leading-[17px] font-medium text-(--muted-foreground)">;
296
556
  /**
297
557
  * The caller's own `error` wins: it is the only way to report something the control does not
298
558
  * know about, such as a search box refusing an empty query.
@@ -300,12 +560,38 @@ declare class UiField {
300
560
  protected readonly message: _angular_core.Signal<string | undefined>;
301
561
  constructor();
302
562
  static ɵfac: _angular_core.ɵɵFactoryDeclaration<UiField, never>;
303
- static ɵcmp: _angular_core.ɵɵComponentDeclaration<UiField, "ui-field", never, { "label": { "alias": "label"; "required": true; "isSignal": true; }; "labelHidden": { "alias": "labelHidden"; "required": false; "isSignal": true; }; "hint": { "alias": "hint"; "required": false; "isSignal": true; }; "error": { "alias": "error"; "required": false; "isSignal": true; }; "unit": { "alias": "unit"; "required": false; "isSignal": true; }; }, {}, ["control"], ["*"], true, never>;
563
+ static ɵcmp: _angular_core.ɵɵComponentDeclaration<UiField, "ui-field", never, { "label": { "alias": "label"; "required": true; "isSignal": true; }; "labelHidden": { "alias": "labelHidden"; "required": false; "isSignal": true; }; "hint": { "alias": "hint"; "required": false; "isSignal": true; }; "error": { "alias": "error"; "required": false; "isSignal": true; }; "unit": { "alias": "unit"; "required": false; "isSignal": true; }; "optional": { "alias": "optional"; "required": false; "isSignal": true; }; "invalid": { "alias": "invalid"; "required": false; "isSignal": true; }; }, {}, ["control", "leading", "trailing"], ["[uiFieldLeading]", "*", "[uiFieldTrailing]"], true, never>;
564
+ }
565
+
566
+ type FilterChipOption = {
567
+ value: string;
568
+ label: string;
569
+ count?: number | string | null;
570
+ };
571
+ /**
572
+ * A row of single-choice filter pills, each with an optional count, that narrows a list in place:
573
+ * an asset class, a status. On touch it scrolls on one line, bleeding to the screen edges; with a
574
+ * fine pointer it wraps.
575
+ *
576
+ * @example
577
+ * <ui-filter-chips ariaLabel="Filter by class" [options]="classes()" [(value)]="selectedClass" />
578
+ */
579
+ declare class UiFilterChips {
580
+ readonly options: _angular_core.InputSignal<FilterChipOption[]>;
581
+ readonly value: _angular_core.ModelSignal<string>;
582
+ readonly ariaLabel: _angular_core.InputSignal<string>;
583
+ protected readonly chipClasses = "flex-none flex h-11 items-center rounded-pill border-0 bg-transparent p-0 font-[inherit] cursor-pointer transition-transform duration-(--duration-press) ease-out active:scale-(--press-scale) focus-visible:outline-2 focus-visible:-outline-offset-2 focus-visible:outline-(--ring) pointer-fine:h-8 pointer-fine:focus-visible:outline-offset-2";
584
+ protected pillClasses(optionValue: string): string;
585
+ protected countClasses(optionValue: string): string;
586
+ static ɵfac: _angular_core.ɵɵFactoryDeclaration<UiFilterChips, never>;
587
+ static ɵcmp: _angular_core.ɵɵComponentDeclaration<UiFilterChips, "ui-filter-chips", never, { "options": { "alias": "options"; "required": true; "isSignal": true; }; "value": { "alias": "value"; "required": true; "isSignal": true; }; "ariaLabel": { "alias": "ariaLabel"; "required": true; "isSignal": true; }; }, { "value": "valueChange"; }, never, never, true, never>;
304
588
  }
305
589
 
306
- /** Available control sizes. `md` is the 44/40px touch target. */
307
- declare const CONTROL_SIZES: readonly ["sm", "md"];
590
+ /** Available control sizes. `md` is the 44/40px touch target; `lg` and `xl` are the 48px sheet and sign-in fields. */
591
+ declare const CONTROL_SIZES: readonly ["sm", "md", "lg", "xl"];
308
592
  type ControlSize = (typeof CONTROL_SIZES)[number];
593
+ declare const CONTROL_SURFACES: readonly ["background", "card"];
594
+ type ControlSurface = (typeof CONTROL_SURFACES)[number];
309
595
  /**
310
596
  * Styled native text input. A directive (not a wrapper component) so the host
311
597
  * stays a plain <input>: every forms flavor (ngModel, reactive, signal forms)
@@ -318,12 +604,13 @@ type ControlSize = (typeof CONTROL_SIZES)[number];
318
604
  * <input uiInput type="email" placeholder="you@example.com" />
319
605
  */
320
606
  declare class UiInput implements UiControl {
321
- readonly size: _angular_core.InputSignal<"sm" | "md">;
607
+ readonly size: _angular_core.InputSignal<"sm" | "md" | "lg" | "xl">;
608
+ readonly surface: _angular_core.InputSignal<"background" | "card">;
322
609
  readonly errors: _angular_core.InputSignal<readonly UiControlError[]>;
323
610
  readonly touched: _angular_core.InputSignal<boolean>;
324
611
  protected readonly classes: _angular_core.Signal<string>;
325
612
  static ɵfac: _angular_core.ɵɵFactoryDeclaration<UiInput, never>;
326
- static ɵdir: _angular_core.ɵɵDirectiveDeclaration<UiInput, "input[uiInput]", never, { "size": { "alias": "size"; "required": false; "isSignal": true; }; "errors": { "alias": "errors"; "required": false; "isSignal": true; }; "touched": { "alias": "touched"; "required": false; "isSignal": true; }; }, {}, never, never, true, never>;
613
+ static ɵdir: _angular_core.ɵɵDirectiveDeclaration<UiInput, "input[uiInput]", never, { "size": { "alias": "size"; "required": false; "isSignal": true; }; "surface": { "alias": "surface"; "required": false; "isSignal": true; }; "errors": { "alias": "errors"; "required": false; "isSignal": true; }; "touched": { "alias": "touched"; "required": false; "isSignal": true; }; }, {}, never, never, true, never>;
327
614
  }
328
615
  /**
329
616
  * Styled native textarea. Lives beside the input because it shares every one of its
@@ -343,6 +630,10 @@ declare class UiTextarea implements UiControl {
343
630
  static ɵdir: _angular_core.ɵɵDirectiveDeclaration<UiTextarea, "textarea[uiTextarea]", never, { "errors": { "alias": "errors"; "required": false; "isSignal": true; }; "touched": { "alias": "touched"; "required": false; "isSignal": true; }; }, {}, never, never, true, never>;
344
631
  }
345
632
 
633
+ declare const TOOLTIP_SIZES: readonly ["compact", "large"];
634
+ type TooltipSize = (typeof TOOLTIP_SIZES)[number];
635
+ type AxisTicks = 3 | 5 | 'auto';
636
+
346
637
  type ChartPoint = {
347
638
  t: number;
348
639
  v: number;
@@ -365,12 +656,6 @@ type ChartGeometry = {
365
656
  plotTop: number;
366
657
  };
367
658
 
368
- type StartLabelPlacement = {
369
- x: number;
370
- y: number;
371
- anchor: 'start' | 'end';
372
- };
373
-
374
659
  type PlotRef = ElementRef<SVGSVGElement>;
375
660
  /**
376
661
  * Value over time: a monotone curve with a dashed line at the starting value and a tooltip.
@@ -383,12 +668,19 @@ declare class UiLineChart {
383
668
  readonly points: _angular_core.InputSignal<ChartPoint[]>;
384
669
  readonly label: _angular_core.InputSignal<string>;
385
670
  readonly valueFormat: _angular_core.InputSignal<(value: number) => string>;
671
+ readonly tooltipFormat: _angular_core.InputSignal<((point: ChartPoint) => string) | undefined>;
386
672
  readonly deltaFormat: _angular_core.InputSignal<(delta: number) => string>;
387
673
  readonly timeFormat: _angular_core.InputSignal<(time: number) => string>;
388
674
  readonly axisFormat: _angular_core.InputSignal<(time: number) => string>;
389
675
  readonly startLabel: _angular_core.InputSignal<string>;
390
676
  readonly timeColumnLabel: _angular_core.InputSignal<string>;
391
677
  readonly valueColumnLabel: _angular_core.InputSignal<string>;
678
+ readonly sparkline: _angular_core.InputSignalWithTransform<boolean, unknown>;
679
+ readonly tooltip: _angular_core.InputSignal<"compact" | "auto" | "large">;
680
+ readonly tooltipDelta: _angular_core.InputSignalWithTransform<boolean, unknown>;
681
+ readonly axisGap: _angular_core.InputSignal<number | "auto">;
682
+ readonly axisTicks: _angular_core.InputSignalWithTransform<AxisTicks, string | 3 | 5>;
683
+ protected readonly isCoreTick: (index: number, count: number) => boolean;
392
684
  protected readonly svgRef: _angular_core.Signal<PlotRef>;
393
685
  protected readonly activeIndex: _angular_core.WritableSignal<number | null>;
394
686
  protected readonly animatedLine: _angular_core.WritableSignal<string | null>;
@@ -398,24 +690,33 @@ declare class UiLineChart {
398
690
  } | null>;
399
691
  protected readonly effectiveWidth: _angular_core.Signal<number>;
400
692
  protected readonly effectiveHeight: _angular_core.Signal<number>;
693
+ protected readonly plotHeight: _angular_core.Signal<number>;
694
+ protected readonly tooltipStyle: (point: PlottedPoint) => string;
695
+ protected readonly tooltipClasses: _angular_core.Signal<{
696
+ box: string;
697
+ value: string;
698
+ delta: string;
699
+ }>;
401
700
  protected readonly geometry: _angular_core.Signal<ChartGeometry | null>;
402
701
  protected readonly displayLine: _angular_core.Signal<string>;
403
702
  protected readonly ticks: _angular_core.Signal<PlottedPoint[]>;
404
703
  protected readonly active: _angular_core.Signal<PlottedPoint | null>;
405
704
  protected readonly startLabelInfo: _angular_core.Signal<{
406
705
  label: string;
407
- placement: StartLabelPlacement;
706
+ placement: {
707
+ y: number;
708
+ x: number;
709
+ anchor: "start" | "end";
710
+ };
408
711
  } | null>;
409
712
  constructor();
410
- protected coreTick(index: number, count: number): boolean;
411
713
  protected deltaFor(point: PlottedPoint): number;
412
714
  protected deltaClasses(point: PlottedPoint): string;
413
- protected tooltipStyle(point: PlottedPoint): string;
414
715
  protected onPointerMove(event: PointerEvent): void;
415
716
  protected onPointerLeave(): void;
416
717
  protected onKeydown(event: KeyboardEvent): void;
417
718
  static ɵfac: _angular_core.ɵɵFactoryDeclaration<UiLineChart, never>;
418
- static ɵcmp: _angular_core.ɵɵComponentDeclaration<UiLineChart, "ui-line-chart", never, { "points": { "alias": "points"; "required": true; "isSignal": true; }; "label": { "alias": "label"; "required": true; "isSignal": true; }; "valueFormat": { "alias": "valueFormat"; "required": false; "isSignal": true; }; "deltaFormat": { "alias": "deltaFormat"; "required": false; "isSignal": true; }; "timeFormat": { "alias": "timeFormat"; "required": false; "isSignal": true; }; "axisFormat": { "alias": "axisFormat"; "required": false; "isSignal": true; }; "startLabel": { "alias": "startLabel"; "required": false; "isSignal": true; }; "timeColumnLabel": { "alias": "timeColumnLabel"; "required": false; "isSignal": true; }; "valueColumnLabel": { "alias": "valueColumnLabel"; "required": false; "isSignal": true; }; }, {}, never, never, true, never>;
719
+ static ɵcmp: _angular_core.ɵɵComponentDeclaration<UiLineChart, "ui-line-chart", never, { "points": { "alias": "points"; "required": true; "isSignal": true; }; "label": { "alias": "label"; "required": true; "isSignal": true; }; "valueFormat": { "alias": "valueFormat"; "required": false; "isSignal": true; }; "tooltipFormat": { "alias": "tooltipFormat"; "required": false; "isSignal": true; }; "deltaFormat": { "alias": "deltaFormat"; "required": false; "isSignal": true; }; "timeFormat": { "alias": "timeFormat"; "required": false; "isSignal": true; }; "axisFormat": { "alias": "axisFormat"; "required": false; "isSignal": true; }; "startLabel": { "alias": "startLabel"; "required": false; "isSignal": true; }; "timeColumnLabel": { "alias": "timeColumnLabel"; "required": false; "isSignal": true; }; "valueColumnLabel": { "alias": "valueColumnLabel"; "required": false; "isSignal": true; }; "sparkline": { "alias": "sparkline"; "required": false; "isSignal": true; }; "tooltip": { "alias": "tooltip"; "required": false; "isSignal": true; }; "tooltipDelta": { "alias": "tooltipDelta"; "required": false; "isSignal": true; }; "axisGap": { "alias": "axisGap"; "required": false; "isSignal": true; }; "axisTicks": { "alias": "axisTicks"; "required": false; "isSignal": true; }; }, {}, never, never, true, never>;
419
720
  }
420
721
 
421
722
  /**
@@ -435,7 +736,10 @@ declare class UiMenuItem {
435
736
  static ɵdir: _angular_core.ɵɵDirectiveDeclaration<UiMenuItem, "button[uiMenuItem]", never, { "destructive": { "alias": "destructive"; "required": false; "isSignal": true; }; }, {}, never, never, true, never>;
436
737
  }
437
738
  /**
438
- * Secondary actions menu, opened from its trigger through the native Popover API.
739
+ * Secondary actions menu, opened from its trigger through the native Popover API. With `sheet`, below
740
+ * 64rem it opens as a bottom action sheet above the tab bar instead of beside its trigger, and
741
+ * `heading` names what the actions apply to. `width` fixes the outer popover width in pixels (the sheet
742
+ * always spans the screen below 64rem); without it the menu fits its content.
439
743
  *
440
744
  * @example
441
745
  * <button ui-button size="icon" aria-label="More" [uiMenuTrigger]="menu">...</button>
@@ -447,16 +751,21 @@ declare class UiMenuItem {
447
751
  declare class UiMenu {
448
752
  #private;
449
753
  readonly label: _angular_core.InputSignal<string>;
754
+ readonly sheet: _angular_core.InputSignalWithTransform<boolean, unknown>;
755
+ readonly heading: _angular_core.InputSignal<string | undefined>;
756
+ readonly width: _angular_core.InputSignalWithTransform<number | undefined, unknown>;
450
757
  readonly menuId: string;
451
758
  readonly isOpen: _angular_core.WritableSignal<boolean>;
452
- protected readonly classes = "m-0 min-w-44 p-1 rounded-container bg-(--elevated) shadow-[0_8px_24px_rgb(0_0_0/0.16)] text-(--foreground) transition-[opacity,transform,overlay,display] transition-discrete duration-(--duration-fast) ease-out starting:open:opacity-0 starting:open:scale-(--enter-scale) opacity-0 scale-(--enter-scale) open:opacity-100 open:scale-100";
759
+ protected readonly hasWidth: _angular_core.Signal<boolean>;
760
+ protected readonly widthVar: _angular_core.Signal<string | null>;
761
+ protected readonly classes: _angular_core.Signal<string>;
453
762
  protected readonly items: _angular_core.Signal<readonly UiMenuItem[]>;
454
763
  open(trigger: HTMLElement): void;
455
764
  close(): void;
456
765
  protected onToggle(event: Event): void;
457
766
  protected onKeydown(event: KeyboardEvent): void;
458
767
  static ɵfac: _angular_core.ɵɵFactoryDeclaration<UiMenu, never>;
459
- static ɵcmp: _angular_core.ɵɵComponentDeclaration<UiMenu, "ui-menu", never, { "label": { "alias": "label"; "required": true; "isSignal": true; }; }, {}, ["items"], ["*"], true, never>;
768
+ static ɵcmp: _angular_core.ɵɵComponentDeclaration<UiMenu, "ui-menu", never, { "label": { "alias": "label"; "required": true; "isSignal": true; }; "sheet": { "alias": "sheet"; "required": false; "isSignal": true; }; "heading": { "alias": "heading"; "required": false; "isSignal": true; }; "width": { "alias": "width"; "required": false; "isSignal": true; }; }, {}, ["items"], ["*"], true, never>;
460
769
  }
461
770
  /**
462
771
  * Opens a `ui-menu` from a trigger element and wires `aria-haspopup`, `aria-expanded` and
@@ -473,6 +782,9 @@ declare class UiMenuTrigger {
473
782
  static ɵdir: _angular_core.ɵɵDirectiveDeclaration<UiMenuTrigger, "[uiMenuTrigger]", never, { "uiMenuTrigger": { "alias": "uiMenuTrigger"; "required": true; "isSignal": true; }; }, {}, never, never, true, never>;
474
783
  }
475
784
 
785
+ /** Track thicknesses. `MeterSize` is derived from this tuple. */
786
+ declare const METER_SIZES: readonly ["md", "sm"];
787
+ type MeterSize = (typeof METER_SIZES)[number];
476
788
  /** Ramp step used to paint the fill. `MeterTone` is derived from this tuple. */
477
789
  declare const METER_TONES: readonly [1, 2, 3, 4, 5, 6];
478
790
  type MeterTone = (typeof METER_TONES)[number];
@@ -487,11 +799,13 @@ declare class UiMeter {
487
799
  readonly value: _angular_core.InputSignal<number>;
488
800
  readonly label: _angular_core.InputSignal<string>;
489
801
  readonly valueText: _angular_core.InputSignal<string>;
490
- readonly tone: _angular_core.InputSignal<3 | 2 | 4 | 1 | 5 | 6>;
802
+ readonly tone: _angular_core.InputSignal<2 | 4 | 3 | 1 | 5 | 6>;
803
+ readonly size: _angular_core.InputSignal<"sm" | "md">;
804
+ protected readonly trackClasses: _angular_core.Signal<string>;
491
805
  protected readonly percent: _angular_core.Signal<number>;
492
806
  protected readonly fillClasses: _angular_core.Signal<string>;
493
807
  static ɵfac: _angular_core.ɵɵFactoryDeclaration<UiMeter, never>;
494
- static ɵcmp: _angular_core.ɵɵComponentDeclaration<UiMeter, "ui-meter", never, { "value": { "alias": "value"; "required": true; "isSignal": true; }; "label": { "alias": "label"; "required": true; "isSignal": true; }; "valueText": { "alias": "valueText"; "required": true; "isSignal": true; }; "tone": { "alias": "tone"; "required": false; "isSignal": true; }; }, {}, never, never, true, never>;
808
+ static ɵcmp: _angular_core.ɵɵComponentDeclaration<UiMeter, "ui-meter", never, { "value": { "alias": "value"; "required": true; "isSignal": true; }; "label": { "alias": "label"; "required": true; "isSignal": true; }; "valueText": { "alias": "valueText"; "required": true; "isSignal": true; }; "tone": { "alias": "tone"; "required": false; "isSignal": true; }; "size": { "alias": "size"; "required": false; "isSignal": true; }; }, {}, never, never, true, never>;
495
809
  }
496
810
 
497
811
  /**
@@ -510,6 +824,12 @@ declare class UiNavItem {
510
824
  static ɵcmp: _angular_core.ɵɵComponentDeclaration<UiNavItem, "a[ui-nav-item]", never, { "active": { "alias": "active"; "required": false; "isSignal": true; }; }, {}, never, ["[navIcon]", "*"], true, never>;
511
825
  }
512
826
 
827
+ declare const ROW_SIZES: readonly ["md", "lg", "xl", "card", "dense"];
828
+ type RowSize = (typeof ROW_SIZES)[number];
829
+ declare const ROW_PADDINGS: readonly ["md", "sm", "none"];
830
+ type RowPadding = (typeof ROW_PADDINGS)[number];
831
+ declare const ROW_GAPS: readonly ["default", "sm"];
832
+ type RowGap = (typeof ROW_GAPS)[number];
513
833
  /**
514
834
  * Clickable row of a list: a holding, an envelope, an account.
515
835
  *
@@ -520,15 +840,53 @@ declare class UiNavItem {
520
840
  */
521
841
  declare class UiRow {
522
842
  readonly selected: _angular_core.InputSignalWithTransform<boolean, unknown>;
843
+ readonly size: _angular_core.InputSignal<"md" | "lg" | "xl" | "card" | "dense">;
844
+ readonly padding: _angular_core.InputSignal<"sm" | "md" | "none">;
845
+ readonly gap: _angular_core.InputSignal<"sm" | "default">;
523
846
  protected readonly classes: _angular_core.Signal<string>;
524
847
  static ɵfac: _angular_core.ɵɵFactoryDeclaration<UiRow, never>;
525
- static ɵcmp: _angular_core.ɵɵComponentDeclaration<UiRow, "a[ui-row], button[ui-row]", never, { "selected": { "alias": "selected"; "required": false; "isSignal": true; }; }, {}, never, ["*"], true, never>;
848
+ static ɵcmp: _angular_core.ɵɵComponentDeclaration<UiRow, "a[ui-row], button[ui-row]", never, { "selected": { "alias": "selected"; "required": false; "isSignal": true; }; "size": { "alias": "size"; "required": false; "isSignal": true; }; "padding": { "alias": "padding"; "required": false; "isSignal": true; }; "gap": { "alias": "gap"; "required": false; "isSignal": true; }; }, {}, never, ["*"], true, never>;
849
+ }
850
+ /**
851
+ * Lays out a `ui-row` with a trailing action beside it, such as a "more" icon button: the row takes
852
+ * the room the action leaves and the action keeps its own size.
853
+ *
854
+ * @example
855
+ * <div uiRowItem>
856
+ * <a ui-row size="xl" padding="sm" routerLink="/accounts/1">...</a>
857
+ * <button ui-button variant="quiet" size="icon-sm" aria-label="Account actions">...</button>
858
+ * </div>
859
+ */
860
+ declare class UiRowItem {
861
+ static ɵfac: _angular_core.ɵɵFactoryDeclaration<UiRowItem, never>;
862
+ static ɵdir: _angular_core.ɵɵDirectiveDeclaration<UiRowItem, "[uiRowItem]", never, {}, {}, never, never, true, never>;
863
+ }
864
+ /**
865
+ * Non-interactive row of a list, separated from the next by a hairline: a passkey with its delete
866
+ * button, a device, a setting. It is a 72px row (68px from 64rem) with a 12px gap; put it on an
867
+ * `li` or a `div`. Use `ui-row` instead when the whole row is a link or an action.
868
+ *
869
+ * @example
870
+ * <ul>
871
+ * <li uiListRow>
872
+ * <span class="flex-1">MacBook Air</span>
873
+ * <button ui-button variant="quiet-destructive" size="icon-sm" aria-label="Delete MacBook Air">...</button>
874
+ * </li>
875
+ * </ul>
876
+ */
877
+ declare class UiListRow {
878
+ readonly ruled: _angular_core.InputSignalWithTransform<boolean, unknown>;
879
+ protected readonly classes: _angular_core.Signal<string>;
880
+ static ɵfac: _angular_core.ɵɵFactoryDeclaration<UiListRow, never>;
881
+ static ɵdir: _angular_core.ɵɵDirectiveDeclaration<UiListRow, "[uiListRow]", never, { "ruled": { "alias": "ruled"; "required": false; "isSignal": true; }; }, {}, never, never, true, never>;
526
882
  }
527
883
 
528
884
  type SegmentedOption = {
529
885
  value: string;
530
886
  label: string;
531
887
  };
888
+ declare const SEGMENTED_SIZES: readonly ["md", "sm"];
889
+ type SegmentedSize = (typeof SEGMENTED_SIZES)[number];
532
890
  /**
533
891
  * Exclusive choice within a small, known set: a time range, a unit, a mode. The selected option's
534
892
  * background is a single thumb that slides under it in `transform`, instead of being redrawn.
@@ -539,7 +897,10 @@ type SegmentedOption = {
539
897
  declare class UiSegmented {
540
898
  readonly options: _angular_core.InputSignal<SegmentedOption[]>;
541
899
  readonly label: _angular_core.InputSignal<string>;
900
+ readonly showLabel: _angular_core.InputSignalWithTransform<boolean, unknown>;
901
+ protected readonly labelId: string;
542
902
  readonly value: _angular_core.ModelSignal<string>;
903
+ readonly size: _angular_core.InputSignal<"sm" | "md">;
543
904
  protected readonly radios: _angular_core.Signal<readonly ElementRef<HTMLButtonElement>[]>;
544
905
  protected readonly thumbIndex: _angular_core.Signal<number>;
545
906
  protected optionClasses(optionValue: string): string;
@@ -547,7 +908,7 @@ declare class UiSegmented {
547
908
  protected select(optionValue: string): void;
548
909
  protected onKeydown(event: KeyboardEvent): void;
549
910
  static ɵfac: _angular_core.ɵɵFactoryDeclaration<UiSegmented, never>;
550
- static ɵcmp: _angular_core.ɵɵComponentDeclaration<UiSegmented, "ui-segmented", never, { "options": { "alias": "options"; "required": true; "isSignal": true; }; "label": { "alias": "label"; "required": true; "isSignal": true; }; "value": { "alias": "value"; "required": true; "isSignal": true; }; }, { "value": "valueChange"; }, never, never, true, never>;
911
+ static ɵcmp: _angular_core.ɵɵComponentDeclaration<UiSegmented, "ui-segmented", never, { "options": { "alias": "options"; "required": true; "isSignal": true; }; "label": { "alias": "label"; "required": true; "isSignal": true; }; "showLabel": { "alias": "showLabel"; "required": false; "isSignal": true; }; "value": { "alias": "value"; "required": true; "isSignal": true; }; "size": { "alias": "size"; "required": false; "isSignal": true; }; }, { "value": "valueChange"; }, never, never, true, never>;
551
912
  }
552
913
 
553
914
  /**
@@ -561,7 +922,7 @@ declare class UiSegmented {
561
922
  * <select uiSelect><option value="pea">PEA</option></select>
562
923
  */
563
924
  declare class UiSelect implements UiControl {
564
- readonly size: _angular_core.InputSignal<"sm" | "md">;
925
+ readonly size: _angular_core.InputSignal<"sm" | "md" | "lg" | "xl">;
565
926
  readonly errors: _angular_core.InputSignal<readonly UiControlError[]>;
566
927
  readonly touched: _angular_core.InputSignal<boolean>;
567
928
  protected readonly classes: _angular_core.Signal<string>;
@@ -569,6 +930,9 @@ declare class UiSelect implements UiControl {
569
930
  static ɵdir: _angular_core.ɵɵDirectiveDeclaration<UiSelect, "select[uiSelect]", never, { "size": { "alias": "size"; "required": false; "isSignal": true; }; "errors": { "alias": "errors"; "required": false; "isSignal": true; }; "touched": { "alias": "touched"; "required": false; "isSignal": true; }; }, {}, never, never, true, never>;
570
931
  }
571
932
 
933
+ /** Available skeleton shapes. `SkeletonShape` is derived from this tuple. */
934
+ declare const SKELETON_SHAPES: readonly ["text", "figure", "row", "chart", "ring", "dot"];
935
+ type SkeletonShape = (typeof SKELETON_SHAPES)[number];
572
936
  /**
573
937
  * Decorative, pulsing placeholder for content that is still loading, at the shape of the content
574
938
  * it stands in for.
@@ -578,13 +942,14 @@ declare class UiSelect implements UiControl {
578
942
  * <ui-skeleton [lines]="3" />
579
943
  */
580
944
  declare class UiSkeleton {
581
- readonly shape: _angular_core.InputSignal<"text" | "figure" | "row" | "chart" | "ring">;
945
+ readonly shape: _angular_core.InputSignal<"text" | "figure" | "row" | "chart" | "ring" | "dot">;
582
946
  readonly lines: _angular_core.InputSignal<number>;
583
947
  readonly height: _angular_core.InputSignal<number>;
948
+ readonly size: _angular_core.InputSignal<number>;
584
949
  protected readonly animation = "cairn-pulse var(--pulse-duration) var(--ease-out) infinite alternate";
585
950
  protected readonly bars: _angular_core.Signal<("62%" | "100%")[]>;
586
951
  static ɵfac: _angular_core.ɵɵFactoryDeclaration<UiSkeleton, never>;
587
- static ɵcmp: _angular_core.ɵɵComponentDeclaration<UiSkeleton, "ui-skeleton", never, { "shape": { "alias": "shape"; "required": false; "isSignal": true; }; "lines": { "alias": "lines"; "required": false; "isSignal": true; }; "height": { "alias": "height"; "required": false; "isSignal": true; }; }, {}, never, never, true, never>;
952
+ static ɵcmp: _angular_core.ɵɵComponentDeclaration<UiSkeleton, "ui-skeleton", never, { "shape": { "alias": "shape"; "required": false; "isSignal": true; }; "lines": { "alias": "lines"; "required": false; "isSignal": true; }; "height": { "alias": "height"; "required": false; "isSignal": true; }; "size": { "alias": "size"; "required": false; "isSignal": true; }; }, {}, never, never, true, never>;
588
953
  }
589
954
 
590
955
  /** Available stat sizes. `StatSize` is derived from this tuple. */
@@ -608,7 +973,8 @@ type StatSize = (typeof STAT_SIZES)[number];
608
973
  declare class UiStat {
609
974
  readonly label: _angular_core.InputSignal<string>;
610
975
  readonly size: _angular_core.InputSignal<"hero" | "tile">;
611
- protected readonly labelClasses = "text-label font-medium text-(--subtle-foreground)";
976
+ protected readonly labelClasses: _angular_core.Signal<string>;
977
+ protected readonly stackClasses: _angular_core.Signal<string>;
612
978
  protected readonly valueClasses: _angular_core.Signal<string>;
613
979
  static ɵfac: _angular_core.ɵɵFactoryDeclaration<UiStat, never>;
614
980
  static ɵcmp: _angular_core.ɵɵComponentDeclaration<UiStat, "ui-stat", never, { "label": { "alias": "label"; "required": true; "isSignal": true; }; "size": { "alias": "size"; "required": false; "isSignal": true; }; }, {}, never, ["[uiStatValue]", "[uiStatDelta]", "[uiStatCaption]", "[uiStatAside]"], true, never>;
@@ -616,85 +982,175 @@ declare class UiStat {
616
982
 
617
983
  /**
618
984
  * Native checkbox styled as an iOS-style switch, exposed to assistive technology as `role="switch"`.
985
+ * 51 by 31 on touch, 40 by 24 with a mouse.
619
986
  *
620
987
  * @example
621
988
  * <input type="checkbox" uiSwitch [checked]="hidden()" (change)="toggle()" aria-label="Hide amounts" />
622
989
  */
623
990
  declare class UiSwitch {
624
- protected readonly classes = "relative shrink-0 w-[51px] h-[31px] appearance-none cursor-pointer rounded-pill bg-(--muted) checked:bg-(--primary) transition-colors duration-(--duration-fast) ease-out disabled:pointer-events-none disabled:opacity-40 focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-(--ring) before:absolute before:inset-x-0 before:top-1/2 before:-translate-y-1/2 before:h-(--row-min) before:content-[''] after:absolute after:top-0.5 after:left-0.5 after:size-[27px] after:rounded-pill after:bg-(--card) after:shadow-[0_1px_3px_rgb(0_0_0/0.2)] after:transition-transform after:duration-(--duration-fast) after:ease-out after:content-[''] checked:after:translate-x-[20px]";
991
+ protected readonly classes = "relative shrink-0 w-[51px] h-[31px] pointer-fine:w-10 pointer-fine:h-6 appearance-none cursor-pointer rounded-pill bg-(--muted) checked:bg-(--primary) transition-colors duration-(--duration-fast) ease-out disabled:pointer-events-none disabled:opacity-40 focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-(--ring) before:absolute before:inset-x-0 before:top-1/2 before:-translate-y-1/2 before:h-(--row-min) before:content-[''] after:absolute after:top-0.5 after:left-0.5 after:size-[27px] pointer-fine:after:size-5 after:rounded-pill after:bg-(--card) after:shadow-[0_1px_3px_rgb(0_0_0/0.2)] after:transition-transform after:duration-(--duration-fast) after:ease-out after:content-[''] checked:after:translate-x-[20px] pointer-fine:checked:after:translate-x-4";
625
992
  static ɵfac: _angular_core.ɵɵFactoryDeclaration<UiSwitch, never>;
626
993
  static ɵdir: _angular_core.ɵɵDirectiveDeclaration<UiSwitch, "input[type=checkbox][uiSwitch]", never, {}, {}, never, never, true, never>;
627
994
  }
628
995
 
996
+ /**
997
+ * Bottom navigation bar for iPhone: 52px of tabs plus the home indicator's safe area.
998
+ *
999
+ * @example
1000
+ * <nav ui-tab-bar>
1001
+ * <a ui-tab [active]="url === '/'" routerLink="/"><lucide-icon tabIcon name="house" />Portfolio</a>
1002
+ * </nav>
1003
+ */
1004
+ declare class UiTabBar {
1005
+ static ɵfac: _angular_core.ɵɵFactoryDeclaration<UiTabBar, never>;
1006
+ static ɵcmp: _angular_core.ɵɵComponentDeclaration<UiTabBar, "nav[ui-tab-bar]", never, {}, {}, never, ["*"], true, never>;
1007
+ }
1008
+ /**
1009
+ * One destination of `ui-tab-bar`.
1010
+ *
1011
+ * @example
1012
+ * <a ui-tab active routerLink="/"><lucide-icon tabIcon name="house" />Portfolio</a>
1013
+ */
1014
+ declare class UiTab {
1015
+ readonly active: _angular_core.InputSignalWithTransform<boolean, unknown>;
1016
+ protected readonly classes: _angular_core.Signal<string>;
1017
+ static ɵfac: _angular_core.ɵɵFactoryDeclaration<UiTab, never>;
1018
+ static ɵcmp: _angular_core.ɵɵComponentDeclaration<UiTab, "a[ui-tab]", never, { "active": { "alias": "active"; "required": false; "isSignal": true; }; }, {}, never, ["[tabIcon]", "*"], true, never>;
1019
+ }
1020
+
629
1021
  /** Breakpoints a secondary column can be held back until. */
630
1022
  declare const CELL_BREAKPOINTS: readonly ["md", "lg"];
631
1023
  type CellBreakpoint = (typeof CELL_BREAKPOINTS)[number];
632
- /** Styled native table. The rows and cells stay plain <tr> and <td>. */
1024
+ /** Body row heights. */
1025
+ declare const TABLE_ROWS: readonly ["48", "52", "60"];
1026
+ type TableRow = (typeof TABLE_ROWS)[number];
1027
+ /**
1028
+ * Styled native table. The rows and cells stay plain <tr> and <td>. `row` sets the height of every
1029
+ * body row, `rule` draws or drops the hairline under the header, `spaced` leaves 4px between the
1030
+ * header and the first row.
1031
+ *
1032
+ * @example
1033
+ * <table uiTable row="60" [rule]="false">
1034
+ */
633
1035
  declare class UiTable {
1036
+ readonly row: _angular_core.InputSignal<"48" | "52" | "60">;
1037
+ readonly rule: _angular_core.InputSignalWithTransform<boolean, unknown>;
1038
+ readonly spaced: _angular_core.InputSignalWithTransform<boolean, unknown>;
1039
+ protected readonly classes: _angular_core.Signal<string>;
634
1040
  static ɵfac: _angular_core.ɵɵFactoryDeclaration<UiTable, never>;
635
- static ɵdir: _angular_core.ɵɵDirectiveDeclaration<UiTable, "table[uiTable]", never, {}, {}, never, never, true, never>;
1041
+ static ɵdir: _angular_core.ɵɵDirectiveDeclaration<UiTable, "table[uiTable]", never, { "row": { "alias": "row"; "required": false; "isSignal": true; }; "rule": { "alias": "rule"; "required": false; "isSignal": true; }; "spaced": { "alias": "spaced"; "required": false; "isSignal": true; }; }, {}, never, never, true, never>;
1042
+ }
1043
+ /** Body of one group of rows: leaves a 4px tail after its last row. */
1044
+ declare class UiGroup {
1045
+ static ɵfac: _angular_core.ɵɵFactoryDeclaration<UiGroup, never>;
1046
+ static ɵdir: _angular_core.ɵɵDirectiveDeclaration<UiGroup, "tbody[uiGroup]", never, {}, {}, never, never, true, never>;
636
1047
  }
637
1048
  /**
638
- * Body or group row. `group` draws the muted banner that opens each account inside a list of
639
- * holdings: it carries no hover state of its own, unlike an ordinary row.
1049
+ * Body or group row. An ordinary row glows on hover and takes the soft fill when `selected`; an
1050
+ * `interactive` row (one that opens something) also presses to the soft fill. A row with no action keeps a
1051
+ * plain name: `<td uiTd primary class="truncate font-medium">`.
1052
+ * `group` marks the row that holds a group band: it carries no hover state.
640
1053
  *
641
1054
  * @example
642
- * <tr uiTr>...
643
- * <tr uiTr group>...
1055
+ * <tr uiTr [selected]="open">...
1056
+ * <tr uiTr group><td ui-group-cell name="Brokerage">...
644
1057
  */
645
1058
  declare class UiTr {
646
1059
  readonly group: _angular_core.InputSignalWithTransform<boolean, unknown>;
647
- protected readonly classes: _angular_core.Signal<"min-h-(--row-min) rounded-control bg-(--muted) font-semibold" | "rounded-control hover:bg-(--glow)">;
1060
+ readonly selected: _angular_core.InputSignalWithTransform<boolean, unknown>;
1061
+ readonly interactive: _angular_core.InputSignalWithTransform<boolean, unknown>;
1062
+ protected readonly classes: _angular_core.Signal<string>;
648
1063
  static ɵfac: _angular_core.ɵɵFactoryDeclaration<UiTr, never>;
649
- static ɵdir: _angular_core.ɵɵDirectiveDeclaration<UiTr, "tr[uiTr]", never, { "group": { "alias": "group"; "required": false; "isSignal": true; }; }, {}, never, never, true, never>;
1064
+ static ɵdir: _angular_core.ɵɵDirectiveDeclaration<UiTr, "tr[uiTr]", never, { "group": { "alias": "group"; "required": false; "isSignal": true; }; "selected": { "alias": "selected"; "required": false; "isSignal": true; }; "interactive": { "alias": "interactive"; "required": false; "isSignal": true; }; }, {}, never, never, true, never>;
650
1065
  }
651
1066
  /**
652
- * Column header. `numeric` right-aligns and lines the digits up; `from` holds a
653
- * secondary column back until the viewport is wide enough for it.
1067
+ * Column header, centred in its 36px. `numeric` right-aligns and lines the digits up; `secondary`
1068
+ * (or `from`) holds a column back until the viewport is wide enough for it; `primary` makes it
1069
+ * the column that absorbs the free width and truncates; `tall` is a 40px header; `width` fixes the column width and keeps it from shrinking.
654
1070
  *
655
1071
  * @example
656
- * <th uiTh numeric from="md">Average cost</th>
1072
+ * <th uiTh numeric secondary width="108px">Quantity</th>
657
1073
  */
658
1074
  declare class UiTh {
1075
+ readonly width: _angular_core.InputSignal<string | null>;
659
1076
  readonly numeric: _angular_core.InputSignalWithTransform<boolean, unknown>;
1077
+ readonly primary: _angular_core.InputSignalWithTransform<boolean, unknown>;
1078
+ readonly secondary: _angular_core.InputSignalWithTransform<boolean, unknown>;
1079
+ readonly tall: _angular_core.InputSignalWithTransform<boolean, unknown>;
660
1080
  readonly from: _angular_core.InputSignal<"md" | "lg" | null>;
661
1081
  protected readonly classes: _angular_core.Signal<string>;
662
1082
  static ɵfac: _angular_core.ɵɵFactoryDeclaration<UiTh, never>;
663
- static ɵdir: _angular_core.ɵɵDirectiveDeclaration<UiTh, "th[uiTh]", never, { "numeric": { "alias": "numeric"; "required": false; "isSignal": true; }; "from": { "alias": "from"; "required": false; "isSignal": true; }; }, {}, never, never, true, never>;
1083
+ static ɵdir: _angular_core.ɵɵDirectiveDeclaration<UiTh, "th[uiTh]", never, { "width": { "alias": "width"; "required": false; "isSignal": true; }; "numeric": { "alias": "numeric"; "required": false; "isSignal": true; }; "primary": { "alias": "primary"; "required": false; "isSignal": true; }; "secondary": { "alias": "secondary"; "required": false; "isSignal": true; }; "tall": { "alias": "tall"; "required": false; "isSignal": true; }; "from": { "alias": "from"; "required": false; "isSignal": true; }; }, {}, never, never, true, never>;
664
1084
  }
665
- /** Body cell. Same two inputs as `UiTh`, and they must be set on both to match. */
1085
+ /** Body cell. Same inputs as `UiTh` (bar `tall` and `width`), and they must be set on both to match. */
666
1086
  declare class UiTd {
667
1087
  readonly numeric: _angular_core.InputSignalWithTransform<boolean, unknown>;
1088
+ readonly primary: _angular_core.InputSignalWithTransform<boolean, unknown>;
1089
+ readonly secondary: _angular_core.InputSignalWithTransform<boolean, unknown>;
668
1090
  readonly from: _angular_core.InputSignal<"md" | "lg" | null>;
669
1091
  protected readonly classes: _angular_core.Signal<string>;
670
1092
  static ɵfac: _angular_core.ɵɵFactoryDeclaration<UiTd, never>;
671
- static ɵdir: _angular_core.ɵɵDirectiveDeclaration<UiTd, "td[uiTd]", never, { "numeric": { "alias": "numeric"; "required": false; "isSignal": true; }; "from": { "alias": "from"; "required": false; "isSignal": true; }; }, {}, never, never, true, never>;
1093
+ static ɵdir: _angular_core.ɵɵDirectiveDeclaration<UiTd, "td[uiTd]", never, { "numeric": { "alias": "numeric"; "required": false; "isSignal": true; }; "primary": { "alias": "primary"; "required": false; "isSignal": true; }; "secondary": { "alias": "secondary"; "required": false; "isSignal": true; }; "from": { "alias": "from"; "required": false; "isSignal": true; }; }, {}, never, never, true, never>;
672
1094
  }
673
-
1095
+ /** Group band sizes. */
1096
+ declare const GROUP_SIZES: readonly ["md", "lg"];
1097
+ type GroupSize = (typeof GROUP_SIZES)[number];
674
1098
  /**
675
- * Bottom navigation bar for iPhone: 52px of tabs plus the home indicator's safe area.
1099
+ * The band that opens a group of rows: name in 600 (a heading), meta beside it, the projected
1100
+ * total pinned to the right. Spans the whole row through `colspan`.
676
1101
  *
677
1102
  * @example
678
- * <nav ui-tab-bar>
679
- * <a ui-tab [active]="url === '/'" routerLink="/"><lucide-icon tabIcon name="house" />Portfolio</a>
680
- * </nav>
1103
+ * <tr uiTr group><td ui-group-cell colspan="4" name="Brokerage" meta="Savings plan">...total...</td></tr>
681
1104
  */
682
- declare class UiTabBar {
683
- static ɵfac: _angular_core.ɵɵFactoryDeclaration<UiTabBar, never>;
684
- static ɵcmp: _angular_core.ɵɵComponentDeclaration<UiTabBar, "nav[ui-tab-bar]", never, {}, {}, never, ["*"], true, never>;
1105
+ declare class UiGroupCell {
1106
+ readonly name: _angular_core.InputSignal<string>;
1107
+ readonly meta: _angular_core.InputSignal<string | undefined>;
1108
+ readonly size: _angular_core.InputSignal<"md" | "lg">;
1109
+ protected readonly hostClasses: _angular_core.Signal<string>;
1110
+ static ɵfac: _angular_core.ɵɵFactoryDeclaration<UiGroupCell, never>;
1111
+ static ɵcmp: _angular_core.ɵɵComponentDeclaration<UiGroupCell, "td[ui-group-cell]", never, { "name": { "alias": "name"; "required": true; "isSignal": true; }; "meta": { "alias": "meta"; "required": false; "isSignal": true; }; "size": { "alias": "size"; "required": false; "isSignal": true; }; }, {}, never, ["*"], true, never>;
685
1112
  }
686
1113
  /**
687
- * One destination of `ui-tab-bar`.
1114
+ * Makes a link or button the way into its row. By default an invisible layer stretches over the
1115
+ * whole row, so the row is one target for the pointer, the keyboard and a screen reader, and its
1116
+ * focus ring wraps the row. With `[stretch]="false"` only the name is the
1117
+ * target: it underlines on hover and takes its own ring. `current` marks the open line.
688
1118
  *
689
1119
  * @example
690
- * <a ui-tab active routerLink="/"><lucide-icon tabIcon name="house" />Portfolio</a>
1120
+ * <td uiTd primary><a uiRowLink href="/lines/42">Ferrari</a></td>
1121
+ * <td uiTd primary><a uiRowLink [stretch]="false" href="/accounts/3">Brokerage</a></td>
691
1122
  */
692
- declare class UiTab {
693
- readonly active: _angular_core.InputSignalWithTransform<boolean, unknown>;
1123
+ declare class UiRowLink {
1124
+ readonly stretch: _angular_core.InputSignalWithTransform<boolean, unknown>;
1125
+ readonly current: _angular_core.InputSignalWithTransform<boolean, unknown>;
1126
+ protected readonly classes: _angular_core.Signal<"block max-w-full truncate rounded-control text-left font-medium outline-none after:absolute after:inset-0 after:rounded-control after:content-[\"\"] focus-visible:after:outline-2 focus-visible:after:-outline-offset-2 focus-visible:after:outline-(--ring)" | "block max-w-full truncate rounded-sm text-left font-medium underline-offset-[3px] outline-none hover:underline focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-(--ring)">;
1127
+ static ɵfac: _angular_core.ɵɵFactoryDeclaration<UiRowLink, never>;
1128
+ static ɵdir: _angular_core.ɵɵDirectiveDeclaration<UiRowLink, "a[uiRowLink], button[uiRowLink]", never, { "stretch": { "alias": "stretch"; "required": false; "isSignal": true; }; "current": { "alias": "current"; "required": false; "isSignal": true; }; }, {}, never, never, true, never>;
1129
+ }
1130
+ /** A control in another cell of a stretched-link row: lifts it above the layer that covers the row. */
1131
+ declare class UiRowAction {
1132
+ static ɵfac: _angular_core.ɵɵFactoryDeclaration<UiRowAction, never>;
1133
+ static ɵdir: _angular_core.ɵɵDirectiveDeclaration<UiRowAction, "[uiRowAction]", never, {}, {}, never, never, true, never>;
1134
+ }
1135
+ /** Tones of a subtitle: subtle (default), `--stale` at 500, or the color of the cell. */
1136
+ declare const SUB_TONES: readonly ["subtle", "stale", "inherit"];
1137
+ type SubTone = (typeof SUB_TONES)[number];
1138
+ /**
1139
+ * A second line under a cell's main text. `narrow` shows it only under 1024px, where it carries
1140
+ * the quantity, average cost and quote that were held back. Its amounts go through `ui-amount`
1141
+ * so they mask.
1142
+ *
1143
+ * @example
1144
+ * <span uiCellSub narrow>10 × 421.26 € · cost 388.10 €</span>
1145
+ * <span uiCellSub tone="stale">Quote of 24/09</span>
1146
+ */
1147
+ declare class UiCellSub {
1148
+ readonly narrow: _angular_core.InputSignalWithTransform<boolean, unknown>;
1149
+ readonly tone: _angular_core.InputSignal<"inherit" | "subtle" | "stale">;
694
1150
  protected readonly classes: _angular_core.Signal<string>;
695
- static ɵfac: _angular_core.ɵɵFactoryDeclaration<UiTab, never>;
696
- static ɵcmp: _angular_core.ɵɵComponentDeclaration<UiTab, "a[ui-tab]", never, { "active": { "alias": "active"; "required": false; "isSignal": true; }; }, {}, never, ["[tabIcon]", "*"], true, never>;
1151
+ static ɵfac: _angular_core.ɵɵFactoryDeclaration<UiCellSub, never>;
1152
+ static ɵdir: _angular_core.ɵɵDirectiveDeclaration<UiCellSub, "[uiCellSub]", never, { "narrow": { "alias": "narrow"; "required": false; "isSignal": true; }; "tone": { "alias": "tone"; "required": false; "isSignal": true; }; }, {}, never, never, true, never>;
697
1153
  }
698
1154
 
699
- export { AMOUNT_MASKINGS, AMOUNT_NUMERICS, ASYNC_STATES, AVATAR_SIZES, BADGE_VARIANTS, BUTTON_SIZES, BUTTON_VARIANTS, CARD_PADDINGS, CARD_VARIANTS, CELL_BREAKPOINTS, CONTROL_SIZES, DELTA_EMPHASES, DIALOG_WIDTHS, METER_TONES, STAT_SIZES, UI_AMOUNT_MASKED, UiAmount, UiAsync, UiAvatar, UiBadge, UiButton, UiCard, UiDelta, UiDialog, UiDonut, UiField, UiInput, UiLineChart, UiMenu, UiMenuItem, UiMenuTrigger, UiMeter, UiNavItem, UiRow, UiSegmented, UiSelect, UiSkeleton, UiStat, UiSwitch, UiTab, UiTabBar, UiTable, UiTd, UiTextarea, UiTh, UiTr, formatAmount };
700
- export type { AmountFormatOptions, AmountMasking, AmountNumeric, AsyncState, AvatarSize, BadgeVariant, ButtonSize, ButtonVariant, CardPadding, CardVariant, CellBreakpoint, ChartPoint, ControlSize, DeltaEmphasis, DialogWidth, DonutSlice, MeterTone, SegmentedOption, StatSize, UiControlError };
1155
+ export { ALERT_VARIANTS, AMOUNT_MASKINGS, AMOUNT_NUMERICS, ASYNC_ALIGNS, ASYNC_STATES, ASYNC_VARIANTS, AVATAR_SIZES, BACK_LINK_SIZES, BADGE_SIZES, BADGE_VARIANTS, BUTTON_SIZES, BUTTON_VARIANTS, CARD_PADDINGS, CARD_SURFACES, CARD_VARIANTS, CELL_BREAKPOINTS, CONTROL_SIZES, CONTROL_SURFACES, DELTA_EMPHASES, DELTA_SIZES, DELTA_WEIGHTS, DIALOG_LAYOUTS, DIALOG_WIDTHS, FACT_SIZES, FACT_SUB_TONES, GROUP_SIZES, METER_SIZES, METER_TONES, ROW_GAPS, ROW_PADDINGS, ROW_SIZES, SEGMENTED_SIZES, SKELETON_SHAPES, STAT_SIZES, SUB_TONES, TABLE_ROWS, UI_AMOUNT_MASKED, UiActionBar, UiAlert, UiAmount, UiAsync, UiAvatar, UiAvatarLink, UiBackLink, UiBadge, UiButton, UiCard, UiCellSub, UiChoiceChips, UiDelta, UiDialog, UiDonut, UiExternalLink, UiFact, UiFacts, UiField, UiFieldLeading, UiFieldTrailing, UiFilterChips, UiGroup, UiGroupCell, UiInput, UiLineChart, UiListRow, UiMenu, UiMenuItem, UiMenuTrigger, UiMeter, UiNavItem, UiRow, UiRowAction, UiRowItem, UiRowLink, UiSegmented, UiSelect, UiSkeleton, UiStat, UiSwitch, UiTab, UiTabBar, UiTable, UiTd, UiTextarea, UiTh, UiTr, formatAmount };
1156
+ export type { AlertVariant, AmountFormatOptions, AmountMasking, AmountNumeric, AsyncAlign, AsyncState, AsyncVariant, AvatarSize, AxisTicks, BackLinkSize, BadgeSize, BadgeVariant, ButtonSize, ButtonVariant, CardPadding, CardSurface, CardVariant, CellBreakpoint, ChartPoint, ChoiceChipOption, ControlSize, ControlSurface, DeltaEmphasis, DeltaSize, DeltaWeight, DialogLayout, DialogWidth, DonutSlice, FactSize, FactSubTone, FilterChipOption, GroupSize, MeterSize, MeterTone, RowGap, RowPadding, RowSize, SegmentedOption, SegmentedSize, SkeletonShape, StatSize, SubTone, TableRow, TooltipSize, UiControlError };