ember-headless-form 1.0.0-beta.0 → 1.0.0-beta.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/-private/components/control/input.js +1 -1
- package/dist/-private/components/control/input.js.map +1 -1
- package/dist/-private/components/control/select.js +1 -1
- package/dist/-private/components/control/select.js.map +1 -1
- package/dist/-private/components/control/textarea.js +1 -1
- package/dist/-private/components/control/textarea.js.map +1 -1
- package/dist/-private/components/field.d.ts +4 -0
- package/dist/-private/components/field.js +1 -1
- package/dist/-private/components/field.js.map +1 -1
- package/dist/components/headless-form.d.ts +4 -0
- package/dist/components/headless-form.js +1 -1
- package/dist/components/headless-form.js.map +1 -1
- package/package.json +1 -1
@@ -5,7 +5,7 @@ import Component from '@glimmer/component';
|
|
5
5
|
import { assert } from '@ember/debug';
|
6
6
|
import { action } from '@ember/object';
|
7
7
|
|
8
|
-
var TEMPLATE = precompileTemplate("<input\n name={{@name}}\n type={{@type}}\n value={{@value}}\n id={{@fieldId}}\n aria-invalid={{if @invalid \'true\'}}\n aria-
|
8
|
+
var TEMPLATE = precompileTemplate("<input\n name={{@name}}\n type={{@type}}\n value={{@value}}\n id={{@fieldId}}\n aria-invalid={{if @invalid \'true\'}}\n aria-describedby={{if @invalid @errorId}}\n ...attributes\n {{on \'input\' this.handleInput}}\n/>");
|
9
9
|
|
10
10
|
var _class;
|
11
11
|
|
@@ -1 +1 @@
|
|
1
|
-
{"version":3,"file":"input.js","sources":["../../../../src/-private/components/control/input.hbs.js","../../../../src/-private/components/control/input.ts"],"sourcesContent":["import { precompileTemplate } from \"@ember/template-compilation\";\nexport default precompileTemplate(\"<input\\n name={{@name}}\\n type={{@type}}\\n value={{@value}}\\n id={{@fieldId}}\\n aria-invalid={{if @invalid \\'true\\'}}\\n aria-
|
1
|
+
{"version":3,"file":"input.js","sources":["../../../../src/-private/components/control/input.hbs.js","../../../../src/-private/components/control/input.ts"],"sourcesContent":["import { precompileTemplate } from \"@ember/template-compilation\";\nexport default precompileTemplate(\"<input\\n name={{@name}}\\n type={{@type}}\\n value={{@value}}\\n id={{@fieldId}}\\n aria-invalid={{if @invalid \\'true\\'}}\\n aria-describedby={{if @invalid @errorId}}\\n ...attributes\\n {{on \\'input\\' this.handleInput}}\\n/>\")","import Component from '@glimmer/component';\nimport { assert } from '@ember/debug';\nimport { action } from '@ember/object';\n\n// Possible values for the input type, see https://developer.mozilla.org/en-US/docs/Web/HTML/Element/input#input_types\n// for the sake of completeness, we list all here, with some commented out that are better handled elsewhere, or not at all...\nexport type InputType =\n // | 'button' - not useful as a control component\n // | 'checkbox' - handled separately, for handling `checked` correctly and operating with true boolean values\n | 'color'\n | 'date'\n | 'datetime-local'\n | 'email'\n // | 'file' - would need special handling\n | 'hidden'\n // | 'image' - not useful as a control component\n | 'month'\n | 'number'\n | 'password'\n // | 'radio' - handled separately, for handling groups or radio buttons\n | 'range'\n // | 'reset' - would need special handling\n | 'search'\n // | 'submit' - not useful as a control component\n | 'tel'\n | 'text'\n | 'time'\n | 'url'\n | 'week';\n\nexport interface HeadlessFormControlInputComponentSignature {\n Element: HTMLInputElement;\n Args: {\n /**\n * The `type` of the `<input>` element, by default `text`.\n *\n * Note that certain types should not be used, as they have dedicated control components:\n * - `checkbox`\n * - `radio`\n *\n * Also these types are not useful to use as input controls:\n * - `button`\n * - `file`\n * - `image`\n * - `reset`\n * - `submit`\n *\n * @see https://developer.mozilla.org/en-US/docs/Web/HTML/Element/input#input_types\n */\n type?: InputType;\n\n // the following are private arguments curried by the component helper, so users will never have to use those\n\n /*\n * @internal\n */\n value: string;\n\n /*\n * @internal\n */\n name: string;\n\n /*\n * @internal\n */\n fieldId: string;\n\n /*\n * @internal\n */\n setValue: (value: string) => void;\n\n /*\n * @internal\n */\n invalid: boolean;\n\n /*\n * @internal\n */\n errorId: string;\n };\n}\n\nexport default class HeadlessFormControlInputComponent extends Component<HeadlessFormControlInputComponentSignature> {\n constructor(\n owner: unknown,\n args: HeadlessFormControlInputComponentSignature['Args']\n ) {\n assert(\n `input component does not support @type=\"${args.type}\" as there is a dedicated component for this. Please use the \\`field.${args.type}\\` instead!`,\n args.type === undefined ||\n // TS would guard us against using an unsupported `InputType`, but for JS consumers we add a dev-only runtime check here\n !['checkbox', 'radio'].includes(args.type as string)\n );\n\n super(owner, args);\n }\n\n get type(): InputType {\n return this.args.type ?? 'text';\n }\n\n @action\n handleInput(e: Event | InputEvent): void {\n assert('Expected HTMLInputElement', e.target instanceof HTMLInputElement);\n this.args.setValue(e.target.value);\n }\n}\n"],"names":["precompileTemplate","HeadlessFormControlInputComponent","Component","constructor","owner","args","assert","type","undefined","includes","handleInput","e","target","HTMLInputElement","setValue","value","action"],"mappings":";;;;;;;AACA,eAAeA,kBAAkB,CAAC,mOAAmO,CAAC;;;;ACGtQ;AACA;AAAA,IAgFqBC,iCAAiC,IAAvC,MAAA,GAAA,MAAMA,iCAAiC,SAASC,SAAS,CAA6C;AACnHC,EAAAA,WAAW,CACTC,KAAc,EACdC,IAAwD,EACxD;AACAC,IAAAA,MAAM,CACH,CAAA,wCAAA,EAA0CD,IAAI,CAACE,IAAK,CAAuEF,qEAAAA,EAAAA,IAAI,CAACE,IAAK,aAAY,EAClJF,IAAI,CAACE,IAAI,KAAKC,SAAS;AACrB;AACA,IAAA,CAAC,CAAC,UAAU,EAAE,OAAO,CAAC,CAACC,QAAQ,CAACJ,IAAI,CAACE,IAAI,CAAW,CACvD,CAAA;AAED,IAAA,KAAK,CAACH,KAAK,EAAEC,IAAI,CAAC,CAAA;AACpB,GAAA;AAEA,EAAA,IAAIE,IAAI,GAAc;AACpB,IAAA,OAAO,IAAI,CAACF,IAAI,CAACE,IAAI,IAAI,MAAM,CAAA;AACjC,GAAA;EAGAG,WAAW,CAACC,CAAqB,EAAQ;IACvCL,MAAM,CAAC,2BAA2B,EAAEK,CAAC,CAACC,MAAM,YAAYC,gBAAgB,CAAC,CAAA;IACzE,IAAI,CAACR,IAAI,CAACS,QAAQ,CAACH,CAAC,CAACC,MAAM,CAACG,KAAK,CAAC,CAAA;AACpC,GAAA;AACF,CAAC,+DALEC,MAAM,CAAA,EAAA,MAAA,CAAA,wBAAA,CAAA,MAAA,CAAA,SAAA,EAAA,aAAA,CAAA,EAAA,MAAA,CAAA,SAAA,CAAA,GAAA,MAAA,EAAA;AAnB6C,oBAAA,CAAA,QAAA,EAAA,iCAAA,CAAA;;;;"}
|
@@ -6,7 +6,7 @@ import Component from '@glimmer/component';
|
|
6
6
|
import { action } from '@ember/object';
|
7
7
|
import HeadlessFormControlSelectOptionComponent from './select/option.js';
|
8
8
|
|
9
|
-
var TEMPLATE = precompileTemplate("<select\n name={{@name}}\n value={{@value}}\n id={{@fieldId}}\n aria-invalid={{if @invalid \'true\'}}\n aria-
|
9
|
+
var TEMPLATE = precompileTemplate("<select\n name={{@name}}\n value={{@value}}\n id={{@fieldId}}\n aria-invalid={{if @invalid \'true\'}}\n aria-describedby={{if @invalid @errorId}}\n ...attributes\n {{on \'input\' this.handleInput}}\n>\n {{yield\n (hash\n Option=(component\n (ensure-safe-component this.OptionComponent) selected=@value\n )\n )\n }}\n</select>");
|
10
10
|
|
11
11
|
var _class;
|
12
12
|
let HeadlessFormControlSelectComponent = (_class = class HeadlessFormControlSelectComponent extends Component {
|
@@ -1 +1 @@
|
|
1
|
-
{"version":3,"file":"select.js","sources":["../../../../src/-private/components/control/select.hbs.js","../../../../src/-private/components/control/select.ts"],"sourcesContent":["import { precompileTemplate } from \"@ember/template-compilation\";\nexport default precompileTemplate(\"<select\\n name={{@name}}\\n value={{@value}}\\n id={{@fieldId}}\\n aria-invalid={{if @invalid \\'true\\'}}\\n aria-
|
1
|
+
{"version":3,"file":"select.js","sources":["../../../../src/-private/components/control/select.hbs.js","../../../../src/-private/components/control/select.ts"],"sourcesContent":["import { precompileTemplate } from \"@ember/template-compilation\";\nexport default precompileTemplate(\"<select\\n name={{@name}}\\n value={{@value}}\\n id={{@fieldId}}\\n aria-invalid={{if @invalid \\'true\\'}}\\n aria-describedby={{if @invalid @errorId}}\\n ...attributes\\n {{on \\'input\\' this.handleInput}}\\n>\\n {{yield\\n (hash\\n Option=(component\\n (ensure-safe-component this.OptionComponent) selected=@value\\n )\\n )\\n }}\\n</select>\")","import Component from '@glimmer/component';\nimport { action } from '@ember/object';\n\nimport OptionComponent from './select/option';\n\nimport type { WithBoundArgs } from '@glint/template';\n\nexport interface HeadlessFormControlSelectComponentSignature {\n Element: HTMLSelectElement;\n Args: {\n // the following are private arguments curried by the component helper, so users will never have to use those\n\n /*\n * @internal\n */\n value: string;\n\n /*\n * @internal\n */\n name: string;\n\n /*\n * @internal\n */\n fieldId: string;\n\n /*\n * @internal\n */\n setValue: (value: string) => void;\n\n /*\n * @internal\n */\n invalid: boolean;\n\n /*\n * @internal\n */\n errorId: string;\n };\n Blocks: {\n default: [\n {\n Option: WithBoundArgs<typeof OptionComponent, 'selected'>;\n }\n ];\n };\n}\n\nexport default class HeadlessFormControlSelectComponent extends Component<HeadlessFormControlSelectComponentSignature> {\n OptionComponent = OptionComponent;\n\n @action\n handleInput(e: Event | InputEvent): void {\n this.args.setValue((e.target as HTMLSelectElement).value);\n }\n}\n"],"names":["precompileTemplate","HeadlessFormControlSelectComponent","Component","OptionComponent","handleInput","e","args","setValue","target","value","action"],"mappings":";;;;;;;;AACA,eAAeA,kBAAkB,CAAC,uWAAuW,CAAC;;;ACE5V,IAgDzBC,kCAAkC,IAAxC,MAAA,GAAA,MAAMA,kCAAkC,SAASC,SAAS,CAA8C;AAAA,EAAA,WAAA,CAAA,GAAA,IAAA,EAAA;AAAA,IAAA,KAAA,CAAA,GAAA,IAAA,CAAA,CAAA;AAAA,IAAA,eAAA,CAAA,IAAA,EAAA,iBAAA,EACnGC,wCAAe,CAAA,CAAA;AAAA,GAAA;EAGjCC,WAAW,CAACC,CAAqB,EAAQ;IACvC,IAAI,CAACC,IAAI,CAACC,QAAQ,CAAEF,CAAC,CAACG,MAAM,CAAuBC,KAAK,CAAC,CAAA;AAC3D,GAAA;AACF,CAAC,+DAJEC,MAAM,CAAA,EAAA,MAAA,CAAA,wBAAA,CAAA,MAAA,CAAA,SAAA,EAAA,aAAA,CAAA,EAAA,MAAA,CAAA,SAAA,CAAA,GAAA,MAAA,EAAA;AAH8C,oBAAA,CAAA,QAAA,EAAA,kCAAA,CAAA;;;;"}
|
@@ -4,7 +4,7 @@ import { precompileTemplate } from '@ember/template-compilation';
|
|
4
4
|
import Component from '@glimmer/component';
|
5
5
|
import { action } from '@ember/object';
|
6
6
|
|
7
|
-
var TEMPLATE = precompileTemplate("<textarea\n name={{@name}}\n id={{@fieldId}}\n aria-invalid={{if @invalid \'true\'}}\n aria-
|
7
|
+
var TEMPLATE = precompileTemplate("<textarea\n name={{@name}}\n id={{@fieldId}}\n aria-invalid={{if @invalid \'true\'}}\n aria-describedby={{if @invalid @errorId}}\n ...attributes\n {{on \'input\' this.handleInput}}\n>{{@value}}</textarea>");
|
8
8
|
|
9
9
|
var _class;
|
10
10
|
let HeadlessFormControlTextareaComponent = (_class = class HeadlessFormControlTextareaComponent extends Component {
|
@@ -1 +1 @@
|
|
1
|
-
{"version":3,"file":"textarea.js","sources":["../../../../src/-private/components/control/textarea.hbs.js","../../../../src/-private/components/control/textarea.ts"],"sourcesContent":["import { precompileTemplate } from \"@ember/template-compilation\";\nexport default precompileTemplate(\"<textarea\\n name={{@name}}\\n id={{@fieldId}}\\n aria-invalid={{if @invalid \\'true\\'}}\\n aria-
|
1
|
+
{"version":3,"file":"textarea.js","sources":["../../../../src/-private/components/control/textarea.hbs.js","../../../../src/-private/components/control/textarea.ts"],"sourcesContent":["import { precompileTemplate } from \"@ember/template-compilation\";\nexport default precompileTemplate(\"<textarea\\n name={{@name}}\\n id={{@fieldId}}\\n aria-invalid={{if @invalid \\'true\\'}}\\n aria-describedby={{if @invalid @errorId}}\\n ...attributes\\n {{on \\'input\\' this.handleInput}}\\n>{{@value}}</textarea>\")","import Component from '@glimmer/component';\nimport { action } from '@ember/object';\n\nexport interface HeadlessFormControlTextareaComponentSignature {\n Element: HTMLTextAreaElement;\n Args: {\n // the following are private arguments curried by the component helper, so users will never have to use those\n\n /*\n * @internal\n */\n value: string;\n\n /*\n * @internal\n */\n name: string;\n\n /*\n * @internal\n */\n fieldId: string;\n\n /*\n * @internal\n */\n setValue: (value: string) => void;\n\n /*\n * @internal\n */\n invalid: boolean;\n\n /*\n * @internal\n */\n errorId: string;\n };\n}\n\nexport default class HeadlessFormControlTextareaComponent extends Component<HeadlessFormControlTextareaComponentSignature> {\n @action\n handleInput(e: Event | InputEvent): void {\n this.args.setValue((e.target as HTMLTextAreaElement).value);\n }\n}\n"],"names":["precompileTemplate","HeadlessFormControlTextareaComponent","Component","handleInput","e","args","setValue","target","value","action"],"mappings":";;;;;;AACA,eAAeA,kBAAkB,CAAC,oNAAoN,CAAC;;;ACAhN,IAuClBC,oCAAoC,IAA1C,MAAA,GAAA,MAAMA,oCAAoC,SAASC,SAAS,CAAgD;EAEzHC,WAAW,CAACC,CAAqB,EAAQ;IACvC,IAAI,CAACC,IAAI,CAACC,QAAQ,CAAEF,CAAC,CAACG,MAAM,CAAyBC,KAAK,CAAC,CAAA;AAC7D,GAAA;AACF,CAAC,+DAJEC,MAAM,CAAA,EAAA,MAAA,CAAA,wBAAA,CAAA,MAAA,CAAA,SAAA,EAAA,aAAA,CAAA,EAAA,MAAA,CAAA,SAAA,CAAA,GAAA,MAAA,EAAA;AADgD,oBAAA,CAAA,QAAA,EAAA,oCAAA,CAAA;;;;"}
|
@@ -95,6 +95,10 @@ interface HeadlessFormFieldComponentSignature<DATA extends UserData, KEY extends
|
|
95
95
|
* You can use this to customize your markup, e.g. apply HTML classes for error styling.
|
96
96
|
*/
|
97
97
|
isInvalid: boolean;
|
98
|
+
/**
|
99
|
+
* An array of raw ValidationError objects, for custom rendering of error output
|
100
|
+
*/
|
101
|
+
rawErrors?: ValidationError<DATA[KEY]>[];
|
98
102
|
/**
|
99
103
|
* When calling this action, validation will be triggered.
|
100
104
|
*
|
@@ -14,7 +14,7 @@ import HeadlessFormControlTextareaComponent from './control/textarea.js';
|
|
14
14
|
import HeadlessFormErrorsComponent from './errors.js';
|
15
15
|
import LabelComponent from './label.js';
|
16
16
|
|
17
|
-
var TEMPLATE = precompileTemplate("{{#let\n (unique-id)\n (unique-id)\n (fn @set @name)\n (fn @triggerValidationFor @name)\n as |fieldId errorId setValue triggerValidation|\n}}\n {{yield\n (hash\n Label=(component\n (ensure-safe-component this.LabelComponent) fieldId=fieldId\n )\n Input=(component\n (ensure-safe-component this.InputComponent)\n name=@name\n fieldId=fieldId\n errorId=errorId\n value=this.valueAsString\n setValue=this.setValue\n invalid=this.hasErrors\n )\n Checkbox=(component\n (ensure-safe-component this.CheckboxComponent)\n name=@name\n fieldId=fieldId\n errorId=errorId\n value=this.valueAsBoolean\n setValue=this.setValue\n invalid=this.hasErrors\n )\n Select=(component\n (ensure-safe-component this.SelectComponent)\n name=@name\n fieldId=fieldId\n errorId=errorId\n value=this.valueAsString\n setValue=this.setValue\n invalid=this.hasErrors\n )\n Textarea=(component\n (ensure-safe-component this.TextareaComponent)\n name=@name\n fieldId=fieldId\n errorId=errorId\n value=this.valueAsString\n setValue=this.setValue\n invalid=this.hasErrors\n )\n Radio=(component\n (ensure-safe-component this.RadioComponent)\n name=@name\n selected=this.valueAsString\n setValue=this.setValue\n )\n value=this.value\n setValue=setValue\n id=fieldId\n errorId=errorId\n Errors=(if\n this.errors\n (component\n (ensure-safe-component this.ErrorsComponent)\n errors=this.errors\n id=errorId\n )\n )\n isInvalid=this.hasErrors\n triggerValidation=triggerValidation\n captureEvents=(modifier\n this.CaptureEventsModifier\n event=(if this.hasErrors @fieldRevalidationEvent @fieldValidationEvent)\n triggerValidation=triggerValidation\n )\n )\n }}\n{{/let}}");
|
17
|
+
var TEMPLATE = precompileTemplate("{{#let\n (unique-id)\n (unique-id)\n (fn @set @name)\n (fn @triggerValidationFor @name)\n as |fieldId errorId setValue triggerValidation|\n}}\n {{yield\n (hash\n Label=(component\n (ensure-safe-component this.LabelComponent) fieldId=fieldId\n )\n Input=(component\n (ensure-safe-component this.InputComponent)\n name=@name\n fieldId=fieldId\n errorId=errorId\n value=this.valueAsString\n setValue=this.setValue\n invalid=this.hasErrors\n )\n Checkbox=(component\n (ensure-safe-component this.CheckboxComponent)\n name=@name\n fieldId=fieldId\n errorId=errorId\n value=this.valueAsBoolean\n setValue=this.setValue\n invalid=this.hasErrors\n )\n Select=(component\n (ensure-safe-component this.SelectComponent)\n name=@name\n fieldId=fieldId\n errorId=errorId\n value=this.valueAsString\n setValue=this.setValue\n invalid=this.hasErrors\n )\n Textarea=(component\n (ensure-safe-component this.TextareaComponent)\n name=@name\n fieldId=fieldId\n errorId=errorId\n value=this.valueAsString\n setValue=this.setValue\n invalid=this.hasErrors\n )\n Radio=(component\n (ensure-safe-component this.RadioComponent)\n name=@name\n selected=this.valueAsString\n setValue=this.setValue\n )\n value=this.value\n setValue=setValue\n id=fieldId\n errorId=errorId\n Errors=(if\n this.errors\n (component\n (ensure-safe-component this.ErrorsComponent)\n errors=this.errors\n id=errorId\n )\n )\n isInvalid=this.hasErrors\n rawErrors=this.errors\n triggerValidation=triggerValidation\n captureEvents=(modifier\n this.CaptureEventsModifier\n event=(if this.hasErrors @fieldRevalidationEvent @fieldValidationEvent)\n triggerValidation=triggerValidation\n )\n )\n }}\n{{/let}}");
|
18
18
|
|
19
19
|
var _class;
|
20
20
|
let HeadlessFormFieldComponent = (_class = class HeadlessFormFieldComponent extends Component {
|
@@ -1 +1 @@
|
|
1
|
-
{"version":3,"file":"field.js","sources":["../../../src/-private/components/field.hbs.js","../../../src/-private/components/field.ts"],"sourcesContent":["import { precompileTemplate } from \"@ember/template-compilation\";\nexport default precompileTemplate(\"{{#let\\n (unique-id)\\n (unique-id)\\n (fn @set @name)\\n (fn @triggerValidationFor @name)\\n as |fieldId errorId setValue triggerValidation|\\n}}\\n {{yield\\n (hash\\n Label=(component\\n (ensure-safe-component this.LabelComponent) fieldId=fieldId\\n )\\n Input=(component\\n (ensure-safe-component this.InputComponent)\\n name=@name\\n fieldId=fieldId\\n errorId=errorId\\n value=this.valueAsString\\n setValue=this.setValue\\n invalid=this.hasErrors\\n )\\n Checkbox=(component\\n (ensure-safe-component this.CheckboxComponent)\\n name=@name\\n fieldId=fieldId\\n errorId=errorId\\n value=this.valueAsBoolean\\n setValue=this.setValue\\n invalid=this.hasErrors\\n )\\n Select=(component\\n (ensure-safe-component this.SelectComponent)\\n name=@name\\n fieldId=fieldId\\n errorId=errorId\\n value=this.valueAsString\\n setValue=this.setValue\\n invalid=this.hasErrors\\n )\\n Textarea=(component\\n (ensure-safe-component this.TextareaComponent)\\n name=@name\\n fieldId=fieldId\\n errorId=errorId\\n value=this.valueAsString\\n setValue=this.setValue\\n invalid=this.hasErrors\\n )\\n Radio=(component\\n (ensure-safe-component this.RadioComponent)\\n name=@name\\n selected=this.valueAsString\\n setValue=this.setValue\\n )\\n value=this.value\\n setValue=setValue\\n id=fieldId\\n errorId=errorId\\n Errors=(if\\n this.errors\\n (component\\n (ensure-safe-component this.ErrorsComponent)\\n errors=this.errors\\n id=errorId\\n )\\n )\\n isInvalid=this.hasErrors\\n triggerValidation=triggerValidation\\n captureEvents=(modifier\\n this.CaptureEventsModifier\\n event=(if this.hasErrors @fieldRevalidationEvent @fieldValidationEvent)\\n triggerValidation=triggerValidation\\n )\\n )\\n }}\\n{{/let}}\")","import Component from '@glimmer/component';\nimport { assert } from '@ember/debug';\nimport { action, get } from '@ember/object';\n\nimport CaptureEventsModifier from '../modifiers/capture-events';\nimport CheckboxComponent from './control/checkbox';\nimport InputComponent from './control/input';\nimport RadioComponent from './control/radio';\nimport SelectComponent from './control/select';\nimport TextareaComponent from './control/textarea';\nimport ErrorsComponent from './errors';\nimport LabelComponent from './label';\n\nimport type { CaptureEventsModifierSignature } from '../modifiers/capture-events';\nimport type {\n ErrorRecord,\n FieldValidateCallback,\n FormData,\n FormKey,\n RegisterFieldCallback,\n UnregisterFieldCallback,\n UserData,\n ValidationError,\n} from '../types';\nimport type { ModifierLike, WithBoundArgs } from '@glint/template';\n\nexport interface HeadlessFormFieldComponentSignature<\n DATA extends UserData,\n KEY extends FormKey<FormData<DATA>> = FormKey<FormData<DATA>>\n> {\n Args: {\n /**\n * The name of your field, which must match a property of the `@data` passed to the form\n */\n name: KEY;\n\n /**\n * Provide a custom validation function, that operates only on this specific field. Eventual validation errors are merged with native validation errors to determine the effective set of errors rendered for the field.\n *\n * Return undefined when no validation errors are present, otherwise an array of (one or multiple) `ValidationError`s.\n */\n validate?: FieldValidateCallback<FormData<DATA>, KEY>;\n\n // the following are private arguments curried by the component helper, so users will never have to use those\n\n /*\n * @internal\n */\n data: FormData<DATA>;\n\n /*\n * @internal\n */\n set: (key: KEY, value: DATA[KEY]) => void;\n\n /*\n * @internal\n */\n errors?: ErrorRecord<DATA, KEY>;\n\n /*\n * @internal\n */\n registerField: RegisterFieldCallback<FormData<DATA>, KEY>;\n\n /*\n * @internal\n */\n unregisterField: UnregisterFieldCallback<FormData<DATA>, KEY>;\n\n /*\n * @internal\n */\n triggerValidationFor(name: KEY): Promise<void>;\n\n /*\n * @internal\n */\n fieldValidationEvent: 'focusout' | 'change' | 'input' | undefined;\n\n /*\n * @internal\n */\n fieldRevalidationEvent: 'focusout' | 'change' | 'input' | undefined;\n };\n Blocks: {\n default: [\n {\n /**\n * Yielded component that renders the `<label>` element.\n */\n Label: WithBoundArgs<typeof LabelComponent, 'fieldId'>;\n\n /**\n * Yielded control component that renders an `<input>` element.\n */\n Input: WithBoundArgs<\n typeof InputComponent,\n 'name' | 'fieldId' | 'value' | 'setValue' | 'invalid' | 'errorId'\n >;\n\n /**\n * Yielded control component that renders an `<input type=\"checkbox\">` element.\n */\n Checkbox: WithBoundArgs<\n typeof CheckboxComponent,\n 'name' | 'fieldId' | 'value' | 'setValue' | 'invalid' | 'errorId'\n >;\n\n /**\n * Yielded control component that renders a single radio control.\n *\n * Use multiple to define a radio group. It further yields components to render `Input` and `Label`.\n */\n Radio: WithBoundArgs<\n typeof RadioComponent,\n 'name' | 'selected' | 'setValue'\n >;\n\n /**\n * Yielded control component that renders a `<select>` element.\n */\n Select: WithBoundArgs<\n typeof SelectComponent,\n 'name' | 'fieldId' | 'value' | 'setValue' | 'invalid' | 'errorId'\n >;\n\n /**\n * Yielded control component that renders a `<textarea>` element.\n */\n Textarea: WithBoundArgs<\n typeof TextareaComponent,\n 'name' | 'fieldId' | 'value' | 'setValue' | 'invalid' | 'errorId'\n >;\n\n /**\n * The current value of the field's form data.\n *\n * If you don't use one of the supplied control components, then use this to pass the value to your custom component.\n */\n value: DATA[KEY];\n\n /**\n * Action to update the (internal) form data for this field.\n *\n * If you don't use one of the supplied control components, then use this to update the value whenever your custom component's value has changed.\n */\n setValue: (value: DATA[KEY]) => void;\n\n /**\n * Unique ID of this field, used to associate the control with its label.\n *\n * If you don't use the supplied components, then you can use this as the `id` of the control and the `for` attribute of the `<label>`.\n */\n id: string;\n\n /**\n * Unique error ID of this field, used to associate the control with its validation error message.\n *\n * If you don't use the supplied components, then you can use this as the `id` of the validation error element and the `aria-errormessage` or `aria-describedby` attribute of the control.\n */\n errorId: string;\n\n /**\n * Yielded component that renders all validation error messages if there are any.\n *\n * In non-block mode it will render all messages by default. In block-mode, it yields all `ValidationError` objects for you to customize the rendering.\n */\n Errors?: WithBoundArgs<\n typeof ErrorsComponent<DATA[KEY]>,\n 'errors' | 'id'\n >;\n\n /**\n * Will be `true` when validation was triggered and this field is invalid.\n *\n * You can use this to customize your markup, e.g. apply HTML classes for error styling.\n */\n isInvalid: boolean;\n\n /**\n * When calling this action, validation will be triggered.\n *\n * Can be used for custom controls that don't emit the `@validateOn` events that would normally trigger a dynamic validation.\n */\n triggerValidation: () => void;\n\n /**\n * Yielded modifier that when applied to the control element or any other element wrapping it will be able to recognize the `@validateOn` events and associate them to this field.\n *\n * This is only needed for very special cases, where the control is not a native form control or does not have the `@name` of the field assigned to the `name` attribute of the control.\n */\n captureEvents: WithBoundArgs<\n ModifierLike<CaptureEventsModifierSignature>,\n 'event' | 'triggerValidation'\n >;\n }\n ];\n };\n}\n\nexport default class HeadlessFormFieldComponent<\n DATA extends FormData,\n KEY extends FormKey<FormData<DATA>> = FormKey<FormData<DATA>>\n> extends Component<HeadlessFormFieldComponentSignature<DATA, KEY>> {\n LabelComponent = LabelComponent;\n InputComponent = InputComponent;\n CheckboxComponent = CheckboxComponent;\n ErrorsComponent = ErrorsComponent<DATA[KEY]>;\n SelectComponent = SelectComponent;\n TextareaComponent = TextareaComponent;\n RadioComponent = RadioComponent;\n CaptureEventsModifier = CaptureEventsModifier;\n\n constructor(\n owner: unknown,\n args: HeadlessFormFieldComponentSignature<DATA, KEY>['Args']\n ) {\n super(owner, args);\n\n assert(\n 'Nested property paths in @name are not supported.',\n typeof this.args.name !== 'string' || !this.args.name.includes('.')\n );\n\n this.args.registerField(this.args.name, {\n validate: this.args.validate,\n });\n }\n\n willDestroy(): void {\n this.args.unregisterField(this.args.name);\n\n super.willDestroy();\n }\n\n get value(): DATA[KEY] {\n // when @mutableData is set, data is something we don't control, i.e. might require old-school get() to be on the safe side\n // we do not want to support nested property paths for now though, see the constructor assertion!\n return get(this.args.data, this.args.name) as DATA[KEY];\n }\n\n get errors(): ValidationError<DATA[KEY]>[] | undefined {\n return this.args.errors?.[this.args.name];\n }\n\n get hasErrors(): boolean {\n return this.errors !== undefined;\n }\n\n get valueAsString(): string | undefined {\n assert(\n `Only string values are expected for ${String(\n this.args.name\n )}, but you passed ${typeof this.value}`,\n typeof this.value === 'undefined' || typeof this.value === 'string'\n );\n\n return this.value;\n }\n\n get valueAsBoolean(): boolean | undefined {\n assert(\n `Only boolean values are expected for ${String(\n this.args.name\n )}, but you passed ${typeof this.value}`,\n typeof this.value === 'undefined' || typeof this.value === 'boolean'\n );\n\n return this.value;\n }\n\n @action\n setValue(value: unknown): void {\n this.args.set(this.args.name, value as DATA[KEY]);\n }\n}\n"],"names":["precompileTemplate","HeadlessFormFieldComponent","Component","constructor","owner","args","LabelComponent","InputComponent","CheckboxComponent","ErrorsComponent","SelectComponent","TextareaComponent","RadioComponent","CaptureEventsModifier","assert","name","includes","registerField","validate","willDestroy","unregisterField","value","get","data","errors","hasErrors","undefined","valueAsString","String","valueAsBoolean","setValue","set","action"],"mappings":"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"}
|
1
|
+
{"version":3,"file":"field.js","sources":["../../../src/-private/components/field.hbs.js","../../../src/-private/components/field.ts"],"sourcesContent":["import { precompileTemplate } from \"@ember/template-compilation\";\nexport default precompileTemplate(\"{{#let\\n (unique-id)\\n (unique-id)\\n (fn @set @name)\\n (fn @triggerValidationFor @name)\\n as |fieldId errorId setValue triggerValidation|\\n}}\\n {{yield\\n (hash\\n Label=(component\\n (ensure-safe-component this.LabelComponent) fieldId=fieldId\\n )\\n Input=(component\\n (ensure-safe-component this.InputComponent)\\n name=@name\\n fieldId=fieldId\\n errorId=errorId\\n value=this.valueAsString\\n setValue=this.setValue\\n invalid=this.hasErrors\\n )\\n Checkbox=(component\\n (ensure-safe-component this.CheckboxComponent)\\n name=@name\\n fieldId=fieldId\\n errorId=errorId\\n value=this.valueAsBoolean\\n setValue=this.setValue\\n invalid=this.hasErrors\\n )\\n Select=(component\\n (ensure-safe-component this.SelectComponent)\\n name=@name\\n fieldId=fieldId\\n errorId=errorId\\n value=this.valueAsString\\n setValue=this.setValue\\n invalid=this.hasErrors\\n )\\n Textarea=(component\\n (ensure-safe-component this.TextareaComponent)\\n name=@name\\n fieldId=fieldId\\n errorId=errorId\\n value=this.valueAsString\\n setValue=this.setValue\\n invalid=this.hasErrors\\n )\\n Radio=(component\\n (ensure-safe-component this.RadioComponent)\\n name=@name\\n selected=this.valueAsString\\n setValue=this.setValue\\n )\\n value=this.value\\n setValue=setValue\\n id=fieldId\\n errorId=errorId\\n Errors=(if\\n this.errors\\n (component\\n (ensure-safe-component this.ErrorsComponent)\\n errors=this.errors\\n id=errorId\\n )\\n )\\n isInvalid=this.hasErrors\\n rawErrors=this.errors\\n triggerValidation=triggerValidation\\n captureEvents=(modifier\\n this.CaptureEventsModifier\\n event=(if this.hasErrors @fieldRevalidationEvent @fieldValidationEvent)\\n triggerValidation=triggerValidation\\n )\\n )\\n }}\\n{{/let}}\")","import Component from '@glimmer/component';\nimport { assert } from '@ember/debug';\nimport { action, get } from '@ember/object';\n\nimport CaptureEventsModifier from '../modifiers/capture-events';\nimport CheckboxComponent from './control/checkbox';\nimport InputComponent from './control/input';\nimport RadioComponent from './control/radio';\nimport SelectComponent from './control/select';\nimport TextareaComponent from './control/textarea';\nimport ErrorsComponent from './errors';\nimport LabelComponent from './label';\n\nimport type { CaptureEventsModifierSignature } from '../modifiers/capture-events';\nimport type {\n ErrorRecord,\n FieldValidateCallback,\n FormData,\n FormKey,\n RegisterFieldCallback,\n UnregisterFieldCallback,\n UserData,\n ValidationError,\n} from '../types';\nimport type { ModifierLike, WithBoundArgs } from '@glint/template';\n\nexport interface HeadlessFormFieldComponentSignature<\n DATA extends UserData,\n KEY extends FormKey<FormData<DATA>> = FormKey<FormData<DATA>>\n> {\n Args: {\n /**\n * The name of your field, which must match a property of the `@data` passed to the form\n */\n name: KEY;\n\n /**\n * Provide a custom validation function, that operates only on this specific field. Eventual validation errors are merged with native validation errors to determine the effective set of errors rendered for the field.\n *\n * Return undefined when no validation errors are present, otherwise an array of (one or multiple) `ValidationError`s.\n */\n validate?: FieldValidateCallback<FormData<DATA>, KEY>;\n\n // the following are private arguments curried by the component helper, so users will never have to use those\n\n /*\n * @internal\n */\n data: FormData<DATA>;\n\n /*\n * @internal\n */\n set: (key: KEY, value: DATA[KEY]) => void;\n\n /*\n * @internal\n */\n errors?: ErrorRecord<DATA, KEY>;\n\n /*\n * @internal\n */\n registerField: RegisterFieldCallback<FormData<DATA>, KEY>;\n\n /*\n * @internal\n */\n unregisterField: UnregisterFieldCallback<FormData<DATA>, KEY>;\n\n /*\n * @internal\n */\n triggerValidationFor(name: KEY): Promise<void>;\n\n /*\n * @internal\n */\n fieldValidationEvent: 'focusout' | 'change' | 'input' | undefined;\n\n /*\n * @internal\n */\n fieldRevalidationEvent: 'focusout' | 'change' | 'input' | undefined;\n };\n Blocks: {\n default: [\n {\n /**\n * Yielded component that renders the `<label>` element.\n */\n Label: WithBoundArgs<typeof LabelComponent, 'fieldId'>;\n\n /**\n * Yielded control component that renders an `<input>` element.\n */\n Input: WithBoundArgs<\n typeof InputComponent,\n 'name' | 'fieldId' | 'value' | 'setValue' | 'invalid' | 'errorId'\n >;\n\n /**\n * Yielded control component that renders an `<input type=\"checkbox\">` element.\n */\n Checkbox: WithBoundArgs<\n typeof CheckboxComponent,\n 'name' | 'fieldId' | 'value' | 'setValue' | 'invalid' | 'errorId'\n >;\n\n /**\n * Yielded control component that renders a single radio control.\n *\n * Use multiple to define a radio group. It further yields components to render `Input` and `Label`.\n */\n Radio: WithBoundArgs<\n typeof RadioComponent,\n 'name' | 'selected' | 'setValue'\n >;\n\n /**\n * Yielded control component that renders a `<select>` element.\n */\n Select: WithBoundArgs<\n typeof SelectComponent,\n 'name' | 'fieldId' | 'value' | 'setValue' | 'invalid' | 'errorId'\n >;\n\n /**\n * Yielded control component that renders a `<textarea>` element.\n */\n Textarea: WithBoundArgs<\n typeof TextareaComponent,\n 'name' | 'fieldId' | 'value' | 'setValue' | 'invalid' | 'errorId'\n >;\n\n /**\n * The current value of the field's form data.\n *\n * If you don't use one of the supplied control components, then use this to pass the value to your custom component.\n */\n value: DATA[KEY];\n\n /**\n * Action to update the (internal) form data for this field.\n *\n * If you don't use one of the supplied control components, then use this to update the value whenever your custom component's value has changed.\n */\n setValue: (value: DATA[KEY]) => void;\n\n /**\n * Unique ID of this field, used to associate the control with its label.\n *\n * If you don't use the supplied components, then you can use this as the `id` of the control and the `for` attribute of the `<label>`.\n */\n id: string;\n\n /**\n * Unique error ID of this field, used to associate the control with its validation error message.\n *\n * If you don't use the supplied components, then you can use this as the `id` of the validation error element and the `aria-errormessage` or `aria-describedby` attribute of the control.\n */\n errorId: string;\n\n /**\n * Yielded component that renders all validation error messages if there are any.\n *\n * In non-block mode it will render all messages by default. In block-mode, it yields all `ValidationError` objects for you to customize the rendering.\n */\n Errors?: WithBoundArgs<\n typeof ErrorsComponent<DATA[KEY]>,\n 'errors' | 'id'\n >;\n\n /**\n * Will be `true` when validation was triggered and this field is invalid.\n *\n * You can use this to customize your markup, e.g. apply HTML classes for error styling.\n */\n isInvalid: boolean;\n\n /**\n * An array of raw ValidationError objects, for custom rendering of error output\n */\n rawErrors?: ValidationError<DATA[KEY]>[];\n\n /**\n * When calling this action, validation will be triggered.\n *\n * Can be used for custom controls that don't emit the `@validateOn` events that would normally trigger a dynamic validation.\n */\n triggerValidation: () => void;\n\n /**\n * Yielded modifier that when applied to the control element or any other element wrapping it will be able to recognize the `@validateOn` events and associate them to this field.\n *\n * This is only needed for very special cases, where the control is not a native form control or does not have the `@name` of the field assigned to the `name` attribute of the control.\n */\n captureEvents: WithBoundArgs<\n ModifierLike<CaptureEventsModifierSignature>,\n 'event' | 'triggerValidation'\n >;\n }\n ];\n };\n}\n\nexport default class HeadlessFormFieldComponent<\n DATA extends FormData,\n KEY extends FormKey<FormData<DATA>> = FormKey<FormData<DATA>>\n> extends Component<HeadlessFormFieldComponentSignature<DATA, KEY>> {\n LabelComponent = LabelComponent;\n InputComponent = InputComponent;\n CheckboxComponent = CheckboxComponent;\n ErrorsComponent = ErrorsComponent<DATA[KEY]>;\n SelectComponent = SelectComponent;\n TextareaComponent = TextareaComponent;\n RadioComponent = RadioComponent;\n CaptureEventsModifier = CaptureEventsModifier;\n\n constructor(\n owner: unknown,\n args: HeadlessFormFieldComponentSignature<DATA, KEY>['Args']\n ) {\n super(owner, args);\n\n assert(\n 'Nested property paths in @name are not supported.',\n typeof this.args.name !== 'string' || !this.args.name.includes('.')\n );\n\n this.args.registerField(this.args.name, {\n validate: this.args.validate,\n });\n }\n\n willDestroy(): void {\n this.args.unregisterField(this.args.name);\n\n super.willDestroy();\n }\n\n get value(): DATA[KEY] {\n // when @mutableData is set, data is something we don't control, i.e. might require old-school get() to be on the safe side\n // we do not want to support nested property paths for now though, see the constructor assertion!\n return get(this.args.data, this.args.name) as DATA[KEY];\n }\n\n get errors(): ValidationError<DATA[KEY]>[] | undefined {\n return this.args.errors?.[this.args.name];\n }\n\n get hasErrors(): boolean {\n return this.errors !== undefined;\n }\n\n get valueAsString(): string | undefined {\n assert(\n `Only string values are expected for ${String(\n this.args.name\n )}, but you passed ${typeof this.value}`,\n typeof this.value === 'undefined' || typeof this.value === 'string'\n );\n\n return this.value;\n }\n\n get valueAsBoolean(): boolean | undefined {\n assert(\n `Only boolean values are expected for ${String(\n this.args.name\n )}, but you passed ${typeof this.value}`,\n typeof this.value === 'undefined' || typeof this.value === 'boolean'\n );\n\n return this.value;\n }\n\n @action\n setValue(value: unknown): void {\n this.args.set(this.args.name, value as DATA[KEY]);\n }\n}\n"],"names":["precompileTemplate","HeadlessFormFieldComponent","Component","constructor","owner","args","LabelComponent","InputComponent","CheckboxComponent","ErrorsComponent","SelectComponent","TextareaComponent","RadioComponent","CaptureEventsModifier","assert","name","includes","registerField","validate","willDestroy","unregisterField","value","get","data","errors","hasErrors","undefined","valueAsString","String","valueAsBoolean","setValue","set","action"],"mappings":"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"}
|
@@ -65,6 +65,10 @@ interface HeadlessFormComponentSignature<DATA extends UserData, SUBMISSION_VALUE
|
|
65
65
|
* Will be true if at least one form field is invalid.
|
66
66
|
*/
|
67
67
|
isInvalid: boolean;
|
68
|
+
/**
|
69
|
+
* An ErrorRecord, for custom rendering of error output
|
70
|
+
*/
|
71
|
+
rawErrors?: ErrorRecord<DATA>;
|
68
72
|
}
|
69
73
|
];
|
70
74
|
};
|
@@ -15,7 +15,7 @@ import { TrackedObject } from 'tracked-built-ins';
|
|
15
15
|
import HeadlessFormFieldComponent from '../-private/components/field.js';
|
16
16
|
import { mergeErrorRecord } from '../-private/utils.js';
|
17
17
|
|
18
|
-
var TEMPLATE = precompileTemplate("<form\n novalidate\n ...attributes\n {{this.registerForm}}\n {{on \'submit\' this.onSubmit}}\n {{(if\n this.fieldValidationEvent\n (modifier this.on this.fieldValidationEvent this.handleFieldValidation)\n )}}\n {{(if\n this.fieldRevalidationEvent\n (modifier this.on this.fieldRevalidationEvent this.handleFieldRevalidation)\n )}}\n>\n {{yield\n (hash\n Field=(component\n (ensure-safe-component this.FieldComponent)\n data=this.internalData\n set=this.set\n errors=this.visibleErrors\n registerField=this.registerField\n unregisterField=this.unregisterField\n triggerValidationFor=this.handleFieldValidation\n fieldValidationEvent=this.fieldValidationEvent\n fieldRevalidationEvent=this.fieldRevalidationEvent\n )\n validationState=this.validationState\n submissionState=this.submissionState\n isInvalid=this.hasValidationErrors\n )\n }}\n</form>");
|
18
|
+
var TEMPLATE = precompileTemplate("<form\n novalidate\n ...attributes\n {{this.registerForm}}\n {{on \'submit\' this.onSubmit}}\n {{(if\n this.fieldValidationEvent\n (modifier this.on this.fieldValidationEvent this.handleFieldValidation)\n )}}\n {{(if\n this.fieldRevalidationEvent\n (modifier this.on this.fieldRevalidationEvent this.handleFieldRevalidation)\n )}}\n>\n {{yield\n (hash\n Field=(component\n (ensure-safe-component this.FieldComponent)\n data=this.internalData\n set=this.set\n errors=this.visibleErrors\n registerField=this.registerField\n unregisterField=this.unregisterField\n triggerValidationFor=this.handleFieldValidation\n fieldValidationEvent=this.fieldValidationEvent\n fieldRevalidationEvent=this.fieldRevalidationEvent\n )\n validationState=this.validationState\n submissionState=this.submissionState\n isInvalid=this.hasValidationErrors\n rawErrors=this.visibleErrors\n )\n }}\n</form>");
|
19
19
|
|
20
20
|
var _class, _descriptor, _class3, _descriptor2, _descriptor3, _descriptor4;
|
21
21
|
/**
|
@@ -1 +1 @@
|
|
1
|
-
{"version":3,"file":"headless-form.js","sources":["../../src/components/headless-form.hbs.js","../../src/components/headless-form.ts"],"sourcesContent":["import { precompileTemplate } from \"@ember/template-compilation\";\nexport default precompileTemplate(\"<form\\n novalidate\\n ...attributes\\n {{this.registerForm}}\\n {{on \\'submit\\' this.onSubmit}}\\n {{(if\\n this.fieldValidationEvent\\n (modifier this.on this.fieldValidationEvent this.handleFieldValidation)\\n )}}\\n {{(if\\n this.fieldRevalidationEvent\\n (modifier this.on this.fieldRevalidationEvent this.handleFieldRevalidation)\\n )}}\\n>\\n {{yield\\n (hash\\n Field=(component\\n (ensure-safe-component this.FieldComponent)\\n data=this.internalData\\n set=this.set\\n errors=this.visibleErrors\\n registerField=this.registerField\\n unregisterField=this.unregisterField\\n triggerValidationFor=this.handleFieldValidation\\n fieldValidationEvent=this.fieldValidationEvent\\n fieldRevalidationEvent=this.fieldRevalidationEvent\\n )\\n validationState=this.validationState\\n submissionState=this.submissionState\\n isInvalid=this.hasValidationErrors\\n )\\n }}\\n</form>\")","import Component from '@glimmer/component';\nimport { tracked } from '@glimmer/tracking';\nimport { assert, warn } from '@ember/debug';\nimport { on } from '@ember/modifier';\nimport { action, set } from '@ember/object';\n\nimport { TrackedAsyncData } from 'ember-async-data';\nimport { modifier } from 'ember-modifier';\nimport { TrackedObject } from 'tracked-built-ins';\n\nimport FieldComponent from '../-private/components/field';\nimport { mergeErrorRecord } from '../-private/utils';\n\nimport type {\n ErrorRecord,\n FieldRegistrationData,\n FieldValidateCallback,\n FormData,\n FormKey,\n FormValidateCallback,\n UserData,\n ValidationError,\n} from '../-private/types';\nimport type { ModifierLike, WithBoundArgs } from '@glint/template';\n\ntype ValidateOn = 'change' | 'focusout' | 'submit' | 'input';\n\nexport interface HeadlessFormComponentSignature<\n DATA extends UserData,\n SUBMISSION_VALUE\n> {\n Element: HTMLFormElement;\n Args: {\n /**\n * The initial data the form will use to pre-populate the fields.\n *\n * Make sure the type of it matches what you expect the form to represent, i.e. the names of all form fields match the properties of the data and their respective types!\n */\n data?: DATA;\n\n /**\n * By default the data you pass as `@data` is never mutated by the form component, you will only receive the updated data (a copy) on successful submission via `@onSubmit`.\n * Setting this to `'mutable'` will mutate the data whenever the user updates a field. This is especially useful when the data already has some \"buffering\" behavior, like with `ember-changeset`.\n */\n dataMode?: 'mutable' | 'immutable';\n\n /**\n * Specify when to dynamically validate a field before even submitting the whole form. By default this is `submit`, which means no dynamic validation happens. Another common setting is to validate on `focusout`.\n */\n validateOn?: ValidateOn;\n\n /**\n * Specify when to revalidate a previously validated field that is invalid. By default this happens on `change`. Another common setting is to revalidate on `input`.\n * Mind that text-based inputs don't emit the `change` event on every key stroke, but only on focusing out. Changing this to `input` would make text-based inputs revalidate on every key stroke.\n */\n revalidateOn?: ValidateOn;\n\n /**\n * Provide a custom validation function, that operates on all fields of the form. Eventual validation errors are merged with native validation errors to determine the effective set of errors rendered in the form.\n *\n * Return undefined when no validation errors are present, otherwise an `ErrorRecord` mapping (one or multiple) `ValidationError`s to each invalid field.\n */\n validate?: FormValidateCallback<DATA>;\n\n /**\n * Called when the user has submitted the form and no validation errors have been determined. Receives the new form data, or in case of `@dataMode=\"mutable\"` the original data object.\n */\n onSubmit?: (\n data: FormData<DATA>\n ) => SUBMISSION_VALUE | Promise<SUBMISSION_VALUE>;\n\n /**\n * Called when the user tried to submit the form, but validation failed. Receives the new data (or in case of `@dataMode=\"mutable\"` the original data object), and the record of validation errors by field.\n */\n onInvalid?: (\n data: FormData<DATA>,\n errors: ErrorRecord<FormData<DATA>>\n ) => void;\n };\n Blocks: {\n default: [\n {\n /**\n * Field component to define the fields of your form. It yields the further components for the form control, label and validation error.\n */\n Field: WithBoundArgs<\n typeof FieldComponent<DATA>,\n | 'data'\n | 'set'\n | 'errors'\n | 'registerField'\n | 'unregisterField'\n | 'triggerValidationFor'\n | 'fieldValidationEvent'\n | 'fieldRevalidationEvent'\n >;\n\n /**\n * The (async) validation state as `TrackedAsyncData`.\n *\n * Use derived state like `.isPending` to render the UI conditionally.\n */\n validationState?: TrackedAsyncData<ErrorRecord<DATA>>;\n\n /**\n * The (async) submission state as `TrackedAsyncData`.\n *\n * Use derived state like `.isPending` to render the UI conditionally.\n */\n submissionState?: TrackedAsyncData<SUBMISSION_VALUE>;\n\n /**\n * Will be true if at least one form field is invalid.\n */\n isInvalid: boolean;\n }\n ];\n };\n}\n\n/**\n * This internal data structure maintains information about each field that is registered to the form by `registerField`.\n */\nclass FieldData<\n DATA extends FormData,\n KEY extends FormKey<DATA> = FormKey<DATA>\n> {\n constructor(fieldRegistration: FieldRegistrationData<DATA, KEY>) {\n this.validate = fieldRegistration.validate;\n }\n\n /**\n * tracked state that enabled a dynamic validation of a field *before* the whole form is submitted, e.g. by `@validateOn=\"blur\" and the blur event being triggered for that particular field.\n */\n @tracked validationEnabled = false;\n\n /**\n * The *field* level validation callback passed to the field as in `<form.field @name=\"foo\" @validate={{this.validateCallback}}>`\n */\n validate?: FieldValidateCallback<DATA, KEY>;\n}\n\n/**\n * Headless form component.\n *\n * @example\n * Usage example:\n *\n * ```hbs\n * <HeadlessForm\n * @data={{this.data}}\n * @validateOn=\"focusout\"\n * @revalidateOn=\"input\"\n * @onSubmit={{this.doSomething}}\n * as |form|\n * >\n * <form.Field @name=\"firstName\" as |field|>\n * <div>\n * <field.Label>First name</field.Label>\n * <field.Input\n * required\n * />\n * <field.errors />\n * </div>\n * </form.Field>\n *\n * <button\n * type=\"submit\"\n * >Submit</button>\n * </HeadlessForm>\n * ```\n */\nexport default class HeadlessFormComponent<\n DATA extends UserData,\n SUBMISSION_VALUE\n> extends Component<HeadlessFormComponentSignature<DATA, SUBMISSION_VALUE>> {\n FieldComponent = FieldComponent<DATA>;\n\n // we cannot use (modifier \"on\") directly in the template due to https://github.com/emberjs/ember.js/issues/19869\n on = on;\n\n formElement?: HTMLFormElement;\n\n registerForm = modifier((el: HTMLFormElement, _p: []) => {\n this.formElement = el;\n }) as unknown as ModifierLike<unknown>; // @todo getting Glint errors without this. Try again with Glint 1.0 (beta)!\n\n /**\n * A copy of the passed `@data` stored internally, which is only passed back to the component consumer after a (successful) form submission.\n */\n internalData: DATA =\n this.args.dataMode == 'mutable' && this.args.data\n ? this.args.data\n : (new TrackedObject(this.args.data ?? {}) as DATA);\n\n fields = new Map<FormKey<FormData<DATA>>, FieldData<FormData<DATA>>>();\n\n @tracked validationState?: TrackedAsyncData<ErrorRecord<DATA>>;\n @tracked submissionState?: TrackedAsyncData<SUBMISSION_VALUE>;\n\n /**\n * When this is set to true by submitting the form, eventual validation errors are show for *all* field, regardless of their individual dynamic validation status in `FieldData#validationEnabled`\n */\n @tracked showAllValidations = false;\n\n get validateOn(): ValidateOn {\n return this.args.validateOn ?? 'submit';\n }\n\n get revalidateOn(): ValidateOn {\n return this.args.revalidateOn ?? 'change';\n }\n\n /**\n * Return the event type that will be listened on for dynamic validation (i.e. *before* submitting)\n */\n get fieldValidationEvent(): 'focusout' | 'change' | 'input' | undefined {\n const { validateOn } = this;\n\n return validateOn === 'submit'\n ? // no need for dynamic validation, as validation always happens on submit\n undefined\n : validateOn;\n }\n\n /**\n * Return the event type that will be listened on for dynamic *re*validation, i.e. updating the validation status of a field that has been previously marked as invalid\n */\n get fieldRevalidationEvent(): 'focusout' | 'change' | 'input' | undefined {\n const { validateOn, revalidateOn } = this;\n\n return revalidateOn === 'submit'\n ? // no need for dynamic validation, as validation always happens on submit\n undefined\n : // when validation happens more frequently than revalidation, then we can ignore revalidation, because the validation handler will already cover us\n validateOn === 'input' ||\n (validateOn === 'change' && revalidateOn === 'focusout') ||\n validateOn === revalidateOn\n ? undefined\n : revalidateOn;\n }\n\n /**\n * Return true if validation has happened (by submitting or by an `@validateOn` event being triggered) and at least one field is invalid\n */\n get hasValidationErrors(): boolean {\n const { validationState } = this;\n\n // Only consider validation errors for which we actually have a field rendered\n return validationState?.isResolved\n ? Object.keys(validationState.value).some((name) =>\n this.fields.has(name as FormKey<FormData<DATA>>)\n )\n : false;\n }\n\n /**\n * Call the passed validation callbacks, defined both on the whole form as well as on field level, and return the merged result for all fields.\n */\n async validate(): Promise<ErrorRecord<FormData<DATA>>> {\n const nativeValidation = this.validateNative();\n const customFormValidation = await this.args.validate?.(\n this.internalData,\n Array.from(this.fields.keys())\n );\n const customFieldValidations: ErrorRecord<FormData<DATA>>[] = [];\n\n for (const [name, field] of this.fields) {\n const fieldValidationResult = await field.validate?.(\n this.internalData[name],\n name,\n this.internalData\n );\n\n if (fieldValidationResult) {\n customFieldValidations.push({\n [name]: fieldValidationResult,\n } as ErrorRecord<FormData<DATA>>);\n }\n }\n\n return mergeErrorRecord(\n nativeValidation,\n customFormValidation,\n ...customFieldValidations\n );\n }\n\n async _validate(): Promise<ErrorRecord<FormData<DATA>>> {\n const promise = this.validate();\n\n this.validationState = new TrackedAsyncData(promise, this);\n\n return promise;\n }\n\n validateNative(): ErrorRecord<FormData<DATA>> | undefined {\n const form = this.formElement;\n\n assert(\n 'Form element expected to be present. If you see this, please report it as a bug to ember-headless-form!',\n form\n );\n\n if (form.checkValidity()) {\n return;\n }\n\n const errors: ErrorRecord<FormData<DATA>> = {};\n\n for (const el of form.elements) {\n // This is just to make TS happy, as we need to access properties on el that only form elements have, but elements in `form.elements` are just typed as plain `Element`. Should never occur in reality.\n assert(\n 'Unexpected form element. If you see this, please report it as a bug to ember-headless-form!',\n el instanceof HTMLInputElement ||\n el instanceof HTMLTextAreaElement ||\n el instanceof HTMLSelectElement ||\n el instanceof HTMLButtonElement ||\n el instanceof HTMLFieldSetElement ||\n el instanceof HTMLObjectElement ||\n el instanceof HTMLOutputElement\n );\n\n if (el.validity.valid) {\n continue;\n }\n\n const name = el.name as FormKey<FormData<DATA>>;\n\n if (this.fields.has(name)) {\n errors[name] = [\n {\n type: 'native',\n value: this.internalData[name],\n message: el.validationMessage,\n },\n ];\n } else {\n warn(\n `An invalid form element with name \"${name}\" was detected, but this name is not used as a form field. It will be ignored for validation. Make sure to apply the correct name to custom form elements that participate in form validation!`,\n { id: 'headless-form.invalid-control-for-unknown-field' }\n );\n }\n }\n\n return errors;\n }\n\n /**\n * Return a mapping of field to validation errors, for all fields that are invalid *and* for which validation errors should be visible.\n * Validation errors will be visible for a certain field, if validation errors for *all* fields are visible, which is the case when trying to submit the form,\n * or when that field has triggered the event given by `@validateOn` for showing validation errors before submitting, e.g. on blur.\n */\n get visibleErrors(): ErrorRecord<FormData<DATA>> | undefined {\n if (!this.validationState?.isResolved) {\n return undefined;\n }\n\n const visibleErrors: ErrorRecord<FormData<DATA>> = {};\n\n for (const [field, errors] of Object.entries(\n this.validationState.value\n ) as [\n FormKey<FormData<DATA>>,\n ValidationError<FormData<DATA>[FormKey<FormData<DATA>>]>[]\n ][]) {\n if (this.showErrorsFor(field)) {\n visibleErrors[field] = errors;\n }\n }\n\n return visibleErrors;\n }\n\n /**\n * Given a field name, return if eventual errors for the field should be visible. See `visibleErrors` for further details.\n */\n showErrorsFor(field: FormKey<FormData<DATA>>): boolean {\n return (\n this.showAllValidations ||\n (this.fields.get(field)?.validationEnabled ?? false)\n );\n }\n\n @action\n async onSubmit(e: Event): Promise<void> {\n e.preventDefault();\n\n await this._validate();\n this.showAllValidations = true;\n\n if (!this.hasValidationErrors) {\n if (this.args.onSubmit) {\n this.submissionState = new TrackedAsyncData(\n this.args.onSubmit(this.internalData),\n this\n );\n }\n } else {\n assert(\n 'Validation errors expected to be present. If you see this, please report it as a bug to ember-headless-form!',\n this.validationState?.isResolved\n );\n this.args.onInvalid?.(this.internalData, this.validationState.value);\n }\n }\n\n @action\n registerField(\n name: FormKey<FormData<DATA>>,\n field: FieldRegistrationData<FormData<DATA>>\n ): void {\n assert(\n `You passed @name=\"${String(\n name\n )}\" to the form field, but this is already in use. Names of form fields must be unique!`,\n !this.fields.has(name)\n );\n this.fields.set(name, new FieldData(field));\n }\n\n @action\n unregisterField(name: FormKey<FormData<DATA>>): void {\n this.fields.delete(name);\n }\n\n @action\n set<KEY extends FormKey<FormData<DATA>>>(key: KEY, value: DATA[KEY]): void {\n // when @mutableData is set, our internalData is something we don't control, i.e. might require old-school set() to be on the safe side\n set(this.internalData, key, value);\n }\n\n /**\n * Handle the `@validateOn` event for a certain field, e.g. \"blur\".\n * Associating the event with a field is done by looking at the event target's `name` attribute, which must match one of the `<form.field @name=\"...\">` invocations by the user's template.\n * Validation will be triggered, and the particular field will be marked to show eventual validation errors.\n */\n @action\n async handleFieldValidation(e: Event | string): Promise<void> {\n let name: string;\n\n if (typeof e === 'string') {\n name = e;\n } else {\n const { target } = e;\n\n name = (target as HTMLInputElement).name;\n }\n\n if (name) {\n const field = this.fields.get(name as FormKey<FormData<DATA>>);\n\n if (field) {\n await this._validate();\n field.validationEnabled = true;\n }\n } else if (e instanceof Event) {\n warn(\n `An event of type \"${e.type}\" was received by headless-form, which is supposed to trigger validations for a certain field. But the name of that field could not be determined. Make sure that your control element has a \\`name\\` attribute matching the field, or use the yielded \\`{{field.captureEvents}}\\` to capture the events.`,\n { id: 'headless-form.validation-event-for-unknown-field' }\n );\n }\n }\n\n /**\n * Handle the `@revalidateOn` event for a certain field, e.g. \"blur\".\n * Associating the event with a field is done by looking at the event target's `name` attribute, which must match one of the `<form.field @name=\"...\">` invocations by the user's template.\n * When a field has been already marked to show validation errors by `@validateOn`, then for revalidation another validation will be triggered.\n *\n * The use case here is to allow this to happen more frequently than the initial validation, e.g. `@validateOn=\"blur\" @revalidateOn=\"change\"`.\n */\n @action\n async handleFieldRevalidation(e: Event): Promise<void> {\n const { target } = e;\n const { name } = target as HTMLInputElement;\n\n if (name) {\n if (this.showErrorsFor(name as FormKey<FormData<DATA>>)) {\n await this._validate();\n }\n } else {\n warn(\n `An event of type \"${e.type}\" was received by headless-form, which is supposed to trigger validations for a certain field. But the name of that field could not be determined. Make sure that your control element has a \\`name\\` attribute matching the field, or use the yielded \\`{{field.captureEvents}}\\` to capture the events.`,\n { id: 'headless-form.validation-event-for-unknown-field' }\n );\n }\n }\n}\n"],"names":["precompileTemplate","FieldData","constructor","fieldRegistration","validate","tracked","HeadlessFormComponent","Component","FieldComponent","on","modifier","el","_p","formElement","args","dataMode","data","TrackedObject","Map","validateOn","revalidateOn","fieldValidationEvent","undefined","fieldRevalidationEvent","hasValidationErrors","validationState","isResolved","Object","keys","value","some","name","fields","has","nativeValidation","validateNative","customFormValidation","internalData","Array","from","customFieldValidations","field","fieldValidationResult","push","mergeErrorRecord","_validate","promise","TrackedAsyncData","form","assert","checkValidity","errors","elements","HTMLInputElement","HTMLTextAreaElement","HTMLSelectElement","HTMLButtonElement","HTMLFieldSetElement","HTMLObjectElement","HTMLOutputElement","validity","valid","type","message","validationMessage","warn","id","visibleErrors","entries","showErrorsFor","showAllValidations","get","validationEnabled","onSubmit","e","preventDefault","submissionState","onInvalid","registerField","String","set","unregisterField","delete","key","handleFieldValidation","target","Event","handleFieldRevalidation","action"],"mappings":"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"}
|
1
|
+
{"version":3,"file":"headless-form.js","sources":["../../src/components/headless-form.hbs.js","../../src/components/headless-form.ts"],"sourcesContent":["import { precompileTemplate } from \"@ember/template-compilation\";\nexport default precompileTemplate(\"<form\\n novalidate\\n ...attributes\\n {{this.registerForm}}\\n {{on \\'submit\\' this.onSubmit}}\\n {{(if\\n this.fieldValidationEvent\\n (modifier this.on this.fieldValidationEvent this.handleFieldValidation)\\n )}}\\n {{(if\\n this.fieldRevalidationEvent\\n (modifier this.on this.fieldRevalidationEvent this.handleFieldRevalidation)\\n )}}\\n>\\n {{yield\\n (hash\\n Field=(component\\n (ensure-safe-component this.FieldComponent)\\n data=this.internalData\\n set=this.set\\n errors=this.visibleErrors\\n registerField=this.registerField\\n unregisterField=this.unregisterField\\n triggerValidationFor=this.handleFieldValidation\\n fieldValidationEvent=this.fieldValidationEvent\\n fieldRevalidationEvent=this.fieldRevalidationEvent\\n )\\n validationState=this.validationState\\n submissionState=this.submissionState\\n isInvalid=this.hasValidationErrors\\n rawErrors=this.visibleErrors\\n )\\n }}\\n</form>\")","import Component from '@glimmer/component';\nimport { tracked } from '@glimmer/tracking';\nimport { assert, warn } from '@ember/debug';\nimport { on } from '@ember/modifier';\nimport { action, set } from '@ember/object';\n\nimport { TrackedAsyncData } from 'ember-async-data';\nimport { modifier } from 'ember-modifier';\nimport { TrackedObject } from 'tracked-built-ins';\n\nimport FieldComponent from '../-private/components/field';\nimport { mergeErrorRecord } from '../-private/utils';\n\nimport type {\n ErrorRecord,\n FieldRegistrationData,\n FieldValidateCallback,\n FormData,\n FormKey,\n FormValidateCallback,\n UserData,\n ValidationError,\n} from '../-private/types';\nimport type { ModifierLike, WithBoundArgs } from '@glint/template';\n\ntype ValidateOn = 'change' | 'focusout' | 'submit' | 'input';\n\nexport interface HeadlessFormComponentSignature<\n DATA extends UserData,\n SUBMISSION_VALUE\n> {\n Element: HTMLFormElement;\n Args: {\n /**\n * The initial data the form will use to pre-populate the fields.\n *\n * Make sure the type of it matches what you expect the form to represent, i.e. the names of all form fields match the properties of the data and their respective types!\n */\n data?: DATA;\n\n /**\n * By default the data you pass as `@data` is never mutated by the form component, you will only receive the updated data (a copy) on successful submission via `@onSubmit`.\n * Setting this to `'mutable'` will mutate the data whenever the user updates a field. This is especially useful when the data already has some \"buffering\" behavior, like with `ember-changeset`.\n */\n dataMode?: 'mutable' | 'immutable';\n\n /**\n * Specify when to dynamically validate a field before even submitting the whole form. By default this is `submit`, which means no dynamic validation happens. Another common setting is to validate on `focusout`.\n */\n validateOn?: ValidateOn;\n\n /**\n * Specify when to revalidate a previously validated field that is invalid. By default this happens on `change`. Another common setting is to revalidate on `input`.\n * Mind that text-based inputs don't emit the `change` event on every key stroke, but only on focusing out. Changing this to `input` would make text-based inputs revalidate on every key stroke.\n */\n revalidateOn?: ValidateOn;\n\n /**\n * Provide a custom validation function, that operates on all fields of the form. Eventual validation errors are merged with native validation errors to determine the effective set of errors rendered in the form.\n *\n * Return undefined when no validation errors are present, otherwise an `ErrorRecord` mapping (one or multiple) `ValidationError`s to each invalid field.\n */\n validate?: FormValidateCallback<DATA>;\n\n /**\n * Called when the user has submitted the form and no validation errors have been determined. Receives the new form data, or in case of `@dataMode=\"mutable\"` the original data object.\n */\n onSubmit?: (\n data: FormData<DATA>\n ) => SUBMISSION_VALUE | Promise<SUBMISSION_VALUE>;\n\n /**\n * Called when the user tried to submit the form, but validation failed. Receives the new data (or in case of `@dataMode=\"mutable\"` the original data object), and the record of validation errors by field.\n */\n onInvalid?: (\n data: FormData<DATA>,\n errors: ErrorRecord<FormData<DATA>>\n ) => void;\n };\n Blocks: {\n default: [\n {\n /**\n * Field component to define the fields of your form. It yields the further components for the form control, label and validation error.\n */\n Field: WithBoundArgs<\n typeof FieldComponent<DATA>,\n | 'data'\n | 'set'\n | 'errors'\n | 'registerField'\n | 'unregisterField'\n | 'triggerValidationFor'\n | 'fieldValidationEvent'\n | 'fieldRevalidationEvent'\n >;\n\n /**\n * The (async) validation state as `TrackedAsyncData`.\n *\n * Use derived state like `.isPending` to render the UI conditionally.\n */\n validationState?: TrackedAsyncData<ErrorRecord<DATA>>;\n\n /**\n * The (async) submission state as `TrackedAsyncData`.\n *\n * Use derived state like `.isPending` to render the UI conditionally.\n */\n submissionState?: TrackedAsyncData<SUBMISSION_VALUE>;\n\n /**\n * Will be true if at least one form field is invalid.\n */\n isInvalid: boolean;\n\n /**\n * An ErrorRecord, for custom rendering of error output\n */\n rawErrors?: ErrorRecord<DATA>;\n }\n ];\n };\n}\n\n/**\n * This internal data structure maintains information about each field that is registered to the form by `registerField`.\n */\nclass FieldData<\n DATA extends FormData,\n KEY extends FormKey<DATA> = FormKey<DATA>\n> {\n constructor(fieldRegistration: FieldRegistrationData<DATA, KEY>) {\n this.validate = fieldRegistration.validate;\n }\n\n /**\n * tracked state that enabled a dynamic validation of a field *before* the whole form is submitted, e.g. by `@validateOn=\"blur\" and the blur event being triggered for that particular field.\n */\n @tracked validationEnabled = false;\n\n /**\n * The *field* level validation callback passed to the field as in `<form.field @name=\"foo\" @validate={{this.validateCallback}}>`\n */\n validate?: FieldValidateCallback<DATA, KEY>;\n}\n\n/**\n * Headless form component.\n *\n * @example\n * Usage example:\n *\n * ```hbs\n * <HeadlessForm\n * @data={{this.data}}\n * @validateOn=\"focusout\"\n * @revalidateOn=\"input\"\n * @onSubmit={{this.doSomething}}\n * as |form|\n * >\n * <form.Field @name=\"firstName\" as |field|>\n * <div>\n * <field.Label>First name</field.Label>\n * <field.Input\n * required\n * />\n * <field.errors />\n * </div>\n * </form.Field>\n *\n * <button\n * type=\"submit\"\n * >Submit</button>\n * </HeadlessForm>\n * ```\n */\nexport default class HeadlessFormComponent<\n DATA extends UserData,\n SUBMISSION_VALUE\n> extends Component<HeadlessFormComponentSignature<DATA, SUBMISSION_VALUE>> {\n FieldComponent = FieldComponent<DATA>;\n\n // we cannot use (modifier \"on\") directly in the template due to https://github.com/emberjs/ember.js/issues/19869\n on = on;\n\n formElement?: HTMLFormElement;\n\n registerForm = modifier((el: HTMLFormElement, _p: []) => {\n this.formElement = el;\n }) as unknown as ModifierLike<unknown>; // @todo getting Glint errors without this. Try again with Glint 1.0 (beta)!\n\n /**\n * A copy of the passed `@data` stored internally, which is only passed back to the component consumer after a (successful) form submission.\n */\n internalData: DATA =\n this.args.dataMode == 'mutable' && this.args.data\n ? this.args.data\n : (new TrackedObject(this.args.data ?? {}) as DATA);\n\n fields = new Map<FormKey<FormData<DATA>>, FieldData<FormData<DATA>>>();\n\n @tracked validationState?: TrackedAsyncData<ErrorRecord<DATA>>;\n @tracked submissionState?: TrackedAsyncData<SUBMISSION_VALUE>;\n\n /**\n * When this is set to true by submitting the form, eventual validation errors are show for *all* field, regardless of their individual dynamic validation status in `FieldData#validationEnabled`\n */\n @tracked showAllValidations = false;\n\n get validateOn(): ValidateOn {\n return this.args.validateOn ?? 'submit';\n }\n\n get revalidateOn(): ValidateOn {\n return this.args.revalidateOn ?? 'change';\n }\n\n /**\n * Return the event type that will be listened on for dynamic validation (i.e. *before* submitting)\n */\n get fieldValidationEvent(): 'focusout' | 'change' | 'input' | undefined {\n const { validateOn } = this;\n\n return validateOn === 'submit'\n ? // no need for dynamic validation, as validation always happens on submit\n undefined\n : validateOn;\n }\n\n /**\n * Return the event type that will be listened on for dynamic *re*validation, i.e. updating the validation status of a field that has been previously marked as invalid\n */\n get fieldRevalidationEvent(): 'focusout' | 'change' | 'input' | undefined {\n const { validateOn, revalidateOn } = this;\n\n return revalidateOn === 'submit'\n ? // no need for dynamic validation, as validation always happens on submit\n undefined\n : // when validation happens more frequently than revalidation, then we can ignore revalidation, because the validation handler will already cover us\n validateOn === 'input' ||\n (validateOn === 'change' && revalidateOn === 'focusout') ||\n validateOn === revalidateOn\n ? undefined\n : revalidateOn;\n }\n\n /**\n * Return true if validation has happened (by submitting or by an `@validateOn` event being triggered) and at least one field is invalid\n */\n get hasValidationErrors(): boolean {\n const { validationState } = this;\n\n // Only consider validation errors for which we actually have a field rendered\n return validationState?.isResolved\n ? Object.keys(validationState.value).some((name) =>\n this.fields.has(name as FormKey<FormData<DATA>>)\n )\n : false;\n }\n\n /**\n * Call the passed validation callbacks, defined both on the whole form as well as on field level, and return the merged result for all fields.\n */\n async validate(): Promise<ErrorRecord<FormData<DATA>>> {\n const nativeValidation = this.validateNative();\n const customFormValidation = await this.args.validate?.(\n this.internalData,\n Array.from(this.fields.keys())\n );\n const customFieldValidations: ErrorRecord<FormData<DATA>>[] = [];\n\n for (const [name, field] of this.fields) {\n const fieldValidationResult = await field.validate?.(\n this.internalData[name],\n name,\n this.internalData\n );\n\n if (fieldValidationResult) {\n customFieldValidations.push({\n [name]: fieldValidationResult,\n } as ErrorRecord<FormData<DATA>>);\n }\n }\n\n return mergeErrorRecord(\n nativeValidation,\n customFormValidation,\n ...customFieldValidations\n );\n }\n\n async _validate(): Promise<ErrorRecord<FormData<DATA>>> {\n const promise = this.validate();\n\n this.validationState = new TrackedAsyncData(promise, this);\n\n return promise;\n }\n\n validateNative(): ErrorRecord<FormData<DATA>> | undefined {\n const form = this.formElement;\n\n assert(\n 'Form element expected to be present. If you see this, please report it as a bug to ember-headless-form!',\n form\n );\n\n if (form.checkValidity()) {\n return;\n }\n\n const errors: ErrorRecord<FormData<DATA>> = {};\n\n for (const el of form.elements) {\n // This is just to make TS happy, as we need to access properties on el that only form elements have, but elements in `form.elements` are just typed as plain `Element`. Should never occur in reality.\n assert(\n 'Unexpected form element. If you see this, please report it as a bug to ember-headless-form!',\n el instanceof HTMLInputElement ||\n el instanceof HTMLTextAreaElement ||\n el instanceof HTMLSelectElement ||\n el instanceof HTMLButtonElement ||\n el instanceof HTMLFieldSetElement ||\n el instanceof HTMLObjectElement ||\n el instanceof HTMLOutputElement\n );\n\n if (el.validity.valid) {\n continue;\n }\n\n const name = el.name as FormKey<FormData<DATA>>;\n\n if (this.fields.has(name)) {\n errors[name] = [\n {\n type: 'native',\n value: this.internalData[name],\n message: el.validationMessage,\n },\n ];\n } else {\n warn(\n `An invalid form element with name \"${name}\" was detected, but this name is not used as a form field. It will be ignored for validation. Make sure to apply the correct name to custom form elements that participate in form validation!`,\n { id: 'headless-form.invalid-control-for-unknown-field' }\n );\n }\n }\n\n return errors;\n }\n\n /**\n * Return a mapping of field to validation errors, for all fields that are invalid *and* for which validation errors should be visible.\n * Validation errors will be visible for a certain field, if validation errors for *all* fields are visible, which is the case when trying to submit the form,\n * or when that field has triggered the event given by `@validateOn` for showing validation errors before submitting, e.g. on blur.\n */\n get visibleErrors(): ErrorRecord<FormData<DATA>> | undefined {\n if (!this.validationState?.isResolved) {\n return undefined;\n }\n\n const visibleErrors: ErrorRecord<FormData<DATA>> = {};\n\n for (const [field, errors] of Object.entries(\n this.validationState.value\n ) as [\n FormKey<FormData<DATA>>,\n ValidationError<FormData<DATA>[FormKey<FormData<DATA>>]>[]\n ][]) {\n if (this.showErrorsFor(field)) {\n visibleErrors[field] = errors;\n }\n }\n\n return visibleErrors;\n }\n\n /**\n * Given a field name, return if eventual errors for the field should be visible. See `visibleErrors` for further details.\n */\n showErrorsFor(field: FormKey<FormData<DATA>>): boolean {\n return (\n this.showAllValidations ||\n (this.fields.get(field)?.validationEnabled ?? false)\n );\n }\n\n @action\n async onSubmit(e: Event): Promise<void> {\n e.preventDefault();\n\n await this._validate();\n this.showAllValidations = true;\n\n if (!this.hasValidationErrors) {\n if (this.args.onSubmit) {\n this.submissionState = new TrackedAsyncData(\n this.args.onSubmit(this.internalData),\n this\n );\n }\n } else {\n assert(\n 'Validation errors expected to be present. If you see this, please report it as a bug to ember-headless-form!',\n this.validationState?.isResolved\n );\n this.args.onInvalid?.(this.internalData, this.validationState.value);\n }\n }\n\n @action\n registerField(\n name: FormKey<FormData<DATA>>,\n field: FieldRegistrationData<FormData<DATA>>\n ): void {\n assert(\n `You passed @name=\"${String(\n name\n )}\" to the form field, but this is already in use. Names of form fields must be unique!`,\n !this.fields.has(name)\n );\n this.fields.set(name, new FieldData(field));\n }\n\n @action\n unregisterField(name: FormKey<FormData<DATA>>): void {\n this.fields.delete(name);\n }\n\n @action\n set<KEY extends FormKey<FormData<DATA>>>(key: KEY, value: DATA[KEY]): void {\n // when @mutableData is set, our internalData is something we don't control, i.e. might require old-school set() to be on the safe side\n set(this.internalData, key, value);\n }\n\n /**\n * Handle the `@validateOn` event for a certain field, e.g. \"blur\".\n * Associating the event with a field is done by looking at the event target's `name` attribute, which must match one of the `<form.field @name=\"...\">` invocations by the user's template.\n * Validation will be triggered, and the particular field will be marked to show eventual validation errors.\n */\n @action\n async handleFieldValidation(e: Event | string): Promise<void> {\n let name: string;\n\n if (typeof e === 'string') {\n name = e;\n } else {\n const { target } = e;\n\n name = (target as HTMLInputElement).name;\n }\n\n if (name) {\n const field = this.fields.get(name as FormKey<FormData<DATA>>);\n\n if (field) {\n await this._validate();\n field.validationEnabled = true;\n }\n } else if (e instanceof Event) {\n warn(\n `An event of type \"${e.type}\" was received by headless-form, which is supposed to trigger validations for a certain field. But the name of that field could not be determined. Make sure that your control element has a \\`name\\` attribute matching the field, or use the yielded \\`{{field.captureEvents}}\\` to capture the events.`,\n { id: 'headless-form.validation-event-for-unknown-field' }\n );\n }\n }\n\n /**\n * Handle the `@revalidateOn` event for a certain field, e.g. \"blur\".\n * Associating the event with a field is done by looking at the event target's `name` attribute, which must match one of the `<form.field @name=\"...\">` invocations by the user's template.\n * When a field has been already marked to show validation errors by `@validateOn`, then for revalidation another validation will be triggered.\n *\n * The use case here is to allow this to happen more frequently than the initial validation, e.g. `@validateOn=\"blur\" @revalidateOn=\"change\"`.\n */\n @action\n async handleFieldRevalidation(e: Event): Promise<void> {\n const { target } = e;\n const { name } = target as HTMLInputElement;\n\n if (name) {\n if (this.showErrorsFor(name as FormKey<FormData<DATA>>)) {\n await this._validate();\n }\n } else {\n warn(\n `An event of type \"${e.type}\" was received by headless-form, which is supposed to trigger validations for a certain field. But the name of that field could not be determined. Make sure that your control element has a \\`name\\` attribute matching the field, or use the yielded \\`{{field.captureEvents}}\\` to capture the events.`,\n { id: 'headless-form.validation-event-for-unknown-field' }\n );\n }\n }\n}\n"],"names":["precompileTemplate","FieldData","constructor","fieldRegistration","validate","tracked","HeadlessFormComponent","Component","FieldComponent","on","modifier","el","_p","formElement","args","dataMode","data","TrackedObject","Map","validateOn","revalidateOn","fieldValidationEvent","undefined","fieldRevalidationEvent","hasValidationErrors","validationState","isResolved","Object","keys","value","some","name","fields","has","nativeValidation","validateNative","customFormValidation","internalData","Array","from","customFieldValidations","field","fieldValidationResult","push","mergeErrorRecord","_validate","promise","TrackedAsyncData","form","assert","checkValidity","errors","elements","HTMLInputElement","HTMLTextAreaElement","HTMLSelectElement","HTMLButtonElement","HTMLFieldSetElement","HTMLObjectElement","HTMLOutputElement","validity","valid","type","message","validationMessage","warn","id","visibleErrors","entries","showErrorsFor","showAllValidations","get","validationEnabled","onSubmit","e","preventDefault","submissionState","onInvalid","registerField","String","set","unregisterField","delete","key","handleFieldValidation","target","Event","handleFieldRevalidation","action"],"mappings":";;;;;;;;;;;;;;;;;AACA,eAAeA,kBAAkB,CAAC,y+BAAy+B,CAAC;;;AC4H5gC;AACA;AACA;AAFA,IAGMC,SAAS,IAAA,MAAA,GAAf,MAAMA,SAAS,CAGb;EACAC,WAAW,CAACC,iBAAmD,EAAE;AAAA,IAAA,0BAAA,CAAA,IAAA,EAAA,mBAAA,EAAA,WAAA,EAAA,IAAA,CAAA,CAAA;AAAA,IAAA,eAAA,CAAA,IAAA,EAAA,UAAA,EAAA,KAAA,CAAA,CAAA,CAAA;AAC/D,IAAA,IAAI,CAACC,QAAQ,GAAGD,iBAAiB,CAACC,QAAQ,CAAA;AAC5C,GAAA;;AAEA;AACF;AACA;AAOA,CAAC,mFANEC,OAAO,CAAA,EAAA;AAAA,EAAA,YAAA,EAAA,IAAA;AAAA,EAAA,UAAA,EAAA,IAAA;AAAA,EAAA,QAAA,EAAA,IAAA;AAAA,EAAA,WAAA,EAAA,YAAA;AAAA,IAAA,OAAqB,KAAK,CAAA;AAAA,GAAA;AAAA,CAAA,CAAA,GAAA,MAAA,CAAA,CAAA;AAQpC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AA7BA,IA8BqBC,qBAAqB,IAA3B,OAAA,GAAA,MAAMA,qBAAqB,SAGhCC,SAAS,CAAyD;AAAA,EAAA,WAAA,CAAA,GAAA,IAAA,EAAA;AAAA,IAAA,KAAA,CAAA,GAAA,IAAA,CAAA,CAAA;AAAA,IAAA,eAAA,CAAA,IAAA,EAAA,gBAAA,EACzDC,0BAAc,CAAA,CAAA;AAAA,IAAA,eAAA,CAAA,IAAA,EAAA,IAAA,EAG1BC,EAAE,CAAA,CAAA;AAAA,IAAA,eAAA,CAAA,IAAA,EAAA,aAAA,EAAA,KAAA,CAAA,CAAA,CAAA;AAAA,IAAA,eAAA,CAAA,IAAA,EAAA,cAAA,EAIQC,QAAQ,CAAC,CAACC,EAAmB,EAAEC,EAAM,KAAK;MACvD,IAAI,CAACC,WAAW,GAAGF,EAAE,CAAA;AACvB,KAAC,CAAC,CAAA,CAAA;AAAA,IAAA,eAAA,CAAA,IAAA,EAAA,cAAA,EAMA,IAAI,CAACG,IAAI,CAACC,QAAQ,IAAI,SAAS,IAAI,IAAI,CAACD,IAAI,CAACE,IAAI,GAC7C,IAAI,CAACF,IAAI,CAACE,IAAI,GACb,IAAIC,aAAa,CAAC,IAAI,CAACH,IAAI,CAACE,IAAI,IAAI,EAAE,CAAU,CAAA,CAAA;IAAA,eAE9C,CAAA,IAAA,EAAA,QAAA,EAAA,IAAIE,GAAG,EAAsD,CAAA,CAAA;AAAA,IAAA,0BAAA,CAAA,IAAA,EAAA,iBAAA,EAAA,YAAA,EAAA,IAAA,CAAA,CAAA;AAAA,IAAA,0BAAA,CAAA,IAAA,EAAA,iBAAA,EAAA,YAAA,EAAA,IAAA,CAAA,CAAA;AAAA,IAAA,0BAAA,CAAA,IAAA,EAAA,oBAAA,EAAA,YAAA,EAAA,IAAA,CAAA,CAAA;AAAA,GAAA;AAUtE,EAAA,IAAIC,UAAU,GAAe;AAC3B,IAAA,OAAO,IAAI,CAACL,IAAI,CAACK,UAAU,IAAI,QAAQ,CAAA;AACzC,GAAA;AAEA,EAAA,IAAIC,YAAY,GAAe;AAC7B,IAAA,OAAO,IAAI,CAACN,IAAI,CAACM,YAAY,IAAI,QAAQ,CAAA;AAC3C,GAAA;;AAEA;AACF;AACA;AACE,EAAA,IAAIC,oBAAoB,GAAgD;IACtE,MAAM;AAAEF,MAAAA,UAAAA;AAAW,KAAC,GAAG,IAAI,CAAA;IAE3B,OAAOA,UAAU,KAAK,QAAQ;AAC1B;AACAG,IAAAA,SAAS,GACTH,UAAU,CAAA;AAChB,GAAA;;AAEA;AACF;AACA;AACE,EAAA,IAAII,sBAAsB,GAAgD;IACxE,MAAM;MAAEJ,UAAU;AAAEC,MAAAA,YAAAA;AAAa,KAAC,GAAG,IAAI,CAAA;IAEzC,OAAOA,YAAY,KAAK,QAAQ;AAC5B;IACAE,SAAS;AACT;AACFH,IAAAA,UAAU,KAAK,OAAO,IACnBA,UAAU,KAAK,QAAQ,IAAIC,YAAY,KAAK,UAAW,IACxDD,UAAU,KAAKC,YAAY,GAC3BE,SAAS,GACTF,YAAY,CAAA;AAClB,GAAA;;AAEA;AACF;AACA;AACE,EAAA,IAAII,mBAAmB,GAAY;IACjC,MAAM;AAAEC,MAAAA,eAAAA;AAAgB,KAAC,GAAG,IAAI,CAAA;;AAEhC;IACA,OAAOA,eAAe,EAAEC,UAAU,GAC9BC,MAAM,CAACC,IAAI,CAACH,eAAe,CAACI,KAAK,CAAC,CAACC,IAAI,CAAEC,IAAI,IAC3C,IAAI,CAACC,MAAM,CAACC,GAAG,CAACF,IAAI,CAA4B,CACjD,GACD,KAAK,CAAA;AACX,GAAA;;AAEA;AACF;AACA;AACE,EAAA,MAAM3B,QAAQ,GAAyC;AACrD,IAAA,MAAM8B,gBAAgB,GAAG,IAAI,CAACC,cAAc,EAAE,CAAA;IAC9C,MAAMC,oBAAoB,GAAG,MAAM,IAAI,CAACtB,IAAI,CAACV,QAAQ,GACnD,IAAI,CAACiC,YAAY,EACjBC,KAAK,CAACC,IAAI,CAAC,IAAI,CAACP,MAAM,CAACJ,IAAI,EAAE,CAAC,CAC/B,CAAA;IACD,MAAMY,sBAAqD,GAAG,EAAE,CAAA;IAEhE,KAAK,MAAM,CAACT,IAAI,EAAEU,KAAK,CAAC,IAAI,IAAI,CAACT,MAAM,EAAE;AACvC,MAAA,MAAMU,qBAAqB,GAAG,MAAMD,KAAK,CAACrC,QAAQ,GAChD,IAAI,CAACiC,YAAY,CAACN,IAAI,CAAC,EACvBA,IAAI,EACJ,IAAI,CAACM,YAAY,CAClB,CAAA;AAED,MAAA,IAAIK,qBAAqB,EAAE;QACzBF,sBAAsB,CAACG,IAAI,CAAC;AAC1B,UAAA,CAACZ,IAAI,GAAGW,qBAAAA;AACV,SAAC,CAAgC,CAAA;AACnC,OAAA;AACF,KAAA;IAEA,OAAOE,gBAAgB,CACrBV,gBAAgB,EAChBE,oBAAoB,EACpB,GAAGI,sBAAsB,CAC1B,CAAA;AACH,GAAA;AAEA,EAAA,MAAMK,SAAS,GAAyC;AACtD,IAAA,MAAMC,OAAO,GAAG,IAAI,CAAC1C,QAAQ,EAAE,CAAA;IAE/B,IAAI,CAACqB,eAAe,GAAG,IAAIsB,gBAAgB,CAACD,OAAO,EAAE,IAAI,CAAC,CAAA;AAE1D,IAAA,OAAOA,OAAO,CAAA;AAChB,GAAA;AAEAX,EAAAA,cAAc,GAA4C;AACxD,IAAA,MAAMa,IAAI,GAAG,IAAI,CAACnC,WAAW,CAAA;AAE7BoC,IAAAA,MAAM,CACJ,yGAAyG,EACzGD,IAAI,CACL,CAAA;AAED,IAAA,IAAIA,IAAI,CAACE,aAAa,EAAE,EAAE;AACxB,MAAA,OAAA;AACF,KAAA;IAEA,MAAMC,MAAmC,GAAG,EAAE,CAAA;AAE9C,IAAA,KAAK,MAAMxC,EAAE,IAAIqC,IAAI,CAACI,QAAQ,EAAE;AAC9B;AACAH,MAAAA,MAAM,CACJ,6FAA6F,EAC7FtC,EAAE,YAAY0C,gBAAgB,IAC5B1C,EAAE,YAAY2C,mBAAmB,IACjC3C,EAAE,YAAY4C,iBAAiB,IAC/B5C,EAAE,YAAY6C,iBAAiB,IAC/B7C,EAAE,YAAY8C,mBAAmB,IACjC9C,EAAE,YAAY+C,iBAAiB,IAC/B/C,EAAE,YAAYgD,iBAAiB,CAClC,CAAA;AAED,MAAA,IAAIhD,EAAE,CAACiD,QAAQ,CAACC,KAAK,EAAE;AACrB,QAAA,SAAA;AACF,OAAA;AAEA,MAAA,MAAM9B,IAAI,GAAGpB,EAAE,CAACoB,IAA+B,CAAA;MAE/C,IAAI,IAAI,CAACC,MAAM,CAACC,GAAG,CAACF,IAAI,CAAC,EAAE;AACzBoB,QAAAA,MAAM,CAACpB,IAAI,CAAC,GAAG,CACb;AACE+B,UAAAA,IAAI,EAAE,QAAQ;AACdjC,UAAAA,KAAK,EAAE,IAAI,CAACQ,YAAY,CAACN,IAAI,CAAC;UAC9BgC,OAAO,EAAEpD,EAAE,CAACqD,iBAAAA;AACd,SAAC,CACF,CAAA;AACH,OAAC,MAAM;AACLC,QAAAA,IAAI,CACD,CAAA,mCAAA,EAAqClC,IAAK,CAAA,8LAAA,CAA+L,EAC1O;AAAEmC,UAAAA,EAAE,EAAE,iDAAA;AAAkD,SAAC,CAC1D,CAAA;AACH,OAAA;AACF,KAAA;AAEA,IAAA,OAAOf,MAAM,CAAA;AACf,GAAA;;AAEA;AACF;AACA;AACA;AACA;AACE,EAAA,IAAIgB,aAAa,GAA4C;AAC3D,IAAA,IAAI,CAAC,IAAI,CAAC1C,eAAe,EAAEC,UAAU,EAAE;AACrC,MAAA,OAAOJ,SAAS,CAAA;AAClB,KAAA;IAEA,MAAM6C,aAA0C,GAAG,EAAE,CAAA;AAErD,IAAA,KAAK,MAAM,CAAC1B,KAAK,EAAEU,MAAM,CAAC,IAAIxB,MAAM,CAACyC,OAAO,CAC1C,IAAI,CAAC3C,eAAe,CAACI,KAAK,CAC3B,EAGI;AACH,MAAA,IAAI,IAAI,CAACwC,aAAa,CAAC5B,KAAK,CAAC,EAAE;AAC7B0B,QAAAA,aAAa,CAAC1B,KAAK,CAAC,GAAGU,MAAM,CAAA;AAC/B,OAAA;AACF,KAAA;AAEA,IAAA,OAAOgB,aAAa,CAAA;AACtB,GAAA;;AAEA;AACF;AACA;EACEE,aAAa,CAAC5B,KAA8B,EAAW;AACrD,IAAA,OACE,IAAI,CAAC6B,kBAAkB,KACtB,IAAI,CAACtC,MAAM,CAACuC,GAAG,CAAC9B,KAAK,CAAC,EAAE+B,iBAAiB,IAAI,KAAK,CAAC,CAAA;AAExD,GAAA;EAEA,MACMC,QAAQ,CAACC,CAAQ,EAAiB;IACtCA,CAAC,CAACC,cAAc,EAAE,CAAA;IAElB,MAAM,IAAI,CAAC9B,SAAS,EAAE,CAAA;IACtB,IAAI,CAACyB,kBAAkB,GAAG,IAAI,CAAA;AAE9B,IAAA,IAAI,CAAC,IAAI,CAAC9C,mBAAmB,EAAE;AAC7B,MAAA,IAAI,IAAI,CAACV,IAAI,CAAC2D,QAAQ,EAAE;AACtB,QAAA,IAAI,CAACG,eAAe,GAAG,IAAI7B,gBAAgB,CACzC,IAAI,CAACjC,IAAI,CAAC2D,QAAQ,CAAC,IAAI,CAACpC,YAAY,CAAC,EACrC,IAAI,CACL,CAAA;AACH,OAAA;AACF,KAAC,MAAM;MACLY,MAAM,CACJ,8GAA8G,EAC9G,IAAI,CAACxB,eAAe,EAAEC,UAAU,CACjC,CAAA;AACD,MAAA,IAAI,CAACZ,IAAI,CAAC+D,SAAS,GAAG,IAAI,CAACxC,YAAY,EAAE,IAAI,CAACZ,eAAe,CAACI,KAAK,CAAC,CAAA;AACtE,KAAA;AACF,GAAA;AAGAiD,EAAAA,aAAa,CACX/C,IAA6B,EAC7BU,KAA4C,EACtC;AACNQ,IAAAA,MAAM,CACH,CAAoB8B,kBAAAA,EAAAA,MAAM,CACzBhD,IAAI,CACJ,CAAsF,qFAAA,CAAA,EACxF,CAAC,IAAI,CAACC,MAAM,CAACC,GAAG,CAACF,IAAI,CAAC,CACvB,CAAA;AACD,IAAA,IAAI,CAACC,MAAM,CAACgD,GAAG,CAACjD,IAAI,EAAE,IAAI9B,SAAS,CAACwC,KAAK,CAAC,CAAC,CAAA;AAC7C,GAAA;EAGAwC,eAAe,CAAClD,IAA6B,EAAQ;AACnD,IAAA,IAAI,CAACC,MAAM,CAACkD,MAAM,CAACnD,IAAI,CAAC,CAAA;AAC1B,GAAA;AAGAiD,EAAAA,GAAG,CAAsCG,GAAQ,EAAEtD,KAAgB,EAAQ;AACzE;IACAmD,GAAG,CAAC,IAAI,CAAC3C,YAAY,EAAE8C,GAAG,EAAEtD,KAAK,CAAC,CAAA;AACpC,GAAA;;AAEA;AACF;AACA;AACA;AACA;EACE,MACMuD,qBAAqB,CAACV,CAAiB,EAAiB;AAC5D,IAAA,IAAI3C,IAAY,CAAA;AAEhB,IAAA,IAAI,OAAO2C,CAAC,KAAK,QAAQ,EAAE;AACzB3C,MAAAA,IAAI,GAAG2C,CAAC,CAAA;AACV,KAAC,MAAM;MACL,MAAM;AAAEW,QAAAA,MAAAA;AAAO,OAAC,GAAGX,CAAC,CAAA;MAEpB3C,IAAI,GAAIsD,MAAM,CAAsBtD,IAAI,CAAA;AAC1C,KAAA;AAEA,IAAA,IAAIA,IAAI,EAAE;MACR,MAAMU,KAAK,GAAG,IAAI,CAACT,MAAM,CAACuC,GAAG,CAACxC,IAAI,CAA4B,CAAA;AAE9D,MAAA,IAAIU,KAAK,EAAE;QACT,MAAM,IAAI,CAACI,SAAS,EAAE,CAAA;QACtBJ,KAAK,CAAC+B,iBAAiB,GAAG,IAAI,CAAA;AAChC,OAAA;AACF,KAAC,MAAM,IAAIE,CAAC,YAAYY,KAAK,EAAE;AAC7BrB,MAAAA,IAAI,CACD,CAAoBS,kBAAAA,EAAAA,CAAC,CAACZ,IAAK,2SAA0S,EACtU;AAAEI,QAAAA,EAAE,EAAE,kDAAA;AAAmD,OAAC,CAC3D,CAAA;AACH,KAAA;AACF,GAAA;;AAEA;AACF;AACA;AACA;AACA;AACA;AACA;EACE,MACMqB,uBAAuB,CAACb,CAAQ,EAAiB;IACrD,MAAM;AAAEW,MAAAA,MAAAA;AAAO,KAAC,GAAGX,CAAC,CAAA;IACpB,MAAM;AAAE3C,MAAAA,IAAAA;AAAK,KAAC,GAAGsD,MAA0B,CAAA;AAE3C,IAAA,IAAItD,IAAI,EAAE;AACR,MAAA,IAAI,IAAI,CAACsC,aAAa,CAACtC,IAAI,CAA4B,EAAE;QACvD,MAAM,IAAI,CAACc,SAAS,EAAE,CAAA;AACxB,OAAA;AACF,KAAC,MAAM;AACLoB,MAAAA,IAAI,CACD,CAAoBS,kBAAAA,EAAAA,CAAC,CAACZ,IAAK,2SAA0S,EACtU;AAAEI,QAAAA,EAAE,EAAE,kDAAA;AAAmD,OAAC,CAC3D,CAAA;AACH,KAAA;AACF,GAAA;AACF,CAAC,mFAlSE7D,OAAO,CAAA,EAAA;AAAA,EAAA,YAAA,EAAA,IAAA;AAAA,EAAA,UAAA,EAAA,IAAA;AAAA,EAAA,QAAA,EAAA,IAAA;AAAA,EAAA,WAAA,EAAA,IAAA;AAAA,CAAA,CAAA,EAAA,YAAA,GAAA,yBAAA,CAAA,OAAA,CAAA,SAAA,EAAA,iBAAA,EAAA,CACPA,OAAO,CAAA,EAAA;AAAA,EAAA,YAAA,EAAA,IAAA;AAAA,EAAA,UAAA,EAAA,IAAA;AAAA,EAAA,QAAA,EAAA,IAAA;AAAA,EAAA,WAAA,EAAA,IAAA;AAAA,CAAA,CAAA,EAAA,YAAA,GAAA,yBAAA,CAAA,OAAA,CAAA,SAAA,EAAA,oBAAA,EAAA,CAKPA,OAAO,CAAA,EAAA;AAAA,EAAA,YAAA,EAAA,IAAA;AAAA,EAAA,UAAA,EAAA,IAAA;AAAA,EAAA,QAAA,EAAA,IAAA;AAAA,EAAA,WAAA,EAAA,YAAA;AAAA,IAAA,OAAsB,KAAK,CAAA;AAAA,GAAA;AAAA,CAqLlCmF,CAAAA,EAAAA,yBAAAA,CAAAA,OAAAA,CAAAA,SAAAA,EAAAA,UAAAA,EAAAA,CAAAA,MAAM,CAuBNA,EAAAA,MAAAA,CAAAA,wBAAAA,CAAAA,OAAAA,CAAAA,SAAAA,EAAAA,UAAAA,CAAAA,EAAAA,OAAAA,CAAAA,SAAAA,CAAAA,EAAAA,yBAAAA,CAAAA,OAAAA,CAAAA,SAAAA,EAAAA,eAAAA,EAAAA,CAAAA,MAAM,CAcNA,EAAAA,MAAAA,CAAAA,wBAAAA,CAAAA,OAAAA,CAAAA,SAAAA,EAAAA,eAAAA,CAAAA,EAAAA,OAAAA,CAAAA,SAAAA,CAAAA,EAAAA,yBAAAA,CAAAA,OAAAA,CAAAA,SAAAA,EAAAA,iBAAAA,EAAAA,CAAAA,MAAM,mJAKNA,MAAM,CAAA,EAAA,MAAA,CAAA,wBAAA,CAAA,OAAA,CAAA,SAAA,EAAA,KAAA,CAAA,EAAA,OAAA,CAAA,SAAA,CAAA,EAAA,yBAAA,CAAA,OAAA,CAAA,SAAA,EAAA,uBAAA,EAAA,CAWNA,MAAM,CAAA,EAAA,MAAA,CAAA,wBAAA,CAAA,OAAA,CAAA,SAAA,EAAA,uBAAA,CAAA,EAAA,OAAA,CAAA,SAAA,CAAA,EAAA,yBAAA,CAAA,OAAA,CAAA,SAAA,EAAA,yBAAA,EAAA,CAkCNA,MAAM,CAAA,EAAA,MAAA,CAAA,wBAAA,CAAA,OAAA,CAAA,SAAA,EAAA,yBAAA,CAAA,EAAA,OAAA,CAAA,SAAA,CAAA,GAAA,OAAA,EAAA;AA3SiC,oBAAA,CAAA,QAAA,EAAA,qBAAA,CAAA;;;;"}
|