diff --git a/knip.ts b/knip.ts index eb6f3804a6..b00211d4be 100644 --- a/knip.ts +++ b/knip.ts @@ -18,7 +18,13 @@ const asPackageDir: WorkspaceEntry = { 'index.js', 'src/index.ts', ], - entry: ['plugins/**/*.{ts,tsx}', 'src/bin/*.ts', '**/resolvers.ts', '**/resolver.ts'], + entry: [ + 'plugins/**/*.{ts,tsx}', + 'src/bin/*.ts', + '**/resolvers.ts', + '**/resolver.ts', + '**/*Resolver.ts', + ], } const asNextjsDir: WorkspaceEntry = { diff --git a/packages/framer-next-pages/example/components/StackedDrawer.tsx b/packages/framer-next-pages/example/components/StackedDrawer.tsx deleted file mode 100644 index 1776976219..0000000000 --- a/packages/framer-next-pages/example/components/StackedDrawer.tsx +++ /dev/null @@ -1,46 +0,0 @@ -import { usePageContext } from '@graphcommerce/framer-next-pages' -import { m } from 'framer-motion' - -export function StackedDrawer(props: { variant: 'left' | 'right'; children: React.ReactNode }) { - const { children, variant } = props - const { depth } = usePageContext() - - const offset = variant === 'right' ? depth * 40 : depth * -40 - - return ( - - {children} - - ) -} diff --git a/packages/magento-customer/components/AccountLatestOrder/AccountLatestOrder.tsx b/packages/magento-customer/components/AccountLatestOrder/AccountLatestOrder.tsx index 7a55b418fb..f3d42744c2 100644 --- a/packages/magento-customer/components/AccountLatestOrder/AccountLatestOrder.tsx +++ b/packages/magento-customer/components/AccountLatestOrder/AccountLatestOrder.tsx @@ -9,6 +9,10 @@ export type AccountLatestOrderProps = AccountOrdersFragment & { loading: boolean } +/** + * @deprecated + * @public + */ export function AccountLatestOrder(props: AccountLatestOrderProps) { const { orders, loading } = props const latestOrderCard = orders?.items?.[(orders?.items?.length ?? 1) - 1] diff --git a/packages/magento-customer/components/AddressFields/AddressCountryRegion.tsx b/packages/magento-customer/components/AddressFields/AddressCountryRegion.tsx index c3a11be4bf..7bebe6dc53 100644 --- a/packages/magento-customer/components/AddressFields/AddressCountryRegion.tsx +++ b/packages/magento-customer/components/AddressFields/AddressCountryRegion.tsx @@ -2,12 +2,13 @@ import type { FieldPath, FieldValues } from '@graphcommerce/ecommerce-ui' import { SelectElement, TextFieldElement, useWatch } from '@graphcommerce/ecommerce-ui' import { useQuery } from '@graphcommerce/graphql' import { CountryRegionsDocument } from '@graphcommerce/magento-store' -import { FormRow, filterNonNullableKeys } from '@graphcommerce/next-ui' +import { filterNonNullableKeys, FormRow } from '@graphcommerce/next-ui' import { Trans } from '@lingui/react' import { useMemo } from 'react' import type { AddressFieldsOptions } from './useAddressFieldsForm' import { useAddressFieldsForm } from './useAddressFieldsForm' +/** @public */ export function useAddressCountryRegion< TFieldValues extends FieldValues = FieldValues, TName extends FieldPath = FieldPath, diff --git a/packages/magento-customer/components/OrderCardItem/OrderCardItem.tsx b/packages/magento-customer/components/OrderCardItem/OrderCardItem.tsx index 123b2df5be..5c48f1a51d 100644 --- a/packages/magento-customer/components/OrderCardItem/OrderCardItem.tsx +++ b/packages/magento-customer/components/OrderCardItem/OrderCardItem.tsx @@ -6,6 +6,10 @@ export type OrderCardItemProps = OrderCardItemFragment & { thumbnail?: Pick } +/** + * @deprecated + * @public + */ export function OrderCardItem(props: OrderCardItemProps) { const { product_sku, product_url_key, thumbnail } = props diff --git a/packages/magento-customer/components/SignInForm/SignInFormInline.tsx b/packages/magento-customer/components/SignInForm/SignInFormInline.tsx index 239284800f..4ff5f6740b 100644 --- a/packages/magento-customer/components/SignInForm/SignInFormInline.tsx +++ b/packages/magento-customer/components/SignInForm/SignInFormInline.tsx @@ -13,6 +13,7 @@ export type InlineSignInFormProps = Omit & const { classes } = extendableComponent('SignInFormInline', ['form', 'button'] as const) +/** @public */ export function SignInFormInline(props: InlineSignInFormProps) { const { email, children, sx = [] } = props const form = useSignInForm({ email }) diff --git a/packages/magento-payment-adyen/hooks/useAdyenHandlePaymentResponse.ts b/packages/magento-payment-adyen/hooks/useAdyenHandlePaymentResponse.ts index 92af32e0c6..ca59618913 100644 --- a/packages/magento-payment-adyen/hooks/useAdyenHandlePaymentResponse.ts +++ b/packages/magento-payment-adyen/hooks/useAdyenHandlePaymentResponse.ts @@ -31,6 +31,10 @@ export type AdyenPaymentResponse = { additionalData?: Types.checkout.PaymentResponse['additionalData'] } +/** + * @deprecated Will be removed + * @public + */ export function parsePaymentResponse( status?: AdyenPaymentResponseFragment | null, ): AdyenPaymentResponse { diff --git a/packages/magento-payment-braintree/methods/braintree/PaymentMethodOptions.tsx b/packages/magento-payment-braintree/methods/braintree/PaymentMethodOptions.tsx index 11253238e2..6a5d10f57c 100644 --- a/packages/magento-payment-braintree/methods/braintree/PaymentMethodOptions.tsx +++ b/packages/magento-payment-braintree/methods/braintree/PaymentMethodOptions.tsx @@ -28,6 +28,7 @@ const Field = React.forwardRef((props, return }) +/** @public */ export function BraintreeField( props: { hostedFields: HostedFields | undefined @@ -259,7 +260,10 @@ export function PaymentMethodOptions(props: PaymentOptionsProps) { const loading = !hostedFields - /** This is the form that the user can fill in. In this case we don't wat the user to fill in anything. */ + /** + * This is the form that the user can fill in. In this case we don't wat the user to fill in + * anything. + */ return (
diff --git a/packages/magento-payment-braintree/utils/isBraintreeError.ts b/packages/magento-payment-braintree/utils/isBraintreeError.ts index 6588665056..218b248396 100644 --- a/packages/magento-payment-braintree/utils/isBraintreeError.ts +++ b/packages/magento-payment-braintree/utils/isBraintreeError.ts @@ -2,10 +2,12 @@ import type { BraintreeError } from 'braintree-web' const errorTypes = ['CUSTOMER', 'MERCHANT', 'NETWORK', 'INTERNAL', 'UNKNOWN'] +/** @public */ export function isBraintreeError(e: unknown): e is BraintreeError { return errorTypes.includes((e as BraintreeError).type) && e instanceof Error } +/** @public */ export function isBraintreeCustomerError(e: unknown): e is BraintreeError { return isBraintreeError(e) && e.type === 'CUSTOMER' } diff --git a/packages/magento-product-bundle/components/BundleCartItem/BundleCartItem.tsx b/packages/magento-product-bundle/components/BundleCartItem/BundleCartItem.tsx index 6b0ddfa24f..7cf81b5a6e 100644 --- a/packages/magento-product-bundle/components/BundleCartItem/BundleCartItem.tsx +++ b/packages/magento-product-bundle/components/BundleCartItem/BundleCartItem.tsx @@ -3,6 +3,10 @@ import { Money } from '@graphcommerce/magento-store' import { Typography } from '@mui/material' import type { BundleProductCartItemOptionsProps } from '../BundleProductCartItemOptions/BundleProductCartItemOptions' +/** + * @deprecated + * @public + */ export function BundleCartItem(props: BundleProductCartItemOptionsProps) { const { bundle_options } = props return ( diff --git a/packages/magento-product-configurable/ConfigurableContext/ConfigurableContext.tsx b/packages/magento-product-configurable/ConfigurableContext/ConfigurableContext.tsx deleted file mode 100644 index e8127d8149..0000000000 --- a/packages/magento-product-configurable/ConfigurableContext/ConfigurableContext.tsx +++ /dev/null @@ -1,157 +0,0 @@ -import type { Context, Dispatch, SetStateAction } from 'react' -import { createContext, useCallback, useContext, useMemo, useState } from 'react' -import type { ConfigurableProductFormFragment } from './ConfigurableProductForm.gql' -import cheapestVariant from './cheapestVariant' - -export type ConfigurableProductFormProps = ConfigurableProductFormFragment & { - sku: string - children?: React.ReactNode -} - -export type Selected = { [attrCode: string]: number } -export type Variants = NonNullable -type GetVariants = (values?: Selected) => Variants -type GetUids = (values?: Selected) => string[] - -type ConfigurableContext = { - selection: Selected - variants: Variants - cheapest: Variants[0] - select: Dispatch> - options: ConfigurableProductFormFragment['configurable_options'] - getVariants: GetVariants - getUids: GetUids -} -const contexts: { [sku: string]: Context } = {} - -function configurableContext(sku: string): Context { - if (contexts?.[sku]) return contexts[sku] - contexts[sku] = createContext({ - selection: {}, - variants: [], - cheapest: {}, - select: () => {}, - options: undefined, - getVariants: () => [], - getUids: () => [], - }) - - return contexts[sku] -} - -type AttributeTree = { - code: string - values: AttributeValues -} -type AttributeValues = { - [index: string]: { - variants: NonNullable - attribute?: AttributeTree - } -} - -function generateAttrTree( - idx: number, - options: ConfigurableProductFormProps['configurable_options'], - variants: ConfigurableProductFormProps['variants'], - selected: Selected, - tree?: AttributeTree, -) { - const attribute = options?.[idx] - if (!attribute || !attribute.attribute_code) return tree - - const attributeTree: AttributeTree = { code: attribute.attribute_code, values: {} } - - attribute.values?.forEach((val) => { - if (!val?.uid) return - const newSelected = { ...selected, [attributeTree.code]: [val.uid] } as Selected - - const filteredVariants = variants?.filter( - (variant) => - !!variant?.attributes?.find( - (attr) => attr?.code === attribute.attribute_code && val.uid === attr?.uid, - ), - ) - - attributeTree.values[val.uid] = { - variants: filteredVariants ?? [], - attribute: generateAttrTree(idx + 1, options, filteredVariants, newSelected), - } - }) - - return attributeTree -} - -function traverseAttrTree(selection: Selected, attrTree: AttributeTree | undefined): Variants { - if (!attrTree) return [] - - const id = selection?.[attrTree.code] - const attrVal = id ? attrTree.values[id] : undefined - - // We have a request, but isn't found in the current tree node - if (id && !attrVal) return [] - - if (attrVal?.attribute) return traverseAttrTree(selection, attrVal.attribute) - if (attrVal?.variants) return attrVal.variants - - const attrValues = Object.entries(attrTree.values) - const variantList: NonNullable = [] - - attrValues.forEach(([optionId, attrVal2]) => { - variantList.push( - ...(attrVal2.attribute - ? traverseAttrTree({ ...selection, [attrTree.code]: Number(optionId) }, attrVal2.attribute) - : attrVal2.variants), - ) - }) - - return variantList -} - -export function ConfigurableContextProvider(props: ConfigurableProductFormProps) { - const { children, sku, configurable_options, variants: providedVariants } = props - const [selection, select] = useState({}) - - if (!configurable_options || !providedVariants) - throw Error('please provide configurabl_options and variants') - - const lookupTree = useMemo( - () => generateAttrTree(0, configurable_options, providedVariants, {}), - [configurable_options, providedVariants], - ) - - const getVariants: GetVariants = useCallback( - (options: Selected = {}) => traverseAttrTree(options, lookupTree), - [lookupTree], - ) - - const getUids: GetUids = useCallback( - (options: Selected = {}) => - (getVariants(options as unknown as Selected) ?? []) - .map((variant) => (variant?.attributes?.map((attr) => attr?.uid) ?? []) as string[]) - .flat(), - [getVariants], - ) - - const context = configurableContext(sku) - const variants = getVariants(selection) - - const value = useMemo( - () => ({ - selection, - variants, - cheapest: cheapestVariant(variants), - select, - getVariants, - getUids, - options: configurable_options, - }), - [configurable_options, getUids, getVariants, selection, variants], - ) - - return {children} -} - -export function useConfigurableContext(sku: string): ConfigurableContext { - return useContext(configurableContext(sku)) -} diff --git a/packages/magento-product-configurable/ConfigurableContext/cheapestVariant.ts b/packages/magento-product-configurable/ConfigurableContext/cheapestVariant.ts deleted file mode 100644 index 0eca97e48d..0000000000 --- a/packages/magento-product-configurable/ConfigurableContext/cheapestVariant.ts +++ /dev/null @@ -1,14 +0,0 @@ -import type { ConfigurableProductFormFragment } from './ConfigurableProductForm.gql' - -type Variants = NonNullable - -export default function cheapestVariant(variants: Variants): Variants[0] { - if (!variants.length) return null - const cheapest = variants?.reduce((prev, curr) => - (curr?.product?.price_range.minimum_price.final_price.value ?? 0) < - (prev?.product?.price_range.minimum_price.final_price.value ?? 0) - ? curr - : prev, - ) - return cheapest -} diff --git a/packages/magento-product-configurable/ConfigurableOptions/ConfigurableOptions.tsx b/packages/magento-product-configurable/ConfigurableOptions/ConfigurableOptions.tsx deleted file mode 100644 index 9f49b82c22..0000000000 --- a/packages/magento-product-configurable/ConfigurableOptions/ConfigurableOptions.tsx +++ /dev/null @@ -1,146 +0,0 @@ -import type { FieldErrors, UseControllerProps } from '@graphcommerce/ecommerce-ui' -import { Controller } from '@graphcommerce/ecommerce-ui' -import { - RenderType, - SectionHeader, - ToggleButton, - ToggleButtonGroup, - extendableComponent, -} from '@graphcommerce/next-ui' -import type { BaseTextFieldProps, SxProps } from '@mui/material' -import { FormHelperText } from '@mui/material' -import React from 'react' -import type { Selected } from '../ConfigurableContext/ConfigurableContext' -import { useConfigurableContext } from '../ConfigurableContext/ConfigurableContext' -import { ColorSwatchData } from '../Swatches/ColorSwatchData' -import { ImageSwatchData } from '../Swatches/ImageSwatchData' -import { TextSwatchData } from '../Swatches/TextSwatchData' -import type { SwatchSize, SwatchTypeRenderer } from '../Swatches/types' - -export type ConfigurableOptionsInputProps = { - sku: string - errors?: FieldErrors - size?: SwatchSize - sx?: SxProps - // eslint-disable-next-line @typescript-eslint/no-explicit-any -} & UseControllerProps & - Pick & { - optionEndLabels?: Record - } - -const renderer: SwatchTypeRenderer = { TextSwatchData, ImageSwatchData, ColorSwatchData } - -const compName = 'ConfigurableOptionsInput' -const parts = ['buttonGroup', 'button', 'helperText'] as const -const { classes } = extendableComponent(compName, parts) - -export function ConfigurableOptionsInput(props: ConfigurableOptionsInputProps) { - const { - sku, - FormHelperTextProps, - name, - defaultValue, - errors, - helperText, - optionEndLabels, - size = 'large', - sx, - ...controlProps - } = props - - const { options, selection, select, getVariants } = useConfigurableContext(sku) - - return ( - <> - {options?.map((option) => { - if (!option?.uid || !option.attribute_code) return null - - const { attribute_code } = option - const error = errors?.[attribute_code] - - return ( - ( - <> - - { - onChange(val) - select((prev) => ({ ...prev, [attribute_code]: val }) as Selected) - }} - ref={ref} - onBlur={onBlur} - value={value} - className={classes.buttonGroup} - size={size} - sx={sx} - > - {option?.values?.map((val) => { - if (!val?.uid || !option.attribute_code) return null - - // Fall back to text swatch if no swatch is given - const swatch_data = val.swatch_data ?? { - __typename: 'TextSwatchData', - value: val.store_label, - } - - const copySelection = { ...selection } - delete copySelection[attribute_code] - - const itemVariant = getVariants(copySelection).find((variant) => - variant?.attributes?.find((attribute) => attribute?.uid === val.uid), - ) - - return ( - - - - ) - })} - - {error && ( - - {`${option.label} is ${errorHelperText?.type}`} - - )} - - )} - /> - ) - })} - - ) -} diff --git a/packages/magento-product-configurable/ConfigurableProductAddToCart/ConfigurableProductAddToCart.tsx b/packages/magento-product-configurable/ConfigurableProductAddToCart/ConfigurableProductAddToCart.tsx deleted file mode 100644 index 2319a05d0c..0000000000 --- a/packages/magento-product-configurable/ConfigurableProductAddToCart/ConfigurableProductAddToCart.tsx +++ /dev/null @@ -1,182 +0,0 @@ -import { NumberFieldElement } from '@graphcommerce/ecommerce-ui' -import { ApolloCartErrorAlert, useFormGqlMutationCart } from '@graphcommerce/magento-cart' -import { Money } from '@graphcommerce/magento-store' -import { - Button, - IconSvg, - MessageSnackbar, - extendableComponent, - iconChevronRight, -} from '@graphcommerce/next-ui' -import { Trans } from '@lingui/macro' -import type { SxProps, Theme } from '@mui/material' -import { Alert, Box, Divider, Typography } from '@mui/material' -import React from 'react' -import { useConfigurableContext } from '../ConfigurableContext/ConfigurableContext' -import cheapestVariant from '../ConfigurableContext/cheapestVariant' -import type { ConfigurableOptionsInputProps } from '../ConfigurableOptions/ConfigurableOptions' -import { ConfigurableOptionsInput } from '../ConfigurableOptions/ConfigurableOptions' -import type { ConfigurableProductAddToCartMutationVariables } from '../graphql/ConfigurableProductAddToCart.gql' -import { ConfigurableProductAddToCartDocument } from '../graphql/ConfigurableProductAddToCart.gql' - -export type ConfigurableProductAddToCartProps = { - variables: Omit - name: string - optionEndLabels?: Record - children?: React.ReactNode - additionalButtons?: React.ReactNode - sx?: SxProps - optionsProps?: Omit< - ConfigurableOptionsInputProps, - 'name' | 'sku' | 'control' | 'rules' | 'errors' | 'optionEndLabels' - > -} - -const compName = 'ConfigurableOptionsInput' -const parts = ['form', 'button', 'finalPrice', 'quantity', 'divider', 'buttonWrapper'] as const -const { classes } = extendableComponent(compName, parts) - -/** - * @deprecated - */ -export function ConfigurableProductAddToCart(props: ConfigurableProductAddToCartProps) { - const { - name, - children, - variables, - optionEndLabels, - optionsProps, - additionalButtons, - sx = [], - ...buttonProps - } = props - - const { getVariants, selection } = useConfigurableContext(variables.sku) - - const form = useFormGqlMutationCart(ConfigurableProductAddToCartDocument, { - defaultValues: { ...variables }, - onBeforeSubmit: ({ selectedOptions, ...vars }) => ({ - ...vars, - selectedOptions: Object.values(selectedOptions), - }), - }) - - const { handleSubmit, formState, required, control, error, data } = form - const submitHandler = handleSubmit(() => {}) - - return ( - - ({ margin: `${theme.spacings.sm} 0` })} /> - - - ({ marginTop: theme.spacings.sm })} - /> - ({ margin: `${theme.spacings.sm} 0` })} /> - ({ marginTop: theme.spacings.sm })} - > - - - {children} - ({ - display: 'flex', - alignItems: 'center', - columnGap: theme.spacings.xs, - })} - className={classes.buttonWrapper} - > - - {additionalButtons} - - - - - {data?.addProductsToCart?.user_errors.map((e) => ( - - {e?.message} - - ))} - - } - > - View shopping cart - - } - > - - {name} has been added to your shopping cart! - - - - ) -} diff --git a/packages/magento-product-configurable/index.ts b/packages/magento-product-configurable/index.ts index 53675bc698..6754496293 100644 --- a/packages/magento-product-configurable/index.ts +++ b/packages/magento-product-configurable/index.ts @@ -1,7 +1,5 @@ export * from './components' export * from './ConfigurableCartItem/ConfigurableCartItem' -export * from './ConfigurableContext/ConfigurableContext' -export * from './ConfigurableProductAddToCart/ConfigurableProductAddToCart' export * from './ConfigurableProductPage.gql' export * from './graphql' export * from './hooks' diff --git a/packages/magento-search/components/CategorySearchResult/CategorySearchResults.tsx b/packages/magento-search/components/CategorySearchResult/CategorySearchResults.tsx index 5e34e672dc..fe0d7ada9a 100644 --- a/packages/magento-search/components/CategorySearchResult/CategorySearchResults.tsx +++ b/packages/magento-search/components/CategorySearchResult/CategorySearchResults.tsx @@ -6,6 +6,7 @@ export type CategorySearchResultsProps = { sx?: SxProps } +/** @public */ export function CategorySearchResults(props: CategorySearchResultsProps) { const { children, sx = [] } = props return {children}