@graphcommerce/next-ui 4.8.1 → 4.8.4
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/FramerScroller/SidebarGallery.tsx +6 -10
- package/TextInputNumber/TextInputNumber.tsx +0 -3
- package/Theme/themeDefaults.ts +2 -3
- package/package.json +2 -2
|
@@ -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.4
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- [#1509](https://github.com/graphcommerce-org/graphcommerce/pull/1509) [`0ab7c5465`](https://github.com/graphcommerce-org/graphcommerce/commit/0ab7c5465441cba9bf8cd185a6790ce2f443f4ed) Thanks [@paales](https://github.com/paales)! - SidebarGallery improvements (product page):
|
|
8
|
+
|
|
9
|
+
- Prevent vertical scrolling
|
|
10
|
+
- Disable zoom fab when there are no images
|
|
11
|
+
- Hide scroller dots when there in only one image
|
|
12
|
+
- Make sure the prev/next buttons are shown as expected
|
|
13
|
+
|
|
14
|
+
- Updated dependencies [[`0ab7c5465`](https://github.com/graphcommerce-org/graphcommerce/commit/0ab7c5465441cba9bf8cd185a6790ce2f443f4ed)]:
|
|
15
|
+
- @graphcommerce/framer-scroller@2.1.15
|
|
16
|
+
|
|
17
|
+
## 4.8.3
|
|
18
|
+
|
|
19
|
+
### Patch Changes
|
|
20
|
+
|
|
21
|
+
- [#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
|
|
22
|
+
|
|
23
|
+
- Updated dependencies []:
|
|
24
|
+
- @graphcommerce/framer-scroller@2.1.14
|
|
25
|
+
|
|
26
|
+
## 4.8.2
|
|
27
|
+
|
|
28
|
+
### Patch Changes
|
|
29
|
+
|
|
30
|
+
- [#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
|
|
31
|
+
|
|
32
|
+
- Updated dependencies []:
|
|
33
|
+
- @graphcommerce/framer-scroller@2.1.13
|
|
34
|
+
|
|
3
35
|
## 4.8.1
|
|
4
36
|
|
|
5
37
|
### Patch Changes
|
|
@@ -114,6 +114,8 @@ export function SidebarGallery(props: SidebarGalleryProps) {
|
|
|
114
114
|
const maxHeight = `calc(100vh - ${headerHeight} - ${galleryMargin} - ${extraSpacing})`
|
|
115
115
|
const ratio = `calc(${height} / ${width} * 100%)`
|
|
116
116
|
|
|
117
|
+
const hasImages = images.length > 0
|
|
118
|
+
|
|
117
119
|
return (
|
|
118
120
|
<ScrollerProvider scrollSnapAlign='center'>
|
|
119
121
|
<Row maxWidth={false} disableGutters className={classes.row} sx={sx}>
|
|
@@ -197,6 +199,7 @@ export function SidebarGallery(props: SidebarGalleryProps) {
|
|
|
197
199
|
width={image.width}
|
|
198
200
|
height={image.height}
|
|
199
201
|
loading={idx === 0 ? 'eager' : 'lazy'}
|
|
202
|
+
sx={{ display: 'block' }}
|
|
200
203
|
sizes={{
|
|
201
204
|
0: '100vw',
|
|
202
205
|
[theme.breakpoints.values.md]: zoomed ? '100vw' : '60vw',
|
|
@@ -221,11 +224,10 @@ export function SidebarGallery(props: SidebarGalleryProps) {
|
|
|
221
224
|
<Fab
|
|
222
225
|
size='small'
|
|
223
226
|
className={classes.toggleIcon}
|
|
227
|
+
disabled={!hasImages}
|
|
224
228
|
onMouseUp={toggle}
|
|
225
229
|
aria-label='Toggle Fullscreen'
|
|
226
|
-
sx={{
|
|
227
|
-
boxShadow: theme.shadows[6],
|
|
228
|
-
}}
|
|
230
|
+
sx={{ boxShadow: 6 }}
|
|
229
231
|
>
|
|
230
232
|
{!zoomed ? <IconSvg src={iconFullscreen} /> : <IconSvg src={iconFullscreenExit} />}
|
|
231
233
|
</Fab>
|
|
@@ -286,13 +288,7 @@ export function SidebarGallery(props: SidebarGalleryProps) {
|
|
|
286
288
|
},
|
|
287
289
|
}}
|
|
288
290
|
>
|
|
289
|
-
<ScrollerDots
|
|
290
|
-
layout
|
|
291
|
-
sx={{
|
|
292
|
-
background: alpha(theme.palette.background.paper, 1),
|
|
293
|
-
boxShadow: theme.shadows[6],
|
|
294
|
-
}}
|
|
295
|
-
/>
|
|
291
|
+
<ScrollerDots layout sx={{ backgroundColor: 'background.paper', boxShadow: 6 }} />
|
|
296
292
|
</Box>
|
|
297
293
|
</MotionBox>
|
|
298
294
|
|
|
@@ -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.4",
|
|
6
6
|
"author": "",
|
|
7
7
|
"license": "MIT",
|
|
8
8
|
"sideEffects": false,
|
|
@@ -20,7 +20,7 @@
|
|
|
20
20
|
"@emotion/server": "^11.4.0",
|
|
21
21
|
"@emotion/styled": "^11.6.0",
|
|
22
22
|
"@graphcommerce/framer-next-pages": "3.2.2",
|
|
23
|
-
"@graphcommerce/framer-scroller": "2.1.
|
|
23
|
+
"@graphcommerce/framer-scroller": "2.1.15",
|
|
24
24
|
"@graphcommerce/framer-utils": "3.1.3",
|
|
25
25
|
"@graphcommerce/image": "3.1.6",
|
|
26
26
|
"react-is": "^17.0.0",
|