astra
alpha-0.1-background
alpha-0.1-dir-prefs
alpha-0.1-sec-dom
menubar-v4-safe
active-uix
morfo-runtime
morfo-driven-soma
semantuix
glm-5
main
sium-v1.0
${ noResults }
9 Commits (c1c3cd9404528b76296fd13a17f3ec0fab00d000)
| Author | SHA1 | Message | Date |
|---|---|---|---|
|
|
c1c3cd9404 |
feat(words): parametric color marks — foreground + background pickers (COLOR-3)
Marks now support parametric values via colon syntax:
- color:#hex — foreground text color
- bgcolor:#hex — highlight / background color
Existing boolean marks (bold/italic/underline/strike/code) are
unchanged. Empty value (color:, bgcolor:) clears that slot.
Engine
- WordsMark union extended with `color:\${string}` and
`bgcolor:\${string}` template literal variants.
- isWordsMark accepts the parametric form (validates against #hex
3/4/6/8 digits).
- normalizeMarks de-duplicates by prefix for parametric marks (only
one color, one bgcolor per inline survives).
- toggleMarkSet REPLACES same-prefix entries instead of toggling
them; empty value strips the slot.
- New helpers markValue() and markPrefix() for reading parametric
data.
Serializers
- HTML out: wrapMarks collects color/bgcolor into a single
`<span style="color:..;background-color:..">` instead of nested
spans, then wraps with the boolean-mark tags.
- HTML in: not extended this pass — round-trip via style attr is a
follow-up. The marks survive in the document model + render OK.
- Markdown out: silently drops parametric marks (no MD syntax for
inline color; HTML round-trip is the supported path).
DOM render
- createWordsTextAttrs splits marks into booleans (→
data-words-marks) and parametrics (→ inline `style` attr) so the
contenteditable paints the colors directly.
Drawer Format panel
- New "Foreground" + "Background" sections with:
- 10-swatch palette (red/orange/amber/green/cyan/blue/violet/pink/
white/grey) — hand-picked editorial set
- Native <input type=color> for free hex pick (no preset constraint)
- "×" clear button (only when a value is set for that slot)
- Active swatch outline when the current value matches the preset
- runCommand passes the `color:#hex` / `bgcolor:#hex` string straight
through commandFromName → toggleMark.
WordsCommandName extended with `color:\${string}` and
`bgcolor:\${string}` for type-safe consumer calls.
152/152 tests pass. Verified visually: clicking the red swatch on
selected "ActiveUI" text in the demo produces
`<span data-words-marks="bold" style="color:#ef4444">ActiveUI</span>`
in the rendered HTML, text paints red in the editor, the swatch
shows active outline + clear (×) button appears.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
|
4 months ago |
|
|
08bef77f4b |
feat(words): image extension foundation — types, render, HTML+Markdown serializers (F3.1-F3.5)
Adds image as a first-class block node to the words engine. Phase F3
of the words rich-text editor. Ships the bottom half of the stack so
images can be authored in source (markdown / HTML / value JSON) and
roundtripped, but UX surfaces (toolbar action, slash command, paste/
drop) land in subsequent commits.
F3.1 — extensions/image/{types,factories,index}.ts:
- WordsImageBlock = { type: 'image', src, alt?, caption?, width?, height?, align?, status? }
- createImage(src, options) factory canonicalising defaults (align='center' stripped, etc.)
- WordsImageStatus = 'pending' | 'error' for upload lifecycle
- WORDS_IMAGE_ALIGNS + isWordsImageAlign predicate
F3.2 — engine/document.ts:
- WordsBlockType + WordsBlock union extended with 'image'
- Image types re-exported (backward-compat with the table-types pattern)
- getBlockText: image → alt text (captions excluded; image stays a
single atom in plain-text contexts)
F3.3 — engine/render.ts:
- Image branch renders <figure data-words-block=image contenteditable=false>
<img src alt width? height? loading=lazy draggable=false>
<figcaption>caption</figcaption?
- WordsRenderTag union gains 'figure' | 'img' | 'figcaption'
- data-words-image-align / data-words-image-status surface state
- renderBlockPlainText: image → alt
F3.4 — engine/serialize-html.ts:
- Out: <figure data-words-image-align?><img alt src width? height?><figcaption?></figure>
- In: 'figure' added to BLOCK_TAGS; <figure><img> elements parsed back
to ImageBlock (with caption from <figcaption>); bare <img> parses
to a block too
- htmlElementText helper added for caption text extraction
F3.5 — engine/serialize-markdown.ts:
- Out:  — escapes ], ( and ) in src, " in caption
- In: standalone line matching ^$ promotes to a
block image. Inline images mid-paragraph become text + no image
(lossy by design — keep the model tight; inline image is a separate
node type if added later)
Engine ripple — exhaustive switches updated:
- normalize.getInlineBlockText
- path.collectContainerChildren (image marked as terminal)
- selection.collectBlockText (image returns empty — opaque atom)
- operations:
- setBlock skips image (image is not convertible to inline-text blocks)
- setTextAlign skips image (no text align on image)
- deleteRange refuses if range crosses an image (atomic)
- insertParagraph on image inserts a fresh paragraph after it and
moves the caret
- blockTextAlign() returns undefined for image
- words-provider.currentTextAlign returns 'left' on image
149/149 tests pass in the full words soma scope. `npx tsc --noEmit`
clean for the touched area. Engine consumers compile unchanged.
Next: F3.6 insertImage operation + toolbar/slash command, F3.7 slash
menu /image entry, F3.8 paste/drop with onUploadImage callback, F3.9
eidos CSS, F3.10 imageExtension stub, F3.11 demo + verify.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
|
4 months ago |
|
|
a0afa44da4 |
refactor(words): extract table factories to extensions/table (F2.3b)
Second atomic checkpoint of F2.3. Moves table factory functions (createTable, createTableRow, createTableCell), predicate functions (isWordsTableCellVerticalAlign, isWordsTableCellTone), and value-set constants (WORDS_TABLE_CELL_VERTICAL_ALIGNS, WORDS_TABLE_CELL_TONES) from engine/document.ts to extensions/table/factories.ts. engine/document.ts now re-exports the moved symbols so existing imports keep working unchanged. The factories module imports its back-references (createText, WordsInline) from engine/document — the extension may depend on the engine core but the engine core only depends on the extension via re-export indirection (no functional dependency). extensions/table/index.ts barrel updated to expose types (F2.3a) + factories (F2.3b) as the table extension's public surface. Document header notes which pieces have been migrated and which are still pending (serializers, render, path, normalize, operations, registry wire-up). Verification: - 143/143 tests pass in src/uix/soma/components/words - 0 new TypeScript errors - No engine behaviour change (symbol relocation only) F2.3 progress: a + b done. Pending: c (serialize-html), d (serialize-markdown), e (render), f (path), g (normalize), h (operations — largest), i (registry wire-up), j (verify). Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> |
4 months ago |
|
|
088d31ec5d |
refactor(words): extract table types to extensions/table/types.ts (F2.3a)
First atomic checkpoint of F2.3 (table migration to extension). Moves
the type declarations only — interfaces and unions for the table node
tree (WordsTableBlock, WordsTableRow, WordsTableCell, WordsTableOptions,
WordsTableCellOptions, WordsTableCellVerticalAlign, WordsTableCellTone)
go from engine/document.ts to extensions/table/types.ts.
engine/document.ts re-exports the moved types via `export type { ... }
from '../extensions/table/types'` so every existing consumer keeps
compiling without changes. Internal usages within document.ts use a
separate `import type` to keep the types in local scope for factory
function signatures.
The rest of F2.3 (factories + serializers + render + normalize + path
+ operations + registry wire-up) requires deeper dependency analysis
across the engine's ~990 LoC of table code spread over 10 files. That
work is deferred to a dedicated session to avoid mid-refactor breakage.
Verification:
- 143/143 tests pass in src/uix/soma/components/words
- 0 new TypeScript errors
- No engine behaviour change (types-only move)
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
|
4 months ago |
|
|
9c6375c96e |
feat(eidos): TSC v2.2 (parts + composition) + universal theming coverage
Token Scope Contract universal — no más excepciones arquitectónicas.
Los 3 componentes que vivían fuera de TSC v2.1 (select, avatar,
toggle-group) ahora están dentro del contrato via dos extensiones nuevas.
TSC v2.2 extensiones (lib/config-types.ts + render-css.ts + config.ts):
- `parts: readonly string[]` en RecipeTokenMultiDeclaration — emite
selectores comma-separados (`[data-{c}-x], [data-{c}-y]`) para
componentes con data-color cascadeado per-part. Consumer: select.
- `composition: { foreignRecipe: { targetSelector, tokens } }` sibling
key — overrides cross-recipe scoped a la cascade del host. Consumer:
toggle-group modifica `--toggle-palette-*` en sus items.
Migraciones:
- select: 3 private `_accent-{track,border,text}` con parts: ['trigger',
'content'] + 7 cascades color:X each. Removed orphan `_accent-solid`
(CSS no consumía).
- avatar: 6 tokens via composite scopes `['variant:X', 'color:Y']` con
matrix helper inline. Badge usa parts: ['badge']. Reemplaza 24 bloques
CSS × 2 partes.
- toggle-group: composition block con 8 palette tokens × 4 colors.
Reemplaza 4 bloques CSS per-color.
Bug toggle-group post-composition (encontrado y arreglado):
Tras la composition migration, el cascade del toggle-group seguía roto
porque los tokens derivados (`--toggle-solid-on-bg`, `--toggle-outline-fg`,
etc.) viven en scope `[data-toggle]`. El `[data-toggle-group-item]` es
sibling (no descendant), así que `var(--toggle-solid-on-bg)` resolvía
undefined. Fix: inlined derivation expressions directamente en
`[data-toggle-group-item]` y sus variant cascades (solid/outline/ghost),
referenciando palette tokens en su propio scope local.
Validador + emisor + contract:
- `validateRecipeComposition` valida el shape `{ targetSelector, tokens }`
y rechaza composition entries con scope='root'.
- `stripCompositionKey` + `emitComposition` separan el pipeline.
- `appendRecipeContractTokens` skip-list para `composition` (no aparece
como fake `--{c}-composition` knob).
- `tokenKeys`/`tokenEntries` helpers en recipe-css-contract.test.ts
filtran composition en todos los iteradores.
Documentación:
- THEMING.md §18 reescrito como "Cobertura universal de TSC". §7
extendido con subsecciones "Multi-part scope" y "Cross-recipe
composition" + ejemplos completos. TOC actualizado.
- eidos/README.md tabla de referencia ampliada con TSC v2.2 + §18.
- CLAUDE.md gana hand-off "2026-05-27 #5" (TSC v2.2 + cobertura universal).
- CONTINUE.md reescrito al estado actual de la sesión.
Working tree también incluye sprint Words en paralelo (multiple authors):
slash menu, find/replace regex, code language picker, table audit,
toolbar family menu, code highlight engine.
Tests: 786/786 pass en src/uix/{eidos,morfo,soma,sema}. `npm run check`:
6 errores pre-existentes (lib/_demo, soma/components/internal,
web/routes/active) no relacionados.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
|
4 months ago |
|
|
e6eee766ee |
Improve words editor tooling
|
5 months ago |
|
|
0804749147 |
Words: text alignment, heading picker, ToolPopover cleanup, word boundary fixes
- Add textAlign to document model (paragraph, heading, quote) - Add setTextAlign engine operation with left/center/right/justify - Add alignment toolbar buttons with icons (TextAlignStart, Center, End, Justify) - Update formatting and full presets to include alignment - Fix sameBlockShape to compare textAlign correctly - Add heading levels h2/h3 with Words.HeadingPicker dropdown (Popover) - Remove Words.ToolPopover component; migrate LinkEditor to native Popover - Fix word boundary algorithm: Intl.Segmenter + CJK/punctuation fallback - Fix bubble menu isSelecting logic and pointer event forwarding - Add 5 engine tests for setTextAlign - Update demo presets for alignment - Words engine tests: 42/42 passing |
5 months ago |
|
|
8d277fe929 |
fix(password-field): align input chrome with system + add Form/SIUM demo
Style fix — input chrome was hand-rolled with raw color tokens (`--color-neutral-border`, `--ring-width`) instead of consuming the recipe layer like every other text input. Now matches search-field and number-field exactly: - Added `password-field` recipe to `src/uix/eidos/lib/recipes/base.ts` with the same surface as `search-field` (height, px, gap, font-size per size; border, focus, invalid, bg, color, focus-shadow tokens). - Regenerated `src/uix/eidos/generated/base.css`. - Rewrote `password-field.css` to consume the new tokens — same focus ring (`focus-shadow`), same border colors, same disabled opacity, same transition tokens. VisibilityTrigger gets its own border/bg/ color-on-hover scheme aligned with search-field's clear button. - Added per-size icon + caps font-size tokens so the trigger and caps pill scale with the input. Form + SIUM demo — answers "how does PasswordField validate?": Added a new subsection in the Live tab with three working forms wired through `<Form>` + `<Field>` and SIUM schemas: 1. Login (purpose='current', non-empty password) 2. Registration (purpose='new', complexity rules via regex pipes — uppercase + digit + symbol + 8+ chars, plus the visual StrengthMeter as a companion to the schema) 3. Password change (3 fields with a cross-field `refine()` so new === confirm; demonstrates SIUM's refine pattern) The section explicitly documents that PasswordField has no built-in complexity rules — validation is schema-first. The schema decides what's "correct"; PasswordField's flags propagate via Field's OR-merge of `formFieldState.isInvalid`. svelte-check: 0 errors. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> |
5 months ago |
|
|
940e94bb64 |
Build TextArea component + fix locale propagation bug across soma providers
Major work in this session:
1. NumberField demo refactored to expose Intl.NumberFormatOptions live
- 9 canonical presets (currency/unit/percent/compact/plain)
- Locale/currency/unit lists derived from $libs/langs, $libs/currency,
$format/units (no more hardcoded arrays)
- Default locale from uix.format.numbers.getLocale()
2. Bug fix: locale prop ignored when soma.format service is active
- soma/NumberField: 5 bypass points via new `hasOwnLocale` getter
(decimalSeparator, groupSeparator, formatValue, formatEditValue, parseValue)
- soma/Calendar: dateOrder respects locale prop (matches DateField precedence)
- soma/RangeCalendar: same dateOrder fix
- When the consumer passes `locale` prop, soma.nums/dates is bypassed
and Intl is used directly with the prop locale
3. TextArea — new component, full 4-layer stack
- morfo: 3 parts (provider/input/count), 3 events
(commit-input/commit-submit/shift-count-overflow), APG textbox
- soma: TextAreaProvider with autosize (scrollHeight measurement),
submitOn modes (false|enter|shift+enter|mod+enter), maxLength soft clamp,
Field integration (OR-merge), counter overflow tracking
- eidos: 5 sizes × 3 variants × 8 colors, autosize suppresses CSS resize
- sema: commit-submit + shift-count-overflow perceptual cues
- demo: canonical 6-tab depth, all props exposed as live controls
- PrimitiveTextareaAttributes added to soma/types/html.ts
4. Also includes accumulated unreleased work from prior sessions:
- Eidos ports: announce, clipboard, drag-drop, feed, table,
tree-grid, tree-view, virtual-grid, virtual-list, words
- Their canonical demos under web/routes/uix/components/
- Semantic events defined for utility morfos
(announce/clipboard/virtual-list/virtual-grid)
- Tree indent guides fixed (TreeView ::before, TreeGrid stacked gradients)
- Sidebar reorganized with Data + Utilities groups
- Eidos words content layer and primitives
Reference library survey performed before TextArea API design (Mantine,
Radix Themes, Chakra v3, React Aria, Ark UI, Bits UI, shadcn, MUI, Prime).
Decision documented: no separate CurrencyField/UnitField — single
NumberField with formatOptions is the canon (matches all surveyed
headless libs except PrimeReact's mode enum, which still uses 1 component).
svelte-check: 0 errors in modified/created files.
See CONTINUE.md for full session notes and next steps.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
|
5 months ago |