@anker-in/headless-ui 1.3.18 → 1.3.19

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 (79) hide show
  1. package/dist/cjs/biz-components/ActiveShelf/ProductCard.d.ts +1 -1
  2. package/dist/cjs/biz-components/ActiveShelf/ProductCard.js +1 -1
  3. package/dist/cjs/biz-components/ActiveShelf/ProductCard.js.map +2 -2
  4. package/dist/cjs/biz-components/BuyOneGetOneShelf/PriceAndActions.d.ts +3 -14
  5. package/dist/cjs/biz-components/BuyOneGetOneShelf/PriceAndActions.js +1 -1
  6. package/dist/cjs/biz-components/BuyOneGetOneShelf/PriceAndActions.js.map +3 -3
  7. package/dist/cjs/biz-components/BuyOneGetOneShelf/ProductCard.js +1 -1
  8. package/dist/cjs/biz-components/BuyOneGetOneShelf/ProductCard.js.map +2 -2
  9. package/dist/cjs/biz-components/BuyOneGetOneShelf/types.d.ts +3 -1
  10. package/dist/cjs/biz-components/BuyOneGetOneShelf/types.js +1 -1
  11. package/dist/cjs/biz-components/BuyOneGetOneShelf/types.js.map +1 -1
  12. package/dist/cjs/biz-components/CreditsShelf/ProductCard.js +1 -1
  13. package/dist/cjs/biz-components/CreditsShelf/ProductCard.js.map +2 -2
  14. package/dist/cjs/biz-components/CreditsShelf/types.d.ts +1 -1
  15. package/dist/cjs/biz-components/CreditsShelf/types.js.map +1 -1
  16. package/dist/cjs/biz-components/ImageOverlayShelf/ProductCard.js +1 -1
  17. package/dist/cjs/biz-components/ImageOverlayShelf/ProductCard.js.map +2 -2
  18. package/dist/cjs/biz-components/ImageOverlayShelf/types.d.ts +3 -1
  19. package/dist/cjs/biz-components/ImageOverlayShelf/types.js +1 -1
  20. package/dist/cjs/biz-components/ImageOverlayShelf/types.js.map +1 -1
  21. package/dist/cjs/biz-components/MediaShelf/ProductCard.js +1 -1
  22. package/dist/cjs/biz-components/MediaShelf/ProductCard.js.map +2 -2
  23. package/dist/cjs/biz-components/MediaShelf/types.d.ts +1 -1
  24. package/dist/cjs/biz-components/MediaShelf/types.js +1 -1
  25. package/dist/cjs/biz-components/MediaShelf/types.js.map +1 -1
  26. package/dist/cjs/biz-components/SceneShelf/ProductCard.js +1 -1
  27. package/dist/cjs/biz-components/SceneShelf/ProductCard.js.map +2 -2
  28. package/dist/cjs/biz-components/SceneShelf/types.d.ts +3 -1
  29. package/dist/cjs/biz-components/SceneShelf/types.js.map +1 -1
  30. package/dist/cjs/biz-components/SceneShelfV2/index.d.ts +3 -1
  31. package/dist/cjs/biz-components/SceneShelfV2/index.js +1 -1
  32. package/dist/cjs/biz-components/SceneShelfV2/index.js.map +2 -2
  33. package/dist/cjs/biz-components/SceneShelfV3/ProductCard.d.ts +1 -1
  34. package/dist/cjs/biz-components/SceneShelfV3/ProductCard.js +1 -1
  35. package/dist/cjs/biz-components/SceneShelfV3/ProductCard.js.map +2 -2
  36. package/dist/cjs/biz-components/ShelfDisplay/index.js +1 -1
  37. package/dist/cjs/biz-components/ShelfDisplay/index.js.map +3 -3
  38. package/dist/cjs/biz-components/ShelfDisplay/shelfDisplay.d.ts +34 -0
  39. package/dist/cjs/biz-components/ShelfDisplay/shelfDisplay.js +1 -1
  40. package/dist/cjs/biz-components/ShelfDisplay/shelfDisplay.js.map +1 -1
  41. package/dist/cjs/biz-components/ShelfDisplay/shelfDisplayItem.js +1 -1
  42. package/dist/cjs/biz-components/ShelfDisplay/shelfDisplayItem.js.map +3 -3
  43. package/dist/esm/biz-components/ActiveShelf/ProductCard.d.ts +1 -1
  44. package/dist/esm/biz-components/ActiveShelf/ProductCard.js +1 -1
  45. package/dist/esm/biz-components/ActiveShelf/ProductCard.js.map +2 -2
  46. package/dist/esm/biz-components/BuyOneGetOneShelf/PriceAndActions.d.ts +3 -14
  47. package/dist/esm/biz-components/BuyOneGetOneShelf/PriceAndActions.js +1 -1
  48. package/dist/esm/biz-components/BuyOneGetOneShelf/PriceAndActions.js.map +3 -3
  49. package/dist/esm/biz-components/BuyOneGetOneShelf/ProductCard.js +1 -1
  50. package/dist/esm/biz-components/BuyOneGetOneShelf/ProductCard.js.map +2 -2
  51. package/dist/esm/biz-components/BuyOneGetOneShelf/types.d.ts +3 -1
  52. package/dist/esm/biz-components/BuyOneGetOneShelf/types.js.map +1 -1
  53. package/dist/esm/biz-components/CreditsShelf/ProductCard.js +1 -1
  54. package/dist/esm/biz-components/CreditsShelf/ProductCard.js.map +2 -2
  55. package/dist/esm/biz-components/CreditsShelf/types.d.ts +1 -1
  56. package/dist/esm/biz-components/ImageOverlayShelf/ProductCard.js +1 -1
  57. package/dist/esm/biz-components/ImageOverlayShelf/ProductCard.js.map +2 -2
  58. package/dist/esm/biz-components/ImageOverlayShelf/types.d.ts +3 -1
  59. package/dist/esm/biz-components/MediaShelf/ProductCard.js +1 -1
  60. package/dist/esm/biz-components/MediaShelf/ProductCard.js.map +2 -2
  61. package/dist/esm/biz-components/MediaShelf/types.d.ts +1 -1
  62. package/dist/esm/biz-components/MediaShelf/types.js.map +1 -1
  63. package/dist/esm/biz-components/SceneShelf/ProductCard.js +1 -1
  64. package/dist/esm/biz-components/SceneShelf/ProductCard.js.map +2 -2
  65. package/dist/esm/biz-components/SceneShelf/types.d.ts +3 -1
  66. package/dist/esm/biz-components/SceneShelfV2/index.d.ts +3 -1
  67. package/dist/esm/biz-components/SceneShelfV2/index.js +1 -1
  68. package/dist/esm/biz-components/SceneShelfV2/index.js.map +2 -2
  69. package/dist/esm/biz-components/SceneShelfV3/ProductCard.d.ts +1 -1
  70. package/dist/esm/biz-components/SceneShelfV3/ProductCard.js +1 -1
  71. package/dist/esm/biz-components/SceneShelfV3/ProductCard.js.map +2 -2
  72. package/dist/esm/biz-components/ShelfDisplay/index.js +1 -1
  73. package/dist/esm/biz-components/ShelfDisplay/index.js.map +3 -3
  74. package/dist/esm/biz-components/ShelfDisplay/shelfDisplay.d.ts +34 -0
  75. package/dist/esm/biz-components/ShelfDisplay/shelfDisplay.js +1 -1
  76. package/dist/esm/biz-components/ShelfDisplay/shelfDisplay.js.map +1 -1
  77. package/dist/esm/biz-components/ShelfDisplay/shelfDisplayItem.js +1 -1
  78. package/dist/esm/biz-components/ShelfDisplay/shelfDisplayItem.js.map +3 -3
  79. package/package.json +1 -1
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../../../src/biz-components/MediaShelf/ProductCard.tsx"],
4
- "sourcesContent": ["'use client'\n\nimport * as React from 'react'\nimport { cn } from '../../helpers/index.js'\nimport { Button, Badge, Card, CardContent, Picture, Text, Heading, Progress } from '../../components/index.js'\n\nimport type {\n ButtonFunctionType,\n CopyConfig,\n ProductCardData,\n StockDisplayMode,\n MediaShelfSemanticName,\n} from './types.js'\n\n/**\n * \u8D85\u5356\u65F6\u5E93\u5B58\u6761\u663E\u793A\u7684\u6700\u5C0F\u767E\u5206\u6BD4\n * \u9632\u6B62\u8D85\u5356\u65F6\u5E93\u5B58\u6761\u663E\u793A\u4E3A\u6EE1\u683C\uFF08100%\uFF09\u6216\u5B8C\u5168\u7A7A\uFF080%\uFF09\n */\nconst OVERSELLING_STOCK_PERCENTAGE = 5\n\n/**\n * \u5224\u65AD\u662F\u5426\u5E94\u8BE5\u663E\u793A\u5E93\u5B58\u4FE1\u606F\n * @param stockDisplayMode \u5E93\u5B58\u5C55\u793A\u6A21\u5F0F\n * @param stockThresholdValue \u5E93\u5B58\u9608\u503C\uFF08\u5F53\u6A21\u5F0F\u4E3A below-quantity \u6216 below-percentage \u65F6\u4F7F\u7528\uFF09\n * @param quantityAvailable \u53EF\u7528\u5E93\u5B58\u6570\u91CF\n * @param totalInventory \u603B\u5E93\u5B58\n * @returns \u662F\u5426\u663E\u793A\u5E93\u5B58\u4FE1\u606F\n */\nfunction shouldShowStock(\n stockDisplayMode: StockDisplayMode | undefined,\n stockThresholdValue: number | undefined,\n quantityAvailable: number,\n totalInventory: number\n): boolean {\n // \u672A\u914D\u7F6E\u65F6\u9ED8\u8BA4\u663E\u793A\n if (stockDisplayMode === undefined) {\n return true\n }\n\n // \u6839\u636E\u5C55\u793A\u6A21\u5F0F\u5224\u65AD\n switch (stockDisplayMode) {\n case 'always':\n // \u603B\u662F\u663E\u793A\n return true\n\n case 'never':\n // \u6C38\u4E0D\u663E\u793A\n return false\n\n case 'below-quantity':\n // \u5F53\u5E93\u5B58\u6570\u91CF\u4F4E\u4E8E\u9608\u503C\u65F6\u663E\u793A\n if (stockThresholdValue === undefined) {\n return true // \u6CA1\u6709\u8BBE\u7F6E\u9608\u503C\u65F6\u9ED8\u8BA4\u663E\u793A\n }\n\n return quantityAvailable <= stockThresholdValue\n\n case 'below-percentage':\n // \u5F53\u5E93\u5B58\u767E\u5206\u6BD4\u4F4E\u4E8E\u9608\u503C\u65F6\u663E\u793A\n if (stockThresholdValue === undefined) {\n return true // \u6CA1\u6709\u8BBE\u7F6E\u9608\u503C\u65F6\u9ED8\u8BA4\u663E\u793A\n }\n return (quantityAvailable / totalInventory) * 100 <= stockThresholdValue\n\n default:\n // \u672A\u77E5\u6A21\u5F0F\u65F6\u9ED8\u8BA4\u663E\u793A\n return true\n }\n}\n\n/**\n * MediaShelf ProductCard \u7EC4\u4EF6 Props \u63A5\u53E3\n */\nexport interface MediaShelfProductCardProps {\n /** \u4EA7\u54C1\u6570\u636E */\n product: ProductCardData\n /** \u6837\u5F0F\u7C7B\u540D */\n className?: string\n /** \u5E93\u5B58\u5C55\u793A\u6A21\u5F0F */\n stockDisplayMode?: StockDisplayMode\n /** \u5E93\u5B58\u9608\u503C\uFF08\u5F53\u6A21\u5F0F\u4E3A below-quantity \u6216 below-percentage \u65F6\u4F7F\u7528\uFF09 */\n stockThresholdValue?: number\n /** \u70B9\u51FB\u4E86\u89E3\u66F4\u591A\u56DE\u8C03 */\n onLearnMore?: (product: ProductCardData) => void\n /** \u70B9\u51FB\u7ACB\u5373\u8D2D\u4E70\u56DE\u8C03 */\n onShopNow?: (product: ProductCardData) => void\n /** \u70B9\u51FB\u52A0\u5165\u8D2D\u7269\u8F66\u56DE\u8C03 */\n onAddToCart?: (product: ProductCardData) => void\n /** \u8BED\u4E49\u5316\u7C7B\u540D */\n classNames?: Partial<Record<MediaShelfSemanticName, string>>\n /** \u4E86\u89E3\u66F4\u591A\u6309\u94AE\u6587\u672C */\n secondaryButtonText?: string\n /** \u4E86\u89E3\u66F4\u591A\u6309\u94AE\u529F\u80FD */\n secondaryButtonFun?: ButtonFunctionType\n /** \u7ACB\u5373\u8D2D\u4E70\u6309\u94AE\u6587\u672C */\n primaryButtonText?: string\n /** \u7ACB\u5373\u8D2D\u4E70\u6309\u94AE\u529F\u80FD */\n primaryButtonFun?: ButtonFunctionType\n /** \u662F\u5426\u5C55\u793A\u539F\u4EF7\uFF08\u5220\u9664\u7EBF\u4EF7\u683C\uFF09 */\n showOriginalPrice?: boolean\n /** \u6587\u6848\u914D\u7F6E */\n copy?: CopyConfig\n /** \u70B9\u51FB\u4EA7\u54C1\u56FE\u7247\u56DE\u8C03 */\n onProductImageClick?: (product: ProductCardData) => void\n /** \u662F\u5426\u5C55\u793A\u6807\u7B7E */\n showTags?: boolean\n}\n\n/**\n * MediaShelf \u4EA7\u54C1\u5361\u7247\u7EC4\u4EF6\n */\nconst ProductCard = React.forwardRef<HTMLDivElement, MediaShelfProductCardProps>(\n (\n {\n product,\n className,\n stockDisplayMode,\n stockThresholdValue,\n onLearnMore,\n onShopNow,\n onAddToCart,\n classNames,\n secondaryButtonText,\n secondaryButtonFun,\n primaryButtonText,\n primaryButtonFun,\n showOriginalPrice,\n copy,\n onProductImageClick,\n showTags = true,\n },\n ref\n ) => {\n const [primaryLoading, setPrimaryLoading] = React.useState(false)\n const [secondaryLoading, setSecondaryLoading] = React.useState(false)\n\n const stockPercentage = React.useMemo(() => {\n if (product?.availableForSale && product?.quantityAvailable <= 0) {\n return OVERSELLING_STOCK_PERCENTAGE\n }\n // \u4E0D\u53EF\u552E\u65F6\u663E\u793A0%\n if (!product?.availableForSale) {\n return 0\n }\n return ((product?.quantityAvailable ?? 0) / (product?.totalInventory ?? 1)) * 100\n }, [product?.availableForSale, product?.quantityAvailable, product?.totalInventory])\n\n // \u6839\u636E\u6309\u94AE\u529F\u80FD\u7C7B\u578B\u8C03\u7528\u76F8\u5E94\u7684\u56DE\u8C03\u51FD\u6570\n const handleButtonClick = async (buttonFun?: ButtonFunctionType, buttonType?: 'primary' | 'secondary') => {\n if (!buttonFun) return\n\n const setLoading = buttonType === 'primary' ? setPrimaryLoading : setSecondaryLoading\n setLoading(true)\n\n try {\n switch (buttonFun) {\n case 'buyNow':\n await onShopNow?.(product)\n break\n case 'addCart':\n await onAddToCart?.(product)\n break\n case 'learnMore':\n await onLearnMore?.(product)\n break\n default:\n break\n }\n } finally {\n setLoading(false)\n }\n }\n\n const overselling = product.availableForSale && product.quantityAvailable <= 0\n\n return (\n <Card\n ref={ref}\n className={cn(\n 'tablet:min-w-[auto] hover:bg-container-secondary-0 flex h-full min-w-[296px] flex-col overflow-hidden border-none',\n product.custom_link ? 'cursor-pointer' : '',\n className,\n classNames?.productCard\n )}\n >\n {/* \u56FE\u7247\u533A\u57DF */}\n <div\n className={cn(\n 'media-shelf-product-card-image-wrapper desktop:h-[240px] relative h-[200px] shrink-0 overflow-hidden',\n classNames?.productCardImageWrapper\n )}\n >\n {/* \u80CC\u666F\u56FE\u7247 */}\n <div className={cn('media-shelf-product-card-image-bg absolute inset-0 ', classNames?.productCardImageBg)}>\n <a\n onClick={() => onProductImageClick?.(product)}\n {...(!onProductImageClick && {\n href: product.custom_link || product.listingLink,\n })}\n className=\"cursor-pointer\"\n >\n <Picture\n source={product.custom_image || product.image}\n alt={product.name}\n className={cn('h-full', classNames?.productCardImage)}\n imgClassName=\"h-full object-contain\"\n />\n </a>\n </div>\n\n {/* \u6807\u7B7E\u533A\u57DF */}\n {showTags && product.tags && product.tags.length > 0 && (\n <div className=\"lg-desktop:h-[28px] absolute left-4 top-4 flex h-[24px]\">\n {product.tags.map((tag: any, index) =>\n (tag as any).label ? (\n <Badge\n key={index}\n size=\"sm\"\n variant={(tag.variant as any) || 'outline'}\n className={cn('mr-1')}\n promotionalType={tag.promotionalType}\n >\n {tag.label}\n </Badge>\n ) : (\n <React.Fragment key={index}>{tag}</React.Fragment>\n )\n )}\n </div>\n )}\n </div>\n\n {/* \u5185\u5BB9\u533A\u57DF */}\n <CardContent className=\"desktop:p-6 bg-container-primary laptop:gap-6 flex h-[calc(100%-240px)] grow flex-col justify-between gap-4 p-4\">\n {/* \u4EA7\u54C1\u6807\u9898\u548C\u526F\u6807\u9898 */}\n <div className=\"flex-0\">\n <Heading\n as=\"h3\"\n size={2}\n className={cn(\n 'text-info-primary mb-1 line-clamp-2 tracking-tight',\n onProductImageClick ? 'cursor-pointer' : '',\n classNames?.productTitle\n )}\n onClick={onProductImageClick ? () => onProductImageClick(product) : undefined}\n >\n {product.custom_name || product.name}\n </Heading>\n {(product.custom_description || product?.description) && (\n <Text\n size={2}\n className={cn('text-info-primary line-clamp-1', classNames?.productDescription)}\n html={product.custom_description || product.description}\n />\n )}\n </div>\n\n {/* \u5E93\u5B58\u4FE1\u606F */}\n {shouldShowStock(\n stockDisplayMode,\n stockThresholdValue,\n product?.quantityAvailable ?? 0,\n product?.totalInventory ?? 0\n ) && (\n <div\n data-total={product?.totalInventory ?? 0}\n data-available={product?.quantityAvailable ?? 0}\n className=\"space-y-2\"\n >\n <Progress\n value={stockPercentage}\n max={100}\n min={0}\n size=\"base\"\n variant=\"default\"\n aria-label=\"stock progress\"\n classNames={{\n progressBar: 'transition-all duration-300 ease-in-out',\n }}\n />\n <Text size={3} className=\"text-info-tertiary desktop:text-[16px] lg-desktop:text-[18px] text-[12px]\">\n {overselling\n ? copy?.limitedStock\n : copy?.stockDisplayText?.replace(\n '{count}',\n `${product.availableForSale ? product.quantityAvailable : 0}`\n )}\n </Text>\n </div>\n )}\n\n <div>\n {/** \u4EF7\u683C\u6807\u7B7E */}\n {product?.priceLabel && product?.availableForSale && (\n <Text\n size={4}\n className={cn(\n 'text-marketing-1 desktop:text-[16px] lg-desktop:text-[18px] mt-2 text-[12px]',\n classNames?.productPriceLabel\n )}\n >\n {product.priceLabel}\n </Text>\n )}\n {/* \u4EF7\u683C\u533A\u57DF */}\n <div className={cn('mb-2', classNames?.productPrice)}>\n <div className=\"flex items-baseline gap-2\">\n {product.availableForSale ? (\n <>\n <Heading size={2} className=\"text-info-primary\" as=\"h6\">\n {product.price}\n </Heading>\n {showOriginalPrice && product.originalPrice && (\n <Heading size={2} className=\"text-info-tertiary line-through\" as=\"h6\">\n {product.originalPrice}\n </Heading>\n )}\n </>\n ) : (\n <Heading size={2} className=\"text-info-tertiary\">\n {copy?.outOfStockLabel ?? 'Sold Out'}\n </Heading>\n )}\n </div>\n </div>\n\n {/* \u6309\u94AE\u533A\u57DF */}\n <div className={cn('lg-desktop:gap-3 tablet:flex-nowrap flex flex-wrap gap-2', classNames?.buttonGroup)}>\n {secondaryButtonText && (\n <Button\n variant=\"secondary\"\n size=\"base\"\n className={cn('tablet:w-fit w-full', classNames?.secondaryButton)}\n onClick={() => handleButtonClick(secondaryButtonFun, 'secondary')}\n disabled={!product.availableForSale && secondaryButtonFun !== 'learnMore'}\n loading={secondaryLoading}\n data-headless-type-name=\"MediaShelf#ProductCard\"\n data-headless-title-desc-button={`${product.custom_name || product.name}#${product.description || ''}#${secondaryButtonText}`}\n data-headless-sku={product.sku}\n >\n {secondaryButtonText}\n </Button>\n )}\n {primaryButtonText && (\n <Button\n variant=\"primary\"\n size=\"base\"\n className={cn('tablet:w-fit w-full', classNames?.primaryButton)}\n onClick={() => handleButtonClick(primaryButtonFun, 'primary')}\n disabled={!product.availableForSale && primaryButtonFun !== 'learnMore'}\n loading={primaryLoading}\n data-headless-type-name=\"MediaShelf#ProductCard\"\n data-headless-title-desc-button={`${product.custom_name || product.name}#${product.description || ''}#${primaryButtonText}`}\n data-headless-sku={product.sku}\n >\n {primaryButtonText}\n </Button>\n )}\n </div>\n </div>\n </CardContent>\n </Card>\n )\n }\n)\n\nProductCard.displayName = 'MediaShelf.ProductCard'\n\nexport default ProductCard\nexport { ProductCard }\n"],
5
- "mappings": "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",
4
+ "sourcesContent": ["'use client'\n\nimport * as React from 'react'\nimport { cn } from '../../helpers/index.js'\nimport { Button, Badge, Card, CardContent, Picture, Text, Heading, Progress } from '../../components/index.js'\n\nimport type {\n ButtonFunctionType,\n CopyConfig,\n ProductCardData,\n StockDisplayMode,\n MediaShelfSemanticName,\n} from './types.js'\n\n/**\n * \u8D85\u5356\u65F6\u5E93\u5B58\u6761\u663E\u793A\u7684\u6700\u5C0F\u767E\u5206\u6BD4\n * \u9632\u6B62\u8D85\u5356\u65F6\u5E93\u5B58\u6761\u663E\u793A\u4E3A\u6EE1\u683C\uFF08100%\uFF09\u6216\u5B8C\u5168\u7A7A\uFF080%\uFF09\n */\nconst OVERSELLING_STOCK_PERCENTAGE = 5\n\n/**\n * \u5224\u65AD\u662F\u5426\u5E94\u8BE5\u663E\u793A\u5E93\u5B58\u4FE1\u606F\n * @param stockDisplayMode \u5E93\u5B58\u5C55\u793A\u6A21\u5F0F\n * @param stockThresholdValue \u5E93\u5B58\u9608\u503C\uFF08\u5F53\u6A21\u5F0F\u4E3A below-quantity \u6216 below-percentage \u65F6\u4F7F\u7528\uFF09\n * @param quantityAvailable \u53EF\u7528\u5E93\u5B58\u6570\u91CF\n * @param totalInventory \u603B\u5E93\u5B58\n * @returns \u662F\u5426\u663E\u793A\u5E93\u5B58\u4FE1\u606F\n */\nfunction shouldShowStock(\n stockDisplayMode: StockDisplayMode | undefined,\n stockThresholdValue: number | undefined,\n quantityAvailable: number,\n totalInventory: number\n): boolean {\n // \u672A\u914D\u7F6E\u65F6\u9ED8\u8BA4\u663E\u793A\n if (stockDisplayMode === undefined) {\n return true\n }\n\n // \u6839\u636E\u5C55\u793A\u6A21\u5F0F\u5224\u65AD\n switch (stockDisplayMode) {\n case 'always':\n // \u603B\u662F\u663E\u793A\n return true\n\n case 'never':\n // \u6C38\u4E0D\u663E\u793A\n return false\n\n case 'below-quantity':\n // \u5F53\u5E93\u5B58\u6570\u91CF\u4F4E\u4E8E\u9608\u503C\u65F6\u663E\u793A\n if (stockThresholdValue === undefined) {\n return true // \u6CA1\u6709\u8BBE\u7F6E\u9608\u503C\u65F6\u9ED8\u8BA4\u663E\u793A\n }\n\n return quantityAvailable <= stockThresholdValue\n\n case 'below-percentage':\n // \u5F53\u5E93\u5B58\u767E\u5206\u6BD4\u4F4E\u4E8E\u9608\u503C\u65F6\u663E\u793A\n if (stockThresholdValue === undefined) {\n return true // \u6CA1\u6709\u8BBE\u7F6E\u9608\u503C\u65F6\u9ED8\u8BA4\u663E\u793A\n }\n return (quantityAvailable / totalInventory) * 100 <= stockThresholdValue\n\n default:\n // \u672A\u77E5\u6A21\u5F0F\u65F6\u9ED8\u8BA4\u663E\u793A\n return true\n }\n}\n\n/**\n * MediaShelf ProductCard \u7EC4\u4EF6 Props \u63A5\u53E3\n */\nexport interface MediaShelfProductCardProps {\n /** \u4EA7\u54C1\u6570\u636E */\n product: ProductCardData\n /** \u6837\u5F0F\u7C7B\u540D */\n className?: string\n /** \u5E93\u5B58\u5C55\u793A\u6A21\u5F0F */\n stockDisplayMode?: StockDisplayMode\n /** \u5E93\u5B58\u9608\u503C\uFF08\u5F53\u6A21\u5F0F\u4E3A below-quantity \u6216 below-percentage \u65F6\u4F7F\u7528\uFF09 */\n stockThresholdValue?: number\n /** \u70B9\u51FB\u4E86\u89E3\u66F4\u591A\u56DE\u8C03 */\n onLearnMore?: (product: ProductCardData) => void\n /** \u70B9\u51FB\u7ACB\u5373\u8D2D\u4E70\u56DE\u8C03 */\n onShopNow?: (product: ProductCardData) => void\n /** \u70B9\u51FB\u52A0\u5165\u8D2D\u7269\u8F66\u56DE\u8C03 */\n onAddToCart?: (product: ProductCardData) => void\n /** \u8BED\u4E49\u5316\u7C7B\u540D */\n classNames?: Partial<Record<MediaShelfSemanticName, string>>\n /** \u4E86\u89E3\u66F4\u591A\u6309\u94AE\u6587\u672C */\n secondaryButtonText?: string\n /** \u4E86\u89E3\u66F4\u591A\u6309\u94AE\u529F\u80FD */\n secondaryButtonFun?: ButtonFunctionType\n /** \u7ACB\u5373\u8D2D\u4E70\u6309\u94AE\u6587\u672C */\n primaryButtonText?: string\n /** \u7ACB\u5373\u8D2D\u4E70\u6309\u94AE\u529F\u80FD */\n primaryButtonFun?: ButtonFunctionType\n /** \u662F\u5426\u5C55\u793A\u539F\u4EF7\uFF08\u5220\u9664\u7EBF\u4EF7\u683C\uFF09 */\n showOriginalPrice?: boolean\n /** \u6587\u6848\u914D\u7F6E */\n copy?: CopyConfig\n /** \u70B9\u51FB\u4EA7\u54C1\u56FE\u7247\u56DE\u8C03 */\n onProductImageClick?: (product: ProductCardData) => void\n /** \u662F\u5426\u5C55\u793A\u6807\u7B7E */\n showTags?: boolean\n}\n\n/**\n * MediaShelf \u4EA7\u54C1\u5361\u7247\u7EC4\u4EF6\n */\nconst ProductCard = React.forwardRef<HTMLDivElement, MediaShelfProductCardProps>(\n (\n {\n product,\n className,\n stockDisplayMode,\n stockThresholdValue,\n onLearnMore,\n onShopNow,\n onAddToCart,\n classNames,\n secondaryButtonText,\n secondaryButtonFun,\n primaryButtonText,\n primaryButtonFun,\n showOriginalPrice,\n copy,\n onProductImageClick,\n showTags = true,\n },\n ref\n ) => {\n const [primaryLoading, setPrimaryLoading] = React.useState(false)\n const [secondaryLoading, setSecondaryLoading] = React.useState(false)\n\n const stockPercentage = React.useMemo(() => {\n if (product?.availableForSale && product?.quantityAvailable <= 0) {\n return OVERSELLING_STOCK_PERCENTAGE\n }\n // \u4E0D\u53EF\u552E\u65F6\u663E\u793A0%\n if (!product?.availableForSale) {\n return 0\n }\n return ((product?.quantityAvailable ?? 0) / (product?.totalInventory ?? 1)) * 100\n }, [product?.availableForSale, product?.quantityAvailable, product?.totalInventory])\n\n // \u6839\u636E\u6309\u94AE\u529F\u80FD\u7C7B\u578B\u8C03\u7528\u76F8\u5E94\u7684\u56DE\u8C03\u51FD\u6570\n const handleButtonClick = async (buttonFun?: ButtonFunctionType, buttonType?: 'primary' | 'secondary') => {\n if (!buttonFun) return\n\n const setLoading = buttonType === 'primary' ? setPrimaryLoading : setSecondaryLoading\n setLoading(true)\n\n try {\n switch (buttonFun) {\n case 'buyNow':\n await onShopNow?.(product)\n break\n case 'addCart':\n await onAddToCart?.(product)\n break\n case 'learnMore':\n await onLearnMore?.(product)\n break\n default:\n break\n }\n } finally {\n setLoading(false)\n }\n }\n\n const overselling = product.availableForSale && product.quantityAvailable <= 0\n\n return (\n <Card\n ref={ref}\n className={cn(\n 'tablet:min-w-[auto] hover:bg-container-secondary-0 flex h-full min-w-[296px] flex-col overflow-hidden border-none',\n product.custom_link ? 'cursor-pointer' : '',\n className,\n classNames?.productCard\n )}\n >\n {/* \u56FE\u7247\u533A\u57DF */}\n <div\n className={cn(\n 'media-shelf-product-card-image-wrapper desktop:h-[240px] relative h-[200px] shrink-0 overflow-hidden',\n classNames?.productCardImageWrapper\n )}\n >\n {/* \u80CC\u666F\u56FE\u7247 */}\n <div className={cn('media-shelf-product-card-image-bg absolute inset-0 ', classNames?.productCardImageBg)}>\n <a\n onClick={() => onProductImageClick?.(product)}\n {...(!onProductImageClick && {\n href: product.custom_link || product.listingLink,\n })}\n className=\"cursor-pointer\"\n >\n <Picture\n source={product.custom_image || product.image}\n alt={product.name}\n className={cn('h-full', classNames?.productCardImage)}\n imgClassName=\"h-full object-contain\"\n />\n </a>\n </div>\n\n {/* \u6807\u7B7E\u533A\u57DF */}\n {showTags && product.tags && product.tags.length > 0 && (\n <div className=\"lg-desktop:h-[28px] absolute left-4 top-4 flex h-[24px]\">\n {product.tags.map((tag: any, index) =>\n (tag as any).label ? (\n <Badge\n key={index}\n size=\"sm\"\n variant={(tag.variant as any) || 'outline'}\n className={cn('mr-1')}\n promotionalType={tag.promotionalType}\n >\n {tag.label}\n </Badge>\n ) : (\n <React.Fragment key={index}>{tag}</React.Fragment>\n )\n )}\n </div>\n )}\n </div>\n\n {/* \u5185\u5BB9\u533A\u57DF */}\n <CardContent className=\"desktop:p-6 bg-container-primary laptop:gap-6 flex h-[calc(100%-240px)] grow flex-col justify-between gap-4 p-4\">\n {/* \u4EA7\u54C1\u6807\u9898\u548C\u526F\u6807\u9898 */}\n <div className=\"flex-0\">\n <Heading\n as=\"h3\"\n size={2}\n className={cn(\n 'text-info-primary mb-1 line-clamp-2 tracking-tight',\n onProductImageClick ? 'cursor-pointer' : '',\n classNames?.productTitle\n )}\n onClick={onProductImageClick ? () => onProductImageClick(product) : undefined}\n >\n {product.custom_name || product.name}\n </Heading>\n {(product.custom_description || product?.description) && (\n <Text\n size={2}\n className={cn('text-info-primary line-clamp-1', classNames?.productDescription)}\n html={product.custom_description || product.description}\n />\n )}\n </div>\n\n {/* \u5E93\u5B58\u4FE1\u606F */}\n {shouldShowStock(\n stockDisplayMode,\n stockThresholdValue,\n product?.quantityAvailable ?? 0,\n product?.totalInventory ?? 0\n ) && (\n <div\n data-total={product?.totalInventory ?? 0}\n data-available={product?.quantityAvailable ?? 0}\n className=\"space-y-2\"\n >\n <Progress\n value={stockPercentage}\n max={100}\n min={0}\n size=\"base\"\n variant=\"default\"\n aria-label=\"stock progress\"\n classNames={{\n progressBar: 'transition-all duration-300 ease-in-out',\n }}\n />\n <Text size={3} className=\"text-info-tertiary desktop:text-[16px] lg-desktop:text-[18px] text-[12px]\">\n {overselling\n ? copy?.limitedStock\n : copy?.stockDisplayText?.replace(\n '{count}',\n `${product.availableForSale ? product.quantityAvailable : 0}`\n )}\n </Text>\n </div>\n )}\n\n <div>\n {/* \u4EF7\u683C\u533A\u57DF */}\n <div className={cn('mb-2', classNames?.productPrice)}>\n <div className=\"flex items-baseline gap-2\">\n {product.availableForSale ? (\n <>\n <Heading size={2} className=\"text-info-primary\" as=\"h6\">\n {product.price}\n </Heading>\n {showOriginalPrice && product.originalPrice && (\n <Heading\n size={2}\n className={cn('text-info-tertiary line-through', classNames?.originalPrice)}\n as=\"h6\"\n >\n {product.originalPrice}\n </Heading>\n )}\n </>\n ) : (\n <Heading size={2} className=\"text-info-tertiary\">\n {copy?.outOfStockLabel ?? 'Sold Out'}\n </Heading>\n )}\n </div>\n </div>\n\n {product?.priceLabel && product?.availableForSale && (\n <Text\n size={4}\n className={cn(\n 'text-marketing-1 desktop:text-[16px] lg-desktop:text-[18px] mt-2 text-[12px]',\n classNames?.productPriceLabel\n )}\n >\n {product.priceLabel}\n </Text>\n )}\n\n {/* \u6309\u94AE\u533A\u57DF */}\n <div className={cn('lg-desktop:gap-3 tablet:flex-nowrap flex flex-wrap gap-2', classNames?.buttonGroup)}>\n {secondaryButtonText && (\n <Button\n variant=\"secondary\"\n size=\"base\"\n className={cn('tablet:w-fit w-full', classNames?.secondaryButton)}\n onClick={() => handleButtonClick(secondaryButtonFun, 'secondary')}\n disabled={!product.availableForSale && secondaryButtonFun !== 'learnMore'}\n loading={secondaryLoading}\n data-headless-type-name=\"MediaShelf#ProductCard\"\n data-headless-title-desc-button={`${product.custom_name || product.name}#${product.description || ''}#${secondaryButtonText}`}\n data-headless-sku={product.sku}\n >\n {secondaryButtonText}\n </Button>\n )}\n {primaryButtonText && (\n <Button\n variant=\"primary\"\n size=\"base\"\n className={cn('tablet:w-fit w-full', classNames?.primaryButton)}\n onClick={() => handleButtonClick(primaryButtonFun, 'primary')}\n disabled={!product.availableForSale && primaryButtonFun !== 'learnMore'}\n loading={primaryLoading}\n data-headless-type-name=\"MediaShelf#ProductCard\"\n data-headless-title-desc-button={`${product.custom_name || product.name}#${product.description || ''}#${primaryButtonText}`}\n data-headless-sku={product.sku}\n >\n {primaryButtonText}\n </Button>\n )}\n </div>\n </div>\n </CardContent>\n </Card>\n )\n }\n)\n\nProductCard.displayName = 'MediaShelf.ProductCard'\n\nexport default ProductCard\nexport { ProductCard }\n"],
5
+ "mappings": "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",
6
6
  "names": ["Fragment", "jsx", "jsxs", "React", "cn", "Button", "Badge", "Card", "CardContent", "Picture", "Text", "Heading", "Progress", "OVERSELLING_STOCK_PERCENTAGE", "shouldShowStock", "stockDisplayMode", "stockThresholdValue", "quantityAvailable", "totalInventory", "ProductCard", "product", "className", "onLearnMore", "onShopNow", "onAddToCart", "classNames", "secondaryButtonText", "secondaryButtonFun", "primaryButtonText", "primaryButtonFun", "showOriginalPrice", "copy", "onProductImageClick", "showTags", "ref", "primaryLoading", "setPrimaryLoading", "secondaryLoading", "setSecondaryLoading", "stockPercentage", "handleButtonClick", "buttonFun", "buttonType", "setLoading", "overselling", "tag", "index", "ProductCard_default"]
7
7
  }
@@ -11,7 +11,7 @@ export type StockDisplayMode = 'always' | 'never' | 'below-quantity' | 'below-pe
11
11
  /**
12
12
  * 语义化类名
13
13
  */
14
- export type MediaShelfSemanticName = 'root' | 'title' | 'description' | 'productCard' | 'productCardImageBg' | 'productCardImageWrapper' | 'productCardImage' | 'productTitle' | 'productDescription' | 'productPriceLabel' | 'productPrice' | 'buttonGroup' | 'secondaryButton' | 'primaryButton' | 'stockBar';
14
+ export type MediaShelfSemanticName = 'root' | 'title' | 'description' | 'productCard' | 'productCardImageBg' | 'productCardImageWrapper' | 'productCardImage' | 'productTitle' | 'productDescription' | 'productPriceLabel' | 'productPrice' | 'originalPrice' | 'buttonGroup' | 'secondaryButton' | 'primaryButton' | 'stockBar';
15
15
  /**
16
16
  * 基础产品数据接口(来自外部数据源)
17
17
  */
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../../../src/biz-components/MediaShelf/types.ts"],
4
- "sourcesContent": ["import * as React from 'react'\nimport type { BadgeProps } from '../../components/badge.js'\n\n/**\n * \u6309\u94AE\u529F\u80FD\u7C7B\u578B\n */\nexport type ButtonFunctionType = 'buyNow' | 'addCart' | 'learnMore'\n\n/**\n * \u5E93\u5B58\u5C55\u793A\u6A21\u5F0F\n */\nexport type StockDisplayMode = 'always' | 'never' | 'below-quantity' | 'below-percentage'\n\n/**\n * \u8BED\u4E49\u5316\u7C7B\u540D\n */\nexport type MediaShelfSemanticName =\n | 'root'\n | 'title'\n | 'description'\n | 'productCard'\n | 'productCardImageBg'\n | 'productCardImageWrapper'\n | 'productCardImage'\n | 'productTitle'\n | 'productDescription'\n | 'productPriceLabel'\n | 'productPrice'\n | 'buttonGroup'\n | 'secondaryButton'\n | 'primaryButton'\n | 'stockBar'\n\n/**\n * \u57FA\u7840\u4EA7\u54C1\u6570\u636E\u63A5\u53E3\uFF08\u6765\u81EA\u5916\u90E8\u6570\u636E\u6E90\uFF09\n */\nexport interface BaseProductData {\n sku: string\n name: string\n image: string\n value: string\n handle: string\n shopify_id: string\n custom_name?: string\n custom_description?: string\n custom_image?: string\n custom_link?: string\n}\n\n/**\n * Shopify \u53D8\u4F53\u6570\u636E\u63A5\u53E3\n */\nexport interface VariantData {\n /**\n * \u4EA7\u54C1\u63CF\u8FF0\n */\n description?: string\n /**\n * \u53D8\u4F53id\n */\n variantId: string\n\n /**\n * \u4EA7\u54C1\u94FE\u63A5, \u70B9\u51FB\u56FE\u7247\u7684\u65F6\u5019\u8DF3\u8F6C\u5230\u8BE5\u94FE\u63A5\n */\n listingLink: string\n /**\n * \u539F\u4EF7\n */\n originalPrice: string\n /**\n * \u73B0\u4EF7\n */\n price: string\n /**\n * \u4EF7\u683C\u4E0A\u9762\u5C55\u793A\u7684\u6807\u7B7E\u6587\u672C\n */\n priceLabel?: string\n /**\n * \u603B\u5E93\u5B58\n */\n totalInventory: number\n /**\n * \u53EF\u7528\u5E93\u5B58\u6570\u91CF\n */\n quantityAvailable: number\n /**\n * \u662F\u5426\u53EF\u552E\n */\n availableForSale: boolean\n\n /**\n * tags \u5217\u8868(\u4F1A\u5458\u4EF7\uFF0C\u6298\u6263\uFF0Cnew, hot\u7B49\u6807\u7B7E\u4FE1\u606F)\n */\n tags: Array<\n | {\n label: string\n variant: BadgeProps['variant']\n promotionalType?: BadgeProps['promotionalType']\n }\n | React.ReactNode\n >\n /**\n * \u901A\u7528\u6298\u6263\u6570\u636E\uFF0C\u5305\u62EC\u6298\u6263title, \u7C7B\u578B\u548C\u503C\n */\n coupon: any\n}\n\n/**\n * \u5B8C\u6574\u7684\u4EA7\u54C1\u5361\u7247\u6570\u636E\u63A5\u53E3\n */\nexport interface ProductCardData extends BaseProductData, VariantData {}\n\n/**\n * \u4EA7\u54C1\u5206\u7EC4Tab\u6570\u636E\u63A5\u53E3\n */\nexport interface ProductTab {\n /** Tab ID */\n id: string\n /** Tab \u6807\u9898 */\n tab: string\n /** \u8BE5\u5206\u7EC4\u4E0B\u7684\u4EA7\u54C1\u6570\u636E */\n data: ProductCardData[]\n}\n\n/**\n * MediaShelf \u6587\u6848\u914D\u7F6E\u63A5\u53E3\n * \u6CE8\u610F\uFF1AsecondaryButtonText \u548C shopNowText \u4F5C\u4E3A\u9AD8\u9891\u5C5E\u6027\u4FDD\u6301\u5728 data \u7684\u76F4\u63A5\u5C5E\u6027\u4E2D\n */\nexport interface CopyConfig {\n /** Plus\u4F1A\u5458\u4EF7\u683C\u6807\u7B7E\u6587\u672C */\n plusMemberPriceLabel?: string\n /** \u4F1A\u5458\u4EF7\u683C\u6807\u7B7E\u6587\u672C */\n memberPriceLabel?: string\n\n /** \u5E93\u5B58\u663E\u793A\u6587\u6848\u6A21\u677F\uFF0C\u652F\u6301 {count} \u5360\u4F4D\u7B26 */\n stockDisplayText?: string\n\n /** \u4E0A\u4E00\u9875\u6ED1\u52A8\u6309\u94AE\u7684\u65E0\u969C\u788D\u6807\u7B7E\uFF08MediaShelf \u4E13\u7528\uFF09 */\n previousSlideLabel?: string\n /** \u4E0B\u4E00\u9875\u6ED1\u52A8\u6309\u94AE\u7684\u65E0\u969C\u788D\u6807\u7B7E\uFF08MediaShelf \u4E13\u7528\uFF09 */\n nextSlideLabel?: string\n\n discountLabel?: string\n outOfStockLabel?: string\n limitedStock?: string\n couponTag?: string\n}\n"],
4
+ "sourcesContent": ["import * as React from 'react'\nimport type { BadgeProps } from '../../components/badge.js'\n\n/**\n * \u6309\u94AE\u529F\u80FD\u7C7B\u578B\n */\nexport type ButtonFunctionType = 'buyNow' | 'addCart' | 'learnMore'\n\n/**\n * \u5E93\u5B58\u5C55\u793A\u6A21\u5F0F\n */\nexport type StockDisplayMode = 'always' | 'never' | 'below-quantity' | 'below-percentage'\n\n/**\n * \u8BED\u4E49\u5316\u7C7B\u540D\n */\nexport type MediaShelfSemanticName =\n | 'root'\n | 'title'\n | 'description'\n | 'productCard'\n | 'productCardImageBg'\n | 'productCardImageWrapper'\n | 'productCardImage'\n | 'productTitle'\n | 'productDescription'\n | 'productPriceLabel'\n | 'productPrice'\n | 'originalPrice'\n | 'buttonGroup'\n | 'secondaryButton'\n | 'primaryButton'\n | 'stockBar'\n\n/**\n * \u57FA\u7840\u4EA7\u54C1\u6570\u636E\u63A5\u53E3\uFF08\u6765\u81EA\u5916\u90E8\u6570\u636E\u6E90\uFF09\n */\nexport interface BaseProductData {\n sku: string\n name: string\n image: string\n value: string\n handle: string\n shopify_id: string\n custom_name?: string\n custom_description?: string\n custom_image?: string\n custom_link?: string\n}\n\n/**\n * Shopify \u53D8\u4F53\u6570\u636E\u63A5\u53E3\n */\nexport interface VariantData {\n /**\n * \u4EA7\u54C1\u63CF\u8FF0\n */\n description?: string\n /**\n * \u53D8\u4F53id\n */\n variantId: string\n\n /**\n * \u4EA7\u54C1\u94FE\u63A5, \u70B9\u51FB\u56FE\u7247\u7684\u65F6\u5019\u8DF3\u8F6C\u5230\u8BE5\u94FE\u63A5\n */\n listingLink: string\n /**\n * \u539F\u4EF7\n */\n originalPrice: string\n /**\n * \u73B0\u4EF7\n */\n price: string\n /**\n * \u4EF7\u683C\u4E0A\u9762\u5C55\u793A\u7684\u6807\u7B7E\u6587\u672C\n */\n priceLabel?: string\n /**\n * \u603B\u5E93\u5B58\n */\n totalInventory: number\n /**\n * \u53EF\u7528\u5E93\u5B58\u6570\u91CF\n */\n quantityAvailable: number\n /**\n * \u662F\u5426\u53EF\u552E\n */\n availableForSale: boolean\n\n /**\n * tags \u5217\u8868(\u4F1A\u5458\u4EF7\uFF0C\u6298\u6263\uFF0Cnew, hot\u7B49\u6807\u7B7E\u4FE1\u606F)\n */\n tags: Array<\n | {\n label: string\n variant: BadgeProps['variant']\n promotionalType?: BadgeProps['promotionalType']\n }\n | React.ReactNode\n >\n /**\n * \u901A\u7528\u6298\u6263\u6570\u636E\uFF0C\u5305\u62EC\u6298\u6263title, \u7C7B\u578B\u548C\u503C\n */\n coupon: any\n}\n\n/**\n * \u5B8C\u6574\u7684\u4EA7\u54C1\u5361\u7247\u6570\u636E\u63A5\u53E3\n */\nexport interface ProductCardData extends BaseProductData, VariantData {}\n\n/**\n * \u4EA7\u54C1\u5206\u7EC4Tab\u6570\u636E\u63A5\u53E3\n */\nexport interface ProductTab {\n /** Tab ID */\n id: string\n /** Tab \u6807\u9898 */\n tab: string\n /** \u8BE5\u5206\u7EC4\u4E0B\u7684\u4EA7\u54C1\u6570\u636E */\n data: ProductCardData[]\n}\n\n/**\n * MediaShelf \u6587\u6848\u914D\u7F6E\u63A5\u53E3\n * \u6CE8\u610F\uFF1AsecondaryButtonText \u548C shopNowText \u4F5C\u4E3A\u9AD8\u9891\u5C5E\u6027\u4FDD\u6301\u5728 data \u7684\u76F4\u63A5\u5C5E\u6027\u4E2D\n */\nexport interface CopyConfig {\n /** Plus\u4F1A\u5458\u4EF7\u683C\u6807\u7B7E\u6587\u672C */\n plusMemberPriceLabel?: string\n /** \u4F1A\u5458\u4EF7\u683C\u6807\u7B7E\u6587\u672C */\n memberPriceLabel?: string\n\n /** \u5E93\u5B58\u663E\u793A\u6587\u6848\u6A21\u677F\uFF0C\u652F\u6301 {count} \u5360\u4F4D\u7B26 */\n stockDisplayText?: string\n\n /** \u4E0A\u4E00\u9875\u6ED1\u52A8\u6309\u94AE\u7684\u65E0\u969C\u788D\u6807\u7B7E\uFF08MediaShelf \u4E13\u7528\uFF09 */\n previousSlideLabel?: string\n /** \u4E0B\u4E00\u9875\u6ED1\u52A8\u6309\u94AE\u7684\u65E0\u969C\u788D\u6807\u7B7E\uFF08MediaShelf \u4E13\u7528\uFF09 */\n nextSlideLabel?: string\n\n discountLabel?: string\n outOfStockLabel?: string\n limitedStock?: string\n couponTag?: string\n}\n"],
5
5
  "mappings": "AAAA,MAAuB",
