GPT that shiz

This commit is contained in:
Tanner Linsley
2023-04-24 23:58:54 -06:00
parent 4b067e2ee4
commit a4fa4f0da8
17 changed files with 599 additions and 37 deletions

View File

@@ -6,40 +6,62 @@
}, },
"menu": [ "menu": [
{ {
"framework": "react", "framework": "core",
"menuItems": [ "menuItems": [
{ {
"label": "Getting Started", "label": "Getting Started",
"children": [ "children": [
{ {
"label": "Overview", "label": "Overview",
"to": "react/overview" "to": "core/overview"
}, },
{ {
"label": "Installation", "label": "Installation",
"to": "react/installation" "to": "core/installation"
}, },
{ {
"label": "Quick Start", "label": "Comparison",
"to": "react/quick-start" "to": "core/comparison"
},
{
"label": "TypeScript",
"to": "core/typescript"
} }
] ]
}, },
{ {
"label": "Guides & Concepts", "label": "Guides",
"children": [ "children": [
{ {
"label": "Important Defaults", "label": "Important Defaults",
"to": "react/guides/important-defaults" "to": "core/guides/important-defaults"
} }
] ]
}, },
{ {
"label": "Examples", "label": "API Reference",
"children": [ "children": [
{ {
"label": "Simple", "label": "FormApi",
"to": "react/examples/react/simple" "to": "core/reference/formApi"
},
{
"label": "FieldApi",
"to": "core/reference/fieldApi"
}
]
}
]
},
{
"framework": "react",
"menuItems": [
{
"label": "Getting Started",
"children": [
{
"label": "Quick Start",
"to": "react/quick-start"
} }
] ]
}, },
@@ -49,6 +71,27 @@
{ {
"label": "useForm", "label": "useForm",
"to": "react/reference/useForm" "to": "react/reference/useForm"
},
{
"label": "useField",
"to": "react/reference/useField"
},
{
"label": "Field",
"to": "react/reference/Field"
},
{
"label": "FormApi",
"to": "react/reference/formApi"
}
]
},
{
"label": "Examples",
"children": [
{
"label": "Simple",
"to": "react/examples/simple"
} }
] ]
} }

View File

@@ -0,0 +1,139 @@
---
id: fieldApi
title: Field API
---
### Creating a new FieldApi Instance
Normally, you will not need to create a new `FieldApi` instance directly. Instead, you will use a framework hook/function like `useField` or `createField` to create a new instance for you that utilizes your frameworks reactivity model. However, if you need to create a new instance manually, you can do so by calling the `new FieldApi` constructor.
```tsx
const fieldApi: FieldApi<TData> = new FieldApi(formOptions: Field Options<TData>)
```
### `FieldOptions<TData, TFormData>`
An object type representing the options for a field in a form.
- `name`
- The field name. If `TFormData` is `unknown`, the type will be `string`. Otherwise, it will be `DeepKeys<TFormData>`.
- `defaultValue?: TData`
- An optional default value for the field.
- `form?: FormApi<TFormData>`
- An optional reference to the form API instance.
- `validate?: (value: TData, fieldApi: FieldApi<TData, TFormData>) => ValidationError | Promise<ValidationError>`
- An optional validation function for the field.
- `validatePristine?: boolean`
- An optional flag indicating whether to validate the field when it is pristine (untouched).
- `filterValue?: (value: TData) => TData`
- An optional function to filter the field value before setting it in the form state.
- `defaultMeta?: Partial<FieldMeta>`
- An optional object with default metadata for the field.
- `validateOn?: 'change' | 'blur' | 'change-blur' | 'change-submit' | 'blur-submit' | 'submit'`
- An optional string indicating when to perform field validation.
### `FieldMeta`
An object type representing the metadata of a field in a form.
- `isTouched: boolean`
- A flag indicating whether the field has been touched.
- `touchedError?: ValidationError`
- An optional error related to the touched state of the field.
- `error?: ValidationError`
- An optional error related to the field value.
- `isValidating: boolean`
- A flag indicating whether the field is currently being validated.
### `FieldApiOptions<TData, TFormData>`
An object type representing the required options for the `FieldApi` class.
- Inherits from `FieldOptions<TData, TFormData>` with the `form` property set as required.
### `FieldApi<TData, TFormData>`
A class representing the API for managing a form field.
#### Properties
- `uid: number`
- A unique identifier for the field instance.
- `form: FormApi<TFormData>`
- A reference to the form API instance.
- `name: DeepKeys<TFormData>`
- The field name.
- `store: Store<FieldState<TData>>`
- The field state store.
- `state: FieldState<TData>`
- The current field state.
- `options: RequiredByKey<FieldOptions<TData, TFormData>, 'validateOn'>`
- The field options with the `validateOn` property set as required.
#### Methods
- `constructor(opts: FieldApiOptions<TData, TFormData>)`
- Initializes a new `FieldApi` instance.
- `mount(): () => void`
- Mounts the field instance to the form.
- `updateStore(): void`
- Updates the field store with the latest form state.
- `update(opts: FieldApiOptions<TData, TFormData>): void`
- Updates the field instance with new options.
- `getValue(): TData`
- Gets the current field value.
- `setValue(updater: Updater<TData>, options?: { touch?: boolean; notify?: boolean }): void`
- Sets the field value.
- `getMeta(): FieldMeta`
- Gets the current field metadata.
- `setMeta(updater: Updater<FieldMeta>): void`
- Sets the field metadata.
- `getInfo(): any`
- Gets the field information object.
- `pushValue(value: TData): void`
- Pushes a new value to the field.
- `insertValue(index: number, value: TData): void`
- Inserts a value at the specified index.
- `removeValue(index: number): void`
- Removes a value at the specified index.
- `swapValues(aIndex: number, bIndex: number): void`
- Swaps the values at the specified indices.
- `getSubField<TName extends DeepKeys<TData>>(name: TName): FieldApi<DeepValue<TData, TName>, TFormData>`
- Gets a subfield instance.
- `validate(): Promise<any>`
- Validates the field value.
- `getChangeProps<T extends ChangeProps<any>>(props: T = {} as T): ChangeProps<TData> & Omit<T, keyof ChangeProps<TData>>`
- Gets the change and blur event handlers.
- `getInputProps<T extends InputProps>(props: T = {} as T): InputProps & Omit<T, keyof InputProps>`
- Gets the input event handlers.
### `FieldState<TData>`
An object type representing the state of a field.
- `value: TData`
- The current value of the field.
- `meta: FieldMeta`
- The current metadata of the field.
### `ChangeProps<TData>`
An object type representing the change and blur event handlers for a field.
- `value: TData`
- The current value of the field.
- `onChange: (updater: Updater<TData>) => void`
- A function to handle the change event.
- `onBlur: (event: any) => void`
- A function to handle the blur event.
### `InputProps`
An object type representing the input event handlers for a field.
- `value: string`
- The current value of the field, coerced to a string.
- `onChange: (event: any) => void`
- A function to handle the change event.
- `onBlur: (event: any) => void`
- A function to handle the blur event.

View File

@@ -0,0 +1,150 @@
---
id: formApi
title: Form API
---
### Creating a new FormApi Instance
Normally, you will not need to create a new `FormApi` instance directly. Instead, you will use a framework hook/function like `useForm` or `createForm` to create a new instance for you that utilizes your frameworks reactivity model. However, if you need to create a new instance manually, you can do so by calling the `new FormApi` constructor.
```tsx
const formApi: FormApi<TData> = new FormApi(formOptions: FormOptions<TData>)
```
### `FormOptions<TData>`
An object representing the options for a form.
- `defaultValues?: TData`
- The default values for the form fields.
- `defaultState?: Partial<FormState<TData>>`
- The default state for the form.
- `onSubmit?: (values: TData, formApi: FormApi<TData>) => Promise<any>`
- A function to be called when the form is submitted and valid.
- `onInvalidSubmit?: (values: TData, formApi: FormApi<TData>) => void`
- A function to be called when the form is submitted but invalid.
- `validate?: (values: TData, formApi: FormApi<TData>) => Promise<any>`
- A function for custom validation logic for the form.
- `debugForm?: boolean`
- A boolean flag to enable or disable form debugging.
- `validatePristine?: boolean`
- A boolean flag to enable or disable validation for pristine fields.
### `FormApi<TFormData>`
A class representing the Form API. It handles the logic and interactions with the form state.
#### Properties
- `options: FormOptions<TFormData>`
- The options for the form.
- `store: Store<FormState<TFormData>>`
- The internal store for the form state.
- `state: FormState<TFormData>`
- The current state of the form.
- `fieldInfo: Record<DeepKeys<TFormData>, FieldInfo<TFormData>>`
- A record of field information for each field in the form.
- `fieldName?: string`
- An optional string representing the name of the field.
- `validationMeta: ValidationMeta`
- The validation metadata for the form.
#### Methods
- `constructor(opts?: FormOptions<TFormData>)`
- Constructs a new `FormApi` instance with the given form options.
- `update(options: FormOptions<TFormData>)`
- Updates the form options and form state.
- `reset()`
- Resets the form state to the default values.
- `validateAllFields()`
- Validates all fields in the form.
- `validateForm()`
- Validates the form itself.
- `handleSubmit(e: FormEvent & { __handled?: boolean })`
- Handles the form submission event, performs validation, and calls the appropriate onSubmit or onInvalidSubmit callbacks.
- `getFieldValue<TField extends DeepKeys<TFormData>>(field: TField)`
- Gets the value of the specified field.
- `getFieldMeta<TField extends DeepKeys<TFormData>>(field: TField)`
- Gets the metadata of the specified field.
- `getFieldInfo<TField extends DeepKeys<TFormData>>(field: TField)`
- Gets the field info of the specified field.
- `setFieldMeta<TField extends DeepKeys<TFormData>>(field: TField, updater: Updater<FieldMeta>)
- Updates the metadata of the specified field.
- `setFieldValue<TField extends DeepKeys<TFormData>>(field: TField, updater: Updater<DeepValue<TFormData, TField>>, opts?: { touch?: boolean })
- Sets the value of the specified field and optionally updates the touched state.
- `pushFieldValue<TField extends DeepKeys<TFormData>>(field: TField, value: DeepValue<TFormData, TField>, opts?: { touch?: boolean })
- Pushes a value into an array field.
- `insertFieldValue<TField extends DeepKeys<TFormData>>(field: TField, index: number, value: DeepValue<TFormData, TField>, opts?: { touch?: boolean })
- Inserts a value into an array field at the specified index.
- `spliceFieldValue<TField extends DeepKeys<TFormData>>(field: TField, index: number, opts?: { touch?: boolean })
- Removes a value from an array field at the specified index.
- `swapFieldValues<TField extends DeepKeys<TFormData>>(field: TField, index1: number, index2: number)
- Swaps the values at the specified indices within an array field.
### `FormState<TData>`
An object representing the current state of the form.
- `values: TData`
- The current values of the form fields.
- `isFormValidating: boolean`
- A boolean indicating if the form is currently validating.
- `formValidationCount: number`
- A counter for tracking the number of validations performed on the form.
- `isFormValid: boolean`
- A boolean indicating if the form is valid.
- `formError?: ValidationError`
- A possible validation error for the form.
- `fieldMeta: Record<DeepKeys<TData>, FieldMeta>`
- A record of field metadata for each field in the form.
- `isFieldsValidating: boolean`
- A boolean indicating if any of the form fields are currently validating.
- `isFieldsValid: boolean`
- A boolean indicating if all the form fields are valid.
- `isSubmitting: boolean`
- A boolean indicating if the form is currently submitting.
- `isTouched: boolean`
- A boolean indicating if any of the form fields have been touched.
- `isSubmitted: boolean`
- A boolean indicating if the form has been submitted.
- `isValidating: boolean`
- A boolean indicating if the form or any of its fields are currently validating.
- `isValid: boolean`
- A boolean indicating if the form and all its fields are valid.
- `canSubmit: boolean`
- A boolean indicating if the form can be submitted based on its current state.
- `submissionAttempts: number`
- A counter for tracking the number of submission attempts.
### `FieldInfo<TFormData>`
An object representing the field information for a specific field within the form.
- `instances: Record<string, FieldApi<any, TFormData>>`
- A record of field instances with unique identifiers as keys.
- `validationCount?: number`
- A counter for tracking the number of validations performed on the field.
- `validationPromise?: Promise<ValidationError>`
- A promise representing the current validation state of the field.
- `validationResolve?: (error: ValidationError) => void`
- A function to resolve the validation promise with a possible validation error.
- `validationReject?: (error: unknown) => void`
- A function to reject the validation promise with an error.
### `ValidationMeta`
An object representing the validation metadata for a field.
- `validationCount?: number`
- A counter for tracking the number of validations performed on the field.
- `validationPromise?: Promise<ValidationError>`
- A promise representing the current validation state of the field.
- `validationResolve?: (error: ValidationError) => void`
- A function to resolve the validation promise with a possible validation error.
- `validationReject?: (error: unknown) => void`
- A function to reject the validation promise with an error.
### `ValidationError`
A type representing a validation error. Possible values are `undefined`, `false`, `null`, or a `string` with an error message.

View File

@@ -0,0 +1,54 @@
---
id: field
title: Field
---
### `type FieldComponent<TFormData>`
A type alias representing a field component for a specific form data type.
```tsx
export type FieldComponent = <TField extends DeepKeys<TFormData>>({
children,
...fieldOptions
}: {
children: (fieldApi: FieldApi<DeepValue<TFormData, TField>, TFormData>) => any
name: TField
} & Omit<FieldOptions<DeepValue<TFormData, TField>, TFormData>, 'name'>) => any
```
A function component that takes field options and a render function as children and returns a React component.
### `Field`
```tsx
export function Field<TData, TFormData>({
children,
...fieldOptions
}: { children: (fieldApi: FieldApi<TData, TFormData>) => any } & FieldOptions<
TData,
TFormData
>): any
```
A functional React component that renders a form field.
- `children: (fieldApi: FieldApi<TData, TFormData>) => any`
- A render function that takes a field API instance and returns a React element.
- `fieldOptions: FieldOptions<TData, TFormData>`
- The field options.
The `Field` component uses the `useField` hook internally to manage the field instance.
### `createFieldComponent`
```tsx
export function createFieldComponent<TFormData>(
formApi: FormApi<TFormData>,
): FieldComponent<TFormData>
```
A factory function that creates a connected field component for a specific form API instance.
- `formApi: FormApi<TFormData>`
- The form API instance to connect the field component to.

View File

@@ -0,0 +1,19 @@
---
id: formApi
title: Form API
---
### `FormApi<TFormData>`
When using `@tanstack/react-form`, the [core form API](../../core//reference/formApi.md) is extended with additional methods for React-specific functionality:
- `Form: FormComponent`
- A pre-bound and type-safe form component, specific to this forms instance.
- `Field: FieldComponent<TFormData>`
- A pre-bound and type-safe field component, specific to this forms instance.
- `useField: UseField<TFormData>`
- A pre-bound and type-safe custom hook to use fields from this form instance.
- `useStore<TSelected = NoInfer<FormState<TFormData>>>(selector?: (state: NoInfer<FormState<TFormData>>) => TSelected): TSelected`
- A custom hook to use the form store.
- `Subscribe<TSelected = NoInfer<FormState<TFormData>>>(props: {selector?: (state: NoInfer<FormState<TFormData>>) => TSelected; children: ((state: NoInfer<TSelected>) => React.ReactNode) | React.ReactNode}): any`
- A subscription component to provide the selected form state to children.

View File

@@ -0,0 +1,47 @@
---
id: useField
title: useField
---
### `UseField<TFormData>`
A type representing a hook for using a field in a form with the given form data type.
```tsx
export type UseField = <TField extends DeepKeys<TFormData>>(
opts?: { name: TField } & FieldOptions<
DeepValue<TFormData, TField>,
TFormData
>,
) => FieldApi<DeepValue<TFormData, TField>, TFormData>
```
- A function that takes an optional object with a `name` property and field options, and returns a `FieldApi` instance for the specified field.
### `useField`
```tsx
export function useField<TData, TFormData>(
opts: FieldOptions<TData, TFormData>,
): FieldApi<TData, TFormData>
```
A hook for managing a field in a form.
- `opts: FieldOptions<TData, TFormData>`
- An object with field options.
#### Returns
- `FieldApi<TData, TFormData>`
- `FieldApi` instance for the specified field.
### `createUseField`
```tsx
export function createUseField<TFormData>(
formApi: FormApi<TFormData>,
): UseField<TFormData>
```
A function that creates a `UseField` hook bound to the given `formApi`.

View File

@@ -3,10 +3,43 @@ id: useForm
title: useForm title: useForm
--- ---
### `useForm`
```tsx ```tsx
const {} = useForm({}) export function useForm<TData>(
opts?: FormOptions<TData> & { listen?: (state: FormState<TData>) => any },
): FormApi<TData>
``` ```
**Options** A custom hook that returns an instance of the `FormApi<TData>` class.
**Returns** - `opts`
- Optional form options and a `listen` function to be called with the form state.
### `FormProps`
An object type representing the form component props.
- Inherits from `React.HTMLProps<HTMLFormElement>`.
- `children: React.ReactNode`
- The form's child elements.
- `noFormElement?: boolean`
- If true, the form component will not render an HTML form element.
### `FormComponent`
A type representing a form component.
- `(props: FormProps) => any`
- A function that takes `FormProps` as an argument and returns a form component.
### `createFormComponent`
```tsx
export function createFormComponent(formApi: FormApi<any>): FormComponent
```
A function that creates a form component with the provided form API instance.
- `formApi`
- An instance of the `FormApi<any>` class.

View File

@@ -8,10 +8,11 @@
"preview": "vite preview" "preview": "vite preview"
}, },
"dependencies": { "dependencies": {
"@tanstack/react-form": "workspace:^",
"axios": "^0.26.1", "axios": "^0.26.1",
"react": "^18.0.0", "react": "^18.0.0",
"react-dom": "^18.0.0", "react-dom": "^18.0.0",
"@tanstack/react-form": "^4.7.1" "zod": "^3.21.4"
}, },
"devDependencies": { "devDependencies": {
"@vitejs/plugin-react": "^2.0.0", "@vitejs/plugin-react": "^2.0.0",

View File

@@ -1,9 +1,64 @@
/* eslint-disable jsx-a11y/anchor-is-valid */
import React from "react"; import React from "react";
import ReactDOM from "react-dom/client"; import ReactDOM from "react-dom/client";
import { useForm } from "@tanstack/react-form"; import { useForm } from "@tanstack/react-form";
export default function App() {} export default function App() {
const form = useForm({
// Memoize your default values to prevent re-renders
defaultValues: React.useMemo(
() => ({
firstName: "",
lastName: "",
}),
[]
),
onSubmit: (values) => {
// Do something with form data
},
});
return (
<div>
<h1>Simple Form Example</h1>
{/* A pre-bound form component */}
<form.Form>
<div>
{/* A type-safe and pre-bound field component*/}
<form.Field
name="firstName"
validate={(value) => !value && "A first name is required"}
children={(field) => (
// Avoid hasty abstractions. Render props are great!
<>
<label htmlFor={field.name}>First Name:</label>
<input name={field.name} {...field.getInputProps()} />
</>
)}
/>
</div>
<div>
<form.Field
name="lastName"
children={(field) => (
<>
<label htmlFor={field.name}>Last Name:</label>
<input name={field.name} {...field.getInputProps()} />
</>
)}
/>
</div>
<form.Subscribe
selector={(state) => [state.canSubmit, state.isSubmitting]}
children={([canSubmit, isSubmitting]) => (
<button type="submit" disabled={!canSubmit}>
{isSubmitting ? "..." : "Submit"}
</button>
)}
/>
</form.Form>
</div>
);
}
const rootElement = document.getElementById("root"); const rootElement = document.getElementById("root");
ReactDOM.createRoot(rootElement).render(<App />); ReactDOM.createRoot(rootElement).render(<App />);

View File

@@ -23,6 +23,13 @@ export type FieldOptions<TData, TFormData> = {
| 'submit' | 'submit'
} }
export type FieldMeta = {
isTouched: boolean
touchedError?: ValidationError
error?: ValidationError
isValidating: boolean
}
export type ChangeProps<TData> = { export type ChangeProps<TData> = {
onChange: (updater: Updater<TData>) => void onChange: (updater: Updater<TData>) => void
onBlur: (event: any) => void onBlur: (event: any) => void
@@ -33,13 +40,6 @@ export type InputProps = {
onBlur: (event: any) => void onBlur: (event: any) => void
} }
export type FieldMeta = {
isTouched: boolean
touchedError?: ValidationError
error?: ValidationError
isValidating: boolean
}
export type FieldApiOptions<TData, TFormData> = RequiredByKey< export type FieldApiOptions<TData, TFormData> = RequiredByKey<
FieldOptions<TData, TFormData>, FieldOptions<TData, TFormData>,
'form' 'form'
@@ -211,17 +211,25 @@ export class FieldApi<TData, TFormData> {
} }
try { try {
const error = await this.options.validate(this.state.value, this) const rawError = await this.options.validate(this.state.value, this)
if (checkLatest()) { if (checkLatest()) {
const error = (() => {
if (rawError) {
if (typeof rawError !== 'string') {
return 'Invalid Form Values'
}
return null
}
return undefined
})()
this.setMeta((prev) => ({ this.setMeta((prev) => ({
...prev, ...prev,
isValidating: false, isValidating: false,
error: error error,
? typeof error === 'string'
? error
: 'Invalid Form Values'
: null,
})) }))
this.getInfo().validationResolve?.(error) this.getInfo().validationResolve?.(error)
} }
@@ -245,6 +253,7 @@ export class FieldApi<TData, TFormData> {
): ChangeProps<TData> & Omit<T, keyof ChangeProps<TData>> => { ): ChangeProps<TData> & Omit<T, keyof ChangeProps<TData>> => {
return { return {
...props, ...props,
value: this.state.value,
onChange: (value) => { onChange: (value) => {
this.setValue(value) this.setValue(value)
props.onChange(value) props.onChange(value)
@@ -268,6 +277,7 @@ export class FieldApi<TData, TFormData> {
): InputProps & Omit<T, keyof InputProps> => { ): InputProps & Omit<T, keyof InputProps> => {
return { return {
...props, ...props,
value: String(this.state.value),
onChange: (e) => { onChange: (e) => {
this.setValue(e.target.value) this.setValue(e.target.value)
props.onChange(e.target.value) props.onChange(e.target.value)

View File

@@ -6,7 +6,6 @@ import React from 'react'
import { createFieldComponent, type FieldComponent } from './Field' import { createFieldComponent, type FieldComponent } from './Field'
import { createUseField, type UseField } from './useField' import { createUseField, type UseField } from './useField'
import { formContext } from './formContext' import { formContext } from './formContext'
//
declare module '@tanstack/form-core' { declare module '@tanstack/form-core' {
// eslint-disable-next-line no-shadow // eslint-disable-next-line no-shadow
@@ -25,22 +24,27 @@ declare module '@tanstack/form-core' {
}) => any }) => any
} }
} }
//
export function useForm<TData>( export function useForm<TData>(opts?: FormOptions<TData>): FormApi<TData> {
opts?: FormOptions<TData> & { listen?: (state: FormState<TData>) => any },
): FormApi<TData> {
// & { listened: TListen }
const [formApi] = React.useState(() => { const [formApi] = React.useState(() => {
// @ts-ignore
const api = new FormApi<TData>(opts || {}) const api = new FormApi<TData>(opts || {})
api.Form = createFormComponent(api) api.Form = createFormComponent(api)
api.Field = createFieldComponent(api) api.Field = createFieldComponent(api)
api.useField = createUseField(api) api.useField = createUseField(api)
api.useStore = (selector) => { api.useStore = (
// @ts-ignore
selector,
) => {
// eslint-disable-next-line react-hooks/rules-of-hooks // eslint-disable-next-line react-hooks/rules-of-hooks
return useStore(api.store, selector) as any return useStore(api.store, selector) as any
} }
api.Subscribe = (props) => { api.Subscribe = (
// @ts-ignore
props,
) => {
return functionalUpdate( return functionalUpdate(
props.children, props.children,
// eslint-disable-next-line react-hooks/rules-of-hooks // eslint-disable-next-line react-hooks/rules-of-hooks

9
pnpm-lock.yaml generated
View File

@@ -230,7 +230,7 @@ importers:
examples/react/simple: examples/react/simple:
dependencies: dependencies:
'@tanstack/react-form': '@tanstack/react-form':
specifier: ^4.7.1 specifier: workspace:^
version: link:../../../packages/react-form version: link:../../../packages/react-form
axios: axios:
specifier: ^0.26.1 specifier: ^0.26.1
@@ -241,6 +241,9 @@ importers:
react-dom: react-dom:
specifier: ^18.0.0 specifier: ^18.0.0
version: 18.2.0(react@18.2.0) version: 18.2.0(react@18.2.0)
zod:
specifier: ^3.21.4
version: 3.21.4
devDependencies: devDependencies:
'@vitejs/plugin-react': '@vitejs/plugin-react':
specifier: ^2.0.0 specifier: ^2.0.0
@@ -10395,3 +10398,7 @@ packages:
resolution: {integrity: sha512-Ux4ygGWsu2c7isFWe8Yu1YluJmqVhxqK2cLXNQA5AcC3QfbGNpM7fu0Y8b/z16pXLnFxZYvWhd3fhBY9DLmC6Q==} resolution: {integrity: sha512-Ux4ygGWsu2c7isFWe8Yu1YluJmqVhxqK2cLXNQA5AcC3QfbGNpM7fu0Y8b/z16pXLnFxZYvWhd3fhBY9DLmC6Q==}
engines: {node: '>=6'} engines: {node: '>=6'}
dev: true dev: true
/zod@3.21.4:
resolution: {integrity: sha512-m46AKbrzKVzOzs/DZgVnG5H55N1sv1M8qZU3A8RIKbs3mrACDNeIOeilDymVb2HdmP8uwshOCF4uJ8uM9rCqJw==}
dev: false