| name | documentation |
| description | Use when writing or editing the Lattice documentation site under docs/ — authoring or changing pages in docs/content/docs, adding live component examples with ComponentExample and test-generated fixtures, emphasizing caveats with the Info/Warning callouts, updating the sidebar, and verifying the docs build. |
Lattice Documentation
The docs are an Astro + Starlight site living
in docs/. Content is Markdown under docs/content/docs/**; the config (and sidebar) is
astro.config.mjs. Build artifacts go to dist-docs/ (git-ignored — never commit it).
npm run docs:dev
npm run docs:build
Both commands run npm run analyze first (a Sonda bundle build that writes docs/public/bundle-report.html),
so the first run is slower and leaves that generated report behind — expected, not a change to commit.
Path aliases available in docs files: @components → docs/components, @lib → docs/lib,
@lattice/lattice → resources/js (the actual package, so previews render real components).
Authoring a page
Live examples — ComponentExample + fixtures
This is how the docs render real, test-generated components instead of hand-maintained JSON.
Use it (in an .mdx page) for anything visual:
import ComponentExample from "@components/ComponentExample.astro";
<ComponentExample
php={`Select::make('country', 'Country')
->placeholder('Pick a country')
->options([Select::option('Germany', 'de')]);`}
fixture="select.basic"
values={{ country: "de" }}
/>
It renders four tabs: PHP (the php string — display only), Preview (the live render),
Tree (the serialized node JSON), and Style (the theme tokens used).
The fixture names a file in docs/fixtures/<key>.json. Fixtures are generated by a Pest test —
never hand-write or edit them. A describe('docs fixtures', …) block builds the component and dumps
it with dumpFixture():
describe('docs fixtures', function (): void {
it('dumps the select examples', function (): void {
dumpFixture('select.basic', [
Select::make('country', 'Country')
->placeholder('Pick a country')
->options([Select::option('Germany', 'de')]),
]);
expect('docs/fixtures/select.basic.json')->toBeReadableFile();
});
});
The loop for a new example:
- Add/extend a
docs fixtures test that builds the component and calls dumpFixture('your.key', [...]),
plus an expect('docs/fixtures/your.key.json')->toBeReadableFile() assertion (the CI guard).
- Run it to generate the file:
vendor/bin/pest --filter="docs fixtures".
- Reference it:
fixture="your.key", and keep the php string in sync with what the test builds.
values={{ … }} seeds initial form state so field previews render with data.
Commit the generated docs/fixtures/*.json alongside the page.
Emphasize important parts with callouts
Pull caveats, footguns, and helpful context out of the prose into a callout. Two reusable boxes live
in docs/components/:
import Info from "@components/Info.astro";
import Warning from "@components/Warning.astro";
<Info>Refreshes only the named component, not the whole page.</Info>
<Warning>This signs the action ref on serialize — an unsigned request is rejected.</Warning>
<Info> — helpful context, defaults, "good to know". (Wraps Starlight's blue note aside.)
<Warning> — gotchas, security/authorization notes, destructive or irreversible behavior,
required setup. (Wraps the yellow caution aside.)
- Both take an optional
title: <Warning title="Authorization">…</Warning>.
- In a plain
.md page (no imports), use the Markdown equivalents instead: :::note for Info and
:::caution for Warning.
- Use them where they earn attention. A page drowning in callouts emphasizes nothing.
Verify before committing
npm run docs:build passes (broken links, MDX, or imports fail the build).
- If you added or changed a fixture, run the
docs fixtures tests and commit the regenerated JSON.
- Do not commit
dist-docs/.