fix(ui): 下拉框贴合选择框并修正宽度与裁剪

This commit is contained in:
TermiNexus committed 2026-10-26 19:26:05 +08:00
1 parent 82939dd772
commit 781ad113cf
2 files changed
+29 -7

No files matched your search

+1 -1
View File
@@ -68,6 +68,6 @@
## 5. 当前仍为近似
- 设置行的组合方式:已按 `rowBlock` / `dropDownTitle` / `slider` / `CheckBoxComponentStyle` 的尺寸重建,但原版每个设置项的具体子组件层级仍需继续展开。
- 下拉选项弹层:已按 `DropDownStyle` + `ContextMenuStyle` 还原菜单/选项高度、背景、hover、选中色;定位仍用 `top:100%`,原版用 `position` 计算屏幕内位置。
- 下拉选项弹层:已按 `DropDownStyle` + `ContextMenuStyle` 还原菜单/选项高度、背景、hover、选中色;使用 `position:fixed` + 控件 `getBoundingClientRect()`,宽度等于选择框、紧贴下沿,避免被设置面板滚动容器裁剪。
- 菜单滑动条:当前按 `index * 5em + 1.25em` 计算,原版由组件状态计算 `margin-top`。
- 部分设置项的分组/顺序仍以官方 key 和现有状态为准,后续可继续按原组件 render 树核对。
@@ -2292,10 +2292,7 @@ private val SettingsSelect: csstype.PropertiesBuilder.() -> Unit = {
}
private val SettingsDropdownList: csstype.PropertiesBuilder.() -> Unit = {
Style("position", "absolute")
Style("left", "0")
Style("top", "100%")
Style("min-width", "18.25em")
Style("position", "fixed")
Style("max-height", "15.75em")
Style("overflow", "auto")
Style("z-index", "999")
@@ -2306,6 +2303,13 @@ private val SettingsDropdownList: csstype.PropertiesBuilder.() -> Unit = {
Style("flex-direction", "column")
Style("align-items", "stretch")
Style("justify-content", "flex-start")
Style("box-sizing", "border-box")
}
private val SettingsDropdownOverlay: csstype.PropertiesBuilder.() -> Unit = {
Style("position", "fixed")
Style("inset", "0")
Style("z-index", "998")
}
private val SettingsDropdownOption: csstype.PropertiesBuilder.() -> Unit = {
@@ -2507,6 +2511,9 @@ private val SettingsScreen = FC<Props> {
var Sliders by useState<Map<String, Int>>(emptyMap())
var Choices by useState<Map<String, Int>>(emptyMap())
var OpenChoice by useState<String?>(null)
var DropdownLeft by useState(0.0)
var DropdownTop by useState(0.0)
var DropdownWidth by useState(0.0)
val UserName = StateOrNull()?.User?.Uid ?: ""
val Tabs = SettingsTabLabels()
val Entries = SettingsEntries(Tab, UserName)
@@ -2625,13 +2632,28 @@ private val SettingsScreen = FC<Props> {
div { css(SettingsDropTitle); +Entry.Label }
div {
css(SettingsSelect)
onClick = { OpenChoice = if (OpenChoice == Entry.Id) null else Entry.Id }
onClick = { E ->
val Rect = E.currentTarget.asDynamic().getBoundingClientRect()
DropdownLeft = (Rect.left as? Number)?.toDouble() ?: 0.0
DropdownTop = (Rect.bottom as? Number)?.toDouble() ?: 0.0
DropdownWidth = (Rect.width as? Number)?.toDouble() ?: 0.0
OpenChoice = if (OpenChoice == Entry.Id) null else Entry.Id
}
span { +Entry.Options.getOrElse(Index) { Entry.Options.firstOrNull() ?: "" } }
div { css(SettingsChevron) }
}
if (OpenChoice == Entry.Id) {
div {
css(SettingsDropdownList)
css(SettingsDropdownOverlay)
onClick = { OpenChoice = null }
}
div {
css {
Apply(SettingsDropdownList)
Style("left", "${DropdownLeft}px")
Style("top", "${DropdownTop}px")
Style("width", "${DropdownWidth}px")
}
for ((OptionIndex, Option) in Entry.Options.withIndex()) {
button {
val OptionBase = SettingsDropdownOption