ProductCard
Introduction
The ProductCard component is used to display product information, including product name, image, description, App Store link, and product website link. The component features a card design with hover effects and provides links to product-related pages.
Features
- Multiple Sizes - Supports xs, sm, md, lg, xl five preset sizes
- Flexible Layout - Supports horizontal and vertical button layouts
- Equal Height - Ensures consistent height for all cards in grid layouts
- Rich Links - Supports product website, App Store, and GitHub links
- Custom Styling - Supports custom shadows, description lines, and other styles
Examples
Vue 产品卡片
这是一个使用 Vue 版本的 ProductCard 组件的示例。
import { ProductCard } from '@coffic/cosy-ui';
<ProductCard
title="产品名称"
description="产品描述信息"
price="¥99.00"
image="https://images.unsplash.com/photo-1523275335684-37898b6baf30?w=500"
href="/products/1"
/><template>
<ProductCard
name="Vue 产品卡片"
:image="productImage"
description="这是一个使用 Vue 版本的 ProductCard 组件的示例。"
:productUrl="productUrl"
:appStoreUrl="appStoreUrl" />
</template>
<script setup lang="ts">
import { getProductImage, ProductCard } from "@coffic/cosy-ui/vue";
import { ref } from "vue";
const productUrl = ref("https://example.com");
const appStoreUrl = ref("https://apps.apple.com/app/example");
const productImage = getProductImage({
width: 300,
height: 200,
tag: "product-basic",
});
</script>
Props
appStoreUrl
App Store link URL for redirecting to the App Store application page.
---
import { getProductImage, ProductCard } from "@coffic/cosy-ui";
import ProductCardAppStoreUrlSourceCode from "./ProductCardAppStoreUrl.astro?raw";
---
<ProductCard
name="App Store 产品"
image={getProductImage({ width: 300, height: 200, tag: 'appstore-product' })}
description="这是一个包含 App Store 链接的产品卡片示例。"
productUrl="https://example.com/product"
appStoreUrl="https://apps.apple.com/app/example-app"
primaryButtonText="访问官网"
secondaryButtonText="App Store"
/>
<template>
<ProductCard
name="带 App Store 链接的产品卡片"
:image="productImage"
description="这是一个带有 App Store 链接的产品卡片示例。"
appStoreUrl="https://apps.apple.com/app/example"
:productUrl="productUrl" />
</template>
<script setup lang="ts">
import { getProductImage, ProductCard } from "@coffic/cosy-ui/vue";
import { ref } from "vue";
const productUrl = ref("https://example.com");
const productImage = getProductImage({
width: 300,
height: 200,
tag: "product-appstore",
});
</script>
background
Card background color, supporting base colors, opacity variants, and gradient backgrounds.
---
import { getProductImage, ProductCard } from "@coffic/cosy-ui";
---
<ProductCard
name="默认背景产品"
image={getProductImage({
width: 300,
height: 200,
tag: 'background-default',
})}
description="使用默认背景色的产品卡片。"
productUrl="https://example.com/product"
/>
---
import { getProductImage, ProductCard } from "@coffic/cosy-ui";
---
<ProductCard
name="主色背景产品"
image={getProductImage({
width: 300,
height: 200,
tag: 'background-primary',
})}
description="使用主色背景的产品卡片。"
productUrl="https://example.com/product"
background="primary"
/>
---
import { getProductImage, ProductCard } from "@coffic/cosy-ui";
---
<ProductCard
name="渐变背景产品"
image={getProductImage({
width: 300,
height: 200,
tag: 'background-gradient',
})}
description="使用日落渐变背景的产品卡片。"
productUrl="https://example.com/product"
background="gradient-sunset"
/>
---
import { getProductImage, ProductCard } from "@coffic/cosy-ui";
---
<ProductCard
name="透明度背景产品"
image={getProductImage({
width: 300,
height: 200,
tag: 'background-opacity',
})}
description="使用主色透明度背景的产品卡片。"
productUrl="https://example.com/product"
background="primary-opacity"
/>
<template>
<ProductCard
name="带背景色的产品卡片"
:image="productImage"
description="这是一个带有自定义背景色的产品卡片示例。"
:productUrl="productUrl"
:appStoreUrl="appStoreUrl"
background="primary" />
</template>
<script setup lang="ts">
import { getProductImage, ProductCard } from "@coffic/cosy-ui/vue";
import { ref } from "vue";
const productUrl = ref("https://example.com");
const appStoreUrl = ref("https://apps.apple.com/app/example");
const productImage = getProductImage({
width: 300,
height: 200,
tag: "product-background",
});
</script>
buttonLayout
Button layout direction, supporting horizontal (row) and vertical (column) layouts.
---
import { getProductImage, ProductCard } from "@coffic/cosy-ui";
---
<ProductCard
name="水平按钮布局"
image={getProductImage({ width: 300, height: 200, tag: 'button-row' })}
description="按钮水平排列,适合较宽的卡片。"
productUrl="https://example.com/product"
appStoreUrl="https://apps.apple.com/app/example"
buttonLayout="row"
/>
---
import { getProductImage, ProductCard } from "@coffic/cosy-ui";
---
<ProductCard
name="垂直按钮布局"
image={getProductImage({ width: 300, height: 200, tag: 'button-column' })}
description="按钮垂直排列,每个按钮占满一行。"
productUrl="https://example.com/product"
appStoreUrl="https://apps.apple.com/app/example"
buttonLayout="column"
/>
class
Custom CSS class name for overriding default styles.
---
import { getProductImage, ProductCard } from "@coffic/cosy-ui";
---
<ProductCard
name="默认产品卡片"
image={getProductImage({ width: 300, height: 200, tag: 'default-class' })}
description="使用默认样式的产品卡片。"
productUrl="https://example.com/product"
/>
---
import { getProductImage, ProductCard } from "@coffic/cosy-ui";
---
<ProductCard
name="自定义样式产品"
image={getProductImage({ width: 300, height: 200, tag: 'custom-class' })}
description="使用自定义类名添加额外样式的产品卡片。"
productUrl="https://example.com/product"
class="cosy:border-2 cosy:border-primary cosy:bg-primary/10"
/>
<template>
<ProductCard
name="自定义样式的产品卡片"
:image="productImage"
description="这是一个使用自定义样式的產品卡片示例。"
:productUrl="productUrl"
:appStoreUrl="appStoreUrl"
class="custom-product-card" />
</template>
<script setup lang="ts">
import { getProductImage, ProductCard } from "@coffic/cosy-ui/vue";
import { ref } from "vue";
const productUrl = ref("https://example.com");
const appStoreUrl = ref("https://apps.apple.com/app/example");
const productImage = getProductImage({
width: 300,
height: 200,
tag: "product-class",
});
</script>
description
Product description text, supporting multi-line display.
---
import { getProductImage, ProductCard } from "@coffic/cosy-ui";
---
<ProductCard
name="简短描述产品"
image={getProductImage({ width: 300, height: 200, tag: 'short-desc' })}
description="简短的产品描述。"
productUrl="https://example.com/product"
/>
---
import { getProductImage, ProductCard } from "@coffic/cosy-ui";
---
<ProductCard
name="详细描述产品"
image={getProductImage({ width: 300, height: 200, tag: 'long-desc' })}
description="这是一个包含详细描述的产品卡片示例。产品描述可以包含更多信息,帮助用户更好地了解产品的特性和优势。这种详细的描述对于复杂产品或需要更多说明的产品特别有用。"
productUrl="https://example.com/product"
/>
<template>
<ProductCard
name="带描述的产品卡片"
:image="productImage"
description="这是一个带有详细描述的产品卡片示例。描述文本可以很长,组件会自动处理换行和截断。"
:productUrl="productUrl"
:appStoreUrl="appStoreUrl" />
</template>
<script setup lang="ts">
import { getProductImage, ProductCard } from "@coffic/cosy-ui/vue";
import { ref } from "vue";
const productUrl = ref("https://example.com");
const appStoreUrl = ref("https://apps.apple.com/app/example");
const productImage = getProductImage({
width: 300,
height: 200,
tag: "product-description",
});
</script>
descriptionLines
Maximum display lines for description text, with overflow content being truncated.
---
import { getProductImage, ProductCard } from "@coffic/cosy-ui";
---
<div class="cosy:grid cosy:grid-cols-2 cosy:gap-4">
<ProductCard
size="md"
name="默认行数限制"
image={getProductImage({ width: 300, height: 200, tag: 'product-default' })}
description="默认情况下,描述文本会根据卡片尺寸自动限制行数。例如中等尺寸(md)卡片默认显示3行文本。这段文本很长,但只会显示前几行,其余部分会被截断。"
productUrl="https://example.com/product3"
/>
<ProductCard
size="md"
descriptionLines={2}
name="自定义行数限制"
image={getProductImage({ width: 300, height: 200, tag: 'product-custom' })}
description="通过设置descriptionLines=2,可以将描述文本限制为最多显示2行。这段文本很长,但只会显示2行,其余部分会被截断。"
productUrl="https://example.com/product4"
/>
</div>
equalHeight
Whether to enable equal height cards, ensuring consistent height for all cards in grid layouts.
---
import { getProductImage, ProductCard } from "@coffic/cosy-ui";
---
<div class="cosy:grid cosy:grid-cols-2 cosy:gap-4">
<ProductCard
equalHeight
size="md"
name="产品一"
image={getProductImage({ width: 300, height: 200, tag: 'product-equal1' })}
description="这是一段很短的产品描述。"
productUrl="https://example.com/product1"
/>
<ProductCard
equalHeight
size="md"
name="产品二"
image={getProductImage({ width: 300, height: 200, tag: 'product-equal2' })}
description="这是一段较长的产品描述,包含更多详细信息,可能会导致卡片高度增加。使用equalHeight属性可以确保所有卡片高度一致。"
productUrl="https://example.com/product2"
appStoreUrl="https://apps.apple.com/app/product2"
/>
</div>
githubButtonText
Display text for the GitHub button.
---
import { getProductImage, ProductCard } from "@coffic/cosy-ui";
---
<ProductCard
name="默认按钮文本"
image={getProductImage({
width: 300,
height: 200,
tag: 'github-default',
})}
description="使用默认 GitHub 按钮文本的产品卡片。"
productUrl="https://example.com/product"
githubUrl="https://github.com/example/repo"
/>
---
import { getProductImage, ProductCard } from "@coffic/cosy-ui";
---
<ProductCard
name="自定义按钮文本"
image={getProductImage({ width: 300, height: 200, tag: 'github-custom' })}
description="使用自定义 GitHub 按钮文本的产品卡片。"
productUrl="https://example.com/product"
githubUrl="https://github.com/example/repo"
githubButtonText="查看源码"
/>
githubUrl
GitHub repository link URL.
---
import { getProductImage, ProductCard } from "@coffic/cosy-ui";
---
<ProductCard
name="无 GitHub 产品"
image={getProductImage({ width: 300, height: 200, tag: 'no-github' })}
description="没有 GitHub 链接的产品卡片。"
productUrl="https://example.com/product"
/>
---
import { getProductImage, ProductCard } from "@coffic/cosy-ui";
---
<ProductCard
name="开源产品"
image={getProductImage({ width: 300, height: 200, tag: 'with-github' })}
description="包含 GitHub 仓库链接的开源产品卡片。"
productUrl="https://example.com/product"
githubUrl="https://github.com/example/awesome-project"
/>
<template>
<ProductCard
name="带 GitHub 链接的产品卡片"
:image="productImage"
description="这是一个带有 GitHub 链接的产品卡片示例。"
:productUrl="productUrl"
:appStoreUrl="appStoreUrl"
:githubUrl="githubUrl" />
</template>
<script setup lang="ts">
import { getProductImage, ProductCard } from "@coffic/cosy-ui/vue";
import { ref } from "vue";
const productUrl = ref("https://example.com");
const appStoreUrl = ref("https://apps.apple.com/app/example");
const githubUrl = ref("https://github.com/example/project");
const productImage = getProductImage({
width: 300,
height: 200,
tag: "product-github",
});
</script>
image
Product image, supporting multiple image source formats.
产品图片示例
带图片的产品卡片
这是一个展示产品图片的产品卡片示例。
---
import { getProductImage, ProductCard } from "@coffic/cosy-ui";
---
<div class="cosy:space-y-4">
<div>
<h3 class="cosy:text-lg cosy:font-semibold cosy:mb-2">产品图片示例</h3>
<ProductCard
name="产品图片展示"
image={getProductImage({ width: 300, height: 200, tag: 'product-image' })}
description="展示产品图片的使用方式,支持多种图片源格式。"
productUrl="https://example.com/product"
/>
</div>
</div>
<template>
<ProductCard
name="带图片的产品卡片"
:image="productImage"
description="这是一个展示产品图片的产品卡片示例。"
:productUrl="productUrl"
:appStoreUrl="appStoreUrl" />
</template>
<script setup lang="ts">
import { getProductImage, ProductCard } from "@coffic/cosy-ui/vue";
import { ref } from "vue";
const productUrl = ref("https://example.com");
const appStoreUrl = ref("https://apps.apple.com/app/example");
const productImage = getProductImage({
width: 300,
height: 200,
tag: "product-image",
});
</script>
muted
Whether to use muted style (inactive state). When set to true, the card will appear semi-transparent and disable interactions.
---
import { getProductImage, ProductCard } from "@coffic/cosy-ui";
---
<ProductCard
name="静音产品卡片"
image={getProductImage({ width: 300, height: 200, tag: 'product-muted' })}
description="这是一个使用了 muted 属性的产品卡片,看起来处于未激活状态。"
productUrl="https://example.com"
appStoreUrl="https://apps.apple.com/app/example"
muted
/>
name
Product name, required property.
产品名称示例
产品名称示例
这是一个展示产品名称的产品卡片示例。
---
import { getProductImage, ProductCard } from "@coffic/cosy-ui";
---
<div class="cosy:space-y-4">
<div>
<h3 class="cosy:text-lg cosy:font-semibold cosy:mb-2">产品名称示例</h3>
<ProductCard
name="产品名称展示"
image={getProductImage({ width: 300, height: 200, tag: 'product-name' })}
description="展示产品名称的使用方式,这是必填属性。"
productUrl="https://example.com/product"
/>
</div>
</div>
<template>
<ProductCard
name="产品名称示例"
:image="productImage"
description="这是一个展示产品名称的产品卡片示例。"
:productUrl="productUrl"
:appStoreUrl="appStoreUrl" />
</template>
<script setup lang="ts">
import { getProductImage, ProductCard } from "@coffic/cosy-ui/vue";
import { ref } from "vue";
const productUrl = ref("https://example.com");
const appStoreUrl = ref("https://apps.apple.com/app/example");
const productImage = getProductImage({
width: 300,
height: 200,
tag: "product-name",
});
</script>
primaryButtonText
Display text for the primary button (product website button).
---
import { getProductImage, ProductCard } from "@coffic/cosy-ui";
---
<ProductCard
name="默认按钮文本"
image={getProductImage({
width: 300,
height: 200,
tag: 'primary-default',
})}
description="使用默认主按钮文本的产品卡片。"
productUrl="https://example.com/product"
/>
---
import { getProductImage, ProductCard } from "@coffic/cosy-ui";
---
<ProductCard
name="自定义按钮文本"
image={getProductImage({
width: 300,
height: 200,
tag: 'primary-custom',
})}
description="使用自定义主按钮文本的产品卡片。"
productUrl="https://example.com/product"
primaryButtonText="立即访问"
/>
productUrl
Product website link URL.
无链接产品
没有产品官网链接的卡片。
---
import { getProductImage, ProductCard } from "@coffic/cosy-ui";
---
<ProductCard
name="无链接产品"
image={getProductImage({ width: 300, height: 200, tag: 'no-url' })}
description="没有产品官网链接的卡片。"
/>
---
import { getProductImage, ProductCard } from "@coffic/cosy-ui";
---
<ProductCard
name="有链接产品"
image={getProductImage({ width: 300, height: 200, tag: 'with-url' })}
description="包含产品官网链接的卡片。"
productUrl="https://example.com/product"
/>
secondaryButtonText
Display text for the secondary button (App Store button).
---
import { getProductImage, ProductCard } from "@coffic/cosy-ui";
---
<ProductCard
name="默认按钮文本"
image={getProductImage({
width: 300,
height: 200,
tag: 'secondary-default',
})}
description="使用默认次按钮文本的产品卡片。"
productUrl="https://example.com/product"
appStoreUrl="https://apps.apple.com/app/example"
/>
---
import { getProductImage, ProductCard } from "@coffic/cosy-ui";
---
<ProductCard
name="自定义按钮文本"
image={getProductImage({
width: 300,
height: 200,
tag: 'secondary-custom',
})}
description="使用自定义次按钮文本的产品卡片。"
productUrl="https://example.com/product"
appStoreUrl="https://apps.apple.com/app/example"
secondaryButtonText="下载应用"
/>
shadow
Card shadow style, providing five style options: none, sm, md, lg, xl.
---
import { getProductImage, ProductCard } from "@coffic/cosy-ui";
---
<ProductCard
name="大阴影产品"
image={getProductImage({ width: 300, height: 200, tag: 'product-shadow-lg' })}
description="使用大阴影突出显示的产品。"
productUrl="https://example.com/product"
shadow="lg"
/>
---
import { getProductImage, ProductCard } from "@coffic/cosy-ui";
---
<ProductCard
name="无阴影产品"
image={getProductImage({
width: 300,
height: 200,
tag: 'product-shadow-none',
})}
description="无阴影的简洁风格。"
productUrl="https://example.com/product"
shadow="none"
/>
size
Card size, supporting five preset sizes: xs, sm, md, lg, xl.
---
import { getProductImage, ProductCard } from "@coffic/cosy-ui";
---
<ProductCard
size="xs"
name="超小尺寸产品"
image={getProductImage({ width: 150, height: 100, tag: 'product-xs' })}
description="小巧精致的产品卡片,节省空间。"
productUrl="https://example.com/xs"
/>
---
import { getProductImage, ProductCard } from "@coffic/cosy-ui";
---
<ProductCard
size="sm"
name="小尺寸产品"
image={getProductImage({ width: 150, height: 100, tag: 'product-sm' })}
description="紧凑型产品卡片,适合在列表中展示。"
productUrl="https://example.com/sm"
/>
---
import { getProductImage, ProductCard } from "@coffic/cosy-ui";
---
<ProductCard
size="md"
name="中等尺寸产品"
image={getProductImage({ width: 300, height: 200, tag: 'product-md' })}
description="标准产品卡片,平衡信息展示和空间占用。"
productUrl="https://example.com/md"
/>
---
import { getProductImage, ProductCard } from "@coffic/cosy-ui";
---
<ProductCard
size="lg"
name="大尺寸产品"
image={getProductImage({ width: 380, height: 253, tag: 'product-lg' })}
description="大尺寸产品卡片,提供更多细节和视觉吸引力,适合突出展示重要产品。"
productUrl="https://example.com/lg"
/>
---
import { getProductImage, ProductCard } from "@coffic/cosy-ui";
---
<ProductCard
size="xl"
name="超大尺寸产品"
image={getProductImage({ width: 480, height: 320, tag: 'product-xl' })}
description="超大尺寸产品卡片,提供最佳视觉体验和完整信息展示,适合特色产品或首页展示。"
productUrl="https://example.com/xl"
appStoreUrl="https://apps.apple.com/app/example-xl"
/>
<template>
<div class="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-6">
<ProductCard
name="超小尺寸 (xs)"
:image="productImageXs"
description="超小尺寸产品卡片示例。"
:productUrl="productUrl"
:appStoreUrl="appStoreUrl"
size="xs" />
<ProductCard
name="小尺寸 (sm)"
:image="productImageSm"
description="小尺寸产品卡片示例。"
:productUrl="productUrl"
:appStoreUrl="appStoreUrl"
size="sm" />
<ProductCard
name="中等尺寸 (md)"
:image="productImageMd"
description="中等尺寸产品卡片示例。"
:productUrl="productUrl"
:appStoreUrl="appStoreUrl"
size="md" />
<ProductCard
name="大尺寸 (lg)"
:image="productImageLg"
description="大尺寸产品卡片示例。"
:productUrl="productUrl"
:appStoreUrl="appStoreUrl"
size="lg" />
<ProductCard
name="超大尺寸 (xl)"
:image="productImageXl"
description="超大尺寸产品卡片示例。"
:productUrl="productUrl"
:appStoreUrl="appStoreUrl"
size="xl" />
</div>
</template>
<script setup lang="ts">
import { getProductImage, ProductCard } from "@coffic/cosy-ui/vue";
import { ref } from "vue";
const productUrl = ref("https://example.com");
const appStoreUrl = ref("https://apps.apple.com/app/example");
const productImageXs = getProductImage({
width: 200,
height: 133,
tag: "product-xs",
});
const productImageSm = getProductImage({
width: 250,
height: 167,
tag: "product-sm",
});
const productImageMd = getProductImage({
width: 300,
height: 200,
tag: "product-md",
});
const productImageLg = getProductImage({
width: 400,
height: 267,
tag: "product-lg",
});
const productImageXl = getProductImage({
width: 500,
height: 333,
tag: "product-xl",
});
</script>
