@hokulea/ember 0.7.2 → 0.8.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/declarations/components/form/description.gts.d.ts.map +1 -0
- package/declarations/components/form/errors.gts.d.ts +15 -0
- package/declarations/components/form/errors.gts.d.ts.map +1 -0
- package/declarations/components/form/field.gts.d.ts +111 -0
- package/declarations/components/form/field.gts.d.ts.map +1 -0
- package/declarations/components/form/fields/checkbox.gts.d.ts +16 -0
- package/declarations/components/form/fields/checkbox.gts.d.ts.map +1 -0
- package/declarations/components/form/fields/currency.gts.d.ts +16 -0
- package/declarations/components/form/fields/currency.gts.d.ts.map +1 -0
- package/declarations/components/form/fields/date.gts.d.ts +16 -0
- package/declarations/components/form/fields/date.gts.d.ts.map +1 -0
- package/declarations/components/form/fields/email.gts.d.ts +16 -0
- package/declarations/components/form/fields/email.gts.d.ts.map +1 -0
- package/declarations/components/form/fields/list.gts.d.ts +28 -0
- package/declarations/components/form/fields/list.gts.d.ts.map +1 -0
- package/declarations/components/form/fields/multiple-choice.gts.d.ts +60 -0
- package/declarations/components/form/fields/multiple-choice.gts.d.ts.map +1 -0
- package/declarations/components/form/fields/number.gts.d.ts +16 -0
- package/declarations/components/form/fields/number.gts.d.ts.map +1 -0
- package/declarations/components/form/fields/password.gts.d.ts +18 -0
- package/declarations/components/form/fields/password.gts.d.ts.map +1 -0
- package/declarations/components/form/fields/phone.gts.d.ts +18 -0
- package/declarations/components/form/fields/phone.gts.d.ts.map +1 -0
- package/declarations/components/form/fields/range.gts.d.ts +16 -0
- package/declarations/components/form/fields/range.gts.d.ts.map +1 -0
- package/declarations/components/form/fields/select.gts.d.ts +17 -0
- package/declarations/components/form/fields/select.gts.d.ts.map +1 -0
- package/declarations/components/form/fields/singular-choice.gts.d.ts +56 -0
- package/declarations/components/form/fields/singular-choice.gts.d.ts.map +1 -0
- package/declarations/{-private/form/components → components/form}/fields/stories-utils.d.ts +2 -2
- package/declarations/components/form/fields/stories-utils.d.ts.map +1 -0
- package/declarations/components/form/fields/text-area.gts.d.ts +16 -0
- package/declarations/components/form/fields/text-area.gts.d.ts.map +1 -0
- package/declarations/components/form/fields/text.gts.d.ts +18 -0
- package/declarations/components/form/fields/text.gts.d.ts.map +1 -0
- package/declarations/components/form/form.gts.d.ts +210 -0
- package/declarations/components/form/form.gts.d.ts.map +1 -0
- package/declarations/components/form/index.d.ts +4 -0
- package/declarations/components/form/index.d.ts.map +1 -0
- package/declarations/components/form/label.gts.d.ts.map +1 -0
- package/declarations/components/form/manage-validation.d.ts +18 -0
- package/declarations/components/form/manage-validation.d.ts.map +1 -0
- package/declarations/components/form/reset.gts.d.ts.map +1 -0
- package/declarations/components/form/rules.gts.d.ts +36 -0
- package/declarations/components/form/rules.gts.d.ts.map +1 -0
- package/declarations/components/form/submit.gts.d.ts.map +1 -0
- package/declarations/components/form.gts.d.ts +1 -318
- package/declarations/components/form.gts.d.ts.map +1 -1
- package/declarations/components/page.gts.d.ts +1 -1
- package/declarations/components/page.gts.d.ts.map +1 -1
- package/declarations/components/select.gts.d.ts.map +1 -1
- package/declarations/index.d.ts +2 -3
- package/declarations/index.d.ts.map +1 -1
- package/declarations/test-support/page-objects/-private/field.d.ts +4 -0
- package/declarations/test-support/page-objects/-private/field.d.ts.map +1 -1
- package/dist/components/checkbox.js +1 -1
- package/dist/components/checkbox.js.map +1 -1
- package/dist/components/currency-input.js +1 -1
- package/dist/components/currency-input.js.map +1 -1
- package/dist/components/date-input.js +1 -1
- package/dist/components/date-input.js.map +1 -1
- package/dist/components/email-input.js +1 -1
- package/dist/components/email-input.js.map +1 -1
- package/dist/components/form.js +1 -835
- package/dist/components/form.js.map +1 -1
- package/dist/components/number-input.js +1 -1
- package/dist/components/number-input.js.map +1 -1
- package/dist/components/page.js +1 -1
- package/dist/components/page.js.map +1 -1
- package/dist/components/password-input.js +1 -1
- package/dist/components/password-input.js.map +1 -1
- package/dist/components/phone-input.js +1 -1
- package/dist/components/phone-input.js.map +1 -1
- package/dist/components/radio.js +1 -1
- package/dist/components/radio.js.map +1 -1
- package/dist/components/range-input.js +3 -3
- package/dist/components/range-input.js.map +1 -1
- package/dist/components/select.js +1 -1
- package/dist/components/select.js.map +1 -1
- package/dist/components/text-area.js +1 -1
- package/dist/components/text-area.js.map +1 -1
- package/dist/components/text-input.js +1 -1
- package/dist/components/text-input.js.map +1 -1
- package/dist/form-DBuzL4_0.js +518 -0
- package/dist/form-DBuzL4_0.js.map +1 -0
- package/dist/index.js +1 -1
- package/dist/test-support/index.js +6 -0
- package/dist/test-support/index.js.map +1 -1
- package/package.json +27 -25
- package/declarations/-private/form/components/description.gts.d.ts.map +0 -1
- package/declarations/-private/form/components/errors.gts.d.ts +0 -15
- package/declarations/-private/form/components/errors.gts.d.ts.map +0 -1
- package/declarations/-private/form/components/field.gts.d.ts +0 -147
- package/declarations/-private/form/components/field.gts.d.ts.map +0 -1
- package/declarations/-private/form/components/fields/checkbox.gts.d.ts +0 -15
- package/declarations/-private/form/components/fields/checkbox.gts.d.ts.map +0 -1
- package/declarations/-private/form/components/fields/currency.gts.d.ts +0 -15
- package/declarations/-private/form/components/fields/currency.gts.d.ts.map +0 -1
- package/declarations/-private/form/components/fields/date.gts.d.ts +0 -15
- package/declarations/-private/form/components/fields/date.gts.d.ts.map +0 -1
- package/declarations/-private/form/components/fields/email.gts.d.ts +0 -15
- package/declarations/-private/form/components/fields/email.gts.d.ts.map +0 -1
- package/declarations/-private/form/components/fields/list.gts.d.ts +0 -27
- package/declarations/-private/form/components/fields/list.gts.d.ts.map +0 -1
- package/declarations/-private/form/components/fields/multiple-choice.gts.d.ts +0 -58
- package/declarations/-private/form/components/fields/multiple-choice.gts.d.ts.map +0 -1
- package/declarations/-private/form/components/fields/number.gts.d.ts +0 -15
- package/declarations/-private/form/components/fields/number.gts.d.ts.map +0 -1
- package/declarations/-private/form/components/fields/password.gts.d.ts +0 -15
- package/declarations/-private/form/components/fields/password.gts.d.ts.map +0 -1
- package/declarations/-private/form/components/fields/phone.gts.d.ts +0 -15
- package/declarations/-private/form/components/fields/phone.gts.d.ts.map +0 -1
- package/declarations/-private/form/components/fields/range.gts.d.ts +0 -15
- package/declarations/-private/form/components/fields/range.gts.d.ts.map +0 -1
- package/declarations/-private/form/components/fields/select.gts.d.ts +0 -16
- package/declarations/-private/form/components/fields/select.gts.d.ts.map +0 -1
- package/declarations/-private/form/components/fields/singular-choice.gts.d.ts +0 -56
- package/declarations/-private/form/components/fields/singular-choice.gts.d.ts.map +0 -1
- package/declarations/-private/form/components/fields/stories-utils.d.ts.map +0 -1
- package/declarations/-private/form/components/fields/text-area.gts.d.ts +0 -15
- package/declarations/-private/form/components/fields/text-area.gts.d.ts.map +0 -1
- package/declarations/-private/form/components/fields/text.gts.d.ts +0 -15
- package/declarations/-private/form/components/fields/text.gts.d.ts.map +0 -1
- package/declarations/-private/form/components/label.gts.d.ts.map +0 -1
- package/declarations/-private/form/components/reset.gts.d.ts.map +0 -1
- package/declarations/-private/form/components/submit.gts.d.ts.map +0 -1
- package/declarations/-private/form/index.d.ts +0 -49
- package/declarations/-private/form/index.d.ts.map +0 -1
- package/declarations/-private/form/modifiers/capture-events.d.ts +0 -21
- package/declarations/-private/form/modifiers/capture-events.d.ts.map +0 -1
- package/declarations/-private/form/modifiers/manage-validation.d.ts +0 -24
- package/declarations/-private/form/modifiers/manage-validation.d.ts.map +0 -1
- /package/declarations/{-private/form/components → components/form}/description.gts.d.ts +0 -0
- /package/declarations/{-private/form/components → components/form}/label.gts.d.ts +0 -0
- /package/declarations/{-private/form/components → components/form}/reset.gts.d.ts +0 -0
- /package/declarations/{-private/form/components → components/form}/submit.gts.d.ts +0 -0
package/dist/components/form.js
CHANGED
|
@@ -1,836 +1,2 @@
|
|
|
1
|
-
|
|
2
|
-
import { tracked, cached } from '@glimmer/tracking';
|
|
3
|
-
import { assert, warn } from '@ember/debug';
|
|
4
|
-
import { hash, fn, uniqueId } from '@ember/helper';
|
|
5
|
-
import { on } from '@ember/modifier';
|
|
6
|
-
import { get, set } from '@ember/object';
|
|
7
|
-
import { TrackedAsyncData } from 'ember-async-data';
|
|
8
|
-
import Modifier, { modifier } from 'ember-modifier';
|
|
9
|
-
import { TrackedObject } from 'tracked-built-ins';
|
|
10
|
-
import styles from '@hokulea/core/forms.module.css';
|
|
11
|
-
import { element } from 'ember-element-helper';
|
|
12
|
-
import { precompileTemplate } from '@ember/template-compilation';
|
|
13
|
-
import { setComponentTemplate } from '@ember/component';
|
|
14
|
-
import templateOnly from '@ember/component/template-only';
|
|
15
|
-
import Checkbox from './checkbox.js';
|
|
16
|
-
import { b as asBoolean, c as asNumber, d as asString, e as eq } from '../helpers-DS9du02l.js';
|
|
17
|
-
import CurrencyInput from './currency-input.js';
|
|
18
|
-
import DateInput from './date-input.js';
|
|
19
|
-
import EmailInput from './email-input.js';
|
|
20
|
-
import List from './list.js';
|
|
21
|
-
import NumberInput from './number-input.js';
|
|
22
|
-
import PasswordInput from './password-input.js';
|
|
23
|
-
import PhoneInput from './phone-input.js';
|
|
24
|
-
import RangeInput from './range-input.js';
|
|
25
|
-
import Select from './select.js';
|
|
26
|
-
import Radio from './radio.js';
|
|
27
|
-
import TextInput from './text-input.js';
|
|
28
|
-
import TextArea from './text-area.js';
|
|
29
|
-
import styles$1 from '@hokulea/core/actions.module.css';
|
|
30
|
-
import { d as disabled } from '../disabled-B_FQ0Z51.js';
|
|
31
|
-
import { g, i, n } from 'decorator-transforms/runtime-esm';
|
|
32
|
-
|
|
33
|
-
const CaptureEventsModifier = modifier(
|
|
34
|
-
// eslint-disable-next-line @typescript-eslint/unbound-method
|
|
35
|
-
(element, _pos, {
|
|
36
|
-
event,
|
|
37
|
-
triggerValidation
|
|
38
|
-
}) => {
|
|
39
|
-
if (event) {
|
|
40
|
-
element.addEventListener(event, triggerValidation, {
|
|
41
|
-
passive: true
|
|
42
|
-
});
|
|
43
|
-
return () => {
|
|
44
|
-
element.removeEventListener(event, triggerValidation);
|
|
45
|
-
};
|
|
46
|
-
}
|
|
47
|
-
return;
|
|
48
|
-
});
|
|
49
|
-
|
|
50
|
-
// import { modifier } from 'ember-modifier';
|
|
51
|
-
class ManageValidationModifier extends Modifier {
|
|
52
|
-
modify(element, _pos, {
|
|
53
|
-
name,
|
|
54
|
-
showErrorsFor,
|
|
55
|
-
invalid,
|
|
56
|
-
errorMessageId
|
|
57
|
-
}) {
|
|
58
|
-
if (showErrorsFor(name)) {
|
|
59
|
-
element.ariaInvalid = invalid ? 'true' : 'false';
|
|
60
|
-
if (invalid) {
|
|
61
|
-
element.setAttribute('aria-errormessage', errorMessageId);
|
|
62
|
-
} else {
|
|
63
|
-
element.removeAttribute('aria-errormessage');
|
|
64
|
-
}
|
|
65
|
-
if (element.parentElement && 'inputBuilder' in element.parentElement.dataset) {
|
|
66
|
-
element.parentElement.dataset.invalid = invalid ? 'true' : 'false';
|
|
67
|
-
}
|
|
68
|
-
}
|
|
69
|
-
return;
|
|
70
|
-
}
|
|
71
|
-
}
|
|
72
|
-
|
|
73
|
-
const Description = setComponentTemplate(precompileTemplate("\n <p class={{styles.description}} data-test-description ...attributes>\n {{yield}}\n </p>\n", {
|
|
74
|
-
strictMode: true,
|
|
75
|
-
scope: () => ({
|
|
76
|
-
styles
|
|
77
|
-
})
|
|
78
|
-
}), templateOnly());
|
|
79
|
-
|
|
80
|
-
class Errors extends Component {
|
|
81
|
-
static {
|
|
82
|
-
setComponentTemplate(precompileTemplate("\n <div id={{@id}} aria-live=\"assertive\" class={{styles.errors}} ...attributes>\n {{!-- <span><Icon @icon='dismiss-circle' @style='filled' /></span> --}}\n {{#if (has-block)}}\n {{yield @errors}}\n {{else}}\n <div>\n {{#each @errors as |e|}}\n {{#if e.message}}\n <p data-test-error data-test-error-type=\"{{e.type}}\" data-test-error-value=\"{{e.value}}\">{{e.message}}</p>\n {{/if}}\n {{/each}}\n </div>\n {{/if}}\n </div>\n ", {
|
|
83
|
-
strictMode: true,
|
|
84
|
-
scope: () => ({
|
|
85
|
-
styles
|
|
86
|
-
})
|
|
87
|
-
}), this);
|
|
88
|
-
}
|
|
89
|
-
}
|
|
90
|
-
|
|
91
|
-
const Label = setComponentTemplate(precompileTemplate("\n {{#let (if @element @element (element \"label\")) as |Element|}}\n <Element class={{styles.label}} data-test-label ...attributes>\n {{yield}}\n </Element>\n {{/let}}\n", {
|
|
92
|
-
strictMode: true,
|
|
93
|
-
scope: () => ({
|
|
94
|
-
element,
|
|
95
|
-
styles
|
|
96
|
-
})
|
|
97
|
-
}), templateOnly());
|
|
98
|
-
|
|
99
|
-
class Field extends Component {
|
|
100
|
-
// Label = this.args.labelComponent ?? Label;
|
|
101
|
-
ManagaValidationModifier = ManageValidationModifier;
|
|
102
|
-
constructor(owner, args) {
|
|
103
|
-
super(owner, args);
|
|
104
|
-
assert('Nested property paths in @name are not supported.', typeof this.args.name !== 'string' || !this.args.name.includes('.'));
|
|
105
|
-
this.args.registerField(this.args.name, {
|
|
106
|
-
validate: this.args.validate
|
|
107
|
-
});
|
|
108
|
-
}
|
|
109
|
-
willDestroy() {
|
|
110
|
-
this.args.unregisterField(this.args.name);
|
|
111
|
-
super.willDestroy();
|
|
112
|
-
}
|
|
113
|
-
get value() {
|
|
114
|
-
// when @mutableData is set, data is something we don't control, i.e. might require old-school get() to be on the safe side
|
|
115
|
-
// we do not want to support nested property paths for now though, see the constructor assertion!
|
|
116
|
-
return get(this.args.data, this.args.name);
|
|
117
|
-
}
|
|
118
|
-
get errors() {
|
|
119
|
-
return this.args.errors?.[this.args.name];
|
|
120
|
-
}
|
|
121
|
-
get invalid() {
|
|
122
|
-
return this.errors !== undefined;
|
|
123
|
-
}
|
|
124
|
-
get valueAsString() {
|
|
125
|
-
assert(`Only string values are expected for ${String(this.args.name)}, but you passed ${typeof this.value}`,
|
|
126
|
-
// eslint-disable-next-line unicorn/no-typeof-undefined
|
|
127
|
-
typeof this.value === 'undefined' || typeof this.value === 'string');
|
|
128
|
-
return this.value;
|
|
129
|
-
}
|
|
130
|
-
get valueAsStringOrNumber() {
|
|
131
|
-
assert(`Only string or number values are expected for ${String(this.args.name)}, but you passed ${typeof this.value}`,
|
|
132
|
-
// eslint-disable-next-line unicorn/no-typeof-undefined
|
|
133
|
-
typeof this.value === 'undefined' || typeof this.value === 'string' || typeof this.value === 'number');
|
|
134
|
-
return this.value;
|
|
135
|
-
}
|
|
136
|
-
get valueAsBoolean() {
|
|
137
|
-
assert(`Only boolean values are expected for ${String(this.args.name)}, but you passed ${typeof this.value}`,
|
|
138
|
-
// eslint-disable-next-line unicorn/no-typeof-undefined
|
|
139
|
-
typeof this.value === 'undefined' || typeof this.value === 'boolean');
|
|
140
|
-
return this.value;
|
|
141
|
-
}
|
|
142
|
-
setValue = value => {
|
|
143
|
-
this.args.set(this.args.name, value);
|
|
144
|
-
};
|
|
145
|
-
static {
|
|
146
|
-
setComponentTemplate(precompileTemplate("\n {{#let (uniqueId) (uniqueId) (fn @triggerValidationFor @name) (if @element @element (element \"div\")) as |fieldId errorId triggerValidation Element|}}\n <Element class={{styles.field}} data-test-field={{@name}}>\n {{#if @label}}\n {{#let (if @labelComponent @labelComponent Label) as |L|}}\n <L for={{unless @labelComponent fieldId}}>{{@label}}</L>\n {{/let}}\n {{/if}}\n\n {{#if @description}}\n <Description>{{@description}}</Description>\n {{/if}}\n\n {{yield (hash value=this.value setValue=this.setValue id=fieldId errorId=errorId invalid=this.invalid rawErrors=this.errors triggerValidation=triggerValidation captureEvents=(modifier CaptureEventsModifier event=(if this.invalid @fieldRevalidationEvent @fieldValidationEvent) triggerValidation=triggerValidation) manageValidation=(modifier this.ManagaValidationModifier invalid=this.invalid errorMessageId=errorId name=@name showErrorsFor=@showErrorsFor))}}\n\n {{#if this.errors}}\n <Errors @id={{errorId}} @errors={{this.errors}} />\n {{/if}}\n </Element>\n {{/let}}\n ", {
|
|
147
|
-
strictMode: true,
|
|
148
|
-
scope: () => ({
|
|
149
|
-
uniqueId,
|
|
150
|
-
fn,
|
|
151
|
-
element,
|
|
152
|
-
styles,
|
|
153
|
-
Label,
|
|
154
|
-
Description,
|
|
155
|
-
hash,
|
|
156
|
-
CaptureEventsModifier,
|
|
157
|
-
Errors
|
|
158
|
-
})
|
|
159
|
-
}), this);
|
|
160
|
-
}
|
|
161
|
-
}
|
|
162
|
-
|
|
163
|
-
class RadioField extends Component {
|
|
164
|
-
Field = this.args.Field;
|
|
165
|
-
setBooleanValue = setValue => {
|
|
166
|
-
return value => setValue(value);
|
|
167
|
-
};
|
|
168
|
-
static {
|
|
169
|
-
setComponentTemplate(precompileTemplate("\n <this.Field @label=\"\" @name={{@name}} @validate={{@validate}} as |f|>\n <div class={{styles.choices}}>\n <div class={{styles.choice}}>\n <span>\n <Checkbox @value={{asBoolean f.value}} @update={{this.setBooleanValue f.setValue}} @disabled={{@disabled}} id={{f.id}} name={{@name}} {{f.manageValidation}} {{f.captureEvents}} ...attributes />\n </span>\n\n <div>\n <Label for={{f.id}}>{{@label}}</Label>\n\n {{#if @description}}\n <Description>{{@description}}</Description>\n {{/if}}\n </div>\n </div>\n </div>\n </this.Field>\n ", {
|
|
170
|
-
strictMode: true,
|
|
171
|
-
scope: () => ({
|
|
172
|
-
styles,
|
|
173
|
-
Checkbox,
|
|
174
|
-
asBoolean,
|
|
175
|
-
Label,
|
|
176
|
-
Description
|
|
177
|
-
})
|
|
178
|
-
}), this);
|
|
179
|
-
}
|
|
180
|
-
}
|
|
181
|
-
|
|
182
|
-
class CurrencyField extends Component {
|
|
183
|
-
Field = this.args.Field;
|
|
184
|
-
setNumberValue = setValue => {
|
|
185
|
-
return value => setValue(value);
|
|
186
|
-
};
|
|
187
|
-
static {
|
|
188
|
-
setComponentTemplate(precompileTemplate("\n <this.Field @name={{@name}} @label={{@label}} @description={{@description}} @validate={{@validate}} as |f|>\n <CurrencyInput @value={{asNumber f.value}} @update={{this.setNumberValue f.setValue}} @disabled={{@disabled}} name={{@name}} id={{f.id}} {{f.manageValidation}} {{f.captureEvents}} ...attributes />\n </this.Field>\n ", {
|
|
189
|
-
strictMode: true,
|
|
190
|
-
scope: () => ({
|
|
191
|
-
CurrencyInput,
|
|
192
|
-
asNumber
|
|
193
|
-
})
|
|
194
|
-
}), this);
|
|
195
|
-
}
|
|
196
|
-
}
|
|
197
|
-
|
|
198
|
-
class DateField extends Component {
|
|
199
|
-
Field = this.args.Field;
|
|
200
|
-
setStringValue = setValue => {
|
|
201
|
-
return value => setValue(value);
|
|
202
|
-
};
|
|
203
|
-
static {
|
|
204
|
-
setComponentTemplate(precompileTemplate("\n <this.Field @name={{@name}} @label={{@label}} @description={{@description}} @validate={{@validate}} as |f|>\n <DateInput @value={{asString f.value}} @update={{this.setStringValue f.setValue}} @disabled={{@disabled}} name={{@name}} id={{f.id}} {{f.manageValidation}} {{f.captureEvents}} ...attributes />\n </this.Field>\n ", {
|
|
205
|
-
strictMode: true,
|
|
206
|
-
scope: () => ({
|
|
207
|
-
DateInput,
|
|
208
|
-
asString
|
|
209
|
-
})
|
|
210
|
-
}), this);
|
|
211
|
-
}
|
|
212
|
-
}
|
|
213
|
-
|
|
214
|
-
class EmailField extends Component {
|
|
215
|
-
Field = this.args.Field;
|
|
216
|
-
setStringValue = setValue => {
|
|
217
|
-
return value => setValue(value);
|
|
218
|
-
};
|
|
219
|
-
static {
|
|
220
|
-
setComponentTemplate(precompileTemplate("\n <this.Field @name={{@name}} @label={{@label}} @description={{@description}} @validate={{@validate}} as |f|>\n <EmailInput @value={{asString f.value}} @update={{this.setStringValue f.setValue}} @disabled={{@disabled}} name={{@name}} id={{f.id}} {{f.manageValidation}} {{f.captureEvents}} ...attributes />\n </this.Field>\n ", {
|
|
221
|
-
strictMode: true,
|
|
222
|
-
scope: () => ({
|
|
223
|
-
EmailInput,
|
|
224
|
-
asString
|
|
225
|
-
})
|
|
226
|
-
}), this);
|
|
227
|
-
}
|
|
228
|
-
}
|
|
229
|
-
|
|
230
|
-
const ListLabel = setComponentTemplate(precompileTemplate("\n <Label @element={{element \"span\"}} id={{@id}}>{{yield}}</Label>\n", {
|
|
231
|
-
strictMode: true,
|
|
232
|
-
scope: () => ({
|
|
233
|
-
Label,
|
|
234
|
-
element
|
|
235
|
-
})
|
|
236
|
-
}), templateOnly());
|
|
237
|
-
class ListField extends Component {
|
|
238
|
-
Field = this.args.Field;
|
|
239
|
-
List = List;
|
|
240
|
-
setValue = setValue => {
|
|
241
|
-
return value => setValue(value);
|
|
242
|
-
};
|
|
243
|
-
asValue = value => value;
|
|
244
|
-
static {
|
|
245
|
-
setComponentTemplate(precompileTemplate("\n {{#let (uniqueId) as |labelId|}}\n <this.Field @name={{@name}} @label={{@label}} @labelComponent={{component ListLabel id=labelId}} @description={{@description}} @validate={{@validate}} as |f|>\n <this.List @value={{this.asValue f.value}} @update={{this.setValue f.setValue}} @disabled={{@disabled}} {{!-- name={{@name}} --}} aria-labelledby={{labelId}} {{f.manageValidation}} {{f.captureEvents}} ...attributes as |s|>\n {{yield s}}\n </this.List>\n </this.Field>\n {{/let}}\n ", {
|
|
246
|
-
strictMode: true,
|
|
247
|
-
scope: () => ({
|
|
248
|
-
uniqueId,
|
|
249
|
-
ListLabel
|
|
250
|
-
})
|
|
251
|
-
}), this);
|
|
252
|
-
}
|
|
253
|
-
}
|
|
254
|
-
|
|
255
|
-
let Option$1 = class Option extends Component {
|
|
256
|
-
select = checked => {
|
|
257
|
-
if (checked) {
|
|
258
|
-
this.args.field.setValue([...(this.args.field.value ?? []), this.args.value]);
|
|
259
|
-
} else {
|
|
260
|
-
const values = this.args.field.value;
|
|
261
|
-
const index = this.args.field.value?.indexOf(this.args.value);
|
|
262
|
-
if (Array.isArray(values) && index) {
|
|
263
|
-
values.splice(index, 1);
|
|
264
|
-
this.args.field.setValue(values);
|
|
265
|
-
}
|
|
266
|
-
}
|
|
267
|
-
};
|
|
268
|
-
get checked() {
|
|
269
|
-
return this.args.field.value?.includes(this.args.value);
|
|
270
|
-
}
|
|
271
|
-
static {
|
|
272
|
-
setComponentTemplate(precompileTemplate("\n {{#let (uniqueId) as |id|}}\n <div class={{styles.choice}} data-test-option>\n <span>\n <Checkbox @value={{this.checked}} @update={{this.select}} @disabled={{@disabled}} id={{id}} name={{@name}} value={{@value}} {{@field.manageValidation}} {{@field.captureEvents}} ...attributes />\n </span>\n\n <div>\n <Label for={{id}}>{{@label}}</Label>\n\n {{#if @description}}\n <Description>{{@description}}</Description>\n {{/if}}\n\n {{yield}}\n </div>\n </div>\n {{/let}}\n ", {
|
|
273
|
-
strictMode: true,
|
|
274
|
-
scope: () => ({
|
|
275
|
-
uniqueId,
|
|
276
|
-
styles,
|
|
277
|
-
Checkbox,
|
|
278
|
-
Label,
|
|
279
|
-
Description
|
|
280
|
-
})
|
|
281
|
-
}), this);
|
|
282
|
-
}
|
|
283
|
-
};
|
|
284
|
-
class MultipleChoiceField extends Component {
|
|
285
|
-
Field = this.args.Field;
|
|
286
|
-
Option = Option$1;
|
|
287
|
-
asMultiField = field => {
|
|
288
|
-
return field;
|
|
289
|
-
};
|
|
290
|
-
static {
|
|
291
|
-
setComponentTemplate(precompileTemplate("\n <this.Field @element={{element \"fieldset\"}} @labelComponent={{component Label element=(element \"legend\")}} @name={{@name}} @label={{@label}} @description={{@description}} @validate={{@validate}} as |f|>\n <div class={{styles.choices}} data-test-choices>\n {{yield (hash Option=(component this.Option field=(this.asMultiField f) name=@name disabled=@disabled))}}\n </div>\n </this.Field>\n ", {
|
|
292
|
-
strictMode: true,
|
|
293
|
-
scope: () => ({
|
|
294
|
-
element,
|
|
295
|
-
Label,
|
|
296
|
-
styles,
|
|
297
|
-
hash
|
|
298
|
-
})
|
|
299
|
-
}), this);
|
|
300
|
-
}
|
|
301
|
-
}
|
|
302
|
-
|
|
303
|
-
class NumberField extends Component {
|
|
304
|
-
Field = this.args.Field;
|
|
305
|
-
setNumberValue = setValue => {
|
|
306
|
-
return value => setValue(value);
|
|
307
|
-
};
|
|
308
|
-
static {
|
|
309
|
-
setComponentTemplate(precompileTemplate("\n <this.Field @name={{@name}} @label={{@label}} @description={{@description}} @validate={{@validate}} as |f|>\n <NumberInput @value={{asNumber f.value}} @update={{this.setNumberValue f.setValue}} @disabled={{@disabled}} name={{@name}} id={{f.id}} {{f.manageValidation}} {{f.captureEvents}} ...attributes />\n </this.Field>\n ", {
|
|
310
|
-
strictMode: true,
|
|
311
|
-
scope: () => ({
|
|
312
|
-
NumberInput,
|
|
313
|
-
asNumber
|
|
314
|
-
})
|
|
315
|
-
}), this);
|
|
316
|
-
}
|
|
317
|
-
}
|
|
318
|
-
|
|
319
|
-
class PasswordField extends Component {
|
|
320
|
-
Field = this.args.Field;
|
|
321
|
-
setStringValue = setValue => {
|
|
322
|
-
return value => setValue(value);
|
|
323
|
-
};
|
|
324
|
-
static {
|
|
325
|
-
setComponentTemplate(precompileTemplate("\n <this.Field @name={{@name}} @label={{@label}} @description={{@description}} @validate={{@validate}} as |f|>\n <PasswordInput @value={{asString f.value}} @update={{this.setStringValue f.setValue}} @disabled={{@disabled}} name={{@name}} id={{f.id}} {{f.manageValidation}} {{f.captureEvents}} ...attributes />\n </this.Field>\n ", {
|
|
326
|
-
strictMode: true,
|
|
327
|
-
scope: () => ({
|
|
328
|
-
PasswordInput,
|
|
329
|
-
asString
|
|
330
|
-
})
|
|
331
|
-
}), this);
|
|
332
|
-
}
|
|
333
|
-
}
|
|
334
|
-
|
|
335
|
-
class PhoneField extends Component {
|
|
336
|
-
Field = this.args.Field;
|
|
337
|
-
setStringValue = setValue => {
|
|
338
|
-
return value => setValue(value);
|
|
339
|
-
};
|
|
340
|
-
static {
|
|
341
|
-
setComponentTemplate(precompileTemplate("\n <this.Field @name={{@name}} @label={{@label}} @description={{@description}} @validate={{@validate}} as |f|>\n <PhoneInput @value={{asString f.value}} @update={{this.setStringValue f.setValue}} @disabled={{@disabled}} name={{@name}} id={{f.id}} {{f.manageValidation}} {{f.captureEvents}} ...attributes />\n </this.Field>\n ", {
|
|
342
|
-
strictMode: true,
|
|
343
|
-
scope: () => ({
|
|
344
|
-
PhoneInput,
|
|
345
|
-
asString
|
|
346
|
-
})
|
|
347
|
-
}), this);
|
|
348
|
-
}
|
|
349
|
-
}
|
|
350
|
-
|
|
351
|
-
class RangeField extends Component {
|
|
352
|
-
Field = this.args.Field;
|
|
353
|
-
setNumberValue = setValue => {
|
|
354
|
-
return value => setValue(value);
|
|
355
|
-
};
|
|
356
|
-
static {
|
|
357
|
-
setComponentTemplate(precompileTemplate("\n <this.Field @name={{@name}} @label={{@label}} @description={{@description}} @validate={{@validate}} as |f|>\n <RangeInput @value={{asNumber f.value}} @update={{this.setNumberValue f.setValue}} @disabled={{@disabled}} @orientation={{@orientation}} @min={{@min}} @max={{@max}} @step={{@step}} name={{@name}} id={{f.id}} {{f.manageValidation}} {{f.captureEvents}} ...attributes />\n </this.Field>\n ", {
|
|
358
|
-
strictMode: true,
|
|
359
|
-
scope: () => ({
|
|
360
|
-
RangeInput,
|
|
361
|
-
asNumber
|
|
362
|
-
})
|
|
363
|
-
}), this);
|
|
364
|
-
}
|
|
365
|
-
}
|
|
366
|
-
|
|
367
|
-
class SelectField extends Component {
|
|
368
|
-
Field = this.args.Field;
|
|
369
|
-
setValue = setValue => {
|
|
370
|
-
return value => setValue(value);
|
|
371
|
-
};
|
|
372
|
-
static {
|
|
373
|
-
setComponentTemplate(precompileTemplate("\n <this.Field @name={{@name}} @label={{@label}} @description={{@description}} @validate={{@validate}} as |f|>\n <Select @value={{asString f.value}} @update={{this.setValue f.setValue}} @disabled={{@disabled}} name={{@name}} id={{f.id}} {{f.manageValidation}} {{f.captureEvents}} ...attributes as |s|>\n {{yield s}}\n </Select>\n </this.Field>\n ", {
|
|
374
|
-
strictMode: true,
|
|
375
|
-
scope: () => ({
|
|
376
|
-
Select,
|
|
377
|
-
asString
|
|
378
|
-
})
|
|
379
|
-
}), this);
|
|
380
|
-
}
|
|
381
|
-
}
|
|
382
|
-
|
|
383
|
-
class Option extends Component {
|
|
384
|
-
select = () => {
|
|
385
|
-
this.args.field.setValue(this.args.value);
|
|
386
|
-
};
|
|
387
|
-
static {
|
|
388
|
-
setComponentTemplate(precompileTemplate("\n {{#let (uniqueId) as |id|}}\n <div class={{styles.choice}} data-test-option>\n <span>\n <Radio @value={{eq @field.value @value}} @update={{this.select}} @disabled={{@disabled}} id={{id}} name={{@name}} value={{@value}} {{@field.manageValidation}} {{@field.captureEvents}} ...attributes />\n </span>\n\n <div>\n <Label for={{id}}>{{@label}}</Label>\n\n {{#if @description}}\n <Description>{{@description}}</Description>\n {{/if}}\n\n {{yield}}\n </div>\n </div>\n {{/let}}\n ", {
|
|
389
|
-
strictMode: true,
|
|
390
|
-
scope: () => ({
|
|
391
|
-
uniqueId,
|
|
392
|
-
styles,
|
|
393
|
-
Radio,
|
|
394
|
-
eq,
|
|
395
|
-
Label,
|
|
396
|
-
Description
|
|
397
|
-
})
|
|
398
|
-
}), this);
|
|
399
|
-
}
|
|
400
|
-
}
|
|
401
|
-
class SingularChoiceField extends Component {
|
|
402
|
-
Field = this.args.Field;
|
|
403
|
-
Option = Option;
|
|
404
|
-
static {
|
|
405
|
-
setComponentTemplate(precompileTemplate("\n <this.Field @element={{element \"fieldset\"}} @labelComponent={{component Label element=(element \"legend\")}} @name={{@name}} @label={{@label}} @description={{@description}} @validate={{@validate}} as |f|>\n <div class={{styles.choices}} data-test-choices>\n {{yield (hash Option=(component this.Option field=f name=@name disabled=@disabled))}}\n </div>\n </this.Field>\n ", {
|
|
406
|
-
strictMode: true,
|
|
407
|
-
scope: () => ({
|
|
408
|
-
element,
|
|
409
|
-
Label,
|
|
410
|
-
styles,
|
|
411
|
-
hash
|
|
412
|
-
})
|
|
413
|
-
}), this);
|
|
414
|
-
}
|
|
415
|
-
}
|
|
416
|
-
|
|
417
|
-
let TextField$1 = class TextField extends Component {
|
|
418
|
-
Field = this.args.Field;
|
|
419
|
-
setStringValue = setValue => {
|
|
420
|
-
return value => setValue(value);
|
|
421
|
-
};
|
|
422
|
-
static {
|
|
423
|
-
setComponentTemplate(precompileTemplate("\n <this.Field @name={{@name}} @label={{@label}} @description={{@description}} @validate={{@validate}} as |f|>\n <TextInput @value={{asString f.value}} @update={{this.setStringValue f.setValue}} @disabled={{@disabled}} name={{@name}} id={{f.id}} {{f.manageValidation}} {{f.captureEvents}} ...attributes />\n </this.Field>\n ", {
|
|
424
|
-
strictMode: true,
|
|
425
|
-
scope: () => ({
|
|
426
|
-
TextInput,
|
|
427
|
-
asString
|
|
428
|
-
})
|
|
429
|
-
}), this);
|
|
430
|
-
}
|
|
431
|
-
};
|
|
432
|
-
|
|
433
|
-
class TextField extends Component {
|
|
434
|
-
Field = this.args.Field;
|
|
435
|
-
setStringValue = setValue => {
|
|
436
|
-
return value => setValue(value);
|
|
437
|
-
};
|
|
438
|
-
static {
|
|
439
|
-
setComponentTemplate(precompileTemplate("\n <this.Field @name={{@name}} @label={{@label}} @description={{@description}} @validate={{@validate}} as |f|>\n <TextArea @value={{asString f.value}} @update={{this.setStringValue f.setValue}} @disabled={{@disabled}} name={{@name}} id={{f.id}} {{f.manageValidation}} {{f.captureEvents}} ...attributes />\n </this.Field>\n ", {
|
|
440
|
-
strictMode: true,
|
|
441
|
-
scope: () => ({
|
|
442
|
-
TextArea,
|
|
443
|
-
asString
|
|
444
|
-
})
|
|
445
|
-
}), this);
|
|
446
|
-
}
|
|
447
|
-
}
|
|
448
|
-
|
|
449
|
-
const Reset = setComponentTemplate(precompileTemplate("\n <button type=\"reset\" class={{styles.button}} data-intent={{if @intent @intent \"action\"}} data-importance={{if @importance @importance \"supreme\"}} data-spacing={{@spacing}} {{disabled when=(if @disabled @disabled false)}} data-test-button ...attributes>\n {{#if (has-block \"before\")}}\n <span data-test-button=\"before\">\n {{yield to=\"before\"}}\n </span>\n {{/if}}\n\n <span data-test-button=\"label\">\n {{#if (has-block \"label\")}}\n {{yield to=\"label\"}}\n {{/if}}\n\n {{#if (has-block)}}\n {{yield}}\n {{/if}}\n </span>\n\n {{#if (has-block \"after\")}}\n <span data-test-button=\"after\">\n {{yield to=\"after\"}}\n </span>\n {{/if}}\n </button>\n", {
|
|
450
|
-
strictMode: true,
|
|
451
|
-
scope: () => ({
|
|
452
|
-
styles: styles$1,
|
|
453
|
-
disabled
|
|
454
|
-
})
|
|
455
|
-
}), templateOnly());
|
|
456
|
-
|
|
457
|
-
const Submit = setComponentTemplate(precompileTemplate("\n <button type=\"submit\" class={{styles.button}} data-intent={{if @intent @intent \"action\"}} data-importance={{if @importance @importance \"supreme\"}} data-spacing={{@spacing}} {{disabled when=(if @disabled @disabled false)}} data-test-button ...attributes>\n {{#if (has-block \"before\")}}\n <span data-test-button=\"before\">\n {{yield to=\"before\"}}\n </span>\n {{/if}}\n\n <span data-test-button=\"label\">\n {{#if (has-block \"label\")}}\n {{yield to=\"label\"}}\n {{/if}}\n\n {{#if (has-block)}}\n {{yield}}\n {{/if}}\n </span>\n\n {{#if (has-block \"after\")}}\n <span data-test-button=\"after\">\n {{yield to=\"after\"}}\n </span>\n {{/if}}\n </button>\n", {
|
|
458
|
-
strictMode: true,
|
|
459
|
-
scope: () => ({
|
|
460
|
-
styles: styles$1,
|
|
461
|
-
disabled
|
|
462
|
-
})
|
|
463
|
-
}), templateOnly());
|
|
464
|
-
|
|
465
|
-
/**
|
|
466
|
-
* What the user can pass as @data
|
|
467
|
-
*/
|
|
468
|
-
|
|
469
|
-
/**
|
|
470
|
-
* The subset of properties of DATA, whose keys are strings (and not number or symbol)
|
|
471
|
-
* Only this data is useable in the form
|
|
472
|
-
*/
|
|
473
|
-
|
|
474
|
-
/**
|
|
475
|
-
* Returns the type of all keys of DATA, that are also strings. Only strings can be used as field @name
|
|
476
|
-
*/
|
|
477
|
-
|
|
478
|
-
/**
|
|
479
|
-
* Generic interface for all validation errors
|
|
480
|
-
*/
|
|
481
|
-
|
|
482
|
-
/**
|
|
483
|
-
* Callback used for form level validation
|
|
484
|
-
*/
|
|
485
|
-
|
|
486
|
-
/**
|
|
487
|
-
* Callback used for field level validation
|
|
488
|
-
*/
|
|
489
|
-
|
|
490
|
-
/**
|
|
491
|
-
* Internal structure to track used fields
|
|
492
|
-
* @private
|
|
493
|
-
*/
|
|
494
|
-
|
|
495
|
-
/**
|
|
496
|
-
* For internal field registration
|
|
497
|
-
* @private
|
|
498
|
-
*/
|
|
499
|
-
|
|
500
|
-
/**
|
|
501
|
-
* Mapper type to construct subset of objects, whose keys are only strings (and not number or symbol)
|
|
502
|
-
*/
|
|
503
|
-
|
|
504
|
-
function mergeErrorRecord(...records) {
|
|
505
|
-
const errors = {};
|
|
506
|
-
for (const record of records) {
|
|
507
|
-
if (!record) {
|
|
508
|
-
continue;
|
|
509
|
-
}
|
|
510
|
-
for (const [name, fieldErrors] of Object.entries(record)) {
|
|
511
|
-
const existingFieldErrors = errors[name];
|
|
512
|
-
errors[name] = existingFieldErrors ? [...existingFieldErrors, ...fieldErrors] : fieldErrors;
|
|
513
|
-
}
|
|
514
|
-
}
|
|
515
|
-
return errors;
|
|
516
|
-
}
|
|
517
|
-
|
|
518
|
-
/**
|
|
519
|
-
* This internal data structure maintains information about each field that is registered to the form by `registerField`.
|
|
520
|
-
*/
|
|
521
|
-
class FieldData {
|
|
522
|
-
constructor(fieldRegistration) {
|
|
523
|
-
this.validate = fieldRegistration.validate;
|
|
524
|
-
}
|
|
525
|
-
/**
|
|
526
|
-
* 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.
|
|
527
|
-
*/
|
|
528
|
-
static {
|
|
529
|
-
g(this.prototype, "validationEnabled", [tracked], function () {
|
|
530
|
-
return false;
|
|
531
|
-
});
|
|
532
|
-
}
|
|
533
|
-
#validationEnabled = (i(this, "validationEnabled"), void 0);
|
|
534
|
-
/**
|
|
535
|
-
* The *field* level validation callback passed to the field as in `<form.field @name="foo" @validate={{this.validateCallback}}>`
|
|
536
|
-
*/
|
|
537
|
-
validate;
|
|
538
|
-
}
|
|
539
|
-
class Form extends Component {
|
|
540
|
-
Field = Field;
|
|
541
|
-
CheckboxField = RadioField;
|
|
542
|
-
CurrencyField = CurrencyField;
|
|
543
|
-
DateField = DateField;
|
|
544
|
-
EmailField = EmailField;
|
|
545
|
-
ListField = ListField;
|
|
546
|
-
MultipleChoiceField = MultipleChoiceField;
|
|
547
|
-
NumberField = NumberField;
|
|
548
|
-
RangeField = RangeField;
|
|
549
|
-
PasswordField = PasswordField;
|
|
550
|
-
PhoneField = PhoneField;
|
|
551
|
-
SelectField = SelectField;
|
|
552
|
-
SingularChoiceField = SingularChoiceField;
|
|
553
|
-
TextField = TextField$1;
|
|
554
|
-
TextAreaField = TextField;
|
|
555
|
-
formElement;
|
|
556
|
-
registerForm = modifier((el, _p) => {
|
|
557
|
-
this.formElement = el;
|
|
558
|
-
});
|
|
559
|
-
submit = async e => {
|
|
560
|
-
e?.preventDefault();
|
|
561
|
-
await this.validateWithState();
|
|
562
|
-
this.showAllValidations = true;
|
|
563
|
-
if (this.validationErrorsExist) {
|
|
564
|
-
assert('Validation errors expected to be present. If you see this, please report it as a bug to ember-headless-form!',
|
|
565
|
-
// with optional chaining this leads to a NPE
|
|
566
|
-
// eslint-disable-next-line @typescript-eslint/prefer-optional-chain
|
|
567
|
-
this.validationState && this.validationState.isResolved);
|
|
568
|
-
this.args.invalidated?.(this.effectiveData, this.validationState.value);
|
|
569
|
-
} else {
|
|
570
|
-
if (this.args.submit) {
|
|
571
|
-
this.submissionState = new TrackedAsyncData(this.args.submit(this.effectiveData));
|
|
572
|
-
}
|
|
573
|
-
}
|
|
574
|
-
};
|
|
575
|
-
reset = e => {
|
|
576
|
-
e?.preventDefault();
|
|
577
|
-
for (const key of Object.keys(this.internalData)) {
|
|
578
|
-
// eslint-disable-next-line @typescript-eslint/no-dynamic-delete
|
|
579
|
-
delete this.internalData[key];
|
|
580
|
-
}
|
|
581
|
-
this.validationState = undefined;
|
|
582
|
-
this.submissionState = undefined;
|
|
583
|
-
};
|
|
584
|
-
/**
|
|
585
|
-
* A copy of the passed `@data` stored internally, which is only passed back to the component consumer after a (successful) form submission.
|
|
586
|
-
*/
|
|
587
|
-
internalData = new TrackedObject({});
|
|
588
|
-
get effectiveData() {
|
|
589
|
-
const obj = this.args.data ?? {};
|
|
590
|
-
if (this.args.dataMode === 'mutable') {
|
|
591
|
-
return obj;
|
|
592
|
-
}
|
|
593
|
-
const {
|
|
594
|
-
internalData
|
|
595
|
-
} = this;
|
|
596
|
-
return new Proxy(obj, {
|
|
597
|
-
get(target, prop) {
|
|
598
|
-
return prop in internalData ? internalData[prop] : Reflect.get(target, prop);
|
|
599
|
-
},
|
|
600
|
-
set(_target, property, value) {
|
|
601
|
-
return Reflect.set(internalData, property, value);
|
|
602
|
-
},
|
|
603
|
-
has(target, prop) {
|
|
604
|
-
return prop in internalData ? true : Reflect.has(target, prop);
|
|
605
|
-
},
|
|
606
|
-
getOwnPropertyDescriptor(target, prop) {
|
|
607
|
-
return Reflect.getOwnPropertyDescriptor(prop in internalData ? internalData : target, prop);
|
|
608
|
-
},
|
|
609
|
-
ownKeys(target) {
|
|
610
|
-
return [...Reflect.ownKeys(target), ...Reflect.ownKeys(internalData)] // return only unique values
|
|
611
|
-
.filter((value, index, array) => array.indexOf(value) === index);
|
|
612
|
-
},
|
|
613
|
-
deleteProperty(_target, prop) {
|
|
614
|
-
if (prop in internalData) {
|
|
615
|
-
// eslint-disable-next-line @typescript-eslint/no-dynamic-delete
|
|
616
|
-
delete internalData[prop];
|
|
617
|
-
}
|
|
618
|
-
return true;
|
|
619
|
-
}
|
|
620
|
-
});
|
|
621
|
-
}
|
|
622
|
-
static {
|
|
623
|
-
n(this.prototype, "effectiveData", [cached]);
|
|
624
|
-
}
|
|
625
|
-
fields = new Map();
|
|
626
|
-
registerField = (name, field) => {
|
|
627
|
-
assert(`You passed @name="${String(name)}" to the form field, but this is already in use. Names of form fields must be unique!`, !this.fields.has(name));
|
|
628
|
-
this.fields.set(name, new FieldData(field));
|
|
629
|
-
};
|
|
630
|
-
unregisterField = name => {
|
|
631
|
-
this.fields.delete(name);
|
|
632
|
-
};
|
|
633
|
-
set = (key, value) => {
|
|
634
|
-
// when @mutableData is set, our effectiveData is something we don't control, i.e. might require old-school set() to be on the safe side
|
|
635
|
-
set(this.effectiveData, key, value);
|
|
636
|
-
// console.log('internalData', this.internalData);
|
|
637
|
-
};
|
|
638
|
-
static {
|
|
639
|
-
g(this.prototype, "validationState", [tracked]);
|
|
640
|
-
}
|
|
641
|
-
#validationState = (i(this, "validationState"), void 0);
|
|
642
|
-
static {
|
|
643
|
-
g(this.prototype, "submissionState", [tracked]);
|
|
644
|
-
}
|
|
645
|
-
#submissionState = (i(this, "submissionState"), void 0);
|
|
646
|
-
static {
|
|
647
|
-
g(this.prototype, "showAllValidations", [tracked], function () {
|
|
648
|
-
return false;
|
|
649
|
-
});
|
|
650
|
-
}
|
|
651
|
-
#showAllValidations = (i(this, "showAllValidations"), void 0);
|
|
652
|
-
/**
|
|
653
|
-
* 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`
|
|
654
|
-
*/
|
|
655
|
-
get validateOn() {
|
|
656
|
-
return this.args.validateOn ?? 'submit';
|
|
657
|
-
}
|
|
658
|
-
get revalidateOn() {
|
|
659
|
-
return this.args.revalidateOn ?? 'change';
|
|
660
|
-
}
|
|
661
|
-
/**
|
|
662
|
-
* Return the event type that will be listened on for dynamic validation (i.e. *before* submitting)
|
|
663
|
-
*/
|
|
664
|
-
get fieldValidationEvent() {
|
|
665
|
-
const {
|
|
666
|
-
validateOn
|
|
667
|
-
} = this;
|
|
668
|
-
return validateOn === 'submit' ? undefined : validateOn;
|
|
669
|
-
}
|
|
670
|
-
/**
|
|
671
|
-
* 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
|
|
672
|
-
*/
|
|
673
|
-
get fieldRevalidationEvent() {
|
|
674
|
-
const {
|
|
675
|
-
validateOn,
|
|
676
|
-
revalidateOn
|
|
677
|
-
} = this;
|
|
678
|
-
return revalidateOn === 'submit' ? undefined : validateOn === 'input' || validateOn === 'change' && revalidateOn === 'focusout' || validateOn === revalidateOn ? undefined : revalidateOn;
|
|
679
|
-
}
|
|
680
|
-
/**
|
|
681
|
-
* Return true if validation has happened (by submitting or by an `@validateOn` event being triggered) and at least one field is invalid
|
|
682
|
-
*/
|
|
683
|
-
get validationErrorsExist() {
|
|
684
|
-
const {
|
|
685
|
-
validationState
|
|
686
|
-
} = this;
|
|
687
|
-
// Only consider validation errors for which we actually have a field rendered
|
|
688
|
-
return validationState?.isResolved ? Object.keys(validationState.value).some(name => this.fields.has(name)) : false;
|
|
689
|
-
}
|
|
690
|
-
/**
|
|
691
|
-
* 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.
|
|
692
|
-
*/
|
|
693
|
-
async validate() {
|
|
694
|
-
const nativeValidation = this.args.ignoreNativeValidation === true ? {} : this.validateNative();
|
|
695
|
-
const customFormValidation = await this.args.validate?.(this.effectiveData, [...this.fields.keys()]);
|
|
696
|
-
const customFieldValidations = [];
|
|
697
|
-
for (const [name, field] of this.fields) {
|
|
698
|
-
const fieldValidationResult = await field.validate?.(this.effectiveData[name], name, this.effectiveData);
|
|
699
|
-
if (fieldValidationResult) {
|
|
700
|
-
customFieldValidations.push({
|
|
701
|
-
[name]: fieldValidationResult
|
|
702
|
-
});
|
|
703
|
-
}
|
|
704
|
-
}
|
|
705
|
-
return mergeErrorRecord(nativeValidation, customFormValidation, ...customFieldValidations);
|
|
706
|
-
}
|
|
707
|
-
validateWithState = async () => {
|
|
708
|
-
const promise = this.validate();
|
|
709
|
-
this.validationState = new TrackedAsyncData(promise);
|
|
710
|
-
return promise;
|
|
711
|
-
};
|
|
712
|
-
validateNative() {
|
|
713
|
-
const form = this.formElement;
|
|
714
|
-
assert('Form element expected to be present. If you see this, please report it as a bug to ember-headless-form!', form);
|
|
715
|
-
if (form.checkValidity()) {
|
|
716
|
-
return;
|
|
717
|
-
}
|
|
718
|
-
const errors = {};
|
|
719
|
-
for (const el of form.elements) {
|
|
720
|
-
// 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.
|
|
721
|
-
assert('Unexpected form element. If you see this, please report it as a bug to ember-headless-form!', el instanceof HTMLInputElement || el instanceof HTMLTextAreaElement || el instanceof HTMLSelectElement || el instanceof HTMLButtonElement || el instanceof HTMLFieldSetElement || el instanceof HTMLObjectElement || el instanceof HTMLOutputElement);
|
|
722
|
-
if (el.validity.valid) {
|
|
723
|
-
continue;
|
|
724
|
-
}
|
|
725
|
-
const name = el.name;
|
|
726
|
-
if (this.fields.has(name)) {
|
|
727
|
-
errors[name] = [{
|
|
728
|
-
type: 'native',
|
|
729
|
-
value: this.effectiveData[name],
|
|
730
|
-
message: el.validationMessage
|
|
731
|
-
}];
|
|
732
|
-
} else {
|
|
733
|
-
warn(`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!`, {
|
|
734
|
-
id: 'headless-form.invalid-control-for-unknown-field'
|
|
735
|
-
});
|
|
736
|
-
}
|
|
737
|
-
}
|
|
738
|
-
return errors;
|
|
739
|
-
}
|
|
740
|
-
/**
|
|
741
|
-
* Return a mapping of field to validation errors, for all fields that are invalid *and* for which validation errors should be visible.
|
|
742
|
-
* 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,
|
|
743
|
-
* or when that field has triggered the event given by `@validateOn` for showing validation errors before submitting, e.g. on blur.
|
|
744
|
-
*/
|
|
745
|
-
get visibleErrors() {
|
|
746
|
-
if (!this.validationState?.isResolved) {
|
|
747
|
-
return undefined;
|
|
748
|
-
}
|
|
749
|
-
const visibleErrors = {};
|
|
750
|
-
for (const [field, errors] of Object.entries(this.validationState.value)) {
|
|
751
|
-
if (this.showErrorsFor(field)) {
|
|
752
|
-
visibleErrors[field] = errors;
|
|
753
|
-
}
|
|
754
|
-
}
|
|
755
|
-
return visibleErrors;
|
|
756
|
-
}
|
|
757
|
-
/**
|
|
758
|
-
* Given a field name, return if eventual errors for the field should be visible. See `visibleErrors` for further details.
|
|
759
|
-
*/
|
|
760
|
-
showErrorsFor = field => {
|
|
761
|
-
return this.showAllValidations || (this.fields.get(field)?.validationEnabled ?? false);
|
|
762
|
-
};
|
|
763
|
-
/**
|
|
764
|
-
* Handle the `@validateOn` event for a certain field, e.g. "blur".
|
|
765
|
-
* 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.
|
|
766
|
-
* Validation will be triggered, and the particular field will be marked to show eventual validation errors.
|
|
767
|
-
*/
|
|
768
|
-
handleFieldValidation = async e => {
|
|
769
|
-
let name;
|
|
770
|
-
if (typeof e === 'string') {
|
|
771
|
-
name = e;
|
|
772
|
-
} else {
|
|
773
|
-
const {
|
|
774
|
-
target
|
|
775
|
-
} = e;
|
|
776
|
-
name = target.name;
|
|
777
|
-
}
|
|
778
|
-
if (name) {
|
|
779
|
-
const field = this.fields.get(name);
|
|
780
|
-
if (field) {
|
|
781
|
-
await this.validateWithState();
|
|
782
|
-
field.validationEnabled = true;
|
|
783
|
-
}
|
|
784
|
-
} else if (e instanceof Event) {
|
|
785
|
-
warn(`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.`, {
|
|
786
|
-
id: 'headless-form.validation-event-for-unknown-field'
|
|
787
|
-
});
|
|
788
|
-
}
|
|
789
|
-
};
|
|
790
|
-
/**
|
|
791
|
-
* Handle the `@revalidateOn` event for a certain field, e.g. "blur".
|
|
792
|
-
* 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.
|
|
793
|
-
* When a field has been already marked to show validation errors by `@validateOn`, then for revalidation another validation will be triggered.
|
|
794
|
-
*
|
|
795
|
-
* The use case here is to allow this to happen more frequently than the initial validation, e.g. `@validateOn="blur" @revalidateOn="change"`.
|
|
796
|
-
*/
|
|
797
|
-
handleFieldRevalidation = async e => {
|
|
798
|
-
const {
|
|
799
|
-
target
|
|
800
|
-
} = e;
|
|
801
|
-
const {
|
|
802
|
-
name
|
|
803
|
-
} = target;
|
|
804
|
-
if (name) {
|
|
805
|
-
if (this.showErrorsFor(name)) {
|
|
806
|
-
await this.validateWithState();
|
|
807
|
-
}
|
|
808
|
-
} else {
|
|
809
|
-
warn(`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.`, {
|
|
810
|
-
id: 'headless-form.validation-event-for-unknown-field'
|
|
811
|
-
});
|
|
812
|
-
}
|
|
813
|
-
};
|
|
814
|
-
attachValidation = modifier((el, [eventName, handler]) => {
|
|
815
|
-
if (eventName) {
|
|
816
|
-
el.addEventListener(eventName, handler);
|
|
817
|
-
return () => el.removeEventListener(eventName, handler);
|
|
818
|
-
}
|
|
819
|
-
return;
|
|
820
|
-
});
|
|
821
|
-
static {
|
|
822
|
-
setComponentTemplate(precompileTemplate("\n <form novalidate class={{styles.form}} data-test-form ...attributes {{this.registerForm}} {{on \"submit\" this.submit}} {{on \"reset\" this.reset}} {{this.attachValidation this.fieldValidationEvent this.handleFieldValidation}} {{this.attachValidation this.fieldRevalidationEvent this.handleFieldRevalidation}}>\n {{#let (component this.Field data=this.effectiveData set=this.set errors=this.visibleErrors showErrorsFor=this.showErrorsFor registerField=this.registerField unregisterField=this.unregisterField triggerValidationFor=this.handleFieldValidation fieldValidationEvent=this.fieldValidationEvent fieldRevalidationEvent=this.fieldRevalidationEvent) as |WiredField|}}\n {{yield (hash Submit=Submit Reset=Reset Field=WiredField Checkbox=(component this.CheckboxField Field=WiredField) Currency=(component this.CurrencyField Field=WiredField) Date=(component this.DateField Field=WiredField) Email=(component this.EmailField Field=WiredField) List=(component this.ListField Field=WiredField) MultipleChoice=(component this.MultipleChoiceField Field=WiredField) Number=(component this.NumberField Field=WiredField) Range=(component this.RangeField Field=WiredField) Password=(component this.PasswordField Field=WiredField) Phone=(component this.PhoneField Field=WiredField) Select=(component this.SelectField Field=WiredField) SingularChoice=(component this.SingularChoiceField Field=WiredField) Text=(component this.TextField Field=WiredField) TextArea=(component this.TextAreaField Field=WiredField) validationState=this.validationState submissionState=this.submissionState invalid=this.validationErrorsExist rawErrors=this.visibleErrors submit=this.submit reset=this.reset)}}\n {{/let}}\n </form>\n ", {
|
|
823
|
-
strictMode: true,
|
|
824
|
-
scope: () => ({
|
|
825
|
-
styles,
|
|
826
|
-
on,
|
|
827
|
-
hash,
|
|
828
|
-
Submit,
|
|
829
|
-
Reset
|
|
830
|
-
})
|
|
831
|
-
}), this);
|
|
832
|
-
}
|
|
833
|
-
}
|
|
834
|
-
|
|
835
|
-
export { Form as default };
|
|
1
|
+
export { F as default } from '../form-DBuzL4_0.js';
|
|
836
2
|
//# sourceMappingURL=form.js.map
|