From 1c30d52300b3eabcf2dc1bd2d83b8fe8959255d5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=B8=85=E5=87=A4?= Date: Mon, 14 Sep 2026 07:36:32 -0700 Subject: [PATCH] =?UTF-8?q?feat(ui):=20select=20trigger=20=E5=A2=9E?= =?UTF-8?q?=E5=8A=A0=20data-hover-lighten=20=E8=B0=83=E7=94=A8=E5=B1=82?= =?UTF-8?q?=E5=BC=80=E5=85=B3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit dark 下 select trigger 的默认 hover 是纯黑压暗(#598 定下的设计),在 近黑画布(--background ≈ RGB 17)上没有向下行程,hover 完全无反馈 ——onboarding 的 Language select 即为此场景。 不改全局 token(压暗是既定美学,且波及 250+ 处 outline/secondary Button),改为新增 data-hover-lighten 属性:设置后该 trigger 的 hover 翻转为白色 8% overlay(--select-trigger-hover-lighten)。light 下该 token 与默认填充相同,属性为无操作。 这是临时调用层开关;surface 感知的 hover 极性归组件库重构统一裁决, 不要扩大此属性的使用范围。 --- src/style.css | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/src/style.css b/src/style.css index e84167b..52a7cba 100644 --- a/src/style.css +++ b/src/style.css @@ -309,6 +309,18 @@ [data-slot="select-trigger"]:hover { background-color: var(--btn-secondary-overlay); } + /* Opt-in hover escape hatch: data-hover-lighten flips JUST this trigger to a + white overlay. The default dark hover is a pure-black fill (darken) — a + deliberate aesthetic — but it is invisible on the near-black app canvas + (--background ≈ RGB 17 offers no downward range). Call sites whose trigger + sits directly on the canvas (onboarding) set this attribute; triggers on + lighter surfaces keep the darken. TEMPORARY call-site distinction: the + surface-aware polarity question (lighten vs darken per surface) is owned + by the upcoming design-system refactor, not by sprinkling this attribute + wider. No-op in light, where the token equals the default fill. */ + [data-slot="select-trigger"][data-hover-lighten]:hover { + background-color: var(--select-trigger-hover-lighten); + } /* No focus ring: reka returns DOM focus to the trigger after a mouse pick, and the browser then paints :focus-visible — which left a near-black ring stuck on the closed trigger ("triggered" look). The resting hairline plus @@ -1422,6 +1434,9 @@ secondary button shell; segmented items). Black in light mode; the .dark block flips the segmented ones to white so they lighten instead. */ --btn-secondary-overlay: oklch(0 0 0 / 0.12); + /* Light: the opt-in lighten variant is identical to the default — the + attribute is a dark-only escape hatch, a no-op here by design. */ + --select-trigger-hover-lighten: oklch(0 0 0 / 0.12); --segment-overlay-hover: oklch(0 0 0 / 0.05); --segment-overlay-active: oklch(0 0 0 / 0.08); /* Segmented idle / hover label — lighter than global muted for an airier read; @@ -1725,6 +1740,10 @@ /* Dark: secondary button hover — pure black fill. Border (--border-hairline) is restored by the .dark override above, so the button shape stays clear. */ --btn-secondary-overlay: oklch(0 0 0); + /* Dark: the opt-in LIGHTEN hover (see the data-hover-lighten rule at the + select-trigger styles). Only meaningfully different from the default on + the near-black app canvas, where the black fill has no downward range. */ + --select-trigger-hover-lighten: oklch(1 0 0 / 0.08); /* Dark: destructive ghost hover — warmer translucent red, brighter than before. */ --btn-destructive-hover-bg: oklch(0.36 0.12 25 / 0.55); --btn-destructive-hover-text: oklch(0.80 0.18 25);