@radix-ng/primitives 1.0.6 → 1.0.8

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.
Files changed (83) hide show
  1. package/aspect-ratio/README.md +1 -1
  2. package/fesm2022/radix-ng-primitives-accordion.mjs +6 -1
  3. package/fesm2022/radix-ng-primitives-accordion.mjs.map +1 -1
  4. package/fesm2022/radix-ng-primitives-aspect-ratio.mjs +9 -34
  5. package/fesm2022/radix-ng-primitives-aspect-ratio.mjs.map +1 -1
  6. package/fesm2022/radix-ng-primitives-autocomplete.mjs +43 -9
  7. package/fesm2022/radix-ng-primitives-autocomplete.mjs.map +1 -1
  8. package/fesm2022/radix-ng-primitives-avatar.mjs +69 -18
  9. package/fesm2022/radix-ng-primitives-avatar.mjs.map +1 -1
  10. package/fesm2022/radix-ng-primitives-checkbox.mjs +93 -16
  11. package/fesm2022/radix-ng-primitives-checkbox.mjs.map +1 -1
  12. package/fesm2022/radix-ng-primitives-collapsible.mjs +4 -3
  13. package/fesm2022/radix-ng-primitives-collapsible.mjs.map +1 -1
  14. package/fesm2022/radix-ng-primitives-combobox.mjs +43 -9
  15. package/fesm2022/radix-ng-primitives-combobox.mjs.map +1 -1
  16. package/fesm2022/radix-ng-primitives-core.mjs +208 -2
  17. package/fesm2022/radix-ng-primitives-core.mjs.map +1 -1
  18. package/fesm2022/radix-ng-primitives-date-field.mjs +50 -9
  19. package/fesm2022/radix-ng-primitives-date-field.mjs.map +1 -1
  20. package/fesm2022/radix-ng-primitives-editable.mjs +31 -5
  21. package/fesm2022/radix-ng-primitives-editable.mjs.map +1 -1
  22. package/fesm2022/radix-ng-primitives-field.mjs +276 -58
  23. package/fesm2022/radix-ng-primitives-field.mjs.map +1 -1
  24. package/fesm2022/radix-ng-primitives-form.mjs +111 -27
  25. package/fesm2022/radix-ng-primitives-form.mjs.map +1 -1
  26. package/fesm2022/radix-ng-primitives-input.mjs +16 -6
  27. package/fesm2022/radix-ng-primitives-input.mjs.map +1 -1
  28. package/fesm2022/radix-ng-primitives-label.mjs +5 -4
  29. package/fesm2022/radix-ng-primitives-label.mjs.map +1 -1
  30. package/fesm2022/radix-ng-primitives-number-field.mjs +39 -10
  31. package/fesm2022/radix-ng-primitives-number-field.mjs.map +1 -1
  32. package/fesm2022/radix-ng-primitives-progress.mjs +37 -22
  33. package/fesm2022/radix-ng-primitives-progress.mjs.map +1 -1
  34. package/fesm2022/radix-ng-primitives-radio.mjs +18 -9
  35. package/fesm2022/radix-ng-primitives-radio.mjs.map +1 -1
  36. package/fesm2022/radix-ng-primitives-scroll-area.mjs +4 -4
  37. package/fesm2022/radix-ng-primitives-scroll-area.mjs.map +1 -1
  38. package/fesm2022/radix-ng-primitives-select.mjs +26 -8
  39. package/fesm2022/radix-ng-primitives-select.mjs.map +1 -1
  40. package/fesm2022/radix-ng-primitives-separator.mjs +7 -13
  41. package/fesm2022/radix-ng-primitives-separator.mjs.map +1 -1
  42. package/fesm2022/radix-ng-primitives-signal-forms.mjs +184 -0
  43. package/fesm2022/radix-ng-primitives-signal-forms.mjs.map +1 -0
  44. package/fesm2022/radix-ng-primitives-slider.mjs +25 -10
  45. package/fesm2022/radix-ng-primitives-slider.mjs.map +1 -1
  46. package/fesm2022/radix-ng-primitives-switch.mjs +32 -8
  47. package/fesm2022/radix-ng-primitives-switch.mjs.map +1 -1
  48. package/fesm2022/radix-ng-primitives-tabs.mjs +4 -4
  49. package/fesm2022/radix-ng-primitives-tabs.mjs.map +1 -1
  50. package/fesm2022/radix-ng-primitives-time-field.mjs +49 -9
  51. package/fesm2022/radix-ng-primitives-time-field.mjs.map +1 -1
  52. package/fesm2022/radix-ng-primitives-toggle-group.mjs +33 -16
  53. package/fesm2022/radix-ng-primitives-toggle-group.mjs.map +1 -1
  54. package/fesm2022/radix-ng-primitives-toggle.mjs +24 -29
  55. package/fesm2022/radix-ng-primitives-toggle.mjs.map +1 -1
  56. package/fesm2022/radix-ng-primitives-toolbar.mjs +15 -2
  57. package/fesm2022/radix-ng-primitives-toolbar.mjs.map +1 -1
  58. package/package.json +11 -1
  59. package/types/radix-ng-primitives-accordion.d.ts +1 -0
  60. package/types/radix-ng-primitives-aspect-ratio.d.ts +10 -23
  61. package/types/radix-ng-primitives-autocomplete.d.ts +21 -2
  62. package/types/radix-ng-primitives-avatar.d.ts +51 -25
  63. package/types/radix-ng-primitives-checkbox.d.ts +78 -101
  64. package/types/radix-ng-primitives-combobox.d.ts +51 -2
  65. package/types/radix-ng-primitives-core.d.ts +206 -3
  66. package/types/radix-ng-primitives-date-field.d.ts +27 -2
  67. package/types/radix-ng-primitives-editable.d.ts +15 -2
  68. package/types/radix-ng-primitives-field.d.ts +165 -236
  69. package/types/radix-ng-primitives-form.d.ts +122 -37
  70. package/types/radix-ng-primitives-input.d.ts +8 -1
  71. package/types/radix-ng-primitives-label.d.ts +3 -2
  72. package/types/radix-ng-primitives-number-field.d.ts +15 -4
  73. package/types/radix-ng-primitives-progress.d.ts +59 -121
  74. package/types/radix-ng-primitives-radio.d.ts +7 -3
  75. package/types/radix-ng-primitives-select.d.ts +11 -3
  76. package/types/radix-ng-primitives-separator.d.ts +0 -7
  77. package/types/radix-ng-primitives-signal-forms.d.ts +97 -0
  78. package/types/radix-ng-primitives-slider.d.ts +9 -7
  79. package/types/radix-ng-primitives-switch.d.ts +15 -2
  80. package/types/radix-ng-primitives-time-field.d.ts +26 -2
  81. package/types/radix-ng-primitives-toggle-group.d.ts +13 -7
  82. package/types/radix-ng-primitives-toggle.d.ts +8 -8
  83. package/types/radix-ng-primitives-toolbar.d.ts +2 -0
