| name | add-sketch |
| description | Full workflow for adding a new UI sketch to ui-flx. Sketches are low-fidelity, content-free wireframes of full screens (dashboard, chat, …) — gray bars, no real values, no shadcn primitives, plain divs. A sketch mirrors a composition's layout. Covers file structure, registry/sketches/<category>/catalog.ts registration, registry.json entry, and sync/build commands. Triggers: "add sketch", "new sketch", "criar sketch", "novo sketch", "add-sketch", or any request to create a new Flexnative sketch under registry/sketches. |
Add a new sketch to ui-flx
Sketches are low-fidelity wireframes of full screens — the blueprint twin of
a [add-composition]. Same archetype and layout as the composition, but content-free:
gray bars instead of text/values, plain divs instead of shadcn primitives.
They follow the pattern model (one inline .tsx, no props, no manifest, no
editor, no sanity) — same as compositions, with these differences:
| Composition | Sketch |
|---|
| Fidelity | high — real text/values | low — gray bars, no values |
| Components | shadcn primitives | plain divs only |
| Registry | registry/compositions/ | registry/sketches/ |
| Slug | dashboard-01 | sketch-dashboard-01 |
Pairing rule (1:1): a sketch mirrors exactly one composition. Its slug is
sketch- + the composition slug (dashboard-01 → sketch-dashboard-01), and its
layout matches that composition's layout. Not every composition needs a sketch, but a
sketch always derives from a composition.
Why the sketch- prefix is mandatory: the registry name namespace is
flat/global (public/r/<name>.json, @flx/<name>). Compositions already own
dashboard-01 / chat-01. Without the prefix the build collides (one
dashboard-01.json overwrites the other). slug = file name = registry name,
and registry:sync ties them — so the prefix lives in all three.
Metadata lives in registry/sketches/<category>/catalog.ts — the single
source of truth for name and description. registry:sync copies them into
registry.json.
src/lib/sketches/sketches-catalog.ts is a thin aggregator — do not edit it
directly unless adding a new category.
What to read before writing — branch here
Adding a sketch to an EXISTING category (most common)
Read only these two — plus the composition you are mirroring, for its layout:
registry/sketches/<category>/catalog.ts ← existing items + last number
registry/sketches/<category>/registry.json ← existing entries + path format
registry/compositions/<category>/<composition-slug>.tsx ← layout to wireframe (reference)
Adding a NEW category
Also read:
registry/sketches/registry.json ← to add the new include entry
src/lib/sketches/sketches-catalog.ts ← to import + register the category
Slug & naming
<category> — archetype: dashboard, chat, … (matches the composition's
category).
<slug> — sketch-{composition-slug} (e.g. sketch-dashboard-01).
- Component name — PascalCase from slug:
sketch-dashboard-01 → export function SketchDashboard01().
File structure to create
registry/sketches/<category>/<slug>.tsx
Only the component file. No manifest, example, editor, or sanity.
1. Create registry/sketches/<category>/<slug>.tsx
- Server component (no
'use client' — sketches are static).
- Export a named PascalCase function matching the slug.
- No imports of shadcn primitives, no
lucide-react, no cn unless truly
needed. Plain divs only.
- No real text or values — represent everything with gray bars:
bg-foreground/10, bg-foreground/15, bg-muted, rounded shapes.
- No comments in the code.
- Mirror the composition's layout (same regions, same responsive behavior:
hidden md:flex sidebars, grid-cols-2 lg:grid-cols-4, etc.).
export function SketchDashboard01() {
return (
<div className="bg-card w-full overflow-hidden rounded-xl border shadow-sm">
<div className="flex items-center gap-3 border-b px-4 py-3">
<div className="bg-foreground/15 size-6 rounded-md" />
<div className="bg-foreground/15 h-2 w-20 rounded-full" />
</div>
<div className="grid grid-cols-2 gap-3 p-4 lg:grid-cols-4">
{[0, 1, 2, 3].map((i) => (
<div key={i} className="flex flex-col gap-2 rounded-lg border p-3">
<div className="bg-foreground/10 h-2 w-12 rounded-full" />
<div className="bg-foreground/20 h-3.5 w-16 rounded-full" />
</div>
))}
</div>
</div>
)
}
Preview loads via the page's sketchRegistry →
import(\registry/sketches/${category}/${slug}`)`.
2. Register in registry/sketches/<category>/catalog.ts
{
slug: 'sketch-dashboard-02',
name: 'Short Human Title',
description: 'Wireframe: …',
span: 'full',
isNew: true,
}
Always set name and description here.
3. Add entry to registry/sketches/<category>/registry.json
files[].path is relative to the category directory. Sketches have no
shadcn or npm dependencies (plain divs), so both arrays are empty.
{
"name": "sketch-dashboard-02",
"type": "registry:block",
"registryDependencies": [],
"dependencies": [],
"files": [
{
"path": "sketch-dashboard-02.tsx",
"type": "registry:component",
"target": "components/flx/sketches/dashboard/sketch-dashboard-02.tsx"
}
]
}
| Field | Rule |
|---|
name | Same as catalog slug (sketch-<composition-slug>) |
type | Always "registry:block" |
files[0].path | Just <slug>.tsx — relative to the category directory |
files[0].target | components/flx/sketches/<category>/<slug>.tsx |
Do NOT add title or description — registry:sync writes them.
4. Run sync, validate, and build
pnpm run registry:sync
pnpm run registry:validate
pnpm run registry:build
Adding a new category (rare)
- Create
registry/sketches/<new-category>/catalog.ts:
import type { SketchCategory } from '@/lib/sketches/sketch-types'
export const kanbanCategory: SketchCategory = {
slug: 'kanban',
name: 'Kanban',
description: 'Low-fidelity wireframes of board layouts.',
hasNew: true,
grid: { columns: 1 },
items: [],
}
- Create
registry/sketches/<new-category>/registry.json — empty items:
{
"$schema": "https://ui.shadcn.com/schema/registry.json",
"name": "flx-sketches-kanban",
"homepage": "https://ui.flexnative.com",
"items": []
}
-
Add include in registry/sketches/registry.json.
-
Import + register in src/lib/sketches/sketches-catalog.ts
(sketchCategories array).
The /sketches page (src/app/(main)/sketches/) and global search pick up the
new category automatically.
Checklist
Key rules
- Sketch = low-fidelity wireframe of a full screen. Gray bars, no real
content, plain
divs — never shadcn primitives.
- Slug must be
sketch-<composition-slug> — the sketch- prefix avoids the
flat-namespace collision with the composition of the same archetype.
- 1:1 pairing — a sketch mirrors exactly one composition's layout.
- Catalog owns display name/description; never duplicate in
registry.json.
- No
manifest.ts / -example.tsx / editor/ / sanity/.
- Responsive is required — mirror the composition's breakpoints.