6
6
  "names": []
7
7
  }
@@ -1,2 +1,2 @@
1
- "use client";import{jsx as a,jsxs as c}from"react/jsx-runtime";import*as T from"react";import{cn as t}from"../../helpers/index.js";import{Checkbox as L,Badge as j,Heading as D,Text as g,Picture as n}from"../../components/index.js";import{useSceneShelfContext as O}from"./context.js";import{LocalizedLink as q}from"../../shared/LocalizedLink.js";const p=T.forwardRef(({className:x,classNames:f,product:e,selected:h,onSelectChange:b,showTags:C,showOriginalPrice:k,onProductImageClick:P,...u},S)=>{const i=O(),N=C??i?.showTags??!0,v=k??i?.showOriginalPrice??!0,s=f??i?.classNames??{},r=h??(i?i.selectedIds.has(e.id):!1),d=b??i?.onSelectChange,m=P??i?.onProductImageClick,l=e.soldOut??!1,w=o=>{l||typeof o=="boolean"&&d?.(o,e)},y=()=>{l||d?.(!r,e)};return c("div",{ref:S,className:t("lg-desktop:gap-2 lg-desktop:h-[362px] lg-desktop:px-6 lg-desktop:pb-6 lg-desktop:pt-4 rounded-box box-border flex h-[284px] flex-col justify-between gap-2 border-2 border-solid p-4 pb-6 transition-colors",l?"cursor-not-allowed opacity-50":"cursor-pointer",r?t("border-brand-0 bg-container-secondary-0",s?.cardSelected):t("border-lines bg-container-primary",s?.card),x),onClick:y,"data-headless-type-name":"SceneShelf#ProductCard","data-headless-title-desc-button":`${e.custom_name??e.title}##Select`,"data-headless-sku":e.id,...u,children:[a("div",{className:t("lg-desktop:left-6 lg-desktop:top-6 flex max-h-[24px] min-h-[24px] flex-wrap gap-1 overflow-visible pr-9",s?.tags),children:N&&e.tags?.map((o,z)=>a(j,{variant:o.variant||"outline",size:"sm",children:o.label},z))}),a(L,{checked:r,disabled:l,onCheckedChange:w,onClick:o=>o.stopPropagation(),className:t("text-brand-0 border-brand-0 lg-desktop:right-6 lg-desktop:top-6 absolute right-4 top-4 size-5 shrink-0",s?.checkbox)}),a("div",{className:t("flex flex-1 grow-0 items-center justify-center",s?.image),children:m?a("a",{onClick:()=>m(e),role:"button",children:a(n,{source:e.imageUrl,alt:e.imageAlt||e.title,className:"lg-desktop:size-[175px] aspect-square size-[124px] ",imgClassName:"object-contain"})}):e?.href?a(q,{href:e.href,children:a(n,{source:e.imageUrl,alt:e.imageAlt||e.title,className:"lg-desktop:size-[175px] aspect-square size-[124px] ",imgClassName:"object-contain"})}):a(n,{source:e.imageUrl,alt:e.imageAlt||e.title,className:"lg-desktop:size-[175px] aspect-square size-[124px] ",imgClassName:"object-contain"})}),c("div",{className:"flex grow flex-col justify-start gap-4",children:[a(D,{as:"h3",size:2,className:t("text-info-primary line-clamp-2 h-[2.2em]",s?.title),html:e.custom_name??e.title}),c("div",{className:t("flex flex-wrap items-center gap-1",s?.priceWrapper),children:[a(g,{as:"span",size:2,className:t("text-info-primary lg-desktop:text-[24px] text-[20px]",s?.currentPrice),children:e.currentPrice.formatted}),v&&e.originalPrice&&e.originalPrice.value>e.currentPrice.value&&a(g,{as:"span",size:2,className:t("text-info-quaternary lg-desktop:text-[24px] text-[20px] line-through",s?.originalPrice),children:e.originalPrice.formatted})]})]})]})});p.displayName="SceneShelf.ProductCard";export{p as SceneProductCard};
1
+ "use client";import{jsx as a,jsxs as d}from"react/jsx-runtime";import*as T from"react";import{cn as t}from"../../helpers/index.js";import{Checkbox as L,Badge as j,Heading as D,Text as n,Picture as c}from"../../components/index.js";import{useSceneShelfContext as O}from"./context.js";import{LocalizedLink as q}from"../../shared/LocalizedLink.js";const p=T.forwardRef(({className:x,classNames:f,product:e,selected:h,onSelectChange:b,showTags:k,showOriginalPrice:C,onProductImageClick:P,...u},N)=>{const i=O(),S=k??i?.showTags??!0,v=C??i?.showOriginalPrice??!0,s=f??i?.classNames??{},r=h??(i?i.selectedIds.has(e.id):!1),m=b??i?.onSelectChange,g=P??i?.onProductImageClick,o=e.soldOut??!1,w=l=>{o||typeof l=="boolean"&&m?.(l,e)},y=()=>{o||m?.(!r,e)};return d("div",{ref:N,className:t("lg-desktop:gap-2 lg-desktop:h-[362px] lg-desktop:px-6 lg-desktop:pb-6 lg-desktop:pt-4 rounded-box box-border flex h-[284px] flex-col justify-between gap-2 border-2 border-solid p-4 pb-6 transition-colors",o?"cursor-not-allowed opacity-50":"cursor-pointer",r?t("border-brand-0 bg-container-secondary-0",s?.cardSelected):t("border-lines bg-container-primary",s?.card),x),onClick:y,"data-headless-type-name":"SceneShelf#ProductCard","data-headless-title-desc-button":`${e.custom_name??e.title}##Select`,"data-headless-sku":e.id,...u,children:[a("div",{className:t("lg-desktop:left-6 lg-desktop:top-6 flex max-h-[24px] min-h-[24px] flex-wrap gap-1 overflow-visible pr-9",s?.tags),children:S&&e.tags?.map((l,z)=>a(j,{variant:l.variant||"outline",size:"sm",children:l.label},z))}),a(L,{checked:r,disabled:o,onCheckedChange:w,onClick:l=>l.stopPropagation(),className:t("text-brand-0 border-brand-0 lg-desktop:right-6 lg-desktop:top-6 absolute right-4 top-4 size-5 shrink-0",s?.checkbox)}),a("div",{className:t("flex flex-1 grow-0 items-center justify-center",s?.image),children:g?a("a",{onClick:()=>g(e),role:"button",children:a(c,{source:e.imageUrl,alt:e.imageAlt||e.title,className:"lg-desktop:size-[175px] aspect-square size-[124px] ",imgClassName:"object-contain"})}):e?.href?a(q,{href:e.href,children:a(c,{source:e.imageUrl,alt:e.imageAlt||e.title,className:"lg-desktop:size-[175px] aspect-square size-[124px] ",imgClassName:"object-contain"})}):a(c,{source:e.imageUrl,alt:e.imageAlt||e.title,className:"lg-desktop:size-[175px] aspect-square size-[124px] ",imgClassName:"object-contain"})}),d("div",{className:"flex grow flex-col justify-start gap-4",children:[a(D,{as:"h3",size:2,className:t("text-info-primary line-clamp-2 h-[2.2em]",s?.title),html:e.custom_name??e.title}),d("div",{className:t("flex flex-wrap items-center gap-1",s?.priceWrapper),children:[a(n,{as:"span",size:2,className:t("text-info-primary lg-desktop:text-[24px] text-[20px]",s?.currentPrice),children:e.currentPrice.formatted}),v&&e.originalPrice&&e.originalPrice.value>e.currentPrice.value&&a(n,{as:"span",size:2,className:t("text-info-quaternary lg-desktop:text-[24px] text-[20px] line-through",s?.originalPrice),children:e.originalPrice.formatted})]}),e?.priceLabel&&a(n,{size:4,className:t("text-marketing-1 desktop:text-[16px] lg-desktop:text-[18px] mt-2 text-[14px]",s?.productPriceLabel),children:e.priceLabel})]})]})});p.displayName="SceneShelf.ProductCard";export{p as SceneProductCard};
2
2
  //# sourceMappingURL=ProductCard.js.map
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../../../src/biz-components/SceneShelf/ProductCard.tsx"],
4
- "sourcesContent": ["'use client'\n\nimport * as React from 'react'\nimport { cn } from '../../helpers/index.js'\nimport { Checkbox, Badge, Heading, Text, Picture } from '../../components/index.js'\nimport { useSceneShelfContext } from './context.js'\nimport { LocalizedLink } from '../../shared/LocalizedLink.js'\nimport type { SceneProductCardSemanticName, SceneProductCardData } from './types.js'\n\nexport interface SceneProductCardProps extends React.HTMLAttributes<HTMLDivElement> {\n /** \u4EA7\u54C1\u6570\u636E */\n product: SceneProductCardData\n /** \u662F\u5426\u9009\u4E2D */\n selected?: boolean\n /** \u9009\u4E2D\u72B6\u6001\u53D8\u5316\u56DE\u8C03 */\n onSelectChange?: (selected: boolean, product: SceneProductCardData) => void\n /** \u662F\u5426\u663E\u793A\u6807\u7B7E */\n showTags?: boolean\n /** \u662F\u5426\u663E\u793A\u539F\u4EF7 */\n showOriginalPrice?: boolean\n /** \u4EA7\u54C1\u56FE\u7247\u70B9\u51FB\u56DE\u8C03 */\n onProductImageClick?: (product: SceneProductCardData) => void\n /** \u8BED\u4E49\u5316\u7C7B\u540D */\n classNames?: Partial<Record<SceneProductCardSemanticName, string>>\n}\n\n/**\n * SceneProductCard - \u573A\u666F\u63A8\u8350\u8D27\u67B6\u4EA7\u54C1\u5361\u7247\n *\n * @description \u7528\u4E8E\u573A\u666F\u63A8\u8350\u8D27\u67B6\u7684\u53EF\u9009\u4E2D\u4EA7\u54C1\u5361\u7247\u7EC4\u4EF6\n */\nconst SceneProductCard = React.forwardRef<HTMLDivElement, SceneProductCardProps>(\n (\n {\n className,\n classNames: classNamesProp,\n product,\n selected: selectedProp,\n onSelectChange: onSelectChangeProp,\n showTags: showTagsProp,\n showOriginalPrice: showOriginalPriceProp,\n onProductImageClick,\n ...props\n },\n ref\n ) => {\n // \u4ECE Context \u8BFB\u53D6\u914D\u7F6E\n const context = useSceneShelfContext()\n\n // Props \u4F18\u5148\u7EA7\u9AD8\u4E8E Context\n const showTags = showTagsProp ?? context?.showTags ?? true\n const showOriginalPrice = showOriginalPriceProp ?? context?.showOriginalPrice ?? true\n const classNames = classNamesProp ?? context?.classNames ?? {}\n\n // \u9009\u4E2D\u72B6\u6001\u548C\u56DE\u8C03\u4ECE Context \u83B7\u53D6\n const selected = selectedProp ?? (context ? context.selectedIds.has(product.id) : false)\n const onSelectChange = onSelectChangeProp ?? context?.onSelectChange\n const resolvedOnProductImageClick = onProductImageClick ?? context?.onProductImageClick\n const disabled = product.soldOut ?? false\n\n const handleCheckboxChange = (checked: boolean | 'indeterminate') => {\n if (disabled) return\n if (typeof checked === 'boolean') {\n onSelectChange?.(checked, product)\n }\n }\n\n const handleCardClick = () => {\n if (disabled) return\n onSelectChange?.(!selected, product)\n }\n\n return (\n <div\n ref={ref}\n className={cn(\n 'lg-desktop:gap-2 lg-desktop:h-[362px] lg-desktop:px-6 lg-desktop:pb-6 lg-desktop:pt-4 rounded-box box-border flex h-[284px] flex-col justify-between gap-2 border-2 border-solid p-4 pb-6 transition-colors',\n disabled ? 'cursor-not-allowed opacity-50' : 'cursor-pointer',\n selected\n ? cn('border-brand-0 bg-container-secondary-0', classNames?.cardSelected)\n : cn('border-lines bg-container-primary', classNames?.card),\n className\n )}\n onClick={handleCardClick}\n data-headless-type-name=\"SceneShelf#ProductCard\"\n data-headless-title-desc-button={`${product.custom_name ?? product.title}##Select`}\n data-headless-sku={product.id}\n {...props}\n >\n {/* \u6807\u7B7E\u533A\u57DF */}\n <div\n className={cn(\n 'lg-desktop:left-6 lg-desktop:top-6 flex max-h-[24px] min-h-[24px] flex-wrap gap-1 overflow-visible pr-9',\n classNames?.tags\n )}\n >\n {showTags &&\n product.tags?.map((tag, index) => (\n <Badge key={index} variant={tag.variant || 'outline'} size=\"sm\">\n {tag.label}\n </Badge>\n ))}\n </div>\n\n {/* Checkbox */}\n <Checkbox\n checked={selected}\n disabled={disabled}\n onCheckedChange={handleCheckboxChange}\n onClick={e => e.stopPropagation()}\n className={cn(\n 'text-brand-0 border-brand-0 lg-desktop:right-6 lg-desktop:top-6 absolute right-4 top-4 size-5 shrink-0',\n classNames?.checkbox\n )}\n />\n\n {/* \u4EA7\u54C1\u56FE\u7247 */}\n <div className={cn('flex flex-1 grow-0 items-center justify-center', classNames?.image)}>\n {resolvedOnProductImageClick ? (\n <a onClick={() => resolvedOnProductImageClick(product)} role=\"button\">\n <Picture\n source={product.imageUrl}\n alt={product.imageAlt || product.title}\n className=\"lg-desktop:size-[175px] aspect-square size-[124px] \"\n imgClassName=\"object-contain\"\n />\n </a>\n ) : product?.href ? (\n <LocalizedLink href={product.href}>\n <Picture\n source={product.imageUrl}\n alt={product.imageAlt || product.title}\n className=\"lg-desktop:size-[175px] aspect-square size-[124px] \"\n imgClassName=\"object-contain\"\n />\n </LocalizedLink>\n ) : (\n <Picture\n source={product.imageUrl}\n alt={product.imageAlt || product.title}\n className=\"lg-desktop:size-[175px] aspect-square size-[124px] \"\n imgClassName=\"object-contain\"\n />\n )}\n </div>\n\n {/* \u4EA7\u54C1\u4FE1\u606F */}\n <div className=\"flex grow flex-col justify-start gap-4\">\n {/* \u4EA7\u54C1\u540D\u79F0 */}\n <Heading\n as=\"h3\"\n size={2}\n className={cn('text-info-primary line-clamp-2 h-[2.2em]', classNames?.title)}\n html={product.custom_name ?? product.title}\n />\n\n {/* \u4EF7\u683C\u533A\u57DF */}\n <div className={cn('flex flex-wrap items-center gap-1', classNames?.priceWrapper)}>\n <Text\n as=\"span\"\n size={2}\n className={cn('text-info-primary lg-desktop:text-[24px] text-[20px]', classNames?.currentPrice)}\n >\n {product.currentPrice.formatted}\n </Text>\n {showOriginalPrice && product.originalPrice && product.originalPrice.value > product.currentPrice.value && (\n <Text\n as=\"span\"\n size={2}\n className={cn(\n 'text-info-quaternary lg-desktop:text-[24px] text-[20px] line-through',\n classNames?.originalPrice\n )}\n >\n {product.originalPrice.formatted}\n </Text>\n )}\n </div>\n </div>\n </div>\n )\n }\n)\n\nSceneProductCard.displayName = 'SceneShelf.ProductCard'\n\nexport { SceneProductCard }\n"],
5
- "mappings": "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",
4
+ "sourcesContent": ["'use client'\n\nimport * as React from 'react'\nimport { cn } from '../../helpers/index.js'\nimport { Checkbox, Badge, Heading, Text, Picture } from '../../components/index.js'\nimport { useSceneShelfContext } from './context.js'\nimport { LocalizedLink } from '../../shared/LocalizedLink.js'\nimport type { SceneProductCardSemanticName, SceneProductCardData } from './types.js'\n\nexport interface SceneProductCardProps extends React.HTMLAttributes<HTMLDivElement> {\n /** \u4EA7\u54C1\u6570\u636E */\n product: SceneProductCardData\n /** \u662F\u5426\u9009\u4E2D */\n selected?: boolean\n /** \u9009\u4E2D\u72B6\u6001\u53D8\u5316\u56DE\u8C03 */\n onSelectChange?: (selected: boolean, product: SceneProductCardData) => void\n /** \u662F\u5426\u663E\u793A\u6807\u7B7E */\n showTags?: boolean\n /** \u662F\u5426\u663E\u793A\u539F\u4EF7 */\n showOriginalPrice?: boolean\n /** \u4EA7\u54C1\u56FE\u7247\u70B9\u51FB\u56DE\u8C03 */\n onProductImageClick?: (product: SceneProductCardData) => void\n /** \u8BED\u4E49\u5316\u7C7B\u540D */\n classNames?: Partial<Record<SceneProductCardSemanticName, string>>\n}\n\n/**\n * SceneProductCard - \u573A\u666F\u63A8\u8350\u8D27\u67B6\u4EA7\u54C1\u5361\u7247\n *\n * @description \u7528\u4E8E\u573A\u666F\u63A8\u8350\u8D27\u67B6\u7684\u53EF\u9009\u4E2D\u4EA7\u54C1\u5361\u7247\u7EC4\u4EF6\n */\nconst SceneProductCard = React.forwardRef<HTMLDivElement, SceneProductCardProps>(\n (\n {\n className,\n classNames: classNamesProp,\n product,\n selected: selectedProp,\n onSelectChange: onSelectChangeProp,\n showTags: showTagsProp,\n showOriginalPrice: showOriginalPriceProp,\n onProductImageClick,\n ...props\n },\n ref\n ) => {\n // \u4ECE Context \u8BFB\u53D6\u914D\u7F6E\n const context = useSceneShelfContext()\n\n // Props \u4F18\u5148\u7EA7\u9AD8\u4E8E Context\n const showTags = showTagsProp ?? context?.showTags ?? true\n const showOriginalPrice = showOriginalPriceProp ?? context?.showOriginalPrice ?? true\n const classNames = classNamesProp ?? context?.classNames ?? {}\n\n // \u9009\u4E2D\u72B6\u6001\u548C\u56DE\u8C03\u4ECE Context \u83B7\u53D6\n const selected = selectedProp ?? (context ? context.selectedIds.has(product.id) : false)\n const onSelectChange = onSelectChangeProp ?? context?.onSelectChange\n const resolvedOnProductImageClick = onProductImageClick ?? context?.onProductImageClick\n const disabled = product.soldOut ?? false\n\n const handleCheckboxChange = (checked: boolean | 'indeterminate') => {\n if (disabled) return\n if (typeof checked === 'boolean') {\n onSelectChange?.(checked, product)\n }\n }\n\n const handleCardClick = () => {\n if (disabled) return\n onSelectChange?.(!selected, product)\n }\n\n return (\n <div\n ref={ref}\n className={cn(\n 'lg-desktop:gap-2 lg-desktop:h-[362px] lg-desktop:px-6 lg-desktop:pb-6 lg-desktop:pt-4 rounded-box box-border flex h-[284px] flex-col justify-between gap-2 border-2 border-solid p-4 pb-6 transition-colors',\n disabled ? 'cursor-not-allowed opacity-50' : 'cursor-pointer',\n selected\n ? cn('border-brand-0 bg-container-secondary-0', classNames?.cardSelected)\n : cn('border-lines bg-container-primary', classNames?.card),\n className\n )}\n onClick={handleCardClick}\n data-headless-type-name=\"SceneShelf#ProductCard\"\n data-headless-title-desc-button={`${product.custom_name ?? product.title}##Select`}\n data-headless-sku={product.id}\n {...props}\n >\n {/* \u6807\u7B7E\u533A\u57DF */}\n <div\n className={cn(\n 'lg-desktop:left-6 lg-desktop:top-6 flex max-h-[24px] min-h-[24px] flex-wrap gap-1 overflow-visible pr-9',\n classNames?.tags\n )}\n >\n {showTags &&\n product.tags?.map((tag, index) => (\n <Badge key={index} variant={tag.variant || 'outline'} size=\"sm\">\n {tag.label}\n </Badge>\n ))}\n </div>\n\n {/* Checkbox */}\n <Checkbox\n checked={selected}\n disabled={disabled}\n onCheckedChange={handleCheckboxChange}\n onClick={e => e.stopPropagation()}\n className={cn(\n 'text-brand-0 border-brand-0 lg-desktop:right-6 lg-desktop:top-6 absolute right-4 top-4 size-5 shrink-0',\n classNames?.checkbox\n )}\n />\n\n {/* \u4EA7\u54C1\u56FE\u7247 */}\n <div className={cn('flex flex-1 grow-0 items-center justify-center', classNames?.image)}>\n {resolvedOnProductImageClick ? (\n <a onClick={() => resolvedOnProductImageClick(product)} role=\"button\">\n <Picture\n source={product.imageUrl}\n alt={product.imageAlt || product.title}\n className=\"lg-desktop:size-[175px] aspect-square size-[124px] \"\n imgClassName=\"object-contain\"\n />\n </a>\n ) : product?.href ? (\n <LocalizedLink href={product.href}>\n <Picture\n source={product.imageUrl}\n alt={product.imageAlt || product.title}\n className=\"lg-desktop:size-[175px] aspect-square size-[124px] \"\n imgClassName=\"object-contain\"\n />\n </LocalizedLink>\n ) : (\n <Picture\n source={product.imageUrl}\n alt={product.imageAlt || product.title}\n className=\"lg-desktop:size-[175px] aspect-square size-[124px] \"\n imgClassName=\"object-contain\"\n />\n )}\n </div>\n\n {/* \u4EA7\u54C1\u4FE1\u606F */}\n <div className=\"flex grow flex-col justify-start gap-4\">\n {/* \u4EA7\u54C1\u540D\u79F0 */}\n <Heading\n as=\"h3\"\n size={2}\n className={cn('text-info-primary line-clamp-2 h-[2.2em]', classNames?.title)}\n html={product.custom_name ?? product.title}\n />\n\n {/* \u4EF7\u683C\u533A\u57DF */}\n <div className={cn('flex flex-wrap items-center gap-1', classNames?.priceWrapper)}>\n <Text\n as=\"span\"\n size={2}\n className={cn('text-info-primary lg-desktop:text-[24px] text-[20px]', classNames?.currentPrice)}\n >\n {product.currentPrice.formatted}\n </Text>\n {showOriginalPrice && product.originalPrice && product.originalPrice.value > product.currentPrice.value && (\n <Text\n as=\"span\"\n size={2}\n className={cn(\n 'text-info-quaternary lg-desktop:text-[24px] text-[20px] line-through',\n classNames?.originalPrice\n )}\n >\n {product.originalPrice.formatted}\n </Text>\n )}\n </div>\n\n {/** \u4EF7\u683C\u6807\u7B7E */}\n {product?.priceLabel && (\n <Text\n size={4}\n className={cn(\n 'text-marketing-1 desktop:text-[16px] lg-desktop:text-[18px] mt-2 text-[14px]',\n classNames?.productPriceLabel\n )}\n >\n {product.priceLabel}\n </Text>\n )}\n </div>\n </div>\n )\n }\n)\n\nSceneProductCard.displayName = 'SceneShelf.ProductCard'\n\nexport { SceneProductCard }\n"],
5
+ "mappings": "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",
6
6
  "names": ["jsx", "jsxs", "React", "cn", "Checkbox", "Badge", "Heading", "Text", "Picture", "useSceneShelfContext", "LocalizedLink", "SceneProductCard", "className", "classNamesProp", "product", "selectedProp", "onSelectChangeProp", "showTagsProp", "showOriginalPriceProp", "onProductImageClick", "props", "ref", "context", "showTags", "showOriginalPrice", "classNames", "selected", "onSelectChange", "resolvedOnProductImageClick", "disabled", "handleCheckboxChange", "checked", "handleCardClick", "tag", "index", "e"]
