refactor: replace NestedPopover with Popover component across multiple files

(cherry picked from commit 38b6674cc134a2cffa907c03dbdfce9b7c916e01)
This commit is contained in:
Shariq Ansari 2025-08-18 15:02:05 +05:30 committed by Mergify
parent d0dc642b12
commit 7b2168232e
8 changed files with 43 additions and 102 deletions

View File

@ -1,7 +1,7 @@
<template>
<NestedPopover>
<template #target>
<div class="flex items-center">
<Popover placement="bottom-end">
<template #target="{ togglePopover }">
<div class="flex items-center" @click="togglePopover">
<component
v-if="assignees?.length"
:is="assignees?.length == 1 ? 'Button' : 'div'"
@ -11,24 +11,23 @@
<Button v-else :label="__('Assign to')" />
</div>
</template>
<template #body="{ open }">
<template #body="{ isOpen }">
<AssignToBody
v-show="open"
v-show="isOpen"
v-model="assignees"
:docname="docname"
:doctype="doctype"
:open="open"
:open="isOpen"
:onUpdate="ownerField && saveAssignees"
/>
</template>
</NestedPopover>
</Popover>
</template>
<script setup>
import NestedPopover from '@/components/NestedPopover.vue'
import MultipleAvatar from '@/components/MultipleAvatar.vue'
import AssignToBody from '@/components/AssignToBody.vue'
import { useDocument } from '@/data/document'
import { toast } from 'frappe-ui'
import { toast, Popover } from 'frappe-ui'
import { computed } from 'vue'
const props = defineProps({

View File

@ -1,7 +1,7 @@
<template>
<NestedPopover>
<template #target>
<Button :label="__('Columns')">
<Popover placement="bottom-end">
<template #target="{ togglePopover }">
<Button :label="__('Columns')" @click="togglePopover">
<template v-if="hideLabel">
<ColumnsIcon class="h-4" />
</template>
@ -67,7 +67,7 @@
variant="ghost"
:label="__('Add Column')"
iconLeft="plus"
@click="togglePopover()"
@click="togglePopover"
/>
</template>
</Autocomplete>
@ -135,7 +135,7 @@
</div>
</div>
</template>
</NestedPopover>
</Popover>
</template>
<script setup>
@ -143,9 +143,8 @@ import ColumnsIcon from '@/components/Icons/ColumnsIcon.vue'
import EditIcon from '@/components/Icons/EditIcon.vue'
import DragIcon from '@/components/Icons/DragIcon.vue'
import ReloadIcon from '@/components/Icons/ReloadIcon.vue'
import NestedPopover from '@/components/NestedPopover.vue'
import Autocomplete from '@/components/frappe-ui/Autocomplete.vue'
import { isTouchScreenDevice } from '@/utils'
import { Autocomplete, Popover } from 'frappe-ui'
import Draggable from 'vuedraggable'
import { computed, ref } from 'vue'
import { watchOnce } from '@vueuse/core'

View File

@ -1,11 +1,12 @@
<template>
<NestedPopover>
<template #target>
<Popover placement="bottom-end">
<template #target="{ togglePopover, close }">
<div class="flex items-center">
<Button
:label="__('Filter')"
:class="filters?.size ? 'rounded-r-none' : ''"
:iconLeft="FilterIcon"
@click="togglePopover"
>
<template v-if="filters?.size" #suffix>
<div
@ -20,7 +21,7 @@
:tooltip="__('Clear all Filter')"
class="rounded-l-none border-l"
icon="x"
@click.stop="clearfilter(false)"
@click.stop="clearfilter(close)"
/>
</div>
</template>
@ -149,17 +150,16 @@
</div>
</div>
</template>
</NestedPopover>
</Popover>
</template>
<script setup>
import NestedPopover from '@/components/NestedPopover.vue'
import FilterIcon from '@/components/Icons/FilterIcon.vue'
import Link from '@/components/Controls/Link.vue'
import Autocomplete from '@/components/frappe-ui/Autocomplete.vue'
import {
FormControl,
createResource,
Tooltip,
Popover,
DatePicker,
DateTimePicker,
DateRangePicker,
@ -480,7 +480,7 @@ function removeFilter(index) {
function clearfilter(close) {
filters.value.clear()
apply()
close && close()
close()
}
function updateValue(value, filter) {

View File

@ -69,7 +69,7 @@
</Popover>
</template>
<script setup>
import Popover from '@/components/frappe-ui/Popover.vue'
import { Popover } from 'frappe-ui'
import { gemoji } from 'gemoji'
import { ref, computed } from 'vue'

View File

@ -15,17 +15,18 @@
>
<div class="flex gap-2 items-center group justify-between">
<div class="flex items-center text-base">
<NestedPopover>
<template #target>
<Popover>
<template #target="{ togglePopover }">
<Button
variant="ghost"
size="sm"
class="hover:!bg-surface-gray-2"
@click="togglePopover"
>
<IndicatorIcon :class="parseColor(column.column.color)" />
</Button>
</template>
<template #body="{ close }">
<template #body>
<div
class="flex flex-col gap-3 px-3 py-2.5 min-w-40 rounded-lg bg-surface-modal shadow-2xl ring-1 ring-black ring-opacity-5 focus:outline-none"
>
@ -48,7 +49,7 @@
</div>
</div>
</template>
</NestedPopover>
</Popover>
<div class="text-ink-gray-9">{{ column.column.name }}</div>
</div>
<div class="flex">
@ -164,11 +165,10 @@
</template>
<script setup>
import Autocomplete from '@/components/frappe-ui/Autocomplete.vue'
import NestedPopover from '@/components/NestedPopover.vue'
import IndicatorIcon from '@/components/Icons/IndicatorIcon.vue'
import { isTouchScreenDevice, colors, parseColor } from '@/utils'
import Draggable from 'vuedraggable'
import { Dropdown } from 'frappe-ui'
import { Dropdown, Popover } from 'frappe-ui'
import { computed } from 'vue'
const props = defineProps({

View File

@ -1,60 +0,0 @@
<template>
<Popover v-slot="{ open }">
<PopoverButton
as="div"
ref="reference"
@click="updatePosition"
@focusin="updatePosition"
@keydown="updatePosition"
v-slot="{ open }"
>
<slot name="target" v-bind="{ open }" />
</PopoverButton>
<div v-show="open">
<PopoverPanel
v-slot="{ open, close }"
ref="popover"
static
class="z-[100]"
>
<slot name="body" v-bind="{ open, close }" />
</PopoverPanel>
</div>
</Popover>
</template>
<script setup>
import { Popover, PopoverButton, PopoverPanel } from '@headlessui/vue'
import { createPopper } from '@popperjs/core'
import { nextTick, ref, onBeforeUnmount } from 'vue'
const props = defineProps({
placement: {
type: String,
default: 'bottom-start',
},
})
const reference = ref(null)
const popover = ref(null)
let popper = ref(null)
function setupPopper() {
if (!popper.value) {
popper.value = createPopper(reference.value.el, popover.value.el, {
placement: props.placement,
})
} else {
popper.value.update()
}
}
function updatePosition() {
nextTick(() => setupPopper())
}
onBeforeUnmount(() => {
popper.value?.destroy()
})
</script>

View File

@ -80,11 +80,12 @@
</Tooltip>
</div>
<div v-else-if="field.fieldtype === 'Dropdown'">
<NestedPopover>
<template #target="{ open }">
<Popover>
<template #target="{ isOpen, togglePopover }">
<Button
:label="doc[field.fieldname]"
class="dropdown-button flex w-full items-center justify-between rounded border border-gray-100 bg-surface-gray-2 px-2 py-1.5 text-base text-ink-gray-8 placeholder-ink-gray-4 transition-colors hover:border-outline-gray-modals hover:bg-surface-gray-3 focus:border-outline-gray-4 focus:bg-surface-white focus:shadow-sm focus:outline-none focus:ring-0 focus-visible:ring-2 focus-visible:ring-outline-gray-3"
@click="togglePopover"
>
<div
v-if="doc[field.fieldname]"
@ -100,7 +101,9 @@
</div>
<template #suffix>
<FeatherIcon
:name="open ? 'chevron-up' : 'chevron-down'"
:name="
isOpen ? 'chevron-up' : 'chevron-down'
"
class="h-4 text-ink-gray-5"
/>
</template>
@ -138,7 +141,7 @@
</div>
</div>
</template>
</NestedPopover>
</Popover>
</div>
<FormControl
v-else-if="field.fieldtype == 'Check'"
@ -363,7 +366,6 @@
import Password from '@/components/Controls/Password.vue'
import FormattedInput from '@/components/Controls/FormattedInput.vue'
import Section from '@/components/Section.vue'
import NestedPopover from '@/components/NestedPopover.vue'
import DropdownItem from '@/components/DropdownItem.vue'
import FadedScrollableDiv from '@/components/FadedScrollableDiv.vue'
import ArrowUpRightIcon from '@/components/Icons/ArrowUpRightIcon.vue'
@ -376,7 +378,7 @@ import { usersStore } from '@/stores/users'
import { isMobileView } from '@/composables/settings'
import { getFormat, evaluateDependsOnValue } from '@/utils'
import { flt } from '@/utils/numberFormat.js'
import { Tooltip, DateTimePicker, DatePicker } from 'frappe-ui'
import { Tooltip, DateTimePicker, DatePicker, Popover } from 'frappe-ui'
import { useDocument } from '@/data/document'
import { ref, computed, getCurrentInstance } from 'vue'

View File

@ -17,13 +17,14 @@
</Button>
</template>
</Autocomplete>
<NestedPopover v-else>
<template #target="{ open }">
<Popover placement="bottom-end" v-else>
<template #target="{ isOpen, togglePopover }">
<Button
v-if="sortValues.size > 1"
:label="__('Sort')"
:icon="hideLabel && SortIcon"
:iconLeft="!hideLabel && SortIcon"
@click="togglePopover"
>
<template v-if="sortValues?.size" #suffix>
<div
@ -55,9 +56,10 @@
class="shrink-0 [&_svg]:text-ink-gray-5"
:iconLeft="!hideLabel && !sortValues?.size && SortIcon"
:iconRight="
sortValues?.size && (open ? 'chevron-up' : 'chevron-down')
sortValues?.size && (isOpen ? 'chevron-up' : 'chevron-down')
"
:class="sortValues.size ? 'rounded-l-none' : ''"
@click.stop="togglePopover"
/>
</div>
</template>
@ -155,18 +157,17 @@
</div>
</div>
</template>
</NestedPopover>
</Popover>
</template>
<script setup>
import AscendingIcon from '@/components/Icons/AscendingIcon.vue'
import DesendingIcon from '@/components/Icons/DesendingIcon.vue'
import NestedPopover from '@/components/NestedPopover.vue'
import SortIcon from '@/components/Icons/SortIcon.vue'
import DragIcon from '@/components/Icons/DragIcon.vue'
import Autocomplete from '@/components/frappe-ui/Autocomplete.vue'
import { useSortable } from '@vueuse/integrations/useSortable'
import { createResource } from 'frappe-ui'
import { createResource, Popover } from 'frappe-ui'
import { computed, nextTick, onMounted } from 'vue'
const props = defineProps({