|
|
---
|
|
|
title: Building a Component — the one door
|
|
|
type: guide
|
|
|
audience: human + agent
|
|
|
authority: navigational — THE entry point for building a new component; content lives in the linked docs
|
|
|
status: current
|
|
|
related:
|
|
|
acceptance: src/uix/COMPONENT_COMPLETION_CHECKLIST.md (when is it done — machine-audited)
|
|
|
soma: src/uix/soma/COMPONENT_GUIDE.md (the deepest phase doc)
|
|
|
---
|
|
|
|
|
|
# Building a Component — the one door
|
|
|
|
|
|
Read **this file first and only this file**. Building a component crosses the four
|
|
|
layers and the theming system; the knowledge lives in eight documents that each own
|
|
|
one phase. Nobody should have to discover that chain by archaeology — this doc IS
|
|
|
the chain. Each phase names **the one document to read**, what you produce, and the
|
|
|
guard that verifies it.
|
|
|
|
|
|
Role note (authoring rule 4 — one source per concern): this doc contains **no
|
|
|
content**, only sequencing. If a phase doc and this table disagree about order,
|
|
|
this doc wins on *order*; the phase doc wins on *content*.
|
|
|
|
|
|
---
|
|
|
|
|
|
## The route
|
|
|
|
|
|
| Phase | You produce | Read THIS | Verified by |
|
|
|
| --- | --- | --- | --- |
|
|
|
| **0 · Decide** | comparison table vs ark/bits/radix (+ react-aria), membership call (soma or eidos-native), compose-first check | [`soma/COMPONENT_GUIDE.md`](../src/uix/soma/COMPONENT_GUIDE.md) §Before You Start (1–4) · membership: [`soma/README.md`](../src/uix/soma/README.md) §2 | reviewer — the table goes in the component README (phase 7) |
|
|
|
| **1 · Morfo** | `src/uix/morfo/components/{kebab}.ts` — parts, data/aria, keyboard, events (family/verb/intent/sequence), `texts`, `expression` | [`morfo/README.md`](../src/uix/morfo/README.md) §Authoring a new morfo · vocabulary: [`CANON.md`](./CANON.md) | `validateMorfo` + `npm run morfo:vocabulary` + audit `A-*` |
|
|
|
| **2 · Soma** | `{kebab}-provider.svelte.ts` + thin wrappers + `types.ts` + provider test | [`soma/COMPONENT_GUIDE.md`](../src/uix/soma/COMPONENT_GUIDE.md) (patterns + rules A1–A37) | provider test + `npm run check` |
|
|
|
| **3 · Sema** | pack `src/uix/sema/components/{kebab}.ts` (or explicit `expression: 'family-default'`) — selectors via `semaSelector` ONLY | [`sema/README.md`](../src/uix/sema/README.md) §packs + §typed builder · pack-vs-default criteria: [`LIBRO_VARIACIONES`](../src/docs/LIBRO_VARIACIONES_Y_EXTENSIONES.md) D.4 | `npm run morfo:vocabulary` (expression coverage) |
|
|
|
| **4 · Eidos wrapper** | `eidos/components/{kebab}/` — root + attached parts (option C), visual props | [`eidos/components/README.md`](../src/uix/eidos/components/README.md) (the 7 hard rules) | `component-api-contract` test + audit `E-*` |
|
|
|
| **5 · Recipe + theming** | recipe tokens in `lib/recipes/base.ts` + `{kebab}.css` | [`eidos/THEMING_GUIDE.md`](../src/uix/eidos/THEMING_GUIDE.md) pasos 1–6 · **mandatory contract**: [`eidos/RECIPE_CONTRACT.md`](../src/uix/eidos/RECIPE_CONTRACT.md) · scope (if `data-color`): [`eidos/TSC.md`](../src/uix/eidos/TSC.md) | `npm run generate:eidos-css` + `recipe-css-contract` test + audit `R-*` (R-4.x = the contract) |
|
|
|
| **6 · Demo** | `web/routes/uix/components/{kebab}/+page.svelte` — v2 9-tab layout | [`DEMO_AUTHORING_GUIDE.md`](../web/routes/uix/lib/DEMO_AUTHORING_GUIDE.md) | audit `D-*` + `npm run smoke` |
|
|
|
| **7 · Component README** | Baseline · Comparativa (≥3 refs) · Decisiones · Gaps-with-disposition · Sema events table | template = any recent PASS component's README; sections audited | audit `F-*` |
|
|
|
| **8 · Acceptance** | nothing new — the component passes | [`COMPONENT_COMPLETION_CHECKLIST.md`](../src/uix/COMPONENT_COMPLETION_CHECKLIST.md) | `npm run component:audit --only {kebab}` + `npm run morfo:check` + `eidos-lint` |
|
|
|
|
|
|
Cross-phase invariants you will hit in every phase: the layer boundaries
|
|
|
([`active_architecture.md`](../src/uix/active_architecture.md) §7 hard rules) and the
|
|
|
2-of-3 rule for extending morfo ([`morfo/README.md`](../src/uix/morfo/README.md)).
|
|
|
|
|
|
---
|
|
|
|
|
|
## Known traps — sections that LOOK authoritative but are superseded
|
|
|
|
|
|
The corpus still carries superseded material inline. Until the cleanup pass lands,
|
|
|
do **not** follow these:
|
|
|
|
|
|
| If you read… | The truth is… |
|
|
|
| --- | --- |
|
|
|
| `translations:` field in morfo examples (morfo/README, SOMA_ARCHITECTURE §7) | The field is **`texts:`** (idlangrefs). `translations:` does not compile — audit rule A-1.3 flags it. |
|
|
|
| THEMING.md §13 (`event:*` TSC scope) + §14's `data-motion-ref` | Superseded — the motion model is [`eidos-motion.md`](../src/uix/eidos/eidos-motion.md) (two moments, signatures in `EidosConfig.motion`). |
|
|
|
| GUIA_IMPLEMENTACION §5.3 (`defaultSemantic`) | The implemented shape is additive `allowedFamilies` ([`LIBRO_VARIACIONES`](../src/docs/LIBRO_VARIACIONES_Y_EXTENSIONES.md) D.11). |
|
|
|
| GUIA_IMPLEMENTACION §6.2 holds table / §4.1 dialog=shift | Code + [`CANON.md`](./CANON.md) win: holds live in `SEMA_MAP` / `holds.ts`; Dialog's events are `emerge` in its morfo. |
|
|
|
| soma/README §3 deps (`@floating-ui`, `clsx`) | Positioning is the in-house engine (`soma/layers/floating` + `$ethereal`); those deps are gone/dev-only. |
|
|
|
| A 6-tab demo `type Tab` union in older demos | The canonical layout is the v2 **9-tab** union (DEMO_AUTHORING_GUIDE); v1 is accepted only pending migration. |
|
|
|
| "24 archetypes" (active_architecture §6, morfo/README) | `ARCHETYPE_VOCABULARY` in `morfo/types.ts` is the source (26 today — the const wins over any count in prose). |
|
|
|
|
|
|
Golden rule when a doc contradicts code: **code + CANON.md win** — and open an
|
|
|
issue/fix for the doc (THEMING.md's own footer says the same).
|