@@ -1 +1 @@
1
- {"version":3,"file":"radix-ng-primitives-field.mjs","sources":["../../../packages/primitives/field/src/field-root.ts","../../../packages/primitives/field/src/field-control.ts","../../../packages/primitives/field/src/field-description.ts","../../../packages/primitives/field/src/field-error.ts","../../../packages/primitives/field/src/field-label.ts","../../../packages/primitives/field/radix-ng-primitives-field.ts"],"sourcesContent":["import { booleanAttribute, computed, DestroyRef, Directive, ElementRef, inject, input, signal } from '@angular/core';\nimport { BooleanInput, createContext, RdxValidationError } from '@radix-ng/primitives/core';\nimport { injectFormRootContext, RdxFormFieldRegistration } from '@radix-ng/primitives/form';\n\nlet fieldId = 0;\n\nconst attr = (value: boolean) => (value ? '' : undefined);\n\n/**\n * External owner of field state. An adapter (e.g. a future Signal Forms\n * `[rdxSignalField]` directive, or a Reactive Forms bridge) registers one via\n * `setStateProvider` so Field reads authoritative form state instead of\n * self-computing it from the DOM. Each member is an optional signal-like\n * accessor; only the states the adapter owns need to be provided — the rest\n * fall back to the root's inputs / DOM heuristic. Keeping these as plain\n * `() => boolean` accessors keeps Field framework-agnostic (no dependency on\n * `@angular/forms/signals`).\n *\n * See ADR 0004 and `signal-forms-readiness.md` (prep #4).\n */\nexport interface RdxFieldState {\n invalid?: () => boolean;\n disabled?: () => boolean;\n required?: () => boolean;\n dirty?: () => boolean;\n touched?: () => boolean;\n filled?: () => boolean;\n focused?: () => boolean;\n /**\n * Optional source of error *content* (not just the invalid boolean). When provided and non-empty\n * it forces `invalidState` true, and its messages (`message ?? kind` per error) surface through\n * `RdxFieldError.messages()` ahead of any enclosing Form's external messages. Uses `core`'s\n * framework-free shim type so the seam stays free of `@angular/forms/signals` (ADR 0004 amendment).\n */\n errors?: () => RdxValidationError[];\n}\n\nconst addId = (ids: string[], id: string) => (ids.includes(id) ? ids : [...ids, id]);\nconst removeId = (ids: string[], id: string) => ids.filter((item) => item !== id);\n\nconst fieldRootContext = () => {\n const root = injectFieldRoot();\n\n return {\n controlId: root.controlId,\n name: root.name,\n descriptionIds: root.descriptionIds,\n errorIds: root.errorIds,\n /** Combined external messages (state provider's, then enclosing Form's), for `RdxFieldError`. */\n messages: root.messages,\n /** Notify an enclosing Form that this field's control was edited (composite-control opt-in). */\n notifyEdited: () => root.notifyEdited(),\n invalidState: root.invalidState,\n disabledState: root.disabledState,\n requiredState: root.requiredState,\n dirtyState: root.dirtyState,\n touchedState: root.touchedState,\n filledState: root.filledState,\n focusedState: root.focusedState,\n setControlId: (id: string) => root.controlId.set(id),\n addDescriptionId: (id: string) => root.descriptionIds.update((ids) => addId(ids, id)),\n removeDescriptionId: (id: string) => root.descriptionIds.update((ids) => removeId(ids, id)),\n addErrorId: (id: string) => root.errorIds.update((ids) => addId(ids, id)),\n removeErrorId: (id: string) => root.errorIds.update((ids) => removeId(ids, id)),\n setFocused: (value: boolean) => root.focusedValue.set(value),\n setFilled: (value: boolean) => root.filledValue.set(value),\n setDirty: (value: boolean) => root.dirtyValue.set(value),\n setTouched: (value: boolean) => root.touchedValue.set(value),\n /**\n * Register (or clear with `null`) an external owner of field state.\n * While a provider is registered, any state it exposes takes precedence\n * over the root inputs and the DOM-derived values. Returns the previous\n * provider so adapters can restore it on teardown.\n */\n setStateProvider: (provider: RdxFieldState | null) => root.setStateProvider(provider),\n hasStateProvider: root.hasStateProvider\n };\n};\n\nexport type RdxFieldRootContext = ReturnType<typeof fieldRootContext>;\n\nexport const [injectFieldRootContext, provideFieldRootContext] = createContext<RdxFieldRootContext>(\n 'RdxFieldRoot',\n 'components/field'\n);\n\n/**\n * Groups a form control with its label, description, error message, and field state.\n *\n * @group Components\n */\n@Directive({\n selector: '[rdxFieldRoot]',\n exportAs: 'rdxFieldRoot',\n providers: [provideFieldRootContext(fieldRootContext)],\n host: {\n '[attr.data-invalid]': 'dataAttr(invalidState())',\n '[attr.data-valid]': 'dataAttr(!invalidState())',\n '[attr.data-disabled]': 'dataAttr(disabledState())',\n '[attr.data-required]': 'dataAttr(requiredState())',\n '[attr.data-dirty]': 'dataAttr(dirtyState())',\n '[attr.data-touched]': 'dataAttr(touchedState())',\n '[attr.data-filled]': 'dataAttr(filledState())',\n '[attr.data-focused]': 'dataAttr(focusedState())',\n '(input)': 'notifyEdited()',\n '(change)': 'notifyEdited()'\n }\n})\nexport class RdxFieldRoot {\n /**\n * Whether the field is invalid.\n *\n * @group Props\n * @defaultValue false\n */\n readonly invalid = input<boolean, BooleanInput>(false, { transform: booleanAttribute });\n\n /**\n * Whether the field is disabled.\n *\n * @group Props\n * @defaultValue false\n */\n readonly disabled = input<boolean, BooleanInput>(false, { transform: booleanAttribute });\n\n /**\n * Whether the field is required.\n *\n * @group Props\n * @defaultValue false\n */\n readonly required = input<boolean, BooleanInput>(false, { transform: booleanAttribute });\n\n /**\n * Whether the field value has changed from its initial value.\n *\n * @group Props\n * @defaultValue false\n */\n readonly dirty = input<boolean, BooleanInput>(false, { transform: booleanAttribute });\n\n /**\n * Whether the field has been blurred after receiving focus.\n *\n * @group Props\n * @defaultValue false\n */\n readonly touched = input<boolean, BooleanInput>(false, { transform: booleanAttribute });\n\n /**\n * Overrides whether the control has a non-empty value.\n *\n * @group Props\n */\n readonly filled = input<boolean>();\n\n /**\n * Overrides whether the control is focused.\n *\n * @group Props\n */\n readonly focused = input<boolean>();\n\n /**\n * Identifies the field to an enclosing Form for external (server) error matching. Fields without a\n * `name` never match external errors.\n *\n * @group Props\n */\n readonly name = input<string>();\n\n /** The enclosing Form, if any. All Form-related behavior is a no-op when this is `null`. */\n private readonly formContext = injectFormRootContext(true);\n\n readonly controlId = signal(`rdx-field-control-${fieldId++}`);\n readonly descriptionIds = signal<string[]>([]);\n readonly errorIds = signal<string[]>([]);\n\n readonly focusedValue = signal(false);\n readonly filledValue = signal(false);\n readonly dirtyValue = signal(false);\n readonly touchedValue = signal(false);\n\n /** External state owner registered through the context; `null` when Field self-computes. */\n private readonly stateProvider = signal<RdxFieldState | null>(null);\n\n /** Whether an external adapter currently owns field state. */\n readonly hasStateProvider = computed(() => this.stateProvider() !== null);\n\n /** Error content from a registered state provider (e.g. a Signal Forms adapter). */\n private readonly providerErrors = computed(() => this.stateProvider()?.errors?.() ?? []);\n\n /** External messages from the enclosing Form matched by this field's `name`. */\n readonly externalErrors = computed(() => this.formContext?.errorsFor(this.name()) ?? []);\n\n /** Provider messages first (`message ?? kind`), then the Form's external messages. */\n readonly messages = computed(() => [\n ...this.providerErrors().map((error) => error.message ?? error.kind),\n ...this.externalErrors()\n ]);\n\n // External errors (provider content or Form server errors) force invalid regardless of the input or\n // a provider's `invalid` accessor — a server error must show even when client-side validity passes.\n readonly invalidState = computed(() => {\n if (this.externalErrors().length > 0 || this.providerErrors().length > 0) {\n return true;\n }\n return this.resolve('invalid', () => this.invalid());\n });\n readonly disabledState = computed(() => this.resolve('disabled', () => this.disabled()));\n readonly requiredState = computed(() => this.resolve('required', () => this.required()));\n readonly dirtyState = computed(() => this.resolve('dirty', () => this.dirty() || this.dirtyValue()));\n readonly touchedState = computed(() => this.resolve('touched', () => this.touched() || this.touchedValue()));\n readonly filledState = computed(() => this.resolve('filled', () => this.filled() ?? this.filledValue()));\n readonly focusedState = computed(() => this.resolve('focused', () => this.focused() ?? this.focusedValue()));\n\n protected readonly dataAttr = attr;\n\n constructor() {\n // Register with an enclosing Form (if any) for aggregate state, submit guard, and reset; a\n // standalone field never enters this branch and behaves exactly as before.\n const formContext = this.formContext;\n if (formContext) {\n const registration: RdxFormFieldRegistration = {\n name: () => this.name(),\n invalid: () => this.invalidState(),\n dirty: () => this.dirtyState(),\n touched: () => this.touchedState(),\n focus: () => this.focusControl(),\n resetState: () => this.resetState()\n };\n const unregister = formContext.register(registration);\n inject(DestroyRef).onDestroy(unregister);\n }\n }\n\n /** Notify the enclosing Form (if any) that this field's control was edited (clear-on-edit). */\n notifyEdited(): void {\n this.formContext?.notifyEdited(this.name());\n }\n\n /** Reset interaction state on native form reset: touched/dirty/focused → false, filled re-synced. */\n resetState(): void {\n this.touchedValue.set(false);\n this.dirtyValue.set(false);\n this.focusedValue.set(false);\n const control = this.controlElement();\n const value = control?.value ?? '';\n this.filledValue.set(value != null && value !== '');\n }\n\n /** Focus the field's control (used by the Form's first-invalid-focus on blocked submit). */\n private focusControl(): void {\n this.controlElement()?.focus();\n }\n\n private readonly host = inject<ElementRef<HTMLElement>>(ElementRef).nativeElement;\n\n /**\n * The field's control element, found by `controlId` but scoped to this field's own subtree — a\n * duplicate or consumer-reused id elsewhere on the page can't steal focus/reset. The control\n * registers its id through `setControlId`, so this matches the same element the labels point at.\n */\n private controlElement(): HTMLInputElement | null {\n return this.host.querySelector<HTMLInputElement>(`[id=\"${this.controlId()}\"]`);\n }\n\n /**\n * Register an external owner of field state, returning the previous one.\n * @ignore\n */\n setStateProvider(provider: RdxFieldState | null): RdxFieldState | null {\n const previous = this.stateProvider();\n this.stateProvider.set(provider);\n return previous;\n }\n\n /**\n * Prefer the registered provider's value for `key` when it exposes one,\n * otherwise fall back to the root inputs / DOM-derived signals.\n */\n private resolve(key: Exclude<keyof RdxFieldState, 'errors'>, fallback: () => boolean): boolean {\n const accessor = this.stateProvider()?.[key];\n return accessor ? accessor() : fallback();\n }\n}\n\nfunction injectFieldRoot(): RdxFieldRoot {\n return inject(RdxFieldRoot);\n}\n","import { afterNextRender, computed, Directive, effect, ElementRef, inject, input } from '@angular/core';\nimport { injectFieldRootContext } from './field-root';\n\nlet controlId = 0;\n\nconst attr = (value: boolean) => (value ? '' : undefined);\n\n/**\n * Connects a form control to the field label, description, error, and state.\n *\n * @group Components\n */\n@Directive({\n selector: '[rdxFieldControl]',\n exportAs: 'rdxFieldControl',\n host: {\n '[attr.id]': 'id()',\n '[attr.aria-describedby]': 'describedBy()',\n '[attr.aria-invalid]': 'rootContext.invalidState() ? \"true\" : undefined',\n '[attr.aria-required]': 'rootContext.requiredState() ? \"true\" : undefined',\n '[attr.aria-disabled]': 'rootContext.disabledState() ? \"true\" : undefined',\n '[attr.disabled]': 'isNativeFormControl() && rootContext.disabledState() ? \"\" : undefined',\n '[attr.required]': 'isNativeFormControl() && rootContext.requiredState() ? \"\" : undefined',\n '[attr.data-invalid]': 'dataAttr(rootContext.invalidState())',\n '[attr.data-valid]': 'dataAttr(!rootContext.invalidState())',\n '[attr.data-disabled]': 'dataAttr(rootContext.disabledState())',\n '[attr.data-required]': 'dataAttr(rootContext.requiredState())',\n '[attr.data-filled]': 'dataAttr(rootContext.filledState())',\n '[attr.data-focused]': 'dataAttr(rootContext.focusedState())',\n '(focus)': 'onFocus()',\n '(blur)': 'onBlur()',\n '(input)': 'syncFilled()',\n '(change)': 'syncFilled()'\n }\n})\nexport class RdxFieldControl {\n protected readonly rootContext = injectFieldRootContext();\n private readonly elementRef = inject<ElementRef<HTMLElement>>(ElementRef);\n private initialValue = '';\n\n /**\n * Control id. Labels and descriptions use this value for accessible relationships.\n *\n * @group Props\n */\n readonly id = input(`rdx-field-control-${controlId++}`);\n\n protected readonly describedBy = computed(() => {\n const ids = [\n ...this.rootContext.descriptionIds(),\n ...(this.rootContext.invalidState() ? this.rootContext.errorIds() : [])\n ];\n\n return ids.length ? ids.join(' ') : undefined;\n });\n\n constructor() {\n effect(() => {\n this.rootContext.setControlId(this.id());\n });\n\n afterNextRender(() => {\n this.initialValue = this.currentValue();\n this.syncFilled();\n });\n }\n\n onFocus(): void {\n this.rootContext.setFocused(true);\n }\n\n onBlur(): void {\n this.rootContext.setFocused(false);\n this.rootContext.setTouched(true);\n }\n\n syncFilled(): void {\n const value = this.currentValue();\n\n this.rootContext.setFilled(Array.isArray(value) ? value.length > 0 : value != null && value !== '');\n this.rootContext.setDirty(value !== this.initialValue);\n }\n\n protected isNativeFormControl(): boolean {\n return ['INPUT', 'SELECT', 'TEXTAREA', 'BUTTON'].includes(this.elementRef.nativeElement.tagName);\n }\n\n protected readonly dataAttr = attr;\n\n private currentValue(): string {\n const element = this.elementRef.nativeElement as HTMLInputElement | HTMLTextAreaElement | HTMLSelectElement;\n return element.value ?? '';\n }\n}\n","import { Directive, effect, input } from '@angular/core';\nimport { injectFieldRootContext } from './field-root';\n\nlet descriptionId = 0;\n\nconst attr = (value: boolean) => (value ? '' : undefined);\n\n/**\n * Describes the field control.\n *\n * @group Components\n */\n@Directive({\n selector: '[rdxFieldDescription]',\n exportAs: 'rdxFieldDescription',\n host: {\n '[attr.id]': 'id()',\n '[attr.data-invalid]': 'dataAttr(rootContext.invalidState())',\n '[attr.data-disabled]': 'dataAttr(rootContext.disabledState())'\n }\n})\nexport class RdxFieldDescription {\n protected readonly rootContext = injectFieldRootContext();\n\n /**\n * Description id.\n *\n * @group Props\n */\n readonly id = input(`rdx-field-description-${descriptionId++}`);\n\n constructor() {\n effect((onCleanup) => {\n const id = this.id();\n this.rootContext.addDescriptionId(id);\n onCleanup(() => this.rootContext.removeDescriptionId(id));\n });\n }\n\n protected readonly dataAttr = attr;\n}\n","import { Directive, effect, input } from '@angular/core';\nimport { injectFieldRootContext } from './field-root';\n\nlet errorId = 0;\n\nconst attr = (value: boolean) => (value ? '' : undefined);\n\n/**\n * Describes an invalid field control.\n *\n * @group Components\n */\n@Directive({\n selector: '[rdxFieldError]',\n exportAs: 'rdxFieldError',\n host: {\n '[attr.id]': 'id()',\n '[attr.hidden]': 'rootContext.invalidState() ? undefined : \"\"',\n '[attr.aria-live]': '\"polite\"',\n '[attr.data-invalid]': 'dataAttr(rootContext.invalidState())',\n '[attr.data-disabled]': 'dataAttr(rootContext.disabledState())'\n }\n})\nexport class RdxFieldError {\n protected readonly rootContext = injectFieldRootContext();\n\n /**\n * Error message id.\n *\n * @group Props\n */\n readonly id = input(`rdx-field-error-${errorId++}`);\n\n /**\n * The field's external messages (state provider's, then enclosing Form's), `[]` when none. Render\n * them explicitly via the `exportAs` reference — the directive never injects text content itself:\n * `<p rdxFieldError #err=\"rdxFieldError\">{{ err.messages().join(' ') }}</p>`.\n */\n readonly messages = this.rootContext.messages;\n\n constructor() {\n effect((onCleanup) => {\n const id = this.id();\n this.rootContext.addErrorId(id);\n onCleanup(() => this.rootContext.removeErrorId(id));\n });\n }\n\n protected readonly dataAttr = attr;\n}\n","import { Directive, input } from '@angular/core';\nimport { rdxCheckLabelElement } from '@radix-ng/primitives/core';\nimport { injectFieldRootContext } from './field-root';\n\nlet labelId = 0;\n\nconst attr = (value: boolean) => (value ? '' : undefined);\n\n/**\n * Labels the field control.\n *\n * @group Components\n */\n@Directive({\n selector: '[rdxFieldLabel]',\n exportAs: 'rdxFieldLabel',\n host: {\n '[attr.id]': 'id()',\n '[attr.for]': 'htmlFor()',\n '[attr.data-invalid]': 'dataAttr(rootContext.invalidState())',\n '[attr.data-disabled]': 'dataAttr(rootContext.disabledState())',\n '[attr.data-required]': 'dataAttr(rootContext.requiredState())'\n }\n})\nexport class RdxFieldLabel {\n protected readonly rootContext = injectFieldRootContext();\n\n /**\n * Label id.\n *\n * @group Props\n */\n readonly id = input(`rdx-field-label-${labelId++}`);\n\n readonly htmlFor = () => this.rootContext.controlId();\n\n constructor() {\n rdxCheckLabelElement('rdxFieldLabel', 'field/unassociated-label', 'components/field');\n }\n\n protected readonly dataAttr = attr;\n}\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './index';\n"],"names":["attr"],"mappings":"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"}
1
+ {"version":3,"file":"radix-ng-primitives-field.mjs","sources":["../../../packages/primitives/field/src/field-root.ts","../../../packages/primitives/field/src/field-control.ts","../../../packages/primitives/field/src/field-description.ts","../../../packages/primitives/field/src/field-error.ts","../../../packages/primitives/field/src/field-item.ts","../../../packages/primitives/field/src/field-label.ts","../../../packages/primitives/field/radix-ng-primitives-field.ts"],"sourcesContent":["import {\n booleanAttribute,\n computed,\n DestroyRef,\n Directive,\n ElementRef,\n inject,\n input,\n signal,\n Signal\n} from '@angular/core';\nimport {\n BooleanInput,\n createContext,\n injectId,\n isValidationRevealed,\n RDX_DEFAULT_VALIDATION_MODE,\n RDX_FIELD_VALIDITY,\n RdxValidationError,\n RdxValidationMode\n} from '@radix-ng/primitives/core';\nimport { injectFormRootContext, RdxFormFieldRegistration } from '@radix-ng/primitives/form';\n\nconst attr = (value: boolean) => (value ? '' : undefined);\n\n/**\n * External owner of field state. An adapter (e.g. a future Signal Forms\n * `[rdxSignalField]` directive, or a Reactive Forms bridge) registers one via\n * `setStateProvider` so Field reads authoritative form state instead of\n * self-computing it from the DOM. Each member is an optional signal-like\n * accessor; only the states the adapter owns need to be provided — the rest\n * fall back to the root's inputs / DOM heuristic. Keeping these as plain\n * `() => boolean` accessors keeps Field framework-agnostic (no dependency on\n * `@angular/forms/signals`).\n *\n * See ADR 0004 and `signal-forms-readiness.md` (prep #4).\n */\nexport interface RdxFieldState {\n /**\n * The control's **actual** invalidity (ungated). The Field decides *when* to display it from its\n * `validationMode` (e.g. only after blur) — the adapter just reports the real state. A non-empty\n * `errors()` also counts as invalid.\n */\n invalid?: () => boolean;\n disabled?: () => boolean;\n required?: () => boolean;\n dirty?: () => boolean;\n touched?: () => boolean;\n filled?: () => boolean;\n focused?: () => boolean;\n /**\n * Optional source of error *content* (not just the invalid boolean). A non-empty list marks the field\n * **actually** invalid (client validation) and its messages (`message ?? kind` per error) surface\n * through `RdxFieldError.messages()` once the field's `validationMode` reveals client validity, ahead of\n * any enclosing Form's server messages. Uses `core`'s framework-free shim type so the seam stays free of\n * `@angular/forms/signals` (ADR 0004 amendment).\n */\n errors?: () => RdxValidationError[];\n}\n\nconst addId = (ids: string[], id: string) => (ids.includes(id) ? ids : [...ids, id]);\nconst removeId = (ids: string[], id: string) => ids.filter((item) => item !== id);\n\nexport interface RdxFieldRootContext {\n controlId: Signal<string>;\n name: Signal<string | undefined>;\n descriptionIds: Signal<string[]>;\n errorIds: Signal<string[]>;\n messages: Signal<string[]>;\n notifyEdited: () => void;\n /** Tri-state *displayed* validity (`true` valid / `false` invalid / `null` neutral), gated by the\n * field's `validationMode`. The source for `data-valid` / `data-invalid` on the field and its controls. */\n validState: Signal<boolean | null>;\n /** Whether the enclosing Form has had a submit attempted (always `false` with no Form). */\n formSubmitAttempted: Signal<boolean>;\n invalidState: Signal<boolean>;\n disabledState: Signal<boolean>;\n requiredState: Signal<boolean>;\n dirtyState: Signal<boolean>;\n touchedState: Signal<boolean>;\n filledState: Signal<boolean>;\n focusedState: Signal<boolean>;\n setControlId: (id: string) => void;\n addDescriptionId: (id: string) => void;\n removeDescriptionId: (id: string) => void;\n addErrorId: (id: string) => void;\n removeErrorId: (id: string) => void;\n setFocused: (value: boolean) => void;\n setFilled: (value: boolean) => void;\n setDirty: (value: boolean) => void;\n setTouched: (value: boolean) => void;\n setStateProvider: (provider: RdxFieldState | null) => RdxFieldState | null;\n /**\n * Identity-checked teardown: roll the slot back to `previous` only if `provider` is still the\n * active one. A newer adapter that registered after `provider` (create-before-destroy during a\n * view swap) owns the slot and must not be clobbered by the old adapter's destroy.\n */\n clearStateProvider: (provider: RdxFieldState | null, previous: RdxFieldState | null) => void;\n hasStateProvider: Signal<boolean>;\n}\n\nconst fieldRootContext = (): RdxFieldRootContext => {\n const root = injectFieldRoot();\n\n return {\n controlId: root.controlId,\n name: root.name,\n descriptionIds: root.descriptionIds,\n errorIds: root.errorIds,\n /** Combined messages for `RdxFieldError`: client (provider + form name-routing, when revealed) then\n * server (`errors` input, always). */\n messages: root.messages,\n /** Notify an enclosing Form that this field's control was edited (composite-control opt-in). */\n notifyEdited: () => root.notifyEdited(),\n validState: root.validState,\n formSubmitAttempted: root.formSubmitAttempted,\n invalidState: root.invalidState,\n disabledState: root.disabledState,\n requiredState: root.requiredState,\n dirtyState: root.dirtyState,\n touchedState: root.touchedState,\n filledState: root.filledState,\n focusedState: root.focusedState,\n setControlId: (id: string) => root.controlId.set(id),\n addDescriptionId: (id: string) => root.descriptionIds.update((ids) => addId(ids, id)),\n removeDescriptionId: (id: string) => root.descriptionIds.update((ids) => removeId(ids, id)),\n addErrorId: (id: string) => root.errorIds.update((ids) => addId(ids, id)),\n removeErrorId: (id: string) => root.errorIds.update((ids) => removeId(ids, id)),\n setFocused: (value: boolean) => root.focusedValue.set(value),\n setFilled: (value: boolean) => root.filledValue.set(value),\n setDirty: (value: boolean) => root.dirtyValue.set(value),\n setTouched: (value: boolean) => root.touchedValue.set(value),\n /**\n * Register (or clear with `null`) an external owner of field state.\n * While a provider is registered, any state it exposes takes precedence\n * over the root inputs and the DOM-derived values. Returns the previous\n * provider so adapters can restore it on teardown.\n */\n setStateProvider: (provider: RdxFieldState | null) => root.setStateProvider(provider),\n clearStateProvider: (provider: RdxFieldState | null, previous: RdxFieldState | null) =>\n root.clearStateProvider(provider, previous),\n hasStateProvider: root.hasStateProvider\n };\n};\n\nexport const [injectFieldRootContext, provideFieldRootContext] = createContext<RdxFieldRootContext>(\n 'RdxFieldRoot',\n 'components/field'\n);\n\n/**\n * Groups a form control with its label, description, error message, and field state.\n *\n * @group Components\n */\n@Directive({\n selector: '[rdxFieldRoot]',\n exportAs: 'rdxFieldRoot',\n providers: [\n provideFieldRootContext(fieldRootContext),\n // Expose the tri-state display validity so controls inside the field reflect it (single source).\n { provide: RDX_FIELD_VALIDITY, useFactory: () => inject(RdxFieldRoot).validState }\n ],\n host: {\n // Tri-state: `data-invalid` when displayed-invalid, `data-valid` only when displayed-valid,\n // and **neither** when neutral (`validState()` is `null`).\n '[attr.data-invalid]': 'dataAttr(validState() === false)',\n '[attr.data-valid]': 'dataAttr(validState() === true)',\n '[attr.data-disabled]': 'dataAttr(disabledState())',\n '[attr.data-required]': 'dataAttr(requiredState())',\n '[attr.data-dirty]': 'dataAttr(dirtyState())',\n '[attr.data-touched]': 'dataAttr(touchedState())',\n '[attr.data-filled]': 'dataAttr(filledState())',\n '[attr.data-focused]': 'dataAttr(focusedState())',\n '(input)': 'notifyEdited()',\n '(change)': 'notifyEdited()'\n }\n})\nexport class RdxFieldRoot {\n /**\n * Whether the field is invalid.\n *\n * @group Props\n * @defaultValue false\n */\n readonly invalid = input<boolean, BooleanInput>(false, { transform: booleanAttribute });\n\n /**\n * Whether the field is disabled.\n *\n * @group Props\n * @defaultValue false\n */\n readonly disabled = input<boolean, BooleanInput>(false, { transform: booleanAttribute });\n\n /**\n * Whether the field is required.\n *\n * @group Props\n * @defaultValue false\n */\n readonly required = input<boolean, BooleanInput>(false, { transform: booleanAttribute });\n\n /**\n * Whether the field value has changed from its initial value.\n *\n * @group Props\n * @defaultValue false\n */\n readonly dirty = input<boolean, BooleanInput>(false, { transform: booleanAttribute });\n\n /**\n * Whether the field has been blurred after receiving focus.\n *\n * @group Props\n * @defaultValue false\n */\n readonly touched = input<boolean, BooleanInput>(false, { transform: booleanAttribute });\n\n /**\n * Overrides whether the control has a non-empty value.\n *\n * @group Props\n */\n readonly filled = input<boolean>();\n\n /**\n * Overrides whether the control is focused.\n *\n * @group Props\n */\n readonly focused = input<boolean>();\n\n /**\n * Identifies the field to an enclosing Form for external (server) error matching. Fields without a\n * `name` never match external errors.\n *\n * @group Props\n */\n readonly name = input<string>();\n\n /**\n * Overrides when this field reveals its validity (error styling + message). Falls back to the\n * enclosing `rdxFormRoot`'s `validationMode`, then `'onBlur'`. Server errors always show regardless.\n *\n * @group Props\n */\n readonly validationMode = input<RdxValidationMode>();\n\n /** The enclosing Form, if any. All Form-related behavior is a no-op when this is `null`. */\n private readonly formContext = injectFormRootContext(true);\n\n readonly controlId = signal(injectId('rdx-field-control-'));\n readonly descriptionIds = signal<string[]>([]);\n readonly errorIds = signal<string[]>([]);\n\n readonly focusedValue = signal(false);\n readonly filledValue = signal(false);\n readonly dirtyValue = signal(false);\n readonly touchedValue = signal(false);\n\n /** External state owner registered through the context; `null` when Field self-computes. */\n private readonly stateProvider = signal<RdxFieldState | null>(null);\n\n /** Whether an external adapter currently owns field state. */\n readonly hasStateProvider = computed(() => this.stateProvider() !== null);\n\n /** Error content from a registered state provider (e.g. a Signal Forms adapter). */\n private readonly providerErrors = computed(() => this.stateProvider()?.errors?.() ?? []);\n\n /** **Client** validation errors routed by a form-level provider (`rdxSignalForm`) — gated by `validationMode`. */\n private readonly clientErrors = computed(() => this.formContext?.clientErrorsFor(this.name()) ?? []);\n\n /** **Server/external** errors from the Form's `errors` input — shown eagerly (never gated). */\n private readonly serverErrors = computed(() => this.formContext?.externalErrorsFor(this.name()) ?? []);\n\n /** Whether the enclosing Form has had a submit attempted; `false` when standalone. A presentation\n * seam an adapter can read to reveal errors after a submit attempt (Base UI's submit-attempt state). */\n readonly formSubmitAttempted = computed(() => this.formContext?.submitAttempted() ?? false);\n\n /**\n * Client messages first (per-field `rdxSignalField` provider, then form-level `rdxSignalForm`\n * name-routing) — only once `validationMode` reveals client validity — then the Form's **server**\n * messages (the `errors` input), which always show. **Deduped by text**: a field can receive the same\n * Signal Forms error from both a per-field provider and the form-level routing (they read the same\n * field state), so deduping renders it once while still surfacing distinct messages from each source.\n */\n readonly messages = computed(() => {\n // **Client** messages (per-field `rdxSignalField` provider + form-level `rdxSignalForm` routing)\n // surface only once the field's `validationMode` reveals them; **server** messages (the `errors`\n // input) always show. So a neutral field stays empty and the polite live region announces on reveal.\n const client = this.validationRevealed()\n ? [...this.providerErrors().map((error) => error.message ?? error.kind), ...this.clientErrors()]\n : [];\n const seen = new Set<string>();\n const result: string[] = [];\n for (const message of [...client, ...this.serverErrors()]) {\n if (message && !seen.has(message)) {\n seen.add(message);\n result.push(message);\n }\n }\n return result;\n });\n\n /** Effective validation-display mode: this field's override → the enclosing Form's → the default. */\n readonly effectiveValidationMode = computed<RdxValidationMode>(\n () => this.validationMode() ?? this.formContext?.validationMode() ?? RDX_DEFAULT_VALIDATION_MODE\n );\n\n /** Whether client-side validity is revealed yet, per {@link effectiveValidationMode} + interaction. */\n private readonly validationRevealed = computed(() =>\n isValidationRevealed(this.effectiveValidationMode(), {\n touched: this.touchedState(),\n dirty: this.dirtyState(),\n submitAttempted: this.formSubmitAttempted()\n })\n );\n\n /**\n * Client-side invalidity (gated by `validationMode`): the per-field provider's error content / `invalid`\n * (`rdxSignalField`), a form-level provider's name-routed errors (`rdxSignalForm`), or the `[invalid]`\n * input. Excludes server errors (which are eager).\n */\n private readonly clientInvalidState = computed(\n () =>\n this.providerErrors().length > 0 ||\n this.clientErrors().length > 0 ||\n this.resolve('invalid', () => this.invalid())\n );\n\n /**\n * Tri-state *displayed* validity (`boolean | null`) — the source for `data-valid` / `data-invalid`.\n * Server errors show immediately; client-side validity (including `rdxSignalForm` name-routing) stays\n * **neutral** (`null`) until the field's {@link effectiveValidationMode} reveals it, then `false`/`true`.\n */\n readonly validState = computed<boolean | null>(() => {\n if (this.serverErrors().length > 0) {\n return false;\n }\n if (!this.validationRevealed()) {\n return null;\n }\n return this.clientInvalidState() ? false : true;\n });\n\n /**\n * Boolean **displayed** invalidity (= `validState() === false`), used by `rdxFieldError` (hidden) and\n * `rdxFieldControl`'s `aria-describedby` error linking. A neutral (`null`) `validState` reads as not\n * invalid here, so the error region stays hidden until the field's mode reveals it.\n */\n readonly invalidState = computed(() => this.validState() === false);\n\n /**\n * Boolean **actual** invalidity — ungated by the display mode. The enclosing Form aggregates this into\n * `anyInvalid` (→ submit-block / focus-first-invalid), so a field that is really invalid but displayed\n * neutral still blocks submit. The form's presentation `data-invalid` comes from the *displayed*\n * aggregate (`anyDisplayedInvalid`) instead — not from this. Server errors + provider error content +\n * the provider/input `invalid`.\n */\n readonly actualInvalidState = computed(() => this.serverErrors().length > 0 || this.clientInvalidState());\n readonly disabledState = computed(() => this.resolve('disabled', () => this.disabled()));\n readonly requiredState = computed(() => this.resolve('required', () => this.required()));\n // `touched`/`dirty` also OR in the enclosing Form's per-name state (`rdxSignalForm` name-routing), so a\n // field with only a bare `[formField]` (no `rdxSignalField`/`rdxFieldControl`) still reveals on blur.\n readonly dirtyState = computed(\n () =>\n this.resolve('dirty', () => this.dirty() || this.dirtyValue()) ||\n (this.formContext?.dirtyFor(this.name()) ?? false)\n );\n readonly touchedState = computed(\n () =>\n this.resolve('touched', () => this.touched() || this.touchedValue()) ||\n (this.formContext?.touchedFor(this.name()) ?? false)\n );\n readonly filledState = computed(() => this.resolve('filled', () => this.filled() ?? this.filledValue()));\n readonly focusedState = computed(() => this.resolve('focused', () => this.focused() ?? this.focusedValue()));\n\n protected readonly dataAttr = attr;\n\n constructor() {\n // Register with an enclosing Form (if any) for aggregate state, submit guard, and reset; a\n // standalone field never enters this branch and behaves exactly as before.\n const formContext = this.formContext;\n if (formContext) {\n const registration: RdxFormFieldRegistration = {\n name: () => this.name(),\n // `invalid` reports *actual* validity (ungated) — `form.anyInvalid` + the submit guard must\n // reflect real state even before a field reveals it. `displayValid` reports the *gated*\n // tri-state so the form's presentation `data-invalid` stays neutral on load.\n invalid: () => this.actualInvalidState(),\n displayValid: () => this.validState(),\n dirty: () => this.dirtyState(),\n touched: () => this.touchedState(),\n focus: () => this.focusControl(),\n resetState: () => this.resetState()\n };\n const unregister = formContext.register(registration);\n inject(DestroyRef).onDestroy(unregister);\n }\n }\n\n /** Notify the enclosing Form (if any) that this field's control was edited (clear-on-edit). */\n notifyEdited(): void {\n this.formContext?.notifyEdited(this.name());\n }\n\n /** Reset interaction state on native form reset: touched/dirty/focused → false, filled re-synced. */\n resetState(): void {\n this.touchedValue.set(false);\n this.dirtyValue.set(false);\n this.focusedValue.set(false);\n const control = this.controlElement();\n const value = control?.value ?? '';\n this.filledValue.set(value != null && value !== '');\n }\n\n /** Focus the field's control (used by the Form's first-invalid-focus on blocked submit). */\n private focusControl(): void {\n this.controlElement()?.focus();\n }\n\n private readonly host = inject<ElementRef<HTMLElement>>(ElementRef).nativeElement;\n\n /**\n * The field's control element, found by `controlId` but scoped to this field's own subtree — a\n * duplicate or consumer-reused id elsewhere on the page can't steal focus/reset. The control\n * registers its id through `setControlId`, so this matches the same element the labels point at.\n */\n private controlElement(): HTMLInputElement | null {\n return this.host.querySelector<HTMLInputElement>(`[id=\"${this.controlId()}\"]`);\n }\n\n /**\n * Register an external owner of field state, returning the previous one.\n * @ignore\n */\n setStateProvider(provider: RdxFieldState | null): RdxFieldState | null {\n const previous = this.stateProvider();\n this.stateProvider.set(provider);\n return previous;\n }\n\n /**\n * Identity-checked teardown — roll back to `previous` only if `provider` is still active. Prevents\n * an old adapter's destroy from clobbering a newer adapter that registered after it (create-before-\n * destroy during a structural view swap).\n */\n clearStateProvider(provider: RdxFieldState | null, previous: RdxFieldState | null): void {\n if (this.stateProvider() === provider) {\n this.stateProvider.set(previous);\n }\n }\n\n /**\n * Prefer the registered provider's value for `key` when it exposes one,\n * otherwise fall back to the root inputs / DOM-derived signals. `errors` (content) and `valid`\n * (tri-state `boolean | null`) are resolved separately, so they're excluded from this boolean key.\n */\n private resolve(key: Exclude<keyof RdxFieldState, 'errors' | 'valid'>, fallback: () => boolean): boolean {\n const accessor = this.stateProvider()?.[key];\n return accessor ? accessor() : fallback();\n }\n}\n\nfunction injectFieldRoot(): RdxFieldRoot {\n return inject(RdxFieldRoot);\n}\n","import { afterNextRender, computed, Directive, effect, ElementRef, inject, input } from '@angular/core';\nimport { injectId } from '@radix-ng/primitives/core';\nimport { injectFieldRootContext } from './field-root';\n\nconst attr = (value: boolean) => (value ? '' : undefined);\n\n/**\n * Connects a form control to the field label, description, error, and state.\n *\n * @group Components\n */\n@Directive({\n selector: '[rdxFieldControl]',\n exportAs: 'rdxFieldControl',\n host: {\n '[attr.id]': 'id()',\n '[attr.aria-describedby]': 'describedBy()',\n // `aria-invalid`/`data-*` follow the field's tri-state `validState`: while it is neutral (`null`,\n // e.g. a field whose `validationMode` defers display (e.g. `onBlur`) before interaction) the control emits no `aria-invalid`\n // and neither `data-valid` nor `data-invalid`, matching the field root.\n '[attr.aria-invalid]': 'rootContext.validState() === false ? \"true\" : undefined',\n // On a native control the native `required`/`disabled` attributes already convey the state, so\n // `aria-required`/`aria-disabled` are only emitted on non-native (custom) controls.\n '[attr.aria-required]': '!isNativeFormControl() && rootContext.requiredState() ? \"true\" : undefined',\n '[attr.aria-disabled]': '!isNativeFormControl() && rootContext.disabledState() ? \"true\" : undefined',\n '[attr.disabled]': 'isNativeFormControl() && rootContext.disabledState() ? \"\" : undefined',\n '[attr.required]': 'isNativeFormControl() && rootContext.requiredState() ? \"\" : undefined',\n '[attr.data-invalid]': 'dataAttr(rootContext.validState() === false)',\n '[attr.data-valid]': 'dataAttr(rootContext.validState() === true)',\n '[attr.data-disabled]': 'dataAttr(rootContext.disabledState())',\n '[attr.data-required]': 'dataAttr(rootContext.requiredState())',\n '[attr.data-dirty]': 'dataAttr(rootContext.dirtyState())',\n '[attr.data-touched]': 'dataAttr(rootContext.touchedState())',\n '[attr.data-filled]': 'dataAttr(rootContext.filledState())',\n '[attr.data-focused]': 'dataAttr(rootContext.focusedState())',\n '(focus)': 'onFocus()',\n '(blur)': 'onBlur()',\n '(input)': 'syncFilled()',\n '(change)': 'syncFilled()'\n }\n})\nexport class RdxFieldControl {\n protected readonly rootContext = injectFieldRootContext();\n private readonly elementRef = inject<ElementRef<HTMLElement>>(ElementRef);\n private initialValue = '';\n\n /**\n * Control id. Labels and descriptions use this value for accessible relationships.\n *\n * @group Props\n */\n readonly id = input(injectId('rdx-field-control-'));\n\n protected readonly describedBy = computed(() => {\n const ids = [\n ...this.rootContext.descriptionIds(),\n ...(this.rootContext.invalidState() ? this.rootContext.errorIds() : [])\n ];\n\n return ids.length ? ids.join(' ') : undefined;\n });\n\n constructor() {\n effect(() => {\n this.rootContext.setControlId(this.id());\n });\n\n afterNextRender(() => {\n this.initialValue = this.currentValue();\n this.syncFilled();\n });\n }\n\n onFocus(): void {\n this.rootContext.setFocused(true);\n }\n\n onBlur(): void {\n this.rootContext.setFocused(false);\n this.rootContext.setTouched(true);\n }\n\n syncFilled(): void {\n const value = this.currentValue();\n\n this.rootContext.setFilled(Array.isArray(value) ? value.length > 0 : value != null && value !== '');\n this.rootContext.setDirty(value !== this.initialValue);\n }\n\n protected isNativeFormControl(): boolean {\n return ['INPUT', 'SELECT', 'TEXTAREA', 'BUTTON'].includes(this.elementRef.nativeElement.tagName);\n }\n\n protected readonly dataAttr = attr;\n\n private currentValue(): string {\n const element = this.elementRef.nativeElement as HTMLInputElement | HTMLTextAreaElement | HTMLSelectElement;\n return element.value ?? '';\n }\n}\n","import { Directive, effect, input } from '@angular/core';\nimport { injectId } from '@radix-ng/primitives/core';\nimport { injectFieldRootContext } from './field-root';\n\nconst attr = (value: boolean) => (value ? '' : undefined);\n\n/**\n * Describes the field control.\n *\n * @group Components\n */\n@Directive({\n selector: '[rdxFieldDescription]',\n exportAs: 'rdxFieldDescription',\n host: {\n '[attr.id]': 'id()',\n '[attr.data-invalid]': 'dataAttr(rootContext.invalidState())',\n '[attr.data-disabled]': 'dataAttr(rootContext.disabledState())'\n }\n})\nexport class RdxFieldDescription {\n protected readonly rootContext = injectFieldRootContext();\n\n /**\n * Description id.\n *\n * @group Props\n */\n readonly id = input(injectId('rdx-field-description-'));\n\n constructor() {\n effect((onCleanup) => {\n const id = this.id();\n this.rootContext.addDescriptionId(id);\n onCleanup(() => this.rootContext.removeDescriptionId(id));\n });\n }\n\n protected readonly dataAttr = attr;\n}\n","import { Directive, effect, input } from '@angular/core';\nimport { injectId } from '@radix-ng/primitives/core';\nimport { injectFieldRootContext } from './field-root';\n\nconst attr = (value: boolean) => (value ? '' : undefined);\n\n/**\n * Describes an invalid field control.\n *\n * @group Components\n */\n@Directive({\n selector: '[rdxFieldError]',\n exportAs: 'rdxFieldError',\n host: {\n '[attr.id]': 'id()',\n '[attr.hidden]': 'rootContext.invalidState() ? undefined : \"\"',\n '[attr.aria-live]': '\"polite\"',\n '[attr.data-invalid]': 'dataAttr(rootContext.invalidState())',\n '[attr.data-disabled]': 'dataAttr(rootContext.disabledState())'\n }\n})\nexport class RdxFieldError {\n protected readonly rootContext = injectFieldRootContext();\n\n /**\n * Error message id.\n *\n * @group Props\n */\n readonly id = input(injectId('rdx-field-error-'));\n\n /**\n * The field's validation messages — client (provider / form name-routing, once `validationMode`\n * reveals them) then server (the Form's `errors` input, always); `[]` when none. Render them\n * explicitly via the `exportAs` reference — the directive never injects text content itself:\n * `<p rdxFieldError #err=\"rdxFieldError\">{{ err.messages().join(' ') }}</p>`.\n */\n readonly messages = this.rootContext.messages;\n\n constructor() {\n effect((onCleanup) => {\n const id = this.id();\n this.rootContext.addErrorId(id);\n onCleanup(() => this.rootContext.removeErrorId(id));\n });\n }\n\n protected readonly dataAttr = attr;\n}\n","import { booleanAttribute, computed, Directive, inject, input, signal } from '@angular/core';\nimport { BooleanInput, injectId, RDX_FIELD_VALIDITY } from '@radix-ng/primitives/core';\nimport { provideFieldRootContext, RdxFieldRoot, RdxFieldRootContext } from './field-root';\n\nconst attr = (value: boolean) => (value ? '' : undefined);\nconst addId = (ids: string[], id: string) => (ids.includes(id) ? ids : [...ids, id]);\nconst removeId = (ids: string[], id: string) => ids.filter((item) => item !== id);\n\n/**\n * The field item context **re-provides** {@link RdxFieldRootContext} so a label, description, and control\n * placed inside the item associate with the **item's** control (own `controlId` / `descriptionIds`),\n * while all validation state (`invalidState` / `dirtyState` / `touchedState` / `filledState` /\n * `focusedState` / `requiredState`, errors and messages) is **delegated to the enclosing `rdxFieldRoot`**.\n * `disabledState` is the item's `disabled` OR'd with the root's. The enclosing root is reached with\n * `skipSelf` (the item provides the same token), so there is no circular injection.\n */\nconst fieldItemContext = (): RdxFieldRootContext => {\n const item = inject(RdxFieldItem);\n const root = item.root;\n\n return {\n controlId: item.controlId,\n name: root.name,\n descriptionIds: item.descriptionIds,\n errorIds: root.errorIds,\n messages: root.messages,\n notifyEdited: () => root.notifyEdited(),\n validState: root.validState,\n formSubmitAttempted: root.formSubmitAttempted,\n invalidState: root.invalidState,\n disabledState: item.disabledState,\n requiredState: root.requiredState,\n dirtyState: root.dirtyState,\n touchedState: root.touchedState,\n filledState: root.filledState,\n focusedState: root.focusedState,\n setControlId: (id: string) => item.controlId.set(id),\n addDescriptionId: (id: string) => item.descriptionIds.update((ids) => addId(ids, id)),\n removeDescriptionId: (id: string) => item.descriptionIds.update((ids) => removeId(ids, id)),\n addErrorId: (id: string) => root.errorIds.update((ids) => addId(ids, id)),\n removeErrorId: (id: string) => root.errorIds.update((ids) => removeId(ids, id)),\n setFocused: (value: boolean) => root.focusedValue.set(value),\n setFilled: (value: boolean) => root.filledValue.set(value),\n setDirty: (value: boolean) => root.dirtyValue.set(value),\n setTouched: (value: boolean) => root.touchedValue.set(value),\n setStateProvider: (provider) => root.setStateProvider(provider),\n clearStateProvider: (provider, previous) => root.clearStateProvider(provider, previous),\n hasStateProvider: root.hasStateProvider\n };\n};\n\n/**\n * Groups an individual item in a checkbox group or radio group with its own label and description.\n *\n * Use inside a `rdxFieldRoot` (typically wrapping a group) when each control needs its own label /\n * description: the item scopes those associations to its control while reflecting the field's validation\n * state. Mirrors Base UI's `Field.Item`.\n *\n * @group Components\n */\n@Directive({\n selector: '[rdxFieldItem]',\n exportAs: 'rdxFieldItem',\n providers: [\n provideFieldRootContext(fieldItemContext),\n // Items delegate validity to the root; expose the root's tri-state to controls inside the item.\n { provide: RDX_FIELD_VALIDITY, useFactory: () => inject(RdxFieldItem).root.validState }\n ],\n host: {\n // Tri-state, mirroring the root: neither attribute while the root's `validState` is neutral.\n '[attr.data-invalid]': 'dataAttr(root.validState() === false)',\n '[attr.data-valid]': 'dataAttr(root.validState() === true)',\n '[attr.data-disabled]': 'dataAttr(disabledState())',\n '[attr.data-required]': 'dataAttr(root.requiredState())',\n '[attr.data-dirty]': 'dataAttr(root.dirtyState())',\n '[attr.data-touched]': 'dataAttr(root.touchedState())',\n '[attr.data-filled]': 'dataAttr(root.filledState())',\n '[attr.data-focused]': 'dataAttr(root.focusedState())'\n }\n})\nexport class RdxFieldItem {\n /** The enclosing field root (items are leaves under the root, so `skipSelf` reaches it). */\n readonly root = inject(RdxFieldRoot, { skipSelf: true });\n\n /**\n * Whether the wrapped control should ignore user interaction. The `disabled` on `rdxFieldRoot` takes\n * precedence (it is OR'd in).\n *\n * @group Props\n * @defaultValue false\n */\n readonly disabled = input<boolean, BooleanInput>(false, { transform: booleanAttribute });\n\n /** This item's control id — label / description / control inside the item associate with it. */\n readonly controlId = signal(injectId('rdx-field-item-control-'));\n /** Description ids for this item's control `aria-describedby`. */\n readonly descriptionIds = signal<string[]>([]);\n\n /** The item's effective disabled state: the root's disabled OR the item's. */\n readonly disabledState = computed(() => this.root.disabledState() || this.disabled());\n\n protected readonly dataAttr = attr;\n}\n","import { Directive, input } from '@angular/core';\nimport { injectId, rdxCheckLabelElement } from '@radix-ng/primitives/core';\nimport { injectFieldRootContext } from './field-root';\n\nconst attr = (value: boolean) => (value ? '' : undefined);\n\n/**\n * Labels the field control.\n *\n * @group Components\n */\n@Directive({\n selector: '[rdxFieldLabel]',\n exportAs: 'rdxFieldLabel',\n host: {\n '[attr.id]': 'id()',\n '[attr.for]': 'htmlFor()',\n '[attr.data-invalid]': 'dataAttr(rootContext.invalidState())',\n '[attr.data-disabled]': 'dataAttr(rootContext.disabledState())',\n '[attr.data-required]': 'dataAttr(rootContext.requiredState())'\n }\n})\nexport class RdxFieldLabel {\n protected readonly rootContext = injectFieldRootContext();\n\n /**\n * Label id.\n *\n * @group Props\n */\n readonly id = input(injectId('rdx-field-label-'));\n\n readonly htmlFor = () => this.rootContext.controlId();\n\n constructor() {\n rdxCheckLabelElement('rdxFieldLabel', 'field/unassociated-label', 'components/field');\n }\n\n protected readonly dataAttr = attr;\n}\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './index';\n"],"names":["attr","addId","removeId"],"mappings":"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"}
@@ -1,14 +1,20 @@
1
1
  import * as i0 from '@angular/core';
