@graphcommerce/next-ui 3.25.1 → 4.0.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 (138) 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 +497 -636
  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 +21 -12
  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 +131 -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 -35
  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/MuiButton.ts +128 -0
  100. package/Theme/MuiSlider.ts +28 -0
  101. package/Theme/MuiSnackbar.ts +31 -0
  102. package/Theme/{types.ts → createTheme.ts} +8 -2
  103. package/Theme/index.ts +4 -0
  104. package/Theme/themeDefaults.ts +51 -0
  105. package/TimeAgo/index.tsx +1 -1
  106. package/ToggleButton/index.tsx +43 -49
  107. package/ToggleButtonGroup/index.tsx +39 -39
  108. package/UspList/UspListItem.tsx +56 -46
  109. package/UspList/index.tsx +29 -26
  110. package/docs/building-components.mdx +3 -0
  111. package/docs/components/ComponentBasic.tsx +26 -0
  112. package/docs/components/ComponentChild.tsx +48 -0
  113. package/docs/components/ComponentChildVariant.tsx +54 -0
  114. package/docs/components/ComponentChildVariantExtendable.tsx +62 -0
  115. package/docs/components/ComponentStylable.tsx +32 -0
  116. package/docs/pages/building-components.tsx +62 -0
  117. package/index.ts +27 -81
  118. package/package.json +25 -27
  119. package/types.d.ts +1 -1
  120. package/AppShell/AppShellSticky/index.tsx +0 -38
  121. package/AppShell/DesktopNavActions.tsx +0 -32
  122. package/AppShell/DesktopNavBar.tsx +0 -158
  123. package/AppShell/Logo.tsx +0 -46
  124. package/AppShell/Menu.tsx +0 -7
  125. package/AppShell/MenuFab.tsx +0 -162
  126. package/AppShell/MenuFabSecondaryItem.tsx +0 -32
  127. package/AppShell/index.ts +0 -15
  128. package/AspectRatioContainer/index.tsx +0 -27
  129. package/Footer/SocialIcon.tsx +0 -23
  130. package/Form/index.tsx +0 -67
  131. package/FramerScroller/components/SidebarGallery.tsx +0 -317
  132. package/FramerScroller/components/SidebarSlider.tsx +0 -97
  133. package/Page/App.tsx +0 -17
  134. package/Page/Document.tsx +0 -24
  135. package/StyledBadge/index.tsx +0 -20
  136. package/Styles/classesPicker.ts +0 -41
  137. package/SvgImage/SvgImageSimple.tsx +0 -100
  138. package/SvgImage/index.tsx +0 -74
@@ -1,14 +1,17 @@
1
+ import { styled, SxProps, Theme } from '@mui/material'
1
2
  import { HTMLMotionProps, m } from 'framer-motion'
2
3
  import { ReactHTML } from 'react'
3
4
 
4
5
  export type AnimatedRowProps = Omit<
5
6
  ReactHTML['div'] & HTMLMotionProps<'div'>,
6
7
  'layout' | 'initial' | 'animate' | 'exit' | 'transition'
7
- >
8
+ > & { sx?: SxProps<Theme> }
8
9
 
