@graphcommerce/ecommerce-ui 8.1.0-canary.9 → 9.0.0-canary.101
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 +236 -37
- package/Config.graphqls +29 -0
- package/components/FormComponents/ActionCardListForm.tsx +96 -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/EmailElement.tsx +27 -0
- package/components/FormComponents/MultiSelectElement.tsx +103 -110
- package/components/FormComponents/NumberFieldElement.tsx +9 -1
- package/components/FormComponents/RadioButtonGroup.tsx +27 -29
- package/components/FormComponents/SliderElement.tsx +28 -29
- package/components/FormComponents/SwitchElement.tsx +15 -13
- package/components/FormComponents/TelephoneElement.tsx +23 -0
- package/components/FormComponents/TextFieldElement.tsx +25 -5
- package/components/FormComponents/ToggleButtonGroup.tsx +49 -48
- package/components/FormComponents/index.ts +6 -3
- package/components/PreviewMode/LightTooltip.tsx +11 -0
- package/components/PreviewMode/PreviewMode.tsx +151 -0
- package/components/PreviewMode/PreviewModeActions.tsx +6 -0
- package/components/PreviewMode/PreviewModeToolbar.tsx +6 -0
- package/components/PreviewMode/index.ts +5 -0
- package/components/PreviewMode/previewModeDefaults.ts +5 -0
- package/components/PreviewMode/usePreviewModeForm.ts +6 -0
- package/components/index.ts +1 -0
- package/package.json +7 -7
- package/plugins/PreviewModeFramerNextPages.tsx +38 -0
- package/route/preview.ts +60 -0
|
@@ -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
|
}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import { emailPattern, FieldValues } from '@graphcommerce/react-hook-form'
|
|
2
|
+
import { i18n } from '@lingui/core'
|
|
3
|
+
import { Trans } from '@lingui/react'
|
|
4
|
+
import { TextFieldElement, TextFieldElementProps } from './TextFieldElement'
|
|
5
|
+
|
|
6
|
+
export type EmailElementProps<T extends FieldValues> = TextFieldElementProps<T>
|
|
7
|
+
|
|
8
|
+
export function EmailElement<TFieldValues extends FieldValues>(
|
|
9
|
+
props: EmailElementProps<TFieldValues>,
|
|
10
|
+
): JSX.Element {
|
|
11
|
+
const { rules, ...rest } = props
|
|
12
|
+
return (
|
|
13
|
+
<TextFieldElement
|
|
14
|
+
type='email'
|
|
15
|
+
label={<Trans id='Email address' />}
|
|
16
|
+
autoComplete='email'
|
|
17
|
+
rules={{
|
|
18
|
+
pattern: {
|
|
19
|
+
value: emailPattern,
|
|
20
|
+
message: i18n._(/* i18n */ 'Please enter a valid email address'),
|
|
21
|
+
},
|
|
22
|
+
...rules,
|
|
23
|
+
}}
|
|
24
|
+
{...rest}
|
|
25
|
+
/>
|
|
26
|
+
)
|
|
27
|
+
}
|