ember-headless-form 0.0.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/README.md +16 -3
- package/dist/{components/-private → -private/components}/control/checkbox.d.ts +1 -0
- package/dist/-private/components/control/checkbox.d.ts.map +1 -0
- package/dist/-private/components/control/checkbox.js.map +1 -0
- package/dist/{components/-private → -private/components}/control/input.d.ts +17 -1
- package/dist/{components/-private → -private/components}/control/input.js +2 -2
- package/dist/-private/components/control/input.js.map +1 -0
- package/dist/-private/components/control/radio/input.js.map +1 -0
- package/dist/-private/components/control/radio.d.ts +35 -0
- package/dist/{components/-private → -private/components}/control/radio.js +1 -1
- package/dist/-private/components/control/radio.js.map +1 -0
- package/dist/-private/components/control/select/option.d.ts +18 -0
- package/dist/-private/components/control/select/option.js +15 -0
- package/dist/-private/components/control/select/option.js.map +1 -0
- package/dist/-private/components/control/select.d.ts +26 -0
- package/dist/-private/components/control/select.js +24 -0
- package/dist/-private/components/control/select.js.map +1 -0
- package/dist/{components/-private → -private/components}/control/textarea.js +1 -1
- package/dist/-private/components/control/textarea.js.map +1 -0
- package/dist/{components/-private → -private/components}/errors.d.ts +1 -1
- package/dist/-private/components/errors.js.map +1 -0
- package/dist/-private/components/field.d.ts +150 -0
- package/dist/{components/-private → -private/components}/field.js +9 -4
- package/dist/-private/components/field.js.map +1 -0
- package/dist/-private/components/label.js.map +1 -0
- package/dist/{components/-private → -private/modifiers}/capture-events.d.ts +1 -2
- package/dist/-private/modifiers/capture-events.js.map +1 -0
- package/dist/{components/-private → -private}/types.d.ts +1 -1
- package/dist/-private/utils.js.map +1 -0
- package/dist/components/headless-form.d.ts +107 -14
- package/dist/components/headless-form.js +71 -23
- package/dist/components/headless-form.js.map +1 -1
- package/dist/index.d.ts +3 -1
- package/dist/index.js +1 -1
- package/dist/template-registry.d.ts +30 -0
- package/package.json +14 -10
- package/dist/components/-private/capture-events.d.ts.map +0 -1
- package/dist/components/-private/capture-events.js.map +0 -1
- package/dist/components/-private/control/checkbox.js.map +0 -1
- package/dist/components/-private/control/input.js.map +0 -1
- package/dist/components/-private/control/radio/input.js.map +0 -1
- package/dist/components/-private/control/radio.d.ts +0 -28
- package/dist/components/-private/control/radio.js.map +0 -1
- package/dist/components/-private/control/textarea.js.map +0 -1
- package/dist/components/-private/errors.js.map +0 -1
- package/dist/components/-private/field.d.ts +0 -76
- package/dist/components/-private/field.js.map +0 -1
- package/dist/components/-private/label.js.map +0 -1
- package/dist/components/-private/utils.js.map +0 -1
- /package/dist/{components/-private → -private/components}/control/checkbox.js +0 -0
- /package/dist/{components/-private → -private/components}/control/radio/input.d.ts +0 -0
- /package/dist/{components/-private → -private/components}/control/radio/input.js +0 -0
- /package/dist/{components/-private → -private/components}/control/textarea.d.ts +0 -0
- /package/dist/{components/-private → -private/components}/errors.js +0 -0
- /package/dist/{components/-private → -private/components}/label.d.ts +0 -0
- /package/dist/{components/-private → -private/components}/label.js +0 -0
- /package/dist/{components/-private → -private/modifiers}/capture-events.js +0 -0
- /package/dist/{components/-private → -private}/types.js +0 -0
- /package/dist/{components/-private → -private}/types.js.map +0 -0
- /package/dist/{components/-private → -private}/utils.d.ts +0 -0
- /package/dist/{components/-private → -private}/utils.js +0 -0
package/README.md
CHANGED
@@ -1,10 +1,23 @@
|
|
1
1
|
# ember-headless-form
|
2
2
|
|
3
|
-
[
|
3
|
+
[](https://github.com/CrowdStrike/ember-headless-form/actions/workflows/ci.yml)
|
4
|
+
|
5
|
+
The Ember.js addon that distills the common behavior and accessibility best practices of forms into reusable components, without any opinions on specific markup or styling. Use it to build your forms directly, or to build your opinionated forms component kit on top of it.
|
6
|
+
|
7
|
+
## Key Features
|
8
|
+
|
9
|
+
- Semantic form markup with accessibility best practices baked in
|
10
|
+
- Integrates native HTML5 validation with custom error rendering
|
11
|
+
- Extension points for custom JavaScript-based validation
|
12
|
+
- Optional ready-to-use integrations for `ember-changeset` and `yup` based validation
|
13
|
+
- Support for async state
|
14
|
+
- TypeScript / Glint support with tight types
|
15
|
+
- Octane-based v2 addon
|
16
|
+
- Fully tested
|
4
17
|
|
5
18
|
## Compatibility
|
6
19
|
|
7
|
-
- Ember.js v4.
|
20
|
+
- Ember.js v4.4 or above
|
8
21
|
- Embroider or ember-auto-import v2
|
9
22
|
|
10
23
|
## Installation
|
@@ -15,7 +28,7 @@ ember install ember-headless-form
|
|
15
28
|
|
16
29
|
## Usage
|
17
30
|
|
18
|
-
|
31
|
+
Visit our [documentation website](https://ember-headless-form.pages.dev/).
|
19
32
|
|
20
33
|
## Contributing
|
21
34
|
|
@@ -14,3 +14,4 @@ declare class HeadlessFormControlCheckboxComponent extends Component<HeadlessFor
|
|
14
14
|
handleInput(e: Event | InputEvent): void;
|
15
15
|
}
|
16
16
|
export { HeadlessFormControlCheckboxComponentSignature, HeadlessFormControlCheckboxComponent as default };
|
17
|
+
//# sourceMappingURL=-private/components/control/checkbox.d.ts.map
|
@@ -0,0 +1 @@
|
|
1
|
+
{"version":3,"file":"-private/components/control/checkbox.d.ts","sourceRoot":"","sources":["../src/-private/components/control/checkbox.ts"],"names":[],"mappings":"AAAA,OAAO,SAAS,MAAM,oBAAoB,CAAC;AAG3C,UAAiB,6CAA6C;IAC5D,OAAO,EAAE,gBAAgB,CAAC;IAC1B,IAAI,EAAE;QAMJ,KAAK,EAAE,OAAO,CAAC;QAKf,IAAI,EAAE,MAAM,CAAC;QAKb,OAAO,EAAE,MAAM,CAAC;QAKhB,QAAQ,EAAE,CAAC,KAAK,EAAE,OAAO,KAAK,IAAI,CAAC;QAKnC,OAAO,EAAE,OAAO,CAAC;QAKjB,OAAO,EAAE,MAAM,CAAC;KACjB,CAAC;CACH;AAED,cAAqB,oCAAqC,SAAQ,SAAS,CAAC,6CAA6C,CAAC;IAExH,WAAW,CAAC,CAAC,EAAE,KAAK,GAAG,UAAU,GAAG,IAAI;CAGzC"}
|
@@ -0,0 +1 @@
|
|
1
|
+
{"version":3,"file":"checkbox.js","sources":["../../../../src/-private/components/control/checkbox.hbs.js","../../../../src/-private/components/control/checkbox.ts"],"sourcesContent":["import { precompileTemplate } from \"@ember/template-compilation\";\nexport default precompileTemplate(\"<input\\n name={{@name}}\\n type=\\'checkbox\\'\\n checked={{@value}}\\n id={{@fieldId}}\\n aria-invalid={{if @invalid \\'true\\'}}\\n ...attributes\\n {{on \\'click\\' this.handleInput}}\\n/>\")","import Component from '@glimmer/component';\nimport { action } from '@ember/object';\n\nexport interface HeadlessFormControlCheckboxComponentSignature {\n Element: HTMLInputElement;\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: boolean;\n\n /*\n * @internal\n */\n name: string;\n\n /*\n * @internal\n */\n fieldId: string;\n\n /*\n * @internal\n */\n setValue: (value: boolean) => void;\n\n /*\n * @internal\n */\n invalid: boolean;\n\n /*\n * @internal\n */\n errorId: string;\n };\n}\n\nexport default class HeadlessFormControlCheckboxComponent extends Component<HeadlessFormControlCheckboxComponentSignature> {\n @action\n handleInput(e: Event | InputEvent): void {\n this.args.setValue((e.target as HTMLInputElement).checked);\n }\n}\n"],"names":["precompileTemplate","HeadlessFormControlCheckboxComponent","Component","handleInput","e","args","setValue","target","checked","action"],"mappings":";;;;;;AACA,eAAeA,kBAAkB,CAAC,2LAA2L,CAAC;;;ACAvL,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,CAAsBC,OAAO,CAAC,CAAA;AAC5D,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;;;;"}
|
@@ -3,9 +3,25 @@ type InputType = 'color' | 'date' | 'datetime-local' | 'email' | 'hidden' | 'mon
|
|
3
3
|
interface HeadlessFormControlInputComponentSignature {
|
4
4
|
Element: HTMLInputElement;
|
5
5
|
Args: {
|
6
|
+
/**
|
7
|
+
* The `type` of the `<input>` element, by default `text`.
|
8
|
+
*
|
9
|
+
* Note that certain types should not be used, as they have dedicated control components:
|
10
|
+
* - `checkbox`
|
11
|
+
* - `radio`
|
12
|
+
*
|
13
|
+
* Also these types are not useful to use as input controls:
|
14
|
+
* - `button`
|
15
|
+
* - `file`
|
16
|
+
* - `image`
|
17
|
+
* - `reset`
|
18
|
+
* - `submit`
|
19
|
+
*
|
20
|
+
* @see https://developer.mozilla.org/en-US/docs/Web/HTML/Element/input#input_types
|
21
|
+
*/
|
22
|
+
type?: InputType;
|
6
23
|
value: string;
|
7
24
|
name: string;
|
8
|
-
type?: InputType;
|
9
25
|
fieldId: string;
|
10
26
|
setValue: (value: string) => void;
|
11
27
|
invalid: boolean;
|
@@ -5,12 +5,12 @@ 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
|
|
12
12
|
// Possible values for the input type, see https://developer.mozilla.org/en-US/docs/Web/HTML/Element/input#input_types
|
13
|
-
// for the sake
|
13
|
+
// for the sake of completeness, we list all here, with some commented out that are better handled elsewhere, or not at all...
|
14
14
|
let HeadlessFormControlInputComponent = (_class = class HeadlessFormControlInputComponent extends Component {
|
15
15
|
constructor(owner, args) {
|
16
16
|
assert(`input component does not support @type="${args.type}" as there is a dedicated component for this. Please use the \`field.${args.type}\` instead!`, args.type === undefined ||
|
@@ -0,0 +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-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;;;;"}
|
@@ -0,0 +1 @@
|
|
1
|
+
{"version":3,"file":"input.js","sources":["../../../../../src/-private/components/control/radio/input.hbs.js","../../../../../src/-private/components/control/radio/input.ts"],"sourcesContent":["import { precompileTemplate } from \"@ember/template-compilation\";\nexport default precompileTemplate(\"<input\\n name={{@name}}\\n type=\\'radio\\'\\n value={{@value}}\\n checked={{@checked}}\\n id={{@fieldId}}\\n ...attributes\\n {{on \\'change\\' (fn @setValue @value)}}\\n/>\")","import templateOnlyComponent from '@ember/component/template-only';\n\nexport interface HeadlessFormControlRadioInputComponentSignature {\n Element: HTMLInputElement;\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 checked: boolean;\n\n /*\n * @internal\n */\n fieldId: string;\n\n /*\n * @internal\n */\n setValue: (value: string) => void;\n };\n}\n\nexport default templateOnlyComponent<HeadlessFormControlRadioInputComponentSignature>();\n"],"names":["precompileTemplate","templateOnlyComponent"],"mappings":";;;;AACA,eAAeA,kBAAkB,CAAC,2KAA2K,CAAC;;ACiC9M,0BAAA,oBAAA,CAAA,QAAA,EAAeC,qBAAqB,EAAmD,CAAA;;;;"}
|
@@ -0,0 +1,35 @@
|
|
1
|
+
import Component from '@glimmer/component';
|
2
|
+
import LabelComponent from "../label.js";
|
3
|
+
import RadioInputComponent from "./radio/input.js";
|
4
|
+
import { WithBoundArgs } from '@glint/template';
|
5
|
+
interface HeadlessFormControlRadioComponentSignature {
|
6
|
+
Args: {
|
7
|
+
/**
|
8
|
+
* The value of this individual radio control. All the radios that belong to the same field (have the same name) should have distinct values.
|
9
|
+
*/
|
10
|
+
value: string;
|
11
|
+
name: string;
|
12
|
+
selected: string;
|
13
|
+
setValue: (value: string) => void;
|
14
|
+
};
|
15
|
+
Blocks: {
|
16
|
+
default: [
|
17
|
+
{
|
18
|
+
/**
|
19
|
+
* Yielded component that renders the `<label>` of this single radio element.
|
20
|
+
*/
|
21
|
+
Label: WithBoundArgs<typeof LabelComponent, 'fieldId'>;
|
22
|
+
/**
|
23
|
+
* Yielded component that renders the `<input type="radio">` element.
|
24
|
+
*/
|
25
|
+
Input: WithBoundArgs<typeof RadioInputComponent, 'fieldId' | 'value' | 'setValue' | 'checked' | 'name'>;
|
26
|
+
}
|
27
|
+
];
|
28
|
+
};
|
29
|
+
}
|
30
|
+
declare class HeadlessFormControlRadioComponent extends Component<HeadlessFormControlRadioComponentSignature> {
|
31
|
+
LabelComponent: import("@ember/component/template-only").TemplateOnlyComponent<import("../label.js").HeadlessFormLabelComponentSignature>;
|
32
|
+
RadioInputComponent: import("@ember/component/template-only").TemplateOnlyComponent<import("./radio/input.js").HeadlessFormControlRadioInputComponentSignature>;
|
33
|
+
get isChecked(): boolean;
|
34
|
+
}
|
35
|
+
export { HeadlessFormControlRadioComponentSignature, HeadlessFormControlRadioComponent as default };
|
@@ -5,7 +5,7 @@ import Component from '@glimmer/component';
|
|
5
5
|
import LabelComponent from '../label.js';
|
6
6
|
import RadioInputComponent from './radio/input.js';
|
7
7
|
|
8
|
-
var TEMPLATE = precompileTemplate("{{#let (unique-id) as |uuid|}}\n {{yield\n (hash\n
|
8
|
+
var TEMPLATE = precompileTemplate("{{#let (unique-id) as |uuid|}}\n {{yield\n (hash\n Label=(component (ensure-safe-component this.LabelComponent) fieldId=uuid)\n Input=(component\n (ensure-safe-component this.RadioInputComponent)\n name=@name\n fieldId=uuid\n value=@value\n checked=this.isChecked\n setValue=@setValue\n )\n )\n }}\n{{/let}}");
|
9
9
|
|
10
10
|
class HeadlessFormControlRadioComponent extends Component {
|
11
11
|
constructor(...args) {
|
@@ -0,0 +1 @@
|
|
1
|
+
{"version":3,"file":"radio.js","sources":["../../../../src/-private/components/control/radio.hbs.js","../../../../src/-private/components/control/radio.ts"],"sourcesContent":["import { precompileTemplate } from \"@ember/template-compilation\";\nexport default precompileTemplate(\"{{#let (unique-id) as |uuid|}}\\n {{yield\\n (hash\\n Label=(component (ensure-safe-component this.LabelComponent) fieldId=uuid)\\n Input=(component\\n (ensure-safe-component this.RadioInputComponent)\\n name=@name\\n fieldId=uuid\\n value=@value\\n checked=this.isChecked\\n setValue=@setValue\\n )\\n )\\n }}\\n{{/let}}\")","import Component from '@glimmer/component';\n\nimport LabelComponent from '../label';\nimport RadioInputComponent from './radio/input';\n\nimport type { WithBoundArgs } from '@glint/template';\n\nexport interface HeadlessFormControlRadioComponentSignature {\n Args: {\n /**\n * The value of this individual radio control. All the radios that belong to the same field (have the same name) should have distinct values.\n */\n value: string;\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 name: string;\n\n /*\n * @internal\n */\n selected: string;\n\n /*\n * @internal\n */\n setValue: (value: string) => void;\n };\n Blocks: {\n default: [\n {\n /**\n * Yielded component that renders the `<label>` of this single radio element.\n */\n Label: WithBoundArgs<typeof LabelComponent, 'fieldId'>;\n\n /**\n * Yielded component that renders the `<input type=\"radio\">` element.\n */\n Input: WithBoundArgs<\n typeof RadioInputComponent,\n 'fieldId' | 'value' | 'setValue' | 'checked' | 'name'\n >;\n }\n ];\n };\n}\n\nexport default class HeadlessFormControlRadioComponent extends Component<HeadlessFormControlRadioComponentSignature> {\n LabelComponent = LabelComponent;\n RadioInputComponent = RadioInputComponent;\n\n get isChecked(): boolean {\n return this.args.selected === this.args.value;\n }\n}\n"],"names":["precompileTemplate","HeadlessFormControlRadioComponent","Component","LabelComponent","RadioInputComponent","isChecked","args","selected","value"],"mappings":";;;;;;;AACA,eAAeA,kBAAkB,CAAC,sXAAsX,CAAC;;ACkD1Y,MAAMC,iCAAiC,SAASC,SAAS,CAA6C;AAAA,EAAA,WAAA,CAAA,GAAA,IAAA,EAAA;AAAA,IAAA,KAAA,CAAA,GAAA,IAAA,CAAA,CAAA;AAAA,IAAA,eAAA,CAAA,IAAA,EAAA,gBAAA,EAClGC,cAAc,CAAA,CAAA;AAAA,IAAA,eAAA,CAAA,IAAA,EAAA,qBAAA,EACTC,mBAAmB,CAAA,CAAA;AAAA,GAAA;AAEzC,EAAA,IAAIC,SAAS,GAAY;IACvB,OAAO,IAAI,CAACC,IAAI,CAACC,QAAQ,KAAK,IAAI,CAACD,IAAI,CAACE,KAAK,CAAA;AAC/C,GAAA;AACF,CAAA;AAAC,oBAAA,CAAA,QAAA,EAPoBP,iCAAiC,CAAA;;;;"}
|
@@ -0,0 +1,18 @@
|
|
1
|
+
import Component from '@glimmer/component';
|
2
|
+
interface HeadlessFormControlSelectOptionComponentSignature {
|
3
|
+
Element: HTMLOptionElement;
|
4
|
+
Args: {
|
5
|
+
/**
|
6
|
+
* The select's value when this option is selected
|
7
|
+
*/
|
8
|
+
value: string;
|
9
|
+
selected: string;
|
10
|
+
};
|
11
|
+
Blocks: {
|
12
|
+
default: [];
|
13
|
+
};
|
14
|
+
}
|
15
|
+
declare class HeadlessFormControlSelectOptionComponent extends Component<HeadlessFormControlSelectOptionComponentSignature> {
|
16
|
+
get isSelected(): boolean;
|
17
|
+
}
|
18
|
+
export { HeadlessFormControlSelectOptionComponentSignature, HeadlessFormControlSelectOptionComponent as default };
|
@@ -0,0 +1,15 @@
|
|
1
|
+
import { setComponentTemplate } from '@ember/component';
|
2
|
+
import { precompileTemplate } from '@ember/template-compilation';
|
3
|
+
import Component from '@glimmer/component';
|
4
|
+
|
5
|
+
var TEMPLATE = precompileTemplate("{{!\nEmber seems to insist to set `selected` as a property instead of an attribute.\nBut an attribute is needed if you want to use this with SSR/FastBoot, so the selected option is preselected before JS has loaded.\nUsing this wonky workaround for now.\nSee https://github.com/emberjs/ember.js/issues/19115\n}}\n{{#if this.isSelected}}\n <option value={{@value}} selected ...attributes>{{yield}}</option>\n{{else}}\n <option value={{@value}} ...attributes>{{yield}}</option>\n{{/if}}");
|
6
|
+
|
7
|
+
class HeadlessFormControlSelectOptionComponent extends Component {
|
8
|
+
get isSelected() {
|
9
|
+
return this.args.selected === this.args.value;
|
10
|
+
}
|
11
|
+
}
|
12
|
+
setComponentTemplate(TEMPLATE, HeadlessFormControlSelectOptionComponent);
|
13
|
+
|
14
|
+
export { HeadlessFormControlSelectOptionComponent as default };
|
15
|
+
//# sourceMappingURL=option.js.map
|
@@ -0,0 +1 @@
|
|
1
|
+
{"version":3,"file":"option.js","sources":["../../../../../src/-private/components/control/select/option.hbs.js","../../../../../src/-private/components/control/select/option.ts"],"sourcesContent":["import { precompileTemplate } from \"@ember/template-compilation\";\nexport default precompileTemplate(\"{{!\\nEmber seems to insist to set `selected` as a property instead of an attribute.\\nBut an attribute is needed if you want to use this with SSR/FastBoot, so the selected option is preselected before JS has loaded.\\nUsing this wonky workaround for now.\\nSee https://github.com/emberjs/ember.js/issues/19115\\n}}\\n{{#if this.isSelected}}\\n <option value={{@value}} selected ...attributes>{{yield}}</option>\\n{{else}}\\n <option value={{@value}} ...attributes>{{yield}}</option>\\n{{/if}}\")","import Component from '@glimmer/component';\n\nexport interface HeadlessFormControlSelectOptionComponentSignature {\n Element: HTMLOptionElement;\n Args: {\n /**\n * The select's value when this option is selected\n */\n value: string;\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 selected: string;\n };\n Blocks: {\n default: [];\n };\n}\n\nexport default class HeadlessFormControlSelectOptionComponent extends Component<HeadlessFormControlSelectOptionComponentSignature> {\n get isSelected(): boolean {\n return this.args.selected === this.args.value;\n }\n}\n"],"names":["precompileTemplate","HeadlessFormControlSelectOptionComponent","Component","isSelected","args","selected","value"],"mappings":";;;;AACA,eAAeA,kBAAkB,CAAC,ueAAue,CAAC;;ACqB3f,MAAMC,wCAAwC,SAASC,SAAS,CAAoD;AACjI,EAAA,IAAIC,UAAU,GAAY;IACxB,OAAO,IAAI,CAACC,IAAI,CAACC,QAAQ,KAAK,IAAI,CAACD,IAAI,CAACE,KAAK,CAAA;AAC/C,GAAA;AACF,CAAA;AAAC,oBAAA,CAAA,QAAA,EAJoBL,wCAAwC,CAAA;;;;"}
|
@@ -0,0 +1,26 @@
|
|
1
|
+
import Component from '@glimmer/component';
|
2
|
+
import OptionComponent from "./select/option.js";
|
3
|
+
import { WithBoundArgs } from '@glint/template';
|
4
|
+
interface HeadlessFormControlSelectComponentSignature {
|
5
|
+
Element: HTMLSelectElement;
|
6
|
+
Args: {
|
7
|
+
value: string;
|
8
|
+
name: string;
|
9
|
+
fieldId: string;
|
10
|
+
setValue: (value: string) => void;
|
11
|
+
invalid: boolean;
|
12
|
+
errorId: string;
|
13
|
+
};
|
14
|
+
Blocks: {
|
15
|
+
default: [
|
16
|
+
{
|
17
|
+
Option: WithBoundArgs<typeof OptionComponent, 'selected'>;
|
18
|
+
}
|
19
|
+
];
|
20
|
+
};
|
21
|
+
}
|
22
|
+
declare class HeadlessFormControlSelectComponent extends Component<HeadlessFormControlSelectComponentSignature> {
|
23
|
+
OptionComponent: typeof OptionComponent;
|
24
|
+
handleInput(e: Event | InputEvent): void;
|
25
|
+
}
|
26
|
+
export { HeadlessFormControlSelectComponentSignature, HeadlessFormControlSelectComponent as default };
|
@@ -0,0 +1,24 @@
|
|
1
|
+
import _defineProperty from '@babel/runtime/helpers/esm/defineProperty';
|
2
|
+
import _applyDecoratedDescriptor from '@babel/runtime/helpers/esm/applyDecoratedDescriptor';
|
3
|
+
import { setComponentTemplate } from '@ember/component';
|
4
|
+
import { precompileTemplate } from '@ember/template-compilation';
|
5
|
+
import Component from '@glimmer/component';
|
6
|
+
import { action } from '@ember/object';
|
7
|
+
import HeadlessFormControlSelectOptionComponent from './select/option.js';
|
8
|
+
|
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
|
+
|
11
|
+
var _class;
|
12
|
+
let HeadlessFormControlSelectComponent = (_class = class HeadlessFormControlSelectComponent extends Component {
|
13
|
+
constructor(...args) {
|
14
|
+
super(...args);
|
15
|
+
_defineProperty(this, "OptionComponent", HeadlessFormControlSelectOptionComponent);
|
16
|
+
}
|
17
|
+
handleInput(e) {
|
18
|
+
this.args.setValue(e.target.value);
|
19
|
+
}
|
20
|
+
}, (_applyDecoratedDescriptor(_class.prototype, "handleInput", [action], Object.getOwnPropertyDescriptor(_class.prototype, "handleInput"), _class.prototype)), _class);
|
21
|
+
setComponentTemplate(TEMPLATE, HeadlessFormControlSelectComponent);
|
22
|
+
|
23
|
+
export { HeadlessFormControlSelectComponent as default };
|
24
|
+
//# sourceMappingURL=select.js.map
|
@@ -0,0 +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-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 {
|
@@ -0,0 +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-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;;;;"}
|
@@ -0,0 +1 @@
|
|
1
|
+
{"version":3,"file":"errors.js","sources":["../../../src/-private/components/errors.hbs.js","../../../src/-private/components/errors.ts"],"sourcesContent":["import { precompileTemplate } from \"@ember/template-compilation\";\nexport default precompileTemplate(\"<div id={{@id}} aria-live=\\'assertive\\' ...attributes>\\n {{#if (has-block)}}\\n {{yield @errors}}\\n {{else}}\\n {{#each @errors as |e|}}\\n {{#if e.message}}\\n {{e.message}}<br />\\n {{/if}}\\n {{/each}}\\n {{/if}}\\n</div>\")","import Component from '@glimmer/component';\n\nimport type { ValidationError } from '../types';\n\nexport interface HeadlessFormErrorsComponentSignature<VALUE> {\n Element: HTMLDivElement;\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 errors: ValidationError<VALUE>[];\n\n /*\n * @internal\n */\n id: string;\n };\n Blocks: {\n default?: [ValidationError<VALUE>[]];\n };\n}\n\n// eslint-disable-next-line ember/no-empty-glimmer-component-classes -- unfortunately we cannot use templateOnlyComponent() here, as it is not possible to type that as a generic type, like templateOnlyComponent<HeadlessFormErrorsComponentSignature<VALUE>>\nexport default class HeadlessFormErrorsComponent<VALUE> extends Component<\n HeadlessFormErrorsComponentSignature<VALUE>\n> {}\n"],"names":["precompileTemplate","HeadlessFormErrorsComponent","Component"],"mappings":";;;;AACA,eAAeA,kBAAkB,CAAC,uPAAuP,CAAC;;ACuB1R;AACe,MAAMC,2BAA2B,SAAgBC,SAAS,CAEvE,EAAA;AAAE,oBAAA,CAAA,QAAA,EAFiBD,2BAA2B,CAAA;;;;"}
|
@@ -0,0 +1,150 @@
|
|
1
|
+
import Component from '@glimmer/component';
|
2
|
+
import CheckboxComponent from "./control/checkbox.js";
|
3
|
+
import InputComponent from "./control/input.js";
|
4
|
+
import RadioComponent from "./control/radio.js";
|
5
|
+
import SelectComponent from "./control/select.js";
|
6
|
+
import TextareaComponent from "./control/textarea.js";
|
7
|
+
import ErrorsComponent from "./errors.js";
|
8
|
+
import LabelComponent from "./label.js";
|
9
|
+
import { CaptureEventsModifierSignature } from "../modifiers/capture-events.js";
|
10
|
+
import { ErrorRecord, FieldValidateCallback, FormData, FormKey, RegisterFieldCallback, UnregisterFieldCallback, UserData, ValidationError } from "../types.js";
|
11
|
+
import { ModifierLike, WithBoundArgs } from '@glint/template';
|
12
|
+
interface HeadlessFormFieldComponentSignature<DATA extends UserData, KEY extends FormKey<FormData<DATA>> = FormKey<FormData<DATA>>> {
|
13
|
+
Args: {
|
14
|
+
/**
|
15
|
+
* The name of your field, which must match a property of the `@data` passed to the form
|
16
|
+
*/
|
17
|
+
name: KEY;
|
18
|
+
/**
|
19
|
+
* 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.
|
20
|
+
*
|
21
|
+
* Return undefined when no validation errors are present, otherwise an array of (one or multiple) `ValidationError`s.
|
22
|
+
*/
|
23
|
+
validate?: FieldValidateCallback<FormData<DATA>, KEY>;
|
24
|
+
data: FormData<DATA>;
|
25
|
+
set: (key: KEY, value: DATA[KEY]) => void;
|
26
|
+
errors?: ErrorRecord<DATA, KEY>;
|
27
|
+
registerField: RegisterFieldCallback<FormData<DATA>, KEY>;
|
28
|
+
unregisterField: UnregisterFieldCallback<FormData<DATA>, KEY>;
|
29
|
+
triggerValidationFor(name: KEY): Promise<void>;
|
30
|
+
fieldValidationEvent: 'focusout' | 'change' | 'input' | undefined;
|
31
|
+
fieldRevalidationEvent: 'focusout' | 'change' | 'input' | undefined;
|
32
|
+
};
|
33
|
+
Blocks: {
|
34
|
+
default: [
|
35
|
+
{
|
36
|
+
/**
|
37
|
+
* Yielded component that renders the `<label>` element.
|
38
|
+
*/
|
39
|
+
Label: WithBoundArgs<typeof LabelComponent, 'fieldId'>;
|
40
|
+
/**
|
41
|
+
* Yielded control component that renders an `<input>` element.
|
42
|
+
*/
|
43
|
+
Input: WithBoundArgs<typeof InputComponent, 'name' | 'fieldId' | 'value' | 'setValue' | 'invalid' | 'errorId'>;
|
44
|
+
/**
|
45
|
+
* Yielded control component that renders an `<input type="checkbox">` element.
|
46
|
+
*/
|
47
|
+
Checkbox: WithBoundArgs<typeof CheckboxComponent, 'name' | 'fieldId' | 'value' | 'setValue' | 'invalid' | 'errorId'>;
|
48
|
+
/**
|
49
|
+
* Yielded control component that renders a single radio control.
|
50
|
+
*
|
51
|
+
* Use multiple to define a radio group. It further yields components to render `Input` and `Label`.
|
52
|
+
*/
|
53
|
+
Radio: WithBoundArgs<typeof RadioComponent, 'name' | 'selected' | 'setValue'>;
|
54
|
+
/**
|
55
|
+
* Yielded control component that renders a `<select>` element.
|
56
|
+
*/
|
57
|
+
Select: WithBoundArgs<typeof SelectComponent, 'name' | 'fieldId' | 'value' | 'setValue' | 'invalid' | 'errorId'>;
|
58
|
+
/**
|
59
|
+
* Yielded control component that renders a `<textarea>` element.
|
60
|
+
*/
|
61
|
+
Textarea: WithBoundArgs<typeof TextareaComponent, 'name' | 'fieldId' | 'value' | 'setValue' | 'invalid' | 'errorId'>;
|
62
|
+
/**
|
63
|
+
* The current value of the field's form data.
|
64
|
+
*
|
65
|
+
* If you don't use one of the supplied control components, then use this to pass the value to your custom component.
|
66
|
+
*/
|
67
|
+
value: DATA[KEY];
|
68
|
+
/**
|
69
|
+
* Action to update the (internal) form data for this field.
|
70
|
+
*
|
71
|
+
* 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.
|
72
|
+
*/
|
73
|
+
setValue: (value: DATA[KEY]) => void;
|
74
|
+
/**
|
75
|
+
* Unique ID of this field, used to associate the control with its label.
|
76
|
+
*
|
77
|
+
* 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>`.
|
78
|
+
*/
|
79
|
+
id: string;
|
80
|
+
/**
|
81
|
+
* Unique error ID of this field, used to associate the control with its validation error message.
|
82
|
+
*
|
83
|
+
* 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.
|
84
|
+
*/
|
85
|
+
errorId: string;
|
86
|
+
/**
|
87
|
+
* Yielded component that renders all validation error messages if there are any.
|
88
|
+
*
|
89
|
+
* 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.
|
90
|
+
*/
|
91
|
+
Errors?: WithBoundArgs<typeof ErrorsComponent<DATA[KEY]>, 'errors' | 'id'>;
|
92
|
+
/**
|
93
|
+
* Will be `true` when validation was triggered and this field is invalid.
|
94
|
+
*
|
95
|
+
* You can use this to customize your markup, e.g. apply HTML classes for error styling.
|
96
|
+
*/
|
97
|
+
isInvalid: boolean;
|
98
|
+
/**
|
99
|
+
* An array of raw ValidationError objects, for custom rendering of error output
|
100
|
+
*/
|
101
|
+
rawErrors?: ValidationError<DATA[KEY]>[];
|
102
|
+
/**
|
103
|
+
* When calling this action, validation will be triggered.
|
104
|
+
*
|
105
|
+
* Can be used for custom controls that don't emit the `@validateOn` events that would normally trigger a dynamic validation.
|
106
|
+
*/
|
107
|
+
triggerValidation: () => void;
|
108
|
+
/**
|
109
|
+
* 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.
|
110
|
+
*
|
111
|
+
* 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.
|
112
|
+
*/
|
113
|
+
captureEvents: WithBoundArgs<ModifierLike<CaptureEventsModifierSignature>, 'event' | 'triggerValidation'>;
|
114
|
+
}
|
115
|
+
];
|
116
|
+
};
|
117
|
+
}
|
118
|
+
declare class HeadlessFormFieldComponent<DATA extends FormData, KEY extends FormKey<FormData<DATA>> = FormKey<FormData<DATA>>> extends Component<HeadlessFormFieldComponentSignature<DATA, KEY>> {
|
119
|
+
LabelComponent: import("@ember/component/template-only").TemplateOnlyComponent<import("./label.js").HeadlessFormLabelComponentSignature>;
|
120
|
+
InputComponent: typeof InputComponent;
|
121
|
+
CheckboxComponent: typeof CheckboxComponent;
|
122
|
+
ErrorsComponent: {
|
123
|
+
new (owner: unknown, args: {
|
124
|
+
errors: ValidationError<DATA[KEY]>[];
|
125
|
+
id: string;
|
126
|
+
}): ErrorsComponent<DATA[KEY]>;
|
127
|
+
};
|
128
|
+
SelectComponent: typeof SelectComponent;
|
129
|
+
TextareaComponent: typeof TextareaComponent;
|
130
|
+
RadioComponent: typeof RadioComponent;
|
131
|
+
CaptureEventsModifier: import("ember-modifier").FunctionBasedModifier<{
|
132
|
+
Element: HTMLElement;
|
133
|
+
Args: {
|
134
|
+
Named: {
|
135
|
+
event: "focusout" | "change";
|
136
|
+
triggerValidation(): void;
|
137
|
+
};
|
138
|
+
Positional: [];
|
139
|
+
};
|
140
|
+
}>;
|
141
|
+
constructor(owner: unknown, args: HeadlessFormFieldComponentSignature<DATA, KEY>['Args']);
|
142
|
+
willDestroy(): void;
|
143
|
+
get value(): DATA[KEY];
|
144
|
+
get errors(): ValidationError<DATA[KEY]>[] | undefined;
|
145
|
+
get hasErrors(): boolean;
|
146
|
+
get valueAsString(): string | undefined;
|
147
|
+
get valueAsBoolean(): boolean | undefined;
|
148
|
+
setValue(value: unknown): void;
|
149
|
+
}
|
150
|
+
export { HeadlessFormFieldComponentSignature, HeadlessFormFieldComponent as default };
|
@@ -4,16 +4,17 @@ import { setComponentTemplate } from '@ember/component';
|
|
4
4
|
import { precompileTemplate } from '@ember/template-compilation';
|
5
5
|
import Component from '@glimmer/component';
|
6
6
|
import { assert } from '@ember/debug';
|
7
|
-
import { action } from '@ember/object';
|
8
|
-
import CaptureEventsModifier from '
|
7
|
+
import { action, get } from '@ember/object';
|
8
|
+
import CaptureEventsModifier from '../modifiers/capture-events.js';
|
9
9
|
import HeadlessFormControlCheckboxComponent from './control/checkbox.js';
|
10
10
|
import HeadlessFormControlInputComponent from './control/input.js';
|
11
11
|
import HeadlessFormControlRadioComponent from './control/radio.js';
|
12
|
+
import HeadlessFormControlSelectComponent from './control/select.js';
|
12
13
|
import HeadlessFormControlTextareaComponent from './control/textarea.js';
|
13
14
|
import HeadlessFormErrorsComponent from './errors.js';
|
14
15
|
import LabelComponent from './label.js';
|
15
16
|
|
16
|
-
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
|
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}}");
|
17
18
|
|
18
19
|
var _class;
|
19
20
|
let HeadlessFormFieldComponent = (_class = class HeadlessFormFieldComponent extends Component {
|
@@ -23,9 +24,11 @@ let HeadlessFormFieldComponent = (_class = class HeadlessFormFieldComponent exte
|
|
23
24
|
_defineProperty(this, "InputComponent", HeadlessFormControlInputComponent);
|
24
25
|
_defineProperty(this, "CheckboxComponent", HeadlessFormControlCheckboxComponent);
|
25
26
|
_defineProperty(this, "ErrorsComponent", HeadlessFormErrorsComponent);
|
27
|
+
_defineProperty(this, "SelectComponent", HeadlessFormControlSelectComponent);
|
26
28
|
_defineProperty(this, "TextareaComponent", HeadlessFormControlTextareaComponent);
|
27
29
|
_defineProperty(this, "RadioComponent", HeadlessFormControlRadioComponent);
|
28
30
|
_defineProperty(this, "CaptureEventsModifier", CaptureEventsModifier);
|
31
|
+
assert('Nested property paths in @name are not supported.', typeof this.args.name !== 'string' || !this.args.name.includes('.'));
|
29
32
|
this.args.registerField(this.args.name, {
|
30
33
|
validate: this.args.validate
|
31
34
|
});
|
@@ -35,7 +38,9 @@ let HeadlessFormFieldComponent = (_class = class HeadlessFormFieldComponent exte
|
|
35
38
|
super.willDestroy();
|
36
39
|
}
|
37
40
|
get value() {
|
38
|
-
|
41
|
+
// when @mutableData is set, data is something we don't control, i.e. might require old-school get() to be on the safe side
|
42
|
+
// we do not want to support nested property paths for now though, see the constructor assertion!
|
43
|
+
return get(this.args.data, this.args.name);
|
39
44
|
}
|
40
45
|
get errors() {
|
41
46
|
return this.args.errors?.[this.args.name];
|
@@ -0,0 +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 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":";;;;;;;;;;;;;;;;AACA,eAAeA,kBAAkB,CAAC,oiEAAoiE,CAAC;;;ACUliE,IAmMhBC,0BAA0B,IAAhC,MAAA,GAAA,MAAMA,0BAA0B,SAGrCC,SAAS,CAAiD;AAUlEC,EAAAA,WAAW,CACTC,KAAc,EACdC,IAA4D,EAC5D;AACA,IAAA,KAAK,CAACD,KAAK,EAAEC,IAAI,CAAC,CAAA;AAAC,IAAA,eAAA,CAAA,IAAA,EAAA,gBAAA,EAbJC,cAAc,CAAA,CAAA;AAAA,IAAA,eAAA,CAAA,IAAA,EAAA,gBAAA,EACdC,iCAAc,CAAA,CAAA;AAAA,IAAA,eAAA,CAAA,IAAA,EAAA,mBAAA,EACXC,oCAAiB,CAAA,CAAA;AAAA,IAAA,eAAA,CAAA,IAAA,EAAA,iBAAA,EACnBC,2BAAe,CAAA,CAAA;AAAA,IAAA,eAAA,CAAA,IAAA,EAAA,iBAAA,EACfC,kCAAe,CAAA,CAAA;AAAA,IAAA,eAAA,CAAA,IAAA,EAAA,mBAAA,EACbC,oCAAiB,CAAA,CAAA;AAAA,IAAA,eAAA,CAAA,IAAA,EAAA,gBAAA,EACpBC,iCAAc,CAAA,CAAA;AAAA,IAAA,eAAA,CAAA,IAAA,EAAA,uBAAA,EACPC,qBAAqB,CAAA,CAAA;IAQ3CC,MAAM,CACJ,mDAAmD,EACnD,OAAO,IAAI,CAACT,IAAI,CAACU,IAAI,KAAK,QAAQ,IAAI,CAAC,IAAI,CAACV,IAAI,CAACU,IAAI,CAACC,QAAQ,CAAC,GAAG,CAAC,CACpE,CAAA;IAED,IAAI,CAACX,IAAI,CAACY,aAAa,CAAC,IAAI,CAACZ,IAAI,CAACU,IAAI,EAAE;AACtCG,MAAAA,QAAQ,EAAE,IAAI,CAACb,IAAI,CAACa,QAAAA;AACtB,KAAC,CAAC,CAAA;AACJ,GAAA;AAEAC,EAAAA,WAAW,GAAS;IAClB,IAAI,CAACd,IAAI,CAACe,eAAe,CAAC,IAAI,CAACf,IAAI,CAACU,IAAI,CAAC,CAAA;IAEzC,KAAK,CAACI,WAAW,EAAE,CAAA;AACrB,GAAA;AAEA,EAAA,IAAIE,KAAK,GAAc;AACrB;AACA;AACA,IAAA,OAAOC,GAAG,CAAC,IAAI,CAACjB,IAAI,CAACkB,IAAI,EAAE,IAAI,CAAClB,IAAI,CAACU,IAAI,CAAC,CAAA;AAC5C,GAAA;AAEA,EAAA,IAAIS,MAAM,GAA6C;IACrD,OAAO,IAAI,CAACnB,IAAI,CAACmB,MAAM,GAAG,IAAI,CAACnB,IAAI,CAACU,IAAI,CAAC,CAAA;AAC3C,GAAA;AAEA,EAAA,IAAIU,SAAS,GAAY;AACvB,IAAA,OAAO,IAAI,CAACD,MAAM,KAAKE,SAAS,CAAA;AAClC,GAAA;AAEA,EAAA,IAAIC,aAAa,GAAuB;AACtCb,IAAAA,MAAM,CACH,CAAA,oCAAA,EAAsCc,MAAM,CAC3C,IAAI,CAACvB,IAAI,CAACU,IAAI,CACd,CAAmB,iBAAA,EAAA,OAAO,IAAI,CAACM,KAAM,CAAC,CAAA,EACxC,OAAO,IAAI,CAACA,KAAK,KAAK,WAAW,IAAI,OAAO,IAAI,CAACA,KAAK,KAAK,QAAQ,CACpE,CAAA;IAED,OAAO,IAAI,CAACA,KAAK,CAAA;AACnB,GAAA;AAEA,EAAA,IAAIQ,cAAc,GAAwB;AACxCf,IAAAA,MAAM,CACH,CAAA,qCAAA,EAAuCc,MAAM,CAC5C,IAAI,CAACvB,IAAI,CAACU,IAAI,CACd,CAAmB,iBAAA,EAAA,OAAO,IAAI,CAACM,KAAM,CAAC,CAAA,EACxC,OAAO,IAAI,CAACA,KAAK,KAAK,WAAW,IAAI,OAAO,IAAI,CAACA,KAAK,KAAK,SAAS,CACrE,CAAA;IAED,OAAO,IAAI,CAACA,KAAK,CAAA;AACnB,GAAA;EAGAS,QAAQ,CAACT,KAAc,EAAQ;AAC7B,IAAA,IAAI,CAAChB,IAAI,CAAC0B,GAAG,CAAC,IAAI,CAAC1B,IAAI,CAACU,IAAI,EAAEM,KAAK,CAAc,CAAA;AACnD,GAAA;AACF,CAAC,4DAJEW,MAAM,CAAA,EAAA,MAAA,CAAA,wBAAA,CAAA,MAAA,CAAA,SAAA,EAAA,UAAA,CAAA,EAAA,MAAA,CAAA,SAAA,CAAA,GAAA,MAAA,EAAA;AAvEsC,oBAAA,CAAA,QAAA,EAAA,0BAAA,CAAA;;;;"}
|
@@ -0,0 +1 @@
|
|
1
|
+
{"version":3,"file":"label.js","sources":["../../../src/-private/components/label.hbs.js","../../../src/-private/components/label.ts"],"sourcesContent":["import { precompileTemplate } from \"@ember/template-compilation\";\nexport default precompileTemplate(\"<label for={{@fieldId}} ...attributes>\\n {{yield}}\\n</label>\")","import templateOnlyComponent from '@ember/component/template-only';\n\nexport interface HeadlessFormLabelComponentSignature {\n Element: HTMLLabelElement;\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 fieldId: string;\n };\n Blocks: {\n default: [];\n };\n}\n\nexport default templateOnlyComponent<HeadlessFormLabelComponentSignature>();\n"],"names":["precompileTemplate","templateOnlyComponent"],"mappings":";;;;AACA,eAAeA,kBAAkB,CAAC,+DAA+D,CAAC;;ACgBlG,qBAAA,oBAAA,CAAA,QAAA,EAAeC,qBAAqB,EAAuC,CAAA;;;;"}
|
@@ -7,7 +7,7 @@ interface CaptureEventsModifierSignature {
|
|
7
7
|
};
|
8
8
|
};
|
9
9
|
}
|
10
|
-
declare const CaptureEventsModifier: import("ember-modifier
|
10
|
+
declare const CaptureEventsModifier: import("ember-modifier").FunctionBasedModifier<{
|
11
11
|
Element: HTMLElement;
|
12
12
|
Args: {
|
13
13
|
Named: {
|
@@ -18,4 +18,3 @@ declare const CaptureEventsModifier: import("ember-modifier/.").FunctionBasedMod
|
|
18
18
|
};
|
19
19
|
}>;
|
20
20
|
export { CaptureEventsModifier as default, CaptureEventsModifierSignature };
|
21
|
-
//# sourceMappingURL=components/-private/capture-events.d.ts.map
|
@@ -0,0 +1 @@
|
|
1
|
+
{"version":3,"file":"capture-events.js","sources":["../../../src/-private/modifiers/capture-events.ts"],"sourcesContent":["import { modifier } from 'ember-modifier';\n\nexport interface CaptureEventsModifierSignature {\n Element: HTMLElement;\n Args: {\n Named: {\n /*\n * @internal\n */\n event: 'focusout' | 'change';\n\n /*\n * @internal\n */\n triggerValidation(): void;\n };\n };\n}\n\nconst CaptureEventsModifier = modifier<CaptureEventsModifierSignature>(\n (element, _pos, { event, triggerValidation }) => {\n element.addEventListener(event, triggerValidation, { passive: true });\n\n return () => {\n element.removeEventListener(event, triggerValidation);\n };\n }\n);\n\nexport default CaptureEventsModifier;\n"],"names":["CaptureEventsModifier","modifier","element","_pos","event","triggerValidation","addEventListener","passive","removeEventListener"],"mappings":";;AAmBMA,MAAAA,qBAAqB,GAAGC,QAAQ,CACpC,CAACC,OAAO,EAAEC,IAAI,EAAE;EAAEC,KAAK;AAAEC,EAAAA,iBAAAA;AAAkB,CAAC,KAAK;AAC/CH,EAAAA,OAAO,CAACI,gBAAgB,CAACF,KAAK,EAAEC,iBAAiB,EAAE;AAAEE,IAAAA,OAAO,EAAE,IAAA;AAAK,GAAC,CAAC,CAAA;AAErE,EAAA,OAAO,MAAM;AACXL,IAAAA,OAAO,CAACM,mBAAmB,CAACJ,KAAK,EAAEC,iBAAiB,CAAC,CAAA;GACtD,CAAA;AACH,CAAC;;;;"}
|
@@ -23,7 +23,7 @@ type ErrorRecord<DATA extends FormData, KEY extends FormKey<DATA> = FormKey<DATA
|
|
23
23
|
/**
|
24
24
|
* Callback used for form level validation
|
25
25
|
*/
|
26
|
-
type FormValidateCallback<DATA extends FormData> = (formData: DATA) => undefined | ErrorRecord<DATA> | Promise<undefined | ErrorRecord<DATA>>;
|
26
|
+
type FormValidateCallback<DATA extends FormData> = (formData: DATA, fields: Array<FormKey<DATA>>) => undefined | ErrorRecord<DATA> | Promise<undefined | ErrorRecord<DATA>>;
|
27
27
|
/**
|
28
28
|
* Callback used for field level validation
|
29
29
|
*/
|
@@ -0,0 +1 @@
|
|
1
|
+
{"version":3,"file":"utils.js","sources":["../../src/-private/utils.ts"],"sourcesContent":["import type { ErrorRecord, FormData, FormKey, ValidationError } from './types';\n\nexport function mergeErrorRecord<\n DATA extends FormData,\n KEY extends FormKey<DATA> = FormKey<DATA>\n>(\n ...records: Array<ErrorRecord<DATA, KEY> | undefined>\n): ErrorRecord<DATA, KEY> {\n const errors: ErrorRecord<DATA, KEY> = {};\n\n for (const record of records) {\n if (!record) {\n continue;\n }\n\n for (const [name, fieldErrors] of Object.entries(record) as [\n // TS does not infer the types correctly here, fieldErrors would be unknown, not sure why\n KEY,\n ValidationError<DATA[KEY]>[]\n ][]) {\n const existingFieldErrors = errors[name];\n\n errors[name] = existingFieldErrors\n ? [...existingFieldErrors, ...fieldErrors]\n : fieldErrors;\n }\n }\n\n return errors;\n}\n"],"names":["mergeErrorRecord","records","errors","record","name","fieldErrors","Object","entries","existingFieldErrors"],"mappings":"AAEO,SAASA,gBAAgB,CAI9B,GAAGC,OAAkD,EAC7B;EACxB,MAAMC,MAA8B,GAAG,EAAE,CAAA;AAEzC,EAAA,KAAK,MAAMC,MAAM,IAAIF,OAAO,EAAE;IAC5B,IAAI,CAACE,MAAM,EAAE;AACX,MAAA,SAAA;AACF,KAAA;AAEA,IAAA,KAAK,MAAM,CAACC,IAAI,EAAEC,WAAW,CAAC,IAAIC,MAAM,CAACC,OAAO,CAACJ,MAAM,CAAC,EAInD;AACH,MAAA,MAAMK,mBAAmB,GAAGN,MAAM,CAACE,IAAI,CAAC,CAAA;AAExCF,MAAAA,MAAM,CAACE,IAAI,CAAC,GAAGI,mBAAmB,GAC9B,CAAC,GAAGA,mBAAmB,EAAE,GAAGH,WAAW,CAAC,GACxCA,WAAW,CAAA;AACjB,KAAA;AACF,GAAA;AAEA,EAAA,OAAOH,MAAM,CAAA;AACf;;;;"}
|