@graphcommerce/magento-product-configurable 9.0.0-canary.99 → 9.0.1-canary.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 (29) hide show
  1. package/CHANGELOG.md +88 -1053
  2. package/ConfigurableCartItem/ConfigurableCartItem.tsx +7 -2
  3. package/ConfigurableCartItem/OptionsList.tsx +5 -4
  4. package/SwatchList.tsx +3 -3
  5. package/Swatches/ColorSwatchData.tsx +7 -6
  6. package/Swatches/ImageSwatchData.tsx +8 -6
  7. package/Swatches/TextSwatchData.tsx +6 -5
  8. package/Swatches/types.ts +4 -4
  9. package/components/ConfigurableCartItemOptions/ConfigurableCartItemOptions.tsx +4 -3
  10. package/components/ConfigurableOptionValue/ConfigurableOptionValue.tsx +2 -2
  11. package/components/ConfigurableOptionValueColor/ConfigurableOptionValueColor.tsx +2 -2
  12. package/components/ConfigurableOptionValueImage/ConfigurableOptionValueImage.tsx +2 -2
  13. package/components/ConfigurableOptionValueText/ConfigurableOptionValueText.tsx +2 -2
  14. package/components/ConfigurableProductOptions/ConfigurableProductOption.tsx +16 -13
  15. package/components/ConfigurableProductOptions/ConfigurableProductOptions.tsx +11 -5
  16. package/components/ProductListItemConfigurable/ProductListItemConfigurable.tsx +3 -6
  17. package/hooks/useConfigurableOptionsSelection.ts +2 -1
  18. package/index.ts +0 -2
  19. package/package.json +19 -19
  20. package/plugins/ConfigurableProductPage/ConfigurableProductPageDescription.tsx +2 -2
  21. package/plugins/ConfigurableProductPage/ConfigurableProductPageGallery.tsx +1 -0
  22. package/plugins/ConfigurableProductPage/ConfigurableProductPageMeta.tsx +2 -5
  23. package/plugins/ConfigurableProductPage/ConfigurableProductPagePrice.tsx +1 -1
  24. package/test/addConfigurableProductToCart.ts +2 -1
  25. package/utils/defaultConfigurableOptionsSelection.ts +3 -3
  26. package/ConfigurableContext/ConfigurableContext.tsx +0 -165
  27. package/ConfigurableContext/cheapestVariant.ts +0 -14
  28. package/ConfigurableOptions/ConfigurableOptions.tsx +0 -143
  29. package/ConfigurableProductAddToCart/ConfigurableProductAddToCart.tsx +0 -185
@@ -1,7 +1,12 @@
1
- import { CartItem, CartItemProps } from '@graphcommerce/magento-cart-items'
2
- import { ConfigurableCartItemFragment } from './ConfigurableCartItem.gql'
1
+ import type { CartItemProps } from '@graphcommerce/magento-cart-items'
2
+ import { CartItem } from '@graphcommerce/magento-cart-items'
3
+ import type { ConfigurableCartItemFragment } from './ConfigurableCartItem.gql'
3
4
  import { OptionsList } from './OptionsList'
4
5
 
