@graphcommerce/next-ui 3.25.3 → 4.1.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 (140) hide show
  1. package/AnimatedRow/index.tsx +6 -3
  2. package/ApolloError/ApolloErrorAlert.tsx +20 -21
  3. package/ApolloError/ApolloErrorFullPage.tsx +3 -4
  4. package/ApolloError/ApolloErrorSnackbar.tsx +3 -3
  5. package/Blog/BlogAuthor/index.tsx +42 -48
  6. package/Blog/BlogContent/index.tsx +6 -23
  7. package/Blog/BlogHeader/index.tsx +26 -23
  8. package/Blog/BlogList/index.tsx +7 -25
  9. package/Blog/BlogListItem/index.tsx +63 -52
  10. package/Blog/BlogTags/BlogTag.tsx +27 -0
  11. package/Blog/BlogTags/index.tsx +7 -32
  12. package/Blog/BlogTitle/index.tsx +7 -21
  13. package/Button/Button.tsx +5 -0
  14. package/Button/LinkOrButton.tsx +80 -0
  15. package/Button/index.tsx +2 -177
  16. package/CHANGELOG.md +524 -645
  17. package/ChipMenu/index.tsx +71 -77
  18. package/ContainerWithHeader/index.tsx +33 -30
  19. package/FlagAvatar/index.tsx +2 -12
  20. package/Footer/Footer.tsx +105 -88
  21. package/Footer/index.ts +0 -1
  22. package/Form/Form.tsx +35 -0
  23. package/Form/FormActions.tsx +9 -14
  24. package/Form/FormDivider.tsx +8 -13
  25. package/Form/FormHeader.tsx +5 -26
  26. package/Form/FormRow.tsx +8 -13
  27. package/Form/InputCheckmark.tsx +9 -22
  28. package/FramerScroller/SidebarGallery.tsx +340 -0
  29. package/FramerScroller/SidebarSlider.tsx +107 -0
  30. package/FramerScroller/index.ts +2 -0
  31. package/FullPageMessage/index.tsx +52 -48
  32. package/Highlight/index.tsx +1 -1
  33. package/IconHeader/index.tsx +63 -58
  34. package/JsonLd/index.tsx +3 -2
  35. package/Layout/components/LayoutHeader.tsx +75 -82
  36. package/Layout/components/LayoutHeaderBack.tsx +26 -18
  37. package/Layout/components/LayoutHeaderClose.tsx +9 -22
  38. package/Layout/components/LayoutHeaderContent.tsx +190 -154
  39. package/Layout/components/LayoutHeadertypes.ts +1 -1
  40. package/Layout/components/LayoutTitle.tsx +60 -55
  41. package/LayoutDefault/components/LayoutDefault.tsx +96 -85
  42. package/LayoutOverlay/components/LayoutOverlay.tsx +2 -8
  43. package/LayoutOverlay/components/LayoutOverlayBase.tsx +233 -239
  44. package/LayoutOverlay/test/LayoutOverlayDemo.tsx +1 -1
  45. package/LayoutParts/DesktopHeaderBadge.tsx +28 -0
  46. package/LayoutParts/DesktopNavActions.tsx +15 -0
  47. package/LayoutParts/DesktopNavBar.tsx +113 -0
  48. package/LayoutParts/DesktopNavBarItem.tsx +44 -0
  49. package/{AppShell → LayoutParts}/GlobalHead.tsx +1 -2
  50. package/LayoutParts/Logo.tsx +77 -0
  51. package/LayoutParts/MenuFab.tsx +132 -0
  52. package/LayoutParts/MenuFabItem.tsx +25 -0
  53. package/LayoutParts/MenuFabSecondaryItem.tsx +37 -0
  54. package/{AppShell/PlaceholderFab/index.tsx → LayoutParts/PlaceholderFab.tsx} +1 -1
  55. package/LayoutParts/StickyBelowHeader.tsx +25 -0
  56. package/LayoutParts/index.ts +12 -0
  57. package/{AppShell → LayoutParts}/useFabAnimation.ts +0 -0
  58. package/Page/CssAndFramerMotionProvider.tsx +21 -0
  59. package/Page/index.ts +2 -0
  60. package/Page/types.ts +2 -8
  61. package/PageLoadIndicator/index.tsx +25 -30
  62. package/PageMeta/index.tsx +1 -1
  63. package/Pagination/index.tsx +37 -54
  64. package/RenderType/index.tsx +1 -1
  65. package/Row/ButtonLinkList/ButtonLinkList.tsx +35 -37
  66. package/Row/ButtonLinkList/ButtonLinkListItem.tsx +16 -33
  67. package/Row/ColumnOne/index.tsx +5 -10
  68. package/Row/ColumnOneBoxed/index.tsx +18 -19
  69. package/Row/ColumnOneCentered/index.tsx +3 -4
  70. package/Row/ColumnThree/index.tsx +62 -57
  71. package/Row/ColumnTwo/index.tsx +37 -32
  72. package/Row/ColumnTwoSpread/index.tsx +28 -37
  73. package/Row/ColumnTwoWithTop/index.tsx +37 -43
  74. package/Row/ContentLinks/index.tsx +24 -25
  75. package/Row/HeroBanner/index.tsx +98 -82
  76. package/Row/IconBlocks/IconBlock/index.tsx +45 -37
  77. package/Row/IconBlocks/index.tsx +29 -44
  78. package/Row/ImageText/index.tsx +71 -67
  79. package/Row/ImageTextBoxed/index.tsx +66 -65
  80. package/Row/ParagraphWithSidebarSlide/index.tsx +80 -76
  81. package/Row/Quote/index.tsx +3 -3
  82. package/Row/SpecialBanner/index.tsx +97 -97
  83. package/Row/index.tsx +4 -9
  84. package/SectionContainer/index.tsx +32 -31
  85. package/SectionHeader/index.tsx +41 -43
  86. package/Separator/index.tsx +19 -18
  87. package/Snackbar/MessageSnackbar.tsx +1 -2
  88. package/Snackbar/MessageSnackbarImpl.tsx +68 -115
  89. package/StarRatingField/index.tsx +24 -25
  90. package/Stepper/Stepper.tsx +34 -32
  91. package/Styles/EmotionProvider.tsx +14 -0
  92. package/Styles/breakpointVal.tsx +16 -10
  93. package/Styles/extendableComponent.ts +70 -0
  94. package/Styles/index.tsx +9 -2
  95. package/Styles/withEmotionCache.tsx +36 -0
  96. package/Styles/withTheme.tsx +15 -24
  97. package/SvgIcon/SvgIcon.tsx +60 -0
  98. package/TextInputNumber/index.tsx +49 -50
  99. package/Theme/DarkLightModeThemeProvider.tsx +119 -0
  100. package/Theme/MuiButton.ts +128 -0
  101. package/Theme/MuiSlider.ts +28 -0
  102. package/Theme/MuiSnackbar.ts +31 -0
  103. package/Theme/{types.ts → createTheme.ts} +8 -2
  104. package/Theme/index.ts +5 -0
  105. package/Theme/themeDefaults.ts +51 -0
  106. package/TimeAgo/index.tsx +1 -1
  107. package/ToggleButton/index.tsx +43 -49
  108. package/ToggleButtonGroup/index.tsx +39 -39
  109. package/UspList/UspListItem.tsx +56 -46
  110. package/UspList/index.tsx +29 -26
  111. package/docs/building-components.mdx +3 -0
  112. package/docs/components/ComponentBasic.tsx +26 -0
  113. package/docs/components/ComponentChild.tsx +48 -0
  114. package/docs/components/ComponentChildVariant.tsx +54 -0
  115. package/docs/components/ComponentChildVariantExtendable.tsx +62 -0
  116. package/docs/components/ComponentStylable.tsx +32 -0
  117. package/docs/pages/building-components.tsx +62 -0
  118. package/icons/index.tsx +2 -0
  119. package/index.ts +27 -81
  120. package/package.json +27 -27
  121. package/types.d.ts +1 -1
  122. package/AppShell/AppShellSticky/index.tsx +0 -38
  123. package/AppShell/DesktopNavActions.tsx +0 -32
  124. package/AppShell/DesktopNavBar.tsx +0 -158
  125. package/AppShell/Logo.tsx +0 -46
  126. package/AppShell/Menu.tsx +0 -7
  127. package/AppShell/MenuFab.tsx +0 -162
  128. package/AppShell/MenuFabSecondaryItem.tsx +0 -32
  129. package/AppShell/index.ts +0 -15
  130. package/AspectRatioContainer/index.tsx +0 -27
  131. package/Footer/SocialIcon.tsx +0 -23
  132. package/Form/index.tsx +0 -67
  133. package/FramerScroller/components/SidebarGallery.tsx +0 -317
  134. package/FramerScroller/components/SidebarSlider.tsx +0 -97
  135. package/Page/App.tsx +0 -17
  136. package/Page/Document.tsx +0 -24
  137. package/StyledBadge/index.tsx +0 -20
  138. package/Styles/classesPicker.ts +0 -41
  139. package/SvgImage/SvgImageSimple.tsx +0 -100
  140. package/SvgImage/index.tsx +0 -74
