fix(ui): regression in submenu functionality; layout of low-height input

This commit is contained in:
upsiflu 2025-03-09 13:07:38 +01:00
parent bd6eecbaba
commit 0101d6cf1e
8 changed files with 48 additions and 45 deletions

View File

@ -117,7 +117,7 @@ const model = defineModel<string|number>({ required: true })
class="input-right show-password"
title="toggle visibility"
@click="showPassword = !showPassword"
@blur="(e) => { console.log(e.relatedTarget); if (e.relatedTarget && 'value' in e.relatedTarget && e.relatedTarget.value === model) showPassword = showPassword; else showPassword = false; }"
@blur="(e) => { if (e.relatedTarget && 'value' in e.relatedTarget && e.relatedTarget.value === model) showPassword = showPassword; else showPassword = false; }"
>
<i class="bi bi-eye" />
</button>

View File

@ -19,7 +19,7 @@ const columnWidth = props.columnWidth ?? '46px'
const maybeGap = Object.entries(props).find(
([key, value]) => value === true && key.startsWith('gap'))
const gapWidth = maybeGap ? `${maybeGap[0].replace('gap', '')}px` : '32px'
const gapWidth = maybeGap ? `${maybeGap[0].replace('gap', '').replace('-', '')}px` : '32px'
const attributes = computed(() => ({
...color(props)(width(props)()),

View File

@ -12,7 +12,7 @@ import { type ColorProps, type DefaultProps, type RaisedProps, color } from '~/c
*/
const open = defineModel<boolean>({ default: false })
const isOpen = defineModel<boolean>({ default: false })
const { positioning = 'vertical', ...colorProps } = defineProps<{
positioning?:'horizontal' | 'vertical'
@ -27,13 +27,13 @@ const inSlot = ref()
const mobileClickOutside = (event: MouseEvent) => {
const inPopover = !!(event.target as HTMLElement).closest('.funkwhale.popover')
if (isMobile.value && !inPopover) {
open.value = false
isOpen.value = false
}
}
onClickOutside(popover, async (event) => {
const inPopover = !!(event.target as HTMLElement).closest('.funkwhale.popover')
if (!isMobile.value && !inPopover) {
open.value = false
isOpen.value = false
}
}, { ignore: [slot] })
@ -44,7 +44,7 @@ const { width: popoverWidth, height: popoverHeight } = useElementBounding(popove
windowScroll: false
})
whenever(open, update, { immediate: true })
whenever(isOpen, update, { immediate: true })
const { width: screenWidth, height: screenHeight } = useScreenSize()
@ -93,9 +93,9 @@ if (!stack) {
provide(POPOVER_INJECTION_KEY, stack = shallowReactive([]))
}
stack.push(open)
stack.push(isOpen)
onScopeDispose(() => {
stack?.splice(stack.indexOf(open), 1)
stack?.splice(stack.indexOf(isOpen), 1)
})
// Provide context for child items
@ -107,14 +107,14 @@ provide(POPOVER_CONTEXT_INJECTION_KEY, {
// Closing
const closeChild = () => {
const ref = stack?.[stack.indexOf(open) + 1]
const ref = stack?.[stack.indexOf(isOpen) + 1]
if (!ref) return
ref.value = false
}
// Recursively close popover tree
watch(open, (isOpen) => {
watch(isOpen, (isOpen) => {
if (isOpen) return
closeChild()
})
@ -128,15 +128,15 @@ watch(open, (isOpen) => {
>
<slot
ref="inSlot"
:is-open="open"
:toggle-open="() => open = !open"
:open="() => open = true"
:close="() => open = false"
:is-open="isOpen"
:toggle-open="() => isOpen = !isOpen"
:open="() => isOpen = true"
:close="() => isOpen = false"
/>
</div>
<teleport
v-if="open"
v-if="isOpen"
to="body"
>
<div

View File

@ -62,7 +62,7 @@
left: 0;
bottom: 0;
height: 48px;
height: 100%;
min-width: 48px;
display: flex;
@ -80,7 +80,7 @@
position: absolute;
right: 0px;
bottom: 0px;
height: 48px;
height: 100%;
min-width: 48px;
display: flex;

View File

@ -5,7 +5,7 @@ import { POPOVER_CONTEXT_INJECTION_KEY, type PopoverContext } from '~/injection-
import Button from '~/components/ui/Button.vue'
const setId = defineEmit<[value: number]>('internal:id')
const emit = defineEmits<{ setId: [value: number] }>()
const { parentPopoverContext, to } = defineProps<{
parentPopoverContext?: PopoverContext;
@ -18,7 +18,7 @@ const { items, hoveredItem } = parentPopoverContext ?? inject(POPOVER_CONTEXT_IN
})
const id = items.value++
setId(id)
emit('setId', id)
</script>
<template>
@ -34,8 +34,9 @@ setId(id)
/>
<slot />
<div class="after" />
<div class="after">
<slot name="after" />
</div>
</a>
<RouterLink
v-else-if="to"
@ -49,13 +50,15 @@ setId(id)
/>
<slot />
<div class="after" />
<div class="after">
<slot name="after" />
</div>
</RouterLink>
<Button
v-else
ghost
thin-font
v-bind="$attrs"
style="
width: 100%;
textAlign: left;
@ -80,7 +83,6 @@ setId(id)
<style lang="scss">
.popover .popover-item {
cursor: pointer;
color: var(--color) !important;
text-decoration: none;
padding: 0px 8px;
height: 32px;
@ -116,6 +118,7 @@ setId(id)
}
span {
width: 100%;
position: relative;
i {
font-size: 14px;
}
@ -123,8 +126,13 @@ setId(id)
margin-right: 14px !important;
}
.after {
margin-right: 0px;
float: right;
position: absolute;
right: -12px;
top: 0;
height: 100%;
display: flex;
place-items: center;
gap: 8px;
}
}
}

View File

@ -10,22 +10,22 @@ const context = inject(POPOVER_CONTEXT_INJECTION_KEY, {
hoveredItem: ref(-2)
})
const open = ref(false)
const isOpen = ref(false)
const id = ref(-1)
watchEffect(() => {
open.value = context.hoveredItem.value === id.value
isOpen.value = context.hoveredItem.value === id.value
})
</script>
<template>
<Popover
v-model="open"
v-model="isOpen"
positioning="horizontal"
>
<PopoverItem
:parent-popover-context="context"
class="submenu"
@click="open = !open"
@click="isOpen = !isOpen"
@internal:id="id = $event"
>
<slot />

View File

@ -93,8 +93,3 @@ export const align = <TProps extends Partial<AlignmentProps>>(
(Object.entries(defaults)) as Entries<Partial<AlignmentProps>>
)).map(getStyle(props))
)
const trace = <T extends unknown>(a:T):T => {
console.log(a)
return a
}

View File

@ -190,7 +190,7 @@ const bcPrivacy = ref("pod");
<Popover v-model="isOpen">
<template #default="{ toggleOpen }">
<Pill
@click="(e) => {
@click="() => {
console.log('Pill clicked');
console.log('Before toggleOpen:', isOpen);
toggleOpen();
@ -397,12 +397,12 @@ To create more complex menus, you can use submenus (`PopoverSubmenu`). Submenus
```vue{10-18}
<script setup lang="ts">
const bc = ref(false)
const open = ref(false)
const isOpen = ref(false)
</script>
<template>
<Popover v-model="open">
<OptionsButton @click="open = !open" />
<Popover v-model="isOpen">
<OptionsButton @click="isOpen = !isOpen" />
<template #items>
<PopoverSubmenu>
<i class="bi bi-collection" />
@ -442,12 +442,12 @@ You can add extra items to the right hand side of a popover item by nesting them
const bc = ref(false)
const privacyChoices = ['public', 'private', 'pod']
const bcPrivacy = ref('pod')
const open = ref(false)
const isOpen = ref(false)
</script>
<template>
<Popover v-model="open">
<OptionsButton @click="open = !open" />
<Popover v-model="isOpen">
<OptionsButton @click="isOpen = !isOpen" />
<template #items>
<PopoverSubmenu>
<i class="bi bi-collection" />
@ -552,7 +552,7 @@ Here is an example of a completed menu containing all supported features.
```vue
<script setup lang="ts">
const open = ref(false);
const isOpen = ref(false);
const bc = ref(false);
const cc = ref(false);
const share = ref(false);
@ -562,8 +562,8 @@ const privacyChoices = ["private", "pod", "public"];
</script>
<template>
<Popover v-model="open">
<OptionsButton @click="open = !open" />
<Popover v-model="isOpen">
<OptionsButton @click="isOpen = !isOpen" />
<template #items>
<PopoverSubmenu>
<i class="bi bi-music-note-list" />