Browse Source

fix(gui): single/multi select issue with arrow and enter keys

Signed-off-by: Pranav C <pranavxc@gmail.com>
pull/4222/head
Pranav C 2 years ago
parent
commit
ad1a64a985
  1. 54
      packages/nc-gui/components/cell/MultiSelect.vue
  2. 11
      packages/nc-gui/components/cell/SingleSelect.vue
  3. 5
      packages/nc-gui/components/smartsheet/Cell.vue
  4. 6
      packages/nc-gui/components/smartsheet/Grid.vue

54
packages/nc-gui/components/cell/MultiSelect.vue

@ -74,30 +74,32 @@ const selectedTitles = computed(() =>
? typeof modelValue === 'string' ? typeof modelValue === 'string'
? isMysql ? isMysql
? modelValue.split(',').sort((a, b) => { ? modelValue.split(',').sort((a, b) => {
const opa = options.value.find((el) => el.title === a) const opa = options.value.find((el) => el.title === a)
const opb = options.value.find((el) => el.title === b) const opb = options.value.find((el) => el.title === b)
if (opa && opb) { if (opa && opb) {
return opa.order! - opb.order! return opa.order! - opb.order!
} }
return 0 return 0
}) })
: modelValue.split(',') : modelValue.split(',')
: modelValue : modelValue
: [], : [],
) )
const v = Math.floor(Math.random() *1000)
const handleKeys = (e: KeyboardEvent) => { const handleKeys = (e: KeyboardEvent) => {
console.log(`handleKeys ${v}`, e.key)
if (!active.value) return true
switch (e.key) { switch (e.key) {
case 'Escape':
e.preventDefault()
isOpen.value = false
break
case 'ArrowDown': case 'ArrowDown':
case 'ArrowUp': case 'ArrowUp':
if (isOpen.value) e.stopPropagation() if (isOpen.value) {
e.stopPropagation()
}
break break
case 'Enter': case 'Enter':
isOpen.value = true
e.stopPropagation() e.stopPropagation()
break break
} }
@ -137,31 +139,43 @@ watch(
) )
watch(isOpen, (n, _o) => { watch(isOpen, (n, _o) => {
if (!n) aselect.value?.$el.blur() if (!n) {
aselect.value?.$el?.querySelector('input')?.blur()
} else {
aselect.value?.$el?.querySelector('input')?.focus()
}
}) })
useSelectedCellKeyupListener(active, (e) => { useSelectedCellKeyupListener(active, (e) => {
if (e.key === 'Escape') { switch (e.key) {
// e.stopPropagation() case 'Escape':
isOpen.value = false isOpen.value = false
select?.value?.blur()
break
case 'Enter':
if (active.value && !isOpen.value) {
isOpen.value = true
e.stopPropagation()
}
break
} }
}) })
</script> </script>
<template> <template>
<a-select <a-select
ref="select" ref="aselect"
v-model:value="vModel" v-model:value="vModel"
mode="multiple" mode="multiple"
class="w-full" class="w-full"
:bordered="false" :bordered="false"
:show-arrow="!readOnly" :show-arrow="!readOnly"
:show-search="false" :show-search="false"
:open="isOpen" v-model:open="isOpen"
:disabled="readOnly" :disabled="readOnly"
:class="{ '!ml-[-8px]': readOnly }" :class="{ '!ml-[-8px]': readOnly }"
:dropdown-class-name="`nc-dropdown-multi-select-cell ${isOpen ? 'active' : ''}`" :dropdown-class-name="`nc-dropdown-multi-select-cell ${isOpen ? 'active' : ''}`"
@keydown="handleKeys"
@click="isOpen = active && !isOpen" @click="isOpen = active && !isOpen"
> >
<a-select-option <a-select-option

11
packages/nc-gui/components/cell/SingleSelect.vue

@ -3,6 +3,7 @@ import tinycolor from 'tinycolor2'
import type { Select as AntSelect } from 'ant-design-vue' import type { Select as AntSelect } from 'ant-design-vue'
import type { SelectOptionType } from 'nocodb-sdk' import type { SelectOptionType } from 'nocodb-sdk'
import { ActiveCellInj, ColumnInj, IsKanbanInj, ReadonlyInj, computed, inject, ref, useEventListener, watch } from '#imports' import { ActiveCellInj, ColumnInj, IsKanbanInj, ReadonlyInj, computed, inject, ref, useEventListener, watch } from '#imports'
import { useSelectedCellKeyupListener } from '~/composables/useSelectedCellKeyupListener'
interface Props { interface Props {
modelValue?: string | undefined modelValue?: string | undefined
@ -61,6 +62,7 @@ const handleKeys = (e: KeyboardEvent) => {
} }
} }
const handleClose = (e: MouseEvent) => { const handleClose = (e: MouseEvent) => {
if (aselect.value && !aselect.value.$el.contains(e.target)) { if (aselect.value && !aselect.value.$el.contains(e.target)) {
isOpen.value = false isOpen.value = false
@ -70,8 +72,13 @@ const handleClose = (e: MouseEvent) => {
useEventListener(document, 'click', handleClose) useEventListener(document, 'click', handleClose)
watch(isOpen, (n, _o) => { watch(isOpen, (n, _o) => {
if (!n) aselect.value?.$el.blur() if (!n) {
aselect.value?.$el?.querySelector('input')?.blur()
} else {
aselect.value?.$el?.querySelector('input')?.focus()
}
}) })
</script> </script>
@ -87,7 +94,7 @@ watch(isOpen, (n, _o) => {
:show-arrow="!readOnly && (active || vModel === null)" :show-arrow="!readOnly && (active || vModel === null)"
:dropdown-class-name="`nc-dropdown-single-select-cell ${isOpen ? 'active' : ''}`" :dropdown-class-name="`nc-dropdown-single-select-cell ${isOpen ? 'active' : ''}`"
@select="isOpen = false" @select="isOpen = false"
@keydown="handleKeys" @keydown="isOpen ? handleKeys : null"
@click="isOpen = active && !isOpen" @click="isOpen = active && !isOpen"
> >
<a-select-option <a-select-option

5
packages/nc-gui/components/smartsheet/Cell.vue

@ -111,6 +111,7 @@ const vModel = computed({
}) })
const syncAndNavigate = (dir: NavigateDir, e: KeyboardEvent) => { const syncAndNavigate = (dir: NavigateDir, e: KeyboardEvent) => {
console.log('syncAndNavigate', e.target)
if (isJSON.value) return if (isJSON.value) return
if (currentRow.value.rowMeta.changed || currentRow.value.rowMeta.new) { if (currentRow.value.rowMeta.changed || currentRow.value.rowMeta.new) {
@ -127,9 +128,9 @@ const syncAndNavigate = (dir: NavigateDir, e: KeyboardEvent) => {
<div <div
class="nc-cell w-full" class="nc-cell w-full"
:class="[`nc-cell-${(column?.uidt || 'default').toLowerCase()}`, { 'text-blue-600': isPrimary && !virtual && !isForm }]" :class="[`nc-cell-${(column?.uidt || 'default').toLowerCase()}`, { 'text-blue-600': isPrimary && !virtual && !isForm }]"
@keydown.enter.exact="syncAndNavigate(NavigateDir.NEXT, $event)" ><!-- @keydown.enter.exact="syncAndNavigate(NavigateDir.NEXT, $event)"
@keydown.shift.enter.exact="syncAndNavigate(NavigateDir.PREV, $event)" @keydown.shift.enter.exact="syncAndNavigate(NavigateDir.PREV, $event)"
> >-->
<LazyCellTextArea v-if="isTextArea" v-model="vModel" /> <LazyCellTextArea v-if="isTextArea" v-model="vModel" />
<LazyCellCheckbox v-else-if="isBoolean" v-model="vModel" /> <LazyCellCheckbox v-else-if="isBoolean" v-model="vModel" />
<LazyCellAttachment v-else-if="isAttachment" v-model="vModel" :row-index="props.rowIndex" /> <LazyCellAttachment v-else-if="isAttachment" v-model="vModel" :row-index="props.rowIndex" />

6
packages/nc-gui/components/smartsheet/Grid.vue

@ -180,6 +180,7 @@ const { selectCell, selectBlock, selectedRange, clearRangeRows, startSelectRange
e.preventDefault() e.preventDefault()
return true return true
} }
console.log('=========', e.key, e.code)
const cmdOrCtrl = isMac() ? e.metaKey : e.ctrlKey const cmdOrCtrl = isMac() ? e.metaKey : e.ctrlKey
if (e.key === ' ') { if (e.key === ' ') {
@ -194,6 +195,11 @@ const { selectCell, selectBlock, selectedRange, clearRangeRows, startSelectRange
editEnabled = false editEnabled = false
return true return true
} }
} else if (e.key === 'Enter') {
if (editEnabled) {
editEnabled = false
return true
}
} }
if (cmdOrCtrl) { if (cmdOrCtrl) {
switch (e.key) { switch (e.key) {

Loading…
Cancel
Save