@anker-in/headless-ui 1.3.55 → 1.3.57
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cjs/biz-components/ActiveShelf/ProductCard.js +1 -1
- package/dist/cjs/biz-components/ActiveShelf/ProductCard.js.map +2 -2
- package/dist/cjs/biz-components/BuyOneGetOneShelf/PriceAndActions.js +1 -1
- package/dist/cjs/biz-components/BuyOneGetOneShelf/PriceAndActions.js.map +2 -2
- package/dist/cjs/biz-components/CreditsShelf/ProductCard.js +1 -1
- package/dist/cjs/biz-components/CreditsShelf/ProductCard.js.map +2 -2
- package/dist/cjs/biz-components/ImageOverlayShelf/ProductCard.js +1 -1
- package/dist/cjs/biz-components/ImageOverlayShelf/ProductCard.js.map +2 -2
- package/dist/cjs/biz-components/Marquee/Marquee.js +1 -1
- package/dist/cjs/biz-components/Marquee/Marquee.js.map +2 -2
- package/dist/cjs/biz-components/Marquee/type.d.ts +1 -0
- package/dist/cjs/biz-components/Marquee/type.js +1 -1
- package/dist/cjs/biz-components/Marquee/type.js.map +1 -1
- package/dist/cjs/biz-components/MediaShelf/ProductCard.js +1 -1
- package/dist/cjs/biz-components/MediaShelf/ProductCard.js.map +2 -2
- package/dist/cjs/biz-components/SceneShelf/ProductsPanel.js +1 -1
- package/dist/cjs/biz-components/SceneShelf/ProductsPanel.js.map +2 -2
- package/dist/cjs/biz-components/SceneShelfV2/index.js +1 -1
- package/dist/cjs/biz-components/SceneShelfV2/index.js.map +2 -2
- package/dist/cjs/biz-components/SceneShelfV3/ProductCard.js +1 -1
- package/dist/cjs/biz-components/SceneShelfV3/ProductCard.js.map +2 -2
- package/dist/esm/biz-components/ActiveShelf/ProductCard.js +1 -1
- package/dist/esm/biz-components/ActiveShelf/ProductCard.js.map +2 -2
- package/dist/esm/biz-components/BuyOneGetOneShelf/PriceAndActions.js +1 -1
- package/dist/esm/biz-components/BuyOneGetOneShelf/PriceAndActions.js.map +2 -2
- package/dist/esm/biz-components/CreditsShelf/ProductCard.js +1 -1
- package/dist/esm/biz-components/CreditsShelf/ProductCard.js.map +2 -2
- package/dist/esm/biz-components/ImageOverlayShelf/ProductCard.js +1 -1
- package/dist/esm/biz-components/ImageOverlayShelf/ProductCard.js.map +2 -2
- package/dist/esm/biz-components/Marquee/Marquee.js +1 -1
- package/dist/esm/biz-components/Marquee/Marquee.js.map +2 -2
- package/dist/esm/biz-components/Marquee/type.d.ts +1 -0
- package/dist/esm/biz-components/MediaShelf/ProductCard.js +1 -1
- package/dist/esm/biz-components/MediaShelf/ProductCard.js.map +2 -2
- package/dist/esm/biz-components/SceneShelf/ProductsPanel.js +1 -1
- package/dist/esm/biz-components/SceneShelf/ProductsPanel.js.map +2 -2
- package/dist/esm/biz-components/SceneShelfV2/index.js +1 -1
- package/dist/esm/biz-components/SceneShelfV2/index.js.map +2 -2
- package/dist/esm/biz-components/SceneShelfV3/ProductCard.js +1 -1
- package/dist/esm/biz-components/SceneShelfV3/ProductCard.js.map +2 -2
- package/package.json +1 -1
- package/style.css +18 -6
|
@@ -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:w-fit laptop:grow-0 w-full flex-1 whitespace-nowrap',\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:w-fit laptop:grow-0 w-full flex-1 whitespace-nowrap',\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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
|
|
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
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"]
|
|
7
7
|
}
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
"use client";import{Fragment as H,jsx as a,jsxs as n}from"react/jsx-runtime";import*as l from"react";import{cn as t}from"../../helpers/index.js";import{Button as
|
|
1
|
+
"use client";import{Fragment as H,jsx as a,jsxs as n}from"react/jsx-runtime";import*as l from"react";import{cn as t}from"../../helpers/index.js";import{Button as w,Badge as M,Card as _,CardContent as R,Picture as $,Text as f,Heading as d,Progress as E}from"../../components/index.js";const I=5;function j(e,o,s,m){if(e===void 0)return!0;switch(e){case"always":return!0;case"never":return!1;case"below-quantity":return o===void 0?!0:s<=o;case"below-percentage":return o===void 0?!0:s/m*100<=o;default:return!0}}const g=l.forwardRef(({product:e,className:o,showTags:s=!0,stockDisplayMode:m,stockThresholdValue:P,onLearnMore:C,onShopNow:S,onAddToCart:N,classNames:i,secondaryButtonText:p,secondaryButtonFun:y,primaryButtonText:u,primaryButtonFun:v,showOriginalPrice:B,copy:b,onProductImageClick:x},D)=>{const[L,T]=l.useState(!1),[F,z]=l.useState(!1),A=l.useMemo(()=>e?.availableForSale&&e?.quantityAvailable<=0?I:e?.availableForSale?(e?.quantityAvailable??0)/(e?.totalInventory??1)*100:0,[e?.availableForSale,e?.quantityAvailable,e?.totalInventory]),k=async(r,c)=>{if(!r)return;const h=c==="primary"?T:z;h(!0);try{switch(r){case"buyNow":await S?.(e);break;case"addCart":await N?.(e);break;case"learnMore":await C?.(e);break;default:break}}finally{h(!1)}},q=e.availableForSale&&e.quantityAvailable<=0;return a(_,{ref:D,className:t("bg-container-primary hover:bg-container-secondary-0 flex h-full flex-col overflow-hidden border-none",o,i?.productCard),children:n(R,{className:"desktop:p-6 relative flex flex-1 flex-col justify-between p-4",children:[a("div",{className:"lg-desktop:h-[28px] flex h-[24px] gap-1",children:s&&e.tags?.map((r,c)=>r.label?a(M,{size:"sm",variant:r.variant||"outline",className:t(r.variant==="promotional"?"ml-2":""),promotionalType:r.promotionalType,children:r.label},c):a(l.Fragment,{children:r},c))}),a("div",{className:"product-image-wrapper lg-desktop:size-[196px] mx-auto size-[138px] cursor-pointer overflow-hidden",children:a("a",{onClick:()=>x?.(e),...!x&&{href:e?.listingLink},rel:"noreferrer",children:a($,{source:e.image,alt:e.name,className:"aspect-square size-full object-contain",imgClassName:"w-full h-full object-contain"})})}),n("div",{className:"flex h-full flex-1 grow flex-col justify-between",children:[n("div",{className:"mb-4",children:[a(d,{as:"h3",size:2,className:t("text-info-primary mb-2 line-clamp-2 min-h-[2.4em]",i?.productTitle),html:e.custom_name||e.name}),e?.description&&a(f,{size:2,className:t("text-info-secondary desktop:line-clamp-2 desktop:min-h-[2.4em] desktop:text-[16px] lg-desktop:text-[18px] line-clamp-2 min-h-[2.4em] text-[14px]",i?.productDescription),html:e.custom_description||e.description})]}),n("div",{children:[a("div",{className:t("mb-2",i?.productPrice),children:a("div",{className:"flex items-baseline gap-2",children:e.availableForSale?n(H,{children:[a(d,{size:2,className:"text-info-primary",as:"h6",children:e.price}),B&&e.originalPrice&&a(d,{size:2,className:t("text-info-tertiary line-through",i?.originalPrice),as:"h6",children:e.originalPrice})]}):a(d,{size:2,className:"text-info-tertiary",children:b?.outOfStockLabel??"Sold Out"})})}),e?.priceLabel&&e?.availableForSale&&a(f,{size:4,className:t("text-marketing-1 desktop:text-[16px] lg-desktop:text-[18px] mt-2 text-[14px]",i?.productPriceLabel),children:e.priceLabel}),n("div",{className:t("lg-desktop:gap-3 tablet:flex-nowrap flex flex-wrap gap-2",i?.buttonGroup),children:[p&&a(w,{variant:"secondary",size:"base",className:t("tablet:w-fit tablet:min-w-0 tablet:whitespace-normal tablet:text-center w-full whitespace-nowrap",i?.secondaryButton),onClick:()=>k(y,"secondary"),disabled:!e.availableForSale&&y!=="learnMore",loading:F,"data-headless-type-name":"ActiveShelf#ProductCard","data-headless-title-desc-button":`${e.custom_name||e.name}#${e.description||""}#${p}`,"data-headless-sku":e.sku,children:p}),u&&a(w,{variant:"primary",size:"base",className:t("tablet:w-fit tablet:min-w-0 tablet:whitespace-normal tablet:text-center w-full whitespace-nowrap",i?.primaryButton),onClick:()=>k(v,"primary"),disabled:!e.availableForSale&&v!=="learnMore",loading:L,"data-headless-type-name":"ActiveShelf#ProductCard","data-headless-title-desc-button":`${e.custom_name||e.name}#${e.description||""}#${u}`,"data-headless-sku":e.sku,children:u})]}),j(m,P,e?.quantityAvailable??0,e?.totalInventory??0)&&n("div",{className:"mt-4 space-y-2",children:[a(E,{value:A,max:100,min:0,size:"base",variant:"default","aria-label":"stock progress",classNames:{root:t("bg-[var(--progress-track-bg,rgba(0,0,0,0.2))]",i?.stockTrack),progressBar:t("bg-brand-0 transition-all duration-300 ease-in-out",i?.stockBar)}}),a(f,{size:3,className:"text-info-tertiary text-[14px]",children:q?b?.limitedStock:b?.stockDisplayText?.replace("{count}",`${e.availableForSale?e.quantityAvailable:0}`)})]})]})]})]})})});g.displayName="ActiveShelf.ProductCard";var K=g;export{g as ProductCard,K as default};
|
|
2
2
|
//# sourceMappingURL=ProductCard.js.map
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../../../src/biz-components/ActiveShelf/ProductCard.tsx"],
|
|
4
|
-
"sourcesContent": ["'use client'\n\nimport * as React from 'react'\nimport { cn } from '../../helpers/index.js'\nimport { Button, Badge, Card, CardContent, Picture, Text, Heading, Progress } from '../../components/index.js'\n\nimport type { ButtonFunctionType, CopyConfig } from './types.js'\nimport type { BadgeProps } from '../../components/badge.js'\n\n/**\n * \u8D85\u5356\u65F6\u5E93\u5B58\u6761\u663E\u793A\u7684\u6700\u5C0F\u767E\u5206\u6BD4\n * \u9632\u6B62\u8D85\u5356\u65F6\u5E93\u5B58\u6761\u663E\u793A\u4E3A\u6EE1\u683C\uFF08100%\uFF09\u6216\u5B8C\u5168\u7A7A\uFF080%\uFF09\n */\nconst OVERSELLING_STOCK_PERCENTAGE = 5\n\n/**\n * \u8BED\u4E49\u5316\u7C7B\u540D\n */\nexport type ActiveShelfSemanticName =\n | 'root'\n | 'title'\n | 'description'\n | 'productCard'\n | 'productTitle'\n | 'productDescription'\n | 'productPriceLabel'\n | 'productPrice'\n | 'originalPrice'\n | 'buttonGroup'\n | 'secondaryButton'\n | 'primaryButton'\n | 'stockTrack'\n | 'stockBar'\n\n/**\n * \u5E93\u5B58\u5C55\u793A\u6A21\u5F0F\n */\nexport type StockDisplayMode = 'always' | 'never' | 'below-quantity' | 'below-percentage'\n\n/**\n * \u57FA\u7840\u4EA7\u54C1\u6570\u636E\u63A5\u53E3\uFF08\u6765\u81EA\u5916\u90E8\u6570\u636E\u6E90\uFF09\n */\nexport interface BaseProductData {\n sku: string\n name: string\n image: string\n value: string\n handle: string\n shopify_id: string\n custom_name?: string\n custom_description?: string\n}\n\n/**\n * Shopify \u53D8\u4F53\u6570\u636E\u63A5\u53E3\n */\nexport interface VariantData {\n /**\n * \u4EA7\u54C1\u63CF\u8FF0\n */\n description?: string\n /**\n * \u53D8\u4F53id\n */\n variantId: string\n\n /**\n * \u4EA7\u54C1\u94FE\u63A5, \u70B9\u51FB\u56FE\u7247\u7684\u65F6\u5019\u8DF3\u8F6C\u5230\u8BE5\u94FE\u63A5\n */\n listingLink: string\n /**\n * \u539F\u4EF7\n */\n originalPrice: string\n /**\n * \u73B0\u4EF7\n */\n price: string\n /**\n * \u4EF7\u683C\u4E0A\u9762\u5C55\u793A\u7684\u6807\u7B7E\u6587\u672C\n */\n priceLabel?: string\n /**\n * \u603B\u5E93\u5B58\n */\n totalInventory: number\n /**\n * \u53EF\u7528\u5E93\u5B58\u6570\u91CF\n */\n quantityAvailable: number\n /**\n * \u662F\u5426\u53EF\u552E\n */\n availableForSale: boolean\n\n /**\n * tags \u5217\u8868(\u4F1A\u5458\u4EF7\uFF0C\u6298\u6263\uFF0Cnew, hot\u7B49\u6807\u7B7E\u4FE1\u606F)\n */\n tags: Array<\n | {\n label: string\n variant: BadgeProps['variant']\n promotionalType?: BadgeProps['promotionalType']\n }\n | React.ReactNode\n >\n /**\n * \u901A\u7528\u6298\u6263\u6570\u636E\uFF0C\u5305\u62EC\u6298\u6263title, \u7C7B\u578B\u548C\u503C\n */\n coupon: any\n}\n\n/**\n * \u5B8C\u6574\u7684\u4EA7\u54C1\u5361\u7247\u6570\u636E\u63A5\u53E3\n */\nexport interface ProductCardData extends BaseProductData, VariantData {}\n\n/**\n * \u4EA7\u54C1\u5361\u7247\u7EC4\u4EF6 Props\n */\nexport interface ProductCardProps {\n /** \u4EA7\u54C1\u6570\u636E */\n product: ProductCardData\n /** \u6837\u5F0F\u7C7B\u540D */\n className?: string\n /** \u662F\u5426\u5C55\u793A\u6807\u7B7E\u7CFB\u7EDF */\n showTags?: boolean\n /** \u5E93\u5B58\u5C55\u793A\u6A21\u5F0F */\n stockDisplayMode?: StockDisplayMode\n /** \u5E93\u5B58\u9608\u503C\uFF08\u5F53\u6A21\u5F0F\u4E3A below-quantity \u6216 below-percentage \u65F6\u4F7F\u7528\uFF09 */\n stockThresholdValue?: number\n /** \u70B9\u51FB\u4E86\u89E3\u66F4\u591A\u56DE\u8C03 */\n onLearnMore?: (product: ProductCardData) => void\n /** \u70B9\u51FB\u7ACB\u5373\u8D2D\u4E70\u56DE\u8C03 */\n onShopNow?: (product: ProductCardData) => void\n /** \u70B9\u51FB\u52A0\u5165\u8D2D\u7269\u8F66\u56DE\u8C03 */\n onAddToCart?: (product: ProductCardData) => void\n /** \u8BED\u4E49\u5316\u7C7B\u540D */\n classNames?: Partial<Record<ActiveShelfSemanticName, string>>\n /** \u4E86\u89E3\u66F4\u591A\u6309\u94AE\u6587\u672C */\n secondaryButtonText?: string\n /** \u4E86\u89E3\u66F4\u591A\u6309\u94AE\u529F\u80FD */\n secondaryButtonFun?: ButtonFunctionType\n /** \u7ACB\u5373\u8D2D\u4E70\u6309\u94AE\u6587\u672C */\n primaryButtonText?: string\n /** \u7ACB\u5373\u8D2D\u4E70\u6309\u94AE\u529F\u80FD */\n primaryButtonFun?: ButtonFunctionType\n /** \u662F\u5426\u5C55\u793A\u539F\u4EF7\uFF08\u5220\u9664\u7EBF\u4EF7\u683C\uFF09 */\n showOriginalPrice?: boolean\n /** \u6587\u6848\u914D\u7F6E */\n copy?: CopyConfig\n onProductImageClick?: (product: ProductCardData) => void\n}\n\n/**\n * \u5224\u65AD\u662F\u5426\u5E94\u8BE5\u663E\u793A\u5E93\u5B58\u4FE1\u606F\n * @param stockDisplayMode \u5E93\u5B58\u5C55\u793A\u6A21\u5F0F\n * @param stockThresholdValue \u5E93\u5B58\u9608\u503C\uFF08\u5F53\u6A21\u5F0F\u4E3A below-quantity \u6216 below-percentage \u65F6\u4F7F\u7528\uFF09\n * @param quantityAvailable \u53EF\u7528\u5E93\u5B58\u6570\u91CF\n * @param totalInventory \u603B\u5E93\u5B58\n * @returns \u662F\u5426\u663E\u793A\u5E93\u5B58\u4FE1\u606F\n */\nfunction shouldShowStock(\n stockDisplayMode: StockDisplayMode | undefined,\n stockThresholdValue: number | undefined,\n quantityAvailable: number,\n totalInventory: number\n): boolean {\n // \u672A\u914D\u7F6E\u65F6\u9ED8\u8BA4\u663E\u793A\n if (stockDisplayMode === undefined) {\n return true\n }\n\n // \u6839\u636E\u5C55\u793A\u6A21\u5F0F\u5224\u65AD\n switch (stockDisplayMode) {\n case 'always':\n // \u603B\u662F\u663E\u793A\n return true\n\n case 'never':\n // \u6C38\u4E0D\u663E\u793A\n return false\n\n case 'below-quantity':\n // \u5F53\u5E93\u5B58\u6570\u91CF\u4F4E\u4E8E\u9608\u503C\u65F6\u663E\u793A\n if (stockThresholdValue === undefined) {\n return true // \u6CA1\u6709\u8BBE\u7F6E\u9608\u503C\u65F6\u9ED8\u8BA4\u663E\u793A\n }\n\n return quantityAvailable <= stockThresholdValue\n\n case 'below-percentage':\n // \u5F53\u5E93\u5B58\u767E\u5206\u6BD4\u4F4E\u4E8E\u9608\u503C\u65F6\u663E\u793A\n if (stockThresholdValue === undefined) {\n return true // \u6CA1\u6709\u8BBE\u7F6E\u9608\u503C\u65F6\u9ED8\u8BA4\u663E\u793A\n }\n return (quantityAvailable / totalInventory) * 100 <= stockThresholdValue\n\n default:\n // \u672A\u77E5\u6A21\u5F0F\u65F6\u9ED8\u8BA4\u663E\u793A\n return true\n }\n}\n\n/**\n * \u4EA7\u54C1\u5361\u7247\u7EC4\u4EF6\n */\nconst ProductCard = React.forwardRef<HTMLDivElement, ProductCardProps>(\n (\n {\n product,\n className,\n showTags = true,\n stockDisplayMode,\n stockThresholdValue,\n onLearnMore,\n onShopNow,\n onAddToCart,\n classNames,\n secondaryButtonText,\n secondaryButtonFun,\n primaryButtonText,\n primaryButtonFun,\n showOriginalPrice,\n copy,\n onProductImageClick,\n },\n ref\n ) => {\n const [primaryLoading, setPrimaryLoading] = React.useState(false)\n const [secondaryLoading, setSecondaryLoading] = React.useState(false)\n\n const stockPercentage = React.useMemo(() => {\n if (product?.availableForSale && product?.quantityAvailable <= 0) {\n return OVERSELLING_STOCK_PERCENTAGE\n }\n // \u4E0D\u53EF\u552E\u65F6\u663E\u793A0%\n if (!product?.availableForSale) {\n return 0\n }\n return ((product?.quantityAvailable ?? 0) / (product?.totalInventory ?? 1)) * 100\n }, [product?.availableForSale, product?.quantityAvailable, product?.totalInventory])\n\n // \u6839\u636E\u6309\u94AE\u529F\u80FD\u7C7B\u578B\u8C03\u7528\u76F8\u5E94\u7684\u56DE\u8C03\u51FD\u6570\n const handleButtonClick = async (buttonFun?: ButtonFunctionType, buttonType?: 'primary' | 'secondary') => {\n if (!buttonFun) return\n\n const setLoading = buttonType === 'primary' ? setPrimaryLoading : setSecondaryLoading\n setLoading(true)\n\n try {\n switch (buttonFun) {\n case 'buyNow':\n await onShopNow?.(product)\n break\n case 'addCart':\n await onAddToCart?.(product)\n break\n case 'learnMore':\n await onLearnMore?.(product)\n break\n default:\n break\n }\n } finally {\n setLoading(false)\n }\n }\n\n const overselling = product.availableForSale && product.quantityAvailable <= 0\n\n return (\n <Card\n ref={ref}\n className={cn(\n 'bg-container-primary hover:bg-container-secondary-0 flex h-full flex-col overflow-hidden border-none',\n className,\n classNames?.productCard\n )}\n >\n <CardContent className=\"desktop:p-6 relative flex flex-1 flex-col justify-between p-4\">\n {/* \u6807\u7B7E */}\n <div className=\"lg-desktop:h-[28px] flex h-[24px] gap-1\">\n {showTags &&\n product.tags?.map((tag: any, index) =>\n (tag as any).label ? (\n <Badge\n key={index}\n size=\"sm\"\n variant={(tag.variant as any) || 'outline'}\n className={cn(tag.variant === 'promotional' ? 'ml-2' : '')}\n promotionalType={tag.promotionalType}\n >\n {tag.label}\n </Badge>\n ) : (\n <React.Fragment key={index}>{tag}</React.Fragment>\n )\n )}\n </div>\n\n {/* \u4EA7\u54C1\u56FE\u533A\u57DF */}\n <div className=\"product-image-wrapper lg-desktop:size-[196px] mx-auto size-[138px] cursor-pointer overflow-hidden\">\n <a\n onClick={() => onProductImageClick?.(product)}\n {...(!onProductImageClick && {\n href: product?.listingLink,\n })}\n rel=\"noreferrer\"\n >\n <Picture\n source={product.image}\n alt={product.name}\n className=\"aspect-square size-full object-contain\"\n imgClassName=\"w-full h-full object-contain\"\n />\n </a>\n </div>\n\n {/* \u5185\u5BB9\u533A\u57DF */}\n <div className=\"flex h-full flex-1 grow flex-col justify-between\">\n {/* \u4EA7\u54C1\u4FE1\u606F */}\n <div className=\"mb-4\">\n <Heading\n as=\"h3\"\n size={2}\n className={cn('text-info-primary mb-2 line-clamp-2 min-h-[2.4em]', classNames?.productTitle)}\n html={product.custom_name || product.name}\n />\n {product?.description && (\n <Text\n size={2}\n className={cn(\n 'text-info-secondary desktop:line-clamp-2 desktop:min-h-[2.4em] desktop:text-[16px] lg-desktop:text-[18px] line-clamp-2 min-h-[2.4em] 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=\"flex items-baseline gap-2\">\n {product.availableForSale ? (\n <>\n <Heading size={2} className=\"text-info-primary\" as=\"h6\">\n {product.price}\n </Heading>\n {showOriginalPrice && product.originalPrice && (\n <Heading\n size={2}\n className={cn('text-info-tertiary line-through', classNames?.originalPrice)}\n as=\"h6\"\n >\n {product.originalPrice}\n </Heading>\n )}\n </>\n ) : (\n <Heading size={2} className=\"text-info-tertiary\">\n {copy?.outOfStockLabel ?? 'Sold Out'}\n </Heading>\n )}\n </div>\n </div>\n\n {product?.priceLabel && product?.availableForSale && (\n <Text\n size={4}\n className={cn(\n 'text-marketing-1 desktop:text-[16px] lg-desktop:text-[18px] mt-2 text-[14px]',\n classNames?.productPriceLabel\n )}\n >\n {product.priceLabel}\n </Text>\n )}\n\n {/* \u6309\u94AE\u533A\u57DF */}\n <div className={cn('lg-desktop:gap-3 tablet:flex-nowrap flex flex-wrap gap-2', classNames?.buttonGroup)}>\n {secondaryButtonText && (\n <Button\n variant=\"secondary\"\n size=\"base\"\n className={cn('tablet:w-fit w-full', classNames?.secondaryButton)}\n onClick={() => handleButtonClick(secondaryButtonFun, 'secondary')}\n disabled={!product.availableForSale && secondaryButtonFun !== 'learnMore'}\n loading={secondaryLoading}\n data-headless-type-name=\"ActiveShelf#ProductCard\"\n data-headless-title-desc-button={`${product.custom_name || product.name}#${product.description || ''}#${secondaryButtonText}`}\n data-headless-sku={product.sku}\n >\n {secondaryButtonText}\n </Button>\n )}\n {primaryButtonText && (\n <Button\n variant=\"primary\"\n size=\"base\"\n className={cn('tablet:w-fit w-full', classNames?.primaryButton)}\n onClick={() => handleButtonClick(primaryButtonFun, 'primary')}\n disabled={!product.availableForSale && primaryButtonFun !== 'learnMore'}\n loading={primaryLoading}\n data-headless-type-name=\"ActiveShelf#ProductCard\"\n data-headless-title-desc-button={`${product.custom_name || product.name}#${product.description || ''}#${primaryButtonText}`}\n data-headless-sku={product.sku}\n >\n {primaryButtonText}\n </Button>\n )}\n </div>\n\n {/* \u5E93\u5B58\u4FE1\u606F */}\n {shouldShowStock(\n stockDisplayMode,\n stockThresholdValue,\n product?.quantityAvailable ?? 0,\n product?.totalInventory ?? 0\n ) && (\n <div className=\"mt-4 space-y-2\">\n <Progress\n value={stockPercentage}\n max={100}\n min={0}\n size=\"base\"\n variant=\"default\"\n aria-label=\"stock progress\"\n classNames={{\n root: cn('bg-[var(--progress-track-bg,rgba(0,0,0,0.2))]', classNames?.stockTrack),\n progressBar: cn('bg-brand-0 transition-all duration-300 ease-in-out', classNames?.stockBar),\n }}\n />\n <Text size={3} className=\"text-info-tertiary text-[14px]\">\n {overselling\n ? copy?.limitedStock\n : copy?.stockDisplayText?.replace(\n '{count}',\n `${product.availableForSale ? product.quantityAvailable : 0}`\n )}\n </Text>\n </div>\n )}\n </div>\n </div>\n </CardContent>\n </Card>\n )\n }\n)\n\nProductCard.displayName = 'ActiveShelf.ProductCard'\n\nexport { ProductCard }\nexport default ProductCard\n"],
|
|
5
|
-
"mappings": "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
|
|
4
|
+
"sourcesContent": ["'use client'\n\nimport * as React from 'react'\nimport { cn } from '../../helpers/index.js'\nimport { Button, Badge, Card, CardContent, Picture, Text, Heading, Progress } from '../../components/index.js'\n\nimport type { ButtonFunctionType, CopyConfig } from './types.js'\nimport type { BadgeProps } from '../../components/badge.js'\n\n/**\n * \u8D85\u5356\u65F6\u5E93\u5B58\u6761\u663E\u793A\u7684\u6700\u5C0F\u767E\u5206\u6BD4\n * \u9632\u6B62\u8D85\u5356\u65F6\u5E93\u5B58\u6761\u663E\u793A\u4E3A\u6EE1\u683C\uFF08100%\uFF09\u6216\u5B8C\u5168\u7A7A\uFF080%\uFF09\n */\nconst OVERSELLING_STOCK_PERCENTAGE = 5\n\n/**\n * \u8BED\u4E49\u5316\u7C7B\u540D\n */\nexport type ActiveShelfSemanticName =\n | 'root'\n | 'title'\n | 'description'\n | 'productCard'\n | 'productTitle'\n | 'productDescription'\n | 'productPriceLabel'\n | 'productPrice'\n | 'originalPrice'\n | 'buttonGroup'\n | 'secondaryButton'\n | 'primaryButton'\n | 'stockTrack'\n | 'stockBar'\n\n/**\n * \u5E93\u5B58\u5C55\u793A\u6A21\u5F0F\n */\nexport type StockDisplayMode = 'always' | 'never' | 'below-quantity' | 'below-percentage'\n\n/**\n * \u57FA\u7840\u4EA7\u54C1\u6570\u636E\u63A5\u53E3\uFF08\u6765\u81EA\u5916\u90E8\u6570\u636E\u6E90\uFF09\n */\nexport interface BaseProductData {\n sku: string\n name: string\n image: string\n value: string\n handle: string\n shopify_id: string\n custom_name?: string\n custom_description?: string\n}\n\n/**\n * Shopify \u53D8\u4F53\u6570\u636E\u63A5\u53E3\n */\nexport interface VariantData {\n /**\n * \u4EA7\u54C1\u63CF\u8FF0\n */\n description?: string\n /**\n * \u53D8\u4F53id\n */\n variantId: string\n\n /**\n * \u4EA7\u54C1\u94FE\u63A5, \u70B9\u51FB\u56FE\u7247\u7684\u65F6\u5019\u8DF3\u8F6C\u5230\u8BE5\u94FE\u63A5\n */\n listingLink: string\n /**\n * \u539F\u4EF7\n */\n originalPrice: string\n /**\n * \u73B0\u4EF7\n */\n price: string\n /**\n * \u4EF7\u683C\u4E0A\u9762\u5C55\u793A\u7684\u6807\u7B7E\u6587\u672C\n */\n priceLabel?: string\n /**\n * \u603B\u5E93\u5B58\n */\n totalInventory: number\n /**\n * \u53EF\u7528\u5E93\u5B58\u6570\u91CF\n */\n quantityAvailable: number\n /**\n * \u662F\u5426\u53EF\u552E\n */\n availableForSale: boolean\n\n /**\n * tags \u5217\u8868(\u4F1A\u5458\u4EF7\uFF0C\u6298\u6263\uFF0Cnew, hot\u7B49\u6807\u7B7E\u4FE1\u606F)\n */\n tags: Array<\n | {\n label: string\n variant: BadgeProps['variant']\n promotionalType?: BadgeProps['promotionalType']\n }\n | React.ReactNode\n >\n /**\n * \u901A\u7528\u6298\u6263\u6570\u636E\uFF0C\u5305\u62EC\u6298\u6263title, \u7C7B\u578B\u548C\u503C\n */\n coupon: any\n}\n\n/**\n * \u5B8C\u6574\u7684\u4EA7\u54C1\u5361\u7247\u6570\u636E\u63A5\u53E3\n */\nexport interface ProductCardData extends BaseProductData, VariantData {}\n\n/**\n * \u4EA7\u54C1\u5361\u7247\u7EC4\u4EF6 Props\n */\nexport interface ProductCardProps {\n /** \u4EA7\u54C1\u6570\u636E */\n product: ProductCardData\n /** \u6837\u5F0F\u7C7B\u540D */\n className?: string\n /** \u662F\u5426\u5C55\u793A\u6807\u7B7E\u7CFB\u7EDF */\n showTags?: boolean\n /** \u5E93\u5B58\u5C55\u793A\u6A21\u5F0F */\n stockDisplayMode?: StockDisplayMode\n /** \u5E93\u5B58\u9608\u503C\uFF08\u5F53\u6A21\u5F0F\u4E3A below-quantity \u6216 below-percentage \u65F6\u4F7F\u7528\uFF09 */\n stockThresholdValue?: number\n /** \u70B9\u51FB\u4E86\u89E3\u66F4\u591A\u56DE\u8C03 */\n onLearnMore?: (product: ProductCardData) => void\n /** \u70B9\u51FB\u7ACB\u5373\u8D2D\u4E70\u56DE\u8C03 */\n onShopNow?: (product: ProductCardData) => void\n /** \u70B9\u51FB\u52A0\u5165\u8D2D\u7269\u8F66\u56DE\u8C03 */\n onAddToCart?: (product: ProductCardData) => void\n /** \u8BED\u4E49\u5316\u7C7B\u540D */\n classNames?: Partial<Record<ActiveShelfSemanticName, string>>\n /** \u4E86\u89E3\u66F4\u591A\u6309\u94AE\u6587\u672C */\n secondaryButtonText?: string\n /** \u4E86\u89E3\u66F4\u591A\u6309\u94AE\u529F\u80FD */\n secondaryButtonFun?: ButtonFunctionType\n /** \u7ACB\u5373\u8D2D\u4E70\u6309\u94AE\u6587\u672C */\n primaryButtonText?: string\n /** \u7ACB\u5373\u8D2D\u4E70\u6309\u94AE\u529F\u80FD */\n primaryButtonFun?: ButtonFunctionType\n /** \u662F\u5426\u5C55\u793A\u539F\u4EF7\uFF08\u5220\u9664\u7EBF\u4EF7\u683C\uFF09 */\n showOriginalPrice?: boolean\n /** \u6587\u6848\u914D\u7F6E */\n copy?: CopyConfig\n onProductImageClick?: (product: ProductCardData) => void\n}\n\n/**\n * \u5224\u65AD\u662F\u5426\u5E94\u8BE5\u663E\u793A\u5E93\u5B58\u4FE1\u606F\n * @param stockDisplayMode \u5E93\u5B58\u5C55\u793A\u6A21\u5F0F\n * @param stockThresholdValue \u5E93\u5B58\u9608\u503C\uFF08\u5F53\u6A21\u5F0F\u4E3A below-quantity \u6216 below-percentage \u65F6\u4F7F\u7528\uFF09\n * @param quantityAvailable \u53EF\u7528\u5E93\u5B58\u6570\u91CF\n * @param totalInventory \u603B\u5E93\u5B58\n * @returns \u662F\u5426\u663E\u793A\u5E93\u5B58\u4FE1\u606F\n */\nfunction shouldShowStock(\n stockDisplayMode: StockDisplayMode | undefined,\n stockThresholdValue: number | undefined,\n quantityAvailable: number,\n totalInventory: number\n): boolean {\n // \u672A\u914D\u7F6E\u65F6\u9ED8\u8BA4\u663E\u793A\n if (stockDisplayMode === undefined) {\n return true\n }\n\n // \u6839\u636E\u5C55\u793A\u6A21\u5F0F\u5224\u65AD\n switch (stockDisplayMode) {\n case 'always':\n // \u603B\u662F\u663E\u793A\n return true\n\n case 'never':\n // \u6C38\u4E0D\u663E\u793A\n return false\n\n case 'below-quantity':\n // \u5F53\u5E93\u5B58\u6570\u91CF\u4F4E\u4E8E\u9608\u503C\u65F6\u663E\u793A\n if (stockThresholdValue === undefined) {\n return true // \u6CA1\u6709\u8BBE\u7F6E\u9608\u503C\u65F6\u9ED8\u8BA4\u663E\u793A\n }\n\n return quantityAvailable <= stockThresholdValue\n\n case 'below-percentage':\n // \u5F53\u5E93\u5B58\u767E\u5206\u6BD4\u4F4E\u4E8E\u9608\u503C\u65F6\u663E\u793A\n if (stockThresholdValue === undefined) {\n return true // \u6CA1\u6709\u8BBE\u7F6E\u9608\u503C\u65F6\u9ED8\u8BA4\u663E\u793A\n }\n return (quantityAvailable / totalInventory) * 100 <= stockThresholdValue\n\n default:\n // \u672A\u77E5\u6A21\u5F0F\u65F6\u9ED8\u8BA4\u663E\u793A\n return true\n }\n}\n\n/**\n * \u4EA7\u54C1\u5361\u7247\u7EC4\u4EF6\n */\nconst ProductCard = React.forwardRef<HTMLDivElement, ProductCardProps>(\n (\n {\n product,\n className,\n showTags = true,\n stockDisplayMode,\n stockThresholdValue,\n onLearnMore,\n onShopNow,\n onAddToCart,\n classNames,\n secondaryButtonText,\n secondaryButtonFun,\n primaryButtonText,\n primaryButtonFun,\n showOriginalPrice,\n copy,\n onProductImageClick,\n },\n ref\n ) => {\n const [primaryLoading, setPrimaryLoading] = React.useState(false)\n const [secondaryLoading, setSecondaryLoading] = React.useState(false)\n\n const stockPercentage = React.useMemo(() => {\n if (product?.availableForSale && product?.quantityAvailable <= 0) {\n return OVERSELLING_STOCK_PERCENTAGE\n }\n // \u4E0D\u53EF\u552E\u65F6\u663E\u793A0%\n if (!product?.availableForSale) {\n return 0\n }\n return ((product?.quantityAvailable ?? 0) / (product?.totalInventory ?? 1)) * 100\n }, [product?.availableForSale, product?.quantityAvailable, product?.totalInventory])\n\n // \u6839\u636E\u6309\u94AE\u529F\u80FD\u7C7B\u578B\u8C03\u7528\u76F8\u5E94\u7684\u56DE\u8C03\u51FD\u6570\n const handleButtonClick = async (buttonFun?: ButtonFunctionType, buttonType?: 'primary' | 'secondary') => {\n if (!buttonFun) return\n\n const setLoading = buttonType === 'primary' ? setPrimaryLoading : setSecondaryLoading\n setLoading(true)\n\n try {\n switch (buttonFun) {\n case 'buyNow':\n await onShopNow?.(product)\n break\n case 'addCart':\n await onAddToCart?.(product)\n break\n case 'learnMore':\n await onLearnMore?.(product)\n break\n default:\n break\n }\n } finally {\n setLoading(false)\n }\n }\n\n const overselling = product.availableForSale && product.quantityAvailable <= 0\n\n return (\n <Card\n ref={ref}\n className={cn(\n 'bg-container-primary hover:bg-container-secondary-0 flex h-full flex-col overflow-hidden border-none',\n className,\n classNames?.productCard\n )}\n >\n <CardContent className=\"desktop:p-6 relative flex flex-1 flex-col justify-between p-4\">\n {/* \u6807\u7B7E */}\n <div className=\"lg-desktop:h-[28px] flex h-[24px] gap-1\">\n {showTags &&\n product.tags?.map((tag: any, index) =>\n (tag as any).label ? (\n <Badge\n key={index}\n size=\"sm\"\n variant={(tag.variant as any) || 'outline'}\n className={cn(tag.variant === 'promotional' ? 'ml-2' : '')}\n promotionalType={tag.promotionalType}\n >\n {tag.label}\n </Badge>\n ) : (\n <React.Fragment key={index}>{tag}</React.Fragment>\n )\n )}\n </div>\n\n {/* \u4EA7\u54C1\u56FE\u533A\u57DF */}\n <div className=\"product-image-wrapper lg-desktop:size-[196px] mx-auto size-[138px] cursor-pointer overflow-hidden\">\n <a\n onClick={() => onProductImageClick?.(product)}\n {...(!onProductImageClick && {\n href: product?.listingLink,\n })}\n rel=\"noreferrer\"\n >\n <Picture\n source={product.image}\n alt={product.name}\n className=\"aspect-square size-full object-contain\"\n imgClassName=\"w-full h-full object-contain\"\n />\n </a>\n </div>\n\n {/* \u5185\u5BB9\u533A\u57DF */}\n <div className=\"flex h-full flex-1 grow flex-col justify-between\">\n {/* \u4EA7\u54C1\u4FE1\u606F */}\n <div className=\"mb-4\">\n <Heading\n as=\"h3\"\n size={2}\n className={cn('text-info-primary mb-2 line-clamp-2 min-h-[2.4em]', classNames?.productTitle)}\n html={product.custom_name || product.name}\n />\n {product?.description && (\n <Text\n size={2}\n className={cn(\n 'text-info-secondary desktop:line-clamp-2 desktop:min-h-[2.4em] desktop:text-[16px] lg-desktop:text-[18px] line-clamp-2 min-h-[2.4em] 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=\"flex items-baseline gap-2\">\n {product.availableForSale ? (\n <>\n <Heading size={2} className=\"text-info-primary\" as=\"h6\">\n {product.price}\n </Heading>\n {showOriginalPrice && product.originalPrice && (\n <Heading\n size={2}\n className={cn('text-info-tertiary line-through', classNames?.originalPrice)}\n as=\"h6\"\n >\n {product.originalPrice}\n </Heading>\n )}\n </>\n ) : (\n <Heading size={2} className=\"text-info-tertiary\">\n {copy?.outOfStockLabel ?? 'Sold Out'}\n </Heading>\n )}\n </div>\n </div>\n\n {product?.priceLabel && product?.availableForSale && (\n <Text\n size={4}\n className={cn(\n 'text-marketing-1 desktop:text-[16px] lg-desktop:text-[18px] mt-2 text-[14px]',\n classNames?.productPriceLabel\n )}\n >\n {product.priceLabel}\n </Text>\n )}\n\n {/* \u6309\u94AE\u533A\u57DF */}\n <div className={cn('lg-desktop:gap-3 tablet:flex-nowrap flex flex-wrap gap-2', classNames?.buttonGroup)}>\n {secondaryButtonText && (\n <Button\n variant=\"secondary\"\n size=\"base\"\n className={cn(\n 'tablet:w-fit tablet:min-w-0 tablet:whitespace-normal tablet:text-center w-full whitespace-nowrap',\n classNames?.secondaryButton\n )}\n onClick={() => handleButtonClick(secondaryButtonFun, 'secondary')}\n disabled={!product.availableForSale && secondaryButtonFun !== 'learnMore'}\n loading={secondaryLoading}\n data-headless-type-name=\"ActiveShelf#ProductCard\"\n data-headless-title-desc-button={`${product.custom_name || product.name}#${product.description || ''}#${secondaryButtonText}`}\n data-headless-sku={product.sku}\n >\n {secondaryButtonText}\n </Button>\n )}\n {primaryButtonText && (\n <Button\n variant=\"primary\"\n size=\"base\"\n className={cn(\n 'tablet:w-fit tablet:min-w-0 tablet:whitespace-normal tablet:text-center w-full whitespace-nowrap',\n classNames?.primaryButton\n )}\n onClick={() => handleButtonClick(primaryButtonFun, 'primary')}\n disabled={!product.availableForSale && primaryButtonFun !== 'learnMore'}\n loading={primaryLoading}\n data-headless-type-name=\"ActiveShelf#ProductCard\"\n data-headless-title-desc-button={`${product.custom_name || product.name}#${product.description || ''}#${primaryButtonText}`}\n data-headless-sku={product.sku}\n >\n {primaryButtonText}\n </Button>\n )}\n </div>\n\n {/* \u5E93\u5B58\u4FE1\u606F */}\n {shouldShowStock(\n stockDisplayMode,\n stockThresholdValue,\n product?.quantityAvailable ?? 0,\n product?.totalInventory ?? 0\n ) && (\n <div className=\"mt-4 space-y-2\">\n <Progress\n value={stockPercentage}\n max={100}\n min={0}\n size=\"base\"\n variant=\"default\"\n aria-label=\"stock progress\"\n classNames={{\n root: cn('bg-[var(--progress-track-bg,rgba(0,0,0,0.2))]', classNames?.stockTrack),\n progressBar: cn('bg-brand-0 transition-all duration-300 ease-in-out', classNames?.stockBar),\n }}\n />\n <Text size={3} className=\"text-info-tertiary text-[14px]\">\n {overselling\n ? copy?.limitedStock\n : copy?.stockDisplayText?.replace(\n '{count}',\n `${product.availableForSale ? product.quantityAvailable : 0}`\n )}\n </Text>\n </div>\n )}\n </div>\n </div>\n </CardContent>\n </Card>\n )\n }\n)\n\nProductCard.displayName = 'ActiveShelf.ProductCard'\n\nexport { ProductCard }\nexport default ProductCard\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
6
|
"names": ["Fragment", "jsx", "jsxs", "React", "cn", "Button", "Badge", "Card", "CardContent", "Picture", "Text", "Heading", "Progress", "OVERSELLING_STOCK_PERCENTAGE", "shouldShowStock", "stockDisplayMode", "stockThresholdValue", "quantityAvailable", "totalInventory", "ProductCard", "product", "className", "showTags", "onLearnMore", "onShopNow", "onAddToCart", "classNames", "secondaryButtonText", "secondaryButtonFun", "primaryButtonText", "primaryButtonFun", "showOriginalPrice", "copy", "onProductImageClick", "ref", "primaryLoading", "setPrimaryLoading", "secondaryLoading", "setSecondaryLoading", "stockPercentage", "handleButtonClick", "buttonFun", "buttonType", "setLoading", "overselling", "tag", "index", "ProductCard_default"]
|
|
7
7
|
}
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
"use client";import{Fragment as
|
|
1
|
+
"use client";import{Fragment as O,jsx as t,jsxs as r}from"react/jsx-runtime";import*as C from"react";import{cn as e}from"../../helpers/index.js";import m from"../../components/button.js";import{Text as u}from"../../components/text.js";import{Heading as g}from"../../components/index.js";const x=C.forwardRef(({currentPrice:f,originalPrice:i,priceLabel:n,learnMoreText:o="Learn More",shopNowText:s="Shop Now",soldOutText:h="Sold out",onLearnMore:y,onShopNow:P,availableForSale:l,learnMoreLoading:N,shopNowLoading:v,className:b,trackingTitle:d,trackingDescription:c,trackingSku:p,classNames:a},w)=>r("div",{ref:w,className:e("flex w-full flex-col justify-center gap-2",b),children:[t("div",{className:"flex w-full items-center gap-2",children:l?r(O,{children:[t(g,{size:2,className:e("text-info-primary"),children:f}),i&&t(g,{size:2,className:e("text-info-tertiary line-through",a?.productCardOriginalPrice),children:i})]}):t(u,{size:4,className:e("text-info-primary text-2xl leading-[1.2] tracking-[-0.48px]","tablet:text-xl tablet:tracking-[-0.4px]"),children:h})}),n&&t(u,{size:4,className:e("text-marketing-1 desktop:text-[16px] lg-desktop:text-[18px] text-[14px]",a?.productCardPriceLabel),children:n}),r("div",{className:e("flex w-full items-stretch gap-3","tablet:gap-2"),children:[t(m,{variant:"secondary",size:"lg",onClick:y,loading:N,className:e("min-w-0 flex-1 whitespace-normal text-center",a?.productCardBtnGroup),"data-headless-type-name":"BuyOneGetOneShelf#ProductCard","data-headless-title-desc-button":`${d||""}#${c||""}#${o}`,"data-headless-sku":p,children:o}),t(m,{variant:"primary",size:"lg",onClick:P,disabled:!l,loading:v,className:e("min-w-0 flex-1 whitespace-normal text-center",a?.productCardBtnGroup),"data-headless-type-name":"BuyOneGetOneShelf#ProductCard","data-headless-title-desc-button":`${d||""}#${c||""}#${s}`,"data-headless-sku":p,children:s})]})]}));x.displayName="PriceAndActions";var L=x;export{L as default};
|
|
2
2
|
//# sourceMappingURL=PriceAndActions.js.map
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../../../src/biz-components/BuyOneGetOneShelf/PriceAndActions.tsx"],
|
|
4
|
-
"sourcesContent": ["'use client'\n\nimport * as React from 'react'\nimport { cn } from '../../helpers/index.js'\nimport Button from '../../components/button.js'\nimport { Text } from '../../components/text.js'\nimport { Heading } from '../../components/index.js'\nimport type { BuyOneGetOneShelfProductCardSemanticName } from './types.js'\n\nexport interface PriceAndActionsProps extends React.HTMLAttributes<HTMLDivElement> {\n currentPrice: string\n originalPrice?: string\n priceLabel?: string\n learnMoreText?: string\n shopNowText?: string\n soldOutText?: string\n onLearnMore?: () => void\n onShopNow?: () => void\n availableForSale: boolean\n learnMoreLoading?: boolean\n shopNowLoading?: boolean\n trackingTitle?: string\n trackingDescription?: string\n trackingSku?: string\n classNames?: Partial<Record<BuyOneGetOneShelfProductCardSemanticName, string>>\n}\n\nconst PriceAndActions = React.forwardRef<HTMLDivElement, PriceAndActionsProps>(\n (\n {\n currentPrice,\n originalPrice,\n priceLabel,\n learnMoreText = 'Learn More',\n shopNowText = 'Shop Now',\n soldOutText = 'Sold out',\n onLearnMore,\n onShopNow,\n availableForSale,\n learnMoreLoading,\n shopNowLoading,\n className,\n trackingTitle,\n trackingDescription,\n trackingSku,\n classNames,\n },\n ref\n ) => {\n return (\n <div ref={ref} className={cn('flex w-full flex-col justify-center gap-2', className)}>\n <div className=\"flex w-full items-center gap-2\">\n {availableForSale ? (\n <>\n <Heading size={2} className={cn('text-info-primary')}>\n {currentPrice}\n </Heading>\n {originalPrice && (\n <Heading\n size={2}\n className={cn('text-info-tertiary line-through', classNames?.productCardOriginalPrice)}\n >\n {originalPrice}\n </Heading>\n )}\n </>\n ) : (\n <Text\n size={4}\n className={cn(\n 'text-info-primary text-2xl leading-[1.2] tracking-[-0.48px]',\n 'tablet:text-xl tablet:tracking-[-0.4px]'\n )}\n >\n {soldOutText}\n </Text>\n )}\n </div>\n\n {priceLabel && (\n <Text\n size={4}\n className={cn(\n 'text-marketing-1 desktop:text-[16px] lg-desktop:text-[18px] text-[14px]',\n classNames?.productCardPriceLabel\n )}\n >\n {priceLabel}\n </Text>\n )}\n\n {/* \u6309\u94AE\u7EC4 */}\n <div className={cn('flex w-full items-
|
|
5
|
-
"mappings": "aAqDY,mBAAAA,EACE,OAAAC,EADF,QAAAC,MAAA,oBAnDZ,UAAYC,MAAW,QACvB,OAAS,MAAAC,MAAU,yBACnB,OAAOC,MAAY,6BACnB,OAAS,QAAAC,MAAY,2BACrB,OAAS,WAAAC,MAAe,4BAqBxB,MAAMC,EAAkBL,EAAM,WAC5B,CACE,CACE,aAAAM,EACA,cAAAC,EACA,WAAAC,EACA,cAAAC,EAAgB,aAChB,YAAAC,EAAc,WACd,YAAAC,EAAc,WACd,YAAAC,EACA,UAAAC,EACA,iBAAAC,EACA,iBAAAC,EACA,eAAAC,EACA,UAAAC,EACA,cAAAC,EACA,oBAAAC,EACA,YAAAC,EACA,WAAAC,CACF,EACAC,IAGEvB,EAAC,OAAI,IAAKuB,EAAK,UAAWrB,EAAG,4CAA6CgB,CAAS,EACjF,UAAAnB,EAAC,OAAI,UAAU,iCACZ,SAAAgB,EACCf,EAAAF,EAAA,CACE,UAAAC,EAACM,EAAA,CAAQ,KAAM,EAAG,UAAWH,EAAG,mBAAmB,EAChD,SAAAK,EACH,EACCC,GACCT,EAACM,EAAA,CACC,KAAM,EACN,UAAWH,EAAG,kCAAmCoB,GAAY,wBAAwB,EAEpF,SAAAd,EACH,GAEJ,EAEAT,EAACK,EAAA,CACC,KAAM,EACN,UAAWF,EACT,8DACA,yCACF,EAEC,SAAAU,EACH,EAEJ,EAECH,GACCV,EAACK,EAAA,CACC,KAAM,EACN,UAAWF,EACT,0EACAoB,GAAY,qBACd,EAEC,SAAAb,EACH,EAIFT,EAAC,OAAI,UAAWE,EAAG,
|
|
4
|
+
"sourcesContent": ["'use client'\n\nimport * as React from 'react'\nimport { cn } from '../../helpers/index.js'\nimport Button from '../../components/button.js'\nimport { Text } from '../../components/text.js'\nimport { Heading } from '../../components/index.js'\nimport type { BuyOneGetOneShelfProductCardSemanticName } from './types.js'\n\nexport interface PriceAndActionsProps extends React.HTMLAttributes<HTMLDivElement> {\n currentPrice: string\n originalPrice?: string\n priceLabel?: string\n learnMoreText?: string\n shopNowText?: string\n soldOutText?: string\n onLearnMore?: () => void\n onShopNow?: () => void\n availableForSale: boolean\n learnMoreLoading?: boolean\n shopNowLoading?: boolean\n trackingTitle?: string\n trackingDescription?: string\n trackingSku?: string\n classNames?: Partial<Record<BuyOneGetOneShelfProductCardSemanticName, string>>\n}\n\nconst PriceAndActions = React.forwardRef<HTMLDivElement, PriceAndActionsProps>(\n (\n {\n currentPrice,\n originalPrice,\n priceLabel,\n learnMoreText = 'Learn More',\n shopNowText = 'Shop Now',\n soldOutText = 'Sold out',\n onLearnMore,\n onShopNow,\n availableForSale,\n learnMoreLoading,\n shopNowLoading,\n className,\n trackingTitle,\n trackingDescription,\n trackingSku,\n classNames,\n },\n ref\n ) => {\n return (\n <div ref={ref} className={cn('flex w-full flex-col justify-center gap-2', className)}>\n <div className=\"flex w-full items-center gap-2\">\n {availableForSale ? (\n <>\n <Heading size={2} className={cn('text-info-primary')}>\n {currentPrice}\n </Heading>\n {originalPrice && (\n <Heading\n size={2}\n className={cn('text-info-tertiary line-through', classNames?.productCardOriginalPrice)}\n >\n {originalPrice}\n </Heading>\n )}\n </>\n ) : (\n <Text\n size={4}\n className={cn(\n 'text-info-primary text-2xl leading-[1.2] tracking-[-0.48px]',\n 'tablet:text-xl tablet:tracking-[-0.4px]'\n )}\n >\n {soldOutText}\n </Text>\n )}\n </div>\n\n {priceLabel && (\n <Text\n size={4}\n className={cn(\n 'text-marketing-1 desktop:text-[16px] lg-desktop:text-[18px] text-[14px]',\n classNames?.productCardPriceLabel\n )}\n >\n {priceLabel}\n </Text>\n )}\n\n {/* \u6309\u94AE\u7EC4 */}\n <div className={cn('flex w-full items-stretch gap-3', 'tablet:gap-2')}>\n <Button\n variant=\"secondary\"\n size=\"lg\"\n onClick={onLearnMore}\n loading={learnMoreLoading}\n className={cn('min-w-0 flex-1 whitespace-normal text-center', classNames?.productCardBtnGroup)}\n data-headless-type-name=\"BuyOneGetOneShelf#ProductCard\"\n data-headless-title-desc-button={`${trackingTitle || ''}#${trackingDescription || ''}#${learnMoreText}`}\n data-headless-sku={trackingSku}\n >\n {learnMoreText}\n </Button>\n <Button\n variant=\"primary\"\n size=\"lg\"\n onClick={onShopNow}\n disabled={!availableForSale}\n loading={shopNowLoading}\n className={cn('min-w-0 flex-1 whitespace-normal text-center', classNames?.productCardBtnGroup)}\n data-headless-type-name=\"BuyOneGetOneShelf#ProductCard\"\n data-headless-title-desc-button={`${trackingTitle || ''}#${trackingDescription || ''}#${shopNowText}`}\n data-headless-sku={trackingSku}\n >\n {shopNowText}\n </Button>\n </div>\n </div>\n )\n }\n)\n\nPriceAndActions.displayName = 'PriceAndActions'\n\nexport default PriceAndActions\n"],
|
|
5
|
+
"mappings": "aAqDY,mBAAAA,EACE,OAAAC,EADF,QAAAC,MAAA,oBAnDZ,UAAYC,MAAW,QACvB,OAAS,MAAAC,MAAU,yBACnB,OAAOC,MAAY,6BACnB,OAAS,QAAAC,MAAY,2BACrB,OAAS,WAAAC,MAAe,4BAqBxB,MAAMC,EAAkBL,EAAM,WAC5B,CACE,CACE,aAAAM,EACA,cAAAC,EACA,WAAAC,EACA,cAAAC,EAAgB,aAChB,YAAAC,EAAc,WACd,YAAAC,EAAc,WACd,YAAAC,EACA,UAAAC,EACA,iBAAAC,EACA,iBAAAC,EACA,eAAAC,EACA,UAAAC,EACA,cAAAC,EACA,oBAAAC,EACA,YAAAC,EACA,WAAAC,CACF,EACAC,IAGEvB,EAAC,OAAI,IAAKuB,EAAK,UAAWrB,EAAG,4CAA6CgB,CAAS,EACjF,UAAAnB,EAAC,OAAI,UAAU,iCACZ,SAAAgB,EACCf,EAAAF,EAAA,CACE,UAAAC,EAACM,EAAA,CAAQ,KAAM,EAAG,UAAWH,EAAG,mBAAmB,EAChD,SAAAK,EACH,EACCC,GACCT,EAACM,EAAA,CACC,KAAM,EACN,UAAWH,EAAG,kCAAmCoB,GAAY,wBAAwB,EAEpF,SAAAd,EACH,GAEJ,EAEAT,EAACK,EAAA,CACC,KAAM,EACN,UAAWF,EACT,8DACA,yCACF,EAEC,SAAAU,EACH,EAEJ,EAECH,GACCV,EAACK,EAAA,CACC,KAAM,EACN,UAAWF,EACT,0EACAoB,GAAY,qBACd,EAEC,SAAAb,EACH,EAIFT,EAAC,OAAI,UAAWE,EAAG,kCAAmC,cAAc,EAClE,UAAAH,EAACI,EAAA,CACC,QAAQ,YACR,KAAK,KACL,QAASU,EACT,QAASG,EACT,UAAWd,EAAG,+CAAgDoB,GAAY,mBAAmB,EAC7F,0BAAwB,gCACxB,kCAAiC,GAAGH,GAAiB,EAAE,IAAIC,GAAuB,EAAE,IAAIV,CAAa,GACrG,oBAAmBW,EAElB,SAAAX,EACH,EACAX,EAACI,EAAA,CACC,QAAQ,UACR,KAAK,KACL,QAASW,EACT,SAAU,CAACC,EACX,QAASE,EACT,UAAWf,EAAG,+CAAgDoB,GAAY,mBAAmB,EAC7F,0BAAwB,gCACxB,kCAAiC,GAAGH,GAAiB,EAAE,IAAIC,GAAuB,EAAE,IAAIT,CAAW,GACnG,oBAAmBU,EAElB,SAAAV,EACH,GACF,GACF,CAGN,EAEAL,EAAgB,YAAc,kBAE9B,IAAOkB,EAAQlB",
|
|
6
6
|
"names": ["Fragment", "jsx", "jsxs", "React", "cn", "Button", "Text", "Heading", "PriceAndActions", "currentPrice", "originalPrice", "priceLabel", "learnMoreText", "shopNowText", "soldOutText", "onLearnMore", "onShopNow", "availableForSale", "learnMoreLoading", "shopNowLoading", "className", "trackingTitle", "trackingDescription", "trackingSku", "classNames", "ref", "PriceAndActions_default"]
|
|
7
7
|
}
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
"use client";import{Fragment as W,jsx as a,jsxs as
|
|
1
|
+
"use client";import{Fragment as W,jsx as a,jsxs as i}from"react/jsx-runtime";import*as r from"react";import{cn as o}from"../../helpers/index.js";import{Button as v,Badge as Z,Card as J,CardContent as K,Picture as Q,Text as u,Heading as c}from"../../components/index.js";import{useCreditsShelfContext as U}from"./context.js";const V=()=>a("svg",{width:"16",height:"16",viewBox:"0 0 16 16",fill:"none",xmlns:"http://www.w3.org/2000/svg",children:a("path",{d:"M8 1L10.163 5.279L15 6.001L11.5 9.409L12.326 14.226L8 11.97L3.674 14.226L4.5 9.409L1 6.001L5.837 5.279L8 1Z",fill:"currentColor"})}),g=r.forwardRef(({product:e,className:w,showTags:b,onLearnMore:N,onShopNow:k,onAddToCart:P,classNames:T,secondaryButtonText:B,secondaryButtonFun:L,primaryButtonText:S,primaryButtonFun:F,showOriginalPrice:z,copy:M,onProductImageClick:D},A)=>{const t=U(),O=b??t?.showTags??!0,$=z??t?.showOriginalPrice??!0,d=M??t?.copy,n=T??t?.classNames,m=B??t?.secondaryButtonText,f=L??t?.secondaryButtonFun,p=S??t?.primaryButtonText,y=F??t?.primaryButtonFun,j=N??t?.onLearnMore,H=k??t?.onShopNow,I=P??t?.onAddToCart,x=D??t?.onProductImageClick,[R,_]=r.useState(!1),[q,E]=r.useState(!1),h=async(s,l)=>{if(!s)return;const C=l==="primary"?_:E;C(!0);try{switch(s){case"buyNow":await H?.(e);break;case"addCart":await I?.(e);break;case"learnMore":await j?.(e);break;default:break}}finally{C(!1)}},G=r.useMemo(()=>e.creditSavingAmount?(d?.creditsSavingLabel??"Save up to {amount} with Credits").replace("{amount}",e.creditSavingAmount):null,[e.creditSavingAmount,d?.creditsSavingLabel]);return i(J,{ref:A,className:o("bg-container-primary hover:bg-container-secondary-0 box-border flex h-full flex-col overflow-hidden border-none",w,n?.productCard),children:[i(K,{className:"lg-desktop:gap-[10px] lg-desktop:px-6 lg-desktop:py-4 relative flex flex-1 flex-col gap-2 p-4",children:[a("div",{className:"lg-desktop:h-[28px] flex h-[24px] gap-1",children:O&&e.tags?.map((s,l)=>s.label?a(Z,{size:"sm",variant:s.variant||"outline",className:o(s.variant==="promotional"?"ml-2":""),promotionalType:s.promotionalType,children:s.label},l):a(r.Fragment,{children:s},l))}),a("div",{className:"product-image-wrapper lg-desktop:size-[196px] mx-auto size-[138px] cursor-pointer overflow-hidden",children:a("a",{onClick:()=>x?.(e),...!x&&{href:e?.listingLink},rel:"noreferrer",children:a(Q,{source:e.image,alt:e.name,className:"aspect-square size-full object-contain",imgClassName:"w-full h-full object-contain"})})}),i("div",{className:"lg-desktop:gap-6 flex flex-1 grow flex-col justify-between gap-4",children:[i("div",{className:"lg-desktop:gap-1 flex flex-col gap-0.5",children:[a(c,{as:"h3",size:2,className:o("text-info-primary line-clamp-2 min-h-[2.4em]",n?.productTitle),html:e.custom_name||e.name}),e?.description&&a(u,{size:2,className:o("text-info-secondary desktop:line-clamp-2 desktop:min-h-[2.4em] line-clamp-2 min-h-[2.4em]",n?.productDescription),html:e.custom_description||e.description})]}),i("div",{className:"lg-desktop:gap-2 flex flex-col gap-1.5",children:[a("div",{className:o(n?.productPrice),children:a("div",{className:"flex items-baseline gap-1",children:e.availableForSale?i(W,{children:[a(c,{size:2,className:"text-info-primary",as:"h6",children:e.price}),$&&e.originalPrice&&a(c,{size:2,className:o("text-info-tertiary line-through",n?.originalPrice),as:"h6",children:e.originalPrice})]}):a(c,{size:2,className:"text-info-tertiary",children:d?.outOfStockLabel??"Sold Out"})})}),e?.priceLabel&&a(u,{size:4,className:o("text-marketing-1 desktop:text-[16px] lg-desktop:text-[18px] text-[14px]",n?.productPriceLabel),children:e.priceLabel}),i("div",{className:o("lg-desktop:gap-3 tablet:flex-nowrap flex flex-wrap gap-2",n?.buttonGroup),children:[m&&a(v,{variant:"secondary",size:"base",className:o("tablet:w-fit tablet:min-w-0 tablet:whitespace-normal tablet:text-center w-full whitespace-nowrap",n?.secondaryButton),onClick:()=>h(f,"secondary"),disabled:!e.availableForSale&&f!=="learnMore",loading:q,"data-headless-type-name":"CreditsShelf#ProductCard","data-headless-title-desc-button":`${e.custom_name||e.name}#${e.description||""}#${m}`,"data-headless-sku":e.sku,children:m}),p&&a(v,{variant:"primary",size:"base",className:o("tablet:w-fit tablet:min-w-0 tablet:whitespace-normal tablet:text-center w-full whitespace-nowrap",n?.primaryButton),onClick:()=>h(y,"primary"),disabled:!e.availableForSale&&y!=="learnMore",loading:R,"data-headless-type-name":"CreditsShelf#ProductCard","data-headless-title-desc-button":`${e.custom_name||e.name}#${e.description||""}#${p}`,"data-headless-sku":e.sku,children:p})]})]})]})]}),i("div",{className:o("bg-container-secondary-0 lg-desktop:px-6 lg-desktop:py-4 flex items-center justify-center gap-1 px-4 py-3",n?.creditTip),children:[a("div",{className:"bg-info-primary flex size-6 items-center justify-center rounded-full p-1",children:a("span",{className:"text-info-white",children:a(V,{})})}),a(u,{size:2,className:"text-info-primary",children:G})]})]})});g.displayName="CreditsShelf.ProductCard";var ae=g;export{g as CreditsProductCard,ae as default};
|
|
2
2
|
//# sourceMappingURL=ProductCard.js.map
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../../../src/biz-components/CreditsShelf/ProductCard.tsx"],
|
|
4
|
-
"sourcesContent": ["'use client'\n\nimport * as React from 'react'\nimport { cn } from '../../helpers/index.js'\nimport { Button, Badge, Card, CardContent, Picture, Text, Heading } from '../../components/index.js'\n\nimport type { ButtonFunctionType, CopyConfig, CreditsShelfSemanticName, CreditsProductCardData } from './types.js'\nimport { useCreditsShelfContext } from './context.js'\n\n/**\n * \u4EA7\u54C1\u5361\u7247\u7EC4\u4EF6 Props\n */\nexport interface CreditsProductCardProps {\n /** \u4EA7\u54C1\u6570\u636E */\n product: CreditsProductCardData\n /** \u6837\u5F0F\u7C7B\u540D */\n className?: string\n /** \u662F\u5426\u5C55\u793A\u6807\u7B7E\u7CFB\u7EDF */\n showTags?: boolean\n /** \u70B9\u51FB\u4E86\u89E3\u66F4\u591A\u56DE\u8C03 */\n onLearnMore?: (product: CreditsProductCardData) => void\n /** \u70B9\u51FB\u7ACB\u5373\u8D2D\u4E70\u56DE\u8C03 */\n onShopNow?: (product: CreditsProductCardData) => void\n /** \u70B9\u51FB\u52A0\u5165\u8D2D\u7269\u8F66\u56DE\u8C03 */\n onAddToCart?: (product: CreditsProductCardData) => void\n /** \u8BED\u4E49\u5316\u7C7B\u540D */\n classNames?: Partial<Record<CreditsShelfSemanticName, string>>\n /** \u4E86\u89E3\u66F4\u591A\u6309\u94AE\u6587\u672C */\n secondaryButtonText?: string\n /** \u4E86\u89E3\u66F4\u591A\u6309\u94AE\u529F\u80FD */\n secondaryButtonFun?: ButtonFunctionType\n /** \u7ACB\u5373\u8D2D\u4E70\u6309\u94AE\u6587\u672C */\n primaryButtonText?: string\n /** \u7ACB\u5373\u8D2D\u4E70\u6309\u94AE\u529F\u80FD */\n primaryButtonFun?: ButtonFunctionType\n /** \u662F\u5426\u5C55\u793A\u539F\u4EF7\uFF08\u5220\u9664\u7EBF\u4EF7\u683C\uFF09 */\n showOriginalPrice?: boolean\n /** \u6587\u6848\u914D\u7F6E */\n copy?: CopyConfig\n /** \u4EA7\u54C1\u56FE\u7247\u70B9\u51FB\u56DE\u8C03 */\n onProductImageClick?: (product: CreditsProductCardData) => void\n}\n\n/**\n * \u661F\u661F\u56FE\u6807\u7EC4\u4EF6\n */\nconst StarIcon = () => (\n <svg width=\"16\" height=\"16\" viewBox=\"0 0 16 16\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\">\n <path\n d=\"M8 1L10.163 5.279L15 6.001L11.5 9.409L12.326 14.226L8 11.97L3.674 14.226L4.5 9.409L1 6.001L5.837 5.279L8 1Z\"\n fill=\"currentColor\"\n />\n </svg>\n)\n\n/**\n * CreditsShelf \u4EA7\u54C1\u5361\u7247\u7EC4\u4EF6\n */\nconst CreditsProductCard = React.forwardRef<HTMLDivElement, CreditsProductCardProps>(\n (\n {\n product,\n className,\n showTags: showTagsProp,\n onLearnMore: onLearnMoreProp,\n onShopNow: onShopNowProp,\n onAddToCart: onAddToCartProp,\n classNames: classNamesProp,\n secondaryButtonText: secondaryButtonTextProp,\n secondaryButtonFun: secondaryButtonFunProp,\n primaryButtonText: primaryButtonTextProp,\n primaryButtonFun: primaryButtonFunProp,\n showOriginalPrice: showOriginalPriceProp,\n copy: copyProp,\n onProductImageClick: onProductImageClickProp,\n },\n ref\n ) => {\n // \u4ECE Context \u8BFB\u53D6\u914D\u7F6E\n const context = useCreditsShelfContext()\n\n // Props \u4F18\u5148\u7EA7\u9AD8\u4E8E Context\n const showTags = showTagsProp ?? context?.showTags ?? true\n const showOriginalPrice = showOriginalPriceProp ?? context?.showOriginalPrice ?? true\n const copy = copyProp ?? context?.copy\n const classNames = classNamesProp ?? context?.classNames\n const secondaryButtonText = secondaryButtonTextProp ?? context?.secondaryButtonText\n const secondaryButtonFun = secondaryButtonFunProp ?? context?.secondaryButtonFun\n const primaryButtonText = primaryButtonTextProp ?? context?.primaryButtonText\n const primaryButtonFun = primaryButtonFunProp ?? context?.primaryButtonFun\n const onLearnMore = onLearnMoreProp ?? context?.onLearnMore\n const onShopNow = onShopNowProp ?? context?.onShopNow\n const onAddToCart = onAddToCartProp ?? context?.onAddToCart\n const onProductImageClick = onProductImageClickProp ?? context?.onProductImageClick\n\n const [primaryLoading, setPrimaryLoading] = React.useState(false)\n const [secondaryLoading, setSecondaryLoading] = React.useState(false)\n\n // \u6839\u636E\u6309\u94AE\u529F\u80FD\u7C7B\u578B\u8C03\u7528\u76F8\u5E94\u7684\u56DE\u8C03\u51FD\u6570\n const handleButtonClick = async (buttonFun?: ButtonFunctionType, buttonType?: 'primary' | 'secondary') => {\n if (!buttonFun) return\n\n const setLoading = buttonType === 'primary' ? setPrimaryLoading : setSecondaryLoading\n setLoading(true)\n\n try {\n switch (buttonFun) {\n case 'buyNow':\n await onShopNow?.(product)\n break\n case 'addCart':\n await onAddToCart?.(product)\n break\n case 'learnMore':\n await onLearnMore?.(product)\n break\n default:\n break\n }\n } finally {\n setLoading(false)\n }\n }\n\n // \u751F\u6210\u79EF\u5206\u62B5\u73B0\u63D0\u793A\u6587\u672C\n const creditTipText = React.useMemo(() => {\n if (!product.creditSavingAmount) return null\n const template = copy?.creditsSavingLabel ?? 'Save up to {amount} with Credits'\n return template.replace('{amount}', product.creditSavingAmount)\n }, [product.creditSavingAmount, copy?.creditsSavingLabel])\n\n return (\n <Card\n ref={ref}\n className={cn(\n 'bg-container-primary hover:bg-container-secondary-0 box-border flex h-full flex-col overflow-hidden border-none',\n className,\n classNames?.productCard\n )}\n >\n {/* \u4E3B\u5185\u5BB9\u533A\u57DF */}\n <CardContent className=\"lg-desktop:gap-[10px] lg-desktop:px-6 lg-desktop:py-4 relative flex flex-1 flex-col gap-2 p-4\">\n {/* \u6807\u7B7E */}\n <div className=\"lg-desktop:h-[28px] flex h-[24px] gap-1\">\n {showTags &&\n product.tags?.map((tag: any, index) =>\n (tag as any).label ? (\n <Badge\n key={index}\n size=\"sm\"\n variant={(tag.variant as any) || 'outline'}\n className={cn(tag.variant === 'promotional' ? 'ml-2' : '')}\n promotionalType={tag.promotionalType}\n >\n {tag.label}\n </Badge>\n ) : (\n <React.Fragment key={index}>{tag}</React.Fragment>\n )\n )}\n </div>\n\n {/* \u4EA7\u54C1\u56FE\u533A\u57DF */}\n <div className=\"product-image-wrapper lg-desktop:size-[196px] mx-auto size-[138px] cursor-pointer overflow-hidden\">\n <a\n onClick={() => onProductImageClick?.(product)}\n {...(!onProductImageClick && {\n href: product?.listingLink,\n })}\n rel=\"noreferrer\"\n >\n <Picture\n source={product.image}\n alt={product.name}\n className=\"aspect-square size-full object-contain\"\n imgClassName=\"w-full h-full object-contain\"\n />\n </a>\n </div>\n\n {/* \u5185\u5BB9\u533A\u57DF */}\n <div className=\"lg-desktop:gap-6 flex flex-1 grow flex-col justify-between gap-4\">\n {/* \u4EA7\u54C1\u4FE1\u606F */}\n <div className=\"lg-desktop:gap-1 flex flex-col gap-0.5\">\n <Heading\n as=\"h3\"\n size={2}\n className={cn('text-info-primary line-clamp-2 min-h-[2.4em]', classNames?.productTitle)}\n html={product.custom_name || product.name}\n />\n {product?.description && (\n <Text\n size={2}\n className={cn(\n 'text-info-secondary desktop:line-clamp-2 desktop:min-h-[2.4em] line-clamp-2 min-h-[2.4em]',\n classNames?.productDescription\n )}\n html={product.custom_description || product.description}\n />\n )}\n </div>\n\n {/* \u4EF7\u683C\u533A\u57DF */}\n <div className=\"lg-desktop:gap-2 flex flex-col gap-1.5\">\n {/* \u4EF7\u683C */}\n <div className={cn(classNames?.productPrice)}>\n <div className=\"flex items-baseline gap-1\">\n {product.availableForSale ? (\n <>\n <Heading size={2} className=\"text-info-primary\" as=\"h6\">\n {product.price}\n </Heading>\n {showOriginalPrice && product.originalPrice && (\n <Heading\n size={2}\n className={cn('text-info-tertiary line-through', classNames?.originalPrice)}\n as=\"h6\"\n >\n {product.originalPrice}\n </Heading>\n )}\n </>\n ) : (\n <Heading size={2} className=\"text-info-tertiary\">\n {copy?.outOfStockLabel ?? 'Sold Out'}\n </Heading>\n )}\n </div>\n </div>\n\n {product?.priceLabel && (\n <Text\n size={4}\n className={cn(\n 'text-marketing-1 desktop:text-[16px] lg-desktop:text-[18px] text-[14px]',\n classNames?.productPriceLabel\n )}\n >\n {product.priceLabel}\n </Text>\n )}\n\n {/* \u6309\u94AE\u533A\u57DF */}\n <div className={cn('lg-desktop:gap-3 flex flex-nowrap gap-2', classNames?.buttonGroup)}>\n {secondaryButtonText && (\n <Button\n variant=\"secondary\"\n size=\"base\"\n className={cn('tablet:w-fit w-full', classNames?.secondaryButton)}\n onClick={() => handleButtonClick(secondaryButtonFun, 'secondary')}\n disabled={!product.availableForSale && secondaryButtonFun !== 'learnMore'}\n loading={secondaryLoading}\n data-headless-type-name=\"CreditsShelf#ProductCard\"\n data-headless-title-desc-button={`${product.custom_name || product.name}#${product.description || ''}#${secondaryButtonText}`}\n data-headless-sku={product.sku}\n >\n {secondaryButtonText}\n </Button>\n )}\n {primaryButtonText && (\n <Button\n variant=\"primary\"\n size=\"base\"\n className={cn('tablet:w-fit w-full', classNames?.primaryButton)}\n onClick={() => handleButtonClick(primaryButtonFun, 'primary')}\n disabled={!product.availableForSale && primaryButtonFun !== 'learnMore'}\n loading={primaryLoading}\n data-headless-type-name=\"CreditsShelf#ProductCard\"\n data-headless-title-desc-button={`${product.custom_name || product.name}#${product.description || ''}#${primaryButtonText}`}\n data-headless-sku={product.sku}\n >\n {primaryButtonText}\n </Button>\n )}\n </div>\n </div>\n </div>\n </CardContent>\n\n {/* \u5E95\u90E8\u79EF\u5206\u62B5\u73B0\u63D0\u793A\u6761 */}\n <div\n className={cn(\n 'bg-container-secondary-0 lg-desktop:px-6 lg-desktop:py-4 flex items-center justify-center gap-1 px-4 py-3',\n classNames?.creditTip\n )}\n >\n <div className=\"bg-info-primary flex size-6 items-center justify-center rounded-full p-1\">\n <span className=\"text-info-white\">\n <StarIcon />\n </span>\n </div>\n <Text size={2} className=\"text-info-primary\">\n {creditTipText}\n </Text>\n </div>\n </Card>\n )\n }\n)\n\nCreditsProductCard.displayName = 'CreditsShelf.ProductCard'\n\nexport { CreditsProductCard }\nexport default CreditsProductCard\n"],
|
|
5
|
-
"mappings": "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
|
|
4
|
+
"sourcesContent": ["'use client'\n\nimport * as React from 'react'\nimport { cn } from '../../helpers/index.js'\nimport { Button, Badge, Card, CardContent, Picture, Text, Heading } from '../../components/index.js'\n\nimport type { ButtonFunctionType, CopyConfig, CreditsShelfSemanticName, CreditsProductCardData } from './types.js'\nimport { useCreditsShelfContext } from './context.js'\n\n/**\n * \u4EA7\u54C1\u5361\u7247\u7EC4\u4EF6 Props\n */\nexport interface CreditsProductCardProps {\n /** \u4EA7\u54C1\u6570\u636E */\n product: CreditsProductCardData\n /** \u6837\u5F0F\u7C7B\u540D */\n className?: string\n /** \u662F\u5426\u5C55\u793A\u6807\u7B7E\u7CFB\u7EDF */\n showTags?: boolean\n /** \u70B9\u51FB\u4E86\u89E3\u66F4\u591A\u56DE\u8C03 */\n onLearnMore?: (product: CreditsProductCardData) => void\n /** \u70B9\u51FB\u7ACB\u5373\u8D2D\u4E70\u56DE\u8C03 */\n onShopNow?: (product: CreditsProductCardData) => void\n /** \u70B9\u51FB\u52A0\u5165\u8D2D\u7269\u8F66\u56DE\u8C03 */\n onAddToCart?: (product: CreditsProductCardData) => void\n /** \u8BED\u4E49\u5316\u7C7B\u540D */\n classNames?: Partial<Record<CreditsShelfSemanticName, string>>\n /** \u4E86\u89E3\u66F4\u591A\u6309\u94AE\u6587\u672C */\n secondaryButtonText?: string\n /** \u4E86\u89E3\u66F4\u591A\u6309\u94AE\u529F\u80FD */\n secondaryButtonFun?: ButtonFunctionType\n /** \u7ACB\u5373\u8D2D\u4E70\u6309\u94AE\u6587\u672C */\n primaryButtonText?: string\n /** \u7ACB\u5373\u8D2D\u4E70\u6309\u94AE\u529F\u80FD */\n primaryButtonFun?: ButtonFunctionType\n /** \u662F\u5426\u5C55\u793A\u539F\u4EF7\uFF08\u5220\u9664\u7EBF\u4EF7\u683C\uFF09 */\n showOriginalPrice?: boolean\n /** \u6587\u6848\u914D\u7F6E */\n copy?: CopyConfig\n /** \u4EA7\u54C1\u56FE\u7247\u70B9\u51FB\u56DE\u8C03 */\n onProductImageClick?: (product: CreditsProductCardData) => void\n}\n\n/**\n * \u661F\u661F\u56FE\u6807\u7EC4\u4EF6\n */\nconst StarIcon = () => (\n <svg width=\"16\" height=\"16\" viewBox=\"0 0 16 16\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\">\n <path\n d=\"M8 1L10.163 5.279L15 6.001L11.5 9.409L12.326 14.226L8 11.97L3.674 14.226L4.5 9.409L1 6.001L5.837 5.279L8 1Z\"\n fill=\"currentColor\"\n />\n </svg>\n)\n\n/**\n * CreditsShelf \u4EA7\u54C1\u5361\u7247\u7EC4\u4EF6\n */\nconst CreditsProductCard = React.forwardRef<HTMLDivElement, CreditsProductCardProps>(\n (\n {\n product,\n className,\n showTags: showTagsProp,\n onLearnMore: onLearnMoreProp,\n onShopNow: onShopNowProp,\n onAddToCart: onAddToCartProp,\n classNames: classNamesProp,\n secondaryButtonText: secondaryButtonTextProp,\n secondaryButtonFun: secondaryButtonFunProp,\n primaryButtonText: primaryButtonTextProp,\n primaryButtonFun: primaryButtonFunProp,\n showOriginalPrice: showOriginalPriceProp,\n copy: copyProp,\n onProductImageClick: onProductImageClickProp,\n },\n ref\n ) => {\n // \u4ECE Context \u8BFB\u53D6\u914D\u7F6E\n const context = useCreditsShelfContext()\n\n // Props \u4F18\u5148\u7EA7\u9AD8\u4E8E Context\n const showTags = showTagsProp ?? context?.showTags ?? true\n const showOriginalPrice = showOriginalPriceProp ?? context?.showOriginalPrice ?? true\n const copy = copyProp ?? context?.copy\n const classNames = classNamesProp ?? context?.classNames\n const secondaryButtonText = secondaryButtonTextProp ?? context?.secondaryButtonText\n const secondaryButtonFun = secondaryButtonFunProp ?? context?.secondaryButtonFun\n const primaryButtonText = primaryButtonTextProp ?? context?.primaryButtonText\n const primaryButtonFun = primaryButtonFunProp ?? context?.primaryButtonFun\n const onLearnMore = onLearnMoreProp ?? context?.onLearnMore\n const onShopNow = onShopNowProp ?? context?.onShopNow\n const onAddToCart = onAddToCartProp ?? context?.onAddToCart\n const onProductImageClick = onProductImageClickProp ?? context?.onProductImageClick\n\n const [primaryLoading, setPrimaryLoading] = React.useState(false)\n const [secondaryLoading, setSecondaryLoading] = React.useState(false)\n\n // \u6839\u636E\u6309\u94AE\u529F\u80FD\u7C7B\u578B\u8C03\u7528\u76F8\u5E94\u7684\u56DE\u8C03\u51FD\u6570\n const handleButtonClick = async (buttonFun?: ButtonFunctionType, buttonType?: 'primary' | 'secondary') => {\n if (!buttonFun) return\n\n const setLoading = buttonType === 'primary' ? setPrimaryLoading : setSecondaryLoading\n setLoading(true)\n\n try {\n switch (buttonFun) {\n case 'buyNow':\n await onShopNow?.(product)\n break\n case 'addCart':\n await onAddToCart?.(product)\n break\n case 'learnMore':\n await onLearnMore?.(product)\n break\n default:\n break\n }\n } finally {\n setLoading(false)\n }\n }\n\n // \u751F\u6210\u79EF\u5206\u62B5\u73B0\u63D0\u793A\u6587\u672C\n const creditTipText = React.useMemo(() => {\n if (!product.creditSavingAmount) return null\n const template = copy?.creditsSavingLabel ?? 'Save up to {amount} with Credits'\n return template.replace('{amount}', product.creditSavingAmount)\n }, [product.creditSavingAmount, copy?.creditsSavingLabel])\n\n return (\n <Card\n ref={ref}\n className={cn(\n 'bg-container-primary hover:bg-container-secondary-0 box-border flex h-full flex-col overflow-hidden border-none',\n className,\n classNames?.productCard\n )}\n >\n {/* \u4E3B\u5185\u5BB9\u533A\u57DF */}\n <CardContent className=\"lg-desktop:gap-[10px] lg-desktop:px-6 lg-desktop:py-4 relative flex flex-1 flex-col gap-2 p-4\">\n {/* \u6807\u7B7E */}\n <div className=\"lg-desktop:h-[28px] flex h-[24px] gap-1\">\n {showTags &&\n product.tags?.map((tag: any, index) =>\n (tag as any).label ? (\n <Badge\n key={index}\n size=\"sm\"\n variant={(tag.variant as any) || 'outline'}\n className={cn(tag.variant === 'promotional' ? 'ml-2' : '')}\n promotionalType={tag.promotionalType}\n >\n {tag.label}\n </Badge>\n ) : (\n <React.Fragment key={index}>{tag}</React.Fragment>\n )\n )}\n </div>\n\n {/* \u4EA7\u54C1\u56FE\u533A\u57DF */}\n <div className=\"product-image-wrapper lg-desktop:size-[196px] mx-auto size-[138px] cursor-pointer overflow-hidden\">\n <a\n onClick={() => onProductImageClick?.(product)}\n {...(!onProductImageClick && {\n href: product?.listingLink,\n })}\n rel=\"noreferrer\"\n >\n <Picture\n source={product.image}\n alt={product.name}\n className=\"aspect-square size-full object-contain\"\n imgClassName=\"w-full h-full object-contain\"\n />\n </a>\n </div>\n\n {/* \u5185\u5BB9\u533A\u57DF */}\n <div className=\"lg-desktop:gap-6 flex flex-1 grow flex-col justify-between gap-4\">\n {/* \u4EA7\u54C1\u4FE1\u606F */}\n <div className=\"lg-desktop:gap-1 flex flex-col gap-0.5\">\n <Heading\n as=\"h3\"\n size={2}\n className={cn('text-info-primary line-clamp-2 min-h-[2.4em]', classNames?.productTitle)}\n html={product.custom_name || product.name}\n />\n {product?.description && (\n <Text\n size={2}\n className={cn(\n 'text-info-secondary desktop:line-clamp-2 desktop:min-h-[2.4em] line-clamp-2 min-h-[2.4em]',\n classNames?.productDescription\n )}\n html={product.custom_description || product.description}\n />\n )}\n </div>\n\n {/* \u4EF7\u683C\u533A\u57DF */}\n <div className=\"lg-desktop:gap-2 flex flex-col gap-1.5\">\n {/* \u4EF7\u683C */}\n <div className={cn(classNames?.productPrice)}>\n <div className=\"flex items-baseline gap-1\">\n {product.availableForSale ? (\n <>\n <Heading size={2} className=\"text-info-primary\" as=\"h6\">\n {product.price}\n </Heading>\n {showOriginalPrice && product.originalPrice && (\n <Heading\n size={2}\n className={cn('text-info-tertiary line-through', classNames?.originalPrice)}\n as=\"h6\"\n >\n {product.originalPrice}\n </Heading>\n )}\n </>\n ) : (\n <Heading size={2} className=\"text-info-tertiary\">\n {copy?.outOfStockLabel ?? 'Sold Out'}\n </Heading>\n )}\n </div>\n </div>\n\n {product?.priceLabel && (\n <Text\n size={4}\n className={cn(\n 'text-marketing-1 desktop:text-[16px] lg-desktop:text-[18px] text-[14px]',\n classNames?.productPriceLabel\n )}\n >\n {product.priceLabel}\n </Text>\n )}\n\n {/* \u6309\u94AE\u533A\u57DF */}\n <div className={cn('lg-desktop:gap-3 tablet:flex-nowrap flex flex-wrap gap-2', classNames?.buttonGroup)}>\n {secondaryButtonText && (\n <Button\n variant=\"secondary\"\n size=\"base\"\n className={cn(\n 'tablet:w-fit tablet:min-w-0 tablet:whitespace-normal tablet:text-center w-full whitespace-nowrap',\n classNames?.secondaryButton\n )}\n onClick={() => handleButtonClick(secondaryButtonFun, 'secondary')}\n disabled={!product.availableForSale && secondaryButtonFun !== 'learnMore'}\n loading={secondaryLoading}\n data-headless-type-name=\"CreditsShelf#ProductCard\"\n data-headless-title-desc-button={`${product.custom_name || product.name}#${product.description || ''}#${secondaryButtonText}`}\n data-headless-sku={product.sku}\n >\n {secondaryButtonText}\n </Button>\n )}\n {primaryButtonText && (\n <Button\n variant=\"primary\"\n size=\"base\"\n className={cn(\n 'tablet:w-fit tablet:min-w-0 tablet:whitespace-normal tablet:text-center w-full whitespace-nowrap',\n classNames?.primaryButton\n )}\n onClick={() => handleButtonClick(primaryButtonFun, 'primary')}\n disabled={!product.availableForSale && primaryButtonFun !== 'learnMore'}\n loading={primaryLoading}\n data-headless-type-name=\"CreditsShelf#ProductCard\"\n data-headless-title-desc-button={`${product.custom_name || product.name}#${product.description || ''}#${primaryButtonText}`}\n data-headless-sku={product.sku}\n >\n {primaryButtonText}\n </Button>\n )}\n </div>\n </div>\n </div>\n </CardContent>\n\n {/* \u5E95\u90E8\u79EF\u5206\u62B5\u73B0\u63D0\u793A\u6761 */}\n <div\n className={cn(\n 'bg-container-secondary-0 lg-desktop:px-6 lg-desktop:py-4 flex items-center justify-center gap-1 px-4 py-3',\n classNames?.creditTip\n )}\n >\n <div className=\"bg-info-primary flex size-6 items-center justify-center rounded-full p-1\">\n <span className=\"text-info-white\">\n <StarIcon />\n </span>\n </div>\n <Text size={2} className=\"text-info-primary\">\n {creditTipText}\n </Text>\n </div>\n </Card>\n )\n }\n)\n\nCreditsProductCard.displayName = 'CreditsShelf.ProductCard'\n\nexport { CreditsProductCard }\nexport default CreditsProductCard\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
6
|
"names": ["Fragment", "jsx", "jsxs", "React", "cn", "Button", "Badge", "Card", "CardContent", "Picture", "Text", "Heading", "useCreditsShelfContext", "StarIcon", "CreditsProductCard", "product", "className", "showTagsProp", "onLearnMoreProp", "onShopNowProp", "onAddToCartProp", "classNamesProp", "secondaryButtonTextProp", "secondaryButtonFunProp", "primaryButtonTextProp", "primaryButtonFunProp", "showOriginalPriceProp", "copyProp", "onProductImageClickProp", "ref", "context", "showTags", "showOriginalPrice", "copy", "classNames", "secondaryButtonText", "secondaryButtonFun", "primaryButtonText", "primaryButtonFun", "onLearnMore", "onShopNow", "onAddToCart", "onProductImageClick", "primaryLoading", "setPrimaryLoading", "secondaryLoading", "setSecondaryLoading", "handleButtonClick", "buttonFun", "buttonType", "setLoading", "creditTipText", "tag", "index", "ProductCard_default"]
|
|
7
7
|
}
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
"use client";import{Fragment as D,jsx as
|
|
1
|
+
"use client";import{Fragment as D,jsx as a,jsxs as d}from"react/jsx-runtime";import*as r from"react";import{cn as t}from"../../helpers/utils.js";import T from"../../components/badge.js";import{Text as u}from"../../components/text.js";import y from"../../components/button.js";import _ from"../../components/picture.js";import{Heading as B}from"../../components/heading.js";const R={center:"object-center",top:"object-top",bottom:"object-bottom",left:"object-left",right:"object-right","top-left":"object-left-top","top-right":"object-right-top","bottom-left":"object-left-bottom","bottom-right":"object-right-bottom"},p=r.forwardRef(({product:e,className:k,showTags:w=!0,showOriginalPrice:P=!0,onLearnMore:j,onShopNow:C,onAddToCart:L,onProductImageClick:f,classNames:o,secondaryButtonText:m,secondaryButtonFun:x,primaryButtonText:c,primaryButtonFun:g,copy:S},O)=>{const[N,$]=r.useState(!1),[z,I]=r.useState(!1),b=!e.availableForSale,h=async(i,s)=>{if(!i)return;const v=s==="primary"?$:I;v(!0);try{switch(i){case"buyNow":await C?.(e);break;case"addCart":await L?.(e);break;case"learnMore":await j?.(e);break;default:break}}finally{v(!1)}},l=e.custom_name||e.name,n=e.custom_description||e.description,M=e.custom_theme??"dark";return a("div",{ref:O,className:t("rounded-box relative box-border w-full cursor-pointer overflow-hidden duration-300","desktop:h-[384px] lg-desktop:h-[480px] h-[360px]","tablet:min-w-[auto] min-w-[276px] max-w-[824px]",{"aiui-dark":M==="dark"},k,o?.productCard),children:d("div",{className:"box-border flex h-full flex-col justify-between overflow-hidden",children:[a("a",{onClick:()=>f?.(e),...!f&&e.listingLink&&{href:e.listingLink},rel:"noreferrer",className:t("absolute inset-0",o?.productImage),children:a(_,{alt:e.name,source:e.custom_image??e.image,className:t("rounded-box h-full overflow-hidden object-cover transition-all duration-300 [&_img]:size-full"),imgClassName:t("object-cover",R[e.imageObjectPosition??"center"])})}),d("div",{className:t("desktop:p-6 collection-shelves-product-content pointer-events-none z-10 box-border flex flex-1 flex-col justify-end overflow-hidden p-4",o?.productContent),children:[w&&e.tags?.length?a("div",{className:t("mb-2 box-border flex flex-wrap gap-1 overflow-visible",o?.tagsContainer),children:e.tags.map((i,s)=>i.label?a(T,{size:"sm",variant:i.variant||"outline",promotionalType:i.promotionalType,children:i.label},s):r.isValidElement(i)&&a(r.Fragment,{children:i},s))}):null,l?a(B,{as:"h3",title:l,html:l,className:t("lg-desktop:text-2xl lg-desktop:leading-7 tablet:text-xl text-info-primary tablet:leading-6 line-clamp-2 text-base font-bold",o?.productTitle)}):null,n?a(u,{size:2,html:n,className:t("lg-desktop:text-lg desktop:text-base text-info-primary line-clamp-1 text-sm font-bold",o?.productDescription)}):null,a("div",{className:t("mb-1 mt-4 flex items-center",o?.priceContainer),children:b?a("div",{className:t("tablet:text-xl text-info-primary text-xl font-bold",o?.productPrice),children:S?.outOfStockLabel??"Sold Out"}):d(D,{children:[a("div",{className:t("tablet:text-xl text-info-primary text-xl font-bold",o?.productPrice),children:e.price}),P&&e.originalPrice&&a("div",{className:t("tablet:text-xl text-info-secondary ml-1 text-lg font-bold line-through",o?.originalPrice),children:e.originalPrice})]})}),e?.priceLabel&&a(u,{size:4,className:t("text-marketing-1 desktop:text-[16px] lg-desktop:text-[18px] mt-2 text-[14px]",o?.productPriceLabel),children:e.priceLabel}),d("div",{className:t("lg-desktop:gap-3 pointer-events-auto flex items-stretch gap-2",o?.buttonGroup),children:[m&&a(y,{variant:"secondary",onClick:()=>h(x,"secondary"),disabled:b&&x!=="learnMore",loading:z,className:t("min-w-0 whitespace-normal text-center",o?.secondaryButton),"data-headless-type-name":"ImageOverlayShelf#ProductCard","data-headless-title-desc-button":`${l}#${n||""}#${m}`,"data-headless-sku":e.sku,children:m}),c&&a(y,{variant:"primary",onClick:()=>h(g,"primary"),disabled:b&&g!=="learnMore",loading:N,className:t("min-w-0 whitespace-normal text-center",o?.primaryButton),"data-headless-type-name":"ImageOverlayShelf#ProductCard","data-headless-title-desc-button":`${l}#${n||""}#${c}`,"data-headless-sku":e.sku,children:c})]})]})]})})});p.displayName="ImageOverlayShelf.ProductCard";var A=p;export{p as ProductCard,A as default};
|
|
2
2
|
//# sourceMappingURL=ProductCard.js.map
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../../../src/biz-components/ImageOverlayShelf/ProductCard.tsx"],
|
|
4
|
-
"sourcesContent": ["'use client'\n\nimport * as React from 'react'\nimport { cn } from '../../helpers/utils.js'\n\nimport Badge from '../../components/badge.js'\nimport { Text } from '../../components/text.js'\nimport Button from '../../components/button.js'\nimport Picture from '../../components/picture.js'\nimport { Heading } from '../../components/heading.js'\nimport type { ProductCardProps, ButtonFunctionType, ImageObjectPosition } from './types.js'\n\n/**\n * \u56FE\u7247\u88C1\u5207\u4F4D\u7F6E\u6620\u5C04\n */\nconst objectPositionClassMap: Record<ImageObjectPosition, string> = {\n center: 'object-center',\n top: 'object-top',\n bottom: 'object-bottom',\n left: 'object-left',\n right: 'object-right',\n 'top-left': 'object-left-top',\n 'top-right': 'object-right-top',\n 'bottom-left': 'object-left-bottom',\n 'bottom-right': 'object-right-bottom',\n}\n\n/**\n * ProductCard - ImageOverlayShelf \u7684\u5355\u4E2A\u4EA7\u54C1\u5361\u7247\n * \u56FE\u6587\u53E0\u52A0\u6837\u5F0F\uFF0C\u80CC\u666F\u56FE\u5B8C\u5168\u8986\u76D6\u5361\u7247\n */\nconst ProductCard = React.forwardRef<HTMLDivElement, ProductCardProps>(\n (\n {\n product,\n className,\n showTags = true,\n showOriginalPrice = true,\n onLearnMore,\n onShopNow,\n onAddToCart,\n onProductImageClick,\n classNames,\n secondaryButtonText,\n secondaryButtonFun,\n primaryButtonText,\n primaryButtonFun,\n copy,\n },\n ref\n ) => {\n const [primaryLoading, setPrimaryLoading] = React.useState(false)\n const [secondaryLoading, setSecondaryLoading] = React.useState(false)\n\n const isSoldOut = !product.availableForSale\n\n // \u6839\u636E\u6309\u94AE\u529F\u80FD\u7C7B\u578B\u8C03\u7528\u76F8\u5E94\u7684\u56DE\u8C03\u51FD\u6570\n const handleButtonClick = async (buttonFun?: ButtonFunctionType, buttonType?: 'primary' | 'secondary') => {\n if (!buttonFun) return\n\n const setLoading = buttonType === 'primary' ? setPrimaryLoading : setSecondaryLoading\n setLoading(true)\n\n try {\n switch (buttonFun) {\n case 'buyNow':\n await onShopNow?.(product)\n break\n case 'addCart':\n await onAddToCart?.(product)\n break\n case 'learnMore':\n await onLearnMore?.(product)\n break\n default:\n break\n }\n } finally {\n setLoading(false)\n }\n }\n\n const displayTitle = product.custom_name || product.name\n const displayDescription = product.custom_description || product.description\n const theme = product.custom_theme ?? 'dark'\n\n return (\n <div\n ref={ref}\n className={cn(\n 'rounded-box relative box-border w-full cursor-pointer overflow-hidden duration-300',\n 'desktop:h-[384px] lg-desktop:h-[480px] h-[360px]',\n 'tablet:min-w-[auto] min-w-[276px] max-w-[824px]',\n {\n 'aiui-dark': theme === 'dark',\n },\n className,\n classNames?.productCard\n )}\n >\n <div className=\"box-border flex h-full flex-col justify-between overflow-hidden\">\n {/* \u80CC\u666F\u56FE */}\n <a\n onClick={() => onProductImageClick?.(product)}\n {...(!onProductImageClick &&\n product.listingLink && {\n href: product.listingLink,\n })}\n rel=\"noreferrer\"\n className={cn('absolute inset-0', classNames?.productImage)}\n >\n <Picture\n alt={product.name}\n source={product.custom_image ?? product.image}\n className={cn(\n 'rounded-box h-full overflow-hidden object-cover transition-all duration-300 [&_img]:size-full'\n )}\n imgClassName={cn('object-cover', objectPositionClassMap[product.imageObjectPosition ?? 'center'])}\n />\n </a>\n {/* \u5185\u5BB9\u533A\u57DF */}\n <div\n className={cn(\n 'desktop:p-6 collection-shelves-product-content pointer-events-none z-10 box-border flex flex-1 flex-col justify-end overflow-hidden p-4',\n classNames?.productContent\n )}\n >\n {/* \u6807\u7B7E */}\n {showTags && product.tags?.length ? (\n <div className={cn('mb-2 box-border flex flex-wrap gap-1 overflow-visible', classNames?.tagsContainer)}>\n {product.tags.map((tag: any, index: number) =>\n (tag as any).label ? (\n <Badge\n key={index}\n size=\"sm\"\n variant={(tag.variant as any) || 'outline'}\n promotionalType={tag.promotionalType}\n >\n {tag.label}\n </Badge>\n ) : (\n React.isValidElement(tag) && <React.Fragment key={index}>{tag}</React.Fragment>\n )\n )}\n </div>\n ) : null}\n\n {/* \u4EA7\u54C1\u6807\u9898 */}\n {displayTitle ? (\n <Heading\n as=\"h3\"\n title={displayTitle}\n html={displayTitle}\n className={cn(\n 'lg-desktop:text-2xl lg-desktop:leading-7 tablet:text-xl text-info-primary tablet:leading-6 line-clamp-2 text-base font-bold',\n classNames?.productTitle\n )}\n />\n ) : null}\n\n {/* \u4EA7\u54C1\u63CF\u8FF0 */}\n {displayDescription ? (\n <Text\n size={2}\n html={displayDescription}\n className={cn(\n 'lg-desktop:text-lg desktop:text-base text-info-primary line-clamp-1 text-sm font-bold',\n classNames?.productDescription\n )}\n />\n ) : null}\n\n {/* \u4EF7\u683C\u533A\u57DF */}\n <div className={cn('mb-1 mt-4 flex items-center', classNames?.priceContainer)}>\n {isSoldOut ? (\n <div className={cn('tablet:text-xl text-info-primary text-xl font-bold', classNames?.productPrice)}>\n {copy?.outOfStockLabel ?? 'Sold Out'}\n </div>\n ) : (\n <>\n <div className={cn('tablet:text-xl text-info-primary text-xl font-bold', classNames?.productPrice)}>\n {product.price}\n </div>\n {showOriginalPrice && product.originalPrice && (\n <div\n className={cn(\n 'tablet:text-xl text-info-secondary ml-1 text-lg font-bold line-through',\n classNames?.originalPrice\n )}\n >\n {product.originalPrice}\n </div>\n )}\n </>\n )}\n </div>\n\n {/** \u4EF7\u683C\u6807\u7B7E */}\n {product?.priceLabel && (\n <Text\n size={4}\n className={cn(\n 'text-marketing-1 desktop:text-[16px] lg-desktop:text-[18px] mt-2 text-[14px]',\n classNames?.productPriceLabel\n )}\n >\n {product.priceLabel}\n </Text>\n )}\n\n {/* \u6309\u94AE\u533A\u57DF */}\n <div\n className={cn('lg-desktop:gap-3 pointer-events-auto flex items-
|
|
5
|
-
"mappings": "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
|
|
4
|
+
"sourcesContent": ["'use client'\n\nimport * as React from 'react'\nimport { cn } from '../../helpers/utils.js'\n\nimport Badge from '../../components/badge.js'\nimport { Text } from '../../components/text.js'\nimport Button from '../../components/button.js'\nimport Picture from '../../components/picture.js'\nimport { Heading } from '../../components/heading.js'\nimport type { ProductCardProps, ButtonFunctionType, ImageObjectPosition } from './types.js'\n\n/**\n * \u56FE\u7247\u88C1\u5207\u4F4D\u7F6E\u6620\u5C04\n */\nconst objectPositionClassMap: Record<ImageObjectPosition, string> = {\n center: 'object-center',\n top: 'object-top',\n bottom: 'object-bottom',\n left: 'object-left',\n right: 'object-right',\n 'top-left': 'object-left-top',\n 'top-right': 'object-right-top',\n 'bottom-left': 'object-left-bottom',\n 'bottom-right': 'object-right-bottom',\n}\n\n/**\n * ProductCard - ImageOverlayShelf \u7684\u5355\u4E2A\u4EA7\u54C1\u5361\u7247\n * \u56FE\u6587\u53E0\u52A0\u6837\u5F0F\uFF0C\u80CC\u666F\u56FE\u5B8C\u5168\u8986\u76D6\u5361\u7247\n */\nconst ProductCard = React.forwardRef<HTMLDivElement, ProductCardProps>(\n (\n {\n product,\n className,\n showTags = true,\n showOriginalPrice = true,\n onLearnMore,\n onShopNow,\n onAddToCart,\n onProductImageClick,\n classNames,\n secondaryButtonText,\n secondaryButtonFun,\n primaryButtonText,\n primaryButtonFun,\n copy,\n },\n ref\n ) => {\n const [primaryLoading, setPrimaryLoading] = React.useState(false)\n const [secondaryLoading, setSecondaryLoading] = React.useState(false)\n\n const isSoldOut = !product.availableForSale\n\n // \u6839\u636E\u6309\u94AE\u529F\u80FD\u7C7B\u578B\u8C03\u7528\u76F8\u5E94\u7684\u56DE\u8C03\u51FD\u6570\n const handleButtonClick = async (buttonFun?: ButtonFunctionType, buttonType?: 'primary' | 'secondary') => {\n if (!buttonFun) return\n\n const setLoading = buttonType === 'primary' ? setPrimaryLoading : setSecondaryLoading\n setLoading(true)\n\n try {\n switch (buttonFun) {\n case 'buyNow':\n await onShopNow?.(product)\n break\n case 'addCart':\n await onAddToCart?.(product)\n break\n case 'learnMore':\n await onLearnMore?.(product)\n break\n default:\n break\n }\n } finally {\n setLoading(false)\n }\n }\n\n const displayTitle = product.custom_name || product.name\n const displayDescription = product.custom_description || product.description\n const theme = product.custom_theme ?? 'dark'\n\n return (\n <div\n ref={ref}\n className={cn(\n 'rounded-box relative box-border w-full cursor-pointer overflow-hidden duration-300',\n 'desktop:h-[384px] lg-desktop:h-[480px] h-[360px]',\n 'tablet:min-w-[auto] min-w-[276px] max-w-[824px]',\n {\n 'aiui-dark': theme === 'dark',\n },\n className,\n classNames?.productCard\n )}\n >\n <div className=\"box-border flex h-full flex-col justify-between overflow-hidden\">\n {/* \u80CC\u666F\u56FE */}\n <a\n onClick={() => onProductImageClick?.(product)}\n {...(!onProductImageClick &&\n product.listingLink && {\n href: product.listingLink,\n })}\n rel=\"noreferrer\"\n className={cn('absolute inset-0', classNames?.productImage)}\n >\n <Picture\n alt={product.name}\n source={product.custom_image ?? product.image}\n className={cn(\n 'rounded-box h-full overflow-hidden object-cover transition-all duration-300 [&_img]:size-full'\n )}\n imgClassName={cn('object-cover', objectPositionClassMap[product.imageObjectPosition ?? 'center'])}\n />\n </a>\n {/* \u5185\u5BB9\u533A\u57DF */}\n <div\n className={cn(\n 'desktop:p-6 collection-shelves-product-content pointer-events-none z-10 box-border flex flex-1 flex-col justify-end overflow-hidden p-4',\n classNames?.productContent\n )}\n >\n {/* \u6807\u7B7E */}\n {showTags && product.tags?.length ? (\n <div className={cn('mb-2 box-border flex flex-wrap gap-1 overflow-visible', classNames?.tagsContainer)}>\n {product.tags.map((tag: any, index: number) =>\n (tag as any).label ? (\n <Badge\n key={index}\n size=\"sm\"\n variant={(tag.variant as any) || 'outline'}\n promotionalType={tag.promotionalType}\n >\n {tag.label}\n </Badge>\n ) : (\n React.isValidElement(tag) && <React.Fragment key={index}>{tag}</React.Fragment>\n )\n )}\n </div>\n ) : null}\n\n {/* \u4EA7\u54C1\u6807\u9898 */}\n {displayTitle ? (\n <Heading\n as=\"h3\"\n title={displayTitle}\n html={displayTitle}\n className={cn(\n 'lg-desktop:text-2xl lg-desktop:leading-7 tablet:text-xl text-info-primary tablet:leading-6 line-clamp-2 text-base font-bold',\n classNames?.productTitle\n )}\n />\n ) : null}\n\n {/* \u4EA7\u54C1\u63CF\u8FF0 */}\n {displayDescription ? (\n <Text\n size={2}\n html={displayDescription}\n className={cn(\n 'lg-desktop:text-lg desktop:text-base text-info-primary line-clamp-1 text-sm font-bold',\n classNames?.productDescription\n )}\n />\n ) : null}\n\n {/* \u4EF7\u683C\u533A\u57DF */}\n <div className={cn('mb-1 mt-4 flex items-center', classNames?.priceContainer)}>\n {isSoldOut ? (\n <div className={cn('tablet:text-xl text-info-primary text-xl font-bold', classNames?.productPrice)}>\n {copy?.outOfStockLabel ?? 'Sold Out'}\n </div>\n ) : (\n <>\n <div className={cn('tablet:text-xl text-info-primary text-xl font-bold', classNames?.productPrice)}>\n {product.price}\n </div>\n {showOriginalPrice && product.originalPrice && (\n <div\n className={cn(\n 'tablet:text-xl text-info-secondary ml-1 text-lg font-bold line-through',\n classNames?.originalPrice\n )}\n >\n {product.originalPrice}\n </div>\n )}\n </>\n )}\n </div>\n\n {/** \u4EF7\u683C\u6807\u7B7E */}\n {product?.priceLabel && (\n <Text\n size={4}\n className={cn(\n 'text-marketing-1 desktop:text-[16px] lg-desktop:text-[18px] mt-2 text-[14px]',\n classNames?.productPriceLabel\n )}\n >\n {product.priceLabel}\n </Text>\n )}\n\n {/* \u6309\u94AE\u533A\u57DF */}\n <div\n className={cn('lg-desktop:gap-3 pointer-events-auto flex items-stretch gap-2', classNames?.buttonGroup)}\n >\n {secondaryButtonText && (\n <Button\n variant=\"secondary\"\n onClick={() => handleButtonClick(secondaryButtonFun, 'secondary')}\n disabled={isSoldOut && secondaryButtonFun !== 'learnMore'}\n loading={secondaryLoading}\n className={cn('min-w-0 whitespace-normal text-center', classNames?.secondaryButton)}\n data-headless-type-name=\"ImageOverlayShelf#ProductCard\"\n data-headless-title-desc-button={`${displayTitle}#${displayDescription || ''}#${secondaryButtonText}`}\n data-headless-sku={product.sku}\n >\n {secondaryButtonText}\n </Button>\n )}\n {primaryButtonText && (\n <Button\n variant=\"primary\"\n onClick={() => handleButtonClick(primaryButtonFun, 'primary')}\n disabled={isSoldOut && primaryButtonFun !== 'learnMore'}\n loading={primaryLoading}\n className={cn('min-w-0 whitespace-normal text-center', classNames?.primaryButton)}\n data-headless-type-name=\"ImageOverlayShelf#ProductCard\"\n data-headless-title-desc-button={`${displayTitle}#${displayDescription || ''}#${primaryButtonText}`}\n data-headless-sku={product.sku}\n >\n {primaryButtonText}\n </Button>\n )}\n </div>\n </div>\n </div>\n </div>\n )\n }\n)\n\nProductCard.displayName = 'ImageOverlayShelf.ProductCard'\n\nexport { ProductCard }\nexport default ProductCard\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
6
|
"names": ["Fragment", "jsx", "jsxs", "React", "cn", "Badge", "Text", "Button", "Picture", "Heading", "objectPositionClassMap", "ProductCard", "product", "className", "showTags", "showOriginalPrice", "onLearnMore", "onShopNow", "onAddToCart", "onProductImageClick", "classNames", "secondaryButtonText", "secondaryButtonFun", "primaryButtonText", "primaryButtonFun", "copy", "ref", "primaryLoading", "setPrimaryLoading", "secondaryLoading", "setSecondaryLoading", "isSoldOut", "handleButtonClick", "buttonFun", "buttonType", "setLoading", "displayTitle", "displayDescription", "theme", "tag", "index", "ProductCard_default"]
|
|
7
7
|
}
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
"use client";import{Fragment as W,jsx as t,jsxs as
|
|
1
|
+
"use client";import{Fragment as W,jsx as t,jsxs as C}from"react/jsx-runtime";import N,{useRef as h,useImperativeHandle as z,useLayoutEffect as E,useState as L}from"react";import{Picture as y,Text as q}from"../../components/index.js";import{cn as n}from"../../helpers/utils.js";import{withLayout as H}from"../../shared/Styles.js";import"swiper/css";import{useExposure as j}from"../../hooks/useExposure.js";const A="image",D="marquee",g=N.forwardRef(({data:{items:e=[],speed:s=3e3,reverseDirection:i=!1,key:p}={},className:k},P)=>{const o=h(null),M=h(null);z(P,()=>o.current),j(o,{componentType:A,componentName:D});const T=`${s*5}ms`,m="clamp(24px, 4vw, 64px)",[w,I]=L(2);return E(()=>{const r=M.current;if(!r)return;const a=()=>{const c=r.offsetWidth;if(c===0)return;const R=window.innerWidth,b=Math.ceil(R/c);I(Math.max(2,b))};a(),o.current?.style.setProperty("--track-width",`${r.offsetWidth}px`);const l=new ResizeObserver(()=>{a(),o.current?.style.setProperty("--track-width",`${r.offsetWidth}px`)});return l.observe(r),()=>l.disconnect()},[e]),t("div",{ref:o,id:p?`Marquee-${p}`:void 0,className:n("text-info-primary w-full",k),children:C("div",{className:n("flex h-full w-max items-center",i?"animate-marquee-reverse":"animate-marquee"),style:{"--marquee-duration":T},children:[t("div",{ref:M,className:"flex h-full shrink-0 items-center",style:{gap:m,paddingRight:m},children:e.map((r,a)=>t("div",{className:"shrink-0",children:t(u,{data:r})},(r?.id??"")+"-orig-"+a))}),Array.from({length:w}).map((r,a)=>t("div",{className:"flex h-full shrink-0 items-center",style:{gap:m,paddingRight:m},"aria-hidden":"true",children:e.map((l,c)=>t("div",{className:"shrink-0",children:t(u,{data:l})},(l?.id??"")+"-copy-"+a+"-"+c))},`copy-group-${a}`))]})})});g.displayName="Marquee";const u=({data:e,configuration:s})=>C(W,{children:[e.type==="image"&&t(d,{image:e?.image,imageClassName:s?.imageClassName}),e.type==="text"&&t(x,{text:e?.text??e?.textContent,textClassName:s?.textClassName}),e.type==="iconAndText"&&t(f,{icon:e?.iconImage,text:e?.iconText,iconClassName:s?.iconClassName,textClassName:s?.textClassName}),e.type==="picture"&&t(v,{pictureImage:e?.pictureImage,pictureClassName:s?.pictureClassName})]});u.displayName="MarqueeItem";const d=({image:e,imageClassName:s})=>t("div",{className:"laptop:w-[120px] h-full w-[72px] shrink-0",children:t(y,{source:e?.url,alt:e?.alt||"",imgClassName:n("object-cover",s)})});d.displayName="MarqueeImageContent";const x=N.forwardRef(({text:e,textClassName:s},i)=>t(q,{as:"div",ref:i,html:e,className:n("text-lines-2 flex size-full items-center justify-center font-bold leading-[1.2]",s)}));x.displayName="MarqueeTextContent";const f=({icon:e,text:s,iconClassName:i,textClassName:p})=>C("div",{className:"laptop:h-[72px] laptop:gap-2 flex h-[48px] items-center gap-1",children:[e&&t("img",{src:e?.url,alt:e?.alt||"",className:n("desktop:size-6 size-5 shrink-0 object-contain",i)}),s&&t(q,{as:"div",html:s,className:n("laptop:text-[16px] lg-desktop::text-[18px] flex h-full items-center text-[14px] ",p)})]});f.displayName="MarqueeIconAndTextContent";const v=({pictureImage:e,pictureClassName:s})=>t("div",{className:"lg-desktop:size-[128px] desktop:size-[112px] laptop:size-[96px] tablet:size-[72px] size-[72px] shrink-0",children:t(y,{source:e?.url,alt:e?.alt||"",className:"w-full",imgClassName:n("object-contain",s)})});v.displayName="MarqueePictureContent";var G=H(g);export{f as MarqueeIconAndTextContent,d as MarqueeImageContent,u as MarqueeItem,v as MarqueePictureContent,x as MarqueeTextContent,G as default};
|
|
2
2
|
//# sourceMappingURL=Marquee.js.map
|