diff --git a/src/uix/eidos/components/palabras/continuar-palabras.md b/src/uix/eidos/components/palabras/continuar-palabras.md index c6846c60f..dbfffb492 100644 --- a/src/uix/eidos/components/palabras/continuar-palabras.md +++ b/src/uix/eidos/components/palabras/continuar-palabras.md @@ -45,10 +45,12 @@ borde dashed. Con alto real las bandas dejan de degenerarse. Words YA documentab "without this, an empty columns block collapses to 0 height". Tokens palabras/globales, no `--words-*`. ### 4. "+" por columna — insertar DENTRO de cada columna -`palabras-column-inserter.svelte` (nuevo): overlay "+" centrado sobre cada columna VACÍA. Click → la -MISMA rejilla (menos "Columnas") → inserta en esa columna con -`insertBlockInColumn(api, columnsIdx, colIdx, block)` (helper espejo del comando del motor que usa el -inspector de Words). El "+" desaparece al llenarse. Imagen → `pickImageFile`. +`palabras-column-inserter.svelte` (nuevo): overlay "+" en CADA columna — **centrado si está VACÍA, +abajo en el borde si tiene bloques** (para añadir MÁS). Click → la MISMA rejilla (menos "Columnas") → +inserta en esa columna con `insertBlockInColumn(api, columnsIdx, colIdx, block)`, que hace **APPEND al +final** (`[...col.children, block]`); el motor lo documenta como "the + overlay in each column" — camino +canónico. Imagen → `pickImageFile`. El botón "+" es **redondo** (border-radius 999px) con **borde + +sombra elevada**. - Posicionado FRAME-relative (`[data-words]`, como el drop-line seam): `position:absolute` que ancla al MARCO, no al canvas (un canvas posicionado rompería el ancla del seam). Menú PORTALIZADO (mismo fix que el grip). `data-words-external-tool` en "+" + menú. diff --git a/src/uix/eidos/components/palabras/palabras-column-inserter.svelte b/src/uix/eidos/components/palabras/palabras-column-inserter.svelte index fe190e617..b0896b6f8 100644 --- a/src/uix/eidos/components/palabras/palabras-column-inserter.svelte +++ b/src/uix/eidos/components/palabras/palabras-column-inserter.svelte @@ -36,7 +36,14 @@ // Types offered inside a column: everything EXCEPT columns (no columns-in-columns). const colTypes = insertableBlockTypes().filter((t) => t.id !== 'columns'); - type Inserter = { key: string; left: number; top: number; columnsIdx: number; colIdx: number }; + type Inserter = { + key: string; + left: number; + top: number; + columnsIdx: number; + colIdx: number; + atBottom: boolean; + }; let inserters = $state([]); function frame(): HTMLElement | null { @@ -68,15 +75,14 @@ c instanceof HTMLElement && (c.hasAttribute('data-words-id') || c.getAttribute('data-words-node') === 'block') ); - if (hasBlock) return; // only empty columns get the "+" const cr = col.getBoundingClientRect(); - out.push({ - key: `${columnsIdx}-${colIdx}`, - columnsIdx, - colIdx, - left: Math.round(cr.left - frameRect.left + cr.width / 2), - top: Math.round(cr.top - frameRect.top + cr.height / 2) - }); + // Empty column → "+" centred. Column with blocks → "+" on the BOTTOM + // dashed border (to append another block). + const left = Math.round(cr.left - frameRect.left + cr.width / 2); + const top = hasBlock + ? Math.round(cr.bottom - frameRect.top) + : Math.round(cr.top - frameRect.top + cr.height / 2); + out.push({ key: `${columnsIdx}-${colIdx}`, columnsIdx, colIdx, left, top, atBottom: hasBlock }); }); }); inserters = out; @@ -118,7 +124,7 @@ variant="ghost" size="xs" iconOnly - rounded="md" + rounded="full" data-palabras-column-inserter-button data-words-external-tool aria-label="Insertar bloque en la columna" diff --git a/src/uix/eidos/components/palabras/palabras.css b/src/uix/eidos/components/palabras/palabras.css index b0c2e4ffe..2c567cfe0 100644 --- a/src/uix/eidos/components/palabras/palabras.css +++ b/src/uix/eidos/components/palabras/palabras.css @@ -195,6 +195,21 @@ transform: translate(-50%, -50%); z-index: 4; } +/* The "+" itself — a fully round, bordered, ELEVATED button (overrides the + ghost Button's transparent chrome). */ +[data-palabras-canvas] [data-palabras-column-inserter] [data-palabras-column-inserter-button] { + background: var(--color-surface-default); + border: 1px solid var(--color-neutral-border); + border-radius: 999px; + box-shadow: + 0 4px 12px -2px rgb(0 0 0 / 0.22), + 0 2px 4px -1px rgb(0 0 0 / 0.16); + color: var(--color-content-muted); +} +[data-palabras-canvas] [data-palabras-column-inserter] [data-palabras-column-inserter-button]:hover { + border-color: var(--color-content-primary); + color: var(--color-content-primary); +} /* ── Floating inspector panel ─────────────────────────────────────────────── */ [data-palabras-panel-card] {