LangSelect dropdown: fixed position, unclipped by the editor panel
This commit is contained in:
@@ -13,10 +13,22 @@ const props = defineProps({
|
|||||||
const emit = defineEmits(['update:modelValue'])
|
const emit = defineEmits(['update:modelValue'])
|
||||||
|
|
||||||
const open = ref(false)
|
const open = ref(false)
|
||||||
|
const toggleBtn = ref(null)
|
||||||
|
const popStyle = ref({})
|
||||||
const current = computed(
|
const current = computed(
|
||||||
() => props.options.find((o) => o.tag === props.modelValue) ?? props.options[0],
|
() => 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) {
|
function select(tag) {
|
||||||
emit('update:modelValue', tag)
|
emit('update:modelValue', tag)
|
||||||
open.value = false
|
open.value = false
|
||||||
@@ -26,15 +38,16 @@ function select(tag) {
|
|||||||
<template>
|
<template>
|
||||||
<span v-if="options.length > 1" class="lang-select">
|
<span v-if="options.length > 1" class="lang-select">
|
||||||
<button
|
<button
|
||||||
|
ref="toggleBtn"
|
||||||
type="button"
|
type="button"
|
||||||
class="lang-current"
|
class="lang-current"
|
||||||
:class="{ open }"
|
:class="{ open }"
|
||||||
:title="title || (current
|
:title="title || (current
|
||||||
? `language: ${current.name}${current.primary ? ' (primary)' : ''}`
|
? `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="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
|
<button
|
||||||
v-for="o in options"
|
v-for="o in options"
|
||||||
:key="o.code"
|
:key="o.code"
|
||||||
@@ -69,11 +82,11 @@ function select(tag) {
|
|||||||
border-color: var(--line);
|
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 {
|
.lang-pop {
|
||||||
position: absolute;
|
position: fixed;
|
||||||
top: 100%;
|
|
||||||
left: 0;
|
|
||||||
z-index: 20;
|
z-index: 20;
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
|
|||||||
Reference in New Issue
Block a user