6
+ /**
7
+ * @deprecated
8
+ * @public
9
+ */
5
10
  export function ConfigurableCartItem(props: ConfigurableCartItemFragment & CartItemProps) {
6
11
  const { configurable_options, configured_variant, product } = props
7
12
  return (
@@ -1,12 +1,13 @@
1
1
  import { extendableComponent } from '@graphcommerce/next-ui'
2
- import { Box, SxProps, Theme } from '@mui/material'
3
- import { ConfigurableCartItemFragment } from './ConfigurableCartItem.gql'
2
+ import type { SxProps, Theme } from '@mui/material'
3
+ import { Box } from '@mui/material'
4
+ import type { ConfigurableCartItemFragment } from './ConfigurableCartItem.gql'
4
5
 
5
- type CartItemOptionsListProps = Partial<ConfigurableCartItemFragment> & {
6
+ export type CartItemOptionsListProps = Partial<ConfigurableCartItemFragment> & {
6
7
  sx?: SxProps<Theme>
7
8
  }
8
9
 
9
- const name = 'ColorSwatchData' as const
10
+ const name = 'ColorSwatchData'
10
11
  const parts = ['root', 'option'] as const
11
12
  const { classes } = extendableComponent(name, parts)
12
13
 
package/SwatchList.tsx CHANGED
@@ -4,10 +4,10 @@ import React from 'react'
4
4
  import { ColorSwatchData } from './Swatches/ColorSwatchData'
5
5
  import { ImageSwatchData } from './Swatches/ImageSwatchData'
6
6
  import { TextSwatchData } from './Swatches/TextSwatchData'
7
- import { SwatchSize, SwatchTypeRenderer } from './Swatches/types'
8
- import { ProductListItemConfigurableFragment } from './components/ProductListItemConfigurable/ProductListItemConfigurable.gql'
7
+ import type { SwatchSize, SwatchTypeRenderer } from './Swatches/types'
8
+ import type { ProductListItemConfigurableFragment } from './components/ProductListItemConfigurable/ProductListItemConfigurable.gql'
9
9
 
10
- type SwatchListProps = {
10
+ export type SwatchListProps = {
11
11
  attributes?: string[]
12
12
  configurable_options?: Maybe<ProductListItemConfigurableFragment['configurable_options']>
13
13
  }
@@ -1,15 +1,16 @@
1
- import { responsiveVal, extendableComponent } from '@graphcommerce/next-ui'
2
- import { Box, SxProps, Theme } from '@mui/material'
3
- import { ColorSwatchDataFragment } from './ColorSwatchData.gql'
4
- import { SwatchDataProps } from './types'
1
+ import { extendableComponent, responsiveVal } from '@graphcommerce/next-ui'
2
+ import type { SxProps, Theme } from '@mui/material'
3
+ import { Box } from '@mui/material'
4
+ import type { ColorSwatchDataFragment } from './ColorSwatchData.gql'
5
+ import type { SwatchDataProps } from './types'
5
6
 
6
- type ColorSwatchDataProps = ColorSwatchDataFragment &
7
+ export type ColorSwatchDataProps = ColorSwatchDataFragment &
7
8
  SwatchDataProps & {
8
9
  sx?: SxProps<Theme>
9
10
  }
10
11
 
11
12
  type OwnerState = Pick<SwatchDataProps, 'size'>
12
- const name = 'ColorSwatchData' as const
13
+ const name = 'ColorSwatchData'
13
14
  const parts = ['root', 'color', 'label'] as const
14
15
  const { withState } = extendableComponent<OwnerState, typeof name, typeof parts>(name, parts)
15
16
 
@@ -1,13 +1,15 @@
1
1
  import { Image } from '@graphcommerce/image'
2
- import { responsiveVal, extendableComponent } from '@graphcommerce/next-ui'
3
- import { Box, SxProps, Theme } from '@mui/material'
4
- import { ImageSwatchDataFragment } from './ImageSwatchData.gql'
5
- import { SwatchDataProps } from './types'
2
+ import { extendableComponent, responsiveVal } from '@graphcommerce/next-ui'
3
+ import type { SxProps, Theme } from '@mui/material'
4
+ import { Box } from '@mui/material'
5
+ import type { ImageSwatchDataFragment } from './ImageSwatchData.gql'
6
+ import type { SwatchDataProps } from './types'
6
7
 
7
- type ImageSwatchDataProps = ImageSwatchDataFragment & SwatchDataProps & { sx?: SxProps<Theme> }
8
+ export type ImageSwatchDataProps = ImageSwatchDataFragment &
9
+ SwatchDataProps & { sx?: SxProps<Theme> }
8
10
 
9
11
  type OwnerState = Pick<SwatchDataProps, 'size'>
10
- const name = 'ColorSwatchData' as const
12
+ const name = 'ColorSwatchData'
11
13
  const parts = ['root', 'image', 'label'] as const
12
14
  const { withState } = extendableComponent<OwnerState, typeof name, typeof parts>(name, parts)
13
15
 
@@ -1,13 +1,14 @@
1
1
  import { Money } from '@graphcommerce/magento-store'
2
2
  import { extendableComponent } from '@graphcommerce/next-ui'
3
- import { Box, SxProps, Theme } from '@mui/material'
4
- import { TextSwatchDataFragment } from './TextSwatchData.gql'
5
- import { SwatchDataProps } from './types'
3
+ import type { SxProps, Theme } from '@mui/material'
4
+ import { Box } from '@mui/material'
5
+ import type { TextSwatchDataFragment } from './TextSwatchData.gql'
6
+ import type { SwatchDataProps } from './types'
6
7
 
7
- type TextSwatchDataProps = TextSwatchDataFragment & SwatchDataProps & { sx?: SxProps<Theme> }
8
+ export type TextSwatchDataProps = TextSwatchDataFragment & SwatchDataProps & { sx?: SxProps<Theme> }
8
9
 
9
10
  type OwnerState = Pick<SwatchDataProps, 'size'>
10
- const name = 'TextSwatchData' as const
11
+ const name = 'TextSwatchData'
11
12
  const parts = ['root', 'value', 'price', 'label', 'storeLabel', 'content'] as const
12
13
  const { withState } = extendableComponent<OwnerState, typeof name, typeof parts>(name, parts)
13
14
 
package/Swatches/types.ts CHANGED
@@ -1,7 +1,7 @@
1
- import { MoneyProps } from '@graphcommerce/magento-store'
2
- import { TypeRenderer } from '@graphcommerce/next-ui'
3
- import { ProductListItemConfigurableFragment } from '../components/ProductListItemConfigurable/ProductListItemConfigurable.gql'
4
- import { SwatchDataFragment } from './SwatchData.gql'
1
+ import type { MoneyProps } from '@graphcommerce/magento-store'
2
+ import type { TypeRenderer } from '@graphcommerce/next-ui'
3
+ import type { ProductListItemConfigurableFragment } from '../components/ProductListItemConfigurable/ProductListItemConfigurable.gql'
4
+ import type { SwatchDataFragment } from './SwatchData.gql'
5
5
 
6
6
  type ConfigurableOption = NonNullable<
7
7
  NonNullable<ProductListItemConfigurableFragment['configurable_options']>[0]
@@ -1,8 +1,9 @@
1
- import { CartItemFragment, SelectedCustomizableOptions } from '@graphcommerce/magento-cart-items'
1
+ import type { CartItemFragment } from '@graphcommerce/magento-cart-items'
2
+ import { SelectedCustomizableOptions } from '@graphcommerce/magento-cart-items'
2
3
  import { Box } from '@mui/material'
3
- import { ConfigurableCartItemFragment } from '../../ConfigurableCartItem/ConfigurableCartItem.gql'
4
+ import type { ConfigurableCartItemFragment } from '../../ConfigurableCartItem/ConfigurableCartItem.gql'
4
5
 
5
- type ConfigurableActionCartItemProps = ConfigurableCartItemFragment & CartItemFragment
6
+ export type ConfigurableActionCartItemProps = ConfigurableCartItemFragment & CartItemFragment
6
7
 
7
8
  export function ConfigurableCartItemOptions(props: ConfigurableActionCartItemProps) {
8
9
  const { configurable_options } = props
@@ -1,9 +1,9 @@
1
- import { ActionCardItemRenderProps } from '@graphcommerce/ecommerce-ui'
1
+ import type { ActionCardItemRenderProps } from '@graphcommerce/ecommerce-ui'
2
2
  import { RenderType } from '@graphcommerce/next-ui'
3
3
  import { ConfigurableOptionValueColor } from '../ConfigurableOptionValueColor'
4
4
  import { ConfigurableOptionValueImage } from '../ConfigurableOptionValueImage/ConfigurableOptionValueImage'
5
5
  import { ConfigurableOptionValueText } from '../ConfigurableOptionValueText/ConfigurableOptionValueText'
6
- import { ConfigurableOptionValueFragment } from './ConfigurableOptionValue.gql'
6
+ import type { ConfigurableOptionValueFragment } from './ConfigurableOptionValue.gql'
7
7
 
8
8
  export type ConfigurabeOptionValueProps = ActionCardItemRenderProps<ConfigurableOptionValueFragment>
9
9
 
@@ -1,8 +1,8 @@
1
- import { ActionCardItemRenderProps } from '@graphcommerce/ecommerce-ui'
1
+ import type { ActionCardItemRenderProps } from '@graphcommerce/ecommerce-ui'
2
2
  import { ActionCard } from '@graphcommerce/next-ui'
3
3
  import { Box } from '@mui/material'
4
4
  import { swatchSizes } from '../ConfigurableOptionValueImage'
5
- import { ConfigurableOptionValueColorFragment } from './ConfigurableOptionValueColor.gql'
5
+ import type { ConfigurableOptionValueColorFragment } from './ConfigurableOptionValueColor.gql'
6
6
 
7
7
  export type ConfigurableOptionValueColorProps =
8
8
  ActionCardItemRenderProps<ConfigurableOptionValueColorFragment>
@@ -1,9 +1,9 @@
1
- import { ActionCardItemRenderProps } from '@graphcommerce/ecommerce-ui'
1
+ import type { ActionCardItemRenderProps } from '@graphcommerce/ecommerce-ui'
2
2
  import { Image } from '@graphcommerce/image'
3
3
  import { ActionCard, responsiveVal } from '@graphcommerce/next-ui'
4
4
  import { Trans } from '@lingui/react'
5
5
  import { Button } from '@mui/material'
6
- import { ConfigurableOptionValueImageFragment } from './ConfigurableOptionValueImage.gql'
6
+ import type { ConfigurableOptionValueImageFragment } from './ConfigurableOptionValueImage.gql'
7
7
 
8
8
  export type ConfigurableOptionValueImageProps =
9
9
  ActionCardItemRenderProps<ConfigurableOptionValueImageFragment>
@@ -1,6 +1,6 @@
1
- import { ActionCardItemRenderProps } from '@graphcommerce/ecommerce-ui'
1
+ import type { ActionCardItemRenderProps } from '@graphcommerce/ecommerce-ui'
2
2
  import { ActionCard } from '@graphcommerce/next-ui'
3
- import { ConfigurableOptionValueTextFragment } from './ConfigurableOptionValueText.gql'
3
+ import type { ConfigurableOptionValueTextFragment } from './ConfigurableOptionValueText.gql'
4
4
 
5
5
  export type ConfigurableOptionValueTextProps =
6
6
  ActionCardItemRenderProps<ConfigurableOptionValueTextFragment>
@@ -1,36 +1,39 @@
1
- import { ActionCardItemBase, ActionCardListForm } from '@graphcommerce/ecommerce-ui'
2
- import {
3
- AddProductsToCartFields,
4
- useFormAddProductsToCart,
5
- } from '@graphcommerce/magento-product/components'
6
- import { filterNonNullableKeys, nonNullable, SectionHeader } from '@graphcommerce/next-ui'
1
+ import type { ActionCardItemBase } from '@graphcommerce/ecommerce-ui'
2
+ import { ActionCardListForm } from '@graphcommerce/ecommerce-ui'
3
+ import type { AddProductsToCartFields } from '@graphcommerce/magento-product/components'
4
+ import { useFormAddProductsToCart } from '@graphcommerce/magento-product/components'
5
+ import { SectionHeader, filterNonNullableKeys, nonNullable } from '@graphcommerce/next-ui'
7
6
  import { useWatch } from '@graphcommerce/react-hook-form'
8
7
  import { i18n } from '@lingui/core'
9
- import { Box, SxProps, Theme } from '@mui/material'
10
- import { ConfigurableOptionsFragment } from '../../graphql/ConfigurableOptions.gql'
11
- import { useConfigurableOptionsForSelection, UseConfigurableOptionsSelection } from '../../hooks'
12
- import {
8
+ import type { SxProps, Theme } from '@mui/material'
9
+ import { Box } from '@mui/material'
10
+ import type { ConfigurableOptionsFragment } from '../../graphql/ConfigurableOptions.gql'
11
+ import type { UseConfigurableOptionsSelection } from '../../hooks'
12
+ import { useConfigurableOptionsForSelection } from '../../hooks'
13
+ import type {
13
14
  ConfigurableOptionValue,
14
15
  ConfigurableOptionValueFragment,
15
16
  } from '../ConfigurableOptionValue'
16
17
 
17
- type Props = NonNullable<
18
+ export type ConfigurableProductOptionProps = NonNullable<
18
19
  NonNullable<ConfigurableOptionsFragment['configurable_options']>[number]
19
20
  > & {
20
21
  index: number
21
22
  optionIndex: number
23
+ optionStartLabels?: Record<string, React.ReactNode>
22
24
  optionEndLabels?: Record<string, React.ReactNode>
23
25
  sx?: SxProps<Theme>
24
26
  attribute_code: string
25
27
  render: typeof ConfigurableOptionValue
26
28
  } & UseConfigurableOptionsSelection
27
29
 
28
- export function ConfigurableProductOption(props: Props) {
30
+ export function ConfigurableProductOption(props: ConfigurableProductOptionProps) {
29
31
  const {
30
32
  values,
31
33
  label,
32
34
  index,
33
35
  optionIndex,
36
+ optionStartLabels,
34
37
  optionEndLabels,
35
38
  sx,
36
39
  attribute_code,
@@ -70,7 +73,7 @@ export function ConfigurableProductOption(props: Props) {
70
73
  return (
71
74
  <Box key={fieldName} sx={[...(Array.isArray(sx) ? sx : [sx])]}>
72
75
  <SectionHeader
73
- labelLeft={label}
76
+ labelLeft={optionStartLabels?.[attribute_code ?? ''] ?? label}
74
77
  labelRight={optionEndLabels?.[attribute_code ?? '']}
75
78
  sx={{ mt: 0 }}
76
79
  />
@@ -1,15 +1,19 @@
1
- import { ActionCardRequireOptionSelection } from '@graphcommerce/ecommerce-ui'
2
- import { AddToCartItemSelector, useFormAddProductsToCart } from '@graphcommerce/magento-product'
3
- import { filterNonNullableKeys, ActionCardListProps, useLocale } from '@graphcommerce/next-ui'
1
+ import type { ActionCardRequireOptionSelection } from '@graphcommerce/ecommerce-ui'
2
+ import type { AddToCartItemSelector } from '@graphcommerce/magento-product'
3
+ import { useFormAddProductsToCart } from '@graphcommerce/magento-product'
4
+ import type { ActionCardListProps } from '@graphcommerce/next-ui'
5
+ import { filterNonNullableKeys, useLocale } from '@graphcommerce/next-ui'
4
6
  import { i18n } from '@lingui/core'
5
- import { Box, SxProps, Theme } from '@mui/material'
7
+ import type { SxProps, Theme } from '@mui/material'
8
+ import { Box } from '@mui/material'
6
9
  import React, { useEffect, useMemo } from 'react'
7
- import { ConfigurableOptionsFragment } from '../../graphql/ConfigurableOptions.gql'
10
+ import type { ConfigurableOptionsFragment } from '../../graphql/ConfigurableOptions.gql'
8
11
  import { useConfigurableOptionsSelection } from '../../hooks'
9
12
  import { ConfigurableOptionValue } from '../ConfigurableOptionValue/ConfigurableOptionValue'
10
13
  import { ConfigurableProductOption } from './ConfigurableProductOption'
11
14
 
12
15
  export type ConfigurableProductOptionsProps = AddToCartItemSelector & {
16
+ optionStartLabels?: Record<string, React.ReactNode>
13
17
  optionEndLabels?: Record<string, React.ReactNode>
14
18
  sx?: SxProps<Theme>
15
19
  render?: typeof ConfigurableOptionValue
@@ -19,6 +23,7 @@ export type ConfigurableProductOptionsProps = AddToCartItemSelector & {
19
23
 
20
24
  export function ConfigurableProductOptions(props: ConfigurableProductOptionsProps) {
21
25
  const {
26
+ optionStartLabels,
22
27
  optionEndLabels,
23
28
  sx,
24
29
  render = ConfigurableOptionValue,
@@ -65,6 +70,7 @@ export function ConfigurableProductOptions(props: ConfigurableProductOptionsProp
65
70
  {...option}
66
71
  key={option.uid}
67
72
  render={render}
73
+ optionStartLabels={optionStartLabels}
68
74
  optionEndLabels={optionEndLabels}
69
75
  index={index}
70
76
  optionIndex={optionIndex}
@@ -1,10 +1,7 @@
1
- import {
2
- ProductListItem,
3
- OverlayAreaKeys,
4
- ProductListItemProps,
5
- } from '@graphcommerce/magento-product'
1
+ import type { OverlayAreaKeys, ProductListItemProps } from '@graphcommerce/magento-product'
2
+ import { ProductListItem } from '@graphcommerce/magento-product'
6
3
  import { SwatchList } from '../../SwatchList'
7
- import { ProductListItemConfigurableFragment } from './ProductListItemConfigurable.gql'
4
+ import type { ProductListItemConfigurableFragment } from './ProductListItemConfigurable.gql'
8
5
 
9
6
  export type ProdustListItemConfigurableProps = ProductListItemConfigurableFragment &
10
7
  ProductListItemProps & {
@@ -1,5 +1,6 @@
1
1
  import { useQuery } from '@graphcommerce/graphql'
2
- import { AddToCartItemSelector, useFormAddProductsToCart } from '@graphcommerce/magento-product'
2
+ import type { AddToCartItemSelector } from '@graphcommerce/magento-product'
3
+ import { useFormAddProductsToCart } from '@graphcommerce/magento-product'
3
4
  import { findByTypename, nonNullable } from '@graphcommerce/next-ui'
4
5
  import { useWatch } from '@graphcommerce/react-hook-form'
5
6
  import { GetConfigurableOptionsSelectionDocument } from '../graphql/GetConfigurableOptionsSelection.gql'
package/index.ts CHANGED
@@ -1,7 +1,5 @@
1
1
  export * from './components'
2
2
  export * from './ConfigurableCartItem/ConfigurableCartItem'
3
- export * from './ConfigurableContext/ConfigurableContext'
4
- export * from './ConfigurableProductAddToCart/ConfigurableProductAddToCart'
5
3
  export * from './ConfigurableProductPage.gql'
6
4
  export * from './graphql'
7
5
  export * from './hooks'
package/package.json CHANGED
@@ -2,7 +2,7 @@
2
2
  "name": "@graphcommerce/magento-product-configurable",
3
3
  "homepage": "https://www.graphcommerce.org/",
4
4
  "repository": "github:graphcommerce-org/graphcommerce",
5
- "version": "9.0.0-canary.99",
5
+ "version": "9.0.1-canary.0",
6
6
  "sideEffects": false,
7
7
  "prettier": "@graphcommerce/prettier-config-pwa",
8
8
  "eslintConfig": {
@@ -12,28 +12,28 @@
12
12
  }
13
13
  },
14
14
  "peerDependencies": {
15
- "@graphcommerce/ecommerce-ui": "^9.0.0-canary.99",
16
- "@graphcommerce/eslint-config-pwa": "^9.0.0-canary.99",
17
- "@graphcommerce/graphql": "^9.0.0-canary.99",
18
- "@graphcommerce/graphql-mesh": "^9.0.0-canary.99",
19
- "@graphcommerce/image": "^9.0.0-canary.99",
20
- "@graphcommerce/lingui-next": "9.0.0-canary.99",
21
- "@graphcommerce/magento-cart": "^9.0.0-canary.99",
22
- "@graphcommerce/magento-cart-items": "^9.0.0-canary.99",
23
- "@graphcommerce/magento-category": "^9.0.0-canary.99",
24
- "@graphcommerce/magento-customer": "^9.0.0-canary.99",
25
- "@graphcommerce/magento-product": "^9.0.0-canary.99",
26
- "@graphcommerce/magento-product-simple": "^9.0.0-canary.99",
27
- "@graphcommerce/magento-store": "^9.0.0-canary.99",
28
- "@graphcommerce/next-ui": "^9.0.0-canary.99",
29
- "@graphcommerce/prettier-config-pwa": "^9.0.0-canary.99",
30
- "@graphcommerce/react-hook-form": "^9.0.0-canary.99",
31
- "@graphcommerce/typescript-config-pwa": "^9.0.0-canary.99",
15
+ "@graphcommerce/ecommerce-ui": "^9.0.1-canary.0",
16
+ "@graphcommerce/eslint-config-pwa": "^9.0.1-canary.0",
17
+ "@graphcommerce/graphql": "^9.0.1-canary.0",
18
+ "@graphcommerce/graphql-mesh": "^9.0.1-canary.0",
19
+ "@graphcommerce/image": "^9.0.1-canary.0",
20
+ "@graphcommerce/lingui-next": "9.0.1-canary.0",
21
+ "@graphcommerce/magento-cart": "^9.0.1-canary.0",
22
+ "@graphcommerce/magento-cart-items": "^9.0.1-canary.0",
23
+ "@graphcommerce/magento-category": "^9.0.1-canary.0",
24
+ "@graphcommerce/magento-customer": "^9.0.1-canary.0",
25
+ "@graphcommerce/magento-product": "^9.0.1-canary.0",
26
+ "@graphcommerce/magento-product-simple": "^9.0.1-canary.0",
27
+ "@graphcommerce/magento-store": "^9.0.1-canary.0",
28
+ "@graphcommerce/next-ui": "^9.0.1-canary.0",
29
+ "@graphcommerce/prettier-config-pwa": "^9.0.1-canary.0",
30
+ "@graphcommerce/react-hook-form": "^9.0.1-canary.0",
31
+ "@graphcommerce/typescript-config-pwa": "^9.0.1-canary.0",
32
32
  "@lingui/core": "^4.2.1",
33
33
  "@lingui/macro": "^4.2.1",
34
34
  "@lingui/react": "^4.2.1",
35
35
  "@mui/material": "^5.10.16",
36
- "framer-motion": "^10.0.0",
36
+ "framer-motion": "^11.0.0",
37
37
  "next": "*",
38
38
  "react": "^18.2.0",
39
39
  "react-dom": "^18.2.0"
@@ -11,9 +11,9 @@ export const config: PluginConfig = {
11
11
  ifConfig: 'configurableVariantValues.content',
12
12
  }
13
13
 
14
- export const ProductPageDescription = (
14
+ export function ProductPageDescription(
15
15
  props: PluginProps<ProductPageDescriptionProps & AddToCartItemSelector>,
16
- ) => {
16
+ ) {
17
17
  const { Prev, product, index, ...rest } = props
18
18
  const variant = useConfigurableSelectedVariant({ url_key: product.url_key, index })
19
19
 
@@ -5,6 +5,7 @@ import { useConfigurableOptionsSelection } from '../../hooks'
5
5
  export const config: PluginConfig = {
6
6
  type: 'component',
7
7
  module: '@graphcommerce/magento-product',
8
+ ifConfig: 'configurableVariantValues.gallery',
8
9
  }
9
10
 
10
11
  export function ProductPageGallery(
@@ -1,9 +1,6 @@
1
1
  import { mergeDeep } from '@graphcommerce/graphql'
2
- import {
3
- productLink,
4
- type AddToCartItemSelector,
5
- ProductPageMetaProps,
6
- } from '@graphcommerce/magento-product'
2
+ import type { ProductPageMetaProps } from '@graphcommerce/magento-product'
3
+ import { type AddToCartItemSelector, productLink } from '@graphcommerce/magento-product'
7
4
  import type { PluginConfig, PluginProps } from '@graphcommerce/next-config'
8
5
  import { useRouter } from 'next/router'
9
6
  import { useEffect } from 'react'
@@ -1,4 +1,4 @@
1
- import { AddToCartItemSelector, ProductPagePriceProps } from '@graphcommerce/magento-product'
1
+ import type { AddToCartItemSelector, ProductPagePriceProps } from '@graphcommerce/magento-product'
2
2
  import type { PluginConfig, PluginProps } from '@graphcommerce/next-config'
3
3
  import { useConfigurableSelectedVariant } from '../../hooks'
4
4
 
@@ -2,7 +2,8 @@
2
2
  import { waitForGraphQlResponse } from '@graphcommerce/graphql/test/apolloClient.fixture'
3
3
  import { CreateEmptyCartDocument } from '@graphcommerce/magento-cart/hooks/CreateEmptyCart.gql'
4
4
  import { ProductAddToCartDocument } from '@graphcommerce/magento-product'
5
- import { Page, expect } from '@playwright/test'
5
+ import type { Page } from '@playwright/test'
6
+ import { expect } from '@playwright/test'
6
7
 
7
8
  export async function addConfigurableProductToCart(page: Page, productUrl: string) {
8
9
  await page.goto(productUrl)
@@ -1,8 +1,8 @@
1
- import { ApolloClient } from '@graphcommerce/graphql'
2
- import { AddProductsToCartFormProps } from '@graphcommerce/magento-product'
1
+ import type { ApolloClient } from '@graphcommerce/graphql'
2
+ import type { AddProductsToCartFormProps } from '@graphcommerce/magento-product'
3
3
  import { filterNonNullableKeys, findByTypename, nonNullable } from '@graphcommerce/next-ui'
4
4
  import { GetConfigurableOptionsSelectionDocument } from '../graphql'
5
- import { DefaultConfigurableOptionsSelectionFragment } from './DefaultConfigurableOptionsSelection.gql'
5
+ import type { DefaultConfigurableOptionsSelectionFragment } from './DefaultConfigurableOptionsSelection.gql'
6
6
 
7
7
  type BaseQuery =
8
8
  | { products?: DefaultConfigurableOptionsSelectionFragment | null | undefined }
@@ -1,165 +0,0 @@
1
- import {
2
- useContext,
3
- createContext,
4
- Context,
5
- useState,
6
- Dispatch,
7
- SetStateAction,
8
- useMemo,
9
- useCallback,
10
- } from 'react'
11
- import { ConfigurableProductFormFragment } from './ConfigurableProductForm.gql'
12
- import cheapestVariant from './cheapestVariant'
13
-
14
- type ConfigurableProductFormProps = ConfigurableProductFormFragment & {
15
- sku: string
16
- children?: React.ReactNode
17
- }
18
-
19
- export type Selected = { [attrCode: string]: number }
20
- export type Variants = NonNullable<ConfigurableProductFormProps['variants']>
21
- type GetVariants = (values?: Selected) => Variants
22
- type GetUids = (values?: Selected) => string[]
23
-
24
- type ConfigurableContext = {
25
- selection: Selected
26
- variants: Variants
27
- cheapest: Variants[0]
28
- select: Dispatch<SetStateAction<Selected>>
29
- options: ConfigurableProductFormFragment['configurable_options']
30
- getVariants: GetVariants
31
- getUids: GetUids
32
- }
33
- const contexts: { [sku: string]: Context<ConfigurableContext> } = {}
34
-
35
- function configurableContext(sku: string): Context<ConfigurableContext> {
36
- if (contexts?.[sku]) return contexts[sku]
37
- contexts[sku] = createContext<ConfigurableContext>({
38
- selection: {},
39
- variants: [],
40
- cheapest: {},
41
- select: () => {},
42
- options: undefined,
43
- getVariants: () => [],
44
- getUids: () => [],
45
- })
46
-
47
- return contexts[sku]
48
- }
49
-
50
- type AttributeTree = {
51
- code: string
52
- values: AttributeValues
53
- }
54
- type AttributeValues = {
55
- [index: string]: {
56
- variants: NonNullable<ConfigurableProductFormProps['variants']>
57
- attribute?: AttributeTree
58
- }
59
- }
60
-
61
- function generateAttrTree(
62
- idx: number,
63
- options: ConfigurableProductFormProps['configurable_options'],
64
- variants: ConfigurableProductFormProps['variants'],
65
- selected: Selected,
66
- tree?: AttributeTree,
67
- ) {
68
- const attribute = options?.[idx]
69
- if (!attribute || !attribute.attribute_code) return tree
70
-
71
- const attributeTree: AttributeTree = { code: attribute.attribute_code, values: {} }
72
-
73
- attribute.values?.forEach((val) => {
74
- if (!val?.uid) return
75
- const newSelected = { ...selected, [attributeTree.code]: [val.uid] } as Selected
76
-
77
- const filteredVariants = variants?.filter(
78
- (variant) =>
79
- !!variant?.attributes?.find(
80
- (attr) => attr?.code === attribute.attribute_code && val.uid === attr?.uid,
81
- ),
82
- )
83
-
84
- attributeTree.values[val.uid] = {
85
- variants: filteredVariants ?? [],
86
- attribute: generateAttrTree(idx + 1, options, filteredVariants, newSelected),
87
- }
88
- })
89
-
90
- return attributeTree
91
- }
92
-
93
- function traverseAttrTree(selection: Selected, attrTree: AttributeTree | undefined): Variants {
94
- if (!attrTree) return []
95
-
96
- const id = selection?.[attrTree.code]
97
- const attrVal = id ? attrTree.values[id] : undefined
98
-
99
- // We have a request, but isn't found in the current tree node
100
- if (id && !attrVal) return []
101
-
102
- if (attrVal?.attribute) return traverseAttrTree(selection, attrVal.attribute)
103
- if (attrVal?.variants) return attrVal.variants
104
-
105
- const attrValues = Object.entries(attrTree.values)
106
- const variantList: NonNullable<ConfigurableProductFormProps['variants']> = []
107
-
108
- attrValues.forEach(([optionId, attrVal2]) => {
109
- variantList.push(
110
- ...(attrVal2.attribute
111
- ? traverseAttrTree({ ...selection, [attrTree.code]: Number(optionId) }, attrVal2.attribute)
112
- : attrVal2.variants),
113
- )
114
- })
115
-
116
- return variantList
117
- }
118
-
119
- export function ConfigurableContextProvider(props: ConfigurableProductFormProps) {
120
- const { children, sku, configurable_options, variants: providedVariants } = props
121
- const [selection, select] = useState<Selected>({})
122
-
123
- if (!configurable_options || !providedVariants)
124
- throw Error('please provide configurabl_options and variants')
125
-
126
- const lookupTree = useMemo(
127
- () => generateAttrTree(0, configurable_options, providedVariants, {}),
128
- [configurable_options, providedVariants],
129
- )
130
-
131
- const getVariants: GetVariants = useCallback(
132
- (options: Selected = {}) => traverseAttrTree(options, lookupTree),
133
- [lookupTree],
134
- )
135
-
136
- const getUids: GetUids = useCallback(
137
- (options: Selected = {}) =>
138
- (getVariants(options as unknown as Selected) ?? [])
139
- .map((variant) => (variant?.attributes?.map((attr) => attr?.uid) ?? []) as string[])
140
- .flat(),
141
- [getVariants],
142
- )
143
-
144
- const context = configurableContext(sku)
145
- const variants = getVariants(selection)
146
-
147
- const value = useMemo(
148
- () => ({
149
- selection,
150
- variants,
151
- cheapest: cheapestVariant(variants),
152
- select,
153
- getVariants,
154
- getUids,
155
- options: configurable_options,
156
- }),
157
- [configurable_options, getUids, getVariants, selection, variants],
158
- )
159
-
160
- return <context.Provider value={value}>{children}</context.Provider>
161
- }
162
-
163
- export function useConfigurableContext(sku: string): ConfigurableContext {
164
- return useContext(configurableContext(sku))
165
- }
@@ -1,14 +0,0 @@
1
- import { ConfigurableProductFormFragment } from './ConfigurableProductForm.gql'
2
-
3
- type Variants = NonNullable<ConfigurableProductFormFragment['variants']>
4
-
5
- export default function cheapestVariant(variants: Variants): Variants[0] {
6
- if (!variants.length) return null
7
- const cheapest = variants?.reduce((prev, curr) =>
8
- (curr?.product?.price_range.minimum_price.final_price.value ?? 0) <
9
- (prev?.product?.price_range.minimum_price.final_price.value ?? 0)
10
- ? curr
11
- : prev,
12
- )
13
- return cheapest
14
- }