fix(ui): 下拉框贴合选择框并修正宽度与裁剪
This commit is contained in:
1 parent
82939dd772
commit
781ad113cf
2 files changed
+29
-7
No files matched your search
@@ -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
|
||||
|
||||
Reference in new issue
Block a user