Files
speckle-server/packages/frontend-2/components/viewer/contextMenu/ContextMenu.vue
T
andrewwallacespeckle ee85634037 Remove unused ref
2025-08-19 10:11:23 +01:00

66 lines
1.9 KiB
Vue

<template>
<div
v-if="shouldShowContextMenu"
class="absolute pointer-events-auto z-50"
:style="contextMenuState.style"
>
<div
class="w-44 origin-top-right divide-y divide-outline-3 rounded-md bg-foundation shadow-lg border border-outline-2"
>
<div
v-for="(group, groupIndex) in contextMenuItems"
:key="groupIndex"
class="p-1"
>
<button
v-for="item in group"
:key="item.id"
:disabled="item.disabled || false"
:class="buildButtonClasses(item)"
@click="onItemChosen({ item })"
>
<Component :is="item.icon" v-if="item.icon" class="h-4 w-4" />
<div class="grow">{{ item.title }}</div>
</button>
</div>
</div>
</div>
<div v-else />
</template>
<script setup lang="ts">
import type { Nullable } from '@speckle/shared'
import type { LayoutMenuItem } from '~~/lib/layout/helpers/components'
import { useViewerContextMenu } from '~~/lib/viewer/composables/contextMenu'
const props = defineProps<{
parentEl: Nullable<HTMLElement>
}>()
const isOpen = defineModel<boolean>('open', { default: false })
const { contextMenuState, contextMenuItems, shouldShowContextMenu, onItemChosen } =
useViewerContextMenu({
parentEl: toRef(() => props.parentEl),
isOpen
})
const buildButtonClasses = (item: LayoutMenuItem) => {
const classParts = [
'group flex space-x-2 w-full items-center rounded-md px-2 py-1 text-body-xs text-left'
]
if (item.disabled) {
classParts.push('opacity-40 cursor-not-allowed')
} else if (item.color === 'danger') {
classParts.push('text-danger hover:bg-danger hover:text-foreground-on-primary')
} else if (item.color === 'info') {
classParts.push('text-info hover:bg-info hover:text-foreground-on-primary')
} else {
classParts.push('text-foreground hover:bg-primary-muted')
}
return classParts.join(' ')
}
</script>