@forgeroute/ui 0.3.12 → 0.4.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.
@@ -1971,6 +1971,107 @@ export declare class ProgressBarComponent {
1971
1971
  };
1972
1972
  }, {}, never, never, true, never>;
1973
1973
  }
1974
+ export type ProgressRingVariant = 'blue' | 'green' | 'amber' | 'red' | 'slate' | 'sky';
1975
+ /**
1976
+ * Circular progress ring with the rounded percentage (or a custom `label`) in the middle.
1977
+ * Pass `value` and `max` (default 100); the arc is clamped to 0–100% and starts at 12 o'clock. A value of 0 draws no arc; invalid numbers
1978
+ * (NaN, a negative or infinite max) draw an empty ring.
1979
+ *
1980
+ * The arc color follows completion exactly like `ui-progress-bar` (red up to 25%, amber up to 50%, blue up to 75%, green above 75%);
1981
+ * `variant` fixes it for a ring whose color means something else (e.g. one ring per metric). The ring is a `role="progressbar"`
1982
+ * (name it with `ariaLabel` or `ariaLabelledby`; `valueText` adds a human reading such as "$200K of $300K"). The arc animates unless
1983
+ * `prefers-reduced-motion` is set and stays visible in forced-colors mode.
1984
+ *
1985
+ * <ui-progress-ring [value]="67" ariaLabel="Gross income progress" variant="green" />
1986
+ * <ui-progress-ring [value]="done" [max]="total" [size]="72" [strokeWidth]="6" [label]="done + '/' + total" ariaLabel="Checklist" />
1987
+ */
1988
+ export declare class ProgressRingComponent {
1989
+ /** Completed amount. */
1990
+ readonly value: import("@angular/core").InputSignal<number>;
1991
+ /** Total amount (default 100, so `value` is a percentage); 0 renders an empty ring. */
1992
+ readonly max: import("@angular/core").InputSignal<number>;
1993
+ /** Diameter in px. */
1994
+ readonly size: import("@angular/core").InputSignal<number>;
1995
+ /** Ring thickness in px. */
1996
+ readonly strokeWidth: import("@angular/core").InputSignal<number>;
1997
+ /** Optional fixed arc color. Leave it out and the color follows completion (red / amber / blue / green). */
1998
+ readonly variant: import("@angular/core").InputSignal<ProgressRingVariant | null | undefined>;
1999
+ /** Text in the middle instead of the rounded percentage, e.g. "3/5". */
2000
+ readonly label: import("@angular/core").InputSignal<string>;
2001
+ /** `false` draws the ring without any text in the middle. */
2002
+ readonly showValue: import("@angular/core").InputSignal<boolean>;
2003
+ readonly ariaLabel: import("@angular/core").InputSignal<string>;
2004
+ /** Id of an element that names the ring (wins over `ariaLabel`). */
2005
+ readonly ariaLabelledby: import("@angular/core").InputSignal<string>;
2006
+ /** Human text for `aria-valuetext`, e.g. "$200K of $300K". Empty = not set. */
2007
+ readonly valueText: import("@angular/core").InputSignal<string>;
2008
+ /** `max` made safe: NaN / negative / infinite become 0 (empty ring, no division by zero). */
2009
+ protected readonly safeMax: import("@angular/core").Signal<number>;
2010
+ protected readonly clampedValue: import("@angular/core").Signal<number>;
2011
+ /** Exact completion in % (0–100). */
2012
+ private readonly exact;
2013
+ /** Rounded completion in %, shown in the middle. */
2014
+ protected readonly percent: import("@angular/core").Signal<number>;
2015
+ protected readonly center: import("@angular/core").Signal<number>;
2016
+ protected readonly radius: import("@angular/core").Signal<number>;
2017
+ protected readonly circumference: import("@angular/core").Signal<number>;
2018
+ protected readonly dashOffset: import("@angular/core").Signal<number>;
2019
+ /** The override when given, else the completion band: up to 25% red, up to 50% amber, up to 75% blue, above 75% green. */
2020
+ protected readonly effectiveVariant: import("@angular/core").Signal<ProgressRingVariant>;
2021
+ static ɵfac: i0.ɵɵFactoryDeclaration<ProgressRingComponent, never>;
2022
+ static ɵcmp: i0.ɵɵComponentDeclaration<ProgressRingComponent, "ui-progress-ring", never, {
2023
+ "value": {
2024
+ "alias": "value";
2025
+ "required": false;
2026
+ "isSignal": true;
2027
+ };
2028
+ "max": {
2029
+ "alias": "max";
2030
+ "required": false;
2031
+ "isSignal": true;
2032
+ };
2033
+ "size": {
2034
+ "alias": "size";
2035
+ "required": false;
2036
+ "isSignal": true;
2037
+ };
2038
+ "strokeWidth": {
2039
+ "alias": "strokeWidth";
2040
+ "required": false;
2041
+ "isSignal": true;
2042
+ };
2043
+ "variant": {
2044
+ "alias": "variant";
2045
+ "required": false;
2046
+ "isSignal": true;
2047
+ };
2048
+ "label": {
2049
+ "alias": "label";
2050
+ "required": false;
2051
+ "isSignal": true;
2052
+ };
2053
+ "showValue": {
2054
+ "alias": "showValue";
2055
+ "required": false;
2056
+ "isSignal": true;
2057
+ };
2058
+ "ariaLabel": {
2059
+ "alias": "ariaLabel";
2060
+ "required": false;
2061
+ "isSignal": true;
2062
+ };
2063
+ "ariaLabelledby": {
2064
+ "alias": "ariaLabelledby";
2065
+ "required": false;
2066
+ "isSignal": true;
2067
+ };
2068
+ "valueText": {
2069
+ "alias": "valueText";
2070
+ "required": false;
2071
+ "isSignal": true;
2072
+ };
2073
+ }, {}, never, never, true, never>;
2074
+ }
1974
2075
  /**
1975
2076
  * Audio player for a recording (a call, a voicemail, a message): the browser's own controls (play / pause, seek, time, volume,
1976
2077
  * keyboard and screen-reader support, the same in Chrome, Edge, Firefox and Safari) in the library's look, plus a readable message
@@ -6193,6 +6294,46 @@ export declare class TextareaInputComponent implements ControlValueAccessor, Val
6193
6294
  "invalidChange": "invalidChange";
6194
6295
  }, never, never, true, never>;
6195
6296
  }
6297
+ export type TextSize = 'sm' | 'md' | 'lg';
6298
+ export type TextTone = 'default' | 'muted';
6299
+ /**
6300
+ * Plain text that keeps its line breaks: a note, a message, an address, a pasted block. It is page content, not a form control —
6301
+ * no tab stop, no resize handle, selectable and copyable, and read normally by screen readers (including browse mode).
6302
+ *
6303
+ * <ui-text [text]="note.content" />
6304
+ * <ui-text [text]="request.message" size="sm" tone="muted" />
6305
+ *
6306
+ * Every line break and run of spaces in `text` is shown as written; long unbroken words and links wrap instead of
6307
+ * stretching the layout. The text is never interpreted as HTML. Pass the text through `[text]` (not as projected content),
6308
+ * so the template's own indentation can never leak into it. An empty or missing text renders nothing.
6309
+ *
6310
+ * Inputs: `text`, `size` (sm 0.8125rem | md 0.875rem | lg 1rem, default md), `tone` (default slate | muted grey).
6311
+ */
6312
+ export declare class TextComponent {
6313
+ /** The text to show. Line breaks are kept; it is never parsed as HTML. */
6314
+ readonly text: import("@angular/core").InputSignal<string | null | undefined>;
6315
+ readonly size: import("@angular/core").InputSignal<TextSize>;
6316
+ readonly tone: import("@angular/core").InputSignal<TextTone>;
6317
+ protected readonly fontSize: import("@angular/core").Signal<string>;
6318
+ static ɵfac: i0.ɵɵFactoryDeclaration<TextComponent, never>;
6319
+ static ɵcmp: i0.ɵɵComponentDeclaration<TextComponent, "ui-text", never, {
6320
+ "text": {
6321
+ "alias": "text";
6322
+ "required": false;
6323
+ "isSignal": true;
6324
+ };
6325
+ "size": {
6326
+ "alias": "size";
6327
+ "required": false;
6328
+ "isSignal": true;
6329
+ };
6330
+ "tone": {
6331
+ "alias": "tone";
6332
+ "required": false;
6333
+ "isSignal": true;
6334
+ };
6335
+ }, {}, never, never, true, never>;
6336
+ }
6196
6337
  /** Why a chosen file was refused. */
