@graphcommerce/magento-product 10.0.0-canary.67 → 10.0.0-canary.72

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 (41) hide show
  1. package/CHANGELOG.md +20 -0
  2. package/components/AddProductsToCart/AddProductsToCartForm.tsx +4 -2
  3. package/components/AddProductsToCart/AddProductsToCartSnackbarMessage.tsx +2 -2
  4. package/components/ProductCustomizable/CustomizableCheckboxOption.tsx +10 -4
  5. package/components/ProductCustomizable/CustomizableDateOption.tsx +6 -3
  6. package/components/ProductCustomizable/CustomizableDropDownOption.tsx +16 -8
  7. package/components/ProductCustomizable/CustomizableMultipleOption.tsx +10 -4
  8. package/components/ProductCustomizable/CustomizablePrice.tsx +16 -7
  9. package/components/ProductCustomizable/CustomizableRadioOption.tsx +10 -4
  10. package/components/ProductFiltersPro/PriceSlider.tsx +4 -4
  11. package/components/ProductFiltersPro/ProductFilterEqualChip.tsx +0 -1
  12. package/components/ProductFiltersPro/ProductFilterEqualSection.tsx +0 -1
  13. package/components/ProductFiltersPro/ProductFiltersProAllFiltersSidebar.tsx +2 -1
  14. package/components/ProductFiltersPro/ProductFiltersProCategorySection.tsx +2 -5
  15. package/components/ProductFiltersPro/ProductFiltersProLayoutSidebar.tsx +44 -12
  16. package/components/ProductFiltersPro/ProductFiltersProNoResults.tsx +4 -4
  17. package/components/ProductListCount/ProductListCount.tsx +8 -6
  18. package/components/ProductListFilters/FilterEqualType.tsx +7 -7
  19. package/components/ProductListFiltersContainer/ProductListFiltersContainer.tsx +5 -5
  20. package/components/ProductListItem/ProductListItemImage.tsx +7 -6
  21. package/components/ProductListItem/ProductListItemImageContainer.tsx +4 -4
  22. package/components/ProductListItem/ProductListItemLinkOrDiv.tsx +4 -4
  23. package/components/ProductListItem/ProductListItemParts.tsx +2 -5
  24. package/components/ProductListItem/ProductListItemTitleAndPrice.tsx +4 -3
  25. package/components/ProductListItems/ProductListItemsBase.tsx +10 -4
  26. package/components/ProductListItems/getFilterTypes.ts +4 -4
  27. package/components/ProductListItems/productListApplyCategoryDefaults.ts +5 -4
  28. package/components/ProductListSort/ProductListSort.tsx +3 -4
  29. package/components/ProductPage/ProductPageAddToCartRow.tsx +4 -3
  30. package/components/ProductPageBreadcrumb/ProductPageBreadcrumb.tsx +7 -1
  31. package/components/ProductPageDescription/ProductPageDescription.tsx +5 -4
  32. package/components/ProductPageGallery/ProductVideo.tsx +1 -2
  33. package/components/ProductPagePrice/ProductPagePrice.tsx +1 -2
  34. package/components/ProductShortDescription/ProductShortDescription.tsx +4 -4
  35. package/components/ProductSidebarDelivery/ProductSidebarDelivery.tsx +6 -8
  36. package/components/ProductSpecs/ProductSpecs.tsx +8 -5
  37. package/components/ProductStaticPaths/getProductStaticPaths.ts +14 -8
  38. package/components/ProductStaticPaths/getSitemapPaths.ts +4 -4
  39. package/components/index.ts +0 -1
  40. package/hooks/useProductList.ts +1 -1
  41. package/package.json +14 -14
package/CHANGELOG.md CHANGED
@@ -1,5 +1,25 @@
1
1
  # Change Log
2
2
 