@@ -1,55 +1,49 @@
1
- import { makeStyles, Theme } from '@material-ui/core'
1
+ import { Box, ContainerProps } from '@mui/material'
2
2
  import React from 'react'
3
- import Row from '..'
4
- import { UseStyles } from '../../Styles'
3
+ import { Row } from '..'
4
+ import { extendableComponent } from '../../Styles'
5
5
 
6
- const useStyles = makeStyles(
7
- (theme: Theme) => ({
8
- root: {
9
- display: 'grid',
10
- gap: `${theme.spacings.lg} 0`,
11
- gridTemplateAreas: `
12
- "top"
13
- "left"
14
- "right"
15
- `,
16
- [theme.breakpoints.up('md')]: {
17
- gridTemplateAreas: `
18
- "top ."
19
- "left right"
20
- `,
21
- gridTemplateColumns: '1fr auto',
22
- gap: `${theme.spacings.sm} ${theme.spacings.xxl}`,
23
- },
24
- },
25
- top: {
26
- gridArea: 'top',
27
- },
28
- left: {
29
- gridArea: 'left',
30
- },
31
- right: {
32
- gridArea: 'right',
33
- },
34
- }),
35
- { name: 'ColumnTwoWithTop' },
36
- )
37
-
38
- export type ColumnTwoWithTopProps = UseStyles<typeof useStyles> & {
6
+ export type ColumnTwoWithTopProps = ContainerProps & {
39
7
  top: React.ReactNode
40
8
  left: React.ReactNode
41
9
  right: React.ReactNode
42
10
  }
43
11
 
44
- export default function ColumnTwoWithTop(props: ColumnTwoWithTopProps) {
45
- const { top, left, right } = props
46
- const classes = useStyles(props)
12
+ const compName = 'ColumnTwoWithTop' as const
13
+ const parts = ['root', 'colOne', 'colTwo'] as const
14
+ const { classes } = extendableComponent(compName, parts)
15
+
16
+ export function ColumnTwoWithTop(props: ColumnTwoWithTopProps) {
17
+ const { left, right, top, sx = [], ...containerProps } = props
47
18
 
48
19
  return (
49
- <Row className={classes.root}>
50
- <div className={classes.top}>{top}</div>
51
- <div className={classes.left}>{left}</div>
52
- <div className={classes.right}>{right}</div>
20
+ <Row
21
+ maxWidth='lg'
22
+ className={classes.root}
23
+ sx={[
24
+ (theme) => ({
25
+ display: 'grid',
26
+ gap: `${theme.spacings.lg} 0`,
27
+ gridTemplateAreas: `"top" "left" "right"`,
28
+ [theme.breakpoints.up('md')]: {
29
+ gridTemplateAreas: `"top ." "left right"`,
30
+ gridTemplateColumns: '1fr auto',
31
+ gap: `${theme.spacings.sm} ${theme.spacings.xxl}`,
32
+ },
33
+ }),
34
+ ...(Array.isArray(sx) ? sx : [sx]),
35
+ ]}
36
+ {...containerProps}
37
+ >
38
+ <Box className={classes.colOne} gridArea='top'>
39
+ {top}
40
+ </Box>
41
+ <Box className={classes.colOne} gridArea='left'>
42
+ {left}
43
+ </Box>
44
+ <Box className={classes.colTwo} gridArea='right'>
45
+ {right}
46
+ </Box>
53
47
  </Row>
54
48
  )
55
49
  }
@@ -1,39 +1,38 @@
1
1
  import { Scroller, ScrollerProvider } from '@graphcommerce/framer-scroller'
2
- import { Container, makeStyles, Theme, Typography } from '@material-ui/core'
2
+ import { Container, SxProps, Theme, Typography } from '@mui/material'
3
3
  import React from 'react'
4
- import { UseStyles } from '../../Styles'
4
+ import { extendableComponent } from '../../Styles'
5
5
 
6
- const useStyles = makeStyles(
7
- (theme: Theme) => ({
8
- root: {
9
- marginBottom: `${theme.spacings.lg}`,
10
- },
11
- scroller: {
12
- justifyContent: 'start',
13
- gap: `${theme.spacings.md}`,
14
- gridAutoColumns: `max-content`,
15
- },
16
- title: {
17
- fontWeight: 600,
18
- },
19
- }),
20
- { name: 'ContentLinks' },
21
- )
22
-
23
- export type ContentLinksProps = UseStyles<typeof useStyles> & {
6
+ export type ContentLinksProps = {
24
7
  title: string
25
8
  children: React.ReactNode
9
+ sx?: SxProps<Theme>
26
10
  }
27
11
 
28
- export default function ContentLinks(props: ContentLinksProps) {
12
+ const compName = 'ContentLinks' as const
13
+ const parts = ['root', 'scroller', 'title'] as const
14
+ const { classes } = extendableComponent(compName, parts)
15
+
16
+ export function ContentLinks(props: ContentLinksProps) {
29
17
  const { title, children } = props
30
- const classes = useStyles(props)
31
18
 
32
19
  return (
33
- <Container className={classes.root} maxWidth={false}>
20
+ <Container
21
+ className={classes.root}
22
+ maxWidth={false}
23
+ sx={(theme) => ({ marginBottom: `${theme.spacings.md}` })}
24
+ >
34
25
  <ScrollerProvider scrollSnapAlign='none'>
35
- <Scroller className={classes.scroller} hideScrollbar>
36
- <Typography variant='body1' component='h3' className={classes.title}>
26
+ <Scroller
27
+ className={classes.scroller}
28
+ hideScrollbar
29
+ sx={(theme) => ({
30
+ justifyContent: 'start',
31
+ gap: `${theme.spacings.md}`,
32
+ gridAutoColumns: `max-content`,
33
+ })}
34
+ >
35
+ <Typography variant='subtitle1' component='h3' className={classes.title}>
37
36
  {title}
38
37
  </Typography>
39
38
  {children}
@@ -1,89 +1,33 @@
1
- import { ContainerProps, Theme, makeStyles, useTheme, useMediaQuery } from '@material-ui/core'
1
+ import { ContainerProps, useTheme, useMediaQuery, Box, styled } from '@mui/material'
2
2
  import { m, useTransform } from 'framer-motion'
3
3
  import React from 'react'
4
- import Row from '..'
4
+ import { Row } from '..'
5
5
  import { useScrollY } from '../../Layout/hooks/useScrollY'
6
- import { UseStyles } from '../../Styles'
6
+ import { extendableComponent } from '../../Styles'
7
7
  import { responsiveVal } from '../../Styles/responsiveVal'
8
8
 
9
- const useStyles = makeStyles(
10
- (theme: Theme) => ({
11
- wrapper: {
12
- position: 'relative',
13
- },
14
- copy: {
15
- zIndex: 1,
16
- color: theme.palette.secondary.contrastText,
17
- position: 'relative',
18
- display: 'grid',
19
- justifyItems: 'center',
20
- alignContent: 'center',
21
- padding: `${theme.spacings.lg} ${theme.spacings.md}`,
22
- paddingTop: `calc(${theme.spacings.lg} - ${theme.spacings.md})`,
23
- minHeight: `calc(100vh - ${theme.appShell.headerHeightSm})`,
24
- '& > *': {
25
- zIndex: 1,
26
- maxWidth: 'max-content',
27
- },
28
- [theme.breakpoints.up('md')]: {
29
- width: '70%',
30
- minHeight: `calc(100vh - ${theme.appShell.headerHeightMd})`,
31
- },
32
- [theme.breakpoints.up('lg')]: {
33
- padding: `${theme.spacings.lg} ${theme.spacings.lg}`,
34
- paddingTop: `calc(${theme.spacings.lg} - ${theme.spacings.md})`,
35
- width: '50%',
36
- },
37
- },
38
- asset: {
39
- position: 'absolute',
40
- top: '0',
41
- zIndex: 0,
42
- width: '100%',
43
- height: '100%',
44
- display: 'grid',
45
- justifyItems: 'center',
46
- overflow: 'hidden',
47
- paddingBottom: theme.page.horizontal,
48
- '& video': {
49
- objectFit: 'cover',
50
- width: '100%',
51
- height: '100%',
52
- [theme.breakpoints.down('sm')]: {
53
- borderRadius: responsiveVal(theme.shape.borderRadius * 2, theme.shape.borderRadius * 3),
54
- },
55
- },
56
- [theme.breakpoints.up('md')]: {
57
- height: '100%',
58
- },
59
- },
60
- animated: {
61
- borderRadius: responsiveVal(theme.shape.borderRadius * 2, theme.shape.borderRadius * 3),
62
- overflow: 'hidden',
63
- transform: 'translateZ(0)',
64
- },
65
- }),
66
- { name: 'HeroBanner' },
67
- )
9
+ export type HeroBannerProps = ContainerProps & {
10
+ pageLinks: React.ReactNode
11
+ videoSrc: string
12
+ children: React.ReactNode
13
+ }
14
+
15
+ const compName = 'HeroBanner' as const
16
+ const parts = ['root', 'wrapper', 'copy', 'asset', 'animated', 'video'] as const
17
+ const { classes } = extendableComponent(compName, parts)
68
18
 
69
- export type HeroBannerProps = UseStyles<typeof useStyles> &
70
- ContainerProps & {
71
- pageLinks: React.ReactNode
72
- videoSrc: string
73
- children: React.ReactNode
74
- }
19
+ const MotionDiv = styled(m.div)({})
75
20
 
76
- export default function HeroBanner(props: HeroBannerProps) {
21
+ export function HeroBanner(props: HeroBannerProps) {
77
22
  const { pageLinks, videoSrc, children, ...containerProps } = props
78
- const classes = useStyles(props)
79
- const theme = useTheme()
23
+ const t = useTheme()
80
24
  const scrollY = useScrollY()
81
25
  const width = useTransform(
82
26
  scrollY,
83
27
  [10, 150],
84
28
  [`calc(100% - ${responsiveVal(20, 60)}))`, `calc(100% - ${responsiveVal(0, 0)})`],
85
29
  )
86
- const matches = useMediaQuery(theme.breakpoints.down('sm'))
30
+ const matches = useMediaQuery(t.breakpoints.down('md'))
87
31
  const borderRadius = useTransform(
88
32
  scrollY,
89
33
  [10, 150],
@@ -91,18 +35,90 @@ export default function HeroBanner(props: HeroBannerProps) {
91
35
  )
92
36
 
93
37
  return (
94
- <Row maxWidth={false} {...containerProps} disableGutters>
95
- <div className={classes.wrapper}>
96
- <div className={classes.copy}>
38
+ <Row maxWidth={false} {...containerProps} disableGutters className={classes.root}>
39
+ <Box className={classes.wrapper} sx={{ position: 'relative' }}>
40
+ <Box
41
+ className={classes.copy}
42
+ sx={(theme) => ({
43
+ zIndex: 1,
44
+ color: theme.palette.secondary.contrastText,
45
+ position: 'relative',
46
+ display: 'grid',
47
+ justifyItems: 'center',
48
+ alignContent: 'center',
49
+ padding: `${theme.spacings.lg} ${theme.spacings.md}`,
50
+ paddingTop: `calc(${theme.spacings.lg} - ${theme.spacings.md})`,
51
+ minHeight: `calc(100vh - ${theme.appShell.headerHeightSm})`,
52
+ '& > *': {
53
+ zIndex: 1,
54
+ maxWidth: 'max-content',
55
+ },
56
+ [theme.breakpoints.up('md')]: {
57
+ width: '70%',
58
+ minHeight: `calc(100vh - ${theme.appShell.headerHeightMd})`,
59
+ },
60
+ [theme.breakpoints.up('lg')]: {
61
+ padding: `${theme.spacings.lg} ${theme.spacings.lg}`,
62
+ paddingTop: `calc(${theme.spacings.lg} - ${theme.spacings.md})`,
63
+ width: '50%',
64
+ },
65
+ })}
66
+ >
97
67
  {children}
98
68
  {pageLinks}
99
- </div>
100
- <div className={classes.asset}>
101
- <m.div style={{ width: !matches ? width : 0, borderRadius }} className={classes.animated}>
102
- <video src={videoSrc} autoPlay muted loop playsInline disableRemotePlayback />
103
- </m.div>
104
- </div>
105
- </div>
69
+ </Box>
70
+ <Box
71
+ className={classes.asset}
72
+ sx={(theme) => ({
73
+ position: 'absolute',
74
+ top: '0',
75
+ zIndex: 0,
76
+ width: '100%',
77
+ height: '100%',
78
+ display: 'grid',
79
+ justifyItems: 'center',
80
+ overflow: 'hidden',
81
+ paddingBottom: theme.page.horizontal,
82
+ '& video': {
83
+ objectFit: 'cover',
84
+ width: '100%',
85
+ height: '100%',
86
+ [theme.breakpoints.down('md')]: {
87
+ borderRadius: responsiveVal(
88
+ theme.shape.borderRadius * 2,
89
+ theme.shape.borderRadius * 3,
90
+ ),
91
+ },
92
+ },
93
+ [theme.breakpoints.up('md')]: {
94
+ height: '100%',
95
+ },
96
+ })}
97
+ >
98
+ <MotionDiv
99
+ style={{ width: !matches ? width : 0, borderRadius }}
100
+ className={classes.animated}
101
+ sx={(theme) => ({
102
+ borderRadius: responsiveVal(
103
+ theme.shape.borderRadius * 2,
104
+ theme.shape.borderRadius * 3,
105
+ ),
106
+ overflow: 'hidden',
107
+ transform: 'translateZ(0)',
108
+ })}
109
+ >
110
+ <video
111
+ src={videoSrc}
112
+ autoPlay
113
+ muted
114
+ loop
115
+ playsInline
116
+ disableRemotePlayback
117
+ className={classes.video}
118
+ />
119
+ </MotionDiv>
120
+ </Box>
121
+ </Box>
106
122
  </Row>
107
123
  )
108
124
  }
@@ -1,63 +1,71 @@
1
- import { makeStyles, Theme, Typography } from '@material-ui/core'
1
+ import { Typography, Button, SxProps, Theme, Box } from '@mui/material'
2
2
  import React from 'react'
3
- import Button from '../../../Button'
4
- import { UseStyles } from '../../../Styles'
3
+ import { extendableComponent } from '../../../Styles'
5
4
 
6
- const useStyles = makeStyles(
7
- (theme: Theme) => ({
8
- block: {
9
- border: `1px solid ${theme.palette.divider}`,
10
- padding: `${theme.spacings.sm}`,
11
- borderRadius: '6px',
12
- textAlign: 'center',
13
- color: theme.palette.text.primary,
14
- '& > * > *': {
15
- display: 'grid',
16
- gridAutoFlow: 'row',
17
- justifyItems: 'center',
18
- gap: `${theme.spacings.xxs}`,
19
- },
20
- },
21
- link: {
22
- textDecoration: 'none',
23
- },
24
- title: {
25
- fontWeight: theme.typography.fontWeightBold,
26
- },
27
- }),
28
- { name: 'IconBlock' },
29
- )
30
-
31
- export type IconBlockProps = UseStyles<typeof useStyles> & {
5
+ export type IconBlockProps = {
32
6
  title: string
33
7
  icon: React.ReactNode
34
8
  children: React.ReactNode
35
9
  href?: string
10
+ sx?: SxProps<Theme>
36
11
  }
37
12
 
38
- const IconBlock = React.forwardRef<HTMLAnchorElement, IconBlockProps>((props, ref) => {
39
- const { title, children, icon, href } = props
40
- const classes = useStyles(props)
13
+ const name = 'IconBlock' as const
14
+ const parts = ['block', 'link', 'title'] as const
15
+ const { classes } = extendableComponent(name, parts)
16
+
17
+ export const IconBlock = React.forwardRef<HTMLAnchorElement, IconBlockProps>((props, ref) => {
18
+ const { title, children, icon, href, sx = [] } = props
41
19
 
42
20
  const content = (
43
21
  <>
44
22
  {icon}
45
- <Typography variant='subtitle1' className={classes.title}>
23
+ <Typography
24
+ variant='subtitle1'
25
+ className={classes.title}
26
+ sx={(theme) => ({ fontWeight: theme.typography.fontWeightBold })}
27
+ >
46
28
  {title}
47
29
  </Typography>
48
30
  {children}
49
31
  </>
50
32
  )
51
33
 
34
+ const blockSx: SxProps<Theme> = [
35
+ (theme) => ({
36
+ border: `1px solid ${theme.palette.divider}`,
37
+ padding: `${theme.spacings.sm}`,
38
+ borderRadius: '6px',
39
+ textAlign: 'center',
40
+ color: theme.palette.text.primary,
41
+ '& > *': {
42
+ display: 'grid',
43
+ gridAutoFlow: 'row',
44
+ justifyItems: 'center',
45
+ gap: `${theme.spacings.xxs}`,
46
+ },
47
+ }),
48
+ ...(Array.isArray(sx) ? sx : [sx]),
49
+ ]
50
+
52
51
  if (href) {
53
52
  return (
54
- <Button href={href} variant='text' color='primary' className={classes.block} ref={ref}>
53
+ <Button
54
+ href={href}
55
+ variant='text'
56
+ color='primary'
57
+ className={classes.block}
58
+ ref={ref}
59
+ sx={blockSx}
60
+ >
55
61
  <div>{content}</div>
56
62
  </Button>
57
63
  )
58
64
  }
59
65
 
60
- return <div className={classes.block}>{content}</div>
66
+ return (
67
+ <Box className={classes.block} sx={blockSx}>
68
+ {content}
69
+ </Box>
70
+ )
61
71
  })
62
-
63
- export default IconBlock
@@ -1,57 +1,42 @@
1
- import { makeStyles, Theme, Typography } from '@material-ui/core'
1
+ import { Box, SxProps, Theme } from '@mui/material'
2
2
  import React from 'react'
3
- import Row from '..'
4
- import { UseStyles } from '../../Styles'
3
+ import { Row } from '..'
4
+ import { extendableComponent } from '../../Styles'
5
5
  import { responsiveVal } from '../../Styles/responsiveVal'
6
6
 
7
- const useStyles = makeStyles(
8
- (theme: Theme) => ({
9
- container: {
10
- maxWidth: 820,
11
- },
12
- title: {
13
- marginBottom: `${theme.spacings.md}`,
14
- },
15
- optionsWrapper: {
16
- display: 'grid',
17
- gridTemplateColumns: `repeat(auto-fill, minmax(${responsiveVal(150, 280)}, 1fr))`,
18
- gap: `${theme.spacings.sm}`,
19
- },
20
- block: {
21
- display: 'grid',
22
- gridAutoFlow: 'row',
23
- justifyItems: 'center',
24
- gap: `${theme.spacings.xs}`,
25
- border: `1px solid ${theme.palette.divider}`,
26
- padding: `${theme.spacings.sm}`,
27
- borderRadius: '6px',
28
- cursor: 'pointer',
29
- textAlign: 'center',
30
- },
31
- wrapper: {
32
- paddingTop: `${theme.spacings.lg}`,
33
- },
34
- }),
35
- { name: 'ServiceOptions' },
36
- )
37
-
38
- export type IconBlocksProps = UseStyles<typeof useStyles> & {
7
+ export type IconBlocksProps = {
39
8
  title: string
40
9
  children: React.ReactNode
10
+ sx?: SxProps<Theme>
41
11
  }
42
12
 
43
- export default function ServiceOptions(props: IconBlocksProps) {
44
- const { title, children } = props
45
- const classes = useStyles(props)
13
+ const compName = 'IconBlocks' as const
14
+ const parts = ['container', 'title', 'optionsWrapper', 'block', 'wrapper'] as const
15
+ const { classes } = extendableComponent(compName, parts)
16
+
17
+ export function IconBlocks(props: IconBlocksProps) {
18
+ const { title, children, sx = [] } = props
46
19
 
47
20
  return (
48
- <Row className={classes.container}>
49
- <div className={classes.wrapper}>
50
- <Typography variant='h5' className={classes.title}>
21
+ <Row className={classes.container} sx={[{ maxWidth: 820 }, ...(Array.isArray(sx) ? sx : [sx])]}>
22
+ <Box className={classes.wrapper} sx={(theme) => ({ paddingTop: `${theme.spacings.lg}` })}>
23
+ <Box
24
+ className={classes.title}
25
+ sx={(theme) => ({ typography: 'h5', marginBottom: `${theme.spacings.md}` })}
26
+ >
51
27
  {title}
52
- </Typography>
53
- <div className={classes.optionsWrapper}>{children}</div>
54
- </div>
28
+ </Box>
29
+ <Box
30
+ className={classes.optionsWrapper}
31
+ sx={(theme) => ({
32
+ display: 'grid',
33
+ gridTemplateColumns: `repeat(auto-fill, minmax(${responsiveVal(150, 280)}, 1fr))`,
34
+ gap: `${theme.spacings.sm}`,
35
+ })}
36
+ >
37
+ {children}
38
+ </Box>
39
+ </Box>
55
40
  </Row>
56
41
  )
57
42
  }