From f815dd95ac993cb07a91d5f1e5b8a02dc237af78 Mon Sep 17 00:00:00 2001 From: dev Date: Sat, 16 May 2026 20:02:36 +0200 Subject: [PATCH] Guard Eidos visual attr wiring --- continue.md | 9 +++ src/uix/eidos/component-visual-attrs.test.ts | 62 ++++++++++++++++++++ src/uix/eidos/components/README.md | 6 ++ 3 files changed, 77 insertions(+) create mode 100644 src/uix/eidos/component-visual-attrs.test.ts diff --git a/continue.md b/continue.md index d6ece870e..e6c9e50f9 100644 --- a/continue.md +++ b/continue.md @@ -215,6 +215,15 @@ Actualizacion smoke 2026-05-16: `/test/soma`; no usarlos como release gate hasta reconectarlos a una route map real del docs shell actual. +Actualizacion Eidos visual wrappers 2026-05-16: + +- Nueva guardia `src/uix/eidos/component-visual-attrs.test.ts`: + asegura que los wrappers Eidos que publican props visuales sigan estampando + los `data-*` que consumen las recipes (`data-size`, `data-variant`, + `data-color`, `data-position`, `data-columns`, `data-motion`, etc.). +- Documentado en `src/uix/eidos/components/README.md` que esta guardia protege + el cableado wrapper -> recipe sin convertir Eidos en runtime headless. + Actualizacion 2026-05-16: - Barrido de wrappers publicos Soma frente a providers cerrado: diff --git a/src/uix/eidos/component-visual-attrs.test.ts b/src/uix/eidos/component-visual-attrs.test.ts new file mode 100644 index 000000000..a09f2dd05 --- /dev/null +++ b/src/uix/eidos/component-visual-attrs.test.ts @@ -0,0 +1,62 @@ +import { readFileSync } from 'node:fs' +import { join } from 'node:path' +import { describe, expect, it } from 'vitest' + +const COMPONENTS_DIR = 'src/uix/eidos/components' + +const VISUAL_ATTRS = [ + ['accordion/accordion.svelte', ['data-size', 'data-variant']], + ['accordion/accordion-content.svelte', ['data-size']], + ['accordion/accordion-header.svelte', ['data-size']], + ['accordion/accordion-trigger.svelte', ['data-size', 'data-indicator-placement']], + ['avatar/avatar.svelte', ['data-size', 'data-variant', 'data-color']], + ['checkbox/checkbox.svelte', ['data-size', 'data-variant', 'data-color']], + ['checkbox/checkbox-group.svelte', ['data-columns']], + ['dialog/dialog-close.svelte', ['data-position', 'data-icon-only']], + ['dialog/dialog-content.svelte', ['data-size', 'data-position', 'data-sheet']], + ['drawer/drawer-close.svelte', ['data-icon-only']], + ['drawer/drawer-content.svelte', ['data-size']], + ['popover/popover-close.svelte', ['data-icon-only']], + ['popover/popover-content.svelte', ['data-size']], + ['radio-group/radio-group.svelte', ['data-size', 'data-variant', 'data-color', 'data-columns']], + ['switch/switch.svelte', ['data-size']], + ['tabs/tabs.svelte', ['data-size', 'data-variant', 'data-fitted', 'data-collapsed', 'data-motion']], + ['tabs/tabs-content.svelte', ['data-motion']], + ['tabs/tabs-indicator.svelte', ['data-ready']], + ['toast/toast-viewport.svelte', ['data-position']], + ['toggle/toggle.svelte', ['data-size', 'data-variant', 'data-block', 'data-icon-only']], + ['tooltip/tooltip-content.svelte', ['data-size', 'data-variant']], + ['svg/svg-check.svelte', ['data-svg']], + ['svg/svg-chevron.svelte', ['data-svg', 'data-svg-direction']], + ['svg/svg-dash.svelte', ['data-svg']], + ['svg/svg-dot.svelte', ['data-svg']] +] as const + +function stripComments(source: string): string { + return source.replace(/\/\*[\s\S]*?\*\//g, '').replace(/(^|[^:])\/\/.*$/gm, '$1') +} + +function readComponentSource(relativePath: string): string { + return stripComments(readFileSync(join(COMPONENTS_DIR, relativePath), 'utf8')) +} + +function attrPattern(attr: string): RegExp { + return new RegExp(`${attr.replaceAll('-', '\\-')}\\s*=`) +} + +describe('Eidos component visual attrs', () => { + it('keeps visual recipe attrs wired in their wrappers', () => { + const missing: string[] = [] + + for (const [relativePath, attrs] of VISUAL_ATTRS) { + const source = readComponentSource(relativePath) + for (const attr of attrs) { + if (!attrPattern(attr).test(source)) { + missing.push(`${relativePath}: ${attr}`) + } + } + } + + expect(missing).toEqual([]) + }) +}) diff --git a/src/uix/eidos/components/README.md b/src/uix/eidos/components/README.md index 7e90b05fc..7b3b06033 100644 --- a/src/uix/eidos/components/README.md +++ b/src/uix/eidos/components/README.md @@ -221,6 +221,12 @@ estos attrs/parts visuales. El lint base sigue siendo estricto con valores inválidos de enums morfo; la allowlist solo evita que el reporte de drift se llene de partes visuales intencionales. +La guardia `src/uix/eidos/component-visual-attrs.test.ts` fija el cableado +mínimo entre wrapper y recipe: si un wrapper visual declara una prop que se +consume como `data-*` (`size`, `variant`, `color`, `position`, `columns`, +etc.), el fichero debe seguir estampando ese atributo. Esto no añade +comportamiento a Eidos; solo evita que la capa visual trague props en silencio. + ### Uso del consumidor ```svelte