@graphcommerce/next-ui 3.18.1 → 3.20.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.
Files changed (97) hide show
  1. package/AppShell/AppShellSticky/index.tsx +3 -19
  2. package/AppShell/DesktopNavActions.tsx +3 -4
  3. package/AppShell/DesktopNavBar.tsx +4 -4
  4. package/AppShell/FixedFab.tsx +1 -6
  5. package/AppShell/GlobalHead.tsx +36 -0
  6. package/AppShell/Logo.tsx +11 -20
  7. package/AppShell/MenuFab.tsx +19 -8
  8. package/AppShell/MenuFabSecondaryItem.tsx +3 -3
  9. package/AppShell/PlaceholderFab/index.tsx +8 -27
  10. package/AppShell/index.tsx +19 -0
  11. package/AppShell/useFabAnimation.tsx +3 -2
  12. package/AppShell/useFixedFabAnimation.tsx +5 -5
  13. package/Blog/BlogAuthor/index.tsx +10 -6
  14. package/Blog/BlogHeader/index.tsx +7 -3
  15. package/Blog/BlogList/index.tsx +1 -1
  16. package/Blog/BlogListItem/index.tsx +2 -1
  17. package/Blog/BlogTitle/index.tsx +5 -5
  18. package/Button/index.tsx +27 -22
  19. package/ButtonLink/index.tsx +1 -1
  20. package/CHANGELOG.md +73 -0
  21. package/ChipMenu/index.tsx +2 -2
  22. package/FlagAvatar/index.tsx +3 -3
  23. package/{AppShell/Footer/index.tsx → Footer/Footer.tsx} +4 -4
  24. package/{AppShell/Footer → Footer}/SocialIcon.tsx +3 -3
  25. package/Footer/index.ts +2 -0
  26. package/Form/InputCheckmark.tsx +3 -3
  27. package/Form/index.tsx +8 -3
  28. package/FramerScroller/components/SidebarGallery.tsx +25 -21
  29. package/FramerScroller/components/SidebarSlider.tsx +2 -6
  30. package/FullPageMessage/index.tsx +1 -1
  31. package/IconHeader/index.tsx +2 -15
  32. package/Layout/components/LayoutHeader.tsx +151 -0
  33. package/Layout/components/LayoutHeaderBack.tsx +50 -0
  34. package/Layout/components/LayoutHeaderClose.tsx +27 -0
  35. package/Layout/components/LayoutHeaderContent.tsx +173 -0
  36. package/Layout/components/LayoutHeadertypes.ts +10 -0
  37. package/Layout/components/LayoutProvider.tsx +17 -0
  38. package/{Title/index.tsx → Layout/components/LayoutTitle.tsx} +24 -15
  39. package/Layout/context/layoutContext.tsx +7 -0
  40. package/Layout/hooks/useScrollY.tsx +6 -0
  41. package/Layout/index.ts +5 -0
  42. package/Layout/types.ts +5 -0
  43. package/LayoutDefault/components/LayoutDefault.tsx +90 -0
  44. package/LayoutDefault/index.ts +1 -0
  45. package/LayoutOverlay/components/LayoutOverlay.tsx +25 -0
  46. package/LayoutOverlay/components/LayoutOverlayBase.tsx +354 -0
  47. package/LayoutOverlay/components/LayoutOverlayHeader.tsx +5 -0
  48. package/LayoutOverlay/hooks/useOverlayPosition.ts +70 -0
  49. package/LayoutOverlay/index.ts +2 -0
  50. package/Page/App.tsx +2 -0
  51. package/PageMeta/index.tsx +3 -0
  52. package/Pagination/index.tsx +0 -1
  53. package/Row/ButtonLinkList/index.tsx +1 -1
  54. package/Row/ColumnOneBoxed/index.tsx +1 -1
  55. package/Row/ColumnTwoWithTop/index.tsx +3 -3
  56. package/Row/ContentLinks/index.tsx +3 -3
  57. package/Row/HeroBanner/index.tsx +28 -21
  58. package/Row/IconBlocks/index.tsx +1 -1
  59. package/Row/ImageText/index.tsx +12 -5
  60. package/Row/ImageTextBoxed/index.tsx +3 -1
  61. package/Row/ParagraphWithSidebarSlide/index.tsx +2 -0
  62. package/Row/SpecialBanner/index.tsx +11 -7
  63. package/Row/index.tsx +1 -1
  64. package/Snackbar/MessageSnackbarImpl.tsx +2 -1
  65. package/StarRatingField/index.tsx +3 -4
  66. package/Stepper/Stepper.tsx +1 -1
  67. package/Styles/breakpointVal.tsx +22 -0
  68. package/Styles/classesPicker.ts +41 -0
  69. package/Styles/responsiveVal.tsx +1 -1
  70. package/SvgImage/SvgImageSimple.tsx +14 -11
  71. package/SvgImage/index.tsx +9 -11
  72. package/TextInputNumber/index.tsx +3 -4
  73. package/Theme/types.ts +14 -12
  74. package/ToggleButton/index.tsx +6 -13
  75. package/UspList/UspListItem.tsx +4 -2
  76. package/icons/index.tsx +2 -0
  77. package/index.ts +9 -42
  78. package/package.json +8 -9
  79. package/AppShell/AppShellHeader/appShellHeaderContext.tsx +0 -11
  80. package/AppShell/AppShellHeader/index.tsx +0 -438
  81. package/AppShell/AppShellHeader/useAppShellHeaderContext.tsx +0 -6
  82. package/AppShell/AppShellProvider/index.tsx +0 -18
  83. package/AppShell/AppShellTitle/index.tsx +0 -45
  84. package/AppShell/ForwardButton.tsx +0 -53
  85. package/AppShell/FullPageShellBase.tsx +0 -82
  86. package/AppShell/MinimalPageShellBase.tsx +0 -22
  87. package/AppShell/PageShellHeader/index.tsx +0 -14
  88. package/AppShell/SheetShellBase/index.tsx +0 -114
  89. package/AppShell/SheetShellBase/useSheetStyles.ts +0 -18
  90. package/AppShell/SheetShellDragIndicator/index.tsx +0 -55
  91. package/AppShell/SheetShellHeader/index.tsx +0 -28
  92. package/AppShell/ShellBase.tsx +0 -45
  93. package/Debug/DebugSpacer.tsx +0 -51
  94. package/FramerNextPagesSlider/Slide.tsx +0 -71
  95. package/FramerNextPagesSlider/Slider.tsx +0 -39
  96. package/FramerNextPagesSlider/index.ts +0 -1
  97. package/FramerNextPagesSlider/types.ts +0 -3
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@graphcommerce/next-ui",
3
- "version": "3.18.1",
3
+ "version": "3.20.0",
4
4
  "author": "",
