@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/module/hooks.js CHANGED
@@ -1,5 +1,5 @@
1
1
  import { objectSpread2 as _objectSpread2 } from './_virtual/_rollupPluginBabelHelpers.js';
2
- import { getFieldElements, setFieldState, isFieldElement, getName, createFieldConfig, shouldSkipValidate, reportValidity, createControlButton } from '@conform-to/dom';
2
+ import { getFieldElements, isFieldElement, getName, getFieldProps, setFieldState, shouldSkipValidate, reportValidity, getControlButtonProps, applyControlCommand } from '@conform-to/dom';
3
3
  import { useRef, useState, useEffect, useReducer, useMemo, createElement } from 'react';
4
4
 
5
5
  function useForm() {
@@ -45,7 +45,7 @@ function useForm() {
45
45
  var handleChange = event => {
46
46
  var _event$target;
47
47
 
48
- if (!isFieldElement(event.target) || ((_event$target = event.target) === null || _event$target === void 0 ? void 0 : _event$target.form) !== ref.current) {
48
+ if (!ref.current || !isFieldElement(event.target) || ((_event$target = event.target) === null || _event$target === void 0 ? void 0 : _event$target.form) !== ref.current) {
49
49
  return;
50
50
  }
51
51
 
@@ -55,15 +55,13 @@ function useForm() {
55
55
  });
56
56
  }
57
57
 
58
- if (ref.current) {
59
- reportValidity(ref.current);
60
- }
58
+ reportValidity(ref.current);
61
59
  };
62
60
 
63
61
  var handleBlur = event => {
64
62
  var _event$target2;
65
63
 
66
- if (!isFieldElement(event.target) || ((_event$target2 = event.target) === null || _event$target2 === void 0 ? void 0 : _event$target2.form) !== ref.current) {
64
+ if (!ref.current || !isFieldElement(event.target) || ((_event$target2 = event.target) === null || _event$target2 === void 0 ? void 0 : _event$target2.form) !== ref.current) {
67
65
  return;
68
66
  }
69
67
 
@@ -73,16 +71,14 @@ function useForm() {
73
71
  });
74
72
  }
75
73
 
76
- if (ref.current) {
77
- reportValidity(ref.current);
78
- }
74
+ reportValidity(ref.current);
79
75
  };
80
76
 
81
- document.body.addEventListener('input', handleChange);
82
- document.body.addEventListener('focusout', handleBlur);
77
+ document.addEventListener('input', handleChange);
78
+ document.addEventListener('focusout', handleBlur);
83
79
  return () => {
84
- document.body.removeEventListener('input', handleChange);
85
- document.body.removeEventListener('focusout', handleBlur);
80
+ document.removeEventListener('input', handleChange);
81
+ document.removeEventListener('focusout', handleBlur);
86
82
  };
87
83
  }, [noValidate, initialReport]);
88
84
  return {
@@ -198,6 +194,27 @@ function useFieldset(schema) {
198
194
  fieldset
199
195
  }
200
196
  });
197
+
198
+ var resetHandler = e => {
199
+ if (e.target !== fieldset.form) {
200
+ return;
201
+ }
202
+
203
+ dispatch({
204
+ type: 'reset'
205
+ });
206
+ setTimeout(() => {
207
+ var _schema$validate2;
208
+
209
+ // Delay revalidation until reset is completed
210
+ (_schema$validate2 = schema.validate) === null || _schema$validate2 === void 0 ? void 0 : _schema$validate2.call(schema, fieldset);
211
+ }, 0);
212
+ };
213
+
214
+ document.addEventListener('reset', resetHandler);
215
+ return () => {
216
+ document.removeEventListener('reset', resetHandler);
217
+ };
201
218
  }, // eslint-disable-next-line react-hooks/exhaustive-deps
202
219
  [schema.validate]);
