import { Surface, Code } from "@cloudflare/kumo";
import { DatabaseIcon } from "@phosphor-icons/react";
function ResourceListPage({
title,
description,
icon,
usage,
additionalContent,
children,
className,
}: ResourceListPageProps) {
return (
<div className={`min-h-[400px] w-full bg-kumo-overlay ${className || ""}`}>
<div className="mx-auto flex max-w-[1400px] flex-col p-6 md:gap-4 md:p-8">
<div className="flex flex-col">
<div className="mb-1.5 flex items-center gap-1.5">
{icon}
<h1 className="font-heading m-0 p-0 text-3xl font-semibold">
{title}
</h1>
</div>
<p className="hidden p-0 text-lg leading-normal text-pretty text-kumo-subtle md:block">
{description}
</p>
</div>
<div className="flex flex-col-reverse gap-6 xl:grid xl:grid-cols-[1fr_2fr] xl:gap-8">
<div className="min-w-0">{children}</div>
{(usage || additionalContent) && (
<div className="top-22 flex h-fit w-full min-w-0 flex-col gap-4 xl:sticky">
{usage}
{additionalContent && (
<div className={usage ? "mt-6" : ""}>{additionalContent}</div>
)}
</div>
)}
</div>
</div>
</div>
);
}
export function ResourceListCompleteDemo() {
return (
<ResourceListPage
title="KV Namespaces"
description="Store key-value data globally with low-latency access"
icon={<DatabaseIcon size={32} className="text-kumo-subtle" />}
usage={
<Surface className="p-4">
<h3 className="mb-2 font-semibold">Usage Example</h3>
<Code
className="overflow-x-auto"
lang="ts"
code={`// Read from KV
const value = await KV.get('key');
// Write to KV
await KV.put('key', 'value');`}
/>
</Surface>
}
additionalContent={
<Surface className="p-4">
<h3 className="mb-2 font-semibold">Learn More</h3>
<p className="text-sm text-kumo-subtle">
Check out our documentation to learn more about KV storage.
</p>
</Surface>
}
>
<div className="space-y-4">
<Surface className="p-6">
<h4 className="mb-2 truncate font-semibold">production-kv</h4>
<p className="text-sm text-kumo-subtle">Created 2 days ago</p>
</Surface>
<Surface className="p-6">
<h4 className="mb-2 truncate font-semibold">staging-kv</h4>
<p className="text-sm text-kumo-subtle">Created 1 week ago</p>
</Surface>
</div>
</ResourceListPage>
);
}安装
ResourceListPage 是一个区块——通过 CLI 安装、归你所有并可自由定制的组件。 与普通组件不同,区块会被复制进你的项目,因此你完全掌控其代码。
1. 初始化 Kumo 配置 (仅首次需要)
npx @cloudflare/kumo init2. 安装区块
npx @cloudflare/kumo add ResourceListPage3. 从本地路径导入
// 路径取决于你的 kumo.json 中的 blocksDir 设置
// 默认:src/components/kumo/
import { ResourceListPage } from "./components/kumo/resource-list/resource-list";为什么用区块?区块让你完全拥有代码的所有权,可以按自己的需求 定制布局。对于这类页面级模式,往往需要按项目情况做调整,区块正是理想选择。
用法
import { ResourceListPage } from "./components/kumo/resource-list/resource-list";
import { Surface } from "@cloudflare/kumo";
import { DatabaseIcon } from "@phosphor-icons/react";
export default function DatabasesPage() {
return (
<ResourceListPage
title="Databases"
description="Manage your database instances and configurations"
icon={<DatabaseIcon size={32} className="text-kumo-strong" />}
>
<Surface className="p-6">{/* Your resource list content */}</Surface>
</ResourceListPage>
);
}示例
基础
一个最简的资源列表页,包含标题、描述和图标。
import { Surface } from "@cloudflare/kumo";
import { DatabaseIcon } from "@phosphor-icons/react";
function ResourceListPage({
title,
description,
icon,
usage,
additionalContent,
children,
className,
}: ResourceListPageProps) {
return (
<div className={`min-h-[400px] w-full bg-kumo-overlay ${className || ""}`}>
<div className="mx-auto flex max-w-[1400px] flex-col p-6 md:gap-4 md:p-8">
<div className="flex flex-col">
<div className="mb-1.5 flex items-center gap-1.5">
{icon}
<h1 className="font-heading m-0 p-0 text-3xl font-semibold">
{title}
</h1>
</div>
<p className="hidden p-0 text-lg leading-normal text-pretty text-kumo-subtle md:block">
{description}
</p>
</div>
<div className="flex flex-col-reverse gap-6 xl:grid xl:grid-cols-[1fr_2fr] xl:gap-8">
<div className="min-w-0">{children}</div>
{(usage || additionalContent) && (
<div className="top-22 flex h-fit w-full min-w-0 flex-col gap-4 xl:sticky">
{usage}
{additionalContent && (
<div className={usage ? "mt-6" : ""}>{additionalContent}</div>
)}
</div>
)}
</div>
</div>
</div>
);
}
export function ResourceListBasicDemo() {
return (
<ResourceListPage
title="Databases"
description="Manage your database instances and configurations"
icon={<DatabaseIcon size={32} className="text-kumo-subtle" />}
>
<Surface className="p-6">
<p>Main content area - your resource list would go here</p>
</Surface>
</ResourceListPage>
);
}带用法侧边栏
附带一个侧边栏,用于放用法示例或快速上手指南。
import { Surface, Code } from "@cloudflare/kumo";
function ResourceListPage({
title,
description,
icon,
usage,
additionalContent,
children,
className,
}: ResourceListPageProps) {
return (
<div className={`min-h-[400px] w-full bg-kumo-overlay ${className || ""}`}>
<div className="mx-auto flex max-w-[1400px] flex-col p-6 md:gap-4 md:p-8">
<div className="flex flex-col">
<div className="mb-1.5 flex items-center gap-1.5">
{icon}
<h1 className="font-heading m-0 p-0 text-3xl font-semibold">
{title}
</h1>
</div>
<p className="hidden p-0 text-lg leading-normal text-pretty text-kumo-subtle md:block">
{description}
</p>
</div>
<div className="flex flex-col-reverse gap-6 xl:grid xl:grid-cols-[1fr_2fr] xl:gap-8">
<div className="min-w-0">{children}</div>
{(usage || additionalContent) && (
<div className="top-22 flex h-fit w-full min-w-0 flex-col gap-4 xl:sticky">
{usage}
{additionalContent && (
<div className={usage ? "mt-6" : ""}>{additionalContent}</div>
)}
</div>
)}
</div>
</div>
</div>
);
}
export function ResourceListWithUsageDemo() {
return (
<ResourceListPage
title="API Keys"
description="Create and manage API keys for your applications"
usage={
<Surface className="p-4">
<h3 className="mb-2 font-semibold">Quick Start</h3>
<p className="mb-3 text-sm text-kumo-subtle">
Generate an API key to authenticate your requests
</p>
<Code
className="overflow-x-auto"
lang="bash"
code='curl -H "Authorization: Bearer YOUR_API_KEY" https://api.example.com'
/>
</Surface>
}
>
<Surface className="p-6">
<p>API keys list would appear here</p>
</Surface>
</ResourceListPage>
);
}API 参考
| 属性 | 类型 | 说明 |
|---|---|---|
| title | string | 显示在顶部的页面标题 |
| description | string | 标题下方的页面描述 |
| icon | ReactNode | 显示在标题旁边的图标 |
| usage | ReactNode | 侧边栏内容,用于放置用法示例或快速上手指南 |
| additionalContent | ReactNode | 额外的侧边栏内容 (如资源、链接) |
| children | ReactNode | 资源列表的主内容区域 |
| className | string | 额外的 CSS 类名 |