@graphcommerce/next-ui 4.8.0 → 4.8.3
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/ActionCard/ActionCard.tsx +29 -40
- package/ActionCard/ActionCardList.tsx +19 -7
- package/ActionCard/ActionCardListForm.tsx +63 -0
- package/CHANGELOG.md +32 -0
- package/LayoutDefault/components/LayoutDefault.tsx +1 -1
- package/LayoutOverlay/components/LayoutOverlayBase.tsx +6 -9
- package/TextInputNumber/TextInputNumber.tsx +0 -3
- package/Theme/themeDefaults.ts +2 -3
- package/package.json +5 -5
|
@@ -2,21 +2,32 @@ import { Theme } from '@emotion/react'
|
|
|
2
2
|
import { SxProps, ButtonBase, Box } from '@mui/material'
|
|
3
3
|
import React, { FormEvent } from 'react'
|
|
4
4
|
|
|
5
|
-
type ActionCardProps = {
|
|
5
|
+
export type ActionCardProps = {
|
|
6
6
|
sx?: SxProps<Theme>
|
|
7
7
|
title?: string | React.ReactNode
|
|
8
8
|
image?: React.ReactNode
|
|
9
9
|
action?: React.ReactNode
|
|
10
10
|
details?: React.ReactNode
|
|
11
11
|
secondaryAction?: React.ReactNode
|
|
12
|
-
onClick?: (e: FormEvent<
|
|
13
|
-
onChange?: (e: FormEvent<HTMLButtonElement>, v: string) => void
|
|
12
|
+
onClick?: (e: FormEvent<HTMLElement>, v: string | number) => void
|
|
14
13
|
selected?: boolean
|
|
15
14
|
hidden?: boolean | (() => boolean)
|
|
16
|
-
value: string
|
|
15
|
+
value: string | number
|
|
17
16
|
reset?: React.ReactNode
|
|
18
17
|
}
|
|
19
18
|
|
|
19
|
+
const actionButtonStyles: SxProps = {
|
|
20
|
+
'& .MuiButton-root': {
|
|
21
|
+
'&.MuiButton-textSecondary': {
|
|
22
|
+
padding: '5px',
|
|
23
|
+
margin: '-5px',
|
|
24
|
+
'&:hover': {
|
|
25
|
+
background: 'none',
|
|
26
|
+
},
|
|
27
|
+
},
|
|
28
|
+
},
|
|
29
|
+
}
|
|
30
|
+
|
|
20
31
|
export function ActionCard(props: ActionCardProps) {
|
|
21
32
|
const {
|
|
22
33
|
title,
|
|
@@ -25,7 +36,6 @@ export function ActionCard(props: ActionCardProps) {
|
|
|
25
36
|
details,
|
|
26
37
|
secondaryAction,
|
|
27
38
|
sx = [],
|
|
28
|
-
onChange,
|
|
29
39
|
onClick,
|
|
30
40
|
value,
|
|
31
41
|
selected,
|
|
@@ -33,52 +43,31 @@ export function ActionCard(props: ActionCardProps) {
|
|
|
33
43
|
reset,
|
|
34
44
|
} = props
|
|
35
45
|
|
|
36
|
-
const
|
|
37
|
-
const handleClick = (event: FormEvent<HTMLButtonElement>) => {
|
|
38
|
-
if (onClick) {
|
|
39
|
-
onClick(event, value)
|
|
40
|
-
if (event.isDefaultPrevented()) return
|
|
41
|
-
}
|
|
42
|
-
handleChange(event)
|
|
43
|
-
}
|
|
44
|
-
|
|
45
|
-
const actionButtonStyles: SxProps = {
|
|
46
|
-
'& .MuiButton-root': {
|
|
47
|
-
'&.MuiButton-textSecondary': {
|
|
48
|
-
padding: '5px',
|
|
49
|
-
margin: '-5px',
|
|
50
|
-
'&:hover': {
|
|
51
|
-
background: 'none',
|
|
52
|
-
},
|
|
53
|
-
},
|
|
54
|
-
},
|
|
55
|
-
}
|
|
46
|
+
const handleClick = (event: FormEvent<HTMLElement>) => onClick?.(event, value)
|
|
56
47
|
|
|
57
48
|
return (
|
|
58
49
|
<ButtonBase
|
|
59
|
-
component='
|
|
50
|
+
component='div'
|
|
60
51
|
className='ActionCard-root'
|
|
61
52
|
onClick={handleClick}
|
|
62
|
-
onChange={handleChange}
|
|
63
|
-
value={value}
|
|
64
53
|
sx={[
|
|
65
|
-
{
|
|
54
|
+
(theme) => ({
|
|
66
55
|
display: 'grid',
|
|
67
56
|
width: '100%',
|
|
68
57
|
gridTemplateColumns: 'min-content',
|
|
69
|
-
gridTemplateAreas:
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
58
|
+
gridTemplateAreas: {
|
|
59
|
+
xs: `
|
|
60
|
+
"image title action"
|
|
61
|
+
"image details details"
|
|
62
|
+
"image secondaryAction additionalDetails"
|
|
63
|
+
"additionalContent additionalContent additionalContent"
|
|
64
|
+
`,
|
|
65
|
+
},
|
|
75
66
|
justifyContent: 'unset',
|
|
76
|
-
},
|
|
77
|
-
(theme) => ({
|
|
78
67
|
typography: 'body1',
|
|
79
|
-
textAlign: 'left',
|
|
68
|
+
// textAlign: 'left',
|
|
80
69
|
background: theme.palette.background.paper,
|
|
81
|
-
padding: `calc(${theme.spacings.xs} + 1px)`,
|
|
70
|
+
padding: `calc(${theme.spacings.xxs} + 1px) calc(${theme.spacings.xs} + 1px)`,
|
|
82
71
|
columnGap: theme.spacings.xxs,
|
|
83
72
|
border: `1px solid ${theme.palette.divider}`,
|
|
84
73
|
borderBottomColor: `transparent`,
|
|
@@ -102,7 +91,7 @@ export function ActionCard(props: ActionCardProps) {
|
|
|
102
91
|
borderTopRightRadius: theme.shape.borderRadius,
|
|
103
92
|
borderBottomLeftRadius: theme.shape.borderRadius,
|
|
104
93
|
borderBottomRightRadius: theme.shape.borderRadius,
|
|
105
|
-
padding: theme.spacings.xs
|
|
94
|
+
padding: `${theme.spacings.xxs} ${theme.spacings.xs}`,
|
|
106
95
|
})),
|
|
107
96
|
...(Array.isArray(sx) ? sx : [sx]),
|
|
108
97
|
]}
|
|
@@ -1,6 +1,8 @@
|
|
|
1
|
-
import { Box } from '@mui/material'
|
|
1
|
+
import { Alert, Box, FormHelperText } from '@mui/material'
|
|
2
|
+
import { AnimatePresence } from 'framer-motion'
|
|
2
3
|
import React from 'react'
|
|
3
4
|
import { isFragment } from 'react-is'
|
|
5
|
+
import { AnimatedRow } from '../AnimatedRow/AnimatedRow'
|
|
4
6
|
|
|
5
7
|
type MultiSelect = {
|
|
6
8
|
multiple: true
|
|
@@ -16,10 +18,11 @@ type Select = {
|
|
|
16
18
|
onChange?: (event: React.MouseEvent<HTMLElement>, value: string | null) => void
|
|
17
19
|
}
|
|
18
20
|
|
|
19
|
-
type ActionCardListProps<SelectOrMulti = MultiSelect | Select> = {
|
|
21
|
+
export type ActionCardListProps<SelectOrMulti = MultiSelect | Select> = {
|
|
20
22
|
children?: React.ReactNode
|
|
21
23
|
required?: boolean
|
|
22
24
|
error?: boolean
|
|
25
|
+
errorMessage?: string
|
|
23
26
|
} & SelectOrMulti
|
|
24
27
|
|
|
25
28
|
function isMulti(props: ActionCardListProps): props is ActionCardListProps<MultiSelect> {
|
|
@@ -33,7 +36,7 @@ function isValueSelected(value: string, candidate: string | string[]) {
|
|
|
33
36
|
}
|
|
34
37
|
|
|
35
38
|
export function ActionCardList(props: ActionCardListProps) {
|
|
36
|
-
const { children, required, value, error = false } = props
|
|
39
|
+
const { children, required, value, error = false, errorMessage } = props
|
|
37
40
|
|
|
38
41
|
const handleChange = isMulti(props)
|
|
39
42
|
? (event: React.MouseEvent<HTMLElement, MouseEvent>, buttonValue: string) => {
|
|
@@ -70,15 +73,15 @@ export function ActionCardList(props: ActionCardListProps) {
|
|
|
70
73
|
paddingLeft: theme.spacings.xs,
|
|
71
74
|
paddingRight: theme.spacings.xs,
|
|
72
75
|
},
|
|
73
|
-
'&
|
|
76
|
+
'& > div:first-of-type.ActionCard-root': {
|
|
74
77
|
borderTop: 2,
|
|
75
78
|
borderTopColor: 'error.main',
|
|
76
|
-
paddingTop: theme.spacings.
|
|
79
|
+
paddingTop: theme.spacings.xxs,
|
|
77
80
|
},
|
|
78
|
-
'&
|
|
81
|
+
'& > div:last-of-type.ActionCard-root': {
|
|
79
82
|
borderBottom: 2,
|
|
80
83
|
borderBottomColor: 'error.main',
|
|
81
|
-
paddingBottom: theme.spacings.
|
|
84
|
+
paddingBottom: theme.spacings.xxs,
|
|
82
85
|
},
|
|
83
86
|
})),
|
|
84
87
|
]}
|
|
@@ -105,6 +108,15 @@ export function ActionCardList(props: ActionCardListProps) {
|
|
|
105
108
|
: child.props.selected,
|
|
106
109
|
})
|
|
107
110
|
})}
|
|
111
|
+
{error && (
|
|
112
|
+
<Alert
|
|
113
|
+
severity='error'
|
|
114
|
+
variant='filled'
|
|
115
|
+
sx={{ borderStartStartRadius: 0, borderStartEndRadius: 0 }}
|
|
116
|
+
>
|
|
117
|
+
{errorMessage}
|
|
118
|
+
</Alert>
|
|
119
|
+
)}
|
|
108
120
|
</Box>
|
|
109
121
|
)
|
|
110
122
|
}
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
/* eslint-disable import/no-extraneous-dependencies */
|
|
2
|
+
import { Controller, ControllerProps } from '@graphcommerce/react-hook-form'
|
|
3
|
+
import React from 'react'
|
|
4
|
+
import { ActionCardProps } from './ActionCard'
|
|
5
|
+
import { ActionCardList, ActionCardListProps } from './ActionCardList'
|
|
6
|
+
|
|
7
|
+
export type ActionCardItemBase = Pick<ActionCardProps, 'value'>
|
|
8
|
+
|
|
9
|
+
export type ActionCardItemRenderer<T> = Pick<ActionCardProps, 'selected' | 'hidden' | 'value'> & {
|
|
10
|
+
onReset: React.MouseEventHandler<HTMLButtonElement>
|
|
11
|
+
} & T
|
|
12
|
+
|
|
13
|
+
export type ActionCardListFormProps<T extends ActionCardItemBase> = Omit<
|
|
14
|
+
ActionCardListProps,
|
|
15
|
+
'value'
|
|
16
|
+
> &
|
|
17
|
+
Omit<ControllerProps<any>, 'render'> & {
|
|
18
|
+
items: T[]
|
|
19
|
+
render: React.VFC<ActionCardItemRenderer<T>>
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
export function ActionCardListForm<T extends ActionCardItemBase>(
|
|
23
|
+
props: ActionCardListFormProps<T>,
|
|
24
|
+
) {
|
|
25
|
+
const { required, rules, items, render, control, name, errorMessage } = props
|
|
26
|
+
const RenderItem = render as React.VFC<ActionCardItemRenderer<ActionCardItemBase>>
|
|
27
|
+
|
|
28
|
+
return (
|
|
29
|
+
<Controller
|
|
30
|
+
{...props}
|
|
31
|
+
control={control}
|
|
32
|
+
name={name}
|
|
33
|
+
rules={{
|
|
34
|
+
required,
|
|
35
|
+
...rules,
|
|
36
|
+
validate: (v) => (v ? true : 'Please select a shipping address'),
|
|
37
|
+
}}
|
|
38
|
+
render={({ field: { onChange, value }, fieldState, formState }) => (
|
|
39
|
+
<ActionCardList
|
|
40
|
+
required
|
|
41
|
+
value={value}
|
|
42
|
+
onChange={(_, incomming) => onChange(incomming)}
|
|
43
|
+
error={formState.isSubmitted && !!fieldState.error}
|
|
44
|
+
errorMessage={errorMessage}
|
|
45
|
+
>
|
|
46
|
+
{items.map((item) => (
|
|
47
|
+
<RenderItem
|
|
48
|
+
{...item}
|
|
49
|
+
key={item.value}
|
|
50
|
+
value={item.value}
|
|
51
|
+
selected={value === item.value}
|
|
52
|
+
hidden={!!value && value !== item.value}
|
|
53
|
+
onReset={(e) => {
|
|
54
|
+
e.preventDefault()
|
|
55
|
+
onChange(null)
|
|
56
|
+
}}
|
|
57
|
+
/>
|
|
58
|
+
))}
|
|
59
|
+
</ActionCardList>
|
|
60
|
+
)}
|
|
61
|
+
/>
|
|
62
|
+
)
|
|
63
|
+
}
|
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,37 @@
|
|
|
1
1
|
# Change Log
|
|
2
2
|
|
|
3
|
+
## 4.8.3
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- [#1487](https://github.com/graphcommerce-org/graphcommerce/pull/1487) [`afc67103d`](https://github.com/graphcommerce-org/graphcommerce/commit/afc67103d0e00583e274465036fd287537f95e79) Thanks [@paales](https://github.com/paales)! - When additing an additional breakpoint it would throw a typescript error
|
|
8
|
+
|
|
9
|
+
- Updated dependencies []:
|
|
10
|
+
- @graphcommerce/framer-scroller@2.1.14
|
|
11
|
+
|
|
12
|
+
## 4.8.2
|
|
13
|
+
|
|
14
|
+
### Patch Changes
|
|
15
|
+
|
|
16
|
+
- [#1485](https://github.com/graphcommerce-org/graphcommerce/pull/1485) [`c8c246b8a`](https://github.com/graphcommerce-org/graphcommerce/commit/c8c246b8aaab0621b68a2fca2a1c529a56fad962) Thanks [@paales](https://github.com/paales)! - TextInputNumber: when adding a label it should be displayed properly
|
|
17
|
+
|
|
18
|
+
- Updated dependencies []:
|
|
19
|
+
- @graphcommerce/framer-scroller@2.1.13
|
|
20
|
+
|
|
21
|
+
## 4.8.1
|
|
22
|
+
|
|
23
|
+
### Patch Changes
|
|
24
|
+
|
|
25
|
+
- [#1477](https://github.com/graphcommerce-org/graphcommerce/pull/1477) [`a9df81310`](https://github.com/graphcommerce-org/graphcommerce/commit/a9df81310c051876dd82fb2819105dece47cc213) Thanks [@paales](https://github.com/paales)! - Revert faulty background color on LayoutDefault
|
|
26
|
+
|
|
27
|
+
* [#1477](https://github.com/graphcommerce-org/graphcommerce/pull/1477) [`f167f9963`](https://github.com/graphcommerce-org/graphcommerce/commit/f167f99630966a7de43717937d43669e66132494) Thanks [@paales](https://github.com/paales)! - LayoutOverlay performance improvements
|
|
28
|
+
|
|
29
|
+
* Updated dependencies [[`55c2dcde7`](https://github.com/graphcommerce-org/graphcommerce/commit/55c2dcde7869ee51b84494af653b3edfd43904a4), [`597e2f413`](https://github.com/graphcommerce-org/graphcommerce/commit/597e2f413bdb5b76793b40ab631ce61390e26e81), [`f167f9963`](https://github.com/graphcommerce-org/graphcommerce/commit/f167f99630966a7de43717937d43669e66132494)]:
|
|
30
|
+
- @graphcommerce/framer-scroller@2.1.12
|
|
31
|
+
- @graphcommerce/framer-next-pages@3.2.2
|
|
32
|
+
- @graphcommerce/framer-utils@3.1.3
|
|
33
|
+
- @graphcommerce/image@3.1.6
|
|
34
|
+
|
|
3
35
|
## 4.8.0
|
|
4
36
|
|
|
5
37
|
### Minor Changes
|
|
@@ -58,7 +58,7 @@ export function LayoutDefault(props: LayoutDefaultProps) {
|
|
|
58
58
|
display: 'grid',
|
|
59
59
|
gridTemplateRows: `auto auto 1fr auto`,
|
|
60
60
|
gridTemplateColumns: '100%',
|
|
61
|
-
background: theme.palette.background.
|
|
61
|
+
background: theme.palette.background.default,
|
|
62
62
|
}),
|
|
63
63
|
...(Array.isArray(sx) ? sx : [sx]),
|
|
64
64
|
]}
|
|
@@ -177,7 +177,6 @@ export function LayoutOverlayBase(incommingProps: LayoutOverlayBaseProps) {
|
|
|
177
177
|
useEffect(() => positions.open.visible.onChange((o) => o === 0 && closeOverlay()))
|
|
178
178
|
|
|
179
179
|
// Measure the offset of the overlay in the scroller.
|
|
180
|
-
|
|
181
180
|
const offsetY = useMotionValue(0)
|
|
182
181
|
useEffect(() => {
|
|
183
182
|
if (!overlayRef.current) return () => {}
|
|
@@ -195,21 +194,20 @@ export function LayoutOverlayBase(incommingProps: LayoutOverlayBaseProps) {
|
|
|
195
194
|
|
|
196
195
|
const onClickAway = useCallback(
|
|
197
196
|
(event: React.MouseEvent<HTMLDivElement>) => {
|
|
198
|
-
const isTarget =
|
|
197
|
+
const isTarget =
|
|
198
|
+
event.target === scrollerRef.current ||
|
|
199
|
+
event.target === beforeRef.current ||
|
|
200
|
+
event.target === overlayRef.current
|
|
199
201
|
if (isTarget && snap.get()) closeOverlay()
|
|
200
202
|
},
|
|
201
203
|
[closeOverlay, scrollerRef, snap],
|
|
202
204
|
)
|
|
203
205
|
|
|
204
|
-
const pointerEvents = useTransform(position, (p) =>
|
|
205
|
-
p === OverlayPosition.CLOSED ? 'none' : 'auto',
|
|
206
|
-
)
|
|
207
|
-
|
|
208
206
|
return (
|
|
209
207
|
<>
|
|
210
208
|
<MotionDiv
|
|
211
209
|
className={classes.backdrop}
|
|
212
|
-
style={{ opacity: positions.open.visible
|
|
210
|
+
style={{ opacity: positions.open.visible }}
|
|
213
211
|
sx={[
|
|
214
212
|
{
|
|
215
213
|
zIndex: -1,
|
|
@@ -233,7 +231,6 @@ export function LayoutOverlayBase(incommingProps: LayoutOverlayBaseProps) {
|
|
|
233
231
|
grid={false}
|
|
234
232
|
hideScrollbar
|
|
235
233
|
onClick={onClickAway}
|
|
236
|
-
style={{ pointerEvents }}
|
|
237
234
|
sx={[
|
|
238
235
|
(theme) => ({
|
|
239
236
|
overscrollBehavior: 'contain',
|
|
@@ -320,9 +317,9 @@ export function LayoutOverlayBase(incommingProps: LayoutOverlayBaseProps) {
|
|
|
320
317
|
<Box
|
|
321
318
|
className={classes.overlay}
|
|
322
319
|
ref={overlayRef}
|
|
320
|
+
onClick={onClickAway}
|
|
323
321
|
sx={(theme) => ({
|
|
324
322
|
display: 'grid',
|
|
325
|
-
pointerEvents: 'none',
|
|
326
323
|
gridArea: 'overlay',
|
|
327
324
|
scrollSnapAlign: 'start',
|
|
328
325
|
scrollSnapStop: 'always',
|
|
@@ -97,13 +97,10 @@ export function TextInputNumber(props: TextInputNumberProps) {
|
|
|
97
97
|
width: responsiveVal(80, 120),
|
|
98
98
|
backgroundColor: 'inherit',
|
|
99
99
|
},
|
|
100
|
-
|
|
101
100
|
...(Array.isArray(sx) ? sx : [sx]),
|
|
102
101
|
]}
|
|
103
102
|
autoComplete='off'
|
|
104
|
-
label={' '}
|
|
105
103
|
id='quantity-input'
|
|
106
|
-
InputLabelProps={{ shrink: false }}
|
|
107
104
|
InputProps={{
|
|
108
105
|
...textFieldProps.InputProps,
|
|
109
106
|
startAdornment: (
|
package/Theme/themeDefaults.ts
CHANGED
|
@@ -1,10 +1,9 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { experimental_sx, SxProps, Theme } from '@mui/material'
|
|
2
2
|
import { Shadows } from '@mui/material/styles/shadows'
|
|
3
|
-
import type { SetRequired } from 'type-fest'
|
|
4
3
|
|
|
5
4
|
// https://material.io/design/environment/elevation.html#default-elevations
|
|
6
5
|
|
|
7
|
-
const breakpoints
|
|
6
|
+
const breakpoints = {
|
|
8
7
|
values: {
|
|
9
8
|
xs: 0,
|
|
10
9
|
sm: 600,
|
package/package.json
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
"name": "@graphcommerce/next-ui",
|
|
3
3
|
"homepage": "https://www.graphcommerce.org/",
|
|
4
4
|
"repository": "github:graphcommerce-org/graphcommerce",
|
|
5
|
-
"version": "4.8.
|
|
5
|
+
"version": "4.8.3",
|
|
6
6
|
"author": "",
|
|
7
7
|
"license": "MIT",
|
|
8
8
|
"sideEffects": false,
|
|
@@ -19,10 +19,10 @@
|
|
|
19
19
|
"@emotion/react": "^11.9.0",
|
|
20
20
|
"@emotion/server": "^11.4.0",
|
|
21
21
|
"@emotion/styled": "^11.6.0",
|
|
22
|
-
"@graphcommerce/framer-next-pages": "3.2.
|
|
23
|
-
"@graphcommerce/framer-scroller": "2.1.
|
|
24
|
-
"@graphcommerce/framer-utils": "3.1.
|
|
25
|
-
"@graphcommerce/image": "3.1.
|
|
22
|
+
"@graphcommerce/framer-next-pages": "3.2.2",
|
|
23
|
+
"@graphcommerce/framer-scroller": "2.1.14",
|
|
24
|
+
"@graphcommerce/framer-utils": "3.1.3",
|
|
25
|
+
"@graphcommerce/image": "3.1.6",
|
|
26
26
|
"react-is": "^17.0.0",
|
|
27
27
|
"react-schemaorg": "^2.0.0",
|
|
28
28
|
"schema-dts": "^1.1.0"
|