@saas-ui/forms 2.0.0-next.0 → 2.0.0-next.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 +95 -0
- package/README.md +53 -6
- package/dist/ajv/index.d.ts +359 -11
- package/dist/ajv/index.js +7 -9
- package/dist/ajv/index.js.map +1 -1
- package/dist/ajv/index.mjs +7 -10
- package/dist/ajv/index.mjs.map +1 -1
- package/dist/index.d.ts +448 -247
- package/dist/index.js +708 -682
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +688 -662
- package/dist/index.mjs.map +1 -1
- package/dist/yup/index.d.ts +581 -21
- package/dist/yup/index.js +6 -10
- package/dist/yup/index.js.map +1 -1
- package/dist/yup/index.mjs +4 -8
- package/dist/yup/index.mjs.map +1 -1
- package/dist/zod/index.d.ts +581 -11
- package/dist/zod/index.js +5 -0
- package/dist/zod/index.js.map +1 -1
- package/dist/zod/index.mjs +5 -1
- package/dist/zod/index.mjs.map +1 -1
- package/package.json +24 -15
- package/src/array-field.tsx +82 -45
- package/src/auto-form.tsx +7 -3
- package/src/base-field.tsx +54 -0
- package/src/create-field.tsx +144 -0
- package/src/create-form.tsx +54 -0
- package/src/default-fields.tsx +163 -0
- package/src/display-field.tsx +9 -11
- package/src/display-if.tsx +20 -13
- package/src/field-resolver.ts +10 -8
- package/src/field.tsx +18 -445
- package/src/fields-context.tsx +23 -0
- package/src/fields.tsx +34 -21
- package/src/form-context.tsx +84 -0
- package/src/form.tsx +72 -52
- package/src/index.ts +44 -4
- package/src/input-right-button/input-right-button.stories.tsx +2 -2
- package/src/input-right-button/input-right-button.tsx +0 -2
- package/src/layout.tsx +16 -11
- package/src/number-input/number-input.stories.tsx +3 -3
- package/src/number-input/number-input.tsx +9 -5
- package/src/object-field.tsx +13 -8
- package/src/password-input/password-input.stories.tsx +23 -2
- package/src/password-input/password-input.tsx +6 -6
- package/src/pin-input/pin-input.tsx +1 -5
- package/src/radio/radio-input.stories.tsx +1 -1
- package/src/radio/radio-input.tsx +12 -10
- package/src/select/native-select.tsx +1 -4
- package/src/select/select-context.tsx +130 -0
- package/src/select/select.stories.tsx +117 -86
- package/src/select/select.test.tsx +1 -1
- package/src/select/select.tsx +162 -146
- package/src/step-form.tsx +29 -11
- package/src/submit-button.tsx +5 -1
- package/src/types.ts +144 -0
- package/src/use-array-field.tsx +9 -3
- package/src/utils.ts +23 -1
- package/src/watch-field.tsx +2 -6
- /package/src/radio/{radio.test.tsx → radio-input.test.tsx} +0 -0
package/src/form.tsx
CHANGED
@@ -1,11 +1,10 @@
|
|
1
1
|
import * as React from 'react'
|
2
2
|
|
3
3
|
import { chakra, HTMLChakraProps, forwardRef } from '@chakra-ui/react'
|
4
|
-
import { cx, runIfFn
|
4
|
+
import { FocusableElement, cx, runIfFn } from '@chakra-ui/utils'
|
5
5
|
|
6
6
|
import {
|
7
7
|
useForm,
|
8
|
-
FormProvider,
|
9
8
|
UseFormProps,
|
10
9
|
UseFormReturn,
|
11
10
|
FieldValues,
|
@@ -15,27 +14,44 @@ import {
|
|
15
14
|
ResolverResult,
|
16
15
|
WatchObserver,
|
17
16
|
} from 'react-hook-form'
|
18
|
-
import {
|
17
|
+
import { FormProvider } from './form-context'
|
18
|
+
import { FieldResolver } from './field-resolver'
|
19
19
|
import { MaybeRenderProp } from '@chakra-ui/react-utils'
|
20
20
|
|
21
21
|
export type { UseFormReturn, FieldValues, SubmitHandler }
|
22
22
|
|
23
|
-
import {
|
23
|
+
import { FieldProps, DefaultFieldOverrides } from './types'
|
24
24
|
|
25
|
-
|
25
|
+
import { Field as DefaultField } from './field'
|
26
|
+
import { FormLayout } from './layout'
|
27
|
+
import { AutoFields } from './fields'
|
28
|
+
import { SubmitButton } from './submit-button'
|
29
|
+
import { DisplayIf, DisplayIfProps } from './display-if'
|
30
|
+
import { ArrayField, ArrayFieldProps } from './array-field'
|
31
|
+
import { ObjectField, ObjectFieldProps } from './object-field'
|
32
|
+
import { UseArrayFieldReturn } from './use-array-field'
|
33
|
+
|
34
|
+
export interface FormRenderContext<
|
26
35
|
TFieldValues extends FieldValues = FieldValues,
|
27
|
-
TContext extends object = object
|
36
|
+
TContext extends object = object,
|
37
|
+
TFieldTypes = FieldProps<TFieldValues>
|
28
38
|
> extends UseFormReturn<TFieldValues, TContext> {
|
29
|
-
Field: React.FC<
|
39
|
+
Field: React.FC<TFieldTypes & React.RefAttributes<FocusableElement>>
|
40
|
+
DisplayIf: React.FC<DisplayIfProps<TFieldValues>>
|
41
|
+
ArrayField: React.FC<
|
42
|
+
ArrayFieldProps<TFieldValues> & React.RefAttributes<UseArrayFieldReturn>
|
43
|
+
>
|
44
|
+
ObjectField: React.FC<ObjectFieldProps<TFieldValues>>
|
30
45
|
}
|
31
46
|
|
32
47
|
interface FormOptions<
|
33
48
|
TFieldValues extends FieldValues = FieldValues,
|
34
49
|
TContext extends object = object,
|
35
|
-
TSchema = any
|
50
|
+
TSchema = any,
|
51
|
+
TFieldTypes = FieldProps<TFieldValues>
|
36
52
|
> {
|
37
53
|
/**
|
38
|
-
* The form schema
|
54
|
+
* The form schema.
|
39
55
|
*/
|
40
56
|
schema?: TSchema
|
41
57
|
/**
|
@@ -57,32 +73,51 @@ interface FormOptions<
|
|
57
73
|
/**
|
58
74
|
* The form children, can be a render prop or a ReactNode.
|
59
75
|
*/
|
60
|
-
children?: MaybeRenderProp<
|
76
|
+
children?: MaybeRenderProp<
|
77
|
+
FormRenderContext<TFieldValues, TContext, TFieldTypes>
|
78
|
+
>
|
79
|
+
/**
|
80
|
+
* The field resolver, used to resolve the fields from schemas.
|
81
|
+
*/
|
82
|
+
fieldResolver?: FieldResolver
|
83
|
+
/**
|
84
|
+
* Field overrides
|
85
|
+
*/
|
86
|
+
fields?: DefaultFieldOverrides
|
61
87
|
}
|
62
88
|
|
63
89
|
export interface FormProps<
|
64
90
|
TFieldValues extends FieldValues = FieldValues,
|
65
91
|
TContext extends object = object,
|
66
|
-
TSchema = any
|
92
|
+
TSchema = any,
|
93
|
+
TFieldTypes = FieldProps<TFieldValues>
|
67
94
|
> extends UseFormProps<TFieldValues, TContext>,
|
68
95
|
Omit<
|
69
96
|
HTMLChakraProps<'form'>,
|
70
97
|
'children' | 'onChange' | 'onSubmit' | 'onError'
|
71
98
|
>,
|
72
|
-
FormOptions<TFieldValues, TContext, TSchema> {}
|
99
|
+
FormOptions<TFieldValues, TContext, TSchema, TFieldTypes> {}
|
73
100
|
|
101
|
+
/**
|
102
|
+
* The wrapper component provides context, state, and focus management.
|
103
|
+
*
|
104
|
+
* @see Docs https://saas-ui.dev/docs/components/forms/form
|
105
|
+
*/
|
74
106
|
export const Form = forwardRef(
|
75
107
|
<
|
76
108
|
TFieldValues extends FieldValues = FieldValues,
|
77
109
|
TContext extends object = object,
|
78
|
-
TSchema = any
|
110
|
+
TSchema = any,
|
111
|
+
TFieldTypes = FieldProps<TFieldValues>
|
79
112
|
>(
|
80
|
-
props: FormProps<TFieldValues, TContext, TSchema>,
|
113
|
+
props: FormProps<TFieldValues, TContext, TSchema, TFieldTypes>,
|
81
114
|
ref: React.ForwardedRef<HTMLFormElement>
|
82
115
|
) => {
|
83
116
|
const {
|
84
117
|
mode = 'all',
|
85
118
|
resolver,
|
119
|
+
fieldResolver,
|
120
|
+
fields,
|
86
121
|
reValidateMode,
|
87
122
|
shouldFocusError,
|
88
123
|
shouldUnregister,
|
@@ -117,10 +152,6 @@ export const Form = forwardRef(
|
|
117
152
|
resetOptions,
|
118
153
|
}
|
119
154
|
|
120
|
-
if (schema && !resolver) {
|
121
|
-
form.resolver = Form.getResolver?.(schema)
|
122
|
-
}
|
123
|
-
|
124
155
|
const methods = useForm<TFieldValues, TContext>(form)
|
125
156
|
const { handleSubmit } = methods
|
126
157
|
|
@@ -135,21 +166,34 @@ export const Form = forwardRef(
|
|
135
166
|
return () => subscription?.unsubscribe()
|
136
167
|
}, [methods, onChange])
|
137
168
|
|
138
|
-
|
139
|
-
|
140
|
-
|
141
|
-
|
169
|
+
let _children = children
|
170
|
+
if (!_children && fieldResolver) {
|
171
|
+
_children = (
|
172
|
+
<FormLayout>
|
173
|
+
<AutoFields />
|
174
|
+
<SubmitButton {...fields?.submit} />
|
175
|
+
</FormLayout>
|
176
|
+
)
|
177
|
+
}
|
142
178
|
|
143
179
|
return (
|
144
|
-
<FormProvider
|
180
|
+
<FormProvider
|
181
|
+
{...methods}
|
182
|
+
schema={schema}
|
183
|
+
fieldResolver={fieldResolver}
|
184
|
+
fields={fields}
|
185
|
+
>
|
145
186
|
<chakra.form
|
146
187
|
ref={ref}
|
147
188
|
onSubmit={handleSubmit(onSubmit, onError)}
|
148
189
|
{...rest}
|
149
190
|
className={cx('sui-form', props.className)}
|
150
191
|
>
|
151
|
-
{runIfFn(
|
152
|
-
Field,
|
192
|
+
{runIfFn(_children, {
|
193
|
+
Field: DefaultField as any,
|
194
|
+
DisplayIf: DisplayIf as any,
|
195
|
+
ArrayField: ArrayField as any,
|
196
|
+
ObjectField: ObjectField as any,
|
153
197
|
...methods,
|
154
198
|
})}
|
155
199
|
</chakra.form>
|
@@ -159,19 +203,16 @@ export const Form = forwardRef(
|
|
159
203
|
) as (<
|
160
204
|
TFieldValues extends FieldValues,
|
161
205
|
TContext extends object = object,
|
162
|
-
TSchema = any
|
206
|
+
TSchema = any,
|
207
|
+
TFieldTypes = FieldProps<TFieldValues>
|
163
208
|
>(
|
164
|
-
props: FormProps<TFieldValues, TContext, TSchema> & {
|
209
|
+
props: FormProps<TFieldValues, TContext, TSchema, TFieldTypes> & {
|
165
210
|
ref?: React.ForwardedRef<HTMLFormElement>
|
166
211
|
}
|
167
212
|
) => React.ReactElement) & {
|
168
213
|
displayName?: string
|
169
|
-
getResolver?: GetResolver
|
170
|
-
getFieldResolver: GetFieldResolver
|
171
214
|
}
|
172
215
|
|
173
|
-
Form.getFieldResolver = objectFieldResolver
|
174
|
-
|
175
216
|
Form.displayName = 'Form'
|
176
217
|
|
177
218
|
export type GetResolver = <
|
@@ -184,24 +225,3 @@ export type GetResolver = <
|
|
184
225
|
context: TContext | undefined,
|
185
226
|
options: ResolverOptions<TFieldValues>
|
186
227
|
) => Promise<ResolverResult<TFieldValues>>
|
187
|
-
|
188
|
-
export type GetFieldResolver = (schema: any) => FieldResolver
|
189
|
-
|
190
|
-
export interface CreateFormProps {
|
191
|
-
resolver?: GetResolver
|
192
|
-
}
|
193
|
-
|
194
|
-
export function createForm<Schema = any>({ resolver }: CreateFormProps) {
|
195
|
-
const CreateForm = <
|
196
|
-
TFieldValues extends FieldValues,
|
197
|
-
TContext extends object = object,
|
198
|
-
TSchema extends Schema = Schema
|
199
|
-
>(
|
200
|
-
props: FormProps<TFieldValues, TContext, TSchema>
|
201
|
-
) => {
|
202
|
-
const { schema, ...rest } = props
|
203
|
-
return <Form resolver={resolver?.(props.schema)} {...rest} />
|
204
|
-
}
|
205
|
-
|
206
|
-
return CreateForm
|
207
|
-
}
|
package/src/index.ts
CHANGED
@@ -1,8 +1,8 @@
|
|
1
1
|
export * from './display-field'
|
2
2
|
export * from './field'
|
3
3
|
export * from './fields'
|
4
|
-
export * from './
|
5
|
-
export * from './auto-form'
|
4
|
+
export * from './fields-context'
|
5
|
+
// export * from './auto-form'
|
6
6
|
export * from './layout'
|
7
7
|
export * from './submit-button'
|
8
8
|
export * from './array-field'
|
@@ -16,6 +16,48 @@ export * from './watch-field'
|
|
16
16
|
export * from './input-right-button'
|
17
17
|
export * from './select'
|
18
18
|
export * from './password-input'
|
19
|
+
export * from './radio'
|
20
|
+
|
21
|
+
export * from './base-field'
|
22
|
+
|
23
|
+
export {
|
24
|
+
CheckboxField,
|
25
|
+
InputField,
|
26
|
+
NativeSelectField,
|
27
|
+
NumberInputField,
|
28
|
+
PasswordInputField,
|
29
|
+
PinField,
|
30
|
+
RadioField,
|
31
|
+
SelectField,
|
32
|
+
SwitchField,
|
33
|
+
TextareaField,
|
34
|
+
defaultFieldTypes,
|
35
|
+
type DefaultFields,
|
36
|
+
type InputFieldProps,
|
37
|
+
type NumberInputFieldProps,
|
38
|
+
type PinFieldProps,
|
39
|
+
} from './default-fields'
|
40
|
+
|
41
|
+
export type {
|
42
|
+
FieldProps,
|
43
|
+
WithFields,
|
44
|
+
BaseFieldProps,
|
45
|
+
FieldOptions,
|
46
|
+
} from './types'
|
47
|
+
|
48
|
+
export { createForm, type CreateFormProps } from './create-form'
|
49
|
+
export { createField, type CreateFieldOptions } from './create-field'
|
50
|
+
|
51
|
+
export {
|
52
|
+
Form as BaseForm,
|
53
|
+
type FormProps,
|
54
|
+
type FormRenderContext,
|
55
|
+
} from './form'
|
56
|
+
|
57
|
+
export { FormProvider, useFormContext } from './form-context'
|
58
|
+
|
59
|
+
import { createForm } from './create-form'
|
60
|
+
export const Form = createForm()
|
19
61
|
|
20
62
|
export type {
|
21
63
|
BatchFieldArrayUpdate,
|
@@ -120,9 +162,7 @@ export {
|
|
120
162
|
useController,
|
121
163
|
useFieldArray,
|
122
164
|
useForm,
|
123
|
-
useFormContext,
|
124
165
|
useFormState,
|
125
166
|
useWatch,
|
126
167
|
Controller,
|
127
|
-
FormProvider,
|
128
168
|
} from 'react-hook-form'
|
@@ -10,7 +10,7 @@ import * as React from 'react'
|
|
10
10
|
|
11
11
|
import { ComponentStory } from '@storybook/react'
|
12
12
|
|
13
|
-
import { InputRightButton } from '
|
13
|
+
import { InputRightButton } from './'
|
14
14
|
|
15
15
|
import { FiEye } from 'react-icons/fi'
|
16
16
|
|
@@ -37,7 +37,7 @@ const Template: ComponentStory<typeof InputRightButton> = (args) => (
|
|
37
37
|
|
38
38
|
export const Basic = Template.bind({})
|
39
39
|
Basic.args = {
|
40
|
-
|
40
|
+
children: 'Save',
|
41
41
|
}
|
42
42
|
|
43
43
|
export const WithIcon = Template.bind({})
|
package/src/layout.tsx
CHANGED
@@ -1,9 +1,15 @@
|
|
1
1
|
import * as React from 'react'
|
2
2
|
|
3
|
-
import {
|
4
|
-
|
3
|
+
import {
|
4
|
+
chakra,
|
5
|
+
ResponsiveValue,
|
6
|
+
SimpleGrid,
|
7
|
+
SimpleGridProps,
|
8
|
+
useTheme,
|
9
|
+
} from '@chakra-ui/react'
|
10
|
+
import { cx } from '@chakra-ui/utils'
|
5
11
|
|
6
|
-
export
|
12
|
+
export interface FormLayoutProps extends SimpleGridProps {}
|
7
13
|
|
8
14
|
interface FormLayoutItemProps {
|
9
15
|
children: React.ReactNode
|
@@ -13,20 +19,21 @@ const FormLayoutItem: React.FC<FormLayoutItemProps> = ({ children }) => {
|
|
13
19
|
return <chakra.div>{children}</chakra.div>
|
14
20
|
}
|
15
21
|
|
16
|
-
|
17
|
-
FormLayoutItem.displayName = 'FormLayoutItem'
|
18
|
-
}
|
22
|
+
FormLayoutItem.displayName = 'FormLayoutItem'
|
19
23
|
|
20
24
|
/**
|
21
|
-
*
|
25
|
+
* Create consistent field spacing and positioning.
|
26
|
+
*
|
22
27
|
*
|
23
28
|
* Renders form items in a `SimpleGrid`
|
24
29
|
* @see https://chakra-ui.com/docs/layout/simple-grid
|
30
|
+
*
|
31
|
+
* @see https://saas-ui.dev/docs/components/forms/form
|
25
32
|
*/
|
26
33
|
export const FormLayout = ({ children, ...props }: FormLayoutProps) => {
|
27
34
|
const theme = useTheme()
|
28
35
|
|
29
|
-
const defaultProps = theme.components?.
|
36
|
+
const defaultProps = theme.components?.SuiFormLayout?.defaultProps ?? {
|
30
37
|
spacing: 4,
|
31
38
|
}
|
32
39
|
|
@@ -50,6 +57,4 @@ export const FormLayout = ({ children, ...props }: FormLayoutProps) => {
|
|
50
57
|
)
|
51
58
|
}
|
52
59
|
|
53
|
-
|
54
|
-
FormLayout.displayName = 'FormLayout'
|
55
|
-
}
|
60
|
+
FormLayout.displayName = 'FormLayout'
|
@@ -2,7 +2,7 @@ import { Container } from '@chakra-ui/react'
|
|
2
2
|
import * as React from 'react'
|
3
3
|
import { Story, Meta } from '@storybook/react'
|
4
4
|
|
5
|
-
import { NumberInput } from '
|
5
|
+
import { NumberInput } from '.'
|
6
6
|
|
7
7
|
export default {
|
8
8
|
title: 'Components/Forms/NumberInput',
|
@@ -34,6 +34,6 @@ MinMax.args = {
|
|
34
34
|
|
35
35
|
export const WithFormatter = Template.bind({})
|
36
36
|
WithFormatter.args = {
|
37
|
-
format: (value) => `$${value}`, // use any currency formatter here
|
38
|
-
parse: (value) => value.replace('$', ''),
|
37
|
+
format: (value: any) => `$${value}`, // use any currency formatter here
|
38
|
+
parse: (value: any) => value.replace('$', ''),
|
39
39
|
}
|
@@ -9,7 +9,8 @@ import {
|
|
9
9
|
NumberDecrementStepper,
|
10
10
|
NumberInputProps as ChakraNumberInputProps,
|
11
11
|
} from '@chakra-ui/react'
|
12
|
-
|
12
|
+
|
13
|
+
import { ChevronDownIcon, ChevronUpIcon } from '@saas-ui/core'
|
13
14
|
|
14
15
|
interface NumberInputOptions {
|
15
16
|
/**
|
@@ -31,7 +32,12 @@ export interface NumberInputProps
|
|
31
32
|
NumberInputOptions {}
|
32
33
|
|
33
34
|
export const NumberInput = forwardRef<NumberInputProps, 'div'>((props, ref) => {
|
34
|
-
const {
|
35
|
+
const {
|
36
|
+
hideStepper,
|
37
|
+
incrementIcon = <ChevronUpIcon />,
|
38
|
+
decrementIcon = <ChevronDownIcon />,
|
39
|
+
...rest
|
40
|
+
} = props
|
35
41
|
|
36
42
|
return (
|
37
43
|
<ChakraNumberInput {...rest} ref={ref}>
|
@@ -51,6 +57,4 @@ NumberInput.defaultProps = {
|
|
51
57
|
hideStepper: false,
|
52
58
|
}
|
53
59
|
|
54
|
-
|
55
|
-
NumberInput.displayName = 'NumberInput'
|
56
|
-
}
|
60
|
+
NumberInput.displayName = 'NumberInput'
|
package/src/object-field.tsx
CHANGED
@@ -6,15 +6,18 @@ import {
|
|
6
6
|
ResponsiveValue,
|
7
7
|
useStyleConfig,
|
8
8
|
} from '@chakra-ui/react'
|
9
|
-
import { __DEV__ } from '@chakra-ui/utils'
|
10
9
|
|
11
10
|
import { FormLayout } from './layout'
|
12
|
-
import {
|
11
|
+
import { BaseFieldProps } from './types'
|
13
12
|
|
14
13
|
import { mapNestedFields } from './utils'
|
14
|
+
import { FieldPath, FieldValues } from 'react-hook-form'
|
15
15
|
|
16
|
-
export interface ObjectFieldProps
|
17
|
-
|
16
|
+
export interface ObjectFieldProps<
|
17
|
+
TFieldValues extends FieldValues = FieldValues,
|
18
|
+
TName extends FieldPath<TFieldValues> = FieldPath<TFieldValues>
|
19
|
+
> extends BaseFieldProps {
|
20
|
+
name: TName
|
18
21
|
children: React.ReactNode
|
19
22
|
columns?: ResponsiveValue<number>
|
20
23
|
spacing?: ResponsiveValue<string | number>
|
@@ -24,7 +27,11 @@ export const FormLegend = (props: FormLabelProps) => {
|
|
24
27
|
const styles = useStyleConfig('SuiFormLegend')
|
25
28
|
return <FormLabel as="legend" sx={styles} {...props} />
|
26
29
|
}
|
27
|
-
|
30
|
+
/**
|
31
|
+
* The object field component.
|
32
|
+
*
|
33
|
+
* @see Docs https://saas-ui.dev/docs/components/forms/object-field
|
34
|
+
*/
|
28
35
|
export const ObjectField: React.FC<ObjectFieldProps> = (props) => {
|
29
36
|
const { name, label, hideLabel, children, columns, spacing, ...fieldProps } =
|
30
37
|
props
|
@@ -39,6 +46,4 @@ export const ObjectField: React.FC<ObjectFieldProps> = (props) => {
|
|
39
46
|
)
|
40
47
|
}
|
41
48
|
|
42
|
-
|
43
|
-
ObjectField.displayName = 'ObjectField'
|
44
|
-
}
|
49
|
+
ObjectField.displayName = 'ObjectField'
|
@@ -1,8 +1,15 @@
|
|
1
|
-
import {
|
1
|
+
import {
|
2
|
+
Container,
|
3
|
+
FormControl,
|
4
|
+
FormLabel,
|
5
|
+
Icon,
|
6
|
+
InputLeftAddon,
|
7
|
+
InputLeftElement,
|
8
|
+
} from '@chakra-ui/react'
|
2
9
|
import { Story } from '@storybook/react'
|
3
10
|
import * as React from 'react'
|
4
11
|
|
5
|
-
import { FiEye, FiEyeOff } from 'react-icons/fi'
|
12
|
+
import { FiEye, FiEyeOff, FiLock } from 'react-icons/fi'
|
6
13
|
|
7
14
|
import { PasswordInput } from './password-input'
|
8
15
|
|
@@ -48,3 +55,17 @@ export const CustomWidth: Story = () => (
|
|
48
55
|
<PasswordInput name="password" width="200px" />
|
49
56
|
</FormControl>
|
50
57
|
)
|
58
|
+
|
59
|
+
export const LeftAddon: Story = () => (
|
60
|
+
<FormControl>
|
61
|
+
<FormLabel>Password</FormLabel>
|
62
|
+
<PasswordInput
|
63
|
+
name="password"
|
64
|
+
leftAddon={
|
65
|
+
<InputLeftElement>
|
66
|
+
<FiLock />
|
67
|
+
</InputLeftElement>
|
68
|
+
}
|
69
|
+
/>
|
70
|
+
</FormControl>
|
71
|
+
)
|
@@ -1,14 +1,15 @@
|
|
1
1
|
import React, { useState } from 'react'
|
2
2
|
|
3
3
|
import { forwardRef, InputGroup, Input, InputProps } from '@chakra-ui/react'
|
4
|
-
|
5
|
-
import { ViewIcon, ViewOffIcon } from '@
|
4
|
+
|
5
|
+
import { ViewIcon, ViewOffIcon } from '@saas-ui/core/icons'
|
6
6
|
|
7
7
|
import { InputRightButton } from '../input-right-button'
|
8
8
|
|
9
9
|
interface PasswordOptions {
|
10
10
|
viewIcon?: React.ReactNode
|
11
11
|
viewOffIcon?: React.ReactNode
|
12
|
+
leftAddon?: React.ReactNode
|
12
13
|
}
|
13
14
|
|
14
15
|
export interface PasswordInputProps extends InputProps, PasswordOptions {}
|
@@ -23,6 +24,7 @@ export const PasswordInput = forwardRef<PasswordInputProps, 'div'>(
|
|
23
24
|
width,
|
24
25
|
size,
|
25
26
|
variant,
|
27
|
+
leftAddon,
|
26
28
|
...inputProps
|
27
29
|
} = props
|
28
30
|
const [show, setShow] = useState(false)
|
@@ -45,13 +47,13 @@ export const PasswordInput = forwardRef<PasswordInputProps, 'div'>(
|
|
45
47
|
|
46
48
|
return (
|
47
49
|
<InputGroup {...groupProps}>
|
50
|
+
{leftAddon}
|
48
51
|
<Input
|
49
52
|
{...inputProps}
|
50
53
|
ref={ref}
|
51
54
|
type={show ? 'text' : 'password'}
|
52
55
|
autoComplete={show ? 'off' : autoComplete}
|
53
56
|
/>
|
54
|
-
|
55
57
|
<InputRightButton
|
56
58
|
onClick={handleClick}
|
57
59
|
aria-label={label}
|
@@ -64,6 +66,4 @@ export const PasswordInput = forwardRef<PasswordInputProps, 'div'>(
|
|
64
66
|
}
|
65
67
|
)
|
66
68
|
|
67
|
-
|
68
|
-
PasswordInput.displayName = 'PasswordInput'
|
69
|
-
}
|
69
|
+
PasswordInput.displayName = 'PasswordInput'
|
@@ -8,8 +8,6 @@ import {
|
|
8
8
|
SystemProps,
|
9
9
|
} from '@chakra-ui/react'
|
10
10
|
|
11
|
-
import { __DEV__ } from '@chakra-ui/utils'
|
12
|
-
|
13
11
|
interface PinInputOptions {
|
14
12
|
/**
|
15
13
|
* The pin length.
|
@@ -45,6 +43,4 @@ PinInput.defaultProps = {
|
|
45
43
|
pinLength: 4,
|
46
44
|
}
|
47
45
|
|
48
|
-
|
49
|
-
PinInput.displayName = 'PinInput'
|
50
|
-
}
|
46
|
+
PinInput.displayName = 'PinInput'
|
@@ -10,15 +10,17 @@ import {
|
|
10
10
|
SystemProps,
|
11
11
|
StackDirection,
|
12
12
|
} from '@chakra-ui/react'
|
13
|
-
import {
|
13
|
+
import { FieldOptions, FieldOption } from '../types'
|
14
|
+
import { mapOptions } from '../utils'
|
14
15
|
|
15
|
-
interface
|
16
|
-
value
|
17
|
-
|
18
|
-
|
16
|
+
export interface RadioOption
|
17
|
+
extends Omit<RadioProps, 'value' | 'label'>,
|
18
|
+
FieldOption {}
|
19
|
+
|
20
|
+
export type RadioOptions = FieldOptions<RadioOption>
|
19
21
|
|
20
22
|
interface RadioInputOptions {
|
21
|
-
options:
|
23
|
+
options: RadioOptions
|
22
24
|
spacing?: SystemProps['margin']
|
23
25
|
direction?: StackDirection
|
24
26
|
}
|
@@ -28,9 +30,11 @@ export interface RadioInputProps
|
|
28
30
|
RadioInputOptions {}
|
29
31
|
|
30
32
|
export const RadioInput = forwardRef<RadioInputProps, 'div'>(
|
31
|
-
({ options, spacing, direction, ...props }, ref) => {
|
33
|
+
({ options: optionsProp, spacing, direction, ...props }, ref) => {
|
32
34
|
const { onBlur, onChange, ...groupProps } = props
|
33
35
|
|
36
|
+
const options = mapOptions(optionsProp)
|
37
|
+
|
34
38
|
return (
|
35
39
|
<RadioGroup onChange={onChange} {...groupProps}>
|
36
40
|
<Stack spacing={spacing} direction={direction}>
|
@@ -53,6 +57,4 @@ export const RadioInput = forwardRef<RadioInputProps, 'div'>(
|
|
53
57
|
}
|
54
58
|
)
|
55
59
|
|
56
|
-
|
57
|
-
RadioInput.displayName = 'RadioInput'
|
58
|
-
}
|
60
|
+
RadioInput.displayName = 'RadioInput'
|
@@ -5,7 +5,6 @@ import {
|
|
5
5
|
Select as ChakraSelect,
|
6
6
|
SelectProps as ChakraSelectProps,
|
7
7
|
} from '@chakra-ui/react'
|
8
|
-
import { __DEV__ } from '@chakra-ui/utils'
|
9
8
|
|
10
9
|
interface Option {
|
11
10
|
value: string
|
@@ -37,6 +36,4 @@ export const NativeSelect = forwardRef<NativeSelectProps, 'select'>(
|
|
37
36
|
}
|
38
37
|
)
|
39
38
|
|
40
|
-
|
41
|
-
NativeSelect.displayName = 'NativeSelect'
|
42
|
-
}
|
39
|
+
NativeSelect.displayName = 'NativeSelect'
|