@conform-to/react
Advanced tools
Comparing version 0.7.0-pre.1 to 0.7.0-pre.2
@@ -1,2 +0,2 @@ | ||
import { type FieldConstraint, type FieldElement, type FieldsetConstraint, type Submission, type KeysOf, type ResolveType, getFormEncType, getFormMethod } from '@conform-to/dom'; | ||
import { type FieldConstraint, type FieldElement, type FieldsetConstraint, type Submission, type KeysOf, type ResolveType, getFormEncType, getFormMethod, parseIntent } from '@conform-to/dom'; | ||
import { type FormEvent, type RefObject } from 'react'; | ||
@@ -214,6 +214,3 @@ export type Primitive = null | undefined | string | number | boolean | Date; | ||
export declare function reportSubmission(form: HTMLFormElement, submission: Submission): void; | ||
/** | ||
* Check if the current focus is on a intent button. | ||
*/ | ||
export declare function isFocusedOnIntentButton(form: HTMLFormElement, intent: string): boolean; | ||
export declare function getScope(intent: ReturnType<typeof parseIntent>): string | null; | ||
export {}; |
100
hooks.js
@@ -147,3 +147,4 @@ 'use strict'; | ||
} | ||
var scope = dom.getScope(submission.intent); | ||
var intent = dom.parseIntent(submission.intent); | ||
var scope = getScope(intent); | ||
return scope === null ? submission.error : { | ||
@@ -234,11 +235,26 @@ [scope]: submission.error[scope] | ||
})) !== null && _config$onValidate !== void 0 ? _config$onValidate : dom.parse(formData); | ||
var messages = Object.entries(submission.error).reduce((messages, _ref2) => { | ||
var [, message] = _ref2; | ||
return messages.concat(normalizeError(message)); | ||
}, []); | ||
var shouldValidate = !config.noValidate && !(submitter !== null && submitter !== void 0 && submitter.formNoValidate); | ||
var shouldFallbackToServer = messages.includes(VALIDATION_UNDEFINED); | ||
var hasClientValidation = typeof config.onValidate !== 'undefined'; | ||
var isValid = messages.length === 0; | ||
if (hasClientValidation && (dom.isSubmitting(submission.intent) ? shouldValidate && !isValid : !shouldFallbackToServer)) { | ||
var { | ||
errors: _errors, | ||
shouldServerValidate | ||
} = Object.entries(submission.error).reduce((result, _ref2) => { | ||
var [, error] = _ref2; | ||
for (var message of normalizeError(error)) { | ||
if (message === VALIDATION_UNDEFINED) { | ||
result.shouldServerValidate = true; | ||
} else if (message !== VALIDATION_SKIPPED) { | ||
result.errors.push(message); | ||
} | ||
} | ||
return result; | ||
}, { | ||
errors: [], | ||
shouldServerValidate: false | ||
}); | ||
if ( | ||
// has client validation | ||
typeof config.onValidate !== 'undefined' && | ||
// not necessary to validate on the server | ||
!shouldServerValidate && ( | ||
// client validation failed or non submit intent | ||
!config.noValidate && !(submitter !== null && submitter !== void 0 && submitter.formNoValidate) && _errors.length > 0 || dom.parseIntent(submission.intent) !== null)) { | ||
report(form, submission); | ||
@@ -346,23 +362,19 @@ event.preventDefault(); | ||
} | ||
var command = dom.parseListCommand(event.detail); | ||
if ((command === null || command === void 0 ? void 0 : command.scope) !== configRef.current.name) { | ||
// Ensure the scope of the listener are limited to specific field name | ||
var intent = dom.parseIntent(event.detail); | ||
if ((intent === null || intent === void 0 ? void 0 : intent.type) !== 'list' || (intent === null || intent === void 0 ? void 0 : intent.payload.name) !== configRef.current.name) { | ||
return; | ||
} | ||
setEntries(entries => { | ||
switch (command.type) { | ||
var list = [...entries]; | ||
switch (intent.payload.operation) { | ||
case 'append': | ||
case 'prepend': | ||
case 'replace': | ||
return dom.updateList([...(entries !== null && entries !== void 0 ? entries : [])], _rollupPluginBabelHelpers.objectSpread2(_rollupPluginBabelHelpers.objectSpread2({}, command), {}, { | ||
payload: _rollupPluginBabelHelpers.objectSpread2(_rollupPluginBabelHelpers.objectSpread2({}, command.payload), {}, { | ||
defaultValue: ["".concat(Date.now()), | ||
// @ts-expect-error unknown type as it is sent through network | ||
command.payload.defaultValue] | ||
}) | ||
return dom.updateList(list, _rollupPluginBabelHelpers.objectSpread2(_rollupPluginBabelHelpers.objectSpread2({}, intent.payload), {}, { | ||
defaultValue: [ | ||
// Generate a random key to avoid conflicts | ||
crypto.getRandomValues(new Uint32Array(1))[0].toString(36), intent.payload.defaultValue] | ||
})); | ||
default: | ||
{ | ||
return dom.updateList([...(entries !== null && entries !== void 0 ? entries : [])], command); | ||
} | ||
return dom.updateList(list, intent.payload); | ||
} | ||
@@ -377,17 +389,13 @@ }); | ||
} | ||
switch (command.type) { | ||
switch (intent.payload.operation) { | ||
case 'append': | ||
case 'prepend': | ||
case 'replace': | ||
errorList = dom.updateList(errorList, _rollupPluginBabelHelpers.objectSpread2(_rollupPluginBabelHelpers.objectSpread2({}, command), {}, { | ||
payload: _rollupPluginBabelHelpers.objectSpread2(_rollupPluginBabelHelpers.objectSpread2({}, command.payload), {}, { | ||
defaultValue: undefined | ||
}) | ||
errorList = dom.updateList(errorList, _rollupPluginBabelHelpers.objectSpread2(_rollupPluginBabelHelpers.objectSpread2({}, intent.payload), {}, { | ||
defaultValue: undefined | ||
})); | ||
break; | ||
default: | ||
{ | ||
errorList = dom.updateList(errorList, command); | ||
break; | ||
} | ||
errorList = dom.updateList(errorList, intent.payload); | ||
break; | ||
} | ||
@@ -729,3 +737,4 @@ return Object.assign({}, errorList); | ||
} | ||
var scope = dom.getScope(submission.intent); | ||
var intent = dom.parseIntent(submission.intent); | ||
var scope = getScope(intent); | ||
for (var element of dom.getFormControls(form)) { | ||
@@ -745,17 +754,14 @@ var _elementName = element.name !== FORM_ERROR_ELEMENT_NAME ? element.name : ''; | ||
} | ||
if (dom.isSubmitting(submission.intent) || isFocusedOnIntentButton(form, submission.intent)) { | ||
if (scope) { | ||
dom.focusFormControl(form, scope); | ||
} else { | ||
dom.focusFirstInvalidControl(form); | ||
} | ||
if (!intent) { | ||
dom.focusFirstInvalidControl(form); | ||
} | ||
} | ||
/** | ||
* Check if the current focus is on a intent button. | ||
*/ | ||
function isFocusedOnIntentButton(form, intent) { | ||
var element = document.activeElement; | ||
return dom.isFieldElement(element) && element.type === 'submit' && element.form === form && element.name === dom.INTENT && element.value === intent; | ||
function getScope(intent) { | ||
switch (intent === null || intent === void 0 ? void 0 : intent.type) { | ||
case 'validate': | ||
return intent.payload; | ||
case 'list': | ||
return intent.payload.name; | ||
} | ||
return null; | ||
} | ||
@@ -766,3 +772,3 @@ | ||
exports.VALIDATION_UNDEFINED = VALIDATION_UNDEFINED; | ||
exports.isFocusedOnIntentButton = isFocusedOnIntentButton; | ||
exports.getScope = getScope; | ||
exports.reportSubmission = reportSubmission; | ||
@@ -769,0 +775,0 @@ exports.useFieldList = useFieldList; |
@@ -6,3 +6,3 @@ { | ||
"license": "MIT", | ||
"version": "0.7.0-pre.1", | ||
"version": "0.7.0-pre.2", | ||
"main": "index.js", | ||
@@ -34,3 +34,3 @@ "module": "index.mjs", | ||
"dependencies": { | ||
"@conform-to/dom": "0.7.0-pre.1" | ||
"@conform-to/dom": "0.7.0-pre.2" | ||
}, | ||
@@ -37,0 +37,0 @@ "peerDependencies": { |
@@ -510,3 +510,3 @@ # @conform-to/react | ||
It provides serveral helpers to configure an intent button for [modifying a list](/docs/commands.md#modifying-a-list). | ||
It provides serveral helpers to configure an intent button for [modifying a list](/docs/intent-button.md#modifying-a-list). | ||
@@ -544,3 +544,3 @@ ```tsx | ||
It returns the properties required to configure an intent button for [validation](/docs/commands.md#validation). | ||
It returns the properties required to configure an intent button for [validation](/docs/intent-button.md#validation). | ||
@@ -567,3 +567,3 @@ ```tsx | ||
It lets you [trigger an intent](/docs/commands.md#triggering-an-intent) without requiring users to click on a button. It supports both [list](#list) and [validate](#validate) intent. | ||
It lets you [trigger an intent](/docs/intent-button.md#triggering-an-intent) without requiring users to click on a button. It supports both [list](#list) and [validate](#validate) intent. | ||
@@ -570,0 +570,0 @@ ```tsx |
Sorry, the diff of this file is not supported yet
2089
98615
+ Added@conform-to/dom@0.7.0-pre.2(transitive)
- Removed@conform-to/dom@0.7.0-pre.1(transitive)
Updated@conform-to/dom@0.7.0-pre.2