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

LG-4146: Table refactor #2546

Draft
wants to merge 7 commits into
base: main
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 12 additions & 0 deletions packages/table/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,17 @@
# @leafygreen-ui/table

## 13.0.0-beta.1
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Add changeset files


### Patch Changes

- Add `react-keyed-flatten-children` to fix install error

## 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
Expand Down
9 changes: 4 additions & 5 deletions packages/table/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@leafygreen-ui/table",
"version": "12.7.0",
"version": "12.7.0-test.2",
"description": "leafyGreen UI Kit Table",
"main": "./dist/index.js",
"module": "./dist/esm/index.js",
Expand Down Expand Up @@ -33,12 +33,11 @@
"@leafygreen-ui/tokens": "^2.11.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-keyed-flatten-children": "^1.3.0",
"react-transition-group": "^4.4.5",
"react-virtual": "^2.10.4"
"react-fast-compare": "3.2.2"
},
"devDependencies": {
"@faker-js/faker": "^8.0.0",
Expand Down
4 changes: 2 additions & 2 deletions packages/table/src/Cell/Cell.spec.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,11 @@ import { Cell, CellProps } from '.';

const onScroll = jest.fn();

const defaultProps: CellProps = {
const defaultProps: CellProps<unknown> = {
onScroll,
};

function renderCell(props: CellProps) {
function renderCell(props: CellProps<unknown>) {
return render(
<table>
<tbody>
Expand Down
2 changes: 0 additions & 2 deletions packages/table/src/Cell/Cell.stories.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -20,11 +20,9 @@ const meta: StoryMetaType<typeof InternalCell> = {
generate: {
combineArgs: {
darkMode: [false, true],
depth: [0, 1],
align: ['left', 'center', 'right'],
},
args: {
cellIndex: 0,
children: 'Cell content',
},
decorator: (Instance, ctx) => {
Expand Down
107 changes: 43 additions & 64 deletions packages/table/src/Cell/Cell.styles.ts
Original file line number Diff line number Diff line change
@@ -1,37 +1,17 @@
import { TransitionStatus } from 'react-transition-group';

import { css } from '@leafygreen-ui/emotion';
import { spacing, transitionDuration, typeScales } from '@leafygreen-ui/tokens';
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;

/** 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};
`;

export const getCellPadding = ({
depth = 0,
isExpandable,
Expand All @@ -44,77 +24,76 @@ 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`
padding-left: ${baseTableSidePadding + depthPadding}px;
`;
};

export const basicCellStyles = css`
export const getCellStyles = (
depth = 0,
isExpandable = false,
isSelectable = false,
) => css`
&:first-child {
${getCellPadding({
depth: 0,
isExpandable: false,
isSelectable: false,
depth,
isExpandable,
isSelectable,
})}
}
`;

export const cellTransitionContainerStyles = css`
export const getCellContainerStyles = (align: Align = 'left') => css`
display: flex;
align-items: center;
min-height: ${standardCellHeight}px;
transition-property: min-height, max-height, opacity, padding, transform;
transition-duration: ${transitionDuration.default}ms;
transition-timing-function: ease;
overflow: hidden;
justify-content: ${align};
text-align: ${align};
`;

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 baseCellStyles = css`
padding: 0 ${spacing[200]}px;
overflow: hidden;
vertical-align: top;

&:focus-visible {
box-shadow: inset;
}

&:last-child {
padding-right: ${baseTableSidePadding}px;
}
`;

export const disableAnimationStyles = css`
transition-duration: 0;
transition: none;
export const cellInnerStyles = css`
display: flex;
align-items: center;
min-width: 100%;
`;

export const cellContentTransitionStateStyles = (
height?: number,
): Record<TransitionStatus, string> => {
const _hiddenStyles = css`
opacity: 0;
min-height: 0;
max-height: 0;
export const getCellEllipsisStyles = (shouldTruncate: boolean) => css`
${shouldTruncate &&
css`
flex: 1;
overflow: hidden;
`;

return {
entered: css`
opacity: 1;
min-height: ${standardCellHeight}px;
max-height: ${height ? height + 'px' : 'unset'};
`,
entering: _hiddenStyles,
exiting: _hiddenStyles,
exited: _hiddenStyles,
unmounted: _hiddenStyles,
};
};
white-space: nowrap;
text-overflow: ellipsis;
contain: inline-size; // 🤯
`}
`;
48 changes: 15 additions & 33 deletions packages/table/src/Cell/Cell.tsx
Original file line number Diff line number Diff line change
@@ -1,44 +1,26 @@
import React from 'react';

import { cx } from '@leafygreen-ui/emotion';
import { LGRowData } from '../useLeafyGreenTable';

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

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

const Cell = ({
className,
contentClassName,
align,
const Cell = <T extends LGRowData>({
children,
cell: reactTableCell,
...rest
}: CellProps) => {
const { disableAnimations } = useTableContext();
}: CellProps<T>) => {
return (
<td
data-lgid={LGIDS.cell}
className={cx(baseCellStyles, basicCellStyles, className)}
{...rest}
>
<div
className={cx(
cellTransitionContainerStyles,
alignmentStyles(align),
{ [disableAnimationStyles]: disableAnimations },
contentClassName,
)}
>
{children}
</div>
</td>
<>
{reactTableCell ? (
<InternalCellWithRT {...rest} cell={reactTableCell}>
{children}
</InternalCellWithRT>
) : (
<InternalCellWithoutRT {...rest}>{children}</InternalCellWithoutRT>
)}
</>
);
};

Expand Down
62 changes: 16 additions & 46 deletions packages/table/src/Cell/Cell.types.ts
Original file line number Diff line number Diff line change
@@ -1,19 +1,12 @@
import { HTMLElementProps } from '@leafygreen-ui/lib';

import { LeafyGreenTableCell, LGRowData } from '../useLeafyGreenTable';

export type Align = Extract<
HTMLElementProps<'td'>['align'],
'left' | 'right' | 'center'
>;

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
Expand All @@ -22,49 +15,26 @@ interface BaseCellProps extends HTMLElementProps<'td'> {
*/
align?: Align;

/** 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
* A `className` applied to the inner `div` of the Cell
*/
overflow?: CellOverflowBehavior;
contentClassName?: string;
}

export type CellProps = BaseCellProps;

export interface InternalCellProps extends BaseCellProps {
export interface CellProps<T extends LGRowData> extends BaseCellProps {
/**
* Index of the cell in its parent row.
* The cell object that is returned when mapping through a row passed from the `useLeafyGreenTable` or `useLeafyGreenVirtualTable` hook.
*/
cellIndex: number;
cell?: LeafyGreenTableCell<T>;
}

/**
* Depth of nesting its parent row has.
*/
depth: number;
export type InternalCellWithRTRequiredProps<T extends LGRowData> = Omit<
CellProps<T>,
'cell'
> &
Required<Pick<CellProps<T>, 'cell'>>;

/**
* Defines whether the cell's row is visible (i.e. expanded)
*
* @default true
*/
isVisible?: boolean;
export interface InternalCellProps extends BaseCellProps {}

/**
* Defines whether the cell's row is expandable
*
* @default false
*/
isExpandable?: boolean;
}
export interface InternalCellWithRTProps<T extends LGRowData>
extends InternalCellWithRTRequiredProps<T> {}
2 changes: 0 additions & 2 deletions packages/table/src/Cell/HeaderCell/HeaderCell.spec.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,6 @@ const TestSortableHeaderCell = () => {
const containerRef = useRef<HTMLDivElement>(null);

const table = useLeafyGreenTable({
containerRef,
columns: headerCellTestColumns,
data: headerCellTestData,
});
Expand Down Expand Up @@ -95,7 +94,6 @@ const useMockTestHeaderData = (
): Header<LGTableDataType<any>, unknown> => {
// eslint-disable-next-line react-hooks/rules-of-hooks
const table = useLeafyGreenTable({
containerRef: React.createRef<HTMLDivElement>(),
data: [],
columns: [columnDef],
});
Expand Down
Loading
Loading