agentsclimarketplace

React shadcn ui

Skill event4u-app/agent-config/dist/agent-src/skills/react-shadcn-ui

Use when building React UI on shadcn/ui primitives + Tailwind — the apply/review/polish skill dispatched by `directives/ui/*` for the `react-shadcn` stack.From its SKILL.md

Install
npx -y skills add event4u-app/agent-config --skill react-shadcn-ui

Assembled from the repository path, not quoted from the project. Check it against their README if it does not work.

One thing to look at

  • 7 stars7 stars. Stars are a popularity signal and not a quality one, but at this level it is likely that nobody has read this closely except its author, and you would be relying on your own review.

SKILL.md

14.9 KB, ~3.8k tokens by cl100k_base, as published. Nobody here has run it

react-shadcn-ui

Grounded stack guidance: pull idiomatic Do/Don't + docs URLs via ./scripts-run <skills-root>/corpus-grounding/scripts/ground search --manifest <skills-root>/design-intelligence/data/manifest.json --stack shadcn "<topic>" (also --stack react, --stack nextjs). See design-intelligence.

Component installer — scripts/shadcn_add.ts (gated, assisted)

Bundled installer (Apache-2.0-derived, see header + design-intelligence/ATTRIBUTION.md) wraps npx shadcn@latest add <components>the only subprocess+network surface in the adopted suite. Per runtime-safety + the execution block above:

  1. Propose, never silent-run — always show the exact npx command + component list first (use --dry-run); the user confirms before any live run.
  2. Missing tool → per missing-tool-handling: if npx/Node is absent, STOP and ask (install vs. manual component copy) — never silently work around.
  3. Verify after run — confirm the component landed (components/ui/<name>.tsx exists, components.json unchanged or sanely updated) before reporting success.

Compatibility

  • Tested against: [email protected], Tailwind CSS 3.x, React 18+.
  • The audit step (directives/ui/audit.ts) reads the line above and compares it with state.ui_audit.shadcn_inventory.version; a major mismatch triggers a soft halt before this skill runs.

When to use

