用 Codex 或 Claude 帮你安装 复制这段 Prompt,粘贴到 Codex、Claude 或其他助手里,让它检查 Skill 页面并帮你完成安装。
直接命令不会经过审查 Prompt;运行前请先检查来源。
npx skills add https://github.com/hiroppy/mf-dashboard --skill ui-component命令会保持在同一行。复制前请横向滚动并检查完整内容。
想先保存到本地?可下载 SkillsMP 当前能够提供的文件。
正在显示 SKILL.md
| name | ui-component |
| description | Use when creating new UI components under apps/web/src/components/ |
*.stories.tsx for StorybookAGENTS.md)pnpm --filter @mf-dashboard/web test:storybookcomponents/charts/ or components/ui/)Data-agnostic, reusable components. Receive all data via props.
// components/charts/my-chart.tsx
"use client";
interface MyChartProps {
data: Array<{ label: string; value: number }>;
// ... props only, no data fetching
}
export function MyChart({ data }: MyChartProps) {
return (/* pure rendering */);
}
components/info/)| File | Purpose |
|---|---|
foo.tsx | Server Component - fetches data via lib/queries |
foo.client.tsx | Client Component - handles interactivity (ONLY if needed) |
foo.stories.tsx | Storybook - uses mock data |
IMPORTANT: Only create .client.tsx when interactivity is required (useState, useEffect, event handlers, etc.). If the component only displays data, keep it as a Server Component.
// components/info/my-info.tsx
import { getMyData } from "../../lib/queries";
export function MyInfo() {
const data = getMyData();
return (
<Card>
<CardHeader>
<CardTitle>My Info</CardTitle>
</CardHeader>
<CardContent>{/* render data */}</CardContent>
</Card>
);
}
// components/info/my-info.tsx
import { getMyData } from "../../lib/queries";
import { MyInfoClient } from "./my-info.client";
export function MyInfo() {
const data = getMyData();
return <MyInfoClient data={data} />;
}
// components/info/my-info.client.tsx
"use client";
interface MyInfoClientProps {
data: MyData;
}
export function MyInfoClient({ data }: MyInfoClientProps) {
const [state, setState] = useState(/* ... */);
return (/* interactive UI */);
}
apps/web/src/components/charts/apps/web/src/components/ui/apps/web/src/components/info/apps/web/src/lib/queries.ts// components/info/my-info.stories.tsx
import type { Meta, StoryObj } from "@storybook/react";
import { MyInfoClient } from "./my-info.client";
const meta = {
component: MyInfoClient,
} satisfies Meta<typeof MyInfoClient>;
export default meta;
type Story = StoryObj<typeof meta>;
export const Default: Story = {
args: {
data: {
// mock data here
},
},
};
| Purpose | Class |
|---|---|
| Income amount | text-income |
| Expense amount | text-expense |
| Positive balance | text-balance-positive |
| Negative balance | text-balance-negative |
Use when adding/modifying database tables or columns in Drizzle ORM schema
基于 SOC 职业分类