@anker-in/headless-ui 1.3.61 → 1.3.62

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 (56) hide show
  1. package/dist/cjs/biz-components/ActiveShelf/ProductCard.d.ts +9 -0
  2. package/dist/cjs/biz-components/ActiveShelf/ProductCard.js +1 -1
  3. package/dist/cjs/biz-components/ActiveShelf/ProductCard.js.map +3 -3
  4. package/dist/cjs/biz-components/ActiveShelf/index.d.ts +9 -0
  5. package/dist/cjs/biz-components/ActiveShelf/index.js +1 -1
  6. package/dist/cjs/biz-components/ActiveShelf/index.js.map +3 -3
  7. package/dist/cjs/biz-components/BuyOneGetOneShelf/PriceAndActions.d.ts +6 -0
  8. package/dist/cjs/biz-components/BuyOneGetOneShelf/PriceAndActions.js +1 -1
  9. package/dist/cjs/biz-components/BuyOneGetOneShelf/PriceAndActions.js.map +3 -3
  10. package/dist/cjs/biz-components/BuyOneGetOneShelf/ProductCard.d.ts +6 -0
  11. package/dist/cjs/biz-components/BuyOneGetOneShelf/ProductCard.js +1 -1
  12. package/dist/cjs/biz-components/BuyOneGetOneShelf/ProductCard.js.map +3 -3
  13. package/dist/cjs/biz-components/BuyOneGetOneShelf/types.d.ts +6 -0
  14. package/dist/cjs/biz-components/BuyOneGetOneShelf/types.js +1 -1
  15. package/dist/cjs/biz-components/BuyOneGetOneShelf/types.js.map +1 -1
  16. package/dist/cjs/biz-components/SceneShelfV3/ProductCard.d.ts +9 -0
  17. package/dist/cjs/biz-components/SceneShelfV3/ProductCard.js +1 -1
  18. package/dist/cjs/biz-components/SceneShelfV3/ProductCard.js.map +3 -3
  19. package/dist/cjs/biz-components/SceneShelfV3/index.d.ts +9 -0
  20. package/dist/cjs/biz-components/SceneShelfV3/index.js +1 -1
  21. package/dist/cjs/biz-components/SceneShelfV3/index.js.map +3 -3
  22. package/dist/cjs/biz-components/ShelfDisplay/shelfDisplay.d.ts +32 -18
  23. package/dist/cjs/biz-components/ShelfDisplay/shelfDisplay.js +1 -1
  24. package/dist/cjs/biz-components/ShelfDisplay/shelfDisplay.js.map +1 -1
  25. package/dist/cjs/biz-components/ShelfDisplay/shelfDisplayItem.js +1 -1
  26. package/dist/cjs/biz-components/ShelfDisplay/shelfDisplayItem.js.map +2 -2
  27. package/dist/cjs/biz-components/ShelfDisplayHorizontal/shelfDisplayHorizontalItem.js +1 -1
  28. package/dist/cjs/biz-components/ShelfDisplayHorizontal/shelfDisplayHorizontalItem.js.map +2 -2
  29. package/dist/esm/biz-components/ActiveShelf/ProductCard.d.ts +9 -0
  30. package/dist/esm/biz-components/ActiveShelf/ProductCard.js +1 -1
  31. package/dist/esm/biz-components/ActiveShelf/ProductCard.js.map +3 -3
  32. package/dist/esm/biz-components/ActiveShelf/index.d.ts +9 -0
  33. package/dist/esm/biz-components/ActiveShelf/index.js +1 -1
  34. package/dist/esm/biz-components/ActiveShelf/index.js.map +3 -3
  35. package/dist/esm/biz-components/BuyOneGetOneShelf/PriceAndActions.d.ts +6 -0
  36. package/dist/esm/biz-components/BuyOneGetOneShelf/PriceAndActions.js +1 -1
  37. package/dist/esm/biz-components/BuyOneGetOneShelf/PriceAndActions.js.map +3 -3
  38. package/dist/esm/biz-components/BuyOneGetOneShelf/ProductCard.d.ts +6 -0
  39. package/dist/esm/biz-components/BuyOneGetOneShelf/ProductCard.js +1 -1
  40. package/dist/esm/biz-components/BuyOneGetOneShelf/ProductCard.js.map +3 -3
  41. package/dist/esm/biz-components/BuyOneGetOneShelf/types.d.ts +6 -0
  42. package/dist/esm/biz-components/BuyOneGetOneShelf/types.js.map +1 -1
  43. package/dist/esm/biz-components/SceneShelfV3/ProductCard.d.ts +9 -0
  44. package/dist/esm/biz-components/SceneShelfV3/ProductCard.js +1 -1
  45. package/dist/esm/biz-components/SceneShelfV3/ProductCard.js.map +3 -3
  46. package/dist/esm/biz-components/SceneShelfV3/index.d.ts +9 -0
  47. package/dist/esm/biz-components/SceneShelfV3/index.js +1 -1
  48. package/dist/esm/biz-components/SceneShelfV3/index.js.map +3 -3
  49. package/dist/esm/biz-components/ShelfDisplay/shelfDisplay.d.ts +32 -18
  50. package/dist/esm/biz-components/ShelfDisplay/shelfDisplay.js +1 -1
  51. package/dist/esm/biz-components/ShelfDisplay/shelfDisplay.js.map +1 -1
  52. package/dist/esm/biz-components/ShelfDisplay/shelfDisplayItem.js +1 -1
  53. package/dist/esm/biz-components/ShelfDisplay/shelfDisplayItem.js.map +2 -2
  54. package/dist/esm/biz-components/ShelfDisplayHorizontal/shelfDisplayHorizontalItem.js +1 -1
  55. package/dist/esm/biz-components/ShelfDisplayHorizontal/shelfDisplayHorizontalItem.js.map +2 -2
  56. package/package.json +1 -1
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../../../src/biz-components/BuyOneGetOneShelf/ProductCard.tsx"],
4
- "sourcesContent": ["'use client'\n\nimport * as React from 'react'\nimport { cn } from '../../helpers/index.js'\nimport ProductImage from './ProductImage.js'\nimport ProductInfo from './ProductInfo.js'\nimport GiftSelection from './GiftSelection.js'\nimport PriceAndActions from './PriceAndActions.js'\nimport { BuyOneGetOneShelfContext } from './context.js'\nimport type {\n FreeGift,\n FreeGiftWithSelection,\n ProductCardData,\n PureProductData,\n ProductTag,\n BuyOneGetOneShelfProductCardSemanticName,\n} from './types.js'\n\nexport interface ProductCardProps extends React.HTMLAttributes<HTMLDivElement> {\n /** \u4EA7\u54C1\u6570\u636E\uFF08\u4E0D\u5305\u542B\u8D60\u54C1\u4FE1\u606F\uFF09 */\n productData: PureProductData\n /** \u8D60\u54C1\u5217\u8868 */\n gifts?: FreeGift[]\n /** \u8D60\u54C1\u7C7B\u578B 1-> \u8D60\u9001\u5176\u4E2D\u4E00\u4E2A\u8D60\u54C1\uFF0C 2 -> \u8D60\u9001\u6240\u6709\u8D60\u54C1 */\n giftType?: 1 | 2\n /** \u573A\u666F\u56FE\u7247 */\n sceneImages: any\n /** \u4EA7\u54C1\u6807\u7B7E */\n tags?: ProductTag[]\n /** \u5F53\u524D\u9009\u4E2D\u7684\u8D60\u54C1SKU\uFF08\u53D7\u63A7\u7EC4\u4EF6\uFF09 */\n selectedGiftSku?: string\n /** @deprecated Layout is now automatically inferred by Root based on children count. */\n layout?: 'horizontal' | 'vertical'\n classNames?: Partial<Record<BuyOneGetOneShelfProductCardSemanticName, string>>\n soldOutText?: string\n /** @deprecated Use `onProductImageClick` instead. */\n onProductClick?: (product: ProductCardData) => void\n /** \u4EA7\u54C1\u56FE\u7247\u70B9\u51FB\u56DE\u8C03 */\n onProductImageClick?: (product: ProductCardData) => void\n /** Learn More \u70B9\u51FB\u56DE\u8C03 */\n onLearnMore?: (product: ProductCardData, selectedGifts: FreeGift[]) => void\n /** Shop Now \u70B9\u51FB\u56DE\u8C03 */\n onShopNow?: (product: ProductCardData, selectedGifts: FreeGift[]) => void\n /** \u8D60\u54C1\u70B9\u51FB\u56DE\u8C03 */\n onGiftClick?: (gift: FreeGift, selectedGifts: FreeGift[]) => void\n /** \u8D60\u54C1\u9009\u62E9\u53D8\u5316\u56DE\u8C03 */\n onGiftSelectionChange?: (selectedGifts: FreeGift[], product: ProductCardData) => void\n /** \u9009\u4E2D\u8D60\u54C1SKU\u53D8\u5316\u56DE\u8C03\uFF08\u53D7\u63A7\u7EC4\u4EF6\uFF09 */\n onSelectedGiftSkuChange?: (selectedSku: string | null) => void\n}\n\n/**\n * ProductCard - \u4E70\u8D60\u8D27\u67B6\u4EA7\u54C1\u5361\u7247\n *\n * @description \u7528\u4E8E\u4E70\u4E00\u8D60\u4E00\u6D3B\u52A8\u7684\u4EA7\u54C1\u5C55\u793A\u5361\u7247\uFF0C\u5DE6\u4FA7\u5C55\u793A\u4EA7\u54C1\u56FE\u7247\u548C\u6807\u7B7E\uFF0C\u53F3\u4FA7\u5C55\u793A\u4EA7\u54C1\u4FE1\u606F\u3001\u8D60\u54C1\u548C\u8D2D\u4E70\u6309\u94AE\n */\nconst ProductCard = React.forwardRef<HTMLDivElement, ProductCardProps>(\n (\n {\n productData,\n gifts = [],\n giftType = 1,\n selectedGiftSku,\n sceneImages,\n tags,\n layout: layoutProp,\n className,\n onProductClick,\n onProductImageClick,\n onLearnMore,\n onShopNow,\n onGiftClick,\n onGiftSelectionChange,\n classNames,\n soldOutText,\n ...props\n },\n ref\n ) => {\n const { layout: contextLayout, theme } = React.useContext(BuyOneGetOneShelfContext)\n const layout = layoutProp ?? contextLayout\n\n const [learnMoreLoading, setLearnMoreLoading] = React.useState(false)\n const [shopNowLoading, setShopNowLoading] = React.useState(false)\n\n // \u5185\u90E8\u72B6\u6001\u7BA1\u7406\u8D60\u54C1\u7684\u9009\u62E9\u72B6\u6001 - \u4F7F\u7528\u9009\u4E2D\u7684ID\u6570\u7EC4\u800C\u4E0D\u662F\u4FEE\u6539gift\u5BF9\u8C61\n const [selectedGiftIds, setSelectedGiftIds] = React.useState<string[]>(() => {\n if (!gifts || gifts.length === 0) return []\n\n if (giftType === 2) {\n // gift_type 2 (\u5168\u9009\u6A21\u5F0F) - \u9009\u4E2D\u6240\u6709\u8D60\u54C1\n return gifts.map((gift: FreeGift) => gift.id)\n } else {\n // gift_type 1 (\u5355\u9009\u6A21\u5F0F) - \u9ED8\u8BA4\u9009\u4E2D\u7B2C\u4E00\u4E2A\u8D60\u54C1\n return [gifts[0].id]\n }\n })\n\n // \u751F\u6210\u5E26\u6709\u9009\u62E9\u72B6\u6001\u7684\u8D60\u54C1\u5217\u8868\u7528\u4E8E\u6E32\u67D3\n const giftsWithSelection = React.useMemo(() => {\n if (!gifts) return []\n\n return gifts.map((gift: FreeGift) => ({\n ...gift,\n selected: selectedGiftIds.includes(gift.id),\n }))\n }, [gifts, selectedGiftIds])\n\n // \u5F53 gifts \u6216 giftType \u66F4\u65B0\u65F6\uFF0C\u540C\u6B65\u66F4\u65B0\u5185\u90E8\u72B6\u6001\n React.useEffect(() => {\n if (!gifts || gifts.length === 0) {\n setSelectedGiftIds([])\n return\n }\n\n if (giftType === 2) {\n // gift_type 2 (\u5168\u9009\u6A21\u5F0F) - \u9009\u4E2D\u6240\u6709\u8D60\u54C1\n setSelectedGiftIds(gifts.map((gift: FreeGift) => gift.id))\n } else {\n // gift_type 1 (\u5355\u9009\u6A21\u5F0F) - \u667A\u80FD\u72B6\u6001\u7BA1\u7406\n setSelectedGiftIds(prevSelectedIds => {\n // \u68C0\u67E5\u5F53\u524D\u9009\u4E2D\u7684\u793C\u54C1\u662F\u5426\u4ECD\u7136\u5B58\u5728\u4E8E\u65B0\u7684 gifts \u5217\u8868\u4E2D\n const currentSelectedId = prevSelectedIds[0]\n const isCurrentSelectionValid =\n currentSelectedId && gifts.some((gift: FreeGift) => gift.id === currentSelectedId)\n\n // \u5982\u679C\u5F53\u524D\u9009\u4E2D\u72B6\u6001\u4ECD\u7136\u6709\u6548\uFF0C\u4FDD\u6301\u4E0D\u53D8\uFF1B\u5426\u5219\u9ED8\u8BA4\u9009\u4E2D\u7B2C\u4E00\u4E2A\n return isCurrentSelectionValid ? [currentSelectedId] : [gifts[0].id]\n })\n }\n }, [gifts, giftType])\n\n // \u6784\u9020\u5B8C\u6574\u7684\u4EA7\u54C1\u6570\u636E\u7528\u4E8E\u56DE\u8C03\n const fullProductData: ProductCardData = React.useMemo(\n () => ({\n ...productData,\n gifts,\n gift_type: giftType,\n }),\n [productData, gifts, giftType]\n )\n\n const handleGiftClick = (gift: FreeGift) => {\n // gift_type 2 (\u5168\u9009\u6A21\u5F0F) - \u4E0D\u5141\u8BB8\u53D6\u6D88\u9009\u62E9\uFF0C\u76F4\u63A5\u8FD4\u56DE\n if (giftType === 2) {\n // \u83B7\u53D6\u5F53\u524D\u6240\u6709\u9009\u4E2D\u7684gifts\u4F5C\u4E3A\u7B2C\u4E8C\u4E2A\u53C2\u6570\n const currentSelectedGifts = giftsWithSelection.filter((g: FreeGiftWithSelection) => g.selected)\n onGiftClick?.(gift, currentSelectedGifts)\n return\n }\n\n // gift_type 1 (\u5355\u9009\u6A21\u5F0F)\n setSelectedGiftIds(() => {\n const newSelectedIds = [gift.id] // \u5355\u9009\uFF1A\u59CB\u7EC8\u9009\u4E2D\u5F53\u524D\u9879\uFF0C\u70B9\u51FB\u5DF2\u9009\u4E2D\u9879\u4FDD\u6301\u72B6\u6001\uFF0C\u70B9\u51FB\u672A\u9009\u4E2D\u9879\u5207\u6362\u5230\u8BE5\u9879\n\n // \u8BA1\u7B97\u65B0\u7684\u9009\u4E2Dgifts\u4F5C\u4E3A\u7B2C\u4E8C\u4E2A\u53C2\u6570\u4F20\u9012\u7ED9\u56DE\u8C03\n const newSelectedGifts = gifts?.filter((g: FreeGift) => newSelectedIds.includes(g.id)) || []\n\n // \u8C03\u7528\u56DE\u8C03\u51FD\u6570\uFF0C\u7B2C\u4E8C\u4E2A\u53C2\u6570\u662F\u5F53\u524D\u9009\u4E2D\u7684gifts\n onGiftClick?.(gift, newSelectedGifts)\n onGiftSelectionChange?.(newSelectedGifts, fullProductData)\n\n return newSelectedIds\n })\n }\n\n const hasClickHandler = !!(onProductImageClick ?? onProductClick)\n const productHref = `/products/${productData.handle}`\n\n const handleProductImageClick = () => {\n const callback = onProductImageClick ?? onProductClick\n callback?.(fullProductData)\n }\n\n const handleLearnMoreClick = async () => {\n const selectedGifts = giftsWithSelection.filter(gift => gift.selected)\n setLearnMoreLoading(true)\n try {\n await onLearnMore?.(fullProductData, selectedGifts)\n } finally {\n setLearnMoreLoading(false)\n }\n }\n\n const handleShopNowClick = async () => {\n const selectedGifts = giftsWithSelection.filter(gift => gift.selected)\n setShopNowLoading(true)\n try {\n await onShopNow?.(fullProductData, selectedGifts)\n } finally {\n setShopNowLoading(false)\n }\n }\n\n return (\n <div\n ref={ref}\n className={cn(\n 'bg-container-primary rounded-box flex items-stretch overflow-hidden',\n // \u6839\u636E\u5E03\u5C40\u6A21\u5F0F\u8C03\u6574\u5BB9\u5668\n layout === 'horizontal'\n ? [\n 'laptop:flex-row lg-desktop:min-h-[560px] desktop:min-h-[448px] tablet:min-h-[526px] min-h-[610px] flex-col',\n 'laptop:col-span-2',\n ]\n : ['flex-col justify-between'],\n className\n )}\n {...props}\n >\n {/* \u4EA7\u54C1\u56FE\u7247\u533A\u57DF */}\n <ProductImage\n images={sceneImages}\n name={productData.name}\n layout={layout}\n tags={productData.tags || tags}\n onClick={hasClickHandler ? handleProductImageClick : undefined}\n href={hasClickHandler ? undefined : productHref}\n />\n\n {/* \u4EA7\u54C1\u4FE1\u606F\u533A\u57DF */}\n <div\n className={cn(\n 'bg-container-primary desktop:p-6 flex flex-col justify-between p-4',\n // \u6839\u636E\u5E03\u5C40\u6A21\u5F0F\u8C03\u6574\u5706\u89D2\u548C\u5C3A\u5BF8\n layout === 'horizontal'\n ? [\n 'rounded-r-box laptop:rounded-r-box tablet:rounded-b-box tablet:rounded-l-none',\n // \u4F7F\u7528 flex-basis \u8BBE\u7F6E\u5BBD\u5EA6\u6BD4\u4F8B\n 'laptop:basis-[39.1%]', // 360px / 921px \u2248 39.1%\n 'desktop:basis-[42.1%]', // 552px / 1312px \u2248 42.1%\n 'lg-desktop:basis-[42.1%]', // 700px / 1664px \u2248 42.1%\n 'shrink-0',\n ]\n : ['rounded-b-box', 'w-full', 'grow']\n )}\n >\n <div className=\"flex flex-1 flex-col justify-between gap-6\">\n {/* \u4EA7\u54C1\u6807\u9898\u548C\u63CF\u8FF0 */}\n <ProductInfo\n name={productData.name}\n onClick={hasClickHandler ? handleProductImageClick : undefined}\n href={hasClickHandler ? undefined : productHref}\n description={productData.description}\n classNames={classNames}\n />\n\n {/* \u514D\u8D39\u8D60\u54C1\u533A\u57DF */}\n <GiftSelection\n freeGiftLabel={productData.freeGiftLabel}\n freeGifts={giftsWithSelection}\n onGiftClick={handleGiftClick}\n giftType={giftType}\n selectedGiftSku={selectedGiftSku}\n theme={theme}\n />\n <PriceAndActions\n currentPrice={productData.currentPrice ?? ''}\n originalPrice={productData.originalPrice}\n priceLabel={productData.priceLabel}\n learnMoreText={productData.learnMoreText}\n shopNowText={productData.shopNowText}\n soldOutText={soldOutText}\n onLearnMore={handleLearnMoreClick}\n onShopNow={handleShopNowClick}\n availableForSale={productData.availableForSale}\n learnMoreLoading={learnMoreLoading}\n shopNowLoading={shopNowLoading}\n trackingTitle={productData.name}\n trackingDescription={productData.description}\n trackingSku={productData.sku}\n classNames={classNames}\n />\n </div>\n </div>\n </div>\n )\n }\n)\n\nProductCard.displayName = 'BuyOneGetOneShelf.ProductCard'\n\nexport default ProductCard\n"],
5
- "mappings": "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",
6
- "names": ["ProductCard_exports", "__export", "ProductCard_default", "__toCommonJS", "import_jsx_runtime", "React", "import_helpers", "import_ProductImage", "import_ProductInfo", "import_GiftSelection", "import_PriceAndActions", "import_context", "ProductCard", "productData", "gifts", "giftType", "selectedGiftSku", "sceneImages", "tags", "layoutProp", "className", "onProductClick", "onProductImageClick", "onLearnMore", "onShopNow", "onGiftClick", "onGiftSelectionChange", "classNames", "soldOutText", "props", "ref", "contextLayout", "theme", "layout", "learnMoreLoading", "setLearnMoreLoading", "shopNowLoading", "setShopNowLoading", "selectedGiftIds", "setSelectedGiftIds", "gift", "giftsWithSelection", "prevSelectedIds", "currentSelectedId", "fullProductData", "handleGiftClick", "currentSelectedGifts", "g", "newSelectedIds", "newSelectedGifts", "hasClickHandler", "productHref", "handleProductImageClick", "handleLearnMoreClick", "selectedGifts", "handleShopNowClick", "ProductImage", "ProductInfo", "GiftSelection", "PriceAndActions"]
4
+ "sourcesContent": ["'use client'\n\nimport * as React from 'react'\nimport { cn } from '../../helpers/index.js'\nimport ProductImage from './ProductImage.js'\nimport ProductInfo from './ProductInfo.js'\nimport GiftSelection from './GiftSelection.js'\nimport PriceAndActions from './PriceAndActions.js'\nimport { BuyOneGetOneShelfContext } from './context.js'\nimport type {\n FreeGift,\n FreeGiftWithSelection,\n ProductCardData,\n PureProductData,\n ProductTag,\n BuyOneGetOneShelfProductCardSemanticName,\n} from './types.js'\n\nexport interface ProductCardProps extends React.HTMLAttributes<HTMLDivElement> {\n /** \u4EA7\u54C1\u6570\u636E\uFF08\u4E0D\u5305\u542B\u8D60\u54C1\u4FE1\u606F\uFF09 */\n productData: PureProductData\n /** \u8D60\u54C1\u5217\u8868 */\n gifts?: FreeGift[]\n /** \u8D60\u54C1\u7C7B\u578B 1-> \u8D60\u9001\u5176\u4E2D\u4E00\u4E2A\u8D60\u54C1\uFF0C 2 -> \u8D60\u9001\u6240\u6709\u8D60\u54C1 */\n giftType?: 1 | 2\n /** \u573A\u666F\u56FE\u7247 */\n sceneImages: any\n /** \u4EA7\u54C1\u6807\u7B7E */\n tags?: ProductTag[]\n /** \u5F53\u524D\u9009\u4E2D\u7684\u8D60\u54C1SKU\uFF08\u53D7\u63A7\u7EC4\u4EF6\uFF09 */\n selectedGiftSku?: string\n /** @deprecated Layout is now automatically inferred by Root based on children count. */\n layout?: 'horizontal' | 'vertical'\n classNames?: Partial<Record<BuyOneGetOneShelfProductCardSemanticName, string>>\n soldOutText?: string\n /** @deprecated Use `onProductImageClick` instead. */\n onProductClick?: (product: ProductCardData) => void\n /** \u4EA7\u54C1\u56FE\u7247\u70B9\u51FB\u56DE\u8C03 */\n onProductImageClick?: (product: ProductCardData) => void\n /** Learn More \u70B9\u51FB\u56DE\u8C03 */\n onLearnMore?: (product: ProductCardData, selectedGifts: FreeGift[]) => void\n /** Shop Now \u70B9\u51FB\u56DE\u8C03 */\n onShopNow?: (product: ProductCardData, selectedGifts: FreeGift[]) => void\n /** \u8D60\u54C1\u70B9\u51FB\u56DE\u8C03 */\n onGiftClick?: (gift: FreeGift, selectedGifts: FreeGift[]) => void\n /** \u8D60\u54C1\u9009\u62E9\u53D8\u5316\u56DE\u8C03 */\n onGiftSelectionChange?: (selectedGifts: FreeGift[], product: ProductCardData) => void\n /** \u9009\u4E2D\u8D60\u54C1SKU\u53D8\u5316\u56DE\u8C03\uFF08\u53D7\u63A7\u7EC4\u4EF6\uFF09 */\n onSelectedGiftSkuChange?: (selectedSku: string | null) => void\n /**\n * \u539F\u4EF7\u533A\u57DF\u6E32\u67D3\u51FD\u6570\uFF0C\u7528\u4E8E\u5728\u539F\u4EF7\u4F4D\u7F6E\u5C55\u793A\u81EA\u5B9A\u4E49\u5185\u5BB9\uFF08\u5982 Save \u91D1\u989D\u6587\u6848\uFF09\u3002\n * \u4E0D\u4F20\u65F6\u4F7F\u7528\u9ED8\u8BA4\u7684\u539F\u4EF7\u6E32\u67D3\uFF08\u5212\u7EBF\u4EF7\uFF09\u3002\n * @param originalPrice - \u683C\u5F0F\u5316\u540E\u7684\u539F\u4EF7\u6587\u672C\n */\n renderOriginalPrice?: (originalPrice: string | undefined) => React.ReactNode\n}\n\n/**\n * ProductCard - \u4E70\u8D60\u8D27\u67B6\u4EA7\u54C1\u5361\u7247\n *\n * @description \u7528\u4E8E\u4E70\u4E00\u8D60\u4E00\u6D3B\u52A8\u7684\u4EA7\u54C1\u5C55\u793A\u5361\u7247\uFF0C\u5DE6\u4FA7\u5C55\u793A\u4EA7\u54C1\u56FE\u7247\u548C\u6807\u7B7E\uFF0C\u53F3\u4FA7\u5C55\u793A\u4EA7\u54C1\u4FE1\u606F\u3001\u8D60\u54C1\u548C\u8D2D\u4E70\u6309\u94AE\n */\nconst ProductCard = React.forwardRef<HTMLDivElement, ProductCardProps>(\n (\n {\n productData,\n gifts = [],\n giftType = 1,\n selectedGiftSku,\n sceneImages,\n tags,\n layout: layoutProp,\n className,\n onProductClick,\n onProductImageClick,\n onLearnMore,\n onShopNow,\n onGiftClick,\n onGiftSelectionChange,\n classNames,\n soldOutText,\n renderOriginalPrice,\n ...props\n },\n ref\n ) => {\n const { layout: contextLayout, theme } = React.useContext(BuyOneGetOneShelfContext)\n const layout = layoutProp ?? contextLayout\n\n const [learnMoreLoading, setLearnMoreLoading] = React.useState(false)\n const [shopNowLoading, setShopNowLoading] = React.useState(false)\n\n // \u5185\u90E8\u72B6\u6001\u7BA1\u7406\u8D60\u54C1\u7684\u9009\u62E9\u72B6\u6001 - \u4F7F\u7528\u9009\u4E2D\u7684ID\u6570\u7EC4\u800C\u4E0D\u662F\u4FEE\u6539gift\u5BF9\u8C61\n const [selectedGiftIds, setSelectedGiftIds] = React.useState<string[]>(() => {\n if (!gifts || gifts.length === 0) return []\n\n if (giftType === 2) {\n // gift_type 2 (\u5168\u9009\u6A21\u5F0F) - \u9009\u4E2D\u6240\u6709\u8D60\u54C1\n return gifts.map((gift: FreeGift) => gift.id)\n } else {\n // gift_type 1 (\u5355\u9009\u6A21\u5F0F) - \u9ED8\u8BA4\u9009\u4E2D\u7B2C\u4E00\u4E2A\u8D60\u54C1\n return [gifts[0].id]\n }\n })\n\n // \u751F\u6210\u5E26\u6709\u9009\u62E9\u72B6\u6001\u7684\u8D60\u54C1\u5217\u8868\u7528\u4E8E\u6E32\u67D3\n const giftsWithSelection = React.useMemo(() => {\n if (!gifts) return []\n\n return gifts.map((gift: FreeGift) => ({\n ...gift,\n selected: selectedGiftIds.includes(gift.id),\n }))\n }, [gifts, selectedGiftIds])\n\n // \u5F53 gifts \u6216 giftType \u66F4\u65B0\u65F6\uFF0C\u540C\u6B65\u66F4\u65B0\u5185\u90E8\u72B6\u6001\n React.useEffect(() => {\n if (!gifts || gifts.length === 0) {\n setSelectedGiftIds([])\n return\n }\n\n if (giftType === 2) {\n // gift_type 2 (\u5168\u9009\u6A21\u5F0F) - \u9009\u4E2D\u6240\u6709\u8D60\u54C1\n setSelectedGiftIds(gifts.map((gift: FreeGift) => gift.id))\n } else {\n // gift_type 1 (\u5355\u9009\u6A21\u5F0F) - \u667A\u80FD\u72B6\u6001\u7BA1\u7406\n setSelectedGiftIds(prevSelectedIds => {\n // \u68C0\u67E5\u5F53\u524D\u9009\u4E2D\u7684\u793C\u54C1\u662F\u5426\u4ECD\u7136\u5B58\u5728\u4E8E\u65B0\u7684 gifts \u5217\u8868\u4E2D\n const currentSelectedId = prevSelectedIds[0]\n const isCurrentSelectionValid =\n currentSelectedId && gifts.some((gift: FreeGift) => gift.id === currentSelectedId)\n\n // \u5982\u679C\u5F53\u524D\u9009\u4E2D\u72B6\u6001\u4ECD\u7136\u6709\u6548\uFF0C\u4FDD\u6301\u4E0D\u53D8\uFF1B\u5426\u5219\u9ED8\u8BA4\u9009\u4E2D\u7B2C\u4E00\u4E2A\n return isCurrentSelectionValid ? [currentSelectedId] : [gifts[0].id]\n })\n }\n }, [gifts, giftType])\n\n // \u6784\u9020\u5B8C\u6574\u7684\u4EA7\u54C1\u6570\u636E\u7528\u4E8E\u56DE\u8C03\n const fullProductData: ProductCardData = React.useMemo(\n () => ({\n ...productData,\n gifts,\n gift_type: giftType,\n }),\n [productData, gifts, giftType]\n )\n\n const handleGiftClick = (gift: FreeGift) => {\n // gift_type 2 (\u5168\u9009\u6A21\u5F0F) - \u4E0D\u5141\u8BB8\u53D6\u6D88\u9009\u62E9\uFF0C\u76F4\u63A5\u8FD4\u56DE\n if (giftType === 2) {\n // \u83B7\u53D6\u5F53\u524D\u6240\u6709\u9009\u4E2D\u7684gifts\u4F5C\u4E3A\u7B2C\u4E8C\u4E2A\u53C2\u6570\n const currentSelectedGifts = giftsWithSelection.filter((g: FreeGiftWithSelection) => g.selected)\n onGiftClick?.(gift, currentSelectedGifts)\n return\n }\n\n // gift_type 1 (\u5355\u9009\u6A21\u5F0F)\n setSelectedGiftIds(() => {\n const newSelectedIds = [gift.id] // \u5355\u9009\uFF1A\u59CB\u7EC8\u9009\u4E2D\u5F53\u524D\u9879\uFF0C\u70B9\u51FB\u5DF2\u9009\u4E2D\u9879\u4FDD\u6301\u72B6\u6001\uFF0C\u70B9\u51FB\u672A\u9009\u4E2D\u9879\u5207\u6362\u5230\u8BE5\u9879\n\n // \u8BA1\u7B97\u65B0\u7684\u9009\u4E2Dgifts\u4F5C\u4E3A\u7B2C\u4E8C\u4E2A\u53C2\u6570\u4F20\u9012\u7ED9\u56DE\u8C03\n const newSelectedGifts = gifts?.filter((g: FreeGift) => newSelectedIds.includes(g.id)) || []\n\n // \u8C03\u7528\u56DE\u8C03\u51FD\u6570\uFF0C\u7B2C\u4E8C\u4E2A\u53C2\u6570\u662F\u5F53\u524D\u9009\u4E2D\u7684gifts\n onGiftClick?.(gift, newSelectedGifts)\n onGiftSelectionChange?.(newSelectedGifts, fullProductData)\n\n return newSelectedIds\n })\n }\n\n const hasClickHandler = !!(onProductImageClick ?? onProductClick)\n const productHref = `/products/${productData.handle}`\n\n const handleProductImageClick = () => {\n const callback = onProductImageClick ?? onProductClick\n callback?.(fullProductData)\n }\n\n const handleLearnMoreClick = async () => {\n const selectedGifts = giftsWithSelection.filter(gift => gift.selected)\n setLearnMoreLoading(true)\n try {\n await onLearnMore?.(fullProductData, selectedGifts)\n } finally {\n setLearnMoreLoading(false)\n }\n }\n\n const handleShopNowClick = async () => {\n const selectedGifts = giftsWithSelection.filter(gift => gift.selected)\n setShopNowLoading(true)\n try {\n await onShopNow?.(fullProductData, selectedGifts)\n } finally {\n setShopNowLoading(false)\n }\n }\n\n return (\n <div\n ref={ref}\n className={cn(\n 'bg-container-primary rounded-box flex items-stretch overflow-hidden',\n // \u6839\u636E\u5E03\u5C40\u6A21\u5F0F\u8C03\u6574\u5BB9\u5668\n layout === 'horizontal'\n ? [\n 'laptop:flex-row lg-desktop:min-h-[560px] desktop:min-h-[448px] tablet:min-h-[526px] min-h-[610px] flex-col',\n 'laptop:col-span-2',\n ]\n : ['flex-col justify-between'],\n className\n )}\n {...props}\n >\n {/* \u4EA7\u54C1\u56FE\u7247\u533A\u57DF */}\n <ProductImage\n images={sceneImages}\n name={productData.name}\n layout={layout}\n tags={productData.tags || tags}\n onClick={hasClickHandler ? handleProductImageClick : undefined}\n href={hasClickHandler ? undefined : productHref}\n />\n\n {/* \u4EA7\u54C1\u4FE1\u606F\u533A\u57DF */}\n <div\n className={cn(\n 'bg-container-primary desktop:p-6 flex flex-col justify-between p-4',\n // \u6839\u636E\u5E03\u5C40\u6A21\u5F0F\u8C03\u6574\u5706\u89D2\u548C\u5C3A\u5BF8\n layout === 'horizontal'\n ? [\n 'rounded-r-box laptop:rounded-r-box tablet:rounded-b-box tablet:rounded-l-none',\n // \u4F7F\u7528 flex-basis \u8BBE\u7F6E\u5BBD\u5EA6\u6BD4\u4F8B\n 'laptop:basis-[39.1%]', // 360px / 921px \u2248 39.1%\n 'desktop:basis-[42.1%]', // 552px / 1312px \u2248 42.1%\n 'lg-desktop:basis-[42.1%]', // 700px / 1664px \u2248 42.1%\n 'shrink-0',\n ]\n : ['rounded-b-box', 'w-full', 'grow']\n )}\n >\n <div className=\"flex flex-1 flex-col justify-between gap-6\">\n {/* \u4EA7\u54C1\u6807\u9898\u548C\u63CF\u8FF0 */}\n <ProductInfo\n name={productData.name}\n onClick={hasClickHandler ? handleProductImageClick : undefined}\n href={hasClickHandler ? undefined : productHref}\n description={productData.description}\n classNames={classNames}\n />\n\n {/* \u514D\u8D39\u8D60\u54C1\u533A\u57DF */}\n <GiftSelection\n freeGiftLabel={productData.freeGiftLabel}\n freeGifts={giftsWithSelection}\n onGiftClick={handleGiftClick}\n giftType={giftType}\n selectedGiftSku={selectedGiftSku}\n theme={theme}\n />\n <PriceAndActions\n currentPrice={productData.currentPrice ?? ''}\n originalPrice={productData.originalPrice}\n priceLabel={productData.priceLabel}\n learnMoreText={productData.learnMoreText}\n shopNowText={productData.shopNowText}\n soldOutText={soldOutText}\n onLearnMore={handleLearnMoreClick}\n onShopNow={handleShopNowClick}\n availableForSale={productData.availableForSale}\n learnMoreLoading={learnMoreLoading}\n shopNowLoading={shopNowLoading}\n trackingTitle={productData.name}\n trackingDescription={productData.description}\n trackingSku={productData.sku}\n classNames={classNames}\n renderOriginalPrice={renderOriginalPrice}\n />\n </div>\n </div>\n </div>\n )\n }\n)\n\nProductCard.displayName = 'BuyOneGetOneShelf.ProductCard'\n\nexport default ProductCard\n"],
5
+ "mappings": "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",
6
+ "names": ["ProductCard_exports", "__export", "ProductCard_default", "__toCommonJS", "import_jsx_runtime", "React", "import_helpers", "import_ProductImage", "import_ProductInfo", "import_GiftSelection", "import_PriceAndActions", "import_context", "ProductCard", "productData", "gifts", "giftType", "selectedGiftSku", "sceneImages", "tags", "layoutProp", "className", "onProductClick", "onProductImageClick", "onLearnMore", "onShopNow", "onGiftClick", "onGiftSelectionChange", "classNames", "soldOutText", "renderOriginalPrice", "props", "ref", "contextLayout", "theme", "layout", "learnMoreLoading", "setLearnMoreLoading", "shopNowLoading", "setShopNowLoading", "selectedGiftIds", "setSelectedGiftIds", "gift", "giftsWithSelection", "prevSelectedIds", "currentSelectedId", "fullProductData", "handleGiftClick", "currentSelectedGifts", "g", "newSelectedIds", "newSelectedGifts", "hasClickHandler", "productHref", "handleProductImageClick", "handleLearnMoreClick", "selectedGifts", "handleShopNowClick", "ProductImage", "ProductInfo", "GiftSelection", "PriceAndActions"]
7
7
  }
