@graphcommerce/next-ui 3.0.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.
Files changed (153) hide show
  1. package/.babelrc +3 -0
  2. package/AnimatedRow/index.tsx +20 -0
  3. package/ApolloError/ApolloErrorAlert.tsx +59 -0
  4. package/ApolloError/ApolloErrorFullPage.tsx +25 -0
  5. package/AppShell/AppShellHeader/appShellHeaderContext.tsx +11 -0
  6. package/AppShell/AppShellHeader/index.tsx +433 -0
  7. package/AppShell/AppShellHeader/useAppShellHeaderContext.tsx +6 -0
  8. package/AppShell/AppShellProvider/index.tsx +18 -0
  9. package/AppShell/AppShellSticky/index.tsx +66 -0
  10. package/AppShell/AppShellTitle/index.tsx +45 -0
  11. package/AppShell/DesktopNavActions.tsx +28 -0
  12. package/AppShell/DesktopNavBar.tsx +110 -0
  13. package/AppShell/FixedFab.tsx +41 -0
  14. package/AppShell/ForwardButton.tsx +53 -0
  15. package/AppShell/FullPageShellBase.tsx +59 -0
  16. package/AppShell/Menu.tsx +7 -0
  17. package/AppShell/MenuFab.tsx +132 -0
  18. package/AppShell/MenuFabSecondaryItem.tsx +32 -0
  19. package/AppShell/MinimalPageShellBase.tsx +22 -0
  20. package/AppShell/PageShellHeader/index.tsx +14 -0
  21. package/AppShell/SheetShellBase/index.tsx +107 -0
  22. package/AppShell/SheetShellBase/useSheetStyles.ts +11 -0
  23. package/AppShell/SheetShellDragIndicator/index.tsx +48 -0
  24. package/AppShell/SheetShellHeader/index.tsx +28 -0
  25. package/AppShell/ShellBase.tsx +45 -0
  26. package/AppShell/useFabAnimation.tsx +19 -0
  27. package/AppShell/useFixedFabAnimation.tsx +18 -0
  28. package/AspectRatioContainer/index.tsx +27 -0
  29. package/Blog/BlogAuthor/index.tsx +60 -0
  30. package/Blog/BlogContent/index.tsx +24 -0
  31. package/Blog/BlogHeader/index.tsx +64 -0
  32. package/Blog/BlogList/index.tsx +27 -0
  33. package/Blog/BlogListItem/index.tsx +83 -0
  34. package/Blog/BlogTags/index.tsx +34 -0
  35. package/Blog/BlogTitle/index.tsx +29 -0
  36. package/Button/index.tsx +164 -0
  37. package/ButtonLink/index.tsx +45 -0
  38. package/CHANGELOG.md +1095 -0
  39. package/ChipMenu/index.tsx +130 -0
  40. package/ContainerWithHeader/index.tsx +49 -0
  41. package/Debug/DebugSpacer.tsx +51 -0
  42. package/FlagAvatar/index.tsx +28 -0
  43. package/Form/FormActions.tsx +15 -0
  44. package/Form/FormDivider.tsx +14 -0
  45. package/Form/FormHeader.tsx +27 -0
  46. package/Form/FormRow.tsx +14 -0
  47. package/Form/InputCheckmark.tsx +19 -0
  48. package/Form/index.tsx +62 -0
  49. package/FramerNextPagesSlider/Slide.tsx +71 -0
  50. package/FramerNextPagesSlider/Slider.tsx +39 -0
  51. package/FramerNextPagesSlider/index.ts +1 -0
  52. package/FramerNextPagesSlider/types.ts +3 -0
  53. package/FramerScroller/components/SidebarGallery.tsx +246 -0
  54. package/FramerScroller/components/SidebarSlider.tsx +103 -0
  55. package/FullPageMessage/index.tsx +68 -0
  56. package/Highlight/index.tsx +14 -0
  57. package/IconHeader/index.tsx +109 -0
  58. package/JsonLd/index.tsx +18 -0
  59. package/Page/App.tsx +15 -0
  60. package/Page/Document.tsx +23 -0
  61. package/Page/framerFeatures.ts +4 -0
  62. package/Page/types.ts +19 -0
  63. package/PageLoadIndicator/index.tsx +46 -0
  64. package/PageMeta/index.tsx +40 -0
  65. package/Pagination/index.tsx +123 -0
  66. package/RenderType/index.tsx +40 -0
  67. package/Row/ButtonLinkList/index.tsx +53 -0
  68. package/Row/ColumnOne/index.tsx +11 -0
  69. package/Row/ColumnOneBoxed/index.tsx +27 -0
  70. package/Row/ColumnOneCentered/index.tsx +22 -0
  71. package/Row/ColumnThree/index.tsx +66 -0
  72. package/Row/ColumnTwo/index.tsx +44 -0
  73. package/Row/ColumnTwoSpread/index.tsx +41 -0
  74. package/Row/ColumnTwoWithTop/index.tsx +53 -0
  75. package/Row/ContentLinks/index.tsx +48 -0
  76. package/Row/HeroBanner/index.tsx +102 -0
  77. package/Row/IconBlocks/IconBlock/index.tsx +56 -0
  78. package/Row/IconBlocks/index.tsx +57 -0
  79. package/Row/ParagraphWithSidebarSlide/index.tsx +114 -0
  80. package/Row/Quote/index.tsx +13 -0
  81. package/Row/RowImageText/index.tsx +67 -0
  82. package/Row/RowImageTextBoxed/index.tsx +75 -0
  83. package/Row/SpecialBanner/index.tsx +107 -0
  84. package/Row/index.tsx +13 -0
  85. package/SectionContainer/index.tsx +39 -0
  86. package/SectionHeader/index.tsx +69 -0
  87. package/Separator/index.tsx +33 -0
  88. package/Snackbar/ErrorSnackbar.tsx +9 -0
  89. package/Snackbar/MessageSnackbar.tsx +5 -0
  90. package/Snackbar/MessageSnackbarImpl.tsx +202 -0
  91. package/StarRatingField/index.tsx +58 -0
  92. package/Stepper/Stepper.tsx +45 -0
  93. package/StyledBadge/index.tsx +21 -0
  94. package/Styles/index.tsx +3 -0
  95. package/Styles/responsiveVal.tsx +20 -0
  96. package/SvgImage/SvgImageSimple.tsx +66 -0
  97. package/SvgImage/index.tsx +76 -0
  98. package/TextInputNumber/index.tsx +169 -0
  99. package/Theme/types.ts +63 -0
  100. package/TimeAgo/index.tsx +29 -0
  101. package/Title/index.tsx +71 -0
  102. package/ToggleButton/index.tsx +100 -0
  103. package/ToggleButtonGroup/index.tsx +112 -0
  104. package/UspList/UspListItem.tsx +46 -0
  105. package/UspList/index.tsx +32 -0
  106. package/icons/icon_addresses.svg +17 -0
  107. package/icons/icon_arrow_back.svg +1 -0
  108. package/icons/icon_arrow_forward.svg +1 -0
  109. package/icons/icon_box.svg +6 -0
  110. package/icons/icon_chat.svg +1 -0
  111. package/icons/icon_checkmark.svg +1 -0
  112. package/icons/icon_checkmark_green.svg +1 -0
  113. package/icons/icon_chevron_back.svg +8 -0
  114. package/icons/icon_chevron_down.svg +8 -0
  115. package/icons/icon_chevron_left.svg +8 -0
  116. package/icons/icon_chevron_right.svg +8 -0
  117. package/icons/icon_chevron_up.svg +8 -0
  118. package/icons/icon_close.svg +6 -0
  119. package/icons/icon_close_circle.svg +1 -0
  120. package/icons/icon_collapse_vertical.svg +11 -0
  121. package/icons/icon_customer_service.svg +6 -0
  122. package/icons/icon_email.svg +1 -0
  123. package/icons/icon_email_outline.svg +6 -0
  124. package/icons/icon_expand_vertical.svg +11 -0
  125. package/icons/icon_heart.svg +15 -0
  126. package/icons/icon_home.svg +6 -0
  127. package/icons/icon_id.svg +6 -0
  128. package/icons/icon_invoice_red.svg +7 -0
  129. package/icons/icon_location_red.svg +7 -0
  130. package/icons/icon_lock.svg +6 -0
  131. package/icons/icon_menu.svg +1 -0
  132. package/icons/icon_min.svg +1 -0
  133. package/icons/icon_newspaper.svg +6 -0
  134. package/icons/icon_party.svg +7 -0
  135. package/icons/icon_person.svg +6 -0
  136. package/icons/icon_person_alt.svg +6 -0
  137. package/icons/icon_person_alt_big.svg +15 -0
  138. package/icons/icon_phone.svg +1 -0
  139. package/icons/icon_plus.svg +1 -0
  140. package/icons/icon_sad_face.svg +11 -0
  141. package/icons/icon_sad_shoppingbag.svg +16 -0
  142. package/icons/icon_search.svg +1 -0
  143. package/icons/icon_shopping_bag.svg +7 -0
  144. package/icons/icon_shutdown.svg +6 -0
  145. package/icons/icon_star.svg +6 -0
  146. package/icons/icon_star_filled_muted.svg +6 -0
  147. package/icons/icon_star_yellow.svg +6 -0
  148. package/icons/index.tsx +42 -0
  149. package/index.ts +163 -0
  150. package/package.json +61 -0
  151. package/tsconfig.json +5 -0
  152. package/types.d.ts +13 -0
  153. package/useIntersectionObserver/index.tsx +31 -0
