@conform-to/dom 1.0.0-pre.5 → 1.0.0-pre.7

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 ADDED
@@ -0,0 +1,32 @@
1
+
2
+
3
+ ███████╗ ██████╗ ███╗ ██╗ ████████╗ ██████╗ ███████╗ ███╗ ███╗
4
+ ██╔═════╝ ██╔═══██╗ ████╗ ██║ ██╔═════╝ ██╔═══██╗ ██╔═══██╗ ████████║
5
+ ██║ ██║ ██║ ██╔██╗██║ ███████╗ ██║ ██║ ███████╔╝ ██╔██╔██║
6
+ ██║ ██║ ██║ ██║╚████║ ██╔════╝ ██║ ██║ ██╔═══██╗ ██║╚═╝██║
7
+ ╚███████╗ ╚██████╔╝ ██║ ╚███║ ██║ ╚██████╔╝ ██║ ██║ ██║ ██║
8
+ ╚══════╝ ╚═════╝ ╚═╝ ╚══╝ ╚═╝ ╚═════╝ ╚═╝ ╚═╝ ╚═╝ ╚═╝
9
+
10
+
11
+ Version 1.0.0-pre.7 / License MIT / Copyright (c) 2024 Edmund Hung
12
+
13
+ A type-safe form validation library utilizing web fundamentals to progressively enhance HTML Forms with full support for server frameworks like Remix route action and Next.js server actions.
14
+
15
+ > Getting Started
16
+
17
+ Check out the overview and tutorial at our website https://conform.guide
18
+
19
+ > Documentation
20
+
21
+ The documentation is divided into several sections:
22
+
23
+ * Overview: https://conform.guide/overview
24
+ * Example Usages: https://conform.guide/examples
25
+ * Complex structures: https://conform.guide/complex-structures
26
+ * UI Integrations: https://conform.guide/integrations
27
+ * Accessibility Guide: https://conform.guide/accessibility
28
+ * API Reference: https://conform.guide/references
29
+
30
+ > Support
31
+
32
+ To report a bug, please open an issue on the repository at https://github.com/edmundhung/conform. For feature requests and questions, you can post them in the Discussions section.
package/form.d.ts CHANGED
@@ -1,5 +1,5 @@
1
1
  import { getFormAction, getFormEncType, getFormMethod } from './dom';
2
- import { type FormControl, type Submission, type SubmissionResult } from './submission';
2
+ import { type Intent, type Submission, type SubmissionResult } from './submission';
3
3
  export type UnionKeyof<T> = T extends any ? keyof T : never;
