From 1d1b32cdd2639d80c2b16a8648d692e9135cb0ed Mon Sep 17 00:00:00 2001 From: xfy Date: Tue, 28 Jul 2026 14:53:59 +0800 Subject: [PATCH] =?UTF-8?q?fix(admin):=20FormSelect=20=E9=9D=A2=E6=9D=BF?= =?UTF-8?q?=E6=B0=B4=E5=B9=B3=E5=B1=85=E4=B8=AD=E4=BA=8E=E7=AA=84=E8=A7=A6?= =?UTF-8?q?=E5=8F=91=E5=99=A8=EF=BC=8C=E4=BF=AE=E5=A4=8D=E5=8F=8C=E5=80=8D?= =?UTF-8?q?=E4=BD=8D=E7=A7=BB?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 紧凑触发器(如「手动」73px)下面板仅左对齐,宽出部分全堆在右侧, 视觉失衡。面板改为 left-1/2 + translateX(-50%) 以触发器中心居中, 宽出部分两侧对称探出。 两个 CSS 陷阱及其解法: - select-enter 关键帧的 transform 会覆盖静态 transform,fill 结束时 位置跳变 → translateX(-50%) 烘进关键帧首尾(同 popover-enter 先例) - Tailwind v4 的 -translate-x-1/2 utility 走独立 translate 属性,与 关键帧的 transform 属性叠加成双倍位移 → 面板改用任意属性类 [transform:translateX(-50%)] 浏览器实测:紧凑面板中心偏差 -0.13px、胶囊面板 0.00px(动画播完后测量)。 --- input.css | 10 +++++++--- src/components/forms.rs | 6 +++++- 2 files changed, 12 insertions(+), 4 deletions(-) diff --git a/input.css b/input.css index 0644b82..3b787ad 100644 --- a/input.css +++ b/input.css @@ -83,15 +83,19 @@ animation: popover-enter 150ms cubic-bezier(0.22, 1, 0.36, 1) both; } - /* 下拉选择面板入场(仅垂直微移,无水平居中变换;展开方向由 transform-origin 控制) */ + /* 下拉选择面板入场。面板的水平居中用 [transform:translateX(-50%)](不用 + -translate-x-1/2 utility:Tailwind v4 的 translate utility 走独立 translate + 属性,会与此处 transform 关键帧叠加成双倍位移),关键帧 fill 值须与面板 + 静态 transform 完全一致,否则动画结束时水平位置跳变;垂直仅微移,展开 + 方向由 transform-origin 控制。 */ @keyframes select-enter { 0% { opacity: 0; - transform: translateY(-4px) scale(0.98); + transform: translateX(-50%) translateY(-4px) scale(0.98); } 100% { opacity: 1; - transform: none; + transform: translateX(-50%); } } diff --git a/src/components/forms.rs b/src/components/forms.rs index fdfffd5..60a7a68 100644 --- a/src/components/forms.rs +++ b/src/components/forms.rs @@ -110,10 +110,14 @@ pub fn FormSelect( ) -> Element { // 面板与 POPOVER_PANEL_CLASS 同源(卡片化圆角 + 阴影)。宽度取 max(触发器, // 最长选项):紧凑触发器(如“手动”)下面板仍能完整展示长选项;上限防出屏。 + // 水平以触发器中心居中:面板宽于触发器时两侧对称探出,窄触发器不失衡。 + // 居中用 [transform:translateX(-50%)] 而非 -translate-x-1/2 utility:Tailwind + // v4 的 translate utility 走独立 translate 属性,会与 select-enter 关键帧的 + // transform 叠加造成双倍位移;关键帧的 fill 值与此处 transform 完全一致。 // 定义在函数体内:模块级私有常量若仅被 wasm 门控调用点引用,会在 server // 构建下触发 dead_code。 const TRIGGER_CLASS: &str = "w-full block cursor-pointer truncate select-none text-left pl-4 pr-10 py-2 border border-paper-border rounded-2xl bg-paper-entry text-paper-primary focus:outline-none focus:border-paper-accent focus:ring-1 focus:ring-paper-accent/30 transition-colors duration-200"; - const PANEL_CLASS: &str = "absolute left-0 z-50 w-max min-w-full max-w-[calc(100vw_-_2rem)] max-h-60 overflow-y-auto rounded-2xl border border-[var(--color-paper-border)] bg-[var(--color-paper-entry)] p-1.5 shadow-lg animate-select-enter"; + const PANEL_CLASS: &str = "absolute left-1/2 z-50 w-max min-w-full max-w-[calc(100vw_-_2rem)] [transform:translateX(-50%)] max-h-60 overflow-y-auto rounded-2xl border border-[var(--color-paper-border)] bg-[var(--color-paper-entry)] p-1.5 shadow-lg animate-select-enter"; let trigger_cls = trigger_class.unwrap_or(TRIGGER_CLASS);