Skip to content

Latest commit

 

History

History
102 lines (82 loc) · 5.43 KB

File metadata and controls

102 lines (82 loc) · 5.43 KB

Hirael — a shadcn-compatible component registry

Hirael ships "the components shadcn/ui doesn't ship": ~64 React components, 80+ section blocks, and full-page templates, distributed through the shadcn registry schema — consumers run npx shadcn add https://hirael.com/r/<name>.json and the source lands in their repo. There's no runtime package. The repo is the showcase site: a static Next.js 16 export that previews every item and serves the generated /r/*.json files. CONTRIBUTING.md has the full workflow and item checklist.

Stack — not the versions you know

Next.js 16, React 19, Tailwind v4. Check the nextjs / shadcn / react-best-practices skills before framework code. Traps hit here:

  • output: "export" — no server at runtime. Data (the /changelog fetch, source reads) is fetched once at next build and frozen into out/. Images are unoptimized; route params are Promises (await them); dynamicParams = false, so add items to registry-meta.ts, not a route table.
  • The React Compiler is on. Don't hand-write useMemo/useCallback in showcase code (app/, components/, lib/, examples/) — but keep explicit memoization in shipped registry source (ui/*, components/*), which consumers may run without the compiler. TanStack Table (v9) components need "use no memo".
  • Tailwind is CSS-first — no config file; tokens via @theme inline in app/globals.css; .dark / .light set on <html> by a prehydration script in app/layout.tsx.

registry-meta.ts is the single source of truth

registry-meta.ts declares every item; the sidebar, counts, pages, and sitemap derive from it (its presence is the only "published" flag). To change the catalog: edit it, register the preview loader in registry-demos.tsx, run pnpm registry:gen, commit. Never hand-edit registry.json — it's generated, and pnpm check:registry fails on drift or a missing loader. List registryDependencies by bare name; generation rewrites hirael-to-hirael deps to /r/<name>.json URLs.

Every item follows the same shape

  • Compound API first — a flat set of composable parts like shadcn primitives, no namespacing. The bare Name holds state; NameTrigger, NameContent, … are the parts. A single-prop form is optional, never the only API.
  • data-slot="<kebab>" on every rendered slot.
  • ui/ is shadcn primitives only; hirael's own go in components/. Import via @/registry/hirael/ui/* and @/registry/hirael/components/* (rewritten on install); never import across items by relative path.
  • Design tokens, never hard-coded colors (defined in app/globals.css); compose classes with cn(). Light is a faithful inverse of dark, both must work. --warm (taupe) is the brand tone; --accent-cool is reserved for live/active state — don't swap or waste them.
  • A demo at examples/<name>-demo.tsx with user-facing strings through useT()t({ en, ar }) — so the RTL toggle shows Arabic.
  • RTL works with no config — logical properties (ms/me, ps/pe, start/end), rtl:rotate-180 on directional icons, mirror horizontal arrow-key focus. Physical geometry stays physical (Radix data-[side], Sheet/Sidebar side). Verify with the toggle.
  • Copy reads like a human — plain and specific, no hype ("Pick a date", not "Effortlessly select your desired date").

Don't undo these

  • Dark is the default canvas (:root); .light is the inverse.
  • No em dashes in site copy; social link is GitHub, not X — both deliberate.
  • Components are generic controls; single-domain compositions are blocks (the cloud / saas / widgets block kinds).
  • Auth embeds (/embed/blocks/auth/*) carry a "doesn't submit" notice — Google Safe Browsing flagged them as phishing. Keep registry components real (native type="password"), fix appearance at the showcase layer, and don't robots-disallow /embed/.
  • Single static-export app — not a monorepo, ships no npm package.

Gating

Before review, all four pass (plus a manual pass in both themes and RTL):

pnpm lint && pnpm typecheck && pnpm registry:build && pnpm build

Releases

/changelog renders MDX entries from content/changelog/*.mdx — one file per release, compiled at build (next-mdx-remote) and frozen into the export. Frontmatter is title, date (YYYY-MM-DD), and optional version / description; the MDX body is visitor-facing (new components, blocks, fixes — no build/deploy internals). Production deploys only when a Release is publishedmain auto-deploy is off in vercel.json — so add the changelog entry in the same change and cut a Release to ship it.

This is NOT the Next.js you know

This version has breaking changes — APIs, conventions, and file structure may all differ from your training data. Read the relevant guide in node_modules/next/dist/docs/ (resolved from this file's directory; in monorepos the next package may not be visible from the repo root) before writing any code. Heed deprecation notices.

This block is written and re-added by next dev — verify at node_modules/next/dist/server/lib/generate-agent-files.js. Removing it from a diff only re-creates the uncommitted change; committing it with your work keeps the tree clean.