Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Table] Updated hooks and internal restructuring [WIP] #2500

Draft
wants to merge 16 commits into
base: table-refactor-integration
Choose a base branch
from
3 changes: 2 additions & 1 deletion packages/table/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand Down
23 changes: 3 additions & 20 deletions packages/table/src/Cell/Cell.styles.ts
Original file line number Diff line number Diff line change
@@ -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';
Expand Down Expand Up @@ -72,11 +72,13 @@ export const basicCellStyles = css`
}
`;

//TODO: update this
export const cellTransitionContainerStyles = css`
display: flex;
align-items: center;
min-height: ${standardCellHeight}px;
overflow: hidden;
max-height: ${standardCellHeight}px;
`;

export const truncatedContentStyles = css`
Expand All @@ -91,22 +93,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,
});
};
53 changes: 34 additions & 19 deletions packages/table/src/Cell/Cell.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,42 +3,57 @@ import React from 'react';
import { cx } from '@leafygreen-ui/emotion';

import { LGIDS } from '../constants';
import { useTableContext } from '../TableContext';
import { useRowContext } from '../Row/RowContext';

import {
alignmentStyles,
baseCellStyles,
basicCellStyles,
cellTransitionContainerStyles,
disableAnimationStyles,
} from './Cell.styles';
import InternalCell from './InternalCell';
import { CellProps } from '.';

const Cell = ({
className,
contentClassName,
align,
children,
cell,
...rest
}: CellProps) => {
const { disableAnimations } = useTableContext();
const { isReactTable } = useRowContext();
return (
<td
data-lgid={LGIDS.cell}
className={cx(baseCellStyles, basicCellStyles, className)}
{...rest}
>
<div
className={cx(
cellTransitionContainerStyles,
alignmentStyles(align),
{ [disableAnimationStyles]: disableAnimations },
contentClassName,
)}
>
{children}
</div>
</td>
<>
{!isReactTable && (
<td
data-lgid={LGIDS.cell}
className={cx(baseCellStyles, basicCellStyles, className)}
{...rest}
>
<div
className={cx(
cellTransitionContainerStyles,
alignmentStyles(align),
contentClassName,
)}
>
{children}
</div>
</td>
)}

{isReactTable && (
<InternalCell
{...rest}
cell={cell}
className={className}
contentClassName={contentClassName}
>
{children}
</InternalCell>
)}
</>
);
};

Expand Down
11 changes: 8 additions & 3 deletions packages/table/src/Cell/Cell.types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -39,20 +39,25 @@ interface BaseCellProps extends HTMLElementProps<'td'> {
* @default CellOverflowBehavior.Default
*/
overflow?: CellOverflowBehavior;

cell?: any; //FIXME:
}

export type CellProps = BaseCellProps;

export interface InternalCellProps extends BaseCellProps {
export type InternalCellRequiredProps = Omit<BaseCellProps, 'cell'> &
Required<Pick<BaseCellProps, 'cell'>>;

export interface InternalCellProps extends InternalCellRequiredProps {
/**
* 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)
Expand Down
8 changes: 8 additions & 0 deletions packages/table/src/Cell/HeaderCell/HeaderCell.styles.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,18 @@
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;
`;

export const getHeaderCellWidthStyles = (size: number) => css`
width: ${size}px;
`;

export const getCellPaddingStyles = (isSelectable?: boolean) => css`
&:first-of-type {
${getCellPadding({ depth: 0, isExpandable: false, isSelectable })}
}
`;
10 changes: 3 additions & 7 deletions packages/table/src/Cell/HeaderCell/HeaderCell.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,11 +9,11 @@ import {
alignmentStyles,
baseCellStyles,
cellTransitionContainerStyles,
getCellPadding,
} from '../Cell.styles';

