@forgeroute/ui 0.4.19 → 0.4.21
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-messaging.mjs +4 -0
- package/fesm2022/forgeroute-ui-messaging.mjs.map +1 -1
- package/fesm2022/forgeroute-ui-stripe.mjs +1 -0
- package/fesm2022/forgeroute-ui-stripe.mjs.map +1 -1
- package/fesm2022/forgeroute-ui.mjs +1779 -132
- package/fesm2022/forgeroute-ui.mjs.map +1 -1
- package/package.json +1 -1
- package/types/forgeroute-ui.d.ts +454 -5
package/package.json
CHANGED
package/types/forgeroute-ui.d.ts
CHANGED
|
@@ -480,6 +480,8 @@ export declare class PaginationComponent {
|
|
|
480
480
|
readonly totalItems: import("@angular/core").InputSignal<number>;
|
|
481
481
|
/** Standalone look (full border, full radius, small top margin) for use under separate cards rather than flush under a table. */
|
|
482
482
|
readonly detached: import("@angular/core").InputSignal<boolean>;
|
|
483
|
+
/** Embedded look for a container that already has its own background and edge (a `ui-detail-card` footer, a panel): transparent, no border, no radius, no padding. Default false: unchanged. Wins over `detached`. */
|
|
484
|
+
readonly embedded: import("@angular/core").InputSignal<boolean>;
|
|
483
485
|
readonly pageChange: import("@angular/core").OutputEmitterRef<number>;
|
|
484
486
|
readonly totalPages: import("@angular/core").Signal<number>;
|
|
485
487
|
readonly startItem: import("@angular/core").Signal<number>;
|
|
@@ -508,6 +510,11 @@ export declare class PaginationComponent {
|
|
|
508
510
|
"required": false;
|
|
509
511
|
"isSignal": true;
|
|
510
512
|
};
|
|
513
|
+
"embedded": {
|
|
514
|
+
"alias": "embedded";
|
|
515
|
+
"required": false;
|
|
516
|
+
"isSignal": true;
|
|
517
|
+
};
|
|
511
518
|
}, {
|
|
512
519
|
"pageChange": "pageChange";
|
|
513
520
|
}, never, never, true, never>;
|
|
@@ -959,6 +966,12 @@ export interface SelectOption<V extends string | number = string> {
|
|
|
959
966
|
* Options without it are unchanged.
|
|
960
967
|
*/
|
|
961
968
|
badge?: string;
|
|
969
|
+
/**
|
|
970
|
+
* Optional: list the choice but make it unselectable (native `<option disabled>`). Use it for an entry that must stay visible because it is the
|
|
971
|
+
* CURRENT value (e.g. an owner who is no longer active) but must not be picked. A disabled option that equals the current value is still shown as
|
|
972
|
+
* selected and still counts as a valid value; the user just cannot choose it again after picking another option. Options without it are unchanged.
|
|
973
|
+
*/
|
|
974
|
+
disabled?: boolean;
|
|
962
975
|
}
|
|
963
976
|
export declare class SelectComponent implements ControlValueAccessor, Validator, UiFieldValidity {
|
|
964
977
|
readonly label: import("@angular/core").InputSignal<string>;
|
|
@@ -1244,7 +1257,13 @@ export declare class DataTableComponent<T extends Record<string, any>> implement
|
|
|
1244
1257
|
* tabs are all off, the header row is not rendered at all.
|
|
1245
1258
|
*/
|
|
1246
1259
|
readonly showQuickTabs: import("@angular/core").InputSignal<boolean>;
|
|
1247
|
-
/**
|
|
1260
|
+
/**
|
|
1261
|
+
* Optional heading shown at the start of the header row, on the same row as the search box / tabs on the left and the
|
|
1262
|
+
* Export / primary buttons on the right (rendered as an `<h3>`, also while the table is loading and when it is empty).
|
|
1263
|
+
* Empty (default) renders nothing. Use it when the table is a section of a page and its title belongs with its toolbar.
|
|
1264
|
+
*/
|
|
1265
|
+
readonly tableTitle: import("@angular/core").InputSignal<string>;
|
|
1266
|
+
/** False when the header row would be empty (no title, no search box, no toolbar, no quick-filter tabs). */
|
|
1248
1267
|
protected readonly _showHeader: Signal<boolean>;
|
|
1249
1268
|
/** Optional endpoint that returns Record<string,number> counts per quick-filter value. */
|
|
1250
1269
|
readonly countsEndpoint: import("@angular/core").InputSignal<string>;
|
|
@@ -1777,6 +1796,11 @@ export declare class DataTableComponent<T extends Record<string, any>> implement
|
|
|
1777
1796
|
"required": false;
|
|
1778
1797
|
"isSignal": true;
|
|
1779
1798
|
};
|
|
1799
|
+
"tableTitle": {
|
|
1800
|
+
"alias": "tableTitle";
|
|
1801
|
+
"required": false;
|
|
1802
|
+
"isSignal": true;
|
|
1803
|
+
};
|
|
1780
1804
|
"countsEndpoint": {
|
|
1781
1805
|
"alias": "countsEndpoint";
|
|
1782
1806
|
"required": false;
|
|
@@ -4292,6 +4316,12 @@ export declare class TextInputComponent implements ControlValueAccessor, Validat
|
|
|
4292
4316
|
readonly label: import("@angular/core").InputSignal<string>;
|
|
4293
4317
|
/** Accessible name for a field with no visible label (e.g. an inline cell or title input). */
|
|
4294
4318
|
readonly ariaLabel: import("@angular/core").InputSignal<string>;
|
|
4319
|
+
/**
|
|
4320
|
+
* `data-testid` placed on the inner `<input>` (the host `<ui-text-input>` keeps its own attributes). Lets e2e tests `fill()` / `blur()` the
|
|
4321
|
+
* field directly instead of `getByTestId('x').locator('input')`. Pass a different id than the host's, e.g. host `data-testid="email"`
|
|
4322
|
+
* and `inputTestId="email-input"`. Omitted = no attribute.
|
|
4323
|
+
*/
|
|
4324
|
+
readonly inputTestId: import("@angular/core").InputSignal<string>;
|
|
4295
4325
|
readonly placeholder: import("@angular/core").InputSignal<string>;
|
|
4296
4326
|
/**
|
|
4297
4327
|
* An optional leading mark shown inside the field, left of the text (e.g. `prefix="$"` for a dollar amount). Hidden unless set; it is
|
|
@@ -4437,6 +4467,11 @@ export declare class TextInputComponent implements ControlValueAccessor, Validat
|
|
|
4437
4467
|
"required": false;
|
|
4438
4468
|
"isSignal": true;
|
|
4439
4469
|
};
|
|
4470
|
+
"inputTestId": {
|
|
4471
|
+
"alias": "inputTestId";
|
|
4472
|
+
"required": false;
|
|
4473
|
+
"isSignal": true;
|
|
4474
|
+
};
|
|
4440
4475
|
"placeholder": {
|
|
4441
4476
|
"alias": "placeholder";
|
|
4442
4477
|
"required": false;
|
|
@@ -4557,7 +4592,7 @@ export declare class TextInputComponent implements ControlValueAccessor, Validat
|
|
|
4557
4592
|
"focused": "focused";
|
|
4558
4593
|
"blurred": "blurred";
|
|
4559
4594
|
"invalidChange": "invalidChange";
|
|
4560
|
-
}, never,
|
|
4595
|
+
}, never, ["[uiLabelEnd]"], true, never>;
|
|
4561
4596
|
}
|
|
4562
4597
|
export declare class TextareaInputComponent implements ControlValueAccessor, Validator, UiFieldValidity {
|
|
4563
4598
|
readonly label: import("@angular/core").InputSignal<string>;
|
|
@@ -6105,6 +6140,213 @@ export declare class ListItemComponent {
|
|
|
6105
6140
|
"select": "select";
|
|
6106
6141
|
}, never, ["[list-item-action], [li-action]"], true, never>;
|
|
6107
6142
|
}
|
|
6143
|
+
/** Colour of the priority dot (`high` red, `medium` amber, `low` grey, `blue`, `green`); `none` = no dot. */
|
|
6144
|
+
export type CardListIndicator = 'high' | 'medium' | 'low' | 'blue' | 'green' | 'none';
|
|
6145
|
+
/** Icon of the round marker on the left. */
|
|
6146
|
+
export type CardListIcon = 'call' | 'email' | 'sms' | 'task' | 'doc' | 'money' | 'deal' | 'survey' | 'property' | 'search' | 'heart' | 'calc' | 'repeat';
|
|
6147
|
+
/**
|
|
6148
|
+
* Record row for the cards of a detail page (tasks, documents, deals, expenses, matches, surveys...). The layout is fixed;
|
|
6149
|
+
* pass inputs only:
|
|
6150
|
+
*
|
|
6151
|
+
* [dot | round icon] [title] [type badge] [status badge] [Edit] [View]
|
|
6152
|
+
* [description] [inline link]
|
|
6153
|
+
* [calendar icon + date]
|
|
6154
|
+
*
|
|
6155
|
+
* Each row is a bordered rounded box, 8px apart; put the rows straight in a `ui-detail-card` body (or in a `ui-list` template).
|
|
6156
|
+
*
|
|
6157
|
+
* <ui-card-list-item title="Call John" indicator="high" type="Meeting" status="Pending" statusVariant="gray"
|
|
6158
|
+
* date="Due Aug 21, 2026" description="Follow up about the offer"
|
|
6159
|
+
* [editButton]="true" (editClick)="edit(t)" [viewButton]="true" (viewClick)="view(t)" />
|
|
6160
|
+
*
|
|
6161
|
+
* Links: the library has no router, so a link is content you project and the app owns (`routerLink` etc.):
|
|
6162
|
+
* - `<a card-list-action class="cli-chip cli-chip--view" routerLink="/x">View</a>` at the row end (blue chip, like the View button);
|
|
6163
|
+
* - `<a card-list-inline class="cli-inline-link" routerLink="/x">View ...</a>` at the end of the description line.
|
|
6164
|
+
* Other projected content (default slot) shows after the chips at the row end; `[card-stats]` and `[card-detail]` add a footer row
|
|
6165
|
+
* under the row (use the `.cli-stat`, `.cli-stat-label`, `.cli-stat-value`, `.cli-stat-divider` classes inside `[card-stats]`).
|
|
6166
|
+
*
|
|
6167
|
+
* Accessibility: the Edit / View buttons are real buttons; give them a longer name with `editAriaLabel` / `viewAriaLabel`
|
|
6168
|
+
* ("Edit task Call John") when the visible word alone is ambiguous in a list. The priority dot (`high`/`medium`/`low`) has a tooltip and an
|
|
6169
|
+
* accessible name (`High priority`, ...), is focusable so the tooltip works by keyboard; `blue`/`green` dots are decorative. The icon circle is decorative.
|
|
6170
|
+
*/
|
|
6171
|
+
export declare class CardListItemComponent {
|
|
6172
|
+
readonly title: import("@angular/core").InputSignal<string>;
|
|
6173
|
+
readonly description: import("@angular/core").InputSignal<string | undefined>;
|
|
6174
|
+
/** Date text with a small calendar icon, e.g. "Due Aug 21, 2026". Pre-formatted by the page. */
|
|
6175
|
+
readonly date: import("@angular/core").InputSignal<string | undefined>;
|
|
6176
|
+
/** Badge after the title; `typeVariant` colours it (default `gray`). */
|
|
6177
|
+
readonly type: import("@angular/core").InputSignal<string | undefined>;
|
|
6178
|
+
readonly typeVariant: import("@angular/core").InputSignal<BadgeVariant>;
|
|
6179
|
+
/** Second badge; shown only together with `statusVariant`. */
|
|
6180
|
+
readonly status: import("@angular/core").InputSignal<string | undefined>;
|
|
6181
|
+
readonly statusVariant: import("@angular/core").InputSignal<BadgeVariant | undefined>;
|
|
6182
|
+
/** Priority dot on the left (ignored when `icon` is set). */
|
|
6183
|
+
readonly indicator: import("@angular/core").InputSignal<CardListIndicator>;
|
|
6184
|
+
/** Round icon on the left (wins over `indicator`). */
|
|
6185
|
+
readonly icon: import("@angular/core").InputSignal<CardListIcon | undefined>;
|
|
6186
|
+
/** Built-in "Edit" chip button -> `editClick`. */
|
|
6187
|
+
readonly editButton: import("@angular/core").InputSignal<boolean>;
|
|
6188
|
+
/** Built-in "View" chip button -> `viewClick`. */
|
|
6189
|
+
readonly viewButton: import("@angular/core").InputSignal<boolean>;
|
|
6190
|
+
/** Accessible names for the buttons when the visible word is not enough ("Edit task Call John"). */
|
|
6191
|
+
readonly editAriaLabel: import("@angular/core").InputSignal<string>;
|
|
6192
|
+
readonly viewAriaLabel: import("@angular/core").InputSignal<string>;
|
|
6193
|
+
readonly editClick: import("@angular/core").OutputEmitterRef<void>;
|
|
6194
|
+
readonly viewClick: import("@angular/core").OutputEmitterRef<void>;
|
|
6195
|
+
protected readonly calendarPath = "M5 4h14a2 2 0 0 1 2 2v14a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V6a2 2 0 0 1 2-2z M16 2v4 M8 2v4 M3 10h18";
|
|
6196
|
+
protected readonly editPath = "M11 4H4a2 2 0 0 0-2 2v14a2 2 0 0 0 2 2h14a2 2 0 0 0 2-2v-7 M18.5 2.5a2.121 2.121 0 0 1 3 3L12 15l-4 1 1-4 9.5-9.5z";
|
|
6197
|
+
protected readonly iconPath: import("@angular/core").Signal<string | null>;
|
|
6198
|
+
protected readonly indicatorLabel: import("@angular/core").Signal<string>;
|
|
6199
|
+
static ɵfac: i0.ɵɵFactoryDeclaration<CardListItemComponent, never>;
|
|
6200
|
+
static ɵcmp: i0.ɵɵComponentDeclaration<CardListItemComponent, "ui-card-list-item", never, {
|
|
6201
|
+
"title": {
|
|
6202
|
+
"alias": "title";
|
|
6203
|
+
"required": false;
|
|
6204
|
+
"isSignal": true;
|
|
6205
|
+
};
|
|
6206
|
+
"description": {
|
|
6207
|
+
"alias": "description";
|
|
6208
|
+
"required": false;
|
|
6209
|
+
"isSignal": true;
|
|
6210
|
+
};
|
|
6211
|
+
"date": {
|
|
6212
|
+
"alias": "date";
|
|
6213
|
+
"required": false;
|
|
6214
|
+
"isSignal": true;
|
|
6215
|
+
};
|
|
6216
|
+
"type": {
|
|
6217
|
+
"alias": "type";
|
|
6218
|
+
"required": false;
|
|
6219
|
+
"isSignal": true;
|
|
6220
|
+
};
|
|
6221
|
+
"typeVariant": {
|
|
6222
|
+
"alias": "typeVariant";
|
|
6223
|
+
"required": false;
|
|
6224
|
+
"isSignal": true;
|
|
6225
|
+
};
|
|
6226
|
+
"status": {
|
|
6227
|
+
"alias": "status";
|
|
6228
|
+
"required": false;
|
|
6229
|
+
"isSignal": true;
|
|
6230
|
+
};
|
|
6231
|
+
"statusVariant": {
|
|
6232
|
+
"alias": "statusVariant";
|
|
6233
|
+
"required": false;
|
|
6234
|
+
"isSignal": true;
|
|
6235
|
+
};
|
|
6236
|
+
"indicator": {
|
|
6237
|
+
"alias": "indicator";
|
|
6238
|
+
"required": false;
|
|
6239
|
+
"isSignal": true;
|
|
6240
|
+
};
|
|
6241
|
+
"icon": {
|
|
6242
|
+
"alias": "icon";
|
|
6243
|
+
"required": false;
|
|
6244
|
+
"isSignal": true;
|
|
6245
|
+
};
|
|
6246
|
+
"editButton": {
|
|
6247
|
+
"alias": "editButton";
|
|
6248
|
+
"required": false;
|
|
6249
|
+
"isSignal": true;
|
|
6250
|
+
};
|
|
6251
|
+
"viewButton": {
|
|
6252
|
+
"alias": "viewButton";
|
|
6253
|
+
"required": false;
|
|
6254
|
+
"isSignal": true;
|
|
6255
|
+
};
|
|
6256
|
+
"editAriaLabel": {
|
|
6257
|
+
"alias": "editAriaLabel";
|
|
6258
|
+
"required": false;
|
|
6259
|
+
"isSignal": true;
|
|
6260
|
+
};
|
|
6261
|
+
"viewAriaLabel": {
|
|
6262
|
+
"alias": "viewAriaLabel";
|
|
6263
|
+
"required": false;
|
|
6264
|
+
"isSignal": true;
|
|
6265
|
+
};
|
|
6266
|
+
}, {
|
|
6267
|
+
"editClick": "editClick";
|
|
6268
|
+
"viewClick": "viewClick";
|
|
6269
|
+
}, never, ["[card-list-inline]", "[card-list-action]", "*", "[card-stats]", "[card-detail]"], true, never>;
|
|
6270
|
+
}
|
|
6271
|
+
/** A note as the notes API returns it. */
|
|
6272
|
+
export interface NoteItem {
|
|
6273
|
+
id: string;
|
|
6274
|
+
body: string;
|
|
6275
|
+
createdByName: string;
|
|
6276
|
+
createdAt: string;
|
|
6277
|
+
updatedAt: string;
|
|
6278
|
+
}
|
|
6279
|
+
/**
|
|
6280
|
+
* Notes for one record: a soft "Add a note" panel, then one clean card per note (author avatar, name, date, edit / delete icons, the text),
|
|
6281
|
+
* inline edit and a delete confirmation. Notes are listed 5 per page in the server's order. It talks to the notes API itself, so a page only names the record:
|
|
6282
|
+
*
|
|
6283
|
+
* <ui-notes resourceType="contact" [resourceId]="contactId" [readOnly]="!canEdit()" (totalChange)="notesTotal.set($event)" />
|
|
6284
|
+
*
|
|
6285
|
+
* API (under `FORGEROUTE_CONFIG.baseUrl`, default `/api`):
|
|
6286
|
+
* - `GET /notes/{resourceType}/{resourceId}?page=<0-based>&size=5` -> `{ content: NoteItem[], totalElements, totalPages, page, size }`
|
|
6287
|
+
* - `POST /notes/{resourceType}/{resourceId}` `{ body }` -> the new note
|
|
6288
|
+
* - `PUT /notes/{noteId}` `{ body }` -> the updated note
|
|
6289
|
+
* - `DELETE /notes/{noteId}`
|
|
6290
|
+
*
|
|
6291
|
+
* `readOnly` lists the notes only (no box, no edit / delete). `totalChange` emits the total after every load. Failures show a
|
|
6292
|
+
* library toast with the server's message. Put it in a `ui-detail-card`: the card's body padding is the only outer inset.
|
|
6293
|
+
* Pagination is the library `ui-pagination` (shown only above one page). Cmd/Ctrl+Enter in the add box adds the note.
|
|
6294
|
+
*/
|
|
6295
|
+
export declare class NotesComponent {
|
|
6296
|
+
/** What the notes belong to, as the API names it: `contact`, `transaction`, `property`, `task`, ... */
|
|
6297
|
+
readonly resourceType: import("@angular/core").InputSignal<string>;
|
|
6298
|
+
readonly resourceId: import("@angular/core").InputSignal<string>;
|
|
6299
|
+
/** True: list only, no add box, edit or delete. */
|
|
6300
|
+
readonly readOnly: import("@angular/core").InputSignal<boolean>;
|
|
6301
|
+
/** Total number of notes after every load / add / delete. */
|
|
6302
|
+
readonly totalChange: import("@angular/core").OutputEmitterRef<number>;
|
|
6303
|
+
private readonly http;
|
|
6304
|
+
private readonly toast;
|
|
6305
|
+
private readonly destroyRef;
|
|
6306
|
+
private readonly apiBase;
|
|
6307
|
+
readonly pageSize = 5;
|
|
6308
|
+
readonly notes: import("@angular/core").WritableSignal<NoteItem[]>;
|
|
6309
|
+
readonly loading: import("@angular/core").WritableSignal<boolean>;
|
|
6310
|
+
readonly saving: import("@angular/core").WritableSignal<boolean>;
|
|
6311
|
+
/** 0-based page index, as the server numbers it. */
|
|
6312
|
+
readonly page: import("@angular/core").WritableSignal<number>;
|
|
6313
|
+
readonly totalElements: import("@angular/core").WritableSignal<number>;
|
|
6314
|
+
readonly editingId: import("@angular/core").WritableSignal<string | null>;
|
|
6315
|
+
readonly deletingId: import("@angular/core").WritableSignal<string | null>;
|
|
6316
|
+
newBody: string;
|
|
6317
|
+
editBody: string;
|
|
6318
|
+
/** Up to two initials of the author's name for the avatar ("Ana Lopez" -> "AL"); "Y" for the current user's own unnamed notes. */
|
|
6319
|
+
protected initials(name: string): string;
|
|
6320
|
+
private get listUrl();
|
|
6321
|
+
constructor();
|
|
6322
|
+
loadPage(p: number): void;
|
|
6323
|
+
addNote(): void;
|
|
6324
|
+
startEdit(note: NoteItem): void;
|
|
6325
|
+
cancelEdit(): void;
|
|
6326
|
+
saveEdit(noteId: string): void;
|
|
6327
|
+
confirmDelete(id: string): void;
|
|
6328
|
+
deleteNote(): void;
|
|
6329
|
+
static ɵfac: i0.ɵɵFactoryDeclaration<NotesComponent, never>;
|
|
6330
|
+
static ɵcmp: i0.ɵɵComponentDeclaration<NotesComponent, "ui-notes", never, {
|
|
6331
|
+
"resourceType": {
|
|
6332
|
+
"alias": "resourceType";
|
|
6333
|
+
"required": false;
|
|
6334
|
+
"isSignal": true;
|
|
6335
|
+
};
|
|
6336
|
+
"resourceId": {
|
|
6337
|
+
"alias": "resourceId";
|
|
6338
|
+
"required": false;
|
|
6339
|
+
"isSignal": true;
|
|
6340
|
+
};
|
|
6341
|
+
"readOnly": {
|
|
6342
|
+
"alias": "readOnly";
|
|
6343
|
+
"required": false;
|
|
6344
|
+
"isSignal": true;
|
|
6345
|
+
};
|
|
6346
|
+
}, {
|
|
6347
|
+
"totalChange": "totalChange";
|
|
6348
|
+
}, never, never, true, never>;
|
|
6349
|
+
}
|
|
6108
6350
|
/**
|
|
6109
6351
|
* Adds one app-wide toast outlet (a `<ui-toast>` appended to `<body>`) when the app starts, so toasts show on pages that have
|
|
6110
6352
|
* no `<ui-data-table>` and no `<ui-toast />` of their own.
|
|
@@ -6539,7 +6781,7 @@ export interface PanelInfoItem {
|
|
|
6539
6781
|
phone?: string;
|
|
6540
6782
|
/** Show the value with an "open" icon instead of blue link styling. */
|
|
6541
6783
|
linkIcon?: boolean;
|
|
6542
|
-
/** Renders a small edit (pencil) icon button after the value. */
|
|
6784
|
+
/** Renders a small edit (pencil) `ui-icon` button after the value; `editTooltip` is its tooltip and accessible name (default "Edit"). */
|
|
6543
6785
|
editAction?: () => void;
|
|
6544
6786
|
editTooltip?: string;
|
|
6545
6787
|
muted?: boolean;
|
|
@@ -6996,7 +7238,7 @@ export declare class AlertComponent {
|
|
|
6996
7238
|
/** The SVG path (24×24 stroke icon) for an icon key, or undefined when the key is unknown. */
|
|
6997
7239
|
export declare function iconPath(name: string): string | undefined;
|
|
6998
7240
|
/** Keys with an icon of their own (the data-table action keys are accepted too — see `builtInActionIcon`). */
|
|
6999
|
-
export type IconName = 'add' | 'close' | 'check' | 'upload' | 'image' | 'chevron-up' | 'chevron-down' | 'arrow-left' | 'bell' | 'print' | 'lock' | 'shield' | 'arrow-up' | 'arrow-down' | 'arrow-right' | 'document' | 'grip' | 'card' | 'bank' | 'view' | 'view-off' | 'edit' | 'delete' | 'download' | 'duplicate' | 'archive' | 'restore' | 'share' | 'email' | 'message' | 'call' | 'refund' | 'chevron-right';
|
|
7241
|
+
export type IconName = 'add' | 'close' | 'check' | 'upload' | 'image' | 'chevron-up' | 'chevron-down' | 'arrow-left' | 'bell' | 'print' | 'lock' | 'shield' | 'arrow-up' | 'arrow-down' | 'arrow-right' | 'document' | 'grip' | 'card' | 'bank' | 'view' | 'view-off' | 'edit' | 'delete' | 'download' | 'duplicate' | 'archive' | 'restore' | 'share' | 'email' | 'message' | 'call' | 'refund' | 'chevron-right' | 'link' | 'save' | 'chart';
|
|
7000
7242
|
/**
|
|
7001
7243
|
* A clickable icon. The host passes a key (`name="delete"`) and the library draws that icon; clicking it emits
|
|
7002
7244
|
* `iconClick`, and the host does the actual work (delete the row, open a panel, …).
|
|
@@ -8524,6 +8766,8 @@ export declare class PdfHotspotComponent {
|
|
|
8524
8766
|
* - `background`: the card's background colour (any CSS colour; default white).
|
|
8525
8767
|
* - `headerBackground`: the background colour of the header bar only (any CSS colour; default none, the card's own background shows). The body keeps the card's `background`, and a header-less card (`showHeader` false) has no bar to colour. A collapsible header keeps this colour on hover. Pair it with `textColor` when the colour is dark.
|
|
8526
8768
|
* - `textColor`: the colour of the title, subtitle, chevron and body text (any CSS colour; default: the normal slate colours). Use it for light text on a dark `background`. Text you colour yourself inside the body keeps its own colour.
|
|
8769
|
+
* - `<ng-container card-footer>` / `<div card-footer>`: a footer bar under the body (a pager, totals, a link). Hidden while empty or collapsed, 10px 18px padding,
|
|
8770
|
+
* a light top line; `footerBackground` colours it (pair it with `headerBackground` to frame the card). In a `fill` card it is pinned to the bottom edge.
|
|
8527
8771
|
* - The body has built-in padding (16px 18px, matching the header's 18px side padding); there is no padding input.
|
|
8528
8772
|
* - `collapsible` (default true): a chevron toggle and a clickable header; `[(expanded)]` is two-way.
|
|
8529
8773
|
* Without a header, or with `collapsible` false, the body is always open.
|
|
@@ -8566,6 +8810,8 @@ export declare class DetailCardComponent {
|
|
|
8566
8810
|
readonly background: import("@angular/core").InputSignal<string>;
|
|
8567
8811
|
/** Background colour of the header bar only, as any CSS colour (`#eaf3ff`, `var(--surface-2)` …). Empty = the header has no colour of its own (the card background shows). The body is not affected. */
|
|
8568
8812
|
readonly headerBackground: import("@angular/core").InputSignal<string>;
|
|
8813
|
+
/** Background colour of the footer bar (the `[card-footer]` slot) as any CSS colour. Empty = no colour of its own. */
|
|
8814
|
+
readonly footerBackground: import("@angular/core").InputSignal<string>;
|
|
8569
8815
|
/** Text colour as any CSS colour (`#fff`, `var(--on-dark)` …). Empty = the default colours. Colours the title, subtitle, chevron and body text. */
|
|
8570
8816
|
readonly textColor: import("@angular/core").InputSignal<string>;
|
|
8571
8817
|
/** false = no header at all (no title, edit button, toggle or divider): the card is only the body, always open. */
|
|
@@ -8645,6 +8891,11 @@ export declare class DetailCardComponent {
|
|
|
8645
8891
|
"required": false;
|
|
8646
8892
|
"isSignal": true;
|
|
8647
8893
|
};
|
|
8894
|
+
"footerBackground": {
|
|
8895
|
+
"alias": "footerBackground";
|
|
8896
|
+
"required": false;
|
|
8897
|
+
"isSignal": true;
|
|
8898
|
+
};
|
|
8648
8899
|
"textColor": {
|
|
8649
8900
|
"alias": "textColor";
|
|
8650
8901
|
"required": false;
|
|
@@ -8719,7 +8970,7 @@ export declare class DetailCardComponent {
|
|
|
8719
8970
|
"expanded": "expandedChange";
|
|
8720
8971
|
"editClick": "editClick";
|
|
8721
8972
|
"selected": "selectedChange";
|
|
8722
|
-
}, never, ["[card-header-leading]", "[card-header]", "[card-header-action]", "*"], true, never>;
|
|
8973
|
+
}, never, ["[card-header-leading]", "[card-header]", "[card-header-action]", "*", "[card-footer]"], true, never>;
|
|
8723
8974
|
}
|
|
8724
8975
|
export type DividerSpace = 'none' | 'sm' | 'md' | 'lg';
|
|
8725
8976
|
/**
|
|
@@ -8760,6 +9011,204 @@ export declare class DividerComponent {
|
|
|
8760
9011
|
};
|
|
8761
9012
|
}, {}, never, never, true, never>;
|
|
8762
9013
|
}
|
|
9014
|
+
/** One column (stage) of a [ui-board]. `items` are the host's own records; the board never reads their fields. */
|
|
9015
|
+
export interface BoardColumn<T = unknown> {
|
|
9016
|
+
/** Unique id of the column (the stage key); reported in `from` / `to` of a move. */
|
|
9017
|
+
key: string;
|
|
9018
|
+
/** Column title (shown uppercase). */
|
|
9019
|
+
label: string;
|
|
9020
|
+
items: T[];
|
|
9021
|
+
/** Dot colour: a CSS colour, or one of blue / cyan / green / teal / amber / orange / red / pink / slate / gray. */
|
|
9022
|
+
color?: string;
|
|
9023
|
+
/** Small line under the title, e.g. a pre-formatted total ("$120,000"). */
|
|
9024
|
+
summary?: string;
|
|
9025
|
+
/** Spoken version of `summary` (aria-label). Defaults to the summary text. */
|
|
9026
|
+
summaryLabel?: string;
|
|
9027
|
+
/** 'success' = green column and green card edge (a won / done stage). */
|
|
9028
|
+
tone?: 'default' | 'success';
|
|
9029
|
+
/** true = display-only column: items can't be dropped into it. */
|
|
9030
|
+
dropDisabled?: boolean;
|
|
9031
|
+
/** Text of the empty column; defaults to the board's `emptyColumnText`. */
|
|
9032
|
+
emptyText?: string;
|
|
9033
|
+
}
|
|
9034
|
+
/** Fired when the user moves a card to another column (drag and drop, or Shift + Arrow keys on a focused card). */
|
|
9035
|
+
export interface BoardMoveEvent<T = unknown> {
|
|
9036
|
+
item: T;
|
|
9037
|
+
from: string;
|
|
9038
|
+
to: string;
|
|
9039
|
+
/** The board has ALREADY moved the card on screen. Call this if the host's save fails to put it back. */
|
|
9040
|
+
revert: () => void;
|
|
9041
|
+
}
|
|
9042
|
+
export interface BoardCardActionEvent<T = unknown> {
|
|
9043
|
+
type: string;
|
|
9044
|
+
item: T;
|
|
9045
|
+
}
|
|
9046
|
+
/** Context of the card template: `<ng-template uiBoardCard let-item let-column="column" let-menu="menu">`. */
|
|
9047
|
+
export interface BoardCardContext<T = unknown> {
|
|
9048
|
+
$implicit: T;
|
|
9049
|
+
column: BoardColumn<T>;
|
|
9050
|
+
/** Template of the card's "⋮" menu (renders nothing without `cardActions`). Output it with `{ $implicit: item }` in the card's top row. */
|
|
9051
|
+
menu: TemplateRef<{
|
|
9052
|
+
$implicit: T;
|
|
9053
|
+
}>;
|
|
9054
|
+
}
|
|
9055
|
+
/** Marks the template that renders the INSIDE of a card (the board draws the card frame, menu and drag handling). */
|
|
9056
|
+
export declare class BoardCardDirective<T = unknown> {
|
|
9057
|
+
readonly template: TemplateRef<BoardCardContext<T>>;
|
|
9058
|
+
static ngTemplateContextGuard<T>(_dir: BoardCardDirective<T>, _ctx: unknown): _ctx is BoardCardContext<T>;
|
|
9059
|
+
static ɵfac: i0.ɵɵFactoryDeclaration<BoardCardDirective<any>, never>;
|
|
9060
|
+
static ɵdir: i0.ɵɵDirectiveDeclaration<BoardCardDirective<any>, "ng-template[uiBoardCard]", never, {}, {}, never, never, true, never>;
|
|
9061
|
+
}
|
|
9062
|
+
/**
|
|
9063
|
+
* Kanban board: columns of cards that can be dragged between columns. Data and saving stay with the host.
|
|
9064
|
+
*
|
|
9065
|
+
* <ui-board [columns]="columns()" [itemKey]="key" [itemLabel]="label" [cardActions]="actions" [readOnly]="perm() !== 'full'"
|
|
9066
|
+
* [loading]="loading()" [error]="error()" (retry)="load()"
|
|
9067
|
+
* (cardClick)="open($event)" (cardAction)="onAction($event)" (itemMove)="onMove($event)">
|
|
9068
|
+
* <ng-template uiBoardCard let-deal let-menu="menu">
|
|
9069
|
+
* <div class="ub-card__top"><span class="ub-card__title">{{ deal.title }}</span>
|
|
9070
|
+
* <ng-container [ngTemplateOutlet]="menu" [ngTemplateOutletContext]="{ $implicit: deal }" /></div>
|
|
9071
|
+
* <div class="ub-card__contact">{{ deal.contactName }}</div>
|
|
9072
|
+
* </ng-template>
|
|
9073
|
+
* </ui-board>
|
|
9074
|
+
*
|
|
9075
|
+
* - A drop moves the card on screen at once and emits `itemMove`; the host saves it and calls `event.revert()` if that fails.
|
|
9076
|
+
* - Keyboard: Enter / Space opens a card; Shift + ← / → moves it to the neighbouring column (announced to screen readers).
|
|
9077
|
+
* - `readOnly` removes dragging and keyboard moves. On phones (≤640px) the columns stack.
|
|
9078
|
+
*/
|
|
9079
|
+
export declare class BoardComponent<T = unknown> {
|
|
9080
|
+
/** The columns in display order, each with its items. A new value replaces the board's content (and any on-screen move). */
|
|
9081
|
+
readonly columns: import("@angular/core").InputSignal<BoardColumn<T>[]>;
|
|
9082
|
+
/** Stable unique id of a card (used to track cards between renders). */
|
|
9083
|
+
readonly itemKey: import("@angular/core").InputSignal<(item: T) => string>;
|
|
9084
|
+
/** Spoken name of a card: title, who, status, value... The card's visible content is the `uiBoardCard` template. */
|
|
9085
|
+
readonly itemLabel: import("@angular/core").InputSignal<(item: T) => string>;
|
|
9086
|
+
/** Menu on every card (the "⋮" button). Empty = no menu. Handle the pick in `(cardAction)`. */
|
|
9087
|
+
readonly cardActions: import("@angular/core").InputSignal<RowAction[]>;
|
|
9088
|
+
readonly loading: import("@angular/core").InputSignal<boolean>;
|
|
9089
|
+
/** Error text: replaces the board with the message and a Retry button. */
|
|
9090
|
+
readonly error: import("@angular/core").InputSignal<string | null>;
|
|
9091
|
+
/** true = no dragging, no keyboard moves. */
|
|
9092
|
+
readonly readOnly: import("@angular/core").InputSignal<boolean>;
|
|
9093
|
+
/** true = moves are paused (e.g. a save is running) so a second card can't be moved before the first is saved. */
|
|
9094
|
+
readonly moveDisabled: import("@angular/core").InputSignal<boolean>;
|
|
9095
|
+
/** Optional rule: may this card go from this column to that one? A refused drop does nothing. */
|
|
9096
|
+
readonly canMove: import("@angular/core").InputSignal<((item: T, from: string, to: string) => boolean) | null>;
|
|
9097
|
+
readonly ariaLabel: import("@angular/core").InputSignal<string>;
|
|
9098
|
+
readonly emptyMessage: import("@angular/core").InputSignal<string>;
|
|
9099
|
+
readonly emptyColumnText: import("@angular/core").InputSignal<string>;
|
|
9100
|
+
/** Singular / plural noun for the column's spoken count ("3 deals"). */
|
|
9101
|
+
readonly itemNoun: import("@angular/core").InputSignal<string>;
|
|
9102
|
+
readonly itemNounPlural: import("@angular/core").InputSignal<string>;
|
|
9103
|
+
readonly retryLabel: import("@angular/core").InputSignal<string>;
|
|
9104
|
+
readonly cardClick: import("@angular/core").OutputEmitterRef<T>;
|
|
9105
|
+
readonly cardAction: import("@angular/core").OutputEmitterRef<BoardCardActionEvent<T>>;
|
|
9106
|
+
readonly itemMove: import("@angular/core").OutputEmitterRef<BoardMoveEvent<T>>;
|
|
9107
|
+
readonly retry: import("@angular/core").OutputEmitterRef<void>;
|
|
9108
|
+
protected readonly card: import("@angular/core").Signal<BoardCardDirective<any> | undefined>;
|
|
9109
|
+
/** The columns as shown: the host's value, plus any move not yet replaced by new data. */
|
|
9110
|
+
protected readonly cols: import("@angular/core").WritableSignal<BoardColumn<T>[]>;
|
|
9111
|
+
protected readonly overKey: import("@angular/core").WritableSignal<string | null>;
|
|
9112
|
+
protected readonly draggingKey: import("@angular/core").WritableSignal<string | null>;
|
|
9113
|
+
protected readonly announcement: import("@angular/core").WritableSignal<string>;
|
|
9114
|
+
private readonly host;
|
|
9115
|
+
private drag;
|
|
9116
|
+
protected readonly skeletonColumns: import("@angular/core").Signal<number[]>;
|
|
9117
|
+
protected readonly canDrag: import("@angular/core").Signal<boolean>;
|
|
9118
|
+
protected readonly canMoveAny: import("@angular/core").Signal<boolean>;
|
|
9119
|
+
protected dot(color?: string): string;
|
|
9120
|
+
protected onDragStart(event: DragEvent, item: T, col: BoardColumn<T>): void;
|
|
9121
|
+
protected onDragEnd(): void;
|
|
9122
|
+
protected onDragOver(event: DragEvent, col: BoardColumn<T>): void;
|
|
9123
|
+
protected onDragLeave(event: DragEvent, col: BoardColumn<T>): void;
|
|
9124
|
+
protected onDrop(event: DragEvent, col: BoardColumn<T>): void;
|
|
9125
|
+
protected onCardKey(event: KeyboardEvent, item: T, col: BoardColumn<T>): void;
|
|
9126
|
+
private accepts;
|
|
9127
|
+
private move;
|
|
9128
|
+
static ɵfac: i0.ɵɵFactoryDeclaration<BoardComponent<any>, never>;
|
|
9129
|
+
static ɵcmp: i0.ɵɵComponentDeclaration<BoardComponent<any>, "ui-board", never, {
|
|
9130
|
+
"columns": {
|
|
9131
|
+
"alias": "columns";
|
|
9132
|
+
"required": true;
|
|
9133
|
+
"isSignal": true;
|
|
9134
|
+
};
|
|
9135
|
+
"itemKey": {
|
|
9136
|
+
"alias": "itemKey";
|
|
9137
|
+
"required": true;
|
|
9138
|
+
"isSignal": true;
|
|
9139
|
+
};
|
|
9140
|
+
"itemLabel": {
|
|
9141
|
+
"alias": "itemLabel";
|
|
9142
|
+
"required": true;
|
|
9143
|
+
"isSignal": true;
|
|
9144
|
+
};
|
|
9145
|
+
"cardActions": {
|
|
9146
|
+
"alias": "cardActions";
|
|
9147
|
+
"required": false;
|
|
9148
|
+
"isSignal": true;
|
|
9149
|
+
};
|
|
9150
|
+
"loading": {
|
|
9151
|
+
"alias": "loading";
|
|
9152
|
+
"required": false;
|
|
9153
|
+
"isSignal": true;
|
|
9154
|
+
};
|
|
9155
|
+
"error": {
|
|
9156
|
+
"alias": "error";
|
|
9157
|
+
"required": false;
|
|
9158
|
+
"isSignal": true;
|
|
9159
|
+
};
|
|
9160
|
+
"readOnly": {
|
|
9161
|
+
"alias": "readOnly";
|
|
9162
|
+
"required": false;
|
|
9163
|
+
"isSignal": true;
|
|
9164
|
+
};
|
|
9165
|
+
"moveDisabled": {
|
|
9166
|
+
"alias": "moveDisabled";
|
|
9167
|
+
"required": false;
|
|
9168
|
+
"isSignal": true;
|
|
9169
|
+
};
|
|
9170
|
+
"canMove": {
|
|
9171
|
+
"alias": "canMove";
|
|
9172
|
+
"required": false;
|
|
9173
|
+
"isSignal": true;
|
|
9174
|
+
};
|
|
9175
|
+
"ariaLabel": {
|
|
9176
|
+
"alias": "ariaLabel";
|
|
9177
|
+
"required": false;
|
|
9178
|
+
"isSignal": true;
|
|
9179
|
+
};
|
|
9180
|
+
"emptyMessage": {
|
|
9181
|
+
"alias": "emptyMessage";
|
|
9182
|
+
"required": false;
|
|
9183
|
+
"isSignal": true;
|
|
9184
|
+
};
|
|
9185
|
+
"emptyColumnText": {
|
|
9186
|
+
"alias": "emptyColumnText";
|
|
9187
|
+
"required": false;
|
|
9188
|
+
"isSignal": true;
|
|
9189
|
+
};
|
|
9190
|
+
"itemNoun": {
|
|
9191
|
+
"alias": "itemNoun";
|
|
9192
|
+
"required": false;
|
|
9193
|
+
"isSignal": true;
|
|
9194
|
+
};
|
|
9195
|
+
"itemNounPlural": {
|
|
9196
|
+
"alias": "itemNounPlural";
|
|
9197
|
+
"required": false;
|
|
9198
|
+
"isSignal": true;
|
|
9199
|
+
};
|
|
9200
|
+
"retryLabel": {
|
|
9201
|
+
"alias": "retryLabel";
|
|
9202
|
+
"required": false;
|
|
9203
|
+
"isSignal": true;
|
|
9204
|
+
};
|
|
9205
|
+
}, {
|
|
9206
|
+
"cardClick": "cardClick";
|
|
9207
|
+
"cardAction": "cardAction";
|
|
9208
|
+
"itemMove": "itemMove";
|
|
9209
|
+
"retry": "retry";
|
|
9210
|
+
}, ["card"], never, true, never>;
|
|
9211
|
+
}
|
|
8763
9212
|
/**
|
|
8764
9213
|
* Wraps a block of form controls (a settings page, a configuration card) so a view-only user can look at the current
|
|
8765
9214
|
* values but change nothing. While `readOnly` is true the wrapper's native `<fieldset>` is `disabled`, and the browser
|