mirror of
https://github.com/we-promise/sure.git
synced 2026-04-10 15:54:48 +00:00
feat(select): improve merchant dropdown behavior and placement controls (#1364)
* feat(select): improve merchant dropdown behavior and placement controls - add configurable menu_placement strategy to DS::Select (auto/down/up) with safe normalization forward menu_placement through StyledFormBuilder#collection_select - force Merchant dropdown to open downward in transaction create and editor forms - fix select option/search text contrast by applying text-primary in DS select menu - prevent form jump on open by scrolling only inside dropdown content instead of using scrollIntoView - clamp internal dropdown scroll to valid bounds for stability - refactor select controller placement logic for readability (placementMode, clamp) without changing behavior * set menu_placement=auto for metchant selector
This commit is contained in:
@@ -2,9 +2,9 @@ import { Controller } from "@hotwired/stimulus"
|
||||
import { autoUpdate } from "@floating-ui/dom"
|
||||
|
||||
export default class extends Controller {
|
||||
static targets = ["button", "menu", "input"]
|
||||
static targets = ["button", "menu", "input", "content"]
|
||||
static values = {
|
||||
placement: { type: String, default: "bottom-start" },
|
||||
menuPlacement: { type: String, default: "auto" },
|
||||
offset: { type: Number, default: 6 }
|
||||
}
|
||||
|
||||
@@ -103,7 +103,25 @@ export default class extends Controller {
|
||||
|
||||
scrollToSelected() {
|
||||
const selected = this.menuTarget.querySelector(".bg-container-inset")
|
||||
if (selected) selected.scrollIntoView({ block: "center" })
|
||||
if (!selected) return
|
||||
|
||||
const container = this.hasContentTarget ? this.contentTarget : this.menuTarget
|
||||
const containerRect = container.getBoundingClientRect()
|
||||
const selectedRect = selected.getBoundingClientRect()
|
||||
const delta = selectedRect.top - containerRect.top - (container.clientHeight - selectedRect.height) / 2
|
||||
|
||||
const nextScrollTop = container.scrollTop + delta
|
||||
const maxScrollTop = Math.max(0, container.scrollHeight - container.clientHeight)
|
||||
container.scrollTop = this.clamp(nextScrollTop, 0, maxScrollTop)
|
||||
}
|
||||
|
||||
clamp(value, min, max) {
|
||||
return Math.min(max, Math.max(min, value))
|
||||
}
|
||||
|
||||
placementMode() {
|
||||
const mode = (this.menuPlacementValue || "auto").toLowerCase()
|
||||
return ["auto", "down", "up"].includes(mode) ? mode : "auto"
|
||||
}
|
||||
|
||||
handleOutsideClick(event) {
|
||||
@@ -163,7 +181,8 @@ export default class extends Controller {
|
||||
|
||||
const spaceBelow = containerRect.bottom - buttonRect.bottom
|
||||
const spaceAbove = buttonRect.top - containerRect.top
|
||||
const shouldOpenUp = spaceBelow < menuHeight && spaceAbove > spaceBelow
|
||||
const placement = this.placementMode()
|
||||
const shouldOpenUp = placement === "up" || (placement === "auto" && spaceBelow < menuHeight && spaceAbove > spaceBelow)
|
||||
|
||||
this.menuTarget.style.left = "0"
|
||||
this.menuTarget.style.width = "100%"
|
||||
|
||||
Reference in New Issue
Block a user