@forgeroute/ui 0.4.39 → 0.4.41
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 -2
- package/fesm2022/forgeroute-ui-messaging.mjs.map +1 -1
- package/fesm2022/forgeroute-ui-stripe.mjs +743 -5
- package/fesm2022/forgeroute-ui-stripe.mjs.map +1 -1
- package/fesm2022/forgeroute-ui.mjs +505 -65
- package/fesm2022/forgeroute-ui.mjs.map +1 -1
- package/package.json +1 -1
- package/types/forgeroute-ui-messaging.d.ts +4 -4
- package/types/forgeroute-ui-stripe.d.ts +246 -2
- package/types/forgeroute-ui.d.ts +192 -25
package/types/forgeroute-ui.d.ts
CHANGED
|
@@ -298,6 +298,8 @@ export type BulkUpdateOption<T = any> = string | {
|
|
|
298
298
|
* It is also the inline select's accessible name, the default confirm's title and confirm button, and the default confirm message reads
|
|
299
299
|
* "<label>: <option> for N items?" (instead of "Change <column> to <option> for N items?"). Host `confirm` copy still wins; its
|
|
300
300
|
* `ctx.columnLabel` stays the column's label. Trimmed; blank = ignored. Ignored for the reserved `delete` key. Omit it and nothing changes.
|
|
301
|
+
* Direct actions (`action: true`): the bar button text, default confirm title and confirm button (required in practice; trimmed,
|
|
302
|
+
* blank = the key split on `_`, `-` and camelCase with only the first word capitalised: 'resend' -> 'Resend', 'send_reminder' / 'sendReminder' -> 'Send reminder'); `ctx.columnLabel` is this label.
|
|
301
303
|
*
|
|
302
304
|
* { field: 'state', label: 'Archive / Restore' }
|
|
303
305
|
*/
|
|
@@ -330,8 +332,32 @@ export type BulkUpdateOption<T = any> = string | {
|
|
|
330
332
|
* { field: 'status', allowedFrom: { SENT: ['DRAFT'] }, canChange: (row, target) => target !== 'SENT' || canSend(row) }
|
|
331
333
|
*/
|
|
332
334
|
canChange?: (row: T, target: string) => boolean;
|
|
335
|
+
/**
|
|
336
|
+
* Direct bulk action (`{ field: 'resend', action: true, label: 'Resend' }`): a bulk-bar button that is neither a field change nor
|
|
337
|
+
* Delete. `field` is the action key (no column needed), the button type is `action-<field>` and there is no inline select.
|
|
338
|
+
* Clicking it opens the library confirm, then POSTs `<endpoint>/bulk/<field>` with exactly `{ ids }` (the eligible rows). The response is
|
|
339
|
+
* handled like a field change (`updated`, `skipped`, `notAllowed`, readable `message`). Ignored for the reserved `delete` key.
|
|
340
|
+
* Read-only users get no bulk bar, so nothing changes for them. Omit it and nothing changes.
|
|
341
|
+
* `confirm` on an action takes only the function form; a map (target value -> function) is ignored and the default copy is used.
|
|
342
|
+
*
|
|
343
|
+
* { field: 'resend', action: true, label: 'Resend', eligible: (row: Request) => row.status === 'PENDING' }
|
|
344
|
+
*/
|
|
345
|
+
action?: boolean;
|
|
346
|
+
/** Direct action only: button style, default 'secondary'. 'danger' also makes the default confirm button red. */
|
|
347
|
+
variant?: 'secondary' | 'danger';
|
|
348
|
+
/**
|
|
349
|
+
* Direct action only: true when the server will accept the action for this row (keep it identical to the backend rule). Rows it
|
|
350
|
+
* refuses are skipped (counted, NEVER sent; "N selected rows don't qualify for <label lower-cased> and will be skipped."). When no selected loaded row passes,
|
|
351
|
+
* the button is disabled with a visible reason ("None of the selected rows qualify for <label lower-cased>."). Omit it and every selected row is sent. A predicate that throws counts as "row not eligible" (never breaks rendering).
|
|
352
|
+
*/
|
|
353
|
+
eligible?: (row: T) => boolean;
|
|
354
|
+
/**
|
|
355
|
+
* Direct action only: the past-tense word in the result toast. "N <doneLabel>, M skipped." when anything was skipped / not allowed,
|
|
356
|
+
* else "N <itemLabel>(s) <doneLabel>.". Default 'updated'.
|
|
357
|
+
*/
|
|
358
|
+
doneLabel?: string;
|
|
333
359
|
};
|
|
334
|
-
/** What a bulk confirm function receives. For bulk Delete: `targetValue`/`targetLabel` are '', `columnLabel` is 'Delete', skipped counts are 0. */
|
|
360
|
+
/** What a bulk confirm function receives. For a direct bulk action: `columnLabel` is the action label, `targetValue`/`targetLabel` are '', `rows`/`skippedRows` the eligible / refused selected rows. For bulk Delete: `targetValue`/`targetLabel` are '', `columnLabel` is 'Delete', skipped counts are 0. */
|
|
335
361
|
export interface BulkConfirmContext<T = any> {
|
|
336
362
|
/** Rows that WILL be sent (eligible). For Delete: the selected count. */
|
|
337
363
|
count: number;
|
|
@@ -391,6 +417,12 @@ export interface BulkActionDef {
|
|
|
391
417
|
deletable?: (row: any) => boolean;
|
|
392
418
|
/** Field changes: per-row check that the server will accept the move to a target (from `{ field, canChange }`). */
|
|
393
419
|
canChange?: (row: any, target: string) => boolean;
|
|
420
|
+
/** True for a direct bulk action (from `{ field, action: true, label }`); `type` is `action-<key>` and `field` is not set (no inline select). */
|
|
421
|
+
action?: boolean;
|
|
422
|
+
/** Direct action: which rows the server will accept (from `{ field, action: true, eligible }`). */
|
|
423
|
+
eligible?: (row: any) => boolean;
|
|
424
|
+
/** Direct action: past-tense word in the result toast (from `{ doneLabel }`), default 'updated'. */
|
|
425
|
+
doneLabel?: string;
|
|
394
426
|
/**
|
|
395
427
|
* The item field this action targets (e.g. 'status', 'type').
|
|
396
428
|
* When set the table shows an inline select populated from the column's option sources.
|
|
@@ -1056,7 +1088,7 @@ export declare class SelectComponent implements ControlValueAccessor, Validator,
|
|
|
1056
1088
|
readonly error: import("@angular/core").InputSignal<string>;
|
|
1057
1089
|
/** Reveal the built-in error messages now (e.g. after a failed Save click), without waiting for blur. */
|
|
1058
1090
|
readonly showErrors: import("@angular/core").InputSignal<boolean>;
|
|
1059
|
-
readonly size: import("@angular/core").InputSignal<"
|
|
1091
|
+
readonly size: import("@angular/core").InputSignal<"default" | "sm">;
|
|
1060
1092
|
readonly _disabledInput: import("@angular/core").InputSignal<boolean>;
|
|
1061
1093
|
private readonly _cvaDisabled;
|
|
1062
1094
|
protected readonly disabled: import("@angular/core").Signal<boolean>;
|
|
@@ -1392,6 +1424,10 @@ export declare class DataTableComponent<T extends Record<string, any>> implement
|
|
|
1392
1424
|
* `[{ field: 'status', exclude: ['EXPIRED'] }, 'delete']` (see `BulkUpdateOption`).
|
|
1393
1425
|
* Use `{ field, allowedFrom: { TARGET: [sourceValues] } }` for a status workflow: only targets some selected row can
|
|
1394
1426
|
* legally move to are offered, and rows that can't move are skipped (never sent).
|
|
1427
|
+
* Use `{ field: 'resend', action: true, label: 'Resend', eligible?, confirm?, variant?, doneLabel? }` for a direct bulk action: a bar button
|
|
1428
|
+
* that confirms and POSTs `<endpoint>/bulk/<field>` with `{ ids }` of the eligible rows (no select, no column needed).
|
|
1429
|
+
* A blank `label` falls back to the key split on `_`, `-` and camelCase with only the first word capitalised ('send_reminder' -> 'Send reminder');
|
|
1430
|
+
* two actions with the same key collapse to the first; an `eligible` that throws counts as "row not eligible".
|
|
1395
1431
|
*/
|
|
1396
1432
|
readonly bulkUpdateOptions: import("@angular/core").InputSignal<BulkUpdateOption<T>[]>;
|
|
1397
1433
|
readonly rowClick: import("@angular/core").OutputEmitterRef<T>;
|
|
@@ -1582,9 +1618,14 @@ export declare class DataTableComponent<T extends Record<string, any>> implement
|
|
|
1582
1618
|
/**
|
|
1583
1619
|
* Derives internal action definitions from the `bulkUpdateOptions` string array.
|
|
1584
1620
|
* 'delete' → built-in danger action with table-managed confirm dialog.
|
|
1621
|
+
* `{ field, action: true, label }` → direct action (type `action-<key>`, no column needed, no select).
|
|
1585
1622
|
* Everything else → matched to a column: label = the entry's `label` when given, else "Change {col.label}"; options from column config.
|
|
1586
1623
|
*/
|
|
1587
1624
|
protected readonly _bulkDefs: Signal<BulkActionDef[]>;
|
|
1625
|
+
/** Fallback label of a direct action without one: splits the key on `_`, `-` and camelCase, capitalises the first word only ('send_reminder' / 'sendReminder' -> 'Send reminder'). */
|
|
1626
|
+
private _actionKeyLabel;
|
|
1627
|
+
/** Runs a direct action's `eligible` predicate; a predicate that throws counts as "row not eligible". */
|
|
1628
|
+
private _isActionEligible;
|
|
1588
1629
|
/** Options for a field-based bulk action: the field's options minus the entry's `exclude` values. */
|
|
1589
1630
|
private _bulkOptionsFor;
|
|
1590
1631
|
/** True when a row whose field currently holds `current` may be moved to `target` by this action. */
|
|
@@ -1638,12 +1679,20 @@ export declare class DataTableComponent<T extends Record<string, any>> implement
|
|
|
1638
1679
|
* skipped-rows sentence, appended on a new paragraph unless the copy sets `omitSkippedNote`.
|
|
1639
1680
|
*/
|
|
1640
1681
|
private _hostConfirm;
|
|
1641
|
-
/** Why a bulk action can't be used right now ('' = it can). Only Delete with `deletable` can be blocked. */
|
|
1682
|
+
/** Why a bulk action can't be used right now ('' = it can). Only Delete with `deletable` and a direct action with `eligible` can be blocked. */
|
|
1642
1683
|
protected _bulkBlockedReason(def: BulkActionDef): string;
|
|
1643
1684
|
/** The distinct reasons of the currently blocked bulk actions, shown as visible text next to the disabled buttons. */
|
|
1644
1685
|
protected _bulkBlockedHints(): string[];
|
|
1645
1686
|
/** Selected rows (loaded page) split by the delete option's `deletable` predicate; without it every selected row is deletable. */
|
|
1646
1687
|
private _deleteSplit;
|
|
1688
|
+
/** Selected rows (loaded page) split by a direct action's `eligible` predicate; without it every selected row is eligible. */
|
|
1689
|
+
private _actionSplit;
|
|
1690
|
+
/** Type of the direct bulk action whose request is in flight (null = none). */
|
|
1691
|
+
protected readonly _runningAction: import("@angular/core").WritableSignal<string | null>;
|
|
1692
|
+
/** True while a direct action's confirm dialog is open (guards against a second click). */
|
|
1693
|
+
private _confirmingAction;
|
|
1694
|
+
/** Direct bulk action: confirm, then POST `<endpoint>/bulk/<key>` with `{ ids }` of the eligible rows. */
|
|
1695
|
+
private _runDirectAction;
|
|
1647
1696
|
/** Called when the user clicks a bulk action button in the selection bar. */
|
|
1648
1697
|
protected onBulkActionClick(def: BulkActionDef): void;
|
|
1649
1698
|
/** True while the field-change confirmation dialog is open (guards against a second Apply click). */
|
|
@@ -1692,6 +1741,11 @@ export declare class DataTableComponent<T extends Record<string, any>> implement
|
|
|
1692
1741
|
*/
|
|
1693
1742
|
private _fetchCounts;
|
|
1694
1743
|
ngOnInit(): void;
|
|
1744
|
+
/**
|
|
1745
|
+
* Retry from the error state. A failed table shows no search box or quick tabs (there is nothing to search), so a search term that was
|
|
1746
|
+
* active when the request failed could not be cleared any more: the retry therefore asks for the unsearched list on page 1.
|
|
1747
|
+
*/
|
|
1748
|
+
protected _retryAfterError(): void;
|
|
1695
1749
|
protected onSearchChange(val: string): void;
|
|
1696
1750
|
/** Phone sort control: "Default" (value '') + one entry per sortable visible column and direction ("<key>:asc|desc"). */
|
|
1697
1751
|
protected readonly _phoneSortOptions: Signal<{
|
|
@@ -2751,7 +2805,7 @@ export declare class CheckboxComponent implements ControlValueAccessor, Validato
|
|
|
2751
2805
|
* clicking it still toggles the box - e.g. a product name that is both the heading of its card and the label of its checkbox.
|
|
2752
2806
|
* Default null: plain label text, exactly as before. Single mode only.
|
|
2753
2807
|
*/
|
|
2754
|
-
readonly headingLevel: import("@angular/core").InputSignal<
|
|
2808
|
+
readonly headingLevel: import("@angular/core").InputSignal<1 | 2 | 3 | 4 | 5 | 6 | null>;
|
|
2755
2809
|
readonly indeterminate: import("@angular/core").InputSignal<boolean>;
|
|
2756
2810
|
readonly checked: import("@angular/core").ModelSignal<boolean>;
|
|
2757
2811
|
/**
|
|
@@ -3662,7 +3716,7 @@ export declare class PhoneNumberPickerComponent {
|
|
|
3662
3716
|
protected readonly modeCtl: FormControl<string>;
|
|
3663
3717
|
protected readonly zipCtl: FormControl<string>;
|
|
3664
3718
|
protected readonly areaCtl: FormControl<string>;
|
|
3665
|
-
protected readonly step: import("@angular/core").WritableSignal<
|
|
3719
|
+
protected readonly step: import("@angular/core").WritableSignal<1 | 2 | 3>;
|
|
3666
3720
|
protected readonly mode: import("@angular/core").WritableSignal<PhoneNumberSearchMode>;
|
|
3667
3721
|
private readonly _zip;
|
|
3668
3722
|
private readonly _area;
|
|
@@ -3776,7 +3830,7 @@ export declare class ButtonComponent {
|
|
|
3776
3830
|
* `ghost-start`: a ghost button for list / section toggles - a full-width row with its content aligned to the start, transparent
|
|
3777
3831
|
* background, hover tint and the normal focus ring. Pair it with `ariaExpanded` / `ariaPressed`; the label may contain a heading element.
|
|
3778
3832
|
*/
|
|
3779
|
-
readonly variant: import("@angular/core").InputSignal<"
|
|
3833
|
+
readonly variant: import("@angular/core").InputSignal<"primary" | "secondary" | "danger" | "warning" | "link" | "ghost" | "ghost-start" | "tab" | "icon" | "icon-danger">;
|
|
3780
3834
|
/** Renders an anchor to this route instead of a button (use with `variant="link"` for an inline text link). `['/settings']` or `'/settings'`. While `disabled` or `loading` it renders a non-clickable `<span role="link" aria-disabled>` with no href (like `href`). */
|
|
3781
3835
|
readonly routerLink: import("@angular/core").InputSignal<string | readonly unknown[] | null>;
|
|
3782
3836
|
/** Query params of the `routerLink` (e.g. `{ section: 'deal-defaults' }`). */
|
|
@@ -3815,13 +3869,13 @@ export declare class ButtonComponent {
|
|
|
3815
3869
|
* shows when the viewport is narrower than this; from the width itself the long text shows (`640`: >= 640px long, < 640px short, like a
|
|
3816
3870
|
* `min-width: 640px` switch). Tokens are pure CSS; a number is tracked with `matchMedia`. Default `'md'`.
|
|
3817
3871
|
*/
|
|
3818
|
-
readonly shortBelow: import("@angular/core").InputSignal<number | "sm" | "
|
|
3872
|
+
readonly shortBelow: import("@angular/core").InputSignal<number | "sm" | "md" | "lg">;
|
|
3819
3873
|
/** Classes of the two label spans: the token class, or `btn-sl-narrow` while a pixel breakpoint is active. */
|
|
3820
3874
|
protected readonly _slClass: import("@angular/core").Signal<string>;
|
|
3821
3875
|
private readonly _narrow;
|
|
3822
3876
|
readonly color: import("@angular/core").InputSignal<string | undefined>;
|
|
3823
3877
|
readonly active: import("@angular/core").InputSignal<boolean>;
|
|
3824
|
-
readonly size: import("@angular/core").InputSignal<"sm" | "
|
|
3878
|
+
readonly size: import("@angular/core").InputSignal<"sm" | "md" | "lg" | "xs">;
|
|
3825
3879
|
readonly type: import("@angular/core").InputSignal<"reset" | "submit" | "button">;
|
|
3826
3880
|
readonly disabled: import("@angular/core").InputSignal<boolean>;
|
|
3827
3881
|
readonly loading: import("@angular/core").InputSignal<boolean>;
|
|
@@ -4254,7 +4308,7 @@ export declare class BulkMessagePanelComponent {
|
|
|
4254
4308
|
readonly sending: import("@angular/core").InputSignal<boolean>;
|
|
4255
4309
|
readonly closed: import("@angular/core").OutputEmitterRef<void>;
|
|
4256
4310
|
readonly send: import("@angular/core").OutputEmitterRef<BulkMessageSendEvent>;
|
|
4257
|
-
readonly channel: import("@angular/core").WritableSignal<"
|
|
4311
|
+
readonly channel: import("@angular/core").WritableSignal<"text" | "email">;
|
|
4258
4312
|
private readonly _subject;
|
|
4259
4313
|
private readonly _body;
|
|
4260
4314
|
get subject(): string;
|
|
@@ -4618,7 +4672,7 @@ export declare class TextInputComponent implements ControlValueAccessor, Validat
|
|
|
4618
4672
|
readonly passwordRequirements: import("@angular/core").InputSignal<boolean>;
|
|
4619
4673
|
/** Rules for `passwordRequirements`; default = the library's five rules (8+ characters, upper, lower, digit, special). */
|
|
4620
4674
|
readonly passwordRules: import("@angular/core").InputSignal<readonly PasswordRule[] | undefined>;
|
|
4621
|
-
readonly type: import("@angular/core").InputSignal<"number" | "
|
|
4675
|
+
readonly type: import("@angular/core").InputSignal<"number" | "text" | "email" | "tel" | "password" | "url">;
|
|
4622
4676
|
readonly maxlength: import("@angular/core").InputSignal<number | undefined>;
|
|
4623
4677
|
readonly required: import("@angular/core").InputSignal<boolean>;
|
|
4624
4678
|
readonly autocomplete: import("@angular/core").InputSignal<string>;
|
|
@@ -4627,7 +4681,7 @@ export declare class TextInputComponent implements ControlValueAccessor, Validat
|
|
|
4627
4681
|
* `search`, `text`, `none`). Empty (default) = the browser's default for the field, except `type="tel"`, which keeps `tel`.
|
|
4628
4682
|
* It only picks the keyboard; it does not restrict what can be typed or pasted.
|
|
4629
4683
|
*/
|
|
4630
|
-
readonly inputmode: import("@angular/core").InputSignal<"" | "
|
|
4684
|
+
readonly inputmode: import("@angular/core").InputSignal<"" | "none" | "text" | "search" | "email" | "tel" | "url" | "decimal" | "numeric">;
|
|
4631
4685
|
readonly readonly: import("@angular/core").InputSignal<boolean>;
|
|
4632
4686
|
readonly hint: import("@angular/core").InputSignal<string>;
|
|
4633
4687
|
readonly error: import("@angular/core").InputSignal<string>;
|
|
@@ -4691,7 +4745,7 @@ export declare class TextInputComponent implements ControlValueAccessor, Validat
|
|
|
4691
4745
|
protected readonly _stepAttr: import("@angular/core").Signal<string | null>;
|
|
4692
4746
|
protected readonly _revealable: import("@angular/core").Signal<boolean>;
|
|
4693
4747
|
protected readonly _shown: import("@angular/core").WritableSignal<boolean>;
|
|
4694
|
-
protected readonly _inputType: import("@angular/core").Signal<"number" | "
|
|
4748
|
+
protected readonly _inputType: import("@angular/core").Signal<"number" | "text" | "email" | "tel" | "password" | "url">;
|
|
4695
4749
|
protected readonly _eyePath: string;
|
|
4696
4750
|
protected readonly _eyeOffPath: string;
|
|
4697
4751
|
protected readonly _showRequirements: import("@angular/core").Signal<boolean>;
|
|
@@ -6031,7 +6085,11 @@ export interface DropdownItem {
|
|
|
6031
6085
|
count?: number;
|
|
6032
6086
|
/** Greyed-out, not selectable and skipped by keyboard navigation. */
|
|
6033
6087
|
disabled?: boolean;
|
|
6088
|
+
/** Optional 14px icon before the label: an SVG path (the `d` value, like a toolbar action's `icon`). Decorative (hidden from assistive tech). */
|
|
6089
|
+
icon?: string;
|
|
6034
6090
|
}
|
|
6091
|
+
/** Which edge of the trigger the menu lines up with: `auto` (default) opens from the trigger's left edge and switches to its right edge when the menu would run off the right of the screen. */
|
|
6092
|
+
export type DropdownAlign = 'auto' | 'start' | 'end';
|
|
6035
6093
|
export declare class DropdownComponent {
|
|
6036
6094
|
readonly label: import("@angular/core").InputSignal<string>;
|
|
6037
6095
|
readonly items: import("@angular/core").InputSignal<DropdownItem[]>;
|
|
@@ -6048,12 +6106,19 @@ export declare class DropdownComponent {
|
|
|
6048
6106
|
*/
|
|
6049
6107
|
readonly ariaLabel: import("@angular/core").InputSignal<string>;
|
|
6050
6108
|
readonly itemClick: import("@angular/core").OutputEmitterRef<DropdownItem>;
|
|
6109
|
+
/** Which edge of the trigger the menu lines up with (default `auto`: from the left edge, switching to the right edge when it would run off the screen). */
|
|
6110
|
+
readonly align: import("@angular/core").InputSignal<DropdownAlign>;
|
|
6051
6111
|
protected readonly open: import("@angular/core").WritableSignal<boolean>;
|
|
6052
6112
|
protected readonly loading: import("@angular/core").WritableSignal<boolean>;
|
|
6113
|
+
/** Placement measured when the menu opens: right-aligned, above the trigger, and the height left on that side (the menu scrolls inside it). */
|
|
6114
|
+
protected readonly alignEnd: import("@angular/core").WritableSignal<boolean>;
|
|
6115
|
+
protected readonly openUp: import("@angular/core").WritableSignal<boolean>;
|
|
6116
|
+
protected readonly menuMaxHeight: import("@angular/core").WritableSignal<number | null>;
|
|
6053
6117
|
private readonly _loaded;
|
|
6054
6118
|
private readonly _id;
|
|
6055
6119
|
private readonly _host;
|
|
6056
6120
|
private readonly _cdr;
|
|
6121
|
+
private readonly _injector;
|
|
6057
6122
|
private _pendingFocus;
|
|
6058
6123
|
private _typeahead;
|
|
6059
6124
|
private _typeaheadTimer;
|
|
@@ -6083,6 +6148,12 @@ export declare class DropdownComponent {
|
|
|
6083
6148
|
protected onMenuKeydown(event: KeyboardEvent): void;
|
|
6084
6149
|
protected onEscape(event: Event): void;
|
|
6085
6150
|
private _setOpen;
|
|
6151
|
+
/**
|
|
6152
|
+
* Places the open menu from its measured size and the trigger's screen position: it keeps 16px clear of the screen edges, lines up with the trigger's
|
|
6153
|
+
* right edge instead of the left when that is the side with room (`align` = auto), opens above the trigger when there is more room there, and is capped to
|
|
6154
|
+
* the room left on that side (so it scrolls inside only when it truly does not fit). No layout APIs (server rendering) = the default placement.
|
|
6155
|
+
*/
|
|
6156
|
+
private _place;
|
|
6086
6157
|
private _openAndFocus;
|
|
6087
6158
|
/** Renders the menu synchronously, then focuses the pending first / last enabled item. */
|
|
6088
6159
|
private _focusPending;
|
|
@@ -6131,6 +6202,11 @@ export declare class DropdownComponent {
|
|
|
6131
6202
|
"required": false;
|
|
6132
6203
|
"isSignal": true;
|
|
6133
6204
|
};
|
|
6205
|
+
"align": {
|
|
6206
|
+
"alias": "align";
|
|
6207
|
+
"required": false;
|
|
6208
|
+
"isSignal": true;
|
|
6209
|
+
};
|
|
6134
6210
|
}, {
|
|
6135
6211
|
"itemClick": "itemClick";
|
|
6136
6212
|
}, never, never, true, never>;
|
|
@@ -6220,7 +6296,7 @@ export declare class FormSectionComponent {
|
|
|
6220
6296
|
}, {}, never, ["*"], true, never>;
|
|
6221
6297
|
}
|
|
6222
6298
|
export declare class FormRowComponent {
|
|
6223
|
-
readonly cols: import("@angular/core").InputSignal<
|
|
6299
|
+
readonly cols: import("@angular/core").InputSignal<1 | 2 | 3 | 4>;
|
|
6224
6300
|
static ɵfac: i0.ɵɵFactoryDeclaration<FormRowComponent, never>;
|
|
6225
6301
|
static ɵcmp: i0.ɵɵComponentDeclaration<FormRowComponent, "ui-form-row", never, {
|
|
6226
6302
|
"cols": {
|
|
@@ -6237,7 +6313,7 @@ export declare class FormRowComponent {
|
|
|
6237
6313
|
* child simply takes the full width. Keep a numeric span within the row's `cols` (use `all` for the whole row).
|
|
6238
6314
|
*/
|
|
6239
6315
|
export declare class FormColSpanDirective {
|
|
6240
|
-
readonly uiColSpan: import("@angular/core").InputSignal<"" |
|
|
6316
|
+
readonly uiColSpan: import("@angular/core").InputSignal<"" | "2" | "3" | 2 | 3 | "all">;
|
|
6241
6317
|
protected readonly _class: import("@angular/core").Signal<string>;
|
|
6242
6318
|
static ɵfac: i0.ɵɵFactoryDeclaration<FormColSpanDirective, never>;
|
|
6243
6319
|
static ɵdir: i0.ɵɵDirectiveDeclaration<FormColSpanDirective, "[uiColSpan]", never, {
|
|
@@ -7259,11 +7335,11 @@ export declare class ChipComponent implements ControlValueAccessor {
|
|
|
7259
7335
|
*/
|
|
7260
7336
|
export declare class ChipGroupComponent {
|
|
7261
7337
|
/** Space between each chip. */
|
|
7262
|
-
readonly gap: import("@angular/core").InputSignal<"sm" | "
|
|
7338
|
+
readonly gap: import("@angular/core").InputSignal<"sm" | "md" | "lg">;
|
|
7263
7339
|
/** Space above the chip group. */
|
|
7264
|
-
readonly spaceAbove: import("@angular/core").InputSignal<"
|
|
7340
|
+
readonly spaceAbove: import("@angular/core").InputSignal<"none" | "sm" | "md">;
|
|
7265
7341
|
/** Space below the chip group. */
|
|
7266
|
-
readonly spaceBelow: import("@angular/core").InputSignal<"
|
|
7342
|
+
readonly spaceBelow: import("@angular/core").InputSignal<"none" | "sm" | "md">;
|
|
7267
7343
|
protected readonly _gap: import("@angular/core").Signal<"6px" | "12px" | "8px">;
|
|
7268
7344
|
protected readonly _spaceAbove: import("@angular/core").Signal<"0" | "6px" | "12px">;
|
|
7269
7345
|
protected readonly _spaceBelow: import("@angular/core").Signal<"0" | "6px" | "12px">;
|
|
@@ -7523,6 +7599,8 @@ export declare class AlertComponent {
|
|
|
7523
7599
|
* Default false: the body is a flex row with a gap, exactly as before (use it for text plus a button).
|
|
7524
7600
|
*/
|
|
7525
7601
|
readonly inline: import("@angular/core").InputSignal<boolean>;
|
|
7602
|
+
/** The box fills the height of its parent cell (two alerts in one grid row get the same height whatever their text length). Default false. */
|
|
7603
|
+
readonly fill: import("@angular/core").InputSignal<boolean>;
|
|
7526
7604
|
readonly dismissed: import("@angular/core").OutputEmitterRef<void>;
|
|
7527
7605
|
static ɵfac: i0.ɵɵFactoryDeclaration<AlertComponent, never>;
|
|
7528
7606
|
static ɵcmp: i0.ɵɵComponentDeclaration<AlertComponent, "ui-alert", never, {
|
|
@@ -7561,6 +7639,11 @@ export declare class AlertComponent {
|
|
|
7561
7639
|
"required": false;
|
|
7562
7640
|
"isSignal": true;
|
|
7563
7641
|
};
|
|
7642
|
+
"fill": {
|
|
7643
|
+
"alias": "fill";
|
|
7644
|
+
"required": false;
|
|
7645
|
+
"isSignal": true;
|
|
7646
|
+
};
|
|
7564
7647
|
}, {
|
|
7565
7648
|
"dismissed": "dismissed";
|
|
7566
7649
|
}, never, ["*"], true, never>;
|
|
@@ -9171,7 +9254,7 @@ export declare class DetailCardComponent {
|
|
|
9171
9254
|
/** true (default) = the title is displayed in capitals (CSS only); false = shown as written. The text, aria-label and heading name are never changed. */
|
|
9172
9255
|
readonly uppercaseTitle: import("@angular/core").InputSignal<boolean>;
|
|
9173
9256
|
/** 1-6 makes the title a real heading for screen readers (role=heading, aria-level); null keeps it plain text. */
|
|
9174
|
-
readonly headingLevel: import("@angular/core").InputSignal<
|
|
9257
|
+
readonly headingLevel: import("@angular/core").InputSignal<1 | 2 | 3 | 4 | 5 | 6 | null>;
|
|
9175
9258
|
/** Optional id for the title text; the card is then labelled by it. Without it the title is the card's aria-label. */
|
|
9176
9259
|
readonly titleId: import("@angular/core").InputSignal<string>;
|
|
9177
9260
|
/** Accessible name of the card when the header gives none (no header, or no title). A visible title wins; blank = no name. */
|
|
@@ -9204,6 +9287,8 @@ export declare class DetailCardComponent {
|
|
|
9204
9287
|
readonly editAriaLabel: import("@angular/core").InputSignal<string>;
|
|
9205
9288
|
/** true = the card fills the height of its container (a grid cell / flex item) so sibling cards line up; the body grows. Spacing between cells comes from the gap: the filled card's margin-bottom is 0. Default false: unchanged. */
|
|
9206
9289
|
readonly fill: import("@angular/core").InputSignal<boolean>;
|
|
9290
|
+
/** Max height of the card body (any CSS length, e.g. `360px`): a longer body scrolls inside the card so the card never gets crazy long. Empty = no limit (or the `--dc-body-max-height` custom property, which a page can set on the card or an ancestor). */
|
|
9291
|
+
readonly maxBodyHeight: import("@angular/core").InputSignal<string>;
|
|
9207
9292
|
/** true = a click on the card (outside interactive controls and text selections) toggles `selected`. The card must contain its own checkbox for keyboard / screen-reader users. Default false: no handler, cursor or outline. */
|
|
9208
9293
|
readonly selectable: import("@angular/core").InputSignal<boolean>;
|
|
9209
9294
|
/** Two-way: whether the card is selected (only shown / toggled when `selectable`). */
|
|
@@ -9318,6 +9403,11 @@ export declare class DetailCardComponent {
|
|
|
9318
9403
|
"required": false;
|
|
9319
9404
|
"isSignal": true;
|
|
9320
9405
|
};
|
|
9406
|
+
"maxBodyHeight": {
|
|
9407
|
+
"alias": "maxBodyHeight";
|
|
9408
|
+
"required": false;
|
|
9409
|
+
"isSignal": true;
|
|
9410
|
+
};
|
|
9321
9411
|
"selectable": {
|
|
9322
9412
|
"alias": "selectable";
|
|
9323
9413
|
"required": false;
|
|
@@ -9383,6 +9473,55 @@ export declare class DividerComponent {
|
|
|
9383
9473
|
};
|
|
9384
9474
|
}, {}, never, never, true, never>;
|
|
9385
9475
|
}
|
|
9476
|
+
export type FixedFooterAlign = 'start' | 'center' | 'end' | 'between';
|
|
9477
|
+
/**
|
|
9478
|
+
* A footer bar fixed to the bottom of the page: it stays visible while the page scrolls, sits flush with the bottom of the viewport
|
|
9479
|
+
* and spans the full width of the content area (from the side nav to the end of the screen). Put it as the LAST child of the page:
|
|
9480
|
+
*
|
|
9481
|
+
* <div class="settings-page">
|
|
9482
|
+
* ...the page content...
|
|
9483
|
+
* <ui-fixed-footer>
|
|
9484
|
+
* <ui-button variant="primary" (click)="save()">Save All Settings</ui-button>
|
|
9485
|
+
* </ui-fixed-footer>
|
|
9486
|
+
* </div>
|
|
9487
|
+
*
|
|
9488
|
+
* How it works: the bar is `position: sticky` at the bottom of the scrolling page. Inside `ui-app-shell` the content area is padded
|
|
9489
|
+
* (24px / 16px / 12px by width) and the shell publishes that padding as `--shell-content-padding`; the footer cancels it with negative
|
|
9490
|
+
* margins and a negative `bottom`, so it reaches the viewport edges instead of stopping inside the padding. Outside the shell the
|
|
9491
|
+
* variable is unset (0px) and the bar simply sticks to the bottom of its scrolling parent. Nothing else needs to be set up.
|
|
9492
|
+
*
|
|
9493
|
+
* Inputs:
|
|
9494
|
+
* - `align` (default `end`): where the projected content sits: start | center | end | between.
|
|
9495
|
+
* - `ariaLabel` (default `Page actions`): the accessible name of the bar (a labelled region).
|
|
9496
|
+
* - `elevated` (default true): the soft shadow above the bar; false = just the top border.
|
|
9497
|
+
* Theming by CSS custom properties: `--ui-footer-bg` (white), `--ui-footer-border` (#e2e8f0), `--ui-footer-pad-y` (20px; 16px up to 1024px, 14px up to 480px).
|
|
9498
|
+
*/
|
|
9499
|
+
export declare class FixedFooterComponent {
|
|
9500
|
+
/** Where the projected content sits in the bar. */
|
|
9501
|
+
readonly align: import("@angular/core").InputSignal<FixedFooterAlign>;
|
|
9502
|
+
/** Accessible name of the bar. */
|
|
9503
|
+
readonly ariaLabel: import("@angular/core").InputSignal<string>;
|
|
9504
|
+
/** The soft shadow above the bar (false = only the top border). */
|
|
9505
|
+
readonly elevated: import("@angular/core").InputSignal<boolean>;
|
|
9506
|
+
static ɵfac: i0.ɵɵFactoryDeclaration<FixedFooterComponent, never>;
|
|
9507
|
+
static ɵcmp: i0.ɵɵComponentDeclaration<FixedFooterComponent, "ui-fixed-footer", never, {
|
|
9508
|
+
"align": {
|
|
9509
|
+
"alias": "align";
|
|
9510
|
+
"required": false;
|
|
9511
|
+
"isSignal": true;
|
|
9512
|
+
};
|
|
9513
|
+
"ariaLabel": {
|
|
9514
|
+
"alias": "ariaLabel";
|
|
9515
|
+
"required": false;
|
|
9516
|
+
"isSignal": true;
|
|
9517
|
+
};
|
|
9518
|
+
"elevated": {
|
|
9519
|
+
"alias": "elevated";
|
|
9520
|
+
"required": false;
|
|
9521
|
+
"isSignal": true;
|
|
9522
|
+
};
|
|
9523
|
+
}, {}, never, ["*"], true, never>;
|
|
9524
|
+
}
|
|
9386
9525
|
/** One column (stage) of a [ui-board]. `items` are the host's own records; the board never reads their fields. */
|
|
9387
9526
|
export interface BoardColumn<T = unknown> {
|
|
9388
9527
|
/** Unique id of the column (the stage key); reported in `from` / `to` of a move. */
|
|
@@ -9921,7 +10060,7 @@ export declare class SectionHeaderComponent {
|
|
|
9921
10060
|
/** 1px border and 10px corners. */
|
|
9922
10061
|
readonly bordered: import("@angular/core").InputSignal<boolean>;
|
|
9923
10062
|
/** Visual size: 'sm', 'md' (default), 'lg' or 'xl'. Independent of `level`; anything else renders as 'md'. */
|
|
9924
|
-
readonly size: import("@angular/core").InputSignal<"sm" | "
|
|
10063
|
+
readonly size: import("@angular/core").InputSignal<"sm" | "md" | "lg" | "xl">;
|
|
9925
10064
|
/** Remove the built-in top padding. */
|
|
9926
10065
|
readonly noPaddingTop: import("@angular/core").InputSignal<boolean>;
|
|
9927
10066
|
/** Remove the built-in left padding. */
|
|
@@ -11005,8 +11144,8 @@ export declare class ShowComponent {
|
|
|
11005
11144
|
readonly from: import("@angular/core").InputSignal<ShowBreakpoint | null>;
|
|
11006
11145
|
readonly below: import("@angular/core").InputSignal<ShowBreakpoint | null>;
|
|
11007
11146
|
private readonly win;
|
|
11008
|
-
protected readonly fromToken: import("@angular/core").Signal<"sm" | "
|
|
11009
|
-
protected readonly belowToken: import("@angular/core").Signal<"sm" | "
|
|
11147
|
+
protected readonly fromToken: import("@angular/core").Signal<"sm" | "md" | "lg" | null>;
|
|
11148
|
+
protected readonly belowToken: import("@angular/core").Signal<"sm" | "md" | "lg" | null>;
|
|
11010
11149
|
protected readonly fromMatch: import("@angular/core").WritableSignal<boolean>;
|
|
11011
11150
|
protected readonly belowMatch: import("@angular/core").WritableSignal<boolean>;
|
|
11012
11151
|
constructor();
|
|
@@ -11230,12 +11369,13 @@ export interface IntegrationPlainText {
|
|
|
11230
11369
|
export declare function integrationPlainText(html: string): IntegrationPlainText;
|
|
11231
11370
|
/**
|
|
11232
11371
|
* How a connect button for an integration works.
|
|
11233
|
-
* - `oauth`: GET `authorizeEndpoint` answers `{ url }` and the browser goes there (QuickBooks, Slack, Gmail, Outlook, Google / Outlook calendar).
|
|
11372
|
+
* - `oauth`: GET `authorizeEndpoint` answers `{ url }` (or `{ authUrl }`) and the browser goes there (in a NEW tab with `newTab: true`, opened inside the click so popup blockers allow it, else in this tab) (QuickBooks, Slack, Gmail, Outlook, Google / Outlook calendar, Stripe, Square).
|
|
11234
11373
|
* - `area-code`: asks for a US area code and POSTs `{ areaCode }` to `connectEndpoint` (Twilio buys a number that way); the status is reloaded after.
|
|
11235
11374
|
*/
|
|
11236
11375
|
export type SetupIntegrationConnect = {
|
|
11237
11376
|
type: 'oauth';
|
|
11238
11377
|
authorizeEndpoint: string;
|
|
11378
|
+
newTab?: boolean;
|
|
11239
11379
|
} | {
|
|
11240
11380
|
type: 'area-code';
|
|
11241
11381
|
connectEndpoint: string;
|
|
@@ -11282,6 +11422,8 @@ export interface SetupWizardTexts {
|
|
|
11282
11422
|
selectSource: string;
|
|
11283
11423
|
connected: string;
|
|
11284
11424
|
importMore: string;
|
|
11425
|
+
/** The link on an import step (before data came in) that downloads the template CSV: the header row and the config's `templateSampleRows`, so the user can add their data to it. */
|
|
11426
|
+
downloadSample: string;
|
|
11285
11427
|
/** Shown (and described by the disabled Continue) on an import step with `requireImport` until data came in. */
|
|
11286
11428
|
importRequired: string;
|
|
11287
11429
|
/** An import where some rows were refused: the warning's title and text (rows that failed must be fixed and imported again before Continue) and the button that returns to the sources. */
|
|
@@ -11311,6 +11453,8 @@ export interface SetupImportStep {
|
|
|
11311
11453
|
buttonLabel: string;
|
|
11312
11454
|
/** Hint above the button. */
|
|
11313
11455
|
hint?: string;
|
|
11456
|
+
/** Text of the template download link, e.g. "Download Products/Services CSV Template" (default: the `downloadSample` text, "Download CSV Template"). The file is this step's own template: the config's field labels and `templateSampleRows`. */
|
|
11457
|
+
templateLabel?: string;
|
|
11314
11458
|
/** Result alert title, built from the number imported (default `${n} ${config.entityNamePlural.toLowerCase()} imported successfully.`). */
|
|
11315
11459
|
resultTitle?: (imported: number) => string;
|
|
11316
11460
|
/** Result alert body. */
|
|
@@ -11373,7 +11517,9 @@ export interface SetupWizardApi {
|
|
|
11373
11517
|
markCompleted(...keys: string[]): void;
|
|
11374
11518
|
}
|
|
11375
11519
|
/**
|
|
11376
|
-
* The integrations every app can offer in a setup step.
|
|
11520
|
+
* The integrations every app can offer in a setup step. Payment processing (`stripe`, `square`) belongs in almost every app's wizard:
|
|
11521
|
+
* `setupIntegrations('stripe', 'square')` is the ready-made "connect payments" step (an app that has one processor passes just that one; the
|
|
11522
|
+
* backend answers 409 when the other is already connected, and the step shows it). The endpoints follow the convention the apps' backends already use (`GET <x>/status`,
|
|
11377
11523
|
* `GET <x>/authorize` answering `{ url }`); an app whose routes differ spreads a preset and overrides what differs:
|
|
11378
11524
|
* `{ ...SETUP_INTEGRATIONS['quickbooks'], statusEndpoint: '/accounting/status' }`.
|
|
11379
11525
|
*/
|
|
@@ -11465,7 +11611,7 @@ export declare class SetupWizardComponent {
|
|
|
11465
11611
|
/** An import step with `requireImport` keeps Continue off until something came in (a CSV import or `markCompleted`, e.g. a live sync). */
|
|
11466
11612
|
protected readonly importBlocked: import("@angular/core").Signal<boolean>;
|
|
11467
11613
|
/** The step's own two parts (`splitLayout`) show as two tabs, one card at a time; this is the open one (it starts on the app's part on every visit). */
|
|
11468
|
-
protected readonly splitTab: import("@angular/core").WritableSignal<"
|
|
11614
|
+
protected readonly splitTab: import("@angular/core").WritableSignal<"main" | "extra">;
|
|
11469
11615
|
protected readonly splitTabs: import("@angular/core").Signal<{
|
|
11470
11616
|
key: string;
|
|
11471
11617
|
label: string;
|
|
@@ -11475,6 +11621,8 @@ export declare class SetupWizardComponent {
|
|
|
11475
11621
|
readonly steps: import("@angular/core").InputSignal<SetupStep[]>;
|
|
11476
11622
|
/** Replaces any of the built-in texts. */
|
|
11477
11623
|
readonly texts: import("@angular/core").InputSignal<Partial<SetupWizardTexts>>;
|
|
11624
|
+
/** The key of the step to open first (for example the one a payment provider's return address names); default (empty or unknown) = the first step. Read once, when the wizard starts. */
|
|
11625
|
+
readonly initialStep: import("@angular/core").InputSignal<string>;
|
|
11478
11626
|
/** The last step's button ("Go to Dashboard"). */
|
|
11479
11627
|
readonly finished: import("@angular/core").OutputEmitterRef<void>;
|
|
11480
11628
|
/** "Exit Setup". */
|
|
@@ -11494,6 +11642,12 @@ export declare class SetupWizardComponent {
|
|
|
11494
11642
|
private readonly importErrors;
|
|
11495
11643
|
private readonly statuses;
|
|
11496
11644
|
readonly busy: import("@angular/core").WritableSignal<boolean>;
|
|
11645
|
+
/** Key of the integration whose authorization address is being requested: only that card's button shows a loader (the footer's Save & Continue is not busy), and no second press starts a second connection. */
|
|
11646
|
+
protected readonly connecting: import("@angular/core").WritableSignal<string>;
|
|
11647
|
+
/** The blank tab opened on the Connect click (the click is the user gesture; the address arrives later), or null when none was opened / the browser blocked it. */
|
|
11648
|
+
private pendingTab;
|
|
11649
|
+
/** A provider's page was opened in another tab: when this tab becomes visible again the step's statuses are read again. */
|
|
11650
|
+
private connectTabOpened;
|
|
11497
11651
|
/** What a custom step's template receives (`let-wizard`). */
|
|
11498
11652
|
protected readonly api: SetupWizardApi;
|
|
11499
11653
|
protected readonly error: import("@angular/core").WritableSignal<string>;
|
|
@@ -11541,6 +11695,8 @@ export declare class SetupWizardComponent {
|
|
|
11541
11695
|
private messageOf;
|
|
11542
11696
|
/** A source card was picked on the step itself: opens the import window already past its source step (at the upload step for that source). */
|
|
11543
11697
|
protected startImport(key: string, source: string): void;
|
|
11698
|
+
/** The sample CSV (the import window's template): the field labels as the header row and the config's example rows. */
|
|
11699
|
+
protected downloadSample(): void;
|
|
11544
11700
|
protected openImport(key: string): void;
|
|
11545
11701
|
protected onImported(key: string): void;
|
|
11546
11702
|
protected importResult(key: string): number | null;
|
|
@@ -11553,12 +11709,18 @@ export declare class SetupWizardComponent {
|
|
|
11553
11709
|
protected isConnected(i: SetupIntegration): boolean;
|
|
11554
11710
|
protected detailFor(i: SetupIntegration): string;
|
|
11555
11711
|
protected connect(i: SetupIntegration): void;
|
|
11712
|
+
/** Opens an empty tab for the provider's page (null when the browser refuses; the address then opens in this tab). */
|
|
11713
|
+
protected openTab(): Window | null;
|
|
11714
|
+
private closePendingTab;
|
|
11556
11715
|
private startConnect;
|
|
11716
|
+
private isWebAddress;
|
|
11557
11717
|
/** SVG path of a library icon (the buttons' leading / trailing glyph). */
|
|
11558
11718
|
protected iconD(name: string): string;
|
|
11559
11719
|
protected areaCodeLabelFor(i: SetupIntegration): string;
|
|
11560
|
-
/**
|
|
11720
|
+
/** Opens the provider's authorization page: in the tab opened on the click, else (a blocked tab) in this one. */
|
|
11561
11721
|
protected redirect(url: string): void;
|
|
11722
|
+
/** Sends THIS tab to the address (no new tab was opened, the browser refused it or the user closed it). */
|
|
11723
|
+
protected navigateHere(url: string): void;
|
|
11562
11724
|
protected submitAreaCode(i: SetupIntegration): void;
|
|
11563
11725
|
static ɵfac: i0.ɵɵFactoryDeclaration<SetupWizardComponent, never>;
|
|
11564
11726
|
static ɵcmp: i0.ɵɵComponentDeclaration<SetupWizardComponent, "ui-setup-wizard", never, {
|
|
@@ -11572,6 +11734,11 @@ export declare class SetupWizardComponent {
|
|
|
11572
11734
|
"required": false;
|
|
11573
11735
|
"isSignal": true;
|
|
11574
11736
|
};
|
|
11737
|
+
"initialStep": {
|
|
11738
|
+
"alias": "initialStep";
|
|
11739
|
+
"required": false;
|
|
11740
|
+
"isSignal": true;
|
|
11741
|
+
};
|
|
11575
11742
|
}, {
|
|
11576
11743
|
"finished": "finished";
|
|
11577
11744
|
"exited": "exited";
|