mirror of
https://github.com/bunkerity/bunkerweb
synced 2026-05-24 09:28:37 +00:00
fix fixed popover position + add zindex handle on fields
This commit is contained in:
parent
7965ae1828
commit
3a3ed63c36
7 changed files with 102 additions and 8 deletions
|
|
@ -252,6 +252,10 @@ body {
|
|||
@apply hover:border-gray-600 outline-none dark:border-slate-600 dark:bg-slate-700 dark:text-gray-200 focus:border-gray-300/0 dark:focus:border-gray-600/0 focus:ring-1 focus:valid:ring-green-500 focus:invalid:ring-red-500 text-sm leading-5.6 ease-in block w-full appearance-none rounded-lg border border-solid border-gray-300 bg-white bg-clip-padding px-1.5 py-1 md:px-2.5 md:py-1.5 font-normal text-gray-700 transition-all placeholder:text-gray-500 disabled:bg-gray-400 disabled:border-gray-400/0 dark:disabled:bg-gray-800 dark:disabled:border-gray-800/0 dark:disabled:text-gray-300 disabled:text-gray-700;
|
||||
}
|
||||
|
||||
.input-regular-container {
|
||||
@apply relative flex flex-col items-start;
|
||||
}
|
||||
|
||||
.invalid.input-regular,
|
||||
.invalid.input-regular:hover,
|
||||
.invalid.input-regular:focus,
|
||||
|
|
@ -374,7 +378,7 @@ body {
|
|||
}
|
||||
|
||||
.popover-container {
|
||||
@apply pointer-events-none z-10 fixed max-w-[80vw] sm:max-w-[350px] opacity-100 justify-center items-center dark:brightness-90 transition z-50 rounded-md py-3 px-5;
|
||||
@apply pointer-events-none fixed max-w-[80vw] sm:max-w-[350px] opacity-100 justify-center items-center dark:brightness-90 transition rounded-md py-3 px-5;
|
||||
}
|
||||
|
||||
.open.popover-container {
|
||||
|
|
|
|||
File diff suppressed because one or more lines are too long
|
|
@ -117,6 +117,7 @@ const checkboxEl = ref(null);
|
|||
const checkbox = reactive({
|
||||
value: props.value,
|
||||
isValid: false,
|
||||
isIndexUp: false,
|
||||
});
|
||||
|
||||
const emits = defineEmits(["inp"]);
|
||||
|
|
@ -127,6 +128,14 @@ function updateValue() {
|
|||
return checkbox.value;
|
||||
}
|
||||
|
||||
function indexUp() {
|
||||
checkbox.isIndexUp = true;
|
||||
}
|
||||
|
||||
function indexDown() {
|
||||
checkbox.isIndexUp = false;
|
||||
}
|
||||
|
||||
onMounted(() => {
|
||||
checkbox.isValid = checkboxEl.value.checkValidity();
|
||||
});
|
||||
|
|
@ -134,7 +143,12 @@ onMounted(() => {
|
|||
|
||||
<template>
|
||||
<Container
|
||||
:containerClass="`w-full p-2 md:p-3 ${props.containerClass}`"
|
||||
@focusin="indexUp()"
|
||||
@focusout="indexDown()"
|
||||
@pointerover="indexUp()"
|
||||
@pointerleave="indexDown()"
|
||||
:class="[checkbox.isIndexUp ? 'z-10' : 'z-0']"
|
||||
:containerClass="`z-0 w-full p-2 md:p-3 ${props.containerClass}`"
|
||||
:columns="props.columns"
|
||||
>
|
||||
<Header
|
||||
|
|
|
|||
|
|
@ -141,8 +141,17 @@ const date = reactive({
|
|||
|
||||
const picker = reactive({
|
||||
isOpen: false,
|
||||
isIndexUp: false,
|
||||
});
|
||||
|
||||
function indexUp() {
|
||||
picker.isIndexUp = true;
|
||||
}
|
||||
|
||||
function indexDown() {
|
||||
picker.isIndexUp = false;
|
||||
}
|
||||
|
||||
let datepicker;
|
||||
onMounted(() => {
|
||||
datepicker = flatpickr(`#${props.id}`, {
|
||||
|
|
@ -635,7 +644,12 @@ function setIndex(calendarEl, tabindex) {
|
|||
<template>
|
||||
<Container
|
||||
v-if="props.inpType === 'datepicker'"
|
||||
:containerClass="`w-full p-2 md:p-3 ${props.containerClass}`"
|
||||
@focusin="indexUp()"
|
||||
@focusout="indexDown()"
|
||||
@pointerover="indexUp()"
|
||||
@pointerleave="indexDown()"
|
||||
:class="[picker.isIndexUp ? 'z-10' : 'z-0']"
|
||||
:containerClass="`z-0 w-full p-2 md:p-3 ${props.containerClass}`"
|
||||
:columns="props.columns"
|
||||
>
|
||||
<Header
|
||||
|
|
|
|||
|
|
@ -5,7 +5,7 @@ import Container from "@components/Widget/Container.vue";
|
|||
import Header from "@components/Forms/Header/Field.vue";
|
||||
import ErrorField from "@components/Forms/Error/Field.vue";
|
||||
|
||||
/**
|
||||
/**
|
||||
@name Forms/Field/Input.vue
|
||||
@description This component is used to create a complete input field input with error handling and label.
|
||||
We can add a clipboard button to copy the input value.
|
||||
|
|
@ -146,8 +146,17 @@ const inp = reactive({
|
|||
showInp: false,
|
||||
isClipAllow: false,
|
||||
isValid: false,
|
||||
isIndexUp: false,
|
||||
});
|
||||
|
||||
function indexUp() {
|
||||
inp.isIndexUp = true;
|
||||
}
|
||||
|
||||
function indexDown() {
|
||||
inp.isIndexUp = false;
|
||||
}
|
||||
|
||||
const emits = defineEmits(["inp"]);
|
||||
|
||||
function copyClipboard() {
|
||||
|
|
@ -183,7 +192,12 @@ onMounted(() => {
|
|||
|
||||
<template>
|
||||
<Container
|
||||
:containerClass="`w-full p-2 md:p-3 ${props.containerClass}`"
|
||||
@focusin="indexUp()"
|
||||
@focusout="indexDown()"
|
||||
@pointerover="indexUp()"
|
||||
@pointerleave="indexDown()"
|
||||
:class="[inp.isIndexUp ? 'z-10' : 'z-0']"
|
||||
:containerClass="`w-full p-2 md:p-3 ${props.containerClass}`"
|
||||
:columns="props.columns"
|
||||
>
|
||||
<Header
|
||||
|
|
@ -195,7 +209,7 @@ onMounted(() => {
|
|||
:headerClass="props.headerClass"
|
||||
/>
|
||||
|
||||
<div class="relative flex flex-col items-start">
|
||||
<div class="input-regular-container">
|
||||
<input
|
||||
:tabindex="props.tabId"
|
||||
ref="inputEl"
|
||||
|
|
|
|||
|
|
@ -147,6 +147,7 @@ const select = reactive({
|
|||
: props.requiredValues.includes(props.value)
|
||||
? true
|
||||
: false,
|
||||
isIndexUp: false,
|
||||
});
|
||||
|
||||
const selectBtn = ref();
|
||||
|
|
@ -247,6 +248,14 @@ function closeOutside(e) {
|
|||
}
|
||||
}
|
||||
|
||||
function indexUp() {
|
||||
select.isIndexUp = true;
|
||||
}
|
||||
|
||||
function indexDown() {
|
||||
select.isIndexUp = false;
|
||||
}
|
||||
|
||||
// Close select dropdown when clicked outside element
|
||||
watch(select, () => {
|
||||
if (select.isOpen) {
|
||||
|
|
@ -272,7 +281,12 @@ const emits = defineEmits(["inp"]);
|
|||
|
||||
<template>
|
||||
<Container
|
||||
:containerClass="`w-full p-2 md:p-3 ${props.containerClass}`"
|
||||
@focusin="indexUp()"
|
||||
@focusout="indexDown()"
|
||||
@pointerover="indexUp()"
|
||||
@pointerleave="indexDown()"
|
||||
:class="[select.isIndexUp ? 'z-10' : 'z-0']"
|
||||
:containerClass="`z-0 w-full p-2 md:p-3 ${props.containerClass}`"
|
||||
:columns="props.columns"
|
||||
>
|
||||
<Header
|
||||
|
|
|
|||
|
|
@ -72,11 +72,45 @@ function showPopover() {
|
|||
|
||||
// Position popover relative to btn
|
||||
const popoverBtnRect = popoverBtn.value.getBoundingClientRect();
|
||||
const popoverContainerRect = popoverContainer.value.getBoundingClientRect();
|
||||
|
||||
popoverContainer.value.style.right = `${
|
||||
window.innerWidth - popoverBtnRect.left - popoverBtnRect.width
|
||||
}px`;
|
||||
|
||||
// We need to take care of parent padding and margin that will affect dropdown position but aren't calculate in rect
|
||||
const parents = [popoverBtn.value.parentElement];
|
||||
let isParent = popoverBtn.value.parentElement ? true : false;
|
||||
while (isParent) {
|
||||
parents.push(parents[parents.length - 1].parentElement);
|
||||
isParent = parents[parents.length - 1].parentElement ? true : false;
|
||||
}
|
||||
|
||||
let noRectParentHeight = 0;
|
||||
for (let i = 0; i < parents.length; i++) {
|
||||
try {
|
||||
noRectParentHeight += +window
|
||||
.getComputedStyle(parents[i], null)
|
||||
.getPropertyValue("padding-top")
|
||||
.replace("px", "");
|
||||
} catch (e) {}
|
||||
|
||||
try {
|
||||
noRectParentHeight += +window
|
||||
.getComputedStyle(parents[i], null)
|
||||
.getPropertyValue("margin-top")
|
||||
.replace("px", "");
|
||||
} catch (e) {}
|
||||
}
|
||||
|
||||
popoverContainer.value.style.top = `${
|
||||
window.scrollY +
|
||||
popoverBtnRect.top -
|
||||
noRectParentHeight -
|
||||
popoverBtnRect.height * 2 -
|
||||
80
|
||||
}px`;
|
||||
|
||||
// Show popover
|
||||
setTimeout(() => {
|
||||
popover.isOpen = popover.isHover ? true : false;
|
||||
|
|
|
|||
Loading…
Reference in a new issue