@graphcommerce/ecommerce-ui 9.0.0-canary.78 → 9.0.0-canary.80
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 +10 -0
- package/components/FormComponents/ActionCardListForm.tsx +85 -0
- package/components/FormComponents/AutoCompleteElement.tsx +101 -90
- package/components/FormComponents/CheckboxButtonGroup.tsx +27 -31
- package/components/FormComponents/CheckboxElement.tsx +56 -60
- package/components/FormComponents/MultiSelectElement.tsx +103 -110
- package/components/FormComponents/NumberFieldElement.tsx +4 -0
- package/components/FormComponents/RadioButtonGroup.tsx +27 -29
- package/components/FormComponents/SliderElement.tsx +28 -29
- package/components/FormComponents/SwitchElement.tsx +15 -13
- package/components/FormComponents/TextFieldElement.tsx +3 -1
- package/components/FormComponents/ToggleButtonGroup.tsx +49 -48
- package/components/FormComponents/index.ts +1 -0
- package/package.json +7 -7
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,15 @@
|
|
|
1
1
|
# @graphcommerce/ecommerce-ui
|
|
2
2
|
|
|
3
|
+
## 9.0.0-canary.80
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- [#2341](https://github.com/graphcommerce-org/graphcommerce/pull/2341) [`7085b4a`](https://github.com/graphcommerce-org/graphcommerce/commit/7085b4a86088328fe54dc4e82ccd296d6459cae7) - Updated all form FieldElements to also accept defaultValue, shouldUnregister and disabled. Moved AutoCompleteElement, CheckboxElement, MultiSelectElement, SliderElement, SwitchElement, ToggleButtonGroup to useController. Removed all parseError props ([@Giovanni-Schroevers](https://github.com/Giovanni-Schroevers))
|
|
8
|
+
|
|
9
|
+
- [#2341](https://github.com/graphcommerce-org/graphcommerce/pull/2341) [`022cbd6`](https://github.com/graphcommerce-org/graphcommerce/commit/022cbd664ea4e8a82997c5edf4451b9182558429) - Moved ActionCardListForm to @graphcommerce/ecommerce-ui to resolve issue with circular dependencies. ([@Giovanni-Schroevers](https://github.com/Giovanni-Schroevers))
|
|
10
|
+
|
|
11
|
+
## 9.0.0-canary.79
|
|
12
|
+
|
|
3
13
|
## 9.0.0-canary.78
|
|
4
14
|
|
|
5
15
|
## 9.0.0-canary.77
|
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
import { ActionCardList, ActionCardListProps, ActionCardProps } from '@graphcommerce/next-ui'
|
|
2
|
+
import { ControllerProps, FieldValues, useController } from '@graphcommerce/react-hook-form'
|
|
3
|
+
import React, { MouseEventHandler } from 'react'
|
|
4
|
+
|
|
5
|
+
export type ActionCardItemBase = Pick<ActionCardProps, 'value'>
|
|
6
|
+
|
|
7
|
+
export type ActionCardItemRenderProps<T> = ActionCardProps & {
|
|
8
|
+
onReset: MouseEventHandler<HTMLElement>
|
|
9
|
+
} & T
|
|
10
|
+
|
|
11
|
+
export type ActionCardListFormProps<A, F extends FieldValues = FieldValues> = Omit<
|
|
12
|
+
ActionCardListProps,
|
|
13
|
+
'value' | 'error' | 'onChange' | 'children'
|
|
14
|
+
> &
|
|
15
|
+
Omit<ControllerProps<F>, 'render'> & {
|
|
16
|
+
items: A[]
|
|
17
|
+
render: React.FC<ActionCardItemRenderProps<A>>
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
export function ActionCardListForm<
|
|
21
|
+
T extends ActionCardItemBase,
|
|
22
|
+
F extends FieldValues = FieldValues,
|
|
23
|
+
>(props: ActionCardListFormProps<T, F>) {
|
|
24
|
+
const {
|
|
25
|
+
required,
|
|
26
|
+
rules,
|
|
27
|
+
items,
|
|
28
|
+
render,
|
|
29
|
+
control,
|
|
30
|
+
name,
|
|
31
|
+
errorMessage,
|
|
32
|
+
defaultValue,
|
|
33
|
+
multiple,
|
|
34
|
+
disabled,
|
|
35
|
+
shouldUnregister,
|
|
36
|
+
...other
|
|
37
|
+
} = props
|
|
38
|
+
const RenderItem = render as React.FC<ActionCardItemRenderProps<ActionCardItemBase>>
|
|
39
|
+
|
|
40
|
+
function onSelect(itemValue: unknown, selectValues: unknown) {
|
|
41
|
+
return multiple
|
|
42
|
+
? Array.isArray(selectValues) && selectValues.some((selectValue) => selectValue === itemValue)
|
|
43
|
+
: selectValues === itemValue
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
const {
|
|
47
|
+
field: { onChange, value, ref },
|
|
48
|
+
fieldState,
|
|
49
|
+
formState,
|
|
50
|
+
} = useController({
|
|
51
|
+
...props,
|
|
52
|
+
control,
|
|
53
|
+
name,
|
|
54
|
+
defaultValue,
|
|
55
|
+
rules: { required, ...rules },
|
|
56
|
+
disabled,
|
|
57
|
+
shouldUnregister,
|
|
58
|
+
})
|
|
59
|
+
|
|
60
|
+
return (
|
|
61
|
+
<ActionCardList
|
|
62
|
+
{...other}
|
|
63
|
+
multiple={multiple}
|
|
64
|
+
required={required}
|
|
65
|
+
value={value}
|
|
66
|
+
ref={ref}
|
|
67
|
+
onChange={(_, incomming) => onChange(incomming)}
|
|
68
|
+
error={formState.isSubmitted && !!fieldState.error}
|
|
69
|
+
errorMessage={fieldState.error?.message}
|
|
70
|
+
>
|
|
71
|
+
{items.map((item) => (
|
|
72
|
+
<RenderItem
|
|
73
|
+
{...item}
|
|
74
|
+
key={`${item.value}`}
|
|
75
|
+
value={item.value}
|
|
76
|
+
selected={onSelect(item.value, value)}
|
|
77
|
+
onReset={(e) => {
|
|
78
|
+
e.preventDefault()
|
|
79
|
+
onChange(null)
|
|
80
|
+
}}
|
|
81
|
+
/>
|
|
82
|
+
))}
|
|
83
|
+
</ActionCardList>
|
|
84
|
+
)
|
|
85
|
+
}
|
|
@@ -1,5 +1,10 @@
|
|
|
1
1
|
/* eslint-disable @typescript-eslint/no-restricted-imports */
|
|
2
|
-
import {
|
|
2
|
+
import {
|
|
3
|
+
Controller,
|
|
4
|
+
ControllerProps,
|
|
5
|
+
FieldValues,
|
|
6
|
+
useController,
|
|
7
|
+
} from '@graphcommerce/react-hook-form'
|
|
3
8
|
import { i18n } from '@lingui/core'
|
|
4
9
|
import {
|
|
5
10
|
Autocomplete,
|
|
@@ -48,6 +53,9 @@ export function AutocompleteElement<TFieldValues extends FieldValues>({
|
|
|
48
53
|
multiple,
|
|
49
54
|
matchId,
|
|
50
55
|
label,
|
|
56
|
+
disabled,
|
|
57
|
+
defaultValue,
|
|
58
|
+
shouldUnregister,
|
|
51
59
|
}: AutocompleteElementProps<
|
|
52
60
|
TFieldValues,
|
|
53
61
|
AutoDefault | string | any,
|
|
@@ -60,99 +68,102 @@ export function AutocompleteElement<TFieldValues extends FieldValues>({
|
|
|
60
68
|
required: rules?.required || i18n._(/* i18n */ 'This field is required'),
|
|
61
69
|
}),
|
|
62
70
|
}
|
|
71
|
+
|
|
72
|
+
const {
|
|
73
|
+
field: { onChange, onBlur, value, ...fieldRest },
|
|
74
|
+
fieldState: { error },
|
|
75
|
+
} = useController({
|
|
76
|
+
name,
|
|
77
|
+
control,
|
|
78
|
+
rules: validationRules,
|
|
79
|
+
defaultValue,
|
|
80
|
+
disabled,
|
|
81
|
+
shouldUnregister,
|
|
82
|
+
})
|
|
83
|
+
|
|
84
|
+
const values = Array.isArray(value) ? (value as (typeof value)[]) : [value]
|
|
85
|
+
let currentValue = multiple ? value || [] : value || null
|
|
86
|
+
if (matchId) {
|
|
87
|
+
currentValue = multiple
|
|
88
|
+
? values.map((i: any) => options.find((j) => (j.id || j) === i))
|
|
89
|
+
: options.find((i) => (i.id || i) === value) || null
|
|
90
|
+
}
|
|
91
|
+
|
|
63
92
|
return (
|
|
64
|
-
<
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
93
|
+
<Autocomplete
|
|
94
|
+
{...autocompleteProps}
|
|
95
|
+
value={currentValue}
|
|
96
|
+
loading={loading}
|
|
97
|
+
multiple={multiple}
|
|
98
|
+
options={options}
|
|
99
|
+
disableCloseOnSelect={
|
|
100
|
+
typeof autocompleteProps?.disableCloseOnSelect === 'boolean'
|
|
101
|
+
? autocompleteProps.disableCloseOnSelect
|
|
102
|
+
: !!multiple
|
|
103
|
+
}
|
|
104
|
+
isOptionEqualToValue={
|
|
105
|
+
autocompleteProps?.isOptionEqualToValue
|
|
106
|
+
? autocompleteProps.isOptionEqualToValue
|
|
107
|
+
: (option, v) => (v ? option.id === (v?.id || v) : false)
|
|
108
|
+
}
|
|
109
|
+
getOptionLabel={
|
|
110
|
+
autocompleteProps?.getOptionLabel
|
|
111
|
+
? autocompleteProps.getOptionLabel
|
|
112
|
+
: (option) => `${option?.label || option}`
|
|
113
|
+
}
|
|
114
|
+
onChange={(event, value, reason, details) => {
|
|
115
|
+
let changedVal = value
|
|
71
116
|
if (matchId) {
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
117
|
+
changedVal = Array.isArray(value) ? value.map((i: any) => i?.id || i) : value?.id || value
|
|
118
|
+
}
|
|
119
|
+
onChange(changedVal)
|
|
120
|
+
if (autocompleteProps?.onChange) {
|
|
121
|
+
autocompleteProps.onChange(event, value, reason, details)
|
|
122
|
+
}
|
|
123
|
+
}}
|
|
124
|
+
renderOption={
|
|
125
|
+
autocompleteProps?.renderOption ??
|
|
126
|
+
(showCheckbox
|
|
127
|
+
? (props, option, { selected }) => (
|
|
128
|
+
<li {...props}>
|
|
129
|
+
<Checkbox sx={{ marginRight: 1 }} checked={selected} />
|
|
130
|
+
{autocompleteProps?.getOptionLabel?.(option) || option.label || option}
|
|
131
|
+
</li>
|
|
132
|
+
)
|
|
133
|
+
: undefined)
|
|
134
|
+
}
|
|
135
|
+
onBlur={(event) => {
|
|
136
|
+
onBlur()
|
|
137
|
+
if (typeof autocompleteProps?.onBlur === 'function') {
|
|
138
|
+
autocompleteProps.onBlur(event)
|
|
75
139
|
}
|
|
76
|
-
return (
|
|
77
|
-
<Autocomplete
|
|
78
|
-
{...autocompleteProps}
|
|
79
|
-
value={currentValue}
|
|
80
|
-
loading={loading}
|
|
81
|
-
multiple={multiple}
|
|
82
|
-
options={options}
|
|
83
|
-
disableCloseOnSelect={
|
|
84
|
-
typeof autocompleteProps?.disableCloseOnSelect === 'boolean'
|
|
85
|
-
? autocompleteProps.disableCloseOnSelect
|
|
86
|
-
: !!multiple
|
|
87
|
-
}
|
|
88
|
-
isOptionEqualToValue={
|
|
89
|
-
autocompleteProps?.isOptionEqualToValue
|
|
90
|
-
? autocompleteProps.isOptionEqualToValue
|
|
91
|
-
: (option, v) => (v ? option.id === (v?.id || v) : false)
|
|
92
|
-
}
|
|
93
|
-
getOptionLabel={
|
|
94
|
-
autocompleteProps?.getOptionLabel
|
|
95
|
-
? autocompleteProps.getOptionLabel
|
|
96
|
-
: (option) => `${option?.label || option}`
|
|
97
|
-
}
|
|
98
|
-
onChange={(event, value, reason, details) => {
|
|
99
|
-
let changedVal = value
|
|
100
|
-
if (matchId) {
|
|
101
|
-
changedVal = Array.isArray(value)
|
|
102
|
-
? value.map((i: any) => i?.id || i)
|
|
103
|
-
: value?.id || value
|
|
104
|
-
}
|
|
105
|
-
onChange(changedVal)
|
|
106
|
-
if (autocompleteProps?.onChange) {
|
|
107
|
-
autocompleteProps.onChange(event, value, reason, details)
|
|
108
|
-
}
|
|
109
|
-
}}
|
|
110
|
-
renderOption={
|
|
111
|
-
autocompleteProps?.renderOption ??
|
|
112
|
-
(showCheckbox
|
|
113
|
-
? (props, option, { selected }) => (
|
|
114
|
-
<li {...props}>
|
|
115
|
-
<Checkbox sx={{ marginRight: 1 }} checked={selected} />
|
|
116
|
-
{autocompleteProps?.getOptionLabel?.(option) || option.label || option}
|
|
117
|
-
</li>
|
|
118
|
-
)
|
|
119
|
-
: undefined)
|
|
120
|
-
}
|
|
121
|
-
onBlur={(event) => {
|
|
122
|
-
onBlur()
|
|
123
|
-
if (typeof autocompleteProps?.onBlur === 'function') {
|
|
124
|
-
autocompleteProps.onBlur(event)
|
|
125
|
-
}
|
|
126
|
-
}}
|
|
127
|
-
renderInput={(params) => (
|
|
128
|
-
<TextField
|
|
129
|
-
name={name}
|
|
130
|
-
required={rules?.required ? true : required}
|
|
131
|
-
label={label}
|
|
132
|
-
{...textFieldProps}
|
|
133
|
-
{...params}
|
|
134
|
-
error={!!error}
|
|
135
|
-
InputProps={{
|
|
136
|
-
...params.InputProps,
|
|
137
|
-
endAdornment: (
|
|
138
|
-
<>
|
|
139
|
-
{loading ? <CircularProgress color='inherit' size={20} /> : null}
|
|
140
|
-
{params.InputProps.endAdornment}
|
|
141
|
-
</>
|
|
142
|
-
),
|
|
143
|
-
...textFieldProps?.InputProps,
|
|
144
|
-
}}
|
|
145
|
-
inputProps={{
|
|
146
|
-
...params.inputProps,
|
|
147
|
-
...textFieldProps?.inputProps,
|
|
148
|
-
}}
|
|
149
|
-
helperText={error ? error.message : textFieldProps?.helperText}
|
|
150
|
-
/>
|
|
151
|
-
)}
|
|
152
|
-
{...fieldRest}
|
|
153
|
-
/>
|
|
154
|
-
)
|
|
155
140
|
}}
|
|
141
|
+
renderInput={(params) => (
|
|
142
|
+
<TextField
|
|
143
|
+
name={name}
|
|
144
|
+
required={rules?.required ? true : required}
|
|
145
|
+
label={label}
|
|
146
|
+
{...textFieldProps}
|
|
147
|
+
{...params}
|
|
148
|
+
error={!!error}
|
|
149
|
+
InputProps={{
|
|
150
|
+
...params.InputProps,
|
|
151
|
+
endAdornment: (
|
|
152
|
+
<>
|
|
153
|
+
{loading ? <CircularProgress color='inherit' size={20} /> : null}
|
|
154
|
+
{params.InputProps.endAdornment}
|
|
155
|
+
</>
|
|
156
|
+
),
|
|
157
|
+
...textFieldProps?.InputProps,
|
|
158
|
+
}}
|
|
159
|
+
inputProps={{
|
|
160
|
+
...params.inputProps,
|
|
161
|
+
...textFieldProps?.inputProps,
|
|
162
|
+
}}
|
|
163
|
+
helperText={error ? error.message : textFieldProps?.helperText}
|
|
164
|
+
/>
|
|
165
|
+
)}
|
|
166
|
+
{...fieldRest}
|
|
156
167
|
/>
|
|
157
168
|
)
|
|
158
169
|
}
|
|
@@ -1,10 +1,4 @@
|
|
|
1
|
-
|
|
2
|
-
import {
|
|
3
|
-
FieldError,
|
|
4
|
-
useController,
|
|
5
|
-
FieldValues,
|
|
6
|
-
UseControllerProps,
|
|
7
|
-
} from '@graphcommerce/react-hook-form'
|
|
1
|
+
import { useController, FieldValues, UseControllerProps } from '@graphcommerce/react-hook-form'
|
|
8
2
|
import { i18n } from '@lingui/core'
|
|
9
3
|
import {
|
|
10
4
|
Checkbox,
|
|
@@ -21,8 +15,6 @@ export type CheckboxButtonGroupProps<T extends FieldValues> = {
|
|
|
21
15
|
options: { id: string | number; label: string }[] | any[]
|
|
22
16
|
helperText?: string
|
|
23
17
|
required?: boolean
|
|
24
|
-
/** @deprecated Form value parsing should happen in the handleSubmit function of the form */
|
|
25
|
-
parseError?: (error: FieldError) => string
|
|
26
18
|
label?: string
|
|
27
19
|
labelKey?: string
|
|
28
20
|
valueKey?: string
|
|
@@ -33,22 +25,27 @@ export type CheckboxButtonGroupProps<T extends FieldValues> = {
|
|
|
33
25
|
checkboxColor?: CheckboxProps['color']
|
|
34
26
|
} & UseControllerProps<T>
|
|
35
27
|
|
|
36
|
-
export function CheckboxButtonGroup<TFieldValues extends FieldValues>(
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
28
|
+
export function CheckboxButtonGroup<TFieldValues extends FieldValues>(
|
|
29
|
+
props: CheckboxButtonGroupProps<TFieldValues>,
|
|
30
|
+
): JSX.Element {
|
|
31
|
+
const {
|
|
32
|
+
helperText,
|
|
33
|
+
options,
|
|
34
|
+
label,
|
|
35
|
+
name,
|
|
36
|
+
required,
|
|
37
|
+
labelKey = 'label',
|
|
38
|
+
valueKey = 'id',
|
|
39
|
+
returnObject,
|
|
40
|
+
disabled,
|
|
41
|
+
row,
|
|
42
|
+
control,
|
|
43
|
+
checkboxColor,
|
|
44
|
+
defaultValue,
|
|
45
|
+
shouldUnregister,
|
|
46
|
+
...rest
|
|
47
|
+
} = props
|
|
48
|
+
|
|
52
49
|
const theme = useTheme()
|
|
53
50
|
const {
|
|
54
51
|
field: { value = [], onChange },
|
|
@@ -57,13 +54,12 @@ export function CheckboxButtonGroup<TFieldValues extends FieldValues>({
|
|
|
57
54
|
name,
|
|
58
55
|
rules: required ? { required: i18n._(/* i18n */ 'This field is required') } : undefined,
|
|
59
56
|
control,
|
|
57
|
+
defaultValue,
|
|
58
|
+
disabled,
|
|
59
|
+
shouldUnregister,
|
|
60
60
|
})
|
|
61
61
|
|
|
62
|
-
|
|
63
|
-
? typeof parseError === 'function'
|
|
64
|
-
? parseError(error)
|
|
65
|
-
: error.message
|
|
66
|
-
: helperText
|
|
62
|
+
const parsedHelperText = error ? error.message : helperText
|
|
67
63
|
|
|
68
64
|
const handleChange = (index: number | string) => {
|
|
69
65
|
const newArray: (string | number)[] | any[] = [...value]
|
|
@@ -120,7 +116,7 @@ export function CheckboxButtonGroup<TFieldValues extends FieldValues>({
|
|
|
120
116
|
)
|
|
121
117
|
})}
|
|
122
118
|
</FormGroup>
|
|
123
|
-
{
|
|
119
|
+
{parsedHelperText && <FormHelperText>{parsedHelperText}</FormHelperText>}
|
|
124
120
|
</FormControl>
|
|
125
121
|
)
|
|
126
122
|
}
|
|
@@ -1,9 +1,4 @@
|
|
|
1
|
-
import {
|
|
2
|
-
Controller,
|
|
3
|
-
ControllerProps,
|
|
4
|
-
FieldError,
|
|
5
|
-
FieldValues,
|
|
6
|
-
} from '@graphcommerce/react-hook-form'
|
|
1
|
+
import { ControllerProps, FieldValues, useController } from '@graphcommerce/react-hook-form'
|
|
7
2
|
import { i18n } from '@lingui/core'
|
|
8
3
|
import {
|
|
9
4
|
Checkbox,
|
|
@@ -19,70 +14,71 @@ import {
|
|
|
19
14
|
} from '@mui/material'
|
|
20
15
|
|
|
21
16
|
export type CheckboxElementProps<T extends FieldValues> = Omit<CheckboxProps, 'name'> & {
|
|
22
|
-
/** @deprecated Form value parsing should happen in the handleSubmit function of the form */
|
|
23
|
-
parseError?: (error: FieldError) => string
|
|
24
17
|
label?: FormControlLabelProps['label']
|
|
25
18
|
helperText?: string
|
|
26
19
|
sx?: SxProps<Theme>
|
|
27
20
|
formControl?: Omit<FormControlProps<'div'>, 'required' | 'error'>
|
|
28
21
|
} & Omit<ControllerProps<T>, 'render'>
|
|
29
22
|
|
|
30
|
-
export function CheckboxElement<TFieldValues extends FieldValues>(
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
23
|
+
export function CheckboxElement<TFieldValues extends FieldValues>(
|
|
24
|
+
props: CheckboxElementProps<TFieldValues>,
|
|
25
|
+
): JSX.Element {
|
|
26
|
+
const {
|
|
27
|
+
name,
|
|
28
|
+
rules = {},
|
|
29
|
+
required,
|
|
30
|
+
label,
|
|
31
|
+
control,
|
|
32
|
+
helperText,
|
|
33
|
+
sx,
|
|
34
|
+
formControl,
|
|
35
|
+
defaultValue,
|
|
36
|
+
disabled,
|
|
37
|
+
shouldUnregister,
|
|
38
|
+
...rest
|
|
39
|
+
} = props
|
|
40
|
+
|
|
42
41
|
if (required && !rules.required) {
|
|
43
42
|
rules.required = i18n._(/* i18n */ 'This field is required')
|
|
44
43
|
}
|
|
45
44
|
|
|
45
|
+
const {
|
|
46
|
+
field: { value, onChange, ref, ...field },
|
|
47
|
+
fieldState: { invalid, error },
|
|
48
|
+
} = useController({
|
|
49
|
+
name,
|
|
50
|
+
rules,
|
|
51
|
+
control,
|
|
52
|
+
defaultValue,
|
|
53
|
+
disabled,
|
|
54
|
+
shouldUnregister,
|
|
55
|
+
})
|
|
56
|
+
|
|
57
|
+
const parsedHelperText = error ? error.message : helperText
|
|
58
|
+
|
|
46
59
|
return (
|
|
47
|
-
<
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
...(Array.isArray(sx) ? sx : [sx]),
|
|
71
|
-
color: invalid ? 'error.main' : undefined,
|
|
72
|
-
}}
|
|
73
|
-
value={value}
|
|
74
|
-
checked={!!value}
|
|
75
|
-
onChange={() => onChange(!value)}
|
|
76
|
-
/>
|
|
77
|
-
}
|
|
78
|
-
/>
|
|
79
|
-
</FormGroup>
|
|
80
|
-
{parsedHelperText && (
|
|
81
|
-
<FormHelperText error={invalid}>{parsedHelperText}</FormHelperText>
|
|
82
|
-
)}
|
|
83
|
-
</FormControl>
|
|
84
|
-
)
|
|
85
|
-
}}
|
|
86
|
-
/>
|
|
60
|
+
<FormControl required={required} error={invalid} {...formControl}>
|
|
61
|
+
<FormGroup row>
|
|
62
|
+
<FormControlLabel
|
|
63
|
+
label={label || ''}
|
|
64
|
+
control={
|
|
65
|
+
<Checkbox
|
|
66
|
+
{...rest}
|
|
67
|
+
{...field}
|
|
68
|
+
inputRef={ref}
|
|
69
|
+
color={rest.color || 'primary'}
|
|
70
|
+
sx={{
|
|
71
|
+
...(Array.isArray(sx) ? sx : [sx]),
|
|
72
|
+
color: invalid ? 'error.main' : undefined,
|
|
73
|
+
}}
|
|
74
|
+
value={value}
|
|
75
|
+
checked={!!value}
|
|
76
|
+
onChange={() => onChange(!value)}
|
|
77
|
+
/>
|
|
78
|
+
}
|
|
79
|
+
/>
|
|
80
|
+
</FormGroup>
|
|
81
|
+
{parsedHelperText && <FormHelperText error={invalid}>{parsedHelperText}</FormHelperText>}
|
|
82
|
+
</FormControl>
|
|
87
83
|
)
|
|
88
84
|
}
|
|
@@ -1,11 +1,6 @@
|
|
|
1
1
|
/* eslint-disable no-nested-ternary */
|
|
2
2
|
import { IconSvg, iconClose } from '@graphcommerce/next-ui'
|
|
3
|
-
import {
|
|
4
|
-
Controller,
|
|
5
|
-
FieldError,
|
|
6
|
-
FieldValues,
|
|
7
|
-
ControllerProps,
|
|
8
|
-
} from '@graphcommerce/react-hook-form'
|
|
3
|
+
import { FieldValues, ControllerProps, useController } from '@graphcommerce/react-hook-form'
|
|
9
4
|
import { i18n } from '@lingui/core'
|
|
10
5
|
import {
|
|
11
6
|
Checkbox,
|
|
@@ -27,8 +22,6 @@ export type MultiSelectElementProps<T extends FieldValues> = Omit<SelectProps, '
|
|
|
27
22
|
itemValue?: string
|
|
28
23
|
itemLabel?: string
|
|
29
24
|
required?: boolean
|
|
30
|
-
/** @deprecated Form value parsing should happen in the handleSubmit function of the form */
|
|
31
|
-
parseError?: (error: FieldError) => string
|
|
32
25
|
minWidth?: number
|
|
33
26
|
menuMaxHeight?: number
|
|
34
27
|
menuMaxWidth?: number
|
|
@@ -44,7 +37,7 @@ const ITEM_PADDING_TOP = 8
|
|
|
44
37
|
export function MultiSelectElement<TFieldValues extends FieldValues>(
|
|
45
38
|
props: MultiSelectElementProps<TFieldValues>,
|
|
46
39
|
): JSX.Element {
|
|
47
|
-
|
|
40
|
+
const {
|
|
48
41
|
options,
|
|
49
42
|
label = '',
|
|
50
43
|
itemKey = 'id',
|
|
@@ -52,7 +45,6 @@ export function MultiSelectElement<TFieldValues extends FieldValues>(
|
|
|
52
45
|
itemLabel = 'label',
|
|
53
46
|
required = false,
|
|
54
47
|
rules = {},
|
|
55
|
-
parseError,
|
|
56
48
|
name,
|
|
57
49
|
menuMaxHeight = ITEM_HEIGHT * 4.5 + ITEM_PADDING_TOP,
|
|
58
50
|
menuMaxWidth = 250,
|
|
@@ -62,114 +54,115 @@ export function MultiSelectElement<TFieldValues extends FieldValues>(
|
|
|
62
54
|
control,
|
|
63
55
|
showCheckbox,
|
|
64
56
|
formControlProps,
|
|
57
|
+
shouldUnregister,
|
|
58
|
+
defaultValue,
|
|
59
|
+
disabled,
|
|
65
60
|
...rest
|
|
66
61
|
} = props
|
|
67
62
|
if (required && !rules.required) {
|
|
68
63
|
rules.required = i18n._(/* i18n */ 'This field is required')
|
|
69
64
|
}
|
|
70
65
|
|
|
66
|
+
const {
|
|
67
|
+
field: { value, onChange, ...field },
|
|
68
|
+
fieldState: { invalid, error },
|
|
69
|
+
} = useController({
|
|
70
|
+
name,
|
|
71
|
+
rules,
|
|
72
|
+
control,
|
|
73
|
+
defaultValue,
|
|
74
|
+
disabled,
|
|
75
|
+
shouldUnregister,
|
|
76
|
+
})
|
|
77
|
+
|
|
78
|
+
const parsedHelperText = error ? error.message : helperText
|
|
79
|
+
|
|
71
80
|
return (
|
|
72
|
-
<
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
81
|
+
<FormControl
|
|
82
|
+
{...formControlProps}
|
|
83
|
+
style={{
|
|
84
|
+
...formControlProps?.style,
|
|
85
|
+
minWidth,
|
|
86
|
+
}}
|
|
87
|
+
variant={rest.variant}
|
|
88
|
+
fullWidth={rest.fullWidth}
|
|
89
|
+
error={invalid}
|
|
90
|
+
size={rest.size}
|
|
91
|
+
>
|
|
92
|
+
{label && (
|
|
93
|
+
<InputLabel
|
|
94
|
+
size={rest.size === 'small' ? 'small' : undefined}
|
|
95
|
+
error={invalid}
|
|
96
|
+
htmlFor={rest.id || `select-multi-select-${name}`}
|
|
97
|
+
required={required}
|
|
98
|
+
>
|
|
99
|
+
{label}
|
|
100
|
+
</InputLabel>
|
|
101
|
+
)}
|
|
102
|
+
<Select
|
|
103
|
+
{...rest}
|
|
104
|
+
{...field}
|
|
105
|
+
id={rest.id || `select-multi-select-${name}`}
|
|
106
|
+
multiple
|
|
107
|
+
label={label || undefined}
|
|
108
|
+
error={invalid}
|
|
109
|
+
value={value || []}
|
|
110
|
+
required={required}
|
|
111
|
+
onChange={onChange}
|
|
112
|
+
MenuProps={{
|
|
113
|
+
...rest.MenuProps,
|
|
114
|
+
PaperProps: {
|
|
115
|
+
...(rest.MenuProps?.PaperProps ?? {
|
|
116
|
+
style: {
|
|
117
|
+
maxHeight: menuMaxHeight,
|
|
118
|
+
width: menuMaxWidth,
|
|
119
|
+
...rest.MenuProps?.PaperProps?.style,
|
|
120
|
+
},
|
|
121
|
+
}),
|
|
122
|
+
},
|
|
123
|
+
}}
|
|
124
|
+
renderValue={
|
|
125
|
+
typeof rest.renderValue === 'function'
|
|
126
|
+
? rest.renderValue
|
|
127
|
+
: showChips
|
|
128
|
+
? (selected) => (
|
|
129
|
+
<div style={{ display: 'flex', flexWrap: 'wrap' }}>
|
|
130
|
+
{((selected as any[]) || []).map((selectedValue) => (
|
|
131
|
+
<Chip
|
|
132
|
+
key={selectedValue}
|
|
133
|
+
label={selectedValue}
|
|
134
|
+
style={{ display: 'flex', flexWrap: 'wrap' }}
|
|
135
|
+
onDelete={() => {
|
|
136
|
+
onChange(value.filter((i: any) => i !== selectedValue))
|
|
137
|
+
// setValue(name, formValue.filter((i: any) => i !== value), { shouldValidate: true })
|
|
138
|
+
}}
|
|
139
|
+
deleteIcon={<IconSvg src={iconClose} />}
|
|
140
|
+
/>
|
|
141
|
+
))}
|
|
142
|
+
</div>
|
|
143
|
+
)
|
|
144
|
+
: (selected) => (Array.isArray(selected) ? selected.join(', ') : '')
|
|
145
|
+
}
|
|
146
|
+
>
|
|
147
|
+
{options.map((item) => {
|
|
148
|
+
const val: string | number = item[itemValue || itemKey] || item
|
|
149
|
+
const isChecked = Array.isArray(value) ? value.includes(val) : false
|
|
150
|
+
return (
|
|
151
|
+
<MenuItem
|
|
152
|
+
key={val}
|
|
153
|
+
value={val}
|
|
154
|
+
sx={{
|
|
155
|
+
fontWeight: (theme) =>
|
|
156
|
+
isChecked ? theme.typography.fontWeightBold : theme.typography.fontWeightRegular,
|
|
125
157
|
}}
|
|
126
|
-
renderValue={
|
|
127
|
-
typeof rest.renderValue === 'function'
|
|
128
|
-
? rest.renderValue
|
|
129
|
-
: showChips
|
|
130
|
-
? (selected) => (
|
|
131
|
-
<div style={{ display: 'flex', flexWrap: 'wrap' }}>
|
|
132
|
-
{((selected as any[]) || []).map((selectedValue) => (
|
|
133
|
-
<Chip
|
|
134
|
-
key={selectedValue}
|
|
135
|
-
label={selectedValue}
|
|
136
|
-
style={{ display: 'flex', flexWrap: 'wrap' }}
|
|
137
|
-
onDelete={() => {
|
|
138
|
-
onChange(value.filter((i: any) => i !== selectedValue))
|
|
139
|
-
// setValue(name, formValue.filter((i: any) => i !== value), { shouldValidate: true })
|
|
140
|
-
}}
|
|
141
|
-
deleteIcon={<IconSvg src={iconClose} />}
|
|
142
|
-
/>
|
|
143
|
-
))}
|
|
144
|
-
</div>
|
|
145
|
-
)
|
|
146
|
-
: (selected) => (Array.isArray(selected) ? selected.join(', ') : '')
|
|
147
|
-
}
|
|
148
158
|
>
|
|
149
|
-
{
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
fontWeight: (theme) =>
|
|
158
|
-
isChecked
|
|
159
|
-
? theme.typography.fontWeightBold
|
|
160
|
-
: theme.typography.fontWeightRegular,
|
|
161
|
-
}}
|
|
162
|
-
>
|
|
163
|
-
{showCheckbox && <Checkbox checked={isChecked} />}
|
|
164
|
-
<ListItemText primary={item[itemLabel] || item} />
|
|
165
|
-
</MenuItem>
|
|
166
|
-
)
|
|
167
|
-
})}
|
|
168
|
-
</Select>
|
|
169
|
-
{helperText && <FormHelperText>{helperText}</FormHelperText>}
|
|
170
|
-
</FormControl>
|
|
171
|
-
)
|
|
172
|
-
}}
|
|
173
|
-
/>
|
|
159
|
+
{showCheckbox && <Checkbox checked={isChecked} />}
|
|
160
|
+
<ListItemText primary={item[itemLabel] || item} />
|
|
161
|
+
</MenuItem>
|
|
162
|
+
)
|
|
163
|
+
})}
|
|
164
|
+
</Select>
|
|
165
|
+
{parsedHelperText && <FormHelperText>{parsedHelperText}</FormHelperText>}
|
|
166
|
+
</FormControl>
|
|
174
167
|
)
|
|
175
168
|
}
|
|
@@ -44,6 +44,8 @@ export function NumberFieldElement<T extends FieldValues>(props: NumberFieldElem
|
|
|
44
44
|
required,
|
|
45
45
|
defaultValue,
|
|
46
46
|
variant = 'outlined',
|
|
47
|
+
disabled,
|
|
48
|
+
shouldUnregister,
|
|
47
49
|
...textFieldProps
|
|
48
50
|
} = props
|
|
49
51
|
|
|
@@ -61,6 +63,8 @@ export function NumberFieldElement<T extends FieldValues>(props: NumberFieldElem
|
|
|
61
63
|
control,
|
|
62
64
|
rules,
|
|
63
65
|
defaultValue,
|
|
66
|
+
disabled,
|
|
67
|
+
shouldUnregister,
|
|
64
68
|
})
|
|
65
69
|
|
|
66
70
|
const valueAsNumber = value ? parseFloat(value) : 0
|
|
@@ -1,9 +1,4 @@
|
|
|
1
|
-
import {
|
|
2
|
-
FieldError,
|
|
3
|
-
useController,
|
|
4
|
-
FieldValues,
|
|
5
|
-
UseControllerProps,
|
|
6
|
-
} from '@graphcommerce/react-hook-form'
|
|
1
|
+
import { useController, FieldValues, UseControllerProps } from '@graphcommerce/react-hook-form'
|
|
7
2
|
import { i18n } from '@lingui/core'
|
|
8
3
|
import {
|
|
9
4
|
FormControl,
|
|
@@ -20,8 +15,6 @@ export type RadioButtonGroupProps<T extends FieldValues> = {
|
|
|
20
15
|
options: { label: string; id: string | number }[] | any[]
|
|
21
16
|
helperText?: string
|
|
22
17
|
required?: boolean
|
|
23
|
-
/** @deprecated Form value parsing should happen in the handleSubmit function of the form */
|
|
24
|
-
parseError?: (error: FieldError) => string
|
|
25
18
|
label?: string
|
|
26
19
|
labelKey?: string
|
|
27
20
|
valueKey?: string
|
|
@@ -32,21 +25,27 @@ export type RadioButtonGroupProps<T extends FieldValues> = {
|
|
|
32
25
|
row?: boolean
|
|
33
26
|
} & UseControllerProps<T>
|
|
34
27
|
|
|
35
|
-
export function RadioButtonGroup<TFieldValues extends FieldValues>(
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
28
|
+
export function RadioButtonGroup<TFieldValues extends FieldValues>(
|
|
29
|
+
props: RadioButtonGroupProps<TFieldValues>,
|
|
30
|
+
): JSX.Element {
|
|
31
|
+
const {
|
|
32
|
+
helperText,
|
|
33
|
+
options,
|
|
34
|
+
label,
|
|
35
|
+
name,
|
|
36
|
+
labelKey = 'label',
|
|
37
|
+
valueKey = 'id',
|
|
38
|
+
required,
|
|
39
|
+
emptyOptionLabel,
|
|
40
|
+
returnObject,
|
|
41
|
+
row,
|
|
42
|
+
control,
|
|
43
|
+
defaultValue,
|
|
44
|
+
disabled,
|
|
45
|
+
shouldUnregister,
|
|
46
|
+
...rest
|
|
47
|
+
} = props
|
|
48
|
+
|
|
50
49
|
const theme = useTheme()
|
|
51
50
|
const {
|
|
52
51
|
field: { value, onChange },
|
|
@@ -55,13 +54,12 @@ export function RadioButtonGroup<TFieldValues extends FieldValues>({
|
|
|
55
54
|
name,
|
|
56
55
|
rules: required ? { required: i18n._(/* i18n */ 'This field is required') } : undefined,
|
|
57
56
|
control,
|
|
57
|
+
defaultValue,
|
|
58
|
+
disabled,
|
|
59
|
+
shouldUnregister,
|
|
58
60
|
})
|
|
59
61
|
|
|
60
|
-
|
|
61
|
-
? typeof parseError === 'function'
|
|
62
|
-
? parseError(error)
|
|
63
|
-
: error.message
|
|
64
|
-
: helperText
|
|
62
|
+
const parsedHelperText = error ? error.message : helperText
|
|
65
63
|
|
|
66
64
|
const onRadioChange = (event: ChangeEvent<HTMLInputElement>) => {
|
|
67
65
|
const radioValue = (event.target as HTMLInputElement).value
|
|
@@ -125,7 +123,7 @@ export function RadioButtonGroup<TFieldValues extends FieldValues>({
|
|
|
125
123
|
)
|
|
126
124
|
})}
|
|
127
125
|
</RadioGroup>
|
|
128
|
-
{
|
|
126
|
+
{parsedHelperText && <FormHelperText>{parsedHelperText}</FormHelperText>}
|
|
129
127
|
</FormControl>
|
|
130
128
|
)
|
|
131
129
|
}
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import {
|
|
2
|
-
Controller,
|
|
3
2
|
ControllerProps,
|
|
4
3
|
FieldError,
|
|
5
4
|
FieldValues,
|
|
5
|
+
useController,
|
|
6
6
|
} from '@graphcommerce/react-hook-form'
|
|
7
7
|
import { i18n } from '@lingui/core'
|
|
8
8
|
import {
|
|
@@ -16,8 +16,6 @@ import {
|
|
|
16
16
|
|
|
17
17
|
export type SliderElementProps<T extends FieldValues> = Omit<SliderProps, 'control'> & {
|
|
18
18
|
label?: string
|
|
19
|
-
/** @deprecated Form value parsing should happen in the handleSubmit function of the form */
|
|
20
|
-
parseError?: (error: FieldError) => string
|
|
21
19
|
required?: boolean
|
|
22
20
|
formControlProps?: FormControlProps
|
|
23
21
|
} & Omit<ControllerProps<T>, 'render'>
|
|
@@ -27,39 +25,40 @@ export function SliderElement<TFieldValues extends FieldValues>({
|
|
|
27
25
|
control,
|
|
28
26
|
label,
|
|
29
27
|
rules = {},
|
|
30
|
-
parseError,
|
|
31
28
|
required,
|
|
32
29
|
formControlProps,
|
|
30
|
+
defaultValue,
|
|
31
|
+
disabled,
|
|
32
|
+
shouldUnregister,
|
|
33
33
|
...other
|
|
34
34
|
}: SliderElementProps<TFieldValues>) {
|
|
35
35
|
if (required && !rules.required) {
|
|
36
36
|
rules.required = i18n._(/* i18n */ 'This field is required')
|
|
37
37
|
}
|
|
38
|
+
|
|
39
|
+
const {
|
|
40
|
+
field,
|
|
41
|
+
fieldState: { invalid, error },
|
|
42
|
+
} = useController({
|
|
43
|
+
name,
|
|
44
|
+
control,
|
|
45
|
+
rules,
|
|
46
|
+
defaultValue,
|
|
47
|
+
disabled,
|
|
48
|
+
shouldUnregister,
|
|
49
|
+
})
|
|
50
|
+
|
|
51
|
+
const parsedHelperText = error ? error.message : null
|
|
52
|
+
|
|
38
53
|
return (
|
|
39
|
-
<
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
: null
|
|
49
|
-
return (
|
|
50
|
-
<FormControl error={invalid} required={required} fullWidth {...formControlProps}>
|
|
51
|
-
{label && (
|
|
52
|
-
<FormLabel component='legend' error={invalid}>
|
|
53
|
-
{label}
|
|
54
|
-
</FormLabel>
|
|
55
|
-
)}
|
|
56
|
-
<Slider {...other} {...field} valueLabelDisplay={other.valueLabelDisplay || 'auto'} />
|
|
57
|
-
{parsedHelperText && (
|
|
58
|
-
<FormHelperText error={invalid}>{parsedHelperText}</FormHelperText>
|
|
59
|
-
)}
|
|
60
|
-
</FormControl>
|
|
61
|
-
)
|
|
62
|
-
}}
|
|
63
|
-
/>
|
|
54
|
+
<FormControl error={invalid} required={required} fullWidth {...formControlProps}>
|
|
55
|
+
{label && (
|
|
56
|
+
<FormLabel component='legend' error={invalid}>
|
|
57
|
+
{label}
|
|
58
|
+
</FormLabel>
|
|
59
|
+
)}
|
|
60
|
+
<Slider {...other} {...field} valueLabelDisplay={other.valueLabelDisplay || 'auto'} />
|
|
61
|
+
{parsedHelperText && <FormHelperText error={invalid}>{parsedHelperText}</FormHelperText>}
|
|
62
|
+
</FormControl>
|
|
64
63
|
)
|
|
65
64
|
}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { FieldValues, ControllerProps, useController } from '@graphcommerce/react-hook-form'
|
|
2
2
|
import { FormControlLabel, FormControlLabelProps, Switch } from '@mui/material'
|
|
3
3
|
|
|
4
4
|
type IProps = Omit<FormControlLabelProps, 'control'>
|
|
@@ -8,18 +8,20 @@ export type SwitchElementProps<T extends FieldValues> = IProps & Omit<Controller
|
|
|
8
8
|
export function SwitchElement<TFieldValues extends FieldValues>({
|
|
9
9
|
name,
|
|
10
10
|
control,
|
|
11
|
+
defaultValue,
|
|
12
|
+
disabled,
|
|
13
|
+
shouldUnregister,
|
|
14
|
+
rules,
|
|
11
15
|
...other
|
|
12
16
|
}: SwitchElementProps<TFieldValues>) {
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
/>
|
|
24
|
-
)
|
|
17
|
+
const { field } = useController({
|
|
18
|
+
name,
|
|
19
|
+
control,
|
|
20
|
+
defaultValue,
|
|
21
|
+
disabled,
|
|
22
|
+
shouldUnregister,
|
|
23
|
+
rules,
|
|
24
|
+
})
|
|
25
|
+
|
|
26
|
+
return <FormControlLabel control={<Switch {...field} checked={!!field.value} />} {...other} />
|
|
25
27
|
}
|
|
@@ -27,7 +27,9 @@ export function TextFieldElement<TFieldValues extends FieldValues>({
|
|
|
27
27
|
control,
|
|
28
28
|
defaultValue,
|
|
29
29
|
rules = validation,
|
|
30
|
+
shouldUnregister,
|
|
30
31
|
showValid,
|
|
32
|
+
disabled,
|
|
31
33
|
...rest
|
|
32
34
|
}: TextFieldElementProps<TFieldValues>): JSX.Element {
|
|
33
35
|
if (required && !rules.required) {
|
|
@@ -44,7 +46,7 @@ export function TextFieldElement<TFieldValues extends FieldValues>({
|
|
|
44
46
|
const {
|
|
45
47
|
field: { onChange, ref, value = '', ...field },
|
|
46
48
|
fieldState: { error },
|
|
47
|
-
} = useController({ name, control, rules, defaultValue })
|
|
49
|
+
} = useController({ name, control, rules, defaultValue, shouldUnregister, disabled })
|
|
48
50
|
|
|
49
51
|
return (
|
|
50
52
|
<TextField
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import {
|
|
2
|
-
Controller,
|
|
3
2
|
ControllerProps,
|
|
4
3
|
FieldError,
|
|
5
4
|
FieldValues,
|
|
5
|
+
useController,
|
|
6
6
|
} from '@graphcommerce/react-hook-form'
|
|
7
7
|
import { i18n } from '@lingui/core'
|
|
8
8
|
import {
|
|
@@ -25,8 +25,6 @@ type SingleToggleButtonProps = Omit<ToggleButtonProps, 'value' | 'children'> & {
|
|
|
25
25
|
export type ToggleButtonGroupElementProps<T extends FieldValues> = ToggleButtonGroupProps & {
|
|
26
26
|
required?: boolean
|
|
27
27
|
label?: string
|
|
28
|
-
/** @deprecated Form value parsing should happen in the handleSubmit function of the form */
|
|
29
|
-
parseError?: (error: FieldError) => string
|
|
30
28
|
options: SingleToggleButtonProps[]
|
|
31
29
|
formLabelProps?: FormLabelProps
|
|
32
30
|
helperText?: string
|
|
@@ -39,9 +37,11 @@ export function ToggleButtonGroupElement<TFieldValues extends FieldValues = Fiel
|
|
|
39
37
|
rules = {},
|
|
40
38
|
required,
|
|
41
39
|
options = [],
|
|
42
|
-
parseError,
|
|
43
40
|
helperText,
|
|
44
41
|
formLabelProps,
|
|
42
|
+
defaultValue,
|
|
43
|
+
disabled,
|
|
44
|
+
shouldUnregister,
|
|
45
45
|
...toggleButtonGroupProps
|
|
46
46
|
}: ToggleButtonGroupElementProps<TFieldValues>) {
|
|
47
47
|
if (required && !rules.required) {
|
|
@@ -49,50 +49,51 @@ export function ToggleButtonGroupElement<TFieldValues extends FieldValues = Fiel
|
|
|
49
49
|
}
|
|
50
50
|
|
|
51
51
|
const isRequired = required || !!rules?.required
|
|
52
|
+
|
|
53
|
+
const {
|
|
54
|
+
field: { value, onChange, onBlur },
|
|
55
|
+
fieldState: { invalid, error },
|
|
56
|
+
} = useController({
|
|
57
|
+
name,
|
|
58
|
+
control,
|
|
59
|
+
rules,
|
|
60
|
+
defaultValue,
|
|
61
|
+
disabled,
|
|
62
|
+
shouldUnregister,
|
|
63
|
+
})
|
|
64
|
+
|
|
65
|
+
const renderHelperText = error ? error.message : helperText
|
|
66
|
+
|
|
52
67
|
return (
|
|
53
|
-
<
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
}
|
|
84
|
-
}}
|
|
85
|
-
>
|
|
86
|
-
{options.map(({ label, id, ...toggleProps }) => (
|
|
87
|
-
<ToggleButton value={id} {...toggleProps} key={id}>
|
|
88
|
-
{label}
|
|
89
|
-
</ToggleButton>
|
|
90
|
-
))}
|
|
91
|
-
</ToggleButtonGroup>
|
|
92
|
-
{renderHelperText && <FormHelperText>{renderHelperText}</FormHelperText>}
|
|
93
|
-
</FormControl>
|
|
94
|
-
)
|
|
95
|
-
}}
|
|
96
|
-
/>
|
|
68
|
+
<FormControl error={invalid} required={isRequired}>
|
|
69
|
+
{label && (
|
|
70
|
+
<FormLabel
|
|
71
|
+
{...formLabelProps}
|
|
72
|
+
error={invalid}
|
|
73
|
+
required={isRequired}
|
|
74
|
+
sx={{ mb: 1, ...formLabelProps?.sx }}
|
|
75
|
+
>
|
|
76
|
+
{label}
|
|
77
|
+
</FormLabel>
|
|
78
|
+
)}
|
|
79
|
+
<ToggleButtonGroup
|
|
80
|
+
{...toggleButtonGroupProps}
|
|
81
|
+
value={value}
|
|
82
|
+
onBlur={onBlur}
|
|
83
|
+
onChange={(event, val) => {
|
|
84
|
+
onChange(val)
|
|
85
|
+
if (typeof toggleButtonGroupProps.onChange === 'function') {
|
|
86
|
+
toggleButtonGroupProps.onChange(event, val)
|
|
87
|
+
}
|
|
88
|
+
}}
|
|
89
|
+
>
|
|
90
|
+
{options.map(({ label, id, ...toggleProps }) => (
|
|
91
|
+
<ToggleButton value={id} {...toggleProps} key={id}>
|
|
92
|
+
{label}
|
|
93
|
+
</ToggleButton>
|
|
94
|
+
))}
|
|
95
|
+
</ToggleButtonGroup>
|
|
96
|
+
{renderHelperText && <FormHelperText>{renderHelperText}</FormHelperText>}
|
|
97
|
+
</FormControl>
|
|
97
98
|
)
|
|
98
99
|
}
|
package/package.json
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
"name": "@graphcommerce/ecommerce-ui",
|
|
3
3
|
"homepage": "https://www.graphcommerce.org/",
|
|
4
4
|
"repository": "github:graphcommerce-org/graphcommerce",
|
|
5
|
-
"version": "9.0.0-canary.
|
|
5
|
+
"version": "9.0.0-canary.80",
|
|
6
6
|
"sideEffects": false,
|
|
7
7
|
"prettier": "@graphcommerce/prettier-config-pwa",
|
|
8
8
|
"eslintConfig": {
|
|
@@ -12,12 +12,12 @@
|
|
|
12
12
|
}
|
|
13
13
|
},
|
|
14
14
|
"peerDependencies": {
|
|
15
|
-
"@graphcommerce/eslint-config-pwa": "^9.0.0-canary.
|
|
16
|
-
"@graphcommerce/graphql": "^9.0.0-canary.
|
|
17
|
-
"@graphcommerce/next-ui": "^9.0.0-canary.
|
|
18
|
-
"@graphcommerce/prettier-config-pwa": "^9.0.0-canary.
|
|
19
|
-
"@graphcommerce/react-hook-form": "^9.0.0-canary.
|
|
20
|
-
"@graphcommerce/typescript-config-pwa": "^9.0.0-canary.
|
|
15
|
+
"@graphcommerce/eslint-config-pwa": "^9.0.0-canary.80",
|
|
16
|
+
"@graphcommerce/graphql": "^9.0.0-canary.80",
|
|
17
|
+
"@graphcommerce/next-ui": "^9.0.0-canary.80",
|
|
18
|
+
"@graphcommerce/prettier-config-pwa": "^9.0.0-canary.80",
|
|
19
|
+
"@graphcommerce/react-hook-form": "^9.0.0-canary.80",
|
|
20
|
+
"@graphcommerce/typescript-config-pwa": "^9.0.0-canary.80",
|
|
21
21
|
"@lingui/core": "^4.2.1",
|
|
22
22
|
"@lingui/macro": "^4.2.1",
|
|
23
23
|
"@lingui/react": "^4.2.1",
|