@conform-to/dom 1.0.0 → 1.0.1

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 CHANGED
@@ -8,25 +8,30 @@
8
8
  ╚══════╝ ╚═════╝ ╚═╝ ╚══╝ ╚═╝ ╚═════╝ ╚═╝ ╚═╝ ╚═╝ ╚═╝
9
9
 
10
10
 
11
- Version 1.0.0-rc.1 / License MIT / Copyright (c) 2024 Edmund Hung
11
+ Version 1.0.1 / License MIT / Copyright (c) 2024 Edmund Hung
12
12
 
13
13
  A type-safe form validation library utilizing web fundamentals to progressively enhance HTML Forms with full support for server frameworks like Remix and Next.js.
14
14
 
15
- > Getting Started
15
+ # Getting Started
16
16
 
17
17
  Check out the overview and tutorial at our website https://conform.guide
18
18
 
19
- > Documentation
19
+ # Features
20
20
 
21
- The documentation is divided into several sections:
21
+ - Progressive enhancement first APIs
22
+ - Type-safe field inference
23
+ - Fine-grained subscription
24
+ - Built-in accessibility helpers
25
+ - Automatic type coercion with Zod
22
26
 
23
- * Overview: https://conform.guide/overview
24
- * Examples: 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
27
+ # Documentation
29
28
 
30
- > Support
29
+ - Validation: https://conform.guide/validation
30
+ - Nested object and Array: https://conform.guide/complex-structures
31
+ - UI Integrations: https://conform.guide/integration/ui-libraries
32
+ - Intent button: https://conform.guide/intent-button
33
+ - Accessibility Guide: https://conform.guide/accessibility
34
+
35
+ # Support
31
36
 
32
37
  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
@@ -4,10 +4,10 @@ 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;
6
6
  } ? T[K] : undefined;
