From 633d4c1a5750679abe7b073ea8b7a770e0d7dc06 Mon Sep 17 00:00:00 2001 From: lublagg Date: Mon, 23 Oct 2023 18:10:34 -0400 Subject: [PATCH] Works with intersection observor --- src/components/draggable-table-tags.tsx | 27 ++++++++---------- src/components/nested-table.tsx | 3 +- src/components/portrait-view.tsx | 38 ++++++++++++++++++++++--- src/types.tsx | 2 +- 4 files changed, 49 insertions(+), 21 deletions(-) diff --git a/src/components/draggable-table-tags.tsx b/src/components/draggable-table-tags.tsx index 3bb1cab..5a2a753 100644 --- a/src/components/draggable-table-tags.tsx +++ b/src/components/draggable-table-tags.tsx @@ -1,4 +1,4 @@ -import React, { useMemo, useRef } from "react"; +import React, { useEffect, useMemo, useRef, useState } from "react"; import { useDraggableTableContext, Side } from "../hooks/useDraggableTable"; import AddIcon from "../assets/plus-level-1.svg"; @@ -82,10 +82,11 @@ interface DraggagleTableDataProps { attrTitle: string; style?: React.CSSProperties; isParent?: boolean; + resizeCounter?: number; } export const DraggagleTableData: React.FC - = ({collectionId, attrTitle, children, isParent}) => { + = ({collectionId, attrTitle, children, isParent, resizeCounter}) => { const {dragOverId, dragSide} = useDraggableTableContext(); const {style} = getIdAndStyle(collectionId, attrTitle, dragOverId, dragSide); const {tableScrollTop, scrollY} = useTableTopScrollTopContext(); @@ -113,8 +114,6 @@ export const DraggagleTableData: React.FC const stickyHeaders = tableScrollTop === 0; const stickyHeaderHeight = (3 + level) * 16; const visibleTop = stickyHeaders ? Math.max(top, stickyHeaderHeight) : top; - // const visibleTop = stickyHeaders ? Math.max(top, (stickyHeaderHeight + scrollY)) : tableScrollTop; - // const visibleBottom = Math.min(window.innerHeight, Math.max(bottom, 0)); const visibleBottom = Math.min(window.innerHeight, bottom); const text = cellRef.current.innerText; const availableHeight = Math.abs(visibleBottom - visibleTop); @@ -125,27 +124,25 @@ export const DraggagleTableData: React.FC // the whole cell is visible return 0; } else if (top < visibleTop && bottom < window.innerHeight) { - // we are in the bottom part of the cell + // we can see the bottom border of the cell but not the top const hiddenHeightOfCell = height - availableHeight; - newTop = Math.max(0, (hiddenHeightOfCell - 16 + (availableHeight / 2))) /* + height of text */; + newTop = Math.max(0, (hiddenHeightOfCell - 16 + (availableHeight / 2))); } else if (top >= visibleTop && bottom > visibleBottom) { - // we are in the top part of the cell - newTop = Math.max(0, ((availableHeight) / 2)) /* + height of text */; + // we can see the top border of the cell but not the bottom + newTop = Math.max(0, ((availableHeight) / 2)); } else { - // we are in the middle of a cell that's taller than the table window - // we need to get the hidden top part of the cell + // we are in the middle of a cell - we can see neither the top nor the bottom border const hiddenTopPartOfCell = Math.max(0, visibleTop - top); - newTop = Math.max(0, (hiddenTopPartOfCell - 16 + (availableHeight) / 2)) /* + height of text */; + newTop = Math.max(0, (hiddenTopPartOfCell - 16 + (availableHeight) / 2)); } - console.log(cellRef.current?.innerText, JSON.stringify({top, bottom, visibleBottom, + console.log(text, JSON.stringify({top, bottom, visibleBottom, tableScrollTop, visibleTop, availableHeight, newTop, scrollY})); return newTop; } + }, [tableScrollTop, isParent, scrollY, level, resizeCounter]); - }, [tableScrollTop, isParent, scrollY, level]); - const textStyle: React.CSSProperties = {top: cellTextTop}; if (cellTextTop === 0) { textStyle.alignContent = "center"; @@ -156,7 +153,7 @@ export const DraggagleTableData: React.FC {isParent ? <> {children} -
{children}
+
{children}
: children } diff --git a/src/components/nested-table.tsx b/src/components/nested-table.tsx index 1cf0d1f..f483cfc 100644 --- a/src/components/nested-table.tsx +++ b/src/components/nested-table.tsx @@ -108,7 +108,7 @@ export const NestedTable = (props: IProps) => { ); }; - const mapCellsFromValues = (collectionId: number, rowKey: string, values: IValues, isParent?: boolean) => { + const mapCellsFromValues = (collectionId: number, rowKey: string, values: IValues, isParent?: boolean, resizeCounter?: number) => { return Object.keys(values).map((key, index) => { const val = values[key]; if (typeof val === "string" || typeof val === "number") { @@ -118,6 +118,7 @@ export const NestedTable = (props: IProps) => { attrTitle={key} key={`${rowKey}-${val}-${index}}`} isParent={isParent} + resizeCounter={resizeCounter} > {val} diff --git a/src/components/portrait-view.tsx b/src/components/portrait-view.tsx index 15396c4..8805aee 100644 --- a/src/components/portrait-view.tsx +++ b/src/components/portrait-view.tsx @@ -1,4 +1,4 @@ -import React, { useRef } from "react"; +import React, { useEffect, useMemo, useRef } from "react"; import { ICollection, IProcessedCaseObj, ITableProps } from "../types"; import { DraggableTableContainer, DroppableTableData, DroppableTableHeader } from "./draggable-table-tags"; @@ -6,11 +6,11 @@ import css from "./tables.scss"; import { TableScrollTopContext, useTableScrollTop } from "../hooks/useTableScrollTop"; export type PortraitViewRowProps = - {collectionId: number, caseObj: IProcessedCaseObj, index?: null|number, isParent: boolean} & ITableProps; + {collectionId: number, caseObj: IProcessedCaseObj, index?: null|number, isParent: boolean, resizeCounter: number} & ITableProps; export const PortraitViewRow = (props: PortraitViewRowProps) => { const {paddingStyle, mapCellsFromValues, mapHeadersFromValues, showHeaders, - getClassName, collectionId, caseObj, index, isParent} = props; + getClassName, collectionId, caseObj, index, isParent, resizeCounter} = props; const {children, values} = caseObj; @@ -30,7 +30,7 @@ export const PortraitViewRow = (props: PortraitViewRowProps) => { } - {mapCellsFromValues(collectionId, `parent-row-${index}`, values, isParent)} + {mapCellsFromValues(collectionId, `parent-row-${index}`, values, isParent, resizeCounter)} @@ -70,6 +70,35 @@ export const PortraitView = (props: ITableProps) => { const {collectionClasses, selectedDataSet, collections, getValueLength} = props; const tableRef = useRef(null); const tableScrollTop = useTableScrollTop(tableRef); + const [resizeCounter, setResizeCounter] = React.useState(0); + + const thresh = useMemo(() => { + const t: number[] = []; + for (let i = 0; i <= 100; i++) { + t.push(i/100); + } + return t; + }, []); + + + useEffect(() => { + const handleIntersection = (entries: IntersectionObserverEntry[], o: any) => { + setResizeCounter((prevState) => prevState + 1); + }; + + const observer = new IntersectionObserver(handleIntersection, {threshold: thresh}); + + document.querySelectorAll(`.parent-row`).forEach((row) => { + observer.observe(row); + }); + + return () => { + document.querySelectorAll(`.parent-row`).forEach((row) => { + observer.unobserve(row); + }); + }; + + }, [thresh]); const renderTable = () => { const parentColl = collections.filter((coll: ICollection) => !coll.parent)[0]; @@ -95,6 +124,7 @@ export const PortraitView = (props: ITableProps) => { caseObj={caseObj} index={index} isParent={true} + resizeCounter={resizeCounter} /> ))} diff --git a/src/types.tsx b/src/types.tsx index c10ea8e..3f6e97c 100644 --- a/src/types.tsx +++ b/src/types.tsx @@ -55,7 +55,7 @@ export interface ITableProps { getClassName: (caseObj: IProcessedCaseObj) => string, selectedDataSet: IDataSet, collections: Array, - mapCellsFromValues: (collectionId: number, rowKey: string, values: IValues, isParent?: boolean) => void, + mapCellsFromValues: (collectionId: number, rowKey: string, values: IValues, isParent?: boolean, resizeCounter?: number) => void, mapHeadersFromValues: (collectionId: number, rowKey: string, values: IValues) => void, getValueLength: (firstRow: Array) => number paddingStyle: Record