@saas-ui/forms 3.0.0-alpha.0 → 3.0.0-alpha.10
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +92 -0
- package/dist/index.d.mts +1 -2
- package/dist/index.d.ts +1 -2
- package/dist/index.js.map +1 -1
- package/dist/index.mjs.map +1 -1
- package/dist/zod/index.d.mts +5 -3
- package/dist/zod/index.d.ts +5 -3
- package/dist/zod/index.js +1 -1
- package/dist/zod/index.js.map +1 -1
- package/dist/zod/index.mjs +1 -1
- package/dist/zod/index.mjs.map +1 -1
- package/package.json +9 -29
- package/dist/ajv/index.d.mts +0 -35
- package/dist/ajv/index.d.ts +0 -35
- package/dist/ajv/index.js +0 -57
- package/dist/ajv/index.js.map +0 -1
- package/dist/ajv/index.mjs +0 -30
- package/dist/ajv/index.mjs.map +0 -1
- package/src/array-field.tsx +0 -266
- package/src/auto-form.tsx +0 -71
- package/src/base-field.tsx +0 -69
- package/src/create-field.tsx +0 -171
- package/src/create-form.tsx +0 -100
- package/src/create-step-form.tsx +0 -118
- package/src/default-fields.tsx +0 -233
- package/src/display-field.tsx +0 -46
- package/src/display-if.tsx +0 -69
- package/src/field-resolver.ts +0 -66
- package/src/field.tsx +0 -44
- package/src/fields-context.tsx +0 -33
- package/src/fields.tsx +0 -93
- package/src/form-context.tsx +0 -80
- package/src/form-layout.tsx +0 -59
- package/src/form.tsx +0 -252
- package/src/index.ts +0 -310
- package/src/object-field.tsx +0 -58
- package/src/step-form.tsx +0 -191
- package/src/submit-button.tsx +0 -71
- package/src/types.ts +0 -242
- package/src/use-array-field.tsx +0 -158
- package/src/use-form.tsx +0 -24
- package/src/use-step-form.tsx +0 -202
- package/src/utils.ts +0 -35
- package/src/watch-field.tsx +0 -37
package/src/create-field.tsx
DELETED
@@ -1,171 +0,0 @@
|
|
1
|
-
import React, {
|
2
|
-
type ForwardRefRenderFunction,
|
3
|
-
type PropsWithoutRef,
|
4
|
-
forwardRef,
|
5
|
-
} from 'react'
|
6
|
-
|
7
|
-
import { callAll, mergeRefs, splitProps } from '@saas-ui/core/utils'
|
8
|
-
import { Controller, type RegisterOptions } from 'react-hook-form'
|
9
|
-
|
10
|
-
import { BaseField } from './base-field'
|
11
|
-
import { useFieldsContext } from './fields-context'
|
12
|
-
import { useFormContext } from './form-context'
|
13
|
-
import { BaseFieldProps, GetBaseField } from './types'
|
14
|
-
|
15
|
-
interface CreateFieldProps<ExtraFieldProps extends object = object> {
|
16
|
-
displayName: string
|
17
|
-
hideLabel?: boolean
|
18
|
-
getBaseField: GetBaseField<ExtraFieldProps>
|
19
|
-
}
|
20
|
-
|
21
|
-
const _createField = (
|
22
|
-
InputComponent: React.FC<any>,
|
23
|
-
{ displayName, hideLabel, getBaseField: getBaseFieldProp }: CreateFieldProps,
|
24
|
-
) => {
|
25
|
-
const Field = forwardRef<HTMLDivElement, any>((props, ref) => {
|
26
|
-
const { id, name, label, isRequired, rules } = props
|
27
|
-
|
28
|
-
const inputRules = {
|
29
|
-
required: isRequired,
|
30
|
-
...rules,
|
31
|
-
}
|
32
|
-
|
33
|
-
const fieldContext = useFieldsContext()
|
34
|
-
|
35
|
-
const getBaseField = fieldContext?.getBaseField ?? getBaseFieldProp
|
36
|
-
|
37
|
-
const { extraProps, BaseField } = React.useMemo(
|
38
|
-
() => getBaseField(),
|
39
|
-
[getBaseField],
|
40
|
-
)
|
41
|
-
|
42
|
-
const [, inputProps] = splitProps(
|
43
|
-
props,
|
44
|
-
[
|
45
|
-
'children',
|
46
|
-
'name',
|
47
|
-
'label',
|
48
|
-
'required',
|
49
|
-
'disabled',
|
50
|
-
'invalid',
|
51
|
-
'readOnly',
|
52
|
-
'help',
|
53
|
-
'hideLabel',
|
54
|
-
].concat(extraProps),
|
55
|
-
)
|
56
|
-
|
57
|
-
return (
|
58
|
-
<BaseField name={name} hideLabel={hideLabel} {...props}>
|
59
|
-
<InputComponent
|
60
|
-
ref={ref}
|
61
|
-
id={id}
|
62
|
-
name={name}
|
63
|
-
label={hideLabel ? label : undefined} // Only pass down the label when it should be inline.
|
64
|
-
{...inputProps}
|
65
|
-
rules={inputRules}
|
66
|
-
/>
|
67
|
-
</BaseField>
|
68
|
-
)
|
69
|
-
})
|
70
|
-
|
71
|
-
Field.displayName = displayName
|
72
|
-
|
73
|
-
return Field
|
74
|
-
}
|
75
|
-
|
76
|
-
const withControlledInput = (InputComponent: React.FC<any>) => {
|
77
|
-
return forwardRef<typeof InputComponent, ControlProps>((props, ref) => {
|
78
|
-
const { name, rules, ...inputProps } = props
|
79
|
-
const { control } = useFormContext()
|
80
|
-
|
81
|
-
const onChange = inputProps.onChange as (...event: any[]) => void
|
82
|
-
|
83
|
-
return (
|
84
|
-
<Controller
|
85
|
-
name={name}
|
86
|
-
control={control}
|
87
|
-
rules={rules}
|
88
|
-
render={({ field: { ref: _ref, ...field } }) => (
|
89
|
-
<InputComponent
|
90
|
-
{...field}
|
91
|
-
{...inputProps}
|
92
|
-
onChange={callAll(onChange, field.onChange)}
|
93
|
-
onBlur={callAll(inputProps.onBlur, field.onBlur)}
|
94
|
-
ref={mergeRefs(ref, _ref)}
|
95
|
-
/>
|
96
|
-
)}
|
97
|
-
/>
|
98
|
-
)
|
99
|
-
})
|
100
|
-
}
|
101
|
-
|
102
|
-
const withUncontrolledInput = (InputComponent: React.FC<any>) => {
|
103
|
-
return forwardRef<typeof InputComponent, ControlProps>(
|
104
|
-
({ name, rules, ...inputProps }, ref) => {
|
105
|
-
const { register } = useFormContext()
|
106
|
-
|
107
|
-
const { ref: _ref, ...field } = register(name, rules)
|
108
|
-
|
109
|
-
const onChange = inputProps.onChange as (...event: any[]) => void
|
110
|
-
|
111
|
-
return (
|
112
|
-
<InputComponent
|
113
|
-
{...field}
|
114
|
-
{...inputProps}
|
115
|
-
onChange={callAll(onChange, field.onChange)}
|
116
|
-
onBlur={callAll(inputProps.onBlur, field.onBlur)}
|
117
|
-
ref={mergeRefs(ref, _ref)}
|
118
|
-
/>
|
119
|
-
)
|
120
|
-
},
|
121
|
-
)
|
122
|
-
}
|
123
|
-
|
124
|
-
export interface CreateFieldOptions {
|
125
|
-
isControlled?: boolean
|
126
|
-
hideLabel?: boolean
|
127
|
-
BaseField?: React.FC<any>
|
128
|
-
}
|
129
|
-
|
130
|
-
interface ControlProps {
|
131
|
-
name: string
|
132
|
-
onChange: (...event: any[]) => void
|
133
|
-
onBlur: (...event: any[]) => void
|
134
|
-
value: unknown
|
135
|
-
disabled?: boolean
|
136
|
-
rules?: RegisterOptions
|
137
|
-
}
|
138
|
-
|
139
|
-
/**
|
140
|
-
* Register a new field type
|
141
|
-
* @param type The name for this field in kebab-case, eg `email` or `array-field`
|
142
|
-
* @param component The React component
|
143
|
-
* @param options
|
144
|
-
* @param options.isControlled Set this to true if this is a controlled field.
|
145
|
-
* @param options.hideLabel Hide the field label, for example for the checkbox field.
|
146
|
-
*/
|
147
|
-
export const createField = <TType = unknown, TProps extends object = object>(
|
148
|
-
component: ForwardRefRenderFunction<
|
149
|
-
TType,
|
150
|
-
PropsWithoutRef<TProps & ControlProps>
|
151
|
-
>,
|
152
|
-
options?: CreateFieldOptions,
|
153
|
-
) => {
|
154
|
-
let InputComponent
|
155
|
-
if (options?.isControlled) {
|
156
|
-
InputComponent = withControlledInput(forwardRef(component))
|
157
|
-
} else {
|
158
|
-
InputComponent = withUncontrolledInput(forwardRef(component))
|
159
|
-
}
|
160
|
-
|
161
|
-
const Field = _createField(InputComponent, {
|
162
|
-
displayName: `${component.displayName ?? 'Custom'}Field`,
|
163
|
-
hideLabel: options?.hideLabel,
|
164
|
-
getBaseField: () => ({
|
165
|
-
extraProps: [],
|
166
|
-
BaseField,
|
167
|
-
}),
|
168
|
-
}) as React.FC<Omit<BaseFieldProps, keyof TProps> & TProps>
|
169
|
-
|
170
|
-
return Field
|
171
|
-
}
|
package/src/create-form.tsx
DELETED
@@ -1,100 +0,0 @@
|
|
1
|
-
import React, { ForwardedRef, forwardRef, useMemo } from 'react'
|
2
|
-
|
3
|
-
import { defaultFieldTypes } from './default-fields'
|
4
|
-
import { objectFieldResolver } from './field-resolver'
|
5
|
-
import { GetFieldResolver } from './field-resolver'
|
6
|
-
import { FieldsProvider } from './fields-context'
|
7
|
-
import { FieldValues, Form, FormProps, GetResolver } from './form'
|
8
|
-
import { GetBaseField, WithFields } from './types'
|
9
|
-
|
10
|
-
export interface CreateFormProps<
|
11
|
-
FieldDefs,
|
12
|
-
TGetBaseField extends GetBaseField = GetBaseField,
|
13
|
-
> {
|
14
|
-
resolver?: GetResolver
|
15
|
-
fieldResolver?: GetFieldResolver
|
16
|
-
fields?: FieldDefs extends Record<string, React.FC<any>> ? FieldDefs : never
|
17
|
-
getBaseField?: TGetBaseField
|
18
|
-
}
|
19
|
-
|
20
|
-
export type FormType<
|
21
|
-
FieldDefs,
|
22
|
-
ExtraProps = object,
|
23
|
-
ExtraFieldProps extends object = object,
|
24
|
-
ExtraOverrides = object,
|
25
|
-
> = (<
|
26
|
-
TSchema = unknown,
|
27
|
-
TFieldValues extends FieldValues = FieldValues,
|
28
|
-
TContext extends object = object,
|
29
|
-
>(
|
30
|
-
props: WithFields<
|
31
|
-
FormProps<TSchema, TFieldValues, TContext, ExtraFieldProps>,
|
32
|
-
FieldDefs,
|
33
|
-
ExtraOverrides
|
34
|
-
> & {
|
35
|
-
ref?: React.ForwardedRef<HTMLFormElement>
|
36
|
-
} & ExtraProps,
|
37
|
-
) => React.ReactElement) & {
|
38
|
-
displayName?: string
|
39
|
-
id?: string
|
40
|
-
}
|
41
|
-
|
42
|
-
export function createForm<
|
43
|
-
FieldDefs,
|
44
|
-
TGetBaseField extends GetBaseField<any> = GetBaseField<any>,
|
45
|
-
>({
|
46
|
-
resolver,
|
47
|
-
fieldResolver = objectFieldResolver,
|
48
|
-
fields,
|
49
|
-
getBaseField,
|
50
|
-
}: CreateFormProps<FieldDefs, TGetBaseField> = {}) {
|
51
|
-
type ExtraFieldProps =
|
52
|
-
TGetBaseField extends GetBaseField<infer ExtraFieldProps>
|
53
|
-
? ExtraFieldProps
|
54
|
-
: object
|
55
|
-
|
56
|
-
const DefaultForm = forwardRef(
|
57
|
-
<
|
58
|
-
TSchema = any,
|
59
|
-
TFieldValues extends FieldValues = FieldValues,
|
60
|
-
TContext extends object = object,
|
61
|
-
>(
|
62
|
-
props: WithFields<
|
63
|
-
FormProps<TSchema, TFieldValues, TContext, ExtraFieldProps>,
|
64
|
-
FieldDefs
|
65
|
-
>,
|
66
|
-
ref: ForwardedRef<HTMLFormElement>,
|
67
|
-
) => {
|
68
|
-
const {
|
69
|
-
schema,
|
70
|
-
resolver: resolverProp,
|
71
|
-
fieldResolver: fieldResolverProp,
|
72
|
-
...rest
|
73
|
-
} = props
|
74
|
-
|
75
|
-
const fieldsContext = useMemo(
|
76
|
-
() => ({
|
77
|
-
fields: { ...defaultFieldTypes, ...fields },
|
78
|
-
getBaseField,
|
79
|
-
}),
|
80
|
-
[fields, getBaseField],
|
81
|
-
)
|
82
|
-
|
83
|
-
return (
|
84
|
-
<FieldsProvider value={fieldsContext}>
|
85
|
-
<Form
|
86
|
-
ref={ref}
|
87
|
-
resolver={resolverProp ?? resolver?.(props.schema)}
|
88
|
-
fieldResolver={fieldResolverProp ?? fieldResolver?.(schema)}
|
89
|
-
{...rest}
|
90
|
-
/>
|
91
|
-
</FieldsProvider>
|
92
|
-
)
|
93
|
-
},
|
94
|
-
) as FormType<FieldDefs, object, ExtraFieldProps>
|
95
|
-
|
96
|
-
DefaultForm.displayName = 'Form'
|
97
|
-
DefaultForm.id = 'Form'
|
98
|
-
|
99
|
-
return DefaultForm
|
100
|
-
}
|
package/src/create-step-form.tsx
DELETED
@@ -1,118 +0,0 @@
|
|
1
|
-
import React, { forwardRef, useMemo } from 'react'
|
2
|
-
|
3
|
-
import { runIfFn } from '@chakra-ui/utils'
|
4
|
-
import { StepperProvider } from '@saas-ui/core'
|
5
|
-
|
6
|
-
import {
|
7
|
-
ArrayField,
|
8
|
-
DisplayIf,
|
9
|
-
FieldProps,
|
10
|
-
FieldValues,
|
11
|
-
FieldsProvider,
|
12
|
-
GetFieldResolver,
|
13
|
-
ObjectField,
|
14
|
-
defaultFieldTypes,
|
15
|
-
} from './'
|
16
|
-
import { Field } from './field'
|
17
|
-
import { Form } from './form'
|
18
|
-
import { GetResolver } from './form'
|
19
|
-
import { FormStep, StepsOptions } from './step-form'
|
20
|
-
import { GetBaseField, WithStepFields } from './types'
|
21
|
-
import {
|
22
|
-
StepFormProvider,
|
23
|
-
UseStepFormProps,
|
24
|
-
useStepForm,
|
25
|
-
} from './use-step-form'
|
26
|
-
|
27
|
-
export type StepFormType<
|
28
|
-
FieldDefs,
|
29
|
-
ExtraProps = object,
|
30
|
-
ExtraFieldProps extends object = object,
|
31
|
-
ExtraOverrides = object,
|
32
|
-
> = (<
|
33
|
-
TSteps extends StepsOptions<any> = StepsOptions<any>,
|
34
|
-
TFieldValues extends FieldValues = FieldValues,
|
35
|
-
TContext extends object = object,
|
36
|
-
TFieldTypes = FieldProps<TFieldValues, ExtraFieldProps>,
|
37
|
-
>(
|
38
|
-
props: WithStepFields<
|
39
|
-
UseStepFormProps<TSteps, TFieldValues, TContext>,
|
40
|
-
FieldDefs,
|
41
|
-
ExtraOverrides
|
42
|
-
> & {
|
43
|
-
ref?: React.ForwardedRef<HTMLFormElement>
|
44
|
-
} & ExtraProps,
|
45
|
-
) => React.ReactElement) & {
|
46
|
-
displayName?: string
|
47
|
-
id?: string
|
48
|
-
}
|
49
|
-
|
50
|
-
export interface CreateStepFormProps<
|
51
|
-
FieldDefs,
|
52
|
-
TGetBaseField extends GetBaseField = GetBaseField,
|
53
|
-
> {
|
54
|
-
resolver?: GetResolver
|
55
|
-
fieldResolver?: GetFieldResolver
|
56
|
-
fields?: FieldDefs extends Record<string, React.FC<any>> ? FieldDefs : never
|
57
|
-
getBaseField?: TGetBaseField
|
58
|
-
}
|
59
|
-
|
60
|
-
export function createStepForm<
|
61
|
-
FieldDefs,
|
62
|
-
TGetBaseField extends GetBaseField<any> = GetBaseField<any>,
|
63
|
-
>({
|
64
|
-
fields,
|
65
|
-
resolver,
|
66
|
-
fieldResolver,
|
67
|
-
getBaseField,
|
68
|
-
}: CreateStepFormProps<FieldDefs, TGetBaseField> = {}) {
|
69
|
-
type ExtraFieldProps =
|
70
|
-
TGetBaseField extends GetBaseField<infer ExtraFieldProps>
|
71
|
-
? ExtraFieldProps
|
72
|
-
: object
|
73
|
-
|
74
|
-
const StepForm = forwardRef<HTMLFormElement, any>((props, ref) => {
|
75
|
-
const { children, steps, ...rest } = props
|
76
|
-
|
77
|
-
const stepper = useStepForm({
|
78
|
-
// resolver: resolver(props),
|
79
|
-
// fieldResolver: fieldResolver(,
|
80
|
-
...props,
|
81
|
-
})
|
82
|
-
|
83
|
-
const { getFormProps, ...ctx } = stepper
|
84
|
-
|
85
|
-
const context = useMemo(() => ctx, [ctx])
|
86
|
-
|
87
|
-
const fieldsContext = {
|
88
|
-
fields: {
|
89
|
-
...defaultFieldTypes,
|
90
|
-
...fields,
|
91
|
-
},
|
92
|
-
getBaseField,
|
93
|
-
}
|
94
|
-
|
95
|
-
return (
|
96
|
-
<StepperProvider value={context}>
|
97
|
-
<StepFormProvider value={context}>
|
98
|
-
<FieldsProvider value={fieldsContext}>
|
99
|
-
<Form ref={ref} {...rest} {...getFormProps()}>
|
100
|
-
{runIfFn(children, {
|
101
|
-
...stepper,
|
102
|
-
Field: Field as any,
|
103
|
-
FormStep: FormStep as any,
|
104
|
-
DisplayIf: DisplayIf as any,
|
105
|
-
ArrayField: ArrayField as any,
|
106
|
-
ObjectField: ObjectField as any,
|
107
|
-
})}
|
108
|
-
</Form>
|
109
|
-
</FieldsProvider>
|
110
|
-
</StepFormProvider>
|
111
|
-
</StepperProvider>
|
112
|
-
)
|
113
|
-
}) as StepFormType<FieldDefs, object, ExtraFieldProps>
|
114
|
-
|
115
|
-
StepForm.displayName = `Step${Form.displayName || Form.name}`
|
116
|
-
|
117
|
-
return StepForm
|
118
|
-
}
|
package/src/default-fields.tsx
DELETED
@@ -1,233 +0,0 @@
|
|
1
|
-
import React from 'react'
|
2
|
-
|
3
|
-
import {
|
4
|
-
Input,
|
5
|
-
InputProps,
|
6
|
-
Stack,
|
7
|
-
type SystemStyleObject,
|
8
|
-
Textarea,
|
9
|
-
TextareaProps,
|
10
|
-
createListCollection,
|
11
|
-
} from '@chakra-ui/react'
|
12
|
-
import { Checkbox, type CheckboxProps } from '@saas-ui/react/checkbox'
|
13
|
-
import { InputGroup } from '@saas-ui/react/input-group'
|
14
|
-
import { NumberInput, type NumberInputProps } from '@saas-ui/react/number-input'
|
15
|
-
import {
|
16
|
-
PasswordInput,
|
17
|
-
type PasswordInputProps,
|
18
|
-
} from '@saas-ui/react/password-input'
|
19
|
-
import { PinInput, type PinInputProps } from '@saas-ui/react/pin-input'
|
20
|
-
import { Radio, RadioGroup, type RadioGroupProps } from '@saas-ui/react/radio'
|
21
|
-
import { Select } from '@saas-ui/react/select'
|
22
|
-
import { Switch, type SwitchProps } from '@saas-ui/react/switch'
|
23
|
-
|
24
|
-
import { createField } from './create-field.tsx'
|
25
|
-
import type { FieldOption, FieldOptions } from './types.ts'
|
26
|
-
|
27
|
-
export interface InputFieldProps extends InputProps {
|
28
|
-
type?: string
|
29
|
-
startElement?: React.ReactNode
|
30
|
-
endElement?: React.ReactNode
|
31
|
-
}
|
32
|
-
|
33
|
-
export const InputField = createField<HTMLInputElement, InputFieldProps>(
|
34
|
-
({ type = 'text', startElement, endElement, size, ...rest }, ref) => {
|
35
|
-
return (
|
36
|
-
<InputGroup startElement={startElement} endElement={endElement}>
|
37
|
-
<Input type={type} size={size} {...rest} ref={ref} />
|
38
|
-
</InputGroup>
|
39
|
-
)
|
40
|
-
},
|
41
|
-
)
|
42
|
-
|
43
|
-
export interface NumberInputFieldProps extends NumberInputProps {
|
44
|
-
type: 'number'
|
45
|
-
}
|
46
|
-
|
47
|
-
export const NumberInputField = createField<
|
48
|
-
HTMLInputElement,
|
49
|
-
NumberInputFieldProps
|
50
|
-
>((props, ref) => <NumberInput {...props} ref={ref} />, {
|
51
|
-
isControlled: true,
|
52
|
-
})
|
53
|
-
|
54
|
-
export const PasswordInputField = createField<
|
55
|
-
HTMLInputElement,
|
56
|
-
PasswordInputProps
|
57
|
-
>(({ type = 'password', ...props }, ref) => (
|
58
|
-
<PasswordInput ref={ref} {...props} />
|
59
|
-
))
|
60
|
-
|
61
|
-
export interface TextareaFieldProps extends TextareaProps {}
|
62
|
-
|
63
|
-
export const TextareaField = createField<
|
64
|
-
HTMLTextAreaElement,
|
65
|
-
TextareaFieldProps
|
66
|
-
>((props, ref) => <Textarea {...props} ref={ref} />)
|
67
|
-
|
68
|
-
export interface SwitchFieldProps extends SwitchProps {
|
69
|
-
type: 'switch'
|
70
|
-
}
|
71
|
-
|
72
|
-
export const SwitchField = createField<HTMLInputElement, SwitchFieldProps>(
|
73
|
-
({ type, value, ...rest }, ref) => {
|
74
|
-
return <Switch checked={!!value} {...rest} ref={ref} />
|
75
|
-
},
|
76
|
-
{
|
77
|
-
isControlled: true,
|
78
|
-
},
|
79
|
-
)
|
80
|
-
|
81
|
-
export interface SelectFieldProps
|
82
|
-
extends Omit<Select.RootProps<FieldOption>, 'collection'> {
|
83
|
-
options: FieldOptions
|
84
|
-
placeholder?: string
|
85
|
-
triggerProps?: Select.TriggerProps
|
86
|
-
contentProps?: Select.ContentProps
|
87
|
-
}
|
88
|
-
|
89
|
-
export const SelectField = createField<HTMLDivElement, SelectFieldProps>(
|
90
|
-
(props, ref) => {
|
91
|
-
const {
|
92
|
-
triggerProps,
|
93
|
-
contentProps,
|
94
|
-
options,
|
95
|
-
placeholder,
|
96
|
-
onChange,
|
97
|
-
onValueChange,
|
98
|
-
onBlur,
|
99
|
-
...rest
|
100
|
-
} = props
|
101
|
-
|
102
|
-
const collection = createListCollection({
|
103
|
-
items: options,
|
104
|
-
})
|
105
|
-
|
106
|
-
return (
|
107
|
-
<Select.Root
|
108
|
-
ref={ref}
|
109
|
-
collection={collection}
|
110
|
-
onValueChange={(details) => {
|
111
|
-
onChange(details.value)
|
112
|
-
}}
|
113
|
-
onInteractOutside={() => onBlur()}
|
114
|
-
{...rest}
|
115
|
-
>
|
116
|
-
<Select.Trigger {...triggerProps}>
|
117
|
-
<Select.ValueText placeholder={placeholder} />
|
118
|
-
</Select.Trigger>
|
119
|
-
<Select.Content {...contentProps}>
|
120
|
-
{collection.items.map((option) => (
|
121
|
-
<Select.Item key={option.value} item={option}>
|
122
|
-
{option.label || option.value}
|
123
|
-
</Select.Item>
|
124
|
-
))}
|
125
|
-
</Select.Content>
|
126
|
-
</Select.Root>
|
127
|
-
)
|
128
|
-
},
|
129
|
-
{
|
130
|
-
isControlled: true,
|
131
|
-
},
|
132
|
-
)
|
133
|
-
|
134
|
-
export interface CheckboxFieldProps extends CheckboxProps {
|
135
|
-
type: 'checkbox'
|
136
|
-
label?: string
|
137
|
-
}
|
138
|
-
|
139
|
-
export const CheckboxField = createField<HTMLInputElement, CheckboxFieldProps>(
|
140
|
-
({ label, type, ...props }, ref) => {
|
141
|
-
return (
|
142
|
-
<Checkbox ref={ref} {...props}>
|
143
|
-
{label}
|
144
|
-
</Checkbox>
|
145
|
-
)
|
146
|
-
},
|
147
|
-
{
|
148
|
-
hideLabel: true,
|
149
|
-
},
|
150
|
-
)
|
151
|
-
|
152
|
-
export interface RadioFieldProps extends RadioGroupProps {
|
153
|
-
type: 'radio'
|
154
|
-
options: FieldOptions
|
155
|
-
flexDirection?: SystemStyleObject['flexDirection']
|
156
|
-
gap?: SystemStyleObject['gap']
|
157
|
-
}
|
158
|
-
|
159
|
-
export const RadioField = createField<HTMLInputElement, RadioFieldProps>(
|
160
|
-
(props, ref) => {
|
161
|
-
const { options, onChange, flexDirection = 'column', gap, ...rest } = props
|
162
|
-
return (
|
163
|
-
<RadioGroup
|
164
|
-
ref={ref}
|
165
|
-
onValueChange={({ value }) => {
|
166
|
-
onChange?.(value)
|
167
|
-
}}
|
168
|
-
{...rest}
|
169
|
-
>
|
170
|
-
<Stack flexDirection={flexDirection} gap={gap}>
|
171
|
-
{options.map((option) => (
|
172
|
-
<Radio key={option.value} value={option.value}>
|
173
|
-
{option.label || option.value}
|
174
|
-
</Radio>
|
175
|
-
))}
|
176
|
-
</Stack>
|
177
|
-
</RadioGroup>
|
178
|
-
)
|
179
|
-
},
|
180
|
-
{
|
181
|
-
isControlled: true,
|
182
|
-
},
|
183
|
-
)
|
184
|
-
|
185
|
-
export interface PinFieldProps
|
186
|
-
extends Omit<PinInputProps, 'type' | 'value' | 'onChange'> {
|
187
|
-
type: 'pin'
|
188
|
-
pinLength?: number
|
189
|
-
pinType?: PinInputProps['type']
|
190
|
-
value?: string
|
191
|
-
onChange?: (value: string) => void
|
192
|
-
}
|
193
|
-
|
194
|
-
export const PinField = createField<HTMLInputElement, PinFieldProps>(
|
195
|
-
(props, ref) => {
|
196
|
-
const { pinType, value: valueProp, onChange, ...inputProps } = props
|
197
|
-
|
198
|
-
const value = valueProp?.split('') || []
|
199
|
-
|
200
|
-
return (
|
201
|
-
<PinInput
|
202
|
-
ref={ref}
|
203
|
-
{...inputProps}
|
204
|
-
value={value}
|
205
|
-
onValueChange={(details) => {
|
206
|
-
onChange(details.valueAsString)
|
207
|
-
}}
|
208
|
-
type={pinType}
|
209
|
-
/>
|
210
|
-
)
|
211
|
-
},
|
212
|
-
{
|
213
|
-
isControlled: true,
|
214
|
-
},
|
215
|
-
)
|
216
|
-
|
217
|
-
export const defaultFieldTypes = {
|
218
|
-
text: InputField,
|
219
|
-
email: InputField,
|
220
|
-
url: InputField,
|
221
|
-
phone: InputField,
|
222
|
-
time: InputField,
|
223
|
-
number: NumberInputField,
|
224
|
-
pin: PinField,
|
225
|
-
checkbox: CheckboxField,
|
226
|
-
radio: RadioField,
|
227
|
-
password: PasswordInputField,
|
228
|
-
select: SelectField,
|
229
|
-
switch: SwitchField,
|
230
|
-
textarea: TextareaField,
|
231
|
-
}
|
232
|
-
|
233
|
-
export type DefaultFields = typeof defaultFieldTypes
|
package/src/display-field.tsx
DELETED
@@ -1,46 +0,0 @@
|
|
1
|
-
import * as React from 'react'
|
2
|
-
|
3
|
-
import { Field as FieldPrimivite, Text } from '@chakra-ui/react'
|
4
|
-
import type { FieldPath, FieldValues } from 'react-hook-form'
|
5
|
-
|
6
|
-
import { useFormContext } from './form-context.tsx'
|
7
|
-
import type { ArrayFieldPath } from './types.ts'
|
8
|
-
|
9
|
-
export interface DisplayFieldProps<
|
10
|
-
TFieldValues extends FieldValues = FieldValues,
|
11
|
-
TName extends FieldPath<TFieldValues> = FieldPath<TFieldValues>,
|
12
|
-
> extends Omit<FieldPrimivite.RootProps, 'type' | 'onChange' | 'defaultValue'> {
|
13
|
-
name: TName | ArrayFieldPath<TName>
|
14
|
-
label?: string
|
15
|
-
}
|
16
|
-
|
17
|
-
/**
|
18
|
-
* Display a field value.
|
19
|
-
*
|
20
|
-
* @see Docs https://saas-ui.dev/
|
21
|
-
*/
|
22
|
-
export const DisplayField: React.FC<DisplayFieldProps> = ({
|
23
|
-
name,
|
24
|
-
label,
|
25
|
-
...props
|
26
|
-
}) => {
|
27
|
-
return (
|
28
|
-
<FieldPrimivite.Root {...props}>
|
29
|
-
{label ? (
|
30
|
-
<FieldPrimivite.Label htmlFor={name}>{label}</FieldPrimivite.Label>
|
31
|
-
) : null}
|
32
|
-
<Text fontSize="md">
|
33
|
-
<FormValue name={name} />
|
34
|
-
</Text>
|
35
|
-
</FieldPrimivite.Root>
|
36
|
-
)
|
37
|
-
}
|
38
|
-
|
39
|
-
DisplayField.displayName = 'DisplayField'
|
40
|
-
|
41
|
-
export const FormValue: React.FC<{ name: string }> = ({ name }) => {
|
42
|
-
const { getValues } = useFormContext()
|
43
|
-
return getValues(name) || null
|
44
|
-
}
|
45
|
-
|
46
|
-
FormValue.displayName = 'FormValue'
|