2
2
  import { inject, ElementRef, input, output, signal, computed, linkedSignal, DestroyRef, Directive, NgModule } from '@angular/core';
3
- import { createContext } from '@radix-ng/primitives/core';
3
+ import { createContext, RDX_DEFAULT_VALIDATION_MODE } from '@radix-ng/primitives/core';
4
4
 
5
5
  const formRootContext = () => {
6
6
  const root = inject(RdxFormRoot);
7
7
  return {
8
- errorsFor: (name) => root.errorsFor(name),
8
+ clientErrorsFor: (name) => root.clientErrorsFor(name),
9
+ externalErrorsFor: (name) => root.externalErrorsFor(name),
10
+ touchedFor: (name) => root.touchedFor(name),
11
+ dirtyFor: (name) => root.dirtyFor(name),
9
12
  notifyEdited: (name) => root.notifyEdited(name),
13
+ submitAttempted: root.submitAttempted,
14
+ validationMode: root.validationMode,
10
15
  register: (field) => root.register(field),
11
16
  setStateProvider: (provider) => root.setStateProvider(provider),
17
+ clearStateProvider: (provider, previous) => root.clearStateProvider(provider, previous),
12
18
  hasStateProvider: root.hasStateProvider
13
19
  };
14
20
  };
@@ -38,31 +44,52 @@ function serializeFormData(data) {
38
44
  * @group Components
39
45
  */
40
46
  class RdxFormRoot {
41
- /** Resolve a boolean aggregate: a registered provider's accessor wins, else OR over the registry. */
47
+ /**
48
+ * Resolve a boolean aggregate. For `dirty` / `touched` a registered provider's accessor wins, else OR
49
+ * over the registry. For **`invalid`** the two are **merged** (`provider || registry`): a registered
50
+ * field's actual invalidity — e.g. a server `[errors]` entry — must still count (and block submit) even
51
+ * when a form-level provider (`rdxSignalForm`) reports the client model valid.
52
+ */
42
53
  aggregate(key) {
43
54
  const accessor = this.stateProvider()?.[key];
44
- return accessor ? accessor() : this.fields().some((field) => field[key]());
55
+ const fromRegistry = this.fields().some((field) => field[key]());
56
+ if (key === 'invalid') {
57
+ return (accessor?.() ?? false) || fromRegistry;
58
+ }
59
+ return accessor ? accessor() : fromRegistry;
45
60
  }
46
- /** Resolves the external messages for a field name (provider source wins over the `errors` input). */
47
- errorsFor(name) {
61
+ /** Client validation errors from a form-level provider (`rdxSignalForm`); `[]` when none. Gated. */
62
+ clientErrorsFor(name) {
48
63
  if (!name) {
49
64
  return [];
50
65
  }
51
- const provider = this.stateProvider();
52
- if (provider?.errorsFor) {
53
- return provider.errorsFor(name);
66
+ return this.stateProvider()?.errorsFor?.(name) ?? [];
67
+ }
68
+ /** Per-name `touched` from a form-level provider (`rdxSignalForm`); `false` when none. */
69
+ touchedFor(name) {
70
+ return name ? (this.stateProvider()?.touchedFor?.(name) ?? false) : false;
71
+ }
72
+ /** Per-name `dirty` from a form-level provider (`rdxSignalForm`); `false` when none. */
73
+ dirtyFor(name) {
74
+ return name ? (this.stateProvider()?.dirtyFor?.(name) ?? false) : false;
75
+ }
76
+ /**
77
+ * Server/external errors from the `errors` input (eager). A separate channel from {@link clientErrorsFor}:
78
+ * the `errors` input always applies, even alongside a form-level client provider (`rdxSignalForm`), so
79
+ * adding `rdxSignalForm` never disables your server errors.
80
+ */
81
+ externalErrorsFor(name) {
82
+ if (!name) {
83
+ return [];
54
84
  }
55
85
  return this.effectiveErrors()[name] ?? [];
56
86
  }
57
- /** Clears a field's external error after a user edit, emitting the remaining map. */
87
+ /** Clears a field's server error (the `errors` input) after a user edit, emitting the remaining map.
88
+ * Client provider errors (`rdxSignalForm`) are not affected — Signal Forms re-validates them itself. */
58
89
  notifyEdited(name) {
59
90
  if (!name) {
60
91
  return;
61
92
  }
62
- // While a provider owns errors, Signal Forms clears/reapplies them itself — stay inert.
63
- if (this.stateProvider()?.errorsFor) {
64
- return;
65
- }
66
93
  const errors = this.errors() ?? {};
67
94
  if (!Object.hasOwn(errors, name) || this.clearedNames().has(name)) {
68
95
  return;
@@ -80,9 +107,22 @@ class RdxFormRoot {
80
107
  this.stateProvider.set(provider);
81
108
  return previous;
82
109
  }
110
+ /**
111
+ * Identity-checked teardown — roll back to `previous` only if `provider` is still active, so an
112
+ * old adapter's destroy can't clobber a newer one (create-before-destroy on a view swap).
113
+ */
114
+ clearStateProvider(provider, previous) {
115
+ if (this.stateProvider() === provider) {
116
+ this.stateProvider.set(previous);
117
+ }
118
+ }
83
119
  onSubmit(event) {
84
120
  // SPA submits never navigate; never stopPropagation so Reactive Forms `(ngSubmit)` keeps firing.
85
121
  event.preventDefault();
122
+ // Record the attempt *before* reading validity. Display-gating uses `submitAttempted` to reveal
123
+ // errors (a `validationMode` of `onBlur`/`onSubmit`), but the Form aggregates *actual* invalidity,
124
+ // so a pristine invalid form is blocked and its errors revealed instead of submitting.
125
+ this.submitAttempted.set(true);
86
126
  if (this.aggregate('invalid')) {
87
127
  // Focus the first invalid registered field (DOM order); provider-only invalid has none to focus.
88
128
  this.fields()
@@ -91,19 +131,19 @@ class RdxFormRoot {
91
131
  return;
92
132
  }
93
133
  const values = serializeFormData(new FormData(this.form));
94
- this.onFormSubmit.emit({ values, event });
134
+ this.onFormSubmit.emit({ values, reason: 'none', event });
95
135
  }
96
136
  onReset() {
97
137
  // Don't prevent the native reset — control values revert on their own.
98
- if (!this.stateProvider()?.errorsFor) {
99
- const keys = Object.keys(this.errors() ?? {});
100
- const hadVisible = keys.some((key) => !this.clearedNames().has(key));
101
- if (keys.length) {
102
- this.clearedNames.set(new Set(keys));
103
- }
104
- if (hadVisible) {
105
- this.onClearErrors.emit({});
106
- }
138
+ this.submitAttempted.set(false);
139
+ // Clear server errors (the `errors` input); client provider errors re-validate themselves.
140
+ const keys = Object.keys(this.errors() ?? {});
141
+ const hadVisible = keys.some((key) => !this.clearedNames().has(key));
142
+ if (keys.length) {
143
+ this.clearedNames.set(new Set(keys));
144
+ }
145
+ if (hadVisible) {
146
+ this.onClearErrors.emit({});
107
147
  }
108
148
  // Values revert asynchronously relative to the reset event — re-sync field state next macrotask.
109
149
  // Read the registry fresh inside the callback (fields may register/unregister in between), and
@@ -119,6 +159,16 @@ class RdxFormRoot {
119
159
  /** External/server validation errors keyed by `Field.Root` `name`. */
120
160
  this.errors = input(/* @ts-ignore */
121
161
  ...(ngDevMode ? [undefined, { debugName: "errors" }] : /* istanbul ignore next */ []));
162
+ /**
163
+ * When fields reveal their validity (error styling + message). The control/adapter always reports the
164
+ * actual state; this decides *when* the Field surfaces it. A `rdxFieldRoot` can override it per field.
165
+ * Server errors (`errors` above) always show regardless. Defaults to `'onBlur'`.
166
+ *
167
+ * @group Props
168
+ * @defaultValue 'onBlur'
169
+ */
170
+ this.validationMode = input(RDX_DEFAULT_VALIDATION_MODE, /* @ts-ignore */
171
+ ...(ngDevMode ? [{ debugName: "validationMode" }] : /* istanbul ignore next */ []));
122
172
  /** Emits the remaining error map after a field's external error is cleared by a user edit (or reset). */
123
173
  this.onClearErrors = output();
124
174
  /** Emits the serialized form values when a valid form is submitted. */
@@ -151,6 +201,8 @@ class RdxFormRoot {
151
201
  return result;
152
202
  }, /* @ts-ignore */
153
203
  ...(ngDevMode ? [{ debugName: "effectiveErrors" }] : /* istanbul ignore next */ []));
204
+ /** **Actual** aggregate invalidity (eager) — drives the submit guard / focus-first-invalid and is the
205
+ * value to read in app logic. Merges a form-level provider with the field registry. */
154
206
  this.anyInvalid = computed(() => this.aggregate('invalid'), /* @ts-ignore */
155
207
  ...(ngDevMode ? [{ debugName: "anyInvalid" }] : /* istanbul ignore next */ []));
156
208
  this.anyDirty = computed(() => this.aggregate('dirty'), /* @ts-ignore */
@@ -159,6 +211,38 @@ class RdxFormRoot {
159
211
  ...(ngDevMode ? [{ debugName: "anyTouched" }] : /* istanbul ignore next */ []));
160
212
  this.submitting = computed(() => this.stateProvider()?.submitting?.() ?? false, /* @ts-ignore */
161
213
  ...(ngDevMode ? [{ debugName: "submitting" }] : /* istanbul ignore next */ []));
214
+ /**
215
+ * **Displayed** aggregate invalidity — the source for the host `data-invalid` (a presentation
216
+ * attribute). A field counts only once its own `validationMode` reveals it (`displayValid() === false`),
217
+ * so the form stays **neutral on load** while its fields are, instead of leaking the gated state.
218
+ * Distinct from {@link anyInvalid} (actual, eager).
219
+ *
220
+ * When **any** display-aware field is registered, those fields are the *authoritative* displayed
221
+ * source and win outright — a form-level provider's aggregate `invalid()` is **not** added on top
222
+ * (it would contradict a field that overrode its own `validationMode` to stay neutral; and the
223
+ * fields already reflect that provider's per-name state). The provider fallback applies only when no
224
+ * display-aware field carries the state, and then conservatively — under `validationMode="always"`
225
+ * or after a submit attempt, never from `anyTouched`.
226
+ */
227
+ this.anyDisplayedInvalid = computed(() => {
228
+ const fields = this.fields();
229
+ if (fields.some((field) => field.displayValid?.() === false)) {
230
+ return true;
231
+ }
232
+ if (fields.some((field) => field.displayValid !== undefined)) {
233
+ return false;
234
+ }
235
+ const providerInvalid = this.stateProvider()?.invalid?.() ?? false;
236
+ return providerInvalid && (this.validationMode() === 'always' || this.submitAttempted());
237
+ }, /* @ts-ignore */
238
+ ...(ngDevMode ? [{ debugName: "anyDisplayedInvalid" }] : /* istanbul ignore next */ []));
239
+ /**
240
+ * Whether a submit has been attempted on this form, exposed to fields via the context. Set true at the
241
+ * very start of {@link onSubmit} (before the validity check, so a field whose `validationMode` defers
242
+ * display, e.g. `onBlur`, reveals its error in time to block the submit) and cleared on native reset.
243
+ */
244
+ this.submitAttempted = signal(false, /* @ts-ignore */
245
+ ...(ngDevMode ? [{ debugName: "submitAttempted" }] : /* istanbul ignore next */ []));
162
246
  this.resetTimers = new Set();
163
247
  inject(DestroyRef).onDestroy(() => this.resetTimers.forEach((timer) => clearTimeout(timer)));
164
248
  }
@@ -174,7 +258,7 @@ class RdxFormRoot {
174
258
  return result;
175
259
  }
176
260
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.0.2", ngImport: i0, type: RdxFormRoot, deps: [], target: i0.ɵɵFactoryTarget.Directive }); }
177
- static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "17.1.0", version: "22.0.2", type: RdxFormRoot, isStandalone: true, selector: "form[rdxFormRoot]", inputs: { errors: { classPropertyName: "errors", publicName: "errors", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { onClearErrors: "onClearErrors", onFormSubmit: "onFormSubmit" }, host: { attributes: { "novalidate": "" }, listeners: { "submit": "onSubmit($event)", "reset": "onReset()" }, properties: { "attr.data-invalid": "anyInvalid() ? \"\" : undefined", "attr.data-dirty": "anyDirty() ? \"\" : undefined", "attr.data-touched": "anyTouched() ? \"\" : undefined", "attr.data-submitting": "submitting() ? \"\" : undefined" } }, providers: [provideFormRootContext(formRootContext)], exportAs: ["rdxFormRoot"], ngImport: i0 }); }
261
+ static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "17.1.0", version: "22.0.2", type: RdxFormRoot, isStandalone: true, selector: "form[rdxFormRoot]", inputs: { errors: { classPropertyName: "errors", publicName: "errors", isSignal: true, isRequired: false, transformFunction: null }, validationMode: { classPropertyName: "validationMode", publicName: "validationMode", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { onClearErrors: "onClearErrors", onFormSubmit: "onFormSubmit" }, host: { attributes: { "novalidate": "" }, listeners: { "submit": "onSubmit($event)", "reset": "onReset()" }, properties: { "attr.data-invalid": "anyDisplayedInvalid() ? \"\" : undefined", "attr.data-dirty": "anyDirty() ? \"\" : undefined", "attr.data-touched": "anyTouched() ? \"\" : undefined", "attr.data-submitting": "submitting() ? \"\" : undefined" } }, providers: [provideFormRootContext(formRootContext)], exportAs: ["rdxFormRoot"], ngImport: i0 }); }
178
262
  }
179
263
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.2", ngImport: i0, type: RdxFormRoot, decorators: [{
180
264
  type: Directive,
@@ -184,7 +268,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.2", ngImpor
184
268
  providers: [provideFormRootContext(formRootContext)],
185
269
  host: {
186
270
  novalidate: '',
187
- '[attr.data-invalid]': 'anyInvalid() ? "" : undefined',
271
+ '[attr.data-invalid]': 'anyDisplayedInvalid() ? "" : undefined',
188
272
  '[attr.data-dirty]': 'anyDirty() ? "" : undefined',
189
273
  '[attr.data-touched]': 'anyTouched() ? "" : undefined',
190
274
  '[attr.data-submitting]': 'submitting() ? "" : undefined',
@@ -192,7 +276,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.0.2", ngImpor
192
276
  '(reset)': 'onReset()'
193
277
  }
194
278
  }]
195
- }], ctorParameters: () => [], propDecorators: { errors: [{ type: i0.Input, args: [{ isSignal: true, alias: "errors", required: false }] }], onClearErrors: [{ type: i0.Output, args: ["onClearErrors"] }], onFormSubmit: [{ type: i0.Output, args: ["onFormSubmit"] }] } });
279
+ }], ctorParameters: () => [], propDecorators: { errors: [{ type: i0.Input, args: [{ isSignal: true, alias: "errors", required: false }] }], validationMode: [{ type: i0.Input, args: [{ isSignal: true, alias: "validationMode", required: false }] }], onClearErrors: [{ type: i0.Output, args: ["onClearErrors"] }], onFormSubmit: [{ type: i0.Output, args: ["onFormSubmit"] }] } });
196
280
 
