@conform-to/dom
Advanced tools
Comparing version 1.1.5 to 1.2.0
343
form.d.ts
import { getFormAction, getFormEncType, getFormMethod } from './dom'; | ||
import { | ||
type Intent, | ||
type Submission, | ||
type SubmissionResult, | ||
} from './submission'; | ||
type BaseCombine< | ||
T, | ||
K extends PropertyKey = T extends unknown ? keyof T : never, | ||
> = T extends unknown ? T & Partial<Record<Exclude<K, keyof T>, never>> : never; | ||
import { type Intent, type Submission, type SubmissionResult } from './submission'; | ||
type BaseCombine<T, K extends PropertyKey = T extends unknown ? keyof T : never> = T extends unknown ? T & Partial<Record<Exclude<K, keyof T>, never>> : never; | ||
export type Combine<T> = { | ||
[K in keyof BaseCombine<T>]: BaseCombine<T>[K]; | ||
[K in keyof BaseCombine<T>]: BaseCombine<T>[K]; | ||
}; | ||
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> | ||
? | ||
| { | ||
[Key in keyof Schema]?: DefaultValue<Schema[Key]>; | ||
} | ||
| null | ||
| undefined | ||
: string | null | undefined; | ||
export type FormValue<Schema> = Schema extends | ||
| string | ||
| number | ||
| boolean | ||
| Date | ||
| bigint | ||
| null | ||
| undefined | ||
? string | undefined | ||
: Schema extends File | ||
? File | undefined | ||
: Schema extends File[] | ||
? File | Array<File> | undefined | ||
: Schema extends Array<infer Item> | ||
? string | Array<FormValue<Item>> | undefined | ||
: Schema extends Record<string, any> | ||
? | ||
| { | ||
[Key in keyof Schema]?: FormValue<Schema[Key]>; | ||
} | ||
| null | ||
| undefined | ||
: unknown; | ||
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> ? { | ||
[Key in keyof Schema]?: DefaultValue<Schema[Key]>; | ||
} | null | undefined : string | null | undefined; | ||
export type FormValue<Schema> = Schema extends string | number | boolean | Date | bigint | null | undefined ? string | undefined : Schema extends File ? File | undefined : Schema extends File[] ? File | Array<File> | undefined : Schema extends Array<infer Item> ? string | Array<FormValue<Item>> | undefined : Schema extends Record<string, any> ? { | ||
[Key in keyof Schema]?: FormValue<Schema[Key]>; | ||
} | undefined : unknown; | ||
declare const error: unique symbol; | ||
declare const field: unique symbol; | ||
declare const form: unique symbol; | ||
export type FormId< | ||
Schema extends Record<string, unknown> = Record<string, unknown>, | ||
Error = string[], | ||
> = string & { | ||
[error]?: Error; | ||
[form]?: Schema; | ||
export type FormId<Schema extends Record<string, unknown> = Record<string, unknown>, Error = string[]> = string & { | ||
[error]?: Error; | ||
[form]?: Schema; | ||
}; | ||
export type FieldName< | ||
FieldSchema, | ||
FormSchema extends Record<string, unknown> = Record<string, unknown>, | ||
Error = string[], | ||
> = string & { | ||
[field]?: FieldSchema; | ||
[error]?: Error; | ||
[form]?: FormSchema; | ||
export type FieldName<FieldSchema, FormSchema extends Record<string, unknown> = Record<string, unknown>, Error = string[]> = string & { | ||
[field]?: FieldSchema; | ||
[error]?: Error; | ||
[form]?: FormSchema; | ||
}; | ||
export type Constraint = { | ||
required?: boolean; | ||
minLength?: number; | ||
maxLength?: number; | ||
min?: string | number; | ||
max?: string | number; | ||
step?: string | number; | ||
multiple?: boolean; | ||
pattern?: string; | ||
required?: boolean; | ||
minLength?: number; | ||
maxLength?: number; | ||
min?: string | number; | ||
max?: string | number; | ||
step?: string | number; | ||
multiple?: boolean; | ||
pattern?: string; | ||
}; | ||
export type FormMeta<FormError> = { | ||
formId: string; | ||
isValueUpdated: boolean; | ||
submissionStatus?: 'error' | 'success'; | ||
defaultValue: Record<string, unknown>; | ||
initialValue: Record<string, unknown>; | ||
value: Record<string, unknown>; | ||
error: Record<string, FormError>; | ||
constraint: Record<string, Constraint>; | ||
key: Record<string, string | undefined>; | ||
validated: Record<string, boolean>; | ||
formId: string; | ||
isValueUpdated: boolean; | ||
submissionStatus?: 'error' | 'success'; | ||
defaultValue: Record<string, unknown>; | ||
initialValue: Record<string, unknown>; | ||
value: Record<string, unknown>; | ||
error: Record<string, FormError>; | ||
constraint: Record<string, Constraint>; | ||
key: Record<string, string | undefined>; | ||
validated: Record<string, boolean>; | ||
}; | ||
export type FormState<FormError> = Omit< | ||
FormMeta<FormError>, | ||
'formId' | 'isValueUpdated' | ||
> & { | ||
valid: Record<string, boolean>; | ||
dirty: Record<string, boolean>; | ||
export type FormState<FormError> = Omit<FormMeta<FormError>, 'formId' | 'isValueUpdated'> & { | ||
valid: Record<string, boolean>; | ||
dirty: Record<string, boolean>; | ||
}; | ||
export type FormOptions<Schema, FormError = string[], FormValue = Schema> = { | ||
/** | ||
* The id of the form. | ||
*/ | ||
formId: string; | ||
/** | ||
* An object representing the initial value of the form. | ||
*/ | ||
defaultValue?: DefaultValue<Schema>; | ||
/** | ||
* An object describing the constraint of each field | ||
*/ | ||
constraint?: Record<string, Constraint>; | ||
/** | ||
* An object describing the result of the last submission | ||
*/ | ||
lastResult?: SubmissionResult<FormError> | null | undefined; | ||
/** | ||
* Define when conform should start validation. | ||
* Support "onSubmit", "onInput", "onBlur". | ||
* | ||
* @default "onSubmit" | ||
*/ | ||
shouldValidate?: 'onSubmit' | 'onBlur' | 'onInput'; | ||
/** | ||
* Define when conform should revalidate again. | ||
* Support "onSubmit", "onInput", "onBlur". | ||
* | ||
* @default Same as shouldValidate, or "onSubmit" if shouldValidate is not provided. | ||
*/ | ||
shouldRevalidate?: 'onSubmit' | 'onBlur' | 'onInput'; | ||
/** | ||
* Define if conform should considered the field for dirty state. | ||
* e.g. Excluding form fields that are not managed by Conform, such as CSRF token | ||
*/ | ||
shouldDirtyConsider?: (name: string) => boolean; | ||
/** | ||
* A function to be called when the form should be (re)validated. | ||
*/ | ||
onValidate?: (context: { | ||
form: HTMLFormElement; | ||
submitter: HTMLInputElement | HTMLButtonElement | null; | ||
formData: FormData; | ||
}) => Submission<Schema, FormError, FormValue>; | ||
/** | ||
* The id of the form. | ||
*/ | ||
formId: string; | ||
/** | ||
* An object representing the initial value of the form. | ||
*/ | ||
defaultValue?: DefaultValue<Schema>; | ||
/** | ||
* An object describing the constraint of each field | ||
*/ | ||
constraint?: Record<string, Constraint>; | ||
/** | ||
* An object describing the result of the last submission | ||
*/ | ||
lastResult?: SubmissionResult<FormError> | null | undefined; | ||
/** | ||
* Define when conform should start validation. | ||
* Support "onSubmit", "onInput", "onBlur". | ||
* | ||
* @default "onSubmit" | ||
*/ | ||
shouldValidate?: 'onSubmit' | 'onBlur' | 'onInput'; | ||
/** | ||
* Define when conform should revalidate again. | ||
* Support "onSubmit", "onInput", "onBlur". | ||
* | ||
* @default Same as shouldValidate, or "onSubmit" if shouldValidate is not provided. | ||
*/ | ||
shouldRevalidate?: 'onSubmit' | 'onBlur' | 'onInput'; | ||
/** | ||
* Define if conform should considered the field for dirty state. | ||
* e.g. Excluding form fields that are not managed by Conform, such as CSRF token | ||
*/ | ||
shouldDirtyConsider?: (name: string) => boolean; | ||
/** | ||
* A function to be called when the form should be (re)validated. | ||
*/ | ||
onValidate?: (context: { | ||
form: HTMLFormElement; | ||
submitter: HTMLInputElement | HTMLButtonElement | null; | ||
formData: FormData; | ||
}) => Submission<Schema, FormError, FormValue>; | ||
}; | ||
export type SubscriptionSubject = { | ||
[key in | ||
| 'error' | ||
| 'initialValue' | ||
| 'value' | ||
| 'key' | ||
| 'valid' | ||
| 'dirty']?: SubscriptionScope; | ||
[key in 'error' | 'initialValue' | 'value' | 'key' | 'valid' | 'dirty']?: SubscriptionScope; | ||
} & { | ||
formId?: boolean; | ||
status?: boolean; | ||
formId?: boolean; | ||
status?: boolean; | ||
}; | ||
export type SubscriptionScope = { | ||
prefix?: string[]; | ||
name?: string[]; | ||
prefix?: string[]; | ||
name?: string[]; | ||
}; | ||
export type ControlButtonProps = { | ||
name: string; | ||
value: string; | ||
form: string; | ||
formNoValidate: boolean; | ||
name: string; | ||
value: string; | ||
form: string; | ||
formNoValidate: boolean; | ||
}; | ||
export type FormContext< | ||
Schema extends Record<string, any> = any, | ||
FormError = string[], | ||
FormValue = Schema, | ||
> = { | ||
getFormId(): string; | ||
submit(event: SubmitEvent): { | ||
formData: FormData; | ||
action: ReturnType<typeof getFormAction>; | ||
encType: ReturnType<typeof getFormEncType>; | ||
method: ReturnType<typeof getFormMethod>; | ||
submission?: Submission<Schema, FormError, FormValue>; | ||
}; | ||
onReset(event: Event): void; | ||
onInput(event: Event): void; | ||
onBlur(event: Event): void; | ||
onUpdate(options: Partial<FormOptions<Schema, FormError, FormValue>>): void; | ||
observe(): () => void; | ||
subscribe( | ||
callback: () => void, | ||
getSubject?: () => SubscriptionSubject | undefined, | ||
): () => void; | ||
getState(): FormState<FormError>; | ||
getSerializedState(): string; | ||
export type FormContext<Schema extends Record<string, any> = any, FormError = string[], FormValue = Schema> = { | ||
getFormId(): string; | ||
submit(event: SubmitEvent): { | ||
formData: FormData; | ||
action: ReturnType<typeof getFormAction>; | ||
encType: ReturnType<typeof getFormEncType>; | ||
method: ReturnType<typeof getFormMethod>; | ||
submission?: Submission<Schema, FormError, FormValue>; | ||
}; | ||
onReset(event: Event): void; | ||
onInput(event: Event): void; | ||
onBlur(event: Event): void; | ||
onUpdate(options: Partial<FormOptions<Schema, FormError, FormValue>>): void; | ||
observe(): () => void; | ||
subscribe(callback: () => void, getSubject?: () => SubscriptionSubject | undefined): () => void; | ||
getState(): FormState<FormError>; | ||
getSerializedState(): string; | ||
} & { | ||
[Type in Intent['type']]: {} extends Extract< | ||
Intent, | ||
{ | ||
type: Type; | ||
} | ||
>['payload'] | ||
? (<FieldSchema = Schema>( | ||
payload?: Extract< | ||
Intent<FieldSchema>, | ||
{ | ||
type: Type; | ||
} | ||
>['payload'], | ||
) => void) & { | ||
getButtonProps<FieldSchema = Schema>( | ||
payload?: Extract< | ||
Intent<FieldSchema>, | ||
{ | ||
type: Type; | ||
} | ||
>['payload'], | ||
): ControlButtonProps; | ||
} | ||
: (<FieldSchema = Schema>( | ||
payload: Extract< | ||
Intent<FieldSchema>, | ||
{ | ||
type: Type; | ||
} | ||
>['payload'], | ||
) => void) & { | ||
getButtonProps<FieldSchema = Schema>( | ||
payload: Extract< | ||
Intent<FieldSchema>, | ||
{ | ||
type: Type; | ||
} | ||
>['payload'], | ||
): ControlButtonProps; | ||
}; | ||
[Type in Intent['type']]: {} extends Extract<Intent, { | ||
type: Type; | ||
}>['payload'] ? (<FieldSchema = Schema>(payload?: Extract<Intent<FieldSchema>, { | ||
type: Type; | ||
}>['payload']) => void) & { | ||
getButtonProps<FieldSchema = Schema>(payload?: Extract<Intent<FieldSchema>, { | ||
type: Type; | ||
}>['payload']): ControlButtonProps; | ||
} : (<FieldSchema = Schema>(payload: Extract<Intent<FieldSchema>, { | ||
type: Type; | ||
}>['payload']) => void) & { | ||
getButtonProps<FieldSchema = Schema>(payload: Extract<Intent<FieldSchema>, { | ||
type: Type; | ||
}>['payload']): ControlButtonProps; | ||
}; | ||
}; | ||
export declare function createFormContext< | ||
Schema extends Record<string, any>, | ||
FormError = string[], | ||
FormValue = Schema, | ||
>( | ||
options: FormOptions<Schema, FormError, FormValue>, | ||
): FormContext<Schema, FormError, FormValue>; | ||
export declare function createFormContext<Schema extends Record<string, any>, FormError = string[], FormValue = Schema>(options: FormOptions<Schema, FormError, FormValue>): FormContext<Schema, FormError, FormValue>; | ||
export {}; |
12
form.js
@@ -25,5 +25,3 @@ 'use strict'; | ||
validated: (_lastResult$state$val = lastResult === null || lastResult === void 0 || (_lastResult$state = lastResult.state) === null || _lastResult$state === void 0 ? void 0 : _lastResult$state.validated) !== null && _lastResult$state$val !== void 0 ? _lastResult$state$val : {}, | ||
key: !initialized ? getDefaultKey(defaultValue) : _rollupPluginBabelHelpers.objectSpread2({ | ||
'': util.generateId() | ||
}, getDefaultKey(defaultValue)), | ||
key: getDefaultKey(defaultValue), | ||
// The `lastResult` should comes from the server which we won't expect the error to be null | ||
@@ -47,3 +45,5 @@ // We can consider adding a warning if it happens | ||
return result; | ||
}, {}); | ||
}, { | ||
[prefix !== null && prefix !== void 0 ? prefix : '']: util.generateId() | ||
}); | ||
} | ||
@@ -152,5 +152,3 @@ function setFieldsValidated(meta, fields) { | ||
meta.value = value; | ||
meta.key = _rollupPluginBabelHelpers.objectSpread2(_rollupPluginBabelHelpers.objectSpread2({}, getDefaultKey(value)), {}, { | ||
'': util.generateId() | ||
}); | ||
meta.key = getDefaultKey(value); | ||
return; | ||
@@ -157,0 +155,0 @@ } |
@@ -6,3 +6,3 @@ { | ||
"license": "MIT", | ||
"version": "1.1.5", | ||
"version": "1.2.0", | ||
"main": "index.js", | ||
@@ -9,0 +9,0 @@ "module": "index.mjs", |
@@ -5,5 +5,8 @@ import type { DefaultValue, FieldName, FormValue } from './form'; | ||
}; | ||
export type SubmissionPayload<Entry extends FormDataEntryValue> = Entry | SubmissionPayload<Entry>[] | { | ||
[key: string]: SubmissionPayload<Entry>; | ||
}; | ||
export type SubmissionContext<Value = null, FormError = string[]> = { | ||
intent: Intent | null; | ||
payload: Record<string, unknown>; | ||
payload: Record<string, SubmissionPayload<FormDataEntryValue>>; | ||
fields: Set<string>; | ||
@@ -16,3 +19,3 @@ value?: Value; | ||
status: 'success'; | ||
payload: Record<string, unknown>; | ||
payload: Record<string, SubmissionPayload<FormDataEntryValue>>; | ||
value: FormValue; | ||
@@ -22,3 +25,3 @@ reply(options?: ReplyOptions<FormError>): SubmissionResult<FormError>; | ||
status: 'error' | undefined; | ||
payload: Record<string, unknown>; | ||
payload: Record<string, SubmissionPayload<FormDataEntryValue>>; | ||
error: Record<string, FormError | null> | null; | ||
@@ -30,3 +33,3 @@ reply(options?: ReplyOptions<FormError>): SubmissionResult<FormError>; | ||
intent?: Intent; | ||
initialValue?: Record<string, unknown> | null; | ||
initialValue?: Record<string, SubmissionPayload<string>> | null; | ||
fields?: string[]; | ||
@@ -33,0 +36,0 @@ error?: Record<string, FormError | null>; |
@@ -118,3 +118,3 @@ 'use strict'; | ||
function replySubmission(context) { | ||
var _context$intent, _context$intent$paylo, _options$formErrors, _normalize; | ||
var _context$intent, _context$intent$paylo, _options$formErrors, _ref; | ||
var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}; | ||
@@ -138,8 +138,13 @@ if ('resetForm' in options && options.resetForm || ((_context$intent = context.intent) === null || _context$intent === void 0 ? void 0 : _context$intent.type) === 'reset' && ((_context$intent$paylo = context.intent.payload.name) !== null && _context$intent$paylo !== void 0 ? _context$intent$paylo : '') === '') { | ||
var error = context.error || extraError ? _rollupPluginBabelHelpers.objectSpread2(_rollupPluginBabelHelpers.objectSpread2({}, context.error), extraError) : undefined; | ||
var initialValue = (_ref = formdata.normalize(context.payload, | ||
// We can't serialize the file and send it back from the server, but we can preserve it in the client | ||
typeof document !== 'undefined' | ||
// We need the file on the client because it's treated as the form value | ||
// But we will exclude the File type for now as it's only used by the internal | ||
// form state and we will remove the need to preserve the file on the client soon | ||
)) !== null && _ref !== void 0 ? _ref : {}; | ||
return { | ||
status: context.intent ? undefined : error ? 'error' : 'success', | ||
intent: context.intent ? context.intent : undefined, | ||
initialValue: (_normalize = formdata.normalize(context.payload, | ||
// We can't serialize the file and send it back from the server, but we can preserve it in the client | ||
typeof document !== 'undefined')) !== null && _normalize !== void 0 ? _normalize : {}, | ||
initialValue, | ||
error, | ||
@@ -214,5 +219,5 @@ state: context.state, | ||
var _loop2 = function _loop2() { | ||
var value = state[key]; | ||
if (formdata.isPrefix(key, name) && key !== name) { | ||
formdata.setValue(target, key, currentValue => { | ||
var value = state[_key]; | ||
if (formdata.isPrefix(_key, name) && _key !== name) { | ||
formdata.setValue(target, _key, currentValue => { | ||
if (typeof currentValue === 'undefined') { | ||
@@ -231,6 +236,6 @@ return value; | ||
// Remove the value from the data | ||
delete state[key]; | ||
delete state[_key]; | ||
} | ||
}; | ||
for (var key of keys) { | ||
for (var _key of keys) { | ||
_loop2(); | ||
@@ -273,4 +278,4 @@ } | ||
// @ts-expect-error FIXME | ||
return Object.entries(defaultValue).reduce((result, _ref) => { | ||
var [key, value] = _ref; | ||
return Object.entries(defaultValue).reduce((result, _ref2) => { | ||
var [key, value] = _ref2; | ||
result[key] = serialize(value); | ||
@@ -277,0 +282,0 @@ return result; |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
124139
3404