fold-ng 0.24.0 → 0.25.0
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 +43 -1
- package/README.md +1 -1
- package/fesm2022/fold-ng.mjs +147 -30
- package/fesm2022/fold-ng.mjs.map +1 -1
- package/package.json +1 -1
- package/tmp-esm2022/tsconfig.lib.tsbuildinfo +1 -1
- package/types/fold-ng.d.ts +119 -8
- package/types/fold-ng.d.ts.map +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -8,6 +8,47 @@ All notable changes to **fold-ng** are documented here. The format follows
|
|
|
8
8
|
|
|
9
9
|
_Nothing yet._
|
|
10
10
|
|
|
11
|
+
## [0.25.0] - 2026-09-05
|
|
12
|
+
|
|
13
|
+
### Added
|
|
14
|
+
|
|
15
|
+
- **`fold-search` devient un contrôle, et non plus un capteur.** Sa `value` est
|
|
16
|
+
un `model()` : la boîte se pilote donc de l'extérieur. C'est ce qui manquait
|
|
17
|
+
pour qu'elle remplace une recherche écrite à la main — choisir un filtre
|
|
18
|
+
ailleurs doit pouvoir VIDER le champ, et une recherche en écriture seule
|
|
19
|
+
continuait d'afficher un terme que les résultats n'honoraient plus.
|
|
20
|
+
|
|
21
|
+
Deux façons de s'en servir, et elles répondent à deux questions : `[(value)]`
|
|
22
|
+
donne le terme comme **état**, à chaque frappe — c'est ce que veut un filtrage
|
|
23
|
+
d'un tableau déjà en mémoire, où l'anti-rebond n'ajoute que de la latence ;
|
|
24
|
+
`(searchChange)` le donne comme **événement**, une fois posé — c'est ce que
|
|
25
|
+
veut une requête au serveur. Les deux se composent. Écrire `value` de
|
|
26
|
+
l'extérieur n'émet jamais : celui qui écrit sait déjà.
|
|
27
|
+
|
|
28
|
+
- **`fold-search` porte enfin sa loupe, sa croix et son compte.** Les trois
|
|
29
|
+
étaient recopiés dans chaque écran, avec le même oubli à chaque fois : le
|
|
30
|
+
compte de résultats change sous une recherche, donc il doit être **annoncé**.
|
|
31
|
+
Il porte `role="status"` et `aria-live="polite"`, et un utilisateur qui ne
|
|
32
|
+
voit pas la grille apprend enfin que quatre cents lignes sont devenues trois.
|
|
33
|
+
|
|
34
|
+
`resultCount` (rien tant qu'il vaut `null`), `resultLabel` (le mot après le
|
|
35
|
+
nombre — « pièces », "rows") et `placement` : `top`, `end` ou `bottom`.
|
|
36
|
+
`end` et non `right` — la bibliothèque se pose en propriétés **logiques**, et
|
|
37
|
+
le compte doit suivre le sens de lecture plutôt qu'un côté de l'écran.
|
|
38
|
+
|
|
39
|
+
- **`fold-input` gagne deux affixes**, et c'est de là que `fold-search` tire les
|
|
40
|
+
siens : `leadingIcon` dessine un glyphe DANS la boîte, avant le texte (le
|
|
41
|
+
champ réserve la place lui-même, et le glyphe ne prend pas le clic) ;
|
|
42
|
+
`clearable` + `clearLabel` posent un `×` de fin tant qu'il y a quelque chose à
|
|
43
|
+
effacer, qui vide la valeur **et rend le focus** — sans quoi il faut un second
|
|
44
|
+
clic pour reprendre la saisie.
|
|
45
|
+
|
|
46
|
+
Les deux sont à `false` par défaut : un champ de formulaire qui s'efface tout
|
|
47
|
+
seul invite l'accident qu'il ne sait pas défaire. Le `×` ne paraît ni en
|
|
48
|
+
lecture seule ni désactivé — il promettrait un geste que le contrôle refuse —
|
|
49
|
+
et un mot de passe `revealable` garde la place de fin : perdre son œil casse
|
|
50
|
+
la saisie, perdre la croix la rend seulement moins commode.
|
|
51
|
+
|
|
11
52
|
## [0.24.0] - 2026-08-29
|
|
12
53
|
|
|
13
54
|
### Added
|
|
@@ -2414,7 +2455,8 @@ design-token stylesheet.
|
|
|
2414
2455
|
`currentColor`; `prefers-reduced-motion` + `forced-colors` are respected;
|
|
2415
2456
|
strings localise via inputs / providers (`provideFoldPanelLabels`).
|
|
2416
2457
|
|
|
2417
|
-
[unreleased]: https://github.com/hugoheynard/fold-ng/compare/v0.
|
|
2458
|
+
[unreleased]: https://github.com/hugoheynard/fold-ng/compare/v0.25.0...HEAD
|
|
2459
|
+
[0.25.0]: https://github.com/hugoheynard/fold-ng/releases/tag/v0.25.0
|
|
2418
2460
|
[0.24.0]: https://github.com/hugoheynard/fold-ng/releases/tag/v0.24.0
|
|
2419
2461
|
[0.23.0]: https://github.com/hugoheynard/fold-ng/releases/tag/v0.23.0
|
|
2420
2462
|
[0.22.1]: https://github.com/hugoheynard/fold-ng/releases/tag/v0.22.1
|
package/README.md
CHANGED
|
@@ -353,7 +353,7 @@ ships it.
|
|
|
353
353
|
| `FoldFieldsetComponent` | `fold-fieldset` | Named group of controls — a real `<fieldset>`/`<legend>` with the browser's margin/padding/3D border undone and the rhythm on tokens. `disabled` disables every control inside (the element's unique power); `hint` wired through `aria-describedby` (`hintPosition` `under`/`inline`); `legend` (empty renders none) or `ariaLabel`; `optional` marks the whole group (not each member); `legendVariant` (`eyebrow`/`heading` — the same two registers as a page-section's title), `direction` (`vertical`/`horizontal`), `appearance` (`plain`/`border`); `--fold-fieldset-gap`. |
|
|
354
354
|
| `FoldPasswordFieldComponent` | `fold-password-field` | Password input + a live requirements checklist (a dot/tick per rule). Rules injected via `FoldPasswordRule` (`{ label, test }` — regex/zod/anything); `revealable` eye (a `fold-input` capability); `marker` dot/check; `[rules]` slot to redesign the list; `validChange`; Signal Forms. |
|
|
355
355
|
| `FoldViewToggleComponent` | `fold-view-toggle` | Segmented single-select (Cards/Table, density, chart-mode…). Generic `options` (`{ value, icon?, label?, ariaLabel?, disabled? }`) + `[(value)]`; a real `role="radiogroup"` — roving tabindex, arrow keys, Home/End, disabled-skip; `size`, `iconOnly`, `activeStyle` (raised / accent). |
|
|
356
|
-
| `FoldSearchComponent` | `fold-search` |
|
|
356
|
+
| `FoldSearchComponent` | `fold-search` | Search box — magnifier, clear `×`, optional announced result count (`resultCount` / `resultLabel` / `placement`). `[(value)]` is the term as state (every keystroke); `searchChange` emits it once typing settles (`delayMs`), trimmed + de-duplicated. |
|
|
357
357
|
| `FoldListboxComponent` / `FoldOptionComponent` | `fold-listbox` / `fold-option` | Styleable single-select — the richer sibling of `fold-select` (native `<select>`) for options that need custom rows (icon, second line, status). On `fold-popover`; `role="listbox"` + `aria-activedescendant`, full keyboard (↑/↓, `Home`/`End`, type-ahead, `Enter`). Signal Forms (`FormValueControl<string>`, `[formField]`/`[(value)]`); shares `fold-input`'s box chrome. |
|
|
358
358
|
| `FoldMultiselectComponent` | `fold-multiselect` | Multi-select sibling of `fold-listbox` (same popover + `fold-option` rows). Value is a set (`readonly string[]`); activating a row toggles it and the panel stays open. Separate component — not a `multiple` flag — so the Signal-Forms value type stays honest. `role="listbox"` + `aria-multiselectable`; the trigger summarises the picks. |
|
|
359
359
|
| `FoldOptgroupComponent` | `fold-optgroup` | Labelled group of `<fold-option>`s inside a `fold-listbox` / `fold-multiselect` — the styleable `<optgroup>`. Presentational: `role="group"` + `aria-labelledby` header (no `role="option"`, so keyboard nav skips it); the owner discovers grouped options in document order, so roving crosses groups seamlessly. |
|
package/fesm2022/fold-ng.mjs
CHANGED
|
@@ -3070,6 +3070,31 @@ class FoldInputComponent {
|
|
|
3070
3070
|
/** Placeholder text. */
|
|
3071
3071
|
placeholder = input("", /* @ts-ignore */
|
|
3072
3072
|
...(ngDevMode ? [{ debugName: "placeholder" }] : /* istanbul ignore next */ []));
|
|
3073
|
+
/**
|
|
3074
|
+
* An icon drawn **inside the box, before the text** — a magnifier on a search
|
|
3075
|
+
* field, a currency mark on an amount.
|
|
3076
|
+
*
|
|
3077
|
+
* The input reserves the room itself, so the glyph never sits on the text.
|
|
3078
|
+
* Purely decorative: it is `aria-hidden`, and it never replaces a `label` or
|
|
3079
|
+
* an `ariaLabel` — an icon is not an accessible name.
|
|
3080
|
+
*/
|
|
3081
|
+
leadingIcon = input(undefined, /* @ts-ignore */
|
|
3082
|
+
...(ngDevMode ? [{ debugName: "leadingIcon" }] : /* istanbul ignore next */ []));
|
|
3083
|
+
/**
|
|
3084
|
+
* Show a trailing **clear** button while the field holds text.
|
|
3085
|
+
*
|
|
3086
|
+
* The affordance every search box grows by hand: a conditional `×` that empties
|
|
3087
|
+
* the value and gives the focus back, so typing can resume without a second
|
|
3088
|
+
* click. Off by default — a form field that clears itself invites the accident
|
|
3089
|
+
* it cannot undo.
|
|
3090
|
+
*
|
|
3091
|
+
* A `revealable` password wins the trailing slot: the two never make sense
|
|
3092
|
+
* together, and hiding the reveal would be the worse of the two losses.
|
|
3093
|
+
*/
|
|
3094
|
+
clearable = input(false, { ...(ngDevMode ? { debugName: "clearable" } : /* istanbul ignore next */ {}), transform: booleanAttribute });
|
|
3095
|
+
/** Accessible name of the clear button. Override it to translate. */
|
|
3096
|
+
clearLabel = input("Clear", /* @ts-ignore */
|
|
3097
|
+
...(ngDevMode ? [{ debugName: "clearLabel" }] : /* istanbul ignore next */ []));
|
|
3073
3098
|
/** Render as read-only. Named `readOnly` (not `readonly`) to avoid the
|
|
3074
3099
|
* signal-forms `FormField` reserved `readonly` field-state binding. */
|
|
3075
3100
|
readOnly = input(false, /* @ts-ignore */
|
|
@@ -3094,6 +3119,9 @@ class FoldInputComponent {
|
|
|
3094
3119
|
...(ngDevMode ? [{ debugName: "autocomplete" }] : /* istanbul ignore next */ []));
|
|
3095
3120
|
/** Unique, SSR-safe id for label association (see {@link FoldIdService}). */
|
|
3096
3121
|
inputId = inject(FoldIdService).next("fold-input");
|
|
3122
|
+
/** The native control — the clear button hands the focus back to it. */
|
|
3123
|
+
field = viewChild("field", /* @ts-ignore */
|
|
3124
|
+
...(ngDevMode ? [{ debugName: "field" }] : /* istanbul ignore next */ []));
|
|
3097
3125
|
/** The message to show under the field: the first error, once touched. */
|
|
3098
3126
|
errorMessage = computed(() => {
|
|
3099
3127
|
if (!this.touched()) {
|
|
@@ -3123,9 +3151,25 @@ class FoldInputComponent {
|
|
|
3123
3151
|
/** The reveal control's accessible name, tracking its state. */
|
|
3124
3152
|
revealAria = computed(() => this.revealed() ? this.hideLabel() : this.revealLabel(), /* @ts-ignore */
|
|
3125
3153
|
...(ngDevMode ? [{ debugName: "revealAria" }] : /* istanbul ignore next */ []));
|
|
3154
|
+
/**
|
|
3155
|
+
* Whether to render the clear button: asked for, something to clear, and a
|
|
3156
|
+
* field that can still be edited. A `×` over a read-only value would promise
|
|
3157
|
+
* a gesture the control refuses.
|
|
3158
|
+
*/
|
|
3159
|
+
showClear = computed(() => this.clearable() &&
|
|
3160
|
+
this.value() !== "" &&
|
|
3161
|
+
!this.disabled() &&
|
|
3162
|
+
!this.readOnly() &&
|
|
3163
|
+
!this.showReveal(), /* @ts-ignore */
|
|
3164
|
+
...(ngDevMode ? [{ debugName: "showClear" }] : /* istanbul ignore next */ []));
|
|
3126
3165
|
toggleReveal() {
|
|
3127
3166
|
this.revealed.update((shown) => !shown);
|
|
3128
3167
|
}
|
|
3168
|
+
/** Empties the field and returns the focus, so typing resumes in place. */
|
|
3169
|
+
clear() {
|
|
3170
|
+
this.value.set("");
|
|
3171
|
+
this.field()?.nativeElement.focus();
|
|
3172
|
+
}
|
|
3129
3173
|
/** Handles native input event. `value.set()` also fires the model's
|
|
3130
3174
|
* auto `valueChange` output for standalone `(valueChange)` consumers. */
|
|
3131
3175
|
onInputChange(event) {
|
|
@@ -3136,14 +3180,14 @@ class FoldInputComponent {
|
|
|
3136
3180
|
this.touched.set(true);
|
|
3137
3181
|
}
|
|
3138
3182
|
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.8", ngImport: i0, type: FoldInputComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
3139
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.0.8", type: FoldInputComponent, isStandalone: true, selector: "fold-input", inputs: { value: { classPropertyName: "value", publicName: "value", isSignal: true, isRequired: false, transformFunction: null }, disabled: { classPropertyName: "disabled", publicName: "disabled", isSignal: true, isRequired: false, transformFunction: null }, touched: { classPropertyName: "touched", publicName: "touched", isSignal: true, isRequired: false, transformFunction: null }, errors: { classPropertyName: "errors", publicName: "errors", isSignal: true, isRequired: false, transformFunction: null }, type: { classPropertyName: "type", publicName: "type", isSignal: true, isRequired: false, transformFunction: null }, revealable: { classPropertyName: "revealable", publicName: "revealable", isSignal: true, isRequired: false, transformFunction: null }, revealLabel: { classPropertyName: "revealLabel", publicName: "revealLabel", isSignal: true, isRequired: false, transformFunction: null }, hideLabel: { classPropertyName: "hideLabel", publicName: "hideLabel", isSignal: true, isRequired: false, transformFunction: null }, size: { classPropertyName: "size", publicName: "size", isSignal: true, isRequired: false, transformFunction: null }, align: { classPropertyName: "align", publicName: "align", isSignal: true, isRequired: false, transformFunction: null }, variant: { classPropertyName: "variant", publicName: "variant", isSignal: true, isRequired: false, transformFunction: null }, label: { classPropertyName: "label", publicName: "label", isSignal: true, isRequired: false, transformFunction: null }, required: { classPropertyName: "required", publicName: "required", isSignal: true, isRequired: false, transformFunction: null }, optional: { classPropertyName: "optional", publicName: "optional", isSignal: true, isRequired: false, transformFunction: null }, optionalLabel: { classPropertyName: "optionalLabel", publicName: "optionalLabel", isSignal: true, isRequired: false, transformFunction: null }, info: { classPropertyName: "info", publicName: "info", isSignal: true, isRequired: false, transformFunction: null }, infoLabel: { classPropertyName: "infoLabel", publicName: "infoLabel", isSignal: true, isRequired: false, transformFunction: null }, ariaLabel: { classPropertyName: "ariaLabel", publicName: "ariaLabel", isSignal: true, isRequired: false, transformFunction: null }, hint: { classPropertyName: "hint", publicName: "hint", isSignal: true, isRequired: false, transformFunction: null }, placeholder: { classPropertyName: "placeholder", publicName: "placeholder", isSignal: true, isRequired: false, transformFunction: null }, readOnly: { classPropertyName: "readOnly", publicName: "readOnly", isSignal: true, isRequired: false, transformFunction: null }, autofocus: { classPropertyName: "autofocus", publicName: "autofocus", isSignal: true, isRequired: false, transformFunction: null }, autocomplete: { classPropertyName: "autocomplete", publicName: "autocomplete", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { value: "valueChange", touched: "touchedChange" }, host: { properties: { "class": "size() + \" \" + align() + \" \" + variant()" } }, ngImport: i0, template: "<fold-input-base\n [label]=\"label()\"\n [for]=\"inputId\"\n [required]=\"required()\"\n [optional]=\"optional()\"\n [optionalLabel]=\"optionalLabel()\"\n [info]=\"info()\"\n [infoLabel]=\"infoLabel()\"\n [hint]=\"hint()\"\n [error]=\"errorMessage()\"\n>\n <div class=\"in-field\">\n <input\n [id]=\"inputId\"\n [class.has-reveal]=\"showReveal()\"\n [attr.type]=\"effectiveType()\"\n [attr.placeholder]=\"placeholder()\"\n [attr.readonly]=\"readOnly() || null\"\n [attr.disabled]=\"disabled() || null\"\n [attr.required]=\"required() || null\"\n [attr.aria-invalid]=\"errorMessage() ? true : null\"\n [attr.aria-describedby]=\"describedBy()\"\n [attr.aria-label]=\"ariaLabel()\"\n [attr.autocomplete]=\"autocomplete()\"\n [value]=\"value()\"\n (input)=\"onInputChange($event)\"\n (blur)=\"onBlur()\"\n />\n @if (showReveal()) {\n <button\n type=\"button\"\n class=\"in-reveal\"\n [attr.aria-label]=\"revealAria()\"\n [attr.aria-pressed]=\"revealed()\"\n [disabled]=\"disabled() || readOnly()\"\n (click)=\"toggleReveal()\"\n >\n <fold-icon\n [name]=\"revealed() ? 'eye-off' : 'eye'\"\n size=\"sm\"\n aria-hidden=\"true\"\n />\n </button>\n }\n </div>\n</fold-input-base>\n", styles: ["@charset \"UTF-8\";:host{display:block}input,select,textarea{all:unset;box-sizing:border-box;width:100%;font-family:inherit;color:var(--fold-color-text);background:var(--fold-color-surface-card);border:1px solid var(--fold-color-border-subtle);transition:border-color var(--fold-motion-fast),box-shadow var(--fold-motion-fast)}input::placeholder,select::placeholder,textarea::placeholder{color:var(--fold-color-text-faded)}input:hover:not(:disabled):not(:read-only):not(:focus),select:hover:not(:disabled):not(:read-only):not(:focus),textarea:hover:not(:disabled):not(:read-only):not(:focus){border-color:var(--fold-color-border)}input:focus,select:focus,textarea:focus{border-color:var(--fold-color-primary);box-shadow:0 0 0 2px var(--fold-color-primary-border)}input:disabled,select:disabled,textarea:disabled{opacity:.4;cursor:not-allowed}input:read-only,select:read-only,textarea:read-only{opacity:.6;cursor:default}input[type=number],select[type=number],textarea[type=number]{appearance:textfield;-moz-appearance:textfield}input[type=number]::-webkit-inner-spin-button,input[type=number]::-webkit-outer-spin-button,select[type=number]::-webkit-inner-spin-button,select[type=number]::-webkit-outer-spin-button,textarea[type=number]::-webkit-inner-spin-button,textarea[type=number]::-webkit-outer-spin-button{-webkit-appearance:none;margin:0}:host(.sm) input,:host(.sm) select{height:1.75rem;font-size:var(--fold-text-sm);padding:.25rem .5rem;border-radius:var(--fold-radius-xs)}:host(.sm) textarea{font-size:var(--fold-text-sm);padding:.25rem .5rem;border-radius:var(--fold-radius-xs)}:host(.md) input,:host(.md) select{height:2.25rem;font-size:var(--fold-text-base);padding:.4rem .65rem;border-radius:var(--fold-radius-sm)}:host(.md) textarea{font-size:var(--fold-text-base);padding:.4rem .65rem;border-radius:var(--fold-radius-sm)}:host(.lg) input,:host(.lg) select{height:2.75rem;font-size:var(--fold-text-lg);padding:.5rem .75rem;border-radius:var(--fold-radius-sm)}:host(.lg) textarea{font-size:var(--fold-text-lg);padding:.5rem .75rem;border-radius:var(--fold-radius-sm)}:host(.center) input{text-align:center}:host(.panel) input,:host(.panel) select,:host(.panel) textarea{height:auto;padding:var(--fold-space-sm) var(--fold-space-sm);border-radius:var(--fold-radius-sm);background:var(--fold-color-surface-raised)}:host(.panel) input:focus,:host(.panel) select:focus,:host(.panel) textarea:focus{box-shadow:none}.in-field{position:relative}:host input.has-reveal{padding-inline-end:2.1rem}.in-reveal{all:unset;position:absolute;inset-inline-end:.4rem;top:50%;transform:translateY(-50%);display:grid;place-items:center;padding:.2rem;border-radius:var(--fold-radius-xs);color:var(--fold-color-text-muted);cursor:pointer}.in-reveal:hover:not(:disabled),.in-reveal:focus-visible{color:var(--fold-color-text);background:var(--fold-color-surface-hover)}.in-reveal:focus-visible{outline:2px solid var(--fold-color-primary-border);outline-offset:1px}.in-reveal:disabled{cursor:not-allowed;opacity:.4}@media(forced-colors:active){.in-reveal:focus-visible{outline-color:Highlight}}\n"], dependencies: [{ kind: "component", type: FoldInputBaseComponent, selector: "fold-input-base", inputs: ["label", "for", "required", "optional", "optionalLabel", "hint", "error", "info", "infoLabel"] }, { kind: "component", type: FoldIconComponent, selector: "fold-icon", inputs: ["name", "size", "tone", "title"] }] });
|
|
3183
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.0.8", type: FoldInputComponent, isStandalone: true, selector: "fold-input", inputs: { value: { classPropertyName: "value", publicName: "value", isSignal: true, isRequired: false, transformFunction: null }, disabled: { classPropertyName: "disabled", publicName: "disabled", isSignal: true, isRequired: false, transformFunction: null }, touched: { classPropertyName: "touched", publicName: "touched", isSignal: true, isRequired: false, transformFunction: null }, errors: { classPropertyName: "errors", publicName: "errors", isSignal: true, isRequired: false, transformFunction: null }, type: { classPropertyName: "type", publicName: "type", isSignal: true, isRequired: false, transformFunction: null }, revealable: { classPropertyName: "revealable", publicName: "revealable", isSignal: true, isRequired: false, transformFunction: null }, revealLabel: { classPropertyName: "revealLabel", publicName: "revealLabel", isSignal: true, isRequired: false, transformFunction: null }, hideLabel: { classPropertyName: "hideLabel", publicName: "hideLabel", isSignal: true, isRequired: false, transformFunction: null }, size: { classPropertyName: "size", publicName: "size", isSignal: true, isRequired: false, transformFunction: null }, align: { classPropertyName: "align", publicName: "align", isSignal: true, isRequired: false, transformFunction: null }, variant: { classPropertyName: "variant", publicName: "variant", isSignal: true, isRequired: false, transformFunction: null }, label: { classPropertyName: "label", publicName: "label", isSignal: true, isRequired: false, transformFunction: null }, required: { classPropertyName: "required", publicName: "required", isSignal: true, isRequired: false, transformFunction: null }, optional: { classPropertyName: "optional", publicName: "optional", isSignal: true, isRequired: false, transformFunction: null }, optionalLabel: { classPropertyName: "optionalLabel", publicName: "optionalLabel", isSignal: true, isRequired: false, transformFunction: null }, info: { classPropertyName: "info", publicName: "info", isSignal: true, isRequired: false, transformFunction: null }, infoLabel: { classPropertyName: "infoLabel", publicName: "infoLabel", isSignal: true, isRequired: false, transformFunction: null }, ariaLabel: { classPropertyName: "ariaLabel", publicName: "ariaLabel", isSignal: true, isRequired: false, transformFunction: null }, hint: { classPropertyName: "hint", publicName: "hint", isSignal: true, isRequired: false, transformFunction: null }, placeholder: { classPropertyName: "placeholder", publicName: "placeholder", isSignal: true, isRequired: false, transformFunction: null }, leadingIcon: { classPropertyName: "leadingIcon", publicName: "leadingIcon", isSignal: true, isRequired: false, transformFunction: null }, clearable: { classPropertyName: "clearable", publicName: "clearable", isSignal: true, isRequired: false, transformFunction: null }, clearLabel: { classPropertyName: "clearLabel", publicName: "clearLabel", isSignal: true, isRequired: false, transformFunction: null }, readOnly: { classPropertyName: "readOnly", publicName: "readOnly", isSignal: true, isRequired: false, transformFunction: null }, autofocus: { classPropertyName: "autofocus", publicName: "autofocus", isSignal: true, isRequired: false, transformFunction: null }, autocomplete: { classPropertyName: "autocomplete", publicName: "autocomplete", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { value: "valueChange", touched: "touchedChange" }, host: { properties: { "class": "size() + \" \" + align() + \" \" + variant()" } }, viewQueries: [{ propertyName: "field", first: true, predicate: ["field"], descendants: true, isSignal: true }], ngImport: i0, template: "<fold-input-base\n [label]=\"label()\"\n [for]=\"inputId\"\n [required]=\"required()\"\n [optional]=\"optional()\"\n [optionalLabel]=\"optionalLabel()\"\n [info]=\"info()\"\n [infoLabel]=\"infoLabel()\"\n [hint]=\"hint()\"\n [error]=\"errorMessage()\"\n>\n <div class=\"in-field\">\n @if (leadingIcon(); as glyph) {\n <fold-icon class=\"in-lead\" [name]=\"glyph\" size=\"sm\" aria-hidden=\"true\" />\n }\n <input\n #field\n [id]=\"inputId\"\n [class.has-lead]=\"leadingIcon() !== undefined\"\n [class.has-reveal]=\"showReveal() || showClear()\"\n [attr.type]=\"effectiveType()\"\n [attr.placeholder]=\"placeholder()\"\n [attr.readonly]=\"readOnly() || null\"\n [attr.disabled]=\"disabled() || null\"\n [attr.required]=\"required() || null\"\n [attr.aria-invalid]=\"errorMessage() ? true : null\"\n [attr.aria-describedby]=\"describedBy()\"\n [attr.aria-label]=\"ariaLabel()\"\n [attr.autocomplete]=\"autocomplete()\"\n [value]=\"value()\"\n (input)=\"onInputChange($event)\"\n (blur)=\"onBlur()\"\n />\n @if (showReveal()) {\n <button\n type=\"button\"\n class=\"in-reveal\"\n [attr.aria-label]=\"revealAria()\"\n [attr.aria-pressed]=\"revealed()\"\n [disabled]=\"disabled() || readOnly()\"\n (click)=\"toggleReveal()\"\n >\n <fold-icon\n [name]=\"revealed() ? 'eye-off' : 'eye'\"\n size=\"sm\"\n aria-hidden=\"true\"\n />\n </button>\n } @else if (showClear()) {\n <button\n type=\"button\"\n class=\"in-reveal\"\n [attr.aria-label]=\"clearLabel()\"\n (click)=\"clear()\"\n >\n <fold-icon name=\"close\" size=\"sm\" aria-hidden=\"true\" />\n </button>\n }\n </div>\n</fold-input-base>\n", styles: ["@charset \"UTF-8\";:host{display:block}input,select,textarea{all:unset;box-sizing:border-box;width:100%;font-family:inherit;color:var(--fold-color-text);background:var(--fold-color-surface-card);border:1px solid var(--fold-color-border-subtle);transition:border-color var(--fold-motion-fast),box-shadow var(--fold-motion-fast)}input::placeholder,select::placeholder,textarea::placeholder{color:var(--fold-color-text-faded)}input:hover:not(:disabled):not(:read-only):not(:focus),select:hover:not(:disabled):not(:read-only):not(:focus),textarea:hover:not(:disabled):not(:read-only):not(:focus){border-color:var(--fold-color-border)}input:focus,select:focus,textarea:focus{border-color:var(--fold-color-primary);box-shadow:0 0 0 2px var(--fold-color-primary-border)}input:disabled,select:disabled,textarea:disabled{opacity:.4;cursor:not-allowed}input:read-only,select:read-only,textarea:read-only{opacity:.6;cursor:default}input[type=number],select[type=number],textarea[type=number]{appearance:textfield;-moz-appearance:textfield}input[type=number]::-webkit-inner-spin-button,input[type=number]::-webkit-outer-spin-button,select[type=number]::-webkit-inner-spin-button,select[type=number]::-webkit-outer-spin-button,textarea[type=number]::-webkit-inner-spin-button,textarea[type=number]::-webkit-outer-spin-button{-webkit-appearance:none;margin:0}:host(.sm) input,:host(.sm) select{height:1.75rem;font-size:var(--fold-text-sm);padding:.25rem .5rem;border-radius:var(--fold-radius-xs)}:host(.sm) textarea{font-size:var(--fold-text-sm);padding:.25rem .5rem;border-radius:var(--fold-radius-xs)}:host(.md) input,:host(.md) select{height:2.25rem;font-size:var(--fold-text-base);padding:.4rem .65rem;border-radius:var(--fold-radius-sm)}:host(.md) textarea{font-size:var(--fold-text-base);padding:.4rem .65rem;border-radius:var(--fold-radius-sm)}:host(.lg) input,:host(.lg) select{height:2.75rem;font-size:var(--fold-text-lg);padding:.5rem .75rem;border-radius:var(--fold-radius-sm)}:host(.lg) textarea{font-size:var(--fold-text-lg);padding:.5rem .75rem;border-radius:var(--fold-radius-sm)}:host(.center) input{text-align:center}:host(.panel) input,:host(.panel) select,:host(.panel) textarea{height:auto;padding:var(--fold-space-sm) var(--fold-space-sm);border-radius:var(--fold-radius-sm);background:var(--fold-color-surface-raised)}:host(.panel) input:focus,:host(.panel) select:focus,:host(.panel) textarea:focus{box-shadow:none}.in-field{position:relative}:host input.has-reveal{padding-inline-end:2.1rem}:host input.has-lead{padding-inline-start:2.1rem}.in-lead{position:absolute;inset-inline-start:.6rem;top:50%;transform:translateY(-50%);display:grid;place-items:center;color:var(--fold-color-text-muted);pointer-events:none}.in-reveal{all:unset;position:absolute;inset-inline-end:.4rem;top:50%;transform:translateY(-50%);display:grid;place-items:center;padding:.2rem;border-radius:var(--fold-radius-xs);color:var(--fold-color-text-muted);cursor:pointer}.in-reveal:hover:not(:disabled),.in-reveal:focus-visible{color:var(--fold-color-text);background:var(--fold-color-surface-hover)}.in-reveal:focus-visible{outline:2px solid var(--fold-color-primary-border);outline-offset:1px}.in-reveal:disabled{cursor:not-allowed;opacity:.4}@media(forced-colors:active){.in-reveal:focus-visible{outline-color:Highlight}}\n"], dependencies: [{ kind: "component", type: FoldInputBaseComponent, selector: "fold-input-base", inputs: ["label", "for", "required", "optional", "optionalLabel", "hint", "error", "info", "infoLabel"] }, { kind: "component", type: FoldIconComponent, selector: "fold-icon", inputs: ["name", "size", "tone", "title"] }] });
|
|
3140
3184
|
}
|
|
3141
3185
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.8", ngImport: i0, type: FoldInputComponent, decorators: [{
|
|
3142
3186
|
type: Component,
|
|
3143
3187
|
args: [{ selector: "fold-input", standalone: true, imports: [FoldInputBaseComponent, FoldIconComponent], host: {
|
|
3144
3188
|
"[class]": 'size() + " " + align() + " " + variant()',
|
|
3145
|
-
}, template: "<fold-input-base\n [label]=\"label()\"\n [for]=\"inputId\"\n [required]=\"required()\"\n [optional]=\"optional()\"\n [optionalLabel]=\"optionalLabel()\"\n [info]=\"info()\"\n [infoLabel]=\"infoLabel()\"\n [hint]=\"hint()\"\n [error]=\"errorMessage()\"\n>\n <div class=\"in-field\">\n <input\n [id]=\"inputId\"\n [class.has-reveal]=\"showReveal()\"\n [attr.type]=\"effectiveType()\"\n [attr.placeholder]=\"placeholder()\"\n [attr.readonly]=\"readOnly() || null\"\n [attr.disabled]=\"disabled() || null\"\n [attr.required]=\"required() || null\"\n [attr.aria-invalid]=\"errorMessage() ? true : null\"\n [attr.aria-describedby]=\"describedBy()\"\n [attr.aria-label]=\"ariaLabel()\"\n [attr.autocomplete]=\"autocomplete()\"\n [value]=\"value()\"\n (input)=\"onInputChange($event)\"\n (blur)=\"onBlur()\"\n />\n @if (showReveal()) {\n <button\n type=\"button\"\n class=\"in-reveal\"\n [attr.aria-label]=\"revealAria()\"\n [attr.aria-pressed]=\"revealed()\"\n [disabled]=\"disabled() || readOnly()\"\n (click)=\"toggleReveal()\"\n >\n <fold-icon\n [name]=\"revealed() ? 'eye-off' : 'eye'\"\n size=\"sm\"\n aria-hidden=\"true\"\n />\n </button>\n }\n </div>\n</fold-input-base>\n", styles: ["@charset \"UTF-8\";:host{display:block}input,select,textarea{all:unset;box-sizing:border-box;width:100%;font-family:inherit;color:var(--fold-color-text);background:var(--fold-color-surface-card);border:1px solid var(--fold-color-border-subtle);transition:border-color var(--fold-motion-fast),box-shadow var(--fold-motion-fast)}input::placeholder,select::placeholder,textarea::placeholder{color:var(--fold-color-text-faded)}input:hover:not(:disabled):not(:read-only):not(:focus),select:hover:not(:disabled):not(:read-only):not(:focus),textarea:hover:not(:disabled):not(:read-only):not(:focus){border-color:var(--fold-color-border)}input:focus,select:focus,textarea:focus{border-color:var(--fold-color-primary);box-shadow:0 0 0 2px var(--fold-color-primary-border)}input:disabled,select:disabled,textarea:disabled{opacity:.4;cursor:not-allowed}input:read-only,select:read-only,textarea:read-only{opacity:.6;cursor:default}input[type=number],select[type=number],textarea[type=number]{appearance:textfield;-moz-appearance:textfield}input[type=number]::-webkit-inner-spin-button,input[type=number]::-webkit-outer-spin-button,select[type=number]::-webkit-inner-spin-button,select[type=number]::-webkit-outer-spin-button,textarea[type=number]::-webkit-inner-spin-button,textarea[type=number]::-webkit-outer-spin-button{-webkit-appearance:none;margin:0}:host(.sm) input,:host(.sm) select{height:1.75rem;font-size:var(--fold-text-sm);padding:.25rem .5rem;border-radius:var(--fold-radius-xs)}:host(.sm) textarea{font-size:var(--fold-text-sm);padding:.25rem .5rem;border-radius:var(--fold-radius-xs)}:host(.md) input,:host(.md) select{height:2.25rem;font-size:var(--fold-text-base);padding:.4rem .65rem;border-radius:var(--fold-radius-sm)}:host(.md) textarea{font-size:var(--fold-text-base);padding:.4rem .65rem;border-radius:var(--fold-radius-sm)}:host(.lg) input,:host(.lg) select{height:2.75rem;font-size:var(--fold-text-lg);padding:.5rem .75rem;border-radius:var(--fold-radius-sm)}:host(.lg) textarea{font-size:var(--fold-text-lg);padding:.5rem .75rem;border-radius:var(--fold-radius-sm)}:host(.center) input{text-align:center}:host(.panel) input,:host(.panel) select,:host(.panel) textarea{height:auto;padding:var(--fold-space-sm) var(--fold-space-sm);border-radius:var(--fold-radius-sm);background:var(--fold-color-surface-raised)}:host(.panel) input:focus,:host(.panel) select:focus,:host(.panel) textarea:focus{box-shadow:none}.in-field{position:relative}:host input.has-reveal{padding-inline-end:2.1rem}.in-reveal{all:unset;position:absolute;inset-inline-end:.4rem;top:50%;transform:translateY(-50%);display:grid;place-items:center;padding:.2rem;border-radius:var(--fold-radius-xs);color:var(--fold-color-text-muted);cursor:pointer}.in-reveal:hover:not(:disabled),.in-reveal:focus-visible{color:var(--fold-color-text);background:var(--fold-color-surface-hover)}.in-reveal:focus-visible{outline:2px solid var(--fold-color-primary-border);outline-offset:1px}.in-reveal:disabled{cursor:not-allowed;opacity:.4}@media(forced-colors:active){.in-reveal:focus-visible{outline-color:Highlight}}\n"] }]
|
|
3146
|
-
}], propDecorators: { value: [{ type: i0.Input, args: [{ isSignal: true, alias: "value", required: false }] }, { type: i0.Output, args: ["valueChange"] }], disabled: [{ type: i0.Input, args: [{ isSignal: true, alias: "disabled", required: false }] }], touched: [{ type: i0.Input, args: [{ isSignal: true, alias: "touched", required: false }] }, { type: i0.Output, args: ["touchedChange"] }], errors: [{ type: i0.Input, args: [{ isSignal: true, alias: "errors", required: false }] }], type: [{ type: i0.Input, args: [{ isSignal: true, alias: "type", required: false }] }], revealable: [{ type: i0.Input, args: [{ isSignal: true, alias: "revealable", required: false }] }], revealLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "revealLabel", required: false }] }], hideLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "hideLabel", required: false }] }], size: [{ type: i0.Input, args: [{ isSignal: true, alias: "size", required: false }] }], align: [{ type: i0.Input, args: [{ isSignal: true, alias: "align", required: false }] }], variant: [{ type: i0.Input, args: [{ isSignal: true, alias: "variant", required: false }] }], label: [{ type: i0.Input, args: [{ isSignal: true, alias: "label", required: false }] }], required: [{ type: i0.Input, args: [{ isSignal: true, alias: "required", required: false }] }], optional: [{ type: i0.Input, args: [{ isSignal: true, alias: "optional", required: false }] }], optionalLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "optionalLabel", required: false }] }], info: [{ type: i0.Input, args: [{ isSignal: true, alias: "info", required: false }] }], infoLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "infoLabel", required: false }] }], ariaLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "ariaLabel", required: false }] }], hint: [{ type: i0.Input, args: [{ isSignal: true, alias: "hint", required: false }] }], placeholder: [{ type: i0.Input, args: [{ isSignal: true, alias: "placeholder", required: false }] }], readOnly: [{ type: i0.Input, args: [{ isSignal: true, alias: "readOnly", required: false }] }], autofocus: [{ type: i0.Input, args: [{ isSignal: true, alias: "autofocus", required: false }] }], autocomplete: [{ type: i0.Input, args: [{ isSignal: true, alias: "autocomplete", required: false }] }] } });
|
|
3189
|
+
}, template: "<fold-input-base\n [label]=\"label()\"\n [for]=\"inputId\"\n [required]=\"required()\"\n [optional]=\"optional()\"\n [optionalLabel]=\"optionalLabel()\"\n [info]=\"info()\"\n [infoLabel]=\"infoLabel()\"\n [hint]=\"hint()\"\n [error]=\"errorMessage()\"\n>\n <div class=\"in-field\">\n @if (leadingIcon(); as glyph) {\n <fold-icon class=\"in-lead\" [name]=\"glyph\" size=\"sm\" aria-hidden=\"true\" />\n }\n <input\n #field\n [id]=\"inputId\"\n [class.has-lead]=\"leadingIcon() !== undefined\"\n [class.has-reveal]=\"showReveal() || showClear()\"\n [attr.type]=\"effectiveType()\"\n [attr.placeholder]=\"placeholder()\"\n [attr.readonly]=\"readOnly() || null\"\n [attr.disabled]=\"disabled() || null\"\n [attr.required]=\"required() || null\"\n [attr.aria-invalid]=\"errorMessage() ? true : null\"\n [attr.aria-describedby]=\"describedBy()\"\n [attr.aria-label]=\"ariaLabel()\"\n [attr.autocomplete]=\"autocomplete()\"\n [value]=\"value()\"\n (input)=\"onInputChange($event)\"\n (blur)=\"onBlur()\"\n />\n @if (showReveal()) {\n <button\n type=\"button\"\n class=\"in-reveal\"\n [attr.aria-label]=\"revealAria()\"\n [attr.aria-pressed]=\"revealed()\"\n [disabled]=\"disabled() || readOnly()\"\n (click)=\"toggleReveal()\"\n >\n <fold-icon\n [name]=\"revealed() ? 'eye-off' : 'eye'\"\n size=\"sm\"\n aria-hidden=\"true\"\n />\n </button>\n } @else if (showClear()) {\n <button\n type=\"button\"\n class=\"in-reveal\"\n [attr.aria-label]=\"clearLabel()\"\n (click)=\"clear()\"\n >\n <fold-icon name=\"close\" size=\"sm\" aria-hidden=\"true\" />\n </button>\n }\n </div>\n</fold-input-base>\n", styles: ["@charset \"UTF-8\";:host{display:block}input,select,textarea{all:unset;box-sizing:border-box;width:100%;font-family:inherit;color:var(--fold-color-text);background:var(--fold-color-surface-card);border:1px solid var(--fold-color-border-subtle);transition:border-color var(--fold-motion-fast),box-shadow var(--fold-motion-fast)}input::placeholder,select::placeholder,textarea::placeholder{color:var(--fold-color-text-faded)}input:hover:not(:disabled):not(:read-only):not(:focus),select:hover:not(:disabled):not(:read-only):not(:focus),textarea:hover:not(:disabled):not(:read-only):not(:focus){border-color:var(--fold-color-border)}input:focus,select:focus,textarea:focus{border-color:var(--fold-color-primary);box-shadow:0 0 0 2px var(--fold-color-primary-border)}input:disabled,select:disabled,textarea:disabled{opacity:.4;cursor:not-allowed}input:read-only,select:read-only,textarea:read-only{opacity:.6;cursor:default}input[type=number],select[type=number],textarea[type=number]{appearance:textfield;-moz-appearance:textfield}input[type=number]::-webkit-inner-spin-button,input[type=number]::-webkit-outer-spin-button,select[type=number]::-webkit-inner-spin-button,select[type=number]::-webkit-outer-spin-button,textarea[type=number]::-webkit-inner-spin-button,textarea[type=number]::-webkit-outer-spin-button{-webkit-appearance:none;margin:0}:host(.sm) input,:host(.sm) select{height:1.75rem;font-size:var(--fold-text-sm);padding:.25rem .5rem;border-radius:var(--fold-radius-xs)}:host(.sm) textarea{font-size:var(--fold-text-sm);padding:.25rem .5rem;border-radius:var(--fold-radius-xs)}:host(.md) input,:host(.md) select{height:2.25rem;font-size:var(--fold-text-base);padding:.4rem .65rem;border-radius:var(--fold-radius-sm)}:host(.md) textarea{font-size:var(--fold-text-base);padding:.4rem .65rem;border-radius:var(--fold-radius-sm)}:host(.lg) input,:host(.lg) select{height:2.75rem;font-size:var(--fold-text-lg);padding:.5rem .75rem;border-radius:var(--fold-radius-sm)}:host(.lg) textarea{font-size:var(--fold-text-lg);padding:.5rem .75rem;border-radius:var(--fold-radius-sm)}:host(.center) input{text-align:center}:host(.panel) input,:host(.panel) select,:host(.panel) textarea{height:auto;padding:var(--fold-space-sm) var(--fold-space-sm);border-radius:var(--fold-radius-sm);background:var(--fold-color-surface-raised)}:host(.panel) input:focus,:host(.panel) select:focus,:host(.panel) textarea:focus{box-shadow:none}.in-field{position:relative}:host input.has-reveal{padding-inline-end:2.1rem}:host input.has-lead{padding-inline-start:2.1rem}.in-lead{position:absolute;inset-inline-start:.6rem;top:50%;transform:translateY(-50%);display:grid;place-items:center;color:var(--fold-color-text-muted);pointer-events:none}.in-reveal{all:unset;position:absolute;inset-inline-end:.4rem;top:50%;transform:translateY(-50%);display:grid;place-items:center;padding:.2rem;border-radius:var(--fold-radius-xs);color:var(--fold-color-text-muted);cursor:pointer}.in-reveal:hover:not(:disabled),.in-reveal:focus-visible{color:var(--fold-color-text);background:var(--fold-color-surface-hover)}.in-reveal:focus-visible{outline:2px solid var(--fold-color-primary-border);outline-offset:1px}.in-reveal:disabled{cursor:not-allowed;opacity:.4}@media(forced-colors:active){.in-reveal:focus-visible{outline-color:Highlight}}\n"] }]
|
|
3190
|
+
}], propDecorators: { value: [{ type: i0.Input, args: [{ isSignal: true, alias: "value", required: false }] }, { type: i0.Output, args: ["valueChange"] }], disabled: [{ type: i0.Input, args: [{ isSignal: true, alias: "disabled", required: false }] }], touched: [{ type: i0.Input, args: [{ isSignal: true, alias: "touched", required: false }] }, { type: i0.Output, args: ["touchedChange"] }], errors: [{ type: i0.Input, args: [{ isSignal: true, alias: "errors", required: false }] }], type: [{ type: i0.Input, args: [{ isSignal: true, alias: "type", required: false }] }], revealable: [{ type: i0.Input, args: [{ isSignal: true, alias: "revealable", required: false }] }], revealLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "revealLabel", required: false }] }], hideLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "hideLabel", required: false }] }], size: [{ type: i0.Input, args: [{ isSignal: true, alias: "size", required: false }] }], align: [{ type: i0.Input, args: [{ isSignal: true, alias: "align", required: false }] }], variant: [{ type: i0.Input, args: [{ isSignal: true, alias: "variant", required: false }] }], label: [{ type: i0.Input, args: [{ isSignal: true, alias: "label", required: false }] }], required: [{ type: i0.Input, args: [{ isSignal: true, alias: "required", required: false }] }], optional: [{ type: i0.Input, args: [{ isSignal: true, alias: "optional", required: false }] }], optionalLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "optionalLabel", required: false }] }], info: [{ type: i0.Input, args: [{ isSignal: true, alias: "info", required: false }] }], infoLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "infoLabel", required: false }] }], ariaLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "ariaLabel", required: false }] }], hint: [{ type: i0.Input, args: [{ isSignal: true, alias: "hint", required: false }] }], placeholder: [{ type: i0.Input, args: [{ isSignal: true, alias: "placeholder", required: false }] }], leadingIcon: [{ type: i0.Input, args: [{ isSignal: true, alias: "leadingIcon", required: false }] }], clearable: [{ type: i0.Input, args: [{ isSignal: true, alias: "clearable", required: false }] }], clearLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "clearLabel", required: false }] }], readOnly: [{ type: i0.Input, args: [{ isSignal: true, alias: "readOnly", required: false }] }], autofocus: [{ type: i0.Input, args: [{ isSignal: true, alias: "autofocus", required: false }] }], autocomplete: [{ type: i0.Input, args: [{ isSignal: true, alias: "autocomplete", required: false }] }], field: [{ type: i0.ViewChild, args: ["field", { isSignal: true }] }] } });
|
|
3147
3191
|
|
|
3148
3192
|
/** The English defaults — the base every override merges onto. */
|
|
3149
3193
|
const FOLD_INLINE_CONFIRM_DEFAULT_LABELS = {
|
|
@@ -3386,7 +3430,7 @@ class FoldInlineConfirmComponent {
|
|
|
3386
3430
|
this.cancelled.emit();
|
|
3387
3431
|
}
|
|
3388
3432
|
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.8", ngImport: i0, type: FoldInlineConfirmComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
3389
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.0.8", type: FoldInlineConfirmComponent, isStandalone: true, selector: "fold-inline-confirm", inputs: { intent: { classPropertyName: "intent", publicName: "intent", isSignal: true, isRequired: false, transformFunction: null }, message: { classPropertyName: "message", publicName: "message", isSignal: true, isRequired: false, transformFunction: null }, match: { classPropertyName: "match", publicName: "match", isSignal: true, isRequired: false, transformFunction: null }, password: { classPropertyName: "password", publicName: "password", isSignal: true, isRequired: false, transformFunction: null }, placeholder: { classPropertyName: "placeholder", publicName: "placeholder", isSignal: true, isRequired: false, transformFunction: null }, loading: { classPropertyName: "loading", publicName: "loading", isSignal: true, isRequired: false, transformFunction: null }, size: { classPropertyName: "size", publicName: "size", isSignal: true, isRequired: false, transformFunction: null }, confirmIcon: { classPropertyName: "confirmIcon", publicName: "confirmIcon", isSignal: true, isRequired: false, transformFunction: null }, cancelIcon: { classPropertyName: "cancelIcon", publicName: "cancelIcon", isSignal: true, isRequired: false, transformFunction: null }, keepOpenOnConfirm: { classPropertyName: "keepOpenOnConfirm", publicName: "keepOpenOnConfirm", isSignal: true, isRequired: false, transformFunction: null }, labels: { classPropertyName: "labels", publicName: "labels", isSignal: true, isRequired: false, transformFunction: null }, open: { classPropertyName: "open", publicName: "open", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { confirmed: "confirmed", cancelled: "cancelled", open: "openChange" }, host: { properties: { "class.is-open": "open()" } }, viewQueries: [{ propertyName: "triggerEl", first: true, predicate: ["triggerWrap"], descendants: true, isSignal: true }, { propertyName: "groupEl", first: true, predicate: ["groupEl"], descendants: true, isSignal: true }], ngImport: i0, template: "@if (!open()) {\n <!-- Idle: the host's projected trigger. A click anywhere in it starts the\n flow; the trigger itself stays a real focusable control (button / anchor),\n so keyboard activation is native (Enter/Space \u2192 click) \u2014 no extra\n role/tabindex, and no keydown handler that would double-fire. -->\n <span #triggerWrap class=\"fic-trigger\" (click)=\"activate()\">\n <ng-content />\n </span>\n} @else {\n <div\n #groupEl\n class=\"fic-confirm\"\n role=\"group\"\n [attr.aria-label]=\"l().group\"\n (keydown.escape)=\"cancel(); $event.stopPropagation()\"\n >\n @if (message(); as text) {\n <p class=\"fic-message\" [id]=\"msgId\">{{ text }}</p>\n }\n\n @if (needsInput()) {\n <fold-input\n class=\"fic-field\"\n [label]=\"prompt()\"\n [type]=\"fieldType()\"\n [size]=\"size() === 'lg' ? 'lg' : 'sm'\"\n [placeholder]=\"placeholder() ?? ''\"\n [autocomplete]=\"password() ? 'current-password' : 'off'\"\n [(value)]=\"typed\"\n (keydown.enter)=\"confirm()\"\n />\n }\n\n <div class=\"fic-actions\">\n <button\n foldButton\n emphasis=\"solid\"\n [intent]=\"intent()\"\n [size]=\"size()\"\n [icon]=\"confirmIcon()\"\n [disabled]=\"!canConfirm()\"\n [attr.aria-describedby]=\"message() ? msgId : null\"\n (click)=\"confirm()\"\n >\n {{ loading() ? l().busy : l().confirm }}\n </button>\n\n @if (cancelIcon(); as icon) {\n <fold-button-icon\n [icon]=\"icon\"\n tone=\"ghost\"\n [size]=\"size()\"\n [disabled]=\"loading()\"\n [tooltip]=\"l().cancelAria\"\n (clicked)=\"cancel()\"\n />\n } @else {\n <button\n foldButton\n emphasis=\"soft\"\n intent=\"neutral\"\n [size]=\"size()\"\n [disabled]=\"loading()\"\n (click)=\"cancel()\"\n >\n {{ l().cancel }}\n </button>\n }\n </div>\n </div>\n}\n", styles: [":host{display:inline-flex;align-items:center;min-width:0}.fic-trigger{display:contents}.fic-confirm{display:inline-flex;flex-direction:column;gap:var(--fold-space-sm);min-width:0;animation:fic-in var(--fold-motion-fast)}.fic-message{margin:0;font-size:var(--fold-text-xs);line-height:var(--fold-leading-normal);color:var(--fold-color-text-secondary)}.fic-field{display:block;width:15rem;max-width:100%}.fic-actions{display:inline-flex;align-items:center;gap:var(--fold-space-xs)}@keyframes fic-in{0%{opacity:0;transform:translateY(-2px)}to{opacity:1;transform:none}}@media(prefers-reduced-motion:reduce){.fic-confirm{animation:none}}\n"], dependencies: [{ kind: "component", type: FoldButtonComponent, selector: "button[foldButton], a[foldButton]", inputs: ["emphasis", "intent", "size", "shape", "block", "icon", "iconTrailing", "type", "disabled", "loading"] }, { kind: "component", type: FoldButtonIconComponent, selector: "fold-button-icon", inputs: ["icon", "shape", "size", "tone", "disabled", "loading", "tooltip", "type"], outputs: ["clicked"] }, { kind: "component", type: FoldInputComponent, selector: "fold-input", inputs: ["value", "disabled", "touched", "errors", "type", "revealable", "revealLabel", "hideLabel", "size", "align", "variant", "label", "required", "optional", "optionalLabel", "info", "infoLabel", "ariaLabel", "hint", "placeholder", "readOnly", "autofocus", "autocomplete"], outputs: ["valueChange", "touchedChange"] }] });
|
|
3433
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.0.8", type: FoldInlineConfirmComponent, isStandalone: true, selector: "fold-inline-confirm", inputs: { intent: { classPropertyName: "intent", publicName: "intent", isSignal: true, isRequired: false, transformFunction: null }, message: { classPropertyName: "message", publicName: "message", isSignal: true, isRequired: false, transformFunction: null }, match: { classPropertyName: "match", publicName: "match", isSignal: true, isRequired: false, transformFunction: null }, password: { classPropertyName: "password", publicName: "password", isSignal: true, isRequired: false, transformFunction: null }, placeholder: { classPropertyName: "placeholder", publicName: "placeholder", isSignal: true, isRequired: false, transformFunction: null }, loading: { classPropertyName: "loading", publicName: "loading", isSignal: true, isRequired: false, transformFunction: null }, size: { classPropertyName: "size", publicName: "size", isSignal: true, isRequired: false, transformFunction: null }, confirmIcon: { classPropertyName: "confirmIcon", publicName: "confirmIcon", isSignal: true, isRequired: false, transformFunction: null }, cancelIcon: { classPropertyName: "cancelIcon", publicName: "cancelIcon", isSignal: true, isRequired: false, transformFunction: null }, keepOpenOnConfirm: { classPropertyName: "keepOpenOnConfirm", publicName: "keepOpenOnConfirm", isSignal: true, isRequired: false, transformFunction: null }, labels: { classPropertyName: "labels", publicName: "labels", isSignal: true, isRequired: false, transformFunction: null }, open: { classPropertyName: "open", publicName: "open", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { confirmed: "confirmed", cancelled: "cancelled", open: "openChange" }, host: { properties: { "class.is-open": "open()" } }, viewQueries: [{ propertyName: "triggerEl", first: true, predicate: ["triggerWrap"], descendants: true, isSignal: true }, { propertyName: "groupEl", first: true, predicate: ["groupEl"], descendants: true, isSignal: true }], ngImport: i0, template: "@if (!open()) {\n <!-- Idle: the host's projected trigger. A click anywhere in it starts the\n flow; the trigger itself stays a real focusable control (button / anchor),\n so keyboard activation is native (Enter/Space \u2192 click) \u2014 no extra\n role/tabindex, and no keydown handler that would double-fire. -->\n <span #triggerWrap class=\"fic-trigger\" (click)=\"activate()\">\n <ng-content />\n </span>\n} @else {\n <div\n #groupEl\n class=\"fic-confirm\"\n role=\"group\"\n [attr.aria-label]=\"l().group\"\n (keydown.escape)=\"cancel(); $event.stopPropagation()\"\n >\n @if (message(); as text) {\n <p class=\"fic-message\" [id]=\"msgId\">{{ text }}</p>\n }\n\n @if (needsInput()) {\n <fold-input\n class=\"fic-field\"\n [label]=\"prompt()\"\n [type]=\"fieldType()\"\n [size]=\"size() === 'lg' ? 'lg' : 'sm'\"\n [placeholder]=\"placeholder() ?? ''\"\n [autocomplete]=\"password() ? 'current-password' : 'off'\"\n [(value)]=\"typed\"\n (keydown.enter)=\"confirm()\"\n />\n }\n\n <div class=\"fic-actions\">\n <button\n foldButton\n emphasis=\"solid\"\n [intent]=\"intent()\"\n [size]=\"size()\"\n [icon]=\"confirmIcon()\"\n [disabled]=\"!canConfirm()\"\n [attr.aria-describedby]=\"message() ? msgId : null\"\n (click)=\"confirm()\"\n >\n {{ loading() ? l().busy : l().confirm }}\n </button>\n\n @if (cancelIcon(); as icon) {\n <fold-button-icon\n [icon]=\"icon\"\n tone=\"ghost\"\n [size]=\"size()\"\n [disabled]=\"loading()\"\n [tooltip]=\"l().cancelAria\"\n (clicked)=\"cancel()\"\n />\n } @else {\n <button\n foldButton\n emphasis=\"soft\"\n intent=\"neutral\"\n [size]=\"size()\"\n [disabled]=\"loading()\"\n (click)=\"cancel()\"\n >\n {{ l().cancel }}\n </button>\n }\n </div>\n </div>\n}\n", styles: [":host{display:inline-flex;align-items:center;min-width:0}.fic-trigger{display:contents}.fic-confirm{display:inline-flex;flex-direction:column;gap:var(--fold-space-sm);min-width:0;animation:fic-in var(--fold-motion-fast)}.fic-message{margin:0;font-size:var(--fold-text-xs);line-height:var(--fold-leading-normal);color:var(--fold-color-text-secondary)}.fic-field{display:block;width:15rem;max-width:100%}.fic-actions{display:inline-flex;align-items:center;gap:var(--fold-space-xs)}@keyframes fic-in{0%{opacity:0;transform:translateY(-2px)}to{opacity:1;transform:none}}@media(prefers-reduced-motion:reduce){.fic-confirm{animation:none}}\n"], dependencies: [{ kind: "component", type: FoldButtonComponent, selector: "button[foldButton], a[foldButton]", inputs: ["emphasis", "intent", "size", "shape", "block", "icon", "iconTrailing", "type", "disabled", "loading"] }, { kind: "component", type: FoldButtonIconComponent, selector: "fold-button-icon", inputs: ["icon", "shape", "size", "tone", "disabled", "loading", "tooltip", "type"], outputs: ["clicked"] }, { kind: "component", type: FoldInputComponent, selector: "fold-input", inputs: ["value", "disabled", "touched", "errors", "type", "revealable", "revealLabel", "hideLabel", "size", "align", "variant", "label", "required", "optional", "optionalLabel", "info", "infoLabel", "ariaLabel", "hint", "placeholder", "leadingIcon", "clearable", "clearLabel", "readOnly", "autofocus", "autocomplete"], outputs: ["valueChange", "touchedChange"] }] });
|
|
3390
3434
|
}
|
|
3391
3435
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.8", ngImport: i0, type: FoldInlineConfirmComponent, decorators: [{
|
|
3392
3436
|
type: Component,
|
|
@@ -9293,23 +9337,54 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.8", ngImpor
|
|
|
9293
9337
|
}], propDecorators: { value: [{ type: i0.Input, args: [{ isSignal: true, alias: "value", required: false }] }, { type: i0.Output, args: ["valueChange"] }], disabled: [{ type: i0.Input, args: [{ isSignal: true, alias: "disabled", required: false }] }], touched: [{ type: i0.Input, args: [{ isSignal: true, alias: "touched", required: false }] }, { type: i0.Output, args: ["touchedChange"] }], errors: [{ type: i0.Input, args: [{ isSignal: true, alias: "errors", required: false }] }], min: [{ type: i0.Input, args: [{ isSignal: true, alias: "min", required: false }] }], max: [{ type: i0.Input, args: [{ isSignal: true, alias: "max", required: false }] }], step: [{ type: i0.Input, args: [{ isSignal: true, alias: "step", required: false }] }], size: [{ type: i0.Input, args: [{ isSignal: true, alias: "size", required: false }] }], variant: [{ type: i0.Input, args: [{ isSignal: true, alias: "variant", required: false }] }], label: [{ type: i0.Input, args: [{ isSignal: true, alias: "label", required: false }] }], required: [{ type: i0.Input, args: [{ isSignal: true, alias: "required", required: false }] }], optional: [{ type: i0.Input, args: [{ isSignal: true, alias: "optional", required: false }] }], optionalLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "optionalLabel", required: false }] }], info: [{ type: i0.Input, args: [{ isSignal: true, alias: "info", required: false }] }], infoLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "infoLabel", required: false }] }], hint: [{ type: i0.Input, args: [{ isSignal: true, alias: "hint", required: false }] }], readOnly: [{ type: i0.Input, args: [{ isSignal: true, alias: "readOnly", required: false }] }] } });
|
|
9294
9338
|
|
|
9295
9339
|
/**
|
|
9296
|
-
* `<fold-search>` —
|
|
9297
|
-
*
|
|
9298
|
-
* triggers one query instead of one per keystroke
|
|
9299
|
-
* emitted term is trimmed and de-duplicated
|
|
9300
|
-
*
|
|
9301
|
-
*
|
|
9340
|
+
* `<fold-search>` — a search box: the magnifier, the clear `×`, an optional
|
|
9341
|
+
* **announced result count**, and a **debounced emit**. `searchChange` fires only once typing pauses for
|
|
9342
|
+
* `delayMs`, so a fast typer triggers one query instead of one per keystroke;
|
|
9343
|
+
* the emitted term is trimmed and de-duplicated.
|
|
9344
|
+
*
|
|
9345
|
+
* `value` is a `model()`, and that is what makes it a control rather than a
|
|
9346
|
+
* one-way sensor. Bind it and the box becomes **steerable from outside** —
|
|
9347
|
+
* picking a filter elsewhere can empty the field, which a write-only search
|
|
9348
|
+
* cannot do: it would keep showing a term the results no longer honour.
|
|
9349
|
+
*
|
|
9350
|
+
* Two ways to use it, and they answer different questions:
|
|
9351
|
+
*
|
|
9352
|
+
* - `[(value)]` — the term as **state**, updated on every keystroke. Filtering
|
|
9353
|
+
* an array already in memory wants this; a debounce there only adds lag.
|
|
9354
|
+
* - `(searchChange)` — the term as an **event**, once it settles. A request to
|
|
9355
|
+
* a server wants this.
|
|
9356
|
+
*
|
|
9357
|
+
* They compose: bind both when a screen filters locally *and* refetches.
|
|
9358
|
+
* Writing `value` from outside never emits `searchChange` — whoever wrote it
|
|
9359
|
+
* already knows.
|
|
9302
9360
|
*
|
|
9303
9361
|
* @selector `fold-search`
|
|
9304
9362
|
*
|
|
9305
9363
|
* @example
|
|
9306
9364
|
* ```html
|
|
9365
|
+
* <!-- Local filtering, instant, with the count beside the box -->
|
|
9366
|
+
* <fold-search
|
|
9367
|
+
* placeholder="Filter…"
|
|
9368
|
+
* [(value)]="term"
|
|
9369
|
+
* [resultCount]="rows().length"
|
|
9370
|
+
* resultLabel="rows" />
|
|
9371
|
+
*
|
|
9372
|
+
* <!-- Remote query, once typing settles -->
|
|
9307
9373
|
* <fold-search
|
|
9308
9374
|
* placeholder="Search name, email, job…"
|
|
9309
9375
|
* (searchChange)="store.setSearch($event)" />
|
|
9310
9376
|
* ```
|
|
9311
9377
|
*/
|
|
9312
9378
|
class FoldSearchComponent {
|
|
9379
|
+
/**
|
|
9380
|
+
* The term in the box — the SOURCE of truth, not a copy of it.
|
|
9381
|
+
*
|
|
9382
|
+
* Two-way, so a screen can clear or preset it: choosing a category that
|
|
9383
|
+
* supersedes the search empties the field in the same gesture, instead of
|
|
9384
|
+
* leaving a stale term above results that ignore it.
|
|
9385
|
+
*/
|
|
9386
|
+
value = model("", /* @ts-ignore */
|
|
9387
|
+
...(ngDevMode ? [{ debugName: "value" }] : /* istanbul ignore next */ []));
|
|
9313
9388
|
placeholder = input("", /* @ts-ignore */
|
|
9314
9389
|
...(ngDevMode ? [{ debugName: "placeholder" }] : /* istanbul ignore next */ []));
|
|
9315
9390
|
size = input("md", /* @ts-ignore */
|
|
@@ -9318,18 +9393,74 @@ class FoldSearchComponent {
|
|
|
9318
9393
|
* forms; `default` elsewhere). */
|
|
9319
9394
|
variant = input("default", /* @ts-ignore */
|
|
9320
9395
|
...(ngDevMode ? [{ debugName: "variant" }] : /* istanbul ignore next */ []));
|
|
9396
|
+
/**
|
|
9397
|
+
* Accessible name, when the design leaves no room for a visible label — the
|
|
9398
|
+
* magnifier is decorative and names nothing.
|
|
9399
|
+
*/
|
|
9400
|
+
ariaLabel = input(undefined, /* @ts-ignore */
|
|
9401
|
+
...(ngDevMode ? [{ debugName: "ariaLabel" }] : /* istanbul ignore next */ []));
|
|
9402
|
+
/** The `×` that empties the box. On by default: it is what a search box is. */
|
|
9403
|
+
clearable = input(true, { ...(ngDevMode ? { debugName: "clearable" } : /* istanbul ignore next */ {}), transform: booleanAttribute });
|
|
9404
|
+
/** Accessible name of the clear button. Override it to translate. */
|
|
9405
|
+
clearLabel = input("Clear search", /* @ts-ignore */
|
|
9406
|
+
...(ngDevMode ? [{ debugName: "clearLabel" }] : /* istanbul ignore next */ []));
|
|
9407
|
+
/**
|
|
9408
|
+
* How many results the term found — `null` (the default) shows nothing.
|
|
9409
|
+
*
|
|
9410
|
+
* It belongs here rather than beside the box because it is the ANSWER to what
|
|
9411
|
+
* the box asked, and because every screen that wrote it by hand forgot the
|
|
9412
|
+
* same thing: a count that changes under a search has to be **announced**.
|
|
9413
|
+
* It carries `role="status"` and `aria-live="polite"`, so a user who cannot
|
|
9414
|
+
* see the grid still learns that four hundred rows became three.
|
|
9415
|
+
*/
|
|
9416
|
+
resultCount = input(null, /* @ts-ignore */
|
|
9417
|
+
...(ngDevMode ? [{ debugName: "resultCount" }] : /* istanbul ignore next */ []));
|
|
9418
|
+
/**
|
|
9419
|
+
* The word after the number — « pièces », "results", "matches".
|
|
9420
|
+
*
|
|
9421
|
+
* A plain string and not a template: the count reads `12 pièces`, and a
|
|
9422
|
+
* language that needs another order or a plural rule formats the whole thing
|
|
9423
|
+
* upstream and passes it as {@link resultLabel} with `resultCount` left null…
|
|
9424
|
+
* which it cannot. So: this covers `<number> <word>`, and anything else stays
|
|
9425
|
+
* the consumer's own markup beside the box.
|
|
9426
|
+
*/
|
|
9427
|
+
resultLabel = input("results", /* @ts-ignore */
|
|
9428
|
+
...(ngDevMode ? [{ debugName: "resultLabel" }] : /* istanbul ignore next */ []));
|
|
9429
|
+
/**
|
|
9430
|
+
* Where the count sits: above the box, after it on the same line, or below.
|
|
9431
|
+
*
|
|
9432
|
+
* `end` and not `right` — the whole library lays out in **logical**
|
|
9433
|
+
* properties, so the count follows the reading direction instead of pinning
|
|
9434
|
+
* itself to a side of the screen.
|
|
9435
|
+
*/
|
|
9436
|
+
placement = input("end", /* @ts-ignore */
|
|
9437
|
+
...(ngDevMode ? [{ debugName: "placement" }] : /* istanbul ignore next */ []));
|
|
9321
9438
|
/** Quiet period after the last keystroke before emitting, in ms. */
|
|
9322
9439
|
delayMs = input(300, /* @ts-ignore */
|
|
9323
9440
|
...(ngDevMode ? [{ debugName: "delayMs" }] : /* istanbul ignore next */ []));
|
|
9324
9441
|
/** Emits the trimmed term once typing pauses for `delayMs` (deduped). */
|
|
9325
9442
|
searchChange = output();
|
|
9443
|
+
showCount = computed(() => this.resultCount() !== null, /* @ts-ignore */
|
|
9444
|
+
...(ngDevMode ? [{ debugName: "showCount" }] : /* istanbul ignore next */ []));
|
|
9445
|
+
countText = computed(() => `${String(this.resultCount() ?? 0)} ${this.resultLabel()}`, /* @ts-ignore */
|
|
9446
|
+
...(ngDevMode ? [{ debugName: "countText" }] : /* istanbul ignore next */ []));
|
|
9326
9447
|
timer = null;
|
|
9327
9448
|
lastEmitted = "";
|
|
9328
9449
|
constructor() {
|
|
9329
9450
|
// A pending timer that outlives the view would fire a stray emit.
|
|
9330
9451
|
inject(DestroyRef).onDestroy(() => this.clear());
|
|
9331
9452
|
}
|
|
9453
|
+
/**
|
|
9454
|
+
* The value moves **now**, the event waits.
|
|
9455
|
+
*
|
|
9456
|
+
* The box must show what was typed on the keystroke — deferring the text
|
|
9457
|
+
* itself would make the field feel broken — while the query it triggers is
|
|
9458
|
+
* what deserves the quiet period. Clearing settles like any other edit: the
|
|
9459
|
+
* empty term goes out after the same delay, so a consumer sees one contract
|
|
9460
|
+
* and not two.
|
|
9461
|
+
*/
|
|
9332
9462
|
onInput(value) {
|
|
9463
|
+
this.value.set(value);
|
|
9333
9464
|
const term = value.trim();
|
|
9334
9465
|
this.clear();
|
|
9335
9466
|
this.timer = setTimeout(() => {
|
|
@@ -9346,28 +9477,14 @@ class FoldSearchComponent {
|
|
|
9346
9477
|
}
|
|
9347
9478
|
}
|
|
9348
9479
|
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.8", ngImport: i0, type: FoldSearchComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
9349
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.
|
|
9350
|
-
<fold-input
|
|
9351
|
-
type="text"
|
|
9352
|
-
[placeholder]="placeholder()"
|
|
9353
|
-
[size]="size()"
|
|
9354
|
-
[variant]="variant()"
|
|
9355
|
-
(valueChange)="onInput($event)"
|
|
9356
|
-
/>
|
|
9357
|
-
`, isInline: true, styles: [":host{display:block}\n"], dependencies: [{ kind: "component", type: FoldInputComponent, selector: "fold-input", inputs: ["value", "disabled", "touched", "errors", "type", "revealable", "revealLabel", "hideLabel", "size", "align", "variant", "label", "required", "optional", "optionalLabel", "info", "infoLabel", "ariaLabel", "hint", "placeholder", "readOnly", "autofocus", "autocomplete"], outputs: ["valueChange", "touchedChange"] }] });
|
|
9480
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.0.8", type: FoldSearchComponent, isStandalone: true, selector: "fold-search", inputs: { value: { classPropertyName: "value", publicName: "value", isSignal: true, isRequired: false, transformFunction: null }, placeholder: { classPropertyName: "placeholder", publicName: "placeholder", isSignal: true, isRequired: false, transformFunction: null }, size: { classPropertyName: "size", publicName: "size", isSignal: true, isRequired: false, transformFunction: null }, variant: { classPropertyName: "variant", publicName: "variant", isSignal: true, isRequired: false, transformFunction: null }, ariaLabel: { classPropertyName: "ariaLabel", publicName: "ariaLabel", isSignal: true, isRequired: false, transformFunction: null }, clearable: { classPropertyName: "clearable", publicName: "clearable", isSignal: true, isRequired: false, transformFunction: null }, clearLabel: { classPropertyName: "clearLabel", publicName: "clearLabel", isSignal: true, isRequired: false, transformFunction: null }, resultCount: { classPropertyName: "resultCount", publicName: "resultCount", isSignal: true, isRequired: false, transformFunction: null }, resultLabel: { classPropertyName: "resultLabel", publicName: "resultLabel", isSignal: true, isRequired: false, transformFunction: null }, placement: { classPropertyName: "placement", publicName: "placement", isSignal: true, isRequired: false, transformFunction: null }, delayMs: { classPropertyName: "delayMs", publicName: "delayMs", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { value: "valueChange", searchChange: "searchChange" }, host: { properties: { "class": "placement()" } }, ngImport: i0, template: "@if (showCount() && placement() === \"top\") {\n <p class=\"se-count\" role=\"status\" aria-live=\"polite\">{{ countText() }}</p>\n}\n\n<fold-input\n type=\"text\"\n leadingIcon=\"search\"\n [clearable]=\"clearable()\"\n [clearLabel]=\"clearLabel()\"\n [placeholder]=\"placeholder()\"\n [ariaLabel]=\"ariaLabel()\"\n [size]=\"size()\"\n [variant]=\"variant()\"\n [value]=\"value()\"\n (valueChange)=\"onInput($event)\"\n/>\n\n@if (showCount() && placement() !== \"top\") {\n <p class=\"se-count\" role=\"status\" aria-live=\"polite\">{{ countText() }}</p>\n}\n", styles: [":host{display:grid;gap:var(--fold-space-2xs)}:host(.end){grid-template-columns:minmax(0,1fr) auto;align-items:center;gap:var(--fold-space-sm)}.se-count{margin:0;font-size:var(--fold-text-xs);color:var(--fold-color-text-muted);white-space:nowrap}:host(.top) .se-count,:host(.bottom) .se-count{justify-self:end}\n"], dependencies: [{ kind: "component", type: FoldInputComponent, selector: "fold-input", inputs: ["value", "disabled", "touched", "errors", "type", "revealable", "revealLabel", "hideLabel", "size", "align", "variant", "label", "required", "optional", "optionalLabel", "info", "infoLabel", "ariaLabel", "hint", "placeholder", "leadingIcon", "clearable", "clearLabel", "readOnly", "autofocus", "autocomplete"], outputs: ["valueChange", "touchedChange"] }] });
|
|
9358
9481
|
}
|
|
9359
9482
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.8", ngImport: i0, type: FoldSearchComponent, decorators: [{
|
|
9360
9483
|
type: Component,
|
|
9361
|
-
args: [{ selector: "fold-search", standalone: true, imports: [FoldInputComponent],
|
|
9362
|
-
|
|
9363
|
-
|
|
9364
|
-
|
|
9365
|
-
[size]="size()"
|
|
9366
|
-
[variant]="variant()"
|
|
9367
|
-
(valueChange)="onInput($event)"
|
|
9368
|
-
/>
|
|
9369
|
-
`, styles: [":host{display:block}\n"] }]
|
|
9370
|
-
}], ctorParameters: () => [], propDecorators: { placeholder: [{ type: i0.Input, args: [{ isSignal: true, alias: "placeholder", required: false }] }], size: [{ type: i0.Input, args: [{ isSignal: true, alias: "size", required: false }] }], variant: [{ type: i0.Input, args: [{ isSignal: true, alias: "variant", required: false }] }], delayMs: [{ type: i0.Input, args: [{ isSignal: true, alias: "delayMs", required: false }] }], searchChange: [{ type: i0.Output, args: ["searchChange"] }] } });
|
|
9484
|
+
args: [{ selector: "fold-search", standalone: true, imports: [FoldInputComponent], host: {
|
|
9485
|
+
"[class]": "placement()",
|
|
9486
|
+
}, template: "@if (showCount() && placement() === \"top\") {\n <p class=\"se-count\" role=\"status\" aria-live=\"polite\">{{ countText() }}</p>\n}\n\n<fold-input\n type=\"text\"\n leadingIcon=\"search\"\n [clearable]=\"clearable()\"\n [clearLabel]=\"clearLabel()\"\n [placeholder]=\"placeholder()\"\n [ariaLabel]=\"ariaLabel()\"\n [size]=\"size()\"\n [variant]=\"variant()\"\n [value]=\"value()\"\n (valueChange)=\"onInput($event)\"\n/>\n\n@if (showCount() && placement() !== \"top\") {\n <p class=\"se-count\" role=\"status\" aria-live=\"polite\">{{ countText() }}</p>\n}\n", styles: [":host{display:grid;gap:var(--fold-space-2xs)}:host(.end){grid-template-columns:minmax(0,1fr) auto;align-items:center;gap:var(--fold-space-sm)}.se-count{margin:0;font-size:var(--fold-text-xs);color:var(--fold-color-text-muted);white-space:nowrap}:host(.top) .se-count,:host(.bottom) .se-count{justify-self:end}\n"] }]
|
|
9487
|
+
}], ctorParameters: () => [], propDecorators: { value: [{ type: i0.Input, args: [{ isSignal: true, alias: "value", required: false }] }, { type: i0.Output, args: ["valueChange"] }], placeholder: [{ type: i0.Input, args: [{ isSignal: true, alias: "placeholder", required: false }] }], size: [{ type: i0.Input, args: [{ isSignal: true, alias: "size", required: false }] }], variant: [{ type: i0.Input, args: [{ isSignal: true, alias: "variant", required: false }] }], ariaLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "ariaLabel", required: false }] }], clearable: [{ type: i0.Input, args: [{ isSignal: true, alias: "clearable", required: false }] }], clearLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "clearLabel", required: false }] }], resultCount: [{ type: i0.Input, args: [{ isSignal: true, alias: "resultCount", required: false }] }], resultLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "resultLabel", required: false }] }], placement: [{ type: i0.Input, args: [{ isSignal: true, alias: "placement", required: false }] }], delayMs: [{ type: i0.Input, args: [{ isSignal: true, alias: "delayMs", required: false }] }], searchChange: [{ type: i0.Output, args: ["searchChange"] }] } });
|
|
9371
9488
|
|
|
9372
9489
|
/**
|
|
9373
9490
|
* `<fold-select>` — the dropdown sibling of {@link FoldInputComponent} and
|
|
@@ -10503,7 +10620,7 @@ class FoldPasswordFieldComponent {
|
|
|
10503
10620
|
effect(() => this.validChange.emit(this.allValid()));
|
|
10504
10621
|
}
|
|
10505
10622
|
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.8", ngImport: i0, type: FoldPasswordFieldComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
10506
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.0.8", type: FoldPasswordFieldComponent, isStandalone: true, selector: "fold-password-field", inputs: { value: { classPropertyName: "value", publicName: "value", isSignal: true, isRequired: false, transformFunction: null }, disabled: { classPropertyName: "disabled", publicName: "disabled", isSignal: true, isRequired: false, transformFunction: null }, touched: { classPropertyName: "touched", publicName: "touched", isSignal: true, isRequired: false, transformFunction: null }, errors: { classPropertyName: "errors", publicName: "errors", isSignal: true, isRequired: false, transformFunction: null }, label: { classPropertyName: "label", publicName: "label", isSignal: true, isRequired: false, transformFunction: null }, placeholder: { classPropertyName: "placeholder", publicName: "placeholder", isSignal: true, isRequired: false, transformFunction: null }, hint: { classPropertyName: "hint", publicName: "hint", isSignal: true, isRequired: false, transformFunction: null }, required: { classPropertyName: "required", publicName: "required", isSignal: true, isRequired: false, transformFunction: null }, size: { classPropertyName: "size", publicName: "size", isSignal: true, isRequired: false, transformFunction: null }, variant: { classPropertyName: "variant", publicName: "variant", isSignal: true, isRequired: false, transformFunction: null }, autocomplete: { classPropertyName: "autocomplete", publicName: "autocomplete", isSignal: true, isRequired: false, transformFunction: null }, revealable: { classPropertyName: "revealable", publicName: "revealable", isSignal: true, isRequired: false, transformFunction: null }, revealLabel: { classPropertyName: "revealLabel", publicName: "revealLabel", isSignal: true, isRequired: false, transformFunction: null }, hideLabel: { classPropertyName: "hideLabel", publicName: "hideLabel", isSignal: true, isRequired: false, transformFunction: null }, rules: { classPropertyName: "rules", publicName: "rules", isSignal: true, isRequired: false, transformFunction: null }, marker: { classPropertyName: "marker", publicName: "marker", isSignal: true, isRequired: false, transformFunction: null }, rulesLabel: { classPropertyName: "rulesLabel", publicName: "rulesLabel", isSignal: true, isRequired: false, transformFunction: null }, metLabel: { classPropertyName: "metLabel", publicName: "metLabel", isSignal: true, isRequired: false, transformFunction: null }, unmetLabel: { classPropertyName: "unmetLabel", publicName: "unmetLabel", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { value: "valueChange", touched: "touchedChange", validChange: "validChange" }, exportAs: ["foldPasswordField"], ngImport: i0, template: "<fold-input\n type=\"password\"\n [label]=\"label()\"\n [placeholder]=\"placeholder()\"\n [hint]=\"hint()\"\n [required]=\"required()\"\n [size]=\"size()\"\n [variant]=\"variant()\"\n [disabled]=\"disabled()\"\n [revealable]=\"revealable()\"\n [revealLabel]=\"revealLabel()\"\n [hideLabel]=\"hideLabel()\"\n [autocomplete]=\"autocomplete()\"\n [errors]=\"errors()\"\n [(value)]=\"value\"\n [(touched)]=\"touched\"\n/>\n\n<!-- Project into `[rules]` to redesign the checklist off the same state\n (`#pw=\"foldPasswordField\"` \u2192 `pw.checklist()`); otherwise the default list\n below is the fallback content. -->\n<ng-content select=\"[rules]\">\n @if (checklist().length) {\n <ul class=\"pw-rules\" [attr.aria-label]=\"rulesLabel()\" aria-live=\"polite\">\n @for (rule of checklist(); track rule.label) {\n <li class=\"pw-rule\" [class.is-met]=\"rule.met\">\n @if (marker() === \"check\") {\n <span class=\"pw-mark\" aria-hidden=\"true\">\n @if (rule.met) {\n <fold-icon name=\"check\" size=\"sm\" />\n }\n </span>\n } @else {\n <span class=\"pw-dot\" aria-hidden=\"true\"></span>\n }\n <span class=\"pw-rule-label\">{{ rule.label }}</span>\n <!-- The met/unmet word is real text (not just an attribute), so the\n aria-live region actually announces a rule flipping. -->\n <span class=\"pw-sr\"\n >\u2014 {{ rule.met ? metLabel() : unmetLabel() }}</span\n >\n </li>\n }\n </ul>\n }\n</ng-content>\n", styles: [":host{display:block}.pw-rules{list-style:none;margin:.5rem 0 0;padding:0;display:flex;flex-direction:column;gap:.25rem}.pw-rule{display:flex;align-items:center;gap:.45rem;font-size:var(--fold-text-xs);color:var(--fold-color-text-muted);transition:color var(--fold-motion-fast)}.pw-dot{flex:none;width:.5rem;height:.5rem;border-radius:var(--fold-radius-round);border:1.5px solid var(--fold-color-text-faded);box-sizing:border-box;transition:background var(--fold-motion-fast),border-color var(--fold-motion-fast)}.pw-rule.is-met{color:var(--fold-color-text)}.pw-rule.is-met .pw-dot{border-color:var(--fold-color-primary);background:var(--fold-color-primary)}.pw-mark{flex:none;width:.85rem;height:.85rem;display:grid;place-items:center;color:var(--fold-color-primary)}.pw-rule:not(.is-met) .pw-mark{border:1.5px solid var(--fold-color-text-faded);border-radius:var(--fold-radius-round);box-sizing:border-box}@media(forced-colors:active){.pw-rule.is-met .pw-dot{background:Highlight;border-color:Highlight}.pw-mark{color:Highlight}}.pw-sr{position:absolute;width:1px;height:1px;margin:-1px;padding:0;border:0;overflow:hidden;clip:rect(0 0 0 0);clip-path:inset(50%);white-space:nowrap}\n"], dependencies: [{ kind: "component", type: FoldInputComponent, selector: "fold-input", inputs: ["value", "disabled", "touched", "errors", "type", "revealable", "revealLabel", "hideLabel", "size", "align", "variant", "label", "required", "optional", "optionalLabel", "info", "infoLabel", "ariaLabel", "hint", "placeholder", "readOnly", "autofocus", "autocomplete"], outputs: ["valueChange", "touchedChange"] }, { kind: "component", type: FoldIconComponent, selector: "fold-icon", inputs: ["name", "size", "tone", "title"] }] });
|
|
10623
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.0.8", type: FoldPasswordFieldComponent, isStandalone: true, selector: "fold-password-field", inputs: { value: { classPropertyName: "value", publicName: "value", isSignal: true, isRequired: false, transformFunction: null }, disabled: { classPropertyName: "disabled", publicName: "disabled", isSignal: true, isRequired: false, transformFunction: null }, touched: { classPropertyName: "touched", publicName: "touched", isSignal: true, isRequired: false, transformFunction: null }, errors: { classPropertyName: "errors", publicName: "errors", isSignal: true, isRequired: false, transformFunction: null }, label: { classPropertyName: "label", publicName: "label", isSignal: true, isRequired: false, transformFunction: null }, placeholder: { classPropertyName: "placeholder", publicName: "placeholder", isSignal: true, isRequired: false, transformFunction: null }, hint: { classPropertyName: "hint", publicName: "hint", isSignal: true, isRequired: false, transformFunction: null }, required: { classPropertyName: "required", publicName: "required", isSignal: true, isRequired: false, transformFunction: null }, size: { classPropertyName: "size", publicName: "size", isSignal: true, isRequired: false, transformFunction: null }, variant: { classPropertyName: "variant", publicName: "variant", isSignal: true, isRequired: false, transformFunction: null }, autocomplete: { classPropertyName: "autocomplete", publicName: "autocomplete", isSignal: true, isRequired: false, transformFunction: null }, revealable: { classPropertyName: "revealable", publicName: "revealable", isSignal: true, isRequired: false, transformFunction: null }, revealLabel: { classPropertyName: "revealLabel", publicName: "revealLabel", isSignal: true, isRequired: false, transformFunction: null }, hideLabel: { classPropertyName: "hideLabel", publicName: "hideLabel", isSignal: true, isRequired: false, transformFunction: null }, rules: { classPropertyName: "rules", publicName: "rules", isSignal: true, isRequired: false, transformFunction: null }, marker: { classPropertyName: "marker", publicName: "marker", isSignal: true, isRequired: false, transformFunction: null }, rulesLabel: { classPropertyName: "rulesLabel", publicName: "rulesLabel", isSignal: true, isRequired: false, transformFunction: null }, metLabel: { classPropertyName: "metLabel", publicName: "metLabel", isSignal: true, isRequired: false, transformFunction: null }, unmetLabel: { classPropertyName: "unmetLabel", publicName: "unmetLabel", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { value: "valueChange", touched: "touchedChange", validChange: "validChange" }, exportAs: ["foldPasswordField"], ngImport: i0, template: "<fold-input\n type=\"password\"\n [label]=\"label()\"\n [placeholder]=\"placeholder()\"\n [hint]=\"hint()\"\n [required]=\"required()\"\n [size]=\"size()\"\n [variant]=\"variant()\"\n [disabled]=\"disabled()\"\n [revealable]=\"revealable()\"\n [revealLabel]=\"revealLabel()\"\n [hideLabel]=\"hideLabel()\"\n [autocomplete]=\"autocomplete()\"\n [errors]=\"errors()\"\n [(value)]=\"value\"\n [(touched)]=\"touched\"\n/>\n\n<!-- Project into `[rules]` to redesign the checklist off the same state\n (`#pw=\"foldPasswordField\"` \u2192 `pw.checklist()`); otherwise the default list\n below is the fallback content. -->\n<ng-content select=\"[rules]\">\n @if (checklist().length) {\n <ul class=\"pw-rules\" [attr.aria-label]=\"rulesLabel()\" aria-live=\"polite\">\n @for (rule of checklist(); track rule.label) {\n <li class=\"pw-rule\" [class.is-met]=\"rule.met\">\n @if (marker() === \"check\") {\n <span class=\"pw-mark\" aria-hidden=\"true\">\n @if (rule.met) {\n <fold-icon name=\"check\" size=\"sm\" />\n }\n </span>\n } @else {\n <span class=\"pw-dot\" aria-hidden=\"true\"></span>\n }\n <span class=\"pw-rule-label\">{{ rule.label }}</span>\n <!-- The met/unmet word is real text (not just an attribute), so the\n aria-live region actually announces a rule flipping. -->\n <span class=\"pw-sr\"\n >\u2014 {{ rule.met ? metLabel() : unmetLabel() }}</span\n >\n </li>\n }\n </ul>\n }\n</ng-content>\n", styles: [":host{display:block}.pw-rules{list-style:none;margin:.5rem 0 0;padding:0;display:flex;flex-direction:column;gap:.25rem}.pw-rule{display:flex;align-items:center;gap:.45rem;font-size:var(--fold-text-xs);color:var(--fold-color-text-muted);transition:color var(--fold-motion-fast)}.pw-dot{flex:none;width:.5rem;height:.5rem;border-radius:var(--fold-radius-round);border:1.5px solid var(--fold-color-text-faded);box-sizing:border-box;transition:background var(--fold-motion-fast),border-color var(--fold-motion-fast)}.pw-rule.is-met{color:var(--fold-color-text)}.pw-rule.is-met .pw-dot{border-color:var(--fold-color-primary);background:var(--fold-color-primary)}.pw-mark{flex:none;width:.85rem;height:.85rem;display:grid;place-items:center;color:var(--fold-color-primary)}.pw-rule:not(.is-met) .pw-mark{border:1.5px solid var(--fold-color-text-faded);border-radius:var(--fold-radius-round);box-sizing:border-box}@media(forced-colors:active){.pw-rule.is-met .pw-dot{background:Highlight;border-color:Highlight}.pw-mark{color:Highlight}}.pw-sr{position:absolute;width:1px;height:1px;margin:-1px;padding:0;border:0;overflow:hidden;clip:rect(0 0 0 0);clip-path:inset(50%);white-space:nowrap}\n"], dependencies: [{ kind: "component", type: FoldInputComponent, selector: "fold-input", inputs: ["value", "disabled", "touched", "errors", "type", "revealable", "revealLabel", "hideLabel", "size", "align", "variant", "label", "required", "optional", "optionalLabel", "info", "infoLabel", "ariaLabel", "hint", "placeholder", "leadingIcon", "clearable", "clearLabel", "readOnly", "autofocus", "autocomplete"], outputs: ["valueChange", "touchedChange"] }, { kind: "component", type: FoldIconComponent, selector: "fold-icon", inputs: ["name", "size", "tone", "title"] }] });
|
|
10507
10624
|
}
|
|
10508
10625
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.8", ngImport: i0, type: FoldPasswordFieldComponent, decorators: [{
|
|
10509
10626
|
type: Component,
|