197
281
  const _importsForm = [RdxFormRoot];
198
282
  class RdxFormModule {
@@ -1 +1 @@
1
- {"version":3,"file":"radix-ng-primitives-form.mjs","sources":["../../../packages/primitives/form/src/form-root.ts","../../../packages/primitives/form/index.ts","../../../packages/primitives/form/radix-ng-primitives-form.ts"],"sourcesContent":["import {\n computed,\n DestroyRef,\n Directive,\n ElementRef,\n inject,\n input,\n linkedSignal,\n output,\n signal\n} from '@angular/core';\nimport { createContext } from '@radix-ng/primitives/core';\n\n/** A normalized external-error map: each field name maps to its message(s) in display order. */\nexport type RdxFormErrors = Record<string, string | string[]>;\n\n/** Payload of {@link RdxFormRoot.onFormSubmit}. */\nexport interface RdxFormSubmitEvent {\n /** The form's values serialized from `FormData` (repeated names collapse into arrays). */\n values: Record<string, FormDataEntryValue | FormDataEntryValue[]>;\n /** The original native submit event (already `preventDefault`-ed). */\n event: SubmitEvent;\n}\n\n/**\n * What a {@link RdxFieldRoot} registers with an enclosing Form. Structural `() =>` accessors keep the\n * Form entry free of any import from `field` (acyclic ng-packagr graph: `field` → `form`).\n */\nexport interface RdxFormFieldRegistration {\n /** The field's `name` (key external errors match against), or `undefined`. */\n name: () => string | undefined;\n /** The field's merged invalid state (includes external errors). */\n invalid: () => boolean;\n /** Whether the field is dirty. */\n dirty: () => boolean;\n /** Whether the field is touched. */\n touched: () => boolean;\n /** Focus the field's control (by its `controlId`). */\n focus: () => void;\n /** Reset the field's interaction state (touched/dirty/focused → false, filled re-sync). */\n resetState: () => void;\n}\n\n/**\n * External owner of form-level state (e.g. a future Signal Forms `[rdxSignalForm]` adapter). Mirrors\n * Field's `RdxFieldState` seam one level up. Each member is optional: a provided accessor wins over the\n * built-in registry/`errors`-input behavior; absent accessors leave the built-in behavior untouched.\n * Kept as framework-free `() =>` accessors (no `@angular/forms/signals` dependency). See ADR 0004.\n */\nexport interface RdxFormState {\n invalid?: () => boolean;\n dirty?: () => boolean;\n touched?: () => boolean;\n submitting?: () => boolean;\n /** Per-name external error source; while provided, the `errors` input + clear-on-edit are inert. */\n errorsFor?: (name: string) => string[];\n}\n\nconst formRootContext = () => {\n const root = inject(RdxFormRoot);\n return {\n errorsFor: (name: string | undefined) => root.errorsFor(name),\n notifyEdited: (name: string | undefined) => root.notifyEdited(name),\n register: (field: RdxFormFieldRegistration) => root.register(field),\n setStateProvider: (provider: RdxFormState | null) => root.setStateProvider(provider),\n hasStateProvider: root.hasStateProvider\n };\n};\n\nexport type RdxFormRootContext = ReturnType<typeof formRootContext>;\n\nexport const [injectFormRootContext, provideFormRootContext] = createContext<RdxFormRootContext>(\n 'RdxFormRoot',\n 'components/form'\n);\n\n/** Collapses `FormData` into a plain object; repeated names collapse into arrays. */\nfunction serializeFormData(data: FormData): Record<string, FormDataEntryValue | FormDataEntryValue[]> {\n const values: Record<string, FormDataEntryValue | FormDataEntryValue[]> = {};\n data.forEach((value, key) => {\n // `Object.hasOwn`, not `key in values` — a control named after an Object.prototype member\n // (`toString`, `constructor`, …) must not be misread as a duplicate.\n if (Object.hasOwn(values, key)) {\n const existing = values[key];\n values[key] = Array.isArray(existing) ? [...existing, value] : [existing, value];\n } else {\n values[key] = value;\n }\n });\n return values;\n}\n\n/**\n * The top of the forms layer cake: a single directive on the native `<form>` element that aggregates\n * field state, maps external (server) errors onto fields by `name`, intercepts submit (values-as-object,\n * focus the first invalid field), and resets field interaction state on native `reset`. It owns no\n * values and runs no validation — Angular form systems (or Field inputs) remain the source of validity.\n *\n * @group Components\n */\n@Directive({\n selector: 'form[rdxFormRoot]',\n exportAs: 'rdxFormRoot',\n providers: [provideFormRootContext(formRootContext)],\n host: {\n novalidate: '',\n '[attr.data-invalid]': 'anyInvalid() ? \"\" : undefined',\n '[attr.data-dirty]': 'anyDirty() ? \"\" : undefined',\n '[attr.data-touched]': 'anyTouched() ? \"\" : undefined',\n '[attr.data-submitting]': 'submitting() ? \"\" : undefined',\n '(submit)': 'onSubmit($event)',\n '(reset)': 'onReset()'\n }\n})\nexport class RdxFormRoot {\n private readonly form = inject<ElementRef<HTMLFormElement>>(ElementRef).nativeElement;\n\n /** External/server validation errors keyed by `Field.Root` `name`. */\n readonly errors = input<RdxFormErrors | null | undefined>();\n\n /** Emits the remaining error map after a field's external error is cleared by a user edit (or reset). */\n readonly onClearErrors = output<RdxFormErrors>();\n\n /** Emits the serialized form values when a valid form is submitted. */\n readonly onFormSubmit = output<RdxFormSubmitEvent>();\n\n private readonly fields = signal<RdxFormFieldRegistration[]>([]);\n\n private readonly stateProvider = signal<RdxFormState | null>(null);\n\n /** Whether an external adapter currently owns form-level state. */\n readonly hasStateProvider = computed(() => this.stateProvider() !== null);\n\n /**\n * Names whose external error has been cleared by a user edit. Reset to empty whenever a new `errors`\n * object reference is assigned — the server just spoke, so everything it said is live again.\n */\n private readonly clearedNames = linkedSignal<RdxFormErrors | null | undefined, Set<string>>({\n source: this.errors,\n computation: () => new Set<string>()\n });\n\n /** The `errors` input minus cleared names, normalized to `string[]`. */\n private readonly effectiveErrors = computed<Record<string, string[]>>(() => {\n const errors = this.errors() ?? {};\n const cleared = this.clearedNames();\n const result: Record<string, string[]> = {};\n for (const key of Object.keys(errors)) {\n if (cleared.has(key)) {\n continue;\n }\n const value = errors[key];\n result[key] = Array.isArray(value) ? value : [value];\n }\n return result;\n });\n\n readonly anyInvalid = computed(() => this.aggregate('invalid'));\n readonly anyDirty = computed(() => this.aggregate('dirty'));\n readonly anyTouched = computed(() => this.aggregate('touched'));\n readonly submitting = computed(() => this.stateProvider()?.submitting?.() ?? false);\n\n /** Resolve a boolean aggregate: a registered provider's accessor wins, else OR over the registry. */\n private aggregate(key: 'invalid' | 'dirty' | 'touched'): boolean {\n const accessor = this.stateProvider()?.[key];\n return accessor ? accessor() : this.fields().some((field) => field[key]());\n }\n\n /** Resolves the external messages for a field name (provider source wins over the `errors` input). */\n errorsFor(name: string | undefined): string[] {\n if (!name) {\n return [];\n }\n const provider = this.stateProvider();\n if (provider?.errorsFor) {\n return provider.errorsFor(name);\n }\n return this.effectiveErrors()[name] ?? [];\n }\n\n /** Clears a field's external error after a user edit, emitting the remaining map. */\n notifyEdited(name: string | undefined): void {\n if (!name) {\n return;\n }\n // While a provider owns errors, Signal Forms clears/reapplies them itself — stay inert.\n if (this.stateProvider()?.errorsFor) {\n return;\n }\n const errors = this.errors() ?? {};\n if (!Object.hasOwn(errors, name) || this.clearedNames().has(name)) {\n return;\n }\n this.clearedNames.update((set) => new Set(set).add(name));\n this.onClearErrors.emit(this.remainingErrors());\n }\n\n register(field: RdxFormFieldRegistration): () => void {\n this.fields.update((list) => [...list, field]);\n return () => this.fields.update((list) => list.filter((item) => item !== field));\n }\n\n /** Register (or clear with `null`) an external owner of form-level state; returns the previous one. */\n setStateProvider(provider: RdxFormState | null): RdxFormState | null {\n const previous = this.stateProvider();\n this.stateProvider.set(provider);\n return previous;\n }\n\n onSubmit(event: SubmitEvent): void {\n // SPA submits never navigate; never stopPropagation so Reactive Forms `(ngSubmit)` keeps firing.\n event.preventDefault();\n\n if (this.aggregate('invalid')) {\n // Focus the first invalid registered field (DOM order); provider-only invalid has none to focus.\n this.fields()\n .find((field) => field.invalid())\n ?.focus();\n return;\n }\n\n const values = serializeFormData(new FormData(this.form));\n this.onFormSubmit.emit({ values, event });\n }\n\n onReset(): void {\n // Don't prevent the native reset — control values revert on their own.\n if (!this.stateProvider()?.errorsFor) {\n const keys = Object.keys(this.errors() ?? {});\n const hadVisible = keys.some((key) => !this.clearedNames().has(key));\n if (keys.length) {\n this.clearedNames.set(new Set(keys));\n }\n if (hadVisible) {\n this.onClearErrors.emit({});\n }\n }\n // Values revert asynchronously relative to the reset event — re-sync field state next macrotask.\n // Read the registry fresh inside the callback (fields may register/unregister in between), and\n // cancel on destroy so resetState never runs against a torn-down field.\n const timer = setTimeout(() => {\n this.resetTimers.delete(timer);\n this.fields().forEach((field) => field.resetState());\n });\n this.resetTimers.add(timer);\n }\n\n private readonly resetTimers = new Set<ReturnType<typeof setTimeout>>();\n\n constructor() {\n inject(DestroyRef).onDestroy(() => this.resetTimers.forEach((timer) => clearTimeout(timer)));\n }\n\n private remainingErrors(): RdxFormErrors {\n const errors = this.errors() ?? {};\n const cleared = this.clearedNames();\n const result: RdxFormErrors = {};\n for (const key of Object.keys(errors)) {\n if (!cleared.has(key)) {\n result[key] = errors[key];\n }\n }\n return result;\n }\n}\n","import { NgModule } from '@angular/core';\nimport { RdxFormRoot } from './src/form-root';\n\nexport * from './src/form-root';\n\nexport const _importsForm = [RdxFormRoot];\n\n@NgModule({\n imports: [..._importsForm],\n exports: [..._importsForm]\n})\nexport class RdxFormModule {}\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-form.mjs","sources":["../../../packages/primitives/form/src/form-root.ts","../../../packages/primitives/form/index.ts","../../../packages/primitives/form/radix-ng-primitives-form.ts"],"sourcesContent":["import {\n computed,\n DestroyRef,\n Directive,\n ElementRef,\n inject,\n input,\n linkedSignal,\n output,\n signal,\n Signal\n} from '@angular/core';\nimport { createContext, RDX_DEFAULT_VALIDATION_MODE, RdxValidationMode } from '@radix-ng/primitives/core';\n\n/** A normalized external-error map: each field name maps to its message(s) in display order. */\nexport type RdxFormErrors = Record<string, string | string[]>;\n\n/** Payload of {@link RdxFormRoot.onFormSubmit}. Mirrors Base UI's `(values, eventDetails)` shape. */\nexport interface RdxFormSubmitEvent {\n /** The form's values serialized from `FormData` (repeated names collapse into arrays). */\n values: Record<string, FormDataEntryValue | FormDataEntryValue[]>;\n /** Why the submit happened (Base UI `SubmitEventDetails.reason`). Always `'none'` for a user submit. */\n reason: 'none';\n /** The original native submit event (already `preventDefault`-ed). */\n event: SubmitEvent;\n}\n\n/**\n * What a {@link RdxFieldRoot} registers with an enclosing Form. Structural `() =>` accessors keep the\n * Form entry free of any import from `field` (acyclic ng-packagr graph: `field` → `form`).\n */\nexport interface RdxFormFieldRegistration {\n /** The field's `name` (key external errors match against), or `undefined`. */\n name: () => string | undefined;\n /** The field's **actual** invalid state (ungated, includes external errors) — drives the submit guard\n * and `anyInvalid`. */\n invalid: () => boolean;\n /** The field's **displayed** tri-state validity, gated by its `validationMode` — drives the form's\n * presentation `data-invalid` so it stays neutral on load while its fields are. `null` = neutral. */\n displayValid?: () => boolean | null;\n /** Whether the field is dirty. */\n dirty: () => boolean;\n /** Whether the field is touched. */\n touched: () => boolean;\n /** Focus the field's control (by its `controlId`). */\n focus: () => void;\n /** Reset the field's interaction state (touched/dirty/focused → false, filled re-sync). */\n resetState: () => void;\n}\n\n/**\n * External owner of form-level state (e.g. the Signal Forms `[rdxSignalForm]` adapter). Mirrors Field's\n * `RdxFieldState` seam one level up. Each member is optional. The aggregate accessors (`dirty`/`touched`/\n * `submitting`) take over the corresponding form-level state; `invalid` is **merged** with the field\n * registry (so a real registered-field error still counts); the per-name accessors route a field's client\n * state by `name`. Kept as framework-free `() =>` accessors (no `@angular/forms/signals` dependency). See\n * ADR 0004.\n */\nexport interface RdxFormState {\n invalid?: () => boolean;\n dirty?: () => boolean;\n touched?: () => boolean;\n submitting?: () => boolean;\n /**\n * Per-name **client** validation errors (e.g. `rdxSignalForm`'s Signal Forms name-routing). Surfaced\n * through the Form's `clientErrorsFor` channel and gated by `validationMode` like any client validity.\n * Independent of the Form's `errors` input (server errors), which stays eager.\n */\n errorsFor?: (name: string) => string[];\n /**\n * Per-name `touched` / `dirty` for a name-routed field. Lets a `rdxFieldRoot` that has only a bare\n * `[formField]` control (no `rdxSignalField` / `rdxFieldControl`) still reveal its error on blur under\n * `validationMode=\"onBlur\"`/`\"onChange\"` — the field reads its interaction state from here.\n */\n touchedFor?: (name: string) => boolean;\n dirtyFor?: (name: string) => boolean;\n}\n\nexport interface RdxFormRootContext {\n /**\n * **Client** validation errors routed by a form-level provider (e.g. `rdxSignalForm`'s Signal Forms\n * name-routing). These are gated by `validationMode` like any client validity — adding `rdxSignalForm`\n * must not change error-display timing.\n */\n clientErrorsFor: (name: string | undefined) => string[];\n /** **Server/external** errors from the Form's `errors` input. Shown eagerly (not gated). */\n externalErrorsFor: (name: string | undefined) => string[];\n /** Per-name `touched` / `dirty` from a form-level provider (`rdxSignalForm`); `false` when none. */\n touchedFor: (name: string | undefined) => boolean;\n dirtyFor: (name: string | undefined) => boolean;\n notifyEdited: (name: string | undefined) => void;\n /**\n * Whether a submit has been attempted (set before the validity check on submit, cleared on reset).\n * A presentation-timing seam: an adapter can reveal a field's error after a submit attempt without the\n * field having been touched, so the consumer never hand-rolls \"mark touched on submit\". Base UI's\n * submit-attempt state, kept at the form level.\n */\n submitAttempted: Signal<boolean>;\n /** The form's default validation-display mode; a `rdxFieldRoot` may override it per field. */\n validationMode: Signal<RdxValidationMode>;\n /** Registers a field; returns its unregister callback. */\n register: (field: RdxFormFieldRegistration) => () => void;\n setStateProvider: (provider: RdxFormState | null) => RdxFormState | null;\n /**\n * Identity-checked teardown: roll the slot back to `previous` only if `provider` is still active,\n * so an old adapter's destroy can't clobber a newer one (create-before-destroy on a view swap).\n */\n clearStateProvider: (provider: RdxFormState | null, previous: RdxFormState | null) => void;\n hasStateProvider: Signal<boolean>;\n}\n\nconst formRootContext = (): RdxFormRootContext => {\n const root = inject(RdxFormRoot);\n return {\n clientErrorsFor: (name: string | undefined) => root.clientErrorsFor(name),\n externalErrorsFor: (name: string | undefined) => root.externalErrorsFor(name),\n touchedFor: (name: string | undefined) => root.touchedFor(name),\n dirtyFor: (name: string | undefined) => root.dirtyFor(name),\n notifyEdited: (name: string | undefined) => root.notifyEdited(name),\n submitAttempted: root.submitAttempted,\n validationMode: root.validationMode,\n register: (field: RdxFormFieldRegistration) => root.register(field),\n setStateProvider: (provider: RdxFormState | null) => root.setStateProvider(provider),\n clearStateProvider: (provider: RdxFormState | null, previous: RdxFormState | null) =>\n root.clearStateProvider(provider, previous),\n hasStateProvider: root.hasStateProvider\n };\n};\n\nexport const [injectFormRootContext, provideFormRootContext] = createContext<RdxFormRootContext>(\n 'RdxFormRoot',\n 'components/form'\n);\n\n/** Collapses `FormData` into a plain object; repeated names collapse into arrays. */\nfunction serializeFormData(data: FormData): Record<string, FormDataEntryValue | FormDataEntryValue[]> {\n const values: Record<string, FormDataEntryValue | FormDataEntryValue[]> = {};\n data.forEach((value, key) => {\n // `Object.hasOwn`, not `key in values` — a control named after an Object.prototype member\n // (`toString`, `constructor`, …) must not be misread as a duplicate.\n if (Object.hasOwn(values, key)) {\n const existing = values[key];\n values[key] = Array.isArray(existing) ? [...existing, value] : [existing, value];\n } else {\n values[key] = value;\n }\n });\n return values;\n}\n\n/**\n * The top of the forms layer cake: a single directive on the native `<form>` element that aggregates\n * field state, maps external (server) errors onto fields by `name`, intercepts submit (values-as-object,\n * focus the first invalid field), and resets field interaction state on native `reset`. It owns no\n * values and runs no validation — Angular form systems (or Field inputs) remain the source of validity.\n *\n * @group Components\n */\n@Directive({\n selector: 'form[rdxFormRoot]',\n exportAs: 'rdxFormRoot',\n providers: [provideFormRootContext(formRootContext)],\n host: {\n novalidate: '',\n '[attr.data-invalid]': 'anyDisplayedInvalid() ? \"\" : undefined',\n '[attr.data-dirty]': 'anyDirty() ? \"\" : undefined',\n '[attr.data-touched]': 'anyTouched() ? \"\" : undefined',\n '[attr.data-submitting]': 'submitting() ? \"\" : undefined',\n '(submit)': 'onSubmit($event)',\n '(reset)': 'onReset()'\n }\n})\nexport class RdxFormRoot {\n private readonly form = inject<ElementRef<HTMLFormElement>>(ElementRef).nativeElement;\n\n /** External/server validation errors keyed by `Field.Root` `name`. */\n readonly errors = input<RdxFormErrors | null | undefined>();\n\n /**\n * When fields reveal their validity (error styling + message). The control/adapter always reports the\n * actual state; this decides *when* the Field surfaces it. A `rdxFieldRoot` can override it per field.\n * Server errors (`errors` above) always show regardless. Defaults to `'onBlur'`.\n *\n * @group Props\n * @defaultValue 'onBlur'\n */\n readonly validationMode = input<RdxValidationMode>(RDX_DEFAULT_VALIDATION_MODE);\n\n /** Emits the remaining error map after a field's external error is cleared by a user edit (or reset). */\n readonly onClearErrors = output<RdxFormErrors>();\n\n /** Emits the serialized form values when a valid form is submitted. */\n readonly onFormSubmit = output<RdxFormSubmitEvent>();\n\n private readonly fields = signal<RdxFormFieldRegistration[]>([]);\n\n private readonly stateProvider = signal<RdxFormState | null>(null);\n\n /** Whether an external adapter currently owns form-level state. */\n readonly hasStateProvider = computed(() => this.stateProvider() !== null);\n\n /**\n * Names whose external error has been cleared by a user edit. Reset to empty whenever a new `errors`\n * object reference is assigned — the server just spoke, so everything it said is live again.\n */\n private readonly clearedNames = linkedSignal<RdxFormErrors | null | undefined, Set<string>>({\n source: this.errors,\n computation: () => new Set<string>()\n });\n\n /** The `errors` input minus cleared names, normalized to `string[]`. */\n private readonly effectiveErrors = computed<Record<string, string[]>>(() => {\n const errors = this.errors() ?? {};\n const cleared = this.clearedNames();\n const result: Record<string, string[]> = {};\n for (const key of Object.keys(errors)) {\n if (cleared.has(key)) {\n continue;\n }\n const value = errors[key];\n result[key] = Array.isArray(value) ? value : [value];\n }\n return result;\n });\n\n /** **Actual** aggregate invalidity (eager) — drives the submit guard / focus-first-invalid and is the\n * value to read in app logic. Merges a form-level provider with the field registry. */\n readonly anyInvalid = computed(() => this.aggregate('invalid'));\n readonly anyDirty = computed(() => this.aggregate('dirty'));\n readonly anyTouched = computed(() => this.aggregate('touched'));\n readonly submitting = computed(() => this.stateProvider()?.submitting?.() ?? false);\n\n /**\n * **Displayed** aggregate invalidity — the source for the host `data-invalid` (a presentation\n * attribute). A field counts only once its own `validationMode` reveals it (`displayValid() === false`),\n * so the form stays **neutral on load** while its fields are, instead of leaking the gated state.\n * Distinct from {@link anyInvalid} (actual, eager).\n *\n * When **any** display-aware field is registered, those fields are the *authoritative* displayed\n * source and win outright — a form-level provider's aggregate `invalid()` is **not** added on top\n * (it would contradict a field that overrode its own `validationMode` to stay neutral; and the\n * fields already reflect that provider's per-name state). The provider fallback applies only when no\n * display-aware field carries the state, and then conservatively — under `validationMode=\"always\"`\n * or after a submit attempt, never from `anyTouched`.\n */\n readonly anyDisplayedInvalid = computed(() => {\n const fields = this.fields();\n if (fields.some((field) => field.displayValid?.() === false)) {\n return true;\n }\n if (fields.some((field) => field.displayValid !== undefined)) {\n return false;\n }\n const providerInvalid = this.stateProvider()?.invalid?.() ?? false;\n return providerInvalid && (this.validationMode() === 'always' || this.submitAttempted());\n });\n\n /**\n * Whether a submit has been attempted on this form, exposed to fields via the context. Set true at the\n * very start of {@link onSubmit} (before the validity check, so a field whose `validationMode` defers\n * display, e.g. `onBlur`, reveals its error in time to block the submit) and cleared on native reset.\n */\n readonly submitAttempted = signal(false);\n\n /**\n * Resolve a boolean aggregate. For `dirty` / `touched` a registered provider's accessor wins, else OR\n * over the registry. For **`invalid`** the two are **merged** (`provider || registry`): a registered\n * field's actual invalidity — e.g. a server `[errors]` entry — must still count (and block submit) even\n * when a form-level provider (`rdxSignalForm`) reports the client model valid.\n */\n private aggregate(key: 'invalid' | 'dirty' | 'touched'): boolean {\n const accessor = this.stateProvider()?.[key];\n const fromRegistry = this.fields().some((field) => field[key]());\n if (key === 'invalid') {\n return (accessor?.() ?? false) || fromRegistry;\n }\n return accessor ? accessor() : fromRegistry;\n }\n\n /** Client validation errors from a form-level provider (`rdxSignalForm`); `[]` when none. Gated. */\n clientErrorsFor(name: string | undefined): string[] {\n if (!name) {\n return [];\n }\n return this.stateProvider()?.errorsFor?.(name) ?? [];\n }\n\n /** Per-name `touched` from a form-level provider (`rdxSignalForm`); `false` when none. */\n touchedFor(name: string | undefined): boolean {\n return name ? (this.stateProvider()?.touchedFor?.(name) ?? false) : false;\n }\n\n /** Per-name `dirty` from a form-level provider (`rdxSignalForm`); `false` when none. */\n dirtyFor(name: string | undefined): boolean {\n return name ? (this.stateProvider()?.dirtyFor?.(name) ?? false) : false;\n }\n\n /**\n * Server/external errors from the `errors` input (eager). A separate channel from {@link clientErrorsFor}:\n * the `errors` input always applies, even alongside a form-level client provider (`rdxSignalForm`), so\n * adding `rdxSignalForm` never disables your server errors.\n */\n externalErrorsFor(name: string | undefined): string[] {\n if (!name) {\n return [];\n }\n return this.effectiveErrors()[name] ?? [];\n }\n\n /** Clears a field's server error (the `errors` input) after a user edit, emitting the remaining map.\n * Client provider errors (`rdxSignalForm`) are not affected — Signal Forms re-validates them itself. */\n notifyEdited(name: string | undefined): void {\n if (!name) {\n return;\n }\n const errors = this.errors() ?? {};\n if (!Object.hasOwn(errors, name) || this.clearedNames().has(name)) {\n return;\n }\n this.clearedNames.update((set) => new Set(set).add(name));\n this.onClearErrors.emit(this.remainingErrors());\n }\n\n register(field: RdxFormFieldRegistration): () => void {\n this.fields.update((list) => [...list, field]);\n return () => this.fields.update((list) => list.filter((item) => item !== field));\n }\n\n /** Register (or clear with `null`) an external owner of form-level state; returns the previous one. */\n setStateProvider(provider: RdxFormState | null): RdxFormState | null {\n const previous = this.stateProvider();\n this.stateProvider.set(provider);\n return previous;\n }\n\n /**\n * Identity-checked teardown — roll back to `previous` only if `provider` is still active, so an\n * old adapter's destroy can't clobber a newer one (create-before-destroy on a view swap).\n */\n clearStateProvider(provider: RdxFormState | null, previous: RdxFormState | null): void {\n if (this.stateProvider() === provider) {\n this.stateProvider.set(previous);\n }\n }\n\n onSubmit(event: SubmitEvent): void {\n // SPA submits never navigate; never stopPropagation so Reactive Forms `(ngSubmit)` keeps firing.\n event.preventDefault();\n\n // Record the attempt *before* reading validity. Display-gating uses `submitAttempted` to reveal\n // errors (a `validationMode` of `onBlur`/`onSubmit`), but the Form aggregates *actual* invalidity,\n // so a pristine invalid form is blocked and its errors revealed instead of submitting.\n this.submitAttempted.set(true);\n\n if (this.aggregate('invalid')) {\n // Focus the first invalid registered field (DOM order); provider-only invalid has none to focus.\n this.fields()\n .find((field) => field.invalid())\n ?.focus();\n return;\n }\n\n const values = serializeFormData(new FormData(this.form));\n this.onFormSubmit.emit({ values, reason: 'none', event });\n }\n\n onReset(): void {\n // Don't prevent the native reset — control values revert on their own.\n this.submitAttempted.set(false);\n // Clear server errors (the `errors` input); client provider errors re-validate themselves.\n const keys = Object.keys(this.errors() ?? {});\n const hadVisible = keys.some((key) => !this.clearedNames().has(key));\n if (keys.length) {\n this.clearedNames.set(new Set(keys));\n }\n if (hadVisible) {\n this.onClearErrors.emit({});\n }\n // Values revert asynchronously relative to the reset event — re-sync field state next macrotask.\n // Read the registry fresh inside the callback (fields may register/unregister in between), and\n // cancel on destroy so resetState never runs against a torn-down field.\n const timer = setTimeout(() => {\n this.resetTimers.delete(timer);\n this.fields().forEach((field) => field.resetState());\n });\n this.resetTimers.add(timer);\n }\n\n private readonly resetTimers = new Set<ReturnType<typeof setTimeout>>();\n\n constructor() {\n inject(DestroyRef).onDestroy(() => this.resetTimers.forEach((timer) => clearTimeout(timer)));\n }\n\n private remainingErrors(): RdxFormErrors {\n const errors = this.errors() ?? {};\n const cleared = this.clearedNames();\n const result: RdxFormErrors = {};\n for (const key of Object.keys(errors)) {\n if (!cleared.has(key)) {\n result[key] = errors[key];\n }\n }\n return result;\n }\n}\n","import { NgModule } from '@angular/core';\nimport { RdxFormRoot } from './src/form-root';\n\nexport * from './src/form-root';\n\nexport const _importsForm = [RdxFormRoot];\n\n@NgModule({\n imports: [..._importsForm],\n exports: [..._importsForm]\n})\nexport class RdxFormModule {}\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './index';\n"],"names":[],"mappings":"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"}