diff --git a/src/uix/eidos/components/words/langs-inspector.ts b/src/uix/eidos/components/words/langs-inspector.ts index 511f5121b..112621e0d 100644 --- a/src/uix/eidos/components/words/langs-inspector.ts +++ b/src/uix/eidos/components/words/langs-inspector.ts @@ -42,35 +42,24 @@ export const WORDS_INSPECTOR_LANGS = { BLOCK_COLUMNS: '#?components.words.inspector.block.columns|Columns', LABEL_COLUMN_WIDTH: '#?components.words.inspector.label.column-width|Width', LABEL_COLUMN_GAP: '#?components.words.inspector.label.column-gap|Gap', - PLACEHOLDER_COLUMN_GAP: - '#?components.words.inspector.placeholder.column-gap|1rem, 24px, 0', + PLACEHOLDER_COLUMN_GAP: '#?components.words.inspector.placeholder.column-gap|1rem, 24px, 0', LABEL_COLUMN_N: '#?components.words.inspector.label.column-n|Column {n}', - ARIA_ADD_COLUMN_END: - '#?components.words.inspector.aria.add-column-end|Add column at end', - ARIA_REMOVE_COLUMN_N: - '#?components.words.inspector.aria.remove-column-n|Remove column {n}', + ARIA_ADD_COLUMN_END: '#?components.words.inspector.aria.add-column-end|Add column at end', + ARIA_REMOVE_COLUMN_N: '#?components.words.inspector.aria.remove-column-n|Remove column {n}', ARIA_ADD_BLOCK_TO_COLUMN_N: '#?components.words.inspector.aria.add-block-to-column-n|Add block to column {n}', - LABEL_ADD_BLOCK: - '#?components.words.inspector.label.add-block|Add block', - LABEL_COLUMN_BLOCKS: - '#?components.words.inspector.label.column-blocks|Blocks', + LABEL_ADD_BLOCK: '#?components.words.inspector.label.add-block|Add block', + LABEL_COLUMN_BLOCKS: '#?components.words.inspector.label.column-blocks|Blocks', ARIA_SELECT_BLOCK_IN_COLUMN: '#?components.words.inspector.aria.select-block-in-column|Select this block', ARIA_DELETE_BLOCK_IN_COLUMN: '#?components.words.inspector.aria.delete-block-in-column|Delete this block', - ARIA_MOVE_BLOCK_UP: - '#?components.words.inspector.aria.move-block-up|Move block up', - ARIA_MOVE_BLOCK_DOWN: - '#?components.words.inspector.aria.move-block-down|Move block down', - BREADCRUMB_DOCUMENT: - '#?components.words.inspector.breadcrumb.document|Document', - BREADCRUMB_LIST_ITEM: - '#?components.words.inspector.breadcrumb.list-item|Item {n}', - BREADCRUMB_TABLE_ROW: - '#?components.words.inspector.breadcrumb.table-row|Row {n}', - PLACEHOLDER_COLUMN_WIDTH: - '#?components.words.inspector.placeholder.column-width|1fr, 200px, 30%', + ARIA_MOVE_BLOCK_UP: '#?components.words.inspector.aria.move-block-up|Move block up', + ARIA_MOVE_BLOCK_DOWN: '#?components.words.inspector.aria.move-block-down|Move block down', + BREADCRUMB_DOCUMENT: '#?components.words.inspector.breadcrumb.document|Document', + BREADCRUMB_LIST_ITEM: '#?components.words.inspector.breadcrumb.list-item|Item {n}', + BREADCRUMB_TABLE_ROW: '#?components.words.inspector.breadcrumb.table-row|Row {n}', + PLACEHOLDER_COLUMN_WIDTH: '#?components.words.inspector.placeholder.column-width|1fr, 200px, 30%', // Section titles ----------------------------------------------------- SECTION_BLOCK: '#?components.words.inspector.section.block|Block', @@ -90,8 +79,7 @@ export const WORDS_INSPECTOR_LANGS = { LABEL_WIDTH: '#?components.words.inspector.label.width|Width', LABEL_HEIGHT: '#?components.words.inspector.label.height|Height', LABEL_IMAGE_ALIGN: '#?components.words.inspector.label.image-align|Align', - LABEL_IMAGE_FULL_WIDTH: - '#?components.words.inspector.label.image-full-width|Full width', + LABEL_IMAGE_FULL_WIDTH: '#?components.words.inspector.label.image-full-width|Full width', IMAGE_FULL_WIDTH_ON: '#?components.words.inspector.image-full-width.on|On', IMAGE_FULL_WIDTH_OFF: '#?components.words.inspector.image-full-width.off|Off', LABEL_INTENT: '#?components.words.inspector.label.intent|Intent', @@ -108,10 +96,8 @@ export const WORDS_INSPECTOR_LANGS = { VALIGN_TOP: '#?components.words.inspector.valign.top|Top', VALIGN_MIDDLE: '#?components.words.inspector.valign.middle|Middle', VALIGN_BOTTOM: '#?components.words.inspector.valign.bottom|Bottom', - ARIA_CELL_ALIGN: - '#?components.words.inspector.aria.cell-align|Cell horizontal align', - ARIA_CELL_VALIGN: - '#?components.words.inspector.aria.cell-valign|Cell vertical align', + ARIA_CELL_ALIGN: '#?components.words.inspector.aria.cell-align|Cell horizontal align', + ARIA_CELL_VALIGN: '#?components.words.inspector.aria.cell-valign|Cell vertical align', // Callout intent options — labels carry the perceptual reading the // sema doctrine assigns to each value (cap. 12). Used as chip text @@ -143,26 +129,19 @@ export const WORDS_INSPECTOR_LANGS = { '#?components.words.inspector.aria.upload-image|Upload image (encodes inline as data URL)', ARIA_INTENT: '#?components.words.inspector.aria.intent|Callout intent', ARIA_TITLE: '#?components.words.inspector.aria.title|Callout title', - ARIA_ADD_ROW_ABOVE: - '#?components.words.inspector.aria.add-row-above|Insert row above', - ARIA_ADD_ROW_BELOW: - '#?components.words.inspector.aria.add-row-below|Insert row below', + ARIA_ADD_ROW_ABOVE: '#?components.words.inspector.aria.add-row-above|Insert row above', + ARIA_ADD_ROW_BELOW: '#?components.words.inspector.aria.add-row-below|Insert row below', ARIA_REMOVE_ROW: '#?components.words.inspector.aria.remove-row|Delete row', - ARIA_ADD_COLUMN_LEFT: - '#?components.words.inspector.aria.add-column-left|Insert column left', - ARIA_ADD_COLUMN_RIGHT: - '#?components.words.inspector.aria.add-column-right|Insert column right', - ARIA_REMOVE_COLUMN: - '#?components.words.inspector.aria.remove-column|Delete column', + ARIA_ADD_COLUMN_LEFT: '#?components.words.inspector.aria.add-column-left|Insert column left', + ARIA_ADD_COLUMN_RIGHT: '#?components.words.inspector.aria.add-column-right|Insert column right', + ARIA_REMOVE_COLUMN: '#?components.words.inspector.aria.remove-column|Delete column', ARIA_HEADER_ROW: '#?components.words.inspector.aria.header-row|Toggle header row', - ARIA_HEADER_COLUMN: - '#?components.words.inspector.aria.header-column|Toggle header column', + ARIA_HEADER_COLUMN: '#?components.words.inspector.aria.header-column|Toggle header column', PLACEHOLDER_CODE_LANGUAGE: '#?components.words.inspector.placeholder.code-language|e.g. javascript', PLACEHOLDER_SRC: '#?components.words.inspector.placeholder.src|https://...', PLACEHOLDER_ALT: '#?components.words.inspector.placeholder.alt|Describe the image', - PLACEHOLDER_CAPTION: - '#?components.words.inspector.placeholder.caption|Optional caption', + PLACEHOLDER_CAPTION: '#?components.words.inspector.placeholder.caption|Optional caption', PLACEHOLDER_CALLOUT_TITLE: '#?components.words.inspector.placeholder.callout-title|Optional title', @@ -307,6 +286,8 @@ export const WORDS_INSPECTOR_BUNDLE = { 'cell-valign': { en: 'Vertical align', es: 'Alineación vertical' }, 'column-width': { en: 'Width', es: 'Ancho' }, 'column-n': { en: 'Column {n}', es: 'Columna {n}' }, + 'column-blocks': { en: 'Blocks', es: 'Bloques' }, + 'add-block': { en: 'Add block', es: 'Añadir bloque' }, font: { en: 'Font', es: 'Fuente' }, 'font-size': { en: 'Font size', es: 'Tamaño' }, weight: { en: 'Weight', es: 'Grosor' }, @@ -443,4 +424,3 @@ export const WORDS_INSPECTOR_BUNDLE = { es: 'Selecciona un bloque para editar su estilo.' } } as const; - diff --git a/src/uix/morfo/components/words.ts b/src/uix/morfo/components/words.ts index 73c1a6bdb..ae352e4ef 100644 --- a/src/uix/morfo/components/words.ts +++ b/src/uix/morfo/components/words.ts @@ -5,6 +5,13 @@ export const wordsMorfo = { name: 'Words', kebab: 'words', scope: ['soma', 'sema'], + // No bespoke sema pack: the 12 events fire into the engine and take + // their perceptual signature from each family's BASE in SEMA_MAP + // (commits = neutral tap, signal-warn = warning tone). `family-default` + // makes that absence explicit so `morfo:vocabulary` stops flagging it + // as an ambiguous omission. Apps can layer cascade rules at + // `defineEngineSemantic({ overrides: { cascade } })` if they want more. + expression: 'family-default', apg: 'https://www.w3.org/WAI/ARIA/apg/patterns/textbox/', texts: { label: '#?components.words.label|Rich text editor', @@ -247,20 +254,23 @@ export const wordsMorfo = { severity: 'optional' }, { + // Structural node KIND — mirrors `WordsDomNodeKind` in the + // engine (`soma/.../engine/dom.ts`). This is NOT the block + // TYPE (paragraph / heading / image / …) — that lives on + // `data-words-block` below. Top-level blocks carry + // `node='block'`; the container kinds (list / table / …) and + // the leaf inlines (link / text) carry their own kind. attr: 'data-words-node', values: [ - 'text', + 'block', + 'inline', 'list', 'list-item', 'table', 'table-row', 'table-cell', 'link', - 'paragraph', - 'heading', - 'quote', - 'code', - 'image' + 'text' ], severity: 'optional' }, diff --git a/src/uix/soma/components/words/engine/operations/visual.ts b/src/uix/soma/components/words/engine/operations/visual.ts index 52954eabd..f9bb52b52 100644 --- a/src/uix/soma/components/words/engine/operations/visual.ts +++ b/src/uix/soma/components/words/engine/operations/visual.ts @@ -143,10 +143,15 @@ export function updateBlockAtPath( safePatch[k] = v; } - const nextDoc = updateNodeAtPath(state.document, blockPath, (node) => ({ - ...(node as Record), - ...safePatch - }) as unknown as WordsBlock); + const nextDoc = updateNodeAtPath( + state.document, + blockPath, + (node) => + ({ + ...(node as unknown as Record), + ...safePatch + }) as unknown as WordsBlock + ); if (nextDoc === state.document) return noOp(state); const normalized = normalizeDocument(nextDoc).document; return changed({ ...state, document: normalized });