@graphcommerce/next-ui 3.21.13 → 3.22.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.
@@ -1,5 +1,4 @@
1
1
  import { Container, makeStyles, Theme } from '@material-ui/core'
2
- import clsx from 'clsx'
3
2
  import React from 'react'
4
3
  import { UseStyles } from '../../Styles'
5
4
 
@@ -7,22 +6,18 @@ const useStyles = makeStyles(
7
6
  (theme: Theme) => ({
8
7
  root: {
9
8
  position: 'sticky',
9
+ top: theme.appShell.headerHeightSm,
10
10
  zIndex: 96,
11
- },
12
- fillMobileOnly: {
13
11
  [theme.breakpoints.up('md')]: {
14
12
  top: `${theme.page.vertical} !important`,
15
13
  },
16
14
  },
17
15
  }),
18
- {
19
- name: 'AppShellSticky',
20
- },
16
+ { name: 'AppShellSticky' },
21
17
  )
22
18
 
23
19
  type AppShellStickyBaseProps = {
24
20
  children: React.ReactNode
25
- headerFill?: 'mobile-only' | 'both'
26
21
  }
27
22
 
28
23
  type AppShellStickyProps = AppShellStickyBaseProps & UseStyles<typeof useStyles>
@@ -32,18 +27,11 @@ type AppShellStickyProps = AppShellStickyBaseProps & UseStyles<typeof useStyles>
32
27
  - determines top offset based on header height dynamically
33
28
  */
