@forgeroute/ui 0.3.0 → 0.3.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.
- package/fesm2022/forgeroute-ui.mjs +2236 -221
- package/fesm2022/forgeroute-ui.mjs.map +1 -1
- package/package.json +1 -1
- package/types/forgeroute-ui.d.ts +651 -15
package/types/forgeroute-ui.d.ts
CHANGED
|
@@ -45,7 +45,8 @@ export interface ToolbarAction {
|
|
|
45
45
|
badge?: number;
|
|
46
46
|
/** Hide this action entirely */
|
|
47
47
|
hidden?: boolean;
|
|
48
|
-
/**
|
|
48
|
+
/** Documentation of intent: marks a mutating action ("Add …", bulk mutations). It does not change behavior - the table hides
|
|
49
|
+
* EVERY page-defined toolbar action for any `permission` other than 'full', with or without this flag. */
|
|
49
50
|
requiresFull?: boolean;
|
|
50
51
|
/**
|
|
51
52
|
* Keep this action when the table is empty and unfiltered. By default only `variant: 'primary'` buttons survive that
|
|
@@ -87,9 +88,13 @@ export interface RowAction {
|
|
|
87
88
|
opens?: 'modal' | 'panel';
|
|
88
89
|
/** Required when opens === 'modal'. Drives the confirm dialog shown by the table. */
|
|
89
90
|
modal?: ConfirmConfig;
|
|
90
|
-
/**
|
|
91
|
-
*
|
|
91
|
+
/** Documentation of intent: marks a mutating action (edit, delete, ...). It does not change behavior - for any `permission`
|
|
92
|
+
* other than 'full' the table offers only View and actions marked `allowReadOnly`, with or without this flag.
|
|
93
|
+
* The built-in `type: 'delete'` action is never offered to read-only users. */
|
|
92
94
|
requiresFull?: boolean;
|
|
95
|
+
/** Keep this action for read-only users too (download, preview: reads that change nothing). Without it a read-only table offers only
|
|
96
|
+
* View. Never applies to the built-in delete, and the table still drops the Actions column when no row has any visible action. */
|
|
97
|
+
allowReadOnly?: boolean;
|
|
93
98
|
}
|
|
94
99
|
/** Page-level permission passed to `<ui-data-table [permission]>`. Anything other than 'full' is read-only
|
|
95
100
|
* (apps use values like 'read-only' / 'hidden'). */
|
|
@@ -105,6 +110,9 @@ export interface ColumnDef {
|
|
|
105
110
|
/** Values a bulk "Change <label>" may set. When omitted the options come from /filter-counts.
|
|
106
111
|
* Use it when only some values are user-settable or when a valid value may currently have no rows. */
|
|
107
112
|
bulkOptions?: string[];
|
|
113
|
+
/** Fixed column width (any CSS length, e.g. '140px'). Applied as width, min-width and max-width; cell text longer than
|
|
114
|
+
* it is cut with an ellipsis. Omit for an automatic width. Not applied to the Actions column's cell clipping. */
|
|
115
|
+
width?: string;
|
|
108
116
|
align?: 'left' | 'right' | 'center';
|
|
109
117
|
headerAlign?: 'left' | 'right' | 'center';
|
|
110
118
|
/** How to render cell content. Defaults to 'text'. */
|
|
@@ -133,14 +141,24 @@ export interface ColumnDef {
|
|
|
133
141
|
value: number;
|
|
134
142
|
max: number;
|
|
135
143
|
label?: string;
|
|
136
|
-
variant?: 'blue' | 'green' | 'amber' | 'red' | 'slate';
|
|
144
|
+
variant?: 'blue' | 'green' | 'amber' | 'red' | 'slate' | 'lime';
|
|
137
145
|
tooltip?: string;
|
|
146
|
+
autoColor?: boolean;
|
|
147
|
+
thresholds?: {
|
|
148
|
+
at: number;
|
|
149
|
+
variant: 'blue' | 'green' | 'amber' | 'red' | 'slate' | 'lime';
|
|
150
|
+
}[];
|
|
138
151
|
} | null;
|
|
139
152
|
/** Key in item holding the tags array. Defaults to col.key.
|
|
140
153
|
* Expected shape: { name: string; variant?: BadgeVariant }[] */
|
|
141
154
|
tagsKey?: string;
|
|
142
155
|
/** Returns the image URL for the row. A falsy value (null / undefined / '') shows the placeholder icon. */
|
|
143
156
|
imageFn?: (item: any) => string | null | undefined;
|
|
157
|
+
/** Focal point (percent, 50/50 = centered) of the cropped image, applied as CSS object-position. */
|
|
158
|
+
imagePositionFn?: (item: any) => {
|
|
159
|
+
x: number | null | undefined;
|
|
160
|
+
y: number | null | undefined;
|
|
161
|
+
} | null | undefined;
|
|
144
162
|
/** Alt text for the row's image. When omitted the image is decorative (`alt=""`). */
|
|
145
163
|
imageAlt?: (item: any) => string;
|
|
146
164
|
/** 'circle' (default) or 'rounded' (3:2 rounded rectangle). */
|
|
@@ -231,6 +249,17 @@ export type BulkUpdateOption<T = any> = string | {
|
|
|
231
249
|
* { field: 'delete', deletable: (row: Invoice) => row.status === 'DRAFT' }
|
|
232
250
|
*/
|
|
233
251
|
deletable?: (row: T) => boolean;
|
|
252
|
+
/**
|
|
253
|
+
* Field changes (`{ field, canChange }`): true when the server will accept moving THIS row to `target` (a value the select offers).
|
|
254
|
+
* For rules the field values alone can't express, e.g. a draft can only be sent when it has a document and a recipient. Keep it
|
|
255
|
+
* identical to the backend rule. Rows it refuses are skipped like rows `allowedFrom` refuses ("N selected rows can't be changed to X
|
|
256
|
+
* and will be skipped." / `ctx.skippedBlocked` + `ctx.skippedRows` for host `confirm` copy), are never sent, and a target is offered
|
|
257
|
+
* only while some selected row can move to it. It runs after `allowedFrom` and only sees rows on the loaded page. Omit it and
|
|
258
|
+
* nothing changes.
|
|
259
|
+
*
|
|
260
|
+
* { field: 'status', allowedFrom: { SENT: ['DRAFT'] }, canChange: (row, target) => target !== 'SENT' || canSend(row) }
|
|
261
|
+
*/
|
|
262
|
+
canChange?: (row: T, target: string) => boolean;
|
|
234
263
|
};
|
|
235
264
|
/** What a bulk confirm function receives. For bulk Delete: `targetValue`/`targetLabel` are '', `columnLabel` is 'Delete', skipped counts are 0. */
|
|
236
265
|
export interface BulkConfirmContext<T = any> {
|
|
@@ -285,6 +314,8 @@ export interface BulkActionDef {
|
|
|
285
314
|
confirm?: BulkConfirmFn | Record<string, BulkConfirmFn>;
|
|
286
315
|
/** Bulk Delete only: which rows the server will delete (from `{ field: 'delete', deletable }`). */
|
|
287
316
|
deletable?: (row: any) => boolean;
|
|
317
|
+
/** Field changes: per-row check that the server will accept the move to a target (from `{ field, canChange }`). */
|
|
318
|
+
canChange?: (row: any, target: string) => boolean;
|
|
288
319
|
/**
|
|
289
320
|
* The item field this action targets (e.g. 'status', 'type').
|
|
290
321
|
* When set the table shows an inline select populated from the column's option sources.
|
|
@@ -767,7 +798,7 @@ export declare function createFieldReveal(showErrors: Signal<boolean>): {
|
|
|
767
798
|
revealed: Signal<boolean>;
|
|
768
799
|
};
|
|
769
800
|
/** Splits `YYYY-MM-DD` (optionally followed by `Thh:mm[:ss]`) and rejects impossible dates (2026-02-31) and times (25:00). */
|
|
770
|
-
export declare function parseIso(value: string, withTime: boolean): {
|
|
801
|
+
export declare function parseIso(value: string | null | undefined, withTime: boolean): {
|
|
771
802
|
y: number;
|
|
772
803
|
mo: number;
|
|
773
804
|
d: number;
|
|
@@ -775,9 +806,9 @@ export declare function parseIso(value: string, withTime: boolean): {
|
|
|
775
806
|
mi: number;
|
|
776
807
|
} | null;
|
|
777
808
|
/** "Oct 20, 2026" from an ISO date (never shifted by the time zone). */
|
|
778
|
-
export declare function formatIsoDate(value: string): string;
|
|
809
|
+
export declare function formatIsoDate(value: string | null | undefined): string;
|
|
779
810
|
/** "Oct 20, 2026, 3:30 PM" from an ISO local date-time. */
|
|
780
|
-
export declare function formatIsoDateTime(value: string): string;
|
|
811
|
+
export declare function formatIsoDateTime(value: string | null | undefined): string;
|
|
781
812
|
/** Sortable key `YYYYMMDDHHmm` of a parsed ISO value. */
|
|
782
813
|
export declare function isoKey(p: {
|
|
783
814
|
y: number;
|
|
@@ -786,6 +817,10 @@ export declare function isoKey(p: {
|
|
|
786
817
|
h: number;
|
|
787
818
|
mi: number;
|
|
788
819
|
}): number;
|
|
820
|
+
/** Parses `HH:mm` (optionally `HH:mm:ss`) into minutes since midnight; null for anything else (25:00, 9:5, 09:30:99, text, null/undefined). */
|
|
821
|
+
export declare function parseTime(value: string | null | undefined): number | null;
|
|
822
|
+
/** "9:00 AM" / "12:30 PM" from an `HH:mm` value (returned unchanged when it cannot be parsed; '' for null/undefined/non-strings). */
|
|
823
|
+
export declare function formatTime(value: string | null | undefined): string;
|
|
789
824
|
export interface SelectOption {
|
|
790
825
|
value: string;
|
|
791
826
|
label: string;
|
|
@@ -1135,6 +1170,8 @@ export declare class DataTableComponent<T extends Record<string, any>> implement
|
|
|
1135
1170
|
private _columnBadgeLabel;
|
|
1136
1171
|
protected readonly _error: import("@angular/core").WritableSignal<string | null>;
|
|
1137
1172
|
protected readonly _search: import("@angular/core").WritableSignal<string>;
|
|
1173
|
+
/** 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. */
|
|
1174
|
+
protected readonly _searchParam: Signal<string>;
|
|
1138
1175
|
protected readonly _page: import("@angular/core").WritableSignal<number>;
|
|
1139
1176
|
protected readonly _sortField: import("@angular/core").WritableSignal<string | null>;
|
|
1140
1177
|
protected readonly _sortDir: import("@angular/core").WritableSignal<SortDir>;
|
|
@@ -1147,6 +1184,8 @@ export declare class DataTableComponent<T extends Record<string, any>> implement
|
|
|
1147
1184
|
protected readonly _effectiveSavedViews: Signal<SavedView[]>;
|
|
1148
1185
|
/** Empty = show all defaultVisible; non-empty = show exactly these keys */
|
|
1149
1186
|
protected readonly _visibleColumns: import("@angular/core").WritableSignal<string[]>;
|
|
1187
|
+
/** Drops the key of every `cellType: 'actions'` column — Actions is never part of a configured/saved column list. */
|
|
1188
|
+
protected _configurableKeys(keys: string[] | null | undefined): string[];
|
|
1150
1189
|
protected readonly _ieRef: Signal<ImportExportComponent | undefined>;
|
|
1151
1190
|
/** Tag overflow tooltip — fixed position to escape table's overflow:auto */
|
|
1152
1191
|
protected readonly _tagTooltip: import("@angular/core").WritableSignal<{
|
|
@@ -1233,12 +1272,19 @@ export declare class DataTableComponent<T extends Record<string, any>> implement
|
|
|
1233
1272
|
* through the column's own `nameFn` / `render` so it reads exactly like the cell. '' when there is none.
|
|
1234
1273
|
*/
|
|
1235
1274
|
protected rowName(item: T): string;
|
|
1236
|
-
/**
|
|
1275
|
+
/**
|
|
1276
|
+
* Rows of the loaded page whose name repeats get a position suffix (" (1 of 2)", " (2 of 2)"), so a screen-reader user never hears two rows
|
|
1277
|
+
* announced identically ("Select Jane Cooper" twice). Names that are unique on the page — and rows with no name — are left exactly as they are.
|
|
1278
|
+
*/
|
|
1279
|
+
private readonly _rowNameSuffix;
|
|
1280
|
+
/** A row's accessible name: its name, plus the position among rows of the same name when that name repeats on the page. */
|
|
1281
|
+
private rowAccessibleName;
|
|
1282
|
+
/** "Select Acme Electric" — a row's selection checkbox name ("Select Acme Electric (2 of 3)" when the name repeats on the page). */
|
|
1237
1283
|
protected selectRowLabel(item: T): string;
|
|
1238
1284
|
/**
|
|
1239
1285
|
* "Row actions for Acme Electric" — a row's actions-menu trigger name. It still contains the generic "Row actions"
|
|
1240
1286
|
* text, so lookups by that accessible name (substring) keep finding the button, while a screen-reader user now
|
|
1241
|
-
* hears which row it belongs to.
|
|
1287
|
+
* hears which row it belongs to ("Row actions for Acme Electric (2 of 3)" when the name repeats on the page).
|
|
1242
1288
|
*/
|
|
1243
1289
|
protected rowActionsLabel(item: T): string;
|
|
1244
1290
|
protected toggleSelectAll(): void;
|
|
@@ -1355,7 +1401,8 @@ export declare class DataTableComponent<T extends Record<string, any>> implement
|
|
|
1355
1401
|
protected onRowKeydown(e: KeyboardEvent, item: T): void;
|
|
1356
1402
|
protected onInternalButtonClick(type: string): void;
|
|
1357
1403
|
protected onImported(): void;
|
|
1358
|
-
/** Row actions visible for the current permission: everything for 'full'
|
|
1404
|
+
/** Row actions visible for the current permission: everything for 'full'; otherwise only View (`type: 'view'`) and actions marked
|
|
1405
|
+
* `allowReadOnly` (never the built-in delete). The Actions column itself is shown only while some row has a visible action. */
|
|
1359
1406
|
protected _rowActions(col: ColumnDef, item: T): RowAction[];
|
|
1360
1407
|
protected onTableRowAction(type: string, col: ColumnDef, item: T): Promise<void>;
|
|
1361
1408
|
private isNumericCol;
|
|
@@ -1367,6 +1414,8 @@ export declare class DataTableComponent<T extends Record<string, any>> implement
|
|
|
1367
1414
|
protected imageUrl(col: ColumnDef, item: T): string | null;
|
|
1368
1415
|
/** Always a string so the <img> keeps an `alt` attribute ('' = decorative). */
|
|
1369
1416
|
protected imageAlt(col: ColumnDef, item: T): string;
|
|
1417
|
+
/** CSS object-position from `imagePositionFn` (percent); centered when there is none or it throws. */
|
|
1418
|
+
protected imagePosition(col: ColumnDef, item: T): string;
|
|
1370
1419
|
protected imageClass(col: ColumnDef, small: boolean): string;
|
|
1371
1420
|
protected onImageError(url: string): void;
|
|
1372
1421
|
protected phoneCell(value: any): string;
|
|
@@ -1525,6 +1574,27 @@ export declare class DataTableComponent<T extends Record<string, any>> implement
|
|
|
1525
1574
|
"rowDeleted": "rowDeleted";
|
|
1526
1575
|
}, never, never, true, never>;
|
|
1527
1576
|
}
|
|
1577
|
+
/**
|
|
1578
|
+
* Column-filter values travel as ONE comma-joined request parameter (`?section=Roofing,Siding`). A value that itself contains a comma
|
|
1579
|
+
* ("Roofing, Inc.") would be read as two. These helpers keep the wire format backward compatible and make such values unambiguous:
|
|
1580
|
+
*
|
|
1581
|
+
* - a value is sent AS IS unless joining it would be ambiguous: it contains a comma, a doubled backslash, or ends with a backslash;
|
|
1582
|
+
* - such a value is escaped: `\` becomes `\\` and `,` becomes `\,`;
|
|
1583
|
+
* - the reader splits on commas that are not escaped and unescapes `\,` and `\\`; any other backslash is an ordinary character.
|
|
1584
|
+
*
|
|
1585
|
+
* So every value that worked before (no comma, no doubled / trailing backslash) is byte-for-byte unchanged, and a backend that does not know the
|
|
1586
|
+
* escaping keeps working for them. Backends that parse filter values should split with the same rules (`splitFilterList` in the contractor
|
|
1587
|
+
* backend, `decodeFilterValues` here).
|
|
1588
|
+
*/
|
|
1589
|
+
/** One value as it is written into the comma-joined parameter. */
|
|
1590
|
+
export declare function encodeFilterValue(value: string): string;
|
|
1591
|
+
/** The comma-joined parameter for a list of filter values (`['Roofing, Inc.', 'Siding']` -> `Roofing\, Inc.,Siding`). */
|
|
1592
|
+
export declare function encodeFilterValues(values: readonly string[]): string;
|
|
1593
|
+
/**
|
|
1594
|
+
* The values of a comma-joined parameter, the inverse of {@link encodeFilterValues}: split on unescaped commas, unescape `\,` and `\\`,
|
|
1595
|
+
* trim each value and drop the empty ones (the same as the plain split it replaces).
|
|
1596
|
+
*/
|
|
1597
|
+
export declare function decodeFilterValues(raw: string): string[];
|
|
1528
1598
|
export declare class SidePanelComponent implements OnDestroy {
|
|
1529
1599
|
readonly open: import("@angular/core").InputSignal<boolean>;
|
|
1530
1600
|
readonly title: import("@angular/core").InputSignal<string>;
|
|
@@ -1694,7 +1764,14 @@ export declare class ToastComponent {
|
|
|
1694
1764
|
static ɵfac: i0.ɵɵFactoryDeclaration<ToastComponent, never>;
|
|
1695
1765
|
static ɵcmp: i0.ɵɵComponentDeclaration<ToastComponent, "ui-toast", never, {}, {}, never, never, true, never>;
|
|
1696
1766
|
}
|
|
1697
|
-
export type ProgressBarVariant = 'blue' | 'green' | 'amber' | 'red' | 'slate';
|
|
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[];
|
|
1698
1775
|
/**
|
|
1699
1776
|
* Horizontal progress bar with an optional trailing label (e.g. "3/5").
|
|
1700
1777
|
* Pass `value` and `max`; the fill width is clamped to 0–100%.
|
|
@@ -1706,12 +1783,22 @@ export declare class ProgressBarComponent {
|
|
|
1706
1783
|
readonly max: import("@angular/core").InputSignal<number>;
|
|
1707
1784
|
/** Text shown to the right of the bar, e.g. "3/5". */
|
|
1708
1785
|
readonly label: import("@angular/core").InputSignal<string>;
|
|
1786
|
+
/** Fixed color; with `autoColor` it is the color below the first step (use `red`). */
|
|
1709
1787
|
readonly variant: import("@angular/core").InputSignal<ProgressBarVariant>;
|
|
1710
|
-
/**
|
|
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>;
|
|
1796
|
+
/** Hover / focus tooltip (library `uiTooltip`); `\n` starts a new line. */
|
|
1711
1797
|
readonly tooltip: import("@angular/core").InputSignal<string>;
|
|
1712
1798
|
readonly ariaLabel: import("@angular/core").InputSignal<string>;
|
|
1713
1799
|
protected readonly clampedValue: import("@angular/core").Signal<number>;
|
|
1714
1800
|
protected readonly percent: import("@angular/core").Signal<number>;
|
|
1801
|
+
protected readonly effectiveVariant: import("@angular/core").Signal<ProgressBarVariant>;
|
|
1715
1802
|
static ɵfac: i0.ɵɵFactoryDeclaration<ProgressBarComponent, never>;
|
|
1716
1803
|
static ɵcmp: i0.ɵɵComponentDeclaration<ProgressBarComponent, "ui-progress-bar", never, {
|
|
1717
1804
|
"value": {
|
|
@@ -1734,6 +1821,16 @@ export declare class ProgressBarComponent {
|
|
|
1734
1821
|
"required": false;
|
|
1735
1822
|
"isSignal": true;
|
|
1736
1823
|
};
|
|
1824
|
+
"thresholds": {
|
|
1825
|
+
"alias": "thresholds";
|
|
1826
|
+
"required": false;
|
|
1827
|
+
"isSignal": true;
|
|
1828
|
+
};
|
|
1829
|
+
"autoColor": {
|
|
1830
|
+
"alias": "autoColor";
|
|
1831
|
+
"required": false;
|
|
1832
|
+
"isSignal": true;
|
|
1833
|
+
};
|
|
1737
1834
|
"tooltip": {
|
|
1738
1835
|
"alias": "tooltip";
|
|
1739
1836
|
"required": false;
|
|
@@ -1775,12 +1872,141 @@ export declare class SkeletonComponent {
|
|
|
1775
1872
|
};
|
|
1776
1873
|
}, {}, never, never, true, never>;
|
|
1777
1874
|
}
|
|
1778
|
-
|
|
1875
|
+
/**
|
|
1876
|
+
* Hover / focus tooltip for any element: `<span uiTooltip="Saved">`.
|
|
1877
|
+
* Empty text shows nothing. Line breaks (`\n`) are kept. Escape or leaving the element closes it.
|
|
1878
|
+
* The bubble is rendered on `document.body` (position: fixed) so table/panel overflow never clips it.
|
|
1879
|
+
*/
|
|
1880
|
+
export declare class TooltipDirective {
|
|
1881
|
+
/** Tooltip text; empty or null disables the tooltip. */
|
|
1882
|
+
readonly uiTooltip: import("@angular/core").InputSignal<string | null | undefined>;
|
|
1883
|
+
/** Preferred side; flips to the other side when there is no room. */
|
|
1884
|
+
readonly tooltipPosition: import("@angular/core").InputSignal<"top" | "bottom">;
|
|
1885
|
+
private readonly host;
|
|
1886
|
+
private readonly doc;
|
|
1887
|
+
private bubble;
|
|
1888
|
+
private readonly id;
|
|
1889
|
+
constructor();
|
|
1890
|
+
protected show(): void;
|
|
1891
|
+
protected hide(): void;
|
|
1892
|
+
static ɵfac: i0.ɵɵFactoryDeclaration<TooltipDirective, never>;
|
|
1893
|
+
static ɵdir: i0.ɵɵDirectiveDeclaration<TooltipDirective, "[uiTooltip]", never, {
|
|
1894
|
+
"uiTooltip": {
|
|
1895
|
+
"alias": "uiTooltip";
|
|
1896
|
+
"required": false;
|
|
1897
|
+
"isSignal": true;
|
|
1898
|
+
};
|
|
1899
|
+
"tooltipPosition": {
|
|
1900
|
+
"alias": "tooltipPosition";
|
|
1901
|
+
"required": false;
|
|
1902
|
+
"isSignal": true;
|
|
1903
|
+
};
|
|
1904
|
+
}, {}, never, never, true, never>;
|
|
1905
|
+
}
|
|
1906
|
+
export type ImageRepositionShape = 'circle' | 'rounded';
|
|
1907
|
+
/**
|
|
1908
|
+
* Drag-to-center photo frame. The image fills the frame (`object-fit: cover`) and the user drags it, or uses the arrow
|
|
1909
|
+
* keys, to choose which part stays visible. The result is a focal point in percent (`x`, `y`, 0-100, 50/50 = centered)
|
|
1910
|
+
* to apply as CSS `object-position` wherever the image is shown (`ui-image-preview` / the data table image cell take it).
|
|
1911
|
+
*
|
|
1912
|
+
* <ui-image-reposition [src]="url" [(x)]="posX" [(y)]="posY" label="Photo position" />
|
|
1913
|
+
*
|
|
1914
|
+
* Only the axis that overflows the frame can move (a landscape photo moves sideways, a portrait one up and down).
|
|
1915
|
+
* Arrow keys nudge by 2% (Shift: 10%). The frame is a labelled group with a hint for assistive tech.
|
|
1916
|
+
*/
|
|
1917
|
+
export declare class ImageRepositionComponent {
|
|
1918
|
+
private static nextId;
|
|
1919
|
+
protected readonly hintId: string;
|
|
1920
|
+
private readonly host;
|
|
1921
|
+
/** Image URL (or data URL). Without one the frame is empty and cannot be moved. */
|
|
1922
|
+
readonly src: import("@angular/core").InputSignal<string | null | undefined>;
|
|
1923
|
+
readonly alt: import("@angular/core").InputSignal<string>;
|
|
1924
|
+
readonly shape: import("@angular/core").InputSignal<ImageRepositionShape>;
|
|
1925
|
+
/** Accessible name of the frame. */
|
|
1926
|
+
readonly label: import("@angular/core").InputSignal<string>;
|
|
1927
|
+
/** Focal point, percent from the left (0-100). Two-way: `[(x)]`. */
|
|
1928
|
+
readonly x: import("@angular/core").ModelSignal<number>;
|
|
1929
|
+
/** Focal point, percent from the top (0-100). Two-way: `[(y)]`. */
|
|
1930
|
+
readonly y: import("@angular/core").ModelSignal<number>;
|
|
1931
|
+
protected readonly dragging: import("@angular/core").WritableSignal<boolean>;
|
|
1932
|
+
private natural;
|
|
1933
|
+
private start;
|
|
1934
|
+
protected onLoad(e: Event): void;
|
|
1935
|
+
/** How many px the cover-scaled image overflows the frame on each axis (0 = that axis cannot move). */
|
|
1936
|
+
private overflow;
|
|
1937
|
+
protected onPointerDown(e: PointerEvent): void;
|
|
1938
|
+
protected onPointerMove(e: PointerEvent): void;
|
|
1939
|
+
protected endDrag(e: PointerEvent): void;
|
|
1940
|
+
protected onKeydown(e: KeyboardEvent): void;
|
|
1941
|
+
static ɵfac: i0.ɵɵFactoryDeclaration<ImageRepositionComponent, never>;
|
|
1942
|
+
static ɵcmp: i0.ɵɵComponentDeclaration<ImageRepositionComponent, "ui-image-reposition", never, {
|
|
1943
|
+
"src": {
|
|
1944
|
+
"alias": "src";
|
|
1945
|
+
"required": false;
|
|
1946
|
+
"isSignal": true;
|
|
1947
|
+
};
|
|
1948
|
+
"alt": {
|
|
1949
|
+
"alias": "alt";
|
|
1950
|
+
"required": false;
|
|
1951
|
+
"isSignal": true;
|
|
1952
|
+
};
|
|
1953
|
+
"shape": {
|
|
1954
|
+
"alias": "shape";
|
|
1955
|
+
"required": false;
|
|
1956
|
+
"isSignal": true;
|
|
1957
|
+
};
|
|
1958
|
+
"label": {
|
|
1959
|
+
"alias": "label";
|
|
1960
|
+
"required": false;
|
|
1961
|
+
"isSignal": true;
|
|
1962
|
+
};
|
|
1963
|
+
"x": {
|
|
1964
|
+
"alias": "x";
|
|
1965
|
+
"required": false;
|
|
1966
|
+
"isSignal": true;
|
|
1967
|
+
};
|
|
1968
|
+
"y": {
|
|
1969
|
+
"alias": "y";
|
|
1970
|
+
"required": false;
|
|
1971
|
+
"isSignal": true;
|
|
1972
|
+
};
|
|
1973
|
+
}, {
|
|
1974
|
+
"x": "xChange";
|
|
1975
|
+
"y": "yChange";
|
|
1976
|
+
}, never, never, true, never>;
|
|
1977
|
+
}
|
|
1978
|
+
export declare class CheckboxComponent implements ControlValueAccessor, Validator, UiFieldValidity {
|
|
1779
1979
|
readonly label: import("@angular/core").InputSignal<string>;
|
|
1780
1980
|
/** Accessible name for the native checkbox when there is no visible `label` (e.g. a table row's selector). */
|
|
1781
1981
|
readonly ariaLabel: import("@angular/core").InputSignal<string>;
|
|
1782
1982
|
readonly indeterminate: import("@angular/core").InputSignal<boolean>;
|
|
1783
1983
|
readonly checked: import("@angular/core").ModelSignal<boolean>;
|
|
1984
|
+
/** The box must be ticked. */
|
|
1985
|
+
readonly required: import("@angular/core").InputSignal<boolean>;
|
|
1986
|
+
/** Replaces the built-in "<label> is required." message. */
|
|
1987
|
+
readonly requiredMessage: import("@angular/core").InputSignal<string>;
|
|
1988
|
+
readonly hint: import("@angular/core").InputSignal<string>;
|
|
1989
|
+
/** Host-provided error message (wins over the built-in one). */
|
|
1990
|
+
readonly error: import("@angular/core").InputSignal<string>;
|
|
1991
|
+
/** Reveal the built-in error message now (e.g. after a failed Save click), without waiting for a toggle. */
|
|
1992
|
+
readonly showErrors: import("@angular/core").InputSignal<boolean>;
|
|
1993
|
+
protected readonly _descId: string;
|
|
1994
|
+
private readonly _reveal;
|
|
1995
|
+
private readonly _issue;
|
|
1996
|
+
/** True while a required box is unticked or the host passed an `[error]`. */
|
|
1997
|
+
readonly invalid: import("@angular/core").Signal<boolean>;
|
|
1998
|
+
/** Message of the broken built-in rule ('' when valid), shown or not. */
|
|
1999
|
+
readonly errorMessage: import("@angular/core").Signal<string>;
|
|
2000
|
+
/** Emits whenever the field becomes invalid / valid. */
|
|
2001
|
+
readonly invalidChange: import("@angular/core").OutputEmitterRef<boolean>;
|
|
2002
|
+
protected readonly _activeError: import("@angular/core").Signal<string>;
|
|
2003
|
+
private _onValidatorChange;
|
|
2004
|
+
constructor();
|
|
2005
|
+
/** Re-run the form control's validation when a rule input (`required`, `requiredMessage`, `label`) changes. */
|
|
2006
|
+
ngOnChanges(): void;
|
|
2007
|
+
validate(control: AbstractControl): ValidationErrors | null;
|
|
2008
|
+
registerOnValidatorChange(fn: () => void): void;
|
|
2009
|
+
private _check;
|
|
1784
2010
|
/** Public so a host template can bind `[disabled]` (a protected input fails strict template type-checking, TS2445). */
|
|
1785
2011
|
readonly _disabledInput: import("@angular/core").InputSignal<boolean>;
|
|
1786
2012
|
private readonly _cvaDisabled;
|
|
@@ -1814,6 +2040,31 @@ export declare class CheckboxComponent implements ControlValueAccessor {
|
|
|
1814
2040
|
"required": false;
|
|
1815
2041
|
"isSignal": true;
|
|
1816
2042
|
};
|
|
2043
|
+
"required": {
|
|
2044
|
+
"alias": "required";
|
|
2045
|
+
"required": false;
|
|
2046
|
+
"isSignal": true;
|
|
2047
|
+
};
|
|
2048
|
+
"requiredMessage": {
|
|
2049
|
+
"alias": "requiredMessage";
|
|
2050
|
+
"required": false;
|
|
2051
|
+
"isSignal": true;
|
|
2052
|
+
};
|
|
2053
|
+
"hint": {
|
|
2054
|
+
"alias": "hint";
|
|
2055
|
+
"required": false;
|
|
2056
|
+
"isSignal": true;
|
|
2057
|
+
};
|
|
2058
|
+
"error": {
|
|
2059
|
+
"alias": "error";
|
|
2060
|
+
"required": false;
|
|
2061
|
+
"isSignal": true;
|
|
2062
|
+
};
|
|
2063
|
+
"showErrors": {
|
|
2064
|
+
"alias": "showErrors";
|
|
2065
|
+
"required": false;
|
|
2066
|
+
"isSignal": true;
|
|
2067
|
+
};
|
|
1817
2068
|
"_disabledInput": {
|
|
1818
2069
|
"alias": "disabled";
|
|
1819
2070
|
"required": false;
|
|
@@ -1821,6 +2072,7 @@ export declare class CheckboxComponent implements ControlValueAccessor {
|
|
|
1821
2072
|
};
|
|
1822
2073
|
}, {
|
|
1823
2074
|
"checked": "checkedChange";
|
|
2075
|
+
"invalidChange": "invalidChange";
|
|
1824
2076
|
}, never, ["*"], true, never>;
|
|
1825
2077
|
}
|
|
1826
2078
|
export declare class ButtonComponent {
|
|
@@ -2919,6 +3171,15 @@ declare class SendEmailComponent implements OnInit {
|
|
|
2919
3171
|
docsRemovedNote: string;
|
|
2920
3172
|
onDocumentsChange(v: DocumentSendValue): void;
|
|
2921
3173
|
onDocumentsInvalid(bad: boolean): void;
|
|
3174
|
+
/** Server limits (400 "Subject must be 255 characters or fewer." / "Body must be 10000 characters or fewer."). */
|
|
3175
|
+
readonly MAX_SUBJECT = 255;
|
|
3176
|
+
readonly MAX_BODY = 10000;
|
|
3177
|
+
/** Inline error when the message, as it will be sent, is over the server limit ('' when fine). */
|
|
3178
|
+
get bodyLengthError(): string;
|
|
3179
|
+
/** Inline error when the subject, as it will be sent, is over the server limit ('' when fine). */
|
|
3180
|
+
get subjectLengthError(): string;
|
|
3181
|
+
/** The length problem shown under the form in every mode; compose mode shows the message one on the editor instead. */
|
|
3182
|
+
get sendLengthError(): string;
|
|
2922
3183
|
get canSend(): boolean;
|
|
2923
3184
|
get minScheduleTime(): string;
|
|
2924
3185
|
/**
|
|
@@ -3826,6 +4087,8 @@ export declare class TextareaInputComponent implements ControlValueAccessor, Val
|
|
|
3826
4087
|
private readonly _cvaDisabled;
|
|
3827
4088
|
protected readonly disabled: import("@angular/core").Signal<boolean>;
|
|
3828
4089
|
protected readonly _value: import("@angular/core").WritableSignal<string>;
|
|
4090
|
+
/** The hint is shown inline after the label; with no label there is nothing to hang it on, so it renders under the field. */
|
|
4091
|
+
protected readonly _unlabelledHint: import("@angular/core").Signal<boolean>;
|
|
3829
4092
|
private readonly _reveal;
|
|
3830
4093
|
private readonly _issue;
|
|
3831
4094
|
/** True while the value breaks a built-in rule or the host passed an `[error]`. */
|
|
@@ -4182,18 +4445,37 @@ export declare class DatetimeInputComponent implements ControlValueAccessor, Val
|
|
|
4182
4445
|
"invalidChange": "invalidChange";
|
|
4183
4446
|
}, never, never, true, never>;
|
|
4184
4447
|
}
|
|
4185
|
-
export declare class TimeInputComponent implements ControlValueAccessor {
|
|
4448
|
+
export declare class TimeInputComponent implements ControlValueAccessor, Validator, UiFieldValidity {
|
|
4186
4449
|
readonly label: import("@angular/core").InputSignal<string>;
|
|
4450
|
+
/** Accessible name when there is no visible `label` (falls back to `label`). */
|
|
4451
|
+
readonly ariaLabel: import("@angular/core").InputSignal<string>;
|
|
4187
4452
|
readonly required: import("@angular/core").InputSignal<boolean>;
|
|
4188
4453
|
readonly min: import("@angular/core").InputSignal<string>;
|
|
4189
4454
|
readonly max: import("@angular/core").InputSignal<string>;
|
|
4190
4455
|
readonly hint: import("@angular/core").InputSignal<string>;
|
|
4191
4456
|
readonly error: import("@angular/core").InputSignal<string>;
|
|
4457
|
+
/** Reveal the built-in error messages now (e.g. after a failed Save click), without waiting for blur. */
|
|
4458
|
+
readonly showErrors: import("@angular/core").InputSignal<boolean>;
|
|
4192
4459
|
protected readonly _disabledInput: import("@angular/core").InputSignal<boolean>;
|
|
4193
4460
|
private readonly _cvaDisabled;
|
|
4194
4461
|
protected readonly disabled: import("@angular/core").Signal<boolean>;
|
|
4195
4462
|
protected readonly _value: import("@angular/core").WritableSignal<string>;
|
|
4196
4463
|
protected readonly _inputId: string;
|
|
4464
|
+
private readonly _reveal;
|
|
4465
|
+
private readonly _issue;
|
|
4466
|
+
/** True while the value breaks a built-in rule or the host passed an `[error]`. */
|
|
4467
|
+
readonly invalid: import("@angular/core").Signal<boolean>;
|
|
4468
|
+
/** Message of the first broken built-in rule ('' when valid), shown or not. */
|
|
4469
|
+
readonly errorMessage: import("@angular/core").Signal<string>;
|
|
4470
|
+
/** Emits whenever the field becomes invalid / valid. */
|
|
4471
|
+
readonly invalidChange: import("@angular/core").OutputEmitterRef<boolean>;
|
|
4472
|
+
protected readonly _activeError: import("@angular/core").Signal<string>;
|
|
4473
|
+
private _onValidatorChange;
|
|
4474
|
+
constructor();
|
|
4475
|
+
/** Re-run the form control's validation when a rule input (required, min, max) changes. */
|
|
4476
|
+
ngOnChanges(): void;
|
|
4477
|
+
validate(control: AbstractControl): ValidationErrors | null;
|
|
4478
|
+
registerOnValidatorChange(fn: () => void): void;
|
|
4197
4479
|
private _onChange;
|
|
4198
4480
|
private _onTouched;
|
|
4199
4481
|
writeValue(val: string): void;
|
|
@@ -4202,6 +4484,7 @@ export declare class TimeInputComponent implements ControlValueAccessor {
|
|
|
4202
4484
|
setDisabledState(d: boolean): void;
|
|
4203
4485
|
protected onChange(event: Event): void;
|
|
4204
4486
|
protected onBlur(): void;
|
|
4487
|
+
private _check;
|
|
4205
4488
|
static ɵfac: i0.ɵɵFactoryDeclaration<TimeInputComponent, never>;
|
|
4206
4489
|
static ɵcmp: i0.ɵɵComponentDeclaration<TimeInputComponent, "ui-time-input", never, {
|
|
4207
4490
|
"label": {
|
|
@@ -4209,6 +4492,11 @@ export declare class TimeInputComponent implements ControlValueAccessor {
|
|
|
4209
4492
|
"required": false;
|
|
4210
4493
|
"isSignal": true;
|
|
4211
4494
|
};
|
|
4495
|
+
"ariaLabel": {
|
|
4496
|
+
"alias": "ariaLabel";
|
|
4497
|
+
"required": false;
|
|
4498
|
+
"isSignal": true;
|
|
4499
|
+
};
|
|
4212
4500
|
"required": {
|
|
4213
4501
|
"alias": "required";
|
|
4214
4502
|
"required": false;
|
|
@@ -4234,12 +4522,19 @@ export declare class TimeInputComponent implements ControlValueAccessor {
|
|
|
4234
4522
|
"required": false;
|
|
4235
4523
|
"isSignal": true;
|
|
4236
4524
|
};
|
|
4525
|
+
"showErrors": {
|
|
4526
|
+
"alias": "showErrors";
|
|
4527
|
+
"required": false;
|
|
4528
|
+
"isSignal": true;
|
|
4529
|
+
};
|
|
4237
4530
|
"_disabledInput": {
|
|
4238
4531
|
"alias": "disabled";
|
|
4239
4532
|
"required": false;
|
|
4240
4533
|
"isSignal": true;
|
|
4241
4534
|
};
|
|
4242
|
-
}, {
|
|
4535
|
+
}, {
|
|
4536
|
+
"invalidChange": "invalidChange";
|
|
4537
|
+
}, never, never, true, never>;
|
|
4243
4538
|
}
|
|
4244
4539
|
/**
|
|
4245
4540
|
* Searchable multi-value dropdown. Selected values render as dismissible chips above the trigger.
|
|
@@ -5070,6 +5365,9 @@ export declare class ImagePreviewComponent {
|
|
|
5070
5365
|
readonly size: import("@angular/core").InputSignal<ImagePreviewSize>;
|
|
5071
5366
|
readonly placeholder: import("@angular/core").InputSignal<ImagePreviewPlaceholder>;
|
|
5072
5367
|
readonly loading: import("@angular/core").InputSignal<"lazy" | "eager">;
|
|
5368
|
+
/** Focal point in percent (0-100, default centered) — which part of a cropped image stays visible (CSS object-position). */
|
|
5369
|
+
readonly positionX: import("@angular/core").InputSignal<number | null | undefined>;
|
|
5370
|
+
readonly positionY: import("@angular/core").InputSignal<number | null | undefined>;
|
|
5073
5371
|
/**
|
|
5074
5372
|
* Optional retry trigger: whenever its value changes, a failed image is attempted again (signal inputs cannot see
|
|
5075
5373
|
* the same `src` being set twice, so a host bumps this, e.g. a counter, to retry the same URL).
|
|
@@ -5078,6 +5376,7 @@ export declare class ImagePreviewComponent {
|
|
|
5078
5376
|
protected readonly _failed: import("@angular/core").WritableSignal<boolean>;
|
|
5079
5377
|
/** Trimmed src; blank / whitespace-only is treated as no image. */
|
|
5080
5378
|
protected readonly _url: import("@angular/core").Signal<string | null>;
|
|
5379
|
+
protected readonly _objectPosition: import("@angular/core").Signal<string>;
|
|
5081
5380
|
protected readonly _cls: import("@angular/core").Signal<string>;
|
|
5082
5381
|
constructor();
|
|
5083
5382
|
/** Clears the failed state so the current `src` is attempted again (call via viewChild). */
|
|
@@ -5115,6 +5414,16 @@ export declare class ImagePreviewComponent {
|
|
|
5115
5414
|
"required": false;
|
|
5116
5415
|
"isSignal": true;
|
|
5117
5416
|
};
|
|
5417
|
+
"positionX": {
|
|
5418
|
+
"alias": "positionX";
|
|
5419
|
+
"required": false;
|
|
5420
|
+
"isSignal": true;
|
|
5421
|
+
};
|
|
5422
|
+
"positionY": {
|
|
5423
|
+
"alias": "positionY";
|
|
5424
|
+
"required": false;
|
|
5425
|
+
"isSignal": true;
|
|
5426
|
+
};
|
|
5118
5427
|
"retryKey": {
|
|
5119
5428
|
"alias": "retryKey";
|
|
5120
5429
|
"required": false;
|
|
@@ -5439,4 +5748,331 @@ export declare class RichTextEditorComponent implements ControlValueAccessor {
|
|
|
5439
5748
|
* raw status text, "null"). Callers fall back to their own generated wording on `null`.
|
|
5440
5749
|
*/
|
|
5441
5750
|
export declare function humanReadableMessage(value: unknown): string | null;
|
|
5751
|
+
/**
|
|
5752
|
+
* Single native radio button (visual tokens of `ui-checkbox`). Normally rendered by `ui-radio-group`; usable standalone
|
|
5753
|
+
* when the host manages the shared `name` and the `checked` state itself.
|
|
5754
|
+
*/
|
|
5755
|
+
export declare class RadioComponent {
|
|
5756
|
+
readonly label: import("@angular/core").InputSignal<string>;
|
|
5757
|
+
readonly description: import("@angular/core").InputSignal<string>;
|
|
5758
|
+
/** Accessible name when there is no visible `label`. */
|
|
5759
|
+
readonly ariaLabel: import("@angular/core").InputSignal<string>;
|
|
5760
|
+
readonly value: import("@angular/core").InputSignal<string>;
|
|
5761
|
+
/** Radios with the same `name` form one keyboard (arrow key) group. */
|
|
5762
|
+
readonly name: import("@angular/core").InputSignal<string>;
|
|
5763
|
+
readonly checked: import("@angular/core").InputSignal<boolean>;
|
|
5764
|
+
readonly invalid: import("@angular/core").InputSignal<boolean>;
|
|
5765
|
+
/** Id(s) of the element(s) describing the group (hint / error). */
|
|
5766
|
+
readonly describedBy: import("@angular/core").InputSignal<string>;
|
|
5767
|
+
/** Public so a host template can bind `[disabled]` (a protected input fails strict template type-checking). */
|
|
5768
|
+
readonly _disabledInput: import("@angular/core").InputSignal<boolean>;
|
|
5769
|
+
protected readonly disabled: import("@angular/core").InputSignal<boolean>;
|
|
5770
|
+
protected readonly _labelId: string;
|
|
5771
|
+
/** With a description inside the <label>, the accessible name would read "Email We send a message": name the input by the label text only. */
|
|
5772
|
+
protected readonly _labelledBy: import("@angular/core").Signal<string | null>;
|
|
5773
|
+
protected readonly _descriptionId: string;
|
|
5774
|
+
/** Group hint/error id plus the option's own description (kept out of the label so the accessible name is label-only). */
|
|
5775
|
+
protected readonly _describedByIds: import("@angular/core").Signal<string | null>;
|
|
5776
|
+
/** Emits the radio's `value` when the user selects it. */
|
|
5777
|
+
readonly selected: import("@angular/core").OutputEmitterRef<string>;
|
|
5778
|
+
protected onChange(event: Event): void;
|
|
5779
|
+
static ɵfac: i0.ɵɵFactoryDeclaration<RadioComponent, never>;
|
|
5780
|
+
static ɵcmp: i0.ɵɵComponentDeclaration<RadioComponent, "ui-radio", never, {
|
|
5781
|
+
"label": {
|
|
5782
|
+
"alias": "label";
|
|
5783
|
+
"required": false;
|
|
5784
|
+
"isSignal": true;
|
|
5785
|
+
};
|
|
5786
|
+
"description": {
|
|
5787
|
+
"alias": "description";
|
|
5788
|
+
"required": false;
|
|
5789
|
+
"isSignal": true;
|
|
5790
|
+
};
|
|
5791
|
+
"ariaLabel": {
|
|
5792
|
+
"alias": "ariaLabel";
|
|
5793
|
+
"required": false;
|
|
5794
|
+
"isSignal": true;
|
|
5795
|
+
};
|
|
5796
|
+
"value": {
|
|
5797
|
+
"alias": "value";
|
|
5798
|
+
"required": false;
|
|
5799
|
+
"isSignal": true;
|
|
5800
|
+
};
|
|
5801
|
+
"name": {
|
|
5802
|
+
"alias": "name";
|
|
5803
|
+
"required": false;
|
|
5804
|
+
"isSignal": true;
|
|
5805
|
+
};
|
|
5806
|
+
"checked": {
|
|
5807
|
+
"alias": "checked";
|
|
5808
|
+
"required": false;
|
|
5809
|
+
"isSignal": true;
|
|
5810
|
+
};
|
|
5811
|
+
"invalid": {
|
|
5812
|
+
"alias": "invalid";
|
|
5813
|
+
"required": false;
|
|
5814
|
+
"isSignal": true;
|
|
5815
|
+
};
|
|
5816
|
+
"describedBy": {
|
|
5817
|
+
"alias": "describedBy";
|
|
5818
|
+
"required": false;
|
|
5819
|
+
"isSignal": true;
|
|
5820
|
+
};
|
|
5821
|
+
"_disabledInput": {
|
|
5822
|
+
"alias": "disabled";
|
|
5823
|
+
"required": false;
|
|
5824
|
+
"isSignal": true;
|
|
5825
|
+
};
|
|
5826
|
+
}, {
|
|
5827
|
+
"selected": "selected";
|
|
5828
|
+
}, never, ["*"], true, never>;
|
|
5829
|
+
}
|
|
5830
|
+
export interface RadioOption {
|
|
5831
|
+
value: string;
|
|
5832
|
+
label: string;
|
|
5833
|
+
description?: string;
|
|
5834
|
+
disabled?: boolean;
|
|
5835
|
+
}
|
|
5836
|
+
/**
|
|
5837
|
+
* Group of native radio buttons inside a `<fieldset>` (+ `<legend>` = `label`), a ControlValueAccessor (string value, `''`
|
|
5838
|
+
* = nothing selected). Arrow keys move and select natively because all radios share one `name`.
|
|
5839
|
+
* Built-in validation: `required` -> "<label> is required."; a non-empty value that is not one of the `options` ->
|
|
5840
|
+
* "Select a valid option." (not checked while `options` is empty). Disabled groups are never invalid.
|
|
5841
|
+
*
|
|
5842
|
+
* Validity API (same on every ui input): Angular `Validator`, signals `invalid` + `errorMessage`, `invalidChange` output,
|
|
5843
|
+
* provides `UiFieldValidity`. Messages show after the group lost focus or while `[showErrors]="true"`; a host `[error]` wins.
|
|
5844
|
+
*/
|
|
5845
|
+
export declare class RadioGroupComponent implements ControlValueAccessor, Validator, UiFieldValidity {
|
|
5846
|
+
readonly label: import("@angular/core").InputSignal<string>;
|
|
5847
|
+
readonly options: import("@angular/core").InputSignal<RadioOption[]>;
|
|
5848
|
+
readonly required: import("@angular/core").InputSignal<boolean>;
|
|
5849
|
+
readonly hint: import("@angular/core").InputSignal<string>;
|
|
5850
|
+
readonly error: import("@angular/core").InputSignal<string>;
|
|
5851
|
+
/** Reveal the built-in error messages now (e.g. after a failed Save click), without waiting for blur. */
|
|
5852
|
+
readonly showErrors: import("@angular/core").InputSignal<boolean>;
|
|
5853
|
+
readonly orientation: import("@angular/core").InputSignal<"vertical" | "horizontal">;
|
|
5854
|
+
/** Native `name` shared by the radios; a unique one is generated when omitted. */
|
|
5855
|
+
readonly name: import("@angular/core").InputSignal<string>;
|
|
5856
|
+
protected readonly _disabledInput: import("@angular/core").InputSignal<boolean>;
|
|
5857
|
+
private readonly _cvaDisabled;
|
|
5858
|
+
protected readonly disabled: import("@angular/core").Signal<boolean>;
|
|
5859
|
+
private readonly _generatedName;
|
|
5860
|
+
protected get _name(): string;
|
|
5861
|
+
protected readonly _descId: string;
|
|
5862
|
+
protected readonly _value: import("@angular/core").WritableSignal<string>;
|
|
5863
|
+
private readonly _reveal;
|
|
5864
|
+
private readonly _issue;
|
|
5865
|
+
/** True while the value breaks a built-in rule or the host passed an `[error]`. */
|
|
5866
|
+
readonly invalid: import("@angular/core").Signal<boolean>;
|
|
5867
|
+
/** Message of the first broken built-in rule ('' when valid), shown or not. */
|
|
5868
|
+
readonly errorMessage: import("@angular/core").Signal<string>;
|
|
5869
|
+
/** Emits whenever the field becomes invalid / valid. */
|
|
5870
|
+
readonly invalidChange: import("@angular/core").OutputEmitterRef<boolean>;
|
|
5871
|
+
protected readonly _activeError: import("@angular/core").Signal<string>;
|
|
5872
|
+
private _onValidatorChange;
|
|
5873
|
+
constructor();
|
|
5874
|
+
/** Re-run the form control's validation when a rule input (required, options) changes. */
|
|
5875
|
+
ngOnChanges(): void;
|
|
5876
|
+
validate(control: AbstractControl): ValidationErrors | null;
|
|
5877
|
+
registerOnValidatorChange(fn: () => void): void;
|
|
5878
|
+
private _onChange;
|
|
5879
|
+
private _onTouched;
|
|
5880
|
+
writeValue(val: string): void;
|
|
5881
|
+
registerOnChange(fn: (v: string) => void): void;
|
|
5882
|
+
registerOnTouched(fn: () => void): void;
|
|
5883
|
+
setDisabledState(d: boolean): void;
|
|
5884
|
+
protected onSelect(value: string): void;
|
|
5885
|
+
/** Touched once focus leaves the whole group (moving between its radios does not count). */
|
|
5886
|
+
protected onFocusOut(event: FocusEvent): void;
|
|
5887
|
+
private _check;
|
|
5888
|
+
static ɵfac: i0.ɵɵFactoryDeclaration<RadioGroupComponent, never>;
|
|
5889
|
+
static ɵcmp: i0.ɵɵComponentDeclaration<RadioGroupComponent, "ui-radio-group", never, {
|
|
5890
|
+
"label": {
|
|
5891
|
+
"alias": "label";
|
|
5892
|
+
"required": false;
|
|
5893
|
+
"isSignal": true;
|
|
5894
|
+
};
|
|
5895
|
+
"options": {
|
|
5896
|
+
"alias": "options";
|
|
5897
|
+
"required": false;
|
|
5898
|
+
"isSignal": true;
|
|
5899
|
+
};
|
|
5900
|
+
"required": {
|
|
5901
|
+
"alias": "required";
|
|
5902
|
+
"required": false;
|
|
5903
|
+
"isSignal": true;
|
|
5904
|
+
};
|
|
5905
|
+
"hint": {
|
|
5906
|
+
"alias": "hint";
|
|
5907
|
+
"required": false;
|
|
5908
|
+
"isSignal": true;
|
|
5909
|
+
};
|
|
5910
|
+
"error": {
|
|
5911
|
+
"alias": "error";
|
|
5912
|
+
"required": false;
|
|
5913
|
+
"isSignal": true;
|
|
5914
|
+
};
|
|
5915
|
+
"showErrors": {
|
|
5916
|
+
"alias": "showErrors";
|
|
5917
|
+
"required": false;
|
|
5918
|
+
"isSignal": true;
|
|
5919
|
+
};
|
|
5920
|
+
"orientation": {
|
|
5921
|
+
"alias": "orientation";
|
|
5922
|
+
"required": false;
|
|
5923
|
+
"isSignal": true;
|
|
5924
|
+
};
|
|
5925
|
+
"name": {
|
|
5926
|
+
"alias": "name";
|
|
5927
|
+
"required": false;
|
|
5928
|
+
"isSignal": true;
|
|
5929
|
+
};
|
|
5930
|
+
"_disabledInput": {
|
|
5931
|
+
"alias": "disabled";
|
|
5932
|
+
"required": false;
|
|
5933
|
+
"isSignal": true;
|
|
5934
|
+
};
|
|
5935
|
+
}, {
|
|
5936
|
+
"invalidChange": "invalidChange";
|
|
5937
|
+
}, never, never, true, never>;
|
|
5938
|
+
}
|
|
5939
|
+
/**
|
|
5940
|
+
* Card for detail pages: an optional header and a body, both filled by the page that uses it.
|
|
5941
|
+
*
|
|
5942
|
+
* Header (all optional - set `[showHeader]="false"` and the card is just the body):
|
|
5943
|
+
* - `title` / `subtitle`: the bold uppercase title and the grey line under it.
|
|
5944
|
+
* - `titleId`: an id for the title text, which also names the card for assistive tech (aria-labelledby).
|
|
5945
|
+
* - `<div card-header-leading>`: something before the title block, such as a logo or an icon.
|
|
5946
|
+
* - `<ng-container card-header>`: your own header content, shown under the title (or instead of it when no title is set).
|
|
5947
|
+
* - `<ng-container card-header-action>`: buttons or links on the right side of the header.
|
|
5948
|
+
* - `showEdit` + `editLabel` + `(editClick)`: the built-in Edit button.
|
|
5949
|
+
* - `collapsible` (default true): a chevron toggle and a clickable header; `[(expanded)]` is two-way.
|
|
5950
|
+
* Without a header, or with `collapsible` false, the body is always open.
|
|
5951
|
+
*
|
|
5952
|
+
* The title is always shown in capitals; the subtitle keeps the case you give it. The body is the default content slot. A collapsed body is removed from the tab order and from assistive tech.
|
|
5953
|
+
*
|
|
5954
|
+
* <ui-detail-card title="COMMUNICATIONS" subtitle="All calls, texts, and emails"> ...body... </ui-detail-card>
|
|
5955
|
+
* <ui-detail-card title="CONTACT INFO" [showEdit]="true" (editClick)="openEdit()"> ... </ui-detail-card>
|
|
5956
|
+
* <ui-detail-card [showHeader]="false"> ...body only... </ui-detail-card>
|
|
5957
|
+
* <ui-detail-card [collapsible]="false">
|
|
5958
|
+
* <div card-header>Any markup</div>
|
|
5959
|
+
* <ui-button card-header-action size="xs" variant="secondary">Add</ui-button>
|
|
5960
|
+
* ...body...
|
|
5961
|
+
* </ui-detail-card>
|
|
5962
|
+
*/
|
|
5963
|
+
export declare class DetailCardComponent {
|
|
5964
|
+
/** Bold uppercase title. Empty = no title text. */
|
|
5965
|
+
readonly title: import("@angular/core").InputSignal<string>;
|
|
5966
|
+
/** 1-6 makes the title a real heading for screen readers (role=heading, aria-level); null keeps it plain text. */
|
|
5967
|
+
readonly headingLevel: import("@angular/core").InputSignal<1 | 2 | 3 | 4 | 5 | 6 | null>;
|
|
5968
|
+
/** Optional id for the title text; the card is then labelled by it. Without it the title is the card's aria-label. */
|
|
5969
|
+
readonly titleId: import("@angular/core").InputSignal<string>;
|
|
5970
|
+
/** Grey line under the title. */
|
|
5971
|
+
readonly subtitle: import("@angular/core").InputSignal<string>;
|
|
5972
|
+
/** false = no header at all (no title, edit button, toggle or divider): the card is only the body, always open. */
|
|
5973
|
+
readonly showHeader: import("@angular/core").InputSignal<boolean>;
|
|
5974
|
+
/** Chevron toggle + clickable header. false = the body is always open. */
|
|
5975
|
+
readonly collapsible: import("@angular/core").InputSignal<boolean>;
|
|
5976
|
+
/** Two-way: whether the body is open. */
|
|
5977
|
+
readonly expanded: import("@angular/core").ModelSignal<boolean>;
|
|
5978
|
+
/** Show the built-in Edit button in the header. */
|
|
5979
|
+
readonly showEdit: import("@angular/core").InputSignal<boolean>;
|
|
5980
|
+
readonly editLabel: import("@angular/core").InputSignal<string>;
|
|
5981
|
+
readonly editClick: import("@angular/core").OutputEmitterRef<void>;
|
|
5982
|
+
/** The body is open unless the card has a header that is collapsible and was collapsed. */
|
|
5983
|
+
isOpen(): boolean;
|
|
5984
|
+
toggle(): void;
|
|
5985
|
+
/** A click on the header toggles, except on a control inside it (Edit, your own header actions, links, inputs). */
|
|
5986
|
+
onHeaderClick(event: Event): void;
|
|
5987
|
+
static ɵfac: i0.ɵɵFactoryDeclaration<DetailCardComponent, never>;
|
|
5988
|
+
static ɵcmp: i0.ɵɵComponentDeclaration<DetailCardComponent, "ui-detail-card", never, {
|
|
5989
|
+
"title": {
|
|
5990
|
+
"alias": "title";
|
|
5991
|
+
"required": false;
|
|
5992
|
+
"isSignal": true;
|
|
5993
|
+
};
|
|
5994
|
+
"headingLevel": {
|
|
5995
|
+
"alias": "headingLevel";
|
|
5996
|
+
"required": false;
|
|
5997
|
+
"isSignal": true;
|
|
5998
|
+
};
|
|
5999
|
+
"titleId": {
|
|
6000
|
+
"alias": "titleId";
|
|
6001
|
+
"required": false;
|
|
6002
|
+
"isSignal": true;
|
|
6003
|
+
};
|
|
6004
|
+
"subtitle": {
|
|
6005
|
+
"alias": "subtitle";
|
|
6006
|
+
"required": false;
|
|
6007
|
+
"isSignal": true;
|
|
6008
|
+
};
|
|
6009
|
+
"showHeader": {
|
|
6010
|
+
"alias": "showHeader";
|
|
6011
|
+
"required": false;
|
|
6012
|
+
"isSignal": true;
|
|
6013
|
+
};
|
|
6014
|
+
"collapsible": {
|
|
6015
|
+
"alias": "collapsible";
|
|
6016
|
+
"required": false;
|
|
6017
|
+
"isSignal": true;
|
|
6018
|
+
};
|
|
6019
|
+
"expanded": {
|
|
6020
|
+
"alias": "expanded";
|
|
6021
|
+
"required": false;
|
|
6022
|
+
"isSignal": true;
|
|
6023
|
+
};
|
|
6024
|
+
"showEdit": {
|
|
6025
|
+
"alias": "showEdit";
|
|
6026
|
+
"required": false;
|
|
6027
|
+
"isSignal": true;
|
|
6028
|
+
};
|
|
6029
|
+
"editLabel": {
|
|
6030
|
+
"alias": "editLabel";
|
|
6031
|
+
"required": false;
|
|
6032
|
+
"isSignal": true;
|
|
6033
|
+
};
|
|
6034
|
+
}, {
|
|
6035
|
+
"expanded": "expandedChange";
|
|
6036
|
+
"editClick": "editClick";
|
|
6037
|
+
}, never, ["[card-header-leading]", "[card-header]", "[card-header-action]", "*"], true, never>;
|
|
6038
|
+
}
|
|
6039
|
+
export type DividerSpace = 'none' | 'sm' | 'md' | 'lg';
|
|
6040
|
+
/**
|
|
6041
|
+
* Horizontal divider line (an `<hr>`) with the app's standard colour and optional space above / below.
|
|
6042
|
+
* It is a real separator for assistive tech by default; set `decorative` when it only adds visual rhythm and the
|
|
6043
|
+
* content around it already reads as separate (the line is then hidden from screen readers).
|
|
6044
|
+
*
|
|
6045
|
+
* <section class="kpi-grid"> ... </section>
|
|
6046
|
+
* <ui-divider /> // line with 16px below
|
|
6047
|
+
* <ui-divider spaceAbove="md" spaceBelow="lg" />
|
|
6048
|
+
* <ui-divider [decorative]="true" />
|
|
6049
|
+
*/
|
|
6050
|
+
export declare class DividerComponent {
|
|
6051
|
+
/** Space above the line: none (0), sm (8px), md (16px), lg (24px). */
|
|
6052
|
+
readonly spaceAbove: import("@angular/core").InputSignal<DividerSpace>;
|
|
6053
|
+
/** Space below the line: none (0), sm (8px), md (16px), lg (24px). */
|
|
6054
|
+
readonly spaceBelow: import("@angular/core").InputSignal<DividerSpace>;
|
|
6055
|
+
/** true = purely visual: hidden from assistive tech. */
|
|
6056
|
+
readonly decorative: import("@angular/core").InputSignal<boolean>;
|
|
6057
|
+
protected readonly above: import("@angular/core").Signal<number>;
|
|
6058
|
+
protected readonly below: import("@angular/core").Signal<number>;
|
|
6059
|
+
static ɵfac: i0.ɵɵFactoryDeclaration<DividerComponent, never>;
|
|
6060
|
+
static ɵcmp: i0.ɵɵComponentDeclaration<DividerComponent, "ui-divider", never, {
|
|
6061
|
+
"spaceAbove": {
|
|
6062
|
+
"alias": "spaceAbove";
|
|
6063
|
+
"required": false;
|
|
6064
|
+
"isSignal": true;
|
|
6065
|
+
};
|
|
6066
|
+
"spaceBelow": {
|
|
6067
|
+
"alias": "spaceBelow";
|
|
6068
|
+
"required": false;
|
|
6069
|
+
"isSignal": true;
|
|
6070
|
+
};
|
|
6071
|
+
"decorative": {
|
|
6072
|
+
"alias": "decorative";
|
|
6073
|
+
"required": false;
|
|
6074
|
+
"isSignal": true;
|
|
6075
|
+
};
|
|
6076
|
+
}, {}, never, never, true, never>;
|
|
6077
|
+
}
|
|
5442
6078
|
export type { SendDocumentsPayload, SendEmailPayload, SendTextPayload };
|