@fr0mpy/component-system 2.2.0 → 3.1.0
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 +86 -27
- package/bin/cli.js +155 -62
- package/bin/validate-compliance.js +447 -0
- package/bin/validate-config.js +175 -0
- package/index.js +15 -0
- package/package.json +6 -4
- package/templates/agents/component-auditor.md +77 -0
- package/templates/agents/design-token-validator.md +72 -0
- package/templates/agents/harness-scaffolder.md +146 -0
- package/templates/agents/playwright-tester.md +437 -0
- package/templates/agents/style-inspector.md +81 -0
- package/templates/commands/component-harness.md +104 -10
- package/templates/commands/retheme.md +142 -0
- package/templates/commands/save-theme.md +50 -0
- package/templates/commands/setup-styling.md +386 -57
- package/templates/component-recipes/accordion.md +9 -9
- package/templates/component-recipes/alert.md +36 -23
- package/templates/component-recipes/avatar.md +14 -12
- package/templates/component-recipes/badge.md +9 -6
- package/templates/component-recipes/breadcrumb.md +4 -4
- package/templates/component-recipes/button.md +2 -2
- package/templates/component-recipes/checkbox.md +5 -5
- package/templates/component-recipes/collapsible.md +13 -13
- package/templates/component-recipes/combobox.md +2 -2
- package/templates/component-recipes/context-menu.md +11 -11
- package/templates/component-recipes/dialog.md +16 -16
- package/templates/component-recipes/drawer.md +18 -18
- package/templates/component-recipes/dropdown-menu.md +12 -12
- package/templates/component-recipes/hover-card.md +11 -11
- package/templates/component-recipes/label.md +4 -4
- package/templates/component-recipes/modal.md +9 -9
- package/templates/component-recipes/navigation-menu.md +19 -19
- package/templates/component-recipes/popover.md +10 -10
- package/templates/component-recipes/progress.md +10 -8
- package/templates/component-recipes/radio.md +6 -6
- package/templates/component-recipes/select.md +5 -5
- package/templates/component-recipes/separator.md +2 -2
- package/templates/component-recipes/slider.md +2 -2
- package/templates/component-recipes/switch.md +6 -6
- package/templates/component-recipes/table.md +1 -1
- package/templates/component-recipes/tabs.md +6 -6
- package/templates/component-recipes/toast.md +56 -42
- package/templates/component-recipes/toggle-group.md +4 -4
- package/templates/component-recipes/tooltip.md +5 -5
- package/templates/mcp/mcp.json +8 -0
- package/templates/playwright/playwright.config.ts +31 -0
- package/templates/playwright/tests/components.spec.ts +104 -0
- package/templates/skills/react-patterns.md +4 -0
- package/templates/skills/styling.md +141 -52
- package/templates/hooks/triggers.d/react-patterns.json +0 -18
- package/templates/hooks/triggers.d/styling.json +0 -23
|
@@ -1,7 +1,51 @@
|
|
|
1
|
+
---
|
|
2
|
+
description: USE WHEN generating, modifying, or reviewing UI components, working with Tailwind CSS theming, design tokens, or component recipes. Enforces token usage, mobile-first patterns, and recipe compliance.
|
|
3
|
+
---
|
|
4
|
+
|
|
1
5
|
# Styling System
|
|
2
6
|
|
|
3
7
|
Apply this skill when generating, modifying, or reviewing UI components.
|
|
4
8
|
|
|
9
|
+
## How the Token System Works
|
|
10
|
+
|
|
11
|
+
The styling system uses a **CSS Variable → Tailwind → Component** architecture:
|
|
12
|
+
|
|
13
|
+
```
|
|
14
|
+
styling-config.json tailwind.config.ts Component
|
|
15
|
+
─────────────────────────────────────────────────────────────────────
|
|
16
|
+
"primary": "#00FF41" → primary: 'var(--color-primary)' → bg-primary
|
|
17
|
+
"success": "#00FF41" → success: 'var(--color-success)' → bg-success
|
|
18
|
+
"warning": "#FFB800" → warning: 'var(--color-warning)' → bg-warning
|
|
19
|
+
```
|
|
20
|
+
|
|
21
|
+
**Key insight:** You use SEMANTIC CLASS NAMES (like `bg-primary`, `bg-success`) that are already mapped to CSS variables. The actual hex values in `styling-config.json` are injected into CSS variables at runtime.
|
|
22
|
+
|
|
23
|
+
**DO NOT:**
|
|
24
|
+
- Try to interpolate `{tokens.*}` placeholders - there is no interpolation engine
|
|
25
|
+
- Use the hex values from config directly - they're for CSS variables only
|
|
26
|
+
- Use generic Tailwind colors (`bg-green-500`) - these bypass the token system
|
|
27
|
+
|
|
28
|
+
**DO:**
|
|
29
|
+
- Use semantic Tailwind classes: `bg-primary`, `bg-success`, `bg-warning`, `bg-destructive`
|
|
30
|
+
- Read `tokens.radius` from config and use that exact class (e.g., `rounded-none`)
|
|
31
|
+
- Trust that the CSS variables will provide the correct colors at runtime
|
|
32
|
+
|
|
33
|
+
## ⚠️ MANDATORY ENFORCEMENT
|
|
34
|
+
|
|
35
|
+
**Before writing ANY UI code, you MUST:**
|
|
36
|
+
|
|
37
|
+
1. Read `.claude/styling-config.json` if it exists
|
|
38
|
+
2. Check for component recipes in `.claude/component-recipes/`
|
|
39
|
+
3. If generating a component that has a recipe, follow it exactly
|
|
40
|
+
|
|
41
|
+
**NEVER:**
|
|
42
|
+
- Use hardcoded hex colors (`#XXXXXX`) - use semantic tokens
|
|
43
|
+
- Use hardcoded RGB/RGBA values - use semantic tokens
|
|
44
|
+
- Use non-semantic Tailwind colors (`bg-blue-500`) - use `bg-primary`, `bg-secondary`, etc.
|
|
45
|
+
- Use `focus:` for focus states - use `focus-visible:` for keyboard accessibility
|
|
46
|
+
- Omit `cursor-pointer` on interactive elements
|
|
47
|
+
- Use desktop-first responsive patterns (`max-sm:`, `max-md:`)
|
|
48
|
+
|
|
5
49
|
## When to Apply
|
|
6
50
|
|
|
7
51
|
- Creating new UI components (buttons, cards, inputs, modals, etc.)
|
|
@@ -21,44 +65,76 @@ Before generating any UI code:
|
|
|
21
65
|
|
|
22
66
|
When `.claude/styling-config.json` exists, use semantic tokens instead of hardcoded values:
|
|
23
67
|
|
|
24
|
-
|
|
|
25
|
-
|
|
68
|
+
| ❌ NEVER Use | ✅ ALWAYS Use |
|
|
69
|
+
|--------------|---------------|
|
|
70
|
+
| `#3b82f6` | `bg-primary` / `text-primary` |
|
|
71
|
+
| `#00FF41` | `bg-primary` / `text-primary` |
|
|
26
72
|
| `bg-blue-500` | `bg-primary` |
|
|
27
|
-
|
|
|
28
|
-
| `
|
|
29
|
-
| `
|
|
73
|
+
| `bg-red-500` | `bg-destructive` |
|
|
74
|
+
| `bg-green-500` | `bg-success` |
|
|
75
|
+
| `bg-yellow-500` | `bg-warning` |
|
|
76
|
+
| `text-gray-500` | `text-muted-foreground` |
|
|
77
|
+
| `rounded-lg` (assumed) | Value from `tokens.radius` |
|
|
78
|
+
| `shadow-md` (assumed) | Value from `tokens.shadows` |
|
|
79
|
+
| `focus:ring-2` | `focus-visible:ring-2` |
|
|
30
80
|
|
|
31
|
-
### Token Reference
|
|
81
|
+
### Complete Token Reference
|
|
32
82
|
|
|
33
83
|
```
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
tokens.colors.
|
|
37
|
-
tokens.colors.
|
|
38
|
-
tokens.colors.
|
|
39
|
-
tokens.colors.
|
|
40
|
-
tokens.colors.
|
|
41
|
-
tokens.colors.
|
|
42
|
-
tokens.
|
|
43
|
-
tokens.
|
|
44
|
-
tokens.
|
|
45
|
-
tokens.
|
|
84
|
+
COLORS (use Tailwind utility prefix: bg-, text-, border-)
|
|
85
|
+
─────────────────────────────────────────────────────────
|
|
86
|
+
tokens.colors.primary → bg-primary, text-primary, border-primary
|
|
87
|
+
tokens.colors.primary-foreground → text-primary-foreground
|
|
88
|
+
tokens.colors.secondary → bg-secondary, text-secondary
|
|
89
|
+
tokens.colors.secondary-foreground → text-secondary-foreground
|
|
90
|
+
tokens.colors.destructive → bg-destructive, text-destructive
|
|
91
|
+
tokens.colors.destructive-foreground → text-destructive-foreground
|
|
92
|
+
tokens.colors.success → bg-success, text-success
|
|
93
|
+
tokens.colors.success-foreground → text-success-foreground
|
|
94
|
+
tokens.colors.warning → bg-warning, text-warning
|
|
95
|
+
tokens.colors.warning-foreground → text-warning-foreground
|
|
96
|
+
tokens.colors.accent → bg-accent, text-accent
|
|
97
|
+
tokens.colors.accent-foreground → text-accent-foreground
|
|
98
|
+
tokens.colors.muted → bg-muted
|
|
99
|
+
tokens.colors.muted-foreground → text-muted-foreground
|
|
100
|
+
tokens.colors.surface → bg-surface (cards, panels)
|
|
101
|
+
tokens.colors.background → bg-background (page)
|
|
102
|
+
tokens.colors.foreground → text-foreground
|
|
103
|
+
tokens.colors.border → border-border
|
|
104
|
+
|
|
105
|
+
TYPOGRAPHY
|
|
106
|
+
───────────────────────────────────────────────────────
|
|
107
|
+
tokens.typography.families.heading → font-heading
|
|
108
|
+
tokens.typography.families.body → font-body
|
|
109
|
+
tokens.typography.families.code → font-mono
|
|
110
|
+
tokens.typography.classes.* → Pre-composed typography classes
|
|
111
|
+
|
|
112
|
+
LAYOUT
|
|
113
|
+
───────────────────────────────────────────────────────
|
|
114
|
+
tokens.radius → border radius class (e.g., rounded-none, rounded-md)
|
|
115
|
+
tokens.shadows.* → shadow-elevation-sm, shadow-elevation-md, etc.
|
|
116
|
+
tokens.spacing.tight/normal/loose → p-1, p-2, p-4, etc.
|
|
46
117
|
```
|
|
47
118
|
|
|
48
119
|
## Recipe Compliance
|
|
49
120
|
|
|
50
121
|
If a recipe exists in `.claude/component-recipes/[component].md`:
|
|
51
122
|
|
|
52
|
-
1. Read the recipe first
|
|
53
|
-
2. Follow the defined structure
|
|
123
|
+
1. **Read the recipe first** - MANDATORY
|
|
124
|
+
2. Follow the defined structure exactly
|
|
54
125
|
3. Use the exact variants specified
|
|
55
126
|
4. Apply the Tailwind classes from the recipe
|
|
56
|
-
5. Include all required states (hover, focus, disabled)
|
|
127
|
+
5. Include all required states (hover, focus-visible, disabled)
|
|
57
128
|
|
|
58
129
|
## Interactive Element Rules
|
|
59
130
|
|
|
60
|
-
All interactive elements MUST have
|
|
131
|
+
All interactive elements MUST have:
|
|
132
|
+
|
|
133
|
+
1. **`cursor-pointer`** - Visual affordance for clickability
|
|
134
|
+
2. **`focus-visible:` states** - Keyboard accessibility (NOT `focus:`)
|
|
135
|
+
3. **Minimum 44x44px touch target** - Mobile accessibility
|
|
61
136
|
|
|
137
|
+
### Elements requiring cursor-pointer:
|
|
62
138
|
- Buttons (`<button>`, `role="button"`)
|
|
63
139
|
- Clickable cards or list items
|
|
64
140
|
- Links styled as buttons
|
|
@@ -68,11 +144,13 @@ All interactive elements MUST have `cursor: pointer`:
|
|
|
68
144
|
- Any element with an `onClick` handler
|
|
69
145
|
|
|
70
146
|
```tsx
|
|
71
|
-
//
|
|
72
|
-
<button className="cursor-pointer ...">
|
|
147
|
+
// ✅ CORRECT - cursor-pointer AND focus-visible
|
|
148
|
+
<button className="cursor-pointer focus-visible:ring-2 focus-visible:ring-primary ...">
|
|
149
|
+
Click me
|
|
150
|
+
</button>
|
|
73
151
|
|
|
74
|
-
//
|
|
75
|
-
<button className="...">Click me</button>
|
|
152
|
+
// ❌ INCORRECT - missing cursor-pointer, using focus instead of focus-visible
|
|
153
|
+
<button className="focus:ring-2 ...">Click me</button>
|
|
76
154
|
```
|
|
77
155
|
|
|
78
156
|
## Mobile-First Design (REQUIRED)
|
|
@@ -89,13 +167,13 @@ All components MUST be built mobile-first. This means:
|
|
|
89
167
|
### Mobile-First Pattern Examples
|
|
90
168
|
|
|
91
169
|
```tsx
|
|
92
|
-
// CORRECT - Mobile first
|
|
170
|
+
// ✅ CORRECT - Mobile first
|
|
93
171
|
<div className="flex flex-col gap-2 sm:flex-row sm:gap-4">
|
|
94
172
|
<div className="p-4 md:p-6 lg:p-8">
|
|
95
|
-
<button className="w-full sm:w-auto px-4 py-3 min-h-[44px]">
|
|
173
|
+
<button className="w-full sm:w-auto px-4 py-3 min-h-[44px] cursor-pointer">
|
|
96
174
|
<h1 className="text-lg md:text-xl lg:text-2xl">
|
|
97
175
|
|
|
98
|
-
// INCORRECT - Desktop first (
|
|
176
|
+
// ❌ INCORRECT - Desktop first (NEVER do this)
|
|
99
177
|
<div className="flex flex-row gap-4 max-sm:flex-col max-sm:gap-2">
|
|
100
178
|
<div className="p-8 max-md:p-6 max-lg:p-4">
|
|
101
179
|
```
|
|
@@ -113,40 +191,49 @@ All components MUST be built mobile-first. This means:
|
|
|
113
191
|
|
|
114
192
|
## Component Generation Checklist
|
|
115
193
|
|
|
116
|
-
|
|
194
|
+
**YOU MUST verify ALL items before delivering any UI component:**
|
|
117
195
|
|
|
118
|
-
|
|
119
|
-
- [ ]
|
|
120
|
-
- [ ]
|
|
121
|
-
- [ ]
|
|
196
|
+
### Critical (MUST pass)
|
|
197
|
+
- [ ] No hardcoded hex colors (`#XXXXXX`)
|
|
198
|
+
- [ ] No hardcoded rgb/rgba values
|
|
199
|
+
- [ ] No non-semantic Tailwind colors (`bg-blue-500`, `text-red-600`, etc.)
|
|
200
|
+
- [ ] All interactive elements have `cursor-pointer`
|
|
201
|
+
- [ ] Using `focus-visible:` NOT `focus:` for focus states
|
|
202
|
+
- [ ] No desktop-first patterns (`max-sm:`, `max-md:`)
|
|
203
|
+
|
|
204
|
+
### Required
|
|
122
205
|
- [ ] Loaded styling config (if exists)
|
|
123
206
|
- [ ] Checked for component recipe (if exists)
|
|
124
|
-
- [ ] Using token-based colors
|
|
125
|
-
- [ ] Radius matches config
|
|
126
|
-
- [ ] Shadow
|
|
127
|
-
- [ ]
|
|
128
|
-
- [ ]
|
|
129
|
-
|
|
130
|
-
|
|
207
|
+
- [ ] Using token-based colors from config
|
|
208
|
+
- [ ] Radius matches config (`tokens.radius`)
|
|
209
|
+
- [ ] Shadow uses elevation system (`shadow-elevation-*`)
|
|
210
|
+
- [ ] All interactive states included (hover, focus-visible, disabled)
|
|
211
|
+
- [ ] Touch targets are minimum 44x44px
|
|
212
|
+
|
|
213
|
+
### Mobile-First
|
|
214
|
+
- [ ] Base styles target mobile (no breakpoint prefix)
|
|
215
|
+
- [ ] Larger screen styles use `sm:`/`md:`/`lg:` prefixes
|
|
216
|
+
- [ ] Layout is flexible (`flex-col` → `sm:flex-row` pattern)
|
|
131
217
|
|
|
132
218
|
## Auditing (when asked to review/audit)
|
|
133
219
|
|
|
134
220
|
Scan UI files for violations:
|
|
135
221
|
|
|
136
|
-
### Critical Violations
|
|
137
|
-
- **Desktop-first responsive patterns** (using `max-sm:`, `max-md:` instead of `sm:`, `md:`)
|
|
138
|
-
- **Missing responsive breakpoints** for layout/spacing/typography
|
|
139
|
-
- **Touch targets smaller than 44x44px** on interactive elements
|
|
222
|
+
### 🚨 Critical Violations (MUST FIX)
|
|
140
223
|
- Hardcoded hex colors (`#[0-9a-fA-F]{3,8}`)
|
|
141
|
-
- Hardcoded rgb/rgba values
|
|
142
|
-
-
|
|
143
|
-
-
|
|
224
|
+
- Hardcoded rgb/rgba values (`rgb(`, `rgba(`)
|
|
225
|
+
- Non-semantic Tailwind colors (`bg-blue-500`, `text-red-600`, etc.)
|
|
226
|
+
- Using `focus:` instead of `focus-visible:`
|
|
144
227
|
- Interactive elements missing `cursor-pointer`
|
|
228
|
+
- Desktop-first responsive patterns (`max-sm:`, `max-md:`, `max-lg:`)
|
|
229
|
+
- Touch targets smaller than 44x44px on interactive elements
|
|
145
230
|
|
|
146
|
-
### Warnings
|
|
231
|
+
### ⚠️ Warnings
|
|
232
|
+
- Missing responsive breakpoints for layout/spacing/typography
|
|
147
233
|
- Inconsistent border radius across components
|
|
148
234
|
- Inconsistent shadow depth
|
|
149
235
|
- Spacing that doesn't match density setting
|
|
236
|
+
- Inline styles with color/spacing values
|
|
150
237
|
|
|
151
238
|
### Audit Output Format
|
|
152
239
|
|
|
@@ -156,13 +243,15 @@ Styling Audit Report
|
|
|
156
243
|
Configuration: [loaded | not found]
|
|
157
244
|
Files scanned: [count]
|
|
158
245
|
|
|
159
|
-
CRITICAL:
|
|
246
|
+
🚨 CRITICAL VIOLATIONS:
|
|
160
247
|
- file.tsx:24 → Hardcoded `#3b82f6` → Use `bg-primary`
|
|
248
|
+
- file.tsx:53 → Using `focus:` → Use `focus-visible:`
|
|
249
|
+
- file.tsx:78 → Missing `cursor-pointer` on <button>
|
|
161
250
|
|
|
162
|
-
WARNINGS:
|
|
251
|
+
⚠️ WARNINGS:
|
|
163
252
|
- file.tsx:12 → `rounded-xl` but config is `rounded-lg`
|
|
164
253
|
|
|
165
|
-
Compliance: [X]%
|
|
254
|
+
Compliance: [X]% ([Y] critical, [Z] warnings)
|
|
166
255
|
```
|
|
167
256
|
|
|
168
257
|
## Fallback Behavior
|
|
@@ -1,23 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"styling": [
|
|
3
|
-
"style",
|
|
4
|
-
"styling",
|
|
5
|
-
"css",
|
|
6
|
-
"tailwind",
|
|
7
|
-
"theme",
|
|
8
|
-
"color",
|
|
9
|
-
"colours",
|
|
10
|
-
"spacing",
|
|
11
|
-
"design system",
|
|
12
|
-
"design tokens",
|
|
13
|
-
"dark mode",
|
|
14
|
-
"light mode",
|
|
15
|
-
"ui component",
|
|
16
|
-
"component library",
|
|
17
|
-
"className",
|
|
18
|
-
"aesthetic",
|
|
19
|
-
"visual",
|
|
20
|
-
"look and feel"
|
|
21
|
-
],
|
|
22
|
-
"_comment": "Styling trigger extension for @claude-tools/component-system"
|
|
23
|
-
}
|