@graphcommerce/next-ui 3.21.15 → 3.22.0
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/AppShell/DesktopNavBar.tsx +2 -2
- package/AppShell/Logo.tsx +2 -2
- package/CHANGELOG.md +19 -0
- package/FramerScroller/components/SidebarGallery.tsx +2 -2
- package/Layout/components/LayoutHeader.tsx +3 -6
- package/Layout/components/LayoutHeaderBack.tsx +7 -4
- package/Layout/components/LayoutHeaderClose.tsx +4 -4
- package/Layout/components/LayoutHeaderContent.tsx +8 -2
- package/Layout/components/LayoutTitle.tsx +6 -0
- package/LayoutOverlay/components/LayoutOverlay.tsx +7 -2
- package/LayoutOverlay/components/LayoutOverlayBase.tsx +150 -97
- package/LayoutOverlay/test/LayoutOverlayDemo.tsx +41 -0
- package/package.json +8 -8
|
@@ -1,9 +1,9 @@
|
|
|
1
|
-
import { usePageRouter } from '@graphcommerce/framer-next-pages'
|
|
2
1
|
import { Scroller, ScrollerButton, ScrollerProvider } from '@graphcommerce/framer-scroller'
|
|
3
2
|
import { Link, LinkProps as MuiLinkProps, makeStyles, Theme } from '@material-ui/core'
|
|
4
3
|
import clsx from 'clsx'
|
|
5
4
|
import { m } from 'framer-motion'
|
|
6
5
|
import PageLink from 'next/link'
|
|
6
|
+
import { useRouter } from 'next/router'
|
|
7
7
|
import React from 'react'
|
|
8
8
|
import { UseStyles } from '../Styles'
|
|
9
9
|
import SvgImageSimple from '../SvgImage/SvgImageSimple'
|
|
@@ -92,7 +92,7 @@ export type MenuTabsProps = MenuProps &
|
|
|
92
92
|
export default function DesktopNavBar(props: MenuTabsProps) {
|
|
93
93
|
const { menu, LinkProps, iconScrollerBtnLeft, iconScrollerBtnRight } = props
|
|
94
94
|
const classes = useStyles(props)
|
|
95
|
-
const router =
|
|
95
|
+
const router = useRouter()
|
|
96
96
|
|
|
97
97
|
return (
|
|
98
98
|
<ScrollerProvider scrollSnapAlign='none'>
|
package/AppShell/Logo.tsx
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import { usePageRouter } from '@graphcommerce/framer-next-pages'
|
|
2
1
|
import { Image, ImageProps } from '@graphcommerce/image'
|
|
3
2
|
import { makeStyles, Theme } from '@material-ui/core'
|
|
4
3
|
import PageLink from 'next/link'
|
|
4
|
+
import { useRouter } from 'next/router'
|
|
5
5
|
import React from 'react'
|
|
6
6
|
import { UseStyles } from '../Styles'
|
|
7
7
|
|
|
@@ -29,7 +29,7 @@ export type LogoProps = { href?: `/${string}`; image: ImageProps } & UseStyles<t
|
|
|
29
29
|
|
|
30
30
|
export default function Logo(props: LogoProps) {
|
|
31
31
|
const { href, image } = props
|
|
32
|
-
const router =
|
|
32
|
+
const router = useRouter()
|
|
33
33
|
const classes = useStyles(props)
|
|
34
34
|
|
|
35
35
|
return router.asPath === '/' ? (
|
package/CHANGELOG.md
CHANGED
|
@@ -3,6 +3,25 @@
|
|
|
3
3
|
All notable changes to this project will be documented in this file.
|
|
4
4
|
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
|
|
5
5
|
|
|
6
|
+
# [3.22.0](https://github.com/ho-nl/m2-pwa/compare/@graphcommerce/next-ui@3.21.15...@graphcommerce/next-ui@3.22.0) (2022-01-03)
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
### Bug Fixes
|
|
10
|
+
|
|
11
|
+
* backbutton had wrong label ([c6d0b27](https://github.com/ho-nl/m2-pwa/commit/c6d0b2738e5de734af40bc632177dcc867e8e556))
|
|
12
|
+
* make sure we're able to close the overlay ([8d19fde](https://github.com/ho-nl/m2-pwa/commit/8d19fde07d51493acfdfaa97a19f61246d04d42a))
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
### Features
|
|
16
|
+
|
|
17
|
+
* add support for minimal overlay size ([96e508a](https://github.com/ho-nl/m2-pwa/commit/96e508a94e23fe5b3ec523cddeb19b7b70f50034))
|
|
18
|
+
* added support for more positioning options for the overlay ([79eae9e](https://github.com/ho-nl/m2-pwa/commit/79eae9eb39513f5611103c4c745c3db99b11f15a))
|
|
19
|
+
* **framer-next-pages:** reduce rerenders when navigating to a new page ([5cf3301](https://github.com/ho-nl/m2-pwa/commit/5cf330130bb3527057da015e3c4a6fa295d7262e))
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
|
|
24
|
+
|
|
6
25
|
## [3.21.15](https://github.com/ho-nl/m2-pwa/compare/@graphcommerce/next-ui@3.21.14...@graphcommerce/next-ui@3.21.15) (2021-12-24)
|
|
7
26
|
|
|
8
27
|
|
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
import { usePageRouter } from '@graphcommerce/framer-next-pages'
|
|
2
1
|
import { usePrevPageRouter } from '@graphcommerce/framer-next-pages/hooks/usePrevPageRouter'
|
|
3
2
|
import {
|
|
4
3
|
MotionImageAspect,
|
|
@@ -11,6 +10,7 @@ import {
|
|
|
11
10
|
import { clientSize, useMotionValueValue } from '@graphcommerce/framer-utils'
|
|
12
11
|
import { Fab, makeStyles, Theme, useTheme, alpha } from '@material-ui/core'
|
|
13
12
|
import { m, useDomEvent, useMotionValue } from 'framer-motion'
|
|
13
|
+
import { useRouter } from 'next/router'
|
|
14
14
|
import React, { useEffect, useRef } from 'react'
|
|
15
15
|
import Row from '../../Row'
|
|
16
16
|
import { UseStyles } from '../../Styles'
|
|
@@ -183,7 +183,7 @@ export default function SidebarGallery(props: SidebarGalleryProps) {
|
|
|
183
183
|
classes: classesBase,
|
|
184
184
|
} = props
|
|
185
185
|
|
|
186
|
-
const router =
|
|
186
|
+
const router = useRouter()
|
|
187
187
|
const prevRoute = usePrevPageRouter()
|
|
188
188
|
const clientHeight = useMotionValueValue(clientSize.y, (y) => y)
|
|
189
189
|
const classes = useStyles({ clientHeight, aspectRatio, classes: classesBase })
|
|
@@ -23,8 +23,6 @@ export type LayoutHeaderProps = FloatingProps &
|
|
|
23
23
|
*/
|
|
24
24
|
secondary?: React.ReactNode
|
|
25
25
|
|
|
26
|
-
additional?: React.ReactNode
|
|
27
|
-
|
|
28
26
|
noAlign?: boolean
|
|
29
27
|
}
|
|
30
28
|
|
|
@@ -97,7 +95,7 @@ const useStyles = makeStyles(
|
|
|
97
95
|
)
|
|
98
96
|
|
|
99
97
|
export function LayoutHeader(props: LayoutHeaderProps) {
|
|
100
|
-
const { children,
|
|
98
|
+
const { children, divider, primary, secondary, noAlign, switchPoint } = props
|
|
101
99
|
const classes = useStyles(props)
|
|
102
100
|
const showBack = useShowBack()
|
|
103
101
|
const showClose = useShowClose()
|
|
@@ -118,8 +116,8 @@ export function LayoutHeader(props: LayoutHeaderProps) {
|
|
|
118
116
|
|
|
119
117
|
if (back) left = back
|
|
120
118
|
|
|
121
|
-
if (!
|
|
122
|
-
else if (!
|
|
119
|
+
if (!right) right = close
|
|
120
|
+
else if (!left) right = close
|
|
123
121
|
|
|
124
122
|
if (!left && !right && !children) return null
|
|
125
123
|
|
|
@@ -144,7 +142,6 @@ export function LayoutHeader(props: LayoutHeaderProps) {
|
|
|
144
142
|
switchPoint={switchPoint}
|
|
145
143
|
>
|
|
146
144
|
{children}
|
|
147
|
-
{additional}
|
|
148
145
|
</LayoutHeaderContent>
|
|
149
146
|
</div>
|
|
150
147
|
)
|
|
@@ -1,15 +1,17 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { useUp, usePrevUp, usePageContext } from '@graphcommerce/framer-next-pages'
|
|
2
2
|
import { t } from '@lingui/macro'
|
|
3
3
|
import PageLink from 'next/link'
|
|
4
|
+
import { useRouter } from 'next/router'
|
|
4
5
|
import React from 'react'
|
|
5
6
|
import Button, { ButtonProps } from '../../Button'
|
|
6
7
|
import SvgImageSimple from '../../SvgImage/SvgImageSimple'
|
|
7
8
|
import { iconChevronLeft } from '../../icons'
|
|
9
|
+
import { usePrevPageRouter } from '@graphcommerce/framer-next-pages/hooks/usePrevPageRouter'
|
|
8
10
|
|
|
9
11
|
export type BackProps = Omit<ButtonProps, 'onClick' | 'children'>
|
|
10
12
|
|
|
11
13
|
export function useShowBack() {
|
|
12
|
-
const router =
|
|
14
|
+
const router = useRouter()
|
|
13
15
|
const up = useUp()
|
|
14
16
|
const prevUp = usePrevUp()
|
|
15
17
|
const { backSteps } = usePageContext()
|
|
@@ -22,8 +24,9 @@ export function useShowBack() {
|
|
|
22
24
|
}
|
|
23
25
|
|
|
24
26
|
export default function LayoutHeaderBack(props: BackProps) {
|
|
25
|
-
const router =
|
|
27
|
+
const router = useRouter()
|
|
26
28
|
const up = useUp()
|
|
29
|
+
const prevRouter = usePrevPageRouter()
|
|
27
30
|
const prevUp = usePrevUp()
|
|
28
31
|
const { backSteps } = usePageContext()
|
|
29
32
|
|
|
@@ -31,7 +34,7 @@ export default function LayoutHeaderBack(props: BackProps) {
|
|
|
31
34
|
const canClickBack = backSteps > 0 && router.asPath !== prevUp?.href
|
|
32
35
|
|
|
33
36
|
if (canClickBack) {
|
|
34
|
-
const label = up?.href ===
|
|
37
|
+
const label = up?.href === prevRouter?.asPath ? up?.title : t`Back`
|
|
35
38
|
return (
|
|
36
39
|
<Button
|
|
37
40
|
onClick={() => router.back()}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { useGo, usePageContext } from '@graphcommerce/framer-next-pages'
|
|
2
2
|
import React from 'react'
|
|
3
3
|
import Button from '../../Button'
|
|
4
4
|
import SvgImageSimple from '../../SvgImage/SvgImageSimple'
|
|
@@ -10,15 +10,15 @@ export function useShowClose() {
|
|
|
10
10
|
}
|
|
11
11
|
|
|
12
12
|
export default function LayoutHeaderClose() {
|
|
13
|
-
const router = usePageRouter()
|
|
14
13
|
const { closeSteps } = usePageContext()
|
|
14
|
+
const onClick = useGo(closeSteps * -1)
|
|
15
15
|
|
|
16
16
|
return (
|
|
17
17
|
<Button
|
|
18
18
|
type='button'
|
|
19
|
-
onClick={
|
|
19
|
+
onClick={onClick}
|
|
20
20
|
aria-label='Close'
|
|
21
|
-
variant='
|
|
21
|
+
variant='text'
|
|
22
22
|
startIcon={<SvgImageSimple src={iconClose} />}
|
|
23
23
|
>
|
|
24
24
|
Close
|
|
@@ -25,6 +25,8 @@ const useStyles = makeStyles(
|
|
|
25
25
|
[theme.breakpoints.up('md')]: {
|
|
26
26
|
height: theme.appShell.appBarHeightMd,
|
|
27
27
|
},
|
|
28
|
+
borderTopLeftRadius: theme.shape.borderRadius * 3,
|
|
29
|
+
borderTopRightRadius: theme.shape.borderRadius * 3,
|
|
28
30
|
},
|
|
29
31
|
bgDivider: {
|
|
30
32
|
boxShadow: 'unset',
|
|
@@ -50,6 +52,7 @@ const useStyles = makeStyles(
|
|
|
50
52
|
gridTemplateAreas: `"left center right"`,
|
|
51
53
|
gridTemplateColumns: '1fr auto 1fr',
|
|
52
54
|
alignItems: 'center',
|
|
55
|
+
// columnGap: theme.spacings.xs,
|
|
53
56
|
|
|
54
57
|
height: theme.appShell.headerHeightSm,
|
|
55
58
|
[theme.breakpoints.up('md')]: {
|
|
@@ -104,7 +107,10 @@ const useStyles = makeStyles(
|
|
|
104
107
|
},
|
|
105
108
|
},
|
|
106
109
|
right: {
|
|
107
|
-
'& > *': {
|
|
110
|
+
'& > *': {
|
|
111
|
+
pointerEvents: 'all',
|
|
112
|
+
width: 'min-content',
|
|
113
|
+
},
|
|
108
114
|
display: 'grid',
|
|
109
115
|
gridAutoFlow: 'column',
|
|
110
116
|
gap: theme.spacings.sm,
|
|
@@ -168,7 +174,7 @@ export default function LayoutHeaderContent(props: ContentProps) {
|
|
|
168
174
|
<>
|
|
169
175
|
<div {...className('bg')} />
|
|
170
176
|
<div {...className('content')} ref={ref}>
|
|
171
|
-
<div {...className('left')}>{left}</div>
|
|
177
|
+
{left && <div {...className('left')}>{left}</div>}
|
|
172
178
|
<div {...className('center')}>{children}</div>
|
|
173
179
|
<div {...className('right')}>{right}</div>
|
|
174
180
|
{divider && <div {...className('divider')}>{divider}</div>}
|
|
@@ -20,11 +20,17 @@ const useStyles = makeStyles(
|
|
|
20
20
|
},
|
|
21
21
|
containerSizeSmall: {
|
|
22
22
|
flexFlow: 'unset',
|
|
23
|
+
overflow: 'hidden',
|
|
23
24
|
'& svg': {
|
|
24
25
|
width: responsiveVal(24, 28),
|
|
25
26
|
height: responsiveVal(24, 28),
|
|
26
27
|
strokeWidth: 1.4,
|
|
27
28
|
},
|
|
29
|
+
'& > *': {
|
|
30
|
+
overflow: 'hidden',
|
|
31
|
+
whiteSpace: 'nowrap',
|
|
32
|
+
textOverflow: 'ellipsis',
|
|
33
|
+
},
|
|
28
34
|
},
|
|
29
35
|
containerGutterTop: {
|
|
30
36
|
marginTop: theme.spacings.xl,
|
|
@@ -8,7 +8,7 @@ export type { LayoutOverlayVariant } from './LayoutOverlayBase'
|
|
|
8
8
|
export type LayoutOverlayProps = SetOptional<LayoutOverlayBaseProps, 'variantSm' | 'variantMd'>
|
|
9
9
|
|
|
10
10
|
export function LayoutOverlay(props: LayoutOverlayProps) {
|
|
11
|
-
const { children, variantSm = 'bottom', variantMd = 'right', classes } = props
|
|
11
|
+
const { children, variantSm = 'bottom', variantMd = 'right', classes, ...otherProps } = props
|
|
12
12
|
|
|
13
13
|
const scrollSnapTypeSm: ScrollSnapType =
|
|
14
14
|
variantSm === 'left' || variantSm === 'right' ? 'inline mandatory' : 'block proximity'
|
|
@@ -17,7 +17,12 @@ export function LayoutOverlay(props: LayoutOverlayProps) {
|
|
|
17
17
|
|
|
18
18
|
return (
|
|
19
19
|
<ScrollerProvider scrollSnapTypeSm={scrollSnapTypeSm} scrollSnapTypeMd={scrollSnapTypeMd}>
|
|
20
|
-
<LayoutOverlayBase
|
|
20
|
+
<LayoutOverlayBase
|
|
21
|
+
variantMd={variantMd}
|
|
22
|
+
variantSm={variantSm}
|
|
23
|
+
classes={classes}
|
|
24
|
+
{...otherProps}
|
|
25
|
+
>
|
|
21
26
|
{children}
|
|
22
27
|
</LayoutOverlayBase>
|
|
23
28
|
</ScrollerProvider>
|
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { useGo, usePageContext, useScrollOffset } from '@graphcommerce/framer-next-pages'
|
|
2
2
|
import { Scroller, useScrollerContext, useScrollTo } from '@graphcommerce/framer-scroller'
|
|
3
3
|
import { useElementScroll, useIsomorphicLayoutEffect } from '@graphcommerce/framer-utils'
|
|
4
|
-
import { makeStyles, Theme,
|
|
4
|
+
import { makeStyles, Theme, capitalize, styled } from '@material-ui/core'
|
|
5
5
|
import { m, useDomEvent, useMotionValue, usePresence, useTransform } from 'framer-motion'
|
|
6
6
|
import React, { useCallback, useEffect, useRef } from 'react'
|
|
7
7
|
import LayoutProvider from '../../Layout/components/LayoutProvider'
|
|
@@ -72,79 +72,20 @@ const useStyles = makeStyles(
|
|
|
72
72
|
height: '100vh',
|
|
73
73
|
},
|
|
74
74
|
},
|
|
75
|
-
beforeOverlay: {
|
|
76
|
-
gridArea: 'beforeOverlay',
|
|
77
|
-
scrollSnapAlign: 'start',
|
|
78
|
-
display: 'grid',
|
|
79
|
-
alignContent: 'end',
|
|
80
|
-
},
|
|
81
|
-
beforeOverlayVariantSmRight: {
|
|
82
|
-
[theme.breakpoints.down('sm')]: {
|
|
83
|
-
width: '100vw',
|
|
84
|
-
},
|
|
85
|
-
},
|
|
86
|
-
beforeOverlayVariantMdRight: {
|
|
87
|
-
[theme.breakpoints.up('md')]: {
|
|
88
|
-
width: '100vw',
|
|
89
|
-
},
|
|
90
|
-
},
|
|
91
75
|
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
width: '100vw',
|
|
95
|
-
},
|
|
96
|
-
},
|
|
97
|
-
beforeOverlayVariantMdLeft: {
|
|
98
|
-
[theme.breakpoints.up('md')]: {
|
|
99
|
-
width: '100vw',
|
|
100
|
-
},
|
|
101
|
-
},
|
|
76
|
+
// Overlay pane styles
|
|
77
|
+
overlayPane: {},
|
|
102
78
|
|
|
103
|
-
|
|
104
|
-
[theme.breakpoints.up('md')]: {
|
|
105
|
-
height: '100vh',
|
|
106
|
-
},
|
|
107
|
-
},
|
|
108
|
-
beforeOverlayVariantSmBottom: {
|
|
109
|
-
[theme.breakpoints.down('sm')]: {
|
|
110
|
-
height: '100vh',
|
|
111
|
-
'@supports (-webkit-touch-callout: none)': {
|
|
112
|
-
height: '-webkit-fill-available',
|
|
113
|
-
},
|
|
114
|
-
},
|
|
115
|
-
},
|
|
116
|
-
overlay: {
|
|
117
|
-
pointerEvents: 'none',
|
|
118
|
-
gridArea: 'overlay',
|
|
119
|
-
scrollSnapAlign: 'start',
|
|
120
|
-
minHeight: '100vh',
|
|
121
|
-
'@supports (-webkit-touch-callout: none)': {
|
|
122
|
-
minHeight: '-webkit-fill-available',
|
|
123
|
-
},
|
|
124
|
-
},
|
|
125
|
-
overlayVariantSmBottom: {
|
|
79
|
+
overlaySizeSmFloating: {
|
|
126
80
|
[theme.breakpoints.down('sm')]: {
|
|
127
|
-
|
|
128
|
-
paddingTop: `calc(${theme.appShell.headerHeightSm} * 0.5)`,
|
|
129
|
-
display: 'grid',
|
|
81
|
+
padding: `${theme.page.vertical} ${theme.page.horizontal}`,
|
|
130
82
|
},
|
|
131
83
|
},
|
|
132
|
-
|
|
84
|
+
overlaySizeMdFloating: {
|
|
133
85
|
[theme.breakpoints.up('md')]: {
|
|
134
|
-
|
|
135
|
-
paddingTop: `calc(${theme.appShell.headerHeightMd} + (${theme.appShell.appBarHeightMd} - ${theme.appShell.appBarInnerHeightMd}) * -0.5)`,
|
|
136
|
-
display: 'grid',
|
|
86
|
+
padding: `${theme.page.vertical} ${theme.page.horizontal}`,
|
|
137
87
|
},
|
|
138
88
|
},
|
|
139
|
-
overlayPane: {
|
|
140
|
-
pointerEvents: 'all',
|
|
141
|
-
backgroundColor: theme.palette.background.paper,
|
|
142
|
-
boxShadow: theme.shadows[24],
|
|
143
|
-
minWidth: 'min(800px, 90vw)',
|
|
144
|
-
scrollSnapAlign: 'end',
|
|
145
|
-
|
|
146
|
-
paddingBottom: 56,
|
|
147
|
-
},
|
|
148
89
|
overlayPaneVariantSmBottom: {
|
|
149
90
|
[theme.breakpoints.down('sm')]: {
|
|
150
91
|
borderTopLeftRadius: theme.shape.borderRadius * 3,
|
|
@@ -157,7 +98,17 @@ const useStyles = makeStyles(
|
|
|
157
98
|
borderTopRightRadius: theme.shape.borderRadius * 3,
|
|
158
99
|
},
|
|
159
100
|
},
|
|
160
|
-
|
|
101
|
+
overlayPaneSizeSmFloating: {
|
|
102
|
+
[theme.breakpoints.down('sm')]: {
|
|
103
|
+
borderRadius: theme.shape.borderRadius * 3,
|
|
104
|
+
},
|
|
105
|
+
},
|
|
106
|
+
overlayPaneSizeMdFloating: {
|
|
107
|
+
[theme.breakpoints.up('md')]: {
|
|
108
|
+
borderRadius: theme.shape.borderRadius * 3,
|
|
109
|
+
},
|
|
110
|
+
},
|
|
111
|
+
overlayPaneSmVariantSizeLeftFull: {
|
|
161
112
|
[theme.breakpoints.down('sm')]: {
|
|
162
113
|
paddingBottom: 1,
|
|
163
114
|
minHeight: '100vh',
|
|
@@ -166,7 +117,7 @@ const useStyles = makeStyles(
|
|
|
166
117
|
},
|
|
167
118
|
},
|
|
168
119
|
},
|
|
169
|
-
|
|
120
|
+
overlayPaneMdVariantSizeLeftFull: {
|
|
170
121
|
[theme.breakpoints.up('md')]: {
|
|
171
122
|
paddingBottom: 1,
|
|
172
123
|
minHeight: '100vh',
|
|
@@ -175,7 +126,7 @@ const useStyles = makeStyles(
|
|
|
175
126
|
},
|
|
176
127
|
},
|
|
177
128
|
},
|
|
178
|
-
|
|
129
|
+
overlayPaneSmVariantSizeRightFull: {
|
|
179
130
|
[theme.breakpoints.down('sm')]: {
|
|
180
131
|
paddingBottom: 1,
|
|
181
132
|
minHeight: '100vh',
|
|
@@ -184,7 +135,7 @@ const useStyles = makeStyles(
|
|
|
184
135
|
},
|
|
185
136
|
},
|
|
186
137
|
},
|
|
187
|
-
|
|
138
|
+
overlayPaneMdVariantSizeRightFull: {
|
|
188
139
|
[theme.breakpoints.up('md')]: {
|
|
189
140
|
paddingBottom: 1,
|
|
190
141
|
minHeight: '100vh',
|
|
@@ -213,33 +164,61 @@ const useStyles = makeStyles(
|
|
|
213
164
|
)
|
|
214
165
|
|
|
215
166
|
export type LayoutOverlayVariant = 'left' | 'bottom' | 'right'
|
|
167
|
+
export type LayoutOverlaySize = 'floating' | 'minimal' | 'full'
|
|
168
|
+
export type LayoutOverlayAlign = 'start' | 'end' | 'center' | 'stretch'
|
|
216
169
|
|
|
217
|
-
|
|
218
|
-
children?: React.ReactNode
|
|
170
|
+
type StyleProps = {
|
|
219
171
|
variantSm: LayoutOverlayVariant
|
|
220
172
|
variantMd: LayoutOverlayVariant
|
|
221
|
-
|
|
173
|
+
sizeSm?: LayoutOverlaySize
|
|
174
|
+
sizeMd?: LayoutOverlaySize
|
|
175
|
+
justifySm?: LayoutOverlayAlign
|
|
176
|
+
justifyMd?: LayoutOverlayAlign
|
|
177
|
+
}
|
|
222
178
|
|
|
223
|
-
export
|
|
179
|
+
export type LayoutOverlayBaseProps = {
|
|
180
|
+
children?: React.ReactNode
|
|
181
|
+
} & StyleProps &
|
|
182
|
+
UseStyles<typeof useStyles>
|
|
183
|
+
|
|
184
|
+
enum OverlayPosition {
|
|
224
185
|
UNOPENED = -1,
|
|
225
186
|
OPENED = 1,
|
|
226
187
|
CLOSED = 0,
|
|
227
188
|
}
|
|
228
189
|
|
|
229
190
|
export function LayoutOverlayBase(props: LayoutOverlayBaseProps) {
|
|
230
|
-
const {
|
|
231
|
-
|
|
191
|
+
const {
|
|
192
|
+
children,
|
|
193
|
+
variantSm,
|
|
194
|
+
variantMd,
|
|
195
|
+
classes: _classes,
|
|
196
|
+
sizeSm = 'full',
|
|
197
|
+
sizeMd = 'full',
|
|
198
|
+
justifySm = 'stretch',
|
|
199
|
+
justifyMd = 'stretch',
|
|
200
|
+
} = props
|
|
201
|
+
|
|
202
|
+
const { scrollerRef, snap } = useScrollerContext()
|
|
232
203
|
const positions = useOverlayPosition()
|
|
233
204
|
const scrollTo = useScrollTo()
|
|
234
205
|
const [isPresent, safeToRemove] = usePresence()
|
|
206
|
+
const beforeRef = useRef<HTMLDivElement>(null)
|
|
235
207
|
|
|
236
208
|
const { closeSteps, active, direction } = usePageContext()
|
|
237
|
-
const
|
|
209
|
+
const close = useGo(closeSteps * -1)
|
|
238
210
|
|
|
239
211
|
const position = useMotionValue<OverlayPosition>(OverlayPosition.UNOPENED)
|
|
240
212
|
|
|
241
|
-
const classes = useStyles(
|
|
242
|
-
const className = classesPicker(classes, {
|
|
213
|
+
const classes = useStyles({ classes: _classes, sizeSm, sizeMd, justifySm, justifyMd })
|
|
214
|
+
const className = classesPicker(classes, {
|
|
215
|
+
variantSm,
|
|
216
|
+
variantMd,
|
|
217
|
+
sizeSm,
|
|
218
|
+
sizeMd,
|
|
219
|
+
smVariantSize: `${variantSm}${capitalize(sizeSm)}`,
|
|
220
|
+
mdVariantSize: `${variantMd}${capitalize(sizeMd)}`,
|
|
221
|
+
})
|
|
243
222
|
|
|
244
223
|
const overlayRef = useRef<HTMLDivElement>(null)
|
|
245
224
|
|
|
@@ -286,7 +265,6 @@ export function LayoutOverlayBase(props: LayoutOverlayBaseProps) {
|
|
|
286
265
|
// When the overlay is closed by navigating away, we're closing the overlay.
|
|
287
266
|
useEffect(() => {
|
|
288
267
|
if (isPresent) return
|
|
289
|
-
|
|
290
268
|
position.set(OverlayPosition.CLOSED)
|
|
291
269
|
// eslint-disable-next-line @typescript-eslint/no-floating-promises
|
|
292
270
|
scrollTo({
|
|
@@ -299,9 +277,8 @@ export function LayoutOverlayBase(props: LayoutOverlayBaseProps) {
|
|
|
299
277
|
const closeOverlay = useCallback(() => {
|
|
300
278
|
if (position.get() !== OverlayPosition.OPENED) return
|
|
301
279
|
position.set(OverlayPosition.CLOSED)
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
}, [closeSteps, pageRouter, position])
|
|
280
|
+
close()
|
|
281
|
+
}, [close, position])
|
|
305
282
|
|
|
306
283
|
// Handle escape key
|
|
307
284
|
const windowRef = useRef(typeof window !== 'undefined' ? window : null)
|
|
@@ -331,25 +308,101 @@ export function LayoutOverlayBase(props: LayoutOverlayBaseProps) {
|
|
|
331
308
|
)
|
|
332
309
|
|
|
333
310
|
const onClickAway = useCallback(
|
|
334
|
-
(event: React.MouseEvent<
|
|
335
|
-
|
|
336
|
-
closeOverlay()
|
|
311
|
+
(event: React.MouseEvent<HTMLDivElement>) => {
|
|
312
|
+
const isTarget = event.target === scrollerRef.current || event.target === beforeRef.current
|
|
313
|
+
if (isTarget && snap.get()) closeOverlay()
|
|
337
314
|
},
|
|
338
|
-
[closeOverlay],
|
|
315
|
+
[closeOverlay, scrollerRef, snap],
|
|
316
|
+
)
|
|
317
|
+
|
|
318
|
+
const Overlay = styled('div')(
|
|
319
|
+
({ theme }) => ({
|
|
320
|
+
display: 'grid',
|
|
321
|
+
pointerEvents: 'none',
|
|
322
|
+
gridArea: 'overlay',
|
|
323
|
+
scrollSnapAlign: 'start',
|
|
324
|
+
|
|
325
|
+
[theme.breakpoints.down('sm')]: {
|
|
326
|
+
justifyContent: justifySm,
|
|
327
|
+
alignItems: justifySm,
|
|
328
|
+
|
|
329
|
+
...(variantSm === 'bottom' && {
|
|
330
|
+
marginTop: `calc(${theme.appShell.headerHeightSm} * 0.5 * -1)`,
|
|
331
|
+
paddingTop: `calc(${theme.appShell.headerHeightSm} * 0.5)`,
|
|
332
|
+
}),
|
|
333
|
+
},
|
|
334
|
+
[theme.breakpoints.up('md')]: {
|
|
335
|
+
justifyContent: justifyMd,
|
|
336
|
+
alignItems: justifyMd,
|
|
337
|
+
|
|
338
|
+
...(variantMd === 'bottom' && {
|
|
339
|
+
marginTop: `calc(${theme.appShell.headerHeightMd} + (${theme.appShell.appBarHeightMd} - ${theme.appShell.appBarInnerHeightMd}) * 0.5)`,
|
|
340
|
+
paddingTop: `calc(${theme.appShell.headerHeightMd} + (${theme.appShell.appBarHeightMd} - ${theme.appShell.appBarInnerHeightMd}) * -0.5)`,
|
|
341
|
+
display: 'grid',
|
|
342
|
+
}),
|
|
343
|
+
},
|
|
344
|
+
}),
|
|
345
|
+
{ name: 'Overlay' },
|
|
346
|
+
)
|
|
347
|
+
|
|
348
|
+
const OverlayPane = styled('div')(
|
|
349
|
+
({ theme }) => ({
|
|
350
|
+
pointerEvents: 'all',
|
|
351
|
+
backgroundColor: theme.palette.background.paper,
|
|
352
|
+
boxShadow: theme.shadows[24],
|
|
353
|
+
// scrollSnapAlign: 'end',
|
|
354
|
+
[theme.breakpoints.down('sm')]: {
|
|
355
|
+
minWidth: '80vw',
|
|
356
|
+
...((sizeSm === 'full' || sizeSm === 'minimal') && {
|
|
357
|
+
paddingBottom: 56,
|
|
358
|
+
}),
|
|
359
|
+
...(variantSm === 'bottom' && sizeSm === 'full' && { height: 'calc(100vh - 56px)' }),
|
|
360
|
+
},
|
|
361
|
+
[theme.breakpoints.up('md')]: {
|
|
362
|
+
...(variantMd === 'bottom' && sizeMd === 'full' && { height: '100vh' }),
|
|
363
|
+
|
|
364
|
+
...(sizeMd === 'full' && {
|
|
365
|
+
minWidth: 'max(600px, 50vw)',
|
|
366
|
+
}),
|
|
367
|
+
},
|
|
368
|
+
}),
|
|
369
|
+
{ name: 'OverlayPane' },
|
|
370
|
+
)
|
|
371
|
+
|
|
372
|
+
const BeforeOverlay = styled('div')(
|
|
373
|
+
({ theme }) => ({
|
|
374
|
+
gridArea: 'beforeOverlay',
|
|
375
|
+
scrollSnapAlign: 'start',
|
|
376
|
+
display: 'grid',
|
|
377
|
+
alignContent: 'end',
|
|
378
|
+
|
|
379
|
+
[theme.breakpoints.down('sm')]: {
|
|
380
|
+
...((variantSm === 'left' || variantSm === 'right') && { width: '100vw' }),
|
|
381
|
+
...(variantSm === 'bottom' && {
|
|
382
|
+
height: '100vh',
|
|
383
|
+
'@supports (-webkit-touch-callout: none)': {
|
|
384
|
+
height: '-webkit-fill-available',
|
|
385
|
+
},
|
|
386
|
+
}),
|
|
387
|
+
},
|
|
388
|
+
[theme.breakpoints.up('md')]: {
|
|
389
|
+
...((variantMd === 'left' || variantMd === 'right') && { width: '100vw' }),
|
|
390
|
+
...(variantSm === 'bottom' && { height: '100vh' }),
|
|
391
|
+
},
|
|
392
|
+
}),
|
|
393
|
+
{ name: 'BeforeOverlay' },
|
|
339
394
|
)
|
|
340
395
|
|
|
341
396
|
return (
|
|
342
397
|
<>
|
|
343
398
|
<m.div {...className('backdrop')} style={{ opacity: positions.open.visible }} />
|
|
344
|
-
<Scroller {...className('root')} grid={false} hideScrollbar>
|
|
345
|
-
<
|
|
346
|
-
<
|
|
347
|
-
<
|
|
348
|
-
<
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
</ClickAwayListener>
|
|
352
|
-
</div>
|
|
399
|
+
<Scroller {...className('root')} grid={false} hideScrollbar onClick={onClickAway}>
|
|
400
|
+
<BeforeOverlay onClick={onClickAway} ref={beforeRef} />
|
|
401
|
+
<Overlay {...className('overlay')} ref={overlayRef}>
|
|
402
|
+
<OverlayPane {...className('overlayPane')}>
|
|
403
|
+
<LayoutProvider scroll={scrollWithoffset}>{children}</LayoutProvider>
|
|
404
|
+
</OverlayPane>
|
|
405
|
+
</Overlay>
|
|
353
406
|
</Scroller>
|
|
354
407
|
</>
|
|
355
408
|
)
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
import { ParsedUrlQuery } from 'querystring'
|
|
2
|
+
import { useRouter } from 'next/router'
|
|
3
|
+
import { useCallback } from 'react'
|
|
4
|
+
import { LayoutOverlay, LayoutOverlayProps } from '../components/LayoutOverlay'
|
|
5
|
+
|
|
6
|
+
export type LayoutOverlayState = Omit<LayoutOverlayProps, 'children' | 'classes'>
|
|
7
|
+
|
|
8
|
+
function useQueryState<T extends ParsedUrlQuery>(builder: (query: T) => T) {
|
|
9
|
+
const { query, replace } = useRouter()
|
|
10
|
+
const queryState = builder(query as T)
|
|
11
|
+
|
|
12
|
+
const setRouterQuery = (partialQuery: T) => {
|
|
13
|
+
// eslint-disable-next-line @typescript-eslint/no-floating-promises
|
|
14
|
+
replace({ query: { ...queryState, ...partialQuery } }, undefined, { shallow: true })
|
|
15
|
+
}
|
|
16
|
+
return [queryState, setRouterQuery] as const
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
export function useLayoutState() {
|
|
20
|
+
const [routerQuery, setRouterQuery] = useQueryState<LayoutOverlayState>(
|
|
21
|
+
useCallback(
|
|
22
|
+
({ sizeMd, sizeSm, justifyMd, justifySm, variantMd, variantSm }) => ({
|
|
23
|
+
sizeMd,
|
|
24
|
+
sizeSm,
|
|
25
|
+
justifyMd,
|
|
26
|
+
justifySm,
|
|
27
|
+
variantMd,
|
|
28
|
+
variantSm,
|
|
29
|
+
}),
|
|
30
|
+
[],
|
|
31
|
+
),
|
|
32
|
+
)
|
|
33
|
+
|
|
34
|
+
return [routerQuery, setRouterQuery] as const
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
export function LayoutOverlayDemo({ children }: { children?: React.ReactNode }) {
|
|
38
|
+
const [layout] = useLayoutState()
|
|
39
|
+
|
|
40
|
+
return <LayoutOverlay {...layout}>{children}</LayoutOverlay>
|
|
41
|
+
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@graphcommerce/next-ui",
|
|
3
|
-
"version": "3.
|
|
3
|
+
"version": "3.22.0",
|
|
4
4
|
"author": "",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"scripts": {
|
|
@@ -10,11 +10,11 @@
|
|
|
10
10
|
},
|
|
11
11
|
"dependencies": {
|
|
12
12
|
"@apollo/client": "^3.5.6",
|
|
13
|
-
"@graphcommerce/framer-next-pages": "^2.
|
|
14
|
-
"@graphcommerce/framer-scroller": "^1.
|
|
15
|
-
"@graphcommerce/framer-utils": "^2.103.
|
|
16
|
-
"@graphcommerce/graphql": "^2.105.
|
|
17
|
-
"@graphcommerce/image": "^2.105.
|
|
13
|
+
"@graphcommerce/framer-next-pages": "^2.109.0",
|
|
14
|
+
"@graphcommerce/framer-scroller": "^1.2.0",
|
|
15
|
+
"@graphcommerce/framer-utils": "^2.103.21",
|
|
16
|
+
"@graphcommerce/graphql": "^2.105.13",
|
|
17
|
+
"@graphcommerce/image": "^2.105.12",
|
|
18
18
|
"@lingui/macro": "^3.13.0",
|
|
19
19
|
"@material-ui/core": "^4.12.3",
|
|
20
20
|
"@material-ui/lab": "^4.0.0-alpha.60",
|
|
@@ -33,7 +33,7 @@
|
|
|
33
33
|
},
|
|
34
34
|
"devDependencies": {
|
|
35
35
|
"@graphcommerce/browserslist-config-pwa": "^3.0.3",
|
|
36
|
-
"@graphcommerce/eslint-config-pwa": "^3.1.
|
|
36
|
+
"@graphcommerce/eslint-config-pwa": "^3.1.10",
|
|
37
37
|
"@graphcommerce/prettier-config-pwa": "^3.0.5",
|
|
38
38
|
"@graphcommerce/typescript-config-pwa": "^3.1.2",
|
|
39
39
|
"@playwright/test": "^1.17.1",
|
|
@@ -52,5 +52,5 @@
|
|
|
52
52
|
"project": "./tsconfig.json"
|
|
53
53
|
}
|
|
54
54
|
},
|
|
55
|
-
"gitHead": "
|
|
55
|
+
"gitHead": "bc5423d7547f8685db4cd8fc6d8f7a2a51ebed05"
|
|
56
56
|
}
|