ember-headless-form 1.0.0-beta.2 → 1.0.0-beta.3

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.
@@ -5,7 +5,7 @@ import '@babel/runtime/helpers/esm/initializerWarningHelper';
5
5
  import { setComponentTemplate } from '@ember/component';
6
6
  import { precompileTemplate } from '@ember/template-compilation';
7
7
  import Component from '@glimmer/component';
8
- import { tracked } from '@glimmer/tracking';
8
+ import { tracked, cached } from '@glimmer/tracking';
9
9
  import { assert, warn } from '@ember/debug';
10
10
  import { hash } from '@ember/helper';
11
11
  import { on } from '@ember/modifier';
@@ -74,22 +74,18 @@ let HeadlessFormComponent = setComponentTemplate(precompileTemplate(`
74
74
  ...attributes
75
75
  {{this.registerForm}}
76
76
  {{on "submit" this.onSubmit}}
77
- {{(if
78
- this.fieldValidationEvent
79
- (modifier this.on this.fieldValidationEvent this.handleFieldValidation)
80
- )}}
81
- {{(if
77
+ {{on "reset" this.onReset}}
78
+ {{this.onValidation this.fieldValidationEvent this.handleFieldValidation}}
79
+ {{this.onValidation
82
80
  this.fieldRevalidationEvent
83
- (modifier
84
- this.on this.fieldRevalidationEvent this.handleFieldRevalidation
85
- )
86
- )}}
81
+ this.handleFieldRevalidation
82
+ }}
87
83
  >
88
84
  {{yield
89
85
  (hash
90
86
  Field=(component
91
87
  this.FieldComponent
92
- data=this.internalData
88
+ data=this.effectiveData
93
89
  set=this.set
94
90
  errors=this.visibleErrors
95
91
  registerField=this.registerField
@@ -102,6 +98,8 @@ let HeadlessFormComponent = setComponentTemplate(precompileTemplate(`
102
98
  submissionState=this.submissionState
103
99
  isInvalid=this.hasValidationErrors
104
100
  rawErrors=this.visibleErrors
101
+ submit=this.onSubmit
102
+ reset=this.onReset
105
103
  )
106
104
  }}
107
105
  </form>