@@ -0,0 +1,40 @@
1
+ import Head from 'next/head'
2
+
3
+ // https://developers.google.com/search/docs/advanced/robots/robots_meta_tag#directives
4
+ export type MetaRobots =
5
+ | 'noindex'
6
+ | 'nofollow'
7
+ | 'noarchive'
8
+ | 'nosnippet'
9
+ | 'notranslate'
10
+ | 'noimageindex'
11
+ | `unavailable_after:${string}`
12
+ | `max-snippet:${number}`
13
+ | `max-image-preview:${'none' | 'standard' | 'large'}`
14
+ | `max-video-preview:${number}`
15
+ type MetaRobotsAll = ['all' | 'none']
16
+
17
+ export type PageMetaProps = {
18
+ title: string
19
+ canonical?: `http://${string}` | `https://${string}` | string
20
+ metaDescription?: string
21
+ metaRobots?: MetaRobotsAll | MetaRobots[]
22
+ }
23
+
24
+ export default function PageMeta(props: PageMetaProps) {
25
+ const { title, canonical, metaDescription, metaRobots = ['all'] } = props
26
+
27
+ if (!(canonical ?? 'http').startsWith('http'))
28
+ throw new Error(`canonical must start with http:// or https://, '${canonical}' given`)
29
+
30
+ return (
31
+ <Head>
32
+ <title>{title.trim()}</title>
33
+ {metaDescription && (
34
+ <meta name='description' content={metaDescription.trim()} key='meta-description' />
35
+ )}
36
+ <meta name='robots' content={metaRobots.join(',')} key='meta-robots' />
37
+ {canonical && <link rel='canonical' href={canonical} key='canonical' />}
38
+ </Head>
39
+ )
40
+ }
@@ -0,0 +1,123 @@
1
+ import { makeStyles, Theme } from '@material-ui/core'
2
+ import { PaginationProps, usePagination } from '@material-ui/lab'
3
+ import React from 'react'
4
+ import { UseStyles } from '../Styles'
5
+ import SvgImage from '../SvgImage'
6
+ import { iconChevronLeft, iconChevronRight } from '../icons'
7
+
8
+ const useStyles = makeStyles((theme: Theme) => ({
9
+ pagination: {
10
+ gridArea: 'pagination',
11
+ justifyContent: 'center',
12
+ display: 'grid',
13
+ gap: 8,
14
+ gridAutoFlow: 'column',
15
+ alignItems: 'center',
16
+ marginBottom: theme.spacings.xxl,
17
+ [theme.breakpoints.up('md')]: {
18
+ marginBottom: theme.spacings.lg,
19
+ },
20
+ ...theme.typography.body1,
21
+ '& > *': {
22
+ whiteSpace: 'nowrap',
23
+ boxShadow: 'none',
24
+ },
25
+ },
26
+ disabled: {
27
+ background: 'none !important',
28
+ },
29
+ root: {
30
+ margin: '32px auto 0 auto',
31
+ marginTop: theme.spacings.lg,
32
+ marginBottom: theme.spacings.lg,
33
+ display: 'flex',
34
+ alignItems: 'center',
35
+ justifyContent: 'center',
36
+ // fontSize: 18,
37
+ '& span': {
38
+ padding: '0 8px 0 0',
39
+ },
40
+ '& a': {
41
+ transition: 'background .25s ease',
42
+ borderRadius: '100%',
43
+ height: 40,
44
+ width: 40,
45
+ '&:hover': {
46
+ background: 'rgba(0, 0, 0, 0.04)',
47
+ },
48
+ },
49
+ [theme.breakpoints.down('xs')]: {
50
+ alignItems: 'center',
51
+ },
52
+ },
53
+ icon: {
54
+ borderRadius: '100%',
55
+ padding: 6,
56
+ height: 40,
57
+ width: 40,
58
+ },
59
+ label: {
60
+ textAlign: 'center',
61
+ },
62
+ labelTitle: {
63
+ display: 'inline',
64
+ [theme.breakpoints.down('xs')]: {
65
+ display: 'block',
66
+ },
67
+ },
68
+ }))
69
+
70
+ export type PagePaginationProps = {
71
+ count: number
72
+ page: number
73
+ renderLink: (page: number, icon: React.ReactNode, btnProps: any) => React.ReactNode
74
+ } & Omit<PaginationProps, 'count' | 'defaultPage' | 'page' | 'renderItem'> &
75
+ UseStyles<typeof useStyles>
76
+
77
+ /**
78
+ * Rel="prev" and rel="next" are deprecated by Google.
79
+ *
80
+ * Read more: https://ahrefs.com/blog/rel-prev-next-pagination/
81
+ */
82
+ export default function Pagination(props: PagePaginationProps) {
83
+ const { count, page, renderLink, classes: styles, ...paginationProps } = props
84
+ const classes = useStyles(props)
85
+ const { items } = usePagination({
86
+ count,
87
+ defaultPage: 1,
88
+ page,
89
+ ...paginationProps,
90
+ })
91
+
92
+ const prevBtnProps = items[0]
93
+ const nextBtnProps = items[items.length - 1]
94
+
95
+ const chevronLeft = (
96
+ <SvgImage
97
+ src={iconChevronLeft}
98
+ alt='chevron left'
99
+ shade={page === 1 ? 'muted' : undefined}
100
+ classes={{ root: classes.icon }}
101
+ />
102
+ )
103
+
104
+ const chevronRight = (
105
+ <SvgImage
106
+ src={iconChevronRight}
107
+ alt='chevron right'
108
+ shade={page === count ? 'muted' : undefined}
109
+ classes={{ root: classes.icon }}
110
+ />
111
+ )
112
+
113
+ return (
114
+ <div className={classes.root}>
115
+ {page === 1 ? chevronLeft : renderLink(page - 1, chevronLeft, prevBtnProps)}
116
+
117
+ <span className={classes.labelTitle}>Page</span>
118
+ <span className={classes.label}>{`${page} of ${Math.max(1, count)}`}</span>
119
+
120
+ {page === count ? chevronRight : renderLink(page + 1, chevronRight, nextBtnProps)}
121
+ </div>
122
+ )
123
+ }
@@ -0,0 +1,40 @@
1
+ import React from 'react'
2
+ /** To make renderers customizable we need to be able to provide renders for all types */
3
+ type TypeObject = { __typename: string; [index: string]: unknown }
4
+
5
+ type FilterTypeByTypename<A extends TypeObject, Typename extends string> = A extends unknown
6
+ ? A['__typename'] extends Typename
7
+ ? A
8
+ : never
9
+ : never
10
+
11
+ type TypeRenderMethod<P> = (props: P) => React.ReactElement | null
12
+
13
+ type TypeRenderMap<
14
+ T extends TypeObject,
15
+ TypeNames extends string,
16
+ TAdd extends Record<string, unknown>
17
+ > = {
18
+ [K in TypeNames]: TypeRenderMethod<FilterTypeByTypename<T, K> & TAdd>
19
+ }
20
+
21
+ export type TypeRenderer<
22
+ T extends TypeObject,
23
+ TAdd extends Record<string, unknown> = Record<string, unknown>
24
+ > = TypeRenderMap<T, T['__typename'], TAdd>
25
+
26
+ /**
27
+ * A simple array with renderers but with strict typing that validates of the provided Renderer is
28
+ * actually able to render the Type
29
+ */
30
+ export default function RenderType<
31
+ T extends TypeObject,
32
+ A extends Record<string, unknown> = Record<string, unknown>
33
+ >(props: { renderer: TypeRenderer<T, A> } & FilterTypeByTypename<T, T['__typename']> & A) {
34
+ const { renderer, __typename, ...typeItemProps } = props
35
+ const TypeItem: TypeRenderMethod<typeof typeItemProps> = renderer[__typename]
36
+ ? renderer[__typename]
37
+ : () => <>{__typename}</>
38
+
39
+ return <TypeItem {...typeItemProps} __typename={__typename} />
40
+ }
@@ -0,0 +1,53 @@
1
+ import { Theme } from '@material-ui/core'
2
+ import { makeStyles } from '@material-ui/styles'
3
+ import React from 'react'
4
+ import Row from '..'
5
+ import SectionContainer from '../../SectionContainer'
6
+ import { UseStyles } from '../../Styles'
7
+ import responsiveVal from '../../Styles/responsiveVal'
8
+
9
+ const useStyles = makeStyles(
10
+ (theme: Theme) => ({
11
+ container: {
12
+ maxWidth: 820,
13
+ },
14
+ h1: {
15
+ textAlign: 'center',
16
+ ...theme.typography.h2,
17
+ },
18
+ overline: {
19
+ display: 'block',
20
+ padding: `${theme.spacings.xs} 0`,
21
+ borderBottom: `1px solid ${theme.palette.grey[300]}`,
22
+ },
23
+ links: ({ containsBigLinks }: ButtonLinkListPropsBase) => ({
24
+ display: 'grid',
25
+ gridTemplateColumns: containsBigLinks
26
+ ? undefined
27
+ : `repeat(auto-fill, minmax(${responsiveVal(210, 350)}, 1fr))`,
28
+ columnGap: theme.spacings.sm,
29
+ }),
30
+ }),
31
+ { name: 'ButtonLinkList' },
32
+ )
33
+
34
+ type ButtonLinkListPropsBase = {
35
+ title: string
36
+ links: React.ReactNode
37
+ containsBigLinks: boolean
38
+ }
39
+
40
+ export type ButtonLinkListProps = UseStyles<typeof useStyles> & ButtonLinkListPropsBase
41
+
42
+ export default function ButtonLinkList(props: ButtonLinkListProps) {
43
+ const { title, links } = props
44
+ const classes = useStyles(props)
45
+
46
+ return (
47
+ <Row maxWidth='md' className={classes.container}>
48
+ <SectionContainer labelLeft={title}>
49
+ <div className={classes.links}>{links}</div>
50
+ </SectionContainer>
51
+ </Row>
52
+ )
53
+ }
@@ -0,0 +1,11 @@
1
+ import { Container, styled } from '@material-ui/core'
2
+
3
+ const ColumnOne = styled(Container)(
4
+ ({ theme }) => ({
5
+ maxWidth: 820,
6
+ marginBottom: theme.spacings.lg,
7
+ }),
8
+ { name: 'ColumnOne' },
9
+ )
10
+
11
+ export default ColumnOne
@@ -0,0 +1,27 @@
1
+ import { Container, ContainerProps, makeStyles, Theme } from '@material-ui/core'
2
+ import React from 'react'
3
+ import Row from '..'
4
+
5
+ const useStyles = makeStyles(
6
+ (theme: Theme) => ({
7
+ boxed: {
8
+ padding: theme.spacings.lg,
9
+ boxShadow: theme.shadows[24],
10
+ '& h1, & h2, & h3': {
11
+ marginTop: 0,
12
+ },
13
+ },
14
+ }),
15
+ { name: 'ColumnOneBoxed' },
16
+ )
17
+
18
+ export default function ColumnOneBoxed(props: ContainerProps) {
19
+ const { children } = props
20
+ const classes = useStyles(props)
21
+
22
+ return (
23
+ <Row {...props}>
24
+ <div className={classes.boxed}>{children}</div>
25
+ </Row>
26
+ )
27
+ }
@@ -0,0 +1,22 @@
1
+ import { ContainerProps, styled } from '@material-ui/core'
2
+ import React from 'react'
3
+ import ColumnOne from '../ColumnOne'
4
+
5
+ const Wrapper = styled('div')(({ theme }) => ({
6
+ marginBottom: theme.spacings.lg,
7
+ marginTop: theme.spacings.lg,
8
+ textAlign: 'center',
9
+ maxWidth: `calc(1050px + calc(${theme.spacings.md} * 2))`,
10
+ margin: `0 auto`,
11
+ position: 'relative',
12
+ }))
13
+
14
+ export default function ColumnOneCentered(props: ContainerProps) {
15
+ const { children } = props
16
+
17
+ return (
18
+ <ColumnOne>
19
+ <Wrapper>{children}</Wrapper>
20
+ </ColumnOne>
21
+ )
22
+ }
@@ -0,0 +1,66 @@
1
+ import { ContainerProps, makeStyles, Theme } from '@material-ui/core'
2
+ import React from 'react'
3
+ import Row from '..'
4
+ import { UseStyles } from '../../Styles'
5
+
6
+ const useStyles = makeStyles(
7
+ (theme: Theme) => ({
8
+ root: {
9
+ display: 'grid',
10
+ gridColumnGap: theme.spacings.md,
11
+ gridRowGap: theme.spacings.lg,
12
+ gridTemplateColumns: `1fr`,
13
+ gridTemplateAreas: `
14
+ "one"
15
+ "two"
16
+ "three"
17
+ `,
18
+ '& h2, & h3': {
19
+ ...theme.typography.h4,
20
+ [theme.breakpoints.up('md')]: {
21
+ marginBottom: '-25px',
22
+ },
23
+ },
24
+ '& p': {
25
+ [theme.breakpoints.up('md')]: {
26
+ marginTop: '65px',
27
+ },
28
+ },
29
+ [theme.breakpoints.up('sm')]: {
30
+ gridTemplateColumns: `1fr 1fr`,
31
+ gridTemplateAreas: `
32
+ "one two"
33
+ "three three"
34
+ `,
35
+ },
36
+ [theme.breakpoints.up('md')]: {
37
+ gridTemplateColumns: `1fr 1fr 1fr`,
38
+ gridTemplateAreas: '"one two three"',
39
+ },
40
+ },
41
+ colOne: { gridArea: 'one', zIndex: 2 },
42
+ colTwo: { gridArea: 'two', zIndex: 2 },
43
+ colThree: { gridArea: 'three', zIndex: 2 },
44
+ }),
45
+ { name: 'ColumnThree' },
46
+ )
47
+
48
+ export type ColumnThreeProps = UseStyles<typeof useStyles> &
49
+ Omit<ContainerProps, 'children'> & {
50
+ colOneContent: React.ReactNode
51
+ colTwoContent: React.ReactNode
52
+ colThreeContent: React.ReactNode
53
+ }
54
+
55
+ export default function ColumnThree(props: ColumnThreeProps) {
56
+ const { colOneContent, colTwoContent, colThreeContent, ...containerProps } = props
57
+ const classes = useStyles(props)
58
+
59
+ return (
60
+ <Row className={classes.root} {...containerProps}>
61
+ <div className={classes.colOne}>{colOneContent}</div>
62
+ <div className={classes.colTwo}>{colTwoContent}</div>
63
+ <div className={classes.colThree}>{colThreeContent}</div>
64
+ </Row>
65
+ )
66
+ }
@@ -0,0 +1,44 @@
1
+ import { ContainerProps, makeStyles, Theme } from '@material-ui/core'
2
+ import React from 'react'
3
+ import Row from '..'
4
+ import { UseStyles } from '../../Styles'
5
+
6
+ const useStyles = makeStyles(
7
+ (theme: Theme) => ({
8
+ root: {
9
+ gridColumnGap: theme.spacings.md,
10
+ gridRowGap: theme.spacings.lg,
11
+ display: `grid`,
12
+ gridTemplateColumns: `1fr`,
13
+ gridTemplateAreas: `"one" "two"`,
14
+ '& h2, & h3': {
15
+ ...theme.typography.h4,
16
+ },
17
+ [theme.breakpoints.up('sm')]: {
18
+ gridTemplateColumns: `1fr 1fr`,
19
+ gridTemplateAreas: `"one two"`,
20
+ },
21
+ },
22
+ colOne: { gridArea: 'one' },
23
+ colTwo: { gridArea: 'two' },
24
+ }),
25
+ { name: 'ColumnTwo' },
26
+ )
27
+
28
+ export type ColumnTwoProps = UseStyles<typeof useStyles> &
29
+ Omit<ContainerProps, 'children'> & {
30
+ colOneContent: React.ReactNode
31
+ colTwoContent: React.ReactNode
32
+ }
33
+
34
+ export default function ColumnTwo(props: ColumnTwoProps) {
35
+ const { colOneContent, colTwoContent, ...containerProps } = props
36
+ const classes = useStyles(props)
37
+
38
+ return (
39
+ <Row maxWidth='lg' {...containerProps} className={classes.root}>
40
+ <div className={classes.colOne}>{colOneContent}</div>
41
+ <div className={classes.colTwo}>{colTwoContent}</div>
42
+ </Row>
43
+ )
44
+ }
@@ -0,0 +1,41 @@
1
+ import { ContainerProps, makeStyles, Theme } from '@material-ui/core'
2
+ import React from 'react'
3
+ import { UseStyles } from '../../Styles'
4
+ import ColumnTwo from '../ColumnTwo'
5
+
6
+ const useStyles = makeStyles(
7
+ ({ breakpoints }: Theme) => ({
8
+ root: {
9
+ [breakpoints.up('md')]: {
10
+ gridTemplateColumns: `1fr 1fr 1fr`,
11
+ gridTemplateAreas: ({ somethingWithNodeLength }: any) =>
12
+ somethingWithNodeLength ? `"one one two"` : `"one two two"`,
13
+ '& h2, & h3': {
14
+ '&:empty': {
15
+ display: 'block',
16
+ minHeight: 30,
17
+ },
18
+ },
19
+ },
20
+ gridTemplateColumns: `1fr`,
21
+ gridTemplateAreas: `
22
+ "one"
23
+ "two"
24
+ `,
25
+ },
26
+ }),
27
+ { name: 'ColumnTwoSpread' },
28
+ )
29
+
30
+ export type ColumnTwoSpreadProps = Omit<ContainerProps, 'children'> &
31
+ UseStyles<typeof useStyles> & {
32
+ nodeLength: boolean
33
+ colOneContent: React.ReactNode
34
+ colTwoContent: React.ReactNode
35
+ }
36
+
37
+ export default function ColumnTwoSpread(props: ColumnTwoSpreadProps) {
38
+ const classes = useStyles(props)
39
+
40
+ return <ColumnTwo {...props} classes={classes} />
41
+ }
@@ -0,0 +1,53 @@
1
+ import { Container, makeStyles, Theme } from '@material-ui/core'
2
+ import React, { PropsWithChildren } from 'react'
3
+ import Row from '..'
4
+ import { UseStyles } from '../../Styles'
5
+
6
+ const useStyles = makeStyles(
7
+ (theme: Theme) => ({
8
+ root: {
9
+ display: 'grid',
10
+ gap: `${theme.spacings.lg} 0`,
11
+ gridTemplateAreas: `"top"
12
+ "left"
13
+ "right"`,
14
+ [theme.breakpoints.up('md')]: {
15
+ gridTemplateAreas: `"top ."
16
+ "left right"`,
17
+ gridTemplateColumns: '1fr auto',
18
+ gap: `${theme.spacings.sm} ${theme.spacings.xl}`,
19
+ },
20
+ },
21
+ top: {
22
+ gridArea: 'top',
23
+ },
24
+ left: {
25
+ gridArea: 'left',
26
+ },
27
+ right: {
28
+ gridArea: 'right',
29
+ },
30
+ }),
31
+ { name: 'ColumnTwoWithTop' },
32
+ )
33
+
34
+ export type ProductDescriptionProps = PropsWithChildren<
35
+ UseStyles<typeof useStyles> & {
36
+ top: React.ReactNode
37
+ left: React.ReactNode
38
+ right: React.ReactNode
39
+ }
40
+ >
41
+
42
+ export default function ColumnTwoWithTop(props: ProductDescriptionProps) {
43
+ const { top, left, right } = props
44
+ const classes = useStyles(props)
45
+
46
+ return (
47
+ <Row className={classes.root}>
48
+ <div className={classes.top}>{top}</div>
49
+ <div className={classes.left}>{left}</div>
50
+ <div className={classes.right}>{right}</div>
51
+ </Row>
52
+ )
53
+ }
@@ -0,0 +1,48 @@
1
+ import { Container, makeStyles, Theme, Typography } from '@material-ui/core'
2
+ import { Scroller, ScrollerProvider } from '@graphcommerce/framer-scroller'
3
+ import React from 'react'
4
+ import { UseStyles } from '../../Styles'
5
+
6
+ const useStyles = makeStyles(
7
+ (theme: Theme) => ({
8
+ root: {},
9
+ scroller: {
10
+ marginBottom: `${theme.spacings.lg}`,
11
+ display: 'grid',
12
+ gridAutoFlow: 'column',
13
+ justifyContent: 'start',
14
+ gap: `${theme.spacings.md}`,
15
+ alignContent: 'center',
16
+ '& > *': {
17
+ minWidth: 'max-content',
18
+ },
19
+ },
20
+ title: {
21
+ fontWeight: 600,
22
+ },
23
+ }),
24
+ { name: 'ContentLinks' },
25
+ )
26
+
27
+ export type ContentLinksProps = UseStyles<typeof useStyles> & {
28
+ title: string
29
+ children: React.ReactNode
30
+ }
31
+
32
+ export default function ContentLinks(props: ContentLinksProps) {
33
+ const { title, children } = props
34
+ const classes = useStyles(props)
35
+
36
+ return (
37
+ <Container className={classes.root} maxWidth={false}>
38
+ <ScrollerProvider scrollSnapAlign='none'>
39
+ <Scroller className={classes.scroller} hideScrollbar>
40
+ <Typography variant='body1' component='h4' className={classes.title}>
41
+ {title}
42
+ </Typography>
43
+ {children}
44
+ </Scroller>
45
+ </ScrollerProvider>
46
+ </Container>
47
+ )
48
+ }
@@ -0,0 +1,102 @@
1
+ import { ContainerProps, Theme } from '@material-ui/core'
2
+ import { makeStyles } from '@material-ui/styles'
3
+ import { m, useTransform, useViewportScroll } from 'framer-motion'
4
+ import React from 'react'
5
+ import Row from '..'
6
+ import { UseStyles } from '../../Styles'
7
+ import responsiveVal from '../../Styles/responsiveVal'
8
+
9
+ const useStyles = makeStyles(
10
+ (theme: Theme) => ({
11
+ container: {
12
+ [theme.breakpoints.up('md')]: {
13
+ paddingTop: theme.spacings.xxs,
14
+ },
15
+ paddingLeft: 0,
16
+ paddingRight: 0,
17
+ },
18
+ wrapper: {
19
+ position: 'relative',
20
+ },
21
+ copy: {
22
+ zIndex: 1,
23
+ color: theme.palette.secondary.contrastText,
24
+ position: 'relative',
25
+ display: 'grid',
26
+ justifyItems: 'center',
27
+ alignContent: 'center',
28
+ padding: `${theme.spacings.lg} ${theme.spacings.md}`,
29
+ minHeight: '90vh',
30
+ '& > *': {
31
+ zIndex: 1,
32
+ maxWidth: 'max-content',
33
+ },
34
+ [theme.breakpoints.up('md')]: {
35
+ width: '70%',
36
+ },
37
+ [theme.breakpoints.up('lg')]: {
38
+ padding: `${theme.spacings.lg} ${theme.spacings.lg}`,
39
+ width: '50%',
40
+ },
41
+ },
42
+ asset: {
43
+ position: 'absolute',
44
+ top: '0',
45
+ zIndex: 0,
46
+ width: '100%',
47
+ height: '100%',
48
+ display: 'grid',
49
+ justifyItems: 'center',
50
+ overflow: 'hidden',
51
+ '& video': {
52
+ objectFit: 'cover',
53
+ width: '100%',
54
+ height: '100%',
55
+ },
56
+ [theme.breakpoints.up('md')]: {
57
+ height: '100%',
58
+ },
59
+ },
60
+ }),
61
+ { name: 'HeroBanner' },
62
+ )
63
+
64
+ export type HeroBannerProps = UseStyles<typeof useStyles> &
65
+ ContainerProps & {
66
+ pageLinks: React.ReactNode
67
+ videoSrc: string
68
+ children: React.ReactNode
69
+ }
70
+
71
+ export default function HeroBanner(props: HeroBannerProps) {
72
+ const { pageLinks, videoSrc, children, ...containerProps } = props
73
+ const classes = useStyles(props)
74
+
75
+ const { scrollY } = useViewportScroll()
76
+ const actionsAnimWidth = useTransform(
77
+ scrollY,
78
+ [10, 150],
79
+ [`calc(100% - ${responsiveVal(30, 60)})`, `calc(100% - ${responsiveVal(0, 0)})`],
80
+ )
81
+
82
+ return (
83
+ <Row maxWidth={false} {...containerProps} className={classes.container}>
84
+ <div className={classes.wrapper}>
85
+ <div className={classes.copy}>
86
+ {children}
87
+ {pageLinks}
88
+ </div>
89
+ <div className={classes.asset}>
90
+ <m.video
91
+ src={videoSrc}
92
+ autoPlay
93
+ muted
94
+ loop
95
+ playsInline
96
+ style={{ width: actionsAnimWidth }}
97
+ />
98
+ </div>
99
+ </div>
100
+ </Row>
101
+ )
102
+ }