Use when state.stack.frontend == "react-shadcn" and directives/ui/apply.ts, review.ts, or polish.ts dispatches to this skill, or when a React project clearly uses shadcn/ui (presence of components.json, @radix-ui/* dependencies, a components/ui/ folder of generated primitives).

Do NOT use when:

  • Project is Blade + Livewire + Flux (use flux / livewire / blade-ui).
  • Project is Vue (use the Vue stack skills).
  • Plain React without shadcn/ui — fall back to manual composition; this skill assumes the primitive set exists.

Gotcha

  • shadcn/ui is not an npm package. Primitives are copied into components/ui/ and edited in-place. Do not npm install shadcn-ui. Run npx shadcn@latest add <primitive> to scaffold; then edit.
  • Major-version drift between this skill's ## Compatibility line and the project's installed primitives is a real risk. The audit step writes state.ui_audit.shadcn_inventory with the detected version — when it diverges by a major, audit emits a soft halt before this skill runs.
  • shadcn/ui composes Radix primitives. Accessibility is built in via Radix but only when you use the wrapper components correctly (asChild, <DialogTrigger> instead of a bare <button>).
  • Tailwind tokens come from tailwind.config.{js,ts} (theme.extend.colors) and CSS custom properties on :root and .dark (--background, --foreground, --primary, --ring, …). Audit writes them into state.ui_audit.design_tokens. Use those tokens; do not hardcode values.
  • Dark mode is class-based (<html class="dark">). Every color must come from bg-background, text-foreground, etc. — never raw bg-white.
  • Every interactive primitive must declare a focus-visible state via focus-visible:ring-2 focus-visible:ring-ring; that comes for free with the generated primitives but is easy to remove during a refactor.
  • Anti-AI-slop: shadcn-default look. The out-of-the-box shadcn theme + Inter-as-system-fallback + neutral grays reads as template across projects (catalog T7/T8 + C5). Unless state.ui_audit.design_tokens pins the neutral palette as the project's identity, the polish step should match typography and color tokens to the design brief's aesthetic: line (from fe-design aesthetic-direction). Theme/font drift within a single audited project breaks consistency — variation lives between projects, not between components in the same surface.
  • Anti-AI-slop catalog + linter. Pull docs/guidelines/design-antipatterns.md before the polish step (Visual V1–V7, Layout L1–L8 are the React-component slop tells); the objective quality floors (WCAG contrast, focus-visible, reduced-motion) are CI-enforced by lint_design_quality.

Covered primitives

This skill is validated against the following shadcn primitives at the declared version:

  • Form / inputs: Button, Input, Textarea, Checkbox, RadioGroup, Select, Switch, Label, Form (react-hook-form wrapper + zodResolver).
  • Overlay: Dialog, Sheet, Popover, Tooltip, DropdownMenu, AlertDialog.
  • Layout: Card, Separator, Tabs, Accordion, ScrollArea.
  • Data display: Table (with @tanstack/react-table), Badge, Avatar, Skeleton, Progress.
  • Feedback: Toast (sonner), Alert.

Not covered — fall back to manual composition

  • Marketing-only components (Hero, Pricing, Features) — outside shadcn/ui.
  • Calendar / DatePicker — composition skill required, not generated.
  • Combobox — built from Command + Popover; case-by-case.
  • Streaming / partial-prerender boundaries — use the project's framework patterns (Next.js / Remix), not shadcn/ui.

Registry & MCP awareness (opt-in)

Default path = bundled scripts/shadcn_add.ts + components.json; works on most projects, stays default. Modern registry model is OPT-IN — no round-trips on every op. JSON-schema + namespace detail lazy-loaded from reference/registry.md; read only on this path.

shadcn info --json handshake — run as grounding step WHEN components.json declares custom/namespaced registries, OR theme-alignment in scope. Returns framework / aliases / installed components / icon lib / base settings. NOT a forced first action on every add (over-gating, low ROI vanilla).

  • Precedence: prefer live shadcn info --json; fall back to state.ui_audit.shadcn_inventory (existing-ui-audit) when CLI/MCP unreachable. Live read wins.

Namespaced installs@ns/item resolves via the registries map to a registry-item.json URL (see reference). view @ns/item before add. Honour registryDependencies (install the graph, incl. version-pinned GitHub refs acme/ui/button#v1.2.0); keep propose-never-silent-run + --dry-run.

Token-aware scaffoldingregistry-item.json cssVars (OKLCH light/dark/theme) → align to project tokens (info --json / components.json / state.ui_audit.design_tokens); never inject the default shadcn neutral theme (flagged anti-slop tell: default theme + Inter + neutral grays).

MCP path (opt-in) — shadcn MCP server: browse / search-across-registries / install-with-NL over MCP; wire per mcp. Alternative to CLI, never a hard dep. Decision: CLI = default + universal; MCP = opt-in when configured; registry-JSON literacy underpins both.

Procedure: render a shadcn/ui component for the design brief

Step 0: Inspect

  1. Read state.ui_audit.shadcn_inventory.version and confirm it matches the version in ## Compatibility within the same major. If audit flagged a mismatch, the user already chose to proceed — note that in state.changes.
  2. Read state.ui_audit.design_tokens — every color, spacing, and radius in the rendered output must reference a token from this map.
  3. Read state.ui_design:
    • components → the primitive list to compose.
    • microcopy → button labels, empty-state text, validation messages. Lock — render verbatim.
    • states → empty / loading / error / success / disabled coverage.
    • a11y → ARIA labels, keyboard nav, focus order.

Step 1: Compose primitives

  1. Import primitives from the project's components/ui/ path (@/components/ui/button, …) — never from shadcn or radix-ui.
  2. Compose Radix-style: <Dialog><DialogTrigger asChild><DialogContent><DialogHeader><DialogTitle>. Never wrap DialogTrigger around a pre-styled <button>; pass asChild.
  3. Use the variant API of Button (variant="default" | "destructive" | "outline" | "secondary" | "ghost" | "link"); do not override with raw Tailwind for the variant set.
  4. Forms: useForm (react-hook-form) + zodResolver(schema)<Form><FormField><FormItem><FormLabel><FormControl><FormMessage>. Validation messages come from the zod schema, mirrored to the design-brief microcopy.

Step 2: Apply tokens, dark mode, a11y

  1. Colors via semantic classes: bg-background, text-foreground, bg-primary text-primary-foreground, text-muted-foreground. No bg-white / text-black / hardcoded #fff.
  2. Spacing / radius from theme tokens (rounded-lg mapped to --radius in tailwind.config.{js,ts}). Polish refactors hardcoded values when a token equivalent exists.
  3. Dark mode: never branch on a dark prop; rely on the .dark class on the root and semantic tokens.
  4. Every interactive primitive: keyboard trigger present (Enter/Space on buttons, Esc on dialogs — Radix free), visible focus ring, aria-label from state.ui_design.a11y when icon-only.

Step 3: State coverage

  1. Empty: render the design-brief empty-state copy in a Card or inline placeholder; never null.
  2. Loading: Skeleton rows for tables; Button disabled + Loader2 icon for submit-in-flight.
  3. Error: Alert variant="destructive" with the design-brief message; FormMessage for field-level errors.
  4. Success: toast.success(...) from sonner with the design-brief confirmation copy.
  5. Disabled: disabled prop on the trigger plus the design-brief reason as aria-describedby text.

Step 4: Validate

  1. No raw <input> / <button> / <select> outside the primitive set.
  2. No hardcoded colors / spacing — every value is a token.
  3. Microcopy matches state.ui_design.microcopy byte-for-byte.
  4. Dark mode: toggle .dark on <html>, render the component, every surface still legible (no text-white on bg-white).
  5. Keyboard: Tab through every focusable element; focus ring visible.

Output format

  1. React component file(s) under the project's components/ (or app/) tree, importing primitives from @/components/ui/*.
  2. Per file, one entry recorded in state.changes with kind="ui", stack="react-shadcn", and the design-brief summary.

Review pass — a11y findings + preview envelope

When this skill is dispatched by directives/ui/review.ts (test slot) or directives/ui/polish.ts (verify slot) — i.e. a review/polish run, not the initial apply — it also emits:

  • state.ui_review.a11y{violations: [{rule, selector, severity}, ...], severity_floor?, accepted_violations?}. Run an a11y tool against the rendered output (e.g. axe-core via Playwright, @axe-core/react, jest-axe) and translate hits into this shape. Use the same (rule, selector) shape as state.ui_audit.a11y_baseline so the engine's de-dup matches pre-existing entries on replay. Omit the envelope on apply passes; the engine's _apply_a11y_gate only fires when a baseline is present.
  • state.ui_review.preview{render_ok: bool, screenshot_path?, dom_dump_path?, error?, skipped?, skip_reason?}. Render evidence is required, not optional on a review/polish pass: you MUST drive the headless browser (Playwright + axe-core) against the rendered output and write render_ok. Omitting it now triggers the preview_render_required halt — a render-capable stack can no longer claim success without rendering. render_ok: false with error populated triggers the preview_render_failed halt; render_ok: true with screenshot_path threads the screenshot into the delivery report's artifacts list. The only no-render path is an explicit, reasoned skip: set skipped: true plus a skip_reason (e.g. no Playwright runner in this env). Browser tooling (Playwright/Cypress/…) is a consumer-project dependency — this package does not ship one.

Polish dispatch: when the dispatcher skips review because a previous review pass already returned SUCCESS, this skill MUST itself synthesise the updated state.ui_review.findings (including any remaining a11y_violation entries) so the engine's gate sees the current state on the next polish round.

Taste Dials

DESIGN.md ## Taste Dials → honour: Variance → layout-family spread + asymmetry; Motion → animation budget + reduced-motion posture; Density → spacing scale + info-per-viewport. Absent → follow brief's inferred dials.

Component workshop (Storybook) — when the library is large enough

Generic "isolate + document reusable components" principle → fe-design § Component Architecture; this is the React carve-out for the tool-specific part.

  • When it pays off — real, growing shared-component library (more than a handful of reused primitives, multiple consumers, ongoing UI work): Storybook makes each component discoverable, reviewable in isolation, reused not re-invented. Skip for a small surface of one-offs — setup + maintenance not worth it yet.
  • Story per reusable primitive, not per screen — a story covers a component + its states (default / loading / empty / error / dark), mirroring the Step 3 state-coverage matrix. Screens composed, not story-fied.
  • Reuse the token layer — stories render under the same semantic tokens + .dark class; never hardcode a preview theme (Step 2 token discipline).
  • A11y in-workshop — run the a11y addon so isolation catches contrast / role / focus before the component reaches a screen.
  • Do NOT let stories drift from the component API — a story props-drilling values the component no longer accepts is stale documentation; keep beside the component, update in the same change.

Do NOT

  • Do NOT install shadcn-ui from npm — primitives are scaffolded.
  • Do NOT hardcode colors / spacing / radii — use the token map.
  • Do NOT branch on a dark prop — use semantic tokens + the .dark class.
  • Do NOT rewrite microcopy — it is locked by state.ui_design.
  • Do NOT skip asChild on DialogTrigger / SheetTrigger / similar Radix wrappers — it breaks the accessibility contract.
  • Do NOT introduce a non-shadcn UI library (MUI, Chakra) into the same surface — pick one system per surface.

Auto-trigger keywords

  • shadcn / shadcn ui / shadcn/ui
  • React component (when the project uses shadcn)
  • Radix primitive
  • Tailwind dark mode
  • React Hook Form + zod

What ships with it: 2 files

16.6 KB alongside SKILL.md, 1 of them executable

reference/

scripts/

Keep looking

Skills are one crate of 325,949. Ordering is by how many stacks a row turns up in, so the top of any crate is what has actually been picked rather than what has the most stars.