From 5c393c78497a8580a827018d4a91e17cca0ae563 Mon Sep 17 00:00:00 2001 From: Shaneeza Date: Fri, 13 Sep 2024 12:13:19 -0400 Subject: [PATCH 001/113] wip --- packages/table/package.json | 3 +- .../table/src/Table/TableWithVS.stories.tsx | 14 +++--- packages/table/src/index.ts | 1 + .../useLeafyGreenTable/useLeafyGreenTable.tsx | 15 ------ .../src/useLeafyGreenVirtualTable/index.ts | 3 ++ .../useLeafyGreenVirtualTable.spec.tsx | 0 .../useLeafyGreenVirtualTable.tsx | 48 +++++++++++++++++++ .../useLeafyGreenVirtualTable.types.ts | 0 yarn.lock | 30 ++++++++---- 9 files changed, 82 insertions(+), 32 deletions(-) create mode 100644 packages/table/src/useLeafyGreenVirtualTable/index.ts create mode 100644 packages/table/src/useLeafyGreenVirtualTable/useLeafyGreenVirtualTable.spec.tsx create mode 100644 packages/table/src/useLeafyGreenVirtualTable/useLeafyGreenVirtualTable.tsx create mode 100644 packages/table/src/useLeafyGreenVirtualTable/useLeafyGreenVirtualTable.types.ts diff --git a/packages/table/package.json b/packages/table/package.json index 933c31b15e..325a589a19 100644 --- a/packages/table/package.json +++ b/packages/table/package.json @@ -33,7 +33,8 @@ "@leafygreen-ui/tokens": "^2.9.0", "@leafygreen-ui/typography": "^19.2.0", "@lg-tools/test-harnesses": "^0.1.2", - "@tanstack/react-table": "^8.13.2", + "@tanstack/react-table": "^8.20.5", + "@tanstack/react-virtual": "^3.10.7", "lodash": "^4.17.21", "polished": "^4.2.2", "react-virtual": "^2.10.4" diff --git a/packages/table/src/Table/TableWithVS.stories.tsx b/packages/table/src/Table/TableWithVS.stories.tsx index e35fa044a9..621843ee29 100644 --- a/packages/table/src/Table/TableWithVS.stories.tsx +++ b/packages/table/src/Table/TableWithVS.stories.tsx @@ -23,7 +23,7 @@ import { TableBody, TableHead, type TableProps, - useLeafyGreenTable, + useLeafyGreenVirtualTable, type VirtualItem, } from '..'; @@ -98,7 +98,7 @@ export const Basic: StoryFn = args => { const columns = useMemo(() => basicColumnDefs, []); - const table = useLeafyGreenTable({ + const table = useLeafyGreenVirtualTable({ containerRef: tableContainerRef, data, columns, @@ -168,7 +168,7 @@ export const NestedRows: StoryFn = args => { const columns = useMemo(() => basicColumnDefs, []); - const table = useLeafyGreenTable({ + const table = useLeafyGreenVirtualTable({ containerRef: tableContainerRef, data, columns, @@ -326,7 +326,7 @@ export const SortableRows: StoryFn = args => { [], ); - const table = useLeafyGreenTable({ + const table = useLeafyGreenVirtualTable({ containerRef: tableContainerRef, data, columns, @@ -401,7 +401,7 @@ export const SelectableRows: StoryFn = args => { const columns = useMemo(() => basicColumnDefs, []); - const table = useLeafyGreenTable({ + const table = useLeafyGreenVirtualTable({ containerRef: tableContainerRef, data, columns, @@ -476,7 +476,7 @@ export const ExpandableContent: StoryFn = args => { const columns = useMemo(() => basicColumnDefs, []); - const table = useLeafyGreenTable({ + const table = useLeafyGreenVirtualTable({ containerRef: tableContainerRef, data, columns, @@ -561,7 +561,7 @@ export const TallRows: StoryFn = args => { const columns = useMemo(() => basicColumnDefs, []); const estimateSize = useCallback(() => 100, []); - const table = useLeafyGreenTable({ + const table = useLeafyGreenVirtualTable({ containerRef: tableContainerRef, data, columns, diff --git a/packages/table/src/index.ts b/packages/table/src/index.ts index e8cd1011d1..c770a3c865 100644 --- a/packages/table/src/index.ts +++ b/packages/table/src/index.ts @@ -26,6 +26,7 @@ export { type LGTableDataType, default as useLeafyGreenTable, } from './useLeafyGreenTable'; +export { default as useLeafyGreenVirtualTable } from './useLeafyGreenVirtualTable'; export { getTestUtils } from './utils/getTestUtils'; export { default as V11Adapter, type V11AdapterProps } from './V11Adapter'; export * from '@tanstack/react-table'; diff --git a/packages/table/src/useLeafyGreenTable/useLeafyGreenTable.tsx b/packages/table/src/useLeafyGreenTable/useLeafyGreenTable.tsx index 91f1989dc3..f2152d93e7 100644 --- a/packages/table/src/useLeafyGreenTable/useLeafyGreenTable.tsx +++ b/packages/table/src/useLeafyGreenTable/useLeafyGreenTable.tsx @@ -1,5 +1,4 @@ import React from 'react'; -import { useVirtual } from 'react-virtual'; import { useReactTable } from '@tanstack/react-table'; import { getCoreRowModel, @@ -21,7 +20,6 @@ function useLeafyGreenTable({ columns: columnsProp, hasSelectableRows, withPagination = false, - useVirtualScrolling = false, allowSelectAll = true, virtualizerOptions, ...rest @@ -72,21 +70,8 @@ function useLeafyGreenTable({ ...rest, }); - const { rows } = table.getRowModel(); - const _rowVirtualizer = useVirtual({ - parentRef: containerRef, - size: rows.length, - overscan: 30, - ...virtualizerOptions, - }); - return { ...table, - ...(useVirtualScrolling && { - virtualRows: _rowVirtualizer.virtualItems, - totalSize: _rowVirtualizer.totalSize, - scrollToIndex: _rowVirtualizer.scrollToIndex, - }), hasSelectableRows, } as LeafyGreenTable; } diff --git a/packages/table/src/useLeafyGreenVirtualTable/index.ts b/packages/table/src/useLeafyGreenVirtualTable/index.ts new file mode 100644 index 0000000000..aa5e66a8b8 --- /dev/null +++ b/packages/table/src/useLeafyGreenVirtualTable/index.ts @@ -0,0 +1,3 @@ +import useLeafyGreenVirtualTable from './useLeafyGreenVirtualTable'; + +export default useLeafyGreenVirtualTable; diff --git a/packages/table/src/useLeafyGreenVirtualTable/useLeafyGreenVirtualTable.spec.tsx b/packages/table/src/useLeafyGreenVirtualTable/useLeafyGreenVirtualTable.spec.tsx new file mode 100644 index 0000000000..e69de29bb2 diff --git a/packages/table/src/useLeafyGreenVirtualTable/useLeafyGreenVirtualTable.tsx b/packages/table/src/useLeafyGreenVirtualTable/useLeafyGreenVirtualTable.tsx new file mode 100644 index 0000000000..19fb341c62 --- /dev/null +++ b/packages/table/src/useLeafyGreenVirtualTable/useLeafyGreenVirtualTable.tsx @@ -0,0 +1,48 @@ +import { useVirtual } from 'react-virtual'; + +import useLeafyGreenTable, { + LeafyGreenTable, + LeafyGreenTableOptions, + LGRowData, +} from '../useLeafyGreenTable'; + +function useLeafyGreenVirtualTable< + T extends LGRowData, + V extends unknown = unknown, +>({ + containerRef, + data, + columns, + hasSelectableRows, + withPagination = false, + allowSelectAll = true, + virtualizerOptions, + ...rest +}: LeafyGreenTableOptions): LeafyGreenTable { + const table = useLeafyGreenTable({ + containerRef, + data, + columns, + withPagination, + allowSelectAll, + ...rest, + }); + + const { rows } = table.getRowModel(); + const _rowVirtualizer = useVirtual({ + parentRef: containerRef, + size: rows.length, + overscan: 30, + ...virtualizerOptions, + }); + + return { + ...table, + virtualRows: _rowVirtualizer.virtualItems, + totalSize: _rowVirtualizer.totalSize, + scrollToIndex: _rowVirtualizer.scrollToIndex, + hasSelectableRows, + } as LeafyGreenTable; +} + +export default useLeafyGreenVirtualTable; diff --git a/packages/table/src/useLeafyGreenVirtualTable/useLeafyGreenVirtualTable.types.ts b/packages/table/src/useLeafyGreenVirtualTable/useLeafyGreenVirtualTable.types.ts new file mode 100644 index 0000000000..e69de29bb2 diff --git a/yarn.lock b/yarn.lock index b7e6063baa..de8a962941 100644 --- a/yarn.lock +++ b/yarn.lock @@ -5642,17 +5642,29 @@ resolved "https://registry.yarnpkg.com/@swc/types/-/types-0.1.5.tgz#043b731d4f56a79b4897a3de1af35e75d56bc63a" integrity sha512-myfUej5naTBWnqOCc/MdVOLVjXUXtIA+NpDrDBKJtLLg2shUjBu3cZmB/85RyitKc55+lUUyl7oRfLOvkr2hsw== -"@tanstack/react-table@^8.13.2": - version "8.13.2" - resolved "https://registry.yarnpkg.com/@tanstack/react-table/-/react-table-8.13.2.tgz#a3aa737ae464abc651f68daa7e82dca17813606c" - integrity sha512-b6mR3mYkjRtJ443QZh9sc7CvGTce81J35F/XMr0OoWbx0KIM7TTTdyNP2XKObvkLpYnLpCrYDwI3CZnLezWvpg== +"@tanstack/react-table@^8.20.5": + version "8.20.5" + resolved "https://registry.yarnpkg.com/@tanstack/react-table/-/react-table-8.20.5.tgz#19987d101e1ea25ef5406dce4352cab3932449d8" + integrity sha512-WEHopKw3znbUZ61s9i0+i9g8drmDo6asTWbrQh8Us63DAk/M0FkmIqERew6P71HI75ksZ2Pxyuf4vvKh9rAkiA== dependencies: - "@tanstack/table-core" "8.13.2" + "@tanstack/table-core" "8.20.5" -"@tanstack/table-core@8.13.2": - version "8.13.2" - resolved "https://registry.yarnpkg.com/@tanstack/table-core/-/table-core-8.13.2.tgz#2512574dd3d20dc94b7db1f9f48090f0c18b5c85" - integrity sha512-/2saD1lWBUV6/uNAwrsg2tw58uvMJ07bO2F1IWMxjFRkJiXKQRuc3Oq2aufeobD3873+4oIM/DRySIw7+QsPPw== +"@tanstack/react-virtual@^3.10.7": + version "3.10.7" + resolved "https://registry.yarnpkg.com/@tanstack/react-virtual/-/react-virtual-3.10.7.tgz#428d0c29c6d2046ab905f4278446a3fe89bfd4ef" + integrity sha512-yeP+M0G8D+15ZFPivpuQ5hoM4Fa/PzERBx8P8EGcfEsXX3JOb9G9UUrqc47ZXAxvK+YqzM9T5qlJUYUFOwCZJw== + dependencies: + "@tanstack/virtual-core" "3.10.7" + +"@tanstack/table-core@8.20.5": + version "8.20.5" + resolved "https://registry.yarnpkg.com/@tanstack/table-core/-/table-core-8.20.5.tgz#3974f0b090bed11243d4107283824167a395cf1d" + integrity sha512-P9dF7XbibHph2PFRz8gfBKEXEY/HJPOhym8CHmjF8y3q5mWpKx9xtZapXQUWCgkqvsK0R46Azuz+VaxD4Xl+Tg== + +"@tanstack/virtual-core@3.10.7": + version "3.10.7" + resolved "https://registry.yarnpkg.com/@tanstack/virtual-core/-/virtual-core-3.10.7.tgz#fb1d8ae1257c9fe3a6e99c911cad0d1a1b07f598" + integrity sha512-ND5dfsU0n9F4gROzwNNDJmg6y8n9pI8YWxtgbfJ5UcNn7Hx+MxEXtXcQ189tS7sh8pmCObgz2qSiyRKTZxT4dg== "@testing-library/dom@9.3.1", "@testing-library/dom@^9.0.0": version "9.3.1" From 82f8e100202e4d5501ed6135c5e872439d3a4df2 Mon Sep 17 00:00:00 2001 From: Shaneeza Date: Thu, 19 Sep 2024 14:55:15 -0400 Subject: [PATCH 002/113] wip --- .../table/src/Cell/HeaderCell/HeaderCell.tsx | 5 +- packages/table/src/Cell/InternalCell.tsx | 8 +- packages/table/src/Row/InternalRowWithRT.tsx | 27 +++-- packages/table/src/Row/Row.types.ts | 2 +- packages/table/src/Table.stories.tsx | 7 -- packages/table/src/Table/Table.styles.ts | 56 ++++++++++ packages/table/src/Table/Table.tsx | 103 +++++++++++++++++- packages/table/src/Table/Table.types.ts | 3 +- .../table/src/Table/TableWithVS.stories.tsx | 61 ++++++----- packages/table/src/Table/VirtualTable.tsx | 0 packages/table/src/TableBody/TableBody.tsx | 28 ++--- packages/table/src/index.ts | 3 +- .../useLeafyGreenTable.types.ts | 22 ++-- .../ReactVirtual.types.ts | 3 + .../useLeafyGreenVirtualTable.tsx | 38 ++++--- .../useLeafyGreenVirtualTable.types.ts | 34 ++++++ 16 files changed, 309 insertions(+), 91 deletions(-) create mode 100644 packages/table/src/Table/VirtualTable.tsx create mode 100644 packages/table/src/useLeafyGreenVirtualTable/ReactVirtual.types.ts diff --git a/packages/table/src/Cell/HeaderCell/HeaderCell.tsx b/packages/table/src/Cell/HeaderCell/HeaderCell.tsx index 9616625bda..9a7ee85274 100644 --- a/packages/table/src/Cell/HeaderCell/HeaderCell.tsx +++ b/packages/table/src/Cell/HeaderCell/HeaderCell.tsx @@ -1,6 +1,6 @@ import React, { PropsWithChildren } from 'react'; -import { cx } from '@leafygreen-ui/emotion'; +import { css, cx } from '@leafygreen-ui/emotion'; import { LGIDS } from '../../constants'; import { useTableContext } from '../../TableContext'; @@ -61,6 +61,9 @@ const HeaderCell = ({ !!header?.getSize(), }, className, + // css` + // width: ${header.getSize()}px; + // `, )} scope="col" {...rest} diff --git a/packages/table/src/Cell/InternalCell.tsx b/packages/table/src/Cell/InternalCell.tsx index ccd556d188..c22176884b 100644 --- a/packages/table/src/Cell/InternalCell.tsx +++ b/packages/table/src/Cell/InternalCell.tsx @@ -1,7 +1,7 @@ import React, { useMemo, useRef } from 'react'; import PropTypes from 'prop-types'; -import { cx } from '@leafygreen-ui/emotion'; +import { css, cx } from '@leafygreen-ui/emotion'; import { LGIDS } from '../constants'; import { useTableContext } from '../TableContext'; @@ -65,6 +65,12 @@ const InternalCell = ({ [truncatedContentStyles]: shouldTruncate, }, contentClassName, + // css` + // ${!!table.virtual && + // css` + // transform: translateY(${virtualRow.start}px); + // `} + // `, )} > {children} diff --git a/packages/table/src/Row/InternalRowWithRT.tsx b/packages/table/src/Row/InternalRowWithRT.tsx index dead3b986d..0ce63c1489 100644 --- a/packages/table/src/Row/InternalRowWithRT.tsx +++ b/packages/table/src/Row/InternalRowWithRT.tsx @@ -1,7 +1,7 @@ import React, { Fragment, useMemo } from 'react'; -import { VirtualItem } from 'react-virtual'; +import { VirtualItem } from '@tanstack/react-virtual'; -import { cx } from '@leafygreen-ui/emotion'; +import { css, cx } from '@leafygreen-ui/emotion'; import { useDarkMode } from '@leafygreen-ui/leafygreen-provider'; import { HTMLElementProps } from '@leafygreen-ui/lib'; import { Polymorph } from '@leafygreen-ui/polymorphic'; @@ -34,7 +34,7 @@ const InternalRowWithRT = ({ const { disabled } = useRowContext(); const { table, getParentRow, shouldAlternateRowColor } = useTableContext(); const parentRow = getParentRow?.(row.id); - const rowRef = virtualRow?.measureRef; + // const rowRef = virtualRow?.measureRef; const isTableExpandable = table?.getCanSomeRowsExpand(); const isNested = !!parentRow; @@ -45,6 +45,10 @@ const InternalRowWithRT = ({ const isExpanded = row.getIsExpanded(); const isSelected = row.getIsSelected(); + // const isVirtualRow = !!virtualRow; + + // console.log({ isVirtualRow }); + /** * Render the row within a `tbody` if * the table itself has any row that is expandable @@ -56,14 +60,12 @@ const InternalRowWithRT = ({ [shouldRenderAsTBody], ); - const tBodyProps: HTMLElementProps<'tbody'> & - Pick = { + const tBodyProps: HTMLElementProps<'tbody'> & VirtualItem = { className: cx({ [expandedContentParentStyles[theme]]: isExpanded, }), + // @ts-ignore - TODO: ? 'data-expanded': isExpanded, - // @ts-expect-error - VirtualItem.measureRef is not typed as a ref - ref: rowRef, }; return ( @@ -78,11 +80,22 @@ const InternalRowWithRT = ({ [selectedRowStyles[theme]]: isSelected && !disabled, }, className, + css` + ${!!virtualRow && + css` + /* transform: translateY(${virtualRow.start}px); */ + /* transform: translateY( + ${virtualRow.start - virtualRow.index * virtualRow.size}px + ); */ + `} + `, )} data-selected={isSelected} aria-hidden={!isRowVisible} data-expanded={isExpanded} id={`lg-table-row-${row.id}`} + // ref={table.virtual.measureElement} + // data-index={virtualRow!.index ?? ''} {...rest} > {children} diff --git a/packages/table/src/Row/Row.types.ts b/packages/table/src/Row/Row.types.ts index 1a3b74600f..7f02fb1178 100644 --- a/packages/table/src/Row/Row.types.ts +++ b/packages/table/src/Row/Row.types.ts @@ -1,4 +1,4 @@ -import { VirtualItem } from 'react-virtual'; +import { VirtualItem } from '@tanstack/react-virtual'; import { HTMLElementProps } from '@leafygreen-ui/lib'; diff --git a/packages/table/src/Table.stories.tsx b/packages/table/src/Table.stories.tsx index b73f23e92d..65b12f7f14 100644 --- a/packages/table/src/Table.stories.tsx +++ b/packages/table/src/Table.stories.tsx @@ -161,7 +161,6 @@ export const LiveExample: StoryFn = args => { ); const table = useLeafyGreenTable({ - containerRef: tableContainerRef, data, columns, }); @@ -346,7 +345,6 @@ export const NestedRows: StoryFn = args => { ); const table = useLeafyGreenTable({ - containerRef: tableContainerRef, data, columns, }); @@ -479,7 +477,6 @@ export const ExpandableContent: StoryFn = args => { ); const table = useLeafyGreenTable({ - containerRef: tableContainerRef, data, columns, }); @@ -582,7 +579,6 @@ export const SortableRows: StoryFn = args => { ); const table = useLeafyGreenTable({ - containerRef: tableContainerRef, data, columns, }); @@ -676,7 +672,6 @@ export const SelectableRows: StoryFn = args => { ); const table = useLeafyGreenTable({ - containerRef: tableContainerRef, data, columns, state: { @@ -803,7 +798,6 @@ export const SelectableRowsNoSelectAll: StoryFn = args => { ); const table = useLeafyGreenTable({ - containerRef: tableContainerRef, data, columns, state: { @@ -934,7 +928,6 @@ export const WithPagination: StoryFn = ({ ); const table = useLeafyGreenTable({ - containerRef: tableContainerRef, data, columns, withPagination: true, diff --git a/packages/table/src/Table/Table.styles.ts b/packages/table/src/Table/Table.styles.ts index 5efb933f61..b78cb4009b 100644 --- a/packages/table/src/Table/Table.styles.ts +++ b/packages/table/src/Table/Table.styles.ts @@ -6,6 +6,12 @@ export const baseStyles = css` border-spacing: 0; border-collapse: collapse; width: 100%; + + &:after { + content: ''; + display: block; + height: var(--pseudo-height); + } `; export const themeStyles: Record = { @@ -22,3 +28,53 @@ export const tableContainerStyles = css` width: 100%; position: relative; `; + +// export const getTableContainerStyles = ( +// isVirtual = false, +// virtualizer: {}, +// ) => css` +// ${isVirtual && +// css` +// table { +// display: grid; +// } + +// thead { +// display: grid; +// top: 0; +// z-index: 1; + +// tr { +// display: flex; +// width: 100%; +// } + +// th { +// display: flex; +// /* width: 100%; */ +// box-sizing: content-box; +// } +// } + +// th { +// display: flex; +// } + +// tbody { +// display: grid; +// position: relative; +// height: ${virtualizer.getTotalSize()}px; + +// tr { +// display: flex; +// position: absolute; +// width: 100%; +// } + +// td { +// display: flex; +// box-sizing: content-box; +// } +// } +// `} +// `; diff --git a/packages/table/src/Table/Table.tsx b/packages/table/src/Table/Table.tsx index 7b94d7f8f6..670faf6562 100644 --- a/packages/table/src/Table/Table.tsx +++ b/packages/table/src/Table/Table.tsx @@ -1,7 +1,8 @@ -import React, { ForwardedRef, forwardRef } from 'react'; +import React, { ForwardedRef, forwardRef, useRef } from 'react'; import PropTypes from 'prop-types'; import { cx } from '@leafygreen-ui/emotion'; +import { useForwardedRef } from '@leafygreen-ui/hooks'; import { useDarkMode } from '@leafygreen-ui/leafygreen-provider'; import { BaseFontSize } from '@leafygreen-ui/tokens'; import { @@ -13,9 +14,33 @@ import { LGIDS } from '../constants'; import { TableContextProvider } from '../TableContext'; import { LGRowData } from '../useLeafyGreenTable'; -import { baseStyles, tableContainerStyles, themeStyles } from './Table.styles'; +// import { LeafyGreenVirtualTable } from '../useLeafyGreenVirtualTable/useLeafyGreenVirtualTable.types'; +import { + baseStyles, + // getTableContainerStyles, + tableContainerStyles, + themeStyles, +} from './Table.styles'; import { TableProps } from './Table.types'; +// const adjustTableHeight = (tableRef, virtualHeight) => { +// if (!tableRef.current) return; + +// // calculate the height for the pseudo element after the table +// const existingPseudoElement = window.getComputedStyle( +// tableRef.current, +// '::after', +// ); +// const existingPseudoHeight = parseFloat(existingPseudoElement.height) || 0; +// const tableHeight = tableRef.current.clientHeight - existingPseudoHeight; +// const pseudoHeight = Math.max(virtualHeight - tableHeight, 0); +// document.documentElement.style.setProperty( +// '--pseudo-height', +// `${pseudoHeight}px`, +// ); +// return pseudoHeight; +// }; + // Inferred generic type from component gets used in place of `any` const Table = forwardRef>( ( @@ -34,15 +59,84 @@ const Table = forwardRef>( ) => { const baseFontSize: BaseFontSize = useUpdatedBaseFontSize(baseFontSizeProp); const { theme, darkMode } = useDarkMode(darkModeProp); + // const isVirtual = !!(table as LeafyGreenVirtualTable)!.virtual ?? false; + // const virtualTable = (table as LeafyGreenVirtualTable)!.virtual; + // console.log({ isVirtual }); + + const parentRef = useForwardedRef(containerRef, null); + const tableRef = useRef(null); + // const [isScrollNearBottom, setIsScrollNearBottom] = useState(false); + + // const virtualizer = table.virtual; + + // const virtualItems = virtualizer.getVirtualItems(); + // const virtualSize = virtualizer.getTotalSize(); + + // // callback to adjust the height of the pseudo element + // const handlePseudoResize = useCallback(() => { + // return adjustTableHeight(tableRef, virtualSize); + // }, [tableRef, virtualSize]); + + // // callback to handle scrolling, checking if we are near the bottom + // const handleScroll = useCallback(() => { + // if (parentRef.current) { + // const scrollPosition = parentRef.current?.scrollTop; + // const visibleHeight = parentRef.current?.clientHeight; + // setIsScrollNearBottom( + // scrollPosition > virtualSize * 0.95 - visibleHeight, + // ); + // } + // }, [parentRef, virtualSize]); + + // add an event listener on the scrollable parent container and resize the + // pseudo element whenever the table renders with new data + // useEffect(() => { + // const scrollable = parentRef.current; + // if (scrollable) scrollable.addEventListener('scroll', handleScroll); + // handlePseudoResize(); + + // return () => { + // if (scrollable) scrollable.removeEventListener('scroll', handleScroll); + // }; + // }, [handleScroll, handlePseudoResize]); + + // if we are near the bottom of the table, resize the pseudo element each time + // the length of virtual items changes (which is effectively the number of table + // rows rendered to the DOM). This ensures we don't scroll too far or too short. + // useEffect(() => { + // if (isScrollNearBottom) handlePseudoResize(); + // }, [isScrollNearBottom, virtualItems.length, handlePseudoResize]); return (
+ {/*
+
*/} + {/*
*/} >( bodyTypeScaleStyles[baseFontSize], )} data-lgid={lgidProp} + ref={tableRef} {...rest} > {children} diff --git a/packages/table/src/Table/Table.types.ts b/packages/table/src/Table/Table.types.ts index 5df40c00fa..8787527181 100644 --- a/packages/table/src/Table/Table.types.ts +++ b/packages/table/src/Table/Table.types.ts @@ -2,6 +2,7 @@ import { DarkModeProps, HTMLElementProps, LgIdProps } from '@leafygreen-ui/lib'; import { BaseFontSize } from '@leafygreen-ui/tokens'; import { LeafyGreenTable, LGRowData } from '../useLeafyGreenTable'; +import { LeafyGreenVirtualTable } from '../useLeafyGreenVirtualTable/useLeafyGreenVirtualTable.types'; export interface TableProps extends HTMLElementProps<'table'>, @@ -21,7 +22,7 @@ export interface TableProps /** * The `useLeafyGreenTable` return value */ - table?: LeafyGreenTable; + table?: LeafyGreenTable | LeafyGreenVirtualTable; /** * Disables all transition animations for smoother rendering of tall content where appropriate diff --git a/packages/table/src/Table/TableWithVS.stories.tsx b/packages/table/src/Table/TableWithVS.stories.tsx index 621843ee29..112f26bff4 100644 --- a/packages/table/src/Table/TableWithVS.stories.tsx +++ b/packages/table/src/Table/TableWithVS.stories.tsx @@ -51,18 +51,19 @@ export default meta; const virtualScrollingContainerHeight = css` max-height: calc(100vh - 200px); + /* height: calc(100vh - 200px); */ `; const basicColumnDefs: Array> = [ { accessorKey: 'index', header: 'index', - size: 10, + size: 40, }, { accessorKey: 'id', header: 'ID', - size: 45, + size: 60, }, { accessorKey: 'firstName', @@ -95,6 +96,7 @@ const basicColumnDefs: Array> = [ export const Basic: StoryFn = args => { const tableContainerRef = React.useRef(null); const data = React.useMemo(() => makeData(false, 10_000), []); + // const data = React.useMemo(() => makeData(false, 100), []); const columns = useMemo(() => basicColumnDefs, []); @@ -102,16 +104,18 @@ export const Basic: StoryFn = args => { containerRef: tableContainerRef, data, columns, - useVirtualScrolling: true, }); + // const virtualItems = table.virtual.getVirtualItems(); + const { rows } = table.getRowModel(); return ( <>
-

{table.getRowModel().rows.length} total rows

-

{table?.virtualRows?.length} virtual rows

+

{table.getRowModel().rows.length} total rowsjsfjsh

+

{table?.virtual.getVirtualItems().length} virtual rows

+

{table?.virtual.getTotalSize()} virtual rows

= args => { ))} - {table.virtualRows && - table.virtualRows.map((virtualRow: VirtualItem) => { + {table.virtual.getVirtualItems() && + table.virtual.getVirtualItems().map((virtualRow: VirtualItem) => { const row = rows[virtualRow.index]; const cells = row.getVisibleCells(); return ( - + {cells.map((cell: LeafyGreenTableCell) => { return ( - + {flexRender( cell.column.columnDef.cell, cell.getContext(), @@ -172,10 +181,10 @@ export const NestedRows: StoryFn = args => { containerRef: tableContainerRef, data, columns, - useVirtualScrolling: true, }); const { rows } = table.getRowModel(); + const virtualItems = table.virtual.getVirtualItems(); return ( <> @@ -206,8 +215,8 @@ export const NestedRows: StoryFn = args => { ))} - {table.virtualRows && - table.virtualRows.map((virtualRow: VirtualItem) => { + {virtualItems && + virtualItems.map((virtualRow: VirtualItem) => { const row = rows[virtualRow.index]; const cells = row.getVisibleCells(); @@ -334,10 +343,10 @@ export const SortableRows: StoryFn = args => { sorting, }, onSortingChange: setSorting, - useVirtualScrolling: true, }); const { rows } = table.getRowModel(); + const virtualItems = table.virtual.getVirtualItems(); return ( <> @@ -368,8 +377,8 @@ export const SortableRows: StoryFn = args => { ))} - {table.virtualRows && - table.virtualRows.map((virtualRow: VirtualItem) => { + {virtualItems && + virtualItems.map((virtualRow: VirtualItem) => { const row = rows[virtualRow.index]; const cells = row.getVisibleCells(); @@ -410,10 +419,10 @@ export const SelectableRows: StoryFn = args => { }, onRowSelectionChange: setRowSelection, hasSelectableRows: true, - useVirtualScrolling: true, }); const { rows } = table.getRowModel(); + const virtualItems = table.virtual.getVirtualItems(); return ( <> @@ -443,8 +452,8 @@ export const SelectableRows: StoryFn = args => { ))} - {table.virtualRows && - table.virtualRows.map((virtualRow: VirtualItem) => { + {virtualItems && + virtualItems.map((virtualRow: VirtualItem) => { const row = rows[virtualRow.index]; const cells = row.getVisibleCells(); @@ -484,10 +493,10 @@ export const ExpandableContent: StoryFn = args => { expanded, }, onExpandedChange: setExpanded, - useVirtualScrolling: true, }); const { rows } = table.getRowModel(); + const virtualItems = table.virtual.getVirtualItems(); return ( <> @@ -518,8 +527,8 @@ export const ExpandableContent: StoryFn = args => { ))} - {table.virtualRows && - table.virtualRows.map((virtualRow: VirtualItem) => { + {virtualItems && + virtualItems.map((virtualRow: VirtualItem) => { const row = rows[virtualRow.index]; const cells = row.getVisibleCells(); @@ -559,25 +568,25 @@ export const TallRows: StoryFn = args => { }, []); const columns = useMemo(() => basicColumnDefs, []); - const estimateSize = useCallback(() => 100, []); + const estimateSize = useCallback(() => 68, []); const table = useLeafyGreenVirtualTable({ containerRef: tableContainerRef, data, columns, - useVirtualScrolling: true, virtualizerOptions: { estimateSize, }, }); const { rows } = table.getRowModel(); + const virtualItems = table.virtual.getVirtualItems(); return ( <>

{table.getRowModel().rows.length} total rows

-

{table?.virtualRows?.length} virtual rows

+

{table?.virtual.getVirtualItems().length} virtual rows

= args => { ))} - {table.virtualRows && - table.virtualRows.map((virtualRow: VirtualItem) => { + {virtualItems && + virtualItems.map((virtualRow: VirtualItem) => { const row = rows[virtualRow.index]; const cells = row.getVisibleCells(); return ( diff --git a/packages/table/src/Table/VirtualTable.tsx b/packages/table/src/Table/VirtualTable.tsx new file mode 100644 index 0000000000..e69de29bb2 diff --git a/packages/table/src/TableBody/TableBody.tsx b/packages/table/src/TableBody/TableBody.tsx index 35d409fd01..9faf47cde0 100644 --- a/packages/table/src/TableBody/TableBody.tsx +++ b/packages/table/src/TableBody/TableBody.tsx @@ -7,8 +7,8 @@ import { useTableContext } from '../TableContext'; import { TableBodyProps } from './TableBody.types'; const TableBody = ({ children, ...rest }: TableBodyProps) => { - let paddingTop = 0; - let paddingBottom = 0; + // const paddingTop = 0; + // const paddingBottom = 0; const { table } = useTableContext(); const areSomeRowsExpandable = table?.getCanSomeRowsExpand(); @@ -18,30 +18,30 @@ const TableBody = ({ children, ...rest }: TableBodyProps) => { [areSomeRowsExpandable], ); - if (table && table.virtualRows) { - const { virtualRows, totalSize } = table; - paddingTop = virtualRows.length > 0 ? virtualRows?.[0]?.start || 0 : 0; - paddingBottom = - virtualRows.length > 0 - ? totalSize - (virtualRows?.[virtualRows.length - 1]?.end || 0) - : 0; - } + // if (table && table.virtualRows) { + // const { virtualRows, totalSize } = table; + // paddingTop = virtualRows.length > 0 ? virtualRows?.[0]?.start || 0 : 0; + // paddingBottom = + // virtualRows.length > 0 + // ? totalSize - (virtualRows?.[virtualRows.length - 1]?.end || 0) + // : 0; + // } return ( {/* As the user scrolls down, the paddingTop grows bigger, creating the effect of virtual scrolling */} - {paddingTop > 0 && ( + {/* {paddingTop > 0 && ( - )} + )} */} {children} {/* As the user scrolls down, the paddingBottom gets smaller, creating the effect of virtual scrolling */} - {paddingBottom > 0 && ( + {/* {paddingBottom > 0 && ( - )} + )} */} ); }; diff --git a/packages/table/src/index.ts b/packages/table/src/index.ts index c770a3c865..43c45d0966 100644 --- a/packages/table/src/index.ts +++ b/packages/table/src/index.ts @@ -30,4 +30,5 @@ export { default as useLeafyGreenVirtualTable } from './useLeafyGreenVirtualTabl export { getTestUtils } from './utils/getTestUtils'; export { default as V11Adapter, type V11AdapterProps } from './V11Adapter'; export * from '@tanstack/react-table'; -export { type VirtualItem } from 'react-virtual'; +// export { type VirtualItem } from 'react-virtual'; +export { type VirtualItem } from '@tanstack/react-virtual'; diff --git a/packages/table/src/useLeafyGreenTable/useLeafyGreenTable.types.ts b/packages/table/src/useLeafyGreenTable/useLeafyGreenTable.types.ts index 59a35b51ac..b5a30a58ff 100644 --- a/packages/table/src/useLeafyGreenTable/useLeafyGreenTable.types.ts +++ b/packages/table/src/useLeafyGreenTable/useLeafyGreenTable.types.ts @@ -1,8 +1,8 @@ import { RefObject } from 'react'; -import { - type Options as VirtualizerOptions, - type VirtualItem, -} from 'react-virtual'; +// import { +// type Options as VirtualizerOptions, +// type VirtualItem, +// } from 'react-virtual'; import { Cell, ColumnDef, @@ -14,7 +14,7 @@ import { import { HTMLElementProps } from '@leafygreen-ui/lib'; -import { VirtualizerValues } from './ReactVirtual.types'; +// import { VirtualizerValues } from './ReactVirtual.types'; /** LeafyGreen extension of `useReactTable` {@link RowData}*/ export type LGRowData = RowData; @@ -50,21 +50,21 @@ export type LeafyGreenTableOptions< T extends LGRowData, V extends unknown = unknown, > = Omit>, 'getCoreRowModel' | 'columns'> & { - containerRef: RefObject; + // containerRef: RefObject; hasSelectableRows?: boolean; columns: Array>; withPagination?: boolean; allowSelectAll?: boolean; - useVirtualScrolling?: boolean; - virtualizerOptions?: Partial>; + // useVirtualScrolling?: boolean; + // virtualizerOptions?: Partial>; }; /** * LeafyGreen extension of `useReactTable` {@link Table} */ export interface LeafyGreenTable - extends Table>, - Omit { - virtualRows?: Array; + extends Table> { + // Omit { + // virtualRows?: Array; hasSelectableRows: boolean; } diff --git a/packages/table/src/useLeafyGreenVirtualTable/ReactVirtual.types.ts b/packages/table/src/useLeafyGreenVirtualTable/ReactVirtual.types.ts new file mode 100644 index 0000000000..de318d90e1 --- /dev/null +++ b/packages/table/src/useLeafyGreenVirtualTable/ReactVirtual.types.ts @@ -0,0 +1,3 @@ +import { useVirtualizer } from '@tanstack/react-virtual'; + +export type VirtualizerValues = ReturnType; diff --git a/packages/table/src/useLeafyGreenVirtualTable/useLeafyGreenVirtualTable.tsx b/packages/table/src/useLeafyGreenVirtualTable/useLeafyGreenVirtualTable.tsx index 19fb341c62..52f0276fd0 100644 --- a/packages/table/src/useLeafyGreenVirtualTable/useLeafyGreenVirtualTable.tsx +++ b/packages/table/src/useLeafyGreenVirtualTable/useLeafyGreenVirtualTable.tsx @@ -1,10 +1,11 @@ -import { useVirtual } from 'react-virtual'; +import { useVirtualizer } from '@tanstack/react-virtual'; -import useLeafyGreenTable, { - LeafyGreenTable, - LeafyGreenTableOptions, - LGRowData, -} from '../useLeafyGreenTable'; +import useLeafyGreenTable, { LGRowData } from '../useLeafyGreenTable'; + +import { + LeafyGreenVirtualTable, + LeafyGreenVirtualTableOptions, +} from './useLeafyGreenVirtualTable.types'; function useLeafyGreenVirtualTable< T extends LGRowData, @@ -18,9 +19,8 @@ function useLeafyGreenVirtualTable< allowSelectAll = true, virtualizerOptions, ...rest -}: LeafyGreenTableOptions): LeafyGreenTable { +}: LeafyGreenVirtualTableOptions): LeafyGreenVirtualTable { const table = useLeafyGreenTable({ - containerRef, data, columns, withPagination, @@ -29,20 +29,24 @@ function useLeafyGreenVirtualTable< }); const { rows } = table.getRowModel(); - const _rowVirtualizer = useVirtual({ - parentRef: containerRef, - size: rows.length, - overscan: 30, + + const _virtualizer = useVirtualizer({ + count: rows.length, + getScrollElement: () => containerRef.current, + estimateSize: () => 40, + overscan: 20, + measureElement: + typeof window !== 'undefined' && + navigator.userAgent.indexOf('Firefox') === -1 + ? element => element?.getBoundingClientRect().height + : undefined, ...virtualizerOptions, }); return { ...table, - virtualRows: _rowVirtualizer.virtualItems, - totalSize: _rowVirtualizer.totalSize, - scrollToIndex: _rowVirtualizer.scrollToIndex, - hasSelectableRows, - } as LeafyGreenTable; + virtual: { ..._virtualizer }, + } as LeafyGreenVirtualTable; } export default useLeafyGreenVirtualTable; diff --git a/packages/table/src/useLeafyGreenVirtualTable/useLeafyGreenVirtualTable.types.ts b/packages/table/src/useLeafyGreenVirtualTable/useLeafyGreenVirtualTable.types.ts index e69de29bb2..f739974552 100644 --- a/packages/table/src/useLeafyGreenVirtualTable/useLeafyGreenVirtualTable.types.ts +++ b/packages/table/src/useLeafyGreenVirtualTable/useLeafyGreenVirtualTable.types.ts @@ -0,0 +1,34 @@ +import { RefObject } from 'react'; +import { + // VirtualItem, + Virtualizer, + VirtualizerOptions, +} from '@tanstack/react-virtual'; + +import { + LeafyGreenTable, + LeafyGreenTableOptions, + LGRowData, +} from '../useLeafyGreenTable'; + +/** + * Options argument for the LeafyGreen extension of `useReactTable` + * + * See: {@link TableOptions} + */ +export interface LeafyGreenVirtualTableOptions< + T extends LGRowData, + V extends unknown = unknown, +> extends LeafyGreenTableOptions { + containerRef: RefObject; + virtualizerOptions?: Partial>; +} + +/** + * LeafyGreen extension of `useReactTable` {@link Table} + */ +export interface LeafyGreenVirtualTable + extends LeafyGreenTable { + // virtualRows?: Array; + virtual: Omit, 'virtualItems'>; +} From 8a87597bd9ebb43963422ad708c849bd7410b057 Mon Sep 17 00:00:00 2001 From: Shaneeza Date: Fri, 20 Sep 2024 14:03:06 -0400 Subject: [PATCH 003/113] updating stories --- packages/table/src/Table.stories.tsx | 137 ++++++------------ .../table/src/Table/TableWithVS.stories.tsx | 93 ++++-------- .../useLeafyGreenTable/useLeafyGreenTable.tsx | 42 +++++- .../useLeafyGreenTable.types.ts | 6 +- .../useLeafyGreenVirtualTable.tsx | 4 +- 5 files changed, 116 insertions(+), 166 deletions(-) diff --git a/packages/table/src/Table.stories.tsx b/packages/table/src/Table.stories.tsx index 65b12f7f14..8667a4430b 100644 --- a/packages/table/src/Table.stories.tsx +++ b/packages/table/src/Table.stories.tsx @@ -165,7 +165,11 @@ export const LiveExample: StoryFn = args => { columns, }); - const { rows } = table.getRowModel(); + // const { rows } = table.getRowModel(); + + const { rows } = table; + + // console.log({ rows }); return (
= args => { {rows.map((row: LeafyGreenTableRow) => { + const isExpandedContent = row.original.isExpandedContent ?? false; return ( <> - - {row.getVisibleCells().map(cell => { - return ( - - {flexRender( - cell.column.columnDef.cell, - cell.getContext(), - )} - - ); - })} - - {row.subRows && - row.subRows.map(subRow => ( - <> - - {subRow.getVisibleCells().map(cell => { - return ( - - {flexRender( - cell.column.columnDef.cell, - cell.getContext(), - )} - - ); - })} - - {subRow.original.renderExpandedContent && ( - - )} - - ))} + {!isExpandedContent && ( + + {row.getVisibleCells().map(cell => { + return ( + + {flexRender( + cell.column.columnDef.cell, + cell.getContext(), + )} + + ); + })} + + )} + {isExpandedContent && } ); })} @@ -242,14 +230,6 @@ LiveExample.argTypes = { }, }; -export const AnimationsDisabled: StoryFn = args => { - return ; -}; - -AnimationsDisabled.args = { - disableAnimations: true, -}; - export const Basic = Template.bind({}); export const ZebraStripes = Template.bind({}); @@ -349,14 +329,15 @@ export const NestedRows: StoryFn = args => { columns, }); - const { rows } = table.getRowModel(); + // const { rows } = table.getRowModel(); + const { rows } = table; return (
{table.getHeaderGroups().map((headerGroup: HeaderGroup) => ( @@ -391,38 +372,6 @@ export const NestedRows: StoryFn = args => { ); })} - {row.subRows && - row.subRows.map(subRow => ( - <> - - {subRow.getVisibleCells().map(cell => { - return ( - - {flexRender( - cell.column.columnDef.cell, - cell.getContext(), - )} - - ); - })} - - {subRow.subRows && - subRow.subRows.map(subSubRow => ( - - {subSubRow.getVisibleCells().map(cell => { - return ( - - {flexRender( - cell.column.columnDef.cell, - cell.getContext(), - )} - - ); - })} - - ))} - - ))} ); @@ -481,14 +430,15 @@ export const ExpandableContent: StoryFn = args => { columns, }); - const { rows } = table.getRowModel(); + // const { rows } = table.getRowModel(); + const { rows } = table; return (
{table.getHeaderGroups().map((headerGroup: HeaderGroup) => ( @@ -508,24 +458,25 @@ export const ExpandableContent: StoryFn = args => { {rows.map((row: LeafyGreenTableRow) => { + const isExpandedContent = row.original.isExpandedContent ?? false; return ( - - {row - .getVisibleCells() - .map((cell: LeafyGreenTableCell) => { - return ( - - {flexRender( - cell.column.columnDef.cell, - cell.getContext(), - )} - - ); - })} - {row.original.renderExpandedContent && ( - + <> + {!isExpandedContent && ( + + {row.getVisibleCells().map(cell => { + return ( + + {flexRender( + cell.column.columnDef.cell, + cell.getContext(), + )} + + ); + })} + )} - + {isExpandedContent && } + ); })} diff --git a/packages/table/src/Table/TableWithVS.stories.tsx b/packages/table/src/Table/TableWithVS.stories.tsx index 112f26bff4..38d2f9e7ad 100644 --- a/packages/table/src/Table/TableWithVS.stories.tsx +++ b/packages/table/src/Table/TableWithVS.stories.tsx @@ -16,7 +16,6 @@ import { type HeaderGroup, HeaderRow, type LeafyGreenTableCell, - type LeafyGreenTableRow, Row, type SortingState, Table, @@ -108,12 +107,14 @@ export const Basic: StoryFn = args => { // const virtualItems = table.virtual.getVirtualItems(); - const { rows } = table.getRowModel(); + // const { rows } = table.getRowModel(); + + const { rows } = table; return ( <>
-

{table.getRowModel().rows.length} total rowsjsfjsh

+

{table.rows.length} total rowsjsfjsh

{table?.virtual.getVirtualItems().length} virtual rows

{table?.virtual.getTotalSize()} virtual rows

@@ -183,13 +184,14 @@ export const NestedRows: StoryFn = args => { columns, }); - const { rows } = table.getRowModel(); + // const { rows } = table.getRowModel(); + const { rows } = table; const virtualItems = table.virtual.getVirtualItems(); return ( <>
-

{table.getRowModel().rows.length} total rows

+

{table.rows.length} total rows

= args => { ); })} - {row.subRows && - row.subRows.map((subRow: LeafyGreenTableRow) => ( - <> - - {subRow - .getVisibleCells() - .map((cell: LeafyGreenTableCell) => { - return ( - - {flexRender( - cell.column.columnDef.cell, - cell.getContext(), - )} - - ); - })} - - {subRow.subRows && - subRow.subRows.map(subSubRow => ( - - {subSubRow - .getVisibleCells() - .map((cell: LeafyGreenTableCell) => { - return ( - - {flexRender( - cell.column.columnDef.cell, - cell.getContext(), - )} - - ); - })} - - ))} - - ))} ); })} @@ -495,13 +453,14 @@ export const ExpandableContent: StoryFn = args => { onExpandedChange: setExpanded, }); - const { rows } = table.getRowModel(); + // const { rows } = table.getRowModel(); + const { rows } = table; const virtualItems = table.virtual.getVirtualItems(); return ( <>
-

{table.getRowModel().rows.length} total rows

+

{table.rows.length} total rows

= args => { {virtualItems && virtualItems.map((virtualRow: VirtualItem) => { const row = rows[virtualRow.index]; - const cells = row.getVisibleCells(); + const isExpandedContent = row.original.isExpandedContent ?? false; return ( <> - - {cells.map((cell: LeafyGreenTableCell) => { - return ( - - {flexRender( - cell.column.columnDef.cell, - cell.getContext(), - )} - - ); - })} - - {row.original.renderExpandedContent && ( - + {!isExpandedContent && ( + + {row + .getVisibleCells() + .map((cell: LeafyGreenTableCell) => { + return ( + + {flexRender( + cell.column.columnDef.cell, + cell.getContext(), + )} + + ); + })} + )} + {isExpandedContent && } ); })} diff --git a/packages/table/src/useLeafyGreenTable/useLeafyGreenTable.tsx b/packages/table/src/useLeafyGreenTable/useLeafyGreenTable.tsx index f2152d93e7..f460644a71 100644 --- a/packages/table/src/useLeafyGreenTable/useLeafyGreenTable.tsx +++ b/packages/table/src/useLeafyGreenTable/useLeafyGreenTable.tsx @@ -1,5 +1,9 @@ import React from 'react'; -import { useReactTable } from '@tanstack/react-table'; +import { + ExpandedState, + getExpandedRowModel, + useReactTable, +} from '@tanstack/react-table'; import { getCoreRowModel, getPaginationRowModel, @@ -15,15 +19,17 @@ import { LeafyGreenTable, LGColumnDef, LGTableDataType } from '.'; const CHECKBOX_WIDTH = 14; function useLeafyGreenTable({ - containerRef, + // containerRef, data, columns: columnsProp, hasSelectableRows, withPagination = false, allowSelectAll = true, - virtualizerOptions, + // virtualizerOptions, ...rest }: LeafyGreenTableOptions): LeafyGreenTable { + const [expanded, setExpanded] = React.useState({}); + /** * A `ColumnDef` object injected into `useReactTable`'s `columns` option when the user is using selectable rows. */ @@ -56,6 +62,10 @@ function useLeafyGreenTable({ ); const table = useReactTable>({ + state: { + expanded, + ...rest.state, + }, data, columns, getCoreRowModel: getCoreRowModel(), @@ -64,15 +74,41 @@ function useLeafyGreenTable({ }, enableExpanding: true, enableSortingRemoval: hasSortableColumns ? true : undefined, + onExpandedChange: setExpanded, getSubRows: row => row.subRows, getSortedRowModel: getSortedRowModel(), getPaginationRowModel: withPagination ? getPaginationRowModel() : undefined, + getExpandedRowModel: getExpandedRowModel(), ...rest, }); + const { rows } = table.getRowModel(); + + // A way to include expandableContent inside of the rows object. + // If a row has expandedContent and its expanded then add a new row below the row + const rowsCopy = [...rows]; + + for (let i = 0; i < rowsCopy.length; i++) { + if ( + rowsCopy[i].original.renderExpandedContent && + rowsCopy[i].getIsExpanded() + ) { + rowsCopy.splice(i + 1, 0, { + ...rowsCopy[i], + id: `${rowsCopy[i].id}-expandedContent`, + original: { + ...rowsCopy[i].original, + isExpandedContent: true, + }, + }); + i++; // Increment index to skip the newly added item + } + } + return { ...table, hasSelectableRows, + rows: rowsCopy, } as LeafyGreenTable; } diff --git a/packages/table/src/useLeafyGreenTable/useLeafyGreenTable.types.ts b/packages/table/src/useLeafyGreenTable/useLeafyGreenTable.types.ts index b5a30a58ff..0322401be4 100644 --- a/packages/table/src/useLeafyGreenTable/useLeafyGreenTable.types.ts +++ b/packages/table/src/useLeafyGreenTable/useLeafyGreenTable.types.ts @@ -1,4 +1,4 @@ -import { RefObject } from 'react'; +// import { RefObject } from 'react'; // import { // type Options as VirtualizerOptions, // type VirtualItem, @@ -22,6 +22,7 @@ export type LGRowData = RowData; export type LGTableDataType = T & { renderExpandedContent?: (row: LeafyGreenTableRow) => JSX.Element; subRows?: Array>; + isExpandedContent?: boolean; }; /** LeafyGreen extension of `useReactTable` {@link Cell}*/ @@ -64,7 +65,6 @@ export type LeafyGreenTableOptions< */ export interface LeafyGreenTable extends Table> { - // Omit { - // virtualRows?: Array; hasSelectableRows: boolean; + rows: Array; } diff --git a/packages/table/src/useLeafyGreenVirtualTable/useLeafyGreenVirtualTable.tsx b/packages/table/src/useLeafyGreenVirtualTable/useLeafyGreenVirtualTable.tsx index 52f0276fd0..eaca8e26df 100644 --- a/packages/table/src/useLeafyGreenVirtualTable/useLeafyGreenVirtualTable.tsx +++ b/packages/table/src/useLeafyGreenVirtualTable/useLeafyGreenVirtualTable.tsx @@ -28,7 +28,9 @@ function useLeafyGreenVirtualTable< ...rest, }); - const { rows } = table.getRowModel(); + // const { rows } = table.getRowModel(); + + const { rows } = table; const _virtualizer = useVirtualizer({ count: rows.length, From 1c9e15d648c2edc46cdc2bd7c5a3f2f52b4fe23f Mon Sep 17 00:00:00 2001 From: Shaneeza Date: Fri, 20 Sep 2024 14:58:14 -0400 Subject: [PATCH 004/113] lg virtual item --- .../table/src/Table/TableWithVS.stories.tsx | 313 +++++++++--------- packages/table/src/index.ts | 7 +- .../src/useLeafyGreenVirtualTable/index.ts | 1 + .../useLeafyGreenVirtualTable.tsx | 12 +- .../useLeafyGreenVirtualTable.types.ts | 11 +- 5 files changed, 175 insertions(+), 169 deletions(-) diff --git a/packages/table/src/Table/TableWithVS.stories.tsx b/packages/table/src/Table/TableWithVS.stories.tsx index 38d2f9e7ad..938978400b 100644 --- a/packages/table/src/Table/TableWithVS.stories.tsx +++ b/packages/table/src/Table/TableWithVS.stories.tsx @@ -16,6 +16,7 @@ import { type HeaderGroup, HeaderRow, type LeafyGreenTableCell, + type LeafyGreenVirtualItem, Row, type SortingState, Table, @@ -23,7 +24,6 @@ import { TableHead, type TableProps, useLeafyGreenVirtualTable, - type VirtualItem, } from '..'; type StoryTableProps = TableProps; @@ -105,12 +105,6 @@ export const Basic: StoryFn = args => { columns, }); - // const virtualItems = table.virtual.getVirtualItems(); - - // const { rows } = table.getRowModel(); - - const { rows } = table; - return ( <>
@@ -142,30 +136,27 @@ export const Basic: StoryFn = args => { ))} - {table.virtual.getVirtualItems() && - table.virtual.getVirtualItems().map((virtualRow: VirtualItem) => { - const row = rows[virtualRow.index]; - const cells = row.getVisibleCells(); - return ( - - {cells.map((cell: LeafyGreenTableCell) => { - return ( - - {flexRender( - cell.column.columnDef.cell, - cell.getContext(), - )} - - ); - })} - - ); - })} + {table.virtual.virtualItems && + table.virtual.virtualItems.map( + (virtualRow: LeafyGreenVirtualItem) => { + const row = virtualRow.row; + const cells = row.getVisibleCells(); + return ( + + {cells.map((cell: LeafyGreenTableCell) => { + return ( + + {flexRender( + cell.column.columnDef.cell, + cell.getContext(), + )} + + ); + })} + + ); + }, + )}
@@ -184,10 +175,6 @@ export const NestedRows: StoryFn = args => { columns, }); - // const { rows } = table.getRowModel(); - const { rows } = table; - const virtualItems = table.virtual.getVirtualItems(); - return ( <>
@@ -217,28 +204,30 @@ export const NestedRows: StoryFn = args => { ))} - {virtualItems && - virtualItems.map((virtualRow: VirtualItem) => { - const row = rows[virtualRow.index]; - const cells = row.getVisibleCells(); + {table.virtual.virtualItems && + table.virtual.virtualItems.map( + (virtualRow: LeafyGreenVirtualItem) => { + const row = virtualRow.row; + const cells = row.getVisibleCells(); - return ( - <> - - {cells.map((cell: LeafyGreenTableCell) => { - return ( - - {flexRender( - cell.column.columnDef.cell, - cell.getContext(), - )} - - ); - })} - - - ); - })} + return ( + <> + + {cells.map((cell: LeafyGreenTableCell) => { + return ( + + {flexRender( + cell.column.columnDef.cell, + cell.getContext(), + )} + + ); + })} + + + ); + }, + )} @@ -303,9 +292,6 @@ export const SortableRows: StoryFn = args => { onSortingChange: setSorting, }); - const { rows } = table.getRowModel(); - const virtualItems = table.virtual.getVirtualItems(); - return ( <>
@@ -335,26 +321,28 @@ export const SortableRows: StoryFn = args => { ))} - {virtualItems && - virtualItems.map((virtualRow: VirtualItem) => { - const row = rows[virtualRow.index]; - const cells = row.getVisibleCells(); - - return ( - - {cells.map((cell: LeafyGreenTableCell) => { - return ( - - {flexRender( - cell.column.columnDef.cell, - cell.getContext(), - )} - - ); - })} - - ); - })} + {table.virtual.virtualItems && + table.virtual.virtualItems.map( + (virtualRow: LeafyGreenVirtualItem) => { + const row = virtualRow.row; + const cells = row.getVisibleCells(); + + return ( + + {cells.map((cell: LeafyGreenTableCell) => { + return ( + + {flexRender( + cell.column.columnDef.cell, + cell.getContext(), + )} + + ); + })} + + ); + }, + )} @@ -379,9 +367,6 @@ export const SelectableRows: StoryFn = args => { hasSelectableRows: true, }); - const { rows } = table.getRowModel(); - const virtualItems = table.virtual.getVirtualItems(); - return ( <>
@@ -410,26 +395,28 @@ export const SelectableRows: StoryFn = args => { ))} - {virtualItems && - virtualItems.map((virtualRow: VirtualItem) => { - const row = rows[virtualRow.index]; - const cells = row.getVisibleCells(); - - return ( - - {cells.map((cell: LeafyGreenTableCell) => { - return ( - - {flexRender( - cell.column.columnDef.cell, - cell.getContext(), - )} - - ); - })} - - ); - })} + {table.virtual.virtualItems && + table.virtual.virtualItems.map( + (virtualRow: LeafyGreenVirtualItem) => { + const row = virtualRow.row; + const cells = row.getVisibleCells(); + + return ( + + {cells.map((cell: LeafyGreenTableCell) => { + return ( + + {flexRender( + cell.column.columnDef.cell, + cell.getContext(), + )} + + ); + })} + + ); + }, + )} @@ -453,10 +440,6 @@ export const ExpandableContent: StoryFn = args => { onExpandedChange: setExpanded, }); - // const { rows } = table.getRowModel(); - const { rows } = table; - const virtualItems = table.virtual.getVirtualItems(); - return ( <>
@@ -486,33 +469,36 @@ export const ExpandableContent: StoryFn = args => { ))} - {virtualItems && - virtualItems.map((virtualRow: VirtualItem) => { - const row = rows[virtualRow.index]; - const isExpandedContent = row.original.isExpandedContent ?? false; - - return ( - <> - {!isExpandedContent && ( - - {row - .getVisibleCells() - .map((cell: LeafyGreenTableCell) => { - return ( - - {flexRender( - cell.column.columnDef.cell, - cell.getContext(), - )} - - ); - })} - - )} - {isExpandedContent && } - - ); - })} + {table.virtual.virtualItems && + table.virtual.virtualItems.map( + (virtualRow: LeafyGreenVirtualItem) => { + const row = virtualRow.row; + const isExpandedContent = + row.original.isExpandedContent ?? false; + + return ( + <> + {!isExpandedContent && ( + + {row + .getVisibleCells() + .map((cell: LeafyGreenTableCell) => { + return ( + + {flexRender( + cell.column.columnDef.cell, + cell.getContext(), + )} + + ); + })} + + )} + {isExpandedContent && } + + ); + }, + )} @@ -540,9 +526,6 @@ export const TallRows: StoryFn = args => { }, }); - const { rows } = table.getRowModel(); - const virtualItems = table.virtual.getVirtualItems(); - return ( <>
@@ -573,34 +556,36 @@ export const TallRows: StoryFn = args => { ))} - {virtualItems && - virtualItems.map((virtualRow: VirtualItem) => { - const row = rows[virtualRow.index]; - const cells = row.getVisibleCells(); - return ( - - {cells.map((cell: LeafyGreenTableCell) => { - return ( - div { - max-height: unset; - } - `} - > - {flexRender( - cell.column.columnDef.cell, - cell.getContext(), - )} - - ); - })} - - ); - })} + {table.virtual.virtualItems && + table.virtual.virtualItems.map( + (virtualRow: LeafyGreenVirtualItem) => { + const row = virtualRow.row; + const cells = row.getVisibleCells(); + return ( + + {cells.map((cell: LeafyGreenTableCell) => { + return ( + div { + max-height: unset; + } + `} + > + {flexRender( + cell.column.columnDef.cell, + cell.getContext(), + )} + + ); + })} + + ); + }, + )} diff --git a/packages/table/src/index.ts b/packages/table/src/index.ts index 43c45d0966..9faaf33da8 100644 --- a/packages/table/src/index.ts +++ b/packages/table/src/index.ts @@ -26,7 +26,12 @@ export { type LGTableDataType, default as useLeafyGreenTable, } from './useLeafyGreenTable'; -export { default as useLeafyGreenVirtualTable } from './useLeafyGreenVirtualTable'; +export { + type LeafyGreenVirtualItem, + type LeafyGreenVirtualTable, + type LeafyGreenVirtualTableOptions, + default as useLeafyGreenVirtualTable, +} from './useLeafyGreenVirtualTable'; export { getTestUtils } from './utils/getTestUtils'; export { default as V11Adapter, type V11AdapterProps } from './V11Adapter'; export * from '@tanstack/react-table'; diff --git a/packages/table/src/useLeafyGreenVirtualTable/index.ts b/packages/table/src/useLeafyGreenVirtualTable/index.ts index aa5e66a8b8..4395a4e266 100644 --- a/packages/table/src/useLeafyGreenVirtualTable/index.ts +++ b/packages/table/src/useLeafyGreenVirtualTable/index.ts @@ -1,3 +1,4 @@ import useLeafyGreenVirtualTable from './useLeafyGreenVirtualTable'; +export * from './useLeafyGreenVirtualTable.types'; export default useLeafyGreenVirtualTable; diff --git a/packages/table/src/useLeafyGreenVirtualTable/useLeafyGreenVirtualTable.tsx b/packages/table/src/useLeafyGreenVirtualTable/useLeafyGreenVirtualTable.tsx index eaca8e26df..9e93e059ce 100644 --- a/packages/table/src/useLeafyGreenVirtualTable/useLeafyGreenVirtualTable.tsx +++ b/packages/table/src/useLeafyGreenVirtualTable/useLeafyGreenVirtualTable.tsx @@ -1,8 +1,9 @@ -import { useVirtualizer } from '@tanstack/react-virtual'; +import { useVirtualizer, VirtualItem } from '@tanstack/react-virtual'; import useLeafyGreenTable, { LGRowData } from '../useLeafyGreenTable'; import { + LeafyGreenVirtualItem, LeafyGreenVirtualTable, LeafyGreenVirtualTableOptions, } from './useLeafyGreenVirtualTable.types'; @@ -45,9 +46,16 @@ function useLeafyGreenVirtualTable< ...virtualizerOptions, }); + const _virtualItems: Array> = _virtualizer + .getVirtualItems() + .map((virtualRow: VirtualItem) => ({ + ...virtualRow, + row: rows[virtualRow.index], + })); + return { ...table, - virtual: { ..._virtualizer }, + virtual: { ..._virtualizer, virtualItems: _virtualItems }, } as LeafyGreenVirtualTable; } diff --git a/packages/table/src/useLeafyGreenVirtualTable/useLeafyGreenVirtualTable.types.ts b/packages/table/src/useLeafyGreenVirtualTable/useLeafyGreenVirtualTable.types.ts index f739974552..f6cb3821c1 100644 --- a/packages/table/src/useLeafyGreenVirtualTable/useLeafyGreenVirtualTable.types.ts +++ b/packages/table/src/useLeafyGreenVirtualTable/useLeafyGreenVirtualTable.types.ts @@ -1,6 +1,6 @@ import { RefObject } from 'react'; import { - // VirtualItem, + VirtualItem as TSVirtualItem, Virtualizer, VirtualizerOptions, } from '@tanstack/react-virtual'; @@ -8,6 +8,7 @@ import { import { LeafyGreenTable, LeafyGreenTableOptions, + LeafyGreenTableRow, LGRowData, } from '../useLeafyGreenTable'; @@ -30,5 +31,11 @@ export interface LeafyGreenVirtualTableOptions< export interface LeafyGreenVirtualTable extends LeafyGreenTable { // virtualRows?: Array; - virtual: Omit, 'virtualItems'>; + virtual: Virtualizer & { + virtualItems: Array>; + }; } + +export type LeafyGreenVirtualItem = TSVirtualItem & { + row: LeafyGreenTableRow; +}; From c1747ba4f3ce28fc5c46d2f47f781e94de3de3be Mon Sep 17 00:00:00 2001 From: Shaneeza Date: Tue, 24 Sep 2024 10:57:57 -0400 Subject: [PATCH 005/113] top styles --- packages/table/src/Table/Table.styles.ts | 72 +++------ packages/table/src/Table/Table.tsx | 145 +++++------------- packages/table/src/Table/VirtualTable.tsx | 0 .../table/src/TableContext/TableContext.tsx | 2 + .../src/TableContext/TableContext.types.ts | 5 + 5 files changed, 66 insertions(+), 158 deletions(-) delete mode 100644 packages/table/src/Table/VirtualTable.tsx diff --git a/packages/table/src/Table/Table.styles.ts b/packages/table/src/Table/Table.styles.ts index b78cb4009b..4bf242c6f4 100644 --- a/packages/table/src/Table/Table.styles.ts +++ b/packages/table/src/Table/Table.styles.ts @@ -29,52 +29,28 @@ export const tableContainerStyles = css` position: relative; `; -// export const getTableContainerStyles = ( -// isVirtual = false, -// virtualizer: {}, -// ) => css` -// ${isVirtual && -// css` -// table { -// display: grid; -// } - -// thead { -// display: grid; -// top: 0; -// z-index: 1; - -// tr { -// display: flex; -// width: 100%; -// } - -// th { -// display: flex; -// /* width: 100%; */ -// box-sizing: content-box; -// } -// } - -// th { -// display: flex; -// } - -// tbody { -// display: grid; -// position: relative; -// height: ${virtualizer.getTotalSize()}px; - -// tr { -// display: flex; -// position: absolute; -// width: 100%; -// } +export const getVirtualStyles = (isVirtual = false, totalSize: number) => css` + ${isVirtual && + css` + position: relative; + height: ${totalSize}px; + `} +`; -// td { -// display: flex; -// box-sizing: content-box; -// } -// } -// `} -// `; +export const getVirtualDynamicStyles = ( + isVirtual = false, + startPosition: number, +) => css` + ${isVirtual && + css` + position: absolute; + top: 0; + left: 0; + transform: translate3d(0, ${startPosition}px, 0); + width: 100%; + + thead { + top: -${startPosition}px; + } + `} +`; diff --git a/packages/table/src/Table/Table.tsx b/packages/table/src/Table/Table.tsx index 670faf6562..1df9e7c6d8 100644 --- a/packages/table/src/Table/Table.tsx +++ b/packages/table/src/Table/Table.tsx @@ -1,8 +1,7 @@ -import React, { ForwardedRef, forwardRef, useRef } from 'react'; +import React, { ForwardedRef, forwardRef } from 'react'; import PropTypes from 'prop-types'; import { cx } from '@leafygreen-ui/emotion'; -import { useForwardedRef } from '@leafygreen-ui/hooks'; import { useDarkMode } from '@leafygreen-ui/leafygreen-provider'; import { BaseFontSize } from '@leafygreen-ui/tokens'; import { @@ -13,34 +12,17 @@ import { import { LGIDS } from '../constants'; import { TableContextProvider } from '../TableContext'; import { LGRowData } from '../useLeafyGreenTable'; +import { LeafyGreenVirtualTable } from '../useLeafyGreenVirtualTable/useLeafyGreenVirtualTable.types'; -// import { LeafyGreenVirtualTable } from '../useLeafyGreenVirtualTable/useLeafyGreenVirtualTable.types'; import { baseStyles, - // getTableContainerStyles, + getVirtualDynamicStyles, + getVirtualStyles, tableContainerStyles, themeStyles, } from './Table.styles'; import { TableProps } from './Table.types'; -// const adjustTableHeight = (tableRef, virtualHeight) => { -// if (!tableRef.current) return; - -// // calculate the height for the pseudo element after the table -// const existingPseudoElement = window.getComputedStyle( -// tableRef.current, -// '::after', -// ); -// const existingPseudoHeight = parseFloat(existingPseudoElement.height) || 0; -// const tableHeight = tableRef.current.clientHeight - existingPseudoHeight; -// const pseudoHeight = Math.max(virtualHeight - tableHeight, 0); -// document.documentElement.style.setProperty( -// '--pseudo-height', -// `${pseudoHeight}px`, -// ); -// return pseudoHeight; -// }; - // Inferred generic type from component gets used in place of `any` const Table = forwardRef>( ( @@ -59,103 +41,46 @@ const Table = forwardRef>( ) => { const baseFontSize: BaseFontSize = useUpdatedBaseFontSize(baseFontSizeProp); const { theme, darkMode } = useDarkMode(darkModeProp); - // const isVirtual = !!(table as LeafyGreenVirtualTable)!.virtual ?? false; - // const virtualTable = (table as LeafyGreenVirtualTable)!.virtual; - // console.log({ isVirtual }); - - const parentRef = useForwardedRef(containerRef, null); - const tableRef = useRef(null); - // const [isScrollNearBottom, setIsScrollNearBottom] = useState(false); - - // const virtualizer = table.virtual; - - // const virtualItems = virtualizer.getVirtualItems(); - // const virtualSize = virtualizer.getTotalSize(); - - // // callback to adjust the height of the pseudo element - // const handlePseudoResize = useCallback(() => { - // return adjustTableHeight(tableRef, virtualSize); - // }, [tableRef, virtualSize]); - - // // callback to handle scrolling, checking if we are near the bottom - // const handleScroll = useCallback(() => { - // if (parentRef.current) { - // const scrollPosition = parentRef.current?.scrollTop; - // const visibleHeight = parentRef.current?.clientHeight; - // setIsScrollNearBottom( - // scrollPosition > virtualSize * 0.95 - visibleHeight, - // ); - // } - // }, [parentRef, virtualSize]); - - // add an event listener on the scrollable parent container and resize the - // pseudo element whenever the table renders with new data - // useEffect(() => { - // const scrollable = parentRef.current; - // if (scrollable) scrollable.addEventListener('scroll', handleScroll); - // handlePseudoResize(); - - // return () => { - // if (scrollable) scrollable.removeEventListener('scroll', handleScroll); - // }; - // }, [handleScroll, handlePseudoResize]); - - // if we are near the bottom of the table, resize the pseudo element each time - // the length of virtual items changes (which is effectively the number of table - // rows rendered to the DOM). This ensures we don't scroll too far or too short. - // useEffect(() => { - // if (isScrollNearBottom) handlePseudoResize(); - // }, [isScrollNearBottom, virtualItems.length, handlePseudoResize]); + const isVirtual = !!(table as LeafyGreenVirtualTable)!.virtual ?? false; + const virtualTable = + isVirtual && (table as LeafyGreenVirtualTable)!.virtual; + const virtualTableTotalSize = virtualTable && virtualTable.getTotalSize(); + const virtualTableStart = + (virtualTable && virtualTable.getVirtualItems()[0]?.start) ?? 0; return (
- {/*
+
*/} - {/*
*/} - - - {children} -
-
+ + + {children} +
+
+
+
); }, diff --git a/packages/table/src/Table/VirtualTable.tsx b/packages/table/src/Table/VirtualTable.tsx deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/packages/table/src/TableContext/TableContext.tsx b/packages/table/src/TableContext/TableContext.tsx index 4de7ee930e..4563185e83 100644 --- a/packages/table/src/TableContext/TableContext.tsx +++ b/packages/table/src/TableContext/TableContext.tsx @@ -22,6 +22,7 @@ const TableContextProvider = ({ table, shouldAlternateRowColor, disableAnimations, + isVirtual, }: PropsWithChildren>>) => { const getRowById = (id?: string) => id ? table?.getRowModel().rowsById?.[id] : undefined; @@ -42,6 +43,7 @@ const TableContextProvider = ({ getParentRow, shouldAlternateRowColor, disableAnimations, + isVirtual, }} > {children} diff --git a/packages/table/src/TableContext/TableContext.types.ts b/packages/table/src/TableContext/TableContext.types.ts index 49d0d05a1c..4748c9327a 100644 --- a/packages/table/src/TableContext/TableContext.types.ts +++ b/packages/table/src/TableContext/TableContext.types.ts @@ -23,4 +23,9 @@ export type TableContextValues = PropsWithChildren< * The `useLeafyGreenTable` return value */ table?: LeafyGreenTable; + + /** + * Whether the table is using virtual scrolling + */ + isVirtual?: boolean; }; From efd7bf00a6e8e7a43af83257ff514b4035649c7e Mon Sep 17 00:00:00 2001 From: Shaneeza Date: Tue, 24 Sep 2024 14:33:53 -0400 Subject: [PATCH 006/113] remove padding from TableBody --- packages/table/src/Cell/Cell.styles.ts | 20 +---- packages/table/src/Cell/InternalCell.tsx | 8 -- .../ExpandedContent/ExpandedContent.styles.ts | 5 ++ .../src/ExpandedContent/ExpandedContent.tsx | 21 +++-- packages/table/src/Row/InternalRowBase.tsx | 51 +++++------ packages/table/src/Row/InternalRowWithRT.tsx | 86 +++++++++---------- packages/table/src/Table.stories.tsx | 2 +- .../table/src/Table/TableWithVS.stories.tsx | 14 ++- packages/table/src/TableBody/TableBody.tsx | 51 ++++++----- .../useLeafyGreenVirtualTable.tsx | 1 + 10 files changed, 123 insertions(+), 136 deletions(-) diff --git a/packages/table/src/Cell/Cell.styles.ts b/packages/table/src/Cell/Cell.styles.ts index 4f63e81722..86ef2187e4 100644 --- a/packages/table/src/Cell/Cell.styles.ts +++ b/packages/table/src/Cell/Cell.styles.ts @@ -77,6 +77,7 @@ export const cellTransitionContainerStyles = css` align-items: center; min-height: ${standardCellHeight}px; overflow: hidden; + max-height: ${standardCellHeight}px; `; export const truncatedContentStyles = css` @@ -91,22 +92,3 @@ export const disableAnimationStyles = css` transition-duration: 0; transition: none; `; - -// TODO: remove this -export const cellContentTransitionStateStyles = ( - height?: number, - isVisible = false, -) => { - return cx({ - [css` - opacity: 0; - min-height: 0; - max-height: 0; - `]: !isVisible, - [css` - opacity: 1; - min-height: ${standardCellHeight}px; - max-height: ${height ? height + 'px' : 'unset'}; - `]: isVisible, - }); -}; diff --git a/packages/table/src/Cell/InternalCell.tsx b/packages/table/src/Cell/InternalCell.tsx index c22176884b..e48a26db56 100644 --- a/packages/table/src/Cell/InternalCell.tsx +++ b/packages/table/src/Cell/InternalCell.tsx @@ -9,7 +9,6 @@ import { useTableContext } from '../TableContext'; import { alignmentStyles, baseCellStyles, - cellContentTransitionStateStyles, cellTransitionContainerStyles, getCellPadding, standardCellHeight, @@ -59,18 +58,11 @@ const InternalCell = ({ ref={contentRef} className={cx( cellTransitionContainerStyles, - cellContentTransitionStateStyles(contentHeight, isVisible), // TODO: remove this alignmentStyles(align), { [truncatedContentStyles]: shouldTruncate, }, contentClassName, - // css` - // ${!!table.virtual && - // css` - // transform: translateY(${virtualRow.start}px); - // `} - // `, )} > {children} diff --git a/packages/table/src/ExpandedContent/ExpandedContent.styles.ts b/packages/table/src/ExpandedContent/ExpandedContent.styles.ts index 857fd28e61..504b911986 100644 --- a/packages/table/src/ExpandedContent/ExpandedContent.styles.ts +++ b/packages/table/src/ExpandedContent/ExpandedContent.styles.ts @@ -7,6 +7,11 @@ export const baseStyles = css` padding: 0; overflow: hidden; transition: ${transitionDuration.default}ms ease; + + //TODO: this is temp + > div { + max-height: inherit; + } `; export const expandedContentStyles: Record = { diff --git a/packages/table/src/ExpandedContent/ExpandedContent.tsx b/packages/table/src/ExpandedContent/ExpandedContent.tsx index aec5ffec41..b15d6a6950 100644 --- a/packages/table/src/ExpandedContent/ExpandedContent.tsx +++ b/packages/table/src/ExpandedContent/ExpandedContent.tsx @@ -4,11 +4,7 @@ import { RowData } from '@tanstack/react-table'; import { cx } from '@leafygreen-ui/emotion'; import { useDarkMode } from '@leafygreen-ui/leafygreen-provider'; -import { - cellContentTransitionStateStyles, - cellTransitionContainerStyles, - disableAnimationStyles, -} from '../Cell/Cell.styles'; +import { cellTransitionContainerStyles } from '../Cell/Cell.styles'; import { LGIDS } from '../constants'; import InternalRowBase from '../Row/InternalRowBase'; import { useTableContext } from '../TableContext'; @@ -21,7 +17,8 @@ const ExpandedContent = ({ row, ...rest }: ExpandedContentProps) => { - const { disableAnimations, getParentRow } = useTableContext(); + const { disableAnimations, getParentRow, table, isVirtual } = + useTableContext(); const contentRef = useRef(null); const areAncestorsExpanded = getAreAncestorsExpanded(row.id, getParentRow); const isNestedRow = !!getParentRow?.(row.id); @@ -41,7 +38,15 @@ const ExpandedContent = ({ ); return ( - + { + // TODO: fix me + // This gets the dynamic size of the element + if (isVirtual && table) table.virtual.measureElement(node); + }} + > ({
{content}
diff --git a/packages/table/src/Row/InternalRowBase.tsx b/packages/table/src/Row/InternalRowBase.tsx index 294f2ac1a1..94e1b820d0 100644 --- a/packages/table/src/Row/InternalRowBase.tsx +++ b/packages/table/src/Row/InternalRowBase.tsx @@ -1,4 +1,4 @@ -import React from 'react'; +import React, { forwardRef } from 'react'; import { cx } from '@leafygreen-ui/emotion'; import { useDarkMode } from '@leafygreen-ui/leafygreen-provider'; @@ -12,29 +12,30 @@ import { useRowContext } from './RowContext'; /** * The base Row component, extended by `InternalRow(With/Without)RT` */ -const InternalRowBase = ({ - className, - onClick, - ...rest -}: InternalRowBaseProps) => { - const { theme } = useDarkMode(); - const { disabled } = useRowContext(); - return ( - - ); -}; +const InternalRowBase = forwardRef( + ({ className, onClick, ...rest }: InternalRowBaseProps, forwardedRef) => { + const { theme } = useDarkMode(); + const { disabled } = useRowContext(); + return ( + + ); + }, +); + +InternalRowBase.displayName = 'InternalRowBase'; export default InternalRowBase; diff --git a/packages/table/src/Row/InternalRowWithRT.tsx b/packages/table/src/Row/InternalRowWithRT.tsx index 0ce63c1489..d0be201f4c 100644 --- a/packages/table/src/Row/InternalRowWithRT.tsx +++ b/packages/table/src/Row/InternalRowWithRT.tsx @@ -11,7 +11,7 @@ import { LGRowData } from '../useLeafyGreenTable'; import InternalRowBase from './InternalRowBase'; import { - expandedContentParentStyles, + // expandedContentParentStyles, grayZebraRowStyles, selectedRowStyles, zebraStyles, @@ -36,7 +36,7 @@ const InternalRowWithRT = ({ const parentRow = getParentRow?.(row.id); // const rowRef = virtualRow?.measureRef; - const isTableExpandable = table?.getCanSomeRowsExpand(); + // const isTableExpandable = table?.getCanSomeRowsExpand(); const isNested = !!parentRow; const isParentExpanded = !!parentRow && parentRow.getIsExpanded(); const isRowVisible = isParentExpanded || !isNested; @@ -54,53 +54,47 @@ const InternalRowWithRT = ({ * the table itself has any row that is expandable * but not if this row is nested */ - const shouldRenderAsTBody = isTableExpandable && !isNested; - const containerAs = useMemo( - () => (shouldRenderAsTBody ? 'tbody' : Fragment), - [shouldRenderAsTBody], - ); + // const shouldRenderAsTBody = isTableExpandable && !isNested; + // const containerAs = useMemo( + // () => (shouldRenderAsTBody ? 'tbody' : Fragment), + // [shouldRenderAsTBody], + // ); - const tBodyProps: HTMLElementProps<'tbody'> & VirtualItem = { - className: cx({ - [expandedContentParentStyles[theme]]: isExpanded, - }), - // @ts-ignore - TODO: ? - 'data-expanded': isExpanded, - }; + // const tBodyProps: HTMLElementProps<'tbody'> & VirtualItem = { + // className: cx({ + // [expandedContentParentStyles[theme]]: isExpanded, + // }), + // // @ts-ignore - TODO: ? + // 'data-expanded': isExpanded, + // }; return ( - - - {children} - - + // + { + if (virtualRow && table) table.virtual.measureElement(node); + }} + data-index={virtualRow ? virtualRow!.index : ''} + {...rest} + > + {children} + + // ); }; diff --git a/packages/table/src/Table.stories.tsx b/packages/table/src/Table.stories.tsx index 8667a4430b..e308c50ada 100644 --- a/packages/table/src/Table.stories.tsx +++ b/packages/table/src/Table.stories.tsx @@ -96,7 +96,7 @@ const Template: StoryFn = args => { export const LiveExample: StoryFn = args => { const tableContainerRef = React.useRef(null); - const [data] = useState(() => makeKitchenSinkData(10)); + const [data] = useState(() => makeKitchenSinkData(200)); const columns = React.useMemo>>( () => [ diff --git a/packages/table/src/Table/TableWithVS.stories.tsx b/packages/table/src/Table/TableWithVS.stories.tsx index 938978400b..9a1080ee07 100644 --- a/packages/table/src/Table/TableWithVS.stories.tsx +++ b/packages/table/src/Table/TableWithVS.stories.tsx @@ -479,7 +479,12 @@ export const ExpandableContent: StoryFn = args => { return ( <> {!isExpandedContent && ( - + {row .getVisibleCells() .map((cell: LeafyGreenTableCell) => { @@ -494,7 +499,12 @@ export const ExpandableContent: StoryFn = args => { })} )} - {isExpandedContent && } + {isExpandedContent && ( + + )} ); }, diff --git a/packages/table/src/TableBody/TableBody.tsx b/packages/table/src/TableBody/TableBody.tsx index 9faf47cde0..4fa58a5496 100644 --- a/packages/table/src/TableBody/TableBody.tsx +++ b/packages/table/src/TableBody/TableBody.tsx @@ -1,22 +1,20 @@ -import React, { Fragment, useMemo } from 'react'; - -import { Polymorph } from '@leafygreen-ui/polymorphic'; - -import { useTableContext } from '../TableContext'; +import React from 'react'; +// import { Polymorph } from '@leafygreen-ui/polymorphic'; +// import { useTableContext } from '../TableContext'; import { TableBodyProps } from './TableBody.types'; const TableBody = ({ children, ...rest }: TableBodyProps) => { // const paddingTop = 0; // const paddingBottom = 0; - const { table } = useTableContext(); - const areSomeRowsExpandable = table?.getCanSomeRowsExpand(); + // const { table } = useTableContext(); + // const areSomeRowsExpandable = table?.getCanSomeRowsExpand(); - const bodyAs = useMemo( - () => (areSomeRowsExpandable ? Fragment : 'tbody'), - [areSomeRowsExpandable], - ); + // const bodyAs = useMemo( + // () => (areSomeRowsExpandable ? Fragment : 'tbody'), + // [areSomeRowsExpandable], + // ); // if (table && table.virtualRows) { // const { virtualRows, totalSize } = table; @@ -28,21 +26,22 @@ const TableBody = ({ children, ...rest }: TableBodyProps) => { // } return ( - - {/* As the user scrolls down, the paddingTop grows bigger, creating the effect of virtual scrolling */} - {/* {paddingTop > 0 && ( - - - - )} */} - {children} - {/* As the user scrolls down, the paddingBottom gets smaller, creating the effect of virtual scrolling */} - {/* {paddingBottom > 0 && ( - - - - )} */} - + {children} + // + // {/* As the user scrolls down, the paddingTop grows bigger, creating the effect of virtual scrolling */} + // {/* {paddingTop > 0 && ( + // + // + // + // )} */} + // {children} + // {/* As the user scrolls down, the paddingBottom gets smaller, creating the effect of virtual scrolling */} + // {/* {paddingBottom > 0 && ( + // + // + // + // )} */} + // ); }; diff --git a/packages/table/src/useLeafyGreenVirtualTable/useLeafyGreenVirtualTable.tsx b/packages/table/src/useLeafyGreenVirtualTable/useLeafyGreenVirtualTable.tsx index 9e93e059ce..381920751d 100644 --- a/packages/table/src/useLeafyGreenVirtualTable/useLeafyGreenVirtualTable.tsx +++ b/packages/table/src/useLeafyGreenVirtualTable/useLeafyGreenVirtualTable.tsx @@ -26,6 +26,7 @@ function useLeafyGreenVirtualTable< columns, withPagination, allowSelectAll, + hasSelectableRows, ...rest, }); From 981d8235e522840ba20a55ca82671fd98c335b47 Mon Sep 17 00:00:00 2001 From: Shaneeza Date: Tue, 24 Sep 2024 15:55:21 -0400 Subject: [PATCH 007/113] expanded row background color --- packages/table/src/Row/InternalRowWithRT.tsx | 49 +++---------------- packages/table/src/Table.stories.tsx | 2 +- packages/table/src/Table/Table.tsx | 15 ++++-- .../table/src/Table/TableWithVS.stories.tsx | 7 +-- packages/table/src/TableBody/TableBody.tsx | 2 +- 5 files changed, 23 insertions(+), 52 deletions(-) diff --git a/packages/table/src/Row/InternalRowWithRT.tsx b/packages/table/src/Row/InternalRowWithRT.tsx index d0be201f4c..a57a18c9d8 100644 --- a/packages/table/src/Row/InternalRowWithRT.tsx +++ b/packages/table/src/Row/InternalRowWithRT.tsx @@ -1,17 +1,14 @@ -import React, { Fragment, useMemo } from 'react'; -import { VirtualItem } from '@tanstack/react-virtual'; +import React from 'react'; -import { css, cx } from '@leafygreen-ui/emotion'; +import { cx } from '@leafygreen-ui/emotion'; import { useDarkMode } from '@leafygreen-ui/leafygreen-provider'; -import { HTMLElementProps } from '@leafygreen-ui/lib'; -import { Polymorph } from '@leafygreen-ui/polymorphic'; import { useTableContext } from '../TableContext'; import { LGRowData } from '../useLeafyGreenTable'; import InternalRowBase from './InternalRowBase'; import { - // expandedContentParentStyles, + expandedContentParentStyles, grayZebraRowStyles, selectedRowStyles, zebraStyles, @@ -32,44 +29,16 @@ const InternalRowWithRT = ({ }: InternalRowWithRTProps) => { const { theme } = useDarkMode(); const { disabled } = useRowContext(); - const { table, getParentRow, shouldAlternateRowColor } = useTableContext(); - const parentRow = getParentRow?.(row.id); - // const rowRef = virtualRow?.measureRef; - - // const isTableExpandable = table?.getCanSomeRowsExpand(); - const isNested = !!parentRow; - const isParentExpanded = !!parentRow && parentRow.getIsExpanded(); - const isRowVisible = isParentExpanded || !isNested; + const { table, shouldAlternateRowColor } = useTableContext(); const isOddVSRow = !!virtualRow && virtualRow.index % 2 !== 0; const isExpanded = row.getIsExpanded(); const isSelected = row.getIsSelected(); - - // const isVirtualRow = !!virtualRow; - - // console.log({ isVirtualRow }); - - /** - * Render the row within a `tbody` if - * the table itself has any row that is expandable - * but not if this row is nested - */ - // const shouldRenderAsTBody = isTableExpandable && !isNested; - // const containerAs = useMemo( - // () => (shouldRenderAsTBody ? 'tbody' : Fragment), - // [shouldRenderAsTBody], - // ); - - // const tBodyProps: HTMLElementProps<'tbody'> & VirtualItem = { - // className: cx({ - // [expandedContentParentStyles[theme]]: isExpanded, - // }), - // // @ts-ignore - TODO: ? - // 'data-expanded': isExpanded, - // }; + const isParentExpanded = row.getParentRow() + ? row.getParentRow()?.getIsExpanded() + : false; return ( - // ({ [zebraStyles[theme]]: !virtualRow && shouldAlternateRowColor && !isSelected, [selectedRowStyles[theme]]: isSelected && !disabled, + [expandedContentParentStyles[theme]]: isExpanded || isParentExpanded, }, className, )} data-selected={isSelected} - aria-hidden={!isRowVisible} data-expanded={isExpanded} id={`lg-table-row-${row.id}`} - // ref={table.virtual.measureElement} ref={node => { if (virtualRow && table) table.virtual.measureElement(node); }} @@ -94,7 +62,6 @@ const InternalRowWithRT = ({ > {children} - // ); }; diff --git a/packages/table/src/Table.stories.tsx b/packages/table/src/Table.stories.tsx index e308c50ada..ab7250fc15 100644 --- a/packages/table/src/Table.stories.tsx +++ b/packages/table/src/Table.stories.tsx @@ -96,7 +96,7 @@ const Template: StoryFn = args => { export const LiveExample: StoryFn = args => { const tableContainerRef = React.useRef(null); - const [data] = useState(() => makeKitchenSinkData(200)); + const [data] = useState(() => makeKitchenSinkData(100)); const columns = React.useMemo>>( () => [ diff --git a/packages/table/src/Table/Table.tsx b/packages/table/src/Table/Table.tsx index 1df9e7c6d8..5a07e25dff 100644 --- a/packages/table/src/Table/Table.tsx +++ b/packages/table/src/Table/Table.tsx @@ -41,7 +41,8 @@ const Table = forwardRef>( ) => { const baseFontSize: BaseFontSize = useUpdatedBaseFontSize(baseFontSizeProp); const { theme, darkMode } = useDarkMode(darkModeProp); - const isVirtual = !!(table as LeafyGreenVirtualTable)!.virtual ?? false; + const isVirtual = + table && (table as LeafyGreenVirtualTable).virtual ? true : false; const virtualTable = isVirtual && (table as LeafyGreenVirtualTable)!.virtual; const virtualTableTotalSize = virtualTable && virtualTable.getTotalSize(); @@ -56,9 +57,17 @@ const Table = forwardRef>( // eslint-disable-next-line jsx-a11y/no-noninteractive-tabindex tabIndex={0} > -
+
= args => { return ( <> {!isExpandedContent && ( - + {row .getVisibleCells() .map((cell: LeafyGreenTableCell) => { diff --git a/packages/table/src/TableBody/TableBody.tsx b/packages/table/src/TableBody/TableBody.tsx index 4fa58a5496..a01189c01c 100644 --- a/packages/table/src/TableBody/TableBody.tsx +++ b/packages/table/src/TableBody/TableBody.tsx @@ -26,7 +26,7 @@ const TableBody = ({ children, ...rest }: TableBodyProps) => { // } return ( - {children} + {children} // // {/* As the user scrolls down, the paddingTop grows bigger, creating the effect of virtual scrolling */} // {/* {paddingTop > 0 && ( From b2d94ba85590e3dc088e8a884d13427f5f4927be Mon Sep 17 00:00:00 2001 From: Shaneeza Date: Wed, 25 Sep 2024 14:23:38 -0400 Subject: [PATCH 008/113] removing stuff --- packages/table/src/Cell/Cell.tsx | 4 -- packages/table/src/Cell/InternalCell.tsx | 1 - .../src/ExpandedContent/ExpandedContent.tsx | 3 +- packages/table/src/Row/RowCellChildren.tsx | 20 ++++----- packages/table/src/Table.stories.tsx | 3 ++ packages/table/src/TableBody/TableBody.tsx | 41 +------------------ 6 files changed, 14 insertions(+), 58 deletions(-) diff --git a/packages/table/src/Cell/Cell.tsx b/packages/table/src/Cell/Cell.tsx index 4f1e38f9d8..8d1ddcd713 100644 --- a/packages/table/src/Cell/Cell.tsx +++ b/packages/table/src/Cell/Cell.tsx @@ -3,14 +3,12 @@ import React from 'react'; import { cx } from '@leafygreen-ui/emotion'; import { LGIDS } from '../constants'; -import { useTableContext } from '../TableContext'; import { alignmentStyles, baseCellStyles, basicCellStyles, cellTransitionContainerStyles, - disableAnimationStyles, } from './Cell.styles'; import { CellProps } from '.'; @@ -21,7 +19,6 @@ const Cell = ({ children, ...rest }: CellProps) => { - const { disableAnimations } = useTableContext(); return ( diff --git a/packages/table/src/Cell/InternalCell.tsx b/packages/table/src/Cell/InternalCell.tsx index e48a26db56..4ae3a0f041 100644 --- a/packages/table/src/Cell/InternalCell.tsx +++ b/packages/table/src/Cell/InternalCell.tsx @@ -22,7 +22,6 @@ const InternalCell = ({ contentClassName, cellIndex, depth, - isVisible = true, isExpandable = false, overflow, align, diff --git a/packages/table/src/ExpandedContent/ExpandedContent.tsx b/packages/table/src/ExpandedContent/ExpandedContent.tsx index b15d6a6950..d883e85626 100644 --- a/packages/table/src/ExpandedContent/ExpandedContent.tsx +++ b/packages/table/src/ExpandedContent/ExpandedContent.tsx @@ -17,8 +17,7 @@ const ExpandedContent = ({ row, ...rest }: ExpandedContentProps) => { - const { disableAnimations, getParentRow, table, isVirtual } = - useTableContext(); + const { getParentRow, table, isVirtual } = useTableContext(); const contentRef = useRef(null); const areAncestorsExpanded = getAreAncestorsExpanded(row.id, getParentRow); const isNestedRow = !!getParentRow?.(row.id); diff --git a/packages/table/src/Row/RowCellChildren.tsx b/packages/table/src/Row/RowCellChildren.tsx index eebf588282..ac86978fe4 100644 --- a/packages/table/src/Row/RowCellChildren.tsx +++ b/packages/table/src/Row/RowCellChildren.tsx @@ -1,11 +1,11 @@ import React, { ReactElement, ReactNode } from 'react'; import InternalCell from '../Cell/InternalCell'; -import { useTableContext } from '../TableContext'; +// import { useTableContext } from '../TableContext'; import ToggleExpandedIcon from '../ToggleExpandedIcon'; import { LGRowData } from '../useLeafyGreenTable'; -import { getAreAncestorsExpanded } from '../utils/areAncestorsExpanded'; +// import { getAreAncestorsExpanded } from '../utils/areAncestorsExpanded'; import { useRowContext } from './RowContext'; import { RowProps } from '.'; @@ -21,13 +21,13 @@ const RowCellChildren = ({ row, children: CellChildren, }: RowCellChildrenProps) => { - const { getParentRow } = useTableContext(); + // const { getParentRow } = useTableContext(); const { disabled } = useRowContext(); - const parentRow = getParentRow?.(row.id); - const isNested = !!parentRow; - const isParentExpanded = !!parentRow && parentRow.getIsExpanded(); - const areAncestorsExpanded = getAreAncestorsExpanded(row.id, getParentRow); - const isRowVisible = (areAncestorsExpanded && isParentExpanded) || !isNested; + // const parentRow = getParentRow?.(row.id); + // const isNested = !!parentRow; + // const isParentExpanded = !!parentRow && parentRow.getIsExpanded(); + // const areAncestorsExpanded = getAreAncestorsExpanded(row.id, getParentRow); + // const isRowVisible = (areAncestorsExpanded && isParentExpanded) || !isNested; const isExpandable = row.getCanExpand(); const isExpanded = row.getIsExpanded(); @@ -48,7 +48,7 @@ const RowCellChildren = ({ ({ )} {children} diff --git a/packages/table/src/Table.stories.tsx b/packages/table/src/Table.stories.tsx index ab7250fc15..58735ad4b6 100644 --- a/packages/table/src/Table.stories.tsx +++ b/packages/table/src/Table.stories.tsx @@ -204,6 +204,9 @@ export const LiveExample: StoryFn = args => { {!isExpandedContent && ( {row.getVisibleCells().map(cell => { + console.log({ + cellIsFirst: cell.column.getIsFirstColumn(), + }); return ( {flexRender( diff --git a/packages/table/src/TableBody/TableBody.tsx b/packages/table/src/TableBody/TableBody.tsx index a01189c01c..737c1b397f 100644 --- a/packages/table/src/TableBody/TableBody.tsx +++ b/packages/table/src/TableBody/TableBody.tsx @@ -1,48 +1,9 @@ import React from 'react'; -// import { Polymorph } from '@leafygreen-ui/polymorphic'; -// import { useTableContext } from '../TableContext'; import { TableBodyProps } from './TableBody.types'; const TableBody = ({ children, ...rest }: TableBodyProps) => { - // const paddingTop = 0; - // const paddingBottom = 0; - - // const { table } = useTableContext(); - // const areSomeRowsExpandable = table?.getCanSomeRowsExpand(); - - // const bodyAs = useMemo( - // () => (areSomeRowsExpandable ? Fragment : 'tbody'), - // [areSomeRowsExpandable], - // ); - - // if (table && table.virtualRows) { - // const { virtualRows, totalSize } = table; - // paddingTop = virtualRows.length > 0 ? virtualRows?.[0]?.start || 0 : 0; - // paddingBottom = - // virtualRows.length > 0 - // ? totalSize - (virtualRows?.[virtualRows.length - 1]?.end || 0) - // : 0; - // } - - return ( - {children} - // - // {/* As the user scrolls down, the paddingTop grows bigger, creating the effect of virtual scrolling */} - // {/* {paddingTop > 0 && ( - // - // - // - // )} */} - // {children} - // {/* As the user scrolls down, the paddingBottom gets smaller, creating the effect of virtual scrolling */} - // {/* {paddingBottom > 0 && ( - // - // - // - // )} */} - // - ); + return {children}; }; TableBody.displayName = 'TableBody'; From 7c81d49bb6350f5b6f9cc3710e3d0fe501b48c25 Mon Sep 17 00:00:00 2001 From: Shaneeza Date: Thu, 26 Sep 2024 10:47:08 -0400 Subject: [PATCH 009/113] row context --- packages/table/src/Cell/Cell.tsx | 47 +++++++++++++------ packages/table/src/Cell/Cell.types.ts | 6 ++- .../table/src/Cell/HeaderCell/HeaderCell.tsx | 4 +- packages/table/src/Cell/InternalCell.tsx | 27 ++++++++--- .../src/ExpandedContent/ExpandedContent.tsx | 23 ++++----- packages/table/src/Row/InternalRowWithRT.tsx | 21 +++++++-- packages/table/src/Row/Row.tsx | 10 ++-- packages/table/src/Row/RowCellChildren.tsx | 8 ++-- packages/table/src/Row/RowContext.tsx | 32 +++++++++++-- packages/table/src/Table.stories.tsx | 12 +++-- packages/table/src/Table/Table.tsx | 3 ++ packages/table/src/Table/Table.types.ts | 2 +- .../table/src/TableContext/TableContext.tsx | 2 + .../src/TableContext/TableContext.types.ts | 2 + .../ToggleExpandedIcon/ToggleExpandedIcon.tsx | 15 +++--- 15 files changed, 147 insertions(+), 67 deletions(-) diff --git a/packages/table/src/Cell/Cell.tsx b/packages/table/src/Cell/Cell.tsx index 8d1ddcd713..aa7b63a019 100644 --- a/packages/table/src/Cell/Cell.tsx +++ b/packages/table/src/Cell/Cell.tsx @@ -3,6 +3,7 @@ import React from 'react'; import { cx } from '@leafygreen-ui/emotion'; import { LGIDS } from '../constants'; +import { useRowContext } from '../Row/RowContext'; import { alignmentStyles, @@ -10,6 +11,7 @@ import { basicCellStyles, cellTransitionContainerStyles, } from './Cell.styles'; +import InternalCell from './InternalCell'; import { CellProps } from '.'; const Cell = ({ @@ -19,22 +21,37 @@ const Cell = ({ children, ...rest }: CellProps) => { + const { isReactTable } = useRowContext(); return ( - -
- {children} -
- + <> + {!isReactTable && ( + +
+ {children} +
+ + )} + + {isReactTable && ( + + {children} + + )} + ); }; diff --git a/packages/table/src/Cell/Cell.types.ts b/packages/table/src/Cell/Cell.types.ts index d1755940f0..be1238a635 100644 --- a/packages/table/src/Cell/Cell.types.ts +++ b/packages/table/src/Cell/Cell.types.ts @@ -39,6 +39,8 @@ interface BaseCellProps extends HTMLElementProps<'td'> { * @default CellOverflowBehavior.Default */ overflow?: CellOverflowBehavior; + + cell?: any; //FIXME: } export type CellProps = BaseCellProps; @@ -47,12 +49,12 @@ export interface InternalCellProps extends BaseCellProps { /** * Index of the cell in its parent row. */ - cellIndex: number; + cellIndex?: number; /** * Depth of nesting its parent row has. */ - depth: number; + depth?: number; /** * Defines whether the cell's row is visible (i.e. expanded) diff --git a/packages/table/src/Cell/HeaderCell/HeaderCell.tsx b/packages/table/src/Cell/HeaderCell/HeaderCell.tsx index 9a7ee85274..2ea10a40e6 100644 --- a/packages/table/src/Cell/HeaderCell/HeaderCell.tsx +++ b/packages/table/src/Cell/HeaderCell/HeaderCell.tsx @@ -35,10 +35,10 @@ const HeaderCell = ({ header, ...rest }: PropsWithChildren>) => { - const { table } = useTableContext(); + const { isSelectable } = useTableContext(); const isFirstCell = cellIndex === 0; - const isSelectable = !!table && !!table.hasSelectableRows; + // const isSelectable = !!table && !!table.hasSelectableRows; let columnName, sortState, onSortIconClick; diff --git a/packages/table/src/Cell/InternalCell.tsx b/packages/table/src/Cell/InternalCell.tsx index 4ae3a0f041..6d36bba1f9 100644 --- a/packages/table/src/Cell/InternalCell.tsx +++ b/packages/table/src/Cell/InternalCell.tsx @@ -4,7 +4,9 @@ import PropTypes from 'prop-types'; import { css, cx } from '@leafygreen-ui/emotion'; import { LGIDS } from '../constants'; +import { useRowContext } from '../Row/RowContext'; import { useTableContext } from '../TableContext'; +import ToggleExpandedIcon from '../ToggleExpandedIcon'; import { alignmentStyles, @@ -20,16 +22,21 @@ const InternalCell = ({ children, className, contentClassName, - cellIndex, - depth, - isExpandable = false, overflow, align, + cell, ...rest }: InternalCellProps) => { - const isFirstCell = cellIndex === 0; - const { table } = useTableContext(); - const isSelectable = !!table && !!table.hasSelectableRows; + const { + depth, + isExpandable = false, + toggleExpanded, + isExpanded = false, + disabled, + } = useRowContext(); + const isFirstCell = (cell && cell.column.getIsFirstColumn()) || false; + const { isSelectable } = useTableContext(); + // const isSelectable = !!table && !!table.hasSelectableRows; //TODO: move to context const contentRef = useRef(null); const contentHeight = standardCellHeight; @@ -59,11 +66,19 @@ const InternalCell = ({ cellTransitionContainerStyles, alignmentStyles(align), { + // [truncatedContentStyles]: true, [truncatedContentStyles]: shouldTruncate, }, contentClassName, )} > + {isFirstCell && isExpandable && ( + + )} {children}
diff --git a/packages/table/src/ExpandedContent/ExpandedContent.tsx b/packages/table/src/ExpandedContent/ExpandedContent.tsx index d883e85626..eccfef939c 100644 --- a/packages/table/src/ExpandedContent/ExpandedContent.tsx +++ b/packages/table/src/ExpandedContent/ExpandedContent.tsx @@ -1,4 +1,4 @@ -import React, { useMemo, useRef } from 'react'; +import React, { useRef } from 'react'; import { RowData } from '@tanstack/react-table'; import { cx } from '@leafygreen-ui/emotion'; @@ -8,7 +8,6 @@ import { cellTransitionContainerStyles } from '../Cell/Cell.styles'; import { LGIDS } from '../constants'; import InternalRowBase from '../Row/InternalRowBase'; import { useTableContext } from '../TableContext'; -import { getAreAncestorsExpanded } from '../utils/areAncestorsExpanded'; import { baseStyles, expandedContentStyles } from './ExpandedContent.styles'; import { ExpandedContentProps } from './ExpandedContent.types'; @@ -17,29 +16,25 @@ const ExpandedContent = ({ row, ...rest }: ExpandedContentProps) => { - const { getParentRow, table, isVirtual } = useTableContext(); + const { table, isVirtual } = useTableContext(); const contentRef = useRef(null); - const areAncestorsExpanded = getAreAncestorsExpanded(row.id, getParentRow); - const isNestedRow = !!getParentRow?.(row.id); - const isExpanded = - row.getIsExpanded() && (!isNestedRow || areAncestorsExpanded); + const content = row.original.renderExpandedContent && row.original.renderExpandedContent(row); const { theme } = useDarkMode(); - const contentHeight = useMemo( - () => (contentRef.current ? contentRef.current.clientHeight : 0), - // Lint flags `content` as an unnecessary dependency, but we want to update `contentHeight` when the value of `content` changes - // eslint-disable-next-line react-hooks/exhaustive-deps - [content], - ); + // const contentHeight = useMemo( + // () => (contentRef.current ? contentRef.current.clientHeight : 0), + // // Lint flags `content` as an unnecessary dependency, but we want to update `contentHeight` when the value of `content` changes + // // eslint-disable-next-line react-hooks/exhaustive-deps + // [content], + // ); return ( { // TODO: fix me // This gets the dynamic size of the element diff --git a/packages/table/src/Row/InternalRowWithRT.tsx b/packages/table/src/Row/InternalRowWithRT.tsx index a57a18c9d8..c8a1c29fe4 100644 --- a/packages/table/src/Row/InternalRowWithRT.tsx +++ b/packages/table/src/Row/InternalRowWithRT.tsx @@ -14,8 +14,8 @@ import { zebraStyles, } from './Row.styles'; import { InternalRowWithRTProps } from './Row.types'; -import RowCellChildren from './RowCellChildren'; -import { useRowContext } from './RowContext'; +import { RowContextProvider } from './RowContext'; +// import { useRowContext } from './RowContext'; /** * Renders row data provided by `useReactTable` @@ -25,10 +25,10 @@ const InternalRowWithRT = ({ className, row, virtualRow, + disabled = false, ...rest }: InternalRowWithRTProps) => { const { theme } = useDarkMode(); - const { disabled } = useRowContext(); const { table, shouldAlternateRowColor } = useTableContext(); const isOddVSRow = !!virtualRow && virtualRow.index % 2 !== 0; @@ -38,6 +38,16 @@ const InternalRowWithRT = ({ ? row.getParentRow()?.getIsExpanded() : false; + //TODO: memoize + const contextValues = { + disabled, + depth: row.depth, + isExpanded: isExpanded, + isExpandable: row.getCanExpand(), + toggleExpanded: () => row.toggleExpanded(), + isReactTable: true, + }; + return ( ({ data-expanded={isExpanded} id={`lg-table-row-${row.id}`} ref={node => { - if (virtualRow && table) table.virtual.measureElement(node); + if (virtualRow && table) table.virtual.measureElement(node); // can this be added to table context? }} data-index={virtualRow ? virtualRow!.index : ''} {...rest} > - {children} + {children} + {/* {children} */} ); }; diff --git a/packages/table/src/Row/Row.tsx b/packages/table/src/Row/Row.tsx index 5502d2c1de..fccdb4063e 100644 --- a/packages/table/src/Row/Row.tsx +++ b/packages/table/src/Row/Row.tsx @@ -6,7 +6,7 @@ import { LGRowData } from '../useLeafyGreenTable'; import InternalRowWithoutRT from './InternalRowWithoutRT'; import InternalRowWithRT from './InternalRowWithRT'; import { RowProps } from './Row.types'; -import { RowContextProvider } from './RowContext'; +// import { RowContextProvider } from './RowContext'; /** * Renders the provided cells @@ -14,17 +14,19 @@ import { RowContextProvider } from './RowContext'; const Row = ({ row, virtualRow, - disabled, + // disabled, ...rest }: RowProps) => { return ( - + // + <> {row ? ( ) : ( )} - + + // ); }; diff --git a/packages/table/src/Row/RowCellChildren.tsx b/packages/table/src/Row/RowCellChildren.tsx index ac86978fe4..ac377dcaf9 100644 --- a/packages/table/src/Row/RowCellChildren.tsx +++ b/packages/table/src/Row/RowCellChildren.tsx @@ -6,7 +6,7 @@ import ToggleExpandedIcon from '../ToggleExpandedIcon'; import { LGRowData } from '../useLeafyGreenTable'; // import { getAreAncestorsExpanded } from '../utils/areAncestorsExpanded'; -import { useRowContext } from './RowContext'; +// import { useRowContext } from './RowContext'; import { RowProps } from '.'; type RowCellChildrenProps = Required< @@ -22,7 +22,7 @@ const RowCellChildren = ({ children: CellChildren, }: RowCellChildrenProps) => { // const { getParentRow } = useTableContext(); - const { disabled } = useRowContext(); + // const { disabled } = useRowContext(); // const parentRow = getParentRow?.(row.id); // const isNested = !!parentRow; // const isParentExpanded = !!parentRow && parentRow.getIsExpanded(); @@ -50,7 +50,7 @@ const RowCellChildren = ({ cellIndex={colIndex} // isVisible={isRowVisible} isExpandable={isExpandable} - disabled={disabled} + // disabled={disabled} depth={row.depth} // @ts-expect-error Cell is not deeply extended align={cell.column.columnDef.align} @@ -59,7 +59,7 @@ const RowCellChildren = ({ )} {children} diff --git a/packages/table/src/Row/RowContext.tsx b/packages/table/src/Row/RowContext.tsx index 27b39e4c1f..fd327232f3 100644 --- a/packages/table/src/Row/RowContext.tsx +++ b/packages/table/src/Row/RowContext.tsx @@ -1,18 +1,44 @@ import React, { createContext, PropsWithChildren, useContext } from 'react'; type RowContextProps = PropsWithChildren<{ - disabled?: boolean; + disabled: boolean; + depth: number; + isExpanded: boolean; + isExpandable: boolean; + toggleExpanded: () => void; + isReactTable: boolean; }>; -const RowContext = createContext({}); +const RowContext = createContext({ + isReactTable: false, + disabled: false, + depth: 0, + isExpandable: false, + isExpanded: false, + toggleExpanded: () => {}, +}); export const useRowContext = () => useContext(RowContext); -export const RowContextProvider = ({ children, disabled }: RowContextProps) => { +// export const RowContextProvider = ({ children, disabled }: RowContextProps) => { +export const RowContextProvider = ({ + children, + disabled, + depth, + isExpanded, + isExpandable, + isReactTable, + toggleExpanded, +}: RowContextProps) => { return ( {children} diff --git a/packages/table/src/Table.stories.tsx b/packages/table/src/Table.stories.tsx index 58735ad4b6..52db20b6f0 100644 --- a/packages/table/src/Table.stories.tsx +++ b/packages/table/src/Table.stories.tsx @@ -96,7 +96,7 @@ const Template: StoryFn = args => { export const LiveExample: StoryFn = args => { const tableContainerRef = React.useRef(null); - const [data] = useState(() => makeKitchenSinkData(100)); + const [data] = useState(() => makeKitchenSinkData(500)); const columns = React.useMemo>>( () => [ @@ -204,11 +204,13 @@ export const LiveExample: StoryFn = args => { {!isExpandedContent && ( {row.getVisibleCells().map(cell => { - console.log({ - cellIsFirst: cell.column.getIsFirstColumn(), - }); return ( - + {flexRender( cell.column.columnDef.cell, cell.getContext(), diff --git a/packages/table/src/Table/Table.tsx b/packages/table/src/Table/Table.tsx index 5a07e25dff..329019eb53 100644 --- a/packages/table/src/Table/Table.tsx +++ b/packages/table/src/Table/Table.tsx @@ -48,6 +48,7 @@ const Table = forwardRef>( const virtualTableTotalSize = virtualTable && virtualTable.getTotalSize(); const virtualTableStart = (virtualTable && virtualTable.getVirtualItems()[0]?.start) ?? 0; + const isSelectable = !!table && !!table.hasSelectableRows; //TODO: move to context return (
>( virtualTableStart as number, )} > + {/* TODO: memoize values */} /** * The `useLeafyGreenTable` return value */ - table?: LeafyGreenTable | LeafyGreenVirtualTable; + table?: LeafyGreenTable | LeafyGreenVirtualTable; //TODO: is there a better way to type this? /** * Disables all transition animations for smoother rendering of tall content where appropriate diff --git a/packages/table/src/TableContext/TableContext.tsx b/packages/table/src/TableContext/TableContext.tsx index 4563185e83..50cbab4205 100644 --- a/packages/table/src/TableContext/TableContext.tsx +++ b/packages/table/src/TableContext/TableContext.tsx @@ -23,6 +23,7 @@ const TableContextProvider = ({ shouldAlternateRowColor, disableAnimations, isVirtual, + isSelectable, }: PropsWithChildren>>) => { const getRowById = (id?: string) => id ? table?.getRowModel().rowsById?.[id] : undefined; @@ -44,6 +45,7 @@ const TableContextProvider = ({ shouldAlternateRowColor, disableAnimations, isVirtual, + isSelectable, }} > {children} diff --git a/packages/table/src/TableContext/TableContext.types.ts b/packages/table/src/TableContext/TableContext.types.ts index 4748c9327a..d1cae37e87 100644 --- a/packages/table/src/TableContext/TableContext.types.ts +++ b/packages/table/src/TableContext/TableContext.types.ts @@ -28,4 +28,6 @@ export type TableContextValues = PropsWithChildren< * Whether the table is using virtual scrolling */ isVirtual?: boolean; + + isSelectable?: boolean; }; diff --git a/packages/table/src/ToggleExpandedIcon/ToggleExpandedIcon.tsx b/packages/table/src/ToggleExpandedIcon/ToggleExpandedIcon.tsx index d2af8da560..b852d33b9c 100644 --- a/packages/table/src/ToggleExpandedIcon/ToggleExpandedIcon.tsx +++ b/packages/table/src/ToggleExpandedIcon/ToggleExpandedIcon.tsx @@ -7,8 +7,8 @@ import IconButton from '@leafygreen-ui/icon-button'; import { useDarkMode } from '@leafygreen-ui/leafygreen-provider'; import { LGIDS } from '../constants'; -import { useTableContext } from '../TableContext'; +// import { useTableContext } from '../TableContext'; import { iconButtonTransitionStyles, iconFills, @@ -26,17 +26,20 @@ const ToggleExpandedIcon = ({ ...rest }: ToggleExpandedIconProps) => { const { theme } = useDarkMode(); - const { disableAnimations } = useTableContext(); + // const { disableAnimations } = useTableContext(); return ( From 4a10d1a4ba934c73f2a43816fd5b1e99674f736b Mon Sep 17 00:00:00 2001 From: Shaneeza Date: Thu, 26 Sep 2024 12:23:41 -0400 Subject: [PATCH 010/113] memoizing stuff --- .../table/src/Cell/HeaderCell/HeaderCell.tsx | 5 +- .../src/ExpandedContent/ExpandedContent.tsx | 4 +- packages/table/src/Row/InternalRowWithRT.tsx | 31 ++++++----- packages/table/src/Row/RowContext.tsx | 31 ++++++----- packages/table/src/Table.stories.tsx | 8 +-- packages/table/src/Table/Table.tsx | 34 ++++++------ .../table/src/Table/TableWithVS.stories.tsx | 2 +- .../table/src/TableContext/TableContext.tsx | 52 ++++++++++++------- .../src/TableContext/TableContext.types.ts | 3 ++ 9 files changed, 96 insertions(+), 74 deletions(-) diff --git a/packages/table/src/Cell/HeaderCell/HeaderCell.tsx b/packages/table/src/Cell/HeaderCell/HeaderCell.tsx index 2ea10a40e6..1dec972b5d 100644 --- a/packages/table/src/Cell/HeaderCell/HeaderCell.tsx +++ b/packages/table/src/Cell/HeaderCell/HeaderCell.tsx @@ -1,6 +1,6 @@ import React, { PropsWithChildren } from 'react'; -import { css, cx } from '@leafygreen-ui/emotion'; +import { cx } from '@leafygreen-ui/emotion'; import { LGIDS } from '../../constants'; import { useTableContext } from '../../TableContext'; @@ -61,9 +61,6 @@ const HeaderCell = ({ !!header?.getSize(), }, className, - // css` - // width: ${header.getSize()}px; - // `, )} scope="col" {...rest} diff --git a/packages/table/src/ExpandedContent/ExpandedContent.tsx b/packages/table/src/ExpandedContent/ExpandedContent.tsx index eccfef939c..57fb0e4976 100644 --- a/packages/table/src/ExpandedContent/ExpandedContent.tsx +++ b/packages/table/src/ExpandedContent/ExpandedContent.tsx @@ -16,7 +16,7 @@ const ExpandedContent = ({ row, ...rest }: ExpandedContentProps) => { - const { table, isVirtual } = useTableContext(); + const { measureElement, isVirtual } = useTableContext(); const contentRef = useRef(null); const content = @@ -38,7 +38,7 @@ const ExpandedContent = ({ ref={node => { // TODO: fix me // This gets the dynamic size of the element - if (isVirtual && table) table.virtual.measureElement(node); + if (isVirtual) measureElement(node); }} >
({ ...rest }: InternalRowWithRTProps) => { const { theme } = useDarkMode(); - const { table, shouldAlternateRowColor } = useTableContext(); + const { measureElement, shouldAlternateRowColor } = useTableContext(); const isOddVSRow = !!virtualRow && virtualRow.index % 2 !== 0; const isExpanded = row.getIsExpanded(); @@ -37,16 +37,23 @@ const InternalRowWithRT = ({ const isParentExpanded = row.getParentRow() ? row.getParentRow()?.getIsExpanded() : false; + const isExpandable = row.getCanExpand(); + const depth = row.depth; - //TODO: memoize - const contextValues = { - disabled, - depth: row.depth, - isExpanded: isExpanded, - isExpandable: row.getCanExpand(), - toggleExpanded: () => row.toggleExpanded(), - isReactTable: true, - }; + const toggleExpanded = useCallback(() => row.toggleExpanded(), []); // Empty dependency array, so the function is only created once + + const contextValues = useMemo(() => { + return { + disabled, + depth, + isExpanded, + isExpandable, + toggleExpanded, + isReactTable: true, + }; + }, [depth, disabled, isExpandable, isExpanded, toggleExpanded]); + + // console.log(`🪼rerender: ${row.id} ${depth}`); return ( ({ data-expanded={isExpanded} id={`lg-table-row-${row.id}`} ref={node => { - if (virtualRow && table) table.virtual.measureElement(node); // can this be added to table context? + if (measureElement) measureElement(node); // can this be added to table context? }} data-index={virtualRow ? virtualRow!.index : ''} {...rest} diff --git a/packages/table/src/Row/RowContext.tsx b/packages/table/src/Row/RowContext.tsx index fd327232f3..221eb304e0 100644 --- a/packages/table/src/Row/RowContext.tsx +++ b/packages/table/src/Row/RowContext.tsx @@ -1,4 +1,9 @@ -import React, { createContext, PropsWithChildren, useContext } from 'react'; +import React, { + createContext, + PropsWithChildren, + useContext, + useMemo, +} from 'react'; type RowContextProps = PropsWithChildren<{ disabled: boolean; @@ -30,18 +35,18 @@ export const RowContextProvider = ({ isReactTable, toggleExpanded, }: RowContextProps) => { + const providerData = useMemo(() => { + return { + disabled, + depth, + isExpanded, + isExpandable, + isReactTable, + toggleExpanded, + }; + }, [disabled, depth, isExpanded, isExpandable, isReactTable, toggleExpanded]); + return ( - - {children} - + {children} ); }; diff --git a/packages/table/src/Table.stories.tsx b/packages/table/src/Table.stories.tsx index 52db20b6f0..24a2c74d08 100644 --- a/packages/table/src/Table.stories.tsx +++ b/packages/table/src/Table.stories.tsx @@ -165,9 +165,8 @@ export const LiveExample: StoryFn = args => { columns, }); - // const { rows } = table.getRowModel(); - - const { rows } = table; + // const { rows } = table; + const { rows } = table.getRowModel(); // console.log({ rows }); @@ -220,7 +219,7 @@ export const LiveExample: StoryFn = args => { })} )} - {isExpandedContent && } + {isExpandedContent && } ); })} @@ -242,6 +241,7 @@ ZebraStripes.args = { shouldAlternateRowColor: true, }; +// TODO: i don't think we need this story export const OverflowingCell: StoryFn = args => { const data = makeData(false, 100); const columns = Object.keys(data[0]).filter( diff --git a/packages/table/src/Table/Table.tsx b/packages/table/src/Table/Table.tsx index 329019eb53..7c5ef733ef 100644 --- a/packages/table/src/Table/Table.tsx +++ b/packages/table/src/Table/Table.tsx @@ -1,4 +1,4 @@ -import React, { ForwardedRef, forwardRef } from 'react'; +import React, { ForwardedRef, forwardRef, useMemo } from 'react'; import PropTypes from 'prop-types'; import { cx } from '@leafygreen-ui/emotion'; @@ -33,7 +33,6 @@ const Table = forwardRef>( baseFontSize: baseFontSizeProp, darkMode: darkModeProp, table, - disableAnimations = false, 'data-lgid': lgidProp = LGIDS.root, ...rest }: TableProps, @@ -45,10 +44,17 @@ const Table = forwardRef>( table && (table as LeafyGreenVirtualTable).virtual ? true : false; const virtualTable = isVirtual && (table as LeafyGreenVirtualTable)!.virtual; - const virtualTableTotalSize = virtualTable && virtualTable.getTotalSize(); - const virtualTableStart = - (virtualTable && virtualTable.getVirtualItems()[0]?.start) ?? 0; - const isSelectable = !!table && !!table.hasSelectableRows; //TODO: move to context + const virtualTableTotalSize = virtualTable + ? virtualTable.getTotalSize() + : 0; + const virtualTableStart = virtualTable + ? virtualTable.getVirtualItems()[0]?.start + : 0; + const isSelectable = table && table.hasSelectableRows; + const measureElement = + isVirtual && table + ? (table as LeafyGreenVirtualTable).virtual.measureElement + : undefined; return (
>( // eslint-disable-next-line jsx-a11y/no-noninteractive-tabindex tabIndex={0} > -
+
- {/* TODO: memoize values */} = args => { {cells.map((cell: LeafyGreenTableCell) => { return ( - + {flexRender( cell.column.columnDef.cell, cell.getContext(), diff --git a/packages/table/src/TableContext/TableContext.tsx b/packages/table/src/TableContext/TableContext.tsx index 50cbab4205..ea4063ebb2 100644 --- a/packages/table/src/TableContext/TableContext.tsx +++ b/packages/table/src/TableContext/TableContext.tsx @@ -1,9 +1,13 @@ -import React, { createContext, PropsWithChildren, useContext } from 'react'; +import React, { + createContext, + PropsWithChildren, + useContext, + useMemo, +} from 'react'; import LeafyGreenProvider from '@leafygreen-ui/leafygreen-provider'; import { LGRowData } from '../useLeafyGreenTable'; -import getParentRowId from '../utils/getParentRowId'; import { type TableContextValues } from './TableContext.types'; @@ -19,34 +23,44 @@ export const useTableContext = () => const TableContextProvider = ({ children, darkMode, - table, shouldAlternateRowColor, - disableAnimations, isVirtual, isSelectable, + measureElement, }: PropsWithChildren>>) => { - const getRowById = (id?: string) => - id ? table?.getRowModel().rowsById?.[id] : undefined; - - const getParentRow = (childId?: string) => - getRowById(getParentRowId(childId)); - /** The appropriately typed context provider */ const TableProvider = (TableContext as React.Context>) .Provider; + const providerData = useMemo(() => { + return { + shouldAlternateRowColor, + darkMode, + isVirtual, + isSelectable, + measureElement, + }; + }, [ + shouldAlternateRowColor, + darkMode, + isVirtual, + isSelectable, + measureElement, + ]); + return ( {children} diff --git a/packages/table/src/TableContext/TableContext.types.ts b/packages/table/src/TableContext/TableContext.types.ts index d1cae37e87..377c5421bd 100644 --- a/packages/table/src/TableContext/TableContext.types.ts +++ b/packages/table/src/TableContext/TableContext.types.ts @@ -1,4 +1,5 @@ import { PropsWithChildren } from 'react'; +import { Virtualizer } from '@tanstack/react-virtual'; import { DarkModeProps } from '@leafygreen-ui/lib'; @@ -30,4 +31,6 @@ export type TableContextValues = PropsWithChildren< isVirtual?: boolean; isSelectable?: boolean; + + measureElement?: Virtualizer['measureElement']; }; From 55e5503f1a4368c5fab1b09e72b7683ac304cb5d Mon Sep 17 00:00:00 2001 From: Shaneeza Date: Mon, 7 Oct 2024 11:38:17 -0400 Subject: [PATCH 011/113] wip --- packages/table/src/Cell/Cell.tsx | 2 ++ packages/table/src/Cell/Cell.types.ts | 5 ++- packages/table/src/Cell/InternalCell.tsx | 27 +++++++------- .../src/ExpandedContent/ExpandedContent.tsx | 4 +-- packages/table/src/Row/InternalRowWithRT.tsx | 13 +++---- packages/table/src/Row/RowContext.tsx | 36 +++++++++---------- packages/table/src/Table.stories.tsx | 6 ++-- .../table/src/Table/TableWithVS.stories.tsx | 9 ++--- .../table/src/TableContext/TableContext.tsx | 1 + 9 files changed, 52 insertions(+), 51 deletions(-) diff --git a/packages/table/src/Cell/Cell.tsx b/packages/table/src/Cell/Cell.tsx index aa7b63a019..89eb214137 100644 --- a/packages/table/src/Cell/Cell.tsx +++ b/packages/table/src/Cell/Cell.tsx @@ -19,6 +19,7 @@ const Cell = ({ contentClassName, align, children, + cell, ...rest }: CellProps) => { const { isReactTable } = useRowContext(); @@ -45,6 +46,7 @@ const Cell = ({ {isReactTable && ( diff --git a/packages/table/src/Cell/Cell.types.ts b/packages/table/src/Cell/Cell.types.ts index be1238a635..6a3e75b80e 100644 --- a/packages/table/src/Cell/Cell.types.ts +++ b/packages/table/src/Cell/Cell.types.ts @@ -45,7 +45,10 @@ interface BaseCellProps extends HTMLElementProps<'td'> { export type CellProps = BaseCellProps; -export interface InternalCellProps extends BaseCellProps { +export type InternalCellRequiredProps = Omit & + Required>; + +export interface InternalCellProps extends InternalCellRequiredProps { /** * Index of the cell in its parent row. */ diff --git a/packages/table/src/Cell/InternalCell.tsx b/packages/table/src/Cell/InternalCell.tsx index 6d36bba1f9..e37740a215 100644 --- a/packages/table/src/Cell/InternalCell.tsx +++ b/packages/table/src/Cell/InternalCell.tsx @@ -1,7 +1,6 @@ import React, { useMemo, useRef } from 'react'; -import PropTypes from 'prop-types'; -import { css, cx } from '@leafygreen-ui/emotion'; +import { cx } from '@leafygreen-ui/emotion'; import { LGIDS } from '../constants'; import { useRowContext } from '../Row/RowContext'; @@ -28,15 +27,20 @@ const InternalCell = ({ ...rest }: InternalCellProps) => { const { - depth, - isExpandable = false, - toggleExpanded, - isExpanded = false, + // depth, + // isExpandable = false, + // toggleExpanded, + // isExpanded = false, disabled, } = useRowContext(); - const isFirstCell = (cell && cell.column.getIsFirstColumn()) || false; + // TODO: log warning if cell is not passed to Cell const { isSelectable } = useTableContext(); - // const isSelectable = !!table && !!table.hasSelectableRows; //TODO: move to context + const isFirstCell = (cell && cell.column.getIsFirstColumn()) || false; + const row = cell.row; + const isExpandable = row.getCanExpand(); + const isExpanded = row.getIsExpanded(); + const depth = row.depth; + const toggleExpanded = () => row.toggleExpanded(); const contentRef = useRef(null); const contentHeight = standardCellHeight; @@ -48,6 +52,7 @@ const InternalCell = ({ overflow === CellOverflowBehavior.Truncate && scrollHeight > contentHeight ); }, [contentHeight, overflow, scrollHeight]); + return ( - {/* {React.Children.map(children, (child: ReactNode, index: number) => { - return ( - - ); - })} */} - {children} - - ); + return {children}; }; HeaderRow.displayName = 'HeaderRow'; diff --git a/packages/table/src/Table/Table.tsx b/packages/table/src/Table/Table.tsx index 52ffc4a132..97532d28b3 100644 --- a/packages/table/src/Table/Table.tsx +++ b/packages/table/src/Table/Table.tsx @@ -40,6 +40,7 @@ const Table = forwardRef>( ) => { const baseFontSize: BaseFontSize = useUpdatedBaseFontSize(baseFontSizeProp); const { theme, darkMode } = useDarkMode(darkModeProp); + //TODO: find a better way to do all these checks const isVirtual = table && (table as LeafyGreenVirtualTable).virtual ? true : false; const virtualTable = From 55021a4b9156a6657c6c679ee87393a6c6e21937 Mon Sep 17 00:00:00 2001 From: Shaneeza Date: Wed, 9 Oct 2024 13:19:36 -0400 Subject: [PATCH 015/113] clean up --- .../src/SearchInput/SearchInput.tsx | 2 ++ packages/table/src/Table/Table.tsx | 7 +++---- .../table/src/TableContext/TableContext.tsx | 17 ++--------------- .../ToggleExpandedIcon/ToggleExpandedIcon.tsx | 3 --- 4 files changed, 7 insertions(+), 22 deletions(-) diff --git a/packages/search-input/src/SearchInput/SearchInput.tsx b/packages/search-input/src/SearchInput/SearchInput.tsx index 469bde59bd..fccb4327f2 100644 --- a/packages/search-input/src/SearchInput/SearchInput.tsx +++ b/packages/search-input/src/SearchInput/SearchInput.tsx @@ -91,6 +91,8 @@ export const SearchInput = React.forwardRef( }: SearchInputProps, forwardRef: React.Ref, ) { + console.log('hjhjhjjhj'); + const { theme, darkMode } = useDarkMode(darkModeProp); const [isOpen, setOpen] = useState(false); // The index of the currently highlighted result option diff --git a/packages/table/src/Table/Table.tsx b/packages/table/src/Table/Table.tsx index 97532d28b3..6ed28d36af 100644 --- a/packages/table/src/Table/Table.tsx +++ b/packages/table/src/Table/Table.tsx @@ -52,10 +52,9 @@ const Table = forwardRef>( ? virtualTable.getVirtualItems()[0]?.start : 0; const isSelectable = table && table.hasSelectableRows; - const measureElement = - isVirtual && table - ? (table as LeafyGreenVirtualTable).virtual.measureElement - : undefined; + const measureElement = isVirtual + ? (table as LeafyGreenVirtualTable).virtual.measureElement + : undefined; return (
() => TableContext as React.Context>, ); -//TODO: a seperate context for virtual scrolling +//TODO: a seperate context for virtual scrolling? const TableContextProvider = ({ children, darkMode, @@ -51,20 +51,7 @@ const TableContextProvider = ({ return ( - - {children} - + {children} ); }; diff --git a/packages/table/src/ToggleExpandedIcon/ToggleExpandedIcon.tsx b/packages/table/src/ToggleExpandedIcon/ToggleExpandedIcon.tsx index b852d33b9c..036517728c 100644 --- a/packages/table/src/ToggleExpandedIcon/ToggleExpandedIcon.tsx +++ b/packages/table/src/ToggleExpandedIcon/ToggleExpandedIcon.tsx @@ -8,7 +8,6 @@ import { useDarkMode } from '@leafygreen-ui/leafygreen-provider'; import { LGIDS } from '../constants'; -// import { useTableContext } from '../TableContext'; import { iconButtonTransitionStyles, iconFills, @@ -26,7 +25,6 @@ const ToggleExpandedIcon = ({ ...rest }: ToggleExpandedIconProps) => { const { theme } = useDarkMode(); - // const { disableAnimations } = useTableContext(); return ( Date: Wed, 9 Oct 2024 13:34:53 -0400 Subject: [PATCH 016/113] comments --- packages/search-input/src/SearchInput/SearchInput.tsx | 2 -- packages/table/src/Cell/Cell.styles.ts | 1 + 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/packages/search-input/src/SearchInput/SearchInput.tsx b/packages/search-input/src/SearchInput/SearchInput.tsx index fccb4327f2..469bde59bd 100644 --- a/packages/search-input/src/SearchInput/SearchInput.tsx +++ b/packages/search-input/src/SearchInput/SearchInput.tsx @@ -91,8 +91,6 @@ export const SearchInput = React.forwardRef( }: SearchInputProps, forwardRef: React.Ref, ) { - console.log('hjhjhjjhj'); - const { theme, darkMode } = useDarkMode(darkModeProp); const [isOpen, setOpen] = useState(false); // The index of the currently highlighted result option diff --git a/packages/table/src/Cell/Cell.styles.ts b/packages/table/src/Cell/Cell.styles.ts index dafcd1287c..001c9606eb 100644 --- a/packages/table/src/Cell/Cell.styles.ts +++ b/packages/table/src/Cell/Cell.styles.ts @@ -72,6 +72,7 @@ export const basicCellStyles = css` } `; +//TODO: update this export const cellTransitionContainerStyles = css` display: flex; align-items: center; From c4dcadaecc29f7b3e6ad97d68edc40ff4b2586fd Mon Sep 17 00:00:00 2001 From: Shaneeza Date: Mon, 14 Oct 2024 16:58:42 -0400 Subject: [PATCH 017/113] wip, memoize regular table --- packages/table/src/Row/InternalRowWithRT.tsx | 74 ++++++++++++++++--- packages/table/src/Row/Row.tsx | 22 +++++- packages/table/src/Table.stories.tsx | 4 +- .../useLeafyGreenTable/useLeafyGreenTable.tsx | 8 +- 4 files changed, 91 insertions(+), 17 deletions(-) diff --git a/packages/table/src/Row/InternalRowWithRT.tsx b/packages/table/src/Row/InternalRowWithRT.tsx index 6d5e93cae4..5a2f132121 100644 --- a/packages/table/src/Row/InternalRowWithRT.tsx +++ b/packages/table/src/Row/InternalRowWithRT.tsx @@ -1,6 +1,6 @@ -import React, { useMemo } from 'react'; +import React, { useEffect, useMemo, useRef } from 'react'; -import { cx } from '@leafygreen-ui/emotion'; +import { css, cx } from '@leafygreen-ui/emotion'; import { useDarkMode } from '@leafygreen-ui/leafygreen-provider'; import { useTableContext } from '../TableContext'; @@ -25,17 +25,29 @@ const InternalRowWithRT = ({ row, virtualRow, disabled = false, + shouldAlternateRowColor, + theme, + measureElement, + isExpanded, + isParentExpanded, ...rest }: InternalRowWithRTProps) => { - const { theme } = useDarkMode(); - const { measureElement, shouldAlternateRowColor } = useTableContext(); + // const { theme } = useDarkMode(); + // const { measureElement, shouldAlternateRowColor } = useTableContext(); + + const renderCount = useRef(0); + + useEffect(() => { + renderCount.current++; + }); + const isOddVSRow = !!virtualRow && virtualRow.index % 2 !== 0; - const isExpanded = row.getIsExpanded(); + // const isExpanded = row.getIsExpanded(); const isSelected = row.getIsSelected(); - const isParentExpanded = row.getParentRow() - ? row.getParentRow()?.getIsExpanded() - : false; + // const isParentExpanded = row.getParentRow() + // ? row.getParentRow()?.getIsExpanded() + // : false; const contextValues = useMemo(() => { return { @@ -44,7 +56,12 @@ const InternalRowWithRT = ({ }; }, [disabled]); - // console.log(`🪼rerender: ${row.id} ${depth}`); + const depth = row.depth; + + console.log(`🪼rerender: ${row.id}, depth: ${depth}`, { + isExpanded: isExpanded, + renderCount: renderCount.current, + }); return ( ({ !virtualRow && shouldAlternateRowColor && !isSelected, [selectedRowStyles[theme]]: isSelected && !disabled, [expandedContentParentStyles[theme]]: isExpanded || isParentExpanded, + [css` + /* display: none; */ + + > td div { + height: 0; + overflow: hidden; + min-height: 0; + } + `]: row.depth !== 0 && isParentExpanded === false, }, className, )} data-selected={isSelected} data-expanded={isExpanded} + data-depth={row.depth} id={`lg-table-row-${row.id}`} ref={node => { if (measureElement) measureElement(node); // can this be added to table context? @@ -74,3 +101,32 @@ const InternalRowWithRT = ({ }; export default InternalRowWithRT; + +const arePropsEqual = (prevProps, nextProps) => { + const prevIsExpanded = prevProps.isExpanded; + const nextIsExpanded = nextProps.isExpanded; + + const prevIsParentExpanded = prevProps.isParentExpanded; + const nextIsParentExpanded = nextProps.isParentExpanded; + + const equal = + prevIsExpanded === nextIsExpanded && + prevIsParentExpanded === nextIsParentExpanded; + + // console.log('🐞 memo check', { + // prevIsExpanded, + // nextIsExpanded, + // prevIsParentExpanded, + // nextIsParentExpanded, + // equal, + // }); + + // return prevIsExpanded === nextIsExpanded; + // return false; + return equal; +}; + +export const MemoizedInternalRowWithRT = React.memo( + InternalRowWithRT, + arePropsEqual, +); diff --git a/packages/table/src/Row/Row.tsx b/packages/table/src/Row/Row.tsx index b939b91394..46d0abc109 100644 --- a/packages/table/src/Row/Row.tsx +++ b/packages/table/src/Row/Row.tsx @@ -1,10 +1,15 @@ import React from 'react'; import PropTypes from 'prop-types'; +import { useDarkMode } from '@leafygreen-ui/leafygreen-provider'; + +import { useTableContext } from '../TableContext'; import { LGRowData } from '../useLeafyGreenTable'; import InternalRowWithoutRT from './InternalRowWithoutRT'; -import InternalRowWithRT from './InternalRowWithRT'; +import InternalRowWithRT, { + MemoizedInternalRowWithRT, +} from './InternalRowWithRT'; import { RowProps } from './Row.types'; /** @@ -15,10 +20,23 @@ const Row = ({ virtualRow, ...rest }: RowProps) => { + const { theme } = useDarkMode(); + const { measureElement, shouldAlternateRowColor } = useTableContext(); return ( <> {row ? ( - + ) : ( )} diff --git a/packages/table/src/Table.stories.tsx b/packages/table/src/Table.stories.tsx index fd96da6171..a4e8f43c03 100644 --- a/packages/table/src/Table.stories.tsx +++ b/packages/table/src/Table.stories.tsx @@ -97,7 +97,7 @@ const Template: StoryFn = args => { export const LiveExample: StoryFn = args => { const tableContainerRef = React.useRef(null); - const [data] = useState(() => makeKitchenSinkData(500)); + const [data] = useState(() => makeKitchenSinkData(200)); const columns = React.useMemo>>( () => [ @@ -167,7 +167,7 @@ export const LiveExample: StoryFn = args => { }); const { rows } = table; - // const { rows } = table.getRowModel(); + // const { flatRows: rows } = table.getRowModel(); return (
({ row, ...rest }: ExpandedContentProps) => { - const { measureElement, isVirtual } = useTableContext(); + const { measureElement } = useTableContext(); const contentRef = useRef(null); const content = @@ -38,7 +38,7 @@ const ExpandedContent = ({ ref={node => { // TODO: fix me // This gets the dynamic size of the element - if (isVirtual) measureElement(node); + if (measureElement) measureElement(node); }} > ({ const isParentExpanded = row.getParentRow() ? row.getParentRow()?.getIsExpanded() : false; - const isExpandable = row.getCanExpand(); - const depth = row.depth; + // const isExpandable = row.getCanExpand(); + // const depth = row.depth; - const toggleExpanded = useCallback(() => row.toggleExpanded(), []); // Empty dependency array, so the function is only created once + // const toggleExpanded = useCallback(() => row.toggleExpanded(), []); // Empty dependency array, so the function is only created once const contextValues = useMemo(() => { return { disabled, - depth, - isExpanded, - isExpandable, - toggleExpanded, + isReactTable: true, }; - }, [depth, disabled, isExpandable, isExpanded, toggleExpanded]); + }, [disabled]); // console.log(`🪼rerender: ${row.id} ${depth}`); diff --git a/packages/table/src/Row/RowContext.tsx b/packages/table/src/Row/RowContext.tsx index 221eb304e0..7190ccbda4 100644 --- a/packages/table/src/Row/RowContext.tsx +++ b/packages/table/src/Row/RowContext.tsx @@ -7,20 +7,20 @@ import React, { type RowContextProps = PropsWithChildren<{ disabled: boolean; - depth: number; - isExpanded: boolean; - isExpandable: boolean; - toggleExpanded: () => void; + // depth: number; + // isExpanded: boolean; + // isExpandable: boolean; + // toggleExpanded: () => void; isReactTable: boolean; }>; const RowContext = createContext({ isReactTable: false, disabled: false, - depth: 0, - isExpandable: false, - isExpanded: false, - toggleExpanded: () => {}, + // depth: 0, + // isExpandable: false, + // isExpanded: false, + // toggleExpanded: () => {}, }); export const useRowContext = () => useContext(RowContext); @@ -29,22 +29,22 @@ export const useRowContext = () => useContext(RowContext); export const RowContextProvider = ({ children, disabled, - depth, - isExpanded, - isExpandable, + // depth, + // isExpanded, + // isExpandable, isReactTable, - toggleExpanded, -}: RowContextProps) => { +}: // toggleExpanded, +RowContextProps) => { const providerData = useMemo(() => { return { disabled, - depth, - isExpanded, - isExpandable, + // depth, + // isExpanded, + // isExpandable, isReactTable, - toggleExpanded, + // toggleExpanded, }; - }, [disabled, depth, isExpanded, isExpandable, isReactTable, toggleExpanded]); + }, [disabled, isReactTable]); return ( {children} diff --git a/packages/table/src/Table.stories.tsx b/packages/table/src/Table.stories.tsx index 24a2c74d08..4da6afebb5 100644 --- a/packages/table/src/Table.stories.tsx +++ b/packages/table/src/Table.stories.tsx @@ -165,10 +165,8 @@ export const LiveExample: StoryFn = args => { columns, }); - // const { rows } = table; - const { rows } = table.getRowModel(); - - // console.log({ rows }); + const { rows } = table; + // const { rows } = table.getRowModel(); return ( = args => { {cells.map((cell: LeafyGreenTableCell) => { return ( - + {flexRender( cell.column.columnDef.cell, cell.getContext(), @@ -331,7 +331,7 @@ export const SortableRows: StoryFn = args => { {cells.map((cell: LeafyGreenTableCell) => { return ( - + {flexRender( cell.column.columnDef.cell, cell.getContext(), @@ -405,7 +405,7 @@ export const SelectableRows: StoryFn = args => { {cells.map((cell: LeafyGreenTableCell) => { return ( - + {flexRender( cell.column.columnDef.cell, cell.getContext(), @@ -484,7 +484,7 @@ export const ExpandableContent: StoryFn = args => { .getVisibleCells() .map((cell: LeafyGreenTableCell) => { return ( - + {flexRender( cell.column.columnDef.cell, cell.getContext(), @@ -579,6 +579,7 @@ export const TallRows: StoryFn = args => { max-height: unset; } `} + cell={cell} > {flexRender( cell.column.columnDef.cell, diff --git a/packages/table/src/TableContext/TableContext.tsx b/packages/table/src/TableContext/TableContext.tsx index ea4063ebb2..58209dcb8a 100644 --- a/packages/table/src/TableContext/TableContext.tsx +++ b/packages/table/src/TableContext/TableContext.tsx @@ -20,6 +20,7 @@ export const useTableContext = () => TableContext as React.Context>, ); +//TODO: a seperate context for virtual scrolling const TableContextProvider = ({ children, darkMode, From cf208fbcf76963e50c3c738399e97fd923737f31 Mon Sep 17 00:00:00 2001 From: Shaneeza Date: Tue, 8 Oct 2024 15:47:33 -0400 Subject: [PATCH 012/113] styled components --- packages/table/src/Cell/Cell.styles.ts | 2 +- .../src/Cell/HeaderCell/HeaderCell.styles.ts | 8 + .../table/src/Cell/HeaderCell/HeaderCell.tsx | 8 +- .../table/src/Row/HeaderRow/HeaderRow.tsx | 10 +- packages/table/src/Row/InternalRowWithRT.tsx | 3 +- packages/table/src/Table.stories.tsx | 168 +++++++++++++++++- packages/table/src/Table/Table.tsx | 2 +- packages/table/src/V11Adapter/V11Adapter.tsx | 1 + .../table/src/V11Adapter/V11Adapter.types.ts | 1 + .../src/utils/testHookCalls.testutils.tsx | 1 + 10 files changed, 183 insertions(+), 21 deletions(-) diff --git a/packages/table/src/Cell/Cell.styles.ts b/packages/table/src/Cell/Cell.styles.ts index 86ef2187e4..dafcd1287c 100644 --- a/packages/table/src/Cell/Cell.styles.ts +++ b/packages/table/src/Cell/Cell.styles.ts @@ -1,4 +1,4 @@ -import { css, cx } from '@leafygreen-ui/emotion'; +import { css } from '@leafygreen-ui/emotion'; import { spacing, typeScales } from '@leafygreen-ui/tokens'; import { Align } from './Cell.types'; diff --git a/packages/table/src/Cell/HeaderCell/HeaderCell.styles.ts b/packages/table/src/Cell/HeaderCell/HeaderCell.styles.ts index 0eb4d9e343..b0b5672499 100644 --- a/packages/table/src/Cell/HeaderCell/HeaderCell.styles.ts +++ b/packages/table/src/Cell/HeaderCell/HeaderCell.styles.ts @@ -1,6 +1,8 @@ import { css } from '@leafygreen-ui/emotion'; import { spacing } from '@leafygreen-ui/tokens'; +import { getCellPadding } from '../Cell.styles'; + export const headerCellContentStyles = css` height: ${spacing[5] + spacing[2]}px; `; @@ -8,3 +10,9 @@ export const headerCellContentStyles = css` export const getHeaderCellWidthStyles = (size: number) => css` width: ${size}px; `; + +export const getCellPaddingStyles = (isSelectable?: boolean) => css` + &:first-of-type { + ${getCellPadding({ depth: 0, isExpandable: false, isSelectable })} + } +`; diff --git a/packages/table/src/Cell/HeaderCell/HeaderCell.tsx b/packages/table/src/Cell/HeaderCell/HeaderCell.tsx index 1dec972b5d..8545adc9c2 100644 --- a/packages/table/src/Cell/HeaderCell/HeaderCell.tsx +++ b/packages/table/src/Cell/HeaderCell/HeaderCell.tsx @@ -9,11 +9,11 @@ import { alignmentStyles, baseCellStyles, cellTransitionContainerStyles, - getCellPadding, } from '../Cell.styles'; import SortIcon from './SortIcon/SortIcon'; import { + getCellPaddingStyles, getHeaderCellWidthStyles, headerCellContentStyles, } from './HeaderCell.styles'; @@ -37,9 +37,6 @@ const HeaderCell = ({ }: PropsWithChildren>) => { const { isSelectable } = useTableContext(); - const isFirstCell = cellIndex === 0; - // const isSelectable = !!table && !!table.hasSelectableRows; - let columnName, sortState, onSortIconClick; if (header && header.column.getCanSort()) { @@ -54,9 +51,8 @@ const HeaderCell = ({ data-lgid={LGIDS.header} className={cx( baseCellStyles, + getCellPaddingStyles(isSelectable), { - [getCellPadding({ depth: 0, isExpandable: false, isSelectable })]: - isFirstCell, [getHeaderCellWidthStyles(header?.getSize() ?? 0)]: !!header?.getSize(), }, diff --git a/packages/table/src/Row/HeaderRow/HeaderRow.tsx b/packages/table/src/Row/HeaderRow/HeaderRow.tsx index 25185a0234..5ee53701fe 100644 --- a/packages/table/src/Row/HeaderRow/HeaderRow.tsx +++ b/packages/table/src/Row/HeaderRow/HeaderRow.tsx @@ -1,7 +1,6 @@ -import React, { PropsWithChildren, ReactElement, ReactNode } from 'react'; - -import { HeaderCell } from '../../Cell'; +import React, { PropsWithChildren } from 'react'; +// import { HeaderCell } from '../../Cell'; import { HeaderRowProps } from './HeaderRow.types'; const HeaderRow = ({ @@ -10,11 +9,12 @@ const HeaderRow = ({ }: PropsWithChildren) => { return ( - {React.Children.map(children, (child: ReactNode, index: number) => { + {/* {React.Children.map(children, (child: ReactNode, index: number) => { return ( ); - })} + })} */} + {children} ); }; diff --git a/packages/table/src/Row/InternalRowWithRT.tsx b/packages/table/src/Row/InternalRowWithRT.tsx index 4d6b93bd9e..3f4f41f7a9 100644 --- a/packages/table/src/Row/InternalRowWithRT.tsx +++ b/packages/table/src/Row/InternalRowWithRT.tsx @@ -1,4 +1,4 @@ -import React, { useCallback, useMemo } from 'react'; +import React, { useMemo } from 'react'; import { cx } from '@leafygreen-ui/emotion'; import { useDarkMode } from '@leafygreen-ui/leafygreen-provider'; @@ -45,7 +45,6 @@ const InternalRowWithRT = ({ const contextValues = useMemo(() => { return { disabled, - isReactTable: true, }; }, [disabled]); diff --git a/packages/table/src/Table.stories.tsx b/packages/table/src/Table.stories.tsx index 4da6afebb5..fd96da6171 100644 --- a/packages/table/src/Table.stories.tsx +++ b/packages/table/src/Table.stories.tsx @@ -1,4 +1,5 @@ import React, { useState } from 'react'; +import styled from '@emotion/styled'; import { storybookExcludedControlParams, StoryMetaType, @@ -367,7 +368,7 @@ export const NestedRows: StoryFn = args => { .getVisibleCells() .map((cell: LeafyGreenTableCell) => { return ( - + {flexRender( cell.column.columnDef.cell, cell.getContext(), @@ -468,7 +469,7 @@ export const ExpandableContent: StoryFn = args => { {row.getVisibleCells().map(cell => { return ( - + {flexRender( cell.column.columnDef.cell, cell.getContext(), @@ -567,7 +568,7 @@ export const SortableRows: StoryFn = args => { {row.getVisibleCells().map(cell => { return ( - + {flexRender(cell.column.columnDef.cell, cell.getContext())} ); @@ -689,7 +690,7 @@ export const SelectableRows: StoryFn = args => { {row.getVisibleCells().map(cell => { return ( - + {flexRender( cell.column.columnDef.cell, cell.getContext(), @@ -816,7 +817,7 @@ export const SelectableRowsNoSelectAll: StoryFn = args => { {row.getVisibleCells().map(cell => { return ( - + {flexRender( cell.column.columnDef.cell, cell.getContext(), @@ -926,7 +927,7 @@ export const WithPagination: StoryFn = ({ {row.getVisibleCells().map(cell => { return ( - + {flexRender( cell.column.columnDef.cell, cell.getContext(), @@ -961,3 +962,158 @@ export const WithPagination: StoryFn = ({ ); }; + +export const StyledComponents: StoryFn = args => { + const tableContainerRef = React.useRef(null); + const [data] = useState(() => makeKitchenSinkData(5)); + + const columns = React.useMemo>>( + () => [ + { + accessorKey: 'dateCreated', + header: 'Date Created', + enableSorting: true, + cell: info => + (info.getValue() as Date).toLocaleDateString('en-us', { + year: 'numeric', + month: 'short', + day: 'numeric', + }), + }, + { + accessorKey: 'frequency', + header: 'Frequency', + }, + { + accessorKey: 'clusterType', + header: 'Cluster Type', + }, + { + accessorKey: 'encryptorEnabled', + header: 'Encryptor', + // eslint-disable-next-line react/display-name + cell: info => ( + + {info.getValue() ? 'Enabled' : 'Not enabled'} + + ), + }, + { + accessorKey: 'mdbVersion', + header: 'MongoDB Version', + enableSorting: true, + size: 90, + }, + { + id: 'actions', + header: '', + size: 90, + // eslint-disable-next-line react/display-name + cell: _ => { + return ( + <> + + + + + + + + + + + ); + }, + }, + ], + [], + ); + + const table = useLeafyGreenTable({ + data, + columns, + }); + + const { rows } = table; + + const StyledCell = styled(Cell)` + color: grey; + `; + + const StyledRow = styled(Row)` + background: snow; + `; + + const StyledHeaderRow = styled(HeaderRow)` + background: whitesmoke; + `; + + const StyledHeaderCell = styled(HeaderCell)` + color: black; + `; + + const StyledExpandedContent = styled(ExpandedContent)` + td > div { + background: whitesmoke; + } + `; + + return ( +
+ + {table.getHeaderGroups().map((headerGroup: HeaderGroup) => ( + + {headerGroup.headers.map(header => { + return ( + + {flexRender( + header.column.columnDef.header, + header.getContext(), + )} + + ); + })} + + ))} + + + {rows.map((row: LeafyGreenTableRow) => { + const isExpandedContent = row.original.isExpandedContent ?? false; + return ( + <> + {!isExpandedContent && ( + + {row.getVisibleCells().map(cell => { + return ( + + {flexRender( + cell.column.columnDef.cell, + cell.getContext(), + )} + + ); + })} + + )} + {isExpandedContent && ( + + )} + + ); + })} + +
+ ); +}; diff --git a/packages/table/src/Table/Table.tsx b/packages/table/src/Table/Table.tsx index 7c5ef733ef..52ffc4a132 100644 --- a/packages/table/src/Table/Table.tsx +++ b/packages/table/src/Table/Table.tsx @@ -1,4 +1,4 @@ -import React, { ForwardedRef, forwardRef, useMemo } from 'react'; +import React, { ForwardedRef, forwardRef } from 'react'; import PropTypes from 'prop-types'; import { cx } from '@leafygreen-ui/emotion'; diff --git a/packages/table/src/V11Adapter/V11Adapter.tsx b/packages/table/src/V11Adapter/V11Adapter.tsx index 0757f94065..cb0176c22d 100644 --- a/packages/table/src/V11Adapter/V11Adapter.tsx +++ b/packages/table/src/V11Adapter/V11Adapter.tsx @@ -1,3 +1,4 @@ +// @ts-nocheck import React, { ReactElement, useEffect, diff --git a/packages/table/src/V11Adapter/V11Adapter.types.ts b/packages/table/src/V11Adapter/V11Adapter.types.ts index a4c8ee109c..acb6939e01 100644 --- a/packages/table/src/V11Adapter/V11Adapter.types.ts +++ b/packages/table/src/V11Adapter/V11Adapter.types.ts @@ -1,3 +1,4 @@ +// @ts-nocheck import { PropsWithChildren } from 'react'; import { DarkModeProps } from '@leafygreen-ui/lib'; diff --git a/packages/table/src/utils/testHookCalls.testutils.tsx b/packages/table/src/utils/testHookCalls.testutils.tsx index 0070a408e0..01f74a21ba 100644 --- a/packages/table/src/utils/testHookCalls.testutils.tsx +++ b/packages/table/src/utils/testHookCalls.testutils.tsx @@ -1,3 +1,4 @@ +// @ts-nocheck import React, { useRef, useState } from 'react'; import useLeafyGreenTable, { From cadf46fd42d06ba93c1bdff201a6ba9ab6d1dee6 Mon Sep 17 00:00:00 2001 From: Shaneeza Date: Wed, 9 Oct 2024 12:34:13 -0400 Subject: [PATCH 013/113] comments --- packages/table/src/Cell/InternalCell.tsx | 9 +-------- packages/table/src/Row/InternalRowWithRT.tsx | 6 ------ packages/table/src/Row/Row.tsx | 4 ---- 3 files changed, 1 insertion(+), 18 deletions(-) diff --git a/packages/table/src/Cell/InternalCell.tsx b/packages/table/src/Cell/InternalCell.tsx index e37740a215..6553bc2692 100644 --- a/packages/table/src/Cell/InternalCell.tsx +++ b/packages/table/src/Cell/InternalCell.tsx @@ -26,13 +26,7 @@ const InternalCell = ({ cell, ...rest }: InternalCellProps) => { - const { - // depth, - // isExpandable = false, - // toggleExpanded, - // isExpanded = false, - disabled, - } = useRowContext(); + const { disabled } = useRowContext(); // TODO: log warning if cell is not passed to Cell const { isSelectable } = useTableContext(); const isFirstCell = (cell && cell.column.getIsFirstColumn()) || false; @@ -71,7 +65,6 @@ const InternalCell = ({ cellTransitionContainerStyles, alignmentStyles(align), { - // [truncatedContentStyles]: true, [truncatedContentStyles]: shouldTruncate, }, contentClassName, diff --git a/packages/table/src/Row/InternalRowWithRT.tsx b/packages/table/src/Row/InternalRowWithRT.tsx index 3f4f41f7a9..6d5e93cae4 100644 --- a/packages/table/src/Row/InternalRowWithRT.tsx +++ b/packages/table/src/Row/InternalRowWithRT.tsx @@ -15,7 +15,6 @@ import { } from './Row.styles'; import { InternalRowWithRTProps } from './Row.types'; import { RowContextProvider } from './RowContext'; -// import { useRowContext } from './RowContext'; /** * Renders row data provided by `useReactTable` @@ -37,10 +36,6 @@ const InternalRowWithRT = ({ const isParentExpanded = row.getParentRow() ? row.getParentRow()?.getIsExpanded() : false; - // const isExpandable = row.getCanExpand(); - // const depth = row.depth; - - // const toggleExpanded = useCallback(() => row.toggleExpanded(), []); // Empty dependency array, so the function is only created once const contextValues = useMemo(() => { return { @@ -74,7 +69,6 @@ const InternalRowWithRT = ({ {...rest} > {children} - {/* {children} */} ); }; diff --git a/packages/table/src/Row/Row.tsx b/packages/table/src/Row/Row.tsx index fccdb4063e..b939b91394 100644 --- a/packages/table/src/Row/Row.tsx +++ b/packages/table/src/Row/Row.tsx @@ -6,7 +6,6 @@ import { LGRowData } from '../useLeafyGreenTable'; import InternalRowWithoutRT from './InternalRowWithoutRT'; import InternalRowWithRT from './InternalRowWithRT'; import { RowProps } from './Row.types'; -// import { RowContextProvider } from './RowContext'; /** * Renders the provided cells @@ -14,11 +13,9 @@ import { RowProps } from './Row.types'; const Row = ({ row, virtualRow, - // disabled, ...rest }: RowProps) => { return ( - // <> {row ? ( @@ -26,7 +23,6 @@ const Row = ({ )} - // ); }; From fa7777e27f68d8efff4e3977be8966f45a099fe9 Mon Sep 17 00:00:00 2001 From: Shaneeza Date: Wed, 9 Oct 2024 12:44:31 -0400 Subject: [PATCH 014/113] more cleanup --- packages/table/src/Row/HeaderRow/HeaderRow.tsx | 12 +----------- packages/table/src/Table/Table.tsx | 1 + 2 files changed, 2 insertions(+), 11 deletions(-) diff --git a/packages/table/src/Row/HeaderRow/HeaderRow.tsx b/packages/table/src/Row/HeaderRow/HeaderRow.tsx index 5ee53701fe..afaef5b3ea 100644 --- a/packages/table/src/Row/HeaderRow/HeaderRow.tsx +++ b/packages/table/src/Row/HeaderRow/HeaderRow.tsx @@ -1,22 +1,12 @@ import React, { PropsWithChildren } from 'react'; -// import { HeaderCell } from '../../Cell'; import { HeaderRowProps } from './HeaderRow.types'; const HeaderRow = ({ children, ...rest }: PropsWithChildren) => { - return ( -
({ const table = useReactTable>({ state: { - expanded, + // expanded, ...rest.state, }, data, @@ -74,15 +74,15 @@ function useLeafyGreenTable({ }, enableExpanding: true, enableSortingRemoval: hasSortableColumns ? true : undefined, - onExpandedChange: setExpanded, + // onExpandedChange: setExpanded, getSubRows: row => row.subRows, getSortedRowModel: getSortedRowModel(), getPaginationRowModel: withPagination ? getPaginationRowModel() : undefined, - getExpandedRowModel: getExpandedRowModel(), + // getExpandedRowModel: getExpandedRowModel(), ...rest, }); - const { rows } = table.getRowModel(); + const { rows, flatRows } = table.getRowModel(); // A way to include expandableContent inside of the rows object. // If a row has expandedContent and its expanded then add a new row below the row From 26d5ff0f1bf44690fe1e9a9dce38912ac834cf58 Mon Sep 17 00:00:00 2001 From: Shaneeza Date: Tue, 15 Oct 2024 09:58:10 -0400 Subject: [PATCH 018/113] testing --- packages/table/src/Row/InternalRowWithRT.tsx | 8 ++++---- packages/table/src/Table.stories.tsx | 2 +- .../table/src/useLeafyGreenTable/useLeafyGreenTable.tsx | 8 +++++--- .../useLeafyGreenVirtualTable.tsx | 9 +++++++++ 4 files changed, 19 insertions(+), 8 deletions(-) diff --git a/packages/table/src/Row/InternalRowWithRT.tsx b/packages/table/src/Row/InternalRowWithRT.tsx index 5a2f132121..e11d19d89b 100644 --- a/packages/table/src/Row/InternalRowWithRT.tsx +++ b/packages/table/src/Row/InternalRowWithRT.tsx @@ -58,10 +58,10 @@ const InternalRowWithRT = ({ const depth = row.depth; - console.log(`🪼rerender: ${row.id}, depth: ${depth}`, { - isExpanded: isExpanded, - renderCount: renderCount.current, - }); + // console.log(`🪼rerender: ${row.id}, depth: ${depth}`, { + // isExpanded: isExpanded, + // renderCount: renderCount.current, + // }); return ( = args => { export const LiveExample: StoryFn = args => { const tableContainerRef = React.useRef(null); - const [data] = useState(() => makeKitchenSinkData(200)); + const [data] = useState(() => makeKitchenSinkData(500)); const columns = React.useMemo>>( () => [ diff --git a/packages/table/src/useLeafyGreenTable/useLeafyGreenTable.tsx b/packages/table/src/useLeafyGreenTable/useLeafyGreenTable.tsx index 67b507d056..7cf6f27d34 100644 --- a/packages/table/src/useLeafyGreenTable/useLeafyGreenTable.tsx +++ b/packages/table/src/useLeafyGreenTable/useLeafyGreenTable.tsx @@ -1,7 +1,7 @@ import React from 'react'; import { ExpandedState, - getExpandedRowModel, + // getExpandedRowModel, useReactTable, } from '@tanstack/react-table'; import { @@ -25,10 +25,11 @@ function useLeafyGreenTable({ hasSelectableRows, withPagination = false, allowSelectAll = true, + isVirtual = false, // virtualizerOptions, ...rest }: LeafyGreenTableOptions): LeafyGreenTable { - const [expanded, setExpanded] = React.useState({}); + // const [expanded, setExpanded] = React.useState({}); /** * A `ColumnDef` object injected into `useReactTable`'s `columns` option when the user is using selectable rows. @@ -86,7 +87,8 @@ function useLeafyGreenTable({ // A way to include expandableContent inside of the rows object. // If a row has expandedContent and its expanded then add a new row below the row - const rowsCopy = [...rows]; + const whichRows = isVirtual ? rows : flatRows; + const rowsCopy = [...whichRows]; for (let i = 0; i < rowsCopy.length; i++) { if ( diff --git a/packages/table/src/useLeafyGreenVirtualTable/useLeafyGreenVirtualTable.tsx b/packages/table/src/useLeafyGreenVirtualTable/useLeafyGreenVirtualTable.tsx index 381920751d..f7ff2aa7da 100644 --- a/packages/table/src/useLeafyGreenVirtualTable/useLeafyGreenVirtualTable.tsx +++ b/packages/table/src/useLeafyGreenVirtualTable/useLeafyGreenVirtualTable.tsx @@ -1,3 +1,5 @@ +import { useState } from 'react'; +import { ExpandedState, getExpandedRowModel } from '@tanstack/react-table'; import { useVirtualizer, VirtualItem } from '@tanstack/react-virtual'; import useLeafyGreenTable, { LGRowData } from '../useLeafyGreenTable'; @@ -21,12 +23,19 @@ function useLeafyGreenVirtualTable< virtualizerOptions, ...rest }: LeafyGreenVirtualTableOptions): LeafyGreenVirtualTable { + const [expanded, setExpanded] = useState({}); const table = useLeafyGreenTable({ data, columns, withPagination, allowSelectAll, hasSelectableRows, + onExpandedChange: setExpanded, + getExpandedRowModel: getExpandedRowModel(), + isVirtual: true, + state: { + expanded, + }, ...rest, }); From e8505d803e2633237f1852cf40d584238617a5b6 Mon Sep 17 00:00:00 2001 From: Shaneeza Date: Tue, 15 Oct 2024 11:54:22 -0400 Subject: [PATCH 019/113] huh --- packages/table/src/Cell/InternalCell.tsx | 2 + .../src/ExpandedContent/ExpandedContent.tsx | 58 +++++++----- .../MemoizedExpandedContent.tsx | 91 +++++++++++++++++++ packages/table/src/Row/InternalRowWithRT.tsx | 8 +- packages/table/src/Table.stories.tsx | 73 ++++++++++----- .../useLeafyGreenTable/useLeafyGreenTable.tsx | 45 ++++----- .../useLeafyGreenVirtualTable.tsx | 22 ++++- 7 files changed, 226 insertions(+), 73 deletions(-) create mode 100644 packages/table/src/ExpandedContent/MemoizedExpandedContent.tsx diff --git a/packages/table/src/Cell/InternalCell.tsx b/packages/table/src/Cell/InternalCell.tsx index 6553bc2692..26c0fe2164 100644 --- a/packages/table/src/Cell/InternalCell.tsx +++ b/packages/table/src/Cell/InternalCell.tsx @@ -47,6 +47,8 @@ const InternalCell = ({ ); }, [contentHeight, overflow, scrollHeight]); + console.log('💚'); + return ( + // + { - // TODO: fix me - // This gets the dynamic size of the element - if (measureElement) measureElement(node); - }} - > - - + /> ); }; diff --git a/packages/table/src/ExpandedContent/MemoizedExpandedContent.tsx b/packages/table/src/ExpandedContent/MemoizedExpandedContent.tsx new file mode 100644 index 0000000000..87526c08f4 --- /dev/null +++ b/packages/table/src/ExpandedContent/MemoizedExpandedContent.tsx @@ -0,0 +1,91 @@ +import React, { useRef } from 'react'; +import { RowData } from '@tanstack/react-table'; + +import { css, cx } from '@leafygreen-ui/emotion'; + +// import { useDarkMode } from '@leafygreen-ui/leafygreen-provider'; +import { cellTransitionContainerStyles } from '../Cell/Cell.styles'; +import { LGIDS } from '../constants'; +import InternalRowBase from '../Row/InternalRowBase'; + +import { baseStyles, expandedContentStyles } from './ExpandedContent.styles'; +import { ExpandedContentProps } from './ExpandedContent.types'; + +const ExpandedContainer = ({ + row, + theme, + measureElement, + content, + isExpanded, + ...rest +}: ExpandedContentProps) => { + const contentRef = useRef(null); + + // const contentHeight = useMemo( + // () => (contentRef.current ? contentRef.current.clientHeight : 0), + // // Lint flags `content` as an unnecessary dependency, but we want to update `contentHeight` when the value of `content` changes + // // eslint-disable-next-line react-hooks/exhaustive-deps + // [content], + // ); + + console.log(`🍉rerender🍉 ExpandedContent: ${row.id}`); + + return ( + { + // TODO: fix me + // This gets the dynamic size of the element + if (measureElement) measureElement(node); + }} + className={cx({ + [css` + /* display: none; */ + color: red; + + > td div { + height: 0; + overflow: hidden; + min-height: 0; + } + `]: isExpanded === false, + })} + data-expanded={isExpanded} + > + + + ); +}; + +ExpandedContainer.displayName = 'ExpandedContainer'; + +export default ExpandedContainer; + +const arePropsEqual = (prevProps, nextProps) => { + const prevIsExpanded = prevProps.isExpanded; + const nextIsExpanded = nextProps.isExpanded; + + // const prevIsParentExpanded = prevProps.isParentExpanded; + // const nextIsParentExpanded = nextProps.isParentExpanded; + + const equal = prevIsExpanded === nextIsExpanded; + return equal; +}; + +export const MemoizedExpandedContent = React.memo( + ExpandedContainer, + arePropsEqual, +); diff --git a/packages/table/src/Row/InternalRowWithRT.tsx b/packages/table/src/Row/InternalRowWithRT.tsx index e11d19d89b..bd1d86d781 100644 --- a/packages/table/src/Row/InternalRowWithRT.tsx +++ b/packages/table/src/Row/InternalRowWithRT.tsx @@ -58,10 +58,10 @@ const InternalRowWithRT = ({ const depth = row.depth; - // console.log(`🪼rerender: ${row.id}, depth: ${depth}`, { - // isExpanded: isExpanded, - // renderCount: renderCount.current, - // }); + console.log(`🪼rerender🪼 row: ${row.id}, depth: ${depth}`, { + isExpanded: isExpanded, + renderCount: renderCount.current, + }); return ( = args => { {rows.map((row: LeafyGreenTableRow) => { - const isExpandedContent = row.original.isExpandedContent ?? false; + // const isExpandedContent = row.original.isExpandedContent ?? false; + return ( - <> - {!isExpandedContent && ( - - {row.getVisibleCells().map(cell => { - return ( - - {flexRender( - cell.column.columnDef.cell, - cell.getContext(), - )} - - ); - })} - - )} - {isExpandedContent && } - + + {/* {!isExpandedContent && ( */} + + {row.getVisibleCells().map(cell => { + return ( + + {flexRender( + cell.column.columnDef.cell, + cell.getContext(), + )} + + ); + })} + + {row.getIsExpanded() && + row.subRows && + row.subRows.map(subRow => ( + + + {subRow.getVisibleCells().map(cell => { + return ( + + {flexRender( + cell.column.columnDef.cell, + cell.getContext(), + )} + + ); + })} + + {subRow.original.renderExpandedContent && + subRow.getIsExpanded() && ( + + )} + + ))} + {/* )} */} + {/* {row.original.renderExpandedContent && row.getIsExpanded() && ( + + )} */} + ); })} diff --git a/packages/table/src/useLeafyGreenTable/useLeafyGreenTable.tsx b/packages/table/src/useLeafyGreenTable/useLeafyGreenTable.tsx index 7cf6f27d34..d6a819c58c 100644 --- a/packages/table/src/useLeafyGreenTable/useLeafyGreenTable.tsx +++ b/packages/table/src/useLeafyGreenTable/useLeafyGreenTable.tsx @@ -1,6 +1,6 @@ import React from 'react'; import { - ExpandedState, + // ExpandedState, // getExpandedRowModel, useReactTable, } from '@tanstack/react-table'; @@ -25,7 +25,7 @@ function useLeafyGreenTable({ hasSelectableRows, withPagination = false, allowSelectAll = true, - isVirtual = false, + // isVirtual = false, // virtualizerOptions, ...rest }: LeafyGreenTableOptions): LeafyGreenTable { @@ -87,30 +87,33 @@ function useLeafyGreenTable({ // A way to include expandableContent inside of the rows object. // If a row has expandedContent and its expanded then add a new row below the row - const whichRows = isVirtual ? rows : flatRows; - const rowsCopy = [...whichRows]; + // const whichRows = isVirtual ? rows : flatRows; + // const rowsCopy = [...whichRows]; - for (let i = 0; i < rowsCopy.length; i++) { - if ( - rowsCopy[i].original.renderExpandedContent && - rowsCopy[i].getIsExpanded() - ) { - rowsCopy.splice(i + 1, 0, { - ...rowsCopy[i], - id: `${rowsCopy[i].id}-expandedContent`, - original: { - ...rowsCopy[i].original, - isExpandedContent: true, - }, - }); - i++; // Increment index to skip the newly added item - } - } + // for (let i = 0; i < rowsCopy.length; i++) { + // if ( + // rowsCopy[i].original.renderExpandedContent && + // rowsCopy[i].getIsExpanded() + // ) { + // rowsCopy.splice(i + 1, 0, { + // ...rowsCopy[i], + // id: `${rowsCopy[i].id}-expandedContent`, + // original: { + // ...rowsCopy[i].original, + // isExpandedContent: true, + // }, + // }); + // i++; // Increment index to skip the newly added item + // } + // } + + // console.log({ rowsCopy }); return { ...table, hasSelectableRows, - rows: rowsCopy, + // rows: rowsCopy, + rows: rows, } as LeafyGreenTable; } diff --git a/packages/table/src/useLeafyGreenVirtualTable/useLeafyGreenVirtualTable.tsx b/packages/table/src/useLeafyGreenVirtualTable/useLeafyGreenVirtualTable.tsx index f7ff2aa7da..9ad3c16e0a 100644 --- a/packages/table/src/useLeafyGreenVirtualTable/useLeafyGreenVirtualTable.tsx +++ b/packages/table/src/useLeafyGreenVirtualTable/useLeafyGreenVirtualTable.tsx @@ -32,7 +32,7 @@ function useLeafyGreenVirtualTable< hasSelectableRows, onExpandedChange: setExpanded, getExpandedRowModel: getExpandedRowModel(), - isVirtual: true, + // isVirtual: true, state: { expanded, }, @@ -43,6 +43,25 @@ function useLeafyGreenVirtualTable< const { rows } = table; + const rowsCopy = [...rows]; + + for (let i = 0; i < rowsCopy.length; i++) { + if ( + rowsCopy[i].original.renderExpandedContent && + rowsCopy[i].getIsExpanded() + ) { + rowsCopy.splice(i + 1, 0, { + ...rowsCopy[i], + id: `${rowsCopy[i].id}-expandedContent`, + original: { + ...rowsCopy[i].original, + isExpandedContent: true, + }, + }); + i++; // Increment index to skip the newly added item + } + } + const _virtualizer = useVirtualizer({ count: rows.length, getScrollElement: () => containerRef.current, @@ -65,6 +84,7 @@ function useLeafyGreenVirtualTable< return { ...table, + rows: rowsCopy, virtual: { ..._virtualizer, virtualItems: _virtualItems }, } as LeafyGreenVirtualTable; } From 75b42d11b1ff28de063f07ae92991e5db8677a09 Mon Sep 17 00:00:00 2001 From: Shaneeza Date: Tue, 15 Oct 2024 12:05:23 -0400 Subject: [PATCH 020/113] why does this work? --- packages/table/src/Cell/InternalCell.tsx | 2 +- .../src/ExpandedContent/ExpandedContent.tsx | 60 ++++++++----------- packages/table/src/Row/InternalRowWithRT.tsx | 18 +++--- 3 files changed, 35 insertions(+), 45 deletions(-) diff --git a/packages/table/src/Cell/InternalCell.tsx b/packages/table/src/Cell/InternalCell.tsx index 26c0fe2164..e1e99f1e90 100644 --- a/packages/table/src/Cell/InternalCell.tsx +++ b/packages/table/src/Cell/InternalCell.tsx @@ -47,7 +47,7 @@ const InternalCell = ({ ); }, [contentHeight, overflow, scrollHeight]); - console.log('💚'); + // console.log('💚'); return ( - // - + ref={node => { + // TODO: fix me + // This gets the dynamic size of the element + if (measureElement) measureElement(node); + }} + > + + ); }; diff --git a/packages/table/src/Row/InternalRowWithRT.tsx b/packages/table/src/Row/InternalRowWithRT.tsx index bd1d86d781..dcd03e8351 100644 --- a/packages/table/src/Row/InternalRowWithRT.tsx +++ b/packages/table/src/Row/InternalRowWithRT.tsx @@ -73,15 +73,15 @@ const InternalRowWithRT = ({ !virtualRow && shouldAlternateRowColor && !isSelected, [selectedRowStyles[theme]]: isSelected && !disabled, [expandedContentParentStyles[theme]]: isExpanded || isParentExpanded, - [css` - /* display: none; */ - - > td div { - height: 0; - overflow: hidden; - min-height: 0; - } - `]: row.depth !== 0 && isParentExpanded === false, + // [css` + // /* display: none; */ + + // > td div { + // height: 0; + // overflow: hidden; + // min-height: 0; + // } + // `]: row.depth !== 0 && isParentExpanded === false, }, className, )} From 90bf2abddc87245226f8426f42ccaa34f08b800f Mon Sep 17 00:00:00 2001 From: Shaneeza Date: Wed, 16 Oct 2024 12:20:07 -0400 Subject: [PATCH 021/113] testing why nothing works --- packages/table/package.json | 3 +- .../MemoizedExpandedContent.tsx | 1 + packages/table/src/Row/InternalRowWithRT.tsx | 34 +- packages/table/src/Row/Row.tsx | 2 + packages/table/src/Table.stories.tsx | 355 ++++++++++-------- .../useLeafyGreenTable/useLeafyGreenTable.tsx | 2 +- .../useLeafyGreenVirtualTable.tsx | 4 +- yarn.lock | 5 + 8 files changed, 228 insertions(+), 178 deletions(-) diff --git a/packages/table/package.json b/packages/table/package.json index 325a589a19..ab5a390bac 100644 --- a/packages/table/package.json +++ b/packages/table/package.json @@ -37,7 +37,8 @@ "@tanstack/react-virtual": "^3.10.7", "lodash": "^4.17.21", "polished": "^4.2.2", - "react-virtual": "^2.10.4" + "react-virtual": "^2.10.4", + "react-fast-compare": "3.2.2" }, "devDependencies": { "@faker-js/faker": "^8.0.0", diff --git a/packages/table/src/ExpandedContent/MemoizedExpandedContent.tsx b/packages/table/src/ExpandedContent/MemoizedExpandedContent.tsx index 87526c08f4..0c6e166a72 100644 --- a/packages/table/src/ExpandedContent/MemoizedExpandedContent.tsx +++ b/packages/table/src/ExpandedContent/MemoizedExpandedContent.tsx @@ -1,3 +1,4 @@ +// @ts-nocheck import React, { useRef } from 'react'; import { RowData } from '@tanstack/react-table'; diff --git a/packages/table/src/Row/InternalRowWithRT.tsx b/packages/table/src/Row/InternalRowWithRT.tsx index dcd03e8351..f2a3ce17d7 100644 --- a/packages/table/src/Row/InternalRowWithRT.tsx +++ b/packages/table/src/Row/InternalRowWithRT.tsx @@ -1,4 +1,6 @@ +// @ts-nocheck import React, { useEffect, useMemo, useRef } from 'react'; +import isEqual from 'react-fast-compare'; import { css, cx } from '@leafygreen-ui/emotion'; import { useDarkMode } from '@leafygreen-ui/leafygreen-provider'; @@ -30,6 +32,7 @@ const InternalRowWithRT = ({ measureElement, isExpanded, isParentExpanded, + isSelected, ...rest }: InternalRowWithRTProps) => { // const { theme } = useDarkMode(); @@ -44,7 +47,7 @@ const InternalRowWithRT = ({ const isOddVSRow = !!virtualRow && virtualRow.index % 2 !== 0; // const isExpanded = row.getIsExpanded(); - const isSelected = row.getIsSelected(); + // const isSelected = row.getIsSelected(); // const isParentExpanded = row.getParentRow() // ? row.getParentRow()?.getIsExpanded() // : false; @@ -103,27 +106,18 @@ const InternalRowWithRT = ({ export default InternalRowWithRT; const arePropsEqual = (prevProps, nextProps) => { - const prevIsExpanded = prevProps.isExpanded; - const nextIsExpanded = nextProps.isExpanded; - - const prevIsParentExpanded = prevProps.isParentExpanded; - const nextIsParentExpanded = nextProps.isParentExpanded; - - const equal = - prevIsExpanded === nextIsExpanded && - prevIsParentExpanded === nextIsParentExpanded; - - // console.log('🐞 memo check', { - // prevIsExpanded, - // nextIsExpanded, - // prevIsParentExpanded, - // nextIsParentExpanded, - // equal, + // Children will never be the same + const { children: prevChildren, ...restPrevProps } = prevProps; + const { children: nextChildren, ...restnextProps } = nextProps; + + const propsAreEqual = isEqual(restPrevProps, restnextProps); + + // console.log('🧤', { + // children: prevProps.children === nextProps.children, + // propsWithoutChildren: isEqual(restPrevProps, restnextProps), // }); - // return prevIsExpanded === nextIsExpanded; - // return false; - return equal; + return propsAreEqual; }; export const MemoizedInternalRowWithRT = React.memo( diff --git a/packages/table/src/Row/Row.tsx b/packages/table/src/Row/Row.tsx index 46d0abc109..6ca4b6adad 100644 --- a/packages/table/src/Row/Row.tsx +++ b/packages/table/src/Row/Row.tsx @@ -1,3 +1,4 @@ +// @ts-nocheck import React from 'react'; import PropTypes from 'prop-types'; @@ -35,6 +36,7 @@ const Row = ({ isParentExpanded={ row.getParentRow() ? row.getParentRow()?.getIsExpanded() : false } + isSelected={row.getIsSelected()} {...rest} /> ) : ( diff --git a/packages/table/src/Table.stories.tsx b/packages/table/src/Table.stories.tsx index a58fac9239..9e58028a69 100644 --- a/packages/table/src/Table.stories.tsx +++ b/packages/table/src/Table.stories.tsx @@ -97,7 +97,8 @@ const Template: StoryFn = args => { export const LiveExample: StoryFn = args => { const tableContainerRef = React.useRef(null); - const [data] = useState(() => makeKitchenSinkData(500)); + const [data, setData] = useState(() => makeKitchenSinkData(500)); + const refreshData = () => setData(() => makeKitchenSinkData(10)); const columns = React.useMemo>>( () => [ @@ -167,88 +168,93 @@ export const LiveExample: StoryFn = args => { }); const { rows } = table; - // const { flatRows: rows } = table.getRowModel(); return ( -
({ row, ...rest }: ExpandedContentProps) => { const { measureElement } = useTableContext(); - const contentRef = useRef(null); + // const contentRef = useRef(null); const content = row.original.renderExpandedContent && @@ -33,29 +34,40 @@ const ExpandedContent = ({ // ); return ( - { + // // TODO: fix me + // // This gets the dynamic size of the element + // if (measureElement) measureElement(node); + // }} + // > + // + //
+ //
{content}
+ //
+ //
-
-
{content}
-
-
+
+
{content}
+
+
({ row, ...rest }: ExpandedContentProps) => { const { measureElement } = useTableContext(); - // const contentRef = useRef(null); + const contentRef = useRef(null); const content = row.original.renderExpandedContent && @@ -33,41 +32,32 @@ const ExpandedContent = ({ // [content], // ); + console.log(`🍉rerender🍉 ExpandedContent: ${row.id}`); + return ( - // { - // // TODO: fix me - // // This gets the dynamic size of the element - // if (measureElement) measureElement(node); - // }} - // > - // - //
- //
{content}
- //
- //
+
+
{content}
+
+
- - {table.getHeaderGroups().map((headerGroup: HeaderGroup) => ( - - {headerGroup.headers.map(header => { - return ( - - {flexRender( - header.column.columnDef.header, - header.getContext(), - )} - - ); - })} - - ))} - - - {rows.map((row: LeafyGreenTableRow) => { - // const isExpandedContent = row.original.isExpandedContent ?? false; + <> +
+ +
+
+ + {table.getHeaderGroups().map((headerGroup: HeaderGroup) => ( + + {headerGroup.headers.map(header => { + return ( + + {flexRender( + header.column.columnDef.header, + header.getContext(), + )} + + ); + })} + + ))} + + + {rows.map((row: LeafyGreenTableRow) => { + // const isExpandedContent = row.original.isExpandedContent ?? false; - return ( - - {/* {!isExpandedContent && ( */} - - {row.getVisibleCells().map(cell => { - return ( - - {flexRender( - cell.column.columnDef.cell, - cell.getContext(), - )} - - ); - })} - - {row.getIsExpanded() && - row.subRows && - row.subRows.map(subRow => ( - - - {subRow.getVisibleCells().map(cell => { - return ( - - {flexRender( - cell.column.columnDef.cell, - cell.getContext(), - )} - - ); - })} - - {subRow.original.renderExpandedContent && - subRow.getIsExpanded() && ( - - )} - - ))} - {/* )} */} - {/* {row.original.renderExpandedContent && row.getIsExpanded() && ( + // TODO: the diff in this approach is that the keys are not chaning when a sub row opens + return ( + + {/* {!isExpandedContent && ( */} + + {row.getVisibleCells().map(cell => { + return ( + + {flexRender( + cell.column.columnDef.cell, + cell.getContext(), + )} + + ); + })} + + {row.getIsExpanded() && + row.subRows && + row.subRows.map(subRow => ( + + + {subRow.getVisibleCells().map(cell => { + return ( + + {flexRender( + cell.column.columnDef.cell, + cell.getContext(), + )} + + ); + })} + + {subRow.original.renderExpandedContent && + subRow.getIsExpanded() && ( + + )} + + ))} + {/* )} */} + {/* {row.original.renderExpandedContent && row.getIsExpanded() && ( )} */} - - ); - })} - -
+ + ); + })} + +
+ ); }; @@ -387,8 +393,8 @@ export const NestedRows: StoryFn = args => { {rows.map((row: LeafyGreenTableRow) => { return ( - <> - + + {row .getVisibleCells() .map((cell: LeafyGreenTableCell) => { @@ -402,7 +408,43 @@ export const NestedRows: StoryFn = args => { ); })} - + {row.getIsExpanded() && + row.subRows && + row.subRows.map(subRow => ( + + + {subRow.getVisibleCells().map(cell => { + return ( + + {flexRender( + cell.column.columnDef.cell, + cell.getContext(), + )} + + ); + })} + + {subRow.getIsExpanded() && + subRow.subRows && + subRow.subRows.map(subSubRow => ( + + + {subSubRow.getVisibleCells().map(cell => { + return ( + + {flexRender( + cell.column.columnDef.cell, + cell.getContext(), + )} + + ); + })} + + + ))} + + ))} + ); })} @@ -487,25 +529,25 @@ export const ExpandableContent: StoryFn = args => { {rows.map((row: LeafyGreenTableRow) => { - const isExpandedContent = row.original.isExpandedContent ?? false; + // const isExpandedContent = row.original.isExpandedContent ?? false; return ( - <> - {!isExpandedContent && ( - - {row.getVisibleCells().map(cell => { - return ( - - {flexRender( - cell.column.columnDef.cell, - cell.getContext(), - )} - - ); - })} - + + + {row.getVisibleCells().map(cell => { + return ( + + {flexRender( + cell.column.columnDef.cell, + cell.getContext(), + )} + + ); + })} + + {row.original.renderExpandedContent && row.getIsExpanded() && ( + )} - {isExpandedContent && } - + ); })} @@ -1083,62 +1125,67 @@ export const StyledComponents: StoryFn = args => { } `; + console.log({ rows }); + return ( - - - {table.getHeaderGroups().map((headerGroup: HeaderGroup) => ( - - {headerGroup.headers.map(header => { - return ( - - {flexRender( - header.column.columnDef.header, - header.getContext(), - )} - - ); - })} - - ))} - - - {rows.map((row: LeafyGreenTableRow) => { - const isExpandedContent = row.original.isExpandedContent ?? false; - return ( - <> - {!isExpandedContent && ( - - {row.getVisibleCells().map(cell => { - return ( - - {flexRender( - cell.column.columnDef.cell, - cell.getContext(), - )} - - ); - })} - - )} - {isExpandedContent && ( - - )} - - ); - })} - -
+ // + // + // {table.getHeaderGroups().map((headerGroup: HeaderGroup) => ( + // + // {headerGroup.headers.map(header => { + // return ( + // + // {flexRender( + // header.column.columnDef.header, + // header.getContext(), + // )} + // + // ); + // })} + // + // ))} + // + // + // {rows.map((row: LeafyGreenTableRow) => { + // // const isExpandedContent = row.original.isExpandedContent ?? false; + // console.log( + // 'shouldRender', + // row.original.renderExpandedContent && row.getIsExpanded(), + // ); + // return ( + // + // + // {row.getVisibleCells().map(cell => { + // return ( + // + // {flexRender( + // cell.column.columnDef.cell, + // cell.getContext(), + // )} + // + // ); + // })} + // + // {row.original.renderExpandedContent && row.getIsExpanded() && ( + // + // )} + // + // ); + // })} + // + //
+

hey

); }; diff --git a/packages/table/src/useLeafyGreenTable/useLeafyGreenTable.tsx b/packages/table/src/useLeafyGreenTable/useLeafyGreenTable.tsx index d6a819c58c..f927e3514e 100644 --- a/packages/table/src/useLeafyGreenTable/useLeafyGreenTable.tsx +++ b/packages/table/src/useLeafyGreenTable/useLeafyGreenTable.tsx @@ -83,7 +83,7 @@ function useLeafyGreenTable({ ...rest, }); - const { rows, flatRows } = table.getRowModel(); + const { rows } = table.getRowModel(); // A way to include expandableContent inside of the rows object. // If a row has expandedContent and its expanded then add a new row below the row diff --git a/packages/table/src/useLeafyGreenVirtualTable/useLeafyGreenVirtualTable.tsx b/packages/table/src/useLeafyGreenVirtualTable/useLeafyGreenVirtualTable.tsx index 9ad3c16e0a..a27c1f7b34 100644 --- a/packages/table/src/useLeafyGreenVirtualTable/useLeafyGreenVirtualTable.tsx +++ b/packages/table/src/useLeafyGreenVirtualTable/useLeafyGreenVirtualTable.tsx @@ -63,7 +63,7 @@ function useLeafyGreenVirtualTable< } const _virtualizer = useVirtualizer({ - count: rows.length, + count: rows.length, //TODO: should be rowscopy getScrollElement: () => containerRef.current, estimateSize: () => 40, overscan: 20, @@ -79,7 +79,7 @@ function useLeafyGreenVirtualTable< .getVirtualItems() .map((virtualRow: VirtualItem) => ({ ...virtualRow, - row: rows[virtualRow.index], + row: rows[virtualRow.index], //TODO: should be rowscopy })); return { diff --git a/yarn.lock b/yarn.lock index de8a962941..c9cd167481 100644 --- a/yarn.lock +++ b/yarn.lock @@ -13595,6 +13595,11 @@ react-error-boundary@^3.1.0: dependencies: "@babel/runtime" "^7.12.5" +react-fast-compare@3.2.2: + version "3.2.2" + resolved "https://registry.yarnpkg.com/react-fast-compare/-/react-fast-compare-3.2.2.tgz#929a97a532304ce9fee4bcae44234f1ce2c21d49" + integrity sha512-nsO+KSNgo1SbJqJEYRE9ERzo7YtYbou/OqjSQKxV7jcKox7+usiUVZOAC+XnDOABXggQTno0Y1CpVnuWEc1boQ== + react-intersection-observer@^8.25.1: version "8.34.0" resolved "https://registry.yarnpkg.com/react-intersection-observer/-/react-intersection-observer-8.34.0.tgz#6f6e67831c52e6233f6b6cc7eb55814820137c42" From c48994fb5c385bd0bf8f726e65dcdc047cbb3e89 Mon Sep 17 00:00:00 2001 From: Shaneeza Date: Wed, 16 Oct 2024 13:01:22 -0400 Subject: [PATCH 022/113] clean up --- .../MemoizedExpandedContent.tsx | 92 ------------ packages/table/src/Row/InternalRowWithRT.tsx | 22 +-- packages/table/src/Row/Row.tsx | 4 +- packages/table/src/Table.stories.tsx | 140 +++++++++--------- .../useLeafyGreenTable/useLeafyGreenTable.tsx | 39 +---- .../useLeafyGreenVirtualTable.tsx | 5 +- 6 files changed, 79 insertions(+), 223 deletions(-) delete mode 100644 packages/table/src/ExpandedContent/MemoizedExpandedContent.tsx diff --git a/packages/table/src/ExpandedContent/MemoizedExpandedContent.tsx b/packages/table/src/ExpandedContent/MemoizedExpandedContent.tsx deleted file mode 100644 index 0c6e166a72..0000000000 --- a/packages/table/src/ExpandedContent/MemoizedExpandedContent.tsx +++ /dev/null @@ -1,92 +0,0 @@ -// @ts-nocheck -import React, { useRef } from 'react'; -import { RowData } from '@tanstack/react-table'; - -import { css, cx } from '@leafygreen-ui/emotion'; - -// import { useDarkMode } from '@leafygreen-ui/leafygreen-provider'; -import { cellTransitionContainerStyles } from '../Cell/Cell.styles'; -import { LGIDS } from '../constants'; -import InternalRowBase from '../Row/InternalRowBase'; - -import { baseStyles, expandedContentStyles } from './ExpandedContent.styles'; -import { ExpandedContentProps } from './ExpandedContent.types'; - -const ExpandedContainer = ({ - row, - theme, - measureElement, - content, - isExpanded, - ...rest -}: ExpandedContentProps) => { - const contentRef = useRef(null); - - // const contentHeight = useMemo( - // () => (contentRef.current ? contentRef.current.clientHeight : 0), - // // Lint flags `content` as an unnecessary dependency, but we want to update `contentHeight` when the value of `content` changes - // // eslint-disable-next-line react-hooks/exhaustive-deps - // [content], - // ); - - console.log(`🍉rerender🍉 ExpandedContent: ${row.id}`); - - return ( - { - // TODO: fix me - // This gets the dynamic size of the element - if (measureElement) measureElement(node); - }} - className={cx({ - [css` - /* display: none; */ - color: red; - - > td div { - height: 0; - overflow: hidden; - min-height: 0; - } - `]: isExpanded === false, - })} - data-expanded={isExpanded} - > - -
-
{content}
-
- -
- ); -}; - -ExpandedContainer.displayName = 'ExpandedContainer'; - -export default ExpandedContainer; - -const arePropsEqual = (prevProps, nextProps) => { - const prevIsExpanded = prevProps.isExpanded; - const nextIsExpanded = nextProps.isExpanded; - - // const prevIsParentExpanded = prevProps.isParentExpanded; - // const nextIsParentExpanded = nextProps.isParentExpanded; - - const equal = prevIsExpanded === nextIsExpanded; - return equal; -}; - -export const MemoizedExpandedContent = React.memo( - ExpandedContainer, - arePropsEqual, -); diff --git a/packages/table/src/Row/InternalRowWithRT.tsx b/packages/table/src/Row/InternalRowWithRT.tsx index f2a3ce17d7..5189605b16 100644 --- a/packages/table/src/Row/InternalRowWithRT.tsx +++ b/packages/table/src/Row/InternalRowWithRT.tsx @@ -1,11 +1,9 @@ // @ts-nocheck -import React, { useEffect, useMemo, useRef } from 'react'; +import React, { useMemo } from 'react'; import isEqual from 'react-fast-compare'; -import { css, cx } from '@leafygreen-ui/emotion'; -import { useDarkMode } from '@leafygreen-ui/leafygreen-provider'; +import { cx } from '@leafygreen-ui/emotion'; -import { useTableContext } from '../TableContext'; import { LGRowData } from '../useLeafyGreenTable'; import InternalRowBase from './InternalRowBase'; @@ -35,23 +33,8 @@ const InternalRowWithRT = ({ isSelected, ...rest }: InternalRowWithRTProps) => { - // const { theme } = useDarkMode(); - // const { measureElement, shouldAlternateRowColor } = useTableContext(); - - const renderCount = useRef(0); - - useEffect(() => { - renderCount.current++; - }); - const isOddVSRow = !!virtualRow && virtualRow.index % 2 !== 0; - // const isExpanded = row.getIsExpanded(); - // const isSelected = row.getIsSelected(); - // const isParentExpanded = row.getParentRow() - // ? row.getParentRow()?.getIsExpanded() - // : false; - const contextValues = useMemo(() => { return { disabled, @@ -63,7 +46,6 @@ const InternalRowWithRT = ({ console.log(`🪼rerender🪼 row: ${row.id}, depth: ${depth}`, { isExpanded: isExpanded, - renderCount: renderCount.current, }); return ( diff --git a/packages/table/src/Row/Row.tsx b/packages/table/src/Row/Row.tsx index 6ca4b6adad..63481ffe4b 100644 --- a/packages/table/src/Row/Row.tsx +++ b/packages/table/src/Row/Row.tsx @@ -8,9 +8,7 @@ import { useTableContext } from '../TableContext'; import { LGRowData } from '../useLeafyGreenTable'; import InternalRowWithoutRT from './InternalRowWithoutRT'; -import InternalRowWithRT, { - MemoizedInternalRowWithRT, -} from './InternalRowWithRT'; +import { MemoizedInternalRowWithRT } from './InternalRowWithRT'; import { RowProps } from './Row.types'; /** diff --git a/packages/table/src/Table.stories.tsx b/packages/table/src/Table.stories.tsx index 9e58028a69..782e4c5fd0 100644 --- a/packages/table/src/Table.stories.tsx +++ b/packages/table/src/Table.stories.tsx @@ -245,10 +245,6 @@ export const LiveExample: StoryFn = args => { )} ))} - {/* )} */} - {/* {row.original.renderExpandedContent && row.getIsExpanded() && ( - - )} */} ); })} @@ -314,7 +310,7 @@ export const OverflowingCell: StoryFn = args => { export const NestedRows: StoryFn = args => { const tableContainerRef = React.useRef(null); - const [data] = React.useState(() => makeData(false, 20, 5, 3)); + const [data] = React.useState(() => makeData(false, 500, 5, 3)); const columns = React.useMemo>>( () => [ @@ -529,7 +525,6 @@ export const ExpandableContent: StoryFn = args => { {rows.map((row: LeafyGreenTableRow) => { - // const isExpandedContent = row.original.isExpandedContent ?? false; return ( @@ -1125,67 +1120,78 @@ export const StyledComponents: StoryFn = args => { } `; - console.log({ rows }); - return ( - // - // - // {table.getHeaderGroups().map((headerGroup: HeaderGroup) => ( - // - // {headerGroup.headers.map(header => { - // return ( - // - // {flexRender( - // header.column.columnDef.header, - // header.getContext(), - // )} - // - // ); - // })} - // - // ))} - // - // - // {rows.map((row: LeafyGreenTableRow) => { - // // const isExpandedContent = row.original.isExpandedContent ?? false; - // console.log( - // 'shouldRender', - // row.original.renderExpandedContent && row.getIsExpanded(), - // ); - // return ( - // - // - // {row.getVisibleCells().map(cell => { - // return ( - // - // {flexRender( - // cell.column.columnDef.cell, - // cell.getContext(), - // )} - // - // ); - // })} - // - // {row.original.renderExpandedContent && row.getIsExpanded() && ( - // - // )} - // - // ); - // })} - // - //
-

hey

+ + + {table.getHeaderGroups().map((headerGroup: HeaderGroup) => ( + + {headerGroup.headers.map(header => { + return ( + + {flexRender( + header.column.columnDef.header, + header.getContext(), + )} + + ); + })} + + ))} + + + {rows.map((row: LeafyGreenTableRow) => { + return ( + + + {row.getVisibleCells().map(cell => { + return ( + + {flexRender( + cell.column.columnDef.cell, + cell.getContext(), + )} + + ); + })} + + {row.getIsExpanded() && + row.subRows && + row.subRows.map(subRow => ( + + + {subRow.getVisibleCells().map(cell => { + return ( + + {flexRender( + cell.column.columnDef.cell, + cell.getContext(), + )} + + ); + })} + + {subRow.original.renderExpandedContent && + subRow.getIsExpanded() && ( + + )} + + ))} + + ); + })} + +
); }; diff --git a/packages/table/src/useLeafyGreenTable/useLeafyGreenTable.tsx b/packages/table/src/useLeafyGreenTable/useLeafyGreenTable.tsx index f927e3514e..7e37ddc6e0 100644 --- a/packages/table/src/useLeafyGreenTable/useLeafyGreenTable.tsx +++ b/packages/table/src/useLeafyGreenTable/useLeafyGreenTable.tsx @@ -1,9 +1,5 @@ import React from 'react'; -import { - // ExpandedState, - // getExpandedRowModel, - useReactTable, -} from '@tanstack/react-table'; +import { useReactTable } from '@tanstack/react-table'; import { getCoreRowModel, getPaginationRowModel, @@ -19,18 +15,13 @@ import { LeafyGreenTable, LGColumnDef, LGTableDataType } from '.'; const CHECKBOX_WIDTH = 14; function useLeafyGreenTable({ - // containerRef, data, columns: columnsProp, hasSelectableRows, withPagination = false, allowSelectAll = true, - // isVirtual = false, - // virtualizerOptions, ...rest }: LeafyGreenTableOptions): LeafyGreenTable { - // const [expanded, setExpanded] = React.useState({}); - /** * A `ColumnDef` object injected into `useReactTable`'s `columns` option when the user is using selectable rows. */ @@ -64,7 +55,6 @@ function useLeafyGreenTable({ const table = useReactTable>({ state: { - // expanded, ...rest.state, }, data, @@ -75,44 +65,17 @@ function useLeafyGreenTable({ }, enableExpanding: true, enableSortingRemoval: hasSortableColumns ? true : undefined, - // onExpandedChange: setExpanded, getSubRows: row => row.subRows, getSortedRowModel: getSortedRowModel(), getPaginationRowModel: withPagination ? getPaginationRowModel() : undefined, - // getExpandedRowModel: getExpandedRowModel(), ...rest, }); const { rows } = table.getRowModel(); - // A way to include expandableContent inside of the rows object. - // If a row has expandedContent and its expanded then add a new row below the row - // const whichRows = isVirtual ? rows : flatRows; - // const rowsCopy = [...whichRows]; - - // for (let i = 0; i < rowsCopy.length; i++) { - // if ( - // rowsCopy[i].original.renderExpandedContent && - // rowsCopy[i].getIsExpanded() - // ) { - // rowsCopy.splice(i + 1, 0, { - // ...rowsCopy[i], - // id: `${rowsCopy[i].id}-expandedContent`, - // original: { - // ...rowsCopy[i].original, - // isExpandedContent: true, - // }, - // }); - // i++; // Increment index to skip the newly added item - // } - // } - - // console.log({ rowsCopy }); - return { ...table, hasSelectableRows, - // rows: rowsCopy, rows: rows, } as LeafyGreenTable; } diff --git a/packages/table/src/useLeafyGreenVirtualTable/useLeafyGreenVirtualTable.tsx b/packages/table/src/useLeafyGreenVirtualTable/useLeafyGreenVirtualTable.tsx index a27c1f7b34..157d5d0d36 100644 --- a/packages/table/src/useLeafyGreenVirtualTable/useLeafyGreenVirtualTable.tsx +++ b/packages/table/src/useLeafyGreenVirtualTable/useLeafyGreenVirtualTable.tsx @@ -32,19 +32,18 @@ function useLeafyGreenVirtualTable< hasSelectableRows, onExpandedChange: setExpanded, getExpandedRowModel: getExpandedRowModel(), - // isVirtual: true, state: { expanded, }, ...rest, }); - // const { rows } = table.getRowModel(); - const { rows } = table; const rowsCopy = [...rows]; + // A way to include expandableContent inside of the rows object. + // If a row has expandedContent and its expanded then add a new row below the row for (let i = 0; i < rowsCopy.length; i++) { if ( rowsCopy[i].original.renderExpandedContent && From 4b3ac8c8ff4da874af4827d6d526f5d8a52dbf39 Mon Sep 17 00:00:00 2001 From: Shaneeza Date: Wed, 16 Oct 2024 13:20:50 -0400 Subject: [PATCH 023/113] update virtual stories --- packages/table/src/Table/TableWithVS.stories.tsx | 16 ++++++++++------ .../useLeafyGreenVirtualTable.tsx | 12 ++++++++---- 2 files changed, 18 insertions(+), 10 deletions(-) diff --git a/packages/table/src/Table/TableWithVS.stories.tsx b/packages/table/src/Table/TableWithVS.stories.tsx index d2a3f283cc..46dc0b6b3e 100644 --- a/packages/table/src/Table/TableWithVS.stories.tsx +++ b/packages/table/src/Table/TableWithVS.stories.tsx @@ -95,7 +95,6 @@ const basicColumnDefs: Array> = [ export const Basic: StoryFn = args => { const tableContainerRef = React.useRef(null); const data = React.useMemo(() => makeData(false, 10_000), []); - // const data = React.useMemo(() => makeData(false, 100), []); const columns = useMemo(() => basicColumnDefs, []); @@ -142,7 +141,7 @@ export const Basic: StoryFn = args => { const row = virtualRow.row; const cells = row.getVisibleCells(); return ( - + {cells.map((cell: LeafyGreenTableCell) => { return ( @@ -212,7 +211,7 @@ export const NestedRows: StoryFn = args => { return ( <> - + {cells.map((cell: LeafyGreenTableCell) => { return ( @@ -328,7 +327,7 @@ export const SortableRows: StoryFn = args => { const cells = row.getVisibleCells(); return ( - + {cells.map((cell: LeafyGreenTableCell) => { return ( @@ -402,7 +401,7 @@ export const SelectableRows: StoryFn = args => { const cells = row.getVisibleCells(); return ( - + {cells.map((cell: LeafyGreenTableCell) => { return ( @@ -479,7 +478,11 @@ export const ExpandableContent: StoryFn = args => { return ( <> {!isExpandedContent && ( - + {row .getVisibleCells() .map((cell: LeafyGreenTableCell) => { @@ -498,6 +501,7 @@ export const ExpandableContent: StoryFn = args => { )} diff --git a/packages/table/src/useLeafyGreenVirtualTable/useLeafyGreenVirtualTable.tsx b/packages/table/src/useLeafyGreenVirtualTable/useLeafyGreenVirtualTable.tsx index 157d5d0d36..59dde3db93 100644 --- a/packages/table/src/useLeafyGreenVirtualTable/useLeafyGreenVirtualTable.tsx +++ b/packages/table/src/useLeafyGreenVirtualTable/useLeafyGreenVirtualTable.tsx @@ -1,4 +1,4 @@ -import { useState } from 'react'; +import { useCallback, useMemo, useState } from 'react'; import { ExpandedState, getExpandedRowModel } from '@tanstack/react-table'; import { useVirtualizer, VirtualItem } from '@tanstack/react-virtual'; @@ -40,7 +40,7 @@ function useLeafyGreenVirtualTable< const { rows } = table; - const rowsCopy = [...rows]; + const rowsCopy = useMemo(() => [...rows], [rows]); // A way to include expandableContent inside of the rows object. // If a row has expandedContent and its expanded then add a new row below the row @@ -62,10 +62,14 @@ function useLeafyGreenVirtualTable< } const _virtualizer = useVirtualizer({ - count: rows.length, //TODO: should be rowscopy + count: rowsCopy.length, getScrollElement: () => containerRef.current, estimateSize: () => 40, overscan: 20, + getItemKey: useCallback( + (index: number) => rowsCopy[index]?.id ?? index, + [rowsCopy], + ), measureElement: typeof window !== 'undefined' && navigator.userAgent.indexOf('Firefox') === -1 @@ -78,7 +82,7 @@ function useLeafyGreenVirtualTable< .getVirtualItems() .map((virtualRow: VirtualItem) => ({ ...virtualRow, - row: rows[virtualRow.index], //TODO: should be rowscopy + row: rowsCopy[virtualRow.index], })); return { From dd1f7f9c25d5df795db670610595f8c9614b5a6e Mon Sep 17 00:00:00 2001 From: Shaneeza Date: Wed, 16 Oct 2024 13:35:26 -0400 Subject: [PATCH 024/113] clean up --- packages/table/package.json | 3 ++- packages/table/src/Table.stories.tsx | 6 +----- 2 files changed, 3 insertions(+), 6 deletions(-) diff --git a/packages/table/package.json b/packages/table/package.json index ab5a390bac..d0e872dd8b 100644 --- a/packages/table/package.json +++ b/packages/table/package.json @@ -38,7 +38,8 @@ "lodash": "^4.17.21", "polished": "^4.2.2", "react-virtual": "^2.10.4", - "react-fast-compare": "3.2.2" + "react-fast-compare": "3.2.2", + "react-transition-group": "^4.4.5" }, "devDependencies": { "@faker-js/faker": "^8.0.0", diff --git a/packages/table/src/Table.stories.tsx b/packages/table/src/Table.stories.tsx index 782e4c5fd0..6c4e0bdb80 100644 --- a/packages/table/src/Table.stories.tsx +++ b/packages/table/src/Table.stories.tsx @@ -97,8 +97,7 @@ const Template: StoryFn = args => { export const LiveExample: StoryFn = args => { const tableContainerRef = React.useRef(null); - const [data, setData] = useState(() => makeKitchenSinkData(500)); - const refreshData = () => setData(() => makeKitchenSinkData(10)); + const [data] = useState(() => makeKitchenSinkData(500)); const columns = React.useMemo>>( () => [ @@ -171,9 +170,6 @@ export const LiveExample: StoryFn = args => { return ( <> -
- -
Date: Wed, 16 Oct 2024 15:38:35 -0400 Subject: [PATCH 025/113] cleanup --- packages/table/src/Cell/Cell.styles.ts | 2 +- packages/table/src/Cell/InternalCell.tsx | 2 +- packages/table/src/Row/RowCellChildren.tsx | 74 ------------------- packages/table/src/Row/RowContext.tsx | 19 +---- .../useLeafyGreenTable.types.ts | 10 --- 5 files changed, 3 insertions(+), 104 deletions(-) delete mode 100644 packages/table/src/Row/RowCellChildren.tsx diff --git a/packages/table/src/Cell/Cell.styles.ts b/packages/table/src/Cell/Cell.styles.ts index 001c9606eb..ee62a3770f 100644 --- a/packages/table/src/Cell/Cell.styles.ts +++ b/packages/table/src/Cell/Cell.styles.ts @@ -72,7 +72,7 @@ export const basicCellStyles = css` } `; -//TODO: update this +//TODO: update this when working on multi line content export const cellTransitionContainerStyles = css` display: flex; align-items: center; diff --git a/packages/table/src/Cell/InternalCell.tsx b/packages/table/src/Cell/InternalCell.tsx index e1e99f1e90..43dcd42d70 100644 --- a/packages/table/src/Cell/InternalCell.tsx +++ b/packages/table/src/Cell/InternalCell.tsx @@ -47,7 +47,7 @@ const InternalCell = ({ ); }, [contentHeight, overflow, scrollHeight]); - // console.log('💚'); + // TODO: memoize me return ( ); diff --git a/packages/table/src/ExpandedContent/ExpandedContent.styles.ts b/packages/table/src/ExpandedContent/ExpandedContent.styles.ts index 504b911986..150a1705aa 100644 --- a/packages/table/src/ExpandedContent/ExpandedContent.styles.ts +++ b/packages/table/src/ExpandedContent/ExpandedContent.styles.ts @@ -8,7 +8,6 @@ export const baseStyles = css` overflow: hidden; transition: ${transitionDuration.default}ms ease; - //TODO: this is temp > div { max-height: inherit; } diff --git a/packages/table/src/ExpandedContent/ExpandedContent.tsx b/packages/table/src/ExpandedContent/ExpandedContent.tsx index 66ba55f9c5..c8b7b241ce 100644 --- a/packages/table/src/ExpandedContent/ExpandedContent.tsx +++ b/packages/table/src/ExpandedContent/ExpandedContent.tsx @@ -1,10 +1,10 @@ -import React, { useRef } from 'react'; +import React from 'react'; import { RowData } from '@tanstack/react-table'; import { cx } from '@leafygreen-ui/emotion'; import { useDarkMode } from '@leafygreen-ui/leafygreen-provider'; -import { cellTransitionContainerStyles } from '../Cell/Cell.styles'; +import { cellContainerStyles } from '../Cell/Cell.styles'; import { LGIDS } from '../constants'; import InternalRowBase from '../Row/InternalRowBase'; import { useTableContext } from '../TableContext'; @@ -17,7 +17,6 @@ const ExpandedContent = ({ ...rest }: ExpandedContentProps) => { const { measureElement } = useTableContext(); - const contentRef = useRef(null); const content = row.original.renderExpandedContent && @@ -25,13 +24,7 @@ const ExpandedContent = ({ const { theme } = useDarkMode(); - // const contentHeight = useMemo( - // () => (contentRef.current ? contentRef.current.clientHeight : 0), - // // Lint flags `content` as an unnecessary dependency, but we want to update `contentHeight` when the value of `content` changes - // // eslint-disable-next-line react-hooks/exhaustive-deps - // [content], - // ); - + // eslint-disable-next-line no-console console.log(`🍉rerender🍉 ExpandedContent: ${row.id}`); return ( @@ -49,12 +42,9 @@ const ExpandedContent = ({ data-lgid={LGIDS.cell} >
-
{content}
+
{content}
diff --git a/packages/table/src/Row/Row.tsx b/packages/table/src/Row/Row.tsx index 63481ffe4b..fc78111d2b 100644 --- a/packages/table/src/Row/Row.tsx +++ b/packages/table/src/Row/Row.tsx @@ -1,4 +1,3 @@ -// @ts-nocheck import React from 'react'; import PropTypes from 'prop-types'; @@ -25,12 +24,15 @@ const Row = ({ <> {row ? ( = args => { - const data = makeData(false, 100); - const columns = Object.keys(data[0]).filter( - x => x !== 'renderExpandedContent' && x !== 'subRows', - ); - return ( -
= Required< - Pick, 'row'> -> & - Pick, 'disabled' | 'children'>; - -/** - * Renders row cells provided by `useReactTable` - */ -const RowCellChildren = ({ - row, - children: CellChildren, -}: RowCellChildrenProps) => { - // const { getParentRow } = useTableContext(); - // const { disabled } = useRowContext(); - // const parentRow = getParentRow?.(row.id); - // const isNested = !!parentRow; - // const isParentExpanded = !!parentRow && parentRow.getIsExpanded(); - // const areAncestorsExpanded = getAreAncestorsExpanded(row.id, getParentRow); - // const isRowVisible = (areAncestorsExpanded && isParentExpanded) || !isNested; - - const isExpandable = row.getCanExpand(); - const isExpanded = row.getIsExpanded(); - - const toggleExpanded = () => row.toggleExpanded(); - - return ( - <> - {React.Children.map( - CellChildren, - (child: ReactNode, colIndex: number) => { - // FIXME: - // eslint-disable-next-line no-unsafe-optional-chaining - const { children, ...props } = (child as ReactElement)?.props; - const isFirstCell = colIndex === 0; - const cell = row.getVisibleCells()[colIndex]; - return ( - - {isFirstCell && isExpandable && ( - - )} - {children} - - ); - }, - )} - - ); -}; - -export default RowCellChildren; diff --git a/packages/table/src/Row/RowContext.tsx b/packages/table/src/Row/RowContext.tsx index 7190ccbda4..de2535c1bd 100644 --- a/packages/table/src/Row/RowContext.tsx +++ b/packages/table/src/Row/RowContext.tsx @@ -7,42 +7,25 @@ import React, { type RowContextProps = PropsWithChildren<{ disabled: boolean; - // depth: number; - // isExpanded: boolean; - // isExpandable: boolean; - // toggleExpanded: () => void; isReactTable: boolean; }>; const RowContext = createContext({ isReactTable: false, disabled: false, - // depth: 0, - // isExpandable: false, - // isExpanded: false, - // toggleExpanded: () => {}, }); export const useRowContext = () => useContext(RowContext); -// export const RowContextProvider = ({ children, disabled }: RowContextProps) => { export const RowContextProvider = ({ children, disabled, - // depth, - // isExpanded, - // isExpandable, isReactTable, -}: // toggleExpanded, -RowContextProps) => { +}: RowContextProps) => { const providerData = useMemo(() => { return { disabled, - // depth, - // isExpanded, - // isExpandable, isReactTable, - // toggleExpanded, }; }, [disabled, isReactTable]); diff --git a/packages/table/src/useLeafyGreenTable/useLeafyGreenTable.types.ts b/packages/table/src/useLeafyGreenTable/useLeafyGreenTable.types.ts index 0322401be4..78b95d11c4 100644 --- a/packages/table/src/useLeafyGreenTable/useLeafyGreenTable.types.ts +++ b/packages/table/src/useLeafyGreenTable/useLeafyGreenTable.types.ts @@ -1,8 +1,3 @@ -// import { RefObject } from 'react'; -// import { -// type Options as VirtualizerOptions, -// type VirtualItem, -// } from 'react-virtual'; import { Cell, ColumnDef, @@ -14,8 +9,6 @@ import { import { HTMLElementProps } from '@leafygreen-ui/lib'; -// import { VirtualizerValues } from './ReactVirtual.types'; - /** LeafyGreen extension of `useReactTable` {@link RowData}*/ export type LGRowData = RowData; @@ -51,13 +44,10 @@ export type LeafyGreenTableOptions< T extends LGRowData, V extends unknown = unknown, > = Omit>, 'getCoreRowModel' | 'columns'> & { - // containerRef: RefObject; hasSelectableRows?: boolean; columns: Array>; withPagination?: boolean; allowSelectAll?: boolean; - // useVirtualScrolling?: boolean; - // virtualizerOptions?: Partial>; }; /** From 3e77d51a1a34259345a4d1d65a3a9bc2fd5d3919 Mon Sep 17 00:00:00 2001 From: Shaneeza Date: Wed, 16 Oct 2024 15:56:15 -0400 Subject: [PATCH 026/113] row types --- packages/table/src/Row/InternalRowWithRT.tsx | 12 ++---------- packages/table/src/Row/Row.types.ts | 11 +++++++++-- 2 files changed, 11 insertions(+), 12 deletions(-) diff --git a/packages/table/src/Row/InternalRowWithRT.tsx b/packages/table/src/Row/InternalRowWithRT.tsx index 5189605b16..22502922b7 100644 --- a/packages/table/src/Row/InternalRowWithRT.tsx +++ b/packages/table/src/Row/InternalRowWithRT.tsx @@ -1,4 +1,3 @@ -// @ts-nocheck import React, { useMemo } from 'react'; import isEqual from 'react-fast-compare'; @@ -44,6 +43,7 @@ const InternalRowWithRT = ({ const depth = row.depth; + // eslint-disable-next-line no-console console.log(`🪼rerender🪼 row: ${row.id}, depth: ${depth}`, { isExpanded: isExpanded, }); @@ -58,15 +58,6 @@ const InternalRowWithRT = ({ !virtualRow && shouldAlternateRowColor && !isSelected, [selectedRowStyles[theme]]: isSelected && !disabled, [expandedContentParentStyles[theme]]: isExpanded || isParentExpanded, - // [css` - // /* display: none; */ - - // > td div { - // height: 0; - // overflow: hidden; - // min-height: 0; - // } - // `]: row.depth !== 0 && isParentExpanded === false, }, className, )} @@ -87,6 +78,7 @@ const InternalRowWithRT = ({ export default InternalRowWithRT; +// @ts-expect-error FIXME: the types are generic const arePropsEqual = (prevProps, nextProps) => { // Children will never be the same const { children: prevChildren, ...restPrevProps } = prevProps; diff --git a/packages/table/src/Row/Row.types.ts b/packages/table/src/Row/Row.types.ts index 7f02fb1178..26f03ee010 100644 --- a/packages/table/src/Row/Row.types.ts +++ b/packages/table/src/Row/Row.types.ts @@ -1,6 +1,6 @@ -import { VirtualItem } from '@tanstack/react-virtual'; +import { VirtualItem, Virtualizer } from '@tanstack/react-virtual'; -import { HTMLElementProps } from '@leafygreen-ui/lib'; +import { HTMLElementProps, Theme } from '@leafygreen-ui/lib'; import { LeafyGreenTableRow, LGRowData } from '../useLeafyGreenTable'; @@ -23,6 +23,13 @@ export interface InternalRowWithRTProps * Virtual row object passed from the `useLeafyGreenTable` hook */ virtualRow?: VirtualItem; + + shouldAlternateRowColor: boolean; + theme: Theme; + measureElement: Virtualizer['measureElement']; + isExpanded: boolean; + isParentExpanded: boolean; + isSelected: boolean; } export type RowProps = InternalRowWithoutRTProps & From 3046147bcf68f01ade1637a42d55468e5047f61b Mon Sep 17 00:00:00 2001 From: Shaneeza Date: Wed, 16 Oct 2024 16:12:00 -0400 Subject: [PATCH 027/113] types --- packages/table/src/Row/Row.types.ts | 2 +- packages/table/src/TableContext/TableContext.tsx | 1 - 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/packages/table/src/Row/Row.types.ts b/packages/table/src/Row/Row.types.ts index 26f03ee010..e189946068 100644 --- a/packages/table/src/Row/Row.types.ts +++ b/packages/table/src/Row/Row.types.ts @@ -26,7 +26,7 @@ export interface InternalRowWithRTProps shouldAlternateRowColor: boolean; theme: Theme; - measureElement: Virtualizer['measureElement']; + measureElement?: Virtualizer['measureElement']; isExpanded: boolean; isParentExpanded: boolean; isSelected: boolean; diff --git a/packages/table/src/TableContext/TableContext.tsx b/packages/table/src/TableContext/TableContext.tsx index 3378e398f6..746392fa7c 100644 --- a/packages/table/src/TableContext/TableContext.tsx +++ b/packages/table/src/TableContext/TableContext.tsx @@ -20,7 +20,6 @@ export const useTableContext = () => TableContext as React.Context>, ); -//TODO: a seperate context for virtual scrolling? const TableContextProvider = ({ children, darkMode, From 1486a8fc58f5afa244ab46bdcaa7fbb9d369e22d Mon Sep 17 00:00:00 2001 From: Shaneeza Date: Wed, 16 Oct 2024 18:05:49 -0400 Subject: [PATCH 028/113] should truncate support --- packages/table/src/Cell/Cell.styles.ts | 55 ++++++++++++------- packages/table/src/Cell/Cell.tsx | 11 ++-- packages/table/src/Cell/Cell.types.ts | 24 -------- .../table/src/Cell/HeaderCell/HeaderCell.tsx | 8 +-- packages/table/src/Cell/InternalCell.tsx | 36 ++++-------- .../ExpandedContent/ExpandedContent.styles.ts | 1 - .../src/ExpandedContent/ExpandedContent.tsx | 20 ++----- packages/table/src/Row/Row.tsx | 4 +- packages/table/src/Table.stories.tsx | 41 -------------- packages/table/src/Table/Table.tsx | 2 + packages/table/src/Table/Table.types.ts | 6 +- .../table/src/TableContext/TableContext.tsx | 3 + .../src/TableContext/TableContext.types.ts | 2 +- 13 files changed, 76 insertions(+), 137 deletions(-) diff --git a/packages/table/src/Cell/Cell.styles.ts b/packages/table/src/Cell/Cell.styles.ts index ee62a3770f..b34f110c28 100644 --- a/packages/table/src/Cell/Cell.styles.ts +++ b/packages/table/src/Cell/Cell.styles.ts @@ -12,19 +12,6 @@ const iconSize = 28; /** the default height of a cell */ export const standardCellHeight = spacing[5] + spacing[2]; -export const baseCellStyles = css` - padding: 0 8px; - overflow: hidden; - - &:focus-visible { - box-shadow: inset; - } - - &:last-child { - padding-right: ${baseTableSidePadding}px; - } -`; - export const alignmentStyles = (align: Align = 'left') => css` justify-content: ${align}; text-align: ${align}; @@ -72,13 +59,16 @@ export const basicCellStyles = css` } `; -//TODO: update this when working on multi line content -export const cellTransitionContainerStyles = css` +export const cellContainerStyles = (shouldTruncate = true) => css` display: flex; align-items: center; min-height: ${standardCellHeight}px; overflow: hidden; - max-height: ${standardCellHeight}px; + + ${shouldTruncate && + css` + max-height: ${standardCellHeight}px; + `} `; export const truncatedContentStyles = css` @@ -89,7 +79,34 @@ export const truncatedContentStyles = css` -webkit-box-align: start; `; -export const disableAnimationStyles = css` - transition-duration: 0; - transition: none; +export const getBaseStyles = (size = 0, shouldTruncate = true) => css` + padding: 0 8px; + overflow: hidden; + + &:focus-visible { + box-shadow: inset; + } + + &:last-child { + padding-right: ${baseTableSidePadding}px; + } + + ${shouldTruncate && + css` + width: ${size}px; + `} +`; + +export const getCellInnerStyles = () => css` + width: inherit; +`; + +export const getCellEllipsisStyles = (shouldTruncate: boolean) => css` + ${shouldTruncate && + css` + flex: 1; /* Allow the element to grow */ + overflow: hidden; + white-space: nowrap; + text-overflow: ellipsis; + `} `; diff --git a/packages/table/src/Cell/Cell.tsx b/packages/table/src/Cell/Cell.tsx index 89eb214137..d29a3d9a3c 100644 --- a/packages/table/src/Cell/Cell.tsx +++ b/packages/table/src/Cell/Cell.tsx @@ -4,12 +4,13 @@ import { cx } from '@leafygreen-ui/emotion'; import { LGIDS } from '../constants'; import { useRowContext } from '../Row/RowContext'; +import { useTableContext } from '../TableContext'; import { alignmentStyles, - baseCellStyles, basicCellStyles, - cellTransitionContainerStyles, + cellContainerStyles, + getBaseStyles, } from './Cell.styles'; import InternalCell from './InternalCell'; import { CellProps } from '.'; @@ -23,17 +24,19 @@ const Cell = ({ ...rest }: CellProps) => { const { isReactTable } = useRowContext(); + const { shouldTruncate } = useTableContext(); + return ( <> {!isReactTable && (
; -export const CellOverflowBehavior = { - Default: 'default', - Truncate: 'truncate', - // TODO: `Expand`: The cell will expand to the height of its content - // Expand: 'expand', -} as const; -export type CellOverflowBehavior = - (typeof CellOverflowBehavior)[keyof typeof CellOverflowBehavior]; - interface BaseCellProps extends HTMLElementProps<'td'> { /** * Alignment of the cell's contents @@ -25,21 +16,6 @@ interface BaseCellProps extends HTMLElementProps<'td'> { /** A `className` applied to the inner `div` of the Cell */ contentClassName?: string; - /** - * Defines how a cell should behave when its content is larger than the standard cell height. - * - * `Default`: The cell height will be fixed to the standard cell height (40px by default). - * Any overflowing content will be clipped. - * - * `Truncate`: The cell height will be fixed to the standard cell height (40px by default), - * and include an ellipsis before the content is clipped. - * - * Note: It's recommended to provide the same value for all cells in a given row. - * - * @default CellOverflowBehavior.Default - */ - overflow?: CellOverflowBehavior; - cell?: any; //FIXME: } diff --git a/packages/table/src/Cell/HeaderCell/HeaderCell.tsx b/packages/table/src/Cell/HeaderCell/HeaderCell.tsx index 8545adc9c2..8a696e43a3 100644 --- a/packages/table/src/Cell/HeaderCell/HeaderCell.tsx +++ b/packages/table/src/Cell/HeaderCell/HeaderCell.tsx @@ -7,8 +7,8 @@ import { useTableContext } from '../../TableContext'; import { LGRowData } from '../../useLeafyGreenTable'; import { alignmentStyles, - baseCellStyles, - cellTransitionContainerStyles, + cellContainerStyles, + getBaseStyles, } from '../Cell.styles'; import SortIcon from './SortIcon/SortIcon'; @@ -50,7 +50,7 @@ const HeaderCell = ({
({ >
{ const { disabled } = useRowContext(); // TODO: log warning if cell is not passed to Cell - const { isSelectable } = useTableContext(); + const { isSelectable, shouldTruncate = true } = useTableContext(); const isFirstCell = (cell && cell.column.getIsFirstColumn()) || false; const row = cell.row; const isExpandable = row.getCanExpand(); @@ -36,16 +35,7 @@ const InternalCell = ({ const depth = row.depth; const toggleExpanded = () => row.toggleExpanded(); const contentRef = useRef(null); - - const contentHeight = standardCellHeight; - const scrollHeight = contentRef.current - ? contentRef.current?.scrollHeight - : 0; - const shouldTruncate = useMemo(() => { - return ( - overflow === CellOverflowBehavior.Truncate && scrollHeight > contentHeight - ); - }, [contentHeight, overflow, scrollHeight]); + const cellSize = cell.column.getSize(); // TODO: memoize me @@ -53,7 +43,7 @@ const InternalCell = ({
@@ -79,7 +67,7 @@ const InternalCell = ({ disabled={disabled} /> )} - {children} +
{children}
- - - {columns.map((columnName: string) => ( - {columnName} - ))} - - - - {data.map((row: AnyDict) => ( - - {Object.keys(row).map((cellKey: string, index: number) => { - return ( - -
- {row[cellKey]} -
-
- ); - })} -
- ))} -
-
- ); -}; - export const NestedRows: StoryFn = args => { const tableContainerRef = React.useRef(null); const [data] = React.useState(() => makeData(false, 500, 5, 3)); diff --git a/packages/table/src/Table/Table.tsx b/packages/table/src/Table/Table.tsx index 6ed28d36af..ae20e8a7c8 100644 --- a/packages/table/src/Table/Table.tsx +++ b/packages/table/src/Table/Table.tsx @@ -30,6 +30,7 @@ const Table = forwardRef>( children, className, shouldAlternateRowColor = false, + shouldTruncate = true, baseFontSize: baseFontSizeProp, darkMode: darkModeProp, table, @@ -74,6 +75,7 @@ const Table = forwardRef>( isVirtual={isVirtual} isSelectable={isSelectable} measureElement={measureElement} + shouldTruncate={shouldTruncate} > table?: LeafyGreenTable | LeafyGreenVirtualTable; //TODO: is there a better way to type this? /** - * Disables all transition animations for smoother rendering of tall content where appropriate - * @default false + * Whether all rows will truncate. If true then the cell will truncate at one line. If false then there will be no height limit and cells will not truncate. + * @default true */ - disableAnimations?: boolean; + shouldTruncate?: boolean; } diff --git a/packages/table/src/TableContext/TableContext.tsx b/packages/table/src/TableContext/TableContext.tsx index 746392fa7c..f47f81607a 100644 --- a/packages/table/src/TableContext/TableContext.tsx +++ b/packages/table/src/TableContext/TableContext.tsx @@ -27,6 +27,7 @@ const TableContextProvider = ({ isVirtual, isSelectable, measureElement, + shouldTruncate, }: PropsWithChildren>>) => { /** The appropriately typed context provider */ const TableProvider = (TableContext as React.Context>) @@ -39,6 +40,7 @@ const TableContextProvider = ({ isVirtual, isSelectable, measureElement, + shouldTruncate, }; }, [ shouldAlternateRowColor, @@ -46,6 +48,7 @@ const TableContextProvider = ({ isVirtual, isSelectable, measureElement, + shouldTruncate, ]); return ( diff --git a/packages/table/src/TableContext/TableContext.types.ts b/packages/table/src/TableContext/TableContext.types.ts index 377c5421bd..8e9724bf5c 100644 --- a/packages/table/src/TableContext/TableContext.types.ts +++ b/packages/table/src/TableContext/TableContext.types.ts @@ -11,7 +11,7 @@ import { } from '../useLeafyGreenTable'; export type TableContextValues = PropsWithChildren< - Pick, 'table' | 'shouldAlternateRowColor' | 'disableAnimations'> + Pick, 'shouldAlternateRowColor' | 'shouldTruncate'> > & DarkModeProps & { /** returns the table row object with the provided `id` */ From 187cfe2e68c114714c1503115a7254f5742a4841 Mon Sep 17 00:00:00 2001 From: Shaneeza Date: Thu, 17 Oct 2024 11:08:15 -0400 Subject: [PATCH 029/113] remove memo from useLeafyGreenVirtualTable --- .../src/ExpandedContent/ExpandedContent.tsx | 3 +++ .../ExpandedContent/ExpandedContent.types.ts | 5 +++++ packages/table/src/Row/InternalRowWithRT.tsx | 6 +----- .../table/src/Table/TableWithVS.stories.tsx | 18 +++++------------- .../useLeafyGreenVirtualTable.tsx | 12 +++++++----- 5 files changed, 21 insertions(+), 23 deletions(-) diff --git a/packages/table/src/ExpandedContent/ExpandedContent.tsx b/packages/table/src/ExpandedContent/ExpandedContent.tsx index 66ba55f9c5..29ee158ca0 100644 --- a/packages/table/src/ExpandedContent/ExpandedContent.tsx +++ b/packages/table/src/ExpandedContent/ExpandedContent.tsx @@ -14,6 +14,7 @@ import { ExpandedContentProps } from './ExpandedContent.types'; const ExpandedContent = ({ row, + virtualRow, ...rest }: ExpandedContentProps) => { const { measureElement } = useTableContext(); @@ -32,6 +33,7 @@ const ExpandedContent = ({ // [content], // ); + // eslint-disable-next-line no-console console.log(`🍉rerender🍉 ExpandedContent: ${row.id}`); return ( @@ -42,6 +44,7 @@ const ExpandedContent = ({ // This gets the dynamic size of the element if (measureElement) measureElement(node); }} + data-index={virtualRow ? virtualRow!.index : ''} > ); From 9dd750d4cb2e68420d4c8220fb3cbc7dfc834afe Mon Sep 17 00:00:00 2001 From: Shaneeza Date: Thu, 17 Oct 2024 17:59:25 -0400 Subject: [PATCH 033/113] dynamic ellipsis --- packages/table/src/Cell/Cell.styles.ts | 34 ++++-------- packages/table/src/Cell/Cell.tsx | 52 +++++-------------- packages/table/src/Cell/InternalCell.tsx | 24 +++------ .../table/src/Cell/InternalCellWithoutRT.tsx | 48 +++++++++++++++++ packages/table/src/Table.stories.tsx | 7 +-- 5 files changed, 77 insertions(+), 88 deletions(-) create mode 100644 packages/table/src/Cell/InternalCellWithoutRT.tsx diff --git a/packages/table/src/Cell/Cell.styles.ts b/packages/table/src/Cell/Cell.styles.ts index 4b6d85ecab..75fc3b1b9c 100644 --- a/packages/table/src/Cell/Cell.styles.ts +++ b/packages/table/src/Cell/Cell.styles.ts @@ -1,5 +1,5 @@ import { css } from '@leafygreen-ui/emotion'; -import { spacing, typeScales } from '@leafygreen-ui/tokens'; +import { spacing } from '@leafygreen-ui/tokens'; import { Align } from './Cell.types'; @@ -59,27 +59,13 @@ export const basicCellStyles = css` } `; -export const cellContainerStyles = (shouldTruncate = true) => css` +export const cellContainerStyles = () => css` display: flex; align-items: center; min-height: ${standardCellHeight}px; overflow: hidden; - - ${shouldTruncate && - css` - max-height: ${standardCellHeight}px; - `} `; - -export const truncatedContentStyles = css` - /* See https://css-tricks.com/line-clampin/#aa-the-standardized-way */ - display: -webkit-box; - -webkit-line-clamp: ${standardCellHeight / typeScales.body1.lineHeight}; - -webkit-box-orient: vertical; - -webkit-box-align: start; -`; - -export const getBaseStyles = (size = 0, shouldTruncate = true) => css` +export const getBaseStyles = () => css` padding: 0 8px; overflow: hidden; vertical-align: top; @@ -91,23 +77,21 @@ export const getBaseStyles = (size = 0, shouldTruncate = true) => css` &:last-child { padding-right: ${baseTableSidePadding}px; } - - ${shouldTruncate && - css` - width: ${size}px; - `} `; -export const getCellInnerStyles = () => css` - width: inherit; +export const cellInnerStyles = () => css` + display: flex; + align-items: center; + min-width: 100%; `; export const getCellEllipsisStyles = (shouldTruncate: boolean) => css` ${shouldTruncate && css` - flex: 1; /* Allow the element to grow */ + flex: 1; overflow: hidden; white-space: nowrap; text-overflow: ellipsis; + contain: inline-size; // 🤯 `} `; diff --git a/packages/table/src/Cell/Cell.tsx b/packages/table/src/Cell/Cell.tsx index d29a3d9a3c..8a7b7a0d44 100644 --- a/packages/table/src/Cell/Cell.tsx +++ b/packages/table/src/Cell/Cell.tsx @@ -1,58 +1,30 @@ import React from 'react'; -import { cx } from '@leafygreen-ui/emotion'; - -import { LGIDS } from '../constants'; import { useRowContext } from '../Row/RowContext'; -import { useTableContext } from '../TableContext'; -import { - alignmentStyles, - basicCellStyles, - cellContainerStyles, - getBaseStyles, -} from './Cell.styles'; import InternalCell from './InternalCell'; +import InternalCellWithoutRT from './InternalCellWithoutRT'; import { CellProps } from '.'; -const Cell = ({ - className, - contentClassName, - align, - children, - cell, - ...rest -}: CellProps) => { +const Cell = ({ align, children, cell, ...rest }: CellProps) => { const { isReactTable } = useRowContext(); - const { shouldTruncate } = useTableContext(); + + // const isFirstCell = (cell && cell.column.getIsFirstColumn()) || false; + // const row = cell && cell.row; + // const isExpandable = cell && row ? row.getCanExpand() : false; + // const isExpanded = cell && row ? row.getIsExpanded() : false; + // const depth = cell && row ? row.depth : 0; + // const toggleExpanded = () => (row ? row.toggleExpanded() : {}); + // const cellSize = cell ? cell.column.getSize() : 0; return ( <> {!isReactTable && ( - + {children} )} {isReactTable && ( - + {children} )} diff --git a/packages/table/src/Cell/InternalCell.tsx b/packages/table/src/Cell/InternalCell.tsx index 568dd70375..ba066c761d 100644 --- a/packages/table/src/Cell/InternalCell.tsx +++ b/packages/table/src/Cell/InternalCell.tsx @@ -1,6 +1,6 @@ -import React, { useRef } from 'react'; +import React from 'react'; -import { css, cx } from '@leafygreen-ui/emotion'; +import { cx } from '@leafygreen-ui/emotion'; import { LGIDS } from '../constants'; import { useRowContext } from '../Row/RowContext'; @@ -10,9 +10,9 @@ import ToggleExpandedIcon from '../ToggleExpandedIcon'; import { alignmentStyles, cellContainerStyles, + cellInnerStyles, getBaseStyles, getCellEllipsisStyles, - getCellInnerStyles, getCellPadding, } from './Cell.styles'; import { InternalCellProps } from './Cell.types'; @@ -34,14 +34,12 @@ const InternalCell = ({ const isExpanded = row.getIsExpanded(); const depth = row.depth; const toggleExpanded = () => row.toggleExpanded(); - const contentRef = useRef(null); - const cellSize = cell.column.getSize(); return ( + ); +}; + +InternalCellWithoutRT.displayName = 'InternalCellWithoutRT'; + +export default InternalCellWithoutRT; diff --git a/packages/table/src/Table.stories.tsx b/packages/table/src/Table.stories.tsx index 19b1936cc5..6abed98630 100644 --- a/packages/table/src/Table.stories.tsx +++ b/packages/table/src/Table.stories.tsx @@ -1102,12 +1102,7 @@ export const StyledComponents: StoryFn = args => { {row.getVisibleCells().map(cell => { return ( - + {flexRender( cell.column.columnDef.cell, cell.getContext(), From da227e3273a674793a1428404ed559010c006333 Mon Sep 17 00:00:00 2001 From: Shaneeza Date: Thu, 17 Oct 2024 18:00:15 -0400 Subject: [PATCH 034/113] comment --- packages/table/src/Cell/Cell.tsx | 2 ++ 1 file changed, 2 insertions(+) diff --git a/packages/table/src/Cell/Cell.tsx b/packages/table/src/Cell/Cell.tsx index 8a7b7a0d44..364769e6d5 100644 --- a/packages/table/src/Cell/Cell.tsx +++ b/packages/table/src/Cell/Cell.tsx @@ -17,6 +17,8 @@ const Cell = ({ align, children, cell, ...rest }: CellProps) => { // const toggleExpanded = () => (row ? row.toggleExpanded() : {}); // const cellSize = cell ? cell.column.getSize() : 0; + // TODO: can i combine these two? + return ( <> {!isReactTable && ( From 205ff31128d18efb0cf7e2ca8e7d5eae802c3fb3 Mon Sep 17 00:00:00 2001 From: Shaneeza Date: Fri, 18 Oct 2024 12:17:11 -0400 Subject: [PATCH 035/113] combined components --- packages/table/src/Cell/Cell.styles.ts | 13 +++-- packages/table/src/Cell/Cell.tsx | 18 ++----- packages/table/src/Cell/Cell.types.ts | 26 +-------- packages/table/src/Cell/InternalCell.tsx | 36 +------------ .../table/src/Cell/InternalCellWithRT.tsx | 53 +++++++++++++++++++ .../table/src/Cell/InternalCellWithoutRT.tsx | 37 +++---------- packages/table/src/Table.stories.tsx | 4 -- 7 files changed, 76 insertions(+), 111 deletions(-) create mode 100644 packages/table/src/Cell/InternalCellWithRT.tsx diff --git a/packages/table/src/Cell/Cell.styles.ts b/packages/table/src/Cell/Cell.styles.ts index 75fc3b1b9c..492b26123e 100644 --- a/packages/table/src/Cell/Cell.styles.ts +++ b/packages/table/src/Cell/Cell.styles.ts @@ -49,12 +49,16 @@ export const getCellPadding = ({ `; }; -export const basicCellStyles = css` +export const basicCellStyles = ( + depth = 0, + isExpandable = false, + isSelectable = false, +) => css` &:first-child { ${getCellPadding({ - depth: 0, - isExpandable: false, - isSelectable: false, + depth, + isExpandable, + isSelectable, })} } `; @@ -65,6 +69,7 @@ export const cellContainerStyles = () => css` min-height: ${standardCellHeight}px; overflow: hidden; `; + export const getBaseStyles = () => css` padding: 0 8px; overflow: hidden; diff --git a/packages/table/src/Cell/Cell.tsx b/packages/table/src/Cell/Cell.tsx index 364769e6d5..add29e5aab 100644 --- a/packages/table/src/Cell/Cell.tsx +++ b/packages/table/src/Cell/Cell.tsx @@ -2,23 +2,13 @@ import React from 'react'; import { useRowContext } from '../Row/RowContext'; -import InternalCell from './InternalCell'; import InternalCellWithoutRT from './InternalCellWithoutRT'; +import InternalCellWithRT from './InternalCellWithRT'; import { CellProps } from '.'; -const Cell = ({ align, children, cell, ...rest }: CellProps) => { +const Cell = ({ children, cell, ...rest }: CellProps) => { const { isReactTable } = useRowContext(); - // const isFirstCell = (cell && cell.column.getIsFirstColumn()) || false; - // const row = cell && cell.row; - // const isExpandable = cell && row ? row.getCanExpand() : false; - // const isExpanded = cell && row ? row.getIsExpanded() : false; - // const depth = cell && row ? row.depth : 0; - // const toggleExpanded = () => (row ? row.toggleExpanded() : {}); - // const cellSize = cell ? cell.column.getSize() : 0; - - // TODO: can i combine these two? - return ( <> {!isReactTable && ( @@ -26,9 +16,9 @@ const Cell = ({ align, children, cell, ...rest }: CellProps) => { )} {isReactTable && ( - + {children} - + )} ); diff --git a/packages/table/src/Cell/Cell.types.ts b/packages/table/src/Cell/Cell.types.ts index d50c583b07..742175324a 100644 --- a/packages/table/src/Cell/Cell.types.ts +++ b/packages/table/src/Cell/Cell.types.ts @@ -24,28 +24,6 @@ export type CellProps = BaseCellProps; export type InternalCellRequiredProps = Omit & Required>; -export interface InternalCellProps extends InternalCellRequiredProps { - /** - * Index of the cell in its parent row. - */ - cellIndex?: number; +export interface InternalCellProps extends BaseCellProps {} - /** - * Depth of nesting its parent row has. - */ - depth?: number; - - /** - * Defines whether the cell's row is visible (i.e. expanded) - * - * @default true - */ - isVisible?: boolean; - - /** - * Defines whether the cell's row is expandable - * - * @default false - */ - isExpandable?: boolean; -} +export interface InternalCellWithRTProps extends InternalCellRequiredProps {} diff --git a/packages/table/src/Cell/InternalCell.tsx b/packages/table/src/Cell/InternalCell.tsx index ba066c761d..a510c71292 100644 --- a/packages/table/src/Cell/InternalCell.tsx +++ b/packages/table/src/Cell/InternalCell.tsx @@ -3,17 +3,12 @@ import React from 'react'; import { cx } from '@leafygreen-ui/emotion'; import { LGIDS } from '../constants'; -import { useRowContext } from '../Row/RowContext'; -import { useTableContext } from '../TableContext'; -import ToggleExpandedIcon from '../ToggleExpandedIcon'; import { alignmentStyles, cellContainerStyles, cellInnerStyles, getBaseStyles, - getCellEllipsisStyles, - getCellPadding, } from './Cell.styles'; import { InternalCellProps } from './Cell.types'; @@ -25,26 +20,10 @@ const InternalCell = ({ cell, ...rest }: InternalCellProps) => { - const { disabled } = useRowContext(); - // TODO: log warning if cell is not passed to Cell - const { isSelectable, shouldTruncate = true } = useTableContext(); - const isFirstCell = (cell && cell.column.getIsFirstColumn()) || false; - const row = cell.row; - const isExpandable = row.getCanExpand(); - const isExpanded = row.getIsExpanded(); - const depth = row.depth; - const toggleExpanded = () => row.toggleExpanded(); - return ( ); diff --git a/packages/table/src/Cell/InternalCellWithRT.tsx b/packages/table/src/Cell/InternalCellWithRT.tsx new file mode 100644 index 0000000000..246feb6fad --- /dev/null +++ b/packages/table/src/Cell/InternalCellWithRT.tsx @@ -0,0 +1,53 @@ +import React from 'react'; + +import { cx } from '@leafygreen-ui/emotion'; + +import { useRowContext } from '../Row/RowContext'; +import { useTableContext } from '../TableContext'; +import ToggleExpandedIcon from '../ToggleExpandedIcon'; + +import { basicCellStyles, getCellEllipsisStyles } from './Cell.styles'; +import { InternalCellWithRTProps } from './Cell.types'; +import InternalCell from './InternalCell'; + +const InternalCellWithRT = ({ + children, + className, + contentClassName, + align, + cell, + ...rest +}: InternalCellWithRTProps) => { + const { disabled } = useRowContext(); + // TODO: log warning if cell is not passed to Cell + const { isSelectable, shouldTruncate = true } = useTableContext(); + const isFirstCell = (cell && cell.column.getIsFirstColumn()) || false; + const row = cell.row; + const isExpandable = row.getCanExpand(); + const isExpanded = row.getIsExpanded(); + const depth = row.depth; + const toggleExpanded = () => row.toggleExpanded(); + + return ( + + {isFirstCell && isExpandable && ( + + )} +
{children}
+
+ ); +}; + +InternalCellWithRT.displayName = 'InternalCellWithRT'; + +export default InternalCellWithRT; diff --git a/packages/table/src/Cell/InternalCellWithoutRT.tsx b/packages/table/src/Cell/InternalCellWithoutRT.tsx index 1cf1d44ff1..cebc9fcd6f 100644 --- a/packages/table/src/Cell/InternalCellWithoutRT.tsx +++ b/packages/table/src/Cell/InternalCellWithoutRT.tsx @@ -2,44 +2,19 @@ import React from 'react'; import { cx } from '@leafygreen-ui/emotion'; -import { LGIDS } from '../constants'; import { useTableContext } from '../TableContext'; -import { - alignmentStyles, - basicCellStyles, - cellContainerStyles, - getBaseStyles, - getCellEllipsisStyles, -} from './Cell.styles'; +import { basicCellStyles, getCellEllipsisStyles } from './Cell.styles'; +import InternalCell from './InternalCell'; import { CellProps } from '.'; -const InternalCellWithoutRT = ({ - className, - contentClassName, - align, - children, - cell, - ...rest -}: CellProps) => { +const InternalCellWithoutRT = ({ children, className, ...rest }: CellProps) => { const { shouldTruncate = true } = useTableContext(); return ( - + +
{children}
+
); }; diff --git a/packages/table/src/Table.stories.tsx b/packages/table/src/Table.stories.tsx index 6abed98630..d8747a0c32 100644 --- a/packages/table/src/Table.stories.tsx +++ b/packages/table/src/Table.stories.tsx @@ -196,12 +196,8 @@ export const LiveExample: StoryFn = args => { {rows.map((row: LeafyGreenTableRow) => { - // const isExpandedContent = row.original.isExpandedContent ?? false; - - // TODO: the diff in this approach is that the keys are not chaning when a sub row opens return ( - {/* {!isExpandedContent && ( */} {row.getVisibleCells().map(cell => { return ( From 23fdeccfc381e266bba8b3d02a53cc0cf0b32574 Mon Sep 17 00:00:00 2001 From: Shaneeza Date: Fri, 18 Oct 2024 14:46:59 -0400 Subject: [PATCH 036/113] cell generic type --- packages/table/src/Cell/Cell.styles.ts | 11 +++----- packages/table/src/Cell/Cell.tsx | 7 +++++- packages/table/src/Cell/Cell.types.ts | 25 +++++++++++++------ .../table/src/Cell/HeaderCell/HeaderCell.tsx | 11 +++----- packages/table/src/Cell/InternalCell.tsx | 12 ++------- .../table/src/Cell/InternalCellWithRT.tsx | 9 ++++--- .../table/src/Cell/InternalCellWithoutRT.tsx | 4 +-- .../src/ExpandedContent/ExpandedContent.tsx | 4 +-- packages/table/src/Row/InternalRowWithRT.tsx | 2 +- packages/table/src/Row/Row.stories.tsx | 4 +-- 10 files changed, 45 insertions(+), 44 deletions(-) diff --git a/packages/table/src/Cell/Cell.styles.ts b/packages/table/src/Cell/Cell.styles.ts index 492b26123e..6454fba9d8 100644 --- a/packages/table/src/Cell/Cell.styles.ts +++ b/packages/table/src/Cell/Cell.styles.ts @@ -12,11 +12,6 @@ const iconSize = 28; /** the default height of a cell */ export const standardCellHeight = spacing[5] + spacing[2]; -export const alignmentStyles = (align: Align = 'left') => css` - justify-content: ${align}; - text-align: ${align}; -`; - export const getCellPadding = ({ depth = 0, isExpandable, @@ -49,7 +44,7 @@ export const getCellPadding = ({ `; }; -export const basicCellStyles = ( +export const getCellStyles = ( depth = 0, isExpandable = false, isSelectable = false, @@ -63,11 +58,13 @@ export const basicCellStyles = ( } `; -export const cellContainerStyles = () => css` +export const getCellContainerStyles = (align: Align = 'left') => css` display: flex; align-items: center; min-height: ${standardCellHeight}px; overflow: hidden; + justify-content: ${align}; + text-align: ${align}; `; export const getBaseStyles = () => css` diff --git a/packages/table/src/Cell/Cell.tsx b/packages/table/src/Cell/Cell.tsx index add29e5aab..b70e7e7e37 100644 --- a/packages/table/src/Cell/Cell.tsx +++ b/packages/table/src/Cell/Cell.tsx @@ -1,12 +1,17 @@ import React from 'react'; import { useRowContext } from '../Row/RowContext'; +import { LGRowData } from '../useLeafyGreenTable'; import InternalCellWithoutRT from './InternalCellWithoutRT'; import InternalCellWithRT from './InternalCellWithRT'; import { CellProps } from '.'; -const Cell = ({ children, cell, ...rest }: CellProps) => { +const Cell = ({ + children, + cell, + ...rest +}: CellProps) => { const { isReactTable } = useRowContext(); return ( diff --git a/packages/table/src/Cell/Cell.types.ts b/packages/table/src/Cell/Cell.types.ts index 742175324a..f9743bbdd5 100644 --- a/packages/table/src/Cell/Cell.types.ts +++ b/packages/table/src/Cell/Cell.types.ts @@ -1,5 +1,7 @@ import { HTMLElementProps } from '@leafygreen-ui/lib'; +import { LeafyGreenTableCell, LGRowData } from '../useLeafyGreenTable'; + export type Align = Extract< HTMLElementProps<'td'>['align'], 'left' | 'right' | 'center' @@ -13,17 +15,26 @@ interface BaseCellProps extends HTMLElementProps<'td'> { */ align?: Align; - /** A `className` applied to the inner `div` of the Cell */ + /** + * A `className` applied to the inner `div` of the Cell + */ contentClassName?: string; - - cell?: any; //FIXME: } -export type CellProps = BaseCellProps; +interface CellProps extends BaseCellProps { + /** + * TODO: + */ + cell?: LeafyGreenTableCell; +} -export type InternalCellRequiredProps = Omit & - Required>; +export type InternalCellWithRTRequiredProps = Omit< + CellProps, + 'cell' +> & + Required, 'cell'>>; export interface InternalCellProps extends BaseCellProps {} -export interface InternalCellWithRTProps extends InternalCellRequiredProps {} +export interface InternalCellWithRTProps + extends InternalCellWithRTRequiredProps {} diff --git a/packages/table/src/Cell/HeaderCell/HeaderCell.tsx b/packages/table/src/Cell/HeaderCell/HeaderCell.tsx index 8a696e43a3..2f105b2f31 100644 --- a/packages/table/src/Cell/HeaderCell/HeaderCell.tsx +++ b/packages/table/src/Cell/HeaderCell/HeaderCell.tsx @@ -5,11 +5,7 @@ import { cx } from '@leafygreen-ui/emotion'; import { LGIDS } from '../../constants'; import { useTableContext } from '../../TableContext'; import { LGRowData } from '../../useLeafyGreenTable'; -import { - alignmentStyles, - cellContainerStyles, - getBaseStyles, -} from '../Cell.styles'; +import { getBaseStyles, getCellContainerStyles } from '../Cell.styles'; import SortIcon from './SortIcon/SortIcon'; import { @@ -63,11 +59,10 @@ const HeaderCell = ({ >
{children} diff --git a/packages/table/src/Cell/InternalCell.tsx b/packages/table/src/Cell/InternalCell.tsx index a510c71292..4ae5629dac 100644 --- a/packages/table/src/Cell/InternalCell.tsx +++ b/packages/table/src/Cell/InternalCell.tsx @@ -5,10 +5,9 @@ import { cx } from '@leafygreen-ui/emotion'; import { LGIDS } from '../constants'; import { - alignmentStyles, - cellContainerStyles, cellInnerStyles, getBaseStyles, + getCellContainerStyles, } from './Cell.styles'; import { InternalCellProps } from './Cell.types'; @@ -17,7 +16,6 @@ const InternalCell = ({ className, contentClassName, align, - cell, ...rest }: InternalCellProps) => { return ( @@ -26,13 +24,7 @@ const InternalCell = ({ className={cx(getBaseStyles(), className)} {...rest} > -
+
{children}
diff --git a/packages/table/src/Cell/InternalCellWithRT.tsx b/packages/table/src/Cell/InternalCellWithRT.tsx index 246feb6fad..045840e84c 100644 --- a/packages/table/src/Cell/InternalCellWithRT.tsx +++ b/packages/table/src/Cell/InternalCellWithRT.tsx @@ -5,19 +5,20 @@ import { cx } from '@leafygreen-ui/emotion'; import { useRowContext } from '../Row/RowContext'; import { useTableContext } from '../TableContext'; import ToggleExpandedIcon from '../ToggleExpandedIcon'; +import { LGRowData } from '../useLeafyGreenTable'; -import { basicCellStyles, getCellEllipsisStyles } from './Cell.styles'; +import { getCellEllipsisStyles, getCellStyles } from './Cell.styles'; import { InternalCellWithRTProps } from './Cell.types'; import InternalCell from './InternalCell'; -const InternalCellWithRT = ({ +const InternalCellWithRT = ({ children, className, contentClassName, align, cell, ...rest -}: InternalCellWithRTProps) => { +}: InternalCellWithRTProps) => { const { disabled } = useRowContext(); // TODO: log warning if cell is not passed to Cell const { isSelectable, shouldTruncate = true } = useTableContext(); @@ -31,7 +32,7 @@ const InternalCellWithRT = ({ return ( { const { shouldTruncate = true } = useTableContext(); return ( - +
{children}
); diff --git a/packages/table/src/ExpandedContent/ExpandedContent.tsx b/packages/table/src/ExpandedContent/ExpandedContent.tsx index f3502208b3..ecf6e32900 100644 --- a/packages/table/src/ExpandedContent/ExpandedContent.tsx +++ b/packages/table/src/ExpandedContent/ExpandedContent.tsx @@ -4,7 +4,7 @@ import { RowData } from '@tanstack/react-table'; import { cx } from '@leafygreen-ui/emotion'; import { useDarkMode } from '@leafygreen-ui/leafygreen-provider'; -import { cellContainerStyles } from '../Cell/Cell.styles'; +import { getCellContainerStyles } from '../Cell/Cell.styles'; import { LGIDS } from '../constants'; import InternalRowBase from '../Row/InternalRowBase'; import { useTableContext } from '../TableContext'; @@ -44,7 +44,7 @@ const ExpandedContent = ({ data-lgid={LGIDS.cell} >
{content}
diff --git a/packages/table/src/Row/InternalRowWithRT.tsx b/packages/table/src/Row/InternalRowWithRT.tsx index 1e27a75d5d..6645e91c50 100644 --- a/packages/table/src/Row/InternalRowWithRT.tsx +++ b/packages/table/src/Row/InternalRowWithRT.tsx @@ -62,7 +62,7 @@ const InternalRowWithRT = ({ data-depth={row.depth} id={`lg-table-row-${row.id}`} ref={node => { - if (measureElement) measureElement(node); // can this be added to table context? + if (measureElement) measureElement(node); }} data-index={virtualRow ? virtualRow!.index : ''} {...rest} diff --git a/packages/table/src/Row/Row.stories.tsx b/packages/table/src/Row/Row.stories.tsx index 0366c0be4a..834f768357 100644 --- a/packages/table/src/Row/Row.stories.tsx +++ b/packages/table/src/Row/Row.stories.tsx @@ -33,6 +33,8 @@ import { RowProps, } from '..'; +// TODO: UPDATE ME + const meta: StoryMetaType = { title: 'Components/Table/Row', component: Row, @@ -158,7 +160,6 @@ export const DisabledNestedRows: StoryFn = ({ row, ...rest }) => { ); const table = useLeafyGreenTable({ - containerRef: tableContainerRef, data, columns, state: { @@ -286,7 +287,6 @@ export const DisabledSelectableRows: StoryFn< ); const table = useLeafyGreenTable({ - containerRef: tableContainerRef, data, columns, state: { From b53019615e03296f027185834a6169728456efa6 Mon Sep 17 00:00:00 2001 From: Shaneeza Date: Fri, 18 Oct 2024 15:06:07 -0400 Subject: [PATCH 037/113] update types --- packages/table/src/Cell/Cell.tsx | 7 ++----- packages/table/src/Cell/Cell.types.ts | 4 ++-- packages/table/src/Cell/InternalCellWithRT.tsx | 1 - packages/table/src/Cell/InternalCellWithoutRT.tsx | 8 ++++++-- packages/table/src/Cell/index.ts | 6 +++++- packages/table/src/Row/InternalRowWithRT.tsx | 1 - packages/table/src/Row/RowContext.tsx | 11 ++--------- 7 files changed, 17 insertions(+), 21 deletions(-) diff --git a/packages/table/src/Cell/Cell.tsx b/packages/table/src/Cell/Cell.tsx index b70e7e7e37..8cdd83417e 100644 --- a/packages/table/src/Cell/Cell.tsx +++ b/packages/table/src/Cell/Cell.tsx @@ -1,6 +1,5 @@ import React from 'react'; -import { useRowContext } from '../Row/RowContext'; import { LGRowData } from '../useLeafyGreenTable'; import InternalCellWithoutRT from './InternalCellWithoutRT'; @@ -12,15 +11,13 @@ const Cell = ({ cell, ...rest }: CellProps) => { - const { isReactTable } = useRowContext(); - return ( <> - {!isReactTable && ( + {!cell && ( {children} )} - {isReactTable && ( + {cell && ( {children} diff --git a/packages/table/src/Cell/Cell.types.ts b/packages/table/src/Cell/Cell.types.ts index f9743bbdd5..4246de1fdc 100644 --- a/packages/table/src/Cell/Cell.types.ts +++ b/packages/table/src/Cell/Cell.types.ts @@ -21,9 +21,9 @@ interface BaseCellProps extends HTMLElementProps<'td'> { contentClassName?: string; } -interface CellProps extends BaseCellProps { +export interface CellProps extends BaseCellProps { /** - * TODO: + * The cell object that is returned when mapping through a row passed from the `useLeafyGreenTable` or `useLeafyGreenVirtualTable` hook. */ cell?: LeafyGreenTableCell; } diff --git a/packages/table/src/Cell/InternalCellWithRT.tsx b/packages/table/src/Cell/InternalCellWithRT.tsx index 045840e84c..8bdd5e1309 100644 --- a/packages/table/src/Cell/InternalCellWithRT.tsx +++ b/packages/table/src/Cell/InternalCellWithRT.tsx @@ -20,7 +20,6 @@ const InternalCellWithRT = ({ ...rest }: InternalCellWithRTProps) => { const { disabled } = useRowContext(); - // TODO: log warning if cell is not passed to Cell const { isSelectable, shouldTruncate = true } = useTableContext(); const isFirstCell = (cell && cell.column.getIsFirstColumn()) || false; const row = cell.row; diff --git a/packages/table/src/Cell/InternalCellWithoutRT.tsx b/packages/table/src/Cell/InternalCellWithoutRT.tsx index bf2c234aeb..a4ade1ad0b 100644 --- a/packages/table/src/Cell/InternalCellWithoutRT.tsx +++ b/packages/table/src/Cell/InternalCellWithoutRT.tsx @@ -6,9 +6,13 @@ import { useTableContext } from '../TableContext'; import { getCellEllipsisStyles, getCellStyles } from './Cell.styles'; import InternalCell from './InternalCell'; -import { CellProps } from '.'; +import { InternalCellProps } from '.'; -const InternalCellWithoutRT = ({ children, className, ...rest }: CellProps) => { +const InternalCellWithoutRT = ({ + children, + className, + ...rest +}: InternalCellProps) => { const { shouldTruncate = true } = useTableContext(); return ( diff --git a/packages/table/src/Cell/index.ts b/packages/table/src/Cell/index.ts index 307b5238e8..a46db93812 100644 --- a/packages/table/src/Cell/index.ts +++ b/packages/table/src/Cell/index.ts @@ -1,4 +1,8 @@ export { default as Cell } from './Cell'; -export { type CellProps } from './Cell.types'; +export type { + CellProps, + InternalCellProps, + InternalCellWithRTProps, +} from './Cell.types'; export { default as HeaderCell } from './HeaderCell/HeaderCell'; export { type HeaderCellProps } from './HeaderCell/HeaderCell.types'; diff --git a/packages/table/src/Row/InternalRowWithRT.tsx b/packages/table/src/Row/InternalRowWithRT.tsx index 6645e91c50..9310eb06a7 100644 --- a/packages/table/src/Row/InternalRowWithRT.tsx +++ b/packages/table/src/Row/InternalRowWithRT.tsx @@ -37,7 +37,6 @@ const InternalRowWithRT = ({ const contextValues = useMemo(() => { return { disabled, - isReactTable: true, }; }, [disabled]); diff --git a/packages/table/src/Row/RowContext.tsx b/packages/table/src/Row/RowContext.tsx index de2535c1bd..e043b12c21 100644 --- a/packages/table/src/Row/RowContext.tsx +++ b/packages/table/src/Row/RowContext.tsx @@ -7,27 +7,20 @@ import React, { type RowContextProps = PropsWithChildren<{ disabled: boolean; - isReactTable: boolean; }>; const RowContext = createContext({ - isReactTable: false, disabled: false, }); export const useRowContext = () => useContext(RowContext); -export const RowContextProvider = ({ - children, - disabled, - isReactTable, -}: RowContextProps) => { +export const RowContextProvider = ({ children, disabled }: RowContextProps) => { const providerData = useMemo(() => { return { disabled, - isReactTable, }; - }, [disabled, isReactTable]); + }, [disabled]); return ( {children} From 6bb4c3938a21ccc5c46445b88f554e8562e062a7 Mon Sep 17 00:00:00 2001 From: Shaneeza Date: Fri, 18 Oct 2024 15:52:55 -0400 Subject: [PATCH 038/113] align styles --- packages/table/src/Cell/HeaderCell/HeaderCell.tsx | 3 ++- packages/table/src/Cell/InternalCellWithRT.tsx | 3 +++ 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/packages/table/src/Cell/HeaderCell/HeaderCell.tsx b/packages/table/src/Cell/HeaderCell/HeaderCell.tsx index 2f105b2f31..e69e882889 100644 --- a/packages/table/src/Cell/HeaderCell/HeaderCell.tsx +++ b/packages/table/src/Cell/HeaderCell/HeaderCell.tsx @@ -29,6 +29,7 @@ const HeaderCell = ({ className, cellIndex, header, + align, ...rest }: PropsWithChildren>) => { const { isSelectable } = useTableContext(); @@ -61,7 +62,7 @@ const HeaderCell = ({ className={cx( // TS error is ignored (and not expected) as it doesn't show up locally but interrupts build // @ts-ignore Header types need to be extended or declared in the react-table namespace - getCellContainerStyles(header?.column.columnDef?.align), + getCellContainerStyles(align || header?.column.columnDef?.align), headerCellContentStyles, )} > diff --git a/packages/table/src/Cell/InternalCellWithRT.tsx b/packages/table/src/Cell/InternalCellWithRT.tsx index 8bdd5e1309..7e1b6c47d3 100644 --- a/packages/table/src/Cell/InternalCellWithRT.tsx +++ b/packages/table/src/Cell/InternalCellWithRT.tsx @@ -34,6 +34,9 @@ const InternalCellWithRT = ({ getCellStyles(depth, isExpandable, isSelectable), className, )} + // TS error is ignored (and not expected) as it doesn't show up locally but interrupts build + // @ts-ignore Cell types need to be extended or declared in the react-table namespace + align={align || cell?.column.columnDef?.align} {...rest} > {isFirstCell && isExpandable && ( From 9bbeb3cd97b51d5c908ab5f116382f7857fe3da0 Mon Sep 17 00:00:00 2001 From: Shaneeza Date: Tue, 22 Oct 2024 11:50:51 -0400 Subject: [PATCH 039/113] Prerelease version packages 13.0.0-beta.0 --- packages/table/CHANGELOG.md | 6 ++++++ packages/table/package.json | 2 +- 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/packages/table/CHANGELOG.md b/packages/table/CHANGELOG.md index 2f671833cb..28896e2d35 100644 --- a/packages/table/CHANGELOG.md +++ b/packages/table/CHANGELOG.md @@ -1,5 +1,11 @@ # @leafygreen-ui/table +## 13.0.0-beta.0 + +### Major Changes + +- First beta pre-release of Table v13. This release is a WIP and should not be used in production. + ## 12.7.0 ### Minor Changes diff --git a/packages/table/package.json b/packages/table/package.json index fac6951cf8..a5589cbc94 100644 --- a/packages/table/package.json +++ b/packages/table/package.json @@ -1,6 +1,6 @@ { "name": "@leafygreen-ui/table", - "version": "12.7.0", + "version": "13.0.0-beta.0", "description": "leafyGreen UI Kit Table", "main": "./dist/index.js", "module": "./dist/esm/index.js", From f3f1838adc00c9a780f9ec8299e8481e4e84daf9 Mon Sep 17 00:00:00 2001 From: Shaneeza Date: Tue, 22 Oct 2024 13:17:17 -0400 Subject: [PATCH 040/113] fix install error --- packages/table/package.json | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/packages/table/package.json b/packages/table/package.json index a5589cbc94..3b0ef4ccdb 100644 --- a/packages/table/package.json +++ b/packages/table/package.json @@ -39,7 +39,8 @@ "polished": "^4.2.2", "react-virtual": "^2.10.4", "react-fast-compare": "3.2.2", - "react-transition-group": "^4.4.5" + "react-transition-group": "^4.4.5", + "react-keyed-flatten-children": "^1.3.0" }, "devDependencies": { "@faker-js/faker": "^8.0.0", From ddeec2d8251f9cb7bf88bfe1943b0a5d843101c6 Mon Sep 17 00:00:00 2001 From: Shaneeza Date: Tue, 22 Oct 2024 13:27:11 -0400 Subject: [PATCH 041/113] Prerelease version packages 13.0.0-beta.1 --- packages/table/CHANGELOG.md | 6 ++++++ packages/table/package.json | 2 +- 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/packages/table/CHANGELOG.md b/packages/table/CHANGELOG.md index 28896e2d35..34c47b2dc3 100644 --- a/packages/table/CHANGELOG.md +++ b/packages/table/CHANGELOG.md @@ -1,5 +1,11 @@ # @leafygreen-ui/table +## 13.0.0-beta.1 + +### Patch Changes + +- Add `react-keyed-flatten-children` to fix install error + ## 13.0.0-beta.0 ### Major Changes diff --git a/packages/table/package.json b/packages/table/package.json index 3b0ef4ccdb..de9f0131fc 100644 --- a/packages/table/package.json +++ b/packages/table/package.json @@ -1,6 +1,6 @@ { "name": "@leafygreen-ui/table", - "version": "13.0.0-beta.0", + "version": "13.0.0-beta.1", "description": "leafyGreen UI Kit Table", "main": "./dist/index.js", "module": "./dist/esm/index.js", From 53c1b2c5508f61302969756ca8bbc8186688a96e Mon Sep 17 00:00:00 2001 From: Shaneeza Date: Wed, 23 Oct 2024 11:33:30 -0400 Subject: [PATCH 042/113] comment, wip --- packages/table/src/Table/Table.styles.ts | 3 +++ packages/table/src/Table/Table.tsx | 1 + 2 files changed, 4 insertions(+) diff --git a/packages/table/src/Table/Table.styles.ts b/packages/table/src/Table/Table.styles.ts index 4bf242c6f4..a57e624a2a 100644 --- a/packages/table/src/Table/Table.styles.ts +++ b/packages/table/src/Table/Table.styles.ts @@ -51,6 +51,9 @@ export const getVirtualDynamicStyles = ( thead { top: -${startPosition}px; + /* transform: translate3d(0, ${startPosition / 2}px, 0); */ + /* top: 0; */ + /* position: absolute; */ } `} `; diff --git a/packages/table/src/Table/Table.tsx b/packages/table/src/Table/Table.tsx index ae20e8a7c8..9119ea4f86 100644 --- a/packages/table/src/Table/Table.tsx +++ b/packages/table/src/Table/Table.tsx @@ -49,6 +49,7 @@ const Table = forwardRef>( const virtualTableTotalSize = virtualTable ? virtualTable.getTotalSize() : 0; + // TODO: look into scroll position instead of start position const virtualTableStart = virtualTable ? virtualTable.getVirtualItems()[0]?.start : 0; From bcb780427d85717bb4261867ea44f16cf69fbb5e Mon Sep 17 00:00:00 2001 From: Shaneeza Date: Tue, 29 Oct 2024 15:59:58 -0400 Subject: [PATCH 043/113] revert useLeafyGreenTable hook so its consistent with a virtual table --- packages/table/src/Row/InternalRowWithRT.tsx | 2 +- packages/table/src/Table.stories.tsx | 260 +++++------------- .../useLeafyGreenTable/useLeafyGreenTable.tsx | 36 ++- .../useLeafyGreenVirtualTable.tsx | 40 +-- 4 files changed, 109 insertions(+), 229 deletions(-) diff --git a/packages/table/src/Row/InternalRowWithRT.tsx b/packages/table/src/Row/InternalRowWithRT.tsx index 1e27a75d5d..682a2ecc0d 100644 --- a/packages/table/src/Row/InternalRowWithRT.tsx +++ b/packages/table/src/Row/InternalRowWithRT.tsx @@ -42,7 +42,7 @@ const InternalRowWithRT = ({ }, [disabled]); // eslint-disable-next-line no-console - console.log(`🪼rerender🪼 row: ${row.id}, depth: ${row.depth}`); + // console.log(`🪼rerender🪼 row: ${row.id}, depth: ${row.depth}`); return ( = args => { {rows.map((row: LeafyGreenTableRow) => { - // const isExpandedContent = row.original.isExpandedContent ?? false; + const isExpandedContent = row.original.isExpandedContent ?? false; - // TODO: the diff in this approach is that the keys are not chaning when a sub row opens return ( - {/* {!isExpandedContent && ( */} - - {row.getVisibleCells().map(cell => { - return ( - - {flexRender( - cell.column.columnDef.cell, - cell.getContext(), - )} - - ); - })} - - {row.getIsExpanded() && - row.subRows && - row.subRows.map(subRow => ( - - - {subRow.getVisibleCells().map(cell => { - return ( - - {flexRender( - cell.column.columnDef.cell, - cell.getContext(), - )} - - ); - })} - - {subRow.original.renderExpandedContent && - subRow.getIsExpanded() && ( - - )} - - ))} + {!isExpandedContent && ( + + {row.getVisibleCells().map(cell => { + return ( + + {flexRender( + cell.column.columnDef.cell, + cell.getContext(), + )} + + ); + })} + + )} + {isExpandedContent && } ); })} @@ -263,47 +242,6 @@ ZebraStripes.args = { shouldAlternateRowColor: true, }; -// TODO: i don't think we need this story -export const OverflowingCell: StoryFn = args => { - const data = makeData(false, 100); - const columns = Object.keys(data[0]).filter( - x => x !== 'renderExpandedContent' && x !== 'subRows', - ); - return ( -
{ row: LeafyGreenTableRow; + /** + * Virtual row object passed from the `useLeafyGreenTable` hook + */ + virtualRow?: VirtualItem; } diff --git a/packages/table/src/Row/InternalRowWithRT.tsx b/packages/table/src/Row/InternalRowWithRT.tsx index 22502922b7..1e27a75d5d 100644 --- a/packages/table/src/Row/InternalRowWithRT.tsx +++ b/packages/table/src/Row/InternalRowWithRT.tsx @@ -41,12 +41,8 @@ const InternalRowWithRT = ({ }; }, [disabled]); - const depth = row.depth; - // eslint-disable-next-line no-console - console.log(`🪼rerender🪼 row: ${row.id}, depth: ${depth}`, { - isExpanded: isExpanded, - }); + console.log(`🪼rerender🪼 row: ${row.id}, depth: ${row.depth}`); return ( = args => { row.original.isExpandedContent ?? false; return ( - <> + {!isExpandedContent && ( - + {row .getVisibleCells() .map((cell: LeafyGreenTableCell) => { @@ -498,13 +494,9 @@ export const ExpandableContent: StoryFn = args => { )} {isExpandedContent && ( - + )} - + ); }, )} diff --git a/packages/table/src/useLeafyGreenVirtualTable/useLeafyGreenVirtualTable.tsx b/packages/table/src/useLeafyGreenVirtualTable/useLeafyGreenVirtualTable.tsx index 59dde3db93..3d27396ad3 100644 --- a/packages/table/src/useLeafyGreenVirtualTable/useLeafyGreenVirtualTable.tsx +++ b/packages/table/src/useLeafyGreenVirtualTable/useLeafyGreenVirtualTable.tsx @@ -40,7 +40,9 @@ function useLeafyGreenVirtualTable< const { rows } = table; - const rowsCopy = useMemo(() => [...rows], [rows]); + //TODO: this memo breaks the for loop below 😭 + // const rowsCopy = useMemo(() => [...rows], [rows]); + const rowsCopy = [...rows]; // A way to include expandableContent inside of the rows object. // If a row has expandedContent and its expanded then add a new row below the row @@ -66,10 +68,10 @@ function useLeafyGreenVirtualTable< getScrollElement: () => containerRef.current, estimateSize: () => 40, overscan: 20, - getItemKey: useCallback( - (index: number) => rowsCopy[index]?.id ?? index, - [rowsCopy], - ), + // getItemKey: useCallback( + // (index: number) => rowsCopy[index]?.id ?? index, + // [rowsCopy], + // ), measureElement: typeof window !== 'undefined' && navigator.userAgent.indexOf('Firefox') === -1 From 8daa4c452104756466ca9c011e966f9d4996f9dd Mon Sep 17 00:00:00 2001 From: Shaneeza Date: Thu, 17 Oct 2024 11:10:33 -0400 Subject: [PATCH 030/113] remove unsed exports --- .../src/useLeafyGreenVirtualTable/useLeafyGreenVirtualTable.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/table/src/useLeafyGreenVirtualTable/useLeafyGreenVirtualTable.tsx b/packages/table/src/useLeafyGreenVirtualTable/useLeafyGreenVirtualTable.tsx index 3d27396ad3..dbb3088d8f 100644 --- a/packages/table/src/useLeafyGreenVirtualTable/useLeafyGreenVirtualTable.tsx +++ b/packages/table/src/useLeafyGreenVirtualTable/useLeafyGreenVirtualTable.tsx @@ -1,4 +1,4 @@ -import { useCallback, useMemo, useState } from 'react'; +import { useState } from 'react'; import { ExpandedState, getExpandedRowModel } from '@tanstack/react-table'; import { useVirtualizer, VirtualItem } from '@tanstack/react-virtual'; From 3848ba55ba674164096beb72fb6c49b22a6c482f Mon Sep 17 00:00:00 2001 From: Shaneeza Date: Thu, 17 Oct 2024 12:24:54 -0400 Subject: [PATCH 031/113] add a new story --- packages/table/src/Table.stories.tsx | 7 +- .../table/src/Table/TableWithVS.stories.tsx | 154 +++++++++++++++++- 2 files changed, 153 insertions(+), 8 deletions(-) diff --git a/packages/table/src/Table.stories.tsx b/packages/table/src/Table.stories.tsx index 975b35f9d2..19b1936cc5 100644 --- a/packages/table/src/Table.stories.tsx +++ b/packages/table/src/Table.stories.tsx @@ -205,12 +205,7 @@ export const LiveExample: StoryFn = args => { {row.getVisibleCells().map(cell => { return ( - + {flexRender( cell.column.columnDef.cell, cell.getContext(), diff --git a/packages/table/src/Table/TableWithVS.stories.tsx b/packages/table/src/Table/TableWithVS.stories.tsx index f8f326a051..18eb8ba9e9 100644 --- a/packages/table/src/Table/TableWithVS.stories.tsx +++ b/packages/table/src/Table/TableWithVS.stories.tsx @@ -1,11 +1,18 @@ -import React, { Fragment, useCallback, useMemo } from 'react'; +import React, { Fragment, useCallback, useMemo, useState } from 'react'; import { faker } from '@faker-js/faker'; import { storybookArgTypes, StoryMetaType } from '@lg-tools/storybook-utils'; import { StoryFn } from '@storybook/react'; +import Badge from '@leafygreen-ui/badge'; import { css } from '@leafygreen-ui/emotion'; +import Icon from '@leafygreen-ui/icon'; +import IconButton from '@leafygreen-ui/icon-button'; -import { makeData, Person } from '../utils/makeData.testutils'; +import { + makeData, + makeKitchenSinkData, + Person, +} from '../utils/makeData.testutils'; import { Cell, type ColumnDef, @@ -17,6 +24,7 @@ import { HeaderRow, type LeafyGreenTableCell, type LeafyGreenVirtualItem, + LGColumnDef, Row, type SortingState, Table, @@ -593,3 +601,145 @@ export const TallRows: StoryFn = args => { ); }; + +export const DifferentHeights: StoryFn = args => { + const tableContainerRef = React.useRef(null); + const [data] = useState(() => makeKitchenSinkData(5000)); + + const columns = React.useMemo>>( + () => [ + { + accessorKey: 'dateCreated', + header: 'Date Created', + enableSorting: true, + cell: info => + (info.getValue() as Date).toLocaleDateString('en-us', { + year: 'numeric', + month: 'short', + day: 'numeric', + }), + }, + { + accessorKey: 'frequency', + header: 'Frequency', + }, + { + accessorKey: 'clusterType', + header: 'Cluster Type', + }, + { + accessorKey: 'encryptorEnabled', + header: 'Encryptor', + // eslint-disable-next-line react/display-name + cell: info => ( + + {info.getValue() ? 'Enabled' : 'Not enabled'} + + ), + }, + { + accessorKey: 'mdbVersion', + header: 'MongoDB Version', + enableSorting: true, + size: 90, + }, + { + id: 'actions', + header: '', + size: 90, + // eslint-disable-next-line react/display-name + cell: _ => { + return ( + <> + + + + + + + + + + + ); + }, + }, + ], + [], + ); + + // FIXME: this table becomes SUPER flickery scrolling up when a lot of rows are expanded + //TODO: fix type + const table = useLeafyGreenVirtualTable({ + containerRef: tableContainerRef, + data, + columns, + }); + + return ( + <> +
+

{table.rows.length} total rows

+
+ + + + {table.getHeaderGroups().map((headerGroup: HeaderGroup) => ( + + {headerGroup.headers.map(header => { + return ( + + {flexRender( + header.column.columnDef.header, + header.getContext(), + )} + + ); + })} + + ))} + + + {table.virtual.virtualItems && + table.virtual.virtualItems.map( + (virtualRow: LeafyGreenVirtualItem) => { + const row = virtualRow.row; + const isExpandedContent = + row.original.isExpandedContent ?? false; + + return ( + + {!isExpandedContent && ( + + {row + .getVisibleCells() + .map((cell: LeafyGreenTableCell) => { + return ( + + {flexRender( + cell.column.columnDef.cell, + cell.getContext(), + )} + + ); + })} + + )} + {isExpandedContent && ( + + )} + + ); + }, + )} + +
+ + ); +}; From 60d4ff1a07d8e106c0ca15577a9b285c9bb9a39b Mon Sep 17 00:00:00 2001 From: Shaneeza Date: Thu, 17 Oct 2024 14:54:35 -0400 Subject: [PATCH 032/113] widths and vertical align --- packages/table/src/Cell/Cell.styles.ts | 1 + packages/table/src/Cell/InternalCell.tsx | 30 +++++++++++++++--------- 2 files changed, 20 insertions(+), 11 deletions(-) diff --git a/packages/table/src/Cell/Cell.styles.ts b/packages/table/src/Cell/Cell.styles.ts index b34f110c28..4b6d85ecab 100644 --- a/packages/table/src/Cell/Cell.styles.ts +++ b/packages/table/src/Cell/Cell.styles.ts @@ -82,6 +82,7 @@ export const truncatedContentStyles = css` export const getBaseStyles = (size = 0, shouldTruncate = true) => css` padding: 0 8px; overflow: hidden; + vertical-align: top; &:focus-visible { box-shadow: inset; diff --git a/packages/table/src/Cell/InternalCell.tsx b/packages/table/src/Cell/InternalCell.tsx index 827998f98a..568dd70375 100644 --- a/packages/table/src/Cell/InternalCell.tsx +++ b/packages/table/src/Cell/InternalCell.tsx @@ -1,6 +1,6 @@ import React, { useRef } from 'react'; -import { cx } from '@leafygreen-ui/emotion'; +import { css, cx } from '@leafygreen-ui/emotion'; import { LGIDS } from '../constants'; import { useRowContext } from '../Row/RowContext'; @@ -37,8 +37,6 @@ const InternalCell = ({ const contentRef = useRef(null); const cellSize = cell.column.getSize(); - // TODO: memoize me - return (
- {isFirstCell && isExpandable && ( - - )} -
{children}
+
+ {isFirstCell && isExpandable && ( + + )} +
+ {children} +
+
-
- {children} -
-
-
+
{isFirstCell && isExpandable && ( { + const { shouldTruncate = true } = useTableContext(); + + return ( +
+
+
{children}
+
+
-
- {isFirstCell && isExpandable && ( - - )} -
- {children} -
-
+
{children}
-
-
{children}
-
-
- - - {columns.map((columnName: string) => ( - {columnName} - ))} - - - - {data.map((row: AnyDict) => ( - - {Object.keys(row).map((cellKey: string, index: number) => { - return ( - -
- {row[cellKey]} -
-
- ); - })} -
- ))} -
-
- ); -}; - export const NestedRows: StoryFn = args => { const tableContainerRef = React.useRef(null); const [data] = React.useState(() => makeData(false, 500, 5, 3)); @@ -385,58 +323,20 @@ export const NestedRows: StoryFn = args => { {rows.map((row: LeafyGreenTableRow) => { return ( - - - {row - .getVisibleCells() - .map((cell: LeafyGreenTableCell) => { - return ( - - {flexRender( - cell.column.columnDef.cell, - cell.getContext(), - )} - - ); - })} - - {row.getIsExpanded() && - row.subRows && - row.subRows.map(subRow => ( - - - {subRow.getVisibleCells().map(cell => { - return ( - - {flexRender( - cell.column.columnDef.cell, - cell.getContext(), - )} - - ); - })} - - {subRow.getIsExpanded() && - subRow.subRows && - subRow.subRows.map(subSubRow => ( - - - {subSubRow.getVisibleCells().map(cell => { - return ( - - {flexRender( - cell.column.columnDef.cell, - cell.getContext(), - )} - - ); - })} - - - ))} - - ))} - + + {row + .getVisibleCells() + .map((cell: LeafyGreenTableCell) => { + return ( + + {flexRender( + cell.column.columnDef.cell, + cell.getContext(), + )} + + ); + })} + ); })} @@ -493,7 +393,6 @@ export const ExpandableContent: StoryFn = args => { columns, }); - // const { rows } = table.getRowModel(); const { rows } = table; return ( @@ -521,23 +420,24 @@ export const ExpandableContent: StoryFn = args => { {rows.map((row: LeafyGreenTableRow) => { + const isExpandedContent = row.original.isExpandedContent ?? false; return ( - - {row.getVisibleCells().map(cell => { - return ( - - {flexRender( - cell.column.columnDef.cell, - cell.getContext(), - )} - - ); - })} - - {row.original.renderExpandedContent && row.getIsExpanded() && ( - + {!isExpandedContent && ( + + {row.getVisibleCells().map(cell => { + return ( + + {flexRender( + cell.column.columnDef.cell, + cell.getContext(), + )} + + ); + })} + )} + {isExpandedContent && } ); })} @@ -1143,47 +1043,29 @@ export const StyledComponents: StoryFn = args => { {rows.map((row: LeafyGreenTableRow) => { + const isExpandedContent = row.original.isExpandedContent ?? false; return ( - - {row.getVisibleCells().map(cell => { - return ( - - {flexRender( - cell.column.columnDef.cell, - cell.getContext(), - )} - - ); - })} - - {row.getIsExpanded() && - row.subRows && - row.subRows.map(subRow => ( - - - {subRow.getVisibleCells().map(cell => { - return ( - - {flexRender( - cell.column.columnDef.cell, - cell.getContext(), - )} - - ); - })} - - {subRow.original.renderExpandedContent && - subRow.getIsExpanded() && ( - - )} - - ))} + {!isExpandedContent && ( + + {row.getVisibleCells().map(cell => { + return ( + + {flexRender( + cell.column.columnDef.cell, + cell.getContext(), + )} + + ); + })} + + )} + {isExpandedContent && } ); })} diff --git a/packages/table/src/useLeafyGreenTable/useLeafyGreenTable.tsx b/packages/table/src/useLeafyGreenTable/useLeafyGreenTable.tsx index 7e37ddc6e0..ea42868e6f 100644 --- a/packages/table/src/useLeafyGreenTable/useLeafyGreenTable.tsx +++ b/packages/table/src/useLeafyGreenTable/useLeafyGreenTable.tsx @@ -1,5 +1,9 @@ -import React from 'react'; -import { useReactTable } from '@tanstack/react-table'; +import React, { useState } from 'react'; +import { + ExpandedState, + getExpandedRowModel, + useReactTable, +} from '@tanstack/react-table'; import { getCoreRowModel, getPaginationRowModel, @@ -22,6 +26,7 @@ function useLeafyGreenTable({ allowSelectAll = true, ...rest }: LeafyGreenTableOptions): LeafyGreenTable { + const [expanded, setExpanded] = useState({}); /** * A `ColumnDef` object injected into `useReactTable`'s `columns` option when the user is using selectable rows. */ @@ -55,6 +60,7 @@ function useLeafyGreenTable({ const table = useReactTable>({ state: { + expanded, ...rest.state, }, data, @@ -68,15 +74,39 @@ function useLeafyGreenTable({ getSubRows: row => row.subRows, getSortedRowModel: getSortedRowModel(), getPaginationRowModel: withPagination ? getPaginationRowModel() : undefined, + onExpandedChange: setExpanded, + getExpandedRowModel: getExpandedRowModel(), ...rest, }); const { rows } = table.getRowModel(); + const rowsCopy = [...rows]; + + // A way to include expandableContent inside of the rows object. + // If a row has expandedContent and its expanded then add a new row below the row + for (let i = 0; i < rowsCopy.length; i++) { + if ( + rowsCopy[i].original.renderExpandedContent && + rowsCopy[i].getIsExpanded() + ) { + rowsCopy.splice(i + 1, 0, { + ...rowsCopy[i], + id: `${rowsCopy[i].id}-expandedContent`, + original: { + // TODO: move outside of original + ...rowsCopy[i].original, + isExpandedContent: true, + }, + }); + i++; // Increment index to skip the newly added item + } + } + return { ...table, hasSelectableRows, - rows: rows, + rows: rowsCopy, } as LeafyGreenTable; } diff --git a/packages/table/src/useLeafyGreenVirtualTable/useLeafyGreenVirtualTable.tsx b/packages/table/src/useLeafyGreenVirtualTable/useLeafyGreenVirtualTable.tsx index dbb3088d8f..56a353259d 100644 --- a/packages/table/src/useLeafyGreenVirtualTable/useLeafyGreenVirtualTable.tsx +++ b/packages/table/src/useLeafyGreenVirtualTable/useLeafyGreenVirtualTable.tsx @@ -1,5 +1,3 @@ -import { useState } from 'react'; -import { ExpandedState, getExpandedRowModel } from '@tanstack/react-table'; import { useVirtualizer, VirtualItem } from '@tanstack/react-virtual'; import useLeafyGreenTable, { LGRowData } from '../useLeafyGreenTable'; @@ -23,54 +21,25 @@ function useLeafyGreenVirtualTable< virtualizerOptions, ...rest }: LeafyGreenVirtualTableOptions): LeafyGreenVirtualTable { - const [expanded, setExpanded] = useState({}); const table = useLeafyGreenTable({ data, columns, withPagination, allowSelectAll, hasSelectableRows, - onExpandedChange: setExpanded, - getExpandedRowModel: getExpandedRowModel(), - state: { - expanded, - }, ...rest, }); const { rows } = table; - //TODO: this memo breaks the for loop below 😭 - // const rowsCopy = useMemo(() => [...rows], [rows]); - const rowsCopy = [...rows]; - - // A way to include expandableContent inside of the rows object. - // If a row has expandedContent and its expanded then add a new row below the row - for (let i = 0; i < rowsCopy.length; i++) { - if ( - rowsCopy[i].original.renderExpandedContent && - rowsCopy[i].getIsExpanded() - ) { - rowsCopy.splice(i + 1, 0, { - ...rowsCopy[i], - id: `${rowsCopy[i].id}-expandedContent`, - original: { - ...rowsCopy[i].original, - isExpandedContent: true, - }, - }); - i++; // Increment index to skip the newly added item - } - } - const _virtualizer = useVirtualizer({ - count: rowsCopy.length, + count: rows.length, getScrollElement: () => containerRef.current, estimateSize: () => 40, overscan: 20, // getItemKey: useCallback( - // (index: number) => rowsCopy[index]?.id ?? index, - // [rowsCopy], + // (index: number) => rows[index]?.id ?? index, + // [rows], // ), measureElement: typeof window !== 'undefined' && @@ -84,12 +53,11 @@ function useLeafyGreenVirtualTable< .getVirtualItems() .map((virtualRow: VirtualItem) => ({ ...virtualRow, - row: rowsCopy[virtualRow.index], + row: rows[virtualRow.index], })); return { ...table, - rows: rowsCopy, virtual: { ..._virtualizer, virtualItems: _virtualItems }, } as LeafyGreenVirtualTable; } From c8cc4600fbe84b8bb28fd4a42329c8f474ebbad5 Mon Sep 17 00:00:00 2001 From: Shaneeza Date: Thu, 31 Oct 2024 11:22:33 -0400 Subject: [PATCH 044/113] add getItemKey --- packages/table/src/Table/TableWithVS.stories.tsx | 2 +- .../useLeafyGreenVirtualTable.tsx | 9 +++++---- 2 files changed, 6 insertions(+), 5 deletions(-) diff --git a/packages/table/src/Table/TableWithVS.stories.tsx b/packages/table/src/Table/TableWithVS.stories.tsx index 18eb8ba9e9..511aa1ff14 100644 --- a/packages/table/src/Table/TableWithVS.stories.tsx +++ b/packages/table/src/Table/TableWithVS.stories.tsx @@ -604,7 +604,7 @@ export const TallRows: StoryFn = args => { export const DifferentHeights: StoryFn = args => { const tableContainerRef = React.useRef(null); - const [data] = useState(() => makeKitchenSinkData(5000)); + const [data] = useState(() => makeKitchenSinkData(10_000)); const columns = React.useMemo>>( () => [ diff --git a/packages/table/src/useLeafyGreenVirtualTable/useLeafyGreenVirtualTable.tsx b/packages/table/src/useLeafyGreenVirtualTable/useLeafyGreenVirtualTable.tsx index 56a353259d..81bfe48991 100644 --- a/packages/table/src/useLeafyGreenVirtualTable/useLeafyGreenVirtualTable.tsx +++ b/packages/table/src/useLeafyGreenVirtualTable/useLeafyGreenVirtualTable.tsx @@ -1,3 +1,4 @@ +import { useCallback } from 'react'; import { useVirtualizer, VirtualItem } from '@tanstack/react-virtual'; import useLeafyGreenTable, { LGRowData } from '../useLeafyGreenTable'; @@ -37,10 +38,10 @@ function useLeafyGreenVirtualTable< getScrollElement: () => containerRef.current, estimateSize: () => 40, overscan: 20, - // getItemKey: useCallback( - // (index: number) => rows[index]?.id ?? index, - // [rows], - // ), + getItemKey: useCallback( + (index: number) => rows[index]?.id ?? index, + [rows], + ), measureElement: typeof window !== 'undefined' && navigator.userAgent.indexOf('Firefox') === -1 From a89ca4aa8614ae0c7c2724dec4c2f03e8ca35f56 Mon Sep 17 00:00:00 2001 From: Shaneeza Date: Thu, 31 Oct 2024 12:03:59 -0400 Subject: [PATCH 045/113] small fix --- packages/table/src/Table/Table.tsx | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/packages/table/src/Table/Table.tsx b/packages/table/src/Table/Table.tsx index 9119ea4f86..3a6401ae08 100644 --- a/packages/table/src/Table/Table.tsx +++ b/packages/table/src/Table/Table.tsx @@ -44,8 +44,9 @@ const Table = forwardRef>( //TODO: find a better way to do all these checks const isVirtual = table && (table as LeafyGreenVirtualTable).virtual ? true : false; - const virtualTable = - isVirtual && (table as LeafyGreenVirtualTable)!.virtual; + const virtualTable = isVirtual + ? (table as LeafyGreenVirtualTable)!.virtual + : undefined; const virtualTableTotalSize = virtualTable ? virtualTable.getTotalSize() : 0; From ca150d96b43e652e934824fb63d7ca12b5c5adbb Mon Sep 17 00:00:00 2001 From: Shaneeza Date: Thu, 31 Oct 2024 13:40:47 -0400 Subject: [PATCH 046/113] stop mapping columns def --- .../table/src/Cell/HeaderCell/HeaderCell.tsx | 4 +++- packages/table/src/Table/Table.tsx | 4 ++-- .../table/src/Table/TableWithVS.stories.tsx | 1 + .../useLeafyGreenTable/useLeafyGreenTable.tsx | 17 ++++++++++------- 4 files changed, 16 insertions(+), 10 deletions(-) diff --git a/packages/table/src/Cell/HeaderCell/HeaderCell.tsx b/packages/table/src/Cell/HeaderCell/HeaderCell.tsx index e69e882889..9971fdf45a 100644 --- a/packages/table/src/Cell/HeaderCell/HeaderCell.tsx +++ b/packages/table/src/Cell/HeaderCell/HeaderCell.tsx @@ -36,7 +36,9 @@ const HeaderCell = ({ let columnName, sortState, onSortIconClick; - if (header && header.column.getCanSort()) { + // console.log({ cansort: header?.column.columnDef.enableSorting }); + + if (header && header?.column.columnDef.enableSorting) { columnName = header.column.columnDef.header as string; const headerSortDirection = header.column.getIsSorted().toString(); sortState = HeaderSortState[headerSortDirection]; diff --git a/packages/table/src/Table/Table.tsx b/packages/table/src/Table/Table.tsx index 3a6401ae08..689f47157c 100644 --- a/packages/table/src/Table/Table.tsx +++ b/packages/table/src/Table/Table.tsx @@ -50,11 +50,11 @@ const Table = forwardRef>( const virtualTableTotalSize = virtualTable ? virtualTable.getTotalSize() : 0; - // TODO: look into scroll position instead of start position + // TODO: look into scroll position instead of start position - diff PR const virtualTableStart = virtualTable ? virtualTable.getVirtualItems()[0]?.start : 0; - const isSelectable = table && table.hasSelectableRows; + const isSelectable = table ? table.hasSelectableRows : false; const measureElement = isVirtual ? (table as LeafyGreenVirtualTable).virtual.measureElement : undefined; diff --git a/packages/table/src/Table/TableWithVS.stories.tsx b/packages/table/src/Table/TableWithVS.stories.tsx index 511aa1ff14..065e32116e 100644 --- a/packages/table/src/Table/TableWithVS.stories.tsx +++ b/packages/table/src/Table/TableWithVS.stories.tsx @@ -622,6 +622,7 @@ export const DifferentHeights: StoryFn = args => { { accessorKey: 'frequency', header: 'Frequency', + align: 'right', }, { accessorKey: 'clusterType', diff --git a/packages/table/src/useLeafyGreenTable/useLeafyGreenTable.tsx b/packages/table/src/useLeafyGreenTable/useLeafyGreenTable.tsx index ea42868e6f..07851a6ac2 100644 --- a/packages/table/src/useLeafyGreenTable/useLeafyGreenTable.tsx +++ b/packages/table/src/useLeafyGreenTable/useLeafyGreenTable.tsx @@ -41,19 +41,22 @@ function useLeafyGreenTable({ () => columnsProp.some(propCol => !!propCol.enableSorting), [columnsProp], ); + const selectColumnConfig = allowSelectAll ? baseSelectColumnConfig : omit(baseSelectColumnConfig, 'header'); + const columns = React.useMemo>>( () => [ ...(hasSelectableRows ? [selectColumnConfig as LGColumnDef] : []), - ...columnsProp.map(propColumn => { - return { - ...propColumn, - align: propColumn.align ?? 'left', - enableSorting: propColumn.enableSorting ?? false, - } as LGColumnDef; - }), + ...columnsProp, + // ...columnsProp.map(propColumn => { + // return { + // ...propColumn, + // align: propColumn.align ?? 'left', + // enableSorting: propColumn.enableSorting ?? false, + // } as LGColumnDef; + // }), ], [columnsProp, hasSelectableRows, selectColumnConfig], ); From 55fbe3e302fba70c95f5d03a707b0d9dabb5d367 Mon Sep 17 00:00:00 2001 From: Shaneeza Date: Thu, 31 Oct 2024 15:33:53 -0400 Subject: [PATCH 047/113] testing --- packages/table/src/Table/Table.styles.ts | 8 ++--- packages/table/src/Table/Table.tsx | 20 +++++++++++ .../table/src/Table/TableWithVS.stories.tsx | 35 ++++++++++--------- packages/table/src/TableBody/TableBody.tsx | 28 ++++++++++++++- .../table/src/TableContext/TableContext.tsx | 15 ++++++++ 5 files changed, 84 insertions(+), 22 deletions(-) diff --git a/packages/table/src/Table/Table.styles.ts b/packages/table/src/Table/Table.styles.ts index a57e624a2a..0a9c2c1251 100644 --- a/packages/table/src/Table/Table.styles.ts +++ b/packages/table/src/Table/Table.styles.ts @@ -33,7 +33,7 @@ export const getVirtualStyles = (isVirtual = false, totalSize: number) => css` ${isVirtual && css` position: relative; - height: ${totalSize}px; + /* height: ${totalSize}px; */ `} `; @@ -43,14 +43,14 @@ export const getVirtualDynamicStyles = ( ) => css` ${isVirtual && css` - position: absolute; + /* position: absolute; top: 0; left: 0; transform: translate3d(0, ${startPosition}px, 0); - width: 100%; + width: 100%; */ thead { - top: -${startPosition}px; + /* top: -${startPosition}px; */ /* transform: translate3d(0, ${startPosition / 2}px, 0); */ /* top: 0; */ /* position: absolute; */ diff --git a/packages/table/src/Table/Table.tsx b/packages/table/src/Table/Table.tsx index 689f47157c..a0b0520ee2 100644 --- a/packages/table/src/Table/Table.tsx +++ b/packages/table/src/Table/Table.tsx @@ -59,6 +59,21 @@ const Table = forwardRef>( ? (table as LeafyGreenVirtualTable).virtual.measureElement : undefined; + const length = virtualTable?.virtualItems.length; + const start = virtualTable?.virtualItems[0]?.start; + const size = virtualTable?.virtualItems[0]?.size; + const end = + virtualTable?.virtualItems[virtualTable?.virtualItems.length - 1]?.end; + const totalSize = virtualTable?.getTotalSize(); + + // console.log({ + // length, + // start, + // size, + // end, + // totalSize, + // }); + return (
>( isSelectable={isSelectable} measureElement={measureElement} shouldTruncate={shouldTruncate} + length={length} + start={start} + size={size} + end={end} + totalSize={totalSize} > = args => { const cells = row.getVisibleCells(); return ( - <> - - {cells.map((cell: LeafyGreenTableCell) => { - return ( - - {flexRender( - cell.column.columnDef.cell, - cell.getContext(), - )} - - ); - })} - - + + {cells.map((cell: LeafyGreenTableCell) => { + return ( + + {flexRender( + cell.column.columnDef.cell, + cell.getContext(), + )} + + ); + })} + ); }, )} @@ -622,7 +620,6 @@ export const DifferentHeights: StoryFn = args => { { accessorKey: 'frequency', header: 'Frequency', - align: 'right', }, { accessorKey: 'clusterType', @@ -709,7 +706,7 @@ export const DifferentHeights: StoryFn = args => { {table.virtual.virtualItems && table.virtual.virtualItems.map( - (virtualRow: LeafyGreenVirtualItem) => { + (virtualRow: LeafyGreenVirtualItem, index: number) => { const row = virtualRow.row; const isExpandedContent = row.original.isExpandedContent ?? false; @@ -717,7 +714,11 @@ export const DifferentHeights: StoryFn = args => { return ( {!isExpandedContent && ( - + {row .getVisibleCells() .map((cell: LeafyGreenTableCell) => { diff --git a/packages/table/src/TableBody/TableBody.tsx b/packages/table/src/TableBody/TableBody.tsx index 737c1b397f..881bae71fe 100644 --- a/packages/table/src/TableBody/TableBody.tsx +++ b/packages/table/src/TableBody/TableBody.tsx @@ -1,9 +1,35 @@ import React from 'react'; +import { useTableContext } from '../TableContext'; + import { TableBodyProps } from './TableBody.types'; const TableBody = ({ children, ...rest }: TableBodyProps) => { - return {children}; + const { isVirtual, length, start, end, totalSize } = useTableContext(); + + let paddingTop = 0; + let paddingBottom = 0; + + if (isVirtual) { + paddingTop = length > 0 ? start || 0 : 0; + paddingBottom = length > 0 ? totalSize - (end || 0) : 0; + } + + return ( + <> + {paddingTop > 0 && ( + + + )} + {children} + {paddingBottom > 0 && ( + + + )} + + ); }; TableBody.displayName = 'TableBody'; diff --git a/packages/table/src/TableContext/TableContext.tsx b/packages/table/src/TableContext/TableContext.tsx index f47f81607a..23bec5bc39 100644 --- a/packages/table/src/TableContext/TableContext.tsx +++ b/packages/table/src/TableContext/TableContext.tsx @@ -28,6 +28,11 @@ const TableContextProvider = ({ isSelectable, measureElement, shouldTruncate, + length, + start, + size, + end, + totalSize, }: PropsWithChildren>>) => { /** The appropriately typed context provider */ const TableProvider = (TableContext as React.Context>) @@ -41,6 +46,11 @@ const TableContextProvider = ({ isSelectable, measureElement, shouldTruncate, + length, + start, + size, + end, + totalSize, }; }, [ shouldAlternateRowColor, @@ -49,6 +59,11 @@ const TableContextProvider = ({ isSelectable, measureElement, shouldTruncate, + length, + start, + size, + end, + totalSize, ]); return ( From 30517cffd849585780d396289abdcc98353ee52e Mon Sep 17 00:00:00 2001 From: Shaneeza Date: Fri, 1 Nov 2024 10:59:55 -0400 Subject: [PATCH 048/113] debugging --- packages/table/src/Table/Table.styles.ts | 62 ++++++++++--------- packages/table/src/Table/Table.tsx | 8 ++- .../table/src/Table/TableWithVS.stories.tsx | 13 +++- packages/table/src/TableBody/TableBody.tsx | 4 +- .../useLeafyGreenVirtualTable.tsx | 27 ++++++-- 5 files changed, 73 insertions(+), 41 deletions(-) diff --git a/packages/table/src/Table/Table.styles.ts b/packages/table/src/Table/Table.styles.ts index 0a9c2c1251..f47fe64ae3 100644 --- a/packages/table/src/Table/Table.styles.ts +++ b/packages/table/src/Table/Table.styles.ts @@ -1,4 +1,4 @@ -import { css } from '@leafygreen-ui/emotion'; +import { css, cx } from '@leafygreen-ui/emotion'; import { Theme } from '@leafygreen-ui/lib'; import { palette } from '@leafygreen-ui/palette'; @@ -29,31 +29,37 @@ export const tableContainerStyles = css` position: relative; `; -export const getVirtualStyles = (isVirtual = false, totalSize: number) => css` - ${isVirtual && - css` - position: relative; - /* height: ${totalSize}px; */ - `} -`; +export const getVirtualStyles = (isVirtual = false, totalSize: number) => + cx({ + [css` + position: relative; + /* height: ${totalSize}px; */ + `]: isVirtual, + }); -export const getVirtualDynamicStyles = ( - isVirtual = false, - startPosition: number, -) => css` - ${isVirtual && - css` - /* position: absolute; - top: 0; - left: 0; - transform: translate3d(0, ${startPosition}px, 0); - width: 100%; */ - - thead { - /* top: -${startPosition}px; */ - /* transform: translate3d(0, ${startPosition / 2}px, 0); */ - /* top: 0; */ - /* position: absolute; */ - } - `} -`; +// export const getVirtualDynamicStyles = ( +// isVirtual = false, +// startPosition: number, +// ) => +// cx( +// { +// [ +// css` +// /* position: absolute; +// top: 0; +// left: 0; +// transform: translate3d(0, ${startPosition}px, 0); +// width: 100%; */ + +// thead { +// /* top: -${startPosition}px; */ +// /* transform: translate3d(0, ${startPosition / 2}px, 0); */ +// /* top: 0; */ +// /* position: absolute; */ +// } +// ` + +// ]:isVirtual +// } +// ) +// `; diff --git a/packages/table/src/Table/Table.tsx b/packages/table/src/Table/Table.tsx index a0b0520ee2..14f7be69c9 100644 --- a/packages/table/src/Table/Table.tsx +++ b/packages/table/src/Table/Table.tsx @@ -16,7 +16,7 @@ import { LeafyGreenVirtualTable } from '../useLeafyGreenVirtualTable/useLeafyGre import { baseStyles, - getVirtualDynamicStyles, + // getVirtualDynamicStyles, getVirtualStyles, tableContainerStyles, themeStyles, @@ -82,9 +82,11 @@ const Table = forwardRef>( // eslint-disable-next-line jsx-a11y/no-noninteractive-tabindex tabIndex={0} > -
+
= args => { // eslint-disable-next-line react/display-name cell: _ => { return ( - <> +
@@ -658,7 +665,7 @@ export const DifferentHeights: StoryFn = args => { - +
); }, }, @@ -685,7 +692,7 @@ export const DifferentHeights: StoryFn = args => { table={table} ref={tableContainerRef} className={virtualScrollingContainerHeight} - shouldTruncate={false} + // shouldTruncate={false} > {table.getHeaderGroups().map((headerGroup: HeaderGroup) => ( diff --git a/packages/table/src/TableBody/TableBody.tsx b/packages/table/src/TableBody/TableBody.tsx index 881bae71fe..15992d3e00 100644 --- a/packages/table/src/TableBody/TableBody.tsx +++ b/packages/table/src/TableBody/TableBody.tsx @@ -19,13 +19,13 @@ const TableBody = ({ children, ...rest }: TableBodyProps) => { <> {paddingTop > 0 && (
- )} {children} {paddingBottom > 0 && ( - )} diff --git a/packages/table/src/useLeafyGreenVirtualTable/useLeafyGreenVirtualTable.tsx b/packages/table/src/useLeafyGreenVirtualTable/useLeafyGreenVirtualTable.tsx index 81bfe48991..013a8b792f 100644 --- a/packages/table/src/useLeafyGreenVirtualTable/useLeafyGreenVirtualTable.tsx +++ b/packages/table/src/useLeafyGreenVirtualTable/useLeafyGreenVirtualTable.tsx @@ -42,14 +42,31 @@ function useLeafyGreenVirtualTable< (index: number) => rows[index]?.id ?? index, [rows], ), - measureElement: - typeof window !== 'undefined' && - navigator.userAgent.indexOf('Firefox') === -1 - ? element => element?.getBoundingClientRect().height - : undefined, + // measureElement: (element, entry, instance) => { + // const direction = instance.scrollDirection + // if (direction === "forward" || direction === null) { + // return element.scrollHeight + // } else { + // // don't remeasure if we are scrolling up + // const indexKey = Number(element.getAttribute("data-index")) + // let cacheMeasurement = instance.itemSizeCache.get(indexKey) + // return cacheMeasurement + // } + // } + // measureElement: + // typeof window !== 'undefined' && + // navigator.userAgent.indexOf('Firefox') === -1 + // ? element => element?.getBoundingClientRect().height + // : undefined, + // onChange: (i, s) => console.log('🪼', { s, i }), + // isScrollingResetDelay: 1000, + // debug: true, ...virtualizerOptions, }); + // Kill the cache entirely to prevent weird scrolling issues. This is a hack + // _virtualizer.measurementsCache = []; + const _virtualItems: Array> = _virtualizer .getVirtualItems() .map((virtualRow: VirtualItem) => ({ From b5474aa3c89ef4016d2156c274773105cf961f50 Mon Sep 17 00:00:00 2001 From: Shaneeza Date: Fri, 1 Nov 2024 14:11:32 -0400 Subject: [PATCH 049/113] tbody updates --- packages/table/package.json | 2 +- packages/table/src/Table/Table.tsx | 1 + packages/table/src/TableBody/TableBody.tsx | 17 +++++++++++------ .../table/src/TableContext/TableContext.tsx | 1 + 4 files changed, 14 insertions(+), 7 deletions(-) diff --git a/packages/table/package.json b/packages/table/package.json index de9f0131fc..4d910caa80 100644 --- a/packages/table/package.json +++ b/packages/table/package.json @@ -1,6 +1,6 @@ { "name": "@leafygreen-ui/table", - "version": "13.0.0-beta.1", + "version": "12.7.0-test.2", "description": "leafyGreen UI Kit Table", "main": "./dist/index.js", "module": "./dist/esm/index.js", diff --git a/packages/table/src/Table/Table.tsx b/packages/table/src/Table/Table.tsx index 14f7be69c9..07b72891e2 100644 --- a/packages/table/src/Table/Table.tsx +++ b/packages/table/src/Table/Table.tsx @@ -1,3 +1,4 @@ +// @ts-nocheck import React, { ForwardedRef, forwardRef } from 'react'; import PropTypes from 'prop-types'; diff --git a/packages/table/src/TableBody/TableBody.tsx b/packages/table/src/TableBody/TableBody.tsx index 15992d3e00..fc0fd9b0d7 100644 --- a/packages/table/src/TableBody/TableBody.tsx +++ b/packages/table/src/TableBody/TableBody.tsx @@ -5,6 +5,7 @@ import { useTableContext } from '../TableContext'; import { TableBodyProps } from './TableBody.types'; const TableBody = ({ children, ...rest }: TableBodyProps) => { + // @ts-ignore const { isVirtual, length, start, end, totalSize } = useTableContext(); let paddingTop = 0; @@ -18,15 +19,19 @@ const TableBody = ({ children, ...rest }: TableBodyProps) => { return ( <> {paddingTop > 0 && ( - - + + + + )} {children} {paddingBottom > 0 && ( - - + + + + )} ); diff --git a/packages/table/src/TableContext/TableContext.tsx b/packages/table/src/TableContext/TableContext.tsx index 23bec5bc39..b19fe3aca4 100644 --- a/packages/table/src/TableContext/TableContext.tsx +++ b/packages/table/src/TableContext/TableContext.tsx @@ -1,3 +1,4 @@ +// @ts-nocheck import React, { createContext, PropsWithChildren, From d1571f05d184fe34c3a842878642fc94c9de9467 Mon Sep 17 00:00:00 2001 From: Shaneeza Date: Fri, 1 Nov 2024 17:30:36 -0400 Subject: [PATCH 050/113] css vars --- packages/table/src/Table.stories.tsx | 4 ++-- packages/table/src/TableBody/TableBody.tsx | 12 ++++++++++-- 2 files changed, 12 insertions(+), 4 deletions(-) diff --git a/packages/table/src/Table.stories.tsx b/packages/table/src/Table.stories.tsx index ef1e42d2f1..8c7b6db3cb 100644 --- a/packages/table/src/Table.stories.tsx +++ b/packages/table/src/Table.stories.tsx @@ -97,7 +97,7 @@ const Template: StoryFn = args => { export const LiveExample: StoryFn = args => { const tableContainerRef = React.useRef(null); - const [data] = useState(() => makeKitchenSinkData(500)); + const [data] = useState(() => makeKitchenSinkData(900)); const columns = React.useMemo>>( () => [ @@ -341,7 +341,7 @@ export const NestedRows: StoryFn = args => { export const ExpandableContent: StoryFn = args => { const tableContainerRef = React.useRef(null); - const data = React.useState(() => makeData(true, 100))[0]; + const data = React.useState(() => makeData(true, 2000))[0]; const columns = React.useMemo>>( () => [ diff --git a/packages/table/src/TableBody/TableBody.tsx b/packages/table/src/TableBody/TableBody.tsx index fc0fd9b0d7..b12241bb49 100644 --- a/packages/table/src/TableBody/TableBody.tsx +++ b/packages/table/src/TableBody/TableBody.tsx @@ -13,7 +13,15 @@ const TableBody = ({ children, ...rest }: TableBodyProps) => { if (isVirtual) { paddingTop = length > 0 ? start || 0 : 0; + document.documentElement.style.setProperty( + '--virtual-padding-top', + `${paddingTop}px`, + ); paddingBottom = length > 0 ? totalSize - (end || 0) : 0; + document.documentElement.style.setProperty( + '--virtual-padding-bottom', + `${paddingBottom}px`, + ); } return ( @@ -21,7 +29,7 @@ const TableBody = ({ children, ...rest }: TableBodyProps) => { {paddingTop > 0 && ( - )} @@ -29,7 +37,7 @@ const TableBody = ({ children, ...rest }: TableBodyProps) => { {paddingBottom > 0 && ( - )} From 9c78c259c07218bd060a4438e8a41185e36af35a Mon Sep 17 00:00:00 2001 From: Shaneeza Date: Mon, 4 Nov 2024 12:52:44 -0500 Subject: [PATCH 051/113] add virtual context --- .../src/ExpandedContent/ExpandedContent.tsx | 4 +- packages/table/src/Row/Row.tsx | 5 +- packages/table/src/Table/Table.tsx | 10 +++ .../table/src/TableBody/TableBody.styles.ts | 9 +++ packages/table/src/TableBody/TableBody.tsx | 47 +++++++++----- .../table/src/TableContext/TableContext.tsx | 46 +++++++------- .../src/TableContext/TableContext.types.ts | 62 +++++++++++-------- .../src/TableContext/VirtualTableContext.tsx | 52 ++++++++++++++++ packages/table/src/TableContext/index.ts | 17 ++++- 9 files changed, 183 insertions(+), 69 deletions(-) create mode 100644 packages/table/src/TableBody/TableBody.styles.ts create mode 100644 packages/table/src/TableContext/VirtualTableContext.tsx diff --git a/packages/table/src/ExpandedContent/ExpandedContent.tsx b/packages/table/src/ExpandedContent/ExpandedContent.tsx index ecf6e32900..ab391b2e64 100644 --- a/packages/table/src/ExpandedContent/ExpandedContent.tsx +++ b/packages/table/src/ExpandedContent/ExpandedContent.tsx @@ -7,7 +7,7 @@ import { useDarkMode } from '@leafygreen-ui/leafygreen-provider'; import { getCellContainerStyles } from '../Cell/Cell.styles'; import { LGIDS } from '../constants'; import InternalRowBase from '../Row/InternalRowBase'; -import { useTableContext } from '../TableContext'; +import { useVirtualTableContext } from '../TableContext'; import { baseStyles, expandedContentStyles } from './ExpandedContent.styles'; import { ExpandedContentProps } from './ExpandedContent.types'; @@ -17,7 +17,7 @@ const ExpandedContent = ({ virtualRow, ...rest }: ExpandedContentProps) => { - const { measureElement } = useTableContext(); + const { measureElement } = useVirtualTableContext(); const content = row.original.renderExpandedContent && diff --git a/packages/table/src/Row/Row.tsx b/packages/table/src/Row/Row.tsx index fc78111d2b..0cd0cba8f0 100644 --- a/packages/table/src/Row/Row.tsx +++ b/packages/table/src/Row/Row.tsx @@ -3,7 +3,7 @@ import PropTypes from 'prop-types'; import { useDarkMode } from '@leafygreen-ui/leafygreen-provider'; -import { useTableContext } from '../TableContext'; +import { useTableContext, useVirtualTableContext } from '../TableContext'; import { LGRowData } from '../useLeafyGreenTable'; import InternalRowWithoutRT from './InternalRowWithoutRT'; @@ -19,7 +19,8 @@ const Row = ({ ...rest }: RowProps) => { const { theme } = useDarkMode(); - const { measureElement, shouldAlternateRowColor } = useTableContext(); + const { shouldAlternateRowColor } = useTableContext(); + const { measureElement } = useVirtualTableContext(); return ( <> {row ? ( diff --git a/packages/table/src/Table/Table.tsx b/packages/table/src/Table/Table.tsx index 07b72891e2..41efaf0b4d 100644 --- a/packages/table/src/Table/Table.tsx +++ b/packages/table/src/Table/Table.tsx @@ -60,6 +60,12 @@ const Table = forwardRef>( ? (table as LeafyGreenVirtualTable).virtual.measureElement : undefined; + const numOfVirtualItems = virtualTable?.virtualItems.length; + const startOfFirstVirtualItem = virtualTable?.virtualItems[0]?.start; + const endOfLastVirtualItem = + virtualTable?.virtualItems[virtualTable?.virtualItems.length - 1]?.end; + const totalSizOfVirtualTable = virtualTable?.getTotalSize(); + const length = virtualTable?.virtualItems.length; const start = virtualTable?.virtualItems[0]?.start; const size = virtualTable?.virtualItems[0]?.size; @@ -101,6 +107,10 @@ const Table = forwardRef>( size={size} end={end} totalSize={totalSize} + numOfVirtualItems={numOfVirtualItems} + startOfFirstVirtualItem={startOfFirstVirtualItem} + endOfLastVirtualItem={endOfLastVirtualItem} + totalSizOfVirtualTable={totalSizOfVirtualTable} >
+
+
+
+
-
+
-
+
+
+
{ - // @ts-ignore - const { isVirtual, length, start, end, totalSize } = useTableContext(); + const { isVirtual } = useTableContext(); + const { + numOfVirtualItems = 0, + startOfFirstVirtualItem = 0, + endOfLastVirtualItem = 0, + totalSizOfVirtualTable = 0, + } = useVirtualTableContext(); + + const topRef = useRef(null); + const bottomRef = useRef(null); let paddingTop = 0; let paddingBottom = 0; if (isVirtual) { - paddingTop = length > 0 ? start || 0 : 0; - document.documentElement.style.setProperty( - '--virtual-padding-top', - `${paddingTop}px`, - ); - paddingBottom = length > 0 ? totalSize - (end || 0) : 0; - document.documentElement.style.setProperty( - '--virtual-padding-bottom', - `${paddingBottom}px`, - ); + paddingTop = numOfVirtualItems > 0 ? startOfFirstVirtualItem || 0 : 0; + topRef.current && + topRef.current.style.setProperty( + '--virtual-padding-top', + `${paddingTop}px`, + ); + paddingBottom = + numOfVirtualItems > 0 + ? totalSizOfVirtualTable - (endOfLastVirtualItem || 0) + : 0; + bottomRef.current && + bottomRef.current.style.setProperty( + '--virtual-padding-bottom', + `${paddingBottom}px`, + ); } return ( <> + {/* As the user scrolls down, the paddingTop grows bigger, creating the effect of virtual scrolling */} {paddingTop > 0 && ( - )} {children} + {/* As the user scrolls down, the paddingBottom gets smaller, creating the effect of virtual scrolling */} {paddingBottom > 0 && ( - )} diff --git a/packages/table/src/TableContext/TableContext.tsx b/packages/table/src/TableContext/TableContext.tsx index b19fe3aca4..23cdd556d3 100644 --- a/packages/table/src/TableContext/TableContext.tsx +++ b/packages/table/src/TableContext/TableContext.tsx @@ -1,4 +1,3 @@ -// @ts-nocheck import React, { createContext, PropsWithChildren, @@ -10,7 +9,11 @@ import LeafyGreenProvider from '@leafygreen-ui/leafygreen-provider'; import { LGRowData } from '../useLeafyGreenTable'; -import { type TableContextValues } from './TableContext.types'; +import { + type TableContextValues, + type TableProviderValues, +} from './TableContext.types'; +import VirtualTableContextProvider from './VirtualTableContext'; export const TableContext = createContext< Partial> @@ -29,47 +32,44 @@ const TableContextProvider = ({ isSelectable, measureElement, shouldTruncate, - length, - start, - size, - end, - totalSize, -}: PropsWithChildren>>) => { + numOfVirtualItems, + startOfFirstVirtualItem, + endOfLastVirtualItem, + totalSizOfVirtualTable, +}: PropsWithChildren>>) => { /** The appropriately typed context provider */ - const TableProvider = (TableContext as React.Context>) + const TableProvider = (TableContext as React.Context>) .Provider; - const providerData = useMemo(() => { + const tableProviderData = useMemo(() => { return { shouldAlternateRowColor, darkMode, isVirtual, isSelectable, - measureElement, shouldTruncate, - length, - start, - size, - end, - totalSize, }; }, [ shouldAlternateRowColor, darkMode, isVirtual, isSelectable, - measureElement, shouldTruncate, - length, - start, - size, - end, - totalSize, ]); return ( - {children} + + + {children} + + ); }; diff --git a/packages/table/src/TableContext/TableContext.types.ts b/packages/table/src/TableContext/TableContext.types.ts index 8e9724bf5c..705178ae00 100644 --- a/packages/table/src/TableContext/TableContext.types.ts +++ b/packages/table/src/TableContext/TableContext.types.ts @@ -4,33 +4,45 @@ import { Virtualizer } from '@tanstack/react-virtual'; import { DarkModeProps } from '@leafygreen-ui/lib'; import { TableProps } from '../Table/Table.types'; -import { - LeafyGreenTable, - LeafyGreenTableRow, - LGRowData, -} from '../useLeafyGreenTable'; +import { LeafyGreenTable, LGRowData } from '../useLeafyGreenTable'; + +export interface SharedVirtualContextValue { + measureElement?: Virtualizer['measureElement']; + numOfVirtualItems?: number; + startOfFirstVirtualItem?: number; + endOfLastVirtualItem?: number; + totalSizOfVirtualTable?: number; +} + +export interface BaseTableContextValue { + /** + * The `useLeafyGreenTable` return value + */ + table?: LeafyGreenTable; + + /** + * Whether the table is using virtual scrolling + */ + isVirtual?: boolean; + + /** + * Whether rows in the table are selectable + */ + isSelectable?: boolean; +} + +export type TableProviderValues = PropsWithChildren< + Pick, 'shouldAlternateRowColor' | 'shouldTruncate'> +> & + DarkModeProps & + SharedVirtualContextValue & + BaseTableContextValue; export type TableContextValues = PropsWithChildren< Pick, 'shouldAlternateRowColor' | 'shouldTruncate'> > & - DarkModeProps & { - /** returns the table row object with the provided `id` */ - getRowById?: (id?: string) => LeafyGreenTableRow | undefined; - - /** returns the parent table row object for the provided `id` if it is nested */ - getParentRow?: (id?: string) => LeafyGreenTableRow | undefined; - - /** - * The `useLeafyGreenTable` return value - */ - table?: LeafyGreenTable; - - /** - * Whether the table is using virtual scrolling - */ - isVirtual?: boolean; - - isSelectable?: boolean; + DarkModeProps & + BaseTableContextValue; - measureElement?: Virtualizer['measureElement']; - }; +export type VirtualTableContextValues = PropsWithChildren & + SharedVirtualContextValue; diff --git a/packages/table/src/TableContext/VirtualTableContext.tsx b/packages/table/src/TableContext/VirtualTableContext.tsx new file mode 100644 index 0000000000..f20b5a0ac4 --- /dev/null +++ b/packages/table/src/TableContext/VirtualTableContext.tsx @@ -0,0 +1,52 @@ +import React, { + createContext, + PropsWithChildren, + useContext, + useMemo, +} from 'react'; + +import { type VirtualTableContextValues } from './TableContext.types'; + +export const VirtualTableContext = createContext< + Partial +>({}); + +export const useVirtualTableContext = () => + useContext( + VirtualTableContext as React.Context, + ); + +const VirtualTableContextProvider = ({ + children, + measureElement, + numOfVirtualItems, + startOfFirstVirtualItem, + endOfLastVirtualItem, + totalSizOfVirtualTable, +}: PropsWithChildren>) => { + const VirtualTableProvider = ( + VirtualTableContext as React.Context + ).Provider; + + const providerData = useMemo(() => { + return { + measureElement, + numOfVirtualItems, + startOfFirstVirtualItem, + endOfLastVirtualItem, + totalSizOfVirtualTable, + }; + }, [ + measureElement, + numOfVirtualItems, + startOfFirstVirtualItem, + endOfLastVirtualItem, + totalSizOfVirtualTable, + ]); + + return ( + {children} + ); +}; + +export default VirtualTableContextProvider; diff --git a/packages/table/src/TableContext/index.ts b/packages/table/src/TableContext/index.ts index 97474effb7..66a8626c4e 100644 --- a/packages/table/src/TableContext/index.ts +++ b/packages/table/src/TableContext/index.ts @@ -1,4 +1,17 @@ import TableContextProvider, { useTableContext } from './TableContext'; -import { type TableContextValues } from './TableContext.types'; +import type { + TableContextValues, + VirtualTableContextValues, +} from './TableContext.types'; +import VirtualTableContextProvider, { + useVirtualTableContext, +} from './VirtualTableContext'; -export { TableContextProvider, type TableContextValues, useTableContext }; +export { + TableContextProvider, + type TableContextValues, + useTableContext, + useVirtualTableContext, + VirtualTableContextProvider, + type VirtualTableContextValues, +}; From ece7167ff57ed895ee4549fac39ef9615951fc94 Mon Sep 17 00:00:00 2001 From: Shaneeza Date: Mon, 4 Nov 2024 12:55:37 -0500 Subject: [PATCH 052/113] remove comment --- packages/table/src/Table/TableWithVS.stories.tsx | 1 - 1 file changed, 1 deletion(-) diff --git a/packages/table/src/Table/TableWithVS.stories.tsx b/packages/table/src/Table/TableWithVS.stories.tsx index ef9e3a9b49..7eb96c8dc3 100644 --- a/packages/table/src/Table/TableWithVS.stories.tsx +++ b/packages/table/src/Table/TableWithVS.stories.tsx @@ -673,7 +673,6 @@ export const DifferentHeights: StoryFn = args => { [], ); - // FIXME: this table becomes SUPER flickery scrolling up when a lot of rows are expanded //TODO: fix type const table = useLeafyGreenVirtualTable({ containerRef: tableContainerRef, From 960be7b6c18654a5121a78246669fd96751c7490 Mon Sep 17 00:00:00 2001 From: Shaneeza Date: Mon, 4 Nov 2024 13:10:07 -0500 Subject: [PATCH 053/113] remove measureElement from hook --- packages/table/src/Table/Table.styles.ts | 43 +-------- packages/table/src/Table/Table.tsx | 93 ++++++------------- .../useLeafyGreenVirtualTable.tsx | 22 ----- 3 files changed, 27 insertions(+), 131 deletions(-) diff --git a/packages/table/src/Table/Table.styles.ts b/packages/table/src/Table/Table.styles.ts index f47fe64ae3..5efb933f61 100644 --- a/packages/table/src/Table/Table.styles.ts +++ b/packages/table/src/Table/Table.styles.ts @@ -1,4 +1,4 @@ -import { css, cx } from '@leafygreen-ui/emotion'; +import { css } from '@leafygreen-ui/emotion'; import { Theme } from '@leafygreen-ui/lib'; import { palette } from '@leafygreen-ui/palette'; @@ -6,12 +6,6 @@ export const baseStyles = css` border-spacing: 0; border-collapse: collapse; width: 100%; - - &:after { - content: ''; - display: block; - height: var(--pseudo-height); - } `; export const themeStyles: Record = { @@ -28,38 +22,3 @@ export const tableContainerStyles = css` width: 100%; position: relative; `; - -export const getVirtualStyles = (isVirtual = false, totalSize: number) => - cx({ - [css` - position: relative; - /* height: ${totalSize}px; */ - `]: isVirtual, - }); - -// export const getVirtualDynamicStyles = ( -// isVirtual = false, -// startPosition: number, -// ) => -// cx( -// { -// [ -// css` -// /* position: absolute; -// top: 0; -// left: 0; -// transform: translate3d(0, ${startPosition}px, 0); -// width: 100%; */ - -// thead { -// /* top: -${startPosition}px; */ -// /* transform: translate3d(0, ${startPosition / 2}px, 0); */ -// /* top: 0; */ -// /* position: absolute; */ -// } -// ` - -// ]:isVirtual -// } -// ) -// `; diff --git a/packages/table/src/Table/Table.tsx b/packages/table/src/Table/Table.tsx index 41efaf0b4d..0005973cad 100644 --- a/packages/table/src/Table/Table.tsx +++ b/packages/table/src/Table/Table.tsx @@ -1,4 +1,3 @@ -// @ts-nocheck import React, { ForwardedRef, forwardRef } from 'react'; import PropTypes from 'prop-types'; @@ -15,13 +14,7 @@ import { TableContextProvider } from '../TableContext'; import { LGRowData } from '../useLeafyGreenTable'; import { LeafyGreenVirtualTable } from '../useLeafyGreenVirtualTable/useLeafyGreenVirtualTable.types'; -import { - baseStyles, - // getVirtualDynamicStyles, - getVirtualStyles, - tableContainerStyles, - themeStyles, -} from './Table.styles'; +import { baseStyles, tableContainerStyles, themeStyles } from './Table.styles'; import { TableProps } from './Table.types'; // Inferred generic type from component gets used in place of `any` @@ -42,45 +35,23 @@ const Table = forwardRef>( ) => { const baseFontSize: BaseFontSize = useUpdatedBaseFontSize(baseFontSizeProp); const { theme, darkMode } = useDarkMode(darkModeProp); - //TODO: find a better way to do all these checks + const isVirtual = table && (table as LeafyGreenVirtualTable).virtual ? true : false; const virtualTable = isVirtual ? (table as LeafyGreenVirtualTable)!.virtual : undefined; - const virtualTableTotalSize = virtualTable - ? virtualTable.getTotalSize() - : 0; - // TODO: look into scroll position instead of start position - diff PR - const virtualTableStart = virtualTable - ? virtualTable.getVirtualItems()[0]?.start - : 0; const isSelectable = table ? table.hasSelectableRows : false; + const measureElement = isVirtual ? (table as LeafyGreenVirtualTable).virtual.measureElement : undefined; - const numOfVirtualItems = virtualTable?.virtualItems.length; const startOfFirstVirtualItem = virtualTable?.virtualItems[0]?.start; const endOfLastVirtualItem = virtualTable?.virtualItems[virtualTable?.virtualItems.length - 1]?.end; const totalSizOfVirtualTable = virtualTable?.getTotalSize(); - const length = virtualTable?.virtualItems.length; - const start = virtualTable?.virtualItems[0]?.start; - const size = virtualTable?.virtualItems[0]?.size; - const end = - virtualTable?.virtualItems[virtualTable?.virtualItems.length - 1]?.end; - const totalSize = virtualTable?.getTotalSize(); - - // console.log({ - // length, - // start, - // size, - // end, - // totalSize, - // }); - return (
>( // eslint-disable-next-line jsx-a11y/no-noninteractive-tabindex tabIndex={0} > -
-
- -
+
+
- {children} -
- -
-
+ {children} + +
); }, ); +// TODO: proptypes Table.propTypes = { darkMode: PropTypes.bool, baseFontSize: PropTypes.oneOf(Object.values(BaseFontSize)), diff --git a/packages/table/src/useLeafyGreenVirtualTable/useLeafyGreenVirtualTable.tsx b/packages/table/src/useLeafyGreenVirtualTable/useLeafyGreenVirtualTable.tsx index 013a8b792f..3e977a4d23 100644 --- a/packages/table/src/useLeafyGreenVirtualTable/useLeafyGreenVirtualTable.tsx +++ b/packages/table/src/useLeafyGreenVirtualTable/useLeafyGreenVirtualTable.tsx @@ -42,31 +42,9 @@ function useLeafyGreenVirtualTable< (index: number) => rows[index]?.id ?? index, [rows], ), - // measureElement: (element, entry, instance) => { - // const direction = instance.scrollDirection - // if (direction === "forward" || direction === null) { - // return element.scrollHeight - // } else { - // // don't remeasure if we are scrolling up - // const indexKey = Number(element.getAttribute("data-index")) - // let cacheMeasurement = instance.itemSizeCache.get(indexKey) - // return cacheMeasurement - // } - // } - // measureElement: - // typeof window !== 'undefined' && - // navigator.userAgent.indexOf('Firefox') === -1 - // ? element => element?.getBoundingClientRect().height - // : undefined, - // onChange: (i, s) => console.log('🪼', { s, i }), - // isScrollingResetDelay: 1000, - // debug: true, ...virtualizerOptions, }); - // Kill the cache entirely to prevent weird scrolling issues. This is a hack - // _virtualizer.measurementsCache = []; - const _virtualItems: Array> = _virtualizer .getVirtualItems() .map((virtualRow: VirtualItem) => ({ From 36a02ee90238223f367f8206a96a0c12a29e93c1 Mon Sep 17 00:00:00 2001 From: Shaneeza Date: Mon, 4 Nov 2024 15:47:53 -0500 Subject: [PATCH 054/113] row context updates --- .../table/src/Cell/InternalCellWithRT.tsx | 12 +++------ packages/table/src/Row/InternalRowWithRT.tsx | 12 +++++++-- .../table/src/Row/InternalRowWithoutRT.tsx | 7 ----- packages/table/src/Row/Row.tsx | 7 ++++- packages/table/src/Row/RowContext.tsx | 23 ++++++++++++++-- .../table/src/utils/areAncestorsExpanded.ts | 26 ------------------- 6 files changed, 41 insertions(+), 46 deletions(-) delete mode 100644 packages/table/src/utils/areAncestorsExpanded.ts diff --git a/packages/table/src/Cell/InternalCellWithRT.tsx b/packages/table/src/Cell/InternalCellWithRT.tsx index 7e1b6c47d3..14d7ad2715 100644 --- a/packages/table/src/Cell/InternalCellWithRT.tsx +++ b/packages/table/src/Cell/InternalCellWithRT.tsx @@ -19,14 +19,10 @@ const InternalCellWithRT = ({ cell, ...rest }: InternalCellWithRTProps) => { - const { disabled } = useRowContext(); + const { disabled, isExpanded, isExpandable, depth, toggleExpanded } = + useRowContext(); const { isSelectable, shouldTruncate = true } = useTableContext(); const isFirstCell = (cell && cell.column.getIsFirstColumn()) || false; - const row = cell.row; - const isExpandable = row.getCanExpand(); - const isExpanded = row.getIsExpanded(); - const depth = row.depth; - const toggleExpanded = () => row.toggleExpanded(); return ( ({ > {isFirstCell && isExpandable && ( )} diff --git a/packages/table/src/Row/InternalRowWithRT.tsx b/packages/table/src/Row/InternalRowWithRT.tsx index a394ebe818..00176c1fbf 100644 --- a/packages/table/src/Row/InternalRowWithRT.tsx +++ b/packages/table/src/Row/InternalRowWithRT.tsx @@ -1,4 +1,4 @@ -import React, { useMemo } from 'react'; +import React, { useCallback, useMemo } from 'react'; import isEqual from 'react-fast-compare'; import { cx } from '@leafygreen-ui/emotion'; @@ -34,11 +34,19 @@ const InternalRowWithRT = ({ }: InternalRowWithRTProps) => { const isOddVSRow = !!virtualRow && virtualRow.index % 2 !== 0; + const isExpandable = row.getCanExpand(); + const depth = row.depth; + const toggleExpanded = useCallback(() => row.toggleExpanded(), [row]); + const contextValues = useMemo(() => { return { disabled, + isExpanded, + isExpandable, + depth, + toggleExpanded, }; - }, [disabled]); + }, [depth, disabled, isExpandable, isExpanded, toggleExpanded]); // eslint-disable-next-line no-console // console.log(`🪼rerender🪼 row: ${row.id}, depth: ${row.depth}`); diff --git a/packages/table/src/Row/InternalRowWithoutRT.tsx b/packages/table/src/Row/InternalRowWithoutRT.tsx index 7c680ad572..082f06300d 100644 --- a/packages/table/src/Row/InternalRowWithoutRT.tsx +++ b/packages/table/src/Row/InternalRowWithoutRT.tsx @@ -21,13 +21,6 @@ const InternalRowWithoutRT = ({ const { shouldAlternateRowColor } = useTableContext(); const { theme } = useDarkMode(); - React.Children.forEach(children, child => { - if (!isComponentType(child, 'Cell')) - consoleOnce.warn( - 'LG Row is rendering a custom cell element. Utilize the `Cell` component for standardized styles, correct HTML properties and additional functionalities when using `useLeafyGreenTable`.', - ); - }); - return ( ({ row, virtualRow, + disabled = false, ...rest }: RowProps) => { const { theme } = useDarkMode(); @@ -38,10 +40,13 @@ const Row = ({ row.getParentRow() ? row.getParentRow()?.getIsExpanded() : false } isSelected={row.getIsSelected()} + disabled={disabled} {...rest} /> ) : ( - + + + )} ); diff --git a/packages/table/src/Row/RowContext.tsx b/packages/table/src/Row/RowContext.tsx index e043b12c21..f76594d991 100644 --- a/packages/table/src/Row/RowContext.tsx +++ b/packages/table/src/Row/RowContext.tsx @@ -7,20 +7,39 @@ import React, { type RowContextProps = PropsWithChildren<{ disabled: boolean; + isExpandable?: boolean; + isExpanded?: boolean; + depth?: number; + toggleExpanded?: () => void; }>; const RowContext = createContext({ disabled: false, + isExpandable: false, + isExpanded: false, + depth: 0, + toggleExpanded: () => {}, }); export const useRowContext = () => useContext(RowContext); -export const RowContextProvider = ({ children, disabled }: RowContextProps) => { +export const RowContextProvider = ({ + children, + disabled, + isExpandable, + isExpanded, + depth, + toggleExpanded, +}: RowContextProps) => { const providerData = useMemo(() => { return { disabled, + isExpanded, + isExpandable, + depth, + toggleExpanded, }; - }, [disabled]); + }, [depth, disabled, isExpandable, isExpanded, toggleExpanded]); return ( {children} diff --git a/packages/table/src/utils/areAncestorsExpanded.ts b/packages/table/src/utils/areAncestorsExpanded.ts deleted file mode 100644 index 9fdcbef7a6..0000000000 --- a/packages/table/src/utils/areAncestorsExpanded.ts +++ /dev/null @@ -1,26 +0,0 @@ -import { type TableContextValues } from '../TableContext'; -import { LGRowData } from '../useLeafyGreenTable'; - -/** - * Returns whether a given row has _all_ ancestor rows expanded - */ -export function getAreAncestorsExpanded( - /** The starting id */ - startId: string, - /** The parent getter function */ - getParentRow: TableContextValues['getParentRow'], -) { - if (!getParentRow) return false; - - let id = startId; - let parent = getParentRow(id); - let isExpanded; - - while (parent) { - isExpanded = (isExpanded ?? true) && parent?.getIsExpanded(); - id = parent.id; - parent = getParentRow(id); - } - - return isExpanded; -} From d1fe64c72f9e4cbabee07abe3e0e9dc393da123b Mon Sep 17 00:00:00 2001 From: Shaneeza Date: Mon, 4 Nov 2024 15:54:20 -0500 Subject: [PATCH 055/113] remove overflow from regular table --- packages/table/src/Row/InternalRowWithRT.tsx | 5 ----- packages/table/src/Table.stories.tsx | 2 +- packages/table/src/Table/Table.styles.ts | 19 +++++++++++++------ packages/table/src/Table/Table.tsx | 2 +- .../src/decorators/ComponentPreview.tsx | 1 - 5 files changed, 15 insertions(+), 14 deletions(-) diff --git a/packages/table/src/Row/InternalRowWithRT.tsx b/packages/table/src/Row/InternalRowWithRT.tsx index 00176c1fbf..659c73de96 100644 --- a/packages/table/src/Row/InternalRowWithRT.tsx +++ b/packages/table/src/Row/InternalRowWithRT.tsx @@ -89,11 +89,6 @@ const arePropsEqual = (prevProps, nextProps) => { const propsAreEqual = isEqual(restPrevProps, restnextProps); - // console.log('🧤', { - // children: prevProps.children === nextProps.children, - // propsWithoutChildren: isEqual(restPrevProps, restnextProps), - // }); - return propsAreEqual; }; diff --git a/packages/table/src/Table.stories.tsx b/packages/table/src/Table.stories.tsx index 8c7b6db3cb..b27ff6e29e 100644 --- a/packages/table/src/Table.stories.tsx +++ b/packages/table/src/Table.stories.tsx @@ -178,7 +178,7 @@ export const LiveExample: StoryFn = args => { width: 1100px; `} > - + {table.getHeaderGroups().map((headerGroup: HeaderGroup) => ( {headerGroup.headers.map(header => { diff --git a/packages/table/src/Table/Table.styles.ts b/packages/table/src/Table/Table.styles.ts index 5efb933f61..7dd1803524 100644 --- a/packages/table/src/Table/Table.styles.ts +++ b/packages/table/src/Table/Table.styles.ts @@ -1,4 +1,4 @@ -import { css } from '@leafygreen-ui/emotion'; +import { css, cx } from '@leafygreen-ui/emotion'; import { Theme } from '@leafygreen-ui/lib'; import { palette } from '@leafygreen-ui/palette'; @@ -17,8 +17,15 @@ export const themeStyles: Record = { `, }; -export const tableContainerStyles = css` - overflow: auto; - width: 100%; - position: relative; -`; +export const tableContainerStyles = (isVirtual = false) => + cx( + css` + width: 100%; + position: relative; + `, + { + [css` + overflow: auto; + `]: isVirtual, + }, + ); diff --git a/packages/table/src/Table/Table.tsx b/packages/table/src/Table/Table.tsx index 0005973cad..ac7cc1845a 100644 --- a/packages/table/src/Table/Table.tsx +++ b/packages/table/src/Table/Table.tsx @@ -55,7 +55,7 @@ const Table = forwardRef>( return (
Date: Tue, 5 Nov 2024 11:44:58 -0500 Subject: [PATCH 056/113] updates virtual types --- .../src/ExpandedContent/ExpandedContent.tsx | 4 +- .../table/src/Row/InternalRowWithoutRT.tsx | 1 - packages/table/src/Row/Row.tsx | 4 +- packages/table/src/Table/Table.tsx | 15 +- .../table/src/Table/TableWithVS.stories.tsx | 136 +++++++++--------- packages/table/src/TableBody/TableBody.tsx | 21 +-- .../table/src/TableContext/TableContext.tsx | 14 +- .../src/TableContext/TableContext.types.ts | 6 +- .../src/TableContext/VirtualTableContext.tsx | 20 +-- .../useLeafyGreenTable/useLeafyGreenTable.tsx | 7 - .../useLeafyGreenVirtualTable.tsx | 2 +- .../useLeafyGreenVirtualTable.types.ts | 16 ++- 12 files changed, 106 insertions(+), 140 deletions(-) diff --git a/packages/table/src/ExpandedContent/ExpandedContent.tsx b/packages/table/src/ExpandedContent/ExpandedContent.tsx index ab391b2e64..8285b163b1 100644 --- a/packages/table/src/ExpandedContent/ExpandedContent.tsx +++ b/packages/table/src/ExpandedContent/ExpandedContent.tsx @@ -17,7 +17,7 @@ const ExpandedContent = ({ virtualRow, ...rest }: ExpandedContentProps) => { - const { measureElement } = useVirtualTableContext(); + const { virtualTable } = useVirtualTableContext(); const content = row.original.renderExpandedContent && @@ -34,7 +34,7 @@ const ExpandedContent = ({ ref={node => { // TODO: fix me // This gets the dynamic size of the element - if (measureElement) measureElement(node); + if (virtualTable) virtualTable.measureElement(node); }} data-index={virtualRow ? virtualRow!.index : ''} > diff --git a/packages/table/src/Row/InternalRowWithoutRT.tsx b/packages/table/src/Row/InternalRowWithoutRT.tsx index 082f06300d..123b34f050 100644 --- a/packages/table/src/Row/InternalRowWithoutRT.tsx +++ b/packages/table/src/Row/InternalRowWithoutRT.tsx @@ -2,7 +2,6 @@ import React from 'react'; import { cx } from '@leafygreen-ui/emotion'; import { useDarkMode } from '@leafygreen-ui/leafygreen-provider'; -import { consoleOnce, isComponentType } from '@leafygreen-ui/lib'; import { useTableContext } from '../TableContext'; diff --git a/packages/table/src/Row/Row.tsx b/packages/table/src/Row/Row.tsx index b0d5c61ddb..9b165a3c0b 100644 --- a/packages/table/src/Row/Row.tsx +++ b/packages/table/src/Row/Row.tsx @@ -22,7 +22,7 @@ const Row = ({ }: RowProps) => { const { theme } = useDarkMode(); const { shouldAlternateRowColor } = useTableContext(); - const { measureElement } = useVirtualTableContext(); + const { virtualTable } = useVirtualTableContext(); return ( <> {row ? ( @@ -31,7 +31,7 @@ const Row = ({ row={row} virtualRow={virtualRow} theme={theme} - measureElement={measureElement} + measureElement={virtualTable?.measureElement} // @ts-ignore FIXME: shouldAlternateRowColor={shouldAlternateRowColor} isExpanded={row.getIsExpanded()} diff --git a/packages/table/src/Table/Table.tsx b/packages/table/src/Table/Table.tsx index ac7cc1845a..9e03e784a9 100644 --- a/packages/table/src/Table/Table.tsx +++ b/packages/table/src/Table/Table.tsx @@ -43,15 +43,6 @@ const Table = forwardRef>( : undefined; const isSelectable = table ? table.hasSelectableRows : false; - const measureElement = isVirtual - ? (table as LeafyGreenVirtualTable).virtual.measureElement - : undefined; - const numOfVirtualItems = virtualTable?.virtualItems.length; - const startOfFirstVirtualItem = virtualTable?.virtualItems[0]?.start; - const endOfLastVirtualItem = - virtualTable?.virtualItems[virtualTable?.virtualItems.length - 1]?.end; - const totalSizOfVirtualTable = virtualTable?.getTotalSize(); - return (
>( darkMode={darkMode} isVirtual={isVirtual} isSelectable={isSelectable} - measureElement={measureElement} shouldTruncate={shouldTruncate} - numOfVirtualItems={numOfVirtualItems} - startOfFirstVirtualItem={startOfFirstVirtualItem} - endOfLastVirtualItem={endOfLastVirtualItem} - totalSizOfVirtualTable={totalSizOfVirtualTable} + virtualTable={virtualTable} > = args => { ))} - {table.virtual.virtualItems && - table.virtual.virtualItems.map( - (virtualRow: LeafyGreenVirtualItem) => { + {table.virtual.getVirtualItems() && + table.virtual + .getVirtualItems() + .map((virtualRow: LeafyGreenVirtualItem) => { const row = virtualRow.row; const cells = row.getVisibleCells(); return ( @@ -162,8 +163,7 @@ export const Basic: StoryFn = args => { })} ); - }, - )} + })}
@@ -211,9 +211,10 @@ export const NestedRows: StoryFn = args => { ))} - {table.virtual.virtualItems && - table.virtual.virtualItems.map( - (virtualRow: LeafyGreenVirtualItem) => { + {table.virtual.getVirtualItems() && + table.virtual + .getVirtualItems() + .map((virtualRow: LeafyGreenVirtualItem) => { const row = virtualRow.row; const cells = row.getVisibleCells(); @@ -231,8 +232,7 @@ export const NestedRows: StoryFn = args => { })} ); - }, - )} + })} @@ -326,9 +326,10 @@ export const SortableRows: StoryFn = args => { ))} - {table.virtual.virtualItems && - table.virtual.virtualItems.map( - (virtualRow: LeafyGreenVirtualItem) => { + {table.virtual.getVirtualItems() && + table.virtual + .getVirtualItems() + .map((virtualRow: LeafyGreenVirtualItem) => { const row = virtualRow.row; const cells = row.getVisibleCells(); @@ -346,8 +347,7 @@ export const SortableRows: StoryFn = args => { })} ); - }, - )} + })} @@ -400,9 +400,10 @@ export const SelectableRows: StoryFn = args => { ))} - {table.virtual.virtualItems && - table.virtual.virtualItems.map( - (virtualRow: LeafyGreenVirtualItem) => { + {table.virtual.getVirtualItems() && + table.virtual + .getVirtualItems() + .map((virtualRow: LeafyGreenVirtualItem) => { const row = virtualRow.row; const cells = row.getVisibleCells(); @@ -420,8 +421,7 @@ export const SelectableRows: StoryFn = args => { })} ); - }, - )} + })} @@ -474,9 +474,10 @@ export const ExpandableContent: StoryFn = args => { ))} - {table.virtual.virtualItems && - table.virtual.virtualItems.map( - (virtualRow: LeafyGreenVirtualItem) => { + {table.virtual.getVirtualItems() && + table.virtual + .getVirtualItems() + .map((virtualRow: LeafyGreenVirtualItem) => { const row = virtualRow.row; const isExpandedContent = row.original.isExpandedContent ?? false; @@ -504,8 +505,7 @@ export const ExpandableContent: StoryFn = args => { )} ); - }, - )} + })} @@ -563,9 +563,10 @@ export const TallRows: StoryFn = args => { ))} - {table.virtual.virtualItems && - table.virtual.virtualItems.map( - (virtualRow: LeafyGreenVirtualItem) => { + {table.virtual.getVirtualItems() && + table.virtual + .getVirtualItems() + .map((virtualRow: LeafyGreenVirtualItem) => { const row = virtualRow.row; const cells = row.getVisibleCells(); return ( @@ -592,8 +593,7 @@ export const TallRows: StoryFn = args => { })} ); - }, - )} + })} @@ -691,7 +691,7 @@ export const DifferentHeights: StoryFn = args => { table={table} ref={tableContainerRef} className={virtualScrollingContainerHeight} - // shouldTruncate={false} + shouldTruncate={false} > {table.getHeaderGroups().map((headerGroup: HeaderGroup) => ( @@ -710,42 +710,44 @@ export const DifferentHeights: StoryFn = args => { ))} - {table.virtual.virtualItems && - table.virtual.virtualItems.map( - (virtualRow: LeafyGreenVirtualItem, index: number) => { - const row = virtualRow.row; - const isExpandedContent = - row.original.isExpandedContent ?? false; - - return ( - - {!isExpandedContent && ( - - {row - .getVisibleCells() - .map((cell: LeafyGreenTableCell) => { - return ( - - {flexRender( - cell.column.columnDef.cell, - cell.getContext(), - )} - - ); - })} - - )} - {isExpandedContent && ( - - )} - - ); - }, - )} + {table.virtual.getVirtualItems() && + table.virtual + .getVirtualItems() + .map( + (virtualRow: LeafyGreenVirtualItem, index: number) => { + const row = virtualRow.row; + const isExpandedContent = + row.original.isExpandedContent ?? false; + + return ( + + {!isExpandedContent && ( + + {row + .getVisibleCells() + .map((cell: LeafyGreenTableCell) => { + return ( + + {flexRender( + cell.column.columnDef.cell, + cell.getContext(), + )} + + ); + })} + + )} + {isExpandedContent && ( + + )} + + ); + }, + )} diff --git a/packages/table/src/TableBody/TableBody.tsx b/packages/table/src/TableBody/TableBody.tsx index e907395b3d..02a1d63cc3 100644 --- a/packages/table/src/TableBody/TableBody.tsx +++ b/packages/table/src/TableBody/TableBody.tsx @@ -8,12 +8,15 @@ import { TableBodyProps } from './TableBody.types'; const TableBody = ({ children, ...rest }: TableBodyProps) => { const { isVirtual } = useTableContext(); - const { - numOfVirtualItems = 0, - startOfFirstVirtualItem = 0, - endOfLastVirtualItem = 0, - totalSizOfVirtualTable = 0, - } = useVirtualTableContext(); + const { virtualTable } = useVirtualTableContext(); + + const numOfVirtualItems = virtualTable?.getVirtualItems().length || 0; + const startOfFirstVirtualItem = + virtualTable?.getVirtualItems()[0]?.start || 0; + const endOfLastVirtualItem = + virtualTable?.getVirtualItems()[virtualTable?.getVirtualItems().length - 1] + ?.end || 0; + const totalSizOfVirtualTable = virtualTable?.getTotalSize() || 0; const topRef = useRef(null); const bottomRef = useRef(null); @@ -22,16 +25,14 @@ const TableBody = ({ children, ...rest }: TableBodyProps) => { let paddingBottom = 0; if (isVirtual) { - paddingTop = numOfVirtualItems > 0 ? startOfFirstVirtualItem || 0 : 0; + paddingTop = numOfVirtualItems > 0 ? startOfFirstVirtualItem : 0; topRef.current && topRef.current.style.setProperty( '--virtual-padding-top', `${paddingTop}px`, ); paddingBottom = - numOfVirtualItems > 0 - ? totalSizOfVirtualTable - (endOfLastVirtualItem || 0) - : 0; + numOfVirtualItems > 0 ? totalSizOfVirtualTable - endOfLastVirtualItem : 0; bottomRef.current && bottomRef.current.style.setProperty( '--virtual-padding-bottom', diff --git a/packages/table/src/TableContext/TableContext.tsx b/packages/table/src/TableContext/TableContext.tsx index 23cdd556d3..55b7373386 100644 --- a/packages/table/src/TableContext/TableContext.tsx +++ b/packages/table/src/TableContext/TableContext.tsx @@ -30,12 +30,8 @@ const TableContextProvider = ({ shouldAlternateRowColor, isVirtual, isSelectable, - measureElement, shouldTruncate, - numOfVirtualItems, - startOfFirstVirtualItem, - endOfLastVirtualItem, - totalSizOfVirtualTable, + virtualTable, }: PropsWithChildren>>) => { /** The appropriately typed context provider */ const TableProvider = (TableContext as React.Context>) @@ -60,13 +56,7 @@ const TableContextProvider = ({ return ( - + {children} diff --git a/packages/table/src/TableContext/TableContext.types.ts b/packages/table/src/TableContext/TableContext.types.ts index 705178ae00..dca50a7e60 100644 --- a/packages/table/src/TableContext/TableContext.types.ts +++ b/packages/table/src/TableContext/TableContext.types.ts @@ -7,11 +7,7 @@ import { TableProps } from '../Table/Table.types'; import { LeafyGreenTable, LGRowData } from '../useLeafyGreenTable'; export interface SharedVirtualContextValue { - measureElement?: Virtualizer['measureElement']; - numOfVirtualItems?: number; - startOfFirstVirtualItem?: number; - endOfLastVirtualItem?: number; - totalSizOfVirtualTable?: number; + virtualTable?: Virtualizer; } export interface BaseTableContextValue { diff --git a/packages/table/src/TableContext/VirtualTableContext.tsx b/packages/table/src/TableContext/VirtualTableContext.tsx index f20b5a0ac4..defe987156 100644 --- a/packages/table/src/TableContext/VirtualTableContext.tsx +++ b/packages/table/src/TableContext/VirtualTableContext.tsx @@ -18,11 +18,7 @@ export const useVirtualTableContext = () => const VirtualTableContextProvider = ({ children, - measureElement, - numOfVirtualItems, - startOfFirstVirtualItem, - endOfLastVirtualItem, - totalSizOfVirtualTable, + virtualTable, }: PropsWithChildren>) => { const VirtualTableProvider = ( VirtualTableContext as React.Context @@ -30,19 +26,9 @@ const VirtualTableContextProvider = ({ const providerData = useMemo(() => { return { - measureElement, - numOfVirtualItems, - startOfFirstVirtualItem, - endOfLastVirtualItem, - totalSizOfVirtualTable, + virtualTable, }; - }, [ - measureElement, - numOfVirtualItems, - startOfFirstVirtualItem, - endOfLastVirtualItem, - totalSizOfVirtualTable, - ]); + }, [virtualTable]); return ( {children} diff --git a/packages/table/src/useLeafyGreenTable/useLeafyGreenTable.tsx b/packages/table/src/useLeafyGreenTable/useLeafyGreenTable.tsx index 07851a6ac2..d839b6d952 100644 --- a/packages/table/src/useLeafyGreenTable/useLeafyGreenTable.tsx +++ b/packages/table/src/useLeafyGreenTable/useLeafyGreenTable.tsx @@ -50,13 +50,6 @@ function useLeafyGreenTable({ () => [ ...(hasSelectableRows ? [selectColumnConfig as LGColumnDef] : []), ...columnsProp, - // ...columnsProp.map(propColumn => { - // return { - // ...propColumn, - // align: propColumn.align ?? 'left', - // enableSorting: propColumn.enableSorting ?? false, - // } as LGColumnDef; - // }), ], [columnsProp, hasSelectableRows, selectColumnConfig], ); diff --git a/packages/table/src/useLeafyGreenVirtualTable/useLeafyGreenVirtualTable.tsx b/packages/table/src/useLeafyGreenVirtualTable/useLeafyGreenVirtualTable.tsx index 3e977a4d23..cb99b1fe79 100644 --- a/packages/table/src/useLeafyGreenVirtualTable/useLeafyGreenVirtualTable.tsx +++ b/packages/table/src/useLeafyGreenVirtualTable/useLeafyGreenVirtualTable.tsx @@ -54,7 +54,7 @@ function useLeafyGreenVirtualTable< return { ...table, - virtual: { ..._virtualizer, virtualItems: _virtualItems }, + virtual: { ..._virtualizer, getVirtualItems: () => _virtualItems }, } as LeafyGreenVirtualTable; } diff --git a/packages/table/src/useLeafyGreenVirtualTable/useLeafyGreenVirtualTable.types.ts b/packages/table/src/useLeafyGreenVirtualTable/useLeafyGreenVirtualTable.types.ts index f6cb3821c1..1987a0fc2b 100644 --- a/packages/table/src/useLeafyGreenVirtualTable/useLeafyGreenVirtualTable.types.ts +++ b/packages/table/src/useLeafyGreenVirtualTable/useLeafyGreenVirtualTable.types.ts @@ -21,7 +21,14 @@ export interface LeafyGreenVirtualTableOptions< T extends LGRowData, V extends unknown = unknown, > extends LeafyGreenTableOptions { + /** + * A ref to the
wrapping + */ containerRef: RefObject; + + /** + * A list of [options](https://tanstack.com/virtual/latest/docs/api/virtualizer) to pass to the virtualizer instance + */ virtualizerOptions?: Partial>; } @@ -30,12 +37,17 @@ export interface LeafyGreenVirtualTableOptions< */ export interface LeafyGreenVirtualTable extends LeafyGreenTable { - // virtualRows?: Array; + /** + * Available [properties and methods](https://tanstack.com/virtual/latest/docs/api/virtualizer#virtualizer-instance) return from the virtulizer instance. + */ virtual: Virtualizer & { - virtualItems: Array>; + getVirtualItems: () => Array>; }; } export type LeafyGreenVirtualItem = TSVirtualItem & { + /** + * The row associated with the virtualItem + */ row: LeafyGreenTableRow; }; From 54b2ccae64ed2ec642ee35795ca414454db98c54 Mon Sep 17 00:00:00 2001 From: Shaneeza Date: Tue, 5 Nov 2024 11:47:18 -0500 Subject: [PATCH 057/113] more TS docs --- packages/table/src/TableContext/TableContext.types.ts | 3 +++ .../useLeafyGreenVirtualTable.types.ts | 2 +- 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/packages/table/src/TableContext/TableContext.types.ts b/packages/table/src/TableContext/TableContext.types.ts index dca50a7e60..710e7e4633 100644 --- a/packages/table/src/TableContext/TableContext.types.ts +++ b/packages/table/src/TableContext/TableContext.types.ts @@ -7,6 +7,9 @@ import { TableProps } from '../Table/Table.types'; import { LeafyGreenTable, LGRowData } from '../useLeafyGreenTable'; export interface SharedVirtualContextValue { + /** + * Available [properties and methods](https://tanstack.com/virtual/latest/docs/api/virtualizer#virtualizer-instance) return from the Virtualizer instance. + */ virtualTable?: Virtualizer; } diff --git a/packages/table/src/useLeafyGreenVirtualTable/useLeafyGreenVirtualTable.types.ts b/packages/table/src/useLeafyGreenVirtualTable/useLeafyGreenVirtualTable.types.ts index 1987a0fc2b..7e5dbef44e 100644 --- a/packages/table/src/useLeafyGreenVirtualTable/useLeafyGreenVirtualTable.types.ts +++ b/packages/table/src/useLeafyGreenVirtualTable/useLeafyGreenVirtualTable.types.ts @@ -38,7 +38,7 @@ export interface LeafyGreenVirtualTableOptions< export interface LeafyGreenVirtualTable extends LeafyGreenTable { /** - * Available [properties and methods](https://tanstack.com/virtual/latest/docs/api/virtualizer#virtualizer-instance) return from the virtulizer instance. + * Available [properties and methods](https://tanstack.com/virtual/latest/docs/api/virtualizer#virtualizer-instance) return from the Virtualizer instance. */ virtual: Virtualizer & { getVirtualItems: () => Array>; From ee730902e9ace7ab2e68e4b56443587a27c649d7 Mon Sep 17 00:00:00 2001 From: Shaneeza Date: Tue, 5 Nov 2024 13:55:11 -0500 Subject: [PATCH 058/113] ts fixes --- packages/table/src/Table.stories.tsx | 9 ++++++--- packages/table/src/Table/TableWithVS.stories.tsx | 6 ++---- .../table/src/TableContext/TableContext.types.ts | 13 ++++++++----- .../src/TableContext/VirtualTableContext.tsx | 16 +++++++++------- .../useLeafyGreenTable/useLeafyGreenTable.tsx | 4 ++-- .../useLeafyGreenTable.types.ts | 5 ++++- .../useLeafyGreenVirtualTable.tsx | 2 ++ .../useLeafyGreenVirtualTable.types.ts | 2 +- 8 files changed, 34 insertions(+), 23 deletions(-) diff --git a/packages/table/src/Table.stories.tsx b/packages/table/src/Table.stories.tsx index b27ff6e29e..b7e7af9f8a 100644 --- a/packages/table/src/Table.stories.tsx +++ b/packages/table/src/Table.stories.tsx @@ -196,7 +196,8 @@ export const LiveExample: StoryFn = args => { {rows.map((row: LeafyGreenTableRow) => { - const isExpandedContent = row.original.isExpandedContent ?? false; + // const isExpandedContent = row.original.isExpandedContent ?? false; + const isExpandedContent = row.isExpandedContent ?? false; return ( @@ -415,7 +416,8 @@ export const ExpandableContent: StoryFn = args => { {rows.map((row: LeafyGreenTableRow) => { - const isExpandedContent = row.original.isExpandedContent ?? false; + // const isExpandedContent = row.original.isExpandedContent ?? false; + const isExpandedContent = row.isExpandedContent ?? false; return ( {!isExpandedContent && ( @@ -1038,7 +1040,8 @@ export const StyledComponents: StoryFn = args => { {rows.map((row: LeafyGreenTableRow) => { - const isExpandedContent = row.original.isExpandedContent ?? false; + // const isExpandedContent = row.original.isExpandedContent ?? false; + const isExpandedContent = row.isExpandedContent ?? false; return ( {!isExpandedContent && ( diff --git a/packages/table/src/Table/TableWithVS.stories.tsx b/packages/table/src/Table/TableWithVS.stories.tsx index 2beaca4495..3b20f252df 100644 --- a/packages/table/src/Table/TableWithVS.stories.tsx +++ b/packages/table/src/Table/TableWithVS.stories.tsx @@ -479,8 +479,7 @@ export const ExpandableContent: StoryFn = args => { .getVirtualItems() .map((virtualRow: LeafyGreenVirtualItem) => { const row = virtualRow.row; - const isExpandedContent = - row.original.isExpandedContent ?? false; + const isExpandedContent = row.isExpandedContent ?? false; return ( @@ -716,8 +715,7 @@ export const DifferentHeights: StoryFn = args => { .map( (virtualRow: LeafyGreenVirtualItem, index: number) => { const row = virtualRow.row; - const isExpandedContent = - row.original.isExpandedContent ?? false; + const isExpandedContent = row.isExpandedContent ?? false; return ( diff --git a/packages/table/src/TableContext/TableContext.types.ts b/packages/table/src/TableContext/TableContext.types.ts index 710e7e4633..32b192fa77 100644 --- a/packages/table/src/TableContext/TableContext.types.ts +++ b/packages/table/src/TableContext/TableContext.types.ts @@ -5,12 +5,15 @@ import { DarkModeProps } from '@leafygreen-ui/lib'; import { TableProps } from '../Table/Table.types'; import { LeafyGreenTable, LGRowData } from '../useLeafyGreenTable'; +import { LeafyGreenVirtualItem } from '../useLeafyGreenVirtualTable'; -export interface SharedVirtualContextValue { +export interface SharedVirtualContextValue { /** * Available [properties and methods](https://tanstack.com/virtual/latest/docs/api/virtualizer#virtualizer-instance) return from the Virtualizer instance. */ - virtualTable?: Virtualizer; + virtualTable?: Omit, 'getVirtualItems'> & { + getVirtualItems: () => Array>; + }; } export interface BaseTableContextValue { @@ -34,7 +37,7 @@ export type TableProviderValues = PropsWithChildren< Pick, 'shouldAlternateRowColor' | 'shouldTruncate'> > & DarkModeProps & - SharedVirtualContextValue & + SharedVirtualContextValue & BaseTableContextValue; export type TableContextValues = PropsWithChildren< @@ -43,5 +46,5 @@ export type TableContextValues = PropsWithChildren< DarkModeProps & BaseTableContextValue; -export type VirtualTableContextValues = PropsWithChildren & - SharedVirtualContextValue; +export type VirtualTableContextValues = PropsWithChildren & + SharedVirtualContextValue; diff --git a/packages/table/src/TableContext/VirtualTableContext.tsx b/packages/table/src/TableContext/VirtualTableContext.tsx index defe987156..d97e79e3a0 100644 --- a/packages/table/src/TableContext/VirtualTableContext.tsx +++ b/packages/table/src/TableContext/VirtualTableContext.tsx @@ -5,23 +5,25 @@ import React, { useMemo, } from 'react'; +import { LGRowData } from '../useLeafyGreenTable'; + import { type VirtualTableContextValues } from './TableContext.types'; export const VirtualTableContext = createContext< - Partial + Partial> >({}); -export const useVirtualTableContext = () => - useContext( - VirtualTableContext as React.Context, +export const useVirtualTableContext = () => + useContext>( + VirtualTableContext as React.Context>, ); -const VirtualTableContextProvider = ({ +const VirtualTableContextProvider = ({ children, virtualTable, -}: PropsWithChildren>) => { +}: PropsWithChildren>>) => { const VirtualTableProvider = ( - VirtualTableContext as React.Context + VirtualTableContext as React.Context> ).Provider; const providerData = useMemo(() => { diff --git a/packages/table/src/useLeafyGreenTable/useLeafyGreenTable.tsx b/packages/table/src/useLeafyGreenTable/useLeafyGreenTable.tsx index d839b6d952..a1dde0762d 100644 --- a/packages/table/src/useLeafyGreenTable/useLeafyGreenTable.tsx +++ b/packages/table/src/useLeafyGreenTable/useLeafyGreenTable.tsx @@ -89,10 +89,10 @@ function useLeafyGreenTable({ rowsCopy.splice(i + 1, 0, { ...rowsCopy[i], id: `${rowsCopy[i].id}-expandedContent`, + // @ts-expect-error - unsure how to add this to Row. Row is typed as Row> which comes directly from . + isExpandedContent: true, original: { - // TODO: move outside of original ...rowsCopy[i].original, - isExpandedContent: true, }, }); i++; // Increment index to skip the newly added item diff --git a/packages/table/src/useLeafyGreenTable/useLeafyGreenTable.types.ts b/packages/table/src/useLeafyGreenTable/useLeafyGreenTable.types.ts index 78b95d11c4..ccc8167f9e 100644 --- a/packages/table/src/useLeafyGreenTable/useLeafyGreenTable.types.ts +++ b/packages/table/src/useLeafyGreenTable/useLeafyGreenTable.types.ts @@ -15,6 +15,9 @@ export type LGRowData = RowData; export type LGTableDataType = T & { renderExpandedContent?: (row: LeafyGreenTableRow) => JSX.Element; subRows?: Array>; +}; + +export type LGRow = Row> & { isExpandedContent?: boolean; }; @@ -26,7 +29,7 @@ export type LeafyGreenTableCell = Cell< /** LeafyGreen extension of `useReactTable` {@link Row}*/ export interface LeafyGreenTableRow - extends Row> {} + extends LGRow> {} export type LGColumnDef< T extends LGRowData, diff --git a/packages/table/src/useLeafyGreenVirtualTable/useLeafyGreenVirtualTable.tsx b/packages/table/src/useLeafyGreenVirtualTable/useLeafyGreenVirtualTable.tsx index cb99b1fe79..1f80765eb8 100644 --- a/packages/table/src/useLeafyGreenVirtualTable/useLeafyGreenVirtualTable.tsx +++ b/packages/table/src/useLeafyGreenVirtualTable/useLeafyGreenVirtualTable.tsx @@ -52,6 +52,8 @@ function useLeafyGreenVirtualTable< row: rows[virtualRow.index], })); + // const { getVirtualItems, ...virtualizerRest } = _virtualizer; + return { ...table, virtual: { ..._virtualizer, getVirtualItems: () => _virtualItems }, diff --git a/packages/table/src/useLeafyGreenVirtualTable/useLeafyGreenVirtualTable.types.ts b/packages/table/src/useLeafyGreenVirtualTable/useLeafyGreenVirtualTable.types.ts index 7e5dbef44e..5f7df0079c 100644 --- a/packages/table/src/useLeafyGreenVirtualTable/useLeafyGreenVirtualTable.types.ts +++ b/packages/table/src/useLeafyGreenVirtualTable/useLeafyGreenVirtualTable.types.ts @@ -40,7 +40,7 @@ export interface LeafyGreenVirtualTable /** * Available [properties and methods](https://tanstack.com/virtual/latest/docs/api/virtualizer#virtualizer-instance) return from the Virtualizer instance. */ - virtual: Virtualizer & { + virtual: Omit, 'getVirtualItems'> & { getVirtualItems: () => Array>; }; } From 317f254d6a00b53e332a268533b2188f5980ef86 Mon Sep 17 00:00:00 2001 From: Shaneeza Date: Tue, 5 Nov 2024 15:56:30 -0500 Subject: [PATCH 059/113] row TS docs --- packages/table/src/Row/Row.types.ts | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/packages/table/src/Row/Row.types.ts b/packages/table/src/Row/Row.types.ts index e189946068..5b249e835d 100644 --- a/packages/table/src/Row/Row.types.ts +++ b/packages/table/src/Row/Row.types.ts @@ -24,11 +24,35 @@ export interface InternalRowWithRTProps */ virtualRow?: VirtualItem; + /** + * Determines whether alternating rows will have dark backgrounds. + * @default false + */ shouldAlternateRowColor: boolean; + + /** + * Whether the theme is dark or light + */ theme: Theme; + + /** + * Function from TanStack Virtual that is called to dynamically measure the size of an item + */ measureElement?: Virtualizer['measureElement']; + + /** + * Whether the row is expanded + */ isExpanded: boolean; + + /** + * Whether the parent row is expanded + */ isParentExpanded: boolean; + + /** + * Whether the row is selected + */ isSelected: boolean; } From d9bd8f7a7676b1d97ea9d807c3657f2c9a3e4bdf Mon Sep 17 00:00:00 2001 From: Shaneeza Date: Tue, 5 Nov 2024 16:03:22 -0500 Subject: [PATCH 060/113] TS docs stuff --- packages/table/src/ExpandedContent/ExpandedContent.types.ts | 2 +- packages/table/src/Row/Row.types.ts | 2 +- packages/table/src/Table/Table.types.ts | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/packages/table/src/ExpandedContent/ExpandedContent.types.ts b/packages/table/src/ExpandedContent/ExpandedContent.types.ts index dad51cd6bd..cc0fdc3d4a 100644 --- a/packages/table/src/ExpandedContent/ExpandedContent.types.ts +++ b/packages/table/src/ExpandedContent/ExpandedContent.types.ts @@ -5,7 +5,7 @@ import { LeafyGreenTableRow } from '../useLeafyGreenTable'; export interface ExpandedContentProps { row: LeafyGreenTableRow; /** - * Virtual row object passed from the `useLeafyGreenTable` hook + * Virtual row object passed from the `useLeafyGreenVirtualTable` hook */ virtualRow?: VirtualItem; } diff --git a/packages/table/src/Row/Row.types.ts b/packages/table/src/Row/Row.types.ts index 5b249e835d..96e24e33a8 100644 --- a/packages/table/src/Row/Row.types.ts +++ b/packages/table/src/Row/Row.types.ts @@ -20,7 +20,7 @@ export interface InternalRowWithRTProps */ row: LeafyGreenTableRow; /** - * Virtual row object passed from the `useLeafyGreenTable` hook + * Virtual row object passed from the `useLeafyGreenVirtualTable` hook */ virtualRow?: VirtualItem; diff --git a/packages/table/src/Table/Table.types.ts b/packages/table/src/Table/Table.types.ts index 06917ec21c..a849b082c5 100644 --- a/packages/table/src/Table/Table.types.ts +++ b/packages/table/src/Table/Table.types.ts @@ -25,7 +25,7 @@ export interface TableProps table?: LeafyGreenTable | LeafyGreenVirtualTable; //TODO: is there a better way to type this? /** - * Whether all rows will truncate. If true then the cell will truncate at one line. If false then there will be no height limit and cells will not truncate. + * Whether all rows will truncate. If true, cells will truncate at one line. If false then there will be no height limit and cells will not truncate. * @default true */ shouldTruncate?: boolean; From 5d7043534dae01aea400ff651ac5b76131cbdf27 Mon Sep 17 00:00:00 2001 From: Shaneeza Date: Tue, 5 Nov 2024 16:09:08 -0500 Subject: [PATCH 061/113] fix comment --- packages/table/src/useLeafyGreenTable/useLeafyGreenTable.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/table/src/useLeafyGreenTable/useLeafyGreenTable.tsx b/packages/table/src/useLeafyGreenTable/useLeafyGreenTable.tsx index a1dde0762d..de54791a72 100644 --- a/packages/table/src/useLeafyGreenTable/useLeafyGreenTable.tsx +++ b/packages/table/src/useLeafyGreenTable/useLeafyGreenTable.tsx @@ -89,7 +89,7 @@ function useLeafyGreenTable({ rowsCopy.splice(i + 1, 0, { ...rowsCopy[i], id: `${rowsCopy[i].id}-expandedContent`, - // @ts-expect-error - unsure how to add this to Row. Row is typed as Row> which comes directly from . + // @ts-expect-error - unsure how to add this to the Row type. Row is typed as Row> which comes directly from useReactTable. isExpandedContent: true, original: { ...rowsCopy[i].original, From 52eaa5ff937b01b9b4130577aa0a13c975838bd7 Mon Sep 17 00:00:00 2001 From: Shaneeza Date: Tue, 5 Nov 2024 17:56:53 -0500 Subject: [PATCH 062/113] add react-intersection-observer --- packages/table/package.json | 3 ++- packages/table/src/Table.stories.tsx | 6 +++-- packages/table/src/Table/Table.tsx | 8 +++++++ .../table/src/TableHead/TableHead.styles.tsx | 23 ++++++++++++++----- packages/table/src/TableHead/TableHead.tsx | 14 +++-------- yarn.lock | 5 ++++ 6 files changed, 39 insertions(+), 20 deletions(-) diff --git a/packages/table/package.json b/packages/table/package.json index 4d910caa80..49d9d98fd1 100644 --- a/packages/table/package.json +++ b/packages/table/package.json @@ -40,7 +40,8 @@ "react-virtual": "^2.10.4", "react-fast-compare": "3.2.2", "react-transition-group": "^4.4.5", - "react-keyed-flatten-children": "^1.3.0" + "react-keyed-flatten-children": "^1.3.0", + "react-intersection-observer":"9.13.1" }, "devDependencies": { "@faker-js/faker": "^8.0.0", diff --git a/packages/table/src/Table.stories.tsx b/packages/table/src/Table.stories.tsx index b7e7af9f8a..e6f18ce6e1 100644 --- a/packages/table/src/Table.stories.tsx +++ b/packages/table/src/Table.stories.tsx @@ -169,7 +169,8 @@ export const LiveExample: StoryFn = args => { const { rows } = table; return ( - <> +
+
= args => { })}
- +
+
); }; diff --git a/packages/table/src/Table/Table.tsx b/packages/table/src/Table/Table.tsx index 9e03e784a9..02d556a2c7 100644 --- a/packages/table/src/Table/Table.tsx +++ b/packages/table/src/Table/Table.tsx @@ -1,4 +1,5 @@ import React, { ForwardedRef, forwardRef } from 'react'; +import { useInView } from 'react-intersection-observer'; import PropTypes from 'prop-types'; import { cx } from '@leafygreen-ui/emotion'; @@ -43,6 +44,11 @@ const Table = forwardRef>( : undefined; const isSelectable = table ? table.hasSelectableRows : false; + // Helps to determine if the header is sticky + const { ref, inView } = useInView({ + threshold: 0, + }); + return (
>( // eslint-disable-next-line jsx-a11y/no-noninteractive-tabindex tabIndex={0} > +
>( bodyTypeScaleStyles[baseFontSize], )} data-lgid={lgidProp} + data-is-sticky={!inView} {...rest} > {children} diff --git a/packages/table/src/TableHead/TableHead.styles.tsx b/packages/table/src/TableHead/TableHead.styles.tsx index 48e8dd9be0..dcc7fefc4e 100644 --- a/packages/table/src/TableHead/TableHead.styles.tsx +++ b/packages/table/src/TableHead/TableHead.styles.tsx @@ -1,12 +1,7 @@ -import { css } from '@leafygreen-ui/emotion'; +import { css, cx } from '@leafygreen-ui/emotion'; import { Theme } from '@leafygreen-ui/lib'; import { palette } from '@leafygreen-ui/palette'; -export const stickyStyles = css` - position: sticky; - z-index: 1; - top: 0; -`; export const themeStyles: Record = { [Theme.Dark]: css` background-color: ${palette.black}; @@ -17,3 +12,19 @@ export const themeStyles: Record = { box-shadow: 0 4px ${palette.gray.light2}; `, }; + +export const getBaseStyles = (isSticky = false, theme: Theme) => + cx( + { + [css` + position: sticky; + z-index: 1; + top: 0; + + table[data-is-sticky='true'] & { + color: red; + } + `]: isSticky, + }, + themeStyles[theme], + ); diff --git a/packages/table/src/TableHead/TableHead.tsx b/packages/table/src/TableHead/TableHead.tsx index 03b8ff3524..52a15146fb 100644 --- a/packages/table/src/TableHead/TableHead.tsx +++ b/packages/table/src/TableHead/TableHead.tsx @@ -3,7 +3,7 @@ import React, { PropsWithChildren } from 'react'; import { cx } from '@leafygreen-ui/emotion'; import { useDarkMode } from '@leafygreen-ui/leafygreen-provider'; -import { stickyStyles, themeStyles } from './TableHead.styles'; +import { getBaseStyles } from './TableHead.styles'; import { TableHeadProps } from './TableHead.types'; const TableHead = ({ @@ -13,17 +13,9 @@ const TableHead = ({ ...rest }: PropsWithChildren) => { const { theme } = useDarkMode(); + return ( - + {children} ); diff --git a/yarn.lock b/yarn.lock index 9f9d2be5a2..ebabcf3204 100644 --- a/yarn.lock +++ b/yarn.lock @@ -13608,6 +13608,11 @@ react-fast-compare@3.2.2: resolved "https://registry.yarnpkg.com/react-fast-compare/-/react-fast-compare-3.2.2.tgz#929a97a532304ce9fee4bcae44234f1ce2c21d49" integrity sha512-nsO+KSNgo1SbJqJEYRE9ERzo7YtYbou/OqjSQKxV7jcKox7+usiUVZOAC+XnDOABXggQTno0Y1CpVnuWEc1boQ== +react-intersection-observer@9.13.1: + version "9.13.1" + resolved "http://localhost:4873/react-intersection-observer/-/react-intersection-observer-9.13.1.tgz#6c61a75801162491c6348bad09967f2caf445584" + integrity sha512-tSzDaTy0qwNPLJHg8XZhlyHTgGW6drFKTtvjdL+p6um12rcnp8Z5XstE+QNBJ7c64n5o0Lj4ilUleA41bmDoMw== + react-intersection-observer@^8.25.1: version "8.34.0" resolved "https://registry.yarnpkg.com/react-intersection-observer/-/react-intersection-observer-8.34.0.tgz#6f6e67831c52e6233f6b6cc7eb55814820137c42" From 70d839980149e9301e4bee23b0039728c34ef504 Mon Sep 17 00:00:00 2001 From: Shaneeza Date: Wed, 6 Nov 2024 12:12:41 -0500 Subject: [PATCH 063/113] wip --- packages/table/src/TableHead/TableHead.styles.tsx | 9 +++++++++ .../table/src/useLeafyGreenTable/useLeafyGreenTable.tsx | 6 +++--- 2 files changed, 12 insertions(+), 3 deletions(-) diff --git a/packages/table/src/TableHead/TableHead.styles.tsx b/packages/table/src/TableHead/TableHead.styles.tsx index dcc7fefc4e..d6aa894b3d 100644 --- a/packages/table/src/TableHead/TableHead.styles.tsx +++ b/packages/table/src/TableHead/TableHead.styles.tsx @@ -23,6 +23,15 @@ export const getBaseStyles = (isSticky = false, theme: Theme) => table[data-is-sticky='true'] & { color: red; + + :after { + content: ''; + position: absolute; + bottom: 0; + width: 100%; + height: 100%; + box-shadow: -1px 0px 10px rgba(0, 0, 0, 0.25); + } } `]: isSticky, }, diff --git a/packages/table/src/useLeafyGreenTable/useLeafyGreenTable.tsx b/packages/table/src/useLeafyGreenTable/useLeafyGreenTable.tsx index de54791a72..fcfcf527d2 100644 --- a/packages/table/src/useLeafyGreenTable/useLeafyGreenTable.tsx +++ b/packages/table/src/useLeafyGreenTable/useLeafyGreenTable.tsx @@ -91,9 +91,9 @@ function useLeafyGreenTable({ id: `${rowsCopy[i].id}-expandedContent`, // @ts-expect-error - unsure how to add this to the Row type. Row is typed as Row> which comes directly from useReactTable. isExpandedContent: true, - original: { - ...rowsCopy[i].original, - }, + // original: { + // ...rowsCopy[i].original, + // }, }); i++; // Increment index to skip the newly added item } From 89dbb96e464559acccfe65c651a3efc9a31e1ecb Mon Sep 17 00:00:00 2001 From: Shaneeza Date: Wed, 6 Nov 2024 12:15:14 -0500 Subject: [PATCH 064/113] remove original from rowCopy --- packages/table/src/useLeafyGreenTable/useLeafyGreenTable.tsx | 3 --- 1 file changed, 3 deletions(-) diff --git a/packages/table/src/useLeafyGreenTable/useLeafyGreenTable.tsx b/packages/table/src/useLeafyGreenTable/useLeafyGreenTable.tsx index de54791a72..96f2955faf 100644 --- a/packages/table/src/useLeafyGreenTable/useLeafyGreenTable.tsx +++ b/packages/table/src/useLeafyGreenTable/useLeafyGreenTable.tsx @@ -91,9 +91,6 @@ function useLeafyGreenTable({ id: `${rowsCopy[i].id}-expandedContent`, // @ts-expect-error - unsure how to add this to the Row type. Row is typed as Row> which comes directly from useReactTable. isExpandedContent: true, - original: { - ...rowsCopy[i].original, - }, }); i++; // Increment index to skip the newly added item } From f311b3916143d882865e7f29cf082cfbfac19755 Mon Sep 17 00:00:00 2001 From: Shaneeza Date: Wed, 6 Nov 2024 12:50:42 -0500 Subject: [PATCH 065/113] story clean up --- packages/table/src/Cell/Cell.spec.tsx | 4 +- packages/table/src/Cell/Cell.stories.tsx | 2 - .../src/Cell/HeaderCell/HeaderCell.spec.tsx | 2 - packages/table/src/Row/InternalRowBase.tsx | 1 + packages/table/src/Row/InternalRowWithRT.tsx | 51 ++++++++++--------- packages/table/src/Row/Row.stories.tsx | 13 ++--- packages/table/src/Row/Row.tsx | 1 + packages/table/src/Table.stories.tsx | 25 +++++---- .../table/src/TableHead/TableHead.stories.tsx | 8 +-- .../useLeafyGreenTable/useLeafyGreenTable.tsx | 2 +- 10 files changed, 52 insertions(+), 57 deletions(-) diff --git a/packages/table/src/Cell/Cell.spec.tsx b/packages/table/src/Cell/Cell.spec.tsx index a6471e9e87..6bfd0037ae 100644 --- a/packages/table/src/Cell/Cell.spec.tsx +++ b/packages/table/src/Cell/Cell.spec.tsx @@ -6,11 +6,11 @@ import { Cell, CellProps } from '.'; const onScroll = jest.fn(); -const defaultProps: CellProps = { +const defaultProps: CellProps = { onScroll, }; -function renderCell(props: CellProps) { +function renderCell(props: CellProps) { return render( diff --git a/packages/table/src/Cell/Cell.stories.tsx b/packages/table/src/Cell/Cell.stories.tsx index 7a3081b971..1ef7dca9ed 100644 --- a/packages/table/src/Cell/Cell.stories.tsx +++ b/packages/table/src/Cell/Cell.stories.tsx @@ -20,11 +20,9 @@ const meta: StoryMetaType = { generate: { combineArgs: { darkMode: [false, true], - depth: [0, 1], align: ['left', 'center', 'right'], }, args: { - cellIndex: 0, children: 'Cell content', }, decorator: (Instance, ctx) => { diff --git a/packages/table/src/Cell/HeaderCell/HeaderCell.spec.tsx b/packages/table/src/Cell/HeaderCell/HeaderCell.spec.tsx index 16058cbc12..d0a08ff7d3 100644 --- a/packages/table/src/Cell/HeaderCell/HeaderCell.spec.tsx +++ b/packages/table/src/Cell/HeaderCell/HeaderCell.spec.tsx @@ -63,7 +63,6 @@ const TestSortableHeaderCell = () => { const containerRef = useRef(null); const table = useLeafyGreenTable({ - containerRef, columns: headerCellTestColumns, data: headerCellTestData, }); @@ -95,7 +94,6 @@ const useMockTestHeaderData = ( ): Header, unknown> => { // eslint-disable-next-line react-hooks/rules-of-hooks const table = useLeafyGreenTable({ - containerRef: React.createRef(), data: [], columns: [columnDef], }); diff --git a/packages/table/src/Row/InternalRowBase.tsx b/packages/table/src/Row/InternalRowBase.tsx index 94e1b820d0..2704f1be83 100644 --- a/packages/table/src/Row/InternalRowBase.tsx +++ b/packages/table/src/Row/InternalRowBase.tsx @@ -16,6 +16,7 @@ const InternalRowBase = forwardRef( ({ className, onClick, ...rest }: InternalRowBaseProps, forwardedRef) => { const { theme } = useDarkMode(); const { disabled } = useRowContext(); + return ( ({ // console.log(`🪼rerender🪼 row: ${row.id}, depth: ${row.depth}`); return ( - { - if (measureElement) measureElement(node); - }} - data-index={virtualRow ? virtualRow!.index : ''} - {...rest} - > - {children} - + + { + if (measureElement) measureElement(node); + }} + data-index={virtualRow ? virtualRow!.index : ''} + {...rest} + > + {children} + + ); }; diff --git a/packages/table/src/Row/Row.stories.tsx b/packages/table/src/Row/Row.stories.tsx index 834f768357..40c6c061fb 100644 --- a/packages/table/src/Row/Row.stories.tsx +++ b/packages/table/src/Row/Row.stories.tsx @@ -168,12 +168,12 @@ export const DisabledNestedRows: StoryFn = ({ row, ...rest }) => { onExpandedChange: setExpanded, }); - const { rows } = table.getRowModel(); + const { rows } = table; return ( <>
-

{table.getRowModel().rows.length} total rows

+

{table.rows.length} total rows

Expanded rows: {JSON.stringify(expanded, null, 2)}
@@ -202,7 +202,7 @@ export const DisabledNestedRows: StoryFn = ({ row, ...rest }) => { .getVisibleCells() .map((cell: LeafyGreenTableCell) => { return ( - + {flexRender( cell.column.columnDef.cell, cell.getContext(), @@ -293,10 +293,11 @@ export const DisabledSelectableRows: StoryFn< rowSelection, }, onRowSelectionChange: setRowSelection, + enableRowSelection: !args.disabled, hasSelectableRows: true, }); - const { rows } = table.getRowModel(); + const { rows } = table; return (
@@ -326,7 +327,7 @@ export const DisabledSelectableRows: StoryFn< darkMode={darkMode} table={table} ref={tableContainerRef} - data-total-rows={table.getRowModel().rows.length} + data-total-rows={table.rows.length} > {table.getHeaderGroups().map((headerGroup: HeaderGroup) => ( @@ -350,7 +351,7 @@ export const DisabledSelectableRows: StoryFn< {row.getVisibleCells().map(cell => { return ( - + {flexRender( cell.column.columnDef.cell, cell.getContext(), diff --git a/packages/table/src/Row/Row.tsx b/packages/table/src/Row/Row.tsx index 9b165a3c0b..21802aa81e 100644 --- a/packages/table/src/Row/Row.tsx +++ b/packages/table/src/Row/Row.tsx @@ -23,6 +23,7 @@ const Row = ({ const { theme } = useDarkMode(); const { shouldAlternateRowColor } = useTableContext(); const { virtualTable } = useVirtualTableContext(); + return ( <> {row ? ( diff --git a/packages/table/src/Table.stories.tsx b/packages/table/src/Table.stories.tsx index b7e7af9f8a..83664aca38 100644 --- a/packages/table/src/Table.stories.tsx +++ b/packages/table/src/Table.stories.tsx @@ -290,7 +290,6 @@ export const NestedRows: StoryFn = args => { columns, }); - // const { rows } = table.getRowModel(); const { rows } = table; return ( @@ -493,13 +492,13 @@ export const SortableRows: StoryFn = args => { columns, }); - const { rows } = table.getRowModel(); + const { rows } = table; return (
{table.getHeaderGroups().map((headerGroup: HeaderGroup) => ( @@ -546,7 +545,7 @@ export const SelectableRows: StoryFn = args => { { accessorKey: 'id', header: 'ID', - size: 60, + size: 100, }, { accessorKey: 'firstName', @@ -575,7 +574,7 @@ export const SelectableRows: StoryFn = args => { { accessorKey: 'status', header: 'Status', - size: 90, + size: 140, }, ], [], @@ -591,7 +590,7 @@ export const SelectableRows: StoryFn = args => { hasSelectableRows: true, }); - const { rows } = table.getRowModel(); + const { rows } = table; return (
@@ -621,7 +620,7 @@ export const SelectableRows: StoryFn = args => { {...args} table={table} ref={tableContainerRef} - data-total-rows={table.getRowModel().rows.length} + data-total-rows={table.rows.length} > {table.getHeaderGroups().map((headerGroup: HeaderGroup) => ( @@ -672,7 +671,7 @@ export const SelectableRowsNoSelectAll: StoryFn = args => { { accessorKey: 'id', header: 'ID', - size: 60, + size: 100, }, { accessorKey: 'firstName', @@ -701,7 +700,7 @@ export const SelectableRowsNoSelectAll: StoryFn = args => { { accessorKey: 'status', header: 'Status', - size: 90, + size: 140, }, ], [], @@ -718,7 +717,7 @@ export const SelectableRowsNoSelectAll: StoryFn = args => { allowSelectAll: false, }); - const { rows } = table.getRowModel(); + const { rows } = table; return (
@@ -802,7 +801,7 @@ export const WithPagination: StoryFn = ({ { accessorKey: 'id', header: 'ID', - size: 60, + size: 100, }, { accessorKey: 'firstName', @@ -831,7 +830,7 @@ export const WithPagination: StoryFn = ({ { accessorKey: 'status', header: 'Status', - size: 90, + size: 140, }, ], [], @@ -843,7 +842,7 @@ export const WithPagination: StoryFn = ({ withPagination: true, }); - const { rows } = table.getRowModel(); + const { rows } = table; return (
diff --git a/packages/table/src/TableHead/TableHead.stories.tsx b/packages/table/src/TableHead/TableHead.stories.tsx index 09e78967c4..1a6058bd23 100644 --- a/packages/table/src/TableHead/TableHead.stories.tsx +++ b/packages/table/src/TableHead/TableHead.stories.tsx @@ -1,8 +1,6 @@ import React from 'react'; import { ComponentStory, Meta } from '@storybook/react'; -import { css } from '@leafygreen-ui/emotion'; - import { Cell, HeaderCell } from '../Cell'; import { HeaderRow, Row } from '../Row'; import Table from '../Table/Table'; @@ -37,11 +35,7 @@ const Template: ComponentStory = args => { const data = makeData(false, 100); const columns = Object.keys(data[0]); return ( -
+
{columns.map((columnName: string) => ( diff --git a/packages/table/src/useLeafyGreenTable/useLeafyGreenTable.tsx b/packages/table/src/useLeafyGreenTable/useLeafyGreenTable.tsx index 96f2955faf..ac3b889407 100644 --- a/packages/table/src/useLeafyGreenTable/useLeafyGreenTable.tsx +++ b/packages/table/src/useLeafyGreenTable/useLeafyGreenTable.tsx @@ -16,7 +16,7 @@ import { TableRowCheckbox } from './TableRowCheckbox'; import { LeafyGreenTableOptions, LGRowData } from './useLeafyGreenTable.types'; import { LeafyGreenTable, LGColumnDef, LGTableDataType } from '.'; -const CHECKBOX_WIDTH = 14; +const CHECKBOX_WIDTH = 40; function useLeafyGreenTable({ data, From 59474ee648d47cc3f58e71c6bb4369b237cbf10d Mon Sep 17 00:00:00 2001 From: Shaneeza Date: Wed, 6 Nov 2024 13:06:20 -0500 Subject: [PATCH 066/113] remove v10 and v11 adapter --- packages/table/package.json | 5 +- packages/table/src/TableV10/Cell.tsx | 140 ----- .../table/src/TableV10/DarkModeContext.tsx | 26 - .../table/src/TableV10/FontSizeContext.tsx | 28 - packages/table/src/TableV10/HeaderRow.tsx | 28 - packages/table/src/TableV10/NestedRow.tsx | 112 ---- packages/table/src/TableV10/Row.tsx | 404 -------------- packages/table/src/TableV10/SortContext.tsx | 82 --- packages/table/src/TableV10/Table.stories.tsx | 330 ----------- packages/table/src/TableV10/Table.tsx | 261 --------- packages/table/src/TableV10/TableBody.tsx | 81 --- packages/table/src/TableV10/TableContext.tsx | 167 ------ packages/table/src/TableV10/TableHead.tsx | 67 --- packages/table/src/TableV10/TableHeader.tsx | 276 --------- .../table/src/TableV10/fixtures.testutils.ts | 229 -------- packages/table/src/TableV10/index.ts | 6 - packages/table/src/TableV10/styles.tsx | 18 - packages/table/src/TableV10/testUtils.tsx | 50 -- packages/table/src/TableV10/useSSR.ts | 63 --- .../table/src/V11Adapter/V11Adapter.spec.tsx | 436 --------------- .../src/V11Adapter/V11Adapter.stories.tsx | 523 ------------------ packages/table/src/V11Adapter/V11Adapter.tsx | 233 -------- .../table/src/V11Adapter/V11Adapter.types.ts | 32 -- packages/table/src/V11Adapter/index.ts | 4 - .../table/src/V11Adapter/processColumns.tsx | 83 --- packages/table/src/V11Adapter/processData.tsx | 97 ---- packages/table/src/index.ts | 11 +- .../useLeafyGreenVirtualTable.spec.tsx | 1 + yarn.lock | 12 - 29 files changed, 3 insertions(+), 3802 deletions(-) delete mode 100644 packages/table/src/TableV10/Cell.tsx delete mode 100644 packages/table/src/TableV10/DarkModeContext.tsx delete mode 100644 packages/table/src/TableV10/FontSizeContext.tsx delete mode 100644 packages/table/src/TableV10/HeaderRow.tsx delete mode 100644 packages/table/src/TableV10/NestedRow.tsx delete mode 100644 packages/table/src/TableV10/Row.tsx delete mode 100644 packages/table/src/TableV10/SortContext.tsx delete mode 100644 packages/table/src/TableV10/Table.stories.tsx delete mode 100644 packages/table/src/TableV10/Table.tsx delete mode 100644 packages/table/src/TableV10/TableBody.tsx delete mode 100644 packages/table/src/TableV10/TableContext.tsx delete mode 100644 packages/table/src/TableV10/TableHead.tsx delete mode 100644 packages/table/src/TableV10/TableHeader.tsx delete mode 100644 packages/table/src/TableV10/fixtures.testutils.ts delete mode 100644 packages/table/src/TableV10/index.ts delete mode 100644 packages/table/src/TableV10/styles.tsx delete mode 100644 packages/table/src/TableV10/testUtils.tsx delete mode 100644 packages/table/src/TableV10/useSSR.ts delete mode 100644 packages/table/src/V11Adapter/V11Adapter.spec.tsx delete mode 100644 packages/table/src/V11Adapter/V11Adapter.stories.tsx delete mode 100644 packages/table/src/V11Adapter/V11Adapter.tsx delete mode 100644 packages/table/src/V11Adapter/V11Adapter.types.ts delete mode 100644 packages/table/src/V11Adapter/index.ts delete mode 100644 packages/table/src/V11Adapter/processColumns.tsx delete mode 100644 packages/table/src/V11Adapter/processData.tsx diff --git a/packages/table/package.json b/packages/table/package.json index 4d910caa80..f5c1342559 100644 --- a/packages/table/package.json +++ b/packages/table/package.json @@ -37,10 +37,7 @@ "@tanstack/react-virtual": "^3.10.7", "lodash": "^4.17.21", "polished": "^4.2.2", - "react-virtual": "^2.10.4", - "react-fast-compare": "3.2.2", - "react-transition-group": "^4.4.5", - "react-keyed-flatten-children": "^1.3.0" + "react-fast-compare": "3.2.2" }, "devDependencies": { "@faker-js/faker": "^8.0.0", diff --git a/packages/table/src/TableV10/Cell.tsx b/packages/table/src/TableV10/Cell.tsx deleted file mode 100644 index 6a905cfe04..0000000000 --- a/packages/table/src/TableV10/Cell.tsx +++ /dev/null @@ -1,140 +0,0 @@ -import React, { forwardRef } from 'react'; - -import { css, cx } from '@leafygreen-ui/emotion'; -import { useDarkMode } from '@leafygreen-ui/leafygreen-provider'; -import { createUniqueClassName, HTMLElementProps } from '@leafygreen-ui/lib'; -import { palette } from '@leafygreen-ui/palette'; -import { useUpdatedBaseFontSize } from '@leafygreen-ui/typography'; - -import { getCommonCellStyles } from './styles'; - -export const tdInnerDivClassName = createUniqueClassName('td-inner-div'); - -/** - * @deprecated - */ -interface HeaderCellProps - extends HTMLElementProps<'th', HTMLTableHeaderCellElement> { - /** - * Renders the cell as a th element - */ - isHeader: true; - - /** - * Determines whether the cell renders as disabled - */ - isDisabled?: boolean; -} - -/** - * @deprecated - */ -interface TableCellProps extends HTMLElementProps<'td', HTMLTableCellElement> { - /** - * Determines whether the cell renders as disabled - */ - isDisabled?: boolean; - /** - * Renders the cell as a th element - */ - isHeader?: false; -} - -/** - * @deprecated - */ -type CellProps = HeaderCellProps | TableCellProps; - -const baseStyles = css` - position: relative; -`; - -const thStyles = css` - font-weight: 600; -`; - -const lightModeThStyles = css` - border-right: 3px solid ${palette.gray.light2}; - background-color: ${palette.gray.light3}; -`; - -const darkModeThStyles = css` - border-right: 3px solid ${palette.gray.dark2}; - background-color: ${palette.gray.dark4}; -`; - -const innerDivStyles = css` - display: flex; - align-items: center; -`; - -const lightModeDisabledHeaderStyles = css` - border-top: 1px solid ${palette.gray.light3}; - border-bottom: 1px solid ${palette.gray.light3}; - color: ${palette.black}; - cursor: auto; -`; - -const darkModeDisabledHeaderStyles = css` - color: ${palette.white}; - cursor: auto; -`; - -/** - * @deprecated - */ -export type CellElement = React.ReactComponentElement; - -/** - * @deprecated - */ -const Cell = forwardRef( - ( - { children, className, isHeader = false, isDisabled, ...rest }: CellProps, - ref: React.Ref, - ) => { - const Root = isHeader ? 'th' : 'td'; - - const baseFontSize = useUpdatedBaseFontSize(); - const { darkMode } = useDarkMode(); - - const props: Partial = { - ref, - className: cx( - getCommonCellStyles(baseFontSize), - baseStyles, - { - [thStyles]: isHeader, - [lightModeThStyles]: isHeader && !darkMode, - [darkModeThStyles]: isHeader && darkMode, - [lightModeDisabledHeaderStyles]: isHeader && isDisabled && !darkMode, - [darkModeDisabledHeaderStyles]: isHeader && isDisabled && darkMode, - }, - className, - ), - }; - - if (isHeader) { - props.scope = 'row'; - props.role = 'rowheader'; - } - - return ( - -
- - {children} - -
-
- ); - }, -); - -Cell.displayName = 'Cell'; - -export default Cell; diff --git a/packages/table/src/TableV10/DarkModeContext.tsx b/packages/table/src/TableV10/DarkModeContext.tsx deleted file mode 100644 index 06596f9650..0000000000 --- a/packages/table/src/TableV10/DarkModeContext.tsx +++ /dev/null @@ -1,26 +0,0 @@ -import React, { createContext, useContext } from 'react'; - -/** - * @deprecated - */ -interface DarkModeProviderInterface { - darkMode: boolean; - children: React.ReactNode; -} - -const DarkModeContext = createContext(false); - -export function DarkModeProvider({ - children, - darkMode, -}: DarkModeProviderInterface) { - return ( - - {children} - - ); -} - -export function useDarkModeContext() { - return useContext(DarkModeContext); -} diff --git a/packages/table/src/TableV10/FontSizeContext.tsx b/packages/table/src/TableV10/FontSizeContext.tsx deleted file mode 100644 index 3c1d38268d..0000000000 --- a/packages/table/src/TableV10/FontSizeContext.tsx +++ /dev/null @@ -1,28 +0,0 @@ -import React, { createContext, useContext } from 'react'; - -type BaseFontSize = 14 | 16; - -/** - * @deprecated - */ -interface FontSizeProviderInterface { - baseFontSize: BaseFontSize; - children: React.ReactNode; -} - -const FontSizeContext = createContext(14); - -export function FontSizeProvider({ - children, - baseFontSize, -}: FontSizeProviderInterface) { - return ( - - {children} - - ); -} - -export function useFontSizeContext() { - return useContext(FontSizeContext); -} diff --git a/packages/table/src/TableV10/HeaderRow.tsx b/packages/table/src/TableV10/HeaderRow.tsx deleted file mode 100644 index 2fbbb2c508..0000000000 --- a/packages/table/src/TableV10/HeaderRow.tsx +++ /dev/null @@ -1,28 +0,0 @@ -import React from 'react'; - -import { HTMLElementProps } from '@leafygreen-ui/lib'; - -/** - * @deprecated - */ -export interface HeaderRowProps extends HTMLElementProps<'tr'> {} - -/** - * @deprecated - */ -export type HeaderRowElement = React.ReactComponentElement; - -/** - * @deprecated - */ -function HeaderRow({ children, className, ...rest }: HeaderRowProps) { - return ( -
- {children} - - ); -} - -HeaderRow.displayName = 'HeaderRow'; - -export default HeaderRow; diff --git a/packages/table/src/TableV10/NestedRow.tsx b/packages/table/src/TableV10/NestedRow.tsx deleted file mode 100644 index ffcf3d2a84..0000000000 --- a/packages/table/src/TableV10/NestedRow.tsx +++ /dev/null @@ -1,112 +0,0 @@ -import React from 'react'; -import { useEffect, useRef, useState } from 'react'; -import { TransitionStatus } from 'react-transition-group/Transition'; - -import { css, cx } from '@leafygreen-ui/emotion'; - -import { tdInnerDivClassName } from './Cell'; -import Row, { RowProps } from './Row'; - -const transitionTime = 200; - -const nestedRowInitialStyle = css` - position: relative; - opacity: 0; - transform-origin: 50% 0%; - transition: ${transitionTime}ms ease-in-out; - transition-property: outline-color, opacity; - - // This makes it so that any tall nested rows appear "below" the parents - // This may cause issues if there are multiple levels of nesting - // that all have more than one line of text. However this scenario is unlikely - z-index: 0; - - & > :is(td, th) { - transition: ${transitionTime}ms ease-in-out; - transition-property: padding-block; - - & > .${tdInnerDivClassName} { - transition: ${transitionTime}ms ease-in-out; - transition-property: min-height, max-height; - } - } -`; - -const hiddenRowStyles = css` - opacity: 0; - outline-color: transparent; - - & > :is(td, th) { - padding-block: 0; - - & > .${tdInnerDivClassName} { - min-height: 0px; - max-height: 0px; - } - } -`; - -const nestedRowTransitionStyles = ( - state: TransitionStatus, - height?: number, -): string => { - switch (state) { - case 'entered': - return css` - opacity: 1; - & > :is(td, th) { - & > .${tdInnerDivClassName} { - --lg-cell-max-height: max(var(--lg-cell-min-height), ${height}px); - min-height: var(--lg-cell-min-height); - max-height: var(--lg-cell-max-height); - } - } - `; - default: - return hiddenRowStyles; - } -}; - -/** - * @deprecated - */ -interface NestedRowProps extends RowProps { - state: TransitionStatus; -} - -const NestedRow = ({ ref, className, state, ...rest }: NestedRowProps) => { - const [nestedRowHeight, setNestedRowHeight] = useState(0); - const nestedRowNodeRef = useRef(null); - - const calculateRowContentHeight = () => { - if (nestedRowNodeRef && nestedRowNodeRef.current) { - const innerSpan: HTMLSpanElement | null = - nestedRowNodeRef.current.querySelector( - `.${tdInnerDivClassName} > span`, - ); - - if (innerSpan && innerSpan.offsetHeight) { - setNestedRowHeight(innerSpan.offsetHeight); - } - } - }; - - useEffect(() => { - calculateRowContentHeight(); - // eslint-disable-next-line react-hooks/exhaustive-deps - }, [nestedRowNodeRef.current]); - - return ( - - ); -}; - -export default NestedRow; diff --git a/packages/table/src/TableV10/Row.tsx b/packages/table/src/TableV10/Row.tsx deleted file mode 100644 index 1e61855fed..0000000000 --- a/packages/table/src/TableV10/Row.tsx +++ /dev/null @@ -1,404 +0,0 @@ -import React, { forwardRef, useEffect, useMemo, useRef, useState } from 'react'; -import { Transition } from 'react-transition-group'; - -import { css, cx } from '@leafygreen-ui/emotion'; -import { useIdAllocator } from '@leafygreen-ui/hooks'; -import ChevronDownIcon from '@leafygreen-ui/icon/dist/ChevronDown'; -import ChevronRightIcon from '@leafygreen-ui/icon/dist/ChevronRight'; -import IconButton from '@leafygreen-ui/icon-button'; -import { useDarkMode } from '@leafygreen-ui/leafygreen-provider'; -import { HTMLElementProps, isComponentType, Theme } from '@leafygreen-ui/lib'; -import { palette } from '@leafygreen-ui/palette'; - -import { CellElement, tdInnerDivClassName } from './Cell'; -import NestedRow from './NestedRow'; -import { DataType, TableActionTypes, useTableContext } from './TableContext'; -import useSSR from './useSSR'; - -/** - * Types & Constants - */ - -const transitionTime = 200; - -/** - * Styles - */ -const iconButtonMargin = css` - margin: -4px; - margin-right: 4px; -`; - -const iconButtonThemeStyles: Record = { - [Theme.Light]: css` - color: ${palette.gray.dark1}; - `, - [Theme.Dark]: css` - color: ${palette.gray.base}; - `, -}; - -export const iconButtonThemeDisabledStyles: Record = { - [Theme.Light]: css` - color: ${palette.gray.light1}; - `, - [Theme.Dark]: css` - color: ${palette.gray.dark1}; - `, -}; - -/** - * @deprecated - */ -type StyledElements = 'rowStyle' | 'altColor' | 'disabledStyle'; - -const themeStyles: Record> = { - [Theme.Light]: { - rowStyle: css` - background-color: ${palette.white}; - color: ${palette.gray.dark3}; - `, - - altColor: css` - &:nth-of-type(even) { - background-color: ${palette.gray.light3}; - } - - &:nth-of-type(odd) > th { - background-color: ${palette.white}; - } - `, - - disabledStyle: css` - background-color: ${palette.gray.light2}; - color: ${palette.gray.base}; - border-top: 1px inset ${palette.gray.light1}; - border-bottom: 1px inset ${palette.gray.light1}; - `, - }, - - [Theme.Dark]: { - rowStyle: css` - background-color: ${palette.black}; - color: ${palette.gray.light2}; - `, - - altColor: css` - &:nth-of-type(even) { - background-color: ${palette.gray.dark4}; - } - - &:nth-of-type(odd) > th { - background-color: ${palette.black}; - } - `, - - disabledStyle: css` - background-color: ${palette.gray.dark2}; - color: ${palette.gray.base}; - `, - }, -}; - -const rowStyle = css` - --lg-cell-min-height: 20px; - position: relative; - z-index: 1; - - & > :is(td, th) > .${tdInnerDivClassName} { - min-height: var(--lg-cell-min-height); - max-height: unset; - } -`; - -const hideRow = css` - opacity: 0; -`; - -function styleColumn(index: string, dataType?: DataType) { - let justify; - - if (dataType === DataType.Number) { - justify = 'flex-end'; - } else { - justify = 'flex-start'; - } - - return css` - & :is(td, th):nth-child(${index}) > div { - justify-content: ${justify}; - } - `; -} - -function getIndentLevelStyle(indentLevel: number) { - const indentLevelMultiplier = 36; - return css` - & > :is(td, th):nth-child(1) { - padding-left: ${8 + indentLevel * indentLevelMultiplier}px; - } - `; -} - -/** - * @deprecated - * @noDocgen - */ -export interface RowProps extends HTMLElementProps<'tr', HTMLTableRowElement> { - /** - * Determines whether or not the row is expanded on first render - */ - expanded?: boolean; - /** - * Determines whether or not the row is disabled - */ - disabled?: boolean; - /** - * @internal - */ - indentLevel?: number; - /** - * @internal - */ - isAnyAncestorCollapsed?: boolean; -} - -/** - * @deprecated - */ -type RowElement = React.ReactComponentElement< - typeof Row, - React.ComponentPropsWithRef ->; - -/** - * @deprecated - */ -const Row = forwardRef( - ( - { - expanded = false, - disabled = false, - indentLevel = 0, - isAnyAncestorCollapsed: isAnyAncestorCollapsedProp, - children, - className, - ...rest - }: RowProps, - ref: React.Ref, - ) => { - const { isBrowser } = useSSR(); - const { - state: { data, columnInfo, hasNestedRows, hasRowSpan }, - dispatch: tableDispatch, - } = useTableContext(); - const { theme, darkMode } = useDarkMode(); - - const shouldAltRowColor = - data && data.length >= 10 && hasNestedRows != null && !hasNestedRows; - - const indexRef = useRef(useIdAllocator({ prefix: 'row' })); - const [isExpanded, setIsExpanded] = useState(expanded); - const nestedRowParentRef = useRef(null); - - useEffect(() => { - let shouldDispatchHasNestedRows = false; - let shouldDispatchHasRowSpan = false; - - if (hasNestedRows && hasRowSpan) { - return; - } - - React.Children.forEach(children, child => { - if ( - isComponentType(child, 'Row') && - !shouldDispatchHasNestedRows && - !hasNestedRows - ) { - shouldDispatchHasNestedRows = true; - } - - if ( - isComponentType(child, 'Cell') && - child.props.rowSpan && - child.props.rowSpan > 1 && - !hasRowSpan && - !shouldDispatchHasRowSpan - ) { - shouldDispatchHasRowSpan = true; - } - }); - - if ( - shouldDispatchHasNestedRows && - hasNestedRows !== shouldDispatchHasNestedRows - ) { - tableDispatch({ - type: TableActionTypes.SetHasNestedRows, - payload: true, - }); - } - - if (shouldDispatchHasRowSpan && hasRowSpan !== shouldDispatchHasRowSpan) { - tableDispatch({ - type: TableActionTypes.SetHasRowSpan, - payload: true, - }); - } - }, [children, hasNestedRows, hasRowSpan, tableDispatch, data]); - - // Render any nested rows and their transition group - const { rowHasNestedRows, renderedNestedRowTransitionGroup } = - useMemo(() => { - const renderedNestedRows: Array = []; - const rowHasNestedRows = React.Children.toArray(children).some(child => - isComponentType(child, 'Row'), - ); - - const shouldTransitionGroupBeVisible = - isExpanded && !isAnyAncestorCollapsedProp; - - // We don't need the transition group except on the client here, and rendering this bit on the server breaks rendering these rows. - const renderedNestedRowTransitionGroup = isBrowser ? ( - - {state => - React.Children.map(children, (child, index) => { - if ( - child != null && - isComponentType(child, 'Row') - ) { - return ( - - ); - } - }) - } - - ) : ( - renderedNestedRows - ); - - return { - rowHasNestedRows, - renderedNestedRows, - renderedNestedRowTransitionGroup, - }; - }, [ - children, - isExpanded, - isAnyAncestorCollapsedProp, - isBrowser, - indentLevel, - ]); - - const renderedChildren = useMemo(() => { - const renderedChildren: Array = []; - - React.Children.forEach(children, (child, index) => { - if (isComponentType(child, 'Cell')) { - if (child.props.children == null) { - return null; - } - - renderedChildren.push( - React.cloneElement(child, { - children: {child.props.children}, - key: `${indexRef.current}-${index}`, - isDisabled: disabled, - isHeader: child.props.isHeader, - ...child.props, - }), - ); - } - }); - - if (rowHasNestedRows) { - const Icon = isExpanded ? ChevronDownIcon : ChevronRightIcon; - - const chevronButton = ( - setIsExpanded(curr => !curr)} - aria-label={isExpanded ? 'Collapse row' : 'Expand row'} - aria-expanded={isExpanded} - className={cx(iconButtonMargin, iconButtonThemeStyles[theme], { - [iconButtonThemeDisabledStyles[theme]]: disabled, - })} - darkMode={darkMode} - > - - - ); - const { children: firstChildChildren, ...firstChildProps } = - renderedChildren[0].props; - renderedChildren[0] = React.cloneElement(renderedChildren[0], { - children: ( - <> - {chevronButton} - {firstChildChildren} - - ), - key: `${indexRef.current}-${renderedChildren[0].props.children}`, - ...firstChildProps, - }); - } - - return renderedChildren; - }, [children, rowHasNestedRows, disabled, isExpanded, theme, darkMode]); - - const alignmentStyles = columnInfo - ? Object.entries(columnInfo).map(([key, { dataType }]) => - styleColumn(key, dataType), - ) - : ['']; - - const rowClassName = cx( - rowStyle, - themeStyles[theme].rowStyle, - getIndentLevelStyle(indentLevel), - [...alignmentStyles], - { - // Hide the row until we can apply correct alignment to cells. - [hideRow]: !columnInfo, - [themeStyles[theme].altColor]: shouldAltRowColor, - [themeStyles[theme].disabledStyle]: disabled, - }, - className, - ); - - return ( - <> - - {renderedChildren} - - - {renderedNestedRowTransitionGroup} - - ); - }, -); - -Row.displayName = 'Row'; - -export default Row; diff --git a/packages/table/src/TableV10/SortContext.tsx b/packages/table/src/TableV10/SortContext.tsx deleted file mode 100644 index bdac1adb60..0000000000 --- a/packages/table/src/TableV10/SortContext.tsx +++ /dev/null @@ -1,82 +0,0 @@ -import React, { createContext, useContext, useMemo, useState } from 'react'; - -/** - * @deprecated - */ -export type SortDirection = 'asc' | 'desc'; - -/** - * @deprecated - */ -interface Sort { - columnId: number; - direction: SortDirection; - accessorValue?: (data: any) => string; - compareFn?: (a: any, b: any, direction: SortDirection) => number; - handleSort?: (direction: SortDirection) => void; -} - -/** - * @deprecated - */ -interface ContextInterface { - sort?: Sort; - setSort: React.Dispatch>; -} - -const SortContext = createContext({ - sort: undefined, - setSort: () => {}, -}); - -export function SortProvider({ children }: { children: React.ReactNode }) { - const [sort, setSort] = useState(undefined); - - const contextValue = useMemo(() => { - return { sort, setSort }; - }, [sort, setSort]); - - return ( - {children} - ); -} - -export function useSortContext() { - return useContext(SortContext); -} - -const alphanumericCollator = new Intl.Collator(undefined, { - numeric: true, - sensitivity: 'base', -}); - -export const getDataComparisonFunction = ({ - direction, - accessorValue, - compareFn, -}: { - direction: SortDirection; - accessorValue?: (data: T) => string; - compareFn?: (a: T, b: T, dir: SortDirection) => number; -}) => { - if (accessorValue) { - return (a: T, b: T) => { - const aVal = accessorValue(a); - const bVal = accessorValue(b); - - if (direction !== 'desc') { - return alphanumericCollator.compare(aVal, bVal); - } - - return alphanumericCollator.compare(bVal, aVal); - }; - } - - if (compareFn) { - return (a: T, b: T) => compareFn(a, b, direction); - } - - console.error( - 'Error getting Table data comparison function. Please supply either an `accessorValue` or `compareFn`', - ); -}; diff --git a/packages/table/src/TableV10/Table.stories.tsx b/packages/table/src/TableV10/Table.stories.tsx deleted file mode 100644 index 399001d472..0000000000 --- a/packages/table/src/TableV10/Table.stories.tsx +++ /dev/null @@ -1,330 +0,0 @@ -/* eslint-disable */ -// TODO: Table Shape is defined as `any` for now since our test data format isn't consistent. -import { Meta } from '@storybook/react'; -import React from 'react'; -import { Table, Row, Cell, TableHeader, HeaderRow, DataType } from '.'; -import { defaultData } from './fixtures.testutils'; -import { TableProps } from './Table'; -import { storybookArgTypes } from '@lg-tools/storybook-utils'; - -export default { - title: 'Components/Table/V10', - component: Table, - parameters: { - chromatic: { disableSnapshot: true }, - }, - args: { - data: defaultData, - withHeaders: false, - }, - argTypes: { - withHeaders: { - control: 'boolean', - description: - '[STORYBOOK ONLY]\n\nDetermines whether the `isHeader` prop should be passed to the first `Cell` of the story.', - }, - children: { control: 'none' }, - data: { control: 'none' }, - columns: { control: 'none' }, - darkMode: storybookArgTypes.darkMode, - ref: { control: 'none' }, - }, -} as Meta; - -type TableArgs = TableProps & { withHeaders?: boolean }; - -export const Basic = ({ withHeaders, ...args }: TableArgs) => ( -
- - - - - - - } - > - {({ datum, index }) => ( - - {index} - {datum.name} - {datum.age} - {datum.color} - {datum.location} - - )} -
-); - -export const BuiltInZebraStripes = ({ - withHeaders, - ...args -}: TableArgs) => ( - - - - - - - } - > - {({ datum }) => ( - - {datum.name} - {datum.age} - {datum.color} - {datum.location} - - )} -
-); - -export const CustomLogic = ({ withHeaders, ...args }: TableArgs) => ( - - { - const reverse = (str: string) => str.split('').reverse().join(''); - - // Pin 'Yvonne' to the top - if (b.name === 'Yvonne') return 1; - else if (a.name === 'Yvonne') return -1; - - // Sort by reversed name - if (dir == 'desc') { - return reverse(b.name) >= reverse(a.name) ? 1 : -1; - } - - return reverse(b.name) >= reverse(a.name) ? -1 : 1; - }} - /> - - datum.age.toString()} - /> - - datum.color} - /> - - { - // eslint-disable-next-line no-console - console.log(`Sorting location ${dir}`); - }} - /> - - } - > - {({ datum }: { datum: any }) => ( - - - {datum.name} {datum.rand} - - {datum.age} - {datum.color} - {datum.location} - - {datum.name === 'Donna' && ( - - - Nulla vitae elit libero, a pharetra augue. Sed posuere consectetur - est at lobortis. Integer posuere erat a ante venenatis dapibus - posuere velit aliquet. Maecenas faucibus mollis interdum. Nullam - id dolor id nibh ultricies vehicula ut id elit. Duis mollis, est - non commodo luctus, nisi erat porttitor ligula, eget lacinia odio - sem nec elit. Cras justo odio, dapibus ac facilisis in, egestas - eget quam. Donec id elit non mi porta gravida at eget metus. Donec - id elit non mi porta gravida at eget metus. Aenean lacinia - bibendum nulla sed consectetur. Vestibulum id ligula porta felis - euismod semper. Maecenas sed diam eget risus varius blandit sit - amet non magna. Etiam porta sem malesuada magna mollis euismod. - Donec ullamcorper nulla non metus auctor fringilla. Donec id elit - non mi porta gravida at eget metus. - - - )} - - {datum.name !== 'Donna' && datum.expandable && ( - - expanded name: {datum.name} - expanded age: {datum.age} - expanded color: {datum.color} - {datum.location} - - {datum.age > 30 && ( - - expanded name: {datum.name} - expanded age: {datum.age} - expanded color: {datum.color} - {datum.location} - - )} - - )} - - )} -
-); - -export const NoNestedRows = ({ withHeaders, ...args }: TableArgs) => ( - - - - datum.color} - dataType="string" - key="color" - /> - - - } - > - {({ datum }: { datum: any }) => ( - - {datum.name} - {datum.age} - {datum.color} - {datum.location} - - )} -
-); - -export const MultipleNestedRows = ({ - withHeaders, - ...args -}: TableArgs) => ( - sum + age, 0) / - defaultData.length - ).toFixed(2), - }, - ]} - columns={ - - - - - - - } - > - {({ datum }: { datum: any }) => ( - - {datum.title} - - {datum.people ? ( - datum.people.map((person: any) => ( - - {person.name} - {person.age} - {person.color} - {person.location} - - )) - ) : ( - {datum.age} - )} - - )} -
-); -MultipleNestedRows.args = { - withHeaders: true, -}; - -export const NestedRowsWithLongContent = ({ - withHeaders, - ...args -}: TableArgs) => ( - sum + age, 0) / - defaultData.length - ).toFixed(2), - }, - ]} - columns={ - - - - - - - } - style={{ maxWidth: '400px ' }} - > - {({ datum }: { datum: any }) => ( - - {datum.title} - - {datum.people ? ( - datum.people.map((person: any) => ( - - {person.name} - {person.age} - {person.color} - {person.location} - - )) - ) : ( - {datum.age} - )} - - )} -
-); -NestedRowsWithLongContent.args = { - withHeaders: true, -}; diff --git a/packages/table/src/TableV10/Table.tsx b/packages/table/src/TableV10/Table.tsx deleted file mode 100644 index 363b236a67..0000000000 --- a/packages/table/src/TableV10/Table.tsx +++ /dev/null @@ -1,261 +0,0 @@ -import React from 'react'; -import debounce from 'lodash/debounce'; -import { transparentize } from 'polished'; - -import { css, cx } from '@leafygreen-ui/emotion'; -import { - useIsomorphicLayoutEffect, - useViewportSize, -} from '@leafygreen-ui/hooks'; -import LeafyGreenProvider, { - useDarkMode, -} from '@leafygreen-ui/leafygreen-provider'; -import { HTMLElementProps } from '@leafygreen-ui/lib'; -import { palette } from '@leafygreen-ui/palette'; -import { fontFamilies, transitionDuration } from '@leafygreen-ui/tokens'; - -import { HeaderRowProps } from './HeaderRow'; -import { SortProvider } from './SortContext'; -import TableBody from './TableBody'; -import { TableProvider } from './TableContext'; -import TableHead from './TableHead'; -import { TableHeaderProps } from './TableHeader'; - -const lmShadowColor = transparentize(0.7, palette.black); -const dmShadowColor = transparentize(0.3, 'black'); - -const containerStyle = css` - position: relative; - max-width: 100%; -`; - -const tableStyles = css` - font-family: ${fontFamilies.default}; - position: relative; - border-collapse: collapse; - box-sizing: border-box; - width: 100%; - z-index: 0; -`; - -const shadow = css` - position: absolute; - top: 0; - bottom: 0; - width: 16px; - overflow: hidden; - pointer-events: none; - - &:after { - opacity: 0; - content: ''; - position: absolute; - top: 0; - bottom: 0; - width: 16px; - border-radius: 100%; - transition: opacity ${transitionDuration.default}ms ease-in-out; - } -`; - -const leftShadow = (darkMode: boolean) => css` - left: 0; - - &:after { - right: 100%; - box-shadow: ${darkMode - ? '4px 0 9px 5px ' + dmShadowColor - : '4px 0 4px ' + - lmShadowColor}; //TODO: Bug: currently the full height of the shadow is not showing unless the background color is removed from - } -`; - -const rightShadow = (darkMode: boolean) => css` - right: 0; - - &:after { - left: 100%; - box-shadow: ${darkMode - ? '-4px 0 9px 5px ' + dmShadowColor - : '-4px 0 4px ' + lmShadowColor}; - } -`; - -const showScroll = css` - &:after { - opacity: 1; - } -`; - -const ScrollState = { - None: 'none', - Left: 'left', - Right: 'right', - Both: 'both', -} as const; - -type ScrollState = (typeof ScrollState)[keyof typeof ScrollState]; - -/** - * @deprecated - */ -export interface TableRowInterface { - datum: Shape; - index: number; -} - -/** - * @deprecated - * @noDocgen - */ -export interface TableProps - extends Omit, 'children' | 'columns'> { - /** - * The array of data displayed in rows. Each array element's type is determined by the `Shape` generic. - * - * @type Array of Objects - */ - data: Array; - - /** - * React element to render the table's header row. - * @type Array of `` - */ - columns: - | React.ReactElement> - | Array>> - | React.ReactFragment; - - /** - * A function that takes in the datum of a single row as a parameter and returns a `JSX.Element` determining how it should be rendered. - * - * Should make use of the `` component. - * @type ({datum}) => JSX.Element - */ - children: (TableRowArgs: TableRowInterface) => JSX.Element; - - /** - * Override the global `baseFontSize` set in LeafyGreenProvider - */ - baseFontSize?: 14 | 16; - - /** - * Determines whether or not the component will appear in dark mode. - */ - darkMode?: boolean; -} - -/** - * @deprecated - * @noDocgen - */ -export default function Table({ - columns = [], - data: dataProp = [], - children, - className, - baseFontSize, - darkMode: darkModeProp, - ...rest -}: TableProps) { - const [scrollState, setScrollState] = React.useState( - ScrollState.None, - ); - const divRef = React.useRef(null); - const viewportSize = useViewportSize(); - const { darkMode } = useDarkMode(darkModeProp); - - useIsomorphicLayoutEffect(() => { - const divNode = divRef.current; - - if (divNode == null) { - return; - } - - if (divNode.scrollWidth > divNode.clientWidth) { - setScrollState(ScrollState.Right); - } else if ( - viewportSize != null && - divNode.getBoundingClientRect().width <= viewportSize.width - ) { - setScrollState(ScrollState.None); - } - }, [viewportSize]); - - const handleScroll = (e: React.UIEvent) => { - const { scrollWidth, clientWidth: elementWidth } = - e.target as HTMLDivElement; - const isScrollable = scrollWidth > elementWidth; - - if (isScrollable) { - const scrollPosition = (e.target as HTMLDivElement).scrollLeft; - const maxPosition = scrollWidth - elementWidth; - - if (scrollPosition > 0 && scrollPosition < maxPosition) { - setScrollState(ScrollState.Both); - } else if (scrollPosition > 0) { - setScrollState(ScrollState.Left); - } else if (scrollPosition < maxPosition) { - setScrollState(ScrollState.Right); - } - } - }; - - const debounceScroll = debounce(handleScroll, 50, { leading: true }); - - const onScroll: React.EventHandler = e => { - e.persist(); - debounceScroll(e); - }; - - const showLeft = - scrollState === ScrollState.Left || scrollState === ScrollState.Both; - const showRight = - scrollState === ScrollState.Right || scrollState === ScrollState.Both; - - return ( -
-
-
- -
- - - - - - {children} - - - -
-
-
- ); -} -Table.displayName = 'Table'; -// TODO: missing proptypes diff --git a/packages/table/src/TableV10/TableBody.tsx b/packages/table/src/TableV10/TableBody.tsx deleted file mode 100644 index 9c99781bd6..0000000000 --- a/packages/table/src/TableV10/TableBody.tsx +++ /dev/null @@ -1,81 +0,0 @@ -import React, { useCallback, useMemo } from 'react'; - -import { getDataComparisonFunction, useSortContext } from './SortContext'; -import { TableProps, TableRowInterface } from './Table'; -import { useTableContext } from './TableContext'; - -/** - * @deprecated - */ -type TableBodyProps = Pick, 'children'>; - -/** - * Hook that avoids re-rendering children when the data used to - * render them hasn't changed, even if their ordering has changed. - */ -function useRenderedChildren( - data: Array, - renderFunction: React.FunctionComponent< - React.PropsWithChildren> - >, - compareFn?: (a: Datum, b: Datum) => number, -): Array { - const resultMap = useMemo(() => { - const resultMap = new Map(); - data.forEach((datum, index) => - resultMap.set( - datum, - - {renderFunction({ datum, index })} - , - ), - ); - return resultMap; - }, [data, renderFunction]); - - return useMemo(() => { - if (!compareFn) { - return Array.from(resultMap.values()); - } - - return [...data].sort(compareFn).map(datum => resultMap.get(datum)); - }, [data, resultMap, compareFn]); -} - -/** - * @deprecated - */ -function TableBody({ children }: TableBodyProps) { - const { - state: { data }, - } = useTableContext(); - - const { sort } = useSortContext(); - - const compareFn = useMemo(() => { - if (sort) { - const { direction, accessorValue, compareFn } = sort; - - if (compareFn) { - return getDataComparisonFunction({ direction, compareFn }); - } - - if (accessorValue) { - return getDataComparisonFunction({ direction, accessorValue }); - } - } - }, [sort]); - - const renderFunction = useCallback( - ({ datum, index }: TableRowInterface) => children({ datum, index }), - [children], - ); - - const rows = useRenderedChildren(data, renderFunction, compareFn); - - return {rows}; -} - -TableBody.displayName = 'TableBody'; - -export default TableBody; diff --git a/packages/table/src/TableV10/TableContext.tsx b/packages/table/src/TableV10/TableContext.tsx deleted file mode 100644 index cfadc089b5..0000000000 --- a/packages/table/src/TableV10/TableContext.tsx +++ /dev/null @@ -1,167 +0,0 @@ -import React, { - createContext, - useContext, - useEffect, - useMemo, - useReducer, -} from 'react'; - -const TableActionTypes = { - RegisterColumn: 'REGISTER_COLUMN_INFO', - SetHasNestedRows: 'SET_HAS_NESTED_ROWS', - SetHasRowSpan: 'SET_HAS_ROW_SPAN', - SetData: 'SET_DATA', -} as const; - -/** - * @deprecated - */ -type TableActionTypes = - (typeof TableActionTypes)[keyof typeof TableActionTypes]; - -export { TableActionTypes }; - -/** - * @deprecated - */ -interface ActionPayload { - [TableActionTypes.RegisterColumn]: { - dataType?: DataType; - index: number; - }; - [TableActionTypes.SetData]: Array; - [TableActionTypes.SetHasRowSpan]: boolean; - [TableActionTypes.SetHasNestedRows]: boolean; -} - -type ActionMap> = { - [Key in keyof A]: A[Key] extends undefined - ? { - type: Key; - } - : { - type: Key; - payload: A[Key]; - }; -}; - -type Action = ActionMap[keyof ActionMap]; - -type Dispatch = (action: Action) => void; - -const DataType = { - Number: 'number', - Weight: 'weight', - ZipCode: 'zipCode', - String: 'string', - Date: 'date', -} as const; - -type DataType = (typeof DataType)[keyof typeof DataType]; - -export { DataType }; - -/** - * @deprecated - */ -export interface State { - data: Array; - columnInfo?: Record; - hasNestedRows?: boolean; - hasRowSpan?: boolean; -} - -/** - * @deprecated - */ -interface TableProviderInterface { - children: React.ReactNode; - data: Array; -} - -/** - * @deprecated - */ -interface ContextInterface { - state: State; - dispatch: Dispatch; -} - -/** - * @deprecated - */ -const TableContext = createContext({ - state: { - data: [], - }, - dispatch: () => {}, -}); - -/** - * @deprecated - */ -export function reducer(state: State, action: Action): State { - switch (action.type) { - case TableActionTypes.SetHasRowSpan: - return { - ...state, - hasRowSpan: action.payload, - }; - - case TableActionTypes.SetHasNestedRows: - return { - ...state, - hasNestedRows: action.payload, - }; - - case TableActionTypes.RegisterColumn: - return { - ...state, - columnInfo: { - ...state.columnInfo, - [action.payload.index]: { - dataType: action.payload.dataType, - }, - }, - }; - - case TableActionTypes.SetData: - return { - ...state, - data: action.payload, - }; - - default: - return state; - } -} - -export function TableProvider({ children, data }: TableProviderInterface) { - const initialState: State = { - data, - hasNestedRows: false, - }; - - const [state, dispatch] = useReducer(reducer, initialState); - - useEffect(() => { - dispatch({ - type: TableActionTypes.SetData, - payload: data, - }); - }, [data]); - - const contextValue = useMemo(() => { - return { state, dispatch }; - }, [state, dispatch]); - - return ( - - {children} - - ); -} - -export function useTableContext() { - return useContext(TableContext); -} diff --git a/packages/table/src/TableV10/TableHead.tsx b/packages/table/src/TableV10/TableHead.tsx deleted file mode 100644 index b71730c71b..0000000000 --- a/packages/table/src/TableV10/TableHead.tsx +++ /dev/null @@ -1,67 +0,0 @@ -import React from 'react'; - -import { isComponentType } from '@leafygreen-ui/lib'; - -import HeaderRow, { HeaderRowElement } from './HeaderRow'; -import { TableProps } from './Table'; -import { TableHeaderElement } from './TableHeader'; - -/** - * @deprecated - */ -type TableHeaderProps = Pick, 'columns'>; - -/** - * @deprecated - */ -function TableHead({ columns = [] }: TableHeaderProps) { - const usingHeaderRow = React.useRef(false); - - function createCols(array: Array): React.ReactNode { - return array.map((child, index) => { - const tableHeaderCommonProps = { - key: index, - index, - }; - - if (isComponentType(child, 'HeaderRow')) { - usingHeaderRow.current = true; - - // FIXME: - // eslint-disable-next-line no-unsafe-optional-chaining - const { children } = child?.props; - - return React.cloneElement(child, { - children: createCols(React.Children.toArray(children)), - }); - } - - if (isComponentType(child, 'TableHeader')) { - return React.cloneElement(child, tableHeaderCommonProps); - } - - return child; - }); - } - - const columnArray: Array = - // @ts-expect-error Property 'type' does not exist on type '{}'.ts(2339) - columns.type === React.Fragment || - isComponentType(columns, 'HeaderRow') - ? React.Children.toArray((columns as React.ReactElement).props.children) - : (columns as Array); - - const cols = createCols(columnArray); - - if (usingHeaderRow.current) { - return {cols}; - } - - return ( - - {cols} - - ); -} - -export default TableHead; diff --git a/packages/table/src/TableV10/TableHeader.tsx b/packages/table/src/TableV10/TableHeader.tsx deleted file mode 100644 index eaa4ffd694..0000000000 --- a/packages/table/src/TableV10/TableHeader.tsx +++ /dev/null @@ -1,276 +0,0 @@ -import React from 'react'; - -import { css, cx } from '@leafygreen-ui/emotion'; -import SortAscendingIcon from '@leafygreen-ui/icon/dist/SortAscending'; -import SortDescendingIcon from '@leafygreen-ui/icon/dist/SortDescending'; -import UnsortedIcon from '@leafygreen-ui/icon/dist/Unsorted'; -import IconButton from '@leafygreen-ui/icon-button'; -import { useDarkMode } from '@leafygreen-ui/leafygreen-provider'; -import { enforceExhaustive, Theme } from '@leafygreen-ui/lib'; -import { palette } from '@leafygreen-ui/palette'; -import { useUpdatedBaseFontSize } from '@leafygreen-ui/typography'; - -import { SortDirection, useSortContext } from './SortContext'; -import { getCommonCellStyles } from './styles'; -import { DataType, TableActionTypes, useTableContext } from './TableContext'; - -type StyledElements = 'thStyle' | 'labelStyle' | 'glyphColor'; - -const themeStyles: Record> = { - [Theme.Light]: { - thStyle: css` - border-color: ${palette.gray.light2}; - `, - labelStyle: css` - color: ${palette.gray.dark3}; - `, - glyphColor: css` - color: ${palette.blue.base}; - `, - }, - - [Theme.Dark]: { - thStyle: css` - background-color: ${palette.black}; - border-color: ${palette.gray.dark2}; - `, - labelStyle: css` - color: ${palette.gray.light2}; - `, - glyphColor: css` - color: ${palette.blue.light1}; - `, - }, -}; - -const thStyle = css` - border-bottom: 3px solid; -`; - -const flexDisplay = css` - display: flex; - justify-content: space-between; - align-items: center; -`; - -const labelStyle = css` - padding-right: 4px; -`; - -const iconButtonMargin = css` - margin: -4px 0; -`; - -const glyphMap = { - unsorted: UnsortedIcon, - asc: SortDescendingIcon, - desc: SortAscendingIcon, -} as const; - -type NormalizedAccessor = T extends string - ? (data: U) => T extends keyof U ? U[T] : undefined - : T; -export function normalizeAccessor( - accessor: T, -): NormalizedAccessor { - let accessorFn = accessor as NormalizedAccessor; - - if (typeof accessor === 'string') { - if (accessor.includes('.')) { - const accessorArr = accessor.split('.'); - - accessorFn = ((data: any) => { - return accessorArr.reduce((obj, access) => { - return obj[access]; - }, data); - }) as NormalizedAccessor; - } else { - accessorFn = ((data: any) => data[accessor]) as NormalizedAccessor; - } - } - - return accessorFn; -} - -/** - * @deprecated - * @noDocgen - */ -interface TableHeaderInterface { - /** - * The label of the column - * - * @type string - */ - label: React.ReactElement | string; - - /** - * The index of the column - */ - index?: number; - - /** - * Callback fired when the header is clicked - */ - onClick?: ( - colId: number, - accessorValue: ((data: any) => string) | string, - ) => void; - - /** - * A callback to define which property of the data structure to sort on - */ - sortBy?: ((data: Shape) => string) | string; - - /** - * A callback to provide more customization in column sorting. - * This callback has a similar signature to the Array.sort method, - * with the addition of a `direction` parameter, which has values `asc` or `desc`. - * - * Pin a row to the top by returning -1 if `a` matches, and 1 if `b` matches the desired row - */ - compareFn?: (a: Shape, b: Shape, direction: SortDirection) => number; - - /** - * A callback that gets called when a user initiates sort on the column. - * Internal sorting is disabled when this callback is provided. - */ - handleSort?: (direction: SortDirection) => void; - - /** - * The type of data as a `DataType` - */ - dataType?: DataType; -} - -export type TableHeaderProps = Omit< - React.ComponentPropsWithoutRef<'th'>, - keyof TableHeaderInterface -> & - TableHeaderInterface; - -export type TableHeaderElement = React.ReactComponentElement< - typeof TableHeader ->; - -/** - * @deprecated - * @noDocgen - */ -function TableHeader({ - label, - onClick, - index, - className, - dataType, - sortBy, - compareFn, - handleSort, - ...rest -}: TableHeaderProps) { - const { dispatch } = useTableContext(); - const { sort, setSort } = useSortContext(); - const baseFontSize = useUpdatedBaseFontSize(); - const { theme, darkMode } = useDarkMode(); - - React.useEffect(() => { - if (typeof index === 'number') { - dispatch({ - type: TableActionTypes.RegisterColumn, - payload: { - // Offsetting 0-index - index: index + 1, - dataType, - }, - }); - } - }, [index, dataType, dispatch]); - - const normalizedAccessor = sortBy && normalizeAccessor(sortBy); - const isSortable = !!(sortBy || compareFn || handleSort); - - const sortDirection = sort && sort.columnId === index ? sort.direction : null; - const glyph: 'unsorted' | SortDirection = sortDirection ?? 'unsorted'; - const Glyph = glyphMap[glyph]; - - const sortRows = () => { - if (typeof index === 'number' && isSortable) { - const newDirection: SortDirection = - index === sort?.columnId - ? sort.direction === 'asc' - ? 'desc' - : 'asc' - : 'desc'; - - // eslint-disable-next-line @typescript-eslint/no-unused-vars - setSort(prevSort => { - return { - columnId: index, - direction: newDirection, - accessorValue: normalizedAccessor || undefined, - compareFn, - }; - }); - - handleSort?.(newDirection); - } - }; - - let ariaSort: React.AriaAttributes['aria-sort']; - - switch (sortDirection) { - case 'asc': - ariaSort = 'ascending'; - break; - case 'desc': - ariaSort = 'descending'; - break; - case null: - ariaSort = 'none'; - break; - default: - enforceExhaustive(sortDirection); - } - - return ( - -
- - {label} - - {isSortable && ( - - - - )} -
- - ); -} - -TableHeader.displayName = 'TableHeader'; - -export default TableHeader; diff --git a/packages/table/src/TableV10/fixtures.testutils.ts b/packages/table/src/TableV10/fixtures.testutils.ts deleted file mode 100644 index 31dd7bbf0d..0000000000 --- a/packages/table/src/TableV10/fixtures.testutils.ts +++ /dev/null @@ -1,229 +0,0 @@ -import { faker } from '@faker-js/faker'; -const SEED = 0; -faker.seed(SEED); - -// eslint-disable-next-line @typescript-eslint/naming-convention -export interface testTableDataShape { - name: string; - age: number; - color: string; - location: string; - rand: number; - disabled?: boolean; - expandable?: boolean; -} - -export const defaultData: Array = [ - { - name: 'Alice', - age: 19, - color: 'blue', - location: 'bedford', - rand: faker.number.float({ precision: 0.001 }), - }, - { - name: 'Brooke', - age: 20, - color: 'green', - location: 'bedford', - rand: faker.number.float({ precision: 0.001 }), - }, - { - name: 'Charlotte', - age: 21, - color: 'white', - location: 'bedford', - rand: faker.number.float({ precision: 0.001 }), - disabled: true, - }, - { - name: 'Donna', - age: 22, - color: 'green', - location: 'bedford', - rand: faker.number.float({ precision: 0.001 }), - }, - { - name: 'Emma', - age: 23, - color: 'white', - location: 'bedford', - rand: faker.number.float({ precision: 0.001 }), - expandable: true, - }, - { - name: 'Georgia', - age: 24, - color: 'white', - location: 'bedford', - rand: faker.number.float({ precision: 0.001 }), - expandable: true, - }, - { - name: 'Frannie', - age: 29, - color: 'green', - location: 'bedford', - rand: faker.number.float({ precision: 0.001 }), - expandable: true, - }, - { - name: 'Iman', - age: 26, - color: 'white', - location: 'bedford', - rand: faker.number.float({ precision: 0.001 }), - expandable: true, - }, - { - name: 'Hannah', - age: 27, - color: 'green', - location: 'bedford', - rand: faker.number.float({ precision: 0.001 }), - expandable: true, - }, - { - name: 'Jill', - age: 28, - color: 'green', - location: 'bedford', - rand: faker.number.float({ precision: 0.001 }), - expandable: true, - }, - { - name: 'Karen', - age: 31, - color: 'orange', - location: 'bedford', - rand: faker.number.float({ precision: 0.001 }), - expandable: true, - }, - { - name: 'Lilly', - age: 32, - color: 'pink', - location: 'bedford', - rand: faker.number.float({ precision: 0.001 }), - expandable: true, - }, - { - name: 'Monica', - age: 33, - color: 'green', - location: 'bedford', - rand: faker.number.float({ precision: 0.001 }), - expandable: true, - }, - { - name: 'Nicole', - age: 35, - color: 'green', - location: 'bedford', - rand: faker.number.float({ precision: 0.001 }), - expandable: true, - }, - { - name: 'Ophelia', - age: 34, - color: 'lavender', - location: 'bedford', - rand: faker.number.float({ precision: 0.001 }), - expandable: true, - }, - { - name: 'Penelope', - age: 30, - color: 'perrywinkle', - location: 'bedford', - rand: faker.number.float({ precision: 0.001 }), - expandable: true, - }, - { - name: 'Queen', - age: 36, - color: 'gold', - location: 'bedford', - rand: faker.number.float({ precision: 0.001 }), - expandable: true, - }, - { - name: 'Rachel', - age: 39, - color: 'orange', - location: 'bedford', - rand: faker.number.float({ precision: 0.001 }), - expandable: true, - }, - { - name: 'Sarah', - age: 40, - color: 'navy', - location: 'bedford', - rand: faker.number.float({ precision: 0.001 }), - expandable: true, - }, - { - name: 'Tina', - age: 44, - color: 'cyan', - location: 'bedford', - rand: faker.number.float({ precision: 0.001 }), - expandable: true, - }, - { - name: 'Ursula', - age: 45, - color: 'purple', - location: 'bedford', - rand: faker.number.float({ precision: 0.001 }), - expandable: true, - }, - { - name: 'Violet', - age: 49, - color: 'violet', - location: 'bedford', - rand: faker.number.float({ precision: 0.001 }), - expandable: true, - }, - { - name: 'Wendy', - age: 54, - color: 'blue', - location: 'bedford', - rand: faker.number.float({ precision: 0.001 }), - expandable: true, - }, - { - name: 'Ximena', - age: 48, - color: 'green', - location: 'bedford', - rand: faker.number.float({ precision: 0.001 }), - expandable: true, - }, - { - name: 'Yvonne', - age: 51, - color: 'pink', - location: 'bedford', - rand: faker.number.float({ precision: 0.001 }), - expandable: true, - }, - { - name: 'Zara', - age: 48, - color: 'green', - location: 'bedford', - rand: faker.number.float({ precision: 0.001 }), - expandable: true, - }, -]; - -export const multiRowData = [ - { flavor: 'Chocolate', price: '$8.00' }, - { flavor: 'Vanilla', price: '$4.00' }, - { flavor: 'Funfetti', price: '$6.00' }, - { price: '$3.00' }, -]; diff --git a/packages/table/src/TableV10/index.ts b/packages/table/src/TableV10/index.ts deleted file mode 100644 index 6512a8c714..0000000000 --- a/packages/table/src/TableV10/index.ts +++ /dev/null @@ -1,6 +0,0 @@ -export { default as Cell } from './Cell'; -export { default as HeaderRow } from './HeaderRow'; -export { default as Row } from './Row'; -export { default as Table } from './Table'; -export { DataType } from './TableContext'; -export { default as TableHeader } from './TableHeader'; diff --git a/packages/table/src/TableV10/styles.tsx b/packages/table/src/TableV10/styles.tsx deleted file mode 100644 index a08cc4221d..0000000000 --- a/packages/table/src/TableV10/styles.tsx +++ /dev/null @@ -1,18 +0,0 @@ -import { css } from '@leafygreen-ui/emotion'; -import { bodyTypeScaleStyles } from '@leafygreen-ui/typography'; - -const sharedStyles = css` - --lg-cell-padding-block: 10px; - min-width: 40px; - padding: var(--lg-cell-padding-block) 8px; - box-sizing: border-box; - vertical-align: baseline; - text-align: left; // Justification is updated in \`Row.tsx\` for number cells -`; - -export const getCommonCellStyles = (baseFontSize: 13 | 16): string => { - return css` - ${sharedStyles} - ${bodyTypeScaleStyles[baseFontSize]} - `; -}; diff --git a/packages/table/src/TableV10/testUtils.tsx b/packages/table/src/TableV10/testUtils.tsx deleted file mode 100644 index 9fa87831bb..0000000000 --- a/packages/table/src/TableV10/testUtils.tsx +++ /dev/null @@ -1,50 +0,0 @@ -import React from 'react'; -import { render, screen } from '@testing-library/react'; - -import '@testing-library/jest-dom/extend-expect'; - -import { defaultData, testTableDataShape } from './fixtures.testutils'; -import { Cell, Row, Table, TableHeader } from '.'; - -interface Props { - table?: any; - row?: any; -} - -export const defaultColumns = [ - , - , - , - , -]; - -export function renderTable(props: Props = {}) { - const { rerender } = render( - - {({ datum }: { datum: testTableDataShape }) => ( - - {datum.name} - {datum.age} - {datum.color} - {datum.location} - - {datum.expandable && ( - - hidden: {datum.name} - expanded age: {datum.age} - expanded color: {datum.color} - {datum.location} - - )} - - )} -
, - ); - const table = screen.getByTestId('table'); - return { table, rerender }; -} diff --git a/packages/table/src/TableV10/useSSR.ts b/packages/table/src/TableV10/useSSR.ts deleted file mode 100644 index 0c59e9787a..0000000000 --- a/packages/table/src/TableV10/useSSR.ts +++ /dev/null @@ -1,63 +0,0 @@ -/** - * There is a security vulnerability related to https://github.com/alex-cory/use-ssr - * The only location this package is used is within the Table component, in Row.tsx. - * - * TODO: In the long term, we should re-evaluate its usage and whether it's needed, - * and if it is, maintain our own useSSR hook instead within the @leafygreen-ui/hooks package. - */ - -interface UseSSRReturn { - isBrowser: boolean; - isServer: boolean; - isNative: boolean; - device: Device; - canUseWorkers: boolean; - canUseEventListeners: boolean; - canUseViewport: boolean; -} - -export enum Device { - Browser = 'browser', - Server = 'server', - Native = 'native', -} - -const { Browser, Server, Native } = Device; - -const canUseDOM = !!( - typeof window !== 'undefined' && - window.document && - window.document.createElement -); - -const canUseNative: boolean = - typeof navigator != 'undefined' && navigator.product == 'ReactNative'; - -const device = canUseNative ? Native : canUseDOM ? Browser : Server; - -const SSRObject = { - isBrowser: device === Browser, - isServer: device === Server, - isNative: device === Native, - device, - canUseWorkers: typeof Worker !== 'undefined', - canUseEventListeners: device === Browser && !!window.addEventListener, - canUseViewport: device === Browser && !!window.screen, -}; - -// TODO: instead of this, do a polyfill for `Object.assign` https://www.npmjs.com/package/es6-object-assign -const assign = (...args: Array) => - args.reduce((acc, obj) => ({ ...acc, ...obj }), {}); -const values = (obj: any) => Object.keys(obj).map(key => obj[key]); -const toArrayObject = (): UseSSRReturn => - assign((values(SSRObject), SSRObject)); - -let useSSRObject = toArrayObject(); - -export const weAreServer = () => { - SSRObject.isServer = true; - useSSRObject = toArrayObject(); -}; - -export const useSSR = (): UseSSRReturn => useSSRObject; -export default useSSR; diff --git a/packages/table/src/V11Adapter/V11Adapter.spec.tsx b/packages/table/src/V11Adapter/V11Adapter.spec.tsx deleted file mode 100644 index f9819330d4..0000000000 --- a/packages/table/src/V11Adapter/V11Adapter.spec.tsx +++ /dev/null @@ -1,436 +0,0 @@ -import React, { useState } from 'react'; -import { getAllByRole } from '@testing-library/dom'; -import { fireEvent, render, screen } from '@testing-library/react'; -import { axe } from 'jest-axe'; - -import { Cell } from '../Cell'; -import { HeaderRow, Row } from '../Row'; -import { TableHeader } from '../TableV10'; -import { Table } from '../TableV10'; -import { defaultData } from '../TableV10/fixtures.testutils'; - -import V11Adapter, { V11AdapterProps } from '.'; - -const data = defaultData.slice(0, 8); - -function BasicWithAdapter(props: V11AdapterProps) { - return ( - - - - - - - - } - > - {({ datum }: any) => ( - - {datum.name} - {datum.age} - {datum.color} - {datum.location} - - )} -
-
- ); -} - -const SortableColumns = () => { - return ( - - - { - const reverse = (str: string) => - str.split('').reverse().join(''); - - // Pin 'Yvonne' to the top - if (b.name === 'Yvonne') return 1; - else if (a.name === 'Yvonne') return -1; - - // Sort by reversed name - if (dir == 'desc') { - return reverse(b.name) >= reverse(a.name) ? 1 : -1; - } - - return reverse(b.name) >= reverse(a.name) ? -1 : 1; - }} - /> - datum.age.toString()} - /> - datum.color} - /> - { - // eslint-disable-next-line no-console - console.log(`Sorting location ${dir}`); - }} - /> - - } - > - {({ datum }: any) => ( - - {datum.name} - {datum.age} - {datum.color} - {datum.location} - - )} -
-
- ); -}; - -const NestedRows = () => { - return ( - - - - - - - - } - data-testid="test-table" - > - {({ datum }: any) => ( - - - {datum.name} - - {datum.age} - {datum.color} - {datum.location} - {datum.name !== 'Donna' && ( - - - expanded name: {datum.name} - - expanded age: {datum.age} - expanded color: {datum.color} - expanded location: {datum.location} - - )} - - )} -
-
- ); -}; - -const ExpandableContent = () => { - return ( - - - - - - - - } - > - {({ datum }: any) => ( - - {datum.name} - {datum.age} - {datum.color} - {datum.location} - {datum.name === 'Donna' && ( - - - Nulla vitae elit libero, a pharetra augue. Sed posuere - consectetur est at lobortis. Integer posuere erat a ante - venenatis dapibus posuere velit aliquet. Maecenas faucibus - mollis interdum. Nullam id dolor id nibh ultricies vehicula ut - id elit. Duis mollis, est non commodo luctus, nisi erat - porttitor ligula, eget lacinia odio sem nec elit. Cras justo - odio, dapibus ac facilisis in, egestas eget quam. Donec id - elit non mi porta gravida at eget metus. Donec id elit non mi - porta gravida at eget metus. Aenean lacinia bibendum nulla sed - consectetur. Vestibulum id ligula porta felis euismod semper. - Maecenas sed diam eget risus varius blandit sit amet non - magna. Etiam porta sem malesuada magna mollis euismod. Donec - ullamcorper nulla non metus auctor fringilla. Donec id elit - non mi porta gravida at eget metus. - - - )} - - )} -
-
- ); -}; - -function StatefulDataTest(props: V11AdapterProps) { - const [data, setData] = useState(defaultData.slice(0, 3)); - return ( - <> - - - - - - - - - } - > - {({ datum }: any) => ( - - {datum.name} - {datum.age} - {datum.color} - {datum.location} - - )} -
-
- - ); -} - -jest.mock('react', () => ({ - ...jest.requireActual('react'), - useLayoutEffect: jest.requireActual('react').useEffect, -})); - -describe('packages/table/Table', () => { - describe('a11y', () => { - test('does not have basic accessibility issues', async () => { - const { container } = render(); - const results = await axe(container); - expect(results).toHaveNoViolations(); - }); - }); - - describe('stateful data change', () => { - test('v11 adapter responds to stateful data change on v10 table', async () => { - const { getByTestId, queryByText } = render(); - expect(queryByText('test')).not.toBeInTheDocument(); - const refreshButton = getByTestId('refresh-data'); - fireEvent.click(refreshButton); - expect(queryByText('test name')).toBeInTheDocument(); - expect(queryByText('test color')).toBeInTheDocument(); - expect(queryByText('test location')).toBeInTheDocument(); - }); - }); - - describe('selectable rows', () => { - test('renders checkboxes', async () => { - const { getAllByRole } = render(); - // +1 for the header row checkbox - expect(getAllByRole('checkbox').length).toBe(data.length + 1); - }); - - test('clicking checkbox marks it as checked', async () => { - const { getAllByRole } = render(); - const firstCheckbox = getAllByRole('checkbox')[1]; - fireEvent.click(firstCheckbox); - expect(firstCheckbox.getAttribute('aria-checked')).toBe('true'); - }); - - test('clicking the header checkbox updates all checkboxes', async () => { - const { getAllByRole } = render(); - const allCheckboxes = getAllByRole('checkbox'); - const headerCheckbox = allCheckboxes[0]; - fireEvent.click(headerCheckbox); - allCheckboxes.forEach(checkbox => { - expect(checkbox.getAttribute('aria-checked')).toBe('true'); - }); - }); - }); - - describe('sortable rows', () => { - test('renders sort icon', async () => { - const { getAllByTestId, queryByLabelText, getAllByLabelText } = render( - , - ); - expect(getAllByTestId('lg-table-sort-icon-button').length).toBe(4); - expect(getAllByLabelText('Unsorted Icon').length).toBe(4); - expect(queryByLabelText('Sort Descending Icon')).not.toBeInTheDocument(); - expect(queryByLabelText('Sort Ascending Icon')).not.toBeInTheDocument(); - }); - - test('clicking sort icon toggles icon', async () => { - const { getAllByTestId, queryByLabelText, getAllByLabelText } = render( - , - ); - expect(getAllByTestId('lg-table-sort-icon-button').length).toBe(4); - expect(getAllByLabelText('Unsorted Icon').length).toBe(4); - expect(queryByLabelText('Sort Descending Icon')).not.toBeInTheDocument(); - expect(queryByLabelText('Sort Ascending Icon')).not.toBeInTheDocument(); - const sortIconButton = getAllByLabelText('Unsorted Icon')[0]; - fireEvent.click(sortIconButton); - expect(queryByLabelText('Sort Descending Icon')).toBeInTheDocument(); - expect(queryByLabelText('Sort Ascending Icon')).not.toBeInTheDocument(); - }); - - test('clicking sort icon renders correct value at the top', async () => { - const { getByLabelText, getAllByLabelText } = render(); - const sortIconButton = getAllByLabelText('Unsorted Icon')[0]; - fireEvent.click(sortIconButton); - expect(getByLabelText('Sort Descending Icon')).toBeInTheDocument(); - const tableCells = screen.getAllByRole('cell'); - const firstCell = tableCells[0]; - expect(firstCell).toHaveTextContent('Lilly'); - }); - - test('clicking sort icon twice render correct value at the top', async () => { - const { getByLabelText, getAllByLabelText } = render(); - const sortIconButton = getAllByLabelText('Unsorted Icon')[0]; - fireEvent.click(sortIconButton); - const descSortIconButton = getByLabelText('Sort Descending Icon'); - fireEvent.click(descSortIconButton); - expect(getByLabelText('Sort Ascending Icon')).toBeInTheDocument(); - const tableCells = screen.getAllByRole('cell'); - const firstCell = tableCells[0]; - expect(firstCell).toHaveTextContent('Yvonne'); - }); - - test('clicking sort icon thrice renders the initial value at the top', async () => { - const { getAllByLabelText, getByLabelText } = render(); - const sortIconButton = getAllByLabelText('Unsorted Icon')[0]; - fireEvent.click(sortIconButton); - const descSortIconButton = getByLabelText('Sort Descending Icon'); - fireEvent.click(descSortIconButton); - const ascSortIconButton = getByLabelText('Sort Ascending Icon'); - fireEvent.click(ascSortIconButton); - const tableCells = screen.getAllByRole('cell'); - const firstCell = tableCells[0]; - expect(firstCell).toHaveTextContent('Alice'); - }); - }); - - describe('nested rows', () => { - test('renders the correct number of children', () => { - const { getAllByRole: getAllByRoleLocal } = render(); - const firstRow = getAllByRoleLocal('row')[1]; - expect(getAllByRole(firstRow, 'cell').length).toBe(4); - }); - test('rows with nested rows render expand icon button', async () => { - const { getAllByLabelText } = render(); - const expandIconButtons = getAllByLabelText('Expand row'); - expect(expandIconButtons.length).toBe(7); // Row with 'Donna' is not expandable - }); - test('having a row with nested rows render all rows as tbody elements', async () => { - const { getAllByRole } = render(); - expect(getAllByRole('rowgroup').length).toBe(9); // 1 for thead, 9 for tbody - }); - test('all data- attributes are passed to all elements', async () => { - const { getByTestId } = render(); - expect(getByTestId('test-table')).toBeInTheDocument(); - expect(getByTestId('test-header-row')).toBeInTheDocument(); - expect(getByTestId('test-header-cell')).toBeInTheDocument(); - expect(getByTestId('test-row')).toBeInTheDocument(); - expect(getByTestId('test-cell')).toBeInTheDocument(); - expect(getByTestId('test-nested-row')).toBeInTheDocument(); - expect(getByTestId('test-nested-cell')).toBeInTheDocument(); - }); - // eslint-disable-next-line jest/no-disabled-tests - test.skip('clicking expand icon button renders collapse button and nested row content', async () => { - const { getByLabelText, getAllByLabelText, queryByText } = render( - , - ); - const expandIconButton = getAllByLabelText('Expand row')[0]; - // the line below is not reliable as the row is expanded - the height is just 0 - expect(queryByText('expanded')).not.toBeVisible(); - fireEvent.click(expandIconButton); - const collapseIconButton = getByLabelText('Collapse row'); - expect(collapseIconButton).toBeInTheDocument(); - // the line below is not reliable as the row is expanded - the height is just 0 - expect(queryByText('expanded')).toBeVisible(); - }); - }); - - describe('expandable content', () => { - test('renders the correct number of cell children', () => { - const { getAllByRole: getAllByRoleLocal } = render(); - const firstRow = getAllByRoleLocal('row')[1]; - expect(getAllByRole(firstRow, 'cell').length).toBe(4); - }); - test('rows with expandable content render expand icon button', async () => { - const { getAllByLabelText } = render(); - const expandIconButtons = getAllByLabelText('Expand row'); - expect(expandIconButtons.length).toBe(1); // Row with 'Donna' is the only expandable - }); - test('rows with expandable content render rows as tbody elements', async () => { - const { getAllByRole } = render(); - expect(getAllByRole('rowgroup').length).toBe(9); // 1 for thead, 9 for tbody - }); - // eslint-disable-next-line jest/no-disabled-tests - test.skip('clicking expand icon button renders collapse button and expanded content', async () => { - const { getByLabelText, queryByText } = render(); - const expandIconButton = getByLabelText('Expand row'); - // the line below is not reliable as the row is expanded - the height is just 0 - expect(queryByText('Expandable content test')).not.toBeInTheDocument(); - fireEvent.click(expandIconButton); - const collapseIconButton = getByLabelText('collapse row'); - expect(collapseIconButton).toBeInTheDocument(); - // the line below is not reliable as the row is expanded - the height is just 0 - expect(queryByText('Expandable content test')).toBeInTheDocument(); - }); - }); -}); diff --git a/packages/table/src/V11Adapter/V11Adapter.stories.tsx b/packages/table/src/V11Adapter/V11Adapter.stories.tsx deleted file mode 100644 index edeadf7a15..0000000000 --- a/packages/table/src/V11Adapter/V11Adapter.stories.tsx +++ /dev/null @@ -1,523 +0,0 @@ -import React, { useState } from 'react'; -import { faker } from '@faker-js/faker'; -import { StoryMetaType } from '@lg-tools/storybook-utils'; -import { StoryFn } from '@storybook/react'; - -import Badge from '@leafygreen-ui/badge'; -import { css } from '@leafygreen-ui/emotion'; - -import { defaultData } from '../TableV10/fixtures.testutils'; -import { makeData } from '../utils/makeData.testutils'; -import { - V10Cell as Cell, - V10HeaderRow as HeaderRow, - V10Row as Row, - V10Table as Table, - V10TableHeader as TableHeader, - V11Adapter, -} from '..'; - -import { V11AdapterProps } from './V11Adapter.types'; - -type StoryAdapterProps = V11AdapterProps; - -const meta: StoryMetaType = { - title: 'Components/Table/V11 Adapter', - component: V11Adapter, - parameters: { - default: null, - chromatic: { - disableSnapshot: true, - }, - }, -}; -export default meta; - -const virtualScrollingContainerHeight = css` - height: 500px; -`; - -export const Basic: StoryFn = () => { - return ( - - - - - - - - } - > - {({ datum }: any) => ( - - {datum.name} - {datum.age} - {datum.color} - {datum.location} - - )} -
-
- ); -}; - -export const DynamicData: StoryFn = () => { - const [data, setData] = useState(defaultData.slice(0, 8)); - - const handleClick = () => { - setData( - defaultData.slice( - 2, - faker.number.int({ min: 0, max: defaultData.length }), - ), - ); - }; - - return ( - <> - - - - - - - - - } - > - {({ datum }: any) => ( - - {datum.name} - {datum.age} - {datum.color} - {datum.location} - - )} -
-
- - ); -}; - -export const BasicVS: StoryFn = () => { - return ( - - - - - - - - } - > - {({ datum }: any) => ( - - {datum.firstName} - {datum.lastName} - {datum.visits} - {datum.status} - - )} -
-
- ); -}; - -export const DefaultZebraStripes: StoryFn = () => { - return ( - - - - - - - - } - > - {({ datum }: any) => ( - - {datum.name} - {datum.age} - {datum.color} - {datum.location} - - )} -
-
- ); -}; - -export const NestedRows: StoryFn = () => { - return ( - - - - - - - - } - > - {({ datum }: any) => ( - - {datum.name} - {datum.age} - {datum.color} - {datum.location} - {datum.name !== 'Donna' && ( - - - {datum.rand < 0.5 && Low Rand} - expanded name: {datum.name} - - expanded age: {datum.age} - expanded color: {datum.color} - expanded location: {datum.location} - - )} - - )} -
-
- ); -}; - -export const NestedRowsVS: StoryFn = () => { - return ( - - - - - - - - } - > - {({ datum }: any) => ( - - {datum.firstName} - {datum.lastName} - {datum.visits} - {datum.status} - {datum.visits > 300 && ( - - -
- Lots of visits - expanded first name: {datum.firstName} -
-
- expanded last name: {datum.lastName} - expanded visits: {datum.visits} - expanded status: {datum.status} -
- )} -
- )} -
-
- ); -}; - -export const ExpandableContent: StoryFn = () => { - return ( - - - - - - - - } - > - {({ datum }: any) => ( - - {datum.name} - {datum.age} - {datum.color} - {datum.location} - {datum.name === 'Donna' && ( - - - Nulla vitae elit libero, a pharetra augue. Sed posuere - consectetur est at lobortis. Integer posuere erat a ante - venenatis dapibus posuere velit aliquet. Maecenas faucibus - mollis interdum. Nullam id dolor id nibh ultricies vehicula ut - id elit. Duis mollis, est non commodo luctus, nisi erat - porttitor ligula, eget lacinia odio sem nec elit. Cras justo - odio, dapibus ac facilisis in, egestas eget quam. Donec id - elit non mi porta gravida at eget metus. Donec id elit non mi - porta gravida at eget metus. Aenean lacinia bibendum nulla sed - consectetur. Vestibulum id ligula porta felis euismod semper. - Maecenas sed diam eget risus varius blandit sit amet non - magna. Etiam porta sem malesuada magna mollis euismod. Donec - ullamcorper nulla non metus auctor fringilla. Donec id elit - non mi porta gravida at eget metus. - - - )} - - )} -
-
- ); -}; - -export const ExpandableContentVS: StoryFn = () => { - return ( - - - - - - - - } - > - {({ datum }: any) => ( - - {datum.firstName} - {datum.lastName} - {datum.visits} - {datum.status} - {datum.visits > 300 && ( - - - Nulla vitae elit libero, a pharetra augue. Sed posuere - consectetur est at lobortis. Integer posuere erat a ante - venenatis dapibus posuere velit aliquet. Maecenas faucibus - mollis interdum. Nullam id dolor id nibh ultricies vehicula ut - id elit. Duis mollis, est non commodo luctus, nisi erat - porttitor ligula, eget lacinia odio sem nec elit. Cras justo - odio, dapibus ac facilisis in, egestas eget quam. Donec id - elit non mi porta gravida at eget metus. Donec id elit non mi - porta gravida at eget metus. Aenean lacinia bibendum nulla sed - consectetur. Vestibulum id ligula porta felis euismod semper. - Maecenas sed diam eget risus varius blandit sit amet non - magna. Etiam porta sem malesuada magna mollis euismod. Donec - ullamcorper nulla non metus auctor fringilla. Donec id elit - non mi porta gravida at eget metus. - - - )} - - )} -
-
- ); -}; - -export const SortableRows: StoryFn = () => { - return ( - <> - First column has a custom sort function! - - - { - const reverse = (str: string) => - str.split('').reverse().join(''); - - // Pin 'Yvonne' to the top - if (b.name === 'Yvonne') return 1; - else if (a.name === 'Yvonne') return -1; - - // Sort by reversed name - if (dir == 'desc') { - return reverse(b.name) >= reverse(a.name) ? 1 : -1; - } - - return reverse(b.name) >= reverse(a.name) ? -1 : 1; - }} - /> - datum.age.toString()} - /> - datum.color} - /> - { - // eslint-disable-next-line no-console - console.log(`Sorting location ${dir}`); - }} - /> - - } - > - {({ datum }: any) => ( - - {datum.name} - {datum.age} - {datum.color} - {datum.location} - - )} -
-
- - ); -}; - -export const SortableRowsVS: StoryFn = () => { - return ( - <> - First column has a custom sort function! - - - { - const reverse = (str: string) => - str.split('').reverse().join(''); - - // Pin 'Yvonne' to the top - if (b.firstName === 'Yvonne') return 1; - else if (a.firstName === 'Yvonne') return -1; - - // Sort by reversed name - if (dir == 'desc') { - return reverse(b.firstName) >= reverse(a.firstName) - ? 1 - : -1; - } - - return reverse(b.firstName) >= reverse(a.firstName) ? -1 : 1; - }} - /> - - datum.visits.toString()} - /> - datum.status} - /> - - } - > - {({ datum }: any) => ( - - {datum.firstName} - {datum.lastName} - {datum.visits} - {datum.status} - - )} -
-
- - ); -}; - -export const SelectableRows: StoryFn = () => { - return ( - - - - - - - - } - > - {({ datum }: any) => ( - - {datum.name} - {datum.age} - {datum.color} - {datum.location} - - )} -
-
- ); -}; - -export const SelectableRowsVS: StoryFn = () => { - return ( - - - - - - - - } - > - {({ datum }: any) => ( - - {datum.firstName} - {datum.lastName} - {datum.visits} - {datum.status} - - )} -
-
- ); -}; diff --git a/packages/table/src/V11Adapter/V11Adapter.tsx b/packages/table/src/V11Adapter/V11Adapter.tsx deleted file mode 100644 index cb0176c22d..0000000000 --- a/packages/table/src/V11Adapter/V11Adapter.tsx +++ /dev/null @@ -1,233 +0,0 @@ -// @ts-nocheck -import React, { - ReactElement, - useEffect, - useMemo, - useRef, - useState, -} from 'react'; -import flattenChildren from 'react-keyed-flatten-children'; -import { VirtualItem } from 'react-virtual'; -import { flexRender } from '@tanstack/react-table'; -import omit from 'lodash/omit'; - -import { useDarkMode } from '@leafygreen-ui/leafygreen-provider'; -import { consoleOnce, isComponentType } from '@leafygreen-ui/lib'; - -import { Cell, HeaderCell } from '../Cell'; -import ExpandedContent from '../ExpandedContent/ExpandedContent'; -import { HeaderRow, Row } from '../Row'; -import Table from '../Table'; -import TableBody from '../TableBody'; -import TableHead from '../TableHead'; -import { TableProps as V10TableProps } from '../TableV10/Table'; -import { TableHeaderProps } from '../TableV10/TableHeader'; -import useLeafyGreenTable, { - LeafyGreenTableCell, - LeafyGreenTableRow, - LGColumnDef, - LGTableDataType, -} from '../useLeafyGreenTable'; - -import processColumns from './processColumns'; -import processData from './processData'; -import { - ProcessedRowData, - V11AdapterProps, - ValidDataType, -} from './V11Adapter.types'; - -/** - * Converts a v10 Table component to a v11 Table component. - * - * Given the two versions' significant differences in API, the adapter makes several assumptions about the v10 Table's usage: - * - It is assumed that the v10 Table component will be the first child. - * - The v11 columns are read from the v10 columns' labels. If the key of the cells' data does not correspond to the v10 column's label, - * the user is expected to pass in the labels through the `headerLabels` prop. - * - Currently only supports up to one layer of nested rows - */ -const V11Adapter = ({ - children, - shouldAlternateRowColor, - useVirtualScrolling = false, - hasSelectableRows = false, - headerLabels, - className, -}: V11AdapterProps) => { - const containerRef = useRef(null); - const OldTable = flattenChildren(children)[0]; - - if (!isComponentType(OldTable, 'Table')) { - consoleOnce.error( - 'The first and only child of `Table.V11Adapter` must be a `V10Table` component', - ); - } - - const OldTableProps = (OldTable as ReactElement).props; - const { darkMode } = useDarkMode(OldTableProps.darkMode); - type TData = typeof OldTableProps.data extends Array ? U : never; - - const { - data: initialData, - columns: initialColumns, - children: childrenFn, - baseFontSize, - ...oldTableProps - } = OldTableProps as V10TableProps; - - const data = initialData as Array; - - const processedColumns = useMemo( - () => processColumns(data, initialColumns, headerLabels), - [data, initialColumns, headerLabels], - ); - - const [processedData, setProcessedData] = useState< - Array> - >(() => processData(data, processedColumns, childrenFn)); - - useEffect(() => { - setProcessedData(processData(data, processedColumns, childrenFn)); - }, [data, processedColumns, childrenFn]); - - const table = useLeafyGreenTable({ - containerRef, - data: processedData as Array>, - columns: processedColumns as Array>, - useVirtualScrolling, - hasSelectableRows, - }); - - const { rows } = table.getRowModel(); - - const iterables = useVirtualScrolling ? table.virtualRows ?? [] : rows; - - const columnsChildren = React.Children.toArray(initialColumns); - const oldHeaderRow = columnsChildren[0] as ReactElement; - - const oldHeaderCellProps: Array> = []; - - if (columnsChildren.length < 2) { - React.Children.toArray(oldHeaderRow.props.children).map(child => { - const { label, dataType, ...props } = (child as ReactElement).props; - oldHeaderCellProps.push(props); - }); - } - - return ( - 10 - } - className={className} - ref={containerRef} - baseFontSize={baseFontSize === 14 ? 13 : baseFontSize} - {...oldTableProps} - > - - - {table.getHeaderGroups()[0].headers.map((header, i) => { - // remove onClick as the API is incompatible with the new API - const validOldHeaderCellProps = omit( - oldHeaderCellProps[i], - 'onClick', - ); - return ( - - {flexRender( - header.column.columnDef.header, - header.getContext(), - )} - - ); - })} - - - - {iterables.map((iterable: LeafyGreenTableRow | VirtualItem) => { - const row = ( - useVirtualScrolling ? rows[iterable.index] : iterable - ) as LeafyGreenTableRow; - return ( - - {row.getVisibleCells().map((cell: LeafyGreenTableCell) => { - if (cell?.column?.id) { - if (cell?.column?.id === 'select') { - return ( - - {cell.column.columnDef?.cell && - typeof cell.column.columnDef?.cell != 'string' && - // Use default values defined by react-table instead of passing in expected parameters - // @ts-expect-error - cell.column.columnDef?.cell({ row, table })} - - ); - } else { - const cellChild = - processedData[row.index]?.[cell.column.id]?.(); - const { - children, - isHeader, - isDisabled, - ...cellChildProps - } = cellChild.props; - return cellChild ? ( - - <>{children} - - ) : ( - <> - ); - } - } else { - return <>; - } - })} - {row.original.renderExpandedContent && ( - - )} - {row.subRows && - row.subRows.map(subRow => { - const { children, ...subRowProps } = subRow.original - .rowProps as ValidDataType['rowProps']; - return ( - - {subRow.getVisibleCells().map(srCell => { - const subRowCell = subRow.original[srCell.column.id](); - const { - children, - isHeader, - isDisabled, - ...subRowCellProps - } = subRowCell.props; - return ( - - {children} - - ); - })} - - ); - })} - - ); - })} - -
- ); -}; - -export default V11Adapter; diff --git a/packages/table/src/V11Adapter/V11Adapter.types.ts b/packages/table/src/V11Adapter/V11Adapter.types.ts deleted file mode 100644 index acb6939e01..0000000000 --- a/packages/table/src/V11Adapter/V11Adapter.types.ts +++ /dev/null @@ -1,32 +0,0 @@ -// @ts-nocheck -import { PropsWithChildren } from 'react'; - -import { DarkModeProps } from '@leafygreen-ui/lib'; - -import { LeafyGreenTableOptions, LGRowData } from '../useLeafyGreenTable'; -import { TableProps } from '..'; - -export type V11AdapterProps = PropsWithChildren< - Pick, 'useVirtualScrolling' | 'hasSelectableRows'> & - Pick, 'shouldAlternateRowColor' | 'className'> & - DarkModeProps & { - /** - * Mapping of TableHeader label to the key of the field in the Table's data - */ - headerLabels?: { [key: string]: string }; - } ->; - -export interface AdapterRowProps { - children?: React.ReactNode; - [key: string]: any; -} - -export interface ValidDataType { - [key: string]: any; - rowProps: AdapterRowProps; -} - -export interface ProcessedRowData extends ValidDataType { - rowProps: AdapterRowProps; -} diff --git a/packages/table/src/V11Adapter/index.ts b/packages/table/src/V11Adapter/index.ts deleted file mode 100644 index eb59810d86..0000000000 --- a/packages/table/src/V11Adapter/index.ts +++ /dev/null @@ -1,4 +0,0 @@ -import V11Adapter from './V11Adapter'; -export { type V11AdapterProps } from './V11Adapter.types'; - -export default V11Adapter; diff --git a/packages/table/src/V11Adapter/processColumns.tsx b/packages/table/src/V11Adapter/processColumns.tsx deleted file mode 100644 index fc902850bb..0000000000 --- a/packages/table/src/V11Adapter/processColumns.tsx +++ /dev/null @@ -1,83 +0,0 @@ -import React, { ReactElement } from 'react'; -import { Row, SortingFn } from '@tanstack/react-table'; -import camelCase from 'lodash/camelCase'; - -import { Align } from '../Cell/Cell.types'; -import { TableProps } from '../TableV10/Table'; - -import { ValidDataType } from './V11Adapter.types'; - -/** - * Converts V10's HeaderRow ReactElement to an Array - * to be consumed by `react-table`. - * - * @param data returned value from `processData` - * @param columns V10's `columns` prop - * @param headerLabels any overrides to the header's label when the label does not correspond to its data's key in `data` - * @returns Array - */ -const processColumns = ( - data: Array, - columns: TableProps['columns'], - headerLabels?: { [key: string]: string }, -) => { - const columnsChildren = React.Children.toArray(columns); - - let TableHeaders; - - // when columnsChildren.length > 1, columns was passed an array of TableHeaders instead of a HeaderRow. - if (columnsChildren.length > 1) { - TableHeaders = columnsChildren; - } else { - const HeaderRow = columnsChildren[0] as ReactElement; - TableHeaders = React.Children.toArray(HeaderRow.props.children); - } - - const processedColumns = TableHeaders.map(TableHeader => { - const headerProps = (TableHeader as ReactElement).props; - - const hasSorting = - !!headerProps.sortBy || - !!headerProps.handleSort || - !!headerProps.compareFn; - - const convertedCompareFn: SortingFn = ( - rowA: Row, - rowB: Row, - _: any, - ) => { - const indexA = rowA.index; - const indexB = rowB.index; - return headerProps.compareFn(data[indexA], data[indexB]); - }; - - const defaultSortingFn = (rowA: Row, rowB: Row, columnId: string) => { - const indexA = rowA.index; - const indexB = rowB.index; - return (data[indexA] as T)[columnId] > (data[indexB] as T)[columnId] - ? -1 - : (data[indexB] as T)[columnId] > (data[indexA] as T)[columnId] - ? 1 - : 0; - }; - - const retVal = { - accessorKey: - (headerLabels && headerLabels[headerProps.label]) ?? - camelCase(headerProps.label), - header: headerProps.label, - align: (headerProps.dataType === 'number' ? 'right' : 'left') as Align, - enableSorting: hasSorting, - sortingFn: headerProps.compareFn - ? convertedCompareFn - : hasSorting - ? defaultSortingFn - : undefined, - }; - - return retVal; - }); - return processedColumns; -}; - -export default processColumns; diff --git a/packages/table/src/V11Adapter/processData.tsx b/packages/table/src/V11Adapter/processData.tsx deleted file mode 100644 index 2702cf29cb..0000000000 --- a/packages/table/src/V11Adapter/processData.tsx +++ /dev/null @@ -1,97 +0,0 @@ -import React, { ReactElement } from 'react'; -import flattenChildren from 'react-keyed-flatten-children'; -import { AccessorKeyColumnDef } from '@tanstack/react-table'; - -import { isComponentType } from '@leafygreen-ui/lib'; - -import { TableRowInterface } from '../TableV10/Table'; -import { LGTableDataType } from '../useLeafyGreenTable'; - -import { ProcessedRowData, ValidDataType } from './V11Adapter.types'; - -const processData: ( - data: Array, - processedColumns: Array>, - childrenFn: (TableRowArgs: TableRowInterface) => JSX.Element, -) => Array = ( - data: Array, - processedColumns: Array>, - childrenFn: (TableRowArgs: TableRowInterface) => JSX.Element, -) => { - const processedData = data.map((oldDatum, index) => { - // for each row, evaluate childrenFn - const evaluatedChildren = childrenFn({ datum: oldDatum, index }); - const childrenArray = flattenChildren(evaluatedChildren); - - const evaluatedRow = childrenArray.filter(child => - isComponentType(child, 'Row'), - )[0]; - const rowChildren = flattenChildren( - (evaluatedRow as ReactElement).props.children, - ); - - const evaluatedCells = rowChildren.filter(child => - isComponentType(child, 'Cell'), - ); - - const newDatum: LGTableDataType = evaluatedCells.reduce( - (acc: T, currVal, index) => { - return { - ...acc, - [processedColumns[index]?.accessorKey]: () => currVal as ReactElement, - } as T; - }, - {} as T, - ); - - const subRowChildren = rowChildren.filter(child => - isComponentType(child, 'Row'), - ); - if (subRowChildren.length > 0) newDatum.subRows = []; - subRowChildren.map(subRow => { - const subRowCells = flattenChildren( - (subRow as ReactElement).props.children, - ); - const firstSubRowCell = subRowCells[0]; - const firstSubRowCellColSpan = (firstSubRowCell as ReactElement).props - .colSpan; - - if ( - firstSubRowCellColSpan && - firstSubRowCellColSpan === processedColumns.length - ) { - // eslint-disable-next-line react/display-name - newDatum.renderExpandedContent = () => ( -
- {(firstSubRowCell as ReactElement).props.children} -
- ); - } else { - const processedSubRow = subRowCells.reduce((acc: T, currVal, index) => { - return { - ...acc, - [processedColumns[index]?.accessorKey]: () => - currVal as ReactElement, - }; - }, {} as T); - const { - children, - expanded, - indentLevel, - isAnyAncestorCollapsed, - ...rowProps - } = (subRow as ReactElement).props; - newDatum.subRows && - newDatum.subRows.push({ - ...processedSubRow, - rowProps, - } as T); - } - }); - - return { ...newDatum, rowProps: (evaluatedRow as ReactElement).props }; - }); - return processedData; -}; - -export default processData; diff --git a/packages/table/src/index.ts b/packages/table/src/index.ts index 9faaf33da8..c48efb0876 100644 --- a/packages/table/src/index.ts +++ b/packages/table/src/index.ts @@ -8,14 +8,6 @@ export { HeaderRow, type HeaderRowProps, Row, type RowProps } from './Row'; export { default as Table, type TableProps } from './Table'; export { default as TableBody, type TableBodyProps } from './TableBody'; export { default as TableHead } from './TableHead/TableHead'; -export { - Cell as V10Cell, - DataType as V10DataType, - HeaderRow as V10HeaderRow, - Row as V10Row, - Table as V10Table, - TableHeader as V10TableHeader, -} from './TableV10'; export { type LeafyGreenTable, type LeafyGreenTableCell, @@ -33,7 +25,6 @@ export { default as useLeafyGreenVirtualTable, } from './useLeafyGreenVirtualTable'; export { getTestUtils } from './utils/getTestUtils'; -export { default as V11Adapter, type V11AdapterProps } from './V11Adapter'; +// TODO: Check if some exports might clash with our exports export * from '@tanstack/react-table'; -// export { type VirtualItem } from 'react-virtual'; export { type VirtualItem } from '@tanstack/react-virtual'; diff --git a/packages/table/src/useLeafyGreenVirtualTable/useLeafyGreenVirtualTable.spec.tsx b/packages/table/src/useLeafyGreenVirtualTable/useLeafyGreenVirtualTable.spec.tsx index e69de29bb2..b4aed496ad 100644 --- a/packages/table/src/useLeafyGreenVirtualTable/useLeafyGreenVirtualTable.spec.tsx +++ b/packages/table/src/useLeafyGreenVirtualTable/useLeafyGreenVirtualTable.spec.tsx @@ -0,0 +1 @@ +// TODO: adding in a new PR diff --git a/yarn.lock b/yarn.lock index 9f9d2be5a2..d1d76afb7d 100644 --- a/yarn.lock +++ b/yarn.lock @@ -4253,11 +4253,6 @@ dependencies: "@babel/runtime" "^7.13.10" -"@reach/observe-rect@^1.1.0": - version "1.2.0" - resolved "https://registry.yarnpkg.com/@reach/observe-rect/-/observe-rect-1.2.0.tgz#d7a6013b8aafcc64c778a0ccb83355a11204d3b2" - integrity sha512-Ba7HmkFgfQxZqqaeIWWkNK0rEhpxVQHIoVyW1YDSkGsGIXzcaW4deC8B0pZrNSSyLTdIk7y+5olKt5+g0GmFIQ== - "@rollup/plugin-babel@6.0.4": version "6.0.4" resolved "https://registry.yarnpkg.com/@rollup/plugin-babel/-/plugin-babel-6.0.4.tgz#bd698e351fa9aa9619fcae780aea2a603d98e4c4" @@ -13746,13 +13741,6 @@ react-transition-group@^4.4.5: loose-envify "^1.4.0" prop-types "^15.6.2" -react-virtual@^2.10.4: - version "2.10.4" - resolved "https://registry.yarnpkg.com/react-virtual/-/react-virtual-2.10.4.tgz#08712f0acd79d7d6f7c4726f05651a13b24d8704" - integrity sha512-Ir6+oPQZTVHfa6+JL9M7cvMILstFZH/H3jqeYeKI4MSUX+rIruVwFC6nGVXw9wqAw8L0Kg2KvfXxI85OvYQdpQ== - dependencies: - "@reach/observe-rect" "^1.1.0" - react@^18.2.0: version "18.2.0" resolved "https://registry.yarnpkg.com/react/-/react-18.2.0.tgz#555bd98592883255fa00de14f1151a917b5d77d5" From e16bbfbbcaab06881faba0bc3019f51955951984 Mon Sep 17 00:00:00 2001 From: Shaneeza Date: Wed, 6 Nov 2024 13:48:28 -0500 Subject: [PATCH 067/113] remove react-virtual --- packages/table/src/useLeafyGreenTable/ReactVirtual.types.ts | 3 --- packages/table/src/useLeafyGreenTable/index.ts | 1 - 2 files changed, 4 deletions(-) delete mode 100644 packages/table/src/useLeafyGreenTable/ReactVirtual.types.ts diff --git a/packages/table/src/useLeafyGreenTable/ReactVirtual.types.ts b/packages/table/src/useLeafyGreenTable/ReactVirtual.types.ts deleted file mode 100644 index c7c2f9fee8..0000000000 --- a/packages/table/src/useLeafyGreenTable/ReactVirtual.types.ts +++ /dev/null @@ -1,3 +0,0 @@ -import { useVirtual } from 'react-virtual'; - -export type VirtualizerValues = ReturnType; diff --git a/packages/table/src/useLeafyGreenTable/index.ts b/packages/table/src/useLeafyGreenTable/index.ts index ee912bbdc1..b78a54457c 100644 --- a/packages/table/src/useLeafyGreenTable/index.ts +++ b/packages/table/src/useLeafyGreenTable/index.ts @@ -1,4 +1,3 @@ import useLeafyGreenTable from './useLeafyGreenTable'; -export { VirtualizerValues } from './ReactVirtual.types'; export * from './useLeafyGreenTable.types'; export default useLeafyGreenTable; From 252d9695644723774480577f76db3bb39c4247d0 Mon Sep 17 00:00:00 2001 From: Shaneeza Date: Wed, 6 Nov 2024 15:41:43 -0500 Subject: [PATCH 068/113] cell styles --- packages/table/src/Cell/Cell.styles.ts | 16 ++++----- .../src/Cell/HeaderCell/HeaderCell.styles.ts | 35 +++++++++++++------ .../table/src/Cell/HeaderCell/HeaderCell.tsx | 18 +++------- packages/table/src/Cell/InternalCell.tsx | 6 ++-- .../ExpandedContent/ExpandedContent.styles.ts | 16 ++++----- .../src/ExpandedContent/ExpandedContent.tsx | 10 ++---- 6 files changed, 48 insertions(+), 53 deletions(-) diff --git a/packages/table/src/Cell/Cell.styles.ts b/packages/table/src/Cell/Cell.styles.ts index 6454fba9d8..5726a6825d 100644 --- a/packages/table/src/Cell/Cell.styles.ts +++ b/packages/table/src/Cell/Cell.styles.ts @@ -4,7 +4,7 @@ import { spacing } from '@leafygreen-ui/tokens'; import { Align } from './Cell.types'; /** The base left & right padding in the table */ -export const baseTableSidePadding = spacing[4]; +export const baseTableSidePadding = spacing[600]; /** the default width of the expand icon */ const iconSize = 28; @@ -24,19 +24,19 @@ export const getCellPadding = ({ if (depth === 0) { if (isSelectable) { return css` - padding-left: ${spacing[2]}px; - padding-right: ${spacing[2]}px; + padding-left: ${spacing[200]}px; + padding-right: ${spacing[200]}px; `; } else { return css` padding-left: ${baseTableSidePadding + - (isExpandable ? 0 : spacing[2])}px; + (isExpandable ? 0 : spacing[200])}px; `; } } const parentIconsPadding = 8 * (depth - 1); // how much space do parent icons take up - const thisIconPadding = isExpandable ? spacing[2] : 0; + const thisIconPadding = isExpandable ? spacing[200] : 0; const depthPadding = iconSize * depth - (parentIconsPadding + thisIconPadding); return css` @@ -67,8 +67,8 @@ export const getCellContainerStyles = (align: Align = 'left') => css` text-align: ${align}; `; -export const getBaseStyles = () => css` - padding: 0 8px; +export const baseCellStyles = css` + padding: 0 ${spacing[200]}px; overflow: hidden; vertical-align: top; @@ -81,7 +81,7 @@ export const getBaseStyles = () => css` } `; -export const cellInnerStyles = () => css` +export const cellInnerStyles = css` display: flex; align-items: center; min-width: 100%; diff --git a/packages/table/src/Cell/HeaderCell/HeaderCell.styles.ts b/packages/table/src/Cell/HeaderCell/HeaderCell.styles.ts index b0b5672499..c3bc272bf5 100644 --- a/packages/table/src/Cell/HeaderCell/HeaderCell.styles.ts +++ b/packages/table/src/Cell/HeaderCell/HeaderCell.styles.ts @@ -1,18 +1,31 @@ -import { css } from '@leafygreen-ui/emotion'; +import { css, cx } from '@leafygreen-ui/emotion'; import { spacing } from '@leafygreen-ui/tokens'; -import { getCellPadding } from '../Cell.styles'; +import { + baseCellStyles, + getCellContainerStyles, + getCellPadding, +} from '../Cell.styles'; +import { Align } from '../Cell.types'; export const headerCellContentStyles = css` - height: ${spacing[5] + spacing[2]}px; + height: ${spacing[800] + spacing[200]}px; `; -export const getHeaderCellWidthStyles = (size: number) => css` - width: ${size}px; -`; +export const getBaseHeaderCellStyles = (size: number, isSelectable?: boolean) => + cx( + baseCellStyles, + css` + &:first-of-type { + ${getCellPadding({ depth: 0, isExpandable: false, isSelectable })} + } + `, + { + [css` + width: ${size}px; + `]: !!size, + }, + ); -export const getCellPaddingStyles = (isSelectable?: boolean) => css` - &:first-of-type { - ${getCellPadding({ depth: 0, isExpandable: false, isSelectable })} - } -`; +export const getHeaderCellContentStyles = (align: Align) => + cx(getCellContainerStyles(align), headerCellContentStyles); diff --git a/packages/table/src/Cell/HeaderCell/HeaderCell.tsx b/packages/table/src/Cell/HeaderCell/HeaderCell.tsx index 9971fdf45a..090bd098cf 100644 --- a/packages/table/src/Cell/HeaderCell/HeaderCell.tsx +++ b/packages/table/src/Cell/HeaderCell/HeaderCell.tsx @@ -5,13 +5,11 @@ import { cx } from '@leafygreen-ui/emotion'; import { LGIDS } from '../../constants'; import { useTableContext } from '../../TableContext'; import { LGRowData } from '../../useLeafyGreenTable'; -import { getBaseStyles, getCellContainerStyles } from '../Cell.styles'; import SortIcon from './SortIcon/SortIcon'; import { - getCellPaddingStyles, - getHeaderCellWidthStyles, - headerCellContentStyles, + getBaseHeaderCellStyles, + getHeaderCellContentStyles, } from './HeaderCell.styles'; import { HeaderCellProps, SortState, SortStates } from './HeaderCell.types'; @@ -36,8 +34,6 @@ const HeaderCell = ({ let columnName, sortState, onSortIconClick; - // console.log({ cansort: header?.column.columnDef.enableSorting }); - if (header && header?.column.columnDef.enableSorting) { columnName = header.column.columnDef.header as string; const headerSortDirection = header.column.getIsSorted().toString(); @@ -49,12 +45,7 @@ const HeaderCell = ({ ({ className={cx( // TS error is ignored (and not expected) as it doesn't show up locally but interrupts build // @ts-ignore Header types need to be extended or declared in the react-table namespace - getCellContainerStyles(align || header?.column.columnDef?.align), - headerCellContentStyles, + getHeaderCellContentStyles(align || header?.column.columnDef?.align), )} > {children} diff --git a/packages/table/src/Cell/InternalCell.tsx b/packages/table/src/Cell/InternalCell.tsx index 4ae5629dac..3cb1876024 100644 --- a/packages/table/src/Cell/InternalCell.tsx +++ b/packages/table/src/Cell/InternalCell.tsx @@ -5,8 +5,8 @@ import { cx } from '@leafygreen-ui/emotion'; import { LGIDS } from '../constants'; import { + baseCellStyles, cellInnerStyles, - getBaseStyles, getCellContainerStyles, } from './Cell.styles'; import { InternalCellProps } from './Cell.types'; @@ -21,11 +21,11 @@ const InternalCell = ({ return (
-
{children}
+
{children}
); diff --git a/packages/table/src/ExpandedContent/ExpandedContent.styles.ts b/packages/table/src/ExpandedContent/ExpandedContent.styles.ts index 150a1705aa..feb0f080b5 100644 --- a/packages/table/src/ExpandedContent/ExpandedContent.styles.ts +++ b/packages/table/src/ExpandedContent/ExpandedContent.styles.ts @@ -1,19 +1,14 @@ -import { css } from '@leafygreen-ui/emotion'; +import { css, cx } from '@leafygreen-ui/emotion'; import { Theme } from '@leafygreen-ui/lib'; import { palette } from '@leafygreen-ui/palette'; -import { transitionDuration } from '@leafygreen-ui/tokens'; + +import { getCellContainerStyles } from '../Cell/Cell.styles'; export const baseStyles = css` padding: 0; - overflow: hidden; - transition: ${transitionDuration.default}ms ease; - - > div { - max-height: inherit; - } `; -export const expandedContentStyles: Record = { +export const expandedContentThemeStyles: Record = { [Theme.Dark]: css` background-color: ${palette.gray.dark4}; `, @@ -21,3 +16,6 @@ export const expandedContentStyles: Record = { background-color: ${palette.gray.light3}; `, }; + +export const getContainerStyles = (theme: Theme) => + cx(expandedContentThemeStyles[theme], getCellContainerStyles()); diff --git a/packages/table/src/ExpandedContent/ExpandedContent.tsx b/packages/table/src/ExpandedContent/ExpandedContent.tsx index 8285b163b1..34343fc2c2 100644 --- a/packages/table/src/ExpandedContent/ExpandedContent.tsx +++ b/packages/table/src/ExpandedContent/ExpandedContent.tsx @@ -4,12 +4,11 @@ import { RowData } from '@tanstack/react-table'; import { cx } from '@leafygreen-ui/emotion'; import { useDarkMode } from '@leafygreen-ui/leafygreen-provider'; -import { getCellContainerStyles } from '../Cell/Cell.styles'; import { LGIDS } from '../constants'; import InternalRowBase from '../Row/InternalRowBase'; import { useVirtualTableContext } from '../TableContext'; -import { baseStyles, expandedContentStyles } from './ExpandedContent.styles'; +import { baseStyles, getContainerStyles } from './ExpandedContent.styles'; import { ExpandedContentProps } from './ExpandedContent.types'; const ExpandedContent = ({ @@ -25,9 +24,6 @@ const ExpandedContent = ({ const { theme } = useDarkMode(); - // eslint-disable-next-line no-console - console.log(`🍉rerender🍉 ExpandedContent: ${row.id}`); - return ( ({ className={cx(baseStyles)} data-lgid={LGIDS.cell} > -
+
{content}
From 275805f0f6601570f2c30e0386203ccaaf19c9f1 Mon Sep 17 00:00:00 2001 From: Shaneeza Date: Wed, 6 Nov 2024 16:07:35 -0500 Subject: [PATCH 069/113] interrowwithRT style updates --- packages/table/src/Row/InternalRowWithRT.tsx | 25 ++++++++------------ packages/table/src/Row/Row.styles.ts | 20 +++++++++++++++- packages/table/src/Table.stories.tsx | 5 ++-- 3 files changed, 31 insertions(+), 19 deletions(-) diff --git a/packages/table/src/Row/InternalRowWithRT.tsx b/packages/table/src/Row/InternalRowWithRT.tsx index 33806f2a2e..543853e59a 100644 --- a/packages/table/src/Row/InternalRowWithRT.tsx +++ b/packages/table/src/Row/InternalRowWithRT.tsx @@ -6,12 +6,7 @@ import { cx } from '@leafygreen-ui/emotion'; import { LGRowData } from '../useLeafyGreenTable'; import InternalRowBase from './InternalRowBase'; -import { - expandedContentParentStyles, - grayZebraRowStyles, - selectedRowStyles, - zebraStyles, -} from './Row.styles'; +import { getRowWithRTStyles } from './Row.styles'; import { InternalRowWithRTProps } from './Row.types'; import { RowContextProvider } from './RowContext'; @@ -55,15 +50,15 @@ const InternalRowWithRT = ({ = { color: ${palette.gray.base}; `, }; + +export const getRowWithRTStyles = ( + isOddVSRow: boolean, + shouldAlternateRowColor: boolean, + isSelected: boolean, + isVirtualRow: boolean, + isDisabled: boolean, + isExpanded: boolean, + theme: Theme, +) => + cx({ + [grayZebraRowStyles[theme]]: + isOddVSRow && shouldAlternateRowColor && !isSelected, + [zebraStyles[theme]]: + !isVirtualRow && shouldAlternateRowColor && !isSelected, + [selectedRowStyles[theme]]: isSelected && !isDisabled, + [expandedContentParentStyles[theme]]: isExpanded, + }); diff --git a/packages/table/src/Table.stories.tsx b/packages/table/src/Table.stories.tsx index 83664aca38..af4b3da1fe 100644 --- a/packages/table/src/Table.stories.tsx +++ b/packages/table/src/Table.stories.tsx @@ -97,7 +97,7 @@ const Template: StoryFn = args => { export const LiveExample: StoryFn = args => { const tableContainerRef = React.useRef(null); - const [data] = useState(() => makeKitchenSinkData(900)); + const [data] = useState(() => makeKitchenSinkData(500)); const columns = React.useMemo>>( () => [ @@ -341,7 +341,7 @@ export const NestedRows: StoryFn = args => { export const ExpandableContent: StoryFn = args => { const tableContainerRef = React.useRef(null); - const data = React.useState(() => makeData(true, 2000))[0]; + const data = React.useState(() => makeData(true, 500))[0]; const columns = React.useMemo>>( () => [ @@ -415,7 +415,6 @@ export const ExpandableContent: StoryFn = args => { {rows.map((row: LeafyGreenTableRow) => { - // const isExpandedContent = row.original.isExpandedContent ?? false; const isExpandedContent = row.isExpandedContent ?? false; return ( From 1201b29798fb7882b920c899a7c71ed74101a394 Mon Sep 17 00:00:00 2001 From: Shaneeza Date: Wed, 6 Nov 2024 16:14:36 -0500 Subject: [PATCH 070/113] table styles --- packages/table/src/Table.stories.tsx | 7 +++++++ packages/table/src/Table/Table.styles.ts | 7 ++++++- packages/table/src/Table/Table.tsx | 15 ++++----------- 3 files changed, 17 insertions(+), 12 deletions(-) diff --git a/packages/table/src/Table.stories.tsx b/packages/table/src/Table.stories.tsx index af4b3da1fe..3139293dbf 100644 --- a/packages/table/src/Table.stories.tsx +++ b/packages/table/src/Table.stories.tsx @@ -64,6 +64,13 @@ const meta: StoryMetaType = { docs: { source: { type: 'code' }, }, + // docs: { + // source: { + // // any non-empty string here will skip jsx rendering, see: + // // https://github.com/storybookjs/storybook/blob/next/code/renderers/react/src/docs/jsxDecorator.tsx#L165 + // code: 'hello world', + // }, + // }, }, }; export default meta; diff --git a/packages/table/src/Table/Table.styles.ts b/packages/table/src/Table/Table.styles.ts index 7dd1803524..55f079927b 100644 --- a/packages/table/src/Table/Table.styles.ts +++ b/packages/table/src/Table/Table.styles.ts @@ -1,6 +1,8 @@ import { css, cx } from '@leafygreen-ui/emotion'; import { Theme } from '@leafygreen-ui/lib'; import { palette } from '@leafygreen-ui/palette'; +import { BaseFontSize } from '@leafygreen-ui/tokens'; +import { bodyTypeScaleStyles } from '@leafygreen-ui/typography'; export const baseStyles = css` border-spacing: 0; @@ -17,7 +19,7 @@ export const themeStyles: Record = { `, }; -export const tableContainerStyles = (isVirtual = false) => +export const getTableContainerStyles = (isVirtual = false) => cx( css` width: 100%; @@ -29,3 +31,6 @@ export const tableContainerStyles = (isVirtual = false) => `]: isVirtual, }, ); + +export const getTableStyles = (theme: Theme, baseFontSize: BaseFontSize) => + cx(baseStyles, themeStyles[theme], bodyTypeScaleStyles[baseFontSize]); diff --git a/packages/table/src/Table/Table.tsx b/packages/table/src/Table/Table.tsx index 9e03e784a9..98c4862b28 100644 --- a/packages/table/src/Table/Table.tsx +++ b/packages/table/src/Table/Table.tsx @@ -4,17 +4,14 @@ import PropTypes from 'prop-types'; import { cx } from '@leafygreen-ui/emotion'; import { useDarkMode } from '@leafygreen-ui/leafygreen-provider'; import { BaseFontSize } from '@leafygreen-ui/tokens'; -import { - bodyTypeScaleStyles, - useUpdatedBaseFontSize, -} from '@leafygreen-ui/typography'; +import { useUpdatedBaseFontSize } from '@leafygreen-ui/typography'; import { LGIDS } from '../constants'; import { TableContextProvider } from '../TableContext'; import { LGRowData } from '../useLeafyGreenTable'; import { LeafyGreenVirtualTable } from '../useLeafyGreenVirtualTable/useLeafyGreenVirtualTable.types'; -import { baseStyles, tableContainerStyles, themeStyles } from './Table.styles'; +import { getTableContainerStyles, getTableStyles } from './Table.styles'; import { TableProps } from './Table.types'; // Inferred generic type from component gets used in place of `any` @@ -46,7 +43,7 @@ const Table = forwardRef>( return (
>( virtualTable={virtualTable} > From b1c5af17be9b69c7af5b52932d468110d207a049 Mon Sep 17 00:00:00 2001 From: Shaneeza Date: Wed, 6 Nov 2024 16:17:46 -0500 Subject: [PATCH 071/113] comment --- packages/table/src/Table.stories.tsx | 1 + 1 file changed, 1 insertion(+) diff --git a/packages/table/src/Table.stories.tsx b/packages/table/src/Table.stories.tsx index 3139293dbf..54fd58799d 100644 --- a/packages/table/src/Table.stories.tsx +++ b/packages/table/src/Table.stories.tsx @@ -102,6 +102,7 @@ const Template: StoryFn = args => { ); }; +// FIXME: this story freezes story book unless opened outside of an iframe export const LiveExample: StoryFn = args => { const tableContainerRef = React.useRef(null); const [data] = useState(() => makeKitchenSinkData(500)); From 61183042abcfdb17e5bae5501ac1f67e5f691312 Mon Sep 17 00:00:00 2001 From: Shaneeza Date: Wed, 6 Nov 2024 17:05:11 -0500 Subject: [PATCH 072/113] comment --- packages/table/src/utils/testHookCalls.testutils.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/table/src/utils/testHookCalls.testutils.tsx b/packages/table/src/utils/testHookCalls.testutils.tsx index 01f74a21ba..fedb320a3b 100644 --- a/packages/table/src/utils/testHookCalls.testutils.tsx +++ b/packages/table/src/utils/testHookCalls.testutils.tsx @@ -1,4 +1,4 @@ -// @ts-nocheck +// @ts-nocheck - this will be updated in a separate PR import React, { useRef, useState } from 'react'; import useLeafyGreenTable, { From e138a50ec87898124fd0725f73d354ac39f9094f Mon Sep 17 00:00:00 2001 From: Shaneeza Date: Wed, 6 Nov 2024 21:24:55 -0500 Subject: [PATCH 073/113] wip --- .../src/Row/HeaderRow/HeaderRow.styles.tsx | 0 packages/table/src/Table.stories.tsx | 2 +- packages/table/src/Table/Table.tsx | 2 ++ .../table/src/TableHead/TableHead.styles.tsx | 27 +++++++++++++++---- 4 files changed, 25 insertions(+), 6 deletions(-) create mode 100644 packages/table/src/Row/HeaderRow/HeaderRow.styles.tsx diff --git a/packages/table/src/Row/HeaderRow/HeaderRow.styles.tsx b/packages/table/src/Row/HeaderRow/HeaderRow.styles.tsx new file mode 100644 index 0000000000..e69de29bb2 diff --git a/packages/table/src/Table.stories.tsx b/packages/table/src/Table.stories.tsx index fba051db9b..3b197420ed 100644 --- a/packages/table/src/Table.stories.tsx +++ b/packages/table/src/Table.stories.tsx @@ -178,7 +178,7 @@ export const LiveExample: StoryFn = args => { return (
-
+
>( // Helps to determine if the header is sticky const { ref, inView } = useInView({ threshold: 0, + initialInView: true, }); return ( @@ -54,6 +55,7 @@ const Table = forwardRef>( // eslint-disable-next-line jsx-a11y/no-noninteractive-tabindex tabIndex={0} > + {/* Empty div used to track if the header is sticky */}
= { [Theme.Dark]: css` @@ -21,16 +22,32 @@ export const getBaseStyles = (isSticky = false, theme: Theme) => z-index: 1; top: 0; - table[data-is-sticky='true'] & { - color: red; + tr { + background-color: inherit; + } + table & { :after { content: ''; position: absolute; + z-index: -1; bottom: 0; - width: 100%; - height: 100%; - box-shadow: -1px 0px 10px rgba(0, 0, 0, 0.25); + left: 0; + right: 0; + margin: auto; + width: 96%; + height: 50%; + box-shadow: 0px 9px 20px 9px rgba(0, 30, 43, 0.2); + /* box-shadow: 0px 6px 30px 17px rgba(0, 0, 0, 0.3); */ + border-radius: 40%; + opacity: 0; + transition: opacity ${transitionDuration.default}ms ease-in-out; + } + } + + table[data-is-sticky='true'] & { + :after { + opacity: 1; } } `]: isSticky, From 20f4aa7a4a5cc187607143ddda201c3845959b13 Mon Sep 17 00:00:00 2001 From: Shaneeza Date: Thu, 7 Nov 2024 10:02:34 -0500 Subject: [PATCH 074/113] story with less rows --- packages/table/src/Table.stories.tsx | 137 ++++++++++++++++++++++++++- 1 file changed, 136 insertions(+), 1 deletion(-) diff --git a/packages/table/src/Table.stories.tsx b/packages/table/src/Table.stories.tsx index 54fd58799d..a0690584b4 100644 --- a/packages/table/src/Table.stories.tsx +++ b/packages/table/src/Table.stories.tsx @@ -44,7 +44,6 @@ const meta: StoryMetaType = { component: Table, argTypes: { shouldAlternateRowColor: { control: 'boolean' }, - disableAnimations: { control: 'boolean' }, }, parameters: { default: 'LiveExample', @@ -104,6 +103,142 @@ const Template: StoryFn = args => { // FIXME: this story freezes story book unless opened outside of an iframe export const LiveExample: StoryFn = args => { + const tableContainerRef = React.useRef(null); + const [data] = useState(() => makeKitchenSinkData(100)); + + const columns = React.useMemo>>( + () => [ + { + accessorKey: 'dateCreated', + header: 'Date Created', + enableSorting: true, + cell: info => + (info.getValue() as Date).toLocaleDateString('en-us', { + year: 'numeric', + month: 'short', + day: 'numeric', + }), + }, + { + accessorKey: 'frequency', + header: 'Frequency', + }, + { + accessorKey: 'clusterType', + header: 'Cluster Type', + }, + { + accessorKey: 'encryptorEnabled', + header: 'Encryptor', + // eslint-disable-next-line react/display-name + cell: info => ( + + {info.getValue() ? 'Enabled' : 'Not enabled'} + + ), + }, + { + accessorKey: 'mdbVersion', + header: 'MongoDB Version', + enableSorting: true, + size: 90, + }, + { + id: 'actions', + header: '', + size: 90, + // eslint-disable-next-line react/display-name + cell: _ => { + return ( + <> + + + + + + + + + + + ); + }, + }, + ], + [], + ); + + const table = useLeafyGreenTable({ + data, + columns, + }); + + const { rows } = table; + + return ( + <> +
+ + {table.getHeaderGroups().map((headerGroup: HeaderGroup) => ( + + {headerGroup.headers.map(header => { + return ( + + {flexRender( + header.column.columnDef.header, + header.getContext(), + )} + + ); + })} + + ))} + + + {rows.map((row: LeafyGreenTableRow) => { + // const isExpandedContent = row.original.isExpandedContent ?? false; + const isExpandedContent = row.isExpandedContent ?? false; + + return ( + + {!isExpandedContent && ( + + {row.getVisibleCells().map(cell => { + return ( + + {flexRender( + cell.column.columnDef.cell, + cell.getContext(), + )} + + ); + })} + + )} + {isExpandedContent && } + + ); + })} + +
+ + ); +}; + +LiveExample.argTypes = { + shouldAlternateRowColor: { + control: 'none', + }, +}; + +export const HundredsOfRows: StoryFn = args => { const tableContainerRef = React.useRef(null); const [data] = useState(() => makeKitchenSinkData(500)); From d2d782dc1c33ede2990bdf39e507ddff1a01a5e9 Mon Sep 17 00:00:00 2001 From: Shaneeza Date: Thu, 7 Nov 2024 10:28:58 -0500 Subject: [PATCH 075/113] move box-shadow to headerRow --- .../table/src/Row/HeaderRow/HeaderRow.styles.tsx | 10 ++++++++++ packages/table/src/Row/HeaderRow/HeaderRow.tsx | 12 +++++++++++- packages/table/src/TableHead/TableHead.styles.tsx | 11 +++++++---- 3 files changed, 28 insertions(+), 5 deletions(-) diff --git a/packages/table/src/Row/HeaderRow/HeaderRow.styles.tsx b/packages/table/src/Row/HeaderRow/HeaderRow.styles.tsx index e69de29bb2..72cc9592ea 100644 --- a/packages/table/src/Row/HeaderRow/HeaderRow.styles.tsx +++ b/packages/table/src/Row/HeaderRow/HeaderRow.styles.tsx @@ -0,0 +1,10 @@ +import { css } from '@leafygreen-ui/emotion'; +import { Theme } from '@leafygreen-ui/lib'; +import { palette } from '@leafygreen-ui/palette'; + +export const getBaseStyles = (theme: Theme) => css` + &:last-of-type { + box-shadow: 0 4px + ${theme === Theme.Dark ? palette.gray.dark2 : palette.gray.light2}; + } +`; diff --git a/packages/table/src/Row/HeaderRow/HeaderRow.tsx b/packages/table/src/Row/HeaderRow/HeaderRow.tsx index afaef5b3ea..5123287d62 100644 --- a/packages/table/src/Row/HeaderRow/HeaderRow.tsx +++ b/packages/table/src/Row/HeaderRow/HeaderRow.tsx @@ -1,12 +1,22 @@ import React, { PropsWithChildren } from 'react'; +import { cx } from '@leafygreen-ui/emotion'; +import { useDarkMode } from '@leafygreen-ui/leafygreen-provider'; + +import { getBaseStyles } from './HeaderRow.styles'; import { HeaderRowProps } from './HeaderRow.types'; const HeaderRow = ({ children, + className, ...rest }: PropsWithChildren) => { - return {children}; + const { theme } = useDarkMode(); + return ( + + {children} + + ); }; HeaderRow.displayName = 'HeaderRow'; diff --git a/packages/table/src/TableHead/TableHead.styles.tsx b/packages/table/src/TableHead/TableHead.styles.tsx index e1974cd832..775c8e99a8 100644 --- a/packages/table/src/TableHead/TableHead.styles.tsx +++ b/packages/table/src/TableHead/TableHead.styles.tsx @@ -1,3 +1,5 @@ +import { transparentize } from 'polished'; + import { css, cx } from '@leafygreen-ui/emotion'; import { Theme } from '@leafygreen-ui/lib'; import { palette } from '@leafygreen-ui/palette'; @@ -6,11 +8,11 @@ import { transitionDuration } from '@leafygreen-ui/tokens'; export const themeStyles: Record = { [Theme.Dark]: css` background-color: ${palette.black}; - box-shadow: 0 4px ${palette.gray.dark2}; + /* box-shadow: 0 4px ${palette.gray.dark2}; */ `, [Theme.Light]: css` background-color: ${palette.white}; - box-shadow: 0 4px ${palette.gray.light2}; + /* box-shadow: 0 4px ${palette.gray.light2}; */ `, }; @@ -37,8 +39,9 @@ export const getBaseStyles = (isSticky = false, theme: Theme) => margin: auto; width: 96%; height: 50%; - box-shadow: 0px 9px 20px 9px rgba(0, 30, 43, 0.2); - /* box-shadow: 0px 6px 30px 17px rgba(0, 0, 0, 0.3); */ + box-shadow: ${theme === Theme.Light + ? `0px 9px 20px 9px ${transparentize(0.8, palette.black)}` + : '0px 6px 30px 17px rgba(0, 0, 0, 0.3)'}; border-radius: 40%; opacity: 0; transition: opacity ${transitionDuration.default}ms ease-in-out; From 94f3ebd4ed5b24225e31426d733ab8da2df122af Mon Sep 17 00:00:00 2001 From: Shaneeza Date: Thu, 7 Nov 2024 13:47:36 -0500 Subject: [PATCH 076/113] darken darkmode scroll shadow --- packages/table/package.json | 5 +++-- packages/table/src/TableHead/TableHead.styles.tsx | 2 +- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/packages/table/package.json b/packages/table/package.json index 3294ae7c79..c4b60b0ad5 100644 --- a/packages/table/package.json +++ b/packages/table/package.json @@ -1,6 +1,6 @@ { "name": "@leafygreen-ui/table", - "version": "12.7.0-test.2", + "version": "12.7.0-test.5", "description": "leafyGreen UI Kit Table", "main": "./dist/index.js", "module": "./dist/esm/index.js", @@ -38,7 +38,8 @@ "lodash": "^4.17.21", "polished": "^4.2.2", "react-fast-compare": "3.2.2", - "react-intersection-observer":"9.13.1" + "react-intersection-observer":"9.13.1", + "@emotion/styled": "^11.10.5" }, "devDependencies": { "@faker-js/faker": "^8.0.0", diff --git a/packages/table/src/TableHead/TableHead.styles.tsx b/packages/table/src/TableHead/TableHead.styles.tsx index 775c8e99a8..c00b025904 100644 --- a/packages/table/src/TableHead/TableHead.styles.tsx +++ b/packages/table/src/TableHead/TableHead.styles.tsx @@ -41,7 +41,7 @@ export const getBaseStyles = (isSticky = false, theme: Theme) => height: 50%; box-shadow: ${theme === Theme.Light ? `0px 9px 20px 9px ${transparentize(0.8, palette.black)}` - : '0px 6px 30px 17px rgba(0, 0, 0, 0.3)'}; + : '0px 6px 30px 17px rgba(0, 0, 0, 0.5)'}; border-radius: 40%; opacity: 0; transition: opacity ${transitionDuration.default}ms ease-in-out; From 9f82e9b295c11e0342a3ea75ca24a12534319e6d Mon Sep 17 00:00:00 2001 From: Shaneeza Date: Thu, 7 Nov 2024 13:51:07 -0500 Subject: [PATCH 077/113] move styles --- packages/table/src/Row/HeaderRow/HeaderRow.styles.tsx | 2 ++ packages/table/src/TableHead/TableHead.styles.tsx | 6 ------ 2 files changed, 2 insertions(+), 6 deletions(-) diff --git a/packages/table/src/Row/HeaderRow/HeaderRow.styles.tsx b/packages/table/src/Row/HeaderRow/HeaderRow.styles.tsx index 72cc9592ea..6fb29ea037 100644 --- a/packages/table/src/Row/HeaderRow/HeaderRow.styles.tsx +++ b/packages/table/src/Row/HeaderRow/HeaderRow.styles.tsx @@ -3,6 +3,8 @@ import { Theme } from '@leafygreen-ui/lib'; import { palette } from '@leafygreen-ui/palette'; export const getBaseStyles = (theme: Theme) => css` + background-color: inherit; + &:last-of-type { box-shadow: 0 4px ${theme === Theme.Dark ? palette.gray.dark2 : palette.gray.light2}; diff --git a/packages/table/src/TableHead/TableHead.styles.tsx b/packages/table/src/TableHead/TableHead.styles.tsx index c00b025904..bb09339b36 100644 --- a/packages/table/src/TableHead/TableHead.styles.tsx +++ b/packages/table/src/TableHead/TableHead.styles.tsx @@ -8,11 +8,9 @@ import { transitionDuration } from '@leafygreen-ui/tokens'; export const themeStyles: Record = { [Theme.Dark]: css` background-color: ${palette.black}; - /* box-shadow: 0 4px ${palette.gray.dark2}; */ `, [Theme.Light]: css` background-color: ${palette.white}; - /* box-shadow: 0 4px ${palette.gray.light2}; */ `, }; @@ -24,10 +22,6 @@ export const getBaseStyles = (isSticky = false, theme: Theme) => z-index: 1; top: 0; - tr { - background-color: inherit; - } - table & { :after { content: ''; From 65897dfd319349390d4bc8a5a66f5dc94b9240a7 Mon Sep 17 00:00:00 2001 From: Shaneeza Date: Fri, 8 Nov 2024 15:45:11 -0500 Subject: [PATCH 078/113] alignment --- packages/table/src/Cell/Cell.styles.ts | 31 +++++++++++-------- .../src/Cell/HeaderCell/HeaderCell.styles.ts | 4 +-- packages/table/src/Cell/InternalCell.tsx | 6 ++-- packages/table/src/Table.stories.tsx | 1 + packages/table/src/Table/Table.tsx | 4 ++- packages/table/src/Table/Table.types.ts | 14 +++++++++ .../table/src/TableContext/TableContext.tsx | 3 ++ .../src/TableContext/TableContext.types.ts | 11 +++++-- 8 files changed, 54 insertions(+), 20 deletions(-) diff --git a/packages/table/src/Cell/Cell.styles.ts b/packages/table/src/Cell/Cell.styles.ts index 5726a6825d..11a4199de3 100644 --- a/packages/table/src/Cell/Cell.styles.ts +++ b/packages/table/src/Cell/Cell.styles.ts @@ -1,6 +1,8 @@ -import { css } from '@leafygreen-ui/emotion'; +import { css, cx } from '@leafygreen-ui/emotion'; import { spacing } from '@leafygreen-ui/tokens'; +import { VerticalAlignment } from '../Table/Table.types'; + import { Align } from './Cell.types'; /** The base left & right padding in the table */ @@ -67,10 +69,13 @@ export const getCellContainerStyles = (align: Align = 'left') => css` text-align: ${align}; `; -export const baseCellStyles = css` +export const getBaseCellStyles = ( + verticalAlignment: VerticalAlignment = VerticalAlignment.Top, +) => css` padding: 0 ${spacing[200]}px; overflow: hidden; - vertical-align: top; + // TODO: this should be a prop + vertical-align: ${verticalAlignment}; &:focus-visible { box-shadow: inset; @@ -87,13 +92,13 @@ export const cellInnerStyles = css` min-width: 100%; `; -export const getCellEllipsisStyles = (shouldTruncate: boolean) => css` - ${shouldTruncate && - css` - flex: 1; - overflow: hidden; - white-space: nowrap; - text-overflow: ellipsis; - contain: inline-size; // 🤯 - `} -`; +export const getCellEllipsisStyles = (shouldTruncate: boolean) => + cx(css``, { + [css` + flex: 1; + overflow: hidden; + white-space: nowrap; + text-overflow: ellipsis; + contain: inline-size; // 🤯 + `]: shouldTruncate, + }); diff --git a/packages/table/src/Cell/HeaderCell/HeaderCell.styles.ts b/packages/table/src/Cell/HeaderCell/HeaderCell.styles.ts index c3bc272bf5..eec6491ce3 100644 --- a/packages/table/src/Cell/HeaderCell/HeaderCell.styles.ts +++ b/packages/table/src/Cell/HeaderCell/HeaderCell.styles.ts @@ -2,7 +2,7 @@ import { css, cx } from '@leafygreen-ui/emotion'; import { spacing } from '@leafygreen-ui/tokens'; import { - baseCellStyles, + getBaseCellStyles, getCellContainerStyles, getCellPadding, } from '../Cell.styles'; @@ -14,7 +14,7 @@ export const headerCellContentStyles = css` export const getBaseHeaderCellStyles = (size: number, isSelectable?: boolean) => cx( - baseCellStyles, + getBaseCellStyles(), css` &:first-of-type { ${getCellPadding({ depth: 0, isExpandable: false, isSelectable })} diff --git a/packages/table/src/Cell/InternalCell.tsx b/packages/table/src/Cell/InternalCell.tsx index 3cb1876024..62e07a88d1 100644 --- a/packages/table/src/Cell/InternalCell.tsx +++ b/packages/table/src/Cell/InternalCell.tsx @@ -3,10 +3,11 @@ import React from 'react'; import { cx } from '@leafygreen-ui/emotion'; import { LGIDS } from '../constants'; +import { useTableContext } from '../TableContext'; import { - baseCellStyles, cellInnerStyles, + getBaseCellStyles, getCellContainerStyles, } from './Cell.styles'; import { InternalCellProps } from './Cell.types'; @@ -18,10 +19,11 @@ const InternalCell = ({ align, ...rest }: InternalCellProps) => { + const { verticalAlignment } = useTableContext(); return (
diff --git a/packages/table/src/Table.stories.tsx b/packages/table/src/Table.stories.tsx index a0690584b4..f3dd3a53d4 100644 --- a/packages/table/src/Table.stories.tsx +++ b/packages/table/src/Table.stories.tsx @@ -184,6 +184,7 @@ export const LiveExample: StoryFn = args => { className={css` width: 1100px; `} + shouldTruncate={false} > {table.getHeaderGroups().map((headerGroup: HeaderGroup) => ( diff --git a/packages/table/src/Table/Table.tsx b/packages/table/src/Table/Table.tsx index 98c4862b28..6554b76114 100644 --- a/packages/table/src/Table/Table.tsx +++ b/packages/table/src/Table/Table.tsx @@ -18,13 +18,14 @@ import { TableProps } from './Table.types'; const Table = forwardRef>( ( { + table, children, className, + verticalAlignment = 'top', shouldAlternateRowColor = false, shouldTruncate = true, baseFontSize: baseFontSizeProp, darkMode: darkModeProp, - table, 'data-lgid': lgidProp = LGIDS.root, ...rest }: TableProps, @@ -55,6 +56,7 @@ const Table = forwardRef>( isSelectable={isSelectable} shouldTruncate={shouldTruncate} virtualTable={virtualTable} + verticalAlignment={verticalAlignment} > extends HTMLElementProps<'table'>, DarkModeProps, @@ -29,4 +37,10 @@ export interface TableProps * @default true */ shouldTruncate?: boolean; + + /** + * When rows are not truncated, this will determine if cells should be top or middle aligned + * @default 'top' + */ + verticalAlignment?: VerticalAlignment; } diff --git a/packages/table/src/TableContext/TableContext.tsx b/packages/table/src/TableContext/TableContext.tsx index 55b7373386..c33ad3f864 100644 --- a/packages/table/src/TableContext/TableContext.tsx +++ b/packages/table/src/TableContext/TableContext.tsx @@ -32,6 +32,7 @@ const TableContextProvider = ({ isSelectable, shouldTruncate, virtualTable, + verticalAlignment, }: PropsWithChildren>>) => { /** The appropriately typed context provider */ const TableProvider = (TableContext as React.Context>) @@ -44,6 +45,7 @@ const TableContextProvider = ({ isVirtual, isSelectable, shouldTruncate, + verticalAlignment, }; }, [ shouldAlternateRowColor, @@ -51,6 +53,7 @@ const TableContextProvider = ({ isVirtual, isSelectable, shouldTruncate, + verticalAlignment, ]); return ( diff --git a/packages/table/src/TableContext/TableContext.types.ts b/packages/table/src/TableContext/TableContext.types.ts index 32b192fa77..20887ca37a 100644 --- a/packages/table/src/TableContext/TableContext.types.ts +++ b/packages/table/src/TableContext/TableContext.types.ts @@ -34,14 +34,21 @@ export interface BaseTableContextValue { } export type TableProviderValues = PropsWithChildren< - Pick, 'shouldAlternateRowColor' | 'shouldTruncate'> + Pick< + TableProps, + 'shouldAlternateRowColor' | 'shouldTruncate' | 'verticalAlignment' + > > & DarkModeProps & SharedVirtualContextValue & BaseTableContextValue; export type TableContextValues = PropsWithChildren< - Pick, 'shouldAlternateRowColor' | 'shouldTruncate'> + // TODO: this is repeated above + Pick< + TableProps, + 'shouldAlternateRowColor' | 'shouldTruncate' | 'verticalAlignment' + > > & DarkModeProps & BaseTableContextValue; From cee55af62821b0f4c04cb1d70f9d91b95baec3e3 Mon Sep 17 00:00:00 2001 From: Shaneeza Date: Fri, 8 Nov 2024 16:08:03 -0500 Subject: [PATCH 079/113] remove comment --- packages/table/src/Cell/Cell.styles.ts | 1 - 1 file changed, 1 deletion(-) diff --git a/packages/table/src/Cell/Cell.styles.ts b/packages/table/src/Cell/Cell.styles.ts index 11a4199de3..c3169fb6ec 100644 --- a/packages/table/src/Cell/Cell.styles.ts +++ b/packages/table/src/Cell/Cell.styles.ts @@ -74,7 +74,6 @@ export const getBaseCellStyles = ( ) => css` padding: 0 ${spacing[200]}px; overflow: hidden; - // TODO: this should be a prop vertical-align: ${verticalAlignment}; &:focus-visible { From 56de09af55ec5aae7e3e4fbe0c26588968be1b7d Mon Sep 17 00:00:00 2001 From: Shaneeza Date: Fri, 8 Nov 2024 16:27:57 -0500 Subject: [PATCH 080/113] add test --- packages/table/src/Table.stories.tsx | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/packages/table/src/Table.stories.tsx b/packages/table/src/Table.stories.tsx index 0c38c10689..b4492b8391 100644 --- a/packages/table/src/Table.stories.tsx +++ b/packages/table/src/Table.stories.tsx @@ -4,7 +4,9 @@ import { storybookExcludedControlParams, StoryMetaType, } from '@lg-tools/storybook-utils'; +import { expect } from '@storybook/jest'; import { StoryFn } from '@storybook/react'; +import { within } from '@storybook/testing-library'; import Badge from '@leafygreen-ui/badge'; import Button from '@leafygreen-ui/button'; @@ -184,6 +186,7 @@ export const LiveExample: StoryFn = args => { className={css` width: 1100px; `} + data-testid="lg-table" > {table.getHeaderGroups().map((headerGroup: HeaderGroup) => ( @@ -1209,3 +1212,14 @@ export const StyledComponents: StoryFn = args => {
); }; + +export const StickyHeader = { + render: () => , + play: async ({ canvasElement }) => { + const canvas = within(canvasElement); + const table = await canvas.findByTestId('lg-table'); + window.scrollTo(0, 500); + await new Promise(r => setTimeout(r, 500)); + expect(table).toHaveAttribute('data-is-sticky', 'true'); + }, +}; From 4387ebdb914b6df3bfe66d3bc5b1b9e4f247355f Mon Sep 17 00:00:00 2001 From: Shaneeza Date: Fri, 8 Nov 2024 16:29:57 -0500 Subject: [PATCH 081/113] remove comments --- packages/table/src/Table.stories.tsx | 10 ---------- 1 file changed, 10 deletions(-) diff --git a/packages/table/src/Table.stories.tsx b/packages/table/src/Table.stories.tsx index b4492b8391..02926fe44f 100644 --- a/packages/table/src/Table.stories.tsx +++ b/packages/table/src/Table.stories.tsx @@ -65,13 +65,6 @@ const meta: StoryMetaType = { docs: { source: { type: 'code' }, }, - // docs: { - // source: { - // // any non-empty string here will skip jsx rendering, see: - // // https://github.com/storybookjs/storybook/blob/next/code/renderers/react/src/docs/jsxDecorator.tsx#L165 - // code: 'hello world', - // }, - // }, }, }; export default meta; @@ -206,7 +199,6 @@ export const LiveExample: StoryFn = args => {
{rows.map((row: LeafyGreenTableRow) => { - // const isExpandedContent = row.original.isExpandedContent ?? false; const isExpandedContent = row.isExpandedContent ?? false; return ( @@ -343,7 +335,6 @@ export const HundredsOfRows: StoryFn = args => { {rows.map((row: LeafyGreenTableRow) => { - // const isExpandedContent = row.original.isExpandedContent ?? false; const isExpandedContent = row.isExpandedContent ?? false; return ( @@ -1186,7 +1177,6 @@ export const StyledComponents: StoryFn = args => { {rows.map((row: LeafyGreenTableRow) => { - // const isExpandedContent = row.original.isExpandedContent ?? false; const isExpandedContent = row.isExpandedContent ?? false; return ( From 617860e1bb7c4964a38c3492caf1eac9ac44cf7c Mon Sep 17 00:00:00 2001 From: Shaneeza Date: Fri, 8 Nov 2024 16:43:02 -0500 Subject: [PATCH 082/113] testing removing styled components --- packages/table/package.json | 3 +- packages/table/src/Table.stories.tsx | 296 +++++++++++++-------------- 2 files changed, 149 insertions(+), 150 deletions(-) diff --git a/packages/table/package.json b/packages/table/package.json index c4b60b0ad5..90e3134d9b 100644 --- a/packages/table/package.json +++ b/packages/table/package.json @@ -38,8 +38,7 @@ "lodash": "^4.17.21", "polished": "^4.2.2", "react-fast-compare": "3.2.2", - "react-intersection-observer":"9.13.1", - "@emotion/styled": "^11.10.5" + "react-intersection-observer":"9.13.1" }, "devDependencies": { "@faker-js/faker": "^8.0.0", diff --git a/packages/table/src/Table.stories.tsx b/packages/table/src/Table.stories.tsx index 02926fe44f..8f7ff9aa06 100644 --- a/packages/table/src/Table.stories.tsx +++ b/packages/table/src/Table.stories.tsx @@ -1,5 +1,5 @@ import React, { Fragment, useState } from 'react'; -import styled from '@emotion/styled'; +// import styled from '@emotion/styled'; import { storybookExcludedControlParams, StoryMetaType, @@ -1055,153 +1055,153 @@ export const WithPagination: StoryFn = ({ ); }; -export const StyledComponents: StoryFn = args => { - const tableContainerRef = React.useRef(null); - const [data] = useState(() => makeKitchenSinkData(5)); - - const columns = React.useMemo>>( - () => [ - { - accessorKey: 'dateCreated', - header: 'Date Created', - enableSorting: true, - cell: info => - (info.getValue() as Date).toLocaleDateString('en-us', { - year: 'numeric', - month: 'short', - day: 'numeric', - }), - }, - { - accessorKey: 'frequency', - header: 'Frequency', - }, - { - accessorKey: 'clusterType', - header: 'Cluster Type', - }, - { - accessorKey: 'encryptorEnabled', - header: 'Encryptor', - // eslint-disable-next-line react/display-name - cell: info => ( - - {info.getValue() ? 'Enabled' : 'Not enabled'} - - ), - }, - { - accessorKey: 'mdbVersion', - header: 'MongoDB Version', - enableSorting: true, - size: 90, - }, - { - id: 'actions', - header: '', - size: 90, - // eslint-disable-next-line react/display-name - cell: _ => { - return ( - <> - - - - - - - - - - - ); - }, - }, - ], - [], - ); - - const table = useLeafyGreenTable({ - data, - columns, - }); - - const { rows } = table; - - const StyledCell = styled(Cell)` - color: grey; - `; - - const StyledRow = styled(Row)` - background: snow; - `; - - const StyledHeaderRow = styled(HeaderRow)` - background: whitesmoke; - `; - - const StyledHeaderCell = styled(HeaderCell)` - color: black; - `; - - const StyledExpandedContent = styled(ExpandedContent)` - td > div { - background: whitesmoke; - } - `; - - return ( - - - {table.getHeaderGroups().map((headerGroup: HeaderGroup) => ( - - {headerGroup.headers.map(header => { - return ( - - {flexRender( - header.column.columnDef.header, - header.getContext(), - )} - - ); - })} - - ))} - - - {rows.map((row: LeafyGreenTableRow) => { - const isExpandedContent = row.isExpandedContent ?? false; - return ( - - {!isExpandedContent && ( - - {row.getVisibleCells().map(cell => { - return ( - - {flexRender( - cell.column.columnDef.cell, - cell.getContext(), - )} - - ); - })} - - )} - {isExpandedContent && } - - ); - })} - -
- ); -}; +// export const StyledComponents: StoryFn = args => { +// const tableContainerRef = React.useRef(null); +// const [data] = useState(() => makeKitchenSinkData(5)); + +// const columns = React.useMemo>>( +// () => [ +// { +// accessorKey: 'dateCreated', +// header: 'Date Created', +// enableSorting: true, +// cell: info => +// (info.getValue() as Date).toLocaleDateString('en-us', { +// year: 'numeric', +// month: 'short', +// day: 'numeric', +// }), +// }, +// { +// accessorKey: 'frequency', +// header: 'Frequency', +// }, +// { +// accessorKey: 'clusterType', +// header: 'Cluster Type', +// }, +// { +// accessorKey: 'encryptorEnabled', +// header: 'Encryptor', +// // eslint-disable-next-line react/display-name +// cell: info => ( +// +// {info.getValue() ? 'Enabled' : 'Not enabled'} +// +// ), +// }, +// { +// accessorKey: 'mdbVersion', +// header: 'MongoDB Version', +// enableSorting: true, +// size: 90, +// }, +// { +// id: 'actions', +// header: '', +// size: 90, +// // eslint-disable-next-line react/display-name +// cell: _ => { +// return ( +// <> +// +// +// +// +// +// +// +// +// +// +// ); +// }, +// }, +// ], +// [], +// ); + +// const table = useLeafyGreenTable({ +// data, +// columns, +// }); + +// const { rows } = table; + +// const StyledCell = styled(Cell)` +// color: grey; +// `; + +// const StyledRow = styled(Row)` +// background: snow; +// `; + +// const StyledHeaderRow = styled(HeaderRow)` +// background: whitesmoke; +// `; + +// const StyledHeaderCell = styled(HeaderCell)` +// color: black; +// `; + +// const StyledExpandedContent = styled(ExpandedContent)` +// td > div { +// background: whitesmoke; +// } +// `; + +// return ( +// +// +// {table.getHeaderGroups().map((headerGroup: HeaderGroup) => ( +// +// {headerGroup.headers.map(header => { +// return ( +// +// {flexRender( +// header.column.columnDef.header, +// header.getContext(), +// )} +// +// ); +// })} +// +// ))} +// +// +// {rows.map((row: LeafyGreenTableRow) => { +// const isExpandedContent = row.isExpandedContent ?? false; +// return ( +// +// {!isExpandedContent && ( +// +// {row.getVisibleCells().map(cell => { +// return ( +// +// {flexRender( +// cell.column.columnDef.cell, +// cell.getContext(), +// )} +// +// ); +// })} +// +// )} +// {isExpandedContent && } +// +// ); +// })} +// +//
+// ); +// }; export const StickyHeader = { render: () => , From a663b4c236ce3554d2d583e3be105d7bf360518e Mon Sep 17 00:00:00 2001 From: Shaneeza Date: Fri, 8 Nov 2024 16:47:00 -0500 Subject: [PATCH 083/113] add back styled --- packages/table/package.json | 3 +- packages/table/src/Table.stories.tsx | 296 +++++++++++++-------------- 2 files changed, 150 insertions(+), 149 deletions(-) diff --git a/packages/table/package.json b/packages/table/package.json index 90e3134d9b..4ea146a4bf 100644 --- a/packages/table/package.json +++ b/packages/table/package.json @@ -46,7 +46,8 @@ "@leafygreen-ui/button": "^21.2.0", "@leafygreen-ui/badge": "^8.1.2", "@leafygreen-ui/pagination": "^1.0.23", - "@lg-tools/storybook-utils": "^0.1.1" + "@lg-tools/storybook-utils": "^0.1.1", + "@emotion/styled": "^11.10.5" }, "peerDependencies": { "@leafygreen-ui/leafygreen-provider": "^3.1.12" diff --git a/packages/table/src/Table.stories.tsx b/packages/table/src/Table.stories.tsx index 8f7ff9aa06..02926fe44f 100644 --- a/packages/table/src/Table.stories.tsx +++ b/packages/table/src/Table.stories.tsx @@ -1,5 +1,5 @@ import React, { Fragment, useState } from 'react'; -// import styled from '@emotion/styled'; +import styled from '@emotion/styled'; import { storybookExcludedControlParams, StoryMetaType, @@ -1055,153 +1055,153 @@ export const WithPagination: StoryFn = ({ ); }; -// export const StyledComponents: StoryFn = args => { -// const tableContainerRef = React.useRef(null); -// const [data] = useState(() => makeKitchenSinkData(5)); - -// const columns = React.useMemo>>( -// () => [ -// { -// accessorKey: 'dateCreated', -// header: 'Date Created', -// enableSorting: true, -// cell: info => -// (info.getValue() as Date).toLocaleDateString('en-us', { -// year: 'numeric', -// month: 'short', -// day: 'numeric', -// }), -// }, -// { -// accessorKey: 'frequency', -// header: 'Frequency', -// }, -// { -// accessorKey: 'clusterType', -// header: 'Cluster Type', -// }, -// { -// accessorKey: 'encryptorEnabled', -// header: 'Encryptor', -// // eslint-disable-next-line react/display-name -// cell: info => ( -// -// {info.getValue() ? 'Enabled' : 'Not enabled'} -// -// ), -// }, -// { -// accessorKey: 'mdbVersion', -// header: 'MongoDB Version', -// enableSorting: true, -// size: 90, -// }, -// { -// id: 'actions', -// header: '', -// size: 90, -// // eslint-disable-next-line react/display-name -// cell: _ => { -// return ( -// <> -// -// -// -// -// -// -// -// -// -// -// ); -// }, -// }, -// ], -// [], -// ); - -// const table = useLeafyGreenTable({ -// data, -// columns, -// }); - -// const { rows } = table; - -// const StyledCell = styled(Cell)` -// color: grey; -// `; - -// const StyledRow = styled(Row)` -// background: snow; -// `; - -// const StyledHeaderRow = styled(HeaderRow)` -// background: whitesmoke; -// `; - -// const StyledHeaderCell = styled(HeaderCell)` -// color: black; -// `; - -// const StyledExpandedContent = styled(ExpandedContent)` -// td > div { -// background: whitesmoke; -// } -// `; - -// return ( -// -// -// {table.getHeaderGroups().map((headerGroup: HeaderGroup) => ( -// -// {headerGroup.headers.map(header => { -// return ( -// -// {flexRender( -// header.column.columnDef.header, -// header.getContext(), -// )} -// -// ); -// })} -// -// ))} -// -// -// {rows.map((row: LeafyGreenTableRow) => { -// const isExpandedContent = row.isExpandedContent ?? false; -// return ( -// -// {!isExpandedContent && ( -// -// {row.getVisibleCells().map(cell => { -// return ( -// -// {flexRender( -// cell.column.columnDef.cell, -// cell.getContext(), -// )} -// -// ); -// })} -// -// )} -// {isExpandedContent && } -// -// ); -// })} -// -//
-// ); -// }; +export const StyledComponents: StoryFn = args => { + const tableContainerRef = React.useRef(null); + const [data] = useState(() => makeKitchenSinkData(5)); + + const columns = React.useMemo>>( + () => [ + { + accessorKey: 'dateCreated', + header: 'Date Created', + enableSorting: true, + cell: info => + (info.getValue() as Date).toLocaleDateString('en-us', { + year: 'numeric', + month: 'short', + day: 'numeric', + }), + }, + { + accessorKey: 'frequency', + header: 'Frequency', + }, + { + accessorKey: 'clusterType', + header: 'Cluster Type', + }, + { + accessorKey: 'encryptorEnabled', + header: 'Encryptor', + // eslint-disable-next-line react/display-name + cell: info => ( + + {info.getValue() ? 'Enabled' : 'Not enabled'} + + ), + }, + { + accessorKey: 'mdbVersion', + header: 'MongoDB Version', + enableSorting: true, + size: 90, + }, + { + id: 'actions', + header: '', + size: 90, + // eslint-disable-next-line react/display-name + cell: _ => { + return ( + <> + + + + + + + + + + + ); + }, + }, + ], + [], + ); + + const table = useLeafyGreenTable({ + data, + columns, + }); + + const { rows } = table; + + const StyledCell = styled(Cell)` + color: grey; + `; + + const StyledRow = styled(Row)` + background: snow; + `; + + const StyledHeaderRow = styled(HeaderRow)` + background: whitesmoke; + `; + + const StyledHeaderCell = styled(HeaderCell)` + color: black; + `; + + const StyledExpandedContent = styled(ExpandedContent)` + td > div { + background: whitesmoke; + } + `; + + return ( + + + {table.getHeaderGroups().map((headerGroup: HeaderGroup) => ( + + {headerGroup.headers.map(header => { + return ( + + {flexRender( + header.column.columnDef.header, + header.getContext(), + )} + + ); + })} + + ))} + + + {rows.map((row: LeafyGreenTableRow) => { + const isExpandedContent = row.isExpandedContent ?? false; + return ( + + {!isExpandedContent && ( + + {row.getVisibleCells().map(cell => { + return ( + + {flexRender( + cell.column.columnDef.cell, + cell.getContext(), + )} + + ); + })} + + )} + {isExpandedContent && } + + ); + })} + +
+ ); +}; export const StickyHeader = { render: () => , From 5cff7c45cbdb455972ba29357af56a3417c0330b Mon Sep 17 00:00:00 2001 From: Shaneeza Date: Fri, 8 Nov 2024 17:09:46 -0500 Subject: [PATCH 084/113] diff react-intersection-observer version --- packages/table/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/table/package.json b/packages/table/package.json index 4ea146a4bf..49c08b4439 100644 --- a/packages/table/package.json +++ b/packages/table/package.json @@ -38,7 +38,7 @@ "lodash": "^4.17.21", "polished": "^4.2.2", "react-fast-compare": "3.2.2", - "react-intersection-observer":"9.13.1" + "react-intersection-observer":"^8.25.1" }, "devDependencies": { "@faker-js/faker": "^8.0.0", From 7bae512a034da93dfcfd1883729a32f51271eec5 Mon Sep 17 00:00:00 2001 From: Shaneeza Date: Mon, 11 Nov 2024 09:05:49 -0500 Subject: [PATCH 085/113] yarn lonk --- yarn.lock | 5 ----- 1 file changed, 5 deletions(-) diff --git a/yarn.lock b/yarn.lock index f231bd7f7a..d1d76afb7d 100644 --- a/yarn.lock +++ b/yarn.lock @@ -13603,11 +13603,6 @@ react-fast-compare@3.2.2: resolved "https://registry.yarnpkg.com/react-fast-compare/-/react-fast-compare-3.2.2.tgz#929a97a532304ce9fee4bcae44234f1ce2c21d49" integrity sha512-nsO+KSNgo1SbJqJEYRE9ERzo7YtYbou/OqjSQKxV7jcKox7+usiUVZOAC+XnDOABXggQTno0Y1CpVnuWEc1boQ== -react-intersection-observer@9.13.1: - version "9.13.1" - resolved "http://localhost:4873/react-intersection-observer/-/react-intersection-observer-9.13.1.tgz#6c61a75801162491c6348bad09967f2caf445584" - integrity sha512-tSzDaTy0qwNPLJHg8XZhlyHTgGW6drFKTtvjdL+p6um12rcnp8Z5XstE+QNBJ7c64n5o0Lj4ilUleA41bmDoMw== - react-intersection-observer@^8.25.1: version "8.34.0" resolved "https://registry.yarnpkg.com/react-intersection-observer/-/react-intersection-observer-8.34.0.tgz#6f6e67831c52e6233f6b6cc7eb55814820137c42" From 21d474200b319e4e57b1925b50c0b859184805b5 Mon Sep 17 00:00:00 2001 From: Shaneeza Date: Mon, 11 Nov 2024 10:41:05 -0500 Subject: [PATCH 086/113] cell ternary, headercell util, expandedcontent styles --- packages/table/src/Cell/Cell.tsx | 12 ++++------ .../table/src/Cell/HeaderCell/HeaderCell.tsx | 18 +++----------- .../HeaderCell/utils/getHeaderCellState.ts | 24 +++++++++++++++++++ .../table/src/Cell/HeaderCell/utils/index.ts | 1 + .../ExpandedContent/ExpandedContent.styles.ts | 7 +----- .../src/ExpandedContent/ExpandedContent.tsx | 7 ++++-- 6 files changed, 39 insertions(+), 30 deletions(-) create mode 100644 packages/table/src/Cell/HeaderCell/utils/getHeaderCellState.ts create mode 100644 packages/table/src/Cell/HeaderCell/utils/index.ts diff --git a/packages/table/src/Cell/Cell.tsx b/packages/table/src/Cell/Cell.tsx index 8cdd83417e..c56337d22c 100644 --- a/packages/table/src/Cell/Cell.tsx +++ b/packages/table/src/Cell/Cell.tsx @@ -8,19 +8,17 @@ import { CellProps } from '.'; const Cell = ({ children, - cell, + cell: reactTableCell, ...rest }: CellProps) => { return ( <> - {!cell && ( - {children} - )} - - {cell && ( - + {reactTableCell ? ( + {children} + ) : ( + {children} )} ); diff --git a/packages/table/src/Cell/HeaderCell/HeaderCell.tsx b/packages/table/src/Cell/HeaderCell/HeaderCell.tsx index 090bd098cf..bfbadb35b2 100644 --- a/packages/table/src/Cell/HeaderCell/HeaderCell.tsx +++ b/packages/table/src/Cell/HeaderCell/HeaderCell.tsx @@ -11,13 +11,8 @@ import { getBaseHeaderCellStyles, getHeaderCellContentStyles, } from './HeaderCell.styles'; -import { HeaderCellProps, SortState, SortStates } from './HeaderCell.types'; - -const HeaderSortState: SortStates = { - false: SortState.Off, - asc: SortState.Asc, - desc: SortState.Desc, -}; +import { HeaderCellProps } from './HeaderCell.types'; +import { getHeaderCellState } from './utils'; /** * Component to wrap `` elements for use inside `` elements. @@ -32,14 +27,7 @@ const HeaderCell = ({ }: PropsWithChildren>) => { const { isSelectable } = useTableContext(); - let columnName, sortState, onSortIconClick; - - if (header && header?.column.columnDef.enableSorting) { - columnName = header.column.columnDef.header as string; - const headerSortDirection = header.column.getIsSorted().toString(); - sortState = HeaderSortState[headerSortDirection]; - onSortIconClick = header.column.getToggleSortingHandler(); - } + const { columnName, sortState, onSortIconClick } = getHeaderCellState(header); return ( ( + header?: Header, +) => { + let columnName, sortState, onSortIconClick; + + if (header && header?.column.columnDef.enableSorting) { + columnName = header.column.columnDef.header as string; + const headerSortDirection = header.column.getIsSorted().toString(); + sortState = HeaderSortState[headerSortDirection]; + onSortIconClick = header.column.getToggleSortingHandler(); + } + + return { columnName, sortState, onSortIconClick }; +}; diff --git a/packages/table/src/Cell/HeaderCell/utils/index.ts b/packages/table/src/Cell/HeaderCell/utils/index.ts new file mode 100644 index 0000000000..4a59f94fae --- /dev/null +++ b/packages/table/src/Cell/HeaderCell/utils/index.ts @@ -0,0 +1 @@ +export { getHeaderCellState } from './getHeaderCellState'; diff --git a/packages/table/src/ExpandedContent/ExpandedContent.styles.ts b/packages/table/src/ExpandedContent/ExpandedContent.styles.ts index feb0f080b5..560b963eb8 100644 --- a/packages/table/src/ExpandedContent/ExpandedContent.styles.ts +++ b/packages/table/src/ExpandedContent/ExpandedContent.styles.ts @@ -1,9 +1,7 @@ -import { css, cx } from '@leafygreen-ui/emotion'; +import { css } from '@leafygreen-ui/emotion'; import { Theme } from '@leafygreen-ui/lib'; import { palette } from '@leafygreen-ui/palette'; -import { getCellContainerStyles } from '../Cell/Cell.styles'; - export const baseStyles = css` padding: 0; `; @@ -16,6 +14,3 @@ export const expandedContentThemeStyles: Record = { background-color: ${palette.gray.light3}; `, }; - -export const getContainerStyles = (theme: Theme) => - cx(expandedContentThemeStyles[theme], getCellContainerStyles()); diff --git a/packages/table/src/ExpandedContent/ExpandedContent.tsx b/packages/table/src/ExpandedContent/ExpandedContent.tsx index 34343fc2c2..0d3a7744ce 100644 --- a/packages/table/src/ExpandedContent/ExpandedContent.tsx +++ b/packages/table/src/ExpandedContent/ExpandedContent.tsx @@ -8,7 +8,10 @@ import { LGIDS } from '../constants'; import InternalRowBase from '../Row/InternalRowBase'; import { useVirtualTableContext } from '../TableContext'; -import { baseStyles, getContainerStyles } from './ExpandedContent.styles'; +import { + baseStyles, + expandedContentThemeStyles, +} from './ExpandedContent.styles'; import { ExpandedContentProps } from './ExpandedContent.types'; const ExpandedContent = ({ @@ -39,7 +42,7 @@ const ExpandedContent = ({ className={cx(baseStyles)} data-lgid={LGIDS.cell} > -
+
{content}
From c3568f47280d64c28f0ec839203e59a184836cc2 Mon Sep 17 00:00:00 2001 From: Shaneeza Date: Mon, 11 Nov 2024 12:23:58 -0500 Subject: [PATCH 087/113] fb - toggleExpand, isVirtual boolean, type casting, tsdocs --- packages/table/src/Row/InternalRowWithRT.tsx | 13 ++++------- packages/table/src/Table/Table.tsx | 3 +-- packages/table/src/Table/Table.types.ts | 5 ++-- .../useLeafyGreenTable.types.ts | 23 +++++++++++++++++++ .../useLeafyGreenVirtualTable.types.ts | 2 +- 5 files changed, 33 insertions(+), 13 deletions(-) diff --git a/packages/table/src/Row/InternalRowWithRT.tsx b/packages/table/src/Row/InternalRowWithRT.tsx index 543853e59a..0c25b4ae47 100644 --- a/packages/table/src/Row/InternalRowWithRT.tsx +++ b/packages/table/src/Row/InternalRowWithRT.tsx @@ -31,7 +31,7 @@ const InternalRowWithRT = ({ const isExpandable = row.getCanExpand(); const depth = row.depth; - const toggleExpanded = useCallback(() => row.toggleExpanded(), [row]); + // const toggleExpanded = useCallback(() => row.toggleExpanded(), [row]); const contextValues = useMemo(() => { return { @@ -39,12 +39,9 @@ const InternalRowWithRT = ({ isExpanded, isExpandable, depth, - toggleExpanded, + toggleExpanded: () => row.toggleExpanded(), }; - }, [depth, disabled, isExpandable, isExpanded, toggleExpanded]); - - // eslint-disable-next-line no-console - // console.log(`🪼rerender🪼 row: ${row.id}, depth: ${row.depth}`); + }, [depth, disabled, isExpandable, isExpanded, row]); return ( @@ -83,9 +80,9 @@ export default InternalRowWithRT; const arePropsEqual = (prevProps, nextProps) => { // Children will never be the same const { children: prevChildren, ...restPrevProps } = prevProps; - const { children: nextChildren, ...restnextProps } = nextProps; + const { children: nextChildren, ...restNextProps } = nextProps; - const propsAreEqual = isEqual(restPrevProps, restnextProps); + const propsAreEqual = isEqual(restPrevProps, restNextProps); return propsAreEqual; }; diff --git a/packages/table/src/Table/Table.tsx b/packages/table/src/Table/Table.tsx index 98c4862b28..1d0fd58f81 100644 --- a/packages/table/src/Table/Table.tsx +++ b/packages/table/src/Table/Table.tsx @@ -33,8 +33,7 @@ const Table = forwardRef>( const baseFontSize: BaseFontSize = useUpdatedBaseFontSize(baseFontSizeProp); const { theme, darkMode } = useDarkMode(darkModeProp); - const isVirtual = - table && (table as LeafyGreenVirtualTable).virtual ? true : false; + const isVirtual = Boolean((table as LeafyGreenVirtualTable)?.virtual); const virtualTable = isVirtual ? (table as LeafyGreenVirtualTable)!.virtual : undefined; diff --git a/packages/table/src/Table/Table.types.ts b/packages/table/src/Table/Table.types.ts index a849b082c5..4297b75c25 100644 --- a/packages/table/src/Table/Table.types.ts +++ b/packages/table/src/Table/Table.types.ts @@ -13,6 +13,7 @@ export interface TableProps * @default false */ shouldAlternateRowColor?: boolean; + /** * The base font size of the title and text rendered in children. * @default 13 @@ -20,9 +21,9 @@ export interface TableProps baseFontSize?: BaseFontSize; /** - * The `useLeafyGreenTable` return value + * The `useLeafyGreenTable` or `useLeafyGreenVirtualTable` return value */ - table?: LeafyGreenTable | LeafyGreenVirtualTable; //TODO: is there a better way to type this? + table?: LeafyGreenTable | LeafyGreenVirtualTable; /** * Whether all rows will truncate. If true, cells will truncate at one line. If false then there will be no height limit and cells will not truncate. diff --git a/packages/table/src/useLeafyGreenTable/useLeafyGreenTable.types.ts b/packages/table/src/useLeafyGreenTable/useLeafyGreenTable.types.ts index ccc8167f9e..be6bb55680 100644 --- a/packages/table/src/useLeafyGreenTable/useLeafyGreenTable.types.ts +++ b/packages/table/src/useLeafyGreenTable/useLeafyGreenTable.types.ts @@ -47,9 +47,24 @@ export type LeafyGreenTableOptions< T extends LGRowData, V extends unknown = unknown, > = Omit>, 'getCoreRowModel' | 'columns'> & { + /** + * Setting this prop will inject a new column containing a checkbox into all rows. + */ hasSelectableRows?: boolean; + + /** + * The column definitions for the table + */ columns: Array>; + + /** + * Setting this prop will indicate that the Table component is being used with the Pagination component. This will expose various pagination utilities from `table.getState().pagination`. + */ withPagination?: boolean; + + /** + * This prop controls whether a 'select all' checkbox will be rendered in the header row. This will be set to `true` by default. + */ allowSelectAll?: boolean; }; @@ -58,6 +73,14 @@ export type LeafyGreenTableOptions< */ export interface LeafyGreenTable extends Table> { + /** + * Whether the table will have selectable rows. + */ hasSelectableRows: boolean; + + /** + * The rows that are returned from calling useLeafyGreenTable or useLeafyGreenVirtualTable + */ rows: Array; + virtual: never; } diff --git a/packages/table/src/useLeafyGreenVirtualTable/useLeafyGreenVirtualTable.types.ts b/packages/table/src/useLeafyGreenVirtualTable/useLeafyGreenVirtualTable.types.ts index 5f7df0079c..9c9d3922e3 100644 --- a/packages/table/src/useLeafyGreenVirtualTable/useLeafyGreenVirtualTable.types.ts +++ b/packages/table/src/useLeafyGreenVirtualTable/useLeafyGreenVirtualTable.types.ts @@ -36,7 +36,7 @@ export interface LeafyGreenVirtualTableOptions< * LeafyGreen extension of `useReactTable` {@link Table} */ export interface LeafyGreenVirtualTable - extends LeafyGreenTable { + extends Omit, 'virtual'> { /** * Available [properties and methods](https://tanstack.com/virtual/latest/docs/api/virtualizer#virtualizer-instance) return from the Virtualizer instance. */ From 9dd632b89142fb0a457855a06f1bb188707775fb Mon Sep 17 00:00:00 2001 From: Shaneeza Date: Mon, 11 Nov 2024 14:15:56 -0500 Subject: [PATCH 088/113] virtual scrolling padding util --- .../table/src/Cell/HeaderCell/HeaderCell.tsx | 2 +- .../table/src/Cell/HeaderCell/utils/index.ts | 1 - packages/table/src/Row/InternalRowWithRT.tsx | 1 - packages/table/src/TableBody/TableBody.tsx | 18 +++------- .../utils/useVirtualScrollPadding.ts | 33 +++++++++++++++++++ packages/table/src/utils/getParentRowId.ts | 17 ---------- 6 files changed, 39 insertions(+), 33 deletions(-) delete mode 100644 packages/table/src/Cell/HeaderCell/utils/index.ts create mode 100644 packages/table/src/TableBody/utils/useVirtualScrollPadding.ts delete mode 100644 packages/table/src/utils/getParentRowId.ts diff --git a/packages/table/src/Cell/HeaderCell/HeaderCell.tsx b/packages/table/src/Cell/HeaderCell/HeaderCell.tsx index bfbadb35b2..aee6b7df6d 100644 --- a/packages/table/src/Cell/HeaderCell/HeaderCell.tsx +++ b/packages/table/src/Cell/HeaderCell/HeaderCell.tsx @@ -7,12 +7,12 @@ import { useTableContext } from '../../TableContext'; import { LGRowData } from '../../useLeafyGreenTable'; import SortIcon from './SortIcon/SortIcon'; +import { getHeaderCellState } from './utils/getHeaderCellState'; import { getBaseHeaderCellStyles, getHeaderCellContentStyles, } from './HeaderCell.styles'; import { HeaderCellProps } from './HeaderCell.types'; -import { getHeaderCellState } from './utils'; /** * Component to wrap `` elements for use inside `` elements. diff --git a/packages/table/src/Cell/HeaderCell/utils/index.ts b/packages/table/src/Cell/HeaderCell/utils/index.ts deleted file mode 100644 index 4a59f94fae..0000000000 --- a/packages/table/src/Cell/HeaderCell/utils/index.ts +++ /dev/null @@ -1 +0,0 @@ -export { getHeaderCellState } from './getHeaderCellState'; diff --git a/packages/table/src/Row/InternalRowWithRT.tsx b/packages/table/src/Row/InternalRowWithRT.tsx index 0c25b4ae47..430b4f4ce1 100644 --- a/packages/table/src/Row/InternalRowWithRT.tsx +++ b/packages/table/src/Row/InternalRowWithRT.tsx @@ -31,7 +31,6 @@ const InternalRowWithRT = ({ const isExpandable = row.getCanExpand(); const depth = row.depth; - // const toggleExpanded = useCallback(() => row.toggleExpanded(), [row]); const contextValues = useMemo(() => { return { diff --git a/packages/table/src/TableBody/TableBody.tsx b/packages/table/src/TableBody/TableBody.tsx index 02a1d63cc3..f5802444b3 100644 --- a/packages/table/src/TableBody/TableBody.tsx +++ b/packages/table/src/TableBody/TableBody.tsx @@ -3,6 +3,7 @@ import React, { useRef } from 'react'; import { useTableContext } from '../TableContext'; import { useVirtualTableContext } from '../TableContext/VirtualTableContext'; +import { useVirtualScrollPadding } from './utils/useVirtualScrollPadding'; import { paddingBottomStyles, paddingTopStyles } from './TableBody.styles'; import { TableBodyProps } from './TableBody.types'; @@ -10,29 +11,20 @@ const TableBody = ({ children, ...rest }: TableBodyProps) => { const { isVirtual } = useTableContext(); const { virtualTable } = useVirtualTableContext(); - const numOfVirtualItems = virtualTable?.getVirtualItems().length || 0; - const startOfFirstVirtualItem = - virtualTable?.getVirtualItems()[0]?.start || 0; - const endOfLastVirtualItem = - virtualTable?.getVirtualItems()[virtualTable?.getVirtualItems().length - 1] - ?.end || 0; - const totalSizOfVirtualTable = virtualTable?.getTotalSize() || 0; + const { paddingTop, paddingBottom } = useVirtualScrollPadding( + isVirtual, + virtualTable, + ); const topRef = useRef(null); const bottomRef = useRef(null); - let paddingTop = 0; - let paddingBottom = 0; - if (isVirtual) { - paddingTop = numOfVirtualItems > 0 ? startOfFirstVirtualItem : 0; topRef.current && topRef.current.style.setProperty( '--virtual-padding-top', `${paddingTop}px`, ); - paddingBottom = - numOfVirtualItems > 0 ? totalSizOfVirtualTable - endOfLastVirtualItem : 0; bottomRef.current && bottomRef.current.style.setProperty( '--virtual-padding-bottom', diff --git a/packages/table/src/TableBody/utils/useVirtualScrollPadding.ts b/packages/table/src/TableBody/utils/useVirtualScrollPadding.ts new file mode 100644 index 0000000000..67d55ce90d --- /dev/null +++ b/packages/table/src/TableBody/utils/useVirtualScrollPadding.ts @@ -0,0 +1,33 @@ +import { LGRowData } from '../../useLeafyGreenTable'; +import { LeafyGreenVirtualTable } from '../../useLeafyGreenVirtualTable'; + +export const useVirtualScrollPadding = ( + isVirtual = false, + virtualTable?: LeafyGreenVirtualTable['virtual'], +) => { + let paddingTop = 0; + let paddingBottom = 0; + + if (isVirtual && virtualTable) { + const virtualItems = virtualTable.getVirtualItems(); + const numOfVirtualItems = virtualItems.length || 0; + const startOfFirstVirtualItem = virtualItems[0]?.start || 0; + const endOfLastVirtualItem = + virtualItems[virtualItems.length - 1]?.end || 0; + const totalSizOfVirtualTable = virtualTable.getTotalSize() || 0; + + paddingTop = numOfVirtualItems > 0 ? startOfFirstVirtualItem : 0; + paddingBottom = + numOfVirtualItems > 0 ? totalSizOfVirtualTable - endOfLastVirtualItem : 0; + + return { + paddingTop, + paddingBottom, + }; + } + + return { + paddingTop, + paddingBottom, + }; +}; diff --git a/packages/table/src/utils/getParentRowId.ts b/packages/table/src/utils/getParentRowId.ts deleted file mode 100644 index c3145db282..0000000000 --- a/packages/table/src/utils/getParentRowId.ts +++ /dev/null @@ -1,17 +0,0 @@ -/** - * `react-table`'s Row `id`s are configured so that the first nested row of Row with `id` '0' is: '0.0'. - * - * This function parses a Row's `id` to return its immediate parent Row's id if it exists, and returns `undefined` otherwise. - * - * @param childId `id` of the referenced row - * @returns the `id` of the parent row - */ -function getParentRowId(childId?: string) { - if (childId) { - const childIds = childId.split('.'); - const parentId = childIds.slice(0, childIds.length - 1).join('.'); - return parentId.length > 0 ? parentId : undefined; - } -} - -export default getParentRowId; From d1037c2f9fc1074c17a369445051aff0741de9cd Mon Sep 17 00:00:00 2001 From: Shaneeza Date: Mon, 11 Nov 2024 14:31:50 -0500 Subject: [PATCH 089/113] forgot to save --- packages/table/src/Table/Table.tsx | 4 +--- packages/table/src/TableContext/TableContext.tsx | 6 +++--- packages/table/src/TableContext/TableContext.types.ts | 2 +- 3 files changed, 5 insertions(+), 7 deletions(-) diff --git a/packages/table/src/Table/Table.tsx b/packages/table/src/Table/Table.tsx index 1d0fd58f81..d71b1f7a1f 100644 --- a/packages/table/src/Table/Table.tsx +++ b/packages/table/src/Table/Table.tsx @@ -34,9 +34,7 @@ const Table = forwardRef>( const { theme, darkMode } = useDarkMode(darkModeProp); const isVirtual = Boolean((table as LeafyGreenVirtualTable)?.virtual); - const virtualTable = isVirtual - ? (table as LeafyGreenVirtualTable)!.virtual - : undefined; + const virtualTable = isVirtual ? table!.virtual : undefined; const isSelectable = table ? table.hasSelectableRows : false; return ( diff --git a/packages/table/src/TableContext/TableContext.tsx b/packages/table/src/TableContext/TableContext.tsx index 55b7373386..731e59ba11 100644 --- a/packages/table/src/TableContext/TableContext.tsx +++ b/packages/table/src/TableContext/TableContext.tsx @@ -11,7 +11,7 @@ import { LGRowData } from '../useLeafyGreenTable'; import { type TableContextValues, - type TableProviderValues, + type TableProviderProps, } from './TableContext.types'; import VirtualTableContextProvider from './VirtualTableContext'; @@ -32,9 +32,9 @@ const TableContextProvider = ({ isSelectable, shouldTruncate, virtualTable, -}: PropsWithChildren>>) => { +}: PropsWithChildren>>) => { /** The appropriately typed context provider */ - const TableProvider = (TableContext as React.Context>) + const TableProvider = (TableContext as React.Context>) .Provider; const tableProviderData = useMemo(() => { diff --git a/packages/table/src/TableContext/TableContext.types.ts b/packages/table/src/TableContext/TableContext.types.ts index 32b192fa77..0181a72fd8 100644 --- a/packages/table/src/TableContext/TableContext.types.ts +++ b/packages/table/src/TableContext/TableContext.types.ts @@ -33,7 +33,7 @@ export interface BaseTableContextValue { isSelectable?: boolean; } -export type TableProviderValues = PropsWithChildren< +export type TableProviderProps = PropsWithChildren< Pick, 'shouldAlternateRowColor' | 'shouldTruncate'> > & DarkModeProps & From 9366b3bae1399801680d490866c82793a029ecfd Mon Sep 17 00:00:00 2001 From: Shaneeza Date: Mon, 11 Nov 2024 15:37:58 -0500 Subject: [PATCH 090/113] fb - remove virtual context --- .../HeaderCell/utils/getHeaderCellState.ts | 7 +-- .../src/ExpandedContent/ExpandedContent.tsx | 4 +- packages/table/src/Row/Row.tsx | 5 +-- packages/table/src/TableBody/TableBody.tsx | 4 +- .../utils/useVirtualScrollPadding.ts | 5 --- .../table/src/TableContext/TableContext.tsx | 20 +++------ .../src/TableContext/TableContext.types.ts | 43 ++++++------------- .../src/TableContext/VirtualTableContext.tsx | 40 ----------------- packages/table/src/TableContext/index.ts | 16 +------ 9 files changed, 31 insertions(+), 113 deletions(-) delete mode 100644 packages/table/src/TableContext/VirtualTableContext.tsx diff --git a/packages/table/src/Cell/HeaderCell/utils/getHeaderCellState.ts b/packages/table/src/Cell/HeaderCell/utils/getHeaderCellState.ts index fda6b3cd16..690cbd1109 100644 --- a/packages/table/src/Cell/HeaderCell/utils/getHeaderCellState.ts +++ b/packages/table/src/Cell/HeaderCell/utils/getHeaderCellState.ts @@ -14,10 +14,11 @@ export const getHeaderCellState = ( let columnName, sortState, onSortIconClick; if (header && header?.column.columnDef.enableSorting) { - columnName = header.column.columnDef.header as string; - const headerSortDirection = header.column.getIsSorted().toString(); + const column = header.column; + columnName = column.columnDef.header as string; + const headerSortDirection = column.getIsSorted().toString(); sortState = HeaderSortState[headerSortDirection]; - onSortIconClick = header.column.getToggleSortingHandler(); + onSortIconClick = column.getToggleSortingHandler(); } return { columnName, sortState, onSortIconClick }; diff --git a/packages/table/src/ExpandedContent/ExpandedContent.tsx b/packages/table/src/ExpandedContent/ExpandedContent.tsx index 0d3a7744ce..4906639c39 100644 --- a/packages/table/src/ExpandedContent/ExpandedContent.tsx +++ b/packages/table/src/ExpandedContent/ExpandedContent.tsx @@ -6,7 +6,7 @@ import { useDarkMode } from '@leafygreen-ui/leafygreen-provider'; import { LGIDS } from '../constants'; import InternalRowBase from '../Row/InternalRowBase'; -import { useVirtualTableContext } from '../TableContext'; +import { useTableContext } from '../TableContext'; import { baseStyles, @@ -19,7 +19,7 @@ const ExpandedContent = ({ virtualRow, ...rest }: ExpandedContentProps) => { - const { virtualTable } = useVirtualTableContext(); + const { virtualTable } = useTableContext(); const content = row.original.renderExpandedContent && diff --git a/packages/table/src/Row/Row.tsx b/packages/table/src/Row/Row.tsx index 21802aa81e..aa72e1ffa0 100644 --- a/packages/table/src/Row/Row.tsx +++ b/packages/table/src/Row/Row.tsx @@ -3,7 +3,7 @@ import PropTypes from 'prop-types'; import { useDarkMode } from '@leafygreen-ui/leafygreen-provider'; -import { useTableContext, useVirtualTableContext } from '../TableContext'; +import { useTableContext } from '../TableContext'; import { LGRowData } from '../useLeafyGreenTable'; import InternalRowWithoutRT from './InternalRowWithoutRT'; @@ -21,8 +21,7 @@ const Row = ({ ...rest }: RowProps) => { const { theme } = useDarkMode(); - const { shouldAlternateRowColor } = useTableContext(); - const { virtualTable } = useVirtualTableContext(); + const { shouldAlternateRowColor, virtualTable } = useTableContext(); return ( <> diff --git a/packages/table/src/TableBody/TableBody.tsx b/packages/table/src/TableBody/TableBody.tsx index f5802444b3..7d14324b38 100644 --- a/packages/table/src/TableBody/TableBody.tsx +++ b/packages/table/src/TableBody/TableBody.tsx @@ -1,15 +1,13 @@ import React, { useRef } from 'react'; import { useTableContext } from '../TableContext'; -import { useVirtualTableContext } from '../TableContext/VirtualTableContext'; import { useVirtualScrollPadding } from './utils/useVirtualScrollPadding'; import { paddingBottomStyles, paddingTopStyles } from './TableBody.styles'; import { TableBodyProps } from './TableBody.types'; const TableBody = ({ children, ...rest }: TableBodyProps) => { - const { isVirtual } = useTableContext(); - const { virtualTable } = useVirtualTableContext(); + const { isVirtual, virtualTable } = useTableContext(); const { paddingTop, paddingBottom } = useVirtualScrollPadding( isVirtual, diff --git a/packages/table/src/TableBody/utils/useVirtualScrollPadding.ts b/packages/table/src/TableBody/utils/useVirtualScrollPadding.ts index 67d55ce90d..601ea816fc 100644 --- a/packages/table/src/TableBody/utils/useVirtualScrollPadding.ts +++ b/packages/table/src/TableBody/utils/useVirtualScrollPadding.ts @@ -19,11 +19,6 @@ export const useVirtualScrollPadding = ( paddingTop = numOfVirtualItems > 0 ? startOfFirstVirtualItem : 0; paddingBottom = numOfVirtualItems > 0 ? totalSizOfVirtualTable - endOfLastVirtualItem : 0; - - return { - paddingTop, - paddingBottom, - }; } return { diff --git a/packages/table/src/TableContext/TableContext.tsx b/packages/table/src/TableContext/TableContext.tsx index 731e59ba11..4a6af05f40 100644 --- a/packages/table/src/TableContext/TableContext.tsx +++ b/packages/table/src/TableContext/TableContext.tsx @@ -9,19 +9,15 @@ import LeafyGreenProvider from '@leafygreen-ui/leafygreen-provider'; import { LGRowData } from '../useLeafyGreenTable'; -import { - type TableContextValues, - type TableProviderProps, -} from './TableContext.types'; -import VirtualTableContextProvider from './VirtualTableContext'; +import { type TableProviderProps } from './TableContext.types'; export const TableContext = createContext< - Partial> + Partial> >({}); export const useTableContext = () => - useContext>( - TableContext as React.Context>, + useContext>( + TableContext as React.Context>, ); const TableContextProvider = ({ @@ -44,6 +40,7 @@ const TableContextProvider = ({ isVirtual, isSelectable, shouldTruncate, + virtualTable, }; }, [ shouldAlternateRowColor, @@ -51,15 +48,12 @@ const TableContextProvider = ({ isVirtual, isSelectable, shouldTruncate, + virtualTable, ]); return ( - - - {children} - - + {children} ); }; diff --git a/packages/table/src/TableContext/TableContext.types.ts b/packages/table/src/TableContext/TableContext.types.ts index 0181a72fd8..9a412bb57d 100644 --- a/packages/table/src/TableContext/TableContext.types.ts +++ b/packages/table/src/TableContext/TableContext.types.ts @@ -1,27 +1,12 @@ import { PropsWithChildren } from 'react'; -import { Virtualizer } from '@tanstack/react-virtual'; import { DarkModeProps } from '@leafygreen-ui/lib'; import { TableProps } from '../Table/Table.types'; -import { LeafyGreenTable, LGRowData } from '../useLeafyGreenTable'; -import { LeafyGreenVirtualItem } from '../useLeafyGreenVirtualTable'; - -export interface SharedVirtualContextValue { - /** - * Available [properties and methods](https://tanstack.com/virtual/latest/docs/api/virtualizer#virtualizer-instance) return from the Virtualizer instance. - */ - virtualTable?: Omit, 'getVirtualItems'> & { - getVirtualItems: () => Array>; - }; -} - -export interface BaseTableContextValue { - /** - * The `useLeafyGreenTable` return value - */ - table?: LeafyGreenTable; +import { LGRowData } from '../useLeafyGreenTable'; +import { LeafyGreenVirtualTable } from '../useLeafyGreenVirtualTable'; +interface BaseTableContextValue { /** * Whether the table is using virtual scrolling */ @@ -31,20 +16,20 @@ export interface BaseTableContextValue { * Whether rows in the table are selectable */ isSelectable?: boolean; + + /** + * Available [properties and methods](https://tanstack.com/virtual/latest/docs/api/virtualizer#virtualizer-instance) returned from the Virtualizer instance. + */ + virtualTable?: LeafyGreenVirtualTable['virtual']; } -export type TableProviderProps = PropsWithChildren< - Pick, 'shouldAlternateRowColor' | 'shouldTruncate'> -> & - DarkModeProps & - SharedVirtualContextValue & - BaseTableContextValue; +type PartialTableProps = Pick< + TableProps, + 'shouldAlternateRowColor' | 'shouldTruncate' +>; -export type TableContextValues = PropsWithChildren< - Pick, 'shouldAlternateRowColor' | 'shouldTruncate'> +export type TableProviderProps = PropsWithChildren< + PartialTableProps > & DarkModeProps & BaseTableContextValue; - -export type VirtualTableContextValues = PropsWithChildren & - SharedVirtualContextValue; diff --git a/packages/table/src/TableContext/VirtualTableContext.tsx b/packages/table/src/TableContext/VirtualTableContext.tsx deleted file mode 100644 index d97e79e3a0..0000000000 --- a/packages/table/src/TableContext/VirtualTableContext.tsx +++ /dev/null @@ -1,40 +0,0 @@ -import React, { - createContext, - PropsWithChildren, - useContext, - useMemo, -} from 'react'; - -import { LGRowData } from '../useLeafyGreenTable'; - -import { type VirtualTableContextValues } from './TableContext.types'; - -export const VirtualTableContext = createContext< - Partial> ->({}); - -export const useVirtualTableContext = () => - useContext>( - VirtualTableContext as React.Context>, - ); - -const VirtualTableContextProvider = ({ - children, - virtualTable, -}: PropsWithChildren>>) => { - const VirtualTableProvider = ( - VirtualTableContext as React.Context> - ).Provider; - - const providerData = useMemo(() => { - return { - virtualTable, - }; - }, [virtualTable]); - - return ( - {children} - ); -}; - -export default VirtualTableContextProvider; diff --git a/packages/table/src/TableContext/index.ts b/packages/table/src/TableContext/index.ts index 66a8626c4e..6c33156707 100644 --- a/packages/table/src/TableContext/index.ts +++ b/packages/table/src/TableContext/index.ts @@ -1,17 +1,3 @@ import TableContextProvider, { useTableContext } from './TableContext'; -import type { - TableContextValues, - VirtualTableContextValues, -} from './TableContext.types'; -import VirtualTableContextProvider, { - useVirtualTableContext, -} from './VirtualTableContext'; -export { - TableContextProvider, - type TableContextValues, - useTableContext, - useVirtualTableContext, - VirtualTableContextProvider, - type VirtualTableContextValues, -}; +export { TableContextProvider, useTableContext }; From 15ff06b8fcd5b5ec0a4ad665f856db8842250050 Mon Sep 17 00:00:00 2001 From: Shaneeza Date: Tue, 12 Nov 2024 13:48:03 -0500 Subject: [PATCH 091/113] custom row model --- packages/table/src/Row/InternalRowWithRT.tsx | 2 +- packages/table/src/Row/Row.stories.tsx | 4 +- packages/table/src/Table.stories.tsx | 44 ++++++------ .../table/src/Table/TableWithVS.stories.tsx | 8 +-- .../useLeafyGreenTable/useLeafyGreenTable.tsx | 69 ++++++++++++------- .../useLeafyGreenTable.types.ts | 13 +--- .../useLeafyGreenVirtualTable.tsx | 4 +- 7 files changed, 76 insertions(+), 68 deletions(-) diff --git a/packages/table/src/Row/InternalRowWithRT.tsx b/packages/table/src/Row/InternalRowWithRT.tsx index 430b4f4ce1..3a5c44e8e7 100644 --- a/packages/table/src/Row/InternalRowWithRT.tsx +++ b/packages/table/src/Row/InternalRowWithRT.tsx @@ -1,4 +1,4 @@ -import React, { useCallback, useMemo } from 'react'; +import React, { useMemo } from 'react'; import isEqual from 'react-fast-compare'; import { cx } from '@leafygreen-ui/emotion'; diff --git a/packages/table/src/Row/Row.stories.tsx b/packages/table/src/Row/Row.stories.tsx index 40c6c061fb..ea33e669d9 100644 --- a/packages/table/src/Row/Row.stories.tsx +++ b/packages/table/src/Row/Row.stories.tsx @@ -168,7 +168,7 @@ export const DisabledNestedRows: StoryFn = ({ row, ...rest }) => { onExpandedChange: setExpanded, }); - const { rows } = table; + const { rows } = table.getRowModel(); return ( <> @@ -297,7 +297,7 @@ export const DisabledSelectableRows: StoryFn< hasSelectableRows: true, }); - const { rows } = table; + const { rows } = table.getRowModel(); return (
diff --git a/packages/table/src/Table.stories.tsx b/packages/table/src/Table.stories.tsx index a0690584b4..33b5bf494c 100644 --- a/packages/table/src/Table.stories.tsx +++ b/packages/table/src/Table.stories.tsx @@ -63,13 +63,6 @@ const meta: StoryMetaType = { docs: { source: { type: 'code' }, }, - // docs: { - // source: { - // // any non-empty string here will skip jsx rendering, see: - // // https://github.com/storybookjs/storybook/blob/next/code/renderers/react/src/docs/jsxDecorator.tsx#L165 - // code: 'hello world', - // }, - // }, }, }; export default meta; @@ -101,7 +94,6 @@ const Template: StoryFn = args => { ); }; -// FIXME: this story freezes story book unless opened outside of an iframe export const LiveExample: StoryFn = args => { const tableContainerRef = React.useRef(null); const [data] = useState(() => makeKitchenSinkData(100)); @@ -173,7 +165,7 @@ export const LiveExample: StoryFn = args => { columns, }); - const { rows } = table; + const { rows } = table.getRowModel(); return ( <> @@ -203,7 +195,6 @@ export const LiveExample: StoryFn = args => { {rows.map((row: LeafyGreenTableRow) => { - // const isExpandedContent = row.original.isExpandedContent ?? false; const isExpandedContent = row.isExpandedContent ?? false; return ( @@ -309,7 +300,7 @@ export const HundredsOfRows: StoryFn = args => { columns, }); - const { rows } = table; + const { rows } = table.getRowModel(); return ( <> @@ -339,7 +330,6 @@ export const HundredsOfRows: StoryFn = args => { {rows.map((row: LeafyGreenTableRow) => { - // const isExpandedContent = row.original.isExpandedContent ?? false; const isExpandedContent = row.isExpandedContent ?? false; return ( @@ -368,12 +358,18 @@ export const HundredsOfRows: StoryFn = args => { ); }; -LiveExample.argTypes = { +HundredsOfRows.argTypes = { shouldAlternateRowColor: { control: 'none', }, }; +HundredsOfRows.parameters = { + chromatic: { + disableSnapshots: true, + }, +}; + export const Basic = Template.bind({}); export const ZebraStripes = Template.bind({}); @@ -433,14 +429,14 @@ export const NestedRows: StoryFn = args => { columns, }); - const { rows } = table; + const { rows } = table.getRowModel(); return ( {table.getHeaderGroups().map((headerGroup: HeaderGroup) => ( @@ -531,14 +527,14 @@ export const ExpandableContent: StoryFn = args => { columns, }); - const { rows } = table; + const { rows } = table.getRowModel(); return (
{table.getHeaderGroups().map((headerGroup: HeaderGroup) => ( @@ -634,13 +630,13 @@ export const SortableRows: StoryFn = args => { columns, }); - const { rows } = table; + const { rows } = table.getRowModel(); return (
{table.getHeaderGroups().map((headerGroup: HeaderGroup) => ( @@ -732,7 +728,7 @@ export const SelectableRows: StoryFn = args => { hasSelectableRows: true, }); - const { rows } = table; + const { rows } = table.getRowModel(); return (
@@ -762,7 +758,7 @@ export const SelectableRows: StoryFn = args => { {...args} table={table} ref={tableContainerRef} - data-total-rows={table.rows.length} + data-total-rows={table.getRowModel().rows.length} > {table.getHeaderGroups().map((headerGroup: HeaderGroup) => ( @@ -859,7 +855,7 @@ export const SelectableRowsNoSelectAll: StoryFn = args => { allowSelectAll: false, }); - const { rows } = table; + const { rows } = table.getRowModel(); return (
@@ -984,7 +980,7 @@ export const WithPagination: StoryFn = ({ withPagination: true, }); - const { rows } = table; + const { rows } = table.getRowModel(); return (
@@ -1130,7 +1126,7 @@ export const StyledComponents: StoryFn = args => { columns, }); - const { rows } = table; + const { rows } = table.getRowModel(); const StyledCell = styled(Cell)` color: grey; diff --git a/packages/table/src/Table/TableWithVS.stories.tsx b/packages/table/src/Table/TableWithVS.stories.tsx index 3b20f252df..66d2815698 100644 --- a/packages/table/src/Table/TableWithVS.stories.tsx +++ b/packages/table/src/Table/TableWithVS.stories.tsx @@ -115,7 +115,7 @@ export const Basic: StoryFn = args => { return ( <>
-

{table.rows.length} total rowsjsfjsh

+

{table.getRowModel().rows.length} total rows

{table?.virtual.getVirtualItems().length} virtual rows

{table?.virtual.getTotalSize()} virtual rows

@@ -185,7 +185,7 @@ export const NestedRows: StoryFn = args => { return ( <>
-

{table.rows.length} total rows

+

{table.getRowModel().rows.length} total rows

= args => { return ( <>
-

{table.rows.length} total rows

+

{table.getRowModel().rows.length} total rows

= args => { return ( <>
-

{table.rows.length} total rows

+

{table.getRowModel().rows.length} total rows

({ [columnsProp, hasSelectableRows, selectColumnConfig], ); + /** + * Custom getExpandedRowModel that manipulates rows to include expandedContent. + */ + function getLGExpandedRowModel>() { + return (table: Table) => { + const baseExpandedRowModel = getExpandedRowModel()(table); + + // Return a function that computes the custom RowModel + return () => { + // Get the default expanded row model by invoking baseExpandedRowModel + const rowModel = baseExpandedRowModel(); + const modifiedRows = [...rowModel.rows]; + + for (let i = 0; i < modifiedRows.length; i++) { + if ( + modifiedRows[i].original.renderExpandedContent && + modifiedRows[i].getIsExpanded() + ) { + const expandedData = { + ...modifiedRows[i], + id: `${modifiedRows[i].id}-expandedContent`, + isExpandedContent: true, + }; + modifiedRows.splice(i + 1, 0, expandedData); + i++; // Increment index to skip the newly added item + } + } + + return { + ...rowModel, + rows: modifiedRows, + } as RowModel; + }; + }; + } + const table = useReactTable>({ state: { expanded, @@ -71,35 +114,13 @@ function useLeafyGreenTable({ getSortedRowModel: getSortedRowModel(), getPaginationRowModel: withPagination ? getPaginationRowModel() : undefined, onExpandedChange: setExpanded, - getExpandedRowModel: getExpandedRowModel(), + getExpandedRowModel: getLGExpandedRowModel(), ...rest, }); - const { rows } = table.getRowModel(); - - const rowsCopy = [...rows]; - - // A way to include expandableContent inside of the rows object. - // If a row has expandedContent and its expanded then add a new row below the row - for (let i = 0; i < rowsCopy.length; i++) { - if ( - rowsCopy[i].original.renderExpandedContent && - rowsCopy[i].getIsExpanded() - ) { - rowsCopy.splice(i + 1, 0, { - ...rowsCopy[i], - id: `${rowsCopy[i].id}-expandedContent`, - // @ts-expect-error - unsure how to add this to the Row type. Row is typed as Row> which comes directly from useReactTable. - isExpandedContent: true, - }); - i++; // Increment index to skip the newly added item - } - } - return { ...table, hasSelectableRows, - rows: rowsCopy, } as LeafyGreenTable; } diff --git a/packages/table/src/useLeafyGreenTable/useLeafyGreenTable.types.ts b/packages/table/src/useLeafyGreenTable/useLeafyGreenTable.types.ts index be6bb55680..ecbc9a7ee0 100644 --- a/packages/table/src/useLeafyGreenTable/useLeafyGreenTable.types.ts +++ b/packages/table/src/useLeafyGreenTable/useLeafyGreenTable.types.ts @@ -17,10 +17,6 @@ export type LGTableDataType = T & { subRows?: Array>; }; -export type LGRow = Row> & { - isExpandedContent?: boolean; -}; - /** LeafyGreen extension of `useReactTable` {@link Cell}*/ export type LeafyGreenTableCell = Cell< LGTableDataType, @@ -29,7 +25,9 @@ export type LeafyGreenTableCell = Cell< /** LeafyGreen extension of `useReactTable` {@link Row}*/ export interface LeafyGreenTableRow - extends LGRow> {} + extends Row> { + isExpandedContent?: boolean; +} export type LGColumnDef< T extends LGRowData, @@ -77,10 +75,5 @@ export interface LeafyGreenTable * Whether the table will have selectable rows. */ hasSelectableRows: boolean; - - /** - * The rows that are returned from calling useLeafyGreenTable or useLeafyGreenVirtualTable - */ - rows: Array; virtual: never; } diff --git a/packages/table/src/useLeafyGreenVirtualTable/useLeafyGreenVirtualTable.tsx b/packages/table/src/useLeafyGreenVirtualTable/useLeafyGreenVirtualTable.tsx index 1f80765eb8..e4cb0b7b43 100644 --- a/packages/table/src/useLeafyGreenVirtualTable/useLeafyGreenVirtualTable.tsx +++ b/packages/table/src/useLeafyGreenVirtualTable/useLeafyGreenVirtualTable.tsx @@ -31,7 +31,7 @@ function useLeafyGreenVirtualTable< ...rest, }); - const { rows } = table; + const { rows } = table.getRowModel(); const _virtualizer = useVirtualizer({ count: rows.length, @@ -52,8 +52,6 @@ function useLeafyGreenVirtualTable< row: rows[virtualRow.index], })); - // const { getVirtualItems, ...virtualizerRest } = _virtualizer; - return { ...table, virtual: { ..._virtualizer, getVirtualItems: () => _virtualItems }, From 06ecf7d9ed52f8680641acbb1728cd867deb9391 Mon Sep 17 00:00:00 2001 From: Shaneeza Date: Tue, 12 Nov 2024 15:28:21 -0500 Subject: [PATCH 092/113] styledcomponent stuff, TS still not correct --- packages/table/src/Row/Row.tsx | 6 +-- packages/table/src/Table.stories.tsx | 50 +++++++++++-------- .../table/src/utils/makeData.testutils.tsx | 12 ++++- 3 files changed, 42 insertions(+), 26 deletions(-) diff --git a/packages/table/src/Row/Row.tsx b/packages/table/src/Row/Row.tsx index aa72e1ffa0..2d32fabfdf 100644 --- a/packages/table/src/Row/Row.tsx +++ b/packages/table/src/Row/Row.tsx @@ -53,9 +53,9 @@ const Row = ({ }; Row.propTypes = { - virtualRow: PropTypes.any, - row: PropTypes.any, - disabled: PropTypes.bool, + // virtualRow: PropTypes.any, + // row: PropTypes.any, + // disabled: PropTypes.bool, }; Row.displayName = 'Row'; diff --git a/packages/table/src/Table.stories.tsx b/packages/table/src/Table.stories.tsx index 33b5bf494c..1111eddf67 100644 --- a/packages/table/src/Table.stories.tsx +++ b/packages/table/src/Table.stories.tsx @@ -14,6 +14,7 @@ import IconButton from '@leafygreen-ui/icon-button'; import Pagination, { PaginationProps } from '@leafygreen-ui/pagination'; import { + KitchenSink, makeData, makeKitchenSinkData, Person, @@ -23,6 +24,7 @@ import { Cell, ExpandedContent, flexRender, + Header, HeaderCell, type HeaderGroup, HeaderRow, @@ -1059,7 +1061,7 @@ export const StyledComponents: StoryFn = args => { const tableContainerRef = React.useRef(null); const [data] = useState(() => makeKitchenSinkData(5)); - const columns = React.useMemo>>( + const columns = React.useMemo>>( () => [ { accessorKey: 'dateCreated', @@ -1121,7 +1123,7 @@ export const StyledComponents: StoryFn = args => { [], ); - const table = useLeafyGreenTable({ + const table = useLeafyGreenTable({ data, columns, }); @@ -1130,25 +1132,27 @@ export const StyledComponents: StoryFn = args => { const StyledCell = styled(Cell)` color: grey; - `; + ` as typeof Cell; + // FIXME: + // @ts-expect-error - proptypes error. The other components don't have proptypes but should have them const StyledRow = styled(Row)` background: snow; - `; + ` as typeof Row; const StyledHeaderRow = styled(HeaderRow)` background: whitesmoke; - `; + ` as typeof HeaderRow; const StyledHeaderCell = styled(HeaderCell)` color: black; - `; + ` as typeof HeaderCell; const StyledExpandedContent = styled(ExpandedContent)` td > div { background: whitesmoke; } - `; + ` as typeof ExpandedContent; return (
= args => { `} > - {table.getHeaderGroups().map((headerGroup: HeaderGroup) => ( - - {headerGroup.headers.map(header => { - return ( - - {flexRender( - header.column.columnDef.header, - header.getContext(), - )} - - ); - })} - - ))} + {table + .getHeaderGroups() + .map((headerGroup: HeaderGroup) => ( + + {headerGroup.headers.map(header => { + return ( + + {flexRender( + header.column.columnDef.header, + header.getContext(), + )} + + ); + })} + + ))} - {rows.map((row: LeafyGreenTableRow) => { + {rows.map((row: LeafyGreenTableRow) => { // const isExpandedContent = row.original.isExpandedContent ?? false; const isExpandedContent = row.isExpandedContent ?? false; return ( diff --git a/packages/table/src/utils/makeData.testutils.tsx b/packages/table/src/utils/makeData.testutils.tsx index f026010db3..fb09d6442a 100644 --- a/packages/table/src/utils/makeData.testutils.tsx +++ b/packages/table/src/utils/makeData.testutils.tsx @@ -97,7 +97,17 @@ const SampleExpandedContent = (row: LeafyGreenTableRow) => { ); }; -const createKitchenSinkData: (depth?: number) => object = (depth = 0) => { +export interface KitchenSink { + dateCreated: Date; + frequency: string; + clusterType: string; + encryptorEnabled: boolean; + mdbVersion: string; + subRows?: Array; + index?: number; +} + +const createKitchenSinkData: (depth?: number) => KitchenSink = (depth = 0) => { return { dateCreated: faker.date.past({ refDate: new Date('2023-12-26') }), frequency: faker.helpers.arrayElement(['Daily', 'Weekly', 'Monthly']), From bbf564202d8526c0498d9e850716a7203c4ee077 Mon Sep 17 00:00:00 2001 From: Shaneeza Date: Tue, 12 Nov 2024 15:53:56 -0500 Subject: [PATCH 093/113] callable virtual items --- packages/table/src/Row/Row.stories.tsx | 4 ++-- packages/table/src/Row/Row.tsx | 6 +++--- packages/table/src/Table.stories.tsx | 1 - .../useLeafyGreenVirtualTable.tsx | 7 +++---- 4 files changed, 8 insertions(+), 10 deletions(-) diff --git a/packages/table/src/Row/Row.stories.tsx b/packages/table/src/Row/Row.stories.tsx index ea33e669d9..4521c93cfe 100644 --- a/packages/table/src/Row/Row.stories.tsx +++ b/packages/table/src/Row/Row.stories.tsx @@ -173,7 +173,7 @@ export const DisabledNestedRows: StoryFn = ({ row, ...rest }) => { return ( <>
-

{table.rows.length} total rows

+

{table.getRowModel().rows.length} total rows

Expanded rows: {JSON.stringify(expanded, null, 2)}
@@ -327,7 +327,7 @@ export const DisabledSelectableRows: StoryFn< darkMode={darkMode} table={table} ref={tableContainerRef} - data-total-rows={table.rows.length} + data-total-rows={table.getRowModel().rows.length} > {table.getHeaderGroups().map((headerGroup: HeaderGroup) => ( diff --git a/packages/table/src/Row/Row.tsx b/packages/table/src/Row/Row.tsx index 2d32fabfdf..aa72e1ffa0 100644 --- a/packages/table/src/Row/Row.tsx +++ b/packages/table/src/Row/Row.tsx @@ -53,9 +53,9 @@ const Row = ({ }; Row.propTypes = { - // virtualRow: PropTypes.any, - // row: PropTypes.any, - // disabled: PropTypes.bool, + virtualRow: PropTypes.any, + row: PropTypes.any, + disabled: PropTypes.bool, }; Row.displayName = 'Row'; diff --git a/packages/table/src/Table.stories.tsx b/packages/table/src/Table.stories.tsx index 1111eddf67..37cccfc6f5 100644 --- a/packages/table/src/Table.stories.tsx +++ b/packages/table/src/Table.stories.tsx @@ -1183,7 +1183,6 @@ export const StyledComponents: StoryFn = args => { {rows.map((row: LeafyGreenTableRow) => { - // const isExpandedContent = row.original.isExpandedContent ?? false; const isExpandedContent = row.isExpandedContent ?? false; return ( diff --git a/packages/table/src/useLeafyGreenVirtualTable/useLeafyGreenVirtualTable.tsx b/packages/table/src/useLeafyGreenVirtualTable/useLeafyGreenVirtualTable.tsx index e4cb0b7b43..a40e44dd69 100644 --- a/packages/table/src/useLeafyGreenVirtualTable/useLeafyGreenVirtualTable.tsx +++ b/packages/table/src/useLeafyGreenVirtualTable/useLeafyGreenVirtualTable.tsx @@ -45,16 +45,15 @@ function useLeafyGreenVirtualTable< ...virtualizerOptions, }); - const _virtualItems: Array> = _virtualizer - .getVirtualItems() - .map((virtualRow: VirtualItem) => ({ + const _getVirtualItems = (): Array> => + _virtualizer.getVirtualItems().map((virtualRow: VirtualItem) => ({ ...virtualRow, row: rows[virtualRow.index], })); return { ...table, - virtual: { ..._virtualizer, getVirtualItems: () => _virtualItems }, + virtual: { ..._virtualizer, getVirtualItems: () => _getVirtualItems() }, } as LeafyGreenVirtualTable; } From 6d86ca3b0eeb6dbb7fe6466c9e47ecbadc497e0e Mon Sep 17 00:00:00 2001 From: Shaneeza Date: Tue, 12 Nov 2024 16:05:14 -0500 Subject: [PATCH 094/113] update ts docs --- .../src/useLeafyGreenTable/useLeafyGreenTable.tsx | 7 +------ .../useLeafyGreenVirtualTable.tsx | 10 ---------- .../useLeafyGreenVirtualTable.types.ts | 6 ++---- 3 files changed, 3 insertions(+), 20 deletions(-) diff --git a/packages/table/src/useLeafyGreenTable/useLeafyGreenTable.tsx b/packages/table/src/useLeafyGreenTable/useLeafyGreenTable.tsx index 2b44264381..1054cdaca6 100644 --- a/packages/table/src/useLeafyGreenTable/useLeafyGreenTable.tsx +++ b/packages/table/src/useLeafyGreenTable/useLeafyGreenTable.tsx @@ -2,7 +2,6 @@ import React, { useState } from 'react'; import { ExpandedState, getExpandedRowModel, - // RowData, RowModel, Table, useReactTable, @@ -16,11 +15,7 @@ import omit from 'lodash/omit'; import { TableHeaderCheckbox } from './TableHeaderCheckbox'; import { TableRowCheckbox } from './TableRowCheckbox'; -import { - LeafyGreenTableOptions, - // LGRow, - LGRowData, -} from './useLeafyGreenTable.types'; +import { LeafyGreenTableOptions, LGRowData } from './useLeafyGreenTable.types'; import { LeafyGreenTable, LGColumnDef, LGTableDataType } from '.'; const CHECKBOX_WIDTH = 40; diff --git a/packages/table/src/useLeafyGreenVirtualTable/useLeafyGreenVirtualTable.tsx b/packages/table/src/useLeafyGreenVirtualTable/useLeafyGreenVirtualTable.tsx index a40e44dd69..dcaf489dde 100644 --- a/packages/table/src/useLeafyGreenVirtualTable/useLeafyGreenVirtualTable.tsx +++ b/packages/table/src/useLeafyGreenVirtualTable/useLeafyGreenVirtualTable.tsx @@ -14,20 +14,10 @@ function useLeafyGreenVirtualTable< V extends unknown = unknown, >({ containerRef, - data, - columns, - hasSelectableRows, - withPagination = false, - allowSelectAll = true, virtualizerOptions, ...rest }: LeafyGreenVirtualTableOptions): LeafyGreenVirtualTable { const table = useLeafyGreenTable({ - data, - columns, - withPagination, - allowSelectAll, - hasSelectableRows, ...rest, }); diff --git a/packages/table/src/useLeafyGreenVirtualTable/useLeafyGreenVirtualTable.types.ts b/packages/table/src/useLeafyGreenVirtualTable/useLeafyGreenVirtualTable.types.ts index 9c9d3922e3..77e1f15961 100644 --- a/packages/table/src/useLeafyGreenVirtualTable/useLeafyGreenVirtualTable.types.ts +++ b/packages/table/src/useLeafyGreenVirtualTable/useLeafyGreenVirtualTable.types.ts @@ -13,9 +13,7 @@ import { } from '../useLeafyGreenTable'; /** - * Options argument for the LeafyGreen extension of `useReactTable` - * - * See: {@link TableOptions} + * Available [options](https://tanstack.com/table/latest/docs/guide/tables#creating-a-table-instance) to pass to the LeafyGreen extension of `useReactTable`. */ export interface LeafyGreenVirtualTableOptions< T extends LGRowData, @@ -27,7 +25,7 @@ export interface LeafyGreenVirtualTableOptions< containerRef: RefObject; /** - * A list of [options](https://tanstack.com/virtual/latest/docs/api/virtualizer) to pass to the virtualizer instance + * Available [options](https://tanstack.com/virtual/latest/docs/api/virtualizer) to pass to the virtualizer instance */ virtualizerOptions?: Partial>; } From 53792c097ff616875d00dd0716cf2094db0f334c Mon Sep 17 00:00:00 2001 From: Shaneeza Date: Tue, 12 Nov 2024 16:53:50 -0500 Subject: [PATCH 095/113] token --- packages/table/src/useLeafyGreenTable/useLeafyGreenTable.tsx | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/packages/table/src/useLeafyGreenTable/useLeafyGreenTable.tsx b/packages/table/src/useLeafyGreenTable/useLeafyGreenTable.tsx index 1054cdaca6..31d252bc8e 100644 --- a/packages/table/src/useLeafyGreenTable/useLeafyGreenTable.tsx +++ b/packages/table/src/useLeafyGreenTable/useLeafyGreenTable.tsx @@ -13,12 +13,14 @@ import { } from '@tanstack/react-table'; import omit from 'lodash/omit'; +import { spacing } from '@leafygreen-ui/tokens'; + import { TableHeaderCheckbox } from './TableHeaderCheckbox'; import { TableRowCheckbox } from './TableRowCheckbox'; import { LeafyGreenTableOptions, LGRowData } from './useLeafyGreenTable.types'; import { LeafyGreenTable, LGColumnDef, LGTableDataType } from '.'; -const CHECKBOX_WIDTH = 40; +const CHECKBOX_WIDTH = spacing[1000]; function useLeafyGreenTable({ data, From de6b74a49f18b8681a4d9cf3d9417a7df708e6ca Mon Sep 17 00:00:00 2001 From: Shaneeza Date: Tue, 12 Nov 2024 17:17:25 -0500 Subject: [PATCH 096/113] use classname --- packages/table/src/Table.stories.tsx | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/packages/table/src/Table.stories.tsx b/packages/table/src/Table.stories.tsx index 02926fe44f..37b8422a97 100644 --- a/packages/table/src/Table.stories.tsx +++ b/packages/table/src/Table.stories.tsx @@ -308,7 +308,11 @@ export const HundredsOfRows: StoryFn = args => { return (
-
+
= args => { })}
-
+
); }; From 407af031a261f1e325eff0599cb43996734b3a43 Mon Sep 17 00:00:00 2001 From: Shaneeza Date: Wed, 13 Nov 2024 13:06:52 -0500 Subject: [PATCH 097/113] move interaction test --- packages/table/package.json | 5 +- .../table/src/Table.Intereactions.stories.tsx | 195 +++++++++++ packages/table/src/Table.stories.tsx | 319 +++++++++--------- 3 files changed, 353 insertions(+), 166 deletions(-) create mode 100644 packages/table/src/Table.Intereactions.stories.tsx diff --git a/packages/table/package.json b/packages/table/package.json index 49c08b4439..ed469448cc 100644 --- a/packages/table/package.json +++ b/packages/table/package.json @@ -1,6 +1,6 @@ { "name": "@leafygreen-ui/table", - "version": "12.7.0-test.5", + "version": "12.7.0-test.9", "description": "leafyGreen UI Kit Table", "main": "./dist/index.js", "module": "./dist/esm/index.js", @@ -46,8 +46,7 @@ "@leafygreen-ui/button": "^21.2.0", "@leafygreen-ui/badge": "^8.1.2", "@leafygreen-ui/pagination": "^1.0.23", - "@lg-tools/storybook-utils": "^0.1.1", - "@emotion/styled": "^11.10.5" + "@lg-tools/storybook-utils": "^0.1.1" }, "peerDependencies": { "@leafygreen-ui/leafygreen-provider": "^3.1.12" diff --git a/packages/table/src/Table.Intereactions.stories.tsx b/packages/table/src/Table.Intereactions.stories.tsx new file mode 100644 index 0000000000..bc914156b1 --- /dev/null +++ b/packages/table/src/Table.Intereactions.stories.tsx @@ -0,0 +1,195 @@ +import React, { Fragment, useState } from 'react'; +import { + storybookExcludedControlParams, + StoryMetaType, +} from '@lg-tools/storybook-utils'; +import { expect } from '@storybook/jest'; +import { within } from '@storybook/testing-library'; + +import Badge from '@leafygreen-ui/badge'; +import { css } from '@leafygreen-ui/emotion'; +import Icon from '@leafygreen-ui/icon'; +import IconButton from '@leafygreen-ui/icon-button'; + +import { makeKitchenSinkData, Person } from './utils/makeData.testutils'; +import { + Cell, + ExpandedContent, + flexRender, + HeaderCell, + type HeaderGroup, + HeaderRow, + type LeafyGreenTableRow, + type LGColumnDef, + Row, + Table, + TableBody, + TableHead, + useLeafyGreenTable, +} from '.'; + +const meta: StoryMetaType = { + title: 'Components/Table/Interactions', + component: Table, + argTypes: { + shouldAlternateRowColor: { control: 'boolean' }, + }, + parameters: { + default: 'Template', + controls: { + exclude: [ + ...storybookExcludedControlParams, + 'table', + 'children', + 'value', + 'onSelectChange', + 'tableContainerClassName', + 'baseFontSize', + ], + }, + // This is needed as a workaround to make arg spreading performant + // https://github.com/storybookjs/storybook/issues/11657 + docs: { + source: { type: 'code' }, + }, + }, +}; +export default meta; + +const Template = () => { + const [data] = useState(() => makeKitchenSinkData(50)); + + const columns = React.useMemo>>( + () => [ + { + accessorKey: 'dateCreated', + header: 'Date Created', + enableSorting: true, + cell: info => + (info.getValue() as Date).toLocaleDateString('en-us', { + year: 'numeric', + month: 'short', + day: 'numeric', + }), + }, + { + accessorKey: 'frequency', + header: 'Frequency', + }, + { + accessorKey: 'clusterType', + header: 'Cluster Type', + }, + { + accessorKey: 'encryptorEnabled', + header: 'Encryptor', + // eslint-disable-next-line react/display-name + cell: info => ( + + {info.getValue() ? 'Enabled' : 'Not enabled'} + + ), + }, + { + accessorKey: 'mdbVersion', + header: 'MongoDB Version', + enableSorting: true, + size: 90, + }, + { + id: 'actions', + header: '', + size: 90, + // eslint-disable-next-line react/display-name + cell: _ => { + return ( + <> + + + + + + + + + + + ); + }, + }, + ], + [], + ); + + const table = useLeafyGreenTable({ + data, + columns, + }); + + const { rows } = table; + + return ( + <> + + + {table.getHeaderGroups().map((headerGroup: HeaderGroup) => ( + + {headerGroup.headers.map(header => { + return ( + + {flexRender( + header.column.columnDef.header, + header.getContext(), + )} + + ); + })} + + ))} + + + {rows.map((row: LeafyGreenTableRow) => { + const isExpandedContent = row.isExpandedContent ?? false; + + return ( + + {!isExpandedContent && ( + + {row.getVisibleCells().map(cell => { + return ( + + {flexRender( + cell.column.columnDef.cell, + cell.getContext(), + )} + + ); + })} + + )} + {isExpandedContent && } + + ); + })} + +
+ + ); +}; + +export const StickyHeader = { + render: () =>