Skip to content

Commit

Permalink
feat(contextmenu): support item disabled
Browse files Browse the repository at this point in the history
  • Loading branch information
qianmoQ committed Nov 12, 2024
1 parent 5bc2533 commit 13f0029
Show file tree
Hide file tree
Showing 5 changed files with 108 additions and 30 deletions.
72 changes: 72 additions & 0 deletions docs/components/contextmenu.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ This document is mainly used to describe some features and usage of the ShadcnCo

- ShadcnContextMenu
- ShadcnContextMenuItem
- ShadcnContextMenuSub

## Usage

Expand Down Expand Up @@ -140,6 +141,66 @@ const onItemClick = (action) => console.log(`Clicked: ${action}`)

:::

## Disabled

::: raw

<CodeRunner title="Disabled">
<ShadcnContextMenu v-model="disabledMenu">
<template #trigger>
<div class="w-full h-32 bg-gray-100 rounded-lg flex items-center justify-center">
Right click in this area to show menu
</div>
</template>
<ShadcnContextMenuItem disabled @on-click="onItemClick('edit')">Edit</ShadcnContextMenuItem>
<ShadcnContextMenuItem @on-click="onItemClick('copy')">Copy</ShadcnContextMenuItem>
<ShadcnContextMenuSub label="More actions">
<ShadcnContextMenuItem @on-click="onItemClick('move')">Move</ShadcnContextMenuItem>
</ShadcnContextMenuSub>
<ShadcnContextMenuSub disabled label="Disabled">
<ShadcnContextMenuItem @on-click="onItemClick('duplicate')">Duplicate</ShadcnContextMenuItem>
<ShadcnContextMenuItem @on-click="onItemClick('duplicate-with-images-and-text')">Duplicate with images and text</ShadcnContextMenuItem>
</ShadcnContextMenuSub>
<ShadcnContextMenuItem @on-click="onItemClick('print')">Print</ShadcnContextMenuItem>
</ShadcnContextMenu>
</CodeRunner>

:::

::: details Show code

```vue
<template>
<ShadcnContextMenu v-model="showMenu">
<template #trigger>
<div class="w-full h-32 bg-gray-100 rounded-lg flex items-center justify-center">
Right click in this area to show menu
</div>
</template>
<ShadcnContextMenuItem disabled @on-click="onItemClick('edit')">Edit</ShadcnContextMenuItem>
<ShadcnContextMenuItem @on-click="onItemClick('copy')">Copy</ShadcnContextMenuItem>
<ShadcnContextMenuSub label="More actions">
<ShadcnContextMenuItem @on-click="onItemClick('move')">Move</ShadcnContextMenuItem>
</ShadcnContextMenuSub>
<ShadcnContextMenuSub disabled label="Disabled">
<ShadcnContextMenuItem @on-click="onItemClick('duplicate')">Duplicate</ShadcnContextMenuItem>
<ShadcnContextMenuItem @on-click="onItemClick('duplicate-with-images-and-text')">Duplicate with images and text</ShadcnContextMenuItem>
</ShadcnContextMenuSub>
<ShadcnContextMenuItem @on-click="onItemClick('print')">Print</ShadcnContextMenuItem>
</ShadcnContextMenu>
</template>
<script setup>
import { ref } from 'vue'
const showMenu = ref(false)
const onItemClick = (action) => console.log(`Clicked: ${action}`)
</script>
```

:::

## Context Menu Props

<ApiTable title="Context Menu Props"
Expand All @@ -151,10 +212,20 @@ const onItemClick = (action) => console.log(`Clicked: ${action}`)

<br />

<ApiTable title="Context Menu Item Props"
:headers="['Attribute', 'Description', 'Type', 'Default Value']"
:columns="[
['disabled', 'Whether the context menu item is disabled', 'boolean', 'false'],
]">
</ApiTable>

<br />

<ApiTable title="Context Menu Sub Props"
:headers="['Attribute', 'Description', 'Type', 'Default Value']"
:columns="[
['label', 'The label of the context menu sub item', 'string', '-'],
['disabled', 'Whether the context menu sub item is disabled', 'boolean', 'false'],
]">
</ApiTable>

Expand Down Expand Up @@ -192,6 +263,7 @@ import { ref } from 'vue'

const showMenu = ref(false)
const subMenu = ref(false)
const disabledMenu = ref(false)

const onItemClick = (action) => console.log(`Clicked: ${action}`)
</script>
28 changes: 8 additions & 20 deletions src/App.vue
Original file line number Diff line number Diff line change
Expand Up @@ -5,28 +5,16 @@
Right click in this area to show menu
</div>
</template>

<ShadcnContextMenuItem @click="onItemClick('edit')">Edit</ShadcnContextMenuItem>
<ShadcnContextMenuItem @click="onItemClick('delete')">Delete</ShadcnContextMenuItem>
<ShadcnContextMenuItem @click="onItemClick('copy')">Copy</ShadcnContextMenuItem>