import SortIcon from './SortIcon/SortIcon';
import {
getCellPaddingStyles,
getHeaderCellWidthStyles,
headerCellContentStyles,
} from './HeaderCell.styles';
Expand All @@ -35,10 +35,7 @@ const HeaderCell = <T extends LGRowData>({
header,
...rest
}: PropsWithChildren<HeaderCellProps<T>>) => {
const { table } = useTableContext();

const isFirstCell = cellIndex === 0;
const isSelectable = !!table && !!table.hasSelectableRows;
const { isSelectable } = useTableContext();

let columnName, sortState, onSortIconClick;

Expand All @@ -54,9 +51,8 @@ const HeaderCell = <T extends LGRowData>({
data-lgid={LGIDS.header}
className={cx(
baseCellStyles,
getCellPaddingStyles(isSelectable),
{
[getCellPadding({ depth: 0, isExpandable: false, isSelectable })]:
isFirstCell,
[getHeaderCellWidthStyles(header?.getSize() ?? 0)]:
!!header?.getSize(),
},
Expand Down
36 changes: 20 additions & 16 deletions packages/table/src/Cell/InternalCell.tsx
Original file line number Diff line number Diff line change
@@ -1,15 +1,15 @@
import React, { useMemo, useRef } from 'react';
import PropTypes from 'prop-types';

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,
baseCellStyles,
cellContentTransitionStateStyles,
cellTransitionContainerStyles,
getCellPadding,
standardCellHeight,
Expand All @@ -21,17 +21,20 @@ const InternalCell = ({
children,
className,
contentClassName,
cellIndex,
depth,
isVisible = true,
isExpandable = false,
overflow,
align,
cell,
...rest
}: InternalCellProps) => {
const isFirstCell = cellIndex === 0;
const { table } = useTableContext();
const isSelectable = !!table && !!table.hasSelectableRows;
const { disabled } = useRowContext();
// TODO: log warning if cell is not passed to Cell
const { isSelectable } = 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();
const contentRef = useRef<HTMLDivElement>(null);

const contentHeight = standardCellHeight;
Expand All @@ -43,6 +46,7 @@ const InternalCell = ({
overflow === CellOverflowBehavior.Truncate && scrollHeight > contentHeight
);
}, [contentHeight, overflow, scrollHeight]);

return (
<td
data-lgid={LGIDS.cell}
Expand All @@ -59,26 +63,26 @@ const InternalCell = ({
ref={contentRef}
className={cx(
cellTransitionContainerStyles,
cellContentTransitionStateStyles(contentHeight, isVisible), // TODO: remove this
alignmentStyles(align),
{
[truncatedContentStyles]: shouldTruncate,
},
contentClassName,
)}
>
{isFirstCell && isExpandable && (
<ToggleExpandedIcon
isExpanded={isExpanded}
toggleExpanded={toggleExpanded}
disabled={disabled}
/>
)}
{children}
</div>
</td>
);
};

InternalCell.displayName = 'Cell';
InternalCell.propTypes = {
cellIndex: PropTypes.number,
depth: PropTypes.number,
isVisible: PropTypes.bool,
isExpandable: PropTypes.bool,
};

export default InternalCell;
Original file line number Diff line number Diff line change
Expand Up @@ -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<Theme, string> = {
Expand Down
39 changes: 18 additions & 21 deletions packages/table/src/ExpandedContent/ExpandedContent.tsx
Original file line number Diff line number Diff line change
@@ -1,18 +1,13 @@
import React, { useMemo, useRef } from 'react';
import React, { useRef } from 'react';
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';
import { getAreAncestorsExpanded } from '../utils/areAncestorsExpanded';

import { baseStyles, expandedContentStyles } from './ExpandedContent.styles';
import { ExpandedContentProps } from './ExpandedContent.types';
Expand All @@ -21,27 +16,31 @@ const ExpandedContent = <T extends RowData>({
row,
...rest
}: ExpandedContentProps<T>) => {
const { disableAnimations, getParentRow } = useTableContext();
const { measureElement } = useTableContext();
const contentRef = useRef<HTMLDivElement>(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 (
<InternalRowBase {...rest} aria-hidden={!isExpanded}>
<InternalRowBase
{...rest}
ref={node => {
// TODO: fix me
// This gets the dynamic size of the element
if (measureElement) measureElement(node);
}}
>
<td
colSpan={row.getVisibleCells().length}
className={cx(baseStyles)}
Expand All @@ -50,9 +49,7 @@ const ExpandedContent = <T extends RowData>({
<div
className={cx(
cellTransitionContainerStyles,
{ [disableAnimationStyles]: disableAnimations },
expandedContentStyles[theme],
cellContentTransitionStateStyles(contentHeight, isExpanded), // TODO: remove this
)}
>
<div ref={contentRef}>{content}</div>
Expand Down
Loading
Loading