Skip to content

Commit

Permalink
feat(Table): add contextmenu handling to table rows (#2283)
Browse files Browse the repository at this point in the history
  • Loading branch information
nfpocket authored Nov 6, 2024
1 parent ce955d2 commit c9e6256
Show file tree
Hide file tree
Showing 3 changed files with 93 additions and 1 deletion.
66 changes: 66 additions & 0 deletions docs/components/content/examples/TableExampleContextmenu.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
<script setup lang="ts">
const people = [{
id: 1,
name: 'Lindsay Walton',
title: 'Front-end Developer',
email: 'lindsay.walton@example.com',
role: 'Member'
}, {
id: 2,
name: 'Courtney Henry',
title: 'Designer',
email: 'courtney.henry@example.com',
role: 'Admin'
}, {
id: 3,
name: 'Tom Cook',
title: 'Director of Product',
email: 'tom.cook@example.com',
role: 'Member'
}, {
id: 4,
name: 'Whitney Francis',
title: 'Copywriter',
email: 'whitney.francis@example.com',
role: 'Admin'
}, {
id: 5,
name: 'Leonard Krasner',
title: 'Senior Designer',
email: 'leonard.krasner@example.com',
role: 'Owner'
}]
const virtualElement = ref({ getBoundingClientRect: () => ({}) })
const contextMenuRow = ref()
function contextmenu(event: MouseEvent, row: any) {
// Prevent the default context menu
event.preventDefault()
virtualElement.value.getBoundingClientRect = () => ({
width: 0,
height: 0,
top: event.clientY,
left: event.clientX
})
contextMenuRow.value = row
}
</script>

<template>
<div>
<UTable :rows="people" @contextmenu.stop="contextmenu" />

<UContextMenu
:virtual-element="virtualElement"
:model-value="!!contextMenuRow"
@update:model-value="contextMenuRow = null"
>
<div class="p-4">
{{ contextMenuRow.id }} - {{ contextMenuRow.name }}
</div>
</UContextMenu>
</div>
</template>
16 changes: 16 additions & 0 deletions docs/content/2.components/table.md
Original file line number Diff line number Diff line change
Expand Up @@ -285,6 +285,22 @@ componentProps:
---
::

### Contextmenu

Use the `contextmenu` listener on your Table to make the rows righ-clickable. The function will receive the original event as the first argument and the row as the second argument.

You can use this to open a [ContextMenu](/components/context-menu) for that row.

::component-example{class="grid"}
---
extraClass: 'overflow-hidden'
padding: false
component: 'table-example-contextmenu'
componentProps:
class: 'flex-1 flex-col overflow-hidden'
---
::

### Searchable

You can easily use the [Input](/components/input) component to filter the rows.
Expand Down
12 changes: 11 additions & 1 deletion src/runtime/components/data/Table.vue
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,7 @@

<template v-else>
<template v-for="(row, index) in rows" :key="index">
<tr :class="[ui.tr.base, isSelected(row) && ui.tr.selected, isExpanded(row) && ui.tr.expanded, $attrs.onSelect && ui.tr.active, row?.class]" @click="() => onSelect(row)">
<tr :class="[ui.tr.base, isSelected(row) && ui.tr.selected, isExpanded(row) && ui.tr.expanded, ($attrs.onSelect || $attrs.onContextmenu) && ui.tr.active, row?.class]" @click="() => onSelect(row)" @contextmenu="(event) => onContextmenu(event, row)">
<td v-if="modelValue" :class="ui.checkbox.padding">
<UCheckbox
:model-value="isSelected(row)"
Expand Down Expand Up @@ -363,6 +363,15 @@ export default defineComponent({
$attrs.onSelect(row)
}
function onContextmenu(event, row) {
if (!$attrs.onContextmenu) {
return
}
// @ts-ignore
$attrs.onContextmenu(event, row)
}
function selectAllRows() {
// Create a new array to ensure reactivity
const newSelected = [...selected.value]
Expand Down Expand Up @@ -451,6 +460,7 @@ export default defineComponent({
isSelected,
onSort,
onSelect,
onContextmenu,
onChange,
getRowData,
toggleOpened,
Expand Down

0 comments on commit c9e6256

Please sign in to comment.