From d2f184da44f3b8509ef5656941ebdcbd41c88359 Mon Sep 17 00:00:00 2001 From: dev Date: Thu, 28 May 2026 02:16:50 +0200 Subject: [PATCH] refactor(toggle-group): item is structurally a Toggle (zero derivation duplication) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Closes the deuda left explicit in hand-off 2026-05-27 #5: the inlined derivation expressions in toggle-group.css duplicated Toggle's recipe because [data-toggle-group-item] wasn't a descendant of [data-toggle]. Resolution is structural, not a drift test: - morfo: each item declares { attr: 'data-toggle', value: v.literal(''), severity: 'required' }. Captures structural identity — an item IS a toggle in every observable sense (same press, same variant/color/size, same on/off machine). - eidos: new context.ts propagates the root's variant + size via reactive getters; the item wrapper writes them as data-attrs on its button. Combined with data-toggle, the item is DOM-equivalent to a standalone . - eidos css: ~150 lines deleted (base derived tokens, variant cascades, size cascade, focus/disabled/icon-only duplicates). Toggle's recipe now paints the item end-to-end. CSS keeps only the grouping concerns: flex, orientation, attached, block, focus z-index, group disabled. - composition (TSC v2.2) stays — palette overrides land on the item under [data-toggle-group][data-color='X'] [data-toggle-group-item], which Toggle's --toggle-palette-* chain reads at item scope. Verification: - DOM probe (12 combinations: 4 colors × 3 variants × 2 states) on /uix/components/toggle-group. Computed values match bit-a-bit with baseline pre-refactor (e.g. affirm/solid on = rgb(18,165,148), risk/outline on = srgb(0.2,0.118,0.043), threat/ghost on = rgb(25,17,17)). - vitest src/uix/{morfo,eidos}: 163/163 pass. - vitest src/uix/soma/components/toggle-group: 4/4 pass. - npm run check: 12 errors (all pre-existing in active Words sprint; zero added by this migration). Drive-by: the same npm-check pass surfaced 4 stale 'orientation' refs in words-toolbar.svelte + words-toolbar-group.svelte from this session's earlier toolbar refactor (orientation was removed from types but not from these soma components). Removed; brings check from 16 → 12 errors. CLAUDE.md hand-off 2026-05-28 documents the new doctrine: when a wrapper visually reuses another, declare structural identity in the wrapper's morfo. Don't duplicate the cascade, don't extend TSC for one case. Co-Authored-By: Claude Opus 4.7 (1M context) --- CLAUDE.md | 28 ++ .../eidos/components/toggle-group/README.md | 28 +- .../eidos/components/toggle-group/context.ts | 35 +++ .../toggle-group/toggle-group-item.svelte | 14 +- .../components/toggle-group/toggle-group.css | 241 ++---------------- .../toggle-group/toggle-group.svelte | 13 + src/uix/morfo/components/toggle-group.ts | 11 + .../components/words-toolbar-group.svelte | 4 +- .../words/components/words-toolbar.svelte | 4 +- 9 files changed, 146 insertions(+), 232 deletions(-) create mode 100644 src/uix/eidos/components/toggle-group/context.ts diff --git a/CLAUDE.md b/CLAUDE.md index b6a30f6d8..8121e68ed 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -532,6 +532,34 @@ Pregunta arquitectónica del usuario: "si activeUIX quiere ser referencia como f **Tests**: 101/101 pass en `src/uix/eidos`. `npm run check`: los mismos 6 errores pre-existentes (lib/_demo, soma/components/internal, web/routes/active). +## Session hand-off — 2026-05-28 (toggle-group structural identity) + +Cierra la deuda dejada explícitamente abierta en el hand-off 2026-05-27 #5 ("Los `inlined derivation expressions` en `toggle-group.css` son la única duplicación entre recipes/base.ts y CSS. Si Toggle's derivations cambian, hay que actualizar ambos."). Ahora son cero. + +**Pregunta arquitectónica del usuario** tras verificar el fix EXT-FIX (color cascade): "¿qué es lo recomendado en referencia al ecosistema y su diseño y arquitectura?". Respuesta firme: **resolver la duplicación estructuralmente, no con un test de drift**. El item de toggle-group ES un toggle (mismo press, mismo variant/color/size, misma máquina on/off) — la doctrina "morfo declara DNA" pide declararlo. + +**Cambios**: + +- `src/uix/morfo/components/toggle-group.ts`: el part `Item` declara `{ attr: 'data-toggle', value: v.literal(''), severity: 'required' }`. Cada item proyecta `data-toggle=""` como atributo de presencia. Cero overhead, captura la identidad estructural. +- `src/uix/eidos/components/toggle-group/context.ts` (nuevo): contexto Svelte tipado (`ToggleGroupEidosCtx` con getters reactivos para `variant` y `size`) — propaga las dos perillas eidos-only del root a cada item. +- `src/uix/eidos/components/toggle-group/toggle-group.svelte`: setea el contexto en el root. Getters mantienen reactividad cuando el prop cambia. +- `src/uix/eidos/components/toggle-group/toggle-group-item.svelte`: lee el contexto y escribe `data-variant={ctx?.variant}` + `data-size={ctx?.size}` en el button. Combinado con `data-toggle` del morfo, el elemento es DOM-equivalente a un `` standalone. +- `src/uix/eidos/components/toggle-group/toggle-group.css`: borradas ~150 líneas (todas las derivaciones base + variant cascade + size cascade + focus-visible / disabled / icon-only duplicados). El CSS conserva SOLO grouping concerns (flex layout, orientation, attached con first/last/border-radius, block, focus z-index, group-level disabled). El header comment se rescribe documentando la nueva división de responsabilidades. +- `src/uix/eidos/components/toggle-group/README.md`: sección "Recipe" + "Decisiones" actualizadas — la entrada "Structural identity" documenta el patrón. + +**Por qué TSC v2.2 composition se queda en la mezcla**: la composition sigue siendo necesaria para overridear `--toggle-palette-*` en el item bajo `[data-toggle-group][data-color='X'] [data-toggle-group-item]`. El color NO se propaga via contexto porque la composition ya hace el trabajo a nivel CSS, sin overhead reactivo. Variant/size sí se propagan porque tienen muchos derivados (height, padding, gap, font, radius × 5 sizes; bg, fg, border, hover, on, on-hover × 3 variants) que solo Toggle's recipe ya emite — no había ningún beneficio en mantener cascadas paralelas. + +**Verificación**: probe DOM en `/uix/components/toggle-group` capturando computed values en las 12 combinaciones (4 colores × 3 variants) × 2 estados (on/off) — match bit-a-bit con baseline pre-refactor. Ejemplos: +- `affirm/solid` on: `rgb(18,165,148)` = `#12a594` (palette-solid affirm) +- `risk/outline` on: `color(srgb 0.2 0.118 0.043)` ≈ `#331e0b` (color-mix outline on-bg) +- `threat/ghost` on: `rgb(25,17,17)` = `#191111` (palette-track threat) + +**Tests**: 163/163 pass en `src/uix/morfo` + `src/uix/eidos`. 4/4 pass en `src/uix/soma/components/toggle-group`. `npm run check`: 16 errores pre-existentes (los mismos del sprint Words), CERO añadidos por esta migración. + +**Coste real vs estimado**: el hand-off #5 estimó el cambio como "too big" — incorrecto. Total = 1 entrada en morfo + 1 archivo de contexto (~30 líneas) + 2 ediciones puntuales en wrappers (~5 líneas cada) + 1 rewrite de CSS reduciendo ~150 líneas a ~85. La parte engañosa era pensar que requería tocar Toggle's CSS — no lo hace. + +**Doctrina reforzada**: cuando un wrapper componente reusa visualmente otro, la respuesta canónica NO es duplicar el cascade ni extender TSC con un tercer feature. Es declarar la identidad estructural en el morfo del wrapper. Patrón aplicable si emerge button-group, link-group, etc. + ## Session hand-off — 2026-05-09 (selector discipline + lint reframing) - **Typed selector builder applied** in diff --git a/src/uix/eidos/components/toggle-group/README.md b/src/uix/eidos/components/toggle-group/README.md index 0cc295db2..84400f702 100644 --- a/src/uix/eidos/components/toggle-group/README.md +++ b/src/uix/eidos/components/toggle-group/README.md @@ -61,11 +61,21 @@ ships a sound payload — no per-component cascade needed. ## Recipe -`toggle-group.css`. Consumes the Toggle token vocabulary -(`--toggle-*`) so item visuals stay coherent with standalone -`` buttons. `data-attached`, `data-block`, `data-orientation`, -`data-size`, `data-variant`, `data-color` cascade from the root to -the items via descendant selectors. +`toggle-group.css` owns only what's unique to grouping: flex layout, +orientation, `data-attached` (segmented control), `data-block` +(stretch), focus-visible z-index, and a group-level disabled +cascade. + +The painting itself comes from Toggle's recipe — each item declares +`data-toggle` in its morfo (structural identity) and the eidos +wrapper propagates `data-variant` + `data-size` from the group via +context, so the item element carries exactly what a standalone +`` would. `data-color` stays on the group; TSC v2.2 +`composition` (see `lib/recipes/base.ts > toggle-group.composition`) +emits `--toggle-palette-*` overrides on every item under +`[data-toggle-group][data-color='X'] [data-toggle-group-item]`. +Zero derivation duplication between toggle-group.css and Toggle's +recipe. ## Baseline @@ -100,6 +110,14 @@ missing. next to a `` looks visually identical at the same `variant` × `color` × `size`. Single source of truth for the "toggle button" vocabulary. +- **Structural identity**: each item declares `data-toggle` in its + morfo and the eidos wrapper propagates the group's `variant`/`size` + to it via context. The Toggle recipe paints the item end-to-end — + base, variant cascades, size cascades, on/off state, hover, + focus-visible, disabled, icon-only. toggle-group.css owns only the + grouping concerns. Prior approach inlined the derivation + expressions, which duplicated Toggle's logic; the structural + identity removes the duplication entirely. - No re-bindable `pressed` per item — the value array on the group is the source of truth (Radix-style). diff --git a/src/uix/eidos/components/toggle-group/context.ts b/src/uix/eidos/components/toggle-group/context.ts new file mode 100644 index 000000000..6527d4d25 --- /dev/null +++ b/src/uix/eidos/components/toggle-group/context.ts @@ -0,0 +1,35 @@ +import { getContext, setContext } from 'svelte'; +import type { ToggleGroupVariant, ToggleGroupSize } from './types'; + +/** + * Eidos context for `` → `` — propagates + * the visual knobs (`variant`, resolved `size`) the root receives so + * each item renders with the same data-* attrs a standalone `` + * would carry. + * + * Why context instead of CSS descendant selectors: the item declares + * `data-toggle` in its morfo (structural identity — an item IS a + * toggle). The Toggle recipe owns the entire `--_toggle-*` derivation + * chain on `[data-toggle][data-variant='X']` and `[data-toggle][data- + * size='Y']`. For those rules to fire on an item, the item element + * itself needs `data-variant` and `data-size` — not its ancestor. + * + * The context value uses property getters so reads stay reactive: when + * the root's `variant` or `size` prop changes, items observing the + * getter see the new value on the next read. + */ + +const KEY = Symbol('toggle-group-eidos-ctx'); + +export interface ToggleGroupEidosCtx { + readonly variant: ToggleGroupVariant; + readonly size: ToggleGroupSize; +} + +export function setToggleGroupEidosCtx(ctx: ToggleGroupEidosCtx): void { + setContext(KEY, ctx); +} + +export function getToggleGroupEidosCtx(): ToggleGroupEidosCtx | undefined { + return getContext(KEY); +} diff --git a/src/uix/eidos/components/toggle-group/toggle-group-item.svelte b/src/uix/eidos/components/toggle-group/toggle-group-item.svelte index 2822818a6..aabcca5be 100644 --- a/src/uix/eidos/components/toggle-group/toggle-group-item.svelte +++ b/src/uix/eidos/components/toggle-group/toggle-group-item.svelte @@ -10,10 +10,22 @@ */ import * as ToggleGroup from '$soma/components/toggle-group'; import type { ToggleGroupItemProps } from './types'; + import { getToggleGroupEidosCtx } from './context'; let { iconOnly = false, children, ...rest }: ToggleGroupItemProps = $props(); + + // Inherit variant/size from the root . The item has + // `data-toggle` (declared in morfo) and the Toggle recipe needs + // these attrs ON the item itself — not on the ancestor — to resolve + // the variant/size cascades. + const ctx = getToggleGroupEidosCtx(); - + {@render children?.()} diff --git a/src/uix/eidos/components/toggle-group/toggle-group.css b/src/uix/eidos/components/toggle-group/toggle-group.css index db469dc8a..2228b972a 100644 --- a/src/uix/eidos/components/toggle-group/toggle-group.css +++ b/src/uix/eidos/components/toggle-group/toggle-group.css @@ -1,25 +1,18 @@ /* * ToggleGroup recipe. * - * Cross-recipe color composition lives in the recipe via TSC v2.2 - * `composition: { toggle: { targetSelector: '[data-toggle-group-item]', - * tokens: { palette-*: ... } } }` (see `lib/recipes/base.ts > - * toggle-group.composition`). The generator emits the per-color - * descendant overrides for Toggle's palette tokens automatically. - * - * Visually each item IS a Toggle — same height / padding / radius - * tokens, same variant + palette vocabulary. The group adds: - * - * - Layout: flex container, orientation-aware direction, gap - * - `data-attached`: items collapse spacing + share borders so the - * group reads as a single segmented control - * - `data-block`: items grow equally to fill the inline-size - * - Disabled cascade: a single `disabled` on the group disables all - * items (the morfo already projects `data-disabled` on each item). - * - Per-color cascade on items via TSC v2.2 composition (above). + * Structural identity: each item declares `data-toggle` in its morfo + * and the eidos wrapper propagates `data-variant` + `data-size` from + * the group to every item. Result: an item is, observably, a Toggle — + * the entire Toggle recipe (base + variant/size cascades + on-state + + * hover / disabled / icon-only) paints it. This file owns ONLY what's + * unique to grouping: flex layout, orientation, attached (segmented + * control), block (stretch), and the per-color palette overrides + * generated via TSC v2.2 `composition` (see `lib/recipes/base.ts > + * toggle-group.composition`). * * [data-toggle-group] → flex container - * [data-toggle-group-item] → button (Toggle-shaped) + * [data-toggle-group-item] → button, also carrier of `[data-toggle]` */ [data-toggle-group] { @@ -95,214 +88,22 @@ z-index: 1; } -/* ── Item ──────────────────────────────────────────────────────────── - * - * Items consume the Toggle palette tokens (one source of truth for the - * "toggle button" visual vocabulary). `data-variant` / `data-color` / - * `data-size` are read from the ancestor group via descendant - * selectors below. - */ - -[data-toggle-group-item] { - --_toggle-height: var(--toggle-height-md); - --_toggle-padding-inline: var(--toggle-px-md); - --_toggle-gap: var(--toggle-gap-md); - --_toggle-font-size: var(--toggle-font-size-md); - --_toggle-font-weight: var(--toggle-font-weight-md); - --_toggle-radius: var(--toggle-radius-md); - --toggle-palette-track: var(--toggle-neutral-track); - --toggle-palette-element: var(--toggle-neutral-element); - --toggle-palette-hover: var(--toggle-neutral-hover); - --toggle-palette-border: var(--toggle-neutral-border); - --toggle-palette-solid: var(--toggle-neutral-solid); - --toggle-palette-solid-hover: var(--toggle-neutral-solid-hover); - --toggle-palette-text: var(--toggle-neutral-text); - --toggle-palette-contrast: var(--toggle-neutral-contrast); - /* - * Derived tokens are inlined here (rather than read via - * `var(--toggle-solid-*)` etc.) because Toggle's recipe declares - * those at `[data-toggle]` scope — which the toggle-group-item is - * NOT a descendant of. Reading them via var() would resolve to - * undefined and collapse the cascade. Inlining keeps the var() - * substitution local to the item, so the TSC v2.2 composition - * override of `--toggle-palette-*` (in `recipes/base.ts > - * toggle-group.composition`) propagates through. - * - * The literal expressions mirror `recipes/base.ts > toggle.solid-*`. - * If those change, update both sides. - */ - --_toggle-bg: var(--toggle-solid-bg); - --_toggle-fg: var(--toggle-solid-fg); - --_toggle-border: var(--toggle-solid-border); - --_toggle-hover-bg: color-mix( - in srgb, - var(--color-surface-overlay) 68%, - var(--toggle-palette-track) - ); - --_toggle-hover-border: color-mix( - in srgb, - var(--toggle-palette-border) 45%, - var(--color-border-strong) - ); - --_toggle-on-bg: var(--toggle-palette-solid); - --_toggle-on-fg: var(--toggle-palette-contrast); - --_toggle-on-border: var(--toggle-palette-solid); - --_toggle-on-hover-bg: var(--toggle-palette-solid-hover); - --_toggle-on-hover-border: var(--toggle-palette-solid-hover); - - display: inline-flex; - align-items: center; - justify-content: center; - gap: var(--_toggle-gap); - min-height: var(--_toggle-height); - padding-inline: var(--_toggle-padding-inline); - border: var(--toggle-border-width) solid var(--_toggle-border); - border-radius: var(--_toggle-radius); - background: var(--_toggle-bg); - color: var(--_toggle-fg); - box-shadow: var(--toggle-shadow); - font-family: var(--toggle-font-family); - font-size: var(--_toggle-font-size); - font-weight: var(--_toggle-font-weight); - line-height: var(--toggle-line-height); - letter-spacing: var(--toggle-letter-spacing); - white-space: nowrap; - cursor: pointer; - transition: - background var(--toggle-transition-duration) var(--toggle-transition-ease), - border-color var(--toggle-transition-duration) var(--toggle-transition-ease), - color var(--toggle-transition-duration) var(--toggle-transition-ease), - box-shadow var(--toggle-transition-duration) var(--toggle-transition-ease); -} - -[data-toggle-group-item]:hover:not([data-disabled]) { - background: var(--_toggle-hover-bg); - border-color: var(--_toggle-hover-border); -} - -[data-toggle-group-item][data-state='on'] { - background: var(--_toggle-on-bg); - color: var(--_toggle-on-fg); - border-color: var(--_toggle-on-border); -} - -[data-toggle-group-item][data-state='on']:hover:not([data-disabled]) { - background: var(--_toggle-on-hover-bg); - border-color: var(--_toggle-on-hover-border); -} - +/* Focused item floats above neighbors so the focus ring isn't clipped + * either. Toggle's recipe owns the ring itself (outline + box-shadow). */ [data-toggle-group-item]:focus-visible { - outline: none; - box-shadow: var(--focus-ring); z-index: 2; } -[data-toggle-group-item][data-disabled] { - cursor: default; - opacity: var(--toggle-disabled-opacity, 0.55); -} - -[data-toggle-group-item][data-icon-only] { - padding-inline: 0; - inline-size: var(--_toggle-height); -} - -/* ── Size cascade — items inherit data-size from the group ───────── */ -[data-toggle-group][data-size='xs'] [data-toggle-group-item] { - --_toggle-height: var(--toggle-height-xs); - --_toggle-padding-inline: var(--toggle-px-xs); - --_toggle-gap: var(--toggle-gap-xs); - --_toggle-font-size: var(--toggle-font-size-xs); - --_toggle-font-weight: var(--toggle-font-weight-xs); - --_toggle-radius: var(--toggle-radius-xs); -} - -[data-toggle-group][data-size='sm'] [data-toggle-group-item] { - --_toggle-height: var(--toggle-height-sm); - --_toggle-padding-inline: var(--toggle-px-sm); - --_toggle-gap: var(--toggle-gap-sm); - --_toggle-font-size: var(--toggle-font-size-sm); - --_toggle-font-weight: var(--toggle-font-weight-sm); - --_toggle-radius: var(--toggle-radius-sm); -} - -[data-toggle-group][data-size='lg'] [data-toggle-group-item] { - --_toggle-height: var(--toggle-height-lg); - --_toggle-padding-inline: var(--toggle-px-lg); - --_toggle-gap: var(--toggle-gap-lg); - --_toggle-font-size: var(--toggle-font-size-lg); - --_toggle-font-weight: var(--toggle-font-weight-lg); - --_toggle-radius: var(--toggle-radius-lg); -} - -[data-toggle-group][data-size='xl'] [data-toggle-group-item] { - --_toggle-height: var(--toggle-height-xl); - --_toggle-padding-inline: var(--toggle-px-xl); - --_toggle-gap: var(--toggle-gap-xl); - --_toggle-font-size: var(--toggle-font-size-xl); - --_toggle-font-weight: var(--toggle-font-weight-xl); - --_toggle-radius: var(--toggle-radius-xl); -} - -/* ── Variant cascade ─────────────────────────────────────────────── - * - * Inlined for the same reason as the item base block above: Toggle's - * `--toggle-{outline,ghost}-*` tokens live at `[data-toggle]` scope, - * which the toggle-group-item is not a descendant of. Reading them - * via var() would resolve to undefined. The expressions mirror - * `recipes/base.ts > toggle.{outline,ghost}-*`. - */ - -[data-toggle-group][data-variant='outline'] [data-toggle-group-item] { - --_toggle-bg: transparent; - --_toggle-fg: var(--toggle-palette-text); - --_toggle-border: color-mix( - in srgb, - var(--toggle-palette-border) 88%, - var(--color-border-default) - ); - --_toggle-hover-bg: var(--toggle-palette-track); - --_toggle-hover-border: color-mix( - in srgb, - var(--toggle-palette-border) 100%, - var(--color-border-default) - ); - --_toggle-on-bg: color-mix( - in srgb, - var(--toggle-palette-element) 100%, - var(--color-surface-raised) - ); - --_toggle-on-fg: var(--toggle-palette-text); - --_toggle-on-border: var(--toggle-palette-border); - --_toggle-on-hover-bg: var(--toggle-palette-hover); - --_toggle-on-hover-border: var(--toggle-palette-border); -} - -[data-toggle-group][data-variant='ghost'] [data-toggle-group-item] { - --_toggle-bg: transparent; - --_toggle-fg: var(--toggle-palette-text); - --_toggle-border: transparent; - --_toggle-hover-bg: color-mix(in srgb, var(--toggle-palette-track) 72%, transparent); - --_toggle-hover-border: transparent; - --_toggle-on-bg: var(--toggle-palette-track); - --_toggle-on-fg: var(--toggle-palette-text); - --_toggle-on-border: color-mix( - in srgb, - var(--toggle-palette-border) 72%, - transparent - ); - --_toggle-on-hover-bg: var(--toggle-palette-element); - --_toggle-on-hover-border: color-mix( - in srgb, - var(--toggle-palette-border) 88%, - transparent - ); -} - -/* Color cascade lives in the recipe (TSC v2.2 composition). See file - * header comment for details. */ - +/* Group-level disabled cascade — the morfo also projects `data-disabled` + * onto each item, so Toggle's `[data-toggle][data-disabled]` rule paints + * each one; this rule disables interaction at the container. */ [data-toggle-group][data-disabled] { opacity: var(--toggle-disabled-opacity, 0.55); pointer-events: none; } + +/* Per-color cascade: TSC v2.2 `composition` in `lib/recipes/base.ts > + * toggle-group.composition` emits the palette overrides on every item + * as `[data-toggle-group][data-color='X'] [data-toggle-group-item]`. + * That feeds Toggle's `--toggle-palette-*` chain on each item. No CSS + * needed here. */ diff --git a/src/uix/eidos/components/toggle-group/toggle-group.svelte b/src/uix/eidos/components/toggle-group/toggle-group.svelte index f0d660657..4837b7fc9 100644 --- a/src/uix/eidos/components/toggle-group/toggle-group.svelte +++ b/src/uix/eidos/components/toggle-group/toggle-group.svelte @@ -17,6 +17,7 @@ import { ActiveEidos } from '$uix/eidos'; import * as ToggleGroup from '$soma/components/toggle-group'; import type { ToggleGroupProps } from './types'; + import { setToggleGroupEidosCtx } from './context'; let { variant = 'solid', @@ -31,6 +32,18 @@ const eidos = ActiveEidos.require(); const resolvedSize = $derived(eidos.resolve(size, 'md')); + + // Propagate variant/size to every so each item's + // own `[data-toggle]` element carries the attrs the Toggle recipe + // reads. Getters keep the bridge reactive. + setToggleGroupEidosCtx({ + get variant() { + return variant; + }, + get size() { + return resolvedSize; + } + }); ref, (v) => (ref = v) - ), - orientation: readableActive(() => orientation) + ) }); const mergedProps = $derived(mergeProps(restProps, state.props)); diff --git a/src/uix/soma/components/words/components/words-toolbar.svelte b/src/uix/soma/components/words/components/words-toolbar.svelte index aabae3ef4..769ea5326 100644 --- a/src/uix/soma/components/words/components/words-toolbar.svelte +++ b/src/uix/soma/components/words/components/words-toolbar.svelte @@ -10,7 +10,6 @@ let { ref = $bindable(null), id = createId(uid, 'words-toolbar'), - orientation = 'horizontal', children, child, ...restProps @@ -21,8 +20,7 @@ ref: writableActive( () => ref, (v) => (ref = v) - ), - orientation: readableActive(() => orientation) + ) }); const mergedProps = $derived(mergeProps(restProps, state.props));