卡片 · Card
组织相关内容,适合摘要、设置和资源展示。
安装与前置条件
npm install @astryxdesign/core@0.7.1 @astryxdesign/theme-neutral@0.7.1 @stylexjs/stylex@0.19.0
需要 React 19+,按顺序导入基础 CSS 和主题,并设置 Theme Provider。参见开始使用。
示例与使用方式
- 卡片 · 综合展示 1:首先体验这个示例,再查看代码理解组件的组合方式。
- 卡片 · 交互示例 2:可交互查看这一用法的行为,复制代码时保留它实际使用的属性与导入。
- 卡片 · 交互示例 3:可交互查看这一用法的行为,复制代码时保留它实际使用的属性与导入。
- 卡片 · 样式变化 / 样式 4:可交互查看这一用法的行为,复制代码时保留它实际使用的属性与导入。
- 卡片 · 交互示例 5:可交互查看这一用法的行为,复制代码时保留它实际使用的属性与导入。
- 卡片 · 交互示例 6:可交互查看这一用法的行为,复制代码时保留它实际使用的属性与导入。
API 与上游详细参考
优先使用 0.7.1 官方中文说明;上游尚未提供中文的条目保留英文。属性名、类型及默认值保持原生 API,不把示例状态名称当成组件属性。
Card
Card is a bordered, elevated container for discrete, self-contained items: things you could reorder, remove, or interact with independently. Cards are NOT the default layout tool. Most content groups don't need a container at all; spacing and alignment create visual grouping naturally. Only reach for a Card when items need clear interaction boundaries or visual comparison in a grid.
| 属性 | 类型 | 默认值 | 说明 |
|---|---|---|---|
| width | SizeValue | 卡片宽度(数字 = 像素,字符串 = 按原样使用)。 | |
| height | SizeValue | 卡片高度(数字 = 像素,字符串 = 按原样使用)。 | |
| maxWidth | SizeValue | 卡片最大宽度。 | |
| minHeight | SizeValue | 卡片最小高度。 | |
| children | ReactNode | 在卡片内部渲染的内容。 | |
| padding | 0 | 0.5 | 1 | 1.5 | 2 | 3 | 4 | 5 | 6 | 8 | 10 | the theme's card padding (spacing step 4 with no theme) | 使用间距比例的内边距。省略时,卡片采用主题的卡片内边距,而不是某个步进值;传入步进值意味着覆盖主题,而不是复述默认值。 |
| variant | 'default' | 'transparent' | 'muted' | 'blue' | 'cyan' | 'gray' | 'green' | 'orange' | 'pink' | 'purple' | 'red' | 'teal' | 'yellow' | 'default' | 背景颜色变体。default 使用标准卡片背景;transparent 完全去掉背景;muted 使用弱化卡片的柔和背景。非语义变体使用对应的 --color-background-<name> 令牌。 |
| elevation | 'none' | 'low' | 'med' | 'high' | 'none' | 静止阴影深度。none 为扁平;low/med/high 对应阴影令牌比例。 |
使用建议
- Ask "could I reorder or remove this independently?" If yes, it's a card. If no, it's just a section of the page: use a heading + Stack or Section.
- Use cards for discrete items: a single user profile, a single notification, a single metric, a product in a grid. Each card represents one "thing" with clear interaction boundaries.
- Spacing and alignment alone create visual grouping. Not everything needs a container; try removing the card and see if the grouping is still clear from whitespace and typography.
- Keep padding consistent across sibling cards so they align visually in a grid or list.
- Pair a card with Layout when you need a structured header, scrollable content, and footer with actions.
- Let cards share a row or grid on a phone: a card shrinks to fit its track and clips content that cannot wrap at its edge. Truncate long IDs, hashes, and URLs with Text maxLines={1} (the full value shows in a tooltip), and give wide content its own scroll region: Table scrolls by itself; put code or other wide content in a ScrollableArea.
- 避免:Default to cards for visual grouping. A heading + Stack with proper spacing creates hierarchy without adding borders everywhere. Cards should be the exception, not the default.
- 避免:Wrap page sections in cards. "General Settings", "Notification Preferences", form groups: these are page regions, use Section or heading + stack.
- 避免:Create identical card grids (icon + heading + text, repeated). Vary the layout or question whether cards are needed at all.
- 避免:Nest cards inside other cards; flatten the hierarchy or use spacing and dividers instead.
- 避免:Use color variants for status; use Banner or Badge for that. Color cards are for categorization.
Cards sharing a row on a phone, with long IDs
import {Card} from '@astryxdesign/core/Card';
import {Grid} from '@astryxdesign/core/Grid';
import {VStack} from '@astryxdesign/core/Layout';
import {Heading} from '@astryxdesign/core/Heading';
import {Text} from '@astryxdesign/core/Text';
const payouts = [
{label: 'Payout', amount: '$1,240.00', id: 'po_1Q8ZK4X7M2N5P3R6T9V1W4YB'},
{label: 'Refund', amount: '-$86.50', id: 're_3NfK9Lm2Qx7Vb4Tz8Rw1Hy6C'},
{label: 'Adjustment', amount: '$12.00', id: 'adj_7Hq2Wm9Kx4Lz8Vn3Rb6Tf1PD'},
];
// Each card takes one grid track and shrinks with it, so three cards fit a
// 390px phone without widening the page. The ID cannot wrap, so it truncates
// with maxLines={1} (the full value shows in a tooltip) instead of running
// past the card edge.
function PayoutCards() {
return (
<Grid columns={3} gap={3}>
{payouts.map(payout => (
<Card key={payout.id}>
<VStack gap={1}>
<Heading level={3}>{payout.label}</Heading>
<Text hasTabularNumbers>{payout.amount}</Text>
<Text type="supporting" maxLines={1}>
{payout.id}
</Text>
</VStack>
</Card>
))}
</Grid>
);
}
主题 API
{
"container": true,
"targets": [
{
"className": "astryx-card",
"visualProps": [
"variant",
"elevation"
]
}
],
"vars": [
{
"name": "--_card-radius",
"description": "Border radius of the card",
"default": "var(--radius-container)",
"private": true
},
{
"name": "--_card-elevation",
"description": "Resting shadow of the card, set from the elevation prop.",
"default": "0 0 transparent",
"private": true
},
{
"name": "--_card-ring",
"description": "Inset ring drawn in the card box-shadow list.",
"default": "0 0 transparent",
"private": true
}
],
"derived": [
{
"property": "borderRadius",
"vars": [
"--_card-radius"
]
},
{
"property": "padding",
"expand": "container"
}
]
}
组件结构
- Container: The outer box with border, background, border-radius, and padding.
- Content: Any children rendered inside the card. Often a stack of heading, text, and actions.