@@ -221,6 +221,12 @@ export interface BuyOneGetOneShelfCardProps extends Omit<React.HTMLAttributes<HT
221
221
  onGiftSelectionChange?: (selectedGifts: FreeGift[], product: ProductCardData) => void;
222
222
  /** 选中赠品SKU变化回调(受控组件) */
223
223
  onSelectedGiftSkuChange?: (selectedSku: string | null) => void;
224
+ /**
225
+ * 原价区域渲染函数,用于在原价位置展示自定义内容(如 Save 金额文案)。
226
+ * 不传时使用默认的原价渲染(划线价)。
227
+ * @param originalPrice - 格式化后的原价文本
228
+ */
229
+ renderOriginalPrice?: (originalPrice: string | undefined) => React.ReactNode;
224
230
  }
225
231
  export interface BuyOneGetOneShelfLegacyProps extends React.HTMLAttributes<HTMLDivElement> {
226
232
  /** 业务数据 */
@@ -1,2 +1,2 @@
1
- "use strict";var o=Object.defineProperty;var a=Object.getOwnPropertyDescriptor;var s=Object.getOwnPropertyNames;var c=Object.prototype.hasOwnProperty;var d=(t,e,n,i)=>{if(e&&typeof e=="object"||typeof e=="function")for(let r of s(e))!c.call(t,r)&&r!==n&&o(t,r,{get:()=>e[r],enumerable:!(i=a(e,r))||i.enumerable});return t};var l=t=>d(o({},"__esModule",{value:!0}),t);var g={};module.exports=l(g);var p=require("react");
1
+ "use strict";var n=Object.defineProperty;var a=Object.getOwnPropertyDescriptor;var s=Object.getOwnPropertyNames;var c=Object.prototype.hasOwnProperty;var d=(t,e,o,i)=>{if(e&&typeof e=="object"||typeof e=="function")for(let r of s(e))!c.call(t,r)&&r!==o&&n(t,r,{get:()=>e[r],enumerable:!(i=a(e,r))||i.enumerable});return t};var g=t=>d(n({},"__esModule",{value:!0}),t);var l={};module.exports=g(l);var p=require("react");
2
2
  //# sourceMappingURL=types.js.map
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../../../src/biz-components/BuyOneGetOneShelf/types.ts"],
4
- "sourcesContent": ["import * as React from 'react'\nimport type { Theme } from '../../types/props'\n\n/**\n * \u514D\u8D39\u8D60\u54C1\u63A5\u53E3\n */\nexport interface FreeGift {\n /** \u8D60\u54C1ID */\n id: string\n /** \u8D60\u54C1\u56FE\u7247URL */\n image: string\n /** \u8D60\u54C1\u540D\u79F0 */\n name: string\n /** \u539F\u4EF7 */\n originalPrice: string\n /** \u73B0\u4EF7\uFF08\u901A\u5E38\u4E3AFree\uFF09 */\n currentPrice: string\n /** \u6570\u91CF */\n quantity: number\n /** \u53D8\u4F53ID */\n variantId: string\n /** SKU */\n sku: string\n /** \u53E5\u67C4 */\n handle: string\n /** \u8D60\u54C1tag */\n tag?: string\n}\n\n/**\n * \u5E26\u9009\u62E9\u72B6\u6001\u7684\u514D\u8D39\u8D60\u54C1\u63A5\u53E3\n */\nexport interface FreeGiftWithSelection extends FreeGift {\n /** \u662F\u5426\u5DF2\u9009\u4E2D */\n selected?: boolean\n}\n\n/**\n * \u4EA7\u54C1\u6807\u7B7E\u63A5\u53E3\n */\nexport interface ProductTag {\n /** \u6807\u7B7E\u6587\u672C */\n label: string\n /** \u6807\u7B7E\u6837\u5F0F\u53D8\u4F53 */\n variant: 'outline' | 'fill' | 'promotional'\n /** \u4FC3\u9500\u7C7B\u578B\uFF08\u4EC5\u5F53 variant \u4E3A 'promotional' \u65F6\u6709\u6548\uFF09 */\n promotionalType?: 'plus-member' | 'regular-member' | 'regular-discount' | 'time-limited-discount'\n}\n\n// Root \u7EC4\u4EF6\u76F8\u5173\u7684\u8BED\u4E49\u7C7B\u540D\nexport type BuyOneGetOneShelfRootSemanticName = 'root' | 'title' | 'description' | 'content' | 'viewMoreBtn'\n\n// ProductCard \u7EC4\u4EF6\u76F8\u5173\u7684\u8BED\u4E49\u7C7B\u540D\nexport type BuyOneGetOneShelfProductCardSemanticName =\n | 'productCard'\n | 'productCardImage'\n | 'productCardTitle'\n | 'productCardDescription'\n | 'productCardPriceLabel'\n | 'productCardPrice'\n | 'productCardOriginalPrice'\n | 'productCardGiftsContainer'\n | 'productCardBtnGroup'\n\n// \u5B8C\u6574\u7684\u8BED\u4E49\u7C7B\u540D\uFF08\u5411\u540E\u517C\u5BB9\uFF09\nexport type BuyOneGetOneShelfSemanticName = BuyOneGetOneShelfRootSemanticName | BuyOneGetOneShelfProductCardSemanticName\n\n/**\n * \u54CD\u5E94\u5F0F\u56FE\u7247\u63A5\u53E3\n */\nexport interface ResponsiveImage {\n id: number\n baseUrl?: string\n url: string\n thumbnailURL?: string\n filename?: string\n mimeType?: string\n width?: number\n height?: number\n}\n\n/**\n * \u54CD\u5E94\u5F0F\u56FE\u7247\u96C6\u5408\u63A5\u53E3\n */\nexport interface ResponsiveImages {\n laptop?: ResponsiveImage\n mobile?: ResponsiveImage\n tablet?: ResponsiveImage\n desktop?: ResponsiveImage\n lgDesktop?: ResponsiveImage\n}\n\n/**\n * \u4EA7\u54C1\u57FA\u7840\u6570\u636E\u63A5\u53E3\n */\nexport interface BaseProductData {\n sku: string\n name: string\n image: string\n value: string\n handle: string\n shopify_id: string\n}\n\nexport interface WithGiftData {\n /**\n * \u8D60\u54C1\n */\n gifts: FreeGift[]\n /**\n * \u8D60\u54C1\u7C7B\u578B 1-> \u8D60\u9001\u5176\u4E2D\u4E00\u4E2A\u8D60\u54C1\uFF0C 2 -> \u8D60\u9001\u6240\u6709\u8D60\u54C1\n */\n gift_type: 1 | 2\n}\n\n/**\n * \u7EAF\u4EA7\u54C1\u6570\u636E\u63A5\u53E3\uFF08\u4E0D\u5305\u542B\u8D60\u54C1\u4FE1\u606F\uFF09\n */\nexport interface PureProductData extends BaseProductData {\n /** \u4EA7\u54C1\u63CF\u8FF0 */\n description?: string\n /** \u5F53\u524D\u4EF7\u683C */\n currentPrice?: string\n /** \u539F\u4EF7 */\n originalPrice?: string\n /** \u4EF7\u683C\u6807\u7B7E\u6587\u672C\uFF08\u5982 \"Plus Member Price\"\uFF09 */\n priceLabel?: string\n /** \u4E86\u89E3\u66F4\u591A\u6309\u94AE\u6587\u672C */\n learnMoreText?: string\n /** \u7ACB\u5373\u8D2D\u4E70\u6309\u94AE\u6587\u672C */\n shopNowText?: string\n /** \u8D60\u54C1\u6807\u7B7E\u6587\u672C */\n freeGiftLabel?: string\n /** \u4EA7\u54C1\u6807\u7B7E */\n tags?: ProductTag[]\n /** \u8D60\u54C1\u9009\u62E9\u6A21\u5F0F */\n giftSelectionMode?: 'single' | 'multiple'\n availableForSale: boolean\n}\n\nexport interface ProductData extends BaseProductData, WithGiftData {\n /** \u4EA7\u54C1\u63CF\u8FF0 */\n description?: string\n /** \u5F53\u524D\u4EF7\u683C */\n currentPrice?: string\n /** \u539F\u4EF7 */\n originalPrice?: string\n /** \u4E86\u89E3\u66F4\u591A\u6309\u94AE\u6587\u672C */\n learnMoreText?: string\n /** \u7ACB\u5373\u8D2D\u4E70\u6309\u94AE\u6587\u672C */\n shopNowText?: string\n /** \u8D60\u54C1\u6807\u7B7E\u6587\u672C */\n freeGiftLabel?: string\n /** \u8D60\u54C1\u9009\u62E9\u6A21\u5F0F */\n giftSelectionMode?: 'single' | 'multiple'\n}\n\n// Alias for consistency with other components\nexport type ProductCardData = ProductData\n\n/**\n * \u6587\u6848\u914D\u7F6E\u63A5\u53E3\n */\nexport interface CopyConfig {\n shopNowText: string\n freeGiftLabel: string\n learnMoreText: string\n freeGiftHeading: string\n soldOutText?: string\n}\n\n/**\n * \u4E70\u8D60\u9879\u76EE\u63A5\u53E3\n */\nexport interface BogoItem {\n id: string\n data: ProductData[]\n images: ResponsiveImages\n shopNowFun: string\n shopNowText: string\n learnMoreText: string\n layout?: 'horizontal' | 'vertical'\n}\n\n/**\n * BuyOneGetOneShelf \u4E1A\u52A1\u7EC4\u4EF6\u6570\u636E\u63A5\u53E3 - \u65B0\u683C\u5F0F\n */\nexport interface BuyOneGetOneShelfData {\n copy: CopyConfig\n theme: string\n title: string\n subtitle: string\n bogoItems: BogoItem[]\n /** \u8D85\u8FC7\u6B64\u6570\u91CF\u7684\u5546\u54C1\u65F6\u663E\u793A\"View More/View Less\"\u6309\u94AE\uFF0C\u9ED8\u8BA4 4 */\n viewMoreThreshold?: number\n /** View More \u6309\u94AE\u6587\u6848\uFF0C\u9ED8\u8BA4 'View More' */\n viewMoreText?: string\n /** View Less \u6309\u94AE\u6587\u6848\uFF0C\u9ED8\u8BA4 'View Less' */\n viewLessText?: string\n}\n\n// Root \u7EC4\u4EF6 Props\uFF08\u65B0\u7684\u7EC4\u5408\u5F0F\u8BBE\u8BA1\uFF09\nexport interface BuyOneGetOneShelfProps extends React.HTMLAttributes<HTMLDivElement> {\n /** \u6807\u9898 */\n title?: string\n /** \u526F\u6807\u9898 */\n subtitle?: string\n theme?: Theme\n /** \u5B50\u7EC4\u4EF6 */\n children: React.ReactNode\n /** Root \u7EC4\u4EF6\u7684\u81EA\u5B9A\u4E49\u7C7B\u540D */\n classNames?: Partial<Record<BuyOneGetOneShelfRootSemanticName, string>>\n /** \u8D85\u8FC7\u6B64\u6570\u91CF\u7684\u5546\u54C1\u65F6\u663E\u793A\"View More/View Less\"\u6309\u94AE\uFF0C\u9ED8\u8BA4 4 */\n viewMoreThreshold?: number\n /** View More \u6309\u94AE\u6587\u6848\uFF0C\u9ED8\u8BA4 'View More' */\n viewMoreText?: string\n /** View Less \u6309\u94AE\u6587\u6848\uFF0C\u9ED8\u8BA4 'View Less' */\n viewLessText?: string\n}\n\n// \u5361\u7247\u7EC4\u4EF6Props - \u57FA\u4E8EProductCardProps\u4F46\u7B80\u5316\nexport interface BuyOneGetOneShelfCardProps extends Omit<React.HTMLAttributes<HTMLDivElement>, 'onClick'> {\n /** \u4EA7\u54C1\u6570\u636E */\n productData: BaseProductData & {\n description?: string\n currentPrice?: string\n originalPrice?: string\n learnMoreText?: string\n shopNowText?: string\n freeGiftLabel?: string\n }\n /** \u8D60\u54C1\u5217\u8868 */\n gifts?: FreeGift[]\n /** \u8D60\u54C1\u7C7B\u578B 1-> \u8D60\u9001\u5176\u4E2D\u4E00\u4E2A\u8D60\u54C1\uFF0C 2 -> \u8D60\u9001\u6240\u6709\u8D60\u54C1 */\n giftType?: 1 | 2\n soldOutText?: string\n /** \u573A\u666F\u56FE\u7247 */\n sceneImages?: ResponsiveImages\n /** @deprecated Layout is now automatically inferred by Root based on children count. */\n layout?: 'horizontal' | 'vertical'\n /** ProductCard \u7EC4\u4EF6\u7684\u81EA\u5B9A\u4E49\u7C7B\u540D */\n classNames?: Partial<Record<BuyOneGetOneShelfProductCardSemanticName, string>>\n /** @deprecated Use `onProductImageClick` instead. */\n onProductClick?: (product: ProductCardData) => void\n /** \u4EA7\u54C1\u56FE\u7247\u70B9\u51FB\u56DE\u8C03 */\n onProductImageClick?: (product: ProductCardData) => void\n /** Learn More \u70B9\u51FB\u56DE\u8C03 */\n onLearnMore?: (product: ProductCardData, selectedGifts: FreeGift[]) => void\n /** Shop Now \u70B9\u51FB\u56DE\u8C03 */\n onShopNow?: (product: ProductCardData, selectedGifts: FreeGift[]) => void\n /** \u8D60\u54C1\u70B9\u51FB\u56DE\u8C03 */\n onGiftClick?: (gift: FreeGift, selectedGifts: FreeGift[]) => void\n /** \u8D60\u54C1\u9009\u62E9\u53D8\u5316\u56DE\u8C03 */\n onGiftSelectionChange?: (selectedGifts: FreeGift[], product: ProductCardData) => void\n /** \u9009\u4E2D\u8D60\u54C1SKU\u53D8\u5316\u56DE\u8C03\uFF08\u53D7\u63A7\u7EC4\u4EF6\uFF09 */\n onSelectedGiftSkuChange?: (selectedSku: string | null) => void\n}\n\n// \u4FDD\u6301\u5411\u540E\u517C\u5BB9\u7684\u4F20\u7EDFProps\nexport interface BuyOneGetOneShelfLegacyProps extends React.HTMLAttributes<HTMLDivElement> {\n /** \u4E1A\u52A1\u6570\u636E */\n data: BuyOneGetOneShelfData\n /** @deprecated Use `onProductImageClick` instead. */\n onProductClick?: (product: ProductCardData) => void\n /** \u4EA7\u54C1\u56FE\u7247\u70B9\u51FB\u56DE\u8C03 */\n onProductImageClick?: (product: ProductCardData) => void\n /** Learn More\u6309\u94AE\u70B9\u51FB\u4E8B\u4EF6 */\n onLearnMore?: (product: ProductCardData, selectedGifts: FreeGift[]) => void\n /** Shop Now\u6309\u94AE\u70B9\u51FB\u4E8B\u4EF6 */\n onShopNow?: (product: ProductCardData, selectedGifts: FreeGift[]) => void\n onAddToCart?: (product: ProductCardData) => void\n /** \u8D60\u54C1\u70B9\u51FB\u4E8B\u4EF6 */\n onGiftClick?: (gift: FreeGift, selectedGifts: FreeGift[]) => void\n /** \u8D60\u54C1\u9009\u62E9\u53D8\u5316\u4E8B\u4EF6 */\n onGiftSelectionChange?: (selectedGifts: FreeGift[], product: ProductCardData) => void\n classNames?: Partial<Record<BuyOneGetOneShelfSemanticName, string>>\n}\n"],
4
+ "sourcesContent": ["import * as React from 'react'\nimport type { Theme } from '../../types/props'\n\n/**\n * \u514D\u8D39\u8D60\u54C1\u63A5\u53E3\n */\nexport interface FreeGift {\n /** \u8D60\u54C1ID */\n id: string\n /** \u8D60\u54C1\u56FE\u7247URL */\n image: string\n /** \u8D60\u54C1\u540D\u79F0 */\n name: string\n /** \u539F\u4EF7 */\n originalPrice: string\n /** \u73B0\u4EF7\uFF08\u901A\u5E38\u4E3AFree\uFF09 */\n currentPrice: string\n /** \u6570\u91CF */\n quantity: number\n /** \u53D8\u4F53ID */\n variantId: string\n /** SKU */\n sku: string\n /** \u53E5\u67C4 */\n handle: string\n /** \u8D60\u54C1tag */\n tag?: string\n}\n\n/**\n * \u5E26\u9009\u62E9\u72B6\u6001\u7684\u514D\u8D39\u8D60\u54C1\u63A5\u53E3\n */\nexport interface FreeGiftWithSelection extends FreeGift {\n /** \u662F\u5426\u5DF2\u9009\u4E2D */\n selected?: boolean\n}\n\n/**\n * \u4EA7\u54C1\u6807\u7B7E\u63A5\u53E3\n */\nexport interface ProductTag {\n /** \u6807\u7B7E\u6587\u672C */\n label: string\n /** \u6807\u7B7E\u6837\u5F0F\u53D8\u4F53 */\n variant: 'outline' | 'fill' | 'promotional'\n /** \u4FC3\u9500\u7C7B\u578B\uFF08\u4EC5\u5F53 variant \u4E3A 'promotional' \u65F6\u6709\u6548\uFF09 */\n promotionalType?: 'plus-member' | 'regular-member' | 'regular-discount' | 'time-limited-discount'\n}\n\n// Root \u7EC4\u4EF6\u76F8\u5173\u7684\u8BED\u4E49\u7C7B\u540D\nexport type BuyOneGetOneShelfRootSemanticName = 'root' | 'title' | 'description' | 'content' | 'viewMoreBtn'\n\n// ProductCard \u7EC4\u4EF6\u76F8\u5173\u7684\u8BED\u4E49\u7C7B\u540D\nexport type BuyOneGetOneShelfProductCardSemanticName =\n | 'productCard'\n | 'productCardImage'\n | 'productCardTitle'\n | 'productCardDescription'\n | 'productCardPriceLabel'\n | 'productCardPrice'\n | 'productCardOriginalPrice'\n | 'productCardGiftsContainer'\n | 'productCardBtnGroup'\n\n// \u5B8C\u6574\u7684\u8BED\u4E49\u7C7B\u540D\uFF08\u5411\u540E\u517C\u5BB9\uFF09\nexport type BuyOneGetOneShelfSemanticName = BuyOneGetOneShelfRootSemanticName | BuyOneGetOneShelfProductCardSemanticName\n\n/**\n * \u54CD\u5E94\u5F0F\u56FE\u7247\u63A5\u53E3\n */\nexport interface ResponsiveImage {\n id: number\n baseUrl?: string\n url: string\n thumbnailURL?: string\n filename?: string\n mimeType?: string\n width?: number\n height?: number\n}\n\n/**\n * \u54CD\u5E94\u5F0F\u56FE\u7247\u96C6\u5408\u63A5\u53E3\n */\nexport interface ResponsiveImages {\n laptop?: ResponsiveImage\n mobile?: ResponsiveImage\n tablet?: ResponsiveImage\n desktop?: ResponsiveImage\n lgDesktop?: ResponsiveImage\n}\n\n/**\n * \u4EA7\u54C1\u57FA\u7840\u6570\u636E\u63A5\u53E3\n */\nexport interface BaseProductData {\n sku: string\n name: string\n image: string\n value: string\n handle: string\n shopify_id: string\n}\n\nexport interface WithGiftData {\n /**\n * \u8D60\u54C1\n */\n gifts: FreeGift[]\n /**\n * \u8D60\u54C1\u7C7B\u578B 1-> \u8D60\u9001\u5176\u4E2D\u4E00\u4E2A\u8D60\u54C1\uFF0C 2 -> \u8D60\u9001\u6240\u6709\u8D60\u54C1\n */\n gift_type: 1 | 2\n}\n\n/**\n * \u7EAF\u4EA7\u54C1\u6570\u636E\u63A5\u53E3\uFF08\u4E0D\u5305\u542B\u8D60\u54C1\u4FE1\u606F\uFF09\n */\nexport interface PureProductData extends BaseProductData {\n /** \u4EA7\u54C1\u63CF\u8FF0 */\n description?: string\n /** \u5F53\u524D\u4EF7\u683C */\n currentPrice?: string\n /** \u539F\u4EF7 */\n originalPrice?: string\n /** \u4EF7\u683C\u6807\u7B7E\u6587\u672C\uFF08\u5982 \"Plus Member Price\"\uFF09 */\n priceLabel?: string\n /** \u4E86\u89E3\u66F4\u591A\u6309\u94AE\u6587\u672C */\n learnMoreText?: string\n /** \u7ACB\u5373\u8D2D\u4E70\u6309\u94AE\u6587\u672C */\n shopNowText?: string\n /** \u8D60\u54C1\u6807\u7B7E\u6587\u672C */\n freeGiftLabel?: string\n /** \u4EA7\u54C1\u6807\u7B7E */\n tags?: ProductTag[]\n /** \u8D60\u54C1\u9009\u62E9\u6A21\u5F0F */\n giftSelectionMode?: 'single' | 'multiple'\n availableForSale: boolean\n}\n\nexport interface ProductData extends BaseProductData, WithGiftData {\n /** \u4EA7\u54C1\u63CF\u8FF0 */\n description?: string\n /** \u5F53\u524D\u4EF7\u683C */\n currentPrice?: string\n /** \u539F\u4EF7 */\n originalPrice?: string\n /** \u4E86\u89E3\u66F4\u591A\u6309\u94AE\u6587\u672C */\n learnMoreText?: string\n /** \u7ACB\u5373\u8D2D\u4E70\u6309\u94AE\u6587\u672C */\n shopNowText?: string\n /** \u8D60\u54C1\u6807\u7B7E\u6587\u672C */\n freeGiftLabel?: string\n /** \u8D60\u54C1\u9009\u62E9\u6A21\u5F0F */\n giftSelectionMode?: 'single' | 'multiple'\n}\n\n// Alias for consistency with other components\nexport type ProductCardData = ProductData\n\n/**\n * \u6587\u6848\u914D\u7F6E\u63A5\u53E3\n */\nexport interface CopyConfig {\n shopNowText: string\n freeGiftLabel: string\n learnMoreText: string\n freeGiftHeading: string\n soldOutText?: string\n}\n\n/**\n * \u4E70\u8D60\u9879\u76EE\u63A5\u53E3\n */\nexport interface BogoItem {\n id: string\n data: ProductData[]\n images: ResponsiveImages\n shopNowFun: string\n shopNowText: string\n learnMoreText: string\n layout?: 'horizontal' | 'vertical'\n}\n\n/**\n * BuyOneGetOneShelf \u4E1A\u52A1\u7EC4\u4EF6\u6570\u636E\u63A5\u53E3 - \u65B0\u683C\u5F0F\n */\nexport interface BuyOneGetOneShelfData {\n copy: CopyConfig\n theme: string\n title: string\n subtitle: string\n bogoItems: BogoItem[]\n /** \u8D85\u8FC7\u6B64\u6570\u91CF\u7684\u5546\u54C1\u65F6\u663E\u793A\"View More/View Less\"\u6309\u94AE\uFF0C\u9ED8\u8BA4 4 */\n viewMoreThreshold?: number\n /** View More \u6309\u94AE\u6587\u6848\uFF0C\u9ED8\u8BA4 'View More' */\n viewMoreText?: string\n /** View Less \u6309\u94AE\u6587\u6848\uFF0C\u9ED8\u8BA4 'View Less' */\n viewLessText?: string\n}\n\n// Root \u7EC4\u4EF6 Props\uFF08\u65B0\u7684\u7EC4\u5408\u5F0F\u8BBE\u8BA1\uFF09\nexport interface BuyOneGetOneShelfProps extends React.HTMLAttributes<HTMLDivElement> {\n /** \u6807\u9898 */\n title?: string\n /** \u526F\u6807\u9898 */\n subtitle?: string\n theme?: Theme\n /** \u5B50\u7EC4\u4EF6 */\n children: React.ReactNode\n /** Root \u7EC4\u4EF6\u7684\u81EA\u5B9A\u4E49\u7C7B\u540D */\n classNames?: Partial<Record<BuyOneGetOneShelfRootSemanticName, string>>\n /** \u8D85\u8FC7\u6B64\u6570\u91CF\u7684\u5546\u54C1\u65F6\u663E\u793A\"View More/View Less\"\u6309\u94AE\uFF0C\u9ED8\u8BA4 4 */\n viewMoreThreshold?: number\n /** View More \u6309\u94AE\u6587\u6848\uFF0C\u9ED8\u8BA4 'View More' */\n viewMoreText?: string\n /** View Less \u6309\u94AE\u6587\u6848\uFF0C\u9ED8\u8BA4 'View Less' */\n viewLessText?: string\n}\n\n// \u5361\u7247\u7EC4\u4EF6Props - \u57FA\u4E8EProductCardProps\u4F46\u7B80\u5316\nexport interface BuyOneGetOneShelfCardProps extends Omit<React.HTMLAttributes<HTMLDivElement>, 'onClick'> {\n /** \u4EA7\u54C1\u6570\u636E */\n productData: BaseProductData & {\n description?: string\n currentPrice?: string\n originalPrice?: string\n learnMoreText?: string\n shopNowText?: string\n freeGiftLabel?: string\n }\n /** \u8D60\u54C1\u5217\u8868 */\n gifts?: FreeGift[]\n /** \u8D60\u54C1\u7C7B\u578B 1-> \u8D60\u9001\u5176\u4E2D\u4E00\u4E2A\u8D60\u54C1\uFF0C 2 -> \u8D60\u9001\u6240\u6709\u8D60\u54C1 */\n giftType?: 1 | 2\n soldOutText?: string\n /** \u573A\u666F\u56FE\u7247 */\n sceneImages?: ResponsiveImages\n /** @deprecated Layout is now automatically inferred by Root based on children count. */\n layout?: 'horizontal' | 'vertical'\n /** ProductCard \u7EC4\u4EF6\u7684\u81EA\u5B9A\u4E49\u7C7B\u540D */\n classNames?: Partial<Record<BuyOneGetOneShelfProductCardSemanticName, string>>\n /** @deprecated Use `onProductImageClick` instead. */\n onProductClick?: (product: ProductCardData) => void\n /** \u4EA7\u54C1\u56FE\u7247\u70B9\u51FB\u56DE\u8C03 */\n onProductImageClick?: (product: ProductCardData) => void\n /** Learn More \u70B9\u51FB\u56DE\u8C03 */\n onLearnMore?: (product: ProductCardData, selectedGifts: FreeGift[]) => void\n /** Shop Now \u70B9\u51FB\u56DE\u8C03 */\n onShopNow?: (product: ProductCardData, selectedGifts: FreeGift[]) => void\n /** \u8D60\u54C1\u70B9\u51FB\u56DE\u8C03 */\n onGiftClick?: (gift: FreeGift, selectedGifts: FreeGift[]) => void\n /** \u8D60\u54C1\u9009\u62E9\u53D8\u5316\u56DE\u8C03 */\n onGiftSelectionChange?: (selectedGifts: FreeGift[], product: ProductCardData) => void\n /** \u9009\u4E2D\u8D60\u54C1SKU\u53D8\u5316\u56DE\u8C03\uFF08\u53D7\u63A7\u7EC4\u4EF6\uFF09 */\n onSelectedGiftSkuChange?: (selectedSku: string | null) => void\n /**\n * \u539F\u4EF7\u533A\u57DF\u6E32\u67D3\u51FD\u6570\uFF0C\u7528\u4E8E\u5728\u539F\u4EF7\u4F4D\u7F6E\u5C55\u793A\u81EA\u5B9A\u4E49\u5185\u5BB9\uFF08\u5982 Save \u91D1\u989D\u6587\u6848\uFF09\u3002\n * \u4E0D\u4F20\u65F6\u4F7F\u7528\u9ED8\u8BA4\u7684\u539F\u4EF7\u6E32\u67D3\uFF08\u5212\u7EBF\u4EF7\uFF09\u3002\n * @param originalPrice - \u683C\u5F0F\u5316\u540E\u7684\u539F\u4EF7\u6587\u672C\n */\n renderOriginalPrice?: (originalPrice: string | undefined) => React.ReactNode\n}\n\n// \u4FDD\u6301\u5411\u540E\u517C\u5BB9\u7684\u4F20\u7EDFProps\nexport interface BuyOneGetOneShelfLegacyProps extends React.HTMLAttributes<HTMLDivElement> {\n /** \u4E1A\u52A1\u6570\u636E */\n data: BuyOneGetOneShelfData\n /** @deprecated Use `onProductImageClick` instead. */\n onProductClick?: (product: ProductCardData) => void\n /** \u4EA7\u54C1\u56FE\u7247\u70B9\u51FB\u56DE\u8C03 */\n onProductImageClick?: (product: ProductCardData) => void\n /** Learn More\u6309\u94AE\u70B9\u51FB\u4E8B\u4EF6 */\n onLearnMore?: (product: ProductCardData, selectedGifts: FreeGift[]) => void\n /** Shop Now\u6309\u94AE\u70B9\u51FB\u4E8B\u4EF6 */\n onShopNow?: (product: ProductCardData, selectedGifts: FreeGift[]) => void\n onAddToCart?: (product: ProductCardData) => void\n /** \u8D60\u54C1\u70B9\u51FB\u4E8B\u4EF6 */\n onGiftClick?: (gift: FreeGift, selectedGifts: FreeGift[]) => void\n /** \u8D60\u54C1\u9009\u62E9\u53D8\u5316\u4E8B\u4EF6 */\n onGiftSelectionChange?: (selectedGifts: FreeGift[], product: ProductCardData) => void\n classNames?: Partial<Record<BuyOneGetOneShelfSemanticName, string>>\n}\n"],
5
5
  "mappings": "+WAAA,IAAAA,EAAA,kBAAAC,EAAAD,GAAA,IAAAE,EAAuB",
6
6
  "names": ["types_exports", "__toCommonJS", "React"]
7
7
  }
