Command palette:
@@ -266,6 +280,32 @@ const form = reactive({
const { $toast } = useNuxtApp()
+const x = ref(0)
+const y = ref(0)
+const isContextMenuOpen = ref(false)
+const contextMenuRef = ref(null)
+
+onMounted(() => {
+ document.addEventListener('mousemove', ({ clientX, clientY }) => {
+ x.value = clientX
+ y.value = clientY
+ })
+})
+
+const virtualElement = computed(() => ({
+ getBoundingClientRect () {
+ return {
+ width: 0,
+ height: 0,
+ top: y.value,
+ right: x.value,
+ bottom: y.value,
+ left: x.value
+ }
+ },
+ contextElement: contextMenuRef.value?.$el
+}))
+
const customQuery = query => computed(() => query.value ? `${query.value} | =1` : '')
function toggleModalIsOpen () {
diff --git a/src/runtime/components/overlays/ContextMenu.vue b/src/runtime/components/overlays/ContextMenu.vue
new file mode 100644
index 00000000..d6608ebd
--- /dev/null
+++ b/src/runtime/components/overlays/ContextMenu.vue
@@ -0,0 +1,73 @@
+
+
+
+
+
+
+
diff --git a/src/runtime/composables/usePopper.ts b/src/runtime/composables/usePopper.ts
index f2b97b5d..b18b0f79 100644
--- a/src/runtime/composables/usePopper.ts
+++ b/src/runtime/composables/usePopper.ts
@@ -1,11 +1,13 @@
import { ref, onMounted, watchEffect } from 'vue'
+import type { Ref } from 'vue'
import { popperGenerator, defaultModifiers } from '@popperjs/core/lib/popper-lite'
+import type { Instance } from '@popperjs/core'
import { omitBy, isUndefined } from 'lodash-es'
import flip from '@popperjs/core/lib/modifiers/flip'
import offset from '@popperjs/core/lib/modifiers/offset'
import preventOverflow from '@popperjs/core/lib/modifiers/preventOverflow'
-const createPopper = popperGenerator({
+export const createPopper = popperGenerator({
defaultModifiers: [...defaultModifiers, offset, flip, preventOverflow]
})
@@ -16,22 +18,23 @@ export function usePopper ({
offsetSkid = 0,
placement,
strategy
-}) {
- const reference = ref(null)
- const popper = ref(null)
+}, virtualReference) {
+ const reference: Ref
= ref(null)
+ const popper: Ref = ref(null)
+ const instance: Ref = ref(null)
onMounted(() => {
watchEffect((onInvalidate) => {
if (!popper.value) { return }
- if (!reference.value) { return }
+ if (!reference.value && !virtualReference.value) { return }
const popperEl = popper.value.$el || popper.value
- const referenceEl = reference.value.$el || reference.value
+ const referenceEl = virtualReference?.value || reference.value.$el || reference.value
- if (!(referenceEl instanceof HTMLElement)) { return }
+ // if (!(referenceEl instanceof HTMLElement)) { return }
if (!(popperEl instanceof HTMLElement)) { return }
- const { destroy } = createPopper(referenceEl, popperEl, omitBy({
+ instance.value = createPopper(referenceEl, popperEl, omitBy({
placement,
strategy,
modifiers: [{
@@ -50,9 +53,9 @@ export function usePopper ({
}]
}, isUndefined))
- onInvalidate(destroy)
+ onInvalidate(instance.value.destroy)
})
})
- return [reference, popper]
+ return [reference, popper, instance]
}
diff --git a/src/runtime/presets/default.ts b/src/runtime/presets/default.ts
index 8c9e4551..0d0cec6f 100644
--- a/src/runtime/presets/default.ts
+++ b/src/runtime/presets/default.ts
@@ -503,6 +503,21 @@ export default (variantColors: string[]) => {
}
}
+ const contextMenu = {
+ wrapper: 'relative',
+ container: 'z-20',
+ width: '',
+ base: '',
+ transition: {
+ enterActiveClass: 'transition ease-out duration-200',
+ enterFromClass: 'opacity-0 translate-y-1',
+ enterToClass: 'opacity-100 translate-y-0',
+ leaveActiveClass: 'transition ease-in duration-150',
+ leaveFromClass: 'opacity-100 translate-y-0',
+ leaveToClass: 'opacity-0 translate-y-1'
+ }
+ }
+
return {
card,
modal,
@@ -527,6 +542,7 @@ export default (variantColors: string[]) => {
slideover,
notification,
tooltip,
- popover
+ popover,
+ contextMenu
}
}