Browse Source

feat(gui-v2): custom mouse and key events for select cells

Signed-off-by: mertmit <mertmit99@gmail.com>
pull/3022/head
mertmit 2 years ago
parent
commit
469b96c8b2
  1. 43
      packages/nc-gui-v2/components/cell/MultiSelect.vue
  2. 46
      packages/nc-gui-v2/components/cell/SingleSelect.vue

43
packages/nc-gui-v2/components/cell/MultiSelect.vue

@ -20,6 +20,8 @@ const editEnabled = inject(EditModeInj, ref(false))
const active = inject(ActiveCellInj, ref(false)) const active = inject(ActiveCellInj, ref(false))
const selectedIds = ref<string[]>([]) const selectedIds = ref<string[]>([])
const aselect = ref<any>(null)
const isOpen = ref(false)
const options = computed(() => { const options = computed(() => {
if (column?.colOptions) { if (column?.colOptions) {
@ -54,10 +56,36 @@ const selectedTitles = computed(() =>
: [], : [],
) )
const handleKeys = (e: any) => {
switch (e.key) {
case 'Escape':
e.preventDefault()
isOpen.value = false
break
case 'Enter':
e.stopPropagation()
break
}
}
const handleClose = (e: any) => {
if (aselect.value) {
const selectClick = aselect.value.$el.contains(e.target)
if (!selectClick) {
isOpen.value = false
}
}
}
onMounted(() => { onMounted(() => {
selectedIds.value = selectedTitles.value.map((el) => { selectedIds.value = selectedTitles.value.map((el) => {
return options.value.find((op: SelectOptionType) => op.title === el).id return options.value.find((op: SelectOptionType) => op.title === el).id
}) })
document.addEventListener('click', handleClose)
})
onUnmounted(() => {
document.removeEventListener('click', handleClose)
}) })
watch( watch(
@ -68,10 +96,20 @@ watch(
}) })
}, },
) )
watch(
() => isOpen.value,
(n, _o) => {
if (n === false) {
aselect.value.blur()
}
},
)
</script> </script>
<template> <template>
<a-select <a-select
ref="aselect"
v-model:value="vModel" v-model:value="vModel"
mode="multiple" mode="multiple"
class="w-full" class="w-full"
@ -79,8 +117,11 @@ watch(
:bordered="false" :bordered="false"
show-arrow show-arrow
:show-search="false" :show-search="false"
:open="isOpen"
@keydown="handleKeys"
@click="isOpen = !isOpen"
> >
<a-select-option v-for="op of options" :key="op.id" :value="op.title" :data-color="op.color"> <a-select-option v-for="op of options" :key="op.id" :value="op.title" @click.stop>
<a-tag class="rounded-tag" :color="op.color"> <a-tag class="rounded-tag" :color="op.color">
<span class="text-slate-500">{{ op.title }}</span> <span class="text-slate-500">{{ op.title }}</span>
</a-tag> </a-tag>

46
packages/nc-gui-v2/components/cell/SingleSelect.vue

@ -16,6 +16,9 @@ const isForm = inject<boolean>('isForm', false)
const editEnabled = inject(EditModeInj, ref(false)) const editEnabled = inject(EditModeInj, ref(false))
const active = inject(ActiveCellInj, ref(false)) const active = inject(ActiveCellInj, ref(false))
const aselect = ref<any>(null)
const isOpen = ref(false)
const vModel = computed({ const vModel = computed({
get: () => modelValue, get: () => modelValue,
set: (val) => emit('update:modelValue', val || null), set: (val) => emit('update:modelValue', val || null),
@ -31,17 +34,58 @@ const options = computed(() => {
} }
return [] return []
}) })
const handleKeys = (e: any) => {
switch (e.key) {
case 'Escape':
e.preventDefault()
isOpen.value = false
break
}
}
const handleClose = (e: any) => {
if (aselect.value) {
const selectClick = aselect.value.$el.contains(e.target)
if (!selectClick) {
isOpen.value = false
aselect.value.blur()
}
}
}
onMounted(() => {
document.addEventListener('click', handleClose)
})
onUnmounted(() => {
document.removeEventListener('click', handleClose)
})
watch(
() => isOpen.value,
(n, _o) => {
if (n === false) {
aselect.value.blur()
}
},
)
</script> </script>
<template> <template>
<a-select <a-select
ref="aselect"
v-model:value="vModel" v-model:value="vModel"
class="w-full" class="w-full"
:allow-clear="!column.rqd && active" :allow-clear="!column.rqd && active"
placeholder="Select an option" placeholder="Select an option"
:bordered="false" :bordered="false"
:open="isOpen"
@select="isOpen = false"
@keydown="handleKeys"
@click="isOpen = !isOpen"
> >
<a-select-option v-for="op of options" :key="op.title"> <a-select-option v-for="op of options" :key="op.title" @click.stop>
<a-tag class="rounded-tag" :color="op.color"> <a-tag class="rounded-tag" :color="op.color">
<span class="text-slate-500">{{ op.title }}</span> <span class="text-slate-500">{{ op.title }}</span>
</a-tag> </a-tag>

Loading…
Cancel
Save