From f80f222596d7bb1899f01c364bcde4f7bd205280 Mon Sep 17 00:00:00 2001 From: dev Date: Mon, 22 Jun 2026 11:52:47 +0200 Subject: [PATCH] feat(dropdown-menu): adopt the `overlay` elevation plane (B2) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Content / SubContent now carry `data-depth="overlay"` and take their surface · border · shadow · halo from the overlay plane instead of the recipe. Prune the now-redundant recipe tokens (content-border-width / border-color / bg / shadow) — the plane is the single source, no double-paint — and point the arrow fill at `--depth-overlay-surface` so it always matches the panel. Radius / font / color stay the panel's own. Verified in-browser: open menu paints bg oklch(0.285) + 1px border + shadow/halo from the plane; orphan-token contract test passes; check 0. Co-Authored-By: Claude Opus 4.8 (1M context) --- src/uix/eidos/components/dropdown-menu/README.md | 16 +++++++++++----- .../dropdown-menu/dropdown-menu-content.svelte | 2 +- .../dropdown-menu-sub-content.svelte | 2 +- .../components/dropdown-menu/dropdown-menu.css | 10 +++++----- src/uix/eidos/generated/base.css | 4 ---- src/uix/eidos/lib/recipes/base.ts | 4 ---- 6 files changed, 18 insertions(+), 20 deletions(-) diff --git a/src/uix/eidos/components/dropdown-menu/README.md b/src/uix/eidos/components/dropdown-menu/README.md index ac569cd60..ee4d8d984 100644 --- a/src/uix/eidos/components/dropdown-menu/README.md +++ b/src/uix/eidos/components/dropdown-menu/README.md @@ -140,11 +140,17 @@ chips" without per-item state bookkeeping. ## Decisiones -- **No `variant` / `color` / `size` at the menu level.** Menus are - the visual variant of "list of actions" within an app; introducing - multiple visual flavors creates noise. If a consumer wants a colored - destructive item they pass `data-color` on the `` - directly (the morfo accepts it). +- **No `variant` / `color` at the menu level.** Menus are the visual + variant of "list of actions" within an app; introducing multiple visual + flavors creates noise. If a consumer wants a colored destructive item they + pass `data-color` on the `` directly (the morfo accepts it). +- **`size` IS a menu axis (1:1 with the controls).** A menu is *content*, so + it scales like a Field input — `size N → --font-size-N` + `--control-height-N`, + not one step below. `` (default `md`) stamps + `data-size`; the recipe retints the panel's own per-size tokens, and the size + flows to every fly-out submenu via a context (submenus portal out, so CSS + inheritance can't carry it). This is what composed menus (e.g. `SplitButton`) + forward their size into — the scale lives here, once, not per consumer. - **Pass-through wrappers** for every part. Visual treatment is in the CSS recipe via `[data-dropdown-menu-*]` selectors — keeping wrappers thin makes context-menu and menubar trivial to derive (just diff --git a/src/uix/eidos/components/dropdown-menu/dropdown-menu-content.svelte b/src/uix/eidos/components/dropdown-menu/dropdown-menu-content.svelte index d5849a829..fd322cf4a 100644 --- a/src/uix/eidos/components/dropdown-menu/dropdown-menu-content.svelte +++ b/src/uix/eidos/components/dropdown-menu/dropdown-menu-content.svelte @@ -34,7 +34,7 @@ setListSurfaceSizeContext({ getSize: () => resolvedSize }); - + {#snippet children(snippetProps)} {@render bodyContent?.(snippetProps)} {/snippet} diff --git a/src/uix/eidos/components/dropdown-menu/dropdown-menu-sub-content.svelte b/src/uix/eidos/components/dropdown-menu/dropdown-menu-sub-content.svelte index 7fa4b182e..0f70f3b35 100644 --- a/src/uix/eidos/components/dropdown-menu/dropdown-menu-sub-content.svelte +++ b/src/uix/eidos/components/dropdown-menu/dropdown-menu-sub-content.svelte @@ -21,7 +21,7 @@ const resolvedSize = $derived(eidos.resolve(size ?? sizeCtx?.getSize(), 'md')); - + {#snippet children(snippetProps)} {@render bodyContent?.(snippetProps)} {/snippet} diff --git a/src/uix/eidos/components/dropdown-menu/dropdown-menu.css b/src/uix/eidos/components/dropdown-menu/dropdown-menu.css index 6eca8f335..6e018a733 100644 --- a/src/uix/eidos/components/dropdown-menu/dropdown-menu.css +++ b/src/uix/eidos/components/dropdown-menu/dropdown-menu.css @@ -36,11 +36,9 @@ max-block-size: var(--dropdown-menu-content-max-height, min(60vh, 22rem)); overflow-y: auto; padding: var(--dropdown-menu-content-padding, var(--space-1)); - border: var(--dropdown-menu-content-border-width, 1px) solid - var(--dropdown-menu-content-border-color, var(--color-border-default)); + /* Elevation — surface · border · shadow — from the `overlay` plane via + `data-depth` (A1, Decisión 8). Radius / font / color stay the panel's own. */ border-radius: var(--dropdown-menu-content-radius, var(--radius-md)); - background: var(--dropdown-menu-content-bg, var(--color-surface-overlay)); - box-shadow: var(--dropdown-menu-content-shadow, var(--shadow-overlay)); font-family: var(--style-label-font-family, var(--font-ui)); font-size: var(--dropdown-menu-content-font-size, var(--font-size-sm)); color: var(--color-content-primary); @@ -182,7 +180,9 @@ /* ── Arrow ────────────────────────────────────────────────────────── */ [data-dropdown-menu-arrow] { - fill: var(--dropdown-menu-content-bg, var(--color-surface-overlay)); + /* The arrow is part of the elevation surface — consume the `overlay` plane so + it always matches the panel (A1, like popover), not a parallel token. */ + fill: var(--depth-overlay-surface); } /* ── State transitions ────────────────────────────────────────────── */ diff --git a/src/uix/eidos/generated/base.css b/src/uix/eidos/generated/base.css index 82aa42a5c..b255b3a93 100644 --- a/src/uix/eidos/generated/base.css +++ b/src/uix/eidos/generated/base.css @@ -3357,11 +3357,7 @@ --dropdown-menu-content-min-width: 12rem; --dropdown-menu-content-max-height: min(60vh, 22rem); --dropdown-menu-content-padding: var(--space-1); - --dropdown-menu-content-border-width: var(--border-width); - --dropdown-menu-content-border-color: var(--color-border-default); --dropdown-menu-content-radius: var(--radius-md); - --dropdown-menu-content-bg: var(--color-surface-overlay); - --dropdown-menu-content-shadow: var(--depth-overlay-shadow), var(--depth-overlay-halo); --dropdown-menu-content-font-size: var(--font-size-sm); --dropdown-menu-item-gap: var(--space-2); --dropdown-menu-item-height: 2rem; diff --git a/src/uix/eidos/lib/recipes/base.ts b/src/uix/eidos/lib/recipes/base.ts index 76527ef60..1e66aa4c8 100644 --- a/src/uix/eidos/lib/recipes/base.ts +++ b/src/uix/eidos/lib/recipes/base.ts @@ -4196,11 +4196,7 @@ export const THEME_BASE_RECIPE_TOKENS = { 'content-min-width': '12rem', 'content-max-height': 'min(60vh, 22rem)', 'content-padding': 'var(--space-1)', - 'content-border-width': 'var(--border-width)', - 'content-border-color': 'var(--color-border-default)', 'content-radius': 'var(--radius-md)', - 'content-bg': 'var(--color-surface-overlay)', - 'content-shadow': 'var(--depth-overlay-shadow), var(--depth-overlay-halo)', 'content-font-size': 'var(--font-size-sm)', 'item-gap': 'var(--space-2)', 'item-height': '2rem',