<ShadcnContextMenuItem disabled @on-click="onItemClick('edit')">Edit</ShadcnContextMenuItem>
<ShadcnContextMenuItem @on-click="onItemClick('copy')">Copy</ShadcnContextMenuItem>
<ShadcnContextMenuSub label="More actions">
<ShadcnContextMenuItem @click="onItemClick('move')">Move</ShadcnContextMenuItem>
<ShadcnContextMenuItem @click="onItemClick('copy')">Copy</ShadcnContextMenuItem>
<ShadcnContextMenuItem @click="onItemClick('print')">Print</ShadcnContextMenuItem>

<ShadcnContextMenuSub>
<template #title>
<ShadcnIcon icon="Save" class="mr-2"/>
More options
</template>

<ShadcnContextMenuItem @click="onItemClick('duplicate')">Duplicate</ShadcnContextMenuItem>
<ShadcnContextMenuItem @click="onItemClick('duplicate-with-images-and-text')">Duplicate with images and text</ShadcnContextMenuItem>
</ShadcnContextMenuSub>
<ShadcnContextMenuItem @on-click="onItemClick('move')">Move</ShadcnContextMenuItem>
</ShadcnContextMenuSub>

<ShadcnContextMenuItem @click="onItemClick('print')">Print</ShadcnContextMenuItem>
<ShadcnContextMenuSub disabled label="Disabled">
<ShadcnContextMenuItem @on-click="onItemClick('duplicate')">Duplicate</ShadcnContextMenuItem>
<ShadcnContextMenuItem @on-click="onItemClick('duplicate-with-images-and-text')">Duplicate with images and text</ShadcnContextMenuItem>
</ShadcnContextMenuSub>
<ShadcnContextMenuItem @on-click="onItemClick('print')">Print</ShadcnContextMenuItem>
</ShadcnContextMenu>
</template>

Expand Down
17 changes: 13 additions & 4 deletions src/ui/contextmenu/ShadcnContextMenuItem.vue
Original file line number Diff line number Diff line change
@@ -1,20 +1,29 @@
<template>
<div @click="onClick"
class="relative flex cursor-default select-none items-center rounded-sm px-2 py-1.5 text-sm outline-none transition-colors hover:bg-gray-100 focus:bg-gray-100 data-[disabled]:pointer-events-none data-[disabled]:opacity-50">
:class="[
'relative flex cursor-default select-none items-center rounded-sm px-2 py-1.5 text-sm outline-none transition-colors hover:bg-gray-100 focus:bg-gray-100 data-[disabled]:pointer-events-none data-[disabled]:opacity-50',
{ 'opacity-50 cursor-not-allowed': disabled }
]">
<slot/>
</div>
</template>

<script setup lang="ts">
import { ContextMenuItemEmits } from './types'
import { ContextMenuItemEmits, ContextMenuItemProps } from './types'
import { inject } from 'vue'
const props = withDefaults(defineProps<ContextMenuItemProps>(), {
disabled: false
})
const closeMenu = inject('closeMenu') as () => void
const emit = defineEmits<ContextMenuItemEmits>()
const onClick = () => {
emit('on-click')
closeMenu()
if (!props.disabled) {
emit('on-click')
closeMenu()
}
}
</script>
20 changes: 14 additions & 6 deletions src/ui/contextmenu/ShadcnContextMenuSub.vue
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
<template>
<div class="relative" @mouseenter="onMouseEnter" @mouseleave="onMouseLeave">
<div
class="relative flex cursor-default select-none items-center rounded-sm px-2 py-1.5 text-sm outline-none transition-colors hover:bg-gray-100 focus:bg-gray-100 data-[disabled]:pointer-events-none data-[disabled]:opacity-50">
<div :class="[
'relative flex cursor-default select-none items-center rounded-sm px-2 py-1.5 text-sm outline-none transition-colors hover:bg-gray-100 focus:bg-gray-100 data-[disabled]:pointer-events-none data-[disabled]:opacity-50',
{ 'opacity-50 cursor-not-allowed': disabled }
]">
<slot name="title">
{{ label }}
</slot>
Expand Down Expand Up @@ -38,7 +40,9 @@ import { computed, CSSProperties, nextTick, onBeforeUnmount, onMounted, ref, wat
import { ContextMenuItemProps } from './types'
import { calcSize } from '@/utils/common.ts'
withDefaults(defineProps<ContextMenuItemProps>(), {})
const props = withDefaults(defineProps<ContextMenuItemProps>(), {
disabled: false
})
const isHovered = ref(false)
const subMenuRef = ref<HTMLElement | null>(null)
Expand Down Expand Up @@ -92,12 +96,16 @@ const updatePosition = async () => {
}
const onMouseEnter = () => {
isHovered.value = true
updatePosition()
if (!props.disabled) {
isHovered.value = true
updatePosition()
}
}
const onMouseLeave = () => {
isHovered.value = false
if (!props.disabled) {
isHovered.value = false
}
}
// Listens for changes in the size of the monitoring window
Expand Down
1 change: 1 addition & 0 deletions src/ui/contextmenu/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,4 +16,5 @@ export interface ContextMenuProps
export interface ContextMenuItemProps
{
label?: string
disabled?: boolean
}

0 comments on commit 13f0029

Please sign in to comment.