From 925508c7647d9e45d2c744443fc53a598b5bcc01 Mon Sep 17 00:00:00 2001 From: dev Date: Thu, 2 Jul 2026 15:48:47 +0200 Subject: [PATCH] docs(reconciliation): translations: -> texts: swept across morfo/soma docs Phase 1a of PLAN-docs-reconciliation (fable_audit D1). The Morfo field is texts (idlangrefs); the multilingual catalog lives in langs/components/*. Fixed every example and mechanism claim that still documented the removed translations: field: morfo/README (contains-list, anatomy, Step 4.5), SOMA_ARCHITECTURE (Texto funcional + checklist), soma/README (morfo field list + runtime registration), COMPONENT_GUIDE (A1/A3 + common mistakes + smoke fixes), COMPONENT_COMPLETION_CHECKLIST M-1.3, active-uix/README, uix/README, 4 component READMEs, and 3 stale JSDoc blocks in code (morfo/types.ts, morfo/schema.ts invariant 7, active-uix/types.ts registerDefaultLangs). Co-Authored-By: Claude Fable 5 --- src/uix/COMPONENT_COMPLETION_CHECKLIST.md | 2 +- src/uix/README.md | 6 ++-- src/uix/active-uix/README.md | 5 +-- src/uix/active-uix/types.ts | 6 ++-- src/uix/morfo/README.md | 28 +++++++-------- src/uix/morfo/schema.ts | 6 +++- src/uix/morfo/types.ts | 4 ++- src/uix/soma/COMPONENT_GUIDE.md | 35 ++++++++++--------- src/uix/soma/README.md | 10 +++--- src/uix/soma/SOMA_ARCHITECTURE.md | 21 ++++++----- .../soma/components/alert-dialog/README.md | 2 +- src/uix/soma/components/drag-drop/README.md | 2 +- src/uix/soma/components/pin-input/README.md | 2 +- .../components/time-range-picker/README.md | 2 +- 14 files changed, 70 insertions(+), 61 deletions(-) diff --git a/src/uix/COMPONENT_COMPLETION_CHECKLIST.md b/src/uix/COMPONENT_COMPLETION_CHECKLIST.md index 9af330f4e..664871124 100644 --- a/src/uix/COMPONENT_COMPLETION_CHECKLIST.md +++ b/src/uix/COMPONENT_COMPLETION_CHECKLIST.md @@ -39,7 +39,7 @@ The morfo is DNA. If it's incomplete, every downstream layer is incomplete. | ----- | ---------------------------------------------------------------------------------------------------------------------------------------------------------- | -------- | ------------- | | M-1.1 | Exports a single `{Name}Morfo` const satisfying `Morfo` | error | all | | M-1.2 | Has `name`, `kebab`, `scope: ['soma', ...]` declared | error | all | -| M-1.3 | Has `translations.label` with at least `es` + `en` | error | all | +| M-1.3 | Has `texts.label` as a valid idlangref (`#?components.{kebab}.label\|Fallback`), catalog entry in `langs/components/{kebab}.ts` | error | all | | M-1.4 | If interactive: `apg` URL declared pointing at the relevant W3C ARIA pattern | warn | interactive | ### A2 · Parts diff --git a/src/uix/README.md b/src/uix/README.md index 95dacda5f..f2772bb83 100644 --- a/src/uix/README.md +++ b/src/uix/README.md @@ -59,9 +59,9 @@ UIX pone nombres y contratos explícitos a esas separaciones. ### `Morfo` (`src/uix/morfo/`) Contrato estructural cross-layer del componente. Define `parts`, `data-*`, -ARIA, foco, teclado, eventos y, cuando el texto pertenece al contrato, -`translations` del componente. No es prose ni runtime — es la forma canónica -pública. +ARIA, foco, teclado, eventos y, cuando el texto pertenece al contrato, los +slots `texts` del componente (idlangrefs). No es prose ni runtime — es la +forma canónica pública. Ver: [morfo/README.md](./morfo/README.md) diff --git a/src/uix/active-uix/README.md b/src/uix/active-uix/README.md index 125fcbb92..b0e443370 100644 --- a/src/uix/active-uix/README.md +++ b/src/uix/active-uix/README.md @@ -21,7 +21,8 @@ directamente. `events` según opciones; - conserva `portal` como target genérico de portales, para que cada capa lo adapte a su API (`portalTo`) sin acoplar `active-uix` a esa capa; -- registra las traducciones comunes y las `morfo.translations`. +- registra las traducciones comunes y los catálogos por componente de + `src/uix/langs/components/*`. `attachActiveUix(app, options)` — **attach** a un `ActiveApp` externo: @@ -30,7 +31,7 @@ directamente. - **exige** `app.langs` y `app.dom`; si faltan, lanza error de configuración; - no vuelve a suscribir `langs` a `prefs.language` (esa conexión pertenece a `defineActiveLangs` dentro de `ActiveApp`); -- registra las traducciones comunes y las `morfo.translations`; +- registra las traducciones comunes y los catálogos por componente; - no posee el lifecycle del `app`. ## Contratos mínimos por módulo diff --git a/src/uix/active-uix/types.ts b/src/uix/active-uix/types.ts index dce791bb8..627c2107c 100644 --- a/src/uix/active-uix/types.ts +++ b/src/uix/active-uix/types.ts @@ -68,9 +68,9 @@ export interface ActiveUixOptions { readonly logger?: LoggerOptions; /** - * If `true` (default), UIX common defaults are merged and - * `ActiveUix` connects the morfo registry to - * `ActiveLangs` so `morfo.translations` registered later become available. + * If `true` (default), UIX common defaults are merged and `ActiveUix` + * registers the per-component catalogs (`src/uix/langs/components/*`) + * under `components.{kebab}.*`. */ readonly registerDefaultLangs?: boolean; diff --git a/src/uix/morfo/README.md b/src/uix/morfo/README.md index 80ede3360..9e88f32c6 100644 --- a/src/uix/morfo/README.md +++ b/src/uix/morfo/README.md @@ -4,7 +4,7 @@ Morfo is the single source of truth for a component's parts, data-attrs, ARIA contract, keyboard shortcuts, focus policy, and public event contract. The same morfo is consumed by soma (to wire the headless provider), by eidos (to generate CSS selectors), by sema (to bind perceptual channels), and by the docs site (to render part tables). -**One file per component**, at `src/uix/morfo/components/{kebab}.ts`. No prose — that's the component's README. No props — those live in `types.ts` with JSDoc. Component-owned translations may live in `translations` when they are part of ARIA labels, live-region text, or internal functional labels. Everything else is the machine-readable contract. +**One file per component**, at `src/uix/morfo/components/{kebab}.ts`. No prose — that's the component's README. No props — those live in `types.ts` with JSDoc. Component-owned text slots may live in `texts` (idlangrefs) when they are part of ARIA labels, live-region text, or internal functional labels — the multilingual catalog itself lives in `src/uix/langs/components/{kebab}.ts`. Everything else is the machine-readable contract. ## Why morfo exists @@ -34,7 +34,7 @@ A `Morfo` is a plain TypeScript constant that describes: - **`apg`** — optional URL to the WAI-ARIA APG pattern when the component implements a formal one. - **`focus`** — optional focus policy for overlays / composites. - **`events`** — the component's public event surface: which semantic occurrences it may emit and expose to cross-layer consumers. -- **`translations`** — optional component-owned translation catalog. Registered under `components.{kebab}` by the morfo registry. +- **`texts`** — optional component-owned text slots, declared as idlangrefs (`'#?components.{kebab}.{key}|Fallback'`). The multilingual catalog itself lives in `src/uix/langs/components/{kebab}.ts` and is registered by `ActiveUix` under `components.{kebab}.*`. - **`parts`** — the part tree (recursive). Each part declares: - `name`, `kebab`, `kind` (`public` / `virtual`). - `archetype` — optional cross-component classification (see "Archetypes" below). @@ -57,7 +57,7 @@ See [`types.ts`](./types.ts) for the full TypeScript shape. | Usage examples | `{component}/README.md` | Narrative | | Props (names, types, defaults) | `{component}/types.ts` with JSDoc | Canonical source is TS + JSDoc | | Shared/common translations | app/langs catalog under `common.*` | Shared vocabulary should not be duplicated per component | -| Provider-only id constants | optional `{component}/langs.ts` | Constants are code ergonomics; the catalog lives in morfo or app langs | +| Provider-only id constants | optional `{component}/langs.ts` | Constants are code ergonomics; the catalog lives in `langs/components/{kebab}.ts` or app langs | | Event handlers / runtime wiring, state machines | `{component}-provider.svelte.ts` | Execution logic, not contract data | | Visual variants / recipes | `src/uix/eidos/` (future) | Layer-specific, not shared | @@ -278,10 +278,8 @@ export const dialogMorfo = { restore: true }, - translations: { - content: { - roledescription: { es: 'ventana de dialogo', en: 'dialog window' } - } + texts: { + 'content.roledescription': '#?components.dialog.content.roledescription|dialog window' }, parts: [ @@ -474,21 +472,21 @@ condition: { when: 'prop-truthy', prop: 'modal' } condition: { when: 'prop-falsy', prop: 'disabled' } ``` -### Step 4.5 — Declare component-owned `translations` +### Step 4.5 — Declare component-owned `texts` -If a translation belongs to the component contract, put the catalog on the -morfo: +If a text slot belongs to the component contract, declare it on the morfo as +an idlangref. The morfo never embeds the literal multilingual record — that +lives in `src/uix/langs/components/{kebab}.ts` and is merged into the active +catalog by `ActiveUix`: ```ts export const dialogMorfo = { name: 'Dialog', kebab: 'dialog', // ... - translations: { - trigger: { es: 'Abrir dialogo', en: 'Open dialog' }, - content: { - roledescription: { es: 'ventana de dialogo', en: 'dialog window' } - } + texts: { + trigger: '#?components.dialog.trigger|Open dialog', + 'content.roledescription': '#?components.dialog.content.roledescription|dialog window' }, parts: [ { diff --git a/src/uix/morfo/schema.ts b/src/uix/morfo/schema.ts index 2988e13e2..e3b9de688 100644 --- a/src/uix/morfo/schema.ts +++ b/src/uix/morfo/schema.ts @@ -76,6 +76,8 @@ const elementSchema = union( literal('aside'), literal('footer'), literal('img'), + literal('video'), + literal('audio'), literal('svg'), literal('path'), literal('g'), @@ -451,7 +453,9 @@ function validateDataAttrName( * 4. Every `state-equals` condition's `state` exists somewhere in the part. * 5. `focus.initial.partRef` / `focus.return.partRef` resolve to a part. * 6. Root `scope` non-empty. - * 7. Component-relative `translationRef` keys resolve inside `morfo.translations`. + * 7. Component-relative `translationRef` keys normalize to + * `#?components.{kebab}.{key}`; catalog presence is checked by + * `scripts/translations-check.ts`, not here. * 8. Morfo `kebab` is valid kebab-case (a-z0-9-). * * Not validated here (requires external sources): diff --git a/src/uix/morfo/types.ts b/src/uix/morfo/types.ts index 47c2e0d56..5296c9b70 100644 --- a/src/uix/morfo/types.ts +++ b/src/uix/morfo/types.ts @@ -75,6 +75,8 @@ export type MorfoElement = | 'aside' | 'footer' | 'img' + | 'video' + | 'audio' | 'svg' | 'path' | 'g' @@ -788,7 +790,7 @@ export type SemaExpressionMode = 'pack' | 'family-default' | 'delegated' | 'none * Minimal by design. Editorial content (summary, comparison table, * when-to-use prose) lives in the component's README, not here. * Props live in the component's `types.ts` with JSDoc. Component-owned - * translations live in `translations`. + * text slots live in `texts`. */ export interface Morfo { /** Component display name, PascalCase. */ diff --git a/src/uix/soma/COMPONENT_GUIDE.md b/src/uix/soma/COMPONENT_GUIDE.md index 13dec6abe..b004c664b 100644 --- a/src/uix/soma/COMPONENT_GUIDE.md +++ b/src/uix/soma/COMPONENT_GUIDE.md @@ -420,7 +420,7 @@ Pattern: `soma-{component}-{part}-{uid}`. Always descriptive. [ ] 4. Create {name}-provider.svelte.ts with concrete provider/state classes [ ] 5. Use `soma.runtime()` inside providers (or `createSomaRuntime()` in tests/tools) so `registerMorfo()` runs — A1 [ ] 6. Create types.ts with JSDoc on ALL props + canonical field shapes -[ ] 7. Add `morfo.translations` for component-owned text; create langs.ts only for imperative constants — A3 +[ ] 7. Add `morfo.texts` for component-owned text (catalog in `langs/components/{kebab}.ts`); create langs.ts only for imperative constants — A3 [ ] 8. Create wrapper .svelte files (thin: props → Active → Provider → mergeProps → render — A11) [ ] 9. Verify: event handlers included in props (not just class methods) [ ] 10. Verify: context captured in constructor, not in handlers @@ -555,7 +555,7 @@ Pattern: `soma-{component}-{part}-{uid}`. Always descriptive. (or `common.*` for shared strings). Any `langs.t('soma.…')` / `langs.ts('soma.…')` is a bug and will log `Translation key not found` at runtime. Component-owned paths should come from - `morfo.translations` + `v.translationRef`; shared paths should use + `morfo.texts` + `v.translationRef`; shared paths should use `v.commonRef` or an explicit idlangref constant (A3). [ ] 38. **DOM topology vs `.require()` audit.** For every `X.require()` @@ -595,7 +595,7 @@ Pattern: `soma-{component}-{part}-{uid}`. Always descriptive. 8. **Redeclaring field types** — defining prop types in both `types.ts` and the provider Opts interface. Define canonical shapes once in `types.ts`, reference with `StateProps<>` / `ActiveProps<>`. -9. **Hardcoding aria strings** — declare component-owned text in `morfo.translations` and reference it with `v.translationRef`; use `v.commonRef` / idlangref constants for shared imperative labels. Never inline strings in providers. +9. **Hardcoding aria strings** — declare component-owned text slots in `morfo.texts` and reference them with `v.translationRef`; use `v.commonRef` / idlangref constants for shared imperative labels. Never inline strings in providers. 10. **Gesture capturing child clicks** — `setPointerCapture` must be deferred until moveBuffer is exceeded. Immediate capture on pointerdown steals click events from buttons inside the draggable area. @@ -611,8 +611,8 @@ These rules were extracted from a full audit of all 25 soma components. Every is ### A1. Register the morfo through the runtime -Every component MUST register its morfo before it relies on `assertContract` -or morfo-owned translations. The canonical path is to create a runtime: +Every component MUST register its morfo before it relies on `assertContract`. +The canonical path is to create a runtime: ```ts const runtime = this.soma.runtime({name}Morfo, { states, props, parts, events }); @@ -631,11 +631,11 @@ const runtime = createSomaRuntime({name}Morfo, { }); ``` -Both paths call `registerMorfo(morfo)` internally. That compiles the morfo, -registers its `data-*` contract and publishes `morfo.translations` to connected -`ActiveLangs` instances. Only call `registerMorfo(morfo)` manually for a -legacy provider or tool that needs the registry side effect without creating -a runtime. +Both paths call `registerMorfo(morfo)` internally. That compiles the morfo +and registers its `data-*` contract (component text catalogs are registered +separately by `ActiveUix` from `src/uix/langs/components/*`). Only call +`registerMorfo(morfo)` manually for a legacy provider or tool that needs the +registry side effect without creating a runtime. ### A2. Root part must use 'provider', not 'root' @@ -665,14 +665,15 @@ this.runtimePart = this.runtime.part('provider', { **Soma access:** Declare `readonly soma = Soma.get()` in the root provider when the component needs prefs-derived services or imperative translations. Sub-parts access soma via `this.provider.soma`. -**Translations:** Component-owned text lives in the morfo, not in a per-component catalog file: +**Texts:** The morfo declares component-owned text slots as idlangrefs; the +multilingual catalog lives in `src/uix/langs/components/{kebab}.ts`: ```ts export const drawerMorfo = { name: 'Drawer', kebab: 'drawer', - translations: { - trigger: { es: 'Abrir cajon', en: 'Open drawer' } + texts: { + trigger: '#?components.drawer.trigger|Open drawer' }, parts: [ { @@ -716,15 +717,15 @@ components.dialog.trigger - Common keys live under `common.*` at the lang root — not under soma - Component keys live under `components.{name}.*` - `ActiveUix` registers `commonLangs` defaults without overwriting user-provided leaves -- `ActiveUix` registers `morfo.translations` dynamically when `registerMorfo(morfo)` runs through the runtime -- There is no global per-component catalog. Component-owned strings live in `morfo.translations`; shared strings live in `common.*`. +- `ActiveUix` registers the per-component catalogs from `src/uix/langs/components/*` under `components.{kebab}.*` +- The morfo only declares slots (`morfo.texts`, idlangrefs); the multilingual records live in `langs/components/{kebab}.ts`. Shared strings live in `common.*`. - `langs.ts()` with idlangref for simple strings. `langs.t()` only for interpolated templates (e.g., `Page {{value}}`) Do NOT: - Create `translate()` helper methods in providers - Use `?? 'fallback'` — the fallback belongs inside the langref (`#?path|fallback`) -- Hardcode aria strings — use `morfo.translations` + `v.translationRef`, `v.commonRef`, or an explicit idlangref constant +- Hardcode aria strings — use `morfo.texts` + `v.translationRef`, `v.commonRef`, or an explicit idlangref constant - Put common keys (close, open, cancel) under component namespaces — they belong in `common.*` **Imports within soma:** Use relative paths, not `$soma/` aliases. Relative paths make the library portable without requiring alias configuration in the consumer's build. soma does not import from `$lib` — trivial utilities (like empty callbacks) are inline (`() => {}`). @@ -1234,7 +1235,7 @@ Three classes of bug cannot be caught by `svelte-check` or HTTP 200 — they all grep -rn "['\"]soma\.[a-z-]" src --include=!*.md ``` - Fixes: route component-owned text through `morfo.translations` + `v.translationRef`; route shared text through `v.commonRef` or an explicit idlangref constant. Don't build translation paths via template strings in demos or providers. If a demo needs a dynamic path helper (like `tt('columns', 'Columns')`), hard-code the namespace prefix `components.{name}.` correctly. + Fixes: route component-owned text through `morfo.texts` + `v.translationRef`; route shared text through `v.commonRef` or an explicit idlangref constant. Don't build translation paths via template strings in demos or providers. If a demo needs a dynamic path helper (like `tt('columns', 'Columns')`), hard-code the namespace prefix `components.{name}.` correctly. 2. **DOM topology vs `.require()` audit.** Svelte's context (via `getContext`) flows only to descendants. Every `X.require()` call must be reachable from a descendant of the component that set the context. The trap is HTML: `` cannot nest ``, so `Table.RowDetail` (rendered as a sibling `` of `Table.Row`) cannot `TableRowProvider.require()`. Use one of: - Receive the object via a prop (consumer passes `{row}` or similar explicitly). This is consistent with `` / `` — Table already requires explicit objects. diff --git a/src/uix/soma/README.md b/src/uix/soma/README.md index 2a3e5d157..cd3cf2492 100644 --- a/src/uix/soma/README.md +++ b/src/uix/soma/README.md @@ -129,7 +129,7 @@ Cada componente tiene un archivo en `src/uix/morfo/components/{kebab}.ts` que de - **aria** — qué atributos ARIA emite cada parte, con la fuente del valor tipada vía tagged union (`v.literal`, `v.stateRef`, `v.partRef`, `v.propRef`, `v.translationRef`) y condición de emisión opcional. - **keyboard** — los atajos de teclado relevantes por parte. - **focus** — política de foco para overlays (`initial`, `trap`, `return`, `restore`). -- **translations** — catálogo de traducciones propio del componente, registrado bajo `components.{kebab}`. +- **texts** — slots de texto propios del componente, declarados como idlangrefs (`'#?components.{kebab}.{key}|Fallback'`). El catálogo multilingüe vive en `src/uix/langs/components/{kebab}.ts`. - **apg** — URL al patrón WAI-ARIA APG cuando aplica. - **scope** — las capas que implementan el componente: `['soma']`, `['soma', 'eidos']`, etc. @@ -140,9 +140,9 @@ vive en [`src/uix/morfo/README.md`](../morfo/README.md). ### Cómo soma consume un morfo -Cada provider raíz crea un runtime con su morfo. Ese paso registra el contrato -`data-*`, compila la declaración y publica `morfo.translations` en los `ActiveLangs` -conectados por `ActiveUix`: +Cada provider raíz crea un runtime con su morfo. Ese paso compila la +declaración y registra el contrato `data-*` (los catálogos de texto por +componente los registra `ActiveUix` desde `src/uix/langs/components/*`): ```ts import { dialogMorfo } from '../../../morfo/components/dialog'; @@ -353,7 +353,7 @@ sema → perception/events: hold, sound, haptic Eidos consume Soma vía los `data-*` públicos y los subpaths públicos (`import { Accordion } from '$soma/components/accordion'`); responde a estados (`[data-accordion][data-state='open'] { ... }`), añade props visuales (`size`, -`variant`, `color`) y reutiliza las translations. Nunca importa Provider classes +`variant`, `color`) y reutiliza los catálogos de texto. Nunca importa Provider classes internas, no depende de estructura DOM incidental ni duplica behavior que soma ya resuelve. diff --git a/src/uix/soma/SOMA_ARCHITECTURE.md b/src/uix/soma/SOMA_ARCHITECTURE.md index 3a5892b3f..21cfbf66d 100644 --- a/src/uix/soma/SOMA_ARCHITECTURE.md +++ b/src/uix/soma/SOMA_ARCHITECTURE.md @@ -145,7 +145,7 @@ del componente (checklist item 27). soma resuelve ARIA por defecto. El consumidor no necesita añadir `role`, `aria-modal`, `aria-expanded`, `aria-controls`, etc. — el Provider los genera. -Texto funcional se resuelve via `langs.ts()` con idlangref. El catalogo propio del componente vive en `morfo.translations` y se referencia con `v.translationRef(...)`; texto compartido como close/cancel/save vive en `common.*` y se referencia con `v.commonRef(...)` o un idlangref absoluto. `langs.ts` por componente queda como comodidad opcional para constantes imperativas, no como catalogo canonico. +Texto funcional se resuelve via `langs.ts()` con idlangref. El morfo declara sus slots de texto en `morfo.texts` (idlangrefs) y los referencia con `v.translationRef(...)`; el catalogo multilingue vive en `src/uix/langs/components/{kebab}.ts`. Texto compartido como close/cancel/save vive en `common.*` y se referencia con `v.commonRef(...)` o un idlangref absoluto. `langs.ts` por componente queda como comodidad opcional para constantes imperativas, no como catalogo canonico. ### 3.7 DOM global via ActiveDom @@ -685,14 +685,16 @@ standalone functions. No `from()`. No `ctx` exposed. ### Texto funcional -Las traducciones propias del componente se declaran en el morfo: +Los slots de texto propios del componente se declaran en el morfo como +idlangrefs (el catalogo multilingue vive en +`src/uix/langs/components/{kebab}.ts`): ```ts export const drawerMorfo = { name: 'Drawer', kebab: 'drawer', - translations: { - trigger: { es: 'Abrir cajon', en: 'Open drawer' } + texts: { + trigger: '#?components.drawer.trigger|Open drawer' }, parts: [ { @@ -710,10 +712,11 @@ Las traducciones compartidas no se duplican por componente: value: v.commonRef('buttons.close', 'Close'); // #?common.buttons.close|Close ``` -`ActiveUix` conecta el registro de morfos con `ActiveLangs`. Cuando el -provider crea `createSomaRuntime(morfo, sources)` o `soma.runtime(morfo, -sources)`, `registerMorfo(morfo)` registra el contrato `data-*` y publica -`morfo.translations` bajo `components.{kebab}`. +`ActiveUix` registra los catalogos de `src/uix/langs/components/*` en +`ActiveLangs` bajo `components.{kebab}.*`. Cuando el provider crea +`createSomaRuntime(morfo, sources)` o `soma.runtime(morfo, sources)`, +`registerMorfo(morfo)` compila y registra el contrato `data-*`; el morfo +solo declara sus slots (`morfo.texts`), no el catalogo. `commonLangs` en `src/uix/langs.ts` aporta los defaults de `common.*`. `ActiveUix` los registra sin pisar hojas existentes, de modo que el @@ -1028,7 +1031,7 @@ See `COMPONENT_GUIDE.md` for the full step-by-step process (27 general steps + 4 ``` [ ] 1. Compare with ark-ui, bits-ui, radix-ui — feature table [ ] 2. Verify membership criteria -[ ] 3. Define parts + attrs + morfo.translations when the component owns text +[ ] 3. Define parts + attrs + morfo.texts when the component owns text [ ] 4. Create types.ts (props + canonical field shapes) [ ] 5. Create langs.ts only for imperative idlangref constants, not as the catalog [ ] 6. Create {name}-provider.svelte.ts (concrete state classes, no Provider inheritance) diff --git a/src/uix/soma/components/alert-dialog/README.md b/src/uix/soma/components/alert-dialog/README.md index 59a968bf5..1d4d5b97e 100644 --- a/src/uix/soma/components/alert-dialog/README.md +++ b/src/uix/soma/components/alert-dialog/README.md @@ -117,7 +117,7 @@ Focus lands on the first focusable child when the dialog opens (`Cancel` by DOM ## i18n -Default button labels resolve through the UIX lang system. The component catalog is owned by `morfo.translations` under `components.alert-dialog`. +Default button labels resolve through the UIX lang system. The morfo declares the slots in `texts`; the catalog lives in `src/uix/langs/components/alert-dialog.ts` under `components.alert-dialog`. | Key | English | Spanish | | -------- | --------- | ----------- | diff --git a/src/uix/soma/components/drag-drop/README.md b/src/uix/soma/components/drag-drop/README.md index 2448a2fc5..2efc92b80 100644 --- a/src/uix/soma/components/drag-drop/README.md +++ b/src/uix/soma/components/drag-drop/README.md @@ -84,7 +84,7 @@ Snippet props: `{ over, accepting }`. | Droppable | `aria-dropeffect` | `'move'` while accepting, `'none'` otherwise | | Droppable | `tabindex` | `0` during drag if accepting; `-1` otherwise | -Each drag step is announced via the `Announce` global API. Component-owned announcement strings live in the drag-drop `morfo.translations` catalog. Disable with `announceEnabled={false}` on the Provider when wiring your own. +Each drag step is announced via the `Announce` global API. Component-owned announcement slots are declared in the drag-drop `morfo.texts`; the catalog lives in `src/uix/langs/components/drag-drop.ts`. Disable with `announceEnabled={false}` on the Provider when wiring your own. ## Data Attributes diff --git a/src/uix/soma/components/pin-input/README.md b/src/uix/soma/components/pin-input/README.md index aa1cb3755..03e62d909 100644 --- a/src/uix/soma/components/pin-input/README.md +++ b/src/uix/soma/components/pin-input/README.md @@ -132,7 +132,7 @@ All keyboard semantics come from the underlying `` — soma does not re-i ## i18n -Default strings live under `components.pin-input`. The canonical catalog is the pin-input morfo `translations`: +Default strings live under `components.pin-input`. The morfo declares the slots in `texts`; the catalog is `src/uix/langs/components/pin-input.ts`: | Key | English | Spanish | | ------- | -------------------------------- | -------------------------------- | diff --git a/src/uix/soma/components/time-range-picker/README.md b/src/uix/soma/components/time-range-picker/README.md index ab5fe2c4e..d21f12541 100644 --- a/src/uix/soma/components/time-range-picker/README.md +++ b/src/uix/soma/components/time-range-picker/README.md @@ -71,7 +71,7 @@ The per-endpoint slider / toggle wrappers read their endpoint from the required ## ARIA -- Sliders emit `role="slider"` with per-endpoint `aria-label` resolved through UIX lang refs (`morfo.translations` for component-owned labels, `langs.ts` only for legacy imperative constants). +- Sliders emit `role="slider"` with per-endpoint `aria-label` resolved through UIX lang refs (`morfo.texts` for component-owned labels, `langs.ts` only for legacy imperative constants). - `DayPeriodToggle` emits `role="radiogroup"` with two `` items. - Input / Segment inherit TimeRangeField / TimeField ARIA.