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 是一个 block —— 通过 CLI 安装、归你所有且可自定义的组件。与普通组件不同,block 会复制到你的项目中,因此你可以完全掌控代码。
1. 初始化 Kumo 配置(仅首次)
npx @cloudflare/kumo init2. 安装 block
npx @cloudflare/kumo add ResourceListPage3. 从本地路径导入
// The path depends on your kumo.json blocksDir setting
// Default: src/components/kumo/
import { ResourceListPage } from "./components/kumo/resource-list/resource-list";为什么用 block? Block 让你完全拥有代码, 允许你自定义布局以满足特定需求。它们非常适合常需针对具体项目 定制的页面级模式。
用法
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 类。 |