Skip to content

Commit 613108b

Browse files
stevekwon211claude
andcommitted
feat(docs): v0.32.0 — Directory page (community registry discovery surface)
shadcn's /docs/directory analog. Closes the Tooling track parity gap except for the optional /create preset page. - New registry/directory.json — schema-shaped list of registries (namespace + title + description + url + homepage + maintainer + counts + license + tags). Default entry seeds with the slintcn official set; community registries land via PR. - scripts/build-docs.mjs gains directoryPage() — renders /docs/directory.html as a card per registry (chips for namespace / counts / license / tags + an `slintcn add @ns/...` install command line), plus "how it works" and "list yours" PR template sections. - Sidebar Directory link in every docs page. - README "Community registries" section pointing at the directory + the JSON. No new runtime code, pure docs/ecosystem surface; the underlying multi-registry support has been in the CLI since v0.14. Co-Authored-By: Claude <noreply@anthropic.com>
1 parent d1051b9 commit 613108b

8 files changed

Lines changed: 141 additions & 7 deletions

File tree

README.md

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -91,6 +91,7 @@ node /path/to/slintcn/bin/slintcn.mjs add button card input dialog
9191
| **v0.29** | **Catalog round-out**`Collapsible` (single show/hide section), `ButtonGroup` (joined Buttons) → 53 components ||
9292
| **v0.30** | **Game HUD expansion**`Hotbar` (SlotTile strip), `Reticle` (crosshair overlay), `CompassStrip` (scrolling heading) → 56 components ||
9393
| **v0.31** | **MCP server**`slintcn-mcp` bin exposes the registry to MCP-capable AI agents (Claude Desktop, Cursor, Windsurf). Tools: `list_components`, `list_blocks`, `view_component`, `install_command` ||
94+
| **v0.32** | **Directory page**`/docs/directory` lists community + official registries; entries land via PR to `registry/directory.json` (ecosystem discovery surface) ||
9495

9596
SaaS-first is a **wedge**, not a ceiling. Once tokens + motion + hover semantics
9697
exist, a second registry (`registry/game/`) is just more `.slint` files.
@@ -158,6 +159,16 @@ against the same registry. The official registry is served at
158159
> **Maintainers:** publish to npm with `npm login && npm publish` (the package
159160
> ships `bin`, `registry`, `templates`, `schema`; `prepublishOnly` runs tests).
160161
162+
## Community registries
163+
164+
slintcn isn't tied to one registry. Any host that serves a `registry.json` +
165+
per-item `r/<name>.json` (the shape `slintcn build` emits) is a valid registry,
166+
and `slintcn add @namespace/name` installs from it once you wire the namespace
167+
into `slintcn.json`'s `registries` map.
168+
169+
Browse + list yours at **[stevekwon211.github.io/slintcn/docs/directory](https://stevekwon211.github.io/slintcn/docs/directory.html)**
170+
open a PR to [`registry/directory.json`](registry/directory.json) to be listed.
171+
161172
## MCP server (AI agents)
162173

163174
slintcn ships a Model Context Protocol server so MCP-capable agents (Claude

docs/ROADMAP.md

Lines changed: 21 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,25 @@
11
# slintcn roadmap
22

3-
## v0.31 — MCP server (current)
3+
## v0.32 — Directory page (current)
4+
5+
shadcn's `/docs/directory` shipped here. The discovery surface for community
6+
+ official registries.
7+
8+
- [x] New `registry/directory.json` — schema-shaped list of registries
9+
(namespace · title · description · url · homepage · maintainer · counts
10+
· license · tags). Default entry seeded with the slintcn official set.
11+
- [x] `scripts/build-docs.mjs` renders **`/docs/directory.html`** — card per
12+
registry (chips for namespace / counts / license / tags + an
13+
`slintcn add @ns/...` install command line), plus "how it works" + "list
14+
yours" PR template sections.
15+
- [x] Sidebar `Directory` link in every docs page.
16+
- [x] README "Community registries" section pointing to the directory + the
17+
JSON to PR into.
18+
19+
No new runtime code — pure docs / ecosystem surface. Closes the shadcn-
20+
Tooling-Track parity except for the optional `/create` preset page.
21+
22+
## v0.31 — MCP server
423

524
shadcn's most-active growth lane is the AI-agent integration. Ship our own:
625

@@ -175,7 +194,7 @@ heavy, separate R&D track; the Game/HUD layer is the long-term differentiator.
175194

176195
### Tooling track (parallel)
177196
- **MCP server** shipped in v0.31.
178-
- **Directory page** (shadcn `/docs/directory` analog) for community registries.
197+
- **Directory page** shipped in v0.32.
179198
- Optional **`/create`-style preset page** (pick components → copy command).
180199

181200
### v1.0+ — Game / HUD round-out (the differentiator)

examples/showcase/Cargo.lock

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

examples/showcase/Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
[package]
22
name = "slintcn-showcase"
3-
version = "0.31.1"
3+
version = "0.32.0"
44
edition = "2021"
55
publish = false
66

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "slintcn",
3-
"version": "0.31.1",
3+
"version": "0.32.0",
44
"description": "Beautiful copy-paste Slint components — shadcn for native UI",
55
"keywords": [
66
"slint",

registry/default/registry.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
"$schema": "https://slintcn.dev/schema/registry.schema.json",
33
"name": "default",
44
"homepage": "https://stevekwon211.github.io/slintcn",
5-
"version": "0.31.1",
5+
"version": "0.32.0",
66
"description": "Dark glass theme — shadcn-adjacent primitives for Slint",
77
"slintVersion": ">=1.16",
88
"theme": {

registry/directory.json

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
{
2+
"$schema": "https://slintcn.dev/schema/directory.schema.json",
3+
"_comment": "Community + official slintcn-compatible registries. To list your registry here, open a PR adding an entry to `registries`. The slintcn CLI consumes registries via slintcn.json's `registries` map; this directory is the public discovery surface.",
4+
"registries": [
5+
{
6+
"namespace": "default",
7+
"title": "slintcn (default)",
8+
"description": "The official dark-glass registry — 56 components + 8 blocks, an a11y contract per item, and a games / tools HUD layer.",
9+
"url": "https://stevekwon211.github.io/slintcn/r",
10+
"homepage": "https://stevekwon211.github.io/slintcn/docs",
11+
"repo": "https://github.com/stevekwon211/slintcn",
12+
"maintainer": "stevekwon211",
13+
"license": "MIT",
14+
"components": 56,
15+
"blocks": 8,
16+
"tags": ["dark", "glass", "games", "hud", "shadcn-style"]
17+
}
18+
]
19+
}

scripts/build-docs.mjs

Lines changed: 86 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,8 @@ function sidebar(items, activeName) {
5858
html += `<div class="s-group"><div class="s-label">Get started</div>`;
5959
html += `<a class="s-item" href="./index.html">Introduction</a>`;
6060
html += `<a class="s-item" href="../">Landing</a>`;
61-
html += `<a class="s-item" href="../demo.html">Playground</a></div>`;
61+
html += `<a class="s-item" href="../demo.html">Playground</a>`;
62+
html += `<a class="s-item" href="./directory.html">Directory</a></div>`;
6263
html += `<div class="s-group"><div class="s-label">Components</div>`;
6364
for (const c of cats) {
6465
html += `<div class="s-sub">${esc(CATEGORY_LABEL[c] ?? c)}</div>`;
@@ -193,6 +194,82 @@ ${apiSection}
193194
</html>`;
194195
}
195196

197+
function directoryPage(items, directory) {
198+
// Card per registry — namespace + meta + install command + counts + tags.
199+
const card = (r) => `
200+
<a class="idx-card" href="${escAttr(r.homepage)}" target="_blank" rel="noreferrer">
201+
<div class="idx-t">${esc(r.title)}</div>
202+
<div class="idx-d">${esc(r.description)}</div>
203+
<div class="dir-meta">
204+
<span class="chip">@${esc(r.namespace)}</span>
205+
${r.components != null ? `<span class="chip">${esc(r.components)} components</span>` : ""}
206+
${r.blocks != null ? `<span class="chip">${esc(r.blocks)} blocks</span>` : ""}
207+
${r.license ? `<span class="chip">${esc(r.license)}</span>` : ""}
208+
${(r.tags ?? []).map((t) => `<span class="chip muted">${esc(t)}</span>`).join("")}
209+
</div>
210+
<div class="dir-cmd"><code>slintcn add @${esc(r.namespace)}/&lt;name&gt;</code></div>
211+
</a>`;
212+
213+
return `<!doctype html>
214+
<html lang="en">
215+
<head>
216+
<meta charset="utf-8">
217+
<meta name="viewport" content="width=device-width, initial-scale=1">
218+
<title>Directory — slintcn docs</title>
219+
<link rel="stylesheet" href="./docs.css">
220+
</head>
221+
<body>
222+
${topnav()}
223+
<div class="shell">
224+
${sidebar(items, "")}
225+
<main class="main">
226+
<div class="hdr">
227+
<h1>Directory</h1>
228+
<p class="desc">Registries you can install slintcn components from. Add yours with a PR to
229+
<a href="https://github.com/stevekwon211/slintcn/blob/main/registry/directory.json"><code>registry/directory.json</code></a>.</p>
230+
</div>
231+
232+
<h2>Registries</h2>
233+
<div class="idx-grid">${directory.registries.map(card).join("")}</div>
234+
235+
<h2>How it works</h2>
236+
<p class="muted">slintcn isn't tied to a single registry. Any host serving a <code>registry.json</code>
237+
+ per-item <code>r/&lt;name&gt;.json</code> files (the shape <code>slintcn build</code> emits) is a
238+
valid registry. Wire it into your project's <code>slintcn.json</code>:</p>
239+
<div class="code-block"><pre><code>{
240+
"style": "default",
241+
"registries": {
242+
"default": "https://stevekwon211.github.io/slintcn/r",
243+
"acme": "https://acme.dev/slintcn"
244+
}
245+
}</code></pre></div>
246+
<p class="muted">Then install with the namespace prefix:</p>
247+
<div class="code-block"><pre><code>slintcn add @acme/button-pro
248+
slintcn add https://example.com/registry/r/special.json # direct URL also works</code></pre></div>
249+
250+
<h2>List yours</h2>
251+
<p class="muted">Open a PR that adds an entry to
252+
<a href="https://github.com/stevekwon211/slintcn/blob/main/registry/directory.json"><code>registry/directory.json</code></a>:</p>
253+
<div class="code-block"><pre><code>{
254+
"namespace": "yours",
255+
"title": "Your registry",
256+
"description": "What it offers in one line.",
257+
"url": "https://yours.example/r",
258+
"homepage": "https://yours.example",
259+
"repo": "https://github.com/you/yours",
260+
"maintainer": "you",
261+
"license": "MIT",
262+
"components": 12,
263+
"blocks": 2,
264+
"tags": ["light", "minimal"]
265+
}</code></pre></div>
266+
</main>
267+
</div>
268+
<script src="./docs.js"></script>
269+
</body>
270+
</html>`;
271+
}
272+
196273
function indexPage(items) {
197274
const ui = items.filter((i) => i.type === "registry:ui");
198275
const blocks = items.filter((i) => i.type === "registry:block");
@@ -234,6 +311,9 @@ async function main() {
234311
const a11y = JSON.parse(
235312
await readFile(path.join(ROOT, "registry", "default", "a11y.json"), "utf8"),
236313
);
314+
const directory = JSON.parse(
315+
await readFile(path.join(ROOT, "registry", "directory.json"), "utf8"),
316+
);
237317
// docs pages = user-facing items only (ui + blocks); skip theme + lib helpers.
238318
const items = catalogFromRegistry(registry).filter(
239319
(i) => i.type === "registry:ui" || i.type === "registry:block",
@@ -243,6 +323,7 @@ async function main() {
243323
await writeFile(path.join(outDir, "docs.css"), DOCS_CSS);
244324
await writeFile(path.join(outDir, "docs.js"), DOCS_JS);
245325
await writeFile(path.join(outDir, "index.html"), indexPage(items));
326+
await writeFile(path.join(outDir, "directory.html"), directoryPage(items, directory));
246327

247328
for (let i = 0; i < items.length; i++) {
248329
const api = {
@@ -379,6 +460,10 @@ h2{font-size:21px;letter-spacing:-.01em;margin:40px 0 14px;scroll-margin-top:72p
379460
.idx-card{border:1px solid var(--line);border-radius:var(--radius);background:var(--card);padding:16px}
380461
.idx-card:hover{border-color:var(--line-strong)}
381462
.idx-t{font-weight:600;margin-bottom:4px}.idx-d{font-size:13px;color:var(--muted)}
463+
.dir-meta{display:flex;flex-wrap:wrap;gap:6px;margin-top:10px}
464+
.dir-meta .chip{font-size:11px;padding:2px 8px}
465+
.dir-meta .chip.muted{opacity:.65}
466+
.dir-cmd{margin-top:10px;font-family:var(--mono);font-size:12px;color:var(--fg);background:var(--surface);border:1px solid var(--line);border-radius:8px;padding:6px 10px;overflow-x:auto;white-space:nowrap}
382467
/* slint syntax highlight */
383468
.tok-cmt{color:#6b7280}.tok-str{color:#86efac}.tok-kw{color:#c4b5fd}.tok-type{color:#7dd3fc}.tok-prop{color:#fca5a5}
384469
/* mobile nav drawer */

0 commit comments

Comments
 (0)