5
5
  "license": "MIT",
6
6
  "scripts": {
@@ -10,12 +10,11 @@
10
10
  },
11
11
  "dependencies": {
12
12
  "@apollo/client": "^3.4.16",
13
- "@graphcommerce/framer-next-pages": "^2.107.5",
14
- "@graphcommerce/framer-scroller": "^1.0.4",
15
- "@graphcommerce/framer-sheet": "^2.106.2",
16
- "@graphcommerce/framer-utils": "^2.103.15",
17
- "@graphcommerce/graphql": "^2.105.5",
18
- "@graphcommerce/image": "^2.105.4",
13
+ "@graphcommerce/framer-next-pages": "^2.108.0",
14
+ "@graphcommerce/framer-scroller": "^1.1.0",
15
+ "@graphcommerce/framer-utils": "^2.103.16",
16
+ "@graphcommerce/graphql": "^2.105.6",
17
+ "@graphcommerce/image": "^2.105.5",
19
18
  "@lingui/macro": "^3.12.1",
20
19
  "@material-ui/core": "^4.12.3",
21
20
  "@material-ui/lab": "^4.0.0-alpha.60",
@@ -34,7 +33,7 @@
34
33
  },
35
34
  "devDependencies": {
36
35
  "@graphcommerce/browserslist-config-pwa": "^3.0.2",
37
- "@graphcommerce/eslint-config-pwa": "^3.1.5",
36
+ "@graphcommerce/eslint-config-pwa": "^3.1.6",
38
37
  "@graphcommerce/prettier-config-pwa": "^3.0.4",
39
38
  "@graphcommerce/typescript-config-pwa": "^3.1.1",
40
39
  "@playwright/test": "^1.16.2",
@@ -53,5 +52,5 @@
53
52
  "project": "./tsconfig.json"
54
53
  }
55
54
  },
56
- "gitHead": "5ed153aa2213be8363138c0956872fe2fde2f590"
55
+ "gitHead": "8f156415c7f5a963e363f0d6d18fe5d6bbd5dba2"
57
56
  }
@@ -1,11 +0,0 @@
1
- import React from 'react'
2
-
3
- export type AppShellHeaderContext = {
4
- titleRef: React.RefObject<HTMLDivElement>
5
- contentHeaderRef: React.RefObject<HTMLDivElement>
6
- }
7
-
8
- const appShellHeaderContext = React.createContext(undefined as unknown as AppShellHeaderContext)
9
- appShellHeaderContext.displayName = 'appShellHeaderContext'
10
-
11
- export default appShellHeaderContext
@@ -1,438 +0,0 @@
1
- import { usePageContext, usePageRouter, usePrevUp, useUp } from '@graphcommerce/framer-next-pages'
2
- import { Fab, makeStyles, Theme } from '@material-ui/core'
3
- import clsx from 'clsx'
4
- import { m, MotionValue, useMotionValue, useTransform } from 'framer-motion'
5
- import PageLink from 'next/link'
6
- import React, { useCallback, useEffect } from 'react'
7
- import Button from '../../Button'
8
- import { UseStyles } from '../../Styles'
9
- import SvgImageSimple from '../../SvgImage/SvgImageSimple'
10
- import { iconChevronLeft, iconClose } from '../../icons'
11
- import useAppShellHeaderContext from './useAppShellHeaderContext'
12
-
13
- export type AppShellHeaderProps = {
14
- children?: React.ReactNode
15
- primary?: React.ReactNode
16
- secondary?: React.ReactNode
17
- divider?: React.ReactNode
18
- /* When a logo is given, children should be given too */
19
- logo?: React.ReactNode
20
- scrollY: MotionValue<number>
21
- hideClose?: boolean
22
- scrolled?: boolean
23
- dragIndicator?: React.ReactNode
24
- additional?: React.ReactNode
25
- fill?: 'both' | 'mobile-only'
26
- sheet?: boolean
27
- } & UseStyles<typeof useStyles>
28
-
29
- // minHeight: x
30
- // to reserve space for back & primary buttons,
31
- // even when there is no app shell header on scroll (e.g. on full page shell)
32
- const minHeight = 40
33
- const useStyles = makeStyles(
34
- (theme: Theme) => ({
35
- divider: {
36
- borderBottom: `1px solid ${theme.palette.divider}`,
37
- },
38
- dividerSpacer: {
39
- minHeight: 1,
40
- },
41
- dividerSheetShell: {
42
- marginTop: `calc((${theme.page.headerInnerHeight.md} * 0.15))`,
43
- },
44
- sheetHeaderContainer: {
45
- position: 'sticky',
46
- top: 0,
47
- zIndex: 98,
48
- // reserve space in the container even without any buttons added
49
- minHeight: 58,
50
- },
51
- sheetHeaderContainerSheetShell: {
52
- marginBottom: `calc((${theme.page.headerInnerHeight.md} * 0.15) * -1)`,
53
- },
54
- sheetHeader: {
55
- background: theme.palette.background.default,
56
- paddingTop: 8,
57
- paddingBottom: 8,
58
- minHeight,
59
- [theme.breakpoints.up('md')]: {
60
- minHeight: `calc(${minHeight}px + ${theme.spacings.xxs} * 2)`,
61
- paddingTop: theme.spacings.xxs,
62
- paddingBottom: theme.spacings.xxs,
63
- },
64
- },
65
- sheetHeaderSheetShell: {
66
- // The bottom sheets offset top is x% short compared to the page headers height,
67
- // so we add x% of the header height to padding top of bottomsheet actions bar
68
- // to keep consistency between app shell buttons.
69
- paddingTop: `calc(${theme.spacings.xxs} + (${theme.page.headerInnerHeight.md} * 0.15))`,
70
- paddingBottom: `calc(${theme.spacings.xxs} + (${theme.page.headerInnerHeight.md} * 0.15))`,
71
- [theme.breakpoints.down('sm')]: {
72
- paddingTop: 8,
73
- paddingBottom: 8,
74
- },
75
- },
76
- sheetHeaderScrolled: {
77
- [theme.breakpoints.up('md')]: {
78
- marginTop: -60,
79
- },
80
- },
81
- sheetHeaderActions: {
82
- display: 'grid',
83
- gridTemplateColumns: `1fr auto 1fr`,
84
- gridAutoFlow: 'column',
85
- alignItems: 'center',
86
- justifyContent: 'space-between',
87
- padding: `0 calc(${theme.page.horizontal} + 2px) 0`,
88
- width: '100%',
89
- minHeight,
90
- [theme.breakpoints.up('md')]: {
91
- '& * > a, & * > button': {
92
- height: minHeight,
93
- },
94
- },
95
- [theme.breakpoints.down('sm')]: {
96
- '& div > .MuiFab-sizeSmall': {
97
- marginLeft: -8,
98
- marginRight: -8,
99
- },
100
- '& div > .MuiButtonBase-root': {
101
- minWidth: 'unset',
102
- marginRight: -8,
103
- marginLeft: -8,
104
- },
105
- },
106
- },
107
- sheetHeaderActionRight: {
108
- justifySelf: 'flex-end',
109
- '& > .Mui-disabled': {
110
- // color: `${theme.palette.primary.contrastText} !important`,
111
- [theme.breakpoints.up('sm')]: {
112
- opacity: 0.25,
113
- color: `${theme.palette.secondary.contrastText} !important`,
114
- '& svg': {
115
- stroke: `${theme.palette.secondary.contrastText} !important`,
116
- },
117
- },
118
- },
119
- },
120
- sheetHeaderNoTitle: {
121
- pointerEvents: 'none',
122
- background: 'transparent',
123
- },
124
- sheetHeaderNoTitleFillMobileOnly: {
125
- [theme.breakpoints.up('md')]: {
126
- pointerEvents: 'none',
127
- background: 'transparent',
128
- top: 98,
129
- },
130
- },
131
- sheetHeaderFillMobileOnly: {
132
- [theme.breakpoints.up('md')]: {
133
- pointerEvents: 'none',
134
- position: 'fixed',
135
- },
136
- },
137
- innerContainer: {
138
- display: 'grid',
139
- textAlign: 'center',
140
- pointerEvents: 'all',
141
- },
142
- fab: {
143
- maxWidth: 38,
144
- maxHeight: 38,
145
- [theme.breakpoints.down('sm')]: {
146
- boxShadow: 'none',
147
- },
148
- },
149
- childs: {
150
- marginLeft: 12,
151
- marginRight: 12,
152
- whiteSpace: 'nowrap',
153
- overflow: 'hidden',
154
- textOverflow: 'ellipsis',
155
- },
156
- fillMobileOnly: {
157
- [theme.breakpoints.up('md')]: {
158
- display: 'none',
159
- },
160
- },
161
- dividerFillMobileOnly: {
162
- [theme.breakpoints.up('md')]: {
163
- visibility: 'hidden',
164
- },
165
- },
166
- logoContainer: {
167
- position: 'absolute',
168
- top: 0,
169
- left: 0,
170
- right: 0,
171
- paddingTop: 8,
172
- paddingBottom: 8,
173
- },
174
- logoInnerContainer: {
175
- minHeight,
176
- display: 'flex',
177
- alignItems: 'center',
178
- [theme.breakpoints.up('md')]: {
179
- display: 'none',
180
- },
181
- },
182
- backButton: {
183
- background: theme.palette.background.paper,
184
- color: theme.palette.text.primary,
185
- '&:hover': {
186
- background: theme.palette.background.paper,
187
- },
188
- },
189
- sheetShellActionsFullPage: {
190
- '& * > a, & * > button': {
191
- pointerEvents: 'all',
192
- },
193
- '& * > button': {
194
- boxShadow: theme.shadows[3],
195
- },
196
- [theme.breakpoints.up('md')]: {
197
- position: 'fixed',
198
- top: `calc(${theme.page.headerInnerHeight.md} + ${theme.spacings.xxs})`,
199
- },
200
- },
201
- sheetShellActionsNoButtonShadow: {
202
- [theme.breakpoints.down('sm')]: {
203
- '& * > button': {
204
- boxShadow: 'none',
205
- },
206
- },
207
- },
208
- }),
209
- { name: 'AppShellHeader' },
210
- )
211
-
212
- export default function AppShellHeader(props: AppShellHeaderProps) {
213
- const {
214
- children,
215
- logo,
216
- divider,
217
- primary = null,
218
- secondary = null,
219
- hideClose,
220
- scrollY,
221
- additional,
222
- dragIndicator,
223
- scrolled,
224
- fill = 'both',
225
- sheet,
226
- } = props
227
-
228
- const router = usePageRouter()
229
- const { closeSteps, backSteps } = usePageContext()
230
- const classes = useStyles(props)
231
- const up = useUp()
232
- const prevUp = usePrevUp()
233
- const { titleRef, contentHeaderRef } = useAppShellHeaderContext()
234
-
235
- const noChildren = typeof children === 'undefined' || !children
236
-
237
- const fillMobileOnly = fill === 'mobile-only'
238
-
239
- const sheetHeaderHeight = useMotionValue<number>(0)
240
- const titleOffset = useMotionValue<number>(100)
241
- const titleHeight = useMotionValue<number>(100)
242
-
243
- const setOffset = useCallback(
244
- (offsetTop: number, offsetParent: Element | null, clientHeight: number) => {
245
- titleHeight.set(clientHeight)
246
- titleOffset.set(offsetTop)
247
- },
248
- [titleHeight, titleOffset],
249
- )
250
-
251
- if (titleRef.current) {
252
- setOffset(
253
- titleRef.current.offsetTop,
254
- titleRef.current.offsetParent,
255
- titleRef.current.clientHeight,
256
- )
257
- }
258
-
259
- // Measure the title sizes so we can animate the opacity
260
- useEffect(() => {
261
- if (!titleRef.current) return () => {}
262
-
263
- const ro = new ResizeObserver(([entry]) => {
264
- const { offsetTop, offsetParent, clientHeight } = entry.target as HTMLDivElement
265
-
266
- setOffset(offsetTop, offsetParent, clientHeight)
267
- })
268
-
269
- ro.observe(titleRef.current)
270
- return () => ro.disconnect()
271
- }, [setOffset, titleHeight, titleOffset, titleRef])
272
-
273
- // Measure the sheetHeight sizes so we can animate the opacity
274
- useEffect(() => {
275
- if (!contentHeaderRef.current) return () => {}
276
-
277
- const ro = new ResizeObserver(([entry]) =>
278
- sheetHeaderHeight.set((entry.target as HTMLDivElement).clientHeight),
279
- )
280
-
281
- ro.observe(contentHeaderRef.current)
282
-
283
- return () => ro.disconnect()
284
- }, [contentHeaderRef, sheetHeaderHeight])
285
-
286
- const opacityTitle = useTransform(
287
- [scrollY, sheetHeaderHeight, titleOffset, titleHeight] as MotionValue<number | string>[],
288
- ([scrollYV, sheetHeaderHeightV, titleOffsetV, titleHeigthV]: number[]) =>
289
- Math.min(
290
- Math.max(
291
- 0,
292
- scrolled
293
- ? 1
294
- : (scrollYV - Math.max(titleOffsetV, 80) + sheetHeaderHeightV) / titleHeigthV,
295
- ),
296
- 1,
297
- ),
298
- )
299
-
300
- const pointerEvents = useTransform(opacityTitle, (o) => (o < 0.2 ? 'none' : 'all'))
301
- const opacityLogo = useTransform(opacityTitle, [0, 1], [1, fillMobileOnly && primary ? 1 : 0])
302
- const pointerEventsLogo = useTransform(opacityLogo, (o) => (o < 0.2 ? 'none' : 'all'))
303
-
304
- const close =
305
- !hideClose &&
306
- (closeSteps > 0 ? (
307
- <Fab
308
- size='small'
309
- type='button'
310
- classes={{ root: classes.fab }}
311
- onClick={() => router.go(closeSteps * -1)}
312
- aria-label='Close'
313
- >
314
- <SvgImageSimple src={iconClose} />
315
- </Fab>
316
- ) : (
317
- <PageLink href='/' passHref>
318
- <Fab size='small' classes={{ root: classes.fab }} aria-label='Close'>
319
- <SvgImageSimple src={iconClose} />
320
- </Fab>
321
- </PageLink>
322
- ))
323
-
324
- const backIcon = <SvgImageSimple src={iconChevronLeft} />
325
-
326
- const canClickBack = backSteps > 0 && router.asPath !== prevUp?.href
327
- let back = canClickBack && (
328
- <Button
329
- onClick={() => router.back()}
330
- variant='pill-link'
331
- size='small'
332
- className={classes.backButton}
333
- startIcon={backIcon}
334
- aria-label='Back'
335
- >
336
- {up?.href === router.asPath ? up?.title : 'Back'}
337
- </Button>
338
- )
339
-
340
- if (!canClickBack && up?.href) {
341
- back = (
342
- <PageLink href={up?.href} passHref>
343
- <Button
344
- variant='pill-link'
345
- className={classes.backButton}
346
- startIcon={backIcon}
347
- aria-label='Back'
348
- >
349
- {up?.title ?? 'Back'}
350
- </Button>
351
- </PageLink>
352
- )
353
- }
354
-
355
- let leftAction: React.ReactNode = secondary ?? back
356
- const rightAction: React.ReactNode = primary ?? close
357
- if (rightAction !== close && !leftAction) leftAction = close
358
- if (!leftAction) leftAction = <div />
359
-
360
- const showDivider = children || (fillMobileOnly && primary)
361
-
362
- return (
363
- <div
364
- className={clsx(
365
- classes.sheetHeaderContainer,
366
- noChildren && !primary && classes.sheetHeaderNoTitle,
367
- fillMobileOnly && classes.sheetHeaderFillMobileOnly,
368
- sheet && classes.sheetHeaderContainerSheetShell,
369
- )}
370
- >
371
- <div
372
- className={clsx(
373
- classes?.sheetHeader,
374
- sheet && classes.sheetHeaderSheetShell,
375
- scrolled && classes?.sheetHeaderScrolled,
376
- noChildren && !primary && classes.sheetHeaderNoTitle,
377
- fillMobileOnly && noChildren && classes.sheetHeaderNoTitleFillMobileOnly,
378
- fillMobileOnly && classes.sheetHeaderFillMobileOnly,
379
- )}
380
- ref={contentHeaderRef}
381
- >
382
- <div className={classes.logoContainer}>
383
- {logo && (
384
- <m.div
385
- style={{
386
- opacity: opacityLogo,
387
- pointerEvents: pointerEventsLogo,
388
- }}
389
- className={classes.logoInnerContainer}
390
- >
391
- {logo}
392
- </m.div>
393
- )}
394
- </div>
395
-
396
- {dragIndicator}
397
-
398
- <div
399
- className={clsx(
400
- classes.sheetHeaderActions,
401
- (noChildren || fillMobileOnly) && classes.sheetShellActionsFullPage,
402
- fillMobileOnly && showDivider && classes.sheetShellActionsNoButtonShadow,
403
- )}
404
- >
405
- {leftAction && <div>{leftAction}</div>}
406
- <div className={classes.innerContainer}>
407
- {children && (
408
- <m.div
409
- style={{ opacity: opacityTitle, pointerEvents }}
410
- className={clsx(classes.childs, fillMobileOnly && classes.fillMobileOnly)}
411
- >
412
- {children}
413
- </m.div>
414
- )}
415
- </div>
416
- <div className={classes?.sheetHeaderActionRight}>{rightAction}</div>
417
- </div>
418
- {additional && (
419
- <div className={clsx(fillMobileOnly && classes.fillMobileOnly)}>
420
- <>{additional}</>
421
- </div>
422
- )}
423
- </div>
424
- {showDivider &&
425
- (divider ?? (
426
- <m.div
427
- className={clsx(
428
- classes.dividerSpacer,
429
- classes.divider,
430
- fillMobileOnly && classes.dividerFillMobileOnly,
431
- )}
432
- style={{ opacity: opacityTitle }}
433
- />
434
- ))}
435
- {!showDivider && <div className={classes.dividerSpacer} />}
436
- </div>
437
- )
438
- }
@@ -1,6 +0,0 @@
1
- import { useContext } from 'react'
2
- import appShellHeaderContext from './appShellHeaderContext'
3
-
4
- export default function useAppShellHeaderContext() {
5
- return useContext(appShellHeaderContext)
6
- }
@@ -1,18 +0,0 @@
1
- import { useRef } from 'react'
2
- import appShellHeaderContext, {
3
- AppShellHeaderContext,
4
- } from '../AppShellHeader/appShellHeaderContext'
5
-
6
- type AppShellProviderProps = {
7
- children: React.ReactNode
8
- }
9
-
10
- export default function AppShellProvider(props: AppShellProviderProps) {
11
- const { children } = props
12
- const context: AppShellHeaderContext = {
13
- titleRef: useRef<HTMLDivElement>(null),
14
- contentHeaderRef: useRef<HTMLDivElement>(null),
15
- }
16
-
17
- return <appShellHeaderContext.Provider value={context}>{children}</appShellHeaderContext.Provider>
18
- }
@@ -1,45 +0,0 @@
1
- import { makeStyles, Theme, TypographyProps } from '@material-ui/core'
2
- import clsx from 'clsx'
3
- import React from 'react'
4
- import { UseStyles } from '../../Styles'
5
- import Title, { TitleProps } from '../../Title'
6
- import useAppShellHeaderContext from '../AppShellHeader/useAppShellHeaderContext'
7
-
8
- type AppShellTitleProps = {
9
- children: React.ReactNode
10
- bare?: boolean
11
- variant?: TypographyProps['variant']
12
- } & Pick<TitleProps, 'icon'> &
13
- UseStyles<typeof useStyles>
14
-
15
- const useStyles = makeStyles(
16
- (theme: Theme) => ({
17
- title: {},
18
- margin: {
19
- marginTop: theme.spacings.lg,
20
- marginBottom: theme.spacings.lg,
21
- },
22
- }),
23
- {
24
- name: 'AppShellTitle',
25
- },
26
- )
27
-
28
- export default function AppShellTitle(props: AppShellTitleProps) {
29
- const { children, icon, bare, variant } = props
30
- const { titleRef } = useAppShellHeaderContext()
31
- const classes = useStyles(props)
32
-
33
- return (
34
- <Title
35
- ref={titleRef}
36
- component='h2'
37
- size='medium'
38
- variant={variant}
39
- icon={icon ?? undefined}
40
- classes={{ container: clsx(classes.title, !bare && classes.margin) }}
41
- >
42
- {children}
43
- </Title>
44
- )
45
- }
@@ -1,53 +0,0 @@
1
- import { ButtonProps, makeStyles, Theme } from '@material-ui/core'
2
- import React from 'react'
3
- import { SvgImageSimple } from '..'
4
- import Button from '../Button'
5
- import { UseStyles } from '../Styles'
6
- import { iconChevronRight } from '../icons'
7
-
8
- const useStyles = makeStyles(
9
- (theme: Theme) => ({
10
- root: {
11
- width: 'min-content',
12
- pointerEvents: 'all',
13
- [theme.breakpoints.down('sm')]: {
14
- height: 40,
15
- minWidth: 40,
16
- borderRadius: 20,
17
- },
18
- [theme.breakpoints.down('xs')]: {
19
- boxShadow: 'unset',
20
- paddingLeft: `12px`,
21
- paddingRight: `10px`,
22
- },
23
- },
24
- label: {
25
- whiteSpace: 'nowrap',
26
- },
27
- icon: {
28
- display: 'none',
29
- [theme.breakpoints.up('sm')]: {
30
- display: 'unset',
31
- },
32
- },
33
- text: {
34
- pointerEvents: 'none',
35
- },
36
- }),
37
- { name: 'ForwardButton' },
38
- )
39
-
40
- export type ForwardButtonProps = UseStyles<typeof useStyles> & ButtonProps & { down?: boolean }
41
-
42
- const ForwardButton = React.forwardRef((props: ForwardButtonProps, ref) => {
43
- const { text, icon, ...classes } = useStyles(props)
44
- const { children, down, ...fabProps } = props
45
-
46
- return (
47
- <Button variant='pill' classes={classes} {...fabProps} ref={ref}>
48
- <span className={text}>{children}</span>
49
- <SvgImageSimple src={iconChevronRight} size='small' className={classes.root} />
50
- </Button>
51
- )
52
- })
53
- export default ForwardButton
@@ -1,82 +0,0 @@
1
- import { makeStyles, Theme } from '@material-ui/core'
2
- import clsx from 'clsx'
3
- import React from 'react'
4
- import { UseStyles } from '../Styles'
5
- import AppShellProvider from './AppShellProvider'
6
- import ShellBase, { PageLayoutBaseProps } from './ShellBase'
7
-
8
- const useStyles = makeStyles(
9
- (theme: Theme) => ({
10
- root: {
11
- minHeight: '100vh',
12
- display: 'grid',
13
- gridTemplateRows: `auto 1fr auto`,
14
- gridTemplateColumns: '100%',
15
- background: theme.palette.background.default,
16
- },
17
- hideFabsOnVirtualKeyboardOpen: {
18
- [theme.breakpoints.down('sm')]: {
19
- '@media (max-height: 530px)': {
20
- display: 'none',
21
- },
22
- },
23
- },
24
- header: {
25
- display: 'flex',
26
- alignItems: 'center',
27
- justifyContent: 'center',
28
- [theme.breakpoints.up('md')]: {
29
- padding: `${theme.spacings.xxs} ${theme.page.horizontal} 0`,
30
- marginBottom: theme.spacings.xxs,
31
- top: 0,
32
- display: 'flex',
33
- pointerEvents: 'none',
34
- justifyContent: 'left',
35
- width: '100%',
36
- height: theme.page.headerInnerHeight.md,
37
- },
38
- },
39
- headerAlwaysShow: {
40
- [theme.breakpoints.down('sm')]: {
41
- marginTop: 20,
42
- marginBottom: 22,
43
- },
44
- },
45
- }),
46
- { name: 'FullPageShellBase' },
47
- )
48
-
49
- export type FullPageShellBaseProps = {
50
- header: React.ReactNode
51
- footer: React.ReactNode
52
- menuFab?: React.ReactNode
53
- cartFab?: React.ReactNode
54
- children?: React.ReactNode
55
- alwaysShowHeader?: boolean
56
- } & UseStyles<typeof useStyles> &
57
- PageLayoutBaseProps
58
-
59
- export default function FullPageShellBase(props: FullPageShellBaseProps) {
60
- const { children, header, footer, menuFab, cartFab, name, alwaysShowHeader } = props
61
- const classes = useStyles(props)
62
-
63
- return (
64
- <div className={classes.root}>
65
- <AppShellProvider>
66
- <ShellBase name={name}>
67
- <header className={clsx(classes.header, alwaysShowHeader && classes.headerAlwaysShow)}>
68
- {header}
69
- </header>
70
- <div>
71
- <div className={classes.hideFabsOnVirtualKeyboardOpen}>
72
- {menuFab}
73
- {cartFab}
74
- </div>
75
- {children}
76
- </div>
77
- <div>{footer}</div>
78
- </ShellBase>
79
- </AppShellProvider>
80
- </div>
81
- )
82
- }