docs: visual design guidelines (tokens, components, interaction states)

This commit is contained in:
Chengdong Zhang
2026-09-24 17:11:51 +08:00
parent a968327b12
commit 8181b3544b
2 changed files with 106 additions and 0 deletions
+1
View File
@@ -6,6 +6,7 @@
- **定位代码先用 `docs/code_index/index.md`**:按业务域渐进披露到具体文件;新增/删除/重命名文件时**必须同步更新对应域的索引文件**。 - **定位代码先用 `docs/code_index/index.md`**:按业务域渐进披露到具体文件;新增/删除/重命名文件时**必须同步更新对应域的索引文件**。
- 总体架构 `docs/architecture.md`;后端规范 `docs/backend-guidelines.md`;前端规范 `docs/frontend-guidelines.md`;领域设计 `docs/domains/`;开发/部署排障 `docs/development.md`。 - 总体架构 `docs/architecture.md`;后端规范 `docs/backend-guidelines.md`;前端规范 `docs/frontend-guidelines.md`;领域设计 `docs/domains/`;开发/部署排障 `docs/development.md`。
- 视觉/交互规范 `docs/design-guidelines.md`(色彩 token、accent 预设、布局、卡片/表格/表单组件用法、加载/错误/409 交互态)——改 UI 前必读。
- 规范性的行为契约仍以 `openspec/specs/` 为准;docs 是实现地图,不是需求来源。 - 规范性的行为契约仍以 `openspec/specs/` 为准;docs 是实现地图,不是需求来源。
## 布局与所有权 ## 布局与所有权
+105
View File
@@ -0,0 +1,105 @@
# Design Guidelines
Visual and interaction conventions for all three frontends. Everything here is
enforced by `packages/shared/src/theme.css` tokens and `packages/ui`
components — if you need a value that does not exist, extend the theme or the
kit instead of improvising locally. No `<style scoped>`, no hex literals in
app code.
## Color
Semantic tokens only (Tailwind classes: `bg-bg`, `text-text`, …):
| Token | Value | Use |
|---|---|---|
| `bg` | `#f5f5f5` | page background |
| `surface` | `#ffffff` | cards, panels, nav, inputs |
| `border` | `#e2e5ea` | all borders/dividers |
| `text` | `#1c2330` | primary text |
| `muted` | `#66707f` | secondary text, placeholders |
| `primary` | accent | actions, links, active states |
| `danger` | `#d64545` | errors, destructive actions |
| `success` | `#1f9d63` | success feedback, positive states |
| `warning` | `#c77d0a` | pending/attention states |
**Accent presets** (`red` default, `blue`, `teal`, `violet`) swap
`--primary*` at runtime via `html[data-accent]`; users pick one with
`VAccentSwatch`. Derivatives: `primary-hover`, `primary-soft` (subtle tint for
selected/hover fills). Never reference a preset's hex directly.
Opacity modifiers for tinted feedback: `bg-danger/10 text-danger` etc. (see
`VBadge` tones).
## Typography
- Font: system stack (`--font-sans`, includes PingFang SC / Microsoft YaHei).
- Page title: `text-xl font-bold` (`VPage` provides it).
- Section heading: `text-base font-semibold` (consoles) /
`text-lg font-semibold` (mall content sections).
- Body: `text-sm`; secondary/meta: `text-xs text-muted` (or `text-[13px]` in
dense console sidebars).
- Bilingual copy renders through locale fallbacks, never side-by-side.
## Radius, borders, elevation
- Radius: `rounded-md` (8px) for cards/inputs/buttons; `rounded` (4px) for
chips/badges; `rounded-full` for avatars and progress bars.
- Cards: `rounded-lg border border-border bg-surface shadow-sm` — this is
exactly `VCard`; use it instead of re-deriving.
- Elevation: one level only (`shadow-sm` on cards). No stacked shadows.
## Layout
- Mall content max width: `max-w-mall` (1200px), centered, `px-4`.
- Consoles: sidebar (`md:w-60`) + fluid `<main class="min-w-0 flex-1">`;
page content in `mx-auto w-full max-w-7xl px-4 md:px-6` (admin) or the
shop-admin equivalent. Content columns must be `w-full min-w-0` — auto
margins on grid items silently shrink them to fit-content.
- Buyer center (`apps/mall/pages/user.vue`): `234px` sidebar + fluid content
in a `max-w-mall` grid.
## Components and when to use them
| Need | Use | Notes |
|---|---|---|
| Page shell | `VPage` (`:title`, `#actions`) | consoles |
| Card/section | `VCard` (`:padded="false"` for edge-to-edge tables) | one card per logical section |
| Button | `VBtn` (`variant`: default/primary/danger, `size`: md/sm) | primary = the one forward action; danger only for destructive |
| Badge/status | `VBadge` (`tone`: green/blue/orange/red/gray) | map domain status → tone once per page |
| Form field | `VField` (`:label`, `:error`) + `VInput` | errors inline, never alert() |
| Table | `VTable` in `overflow-x-auto` wrapper | dense console data |
| Empty state | `UiEmptyState` (mall) / muted text (consoles) | always provide one |
| Pagination | `UiPagination` (mall) / prev-next block (consoles) | server-driven totals |
## Interaction states (every async surface)
1. **Loading**: muted text/skeleton region; never a blank card.
2. **Error**: `role="alert"` + `text-danger`, keep user input intact.
3. **Success**: transient `role="status"` text near the action
(`text-success`), not a toast system.
4. **Conflict (409)**: show the message and refresh from server state —
the UI must converge to truth, not stack retries.
5. **Destructive actions**: `confirm()` + `VBtn variant="danger"`.
## Imagery and icons
- Product/content images: `object-cover` in fixed-ratio boxes
(`h-12 w-20` thumbnails, `w-full` heroes).
- Icons: inline SVG path data (storefront quick links carry glyphs in the
API). No icon font, no emoji as UI icons.
- Avatars: `rounded-full`, fallback `/mock/avatar.svg`.
## Accessibility floor
- All controls keyboard-reachable; visible focus via
`focus:border-primary focus:outline-2 focus:outline-primary/30` (built into
`VInput`).
- Icon-only buttons need an accessible name; star ratings use
`role="img"` + `aria-label`.
- Respect locale switching without layout overflow (`min-w-0`, `truncate`).
## What stays out of scope
Charts, drag-and-drop builders, dark mode, and print styles have no tokens
yet. Propose them as a design extension (new tokens in `theme.css` + kit
components) instead of local one-offs.