9
- export default function AnimatedRow(props: AnimatedRowProps) {
10
+ const StyledDiv = styled(m.div)({})
11
+
12
+ export function AnimatedRow(props: AnimatedRowProps) {
10
13
  return (
11
- <m.div
14
+ <StyledDiv
12
15
  {...props}
13
16
  layout
14
17
  initial={{ opacity: 0, height: 0 }}
@@ -1,35 +1,25 @@
1
- import { ApolloError } from '@apollo/client'
2
- import { makeStyles, Theme } from '@material-ui/core'
3
- import { Alert, AlertProps } from '@material-ui/lab'
1
+ import { ApolloError } from '@graphcommerce/graphql'
2
+ import { AlertProps, Alert, Box, SxProps, Theme } from '@mui/material'
4
3
  import { AnimatePresence } from 'framer-motion'
5
- import React from 'react'
6
- import AnimatedRow from '../AnimatedRow'
4
+ import { AnimatedRow } from '../AnimatedRow'
5
+ import { extendableComponent } from '../Styles/extendableComponent'
7
6
 
8
- export const useStyles = makeStyles(
9
- (theme: Theme) => ({
10
- alerts: {},
11
- alert: {
12
- paddingTop: `calc(${theme.spacings.xxs} / 2)`,
13
- paddingBottom: `calc(${theme.spacings.xxs} / 2)`,
14
- },
15
- }),
16
- { name: 'ApolloErrorAlert' },
17
- )
7
+ const { classes, selectors } = extendableComponent('ApolloErrorAlert', ['root', 'alert'] as const)
18
8
 
19
9
  export type ApolloErrorAlertProps = {
20
10
  error?: ApolloError
21
11
  graphqlErrorAlertProps?: Omit<AlertProps, 'severity'>
22
12
  networkErrorAlertProps?: Omit<AlertProps, 'severity'>
13
+ sx?: SxProps<Theme>
23
14
  }
24
15
  export default function ApolloErrorAlert(props: ApolloErrorAlertProps) {
25
- const classes = useStyles()
26
- const { error, graphqlErrorAlertProps, networkErrorAlertProps } = props
16
+ const { error, graphqlErrorAlertProps, networkErrorAlertProps, sx } = props
27
17
 
28
18
  return (
29
19
  <AnimatePresence initial={false}>
30
20
  {error && (
31
21
  <AnimatedRow key='alerts'>
32
- <div className={classes.alerts}>
22
+ <Box sx={sx} className={classes.root}>
33
23
  <AnimatePresence initial={false}>
34
24
  {error.graphQLErrors.map((e, index) => (
35
25
  // eslint-disable-next-line react/no-array-index-key
@@ -43,17 +33,26 @@ export default function ApolloErrorAlert(props: ApolloErrorAlertProps) {
43
33
  ))}
44
34
  {error.networkError && (
45
35
  <AnimatedRow key='networkError'>
46
- <div className={classes.alert} key='networkError'>
36
+ <Box
37
+ sx={(theme) => ({
38
+ paddingTop: theme.spacings.xxs,
39
+ paddingBottom: theme.spacings.xxs,
40
+ })}
41
+ className={classes.alert}
42
+ key='networkError'
43
+ >
47
44
  <Alert severity='error' {...networkErrorAlertProps}>
48
45
  Network Error: {error.networkError.message}
49
46
  </Alert>
50
- </div>
47
+ </Box>
51
48
  </AnimatedRow>
52
49
  )}
53
50
  </AnimatePresence>
54
- </div>
51
+ </Box>
55
52
  </AnimatedRow>
56
53
  )}
57
54
  </AnimatePresence>
58
55
  )
59
56
  }
57
+
58
+ ApolloErrorAlert.selectors = selectors
@@ -1,7 +1,6 @@
1
- import { ApolloError } from '@apollo/client'
2
- import { AlertProps } from '@material-ui/lab'
3
- import React from 'react'
4
- import FullPageMessage, { FullPageMessageProps } from '../FullPageMessage'
1
+ import { ApolloError } from '@graphcommerce/graphql'
2
+ import { AlertProps } from '@mui/material'
3
+ import { FullPageMessage, FullPageMessageProps } from '../FullPageMessage'
5
4
  import ApolloErrorAlert from './ApolloErrorAlert'
6
5
 
7
6
  export type ApolloErrorFullPageProps = {
@@ -1,7 +1,7 @@
1
- import { ApolloError } from '@apollo/client'
1
+ import { ApolloError } from '@graphcommerce/graphql'
2
2
  import { Trans } from '@lingui/macro'
3
- import Button from '../Button'
4
- import MessageSnackbar from '../Snackbar/MessageSnackbar'
3
+ import { Button } from '@mui/material'
4
+ import { MessageSnackbar } from '../Snackbar/MessageSnackbar'
5
5
  import { MessageSnackbarImplProps } from '../Snackbar/MessageSnackbarImpl'
6
6
 
7
7
  export type ApolloErrorSnackbarProps = {
@@ -1,68 +1,62 @@
1
- import { Avatar, Chip, makeStyles, Theme } from '@material-ui/core'
2
- import React from 'react'
3
- import { UseStyles } from '../../Styles'
1
+ import { Avatar, Box, Chip, SxProps } from '@mui/material'
2
+ import { useRouter } from 'next/router'
3
+ import { useMemo } from 'react'
4
4
  import { responsiveVal } from '../../Styles/responsiveVal'
5
5
 
6
- const useStyles = makeStyles(
7
- (theme: Theme) => ({
8
- wrapper: {
9
- display: 'flex',
10
- justifyContent: 'left',
11
- maxWidth: 800,
12
- margin: `0 auto`,
13
- marginBottom: theme.spacings.md,
14
- },
15
- authorChip: {
16
- height: responsiveVal(44, 66),
17
- '& .MuiChip-label': {
18
- paddingLeft: responsiveVal(10, 14),
19
- paddingRight: responsiveVal(14, 18),
20
- },
21
- '& .MuiAvatar-root': {
22
- width: responsiveVal(28, 44),
23
- height: responsiveVal(28, 44),
24
- },
25
- },
26
- date: {
27
- lineHeight: 1.4,
28
- color: theme.palette.text.disabled,
29
- },
30
- author: {
31
- lineHeight: 1.4,
32
- },
33
- }),
34
- { name: 'BlogAuthor' },
35
- )
36
-
37
- export type BlogAuthorProps = UseStyles<typeof useStyles> & {
6
+ export type BlogAuthorProps = {
38
7
  author: string
39
8
  date: string
40
- locale: string
9
+ sx?: SxProps
41
10
  }
42
11
 
43
- export default function BlogAuthor(props: BlogAuthorProps) {
44
- const { author, date, locale } = props
45
- const classes = useStyles()
12
+ export function BlogAuthor(props: BlogAuthorProps) {
13
+ const { author, date, sx = [] } = props
46
14
 
47
- const formatter = new Intl.DateTimeFormat(locale, {
48
- month: 'long',
49
- day: 'numeric',
50
- })
15
+ const { locale } = useRouter()
16
+ const formatter = useMemo(
17
+ () => new Intl.DateTimeFormat(locale, { month: 'long', day: 'numeric' }),
18
+ [locale],
19
+ )
51
20
 
52
21
  return (
53
- <div className={classes.wrapper}>
22
+ <Box
23
+ sx={[
24
+ {
25
+ display: 'flex',
26
+ justifyContent: 'left',
27
+ maxWidth: 800,
28
+ margin: `0 auto`,
29
+ marginBottom: (theme) => theme.spacings.md,
30
+ },
31
+ ...(Array.isArray(sx) ? sx : [sx]),
32
+ ]}
33
+ >
54
34
  <Chip
35
+ sx={{
36
+ height: responsiveVal(44, 66),
37
+ '& .MuiChip-label': {
38
+ paddingLeft: responsiveVal(10, 14),
39
+ paddingRight: responsiveVal(14, 18),
40
+ },
41
+ '& .MuiAvatar-root': {
42
+ width: responsiveVal(28, 44),
43
+ height: responsiveVal(28, 44),
44
+ },
45
+ }}
55
46
  variant='outlined'
56
47
  size='medium'
57
48
  avatar={<Avatar>{author.charAt(0).toUpperCase()}</Avatar>}
58
- className={classes.authorChip}
59
49
  label={
60
50
  <section>
61
- <div className={classes.author}>{author}</div>
62
- <div className={classes.date}>{formatter.format(new Date(date))}</div>
51
+ <Box slot='Author' sx={{ lineHeight: 1.4 }}>
52
+ {author}
53
+ </Box>
54
+ <Box sx={(theme) => ({ lineHeight: 1.4, color: theme.palette.text.disabled })}>
55
+ {formatter.format(new Date(date))}
56
+ </Box>
63
57
  </section>
64
58
  }
65
59
  />
66
- </div>
60
+ </Box>
67
61
  )
68
62
  }
@@ -1,24 +1,7 @@
1
- import { makeStyles, Theme } from '@material-ui/core'
2
- import React from 'react'
1
+ import { styled } from '@mui/material'
3
2
 
4
- const useStyles = makeStyles(
5
- (theme: Theme) => ({
6
- wrapper: {
7
- maxWidth: 800,
8
- margin: '0 auto',
9
- marginBottom: theme.spacings.sm,
10
- },
11
- }),
12
- { name: 'BlogContent' },
13
- )
14
-
15
- export type BlogContentProps = {
16
- content: React.ReactElement
17
- }
18
-
19
- export default function BlogContent(props: BlogContentProps) {
20
- const { content } = props
21
- const classes = useStyles()
22
-
23
- return <div className={classes.wrapper}>{content}</div>
24
- }
3
+ export const BlogContent = styled('div')(({ theme }) => ({
4
+ maxWidth: 800,
5
+ margin: '0 auto',
6
+ marginBottom: theme.spacings.sm,
7
+ }))
@@ -1,33 +1,36 @@
1
- import { makeStyles, Theme } from '@material-ui/core'
1
+ import { Box, SxProps, Theme } from '@mui/material'
2
2
  import React from 'react'
3
- import { UseStyles } from '../../Styles'
3
+ import { extendableComponent } from '../../Styles'
4
4
  import { responsiveVal } from '../../Styles/responsiveVal'
5
5
 
6
- const useStyles = makeStyles(
7
- (theme: Theme) => ({
8
- header: {
9
- maxWidth: 800,
10
- margin: `0 auto`,
11
- marginBottom: theme.spacings.md,
12
- },
13
- asset: {
14
- '& img': {
15
- borderRadius: responsiveVal(theme.shape.borderRadius * 2, theme.shape.borderRadius * 3),
16
- },
17
- },
18
- }),
19
- { name: 'BlogHeader' },
20
- )
21
-
22
- export type BlogHeaderProps = UseStyles<typeof useStyles> & {
6
+ export type BlogHeaderProps = {
7
+ sx?: SxProps<Theme>
23
8
  asset?: React.ReactNode
24
9
  }
25
10
 
26
- export default function BlogHeader(props: BlogHeaderProps) {
27
- const { asset } = props
28
- const classes = useStyles()
11
+ const name = 'BlogHeader' as const
12
+ const parts = ['header', 'asset'] as const
13
+ const { classes } = extendableComponent(name, parts)
14
+
15
+ export function BlogHeader(props: BlogHeaderProps) {
16
+ const { asset, sx = [] } = props
29
17
 
30
18
  return (
31
- <div className={classes.header}>{asset && <div className={classes.asset}>{asset}</div>}</div>
19
+ <Box
20
+ className={classes.header}
21
+ sx={[
22
+ (theme) => ({
23
+ maxWidth: 800,
24
+ margin: `0 auto`,
25
+ marginBottom: theme.spacings.md,
26
+ '& img': {
27
+ borderRadius: responsiveVal(theme.shape.borderRadius * 2, theme.shape.borderRadius * 3),
28
+ },
29
+ }),
30
+ ...(Array.isArray(sx) ? sx : [sx]),
31
+ ]}
32
+ >
33
+ {asset}
34
+ </Box>
32
35
  )
33
36
  }
@@ -1,27 +1,9 @@
1
- import { makeStyles, Theme } from '@material-ui/core'
2
- import React from 'react'
3
- import Row from '../../Row'
4
- import { UseStyles } from '../../Styles'
1
+ import { styled } from '@mui/material'
2
+ import { Row } from '../../Row'
5
3
  import { responsiveVal } from '../../Styles/responsiveVal'
6
4
 
7
- const useStyles = makeStyles(
8
- (theme: Theme) => ({
9
- root: {
10
- display: 'grid',
11
- gap: theme.spacings.md,
12
- gridTemplateColumns: `repeat(auto-fill, minmax(${responsiveVal(150, 285)}, 1fr))`,
13
- },
14
- }),
15
- { name: 'BlogList' },
16
- )
17
-
18
- export type BlogListProps = UseStyles<typeof useStyles> & {
19
- children: React.ReactElement
20
- }
21
-
22
- export default function BlogList(props: BlogListProps) {
23
- const { children } = props
24
- const classes = useStyles()
25
-
26
- return <Row className={classes.root}>{children}</Row>
27
- }
5
+ export const BlogItemGrid = styled(Row, { name: 'BlogList' })(({ theme }) => ({
6
+ display: 'grid',
7
+ gap: theme.spacings.md,
8
+ gridTemplateColumns: `repeat(auto-fill, minmax(${responsiveVal(150, 285)}, 1fr))`,
9
+ }))
@@ -1,58 +1,24 @@
1
- import { Link, makeStyles, Theme, Typography } from '@material-ui/core'
1
+ import { Box, Link, SxProps, Theme, Typography } from '@mui/material'
2
2
  import PageLink from 'next/link'
3
3
  import React from 'react'
4
- import { UseStyles } from '../../Styles'
4
+ import { extendableComponent } from '../../Styles'
5
5
  import { responsiveVal } from '../../Styles/responsiveVal'
6
6
 
7
- const useStyles = makeStyles(
8
- (theme: Theme) => ({
9
- item: {
10
- display: 'grid',
11
- gridTemplateRows: `${responsiveVal(140, 220)} auto auto`,
12
- alignContent: 'start',
13
- color: theme.palette.text.primary,
14
- gap: theme.spacings.sm,
15
- marginBottom: theme.spacings.sm,
16
- },
17
- date: {
18
- display: 'inline-block',
19
- textDecoration: 'none',
20
- color: theme.palette.text.secondary,
21
- },
22
- asset: {
23
- display: 'grid',
24
- overflow: 'hidden',
25
- height: '100%',
26
- width: '100%',
27
- borderRadius: responsiveVal(theme.shape.borderRadius * 2, theme.shape.borderRadius * 3),
28
- '& img': {
29
- height: '100% !important',
30
- objectFit: 'cover',
31
- },
32
- '& p': {
33
- alignSelf: 'center',
34
- justifySelf: 'center',
35
- },
36
- background: theme.palette.background.paper,
37
- },
38
- title: {
39
- ...theme.typography.h3,
40
- },
41
- }),
42
- { name: 'BlogListItem' },
43
- )
44
-
45
- export type BlogListItemProps = UseStyles<typeof useStyles> & {
7
+ export type BlogListItemProps = {
46
8
  asset: React.ReactNode
47
9
  url: string
48
10
  date: string
49
11
  locale: string
50
12
  title: string
13
+ sx?: SxProps<Theme>
51
14
  }
52
15
 
53
- export default function BlogListItem(props: BlogListItemProps) {
54
- const { asset, url, date, locale, title } = props
55
- const classes = useStyles(props)
16
+ const name = 'BlogListItem' as const
17
+ const parts = ['item', 'date', 'asset', 'title'] as const
18
+ const { classes } = extendableComponent(name, parts)
19
+
20
+ export function BlogListItem(props: BlogListItemProps) {
21
+ const { asset, url, date, locale, title, sx = [] } = props
56
22
 
57
23
  const formatter = new Intl.DateTimeFormat(locale, {
58
24
  year: 'numeric',
@@ -61,24 +27,69 @@ export default function BlogListItem(props: BlogListItemProps) {
61
27
  })
62
28
 
63
29
  return (
64
- <div className={classes.item}>
30
+ <Box
31
+ className={classes.item}
32
+ sx={[
33
+ (theme) => ({
34
+ display: 'grid',
35
+ gridTemplateRows: `${responsiveVal(140, 220)} auto auto`,
36
+ alignContent: 'start',
37
+ color: theme.palette.text.primary,
38
+ gap: theme.spacings.xxs,
39
+ marginBottom: theme.spacings.sm,
40
+ }),
41
+ ...(Array.isArray(sx) ? sx : [sx]),
42
+ ]}
43
+ >
65
44
  <PageLink href={`/${url}`} passHref>
66
- <Link color='inherit'>
67
- <div className={classes.asset}>{asset}</div>
45
+ <Link color='inherit' underline='hover'>
46
+ <Box
47
+ className={classes.asset}
48
+ sx={(theme) => ({
49
+ display: 'grid',
50
+ overflow: 'hidden',
51
+ height: '100%',
52
+ width: '100%',
53
+ borderRadius: responsiveVal(
54
+ theme.shape.borderRadius * 2,
55
+ theme.shape.borderRadius * 3,
56
+ ),
57
+ '& img': {
58
+ height: '100% !important',
59
+ objectFit: 'cover',
60
+ },
61
+ '& p': {
62
+ alignSelf: 'center',
63
+ justifySelf: 'center',
64
+ },
65
+ background: theme.palette.background.paper,
66
+ })}
67
+ >
68
+ {asset}
69
+ </Box>
68
70
  </Link>
69
71
  </PageLink>
70
72
 
71
- <time className={classes.date} dateTime={date}>
73
+ <Box
74
+ component='time'
75
+ className={classes.date}
76
+ dateTime={date}
77
+ sx={(theme) => ({
78
+ display: 'inline-block',
79
+ textDecoration: 'none',
80
+ color: theme.palette.text.secondary,
81
+ })}
82
+ >
72
83
  {formatter.format(new Date(date))}
73
- </time>
84
+ </Box>
74
85
 
75
86
  <PageLink href={`/${url}`} passHref>
76
- <Link href={`/${url}`} className={classes.title} color='inherit'>
77
- <Typography component='h2' variant='h4' color='inherit'>
87
+ <Link href={`/${url}`} className={classes.title} color='inherit' underline='hover'>
88
+ <Typography component='h2' variant='h4'>
78
89
  {title}
79
90
  </Typography>
80
91
  </Link>
81
92
  </PageLink>
82
- </div>
93
+ </Box>
83
94
  )
84
95
  }
@@ -0,0 +1,27 @@
1
+ import { Chip, SxProps } from '@mui/material'
2
+ import PageLink from 'next/link'
3
+
4
+ type BlogTagsProps = {
5
+ url: string
6
+ title: string
7
+ sx?: SxProps
8
+ }
9
+
10
+ export function BlogTag(props: BlogTagsProps) {
11
+ const { url, title, sx = [] } = props
12
+ return (
13
+ <PageLink href={`/${url}`} passHref>
14
+ <Chip
15
+ label={title}
16
+ sx={[
17
+ {
18
+ marginRight: '8px',
19
+ borderRadius: '4px',
20
+ fontSize: '14px',
21
+ },
22
+ ...(Array.isArray(sx) ? sx : [sx]),
23
+ ]}
24
+ />
25
+ </PageLink>
26
+ )
27
+ }
@@ -1,34 +1,9 @@
1
- import { Chip, makeStyles, Theme } from '@material-ui/core'
2
- import PageLink from 'next/link'
3
- import React from 'react'
1
+ import { styled } from '@mui/material'
4
2
 
5
- const useStyles = makeStyles(
6
- (theme: Theme) => ({
7
- wrapper: {
8
- maxWidth: 800,
9
- margin: `0 auto`,
10
- marginBottom: theme.spacings.sm,
11
- },
12
- tag: {
13
- marginRight: 8,
14
- borderRadius: 4,
15
- fontSize: 14,
16
- },
17
- }),
18
- { name: 'BlogTitle' },
19
- )
3
+ export const BlogTags = styled('div')(({ theme }) => ({
4
+ maxWidth: 800,
5
+ margin: `0 auto`,
6
+ marginBottom: theme.spacings.sm,
7
+ }))
20
8
 
21
- export default function BlogTitle(props) {
22
- const { relatedPages } = props
23
- const classes = useStyles()
24
-
25
- return (
26
- <div className={classes.wrapper}>
27
- {relatedPages.map((page) => (
28
- <PageLink key={page.url} href={`/${page.url}`} passHref>
29
- <Chip label={page.title} className={classes.tag} />
30
- </PageLink>
31
- ))}
32
- </div>
33
- )
34
- }
9
+ export * from './BlogTag'
@@ -1,29 +1,15 @@
1
- import { makeStyles } from '@material-ui/core'
1
+ import { Box } from '@mui/material'
2
2
  import React from 'react'
3
3
  import { LayoutTitle } from '../../Layout'
4
- import { UseStyles } from '../../Styles'
5
4
 
6
- const useStyles = makeStyles(
7
- {
8
- wrapper: {
9
- maxWidth: 800,
10
- margin: `0 auto`,
11
- },
12
- },
13
- { name: 'BlogTitle' },
14
- )
5
+ export type BlogTitleProps = Pick<React.ComponentProps<typeof Box>, 'sx' | 'children'>
15
6
 
16
- export type BlogTitleProps = UseStyles<typeof useStyles> & {
17
- title: string
18
- }
19
-
20
- export default function BlogTitle(props: BlogTitleProps) {
21
- const { title } = props
22
- const classes = useStyles()
7
+ export function BlogTitle(props: BlogTitleProps) {
8
+ const { sx = [], children } = props
23
9
 
24
10
  return (
25
- <div className={classes.wrapper}>
26
- <LayoutTitle variant='h1'>{title}</LayoutTitle>
27
- </div>
11
+ <Box sx={[{ maxWidth: 800, margin: '0 auto' }, ...(Array.isArray(sx) ? sx : [sx])]}>
12
+ <LayoutTitle variant='h1'>{children}</LayoutTitle>
13
+ </Box>
28
14
  )
29
15
  }
@@ -0,0 +1,5 @@
1
+ /* eslint-disable react/forbid-foreign-prop-types */
2
+ import { LoadingButton as Button, LoadingButtonProps } from '@mui/lab'
3
+
4
+ export type ButtonProps = LoadingButtonProps
5
+ export { Button }