@@ -71,6 +71,15 @@ export interface ProductCardProps {
71
71
  primaryButtonText?: string;
72
72
  primaryButtonFun?: ButtonFunctionType;
73
73
  showOriginalPrice?: boolean;
74
+ /**
75
+ * 原价区域渲染函数,用于在原价位置展示自定义内容(如 Save 金额文案)。
76
+ * 不传时使用默认的原价渲染(划线价)。
77
+ * @param product - 当前产品数据
78
+ * @param context - 渲染上下文(含 showOriginalPrice)
79
+ */
80
+ renderOriginalPrice?: (product: ProductCardData, context: {
81
+ showOriginalPrice?: boolean;
82
+ }) => React.ReactNode;
74
83
  copy?: CopyConfig;
75
84
  onProductImageClick?: (product: ProductCardData) => void;
76
85
  /** 主题 */
@@ -1,2 +1,2 @@
1
- "use strict";"use client";var R=Object.create;var g=Object.defineProperty;var V=Object.getOwnPropertyDescriptor;var q=Object.getOwnPropertyNames;var K=Object.getPrototypeOf,W=Object.prototype.hasOwnProperty;var I=(e,o)=>{for(var r in o)g(e,r,{get:o[r],enumerable:!0})},T=(e,o,r,m)=>{if(o&&typeof o=="object"||typeof o=="function")for(let l of q(o))!W.call(e,l)&&l!==r&&g(e,l,{get:()=>o[l],enumerable:!(m=V(o,l))||m.enumerable});return e};var J=(e,o,r)=>(r=e!=null?R(K(e)):{},T(o||!e||!e.__esModule?g(r,"default",{value:e,enumerable:!0}):r,e)),Q=e=>T(g({},"__esModule",{value:!0}),e);var Y={};I(Y,{ProductCard:()=>x,default:()=>X});module.exports=Q(Y);var t=require("react/jsx-runtime"),c=J(require("react")),i=require("../../helpers/index.js"),a=require("../../components/index.js"),B=require("../../shared/trackUrlRef.js"),u=require("../../shared/track.js"),L=require("../AiuiProvider/index.js");const x=c.forwardRef(({product:e,className:o,showTags:r=!0,onLearnMore:m,onShopNow:l,onAddToCart:_,classNames:n,secondaryButtonText:f,secondaryButtonFun:h,primaryButtonText:y,primaryButtonFun:k,showOriginalPrice:z,copy:D,onProductImageClick:v,theme:M="light",locale:P="us",index:d=0,tabName:w},H)=>{const[O,j]=c.useState(!1),[A,G]=c.useState(!1),{trackingData:U}=(0,L.useAiuiContext)(),p=U?.pageGroup,C=!e.soldOut,S=c.useCallback(async(s,b)=>{if(!s)return;const N=b==="primary"?j:G;N(!0);try{switch(s){case"buyNow":await l?.(e);break;case"addCart":await _?.(e);break;case"learnMore":await m?.(e.href);break}}finally{N(!1)}},[e,l,_,m]),E=c.useMemo(()=>(0,i.getLocalizedPath)((0,B.trackUrlRef)(e.href,p+"_shelf_scene_shelf_v3"),P),[e.href,p,P]),F=c.useCallback(()=>{v?.(e),(0,u.gaTrack)({event:"ga4Event",event_name:"select_item",item_list_name:"Scene_Shelf_3_Products",page_group:p,items:[{item_id:e.sku,item_name:e.title,item_variant:e.id,price:e.currentPrice,index:d}],tab_name:w,position:d})},[v,e,p,d,w]);return(0,t.jsx)(a.Card,{ref:H,className:(0,i.cn)("bg-container-primary flex h-full flex-col overflow-hidden border-none hover:bg-white",o,n?.productCard,{"hover:bg-container-secondary-0 ":M==="dark"}),children:(0,t.jsxs)(a.CardContent,{className:"desktop:p-6 relative flex flex-1 flex-col justify-between p-4",children:[(0,t.jsx)("div",{className:"product-image-wrapper lg-desktop:size-[196px] mx-auto size-[138px] cursor-pointer overflow-hidden",children:(0,t.jsx)("a",{onClick:F,...!v&&{href:E},rel:"noreferrer",children:(0,t.jsx)(a.Picture,{source:e.imageUrl,alt:e.imageAlt,className:"aspect-square size-full object-contain",imgClassName:"w-full h-full object-contain"})})}),(0,t.jsx)("div",{className:"lg-desktop:h-[28px] mb-1 flex h-[24px] gap-1",children:r&&e.tags?.map((s,b)=>(0,t.jsx)(a.Badge,{size:"sm",variant:s.variant||"outline",className:(0,i.cn)(s.variant==="promotional"?"ml-2":""),promotionalType:s.promotionalType,children:s.label},b))}),(0,t.jsxs)("div",{className:"flex h-full flex-1 grow flex-col justify-between",children:[(0,t.jsxs)("div",{className:"mb-4",children:[(0,t.jsx)(a.Heading,{as:"h3",size:2,className:(0,i.cn)("text-info-primary laptop:line-clamp-2 mb-2 line-clamp-3 min-h-[2.4em]",n?.productTitle),html:e.custom_name||e.title}),(e?.custom_description||e?.description)&&(0,t.jsx)(a.Text,{size:2,className:(0,i.cn)("text-info-secondary desktop:text-[16px] lg-desktop:text-[18px] line-clamp-1 text-[14px]",n?.productDescription),html:e.custom_description||e.description})]}),(0,t.jsxs)("div",{children:[(0,t.jsx)("div",{className:(0,i.cn)("mb-2",n?.productPrice),children:(0,t.jsx)("div",{className:(0,i.cn)("flex items-baseline gap-2",n?.priceWrapper),children:C?(0,t.jsxs)(t.Fragment,{children:[(0,t.jsx)(a.Heading,{size:2,className:"text-info-primary",as:"h6",children:e.currentPrice}),z&&e.originalPrice&&(0,t.jsx)(a.Heading,{size:2,className:(0,i.cn)("text-info-tertiary line-through",n?.originalPrice),as:"h6",children:e.originalPrice})]}):(0,t.jsx)(a.Heading,{size:2,className:"text-info-tertiary",children:D?.outOfStockLabel??"Sold Out"})})}),e?.priceLabel&&C&&(0,t.jsx)(a.Text,{size:4,className:(0,i.cn)("text-marketing-1 desktop:text-[16px] lg-desktop:text-[18px] mt-2 text-[14px]",n?.productPriceLabel),children:e.priceLabel}),(0,t.jsxs)("div",{className:(0,i.cn)("lg-desktop:gap-3 laptop:flex-row laptop:flex-nowrap flex flex-col flex-wrap gap-2",n?.buttonGroup),children:[f&&(0,t.jsx)(a.Button,{variant:"secondary",size:"base",className:(0,i.cn)("laptop:flex-1 laptop:min-w-0 laptop:whitespace-normal laptop:text-center w-full min-w-0 whitespace-normal text-center",n?.secondaryButton),onClick:()=>{S(h,"secondary"),(0,u.gaTrack)({event:"ga4Event",event_name:"component_click",event_parameters:{page_group:p||"Home Page",component_type:"copy",component_name:"scene_shelf_product",component_title:e.custom_name||e.title,component_description:e.custom_description||"",button_name:f,SKU:e.sku||"",position:d}})},disabled:e.soldOut&&h!=="learnMore",loading:A,children:f}),y&&(0,t.jsx)(a.Button,{variant:"primary",size:"base",className:(0,i.cn)("laptop:flex-1 laptop:min-w-0 laptop:whitespace-normal laptop:text-center w-full min-w-0 whitespace-normal text-center",n?.primaryButton),onClick:()=>{S(k,"primary"),(0,u.gaTrack)({event:"ga4Event",event_name:"component_click",event_parameters:{page_group:p||"Home Page",component_type:"copy",component_name:"scene_shelf_product",component_title:e.custom_name||e.title,component_description:e.custom_description||"",button_name:y,SKU:e.sku||"",position:d}})},disabled:e.soldOut&&k!=="learnMore",loading:O,children:y})]})]})]})]})})});x.displayName="SceneShelfV3.ProductCard";var X=x;
1
+ "use strict";"use client";var V=Object.create;var g=Object.defineProperty;var q=Object.getOwnPropertyDescriptor;var K=Object.getOwnPropertyNames;var W=Object.getPrototypeOf,I=Object.prototype.hasOwnProperty;var J=(e,i)=>{for(var r in i)g(e,r,{get:i[r],enumerable:!0})},L=(e,i,r,m)=>{if(i&&typeof i=="object"||typeof i=="function")for(let l of K(i))!I.call(e,l)&&l!==r&&g(e,l,{get:()=>i[l],enumerable:!(m=q(i,l))||m.enumerable});return e};var Q=(e,i,r)=>(r=e!=null?V(W(e)):{},L(i||!e||!e.__esModule?g(r,"default",{value:e,enumerable:!0}):r,e)),X=e=>L(g({},"__esModule",{value:!0}),e);var Z={};J(Z,{ProductCard:()=>x,default:()=>Y});module.exports=X(Z);var t=require("react/jsx-runtime"),c=Q(require("react")),o=require("../../helpers/index.js"),a=require("../../components/index.js"),z=require("../../shared/trackUrlRef.js"),u=require("../../shared/track.js"),D=require("../AiuiProvider/index.js");const x=c.forwardRef(({product:e,className:i,showTags:r=!0,onLearnMore:m,onShopNow:l,onAddToCart:_,classNames:n,secondaryButtonText:f,secondaryButtonFun:h,primaryButtonText:y,primaryButtonFun:P,showOriginalPrice:k,renderOriginalPrice:w,copy:M,onProductImageClick:v,theme:H="light",locale:C="us",index:d=0,tabName:S},O)=>{const[j,R]=c.useState(!1),[A,G]=c.useState(!1),{trackingData:U}=(0,D.useAiuiContext)(),p=U?.pageGroup,N=!e.soldOut,T=c.useCallback(async(s,b)=>{if(!s)return;const B=b==="primary"?R:G;B(!0);try{switch(s){case"buyNow":await l?.(e);break;case"addCart":await _?.(e);break;case"learnMore":await m?.(e.href);break}}finally{B(!1)}},[e,l,_,m]),E=c.useMemo(()=>(0,o.getLocalizedPath)((0,z.trackUrlRef)(e.href,p+"_shelf_scene_shelf_v3"),C),[e.href,p,C]),F=c.useCallback(()=>{v?.(e),(0,u.gaTrack)({event:"ga4Event",event_name:"select_item",item_list_name:"Scene_Shelf_3_Products",page_group:p,items:[{item_id:e.sku,item_name:e.title,item_variant:e.id,price:e.currentPrice,index:d}],tab_name:S,position:d})},[v,e,p,d,S]);return(0,t.jsx)(a.Card,{ref:O,className:(0,o.cn)("bg-container-primary flex h-full flex-col overflow-hidden border-none hover:bg-white",i,n?.productCard,{"hover:bg-container-secondary-0 ":H==="dark"}),children:(0,t.jsxs)(a.CardContent,{className:"desktop:p-6 relative flex flex-1 flex-col justify-between p-4",children:[(0,t.jsx)("div",{className:"product-image-wrapper lg-desktop:size-[196px] mx-auto size-[138px] cursor-pointer overflow-hidden",children:(0,t.jsx)("a",{onClick:F,...!v&&{href:E},rel:"noreferrer",children:(0,t.jsx)(a.Picture,{source:e.imageUrl,alt:e.imageAlt,className:"aspect-square size-full object-contain",imgClassName:"w-full h-full object-contain"})})}),(0,t.jsx)("div",{className:"lg-desktop:h-[28px] mb-1 flex h-[24px] gap-1",children:r&&e.tags?.map((s,b)=>(0,t.jsx)(a.Badge,{size:"sm",variant:s.variant||"outline",className:(0,o.cn)(s.variant==="promotional"?"ml-2":""),promotionalType:s.promotionalType,children:s.label},b))}),(0,t.jsxs)("div",{className:"flex h-full flex-1 grow flex-col justify-between",children:[(0,t.jsxs)("div",{className:"mb-4",children:[(0,t.jsx)(a.Heading,{as:"h3",size:2,className:(0,o.cn)("text-info-primary laptop:line-clamp-2 mb-2 line-clamp-3 min-h-[2.4em]",n?.productTitle),html:e.custom_name||e.title}),(e?.custom_description||e?.description)&&(0,t.jsx)(a.Text,{size:2,className:(0,o.cn)("text-info-secondary desktop:text-[16px] lg-desktop:text-[18px] line-clamp-1 text-[14px]",n?.productDescription),html:e.custom_description||e.description})]}),(0,t.jsxs)("div",{children:[(0,t.jsx)("div",{className:(0,o.cn)("mb-2",n?.productPrice),children:(0,t.jsx)("div",{className:(0,o.cn)("flex items-baseline gap-2",n?.priceWrapper),children:N?(0,t.jsxs)(t.Fragment,{children:[(0,t.jsx)(a.Heading,{size:2,className:"text-info-primary",as:"h6",children:e.currentPrice}),w?w(e,{showOriginalPrice:k}):k&&e.originalPrice&&(0,t.jsx)(a.Heading,{size:2,className:(0,o.cn)("text-info-tertiary line-through",n?.originalPrice),as:"h6",children:e.originalPrice})]}):(0,t.jsx)(a.Heading,{size:2,className:"text-info-tertiary",children:M?.outOfStockLabel??"Sold Out"})})}),e?.priceLabel&&N&&(0,t.jsx)(a.Text,{size:4,className:(0,o.cn)("text-marketing-1 desktop:text-[16px] lg-desktop:text-[18px] mt-2 text-[14px]",n?.productPriceLabel),children:e.priceLabel}),(0,t.jsxs)("div",{className:(0,o.cn)("lg-desktop:gap-3 laptop:flex-row laptop:flex-nowrap flex flex-col flex-wrap gap-2",n?.buttonGroup),children:[f&&(0,t.jsx)(a.Button,{variant:"secondary",size:"base",className:(0,o.cn)("laptop:flex-1 laptop:min-w-0 laptop:whitespace-normal laptop:text-center w-full min-w-0 whitespace-normal text-center",n?.secondaryButton),onClick:()=>{T(h,"secondary"),(0,u.gaTrack)({event:"ga4Event",event_name:"component_click",event_parameters:{page_group:p||"Home Page",component_type:"copy",component_name:"scene_shelf_product",component_title:e.custom_name||e.title,component_description:e.custom_description||"",button_name:f,SKU:e.sku||"",position:d}})},disabled:e.soldOut&&h!=="learnMore",loading:A,children:f}),y&&(0,t.jsx)(a.Button,{variant:"primary",size:"base",className:(0,o.cn)("laptop:flex-1 laptop:min-w-0 laptop:whitespace-normal laptop:text-center w-full min-w-0 whitespace-normal text-center",n?.primaryButton),onClick:()=>{T(P,"primary"),(0,u.gaTrack)({event:"ga4Event",event_name:"component_click",event_parameters:{page_group:p||"Home Page",component_type:"copy",component_name:"scene_shelf_product",component_title:e.custom_name||e.title,component_description:e.custom_description||"",button_name:y,SKU:e.sku||"",position:d}})},disabled:e.soldOut&&P!=="learnMore",loading:j,children:y})]})]})]})]})})});x.displayName="SceneShelfV3.ProductCard";var Y=x;
2
2
  //# sourceMappingURL=ProductCard.js.map
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../../../src/biz-components/SceneShelfV3/ProductCard.tsx"],
4
- "sourcesContent": ["'use client'\n\nimport * as React from 'react'\nimport { cn, getLocalizedPath } from '../../helpers/index.js'\nimport { Button, Badge, Card, CardContent, Picture, Text, Heading } from '../../components/index.js'\nimport type { BadgeProps } from '../../components/badge.js'\nimport { trackUrlRef } from '../../shared/trackUrlRef.js'\nimport type { ButtonFunctionType, CopyConfig } from './types.js'\nimport type { Theme } from '../../types/props.js'\nimport { gaTrack } from '../../shared/track.js'\nimport { useAiuiContext } from '../AiuiProvider/index.js'\n\n/**\n * \u8BED\u4E49\u5316\u7C7B\u540D\n */\nexport type SceneShelfV3SemanticName =\n | 'root'\n | 'title'\n | 'description'\n | 'tabsList'\n | 'promotionalBar'\n | 'productGrid'\n | 'viewMore'\n | 'productCard'\n | 'productTitle'\n | 'productDescription'\n | 'productPriceLabel'\n | 'productPrice'\n | 'priceWrapper'\n | 'originalPrice'\n | 'buttonGroup'\n | 'secondaryButton'\n | 'primaryButton'\n\n/**\n * \u5E93\u5B58\u5C55\u793A\u6A21\u5F0F\n */\nexport type StockDisplayMode = 'always' | 'never' | 'below-quantity' | 'below-percentage'\n\n/**\n * \u4EA7\u54C1\u5361\u7247\u6570\u636E\u63A5\u53E3\uFF08\u76F4\u63A5\u5339\u914D mock.json \u7ED3\u6784\uFF09\n */\nexport interface ProductCardData {\n sku?: string\n id: string\n /** \u4EA7\u54C1\u6807\u9898 */\n title: string\n /**\n * \u4EA7\u54C1\u63CF\u8FF0\n */\n description?: string\n /** \u4EA7\u54C1\u56FE\u7247 URL */\n imageUrl: string\n /** \u4EA7\u54C1\u56FE\u7247 alt \u6587\u672C */\n imageAlt: string\n /** \u5F53\u524D\u4EF7\u683C */\n currentPrice: string\n /** \u539F\u4EF7\uFF08\u683C\u5F0F\u5316\u5B57\u7B26\u4E32\uFF0C\u5982 \"$129.99\"\uFF0C\u7528\u4E8E\u663E\u793A\u5220\u9664\u7EBF\u4EF7\u683C\uFF09 */\n originalPrice?: string\n /** \u6807\u7B7E\u5217\u8868 */\n tags: Array<{\n label: string\n variant?: 'outline' | 'fill' | 'promotional'\n promotionalType?: BadgeProps['promotionalType']\n }>\n /** \u4EA7\u54C1\u8BE6\u60C5\u9875\u94FE\u63A5 */\n href: string\n /** \u662F\u5426\u552E\u7F44 */\n soldOut: boolean\n\n // ===== \u53EF\u9009\u5B57\u6BB5\uFF08CMS \u53EF\u80FD\u914D\u7F6E\uFF09 =====\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\uFF08\u5982 \"Member Price\"\uFF09 */\n priceLabel?: string\n /** \u5E93\u5B58\u4FE1\u606F\uFF08\u5982\u679C\u540E\u7AEF\u63D0\u4F9B\uFF09 */\n totalInventory?: number\n quantityAvailable?: number\n}\n\n/**\n * \u4EA7\u54C1\u5361\u7247\u7EC4\u4EF6 Props\n */\nexport interface ProductCardProps {\n product: ProductCardData\n className?: string\n showTags?: boolean\n stockDisplayMode?: StockDisplayMode\n stockThresholdValue?: number\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: ProductCardData) => void | Promise<void>\n /** \u70B9\u51FB\u52A0\u5165\u8D2D\u7269\u8F66\u56DE\u8C03\uFF08\u652F\u6301\u5F02\u6B65\uFF09 */\n onAddToCart?: (product: ProductCardData) => void | Promise<void>\n classNames?: Partial<Record<SceneShelfV3SemanticName, string>>\n secondaryButtonText?: string\n secondaryButtonFun?: ButtonFunctionType\n primaryButtonText?: string\n primaryButtonFun?: ButtonFunctionType\n showOriginalPrice?: boolean\n copy?: CopyConfig\n onProductImageClick?: (product: ProductCardData) => void\n /** \u4E3B\u9898 */\n theme?: Theme\n /** \u8BED\u8A00\u73AF\u5883 */\n locale?: string\n /** \u5F53\u524D\u4E0B\u6807 */\n index?: number\n /** tabName */\n tabName?: string\n}\n\n/**\n * SceneShelfV3 \u4EA7\u54C1\u5361\u7247\u7EC4\u4EF6\n */\nexport const ProductCard = React.forwardRef<HTMLDivElement, ProductCardProps>(\n (\n {\n product,\n className,\n showTags = true,\n onLearnMore,\n onShopNow,\n onAddToCart,\n classNames,\n secondaryButtonText,\n secondaryButtonFun,\n primaryButtonText,\n primaryButtonFun,\n showOriginalPrice,\n copy,\n onProductImageClick,\n theme = 'light',\n locale = 'us',\n index = 0,\n tabName,\n },\n ref\n ) => {\n const [primaryLoading, setPrimaryLoading] = React.useState(false)\n const [secondaryLoading, setSecondaryLoading] = React.useState(false)\n const { trackingData } = useAiuiContext()\n\n const pageGroup = trackingData?.pageGroup\n\n const availableForSale = !product.soldOut\n\n const handleButtonClick = React.useCallback(\n async (buttonFun?: ButtonFunctionType, buttonType?: 'primary' | 'secondary') => {\n if (!buttonFun) return\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 }\n } finally {\n setLoading(false)\n }\n },\n [product, onShopNow, onAddToCart, onLearnMore]\n )\n\n const trackedHref = React.useMemo(\n () => getLocalizedPath(trackUrlRef(product.href, pageGroup + '_' + 'shelf' + '_' + 'scene_shelf_v3'), locale),\n [product.href, pageGroup, locale]\n )\n\n const onProductClick = React.useCallback(() => {\n onProductImageClick?.(product)\n gaTrack({\n event: 'ga4Event',\n event_name: 'select_item',\n item_list_name: 'Scene_Shelf_3_Products',\n page_group: pageGroup,\n items: [\n {\n item_id: product.sku,\n item_name: product.title,\n item_variant: product.id,\n price: product.currentPrice,\n index: index,\n },\n ],\n tab_name: tabName,\n position: index,\n })\n }, [onProductImageClick, product, pageGroup, index, tabName])\n\n return (\n <Card\n ref={ref}\n className={cn(\n 'bg-container-primary flex h-full flex-col overflow-hidden border-none hover:bg-white',\n className,\n classNames?.productCard,\n {\n 'hover:bg-container-secondary-0 ': theme === 'dark',\n }\n )}\n >\n <CardContent className=\"desktop:p-6 relative flex flex-1 flex-col justify-between p-4\">\n <div className=\"product-image-wrapper lg-desktop:size-[196px] mx-auto size-[138px] cursor-pointer overflow-hidden\">\n <a\n onClick={onProductClick}\n {...(!onProductImageClick && {\n href: trackedHref,\n })}\n rel=\"noreferrer\"\n >\n <Picture\n source={product.imageUrl}\n alt={product.imageAlt}\n className=\"aspect-square size-full object-contain\"\n imgClassName=\"w-full h-full object-contain\"\n />\n </a>\n </div>\n\n {/* \u6807\u7B7E */}\n <div className=\"lg-desktop:h-[28px] mb-1 flex h-[24px] gap-1\">\n {showTags &&\n product.tags?.map((tag, index) => (\n <Badge\n key={index}\n size=\"sm\"\n variant={tag.variant || 'outline'}\n className={cn(tag.variant === 'promotional' ? 'ml-2' : '')}\n promotionalType={tag.promotionalType}\n >\n {tag.label}\n </Badge>\n ))}\n </div>\n\n {/* \u5185\u5BB9\u533A\u57DF */}\n <div className=\"flex h-full flex-1 grow flex-col justify-between\">\n <div className=\"mb-4\">\n <Heading\n as=\"h3\"\n size={2}\n className={cn(\n 'text-info-primary laptop:line-clamp-2 mb-2 line-clamp-3 min-h-[2.4em]',\n classNames?.productTitle\n )}\n html={product.custom_name || product.title}\n />\n {(product?.custom_description || product?.description) && (\n <Text\n size={2}\n className={cn(\n 'text-info-secondary desktop:text-[16px] lg-desktop:text-[18px] line-clamp-1 text-[14px]',\n classNames?.productDescription\n )}\n html={product.custom_description || product.description}\n />\n )}\n </div>\n\n {/* \u4EF7\u683C\u533A\u57DF */}\n <div>\n <div className={cn('mb-2', classNames?.productPrice)}>\n <div className={cn('flex items-baseline gap-2', classNames?.priceWrapper)}>\n {availableForSale ? (\n <>\n <Heading size={2} className=\"text-info-primary\" as=\"h6\">\n {product.currentPrice}\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 && availableForSale && (\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\n {/* \u6309\u94AE\u533A\u57DF */}\n <div\n className={cn(\n 'lg-desktop:gap-3 laptop:flex-row laptop:flex-nowrap flex flex-col flex-wrap gap-2',\n classNames?.buttonGroup\n )}\n >\n {secondaryButtonText && (\n <Button\n variant=\"secondary\"\n size=\"base\"\n className={cn(\n 'laptop:flex-1 laptop:min-w-0 laptop:whitespace-normal laptop:text-center w-full min-w-0 whitespace-normal text-center',\n classNames?.secondaryButton\n )}\n onClick={() => {\n handleButtonClick(secondaryButtonFun, 'secondary')\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.custom_name || product.title,\n component_description: product.custom_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 size=\"base\"\n className={cn(\n 'laptop:flex-1 laptop:min-w-0 laptop:whitespace-normal laptop:text-center w-full min-w-0 whitespace-normal text-center',\n classNames?.primaryButton\n )}\n onClick={() => {\n handleButtonClick(primaryButtonFun, 'primary')\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.custom_name || product.title,\n component_description: product.custom_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 </div>\n </div>\n </CardContent>\n </Card>\n )\n }\n)\n\nProductCard.displayName = 'SceneShelfV3.ProductCard'\n\nexport default ProductCard\n"],
5
- "mappings": "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",
6
- "names": ["ProductCard_exports", "__export", "ProductCard", "ProductCard_default", "__toCommonJS", "import_jsx_runtime", "React", "import_helpers", "import_components", "import_trackUrlRef", "import_track", "import_AiuiProvider", "product", "className", "showTags", "onLearnMore", "onShopNow", "onAddToCart", "classNames", "secondaryButtonText", "secondaryButtonFun", "primaryButtonText", "primaryButtonFun", "showOriginalPrice", "copy", "onProductImageClick", "theme", "locale", "index", "tabName", "ref", "primaryLoading", "setPrimaryLoading", "secondaryLoading", "setSecondaryLoading", "trackingData", "pageGroup", "availableForSale", "handleButtonClick", "buttonFun", "buttonType", "setLoading", "trackedHref", "onProductClick", "tag"]
4
+ "sourcesContent": ["'use client'\n\nimport * as React from 'react'\nimport { cn, getLocalizedPath } from '../../helpers/index.js'\nimport { Button, Badge, Card, CardContent, Picture, Text, Heading } from '../../components/index.js'\nimport type { BadgeProps } from '../../components/badge.js'\nimport { trackUrlRef } from '../../shared/trackUrlRef.js'\nimport type { ButtonFunctionType, CopyConfig } from './types.js'\nimport type { Theme } from '../../types/props.js'\nimport { gaTrack } from '../../shared/track.js'\nimport { useAiuiContext } from '../AiuiProvider/index.js'\n\n/**\n * \u8BED\u4E49\u5316\u7C7B\u540D\n */\nexport type SceneShelfV3SemanticName =\n | 'root'\n | 'title'\n | 'description'\n | 'tabsList'\n | 'promotionalBar'\n | 'productGrid'\n | 'viewMore'\n | 'productCard'\n | 'productTitle'\n | 'productDescription'\n | 'productPriceLabel'\n | 'productPrice'\n | 'priceWrapper'\n | 'originalPrice'\n | 'buttonGroup'\n | 'secondaryButton'\n | 'primaryButton'\n\n/**\n * \u5E93\u5B58\u5C55\u793A\u6A21\u5F0F\n */\nexport type StockDisplayMode = 'always' | 'never' | 'below-quantity' | 'below-percentage'\n\n/**\n * \u4EA7\u54C1\u5361\u7247\u6570\u636E\u63A5\u53E3\uFF08\u76F4\u63A5\u5339\u914D mock.json \u7ED3\u6784\uFF09\n */\nexport interface ProductCardData {\n sku?: string\n id: string\n /** \u4EA7\u54C1\u6807\u9898 */\n title: string\n /**\n * \u4EA7\u54C1\u63CF\u8FF0\n */\n description?: string\n /** \u4EA7\u54C1\u56FE\u7247 URL */\n imageUrl: string\n /** \u4EA7\u54C1\u56FE\u7247 alt \u6587\u672C */\n imageAlt: string\n /** \u5F53\u524D\u4EF7\u683C */\n currentPrice: string\n /** \u539F\u4EF7\uFF08\u683C\u5F0F\u5316\u5B57\u7B26\u4E32\uFF0C\u5982 \"$129.99\"\uFF0C\u7528\u4E8E\u663E\u793A\u5220\u9664\u7EBF\u4EF7\u683C\uFF09 */\n originalPrice?: string\n /** \u6807\u7B7E\u5217\u8868 */\n tags: Array<{\n label: string\n variant?: 'outline' | 'fill' | 'promotional'\n promotionalType?: BadgeProps['promotionalType']\n }>\n /** \u4EA7\u54C1\u8BE6\u60C5\u9875\u94FE\u63A5 */\n href: string\n /** \u662F\u5426\u552E\u7F44 */\n soldOut: boolean\n\n // ===== \u53EF\u9009\u5B57\u6BB5\uFF08CMS \u53EF\u80FD\u914D\u7F6E\uFF09 =====\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\uFF08\u5982 \"Member Price\"\uFF09 */\n priceLabel?: string\n /** \u5E93\u5B58\u4FE1\u606F\uFF08\u5982\u679C\u540E\u7AEF\u63D0\u4F9B\uFF09 */\n totalInventory?: number\n quantityAvailable?: number\n}\n\n/**\n * \u4EA7\u54C1\u5361\u7247\u7EC4\u4EF6 Props\n */\nexport interface ProductCardProps {\n product: ProductCardData\n className?: string\n showTags?: boolean\n stockDisplayMode?: StockDisplayMode\n stockThresholdValue?: number\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: ProductCardData) => void | Promise<void>\n /** \u70B9\u51FB\u52A0\u5165\u8D2D\u7269\u8F66\u56DE\u8C03\uFF08\u652F\u6301\u5F02\u6B65\uFF09 */\n onAddToCart?: (product: ProductCardData) => void | Promise<void>\n classNames?: Partial<Record<SceneShelfV3SemanticName, string>>\n secondaryButtonText?: string\n secondaryButtonFun?: ButtonFunctionType\n primaryButtonText?: string\n primaryButtonFun?: ButtonFunctionType\n showOriginalPrice?: boolean\n /**\n * \u539F\u4EF7\u533A\u57DF\u6E32\u67D3\u51FD\u6570\uFF0C\u7528\u4E8E\u5728\u539F\u4EF7\u4F4D\u7F6E\u5C55\u793A\u81EA\u5B9A\u4E49\u5185\u5BB9\uFF08\u5982 Save \u91D1\u989D\u6587\u6848\uFF09\u3002\n * \u4E0D\u4F20\u65F6\u4F7F\u7528\u9ED8\u8BA4\u7684\u539F\u4EF7\u6E32\u67D3\uFF08\u5212\u7EBF\u4EF7\uFF09\u3002\n * @param product - \u5F53\u524D\u4EA7\u54C1\u6570\u636E\n * @param context - \u6E32\u67D3\u4E0A\u4E0B\u6587\uFF08\u542B showOriginalPrice\uFF09\n */\n renderOriginalPrice?: (product: ProductCardData, context: { showOriginalPrice?: boolean }) => React.ReactNode\n copy?: CopyConfig\n onProductImageClick?: (product: ProductCardData) => void\n /** \u4E3B\u9898 */\n theme?: Theme\n /** \u8BED\u8A00\u73AF\u5883 */\n locale?: string\n /** \u5F53\u524D\u4E0B\u6807 */\n index?: number\n /** tabName */\n tabName?: string\n}\n\n/**\n * SceneShelfV3 \u4EA7\u54C1\u5361\u7247\u7EC4\u4EF6\n */\nexport const ProductCard = React.forwardRef<HTMLDivElement, ProductCardProps>(\n (\n {\n product,\n className,\n showTags = true,\n onLearnMore,\n onShopNow,\n onAddToCart,\n classNames,\n secondaryButtonText,\n secondaryButtonFun,\n primaryButtonText,\n primaryButtonFun,\n showOriginalPrice,\n renderOriginalPrice,\n copy,\n onProductImageClick,\n theme = 'light',\n locale = 'us',\n index = 0,\n tabName,\n },\n ref\n ) => {\n const [primaryLoading, setPrimaryLoading] = React.useState(false)\n const [secondaryLoading, setSecondaryLoading] = React.useState(false)\n const { trackingData } = useAiuiContext()\n\n const pageGroup = trackingData?.pageGroup\n\n const availableForSale = !product.soldOut\n\n const handleButtonClick = React.useCallback(\n async (buttonFun?: ButtonFunctionType, buttonType?: 'primary' | 'secondary') => {\n if (!buttonFun) return\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 }\n } finally {\n setLoading(false)\n }\n },\n [product, onShopNow, onAddToCart, onLearnMore]\n )\n\n const trackedHref = React.useMemo(\n () => getLocalizedPath(trackUrlRef(product.href, pageGroup + '_' + 'shelf' + '_' + 'scene_shelf_v3'), locale),\n [product.href, pageGroup, locale]\n )\n\n const onProductClick = React.useCallback(() => {\n onProductImageClick?.(product)\n gaTrack({\n event: 'ga4Event',\n event_name: 'select_item',\n item_list_name: 'Scene_Shelf_3_Products',\n page_group: pageGroup,\n items: [\n {\n item_id: product.sku,\n item_name: product.title,\n item_variant: product.id,\n price: product.currentPrice,\n index: index,\n },\n ],\n tab_name: tabName,\n position: index,\n })\n }, [onProductImageClick, product, pageGroup, index, tabName])\n\n return (\n <Card\n ref={ref}\n className={cn(\n 'bg-container-primary flex h-full flex-col overflow-hidden border-none hover:bg-white',\n className,\n classNames?.productCard,\n {\n 'hover:bg-container-secondary-0 ': theme === 'dark',\n }\n )}\n >\n <CardContent className=\"desktop:p-6 relative flex flex-1 flex-col justify-between p-4\">\n <div className=\"product-image-wrapper lg-desktop:size-[196px] mx-auto size-[138px] cursor-pointer overflow-hidden\">\n <a\n onClick={onProductClick}\n {...(!onProductImageClick && {\n href: trackedHref,\n })}\n rel=\"noreferrer\"\n >\n <Picture\n source={product.imageUrl}\n alt={product.imageAlt}\n className=\"aspect-square size-full object-contain\"\n imgClassName=\"w-full h-full object-contain\"\n />\n </a>\n </div>\n\n {/* \u6807\u7B7E */}\n <div className=\"lg-desktop:h-[28px] mb-1 flex h-[24px] gap-1\">\n {showTags &&\n product.tags?.map((tag, index) => (\n <Badge\n key={index}\n size=\"sm\"\n variant={tag.variant || 'outline'}\n className={cn(tag.variant === 'promotional' ? 'ml-2' : '')}\n promotionalType={tag.promotionalType}\n >\n {tag.label}\n </Badge>\n ))}\n </div>\n\n {/* \u5185\u5BB9\u533A\u57DF */}\n <div className=\"flex h-full flex-1 grow flex-col justify-between\">\n <div className=\"mb-4\">\n <Heading\n as=\"h3\"\n size={2}\n className={cn(\n 'text-info-primary laptop:line-clamp-2 mb-2 line-clamp-3 min-h-[2.4em]',\n classNames?.productTitle\n )}\n html={product.custom_name || product.title}\n />\n {(product?.custom_description || product?.description) && (\n <Text\n size={2}\n className={cn(\n 'text-info-secondary desktop:text-[16px] lg-desktop:text-[18px] line-clamp-1 text-[14px]',\n classNames?.productDescription\n )}\n html={product.custom_description || product.description}\n />\n )}\n </div>\n\n {/* \u4EF7\u683C\u533A\u57DF */}\n <div>\n <div className={cn('mb-2', classNames?.productPrice)}>\n <div className={cn('flex items-baseline gap-2', classNames?.priceWrapper)}>\n {availableForSale ? (\n <>\n <Heading size={2} className=\"text-info-primary\" as=\"h6\">\n {product.currentPrice}\n </Heading>\n {renderOriginalPrice\n ? renderOriginalPrice(product, { showOriginalPrice })\n : showOriginalPrice &&\n 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 && availableForSale && (\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\n {/* \u6309\u94AE\u533A\u57DF */}\n <div\n className={cn(\n 'lg-desktop:gap-3 laptop:flex-row laptop:flex-nowrap flex flex-col flex-wrap gap-2',\n classNames?.buttonGroup\n )}\n >\n {secondaryButtonText && (\n <Button\n variant=\"secondary\"\n size=\"base\"\n className={cn(\n 'laptop:flex-1 laptop:min-w-0 laptop:whitespace-normal laptop:text-center w-full min-w-0 whitespace-normal text-center',\n classNames?.secondaryButton\n )}\n onClick={() => {\n handleButtonClick(secondaryButtonFun, 'secondary')\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.custom_name || product.title,\n component_description: product.custom_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 size=\"base\"\n className={cn(\n 'laptop:flex-1 laptop:min-w-0 laptop:whitespace-normal laptop:text-center w-full min-w-0 whitespace-normal text-center',\n classNames?.primaryButton\n )}\n onClick={() => {\n handleButtonClick(primaryButtonFun, 'primary')\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.custom_name || product.title,\n component_description: product.custom_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 </div>\n </div>\n </CardContent>\n </Card>\n )\n }\n)\n\nProductCard.displayName = 'SceneShelfV3.ProductCard'\n\nexport default ProductCard\n"],
5
+ "mappings": "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",
6
+ "names": ["ProductCard_exports", "__export", "ProductCard", "ProductCard_default", "__toCommonJS", "import_jsx_runtime", "React", "import_helpers", "import_components", "import_trackUrlRef", "import_track", "import_AiuiProvider", "product", "className", "showTags", "onLearnMore", "onShopNow", "onAddToCart", "classNames", "secondaryButtonText", "secondaryButtonFun", "primaryButtonText", "primaryButtonFun", "showOriginalPrice", "renderOriginalPrice", "copy", "onProductImageClick", "theme", "locale", "index", "tabName", "ref", "primaryLoading", "setPrimaryLoading", "secondaryLoading", "setSecondaryLoading", "trackingData", "pageGroup", "availableForSale", "handleButtonClick", "buttonFun", "buttonType", "setLoading", "trackedHref", "onProductClick", "tag"]
7
7
  }
