All pages

Components

Every frame on the pages below is the component running, followed by the file that produced it, read off disk by the server. The code under a frame is the code that rendered it, so the two cannot drift apart.

What a demo does not promise is that its fixtures are the values the shipped page passes. Where that distinction matters the demo file says so in a comment.

The gallery is a short list rather than an inventory. src/components/ holds more than this, and a component appears here when someone registers it.

Adding your own

Three files, in this order.

  1. Write the demo

    src/lib/docs/showcase/<name>.tsx, kebab-case, exporting one component that takes no props. This file is what gets printed under the frame, so it is also the answer to "how do I call this", and anything the component needs as a prop is a fixture written at the top of it.

    import { StatsCard } from '@/components/Admin/StatsCard/StatsCard'
    
    export function StatsCardDemo() {
      return (
        <div className="flex flex-wrap gap-10">
          <StatsCard title="Matches" value={3} />
          <StatsCard title="Offers held" value={2} />
          <StatsCard title="Invites delivered" value="1 of 2" />
        </div>
      )
    }
  2. Register it

    src/lib/docs/showcase/index.ts. The key is the name the markdown will use, and it has to match the filename, because the path is derived from it.

    demo(
      'stats-card',
      StatsCardDemo,
      'One number with a label. These count what is on the page rather than ' +
        'what is in the database.',
    )

    The description is one sentence. It is printed under the frame, and it is printed instead of the render in /llms-full.txt, where a live component has no text form.

  3. Reference it from a page

    Any page under src/content/docs/, though the four gallery pages are where these belong.

    ## StatsCard
    
    :::demo{name="stats-card"}

:::

The lookup happens while the content is rendered. A name with no entry fails the render and names itself in the message, so a gallery page cannot show a blank frame that nobody notices.

## What a demo costs

The page itself stays a server component, demo or no demo. What a demo adds is one component's bundle: whichever of them opted into `'use client'`, which is why `ThemeToggle` in a frame is a working switch and `Footer` in a frame is markup.

No documentation page is JS-free. The shell ships `ThemeToggle` through the header in `routes/docs.tsx` and `CopyCode` from `DocsArticle` on every page in the corpus.
  1. 01KitThe twelve components under src/components/ui/, what each one decides for you, and the props it takes.
  2. 02ButtonsThe button components, rendered live with the props each one takes.
  3. 03Marketing sectionsThe landing page sections, rendered live with the content each one expects.
  4. 04AdminThe admin dashboard components, rendered live with the data each one displays.
  5. 05LayoutThe site header, the footer, and the card shell every dashboard panel renders in.

Updated