This skill turns "writing interfaces with lobe-ui" from a matter of luck into something controllable: it makes component semantics, visual values, craft standards, and acceptance mechanisms explicit, intervening at every step of generation rather than trying to patch things up at the end with a single prompt.
The model has seen far more interfaces than any designer. The problem isn't insufficient capability—it's that when requirements are vague, it converges on the most frequent, safest kind of result in its training data: uniform sans-serif fonts, purple-blue gradients, and steady, evenly sized cards. Generic, safe—and that is precisely the root of mediocrity. Every step below is fighting against this tendency.
Division of labor with other skills
| Focus | Belongs to |
|---|---|
| What this interface should be, and why | Upstream product design judgment, outside the scope of this skill |
| Which component to use, which token to pick, whether it counts as passing | This skill |
| Evidence of it actually running in the browser | This repository's local-testing skill |
Choose the minimal run mode
Don't read all six files every time. First decide what you're delivering this time:
| Mode | Endpoint | Need to read |
|---|---|---|
| Choose component | Answer "which component should this information use" | Hard prerequisites + components.md |
| Values | Write a piece of style.ts |
Hard prerequisites + design.md |
| Build interface | A complete page or component, including non-ideal states | Full five-step process + all references |
| Review | Judge whether an existing interface can be approved | evaluator.md + the rules that were hit |
For narrow questions, read only the relevant file, and state the scope of the check.
Hard prerequisites: get these three things right, or everything is wasted effort
One,@lobehub/ui/base-ui is the current canonical namespace. Top-level Button、Modal、Select、Tabs、Text、Tag、Avatar、ActionIcon、Segmented、Skeleton、Dropdown and 27 other classic components are marked @deprecated, they are antd wrapper layers. New code should always be imported from @lobehub/ui/base-ui , and@lobehub/ui/eslint will enforce this rule. See the full list in components.md C-01.
Two, styles are written only with createStaticStyles + cssVar。 createStyles has been disabled by eslint. The roughly 170 style.ts in the repository all use this style, with zero exceptions:
import { createStaticStyles } from 'antd-style';
export const styles = createStaticStyles(({ css, cssVar, responsive }) => ({
root: css`
border-block-end: 1px solid ${cssVar.colorBorderSecondary};
border-radius: ${cssVar.borderRadiusLG};
${responsive.sm} {
padding-inline: 12px;
}
`,
}));
Styles written with cssVar natively support dark mode, without needing any branching.
Three, the Provider order cannot be reversed, and motion must be passed explicitly.
import { ConfigProvider, ThemeProvider } from '@lobehub/ui';
import { zhCn } from '@lobehub/ui/i18n';
import { motion } from 'motion/react';
<ConfigProvider locale="zh-CN" motion={motion} resources={zhCn}>
<ThemeProvider>
<App />
</ThemeProvider>
</ConfigProvider>;
ConfigProvider must be on the outer layer:ThemeProvider renders antd's App(carrying static notification / modal holders) and reads the CDN configuration to load webfonts; both depend on the context above.
Three easy pitfalls:
motionis required. Not passing it will cause any component that uses animation to throw an error directly atuseMotionComponent(). Apps usingLazyMotionshould passmrather thanmotion。- Component-internal copy (chat actions, forms, EmojiPicker, etc.) is provided by
resources, optionalenorzhCn。Don't wrap another layer ofI18nProvider—it is itself a forwarding ofConfigProvider(which likewise requiresmotion), so nesting is equivalent to installing two providers. ConfigProviderinstalls a global keyboard focus ring for the entire document, including native controls and controls outside the provider subtree. So normally you don't need to write your own focus styles, and you must never useoutline: noneto erase it.
Five-step chain
Don't start by drawing the interface. Each step depends on the output of the previous step, and upstream deviations amplify along the chain, so constraints must enter as early as possible and every step must be checked.
1. Planning — first turn vague requirements into an executable feature definition
Before writing any JSX, expand the requirements into six layers. Whatever you can't write out is what you need to confirm with the user.
L1 定位与意图 一句话定义 · 目标用户 · 场景清单 · 非目标 · 行为边界
L2 信息架构 空间区域 · 区域边界规则 · 内容生长规则
L3 核心链路 状态清单 · 主链路 · 分支链路
L4 组件功能 组件定位 · 功能清单 · 默认/悬停/加载/禁用/错误各态
L5 边界条件 空态 · 加载态 · 错误态 · 权限降级
L6 验收标准 Given/When/Then · 完成的定义
The easiest to skip are L5 and L6. Models tend to prioritize completing the main flow and success state, because that looks most like a complete screenshot; but in real products, users more often encounter loading, no data, no permission, and retry after failure.If L5 isn't written, the page will lose operability at critical moments.
At the same time, set the visual direction. If you don't, the model will first fill in with default visuals, then carry those default choices into the later structure and components.
2. Build the skeleton — decide in what spatial structure the information unfolds
First determine which type of page this is, then choose the skeleton; don't assemble components from a blank page:
| Scenario | Starting point |
|---|---|
| Document / application page shell | Layout + LayoutHeader / LayoutSidebar / LayoutMain / LayoutToc / LayoutFooter |
| Conversation interface | ChatHeader → ChatList → ChatInputArea(for composition order see C-04) |
| Mobile shell | @lobehub/ui/mobile of ChatHeader / ChatInputArea / TabBar / SafeArea |
| fixed narrow navigation bar | SideNav; if draggable resizing is needed use DraggableSideNav |
| resizable sidebar / floating panel | base-ui of DraggablePanel |
| Marketing landing page | @lobehub/ui/awesome of Hero / Features / GridShowcase |
The skeleton determines the relationship between the main area, sidebar, action area, and status area.If this step is wrong, the whole page is off—a list page made into a card wall, a batch task page without a batch action area; no matter how you change the components later, it can't be saved.
Also set density along the way: landing pages and consoles cannot use the same density (see craft.md K-09).
3. Filling — map information to the correct component semantics
It's not about filling the slots. "Running", "High risk", "ECS", and "Production environment" are all short texts, but their responsibilities differ: one is a status, one is a risk, one is a resource type, one is a business category. Making them all the same kind of tag looks visually neat, but the semantics are flattened and the user's judgment slows down.
First determine whether this piece of information expresses status, category, action, container, or navigation relationship, then choose the component. See components.md —the decision table for looking up by requirement, the real differences between easily confused components, and where to get components this library doesn't have.
4. Refinement — complete states, feedback, and craft
The main flow running only means it can display a successful result. This step handles non-ideal states and visual craft:
- Visual values, token derivation, dark mode, execution constraints → design.md
- Loading tiers, motion purpose, accessibility baseline, anti-AI flavor → craft.md
- Charts, model badges, emoji, streaming markdown → ecosystem.md
5. Evaluation — take it back to the standards and check
Don't say "it's about good enough" yourself. Compare item by item across six dimensions, and if a blocking item is hit, go back. See evaluator.md。
Browser evidence cannot be omitted: existing in the DOM does not mean the user can see it. This repository's local-testing The skill defines the complete validation process.
Feedback loop: issues must be traced to a specific rule
When you find an issue, don't just change the prompt at the outermost layer and wait for the next result. Use the table below to trace it to the stage and rule number:
| Symptom | Which step to return to | Rule |
|---|---|---|
| Missing empty / loading / error / permission states | L5 of planning | craft.md K-05 |
| The page looks like a wall of cards, not a dashboard | Build the skeleton | Step 2 of this document + K-09 |
| The component looks right but its semantics are used incorrectly | Fill in | components.md C-03 |
| A deprecated top-level component is used | Fill in | components.md C-01 |
| Raw hex, raw rgba | Refine the visual values | design.md D-01 / D-10 |
| The state colors are newly invented | Refine the visual values | design.md D-03 |
| It looks like an AI template at a glance | Refine the craftsmanship | craft.md K-01 |
| The landing page effect has been carried into the console | Fill in | components.md C-06 |
| Chart colors are disconnected from the theme | Refine the ecosystem selection | ecosystem.md E-02 |
| Can't articulate what's wrong | Evaluate | evaluator.md |
Anti-patterns
- From
antdimport directlyButton/Select/Modaland other components that have a base-ui counterpart implementation, or use antd'smessage/notificationinstead of base-ui'stoast。 - Pick one between the top level and
base-uibased on intuition. Most top-level components with the same name are deprecated antd wrapper layers. - Treat examples and templates as copy-and-paste boards. The skeleton is a starting point; business fields, content density, and state lists all need to be adjusted according to real requirements.
- Where
cssVaris needed, hard-code the value. When no corresponding token can be found, state the gap explicitly (design.md D-11), don't quietly write a hex to bypass the system. - Introduce a second chart library for one chart, or fetch a remote SVG for one model badge.
- Announcing completion after only submitting a screenshot. A "verification" without runtime evidence does not hold.
- Take
lint/type-check/ passing unit tests as an acceptance item. They are preconditions, not delivery evidence.
Reference map
Load by run mode, don't read everything at once:
| Needs | File |
|---|---|
| Component selection decision table, easily confused component comparison, conversation interface composition | components.md C- |
| Token values, state color derivation, dark mode, execution constraints | design.md D- |
| Craftsmanship rules, AI Slop anti-patterns, accessibility, coding pitfalls | craft.md K- |
| API for charts / model badges / emoji / streaming markdown | ecosystem.md E- |
| Six-dimension scoring, blocking items, evidence requirements, release strategy | evaluator.md |