203
220
  useEffect(() => {
@@ -215,10 +232,10 @@ function useFieldset(schema) {
215
232
  form: config.form,
216
233
 
217
234
  onInput(e) {
218
- var _schema$validate2;
235
+ var _schema$validate3;
219
236
 
220
237
  var fieldset = e.currentTarget;
221
- (_schema$validate2 = schema.validate) === null || _schema$validate2 === void 0 ? void 0 : _schema$validate2.call(schema, fieldset);
238
+ (_schema$validate3 = schema.validate) === null || _schema$validate3 === void 0 ? void 0 : _schema$validate3.call(schema, fieldset);
222
239
  dispatch({
223
240
  type: 'cleanup',
224
241
  payload: {
@@ -227,15 +244,6 @@ function useFieldset(schema) {
227
244
  });
228
245
  },
229
246
 
230
- onReset(e) {
231
- setFieldState(e.currentTarget, {
232
- touched: false
233
- });
234
- dispatch({
235
- type: 'reset'
236
- });
237
- },
238
-
239
247
  onInvalid(e) {
240
248
  var element = isFieldElement(e.target) ? e.target : null;
241
249
  var key = Object.keys(schema.fields).find(key => (element === null || element === void 0 ? void 0 : element.name) === getName([e.currentTarget.name, key]));
@@ -255,45 +263,69 @@ function useFieldset(schema) {
255
263
  });
256
264
  }
257
265
 
258
- }, createFieldConfig(schema, _objectSpread2(_objectSpread2({}, config), {}, {
266
+ }, getFieldProps(schema, _objectSpread2(_objectSpread2({}, config), {}, {
259
267
  error: Object.assign({}, config.error, errorMessage)
260
268
  }))];
261
269
  }
262
- function useFieldList(config) {
263
- var _config$initialValue$, _config$initialValue;
270
+ function useFieldList(props) {
271
+ var [entries, setEntries] = useState(() => {
272
+ var _props$defaultValue;
264
273
 
265
- 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;
266
- var [keys, setKeys] = useState(() => [...Array(size).keys()]);
267
- var list = useMemo(() => keys.map((key, index) => {
268
- var _config$initialValue2, _config$error2;
274
+ return Object.entries((_props$defaultValue = props.defaultValue) !== null && _props$defaultValue !== void 0 ? _props$defaultValue : [undefined]);
275
+ });
276
+ var list = entries.map((_ref, index) => {
277
+ var _props$defaultValue2, _props$error;
269
278
 
279
+ var [key, defaultValue] = _ref;
270
280
  return {
271
281
  key: "".concat(key),
272
- config: _objectSpread2(_objectSpread2({}, config), {}, {
273
- name: "".concat(config.name, "[").concat(index, "]"),
274
- initialValue: (_config$initialValue2 = config.initialValue) === null || _config$initialValue2 === void 0 ? void 0 : _config$initialValue2[index],
275
- error: (_config$error2 = config.error) === null || _config$error2 === void 0 ? void 0 : _config$error2[index],
276
- constraint: _objectSpread2(_objectSpread2({}, config.constraint), {}, {
277
- multiple: false
278
- })
282
+ props: _objectSpread2(_objectSpread2({}, props), {}, {
283
+ name: "".concat(props.name, "[").concat(index, "]"),
284
+ defaultValue: defaultValue !== null && defaultValue !== void 0 ? defaultValue : (_props$defaultValue2 = props.defaultValue) === null || _props$defaultValue2 === void 0 ? void 0 : _props$defaultValue2[index],
285
+ error: (_props$error = props.error) === null || _props$error === void 0 ? void 0 : _props$error[index],
286
+ multiple: false
279
287
  })
280
288
  };
281
- }), [keys, config]);
289
+ });
282
290
  var controls = {
283
- prepend() {
284
- return _objectSpread2(_objectSpread2({}, createControlButton(config.name, 'prepend', {})), {}, {
291
+ prepend(defaultValue) {
292
+ return _objectSpread2(_objectSpread2({}, getControlButtonProps(props.name, 'prepend', {
293
+ defaultValue
294
+ })), {}, {
295
+ onClick(e) {
296
+ setEntries(entries => applyControlCommand([...entries], 'prepend', {
297
+ defaultValue: ["".concat(Date.now()), defaultValue]
298
+ }));
299
+ e.preventDefault();
300
+ }
301
+
302
+ });
303
+ },
304
+
305
+ append(defaultValue) {
306
+ return _objectSpread2(_objectSpread2({}, getControlButtonProps(props.name, 'append', {
307
+ defaultValue
308
+ })), {}, {
285
309
  onClick(e) {
286
- setKeys(keys => [Date.now(), ...keys]);
310
+ setEntries(entries => applyControlCommand([...entries], 'append', {
311
+ defaultValue: ["".concat(Date.now()), defaultValue]
312
+ }));
287
313
  e.preventDefault();
288
314
  }
289
315
 
290
316
  });
291
317
  },
292
318
 
293
- append() {
294
- return _objectSpread2(_objectSpread2({}, createControlButton(config.name, 'append', {})), {}, {
319
+ replace(index, defaultValue) {
320
+ return _objectSpread2(_objectSpread2({}, getControlButtonProps(props.name, 'replace', {
321
+ index,
322
+ defaultValue
323
+ })), {}, {
295
324
  onClick(e) {
296
- setKeys(keys => [...keys, Date.now()]);
325
+ setEntries(entries => applyControlCommand([...entries], 'replace', {
326
+ defaultValue: ["".concat(Date.now()), defaultValue],
327
+ index
328
+ }));
297
329
  e.preventDefault();
298
330
  }
299
331
 
@@ -301,11 +333,32 @@ function useFieldList(config) {
301
333
  },
302
334
 
303
335
  remove(index) {
304
- return _objectSpread2(_objectSpread2({}, createControlButton(config.name, 'remove', {
336
+ return _objectSpread2(_objectSpread2({}, getControlButtonProps(props.name, 'remove', {
305
337
  index
306
338
  })), {}, {
307
339
  onClick(e) {
308
- setKeys(keys => [...keys.slice(0, index), ...keys.slice(index + 1)]);
340
+ setEntries(entries => applyControlCommand([...entries], 'remove', {
341
+ index
342
+ }));
343
+ e.preventDefault();
344
+ }
345
+
346
+ });
347
+ },
348
+
349
+ reorder(fromIndex, toIndex) {
350
+ return _objectSpread2(_objectSpread2({}, getControlButtonProps(props.name, 'reorder', {
351
+ from: fromIndex,
352
+ to: toIndex
353
+ })), {}, {
354
+ onClick(e) {
355
+ if (fromIndex !== toIndex) {
356
+ setEntries(entries => applyControlCommand([...entries], 'reorder', {
357
+ from: fromIndex,
358
+ to: toIndex
359
+ }));
360
+ }
361
+
309
362
  e.preventDefault();
310
363
  }
311
364
 
@@ -314,60 +367,49 @@ function useFieldList(config) {
314
367
 
315
368
  };
316
369
  useEffect(() => {
317
- setKeys(keys => {
318
- if (keys.length === size) {
319
- return keys;
320
- }
370
+ var _props$defaultValue3;
321
371
 
322
- return [...Array(size).keys()];
323
- });
324
- }, [size]);
372
+ setEntries(Object.entries((_props$defaultValue3 = props.defaultValue) !== null && _props$defaultValue3 !== void 0 ? _props$defaultValue3 : [undefined]));
373
+ }, [props.defaultValue]);
325
374
  return [list, controls];
326
375
  }
327
376
  function useControlledInput(field) {
328
- var _field$initialValue;
377
+ var _ref$current$value, _ref$current, _field$defaultValue;
329
378
 
330
- var [value, setValue] = useState("".concat((_field$initialValue = field.initialValue) !== null && _field$initialValue !== void 0 ? _field$initialValue : ''));
331
- var [shouldBlur, setShouldBlur] = useState(false);
332
379
  var ref = useRef(null);
333
- var input = useMemo(() => /*#__PURE__*/createElement('input', _objectSpread2(_objectSpread2({}, field.constraint), {}, {
380
+ var input = useMemo(() => /*#__PURE__*/createElement('input', {
334
381
  ref,
335
382
  name: field.name,
336
- defaultValue: field.initialValue,
337
- style: {
338
- display: 'none'
339
- },
383
+ form: field.form,
384
+ defaultValue: field.defaultValue,
385
+ required: field.required,
386
+ minLength: field.minLength,
387
+ maxLength: field.maxLength,
388
+ min: field.min,
389
+ max: field.max,
390
+ step: field.step,
391
+ pattern: field.pattern,
392
+ hidden: true,
340
393
  'aria-hidden': true
341
- })), [field.constraint, field.name, field.initialValue]);
342
- useEffect(() => {
343
- if (!ref.current) {
344
- return;
345
- }
346
-
347
- ref.current.value = value;
348
- ref.current.dispatchEvent(new InputEvent('input', {
349
- bubbles: true
350
- }));
351
- }, [value]);
352
- useEffect(() => {
353
- var _ref$current;
354
-
355
- if (!shouldBlur) {
356
- return;
357
- }
358
-
359
- (_ref$current = ref.current) === null || _ref$current === void 0 ? void 0 : _ref$current.dispatchEvent(new FocusEvent('focusout', {
360
- bubbles: true
361
- }));
362
- setShouldBlur(false);
363
- }, [shouldBlur]);
394
+ }), [field.name, field.form, field.defaultValue, field.required, field.minLength, field.maxLength, field.min, field.max, field.step, field.pattern]);
364
395
  return [input, {
365
- value,
396
+ 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 : ''),
366
397
  onChange: value => {
367
- setValue(value);
398
+ if (!ref.current) {
399
+ return;
400
+ }
401
+
402
+ ref.current.value = value;
403
+ ref.current.dispatchEvent(new InputEvent('input', {
404
+ bubbles: true
405
+ }));
368
406
  },
369
407
  onBlur: () => {
370
- setShouldBlur(true);
408
+ var _ref$current2;
409
+
410
+ (_ref$current2 = ref.current) === null || _ref$current2 === void 0 ? void 0 : _ref$current2.dispatchEvent(new FocusEvent('focusout', {
411
+ bubbles: true
412
+ }));
371
413
  }
372
414
  }];
373
415
  }
package/package.json CHANGED
@@ -2,7 +2,7 @@
2
2
  "name": "@conform-to/react",
3
3
  "description": "Conform view adapter for react",
4
4
  "license": "MIT",
5
- "version": "0.1.1",
5
+ "version": "0.2.0",
6
6
  "main": "index.js",
7
7
  "module": "module/index.js",
8
8
  "repository": {
@@ -19,7 +19,7 @@
19
19
  "url": "https://github.com/edmundhung/conform/issues"
20
20
  },
21
21
  "dependencies": {
22
- "@conform-to/dom": "0.1.1"
22
+ "@conform-to/dom": "0.2.0"
23
23
  },
24
24
  "peerDependencies": {
25
25
  "react": ">=16.8"