From 540c35e67967f89a095bfdc471e9507f740c45de Mon Sep 17 00:00:00 2001 From: dev Date: Fri, 29 May 2026 14:30:05 +0200 Subject: [PATCH] =?UTF-8?q?feat(words):=20gutter=20rework=20=E2=80=94=20dr?= =?UTF-8?q?op=20"+",=20move=20insert=20into=20drag=20menu,=20silver=20band?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit User-directed editor rework, step 1 (left gutter): - Remove the "+" inserter button from the block-handle gutter. Its action moves into the drag-handle menu as a new "Insert below" item (folded into `act('insertBelow')`); the standalone `insertBelow` helper is gone. The separate seam inserter (words-block-inserter) is untouched. - Turn the left gutter into a soft silver margin band: narrow it (`--_words-gutter-size` 3.5rem→2.5rem) and paint it via a background-gradient on [data-words-content] — `--words-rail-bg` #ededed band with a 1px, slightly stronger `--words-rail-border` #cfcfcf right edge. Background only, so the contenteditable text / selection is undisturbed. Recipe tokens softened + eidos CSS regenerated. Verified in browser: gutter shows only the grip on hover (no "+"); the menu reads Insert below / Move up / Move down / Duplicate / Delete and "Insert below" inserts a paragraph (7→8 blocks) and closes the menu; the silver band renders at 40px with the 1px border. npm run check: 0 errors. Co-Authored-By: Claude Opus 4.7 --- continue.md | 27 ++++++++++++ .../words/words-block-handle.svelte | 44 +++++++------------ src/uix/eidos/components/words/words.css | 19 +++++++- src/uix/eidos/generated/base.css | 4 +- src/uix/eidos/lib/recipes/base.ts | 11 ++--- 5 files changed, 68 insertions(+), 37 deletions(-) diff --git a/continue.md b/continue.md index 74d8a06af..482ade63a 100644 --- a/continue.md +++ b/continue.md @@ -172,6 +172,33 @@ browser: caret en heading → el panel muestra "Heading level"; el toggle refleja el nivel actual; el click convierte bidireccional (H1→H3→H2) y el toggle se actualiza. `npm run check` 0 errors. +## Rework del editor Words (2026-05-29 #2 — redirect del usuario) + +El usuario redirigió a un nuevo bloque de trabajo sobre el editor. Plan +en 3 pasos (acordado: overlays a eidos POR FASES, con revisión entre +cada una): + +- **Paso 1 — gutter izquierdo (✅ hecho):** quitado el botón "+" del + gutter; "insertar bloque" integrado en el menú del drag handle como + "Insert below" (vía `act('insertBelow')`). Gutter convertido en banda + silver estrecha: `--_words-gutter-size` 3.5rem→2.5rem, fondo + `--words-rail-bg` #ededed (muy suave) + borde derecho 1px + `--words-rail-border` #cfcfcf (un poco más fuerte), pintado como + `linear-gradient` en `[data-words-content]` (solo background, no toca + el contenteditable). Tokens del recipe actualizados + `generate:eidos-css`. + El inserter de SEAM (`words-block-inserter.svelte`, el "+" entre + bloques) NO se tocó — es otro overlay; preguntar si también debe irse. +- **Paso 2 — props de bloque (#3, pendiente):** añadir `color` (texto) + a `BlockVisual` + per-type subsets + `visualToStyle` + validador; y + sección común (margen/espaciado/fondo/color-texto) en el block panel. + Construir esos color controls con **eidos ColorPicker** y migrar los + `` nativos existentes (foreground/background marks + + panel de imagen) a ColorPicker. (Cubre #3 + la parte "color pickers → + eidos" de #4-fase1.) +- **Paso 3 — menú del drag → eidos (#4-fase1 resto) + #4-fase2:** + migrar el menú del block-handle a eidos Menu/Popover; luego link + editor / find / status a Popover+Tooltip. + ## Pendiente para mañana ### P2 — Heredados diff --git a/src/uix/eidos/components/words/words-block-handle.svelte b/src/uix/eidos/components/words/words-block-handle.svelte index 93d432518..d184d3431 100644 --- a/src/uix/eidos/components/words/words-block-handle.svelte +++ b/src/uix/eidos/components/words/words-block-handle.svelte @@ -254,10 +254,18 @@ return () => document.removeEventListener('click', onclick); }); - function act(command: 'moveUp' | 'moveDown' | 'duplicate' | 'delete') { + function act(command: 'insertBelow' | 'moveUp' | 'moveDown' | 'duplicate' | 'delete') { const idx = hoverBlockIndex; if (idx === undefined) return; - if (command === 'moveUp') { + if (command === 'insertBelow') { + // Canon Notion: "+ here adds a line below". The caret follows + // so the user can type right away. + snippet.applyCommand({ + type: 'insertBlock', + blockIndex: idx + 1, + block: { type: 'paragraph', children: [{ type: 'text', text: '' }] } + }); + } else if (command === 'moveUp') { snippet.applyCommand({ type: 'moveBlock', blockIndex: idx, direction: 'up' }); } else if (command === 'moveDown') { snippet.applyCommand({ type: 'moveBlock', blockIndex: idx, direction: 'down' }); @@ -271,23 +279,6 @@ position = null; } - /** - * "+" affordance — inserts a fresh empty paragraph immediately - * AFTER the hovered block (canon Notion behavior: "+ here adds a - * line below"). The caret follows so the user can type right - * away. Mousedown is `preventDefault`ed so the click doesn't blur - * the editor. - */ - function insertBelow() { - const idx = hoverBlockIndex; - if (idx === undefined) return; - snippet.applyCommand({ - type: 'insertBlock', - blockIndex: idx + 1, - block: { type: 'paragraph', children: [{ type: 'text', text: '' }] } - }); - } - function ondragstart(e: DragEvent) { const idx = hoverBlockIndex; if (idx === undefined) { @@ -364,16 +355,6 @@ style="top: {position.top}px; left: {position.left}px;" role="presentation" > - +