@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 +2 -0
- package/components/ProductFiltersPro/ProductFiltersProNoResults.tsx +2 -2
- package/components/ProductList/ProductList.graphql +2 -1
- package/components/ProductListItem/ProductListItem.tsx +43 -13
- package/components/ProductListItem/ProductListItemImage.tsx +4 -4
- package/components/ProductListItem/ProductListItemLinkOrDiv.tsx +9 -5
- package/components/ProductListSuggestions/ProductListSearchSuggestion.graphql +3 -0
- package/components/ProductListSuggestions/ProductListSuggestions.graphql +1 -1
- package/components/index.ts +5 -0
- package/package.json +13 -13
package/CHANGELOG.md
CHANGED
@@ -33,8 +33,8 @@ export function ProductFiltersProNoResults(props: ProductFitlersProNoResultProps
|
|
33
33
|
>
|
34
34
|
{term ? (
|
35
35
|
<>
|
36
|
-
<Typography variant='h5'
|
37
|
-
<Trans>We couldn
|
36
|
+
<Typography variant='h5'>
|
37
|
+
<Trans>We couldn’t 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
|
-
|
48
|
-
|
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
|
-
|
93
|
-
|
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 {
|
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
|
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
|
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
|
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
|
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
|
83
|
+
<PlaceHolderContainer className={`${classes?.placeholder} ${classes?.image}`}>
|
84
84
|
<Box
|
85
85
|
sx={[
|
86
86
|
{
|
@@ -1,6 +1,7 @@
|
|
1
|
-
import {
|
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
|
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
|
+
})
|
package/components/index.ts
CHANGED
@@ -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.
|
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.
|
22
|
-
"@graphcommerce/eslint-config-pwa": "^9.0.0-canary.
|
23
|
-
"@graphcommerce/framer-next-pages": "^9.0.0-canary.
|
24
|
-
"@graphcommerce/framer-scroller": "^9.0.0-canary.
|
25
|
-
"@graphcommerce/graphql": "^9.0.0-canary.
|
26
|
-
"@graphcommerce/graphql-mesh": "^9.0.0-canary.
|
27
|
-
"@graphcommerce/image": "^9.0.0-canary.
|
28
|
-
"@graphcommerce/magento-cart": "^9.0.0-canary.
|
29
|
-
"@graphcommerce/magento-store": "^9.0.0-canary.
|
30
|
-
"@graphcommerce/next-ui": "^9.0.0-canary.
|
31
|
-
"@graphcommerce/prettier-config-pwa": "^9.0.0-canary.
|
32
|
-
"@graphcommerce/typescript-config-pwa": "^9.0.0-canary.
|
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",
|