开始使用 Lark
import { LayerCard, Button } from "@lark-ui/core";
import { ArrowRightIcon } from "@phosphor-icons/react";
export function LayerCardDemo() {
return (
<LayerCard>
<LayerCard.Secondary className="flex items-center justify-between">
<div>后续步骤</div>
<Button
variant="ghost"
size="sm"
shape="square"
aria-label="前往后续步骤"
>
<ArrowRightIcon size={16} />
</Button>
</LayerCard.Secondary>
<LayerCard.Primary>开始使用 Lark</LayerCard.Primary>
</LayerCard>
);
}安装
统一导出
import { LayerCard } from "@lark-ui/core";按需导出
import { LayerCard } from "@lark-ui/core/components/layer-card";用法
import { LayerCard } from "@lark-ui/core";
export default function Example() {
return (
<LayerCard className="w-[250px]">
<LayerCard.Secondary>Documentation</LayerCard.Secondary>
<LayerCard.Primary>Learn how to use Lark components</LayerCard.Primary>
</LayerCard>
);
}LayerCard 还支持简单的表面样式模式,适用于不需要次级标题行的场景。在这种情况下,请直接把内容渲染在 LayerCard 内部,而不要包裹在 LayerCard.Primary 中。
import { LayerCard } from "@lark-ui/core";
export default function Example() {
return (
<LayerCard className="w-[250px] p-4">
Learn how to use Lark components
</LayerCard>
);
}示例
基础卡片
面向新用户的快速上手指南
import { LayerCard } from "@lark-ui/core";
export function LayerCardBasicDemo() {
return (
<LayerCard className="w-[250px]">
<LayerCard.Secondary>快速上手</LayerCard.Secondary>
<LayerCard.Primary>
<p className="text-sm text-lark-subtle">面向新用户的快速上手指南</p>
</LayerCard.Primary>
</LayerCard>
);
}表面样式的卡片
对于简单的卡片容器,请直接把内容渲染在 LayerCard 内部,不要使用 LayerCard.Primary。
面向新用户的快速上手指南
import { LayerCard } from "@lark-ui/core";
export function LayerCardSurfaceDemo() {
return (
<LayerCard className="w-[250px] p-4">
<p className="text-sm text-lark-subtle">面向新用户的快速上手指南</p>
</LayerCard>
);
}多张卡片
浏览所有组件
查看代码示例
import { LayerCard } from "@lark-ui/core";
export function LayerCardMultipleDemo() {
return (
<div className="flex gap-4">
<LayerCard className="w-[200px]">
<LayerCard.Secondary>组件</LayerCard.Secondary>
<LayerCard.Primary>
<p className="text-sm">浏览所有组件</p>
</LayerCard.Primary>
</LayerCard>
<LayerCard className="w-[200px]">
<LayerCard.Secondary>示例</LayerCard.Secondary>
<LayerCard.Primary>
<p className="text-sm">查看代码示例</p>
</LayerCard.Primary>
</LayerCard>
</div>
);
}带小号标签页的筛选工具栏
在 LayerCard 内部组合使用 Tabs size=“sm” 和 Input size=“sm”,即可构建紧凑的筛选工具栏。两者使用相同的 h-6.5(26px)高度。
源站请求数耗时
challenges.cloudflare.com
2xx 1
95.4ms未知
2xx 194xx 7
463.7msapi.example.com
2xx 424xx 3
128.1ms显示 3 项,共 3 项
import { useState } from "react";
import { Badge, Input, LayerCard, Tabs } from "@lark-ui/core";
// ─── Mockup: Segmented filter + search ───────────────────────────────
/** 子请求卡片,Primary 内部带有行内筛选工具栏。 */
export function LayerCardFilterSubrequestsDemo() {
const [filter, setFilter] = useState<StatusFilter>("all");
const [search, setSearch] = useState("");
const filtered = ORIGINS.filter((o) => {
if (filter === "2xx" && o.s2xx === 0) return false;
if (filter === "4xx" && o.s4xx === 0) return false;
if (search && !o.origin.toLowerCase().includes(search.toLowerCase()))
return false;
return true;
});
return (
<LayerCard className="w-full max-w-[540px]">
<LayerCard.Secondary>子请求</LayerCard.Secondary>
<LayerCard.Primary>
{/* Toolbar: tabs + search on one line */}
<div className="mb-2 flex items-center gap-3">
<Input
size="sm"
placeholder="筛选源站…"
aria-label="筛选源站"
value={search}
onChange={(e) => setSearch(e.target.value)}
className="min-w-0 flex-1"
/>
<Tabs
variant="segmented"
size="sm"
className="shrink-0"
tabs={[
{ value: "all", label: "全部" },
{ value: "2xx", label: "2xx" },
{ value: "3xx", label: "3xx" },
{ value: "4xx", label: "4xx" },
{ value: "5xx", label: "5xx" },
]}
value={filter}
onValueChange={(v) => setFilter(v as StatusFilter)}
/>
</div>
{/* Custom lightweight table — no banding, uniform bg */}
<div className="-mx-1 text-sm">
{/* Header */}
<div className="grid grid-cols-[1fr_auto_auto] gap-x-4 border-b border-lark-fill px-1 pb-2 text-xs font-medium text-lark-subtle">
<span>源站</span>
<span className="w-28 text-right">请求数</span>
<span className="w-20 text-right">耗时</span>
</div>
{/* Rows */}
{filtered.map((row, i) => (
<div
key={row.origin}
className={`grid grid-cols-[1fr_auto_auto] items-center gap-x-4 px-1 py-2.5 ${i < filtered.length - 1 ? "border-b border-lark-hairline" : ""}`}
>
<span className="truncate font-medium text-lark-default">
{row.origin}
</span>
<div className="flex w-28 items-center justify-end gap-1.5">
{row.s2xx > 0 && (
<Badge variant="success">{`2xx ${row.s2xx}`}</Badge>
)}
{row.s4xx > 0 && (
<Badge variant="error">{`4xx ${row.s4xx}`}</Badge>
)}
</div>
<span className="w-20 text-right text-lark-subtle">
{row.duration}
</span>
</div>
))}
</div>
{/* Footer */}
<div className="-mx-1 border-t border-lark-fill pt-2 text-xs text-lark-subtle">
显示 {filtered.length} 项,共 {ORIGINS.length} 项
</div>
</LayerCard.Primary>
</LayerCard>
);
}测试 ID
LayerCard.Primary 和 LayerCard.Secondary 接受所有标准 HTML 属性,包括用于测试的 data-testid。
面向新用户的快速上手指南
import { LayerCard } from "@lark-ui/core";
/** 将 `data-testid` 等 HTML 属性传给 `Primary` 和 `Secondary`,便于测试。 */
export function LayerCardTestIdDemo() {
return (
<LayerCard className="w-[250px]">
<LayerCard.Secondary data-testid="card-header">
快速上手
</LayerCard.Secondary>
<LayerCard.Primary data-testid="card-body">
<p className="text-sm text-lark-subtle">面向新用户的快速上手指南</p>
</LayerCard.Primary>
</LayerCard>
);
}API 参考
| 属性 | 类型 | 默认值 | 说明 |
|---|---|---|---|
| render | ReactNode | - | 允许用其他标签替换组件的 HTML 元素,或与其他组件组合。 接受 `ReactElement` 或返回待渲染元素的函数。 |
| children | ReactNode | - | - |
| className | string | - | - |
| id | string | - | - |
| lang | string | - | - |
| title | string | - | - |