34
29
  export default function AppShellSticky(props: AppShellStickyProps) {
35
- const { children, headerFill = 'both' } = props
30
+ const { children } = props
36
31
  const classes = useStyles(props)
37
32
 
38
- // todo
39
- const top = 0
40
-
41
33
  return (
42
- <Container
43
- maxWidth={false}
44
- className={clsx(classes.root, headerFill === 'mobile-only' && classes.fillMobileOnly)}
45
- style={{ top }}
46
- >
34
+ <Container maxWidth={false} className={classes.root}>
47
35
  <>{children}</>
48
36
  </Container>
49
37
  )
@@ -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 = usePageRouter()
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 = usePageRouter()
32
+ const router = useRouter()
33
33
  const classes = useStyles(props)
34
34
 
35
35
  return router.asPath === '/' ? (
package/CHANGELOG.md CHANGED
@@ -3,6 +3,47 @@
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.1](https://github.com/ho-nl/m2-pwa/compare/@graphcommerce/next-ui@3.22.0...@graphcommerce/next-ui@3.22.1) (2022-01-04)
7
+
8
+
9
+ ### Bug Fixes
10
+
11
+ * overlay would have a height instead of minHeight ([07dba4b](https://github.com/ho-nl/m2-pwa/commit/07dba4b875a37beac2ab6a8afe50e6b7a7ba1bf9))
12
+
13
+
14
+
15
+
16
+
17
+ # [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)
18
+
19
+
20
+ ### Bug Fixes
21
+
22
+ * backbutton had wrong label ([c6d0b27](https://github.com/ho-nl/m2-pwa/commit/c6d0b2738e5de734af40bc632177dcc867e8e556))
23
+ * make sure we're able to close the overlay ([8d19fde](https://github.com/ho-nl/m2-pwa/commit/8d19fde07d51493acfdfaa97a19f61246d04d42a))
24
+
25
+
26
+ ### Features
27
+
28
+ * add support for minimal overlay size ([96e508a](https://github.com/ho-nl/m2-pwa/commit/96e508a94e23fe5b3ec523cddeb19b7b70f50034))
29
+ * added support for more positioning options for the overlay ([79eae9e](https://github.com/ho-nl/m2-pwa/commit/79eae9eb39513f5611103c4c745c3db99b11f15a))
30
+ * **framer-next-pages:** reduce rerenders when navigating to a new page ([5cf3301](https://github.com/ho-nl/m2-pwa/commit/5cf330130bb3527057da015e3c4a6fa295d7262e))
31
+
32
+
33
+
34
+
35
+
36
+ ## [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)
37
+
38
+
39
+ ### Bug Fixes
40
+
41
+ * make sure the filters are aligned properly on mobile ([4bfe978](https://github.com/ho-nl/m2-pwa/commit/4bfe978f095c1b9867608c138eccf3227b18d4e9))
42
+
43
+
44
+
45
+
46
+
6
47
  ## [3.21.13](https://github.com/ho-nl/m2-pwa/compare/@graphcommerce/next-ui@3.21.12...@graphcommerce/next-ui@3.21.13) (2021-12-23)
7
48
 
8
49
 
@@ -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 = usePageRouter()
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, additional, divider, primary, secondary, noAlign, switchPoint } = props
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 (!left) left = close
122
- else if (!right) right = close
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 { usePageRouter, useUp, usePrevUp, usePageContext } from '@graphcommerce/framer-next-pages'
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 = usePageRouter()
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 = usePageRouter()
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 === router.asPath ? up.title : t`Back`
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 { usePageRouter, usePageContext } from '@graphcommerce/framer-next-pages'
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={() => router.go(closeSteps * -1)}
19
+ onClick={onClick}
20
20
  aria-label='Close'
21
- variant='pill-link'
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
- '& > *': { pointerEvents: 'all' },
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 variantMd={variantMd} variantSm={variantSm} classes={classes}>
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 { usePageContext, usePageRouter, useScrollOffset } from '@graphcommerce/framer-next-pages'
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, ClickAwayListener } from '@material-ui/core'
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
- beforeOverlayVariantSmLeft: {
93
- [theme.breakpoints.down('sm')]: {
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
- beforeOverlayVariantMdBottom: {
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
- marginTop: `calc(${theme.appShell.headerHeightSm} * 0.5 * -1)`,
128
- paddingTop: `calc(${theme.appShell.headerHeightSm} * 0.5)`,
129
- display: 'grid',
81
+ padding: `${theme.page.vertical} ${theme.page.horizontal}`,
130
82
  },
131
83
  },
132
- overlayVariantMdBottom: {
84
+ overlaySizeMdFloating: {
133
85
  [theme.breakpoints.up('md')]: {
134
- marginTop: `calc(${theme.appShell.headerHeightMd} + (${theme.appShell.appBarHeightMd} - ${theme.appShell.appBarInnerHeightMd}) * 0.5)`,
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
- overlayPaneVariantSmLeft: {
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
- overlayPaneVariantMdLeft: {
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
- overlayPaneVariantSmRight: {
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
- overlayPaneVariantMdRight: {
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
- export type LayoutOverlayBaseProps = {
218
- children?: React.ReactNode
170
+ type StyleProps = {
219
171
  variantSm: LayoutOverlayVariant
220
172
  variantMd: LayoutOverlayVariant
221
- } & UseStyles<typeof useStyles>
173
+ sizeSm?: LayoutOverlaySize
174
+ sizeMd?: LayoutOverlaySize
175
+ justifySm?: LayoutOverlayAlign
176
+ justifyMd?: LayoutOverlayAlign
177
+ }
222
178
 
223
- export enum OverlayPosition {
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 { children, variantSm, variantMd } = props
231
- const { scrollerRef } = useScrollerContext()
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 pageRouter = usePageRouter()
209
+ const close = useGo(closeSteps * -1)
238
210
 
239
211
  const position = useMotionValue<OverlayPosition>(OverlayPosition.UNOPENED)
240
212
 
241
- const classes = useStyles(props)
242
- const className = classesPicker(classes, { variantSm, variantMd })
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
- // eslint-disable-next-line @typescript-eslint/no-floating-promises
303
- pageRouter.go(closeSteps * -1)
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,96 @@ export function LayoutOverlayBase(props: LayoutOverlayBaseProps) {
331
308
  )
332
309
 
333
310
  const onClickAway = useCallback(
334
- (event: React.MouseEvent<Document>) => {
335
- if (event.target === document.body && event.type === 'click') return
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') && { paddingBottom: 56 }),
357
+ ...(variantSm === 'bottom' && sizeSm === 'full' && { minHeight: 'calc(100vh - 56px)' }),
358
+ },
359
+ [theme.breakpoints.up('md')]: {
360
+ ...(variantMd === 'bottom' && sizeMd === 'full' && { minHeight: '100vh' }),
361
+ ...(sizeMd === 'full' && { minWidth: 'max(600px, 50vw)' }),
362
+ },
363
+ }),
364
+ { name: 'OverlayPane' },
365
+ )
366
+
367
+ const BeforeOverlay = styled('div')(
368
+ ({ theme }) => ({
369
+ gridArea: 'beforeOverlay',
370
+ scrollSnapAlign: 'start',
371
+ display: 'grid',
372
+ alignContent: 'end',
373
+
374
+ [theme.breakpoints.down('sm')]: {
375
+ ...((variantSm === 'left' || variantSm === 'right') && { width: '100vw' }),
376
+ ...(variantSm === 'bottom' && {
377
+ height: '100vh',
378
+ '@supports (-webkit-touch-callout: none)': {
379
+ height: '-webkit-fill-available',
380
+ },
381
+ }),
382
+ },
383
+ [theme.breakpoints.up('md')]: {
384
+ ...((variantMd === 'left' || variantMd === 'right') && { width: '100vw' }),
385
+ ...(variantSm === 'bottom' && { height: '100vh' }),
386
+ },
387
+ }),
388
+ { name: 'BeforeOverlay' },
339
389
  )
340
390
 
341
391
  return (
342
392
  <>
343
393
  <m.div {...className('backdrop')} style={{ opacity: positions.open.visible }} />
344
- <Scroller {...className('root')} grid={false} hideScrollbar>
345
- <div {...className('beforeOverlay')} />
346
- <div {...className('overlay')} ref={overlayRef}>
347
- <ClickAwayListener onClickAway={onClickAway}>
348
- <div {...className('overlayPane')}>
349
- <LayoutProvider scroll={scrollWithoffset}>{children}</LayoutProvider>
350
- </div>
351
- </ClickAwayListener>
352
- </div>
394
+ <Scroller {...className('root')} grid={false} hideScrollbar onClick={onClickAway}>
395
+ <BeforeOverlay onClick={onClickAway} ref={beforeRef} />
396
+ <Overlay {...className('overlay')} ref={overlayRef}>
397
+ <OverlayPane {...className('overlayPane')}>
398
+ <LayoutProvider scroll={scrollWithoffset}>{children}</LayoutProvider>
399
+ </OverlayPane>
400
+ </Overlay>
353
401
  </Scroller>
354
402
  </>
355
403
  )
@@ -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.21.13",
3
+ "version": "3.22.1",
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.108.9",
14
- "@graphcommerce/framer-scroller": "^1.1.23",
15
- "@graphcommerce/framer-utils": "^2.103.20",
16
- "@graphcommerce/graphql": "^2.105.12",
17
- "@graphcommerce/image": "^2.105.11",
13
+ "@graphcommerce/framer-next-pages": "^2.109.1",
14
+ "@graphcommerce/framer-scroller": "^1.2.1",
15
+ "@graphcommerce/framer-utils": "^2.103.21",
16
+ "@graphcommerce/graphql": "^2.105.13",
17
+ "@graphcommerce/image": "^2.105.13",
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",
@@ -25,7 +25,6 @@
25
25
  "next": "^12.0.7",
26
26
  "react": "^17.0.2",
27
27
  "react-dom": "^17.0.2",
28
- "react-focus-lock": "^2.7.1",
29
28
  "react-is": "^17.0.2",
30
29
  "react-schemaorg": "^2.0.0",
31
30
  "schema-dts": "^1.0.0",
@@ -33,7 +32,7 @@
33
32
  },
34
33
  "devDependencies": {
35
34
  "@graphcommerce/browserslist-config-pwa": "^3.0.3",
36
- "@graphcommerce/eslint-config-pwa": "^3.1.9",
35
+ "@graphcommerce/eslint-config-pwa": "^3.1.10",
37
36
  "@graphcommerce/prettier-config-pwa": "^3.0.5",
38
37
  "@graphcommerce/typescript-config-pwa": "^3.1.2",
39
38
  "@playwright/test": "^1.17.1",
@@ -52,5 +51,5 @@
52
51
  "project": "./tsconfig.json"
53
52
  }
54
53
  },
55
- "gitHead": "2c255f0b276983c31b7c727743f93c1ae558b4c5"
54
+ "gitHead": "ddea6bd034cb06864b33fc4d8af9a3b5dad1c914"
56
55
  }