@samline/forms 1.0.0 → 1.0.3

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.
Files changed (38) hide show
  1. package/README.md +40 -3
  2. package/dist/browser/global.global.js +4 -0
  3. package/dist/browser/global.global.js.map +1 -1
  4. package/dist/{chunk-KKQD25KI.js → chunk-PCKGH2WA.js} +2 -2
  5. package/dist/{chunk-KIJEFIHP.js → chunk-WM2CL7IO.js} +5 -1
  6. package/dist/chunk-WM2CL7IO.js.map +1 -0
  7. package/dist/core/index.d.cts +2 -2
  8. package/dist/core/index.d.ts +2 -2
  9. package/dist/index.cjs +4 -0
  10. package/dist/index.cjs.map +1 -1
  11. package/dist/index.d.cts +1 -1
  12. package/dist/index.d.ts +1 -1
  13. package/dist/index.js +2 -2
  14. package/dist/react/index.cjs +4 -0
  15. package/dist/react/index.cjs.map +1 -1
  16. package/dist/react/index.d.cts +1 -1
  17. package/dist/react/index.d.ts +1 -1
  18. package/dist/react/index.js +1 -1
  19. package/dist/svelte/index.cjs +4 -0
  20. package/dist/svelte/index.cjs.map +1 -1
  21. package/dist/svelte/index.d.cts +1 -1
  22. package/dist/svelte/index.d.ts +1 -1
  23. package/dist/svelte/index.js +1 -1
  24. package/dist/{types-C0_1rYlm.d.cts → types-jYB7Wp7C.d.cts} +1 -0
  25. package/dist/{types-C0_1rYlm.d.ts → types-jYB7Wp7C.d.ts} +1 -0
  26. package/dist/vanilla/index.cjs +4 -0
  27. package/dist/vanilla/index.cjs.map +1 -1
  28. package/dist/vanilla/index.d.cts +1 -1
  29. package/dist/vanilla/index.d.ts +1 -1
  30. package/dist/vanilla/index.js +2 -2
  31. package/dist/vue/index.cjs +4 -0
  32. package/dist/vue/index.cjs.map +1 -1
  33. package/dist/vue/index.d.cts +1 -1
  34. package/dist/vue/index.d.ts +1 -1
  35. package/dist/vue/index.js +1 -1
  36. package/package.json +1 -1
  37. package/dist/chunk-KIJEFIHP.js.map +0 -1
  38. /package/dist/{chunk-KKQD25KI.js.map → chunk-PCKGH2WA.js.map} +0 -0
package/README.md CHANGED
@@ -1,4 +1,4 @@
1
- # @samline/forms
1
+ # Forms
2
2
 
3
3
  Form controller for native HTML forms, React, Vue, Svelte, and direct browser usage.
4
4
 
@@ -37,7 +37,7 @@ bun add @samline/forms
37
37
  Use the browser build when you do not have a bundler and need to run the package directly in HTML.
38
38
 
39
39
  ```html
40
- <script src="https://unpkg.com/@samline/forms@1.0.0/dist/browser/global.global.js"></script>
40
+ <script src="https://unpkg.com/@samline/forms@1.0.3/dist/browser/global.global.js"></script>
41
41
  ```
42
42
 
43
43
  Pin the version in production.
@@ -49,7 +49,7 @@ The browser build exposes `window.forms`.
49
49
  <input name="email" type="email" />
50
50
  </form>
51
51
 
52
- <script src="https://unpkg.com/@samline/forms@1.0.0/dist/browser/global.global.js"></script>
52
+ <script src="https://unpkg.com/@samline/forms@1.0.3/dist/browser/global.global.js"></script>
53
53
  <script>
54
54
  const contactForm = window.forms.form('contact-form')
55
55
  contactForm.validate()
@@ -121,6 +121,13 @@ Creates a controller from:
121
121
  - `autoSubmit(options?)`
122
122
  - `disableAutoSubmit()`
123
123
 
124
+ `onSubmit` accepts an optional second argument named `preventDefault`.
125
+
126
+ - `onSubmit(callback)` is equivalent to `onSubmit(callback, true)`
127
+ - with `true`, valid submissions are intercepted, which is the right choice for `fetch` or AJAX flows
128
+ - with `false`, valid submissions continue with the browser's native form submit behavior
129
+ - invalid submissions are still prevented, even when you pass `false`
130
+
124
131
  ### Field observation
125
132
 
126
133
  - `watch(field, callback)`
@@ -142,6 +149,8 @@ Creates a controller from:
142
149
  - `setErrors(fields)`
143
150
  - `clearErrors(fields?)`
144
151
 
152
+ Manual errors created with `setErrors()` are cleared per field by default as soon as that field changes, including updates triggered through `setValue()`. Pass `clearManualErrorsOnChange: false` to keep manual errors until you clear them explicitly.
153
+
145
154
  ### Form lifecycle and state
146
155
 
147
156
  - `getData()`
@@ -160,6 +169,18 @@ Built-in rules supported through `validators`:
160
169
  - `pattern`
161
170
  - `validate` for custom callbacks
162
171
 
172
+ Controller options also include:
173
+
174
+ - `autoValidate` to validate on initialization and subsequent field changes
175
+ - `clearErrorsOnSubmit` to reset manual errors before submit validation runs
176
+ - `clearManualErrorsOnChange` to clear only the changed field's manual error before the normal validation flow continues
177
+
178
+ ```ts
179
+ const profileForm = form('profile-form', {
180
+ clearManualErrorsOnChange: false
181
+ })
182
+ ```
183
+
163
184
  ## Examples
164
185
 
165
186
  ### Bind by id
@@ -219,6 +240,22 @@ profileForm.onSubmit(async (_element, _data, formData) => {
219
240
  })
220
241
  ```
221
242
 
243
+ This uses the default `preventDefault = true`, so the package intercepts the valid submit and lets you handle the request yourself.
244
+
245
+ ### Submit with native form behavior
246
+
247
+ ```ts
248
+ const profileForm = form('profile-form')
249
+
250
+ profileForm.onSubmit(() => {
251
+ console.log('validation passed')
252
+ }, false)
253
+ ```
254
+
255
+ Use `false` when the form should continue with its normal HTML submission after validation succeeds, for example in server-rendered applications such as Laravel with Blade.
256
+
257
+ If validation fails, the package still prevents the submit.
258
+
222
259
  ### Prefill from the URL
223
260
 
224
261
  ```ts
