fix(modal): kebab menus weren't opening (chip + suggestion rows)
Operator-flagged 2026-06-02. Both kebab activators were broken: - TagPanel chip kebab had `@click.stop` directly on the v-icon activator. In Vue 3, an explicit @click on the same element as `v-bind="props"` overrides the spread onClick — so Vuetify's activator handler never fired. Menu never opened. - SuggestionItem kebab didn't have @click.stop, but for consistency and to make both kebabs follow the same shape, wrap it too. The fix: each kebab is now wrapped in a `<span @click.stop>`. The v-icon / v-btn receives Vuetify's onClick cleanly and opens the menu; the bubbling click then reaches the span where stopPropagation absorbs it before it can affect a parent (the v-chip's close button in TagPanel's case).
This commit is contained in:
@@ -19,25 +19,34 @@
|
|||||||
>
|
>
|
||||||
Accept
|
Accept
|
||||||
</v-btn>
|
</v-btn>
|
||||||
<v-menu>
|
<!-- Operator-flagged 2026-06-02: the kebab menu wasn't opening.
|
||||||
<template #activator="{ props }">
|
Wrapping in a <span @click.stop> matches the TagPanel chip
|
||||||
<v-btn
|
fix — even though there's no parent click capture here today,
|
||||||
class="fc-suggestion__menu"
|
the wrap is harmless and keeps both kebabs on the same
|
||||||
icon="mdi-dots-vertical" size="small"
|
pattern. Click bubbles from the v-btn → opens menu via
|
||||||
variant="outlined" density="compact"
|
activator props → bubble continues to span → stopPropagation
|
||||||
:aria-label="`More actions for ${suggestion.display_name}`"
|
halts it. -->
|
||||||
v-bind="props"
|
<span class="fc-suggestion__menu-wrap" @click.stop>
|
||||||
/>
|
<v-menu>
|
||||||
</template>
|
<template #activator="{ props }">
|
||||||
<v-list density="compact">
|
<v-btn
|
||||||
<v-list-item @click="$emit('alias', suggestion)">
|
class="fc-suggestion__menu"
|
||||||
<v-list-item-title>Treat as alias for…</v-list-item-title>
|
icon="mdi-dots-vertical" size="small"
|
||||||
</v-list-item>
|
variant="outlined" density="compact"
|
||||||
<v-list-item @click="$emit('dismiss', suggestion)">
|
:aria-label="`More actions for ${suggestion.display_name}`"
|
||||||
<v-list-item-title>Dismiss for this image</v-list-item-title>
|
v-bind="props"
|
||||||
</v-list-item>
|
/>
|
||||||
</v-list>
|
</template>
|
||||||
</v-menu>
|
<v-list density="compact">
|
||||||
|
<v-list-item @click="$emit('alias', suggestion)">
|
||||||
|
<v-list-item-title>Treat as alias for…</v-list-item-title>
|
||||||
|
</v-list-item>
|
||||||
|
<v-list-item @click="$emit('dismiss', suggestion)">
|
||||||
|
<v-list-item-title>Dismiss for this image</v-list-item-title>
|
||||||
|
</v-list-item>
|
||||||
|
</v-list>
|
||||||
|
</v-menu>
|
||||||
|
</span>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
@@ -90,6 +99,11 @@ const scorePct = computed(() => `${Math.round(props.suggestion.score * 100)}%`)
|
|||||||
.fc-suggestion__accept :deep(.v-btn__content) {
|
.fc-suggestion__accept :deep(.v-btn__content) {
|
||||||
font-size: 12px; letter-spacing: 0.02em;
|
font-size: 12px; letter-spacing: 0.02em;
|
||||||
}
|
}
|
||||||
|
.fc-suggestion__menu-wrap {
|
||||||
|
flex: 0 0 auto;
|
||||||
|
display: inline-flex;
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
.fc-suggestion__menu {
|
.fc-suggestion__menu {
|
||||||
flex: 0 0 auto;
|
flex: 0 0 auto;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -113,4 +113,5 @@ async function onRenamed() {
|
|||||||
margin-bottom: 12px;
|
margin-bottom: 12px;
|
||||||
}
|
}
|
||||||
.fc-tag-panel__chips { display: flex; flex-wrap: wrap; gap: 6px; }
|
.fc-tag-panel__chips { display: flex; flex-wrap: wrap; gap: 6px; }
|
||||||
|
.kebab-wrap { display: inline-flex; align-items: center; }
|
||||||
</style>
|
</style>
|
||||||
|
|||||||
Reference in New Issue
Block a user