You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
svelte-kit-vice/src/uix/blocks/README.md

4.1 KiB

Blocks ($blocks)

Named compositions of canon components performing a page function (sticky site header, hero, app shell, docs shell, …). This tree IS the live inventory — one folder per block, no list in any doc.

Every block's README states its position under the coordination doctrine (2026-07-31): whether it owns its section's state, the shape of its data and the words for its states — or owns nothing because it is layout. Most are layout, and saying so explicitly is the point: inventing state for a block that coordinates nothing is the opposite mistake. Worked example: contact. Open candidate: newsletter.

  • Doctrine (what a block is, the admission rule, the B contract): docs/architecture/blocks.md
  • Guard: npm run blocks:check (B contract, self-testing) — it also decides what a block may import, that its README carries the template's four sections plus the landmark declaration, and that the demo catalog and this tree agree
  • Execution plan / state: docs/process/PLAN-blocks.md
  • Demos: web/routes/blocks/{kebab}/+page.svelte + gallery at web/routes/blocks/

Anatomy of a block

src/uix/blocks/{kebab}/
├── README.md          # Function · Composition map · Coordination · Decisions · Gaps
├── index.ts           # public export (compound component)
└── {kebab}.svelte     # composition — canon components only, layout via
                       # layout components, no .css file (B contract)

Anatomy of a block DEMO (B-9, second half)

Every block also ships a demo under web/routes/blocks/{kebab}/, and they all have the same shape — written once in web/routes/blocks/_lib/:

web/routes/blocks/{kebab}/
├── +page.svelte            # the demo: BlockDemo + live controls + doc tabs
├── {Name}Site.svelte       # the block inside a page's worth of REAL content
└── preview/
    ├── +layout@.svelte     # `@` resets the layout: the preview is its own page
    └── +page.svelte        # serves {Name}Site from URL params
  • _lib/BlockDemo.svelte — identity (name · function · fact chips) → the block full-bleed on the page → controls → tabs (Composición · API · A11y · Gaps · Notas).
  • The block is never framed. A stage with padding, a scroll box or a sticky chrome above it changes what the block does: a header pinned at offset: 0 measured 21px off inside a Card, and a position: sticky inside a scrolling div is a behaviour nobody experiences. If a block anchors to something, it is measured against what it will anchor to in production.
  • Device widths (375 / 768) mount the preview route in an iframe, because a narrow viewport can only be shown by a real document. Opt-in: in dev, two unbundled documents at once exhaust the browser's connections.
  • _lib/DocRow.svelte — the two-column row the doc tabs use (the canon Table is a DATA table; it wants a createTable instance).
  • _lib/catalog.ts — the single list the section rail and the gallery read.
  • The section's axes (colour mode, language, direction, density) live in the shell (web/routes/blocks/+layout@.svelte), so every demo inherits them.

Block README template (B-9)

# {Name}

## Function

One paragraph: the page function this block performs.

## Composition map

| Part   | Composes         | Key props |
| ------ | ---------------- | --------- |
| `.Nav` | `NavigationMenu` | …         |

**Landmark + headings**: which sectioning element and which heading levels the
block emits, and how the app adjusts them. Required by B-8 and checked by
`blocks:check` — a block with no landmark of its own declares THAT (a bare
`<section>` with no accessible name is not an exposed landmark; the app names
it through `...rest`).

## Decisions

Dated, with the reference comparison (which block catalogs were studied,
what was adopted/discarded).

## Gaps

Every deferred feature with a disposition (canon candidate · future variant
· rejected-with-reason).

Powered by TurnKey Linux.