@forgeroute/ui 0.3.1 → 0.3.2

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.3.1",
3
+ "version": "0.3.2",
4
4
  "peerDependencies": {
5
5
  "@angular/common": ">=22.0.0",
6
6
  "@angular/core": ">=22.0.0",
@@ -135,19 +135,14 @@ export interface ColumnDef {
135
135
  overdueThreshold?: number;
136
136
  /**
137
137
  * Maps a row to a progress bar. Return null to render a plain '—' (e.g. nothing to track).
138
- * `label` is the text beside the bar (e.g. "3/5"); `tooltip` is the hover text.
138
+ * `label` is the text beside the bar (e.g. "3/5"); `tooltip` is the hover text. Leave `variant` out and the bar colors itself by completion (red / amber / blue / green).
139
139
  */
140
140
  progressFn?: (item: any) => {
141
141
  value: number;
142
142
  max: number;
143
143
  label?: string;
144
- variant?: 'blue' | 'green' | 'amber' | 'red' | 'slate' | 'lime';
144
+ variant?: 'blue' | 'green' | 'amber' | 'red' | 'slate';
145
145
  tooltip?: string;
146
- autoColor?: boolean;
147
- thresholds?: {
148
- at: number;
149
- variant: 'blue' | 'green' | 'amber' | 'red' | 'slate' | 'lime';
150
- }[];
151
146
  } | null;
152
147
  /** Key in item holding the tags array. Defaults to col.key.
153
148
  * Expected shape: { name: string; variant?: BadgeVariant }[] */
@@ -279,14 +274,17 @@ export interface BulkConfirmContext<T = any> {
279
274
  /** Raw target value ("APPROVED") and its display label ("Approved"). */
280
275
  targetValue: string;
281
276
  targetLabel: string;
282
- /** The eligible row objects (name records, show before -> after). Only rows on the loaded page are available. */
277
+ /**
278
+ * The eligible row objects (name records, show before -> after). A selection never spans pages (any reload clears it and
279
+ * select-all takes the loaded page), so these are every row that will be sent.
280
+ */
283
281
  rows: T[];
284
282
  /** The selected rows that will be skipped. */
285
283
  skippedRows: T[];
286
284
  }
287
285
  /** Host copy for one bulk confirm. Plain text only (never HTML); `\n` in `message` shows as a line break. */
288
286
  export interface BulkConfirmCopy {
289
- /** Default: the action label ("Change Status") / "Delete Selected". */
287
+ /** Default: the action label ("Change Status") / "Delete <Items>" built from the table's item label ("template" → "Delete Templates"). */
290
288
  title?: string;
291
289
  message: string;
292
290
  /** Rendered as a bullet list under the message (consequences, what is NOT affected, undoable or not). */
@@ -1086,6 +1084,8 @@ export declare class DataTableComponent<T extends Record<string, any>> implement
1086
1084
  /** Plural label; defaults to English pluralisation of `itemLabel` ("property" → "properties"). */
1087
1085
  readonly itemLabelPlural: import("@angular/core").InputSignal<string>;
1088
1086
  protected _countLabel(count: number): string;
1087
+ /** Default bulk-Delete confirm title: "Delete " + the title-cased plural item label ("template" → "Delete Templates", "lien waiver" → "Delete Lien Waivers"). */
1088
+ protected _deleteTitle(): string;
1089
1089
  /**
1090
1090
  * Column keys to enable bulk updates for, plus the special keyword `'delete'`.
1091
1091
  * e.g. `['status', 'type', 'delete']`
@@ -1764,17 +1764,14 @@ export declare class ToastComponent {
1764
1764
  static ɵfac: i0.ɵɵFactoryDeclaration<ToastComponent, never>;
1765
1765
  static ɵcmp: i0.ɵɵComponentDeclaration<ToastComponent, "ui-toast", never, {}, {}, never, never, true, never>;
1766
1766
  }
1767
- export type ProgressBarVariant = 'blue' | 'green' | 'amber' | 'red' | 'slate' | 'lime';
1768
- /** Switch the fill to `variant` once completion reaches `at` percent (0-100). */
1769
- export interface ProgressThreshold {
1770
- at: number;
1771
- variant: ProgressBarVariant;
1772
- }
1773
- /** Standard completion colors: red under 25%, amber 25%, blue 50%, lime 75%, green at 100%. */
1774
- export declare const PROGRESS_STEP_THRESHOLDS: ProgressThreshold[];
1767
+ export type ProgressBarVariant = 'blue' | 'green' | 'amber' | 'red' | 'slate';
1775
1768
  /**
1776
1769
  * Horizontal progress bar with an optional trailing label (e.g. "3/5").
1777
1770
  * Pass `value` and `max`; the fill width is clamped to 0–100%.
1771
+ *
1772
+ * The fill color is built in and follows completion, in four bands: red up to 25%, amber up to 50%, blue up to 75%,
1773
+ * green above 75% (full = green). Nothing needs to be passed. `variant` is an optional override for a bar whose
1774
+ * color means something else (for example an overdue status) — when it is set the color stays fixed.
1778
1775
  */
1779
1776
  export declare class ProgressBarComponent {
1780
1777
  /** Completed amount. */
@@ -1783,21 +1780,14 @@ export declare class ProgressBarComponent {
1783
1780
  readonly max: import("@angular/core").InputSignal<number>;
1784
1781
  /** Text shown to the right of the bar, e.g. "3/5". */
1785
1782
  readonly label: import("@angular/core").InputSignal<string>;
1786
- /** Fixed color; with `autoColor` it is the color below the first step (use `red`). */
1787
- readonly variant: import("@angular/core").InputSignal<ProgressBarVariant>;
1788
- /**
1789
- * Optional automatic color: the fill uses the variant of the highest threshold whose `at` is
1790
- * <= the exact completion percent (not the rounded one), else `variant`.
1791
- * e.g. `[{ at: 50, variant: 'amber' }, { at: 100, variant: 'green' }]`. Omit to keep `variant` fixed.
1792
- */
1793
- readonly thresholds: import("@angular/core").InputSignal<ProgressThreshold[] | null>;
1794
- /** Shortcut for the standard steps (`PROGRESS_STEP_THRESHOLDS`): red <25%, amber 25%, blue 50%, lime 75%, green 100%. Explicit `thresholds` win. */
1795
- readonly autoColor: import("@angular/core").InputSignal<boolean>;
1783
+ /** Optional fixed color override. Leave it out and the color follows completion (red / amber / blue / green). */
1784
+ readonly variant: import("@angular/core").InputSignal<ProgressBarVariant | null | undefined>;
1796
1785
  /** Hover / focus tooltip (library `uiTooltip`); `\n` starts a new line. */
1797
1786
  readonly tooltip: import("@angular/core").InputSignal<string>;
1798
1787
  readonly ariaLabel: import("@angular/core").InputSignal<string>;
1799
1788
  protected readonly clampedValue: import("@angular/core").Signal<number>;
1800
1789
  protected readonly percent: import("@angular/core").Signal<number>;
1790
+ /** The override when given, else the completion band: up to 25% red, up to 50% amber, up to 75% blue, above 75% green. */
1801
1791
  protected readonly effectiveVariant: import("@angular/core").Signal<ProgressBarVariant>;
1802
1792
  static ɵfac: i0.ɵɵFactoryDeclaration<ProgressBarComponent, never>;
1803
1793
  static ɵcmp: i0.ɵɵComponentDeclaration<ProgressBarComponent, "ui-progress-bar", never, {
@@ -1821,16 +1811,6 @@ export declare class ProgressBarComponent {
1821
1811
  "required": false;
1822
1812
  "isSignal": true;
1823
1813
  };
1824
- "thresholds": {
1825
- "alias": "thresholds";
1826
- "required": false;
1827
- "isSignal": true;
1828
- };
1829
- "autoColor": {
1830
- "alias": "autoColor";
1831
- "required": false;
1832
- "isSignal": true;
1833
- };
1834
1814
  "tooltip": {
1835
1815
  "alias": "tooltip";
1836
1816
  "required": false;
@@ -2087,6 +2067,8 @@ export declare class ButtonComponent {
2087
2067
  readonly ariaLabel: import("@angular/core").InputSignal<string | undefined>;
2088
2068
  readonly ariaExpanded: import("@angular/core").InputSignal<boolean | undefined>;
2089
2069
  readonly ariaPressed: import("@angular/core").InputSignal<boolean | undefined>;
2070
+ /** Id of the element that describes this button (an error or hint rendered next to it), e.g. `<ui-error errorId="x">`. Absent when empty. */
2071
+ readonly ariaDescribedBy: import("@angular/core").InputSignal<string | undefined>;
2090
2072
  _footerLeft?: string;
2091
2073
  _footerRight?: string;
2092
2074
  static ɵfac: i0.ɵɵFactoryDeclaration<ButtonComponent, never>;
@@ -2146,6 +2128,11 @@ export declare class ButtonComponent {
2146
2128
  "required": false;
2147
2129
  "isSignal": true;
2148
2130
  };
2131
+ "ariaDescribedBy": {
2132
+ "alias": "ariaDescribedBy";
2133
+ "required": false;
2134
+ "isSignal": true;
2135
+ };
2149
2136
  "_footerLeft": {
2150
2137
  "alias": "modal-footer-left";
2151
2138
  "required": false;
@@ -5936,6 +5923,133 @@ export declare class RadioGroupComponent implements ControlValueAccessor, Valida
5936
5923
  "invalidChange": "invalidChange";
5937
5924
  }, never, never, true, never>;
5938
5925
  }
5926
+ /** One row of a `ui-radio-matrix`: `value` is the key in the model, `label` the row header. */
5927
+ export interface RadioMatrixRow {
5928
+ value: string;
5929
+ label: string;
5930
+ disabled?: boolean;
5931
+ }
5932
+ /**
5933
+ * Matrix of native radio buttons: one row per item, one column per choice, exactly one choice per row (e.g. a page-permission
5934
+ * grid: rows = pages, columns = Full Access / Read Only / Hidden). A ControlValueAccessor whose value is a record
5935
+ * `{ [row.value]: column.value }` (`''` / missing = nothing chosen for that row). Arrow keys move inside a row natively because the
5936
+ * radios of a row share one `name`. Every radio is named "<row>: <column>" for screen readers; rows are `<th scope="row">`, columns
5937
+ * `<th scope="col">`.
5938
+ *
5939
+ * Built-in validation: `required` -> every row needs a choice ("Choose an option in every row." / "<label>: choose an option in
5940
+ * every row."); a value that is not one of the `columns` -> "Select a valid option."; a key that is not one of the `rows` is
5941
+ * ignored (and kept untouched in the model). Disabled matrices are never invalid.
5942
+ *
5943
+ * Validity API (same on every ui input): Angular `Validator`, signals `invalid` + `errorMessage`, `invalidChange` output,
5944
+ * provides `UiFieldValidity`. Messages show after the matrix lost focus or while `[showErrors]="true"`; a host `[error]` wins.
5945
+ *
5946
+ * <ui-radio-matrix label="Page permissions" rowHeader="Page" [rows]="pages" [columns]="levels" [(ngModel)]="permissions" />
5947
+ */
5948
+ export declare class RadioMatrixComponent implements ControlValueAccessor, Validator, UiFieldValidity {
5949
+ readonly label: import("@angular/core").InputSignal<string>;
5950
+ /** Text of the top-left header cell (what the rows are, e.g. "Page"). */
5951
+ readonly rowHeader: import("@angular/core").InputSignal<string>;
5952
+ readonly rows: import("@angular/core").InputSignal<RadioMatrixRow[]>;
5953
+ /** The choices, one column each (same shape as `ui-radio-group` options; `description` is not shown). */
5954
+ readonly columns: import("@angular/core").InputSignal<RadioOption[]>;
5955
+ readonly required: import("@angular/core").InputSignal<boolean>;
5956
+ readonly hint: import("@angular/core").InputSignal<string>;
5957
+ readonly error: import("@angular/core").InputSignal<string>;
5958
+ /** Reveal the built-in error messages now (e.g. after a failed Save click), without waiting for blur. */
5959
+ readonly showErrors: import("@angular/core").InputSignal<boolean>;
5960
+ /** Prefix of the native radio `name`s (one name per row); a unique one is generated when omitted. */
5961
+ readonly name: import("@angular/core").InputSignal<string>;
5962
+ protected readonly _disabledInput: import("@angular/core").InputSignal<boolean>;
5963
+ private readonly _cvaDisabled;
5964
+ protected readonly disabled: import("@angular/core").Signal<boolean>;
5965
+ private readonly _generatedName;
5966
+ protected get _name(): string;
5967
+ protected readonly _descId: string;
5968
+ protected readonly _value: import("@angular/core").WritableSignal<Record<string, string>>;
5969
+ private readonly _reveal;
5970
+ private readonly _issue;
5971
+ /** True while the value breaks a built-in rule or the host passed an `[error]`. */
5972
+ readonly invalid: import("@angular/core").Signal<boolean>;
5973
+ /** Message of the first broken built-in rule ('' when valid), shown or not. */
5974
+ readonly errorMessage: import("@angular/core").Signal<string>;
5975
+ /** Emits whenever the field becomes invalid / valid. */
5976
+ readonly invalidChange: import("@angular/core").OutputEmitterRef<boolean>;
5977
+ protected readonly _activeError: import("@angular/core").Signal<string>;
5978
+ private _onValidatorChange;
5979
+ constructor();
5980
+ /** Re-run the form control's validation when a rule input (required, rows, columns) changes. */
5981
+ ngOnChanges(): void;
5982
+ validate(control: AbstractControl): ValidationErrors | null;
5983
+ registerOnValidatorChange(fn: () => void): void;
5984
+ private _onChange;
5985
+ private _onTouched;
5986
+ writeValue(val: Record<string, string> | null): void;
5987
+ registerOnChange(fn: (v: Record<string, string>) => void): void;
5988
+ registerOnTouched(fn: () => void): void;
5989
+ setDisabledState(d: boolean): void;
5990
+ protected onSelect(row: string, column: string): void;
5991
+ /** True when a required matrix has no valid choice in this row (shown on the row header and the dots). */
5992
+ protected _rowInvalid(row: RadioMatrixRow): boolean;
5993
+ /** Touched once focus leaves the whole matrix (moving between its radios does not count). */
5994
+ protected onFocusOut(event: FocusEvent): void;
5995
+ private _toRecord;
5996
+ private _check;
5997
+ static ɵfac: i0.ɵɵFactoryDeclaration<RadioMatrixComponent, never>;
5998
+ static ɵcmp: i0.ɵɵComponentDeclaration<RadioMatrixComponent, "ui-radio-matrix", never, {
5999
+ "label": {
6000
+ "alias": "label";
6001
+ "required": false;
6002
+ "isSignal": true;
6003
+ };
6004
+ "rowHeader": {
6005
+ "alias": "rowHeader";
6006
+ "required": false;
6007
+ "isSignal": true;
6008
+ };
6009
+ "rows": {
6010
+ "alias": "rows";
6011
+ "required": false;
6012
+ "isSignal": true;
6013
+ };
6014
+ "columns": {
6015
+ "alias": "columns";
6016
+ "required": false;
6017
+ "isSignal": true;
6018
+ };
6019
+ "required": {
6020
+ "alias": "required";
6021
+ "required": false;
6022
+ "isSignal": true;
6023
+ };
6024
+ "hint": {
6025
+ "alias": "hint";
6026
+ "required": false;
6027
+ "isSignal": true;
6028
+ };
6029
+ "error": {
6030
+ "alias": "error";
6031
+ "required": false;
6032
+ "isSignal": true;
6033
+ };
6034
+ "showErrors": {
6035
+ "alias": "showErrors";
6036
+ "required": false;
6037
+ "isSignal": true;
6038
+ };
6039
+ "name": {
6040
+ "alias": "name";
6041
+ "required": false;
6042
+ "isSignal": true;
6043
+ };
6044
+ "_disabledInput": {
6045
+ "alias": "disabled";
6046
+ "required": false;
6047
+ "isSignal": true;
6048
+ };
6049
+ }, {
6050
+ "invalidChange": "invalidChange";
6051
+ }, never, never, true, never>;
6052
+ }
5939
6053
  /**
5940
6054
  * Card for detail pages: an optional header and a body, both filled by the page that uses it.
5941
6055
  *