@wangs-ui/skills 1.3.0-alpha.2 → 1.3.0-alpha.9
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +2 -5
- package/dist/bin.js +1 -1
- package/dist/index.js +1 -1
- package/dist/skills/craft-theme/SKILL.md +62 -0
- package/dist/skills/create-form/SKILL.md +23 -15
- package/dist/skills/data-table/SKILL.md +19 -12
- package/dist/skills/dialog-modal/SKILL.md +15 -7
- package/dist/skills/i18n-usage/SKILL.md +15 -8
- package/dist/skills/layout-navigation/SKILL.md +15 -8
- package/dist/skills/universal-layout/SKILL.md +87 -0
- package/dist/skills/wangs-ui-components/SKILL.md +23 -15
- package/dist/{src-DDi-O7tk.js → src-BvsMfJmb.js} +20 -12
- package/package.json +1 -1
- package/skills/craft-theme/SKILL.md +62 -0
- package/skills/create-form/SKILL.md +23 -15
- package/skills/data-table/SKILL.md +19 -12
- package/skills/dialog-modal/SKILL.md +15 -7
- package/skills/i18n-usage/SKILL.md +15 -8
- package/skills/layout-navigation/SKILL.md +15 -8
- package/skills/universal-layout/SKILL.md +87 -0
- package/skills/wangs-ui-components/SKILL.md +23 -15
package/README.md
CHANGED
|
@@ -2,11 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
Modular AI agent skills installer and manager for **Wangs UI** React components and design patterns.
|
|
4
4
|
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
## 📚 Dedicated Storybook Guide
|
|
8
|
-
|
|
9
|
-
For a step-by-step guide on using `@wangs-ui/skills` independently with any Storybook project, see the [Dedicated Storybook Guide](../../docs/storybook-mcp-skills.md).
|
|
5
|
+
Skills are standalone: they work in any Storybook or React project without requiring project scaffolding tools. They pair with [`@wangs-ui/mcp`](../mcp/README.md), which supplies the live component catalog, typed APIs, and story implementations the skills tell agents to verify against.
|
|
10
6
|
|
|
11
7
|
---
|
|
12
8
|
|
|
@@ -34,5 +30,6 @@ npx @wangs-ui/skills remove create-form
|
|
|
34
30
|
## 🛠️ Features
|
|
35
31
|
|
|
36
32
|
- **Modular UI Skills**: Installs specialized guidelines, component patterns, and rules into your AI agent environment.
|
|
33
|
+
- **MCP-Verified Guidance**: Skills mandate querying the MCP server for live contracts instead of hardcoding props, so guidance never drifts from the installed package version.
|
|
37
34
|
- **Cross-Platform & Multi-Agent**: Supports Antigravity IDE, Claude Code, OpenCode, Kilo, and universal agent directories on Mac and Windows.
|
|
38
35
|
- **Independent Usage**: Works in any Storybook or React project without requiring project scaffolding tools.
|
package/dist/bin.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
import { i as listSkills, n as updateSkills, r as addSkills, t as removeSkills } from "./src-
|
|
2
|
+
import { i as listSkills, n as updateSkills, r as addSkills, t as removeSkills } from "./src-BvsMfJmb.js";
|
|
3
3
|
import path from "node:path";
|
|
4
4
|
import { parseArgs } from "node:util";
|
|
5
5
|
//#region bin.ts
|
package/dist/index.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { a as getAgentSkillDirs, c as isSkillInstalled, d as loadAllSkills, i as listSkills, l as removeSkill, n as updateSkills, o as getInstalledSkills, r as addSkills, s as installSkill, t as removeSkills, u as getSkill } from "./src-
|
|
1
|
+
import { a as getAgentSkillDirs, c as isSkillInstalled, d as loadAllSkills, i as listSkills, l as removeSkill, n as updateSkills, o as getInstalledSkills, r as addSkills, s as installSkill, t as removeSkills, u as getSkill } from "./src-BvsMfJmb.js";
|
|
2
2
|
export { addSkills, getAgentSkillDirs, getInstalledSkills, getSkill, installSkill, isSkillInstalled, listSkills, loadAllSkills, removeSkill, removeSkills, updateSkills };
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: craft-theme
|
|
3
|
+
description: Generate a brand-color theme (13-shade tonal palette + M3-style semantic tokens) for a Wangs UI app via the `wangs-ui-generate-palette` CLI — never hand-write hex shade ramps.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Skill: Craft Theme
|
|
7
|
+
|
|
8
|
+
Use this skill whenever the user asks to create, customize, or rebrand the color theme of an app built on `@wangs-ui/react-core` / `@wangs-ui/foundation` — "make the app's theme orange", "use our brand color #ff6b35", "add a new palette called sunset", etc.
|
|
9
|
+
|
|
10
|
+
## The rule this skill exists to enforce
|
|
11
|
+
|
|
12
|
+
**Never hand-write a 13-shade tonal ramp, and never hand-pick which shade pairs with which as a text/foreground color.** Wangs UI's own design system shipped with exactly that mistake for a while: hand-tuned palette files drifted from what the perceptual (OKLCH) generator would produce, which caused white text to render at 2.54:1 contrast on one brand's primary color — invisible-adjacent, and only caught by a dedicated audit. The generator and the contrast math it's paired with exist specifically so this class of bug can't happen again. Always reach for the CLI below instead of writing hex values yourself.
|
|
13
|
+
|
|
14
|
+
## 1. Generate the palette
|
|
15
|
+
|
|
16
|
+
```bash
|
|
17
|
+
npx wangs-ui-generate-palette --name=<id> --primary=<#hex> [options] --out=<path>
|
|
18
|
+
```
|
|
19
|
+
|
|
20
|
+
- `--name` (required): identifier for the palette, e.g. `sunset`. Used for the exported const name (`sunsetPalette`) and, unless `--out` is given, the output filename (`sunset.ts`).
|
|
21
|
+
- `--primary` (required): the brand/key hex color, e.g. `#ff6b35`.
|
|
22
|
+
- Optional per-family overrides — omit any of these to let the generator harmoniously auto-derive it from `--primary` (secondary: boosted-lightness variant of primary's hue; tertiary: +60° hue rotation; general: near-neutral variant of primary's hue) or fall back to the generator's calibrated defaults (success/danger/warning/info):
|
|
23
|
+
`--secondary=#hex --tertiary=#hex --general=#hex --success=#hex --danger=#hex --warning=#hex --info=#hex`
|
|
24
|
+
- `--out=<path>` (optional): where to write the file. Defaults to `./<name>.ts` in the current working directory — always pass an explicit `--out` pointing into the consumer app's own theme directory (e.g. `src/theme/sunset.ts`), don't rely on the default.
|
|
25
|
+
|
|
26
|
+
If `@wangs-ui/foundation` isn't already a dependency of the project you're working in, install it first (`pnpm add @wangs-ui/foundation` or the project's equivalent) — the CLI ships as its `bin`.
|
|
27
|
+
|
|
28
|
+
**The written file is chmod'd read-only (0o444) and headed with an AUTO-GENERATED / DO NOT EDIT BY HAND comment.** If a color needs to change, re-run the command (it clears the read-only bit, rewrites, and re-locks it) — never hand-edit a shade in the output, and never `chmod` it writable to bypass this. Note the read-only bit is a local filesystem attribute only; it is not preserved by git across clones, so it is a deterrent for the person/agent working in this checkout right now, not a hard guarantee for every future contributor.
|
|
29
|
+
|
|
30
|
+
## 2. Wire it into the app
|
|
31
|
+
|
|
32
|
+
The generated file exports a plain `Palette` object — pass it directly to `WangsUiProvider`'s `theme.palette` (or `theme.defaultPalette` for uncontrolled mode):
|
|
33
|
+
|
|
34
|
+
```tsx
|
|
35
|
+
import { WangsUiProvider } from '@wangs-ui/react-core/api';
|
|
36
|
+
import preset from '@wangs-ui/react-presets/fixedasset'; // or whichever preset the app uses
|
|
37
|
+
import { sunsetPalette } from './theme/sunset';
|
|
38
|
+
|
|
39
|
+
const App = () => (
|
|
40
|
+
<WangsUiProvider configOptions={{ preset }} theme={{ palette: sunsetPalette, mode: 'light' }}>
|
|
41
|
+
<YourApp />
|
|
42
|
+
</WangsUiProvider>
|
|
43
|
+
);
|
|
44
|
+
```
|
|
45
|
+
|
|
46
|
+
`theme.palette` also accepts a built-in palette name (`'blue' | 'emerald' | 'crimson' | 'carbon' | 'gold'`) or a raw hex string — a generated `Palette` object is the right choice once you have brand-specific secondary/tertiary/status colors to preserve, not just a single key color.
|
|
47
|
+
|
|
48
|
+
## 3. Regenerating / evolving an existing custom palette
|
|
49
|
+
|
|
50
|
+
To change a color, re-run the same command with a new hex for the family that changed — **always pass every family you want to keep**, not just the one changing, since each run is a full regeneration from the anchors you give it:
|
|
51
|
+
|
|
52
|
+
```bash
|
|
53
|
+
npx wangs-ui-generate-palette --name=sunset --primary=#ff6b35 --tertiary=#2a9d8f --out=src/theme/sunset.ts
|
|
54
|
+
```
|
|
55
|
+
|
|
56
|
+
## 4. If you're extending Wangs UI itself (contributing a new official palette)
|
|
57
|
+
|
|
58
|
+
This is a different, rarer case than theming a consumer app — only relevant if you're working inside the `wangs-ui-react` monorepo itself and adding a 6th built-in palette alongside blue/emerald/crimson/carbon/gold:
|
|
59
|
+
|
|
60
|
+
1. Run the generator with `--out` pointing at `packages/foundation/theme/tokens/palettes/<name>.ts`.
|
|
61
|
+
2. Register it: add `'<name>'` to the `PaletteName` union and `paletteLoaders` map in `packages/foundation/theme/context/ThemeContext.tsx`, and re-export it from `packages/foundation/theme/tokens/palettes/index.ts`.
|
|
62
|
+
3. Run the contrast regression suite before considering it done: `pnpm exec vitest run --config packages/foundation/vitest.config.ts` — it checks every semantic token pairing (including the new palette) against WCAG AA across both light and dark mode. See `packages/foundation/theme/tokens/COLOR_TOKEN_CONTRACT.md` for the full rule set this is checked against.
|
|
@@ -13,28 +13,36 @@ Use this skill when building forms, data entry panels, modal forms, settings pag
|
|
|
13
13
|
|
|
14
14
|
Do **NOT** hardcode or guess prop names, component options, preset variations, or Storybook patterns in this document. Always retrieve component definitions, active props, and live Storybook implementations directly via MCP:
|
|
15
15
|
|
|
16
|
-
### Component & Form
|
|
16
|
+
### Component & Form API Protocol:
|
|
17
17
|
|
|
18
18
|
```json
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
19
|
+
get_component_api({ "id": "form" })
|
|
20
|
+
get_component_api({ "id": "field" })
|
|
21
|
+
get_component_api({ "id": "dialogform" })
|
|
22
|
+
get_component_api({ "id": "input" })
|
|
23
|
+
get_component_api({ "id": "numberinput" })
|
|
24
|
+
get_component_api({ "id": "select" })
|
|
25
|
+
get_component_api({ "id": "multiselect" })
|
|
26
|
+
get_component_api({ "id": "datepicker" })
|
|
27
|
+
get_component_api({ "id": "fileupload" })
|
|
28
|
+
```
|
|
29
|
+
|
|
30
|
+
### Curated Form Documentation:
|
|
31
|
+
|
|
32
|
+
```json
|
|
33
|
+
get_documentation({ "id": "form" })
|
|
34
|
+
get_documentation({ "id": "dialogform" })
|
|
35
|
+
get_documentation({ "id": "field" })
|
|
28
36
|
```
|
|
29
37
|
|
|
30
38
|
### Live Storybook & Interactive Behavior Protocol:
|
|
31
39
|
|
|
32
40
|
```json
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
41
|
+
get_component_examples({ "component": "form", "variant": "Default" })
|
|
42
|
+
get_component_examples({ "component": "form", "variant": "AsyncInitialValues" })
|
|
43
|
+
get_component_examples({ "component": "form", "variant": "ConditionalFields" })
|
|
44
|
+
get_component_examples({ "component": "form", "variant": "CascadingOptions" })
|
|
45
|
+
get_component_examples({ "component": "dialogform", "variant": "Default" })
|
|
38
46
|
```
|
|
39
47
|
|
|
40
48
|
### Knowledge Graph & Symbol Usages:
|
|
@@ -16,21 +16,28 @@ Do **NOT** guess table prop names or hardcode table structures. Query the MCP se
|
|
|
16
16
|
### Inspect Component Contracts:
|
|
17
17
|
|
|
18
18
|
```json
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
19
|
+
get_component_api({ "id": "datatable" })
|
|
20
|
+
get_component_api({ "id": "exportbutton" })
|
|
21
|
+
get_component_api({ "id": "filtercontainer" })
|
|
22
|
+
get_component_api({ "id": "bulkactionbutton" })
|
|
23
|
+
```
|
|
24
|
+
|
|
25
|
+
### Read Curated Documentation:
|
|
26
|
+
|
|
27
|
+
```json
|
|
28
|
+
get_documentation({ "id": "datatable" })
|
|
29
|
+
get_documentation({ "id": "exportbutton" })
|
|
23
30
|
```
|
|
24
31
|
|
|
25
32
|
### Inspect Live Story Implementations:
|
|
26
33
|
|
|
27
34
|
```json
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
35
|
+
get_component_examples({ "component": "datatable", "variant": "Basic" })
|
|
36
|
+
get_component_examples({ "component": "datatable", "variant": "CursorPagination" })
|
|
37
|
+
get_component_examples({ "component": "datatable", "variant": "Sortable" })
|
|
38
|
+
get_component_examples({ "component": "datatable", "variant": "MultipleSelection" })
|
|
39
|
+
get_component_examples({ "component": "datatable", "variant": "CustomColumn" })
|
|
40
|
+
get_component_examples({ "component": "exportbutton", "variant": "WithTable" })
|
|
34
41
|
```
|
|
35
42
|
|
|
36
43
|
### Inspect Knowledge Graph & Usages:
|
|
@@ -47,7 +54,7 @@ query_graph({ "query": "useDataTableFetch" })
|
|
|
47
54
|
The Wangs UI `DataTable` is built on a modular, headless-first architecture:
|
|
48
55
|
|
|
49
56
|
1. **Declarative Column Definitions (`TableColumn<T>[]`)**:
|
|
50
|
-
Columns are configured as typed array objects, not as JSX children. Check `
|
|
57
|
+
Columns are configured as typed array objects, not as JSX children. Check `get_component_api({ "id": "datatable" })` for column field types.
|
|
51
58
|
2. **Table Instance Hook (`useDataTable`)**:
|
|
52
59
|
Coordinates table state (sorting, pagination, selection, column ordering, pinning, visibility).
|
|
53
60
|
3. **Data Fetching Hook (`useDataTableFetch`)**:
|
|
@@ -62,7 +69,7 @@ The Wangs UI `DataTable` is built on a modular, headless-first architecture:
|
|
|
62
69
|
|
|
63
70
|
## 3. Mandatory Implementation Rules
|
|
64
71
|
|
|
65
|
-
1. **Query MCP for Current Code Patterns**: Always run `
|
|
72
|
+
1. **Query MCP for Current Code Patterns**: Always run `get_component_examples` for `datatable` before drafting code.
|
|
66
73
|
2. **Strict Subpath Imports**: Import via `@wangs-ui/react-core/primitive/datatable` and companion primitive paths.
|
|
67
74
|
3. **Always Translate Visible Copy**: All column header labels, empty state messages, and action button labels must be wrapped in `t('...')` from `@wangs-ui/react-i18n`.
|
|
68
75
|
4. **Stable Row Identity**: Always configure a unique key identifier for stable selection and row identity.
|
|
@@ -16,18 +16,26 @@ Do **NOT** guess overlay props, event names, or footer slots. Query the MCP serv
|
|
|
16
16
|
### Inspect Overlay Contracts:
|
|
17
17
|
|
|
18
18
|
```json
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
19
|
+
get_component_api({ "id": "dialog" })
|
|
20
|
+
get_component_api({ "id": "dialogform" })
|
|
21
|
+
get_component_api({ "id": "modal" })
|
|
22
|
+
get_component_api({ "id": "toast" })
|
|
23
|
+
```
|
|
24
|
+
|
|
25
|
+
### Read Curated Overlay Documentation:
|
|
26
|
+
|
|
27
|
+
```json
|
|
28
|
+
get_documentation({ "id": "dialog" })
|
|
29
|
+
get_documentation({ "id": "dialogform" })
|
|
30
|
+
get_documentation({ "id": "modal" })
|
|
23
31
|
```
|
|
24
32
|
|
|
25
33
|
### Inspect Live Story Implementations:
|
|
26
34
|
|
|
27
35
|
```json
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
36
|
+
get_component_examples({ "component": "dialog", "variant": "RichHeaderFooter" })
|
|
37
|
+
get_component_examples({ "component": "dialogform", "variant": "Default" })
|
|
38
|
+
get_component_examples({ "component": "modal", "variant": "Default" })
|
|
31
39
|
```
|
|
32
40
|
|
|
33
41
|
### Inspect Knowledge Graph & Usages:
|
|
@@ -16,19 +16,26 @@ Do **NOT** guess component localization contracts, language switcher variants, o
|
|
|
16
16
|
### Inspect Localized Component Contracts:
|
|
17
17
|
|
|
18
18
|
```json
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
19
|
+
get_component_api({ "id": "languageswitcher" })
|
|
20
|
+
get_component_api({ "id": "currencyinput" })
|
|
21
|
+
get_component_api({ "id": "datepicker" })
|
|
22
|
+
get_component_api({ "id": "select" })
|
|
23
|
+
get_component_api({ "id": "datatable" })
|
|
24
|
+
```
|
|
25
|
+
|
|
26
|
+
### Read Curated Localization Documentation:
|
|
27
|
+
|
|
28
|
+
```json
|
|
29
|
+
get_documentation({ "id": "languageswitcher" })
|
|
30
|
+
get_documentation({ "id": "currencyinput" })
|
|
24
31
|
```
|
|
25
32
|
|
|
26
33
|
### Inspect Live Story Implementations:
|
|
27
34
|
|
|
28
35
|
```json
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
36
|
+
get_component_examples({ "component": "languageswitcher", "variant": "Default" })
|
|
37
|
+
get_component_examples({ "component": "currencyinput", "variant": "Default" })
|
|
38
|
+
get_component_examples({ "component": "datepicker", "variant": "Default" })
|
|
32
39
|
```
|
|
33
40
|
|
|
34
41
|
---
|
|
@@ -16,19 +16,26 @@ Do **NOT** guess layout block slots, sidebar item interfaces, or breadcrumb prop
|
|
|
16
16
|
### Inspect Layout & Navigation Contracts:
|
|
17
17
|
|
|
18
18
|
```json
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
19
|
+
get_component_api({ "id": "applayout" })
|
|
20
|
+
get_component_api({ "id": "sidebar" })
|
|
21
|
+
get_component_api({ "id": "breadcrumb" })
|
|
22
|
+
get_component_api({ "id": "tabs" })
|
|
23
|
+
```
|
|
24
|
+
|
|
25
|
+
### Read Curated Layout Documentation:
|
|
26
|
+
|
|
27
|
+
```json
|
|
28
|
+
get_documentation({ "id": "applayout" })
|
|
29
|
+
get_documentation({ "id": "sidebar" })
|
|
23
30
|
```
|
|
24
31
|
|
|
25
32
|
### Inspect Live Story Implementations:
|
|
26
33
|
|
|
27
34
|
```json
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
35
|
+
get_component_examples({ "component": "applayout", "variant": "TopNavbar" })
|
|
36
|
+
get_component_examples({ "component": "sidebar", "variant": "WithSubMenu" })
|
|
37
|
+
get_component_examples({ "component": "breadcrumb", "variant": "Default" })
|
|
38
|
+
get_component_examples({ "component": "tabs", "variant": "Default" })
|
|
32
39
|
```
|
|
33
40
|
|
|
34
41
|
### Inspect Knowledge Graph & Usages:
|
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: universal-layout
|
|
3
|
+
description: Universal layout primitives (Box, Flex, Stack, Grid, Container, Section) with ResponsiveValue patterns for Web and React Native in Wangs UI.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Skill: Universal Layout Primitives
|
|
7
|
+
|
|
8
|
+
Use this skill when arranging page structure, spacing, or responsive grids with
|
|
9
|
+
`@wangs-ui/foundation/layout`.
|
|
10
|
+
For app shells (sidebar, breadcrumb, tabs), see the `layout-navigation` skill instead.
|
|
11
|
+
|
|
12
|
+
---
|
|
13
|
+
|
|
14
|
+
## 1. MCP Inspection Protocol (Mandatory Single Source of Truth)
|
|
15
|
+
|
|
16
|
+
Do **NOT** guess layout prop names, spacing scales, or breakpoint keys. Query the MCP
|
|
17
|
+
server dynamically:
|
|
18
|
+
|
|
19
|
+
```json
|
|
20
|
+
list_catalog({ "category": "layout" })
|
|
21
|
+
get_component_api({ "id": "layout:box" })
|
|
22
|
+
get_component_api({ "id": "layout:grid" })
|
|
23
|
+
get_documentation({ "id": "layout-stack" })
|
|
24
|
+
```
|
|
25
|
+
|
|
26
|
+
Resolve shared types before writing responsive props:
|
|
27
|
+
|
|
28
|
+
```json
|
|
29
|
+
resolve_type_definition({ "name": "ResponsiveValue" })
|
|
30
|
+
resolve_type_definition({ "name": "SpacingKey" })
|
|
31
|
+
```
|
|
32
|
+
|
|
33
|
+
---
|
|
34
|
+
|
|
35
|
+
## 2. Choosing the Right Primitive
|
|
36
|
+
|
|
37
|
+
1. **Stack (VStack)** — default for vertical flows (forms, cards, page sections).
|
|
38
|
+
Fixed `column` direction, uniform `gap`, optional auto-`separator`.
|
|
39
|
+
2. **HStack** — horizontal rows with vertical centering (avatar + label + action,
|
|
40
|
+
toolbar clusters). Fixed `row` direction.
|
|
41
|
+
3. **Flex** — only when you need explicit `direction`, `wrap`, `align`, or `justify`
|
|
42
|
+
control beyond what Stack/HStack fix. Prefer Stack/HStack otherwise.
|
|
43
|
+
4. **Grid** — two-dimensional placement or multi-column flows:
|
|
44
|
+
- explicit `columns={{ compact: 1, medium: 2, expanded: 4 }}` for fixed column counts;
|
|
45
|
+
- `minItemWidth` for auto-fit (columns grow/shrink with container width, no media query);
|
|
46
|
+
- `GridItem` with `colSpan` / `rowSpan` for featured tiles.
|
|
47
|
+
5. **Box** — leaf-level spacing/sizing wrapper (`p`, `m`, `radius`, `overflow`), or
|
|
48
|
+
polymorphic `as="section" | "main" | "article"` for landmarks.
|
|
49
|
+
6. **Container / Section** — page-level rhythm only: `Container` bounds max-width
|
|
50
|
+
(`size`, default `'xl'`) with consistent horizontal padding; `Section` sets
|
|
51
|
+
vertical rhythm (`space: 'sm' | 'md' | 'lg'`, default `'md'`). Never nest
|
|
52
|
+
`Container` inside `Container`.
|
|
53
|
+
7. **ZStack** — overlays (badge on card, status dot on avatar, hero overlay).
|
|
54
|
+
8. **AspectRatio / Bleed / Spacer** — media frames (`ratio`), full-bleed breakouts
|
|
55
|
+
inside padded containers (`Bleed`), and flexible fillers in stacks (`Spacer`).
|
|
56
|
+
|
|
57
|
+
---
|
|
58
|
+
|
|
59
|
+
## 3. Mandatory Implementation Rules
|
|
60
|
+
|
|
61
|
+
1. **ResponsiveValue everywhere**: scalar for static (`gap={4}`), object for
|
|
62
|
+
adaptive (`gap={{ compact: 2, medium: 4, expanded: 6 }}`,
|
|
63
|
+
`columns={{ compact: 1, medium: 2, expanded: 4 }}`). Breakpoints are
|
|
64
|
+
`compact` (mobile-first base), `medium` (`md:`), `expanded` (`lg:`).
|
|
65
|
+
2. **Separators, not manual dividers**: `<Stack separator={<Divider />}>` inserts
|
|
66
|
+
dividers between children with no trailing element. Never hand-place a divider
|
|
67
|
+
after every child.
|
|
68
|
+
3. **Spacing scale**: `gap`/`p`/`m` use `SpacingKey` (Tailwind numeric scale,
|
|
69
|
+
1 unit = 4px). Never pass raw pixel strings to spacing props.
|
|
70
|
+
4. **Strict subpath imports**:
|
|
71
|
+
```tsx
|
|
72
|
+
import { Stack, HStack, Grid, Container } from '@wangs-ui/foundation/layout';
|
|
73
|
+
```
|
|
74
|
+
5. **Translate visible labels** inside layout children via `t('...')` from
|
|
75
|
+
`@wangs-ui/react-i18n` (layout props themselves are never translated).
|
|
76
|
+
|
|
77
|
+
---
|
|
78
|
+
|
|
79
|
+
## 4. Anti-Patterns (Forbidden)
|
|
80
|
+
|
|
81
|
+
1. **Gap vs margin**: NEVER hardcode `marginBottom`/`mb-*` on children inside a
|
|
82
|
+
Stack/Flex/Grid to fake spacing — always use the parent's `gap`/`gapX`/`gapY`.
|
|
83
|
+
Margins collapse unpredictably and break `separator` insertion.
|
|
84
|
+
2. **No nested Containers** and no `Container` for non-page content (cards, modals).
|
|
85
|
+
3. **No `Flex` with hardcoded `flexDirection` styles** when `Stack`/`HStack` express it.
|
|
86
|
+
4. **No raw media queries** for `direction`/`gap`/`columns` — use `ResponsiveValue`.
|
|
87
|
+
5. **No `Grid` for one-dimensional lists** — that is `Stack`/`HStack` territory.
|
|
@@ -15,28 +15,34 @@ Do **NOT** guess component props, Pass-Through (`pt`) slots, or event names. Alw
|
|
|
15
15
|
|
|
16
16
|
```mermaid
|
|
17
17
|
graph TD
|
|
18
|
-
A[Identify Component Needed] --> B[
|
|
19
|
-
B --> C
|
|
20
|
-
C
|
|
21
|
-
|
|
22
|
-
D
|
|
23
|
-
E -->
|
|
18
|
+
A[Identify Component Needed] --> B[list_catalog to confirm the id]
|
|
19
|
+
B --> C[get_component_api for the typed contract]
|
|
20
|
+
C --> D{Need live story / variant code?}
|
|
21
|
+
D -->|Yes| E[get_component_examples]
|
|
22
|
+
D -->|No| F[get_documentation for curated guidance]
|
|
23
|
+
E --> G[Check Graphify: query_graph]
|
|
24
|
+
F --> G
|
|
25
|
+
G --> H[Implement Component with Subpath Imports]
|
|
24
26
|
```
|
|
25
27
|
|
|
26
28
|
### Discovery Steps:
|
|
27
29
|
|
|
28
30
|
1. **Inspect Component Contract & Props**:
|
|
29
31
|
```json
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
32
|
+
get_component_api({ "id": "button" })
|
|
33
|
+
get_component_api({ "id": "input" })
|
|
34
|
+
get_component_api({ "id": "datatable" })
|
|
33
35
|
```
|
|
34
|
-
2. **Inspect
|
|
36
|
+
2. **Inspect Curated Documentation**:
|
|
35
37
|
```json
|
|
36
|
-
|
|
37
|
-
get-documentation-for-story({ "id": "datatable", "storyName": "ServerPagination" })
|
|
38
|
+
get_documentation({ "id": "button" })
|
|
38
39
|
```
|
|
39
|
-
3. **Inspect
|
|
40
|
+
3. **Inspect Live Usage & Story Variants**:
|
|
41
|
+
```json
|
|
42
|
+
get_component_examples({ "component": "button", "variant": "Sizes" })
|
|
43
|
+
get_component_examples({ "component": "datatable", "variant": "CursorPagination" })
|
|
44
|
+
```
|
|
45
|
+
4. **Inspect Relationships & Real Usages in Graph**:
|
|
40
46
|
```json
|
|
41
47
|
query_graph({ "query": "DataTable" })
|
|
42
48
|
query_graph({ "query": "usePT" })
|
|
@@ -104,5 +110,7 @@ Never write raw HTML elements when a Wangs UI primitive exists:
|
|
|
104
110
|
|
|
105
111
|
### Spacing Tokens
|
|
106
112
|
|
|
107
|
-
-
|
|
108
|
-
-
|
|
113
|
+
- Flat numeric scale, Tailwind-aligned (1 unit = 4px): `0`, `0.5`, `1`, `1.5`, `2`, `2.5`, `3`, `3.5`, `4`…`16` (e.g. `4` = 16px)
|
|
114
|
+
- Web: use numeric utilities directly — Gap: `gap-4`, Padding: `px-4 py-1.5`
|
|
115
|
+
- Native: read pixel values via `useTheme().spacing` (e.g. `spacing[4] === 16`)
|
|
116
|
+
- Responsiveness via `ResponsiveValue<T>` size props and `<Show>`, not per-density spacing tokens
|