@conform-to/react 0.1.1 → 0.2.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/hooks.js CHANGED
@@ -49,7 +49,7 @@ function useForm() {
49
49
  var handleChange = event => {
50
50
  var _event$target;
51
51
 
52
- if (!dom.isFieldElement(event.target) || ((_event$target = event.target) === null || _event$target === void 0 ? void 0 : _event$target.form) !== ref.current) {
52
+ if (!ref.current || !dom.isFieldElement(event.target) || ((_event$target = event.target) === null || _event$target === void 0 ? void 0 : _event$target.form) !== ref.current) {
53
53
  return;
54
54
  }
55
55
 
@@ -59,15 +59,13 @@ function useForm() {
59
59
  });
60
60
  }
61
61
 
62
- if (ref.current) {
63
- dom.reportValidity(ref.current);
64
- }
62
+ dom.reportValidity(ref.current);
65
63
  };
66
64
 
67
65
  var handleBlur = event => {
68
66
  var _event$target2;
69
67
 
70
- if (!dom.isFieldElement(event.target) || ((_event$target2 = event.target) === null || _event$target2 === void 0 ? void 0 : _event$target2.form) !== ref.current) {
68
+ if (!ref.current || !dom.isFieldElement(event.target) || ((_event$target2 = event.target) === null || _event$target2 === void 0 ? void 0 : _event$target2.form) !== ref.current) {
71
69
  return;
72
70
  }
73
71
 
@@ -77,16 +75,14 @@ function useForm() {
77
75
  });
78
76
  }
79
77
 
80
- if (ref.current) {
81
- dom.reportValidity(ref.current);
82
- }
78
+ dom.reportValidity(ref.current);
83
79
  };
84
80
 
85
- document.body.addEventListener('input', handleChange);
86
- document.body.addEventListener('focusout', handleBlur);
81
+ document.addEventListener('input', handleChange);
82
+ document.addEventListener('focusout', handleBlur);
87
83
  return () => {
88
- document.body.removeEventListener('input', handleChange);
89
- document.body.removeEventListener('focusout', handleBlur);
84
+ document.removeEventListener('input', handleChange);
85
+ document.removeEventListener('focusout', handleBlur);
90
86
  };
91
87
  }, [noValidate, initialReport]);
92
88
  return {
@@ -202,6 +198,27 @@ function useFieldset(schema) {
202
198
  fieldset
203
199
  }
204
200
  });
201
+
202
+ var resetHandler = e => {
203
+ if (e.target !== fieldset.form) {
204
+ return;
205
+ }
206
+
207
+ dispatch({
208
+ type: 'reset'
209
+ });
210
+ setTimeout(() => {
211
+ var _schema$validate2;
212
+
213
+ // Delay revalidation until reset is completed
214
+ (_schema$validate2 = schema.validate) === null || _schema$validate2 === void 0 ? void 0 : _schema$validate2.call(schema, fieldset);
215
+ }, 0);
216
+ };
217
+
218
+ document.addEventListener('reset', resetHandler);
219
+ return () => {
220
+ document.removeEventListener('reset', resetHandler);
221
+ };
205
222
  }, // eslint-disable-next-line react-hooks/exhaustive-deps
206
223
  [schema.validate]);