@@ -263,6 +263,7 @@ var SamlineForms = (() => {
263
263
  };
264
264
  var DEFAULT_OPTIONS = {
265
265
  autoValidate: true,
266
+ clearManualErrorsOnChange: true,
266
267
  clearErrorsOnSubmit: true
267
268
  };
268
269
  var mergeErrors = (left, right) => {
@@ -410,6 +411,9 @@ var SamlineForms = (() => {
410
411
  return;
411
412
  }
412
413
  clearFieldCache();
414
+ if (normalizedOptions.clearManualErrorsOnChange) {
415
+ delete manualErrors[name];
416
+ }
413
417
  syncVisualState([name]);
414
418
  if (isValidated && validators[name]) {
415
419
  validateNames([name]);
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/browser/global.ts","../../src/core/serialize.ts","../../src/core/state.ts","../../src/core/validation.ts","../../src/internal/dom.ts","../../src/internal/controller.ts","../../src/vanilla/index.ts"],"sourcesContent":["import { parseFormData, validateValues } from '../core'\nimport { createFormController, form } from '../vanilla'\n\nconst browserApi = {\n createFormController,\n form,\n parseFormData,\n validateValues\n}\n\ndeclare global {\n interface Window {\n forms: typeof browserApi\n }\n}\n\nif (typeof globalThis !== 'undefined') {\n ;(globalThis as typeof globalThis & { forms: typeof browserApi }).forms =\n browserApi\n}\n\nexport default browserApi","import type { SerializedFormResult, SerializedFormValue } from './types'\n\nconst isEmptyFile = (value: FormDataEntryValue): value is File =>\n value instanceof File && value.size === 0 && value.name === ''\n\nconst appendValue = (\n data: Record<string, SerializedFormValue>,\n key: string,\n value: FormDataEntryValue\n) => {\n const current = data[key]\n\n if (current === undefined) {\n data[key] = value\n return\n }\n\n if (Array.isArray(current)) {\n current.push(value)\n return\n }\n\n data[key] = [current, value]\n}\n\nexport const parseFormData = (\n formElement: HTMLFormElement\n): SerializedFormResult => {\n const rawFormData = new FormData(formElement)\n const formData = new FormData()\n const data: Record<string, SerializedFormValue> = {}\n\n rawFormData.forEach((value, key) => {\n if (isEmptyFile(value)) {\n return\n }\n\n formData.append(key, value)\n appendValue(data, key, value)\n })\n\n return { data, formData }\n}","import type { FormStateSnapshot } from './types'\n\nexport const createEmptyFormState = (): FormStateSnapshot => ({\n values: {},\n errors: {},\n filledFields: [],\n isValid: true,\n isValidated: false,\n autoSubmit: false,\n submitCount: 0\n})","import type {\n FieldValidationContext,\n FieldValidationRules,\n FormErrors,\n FormFieldValue,\n FormValues,\n RuleConfig,\n ValidationResult,\n ValidationSchema\n} from './types'\n\nconst resolveRule = <T>(rule: RuleConfig<T> | undefined) => {\n if (rule === undefined) {\n return { value: undefined as T | undefined, message: undefined as string | undefined }\n }\n\n if (typeof rule === 'object' && rule !== null && 'value' in rule) {\n return { value: rule.value, message: rule.message }\n }\n\n return { value: rule, message: undefined as string | undefined }\n}\n\nconst hasValue = (value: FormFieldValue) => {\n if (Array.isArray(value)) {\n return value.length > 0\n }\n\n return typeof value === 'string' ? value.trim().length > 0 : value !== undefined\n}\n\nconst getValueLength = (value: FormFieldValue) => {\n if (Array.isArray(value)) {\n return value.length\n }\n\n if (typeof value === 'string') {\n return value.length\n }\n\n return 0\n}\n\nconst toPatternTarget = (value: FormFieldValue) => {\n if (typeof value === 'string') {\n return value\n }\n\n if (Array.isArray(value)) {\n return value\n .map(entry => (typeof entry === 'string' ? entry : entry.name))\n .join(',')\n }\n\n return ''\n}\n\nexport const validateFieldValue = (\n field: string,\n value: FormFieldValue,\n rules: FieldValidationRules,\n values: FormValues\n) => {\n const errors: string[] = []\n const context: FieldValidationContext = { field, value, values }\n const required = resolveRule(rules.required)\n const minLength = resolveRule(rules.minLength)\n const maxLength = resolveRule(rules.maxLength)\n const pattern = resolveRule(rules.pattern)\n\n if (required.value && !hasValue(value)) {\n errors.push(required.message ?? 'This field is required.')\n }\n\n if (minLength.value !== undefined && getValueLength(value) < minLength.value) {\n errors.push(minLength.message ?? `Minimum length is ${minLength.value}.`)\n }\n\n if (maxLength.value !== undefined && getValueLength(value) > maxLength.value) {\n errors.push(maxLength.message ?? `Maximum length is ${maxLength.value}.`)\n }\n\n if (pattern.value && hasValue(value) && !pattern.value.test(toPatternTarget(value))) {\n errors.push(pattern.message ?? 'Value does not match the required pattern.')\n }\n\n const customValidators = rules.validate\n ? Array.isArray(rules.validate)\n ? rules.validate\n : [rules.validate]\n : []\n\n for (const validator of customValidators) {\n const result = validator(context)\n\n if (typeof result === 'string' && result.length > 0) {\n errors.push(result)\n }\n\n if (result === false) {\n errors.push('Validation failed.')\n }\n }\n\n return errors\n}\n\nexport const validateValues = (\n values: FormValues,\n schema: ValidationSchema\n): ValidationResult => {\n const errors: FormErrors = {}\n\n for (const [field, rules] of Object.entries(schema)) {\n const messages = validateFieldValue(field, values[field], rules, values)\n if (messages.length > 0) {\n errors[field] = messages\n }\n }\n\n return {\n isValid: Object.keys(errors).length === 0,\n errors\n }\n}","import type { FormFieldElement, FormFieldValue, FormTarget } from '../core/types'\n\nconst isFormFieldElement = (value: Element): value is FormFieldElement =>\n value instanceof HTMLInputElement ||\n value instanceof HTMLSelectElement ||\n value instanceof HTMLTextAreaElement\n\nexport const resolveFormElement = (target: FormTarget): HTMLFormElement | null => {\n if (!target) {\n return null\n }\n\n if (target instanceof HTMLFormElement) {\n return target\n }\n\n if (typeof target === 'string') {\n const element = document.getElementById(target)\n return element instanceof HTMLFormElement ? element : null\n }\n\n if ('current' in target) {\n return target.current instanceof HTMLFormElement ? target.current : null\n }\n\n return null\n}\n\nexport const getNamedFields = (form: HTMLFormElement): FormFieldElement[] =>\n Array.from(form.querySelectorAll('input[name], select[name], textarea[name]')).filter(\n isFormFieldElement\n )\n\nexport const queryNamedFields = (\n form: HTMLFormElement,\n name: string\n): FormFieldElement[] => getNamedFields(form).filter(field => field.name === name)\n\nexport const isFieldFilled = (field: FormFieldElement) => {\n if (field instanceof HTMLInputElement) {\n if (field.type === 'checkbox' || field.type === 'radio') {\n return field.checked\n }\n\n if (field.type === 'file') {\n return Boolean(field.files && field.files.length > 0)\n }\n\n return field.value.trim() !== ''\n }\n\n return field.value !== ''\n}\n\nexport const applyBooleanAttribute = (\n field: FormFieldElement,\n attribute: string,\n enabled: boolean\n) => {\n if (enabled) {\n field.setAttribute(attribute, '')\n return\n }\n\n field.removeAttribute(attribute)\n}\n\nexport const readFieldValue = (\n fields: FormFieldElement[]\n): FormFieldValue => {\n if (fields.length === 0) {\n return undefined\n }\n\n const firstField = fields[0]\n if (!firstField) {\n return undefined\n }\n\n if (firstField instanceof HTMLSelectElement || firstField instanceof HTMLTextAreaElement) {\n return firstField.value\n }\n\n if (firstField.type === 'radio') {\n const checked = fields.find(\n field => field instanceof HTMLInputElement && field.checked\n ) as HTMLInputElement | undefined\n\n return checked?.value ?? ''\n }\n\n if (firstField.type === 'checkbox') {\n const values = fields\n .filter(field => field instanceof HTMLInputElement && field.checked)\n .map(field => (field as HTMLInputElement).value)\n\n return values.length > 1 ? values : (values[0] ?? '')\n }\n\n if (firstField.type === 'file') {\n return firstField.files ? Array.from(firstField.files) : []\n }\n\n return firstField.value\n}\n\nexport const writeFieldValue = (\n fields: FormFieldElement[],\n value: unknown\n) => {\n const normalizedArray = Array.isArray(value)\n ? value.map(item => String(item))\n : null\n const normalizedValue = value === undefined || value === null ? '' : String(value)\n\n for (const field of fields) {\n if (field instanceof HTMLInputElement) {\n if (field.type === 'checkbox') {\n field.checked = normalizedArray\n ? normalizedArray.includes(field.value)\n : normalizedValue === field.value\n continue\n }\n\n if (field.type === 'radio') {\n field.checked = field.value === normalizedValue\n continue\n }\n\n if (field.type === 'file') {\n if (Array.isArray(value) && value.length === 0) {\n field.value = ''\n }\n continue\n }\n\n field.value = normalizedValue\n continue\n }\n\n field.value = normalizedValue\n }\n}\n\nexport const clearAttributes = (\n form: HTMLFormElement,\n attributes: string[]\n) => {\n for (const attribute of attributes) {\n form.querySelectorAll(`[${attribute}]`).forEach(element => {\n element.removeAttribute(attribute)\n })\n }\n}\n\nexport const submitForm = (form: HTMLFormElement) => {\n if (typeof form.requestSubmit === 'function') {\n form.requestSubmit()\n return\n }\n\n const submitButton = form.querySelector(\n 'button[type=\"submit\"], input[type=\"submit\"]'\n ) as HTMLButtonElement | HTMLInputElement | null\n\n if (submitButton) {\n submitButton.click()\n return\n }\n\n form.submit()\n}","import { createEmptyFormState, parseFormData, validateFieldValue } from '../core'\nimport type {\n AppendContentOptions,\n AutoSubmitOptions,\n FormController,\n FormControllerOptions,\n FormErrors,\n FormFieldElement,\n FormFieldWatcher,\n FormSubmitHandler,\n FormStateListener,\n FormStateSnapshot,\n FormTarget,\n ValidationResult,\n VisualAttributes\n} from '../core/types'\nimport {\n applyBooleanAttribute,\n clearAttributes,\n getNamedFields,\n isFieldFilled,\n queryNamedFields,\n readFieldValue,\n resolveFormElement,\n submitForm,\n writeFieldValue\n} from './dom'\n\nconst DEFAULT_ATTRIBUTES: VisualAttributes = {\n filled: 'css-filled',\n error: 'css-error'\n}\n\nconst DEFAULT_OPTIONS: Required<\n Pick<FormControllerOptions, 'autoValidate' | 'clearErrorsOnSubmit'>\n> = {\n autoValidate: true,\n clearErrorsOnSubmit: true\n}\n\nconst mergeErrors = (left: FormErrors, right: FormErrors) => {\n const merged: FormErrors = { ...left }\n\n for (const [field, messages] of Object.entries(right)) {\n merged[field] = merged[field] ? [...merged[field], ...messages] : [...messages]\n }\n\n return merged\n}\n\nconst cloneErrors = (errors: FormErrors) =>\n Object.fromEntries(\n Object.entries(errors).map(([field, messages]) => [field, [...messages]])\n )\n\nexport const createFormController = (\n target: FormTarget,\n options: FormControllerOptions = {}\n): FormController => {\n const element = resolveFormElement(target)\n const attributes = { ...DEFAULT_ATTRIBUTES, ...options.attributes }\n const normalizedOptions: FormControllerOptions = {\n ...DEFAULT_OPTIONS,\n ...options,\n attributes\n }\n\n const validators = normalizedOptions.validators ?? {}\n const watchedFields = new Map<string, Set<FormFieldWatcher>>()\n const listeners: Array<{\n element: EventTarget\n type: string\n handler: EventListenerOrEventListenerObject\n }> = []\n const subscribers = new Set<FormStateListener>()\n const submitHandlers = new Set<{\n callback: FormSubmitHandler\n preventDefault: boolean\n }>()\n const fieldCache = new Map<string, FormFieldElement[]>()\n\n let manualErrors: FormErrors = {}\n let validationErrors: FormErrors = {}\n let isValidated = Boolean(normalizedOptions.autoValidate)\n let autoSubmitEnabled = false\n let autoSubmitDebounce = 0\n let submitCount = 0\n let autoSubmitTimer: ReturnType<typeof setTimeout> | null = null\n let mutationObserver: MutationObserver | null = null\n let isDestroyed = false\n\n const notifySubscribers = () => {\n const state = api.getState()\n subscribers.forEach(listener => listener(state))\n }\n\n const addListener = (\n listenerTarget: EventTarget,\n type: string,\n handler: EventListenerOrEventListenerObject\n ) => {\n listenerTarget.addEventListener(type, handler)\n listeners.push({ element: listenerTarget, type, handler })\n }\n\n const clearFieldCache = () => {\n fieldCache.clear()\n }\n\n const getFieldsByName = (name: string) => {\n if (!element) {\n return []\n }\n\n if (!fieldCache.has(name)) {\n fieldCache.set(name, queryNamedFields(element, name))\n }\n\n return fieldCache.get(name) ?? []\n }\n\n const getTrackedFieldNames = () => {\n if (!element) {\n return Object.keys(validators)\n }\n\n const names = new Set<string>(Object.keys(validators))\n for (const field of getNamedFields(element)) {\n names.add(field.name)\n }\n\n return Array.from(names)\n }\n\n const getValues = () => {\n const values: FormStateSnapshot['values'] = {}\n for (const name of getTrackedFieldNames()) {\n values[name] = api.getValue(name)\n }\n return values\n }\n\n const getMergedErrors = () => mergeErrors(validationErrors, manualErrors)\n\n const syncVisualState = (names?: string[]) => {\n if (!element) {\n return\n }\n\n const targetNames = names ?? getTrackedFieldNames()\n const errors = getMergedErrors()\n\n for (const name of targetNames) {\n const fields = getFieldsByName(name)\n const hasError = Boolean(errors[name]?.length)\n for (const field of fields) {\n applyBooleanAttribute(field, attributes.filled, isFieldFilled(field))\n applyBooleanAttribute(field, attributes.error, hasError)\n }\n }\n }\n\n const validateNames = (names?: string[]) => {\n const targetNames = names ?? Object.keys(validators)\n const values = getValues()\n const nextValidationErrors = names ? cloneErrors(validationErrors) : {}\n\n for (const name of targetNames) {\n const rules = validators[name]\n\n if (!rules) {\n delete nextValidationErrors[name]\n continue\n }\n\n const errors = validateFieldValue(name, values[name], rules, values)\n if (errors.length > 0) {\n nextValidationErrors[name] = errors\n } else {\n delete nextValidationErrors[name]\n }\n }\n\n validationErrors = nextValidationErrors\n syncVisualState(names)\n\n return {\n isValid: Object.keys(getMergedErrors()).length === 0,\n errors: cloneErrors(getMergedErrors())\n } satisfies ValidationResult\n }\n\n const emitFieldWatchers = (name: string) => {\n if (!element) {\n return\n }\n\n const callbacks = watchedFields.get(name)\n if (!callbacks || callbacks.size === 0) {\n return\n }\n\n const value = api.getValue(name)\n const state = api.getState()\n callbacks.forEach(callback => callback(value, element, state))\n }\n\n const scheduleAutoSubmit = () => {\n if (!element || !autoSubmitEnabled) {\n return\n }\n\n if (autoSubmitTimer) {\n clearTimeout(autoSubmitTimer)\n }\n\n if (autoSubmitDebounce > 0) {\n autoSubmitTimer = setTimeout(() => submitForm(element), autoSubmitDebounce)\n return\n }\n\n submitForm(element)\n }\n\n const handleDelegatedEvent = (event: Event) => {\n const target = event.target\n if (!(target instanceof Element) || !isFieldElement(target)) {\n return\n }\n\n const name = target.name\n if (!name) {\n return\n }\n\n clearFieldCache()\n syncVisualState([name])\n\n if (isValidated && validators[name]) {\n validateNames([name])\n }\n\n emitFieldWatchers(name)\n notifySubscribers()\n scheduleAutoSubmit()\n }\n\n const handleSubmitEvent = (event: Event) => {\n if (!element || isDestroyed) {\n return\n }\n\n if (normalizedOptions.clearErrorsOnSubmit) {\n manualErrors = {}\n }\n\n const validation = api.validate()\n const handlers = Array.from(submitHandlers)\n const shouldPrevent = validation.isValid\n ? handlers.some(handler => handler.preventDefault)\n : true\n\n if (shouldPrevent) {\n event.preventDefault()\n }\n\n submitCount += 1\n notifySubscribers()\n\n if (!validation.isValid) {\n return\n }\n\n const { data, formData } = api.getData()\n const state = api.getState()\n handlers.forEach(handler => handler.callback(element, data, formData, state))\n }\n\n const startMutationObserver = () => {\n if (!element || typeof MutationObserver === 'undefined') {\n return\n }\n\n mutationObserver = new MutationObserver(() => {\n clearFieldCache()\n if (isValidated) {\n syncVisualState()\n validateNames()\n }\n notifySubscribers()\n })\n\n mutationObserver.observe(element, {\n childList: true,\n subtree: true,\n attributes: true,\n attributeFilter: ['name', 'type']\n })\n }\n\n const isFieldElement = (value: Element): value is FormFieldElement =>\n value instanceof HTMLInputElement ||\n value instanceof HTMLSelectElement ||\n value instanceof HTMLTextAreaElement\n\n const api: FormController = {\n element,\n f: element,\n options: normalizedOptions,\n onSubmit(callback, preventDefault = true) {\n submitHandlers.add({ callback, preventDefault })\n return api\n },\n watch(field, callback) {\n api.observe(field, callback)\n return api\n },\n observe(field, callback) {\n const callbacks = watchedFields.get(field) ?? new Set<FormFieldWatcher>()\n callbacks.add(callback)\n watchedFields.set(field, callbacks)\n\n if (element) {\n callback(api.getValue(field), element, api.getState())\n }\n\n return () => {\n const currentCallbacks = watchedFields.get(field)\n currentCallbacks?.delete(callback)\n if (currentCallbacks && currentCallbacks.size === 0) {\n watchedFields.delete(field)\n }\n }\n },\n unwatch(field, callback) {\n if (!field) {\n watchedFields.clear()\n return api\n }\n\n if (!callback) {\n watchedFields.delete(field)\n return api\n }\n\n const callbacks = watchedFields.get(field)\n callbacks?.delete(callback)\n if (callbacks && callbacks.size === 0) {\n watchedFields.delete(field)\n }\n return api\n },\n subscribe(listener) {\n subscribers.add(listener)\n listener(api.getState())\n return () => {\n subscribers.delete(listener)\n }\n },\n prefill(fieldName) {\n if (!element) {\n return api\n }\n\n const queryParams = new URLSearchParams(window.location.search)\n queryParams.forEach((value, key) => {\n if (fieldName && fieldName !== key) {\n return\n }\n\n api.setValue(key, value)\n })\n return api\n },\n append({ tag, content, class: className, atStart = false }: AppendContentOptions) {\n if (!element) {\n return null\n }\n\n clearFieldCache()\n if (className) {\n const classSelector = className.trim().split(/\\s+/)[0]\n element.querySelector(`.${classSelector}`)?.remove()\n }\n\n const node = document.createElement(tag)\n if (className) {\n node.className = className\n }\n node.innerHTML = content\n\n if (atStart && element.firstChild) {\n element.insertBefore(node, element.firstChild)\n } else {\n element.appendChild(node)\n }\n\n return node\n },\n setErrors(fields) {\n if (Array.isArray(fields)) {\n manualErrors = {\n ...manualErrors,\n ...Object.fromEntries(fields.map(field => [field, ['Invalid value.']]))\n }\n } else {\n manualErrors = {\n ...manualErrors,\n ...cloneErrors(fields)\n }\n }\n\n syncVisualState(Array.isArray(fields) ? fields : Object.keys(fields))\n notifySubscribers()\n return api\n },\n clearErrors(fields) {\n if (!fields) {\n manualErrors = {}\n syncVisualState()\n notifySubscribers()\n return api\n }\n\n for (const field of fields) {\n delete manualErrors[field]\n }\n\n syncVisualState(fields)\n notifySubscribers()\n return api\n },\n setValue(name, value) {\n const fields = getFieldsByName(name)\n if (fields.length === 0) {\n return api\n }\n\n writeFieldValue(fields, value)\n const firstField = fields[0]\n if (!firstField) {\n return api\n }\n\n const eventType =\n firstField instanceof HTMLSelectElement ||\n (firstField instanceof HTMLInputElement &&\n (firstField.type === 'checkbox' || firstField.type === 'radio'))\n ? 'change'\n : 'input'\n\n firstField.dispatchEvent(new Event(eventType, { bubbles: true }))\n return api\n },\n validate(fields) {\n isValidated = true\n syncVisualState(fields)\n return validateNames(fields)\n },\n revalidate(fields) {\n return api.validate(fields)\n },\n reset() {\n if (!element) {\n return api\n }\n\n element.reset()\n manualErrors = {}\n validationErrors = {}\n clearAttributes(element, [attributes.error, attributes.filled])\n if (isValidated) {\n syncVisualState()\n }\n notifySubscribers()\n return api\n },\n autoSubmit(nextOptions = true) {\n autoSubmitEnabled = nextOptions !== false\n autoSubmitDebounce =\n typeof nextOptions === 'object' && nextOptions\n ? nextOptions.debounce ?? 0\n : 0\n notifySubscribers()\n return api\n },\n disableAutoSubmit() {\n autoSubmitEnabled = false\n if (autoSubmitTimer) {\n clearTimeout(autoSubmitTimer)\n autoSubmitTimer = null\n }\n notifySubscribers()\n return api\n },\n getValue(name) {\n return readFieldValue(getFieldsByName(name))\n },\n getField(name) {\n const fields = getFieldsByName(name)\n if (fields.length === 0) {\n return null\n }\n const [firstField] = fields\n if (!firstField) {\n return null\n }\n return fields.length === 1 ? firstField : fields\n },\n getData() {\n if (!element) {\n return { data: {}, formData: new FormData() }\n }\n return parseFormData(element)\n },\n getState() {\n const values = getValues()\n const errors = cloneErrors(getMergedErrors())\n const filledFields = getTrackedFieldNames().filter(name => {\n const value = values[name]\n return Array.isArray(value)\n ? value.length > 0\n : typeof value === 'string'\n ? value.trim().length > 0\n : value !== undefined\n })\n\n return {\n ...createEmptyFormState(),\n values,\n errors,\n filledFields,\n isValid: Object.keys(errors).length === 0,\n isValidated,\n autoSubmit: autoSubmitEnabled,\n submitCount\n }\n },\n destroy() {\n if (isDestroyed) {\n return\n }\n\n isDestroyed = true\n for (const listener of listeners) {\n listener.element.removeEventListener(listener.type, listener.handler)\n }\n listeners.length = 0\n\n if (autoSubmitTimer) {\n clearTimeout(autoSubmitTimer)\n autoSubmitTimer = null\n }\n\n mutationObserver?.disconnect()\n mutationObserver = null\n watchedFields.clear()\n subscribers.clear()\n submitHandlers.clear()\n clearFieldCache()\n manualErrors = {}\n validationErrors = {}\n }\n }\n\n if (element) {\n addListener(element, 'input', handleDelegatedEvent)\n addListener(element, 'change', handleDelegatedEvent)\n addListener(element, 'submit', handleSubmitEvent)\n startMutationObserver()\n }\n\n if (normalizedOptions.autoSubmit) {\n const autoSubmitOption = normalizedOptions.autoSubmit as boolean | AutoSubmitOptions\n api.autoSubmit(autoSubmitOption)\n }\n\n if (isValidated) {\n syncVisualState()\n validateNames()\n }\n\n return api\n}","import type { FormControllerOptions, FormTarget } from '../core'\nimport { createFormController } from '../internal/controller'\n\nexport const form = (\n target: FormTarget,\n options?: FormControllerOptions\n) => createFormController(target, options)\n\nexport { createFormController }"],"mappings":"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","names":["form","target"]}
1
+ {"version":3,"sources":["../../src/browser/global.ts","../../src/core/serialize.ts","../../src/core/state.ts","../../src/core/validation.ts","../../src/internal/dom.ts","../../src/internal/controller.ts","../../src/vanilla/index.ts"],"sourcesContent":["import { parseFormData, validateValues } from '../core'\nimport { createFormController, form } from '../vanilla'\n\nconst browserApi = {\n createFormController,\n form,\n parseFormData,\n validateValues\n}\n\ndeclare global {\n interface Window {\n forms: typeof browserApi\n }\n}\n\nif (typeof globalThis !== 'undefined') {\n ;(globalThis as typeof globalThis & { forms: typeof browserApi }).forms =\n browserApi\n}\n\nexport default browserApi","import type { SerializedFormResult, SerializedFormValue } from './types'\n\nconst isEmptyFile = (value: FormDataEntryValue): value is File =>\n value instanceof File && value.size === 0 && value.name === ''\n\nconst appendValue = (\n data: Record<string, SerializedFormValue>,\n key: string,\n value: FormDataEntryValue\n) => {\n const current = data[key]\n\n if (current === undefined) {\n data[key] = value\n return\n }\n\n if (Array.isArray(current)) {\n current.push(value)\n return\n }\n\n data[key] = [current, value]\n}\n\nexport const parseFormData = (\n formElement: HTMLFormElement\n): SerializedFormResult => {\n const rawFormData = new FormData(formElement)\n const formData = new FormData()\n const data: Record<string, SerializedFormValue> = {}\n\n rawFormData.forEach((value, key) => {\n if (isEmptyFile(value)) {\n return\n }\n\n formData.append(key, value)\n appendValue(data, key, value)\n })\n\n return { data, formData }\n}","import type { FormStateSnapshot } from './types'\n\nexport const createEmptyFormState = (): FormStateSnapshot => ({\n values: {},\n errors: {},\n filledFields: [],\n isValid: true,\n isValidated: false,\n autoSubmit: false,\n submitCount: 0\n})","import type {\n FieldValidationContext,\n FieldValidationRules,\n FormErrors,\n FormFieldValue,\n FormValues,\n RuleConfig,\n ValidationResult,\n ValidationSchema\n} from './types'\n\nconst resolveRule = <T>(rule: RuleConfig<T> | undefined) => {\n if (rule === undefined) {\n return { value: undefined as T | undefined, message: undefined as string | undefined }\n }\n\n if (typeof rule === 'object' && rule !== null && 'value' in rule) {\n return { value: rule.value, message: rule.message }\n }\n\n return { value: rule, message: undefined as string | undefined }\n}\n\nconst hasValue = (value: FormFieldValue) => {\n if (Array.isArray(value)) {\n return value.length > 0\n }\n\n return typeof value === 'string' ? value.trim().length > 0 : value !== undefined\n}\n\nconst getValueLength = (value: FormFieldValue) => {\n if (Array.isArray(value)) {\n return value.length\n }\n\n if (typeof value === 'string') {\n return value.length\n }\n\n return 0\n}\n\nconst toPatternTarget = (value: FormFieldValue) => {\n if (typeof value === 'string') {\n return value\n }\n\n if (Array.isArray(value)) {\n return value\n .map(entry => (typeof entry === 'string' ? entry : entry.name))\n .join(',')\n }\n\n return ''\n}\n\nexport const validateFieldValue = (\n field: string,\n value: FormFieldValue,\n rules: FieldValidationRules,\n values: FormValues\n) => {\n const errors: string[] = []\n const context: FieldValidationContext = { field, value, values }\n const required = resolveRule(rules.required)\n const minLength = resolveRule(rules.minLength)\n const maxLength = resolveRule(rules.maxLength)\n const pattern = resolveRule(rules.pattern)\n\n if (required.value && !hasValue(value)) {\n errors.push(required.message ?? 'This field is required.')\n }\n\n if (minLength.value !== undefined && getValueLength(value) < minLength.value) {\n errors.push(minLength.message ?? `Minimum length is ${minLength.value}.`)\n }\n\n if (maxLength.value !== undefined && getValueLength(value) > maxLength.value) {\n errors.push(maxLength.message ?? `Maximum length is ${maxLength.value}.`)\n }\n\n if (pattern.value && hasValue(value) && !pattern.value.test(toPatternTarget(value))) {\n errors.push(pattern.message ?? 'Value does not match the required pattern.')\n }\n\n const customValidators = rules.validate\n ? Array.isArray(rules.validate)\n ? rules.validate\n : [rules.validate]\n : []\n\n for (const validator of customValidators) {\n const result = validator(context)\n\n if (typeof result === 'string' && result.length > 0) {\n errors.push(result)\n }\n\n if (result === false) {\n errors.push('Validation failed.')\n }\n }\n\n return errors\n}\n\nexport const validateValues = (\n values: FormValues,\n schema: ValidationSchema\n): ValidationResult => {\n const errors: FormErrors = {}\n\n for (const [field, rules] of Object.entries(schema)) {\n const messages = validateFieldValue(field, values[field], rules, values)\n if (messages.length > 0) {\n errors[field] = messages\n }\n }\n\n return {\n isValid: Object.keys(errors).length === 0,\n errors\n }\n}","import type { FormFieldElement, FormFieldValue, FormTarget } from '../core/types'\n\nconst isFormFieldElement = (value: Element): value is FormFieldElement =>\n value instanceof HTMLInputElement ||\n value instanceof HTMLSelectElement ||\n value instanceof HTMLTextAreaElement\n\nexport const resolveFormElement = (target: FormTarget): HTMLFormElement | null => {\n if (!target) {\n return null\n }\n\n if (target instanceof HTMLFormElement) {\n return target\n }\n\n if (typeof target === 'string') {\n const element = document.getElementById(target)\n return element instanceof HTMLFormElement ? element : null\n }\n\n if ('current' in target) {\n return target.current instanceof HTMLFormElement ? target.current : null\n }\n\n return null\n}\n\nexport const getNamedFields = (form: HTMLFormElement): FormFieldElement[] =>\n Array.from(form.querySelectorAll('input[name], select[name], textarea[name]')).filter(\n isFormFieldElement\n )\n\nexport const queryNamedFields = (\n form: HTMLFormElement,\n name: string\n): FormFieldElement[] => getNamedFields(form).filter(field => field.name === name)\n\nexport const isFieldFilled = (field: FormFieldElement) => {\n if (field instanceof HTMLInputElement) {\n if (field.type === 'checkbox' || field.type === 'radio') {\n return field.checked\n }\n\n if (field.type === 'file') {\n return Boolean(field.files && field.files.length > 0)\n }\n\n return field.value.trim() !== ''\n }\n\n return field.value !== ''\n}\n\nexport const applyBooleanAttribute = (\n field: FormFieldElement,\n attribute: string,\n enabled: boolean\n) => {\n if (enabled) {\n field.setAttribute(attribute, '')\n return\n }\n\n field.removeAttribute(attribute)\n}\n\nexport const readFieldValue = (\n fields: FormFieldElement[]\n): FormFieldValue => {\n if (fields.length === 0) {\n return undefined\n }\n\n const firstField = fields[0]\n if (!firstField) {\n return undefined\n }\n\n if (firstField instanceof HTMLSelectElement || firstField instanceof HTMLTextAreaElement) {\n return firstField.value\n }\n\n if (firstField.type === 'radio') {\n const checked = fields.find(\n field => field instanceof HTMLInputElement && field.checked\n ) as HTMLInputElement | undefined\n\n return checked?.value ?? ''\n }\n\n if (firstField.type === 'checkbox') {\n const values = fields\n .filter(field => field instanceof HTMLInputElement && field.checked)\n .map(field => (field as HTMLInputElement).value)\n\n return values.length > 1 ? values : (values[0] ?? '')\n }\n\n if (firstField.type === 'file') {\n return firstField.files ? Array.from(firstField.files) : []\n }\n\n return firstField.value\n}\n\nexport const writeFieldValue = (\n fields: FormFieldElement[],\n value: unknown\n) => {\n const normalizedArray = Array.isArray(value)\n ? value.map(item => String(item))\n : null\n const normalizedValue = value === undefined || value === null ? '' : String(value)\n\n for (const field of fields) {\n if (field instanceof HTMLInputElement) {\n if (field.type === 'checkbox') {\n field.checked = normalizedArray\n ? normalizedArray.includes(field.value)\n : normalizedValue === field.value\n continue\n }\n\n if (field.type === 'radio') {\n field.checked = field.value === normalizedValue\n continue\n }\n\n if (field.type === 'file') {\n if (Array.isArray(value) && value.length === 0) {\n field.value = ''\n }\n continue\n }\n\n field.value = normalizedValue\n continue\n }\n\n field.value = normalizedValue\n }\n}\n\nexport const clearAttributes = (\n form: HTMLFormElement,\n attributes: string[]\n) => {\n for (const attribute of attributes) {\n form.querySelectorAll(`[${attribute}]`).forEach(element => {\n element.removeAttribute(attribute)\n })\n }\n}\n\nexport const submitForm = (form: HTMLFormElement) => {\n if (typeof form.requestSubmit === 'function') {\n form.requestSubmit()\n return\n }\n\n const submitButton = form.querySelector(\n 'button[type=\"submit\"], input[type=\"submit\"]'\n ) as HTMLButtonElement | HTMLInputElement | null\n\n if (submitButton) {\n submitButton.click()\n return\n }\n\n form.submit()\n}","import { createEmptyFormState, parseFormData, validateFieldValue } from '../core'\nimport type {\n AppendContentOptions,\n AutoSubmitOptions,\n FormController,\n FormControllerOptions,\n FormErrors,\n FormFieldElement,\n FormFieldWatcher,\n FormSubmitHandler,\n FormStateListener,\n FormStateSnapshot,\n FormTarget,\n ValidationResult,\n VisualAttributes\n} from '../core/types'\nimport {\n applyBooleanAttribute,\n clearAttributes,\n getNamedFields,\n isFieldFilled,\n queryNamedFields,\n readFieldValue,\n resolveFormElement,\n submitForm,\n writeFieldValue\n} from './dom'\n\nconst DEFAULT_ATTRIBUTES: VisualAttributes = {\n filled: 'css-filled',\n error: 'css-error'\n}\n\nconst DEFAULT_OPTIONS: Required<\n Pick<\n FormControllerOptions,\n 'autoValidate' | 'clearErrorsOnSubmit' | 'clearManualErrorsOnChange'\n >\n> = {\n autoValidate: true,\n clearManualErrorsOnChange: true,\n clearErrorsOnSubmit: true\n}\n\nconst mergeErrors = (left: FormErrors, right: FormErrors) => {\n const merged: FormErrors = { ...left }\n\n for (const [field, messages] of Object.entries(right)) {\n merged[field] = merged[field] ? [...merged[field], ...messages] : [...messages]\n }\n\n return merged\n}\n\nconst cloneErrors = (errors: FormErrors) =>\n Object.fromEntries(\n Object.entries(errors).map(([field, messages]) => [field, [...messages]])\n )\n\nexport const createFormController = (\n target: FormTarget,\n options: FormControllerOptions = {}\n): FormController => {\n const element = resolveFormElement(target)\n const attributes = { ...DEFAULT_ATTRIBUTES, ...options.attributes }\n const normalizedOptions: FormControllerOptions = {\n ...DEFAULT_OPTIONS,\n ...options,\n attributes\n }\n\n const validators = normalizedOptions.validators ?? {}\n const watchedFields = new Map<string, Set<FormFieldWatcher>>()\n const listeners: Array<{\n element: EventTarget\n type: string\n handler: EventListenerOrEventListenerObject\n }> = []\n const subscribers = new Set<FormStateListener>()\n const submitHandlers = new Set<{\n callback: FormSubmitHandler\n preventDefault: boolean\n }>()\n const fieldCache = new Map<string, FormFieldElement[]>()\n\n let manualErrors: FormErrors = {}\n let validationErrors: FormErrors = {}\n let isValidated = Boolean(normalizedOptions.autoValidate)\n let autoSubmitEnabled = false\n let autoSubmitDebounce = 0\n let submitCount = 0\n let autoSubmitTimer: ReturnType<typeof setTimeout> | null = null\n let mutationObserver: MutationObserver | null = null\n let isDestroyed = false\n\n const notifySubscribers = () => {\n const state = api.getState()\n subscribers.forEach(listener => listener(state))\n }\n\n const addListener = (\n listenerTarget: EventTarget,\n type: string,\n handler: EventListenerOrEventListenerObject\n ) => {\n listenerTarget.addEventListener(type, handler)\n listeners.push({ element: listenerTarget, type, handler })\n }\n\n const clearFieldCache = () => {\n fieldCache.clear()\n }\n\n const getFieldsByName = (name: string) => {\n if (!element) {\n return []\n }\n\n if (!fieldCache.has(name)) {\n fieldCache.set(name, queryNamedFields(element, name))\n }\n\n return fieldCache.get(name) ?? []\n }\n\n const getTrackedFieldNames = () => {\n if (!element) {\n return Object.keys(validators)\n }\n\n const names = new Set<string>(Object.keys(validators))\n for (const field of getNamedFields(element)) {\n names.add(field.name)\n }\n\n return Array.from(names)\n }\n\n const getValues = () => {\n const values: FormStateSnapshot['values'] = {}\n for (const name of getTrackedFieldNames()) {\n values[name] = api.getValue(name)\n }\n return values\n }\n\n const getMergedErrors = () => mergeErrors(validationErrors, manualErrors)\n\n const syncVisualState = (names?: string[]) => {\n if (!element) {\n return\n }\n\n const targetNames = names ?? getTrackedFieldNames()\n const errors = getMergedErrors()\n\n for (const name of targetNames) {\n const fields = getFieldsByName(name)\n const hasError = Boolean(errors[name]?.length)\n for (const field of fields) {\n applyBooleanAttribute(field, attributes.filled, isFieldFilled(field))\n applyBooleanAttribute(field, attributes.error, hasError)\n }\n }\n }\n\n const validateNames = (names?: string[]) => {\n const targetNames = names ?? Object.keys(validators)\n const values = getValues()\n const nextValidationErrors = names ? cloneErrors(validationErrors) : {}\n\n for (const name of targetNames) {\n const rules = validators[name]\n\n if (!rules) {\n delete nextValidationErrors[name]\n continue\n }\n\n const errors = validateFieldValue(name, values[name], rules, values)\n if (errors.length > 0) {\n nextValidationErrors[name] = errors\n } else {\n delete nextValidationErrors[name]\n }\n }\n\n validationErrors = nextValidationErrors\n syncVisualState(names)\n\n return {\n isValid: Object.keys(getMergedErrors()).length === 0,\n errors: cloneErrors(getMergedErrors())\n } satisfies ValidationResult\n }\n\n const emitFieldWatchers = (name: string) => {\n if (!element) {\n return\n }\n\n const callbacks = watchedFields.get(name)\n if (!callbacks || callbacks.size === 0) {\n return\n }\n\n const value = api.getValue(name)\n const state = api.getState()\n callbacks.forEach(callback => callback(value, element, state))\n }\n\n const scheduleAutoSubmit = () => {\n if (!element || !autoSubmitEnabled) {\n return\n }\n\n if (autoSubmitTimer) {\n clearTimeout(autoSubmitTimer)\n }\n\n if (autoSubmitDebounce > 0) {\n autoSubmitTimer = setTimeout(() => submitForm(element), autoSubmitDebounce)\n return\n }\n\n submitForm(element)\n }\n\n const handleDelegatedEvent = (event: Event) => {\n const target = event.target\n if (!(target instanceof Element) || !isFieldElement(target)) {\n return\n }\n\n const name = target.name\n if (!name) {\n return\n }\n\n clearFieldCache()\n\n if (normalizedOptions.clearManualErrorsOnChange) {\n delete manualErrors[name]\n }\n\n syncVisualState([name])\n\n if (isValidated && validators[name]) {\n validateNames([name])\n }\n\n emitFieldWatchers(name)\n notifySubscribers()\n scheduleAutoSubmit()\n }\n\n const handleSubmitEvent = (event: Event) => {\n if (!element || isDestroyed) {\n return\n }\n\n if (normalizedOptions.clearErrorsOnSubmit) {\n manualErrors = {}\n }\n\n const validation = api.validate()\n const handlers = Array.from(submitHandlers)\n const shouldPrevent = validation.isValid\n ? handlers.some(handler => handler.preventDefault)\n : true\n\n if (shouldPrevent) {\n event.preventDefault()\n }\n\n submitCount += 1\n notifySubscribers()\n\n if (!validation.isValid) {\n return\n }\n\n const { data, formData } = api.getData()\n const state = api.getState()\n handlers.forEach(handler => handler.callback(element, data, formData, state))\n }\n\n const startMutationObserver = () => {\n if (!element || typeof MutationObserver === 'undefined') {\n return\n }\n\n mutationObserver = new MutationObserver(() => {\n clearFieldCache()\n if (isValidated) {\n syncVisualState()\n validateNames()\n }\n notifySubscribers()\n })\n\n mutationObserver.observe(element, {\n childList: true,\n subtree: true,\n attributes: true,\n attributeFilter: ['name', 'type']\n })\n }\n\n const isFieldElement = (value: Element): value is FormFieldElement =>\n value instanceof HTMLInputElement ||\n value instanceof HTMLSelectElement ||\n value instanceof HTMLTextAreaElement\n\n const api: FormController = {\n element,\n f: element,\n options: normalizedOptions,\n onSubmit(callback, preventDefault = true) {\n submitHandlers.add({ callback, preventDefault })\n return api\n },\n watch(field, callback) {\n api.observe(field, callback)\n return api\n },\n observe(field, callback) {\n const callbacks = watchedFields.get(field) ?? new Set<FormFieldWatcher>()\n callbacks.add(callback)\n watchedFields.set(field, callbacks)\n\n if (element) {\n callback(api.getValue(field), element, api.getState())\n }\n\n return () => {\n const currentCallbacks = watchedFields.get(field)\n currentCallbacks?.delete(callback)\n if (currentCallbacks && currentCallbacks.size === 0) {\n watchedFields.delete(field)\n }\n }\n },\n unwatch(field, callback) {\n if (!field) {\n watchedFields.clear()\n return api\n }\n\n if (!callback) {\n watchedFields.delete(field)\n return api\n }\n\n const callbacks = watchedFields.get(field)\n callbacks?.delete(callback)\n if (callbacks && callbacks.size === 0) {\n watchedFields.delete(field)\n }\n return api\n },\n subscribe(listener) {\n subscribers.add(listener)\n listener(api.getState())\n return () => {\n subscribers.delete(listener)\n }\n },\n prefill(fieldName) {\n if (!element) {\n return api\n }\n\n const queryParams = new URLSearchParams(window.location.search)\n queryParams.forEach((value, key) => {\n if (fieldName && fieldName !== key) {\n return\n }\n\n api.setValue(key, value)\n })\n return api\n },\n append({ tag, content, class: className, atStart = false }: AppendContentOptions) {\n if (!element) {\n return null\n }\n\n clearFieldCache()\n if (className) {\n const classSelector = className.trim().split(/\\s+/)[0]\n element.querySelector(`.${classSelector}`)?.remove()\n }\n\n const node = document.createElement(tag)\n if (className) {\n node.className = className\n }\n node.innerHTML = content\n\n if (atStart && element.firstChild) {\n element.insertBefore(node, element.firstChild)\n } else {\n element.appendChild(node)\n }\n\n return node\n },\n setErrors(fields) {\n if (Array.isArray(fields)) {\n manualErrors = {\n ...manualErrors,\n ...Object.fromEntries(fields.map(field => [field, ['Invalid value.']]))\n }\n } else {\n manualErrors = {\n ...manualErrors,\n ...cloneErrors(fields)\n }\n }\n\n syncVisualState(Array.isArray(fields) ? fields : Object.keys(fields))\n notifySubscribers()\n return api\n },\n clearErrors(fields) {\n if (!fields) {\n manualErrors = {}\n syncVisualState()\n notifySubscribers()\n return api\n }\n\n for (const field of fields) {\n delete manualErrors[field]\n }\n\n syncVisualState(fields)\n notifySubscribers()\n return api\n },\n setValue(name, value) {\n const fields = getFieldsByName(name)\n if (fields.length === 0) {\n return api\n }\n\n writeFieldValue(fields, value)\n const firstField = fields[0]\n if (!firstField) {\n return api\n }\n\n const eventType =\n firstField instanceof HTMLSelectElement ||\n (firstField instanceof HTMLInputElement &&\n (firstField.type === 'checkbox' || firstField.type === 'radio'))\n ? 'change'\n : 'input'\n\n firstField.dispatchEvent(new Event(eventType, { bubbles: true }))\n return api\n },\n validate(fields) {\n isValidated = true\n syncVisualState(fields)\n return validateNames(fields)\n },\n revalidate(fields) {\n return api.validate(fields)\n },\n reset() {\n if (!element) {\n return api\n }\n\n element.reset()\n manualErrors = {}\n validationErrors = {}\n clearAttributes(element, [attributes.error, attributes.filled])\n if (isValidated) {\n syncVisualState()\n }\n notifySubscribers()\n return api\n },\n autoSubmit(nextOptions = true) {\n autoSubmitEnabled = nextOptions !== false\n autoSubmitDebounce =\n typeof nextOptions === 'object' && nextOptions\n ? nextOptions.debounce ?? 0\n : 0\n notifySubscribers()\n return api\n },\n disableAutoSubmit() {\n autoSubmitEnabled = false\n if (autoSubmitTimer) {\n clearTimeout(autoSubmitTimer)\n autoSubmitTimer = null\n }\n notifySubscribers()\n return api\n },\n getValue(name) {\n return readFieldValue(getFieldsByName(name))\n },\n getField(name) {\n const fields = getFieldsByName(name)\n if (fields.length === 0) {\n return null\n }\n const [firstField] = fields\n if (!firstField) {\n return null\n }\n return fields.length === 1 ? firstField : fields\n },\n getData() {\n if (!element) {\n return { data: {}, formData: new FormData() }\n }\n return parseFormData(element)\n },\n getState() {\n const values = getValues()\n const errors = cloneErrors(getMergedErrors())\n const filledFields = getTrackedFieldNames().filter(name => {\n const value = values[name]\n return Array.isArray(value)\n ? value.length > 0\n : typeof value === 'string'\n ? value.trim().length > 0\n : value !== undefined\n })\n\n return {\n ...createEmptyFormState(),\n values,\n errors,\n filledFields,\n isValid: Object.keys(errors).length === 0,\n isValidated,\n autoSubmit: autoSubmitEnabled,\n submitCount\n }\n },\n destroy() {\n if (isDestroyed) {\n return\n }\n\n isDestroyed = true\n for (const listener of listeners) {\n listener.element.removeEventListener(listener.type, listener.handler)\n }\n listeners.length = 0\n\n if (autoSubmitTimer) {\n clearTimeout(autoSubmitTimer)\n autoSubmitTimer = null\n }\n\n mutationObserver?.disconnect()\n mutationObserver = null\n watchedFields.clear()\n subscribers.clear()\n submitHandlers.clear()\n clearFieldCache()\n manualErrors = {}\n validationErrors = {}\n }\n }\n\n if (element) {\n addListener(element, 'input', handleDelegatedEvent)\n addListener(element, 'change', handleDelegatedEvent)\n addListener(element, 'submit', handleSubmitEvent)\n startMutationObserver()\n }\n\n if (normalizedOptions.autoSubmit) {\n const autoSubmitOption = normalizedOptions.autoSubmit as boolean | AutoSubmitOptions\n api.autoSubmit(autoSubmitOption)\n }\n\n if (isValidated) {\n syncVisualState()\n validateNames()\n }\n\n return api\n}","import type { FormControllerOptions, FormTarget } from '../core'\nimport { createFormController } from '../internal/controller'\n\nexport const form = (\n target: FormTarget,\n options?: FormControllerOptions\n) => createFormController(target, options)\n\nexport { createFormController }"],"mappings":"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","names":["form","target"]}
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  createFormController
3
- } from "./chunk-KIJEFIHP.js";
3
+ } from "./chunk-WM2CL7IO.js";
4
4
 
5
5
  // src/vanilla/index.ts
6
6
  var form = (target, options) => createFormController(target, options);
@@ -8,4 +8,4 @@ var form = (target, options) => createFormController(target, options);
8
8
  export {
9
9
  form
10
10
  };
11
- //# sourceMappingURL=chunk-KKQD25KI.js.map
11
+ //# sourceMappingURL=chunk-PCKGH2WA.js.map
@@ -125,6 +125,7 @@ var DEFAULT_ATTRIBUTES = {
125
125
  };
126
126
  var DEFAULT_OPTIONS = {
127
127
  autoValidate: true,
128
+ clearManualErrorsOnChange: true,
128
129
  clearErrorsOnSubmit: true
129
130
  };
130
131
  var mergeErrors = (left, right) => {
@@ -272,6 +273,9 @@ var createFormController = (target, options = {}) => {
272
273
  return;
273
274
  }
274
275
  clearFieldCache();
276
+ if (normalizedOptions.clearManualErrorsOnChange) {
277
+ delete manualErrors[name];
278
+ }
275
279
  syncVisualState([name]);
276
280
  if (isValidated && validators[name]) {
277
281
  validateNames([name]);
@@ -569,4 +573,4 @@ export {
569
573
  resolveFormElement,
570
574
  createFormController
571
575
  };
572
- //# sourceMappingURL=chunk-KIJEFIHP.js.map
576
+ //# sourceMappingURL=chunk-WM2CL7IO.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/internal/dom.ts","../src/internal/controller.ts"],"sourcesContent":["import type { FormFieldElement, FormFieldValue, FormTarget } from '../core/types'\n\nconst isFormFieldElement = (value: Element): value is FormFieldElement =>\n value instanceof HTMLInputElement ||\n value instanceof HTMLSelectElement ||\n value instanceof HTMLTextAreaElement\n\nexport const resolveFormElement = (target: FormTarget): HTMLFormElement | null => {\n if (!target) {\n return null\n }\n\n if (target instanceof HTMLFormElement) {\n return target\n }\n\n if (typeof target === 'string') {\n const element = document.getElementById(target)\n return element instanceof HTMLFormElement ? element : null\n }\n\n if ('current' in target) {\n return target.current instanceof HTMLFormElement ? target.current : null\n }\n\n return null\n}\n\nexport const getNamedFields = (form: HTMLFormElement): FormFieldElement[] =>\n Array.from(form.querySelectorAll('input[name], select[name], textarea[name]')).filter(\n isFormFieldElement\n )\n\nexport const queryNamedFields = (\n form: HTMLFormElement,\n name: string\n): FormFieldElement[] => getNamedFields(form).filter(field => field.name === name)\n\nexport const isFieldFilled = (field: FormFieldElement) => {\n if (field instanceof HTMLInputElement) {\n if (field.type === 'checkbox' || field.type === 'radio') {\n return field.checked\n }\n\n if (field.type === 'file') {\n return Boolean(field.files && field.files.length > 0)\n }\n\n return field.value.trim() !== ''\n }\n\n return field.value !== ''\n}\n\nexport const applyBooleanAttribute = (\n field: FormFieldElement,\n attribute: string,\n enabled: boolean\n) => {\n if (enabled) {\n field.setAttribute(attribute, '')\n return\n }\n\n field.removeAttribute(attribute)\n}\n\nexport const readFieldValue = (\n fields: FormFieldElement[]\n): FormFieldValue => {\n if (fields.length === 0) {\n return undefined\n }\n\n const firstField = fields[0]\n if (!firstField) {\n return undefined\n }\n\n if (firstField instanceof HTMLSelectElement || firstField instanceof HTMLTextAreaElement) {\n return firstField.value\n }\n\n if (firstField.type === 'radio') {\n const checked = fields.find(\n field => field instanceof HTMLInputElement && field.checked\n ) as HTMLInputElement | undefined\n\n return checked?.value ?? ''\n }\n\n if (firstField.type === 'checkbox') {\n const values = fields\n .filter(field => field instanceof HTMLInputElement && field.checked)\n .map(field => (field as HTMLInputElement).value)\n\n return values.length > 1 ? values : (values[0] ?? '')\n }\n\n if (firstField.type === 'file') {\n return firstField.files ? Array.from(firstField.files) : []\n }\n\n return firstField.value\n}\n\nexport const writeFieldValue = (\n fields: FormFieldElement[],\n value: unknown\n) => {\n const normalizedArray = Array.isArray(value)\n ? value.map(item => String(item))\n : null\n const normalizedValue = value === undefined || value === null ? '' : String(value)\n\n for (const field of fields) {\n if (field instanceof HTMLInputElement) {\n if (field.type === 'checkbox') {\n field.checked = normalizedArray\n ? normalizedArray.includes(field.value)\n : normalizedValue === field.value\n continue\n }\n\n if (field.type === 'radio') {\n field.checked = field.value === normalizedValue\n continue\n }\n\n if (field.type === 'file') {\n if (Array.isArray(value) && value.length === 0) {\n field.value = ''\n }\n continue\n }\n\n field.value = normalizedValue\n continue\n }\n\n field.value = normalizedValue\n }\n}\n\nexport const clearAttributes = (\n form: HTMLFormElement,\n attributes: string[]\n) => {\n for (const attribute of attributes) {\n form.querySelectorAll(`[${attribute}]`).forEach(element => {\n element.removeAttribute(attribute)\n })\n }\n}\n\nexport const submitForm = (form: HTMLFormElement) => {\n if (typeof form.requestSubmit === 'function') {\n form.requestSubmit()\n return\n }\n\n const submitButton = form.querySelector(\n 'button[type=\"submit\"], input[type=\"submit\"]'\n ) as HTMLButtonElement | HTMLInputElement | null\n\n if (submitButton) {\n submitButton.click()\n return\n }\n\n form.submit()\n}","import { createEmptyFormState, parseFormData, validateFieldValue } from '../core'\nimport type {\n AppendContentOptions,\n AutoSubmitOptions,\n FormController,\n FormControllerOptions,\n FormErrors,\n FormFieldElement,\n FormFieldWatcher,\n FormSubmitHandler,\n FormStateListener,\n FormStateSnapshot,\n FormTarget,\n ValidationResult,\n VisualAttributes\n} from '../core/types'\nimport {\n applyBooleanAttribute,\n clearAttributes,\n getNamedFields,\n isFieldFilled,\n queryNamedFields,\n readFieldValue,\n resolveFormElement,\n submitForm,\n writeFieldValue\n} from './dom'\n\nconst DEFAULT_ATTRIBUTES: VisualAttributes = {\n filled: 'css-filled',\n error: 'css-error'\n}\n\nconst DEFAULT_OPTIONS: Required<\n Pick<\n FormControllerOptions,\n 'autoValidate' | 'clearErrorsOnSubmit' | 'clearManualErrorsOnChange'\n >\n> = {\n autoValidate: true,\n clearManualErrorsOnChange: true,\n clearErrorsOnSubmit: true\n}\n\nconst mergeErrors = (left: FormErrors, right: FormErrors) => {\n const merged: FormErrors = { ...left }\n\n for (const [field, messages] of Object.entries(right)) {\n merged[field] = merged[field] ? [...merged[field], ...messages] : [...messages]\n }\n\n return merged\n}\n\nconst cloneErrors = (errors: FormErrors) =>\n Object.fromEntries(\n Object.entries(errors).map(([field, messages]) => [field, [...messages]])\n )\n\nexport const createFormController = (\n target: FormTarget,\n options: FormControllerOptions = {}\n): FormController => {\n const element = resolveFormElement(target)\n const attributes = { ...DEFAULT_ATTRIBUTES, ...options.attributes }\n const normalizedOptions: FormControllerOptions = {\n ...DEFAULT_OPTIONS,\n ...options,\n attributes\n }\n\n const validators = normalizedOptions.validators ?? {}\n const watchedFields = new Map<string, Set<FormFieldWatcher>>()\n const listeners: Array<{\n element: EventTarget\n type: string\n handler: EventListenerOrEventListenerObject\n }> = []\n const subscribers = new Set<FormStateListener>()\n const submitHandlers = new Set<{\n callback: FormSubmitHandler\n preventDefault: boolean\n }>()\n const fieldCache = new Map<string, FormFieldElement[]>()\n\n let manualErrors: FormErrors = {}\n let validationErrors: FormErrors = {}\n let isValidated = Boolean(normalizedOptions.autoValidate)\n let autoSubmitEnabled = false\n let autoSubmitDebounce = 0\n let submitCount = 0\n let autoSubmitTimer: ReturnType<typeof setTimeout> | null = null\n let mutationObserver: MutationObserver | null = null\n let isDestroyed = false\n\n const notifySubscribers = () => {\n const state = api.getState()\n subscribers.forEach(listener => listener(state))\n }\n\n const addListener = (\n listenerTarget: EventTarget,\n type: string,\n handler: EventListenerOrEventListenerObject\n ) => {\n listenerTarget.addEventListener(type, handler)\n listeners.push({ element: listenerTarget, type, handler })\n }\n\n const clearFieldCache = () => {\n fieldCache.clear()\n }\n\n const getFieldsByName = (name: string) => {\n if (!element) {\n return []\n }\n\n if (!fieldCache.has(name)) {\n fieldCache.set(name, queryNamedFields(element, name))\n }\n\n return fieldCache.get(name) ?? []\n }\n\n const getTrackedFieldNames = () => {\n if (!element) {\n return Object.keys(validators)\n }\n\n const names = new Set<string>(Object.keys(validators))\n for (const field of getNamedFields(element)) {\n names.add(field.name)\n }\n\n return Array.from(names)\n }\n\n const getValues = () => {\n const values: FormStateSnapshot['values'] = {}\n for (const name of getTrackedFieldNames()) {\n values[name] = api.getValue(name)\n }\n return values\n }\n\n const getMergedErrors = () => mergeErrors(validationErrors, manualErrors)\n\n const syncVisualState = (names?: string[]) => {\n if (!element) {\n return\n }\n\n const targetNames = names ?? getTrackedFieldNames()\n const errors = getMergedErrors()\n\n for (const name of targetNames) {\n const fields = getFieldsByName(name)\n const hasError = Boolean(errors[name]?.length)\n for (const field of fields) {\n applyBooleanAttribute(field, attributes.filled, isFieldFilled(field))\n applyBooleanAttribute(field, attributes.error, hasError)\n }\n }\n }\n\n const validateNames = (names?: string[]) => {\n const targetNames = names ?? Object.keys(validators)\n const values = getValues()\n const nextValidationErrors = names ? cloneErrors(validationErrors) : {}\n\n for (const name of targetNames) {\n const rules = validators[name]\n\n if (!rules) {\n delete nextValidationErrors[name]\n continue\n }\n\n const errors = validateFieldValue(name, values[name], rules, values)\n if (errors.length > 0) {\n nextValidationErrors[name] = errors\n } else {\n delete nextValidationErrors[name]\n }\n }\n\n validationErrors = nextValidationErrors\n syncVisualState(names)\n\n return {\n isValid: Object.keys(getMergedErrors()).length === 0,\n errors: cloneErrors(getMergedErrors())\n } satisfies ValidationResult\n }\n\n const emitFieldWatchers = (name: string) => {\n if (!element) {\n return\n }\n\n const callbacks = watchedFields.get(name)\n if (!callbacks || callbacks.size === 0) {\n return\n }\n\n const value = api.getValue(name)\n const state = api.getState()\n callbacks.forEach(callback => callback(value, element, state))\n }\n\n const scheduleAutoSubmit = () => {\n if (!element || !autoSubmitEnabled) {\n return\n }\n\n if (autoSubmitTimer) {\n clearTimeout(autoSubmitTimer)\n }\n\n if (autoSubmitDebounce > 0) {\n autoSubmitTimer = setTimeout(() => submitForm(element), autoSubmitDebounce)\n return\n }\n\n submitForm(element)\n }\n\n const handleDelegatedEvent = (event: Event) => {\n const target = event.target\n if (!(target instanceof Element) || !isFieldElement(target)) {\n return\n }\n\n const name = target.name\n if (!name) {\n return\n }\n\n clearFieldCache()\n\n if (normalizedOptions.clearManualErrorsOnChange) {\n delete manualErrors[name]\n }\n\n syncVisualState([name])\n\n if (isValidated && validators[name]) {\n validateNames([name])\n }\n\n emitFieldWatchers(name)\n notifySubscribers()\n scheduleAutoSubmit()\n }\n\n const handleSubmitEvent = (event: Event) => {\n if (!element || isDestroyed) {\n return\n }\n\n if (normalizedOptions.clearErrorsOnSubmit) {\n manualErrors = {}\n }\n\n const validation = api.validate()\n const handlers = Array.from(submitHandlers)\n const shouldPrevent = validation.isValid\n ? handlers.some(handler => handler.preventDefault)\n : true\n\n if (shouldPrevent) {\n event.preventDefault()\n }\n\n submitCount += 1\n notifySubscribers()\n\n if (!validation.isValid) {\n return\n }\n\n const { data, formData } = api.getData()\n const state = api.getState()\n handlers.forEach(handler => handler.callback(element, data, formData, state))\n }\n\n const startMutationObserver = () => {\n if (!element || typeof MutationObserver === 'undefined') {\n return\n }\n\n mutationObserver = new MutationObserver(() => {\n clearFieldCache()\n if (isValidated) {\n syncVisualState()\n validateNames()\n }\n notifySubscribers()\n })\n\n mutationObserver.observe(element, {\n childList: true,\n subtree: true,\n attributes: true,\n attributeFilter: ['name', 'type']\n })\n }\n\n const isFieldElement = (value: Element): value is FormFieldElement =>\n value instanceof HTMLInputElement ||\n value instanceof HTMLSelectElement ||\n value instanceof HTMLTextAreaElement\n\n const api: FormController = {\n element,\n f: element,\n options: normalizedOptions,\n onSubmit(callback, preventDefault = true) {\n submitHandlers.add({ callback, preventDefault })\n return api\n },\n watch(field, callback) {\n api.observe(field, callback)\n return api\n },\n observe(field, callback) {\n const callbacks = watchedFields.get(field) ?? new Set<FormFieldWatcher>()\n callbacks.add(callback)\n watchedFields.set(field, callbacks)\n\n if (element) {\n callback(api.getValue(field), element, api.getState())\n }\n\n return () => {\n const currentCallbacks = watchedFields.get(field)\n currentCallbacks?.delete(callback)\n if (currentCallbacks && currentCallbacks.size === 0) {\n watchedFields.delete(field)\n }\n }\n },\n unwatch(field, callback) {\n if (!field) {\n watchedFields.clear()\n return api\n }\n\n if (!callback) {\n watchedFields.delete(field)\n return api\n }\n\n const callbacks = watchedFields.get(field)\n callbacks?.delete(callback)\n if (callbacks && callbacks.size === 0) {\n watchedFields.delete(field)\n }\n return api\n },\n subscribe(listener) {\n subscribers.add(listener)\n listener(api.getState())\n return () => {\n subscribers.delete(listener)\n }\n },\n prefill(fieldName) {\n if (!element) {\n return api\n }\n\n const queryParams = new URLSearchParams(window.location.search)\n queryParams.forEach((value, key) => {\n if (fieldName && fieldName !== key) {\n return\n }\n\n api.setValue(key, value)\n })\n return api\n },\n append({ tag, content, class: className, atStart = false }: AppendContentOptions) {\n if (!element) {\n return null\n }\n\n clearFieldCache()\n if (className) {\n const classSelector = className.trim().split(/\\s+/)[0]\n element.querySelector(`.${classSelector}`)?.remove()\n }\n\n const node = document.createElement(tag)\n if (className) {\n node.className = className\n }\n node.innerHTML = content\n\n if (atStart && element.firstChild) {\n element.insertBefore(node, element.firstChild)\n } else {\n element.appendChild(node)\n }\n\n return node\n },\n setErrors(fields) {\n if (Array.isArray(fields)) {\n manualErrors = {\n ...manualErrors,\n ...Object.fromEntries(fields.map(field => [field, ['Invalid value.']]))\n }\n } else {\n manualErrors = {\n ...manualErrors,\n ...cloneErrors(fields)\n }\n }\n\n syncVisualState(Array.isArray(fields) ? fields : Object.keys(fields))\n notifySubscribers()\n return api\n },\n clearErrors(fields) {\n if (!fields) {\n manualErrors = {}\n syncVisualState()\n notifySubscribers()\n return api\n }\n\n for (const field of fields) {\n delete manualErrors[field]\n }\n\n syncVisualState(fields)\n notifySubscribers()\n return api\n },\n setValue(name, value) {\n const fields = getFieldsByName(name)\n if (fields.length === 0) {\n return api\n }\n\n writeFieldValue(fields, value)\n const firstField = fields[0]\n if (!firstField) {\n return api\n }\n\n const eventType =\n firstField instanceof HTMLSelectElement ||\n (firstField instanceof HTMLInputElement &&\n (firstField.type === 'checkbox' || firstField.type === 'radio'))\n ? 'change'\n : 'input'\n\n firstField.dispatchEvent(new Event(eventType, { bubbles: true }))\n return api\n },\n validate(fields) {\n isValidated = true\n syncVisualState(fields)\n return validateNames(fields)\n },\n revalidate(fields) {\n return api.validate(fields)\n },\n reset() {\n if (!element) {\n return api\n }\n\n element.reset()\n manualErrors = {}\n validationErrors = {}\n clearAttributes(element, [attributes.error, attributes.filled])\n if (isValidated) {\n syncVisualState()\n }\n notifySubscribers()\n return api\n },\n autoSubmit(nextOptions = true) {\n autoSubmitEnabled = nextOptions !== false\n autoSubmitDebounce =\n typeof nextOptions === 'object' && nextOptions\n ? nextOptions.debounce ?? 0\n : 0\n notifySubscribers()\n return api\n },\n disableAutoSubmit() {\n autoSubmitEnabled = false\n if (autoSubmitTimer) {\n clearTimeout(autoSubmitTimer)\n autoSubmitTimer = null\n }\n notifySubscribers()\n return api\n },\n getValue(name) {\n return readFieldValue(getFieldsByName(name))\n },\n getField(name) {\n const fields = getFieldsByName(name)\n if (fields.length === 0) {\n return null\n }\n const [firstField] = fields\n if (!firstField) {\n return null\n }\n return fields.length === 1 ? firstField : fields\n },\n getData() {\n if (!element) {\n return { data: {}, formData: new FormData() }\n }\n return parseFormData(element)\n },\n getState() {\n const values = getValues()\n const errors = cloneErrors(getMergedErrors())\n const filledFields = getTrackedFieldNames().filter(name => {\n const value = values[name]\n return Array.isArray(value)\n ? value.length > 0\n : typeof value === 'string'\n ? value.trim().length > 0\n : value !== undefined\n })\n\n return {\n ...createEmptyFormState(),\n values,\n errors,\n filledFields,\n isValid: Object.keys(errors).length === 0,\n isValidated,\n autoSubmit: autoSubmitEnabled,\n submitCount\n }\n },\n destroy() {\n if (isDestroyed) {\n return\n }\n\n isDestroyed = true\n for (const listener of listeners) {\n listener.element.removeEventListener(listener.type, listener.handler)\n }\n listeners.length = 0\n\n if (autoSubmitTimer) {\n clearTimeout(autoSubmitTimer)\n autoSubmitTimer = null\n }\n\n mutationObserver?.disconnect()\n mutationObserver = null\n watchedFields.clear()\n subscribers.clear()\n submitHandlers.clear()\n clearFieldCache()\n manualErrors = {}\n validationErrors = {}\n }\n }\n\n if (element) {\n addListener(element, 'input', handleDelegatedEvent)\n addListener(element, 'change', handleDelegatedEvent)\n addListener(element, 'submit', handleSubmitEvent)\n startMutationObserver()\n }\n\n if (normalizedOptions.autoSubmit) {\n const autoSubmitOption = normalizedOptions.autoSubmit as boolean | AutoSubmitOptions\n api.autoSubmit(autoSubmitOption)\n }\n\n if (isValidated) {\n syncVisualState()\n validateNames()\n }\n\n return api\n}"],"mappings":"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","names":["target"]}
@@ -1,5 +1,5 @@
1
- import { S as SerializedFormResult, l as FormStateSnapshot, i as FormFieldValue, b as FieldValidationRules, o as FormValues, q as ValidationSchema, V as ValidationResult } from '../types-C0_1rYlm.cjs';
2
- export { A as AppendContentOptions, a as AutoSubmitOptions, F as FieldValidationContext, c as FieldValidator, d as FormController, e as FormControllerOptions, f as FormDataPrimitive, g as FormErrors, h as FormFieldElement, j as FormFieldWatcher, k as FormStateListener, m as FormSubmitHandler, n as FormTarget, R as RuleConfig, p as SerializedFormValue, r as VisualAttributes } from '../types-C0_1rYlm.cjs';
1
+ import { S as SerializedFormResult, l as FormStateSnapshot, i as FormFieldValue, b as FieldValidationRules, o as FormValues, q as ValidationSchema, V as ValidationResult } from '../types-jYB7Wp7C.cjs';
2
+ export { A as AppendContentOptions, a as AutoSubmitOptions, F as FieldValidationContext, c as FieldValidator, d as FormController, e as FormControllerOptions, f as FormDataPrimitive, g as FormErrors, h as FormFieldElement, j as FormFieldWatcher, k as FormStateListener, m as FormSubmitHandler, n as FormTarget, R as RuleConfig, p as SerializedFormValue, r as VisualAttributes } from '../types-jYB7Wp7C.cjs';
3
3
 
4
4
  declare const parseFormData: (formElement: HTMLFormElement) => SerializedFormResult;
5
5
 
@@ -1,5 +1,5 @@
1
- import { S as SerializedFormResult, l as FormStateSnapshot, i as FormFieldValue, b as FieldValidationRules, o as FormValues, q as ValidationSchema, V as ValidationResult } from '../types-C0_1rYlm.js';
2
- export { A as AppendContentOptions, a as AutoSubmitOptions, F as FieldValidationContext, c as FieldValidator, d as FormController, e as FormControllerOptions, f as FormDataPrimitive, g as FormErrors, h as FormFieldElement, j as FormFieldWatcher, k as FormStateListener, m as FormSubmitHandler, n as FormTarget, R as RuleConfig, p as SerializedFormValue, r as VisualAttributes } from '../types-C0_1rYlm.js';
1
+ import { S as SerializedFormResult, l as FormStateSnapshot, i as FormFieldValue, b as FieldValidationRules, o as FormValues, q as ValidationSchema, V as ValidationResult } from '../types-jYB7Wp7C.js';
2
+ export { A as AppendContentOptions, a as AutoSubmitOptions, F as FieldValidationContext, c as FieldValidator, d as FormController, e as FormControllerOptions, f as FormDataPrimitive, g as FormErrors, h as FormFieldElement, j as FormFieldWatcher, k as FormStateListener, m as FormSubmitHandler, n as FormTarget, R as RuleConfig, p as SerializedFormValue, r as VisualAttributes } from '../types-jYB7Wp7C.js';
3
3
 
4
4
  declare const parseFormData: (formElement: HTMLFormElement) => SerializedFormResult;
5
5
 
package/dist/index.cjs CHANGED
@@ -268,6 +268,7 @@ var DEFAULT_ATTRIBUTES = {
268
268
  };
269
269
  var DEFAULT_OPTIONS = {
270
270
  autoValidate: true,
271
+ clearManualErrorsOnChange: true,
271
272
  clearErrorsOnSubmit: true
272
273
  };
273
274
  var mergeErrors = (left, right) => {
@@ -415,6 +416,9 @@ var createFormController = (target, options = {}) => {
415
416
  return;
416
417
  }
417
418
  clearFieldCache();
419
+ if (normalizedOptions.clearManualErrorsOnChange) {
420
+ delete manualErrors[name];
421
+ }
418
422
  syncVisualState([name]);
419
423
  if (isValidated && validators[name]) {
420
424
  validateNames([name]);