@graphcommerce/ecommerce-ui 1.5.0 → 1.5.1
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
CHANGED
|
@@ -1,5 +1,14 @@
|
|
|
1
1
|
# @graphcommerce/ecommerce-ui
|
|
2
2
|
|
|
3
|
+
## 1.5.1
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- [#1660](https://github.com/graphcommerce-org/graphcommerce/pull/1660) [`e5048c5ec`](https://github.com/graphcommerce-org/graphcommerce/commit/e5048c5ec52b83dbe70a246ffdcea65b55a884c6) Thanks [@paales](https://github.com/paales)! - Flatten the NumberFieldElement to use the Controller directly
|
|
8
|
+
|
|
9
|
+
- Updated dependencies [[`75ae24a93`](https://github.com/graphcommerce-org/graphcommerce/commit/75ae24a93bd74e3b9b7efda21ec7ba6fbe9a3a75)]:
|
|
10
|
+
- @graphcommerce/react-hook-form@3.3.4
|
|
11
|
+
|
|
3
12
|
## 1.5.0
|
|
4
13
|
|
|
5
14
|
### Minor Changes
|
|
@@ -5,32 +5,33 @@ import {
|
|
|
5
5
|
IconSvg,
|
|
6
6
|
responsiveVal,
|
|
7
7
|
} from '@graphcommerce/next-ui'
|
|
8
|
-
import { FieldValues } from '@graphcommerce/react-hook-form'
|
|
8
|
+
import { Controller, ControllerProps, FieldValues } from '@graphcommerce/react-hook-form'
|
|
9
9
|
import { i18n } from '@lingui/core'
|
|
10
10
|
import {
|
|
11
11
|
IconButton,
|
|
12
12
|
IconButtonProps,
|
|
13
13
|
SxProps,
|
|
14
|
-
useForkRef,
|
|
15
14
|
Theme,
|
|
16
|
-
|
|
15
|
+
TextField,
|
|
16
|
+
TextFieldProps,
|
|
17
17
|
} from '@mui/material'
|
|
18
|
-
import { ChangeEvent, Ref, useRef } from 'react'
|
|
19
|
-
import { TextFieldElement, TextFieldElementProps } from './TextFieldElement'
|
|
20
18
|
|
|
21
19
|
export type NumberFieldElementProps<T extends FieldValues = FieldValues> = Omit<
|
|
22
|
-
|
|
23
|
-
'type'
|
|
20
|
+
TextFieldProps,
|
|
21
|
+
'type' | 'defaultValue'
|
|
24
22
|
> & {
|
|
25
23
|
DownProps?: IconButtonProps
|
|
26
24
|
UpProps?: IconButtonProps
|
|
27
25
|
sx?: SxProps<Theme>
|
|
28
|
-
}
|
|
26
|
+
} & Omit<ControllerProps<T>, 'render'>
|
|
29
27
|
|
|
30
28
|
type OwnerState = { size?: 'small' | 'medium' }
|
|
31
|
-
const
|
|
29
|
+
const componentName = 'TextInputNumber' as const
|
|
32
30
|
const parts = ['quantity', 'quantityInput', 'button'] as const
|
|
33
|
-
const { withState } = extendableComponent<OwnerState, typeof
|
|
31
|
+
const { withState } = extendableComponent<OwnerState, typeof componentName, typeof parts>(
|
|
32
|
+
componentName,
|
|
33
|
+
parts,
|
|
34
|
+
)
|
|
34
35
|
|
|
35
36
|
export function NumberFieldElement<T extends FieldValues = FieldValues>(
|
|
36
37
|
props: NumberFieldElementProps<T>,
|
|
@@ -39,81 +40,100 @@ export function NumberFieldElement<T extends FieldValues = FieldValues>(
|
|
|
39
40
|
DownProps = {},
|
|
40
41
|
UpProps = {},
|
|
41
42
|
inputProps = {},
|
|
42
|
-
inputRef,
|
|
43
43
|
sx = [],
|
|
44
44
|
size = 'medium',
|
|
45
|
+
control,
|
|
46
|
+
name,
|
|
47
|
+
rules = {},
|
|
48
|
+
required,
|
|
49
|
+
defaultValue,
|
|
45
50
|
...textFieldProps
|
|
46
51
|
} = props
|
|
47
52
|
|
|
48
53
|
const classes = withState({ size })
|
|
49
|
-
const ref = useRef<HTMLInputElement>(null)
|
|
50
|
-
const forkRef = useForkRef(ref, inputRef as Ref<HTMLInputElement>)
|
|
51
54
|
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
size={size}
|
|
56
|
-
type='number'
|
|
57
|
-
inputRef={forkRef}
|
|
58
|
-
className={`${textFieldProps.className ?? ''} ${classes.quantity}`}
|
|
59
|
-
sx={[{ width: responsiveVal(80, 120) }, ...(Array.isArray(sx) ? sx : [sx])]}
|
|
60
|
-
autoComplete='off'
|
|
61
|
-
InputProps={{
|
|
62
|
-
...textFieldProps.InputProps,
|
|
63
|
-
startAdornment: (
|
|
64
|
-
<IconButton
|
|
65
|
-
aria-label={i18n._(/* i18n */ 'Decrease')}
|
|
66
|
-
size='medium'
|
|
67
|
-
edge='start'
|
|
68
|
-
onClick={useEventCallback(() => {
|
|
69
|
-
if ((ref.current?.value ?? Infinity) >= inputProps.max) return
|
|
55
|
+
if (required && !rules.required) {
|
|
56
|
+
rules.required = i18n._(/* i18n */ 'This field is required')
|
|
57
|
+
}
|
|
70
58
|
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
{DownProps.children ?? <IconSvg src={iconMin} size='small' />}
|
|
80
|
-
</IconButton>
|
|
81
|
-
),
|
|
82
|
-
endAdornment: (
|
|
83
|
-
<IconButton
|
|
84
|
-
aria-label={i18n._(/* i18n */ 'Increase')}
|
|
85
|
-
size='medium'
|
|
86
|
-
edge='end'
|
|
87
|
-
onClick={useEventCallback(() => {
|
|
88
|
-
if ((ref.current?.value ?? 0) <= inputProps.min) return
|
|
59
|
+
return (
|
|
60
|
+
<Controller
|
|
61
|
+
name={name}
|
|
62
|
+
control={control}
|
|
63
|
+
rules={rules}
|
|
64
|
+
defaultValue={defaultValue}
|
|
65
|
+
render={({ field: { value, onChange, onBlur }, fieldState: { invalid, error } }) => {
|
|
66
|
+
const valueAsNumber = value ? parseFloat(value) : 0
|
|
89
67
|
|
|
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
|
-
|
|
68
|
+
return (
|
|
69
|
+
<TextField
|
|
70
|
+
{...textFieldProps}
|
|
71
|
+
name={name}
|
|
72
|
+
value={value ?? ''}
|
|
73
|
+
onChange={(ev) => {
|
|
74
|
+
const newValue = (ev.target as HTMLInputElement).valueAsNumber
|
|
75
|
+
onChange(Number.isNaN(newValue) ? '' : newValue)
|
|
76
|
+
textFieldProps.onChange?.(ev)
|
|
77
|
+
}}
|
|
78
|
+
onBlur={onBlur}
|
|
79
|
+
required={required}
|
|
80
|
+
error={invalid}
|
|
81
|
+
helperText={error ? error.message : textFieldProps.helperText}
|
|
82
|
+
size={size}
|
|
83
|
+
type='number'
|
|
84
|
+
className={`${textFieldProps.className ?? ''} ${classes.quantity}`}
|
|
85
|
+
sx={[{ width: responsiveVal(80, 120) }, ...(Array.isArray(sx) ? sx : [sx])]}
|
|
86
|
+
autoComplete='off'
|
|
87
|
+
InputProps={{
|
|
88
|
+
...textFieldProps.InputProps,
|
|
89
|
+
startAdornment: (
|
|
90
|
+
<IconButton
|
|
91
|
+
aria-label={i18n._(/* i18n */ 'Decrease')}
|
|
92
|
+
size='medium'
|
|
93
|
+
edge='start'
|
|
94
|
+
onClick={() => {
|
|
95
|
+
if ((valueAsNumber || Infinity) <= inputProps.min) return
|
|
96
|
+
onChange(value - 1)
|
|
97
|
+
}}
|
|
98
|
+
tabIndex={-1}
|
|
99
|
+
color='inherit'
|
|
100
|
+
{...DownProps}
|
|
101
|
+
className={`${classes.button} ${DownProps.className ?? ''}`}
|
|
102
|
+
>
|
|
103
|
+
{DownProps.children ?? <IconSvg src={iconMin} size='small' />}
|
|
104
|
+
</IconButton>
|
|
105
|
+
),
|
|
106
|
+
endAdornment: (
|
|
107
|
+
<IconButton
|
|
108
|
+
aria-label={i18n._(/* i18n */ 'Increase')}
|
|
109
|
+
size='medium'
|
|
110
|
+
edge='end'
|
|
111
|
+
onClick={() => {
|
|
112
|
+
if (valueAsNumber >= (inputProps.max ?? Infinity)) return
|
|
113
|
+
onChange(valueAsNumber + 1)
|
|
114
|
+
}}
|
|
115
|
+
tabIndex={-1}
|
|
116
|
+
color='inherit'
|
|
117
|
+
{...UpProps}
|
|
118
|
+
className={`${classes.button} ${UpProps.className ?? ''}`}
|
|
119
|
+
>
|
|
120
|
+
{UpProps.children ?? <IconSvg src={iconPlus} size='small' />}
|
|
121
|
+
</IconButton>
|
|
122
|
+
),
|
|
123
|
+
}}
|
|
124
|
+
inputProps={{
|
|
125
|
+
...inputProps,
|
|
126
|
+
'aria-label': i18n._(/* i18n */ 'Number'),
|
|
127
|
+
className: `${inputProps?.className ?? ''} ${classes.quantityInput}`,
|
|
128
|
+
sx: {
|
|
129
|
+
textAlign: 'center',
|
|
130
|
+
'&::-webkit-inner-spin-button,&::-webkit-outer-spin-button': {
|
|
131
|
+
appearance: 'none',
|
|
132
|
+
},
|
|
133
|
+
},
|
|
134
|
+
}}
|
|
135
|
+
/>
|
|
136
|
+
)
|
|
117
137
|
}}
|
|
118
138
|
/>
|
|
119
139
|
)
|
|
@@ -4,6 +4,7 @@ import {
|
|
|
4
4
|
FieldError,
|
|
5
5
|
FieldValues,
|
|
6
6
|
} from '@graphcommerce/react-hook-form'
|
|
7
|
+
import { i18n } from '@lingui/core'
|
|
7
8
|
import { TextField, TextFieldProps } from '@mui/material'
|
|
8
9
|
|
|
9
10
|
export type TextFieldElementProps<T extends FieldValues = FieldValues> = Omit<
|
|
@@ -26,7 +27,7 @@ export function TextFieldElement<TFieldValues extends FieldValues = FieldValues>
|
|
|
26
27
|
...rest
|
|
27
28
|
}: TextFieldElementProps<TFieldValues>): JSX.Element {
|
|
28
29
|
if (required && !validation.required) {
|
|
29
|
-
validation.required = 'This field is required'
|
|
30
|
+
validation.required = i18n._(/* i18n */ 'This field is required')
|
|
30
31
|
}
|
|
31
32
|
|
|
32
33
|
if (type === 'email' && !validation.pattern) {
|
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": "1.5.
|
|
5
|
+
"version": "1.5.1",
|
|
6
6
|
"sideEffects": false,
|
|
7
7
|
"prettier": "@graphcommerce/prettier-config-pwa",
|
|
8
8
|
"eslintConfig": {
|
|
@@ -14,7 +14,7 @@
|
|
|
14
14
|
"dependencies": {
|
|
15
15
|
"@graphcommerce/graphql": "3.4.8",
|
|
16
16
|
"@graphcommerce/next-ui": "4.27.0",
|
|
17
|
-
"@graphcommerce/react-hook-form": "3.3.
|
|
17
|
+
"@graphcommerce/react-hook-form": "3.3.4",
|
|
18
18
|
"@mui/icons-material": "^5.10.3",
|
|
19
19
|
"@mui/x-date-pickers": "^5.0.0",
|
|
20
20
|
"react-hook-form-mui": "^5.7.1"
|