Browse Source

feat: better scroll for borders and sticky header

Signed-off-by: mertmit <mertmit99@gmail.com>
pull/4101/head
mertmit 2 years ago
parent
commit
7e5a52d0ff
  1. 61
      packages/nc-gui/components/smartsheet/Grid.vue
  2. 2
      packages/nc-gui/composables/useMultiSelect/index.ts

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

@ -88,6 +88,8 @@ const expandedFormDlg = ref(false)
const expandedFormRow = ref<Row>()
const expandedFormRowState = ref<Record<string, any>>()
const tbodyEl = ref<HTMLElement>()
const gridWrapper = ref<HTMLElement>()
const tableHead = ref<HTMLElement>()
const {
isLoading,
@ -114,16 +116,57 @@ const { selectCell, selectBlock, selectedRange, clearRangeRows, startSelectRange
isPkAvail,
clearCell,
makeEditable,
() => {
if (selected.row !== null && selected.col !== null) {
(row?: number | null, col?: number | null) => {
row = row ?? selected.row
col = col ?? selected.col
if (row !== undefined && col !== undefined && row !== null && col !== null) {
// get active cell
const td = tbodyEl.value?.querySelectorAll('tr')[selected.row]?.querySelectorAll('td')[selected.col + 1]
if (!td) return
const rows = tbodyEl.value?.querySelectorAll('tr')
const td = rows?.[row].querySelectorAll('td')[col === 0 ? 0 : col + 1]
if (!td || !gridWrapper.value) return
const { height: headerHeight } = tableHead.value!.getBoundingClientRect()
const childPos = td.getBoundingClientRect()
const parentPos = gridWrapper.value.getBoundingClientRect()
const relativePos = {
top: childPos.top - parentPos.top,
right: childPos.right - parentPos.right,
bottom: childPos.bottom - parentPos.bottom,
left: childPos.left - parentPos.left,
}
if (rows && row === rows.length - 2) {
// if last row make 'Add New Row' visible
gridWrapper.value.scrollTo({
top: gridWrapper.value.scrollHeight,
left:
relativePos.right > 0
? gridWrapper.value.scrollLeft + relativePos.right + 9 // 9 is for border
: relativePos.left < 0
? gridWrapper.value.scrollLeft + relativePos.left
: gridWrapper.value.scrollLeft,
behavior: 'smooth',
})
return
}
// scroll into the active cell
td.scrollIntoView({
gridWrapper.value.scrollTo({
top:
relativePos.bottom > 0
? gridWrapper.value.scrollTop + relativePos.bottom + 9 // 9 is for border
: relativePos.top - headerHeight < 0
? gridWrapper.value.scrollTop + relativePos.top - headerHeight
: gridWrapper.value.scrollTop,
left:
relativePos.right > 0
? gridWrapper.value.scrollLeft + relativePos.right + 9 // 9 is for border
: relativePos.left < 0
? gridWrapper.value.scrollLeft + relativePos.left
: gridWrapper.value.scrollLeft,
behavior: 'smooth',
block: 'nearest',
inline: 'nearest',
})
}
},
@ -380,7 +423,7 @@ watch(
</div>
</general-overlay>
<div class="nc-grid-wrapper min-h-0 flex-1 scrollbar-thin-dull">
<div ref="gridWrapper" class="nc-grid-wrapper min-h-0 flex-1 scrollbar-thin-dull">
<a-dropdown
v-model:visible="contextMenu"
:trigger="isSqlView ? [] : ['contextmenu']"
@ -391,7 +434,7 @@ watch(
class="xc-row-table nc-grid backgroundColorDefault !h-auto bg-white"
@contextmenu="showContextMenu"
>
<thead>
<thead ref="tableHead">
<tr class="nc-grid-header border-1 bg-gray-100 sticky top[-1px]">
<th>
<div class="w-full h-full bg-gray-100 flex min-w-[70px] pl-5 pr-1 items-center">

2
packages/nc-gui/composables/useMultiSelect/index.ts

@ -17,7 +17,7 @@ export function useMultiSelect(
isPkAvail: MaybeRef<boolean>,
clearCell: Function,
makeEditable: Function,
scrollToActiveCell?: () => void,
scrollToActiveCell?: (row?: number | null, col?: number | null) => void,
) {
const { t } = useI18n()

Loading…
Cancel
Save