@@ -115,16 +113,55 @@ let HeadlessFormComponent = setComponentTemplate(precompileTemplate(`
115
113
  constructor(...args) {
116
114
  super(...args);
117
115
  _defineProperty(this, "FieldComponent", HeadlessFormFieldComponent);
118
- _defineProperty(this, "on", on);
119
116
  _defineProperty(this, "formElement", void 0);
120
117
  _defineProperty(this, "registerForm", modifier((el, _p) => {
121
118
  this.formElement = el;
122
119
  }));
123
- _defineProperty(this, "internalData", this.args.dataMode == 'mutable' && this.args.data ? this.args.data : new TrackedObject(this.args.data ?? {}));
120
+ _defineProperty(this, "internalData", new TrackedObject({}));
124
121
  _defineProperty(this, "fields", new Map());
125
122
  _initializerDefineProperty(this, "validationState", _descriptor2, this);
126
123
  _initializerDefineProperty(this, "submissionState", _descriptor3, this);
127
124
  _initializerDefineProperty(this, "showAllValidations", _descriptor4, this);
125
+ _defineProperty(this, "onValidation", modifier((el, [eventName, handler]) => {
126
+ if (eventName) {
127
+ el.addEventListener(eventName, handler);
128
+ return () => el.removeEventListener(eventName, handler);
129
+ }
130
+ }));
131
+ }
132
+ get effectiveData() {
133
+ const obj = this.args.data ?? {};
134
+ if (this.args.dataMode === 'mutable') {
135
+ return obj;
136
+ }
137
+ const {
138
+ internalData
139
+ } = this;
140
+ return new Proxy(obj, {
141
+ get(target, prop) {
142
+ return prop in internalData ? internalData[prop] : Reflect.get(target, prop);
143
+ },
144
+ set(target, property, value) {
145
+ return Reflect.set(internalData, property, value);
146
+ },
147
+ has(target, prop) {
148
+ return prop in internalData ? true : Reflect.has(target, prop);
149
+ },
150
+ getOwnPropertyDescriptor(target, prop) {
151
+ return Reflect.getOwnPropertyDescriptor(prop in internalData ? internalData : target, prop);
152
+ },
153
+ ownKeys(target) {
154
+ return [...Reflect.ownKeys(target), ...Reflect.ownKeys(internalData)]
155
+ // return only unique values
156
+ .filter((value, index, array) => array.indexOf(value) === index);
157
+ },
158
+ deleteProperty(target, prop) {
159
+ if (prop in internalData) {
160
+ delete internalData[prop];
161
+ }
162
+ return true;
163
+ }
164
+ });
128
165
  }
129
166
  get validateOn() {
130
167
  return this.args.validateOn ?? 'submit';
@@ -177,10 +214,10 @@ let HeadlessFormComponent = setComponentTemplate(precompileTemplate(`
177
214
  */
178
215
  async validate() {
179
216
  const nativeValidation = this.args.ignoreNativeValidation !== true ? this.validateNative() : {};
180
- const customFormValidation = await this.args.validate?.(this.internalData, Array.from(this.fields.keys()));
217
+ const customFormValidation = await this.args.validate?.(this.effectiveData, Array.from(this.fields.keys()));
181
218
  const customFieldValidations = [];
182
219
  for (const [name, field] of this.fields) {
183
- const fieldValidationResult = await field.validate?.(this.internalData[name], name, this.internalData);
220
+ const fieldValidationResult = await field.validate?.(this.effectiveData[name], name, this.effectiveData);
184
221
  if (fieldValidationResult) {
185
222
  customFieldValidations.push({
186
223
  [name]: fieldValidationResult
@@ -211,7 +248,7 @@ let HeadlessFormComponent = setComponentTemplate(precompileTemplate(`
211
248
  if (this.fields.has(name)) {
212
249
  errors[name] = [{
213
250
  type: 'native',
214
- value: this.internalData[name],
251
+ value: this.effectiveData[name],
215
252
  message: el.validationMessage
216
253
  }];
217
254
  } else {
@@ -248,17 +285,25 @@ let HeadlessFormComponent = setComponentTemplate(precompileTemplate(`
248
285
  return this.showAllValidations || (this.fields.get(field)?.validationEnabled ?? false);
249
286
  }
250
287
  async onSubmit(e) {
251
- e.preventDefault();
288
+ e?.preventDefault();
252
289
  await this._validate();
253
290
  this.showAllValidations = true;
254
291
  if (!this.hasValidationErrors) {
255
292
  if (this.args.onSubmit) {
256
- this.submissionState = new TrackedAsyncData(this.args.onSubmit(this.internalData), this);
293
+ this.submissionState = new TrackedAsyncData(this.args.onSubmit(this.effectiveData), this);
257
294
  }
258
295
  } else {
259
296
  assert('Validation errors expected to be present. If you see this, please report it as a bug to ember-headless-form!', this.validationState?.isResolved);
260
- this.args.onInvalid?.(this.internalData, this.validationState.value);
297
+ this.args.onInvalid?.(this.effectiveData, this.validationState.value);
298
+ }
299
+ }
300
+ async onReset(e) {
301
+ e?.preventDefault();
302
+ for (const key of Object.keys(this.internalData)) {
303
+ delete this.internalData[key];
261
304
  }
305
+ this.validationState = undefined;
306
+ this.submissionState = undefined;
262
307
  }
263
308
  registerField(name, field) {
264
309
  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));
@@ -268,8 +313,8 @@ let HeadlessFormComponent = setComponentTemplate(precompileTemplate(`
268
313
  this.fields.delete(name);
269
314
  }
270
315
  set(key, value) {
271
- // when @mutableData is set, our internalData is something we don't control, i.e. might require old-school set() to be on the safe side
272
- set(this.internalData, key, value);
316
+ // 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
317
+ set(this.effectiveData, key, value);
273
318
  }
274
319
 
275
320
  /**
@@ -324,7 +369,7 @@ let HeadlessFormComponent = setComponentTemplate(precompileTemplate(`
324
369
  });
325
370
  }
326
371
  }
327
- }, (_descriptor2 = _applyDecoratedDescriptor(_class3.prototype, "validationState", [tracked], {
372
+ }, (_applyDecoratedDescriptor(_class3.prototype, "effectiveData", [cached], Object.getOwnPropertyDescriptor(_class3.prototype, "effectiveData"), _class3.prototype), _descriptor2 = _applyDecoratedDescriptor(_class3.prototype, "validationState", [tracked], {
328
373
  configurable: true,
329
374
  enumerable: true,
330
375
  writable: true,
@@ -341,8 +386,7 @@ let HeadlessFormComponent = setComponentTemplate(precompileTemplate(`
341
386
  initializer: function () {
342
387
  return false;
343
388
  }
344
- }), _applyDecoratedDescriptor(_class3.prototype, "onSubmit", [action], Object.getOwnPropertyDescriptor(_class3.prototype, "onSubmit"), _class3.prototype), _applyDecoratedDescriptor(_class3.prototype, "registerField", [action], Object.getOwnPropertyDescriptor(_class3.prototype, "registerField"), _class3.prototype), _applyDecoratedDescriptor(_class3.prototype, "unregisterField", [action], Object.getOwnPropertyDescriptor(_class3.prototype, "unregisterField"), _class3.prototype), _applyDecoratedDescriptor(_class3.prototype, "set", [action], Object.getOwnPropertyDescriptor(_class3.prototype, "set"), _class3.prototype), _applyDecoratedDescriptor(_class3.prototype, "handleFieldValidation", [action], Object.getOwnPropertyDescriptor(_class3.prototype, "handleFieldValidation"), _class3.prototype), _applyDecoratedDescriptor(_class3.prototype, "handleFieldRevalidation", [action], Object.getOwnPropertyDescriptor(_class3.prototype, "handleFieldRevalidation"), _class3.prototype)), _class3));
345
- // eslint-disable-next-line @typescript-eslint/no-unused-vars -- workaround for unknown modifier helper: https://github.com/typed-ember/glint/issues/410
389
+ }), _applyDecoratedDescriptor(_class3.prototype, "onSubmit", [action], Object.getOwnPropertyDescriptor(_class3.prototype, "onSubmit"), _class3.prototype), _applyDecoratedDescriptor(_class3.prototype, "onReset", [action], Object.getOwnPropertyDescriptor(_class3.prototype, "onReset"), _class3.prototype), _applyDecoratedDescriptor(_class3.prototype, "registerField", [action], Object.getOwnPropertyDescriptor(_class3.prototype, "registerField"), _class3.prototype), _applyDecoratedDescriptor(_class3.prototype, "unregisterField", [action], Object.getOwnPropertyDescriptor(_class3.prototype, "unregisterField"), _class3.prototype), _applyDecoratedDescriptor(_class3.prototype, "set", [action], Object.getOwnPropertyDescriptor(_class3.prototype, "set"), _class3.prototype), _applyDecoratedDescriptor(_class3.prototype, "handleFieldValidation", [action], Object.getOwnPropertyDescriptor(_class3.prototype, "handleFieldValidation"), _class3.prototype), _applyDecoratedDescriptor(_class3.prototype, "handleFieldRevalidation", [action], Object.getOwnPropertyDescriptor(_class3.prototype, "handleFieldRevalidation"), _class3.prototype)), _class3));
346
390
 
347
391
  export { HeadlessFormComponent as default };
348
392
  //# sourceMappingURL=headless-form.js.map