207
224
  react.useEffect(() => {
@@ -219,10 +236,10 @@ function useFieldset(schema) {
219
236
  form: config.form,
220
237
 
221
238
  onInput(e) {
222
- var _schema$validate2;
239
+ var _schema$validate3;
223
240
 
224
241
  var fieldset = e.currentTarget;
225
- (_schema$validate2 = schema.validate) === null || _schema$validate2 === void 0 ? void 0 : _schema$validate2.call(schema, fieldset);
242
+ (_schema$validate3 = schema.validate) === null || _schema$validate3 === void 0 ? void 0 : _schema$validate3.call(schema, fieldset);
226
243
  dispatch({
227
244
  type: 'cleanup',
228
245
  payload: {
@@ -231,15 +248,6 @@ function useFieldset(schema) {
231
248
  });
232
249
  },
233
250
 
234
- onReset(e) {
235
- dom.setFieldState(e.currentTarget, {
236
- touched: false
237
- });
238
- dispatch({
239
- type: 'reset'
240
- });
241
- },
242
-
243
251
  onInvalid(e) {
244
252
  var element = dom.isFieldElement(e.target) ? e.target : null;
245
253
  var key = Object.keys(schema.fields).find(key => (element === null || element === void 0 ? void 0 : element.name) === dom.getName([e.currentTarget.name, key]));
@@ -259,45 +267,69 @@ function useFieldset(schema) {
259
267
  });
260
268
  }
261
269
 
262
- }, dom.createFieldConfig(schema, _rollupPluginBabelHelpers.objectSpread2(_rollupPluginBabelHelpers.objectSpread2({}, config), {}, {
270
+ }, dom.getFieldProps(schema, _rollupPluginBabelHelpers.objectSpread2(_rollupPluginBabelHelpers.objectSpread2({}, config), {}, {
263
271
  error: Object.assign({}, config.error, errorMessage)
264
272
  }))];
265
273
  }
266
- function useFieldList(config) {
267
- var _config$initialValue$, _config$initialValue;
274
+ function useFieldList(props) {
275
+ var [entries, setEntries] = react.useState(() => {
276
+ var _props$defaultValue;
268
277
 
269
- var size = (_config$initialValue$ = (_config$initialValue = config.initialValue) === null || _config$initialValue === void 0 ? void 0 : _config$initialValue.length) !== null && _config$initialValue$ !== void 0 ? _config$initialValue$ : 1;
270
- var [keys, setKeys] = react.useState(() => [...Array(size).keys()]);
271
- var list = react.useMemo(() => keys.map((key, index) => {
272
- var _config$initialValue2, _config$error2;
278
+ return Object.entries((_props$defaultValue = props.defaultValue) !== null && _props$defaultValue !== void 0 ? _props$defaultValue : [undefined]);
279
+ });
280
+ var list = entries.map((_ref, index) => {
281
+ var _props$defaultValue2, _props$error;
273
282
 
283
+ var [key, defaultValue] = _ref;
274
284
  return {
275
285
  key: "".concat(key),
276
- config: _rollupPluginBabelHelpers.objectSpread2(_rollupPluginBabelHelpers.objectSpread2({}, config), {}, {
277
- name: "".concat(config.name, "[").concat(index, "]"),
278
- initialValue: (_config$initialValue2 = config.initialValue) === null || _config$initialValue2 === void 0 ? void 0 : _config$initialValue2[index],
279
- error: (_config$error2 = config.error) === null || _config$error2 === void 0 ? void 0 : _config$error2[index],
280
- constraint: _rollupPluginBabelHelpers.objectSpread2(_rollupPluginBabelHelpers.objectSpread2({}, config.constraint), {}, {
281
- multiple: false
282
- })
286
+ props: _rollupPluginBabelHelpers.objectSpread2(_rollupPluginBabelHelpers.objectSpread2({}, props), {}, {
287
+ name: "".concat(props.name, "[").concat(index, "]"),
288
+ defaultValue: defaultValue !== null && defaultValue !== void 0 ? defaultValue : (_props$defaultValue2 = props.defaultValue) === null || _props$defaultValue2 === void 0 ? void 0 : _props$defaultValue2[index],
289
+ error: (_props$error = props.error) === null || _props$error === void 0 ? void 0 : _props$error[index],
290
+ multiple: false
283
291
  })
284
292
  };
285
- }), [keys, config]);
293
+ });
286
294
  var controls = {
287
- prepend() {
288
- return _rollupPluginBabelHelpers.objectSpread2(_rollupPluginBabelHelpers.objectSpread2({}, dom.createControlButton(config.name, 'prepend', {})), {}, {
295
+ prepend(defaultValue) {
296
+ return _rollupPluginBabelHelpers.objectSpread2(_rollupPluginBabelHelpers.objectSpread2({}, dom.getControlButtonProps(props.name, 'prepend', {
297
+ defaultValue
298
+ })), {}, {
299
+ onClick(e) {
300
+ setEntries(entries => dom.applyControlCommand([...entries], 'prepend', {
301
+ defaultValue: ["".concat(Date.now()), defaultValue]
302
+ }));
303
+ e.preventDefault();
304
+ }
305
+
306
+ });
307
+ },
308
+
309
+ append(defaultValue) {
310
+ return _rollupPluginBabelHelpers.objectSpread2(_rollupPluginBabelHelpers.objectSpread2({}, dom.getControlButtonProps(props.name, 'append', {
311
+ defaultValue
312
+ })), {}, {
289
313
  onClick(e) {
290
- setKeys(keys => [Date.now(), ...keys]);
314
+ setEntries(entries => dom.applyControlCommand([...entries], 'append', {
315
+ defaultValue: ["".concat(Date.now()), defaultValue]
316
+ }));
291
317
  e.preventDefault();
292
318
  }
293
319
 
294
320
  });
295
321
  },
296
322
 
297
- append() {
298
- return _rollupPluginBabelHelpers.objectSpread2(_rollupPluginBabelHelpers.objectSpread2({}, dom.createControlButton(config.name, 'append', {})), {}, {
323
+ replace(index, defaultValue) {
324
+ return _rollupPluginBabelHelpers.objectSpread2(_rollupPluginBabelHelpers.objectSpread2({}, dom.getControlButtonProps(props.name, 'replace', {
325
+ index,
326
+ defaultValue
327
+ })), {}, {
299
328
  onClick(e) {
300
- setKeys(keys => [...keys, Date.now()]);
329
+ setEntries(entries => dom.applyControlCommand([...entries], 'replace', {
330
+ defaultValue: ["".concat(Date.now()), defaultValue],
331
+ index
332
+ }));
301
333
  e.preventDefault();
302
334
  }
303
335
 
@@ -305,11 +337,32 @@ function useFieldList(config) {
305
337
  },
306
338
 
307
339
  remove(index) {
308
- return _rollupPluginBabelHelpers.objectSpread2(_rollupPluginBabelHelpers.objectSpread2({}, dom.createControlButton(config.name, 'remove', {
340
+ return _rollupPluginBabelHelpers.objectSpread2(_rollupPluginBabelHelpers.objectSpread2({}, dom.getControlButtonProps(props.name, 'remove', {
309
341
  index
310
342
  })), {}, {
311
343
  onClick(e) {
312
- setKeys(keys => [...keys.slice(0, index), ...keys.slice(index + 1)]);
344
+ setEntries(entries => dom.applyControlCommand([...entries], 'remove', {
345
+ index
346
+ }));
347
+ e.preventDefault();
348
+ }
349
+
350
+ });
351
+ },
352
+
353
+ reorder(fromIndex, toIndex) {
354
+ return _rollupPluginBabelHelpers.objectSpread2(_rollupPluginBabelHelpers.objectSpread2({}, dom.getControlButtonProps(props.name, 'reorder', {
355
+ from: fromIndex,
356
+ to: toIndex
357
+ })), {}, {
358
+ onClick(e) {
359
+ if (fromIndex !== toIndex) {
360
+ setEntries(entries => dom.applyControlCommand([...entries], 'reorder', {
361
+ from: fromIndex,
362
+ to: toIndex
363
+ }));
364
+ }
365
+
313
366
  e.preventDefault();
314
367
  }
315
368
 
@@ -318,60 +371,49 @@ function useFieldList(config) {
318
371
 
319
372
  };
320
373
  react.useEffect(() => {
321
- setKeys(keys => {
322
- if (keys.length === size) {
323
- return keys;
324
- }
374
+ var _props$defaultValue3;
325
375
 
326
- return [...Array(size).keys()];
327
- });
328
- }, [size]);
376
+ setEntries(Object.entries((_props$defaultValue3 = props.defaultValue) !== null && _props$defaultValue3 !== void 0 ? _props$defaultValue3 : [undefined]));
377
+ }, [props.defaultValue]);
329
378
  return [list, controls];
330
379
  }
331
380
  function useControlledInput(field) {
332
- var _field$initialValue;
381
+ var _ref$current$value, _ref$current, _field$defaultValue;
333
382
 
334
- var [value, setValue] = react.useState("".concat((_field$initialValue = field.initialValue) !== null && _field$initialValue !== void 0 ? _field$initialValue : ''));
335
- var [shouldBlur, setShouldBlur] = react.useState(false);
336
383
  var ref = react.useRef(null);
337
- var input = react.useMemo(() => /*#__PURE__*/react.createElement('input', _rollupPluginBabelHelpers.objectSpread2(_rollupPluginBabelHelpers.objectSpread2({}, field.constraint), {}, {
384
+ var input = react.useMemo(() => /*#__PURE__*/react.createElement('input', {
338
385
  ref,
339
386
  name: field.name,
340
- defaultValue: field.initialValue,
341
- style: {
342
- display: 'none'
343
- },
387
+ form: field.form,
388
+ defaultValue: field.defaultValue,
389
+ required: field.required,
390
+ minLength: field.minLength,
391
+ maxLength: field.maxLength,
392
+ min: field.min,
393
+ max: field.max,
394
+ step: field.step,
395
+ pattern: field.pattern,
396
+ hidden: true,
344
397
  'aria-hidden': true
345
- })), [field.constraint, field.name, field.initialValue]);
346
- react.useEffect(() => {
347
- if (!ref.current) {
348
- return;
349
- }
350
-
351
- ref.current.value = value;
352
- ref.current.dispatchEvent(new InputEvent('input', {
353
- bubbles: true
354
- }));
355
- }, [value]);
356
- react.useEffect(() => {
357
- var _ref$current;
358
-
359
- if (!shouldBlur) {
360
- return;
361
- }
362
-
363
- (_ref$current = ref.current) === null || _ref$current === void 0 ? void 0 : _ref$current.dispatchEvent(new FocusEvent('focusout', {
364
- bubbles: true
365
- }));
366
- setShouldBlur(false);
367
- }, [shouldBlur]);
398
+ }), [field.name, field.form, field.defaultValue, field.required, field.minLength, field.maxLength, field.min, field.max, field.step, field.pattern]);
368
399
  return [input, {
369
- value,
400
+ value: (_ref$current$value = (_ref$current = ref.current) === null || _ref$current === void 0 ? void 0 : _ref$current.value) !== null && _ref$current$value !== void 0 ? _ref$current$value : "".concat((_field$defaultValue = field.defaultValue) !== null && _field$defaultValue !== void 0 ? _field$defaultValue : ''),
370
401
  onChange: value => {
371
- setValue(value);
402
+ if (!ref.current) {
403
+ return;
404
+ }
405
+
406
+ ref.current.value = value;
407
+ ref.current.dispatchEvent(new InputEvent('input', {
408
+ bubbles: true
409
+ }));
372
410
  },
373
411
  onBlur: () => {
374
- setShouldBlur(true);
412
+ var _ref$current2;
413
+
414
+ (_ref$current2 = ref.current) === null || _ref$current2 === void 0 ? void 0 : _ref$current2.dispatchEvent(new FocusEvent('focusout', {
415
+ bubbles: true
416
+ }));
375
417
  }
376
418
  }];
377
419
  }
package/index.d.ts CHANGED
@@ -1,3 +1,3 @@
1
- export { type FieldConfig, type Schema, parse, getFieldElements, } from '@conform-to/dom';
1
+ export { type FieldProps, type FormState, type Schema, type Submission, parse, getFieldElements, } from '@conform-to/dom';
2
2
  export * from './hooks';
3
3
  export * as conform from './helpers';
package/module/helpers.js CHANGED
@@ -1,6 +1,4 @@
1
- function input(config) {
2
- var _config$constraint, _config$constraint2, _config$constraint3, _config$constraint4, _config$constraint5, _config$constraint6, _config$constraint7;
3
-
1
+ function input(props) {
4
2
  var {
5
3
  type,
6
4
  value
@@ -8,49 +6,50 @@ function input(config) {
8
6
  var isCheckboxOrRadio = type === 'checkbox' || type === 'radio';
9
7
  var attributes = {
10
8
  type,
11
- name: config.name,
12
- form: config.form,
13
- required: (_config$constraint = config.constraint) === null || _config$constraint === void 0 ? void 0 : _config$constraint.required,
14
- minLength: (_config$constraint2 = config.constraint) === null || _config$constraint2 === void 0 ? void 0 : _config$constraint2.minLength,
15
- maxLength: (_config$constraint3 = config.constraint) === null || _config$constraint3 === void 0 ? void 0 : _config$constraint3.maxLength,
16
- min: (_config$constraint4 = config.constraint) === null || _config$constraint4 === void 0 ? void 0 : _config$constraint4.min,
17
- max: (_config$constraint5 = config.constraint) === null || _config$constraint5 === void 0 ? void 0 : _config$constraint5.max,
18
- step: (_config$constraint6 = config.constraint) === null || _config$constraint6 === void 0 ? void 0 : _config$constraint6.step,
19
- pattern: (_config$constraint7 = config.constraint) === null || _config$constraint7 === void 0 ? void 0 : _config$constraint7.pattern
9
+ name: props.name,
10
+ form: props.form,
11
+ required: props.required,
12
+ minLength: props.minLength,
13
+ maxLength: props.maxLength,
14
+ min: props.min,
15
+ max: props.max,
16
+ step: props.step,
17
+ pattern: props.pattern,
18
+ multiple: props.multiple
20
19
  };
21
20
 
22
21
  if (isCheckboxOrRadio) {
23
22
  attributes.value = value !== null && value !== void 0 ? value : 'on';
24
- attributes.defaultChecked = config.initialValue === attributes.value;
23
+ attributes.defaultChecked = props.defaultValue === attributes.value;
25
24
  } else {
26
- var _config$initialValue;
25
+ var _props$defaultValue;
27
26
 
28
- attributes.defaultValue = "".concat((_config$initialValue = config.initialValue) !== null && _config$initialValue !== void 0 ? _config$initialValue : '');
27
+ attributes.defaultValue = "".concat((_props$defaultValue = props.defaultValue) !== null && _props$defaultValue !== void 0 ? _props$defaultValue : '');
29
28
  }
30
29
 
31
30
  return attributes;
32
31
  }
33
- function select(config) {
34
- var _config$initialValue2, _config$constraint8, _config$constraint9;
32
+ function select(props) {
33
+ var _props$defaultValue2;
35
34
 
36
35
  return {
37
- name: config.name,
38
- form: config.form,
39
- defaultValue: "".concat((_config$initialValue2 = config.initialValue) !== null && _config$initialValue2 !== void 0 ? _config$initialValue2 : ''),
40
- required: (_config$constraint8 = config.constraint) === null || _config$constraint8 === void 0 ? void 0 : _config$constraint8.required,
41
- multiple: (_config$constraint9 = config.constraint) === null || _config$constraint9 === void 0 ? void 0 : _config$constraint9.multiple
36
+ name: props.name,
37
+ form: props.form,
38
+ defaultValue: props.multiple ? Array.isArray(props.defaultValue) ? props.defaultValue : [] : "".concat((_props$defaultValue2 = props.defaultValue) !== null && _props$defaultValue2 !== void 0 ? _props$defaultValue2 : ''),
39
+ required: props.required,
40
+ multiple: props.multiple
42
41
  };
43
42
  }
44
- function textarea(config) {
45
- var _config$initialValue3, _config$constraint10, _config$constraint11, _config$constraint12;
43
+ function textarea(props) {
44
+ var _props$defaultValue3;
46
45
 
47
46
  return {
48
- name: config.name,
49
- form: config.form,
50
- defaultValue: "".concat((_config$initialValue3 = config.initialValue) !== null && _config$initialValue3 !== void 0 ? _config$initialValue3 : ''),
51
- required: (_config$constraint10 = config.constraint) === null || _config$constraint10 === void 0 ? void 0 : _config$constraint10.required,
52
- minLength: (_config$constraint11 = config.constraint) === null || _config$constraint11 === void 0 ? void 0 : _config$constraint11.minLength,
53
- maxLength: (_config$constraint12 = config.constraint) === null || _config$constraint12 === void 0 ? void 0 : _config$constraint12.maxLength
47
+ name: props.name,
48
+ form: props.form,
49
+ defaultValue: "".concat((_props$defaultValue3 = props.defaultValue) !== null && _props$defaultValue3 !== void 0 ? _props$defaultValue3 : ''),
50
+ required: props.required,
51
+ minLength: props.minLength,
52
+ maxLength: props.maxLength
54
53
  };
55
54
  }
56
55