@forgeroute/ui 0.4.47 → 0.4.49

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.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@forgeroute/ui",
3
- "version": "0.4.47",
3
+ "version": "0.4.49",
4
4
  "peerDependencies": {
5
5
  "@angular/common": ">=22.0.0",
6
6
  "@angular/core": ">=22.0.0",
@@ -1268,6 +1268,8 @@ export declare class ImportExportComponent {
1268
1268
  /** Unique prefix for the ids this window links with aria-describedby / aria-labelledby. */
1269
1269
  readonly uid: string;
1270
1270
  private readonly resultBox;
1271
+ /** The container of the step on screen (Source / Upload / Map Columns / Preview): focused when the step changes, because the control the user pressed is gone. */
1272
+ private readonly stepBox;
1271
1273
  private readonly http;
1272
1274
  /** API root from FORGEROUTE_CONFIG (e.g. a cross-origin prod API); falls back to same-origin `/api`. */
1273
1275
  private readonly apiBase;
@@ -1326,6 +1328,8 @@ export declare class ImportExportComponent {
1326
1328
  goToPreview(): void;
1327
1329
  get mappedFields(): ImportFieldDef[];
1328
1330
  get previewRows(): Record<string, string>[];
1331
+ /** Shows another step and moves focus to its container (the pressed button / focused file input was removed from the page). */
1332
+ goTo(step: ImportStep): void;
1329
1333
  /** Moves focus to the result summary (the button that had it is gone), so keyboard and screen reader users land on the outcome. */
1330
1334
  private focusResult;
1331
1335
  private stopImportTimer;
@@ -1573,6 +1577,13 @@ export declare class DataTableComponent<T extends Record<string, any>> implement
1573
1577
  */
1574
1578
  private _columnBadgeLabel;
1575
1579
  protected readonly _error: import("@angular/core").WritableSignal<string | null>;
1580
+ private readonly _loadFailed;
1581
+ /**
1582
+ * True from a failed load (the table shows its error state) until a later load SUCCEEDS. Unlike the error state itself it stays true while
1583
+ * Retry / a reload is in flight, so a host can keep its own controls (a date range card, say) out of the page for the whole time the
1584
+ * table is not showing real data. Read it through the table reference: `tableRef()?.loadFailed()`.
1585
+ */
1586
+ readonly loadFailed: Signal<boolean>;
1576
1587
  protected readonly _search: import("@angular/core").WritableSignal<string>;
1577
1588
  /** The search text as sent to the API: lower-cased, so every search is case-insensitive whatever the backend does. The input still shows what the user typed. */
1578
1589
  protected readonly _searchParam: Signal<string>;
@@ -2222,7 +2233,7 @@ export declare class ModalComponent implements OnInit, OnDestroy {
2222
2233
  readonly title: import("@angular/core").InputSignal<string>;
2223
2234
  readonly description: import("@angular/core").InputSignal<string>;
2224
2235
  readonly maxWidth: import("@angular/core").InputSignal<string>;
2225
- readonly bodyOverflow: import("@angular/core").InputSignal<"auto" | "hidden" | "visible">;
2236
+ readonly bodyOverflow: import("@angular/core").InputSignal<"hidden" | "auto" | "visible">;
2226
2237
  /** `data-testid` of the dialog element itself (the host `<ui-modal>` is always in the page, the dialog only while open). None when empty. */
2227
2238
  readonly dialogTestId: import("@angular/core").InputSignal<string>;
2228
2239
  /** Hides the header X button (e.g. while a request is running). Escape and a backdrop click still close unless `closable` is false. */
@@ -2606,7 +2617,7 @@ export declare class AudioPlayerComponent {
2606
2617
  /** Accessible name of the player. */
2607
2618
  readonly ariaLabel: import("@angular/core").InputSignal<string>;
2608
2619
  /** How much to load before play: 'metadata' (default), 'auto' or 'none'. */
2609
- readonly preload: import("@angular/core").InputSignal<"auto" | "none" | "metadata">;
2620
+ readonly preload: import("@angular/core").InputSignal<"none" | "metadata" | "auto">;
2610
2621
  /** Fires when the browser can't load or decode the source. */
2611
2622
  readonly playbackError: import("@angular/core").OutputEmitterRef<void>;
2612
2623
  protected readonly failed: import("@angular/core").WritableSignal<boolean>;
@@ -2860,7 +2871,7 @@ export declare class CheckboxComponent implements ControlValueAccessor, Validato
2860
2871
  * clicking it still toggles the box - e.g. a product name that is both the heading of its card and the label of its checkbox.
2861
2872
  * Default null: plain label text, exactly as before. Single mode only.
2862
2873
  */
2863
- readonly headingLevel: import("@angular/core").InputSignal<1 | 4 | 2 | 3 | 5 | 6 | null>;
2874
+ readonly headingLevel: import("@angular/core").InputSignal<1 | 2 | 5 | 3 | 6 | 4 | null>;
2864
2875
  readonly indeterminate: import("@angular/core").InputSignal<boolean>;
2865
2876
  readonly checked: import("@angular/core").ModelSignal<boolean>;
2866
2877
  /**
@@ -4076,6 +4087,10 @@ export interface ToggleBadgeAction {
4076
4087
  * Pill that toggles on / off. Optional `actions` put small icon buttons INSIDE the pill, after the label and a divider, each with its own
4077
4088
  * tooltip; the label button and the icon buttons are separate buttons (never nested). Clicking an icon button emits `(action)` with its id and
4078
4089
  * never `(toggle)`. Content projected into the component (an icon) goes before the label, as before.
4090
+ *
4091
+ * Accessibility: the label button is a toggle button, so it carries `aria-pressed` (true while `active`); on touch devices
4092
+ * (`pointer: coarse`) its hit area, and each icon button's, is 44px (an invisible overlay; it can reach into a neighbouring badge when the
4093
+ * host's gap between badges is smaller than the overlay, see docs/ui-timeline-and-small-additions.md).
4079
4094
  */
4080
4095
  export declare class ToggleBadgeComponent {
4081
4096
  readonly label: import("@angular/core").InputSignal<string>;
@@ -4141,6 +4156,8 @@ export declare class PillTabsComponent {
4141
4156
  /** Accessible name for the tab list (e.g. 'Reporting period'). Omit to leave it unnamed. */
4142
4157
  readonly ariaLabel: import("@angular/core").InputSignal<string | null>;
4143
4158
  readonly name: import("@angular/core").InputSignal<string>;
4159
+ /** Keep every pill at its own width on one line (default false: pills may shrink and wrap their text). On a phone the row scrolls sideways, as it always does. */
4160
+ readonly noWrap: import("@angular/core").InputSignal<boolean>;
4144
4161
  readonly tabChange: import("@angular/core").OutputEmitterRef<string>;
4145
4162
  /** True while pills are hidden past the start / end edge of the scroll area (drives the fade hints). */
4146
4163
  protected readonly canScrollStart: import("@angular/core").WritableSignal<boolean>;
@@ -4173,6 +4190,11 @@ export declare class PillTabsComponent {
4173
4190
  "required": false;
4174
4191
  "isSignal": true;
4175
4192
  };
4193
+ "noWrap": {
4194
+ "alias": "noWrap";
4195
+ "required": false;
4196
+ "isSignal": true;
4197
+ };
4176
4198
  }, {
4177
4199
  "tabChange": "tabChange";
4178
4200
  }, never, never, true, never>;
@@ -4363,7 +4385,7 @@ export declare class BulkMessagePanelComponent {
4363
4385
  readonly sending: import("@angular/core").InputSignal<boolean>;
4364
4386
  readonly closed: import("@angular/core").OutputEmitterRef<void>;
4365
4387
  readonly send: import("@angular/core").OutputEmitterRef<BulkMessageSendEvent>;
4366
- readonly channel: import("@angular/core").WritableSignal<"email" | "text">;
4388
+ readonly channel: import("@angular/core").WritableSignal<"text" | "email">;
4367
4389
  private readonly _subject;
4368
4390
  private readonly _body;
4369
4391
  get subject(): string;
@@ -4418,7 +4440,7 @@ export declare class ImportSourceGridComponent {
4418
4440
  /** The `value` of the picked source (highlighted). `tile` only: the `card` appearance does not keep a selection. */
4419
4441
  readonly selected: import("@angular/core").InputSignal<string>;
4420
4442
  /** `tile`: the compact buttons of the import window. `card`: one `ui-detail-card` per source with its own select button (used on a page). */
4421
- readonly appearance: import("@angular/core").InputSignal<"tile" | "card">;
4443
+ readonly appearance: import("@angular/core").InputSignal<"card" | "tile">;
4422
4444
  /** `card`: disables every card's button (for example while the page is saving). */
4423
4445
  readonly disabled: import("@angular/core").InputSignal<boolean>;
4424
4446
  /** `card`: the text of each card's button. */
@@ -4727,7 +4749,7 @@ export declare class TextInputComponent implements ControlValueAccessor, Validat
4727
4749
  readonly passwordRequirements: import("@angular/core").InputSignal<boolean>;
4728
4750
  /** Rules for `passwordRequirements`; default = the library's five rules (8+ characters, upper, lower, digit, special). */
4729
4751
  readonly passwordRules: import("@angular/core").InputSignal<readonly PasswordRule[] | undefined>;
4730
- readonly type: import("@angular/core").InputSignal<"number" | "email" | "text" | "password" | "tel" | "url">;
4752
+ readonly type: import("@angular/core").InputSignal<"number" | "text" | "email" | "tel" | "password" | "url">;
4731
4753
  readonly maxlength: import("@angular/core").InputSignal<number | undefined>;
4732
4754
  readonly required: import("@angular/core").InputSignal<boolean>;
4733
4755
  readonly autocomplete: import("@angular/core").InputSignal<string>;
@@ -4736,7 +4758,7 @@ export declare class TextInputComponent implements ControlValueAccessor, Validat
4736
4758
  * `search`, `text`, `none`). Empty (default) = the browser's default for the field, except `type="tel"`, which keeps `tel`.
4737
4759
  * It only picks the keyboard; it does not restrict what can be typed or pasted.
4738
4760
  */
4739
- readonly inputmode: import("@angular/core").InputSignal<"" | "email" | "search" | "none" | "text" | "tel" | "url" | "decimal" | "numeric">;
4761
+ readonly inputmode: import("@angular/core").InputSignal<"" | "none" | "text" | "search" | "email" | "tel" | "url" | "decimal" | "numeric">;
4740
4762
  readonly readonly: import("@angular/core").InputSignal<boolean>;
4741
4763
  readonly hint: import("@angular/core").InputSignal<string>;
4742
4764
  readonly error: import("@angular/core").InputSignal<string>;
@@ -4800,7 +4822,7 @@ export declare class TextInputComponent implements ControlValueAccessor, Validat
4800
4822
  protected readonly _stepAttr: import("@angular/core").Signal<string | null>;
4801
4823
  protected readonly _revealable: import("@angular/core").Signal<boolean>;
4802
4824
  protected readonly _shown: import("@angular/core").WritableSignal<boolean>;
4803
- protected readonly _inputType: import("@angular/core").Signal<"number" | "email" | "text" | "password" | "tel" | "url">;
4825
+ protected readonly _inputType: import("@angular/core").Signal<"number" | "text" | "email" | "tel" | "password" | "url">;
4804
4826
  protected readonly _eyePath: string;
4805
4827
  protected readonly _eyeOffPath: string;
4806
4828
  protected readonly _showRequirements: import("@angular/core").Signal<boolean>;
@@ -6158,8 +6180,13 @@ export declare class DropdownComponent {
6158
6180
  readonly loader: import("@angular/core").InputSignal<(() => Promise<DropdownItem[]>) | null>;
6159
6181
  readonly active: import("@angular/core").InputSignal<boolean>;
6160
6182
  readonly activeValue: import("@angular/core").InputSignal<string>;
6161
- readonly variant: import("@angular/core").InputSignal<"button" | "badge">;
6183
+ readonly variant: import("@angular/core").InputSignal<"badge" | "button">;
6162
6184
  readonly menuWidth: import("@angular/core").InputSignal<string>;
6185
+ /**
6186
+ * Fixed width of the trigger as a CSS length (e.g. `'280px'`). Empty (default) = the trigger is as wide as its label. When set, the trigger keeps that
6187
+ * width whatever label is selected (never wider than its container) and its label and chevron sit at the two ends.
6188
+ */
6189
+ readonly width: import("@angular/core").InputSignal<string>;
6163
6190
  /**
6164
6191
  * Accessible name. Set it when the trigger has no meaningful visible text. Applied as `aria-label` on the
6165
6192
  * trigger and on the menu; when empty (default) no `aria-label` is rendered, the trigger is named by its
@@ -6258,6 +6285,11 @@ export declare class DropdownComponent {
6258
6285
  "required": false;
6259
6286
  "isSignal": true;
6260
6287
  };
6288
+ "width": {
6289
+ "alias": "width";
6290
+ "required": false;
6291
+ "isSignal": true;
6292
+ };
6261
6293
  "ariaLabel": {
6262
6294
  "alias": "ariaLabel";
6263
6295
  "required": false;
@@ -6357,7 +6389,7 @@ export declare class FormSectionComponent {
6357
6389
  }, {}, never, ["*"], true, never>;
6358
6390
  }
6359
6391
  export declare class FormRowComponent {
6360
- readonly cols: import("@angular/core").InputSignal<1 | 4 | 2 | 3>;
6392
+ readonly cols: import("@angular/core").InputSignal<1 | 2 | 3 | 4>;
6361
6393
  static ɵfac: i0.ɵɵFactoryDeclaration<FormRowComponent, never>;
6362
6394
  static ɵcmp: i0.ɵɵComponentDeclaration<FormRowComponent, "ui-form-row", never, {
6363
6395
  "cols": {
@@ -7401,7 +7433,7 @@ export declare class ChipGroupComponent {
7401
7433
  readonly spaceAbove: import("@angular/core").InputSignal<"none" | "sm" | "md">;
7402
7434
  /** Space below the chip group. */
7403
7435
  readonly spaceBelow: import("@angular/core").InputSignal<"none" | "sm" | "md">;
7404
- protected readonly _gap: import("@angular/core").Signal<"8px" | "6px" | "12px">;
7436
+ protected readonly _gap: import("@angular/core").Signal<"6px" | "12px" | "8px">;
7405
7437
  protected readonly _spaceAbove: import("@angular/core").Signal<"0" | "6px" | "12px">;
7406
7438
  protected readonly _spaceBelow: import("@angular/core").Signal<"0" | "6px" | "12px">;
7407
7439
  static ɵfac: i0.ɵɵFactoryDeclaration<ChipGroupComponent, never>;
@@ -8492,7 +8524,7 @@ export interface DateRange {
8492
8524
  * Date range picker: preset pills (Today … Year to Date, optional All Time, Custom Range) plus
8493
8525
  * From / To date inputs with an Apply button for the custom range. With the presets shown, the custom range opens in a
8494
8526
  * popover card under the pills (right-aligned, closes on Apply / Escape / outside click; picking Custom Range again
8495
- * reopens it); with `showPresets` false the From / To row is rendered inline. Emits `rangeChange` with the
8527
+ * reopens it; a picker CREATED on `activePreset="custom"` starts with the popover closed and the Custom Range tab highlighted); with `showPresets` false the From / To row is rendered inline. Emits `rangeChange` with the
8496
8528
  * resolved ISO dates whenever a preset is picked or a custom range is applied.
8497
8529
  *
8498
8530
  * <ui-date-range-picker [activePreset]="preset()" [includeAllTime]="true" (rangeChange)="onRange($event)" />
@@ -8506,9 +8538,16 @@ export declare class DateRangePickerComponent {
8506
8538
  /** Accessible name of the preset tab list (screen readers announce it when the tabs get focus). */
8507
8539
  readonly ariaLabel: import("@angular/core").InputSignal<string>;
8508
8540
  readonly rangeChange: import("@angular/core").OutputEmitterRef<DateRange>;
8509
- /** Follows `activePreset` from the host, and the user's own picks in between. */
8541
+ /**
8542
+ * Follows `activePreset` from the host, and the user's own picks in between. A pick of Custom Range that is closed without Apply
8543
+ * (Escape / outside click) is discarded: the selection goes back to `activePreset`, the range the host actually applied.
8544
+ */
8510
8545
  protected readonly selectedPreset: import("@angular/core").WritableSignal<DatePreset>;
8511
- /** The popover was closed (Apply / Escape / outside click); any preset change reopens it. */
8546
+ /**
8547
+ * The popover was closed (Apply / Escape / outside click); any preset change reopens it. It starts CLOSED: a picker created with
8548
+ * `activePreset="custom"` (a host that re-creates it while a custom range is applied: a tab switched back to, a retry after an error)
8549
+ * shows that applied range as the highlighted tab, it does not open an empty From / To card. Clicking the tab reopens it.
8550
+ */
8512
8551
  private readonly popoverDismissed;
8513
8552
  protected readonly popoverVisible: import("@angular/core").Signal<boolean>;
8514
8553
  protected readonly popTop: import("@angular/core").WritableSignal<number>;
@@ -8521,6 +8560,13 @@ export declare class DateRangePickerComponent {
8521
8560
  private place;
8522
8561
  protected onDocumentClick(e: Event): void;
8523
8562
  protected onEscape(e: Event): void;
8563
+ /** Closes the custom popover without applying: nothing was applied, so the highlighted preset returns to the host's applied one. */
8564
+ private dismissWithoutApply;
8565
+ /**
8566
+ * The tab list only reports a CHANGE of tab, so a click on the Custom Range tab that is already selected (an applied custom range whose
8567
+ * popover was closed) reopens the popover here.
8568
+ */
8569
+ protected onPillsClick(e: Event): void;
8524
8570
  selectPreset(key: DatePreset): void;
8525
8571
  applyCustom(): void;
8526
8572
  static ɵfac: i0.ɵɵFactoryDeclaration<DateRangePickerComponent, never>;
@@ -9315,7 +9361,7 @@ export declare class DetailCardComponent {
9315
9361
  /** true (default) = the title is displayed in capitals (CSS only); false = shown as written. The text, aria-label and heading name are never changed. */
9316
9362
  readonly uppercaseTitle: import("@angular/core").InputSignal<boolean>;
9317
9363
  /** 1-6 makes the title a real heading for screen readers (role=heading, aria-level); null keeps it plain text. */
9318
- readonly headingLevel: import("@angular/core").InputSignal<1 | 4 | 2 | 3 | 5 | 6 | null>;
9364
+ readonly headingLevel: import("@angular/core").InputSignal<1 | 2 | 5 | 3 | 6 | 4 | null>;
9319
9365
  /** Optional id for the title text; the card is then labelled by it. Without it the title is the card's aria-label. */
9320
9366
  readonly titleId: import("@angular/core").InputSignal<string>;
9321
9367
  /** Accessible name of the card when the header gives none (no header, or no title). A visible title wins; blank = no name. */
@@ -10232,6 +10278,12 @@ export type ColumnsAlign = 'start' | 'center' | 'stretch';
10232
10278
  * - `collapseAt`: sm (480px) | md (768px) | lg (1024px) | never. Below that viewport width the columns become one.
10233
10279
  * Plain media queries are used (not container queries) because they behave the same in every supported browser.
10234
10280
  * - `align`: start | center | stretch (default start) - how cells of different heights line up.
10281
+ * - `spanLastOdd` (default false): in a 2-column grid, a last cell that would sit alone in its row spans the whole row instead of
10282
+ * leaving an empty half (3 cells -> 2 + 1 full-width; 1 cell -> full width). Only for a grid that has 1 or 2 columns at EVERY width:
10283
+ * `count` 2 and every `countBelow*` tier (after its fallback to the next wider tier) 1 or 2, collapsing included. With a 3 or 4 column tier
10284
+ * at any width, or in `countFrom*` mode, the span is not applied at all (an inline span would break that width's grid). It is applied to the
10285
+ * last VISIBLE element child (a `hidden` / `display: none` cell is skipped), and a last cell that already has its own inline `grid-column`
10286
+ * is left alone. It is re-applied when cells come and go and when a direct child's `hidden`, `style` or `class` attribute changes.
10235
10287
  * - Responsive tiers (optional): `countBelowLg` (viewport <= 1024px), `countBelowMd` (<= 768px) and `countBelowSm` (<= 480px)
10236
10288
  * give a different column count (1-4) at narrower widths. Each tier falls back to the next wider one, then to `count`, so
10237
10289
  * a grid that sets none of them is unchanged. `collapseAt` is applied last: a width at or below it is one column.
@@ -10250,6 +10302,8 @@ export declare class ColumnsComponent {
10250
10302
  readonly gap: import("@angular/core").InputSignal<string>;
10251
10303
  readonly collapseAt: import("@angular/core").InputSignal<ColumnsCollapse>;
10252
10304
  readonly align: import("@angular/core").InputSignal<ColumnsAlign>;
10305
+ /** 2-column grids: an odd last cell spans the full row instead of leaving an empty half. Default false. */
10306
+ readonly spanLastOdd: import("@angular/core").InputSignal<boolean>;
10253
10307
  /** Column count at viewport widths <= 1024px (falls back to `count`). */
10254
10308
  readonly countBelowLg: import("@angular/core").InputSignal<ColumnsCount | null>;
10255
10309
  /** Column count at <= 768px (falls back to `countBelowLg`, then `count`). */
@@ -10276,8 +10330,21 @@ export declare class ColumnsComponent {
10276
10330
  protected readonly fromSm: import("@angular/core").Signal<ColumnsCount | null>;
10277
10331
  protected readonly fromMd: import("@angular/core").Signal<ColumnsCount | null>;
10278
10332
  protected readonly fromLg: import("@angular/core").Signal<ColumnsCount | null>;
10333
+ /** The column count at each width after the tier fallbacks: base (> 1024px), <= 1024, <= 768, <= 480. */
10334
+ private readonly effectiveCols;
10335
+ /** spanLastOdd only when the grid has 2 columns on wide screens and never more than 2 at any width (and is not in countFrom* mode). */
10336
+ protected readonly spanFits: import("@angular/core").Signal<boolean>;
10279
10337
  protected readonly gapCss: import("@angular/core").Signal<string>;
10280
10338
  protected readonly collapseClass: import("@angular/core").Signal<string>;
10339
+ private readonly grid;
10340
+ private readonly destroyRef;
10341
+ private static readonly SPAN_MARK;
10342
+ constructor();
10343
+ /**
10344
+ * Marks the last VISIBLE element child (when it would be alone in its row) with `grid-column: 1 / -1`, and clears a mark left on any other child.
10345
+ * A cell the consumer gave its own inline `grid-column` is never marked or cleared.
10346
+ */
10347
+ private applySpan;
10281
10348
  static ɵfac: i0.ɵɵFactoryDeclaration<ColumnsComponent, never>;
10282
10349
  static ɵcmp: i0.ɵɵComponentDeclaration<ColumnsComponent, "ui-columns", never, {
10283
10350
  "count": {
@@ -10300,6 +10367,11 @@ export declare class ColumnsComponent {
10300
10367
  "required": false;
10301
10368
  "isSignal": true;
10302
10369
  };
10370
+ "spanLastOdd": {
10371
+ "alias": "spanLastOdd";
10372
+ "required": false;
10373
+ "isSignal": true;
10374
+ };
10303
10375
  "countBelowLg": {
10304
10376
  "alias": "countBelowLg";
10305
10377
  "required": false;