Skip to content

Commit

Permalink
fix: tab focus issue in shared form and expanded form
Browse files Browse the repository at this point in the history
  • Loading branch information
rameshmane7218 committed Dec 28, 2023
1 parent 42fcaa4 commit 44754e1
Show file tree
Hide file tree
Showing 13 changed files with 103 additions and 24 deletions.
17 changes: 15 additions & 2 deletions packages/nc-gui/components/cell/Currency.vue
Original file line number Diff line number Diff line change
@@ -1,6 +1,16 @@
<script setup lang="ts">
import type { VNodeRef } from '@vue/runtime-core'
import { ColumnInj, EditColumnInj, EditModeInj, IsExpandedFormOpenInj, computed, inject, parseProp, useVModel } from '#imports'
import {
ColumnInj,
EditColumnInj,
EditModeInj,
IsExpandedFormOpenInj,
IsFormInj,
computed,
inject,
parseProp,
useVModel,
} from '#imports'
interface Props {
modelValue: number | null | undefined
Expand Down Expand Up @@ -57,7 +67,10 @@ const currency = computed(() => {
const isExpandedFormOpen = inject(IsExpandedFormOpenInj, ref(false))!
const focus: VNodeRef = (el) => !isExpandedFormOpen.value && !isEditColumn.value && (el as HTMLInputElement)?.focus()
const isForm = inject(IsFormInj)!
const focus: VNodeRef = (el) =>
!isExpandedFormOpen.value && !isEditColumn.value && !isForm.value && (el as HTMLInputElement)?.focus()
const submitCurrency = () => {
if (lastSaved.value !== vModel.value) {
Expand Down
2 changes: 1 addition & 1 deletion packages/nc-gui/components/cell/DatePicker.vue
Original file line number Diff line number Diff line change
Expand Up @@ -241,7 +241,7 @@ const clickHandler = () => {
<a-date-picker
v-model:value="localState"
:picker="picker"
tabindex="0"
:tabindex="0"
:bordered="false"
class="!w-full !py-1 !border-none"
:class="{ 'nc-null': modelValue === null && showNull, '!px-2': isExpandedFormOpen, '!px-0': !isExpandedFormOpen }"
Expand Down
7 changes: 5 additions & 2 deletions packages/nc-gui/components/cell/Decimal.vue
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
<script lang="ts" setup>
import type { VNodeRef } from '@vue/runtime-core'
import { EditColumnInj, EditModeInj, IsExpandedFormOpenInj, inject, useVModel } from '#imports'
import { EditColumnInj, EditModeInj, IsExpandedFormOpenInj, IsFormInj, inject, useVModel } from '#imports'
interface Props {
// when we set a number, then it is number type
Expand Down Expand Up @@ -63,6 +63,8 @@ const precision = computed(() => {
const isExpandedFormOpen = inject(IsExpandedFormOpenInj, ref(false))!
const isForm = inject(IsFormInj)!
// Handle the arrow keys as its default behavior is to increment/decrement the value
const onKeyDown = (e: any) => {
if (e.key === 'ArrowDown') {
Expand All @@ -80,7 +82,8 @@ const onKeyDown = (e: any) => {
}
}
const focus: VNodeRef = (el) => !isExpandedFormOpen.value && !isEditColumn.value && (el as HTMLInputElement)?.focus()
const focus: VNodeRef = (el) =>
!isExpandedFormOpen.value && !isEditColumn.value && !isForm.value && (el as HTMLInputElement)?.focus()
watch(isExpandedFormOpen, () => {
if (!isExpandedFormOpen.value) {
Expand Down
6 changes: 5 additions & 1 deletion packages/nc-gui/components/cell/Duration.vue
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import {
EditColumnInj,
EditModeInj,
IsExpandedFormOpenInj,
IsFormInj,
computed,
convertDurationToSeconds,
convertMS2Duration,
Expand Down Expand Up @@ -83,7 +84,10 @@ const submitDuration = () => {
const isExpandedFormOpen = inject(IsExpandedFormOpenInj, ref(false))!
const focus: VNodeRef = (el) => !isExpandedFormOpen.value && !isEditColumn.value && (el as HTMLInputElement)?.focus()
const isForm = inject(IsFormInj)!
const focus: VNodeRef = (el) =>
!isExpandedFormOpen.value && !isEditColumn.value && !isForm.value && (el as HTMLInputElement)?.focus()
</script>

<template>
Expand Down
6 changes: 5 additions & 1 deletion packages/nc-gui/components/cell/Email.vue
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import {
EditColumnInj,
EditModeInj,
IsExpandedFormOpenInj,
IsFormInj,
IsSurveyFormInj,
computed,
inject,
Expand Down Expand Up @@ -50,7 +51,10 @@ const validEmail = computed(() => vModel.value && validateEmail(vModel.value))
const isExpandedFormOpen = inject(IsExpandedFormOpenInj, ref(false))!
const focus: VNodeRef = (el) => !isExpandedFormOpen.value && !isEditColumn.value && (el as HTMLInputElement)?.focus()
const isForm = inject(IsFormInj)!
const focus: VNodeRef = (el) =>
!isExpandedFormOpen.value && !isEditColumn.value && !isForm.value && (el as HTMLInputElement)?.focus()
watch(
() => editEnabled.value,
Expand Down
7 changes: 5 additions & 2 deletions packages/nc-gui/components/cell/Float.vue
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
<script lang="ts" setup>
import type { VNodeRef } from '@vue/runtime-core'
import { EditColumnInj, EditModeInj, IsExpandedFormOpenInj, inject, useVModel } from '#imports'
import { EditColumnInj, EditModeInj, IsExpandedFormOpenInj, IsFormInj, inject, useVModel } from '#imports'
interface Props {
// when we set a number, then it is number type
Expand Down Expand Up @@ -40,7 +40,10 @@ const vModel = computed({
const isExpandedFormOpen = inject(IsExpandedFormOpenInj, ref(false))!
const focus: VNodeRef = (el) => !isExpandedFormOpen.value && !isEditColumn.value && (el as HTMLInputElement)?.focus()
const isForm = inject(IsFormInj)!
const focus: VNodeRef = (el) =>
!isExpandedFormOpen.value && !isEditColumn.value && !isForm.value && (el as HTMLInputElement)?.focus()
</script>

<template>
Expand Down
7 changes: 5 additions & 2 deletions packages/nc-gui/components/cell/Integer.vue
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
<script setup lang="ts">
import type { VNodeRef } from '@vue/runtime-core'
import { EditColumnInj, EditModeInj, IsExpandedFormOpenInj, inject, useVModel } from '#imports'
import { EditColumnInj, EditModeInj, IsExpandedFormOpenInj, IsFormInj, inject, useVModel } from '#imports'
interface Props {
// when we set a number, then it is number type
Expand Down Expand Up @@ -48,7 +48,10 @@ const vModel = computed({
const isExpandedFormOpen = inject(IsExpandedFormOpenInj, ref(false))!
const focus: VNodeRef = (el) => !isExpandedFormOpen.value && !isEditColumn.value && (el as HTMLInputElement)?.focus()
const isForm = inject(IsFormInj)!
const focus: VNodeRef = (el) =>
!isExpandedFormOpen.value && !isEditColumn.value && !isForm.value && (el as HTMLInputElement)?.focus()
function onKeyDown(e: any) {
const cmdOrCtrl = isMac() ? e.metaKey : e.ctrlKey
Expand Down
19 changes: 13 additions & 6 deletions packages/nc-gui/components/cell/Percent.vue
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
<script setup lang="ts">
import type { VNodeRef } from '@vue/runtime-core'
import { EditColumnInj, EditModeInj, IsExpandedFormOpenInj, inject, useVModel } from '#imports'
import { EditColumnInj, EditModeInj, IsExpandedFormOpenInj, IsFormInj, inject, useVModel } from '#imports'
interface Props {
modelValue?: number | string | null
Expand Down Expand Up @@ -35,7 +35,10 @@ const vModel = computed({
const isExpandedFormOpen = inject(IsExpandedFormOpenInj, ref(false))!
const focus: VNodeRef = (el) => !isExpandedFormOpen.value && !isEditColumn.value && (el as HTMLInputElement)?.focus()
const isForm = inject(IsFormInj)!
const focus: VNodeRef = (el) =>
!isExpandedFormOpen.value && !isEditColumn.value && !isForm.value && (el as HTMLInputElement)?.focus()
const cellFocused = ref(false)
Expand Down Expand Up @@ -84,18 +87,22 @@ const onMouseleave = () => {
}
const onTabPress = (e: KeyboardEvent) => {
if (e.shiftKey) {
if (e.shiftKey && (isExpandedFormOpen.value || isForm.value)) {
e.preventDefault()
// Shift + Tab does not work for percent cell
// so we manually focus on the last form item
const focusesNcCellIndex = Array.from(document.querySelectorAll('.nc-expanded-form-row .nc-data-cell')).findIndex((el) => {
const focusesNcCellIndex = Array.from(
document.querySelectorAll(`${isExpandedFormOpen.value ? '.nc-expanded-form-row' : '.nc-form-wrapper'} .nc-data-cell`),
).findIndex((el) => {
return el.querySelector('.nc-filter-value-select') === wrapperRef.value
})
if (focusesNcCellIndex >= 0) {
const nodes = document.querySelectorAll('.nc-expanded-form-row .nc-data-cell')
const nodes = document.querySelectorAll(
`${isExpandedFormOpen.value ? '.nc-expanded-form-row' : '.nc-form-wrapper'} .nc-data-cell`,
)
for (let i = focusesNcCellIndex - 1; i >= 0; i--) {
const lastFormItem = nodes[i].querySelector('[tabindex="0"]') as HTMLElement
if (lastFormItem) {
Expand Down
7 changes: 5 additions & 2 deletions packages/nc-gui/components/cell/PhoneNumber.vue
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
<script lang="ts" setup>
import type { VNodeRef } from '@vue/runtime-core'
import isMobilePhone from 'validator/lib/isMobilePhone'
import { EditColumnInj, EditModeInj, IsExpandedFormOpenInj, IsSurveyFormInj, computed, inject } from '#imports'
import { EditColumnInj, EditModeInj, IsExpandedFormOpenInj, IsFormInj, IsSurveyFormInj, computed, inject } from '#imports'
interface Props {
modelValue: string | null | number | undefined
Expand Down Expand Up @@ -42,7 +42,10 @@ const validEmail = computed(() => vModel.value && isMobilePhone(vModel.value))
const isExpandedFormOpen = inject(IsExpandedFormOpenInj, ref(false))!
const focus: VNodeRef = (el) => !isExpandedFormOpen.value && !isEditColumn.value && (el as HTMLInputElement)?.focus()
const isForm = inject(IsFormInj)!
const focus: VNodeRef = (el) =>
!isExpandedFormOpen.value && !isEditColumn.value && !isForm.value && (el as HTMLInputElement)?.focus()
watch(
() => editEnabled.value,
Expand Down
17 changes: 15 additions & 2 deletions packages/nc-gui/components/cell/Text.vue
Original file line number Diff line number Diff line change
@@ -1,6 +1,16 @@
<script setup lang="ts">
import type { VNodeRef } from '@vue/runtime-core'
import { EditColumnInj, EditModeInj, IsExpandedFormOpenInj, ReadonlyInj, RowHeightInj, inject, ref, useVModel } from '#imports'
import {
EditColumnInj,
EditModeInj,
IsExpandedFormOpenInj,
IsFormInj,
ReadonlyInj,
RowHeightInj,
inject,
ref,
useVModel,
} from '#imports'
interface Props {
modelValue?: string | null
Expand All @@ -24,7 +34,10 @@ const vModel = useVModel(props, 'modelValue', emits)
const isExpandedFormOpen = inject(IsExpandedFormOpenInj, ref(false))!
const focus: VNodeRef = (el) => !isExpandedFormOpen.value && !isEditColumn.value && (el as HTMLInputElement)?.focus()
const isForm = inject(IsFormInj)!
const focus: VNodeRef = (el) =>
!isExpandedFormOpen.value && !isEditColumn.value && !isForm.value && (el as HTMLInputElement)?.focus()
</script>

<template>
Expand Down
3 changes: 2 additions & 1 deletion packages/nc-gui/components/cell/TextArea.vue
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,8 @@ const position = ref<
const isDragging = ref(false)
const focus: VNodeRef = (el) => !isExpandedFormOpen.value && !isEditColumn.value && (el as HTMLTextAreaElement)?.focus()
const focus: VNodeRef = (el) =>
!isExpandedFormOpen.value && !isEditColumn.value && isForm.value && (el as HTMLTextAreaElement)?.focus()
const height = computed(() => {
if (isExpandedFormOpen.value) return 36 * 4
Expand Down
6 changes: 5 additions & 1 deletion packages/nc-gui/components/cell/Url.vue
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import {
EditColumnInj,
EditModeInj,
IsExpandedFormOpenInj,
IsFormInj,
IsSurveyFormInj,
computed,
inject,
Expand Down Expand Up @@ -70,7 +71,10 @@ const { cellUrlOptions } = useCellUrlConfig(url)
const isExpandedFormOpen = inject(IsExpandedFormOpenInj, ref(false))!
const focus: VNodeRef = (el) => !isExpandedFormOpen.value && !isEditColumn.value && (el as HTMLInputElement)?.focus()
const isForm = inject(IsFormInj)!
const focus: VNodeRef = (el) =>
!isExpandedFormOpen.value && !isEditColumn.value && isForm.value && (el as HTMLInputElement)?.focus()
watch(
() => editEnabled.value,
Expand Down
23 changes: 22 additions & 1 deletion packages/nc-gui/components/smartsheet/DivDataCell.vue
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,31 @@ import { CurrentCellInj, ref } from '#imports'
const el = ref()
provide(CurrentCellInj, el)
const isExpandedFormOpen = inject(IsExpandedFormOpenInj, ref(false))!
const isForm = inject(IsFormInj)!
const onTabPress = () => {
if (!isExpandedFormOpen.value && !isForm.value) return
// Find the focused element
const focusedElement = document.activeElement
if (focusedElement) {
// Check if the focused element is a descendant of the wrapper
const closestWrapper = focusedElement.closest('.nc-data-cell')
// Scroll it into view
if (closestWrapper === el.value) {
el.value?.scrollIntoView({ block: 'center' })
}
}
}
</script>

<template>
<div ref="el" class="select-none nc-data-cell">
<div ref="el" class="select-none nc-data-cell" @keydown.tab="onTabPress">
<slot />
</div>
</template>
Expand Down

1 comment on commit 44754e1

@github-actions
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The PR changes have been deployed. Please run the following command to verify:

docker run -d -p 8888:8080 nocodb/nocodb-timely:0.202.10-pr-7298-20231228-0842

Please sign in to comment.