4
4
  export type UnionKeyType<T, K extends UnionKeyof<T>> = T extends {
5
5
  [k in K]?: any;
@@ -10,14 +10,17 @@ export type DefaultValue<Schema> = Schema extends string | number | boolean | Da
10
10
  export type FormValue<Schema> = Schema extends string | number | boolean | Date | null | undefined ? string | undefined : Schema extends File ? File | undefined : Schema extends Array<infer Item> ? Array<FormValue<Item>> | undefined : Schema extends Record<string, any> ? {
11
11
  [Key in UnionKeyof<Schema>]?: FormValue<UnionKeyType<Schema, Key>>;
12
12
  } | undefined : unknown;
13
+ declare const error: unique symbol;
14
+ declare const field: unique symbol;
15
+ declare const form: unique symbol;
13
16
  export type FormId<Schema extends Record<string, unknown> = Record<string, unknown>, Error = string[]> = string & {
14
- __error?: Error;
15
- __schema?: Schema;
17
+ [error]?: Error;
18
+ [form]?: Schema;
16
19
  };
17
- export type FieldName<FieldSchema, Error = string[], FormSchema extends Record<string, unknown> = Record<string, unknown>> = string & {
18
- __field?: FieldSchema;
19
- __error?: Error;
20
- __form?: FormSchema;
20
+ export type FieldName<FieldSchema, FormSchema extends Record<string, unknown> = Record<string, unknown>, Error = string[]> = string & {
21
+ [field]?: FieldSchema;
22
+ [error]?: Error;
23
+ [form]?: FormSchema;
21
24
  };
22
25
  export type Constraint = {
23
26
  required?: boolean;
@@ -43,7 +46,7 @@ export type FormState<FormError> = FormMeta<FormError> & {
43
46
  valid: Record<string, boolean>;
44
47
  dirty: Record<string, boolean>;
45
48
  };
46
- export type FormOptions<Schema, FormError, Value = Schema> = {
49
+ export type FormOptions<Schema, FormError = string[], FormValue = Schema> = {
47
50
  /**
48
51
  * The id of the form.
49
52
  */
@@ -59,7 +62,7 @@ export type FormOptions<Schema, FormError, Value = Schema> = {
59
62
  /**
60
63
  * An object describing the result of the last submission
61
64
  */
62
- lastResult?: SubmissionResult<FormError>;
65
+ lastResult?: SubmissionResult<FormError> | null;
63
66
  /**
64
67
  * Define when conform should start validation.
65
68
  * Support "onSubmit", "onInput", "onBlur".
@@ -74,6 +77,11 @@ export type FormOptions<Schema, FormError, Value = Schema> = {
74
77
  * @default Same as shouldValidate, or "onSubmit" if shouldValidate is not provided.
75
78
  */
76
79
  shouldRevalidate?: 'onSubmit' | 'onBlur' | 'onInput';
80
+ /**
81
+ * Define if conform should considered the field for dirty state.
82
+ * e.g. Excluding form fields that are not managed by Conform, such as CSRF token
83
+ */
84
+ shouldDirtyConsider?: (name: string) => boolean;
77
85
  /**
78
86
  * A function to be called when the form should be (re)validated.
79
87
  */
@@ -81,7 +89,7 @@ export type FormOptions<Schema, FormError, Value = Schema> = {
81
89
  form: HTMLFormElement;
82
90
  submitter: HTMLInputElement | HTMLButtonElement | null;
83
91
  formData: FormData;
84
- }) => Submission<Schema, FormError, Value>;
92
+ }) => Submission<Schema, FormError, FormValue>;
85
93
  /**
86
94
  * A function to be called before the form is submitted.
87
95
  */
@@ -90,7 +98,7 @@ export type FormOptions<Schema, FormError, Value = Schema> = {
90
98
  action: ReturnType<typeof getFormAction>;
91
99
  encType: ReturnType<typeof getFormEncType>;
92
100
  method: ReturnType<typeof getFormMethod>;
93
- submission?: Submission<Schema, FormError, Value>;
101
+ submission?: Submission<Schema, FormError, FormValue>;
94
102
  }) => void;
95
103
  };
96
104
  export type SubscriptionSubject = {
@@ -108,18 +116,32 @@ export type ControlButtonProps = {
108
116
  form: string;
109
117
  formNoValidate: boolean;
110
118
  };
111
- export type FormContext<Schema extends Record<string, any> = any, FormError = string[], Value = Schema> = {
119
+ export type FormContext<Schema extends Record<string, any> = any, FormValue = Schema, FormError = string[]> = {
112
120
  formId: string;
113
- submit(event: SubmitEvent): void;
114
- reset(event: Event): void;
115
- input(event: Event): void;
116
- blur(event: Event): void;
117
- report(result: SubmissionResult<FormError>): void;
118
- update(options: Omit<FormOptions<Schema, FormError, Value>, 'lastResult'>): void;
121
+ submit(event: SubmitEvent): Submission<Schema, FormError, FormValue> | undefined;
122
+ onReset(event: Event): void;
123
+ onInput(event: Event): void;
124
+ onBlur(event: Event): void;
125
+ onUpdate(options: Partial<FormOptions<Schema, FormError, FormValue>>): void;
119
126
  subscribe(callback: () => void, getSubject?: () => SubscriptionSubject | undefined): () => void;
120
- dispatch(control: FormControl): void;
121
- getControlButtonProps(control: FormControl): ControlButtonProps;
122
127
  getState(): FormState<FormError>;
123
128
  getSerializedState(): string;
129
+ } & {
130
+ [Type in Intent['type']]: {} extends Extract<Intent, {
131
+ type: Type;
132
+ }>['payload'] ? (<FieldSchema = Schema>(payload?: Extract<Intent<FieldSchema>, {
133
+ type: Type;
134
+ }>['payload']) => void) & {
135
+ getButtonProps<FieldSchema = Schema>(payload?: Extract<Intent<FieldSchema>, {
136
+ type: Type;
137
+ }>['payload']): ControlButtonProps;
138
+ } : (<FieldSchema = Schema>(payload: Extract<Intent<FieldSchema>, {
139
+ type: Type;
140
+ }>['payload']) => void) & {
141
+ getButtonProps<FieldSchema = Schema>(payload: Extract<Intent<FieldSchema>, {
142
+ type: Type;
143
+ }>['payload']): ControlButtonProps;
144
+ };
124
145
  };
125
- export declare function createFormContext<Schema extends Record<string, any>, FormError, Value>(options: FormOptions<Schema, FormError, Value>): FormContext<Schema, FormError, Value>;
146
+ export declare function createFormContext<Schema extends Record<string, any>, FormValue, FormError>(options: FormOptions<Schema, FormError, FormValue>): FormContext<Schema, FormValue, FormError>;
147
+ export {};
package/form.js CHANGED
@@ -27,8 +27,8 @@ function createFormMeta(options, initialized) {
27
27
  // We can consider adding a warning if it happens
28
28
  error: (_ref = lastResult === null || lastResult === void 0 ? void 0 : lastResult.error) !== null && _ref !== void 0 ? _ref : {}
29
29
  };
30
- if (lastResult !== null && lastResult !== void 0 && lastResult.control) {
31
- handleControl(result, lastResult.control);
30
+ if (lastResult !== null && lastResult !== void 0 && lastResult.intent) {
31
+ handleIntent(result, lastResult.intent);
32
32
  }
33
33
  return result;
34
34
  }
@@ -45,24 +45,24 @@ function getDefaultKey(defaultValue, prefix) {
45
45
  return result;
46
46
  }, {});
47
47
  }
48
- function handleControl(meta, control, initialized) {
49
- switch (control.type) {
50
- case 'replace':
48
+ function handleIntent(meta, intent, initialized) {
49
+ switch (intent.type) {
50
+ case 'update':
51
51
  {
52
- var _control$payload$name;
53
- var _name = (_control$payload$name = control.payload.name) !== null && _control$payload$name !== void 0 ? _control$payload$name : '';
54
- var value = control.payload.value;
55
- updateValue(meta, _name, value);
52
+ if (typeof intent.payload.value !== 'undefined') {
53
+ var _intent$payload$name;
54
+ var _name = (_intent$payload$name = intent.payload.name) !== null && _intent$payload$name !== void 0 ? _intent$payload$name : '';
55
+ var value = intent.payload.value;
56
+ updateValue(meta, _name, value);
57
+ }
56
58
  break;
57
59
  }
58
60
  case 'reset':
59
61
  {
60
- if (typeof control.payload.value === 'undefined' || control.payload.value) {
61
- var _control$payload$name2;
62
- var _name2 = (_control$payload$name2 = control.payload.name) !== null && _control$payload$name2 !== void 0 ? _control$payload$name2 : '';
63
- var _value = formdata.getValue(meta.defaultValue, _name2);
64
- updateValue(meta, _name2, _value);
65
- }
62
+ var _intent$payload$name2;
63
+ var _name2 = (_intent$payload$name2 = intent.payload.name) !== null && _intent$payload$name2 !== void 0 ? _intent$payload$name2 : '';
64
+ var _value = formdata.getValue(meta.defaultValue, _name2);
65
+ updateValue(meta, _name2, _value);
66
66
  break;
67
67
  }
68
68
  case 'insert':
@@ -72,8 +72,8 @@ function handleControl(meta, control, initialized) {
72
72
  if (initialized) {
73
73
  meta.initialValue = util.clone(meta.initialValue);
74
74
  meta.key = util.clone(meta.key);
75
- submission.setListState(meta.key, control, util.generateId);
76
- submission.setListValue(meta.initialValue, control);
75
+ submission.setListState(meta.key, intent, util.generateId);
76
+ submission.setListValue(meta.initialValue, intent);
77
77
  }
78
78
  break;
79
79
  }
@@ -149,10 +149,34 @@ function createKeyProxy(key) {
149
149
  });
150
150
  }
151
151
  function createValidProxy(error) {
152
- return createStateProxy(name => typeof error[name] === 'undefined');
152
+ return createStateProxy(name => {
153
+ var keys = Object.keys(error);
154
+ if (name === '') {
155
+ return keys.length === 0;
156
+ }
157
+ for (var key of keys) {
158
+ if (formdata.isPrefix(key, name) && typeof error[key] !== 'undefined') {
159
+ return false;
160
+ }
161
+ }
162
+ return true;
163
+ });
153
164
  }
154
- function createDirtyProxy(defaultValue, value) {
155
- return createStateProxy(name => JSON.stringify(defaultValue[name]) !== JSON.stringify(value[name]));
165
+ function createDirtyProxy(defaultValue, value, shouldDirtyConsider) {
166
+ return createStateProxy(name => JSON.stringify(defaultValue[name]) !== JSON.stringify(value[name], (key, value) => {
167
+ if (name === '' && key === '' && value) {
168
+ return Object.entries(value).reduce((result, _ref3) => {
169
+ var [name, value] = _ref3;
170
+ if (!shouldDirtyConsider(name)) {
171
+ return result;
172
+ }
173
+ return Object.assign(result !== null && result !== void 0 ? result : {}, {
174
+ [name]: value
175
+ });
176
+ }, undefined);
177
+ }
178
+ return value;
179
+ }));
156
180
  }
157
181
  function shouldNotify(prev, next, cache, scope) {
158
182
  var compareFn = arguments.length > 4 && arguments[4] !== undefined ? arguments[4] : (prev, next) => JSON.stringify(prev) !== JSON.stringify(next);
@@ -180,25 +204,6 @@ function shouldNotify(prev, next, cache, scope) {
180
204
  }
181
205
  return false;
182
206
  }
183
- function createFormState(next) {
184
- var prev = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : next;
185
- var state = arguments.length > 2 ? arguments[2] : undefined;
186
- var defaultValue = !state || prev.defaultValue !== next.defaultValue ? createValueProxy(next.defaultValue) : state.defaultValue;
187
- var initialValue = next.initialValue === next.defaultValue ? defaultValue : !state || prev.initialValue !== next.initialValue ? createValueProxy(next.initialValue) : state.initialValue;
188
- var value = next.value === next.initialValue ? initialValue : !state || prev.value !== next.value ? createValueProxy(next.value) : state.value;
189
- return {
190
- submissionStatus: next.submissionStatus,
191
- defaultValue,
192
- initialValue,
193
- value,
194
- error: !state || prev.error !== next.error ? next.error : state.error,
195
- validated: next.validated,
196
- constraint: !state || prev.constraint !== next.constraint ? createConstraintProxy(next.constraint) : state.constraint,
197
- key: !state || prev.key !== next.key ? createKeyProxy(next.key) : state.key,
198
- valid: !state || prev.error !== next.error ? createValidProxy(next.error) : state.valid,
199
- dirty: !state || prev.defaultValue !== next.defaultValue || prev.value !== next.value ? createDirtyProxy(defaultValue, value) : state.dirty
200
- };
201
- }
202
207
  function createFormContext(options) {
203
208
  var subscribers = [];
204
209
  var latestOptions = options;
@@ -209,6 +214,28 @@ function createFormContext(options) {
209
214
  util.invariant(element !== null, "Form#".concat(latestOptions.formId, " does not exist"));
210
215
  return element;
211
216
  }
217
+ function createFormState(next) {
218
+ var prev = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : next;
219
+ var state = arguments.length > 2 ? arguments[2] : undefined;
220
+ var defaultValue = !state || prev.defaultValue !== next.defaultValue ? createValueProxy(next.defaultValue) : state.defaultValue;
221
+ var initialValue = next.initialValue === next.defaultValue ? defaultValue : !state || prev.initialValue !== next.initialValue ? createValueProxy(next.initialValue) : state.initialValue;
222
+ var value = next.value === next.initialValue ? initialValue : !state || prev.value !== next.value ? createValueProxy(next.value) : state.value;
223
+ return {
224
+ submissionStatus: next.submissionStatus,
225
+ defaultValue,
226
+ initialValue,
227
+ value,
228
+ error: !state || prev.error !== next.error ? next.error : state.error,
229
+ validated: next.validated,
230
+ constraint: !state || prev.constraint !== next.constraint ? createConstraintProxy(next.constraint) : state.constraint,
231
+ key: !state || prev.key !== next.key ? createKeyProxy(next.key) : state.key,
232
+ valid: !state || prev.error !== next.error ? createValidProxy(next.error) : state.valid,
233
+ dirty: !state || prev.defaultValue !== next.defaultValue || prev.value !== next.value ? createDirtyProxy(defaultValue, value, key => {
234
+ var _latestOptions$should, _latestOptions$should2;
235
+ return (_latestOptions$should = (_latestOptions$should2 = latestOptions.shouldDirtyConsider) === null || _latestOptions$should2 === void 0 ? void 0 : _latestOptions$should2.call(latestOptions, key)) !== null && _latestOptions$should !== void 0 ? _latestOptions$should : true;
236
+ }) : state.dirty
237
+ };
238
+ }
212
239
  function updateFormMeta(nextMeta) {
213
240
  var prevMeta = meta;
214
241
  var prevState = state;
@@ -242,12 +269,12 @@ function createFormContext(options) {
242
269
  var element = form.elements.namedItem(submission.STATE);
243
270
  util.invariant(element === null || dom.isFieldElement(element), "The input name \"".concat(submission.STATE, "\" is reserved by Conform. Please use another name."));
244
271
  if (!element) {
245
- var _input = document.createElement('input');
246
- _input.type = 'hidden';
247
- _input.name = submission.STATE;
248
- _input.value = '';
249
- form.append(_input);
250
- return _input;
272
+ var input = document.createElement('input');
273
+ input.type = 'hidden';
274
+ input.name = submission.STATE;
275
+ input.value = '';
276
+ form.append(input);
277
+ return input;
251
278
  }
252
279
  return element;
253
280
  }
@@ -257,7 +284,6 @@ function createFormContext(options) {
257
284
  });
258
285
  }
259
286
  function submit(event) {
260
- var _latestOptions;
261
287
  var form = event.target;
262
288
  var submitter = event.submitter;
263
289
  util.invariant(form === getFormElement(), "The submit event is dispatched by form#".concat(form.id, " instead of form#").concat(latestOptions.formId));
@@ -272,24 +298,25 @@ function createFormContext(options) {
272
298
  encType: dom.getFormEncType(event),
273
299
  method: dom.getFormMethod(event)
274
300
  };
275
- if (typeof ((_latestOptions = latestOptions) === null || _latestOptions === void 0 ? void 0 : _latestOptions.onValidate) === 'undefined') {
276
- var _latestOptions$onSubm, _latestOptions2;
277
- (_latestOptions$onSubm = (_latestOptions2 = latestOptions).onSubmit) === null || _latestOptions$onSubm === void 0 || _latestOptions$onSubm.call(_latestOptions2, event, context);
301
+ if (typeof (latestOptions === null || latestOptions === void 0 ? void 0 : latestOptions.onValidate) === 'undefined') {
302
+ var _latestOptions$onSubm;
303
+ (_latestOptions$onSubm = latestOptions.onSubmit) === null || _latestOptions$onSubm === void 0 || _latestOptions$onSubm.call(latestOptions, event, context);
304
+ return;
305
+ }
306
+ var submission = latestOptions.onValidate({
307
+ form,
308
+ formData,
309
+ submitter
310
+ });
311
+ if (submission.status !== 'success' && submission.error !== null) {
312
+ report(submission.reply());
278
313
  } else {
279
- var _latestOptions$onSubm2, _latestOptions3;
280
- var submission = latestOptions.onValidate({
281
- form,
282
- formData,
283
- submitter
284
- });
285
- if (submission.status !== 'success' && submission.error !== null) {
286
- report(submission.reply());
287
- event.preventDefault();
288
- }
289
- (_latestOptions$onSubm2 = (_latestOptions3 = latestOptions).onSubmit) === null || _latestOptions$onSubm2 === void 0 || _latestOptions$onSubm2.call(_latestOptions3, event, _rollupPluginBabelHelpers.objectSpread2(_rollupPluginBabelHelpers.objectSpread2({}, context), {}, {
314
+ var _latestOptions$onSubm2;
315
+ (_latestOptions$onSubm2 = latestOptions.onSubmit) === null || _latestOptions$onSubm2 === void 0 || _latestOptions$onSubm2.call(latestOptions, event, _rollupPluginBabelHelpers.objectSpread2(_rollupPluginBabelHelpers.objectSpread2({}, context), {}, {
290
316
  submission
291
317
  }));
292
318
  }
319
+ return submission;
293
320
  }
294
321
  function resolveTarget(event) {
295
322
  var form = getFormElement();
@@ -307,33 +334,39 @@ function createFormContext(options) {
307
334
  var validated = meta.validated[element.name];
308
335
  return validated ? shouldRevalidate === eventName : shouldValidate === eventName;
309
336
  }
310
- function input(event) {
337
+ function onInput(event) {
311
338
  var element = resolveTarget(event);
312
339
  if (!element || !element.form) {
313
340
  return;
314
341
  }
315
342
  if (event.defaultPrevented || !willValidate(element, 'onInput')) {
316
343
  var formData = new FormData(element.form);
317
- var _result2 = submission.getSubmissionContext(formData);
344
+ var result = submission.getSubmissionContext(formData);
318
345
  updateFormMeta(_rollupPluginBabelHelpers.objectSpread2(_rollupPluginBabelHelpers.objectSpread2({}, meta), {}, {
319
- value: _result2.payload
346
+ value: result.payload
320
347
  }));
321
348
  } else {
322
- dispatch(submission.control.validate({
323
- name: element.name
324
- }));
349
+ dispatch({
350
+ type: 'validate',
351
+ payload: {
352
+ name: element.name
353
+ }
354
+ });
325
355
  }
326
356
  }
327
- function blur(event) {
357
+ function onBlur(event) {
328
358
  var element = resolveTarget(event);
329
359
  if (!element || event.defaultPrevented || !willValidate(element, 'onBlur')) {
330
360
  return;
331
361
  }
332
- dispatch(submission.control.validate({
333
- name: element.name
334
- }));
362
+ dispatch({
363
+ type: 'validate',
364
+ payload: {
365
+ name: element.name
366
+ }
367
+ });
335
368
  }
336
- function reset(event) {
369
+ function onReset(event) {
337
370
  var element = getFormElement();
338
371
  if (event.type !== 'reset' || event.target !== element || event.defaultPrevented) {
339
372
  return;
@@ -347,8 +380,8 @@ function createFormContext(options) {
347
380
  formElement.reset();
348
381
  return;
349
382
  }
350
- var error = Object.entries((_result$error = result.error) !== null && _result$error !== void 0 ? _result$error : {}).reduce((result, _ref3) => {
351
- var [name, newError] = _ref3;
383
+ var error = Object.entries((_result$error = result.error) !== null && _result$error !== void 0 ? _result$error : {}).reduce((result, _ref4) => {
384
+ var [name, newError] = _ref4;
352
385
  var error = newError === null ? meta.error[name] : newError;
353
386
  if (error) {
354
387
  result[name] = error;
@@ -361,8 +394,8 @@ function createFormContext(options) {
361
394
  error,
362
395
  validated: (_result$state$validat = (_result$state = result.state) === null || _result$state === void 0 ? void 0 : _result$state.validated) !== null && _result$state$validat !== void 0 ? _result$state$validat : {}
363
396
  });
364
- if (result.control) {
365
- handleControl(update, result.control, true);
397
+ if (result.intent) {
398
+ handleIntent(update, result.intent, true);
366
399
  }
367
400
  updateFormMeta(update);
368
401
  if (result.status === 'error') {
@@ -374,11 +407,16 @@ function createFormContext(options) {
374
407
  }
375
408
  }
376
409
  }
377
- function update(options) {
410
+ function onUpdate(options) {
378
411
  var currentFormId = latestOptions.formId;
379
- latestOptions = options;
412
+ var currentResult = latestOptions.lastResult;
413
+
414
+ // Merge new options with the latest options
415
+ Object.assign(latestOptions, options);
380
416
  if (latestOptions.formId !== currentFormId) {
381
417
  getFormElement().reset();
418
+ } else if (options.lastResult && options.lastResult !== currentResult) {
419
+ report(options.lastResult);
382
420
  }
383
421
  }
384
422
  function subscribe(callback, getSubject) {
@@ -394,10 +432,10 @@ function createFormContext(options) {
394
432
  function getState() {
395
433
  return state;
396
434
  }
397
- function dispatch(control) {
435
+ function dispatch(intent) {
398
436
  var form = getFormElement();
399
437
  var submitter = document.createElement('button');
400
- var buttonProps = getControlButtonProps(control);
438
+ var buttonProps = getControlButtonProps(intent);
401
439
  submitter.name = buttonProps.name;
402
440
  submitter.value = buttonProps.value;
403
441
  submitter.hidden = true;
@@ -406,26 +444,47 @@ function createFormContext(options) {
406
444
  dom.requestSubmit(form, submitter);
407
445
  form === null || form === void 0 || form.removeChild(submitter);
408
446
  }
409
- function getControlButtonProps(control) {
447
+ function getControlButtonProps(intent) {
410
448
  return {
411
- name: submission.CONTROL,
412
- value: submission.serializeControl(control),
449
+ name: submission.INTENT,
450
+ value: submission.serializeIntent(intent),
413
451
  form: latestOptions.formId,
414
452
  formNoValidate: true
415
453
  };
416
454
  }
455
+ function createFormControl(type) {
456
+ var control = function control() {
457
+ var payload = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
458
+ return dispatch({
459
+ type,
460
+ payload
461
+ });
462
+ };
463
+ return Object.assign(control, {
464
+ getButtonProps() {
465
+ var payload = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
466
+ return getControlButtonProps({
467
+ type,
468
+ payload
469
+ });
470
+ }
471
+ });
472
+ }
417
473
  return {
418
474
  get formId() {
419
475
  return latestOptions.formId;
420
476
  },
421
477
  submit,
422
- reset,
423
- input,
424
- blur,
425
- dispatch,
426
- getControlButtonProps,
427
- report,
428
- update,
478
+ onReset,
479
+ onInput,
480
+ onBlur,
481
+ onUpdate,
482
+ validate: createFormControl('validate'),
483
+ reset: createFormControl('reset'),
484
+ update: createFormControl('update'),
485
+ insert: createFormControl('insert'),
486
+ remove: createFormControl('remove'),
487
+ reorder: createFormControl('reorder'),
429
488
  subscribe,
430
489
  getState,
431
490
  getSerializedState