From b59c86f78f2c783464bb3a01628d946f86b707ac Mon Sep 17 00:00:00 2001 From: jeffvli Date: Fri, 6 Jan 2023 11:44:50 -0800 Subject: [PATCH] Add hook to fix table header to detail header --- .../hooks/use-fixed-table-header.tsx | 30 +++++++++++++++++++ .../components/virtual-table/index.tsx | 2 ++ src/renderer/styles/ag-grid.scss | 15 ++++++++++ src/renderer/styles/global.scss | 1 + 4 files changed, 48 insertions(+) create mode 100644 src/renderer/components/virtual-table/hooks/use-fixed-table-header.tsx create mode 100644 src/renderer/styles/ag-grid.scss diff --git a/src/renderer/components/virtual-table/hooks/use-fixed-table-header.tsx b/src/renderer/components/virtual-table/hooks/use-fixed-table-header.tsx new file mode 100644 index 00000000..f7acb778 --- /dev/null +++ b/src/renderer/components/virtual-table/hooks/use-fixed-table-header.tsx @@ -0,0 +1,30 @@ +import { useEffect, useRef } from 'react'; +import { useInView } from 'framer-motion'; + +export const useFixedTableHeader = () => { + const intersectRef = useRef(null); + const tableContainerRef = useRef(null); + + const isNotPastTableIntersection = useInView(intersectRef, { + margin: '-64px 0px 0px 0px', + }); + + const tableInView = useInView(tableContainerRef, { + margin: '-128px 0px 0px 0px', + }); + + useEffect(() => { + const header = document.querySelector('.ag-header'); + const root = document.querySelector('.ag-root'); + + if (isNotPastTableIntersection || !tableInView) { + header?.classList.remove('ag-header-fixed'); + root?.classList.remove('ag-header-fixed-margin'); + } else { + header?.classList.add('ag-header-fixed'); + root?.classList.add('ag-header-fixed-margin'); + } + }, [isNotPastTableIntersection, tableInView]); + + return { intersectRef, tableContainerRef }; +}; diff --git a/src/renderer/components/virtual-table/index.tsx b/src/renderer/components/virtual-table/index.tsx index 6231b60d..be7ccd58 100644 --- a/src/renderer/components/virtual-table/index.tsx +++ b/src/renderer/components/virtual-table/index.tsx @@ -29,6 +29,7 @@ import { FavoriteCell } from '/@/renderer/components/virtual-table/cells/favorit export * from './table-config-dropdown'; export * from './table-pagination'; +export * from './hooks/use-fixed-table-header'; const TableWrapper = styled.div` display: flex; @@ -325,6 +326,7 @@ export const VirtualTable = forwardRef( ref={mergedRef} suppressMoveWhenRowDragging suppressScrollOnNewData + headerHeight={36} rowBuffer={30} {...rest} /> diff --git a/src/renderer/styles/ag-grid.scss b/src/renderer/styles/ag-grid.scss new file mode 100644 index 00000000..ea500f2b --- /dev/null +++ b/src/renderer/styles/ag-grid.scss @@ -0,0 +1,15 @@ +.ag-header-fixed { + position: fixed !important; + top: 61px; + z-index: 5; + background: #181818 !important; + margin: 0 -24px; + padding: 0 24px; + border-bottom: 1px solid hsla(0, 0%, 100%, 0.1); + box-shadow: 0 -1px 0 0 #181818; + transition: position 0.2s ease-in-out; +} + +.ag-header-fixed-margin { + margin-top: 49px !important; +} diff --git a/src/renderer/styles/global.scss b/src/renderer/styles/global.scss index aa0725eb..c29de7e4 100644 --- a/src/renderer/styles/global.scss +++ b/src/renderer/styles/global.scss @@ -1,6 +1,7 @@ @use '../themes/default.scss'; @use '../themes/dark.scss'; @use '../themes/light.scss'; +@use './ag-grid.scss'; * { box-sizing: border-box;