@@ -69,6 +69,15 @@ export interface SceneShelfV3Props extends React.HTMLAttributes<HTMLDivElement>
69
69
  onProductImageClick?: (product: ProductCardData) => void;
70
70
  /** 语义化类名 */
71
71
  classNames?: Partial<Record<SceneShelfV3SemanticName, string>>;
72
+ /**
73
+ * 原价区域渲染函数,用于在原价位置展示自定义内容(如 Save 金额文案)。
74
+ * 不传时使用默认的原价渲染(划线价)。
75
+ * @param product - 当前产品数据
76
+ * @param context - 渲染上下文(含 showOriginalPrice)
77
+ */
78
+ renderOriginalPrice?: (product: ProductCardData, context: {
79
+ showOriginalPrice?: boolean;
80
+ }) => React.ReactNode;
72
81
  }
73
82
  export interface SceneShelfV3Component extends React.ForwardRefExoticComponent<SceneShelfV3Props & React.RefAttributes<HTMLDivElement>> {
74
83
  ProductCard: typeof ProductCard;
@@ -1,2 +1,2 @@
1
- "use strict";"use client";var q=Object.create;var k=Object.defineProperty;var J=Object.getOwnPropertyDescriptor;var K=Object.getOwnPropertyNames;var Q=Object.getPrototypeOf,U=Object.prototype.hasOwnProperty;var X=(e,t)=>{for(var r in t)k(e,r,{get:t[r],enumerable:!0})},F=(e,t,r,u)=>{if(t&&typeof t=="object"||typeof t=="function")for(let s of K(t))!U.call(e,s)&&s!==r&&k(e,s,{get:()=>t[s],enumerable:!(u=J(t,s))||u.enumerable});return e};var E=(e,t,r)=>(r=e!=null?q(Q(e)):{},F(t||!e||!e.__esModule?k(r,"default",{value:e,enumerable:!0}):r,e)),Y=e=>F(k({},"__esModule",{value:!0}),e);var oe={};X(oe,{default:()=>te});module.exports=Y(oe);var o=require("react/jsx-runtime"),y=E(require("react")),c=require("../../helpers/index.js"),i=require("../../components/index.js"),A=E(require("../PromotionalBar/index.js")),I=require("../../hooks/useExposure.js"),O=require("../../hooks/useViewItemList.js"),z=require("../../hooks/useGridRowCount.js"),W=require("../AiuiProvider/index.js"),R=require("./ProductCard.js"),j=require("../../shared/Styles.js");const Z="shelf",$="Scene_Shelf_3_Products";function ee({products:e,copy:t,showTags:r,stockDisplayMode:u,stockThresholdValue:s,onLearnMore:C,onShopNow:d,onAddToCart:v,onProductImageClick:x,classNames:l,secondaryButtonText:B,secondaryButtonFun:h,primaryButtonText:m,primaryButtonFun:w,showOriginalPrice:D,viewMoreLimit:g,theme:M="light",locale:L="us",tabName:T=""}){const[f,V]=y.useState(!1),P=y.useRef(null);(0,O.useViewItemList)(P,{componentType:Z,componentName:$,itemListName:"Scene_Shelf_3_Products",items:e.map((n,p)=>({item_id:n.sku??"",item_name:n.title,item_variant:n.id??"",price:n.currentPrice,index:p})),tabName:T});const S=(0,z.useGridRowCount)({rows:g??0,mobileCols:2,tabletCols:3,desktopCols:4});if(!e?.length)return null;const b=g!==void 0&&g>0&&e.length>S,N=b&&!f?e.slice(0,S):e,a=()=>{V(n=>!n)};return(0,o.jsxs)(o.Fragment,{children:[(0,o.jsx)("div",{ref:P,className:(0,c.cn)("lg-desktop:gap-4 tablet:grid-cols-3 text-info-primary laptop:grid-cols-3 desktop:grid-cols-4 laptop:gap-3 grid grid-cols-2 gap-3",l?.productGrid),children:N.map((n,p)=>(0,o.jsx)(R.ProductCard,{product:n,showTags:r,stockDisplayMode:u,stockThresholdValue:s,onLearnMore:C,onShopNow:d,onAddToCart:v,onProductImageClick:x,classNames:l,secondaryButtonText:B,secondaryButtonFun:h,primaryButtonText:m,primaryButtonFun:w,showOriginalPrice:D,copy:t,theme:M,locale:L,index:p,tabName:T},n.sku||p))}),b&&(0,o.jsx)("div",{className:(0,c.cn)("laptop:mt-4 mt-3 flex justify-center",l?.viewMore),children:(0,o.jsxs)("button",{onClick:a,className:"text-info-primary hover:text-brand-0 lg-desktop:text-[16px] flex items-center gap-2 text-[14px] font-bold transition-colors","aria-expanded":f,children:[f?t?.viewLessLabel:t?.viewMoreLabel,(0,o.jsx)("svg",{className:(0,c.cn)("size-4 transition-transform",f&&"rotate-180"),fill:"none",stroke:"currentColor",viewBox:"0 0 24 24",children:(0,o.jsx)("path",{strokeLinecap:"round",strokeLinejoin:"round",strokeWidth:2,d:"M19 9l-7 7-7-7"})})]})})]})}const _=y.memo(ee);_.displayName="SceneShelfV3.ProductsGrid";const H=y.forwardRef(({className:e,data:t,onLearnMore:r,onShopNow:u,onAddToCart:s,onProductImageClick:C,classNames:d,...v},x)=>{const l=y.useRef(null),{locale:B="us"}=(0,W.useAiuiContext)();(0,I.useExposure)(l,{componentType:"image",componentName:"scene_shelf_banner"}),y.useImperativeHandle(x,()=>l.current);const{theme:h="light",sceneTabs:m=[],showTags:w=!0,stockDisplayMode:D,stockThresholdValue:g,showOriginalPrice:M=!0,secondaryButtonText:L,primaryButtonText:T,secondaryButtonFun:f="learnMore",primaryButtonFun:V="buyNow",copy:P,viewMoreLimit:S}=t,b=m.length>1,N={copy:P,showTags:w,stockDisplayMode:D,stockThresholdValue:g,onLearnMore:r,onShopNow:u,onAddToCart:s,onProductImageClick:C,classNames:d,secondaryButtonText:L,secondaryButtonFun:f,primaryButtonText:T,primaryButtonFun:V,showOriginalPrice:M,viewMoreLimit:S,theme:h,locale:B};return(0,o.jsxs)("div",{ref:l,className:(0,c.cn)("w-full",{"aiui-dark":h==="dark"},e,d?.root),style:{"--progress-track-bg":h==="dark"?"rgba(255, 255, 255, 0.2)":"rgba(0, 0, 0, 0.2)"},...v,children:[t.title&&(0,o.jsx)(i.Heading,{as:"h2",html:t.title,size:4,className:(0,c.cn)("text-info-primary mb-4",d?.title)}),t.description&&(0,o.jsx)(i.Text,{size:3,as:"p",html:t.description,className:(0,c.cn)("text-info-primary mb-6",d?.description)}),(0,o.jsxs)(i.Tabs,{defaultValue:m[0]?.id,className:"w-full",children:[b&&(0,o.jsx)(i.TabsList,{className:(0,c.cn)("mb-6",d?.tabsList),children:m.map(a=>(0,o.jsx)(i.TabsTrigger,{value:a.id,children:a.label},a.id))}),m.map(a=>{const n=a.resourceBlocks?.find(p=>p.blockType==="PromotionalBar"&&p.display==="visible");return(0,o.jsxs)(i.TabsContent,{value:a.id,children:[n&&(0,o.jsx)(A.default,{data:n,className:(0,c.cn)("laptop:mb-4 mb-3",d?.promotionalBar)}),(0,o.jsx)(_,{products:a.products,...N,tabName:a.label})]},a.id)})]})]})});H.displayName="SceneShelfV3";const G=H;G.ProductCard=R.ProductCard;var te=(0,j.withLayout)(G);
1
+ "use strict";"use client";var J=Object.create;var k=Object.defineProperty;var K=Object.getOwnPropertyDescriptor;var Q=Object.getOwnPropertyNames;var U=Object.getPrototypeOf,X=Object.prototype.hasOwnProperty;var Y=(e,t)=>{for(var r in t)k(e,r,{get:t[r],enumerable:!0})},E=(e,t,r,p)=>{if(t&&typeof t=="object"||typeof t=="function")for(let s of Q(t))!X.call(e,s)&&s!==r&&k(e,s,{get:()=>t[s],enumerable:!(p=K(t,s))||p.enumerable});return e};var _=(e,t,r)=>(r=e!=null?J(U(e)):{},E(t||!e||!e.__esModule?k(r,"default",{value:e,enumerable:!0}):r,e)),Z=e=>E(k({},"__esModule",{value:!0}),e);var re={};Y(re,{default:()=>oe});module.exports=Z(re);var o=require("react/jsx-runtime"),f=_(require("react")),c=require("../../helpers/index.js"),a=require("../../components/index.js"),A=_(require("../PromotionalBar/index.js")),I=require("../../hooks/useExposure.js"),z=require("../../hooks/useViewItemList.js"),W=require("../../hooks/useGridRowCount.js"),j=require("../AiuiProvider/index.js"),F=require("./ProductCard.js"),q=require("../../shared/Styles.js");const $="shelf",ee="Scene_Shelf_3_Products";function te({products:e,copy:t,showTags:r,stockDisplayMode:p,stockThresholdValue:s,onLearnMore:x,onShopNow:d,onAddToCart:v,onProductImageClick:B,classNames:g,secondaryButtonText:h,secondaryButtonFun:w,primaryButtonText:y,primaryButtonFun:u,showOriginalPrice:D,renderOriginalPrice:M,viewMoreLimit:P,theme:L="light",locale:N="us",tabName:T=""}){const[m,V]=f.useState(!1),b=f.useRef(null);(0,z.useViewItemList)(b,{componentType:$,componentName:ee,itemListName:"Scene_Shelf_3_Products",items:e.map((n,l)=>({item_id:n.sku??"",item_name:n.title,item_variant:n.id??"",price:n.currentPrice,index:l})),tabName:T});const S=(0,W.useGridRowCount)({rows:P??0,mobileCols:2,tabletCols:3,desktopCols:4});if(!e?.length)return null;const C=P!==void 0&&P>0&&e.length>S,R=C&&!m?e.slice(0,S):e,i=()=>{V(n=>!n)};return(0,o.jsxs)(o.Fragment,{children:[(0,o.jsx)("div",{ref:b,className:(0,c.cn)("lg-desktop:gap-4 tablet:grid-cols-3 text-info-primary laptop:grid-cols-3 desktop:grid-cols-4 laptop:gap-3 grid grid-cols-2 gap-3",g?.productGrid),children:R.map((n,l)=>(0,o.jsx)(F.ProductCard,{product:n,showTags:r,stockDisplayMode:p,stockThresholdValue:s,onLearnMore:x,onShopNow:d,onAddToCart:v,onProductImageClick:B,classNames:g,secondaryButtonText:h,secondaryButtonFun:w,primaryButtonText:y,primaryButtonFun:u,showOriginalPrice:D,renderOriginalPrice:M,copy:t,theme:L,locale:N,index:l,tabName:T},n.sku||l))}),C&&(0,o.jsx)("div",{className:(0,c.cn)("laptop:mt-4 mt-3 flex justify-center",g?.viewMore),children:(0,o.jsxs)("button",{onClick:i,className:"text-info-primary hover:text-brand-0 lg-desktop:text-[16px] flex items-center gap-2 text-[14px] font-bold transition-colors","aria-expanded":m,children:[m?t?.viewLessLabel:t?.viewMoreLabel,(0,o.jsx)("svg",{className:(0,c.cn)("size-4 transition-transform",m&&"rotate-180"),fill:"none",stroke:"currentColor",viewBox:"0 0 24 24",children:(0,o.jsx)("path",{strokeLinecap:"round",strokeLinejoin:"round",strokeWidth:2,d:"M19 9l-7 7-7-7"})})]})})]})}const O=f.memo(te);O.displayName="SceneShelfV3.ProductsGrid";const H=f.forwardRef(({className:e,data:t,onLearnMore:r,onShopNow:p,onAddToCart:s,onProductImageClick:x,classNames:d,renderOriginalPrice:v,...B},g)=>{const h=f.useRef(null),{locale:w="us"}=(0,j.useAiuiContext)();(0,I.useExposure)(h,{componentType:"image",componentName:"scene_shelf_banner"}),f.useImperativeHandle(g,()=>h.current);const{theme:y="light",sceneTabs:u=[],showTags:D=!0,stockDisplayMode:M,stockThresholdValue:P,showOriginalPrice:L=!0,secondaryButtonText:N,primaryButtonText:T,secondaryButtonFun:m="learnMore",primaryButtonFun:V="buyNow",copy:b,viewMoreLimit:S}=t,C=u.length>1,R={copy:b,showTags:D,stockDisplayMode:M,stockThresholdValue:P,onLearnMore:r,onShopNow:p,onAddToCart:s,onProductImageClick:x,classNames:d,secondaryButtonText:N,secondaryButtonFun:m,primaryButtonText:T,primaryButtonFun:V,showOriginalPrice:L,renderOriginalPrice:v,viewMoreLimit:S,theme:y,locale:w};return(0,o.jsxs)("div",{ref:h,className:(0,c.cn)("w-full",{"aiui-dark":y==="dark"},e,d?.root),style:{"--progress-track-bg":y==="dark"?"rgba(255, 255, 255, 0.2)":"rgba(0, 0, 0, 0.2)"},...B,children:[t.title&&(0,o.jsx)(a.Heading,{as:"h2",html:t.title,size:4,className:(0,c.cn)("text-info-primary mb-4",d?.title)}),t.description&&(0,o.jsx)(a.Text,{size:3,as:"p",html:t.description,className:(0,c.cn)("text-info-primary mb-6",d?.description)}),(0,o.jsxs)(a.Tabs,{defaultValue:u[0]?.id,className:"w-full",children:[C&&(0,o.jsx)(a.TabsList,{className:(0,c.cn)("mb-6",d?.tabsList),children:u.map(i=>(0,o.jsx)(a.TabsTrigger,{value:i.id,children:i.label},i.id))}),u.map(i=>{const n=i.resourceBlocks?.find(l=>l.blockType==="PromotionalBar"&&l.display==="visible");return(0,o.jsxs)(a.TabsContent,{value:i.id,children:[n&&(0,o.jsx)(A.default,{data:n,className:(0,c.cn)("laptop:mb-4 mb-3",d?.promotionalBar)}),(0,o.jsx)(O,{products:i.products,...R,tabName:i.label})]},i.id)})]})]})});H.displayName="SceneShelfV3";const G=H;G.ProductCard=F.ProductCard;var oe=(0,q.withLayout)(G);
2
2
  //# sourceMappingURL=index.js.map
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../../../src/biz-components/SceneShelfV3/index.tsx"],
4
- "sourcesContent": ["'use client'\n\nimport * as React from 'react'\nimport { cn } from '../../helpers/index.js'\nimport { Text, Heading, Tabs, TabsList, TabsTrigger, TabsContent } from '../../components/index.js'\nimport PromotionalBar, { type PromotionalBarProps } from '../PromotionalBar/index.js'\nimport { useExposure } from '../../hooks/useExposure.js'\nimport { useViewItemList } from '../../hooks/useViewItemList.js'\nimport { useGridRowCount } from '../../hooks/useGridRowCount.js'\nimport { useAiuiContext } from '../AiuiProvider/index.js'\nimport {\n ProductCard,\n type ProductCardData,\n type SceneShelfV3SemanticName,\n type StockDisplayMode,\n} from './ProductCard.js'\nimport type { ButtonFunctionType, CopyConfig } from './types.js'\nimport { withLayout } from '../../shared/Styles.js'\n\nconst componentType = 'shelf'\nconst componentName = 'Scene_Shelf_3_Products'\n\n/**\n * \u573A\u666F Tab \u6570\u636E\u63A5\u53E3\uFF08\u5339\u914D mock.json.sceneTabs \u7ED3\u6784\uFF09\n */\nexport interface ProductTab {\n /** Tab \u552F\u4E00 ID */\n id: string\n /** Tab \u6807\u7B7E\u6587\u672C */\n label: string\n /** \u4EA7\u54C1\u5217\u8868 */\n products: ProductCardData[]\n /** \u8D44\u6E90\u5757\uFF08\u5982 PromotionalBar\uFF09 */\n resourceBlocks?: Array<PromotionalBarProps['data'] & { blockType: string; display: 'visible' | 'hidden' }>\n}\n\n/**\n * SceneShelfV3 \u6570\u636E\u63A5\u53E3\uFF08\u76F4\u63A5\u5339\u914D mock.json \u7ED3\u6784\uFF09\n */\nexport interface SceneShelfV3Data {\n // ===== \u9876\u5C42\u914D\u7F6E\u5B57\u6BB5 =====\n /** \u7EC4\u4EF6\u5B9E\u4F8B ID */\n id: string\n /** \u4E3B\u9898 */\n theme?: 'light' | 'dark'\n /** \u663E\u793A\u72B6\u6001 */\n display?: 'visible' | 'hidden'\n /** \u7EC4\u4EF6\u7C7B\u578B\u6807\u8BC6 */\n blockType: 'ipc-scene-shelf-v3'\n\n // ===== \u573A\u666F Tab \u5217\u8868 =====\n /** \u573A\u666F Tab \u5217\u8868\uFF08\u6BCF\u4E2A Tab \u5305\u542B\u4EA7\u54C1\u548C resourceBlocks\uFF09 */\n sceneTabs: ProductTab[]\n\n // ===== \u6587\u6848\u914D\u7F6E =====\n copy?: CopyConfig\n\n // ===== \u663E\u793A\u914D\u7F6E =====\n /** \u662F\u5426\u663E\u793A\u6807\u7B7E */\n showTags?: boolean\n /** \u67E5\u770B\u66F4\u591A\u9650\u5236\u6570 */\n viewMoreLimit?: number\n\n // ===== \u6309\u94AE\u914D\u7F6E =====\n /** \u4E3B\u6309\u94AE\u6587\u672C */\n primaryButtonText?: string\n /** \u4E3B\u6309\u94AE\u529F\u80FD */\n primaryButtonFun?: ButtonFunctionType\n /** \u6B21\u6309\u94AE\u6587\u672C */\n secondaryButtonText?: string\n /** \u6B21\u6309\u94AE\u529F\u80FD */\n secondaryButtonFun?: ButtonFunctionType\n\n // ===== \u53EF\u9009\u5B57\u6BB5\uFF08\u7EC4\u4EF6\u5185\u90E8\u53EF\u80FD\u4F7F\u7528\uFF09 =====\n /** \u7EC4\u4EF6\u6807\u9898\uFF08\u53EF\u9009\uFF0C\u975E mock \u5FC5\u9700\uFF09 */\n title?: string\n /** \u7EC4\u4EF6\u63CF\u8FF0\uFF08\u53EF\u9009\uFF0C\u975E mock \u5FC5\u9700\uFF09 */\n description?: string\n /** \u5E93\u5B58\u5C55\u793A\u6A21\u5F0F\uFF08\u53EF\u9009\uFF09 */\n stockDisplayMode?: StockDisplayMode\n /** \u5E93\u5B58\u9608\u503C\uFF08\u53EF\u9009\uFF09 */\n stockThresholdValue?: number\n /** \u662F\u5426\u663E\u793A\u539F\u4EF7\uFF08\u53EF\u9009\uFF09 */\n showOriginalPrice?: boolean\n}\n\nexport interface SceneShelfV3Props extends React.HTMLAttributes<HTMLDivElement> {\n /** \u4E1A\u52A1\u6570\u636E */\n data: SceneShelfV3Data\n /** \u70B9\u51FB\u4E86\u89E3\u66F4\u591A\u56DE\u8C03 */\n onLearnMore?: (link: string) => 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 /** \u70B9\u51FB\u4EA7\u54C1\u56FE\u7247\u56DE\u8C03 */\n onProductImageClick?: (product: ProductCardData) => void\n /** \u8BED\u4E49\u5316\u7C7B\u540D */\n classNames?: Partial<Record<SceneShelfV3SemanticName, string>>\n}\n\nexport interface SceneShelfV3Component extends React.ForwardRefExoticComponent<\n SceneShelfV3Props & React.RefAttributes<HTMLDivElement>\n> {\n ProductCard: typeof ProductCard\n}\n\n/**\n * \u4EA7\u54C1\u7F51\u683C\u7EC4\u4EF6 Props\n */\ninterface ProductsGridProps {\n products: ProductCardData[]\n copy?: CopyConfig\n showTags?: boolean\n stockDisplayMode?: StockDisplayMode\n stockThresholdValue?: number\n onLearnMore?: (link: string) => void\n onShopNow?: (product: ProductCardData) => void\n onAddToCart?: (product: ProductCardData) => void\n onProductImageClick?: (product: ProductCardData) => void\n classNames?: Partial<Record<SceneShelfV3SemanticName, string>>\n secondaryButtonText?: string\n secondaryButtonFun?: ButtonFunctionType\n primaryButtonText?: string\n primaryButtonFun?: ButtonFunctionType\n showOriginalPrice?: boolean\n viewMoreLimit?: number\n theme?: 'light' | 'dark'\n locale?: string\n tabName?: string\n}\n\n/**\n * \u4EA7\u54C1\u7F51\u683C\u7EC4\u4EF6 - \u4EC5\u652F\u6301\u5E73\u94FA\u7F51\u683C\u5E03\u5C40\uFF08\u65E0\u8F6E\u64AD\uFF09\n */\nfunction ProductsGridComponent({\n products,\n copy,\n showTags,\n stockDisplayMode,\n stockThresholdValue,\n onLearnMore,\n onShopNow,\n onAddToCart,\n onProductImageClick,\n classNames,\n secondaryButtonText,\n secondaryButtonFun,\n primaryButtonText,\n primaryButtonFun,\n showOriginalPrice,\n viewMoreLimit,\n theme = 'light',\n locale = 'us',\n tabName = '',\n}: ProductsGridProps) {\n const [isExpanded, setIsExpanded] = React.useState(false)\n const productWrapperRef = React.useRef<HTMLDivElement>(null)\n\n useViewItemList(productWrapperRef, {\n componentType,\n componentName,\n itemListName: 'Scene_Shelf_3_Products',\n items: products.map((item, index) => ({\n item_id: item.sku ?? '',\n item_name: item.title,\n item_variant: item.id ?? '',\n price: item.currentPrice,\n index: index,\n })),\n tabName,\n })\n\n const visibleLimit = useGridRowCount({\n rows: viewMoreLimit ?? 0,\n mobileCols: 2,\n tabletCols: 3,\n desktopCols: 4,\n })\n\n if (!products?.length) return null\n\n const shouldShowViewMore = viewMoreLimit !== undefined && viewMoreLimit > 0 && products.length > visibleLimit\n\n const displayedProducts = shouldShowViewMore && !isExpanded ? products.slice(0, visibleLimit) : products\n\n // \u5207\u6362\u5C55\u5F00\u72B6\u6001\n const toggleExpanded = () => {\n setIsExpanded(prev => !prev)\n }\n\n return (\n <>\n <div\n ref={productWrapperRef}\n className={cn(\n 'lg-desktop:gap-4 tablet:grid-cols-3 text-info-primary laptop:grid-cols-3 desktop:grid-cols-4 laptop:gap-3 grid grid-cols-2 gap-3',\n classNames?.productGrid\n )}\n >\n {displayedProducts.map((product, index) => (\n <ProductCard\n key={product.sku || index}\n product={product}\n showTags={showTags}\n stockDisplayMode={stockDisplayMode}\n stockThresholdValue={stockThresholdValue}\n onLearnMore={onLearnMore}\n onShopNow={onShopNow}\n onAddToCart={onAddToCart}\n onProductImageClick={onProductImageClick}\n classNames={classNames}\n secondaryButtonText={secondaryButtonText}\n secondaryButtonFun={secondaryButtonFun}\n primaryButtonText={primaryButtonText}\n primaryButtonFun={primaryButtonFun}\n showOriginalPrice={showOriginalPrice}\n copy={copy}\n theme={theme}\n locale={locale}\n index={index}\n tabName={tabName}\n />\n ))}\n </div>\n\n {/* \u67E5\u770B\u66F4\u591A\u6309\u94AE */}\n {shouldShowViewMore && (\n <div className={cn('laptop:mt-4 mt-3 flex justify-center', classNames?.viewMore)}>\n <button\n onClick={toggleExpanded}\n className=\"text-info-primary hover:text-brand-0 lg-desktop:text-[16px] flex items-center gap-2 text-[14px] font-bold transition-colors\"\n aria-expanded={isExpanded}\n >\n {isExpanded ? copy?.viewLessLabel : copy?.viewMoreLabel}\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\nconst ProductsGrid = React.memo(ProductsGridComponent)\nProductsGrid.displayName = 'SceneShelfV3.ProductsGrid'\n\n/**\n * SceneShelfV3 - \u573A\u666F\u63A8\u8350\u8D27\u67B6 V3\n *\n * @description \u5E73\u94FA\u7F51\u683C\u5E03\u5C40\u7684\u8D27\u67B6\u7EC4\u4EF6\uFF0C\u652F\u6301 Tab \u5206\u7EC4\u3001\u6BCF\u4E2A Tab \u72EC\u7ACB\u914D\u7F6E PromotionalBar \u548C\u67E5\u770B\u66F4\u591A\u529F\u80FD\n */\nconst SceneShelfV3 = React.forwardRef<HTMLDivElement, SceneShelfV3Props>(\n ({ className, data, onLearnMore, onShopNow, onAddToCart, onProductImageClick, classNames, ...props }, ref) => {\n const boxRef = React.useRef<HTMLDivElement>(null)\n const { locale = 'us' } = useAiuiContext()\n\n useExposure(boxRef, {\n componentType: 'image',\n componentName: 'scene_shelf_banner',\n })\n\n React.useImperativeHandle(ref, () => boxRef.current as HTMLDivElement)\n\n const {\n theme = 'light',\n sceneTabs = [],\n showTags = true,\n stockDisplayMode,\n stockThresholdValue,\n showOriginalPrice = true,\n secondaryButtonText,\n primaryButtonText,\n secondaryButtonFun = 'learnMore',\n primaryButtonFun = 'buyNow',\n copy,\n viewMoreLimit,\n } = data\n\n // \u5224\u65AD\u662F\u5426\u663E\u793A Tab\uFF08\u591A\u4E8E 1 \u4E2A Tab \u65F6\u663E\u793A\uFF09\n const shouldShowTab = sceneTabs.length > 1\n\n const gridProps: Omit<ProductsGridProps, 'products'> = {\n copy,\n showTags,\n stockDisplayMode,\n stockThresholdValue,\n onLearnMore,\n onShopNow,\n onAddToCart,\n onProductImageClick,\n classNames,\n secondaryButtonText,\n secondaryButtonFun,\n primaryButtonText,\n primaryButtonFun,\n showOriginalPrice,\n viewMoreLimit,\n theme,\n locale,\n }\n\n return (\n <div\n ref={boxRef}\n className={cn('w-full', { 'aiui-dark': theme === 'dark' }, className, classNames?.root)}\n style={\n {\n '--progress-track-bg': theme === 'dark' ? 'rgba(255, 255, 255, 0.2)' : 'rgba(0, 0, 0, 0.2)',\n } as React.CSSProperties\n }\n {...props}\n >\n {/* \u6807\u9898\u533A\u57DF */}\n {data.title && (\n <Heading as=\"h2\" html={data.title} size={4} className={cn('text-info-primary mb-4', classNames?.title)} />\n )}\n {data.description && (\n <Text\n size={3}\n as=\"p\"\n html={data.description}\n className={cn('text-info-primary mb-6', classNames?.description)}\n />\n )}\n\n {/* \u4EA7\u54C1\u5C55\u793A\u533A\u57DF */}\n <Tabs defaultValue={sceneTabs[0]?.id} className=\"w-full\">\n {/* Tab \u5217\u8868 */}\n {shouldShowTab && (\n <TabsList className={cn('mb-6', classNames?.tabsList)}>\n {sceneTabs.map(tab => (\n <TabsTrigger key={tab.id} value={tab.id}>\n {tab.label}\n </TabsTrigger>\n ))}\n </TabsList>\n )}\n\n {/* \u4EA7\u54C1\u5185\u5BB9\u533A\u57DF */}\n {sceneTabs.map(tab => {\n // \u4ECE resourceBlocks \u4E2D\u63D0\u53D6 PromotionalBar \u6570\u636E\n const promotionalBarBlock: any = tab.resourceBlocks?.find(\n block => block.blockType === 'PromotionalBar' && block.display === 'visible'\n )\n\n return (\n <TabsContent key={tab.id} value={tab.id}>\n {/* \u6BCF\u4E2A Tab \u72EC\u7ACB\u7684 PromotionalBar\uFF08\u53EF\u9009\uFF09 */}\n {promotionalBarBlock && (\n <PromotionalBar\n data={promotionalBarBlock}\n className={cn('laptop:mb-4 mb-3', classNames?.promotionalBar)}\n />\n )}\n <ProductsGrid products={tab.products} {...gridProps} tabName={tab.label} />\n </TabsContent>\n )\n })}\n </Tabs>\n </div>\n )\n }\n)\n\nSceneShelfV3.displayName = 'SceneShelfV3'\n\n// \u521B\u5EFA\u590D\u5408\u7EC4\u4EF6\nconst SceneShelfV3WithProductCard = SceneShelfV3 as SceneShelfV3Component\nSceneShelfV3WithProductCard.ProductCard = ProductCard\n\nexport default withLayout(SceneShelfV3WithProductCard)\nexport type { StockDisplayMode, SceneShelfV3SemanticName, ProductCardData }\n"],
5
- "mappings": "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",
6
- "names": ["SceneShelfV3_exports", "__export", "SceneShelfV3_default", "__toCommonJS", "import_jsx_runtime", "React", "import_helpers", "import_components", "import_PromotionalBar", "import_useExposure", "import_useViewItemList", "import_useGridRowCount", "import_AiuiProvider", "import_ProductCard", "import_Styles", "componentType", "componentName", "ProductsGridComponent", "products", "copy", "showTags", "stockDisplayMode", "stockThresholdValue", "onLearnMore", "onShopNow", "onAddToCart", "onProductImageClick", "classNames", "secondaryButtonText", "secondaryButtonFun", "primaryButtonText", "primaryButtonFun", "showOriginalPrice", "viewMoreLimit", "theme", "locale", "tabName", "isExpanded", "setIsExpanded", "productWrapperRef", "item", "index", "visibleLimit", "shouldShowViewMore", "displayedProducts", "toggleExpanded", "prev", "product", "ProductsGrid", "SceneShelfV3", "className", "data", "props", "ref", "boxRef", "sceneTabs", "shouldShowTab", "gridProps", "tab", "promotionalBarBlock", "block", "PromotionalBar", "SceneShelfV3WithProductCard"]
4
+ "sourcesContent": ["'use client'\n\nimport * as React from 'react'\nimport { cn } from '../../helpers/index.js'\nimport { Text, Heading, Tabs, TabsList, TabsTrigger, TabsContent } from '../../components/index.js'\nimport PromotionalBar, { type PromotionalBarProps } from '../PromotionalBar/index.js'\nimport { useExposure } from '../../hooks/useExposure.js'\nimport { useViewItemList } from '../../hooks/useViewItemList.js'\nimport { useGridRowCount } from '../../hooks/useGridRowCount.js'\nimport { useAiuiContext } from '../AiuiProvider/index.js'\nimport {\n ProductCard,\n type ProductCardData,\n type SceneShelfV3SemanticName,\n type StockDisplayMode,\n} from './ProductCard.js'\nimport type { ButtonFunctionType, CopyConfig } from './types.js'\nimport { withLayout } from '../../shared/Styles.js'\n\nconst componentType = 'shelf'\nconst componentName = 'Scene_Shelf_3_Products'\n\n/**\n * \u573A\u666F Tab \u6570\u636E\u63A5\u53E3\uFF08\u5339\u914D mock.json.sceneTabs \u7ED3\u6784\uFF09\n */\nexport interface ProductTab {\n /** Tab \u552F\u4E00 ID */\n id: string\n /** Tab \u6807\u7B7E\u6587\u672C */\n label: string\n /** \u4EA7\u54C1\u5217\u8868 */\n products: ProductCardData[]\n /** \u8D44\u6E90\u5757\uFF08\u5982 PromotionalBar\uFF09 */\n resourceBlocks?: Array<PromotionalBarProps['data'] & { blockType: string; display: 'visible' | 'hidden' }>\n}\n\n/**\n * SceneShelfV3 \u6570\u636E\u63A5\u53E3\uFF08\u76F4\u63A5\u5339\u914D mock.json \u7ED3\u6784\uFF09\n */\nexport interface SceneShelfV3Data {\n // ===== \u9876\u5C42\u914D\u7F6E\u5B57\u6BB5 =====\n /** \u7EC4\u4EF6\u5B9E\u4F8B ID */\n id: string\n /** \u4E3B\u9898 */\n theme?: 'light' | 'dark'\n /** \u663E\u793A\u72B6\u6001 */\n display?: 'visible' | 'hidden'\n /** \u7EC4\u4EF6\u7C7B\u578B\u6807\u8BC6 */\n blockType: 'ipc-scene-shelf-v3'\n\n // ===== \u573A\u666F Tab \u5217\u8868 =====\n /** \u573A\u666F Tab \u5217\u8868\uFF08\u6BCF\u4E2A Tab \u5305\u542B\u4EA7\u54C1\u548C resourceBlocks\uFF09 */\n sceneTabs: ProductTab[]\n\n // ===== \u6587\u6848\u914D\u7F6E =====\n copy?: CopyConfig\n\n // ===== \u663E\u793A\u914D\u7F6E =====\n /** \u662F\u5426\u663E\u793A\u6807\u7B7E */\n showTags?: boolean\n /** \u67E5\u770B\u66F4\u591A\u9650\u5236\u6570 */\n viewMoreLimit?: number\n\n // ===== \u6309\u94AE\u914D\u7F6E =====\n /** \u4E3B\u6309\u94AE\u6587\u672C */\n primaryButtonText?: string\n /** \u4E3B\u6309\u94AE\u529F\u80FD */\n primaryButtonFun?: ButtonFunctionType\n /** \u6B21\u6309\u94AE\u6587\u672C */\n secondaryButtonText?: string\n /** \u6B21\u6309\u94AE\u529F\u80FD */\n secondaryButtonFun?: ButtonFunctionType\n\n // ===== \u53EF\u9009\u5B57\u6BB5\uFF08\u7EC4\u4EF6\u5185\u90E8\u53EF\u80FD\u4F7F\u7528\uFF09 =====\n /** \u7EC4\u4EF6\u6807\u9898\uFF08\u53EF\u9009\uFF0C\u975E mock \u5FC5\u9700\uFF09 */\n title?: string\n /** \u7EC4\u4EF6\u63CF\u8FF0\uFF08\u53EF\u9009\uFF0C\u975E mock \u5FC5\u9700\uFF09 */\n description?: string\n /** \u5E93\u5B58\u5C55\u793A\u6A21\u5F0F\uFF08\u53EF\u9009\uFF09 */\n stockDisplayMode?: StockDisplayMode\n /** \u5E93\u5B58\u9608\u503C\uFF08\u53EF\u9009\uFF09 */\n stockThresholdValue?: number\n /** \u662F\u5426\u663E\u793A\u539F\u4EF7\uFF08\u53EF\u9009\uFF09 */\n showOriginalPrice?: boolean\n}\n\nexport interface SceneShelfV3Props extends React.HTMLAttributes<HTMLDivElement> {\n /** \u4E1A\u52A1\u6570\u636E */\n data: SceneShelfV3Data\n /** \u70B9\u51FB\u4E86\u89E3\u66F4\u591A\u56DE\u8C03 */\n onLearnMore?: (link: string) => 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 /** \u70B9\u51FB\u4EA7\u54C1\u56FE\u7247\u56DE\u8C03 */\n onProductImageClick?: (product: ProductCardData) => void\n /** \u8BED\u4E49\u5316\u7C7B\u540D */\n classNames?: Partial<Record<SceneShelfV3SemanticName, string>>\n /**\n * \u539F\u4EF7\u533A\u57DF\u6E32\u67D3\u51FD\u6570\uFF0C\u7528\u4E8E\u5728\u539F\u4EF7\u4F4D\u7F6E\u5C55\u793A\u81EA\u5B9A\u4E49\u5185\u5BB9\uFF08\u5982 Save \u91D1\u989D\u6587\u6848\uFF09\u3002\n * \u4E0D\u4F20\u65F6\u4F7F\u7528\u9ED8\u8BA4\u7684\u539F\u4EF7\u6E32\u67D3\uFF08\u5212\u7EBF\u4EF7\uFF09\u3002\n * @param product - \u5F53\u524D\u4EA7\u54C1\u6570\u636E\n * @param context - \u6E32\u67D3\u4E0A\u4E0B\u6587\uFF08\u542B showOriginalPrice\uFF09\n */\n renderOriginalPrice?: (product: ProductCardData, context: { showOriginalPrice?: boolean }) => React.ReactNode\n}\n\nexport interface SceneShelfV3Component extends React.ForwardRefExoticComponent<\n SceneShelfV3Props & React.RefAttributes<HTMLDivElement>\n> {\n ProductCard: typeof ProductCard\n}\n\n/**\n * \u4EA7\u54C1\u7F51\u683C\u7EC4\u4EF6 Props\n */\ninterface ProductsGridProps {\n products: ProductCardData[]\n copy?: CopyConfig\n showTags?: boolean\n stockDisplayMode?: StockDisplayMode\n stockThresholdValue?: number\n onLearnMore?: (link: string) => void\n onShopNow?: (product: ProductCardData) => void\n onAddToCart?: (product: ProductCardData) => void\n onProductImageClick?: (product: ProductCardData) => void\n classNames?: Partial<Record<SceneShelfV3SemanticName, string>>\n secondaryButtonText?: string\n secondaryButtonFun?: ButtonFunctionType\n primaryButtonText?: string\n primaryButtonFun?: ButtonFunctionType\n showOriginalPrice?: boolean\n renderOriginalPrice?: (product: ProductCardData, context: { showOriginalPrice?: boolean }) => React.ReactNode\n viewMoreLimit?: number\n theme?: 'light' | 'dark'\n locale?: string\n tabName?: string\n}\n\n/**\n * \u4EA7\u54C1\u7F51\u683C\u7EC4\u4EF6 - \u4EC5\u652F\u6301\u5E73\u94FA\u7F51\u683C\u5E03\u5C40\uFF08\u65E0\u8F6E\u64AD\uFF09\n */\nfunction ProductsGridComponent({\n products,\n copy,\n showTags,\n stockDisplayMode,\n stockThresholdValue,\n onLearnMore,\n onShopNow,\n onAddToCart,\n onProductImageClick,\n classNames,\n secondaryButtonText,\n secondaryButtonFun,\n primaryButtonText,\n primaryButtonFun,\n showOriginalPrice,\n renderOriginalPrice,\n viewMoreLimit,\n theme = 'light',\n locale = 'us',\n tabName = '',\n}: ProductsGridProps) {\n const [isExpanded, setIsExpanded] = React.useState(false)\n const productWrapperRef = React.useRef<HTMLDivElement>(null)\n\n useViewItemList(productWrapperRef, {\n componentType,\n componentName,\n itemListName: 'Scene_Shelf_3_Products',\n items: products.map((item, index) => ({\n item_id: item.sku ?? '',\n item_name: item.title,\n item_variant: item.id ?? '',\n price: item.currentPrice,\n index: index,\n })),\n tabName,\n })\n\n const visibleLimit = useGridRowCount({\n rows: viewMoreLimit ?? 0,\n mobileCols: 2,\n tabletCols: 3,\n desktopCols: 4,\n })\n\n if (!products?.length) return null\n\n const shouldShowViewMore = viewMoreLimit !== undefined && viewMoreLimit > 0 && products.length > visibleLimit\n\n const displayedProducts = shouldShowViewMore && !isExpanded ? products.slice(0, visibleLimit) : products\n\n // \u5207\u6362\u5C55\u5F00\u72B6\u6001\n const toggleExpanded = () => {\n setIsExpanded(prev => !prev)\n }\n\n return (\n <>\n <div\n ref={productWrapperRef}\n className={cn(\n 'lg-desktop:gap-4 tablet:grid-cols-3 text-info-primary laptop:grid-cols-3 desktop:grid-cols-4 laptop:gap-3 grid grid-cols-2 gap-3',\n classNames?.productGrid\n )}\n >\n {displayedProducts.map((product, index) => (\n <ProductCard\n key={product.sku || index}\n product={product}\n showTags={showTags}\n stockDisplayMode={stockDisplayMode}\n stockThresholdValue={stockThresholdValue}\n onLearnMore={onLearnMore}\n onShopNow={onShopNow}\n onAddToCart={onAddToCart}\n onProductImageClick={onProductImageClick}\n classNames={classNames}\n secondaryButtonText={secondaryButtonText}\n secondaryButtonFun={secondaryButtonFun}\n primaryButtonText={primaryButtonText}\n primaryButtonFun={primaryButtonFun}\n showOriginalPrice={showOriginalPrice}\n renderOriginalPrice={renderOriginalPrice}\n copy={copy}\n theme={theme}\n locale={locale}\n index={index}\n tabName={tabName}\n />\n ))}\n </div>\n\n {/* \u67E5\u770B\u66F4\u591A\u6309\u94AE */}\n {shouldShowViewMore && (\n <div className={cn('laptop:mt-4 mt-3 flex justify-center', classNames?.viewMore)}>\n <button\n onClick={toggleExpanded}\n className=\"text-info-primary hover:text-brand-0 lg-desktop:text-[16px] flex items-center gap-2 text-[14px] font-bold transition-colors\"\n aria-expanded={isExpanded}\n >\n {isExpanded ? copy?.viewLessLabel : copy?.viewMoreLabel}\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\nconst ProductsGrid = React.memo(ProductsGridComponent)\nProductsGrid.displayName = 'SceneShelfV3.ProductsGrid'\n\n/**\n * SceneShelfV3 - \u573A\u666F\u63A8\u8350\u8D27\u67B6 V3\n *\n * @description \u5E73\u94FA\u7F51\u683C\u5E03\u5C40\u7684\u8D27\u67B6\u7EC4\u4EF6\uFF0C\u652F\u6301 Tab \u5206\u7EC4\u3001\u6BCF\u4E2A Tab \u72EC\u7ACB\u914D\u7F6E PromotionalBar \u548C\u67E5\u770B\u66F4\u591A\u529F\u80FD\n */\nconst SceneShelfV3 = React.forwardRef<HTMLDivElement, SceneShelfV3Props>(\n (\n {\n className,\n data,\n onLearnMore,\n onShopNow,\n onAddToCart,\n onProductImageClick,\n classNames,\n renderOriginalPrice,\n ...props\n },\n ref\n ) => {\n const boxRef = React.useRef<HTMLDivElement>(null)\n const { locale = 'us' } = useAiuiContext()\n\n useExposure(boxRef, {\n componentType: 'image',\n componentName: 'scene_shelf_banner',\n })\n\n React.useImperativeHandle(ref, () => boxRef.current as HTMLDivElement)\n\n const {\n theme = 'light',\n sceneTabs = [],\n showTags = true,\n stockDisplayMode,\n stockThresholdValue,\n showOriginalPrice = true,\n secondaryButtonText,\n primaryButtonText,\n secondaryButtonFun = 'learnMore',\n primaryButtonFun = 'buyNow',\n copy,\n viewMoreLimit,\n } = data\n\n // \u5224\u65AD\u662F\u5426\u663E\u793A Tab\uFF08\u591A\u4E8E 1 \u4E2A Tab \u65F6\u663E\u793A\uFF09\n const shouldShowTab = sceneTabs.length > 1\n\n const gridProps: Omit<ProductsGridProps, 'products'> = {\n copy,\n showTags,\n stockDisplayMode,\n stockThresholdValue,\n onLearnMore,\n onShopNow,\n onAddToCart,\n onProductImageClick,\n classNames,\n secondaryButtonText,\n secondaryButtonFun,\n primaryButtonText,\n primaryButtonFun,\n showOriginalPrice,\n renderOriginalPrice,\n viewMoreLimit,\n theme,\n locale,\n }\n\n return (\n <div\n ref={boxRef}\n className={cn('w-full', { 'aiui-dark': theme === 'dark' }, className, classNames?.root)}\n style={\n {\n '--progress-track-bg': theme === 'dark' ? 'rgba(255, 255, 255, 0.2)' : 'rgba(0, 0, 0, 0.2)',\n } as React.CSSProperties\n }\n {...props}\n >\n {/* \u6807\u9898\u533A\u57DF */}\n {data.title && (\n <Heading as=\"h2\" html={data.title} size={4} className={cn('text-info-primary mb-4', classNames?.title)} />\n )}\n {data.description && (\n <Text\n size={3}\n as=\"p\"\n html={data.description}\n className={cn('text-info-primary mb-6', classNames?.description)}\n />\n )}\n\n {/* \u4EA7\u54C1\u5C55\u793A\u533A\u57DF */}\n <Tabs defaultValue={sceneTabs[0]?.id} className=\"w-full\">\n {/* Tab \u5217\u8868 */}\n {shouldShowTab && (\n <TabsList className={cn('mb-6', classNames?.tabsList)}>\n {sceneTabs.map(tab => (\n <TabsTrigger key={tab.id} value={tab.id}>\n {tab.label}\n </TabsTrigger>\n ))}\n </TabsList>\n )}\n\n {/* \u4EA7\u54C1\u5185\u5BB9\u533A\u57DF */}\n {sceneTabs.map(tab => {\n // \u4ECE resourceBlocks \u4E2D\u63D0\u53D6 PromotionalBar \u6570\u636E\n const promotionalBarBlock: any = tab.resourceBlocks?.find(\n block => block.blockType === 'PromotionalBar' && block.display === 'visible'\n )\n\n return (\n <TabsContent key={tab.id} value={tab.id}>\n {/* \u6BCF\u4E2A Tab \u72EC\u7ACB\u7684 PromotionalBar\uFF08\u53EF\u9009\uFF09 */}\n {promotionalBarBlock && (\n <PromotionalBar\n data={promotionalBarBlock}\n className={cn('laptop:mb-4 mb-3', classNames?.promotionalBar)}\n />\n )}\n <ProductsGrid products={tab.products} {...gridProps} tabName={tab.label} />\n </TabsContent>\n )\n })}\n </Tabs>\n </div>\n )\n }\n)\n\nSceneShelfV3.displayName = 'SceneShelfV3'\n\n// \u521B\u5EFA\u590D\u5408\u7EC4\u4EF6\nconst SceneShelfV3WithProductCard = SceneShelfV3 as SceneShelfV3Component\nSceneShelfV3WithProductCard.ProductCard = ProductCard\n\nexport default withLayout(SceneShelfV3WithProductCard)\nexport type { StockDisplayMode, SceneShelfV3SemanticName, ProductCardData }\n"],
5
+ "mappings": "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",
6
+ "names": ["SceneShelfV3_exports", "__export", "SceneShelfV3_default", "__toCommonJS", "import_jsx_runtime", "React", "import_helpers", "import_components", "import_PromotionalBar", "import_useExposure", "import_useViewItemList", "import_useGridRowCount", "import_AiuiProvider", "import_ProductCard", "import_Styles", "componentType", "componentName", "ProductsGridComponent", "products", "copy", "showTags", "stockDisplayMode", "stockThresholdValue", "onLearnMore", "onShopNow", "onAddToCart", "onProductImageClick", "classNames", "secondaryButtonText", "secondaryButtonFun", "primaryButtonText", "primaryButtonFun", "showOriginalPrice", "renderOriginalPrice", "viewMoreLimit", "theme", "locale", "tabName", "isExpanded", "setIsExpanded", "productWrapperRef", "item", "index", "visibleLimit", "shouldShowViewMore", "displayedProducts", "toggleExpanded", "prev", "product", "ProductsGrid", "SceneShelfV3", "className", "data", "props", "ref", "boxRef", "sceneTabs", "shouldShowTab", "gridProps", "tab", "promotionalBarBlock", "block", "PromotionalBar", "SceneShelfV3WithProductCard"]
7
7
  }
