LangSelect dropdown: fixed position, unclipped by the editor panel

This commit is contained in:
2026-09-03 03:06:34 +00:00
parent fb159f0cb0
commit 87b7591bec
+19 -6
View File
@@ -13,10 +13,22 @@ const props = defineProps({
const emit = defineEmits(['update:modelValue'])
const open = ref(false)
const toggleBtn = ref(null)
const popStyle = ref({})
const current = computed(
() => props.options.find((o) => o.tag === props.modelValue) ?? props.options[0],
)
function toggle() {
open.value = !open.value
if (open.value) {
// Position: fixed so the popup overflows the scrolling editor panel
// onto the page area instead of being clipped by it.
const r = toggleBtn.value.getBoundingClientRect()
popStyle.value = { top: `${r.bottom + 2}px`, left: `${r.left}px` }
}
}
function select(tag) {
emit('update:modelValue', tag)
open.value = false
@@ -26,15 +38,16 @@ function select(tag) {
<template>
<span v-if="options.length > 1" class="lang-select">
<button
ref="toggleBtn"
type="button"
class="lang-current"
:class="{ open }"
:title="title || (current
? `language: ${current.name}${current.primary ? ' (primary)' : ''}`
: '')"
@click="open = !open"
@click="toggle"
><span v-if="current?.flag" class="flag" v-html="current.flag" /></button>
<span v-if="open" class="lang-pop" @mouseleave="open = false">
<span v-if="open" class="lang-pop" :style="popStyle" @mouseleave="open = false">
<button
v-for="o in options"
:key="o.code"
@@ -69,11 +82,11 @@ function select(tag) {
border-color: var(--line);
}
/* The dropdown matches the page's existing popups (.picker-pop look). */
/* The dropdown matches the page's existing popups (.picker-pop look).
Fixed-positioned (anchored to the toggle's viewport rect on open) so it
is not clipped by the editor panel's scrolling overflow. */
.lang-pop {
position: absolute;
top: 100%;
left: 0;
position: fixed;
z-index: 20;
display: flex;
flex-direction: column;