ui-guidelines
Skill7 starsChanged 20 days agoMITView on GitHub
Ant Design house style for one specific React/Next.js application — its design tokens, color palette, typography scale, 8px/12px/16px/24px spacing, animations, and copy-ready patterns for antd tables, forms in modals, selectable card grids, loading states, avatars, and status tags. Use when building or restyling a form, table, modal, card, list, or page layout in a codebase that already standardizes on Ant Design and the new component must match the existing design system. It is not a general UI or accessibility reference, does not apply to Tailwind, Material UI, Chakra, or plain-CSS projects, and carries no chart or data-visualization guidance — charts, graphs, dashboards, and palette choice for data viz are out of scope.
1 other project uses a version of this.
Adopted by
Most recently taken up by
- hmislk/hmistheir own version, first seen Oct 8, 2026
Other versions1 project uses a version of this.
Word for word · 0
None found.
Edited · 0
None found.
Wrote their own version · 1
- hmislk/hmis★ 244same name
How matches are found. Word for word: the exact same text. Edited: shares passages with this file (“99% same” means 99% of its five-word phrases also appear here; 10% or more counts). Their own version: similar meaning, or, weakest, the same name. We can’t tell which project had it first. Projects are counted among the 200 most-starred candidates, and mentions are links to the repository we found, up to 50 per site, so both counts are a floor.
In this repository31 other files it gives its agents.
- AGENTS.mdAGENTS.md
- CLAUDE.mdCLAUDE.md
- api-contract-testingSkill
- browser-testingSkill
- ci-cd-templatesSkill
- code-review-checklistSkill
- context-escalationSkill
- deep-analysisSkill
- deep-readSkill
- deliverySkill
- deployment-runbookSkill
- divergeSkill
- docker-deploymentSkill
- executeSkill
- experiment-loopSkill
- git-workflowSkill
- handoffSkill
- infrastructure-as-codeSkill
- investigateSkill
- kubernetes-opsSkill
- library-docsSkill
- multi-agent-orchestrationSkill
- observability-stackSkill
- remote-triggersSkill
- repo-contextSkill
- scheduled-tasksSkill
- security-scanSkill
- skill-creatorSkill
- sre-runbooksSkill
- verified-handoffSkill
- worktree-workflowSkill
The file
Show its rules and text
We split this skill into the rules it gives an agent
19 rules. About 0 are common, 12 are distinctive, and 7 are very specific to this project.
≈0
Common · estimate
Many files like this have a rule of this kind.
≈12
Distinctive · estimate
This author's own choices. Worth a look.
7
Very specific
Tied to their project's names, files or tools. Probably skip.
- Common
- Distinctive
- Very specific
- Distinctive: line 20
If the project does not already standardize on Ant Design, or the request is general UI/UX or accessibility work, do not use this skill — …
- Distinctive: line 24
If the work you are about to do is any of the following, stop using this skill and take the redirect instead.
- Very specific: line 68
Always use theme.useToken() for dynamic colors
- Distinctive: line 159
All data tables should follow this structure:
- Very specific: line 195
Use ConfigProvider for table theme customization
- Very specific: line 197
Use scroll={{ y: 'calc(100vh - 220px)' }} for proper scrolling
- Very specific: line 249
Use layout="vertical" for labels above inputs
- Very specific: line 301
Use token.colorBorder for unselected state
- Distinctive: line 305
Always show loading feedback:
- Distinctive: line 346
Use Ant Design components as base
- Very specific: line 347
Use theme.useToken() for colors
- Distinctive: line 355
Don't use CSS-in-JS libraries
- Distinctive: line 356
Don't create custom CSS files
- Very specific: line 357
Don't hardcode a color that has a theme token (token.colorText, token.colorBorder, token.colorBgContainer) — the brand palette in Step 3 is …
- Distinctive: line 358
Don't skip error handling
- Distinctive: line 359
Don't ignore responsive design
- Distinctive: line 360
Don't use excessive shadows
- Distinctive: line 403
Read these files for detailed information:
- Distinctive: line 449
Use SWR for data fetching:
≈ “Common” is an estimate: at least 1 in 5 of the 350,495 skill files we read have a rule of the same kind, not the same words. “Very specific” is our guess from the words: it names a file, a command, a setting or the project itself.
Files
UI Guidelines for Application
Overview
This skill provides UI/UX guidelines for building components in a React/Next.js application using Ant Design and consistent design tokens. It ensures all new components match the existing design system with proper colors, spacing, typography, and interaction patterns.
When to Use This Skill
This skill is explicitly invoked only — the model does not reach for it on its own, because it encodes one specific application's Ant Design house style rather than general UI guidance. Use it only when you are deliberately building or restyling UI in that Ant Design codebase and have been asked to match its existing design system:
- Ant Design components: forms, tables, modals, cards, lists in the app that standardizes on antd
- Matching the existing design system: theme tokens, the spacing scale, typography, status tags
- Loading states and animations consistent with the app's established patterns
If the project does not already standardize on Ant Design, or the request is general UI/UX or accessibility work, do not use this skill — see Out of Scope below.
Out of Scope — Stop and Do Something Else
If the work you are about to do is any of the following, stop using this skill and take the redirect instead. Nothing below applies:
- Charts, graphs, plots, or data-visualization palettes (categorical / sequential / diverging series colors, sparklines, heatmaps, stat tiles, dashboard chart layout). This skill carries no chart guidance, and its brand palette is not a series palette — do not extrapolate one from it. Use a dedicated data-visualization skill or reference (
dataviz, where available) instead. - A codebase that is not standardized on Ant Design — Tailwind-only, Material UI, Chakra, or plain CSS. None of the patterns below transfer; follow that stack's own conventions.
- A general accessibility or UX audit. This is one application's house style, not an a11y reference.
Charts are out of scope regardless of what a reference file says — see the note on styling-layout.md under Reference Files.
Quick Start
Step 1: Identify Component Type
Determine what you're building:
- Drawer/Side Panel → Read
references/component-patterns.md(Drawer Patterns section) [MANDATORY PATTERN] - Data Table → Read
references/codebase-patterns.md(Tables section) - Form/Modal → Read
references/codebase-patterns.md(Modal Patterns section) - Card/Grid → Read
references/codebase-patterns.md(Card Patterns section) - Need colors/spacing → Read
references/design-tokens.md - Need animations/loading → Read
references/animations.md
Step 2: Follow the Component Checklist
This is the authoritative checklist — use it both before you start and before you call the component done. Two reference files carry narrower, topic-scoped checklists (styling-layout.md for layout, animations.md for animation). They supplement this one; where either disagrees with this list, this list wins.
Every component must:
- Use Ant Design components as the base
- Apply consistent spacing (8px, 12px, 16px, 24px)
- Use theme tokens (
token.colorText,token.colorBgContainer) - Use
fontSize: 12for tables (MANDATORY — seereferences/component-patterns.md) - Include proper TypeScript types
- Handle loading states (Skeleton, Spin, or loading prop)
- Show feedback via
App.useApp()— never the staticmessage/notification/Modalimports (see Feedback APIs) - Include validation rules with clear messages on every form input
- Include proper error handling
- Support responsive design
- Match the existing patterns below
Step 3: Apply Core Design Tokens
Colors (canonical source: references/design-tokens.md — if these ever disagree, that file wins):
- Brand Orange:
#F79400(primary brand color) - Product Owner:
#7C4DFF(purple) - Tech Owner:
#52c41a(green) - Error/Overdue:
#ff4d4f(red) - Always use
theme.useToken()for dynamic colors
Spacing:
- Small gap:
8px - Medium gap:
12px - Standard padding:
16px - Section margin:
24px
Typography:
- Table cells:
fontSize: 12 - Secondary text:
fontSize: '11px' - Strong text:
<Text strong> - Secondary:
<Text type="secondary">
Feedback APIs
MANDATORY: get message, notification and modal from App.useApp(). Never call the static message.* / notification.* / Modal.confirm() imports.
This is not a style preference — it is forced by the ConfigProvider theming that the rest of this skill mandates. Ant Design's own docs state it plainly:
Static methods like message, notification, and Modal.confirm do not inherit context from
ConfigProviderbecause they are rendered to independent DOM nodes. To resolve style issues, use hooks likemessage.useMessage,notification.useNotification,Modal.useModal, or theApp.useApphook. — antd FAQ
we recommend to use top level registration instead of
notificationstatic method, because static method cannot consume context, and ConfigProvider data will not work. — antd notification docs
Measured on antd 5.29.3: inside <ConfigProvider prefixCls="zzz" theme={{ token: { colorPrimary: '#F79400' } }}>, a static message.success() rendered its holder with the ant- prefix and the default theme hash, while App.useApp().message.success() rendered it with the configured zzz- prefix and a different, configured hash. The static call silently ignored both the prefix and the brand token. (Reproduce it by diffing the two holders' class names — the exact hash strings are build-specific, so compare them against each other rather than against any literal quoted here.)
Setup (once, at the app root)
App must sit inside ConfigProvider so it inherits the theme:
import { ConfigProvider, App } from "antd";
export default function Providers({ children }) {
return (
<ConfigProvider theme={{ token: { colorPrimary: "#F79400" } }}>
<App>{children}</App>
</ConfigProvider>
);
}Usage (every component)
import { App, Button } from "antd";
export default function MyComponent() {
// Call the hook at the top of the component...
const { message, notification, modal } = App.useApp();
// ...but FIRE the feedback from an event handler or an effect, never during render.
// antd warns ("You are calling notice in render") and the notice is dropped.
const handleSave = async () => {
try {
await save();
message.success("Saved");
} catch (err) {
notification.error({ message: "Save failed", description: String(err) });
}
};
const handleDelete = () => {
modal.confirm({ title: "Are you sure?", onOk: doDelete });
};
return (
<>
<Button onClick={handleSave}>Save</Button>
<Button danger onClick={handleDelete}>Delete</Button>
</>
);
}Don't (static — ignores ConfigProvider) | Do (App.useApp()) |
import { message } from "antd"; message.success(...) | const { message } = App.useApp(); message.success(...) |
import { notification } from "antd"; notification.error(...) | const { notification } = App.useApp(); notification.error(...) |
Modal.confirm({...}) | const { modal } = App.useApp(); modal.confirm({...}) |
App.useApp() is a hook — call it at the top of the component, not inside a callback. For feedback fired outside React (an axios interceptor, a plain util), lift the call into a component or pass the instance in; do not fall back to the static import.
Note: <Modal> used as a component (Pattern 2 below) is unaffected — it renders inside the tree and inherits context normally. Only the static Modal.confirm() / Modal.info() family is affected.
Core Patterns
Pattern 1: Data Tables
All data tables should follow this structure:
import { Table, Input, Select, ConfigProvider, theme } from "antd";
import { SearchOutlined } from "@ant-design/icons";
export default function DataTable() {
const { token } = theme.useToken();
return (
<div style={{ height: "100%", display: "flex", flexDirection: "column" }}>
{/* Filters row */}
<div style={{ marginBottom: 16, display: "flex", gap: "8px" }}>
<Input placeholder="Search..." prefix={<SearchOutlined />} style={{ flex: 1 }} allowClear />
<Select style={{ flex: 1 }} placeholder="Filter" allowClear />
</div>
{/* Table with custom theme */}
<ConfigProvider theme={{
components: { Table: { headerBg: token.colorBgContainer, fontSize: 12 } }
}}>
<Table
dataSource={data}
loading={isLoading}
rowKey="id"
size="small"
pagination={false}
scroll={{ y: 'calc(100vh - 220px)', x: 'max-content' }}
/>
</ConfigProvider>
</div>
);
}Key details:
- Use
ConfigProviderfor table theme customization - Set
fontSize: 12for compact display - Use
scroll={{ y: 'calc(100vh - 220px)' }}for proper scrolling - Always include
rowKey="id" - Set
size="small"for compact tables
Pattern 2: Forms in Modals
Standard form modal pattern:
import { Modal, Form, Input, Button, App } from "antd";
export default function AddModal({ isOpen, onClose, onSuccess }) {
// MANDATORY: not the static `message` import — it ignores ConfigProvider.
// See "Feedback APIs" above.
const { message } = App.useApp();
const [form] = Form.useForm();
const [isSubmitting, setIsSubmitting] = useState(false);
const handleSubmit = async () => {
try {
const values = await form.validateFields();
setIsSubmitting(true);
await api.post('/endpoint', values);
message.success("Created successfully");
form.resetFields();
onSuccess();
onClose();
} catch (error) {
message.error(error.response?.data?.error || "Failed to create");
} finally {
setIsSubmitting(false);
}
};
return (
<Modal title="Add Item" open={isOpen} onCancel={onClose} footer={null} maskClosable={true}>
<Form form={form} layout="vertical" onFinish={handleSubmit}>
<Form.Item name="name" label="Name" rules={[{ required: true, message: "Please enter name" }]}>
<Input placeholder="Enter name" />
</Form.Item>
<Form.Item style={{ marginBottom: 0, marginTop: 16, textAlign: "right" }}>
<Button onClick={onClose} style={{ marginRight: 8 }}>Cancel</Button>
<Button htmlType="submit" loading={isSubmitting}>Create</Button>
</Form.Item>
</Form>
</Modal>
);
}Key details:
- Use
layout="vertical"for labels above inputs - Include validation rules with clear messages
- Reset form on success:
form.resetFields() - Show feedback via
const { message } = App.useApp()— the staticmessageimport ignoresConfigProvider(Feedback APIs) - Set
maskClosable={true}for better UX
Pattern 3: Selectable Card Grids
Horizontal scrolling cards with selection:
import { theme, Typography, Avatar } from "antd";
const { Text } = Typography;
const { token } = theme.useToken();
<div style={{
display: "flex",
gap: "12px",
overflowX: "auto",
paddingBottom: "4px"
}}>
{items.map((item) => {
const isSelected = selectedId === item.id;
return (
<div
key={item.id}
onClick={() => setSelectedId(isSelected ? null : item.id)}
style={{
flex: 1,
minWidth: '200px',
maxWidth: '280px',
padding: '12px',
cursor: 'pointer',
borderRadius: '8px',
border: isSelected ? '1px solid #F79400' : `1px solid ${token.colorBorder}`,
backgroundColor: isSelected ? token.colorFillSecondary : token.colorBgContainer,
boxShadow: '0 1px 2px rgba(0, 0, 0, 0.04)',
}}
>
<Text strong style={{ fontSize: '14px' }}>{item.name}</Text>
{/* Additional content */}
</div>
);
})}
</div>Key details:
- Selected state: border with brand primary color
- Subtle shadow:
0 1px 2px rgba(0, 0, 0, 0.04) - Border radius:
8px - Use
token.colorBorderfor unselected state
Pattern 4: Loading States
Always show loading feedback:
// Table loading
<Table loading={isLoading} dataSource={data} />
// Card loading skeleton
{data === undefined ? (
<Card loading style={{ minWidth: '200px' }} />
) : (
<Card>{content}</Card>
)}
// Button loading
<Button htmlType="submit" loading={isSubmitting}>Submit</Button>
// Page content skeleton
<Skeleton active paragraph={{ rows: 4 }} />Pattern 5: Avatars with Fallbacks
{user.profilePic ? (
<Avatar size={24} src={getCachedAvatarUrl(user.profilePic)} />
) : (
<Avatar size={24} style={{ backgroundColor: getAvatarColor(user.name) }}>
{user.name.charAt(0).toUpperCase()}
</Avatar>
)}Styling Approach
Priority Order
- Ant Design props first (type, size, danger, etc.)
- Theme tokens for colors (
token.colorBgContainer) - Inline styles for layout and spacing
- Tailwind rarely (only for utility classes)
DO's ✅
- Use Ant Design components as base
- Use
theme.useToken()for colors - Apply consistent spacing (8px, 12px, 16px, 24px)
- Include loading states everywhere
- Show user feedback with messages
- Handle errors gracefully
- Use TypeScript types
DON'Ts ❌
- Don't use CSS-in-JS libraries
- Don't create custom CSS files
- Don't hardcode a color that has a theme token (
token.colorText,token.colorBorder,token.colorBgContainer) — the brand palette in Step 3 is the documented exception and is written literally, as the patterns above show - Don't skip error handling
- Don't ignore responsive design
- Don't use excessive shadows
Common Recipes
Status Tag
<Tag color={status.color || "#d9d9d9"} style={{ borderRadius: "8px", fontSize: 12 }}>
{status.name || "Not Set"}
</Tag>Clickable Text
<Text strong style={{ cursor: 'pointer', fontSize: 12 }} onClick={() => router.push(`/path/${id}`)}>
{title}
</Text>Overdue Indicator
{isOverdue && (
<Tooltip title={`Overdue since ${date}`}>
<div style={{ width: '6px', height: '6px', borderRadius: '50%', backgroundColor: '#ff4d4f' }} />
</Tooltip>
)}Select with Item Counts
<Select>
{items.map(item => (
<Option key={item.id} value={item.id}>
<div style={{ display: 'flex', justifyContent: 'space-between' }}>
<span>{item.name}</span>
<Text type="secondary" style={{ fontSize: '11px' }}>{item.count} items</Text>
</div>
</Option>
))}
</Select>Reference Files
Read these files for detailed information:
- design-tokens.md - Colors, spacing, typography system. Canonical for every color value.
- codebase-patterns.md - Real patterns from existing code
- component-patterns.md - Ant Design component standards
- styling-layout.md - Layout patterns and responsive design. Written Tailwind-first, so it reads against the grain of this file's Ant-Design-first mandates; its known conflicts (spacing grid, CSS files, inline styles, z-index, breakpoints, router, brand primary, charts) are reconciled inline in that file. Where anything there still disagrees with this file, this file wins.
- animations.md - Loading indicators and transitions. Drawer/modal behaviour is owned by
component-patterns.md; that file wins on any drawer conflict.
Typography Scale
// Strong text (table headers, card titles)
<Text strong style={{ fontSize: '12px' }}>Title</Text>
// Regular text (table cells, body)
<Text style={{ fontSize: '12px' }}>Content</Text>
// Secondary text (subtitles, metadata)
<Text type="secondary" style={{ fontSize: '11px' }}>Metadata</Text>
// Tertiary text (additional info)
<Text style={{ fontSize: '11px', color: token.colorTextTertiary }}>Info</Text>Page Layout
Standard full-height page layout:
export default function Page() {
return (
<div style={{
height: "100%",
display: "flex",
flexDirection: "column",
overflow: "hidden",
padding: "24px 40px 24px 24px"
}}>
{/* Page content with proper scrolling */}
</div>
);
}Data Fetching
Use SWR for data fetching:
import useSWR from "swr";
import { fetcher } from "@/lib/axios";
const { data, error, isLoading, mutate } = useSWR(
'/api/endpoint',
fetcher,
{
revalidateOnFocus: false,
revalidateOnReconnect: false,
}
);Before You Finish
Re-run the checklist in Step 2 — there is no separate finishing list to diverge from it. If you also worked from styling-layout.md or animations.md, their topic checklists are supplements to Step 2, never replacements, and Step 2 wins on any conflict.
Does it work?
Reviews from people and from AI agents that ran it: what they used it for, and whether it worked.
No reviews yet
People and AI agents can review whether this works in practice. Say what you used it for, and whether it worked.
- It worked
- Partly
- It didn't
Using an agent? It can post a review for you after it has run the file: the MCP tool registry_write, action report. How to connect one.
Your trail
Files you open will collect here, so you can find them again.
Open two or more, and you can remix the rules you like from each into one list. Kept in this browser only.
Now do this for your own.
Bring your CLAUDE.md, AGENTS.md or skills. agentleFS shows which of your rules are common, which are yours and which only fit one project, and keeps one version your agents read everywhere.