3
+ ## 10.0.0-canary.72
4
+
5
+ ## 10.0.0-canary.71
6
+
7
+ ## 10.0.0-canary.70
8
+
9
+ ### Major Changes
10
+
11
+ - [#2565](https://github.com/graphcommerce-org/graphcommerce/pull/2565) [`c96dfcd`](https://github.com/graphcommerce-org/graphcommerce/commit/c96dfcdca981baca387c270ad9e2b9515cdd00cc) - Updated to Apollo Client 4 ([@paales](https://github.com/paales))
12
+
13
+ ## 10.0.0-canary.69
14
+
15
+ ## 10.0.0-canary.68
16
+
17
+ ### Major Changes
18
+
19
+ - [#2557](https://github.com/graphcommerce-org/graphcommerce/pull/2557) [`ceaadd8`](https://github.com/graphcommerce-org/graphcommerce/commit/ceaadd87f0648982a068a3b07b1fa149c9127f49) - ## Material UI v5 → v7 Migration
20
+
21
+ This release upgrades Material UI from v5 to v7 with full CSS variables support. ([@paales](https://github.com/paales))
22
+
3
23
  ## 10.0.0-canary.67
4
24
 
5
25
  ### Patch Changes
@@ -1,5 +1,5 @@
1
1
  import type { UseFormGraphQlOptions } from '@graphcommerce/ecommerce-ui'
2
- import type { ApolloQueryResult } from '@graphcommerce/graphql'
2
+ import type { ApolloClient } from '@graphcommerce/graphql'
3
3
  import { useApolloClient } from '@graphcommerce/graphql'
4
4
  import type { CrosssellsQuery } from '@graphcommerce/magento-cart'
5
5
  import { CrosssellsDocument, useFormGqlMutationCart } from '@graphcommerce/magento-cart'
@@ -44,7 +44,9 @@ export function AddProductsToCartForm(props: AddProductsToCartFormProps) {
44
44
  const { children, redirect, onComplete, sx, snackbarProps, ...formProps } = props
45
45
  const router = useRouter()
46
46
  const client = useApolloClient()
47
- const crosssellsQuery = useRef<Promise<ApolloQueryResult<CrosssellsQuery>> | undefined>(undefined)
47
+ const crosssellsQuery = useRef<Promise<ApolloClient.QueryResult<CrosssellsQuery>> | undefined>(
48
+ undefined,
49
+ )
48
50
 
49
51
  const form = useFormGqlMutationCart<AddProductsToCartMutation, AddProductsToCartFields>(
50
52
  AddProductsToCartDocument,
@@ -1,4 +1,3 @@
1
- import type { ApolloError } from '@graphcommerce/graphql'
2
1
  import type { CartUserInputError } from '@graphcommerce/graphql-mesh'
3
2
  import {
4
3
  ApolloCartErrorSnackbar,
@@ -13,12 +12,13 @@ import {
13
12
  ListFormat,
14
13
  MessageSnackbar,
15
14
  } from '@graphcommerce/next-ui'
15
+ import type { ErrorLike } from '@apollo/client'
16
16
  import { Plural, Trans } from '@lingui/react/macro'
17
17
 
18
18
  export type AddProductsToCartSnackbarMessageProps = {
19
19
  errorSnackbar?: Omit<ErrorSnackbarProps, 'open'>
20
20
  successSnackbar?: Omit<MessageSnackbarProps, 'open' | 'action'>
21
- error?: ApolloError | null
21
+ error?: ErrorLike | null
22
22
  userErrors?: Pick<CartUserInputError, 'message'>[]
23
23
  showSuccess: boolean
24
24
  addedItems: string[]
@@ -1,7 +1,7 @@
1
1
  import { ActionCardListForm } from '@graphcommerce/ecommerce-ui'
2
2
  import { Money } from '@graphcommerce/magento-store'
3
3
  import type { ActionCardProps } from '@graphcommerce/next-ui'
4
- import { ActionCard, nonNullable, SectionHeader } from '@graphcommerce/next-ui'
4
+ import { ActionCard, nonNullable, SectionHeader, sxx } from '@graphcommerce/next-ui'
5
5
  import { t } from '@lingui/core/macro'
6
6
  import { Box, Checkbox } from '@mui/material'
7
7
  import { useFormAddProductsToCart } from '../AddProductsToCart'
@@ -36,9 +36,15 @@ function CustomizableCheckboxActionCard(props: CheckboxActionCardProps) {
36
36
  ? null
37
37
  : price && (
38
38
  <Box
39
- sx={{
40
- color: selected ? 'text.primary' : 'text.secondary',
41
- }}
39
+ sx={sxx(
40
+ selected
41
+ ? {
42
+ color: 'text.primary',
43
+ }
44
+ : {
45
+ color: 'text.secondary',
46
+ },
47
+ )}
42
48
  >
43
49
  <span style={{ fontFamily: 'arial' }}>{'+ '}</span>
44
50
  <Money
@@ -38,13 +38,16 @@ export function CustomizableDateOption(props: CustomizableDateOptionProps) {
38
38
  <TextFieldElement
39
39
  control={control}
40
40
  name={name}
41
- sx={{
41
+ sx={(theme) => ({
42
42
  width: '100%',
43
43
  '& ::-webkit-calendar-picker-indicator': {
44
- filter: (theme) => (theme.palette.mode === 'dark' ? 'invert(100%)' : 'none'),
44
+ filter: 'none',
45
45
  mr: '10px',
46
+ ...theme.applyStyles('dark', {
47
+ filter: 'invert(100%)',
48
+ }),
46
49
  },
47
- }}
50
+ })}
48
51
  required={!!required}
49
52
  type={getInputType(dateValue.type)}
50
53
  InputProps={{
@@ -1,6 +1,6 @@
1
1
  import { useController } from '@graphcommerce/ecommerce-ui'
2
2
  import { Money } from '@graphcommerce/magento-store'
3
- import { filterNonNullableKeys, SectionHeader } from '@graphcommerce/next-ui'
3
+ import { filterNonNullableKeys, SectionHeader, sxx } from '@graphcommerce/next-ui'
4
4
  import { t } from '@lingui/core/macro'
5
5
  import { Box, MenuItem, TextField } from '@mui/material'
6
6
  import { useFormAddProductsToCart } from '../AddProductsToCart'
@@ -61,13 +61,21 @@ export function CustomizableDropDownOption(props: CustomizableDropDownOptionProp
61
61
 
62
62
  {option.price ? (
63
63
  <Box
64
- sx={{
65
- // display: 'flex',
66
- typography: 'body1',
67
- '&.sizeMedium': { typographty: 'subtitle1' },
68
- '&.sizeLarge': { typography: 'h6' },
69
- color: option.uid === value ? 'text.primary' : 'text.secondary',
70
- }}
64
+ sx={sxx(
65
+ {
66
+ // display: 'flex',
67
+ typography: 'body1',
68
+ '&.sizeMedium': { typographty: 'subtitle1' },
69
+ '&.sizeLarge': { typography: 'h6' },
70
+ },
71
+ option.uid === value
72
+ ? {
73
+ color: 'text.primary',
74
+ }
75
+ : {
76
+ color: 'text.secondary',
77
+ },
78
+ )}
71
79
  >
72
80
  <span style={{ fontFamily: 'arial', paddingTop: '1px' }}>+&nbsp;</span>
73
81
  <Money
@@ -1,7 +1,7 @@
1
1
  import { ActionCardListForm } from '@graphcommerce/ecommerce-ui'
2
2
  import { Money } from '@graphcommerce/magento-store'
3
3
  import type { ActionCardProps } from '@graphcommerce/next-ui'
4
- import { ActionCard, filterNonNullableKeys, SectionHeader } from '@graphcommerce/next-ui'
4
+ import { ActionCard, filterNonNullableKeys, SectionHeader, sxx } from '@graphcommerce/next-ui'
5
5
  import { t } from '@lingui/core/macro'
6
6
  import { Box } from '@mui/material'
7
7
  import { useFormAddProductsToCart } from '../AddProductsToCart'
@@ -31,9 +31,15 @@ function CustomizableMultipleActionCard(props: MultipleActionCardProps) {
31
31
  ? null
32
32
  : price && (
33
33
  <Box
34
- sx={{
35
- color: selected ? 'text.primary' : 'text.secondary',
36
- }}
34
+ sx={sxx(
35
+ selected
36
+ ? {
37
+ color: 'text.primary',
38
+ }
39
+ : {
40
+ color: 'text.secondary',
41
+ },
42
+ )}
37
43
  >
38
44
  <span style={{ fontFamily: 'arial' }}>{'+ '}</span>
39
45
  <Money
@@ -2,6 +2,7 @@ import type { Control, FieldName, FieldPath } from '@graphcommerce/ecommerce-ui'
2
2
  import { useWatch, type FieldValues } from '@graphcommerce/ecommerce-ui'
3
3
  import type { PriceTypeEnum } from '@graphcommerce/graphql-mesh'
4
4
  import { Money, type MoneyFragment } from '@graphcommerce/magento-store'
5
+ import { sxx } from '@graphcommerce/next-ui'
5
6
  import { Box } from '@mui/material'
6
7
  import { useFormAddProductsToCart, type AddProductsToCartFields } from '../AddProductsToCart'
7
8
 
@@ -21,13 +22,21 @@ export function CustomizablePrice(props: CustomizablePriceProps) {
21
22
 
22
23
  return (
23
24
  <Box
24
- sx={{
25
- display: 'flex',
26
- typography: 'body1',
27
- '&.sizeMedium': { typographty: 'subtitle1' },
28
- '&.sizeLarge': { typography: 'h6' },
29
- color: optionValue ? 'text.primary' : 'text.secondary',
30
- }}
25
+ sx={sxx(
26
+ {
27
+ display: 'flex',
28
+ typography: 'body1',
29
+ '&.sizeMedium': { typographty: 'subtitle1' },
30
+ '&.sizeLarge': { typography: 'h6' },
31
+ },
32
+ optionValue
33
+ ? {
34
+ color: 'text.primary',
35
+ }
36
+ : {
37
+ color: 'text.secondary',
38
+ },
39
+ )}
31
40
  >
32
41
  {/* Change fontFamily so the + is properly outlined */}
33
42
  <span style={{ fontFamily: 'arial' }}>+{'\u00A0'}</span>
@@ -1,7 +1,7 @@
1
1
  import { ActionCardListForm } from '@graphcommerce/ecommerce-ui'
2
2
  import { Money } from '@graphcommerce/magento-store'
3
3
  import type { ActionCardProps } from '@graphcommerce/next-ui'
4
- import { ActionCard, filterNonNullableKeys, SectionHeader } from '@graphcommerce/next-ui'
4
+ import { ActionCard, filterNonNullableKeys, SectionHeader, sxx } from '@graphcommerce/next-ui'
5
5
  import { t } from '@lingui/core/macro'
6
6
  import { Box } from '@mui/material'
7
7
  import { useFormAddProductsToCart } from '../AddProductsToCart'
@@ -32,9 +32,15 @@ function CustomizableRadioActionCard(props: RadioActionCardProps) {
32
32
  ? null
33
33
  : price && (
34
34
  <Box
35
- sx={{
36
- color: selected ? 'text.primary' : 'text.secondary',
37
- }}
35
+ sx={sxx(
36
+ selected
37
+ ? {
38
+ color: 'text.primary',
39
+ }
40
+ : {
41
+ color: 'text.secondary',
42
+ },
43
+ )}
38
44
  >
39
45
  {/* Change fontFamily so the + is properly outlined */}
40
46
  <span style={{ fontFamily: 'arial' }}>{'+ '}</span>
@@ -1,6 +1,6 @@
1
1
  import type { FilterRangeTypeInput } from '@graphcommerce/graphql-mesh'
2
2
  import { Money } from '@graphcommerce/magento-store'
3
- import { extendableComponent, filterNonNullableKeys } from '@graphcommerce/next-ui'
3
+ import { extendableComponent, filterNonNullableKeys, sxx } from '@graphcommerce/next-ui'
4
4
  import type { SxProps, Theme } from '@mui/material'
5
5
  import { Box, Slider, useEventCallback } from '@mui/material'
6
6
  import { useCallback } from 'react'
@@ -38,14 +38,14 @@ export function PriceSlider(props: PriceSliderProps) {
38
38
 
39
39
  return (
40
40
  <Box
41
- sx={[
41
+ sx={sxx(
42
42
  (theme) => ({
43
43
  pt: theme.spacings.md,
44
44
  pb: theme.spacings.xs,
45
45
  px: theme.spacings.xxs,
46
46
  }),
47
- ...(Array.isArray(sx) ? sx : [sx]),
48
- ]}
47
+ sx,
48
+ )}
49
49
  className={classes.container}
50
50
  >
51
51
  <Slider
@@ -58,7 +58,6 @@ export function ProductFilterEqualChip(props: FilterProps) {
58
58
  })),
59
59
  [attrCode, options],
60
60
  )
61
-
62
61
  return (
63
62
  items.length !== 0 && (
64
63
  <ChipOverlayOrPopper
@@ -52,7 +52,6 @@ export function ProductFilterEqualSection(props: FilterProps) {
52
52
  })),
53
53
  [attrCode, options],
54
54
  )
55
-
56
55
  return (
57
56
  <ActionCardAccordion
58
57
  summary={label}
@@ -1,3 +1,4 @@
1
+ import { sxx } from '@graphcommerce/next-ui'
1
2
  import type { SxProps, Theme } from '@mui/material'
2
3
  import { Box } from '@mui/material'
3
4
  import type { ProductFiltersProAggregationsProps } from './ProductFiltersProAggregations'
@@ -23,7 +24,7 @@ export function ProductFiltersProAllFiltersSidebar(props: ProductFiltersProAllFi
23
24
  const { sort_fields, total_count, renderer, sx = [], category, params } = props
24
25
 
25
26
  return (
26
- <Box sx={[{ display: { xs: 'none', md: 'grid' } }, ...(Array.isArray(sx) ? sx : [sx])]}>
27
+ <Box sx={sxx({ display: { xs: 'none', md: 'grid' } }, sx)}>
27
28
  <ProductFiltersProCategorySection category={category} params={params} />
28
29
  <ProductFiltersProSortSection
29
30
  sort_fields={sort_fields}
@@ -10,6 +10,7 @@ import {
10
10
  iconChevronLeft,
11
11
  IconSvg,
12
12
  responsiveVal,
13
+ sxx,
13
14
  } from '@graphcommerce/next-ui'
14
15
  import { Trans } from '@lingui/react/macro'
15
16
  import type { SxProps, Theme } from '@mui/material'
@@ -33,11 +34,7 @@ export function ProductFiltersProCategoryAccordion(props: ProductFiltersProCateg
33
34
 
34
35
  return (
35
36
  <ActionCardAccordion
36
- sx={[
37
- hideTitle ? { '& .MuiAccordionSummary-root': { display: 'none' } } : {},
38
- sx,
39
- ...(Array.isArray(sx) ? sx : [sx]),
40
- ]}
37
+ sx={sxx(hideTitle ? { '& .MuiAccordionSummary-root': { display: 'none' } } : {}, sx, sx)}
41
38
  defaultExpanded={defaultExpanded}
42
39
  summary={<Trans>Categories</Trans>}
43
40
  right={
@@ -52,9 +52,7 @@ export function ProductFiltersProLayoutSidebar(props: ProductFiltersProLayoutSid
52
52
  return (
53
53
  <>
54
54
  {headerPosition === 'before' ? header : null}
55
-
56
55
  <FormAutoSubmit control={form.control} disabled={autoSubmitDisabled} submit={submit} />
57
-
58
56
  <Container
59
57
  maxWidth={false}
60
58
  className={classes.content}
@@ -77,9 +75,7 @@ export function ProductFiltersProLayoutSidebar(props: ProductFiltersProLayoutSid
77
75
  /300px auto
78
76
  `,
79
77
  },
80
-
81
78
  columnGap: { md: theme.spacings.md, xl: theme.spacings.xxl },
82
-
83
79
  '& .ProductListItemsBase-root.sizeNormal': {
84
80
  gridTemplateColumns: {
85
81
  xs: 'repeat(2, 1fr)',
@@ -89,25 +85,61 @@ export function ProductFiltersProLayoutSidebar(props: ProductFiltersProLayoutSid
89
85
  },
90
86
  })}
91
87
  >
92
- <Box gridArea='topleft' sx={{ display: { xs: 'none', md: 'block' }, alignSelf: 'center' }}>
88
+ <Box
89
+ sx={{
90
+ gridArea: 'topleft',
91
+ display: { xs: 'none', md: 'block' },
92
+ alignSelf: 'center',
93
+ }}
94
+ >
93
95
  {clearAll}
94
96
  </Box>
95
97
  {sidebarFilters && (
96
- <Box gridArea='sidebar' sx={{ display: { xs: 'none', md: 'block' } }}>
98
+ <Box
99
+ sx={{
100
+ gridArea: 'sidebar',
101
+ display: { xs: 'none', md: 'block' },
102
+ }}
103
+ >
97
104
  {sidebarFilters}
98
105
  </Box>
99
106
  )}
100
- {children && <Box gridArea='content'>{children}</Box>}
107
+ {children && (
108
+ <Box
109
+ sx={{
110
+ gridArea: 'content',
111
+ }}
112
+ >
113
+ {children}
114
+ </Box>
115
+ )}
101
116
  <StickyBelowHeader sx={{ display: { md: 'none', gridArea: 'horizontalFilters' } }}>
102
117
  {horizontalFilters}
103
118
  </StickyBelowHeader>
104
-
105
- <Box gridArea='beforeContent' sx={{ mt: { md: 0 } }}>
119
+ <Box
120
+ sx={{
121
+ gridArea: 'beforeContent',
122
+ mt: { md: 0 },
123
+ }}
124
+ >
106
125
  {count}
107
126
  </Box>
108
- <Box gridArea='items'>{items}</Box>
109
-
110
- {pagination && <Box gridArea='afterContent'>{pagination}</Box>}
127
+ <Box
128
+ sx={{
129
+ gridArea: 'items',
130
+ }}
131
+ >
132
+ {items}
133
+ </Box>
134
+ {pagination && (
135
+ <Box
136
+ sx={{
137
+ gridArea: 'afterContent',
138
+ }}
139
+ >
140
+ {pagination}
141
+ </Box>
142
+ )}
111
143
  </Container>
112
144
  </>
113
145
  )
@@ -1,4 +1,4 @@
1
- import { extendableComponent } from '@graphcommerce/next-ui'
1
+ import { extendableComponent, sxx } from '@graphcommerce/next-ui'
2
2
  import { Trans } from '@lingui/react/macro'
3
3
  import type { SxProps, Theme } from '@mui/material'
4
4
  import { Box, Link, Typography } from '@mui/material'
@@ -22,14 +22,14 @@ export function ProductFiltersProNoResults(props: ProductFitlersProNoResultProps
22
22
  return (
23
23
  <Box
24
24
  className={classes.root}
25
- sx={[
25
+ sx={sxx(
26
26
  (theme) => ({
27
27
  marginTop: theme.spacings.md,
28
28
  marginBottom: theme.spacings.sm,
29
29
  textAlign: 'center',
30
30
  }),
31
- ...(Array.isArray(sx) ? sx : [sx]),
32
- ]}
31
+ sx,
32
+ )}
33
33
  >
34
34
  {term ? (
35
35
  <>
@@ -1,4 +1,4 @@
1
- import { extendableComponent, responsiveVal } from '@graphcommerce/next-ui'
1
+ import { extendableComponent, responsiveVal, sxx } from '@graphcommerce/next-ui'
2
2
  import { Trans } from '@lingui/react/macro'
3
3
  import type { SxProps, Theme } from '@mui/material'
4
4
  import { Box, Divider, Typography } from '@mui/material'
@@ -20,7 +20,7 @@ export function ProductListCount(props: ProductCountProps) {
20
20
 
21
21
  return (
22
22
  <Box
23
- sx={[
23
+ sx={sxx(
24
24
  (theme) => ({
25
25
  display: 'grid',
26
26
  gridAutoFlow: 'column',
@@ -32,16 +32,18 @@ export function ProductListCount(props: ProductCountProps) {
32
32
  my: theme.spacings.md,
33
33
  mx: 'auto',
34
34
  }),
35
- ...(Array.isArray(sx) ? sx : [sx]),
36
- ]}
35
+ sx,
36
+ )}
37
37
  className={classes.root}
38
38
  >
39
39
  <Divider component='div' className={classes.line} />
40
40
  <Typography
41
41
  variant='body2'
42
- color='text.disabled'
43
42
  className={classes.count}
44
- sx={{ lineHeight: 0 }}
43
+ sx={{
44
+ color: 'text.disabled',
45
+ lineHeight: 0,
46
+ }}
45
47
  >
46
48
  {children ? <> {children} </> : null}
47
49
  {total_count === 0 && <Trans>no products</Trans>}
@@ -1,7 +1,7 @@
1
1
  import { cloneDeep } from '@graphcommerce/graphql'
2
2
  import type { FilterEqualTypeInput } from '@graphcommerce/graphql-mesh'
3
3
  import type { ChipMenuProps } from '@graphcommerce/next-ui'
4
- import { ChipMenu, extendableComponent, responsiveVal } from '@graphcommerce/next-ui'
4
+ import { ChipMenu, extendableComponent, responsiveVal, sxx } from '@graphcommerce/next-ui'
5
5
  import {
6
6
  Box, // eslint-disable-next-line @typescript-eslint/no-restricted-imports
7
7
  Checkbox,
@@ -127,7 +127,7 @@ export function FilterEqualType(props: FilterEqualTypeProps) {
127
127
  padding: `0 ${theme.spacings.xxs} 0`,
128
128
  display: 'block',
129
129
  '&:not(:nth-last-of-type(-n+2)) > div': {
130
- borderBottom: `1px solid ${theme.palette.divider}`,
130
+ borderBottom: `1px solid ${theme.vars.palette.divider}`,
131
131
  },
132
132
  })}
133
133
  >
@@ -155,7 +155,7 @@ export function FilterEqualType(props: FilterEqualTypeProps) {
155
155
  whiteSpace: 'break-spaces',
156
156
  },
157
157
  [`& .${listItemTextClasses.secondary}`]: {
158
- color: theme.palette.grey[500],
158
+ color: theme.vars.palette.grey[500],
159
159
  marginLeft: '4px',
160
160
  fontSize: theme.typography.pxToRem(11),
161
161
  display: 'inline',
@@ -172,7 +172,7 @@ export function FilterEqualType(props: FilterEqualTypeProps) {
172
172
  disableRipple
173
173
  inputProps={{ 'aria-labelledby': labelId }}
174
174
  className={cls.checkbox}
175
- sx={[
175
+ sx={sxx(
176
176
  {
177
177
  padding: 0,
178
178
  margin: '-10px 0 0 0',
@@ -187,10 +187,10 @@ export function FilterEqualType(props: FilterEqualTypeProps) {
187
187
  },
188
188
  isActive &&
189
189
  ((theme) => ({
190
- border: `1px solid ${theme.palette.primary.main}`,
191
- boxShadow: `inset 0 0 0 4px ${theme.palette.background.paper}`,
190
+ border: `1px solid ${theme.vars.palette.primary.main}`,
191
+ boxShadow: `inset 0 0 0 4px ${theme.vars.palette.background.paper}`,
192
192
  })),
193
- ]}
193
+ )}
194
194
  style={
195
195
  isColor
196
196
  ? { background: `${option?.label}`, color: `${option?.label}` }
@@ -4,6 +4,7 @@ import {
4
4
  iconChevronLeft,
5
5
  iconChevronRight,
6
6
  IconSvg,
7
+ sxx,
7
8
  useScrollY,
8
9
  } from '@graphcommerce/next-ui'
9
10
  import type { SxProps, Theme } from '@mui/material'
@@ -89,7 +90,7 @@ export function ProductListFiltersContainer(props: ProductListFiltersContainerPr
89
90
  <MotionDiv
90
91
  className={classes.wrapper}
91
92
  ref={wrapperRef}
92
- sx={[
93
+ sx={sxx(
93
94
  (theme) => ({
94
95
  display: 'flex',
95
96
  justifyContent: 'center',
@@ -98,15 +99,14 @@ export function ProductListFiltersContainer(props: ProductListFiltersContainerPr
98
99
  top: theme.page.vertical,
99
100
  zIndex: 9,
100
101
  margin: '0 auto',
101
-
102
102
  [theme.breakpoints.down('md')]: {
103
103
  textAlign: 'center',
104
104
  maxWidth: 'unset',
105
105
  margin: `0 calc(${theme.page.horizontal} * -1)`,
106
106
  },
107
107
  }),
108
- ...(Array.isArray(sx) ? sx : [sx]),
109
- ]}
108
+ sx,
109
+ )}
110
110
  >
111
111
  <ScrollerProvider scrollSnapAlign='none'>
112
112
  <ScrollerButton
@@ -126,7 +126,7 @@ export function ProductListFiltersContainer(props: ProductListFiltersContainerPr
126
126
  paddingLeft: 0,
127
127
  paddingRight: 0,
128
128
  [theme.breakpoints.up('md')]: {
129
- background: theme.palette.background.default,
129
+ background: theme.vars.palette.background.default,
130
130
  borderRadius: '99em',
131
131
  },
132
132
  display: 'grid',
@@ -1,5 +1,6 @@
1
1
  import type { ImageProps } from '@graphcommerce/image'
2
2
  import { Image } from '@graphcommerce/image'
3
+ import { sxx } from '@graphcommerce/next-ui'
3
4
  import { Trans } from '@lingui/react/macro'
4
5
  import type { BoxProps } from '@mui/material'
5
6
  import { Box, Skeleton, styled } from '@mui/material'
@@ -67,14 +68,14 @@ export function ProductListItemImage(props: ImageOrPlaceholderProps) {
67
68
  alt={alt ?? ''}
68
69
  {...image}
69
70
  className={classes?.image}
70
- sx={[
71
+ sx={sxx(
71
72
  {
72
73
  objectFit: 'contain',
73
74
  aspectRatio: `${aspectRatio[0] / aspectRatio[1]}`,
74
75
  display: 'block',
75
76
  },
76
- ...(Array.isArray(sx) ? sx : [sx]),
77
- ]}
77
+ sx,
78
+ )}
78
79
  />
79
80
  )
80
81
  }
@@ -82,14 +83,14 @@ export function ProductListItemImage(props: ImageOrPlaceholderProps) {
82
83
  return (
83
84
  <PlaceHolderContainer className={`${classes?.placeholder} ${classes?.image}`}>
84
85
  <Box
85
- sx={[
86
+ sx={sxx(
86
87
  {
87
88
  width: '100%',
88
89
  height: '100%',
89
90
  aspectRatio: `${aspectRatio[0] / aspectRatio[1]}`,
90
91
  },
91
- ...(Array.isArray(sx) ? sx : [sx]),
92
- ]}
92
+ sx,
93
+ )}
93
94
  >
94
95
  <Trans>No Image</Trans>
95
96
  </Box>
@@ -1,4 +1,4 @@
1
- import { breakpointVal, responsiveVal } from '@graphcommerce/next-ui'
1
+ import { breakpointVal, responsiveVal, sxx } from '@graphcommerce/next-ui'
2
2
  import type { BoxProps } from '@mui/material'
3
3
  import { Box } from '@mui/material'
4
4
 
@@ -10,7 +10,7 @@ export function ProductImageContainer(props: ProductImageContainerProps) {
10
10
  return (
11
11
  <Box
12
12
  {...props}
13
- sx={[
13
+ sx={sxx(
14
14
  (theme) => ({
15
15
  display: 'grid',
16
16
  bgcolor: 'background.image',
@@ -28,8 +28,8 @@ export function ProductImageContainer(props: ProductImageContainerProps) {
28
28
  height: 'auto',
29
29
  },
30
30
  }),
31
- ...(Array.isArray(sx) ? sx : [sx]),
32
- ]}
31
+ sx,
32
+ )}
33
33
  />
34
34
  )
35
35
  }
@@ -1,4 +1,4 @@
1
- import { breakpointVal, NextLink } from '@graphcommerce/next-ui'
1
+ import { breakpointVal, NextLink, sxx } from '@graphcommerce/next-ui'
2
2
  import type { BoxProps, ButtonBaseProps, SxProps, Theme } from '@mui/material'
3
3
  import { Box, ButtonBase } from '@mui/material'
4
4
  import React from 'react'
@@ -16,7 +16,7 @@ export const ProductListItemLinkOrDiv = React.forwardRef<
16
16
  >((props, ref) => {
17
17
  const { sx = [] } = props
18
18
 
19
- const sxProps: SxProps<Theme> = [
19
+ const sxProps = sxx(
20
20
  (theme) => ({
21
21
  display: 'block',
22
22
  position: 'relative',
@@ -28,8 +28,8 @@ export const ProductListItemLinkOrDiv = React.forwardRef<
28
28
  theme.breakpoints.values,
29
29
  ),
30
30
  }),
31
- ...(Array.isArray(sx) ? sx : [sx]),
32
- ]
31
+ sx,
32
+ )
33
33
 
34
34
  return isLink(props) ? (
35
35
  <ButtonBase ref={ref} component={NextLink} {...props} sx={sxProps} focusRipple />
@@ -1,5 +1,5 @@
1
1
  import type { ImageProps } from '@graphcommerce/image'
2
- import { extendableComponent } from '@graphcommerce/next-ui'
2
+ import { extendableComponent, sxx } from '@graphcommerce/next-ui'
3
3
  import type { SxProps, Theme } from '@mui/material'
4
4
  import { Skeleton } from '@mui/material'
5
5
  import React from 'react'
@@ -93,10 +93,7 @@ export function ProductListItemReal(props: ProductListItemRealProps) {
93
93
  className={classes.root}
94
94
  onClick={(e: React.MouseEvent<HTMLAnchorElement | HTMLDivElement>) => onClick?.(e, props)}
95
95
  {...slotProps.root}
96
- sx={[
97
- ...(Array.isArray(sx) ? sx : [sx]),
98
- ...(Array.isArray(slotProps.root?.sx) ? slotProps.root.sx : [slotProps.root?.sx]),
99
- ]}
96
+ sx={sxx(sx, slotProps.root?.sx)}
100
97
  ref={slotProps.root?.ref as React.Ref<HTMLAnchorElement | HTMLDivElement>}
101
98
  >
102
99
  <ProductImageContainer className={classes.imageContainer}>
@@ -1,3 +1,4 @@
1
+ import { sxx } from '@graphcommerce/next-ui'
1
2
  import type { SxProps, Theme } from '@mui/material'
2
3
  import { Box, Typography } from '@mui/material'
3
4
  import { productListPrice } from '../ProductListPrice'
@@ -17,7 +18,7 @@ export function ProductListItemTitleAndPrice(props: ProductListItemTitleAndPrice
17
18
  return (
18
19
  <Box
19
20
  className={classes.titleContainer}
20
- sx={[
21
+ sx={sxx(
21
22
  (theme) => ({
22
23
  display: 'grid',
23
24
  alignItems: 'baseline',
@@ -30,8 +31,8 @@ export function ProductListItemTitleAndPrice(props: ProductListItemTitleAndPrice
30
31
  gridTemplateColumns: { xs: 'unset', md: 'auto auto 1fr' },
31
32
  justifyContent: 'space-between',
32
33
  }),
33
- ...(Array.isArray(sx) ? sx : [sx]),
34
- ]}
34
+ sx,
35
+ )}
35
36
  >
36
37
  <Typography
37
38
  component={titleComponent}
@@ -1,4 +1,10 @@
1
- import { extendableComponent, LazyHydrate, RenderType, responsiveVal } from '@graphcommerce/next-ui'
1
+ import {
2
+ extendableComponent,
3
+ LazyHydrate,
4
+ RenderType,
5
+ responsiveVal,
6
+ sxx,
7
+ } from '@graphcommerce/next-ui'
2
8
  import type { BoxProps, Breakpoint, Theme } from '@mui/material'
3
9
  import { Box, useTheme } from '@mui/material'
4
10
  import React from 'react'
@@ -93,7 +99,7 @@ export function ProductListItemsBase(props: ProductItemsGridProps) {
93
99
  <Box
94
100
  ref={containerRef}
95
101
  className={classes.root}
96
- sx={[
102
+ sx={sxx(
97
103
  ...Object.entries(columnConfig).map(([key, column]) => ({
98
104
  [theme.breakpoints.up(key as Breakpoint)]: {
99
105
  gap: column.gap ?? gap,
@@ -102,8 +108,8 @@ export function ProductListItemsBase(props: ProductItemsGridProps) {
102
108
  },
103
109
  })),
104
110
  { display: 'grid' },
105
- ...(Array.isArray(sx) ? sx : [sx]),
106
- ]}
111
+ sx,
112
+ )}
107
113
  >
108
114
  {items?.map((item, idx) =>
109
115
  item ? (
@@ -1,4 +1,4 @@
1
- import type { ApolloClient, NormalizedCacheObject, TypedDocumentNode } from '@graphcommerce/graphql'
1
+ import type { ApolloClient, TypedDocumentNode } from '@graphcommerce/graphql'
2
2
  import { gql } from '@graphcommerce/graphql'
3
3
  import type { AttributeFrontendInputEnum, Exact } from '@graphcommerce/graphql-mesh'
4
4
  import { magentoVersion } from '@graphcommerce/next-config/config'
@@ -32,7 +32,7 @@ const FilterInputTypesDocument = gql`
32
32
  export type FilterTypes = Partial<Record<string, AttributeFrontendInputEnum>>
33
33
 
34
34
  export async function getFilterTypes(
35
- client: ApolloClient<NormalizedCacheObject>,
35
+ client: ApolloClient,
36
36
  isSearch: boolean = false,
37
37
  ): Promise<FilterTypes> {
38
38
  if (magentoVersion >= 247) {
@@ -44,7 +44,7 @@ export async function getFilterTypes(
44
44
  })
45
45
 
46
46
  const typeMap: FilterTypes = Object.fromEntries(
47
- filterNonNullableKeys(types.data.attributesList?.items, ['frontend_input'])
47
+ filterNonNullableKeys(types.data?.attributesList?.items ?? [], ['frontend_input'])
48
48
  .map((i) => [i.code, i.frontend_input])
49
49
  .filter(nonNullable),
50
50
  )
@@ -55,7 +55,7 @@ export async function getFilterTypes(
55
55
  const filterInputTypes = await client.query({ query: FilterInputTypesDocument })
56
56
 
57
57
  const typeMap: FilterTypes = Object.fromEntries(
58
- filterInputTypes.data?.__type.inputFields
58
+ (filterInputTypes.data?.__type?.inputFields ?? [])
59
59
  .map<[string, AttributeFrontendInputEnum] | undefined>((field) => {
60
60
  if (field.type.name === 'FilterEqualTypeInput') return [field.name, 'SELECT']
61
61
  if (field.type.name === 'FilterRangeTypeInput') return [field.name, 'PRICE']
@@ -33,7 +33,7 @@ export function useProductListApplyCategoryDefaults(
33
33
 
34
34
  export async function productListApplyCategoryDefaults(
35
35
  params: ProductListParams,
36
- conf: StoreConfigQuery,
36
+ conf: StoreConfigQuery | undefined,
37
37
  category:
38
38
  | Promise<CategoryDefaultFragment | null | undefined>
39
39
  | CategoryDefaultFragment
@@ -42,7 +42,7 @@ export async function productListApplyCategoryDefaults(
42
42
  ): Promise<ProductListQueryVariables>
43
43
  export async function productListApplyCategoryDefaults(
44
44
  params: ProductListParams | undefined,
45
- conf: StoreConfigQuery,
45
+ conf: StoreConfigQuery | undefined,
46
46
  category:
47
47
  | Promise<CategoryDefaultFragment | null | undefined>
48
48
  | CategoryDefaultFragment
@@ -52,11 +52,12 @@ export async function productListApplyCategoryDefaults(
52
52
  if (!params) return params
53
53
 
54
54
  const newParams = cloneDeep(params)
55
- if (!newParams.pageSize) newParams.pageSize = conf.storeConfig?.grid_per_page ?? 12
55
+ if (!newParams.pageSize) newParams.pageSize = conf?.storeConfig?.grid_per_page ?? 12
56
56
 
57
57
  if (Object.keys(params.sort).length === 0) {
58
58
  const categorySort = (await category)?.default_sort_by as keyof ProductListParams['sort']
59
- const defaultSort = conf.storeConfig?.catalog_default_sort_by as keyof ProductListParams['sort']
59
+ const defaultSort = conf?.storeConfig
60
+ ?.catalog_default_sort_by as keyof ProductListParams['sort']
60
61
  if (categorySort) newParams.sort = { [categorySort]: 'ASC' }
61
62
  else if (defaultSort) newParams.sort = { [defaultSort]: 'ASC' }
62
63
  }
@@ -4,7 +4,7 @@ import type { ChipMenuProps } from '@graphcommerce/next-ui'
4
4
  import { ChipMenu, extendableComponent } from '@graphcommerce/next-ui'
5
5
  import { Trans } from '@lingui/react/macro'
6
6
  import type { SxProps, Theme } from '@mui/material'
7
- import { ListItem, ListItemText } from '@mui/material'
7
+ import { ListItemButton, ListItemText } from '@mui/material'
8
8
  import React from 'react'
9
9
  import { useProductListLinkReplace } from '../../hooks/useProductListLinkReplace'
10
10
  import { useProductListParamsContext } from '../../hooks/useProductListParamsContext'
@@ -59,9 +59,8 @@ export function ProductListSort(props: ProductListSortProps) {
59
59
  delete linkParams.currentPage
60
60
 
61
61
  return (
62
- <ListItem
62
+ <ListItemButton
63
63
  className={classes.item}
64
- button
65
64
  key={option?.value ?? ''}
66
65
  dense
67
66
  selected={option?.value === currentSort}
@@ -81,7 +80,7 @@ export function ProductListSort(props: ProductListSortProps) {
81
80
  )}
82
81
  >
83
82
  <ListItemText>{option?.label}</ListItemText>
84
- </ListItem>
83
+ </ListItemButton>
85
84
  )
86
85
  })}
87
86
  </ChipMenu>
@@ -1,3 +1,4 @@
1
+ import { sxx } from '@graphcommerce/next-ui'
1
2
  import type { SxProps, Theme } from '@mui/material'
2
3
  import { Box } from '@mui/material'
3
4
  import type { UseAddProductsToCartActionFragment } from '../AddProductsToCart/UseAddProductsToCartAction.gql'
@@ -15,10 +16,10 @@ function ProductPageAddToCartRow(props: ProductPageAddToCartRowProps) {
15
16
  return (
16
17
  <>
17
18
  <Box
18
- sx={[
19
+ sx={sxx(
19
20
  (theme) => ({ display: 'flex', alignItems: 'center', columnGap: theme.spacings.xs }),
20
- ...(Array.isArray(sx) ? sx : [sx]),
21
- ]}
21
+ sx,
22
+ )}
22
23
  >
23
24
  {children}
24
25
  </Box>
@@ -42,7 +42,13 @@ export function ProductPageBreadcrumb(props: ProductPageBreadcrumbProps) {
42
42
  {category?.name}
43
43
  </Link>
44
44
  )}
45
- <Typography color='text.primary'>{name}</Typography>
45
+ <Typography
46
+ sx={{
47
+ color: 'text.primary',
48
+ }}
49
+ >
50
+ {name}
51
+ </Typography>
46
52
  </Breadcrumbs>
47
53
  )
48
54
  }
@@ -4,17 +4,18 @@ import {
4
4
  ColumnTwoWithTop,
5
5
  extendableComponent,
6
6
  LazyHydrate,
7
+ sxx,
7
8
  } from '@graphcommerce/next-ui'
8
9
  import type { SxProps, Theme } from '@mui/material'
9
10
  import { Box, Typography } from '@mui/material'
10
- import type { Variant } from '@mui/material/styles/createTypography'
11
+ import type { TypographyVariant } from '@mui/material/styles'
11
12
  import type { ProductListItemRenderer } from '../ProductListItems/renderer'
12
13
  import { ProductPageName } from '../ProductPageName'
13
14
  import type { ProductPageDescriptionFragment } from './ProductPageDescription.gql'
14
15
 
15
16
  export type ProductPageDescriptionProps = Omit<ColumnTwoWithTopProps, 'top' | 'left'> & {
16
17
  sx?: SxProps<Theme>
17
- fontSize?: 'responsive' | Variant
18
+ fontSize?: 'responsive' | TypographyVariant
18
19
  product: ProductPageDescriptionFragment
19
20
  productListRenderer: ProductListItemRenderer
20
21
  }
@@ -51,7 +52,7 @@ export function ProductPageDescription(props: ProductPageDescriptionProps) {
51
52
  className={classes.description}
52
53
  // eslint-disable-next-line react/no-danger
53
54
  dangerouslySetInnerHTML={{ __html: product.description.html }}
54
- sx={[
55
+ sx={sxx(
55
56
  {
56
57
  '& p:first-of-type': {
57
58
  marginTop: 0,
@@ -77,7 +78,7 @@ export function ProductPageDescription(props: ProductPageDescriptionProps) {
77
78
  fontSize,
78
79
  },
79
80
  },
80
- ]}
81
+ )}
81
82
  />
82
83
  )
83
84
  }
@@ -126,7 +126,7 @@ export function ProductVideo(props: ProductVideoProps) {
126
126
  sx={(theme) => ({
127
127
  width: '100%',
128
128
  height: '100%',
129
- background: theme.palette.background.image,
129
+ background: theme.vars.palette.background.image,
130
130
  })}
131
131
  >
132
132
  <Iframe
@@ -155,7 +155,6 @@ export function ProductVideo(props: ProductVideoProps) {
155
155
  sx={sxx(baseSx, sx, videoProps?.sx)}
156
156
  />
157
157
  ))}
158
-
159
158
  {!play && (
160
159
  <PlayCircle
161
160
  onClick={(e) => {
@@ -68,7 +68,7 @@ export function ProductPagePrice(props: ProductPagePriceProps) {
68
68
  component='span'
69
69
  className={classes.discountPrice}
70
70
  skeleton={{ variant: 'text', sx: { width: '3.5em', transform: 'none' } }}
71
- sx={[{ textDecoration: 'line-through', color: 'text.disabled' }]}
71
+ sx={sxx({ textDecoration: 'line-through', color: 'text.disabled' })}
72
72
  >
73
73
  <Money {...regularPrice} value={regularPriceValue} asNumber={asNumber} />
74
74
  </PrivateQueryMask>
@@ -80,7 +80,6 @@ export function ProductPagePrice(props: ProductPagePriceProps) {
80
80
  >
81
81
  <Money {...price} value={finalPriceValue} asNumber={asNumber} />
82
82
  </PrivateQueryMask>
83
-
84
83
  {suffix && (
85
84
  <PrivateQueryMask
86
85
  component='span'
@@ -1,4 +1,4 @@
1
- import { extendableComponent } from '@graphcommerce/next-ui'
1
+ import { extendableComponent, sxx } from '@graphcommerce/next-ui'
2
2
  import type { SxProps, Theme } from '@mui/material'
3
3
  import { Typography } from '@mui/material'
4
4
  import type { ProductShortDescriptionFragment } from './ProductShortDescription.gql'
@@ -22,13 +22,13 @@ export function ProductShortDescription(props: ProductShortDescriptionProps) {
22
22
  component='div'
23
23
  className={classes.description}
24
24
  dangerouslySetInnerHTML={{ __html: short_description?.html ?? '' }}
25
- sx={[
25
+ sx={sxx(
26
26
  {
27
27
  '& > p:first-of-type': { marginTop: 0 },
28
28
  '& > p:last-of-type': { marginBottom: 0 },
29
29
  },
30
- ...(Array.isArray(sx) ? sx : [sx]),
31
- ]}
30
+ sx,
31
+ )}
32
32
  />
33
33
  )
34
34
  }
@@ -1,6 +1,6 @@
1
1
  import { breakpointVal, iconOrderBefore, IconSvg } from '@graphcommerce/next-ui'
2
2
  import { Trans } from '@lingui/react/macro'
3
- import { Box, darken, lighten } from '@mui/material'
3
+ import { Box } from '@mui/material'
4
4
  import type { UseAddProductsToCartActionFragment } from '../AddProductsToCart/UseAddProductsToCartAction.gql'
5
5
 
6
6
  export type ProductSidebarDeliveryProps = {
@@ -19,9 +19,7 @@ export function ProductSidebarDelivery(props: ProductSidebarDeliveryProps) {
19
19
  subtitle = <Trans>We are sorry, this product is currently out of stock.</Trans>
20
20
  } else if (stock_status === 'IN_STOCK' && only_x_left_in_stock) {
21
21
  title = <Trans>Only a few left</Trans>
22
- subtitle = (
23
- <Trans>Only {only_x_left_in_stock} left in stock.</Trans>
24
- )
22
+ subtitle = <Trans>Only {only_x_left_in_stock} left in stock.</Trans>
25
23
  }
26
24
  if (only_x_left_in_stock === 1) {
27
25
  subtitle = <Trans>Only 1 left in stock.</Trans>
@@ -38,10 +36,7 @@ export function ProductSidebarDelivery(props: ProductSidebarDeliveryProps) {
38
36
  `,
39
37
  gridTemplateColumns: 'min-content auto',
40
38
  columnGap: theme.spacings.xxs,
41
- background:
42
- theme.palette.mode === 'light'
43
- ? darken(theme.palette.background.default, 0.01)
44
- : lighten(theme.palette.background.default, 0.2),
39
+ background: theme.lighten(theme.vars.palette.background.default, 0.2),
45
40
  padding: theme.spacings.xxs,
46
41
  ...breakpointVal(
47
42
  'borderRadius',
@@ -49,6 +44,9 @@ export function ProductSidebarDelivery(props: ProductSidebarDeliveryProps) {
49
44
  theme.shape.borderRadius * 4,
50
45
  theme.breakpoints.values,
51
46
  ),
47
+ ...theme.applyStyles('light', {
48
+ background: theme.darken(theme.vars.palette.background.default, 0.01),
49
+ }),
52
50
  })}
53
51
  >
54
52
  <IconSvg src={iconOrderBefore} size='small' sx={{ gridArea: 'image' }} />
@@ -1,4 +1,10 @@
1
- import { extendableComponent, responsiveVal, Row, SectionContainer } from '@graphcommerce/next-ui'
1
+ import {
2
+ extendableComponent,
3
+ responsiveVal,
4
+ Row,
5
+ SectionContainer,
6
+ sxx,
7
+ } from '@graphcommerce/next-ui'
2
8
  import type { SxProps, Theme } from '@mui/material'
3
9
  import { Box } from '@mui/material'
4
10
  import type { ProductSpecsFragment } from './ProductSpecs.gql'
@@ -25,10 +31,7 @@ export function ProductSpecs(props: ProductSpecsProps) {
25
31
  if (specs?.length === 0) return null
26
32
 
27
33
  return (
28
- <Row
29
- className={classes.root}
30
- sx={[{ typography: 'subtitle1' }, ...(Array.isArray(sx) ? sx : [sx])]}
31
- >
34
+ <Row className={classes.root} sx={sxx({ typography: 'subtitle1' }, sx)}>
32
35
  <SectionContainer
33
36
  labelLeft={title}
34
37
  sx={(theme) => ({ '& .SectionHeader-root': { marginBottom: theme.spacings.md } })}
@@ -1,17 +1,22 @@
1
- import type { ApolloClient, ApolloQueryResult, NormalizedCacheObject } from '@graphcommerce/graphql'
1
+ import type { ApolloClient } from '@graphcommerce/graphql'
2
2
  import { limitSsg } from '@graphcommerce/next-config/config'
3
3
  import type { GetStaticPathsResult } from 'next'
4
- import type { ProductStaticPathsQuery } from './ProductStaticPaths.gql'
5
4
  import { ProductStaticPathsDocument } from './ProductStaticPaths.gql'
6
5
 
7
6
  type Return = GetStaticPathsResult<{ url: string }>
8
7
 
9
8
  export type ProductTypenames = NonNullable<
10
- NonNullable<NonNullable<ProductStaticPathsQuery['products']>['items']>[0]
11
- >['__typename']
9
+ NonNullable<
10
+ NonNullable<
11
+ Awaited<ReturnType<typeof getProductStaticPaths>> extends Return
12
+ ? Return['paths'][number]
13
+ : never
14
+ >
15
+ >
16
+ >
12
17
 
13
18
  export async function getProductStaticPaths(
14
- client: ApolloClient<NormalizedCacheObject>,
19
+ client: ApolloClient,
15
20
  locale: string,
16
21
  options: { limit?: boolean } = { limit: limitSsg || false },
17
22
  ) {
@@ -19,10 +24,11 @@ export async function getProductStaticPaths(
19
24
  query: ProductStaticPathsDocument,
20
25
  variables: { currentPage: 1, pageSize: 100 },
21
26
  })
22
- const pages: Promise<ApolloQueryResult<ProductStaticPathsQuery>>[] = [query]
23
27
 
24
28
  const { data } = await query
25
- const totalPages = data.products?.page_info?.total_pages ?? 1
29
+ const totalPages = data?.products?.page_info?.total_pages ?? 1
30
+
31
+ const pages = [query]
26
32
 
27
33
  if (totalPages > 1 && options.limit !== true) {
28
34
  for (let i = 2; i <= totalPages; i++) {
@@ -36,7 +42,7 @@ export async function getProductStaticPaths(
36
42
  }
37
43
 
38
44
  const paths: Return['paths'] = (await Promise.all(pages))
39
- .map((q) => q.data.products?.items)
45
+ .map((q) => q.data?.products?.items ?? [])
40
46
  .flat(1)
41
47
  .map((p) => ({ params: { url: `${p?.url_key}` }, locale }))
42
48
 
@@ -1,4 +1,4 @@
1
- import type { ApolloClient, NormalizedCacheObject } from '@graphcommerce/graphql'
1
+ import type { ApolloClient } from '@graphcommerce/graphql'
2
2
  import { canonicalize, nonNullable } from '@graphcommerce/next-ui'
3
3
  import { productLink } from '../../hooks/useProductLink'
4
4
  import { ProductStaticPathsDocument } from './ProductStaticPaths.gql'
@@ -8,7 +8,7 @@ import { ProductStaticPathsDocument } from './ProductStaticPaths.gql'
8
8
  * @public
9
9
  */
10
10
  export async function getSitemapPaths(
11
- client: ApolloClient<NormalizedCacheObject>,
11
+ client: ApolloClient,
12
12
  ctx: { locale?: string; defaultLocale?: string },
13
13
  pageSize: number,
14
14
  ) {
@@ -16,11 +16,11 @@ export async function getSitemapPaths(
16
16
  const query = ProductStaticPathsDocument
17
17
 
18
18
  const pageInfo = client.query({ query, variables: { currentPage: 1, pageSize } })
19
- const total = (await pageInfo).data.products?.page_info?.total_pages || 0
19
+ const total = (await pageInfo).data?.products?.page_info?.total_pages || 0
20
20
 
21
21
  const result = Array.from(Array(total).keys()).map(async (currentPage) => {
22
22
  const res = await client.query({ query, variables: { currentPage: currentPage + 1, pageSize } })
23
- return res.data.products?.items
23
+ return res.data?.products?.items
24
24
  })
25
25
 
26
26
  const options = { locale, defaultLocale, pathname: '/', isLocaleDomain: false }
@@ -45,4 +45,3 @@ export * from './ProductStaticPaths/getProductStaticPaths'
45
45
  export * from './ProductStaticPaths/getSitemapPaths'
46
46
  export * from './ProductUpsells/UpsellProducts.gql'
47
47
  export * from './ProductWeight/ProductWeight'
48
-
@@ -34,7 +34,7 @@ export const prefetchProductList = debounce(
34
34
  variables: ProductListQueryVariables,
35
35
  filtersVariables: ProductFiltersQueryVariables,
36
36
  next: Next,
37
- client: ApolloClient<unknown>,
37
+ client: ApolloClient,
38
38
  shallow: boolean,
39
39
  ) => {
40
40
  if (!shallow) return next(shallow)
package/package.json CHANGED
@@ -2,7 +2,7 @@
2
2
  "name": "@graphcommerce/magento-product",
3
3
  "homepage": "https://www.graphcommerce.org/",
4
4
  "repository": "github:graphcommerce-org/graphcommerce",
5
- "version": "10.0.0-canary.67",
5
+ "version": "10.0.0-canary.72",
6
6
  "sideEffects": false,
7
7
  "prettier": "@graphcommerce/prettier-config-pwa",
8
8
  "eslintConfig": {
@@ -18,22 +18,22 @@
18
18
  "typescript": "5.9.3"
19
19
  },
20
20
  "peerDependencies": {
21
- "@graphcommerce/ecommerce-ui": "^10.0.0-canary.67",
22
- "@graphcommerce/eslint-config-pwa": "^10.0.0-canary.67",
23
- "@graphcommerce/framer-next-pages": "^10.0.0-canary.67",
24
- "@graphcommerce/framer-scroller": "^10.0.0-canary.67",
25
- "@graphcommerce/graphql": "^10.0.0-canary.67",
26
- "@graphcommerce/graphql-mesh": "^10.0.0-canary.67",
27
- "@graphcommerce/image": "^10.0.0-canary.67",
28
- "@graphcommerce/magento-cart": "^10.0.0-canary.67",
29
- "@graphcommerce/magento-store": "^10.0.0-canary.67",
30
- "@graphcommerce/next-ui": "^10.0.0-canary.67",
31
- "@graphcommerce/prettier-config-pwa": "^10.0.0-canary.67",
32
- "@graphcommerce/typescript-config-pwa": "^10.0.0-canary.67",
21
+ "@graphcommerce/ecommerce-ui": "^10.0.0-canary.72",
22
+ "@graphcommerce/eslint-config-pwa": "^10.0.0-canary.72",
23
+ "@graphcommerce/framer-next-pages": "^10.0.0-canary.72",
24
+ "@graphcommerce/framer-scroller": "^10.0.0-canary.72",
25
+ "@graphcommerce/graphql": "^10.0.0-canary.72",
26
+ "@graphcommerce/graphql-mesh": "^10.0.0-canary.72",
27
+ "@graphcommerce/image": "^10.0.0-canary.72",
28
+ "@graphcommerce/magento-cart": "^10.0.0-canary.72",
29
+ "@graphcommerce/magento-store": "^10.0.0-canary.72",
30
+ "@graphcommerce/next-ui": "^10.0.0-canary.72",
31
+ "@graphcommerce/prettier-config-pwa": "^10.0.0-canary.72",
32
+ "@graphcommerce/typescript-config-pwa": "^10.0.0-canary.72",
33
33
  "@lingui/core": "^5",
34
34
  "@lingui/macro": "^5",
35
35
  "@lingui/react": "^5",
36
- "@mui/material": "^5.10.16",
36
+ "@mui/material": "^7.0.0",
37
37
  "framer-motion": "^11.0.0",
38
38
  "next": "*",
39
39
  "react": "^19.2.0",