7
- export type DefaultValue<Schema> = Schema extends string | number | boolean | Date | null | undefined ? Schema | string | null | undefined : Schema extends File ? null | undefined : Schema extends Array<infer Item> ? Array<DefaultValue<Item>> | null | undefined : Schema extends Record<string, any> ? {
7
+ export type DefaultValue<Schema> = Schema extends string | number | boolean | Date | bigint | null | undefined ? Schema | string | null | undefined : Schema extends File ? null | undefined : Schema extends Array<infer Item> ? Array<DefaultValue<Item>> | null | undefined : Schema extends Record<string, any> ? {
8
8
  [Key in UnionKeyof<Schema>]?: DefaultValue<UnionKeyType<Schema, Key>>;
9
9
  } | null | undefined : string | null | undefined;
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> ? {
10
+ export type FormValue<Schema> = Schema extends string | number | boolean | Date | bigint | null | undefined ? string | undefined : Schema extends File ? File | undefined : Schema extends Array<infer Item> ? string | Array<FormValue<Item>> | undefined : Schema extends Record<string, any> ? {
11
11
  [Key in UnionKeyof<Schema>]?: FormValue<UnionKeyType<Schema, Key>>;
12
12
  } | undefined : unknown;
13
13
  declare const error: unique symbol;
package/form.js CHANGED
@@ -52,7 +52,7 @@ function handleIntent(meta, intent, initialized) {
52
52
  if (typeof intent.payload.value !== 'undefined') {
53
53
  var _intent$payload$name;
54
54
  var _name = (_intent$payload$name = intent.payload.name) !== null && _intent$payload$name !== void 0 ? _intent$payload$name : '';
55
- var value = intent.payload.value;
55
+ var value = submission.serialize(intent.payload.value);
56
56
  updateValue(meta, _name, value);
57
57
  }
58
58
  break;
@@ -101,7 +101,7 @@ function createStateProxy(fn) {
101
101
  });
102
102
  }
103
103
  function createValueProxy(value) {
104
- var val = formdata.simplify(value);
104
+ var val = formdata.normalize(value);
105
105
  return createStateProxy((name, proxy) => {
106
106
  if (name === '') {
107
107
  return val;
@@ -210,9 +210,7 @@ function createFormContext(options) {
210
210
  var meta = createFormMeta(options);
211
211
  var state = createFormState(meta);
212
212
  function getFormElement() {
213
- var element = document.forms.namedItem(latestOptions.formId);
214
- util.invariant(element !== null, "Form#".concat(latestOptions.formId, " does not exist"));
215
- return element;
213
+ return document.forms.namedItem(latestOptions.formId);
216
214
  }
217
215
  function createFormState(next) {
218
216
  var prev = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : next;
@@ -316,7 +314,7 @@ function createFormContext(options) {
316
314
  function resolveTarget(event) {
317
315
  var form = getFormElement();
318
316
  var element = event.target;
319
- if (!dom.isFieldElement(element) || element.form !== form || element.name === '') {
317
+ if (!form || !dom.isFieldElement(element) || element.form !== form || element.name === '') {
320
318
  return null;
321
319
  }
322
320
  return element;
@@ -372,7 +370,7 @@ function createFormContext(options) {
372
370
  var _result$error, _result$state$validat, _result$state;
373
371
  var formElement = getFormElement();
374
372
  if (!result.initialValue) {
375
- formElement.reset();
373
+ formElement === null || formElement === void 0 || formElement.reset();
376
374
  return;
377
375
  }
378
376
  var error = Object.entries((_result$error = result.error) !== null && _result$error !== void 0 ? _result$error : {}).reduce((result, _ref4) => {
@@ -393,7 +391,7 @@ function createFormContext(options) {
393
391
  handleIntent(update, result.intent, true);
394
392
  }
395
393
  updateFormMeta(update);
396
- if (result.status === 'error') {
394
+ if (formElement && result.status === 'error') {
397
395
  for (var element of formElement.elements) {
398
396
  if (dom.isFieldElement(element) && error[element.name]) {
399
397
  element.focus();
@@ -409,7 +407,8 @@ function createFormContext(options) {
409
407
  // Merge new options with the latest options
410
408
  Object.assign(latestOptions, options);
411
409
  if (latestOptions.formId !== currentFormId) {
412
- getFormElement().reset();
410
+ var _getFormElement;
411
+ (_getFormElement = getFormElement()) === null || _getFormElement === void 0 || _getFormElement.reset();
413
412
  } else if (options.lastResult && options.lastResult !== currentResult) {
414
413
  report(options.lastResult);
415
414
  }
package/form.mjs CHANGED
@@ -1,5 +1,5 @@
1
1
  import { objectSpread2 as _objectSpread2 } from './_virtual/_rollupPluginBabelHelpers.mjs';
2
- import { flatten, formatPaths, getPaths, getValue, setValue, isPlainObject, simplify, getFormData, isPrefix } from './formdata.mjs';
2
+ import { flatten, formatPaths, getPaths, getValue, setValue, isPlainObject, normalize, getFormData, isPrefix } from './formdata.mjs';
3
3
  import { getFormAction, getFormEncType, getFormMethod, isFieldElement, requestSubmit } from './dom.mjs';
4
4
  import { generateId, clone, invariant } from './util.mjs';
5
5
  import { serialize, setListState, setListValue, setState, getSubmissionContext, INTENT, serializeIntent, STATE } from './submission.mjs';
@@ -48,7 +48,7 @@ function handleIntent(meta, intent, initialized) {
48
48
  if (typeof intent.payload.value !== 'undefined') {
49
49
  var _intent$payload$name;
50
50
  var _name = (_intent$payload$name = intent.payload.name) !== null && _intent$payload$name !== void 0 ? _intent$payload$name : '';
51
- var value = intent.payload.value;
51
+ var value = serialize(intent.payload.value);
52
52
  updateValue(meta, _name, value);
53
53
  }
54
54
  break;
@@ -97,7 +97,7 @@ function createStateProxy(fn) {
97
97
  });
98
98
  }
99
99
  function createValueProxy(value) {
100
- var val = simplify(value);
100
+ var val = normalize(value);
101
101
  return createStateProxy((name, proxy) => {
102
102
  if (name === '') {
103
103
  return val;
@@ -206,9 +206,7 @@ function createFormContext(options) {
206
206
  var meta = createFormMeta(options);
207
207
  var state = createFormState(meta);
208
208
  function getFormElement() {
209
- var element = document.forms.namedItem(latestOptions.formId);
210
- invariant(element !== null, "Form#".concat(latestOptions.formId, " does not exist"));
211
- return element;
209
+ return document.forms.namedItem(latestOptions.formId);
212
210
  }
213
211
  function createFormState(next) {
214
212
  var prev = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : next;
@@ -312,7 +310,7 @@ function createFormContext(options) {
312
310
  function resolveTarget(event) {
313
311
  var form = getFormElement();
314
312
  var element = event.target;
315
- if (!isFieldElement(element) || element.form !== form || element.name === '') {
313
+ if (!form || !isFieldElement(element) || element.form !== form || element.name === '') {
316
314
  return null;
317
315
  }
318
316
  return element;
@@ -368,7 +366,7 @@ function createFormContext(options) {
368
366
  var _result$error, _result$state$validat, _result$state;
369
367
  var formElement = getFormElement();
370
368
  if (!result.initialValue) {
371
- formElement.reset();
369
+ formElement === null || formElement === void 0 || formElement.reset();
372
370
  return;
373
371
  }
374
372
  var error = Object.entries((_result$error = result.error) !== null && _result$error !== void 0 ? _result$error : {}).reduce((result, _ref4) => {
@@ -389,7 +387,7 @@ function createFormContext(options) {
389
387
  handleIntent(update, result.intent, true);
390
388
  }
391
389
  updateFormMeta(update);
392
- if (result.status === 'error') {
390
+ if (formElement && result.status === 'error') {
393
391
  for (var element of formElement.elements) {
394
392
  if (isFieldElement(element) && error[element.name]) {
395
393
  element.focus();
@@ -405,7 +403,8 @@ function createFormContext(options) {
405
403
  // Merge new options with the latest options
406
404
  Object.assign(latestOptions, options);
407
405
  if (latestOptions.formId !== currentFormId) {
408
- getFormElement().reset();
406
+ var _getFormElement;
407
+ (_getFormElement = getFormElement()) === null || _getFormElement === void 0 || _getFormElement.reset();
409
408
  } else if (options.lastResult && options.lastResult !== currentResult) {
410
409
  report(options.lastResult);
411
410
  }
package/formdata.d.ts CHANGED
@@ -43,11 +43,11 @@ export declare function isPlainObject(obj: unknown): obj is Record<string | numb
43
43
  */
44
44
  export declare function isFile(obj: unknown): obj is File;
45
45
  /**
46
- * Simplify value by removing empty object or array and null values
46
+ * Normalize value by removing empty object or array, empty string and null values
47
47
  */
48
- export declare function simplify<Type extends Record<string, unknown>>(value: Type | null): Type | undefined;
49
- export declare function simplify<Type extends Array<unknown>>(value: Type | null): Type | undefined;
50
- export declare function simplify(value: unknown): unknown | undefined;
48
+ export declare function normalize<Type extends Record<string, unknown>>(value: Type | null): Type | null | undefined;
49
+ export declare function normalize<Type extends Array<unknown>>(value: Type | null): Type | null | undefined;
50
+ export declare function normalize(value: unknown): unknown | undefined;
51
51
  /**
52
52
  * Flatten a tree into a dictionary
53
53
  */
package/formdata.js CHANGED
@@ -132,13 +132,13 @@ function isFile(obj) {
132
132
  }
133
133
 
134
134
  /**
135
- * Simplify value by removing empty object or array and null values
135
+ * Normalize value by removing empty object or array, empty string and null values
136
136
  */
137
137
 
138
- function simplify(value) {
138
+ function normalize(value) {
139
139
  if (isPlainObject(value)) {
140
140
  var obj = Object.keys(value).sort().reduce((result, key) => {
141
- var data = simplify(value[key]);
141
+ var data = normalize(value[key]);
142
142
  if (typeof data !== 'undefined') {
143
143
  result[key] = data;
144
144
  }
@@ -153,7 +153,7 @@ function simplify(value) {
153
153
  if (value.length === 0) {
154
154
  return undefined;
155
155
  }
156
- return value.map(simplify);
156
+ return value.map(normalize);
157
157
  }
158
158
  if (typeof value === 'string' && value === '' || value === null || isFile(value)) {
159
159
  return;
@@ -169,7 +169,7 @@ function flatten(data, options) {
169
169
  var result = {};
170
170
  var resolve = (_options$resolve = options === null || options === void 0 ? void 0 : options.resolve) !== null && _options$resolve !== void 0 ? _options$resolve : data => data;
171
171
  function setResult(data, name) {
172
- var value = simplify(resolve(data));
172
+ var value = normalize(resolve(data));
173
173
  if (typeof value !== 'undefined') {
174
174
  result[name] = value;
175
175
  }
@@ -221,5 +221,5 @@ exports.getValue = getValue;
221
221
  exports.isFile = isFile;
222
222
  exports.isPlainObject = isPlainObject;
223
223
  exports.isPrefix = isPrefix;
224
+ exports.normalize = normalize;
224
225
  exports.setValue = setValue;
225
- exports.simplify = simplify;
package/formdata.mjs CHANGED
@@ -128,13 +128,13 @@ function isFile(obj) {
128
128
  }
129
129
 
130
130
  /**
131
- * Simplify value by removing empty object or array and null values
131
+ * Normalize value by removing empty object or array, empty string and null values
132
132
  */
133
133
 
134
- function simplify(value) {
134
+ function normalize(value) {
135
135
  if (isPlainObject(value)) {
136
136
  var obj = Object.keys(value).sort().reduce((result, key) => {
137
- var data = simplify(value[key]);
137
+ var data = normalize(value[key]);
138
138
  if (typeof data !== 'undefined') {
139
139
  result[key] = data;
140
140
  }
@@ -149,7 +149,7 @@ function simplify(value) {
149
149
  if (value.length === 0) {
150
150
  return undefined;
151
151
  }
152
- return value.map(simplify);
152
+ return value.map(normalize);
153
153
  }
154
154
  if (typeof value === 'string' && value === '' || value === null || isFile(value)) {
155
155
  return;
@@ -165,7 +165,7 @@ function flatten(data, options) {
165
165
  var result = {};
166
166
  var resolve = (_options$resolve = options === null || options === void 0 ? void 0 : options.resolve) !== null && _options$resolve !== void 0 ? _options$resolve : data => data;
167
167
  function setResult(data, name) {
168
- var value = simplify(resolve(data));
168
+ var value = normalize(resolve(data));
169
169
  if (typeof value !== 'undefined') {
170
170
  result[name] = value;
171
171
  }
@@ -209,4 +209,4 @@ function flatten(data, options) {
209
209
  return result;
210
210
  }
211
211
 
212
- export { flatten, formatPaths, getFormData, getPaths, getValue, isFile, isPlainObject, isPrefix, setValue, simplify };
212
+ export { flatten, formatPaths, getFormData, getPaths, getValue, isFile, isPlainObject, isPrefix, normalize, setValue };
package/package.json CHANGED
@@ -3,7 +3,7 @@
3
3
  "description": "A set of opinionated helpers built on top of the Constraint Validation API",
4
4
  "homepage": "https://conform.guide",
5
5
  "license": "MIT",
6
- "version": "1.0.0",
6
+ "version": "1.0.1",
7
7
  "main": "index.js",
8
8
  "module": "index.mjs",
9
9
  "types": "index.d.ts",
package/submission.js CHANGED
@@ -62,9 +62,9 @@ function parse(payload, options) {
62
62
  {
63
63
  var {
64
64
  name,
65
- value: _value,
66
65
  validated
67
66
  } = intent.payload;
67
+ var _value = serialize(intent.payload.value);
68
68
  if (typeof _value !== 'undefined') {
69
69
  if (name) {
70
70
  formdata.setValue(context.payload, name, () => _value);
@@ -161,7 +161,7 @@ function createSubmission(context) {
161
161
  };
162
162
  }
163
163
  function replySubmission(context) {
164
- var _context$intent, _context$error, _simplify;
164
+ var _context$intent, _options$formErrors, _normalize;
165
165
  var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
166
166
  switch ((_context$intent = context.intent) === null || _context$intent === void 0 ? void 0 : _context$intent.type) {
167
167
  case 'reset':
@@ -188,21 +188,21 @@ function replySubmission(context) {
188
188
  }
189
189
  }
190
190
  }
191
- var submissionError = Object.entries((_context$error = context.error) !== null && _context$error !== void 0 ? _context$error : {}).reduce((result, _ref) => {
191
+ var submissionError = context.error ? Object.entries(context.error).reduce((result, _ref) => {
192
192
  var [name, error] = _ref;
193
193
  if (context.state.validated[name]) {
194
194
  result[name] = error;
195
195
  }
196
196
  return result;
197
- }, {});
198
- var extraError = 'formErrors' in options || 'fieldErrors' in options ? formdata.simplify(_rollupPluginBabelHelpers.objectSpread2({
199
- '': options.formErrors
197
+ }, {}) : undefined;
198
+ var extraError = 'formErrors' in options || 'fieldErrors' in options ? formdata.normalize(_rollupPluginBabelHelpers.objectSpread2({
199
+ '': (_options$formErrors = options.formErrors) !== null && _options$formErrors !== void 0 ? _options$formErrors : null
200
200
  }, options.fieldErrors)) : null;
201
- var error = formdata.simplify(_rollupPluginBabelHelpers.objectSpread2(_rollupPluginBabelHelpers.objectSpread2({}, submissionError), extraError));
201
+ var error = submissionError || extraError ? _rollupPluginBabelHelpers.objectSpread2(_rollupPluginBabelHelpers.objectSpread2({}, submissionError), extraError) : undefined;
202
202
  return {
203
203
  status: context.intent ? undefined : error ? 'error' : 'success',
204
204
  intent: context.intent ? context.intent : undefined,
205
- initialValue: (_simplify = formdata.simplify(context.payload)) !== null && _simplify !== void 0 ? _simplify : {},
205
+ initialValue: (_normalize = formdata.normalize(context.payload)) !== null && _normalize !== void 0 ? _normalize : {},
206
206
  error,
207
207
  state: context.state
208
208
  };
package/submission.mjs CHANGED
@@ -1,5 +1,5 @@
1
1
  import { objectSpread2 as _objectSpread2 } from './_virtual/_rollupPluginBabelHelpers.mjs';
2
- import { setValue, isPlainObject, flatten, getValue, simplify, isPrefix } from './formdata.mjs';
2
+ import { setValue, isPlainObject, flatten, getValue, normalize, isPrefix } from './formdata.mjs';
3
3
  import { invariant } from './util.mjs';
4
4
 
5
5
  /**
@@ -58,9 +58,9 @@ function parse(payload, options) {
58
58
  {
59
59
  var {
60
60
  name,
61
- value: _value,
62
61
  validated
63
62
  } = intent.payload;
63
+ var _value = serialize(intent.payload.value);
64
64
  if (typeof _value !== 'undefined') {
65
65
  if (name) {
66
66
  setValue(context.payload, name, () => _value);
@@ -157,7 +157,7 @@ function createSubmission(context) {
157
157
  };
158
158
  }
159
159
  function replySubmission(context) {
160
- var _context$intent, _context$error, _simplify;
160
+ var _context$intent, _options$formErrors, _normalize;
161
161
  var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
162
162
  switch ((_context$intent = context.intent) === null || _context$intent === void 0 ? void 0 : _context$intent.type) {
163
163
  case 'reset':
@@ -184,21 +184,21 @@ function replySubmission(context) {
184
184
  }
185
185
  }
186
186
  }
187
- var submissionError = Object.entries((_context$error = context.error) !== null && _context$error !== void 0 ? _context$error : {}).reduce((result, _ref) => {
187
+ var submissionError = context.error ? Object.entries(context.error).reduce((result, _ref) => {
188
188
  var [name, error] = _ref;
189
189
  if (context.state.validated[name]) {
190
190
  result[name] = error;
191
191
  }
192
192
  return result;
193
- }, {});
194
- var extraError = 'formErrors' in options || 'fieldErrors' in options ? simplify(_objectSpread2({
195
- '': options.formErrors
193
+ }, {}) : undefined;
194
+ var extraError = 'formErrors' in options || 'fieldErrors' in options ? normalize(_objectSpread2({
195
+ '': (_options$formErrors = options.formErrors) !== null && _options$formErrors !== void 0 ? _options$formErrors : null
196
196
  }, options.fieldErrors)) : null;
197
- var error = simplify(_objectSpread2(_objectSpread2({}, submissionError), extraError));
197
+ var error = submissionError || extraError ? _objectSpread2(_objectSpread2({}, submissionError), extraError) : undefined;
198
198
  return {
199
199
  status: context.intent ? undefined : error ? 'error' : 'success',
200
200
  intent: context.intent ? context.intent : undefined,
201
- initialValue: (_simplify = simplify(context.payload)) !== null && _simplify !== void 0 ? _simplify : {},
201
+ initialValue: (_normalize = normalize(context.payload)) !== null && _normalize !== void 0 ? _normalize : {},
202
202
  error,
203
203
  state: context.state
204
204
  };