Skip to content

Frontend Ui Conventions

worable edited this page Oct 20, 2026 · 2 revisions

UI 与样式约定

插件和主题的前端组件由平台渲染,必须与平台的样式系统保持一致。本文说明可用组件、样式规则和几个必踩的坑。

样式规则(硬性)

  • 禁止自定义 CSS 文件和内联 style 属性。 不写 <style>、不引入 .css。
  • 只用 Tailwind CSS utility classes。 需要组合样式时,用 className 拼 Tailwind 类。
  • 需要现成控件时,用 @stackpanel/ui(见下),不要自己从零写按钮/输入框。
  • 主题色、圆角、阴影等通过 CSS Token 引用(bg-background、text-muted-foreground、rounded-lg、shadow-sm 等),不要写死颜色值。

这套规则和 apps/web/AGENTS.md 一致。插件前端和平台自带页面的观感必须统一。

可用组件:@stackpanel/ui

跨应用共享的组件库,两个入口(index.tsx / admin.tsx)都可直接导入:

import { Button, Input, Label, Select, StatusBadge, Dialog, DialogContent, DialogHeader, DialogTitle } from '@stackpanel/ui';
导出 说明
Button / buttonVariants 按钮
Input 文本输入
Label 表单标签
Select 下拉选择
PageHeader 页面标题区(标题/副标题 + 右侧操作按钮)
StatusBadge 状态徽标(含 StatusTone 类型)
Dialog + DialogTrigger / DialogContent / DialogHeader / DialogTitle / DialogDescription / DialogFooter 对话框
AnimatedGridPattern、BorderBeam、Marquee、NumberTicker、WordRotate、AuroraText、AnimatedGradientText、AnimatedShinyText、LightRays、ShimmerButton、InteractiveHoverButton、RainbowButton、Meteors、DiaTextReveal、GlyphMatrix、Particles、TextAnimate 装饰性动效组件

示例:

import { Button, Input, Label } from '@stackpanel/ui';

<div className="grid gap-1 text-sm">
  <Label htmlFor="name">名称</Label>
  <Input id="name" name="name" required />
</div>
<Button type="submit">保存</Button>

页面标题区:统一用 PageHeader

后台页和账户页的标题区固定为「左侧标题 + 副标题,右侧操作按钮」。不要各自手写 <h1> + flex justify-between,直接用 PageHeader:

import { PageHeader, Button } from '@stackpanel/ui';

<main className="w-full space-y-6">
  <PageHeader
    title="钱包管理"
    description="查看用户余额并进行人工调整。"
    actions={<Button>调整余额</Button>}
  />
  {/* 页面内容 */}
</main>
  • eyebrow:标题上方的返回链接/面包屑(详情页常用)。
  • title / description:标题与副标题,接受 ReactNode(可放徽标、代码片段)。
  • actions:右侧操作区,多个按钮会自动排成一行。

Base UI 差异:没有 asChild

平台 UI 基于 Base UI,不支持 asChild。要让按钮渲染成链接,用 render:

import Link from 'next/link';
import { Button } from '@stackpanel/ui';

<Button render={<Link href="/admin/plugins" />} variant="outline">
  返回
</Button>

可用依赖

编译时下列依赖是外置的,可直接 import,不会被打进产物(保证与平台共用同一份 React 实例):

react、react/jsx-runtime、next/link、@stackpanel/sdk、@stackpanel/ui、zod、lucide-react;客户端入口 admin.tsx 另外置 react-dom(scripts/build-frontend.mjs)。

不要引入其它 UI 库或状态管理库——它们无法保证被平台解析,且会带来重复 React 实例、hook 报错等运行时问题。

样式不生效?(Tailwind 扫描源)

Tailwind 只扫描 apps/web/src/app/globals.css 里 @source 列出的目录。新建的插件前端默认不在列表里,其 className 会被当作未使用而摇掉,页面看起来「没样式」。

在 apps/web/src/app/globals.css 顶部按现有格式补一行:

@source "../../../../packages/plugins/my-plugin/frontend/src";

(外部上传安装的插件走 data/plugins/<id>/frontend/dist/,同样需要覆盖。)

这是手维护的列表,pnpm build:frontend 不会自动改它。

主题 Token

颜色、圆角、阴影等由平台的 CSS Token 提供,常用语义类:

用途 类名示例
页面底色 / 主文字 bg-background / text-foreground
卡片 bg-card / text-card-foreground
次要文字 text-muted-foreground
主色 bg-primary / text-primary-foreground
边框 / 输入 border / bg-background
成功 / 警告 / 危险 text-success / text-warning / text-destructive
圆角 rounded-lg / rounded-xl / rounded-2xl
阴影 shadow-sm / shadow-md

平台使用了暗色主题 token(.dark),因此不要写死十六进制颜色,否则暗色下不可读。完整 token 见 apps/web/src/app/globals.css。

相关

Clone this wiki locally