fold-ng 0.3.0 → 0.5.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/CHANGELOG.md +376 -1
- package/README.md +136 -50
- package/fesm2022/fold-ng.mjs +3968 -1251
- package/fesm2022/fold-ng.mjs.map +1 -1
- package/llms.txt +1 -1
- package/package.json +1 -1
- package/tokens/primitives.css +19 -0
- package/tokens/scales.css +11 -0
- package/tokens/semantic.css +238 -0
- package/types/fold-ng.d.ts +1443 -72
- package/types/fold-ng.d.ts.map +1 -1
package/types/fold-ng.d.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import * as _angular_core from '@angular/core';
|
|
2
|
-
import {
|
|
3
|
-
import { FormValueControl, ValidationError } from '@angular/forms/signals';
|
|
2
|
+
import { InjectionToken, Provider, TemplateRef, ElementRef, Signal, Type, Injector, InputSignal, WritableSignal } from '@angular/core';
|
|
3
|
+
import { FormValueControl, ValidationError, FormCheckboxControl } from '@angular/forms/signals';
|
|
4
4
|
|
|
5
5
|
/**
|
|
6
6
|
* `<fold-app-shell>` — the responsive application skeleton.
|
|
@@ -238,11 +238,17 @@ type FoldAvatarRingStyle = "solid" | "dotted";
|
|
|
238
238
|
* (so the same seed is the same colour everywhere, and one `registry.use(...)`
|
|
239
239
|
* recolours every avatar).
|
|
240
240
|
*
|
|
241
|
+
* A broken `imageUrl` falls back to the initials rather than the browser's
|
|
242
|
+
* broken-image glyph (and retries when the URL changes).
|
|
243
|
+
*
|
|
241
244
|
* Three orthogonal state axes compose: `variant` (fill), `muted` (presence —
|
|
242
245
|
* dim for an absence/inactive person), and `ring` + `ringStyle` (a status
|
|
243
246
|
* outline). The component stays domain-agnostic: a screen maps its own states
|
|
244
247
|
* (e.g. absent → `[muted]`, a scheduled arrival → `ring="accent"`
|
|
245
|
-
* `ringStyle="dotted"`), the avatar just draws the primitives.
|
|
248
|
+
* `ringStyle="dotted"`), the avatar just draws the primitives. The ring is a
|
|
249
|
+
* redundant emphasis cue — never the sole carrier of a state — because on a
|
|
250
|
+
* light page a soft status hue (amber/green) can't clear WCAG 3:1 as a thin
|
|
251
|
+
* line (status-ring-contrast.spec.ts).
|
|
246
252
|
*
|
|
247
253
|
* ## Inputs
|
|
248
254
|
*
|
|
@@ -253,12 +259,19 @@ type FoldAvatarRingStyle = "solid" | "dotted";
|
|
|
253
259
|
* | `colorSeed` | `string` | `name` | String used to pick the deterministic colour. |
|
|
254
260
|
* | `variant` | `'solid' \| 'ghost'` | `'solid'` | `'ghost'` renders a dashed border (for guests). |
|
|
255
261
|
* | `square` | `boolean` | `false` | Square shape with a small radius (for orgs). |
|
|
256
|
-
* | `imageUrl` | `string` | — | Image/logo URL. Replaces initials when set.
|
|
262
|
+
* | `imageUrl` | `string` | — | Image/logo URL. Replaces initials when set; falls back to initials if it fails to load. |
|
|
257
263
|
* | `muted` | `boolean` | `false` | Dim the avatar (same hue, less intense) — absence / inactive. |
|
|
258
264
|
* | `ring` | `FoldAvatarRing` | `'none'` | A status outline (`accent`/`info`/`warning`/`alert`/`success`). |
|
|
259
265
|
* | `ringStyle` | `'solid' \| 'dotted'` | `'solid'` | Ring line style — `dotted` for scheduled/tentative states. |
|
|
260
266
|
*
|
|
261
267
|
* @selector `fold-avatar`
|
|
268
|
+
*
|
|
269
|
+
* @example
|
|
270
|
+
* ```html
|
|
271
|
+
* <fold-avatar name="Clément Aubry" size="lg" />
|
|
272
|
+
* <fold-avatar name="Léa Petit" ring="accent" ringStyle="dotted" />
|
|
273
|
+
* <fold-avatar name="Acme Corp" square imageUrl="/logo.svg" />
|
|
274
|
+
* ```
|
|
262
275
|
*/
|
|
263
276
|
declare class FoldAvatarComponent {
|
|
264
277
|
private readonly palette;
|
|
@@ -274,7 +287,14 @@ declare class FoldAvatarComponent {
|
|
|
274
287
|
readonly ring: _angular_core.InputSignal<FoldAvatarRing>;
|
|
275
288
|
/** Ring line style — `'dotted'` for scheduled / tentative states. */
|
|
276
289
|
readonly ringStyle: _angular_core.InputSignal<FoldAvatarRingStyle>;
|
|
277
|
-
/**
|
|
290
|
+
/** True once the `<img>` fails to load. Resets whenever `imageUrl` changes,
|
|
291
|
+
* so a corrected URL is retried rather than staying on the fallback. */
|
|
292
|
+
protected readonly imageFailed: _angular_core.WritableSignal<boolean>;
|
|
293
|
+
/** Show the image only when a URL is set AND it has not failed — a broken URL
|
|
294
|
+
* falls back to the initials instead of the browser's broken-image glyph. */
|
|
295
|
+
protected readonly showImage: _angular_core.Signal<boolean>;
|
|
296
|
+
/** Readable ink for the initials — the higher-contrast of dark/light ink on
|
|
297
|
+
* the fill, so a custom palette stays legible. */
|
|
278
298
|
protected readonly onColor: _angular_core.Signal<string>;
|
|
279
299
|
readonly initials: _angular_core.Signal<string>;
|
|
280
300
|
/** Deterministic fill from the active palette (via the shared registry). */
|
|
@@ -308,6 +328,12 @@ declare class FoldAvatarComponent {
|
|
|
308
328
|
* | `ringStyle` | `'solid' \| 'dotted'` | `'solid'` | Ring line style (`dotted` = scheduled). |
|
|
309
329
|
*
|
|
310
330
|
* @selector `fold-avatar-detail`
|
|
331
|
+
*
|
|
332
|
+
* @example
|
|
333
|
+
* ```html
|
|
334
|
+
* <fold-avatar-detail primary="Alex Rivers" secondary="alex@sh3pherd.dev" />
|
|
335
|
+
* <fold-avatar-detail primary="Acme Corp" secondary="Organisation" square />
|
|
336
|
+
* ```
|
|
311
337
|
*/
|
|
312
338
|
declare class FoldAvatarDetailComponent {
|
|
313
339
|
readonly primary: _angular_core.InputSignal<string>;
|
|
@@ -821,6 +847,186 @@ declare class FoldToggleIconComponent {
|
|
|
821
847
|
static ɵcmp: _angular_core.ɵɵComponentDeclaration<FoldToggleIconComponent, "fold-toggle-icon", never, { "icon": { "alias": "icon"; "required": true; "isSignal": true; }; "shape": { "alias": "shape"; "required": false; "isSignal": true; }; "size": { "alias": "size"; "required": false; "isSignal": true; }; "tone": { "alias": "tone"; "required": false; "isSignal": true; }; "active": { "alias": "active"; "required": false; "isSignal": true; }; "disabled": { "alias": "disabled"; "required": false; "isSignal": true; }; "loading": { "alias": "loading"; "required": false; "isSignal": true; }; "tooltip": { "alias": "tooltip"; "required": false; "isSignal": true; }; "type": { "alias": "type"; "required": false; "isSignal": true; }; }, { "active": "activeChange"; "toggled": "toggled"; }, never, never, true, never>;
|
|
822
848
|
}
|
|
823
849
|
|
|
850
|
+
/**
|
|
851
|
+
* Every user-facing / accessible string the inline-confirm renders. The
|
|
852
|
+
* `typePrompt` is a function of the value to match, so a locale can reword the
|
|
853
|
+
* whole sentence rather than translate a fixed template. All defaults are
|
|
854
|
+
* English — a non-English app overrides them once via
|
|
855
|
+
* {@link provideFoldInlineConfirmLabels}, or per instance via the `labels` input.
|
|
856
|
+
*/
|
|
857
|
+
interface FoldInlineConfirmLabels {
|
|
858
|
+
/** Label of the confirm button. */
|
|
859
|
+
readonly confirm: string;
|
|
860
|
+
/** Label of the cancel button. */
|
|
861
|
+
readonly cancel: string;
|
|
862
|
+
/** `aria-label` of the icon-only cancel button (`cancelIcon`). */
|
|
863
|
+
readonly cancelAria: string;
|
|
864
|
+
/** Confirm-button label while `loading`. */
|
|
865
|
+
readonly busy: string;
|
|
866
|
+
/** Accessible name of the confirmation group that replaces the trigger. */
|
|
867
|
+
readonly group: string;
|
|
868
|
+
/** Placeholder + prompt for the secret field (`password`, no `match`). */
|
|
869
|
+
readonly secret: string;
|
|
870
|
+
/** The type-to-confirm prompt, e.g. `("prod") => "Type prod to confirm"`. */
|
|
871
|
+
readonly typePrompt: (match: string) => string;
|
|
872
|
+
}
|
|
873
|
+
/** The English defaults — the base every override merges onto. */
|
|
874
|
+
declare const FOLD_INLINE_CONFIRM_DEFAULT_LABELS: FoldInlineConfirmLabels;
|
|
875
|
+
/** App-wide inline-confirm labels; defaults to English. */
|
|
876
|
+
declare const FOLD_INLINE_CONFIRM_LABELS: InjectionToken<FoldInlineConfirmLabels>;
|
|
877
|
+
/**
|
|
878
|
+
* Provide app-wide inline-confirm labels once at bootstrap. Partial — any key
|
|
879
|
+
* you omit keeps its English default.
|
|
880
|
+
*
|
|
881
|
+
* @example
|
|
882
|
+
* ```ts
|
|
883
|
+
* // app.config.ts
|
|
884
|
+
* providers: [
|
|
885
|
+
* provideFoldInlineConfirmLabels({
|
|
886
|
+
* confirm: "Confirmer",
|
|
887
|
+
* cancel: "Annuler",
|
|
888
|
+
* typePrompt: (m) => `Saisissez ${m} pour confirmer`,
|
|
889
|
+
* }),
|
|
890
|
+
* ];
|
|
891
|
+
* ```
|
|
892
|
+
*/
|
|
893
|
+
declare function provideFoldInlineConfirmLabels(labels: Partial<FoldInlineConfirmLabels>): Provider;
|
|
894
|
+
|
|
895
|
+
/**
|
|
896
|
+
* `<fold-inline-confirm>` — an in-place "are you sure?" affordance. The host
|
|
897
|
+
* projects a **trigger** (a real, focusable control — a `foldButton`, a
|
|
898
|
+
* `fold-button-icon`); on activation the trigger is replaced *in the same slot*
|
|
899
|
+
* by a confirm/cancel row, so a destructive action is guarded without a modal
|
|
900
|
+
* and without the layout jumping. Emits `confirmed` / `cancelled`.
|
|
901
|
+
*
|
|
902
|
+
* Three families, chosen by input:
|
|
903
|
+
*
|
|
904
|
+
* - **Simple** (default) — trigger → `Confirm` · `Cancel`. `confirmed` emits `""`.
|
|
905
|
+
* - **Type-to-confirm** — set `match`: the confirm button stays disabled until
|
|
906
|
+
* the user types the value (case-insensitive, trimmed). `confirmed` emits the
|
|
907
|
+
* typed text.
|
|
908
|
+
* - **Secret** — set `password` (no `match`): a masked field that confirms once
|
|
909
|
+
* non-empty. `confirmed` emits the secret, so a handler can post it to the
|
|
910
|
+
* server (which is the only place a password can actually be checked).
|
|
911
|
+
*
|
|
912
|
+
* `Escape` cancels; `Enter` in the field confirms when valid. Opening moves
|
|
913
|
+
* focus to the field (typed families) or the confirm button (simple), and
|
|
914
|
+
* cancelling returns focus to the trigger.
|
|
915
|
+
*
|
|
916
|
+
* @selector `fold-inline-confirm`
|
|
917
|
+
*
|
|
918
|
+
* @example
|
|
919
|
+
* ```html
|
|
920
|
+
* <!-- simple -->
|
|
921
|
+
* <fold-inline-confirm (confirmed)="remove()">
|
|
922
|
+
* <fold-button-icon icon="trash" tooltip="Delete" />
|
|
923
|
+
* </fold-inline-confirm>
|
|
924
|
+
*
|
|
925
|
+
* <!-- type-to-confirm -->
|
|
926
|
+
* <fold-inline-confirm [match]="node.name" (confirmed)="archive()">
|
|
927
|
+
* <button foldButton emphasis="outline" intent="danger">Delete node</button>
|
|
928
|
+
* </fold-inline-confirm>
|
|
929
|
+
*
|
|
930
|
+
* <!-- password-gated -->
|
|
931
|
+
* <fold-inline-confirm password (confirmed)="deleteAccount($event)">
|
|
932
|
+
* <button foldButton intent="danger">Delete account</button>
|
|
933
|
+
* </fold-inline-confirm>
|
|
934
|
+
*
|
|
935
|
+
* <!-- async: keep it open + show a spinner until the request settles -->
|
|
936
|
+
* <fold-inline-confirm
|
|
937
|
+
* keepOpenOnConfirm
|
|
938
|
+
* [loading]="pending()"
|
|
939
|
+
* [(open)]="confirmOpen"
|
|
940
|
+
* confirmIcon="bin"
|
|
941
|
+
* cancelIcon="close"
|
|
942
|
+
* (confirmed)="onDelete()">
|
|
943
|
+
* <fold-button-icon icon="bin" tooltip="Delete" />
|
|
944
|
+
* </fold-inline-confirm>
|
|
945
|
+
* ```
|
|
946
|
+
*/
|
|
947
|
+
declare class FoldInlineConfirmComponent {
|
|
948
|
+
private readonly defaults;
|
|
949
|
+
/** Intent (colour) of the confirm button. @default "danger" */
|
|
950
|
+
readonly intent: _angular_core.InputSignal<FoldButtonIntent>;
|
|
951
|
+
/** Optional warning shown above the confirm row. */
|
|
952
|
+
readonly message: _angular_core.InputSignal<string | undefined>;
|
|
953
|
+
/**
|
|
954
|
+
* The exact text the user must type to confirm (type-to-confirm family).
|
|
955
|
+
* Empty → the simple family. Matching is case-insensitive + trimmed.
|
|
956
|
+
*/
|
|
957
|
+
readonly match: _angular_core.InputSignal<string>;
|
|
958
|
+
/**
|
|
959
|
+
* Mask the field and confirm on any non-empty value (secret family). A
|
|
960
|
+
* password can't be verified in the browser, so this only *collects* it —
|
|
961
|
+
* `confirmed` emits it for the handler to send to the server. Ignored when
|
|
962
|
+
* `match` is set.
|
|
963
|
+
*/
|
|
964
|
+
readonly password: _angular_core.InputSignalWithTransform<boolean, unknown>;
|
|
965
|
+
/** Placeholder for the typed / secret field. */
|
|
966
|
+
readonly placeholder: _angular_core.InputSignal<string | undefined>;
|
|
967
|
+
/** Pending state — disables the buttons and shows the `busy` label. */
|
|
968
|
+
readonly loading: _angular_core.InputSignalWithTransform<boolean, unknown>;
|
|
969
|
+
/** Control density. @default "sm" */
|
|
970
|
+
readonly size: _angular_core.InputSignal<FoldButtonSize>;
|
|
971
|
+
/** Optional leading icon on the confirm button (e.g. `"bin"` on "Delete"). */
|
|
972
|
+
readonly confirmIcon: _angular_core.InputSignal<FoldIconName | undefined>;
|
|
973
|
+
/**
|
|
974
|
+
* Render the cancel as an icon-only button of the given icon (e.g. `"close"`)
|
|
975
|
+
* instead of a labelled button. Unset → a labelled cancel. The name is your
|
|
976
|
+
* choice from the icon registry.
|
|
977
|
+
*/
|
|
978
|
+
readonly cancelIcon: _angular_core.InputSignal<FoldIconName | undefined>;
|
|
979
|
+
/**
|
|
980
|
+
* Keep the affordance open after `confirmed` fires, so an async handler can
|
|
981
|
+
* show `loading` and then close it via `[(open)]`. Default: close on confirm
|
|
982
|
+
* (the right behaviour for synchronous / optimistic actions).
|
|
983
|
+
*/
|
|
984
|
+
readonly keepOpenOnConfirm: _angular_core.InputSignalWithTransform<boolean, unknown>;
|
|
985
|
+
/** Per-instance label overrides, merged over the app-wide + English defaults. */
|
|
986
|
+
readonly labels: _angular_core.InputSignal<Partial<FoldInlineConfirmLabels> | undefined>;
|
|
987
|
+
/** Emitted when the user confirms — carries the typed text (or `""`). */
|
|
988
|
+
readonly confirmed: _angular_core.OutputEmitterRef<string>;
|
|
989
|
+
/** Emitted when the user cancels (button or `Escape`). */
|
|
990
|
+
readonly cancelled: _angular_core.OutputEmitterRef<void>;
|
|
991
|
+
/**
|
|
992
|
+
* Whether the confirm affordance (vs. the trigger) is showing. Two-way, so a
|
|
993
|
+
* parent can drive it — open it programmatically, or close it when an async
|
|
994
|
+
* `confirmed` handler settles (paired with `keepOpenOnConfirm`).
|
|
995
|
+
*/
|
|
996
|
+
readonly open: _angular_core.ModelSignal<boolean>;
|
|
997
|
+
/** The text currently typed in the field. */
|
|
998
|
+
protected readonly typed: _angular_core.WritableSignal<string>;
|
|
999
|
+
private readonly triggerEl;
|
|
1000
|
+
private readonly groupEl;
|
|
1001
|
+
/** SSR-safe id tying the message to the confirm group. */
|
|
1002
|
+
protected readonly msgId: string;
|
|
1003
|
+
/** Effective labels: English defaults ← app-wide provider ← per-instance input. */
|
|
1004
|
+
protected readonly l: _angular_core.Signal<FoldInlineConfirmLabels>;
|
|
1005
|
+
/** True when a value must be typed before confirming. */
|
|
1006
|
+
protected readonly needsInput: _angular_core.Signal<boolean>;
|
|
1007
|
+
/** Whether the typed value satisfies the gate (match, or non-empty secret). */
|
|
1008
|
+
protected readonly inputValid: _angular_core.Signal<boolean>;
|
|
1009
|
+
/** The confirm button is live once the gate is satisfied and nothing pends. */
|
|
1010
|
+
protected readonly canConfirm: _angular_core.Signal<boolean>;
|
|
1011
|
+
protected readonly fieldType: _angular_core.Signal<"text" | "password">;
|
|
1012
|
+
/** Prompt above a typed field: the match sentence, or the secret label. */
|
|
1013
|
+
protected readonly prompt: _angular_core.Signal<string>;
|
|
1014
|
+
/** Has the affordance ever opened? Gates focus-return so mount doesn't steal. */
|
|
1015
|
+
private opened;
|
|
1016
|
+
constructor();
|
|
1017
|
+
/** Start the confirm flow (called by the projected trigger's click). */
|
|
1018
|
+
protected activate(): void;
|
|
1019
|
+
/** Complete the confirmation, emitting the typed value (or `""`). */
|
|
1020
|
+
protected confirm(): void;
|
|
1021
|
+
/** Abort and restore the trigger (focus returns via the render effect). */
|
|
1022
|
+
protected cancel(): void;
|
|
1023
|
+
static ɵfac: _angular_core.ɵɵFactoryDeclaration<FoldInlineConfirmComponent, never>;
|
|
1024
|
+
static ɵcmp: _angular_core.ɵɵComponentDeclaration<FoldInlineConfirmComponent, "fold-inline-confirm", never, { "intent": { "alias": "intent"; "required": false; "isSignal": true; }; "message": { "alias": "message"; "required": false; "isSignal": true; }; "match": { "alias": "match"; "required": false; "isSignal": true; }; "password": { "alias": "password"; "required": false; "isSignal": true; }; "placeholder": { "alias": "placeholder"; "required": false; "isSignal": true; }; "loading": { "alias": "loading"; "required": false; "isSignal": true; }; "size": { "alias": "size"; "required": false; "isSignal": true; }; "confirmIcon": { "alias": "confirmIcon"; "required": false; "isSignal": true; }; "cancelIcon": { "alias": "cancelIcon"; "required": false; "isSignal": true; }; "keepOpenOnConfirm": { "alias": "keepOpenOnConfirm"; "required": false; "isSignal": true; }; "labels": { "alias": "labels"; "required": false; "isSignal": true; }; "open": { "alias": "open"; "required": false; "isSignal": true; }; }, { "confirmed": "confirmed"; "cancelled": "cancelled"; "open": "openChange"; }, never, ["*"], true, never>;
|
|
1025
|
+
}
|
|
1026
|
+
|
|
1027
|
+
/** Which band(s) carry a chrome treatment (a separator hairline or a raised
|
|
1028
|
+
* tint): neither, just the header, just the footer, or both. */
|
|
1029
|
+
type FoldCardBandChrome = "none" | "header" | "footer" | "both";
|
|
824
1030
|
/**
|
|
825
1031
|
* `<fold-card>` — the canonical raised content surface: a solid
|
|
826
1032
|
* `surface-card` background, a hairline border and a consistent radius. Use it
|
|
@@ -829,14 +1035,19 @@ declare class FoldToggleIconComponent {
|
|
|
829
1035
|
*
|
|
830
1036
|
* - `surface` — `card` (the raised card tint, default) · `sunken` (a deeper
|
|
831
1037
|
* surface for large containers, below the card — the ref's second card tint;
|
|
832
|
-
* pairs with a fainter `border-subtle` hairline)
|
|
1038
|
+
* pairs with a fainter `border-subtle` hairline) · `accent` (an accent-filled
|
|
1039
|
+
* card whose content sub-tree auto-inverts to a compatible on-accent palette).
|
|
833
1040
|
* - `radius` — `lg` (14px, default) · `md` · `sm`.
|
|
834
1041
|
* - `padding` — `md` (16px, default) · `none` · `sm` · `lg`. Sets the *body*
|
|
835
1042
|
* padding; override with a custom value via `--fold-card-padding`.
|
|
836
|
-
* - `interactive` —
|
|
837
|
-
* - `separators` —
|
|
838
|
-
*
|
|
839
|
-
*
|
|
1043
|
+
* - `interactive` — makes the whole card a clickable control (see below).
|
|
1044
|
+
* - `separators` — which bands get a hairline against the body:
|
|
1045
|
+
* `none` (default) · `header` · `footer` · `both`.
|
|
1046
|
+
* - `raisedBands` — which bands are tinted a step above the surface (fainter on
|
|
1047
|
+
* `sunken`): `none` (default) · `header` · `footer` · `both`.
|
|
1048
|
+
*
|
|
1049
|
+
* `separators` and `raisedBands` are per-band and independent axes, so a card can
|
|
1050
|
+
* have (say) a raised, un-separated header over a flush footer.
|
|
840
1051
|
*
|
|
841
1052
|
* Content projection:
|
|
842
1053
|
* - default slot → the card body.
|
|
@@ -848,10 +1059,18 @@ declare class FoldToggleIconComponent {
|
|
|
848
1059
|
* never pads. So the content padding is identical whether or not the bands show —
|
|
849
1060
|
* toggling a header/footer never shifts the body.
|
|
850
1061
|
*
|
|
1062
|
+
* **Interactive cards.** `interactive` turns the whole card into a real control:
|
|
1063
|
+
* the host gains `role="button"`, `tabindex="0"`, a focus ring and a hover lift,
|
|
1064
|
+
* and Enter / Space (or a click) emit `(activated)`. Give it an accessible name
|
|
1065
|
+
* with `ariaLabel` when the card's text isn't a sufficient label.
|
|
1066
|
+
* A `role="button"` must not wrap other interactive controls — so an interactive
|
|
1067
|
+
* card must NOT contain buttons/links. For a card with its own inner actions,
|
|
1068
|
+
* keep it non-interactive and put a single primary `<a>`/`<button>` inside.
|
|
1069
|
+
*
|
|
851
1070
|
* ```html
|
|
852
1071
|
* <fold-card>Static content</fold-card>
|
|
853
1072
|
* <fold-card surface="sunken" padding="lg">Deep container</fold-card>
|
|
854
|
-
* <fold-card separators>
|
|
1073
|
+
* <fold-card separators="both">
|
|
855
1074
|
* <h3 cardHeader>Title</h3>
|
|
856
1075
|
* Body content
|
|
857
1076
|
* <div cardFooter>Actions</div>
|
|
@@ -863,24 +1082,49 @@ declare class FoldToggleIconComponent {
|
|
|
863
1082
|
* (default `clip`) lets content escape the rounded corners.
|
|
864
1083
|
*
|
|
865
1084
|
* @selector `fold-card`
|
|
1085
|
+
*
|
|
1086
|
+
* @example
|
|
1087
|
+
* ```html
|
|
1088
|
+
* <fold-card interactive ariaLabel="Open Acme Records" (activated)="open()">
|
|
1089
|
+
* <h3>Acme Records</h3>
|
|
1090
|
+
* <p>128 contracts · 96 active</p>
|
|
1091
|
+
* </fold-card>
|
|
1092
|
+
* ```
|
|
866
1093
|
*/
|
|
867
1094
|
declare class FoldCardComponent {
|
|
868
|
-
/** Surface tint — `card` (raised, default)
|
|
869
|
-
|
|
1095
|
+
/** Surface tint — `card` (raised, default), `sunken` (deeper container), or
|
|
1096
|
+
* `accent` (an **accent-filled** card: the accent colour as ground, with the
|
|
1097
|
+
* whole content sub-tree auto-inverted to a compatible on-accent role-set —
|
|
1098
|
+
* text, borders, band gradation, and even nested buttons/links/icon-tiles
|
|
1099
|
+
* convert automatically). Use it to make a card in a grid stand out. */
|
|
1100
|
+
readonly surface: _angular_core.InputSignal<"accent" | "card" | "sunken">;
|
|
870
1101
|
/** Corner radius — `lg` (default), `md`, or `sm`. */
|
|
871
1102
|
readonly radius: _angular_core.InputSignal<"sm" | "md" | "lg">;
|
|
872
1103
|
/** Body padding — `md` (default), `none`, `sm`, or `lg`; a custom value can be
|
|
873
1104
|
* set with the `--fold-card-padding` CSS variable. */
|
|
874
1105
|
readonly padding: _angular_core.InputSignal<"none" | "sm" | "md" | "lg">;
|
|
875
|
-
/**
|
|
876
|
-
|
|
877
|
-
|
|
878
|
-
readonly
|
|
879
|
-
/**
|
|
880
|
-
|
|
881
|
-
|
|
1106
|
+
/** Make the whole card a clickable control: `role="button"` + `tabindex`, a
|
|
1107
|
+
* focus ring, a hover lift, and Enter/Space/click → `(activated)`. Must not
|
|
1108
|
+
* wrap other interactive controls (see the class docs). */
|
|
1109
|
+
readonly interactive: _angular_core.InputSignalWithTransform<boolean, unknown>;
|
|
1110
|
+
/** Accessible name for the interactive card, when its content isn't enough. */
|
|
1111
|
+
readonly ariaLabel: _angular_core.InputSignal<string | undefined>;
|
|
1112
|
+
/** Which bands get a hairline against the body — `none` (default), `header`,
|
|
1113
|
+
* `footer`, or `both`. */
|
|
1114
|
+
readonly separators: _angular_core.InputSignal<FoldCardBandChrome>;
|
|
1115
|
+
/** Which bands are lifted with a subtle raised tint over the card surface
|
|
1116
|
+
* (fainter on `sunken`) — `none` (default), `header`, `footer`, or `both`. */
|
|
1117
|
+
readonly raisedBands: _angular_core.InputSignal<FoldCardBandChrome>;
|
|
1118
|
+
/** Fires when an `interactive` card is activated (click, Enter, or Space). */
|
|
1119
|
+
readonly activated: _angular_core.OutputEmitterRef<Event>;
|
|
1120
|
+
/** Whether a per-band chrome value applies to the given band. */
|
|
1121
|
+
protected hasBand(value: FoldCardBandChrome, band: "header" | "footer"): boolean;
|
|
1122
|
+
protected onActivate(event: Event): void;
|
|
1123
|
+
/** Enter/Space activate the card, matching the native button keyboard contract
|
|
1124
|
+
* (Space is prevented from scrolling the page). */
|
|
1125
|
+
protected onKeydown(event: KeyboardEvent): void;
|
|
882
1126
|
static ɵfac: _angular_core.ɵɵFactoryDeclaration<FoldCardComponent, never>;
|
|
883
|
-
static ɵcmp: _angular_core.ɵɵComponentDeclaration<FoldCardComponent, "fold-card", never, { "surface": { "alias": "surface"; "required": false; "isSignal": true; }; "radius": { "alias": "radius"; "required": false; "isSignal": true; }; "padding": { "alias": "padding"; "required": false; "isSignal": true; }; "interactive": { "alias": "interactive"; "required": false; "isSignal": true; }; "separators": { "alias": "separators"; "required": false; "isSignal": true; }; "raisedBands": { "alias": "raisedBands"; "required": false; "isSignal": true; }; }, {}, never, ["[cardHeader]", "*", "[cardFooter]"], true, never>;
|
|
1127
|
+
static ɵcmp: _angular_core.ɵɵComponentDeclaration<FoldCardComponent, "fold-card", never, { "surface": { "alias": "surface"; "required": false; "isSignal": true; }; "radius": { "alias": "radius"; "required": false; "isSignal": true; }; "padding": { "alias": "padding"; "required": false; "isSignal": true; }; "interactive": { "alias": "interactive"; "required": false; "isSignal": true; }; "ariaLabel": { "alias": "ariaLabel"; "required": false; "isSignal": true; }; "separators": { "alias": "separators"; "required": false; "isSignal": true; }; "raisedBands": { "alias": "raisedBands"; "required": false; "isSignal": true; }; }, { "activated": "activated"; }, never, ["[cardHeader]", "*", "[cardFooter]"], true, never>;
|
|
884
1128
|
}
|
|
885
1129
|
|
|
886
1130
|
/**
|
|
@@ -1117,6 +1361,9 @@ declare class FoldFieldComponent {
|
|
|
1117
1361
|
* - `tone` — `accent` (default, brand link) · `muted` (secondary).
|
|
1118
1362
|
* - `icon` / `trailingIcon` — optional glyphs around the label.
|
|
1119
1363
|
* - `disabled` — button mode only.
|
|
1364
|
+
* - `target` / `rel` — anchor mode only. Setting `target="_blank"` auto-applies
|
|
1365
|
+
* `rel="noopener noreferrer"` (safe by default); override with an explicit
|
|
1366
|
+
* `rel`.
|
|
1120
1367
|
*
|
|
1121
1368
|
* @selector `fold-link`
|
|
1122
1369
|
*
|
|
@@ -1125,7 +1372,9 @@ declare class FoldFieldComponent {
|
|
|
1125
1372
|
* <fold-link icon="company" trailingIcon="chevron-right" (clicked)="openOrg()">
|
|
1126
1373
|
* Voir l'organigramme
|
|
1127
1374
|
* </fold-link>
|
|
1128
|
-
* <fold-link href="https://sh3pherd.dev/docs" tone="muted">
|
|
1375
|
+
* <fold-link href="https://sh3pherd.dev/docs" target="_blank" tone="muted">
|
|
1376
|
+
* Documentation
|
|
1377
|
+
* </fold-link>
|
|
1129
1378
|
* ```
|
|
1130
1379
|
*/
|
|
1131
1380
|
declare class FoldLinkComponent {
|
|
@@ -1137,12 +1386,19 @@ declare class FoldLinkComponent {
|
|
|
1137
1386
|
readonly tone: _angular_core.InputSignal<"accent" | "muted">;
|
|
1138
1387
|
/** When set, the link renders as an `<a href>` instead of a button. */
|
|
1139
1388
|
readonly href: _angular_core.InputSignal<string | undefined>;
|
|
1389
|
+
/** Anchor target (e.g. `_blank`). Anchor mode only. */
|
|
1390
|
+
readonly target: _angular_core.InputSignal<string | undefined>;
|
|
1391
|
+
/** Anchor `rel`. Anchor mode only. Defaults to `noopener noreferrer` when
|
|
1392
|
+
* `target="_blank"`; set explicitly to override. */
|
|
1393
|
+
readonly rel: _angular_core.InputSignal<string | undefined>;
|
|
1140
1394
|
/** Disable the button form (no effect on the `href` form). */
|
|
1141
1395
|
readonly disabled: _angular_core.InputSignalWithTransform<boolean, unknown>;
|
|
1142
|
-
/** Fires on click in the button form
|
|
1143
|
-
readonly clicked: _angular_core.OutputEmitterRef<
|
|
1396
|
+
/** Fires on click in the button form; carries the `MouseEvent`. */
|
|
1397
|
+
readonly clicked: _angular_core.OutputEmitterRef<MouseEvent>;
|
|
1398
|
+
/** Resolved `rel` — the explicit value, or a safe default for a new tab. */
|
|
1399
|
+
protected readonly resolvedRel: _angular_core.Signal<string | null>;
|
|
1144
1400
|
static ɵfac: _angular_core.ɵɵFactoryDeclaration<FoldLinkComponent, never>;
|
|
1145
|
-
static ɵcmp: _angular_core.ɵɵComponentDeclaration<FoldLinkComponent, "fold-link", never, { "icon": { "alias": "icon"; "required": false; "isSignal": true; }; "trailingIcon": { "alias": "trailingIcon"; "required": false; "isSignal": true; }; "tone": { "alias": "tone"; "required": false; "isSignal": true; }; "href": { "alias": "href"; "required": false; "isSignal": true; }; "disabled": { "alias": "disabled"; "required": false; "isSignal": true; }; }, { "clicked": "clicked"; }, never, ["*"], true, never>;
|
|
1401
|
+
static ɵcmp: _angular_core.ɵɵComponentDeclaration<FoldLinkComponent, "fold-link", never, { "icon": { "alias": "icon"; "required": false; "isSignal": true; }; "trailingIcon": { "alias": "trailingIcon"; "required": false; "isSignal": true; }; "tone": { "alias": "tone"; "required": false; "isSignal": true; }; "href": { "alias": "href"; "required": false; "isSignal": true; }; "target": { "alias": "target"; "required": false; "isSignal": true; }; "rel": { "alias": "rel"; "required": false; "isSignal": true; }; "disabled": { "alias": "disabled"; "required": false; "isSignal": true; }; }, { "clicked": "clicked"; }, never, ["*"], true, never>;
|
|
1146
1402
|
}
|
|
1147
1403
|
|
|
1148
1404
|
/**
|
|
@@ -1521,10 +1777,13 @@ interface FoldTableColumn {
|
|
|
1521
1777
|
readonly label: string;
|
|
1522
1778
|
/** Renders a sort button in the header; emits `sortChange` with `key`. */
|
|
1523
1779
|
readonly sortable?: boolean;
|
|
1524
|
-
/**
|
|
1525
|
-
readonly align?: "right";
|
|
1780
|
+
/** Text alignment of the header + cells. Default left; `right` for numeric. */
|
|
1781
|
+
readonly align?: "right" | "center";
|
|
1526
1782
|
/** Optional fixed column width (any CSS length). */
|
|
1527
1783
|
readonly width?: string;
|
|
1784
|
+
/** Clip overflowing text to one line with an ellipsis (pair with `width`).
|
|
1785
|
+
* Cell templates should set their own `title` for the full-text tooltip. */
|
|
1786
|
+
readonly truncate?: boolean;
|
|
1528
1787
|
/** Extra class applied to every cell in the column. */
|
|
1529
1788
|
readonly cellClass?: string;
|
|
1530
1789
|
}
|
|
@@ -1534,12 +1793,66 @@ interface FoldTableEmpty {
|
|
|
1534
1793
|
readonly subtitle?: string;
|
|
1535
1794
|
}
|
|
1536
1795
|
|
|
1796
|
+
/**
|
|
1797
|
+
* Every user-facing / accessible string {@link FoldDataTableComponent} renders
|
|
1798
|
+
* that isn't supplied per row. Parameterised strings are functions so a locale
|
|
1799
|
+
* can reword, not just translate. All defaults are English — a non-English app
|
|
1800
|
+
* overrides them once via {@link provideFoldDataTableLabels}, or per instance
|
|
1801
|
+
* via the `labels` input. (Per-row names come from the `selectionLabel` input;
|
|
1802
|
+
* {@link FoldDataTableLabels.selectRow} is only the fallback when it's unset.)
|
|
1803
|
+
*/
|
|
1804
|
+
interface FoldDataTableLabels {
|
|
1805
|
+
/** `aria-label` of the select-all header checkbox. */
|
|
1806
|
+
readonly selectAll: string;
|
|
1807
|
+
/** Fallback `aria-label` of a row checkbox (used when no `selectionLabel`). */
|
|
1808
|
+
readonly selectRow: string;
|
|
1809
|
+
/** A sortable header's button `aria-label`, e.g. `("Name") => "Sort by Name"`. */
|
|
1810
|
+
readonly sortBy: (column: string) => string;
|
|
1811
|
+
/** The loading spinner's accessible label. */
|
|
1812
|
+
readonly loading: string;
|
|
1813
|
+
}
|
|
1814
|
+
/** The English defaults — the base every override merges onto. */
|
|
1815
|
+
declare const FOLD_DATA_TABLE_DEFAULT_LABELS: FoldDataTableLabels;
|
|
1816
|
+
/** App-wide data-table labels; defaults to English. */
|
|
1817
|
+
declare const FOLD_DATA_TABLE_LABELS: InjectionToken<FoldDataTableLabels>;
|
|
1818
|
+
/**
|
|
1819
|
+
* Provide app-wide data-table labels once at bootstrap. Partial — any key you
|
|
1820
|
+
* omit keeps its English default.
|
|
1821
|
+
*
|
|
1822
|
+
* @example
|
|
1823
|
+
* ```ts
|
|
1824
|
+
* providers: [
|
|
1825
|
+
* provideFoldDataTableLabels({
|
|
1826
|
+
* selectAll: "Tout sélectionner",
|
|
1827
|
+
* sortBy: (c) => `Trier par ${c}`,
|
|
1828
|
+
* }),
|
|
1829
|
+
* ];
|
|
1830
|
+
* ```
|
|
1831
|
+
*/
|
|
1832
|
+
declare function provideFoldDataTableLabels(labels: Partial<FoldDataTableLabels>): Provider;
|
|
1833
|
+
|
|
1537
1834
|
/**
|
|
1538
1835
|
* `fold-data-table` — a controlled, presentational roster table. The parent
|
|
1539
1836
|
* supplies already-paged/sorted `rows`, a `columns` definition, and a
|
|
1540
1837
|
* `<ng-template foldCell="<key>">` per column for the cell content; the table
|
|
1541
1838
|
* owns the chrome (sticky sortable header, row tone accents, focus/click, the
|
|
1542
|
-
* mobile card layout, the empty
|
|
1839
|
+
* mobile card layout, the loading + empty states).
|
|
1840
|
+
*
|
|
1841
|
+
* Selection stays controlled too: pass a `selected` set of row keys and handle
|
|
1842
|
+
* `selectionChange` — the table renders the checkbox column, the header
|
|
1843
|
+
* select-all (with an indeterminate state over the current rows), and the
|
|
1844
|
+
* selected-row tint, but never owns the set.
|
|
1845
|
+
*
|
|
1846
|
+
* The narrow-screen behaviour is the parent's choice, not an imposed one, via
|
|
1847
|
+
* `mobileLayout`: `scroll` (default — stay tabular, scroll horizontally),
|
|
1848
|
+
* `auto-cards` (each row stacks into a label/value card), or `custom` (the
|
|
1849
|
+
* parent supplies `<ng-template foldRowCard let-row>` and owns the card).
|
|
1850
|
+
*
|
|
1851
|
+
* Accessible by construction: the first column renders as `<th scope="row">`
|
|
1852
|
+
* (screen readers announce each row by its identity cell), the sort direction
|
|
1853
|
+
* rides on `aria-sort` (the icon is decorative), clickable rows answer Enter and
|
|
1854
|
+
* Space and form a single roving-tabindex group (Arrow/Home/End move between
|
|
1855
|
+
* rows), and `caption` gives the table a visually-hidden name.
|
|
1543
1856
|
*
|
|
1544
1857
|
* Generic over the row type `T` so `rowKey`/`rowTone`/`rowClick` stay typed.
|
|
1545
1858
|
* Cell templates are untyped (`let-row` is `any`) — render through the parent's
|
|
@@ -1554,28 +1867,101 @@ declare class FoldDataTableComponent<T> {
|
|
|
1554
1867
|
readonly rowTone: _angular_core.InputSignal<((row: T) => FoldTableTone) | undefined>;
|
|
1555
1868
|
readonly sort: _angular_core.InputSignal<FoldTableSort | null>;
|
|
1556
1869
|
readonly empty: _angular_core.InputSignal<FoldTableEmpty | undefined>;
|
|
1870
|
+
/** While `true`, shows a spinner instead of the empty state — a table that
|
|
1871
|
+
* is fetching reads as "loading", never as "no data". */
|
|
1872
|
+
readonly loading: _angular_core.InputSignalWithTransform<boolean, unknown>;
|
|
1873
|
+
/** Accessible table name, rendered as a visually-hidden `<caption>`. Set it
|
|
1874
|
+
* when the surrounding context does not already name the table for AT. */
|
|
1875
|
+
readonly caption: _angular_core.InputSignal<string | undefined>;
|
|
1557
1876
|
/** Makes rows focusable + clickable (emits `rowClick`). */
|
|
1558
1877
|
readonly clickable: _angular_core.InputSignalWithTransform<boolean, unknown>;
|
|
1559
1878
|
readonly zebra: _angular_core.InputSignalWithTransform<boolean, unknown>;
|
|
1560
1879
|
readonly hover: _angular_core.InputSignalWithTransform<boolean, unknown>;
|
|
1561
|
-
|
|
1880
|
+
/**
|
|
1881
|
+
* How the table behaves on a narrow screen:
|
|
1882
|
+
* - `scroll` (default) — stay tabular; the body scrolls horizontally. The
|
|
1883
|
+
* table imposes no card layout unless asked.
|
|
1884
|
+
* - `auto-cards` — each row stacks into an auto label/value card.
|
|
1885
|
+
* - `custom` — hide the table and render the projected `foldRowCard` template
|
|
1886
|
+
* per row, so the parent owns the mobile presentation.
|
|
1887
|
+
*/
|
|
1888
|
+
readonly mobileLayout: _angular_core.InputSignal<"scroll" | "auto-cards" | "custom">;
|
|
1889
|
+
/** Row density — `compact` tightens padding for dense rosters. */
|
|
1890
|
+
readonly density: _angular_core.InputSignal<"comfortable" | "compact">;
|
|
1891
|
+
/** Pin the identity column while the body scrolls horizontally (wide tables). */
|
|
1892
|
+
readonly stickyFirst: _angular_core.InputSignalWithTransform<boolean, unknown>;
|
|
1893
|
+
/** Renders the checkbox column + header select-all. */
|
|
1894
|
+
readonly selectable: _angular_core.InputSignalWithTransform<boolean, unknown>;
|
|
1895
|
+
/** Controlled selection — the set of selected row keys. The parent owns it. */
|
|
1896
|
+
readonly selected: _angular_core.InputSignal<ReadonlySet<string | number>>;
|
|
1897
|
+
/** Accessible label for a row's checkbox, e.g. `(row) => row.name`. */
|
|
1898
|
+
readonly selectionLabel: _angular_core.InputSignal<((row: T) => string) | undefined>;
|
|
1899
|
+
/** Per-instance label overrides (merged over the app-wide / English defaults). */
|
|
1900
|
+
readonly labels: _angular_core.InputSignal<Partial<FoldDataTableLabels> | undefined>;
|
|
1901
|
+
/** Emits the next selection set on any checkbox toggle (never mutates input). */
|
|
1902
|
+
readonly selectionChange: _angular_core.OutputEmitterRef<Set<string | number>>;
|
|
1562
1903
|
/** Emits the clicked sortable column's `key`. */
|
|
1563
1904
|
readonly sortChange: _angular_core.OutputEmitterRef<string>;
|
|
1564
1905
|
readonly rowClick: _angular_core.OutputEmitterRef<T>;
|
|
1906
|
+
/** Key of the row that currently holds the single tab stop (roving tabindex). */
|
|
1907
|
+
private readonly focusedKey;
|
|
1908
|
+
/** True on a narrow viewport — gates the custom mobile-card rendering so the
|
|
1909
|
+
* desktop never instantiates the (CSS-hidden) per-row cards. */
|
|
1910
|
+
protected readonly isNarrow: _angular_core.WritableSignal<boolean>;
|
|
1911
|
+
private readonly destroyRef;
|
|
1912
|
+
private readonly injectedLabels;
|
|
1913
|
+
/** Effective labels — the app-wide (or English) set, with the `labels` input on top. */
|
|
1914
|
+
protected readonly l: _angular_core.Signal<FoldDataTableLabels>;
|
|
1915
|
+
constructor();
|
|
1565
1916
|
private readonly cells;
|
|
1566
1917
|
private readonly cellMap;
|
|
1918
|
+
private readonly rowCard;
|
|
1919
|
+
/** The custom mobile-card template, only when `mobileLayout="custom"`. */
|
|
1920
|
+
readonly rowCardTemplate: _angular_core.Signal<TemplateRef<unknown> | null>;
|
|
1921
|
+
/**
|
|
1922
|
+
* The toolbar's surface level — the "weight" the title bar lends the table.
|
|
1923
|
+
* All four map to fold surface tokens (never a hard-coded colour): `default`
|
|
1924
|
+
* (a subtle header lift), `sunken` / `raised` (a step down / up the elevation
|
|
1925
|
+
* ramp), and `accent` — a brand-filled bar whose projected content
|
|
1926
|
+
* auto-inverts to the on-accent palette per theme (the shared
|
|
1927
|
+
* `[data-surface="accent"]` machinery).
|
|
1928
|
+
*/
|
|
1929
|
+
readonly toolbarSurface: _angular_core.InputSignal<"accent" | "default" | "sunken" | "raised">;
|
|
1567
1930
|
/** The first column is the identity/primary cell (full-width on mobile). */
|
|
1568
1931
|
readonly primaryKey: _angular_core.Signal<string>;
|
|
1932
|
+
/** Total ARIA column count (data columns + the checkbox column). */
|
|
1933
|
+
readonly colCount: _angular_core.Signal<number>;
|
|
1934
|
+
/** Current row keys, in order — the roving-nav anchor set. */
|
|
1935
|
+
private readonly rowKeys;
|
|
1936
|
+
/** The row that holds the single tab stop: the focused row while it still
|
|
1937
|
+
* exists, else the first row — so a removed/filtered focus never strands the
|
|
1938
|
+
* roving group with zero tab stops. */
|
|
1939
|
+
private readonly activeRowKey;
|
|
1569
1940
|
cellTemplate(key: string): TemplateRef<unknown> | null;
|
|
1570
1941
|
keyOf(row: T, index: number): string | number;
|
|
1571
1942
|
toneOf(row: T): FoldTableTone;
|
|
1572
1943
|
isSorted(key: string): boolean;
|
|
1573
|
-
/** The sort
|
|
1574
|
-
|
|
1944
|
+
/** The sort icon for a column: a neutral up/down (`expand-all`) when idle, or
|
|
1945
|
+
* the active direction chevron. Decorative — `aria-sort` on the `<th>` is the
|
|
1946
|
+
* accessible carrier, so these icons stay `aria-hidden` (fold-icon default). */
|
|
1947
|
+
sortIcon(key: string): FoldIconName;
|
|
1575
1948
|
ariaSort(key: string): "ascending" | "descending" | "none";
|
|
1576
1949
|
onRowActivate(row: T): void;
|
|
1950
|
+
isRowSelected(row: T, index: number): boolean;
|
|
1951
|
+
/** All current rows selected (drives the header checkbox `checked`). */
|
|
1952
|
+
readonly allSelected: _angular_core.Signal<boolean>;
|
|
1953
|
+
/** Some — but not all — current rows selected (header `indeterminate`). */
|
|
1954
|
+
readonly someSelected: _angular_core.Signal<boolean>;
|
|
1955
|
+
toggleRow(row: T, index: number): void;
|
|
1956
|
+
/** Select-all toggles every current row; if all are already in, clears them. */
|
|
1957
|
+
toggleAll(): void;
|
|
1958
|
+
labelFor(row: T): string;
|
|
1959
|
+
/** The single tab stop: the focused (or fallback first) row. */
|
|
1960
|
+
rowTabIndex(row: T, index: number): 0 | -1 | null;
|
|
1961
|
+
onRowFocus(row: T, index: number): void;
|
|
1962
|
+
onRowKeydown(event: KeyboardEvent, row: T): void;
|
|
1577
1963
|
static ɵfac: _angular_core.ɵɵFactoryDeclaration<FoldDataTableComponent<any>, never>;
|
|
1578
|
-
static ɵcmp: _angular_core.ɵɵComponentDeclaration<FoldDataTableComponent<any>, "fold-data-table", never, { "columns": { "alias": "columns"; "required": true; "isSignal": true; }; "rows": { "alias": "rows"; "required": true; "isSignal": true; }; "rowKey": { "alias": "rowKey"; "required": false; "isSignal": true; }; "rowTone": { "alias": "rowTone"; "required": false; "isSignal": true; }; "sort": { "alias": "sort"; "required": false; "isSignal": true; }; "empty": { "alias": "empty"; "required": false; "isSignal": true; }; "clickable": { "alias": "clickable"; "required": false; "isSignal": true; }; "zebra": { "alias": "zebra"; "required": false; "isSignal": true; }; "hover": { "alias": "hover"; "required": false; "isSignal": true; }; "
|
|
1964
|
+
static ɵcmp: _angular_core.ɵɵComponentDeclaration<FoldDataTableComponent<any>, "fold-data-table", never, { "columns": { "alias": "columns"; "required": true; "isSignal": true; }; "rows": { "alias": "rows"; "required": true; "isSignal": true; }; "rowKey": { "alias": "rowKey"; "required": false; "isSignal": true; }; "rowTone": { "alias": "rowTone"; "required": false; "isSignal": true; }; "sort": { "alias": "sort"; "required": false; "isSignal": true; }; "empty": { "alias": "empty"; "required": false; "isSignal": true; }; "loading": { "alias": "loading"; "required": false; "isSignal": true; }; "caption": { "alias": "caption"; "required": false; "isSignal": true; }; "clickable": { "alias": "clickable"; "required": false; "isSignal": true; }; "zebra": { "alias": "zebra"; "required": false; "isSignal": true; }; "hover": { "alias": "hover"; "required": false; "isSignal": true; }; "mobileLayout": { "alias": "mobileLayout"; "required": false; "isSignal": true; }; "density": { "alias": "density"; "required": false; "isSignal": true; }; "stickyFirst": { "alias": "stickyFirst"; "required": false; "isSignal": true; }; "selectable": { "alias": "selectable"; "required": false; "isSignal": true; }; "selected": { "alias": "selected"; "required": false; "isSignal": true; }; "selectionLabel": { "alias": "selectionLabel"; "required": false; "isSignal": true; }; "labels": { "alias": "labels"; "required": false; "isSignal": true; }; "toolbarSurface": { "alias": "toolbarSurface"; "required": false; "isSignal": true; }; }, { "selectionChange": "selectionChange"; "sortChange": "sortChange"; "rowClick": "rowClick"; }, ["cells", "rowCard"], ["[foldToolbar]"], true, never>;
|
|
1579
1965
|
}
|
|
1580
1966
|
|
|
1581
1967
|
/**
|
|
@@ -1599,6 +1985,28 @@ declare class FoldDataTableCellDirective {
|
|
|
1599
1985
|
static ɵdir: _angular_core.ɵɵDirectiveDeclaration<FoldDataTableCellDirective, "ng-template[foldCell]", never, { "foldCell": { "alias": "foldCell"; "required": true; "isSignal": true; }; }, {}, never, never, true, never>;
|
|
1600
1986
|
}
|
|
1601
1987
|
|
|
1988
|
+
/**
|
|
1989
|
+
* Marks the `<ng-template>` that renders a whole row as a **custom mobile card**
|
|
1990
|
+
* inside `<fold-data-table mobileLayout="custom">`:
|
|
1991
|
+
*
|
|
1992
|
+
* ```html
|
|
1993
|
+
* <ng-template foldRowCard let-row let-i="index"> … </ng-template>
|
|
1994
|
+
* ```
|
|
1995
|
+
*
|
|
1996
|
+
* The template context is `{ $implicit: row, index }`. When `mobileLayout` is
|
|
1997
|
+
* `"custom"`, the table hides on narrow screens and this template renders once
|
|
1998
|
+
* per row instead of the auto label/value stack — the parent owns the mobile
|
|
1999
|
+
* presentation entirely (including any interactions it wants inside the card).
|
|
2000
|
+
*
|
|
2001
|
+
* As with cell templates, `let-row` is untyped by design — annotate through the
|
|
2002
|
+
* parent component's typed helpers.
|
|
2003
|
+
*/
|
|
2004
|
+
declare class FoldDataTableRowCardDirective {
|
|
2005
|
+
readonly template: TemplateRef<any>;
|
|
2006
|
+
static ɵfac: _angular_core.ɵɵFactoryDeclaration<FoldDataTableRowCardDirective, never>;
|
|
2007
|
+
static ɵdir: _angular_core.ɵɵDirectiveDeclaration<FoldDataTableRowCardDirective, "ng-template[foldRowCard]", never, {}, {}, never, never, true, never>;
|
|
2008
|
+
}
|
|
2009
|
+
|
|
1602
2010
|
/** Where the column pins while the main content scrolls past it. */
|
|
1603
2011
|
type FoldStickyColumnAnchor = "top" | "center" | "bottom";
|
|
1604
2012
|
/**
|
|
@@ -1652,7 +2060,7 @@ declare class FoldStickyColumnDirective {
|
|
|
1652
2060
|
* flow position: `top`/`center` (which pin the top edge, at 0 / 50%) need the
|
|
1653
2061
|
* column at the *top* of its tall row (`start`); `bottom` needs it at the
|
|
1654
2062
|
* *bottom* (`end`), else it starts off-screen and only catches mid-scroll. */
|
|
1655
|
-
protected readonly alignSelfStyle: _angular_core.Signal<"
|
|
2063
|
+
protected readonly alignSelfStyle: _angular_core.Signal<"start" | "end">;
|
|
1656
2064
|
/** Centre anchoring pins the top edge at 50%, then pulls back half its height. */
|
|
1657
2065
|
protected readonly transformStyle: _angular_core.Signal<"none" | "translateY(-50%)">;
|
|
1658
2066
|
static ɵfac: _angular_core.ɵɵFactoryDeclaration<FoldStickyColumnDirective, never>;
|
|
@@ -1918,10 +2326,12 @@ declare function observeElementWidth(element?: ElementRef<HTMLElement> | HTMLEle
|
|
|
1918
2326
|
|
|
1919
2327
|
/**
|
|
1920
2328
|
* A named surface — the ground a subtree paints itself on. `page` is the
|
|
1921
|
-
* document body; `chrome` is application furniture (rails, header) that a
|
|
1922
|
-
*
|
|
2329
|
+
* document body; `chrome` is application furniture (rails, header) that a theme
|
|
2330
|
+
* may colour differently from the page; `accent` is an **auto-inverting** region
|
|
2331
|
+
* filled with the brand accent, whose content re-points to a compatible
|
|
2332
|
+
* on-accent palette (see the `[data-surface="accent"]` block in `semantic.css`).
|
|
1923
2333
|
*/
|
|
1924
|
-
type FoldSurfaceName = "page" | "chrome";
|
|
2334
|
+
type FoldSurfaceName = "page" | "chrome" | "accent";
|
|
1925
2335
|
/**
|
|
1926
2336
|
* `[foldSurface]` — declares the element a **named surface**, so a theme can
|
|
1927
2337
|
* re-colour it without knowing anything about the component it lives in.
|
|
@@ -2041,6 +2451,12 @@ declare class FoldInputComponent implements FormValueControl<string> {
|
|
|
2041
2451
|
* @default 'text'
|
|
2042
2452
|
*/
|
|
2043
2453
|
readonly type: _angular_core.InputSignal<"text" | "email" | "password" | "tel" | "url">;
|
|
2454
|
+
/** On a `password` input, offer a reveal (eye) toggle to show/hide the value. */
|
|
2455
|
+
readonly revealable: _angular_core.InputSignalWithTransform<boolean, unknown>;
|
|
2456
|
+
/** Accessible name of the reveal control while hidden. @default 'Show password' */
|
|
2457
|
+
readonly revealLabel: _angular_core.InputSignal<string>;
|
|
2458
|
+
/** Accessible name of the reveal control while shown. @default 'Hide password' */
|
|
2459
|
+
readonly hideLabel: _angular_core.InputSignal<string>;
|
|
2044
2460
|
/**
|
|
2045
2461
|
* Size preset controlling height, font-size, padding and border-radius.
|
|
2046
2462
|
* - `sm` — compact (text-sm, tight padding) — inline table edits, compact forms
|
|
@@ -2103,13 +2519,22 @@ declare class FoldInputComponent implements FormValueControl<string> {
|
|
|
2103
2519
|
protected readonly errorMessage: _angular_core.Signal<string | undefined>;
|
|
2104
2520
|
/** `aria-describedby` target: the error when shown, else the hint, else none. */
|
|
2105
2521
|
protected readonly describedBy: _angular_core.Signal<string | null>;
|
|
2522
|
+
/** Is the password currently revealed (shown as plain text)? */
|
|
2523
|
+
protected readonly revealed: _angular_core.WritableSignal<boolean>;
|
|
2524
|
+
/** Whether to render the reveal toggle — a `revealable` password input. */
|
|
2525
|
+
protected readonly showReveal: _angular_core.Signal<boolean>;
|
|
2526
|
+
/** The native `type` to render — `text` while a password is revealed. */
|
|
2527
|
+
protected readonly effectiveType: _angular_core.Signal<"text" | "email" | "password" | "tel" | "url">;
|
|
2528
|
+
/** The reveal control's accessible name, tracking its state. */
|
|
2529
|
+
protected readonly revealAria: _angular_core.Signal<string>;
|
|
2530
|
+
protected toggleReveal(): void;
|
|
2106
2531
|
/** Handles native input event. `value.set()` also fires the model's
|
|
2107
2532
|
* auto `valueChange` output for standalone `(valueChange)` consumers. */
|
|
2108
2533
|
onInputChange(event: Event): void;
|
|
2109
2534
|
/** Mark the field touched on blur, so errors can surface. */
|
|
2110
2535
|
protected onBlur(): void;
|
|
2111
2536
|
static ɵfac: _angular_core.ɵɵFactoryDeclaration<FoldInputComponent, never>;
|
|
2112
|
-
static ɵcmp: _angular_core.ɵɵComponentDeclaration<FoldInputComponent, "fold-input", never, { "value": { "alias": "value"; "required": false; "isSignal": true; }; "disabled": { "alias": "disabled"; "required": false; "isSignal": true; }; "touched": { "alias": "touched"; "required": false; "isSignal": true; }; "errors": { "alias": "errors"; "required": false; "isSignal": true; }; "type": { "alias": "type"; "required": false; "isSignal": true; }; "size": { "alias": "size"; "required": false; "isSignal": true; }; "align": { "alias": "align"; "required": false; "isSignal": true; }; "variant": { "alias": "variant"; "required": false; "isSignal": true; }; "label": { "alias": "label"; "required": false; "isSignal": true; }; "required": { "alias": "required"; "required": false; "isSignal": true; }; "optional": { "alias": "optional"; "required": false; "isSignal": true; }; "optionalLabel": { "alias": "optionalLabel"; "required": false; "isSignal": true; }; "hint": { "alias": "hint"; "required": false; "isSignal": true; }; "placeholder": { "alias": "placeholder"; "required": false; "isSignal": true; }; "readOnly": { "alias": "readOnly"; "required": false; "isSignal": true; }; "autofocus": { "alias": "autofocus"; "required": false; "isSignal": true; }; "autocomplete": { "alias": "autocomplete"; "required": false; "isSignal": true; }; }, { "value": "valueChange"; "touched": "touchedChange"; }, never, never, true, never>;
|
|
2537
|
+
static ɵcmp: _angular_core.ɵɵComponentDeclaration<FoldInputComponent, "fold-input", never, { "value": { "alias": "value"; "required": false; "isSignal": true; }; "disabled": { "alias": "disabled"; "required": false; "isSignal": true; }; "touched": { "alias": "touched"; "required": false; "isSignal": true; }; "errors": { "alias": "errors"; "required": false; "isSignal": true; }; "type": { "alias": "type"; "required": false; "isSignal": true; }; "revealable": { "alias": "revealable"; "required": false; "isSignal": true; }; "revealLabel": { "alias": "revealLabel"; "required": false; "isSignal": true; }; "hideLabel": { "alias": "hideLabel"; "required": false; "isSignal": true; }; "size": { "alias": "size"; "required": false; "isSignal": true; }; "align": { "alias": "align"; "required": false; "isSignal": true; }; "variant": { "alias": "variant"; "required": false; "isSignal": true; }; "label": { "alias": "label"; "required": false; "isSignal": true; }; "required": { "alias": "required"; "required": false; "isSignal": true; }; "optional": { "alias": "optional"; "required": false; "isSignal": true; }; "optionalLabel": { "alias": "optionalLabel"; "required": false; "isSignal": true; }; "hint": { "alias": "hint"; "required": false; "isSignal": true; }; "placeholder": { "alias": "placeholder"; "required": false; "isSignal": true; }; "readOnly": { "alias": "readOnly"; "required": false; "isSignal": true; }; "autofocus": { "alias": "autofocus"; "required": false; "isSignal": true; }; "autocomplete": { "alias": "autocomplete"; "required": false; "isSignal": true; }; }, { "value": "valueChange"; "touched": "touchedChange"; }, never, never, true, never>;
|
|
2113
2538
|
}
|
|
2114
2539
|
|
|
2115
2540
|
/** The increment/decrement glyph: chevrons, `− / +`, or no buttons. */
|
|
@@ -2354,50 +2779,690 @@ declare class FoldSelectComponent implements FormValueControl<string> {
|
|
|
2354
2779
|
}
|
|
2355
2780
|
|
|
2356
2781
|
/**
|
|
2357
|
-
*
|
|
2358
|
-
*
|
|
2359
|
-
* `
|
|
2782
|
+
* Zero-dependency placement math for {@link FoldPopoverComponent}. Pure and
|
|
2783
|
+
* framework-free so it unit-tests without a DOM: give it the anchor rect, the
|
|
2784
|
+
* floating size and the viewport, get back the `{ x, y }` to pin the floating
|
|
2785
|
+
* element (viewport coordinates, for `position: fixed`) plus the placement it
|
|
2786
|
+
* actually resolved to after collision handling.
|
|
2787
|
+
*
|
|
2788
|
+
* Three middlewares, in the order a good popover applies them:
|
|
2789
|
+
* 1. **flip** — pick the best-fitting side: keep the preferred one if it fits,
|
|
2790
|
+
* else its opposite, else whichever has the most room (so a bottom menu opens
|
|
2791
|
+
* upward near the fold instead of spilling offscreen).
|
|
2792
|
+
* 2. **size** — report the space available on the chosen side (`maxWidth` /
|
|
2793
|
+
* `maxHeight`), so the caller caps the panel and scrolls the overflow instead
|
|
2794
|
+
* of letting it run off the viewport.
|
|
2795
|
+
* 3. **shift** — slide along the cross axis to stay within the viewport padding,
|
|
2796
|
+
* without leaving the anchor's side.
|
|
2797
|
+
*
|
|
2798
|
+
* We deliberately do not depend on Floating UI — fold ships no runtime deps.
|
|
2799
|
+
*/
|
|
2800
|
+
/** The side of the anchor the floating element sits on. */
|
|
2801
|
+
type FoldPopoverSide = "top" | "bottom" | "left" | "right";
|
|
2802
|
+
/** Alignment of the floating element along the anchor's cross axis. */
|
|
2803
|
+
type FoldPopoverAlign = "start" | "center" | "end";
|
|
2804
|
+
/** A full placement: a side, optionally suffixed with an alignment. */
|
|
2805
|
+
type FoldPopoverPlacement = FoldPopoverSide | `${FoldPopoverSide}-${FoldPopoverAlign}`;
|
|
2806
|
+
/** A rectangle in viewport coordinates (a subset of `DOMRect`). */
|
|
2807
|
+
interface FoldRect {
|
|
2808
|
+
readonly x: number;
|
|
2809
|
+
readonly y: number;
|
|
2810
|
+
readonly width: number;
|
|
2811
|
+
readonly height: number;
|
|
2812
|
+
}
|
|
2813
|
+
interface FoldPlacementInput {
|
|
2814
|
+
/** The trigger's bounding rect, in viewport coordinates. */
|
|
2815
|
+
readonly anchor: FoldRect;
|
|
2816
|
+
/** The floating element's measured size. */
|
|
2817
|
+
readonly floating: {
|
|
2818
|
+
readonly width: number;
|
|
2819
|
+
readonly height: number;
|
|
2820
|
+
};
|
|
2821
|
+
/** Preferred placement before collision handling. */
|
|
2822
|
+
readonly placement: FoldPopoverPlacement;
|
|
2823
|
+
/**
|
|
2824
|
+
* Ordered fallbacks tried (after the preferred) when the preferred side can't
|
|
2825
|
+
* fit — the first that fits wins, else the roomiest of all candidates. Each
|
|
2826
|
+
* may change side *and* alignment. Defaults to the opposite side.
|
|
2827
|
+
*/
|
|
2828
|
+
readonly fallbackPlacements?: readonly FoldPopoverPlacement[] | undefined;
|
|
2829
|
+
/** Gap between the anchor and the floating element, in px. */
|
|
2830
|
+
readonly offset: number;
|
|
2831
|
+
/** Viewport size (usually `innerWidth` / `innerHeight`). */
|
|
2832
|
+
readonly viewport: {
|
|
2833
|
+
readonly width: number;
|
|
2834
|
+
readonly height: number;
|
|
2835
|
+
};
|
|
2836
|
+
/** Minimum gap kept between the floating element and the viewport edge. */
|
|
2837
|
+
readonly padding: number;
|
|
2838
|
+
}
|
|
2839
|
+
interface FoldPlacementResult {
|
|
2840
|
+
readonly x: number;
|
|
2841
|
+
readonly y: number;
|
|
2842
|
+
/** The placement after flip — drives the arrow / `data-placement`. */
|
|
2843
|
+
readonly placement: FoldPopoverPlacement;
|
|
2844
|
+
/** Space available to the floating element on the resolved side, minus
|
|
2845
|
+
* padding — the consumer caps `max-width` / `max-height` to these and lets
|
|
2846
|
+
* the panel scroll (the `size` middleware). */
|
|
2847
|
+
readonly maxWidth: number;
|
|
2848
|
+
readonly maxHeight: number;
|
|
2849
|
+
}
|
|
2850
|
+
/**
|
|
2851
|
+
* Resolve `{ x, y, placement, maxWidth, maxHeight }` for a floating element.
|
|
2852
|
+
* Order: **flip** (choose the best-fitting side) → **size** (available space on
|
|
2853
|
+
* that side, for the caller to cap + scroll) → **shift** (slide along the cross
|
|
2854
|
+
* axis to stay in the viewport).
|
|
2855
|
+
*/
|
|
2856
|
+
declare function computePlacement(input: FoldPlacementInput): FoldPlacementResult;
|
|
2857
|
+
|
|
2858
|
+
/**
|
|
2859
|
+
* A data-driven option for the array API of `fold-listbox` / `fold-multiselect`
|
|
2860
|
+
* (`[options]`). Use it — instead of projecting `<fold-option>` — when the list
|
|
2861
|
+
* is data, not markup: the value type is linked to the control's value at compile
|
|
2862
|
+
* time (no projection seam). For rich per-row content, project an
|
|
2863
|
+
* `<ng-template #option let-o>` alongside `[options]`; otherwise `label` renders.
|
|
2864
|
+
*/
|
|
2865
|
+
interface FoldSelectOption<T> {
|
|
2866
|
+
/** The value written back to the control when the row is chosen. */
|
|
2867
|
+
readonly value: T;
|
|
2868
|
+
/** The row's visible text (also the type-ahead + trigger label). */
|
|
2869
|
+
readonly label: string;
|
|
2870
|
+
/** Skip in keyboard nav and block selection. @default false */
|
|
2871
|
+
readonly disabled?: boolean;
|
|
2872
|
+
}
|
|
2873
|
+
|
|
2874
|
+
/**
|
|
2875
|
+
* The contract a `fold-option` needs from whatever owns it — the single-select
|
|
2876
|
+
* `fold-listbox` or the multi-select `fold-multiselect`. Injected through a token
|
|
2877
|
+
* (not the concrete class) so an option stays decoupled from either component and
|
|
2878
|
+
* there is no circular import. Generic over the option value type `T`; the token
|
|
2879
|
+
* itself is erased to `unknown` (the option↔owner value link is a runtime
|
|
2880
|
+
* contract — content projection can't carry `T` statically).
|
|
2881
|
+
*/
|
|
2882
|
+
interface FoldListboxOwner<T> {
|
|
2883
|
+
/** Is this option's value currently selected? (equality vs. membership.) */
|
|
2884
|
+
isSelected(value: T): boolean;
|
|
2885
|
+
/** The keyboard-active option's id — the listbox's `aria-activedescendant`. */
|
|
2886
|
+
readonly activeId: Signal<string | null>;
|
|
2887
|
+
}
|
|
2888
|
+
|
|
2889
|
+
/**
|
|
2890
|
+
* `<fold-listbox>` — a **styleable** single-select, the richer sibling of the
|
|
2891
|
+
* native-`<select>`-wrapping {@link FoldSelectComponent}. Reach for it when the
|
|
2892
|
+
* options need custom rendering the native popup can't give (an icon, a second
|
|
2893
|
+
* line, a status) — otherwise `fold-select` stays the lighter, mobile-native
|
|
2894
|
+
* default. For picking several values, use `fold-multiselect`.
|
|
2895
|
+
*
|
|
2896
|
+
* Built on {@link FoldPopoverComponent}: the popover owns positioning, the native
|
|
2897
|
+
* top layer, outside-click / `Escape` dismissal and focus return. On top of that
|
|
2898
|
+
* this adds the ARIA select pattern — a `role="listbox"` that holds focus and
|
|
2899
|
+
* drives `aria-activedescendant`, full keyboard (↑/↓, `Home`/`End`, type-ahead,
|
|
2900
|
+
* `Enter`) — and Signal-Forms wiring (`FormValueControl<string>`), so `[formField]`
|
|
2901
|
+
* and `[(value)]` both work, exactly like `fold-input` / `fold-select`.
|
|
2902
|
+
*
|
|
2903
|
+
* ```html
|
|
2904
|
+
* <fold-listbox label="Devise" [(value)]="currency" placeholder="Choisir…">
|
|
2905
|
+
* <fold-option value="EUR">Euro</fold-option>
|
|
2906
|
+
* <fold-option value="USD">US Dollar</fold-option>
|
|
2907
|
+
* </fold-listbox>
|
|
2908
|
+
* ```
|
|
2909
|
+
*
|
|
2910
|
+
* @selector `fold-listbox`
|
|
2911
|
+
*/
|
|
2912
|
+
declare class FoldListboxComponent<T> implements FormValueControl<T | null>, FoldListboxOwner<T> {
|
|
2913
|
+
/** Selected value (the chosen option's `value`), or `null` when nothing is
|
|
2914
|
+
* picked. A `model()` so `FormField` and `[(value)]` stay in sync. Generic
|
|
2915
|
+
* over the option value — `string` by inference, but `number`, an `enum` or
|
|
2916
|
+
* an object all work (objects need {@link compareWith}). */
|
|
2917
|
+
readonly value: _angular_core.ModelSignal<T | null>;
|
|
2918
|
+
/** How two values are compared for selection — supply it for **object** values
|
|
2919
|
+
* (reference equality won't match); primitives (string/number/enum) don't need
|
|
2920
|
+
* it. @default `Object.is` */
|
|
2921
|
+
readonly compareWith: _angular_core.InputSignal<((a: T, b: T) => boolean) | undefined>;
|
|
2922
|
+
/** Data-driven options — the alternative to projecting `<fold-option>`. When
|
|
2923
|
+
* set, the value type is linked to the options at compile time (no projection
|
|
2924
|
+
* seam). For rich rows, project `<ng-template #option let-o>`. */
|
|
2925
|
+
readonly options: _angular_core.InputSignal<readonly FoldSelectOption<T>[] | undefined>;
|
|
2926
|
+
/** Disabled state — bound automatically by `FormField`. */
|
|
2927
|
+
readonly disabled: _angular_core.InputSignal<boolean>;
|
|
2928
|
+
/** Two-way touched state — set on selection / blur, kept in sync with the field. */
|
|
2929
|
+
readonly touched: _angular_core.ModelSignal<boolean>;
|
|
2930
|
+
/** Validation errors — bound by `FormField`. */
|
|
2931
|
+
readonly errors: _angular_core.InputSignal<readonly ValidationError.WithOptionalFieldTree[]>;
|
|
2932
|
+
/** Two-way open state of the popup. */
|
|
2933
|
+
readonly open: _angular_core.ModelSignal<boolean>;
|
|
2934
|
+
/** Size preset — see {@link FoldInputComponent.size}. @default 'md' */
|
|
2935
|
+
readonly size: _angular_core.InputSignal<"sm" | "md" | "lg">;
|
|
2936
|
+
/** Visual variant — see {@link FoldInputComponent.variant}. @default 'default' */
|
|
2937
|
+
readonly variant: _angular_core.InputSignal<"default" | "panel">;
|
|
2938
|
+
/** Optional label displayed above the control. */
|
|
2939
|
+
readonly label: _angular_core.InputSignal<string | undefined>;
|
|
2940
|
+
/** Show a required marker on the label. */
|
|
2941
|
+
readonly required: _angular_core.InputSignalWithTransform<boolean, unknown>;
|
|
2942
|
+
/** Show a lighter `(optional)` marker on the label (ignored when required). */
|
|
2943
|
+
readonly optional: _angular_core.InputSignalWithTransform<boolean, unknown>;
|
|
2944
|
+
/** The word inside the optional marker. @default 'optional' */
|
|
2945
|
+
readonly optionalLabel: _angular_core.InputSignal<string>;
|
|
2946
|
+
/** Optional helper text shown under the control. */
|
|
2947
|
+
readonly hint: _angular_core.InputSignal<string | undefined>;
|
|
2948
|
+
/** Text shown on the trigger while nothing is selected. */
|
|
2949
|
+
readonly placeholder: _angular_core.InputSignal<string | undefined>;
|
|
2950
|
+
/** Preferred popup placement. @default 'bottom-start' */
|
|
2951
|
+
readonly placement: _angular_core.InputSignal<FoldPopoverPlacement>;
|
|
2952
|
+
/** Show a clear (×) affordance on the trigger once a value is picked. */
|
|
2953
|
+
readonly allowClear: _angular_core.InputSignalWithTransform<boolean, unknown>;
|
|
2954
|
+
/** Accessible name of the clear button. @default 'Clear' */
|
|
2955
|
+
readonly clearLabel: _angular_core.InputSignal<string>;
|
|
2956
|
+
/** Unique, SSR-safe id for label association (see {@link FoldIdService}). */
|
|
2957
|
+
readonly inputId: string;
|
|
2958
|
+
/** Id of the `role="listbox"` element (own, distinct from the popover panel). */
|
|
2959
|
+
protected readonly listId: string;
|
|
2960
|
+
/** Rich per-row template for the `[options]` array API (`<ng-template #option>`). */
|
|
2961
|
+
protected readonly optionTemplate: _angular_core.Signal<TemplateRef<{
|
|
2962
|
+
$implicit: FoldSelectOption<T>;
|
|
2963
|
+
}> | undefined>;
|
|
2964
|
+
private readonly projectedOptions;
|
|
2965
|
+
private readonly renderedOptions;
|
|
2966
|
+
/** The live option instances, from whichever API is in use — the `[options]`
|
|
2967
|
+
* array (rendered in the view) when set, else the projected `<fold-option>`s. */
|
|
2968
|
+
private readonly allOptions;
|
|
2969
|
+
private readonly list;
|
|
2970
|
+
/** Compare two values — the injected `compareWith`, else `Object.is`. Called
|
|
2971
|
+
* only where both operands are `T`, so no erasure leaks in. */
|
|
2972
|
+
private eq;
|
|
2973
|
+
/** Shared roving/keyboard core; single-select commits + closes on activation. */
|
|
2974
|
+
private readonly nav;
|
|
2975
|
+
/** `aria-activedescendant`, read by each `fold-option` for its `is-active`. */
|
|
2976
|
+
readonly activeId: _angular_core.Signal<string | null>;
|
|
2977
|
+
/** The selected option's label, for the trigger. */
|
|
2978
|
+
protected readonly selectedLabel: _angular_core.Signal<string | undefined>;
|
|
2979
|
+
/** Whether the clear affordance is currently offered. */
|
|
2980
|
+
protected readonly showClear: _angular_core.Signal<boolean>;
|
|
2981
|
+
/** The message to show under the field: the first error, once touched. */
|
|
2982
|
+
protected readonly errorMessage: _angular_core.Signal<string | undefined>;
|
|
2983
|
+
/** `aria-describedby` target: the error when shown, else the hint, else none. */
|
|
2984
|
+
protected readonly describedBy: _angular_core.Signal<string | null>;
|
|
2985
|
+
/** Has the popup been opened at least once this lifetime — so closing it (by
|
|
2986
|
+
* Escape, outside-click, Tab or a pick) can mark the field touched, exactly as
|
|
2987
|
+
* a native `<select>` does on blur. Without this a `required` select that the
|
|
2988
|
+
* user opens and dismisses would never surface its error. */
|
|
2989
|
+
private hasOpened;
|
|
2990
|
+
constructor();
|
|
2991
|
+
/** A value is selected when it equals the current one (via `compareWith`). */
|
|
2992
|
+
isSelected(value: T): boolean;
|
|
2993
|
+
/** Clear the selection (the `allowClear` ×). */
|
|
2994
|
+
protected clear(event: Event): void;
|
|
2995
|
+
/** Open with the keys a native select opens on; otherwise type-ahead picks
|
|
2996
|
+
* directly without opening — native-`<select>` parity. */
|
|
2997
|
+
protected onTriggerKeydown(event: KeyboardEvent): void;
|
|
2998
|
+
/** Keyboard while the list is open and focused — delegated to the core. */
|
|
2999
|
+
protected onListKeydown(event: KeyboardEvent): void;
|
|
3000
|
+
/** Click on a row selects it (delegated, so projected rows need no wiring). */
|
|
3001
|
+
protected onListClick(event: MouseEvent): void;
|
|
3002
|
+
/** Hover arms the row, so pointer and keyboard share one active row. */
|
|
3003
|
+
protected onListPointermove(event: PointerEvent): void;
|
|
3004
|
+
/** Index of the selected option (or -1) — where the keyboard arms on open. */
|
|
3005
|
+
private selectedIndex;
|
|
3006
|
+
/** The enabled option under an event target, or null. */
|
|
3007
|
+
private enabledOptionFrom;
|
|
3008
|
+
private selectAt;
|
|
3009
|
+
private commit;
|
|
3010
|
+
static ɵfac: _angular_core.ɵɵFactoryDeclaration<FoldListboxComponent<any>, never>;
|
|
3011
|
+
static ɵcmp: _angular_core.ɵɵComponentDeclaration<FoldListboxComponent<any>, "fold-listbox", never, { "value": { "alias": "value"; "required": false; "isSignal": true; }; "compareWith": { "alias": "compareWith"; "required": false; "isSignal": true; }; "options": { "alias": "options"; "required": false; "isSignal": true; }; "disabled": { "alias": "disabled"; "required": false; "isSignal": true; }; "touched": { "alias": "touched"; "required": false; "isSignal": true; }; "errors": { "alias": "errors"; "required": false; "isSignal": true; }; "open": { "alias": "open"; "required": false; "isSignal": true; }; "size": { "alias": "size"; "required": false; "isSignal": true; }; "variant": { "alias": "variant"; "required": false; "isSignal": true; }; "label": { "alias": "label"; "required": false; "isSignal": true; }; "required": { "alias": "required"; "required": false; "isSignal": true; }; "optional": { "alias": "optional"; "required": false; "isSignal": true; }; "optionalLabel": { "alias": "optionalLabel"; "required": false; "isSignal": true; }; "hint": { "alias": "hint"; "required": false; "isSignal": true; }; "placeholder": { "alias": "placeholder"; "required": false; "isSignal": true; }; "placement": { "alias": "placement"; "required": false; "isSignal": true; }; "allowClear": { "alias": "allowClear"; "required": false; "isSignal": true; }; "clearLabel": { "alias": "clearLabel"; "required": false; "isSignal": true; }; }, { "value": "valueChange"; "touched": "touchedChange"; "open": "openChange"; }, ["optionTemplate", "projectedOptions"], ["*"], true, never>;
|
|
3012
|
+
}
|
|
3013
|
+
|
|
3014
|
+
/**
|
|
3015
|
+
* `<fold-multiselect>` — the multi-select sibling of {@link FoldListboxComponent}.
|
|
3016
|
+
* Same styleable popover + `fold-option` rows, but the value is a set: activating
|
|
3017
|
+
* a row **toggles** its membership and the panel **stays open**, so several picks
|
|
3018
|
+
* are one interaction. It's a separate component (not a `multiple` flag) because
|
|
3019
|
+
* the Signal-Forms value type is genuinely different — `readonly string[]`, not
|
|
3020
|
+
* `string` — so `[formField]` and `[(value)]` stay honestly typed.
|
|
3021
|
+
*
|
|
3022
|
+
* `role="listbox"` + `aria-multiselectable`, full keyboard (↑/↓, `Home`/`End`,
|
|
3023
|
+
* type-ahead; `Enter`/`Space` toggle), and each selected row keeps its check. The
|
|
3024
|
+
* trigger summarises the selection (the chosen labels, joined).
|
|
3025
|
+
*
|
|
3026
|
+
* ```html
|
|
3027
|
+
* <fold-multiselect label="Genres" [(value)]="genres" placeholder="Pick a few…">
|
|
3028
|
+
* <fold-option value="rock">Rock</fold-option>
|
|
3029
|
+
* <fold-option value="jazz">Jazz</fold-option>
|
|
3030
|
+
* </fold-multiselect>
|
|
3031
|
+
* ```
|
|
3032
|
+
*
|
|
3033
|
+
* @selector `fold-multiselect`
|
|
3034
|
+
*/
|
|
3035
|
+
declare class FoldMultiselectComponent<T> implements FormValueControl<readonly T[]>, FoldListboxOwner<T> {
|
|
3036
|
+
/** Selected values. A `model()` so `FormField` and `[(value)]` stay in sync.
|
|
3037
|
+
* Generic over the option value (string by inference; number/enum/object all
|
|
3038
|
+
* work — objects need {@link compareWith}). */
|
|
3039
|
+
readonly value: _angular_core.ModelSignal<readonly T[]>;
|
|
3040
|
+
/** How two values are compared for membership — supply it for **object**
|
|
3041
|
+
* values; primitives don't need it. @default `Object.is` */
|
|
3042
|
+
readonly compareWith: _angular_core.InputSignal<((a: T, b: T) => boolean) | undefined>;
|
|
3043
|
+
/** Data-driven options — the alternative to projecting `<fold-option>`. When
|
|
3044
|
+
* set, the value type is linked to the options at compile time. For rich rows,
|
|
3045
|
+
* project `<ng-template #option let-o>`. */
|
|
3046
|
+
readonly options: _angular_core.InputSignal<readonly FoldSelectOption<T>[] | undefined>;
|
|
3047
|
+
/** Disabled state — bound automatically by `FormField`. */
|
|
3048
|
+
readonly disabled: _angular_core.InputSignal<boolean>;
|
|
3049
|
+
/** Two-way touched state — set on the first toggle, kept in sync with the field. */
|
|
3050
|
+
readonly touched: _angular_core.ModelSignal<boolean>;
|
|
3051
|
+
/** Validation errors — bound by `FormField`. */
|
|
3052
|
+
readonly errors: _angular_core.InputSignal<readonly ValidationError.WithOptionalFieldTree[]>;
|
|
3053
|
+
/** Two-way open state of the popup. */
|
|
3054
|
+
readonly open: _angular_core.ModelSignal<boolean>;
|
|
3055
|
+
/** Size preset — see {@link FoldInputComponent.size}. @default 'md' */
|
|
3056
|
+
readonly size: _angular_core.InputSignal<"sm" | "md" | "lg">;
|
|
3057
|
+
/** Visual variant — see {@link FoldInputComponent.variant}. @default 'default' */
|
|
3058
|
+
readonly variant: _angular_core.InputSignal<"default" | "panel">;
|
|
3059
|
+
/** Optional label displayed above the control. */
|
|
3060
|
+
readonly label: _angular_core.InputSignal<string | undefined>;
|
|
3061
|
+
/** Show a required marker on the label. */
|
|
3062
|
+
readonly required: _angular_core.InputSignalWithTransform<boolean, unknown>;
|
|
3063
|
+
/** Show a lighter `(optional)` marker on the label (ignored when required). */
|
|
3064
|
+
readonly optional: _angular_core.InputSignalWithTransform<boolean, unknown>;
|
|
3065
|
+
/** The word inside the optional marker. @default 'optional' */
|
|
3066
|
+
readonly optionalLabel: _angular_core.InputSignal<string>;
|
|
3067
|
+
/** Optional helper text shown under the control. */
|
|
3068
|
+
readonly hint: _angular_core.InputSignal<string | undefined>;
|
|
3069
|
+
/** Text shown on the trigger while nothing is selected. */
|
|
3070
|
+
readonly placeholder: _angular_core.InputSignal<string | undefined>;
|
|
3071
|
+
/** Preferred popup placement. @default 'bottom-start' */
|
|
3072
|
+
readonly placement: _angular_core.InputSignal<FoldPopoverPlacement>;
|
|
3073
|
+
/** Unique, SSR-safe id for label association (see {@link FoldIdService}). */
|
|
3074
|
+
readonly inputId: string;
|
|
3075
|
+
/** Id of the `role="listbox"` element (own, distinct from the popover panel). */
|
|
3076
|
+
protected readonly listId: string;
|
|
3077
|
+
/** Rich per-row template for the `[options]` array API (`<ng-template #option>`). */
|
|
3078
|
+
protected readonly optionTemplate: _angular_core.Signal<TemplateRef<{
|
|
3079
|
+
$implicit: FoldSelectOption<T>;
|
|
3080
|
+
}> | undefined>;
|
|
3081
|
+
private readonly projectedOptions;
|
|
3082
|
+
private readonly renderedOptions;
|
|
3083
|
+
/** The live option instances, from whichever API is in use. */
|
|
3084
|
+
private readonly allOptions;
|
|
3085
|
+
private readonly list;
|
|
3086
|
+
/** Compare two values — the injected `compareWith`, else `Object.is`. */
|
|
3087
|
+
private eq;
|
|
3088
|
+
/** Shared roving/keyboard core; multi-select toggles + stays open on activation. */
|
|
3089
|
+
private readonly nav;
|
|
3090
|
+
/** `aria-activedescendant`, read by each `fold-option` for its `is-active`. */
|
|
3091
|
+
readonly activeId: _angular_core.Signal<string | null>;
|
|
3092
|
+
/** Fast-path membership: a `Set` when values compare by identity (the default,
|
|
3093
|
+
* O(1) per option), or `null` when a `compareWith` is supplied — then
|
|
3094
|
+
* membership falls back to a linear `eq` scan (correct for object values). */
|
|
3095
|
+
private readonly selectedSet;
|
|
3096
|
+
/** The chosen labels (in option order) — joined, collapsing to "…, +N" past
|
|
3097
|
+
* {@link SUMMARY_MAX} so the trigger can't grow unbounded. */
|
|
3098
|
+
protected readonly summaryLabel: _angular_core.Signal<string | undefined>;
|
|
3099
|
+
/** The message to show under the field: the first error, once touched. */
|
|
3100
|
+
protected readonly errorMessage: _angular_core.Signal<string | undefined>;
|
|
3101
|
+
/** `aria-describedby` target: the error when shown, else the hint, else none. */
|
|
3102
|
+
protected readonly describedBy: _angular_core.Signal<string | null>;
|
|
3103
|
+
/** Has the popup been opened this lifetime — so any close marks touched (blur
|
|
3104
|
+
* parity), even one that picked nothing. */
|
|
3105
|
+
private hasOpened;
|
|
3106
|
+
constructor();
|
|
3107
|
+
/** A value is selected when it's in the current set (via `compareWith`). */
|
|
3108
|
+
isSelected(value: T): boolean;
|
|
3109
|
+
/** Open with the keys a native select opens on. */
|
|
3110
|
+
protected onTriggerKeydown(event: KeyboardEvent): void;
|
|
3111
|
+
/** Keyboard while the list is open and focused — delegated to the core. */
|
|
3112
|
+
protected onListKeydown(event: KeyboardEvent): void;
|
|
3113
|
+
/** Click on a row toggles it (delegated, so projected rows need no wiring). */
|
|
3114
|
+
protected onListClick(event: MouseEvent): void;
|
|
3115
|
+
/** Hover arms the row, so pointer and keyboard share one active row. */
|
|
3116
|
+
protected onListPointermove(event: PointerEvent): void;
|
|
3117
|
+
/** Index of the first selected option (or -1) — where the keyboard arms on open. */
|
|
3118
|
+
private firstSelectedIndex;
|
|
3119
|
+
/** Index of the enabled option under an event target, or -1. */
|
|
3120
|
+
private enabledIndexFrom;
|
|
3121
|
+
/** Add or remove the option's value from the set; the panel stays open. */
|
|
3122
|
+
private toggle;
|
|
3123
|
+
static ɵfac: _angular_core.ɵɵFactoryDeclaration<FoldMultiselectComponent<any>, never>;
|
|
3124
|
+
static ɵcmp: _angular_core.ɵɵComponentDeclaration<FoldMultiselectComponent<any>, "fold-multiselect", never, { "value": { "alias": "value"; "required": false; "isSignal": true; }; "compareWith": { "alias": "compareWith"; "required": false; "isSignal": true; }; "options": { "alias": "options"; "required": false; "isSignal": true; }; "disabled": { "alias": "disabled"; "required": false; "isSignal": true; }; "touched": { "alias": "touched"; "required": false; "isSignal": true; }; "errors": { "alias": "errors"; "required": false; "isSignal": true; }; "open": { "alias": "open"; "required": false; "isSignal": true; }; "size": { "alias": "size"; "required": false; "isSignal": true; }; "variant": { "alias": "variant"; "required": false; "isSignal": true; }; "label": { "alias": "label"; "required": false; "isSignal": true; }; "required": { "alias": "required"; "required": false; "isSignal": true; }; "optional": { "alias": "optional"; "required": false; "isSignal": true; }; "optionalLabel": { "alias": "optionalLabel"; "required": false; "isSignal": true; }; "hint": { "alias": "hint"; "required": false; "isSignal": true; }; "placeholder": { "alias": "placeholder"; "required": false; "isSignal": true; }; "placement": { "alias": "placement"; "required": false; "isSignal": true; }; }, { "value": "valueChange"; "touched": "touchedChange"; "open": "openChange"; }, ["optionTemplate", "projectedOptions"], ["*"], true, never>;
|
|
3125
|
+
}
|
|
3126
|
+
|
|
3127
|
+
/**
|
|
3128
|
+
* `<fold-option>` — a single choice inside a {@link FoldListboxComponent}. Project
|
|
3129
|
+
* as many as you need; the label is whatever you put inside (plain text, or richer
|
|
3130
|
+
* content — an icon, a description). It reads the parent for its own `is-selected`
|
|
3131
|
+
* / `is-active` state (computed, so nothing is pushed in during change detection —
|
|
3132
|
+
* which would read this required `value` before it is set), and exposes a stable
|
|
3133
|
+
* id the listbox points `aria-activedescendant` at.
|
|
3134
|
+
*
|
|
3135
|
+
* ```html
|
|
3136
|
+
* <fold-listbox [(value)]="currency">
|
|
3137
|
+
* <fold-option value="EUR">Euro</fold-option>
|
|
3138
|
+
* <fold-option value="USD" [disabled]="!usdAllowed">US Dollar</fold-option>
|
|
3139
|
+
* </fold-listbox>
|
|
3140
|
+
* ```
|
|
3141
|
+
*
|
|
3142
|
+
* @selector `fold-option`
|
|
3143
|
+
*/
|
|
3144
|
+
declare class FoldOptionComponent<T> {
|
|
3145
|
+
private readonly host;
|
|
3146
|
+
private readonly owner;
|
|
3147
|
+
/** The value written back to the listbox when this option is chosen. */
|
|
3148
|
+
readonly value: _angular_core.InputSignal<T>;
|
|
3149
|
+
/** Disabled options are skipped by keyboard nav and can't be selected. */
|
|
3150
|
+
readonly disabled: _angular_core.InputSignalWithTransform<boolean, unknown>;
|
|
3151
|
+
/** Stable, SSR-safe id — the listbox points `aria-activedescendant` at it. */
|
|
3152
|
+
readonly id: string;
|
|
3153
|
+
/** Derived from the parent — evaluated lazily during this option's own render,
|
|
3154
|
+
* so the required `value` is always set by the time it's read. */
|
|
3155
|
+
readonly selected: _angular_core.Signal<boolean>;
|
|
3156
|
+
readonly active: _angular_core.Signal<boolean>;
|
|
3157
|
+
/** The option's visible text — used for the trigger label and type-ahead. */
|
|
3158
|
+
get label(): string;
|
|
3159
|
+
/** Bring the option into view when it becomes keyboard-active. Optional-chained
|
|
3160
|
+
* so it's a no-op where `scrollIntoView` is absent (jsdom, non-DOM SSR). */
|
|
3161
|
+
scrollIntoView(): void;
|
|
3162
|
+
static ɵfac: _angular_core.ɵɵFactoryDeclaration<FoldOptionComponent<any>, never>;
|
|
3163
|
+
static ɵcmp: _angular_core.ɵɵComponentDeclaration<FoldOptionComponent<any>, "fold-option", never, { "value": { "alias": "value"; "required": true; "isSignal": true; }; "disabled": { "alias": "disabled"; "required": false; "isSignal": true; }; }, {}, never, ["*"], true, never>;
|
|
3164
|
+
}
|
|
3165
|
+
|
|
3166
|
+
/**
|
|
3167
|
+
* One password requirement shown as a live-validating dot in
|
|
3168
|
+
* {@link FoldPasswordFieldComponent}. The predicate is deliberately just a
|
|
3169
|
+
* function, so any validation style drops in:
|
|
3170
|
+
*
|
|
3171
|
+
* - **regex** — `foldRegexRule('An uppercase letter', /[A-Z]/)`, or inline
|
|
3172
|
+
* `{ label, test: (v) => /\d/.test(v) }`.
|
|
3173
|
+
* - **zod** (no dependency added here) —
|
|
3174
|
+
* `{ label: 'Valid', test: (v) => schema.safeParse(v).success }`.
|
|
3175
|
+
* - **anything** — length, an entropy score, a server-known blocklist, …
|
|
3176
|
+
*/
|
|
3177
|
+
interface FoldPasswordRule {
|
|
3178
|
+
/** Human-readable requirement, e.g. "At least 8 characters". */
|
|
3179
|
+
readonly label: string;
|
|
3180
|
+
/** Passes when the value satisfies the rule. */
|
|
3181
|
+
readonly test: (value: string) => boolean;
|
|
3182
|
+
}
|
|
3183
|
+
/** Build a rule from a `RegExp` — the common case. */
|
|
3184
|
+
declare function foldRegexRule(label: string, pattern: RegExp): FoldPasswordRule;
|
|
3185
|
+
/**
|
|
3186
|
+
* A sensible default policy (English labels): 8+ characters, an uppercase and a
|
|
3187
|
+
* lowercase letter, and a digit. Override via the `rules` input for a different
|
|
3188
|
+
* policy or localised labels.
|
|
3189
|
+
*/
|
|
3190
|
+
declare function foldDefaultPasswordRules(): readonly FoldPasswordRule[];
|
|
3191
|
+
|
|
3192
|
+
/**
|
|
3193
|
+
* `<fold-password-field>` — a password input with a **live requirements
|
|
3194
|
+
* checklist**. Composes `fold-input[type=password][revealable]` (so it inherits
|
|
3195
|
+
* the tokened box, the label/hint/error chrome and the show/hide eye) and renders
|
|
3196
|
+
* a dot per {@link FoldPasswordRule} that turns on as the value satisfies it.
|
|
3197
|
+
*
|
|
3198
|
+
* The rules are **injected**, not hard-coded — a `RegExp` (via `foldRegexRule`),
|
|
3199
|
+
* a `zod` `safeParse`, a length check, anything (see {@link FoldPasswordRule}).
|
|
3200
|
+
* `rules` defaults to {@link foldDefaultPasswordRules}. `validChange` emits
|
|
3201
|
+
* whether every rule passes; Signal-Forms-native (`FormValueControl<string>`).
|
|
3202
|
+
*
|
|
3203
|
+
* ```html
|
|
3204
|
+
* <fold-password-field
|
|
3205
|
+
* label="New password"
|
|
3206
|
+
* [(value)]="password"
|
|
3207
|
+
* (validChange)="ok.set($event)"
|
|
3208
|
+
* />
|
|
3209
|
+
* ```
|
|
2360
3210
|
*
|
|
2361
|
-
*
|
|
3211
|
+
* @selector `fold-password-field`
|
|
3212
|
+
*/
|
|
3213
|
+
declare class FoldPasswordFieldComponent implements FormValueControl<string> {
|
|
3214
|
+
/** The password value. A `model()` so `FormField` and `[(value)]` stay in sync. */
|
|
3215
|
+
readonly value: _angular_core.ModelSignal<string>;
|
|
3216
|
+
/** Disabled state — bound automatically by `FormField`. */
|
|
3217
|
+
readonly disabled: _angular_core.InputSignal<boolean>;
|
|
3218
|
+
/** Two-way touched state — forwarded to the inner input (set on blur). */
|
|
3219
|
+
readonly touched: _angular_core.ModelSignal<boolean>;
|
|
3220
|
+
/** Validation errors — bound by `FormField`, shown under the input. */
|
|
3221
|
+
readonly errors: _angular_core.InputSignal<readonly ValidationError.WithOptionalFieldTree[]>;
|
|
3222
|
+
/** Label above the field. @default 'Password' */
|
|
3223
|
+
readonly label: _angular_core.InputSignal<string>;
|
|
3224
|
+
/** Placeholder text. */
|
|
3225
|
+
readonly placeholder: _angular_core.InputSignal<string>;
|
|
3226
|
+
/** Helper text under the input (above the rules). */
|
|
3227
|
+
readonly hint: _angular_core.InputSignal<string | undefined>;
|
|
3228
|
+
/** Show a required marker on the label. */
|
|
3229
|
+
readonly required: _angular_core.InputSignalWithTransform<boolean, unknown>;
|
|
3230
|
+
/** Size preset — see {@link FoldInputComponent.size}. @default 'md' */
|
|
3231
|
+
readonly size: _angular_core.InputSignal<"sm" | "md" | "lg">;
|
|
3232
|
+
/** Visual variant — see {@link FoldInputComponent.variant}. @default 'default' */
|
|
3233
|
+
readonly variant: _angular_core.InputSignal<"default" | "panel">;
|
|
3234
|
+
/** Native `autocomplete`. @default 'new-password' */
|
|
3235
|
+
readonly autocomplete: _angular_core.InputSignal<string | null>;
|
|
3236
|
+
/** Offer the reveal (eye) toggle. @default true */
|
|
3237
|
+
readonly revealable: _angular_core.InputSignalWithTransform<boolean, unknown>;
|
|
3238
|
+
/** `aria-label` of the reveal toggle when hidden — forwarded to the input. */
|
|
3239
|
+
readonly revealLabel: _angular_core.InputSignal<string>;
|
|
3240
|
+
/** `aria-label` of the reveal toggle when shown — forwarded to the input. */
|
|
3241
|
+
readonly hideLabel: _angular_core.InputSignal<string>;
|
|
3242
|
+
/** The requirements to display and validate against. @default the built-ins. */
|
|
3243
|
+
readonly rules: _angular_core.InputSignal<readonly FoldPasswordRule[]>;
|
|
3244
|
+
/** Built-in row marker: a filling `dot`, or a `check` tick on satisfied rows.
|
|
3245
|
+
* @default 'dot' */
|
|
3246
|
+
readonly marker: _angular_core.InputSignal<"check" | "dot">;
|
|
3247
|
+
/** Accessible name of the requirements list. @default 'Password requirements' */
|
|
3248
|
+
readonly rulesLabel: _angular_core.InputSignal<string>;
|
|
3249
|
+
/** Word prefixed to a satisfied rule for screen readers. @default 'met' */
|
|
3250
|
+
readonly metLabel: _angular_core.InputSignal<string>;
|
|
3251
|
+
/** Word prefixed to an unmet rule for screen readers. @default 'not met' */
|
|
3252
|
+
readonly unmetLabel: _angular_core.InputSignal<string>;
|
|
3253
|
+
/** Emits whether every rule passes, on each change. */
|
|
3254
|
+
readonly validChange: _angular_core.OutputEmitterRef<boolean>;
|
|
3255
|
+
/** Each rule paired with its live pass/fail state. Public + `exportAs`, so a
|
|
3256
|
+
* custom `[rules]` projection can render its own list off the same state:
|
|
3257
|
+
* `#pw="foldPasswordField"` then loop `pw.checklist()`. */
|
|
3258
|
+
readonly checklist: _angular_core.Signal<{
|
|
3259
|
+
label: string;
|
|
3260
|
+
met: boolean;
|
|
3261
|
+
}[]>;
|
|
3262
|
+
/** True when every rule passes. */
|
|
3263
|
+
protected readonly allValid: _angular_core.Signal<boolean>;
|
|
3264
|
+
constructor();
|
|
3265
|
+
static ɵfac: _angular_core.ɵɵFactoryDeclaration<FoldPasswordFieldComponent, never>;
|
|
3266
|
+
static ɵcmp: _angular_core.ɵɵComponentDeclaration<FoldPasswordFieldComponent, "fold-password-field", ["foldPasswordField"], { "value": { "alias": "value"; "required": false; "isSignal": true; }; "disabled": { "alias": "disabled"; "required": false; "isSignal": true; }; "touched": { "alias": "touched"; "required": false; "isSignal": true; }; "errors": { "alias": "errors"; "required": false; "isSignal": true; }; "label": { "alias": "label"; "required": false; "isSignal": true; }; "placeholder": { "alias": "placeholder"; "required": false; "isSignal": true; }; "hint": { "alias": "hint"; "required": false; "isSignal": true; }; "required": { "alias": "required"; "required": false; "isSignal": true; }; "size": { "alias": "size"; "required": false; "isSignal": true; }; "variant": { "alias": "variant"; "required": false; "isSignal": true; }; "autocomplete": { "alias": "autocomplete"; "required": false; "isSignal": true; }; "revealable": { "alias": "revealable"; "required": false; "isSignal": true; }; "revealLabel": { "alias": "revealLabel"; "required": false; "isSignal": true; }; "hideLabel": { "alias": "hideLabel"; "required": false; "isSignal": true; }; "rules": { "alias": "rules"; "required": false; "isSignal": true; }; "marker": { "alias": "marker"; "required": false; "isSignal": true; }; "rulesLabel": { "alias": "rulesLabel"; "required": false; "isSignal": true; }; "metLabel": { "alias": "metLabel"; "required": false; "isSignal": true; }; "unmetLabel": { "alias": "unmetLabel"; "required": false; "isSignal": true; }; }, { "value": "valueChange"; "touched": "touchedChange"; "validChange": "validChange"; }, never, ["[rules]"], true, never>;
|
|
3267
|
+
}
|
|
3268
|
+
|
|
3269
|
+
/** One segment of a {@link FoldViewToggleComponent}. */
|
|
3270
|
+
interface FoldViewToggleOption {
|
|
3271
|
+
/** The value emitted when this segment is chosen. */
|
|
3272
|
+
readonly value: string;
|
|
3273
|
+
/** Optional leading icon. */
|
|
3274
|
+
readonly icon?: FoldIconName;
|
|
3275
|
+
/** Optional visible label. Omit for an icon-only segment (set `ariaLabel`). */
|
|
3276
|
+
readonly label?: string;
|
|
3277
|
+
/** Accessible name — required when there is no visible `label`. */
|
|
3278
|
+
readonly ariaLabel?: string;
|
|
3279
|
+
/** Disable this segment. */
|
|
3280
|
+
readonly disabled?: boolean;
|
|
3281
|
+
}
|
|
3282
|
+
/**
|
|
3283
|
+
* `<fold-view-toggle>` — a compact **segmented single-select** (Cards / Table, a
|
|
3284
|
+
* density switch, a chart mode…). Generic and zero-domain: pass `options` and
|
|
3285
|
+
* bind `[(value)]`. It's a proper `role="radiogroup"` of `role="radio"` segments
|
|
3286
|
+
* with roving tabindex and arrow-key selection (Home/End too), so it's a real
|
|
3287
|
+
* single-choice control, not two independent toggles.
|
|
3288
|
+
*
|
|
3289
|
+
* ```html
|
|
3290
|
+
* <fold-view-toggle
|
|
3291
|
+
* ariaLabel="View"
|
|
3292
|
+
* [options]="[
|
|
3293
|
+
* { value: 'cards', icon: 'grid', ariaLabel: 'Cards' },
|
|
3294
|
+
* { value: 'table', icon: 'list', ariaLabel: 'Table' },
|
|
3295
|
+
* ]"
|
|
3296
|
+
* [(value)]="view"
|
|
3297
|
+
* />
|
|
3298
|
+
* ```
|
|
3299
|
+
*
|
|
3300
|
+
* @selector `fold-view-toggle`
|
|
3301
|
+
*/
|
|
3302
|
+
declare class FoldViewToggleComponent {
|
|
3303
|
+
private readonly host;
|
|
3304
|
+
/** The segments, in order. */
|
|
3305
|
+
readonly options: _angular_core.InputSignal<readonly FoldViewToggleOption[]>;
|
|
3306
|
+
/** The selected value. `[(value)]` / `FormField`-friendly. */
|
|
3307
|
+
readonly value: _angular_core.ModelSignal<string>;
|
|
3308
|
+
/** Accessible name of the group. */
|
|
3309
|
+
readonly ariaLabel: _angular_core.InputSignal<string | undefined>;
|
|
3310
|
+
/** Size preset. @default 'md' */
|
|
3311
|
+
readonly size: _angular_core.InputSignal<"sm" | "md">;
|
|
3312
|
+
/** How the selected segment reads: a neutral `raised` chip, or an `accent`
|
|
3313
|
+
* brand tint. @default 'raised' */
|
|
3314
|
+
readonly activeStyle: _angular_core.InputSignal<"accent" | "raised">;
|
|
3315
|
+
/** Hide visible labels, keeping icons only (labels stay as accessible names). */
|
|
3316
|
+
readonly iconOnly: _angular_core.InputSignalWithTransform<boolean, unknown>;
|
|
3317
|
+
constructor();
|
|
3318
|
+
/** The segment holding the tab stop: the selected one when enabled, else the
|
|
3319
|
+
* first enabled — never a disabled (unfocusable) segment, so Tab always
|
|
3320
|
+
* reaches the group even if the selected value is disabled. */
|
|
3321
|
+
protected readonly rovingValue: _angular_core.Signal<string | null>;
|
|
3322
|
+
/** Pick a segment (no-op if disabled or already selected). */
|
|
3323
|
+
protected select(option: FoldViewToggleOption): void;
|
|
3324
|
+
/** Arrow keys move the selection between enabled segments (radiogroup pattern). */
|
|
3325
|
+
protected onKeydown(event: KeyboardEvent): void;
|
|
3326
|
+
/** The value to move to for a nav key, or null if the key isn't one. */
|
|
3327
|
+
private nextValue;
|
|
3328
|
+
private focusValue;
|
|
3329
|
+
static ɵfac: _angular_core.ɵɵFactoryDeclaration<FoldViewToggleComponent, never>;
|
|
3330
|
+
static ɵcmp: _angular_core.ɵɵComponentDeclaration<FoldViewToggleComponent, "fold-view-toggle", never, { "options": { "alias": "options"; "required": true; "isSignal": true; }; "value": { "alias": "value"; "required": true; "isSignal": true; }; "ariaLabel": { "alias": "ariaLabel"; "required": false; "isSignal": true; }; "size": { "alias": "size"; "required": false; "isSignal": true; }; "activeStyle": { "alias": "activeStyle"; "required": false; "isSignal": true; }; "iconOnly": { "alias": "iconOnly"; "required": false; "isSignal": true; }; }, { "value": "valueChange"; }, never, never, true, never>;
|
|
3331
|
+
}
|
|
3332
|
+
|
|
3333
|
+
/**
|
|
3334
|
+
* `<fold-checkbox>` — the boolean form control. A **native** `<input
|
|
3335
|
+
* type="checkbox">` (so keyboard, focus, the `checkbox` role, form submission
|
|
3336
|
+
* and `indeterminate` all come for free) is visually replaced by a tokenised
|
|
3337
|
+
* box + check/dash mark: best-in-class semantics with full visual control.
|
|
3338
|
+
*
|
|
3339
|
+
* Drive it standalone with `[(checked)]` / `(checkedChange)`, or bind a signal
|
|
3340
|
+
* form field with `[formField]` (it implements `FormCheckboxControl`, whose
|
|
3341
|
+
* value member is `checked` — not `value` — so the field's value **is** the
|
|
3342
|
+
* checked state; `disabled`, `touched` and `errors` are wired by `FormField`).
|
|
3343
|
+
* `indeterminate` renders the mixed state
|
|
3344
|
+
* (e.g. a "select all" over a partial selection); it is a visual cue only —
|
|
3345
|
+
* clicking a mixed box checks it, as natively.
|
|
3346
|
+
*
|
|
3347
|
+
* Accessible by construction: the box is decorative, the native input carries
|
|
3348
|
+
* the semantics; a visible `label` wraps the input (click-to-toggle) and names
|
|
3349
|
+
* it, otherwise pass `ariaLabel`. Focus-visible ring, `prefers-reduced-motion`
|
|
3350
|
+
* and `forced-colors` are all handled.
|
|
3351
|
+
*
|
|
3352
|
+
* @selector `fold-checkbox`
|
|
3353
|
+
*
|
|
3354
|
+
* @example
|
|
3355
|
+
* ```html
|
|
3356
|
+
* <fold-checkbox label="Remember me" [(checked)]="remember" />
|
|
3357
|
+
* <fold-checkbox ariaLabel="Select row" [checked]="selected" (checkedChange)="toggle()" />
|
|
3358
|
+
* <fold-checkbox label="I accept the terms" required [formField]="form.consent" />
|
|
3359
|
+
* ```
|
|
3360
|
+
*/
|
|
3361
|
+
declare class FoldCheckboxComponent implements FormCheckboxControl {
|
|
3362
|
+
/** Checked state — the signal-forms field value. Bind with `[(checked)]`,
|
|
3363
|
+
* `(checkedChange)`, or `[formField]`. */
|
|
3364
|
+
readonly checked: _angular_core.ModelSignal<boolean>;
|
|
3365
|
+
/** Disabled state — bound automatically by `FormField`. */
|
|
3366
|
+
readonly disabled: _angular_core.InputSignal<boolean>;
|
|
3367
|
+
/** Two-way touched state — set on blur so `FormField` can surface errors. */
|
|
3368
|
+
readonly touched: _angular_core.ModelSignal<boolean>;
|
|
3369
|
+
/** Validation errors — bound by `FormField` from the field. */
|
|
3370
|
+
readonly errors: _angular_core.InputSignal<readonly ValidationError.WithOptionalFieldTree[]>;
|
|
3371
|
+
/** Mixed / tri-state visual (native `indeterminate`, a property not attribute). */
|
|
3372
|
+
readonly indeterminate: _angular_core.InputSignalWithTransform<boolean, unknown>;
|
|
3373
|
+
/** Optional visible label — wraps the box, so clicking it toggles. */
|
|
3374
|
+
readonly label: _angular_core.InputSignal<string | undefined>;
|
|
3375
|
+
/** Accessible name when there is no visible `label`. */
|
|
3376
|
+
readonly ariaLabel: _angular_core.InputSignal<string | undefined>;
|
|
3377
|
+
/** Optional helper text shown under the control. */
|
|
3378
|
+
readonly hint: _angular_core.InputSignal<string | undefined>;
|
|
3379
|
+
/** Show a required marker on the label (and set the native `required`). */
|
|
3380
|
+
readonly required: _angular_core.InputSignalWithTransform<boolean, unknown>;
|
|
3381
|
+
/** Size preset — `sm` for dense rows/tables, `md` (default) for forms. */
|
|
3382
|
+
readonly size: _angular_core.InputSignal<"sm" | "md">;
|
|
3383
|
+
/** Unique, SSR-safe id for label + message association. */
|
|
3384
|
+
readonly inputId: string;
|
|
3385
|
+
/** The message under the control: the first error once touched, else the hint. */
|
|
3386
|
+
protected readonly errorMessage: _angular_core.Signal<string | undefined>;
|
|
3387
|
+
protected readonly message: _angular_core.Signal<string | null>;
|
|
3388
|
+
/** `aria-describedby` target: the error when shown, else the hint, else none. */
|
|
3389
|
+
protected readonly describedBy: _angular_core.Signal<string | null>;
|
|
3390
|
+
constructor();
|
|
3391
|
+
/** Native change → sync the model (also fires the auto `checkedChange`). */
|
|
3392
|
+
onChange(event: Event): void;
|
|
3393
|
+
protected onBlur(): void;
|
|
3394
|
+
static ɵfac: _angular_core.ɵɵFactoryDeclaration<FoldCheckboxComponent, never>;
|
|
3395
|
+
static ɵcmp: _angular_core.ɵɵComponentDeclaration<FoldCheckboxComponent, "fold-checkbox", never, { "checked": { "alias": "checked"; "required": false; "isSignal": true; }; "disabled": { "alias": "disabled"; "required": false; "isSignal": true; }; "touched": { "alias": "touched"; "required": false; "isSignal": true; }; "errors": { "alias": "errors"; "required": false; "isSignal": true; }; "indeterminate": { "alias": "indeterminate"; "required": false; "isSignal": true; }; "label": { "alias": "label"; "required": false; "isSignal": true; }; "ariaLabel": { "alias": "ariaLabel"; "required": false; "isSignal": true; }; "hint": { "alias": "hint"; "required": false; "isSignal": true; }; "required": { "alias": "required"; "required": false; "isSignal": true; }; "size": { "alias": "size"; "required": false; "isSignal": true; }; }, { "checked": "checkedChange"; "touched": "touchedChange"; }, never, never, true, never>;
|
|
3396
|
+
}
|
|
3397
|
+
|
|
3398
|
+
/**
|
|
3399
|
+
* `<fold-slider>` — a single-value range slider with the design-system track,
|
|
3400
|
+
* fill and thumb (a styled native `<input type="range">`, so keyboard, focus and
|
|
3401
|
+
* the `slider` role are all native). The fill is a `--sl-pct` custom property, so
|
|
2362
3402
|
* there is no overlay markup. For a min↔max pair, use {@link FoldRangeSliderComponent}.
|
|
2363
3403
|
*
|
|
3404
|
+
* Integrates with signal forms via `FormValueControl<number>` (bind
|
|
3405
|
+
* `[formField]`), or drive it standalone with `[(value)]` / `(valueChange)`. A
|
|
3406
|
+
* visible `label` is a real `<label for>`; a `valueText` override is announced
|
|
3407
|
+
* to assistive tech through `aria-valuetext` (so a value that _means_ something —
|
|
3408
|
+
* `"off"`, `"12:30"` — reads as that, not the raw number).
|
|
3409
|
+
*
|
|
2364
3410
|
* @selector `fold-slider`
|
|
2365
3411
|
*
|
|
2366
3412
|
* @example
|
|
2367
3413
|
* ```html
|
|
2368
|
-
* <fold-slider label="
|
|
2369
|
-
* <fold-slider label="
|
|
3414
|
+
* <fold-slider label="Rail width" [min]="48" [max]="120" [(value)]="width" />
|
|
3415
|
+
* <fold-slider label="Volume" [formField]="form.volume" />
|
|
3416
|
+
* <fold-slider label="Min" [max]="10" [valueText]="min() || 'off'" [(value)]="min" />
|
|
2370
3417
|
* ```
|
|
2371
3418
|
*/
|
|
2372
|
-
declare class FoldSliderComponent {
|
|
2373
|
-
/** The bound value
|
|
3419
|
+
declare class FoldSliderComponent implements FormValueControl<number> {
|
|
3420
|
+
/** The bound value — a `model()`, so `[(value)]` and signal forms both sync. */
|
|
2374
3421
|
readonly value: _angular_core.ModelSignal<number>;
|
|
2375
|
-
/** Minimum value. @default 0 */
|
|
2376
|
-
readonly min: _angular_core.InputSignal<number>;
|
|
2377
|
-
/** Maximum value. @default 100 */
|
|
2378
|
-
readonly max: _angular_core.InputSignal<number>;
|
|
3422
|
+
/** Minimum value (also the field's min validator via `FormField`). @default 0 */
|
|
3423
|
+
readonly min: _angular_core.InputSignal<number | undefined>;
|
|
3424
|
+
/** Maximum value (also the field's max validator via `FormField`). @default 100 */
|
|
3425
|
+
readonly max: _angular_core.InputSignal<number | undefined>;
|
|
2379
3426
|
/** Increment granularity. @default 1 */
|
|
2380
|
-
readonly step: _angular_core.InputSignal<number>;
|
|
2381
|
-
/** Optional label
|
|
3427
|
+
readonly step: _angular_core.InputSignal<number | undefined>;
|
|
3428
|
+
/** Optional visible label (a real `<label for>`), also the accessible name. */
|
|
2382
3429
|
readonly label: _angular_core.InputSignal<string | undefined>;
|
|
2383
|
-
/**
|
|
3430
|
+
/** Accessible name when there is no visible `label`. */
|
|
3431
|
+
readonly ariaLabel: _angular_core.InputSignal<string | undefined>;
|
|
3432
|
+
/** Override the displayed + announced value text — e.g. `'off'` for "no bound". */
|
|
2384
3433
|
readonly valueText: _angular_core.InputSignal<string | undefined>;
|
|
2385
3434
|
/** Show the current value next to the label. @default true */
|
|
2386
3435
|
readonly showValue: _angular_core.InputSignalWithTransform<boolean, unknown>;
|
|
3436
|
+
/** Optional helper text shown under the track. */
|
|
3437
|
+
readonly hint: _angular_core.InputSignal<string | undefined>;
|
|
2387
3438
|
/** Disable interaction. */
|
|
2388
3439
|
readonly disabled: _angular_core.InputSignalWithTransform<boolean, unknown>;
|
|
2389
|
-
/**
|
|
3440
|
+
/** Two-way touched state — set on blur so `FormField` can surface errors. */
|
|
3441
|
+
readonly touched: _angular_core.ModelSignal<boolean>;
|
|
3442
|
+
/** Validation errors — bound by `FormField` from the field. */
|
|
3443
|
+
readonly errors: _angular_core.InputSignal<readonly ValidationError.WithOptionalFieldTree[]>;
|
|
3444
|
+
/** Unique, SSR-safe id for label + message association. */
|
|
2390
3445
|
readonly inputId: string;
|
|
3446
|
+
/** Resolved bounds — the interface types min/max/step as `number | undefined`
|
|
3447
|
+
* (a `FormField` may leave a bound unset); fall back to the standalone defaults. */
|
|
3448
|
+
protected readonly rMin: _angular_core.Signal<number>;
|
|
3449
|
+
protected readonly rMax: _angular_core.Signal<number>;
|
|
3450
|
+
protected readonly rStep: _angular_core.Signal<number>;
|
|
2391
3451
|
/** Fill percentage (0–100) of the track, from the value within [min, max]. */
|
|
2392
3452
|
protected readonly percent: _angular_core.Signal<number>;
|
|
2393
3453
|
/** The value text to display: the explicit {@link valueText} override, else the number. */
|
|
2394
3454
|
protected readonly display: _angular_core.Signal<string>;
|
|
3455
|
+
/** The message under the track: the first error once touched, else the hint. */
|
|
3456
|
+
protected readonly errorMessage: _angular_core.Signal<string | undefined>;
|
|
3457
|
+
protected readonly message: _angular_core.Signal<string | null>;
|
|
3458
|
+
protected readonly describedBy: _angular_core.Signal<string | null>;
|
|
2395
3459
|
protected onInput(event: Event): void;
|
|
3460
|
+
protected onBlur(): void;
|
|
2396
3461
|
static ɵfac: _angular_core.ɵɵFactoryDeclaration<FoldSliderComponent, never>;
|
|
2397
|
-
static ɵcmp: _angular_core.ɵɵComponentDeclaration<FoldSliderComponent, "fold-slider", never, { "value": { "alias": "value"; "required": false; "isSignal": true; }; "min": { "alias": "min"; "required": false; "isSignal": true; }; "max": { "alias": "max"; "required": false; "isSignal": true; }; "step": { "alias": "step"; "required": false; "isSignal": true; }; "label": { "alias": "label"; "required": false; "isSignal": true; }; "valueText": { "alias": "valueText"; "required": false; "isSignal": true; }; "showValue": { "alias": "showValue"; "required": false; "isSignal": true; }; "disabled": { "alias": "disabled"; "required": false; "isSignal": true; }; }, { "value": "valueChange"; }, never, never, true, never>;
|
|
3462
|
+
static ɵcmp: _angular_core.ɵɵComponentDeclaration<FoldSliderComponent, "fold-slider", never, { "value": { "alias": "value"; "required": false; "isSignal": true; }; "min": { "alias": "min"; "required": false; "isSignal": true; }; "max": { "alias": "max"; "required": false; "isSignal": true; }; "step": { "alias": "step"; "required": false; "isSignal": true; }; "label": { "alias": "label"; "required": false; "isSignal": true; }; "ariaLabel": { "alias": "ariaLabel"; "required": false; "isSignal": true; }; "valueText": { "alias": "valueText"; "required": false; "isSignal": true; }; "showValue": { "alias": "showValue"; "required": false; "isSignal": true; }; "hint": { "alias": "hint"; "required": false; "isSignal": true; }; "disabled": { "alias": "disabled"; "required": false; "isSignal": true; }; "touched": { "alias": "touched"; "required": false; "isSignal": true; }; "errors": { "alias": "errors"; "required": false; "isSignal": true; }; }, { "value": "valueChange"; "touched": "touchedChange"; }, never, never, true, never>;
|
|
2398
3463
|
}
|
|
2399
3464
|
|
|
2400
|
-
/** A min↔max pair
|
|
3465
|
+
/** A min↔max pair held by {@link FoldRangeSliderComponent}. */
|
|
2401
3466
|
type FoldRangeValue = {
|
|
2402
3467
|
min: number;
|
|
2403
3468
|
max: number;
|
|
@@ -2407,16 +3472,21 @@ type FoldRangeValue = {
|
|
|
2407
3472
|
* window over `[min, max]`. Shares the design-system track / fill / thumb with
|
|
2408
3473
|
* {@link FoldSliderComponent}. For a single value, use `fold-slider`.
|
|
2409
3474
|
*
|
|
3475
|
+
* Two-way bound via `[(value)]` (a `model()`), or one-way `[value]` +
|
|
3476
|
+
* `(valueChange)`. The thumbs never cross (each clamps against the other). The
|
|
3477
|
+
* pair is a labelled `role="group"`; each thumb announces its formatted value
|
|
3478
|
+
* through `aria-valuetext`, and the thumb names (`minLabel` / `maxLabel`) are
|
|
3479
|
+
* inputs so a non-English app can localise them.
|
|
3480
|
+
*
|
|
2410
3481
|
* @selector `fold-range-slider`
|
|
2411
3482
|
*
|
|
2412
3483
|
* @example
|
|
2413
3484
|
* ```html
|
|
2414
|
-
* <fold-range-slider label="BPM" [min]="60" [max]="220" [step]="5"
|
|
2415
|
-
* [value]="bpm()" (valueChange)="onBpm($event)" />
|
|
3485
|
+
* <fold-range-slider label="BPM" [min]="60" [max]="220" [step]="5" [(value)]="bpm" />
|
|
2416
3486
|
* ```
|
|
2417
3487
|
*/
|
|
2418
3488
|
declare class FoldRangeSliderComponent {
|
|
2419
|
-
/** Label shown above the track. */
|
|
3489
|
+
/** Label shown above the track (names the `role="group"`). */
|
|
2420
3490
|
readonly label: _angular_core.InputSignal<string>;
|
|
2421
3491
|
/** Lower bound of the selectable range. @default 0 */
|
|
2422
3492
|
readonly min: _angular_core.InputSignal<number>;
|
|
@@ -2424,12 +3494,19 @@ declare class FoldRangeSliderComponent {
|
|
|
2424
3494
|
readonly max: _angular_core.InputSignal<number>;
|
|
2425
3495
|
/** Increment granularity. @default 1 */
|
|
2426
3496
|
readonly step: _angular_core.InputSignal<number>;
|
|
2427
|
-
/** The current `{ min, max }` window; falls back to the full range when unset.
|
|
2428
|
-
|
|
2429
|
-
|
|
3497
|
+
/** The current `{ min, max }` window; falls back to the full range when unset.
|
|
3498
|
+
* A `model()`, so `[(value)]` and `(valueChange)` both work. */
|
|
3499
|
+
readonly value: _angular_core.ModelSignal<FoldRangeValue | undefined>;
|
|
3500
|
+
/** How the values are formatted for display + `aria-valuetext`. @default 'number' */
|
|
2430
3501
|
readonly unit: _angular_core.InputSignal<"number" | "duration">;
|
|
2431
|
-
/**
|
|
2432
|
-
readonly
|
|
3502
|
+
/** Disable both thumbs. */
|
|
3503
|
+
readonly disabled: _angular_core.InputSignalWithTransform<boolean, unknown>;
|
|
3504
|
+
/** Accessible name suffix for the lower thumb. @default 'minimum' */
|
|
3505
|
+
readonly minLabel: _angular_core.InputSignal<string>;
|
|
3506
|
+
/** Accessible name suffix for the upper thumb. @default 'maximum' */
|
|
3507
|
+
readonly maxLabel: _angular_core.InputSignal<string>;
|
|
3508
|
+
/** Id of the visible label, so the group can point at it. */
|
|
3509
|
+
readonly labelId: string;
|
|
2433
3510
|
protected readonly currentMin: _angular_core.Signal<number>;
|
|
2434
3511
|
protected readonly currentMax: _angular_core.Signal<number>;
|
|
2435
3512
|
protected readonly fillLeft: _angular_core.Signal<number>;
|
|
@@ -2438,7 +3515,7 @@ declare class FoldRangeSliderComponent {
|
|
|
2438
3515
|
protected onMinChange(event: Event): void;
|
|
2439
3516
|
protected onMaxChange(event: Event): void;
|
|
2440
3517
|
static ɵfac: _angular_core.ɵɵFactoryDeclaration<FoldRangeSliderComponent, never>;
|
|
2441
|
-
static ɵcmp: _angular_core.ɵɵComponentDeclaration<FoldRangeSliderComponent, "fold-range-slider", never, { "label": { "alias": "label"; "required": true; "isSignal": true; }; "min": { "alias": "min"; "required": false; "isSignal": true; }; "max": { "alias": "max"; "required": false; "isSignal": true; }; "step": { "alias": "step"; "required": false; "isSignal": true; }; "value": { "alias": "value"; "required": false; "isSignal": true; }; "unit": { "alias": "unit"; "required": false; "isSignal": true; }; }, { "
|
|
3518
|
+
static ɵcmp: _angular_core.ɵɵComponentDeclaration<FoldRangeSliderComponent, "fold-range-slider", never, { "label": { "alias": "label"; "required": true; "isSignal": true; }; "min": { "alias": "min"; "required": false; "isSignal": true; }; "max": { "alias": "max"; "required": false; "isSignal": true; }; "step": { "alias": "step"; "required": false; "isSignal": true; }; "value": { "alias": "value"; "required": false; "isSignal": true; }; "unit": { "alias": "unit"; "required": false; "isSignal": true; }; "disabled": { "alias": "disabled"; "required": false; "isSignal": true; }; "minLabel": { "alias": "minLabel"; "required": false; "isSignal": true; }; "maxLabel": { "alias": "maxLabel"; "required": false; "isSignal": true; }; }, { "value": "valueChange"; }, never, never, true, never>;
|
|
2442
3519
|
}
|
|
2443
3520
|
|
|
2444
3521
|
/** Severity of a {@link FoldCalloutComponent} — colour + default icon. */
|
|
@@ -3239,6 +4316,53 @@ declare class FoldHeroSectionComponent {
|
|
|
3239
4316
|
static ɵcmp: _angular_core.ɵɵComponentDeclaration<FoldHeroSectionComponent, "fold-hero-section", never, { "align": { "alias": "align"; "required": false; "isSignal": true; }; "wash": { "alias": "wash"; "required": false; "isSignal": true; }; }, {}, never, ["[heroBackdrop]", "*"], true, never>;
|
|
3240
4317
|
}
|
|
3241
4318
|
|
|
4319
|
+
/**
|
|
4320
|
+
* Every user-facing / accessible string the paginator renders. Parameterised
|
|
4321
|
+
* strings (the visible range, a page's aria-label) are functions so a locale
|
|
4322
|
+
* can reorder or reword them, not just translate a fixed template. All defaults
|
|
4323
|
+
* are English — a non-English app overrides them once via
|
|
4324
|
+
* {@link provideFoldPaginatorLabels}, or per instance via the `labels` input.
|
|
4325
|
+
*/
|
|
4326
|
+
interface FoldPaginatorLabels {
|
|
4327
|
+
/** `aria-label` of the page-size `<select>`. */
|
|
4328
|
+
readonly pageSize: string;
|
|
4329
|
+
/** Trailing text after the size selector, e.g. "per page". */
|
|
4330
|
+
readonly perPage: string;
|
|
4331
|
+
/** `aria-label` of the page-navigation `<nav>`. */
|
|
4332
|
+
readonly nav: string;
|
|
4333
|
+
/** Previous-page button `aria-label`. */
|
|
4334
|
+
readonly previous: string;
|
|
4335
|
+
/** Next-page button `aria-label`. */
|
|
4336
|
+
readonly next: string;
|
|
4337
|
+
/** Shown in place of the range when there are no items. */
|
|
4338
|
+
readonly empty: string;
|
|
4339
|
+
/** A page button's `aria-label`, e.g. `(3) => "Page 3"`. */
|
|
4340
|
+
readonly page: (page: number) => string;
|
|
4341
|
+
/** The visible range label, e.g. `(21, 30, 237) => "21–30 of 237"`. */
|
|
4342
|
+
readonly range: (start: number, end: number, total: number) => string;
|
|
4343
|
+
}
|
|
4344
|
+
/** The English defaults — the base every override merges onto. */
|
|
4345
|
+
declare const FOLD_PAGINATOR_DEFAULT_LABELS: FoldPaginatorLabels;
|
|
4346
|
+
/** App-wide paginator labels; defaults to English. */
|
|
4347
|
+
declare const FOLD_PAGINATOR_LABELS: InjectionToken<FoldPaginatorLabels>;
|
|
4348
|
+
/**
|
|
4349
|
+
* Provide app-wide paginator labels once at bootstrap. Partial — any key you
|
|
4350
|
+
* omit keeps its English default.
|
|
4351
|
+
*
|
|
4352
|
+
* @example
|
|
4353
|
+
* ```ts
|
|
4354
|
+
* // app.config.ts
|
|
4355
|
+
* providers: [
|
|
4356
|
+
* provideFoldPaginatorLabels({
|
|
4357
|
+
* perPage: "par page",
|
|
4358
|
+
* previous: "Page précédente",
|
|
4359
|
+
* range: (s, e, t) => `${s}–${e} sur ${t}`,
|
|
4360
|
+
* }),
|
|
4361
|
+
* ];
|
|
4362
|
+
* ```
|
|
4363
|
+
*/
|
|
4364
|
+
declare function provideFoldPaginatorLabels(labels: Partial<FoldPaginatorLabels>): Provider;
|
|
4365
|
+
|
|
3242
4366
|
/**
|
|
3243
4367
|
* Item representing one slot in the page navigation bar.
|
|
3244
4368
|
* Either a concrete page number (1-indexed) or an ellipsis gap.
|
|
@@ -3249,15 +4373,29 @@ type FoldPageItem = {
|
|
|
3249
4373
|
} | {
|
|
3250
4374
|
kind: "gap";
|
|
3251
4375
|
};
|
|
4376
|
+
/** Which control a page change should refocus after the parent re-renders. */
|
|
4377
|
+
type RefocusTarget = "active" | "prev" | "next";
|
|
3252
4378
|
/**
|
|
3253
4379
|
* `fold-paginator` — presentational, fully controlled.
|
|
3254
4380
|
*
|
|
3255
4381
|
* Designed for **server-side pagination** (offset/limit): the parent owns
|
|
3256
4382
|
* `currentPage`, `pageSize` and `totalItems`, fires the HTTP call on
|
|
3257
|
-
* `(pageChange)` / `(pageSizeChange)`, then feeds the new values back in.
|
|
4383
|
+
* `(pageChange)` / `(pageSizeChange)`, then feeds the new values back in. The
|
|
4384
|
+
* component tolerates a lagging or out-of-range `currentPage` — the visible
|
|
4385
|
+
* range, the active button and the prev/next guards all use an internally
|
|
4386
|
+
* clamped page, so a stale value can never render a nonsensical range.
|
|
3258
4387
|
*
|
|
3259
4388
|
* Renders: `[page size selector] [items range] [‹ 1 2 3 … N ›]`.
|
|
3260
4389
|
*
|
|
4390
|
+
* **Accessible:** the `<nav>`, both arrows, each page (`aria-current="page"` on
|
|
4391
|
+
* the active one) and the size selector carry labels, all overridable for i18n
|
|
4392
|
+
* via {@link provideFoldPaginatorLabels} (English by default) or the `labels`
|
|
4393
|
+
* input. After a page change it moves focus to the control the user was on (the
|
|
4394
|
+
* active page, or the prev/next arrow while it stays enabled) so keyboard focus
|
|
4395
|
+
* is never dropped to `<body>`.
|
|
4396
|
+
*
|
|
4397
|
+
* @selector `fold-paginator`
|
|
4398
|
+
*
|
|
3261
4399
|
* @example
|
|
3262
4400
|
* ```html
|
|
3263
4401
|
* <fold-paginator
|
|
@@ -3285,13 +4423,28 @@ declare class FoldPaginatorComponent {
|
|
|
3285
4423
|
*/
|
|
3286
4424
|
readonly siblingCount: _angular_core.InputSignal<number>;
|
|
3287
4425
|
/** Disables all controls (both page nav and size selector). */
|
|
3288
|
-
readonly disabled: _angular_core.
|
|
4426
|
+
readonly disabled: _angular_core.InputSignalWithTransform<boolean, unknown>;
|
|
4427
|
+
/** Per-instance label overrides (merged over the app-wide / English defaults). */
|
|
4428
|
+
readonly labels: _angular_core.InputSignal<Partial<FoldPaginatorLabels> | undefined>;
|
|
3289
4429
|
/** Fires with the new 1-indexed page number. */
|
|
3290
4430
|
readonly pageChange: _angular_core.OutputEmitterRef<number>;
|
|
3291
4431
|
/** Fires with the newly selected page size. */
|
|
3292
4432
|
readonly pageSizeChange: _angular_core.OutputEmitterRef<number>;
|
|
4433
|
+
private readonly host;
|
|
4434
|
+
private readonly injectedLabels;
|
|
4435
|
+
/** Effective labels — the app-wide (or English) set, with the `labels` input on top. */
|
|
4436
|
+
readonly l: _angular_core.Signal<FoldPaginatorLabels>;
|
|
3293
4437
|
/** Total pages, minimum 1 so the UI always shows at least "1 of 1". */
|
|
3294
4438
|
readonly totalPages: _angular_core.Signal<number>;
|
|
4439
|
+
/** The current page clamped into `[1, totalPages]` — the value everything
|
|
4440
|
+
* visible derives from, so a lagging/out-of-range parent never shows a
|
|
4441
|
+
* broken range or highlights a phantom page. */
|
|
4442
|
+
readonly page: _angular_core.Signal<number>;
|
|
4443
|
+
/** Sanitised sibling count — a non-negative integer. */
|
|
4444
|
+
private readonly siblings;
|
|
4445
|
+
/** The rendered size options, always including the current `pageSize` (so the
|
|
4446
|
+
* `<select>` can never silently show a value the parent isn't using). */
|
|
4447
|
+
readonly sizeOptions: _angular_core.Signal<readonly number[]>;
|
|
3295
4448
|
/** Zero-indexed start / end of the currently visible range (for the label). */
|
|
3296
4449
|
readonly rangeStart: _angular_core.Signal<number>;
|
|
3297
4450
|
readonly rangeEnd: _angular_core.Signal<number>;
|
|
@@ -3305,12 +4458,16 @@ declare class FoldPaginatorComponent {
|
|
|
3305
4458
|
* any two non-contiguous blocks.
|
|
3306
4459
|
*/
|
|
3307
4460
|
readonly pageItems: _angular_core.Signal<FoldPageItem[]>;
|
|
3308
|
-
|
|
4461
|
+
private refocus;
|
|
4462
|
+
private lastFocusedPage;
|
|
4463
|
+
constructor();
|
|
4464
|
+
private applyRefocus;
|
|
4465
|
+
goToPage(page: number, via?: RefocusTarget): void;
|
|
3309
4466
|
prev(): void;
|
|
3310
4467
|
next(): void;
|
|
3311
4468
|
onPageSizeChange(raw: string): void;
|
|
3312
4469
|
static ɵfac: _angular_core.ɵɵFactoryDeclaration<FoldPaginatorComponent, never>;
|
|
3313
|
-
static ɵcmp: _angular_core.ɵɵComponentDeclaration<FoldPaginatorComponent, "fold-paginator", never, { "currentPage": { "alias": "currentPage"; "required": true; "isSignal": true; }; "totalItems": { "alias": "totalItems"; "required": true; "isSignal": true; }; "pageSize": { "alias": "pageSize"; "required": true; "isSignal": true; }; "pageSizeOptions": { "alias": "pageSizeOptions"; "required": false; "isSignal": true; }; "siblingCount": { "alias": "siblingCount"; "required": false; "isSignal": true; }; "disabled": { "alias": "disabled"; "required": false; "isSignal": true; }; }, { "pageChange": "pageChange"; "pageSizeChange": "pageSizeChange"; }, never, never, true, never>;
|
|
4470
|
+
static ɵcmp: _angular_core.ɵɵComponentDeclaration<FoldPaginatorComponent, "fold-paginator", never, { "currentPage": { "alias": "currentPage"; "required": true; "isSignal": true; }; "totalItems": { "alias": "totalItems"; "required": true; "isSignal": true; }; "pageSize": { "alias": "pageSize"; "required": true; "isSignal": true; }; "pageSizeOptions": { "alias": "pageSizeOptions"; "required": false; "isSignal": true; }; "siblingCount": { "alias": "siblingCount"; "required": false; "isSignal": true; }; "disabled": { "alias": "disabled"; "required": false; "isSignal": true; }; "labels": { "alias": "labels"; "required": false; "isSignal": true; }; }, { "pageChange": "pageChange"; "pageSizeChange": "pageSizeChange"; }, never, never, true, never>;
|
|
3314
4471
|
}
|
|
3315
4472
|
|
|
3316
4473
|
type FoldViewNavItem = {
|
|
@@ -3387,7 +4544,7 @@ declare class FoldViewNavComponent {
|
|
|
3387
4544
|
* - `compact` (default) — inline / popover bars.
|
|
3388
4545
|
* - `comfortable` — a prominent, page-level bar.
|
|
3389
4546
|
*/
|
|
3390
|
-
readonly size: _angular_core.InputSignal<"
|
|
4547
|
+
readonly size: _angular_core.InputSignal<"comfortable" | "compact">;
|
|
3391
4548
|
/**
|
|
3392
4549
|
* Collapse the bar to icons (independent of {@link size}). **Horizontal**, an
|
|
3393
4550
|
* icon accordion: every item but the active one drops to its icon, the active
|
|
@@ -3483,7 +4640,7 @@ declare class FoldTabsComponent implements FoldTabsContext {
|
|
|
3483
4640
|
*/
|
|
3484
4641
|
readonly direction: _angular_core.InputSignal<"auto" | "vertical" | "horizontal">;
|
|
3485
4642
|
/** Density — see {@link FoldViewNavComponent} for the same scale. */
|
|
3486
|
-
readonly size: _angular_core.InputSignal<"
|
|
4643
|
+
readonly size: _angular_core.InputSignal<"comfortable" | "compact">;
|
|
3487
4644
|
/** Collapse to icons — see {@link FoldViewNavComponent.collapsed}. */
|
|
3488
4645
|
readonly collapsed: _angular_core.InputSignalWithTransform<boolean, unknown>;
|
|
3489
4646
|
/** `surface` (filled bar, default) or `transparent`. */
|
|
@@ -3997,6 +5154,220 @@ interface FoldPanelLabels {
|
|
|
3997
5154
|
*/
|
|
3998
5155
|
declare function provideFoldPanelLabels(labels: FoldPanelLabels): Provider;
|
|
3999
5156
|
|
|
5157
|
+
/**
|
|
5158
|
+
* `<fold-popover>` — an anchored floating layer. Project a trigger
|
|
5159
|
+
* (`[foldPopoverTrigger]`) and any content; the content renders in the native
|
|
5160
|
+
* **top layer** (via the `popover` attribute, so it escapes `overflow: hidden`
|
|
5161
|
+
* and every `z-index`) and is positioned against the trigger with a
|
|
5162
|
+
* dependency-free flip/shift engine ({@link computePlacement}).
|
|
5163
|
+
*
|
|
5164
|
+
* Controlled or uncontrolled through `[(open)]`. Dismissal is owned here
|
|
5165
|
+
* (outside-click + `Escape`) rather than the browser's light-dismiss, so
|
|
5166
|
+
* re-clicking the trigger toggles cleanly instead of reopening. Opening moves
|
|
5167
|
+
* focus into the panel; closing returns it to the trigger. The trigger gets
|
|
5168
|
+
* `aria-haspopup` / `aria-expanded` / `aria-controls` wired automatically.
|
|
5169
|
+
*
|
|
5170
|
+
* For an actions menu with `role="menu"` + keyboard, use `fold-dropdown`, which
|
|
5171
|
+
* is built on this.
|
|
5172
|
+
*
|
|
5173
|
+
* The panel's width is `max-content`; to make it match the trigger (a select-like
|
|
5174
|
+
* dropdown), read the published `--fold-popover-anchor-width` in the panel's CSS
|
|
5175
|
+
* (e.g. `min-width: var(--fold-popover-anchor-width)`) — it tracks the trigger.
|
|
5176
|
+
*
|
|
5177
|
+
* @selector `fold-popover`
|
|
5178
|
+
*
|
|
5179
|
+
* The trigger carries `[foldPopoverTrigger]`; the floating content is marked
|
|
5180
|
+
* `foldPopoverPanel`.
|
|
5181
|
+
*
|
|
5182
|
+
* @example
|
|
5183
|
+
* ```html
|
|
5184
|
+
* <fold-popover placement="bottom-end">
|
|
5185
|
+
* <button foldButton foldPopoverTrigger>Filters</button>
|
|
5186
|
+
* <div foldPopoverPanel class="my-panel">…</div>
|
|
5187
|
+
* </fold-popover>
|
|
5188
|
+
* ```
|
|
5189
|
+
*/
|
|
5190
|
+
declare class FoldPopoverComponent {
|
|
5191
|
+
private readonly renderer;
|
|
5192
|
+
private readonly host;
|
|
5193
|
+
/** Preferred placement before collision handling. @default "bottom-start" */
|
|
5194
|
+
readonly placement: _angular_core.InputSignal<FoldPopoverPlacement>;
|
|
5195
|
+
/** Ordered placements to try when the preferred can't fit (default: the
|
|
5196
|
+
* opposite side). The first that fits wins, else the roomiest. */
|
|
5197
|
+
readonly fallbackPlacements: _angular_core.InputSignal<readonly FoldPopoverPlacement[] | undefined>;
|
|
5198
|
+
/** Gap between the trigger and the panel, in px. @default 8 */
|
|
5199
|
+
readonly offset: _angular_core.InputSignal<number>;
|
|
5200
|
+
/** Minimum gap kept from the viewport edge, in px. @default 8 */
|
|
5201
|
+
readonly padding: _angular_core.InputSignal<number>;
|
|
5202
|
+
/** Move focus into the panel on open. @default true (a dropdown sets false to
|
|
5203
|
+
* focus its first item instead). */
|
|
5204
|
+
readonly autoFocus: _angular_core.InputSignal<boolean>;
|
|
5205
|
+
/** Show a small arrow pointing at the trigger. @default false */
|
|
5206
|
+
readonly arrow: _angular_core.InputSignalWithTransform<boolean, unknown>;
|
|
5207
|
+
/** Two-way open state — drive it, or let the trigger toggle it. */
|
|
5208
|
+
readonly open: _angular_core.ModelSignal<boolean>;
|
|
5209
|
+
/** SSR-safe id linking the trigger's `aria-controls` to the panel. */
|
|
5210
|
+
readonly panelId: string;
|
|
5211
|
+
/** Override the trigger's `aria-controls` target — point it at the real
|
|
5212
|
+
* controlled element (e.g. an inner `role="listbox"`) when the panel is just a
|
|
5213
|
+
* wrapper. @default the panel's own id. */
|
|
5214
|
+
readonly ariaControls: _angular_core.InputSignal<string | undefined>;
|
|
5215
|
+
private readonly panel;
|
|
5216
|
+
private readonly inner;
|
|
5217
|
+
private readonly arrowEl;
|
|
5218
|
+
/**
|
|
5219
|
+
* The marked trigger — the projected `[foldPopoverTrigger]`. Found by DOM
|
|
5220
|
+
* query on the host (projected content is a DOM descendant of the host), so it
|
|
5221
|
+
* resolves regardless of how deeply it is re-projected (e.g. through
|
|
5222
|
+
* `fold-dropdown`) — a content query would not survive the re-projection. Used
|
|
5223
|
+
* to anchor against and to detect trigger clicks.
|
|
5224
|
+
*/
|
|
5225
|
+
private markedTrigger;
|
|
5226
|
+
private static readonly FOCUSABLE;
|
|
5227
|
+
/**
|
|
5228
|
+
* The focusable trigger — the marked element itself if it's focusable, else
|
|
5229
|
+
* the first focusable inside it (e.g. `fold-button-icon`'s inner `<button>`).
|
|
5230
|
+
* This is what receives focus + the aria wiring, so a wrapper trigger is still
|
|
5231
|
+
* fully keyboard-accessible.
|
|
5232
|
+
*/
|
|
5233
|
+
private focusableTrigger;
|
|
5234
|
+
constructor();
|
|
5235
|
+
/** Position the panel against the trigger: flip → size (cap + scroll) → shift,
|
|
5236
|
+
* then place the arrow. */
|
|
5237
|
+
private reposition;
|
|
5238
|
+
/** Set a `max-*` cap in px, but only when positive (skip a degenerate 0). */
|
|
5239
|
+
private applyCap;
|
|
5240
|
+
/** Center the arrow on the anchor along the cross axis, clamped to the panel. */
|
|
5241
|
+
private positionArrow;
|
|
5242
|
+
protected onHostClick(event: MouseEvent): void;
|
|
5243
|
+
protected onArrowDown(event: Event): void;
|
|
5244
|
+
static ɵfac: _angular_core.ɵɵFactoryDeclaration<FoldPopoverComponent, never>;
|
|
5245
|
+
static ɵcmp: _angular_core.ɵɵComponentDeclaration<FoldPopoverComponent, "fold-popover", never, { "placement": { "alias": "placement"; "required": false; "isSignal": true; }; "fallbackPlacements": { "alias": "fallbackPlacements"; "required": false; "isSignal": true; }; "offset": { "alias": "offset"; "required": false; "isSignal": true; }; "padding": { "alias": "padding"; "required": false; "isSignal": true; }; "autoFocus": { "alias": "autoFocus"; "required": false; "isSignal": true; }; "arrow": { "alias": "arrow"; "required": false; "isSignal": true; }; "open": { "alias": "open"; "required": false; "isSignal": true; }; "ariaControls": { "alias": "ariaControls"; "required": false; "isSignal": true; }; }, { "open": "openChange"; }, never, ["*", "[foldPopoverPanel]"], true, never>;
|
|
5246
|
+
}
|
|
5247
|
+
|
|
5248
|
+
/**
|
|
5249
|
+
* Marks the element inside a `<fold-popover>` that opens it — apply to a real,
|
|
5250
|
+
* focusable control (a `foldButton`), or a wrapper whose first focusable child
|
|
5251
|
+
* is the control (a `fold-button-icon`). The popover anchors to this element,
|
|
5252
|
+
* and wires `aria-haspopup` / `aria-expanded` / `aria-controls` onto the
|
|
5253
|
+
* focusable control. The value picks the `aria-haspopup` token — it is reflected
|
|
5254
|
+
* to the marker attribute so both `foldPopoverTrigger="menu"` and
|
|
5255
|
+
* `[foldPopoverTrigger]="expr"` work.
|
|
5256
|
+
*
|
|
5257
|
+
* ```html
|
|
5258
|
+
* <fold-popover>
|
|
5259
|
+
* <button foldButton foldPopoverTrigger="menu">Actions</button>
|
|
5260
|
+
* …panel…
|
|
5261
|
+
* </fold-popover>
|
|
5262
|
+
* ```
|
|
5263
|
+
*
|
|
5264
|
+
* @selector `[foldPopoverTrigger]`
|
|
5265
|
+
*/
|
|
5266
|
+
declare class FoldPopoverTriggerDirective {
|
|
5267
|
+
/** The trigger's host element. */
|
|
5268
|
+
readonly el: ElementRef<HTMLElement>;
|
|
5269
|
+
/**
|
|
5270
|
+
* `aria-haspopup` value. @default "dialog" (use "menu" for a dropdown). Bare
|
|
5271
|
+
* `foldPopoverTrigger` (no value) keeps the default.
|
|
5272
|
+
*/
|
|
5273
|
+
readonly haspopup: _angular_core.InputSignalWithTransform<FoldTriggerHaspopup, string>;
|
|
5274
|
+
static ɵfac: _angular_core.ɵɵFactoryDeclaration<FoldPopoverTriggerDirective, never>;
|
|
5275
|
+
static ɵdir: _angular_core.ɵɵDirectiveDeclaration<FoldPopoverTriggerDirective, "[foldPopoverTrigger]", never, { "haspopup": { "alias": "foldPopoverTrigger"; "required": false; "isSignal": true; }; }, {}, never, never, true, never>;
|
|
5276
|
+
}
|
|
5277
|
+
type FoldTriggerHaspopup = "menu" | "dialog" | "listbox" | "true";
|
|
5278
|
+
|
|
5279
|
+
/**
|
|
5280
|
+
* `<fold-dropdown>` — an actions menu built on {@link FoldPopoverComponent}.
|
|
5281
|
+
* Project a trigger (`[foldPopoverTrigger]`) and a list of
|
|
5282
|
+
* `<fold-dropdown-item>`s; the menu is a `role="menu"` with full keyboard
|
|
5283
|
+
* support (↑/↓ roving, `Home`/`End`, type-ahead), opens focused on its first
|
|
5284
|
+
* enabled item, and closes — returning focus to the trigger — when an item is
|
|
5285
|
+
* chosen or on `Escape` / outside-click. Give the trigger `foldPopoverTrigger="menu"`
|
|
5286
|
+
* so its `aria-haspopup` reads as a menu.
|
|
5287
|
+
*
|
|
5288
|
+
* @selector `fold-dropdown`
|
|
5289
|
+
*
|
|
5290
|
+
* @example
|
|
5291
|
+
* ```html
|
|
5292
|
+
* <fold-dropdown ariaLabel="Row actions">
|
|
5293
|
+
* <fold-button-icon icon="more-vertical" tooltip="Actions" foldPopoverTrigger="menu" />
|
|
5294
|
+
* <fold-dropdown-item icon="edit" (selected)="rename(row)">Rename</fold-dropdown-item>
|
|
5295
|
+
* <fold-dropdown-item tone="danger" (selected)="remove(row)">Delete</fold-dropdown-item>
|
|
5296
|
+
* </fold-dropdown>
|
|
5297
|
+
* ```
|
|
5298
|
+
*/
|
|
5299
|
+
declare class FoldDropdownComponent {
|
|
5300
|
+
private readonly renderer;
|
|
5301
|
+
/** Preferred placement. @default "bottom-start" */
|
|
5302
|
+
readonly placement: _angular_core.InputSignal<FoldPopoverPlacement>;
|
|
5303
|
+
/** Gap between trigger and menu, in px. @default 8 */
|
|
5304
|
+
readonly offset: _angular_core.InputSignal<number>;
|
|
5305
|
+
/** Accessible name of the menu. */
|
|
5306
|
+
readonly ariaLabel: _angular_core.InputSignal<string | undefined>;
|
|
5307
|
+
/** Two-way open state. */
|
|
5308
|
+
readonly open: _angular_core.ModelSignal<boolean>;
|
|
5309
|
+
private readonly items;
|
|
5310
|
+
/** Active row = index into {@link enabled}. Roving state lives here (not read
|
|
5311
|
+
* from `document.activeElement`), so it stays correct regardless of focus. */
|
|
5312
|
+
private readonly active;
|
|
5313
|
+
constructor();
|
|
5314
|
+
/** Enabled items only — keyboard nav + focus skip disabled rows. */
|
|
5315
|
+
private enabled;
|
|
5316
|
+
private focusIndex;
|
|
5317
|
+
protected onMenuKeydown(event: KeyboardEvent): void;
|
|
5318
|
+
/** Type-ahead buffer (multi-letter): keystrokes within 500 ms accumulate, so
|
|
5319
|
+
* "de" jumps to "Delete", not just the next "d". */
|
|
5320
|
+
private typeBuffer;
|
|
5321
|
+
private typeAt;
|
|
5322
|
+
private typeahead;
|
|
5323
|
+
/** A menuitem was activated (click / Enter / Space bubbles here) → close. */
|
|
5324
|
+
protected onMenuActivate(event: MouseEvent): void;
|
|
5325
|
+
static ɵfac: _angular_core.ɵɵFactoryDeclaration<FoldDropdownComponent, never>;
|
|
5326
|
+
static ɵcmp: _angular_core.ɵɵComponentDeclaration<FoldDropdownComponent, "fold-dropdown", never, { "placement": { "alias": "placement"; "required": false; "isSignal": true; }; "offset": { "alias": "offset"; "required": false; "isSignal": true; }; "ariaLabel": { "alias": "ariaLabel"; "required": false; "isSignal": true; }; "open": { "alias": "open"; "required": false; "isSignal": true; }; }, { "open": "openChange"; }, ["items"], ["[foldPopoverTrigger]", "*"], true, never>;
|
|
5327
|
+
}
|
|
5328
|
+
|
|
5329
|
+
/**
|
|
5330
|
+
* `<fold-dropdown-item>` — one actionable row inside a {@link FoldDropdownComponent}.
|
|
5331
|
+
* Renders a `role="menuitem"` button; emits `selected` on activation (click,
|
|
5332
|
+
* `Enter` or `Space`) and the parent closes the menu. Roving focus + arrow-key
|
|
5333
|
+
* navigation are owned by the dropdown.
|
|
5334
|
+
*
|
|
5335
|
+
* @selector `fold-dropdown-item`
|
|
5336
|
+
*
|
|
5337
|
+
* @example
|
|
5338
|
+
* ```html
|
|
5339
|
+
* <fold-dropdown-item icon="edit" (selected)="rename()">Rename</fold-dropdown-item>
|
|
5340
|
+
* <fold-dropdown-item tone="danger" (selected)="remove()">Delete</fold-dropdown-item>
|
|
5341
|
+
* ```
|
|
5342
|
+
*/
|
|
5343
|
+
declare class FoldDropdownItemComponent {
|
|
5344
|
+
/** Disable the row — skipped by keyboard navigation, inert to clicks. */
|
|
5345
|
+
readonly disabled: _angular_core.InputSignalWithTransform<boolean, unknown>;
|
|
5346
|
+
/** Visual tone. @default "default" */
|
|
5347
|
+
readonly tone: _angular_core.InputSignal<"danger" | "default">;
|
|
5348
|
+
/** Optional leading icon. */
|
|
5349
|
+
readonly icon: _angular_core.InputSignal<FoldIconName | undefined>;
|
|
5350
|
+
/** Emitted on activation (click / Enter / Space). */
|
|
5351
|
+
readonly selected: _angular_core.OutputEmitterRef<void>;
|
|
5352
|
+
private readonly btn;
|
|
5353
|
+
/** The native button — the dropdown reads it for roving focus + typeahead. */
|
|
5354
|
+
get button(): HTMLButtonElement | undefined;
|
|
5355
|
+
focus(): void;
|
|
5356
|
+
protected onClick(): void;
|
|
5357
|
+
static ɵfac: _angular_core.ɵɵFactoryDeclaration<FoldDropdownItemComponent, never>;
|
|
5358
|
+
static ɵcmp: _angular_core.ɵɵComponentDeclaration<FoldDropdownItemComponent, "fold-dropdown-item", never, { "disabled": { "alias": "disabled"; "required": false; "isSignal": true; }; "tone": { "alias": "tone"; "required": false; "isSignal": true; }; "icon": { "alias": "icon"; "required": false; "isSignal": true; }; }, { "selected": "selected"; }, never, ["*"], true, never>;
|
|
5359
|
+
}
|
|
5360
|
+
|
|
5361
|
+
/**
|
|
5362
|
+
* Keep a floating element pinned to its anchor: call `onChange` whenever
|
|
5363
|
+
* anything that could move the anchor or resize either element happens —
|
|
5364
|
+
* scrolling (capture phase, so nested scroll containers count), a window
|
|
5365
|
+
* resize, or a size change of the anchor / floating element (`ResizeObserver`).
|
|
5366
|
+
* Returns a teardown that removes every listener. Mirrors Floating UI's
|
|
5367
|
+
* `autoUpdate`, dependency-free and scoped to fold's needs.
|
|
5368
|
+
*/
|
|
5369
|
+
declare function autoUpdate(anchor: HTMLElement | null, floating: HTMLElement, onChange: () => void): () => void;
|
|
5370
|
+
|
|
4000
5371
|
/**
|
|
4001
5372
|
* Categorical auto-colour palettes + the seed→index hash.
|
|
4002
5373
|
*
|
|
@@ -4064,6 +5435,6 @@ declare class FoldPaletteRegistry {
|
|
|
4064
5435
|
static ɵprov: _angular_core.ɵɵInjectableDeclaration<FoldPaletteRegistry>;
|
|
4065
5436
|
}
|
|
4066
5437
|
|
|
4067
|
-
export { FOLD_AUTO_PALETTES, FOLD_BLUR_TOKENS, FOLD_BUILTIN_ICONS, FOLD_MOTION_TOKENS, FOLD_PALETTE_DEFAULT, FOLD_PANEL_CLOSE_LABEL, FOLD_RADIUS_TOKENS, FOLD_SEMANTIC_COLOR_TOKENS, FOLD_SHADOW_TOKENS, FOLD_SPACE_TOKENS, FOLD_TEXT_TOKENS, FOLD_TOAST_CONFIG, FoldAppShellComponent, FoldAsideLayoutComponent, FoldAvatarComponent, FoldAvatarDetailComponent, FoldAvatarListComponent, FoldBadgeComponent, FoldButtonComponent, FoldButtonIconComponent, FoldCalloutComponent, FoldCardComponent, FoldChoiceRowComponent, FoldContextCardComponent, FoldDataTableCellDirective, FoldDataTableComponent, FoldDisclosureComponent, FoldElementTitleComponent, FoldElevatedDirective, FoldEmptyStateComponent, FoldFieldComponent, FoldFieldIdDirective, FoldFieldListComponent, FoldFileDropzoneComponent, FoldHeroCardComponent, FoldHeroSectionComponent, FoldIconComponent, FoldIconRegistry, FoldIdService, FoldInputComponent, FoldLinkComponent, FoldLoadingStateComponent, FoldMenuComponent, FoldMenuItemComponent, FoldMenuSectionComponent, FoldMenuSeparatorComponent, FoldNavLauncherComponent, FoldNavLayoutComponent, FoldNavTileComponent, FoldNumberInputComponent, FoldPageLayoutComponent, FoldPageSectionComponent, FoldPageTitleDirective, FoldPaginatorComponent, FoldPaletteRegistry, FoldPanelComponentOutletDirective, FoldPanelHeaderComponent, FoldPanelHostComponent, FoldPanelHostService, FoldPanelRef, FoldPanelToggle, FoldRangeSliderComponent, FoldRepeatPressDirective, FoldSearchComponent, FoldSelectComponent, FoldSliderComponent, FoldSpinnerComponent, FoldStatusBadgeComponent, FoldStickyColumnDirective, FoldSurfaceDirective, FoldTabPanelComponent, FoldTabsComponent, FoldTimelineComponent, FoldToastComponent, FoldToastContainerComponent, FoldToastService, FoldToggleIconComponent, FoldViewNavComponent, foldBlurVar, foldColorProperty, foldColorVar, foldHashSeed, foldMotionVar, foldRadiusVar, foldResolvePalette, foldShadowVar, foldSpaceVar, foldTextVar, observeElementWidth, provideFoldIcons, provideFoldPalette, provideFoldPanelLabels, provideFoldToasts };
|
|
4068
|
-
export type { FoldAutoPaletteName, FoldAvatarListItem, FoldAvatarRing, FoldAvatarRingStyle, FoldAvatarVariant, FoldBadgeVariant, FoldBlurToken, FoldBuiltinIconName, FoldButtonEmphasis, FoldButtonIconShape, FoldButtonIconSize, FoldButtonIconTone, FoldButtonIntent, FoldButtonShape, FoldButtonSize, FoldCalloutAppearance, FoldCalloutVariant, FoldChoiceOption, FoldComponentPanelDescriptor, FoldIconName, FoldIconSet, FoldIconSize, FoldMenuItemBadgeTone, FoldMenuLevel, FoldMenuTint, FoldMenuTogglePlacement, FoldMotionToken, FoldNumberControls, FoldNumberSpinner, FoldPageItem, FoldPaletteInput, FoldPanelConfig, FoldPanelContent, FoldPanelDescriptor, FoldPanelHandle, FoldPanelLabels, FoldPanelSide, FoldRadiusToken, FoldRangeValue, FoldSemanticColorToken, FoldShadowToken, FoldSpaceToken, FoldSpinnerSize, FoldStickyColumnAnchor, FoldSurfaceName, FoldTabItem, FoldTableColumn, FoldTableEmpty, FoldTableSort, FoldTableSortDir, FoldTableTone, FoldTabsContext, FoldTemplatePanelDescriptor, FoldTextToken, FoldTimelineDatePlacement, FoldTimelineNode, FoldToast, FoldToastConfig, FoldToastVariant, FoldViewNavItem };
|
|
5438
|
+
export { FOLD_AUTO_PALETTES, FOLD_BLUR_TOKENS, FOLD_BUILTIN_ICONS, FOLD_DATA_TABLE_DEFAULT_LABELS, FOLD_DATA_TABLE_LABELS, FOLD_INLINE_CONFIRM_DEFAULT_LABELS, FOLD_INLINE_CONFIRM_LABELS, FOLD_MOTION_TOKENS, FOLD_PAGINATOR_DEFAULT_LABELS, FOLD_PAGINATOR_LABELS, FOLD_PALETTE_DEFAULT, FOLD_PANEL_CLOSE_LABEL, FOLD_RADIUS_TOKENS, FOLD_SEMANTIC_COLOR_TOKENS, FOLD_SHADOW_TOKENS, FOLD_SPACE_TOKENS, FOLD_TEXT_TOKENS, FOLD_TOAST_CONFIG, FoldAppShellComponent, FoldAsideLayoutComponent, FoldAvatarComponent, FoldAvatarDetailComponent, FoldAvatarListComponent, FoldBadgeComponent, FoldButtonComponent, FoldButtonIconComponent, FoldCalloutComponent, FoldCardComponent, FoldCheckboxComponent, FoldChoiceRowComponent, FoldContextCardComponent, FoldDataTableCellDirective, FoldDataTableComponent, FoldDataTableRowCardDirective, FoldDisclosureComponent, FoldDropdownComponent, FoldDropdownItemComponent, FoldElementTitleComponent, FoldElevatedDirective, FoldEmptyStateComponent, FoldFieldComponent, FoldFieldIdDirective, FoldFieldListComponent, FoldFileDropzoneComponent, FoldHeroCardComponent, FoldHeroSectionComponent, FoldIconComponent, FoldIconRegistry, FoldIdService, FoldInlineConfirmComponent, FoldInputComponent, FoldLinkComponent, FoldListboxComponent, FoldLoadingStateComponent, FoldMenuComponent, FoldMenuItemComponent, FoldMenuSectionComponent, FoldMenuSeparatorComponent, FoldMultiselectComponent, FoldNavLauncherComponent, FoldNavLayoutComponent, FoldNavTileComponent, FoldNumberInputComponent, FoldOptionComponent, FoldPageLayoutComponent, FoldPageSectionComponent, FoldPageTitleDirective, FoldPaginatorComponent, FoldPaletteRegistry, FoldPanelComponentOutletDirective, FoldPanelHeaderComponent, FoldPanelHostComponent, FoldPanelHostService, FoldPanelRef, FoldPanelToggle, FoldPasswordFieldComponent, FoldPopoverComponent, FoldPopoverTriggerDirective, FoldRangeSliderComponent, FoldRepeatPressDirective, FoldSearchComponent, FoldSelectComponent, FoldSliderComponent, FoldSpinnerComponent, FoldStatusBadgeComponent, FoldStickyColumnDirective, FoldSurfaceDirective, FoldTabPanelComponent, FoldTabsComponent, FoldTimelineComponent, FoldToastComponent, FoldToastContainerComponent, FoldToastService, FoldToggleIconComponent, FoldViewNavComponent, FoldViewToggleComponent, autoUpdate, computePlacement, foldBlurVar, foldColorProperty, foldColorVar, foldDefaultPasswordRules, foldHashSeed, foldMotionVar, foldRadiusVar, foldRegexRule, foldResolvePalette, foldShadowVar, foldSpaceVar, foldTextVar, observeElementWidth, provideFoldDataTableLabels, provideFoldIcons, provideFoldInlineConfirmLabels, provideFoldPaginatorLabels, provideFoldPalette, provideFoldPanelLabels, provideFoldToasts };
|
|
5439
|
+
export type { FoldAutoPaletteName, FoldAvatarListItem, FoldAvatarRing, FoldAvatarRingStyle, FoldAvatarVariant, FoldBadgeVariant, FoldBlurToken, FoldBuiltinIconName, FoldButtonEmphasis, FoldButtonIconShape, FoldButtonIconSize, FoldButtonIconTone, FoldButtonIntent, FoldButtonShape, FoldButtonSize, FoldCalloutAppearance, FoldCalloutVariant, FoldCardBandChrome, FoldChoiceOption, FoldComponentPanelDescriptor, FoldDataTableLabels, FoldIconName, FoldIconSet, FoldIconSize, FoldInlineConfirmLabels, FoldMenuItemBadgeTone, FoldMenuLevel, FoldMenuTint, FoldMenuTogglePlacement, FoldMotionToken, FoldNumberControls, FoldNumberSpinner, FoldPageItem, FoldPaginatorLabels, FoldPaletteInput, FoldPanelConfig, FoldPanelContent, FoldPanelDescriptor, FoldPanelHandle, FoldPanelLabels, FoldPanelSide, FoldPasswordRule, FoldPlacementInput, FoldPlacementResult, FoldPopoverAlign, FoldPopoverPlacement, FoldPopoverSide, FoldRadiusToken, FoldRangeValue, FoldRect, FoldSelectOption, FoldSemanticColorToken, FoldShadowToken, FoldSpaceToken, FoldSpinnerSize, FoldStickyColumnAnchor, FoldSurfaceName, FoldTabItem, FoldTableColumn, FoldTableEmpty, FoldTableSort, FoldTableSortDir, FoldTableTone, FoldTabsContext, FoldTemplatePanelDescriptor, FoldTextToken, FoldTimelineDatePlacement, FoldTimelineNode, FoldToast, FoldToastConfig, FoldToastVariant, FoldViewNavItem, FoldViewToggleOption };
|
|
4069
5440
|
//# sourceMappingURL=fold-ng.d.ts.map
|