@graphcommerce/ecommerce-ui 8.0.3-canary.3 → 8.0.3-canary.5
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 +14 -0
- package/components/FormComponents/CheckboxButtonGroup.tsx +1 -0
- package/components/FormComponents/CheckboxElement.tsx +6 -4
- package/components/FormComponents/MultiSelectElement.tsx +20 -19
- package/components/FormComponents/NumberFieldElement.tsx +4 -4
- package/components/FormComponents/PasswordRepeatElement.tsx +1 -1
- package/components/FormComponents/RadioButtonGroup.tsx +1 -0
- package/components/FormComponents/SelectElement.tsx +9 -7
- package/components/FormComponents/SliderElement.tsx +3 -7
- package/components/FormComponents/TextFieldElement.tsx +12 -17
- package/components/FormComponents/ToggleButtonGroup.tsx +1 -0
- package/package.json +7 -7
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,19 @@
|
|
|
1
1
|
# @graphcommerce/ecommerce-ui
|
|
2
2
|
|
|
3
|
+
## 8.0.3-canary.5
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- [#2212](https://github.com/graphcommerce-org/graphcommerce/pull/2212) [`e12d1dc`](https://github.com/graphcommerce-org/graphcommerce/commit/e12d1dc201bf7b23a996bd58a256a117b91a9334) - Rename validation to rules for all Form field components and deprecate validation
|
|
8
|
+
([@paales](https://github.com/paales))
|
|
9
|
+
|
|
10
|
+
## 8.0.3-canary.4
|
|
11
|
+
|
|
12
|
+
### Patch Changes
|
|
13
|
+
|
|
14
|
+
- [#2203](https://github.com/graphcommerce-org/graphcommerce/pull/2203) [`7ef7dc7`](https://github.com/graphcommerce-org/graphcommerce/commit/7ef7dc7631f61a2feba67a531a210df9c22fed4b) - CheckboxElement, MultiSelectElement, NumberFieldElement, SelectElement, SliderElement and TextFieldElement have their inputRef passed, allowing focus to be set by the form.
|
|
15
|
+
([@Jessevdpoel](https://github.com/Jessevdpoel))
|
|
16
|
+
|
|
3
17
|
## 8.0.3-canary.3
|
|
4
18
|
|
|
5
19
|
## 8.0.3-canary.2
|
|
@@ -21,6 +21,7 @@ export type CheckboxButtonGroupProps<T extends FieldValues> = {
|
|
|
21
21
|
options: { id: string | number; label: string }[] | any[]
|
|
22
22
|
helperText?: string
|
|
23
23
|
required?: boolean
|
|
24
|
+
/** @deprecated Form value parsing should happen in the handleSubmit function of the form */
|
|
24
25
|
parseError?: (error: FieldError) => string
|
|
25
26
|
label?: string
|
|
26
27
|
labelKey?: string
|
|
@@ -19,6 +19,7 @@ import {
|
|
|
19
19
|
} from '@mui/material'
|
|
20
20
|
|
|
21
21
|
export type CheckboxElementProps<T extends FieldValues> = Omit<CheckboxProps, 'name'> & {
|
|
22
|
+
/** @deprecated Form value parsing should happen in the handleSubmit function of the form */
|
|
22
23
|
parseError?: (error: FieldError) => string
|
|
23
24
|
label?: FormControlLabelProps['label']
|
|
24
25
|
helperText?: string
|
|
@@ -47,7 +48,8 @@ export function CheckboxElement<TFieldValues extends FieldValues>({
|
|
|
47
48
|
name={name}
|
|
48
49
|
rules={rules}
|
|
49
50
|
control={control}
|
|
50
|
-
render={({ field: { value, onChange }, fieldState: { invalid, error } }) => {
|
|
51
|
+
render={({ field: { value, onChange, ref, ...field }, fieldState: { invalid, error } }) => {
|
|
52
|
+
// eslint-disable-next-line no-nested-ternary
|
|
51
53
|
const parsedHelperText = error
|
|
52
54
|
? typeof parseError === 'function'
|
|
53
55
|
? parseError(error)
|
|
@@ -61,6 +63,8 @@ export function CheckboxElement<TFieldValues extends FieldValues>({
|
|
|
61
63
|
control={
|
|
62
64
|
<Checkbox
|
|
63
65
|
{...rest}
|
|
66
|
+
{...field}
|
|
67
|
+
inputRef={ref}
|
|
64
68
|
color={rest.color || 'primary'}
|
|
65
69
|
sx={{
|
|
66
70
|
...(Array.isArray(sx) ? sx : [sx]),
|
|
@@ -68,9 +72,7 @@ export function CheckboxElement<TFieldValues extends FieldValues>({
|
|
|
68
72
|
}}
|
|
69
73
|
value={value}
|
|
70
74
|
checked={!!value}
|
|
71
|
-
onChange={() =>
|
|
72
|
-
onChange(!value)
|
|
73
|
-
}}
|
|
75
|
+
onChange={() => onChange(!value)}
|
|
74
76
|
/>
|
|
75
77
|
}
|
|
76
78
|
/>
|
|
@@ -27,6 +27,7 @@ export type MultiSelectElementProps<T extends FieldValues> = Omit<SelectProps, '
|
|
|
27
27
|
itemValue?: string
|
|
28
28
|
itemLabel?: string
|
|
29
29
|
required?: boolean
|
|
30
|
+
/** @deprecated Form value parsing should happen in the handleSubmit function of the form */
|
|
30
31
|
parseError?: (error: FieldError) => string
|
|
31
32
|
minWidth?: number
|
|
32
33
|
menuMaxHeight?: number
|
|
@@ -72,7 +73,7 @@ export function MultiSelectElement<TFieldValues extends FieldValues>(
|
|
|
72
73
|
name={name}
|
|
73
74
|
rules={rules}
|
|
74
75
|
control={control}
|
|
75
|
-
render={({ field: { value, onChange,
|
|
76
|
+
render={({ field: { value, onChange, ...field }, fieldState: { invalid, error } }) => {
|
|
76
77
|
helperText = error
|
|
77
78
|
? typeof parseError === 'function'
|
|
78
79
|
? parseError(error)
|
|
@@ -102,6 +103,7 @@ export function MultiSelectElement<TFieldValues extends FieldValues>(
|
|
|
102
103
|
)}
|
|
103
104
|
<Select
|
|
104
105
|
{...rest}
|
|
106
|
+
{...field}
|
|
105
107
|
id={rest.id || `select-multi-select-${name}`}
|
|
106
108
|
multiple
|
|
107
109
|
label={label || undefined}
|
|
@@ -109,7 +111,6 @@ export function MultiSelectElement<TFieldValues extends FieldValues>(
|
|
|
109
111
|
value={value || []}
|
|
110
112
|
required={required}
|
|
111
113
|
onChange={onChange}
|
|
112
|
-
onBlur={onBlur}
|
|
113
114
|
MenuProps={{
|
|
114
115
|
...rest.MenuProps,
|
|
115
116
|
PaperProps: {
|
|
@@ -126,23 +127,23 @@ export function MultiSelectElement<TFieldValues extends FieldValues>(
|
|
|
126
127
|
typeof rest.renderValue === 'function'
|
|
127
128
|
? rest.renderValue
|
|
128
129
|
: showChips
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
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(', ') : '')
|
|
146
147
|
}
|
|
147
148
|
>
|
|
148
149
|
{options.map((item) => {
|
|
@@ -54,21 +54,21 @@ export function NumberFieldElement<T extends FieldValues>(props: NumberFieldElem
|
|
|
54
54
|
control={control}
|
|
55
55
|
rules={rules}
|
|
56
56
|
defaultValue={defaultValue}
|
|
57
|
-
render={({ field: { value, onChange,
|
|
57
|
+
render={({ field: { value, onChange, ref, ...field }, fieldState: { invalid, error } }) => {
|
|
58
58
|
const valueAsNumber = value ? parseFloat(value) : 0
|
|
59
59
|
|
|
60
60
|
return (
|
|
61
61
|
<TextField
|
|
62
62
|
{...textFieldProps}
|
|
63
|
-
|
|
64
|
-
|
|
63
|
+
{...field}
|
|
64
|
+
inputRef={ref}
|
|
65
65
|
value={value ?? ''}
|
|
66
66
|
onChange={(ev) => {
|
|
67
67
|
const newValue = (ev.target as HTMLInputElement).valueAsNumber
|
|
68
68
|
onChange(Number.isNaN(newValue) ? '' : newValue)
|
|
69
69
|
textFieldProps.onChange?.(ev)
|
|
70
70
|
}}
|
|
71
|
-
|
|
71
|
+
variant={variant}
|
|
72
72
|
required={required}
|
|
73
73
|
error={invalid}
|
|
74
74
|
helperText={error ? error.message : textFieldProps.helperText}
|
|
@@ -20,6 +20,7 @@ export type RadioButtonGroupProps<T extends FieldValues> = {
|
|
|
20
20
|
options: { label: string; id: string | number }[] | any[]
|
|
21
21
|
helperText?: string
|
|
22
22
|
required?: boolean
|
|
23
|
+
/** @deprecated Form value parsing should happen in the handleSubmit function of the form */
|
|
23
24
|
parseError?: (error: FieldError) => string
|
|
24
25
|
label?: string
|
|
25
26
|
labelKey?: string
|
|
@@ -8,6 +8,7 @@ export type SelectElementProps<T extends FieldValues, O extends OptionBase> = Om
|
|
|
8
8
|
TextFieldProps,
|
|
9
9
|
'name' | 'type' | 'onChange' | 'defaultValue'
|
|
10
10
|
> & {
|
|
11
|
+
/** @deprecated Please use the rules props instead */
|
|
11
12
|
validation?: ControllerProps<T>['rules']
|
|
12
13
|
options?: O[]
|
|
13
14
|
type?: 'string' | 'number'
|
|
@@ -19,25 +20,26 @@ export function SelectElement<TFieldValues extends FieldValues, O extends Option
|
|
|
19
20
|
required,
|
|
20
21
|
options = [],
|
|
21
22
|
type,
|
|
22
|
-
validation
|
|
23
|
+
validation,
|
|
23
24
|
control,
|
|
24
25
|
defaultValue,
|
|
26
|
+
rules = validation ?? {},
|
|
25
27
|
...rest
|
|
26
28
|
}: SelectElementProps<TFieldValues, O>): JSX.Element {
|
|
27
29
|
const isNativeSelect = !!rest.SelectProps?.native
|
|
28
30
|
const ChildComponent = isNativeSelect ? 'option' : MenuItem
|
|
29
31
|
|
|
30
|
-
if (required && !
|
|
31
|
-
|
|
32
|
+
if (required && !rules.required) {
|
|
33
|
+
rules.required = i18n._(/* i18n */ 'This field is required')
|
|
32
34
|
}
|
|
33
35
|
|
|
34
36
|
return (
|
|
35
37
|
<Controller
|
|
36
38
|
name={name}
|
|
37
|
-
rules={
|
|
39
|
+
rules={rules}
|
|
38
40
|
control={control}
|
|
39
41
|
defaultValue={defaultValue}
|
|
40
|
-
render={({ field: {
|
|
42
|
+
render={({ field: { onChange, value, ref, ...field }, fieldState: { invalid, error } }) => {
|
|
41
43
|
// handle shrink on number input fields
|
|
42
44
|
if (type === 'number' && typeof value !== 'undefined') {
|
|
43
45
|
rest.InputLabelProps = rest.InputLabelProps || {}
|
|
@@ -47,9 +49,9 @@ export function SelectElement<TFieldValues extends FieldValues, O extends Option
|
|
|
47
49
|
return (
|
|
48
50
|
<TextField
|
|
49
51
|
{...rest}
|
|
50
|
-
name={name}
|
|
51
52
|
value={value ?? ''}
|
|
52
|
-
|
|
53
|
+
{...field}
|
|
54
|
+
inputRef={ref}
|
|
53
55
|
onChange={(event) => {
|
|
54
56
|
let item: number | string | O | undefined = event.target.value
|
|
55
57
|
if (type === 'number') item = Number(item)
|
|
@@ -16,6 +16,7 @@ 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 */
|
|
19
20
|
parseError?: (error: FieldError) => string
|
|
20
21
|
required?: boolean
|
|
21
22
|
formControlProps?: FormControlProps
|
|
@@ -39,7 +40,7 @@ export function SliderElement<TFieldValues extends FieldValues>({
|
|
|
39
40
|
name={name}
|
|
40
41
|
control={control}
|
|
41
42
|
rules={rules}
|
|
42
|
-
render={({ field
|
|
43
|
+
render={({ field, fieldState: { invalid, error } }) => {
|
|
43
44
|
const parsedHelperText = error
|
|
44
45
|
? typeof parseError === 'function'
|
|
45
46
|
? parseError(error)
|
|
@@ -52,12 +53,7 @@ export function SliderElement<TFieldValues extends FieldValues>({
|
|
|
52
53
|
{label}
|
|
53
54
|
</FormLabel>
|
|
54
55
|
)}
|
|
55
|
-
<Slider
|
|
56
|
-
{...other}
|
|
57
|
-
value={value}
|
|
58
|
-
onChange={onChange}
|
|
59
|
-
valueLabelDisplay={other.valueLabelDisplay || 'auto'}
|
|
60
|
-
/>
|
|
56
|
+
<Slider {...other} {...field} valueLabelDisplay={other.valueLabelDisplay || 'auto'} />
|
|
61
57
|
{parsedHelperText && (
|
|
62
58
|
<FormHelperText error={invalid}>{parsedHelperText}</FormHelperText>
|
|
63
59
|
)}
|
|
@@ -1,10 +1,5 @@
|
|
|
1
1
|
/* eslint-disable no-nested-ternary */
|
|
2
|
-
import {
|
|
3
|
-
Controller,
|
|
4
|
-
FieldError,
|
|
5
|
-
FieldValues,
|
|
6
|
-
UseControllerProps,
|
|
7
|
-
} from '@graphcommerce/react-hook-form'
|
|
2
|
+
import { Controller, FieldValues, UseControllerProps } from '@graphcommerce/react-hook-form'
|
|
8
3
|
import { i18n } from '@lingui/core'
|
|
9
4
|
import { TextField, TextFieldProps } from '@mui/material'
|
|
10
5
|
|
|
@@ -12,8 +7,9 @@ export type TextFieldElementProps<T extends FieldValues = FieldValues> = Omit<
|
|
|
12
7
|
TextFieldProps,
|
|
13
8
|
'name' | 'defaultValue'
|
|
14
9
|
> & {
|
|
10
|
+
/** @deprecated Please use the rules props instead */
|
|
15
11
|
validation?: UseControllerProps<T>['rules']
|
|
16
|
-
} &
|
|
12
|
+
} & UseControllerProps<T>
|
|
17
13
|
|
|
18
14
|
export function TextFieldElement<TFieldValues extends FieldValues>({
|
|
19
15
|
validation = {},
|
|
@@ -22,14 +18,15 @@ export function TextFieldElement<TFieldValues extends FieldValues>({
|
|
|
22
18
|
name,
|
|
23
19
|
control,
|
|
24
20
|
defaultValue,
|
|
21
|
+
rules = validation,
|
|
25
22
|
...rest
|
|
26
23
|
}: TextFieldElementProps<TFieldValues>): JSX.Element {
|
|
27
|
-
if (required && !
|
|
28
|
-
|
|
24
|
+
if (required && !rules.required) {
|
|
25
|
+
rules.required = i18n._(/* i18n */ 'This field is required')
|
|
29
26
|
}
|
|
30
27
|
|
|
31
|
-
if (type === 'email' && !
|
|
32
|
-
|
|
28
|
+
if (type === 'email' && !rules.pattern) {
|
|
29
|
+
rules.pattern = {
|
|
33
30
|
// eslint-disable-next-line no-useless-escape
|
|
34
31
|
value:
|
|
35
32
|
/^(([^<>()\[\]\\.,;:\s@"]+(\.[^<>()\[\]\\.,;:\s@"]+)*)|(".+"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/,
|
|
@@ -41,25 +38,23 @@ export function TextFieldElement<TFieldValues extends FieldValues>({
|
|
|
41
38
|
<Controller
|
|
42
39
|
name={name}
|
|
43
40
|
control={control}
|
|
44
|
-
rules={
|
|
41
|
+
rules={rules}
|
|
45
42
|
defaultValue={defaultValue}
|
|
46
|
-
render={({ field: {
|
|
43
|
+
render={({ field: { onChange, ref, ...field }, fieldState: { error } }) => (
|
|
47
44
|
<TextField
|
|
48
45
|
{...rest}
|
|
49
|
-
|
|
50
|
-
value={value ?? ''}
|
|
46
|
+
{...field}
|
|
51
47
|
onChange={(ev) => {
|
|
52
48
|
onChange(
|
|
53
49
|
type === 'number' && ev.target.value ? Number(ev.target.value) : ev.target.value,
|
|
54
50
|
)
|
|
55
51
|
rest.onChange?.(ev)
|
|
56
52
|
}}
|
|
57
|
-
|
|
53
|
+
inputRef={ref}
|
|
58
54
|
required={required}
|
|
59
55
|
type={type}
|
|
60
56
|
error={Boolean(error) || rest.error}
|
|
61
57
|
helperText={error ? error.message : rest.helperText}
|
|
62
|
-
inputRef={ref}
|
|
63
58
|
/>
|
|
64
59
|
)}
|
|
65
60
|
/>
|
|
@@ -25,6 +25,7 @@ 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 */
|
|
28
29
|
parseError?: (error: FieldError) => string
|
|
29
30
|
options: SingleToggleButtonProps[]
|
|
30
31
|
formLabelProps?: FormLabelProps
|
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": "8.0.3-canary.
|
|
5
|
+
"version": "8.0.3-canary.5",
|
|
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": "^8.0.3-canary.
|
|
16
|
-
"@graphcommerce/graphql": "^8.0.3-canary.
|
|
17
|
-
"@graphcommerce/next-ui": "^8.0.3-canary.
|
|
18
|
-
"@graphcommerce/prettier-config-pwa": "^8.0.3-canary.
|
|
19
|
-
"@graphcommerce/react-hook-form": "^8.0.3-canary.
|
|
20
|
-
"@graphcommerce/typescript-config-pwa": "^8.0.3-canary.
|
|
15
|
+
"@graphcommerce/eslint-config-pwa": "^8.0.3-canary.5",
|
|
16
|
+
"@graphcommerce/graphql": "^8.0.3-canary.5",
|
|
17
|
+
"@graphcommerce/next-ui": "^8.0.3-canary.5",
|
|
18
|
+
"@graphcommerce/prettier-config-pwa": "^8.0.3-canary.5",
|
|
19
|
+
"@graphcommerce/react-hook-form": "^8.0.3-canary.5",
|
|
20
|
+
"@graphcommerce/typescript-config-pwa": "^8.0.3-canary.5",
|
|
21
21
|
"@lingui/core": "^4.2.1",
|
|
22
22
|
"@lingui/macro": "^4.2.1",
|
|
23
23
|
"@lingui/react": "^4.2.1",
|