@radix-ng/primitives 1.0.10 → 1.1.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/README.md +26 -5
- package/fesm2022/radix-ng-primitives-autocomplete.mjs +88 -21
- package/fesm2022/radix-ng-primitives-autocomplete.mjs.map +1 -1
- package/fesm2022/radix-ng-primitives-checkbox.mjs +199 -129
- package/fesm2022/radix-ng-primitives-checkbox.mjs.map +1 -1
- package/fesm2022/radix-ng-primitives-combobox.mjs +203 -52
- package/fesm2022/radix-ng-primitives-combobox.mjs.map +1 -1
- package/fesm2022/radix-ng-primitives-composite.mjs +221 -36
- package/fesm2022/radix-ng-primitives-composite.mjs.map +1 -1
- package/fesm2022/radix-ng-primitives-core.mjs +352 -24
- package/fesm2022/radix-ng-primitives-core.mjs.map +1 -1
- package/fesm2022/radix-ng-primitives-date-field.mjs +11 -5
- package/fesm2022/radix-ng-primitives-date-field.mjs.map +1 -1
- package/fesm2022/radix-ng-primitives-field.mjs +127 -23
- package/fesm2022/radix-ng-primitives-field.mjs.map +1 -1
- package/fesm2022/radix-ng-primitives-form.mjs +35 -4
- package/fesm2022/radix-ng-primitives-form.mjs.map +1 -1
- package/fesm2022/radix-ng-primitives-input.mjs +87 -15
- package/fesm2022/radix-ng-primitives-input.mjs.map +1 -1
- package/fesm2022/radix-ng-primitives-menu.mjs +34 -7
- package/fesm2022/radix-ng-primitives-menu.mjs.map +1 -1
- package/fesm2022/radix-ng-primitives-number-field.mjs +38 -7
- package/fesm2022/radix-ng-primitives-number-field.mjs.map +1 -1
- package/fesm2022/radix-ng-primitives-popper.mjs +80 -11
- package/fesm2022/radix-ng-primitives-popper.mjs.map +1 -1
- package/fesm2022/radix-ng-primitives-radio.mjs +49 -2
- package/fesm2022/radix-ng-primitives-radio.mjs.map +1 -1
- package/fesm2022/radix-ng-primitives-scroll-area.mjs +6 -3
- package/fesm2022/radix-ng-primitives-scroll-area.mjs.map +1 -1
- package/fesm2022/radix-ng-primitives-select.mjs +70 -14
- package/fesm2022/radix-ng-primitives-select.mjs.map +1 -1
- package/fesm2022/radix-ng-primitives-signal-forms.mjs +27 -11
- package/fesm2022/radix-ng-primitives-signal-forms.mjs.map +1 -1
- package/fesm2022/radix-ng-primitives-slider.mjs +17 -2
- package/fesm2022/radix-ng-primitives-slider.mjs.map +1 -1
- package/fesm2022/radix-ng-primitives-switch.mjs +60 -7
- package/fesm2022/radix-ng-primitives-switch.mjs.map +1 -1
- package/fesm2022/radix-ng-primitives-time-field.mjs +12 -6
- package/fesm2022/radix-ng-primitives-time-field.mjs.map +1 -1
- package/fesm2022/radix-ng-primitives-toggle-group.mjs +25 -3
- package/fesm2022/radix-ng-primitives-toggle-group.mjs.map +1 -1
- package/package.json +8 -3
- package/types/radix-ng-primitives-autocomplete.d.ts +16 -2
- package/types/radix-ng-primitives-checkbox.d.ts +66 -44
- package/types/radix-ng-primitives-combobox.d.ts +74 -3
- package/types/radix-ng-primitives-composite.d.ts +48 -2
- package/types/radix-ng-primitives-core.d.ts +212 -96
- package/types/radix-ng-primitives-date-field.d.ts +7 -4
- package/types/radix-ng-primitives-field.d.ts +55 -8
- package/types/radix-ng-primitives-form.d.ts +9 -0
- package/types/radix-ng-primitives-input.d.ts +10 -2
- package/types/radix-ng-primitives-menu.d.ts +45 -4
- package/types/radix-ng-primitives-navigation-menu.d.ts +2 -2
- package/types/radix-ng-primitives-number-field.d.ts +12 -5
- package/types/radix-ng-primitives-popover.d.ts +2 -2
- package/types/radix-ng-primitives-popper.d.ts +60 -15
- package/types/radix-ng-primitives-preview-card.d.ts +2 -2
- package/types/radix-ng-primitives-radio.d.ts +6 -1
- package/types/radix-ng-primitives-select.d.ts +25 -4
- package/types/radix-ng-primitives-signal-forms.d.ts +22 -8
- package/types/radix-ng-primitives-slider.d.ts +2 -1
- package/types/radix-ng-primitives-switch.d.ts +19 -3
- package/types/radix-ng-primitives-time-field.d.ts +9 -6
- package/types/radix-ng-primitives-toggle-group.d.ts +5 -1
- package/types/radix-ng-primitives-tooltip.d.ts +2 -2
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import * as i0 from '@angular/core';
|
|
2
|
-
import { inject, DestroyRef, Directive, input, NgModule } from '@angular/core';
|
|
3
|
-
import { FormField } from '@angular/forms/signals';
|
|
2
|
+
import { inject, DestroyRef, Directive, input, booleanAttribute, NgModule } from '@angular/core';
|
|
3
|
+
import { FormField, submit } from '@angular/forms/signals';
|
|
4
4
|
import { injectFieldRootContext } from '@radix-ng/primitives/field';
|
|
5
5
|
import { injectFormRootContext } from '@radix-ng/primitives/form';
|
|
6
6
|
|
|
@@ -19,9 +19,9 @@ import { injectFormRootContext } from '@radix-ng/primitives/form';
|
|
|
19
19
|
*
|
|
20
20
|
* It owns no model and runs no validation — Signal Forms remains the source of truth. It only registers
|
|
21
21
|
* an {@link RdxFieldState} provider on the ancestor Field context so the field's `invalid` / `disabled` /
|
|
22
|
-
* `required` / `dirty` / `touched` data-attributes and the error *content*
|
|
23
|
-
* read authoritative Signal Forms state. `filled` / `focused` stay on
|
|
24
|
-
* ownership — the seam supports it).
|
|
22
|
+
* `required` / `dirty` / `touched` data-attributes, tri-state pending validity, and the error *content*
|
|
23
|
+
* (`rdxFieldError.messages()`) read authoritative Signal Forms state. `filled` / `focused` stay on
|
|
24
|
+
* Field's DOM heuristic (partial ownership — the seam supports it).
|
|
25
25
|
*
|
|
26
26
|
* It reports the **actual** Signal Forms state only; the `Field` decides *when* to display it from its
|
|
27
27
|
* `validationMode` (default `'onBlur'` — neutral until the field is touched or the form submitted). So an
|
|
@@ -42,6 +42,7 @@ class RdxSignalField {
|
|
|
42
42
|
// adapter reports authoritative *actual* state; the Field gates the *display* by its validationMode.
|
|
43
43
|
const state = {
|
|
44
44
|
invalid: () => this.state().invalid(),
|
|
45
|
+
pending: () => this.state().pending(),
|
|
45
46
|
disabled: () => this.state().disabled(),
|
|
46
47
|
required: () => this.state().required(),
|
|
47
48
|
dirty: () => this.state().dirty(),
|
|
@@ -81,9 +82,13 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.2", ngImpor
|
|
|
81
82
|
*
|
|
82
83
|
* Registers an {@link RdxFormState} provider so the Form's aggregate `data-invalid` / `data-dirty` /
|
|
83
84
|
* `data-touched` / `data-submitting` attributes and the submit guard read authoritative Signal Forms
|
|
84
|
-
* state.
|
|
85
|
-
* eager channel applied through `rdxFormRoot[errors]
|
|
86
|
-
* submit lifecycle.
|
|
85
|
+
* state. By default this adapter owns only client-side state and `name`-routing; server errors stay a
|
|
86
|
+
* separate eager channel applied through `rdxFormRoot[errors]`. Add `rdxSignalSubmit` to delegate native
|
|
87
|
+
* submission to Signal Forms' own `submit()` lifecycle instead of `rdxFormRoot.onFormSubmit`:
|
|
88
|
+
*
|
|
89
|
+
* ```html
|
|
90
|
+
* <form rdxFormRoot [rdxSignalForm]="loginForm" rdxSignalSubmit>…</form>
|
|
91
|
+
* ```
|
|
87
92
|
*
|
|
88
93
|
* `errorsFor(name)` routes a field's errors to a `rdxFieldRoot` by its `name`, walking the `FieldTree`
|
|
89
94
|
* so dotted paths into nested object/array fields resolve too (`address.street`, `items.0.name`). A
|
|
@@ -92,7 +97,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.2", ngImpor
|
|
|
92
97
|
* a field carries both, `rdxFieldError.messages()` deduplicates by text so the shared message is not
|
|
93
98
|
* shown twice.
|
|
94
99
|
*
|
|
95
|
-
* See ADR 0018.
|
|
100
|
+
* See ADR 0018 and ADR 0020.
|
|
96
101
|
*
|
|
97
102
|
* @group Components
|
|
98
103
|
*/
|
|
@@ -100,12 +105,23 @@ class RdxSignalForm {
|
|
|
100
105
|
constructor() {
|
|
101
106
|
/** The Signal Forms root field (from `form(...)`) whose aggregate state drives the enclosing Form. */
|
|
102
107
|
this.form = input.required({ ...(ngDevMode ? { debugName: "form" } : /* istanbul ignore next */ {}), alias: 'rdxSignalForm' });
|
|
108
|
+
/**
|
|
109
|
+
* Delegate native submission to Angular Signal Forms' `submit()` lifecycle. Opt-in so adding the
|
|
110
|
+
* state adapter to an existing 1.x form cannot silently replace its `(onFormSubmit)` side effects.
|
|
111
|
+
* The bound `form()` must define `submission.action`; Angular reports a descriptive error otherwise.
|
|
112
|
+
*
|
|
113
|
+
* @group Props
|
|
114
|
+
* @defaultValue false
|
|
115
|
+
*/
|
|
116
|
+
this.signalSubmit = input(false, { ...(ngDevMode ? { debugName: "signalSubmit" } : /* istanbul ignore next */ {}), alias: 'rdxSignalSubmit',
|
|
117
|
+
transform: booleanAttribute });
|
|
103
118
|
this.formContext = injectFormRootContext();
|
|
104
119
|
const state = {
|
|
105
120
|
invalid: () => this.state().invalid(),
|
|
106
121
|
dirty: () => this.state().dirty(),
|
|
107
122
|
touched: () => this.state().touched(),
|
|
108
123
|
submitting: () => this.state().submitting(),
|
|
124
|
+
submit: () => (this.signalSubmit() ? submit(this.form()) : undefined),
|
|
109
125
|
errorsFor: (name) => this.errorsFor(name),
|
|
110
126
|
// Per-name interaction state so a name-routed field (bare `[formField]`, no `rdxSignalField`)
|
|
111
127
|
// can reveal its error on blur/change under `validationMode="onBlur"`/`"onChange"`.
|
|
@@ -152,7 +168,7 @@ class RdxSignalForm {
|
|
|
152
168
|
return this.form()();
|
|
153
169
|
}
|
|
154
170
|
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.2", ngImport: i0, type: RdxSignalForm, deps: [], target: i0.ɵɵFactoryTarget.Directive }); }
|
|
155
|
-
static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "17.1.0", version: "22.0.2", type: RdxSignalForm, isStandalone: true, selector: "form[rdxFormRoot][rdxSignalForm]", inputs: { form: { classPropertyName: "form", publicName: "rdxSignalForm", isSignal: true, isRequired: true, transformFunction: null } }, exportAs: ["rdxSignalForm"], ngImport: i0 }); }
|
|
171
|
+
static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "17.1.0", version: "22.0.2", type: RdxSignalForm, isStandalone: true, selector: "form[rdxFormRoot][rdxSignalForm]", inputs: { form: { classPropertyName: "form", publicName: "rdxSignalForm", isSignal: true, isRequired: true, transformFunction: null }, signalSubmit: { classPropertyName: "signalSubmit", publicName: "rdxSignalSubmit", isSignal: true, isRequired: false, transformFunction: null } }, exportAs: ["rdxSignalForm"], ngImport: i0 }); }
|
|
156
172
|
}
|
|
157
173
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.2", ngImport: i0, type: RdxSignalForm, decorators: [{
|
|
158
174
|
type: Directive,
|
|
@@ -160,7 +176,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.2", ngImpor
|
|
|
160
176
|
selector: 'form[rdxFormRoot][rdxSignalForm]',
|
|
161
177
|
exportAs: 'rdxSignalForm'
|
|
162
178
|
}]
|
|
163
|
-
}], ctorParameters: () => [], propDecorators: { form: [{ type: i0.Input, args: [{ isSignal: true, alias: "rdxSignalForm", required: true }] }] } });
|
|
179
|
+
}], ctorParameters: () => [], propDecorators: { form: [{ type: i0.Input, args: [{ isSignal: true, alias: "rdxSignalForm", required: true }] }], signalSubmit: [{ type: i0.Input, args: [{ isSignal: true, alias: "rdxSignalSubmit", required: false }] }] } });
|
|
164
180
|
|
|
165
181
|
const _importsSignalForms = [RdxSignalField, RdxSignalForm];
|
|
166
182
|
class RdxSignalFormsModule {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"radix-ng-primitives-signal-forms.mjs","sources":["../../../packages/primitives/signal-forms/src/signal-field.ts","../../../packages/primitives/signal-forms/src/signal-form.ts","../../../packages/primitives/signal-forms/index.ts","../../../packages/primitives/signal-forms/radix-ng-primitives-signal-forms.ts"],"sourcesContent":["import { DestroyRef, Directive, inject } from '@angular/core';\nimport { FormField } from '@angular/forms/signals';\nimport { injectFieldRootContext, RdxFieldState } from '@radix-ng/primitives/field';\n\n/**\n * Bridges an Angular **Signal Forms** field into an enclosing `rdxFieldRoot` — with **no duplicate\n * binding**. Place it on the control that already carries `[formField]`; it reads the bound field's\n * state from that directive, so the field expression is written exactly once:\n *\n * ```html\n * <div rdxFieldRoot>\n * <label rdxFieldLabel>Email</label>\n * <input rdxInput [formField]=\"loginForm.email\" rdxSignalField />\n * <p rdxFieldError>Email is required.</p>\n * </div>\n * ```\n *\n * It owns no model and runs no validation — Signal Forms remains the source of truth. It only registers\n * an {@link RdxFieldState} provider on the ancestor Field context so the field's `invalid` / `disabled` /\n * `required` / `dirty` / `touched` data-attributes and the error *content* (`rdxFieldError.messages()`)\n * read authoritative Signal Forms state. `filled` / `focused` stay on Field's DOM heuristic (partial\n * ownership — the seam supports it).\n *\n * It reports the **actual** Signal Forms state only; the `Field` decides *when* to display it from its\n * `validationMode` (default `'onBlur'` — neutral until the field is touched or the form submitted). So an\n * empty required field is neutral on load with no manual `[invalid]`/`[touched]` wiring, and a pristine\n * submit reveals the errors (the `Form` records the submit attempt before checking validity and blocks).\n *\n * See ADR 0018.\n *\n * @group Components\n */\n@Directive({\n selector: '[formField][rdxSignalField]',\n exportAs: 'rdxSignalField'\n})\nexport class RdxSignalField {\n /** The co-located `[formField]` directive — the single source of the bound field's state. */\n private readonly formField = inject(FormField);\n private readonly fieldContext = injectFieldRootContext();\n\n constructor() {\n // The accessors are evaluated lazily by Field's `*State` computeds during change detection (after\n // the `[formField]` binding resolves), so reading `state()` inside these closures is safe. The\n // adapter reports authoritative *actual* state; the Field gates the *display* by its validationMode.\n const state: RdxFieldState = {\n invalid: () => this.state().invalid(),\n disabled: () => this.state().disabled(),\n required: () => this.state().required(),\n dirty: () => this.state().dirty(),\n touched: () => this.state().touched(),\n errors: () =>\n this.state()\n .errors()\n .map((error) => ({ kind: error.kind, message: error.message }))\n };\n\n const previous = this.fieldContext.setStateProvider(state);\n // Identity-checked teardown: only roll back if our provider is still active, so a newer adapter\n // mounted during a view swap (create-before-destroy) is not clobbered by this destroy.\n inject(DestroyRef).onDestroy(() => this.fieldContext.clearStateProvider(state, previous));\n }\n\n /** Current Signal Forms field state, read from the co-located `[formField]` directive. */\n private state() {\n return this.formField.state();\n }\n}\n","import { DestroyRef, Directive, inject, input } from '@angular/core';\nimport type { FieldTree } from '@angular/forms/signals';\nimport { injectFormRootContext, RdxFormState } from '@radix-ng/primitives/form';\n\n/** A Signal Forms subfield read structurally — callable to its state (`errors()` / `touched()` / `dirty()`). */\ntype NamedField = () => {\n errors: () => readonly { kind: string; message?: string }[];\n touched: () => boolean;\n dirty: () => boolean;\n};\n\n/**\n * Bridges an Angular **Signal Forms** form into an enclosing `form[rdxFormRoot]`.\n *\n * ```html\n * <form rdxFormRoot [rdxSignalForm]=\"loginForm\">\n * <!-- fields bound with [formField] (+ rdxSignalField) -->\n * </form>\n * ```\n *\n * Registers an {@link RdxFormState} provider so the Form's aggregate `data-invalid` / `data-dirty` /\n * `data-touched` / `data-submitting` attributes and the submit guard read authoritative Signal Forms\n * state. This adapter owns only client-side state and `name`-routing; server errors stay a separate\n * eager channel applied through `rdxFormRoot[errors]`, and Signal Forms' own `submit()` owns the\n * submit lifecycle.\n *\n * `errorsFor(name)` routes a field's errors to a `rdxFieldRoot` by its `name`, walking the `FieldTree`\n * so dotted paths into nested object/array fields resolve too (`address.street`, `items.0.name`). A\n * field can surface messages from the form alone — no per-field `rdxSignalField` needed for errors.\n * These are the **two modes** (per-field adapter vs form-level name routing) — prefer one per field; if\n * a field carries both, `rdxFieldError.messages()` deduplicates by text so the shared message is not\n * shown twice.\n *\n * See ADR 0018.\n *\n * @group Components\n */\n@Directive({\n selector: 'form[rdxFormRoot][rdxSignalForm]',\n exportAs: 'rdxSignalForm'\n})\nexport class RdxSignalForm {\n /** The Signal Forms root field (from `form(...)`) whose aggregate state drives the enclosing Form. */\n readonly form = input.required<FieldTree<unknown>>({ alias: 'rdxSignalForm' });\n\n private readonly formContext = injectFormRootContext();\n\n constructor() {\n const state: RdxFormState = {\n invalid: () => this.state().invalid(),\n dirty: () => this.state().dirty(),\n touched: () => this.state().touched(),\n submitting: () => this.state().submitting(),\n errorsFor: (name) => this.errorsFor(name),\n // Per-name interaction state so a name-routed field (bare `[formField]`, no `rdxSignalField`)\n // can reveal its error on blur/change under `validationMode=\"onBlur\"`/`\"onChange\"`.\n touchedFor: (name) => this.fieldState(name)?.touched() ?? false,\n dirtyFor: (name) => this.fieldState(name)?.dirty() ?? false\n };\n\n const previous = this.formContext.setStateProvider(state);\n // Identity-checked teardown: only roll back if our provider is still active, so a newer adapter\n // mounted during a view swap (create-before-destroy) is not clobbered by this destroy.\n inject(DestroyRef).onDestroy(() => this.formContext.clearStateProvider(state, previous));\n }\n\n /**\n * Messages for the field at the dotted `name` path (`message ?? kind` per error). Walks the\n * `FieldTree` so nested object/array fields resolve too — e.g. `address.street`, `items.0.name`.\n */\n private errorsFor(name: string): string[] {\n return (\n this.fieldState(name)\n ?.errors()\n .map((error) => error.message ?? error.kind) ?? []\n );\n }\n\n /**\n * The Signal Forms field *state* at the dotted `name` path, or `null` if it doesn't resolve. Walks the\n * `FieldTree` so nested object/array fields work (`address.street`, `items.0.name`).\n */\n private fieldState(name: string): ReturnType<NamedField> | null {\n let node: unknown = this.form();\n for (const segment of name.split('.')) {\n if (node == null || (typeof node !== 'object' && typeof node !== 'function')) {\n return null;\n }\n // Only walk into own properties: a `FieldTree` exposes its subfields as own keys, so a\n // segment that is not one (`constructor`, `__proto__`, `toString`, …) is not a real field.\n // Reading it would resolve to an inherited member — and a function one would then be called\n // below — so reject it instead.\n if (!Object.hasOwn(node, segment)) {\n return null;\n }\n node = (node as Record<string, unknown>)[segment];\n }\n return typeof node === 'function' ? (node as NamedField)() : null;\n }\n\n /** The current Signal Forms root field state (a `FieldTree` is callable). */\n private state() {\n return this.form()();\n }\n}\n","import { NgModule } from '@angular/core';\nimport { RdxSignalField } from './src/signal-field';\nimport { RdxSignalForm } from './src/signal-form';\n\nexport * from './src/signal-field';\nexport * from './src/signal-form';\n\nexport const _importsSignalForms = [RdxSignalField, RdxSignalForm];\n\n@NgModule({\n imports: [..._importsSignalForms],\n exports: [..._importsSignalForms]\n})\nexport class RdxSignalFormsModule {}\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './index';\n"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"radix-ng-primitives-signal-forms.mjs","sources":["../../../packages/primitives/signal-forms/src/signal-field.ts","../../../packages/primitives/signal-forms/src/signal-form.ts","../../../packages/primitives/signal-forms/index.ts","../../../packages/primitives/signal-forms/radix-ng-primitives-signal-forms.ts"],"sourcesContent":["import { DestroyRef, Directive, inject } from '@angular/core';\nimport { FormField } from '@angular/forms/signals';\nimport { injectFieldRootContext, RdxFieldState } from '@radix-ng/primitives/field';\n\n/**\n * Bridges an Angular **Signal Forms** field into an enclosing `rdxFieldRoot` — with **no duplicate\n * binding**. Place it on the control that already carries `[formField]`; it reads the bound field's\n * state from that directive, so the field expression is written exactly once:\n *\n * ```html\n * <div rdxFieldRoot>\n * <label rdxFieldLabel>Email</label>\n * <input rdxInput [formField]=\"loginForm.email\" rdxSignalField />\n * <p rdxFieldError>Email is required.</p>\n * </div>\n * ```\n *\n * It owns no model and runs no validation — Signal Forms remains the source of truth. It only registers\n * an {@link RdxFieldState} provider on the ancestor Field context so the field's `invalid` / `disabled` /\n * `required` / `dirty` / `touched` data-attributes, tri-state pending validity, and the error *content*\n * (`rdxFieldError.messages()`) read authoritative Signal Forms state. `filled` / `focused` stay on\n * Field's DOM heuristic (partial ownership — the seam supports it).\n *\n * It reports the **actual** Signal Forms state only; the `Field` decides *when* to display it from its\n * `validationMode` (default `'onBlur'` — neutral until the field is touched or the form submitted). So an\n * empty required field is neutral on load with no manual `[invalid]`/`[touched]` wiring, and a pristine\n * submit reveals the errors (the `Form` records the submit attempt before checking validity and blocks).\n *\n * See ADR 0018.\n *\n * @group Components\n */\n@Directive({\n selector: '[formField][rdxSignalField]',\n exportAs: 'rdxSignalField'\n})\nexport class RdxSignalField {\n /** The co-located `[formField]` directive — the single source of the bound field's state. */\n private readonly formField = inject(FormField);\n private readonly fieldContext = injectFieldRootContext();\n\n constructor() {\n // The accessors are evaluated lazily by Field's `*State` computeds during change detection (after\n // the `[formField]` binding resolves), so reading `state()` inside these closures is safe. The\n // adapter reports authoritative *actual* state; the Field gates the *display* by its validationMode.\n const state: RdxFieldState = {\n invalid: () => this.state().invalid(),\n pending: () => this.state().pending(),\n disabled: () => this.state().disabled(),\n required: () => this.state().required(),\n dirty: () => this.state().dirty(),\n touched: () => this.state().touched(),\n errors: () =>\n this.state()\n .errors()\n .map((error) => ({ kind: error.kind, message: error.message }))\n };\n\n const previous = this.fieldContext.setStateProvider(state);\n // Identity-checked teardown: only roll back if our provider is still active, so a newer adapter\n // mounted during a view swap (create-before-destroy) is not clobbered by this destroy.\n inject(DestroyRef).onDestroy(() => this.fieldContext.clearStateProvider(state, previous));\n }\n\n /** Current Signal Forms field state, read from the co-located `[formField]` directive. */\n private state() {\n return this.formField.state();\n }\n}\n","import { booleanAttribute, DestroyRef, Directive, inject, input } from '@angular/core';\nimport { submit, type FieldTree } from '@angular/forms/signals';\nimport { BooleanInput } from '@radix-ng/primitives/core';\nimport { injectFormRootContext, RdxFormState } from '@radix-ng/primitives/form';\n\n/** A Signal Forms subfield read structurally — callable to its state (`errors()` / `touched()` / `dirty()`). */\ntype NamedField = () => {\n errors: () => readonly { kind: string; message?: string }[];\n touched: () => boolean;\n dirty: () => boolean;\n};\n\n/**\n * Bridges an Angular **Signal Forms** form into an enclosing `form[rdxFormRoot]`.\n *\n * ```html\n * <form rdxFormRoot [rdxSignalForm]=\"loginForm\">\n * <!-- fields bound with [formField] (+ rdxSignalField) -->\n * </form>\n * ```\n *\n * Registers an {@link RdxFormState} provider so the Form's aggregate `data-invalid` / `data-dirty` /\n * `data-touched` / `data-submitting` attributes and the submit guard read authoritative Signal Forms\n * state. By default this adapter owns only client-side state and `name`-routing; server errors stay a\n * separate eager channel applied through `rdxFormRoot[errors]`. Add `rdxSignalSubmit` to delegate native\n * submission to Signal Forms' own `submit()` lifecycle instead of `rdxFormRoot.onFormSubmit`:\n *\n * ```html\n * <form rdxFormRoot [rdxSignalForm]=\"loginForm\" rdxSignalSubmit>…</form>\n * ```\n *\n * `errorsFor(name)` routes a field's errors to a `rdxFieldRoot` by its `name`, walking the `FieldTree`\n * so dotted paths into nested object/array fields resolve too (`address.street`, `items.0.name`). A\n * field can surface messages from the form alone — no per-field `rdxSignalField` needed for errors.\n * These are the **two modes** (per-field adapter vs form-level name routing) — prefer one per field; if\n * a field carries both, `rdxFieldError.messages()` deduplicates by text so the shared message is not\n * shown twice.\n *\n * See ADR 0018 and ADR 0020.\n *\n * @group Components\n */\n@Directive({\n selector: 'form[rdxFormRoot][rdxSignalForm]',\n exportAs: 'rdxSignalForm'\n})\nexport class RdxSignalForm {\n /** The Signal Forms root field (from `form(...)`) whose aggregate state drives the enclosing Form. */\n readonly form = input.required<FieldTree<unknown>>({ alias: 'rdxSignalForm' });\n\n /**\n * Delegate native submission to Angular Signal Forms' `submit()` lifecycle. Opt-in so adding the\n * state adapter to an existing 1.x form cannot silently replace its `(onFormSubmit)` side effects.\n * The bound `form()` must define `submission.action`; Angular reports a descriptive error otherwise.\n *\n * @group Props\n * @defaultValue false\n */\n readonly signalSubmit = input<boolean, BooleanInput>(false, {\n alias: 'rdxSignalSubmit',\n transform: booleanAttribute\n });\n\n private readonly formContext = injectFormRootContext();\n\n constructor() {\n const state: RdxFormState = {\n invalid: () => this.state().invalid(),\n dirty: () => this.state().dirty(),\n touched: () => this.state().touched(),\n submitting: () => this.state().submitting(),\n submit: () => (this.signalSubmit() ? submit(this.form()) : undefined),\n errorsFor: (name) => this.errorsFor(name),\n // Per-name interaction state so a name-routed field (bare `[formField]`, no `rdxSignalField`)\n // can reveal its error on blur/change under `validationMode=\"onBlur\"`/`\"onChange\"`.\n touchedFor: (name) => this.fieldState(name)?.touched() ?? false,\n dirtyFor: (name) => this.fieldState(name)?.dirty() ?? false\n };\n\n const previous = this.formContext.setStateProvider(state);\n // Identity-checked teardown: only roll back if our provider is still active, so a newer adapter\n // mounted during a view swap (create-before-destroy) is not clobbered by this destroy.\n inject(DestroyRef).onDestroy(() => this.formContext.clearStateProvider(state, previous));\n }\n\n /**\n * Messages for the field at the dotted `name` path (`message ?? kind` per error). Walks the\n * `FieldTree` so nested object/array fields resolve too — e.g. `address.street`, `items.0.name`.\n */\n private errorsFor(name: string): string[] {\n return (\n this.fieldState(name)\n ?.errors()\n .map((error) => error.message ?? error.kind) ?? []\n );\n }\n\n /**\n * The Signal Forms field *state* at the dotted `name` path, or `null` if it doesn't resolve. Walks the\n * `FieldTree` so nested object/array fields work (`address.street`, `items.0.name`).\n */\n private fieldState(name: string): ReturnType<NamedField> | null {\n let node: unknown = this.form();\n for (const segment of name.split('.')) {\n if (node == null || (typeof node !== 'object' && typeof node !== 'function')) {\n return null;\n }\n // Only walk into own properties: a `FieldTree` exposes its subfields as own keys, so a\n // segment that is not one (`constructor`, `__proto__`, `toString`, …) is not a real field.\n // Reading it would resolve to an inherited member — and a function one would then be called\n // below — so reject it instead.\n if (!Object.hasOwn(node, segment)) {\n return null;\n }\n node = (node as Record<string, unknown>)[segment];\n }\n return typeof node === 'function' ? (node as NamedField)() : null;\n }\n\n /** The current Signal Forms root field state (a `FieldTree` is callable). */\n private state() {\n return this.form()();\n }\n}\n","import { NgModule } from '@angular/core';\nimport { RdxSignalField } from './src/signal-field';\nimport { RdxSignalForm } from './src/signal-form';\n\nexport * from './src/signal-field';\nexport * from './src/signal-form';\n\nexport const _importsSignalForms = [RdxSignalField, RdxSignalForm];\n\n@NgModule({\n imports: [..._importsSignalForms],\n exports: [..._importsSignalForms]\n})\nexport class RdxSignalFormsModule {}\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './index';\n"],"names":[],"mappings":"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"}
|
|
@@ -2,7 +2,7 @@ import * as i0 from '@angular/core';
|
|
|
2
2
|
import { inject, ElementRef, DestroyRef, Directive, computed, input, numberAttribute, booleanAttribute, model, output, signal, effect, afterNextRender, afterRenderEffect, untracked, NgModule } from '@angular/core';
|
|
3
3
|
import { DOCUMENT } from '@angular/common';
|
|
4
4
|
import * as i2 from '@radix-ng/primitives/core';
|
|
5
|
-
import { createContext, clamp, RdxFormUiControlBase, injectControlValueAccessor, injectDocument, injectId, createCancelableChangeEventDetails, provideFormUiState, RdxFormUiStateHost, RdxControlValueAccessor } from '@radix-ng/primitives/core';
|
|
5
|
+
import { createContext, clamp, RdxFormUiControlBase, injectControlValueAccessor, injectDocument, injectId, useNativeFormControl, createCancelableChangeEventDetails, provideFormUiState, RdxFormUiStateHost, RdxControlValueAccessor } from '@radix-ng/primitives/core';
|
|
6
6
|
export { clamp } from '@radix-ng/primitives/core';
|
|
7
7
|
import * as i1 from '@radix-ng/primitives/composite';
|
|
8
8
|
import { RdxCompositeList, RdxCompositeListItem } from '@radix-ng/primitives/composite';
|
|
@@ -787,7 +787,7 @@ class RdxSliderRoot extends RdxFormUiControlBase {
|
|
|
787
787
|
/** Locale used for value formatting. */
|
|
788
788
|
this.locale = input(/* @ts-ignore */
|
|
789
789
|
...(ngDevMode ? [undefined, { debugName: "locale" }] : /* istanbul ignore next */ []));
|
|
790
|
-
/** Name of the
|
|
790
|
+
/** Name of the native range input rendered by each thumb, for form submission. */
|
|
791
791
|
this.name = input(/* @ts-ignore */
|
|
792
792
|
...(ngDevMode ? [undefined, { debugName: "name" }] : /* istanbul ignore next */ []));
|
|
793
793
|
/** Id of the form the slider belongs to. */
|
|
@@ -837,6 +837,21 @@ class RdxSliderRoot extends RdxFormUiControlBase {
|
|
|
837
837
|
/** @ignore */
|
|
838
838
|
this.isDisabled = computed(() => !!this.cva.disabled(), /* @ts-ignore */
|
|
839
839
|
...(ngDevMode ? [{ debugName: "isDisabled" }] : /* istanbul ignore next */ []));
|
|
840
|
+
// Range thumbs already are native inputs and therefore serialize themselves. The shared layer
|
|
841
|
+
// owns only reset here, so the root model follows a native `<form>.reset()` as well.
|
|
842
|
+
this.nativeFormControl = useNativeFormControl({
|
|
843
|
+
name: this.name,
|
|
844
|
+
form: this.form,
|
|
845
|
+
disabled: this.isDisabled,
|
|
846
|
+
defaultValue: () => this.cva.value() ?? this.defaultValue() ?? this.min(),
|
|
847
|
+
onReset: (value) => {
|
|
848
|
+
this.value.set(value);
|
|
849
|
+
if (!this.resetNgControl(value)) {
|
|
850
|
+
this.cva.setValue(value);
|
|
851
|
+
}
|
|
852
|
+
this.formUi.resetInteractionState?.();
|
|
853
|
+
}
|
|
854
|
+
});
|
|
840
855
|
/** @ignore */
|
|
841
856
|
this.inset = computed(() => this.thumbAlignment() !== 'center', /* @ts-ignore */
|
|
842
857
|
...(ngDevMode ? [{ debugName: "inset" }] : /* istanbul ignore next */ []));
|