From 59a79b0063da307cf6871524023064d0863c9b2d Mon Sep 17 00:00:00 2001 From: JOJO <1498581755@qq.com> Date: Sun, 31 May 2026 09:30:46 +0800 Subject: [PATCH] fix(web): align slash menu spacing, corners, and scroll step - Add bottom padding so the last option has a gap below it - Size max-height for 5 rows + 6 gaps (incl. border) so all 5 show - Equalize side/row gaps at 5px and make first-item corners concentric - Read row height + gap from CSS vars in scroll logic instead of hardcoded 41px Co-Authored-By: Claude Opus 4.8 (1M context) --- static/src/components/input/InputComposer.vue | 6 +++++- .../styles/components/input/_composer.scss | 19 ++++++++++++++----- 2 files changed, 19 insertions(+), 6 deletions(-) diff --git a/static/src/components/input/InputComposer.vue b/static/src/components/input/InputComposer.vue index d70c2aa..bab8f7c 100644 --- a/static/src/components/input/InputComposer.vue +++ b/static/src/components/input/InputComposer.vue @@ -542,7 +542,11 @@ const scrollSkillSlashSelectionIntoMiddle = () => { nextTick(() => { const list = skillSlashList.value; if (!list) return; - const rowHeight = 41; + const styles = getComputedStyle(list); + const cssRowHeight = parseFloat(styles.getPropertyValue('--skill-slash-row-height')); + const cssGap = parseFloat(styles.getPropertyValue('--skill-slash-gap')); + const rowHeight = (Number.isFinite(cssRowHeight) ? cssRowHeight : 38) + + (Number.isFinite(cssGap) ? cssGap : 5); const visibleRows = Math.max(1, Math.floor(list.clientHeight / rowHeight) || 5); const middleOffset = Math.floor(visibleRows / 2); const maxScroll = Math.max(0, list.scrollHeight - list.clientHeight); diff --git a/static/src/styles/components/input/_composer.scss b/static/src/styles/components/input/_composer.scss index 9034fb3..6875eb3 100644 --- a/static/src/styles/components/input/_composer.scss +++ b/static/src/styles/components/input/_composer.scss @@ -124,7 +124,9 @@ .skill-slash-menu { --skill-slash-row-height: 38px; - --skill-slash-gap: 3px; + --skill-slash-gap: 5px; + --skill-slash-radius: 12px; + --skill-slash-pad-x: 5px; --skill-slash-motion-duration: 300ms; --skill-slash-motion-easing: cubic-bezier(0.25, 0.8, 0.25, 1); --skill-slash-visible-rows: 5; @@ -138,17 +140,18 @@ box-sizing: border-box; max-height: calc( (var(--skill-slash-row-height) * var(--skill-slash-visible-rows)) + - (var(--skill-slash-gap) * (var(--skill-slash-visible-rows) + 1)) + (var(--skill-slash-gap) * (var(--skill-slash-visible-rows) + 1)) + + 2px ); overflow-y: auto; border: 1px solid var(--claude-border); - border-top-left-radius: 12px; - border-top-right-radius: 12px; + border-top-left-radius: var(--skill-slash-radius); + border-top-right-radius: var(--skill-slash-radius); background: rgba(255, 255, 255, 0.98); box-shadow: none; pointer-events: auto; scrollbar-width: none; - padding: var(--skill-slash-gap) 7px; + padding: var(--skill-slash-gap) var(--skill-slash-pad-x); display: flex; flex-direction: column; gap: var(--skill-slash-gap); @@ -197,6 +200,12 @@ cursor: pointer; } +.skill-slash-item:first-child { + /* 间隙四周相等(5px),与菜单外圆角同心:内圆角 = 外圆角 − 间隙 */ + border-top-left-radius: calc(var(--skill-slash-radius) - var(--skill-slash-gap)); + border-top-right-radius: calc(var(--skill-slash-radius) - var(--skill-slash-gap)); +} + .skill-slash-item:hover, .skill-slash-item--active { background: rgba(118, 103, 84, 0.12);