@@ -106,6 +106,32 @@ export type ShelfDisplayType = {
106
106
  /** shelf-items-tag 背景颜色,设置后会覆盖默认的品牌渐变背景并隐藏默认品牌色描边。仅作用于纵向卡片 ShelfDisplayWrapItem */
107
107
  itemsTagBgColor?: string;
108
108
  };
109
+ /**
110
+ * 价格渲染上下文:renderOriginalPrice / renderPrice 等渲染函数共享的格式化价格信息。
111
+ * 后续如需向渲染函数抛出更多参数,直接在本类型中追加字段即可(向后兼容)。
112
+ */
113
+ export interface ShelfDisplayPriceInfo {
114
+ price: string;
115
+ basePrice: string | undefined;
116
+ discount: string | null;
117
+ discountAmount: string | undefined;
118
+ /** 是否显示原价(来源 data.isShowOriginalPrice,默认 true) */
119
+ isShowOriginalPrice: boolean;
120
+ }
121
+ /** renderPrice 完整上下文:在价格信息基础上追加变体 / 优惠券 / 售罄状态。 */
122
+ export interface ShelfDisplayPriceRenderInfo extends ShelfDisplayPriceInfo {
123
+ variant: any;
124
+ coupon: any;
125
+ isSoldOut: boolean;
126
+ }
127
+ /**
128
+ * renderPriceLabel 上下文:用于向价格标签渲染函数抛出配置信息。
129
+ * 后续扩展时在此追加字段即可(向后兼容)。
130
+ */
131
+ export interface ShelfDisplayPriceLabelContext {
132
+ /** 是否显示原价(来源 data.isShowOriginalPrice,默认 true) */
133
+ isShowOriginalPrice: boolean;
134
+ }
109
135
  export interface ShelfDisplayProps extends React.HTMLAttributes<HTMLDivElement> {
110
136
  data: ShelfDisplayType;
111
137
  buildData?: {
@@ -143,35 +169,23 @@ export interface ShelfDisplayProps extends React.HTMLAttributes<HTMLDivElement>
143
169
  * 原价区域渲染函数,用于在原价位置展示自定义内容(如折扣信息)。
144
170
  * 不传时使用默认的原价渲染(划线价)。
145
171
  * @param item - 当前产品数据
146
- * @param priceInfo - 格式化后的价格信息
172
+ * @param priceInfo - 格式化后的价格信息(含 isShowOriginalPrice)
147
173
  */
148
- renderOriginalPrice?: (item: ShelfDisplayItem, priceInfo: {
149
- price: string;
150
- basePrice: string | undefined;
151
- discount: string | null;
152
- discountAmount: string | undefined;
153
- }) => React.ReactNode;
174
+ renderOriginalPrice?: (item: ShelfDisplayItem, priceInfo: ShelfDisplayPriceInfo) => React.ReactNode;
154
175
  /**
155
176
  * 价格标签渲染函数,在价格下方展示自定义内容。
156
177
  * 不传时不展示。
157
178
  * @param item - 当前产品数据
158
179
  * @param variant - 当前匹配的变体数据
180
+ * @param context - 渲染上下文(含 isShowOriginalPrice,后续可扩展更多字段)
159
181
  */
160
- renderPriceLabel?: (item: ShelfDisplayItem, variant: any) => React.ReactNode;
182
+ renderPriceLabel?: (item: ShelfDisplayItem, variant: any, context?: ShelfDisplayPriceLabelContext) => React.ReactNode;
161
183
  /**
162
184
  * 价格区域渲染函数,用于完全自定义价格区域(包括最终价格、原价、售罄状态等)。
163
185
  * 不传时使用默认的价格渲染逻辑。
164
186
  * @param item - 当前产品数据
165
- * @param priceInfo - 格式化后的价格信息及上下文
187
+ * @param priceInfo - 格式化后的价格信息及上下文(含 isShowOriginalPrice)
166
188
  */
167
- renderPrice?: (item: ShelfDisplayItem, priceInfo: {
168
- price: string;
169
- basePrice: string | undefined;
170
- discount: string | null;
171
- discountAmount: string | undefined;
172
- variant: any;
173
- coupon: any;
174
- isSoldOut: boolean;
175
- }) => React.ReactNode;
189
+ renderPrice?: (item: ShelfDisplayItem, priceInfo: ShelfDisplayPriceRenderInfo) => React.ReactNode;
176
190
  }
177
191
  export {};
@@ -1,2 +1,2 @@
1
- "use strict";var S=Object.create;var l=Object.defineProperty;var T=Object.getOwnPropertyDescriptor;var x=Object.getOwnPropertyNames;var P=Object.getPrototypeOf,I=Object.prototype.hasOwnProperty;var v=(e,n)=>{for(var i in n)l(e,i,{get:n[i],enumerable:!0})},g=(e,n,i,a)=>{if(n&&typeof n=="object"||typeof n=="function")for(let t of x(n))!I.call(e,t)&&t!==i&&l(e,t,{get:()=>n[t],enumerable:!(a=T(n,t))||a.enumerable});return e};var C=(e,n,i)=>(i=e!=null?S(P(e)):{},g(n||!e||!e.__esModule?l(i,"default",{value:e,enumerable:!0}):i,e)),w=e=>g(l({},"__esModule",{value:!0}),e);var B={};v(B,{formatVariantPrice:()=>_});module.exports=w(B);var y=C(require("decimal.js")),r=require("../../helpers/index.js");function _({amount:e,baseAmount:n,currencyCode:i,currencyDisplay:a,locale:t,maximumFractionDigits:f,minimumFractionDigits:b,removeTrailingZeros:d,customFormatPrice:o}){if(typeof Intl>"u")return{price:`${r.PRICE_SYMBOL[t]}${e}`,basePrice:`${r.PRICE_SYMBOL[t]}${n}`,discount:`${r.PRICE_SYMBOL[t]}${n-e||0}`};const p=n>e;let c=null;const u=(0,r.languageTerritory)(t);if(u){const s=new Intl.NumberFormat(u,{style:"percent"});c=p?s.format((n-e)/n):null}let m;if(p){const s=new y.default(n).sub(e||0).toNumber();m=o?o({amount:s,locale:t}):(0,r.formatPrice)({amount:s,currencyDisplay:a,currencyCode:i||"USD",locale:t,maximumFractionDigits:2})}const h=o?o({amount:e,locale:t}):(0,r.formatPrice)({amount:e,currencyCode:i,currencyDisplay:a,locale:t,removeTrailingZeros:d}),D=p?o?o({amount:n,locale:t}):(0,r.formatPrice)({amount:n,currencyCode:i,currencyDisplay:a,locale:t,maximumFractionDigits:f,minimumFractionDigits:b,removeTrailingZeros:d}):void 0;return{price:h,basePrice:D,discount:c,discountAmount:m}}
1
+ "use strict";var S=Object.create;var l=Object.defineProperty;var T=Object.getOwnPropertyDescriptor;var x=Object.getOwnPropertyNames;var P=Object.getPrototypeOf,I=Object.prototype.hasOwnProperty;var C=(e,i)=>{for(var t in i)l(e,t,{get:i[t],enumerable:!0})},u=(e,i,t,a)=>{if(i&&typeof i=="object"||typeof i=="function")for(let n of x(i))!I.call(e,n)&&n!==t&&l(e,n,{get:()=>i[n],enumerable:!(a=T(i,n))||a.enumerable});return e};var w=(e,i,t)=>(t=e!=null?S(P(e)):{},u(i||!e||!e.__esModule?l(t,"default",{value:e,enumerable:!0}):t,e)),v=e=>u(l({},"__esModule",{value:!0}),e);var _={};C(_,{formatVariantPrice:()=>R});module.exports=v(_);var g=w(require("decimal.js")),r=require("../../helpers/index.js");function R({amount:e,baseAmount:i,currencyCode:t,currencyDisplay:a,locale:n,maximumFractionDigits:f,minimumFractionDigits:b,removeTrailingZeros:c,customFormatPrice:o}){if(typeof Intl>"u")return{price:`${r.PRICE_SYMBOL[n]}${e}`,basePrice:`${r.PRICE_SYMBOL[n]}${i}`,discount:`${r.PRICE_SYMBOL[n]}${i-e||0}`};const p=i>e;let d=null;const m=(0,r.languageTerritory)(n);if(m){const s=new Intl.NumberFormat(m,{style:"percent"});d=p?s.format((i-e)/i):null}let y;if(p){const s=new g.default(i).sub(e||0).toNumber();y=o?o({amount:s,locale:n}):(0,r.formatPrice)({amount:s,currencyDisplay:a,currencyCode:t||"USD",locale:n,maximumFractionDigits:2})}const h=o?o({amount:e,locale:n}):(0,r.formatPrice)({amount:e,currencyCode:t,currencyDisplay:a,locale:n,removeTrailingZeros:c}),D=p?o?o({amount:i,locale:n}):(0,r.formatPrice)({amount:i,currencyCode:t,currencyDisplay:a,locale:n,maximumFractionDigits:f,minimumFractionDigits:b,removeTrailingZeros:c}):void 0;return{price:h,basePrice:D,discount:d,discountAmount:y}}
2
2
  //# sourceMappingURL=shelfDisplay.js.map