6197
6338
  /** 'type' = not an accepted type, 'size' = over `maxSize`, 'empty' = a 0-byte file (`rejectEmpty`), 'small' = under `minSize`. */
6198
6339
  export type FileRejectReason = 'type' | 'size' | 'empty' | 'small';
@@ -7129,20 +7270,31 @@ export declare class ListItemComponent {
7129
7270
  export declare function provideForgerouteToast(options?: {
7130
7271
  dismissible?: boolean;
7131
7272
  }): EnvironmentProviders;
7132
- /** Payload of `(reorder)`. `order[newIndex] = oldIndex`; apply it with `reorderItems(items, order)`. */
7133
- export interface ListReorderEvent {
7273
+ /** Payload of `(reorder)`. Apply it with `reorderItems(items, order)` or take the ready-made `items`. */
7274
+ export interface ListReorderEvent<T = unknown> {
7275
+ /** The row that was moved. */
7276
+ item: T;
7134
7277
  /** Index the moved row had before the move. */
7135
7278
  from: number;
7136
7279
  /** Index the moved row has after the move. */
7137
7280
  to: number;
7138
7281
  /** The new index order of the whole list: `order[newIndex] = oldIndex`. */
7139
7282
  order: number[];
7283
+ /** The new full order of the items (a new array; the input array is not changed). */
7284
+ items: T[];
7140
7285
  }
7141
- /** Context handed to the row template: `<ng-template let-item let-i="index" let-n="count">`. */
7286
+ /**
7287
+ * Context handed to the row template:
7288
+ * `<ng-template let-item let-i="index" let-n="count" let-first="first" let-last="last" let-dragging="dragging">`.
7289
+ */
7142
7290
  export interface ListRowContext<T = unknown> {
7143
7291
  $implicit: T;
7144
7292
  index: number;
7145
7293
  count: number;
7294
+ first: boolean;
7295
+ last: boolean;
7296
+ /** True while this row is being dragged. */
7297
+ dragging: boolean;
7146
7298
  }
7147
7299
  /** Returns a new array in the order given by a `ListReorderEvent.order` (the input array is not changed). */
7148
7300
  export declare function reorderItems<T>(items: readonly T[], order: readonly number[]): T[];
@@ -7151,22 +7303,26 @@ interface Row {
7151
7303
  key: unknown;
7152
7304
  index: number;
7153
7305
  label: string;
7154
- upLabel: string;
7155
- downLabel: string;
7306
+ earlierLabel: string;
7307
+ laterLabel: string;
7156
7308
  first: boolean;
7157
7309
  last: boolean;
7310
+ dragging: boolean;
7158
7311
  ctx: ListRowContext;
7159
7312
  }
7160
7313
  /**
7161
7314
  * Semantic list container. Renders a real `<ul>` (default) or `<ol>` (`[ordered]="true"`) whose children are real `<li>`
7162
- * elements, one per entry of `items`. The row template (the single `<ng-template>` child) renders what is inside each
7163
- * `<li>`, normally a `<ui-list-item>`. Screen readers announce "list, N items" and "item i of N" natively.
7315
+ * elements, one per entry of `items`. The single `<ng-template>` child renders what is inside each `<li>`, normally a
7316
+ * `<ui-list-item>`. Screen readers announce "list, N items" and "item i of N" natively. `layout="grid"` lays the same
7317
+ * `<ul>` out as a wrapping CSS grid (columns of at least `gridMin` px).
7164
7318
  *
7165
- * Optional reordering (`[reorderable]="true"`, off by default): Move up / Move down icon buttons at the row end,
7166
- * Alt+ArrowUp / Alt+ArrowDown from any focused element in the row, a polite live region and a `(reorder)` output.
7167
- * The host owns the data: the list never changes `items`; apply the event (`reorderItems`) and pass the new array.
7319
+ * Optional reordering (`[reorderable]="true"`, off by default): Move buttons, Alt+ArrowUp / Alt+ArrowDown from any
7320
+ * focused element in a row, drag and drop plus Shift+Arrow / Home / End on a focused row (default in the grid layout, see
7321
+ * `dragDrop`), a polite live region, and `(reorder)` / `(itemsChange)` outputs.
7322
+ * The host owns the data: the list never changes `items`. Either bind `[(items)]` (the list emits the new array) or
7323
+ * apply the event yourself (`reorderItems`) and pass the new array.
7168
7324
  *
7169
- * <ui-list ariaLabel="Documents" [items]="docs()" [reorderable]="true" (reorder)="docs.set(reorderItems(docs(), $event.order))">
7325
+ * <ui-list ariaLabel="Documents" [items]="docs()" [reorderable]="true" (reorder)="docs.set($event.items)">
7170
7326
  * <ng-template let-doc let-i="index">
7171
7327
  * <ui-list-item [interactive]="false" [bordered]="true" [title]="doc.title" [details]="[doc.fileName]" />
7172
7328
  * </ng-template>
@@ -7175,43 +7331,96 @@ interface Row {
7175
7331
  export declare class ListComponent<T = unknown> {
7176
7332
  private readonly host;
7177
7333
  private readonly injector;
7178
- /** The entries to render, one `<li>` each. The host owns this array; the list never changes it. */
7334
+ /**
7335
+ * The entries to render, one `<li>` each. The host owns this array; the list never changes it. Two-way binding
7336
+ * (`[(items)]`) works: the list emits `itemsChange` with the new array and the host stores it.
7337
+ */
7179
7338
  readonly items: import("@angular/core").InputSignal<readonly T[]>;
7180
- /** `false` (default) renders a `<ul>`; `true` renders an `<ol>` with native numbering. */
7339
+ /** `false` (default) renders a `<ul>`; `true` renders an `<ol>` with native numbering (no numbers in the grid layout). */
7181
7340
  readonly ordered: import("@angular/core").InputSignal<boolean>;
7182
- /** Shows Move up / Move down controls and enables Alt+ArrowUp / Alt+ArrowDown. Default `false`: no controls, no live region. */
7341
+ /** 'list' = one column; 'grid' = wrapping columns of at least `gridMin` px (still a real `<ul>`). */
7342
+ readonly layout: import("@angular/core").InputSignal<"list" | "grid">;
7343
+ /** Minimum column width in px of the grid layout. */
7344
+ readonly gridMin: import("@angular/core").InputSignal<number>;
7345
+ /**
7346
+ * Space between rows (list) or between rows and columns (grid): none | xs | sm | md | lg | xl (0/4/8/16/24/32px, the scale of
7347
+ * `ui-stack` / `ui-columns`) or any CSS length (`gap="20px"`). Not set, or not a token / length: 0 in a list, 12px in a grid.
7348
+ */
7349
+ readonly gap: import("@angular/core").InputSignal<string | undefined>;
7350
+ /** Turns reordering on. Default `false`: no controls, no live region, no drag, no keys. */
7183
7351
  readonly reorderable: import("@angular/core").InputSignal<boolean>;
7184
- /** Disables all move controls and the keyboard shortcut (the rows stay visible). */
7352
+ /** Disables all moves (buttons, keys, drag and drop); the rows stay visible. */
7185
7353
  readonly disabled: import("@angular/core").InputSignal<boolean>;
7354
+ /**
7355
+ * Move buttons on each row (needs `reorderable`). 'auto' (default) = shown in the list layout, hidden in the grid layout;
7356
+ * `true` / `false` force them.
7357
+ */
7358
+ readonly moveControls: import("@angular/core").InputSignal<boolean | "auto">;
7359
+ /**
7360
+ * Drag and drop plus focusable rows (Shift+Arrow / Home / End). 'auto' (default) = on in the grid layout, off in the list
7361
+ * layout (where the Move buttons are the way); `true` / `false` force it. Needs `reorderable`.
7362
+ */
7363
+ readonly dragDrop: import("@angular/core").InputSignal<boolean | "auto">;
7186
7364
  /** Accessible name of the list (`aria-label`). */
7187
7365
  readonly ariaLabel: import("@angular/core").InputSignal<string | undefined>;
7188
7366
  /** Id of the element naming the list (`aria-labelledby`). */
7189
7367
  readonly ariaLabelledby: import("@angular/core").InputSignal<string | undefined>;
7190
7368
  /**
7191
- * Row label used in "Move <label> up" and the live announcement. Default: the string itself, else the item's
7192
- * `title`, `label` or `name`, else "Item N".
7369
+ * Row label used in the button names, the row's accessible name and the live announcement. Default: the string itself,
7370
+ * else the item's `title`, `label` or `name`, else "Item N".
7193
7371
  */
7194
7372
  readonly itemLabelFn: import("@angular/core").InputSignal<(item: T, index: number) => string>;
7195
7373
  /** Stable identity per row (default: the item object itself) so reordering moves DOM instead of recreating it. */
7196
7374
  readonly trackBy: import("@angular/core").InputSignal<(item: T, index: number) => unknown>;
7197
- /** Fires when the user moves a row. The host applies it and passes the new `items`. */
7198
- readonly reorder: import("@angular/core").OutputEmitterRef<ListReorderEvent>;
7375
+ /**
7376
+ * Start of the up / earlier button name; the row label is appended ("Move earlier Image 3"). Default: "Move <label> up"
7377
+ * in the list layout, "Move earlier <label>" in the grid layout.
7378
+ */
7379
+ readonly moveEarlierLabel: import("@angular/core").InputSignal<string | undefined>;
7380
+ /** Start of the down / later button name ("Move later Image 3"). Default: "Move <label> down" (list), "Move later <label>" (grid). */
7381
+ readonly moveLaterLabel: import("@angular/core").InputSignal<string | undefined>;
7382
+ /** Screen-reader instruction for a focused draggable row (aria-describedby). */
7383
+ readonly helpText: import("@angular/core").InputSignal<string>;
7384
+ /** Announcement after a move; receives the row label, the new position (1-based) and the list size. */
7385
+ readonly moveAnnouncement: import("@angular/core").InputSignal<(label: string, position: number, total: number) => string>;
7386
+ /** Fires with the new array when the user moves a row (`[(items)]`). The list does not change `items` itself. */
7387
+ readonly itemsChange: import("@angular/core").OutputEmitterRef<T[]>;
7388
+ /** Fires when the user moves a row. The host applies it (or uses `[(items)]`) and passes the new `items`. */
7389
+ readonly reorder: import("@angular/core").OutputEmitterRef<ListReorderEvent<T>>;
7199
7390
  protected readonly rowTemplate: import("@angular/core").Signal<TemplateRef<any> | undefined>;
7391
+ protected readonly helpId: string;
7200
7392
  protected readonly announcement: import("@angular/core").WritableSignal<string>;
7201
7393
  protected readonly movedKey: import("@angular/core").WritableSignal<unknown>;
7394
+ protected readonly dragIndex: import("@angular/core").WritableSignal<number | null>;
7395
+ protected readonly overIndex: import("@angular/core").WritableSignal<number | null>;
7202
7396
  private pendingFocus;
7203
7397
  private announceSeq;
7204
7398
  /** Stable disambiguation tokens for repeated keys (duplicates in a primitive list), reused across recomputes. */
7205
7399
  private dupTokens;
7400
+ protected readonly isGrid: import("@angular/core").Signal<boolean>;
7401
+ private readonly canReorder;
7402
+ protected readonly showControls: import("@angular/core").Signal<boolean>;
7403
+ /** Rows are draggable, focusable and move with Shift+arrows. */
7404
+ protected readonly direct: import("@angular/core").Signal<boolean>;
7405
+ /** The `--ul-gap` custom property: the token / length, or the default of the layout when unset or invalid. */
7406
+ protected readonly gapCss: import("@angular/core").Signal<string>;
7206
7407
  protected readonly rows: import("@angular/core").Signal<Row[]>;
7207
- private canReorder;
7208
- /** The `<li>` (direct child of this list) that contains `el`, or null. */
7408
+ /** Index of the `<li>` (direct child of this list) that contains `el`, or -1. */
7209
7409
  private rowIndexOf;
7410
+ /**
7411
+ * Moves the row at `from` to position `to` (clamped) and emits `itemsChange` + `reorder`. No-op (returns false) when
7412
+ * reordering is off or disabled, `from` is out of range, or nothing would change. Does not touch focus.
7413
+ */
7414
+ move(from: number, to: number): boolean;
7210
7415
  protected onKeydown(e: KeyboardEvent): void;
7211
7416
  protected onClick(e: Event): void;
7212
7417
  protected onFocusOut(e: FocusEvent): void;
7213
- /** Emits the reorder, announces it and restores focus to the moved row's control once the host has re-rendered. */
7214
- private move;
7418
+ protected onDragStart(e: DragEvent): void;
7419
+ protected onDragOver(e: DragEvent): void;
7420
+ protected onDrop(e: DragEvent): void;
7421
+ protected onDragEnd(): void;
7422
+ /** Emits the move, announces it and (for key / button moves) restores focus once the host has re-rendered. */
7423
+ private apply;
7215
7424
  /** Identical text is not re-read by screen readers, so a repeat of the current message is cleared first and written after the next render. */
7216
7425
  private announce;
7217
7426
  private restoreFocus;
@@ -7227,6 +7436,21 @@ export declare class ListComponent<T = unknown> {
7227
7436
  "required": false;
7228
7437
  "isSignal": true;
7229
7438
  };
7439
+ "layout": {
7440
+ "alias": "layout";
7441
+ "required": false;
7442
+ "isSignal": true;
7443
+ };
7444
+ "gridMin": {
7445
+ "alias": "gridMin";
7446
+ "required": false;
7447
+ "isSignal": true;
7448
+ };
7449
+ "gap": {
7450
+ "alias": "gap";
7451
+ "required": false;
7452
+ "isSignal": true;
7453
+ };
7230
7454
  "reorderable": {
7231
7455
  "alias": "reorderable";
7232
7456
  "required": false;
@@ -7237,6 +7461,16 @@ export declare class ListComponent<T = unknown> {
7237
7461
  "required": false;
7238
7462
  "isSignal": true;
7239
7463
  };
7464
+ "moveControls": {
7465
+ "alias": "moveControls";
7466
+ "required": false;
7467
+ "isSignal": true;
7468
+ };
7469
+ "dragDrop": {
7470
+ "alias": "dragDrop";
7471
+ "required": false;
7472
+ "isSignal": true;
7473
+ };
7240
7474
  "ariaLabel": {
7241
7475
  "alias": "ariaLabel";
7242
7476
  "required": false;
@@ -7257,7 +7491,28 @@ export declare class ListComponent<T = unknown> {
7257
7491
  "required": false;
7258
7492
  "isSignal": true;
7259
7493
  };
7494
+ "moveEarlierLabel": {
7495
+ "alias": "moveEarlierLabel";
7496
+ "required": false;
7497
+ "isSignal": true;
7498
+ };
7499
+ "moveLaterLabel": {
7500
+ "alias": "moveLaterLabel";
7501
+ "required": false;
7502
+ "isSignal": true;
7503
+ };
7504
+ "helpText": {
7505
+ "alias": "helpText";
7506
+ "required": false;
7507
+ "isSignal": true;
7508
+ };
7509
+ "moveAnnouncement": {
7510
+ "alias": "moveAnnouncement";
7511
+ "required": false;
7512
+ "isSignal": true;
7513
+ };
7260
7514
  }, {
7515
+ "itemsChange": "itemsChange";
7261
7516
  "reorder": "reorder";
7262
7517
  }, ["rowTemplate"], ["[list-empty]"], true, never>;
7263
7518
  }
@@ -7542,7 +7797,7 @@ export declare class ChipGroupComponent {
7542
7797
  readonly spaceAbove: import("@angular/core").InputSignal<"none" | "sm" | "md">;
7543
7798
  /** Space below the chip group. */
7544
7799
  readonly spaceBelow: import("@angular/core").InputSignal<"none" | "sm" | "md">;
7545
- protected readonly _gap: import("@angular/core").Signal<"6px" | "8px" | "12px">;
7800
+ protected readonly _gap: import("@angular/core").Signal<"6px" | "12px" | "8px">;
7546
7801
  protected readonly _spaceAbove: import("@angular/core").Signal<"0" | "6px" | "12px">;
7547
7802
  protected readonly _spaceBelow: import("@angular/core").Signal<"0" | "6px" | "12px">;
7548
7803
  static ɵfac: i0.ɵɵFactoryDeclaration<ChipGroupComponent, never>;
@@ -7769,16 +8024,27 @@ export type AlertVariant = 'info' | 'success' | 'warning' | 'danger';
7769
8024
  /**
7770
8025
  * Inline status message (info / success / warning / danger) with an optional title,
7771
8026
  * optional dismiss button, and projected body content (text, links, a retry ui-button…).
8027
+ * `quiet` drops the live-region role (no announcement) and `compact` tightens it for list rows — both off by default.
7772
8028
  *
7773
8029
  * <ui-alert variant="warning">No recipients — this campaign will not be sent.</ui-alert>
7774
8030
  * <ui-alert variant="danger" title="Couldn't load recipients">
7775
8031
  * {{ error }} <ui-button variant="ghost" size="sm" (click)="retry()">Retry</ui-button>
7776
8032
  * </ui-alert>
8033
+ * <ui-alert variant="danger" [quiet]="true" [compact]="true">Row 4: Email is not valid.</ui-alert>
7777
8034
  */
7778
8035
  export declare class AlertComponent {
7779
8036
  readonly variant: import("@angular/core").InputSignal<AlertVariant>;
7780
8037
  readonly title: import("@angular/core").InputSignal<string>;
7781
8038
  readonly dismissible: import("@angular/core").InputSignal<boolean>;
8039
+ /**
8040
+ * Quiet: no live-region role, so a screen reader does NOT announce it when it appears. Use it for an alert that is already on
8041
+ * the page when the user gets there, or for each item of a long list of alerts (e.g. one per failed import row — 500 danger
8042
+ * alerts would be 500 announcements). The default (false) keeps `role="alert"` for danger and `role="status"` for the rest.
8043
+ * The text stays normal page content, so it is still read in browse mode.
8044
+ */
8045
+ readonly quiet: import("@angular/core").InputSignal<boolean>;
8046
+ /** Tighter padding and a slightly smaller font, for an alert that is one row of a list. */
8047
+ readonly compact: import("@angular/core").InputSignal<boolean>;
7782
8048
  readonly dismissed: import("@angular/core").OutputEmitterRef<void>;
7783
8049
  static ɵfac: i0.ɵɵFactoryDeclaration<AlertComponent, never>;
7784
8050
  static ɵcmp: i0.ɵɵComponentDeclaration<AlertComponent, "ui-alert", never, {
@@ -7797,6 +8063,16 @@ export declare class AlertComponent {
7797
8063
  "required": false;
7798
8064
  "isSignal": true;
7799
8065
  };
8066
+ "quiet": {
8067
+ "alias": "quiet";
8068
+ "required": false;
8069
+ "isSignal": true;
8070
+ };
8071
+ "compact": {
8072
+ "alias": "compact";
8073
+ "required": false;
8074
+ "isSignal": true;
8075
+ };
7800
8076
  }, {
7801
8077
  "dismissed": "dismissed";
7802
8078
  }, never, ["*"], true, never>;
@@ -7897,143 +8173,6 @@ export declare class IconComponent {
7897
8173
  "iconClick": "iconClick";
7898
8174
  }, never, never, true, never>;
7899
8175
  }
7900
- /** What an item template receives (`let-item let-i="index"`). */
7901
- export interface SortableItemContext<T> {
7902
- $implicit: T;
7903
- index: number;
7904
- first: boolean;
7905
- last: boolean;
7906
- /** True while this item is being dragged. */
7907
- dragging: boolean;
7908
- }
7909
- /** Marks the `<ng-template>` that renders one item: `<ng-template uiSortableItem let-item let-i="index"> … </ng-template>`. */
7910
- export declare class SortableItemDirective<T = unknown> {
7911
- readonly template: TemplateRef<SortableItemContext<T>>;
7912
- static ngTemplateContextGuard<T>(_dir: SortableItemDirective<T>, _ctx: unknown): _ctx is SortableItemContext<T>;
7913
- static ɵfac: i0.ɵɵFactoryDeclaration<SortableItemDirective<any>, never>;
7914
- static ɵdir: i0.ɵɵDirectiveDeclaration<SortableItemDirective<any>, "ng-template[uiSortableItem]", never, {}, {}, never, never, true, never>;
7915
- }
7916
- /** Emitted after the order changed (a drop, a keyboard move or a move button). */
7917
- export interface SortableOrderChange<T> {
7918
- item: T;
7919
- from: number;
7920
- to: number;
7921
- /** The new full order. */
7922
- items: T[];
7923
- }
7924
- /**
7925
- * A list (or wrapping grid) of items that can optionally be reordered. Reordering is OFF by default: with `sortable` false it only
7926
- * renders the items (nothing is draggable or focusable and no controls show), so it is safe to use as a plain list.
7927
- *
7928
- * <ui-sortable-list [(items)]="images" [sortable]="canReorder" layout="grid" ariaLabel="Product images"
7929
- * [itemLabel]="imageLabel" (orderChange)="saveOrder($event)">
7930
- * <ng-template uiSortableItem let-url let-i="index"> <ui-image-preview [src]="url" /> </ng-template>
7931
- * </ui-sortable-list>
7932
- *
7933
- * With `sortable` on, an item can be moved by
7934
- * - dragging it onto another item (mouse and any browser with native drag and drop; Firefox / Safari quirks are handled),
7935
- * - the keyboard: focus an item and press Shift + Arrow keys (Shift + Home / End = first / last),
7936
- * - the optional move buttons (`moveControls`), the touch- and pointer-friendly way (and the one that needs no gesture).
7937
- * Every change updates `items` (two-way `[(items)]`) and emits `orderChange`; the host saves it and can set `items` back if the
7938
- * save fails. A polite live region announces each move ("Image 3 moved to position 1 of 4").
7939
- */
7940
- export declare class SortableListComponent<T = unknown> {
7941
- /** The items in their current order (two-way: `[(items)]`). */
7942
- readonly items: import("@angular/core").ModelSignal<T[]>;
7943
- /** Reordering on/off. Default OFF: the list only renders its items. */
7944
- readonly sortable: import("@angular/core").InputSignal<boolean>;
7945
- /** 'list' = one column; 'grid' = wrapping columns of at least `gridMin` px. */
7946
- readonly layout: import("@angular/core").InputSignal<"list" | "grid">;
7947
- readonly gridMin: import("@angular/core").InputSignal<number>;
7948
- /** Accessible name of the list. */
7949
- readonly ariaLabel: import("@angular/core").InputSignal<string>;
7950
- /** Name of an item for assistive tech and tooltips ("Image 3"). */
7951
- readonly itemLabel: import("@angular/core").InputSignal<(item: T, index: number) => string>;
7952
- /** Show Move earlier / Move later buttons on each item (needs `sortable`) — the touch-friendly way to reorder. */
7953
- readonly moveControls: import("@angular/core").InputSignal<boolean>;
7954
- readonly moveEarlierLabel: import("@angular/core").InputSignal<string>;
7955
- readonly moveLaterLabel: import("@angular/core").InputSignal<string>;
7956
- /** Screen-reader instruction for a focused sortable item. */
7957
- readonly helpText: import("@angular/core").InputSignal<string>;
7958
- /** Announcement after a move; receives the item label, the new position (1-based) and the list size. */
7959
- readonly moveAnnouncement: import("@angular/core").InputSignal<(label: string, position: number, total: number) => string>;
7960
- /** The order changed. */
7961
- readonly orderChange: import("@angular/core").OutputEmitterRef<SortableOrderChange<T>>;
7962
- protected readonly itemTemplate: import("@angular/core").Signal<SortableItemDirective<any>>;
7963
- protected readonly _helpId: string;
7964
- protected readonly _dragIndex: import("@angular/core").WritableSignal<number | null>;
7965
- protected readonly _overIndex: import("@angular/core").WritableSignal<number | null>;
7966
- protected readonly _announcement: import("@angular/core").WritableSignal<string>;
7967
- protected readonly _count: import("@angular/core").Signal<number>;
7968
- /** Moves the item at `from` to position `to` (clamped). No-op when nothing changes or sorting is off. */
7969
- move(from: number, to: number): void;
7970
- protected onDragStart(event: DragEvent, index: number): void;
7971
- protected onDragOver(event: DragEvent, index: number): void;
7972
- protected onDrop(event: DragEvent, index: number): void;
7973
- protected onDragEnd(): void;
7974
- protected onKeydown(event: KeyboardEvent, index: number): void;
7975
- static ɵfac: i0.ɵɵFactoryDeclaration<SortableListComponent<any>, never>;
7976
- static ɵcmp: i0.ɵɵComponentDeclaration<SortableListComponent<any>, "ui-sortable-list", never, {
7977
- "items": {
7978
- "alias": "items";
7979
- "required": false;
7980
- "isSignal": true;
7981
- };
7982
- "sortable": {
7983
- "alias": "sortable";
7984
- "required": false;
7985
- "isSignal": true;
7986
- };
7987
- "layout": {
7988
- "alias": "layout";
7989
- "required": false;
7990
- "isSignal": true;
7991
- };
7992
- "gridMin": {
7993
- "alias": "gridMin";
7994
- "required": false;
7995
- "isSignal": true;
7996
- };
7997
- "ariaLabel": {
7998
- "alias": "ariaLabel";
7999
- "required": false;
8000
- "isSignal": true;
8001
- };
8002
- "itemLabel": {
8003
- "alias": "itemLabel";
8004
- "required": false;
8005
- "isSignal": true;
8006
- };
8007
- "moveControls": {
8008
- "alias": "moveControls";
8009
- "required": false;
8010
- "isSignal": true;
8011
- };
8012
- "moveEarlierLabel": {
8013
- "alias": "moveEarlierLabel";
8014
- "required": false;
8015
- "isSignal": true;
8016
- };
8017
- "moveLaterLabel": {
8018
- "alias": "moveLaterLabel";
8019
- "required": false;
8020
- "isSignal": true;
8021
- };
8022
- "helpText": {
8023
- "alias": "helpText";
8024
- "required": false;
8025
- "isSignal": true;
8026
- };
8027
- "moveAnnouncement": {
8028
- "alias": "moveAnnouncement";
8029
- "required": false;
8030
- "isSignal": true;
8031
- };
8032
- }, {
8033
- "items": "itemsChange";
8034
- "orderChange": "orderChange";
8035
- }, ["itemTemplate"], never, true, never>;
8036
- }
8037
8176
  export type ImagePreviewShape = 'circle' | 'rounded';
8038
8177
  export type ImagePreviewSize = 'sm' | 'md' | 'lg';
8039
8178
  export type ImagePreviewPlaceholder = 'person' | 'image';
@@ -8157,6 +8296,9 @@ export type KpiCardValueColor = 'default' | 'green' | 'blue';
8157
8296
  * role="button", focusable (tabindex 0, visible focus ring), and Enter / Space fire the host's (click). Give it an
8158
8297
  * accessible name with [attr.aria-label] when the label alone isn't enough (e.g. "Net Commission: $12.5K — show details").
8159
8298
  *
8299
+ * Optional ring: `[progress]="67"` (+ `progressMax`, `progressVariant`, `progressSize`) draws a ui-progress-ring beside the label; extra lines
8300
+ * (a pace badge, a projection…) go in an element with the `kpi-footer` attribute.
8301
+ *
8160
8302
  * <ui-kpi-card label="Deals Closed" [value]="'' + deals" subtitle="Year to Date" icon="check-circle" color="blue" />
8161
8303
  * <ui-kpi-card label="Net Commission" [value]="net" icon="dollar" color="green" [highlight]="true"
8162
8304
  * [clickable]="true" (click)="openDetails()" />
@@ -8173,6 +8315,20 @@ export declare class KpiCardComponent {
8173
8315
  readonly highlight: import("@angular/core").InputSignal<boolean>;
8174
8316
  readonly clickable: import("@angular/core").InputSignal<boolean>;
8175
8317
  readonly valueColor: import("@angular/core").InputSignal<KpiCardValueColor>;
8318
+ /** Completed amount shown as a `ui-progress-ring` beside the label. `null` (default) = no ring. */
8319
+ readonly progress: import("@angular/core").InputSignal<number | null>;
8320
+ /** Total for `progress` (default 100, so `progress` is a percentage). */
8321
+ readonly progressMax: import("@angular/core").InputSignal<number>;
8322
+ /** Ring diameter in px. */
8323
+ readonly progressSize: import("@angular/core").InputSignal<number>;
8324
+ readonly progressStrokeWidth: import("@angular/core").InputSignal<number>;
8325
+ /** Fixed ring color; leave it out and the color follows completion (red / amber / blue / green). */
8326
+ readonly progressVariant: import("@angular/core").InputSignal<ProgressRingVariant | null | undefined>;
8327
+ /** Accessible name of the ring; default "<label> progress". */
8328
+ readonly progressAriaLabel: import("@angular/core").InputSignal<string>;
8329
+ /** Human reading of the ring for assistive tech, e.g. "$200K of $300K". */
8330
+ readonly progressValueText: import("@angular/core").InputSignal<string>;
8331
+ protected readonly hasProgress: import("@angular/core").Signal<boolean>;
8176
8332
  /** Enter / Space on a clickable card act like a click (Space would otherwise scroll the page). */
8177
8333
  protected onActivateKey(event: Event): void;
8178
8334
  protected readonly iconSvg: import("@angular/core").Signal<SafeHtml | null>;
@@ -8218,7 +8374,42 @@ export declare class KpiCardComponent {
8218
8374
  "required": false;
8219
8375
  "isSignal": true;
8220
8376
  };
8221
- }, {}, never, never, true, never>;
8377
+ "progress": {
8378
+ "alias": "progress";
8379
+ "required": false;
8380
+ "isSignal": true;
8381
+ };
8382
+ "progressMax": {
8383
+ "alias": "progressMax";
8384
+ "required": false;
8385
+ "isSignal": true;
8386
+ };
8387
+ "progressSize": {
8388
+ "alias": "progressSize";
8389
+ "required": false;
8390
+ "isSignal": true;
8391
+ };
8392
+ "progressStrokeWidth": {
8393
+ "alias": "progressStrokeWidth";
8394
+ "required": false;
8395
+ "isSignal": true;
8396
+ };
8397
+ "progressVariant": {
8398
+ "alias": "progressVariant";
8399
+ "required": false;
8400
+ "isSignal": true;
8401
+ };
8402
+ "progressAriaLabel": {
8403
+ "alias": "progressAriaLabel";
8404
+ "required": false;
8405
+ "isSignal": true;
8406
+ };
8407
+ "progressValueText": {
8408
+ "alias": "progressValueText";
8409
+ "required": false;
8410
+ "isSignal": true;
8411
+ };
8412
+ }, {}, never, ["[kpi-footer]"], true, never>;
8222
8413
  }
8223
8414
  export type DatePreset = 'today' | '7days' | '30days' | 'month' | 'quarter' | 'ytd' | 'all' | 'custom';
8224
8415
  export interface DateRange {