Skip to content

feat(shadcn): production catalog — 32 components, 48 rules, 14 worked examples - #35

Merged
ryandmonk merged 1 commit into
mainfrom
feat/shadcn-production
Aug 5, 2026
Merged

feat(shadcn): production catalog — 32 components, 48 rules, 14 worked examples#35
ryandmonk merged 1 commit into
mainfrom
feat/shadcn-production

Conversation

@ryandmonk

Copy link
Copy Markdown
Contributor

Grows the canonical shadcn/ui contract from a demonstration vocabulary (8 components, 2 intents, 8 rules, 2 examples — 70 KB) into the first production-quality governed catalog for the ecosystem (32 components, 11 intents, 48 rules, 14 examples — 459 KB).

What is in it

before after
components 8 32
sub-components 39 106
props 17 152
constraints 19 226
accessibility blocks 7/8 31/32
intents 2 11
rules 8 48
worked examples 2 14

New families: form controls (label, textarea, checkbox, switch, radio-group, select), form structure (field, form), feedback (alert, progress, skeleton, spinner, sonner), navigation (tabs, breadcrumb, pagination), overlays (popover, tooltip, sheet), layout/content (separator, avatar, accordion, scroll-area, aspect-ratio). Plus 5 new categories and the popover token pair.

Authored against the shadcn registry source and the Radix primitives, not recall. Several entries correct facts that are easy to get wrong and expensive to miss:

  • Separator ships decorative=true, so its default is role="none" — invisible to assistive tech.
  • Popover has no Title/Description ARIA wiring (unlike Dialog); aria-labelledby must be hand-wired.
  • Tooltip is absent on touch, closes on click, and carries aria-describedby — so it can never be a control's accessible name.
  • TooltipProvider is genuinely required (Radix throws without it).

Governance

48 rules, each with an authored rationale naming a concrete failure mode. 24/32 components are named by ≥1 rule; 9/11 intents carry scoped rules; every intent has ≥1 worked example.

Scoping was treated as load-bearing, not cosmetic: appliesTo filters enforcement, not just prompt text (rules.ts skips out-of-scope rules in S3), so a rule scoped too narrowly silently deletes governance. Three rules are deliberately universal — the naming floor true of every surface.

Verification

  • node scripts/validate.mjs PASSES — schema, back-compat, governance consistency, category membership, example reference resolution.
  • All 14 examples lint S1/S2/S3 with zero errors, and each validates against buildGenerationSchema for its intent, so the few-shot corpus is reachable by a constrained decoder.
  • A 14-mutation fail-first pass (drop a label's htmlFor, nest a card in a card, empty a tooltip, remove an alert-dialog cancel, …) is caught by the expected rule — the green run is not vacuous.

Adversarial verification caught two defects before they landed: a forbidden-composition rule with no forbidden* key (schema-invalid as written), and nine rules scoped too narrowly to reach the intents their components serve.

Known limits, recorded honestly

  • Sub-components cannot carry props in v0.4 (subComponentDescriptor has no props, and S2 rejects them). This makes the strongest constraints in this vocabulary inexpressible — trigger↔panel value pairing, href on every crumb, alt on AvatarImage. Each affected rule states its enforceable floor and admits the rest as guidance, in the voice of rule.table-carries-caption.
  • No rule type expresses "an ancestor must exist", so TooltipProvider's requirement is prose.
  • The shadcn docs are migrating to Base UI; these entries target Radix, matching the existing exemplars. The catalog should state its primitive target explicitly or it will drift.

🤖 Generated with Claude Code

… examples

Grows the canonical shadcn/ui contract from a demonstration vocabulary
(8 components, 2 intents, 8 rules, 2 examples) into the first
production-quality governed catalog for the ecosystem.

Vocabulary: +24 components / +67 sub-components covering the families a
real product screen needs — form controls (label, textarea, checkbox,
switch, radio-group, select), form structure (field, form), feedback
(alert, progress, skeleton, spinner, sonner), navigation (tabs,
breadcrumb, pagination), overlays (popover, tooltip, sheet), and
layout/content (separator, avatar, accordion, scroll-area,
aspect-ratio). 152 props, 226 constraints, accessibility blocks on 31 of
32, authored against the shadcn registry source and Radix primitives
rather than recall — several entries correct facts that are easy to get
wrong (Separator's shipped default is decorative=true / role=none;
Popover has no Title/Description ARIA wiring unlike Dialog; Tooltip is
absent on touch and can never be a control's accessible name;
TooltipProvider is genuinely required).

Governance: 11 intents (the 2 shipped ones verbatim, +9 covering
structured input, preference settings, record detail, overlay task,
panel navigation, wayfinding, supplementary detail, status feedback,
loading state) and 48 rules, each carrying an authored rationale that
names a concrete failure mode. 24 of 32 components are named by at least
one rule; 9 of 11 intents carry scoped rules; every intent has at least
one worked example.

Corpus: 14 worked examples, one or more per intent, every one S1/S2/S3
clean and reachable by the constrained decoder. They are simultaneously
the few-shot corpus and the proof the governance is satisfiable.

Verified: node scripts/validate.mjs PASSES (schema, back-compat,
governance consistency, category membership, example reference
resolution); all 14 examples lint S1/S2/S3 with zero errors; a
14-mutation fail-first pass proves the green run is not vacuous.

Two authored defects were caught by adversarial verification before
landing: a forbidden-composition rule with no forbidden* key (schema-
invalid) and nine rules scoped too narrowly to reach the intents their
components serve.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Copilot AI lite review requested due to automatic review settings August 5, 2026 17:24

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot wasn't able to review any files in this pull request.


💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants