Showcase Contract

The showcase is a composition chain, not a page-by-page metadata copy:

flowchart LR
  Registry["registry.ts"] --> Shell["ComponentPage.svelte"]
  Registry --> Route["components slug +page.svelte"]
  Route --> Shell
  Route --> Demo["Demo.svelte"]
  DemoSource["Demo component source"] --> Raw["Vite ?raw import"]
  Raw --> Demo
  Demo --> Code["CodeBlock.svelte"]

Every Mermaid label containing . or + is quoted above; the diagram represents source relationships, not deployment state.

1. Registry authority

src/lib/showcase/registry.ts is the single source of truth for:

  • route slug;
  • display name;
  • category and category order;
  • one-line blurb;
  • optional Bits UI namespace; and
  • whether an entry is a utility.

bySlug supplies lookup, grouped() supplies ordered navigation groups, neighbours() supplies previous and next entries, and docsUrl() maps every showcase entry to its local wiki guide at https://wiki.bits.loca.zone/components/<slug>.

2. Shared component page

ComponentPage.svelte accepts slug, optional anatomy, optional notes, and child content. It looks up the registry entry, writes title and description metadata, renders category/name/blurb/import guidance, exposes the anatomy list, and derives previous/next navigation from registry order.

A route page supplies component-specific demos and notes; it does not duplicate the registry record.

3. Demo shell and source handoff

Demo.svelte accepts this interface:

type Props = {
	title: string;
	description?: string;
	/** raw source of the demo component, imported with `?raw` */
	src?: string;
	/** extra vertical room for overlay-heavy demos */
	tall?: boolean;
	children: Snippet;
};

The source disclosure exists only when src is truthy. Importing a raw string without passing it to Demo is not sufficient. tall adds vertical room but does not change overlay behavior.

Reference composition

This is the canonical route shape. The explicit src={basicSrc} handoff is the contract that activates the source disclosure:

<script lang="ts">
	import ComponentPage from '$lib/showcase/ComponentPage.svelte';
	import Demo from '$lib/showcase/Demo.svelte';
 
	import BasicDemo from '$lib/demos/accordion/BasicDemo.svelte';
	import basicSrc from '$lib/demos/accordion/BasicDemo.svelte?raw';
</script>
 
<ComponentPage
	slug="accordion"
	anatomy={[
		'Accordion.Root',
		'Accordion.Item',
		'Accordion.Header',
		'Accordion.Trigger',
		'Accordion.Content'
	]}
>
	<Demo
		title="Single"
		description={'type="single" keeps at most one section open'}
		src={basicSrc}
	>
		<BasicDemo />
	</Demo>
 
	{#snippet notes()}
		<p>Document required props, value shape, form behavior, portals, CSS variables, or accessibility details here.</p>
	{/snippet}
</ComponentPage>

Invariants

  1. A component route slug must resolve in the registry.
  2. Registry order, not filesystem discovery, controls category navigation.
  3. A demo stays self-contained under src/lib/demos/<slug>/.
  4. Source reveal requires a ?raw import passed through src.
  5. Component-specific, non-obvious API guidance belongs in the notes snippet.
  6. Primary guide URLs come from docsUrl and stay on the local wiki; upstream references are secondary links inside the generated guide.
  7. bun run generate:component-guides derives all 46 guides, their index, and the reference catalog from this registry; never hand-maintain a parallel component list.

loca.zone · bits.loca.zone · Bits UI · Vite