@graphcommerce/magento-product 9.0.0-canary.116 → 9.0.0-canary.117

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.
package/CHANGELOG.md CHANGED
@@ -1,5 +1,7 @@
1
1
  # Change Log
2
2
 
3
+ ## 9.0.0-canary.117
4
+
3
5
  ## 9.0.0-canary.116
4
6
 
5
7
  ### Patch Changes
@@ -33,8 +33,8 @@ export function ProductFiltersProNoResults(props: ProductFitlersProNoResultProps
33
33
  >
34
34
  {term ? (
35
35
  <>
36
- <Typography variant='h5' align='center'>
37
- <Trans>We couldn&apos;t find any results for {term}</Trans>
36
+ <Typography variant='h5'>
37
+ <Trans>We couldnt find any results for {term}’</Trans>
38
38
  </Typography>
39
39
  <p>
40
40
  {hasFilters ? (
@@ -6,6 +6,7 @@ query ProductList(
6
6
  $search: String = ""
7
7
  $context: PrivateContext
8
8
  $onlyItems: Boolean = false
9
+ $quickSearch: Boolean = false
9
10
  ) {
10
11
  products(
11
12
  pageSize: $pageSize
@@ -16,7 +17,7 @@ query ProductList(
16
17
  ) @privateContext(context: $context) {
17
18
  ...ProductListSuggestions @skip(if: $onlyItems)
18
19
  ...ProductListFilters @skip(if: $onlyItems)
19
- ...ProductListCount @skip(if: $onlyItems)
20
+ ...ProductListCount @skip(if: $onlyItems) @include(if: $quickSearch)
20
21
  ...ProductListPagination @skip(if: $onlyItems)
21
22
  ...ProductListSort @skip(if: $onlyItems)
22
23
  ...ProductListItems
@@ -14,7 +14,7 @@ import type {
14
14
  ProductListsItemImageAreaProps,
15
15
  } from './ProductListItemImageContainer'
16
16
  import { ProductImageContainer, ProductListItemImageAreas } from './ProductListItemImageContainer'
17
- import { ProductListItemLinkOrDiv } from './ProductListItemLinkOrDiv'
17
+ import { ProductListItemLinkOrDiv, ProductListItemLinkOrDivProps } from './ProductListItemLinkOrDiv'
18
18
  import type { ProductListItemTitleAndPriceProps } from './ProductListItemTitleAndPrice'
19
19
  import { ProductListItemTitleAndPrice } from './ProductListItemTitleAndPrice'
20
20
 
@@ -44,15 +44,22 @@ export type BaseProps = {
44
44
  imageOnly?: boolean
45
45
  children?: React.ReactNode
46
46
  sx?: SxProps<Theme>
47
- // eslint-disable-next-line react/no-unused-prop-types
48
- onClick?: (event: React.MouseEvent<HTMLAnchorElement>, item: ProductListItemFragment) => void
47
+ onClick?: (
48
+ event: React.MouseEvent<HTMLAnchorElement | HTMLDivElement>,
49
+ item: ProductListItemFragment,
50
+ ) => void
51
+ slotProps?: {
52
+ root?: Partial<ProductListItemLinkOrDivProps>
53
+ image?: Partial<ProductListItemImageProps>
54
+ imageAreas?: Partial<ProductListsItemImageAreaProps>
55
+ titleAndPrice?: Partial<ProductListItemTitleAndPriceProps>
56
+ }
49
57
  } & StyleProps &
50
58
  Omit<ProductListItemTitleAndPriceProps, 'title' | 'classes' | 'children'> &
51
59
  Omit<ProductListItemImageProps, 'classes'> &
52
60
  Omit<ProductListsItemImageAreaProps, 'classes'> &
53
61
  Pick<ImageProps, 'loading' | 'sizes' | 'dontReportWronglySizedImages'>
54
62
 
55
- // eslint-disable-next-line react/no-unused-prop-types
56
63
  export type SkeletonProps = BaseProps & { __typename: 'Skeleton' }
57
64
 
58
65
  export type ProductProps = BaseProps & ProductListItemFragment
@@ -79,18 +86,20 @@ export function ProductListItemReal(props: ProductProps) {
79
86
  titleComponent = 'h2',
80
87
  sx = [],
81
88
  onClick,
89
+ slotProps = {},
82
90
  } = props
83
91
 
84
- const handleClick = useEventCallback((e: React.MouseEvent<HTMLAnchorElement>) =>
85
- onClick?.(e, props),
86
- )
87
-
88
92
  return (
89
93
  <ProductListItemLinkOrDiv
90
94
  href={productLink(props)}
91
95
  className={classes.root}
92
- sx={sx}
93
- onClick={handleClick}
96
+ onClick={(e: React.MouseEvent<HTMLAnchorElement | HTMLDivElement>) => onClick?.(e, props)}
97
+ {...slotProps.root}
98
+ sx={[
99
+ ...(Array.isArray(sx) ? sx : [sx]),
100
+ ...(Array.isArray(slotProps.root?.sx) ? slotProps.root.sx : [slotProps.root?.sx]),
101
+ ]}
102
+ ref={slotProps.root?.ref as React.Ref<HTMLAnchorElement | HTMLDivElement>}
94
103
  >
95
104
  <ProductImageContainer className={classes.imageContainer}>
96
105
  <ProductListItemImage
@@ -101,6 +110,7 @@ export function ProductListItemReal(props: ProductProps) {
101
110
  loading={loading}
102
111
  sizes={sizes}
103
112
  dontReportWronglySizedImages={dontReportWronglySizedImages}
113
+ {...slotProps.image}
104
114
  />
105
115
 
106
116
  {!imageOnly && (
@@ -115,6 +125,7 @@ export function ProductListItemReal(props: ProductProps) {
115
125
  {topLeft}
116
126
  </>
117
127
  }
128
+ {...slotProps.imageAreas}
118
129
  />
119
130
  )}
120
131
  </ProductImageContainer>
@@ -126,6 +137,7 @@ export function ProductListItemReal(props: ProductProps) {
126
137
  titleComponent={titleComponent}
127
138
  title={name}
128
139
  subTitle={subTitle}
140
+ {...slotProps.titleAndPrice}
129
141
  >
130
142
  <ProductListPrice {...price_range.minimum_price} />
131
143
  </ProductListItemTitleAndPrice>
@@ -138,12 +150,28 @@ export function ProductListItemReal(props: ProductProps) {
138
150
 
139
151
  /** @public */
140
152
  export function ProductListItemSkeleton(props: BaseProps) {
141
- const { children, imageOnly = false, aspectRatio, titleComponent = 'h2', sx = [] } = props
153
+ const {
154
+ children,
155
+ imageOnly = false,
156
+ aspectRatio,
157
+ titleComponent = 'h2',
158
+ sx = [],
159
+ slotProps = {},
160
+ } = props
142
161
 
143
162
  return (
144
- <ProductListItemLinkOrDiv sx={sx} className={classes.root}>
163
+ <ProductListItemLinkOrDiv
164
+ sx={sx}
165
+ className={classes.root}
166
+ {...slotProps.root}
167
+ ref={slotProps.root?.ref as React.Ref<HTMLAnchorElement | HTMLDivElement>}
168
+ >
145
169
  <ProductImageContainer className={classes.imageContainer}>
146
- <ProductListItemImageSkeleton classes={classes} aspectRatio={aspectRatio} />
170
+ <ProductListItemImageSkeleton
171
+ classes={classes}
172
+ aspectRatio={aspectRatio}
173
+ {...slotProps.image}
174
+ />
147
175
  </ProductImageContainer>
148
176
 
149
177
  {!imageOnly && (
@@ -153,6 +181,7 @@ export function ProductListItemSkeleton(props: BaseProps) {
153
181
  titleComponent={titleComponent}
154
182
  title={<Skeleton variant='text' sx={{ width: '100px' }} />}
155
183
  subTitle={<Skeleton variant='text' sx={{ width: '20px' }} />}
184
+ {...slotProps.titleAndPrice}
156
185
  >
157
186
  <Skeleton variant='text' sx={{ width: '20px' }} />
158
187
  </ProductListItemTitleAndPrice>
@@ -166,6 +195,7 @@ export function ProductListItemSkeleton(props: BaseProps) {
166
195
  function isSkeleton(props: ProductListItemProps): props is SkeletonProps {
167
196
  return props.__typename === 'Skeleton'
168
197
  }
198
+
169
199
  export function ProductListItem(props: ProductListItemProps) {
170
200
  return isSkeleton(props) ? (
171
201
  <ProductListItemSkeleton {...props} />
@@ -26,7 +26,7 @@ function PlaceHolderContainer(props: BoxProps) {
26
26
 
27
27
  export type ProductListItemImageProps = {
28
28
  aspectRatio?: [number, number]
29
- classes: {
29
+ classes?: {
30
30
  image?: string
31
31
  placeholder?: string
32
32
  }
@@ -35,7 +35,7 @@ export type ProductListItemImageProps = {
35
35
  export function ProductListItemImageSkeleton(props: ProductListItemImageProps) {
36
36
  const { aspectRatio = [4, 3], classes } = props
37
37
  return (
38
- <PlaceHolderContainer className={`${classes.placeholder} ${classes.image}`}>
38
+ <PlaceHolderContainer className={`${classes?.placeholder} ${classes?.image}`}>
39
39
  <Skeleton
40
40
  animation='wave'
41
41
  sx={{
@@ -66,7 +66,7 @@ export function ProductListItemImage(props: ImageOrPlaceholderProps) {
66
66
  src={src}
67
67
  alt={alt ?? ''}
68
68
  {...image}
69
- className={classes.image}
69
+ className={classes?.image}
70
70
  sx={[
71
71
  {
72
72
  objectFit: 'contain',
@@ -80,7 +80,7 @@ export function ProductListItemImage(props: ImageOrPlaceholderProps) {
80
80
  }
81
81
 
82
82
  return (
83
- <PlaceHolderContainer className={`${classes.placeholder} ${classes.image}`}>
83
+ <PlaceHolderContainer className={`${classes?.placeholder} ${classes?.image}`}>
84
84
  <Box
85
85
  sx={[
86
86
  {
@@ -1,6 +1,7 @@
1
- import { NextLink, breakpointVal } from '@graphcommerce/next-ui'
1
+ import { breakpointVal, NextLink } from '@graphcommerce/next-ui'
2
2
  import type { BoxProps, ButtonBaseProps, SxProps, Theme } from '@mui/material'
3
3
  import { Box, ButtonBase } from '@mui/material'
4
+ import React from 'react'
4
5
 
5
6
  export type ProductListItemLinkProps = ButtonBaseProps<typeof NextLink>
6
7
  export type ProductListItemLinkOrDivProps = ProductListItemLinkProps | BoxProps
@@ -9,7 +10,10 @@ function isLink(props: ProductListItemLinkOrDivProps): props is ProductListItemL
9
10
  return 'href' in props
10
11
  }
11
12
 
12
- export function ProductListItemLinkOrDiv(props: ProductListItemLinkOrDivProps) {
13
+ export const ProductListItemLinkOrDiv = React.forwardRef<
14
+ HTMLDivElement | HTMLAnchorElement,
15
+ ProductListItemLinkOrDivProps
16
+ >((props, ref) => {
13
17
  const { sx = [] } = props
14
18
 
15
19
  const sxProps: SxProps<Theme> = [
@@ -28,8 +32,8 @@ export function ProductListItemLinkOrDiv(props: ProductListItemLinkOrDivProps) {
28
32
  ]
29
33
 
30
34
  return isLink(props) ? (
31
- <ButtonBase component={NextLink} {...props} sx={sxProps} />
35
+ <ButtonBase ref={ref} component={NextLink} {...props} sx={sxProps} focusRipple />
32
36
  ) : (
33
- <Box {...props} sx={sxProps} />
37
+ <Box ref={ref} component='div' {...props} sx={sxProps} />
34
38
  )
35
- }
39
+ })
@@ -0,0 +1,3 @@
1
+ fragment ProductListSearchSuggestion on SearchSuggestion {
2
+ search
3
+ }
@@ -1,5 +1,5 @@
1
1
  fragment ProductListSuggestions on Products {
2
2
  suggestions {
3
- search
3
+ ...ProductListSearchSuggestion
4
4
  }
5
5
  }
@@ -8,6 +8,10 @@ export * from './ProductListCount/ProductListCount'
8
8
  export * from './ProductListFilters'
9
9
  export * from './ProductListFiltersContainer/ProductListFiltersContainer'
10
10
  export * from './ProductListItem/ProductListItem'
11
+ export * from './ProductListItem/ProductListItemImage'
12
+ export * from './ProductListItem/ProductListItemTitleAndPrice'
13
+ export * from './ProductListItem/ProductListItemImageContainer'
14
+ export * from './ProductListItem/ProductListItemLinkOrDiv'
11
15
  export * from './ProductListItems/filteredProductList'
12
16
  export * from './ProductListItems/filterTypes'
13
17
  export * from './ProductListItems/getFilterTypes'
@@ -43,3 +47,4 @@ export * from './ProductWeight/ProductWeight'
43
47
  export * from './ProductListPrice'
44
48
  export * from './ProductListSuggestions/ProductListSuggestions'
45
49
  export * from './ProductListSuggestions/ProductListSuggestions.gql'
50
+ export * from './ProductListSuggestions/ProductListSearchSuggestion.gql'
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": "9.0.0-canary.116",
5
+ "version": "9.0.0-canary.117",
6
6
  "sideEffects": false,
7
7
  "prettier": "@graphcommerce/prettier-config-pwa",
8
8
  "eslintConfig": {
@@ -18,18 +18,18 @@
18
18
  "typescript": "5.7.2"
19
19
  },
20
20
  "peerDependencies": {
21
- "@graphcommerce/ecommerce-ui": "^9.0.0-canary.116",
22
- "@graphcommerce/eslint-config-pwa": "^9.0.0-canary.116",
23
- "@graphcommerce/framer-next-pages": "^9.0.0-canary.116",
24
- "@graphcommerce/framer-scroller": "^9.0.0-canary.116",
25
- "@graphcommerce/graphql": "^9.0.0-canary.116",
26
- "@graphcommerce/graphql-mesh": "^9.0.0-canary.116",
27
- "@graphcommerce/image": "^9.0.0-canary.116",
28
- "@graphcommerce/magento-cart": "^9.0.0-canary.116",
29
- "@graphcommerce/magento-store": "^9.0.0-canary.116",
30
- "@graphcommerce/next-ui": "^9.0.0-canary.116",
31
- "@graphcommerce/prettier-config-pwa": "^9.0.0-canary.116",
32
- "@graphcommerce/typescript-config-pwa": "^9.0.0-canary.116",
21
+ "@graphcommerce/ecommerce-ui": "^9.0.0-canary.117",
22
+ "@graphcommerce/eslint-config-pwa": "^9.0.0-canary.117",
23
+ "@graphcommerce/framer-next-pages": "^9.0.0-canary.117",
24
+ "@graphcommerce/framer-scroller": "^9.0.0-canary.117",
25
+ "@graphcommerce/graphql": "^9.0.0-canary.117",
26
+ "@graphcommerce/graphql-mesh": "^9.0.0-canary.117",
27
+ "@graphcommerce/image": "^9.0.0-canary.117",
28
+ "@graphcommerce/magento-cart": "^9.0.0-canary.117",
29
+ "@graphcommerce/magento-store": "^9.0.0-canary.117",
30
+ "@graphcommerce/next-ui": "^9.0.0-canary.117",
31
+ "@graphcommerce/prettier-config-pwa": "^9.0.0-canary.117",
32
+ "@graphcommerce/typescript-config-pwa": "^9.0.0-canary.117",
33
33
  "@lingui/core": "^4.2.1",
34
34
  "@lingui/macro": "^4.2.1",
35
35
  "@lingui/react": "^4.2.1",