7
7
  }
@@ -5,7 +5,7 @@ export type ButtonFunctionType = 'buyNow' | 'addCart' | 'learnMore';
5
5
  /**
6
6
  * 产品卡片语义化名称
7
7
  */
8
- export type SceneProductCardSemanticName = 'card' | 'cardSelected' | 'tags' | 'checkbox' | 'image' | 'title' | 'priceWrapper' | 'currentPrice' | 'originalPrice';
8
+ export type SceneProductCardSemanticName = 'card' | 'cardSelected' | 'tags' | 'checkbox' | 'image' | 'title' | 'priceWrapper' | 'currentPrice' | 'originalPrice' | 'productPriceLabel';
9
9
  /**
10
10
  * SceneShelf 语义化类名
11
11
  */
@@ -44,6 +44,8 @@ export interface SceneProductCardData {
44
44
  imageAlt?: string;
45
45
  /** 当前价格 */
46
46
  currentPrice: PriceData;
47
+ /** 价格标签文本(如 "Plus Member Price") */
48
+ priceLabel?: string;
47
49
  /** 原价(可选,用于显示删除线价格) */
48
50
  originalPrice?: PriceData;
49
51
  /** 产品标签列表 */
@@ -6,7 +6,7 @@ import 'swiper/css/navigation';
6
6
  * 按钮功能类型
7
7
  */
8
8
  export type ButtonFunctionType = 'buyNow' | 'addCart' | 'learnMore';
9
- export type SceneShelfV2SemanticName = 'root' | 'media' | 'mediaOverlay' | 'mediaQuote' | 'mediaPlayButton' | 'products' | 'productsTitle' | 'productGrid' | 'productCardSlideWrapper' | 'productCard' | 'productCardImage' | 'productCardTags' | 'productCardTitle' | 'productCardDescription' | 'productCardPriceWrapper' | 'productCardCurrentPrice' | 'productCardOriginalPrice' | 'productCardButtons';
9
+ export type SceneShelfV2SemanticName = 'root' | 'media' | 'mediaOverlay' | 'mediaQuote' | 'mediaPlayButton' | 'products' | 'productsTitle' | 'productGrid' | 'productCardSlideWrapper' | 'productCard' | 'productCardImage' | 'productCardTags' | 'productCardTitle' | 'productCardDescription' | 'productCardPriceWrapper' | 'productCardCurrentPrice' | 'productCardOriginalPrice' | 'productCardPriceLabel' | 'productCardButtons';
10
10
  export interface SceneShelfV2Tag {
11
11
  label: string;
12
12
  variant?: 'outline' | 'fill';
@@ -45,6 +45,8 @@ export interface SceneShelfV2Product {
45
45
  custom_name?: string;
46
46
  /** 自定义产品描述 */
47
47
  custom_description?: string;
48
+ /** 价格标签文本(如 "Plus Member Price") */
49
+ priceLabel?: string;
48
50
  }
49
51
  /**
50
52
  * 文案配置
@@ -1,2 +1,2 @@
1
- "use client";import{Fragment as de,jsx as t,jsxs as d}from"react/jsx-runtime";import*as a from"react";import{cn as o,getLocalizedPath as Q}from"../../helpers/index.js";import{Heading as E,Text as q,Badge as J,Button as O,Picture as G}from"../../components/index.js";import X from"../Media/index.js";import{Swiper as Y,SwiperSlide as Z}from"swiper/react";import{Mousewheel as ee}from"swiper/modules";import"swiper/css";import"swiper/css/navigation";import{withLayout as te}from"../../shared/Styles.js";import{useGridRowCount as ie}from"../../hooks/useGridRowCount.js";import{useExposure as oe}from"../../hooks/useExposure.js";import{useViewItemList as ae}from"../../hooks/useViewItemList.js";import{trackUrlRef as ne}from"../../shared/trackUrlRef.js";import{useAiuiContext as U}from"../AiuiProvider/index.js";import{gaTrack as H}from"../../shared/track.js";const re="shelf",se="scene_shelf_v2",le=()=>t("svg",{width:"24",height:"24",viewBox:"0 0 24 24",fill:"none",xmlns:"http://www.w3.org/2000/svg","aria-hidden":"true",children:t("path",{d:"M8 5.14v13.72L19 12 8 5.14z",fill:"white"})}),ce=()=>d("svg",{width:"24",height:"24",viewBox:"0 0 24 24",fill:"none",xmlns:"http://www.w3.org/2000/svg","aria-hidden":"true",children:[t("rect",{x:"6",y:"5",width:"4",height:"14",rx:"1",fill:"white"}),t("rect",{x:"14",y:"5",width:"4",height:"14",rx:"1",fill:"white"})]}),j=a.memo(({product:e,isShowTag:p=!0,onImageClick:m,onProductImageClick:l,onLearnMore:S,onShopNow:P,onAddToCart:_,secondaryButtonText:h,secondaryButtonFun:x,primaryButtonText:b,primaryButtonFun:k,classNames:r,className:n,theme:V,index:s})=>{const{locale:N="us",trackingData:B}=U(),[L,M]=a.useState(!1),[C,z]=a.useState(!1),u=B?.pageGroup,y=a.useCallback(async(c,v)=>{if(!c)return;const T=v==="primary"?M:z;T(!0);try{switch(c){case"buyNow":await P?.(e);break;case"addCart":await _?.(e);break;case"learnMore":await S?.(e?.href??"");break;default:break}}finally{T(!1)}},[S,P,_,e]),I=a.useCallback(()=>y(k,"primary"),[y,k]),R=a.useCallback(()=>y(x,"secondary"),[y,x]),f=a.useCallback(c=>{const v=l??m;!e.href&&v&&c.preventDefault(),v?.(e),H({event:"ga4Event",event_name:"select_item",item_list_name:"Scene_Shelf_2_Products",page_group:u,items:[{item_id:e.sku,item_name:e.custom_name||e.title,item_variant:e.variantId,price:e.currentPrice,index:s}]})},[s,m,l,u,e]);return d("div",{className:o("scene-shelf-v2-product-card rounded-box bg-container-secondary-1 tablet:px-6 desktop:pb-6 desktop:px-6 box-border flex h-full flex-col items-center justify-between gap-3 overflow-hidden px-2 py-4",n,r?.productCard,{"bg-container-secondary-0":V==="dark"}),children:[e.href?t("a",{href:Q(ne(e.href,u+"_"+re+"_"+se),N),onClick:f,className:o("scene-shelf-v2-product-card-image desktop:size-[196px] tablet:size-[140px] lg-desktop:size-[196px] flex size-[128px] shrink-0 items-center justify-center transition-opacity hover:opacity-80",r?.productCardImage),"aria-label":`View ${e.title}`,children:t(G,{source:e.imageUrl,alt:e.imageAlt,className:"size-full",imgClassName:"object-contain"})}):t("div",{className:o("scene-shelf-v2-product-card-image desktop:size-[196px] tablet:size-[140px] lg-desktop:size-[196px] flex size-[128px] shrink-0 items-center justify-center ",(l??m)&&"cursor-pointer transition-opacity hover:opacity-80",r?.productCardImage),onClick:l??m?f:void 0,role:l??m?"button":void 0,tabIndex:l??m?0:void 0,"aria-label":l??m?`View ${e.title}`:void 0,children:t(G,{source:e.imageUrl,alt:e.imageAlt,className:"size-full",imgClassName:"object-contain"})}),d("div",{className:"desktop:gap-6 flex w-full flex-1 flex-col justify-between gap-4",children:[d("div",{className:"flex flex-col gap-2",children:[t("div",{className:o("scene-shelf-v2-product-card-tags flex min-h-[24px] flex-wrap gap-1",r?.productCardTags),children:p&&e?.tags?.map((c,v)=>t(J,{variant:c.variant??"outline",size:"sm",className:"",children:c.label},v))}),t(E,{as:"h3",size:2,className:o("scene-shelf-v2-product-card-title text-info-primary laptop:line-clamp-2 line-clamp-3 pr-[16%] text-[16px]",r?.productCardTitle),children:e.custom_name||e.title}),(e.custom_description||e.description)&&t(q,{as:"p",size:1,className:o("scene-shelf-v2-product-card-description text-info-primary tablet:text-[14px] desktop:text-[16px] lg-desktop:text-[18px] line-clamp-1",r?.productCardDescription),children:e.custom_description||e.description})]}),d("div",{className:"flex flex-col gap-2",children:[d("div",{className:o("scene-shelf-v2-product-card-price flex flex-wrap items-center gap-1",r?.productCardPriceWrapper),children:[t(E,{as:"h6",size:2,className:o("scene-shelf-v2-product-card-current-price text-info-primary",r?.productCardCurrentPrice),children:e.currentPrice}),e.originalPrice&&t(E,{as:"h6",size:2,className:o("scene-shelf-v2-product-card-original-price text-info-tertiary line-through",r?.productCardOriginalPrice),children:e.originalPrice})]}),(h||b)&&d("div",{className:o("scene-shelf-v2-product-card-buttons laptop:flex-nowrap lg-desktop:gap-3 flex flex-wrap gap-2",r?.productCardButtons),children:[h&&t(O,{variant:"secondary",className:"laptop:grow-0 flex-1 whitespace-nowrap",onClick:()=>{R(),H({event:"ga4Event",event_name:"component_click",event_parameters:{page_group:u||"Home Page",component_type:"copy",component_name:"scene_shelf_product",component_title:e.title,component_description:"",button_name:h,SKU:e.sku||"",position:s}})},disabled:e.soldOut&&x!=="learnMore",loading:C,children:h}),b&&t(O,{variant:"primary",className:"laptop:grow-0 flex-1 whitespace-nowrap",onClick:()=>{I(),H({event:"ga4Event",event_name:"component_click",event_parameters:{page_group:u||"Home Page",component_type:"copy",component_name:"scene_shelf_product",component_title:e.title,component_description:"",button_name:b,SKU:e.sku||"",position:s}})},disabled:e.soldOut&&k!=="learnMore",loading:L,children:b})]})]})]})]})});j.displayName="SceneShelfV2.ProductCard";const W=a.forwardRef(({className:e,classNames:p={},data:m,onPlayClick:l,onImageClick:S,onProductImageClick:P,onLearnMore:_,onShopNow:h,onAddToCart:x,...b},k)=>{const{theme:r="light",sceneImage:n,productsTitle:V,products:s,secondaryButtonText:N,secondaryButtonFun:B,primaryButtonText:L,primaryButtonFun:M,viewMoreLimit:C=2,copy:z}=m,u=a.useRef(null),y=a.useRef(null),I=a.useRef(null),[R,f]=a.useState(!1),[c,v]=a.useState(!1),{trackingData:T}=U();oe(y,{componentType:"image",componentName:"scene_shelf_banner"}),ae(I,{componentType:"video",componentName:"scene_shelf_banner",itemListName:"Scene_Shelf_2_Products",items:s.map((i,g)=>({item_id:i.sku??"",item_name:i.title,item_variant:i.variantId??"",price:i.currentPrice,index:g})),tabName:""});const F=ie({rows:C??0,mobileCols:2}),A=a.useMemo(()=>[n?.pc,n?.desktop,n?.laptop,n?.pad,n?.mobile].some(i=>i?.mimeType==="video/mp4"),[n]),K=a.useCallback(()=>{const i=u.current;i?i.paused?(i.play(),f(!0),l?.(!0)):(i.pause(),f(!1),l?.(!1)):l?.(!0),H({event:"ga4Event",event_name:"component_click",event_parameters:{page_group:T?.pageGroup,component_type:"video",component_name:"scene_shelf_banner",position:1,creative_id:n?.pc?.id}})},[l,n?.pc?.id,T?.pageGroup]);return a.useEffect(()=>{const i=u.current;if(!i||!A)return;const g=new IntersectionObserver(w=>{w.forEach(D=>{D.isIntersecting?i.play().catch($=>{console.warn("Video autoplay failed:",$)}):i.pause()})},{threshold:.5});return g.observe(i),()=>{g.disconnect()}},[]),d("div",{...b,ref:k,className:o("scene-shelf-v2-root w-full overflow-hidden",{"aiui-dark":r==="dark"},e,p?.root),children:[d("div",{className:o("scene-shelf-v2-media laptop:h-[360px] tablet:h-[400px] desktop:h-[384px] rounded-box tablet:rounded-t-box tablet:rounded-b-none lg-desktop:h-[480px] relative h-[240px] overflow-hidden",p?.media),ref:y,children:[t(X,{pcImage:n?.pc,desktopImage:n?.desktop,laptopImage:n?.laptop,padImage:n?.pad,mobileImage:n?.mobile,className:"size-full",videoClassName:"absolute inset-0 size-full object-cover",videoRef:u,onVideoPlay:()=>f(!0),onVideoPause:()=>f(!1),onVideoEnded:()=>f(!1)}),t("div",{"aria-hidden":"true",className:o("scene-shelf-v2-media-overlay pointer-events-none absolute inset-0",p?.mediaOverlay)}),A&&t("div",{className:"desktop:gap-16 desktop:p-8 absolute inset-0 flex items-end justify-end gap-4 p-6",children:t("button",{type:"button","aria-label":R?"Pause video":"Play video",onClick:K,className:o("scene-shelf-v2-media-play-button flex size-14 shrink-0 items-center justify-center rounded-full bg-white/20 transition-opacity hover:opacity-80",p?.mediaPlayButton),children:R?t(ce,{}):t(le,{})})})]}),d("div",{ref:I,className:o("scene-shelf-v2-products text-info-primary tablet:bg-container-primary laptop:p-6 desktop:p-8 rounded-b-box tablet:p-4 flex flex-col gap-4 bg-transparent p-0 pt-3",p?.products),children:[V&&t(E,{as:"h2",size:3,className:o("scene-shelf-v2-products-title text-info-primary",p?.productsTitle),html:V}),t("div",{className:"tablet:hidden grid grid-cols-2 gap-3",children:(()=>{const i=C!==void 0&&C>0&&s.length>F,g=i&&!c?s.slice(0,F):s;return d(de,{children:[g.map((w,D)=>t(j,{isShowTag:m.isShowTag??!0,product:w,onImageClick:S,onProductImageClick:P,onLearnMore:_,onShopNow:h,onAddToCart:x,secondaryButtonText:N,secondaryButtonFun:B,primaryButtonText:L,primaryButtonFun:M,classNames:p,theme:r,index:D},w.productKey)),i&&t("div",{className:"col-span-2 mt-6 flex justify-center",children:d("button",{type:"button",onClick:()=>v(w=>!w),className:"text-info-primary hover:text-brand-0 flex items-center gap-2 text-[14px] font-bold transition-colors","aria-expanded":c,children:[c?z?.viewLessLabel??"View Less":z?.viewMoreLabel??"View More",t("svg",{className:o("size-4 transition-transform",c&&"rotate-180"),fill:"none",stroke:"currentColor",viewBox:"0 0 24 24",children:t("path",{strokeLinecap:"round",strokeLinejoin:"round",strokeWidth:2,d:"M19 9l-7 7-7-7"})})]})})]})})()}),t("div",{className:"tablet:block hidden",children:t("div",{className:"relative",children:t(Y,{slidesPerView:"auto",observer:!0,observeParents:!0,modules:[ee],mousewheel:{enabled:!0,forceToAxis:!0,sensitivity:1},className:"!overflow-visible",breakpoints:{768:{spaceBetween:16,slidesPerView:s.length>3?2.3:2},1024:{spaceBetween:16,slidesPerView:s.length>3?2.8:3},1440:{spaceBetween:16,slidesPerView:s.length>4?3.8:4},1920:{spaceBetween:16,slidesPerView:s.length>4?3.8:4}},children:s.map((i,g)=>t(Z,{className:o("!h-auto ",p.productCardSlideWrapper),children:t(j,{product:i,isShowTag:m.isShowTag??!0,onImageClick:S,onProductImageClick:P,onLearnMore:_,onShopNow:h,onAddToCart:x,secondaryButtonText:N,secondaryButtonFun:B,primaryButtonText:L,primaryButtonFun:M,classNames:p,theme:r,index:g})},i.productKey))})})})]})]})});W.displayName="SceneShelfV2";var ke=te(W);export{j as SceneShelfV2ProductCard,ke as default};
1
+ "use client";import{Fragment as de,jsx as t,jsxs as d}from"react/jsx-runtime";import*as a from"react";import{cn as o,getLocalizedPath as q}from"../../helpers/index.js";import{Heading as E,Text as O,Badge as J,Button as G,Picture as U}from"../../components/index.js";import X from"../Media/index.js";import{Swiper as Y,SwiperSlide as Z}from"swiper/react";import{Mousewheel as ee}from"swiper/modules";import"swiper/css";import"swiper/css/navigation";import{withLayout as te}from"../../shared/Styles.js";import{useGridRowCount as ie}from"../../hooks/useGridRowCount.js";import{useExposure as oe}from"../../hooks/useExposure.js";import{useViewItemList as ae}from"../../hooks/useViewItemList.js";import{trackUrlRef as re}from"../../shared/trackUrlRef.js";import{useAiuiContext as W}from"../AiuiProvider/index.js";import{gaTrack as H}from"../../shared/track.js";const ne="shelf",se="scene_shelf_v2",le=()=>t("svg",{width:"24",height:"24",viewBox:"0 0 24 24",fill:"none",xmlns:"http://www.w3.org/2000/svg","aria-hidden":"true",children:t("path",{d:"M8 5.14v13.72L19 12 8 5.14z",fill:"white"})}),ce=()=>d("svg",{width:"24",height:"24",viewBox:"0 0 24 24",fill:"none",xmlns:"http://www.w3.org/2000/svg","aria-hidden":"true",children:[t("rect",{x:"6",y:"5",width:"4",height:"14",rx:"1",fill:"white"}),t("rect",{x:"14",y:"5",width:"4",height:"14",rx:"1",fill:"white"})]}),j=a.memo(({product:e,isShowTag:p=!0,onImageClick:m,onProductImageClick:l,onLearnMore:S,onShopNow:P,onAddToCart:k,secondaryButtonText:h,secondaryButtonFun:y,primaryButtonText:b,primaryButtonFun:_,classNames:r,className:n,theme:V,index:s})=>{const{locale:N="us",trackingData:L}=W(),[B,M]=a.useState(!1),[C,z]=a.useState(!1),u=L?.pageGroup,x=a.useCallback(async(c,g)=>{if(!c)return;const T=g==="primary"?M:z;T(!0);try{switch(c){case"buyNow":await P?.(e);break;case"addCart":await k?.(e);break;case"learnMore":await S?.(e?.href??"");break;default:break}}finally{T(!1)}},[S,P,k,e]),I=a.useCallback(()=>x(_,"primary"),[x,_]),R=a.useCallback(()=>x(y,"secondary"),[x,y]),f=a.useCallback(c=>{const g=l??m;!e.href&&g&&c.preventDefault(),g?.(e),H({event:"ga4Event",event_name:"select_item",item_list_name:"Scene_Shelf_2_Products",page_group:u,items:[{item_id:e.sku,item_name:e.custom_name||e.title,item_variant:e.variantId,price:e.currentPrice,index:s}]})},[s,m,l,u,e]);return d("div",{className:o("scene-shelf-v2-product-card rounded-box bg-container-secondary-1 tablet:px-6 desktop:pb-6 desktop:px-6 box-border flex h-full flex-col items-center justify-between gap-3 overflow-hidden px-2 py-4",n,r?.productCard,{"bg-container-secondary-0":V==="dark"}),children:[e.href?t("a",{href:q(re(e.href,u+"_"+ne+"_"+se),N),onClick:f,className:o("scene-shelf-v2-product-card-image desktop:size-[196px] tablet:size-[140px] lg-desktop:size-[196px] flex size-[128px] shrink-0 items-center justify-center transition-opacity hover:opacity-80",r?.productCardImage),"aria-label":`View ${e.title}`,children:t(U,{source:e.imageUrl,alt:e.imageAlt,className:"size-full",imgClassName:"object-contain"})}):t("div",{className:o("scene-shelf-v2-product-card-image desktop:size-[196px] tablet:size-[140px] lg-desktop:size-[196px] flex size-[128px] shrink-0 items-center justify-center ",(l??m)&&"cursor-pointer transition-opacity hover:opacity-80",r?.productCardImage),onClick:l??m?f:void 0,role:l??m?"button":void 0,tabIndex:l??m?0:void 0,"aria-label":l??m?`View ${e.title}`:void 0,children:t(U,{source:e.imageUrl,alt:e.imageAlt,className:"size-full",imgClassName:"object-contain"})}),d("div",{className:"desktop:gap-6 flex w-full flex-1 flex-col justify-between gap-4",children:[d("div",{className:"flex flex-col gap-2",children:[t("div",{className:o("scene-shelf-v2-product-card-tags flex min-h-[24px] flex-wrap gap-1",r?.productCardTags),children:p&&e?.tags?.map((c,g)=>t(J,{variant:c.variant??"outline",size:"sm",className:"",children:c.label},g))}),t(E,{as:"h3",size:2,className:o("scene-shelf-v2-product-card-title text-info-primary laptop:line-clamp-2 line-clamp-3 pr-[16%] text-[16px]",r?.productCardTitle),children:e.custom_name||e.title}),(e.custom_description||e.description)&&t(O,{as:"p",size:1,className:o("scene-shelf-v2-product-card-description text-info-primary tablet:text-[14px] desktop:text-[16px] lg-desktop:text-[18px] line-clamp-1",r?.productCardDescription),children:e.custom_description||e.description})]}),d("div",{className:"flex flex-col gap-2",children:[d("div",{className:o("scene-shelf-v2-product-card-price flex flex-wrap items-center gap-1",r?.productCardPriceWrapper),children:[t(E,{as:"h6",size:2,className:o("scene-shelf-v2-product-card-current-price text-info-primary",r?.productCardCurrentPrice),children:e.currentPrice}),e.originalPrice&&t(E,{as:"h6",size:2,className:o("scene-shelf-v2-product-card-original-price text-info-tertiary line-through",r?.productCardOriginalPrice),children:e.originalPrice})]}),e?.priceLabel&&t(O,{size:4,className:o("text-marketing-1 desktop:text-[16px] lg-desktop:text-[18px] text-[14px]",r?.productCardPriceLabel),children:e.priceLabel}),(h||b)&&d("div",{className:o("scene-shelf-v2-product-card-buttons laptop:flex-nowrap lg-desktop:gap-3 flex flex-wrap gap-2",r?.productCardButtons),children:[h&&t(G,{variant:"secondary",className:"laptop:grow-0 flex-1 whitespace-nowrap",onClick:()=>{R(),H({event:"ga4Event",event_name:"component_click",event_parameters:{page_group:u||"Home Page",component_type:"copy",component_name:"scene_shelf_product",component_title:e.title,component_description:"",button_name:h,SKU:e.sku||"",position:s}})},disabled:e.soldOut&&y!=="learnMore",loading:C,children:h}),b&&t(G,{variant:"primary",className:"laptop:grow-0 flex-1 whitespace-nowrap",onClick:()=>{I(),H({event:"ga4Event",event_name:"component_click",event_parameters:{page_group:u||"Home Page",component_type:"copy",component_name:"scene_shelf_product",component_title:e.title,component_description:"",button_name:b,SKU:e.sku||"",position:s}})},disabled:e.soldOut&&_!=="learnMore",loading:B,children:b})]})]})]})]})});j.displayName="SceneShelfV2.ProductCard";const K=a.forwardRef(({className:e,classNames:p={},data:m,onPlayClick:l,onImageClick:S,onProductImageClick:P,onLearnMore:k,onShopNow:h,onAddToCart:y,...b},_)=>{const{theme:r="light",sceneImage:n,productsTitle:V,products:s,secondaryButtonText:N,secondaryButtonFun:L,primaryButtonText:B,primaryButtonFun:M,viewMoreLimit:C=2,copy:z}=m,u=a.useRef(null),x=a.useRef(null),I=a.useRef(null),[R,f]=a.useState(!1),[c,g]=a.useState(!1),{trackingData:T}=W();oe(x,{componentType:"image",componentName:"scene_shelf_banner"}),ae(I,{componentType:"video",componentName:"scene_shelf_banner",itemListName:"Scene_Shelf_2_Products",items:s.map((i,v)=>({item_id:i.sku??"",item_name:i.title,item_variant:i.variantId??"",price:i.currentPrice,index:v})),tabName:""});const F=ie({rows:C??0,mobileCols:2}),A=a.useMemo(()=>[n?.pc,n?.desktop,n?.laptop,n?.pad,n?.mobile].some(i=>i?.mimeType==="video/mp4"),[n]),$=a.useCallback(()=>{const i=u.current;i?i.paused?(i.play(),f(!0),l?.(!0)):(i.pause(),f(!1),l?.(!1)):l?.(!0),H({event:"ga4Event",event_name:"component_click",event_parameters:{page_group:T?.pageGroup,component_type:"video",component_name:"scene_shelf_banner",position:1,creative_id:n?.pc?.id}})},[l,n?.pc?.id,T?.pageGroup]);return a.useEffect(()=>{const i=u.current;if(!i||!A)return;const v=new IntersectionObserver(w=>{w.forEach(D=>{D.isIntersecting?i.play().catch(Q=>{console.warn("Video autoplay failed:",Q)}):i.pause()})},{threshold:.5});return v.observe(i),()=>{v.disconnect()}},[]),d("div",{...b,ref:_,className:o("scene-shelf-v2-root w-full overflow-hidden",{"aiui-dark":r==="dark"},e,p?.root),children:[d("div",{className:o("scene-shelf-v2-media laptop:h-[360px] tablet:h-[400px] desktop:h-[384px] rounded-box tablet:rounded-t-box tablet:rounded-b-none lg-desktop:h-[480px] relative h-[240px] overflow-hidden",p?.media),ref:x,children:[t(X,{pcImage:n?.pc,desktopImage:n?.desktop,laptopImage:n?.laptop,padImage:n?.pad,mobileImage:n?.mobile,className:"size-full",videoClassName:"absolute inset-0 size-full object-cover",videoRef:u,onVideoPlay:()=>f(!0),onVideoPause:()=>f(!1),onVideoEnded:()=>f(!1)}),t("div",{"aria-hidden":"true",className:o("scene-shelf-v2-media-overlay pointer-events-none absolute inset-0",p?.mediaOverlay)}),A&&t("div",{className:"desktop:gap-16 desktop:p-8 absolute inset-0 flex items-end justify-end gap-4 p-6",children:t("button",{type:"button","aria-label":R?"Pause video":"Play video",onClick:$,className:o("scene-shelf-v2-media-play-button flex size-14 shrink-0 items-center justify-center rounded-full bg-white/20 transition-opacity hover:opacity-80",p?.mediaPlayButton),children:R?t(ce,{}):t(le,{})})})]}),d("div",{ref:I,className:o("scene-shelf-v2-products text-info-primary tablet:bg-container-primary laptop:p-6 desktop:p-8 rounded-b-box tablet:p-4 flex flex-col gap-4 bg-transparent p-0 pt-3",p?.products),children:[V&&t(E,{as:"h2",size:3,className:o("scene-shelf-v2-products-title text-info-primary",p?.productsTitle),html:V}),t("div",{className:"tablet:hidden grid grid-cols-2 gap-3",children:(()=>{const i=C!==void 0&&C>0&&s.length>F,v=i&&!c?s.slice(0,F):s;return d(de,{children:[v.map((w,D)=>t(j,{isShowTag:m.isShowTag??!0,product:w,onImageClick:S,onProductImageClick:P,onLearnMore:k,onShopNow:h,onAddToCart:y,secondaryButtonText:N,secondaryButtonFun:L,primaryButtonText:B,primaryButtonFun:M,classNames:p,theme:r,index:D},w.productKey)),i&&t("div",{className:"col-span-2 mt-6 flex justify-center",children:d("button",{type:"button",onClick:()=>g(w=>!w),className:"text-info-primary hover:text-brand-0 flex items-center gap-2 text-[14px] font-bold transition-colors","aria-expanded":c,children:[c?z?.viewLessLabel??"View Less":z?.viewMoreLabel??"View More",t("svg",{className:o("size-4 transition-transform",c&&"rotate-180"),fill:"none",stroke:"currentColor",viewBox:"0 0 24 24",children:t("path",{strokeLinecap:"round",strokeLinejoin:"round",strokeWidth:2,d:"M19 9l-7 7-7-7"})})]})})]})})()}),t("div",{className:"tablet:block hidden",children:t("div",{className:"relative",children:t(Y,{slidesPerView:"auto",observer:!0,observeParents:!0,modules:[ee],mousewheel:{enabled:!0,forceToAxis:!0,sensitivity:1},className:"!overflow-visible",breakpoints:{768:{spaceBetween:16,slidesPerView:s.length>3?2.3:2},1024:{spaceBetween:16,slidesPerView:s.length>3?2.8:3},1440:{spaceBetween:16,slidesPerView:s.length>4?3.8:4},1920:{spaceBetween:16,slidesPerView:s.length>4?3.8:4}},children:s.map((i,v)=>t(Z,{className:o("!h-auto ",p.productCardSlideWrapper),children:t(j,{product:i,isShowTag:m.isShowTag??!0,onImageClick:S,onProductImageClick:P,onLearnMore:k,onShopNow:h,onAddToCart:y,secondaryButtonText:N,secondaryButtonFun:L,primaryButtonText:B,primaryButtonFun:M,classNames:p,theme:r,index:v})},i.productKey))})})})]})]})});K.displayName="SceneShelfV2";var _e=te(K);export{j as SceneShelfV2ProductCard,_e as default};
2
2
  //# sourceMappingURL=index.js.map
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../../../src/biz-components/SceneShelfV2/index.tsx"],
4
- "sourcesContent": ["'use client'\n\nimport * as React from 'react'\nimport { cn, getLocalizedPath } from '../../helpers/index.js'\nimport { Heading, Text, Badge, Button, Picture } from '../../components/index.js'\nimport Media from '../Media/index.js'\nimport type { ResponsiveMedia, Theme } from '../../types/props.js'\nimport { Swiper, SwiperSlide } from 'swiper/react'\nimport { Mousewheel } from 'swiper/modules'\nimport 'swiper/css'\nimport 'swiper/css/navigation'\nimport { withLayout } from '../../shared/Styles.js'\nimport { useGridRowCount } from '../../hooks/useGridRowCount.js'\nimport { useExposure } from '../../hooks/useExposure.js'\nimport { useViewItemList } from '../../hooks/useViewItemList.js'\nimport { trackUrlRef } from '../../shared/trackUrlRef.js'\nimport { useAiuiContext } from '../AiuiProvider/index.js'\nimport { gaTrack } from '../../shared/track.js'\n\nconst componentType = 'shelf'\nconst componentName = 'scene_shelf_v2'\n\n// \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n// Types\n// \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\n/**\n * \u6309\u94AE\u529F\u80FD\u7C7B\u578B\n */\nexport type ButtonFunctionType = 'buyNow' | 'addCart' | 'learnMore'\n\nexport type SceneShelfV2SemanticName =\n | 'root'\n | 'media'\n | 'mediaOverlay'\n | 'mediaQuote'\n | 'mediaPlayButton'\n | 'products'\n | 'productsTitle'\n | 'productGrid'\n | 'productCardSlideWrapper'\n | 'productCard'\n | 'productCardImage'\n | 'productCardTags'\n | 'productCardTitle'\n | 'productCardDescription'\n | 'productCardPriceWrapper'\n | 'productCardCurrentPrice'\n | 'productCardOriginalPrice'\n | 'productCardButtons'\n\nexport interface SceneShelfV2Tag {\n label: string\n variant?: 'outline' | 'fill'\n}\n\nexport interface SceneShelfV2Product {\n /** \u4EA7\u54C1\u552F\u4E00\u6807\u8BC6 */\n productKey: string\n /** \u4EA7\u54C1\u4E3B\u6807\u9898 */\n title: string\n /** \u4EA7\u54C1\u63CF\u8FF0 */\n description?: string\n /** \u4EA7\u54C1\u56FE\u7247 */\n imageUrl: string\n imageAlt: string\n /**\n * \u4EA7\u54C1\u94FE\u63A5 URL\u3002\n */\n href?: string\n /** \u5F53\u524D\u4EF7\u683C\uFF08\u683C\u5F0F\u5316\u5B57\u7B26\u4E32\uFF0C\u5982 \"$1,999.00\"\uFF09 */\n currentPrice: string\n /** \u539F\u4EF7\uFF08\u663E\u793A\u5220\u9664\u7EBF\uFF09 */\n originalPrice?: string\n /** \u6807\u7B7E\u5217\u8868 */\n tags?: SceneShelfV2Tag[]\n /** \u662F\u5426\u552E\u7F44 */\n soldOut?: boolean\n /**\n * sku\n */\n sku?: string\n /**\n * \u53D8\u4F53id\n */\n variantId?: string\n /** \u81EA\u5B9A\u4E49\u4EA7\u54C1\u540D\u79F0 */\n custom_name?: string\n /** \u81EA\u5B9A\u4E49\u4EA7\u54C1\u63CF\u8FF0 */\n custom_description?: string\n}\n\n/**\n * \u6587\u6848\u914D\u7F6E\n */\nexport interface SceneShelfV2CopyConfig {\n /** \u67E5\u770B\u66F4\u591A\u6807\u7B7E */\n viewMoreLabel?: string\n /** \u6536\u8D77\u6807\u7B7E */\n viewLessLabel?: string\n}\n\nexport interface SceneShelfV2Data {\n theme?: 'light' | 'dark'\n isShowTag?: boolean\n sceneImage: ResponsiveMedia\n /** \u4EA7\u54C1\u533A\u6807\u9898\uFF08\u53EF\u9009\uFF09 */\n productsTitle?: string\n /** \u4EA7\u54C1\u5217\u8868 */\n products: SceneShelfV2Product[]\n /** \u6B21\u8981\u6309\u94AE\u6587\u672C */\n secondaryButtonText?: string\n /** \u6B21\u8981\u6309\u94AE\u529F\u80FD\u7C7B\u578B */\n secondaryButtonFun?: ButtonFunctionType\n /** \u4E3B\u8981\u6309\u94AE\u6587\u672C */\n primaryButtonText?: string\n /** \u4E3B\u8981\u6309\u94AE\u529F\u80FD\u7C7B\u578B */\n primaryButtonFun?: ButtonFunctionType\n /** \u67E5\u770B\u66F4\u591A\u9650\u5236\u6570\uFF08\u624B\u673A\u7AEF\u8D85\u8FC7\u4E24\u884C\u65F6\u663E\u793AviewMore\u6309\u94AE\uFF09 */\n viewMoreLimit?: number\n /** \u6587\u6848\u914D\u7F6E */\n copy?: SceneShelfV2CopyConfig\n}\n\nexport interface SceneShelfV2Props extends React.HTMLAttributes<HTMLDivElement> {\n data: SceneShelfV2Data\n /**\n * \u70B9\u51FB\u64AD\u653E/\u6682\u505C\u6309\u94AE\u56DE\u8C03\u3002\n * \u5F53\u5A92\u4F53\u533A\u4E3A\u89C6\u9891\u65F6\uFF0C\u7EC4\u4EF6\u5185\u90E8\u4F1A\u81EA\u52A8\u63A7\u5236\u64AD\u653E/\u6682\u505C,\u6B64\u56DE\u8C03\u4ECD\u4F1A\u89E6\u53D1\u3002\n */\n onPlayClick?: (isPlaying: boolean) => void\n /** @deprecated Use `onProductImageClick` instead. */\n onImageClick?: (product: SceneShelfV2Product) => void\n /** \u70B9\u51FB\u4EA7\u54C1\u56FE\u7247\u56DE\u8C03 */\n onProductImageClick?: (product: SceneShelfV2Product) => void\n /** \u70B9\u51FB\u4E86\u89E3\u66F4\u591A\u56DE\u8C03\uFF08\u652F\u6301\u5F02\u6B65\uFF09 */\n onLearnMore?: (link: string) => void | Promise<void>\n /** \u70B9\u51FB\u7ACB\u5373\u8D2D\u4E70\u56DE\u8C03\uFF08\u652F\u6301\u5F02\u6B65\uFF09 */\n onShopNow?: (product: SceneShelfV2Product) => void | Promise<void>\n /** \u70B9\u51FB\u52A0\u5165\u8D2D\u7269\u8F66\u56DE\u8C03\uFF08\u652F\u6301\u5F02\u6B65\uFF09 */\n onAddToCart?: (product: SceneShelfV2Product) => void | Promise<void>\n classNames?: Partial<Record<SceneShelfV2SemanticName, string>>\n}\n\n// \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n// Icons\n// \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\nconst PlayIcon = () => (\n <svg width=\"24\" height=\"24\" viewBox=\"0 0 24 24\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\" aria-hidden=\"true\">\n <path d=\"M8 5.14v13.72L19 12 8 5.14z\" fill=\"white\" />\n </svg>\n)\n\nconst PauseIcon = () => (\n <svg width=\"24\" height=\"24\" viewBox=\"0 0 24 24\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\" aria-hidden=\"true\">\n <rect x=\"6\" y=\"5\" width=\"4\" height=\"14\" rx=\"1\" fill=\"white\" />\n <rect x=\"14\" y=\"5\" width=\"4\" height=\"14\" rx=\"1\" fill=\"white\" />\n </svg>\n)\n\n// \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n// Product Card\n// \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\ninterface ProductCardInnerProps {\n product: SceneShelfV2Product\n isShowTag: boolean\n onImageClick?: (product: SceneShelfV2Product) => void\n onProductImageClick?: (product: SceneShelfV2Product) => void\n onLearnMore?: (link: string) => void | Promise<void>\n onShopNow?: (product: SceneShelfV2Product) => void | Promise<void>\n onAddToCart?: (product: SceneShelfV2Product) => void | Promise<void>\n secondaryButtonText?: string\n secondaryButtonFun?: ButtonFunctionType\n primaryButtonText?: string\n primaryButtonFun?: ButtonFunctionType\n classNames?: Partial<Record<SceneShelfV2SemanticName, string>>\n className?: string\n theme?: Theme\n index?: number\n}\n\nconst ProductCardInner = React.memo(\n ({\n product,\n isShowTag = true,\n onImageClick,\n onProductImageClick,\n onLearnMore,\n onShopNow,\n onAddToCart,\n secondaryButtonText,\n secondaryButtonFun,\n primaryButtonText,\n primaryButtonFun,\n classNames,\n className,\n theme,\n index,\n }: ProductCardInnerProps) => {\n const { locale = 'us', trackingData } = useAiuiContext()\n const [primaryLoading, setPrimaryLoading] = React.useState(false)\n const [secondaryLoading, setSecondaryLoading] = React.useState(false)\n\n const pageGroup = trackingData?.pageGroup\n\n // \u6839\u636E\u6309\u94AE\u529F\u80FD\u7C7B\u578B\u8C03\u7528\u76F8\u5E94\u7684\u56DE\u8C03\u51FD\u6570\n const handleButtonClick = React.useCallback(\n async (buttonFun?: ButtonFunctionType, buttonType?: 'primary' | 'secondary') => {\n if (!buttonFun) return\n\n const setLoading = buttonType === 'primary' ? setPrimaryLoading : setSecondaryLoading\n setLoading(true)\n try {\n switch (buttonFun) {\n case 'buyNow':\n await onShopNow?.(product)\n break\n case 'addCart':\n await onAddToCart?.(product)\n break\n case 'learnMore':\n await onLearnMore?.(product?.href ?? '')\n break\n default:\n break\n }\n } finally {\n setLoading(false)\n }\n },\n [onLearnMore, onShopNow, onAddToCart, product]\n )\n\n const handlePrimary = React.useCallback(\n () => handleButtonClick(primaryButtonFun, 'primary'),\n [handleButtonClick, primaryButtonFun]\n )\n const handleSecondary = React.useCallback(\n () => handleButtonClick(secondaryButtonFun, 'secondary'),\n [handleButtonClick, secondaryButtonFun]\n )\n\n const handleImageClick = React.useCallback(\n (e: React.MouseEvent) => {\n const callback = onProductImageClick ?? onImageClick\n if (!product.href && callback) {\n e.preventDefault()\n }\n callback?.(product)\n gaTrack({\n event: 'ga4Event',\n event_name: 'select_item',\n item_list_name: 'Scene_Shelf_2_Products',\n page_group: pageGroup,\n items: [\n {\n item_id: product.sku,\n item_name: product.custom_name || product.title,\n item_variant: product.variantId,\n price: product.currentPrice,\n index: index,\n },\n ],\n })\n },\n [index, onImageClick, onProductImageClick, pageGroup, product]\n )\n\n return (\n <div\n className={cn(\n 'scene-shelf-v2-product-card rounded-box bg-container-secondary-1 tablet:px-6 desktop:pb-6 desktop:px-6 box-border flex h-full flex-col items-center justify-between gap-3 overflow-hidden px-2 py-4',\n className,\n classNames?.productCard,\n {\n 'bg-container-secondary-0': theme === 'dark',\n }\n )}\n >\n {/* \u4EA7\u54C1\u56FE\u7247 */}\n {product.href ? (\n <a\n href={getLocalizedPath(\n trackUrlRef(product.href, pageGroup + '_' + componentType + '_' + componentName),\n locale\n )}\n onClick={handleImageClick}\n className={cn(\n 'scene-shelf-v2-product-card-image desktop:size-[196px] tablet:size-[140px] lg-desktop:size-[196px] flex size-[128px] shrink-0 items-center justify-center transition-opacity hover:opacity-80',\n classNames?.productCardImage\n )}\n aria-label={`View ${product.title}`}\n >\n <Picture\n source={product.imageUrl}\n alt={product.imageAlt}\n className=\"size-full\"\n imgClassName=\"object-contain\"\n />\n </a>\n ) : (\n <div\n className={cn(\n 'scene-shelf-v2-product-card-image desktop:size-[196px] tablet:size-[140px] lg-desktop:size-[196px] flex size-[128px] shrink-0 items-center justify-center ',\n (onProductImageClick ?? onImageClick) && 'cursor-pointer transition-opacity hover:opacity-80',\n classNames?.productCardImage\n )}\n onClick={(onProductImageClick ?? onImageClick) ? handleImageClick : undefined}\n role={(onProductImageClick ?? onImageClick) ? 'button' : undefined}\n tabIndex={(onProductImageClick ?? onImageClick) ? 0 : undefined}\n aria-label={(onProductImageClick ?? onImageClick) ? `View ${product.title}` : undefined}\n >\n <Picture\n source={product.imageUrl}\n alt={product.imageAlt}\n className=\"size-full\"\n imgClassName=\"object-contain\"\n />\n </div>\n )}\n\n {/* \u4EA7\u54C1\u4FE1\u606F */}\n <div className=\"desktop:gap-6 flex w-full flex-1 flex-col justify-between gap-4\">\n {/* \u6807\u7B7E + \u6807\u9898 + \u526F\u6807\u9898 */}\n <div className=\"flex flex-col gap-2\">\n <div\n className={cn(\n 'scene-shelf-v2-product-card-tags flex min-h-[24px] flex-wrap gap-1',\n classNames?.productCardTags\n )}\n >\n {isShowTag &&\n product?.tags?.map((tag, idx) => (\n <Badge key={idx} variant={tag.variant ?? 'outline'} size=\"sm\" className=\"\">\n {tag.label}\n </Badge>\n ))}\n </div>\n\n <Heading\n as=\"h3\"\n size={2}\n className={cn(\n 'scene-shelf-v2-product-card-title text-info-primary laptop:line-clamp-2 line-clamp-3 pr-[16%] text-[16px]',\n classNames?.productCardTitle\n )}\n >\n {product.custom_name || product.title}\n </Heading>\n\n {(product.custom_description || product.description) && (\n <Text\n as=\"p\"\n size={1}\n className={cn(\n 'scene-shelf-v2-product-card-description text-info-primary tablet:text-[14px] desktop:text-[16px] lg-desktop:text-[18px] line-clamp-1',\n classNames?.productCardDescription\n )}\n >\n {product.custom_description || product.description}\n </Text>\n )}\n </div>\n\n {/* \u4EF7\u683C + \u6309\u94AE */}\n <div className=\"flex flex-col gap-2\">\n {/* \u4EF7\u683C */}\n <div\n className={cn(\n 'scene-shelf-v2-product-card-price flex flex-wrap items-center gap-1',\n classNames?.productCardPriceWrapper\n )}\n >\n <Heading\n as=\"h6\"\n size={2}\n className={cn(\n 'scene-shelf-v2-product-card-current-price text-info-primary',\n classNames?.productCardCurrentPrice\n )}\n >\n {product.currentPrice}\n </Heading>\n {product.originalPrice && (\n <Heading\n as=\"h6\"\n size={2}\n className={cn(\n 'scene-shelf-v2-product-card-original-price text-info-tertiary line-through',\n classNames?.productCardOriginalPrice\n )}\n >\n {product.originalPrice}\n </Heading>\n )}\n </div>\n\n {/* \u6309\u94AE\u7EC4 */}\n {(secondaryButtonText || primaryButtonText) && (\n <div\n className={cn(\n 'scene-shelf-v2-product-card-buttons laptop:flex-nowrap lg-desktop:gap-3 flex flex-wrap gap-2',\n classNames?.productCardButtons\n )}\n >\n {secondaryButtonText && (\n <Button\n variant=\"secondary\"\n className=\"laptop:grow-0 flex-1 whitespace-nowrap\"\n onClick={() => {\n handleSecondary()\n gaTrack({\n event: 'ga4Event',\n event_name: 'component_click',\n event_parameters: {\n page_group: pageGroup || 'Home Page',\n component_type: 'copy',\n component_name: 'scene_shelf_product',\n component_title: product.title,\n component_description: '',\n button_name: secondaryButtonText,\n SKU: product.sku || '',\n position: index,\n },\n })\n }}\n disabled={product.soldOut && secondaryButtonFun !== 'learnMore'}\n loading={secondaryLoading}\n >\n {secondaryButtonText}\n </Button>\n )}\n {primaryButtonText && (\n <Button\n variant=\"primary\"\n className=\"laptop:grow-0 flex-1 whitespace-nowrap\"\n onClick={() => {\n handlePrimary()\n gaTrack({\n event: 'ga4Event',\n event_name: 'component_click',\n event_parameters: {\n page_group: pageGroup || 'Home Page',\n component_type: 'copy',\n component_name: 'scene_shelf_product',\n component_title: product.title,\n component_description: '',\n button_name: primaryButtonText,\n SKU: product.sku || '',\n position: index,\n },\n })\n }}\n disabled={product.soldOut && primaryButtonFun !== 'learnMore'}\n loading={primaryLoading}\n >\n {primaryButtonText}\n </Button>\n )}\n </div>\n )}\n </div>\n </div>\n </div>\n )\n }\n)\n\nProductCardInner.displayName = 'SceneShelfV2.ProductCard'\n\n// \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n// Main Component\n// \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\nconst SceneShelfV2 = React.forwardRef<HTMLDivElement, SceneShelfV2Props>(\n (\n {\n className,\n classNames = {},\n data,\n onPlayClick,\n onImageClick,\n onProductImageClick,\n onLearnMore,\n onShopNow,\n onAddToCart,\n ...props\n },\n ref\n ) => {\n const {\n theme = 'light',\n sceneImage,\n productsTitle,\n products,\n secondaryButtonText,\n secondaryButtonFun,\n primaryButtonText,\n primaryButtonFun,\n viewMoreLimit = 2,\n copy,\n } = data\n const videoRef = React.useRef<HTMLVideoElement>(null)\n const mediaRef = React.useRef<HTMLDivElement>(null)\n const productWrapperRef = React.useRef<HTMLDivElement>(null)\n const [isPlaying, setIsPlaying] = React.useState(false)\n const [isExpanded, setIsExpanded] = React.useState(false)\n const { trackingData } = useAiuiContext()\n\n useExposure(mediaRef, {\n componentType: 'image',\n componentName: 'scene_shelf_banner',\n })\n\n useViewItemList(productWrapperRef, {\n componentType: 'video',\n componentName: 'scene_shelf_banner',\n itemListName: 'Scene_Shelf_2_Products',\n items: products.map((item, index) => ({\n item_id: item.sku ?? '',\n item_name: item.title,\n item_variant: item.variantId ?? '',\n price: item.currentPrice,\n index: index,\n })),\n tabName: '',\n })\n\n const visibleLimit = useGridRowCount({\n rows: viewMoreLimit ?? 0,\n mobileCols: 2,\n })\n\n const hasVideo = React.useMemo(\n () =>\n [sceneImage?.pc, sceneImage?.desktop, sceneImage?.laptop, sceneImage?.pad, sceneImage?.mobile].some(\n media => media?.mimeType === 'video/mp4'\n ),\n [sceneImage]\n )\n\n const handlePlayButtonClick = React.useCallback(() => {\n const video = videoRef.current\n if (video) {\n if (video.paused) {\n video.play()\n setIsPlaying(true)\n onPlayClick?.(true)\n } else {\n video.pause()\n setIsPlaying(false)\n onPlayClick?.(false)\n }\n } else {\n onPlayClick?.(true)\n }\n gaTrack({\n event: 'ga4Event',\n event_name: 'component_click',\n event_parameters: {\n page_group: trackingData?.pageGroup,\n component_type: 'video',\n component_name: 'scene_shelf_banner',\n position: 1,\n creative_id: sceneImage?.pc?.id,\n },\n })\n }, [onPlayClick, sceneImage?.pc?.id, trackingData?.pageGroup])\n\n // \u8FDB\u5165\u89C6\u7A97\u81EA\u52A8\u64AD\u653E\n React.useEffect(() => {\n const video = videoRef.current\n if (!video || !hasVideo) return\n\n const observer = new IntersectionObserver(\n entries => {\n entries.forEach(entry => {\n if (entry.isIntersecting) {\n // \u8FDB\u5165\u89C6\u7A97\uFF0C\u81EA\u52A8\u64AD\u653E\n video.play().catch(error => {\n // \u5904\u7406\u81EA\u52A8\u64AD\u653E\u5931\u8D25\uFF08\u6D4F\u89C8\u5668\u7B56\u7565\u53EF\u80FD\u963B\u6B62\u81EA\u52A8\u64AD\u653E\uFF09\n console.warn('Video autoplay failed:', error)\n })\n } else {\n // \u79BB\u5F00\u89C6\u7A97\uFF0C\u6682\u505C\u64AD\u653E\n video.pause()\n }\n })\n },\n {\n threshold: 0.5, // \u5F53\u89C6\u9891 50% \u53EF\u89C1\u65F6\u89E6\u53D1\n }\n )\n\n observer.observe(video)\n\n return () => {\n observer.disconnect()\n }\n }, [])\n\n return (\n <div\n {...props}\n ref={ref}\n className={cn(\n 'scene-shelf-v2-root w-full overflow-hidden',\n { 'aiui-dark': theme === 'dark' },\n className,\n classNames?.root\n )}\n >\n {/* \u2500\u2500 \u5A92\u4F53\u533A \u2500\u2500 */}\n <div\n className={cn(\n 'scene-shelf-v2-media laptop:h-[360px] tablet:h-[400px] desktop:h-[384px] rounded-box tablet:rounded-t-box tablet:rounded-b-none lg-desktop:h-[480px] relative h-[240px] overflow-hidden',\n classNames?.media\n )}\n ref={mediaRef}\n >\n <Media\n pcImage={sceneImage?.pc}\n desktopImage={sceneImage?.desktop}\n laptopImage={sceneImage?.laptop}\n padImage={sceneImage?.pad}\n mobileImage={sceneImage?.mobile}\n className=\"size-full\"\n videoClassName=\"absolute inset-0 size-full object-cover\"\n videoRef={videoRef}\n onVideoPlay={() => setIsPlaying(true)}\n onVideoPause={() => setIsPlaying(false)}\n onVideoEnded={() => setIsPlaying(false)}\n />\n {/* \u6E10\u53D8\u906E\u7F69 */}\n <div\n aria-hidden=\"true\"\n className={cn(\n 'scene-shelf-v2-media-overlay pointer-events-none absolute inset-0',\n classNames?.mediaOverlay\n )}\n />\n\n {/* \u5F15\u8A00 + \u64AD\u653E/\u6682\u505C\u6309\u94AE */}\n {hasVideo && (\n <div className=\"desktop:gap-16 desktop:p-8 absolute inset-0 flex items-end justify-end gap-4 p-6\">\n <button\n type=\"button\"\n aria-label={isPlaying ? 'Pause video' : 'Play video'}\n onClick={handlePlayButtonClick}\n className={cn(\n 'scene-shelf-v2-media-play-button flex size-14 shrink-0 items-center justify-center rounded-full bg-white/20 transition-opacity hover:opacity-80',\n classNames?.mediaPlayButton\n )}\n >\n {isPlaying ? <PauseIcon /> : <PlayIcon />}\n </button>\n </div>\n )}\n </div>\n\n {/* \u2500\u2500 \u4EA7\u54C1\u533A \u2500\u2500 */}\n <div\n ref={productWrapperRef}\n className={cn(\n 'scene-shelf-v2-products text-info-primary tablet:bg-container-primary laptop:p-6 desktop:p-8 rounded-b-box tablet:p-4 flex flex-col gap-4 bg-transparent p-0 pt-3',\n classNames?.products\n )}\n >\n {productsTitle && (\n <Heading\n as=\"h2\"\n size={3}\n className={cn('scene-shelf-v2-products-title text-info-primary', classNames?.productsTitle)}\n html={productsTitle}\n />\n )}\n\n {/* Mobile\uFF1A2\u5217\u5E73\u94FA */}\n <div className=\"tablet:hidden grid grid-cols-2 gap-3\">\n {(() => {\n const shouldShowViewMore =\n viewMoreLimit !== undefined && viewMoreLimit > 0 && products.length > visibleLimit\n const displayedProducts = shouldShowViewMore && !isExpanded ? products.slice(0, visibleLimit) : products\n\n return (\n <>\n {displayedProducts.map((product, index) => (\n <ProductCardInner\n key={product.productKey}\n isShowTag={data.isShowTag ?? true}\n product={product}\n onImageClick={onImageClick}\n onProductImageClick={onProductImageClick}\n onLearnMore={onLearnMore}\n onShopNow={onShopNow}\n onAddToCart={onAddToCart}\n secondaryButtonText={secondaryButtonText}\n secondaryButtonFun={secondaryButtonFun}\n primaryButtonText={primaryButtonText}\n primaryButtonFun={primaryButtonFun}\n classNames={classNames}\n theme={theme}\n index={index}\n />\n ))}\n {shouldShowViewMore && (\n <div className=\"col-span-2 mt-6 flex justify-center\">\n <button\n type=\"button\"\n onClick={() => setIsExpanded(prev => !prev)}\n className=\"text-info-primary hover:text-brand-0 flex items-center gap-2 text-[14px] font-bold transition-colors\"\n aria-expanded={isExpanded}\n >\n {isExpanded ? (copy?.viewLessLabel ?? 'View Less') : (copy?.viewMoreLabel ?? 'View More')}\n <svg\n className={cn('size-4 transition-transform', isExpanded && 'rotate-180')}\n fill=\"none\"\n stroke=\"currentColor\"\n viewBox=\"0 0 24 24\"\n >\n <path strokeLinecap=\"round\" strokeLinejoin=\"round\" strokeWidth={2} d=\"M19 9l-7 7-7-7\" />\n </svg>\n </button>\n </div>\n )}\n </>\n )\n })()}\n </div>\n\n {/* Tablet\uFF1ASwiper \u6A2A\u6ED1 */}\n <div className=\"tablet:block hidden\">\n <div className=\"relative\">\n <Swiper\n slidesPerView=\"auto\"\n observer\n observeParents\n modules={[Mousewheel]}\n mousewheel={{\n enabled: true,\n forceToAxis: true,\n sensitivity: 1,\n }}\n className=\"!overflow-visible\"\n breakpoints={{\n 768: {\n spaceBetween: 16,\n slidesPerView: products.length > 3 ? 2.3 : 2,\n },\n 1024: {\n spaceBetween: 16,\n slidesPerView: products.length > 3 ? 2.8 : 3,\n },\n 1440: {\n spaceBetween: 16,\n slidesPerView: products.length > 4 ? 3.8 : 4,\n },\n 1920: {\n spaceBetween: 16,\n slidesPerView: products.length > 4 ? 3.8 : 4,\n },\n }}\n >\n {products.map((product, index) => (\n <SwiperSlide key={product.productKey} className={cn('!h-auto ', classNames.productCardSlideWrapper)}>\n <ProductCardInner\n product={product}\n isShowTag={data.isShowTag ?? true}\n onImageClick={onImageClick}\n onProductImageClick={onProductImageClick}\n onLearnMore={onLearnMore}\n onShopNow={onShopNow}\n onAddToCart={onAddToCart}\n secondaryButtonText={secondaryButtonText}\n secondaryButtonFun={secondaryButtonFun}\n primaryButtonText={primaryButtonText}\n primaryButtonFun={primaryButtonFun}\n classNames={classNames}\n theme={theme}\n index={index}\n />\n </SwiperSlide>\n ))}\n </Swiper>\n </div>\n </div>\n </div>\n </div>\n )\n }\n)\n\nSceneShelfV2.displayName = 'SceneShelfV2'\nexport default withLayout(SceneShelfV2)\nexport { ProductCardInner as SceneShelfV2ProductCard }\n"],
5
- "mappings": "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",
4
+ "sourcesContent": ["'use client'\n\nimport * as React from 'react'\nimport { cn, getLocalizedPath } from '../../helpers/index.js'\nimport { Heading, Text, Badge, Button, Picture } from '../../components/index.js'\nimport Media from '../Media/index.js'\nimport type { ResponsiveMedia, Theme } from '../../types/props.js'\nimport { Swiper, SwiperSlide } from 'swiper/react'\nimport { Mousewheel } from 'swiper/modules'\nimport 'swiper/css'\nimport 'swiper/css/navigation'\nimport { withLayout } from '../../shared/Styles.js'\nimport { useGridRowCount } from '../../hooks/useGridRowCount.js'\nimport { useExposure } from '../../hooks/useExposure.js'\nimport { useViewItemList } from '../../hooks/useViewItemList.js'\nimport { trackUrlRef } from '../../shared/trackUrlRef.js'\nimport { useAiuiContext } from '../AiuiProvider/index.js'\nimport { gaTrack } from '../../shared/track.js'\n\nconst componentType = 'shelf'\nconst componentName = 'scene_shelf_v2'\n\n// \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n// Types\n// \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\n/**\n * \u6309\u94AE\u529F\u80FD\u7C7B\u578B\n */\nexport type ButtonFunctionType = 'buyNow' | 'addCart' | 'learnMore'\n\nexport type SceneShelfV2SemanticName =\n | 'root'\n | 'media'\n | 'mediaOverlay'\n | 'mediaQuote'\n | 'mediaPlayButton'\n | 'products'\n | 'productsTitle'\n | 'productGrid'\n | 'productCardSlideWrapper'\n | 'productCard'\n | 'productCardImage'\n | 'productCardTags'\n | 'productCardTitle'\n | 'productCardDescription'\n | 'productCardPriceWrapper'\n | 'productCardCurrentPrice'\n | 'productCardOriginalPrice'\n | 'productCardPriceLabel'\n | 'productCardButtons'\n\nexport interface SceneShelfV2Tag {\n label: string\n variant?: 'outline' | 'fill'\n}\n\nexport interface SceneShelfV2Product {\n /** \u4EA7\u54C1\u552F\u4E00\u6807\u8BC6 */\n productKey: string\n /** \u4EA7\u54C1\u4E3B\u6807\u9898 */\n title: string\n /** \u4EA7\u54C1\u63CF\u8FF0 */\n description?: string\n /** \u4EA7\u54C1\u56FE\u7247 */\n imageUrl: string\n imageAlt: string\n /**\n * \u4EA7\u54C1\u94FE\u63A5 URL\u3002\n */\n href?: string\n /** \u5F53\u524D\u4EF7\u683C\uFF08\u683C\u5F0F\u5316\u5B57\u7B26\u4E32\uFF0C\u5982 \"$1,999.00\"\uFF09 */\n currentPrice: string\n /** \u539F\u4EF7\uFF08\u663E\u793A\u5220\u9664\u7EBF\uFF09 */\n originalPrice?: string\n /** \u6807\u7B7E\u5217\u8868 */\n tags?: SceneShelfV2Tag[]\n /** \u662F\u5426\u552E\u7F44 */\n soldOut?: boolean\n /**\n * sku\n */\n sku?: string\n /**\n * \u53D8\u4F53id\n */\n variantId?: string\n /** \u81EA\u5B9A\u4E49\u4EA7\u54C1\u540D\u79F0 */\n custom_name?: string\n /** \u81EA\u5B9A\u4E49\u4EA7\u54C1\u63CF\u8FF0 */\n custom_description?: string\n /** \u4EF7\u683C\u6807\u7B7E\u6587\u672C\uFF08\u5982 \"Plus Member Price\"\uFF09 */\n priceLabel?: string\n}\n\n/**\n * \u6587\u6848\u914D\u7F6E\n */\nexport interface SceneShelfV2CopyConfig {\n /** \u67E5\u770B\u66F4\u591A\u6807\u7B7E */\n viewMoreLabel?: string\n /** \u6536\u8D77\u6807\u7B7E */\n viewLessLabel?: string\n}\n\nexport interface SceneShelfV2Data {\n theme?: 'light' | 'dark'\n isShowTag?: boolean\n sceneImage: ResponsiveMedia\n /** \u4EA7\u54C1\u533A\u6807\u9898\uFF08\u53EF\u9009\uFF09 */\n productsTitle?: string\n /** \u4EA7\u54C1\u5217\u8868 */\n products: SceneShelfV2Product[]\n /** \u6B21\u8981\u6309\u94AE\u6587\u672C */\n secondaryButtonText?: string\n /** \u6B21\u8981\u6309\u94AE\u529F\u80FD\u7C7B\u578B */\n secondaryButtonFun?: ButtonFunctionType\n /** \u4E3B\u8981\u6309\u94AE\u6587\u672C */\n primaryButtonText?: string\n /** \u4E3B\u8981\u6309\u94AE\u529F\u80FD\u7C7B\u578B */\n primaryButtonFun?: ButtonFunctionType\n /** \u67E5\u770B\u66F4\u591A\u9650\u5236\u6570\uFF08\u624B\u673A\u7AEF\u8D85\u8FC7\u4E24\u884C\u65F6\u663E\u793AviewMore\u6309\u94AE\uFF09 */\n viewMoreLimit?: number\n /** \u6587\u6848\u914D\u7F6E */\n copy?: SceneShelfV2CopyConfig\n}\n\nexport interface SceneShelfV2Props extends React.HTMLAttributes<HTMLDivElement> {\n data: SceneShelfV2Data\n /**\n * \u70B9\u51FB\u64AD\u653E/\u6682\u505C\u6309\u94AE\u56DE\u8C03\u3002\n * \u5F53\u5A92\u4F53\u533A\u4E3A\u89C6\u9891\u65F6\uFF0C\u7EC4\u4EF6\u5185\u90E8\u4F1A\u81EA\u52A8\u63A7\u5236\u64AD\u653E/\u6682\u505C,\u6B64\u56DE\u8C03\u4ECD\u4F1A\u89E6\u53D1\u3002\n */\n onPlayClick?: (isPlaying: boolean) => void\n /** @deprecated Use `onProductImageClick` instead. */\n onImageClick?: (product: SceneShelfV2Product) => void\n /** \u70B9\u51FB\u4EA7\u54C1\u56FE\u7247\u56DE\u8C03 */\n onProductImageClick?: (product: SceneShelfV2Product) => void\n /** \u70B9\u51FB\u4E86\u89E3\u66F4\u591A\u56DE\u8C03\uFF08\u652F\u6301\u5F02\u6B65\uFF09 */\n onLearnMore?: (link: string) => void | Promise<void>\n /** \u70B9\u51FB\u7ACB\u5373\u8D2D\u4E70\u56DE\u8C03\uFF08\u652F\u6301\u5F02\u6B65\uFF09 */\n onShopNow?: (product: SceneShelfV2Product) => void | Promise<void>\n /** \u70B9\u51FB\u52A0\u5165\u8D2D\u7269\u8F66\u56DE\u8C03\uFF08\u652F\u6301\u5F02\u6B65\uFF09 */\n onAddToCart?: (product: SceneShelfV2Product) => void | Promise<void>\n classNames?: Partial<Record<SceneShelfV2SemanticName, string>>\n}\n\n// \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n// Icons\n// \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\nconst PlayIcon = () => (\n <svg width=\"24\" height=\"24\" viewBox=\"0 0 24 24\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\" aria-hidden=\"true\">\n <path d=\"M8 5.14v13.72L19 12 8 5.14z\" fill=\"white\" />\n </svg>\n)\n\nconst PauseIcon = () => (\n <svg width=\"24\" height=\"24\" viewBox=\"0 0 24 24\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\" aria-hidden=\"true\">\n <rect x=\"6\" y=\"5\" width=\"4\" height=\"14\" rx=\"1\" fill=\"white\" />\n <rect x=\"14\" y=\"5\" width=\"4\" height=\"14\" rx=\"1\" fill=\"white\" />\n </svg>\n)\n\n// \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n// Product Card\n// \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\ninterface ProductCardInnerProps {\n product: SceneShelfV2Product\n isShowTag: boolean\n onImageClick?: (product: SceneShelfV2Product) => void\n onProductImageClick?: (product: SceneShelfV2Product) => void\n onLearnMore?: (link: string) => void | Promise<void>\n onShopNow?: (product: SceneShelfV2Product) => void | Promise<void>\n onAddToCart?: (product: SceneShelfV2Product) => void | Promise<void>\n secondaryButtonText?: string\n secondaryButtonFun?: ButtonFunctionType\n primaryButtonText?: string\n primaryButtonFun?: ButtonFunctionType\n classNames?: Partial<Record<SceneShelfV2SemanticName, string>>\n className?: string\n theme?: Theme\n index?: number\n}\n\nconst ProductCardInner = React.memo(\n ({\n product,\n isShowTag = true,\n onImageClick,\n onProductImageClick,\n onLearnMore,\n onShopNow,\n onAddToCart,\n secondaryButtonText,\n secondaryButtonFun,\n primaryButtonText,\n primaryButtonFun,\n classNames,\n className,\n theme,\n index,\n }: ProductCardInnerProps) => {\n const { locale = 'us', trackingData } = useAiuiContext()\n const [primaryLoading, setPrimaryLoading] = React.useState(false)\n const [secondaryLoading, setSecondaryLoading] = React.useState(false)\n\n const pageGroup = trackingData?.pageGroup\n\n // \u6839\u636E\u6309\u94AE\u529F\u80FD\u7C7B\u578B\u8C03\u7528\u76F8\u5E94\u7684\u56DE\u8C03\u51FD\u6570\n const handleButtonClick = React.useCallback(\n async (buttonFun?: ButtonFunctionType, buttonType?: 'primary' | 'secondary') => {\n if (!buttonFun) return\n\n const setLoading = buttonType === 'primary' ? setPrimaryLoading : setSecondaryLoading\n setLoading(true)\n try {\n switch (buttonFun) {\n case 'buyNow':\n await onShopNow?.(product)\n break\n case 'addCart':\n await onAddToCart?.(product)\n break\n case 'learnMore':\n await onLearnMore?.(product?.href ?? '')\n break\n default:\n break\n }\n } finally {\n setLoading(false)\n }\n },\n [onLearnMore, onShopNow, onAddToCart, product]\n )\n\n const handlePrimary = React.useCallback(\n () => handleButtonClick(primaryButtonFun, 'primary'),\n [handleButtonClick, primaryButtonFun]\n )\n const handleSecondary = React.useCallback(\n () => handleButtonClick(secondaryButtonFun, 'secondary'),\n [handleButtonClick, secondaryButtonFun]\n )\n\n const handleImageClick = React.useCallback(\n (e: React.MouseEvent) => {\n const callback = onProductImageClick ?? onImageClick\n if (!product.href && callback) {\n e.preventDefault()\n }\n callback?.(product)\n gaTrack({\n event: 'ga4Event',\n event_name: 'select_item',\n item_list_name: 'Scene_Shelf_2_Products',\n page_group: pageGroup,\n items: [\n {\n item_id: product.sku,\n item_name: product.custom_name || product.title,\n item_variant: product.variantId,\n price: product.currentPrice,\n index: index,\n },\n ],\n })\n },\n [index, onImageClick, onProductImageClick, pageGroup, product]\n )\n\n return (\n <div\n className={cn(\n 'scene-shelf-v2-product-card rounded-box bg-container-secondary-1 tablet:px-6 desktop:pb-6 desktop:px-6 box-border flex h-full flex-col items-center justify-between gap-3 overflow-hidden px-2 py-4',\n className,\n classNames?.productCard,\n {\n 'bg-container-secondary-0': theme === 'dark',\n }\n )}\n >\n {/* \u4EA7\u54C1\u56FE\u7247 */}\n {product.href ? (\n <a\n href={getLocalizedPath(\n trackUrlRef(product.href, pageGroup + '_' + componentType + '_' + componentName),\n locale\n )}\n onClick={handleImageClick}\n className={cn(\n 'scene-shelf-v2-product-card-image desktop:size-[196px] tablet:size-[140px] lg-desktop:size-[196px] flex size-[128px] shrink-0 items-center justify-center transition-opacity hover:opacity-80',\n classNames?.productCardImage\n )}\n aria-label={`View ${product.title}`}\n >\n <Picture\n source={product.imageUrl}\n alt={product.imageAlt}\n className=\"size-full\"\n imgClassName=\"object-contain\"\n />\n </a>\n ) : (\n <div\n className={cn(\n 'scene-shelf-v2-product-card-image desktop:size-[196px] tablet:size-[140px] lg-desktop:size-[196px] flex size-[128px] shrink-0 items-center justify-center ',\n (onProductImageClick ?? onImageClick) && 'cursor-pointer transition-opacity hover:opacity-80',\n classNames?.productCardImage\n )}\n onClick={(onProductImageClick ?? onImageClick) ? handleImageClick : undefined}\n role={(onProductImageClick ?? onImageClick) ? 'button' : undefined}\n tabIndex={(onProductImageClick ?? onImageClick) ? 0 : undefined}\n aria-label={(onProductImageClick ?? onImageClick) ? `View ${product.title}` : undefined}\n >\n <Picture\n source={product.imageUrl}\n alt={product.imageAlt}\n className=\"size-full\"\n imgClassName=\"object-contain\"\n />\n </div>\n )}\n\n {/* \u4EA7\u54C1\u4FE1\u606F */}\n <div className=\"desktop:gap-6 flex w-full flex-1 flex-col justify-between gap-4\">\n {/* \u6807\u7B7E + \u6807\u9898 + \u526F\u6807\u9898 */}\n <div className=\"flex flex-col gap-2\">\n <div\n className={cn(\n 'scene-shelf-v2-product-card-tags flex min-h-[24px] flex-wrap gap-1',\n classNames?.productCardTags\n )}\n >\n {isShowTag &&\n product?.tags?.map((tag, idx) => (\n <Badge key={idx} variant={tag.variant ?? 'outline'} size=\"sm\" className=\"\">\n {tag.label}\n </Badge>\n ))}\n </div>\n\n <Heading\n as=\"h3\"\n size={2}\n className={cn(\n 'scene-shelf-v2-product-card-title text-info-primary laptop:line-clamp-2 line-clamp-3 pr-[16%] text-[16px]',\n classNames?.productCardTitle\n )}\n >\n {product.custom_name || product.title}\n </Heading>\n\n {(product.custom_description || product.description) && (\n <Text\n as=\"p\"\n size={1}\n className={cn(\n 'scene-shelf-v2-product-card-description text-info-primary tablet:text-[14px] desktop:text-[16px] lg-desktop:text-[18px] line-clamp-1',\n classNames?.productCardDescription\n )}\n >\n {product.custom_description || product.description}\n </Text>\n )}\n </div>\n\n {/* \u4EF7\u683C + \u6309\u94AE */}\n <div className=\"flex flex-col gap-2\">\n {/* \u4EF7\u683C */}\n <div\n className={cn(\n 'scene-shelf-v2-product-card-price flex flex-wrap items-center gap-1',\n classNames?.productCardPriceWrapper\n )}\n >\n <Heading\n as=\"h6\"\n size={2}\n className={cn(\n 'scene-shelf-v2-product-card-current-price text-info-primary',\n classNames?.productCardCurrentPrice\n )}\n >\n {product.currentPrice}\n </Heading>\n {product.originalPrice && (\n <Heading\n as=\"h6\"\n size={2}\n className={cn(\n 'scene-shelf-v2-product-card-original-price text-info-tertiary line-through',\n classNames?.productCardOriginalPrice\n )}\n >\n {product.originalPrice}\n </Heading>\n )}\n </div>\n\n {product?.priceLabel && (\n <Text\n size={4}\n className={cn(\n 'text-marketing-1 desktop:text-[16px] lg-desktop:text-[18px] text-[14px]',\n classNames?.productCardPriceLabel\n )}\n >\n {product.priceLabel}\n </Text>\n )}\n\n {/* \u6309\u94AE\u7EC4 */}\n {(secondaryButtonText || primaryButtonText) && (\n <div\n className={cn(\n 'scene-shelf-v2-product-card-buttons laptop:flex-nowrap lg-desktop:gap-3 flex flex-wrap gap-2',\n classNames?.productCardButtons\n )}\n >\n {secondaryButtonText && (\n <Button\n variant=\"secondary\"\n className=\"laptop:grow-0 flex-1 whitespace-nowrap\"\n onClick={() => {\n handleSecondary()\n gaTrack({\n event: 'ga4Event',\n event_name: 'component_click',\n event_parameters: {\n page_group: pageGroup || 'Home Page',\n component_type: 'copy',\n component_name: 'scene_shelf_product',\n component_title: product.title,\n component_description: '',\n button_name: secondaryButtonText,\n SKU: product.sku || '',\n position: index,\n },\n })\n }}\n disabled={product.soldOut && secondaryButtonFun !== 'learnMore'}\n loading={secondaryLoading}\n >\n {secondaryButtonText}\n </Button>\n )}\n {primaryButtonText && (\n <Button\n variant=\"primary\"\n className=\"laptop:grow-0 flex-1 whitespace-nowrap\"\n onClick={() => {\n handlePrimary()\n gaTrack({\n event: 'ga4Event',\n event_name: 'component_click',\n event_parameters: {\n page_group: pageGroup || 'Home Page',\n component_type: 'copy',\n component_name: 'scene_shelf_product',\n component_title: product.title,\n component_description: '',\n button_name: primaryButtonText,\n SKU: product.sku || '',\n position: index,\n },\n })\n }}\n disabled={product.soldOut && primaryButtonFun !== 'learnMore'}\n loading={primaryLoading}\n >\n {primaryButtonText}\n </Button>\n )}\n </div>\n )}\n </div>\n </div>\n </div>\n )\n }\n)\n\nProductCardInner.displayName = 'SceneShelfV2.ProductCard'\n\n// \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n// Main Component\n// \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\nconst SceneShelfV2 = React.forwardRef<HTMLDivElement, SceneShelfV2Props>(\n (\n {\n className,\n classNames = {},\n data,\n onPlayClick,\n onImageClick,\n onProductImageClick,\n onLearnMore,\n onShopNow,\n onAddToCart,\n ...props\n },\n ref\n ) => {\n const {\n theme = 'light',\n sceneImage,\n productsTitle,\n products,\n secondaryButtonText,\n secondaryButtonFun,\n primaryButtonText,\n primaryButtonFun,\n viewMoreLimit = 2,\n copy,\n } = data\n const videoRef = React.useRef<HTMLVideoElement>(null)\n const mediaRef = React.useRef<HTMLDivElement>(null)\n const productWrapperRef = React.useRef<HTMLDivElement>(null)\n const [isPlaying, setIsPlaying] = React.useState(false)\n const [isExpanded, setIsExpanded] = React.useState(false)\n const { trackingData } = useAiuiContext()\n\n useExposure(mediaRef, {\n componentType: 'image',\n componentName: 'scene_shelf_banner',\n })\n\n useViewItemList(productWrapperRef, {\n componentType: 'video',\n componentName: 'scene_shelf_banner',\n itemListName: 'Scene_Shelf_2_Products',\n items: products.map((item, index) => ({\n item_id: item.sku ?? '',\n item_name: item.title,\n item_variant: item.variantId ?? '',\n price: item.currentPrice,\n index: index,\n })),\n tabName: '',\n })\n\n const visibleLimit = useGridRowCount({\n rows: viewMoreLimit ?? 0,\n mobileCols: 2,\n })\n\n const hasVideo = React.useMemo(\n () =>\n [sceneImage?.pc, sceneImage?.desktop, sceneImage?.laptop, sceneImage?.pad, sceneImage?.mobile].some(\n media => media?.mimeType === 'video/mp4'\n ),\n [sceneImage]\n )\n\n const handlePlayButtonClick = React.useCallback(() => {\n const video = videoRef.current\n if (video) {\n if (video.paused) {\n video.play()\n setIsPlaying(true)\n onPlayClick?.(true)\n } else {\n video.pause()\n setIsPlaying(false)\n onPlayClick?.(false)\n }\n } else {\n onPlayClick?.(true)\n }\n gaTrack({\n event: 'ga4Event',\n event_name: 'component_click',\n event_parameters: {\n page_group: trackingData?.pageGroup,\n component_type: 'video',\n component_name: 'scene_shelf_banner',\n position: 1,\n creative_id: sceneImage?.pc?.id,\n },\n })\n }, [onPlayClick, sceneImage?.pc?.id, trackingData?.pageGroup])\n\n // \u8FDB\u5165\u89C6\u7A97\u81EA\u52A8\u64AD\u653E\n React.useEffect(() => {\n const video = videoRef.current\n if (!video || !hasVideo) return\n\n const observer = new IntersectionObserver(\n entries => {\n entries.forEach(entry => {\n if (entry.isIntersecting) {\n // \u8FDB\u5165\u89C6\u7A97\uFF0C\u81EA\u52A8\u64AD\u653E\n video.play().catch(error => {\n // \u5904\u7406\u81EA\u52A8\u64AD\u653E\u5931\u8D25\uFF08\u6D4F\u89C8\u5668\u7B56\u7565\u53EF\u80FD\u963B\u6B62\u81EA\u52A8\u64AD\u653E\uFF09\n console.warn('Video autoplay failed:', error)\n })\n } else {\n // \u79BB\u5F00\u89C6\u7A97\uFF0C\u6682\u505C\u64AD\u653E\n video.pause()\n }\n })\n },\n {\n threshold: 0.5, // \u5F53\u89C6\u9891 50% \u53EF\u89C1\u65F6\u89E6\u53D1\n }\n )\n\n observer.observe(video)\n\n return () => {\n observer.disconnect()\n }\n }, [])\n\n return (\n <div\n {...props}\n ref={ref}\n className={cn(\n 'scene-shelf-v2-root w-full overflow-hidden',\n { 'aiui-dark': theme === 'dark' },\n className,\n classNames?.root\n )}\n >\n {/* \u2500\u2500 \u5A92\u4F53\u533A \u2500\u2500 */}\n <div\n className={cn(\n 'scene-shelf-v2-media laptop:h-[360px] tablet:h-[400px] desktop:h-[384px] rounded-box tablet:rounded-t-box tablet:rounded-b-none lg-desktop:h-[480px] relative h-[240px] overflow-hidden',\n classNames?.media\n )}\n ref={mediaRef}\n >\n <Media\n pcImage={sceneImage?.pc}\n desktopImage={sceneImage?.desktop}\n laptopImage={sceneImage?.laptop}\n padImage={sceneImage?.pad}\n mobileImage={sceneImage?.mobile}\n className=\"size-full\"\n videoClassName=\"absolute inset-0 size-full object-cover\"\n videoRef={videoRef}\n onVideoPlay={() => setIsPlaying(true)}\n onVideoPause={() => setIsPlaying(false)}\n onVideoEnded={() => setIsPlaying(false)}\n />\n {/* \u6E10\u53D8\u906E\u7F69 */}\n <div\n aria-hidden=\"true\"\n className={cn(\n 'scene-shelf-v2-media-overlay pointer-events-none absolute inset-0',\n classNames?.mediaOverlay\n )}\n />\n\n {/* \u5F15\u8A00 + \u64AD\u653E/\u6682\u505C\u6309\u94AE */}\n {hasVideo && (\n <div className=\"desktop:gap-16 desktop:p-8 absolute inset-0 flex items-end justify-end gap-4 p-6\">\n <button\n type=\"button\"\n aria-label={isPlaying ? 'Pause video' : 'Play video'}\n onClick={handlePlayButtonClick}\n className={cn(\n 'scene-shelf-v2-media-play-button flex size-14 shrink-0 items-center justify-center rounded-full bg-white/20 transition-opacity hover:opacity-80',\n classNames?.mediaPlayButton\n )}\n >\n {isPlaying ? <PauseIcon /> : <PlayIcon />}\n </button>\n </div>\n )}\n </div>\n\n {/* \u2500\u2500 \u4EA7\u54C1\u533A \u2500\u2500 */}\n <div\n ref={productWrapperRef}\n className={cn(\n 'scene-shelf-v2-products text-info-primary tablet:bg-container-primary laptop:p-6 desktop:p-8 rounded-b-box tablet:p-4 flex flex-col gap-4 bg-transparent p-0 pt-3',\n classNames?.products\n )}\n >\n {productsTitle && (\n <Heading\n as=\"h2\"\n size={3}\n className={cn('scene-shelf-v2-products-title text-info-primary', classNames?.productsTitle)}\n html={productsTitle}\n />\n )}\n\n {/* Mobile\uFF1A2\u5217\u5E73\u94FA */}\n <div className=\"tablet:hidden grid grid-cols-2 gap-3\">\n {(() => {\n const shouldShowViewMore =\n viewMoreLimit !== undefined && viewMoreLimit > 0 && products.length > visibleLimit\n const displayedProducts = shouldShowViewMore && !isExpanded ? products.slice(0, visibleLimit) : products\n\n return (\n <>\n {displayedProducts.map((product, index) => (\n <ProductCardInner\n key={product.productKey}\n isShowTag={data.isShowTag ?? true}\n product={product}\n onImageClick={onImageClick}\n onProductImageClick={onProductImageClick}\n onLearnMore={onLearnMore}\n onShopNow={onShopNow}\n onAddToCart={onAddToCart}\n secondaryButtonText={secondaryButtonText}\n secondaryButtonFun={secondaryButtonFun}\n primaryButtonText={primaryButtonText}\n primaryButtonFun={primaryButtonFun}\n classNames={classNames}\n theme={theme}\n index={index}\n />\n ))}\n {shouldShowViewMore && (\n <div className=\"col-span-2 mt-6 flex justify-center\">\n <button\n type=\"button\"\n onClick={() => setIsExpanded(prev => !prev)}\n className=\"text-info-primary hover:text-brand-0 flex items-center gap-2 text-[14px] font-bold transition-colors\"\n aria-expanded={isExpanded}\n >\n {isExpanded ? (copy?.viewLessLabel ?? 'View Less') : (copy?.viewMoreLabel ?? 'View More')}\n <svg\n className={cn('size-4 transition-transform', isExpanded && 'rotate-180')}\n fill=\"none\"\n stroke=\"currentColor\"\n viewBox=\"0 0 24 24\"\n >\n <path strokeLinecap=\"round\" strokeLinejoin=\"round\" strokeWidth={2} d=\"M19 9l-7 7-7-7\" />\n </svg>\n </button>\n </div>\n )}\n </>\n )\n })()}\n </div>\n\n {/* Tablet\uFF1ASwiper \u6A2A\u6ED1 */}\n <div className=\"tablet:block hidden\">\n <div className=\"relative\">\n <Swiper\n slidesPerView=\"auto\"\n observer\n observeParents\n modules={[Mousewheel]}\n mousewheel={{\n enabled: true,\n forceToAxis: true,\n sensitivity: 1,\n }}\n className=\"!overflow-visible\"\n breakpoints={{\n 768: {\n spaceBetween: 16,\n slidesPerView: products.length > 3 ? 2.3 : 2,\n },\n 1024: {\n spaceBetween: 16,\n slidesPerView: products.length > 3 ? 2.8 : 3,\n },\n 1440: {\n spaceBetween: 16,\n slidesPerView: products.length > 4 ? 3.8 : 4,\n },\n 1920: {\n spaceBetween: 16,\n slidesPerView: products.length > 4 ? 3.8 : 4,\n },\n }}\n >\n {products.map((product, index) => (\n <SwiperSlide key={product.productKey} className={cn('!h-auto ', classNames.productCardSlideWrapper)}>\n <ProductCardInner\n product={product}\n isShowTag={data.isShowTag ?? true}\n onImageClick={onImageClick}\n onProductImageClick={onProductImageClick}\n onLearnMore={onLearnMore}\n onShopNow={onShopNow}\n onAddToCart={onAddToCart}\n secondaryButtonText={secondaryButtonText}\n secondaryButtonFun={secondaryButtonFun}\n primaryButtonText={primaryButtonText}\n primaryButtonFun={primaryButtonFun}\n classNames={classNames}\n theme={theme}\n index={index}\n />\n </SwiperSlide>\n ))}\n </Swiper>\n </div>\n </div>\n </div>\n </div>\n )\n }\n)\n\nSceneShelfV2.displayName = 'SceneShelfV2'\nexport default withLayout(SceneShelfV2)\nexport { ProductCardInner as SceneShelfV2ProductCard }\n"],
5
+ "mappings": "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",
6
6
  "names": ["Fragment", "jsx", "jsxs", "React", "cn", "getLocalizedPath", "Heading", "Text", "Badge", "Button", "Picture", "Media", "Swiper", "SwiperSlide", "Mousewheel", "withLayout", "useGridRowCount", "useExposure", "useViewItemList", "trackUrlRef", "useAiuiContext", "gaTrack", "componentType", "componentName", "PlayIcon", "PauseIcon", "ProductCardInner", "product", "isShowTag", "onImageClick", "onProductImageClick", "onLearnMore", "onShopNow", "onAddToCart", "secondaryButtonText", "secondaryButtonFun", "primaryButtonText", "primaryButtonFun", "classNames", "className", "theme", "index", "locale", "trackingData", "primaryLoading", "setPrimaryLoading", "secondaryLoading", "setSecondaryLoading", "pageGroup", "handleButtonClick", "buttonFun", "buttonType", "setLoading", "handlePrimary", "handleSecondary", "handleImageClick", "e", "callback", "tag", "idx", "SceneShelfV2", "data", "onPlayClick", "props", "ref", "sceneImage", "productsTitle", "products", "viewMoreLimit", "copy", "videoRef", "mediaRef", "productWrapperRef", "isPlaying", "setIsPlaying", "isExpanded", "setIsExpanded", "item", "visibleLimit", "hasVideo", "media", "handlePlayButtonClick", "video", "observer", "entries", "entry", "error", "shouldShowViewMore", "displayedProducts", "prev", "SceneShelfV2_default"]
7
7
  }
@@ -5,7 +5,7 @@ import type { Theme } from '../../types/props.js';
5
5
  /**
6
6
  * 语义化类名
7
7
  */
8
- export type SceneShelfV3SemanticName = 'root' | 'title' | 'description' | 'tabsList' | 'promotionalBar' | 'productGrid' | 'viewMore' | 'productCard' | 'productTitle' | 'productDescription' | 'productPriceLabel' | 'productPrice' | 'buttonGroup' | 'secondaryButton' | 'primaryButton' | 'stockTrack' | 'stockBar';
8
+ export type SceneShelfV3SemanticName = 'root' | 'title' | 'description' | 'tabsList' | 'promotionalBar' | 'productGrid' | 'viewMore' | 'productCard' | 'productTitle' | 'productDescription' | 'productPriceLabel' | 'productPrice' | 'priceWrapper' | 'originalPrice' | 'buttonGroup' | 'secondaryButton' | 'primaryButton';
9
9
  /**
10
10
  * 库存展示模式
11
11
  */
@@ -1,2 +1,2 @@
1
- "use client";import{Fragment as Q,jsx as t,jsxs as s}from"react/jsx-runtime";import*as n from"react";import{cn as a,getLocalizedPath as F}from"../../helpers/index.js";import{Button as C,Badge as R,Card as V,CardContent as q,Picture as K,Text as S,Heading as c}from"../../components/index.js";import{trackUrlRef as I}from"../../shared/trackUrlRef.js";import{gaTrack as f}from"../../shared/track.js";import{useAiuiContext as J}from"../AiuiProvider/index.js";const N=n.forwardRef(({product:e,className:T,showTags:B=!0,onLearnMore:u,onShopNow:y,onAddToCart:v,classNames:o,secondaryButtonText:p,secondaryButtonFun:b,primaryButtonText:m,primaryButtonFun:_,showOriginalPrice:L,copy:z,onProductImageClick:d,theme:D="light",locale:h="us",index:l=0,tabName:x},M)=>{const[H,O]=n.useState(!1),[j,A]=n.useState(!1),{trackingData:G}=J(),r=G?.pageGroup,k=!e.soldOut,P=n.useCallback(async(i,g)=>{if(!i)return;const w=g==="primary"?O:A;w(!0);try{switch(i){case"buyNow":await y?.(e);break;case"addCart":await v?.(e);break;case"learnMore":await u?.(e.href);break}}finally{w(!1)}},[e,y,v,u]),U=n.useMemo(()=>F(I(e.href,r+"_shelf_scene_shelf_v3"),h),[e.href,r,h]),E=n.useCallback(()=>{d?.(e),f({event:"ga4Event",event_name:"select_item",item_list_name:"Scene_Shelf_3_Products",page_group:r,items:[{item_id:e.sku,item_name:e.title,item_variant:e.id,price:e.currentPrice,index:l}],tab_name:x,position:l})},[d,e,r,l,x]);return t(V,{ref:M,className:a("bg-container-primary flex h-full flex-col overflow-hidden border-none hover:bg-white",T,o?.productCard,{"hover:bg-container-secondary-0 ":D==="dark"}),children:s(q,{className:"desktop:p-6 relative flex flex-1 flex-col justify-between p-4",children:[t("div",{className:"product-image-wrapper lg-desktop:size-[196px] mx-auto size-[138px] cursor-pointer overflow-hidden",children:t("a",{onClick:E,...!d&&{href:U},rel:"noreferrer",children:t(K,{source:e.imageUrl,alt:e.imageAlt,className:"aspect-square size-full object-contain",imgClassName:"w-full h-full object-contain"})})}),t("div",{className:"lg-desktop:h-[28px] mb-1 flex h-[24px] gap-1",children:B&&e.tags?.map((i,g)=>t(R,{size:"sm",variant:i.variant||"outline",className:a(i.variant==="promotional"?"ml-2":""),promotionalType:i.promotionalType,children:i.label},g))}),s("div",{className:"flex h-full flex-1 grow flex-col justify-between",children:[s("div",{className:"mb-4",children:[t(c,{as:"h3",size:2,className:a("text-info-primary laptop:line-clamp-2 mb-2 line-clamp-3 min-h-[2.4em]",o?.productTitle),html:e.custom_name||e.title}),(e?.custom_description||e?.description)&&t(S,{size:2,className:a("text-info-secondary desktop:text-[16px] lg-desktop:text-[18px] line-clamp-1 text-[14px]",o?.productDescription),html:e.custom_description||e.description})]}),e?.priceLabel&&k&&t(S,{size:4,className:a("text-marketing-1 desktop:text-[16px] lg-desktop:text-[18px] mt-2 text-[14px]",o?.productPriceLabel),children:e.priceLabel}),s("div",{children:[t("div",{className:a("mb-2",o?.productPrice),children:t("div",{className:"flex items-baseline gap-2",children:k?s(Q,{children:[t(c,{size:2,className:"text-info-primary",as:"h6",children:e.currentPrice}),L&&e.originalPrice&&t(c,{size:2,className:"text-info-tertiary line-through",as:"h6",children:e.originalPrice})]}):t(c,{size:2,className:"text-info-tertiary",children:z?.outOfStockLabel??"Sold Out"})})}),s("div",{className:a("lg-desktop:gap-3 laptop:flex-row laptop:flex-nowrap flex flex-col flex-wrap gap-2",o?.buttonGroup),children:[p&&t(C,{variant:"secondary",size:"base",className:a("laptop:w-fit laptop:grow-0 w-full flex-1 whitespace-nowrap",o?.secondaryButton),onClick:()=>{P(b,"secondary"),f({event:"ga4Event",event_name:"component_click",event_parameters:{page_group:r||"Home Page",component_type:"copy",component_name:"scene_shelf_product",component_title:e.custom_name||e.title,component_description:e.custom_description||"",button_name:p,SKU:e.sku||"",position:l}})},disabled:e.soldOut&&b!=="learnMore",loading:j,children:p}),m&&t(C,{variant:"primary",size:"base",className:a("laptop:w-fit laptop:grow-0 w-full flex-1 whitespace-nowrap",o?.primaryButton),onClick:()=>{P(_,"primary"),f({event:"ga4Event",event_name:"component_click",event_parameters:{page_group:r||"Home Page",component_type:"copy",component_name:"scene_shelf_product",component_title:e.custom_name||e.title,component_description:e.custom_description||"",button_name:m,SKU:e.sku||"",position:l}})},disabled:e.soldOut&&_!=="learnMore",loading:H,children:m})]})]})]})]})})});N.displayName="SceneShelfV3.ProductCard";var ee=N;export{N as ProductCard,ee as default};
1
+ "use client";import{Fragment as J,jsx as t,jsxs as s}from"react/jsx-runtime";import*as n from"react";import{cn as a,getLocalizedPath as F}from"../../helpers/index.js";import{Button as C,Badge as R,Card as V,CardContent as q,Picture as K,Text as S,Heading as p}from"../../components/index.js";import{trackUrlRef as W}from"../../shared/trackUrlRef.js";import{gaTrack as f}from"../../shared/track.js";import{useAiuiContext as I}from"../AiuiProvider/index.js";const N=n.forwardRef(({product:e,className:T,showTags:B=!0,onLearnMore:u,onShopNow:y,onAddToCart:v,classNames:i,secondaryButtonText:c,secondaryButtonFun:b,primaryButtonText:m,primaryButtonFun:_,showOriginalPrice:L,copy:z,onProductImageClick:d,theme:D="light",locale:h="us",index:l=0,tabName:x},M)=>{const[H,O]=n.useState(!1),[j,A]=n.useState(!1),{trackingData:G}=I(),r=G?.pageGroup,k=!e.soldOut,P=n.useCallback(async(o,g)=>{if(!o)return;const w=g==="primary"?O:A;w(!0);try{switch(o){case"buyNow":await y?.(e);break;case"addCart":await v?.(e);break;case"learnMore":await u?.(e.href);break}}finally{w(!1)}},[e,y,v,u]),U=n.useMemo(()=>F(W(e.href,r+"_shelf_scene_shelf_v3"),h),[e.href,r,h]),E=n.useCallback(()=>{d?.(e),f({event:"ga4Event",event_name:"select_item",item_list_name:"Scene_Shelf_3_Products",page_group:r,items:[{item_id:e.sku,item_name:e.title,item_variant:e.id,price:e.currentPrice,index:l}],tab_name:x,position:l})},[d,e,r,l,x]);return t(V,{ref:M,className:a("bg-container-primary flex h-full flex-col overflow-hidden border-none hover:bg-white",T,i?.productCard,{"hover:bg-container-secondary-0 ":D==="dark"}),children:s(q,{className:"desktop:p-6 relative flex flex-1 flex-col justify-between p-4",children:[t("div",{className:"product-image-wrapper lg-desktop:size-[196px] mx-auto size-[138px] cursor-pointer overflow-hidden",children:t("a",{onClick:E,...!d&&{href:U},rel:"noreferrer",children:t(K,{source:e.imageUrl,alt:e.imageAlt,className:"aspect-square size-full object-contain",imgClassName:"w-full h-full object-contain"})})}),t("div",{className:"lg-desktop:h-[28px] mb-1 flex h-[24px] gap-1",children:B&&e.tags?.map((o,g)=>t(R,{size:"sm",variant:o.variant||"outline",className:a(o.variant==="promotional"?"ml-2":""),promotionalType:o.promotionalType,children:o.label},g))}),s("div",{className:"flex h-full flex-1 grow flex-col justify-between",children:[s("div",{className:"mb-4",children:[t(p,{as:"h3",size:2,className:a("text-info-primary laptop:line-clamp-2 mb-2 line-clamp-3 min-h-[2.4em]",i?.productTitle),html:e.custom_name||e.title}),(e?.custom_description||e?.description)&&t(S,{size:2,className:a("text-info-secondary desktop:text-[16px] lg-desktop:text-[18px] line-clamp-1 text-[14px]",i?.productDescription),html:e.custom_description||e.description})]}),s("div",{children:[t("div",{className:a("mb-2",i?.productPrice),children:t("div",{className:a("flex items-baseline gap-2",i?.priceWrapper),children:k?s(J,{children:[t(p,{size:2,className:"text-info-primary",as:"h6",children:e.currentPrice}),L&&e.originalPrice&&t(p,{size:2,className:a("text-info-tertiary line-through",i?.originalPrice),as:"h6",children:e.originalPrice})]}):t(p,{size:2,className:"text-info-tertiary",children:z?.outOfStockLabel??"Sold Out"})})}),e?.priceLabel&&k&&t(S,{size:4,className:a("text-marketing-1 desktop:text-[16px] lg-desktop:text-[18px] mt-2 text-[14px]",i?.productPriceLabel),children:e.priceLabel}),s("div",{className:a("lg-desktop:gap-3 laptop:flex-row laptop:flex-nowrap flex flex-col flex-wrap gap-2",i?.buttonGroup),children:[c&&t(C,{variant:"secondary",size:"base",className:a("laptop:w-fit laptop:grow-0 w-full flex-1 whitespace-nowrap",i?.secondaryButton),onClick:()=>{P(b,"secondary"),f({event:"ga4Event",event_name:"component_click",event_parameters:{page_group:r||"Home Page",component_type:"copy",component_name:"scene_shelf_product",component_title:e.custom_name||e.title,component_description:e.custom_description||"",button_name:c,SKU:e.sku||"",position:l}})},disabled:e.soldOut&&b!=="learnMore",loading:j,children:c}),m&&t(C,{variant:"primary",size:"base",className:a("laptop:w-fit laptop:grow-0 w-full flex-1 whitespace-nowrap",i?.primaryButton),onClick:()=>{P(_,"primary"),f({event:"ga4Event",event_name:"component_click",event_parameters:{page_group:r||"Home Page",component_type:"copy",component_name:"scene_shelf_product",component_title:e.custom_name||e.title,component_description:e.custom_description||"",button_name:m,SKU:e.sku||"",position:l}})},disabled:e.soldOut&&_!=="learnMore",loading:H,children:m})]})]})]})]})})});N.displayName="SceneShelfV3.ProductCard";var ee=N;export{N as ProductCard,ee as default};
2
2
  //# sourceMappingURL=ProductCard.js.map