diff --git a/packages/table/src/Cell/Cell.styles.ts b/packages/table/src/Cell/Cell.styles.ts index 5726a6825d..f4b3b5e12b 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,12 @@ 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; + vertical-align: ${verticalAlignment}; &:focus-visible { box-shadow: inset; @@ -87,13 +91,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` + 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 deleted file mode 100644 index 3cb1876024..0000000000 --- a/packages/table/src/Cell/InternalCell.tsx +++ /dev/null @@ -1,36 +0,0 @@ -import React from 'react'; - -import { cx } from '@leafygreen-ui/emotion'; - -import { LGIDS } from '../constants'; - -import { - baseCellStyles, - cellInnerStyles, - getCellContainerStyles, -} from './Cell.styles'; -import { InternalCellProps } from './Cell.types'; - -const InternalCell = ({ - children, - className, - contentClassName, - align, - ...rest -}: InternalCellProps) => { - return ( - -
-
{children}
-
- - ); -}; - -InternalCell.displayName = 'InternalCell'; - -export default InternalCell; diff --git a/packages/table/src/Cell/InternalCellBase.tsx b/packages/table/src/Cell/InternalCellBase.tsx index 2d3a5462fd..fe73019a08 100644 --- a/packages/table/src/Cell/InternalCellBase.tsx +++ b/packages/table/src/Cell/InternalCellBase.tsx @@ -3,10 +3,11 @@ import React, { forwardRef } 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'; @@ -25,10 +26,11 @@ const InternalCellBase = forwardRef( }: InternalCellProps, fwdRref, ) => { + const { verticalAlignment } = useTableContext(); return ( diff --git a/packages/table/src/Row/Row.stories.tsx b/packages/table/src/Row/Row.stories.tsx index 4521c93cfe..86bd28d032 100644 --- a/packages/table/src/Row/Row.stories.tsx +++ b/packages/table/src/Row/Row.stories.tsx @@ -10,6 +10,7 @@ import { import { StoryFn } from '@storybook/react'; import Button from '@leafygreen-ui/button'; +import { css } from '@leafygreen-ui/emotion'; import LeafyGreenProvider from '@leafygreen-ui/leafygreen-provider'; import { DarkModeProps } from '@leafygreen-ui/lib'; @@ -33,21 +34,22 @@ import { RowProps, } from '..'; -// TODO: UPDATE ME - const meta: StoryMetaType = { title: 'Components/Table/Row', component: Row, argTypes: { - virtualRow: { control: 'none' }, - row: { control: 'none' }, - className: { control: 'none' }, disabled: { control: 'boolean' }, }, parameters: { default: null, controls: { - exclude: [...storybookExcludedControlParams, 'ref', 'children'], + exclude: [ + ...storybookExcludedControlParams, + 'ref', + 'children', + 'row', + 'virtualRow', + ], }, chromatic: { disableSnapshot: true, @@ -61,18 +63,45 @@ const meta: StoryMetaType = { combineArgs: { darkMode: [false, true], disabled: [false, true], + // @ts-ignore - this is a table prop + shouldTruncate: [false, true], + verticalAlignment: ['top', 'center'], }, - args: { - children: makeData(false, 1).map(rowData => - Object.values(rowData).map(c => {c}), - ), - }, + excludeCombinations: [ + { + // @ts-ignore - this is a table prop + shouldTruncate: true, + verticalAlignment: 'center', + }, + ], decorator: (Instance, ctx) => { return ( - +
- + + + 1 + + + Est mollitia laborum dolores dolorem corporis explicabo + nobis enim omnis. Minima excepturi accusantium iure culpa. + + MongoDB + 7.85 + Complicated +
@@ -242,7 +271,6 @@ DisabledClickableRows.args = { export const DisabledSelectableRows: StoryFn< RowProps & DarkModeProps > = ({ darkMode, ...args }: DarkModeProps & RowProps) => { - const tableContainerRef = React.useRef(null); const data = React.useState(() => makeData(false, 100))[0]; const [rowSelection, setRowSelection] = React.useState({}); @@ -326,7 +354,6 @@ export const DisabledSelectableRows: StoryFn< @@ -371,4 +398,8 @@ DisabledSelectableRows.argTypes = { darkMode: storybookArgTypes.darkMode, }; +DisabledSelectableRows.args = { + disabled: true, +}; + export const Generated = () => <>; diff --git a/packages/table/src/Table.stories.tsx b/packages/table/src/Table.stories.tsx index fac1b74489..997397a4f1 100644 --- a/packages/table/src/Table.stories.tsx +++ b/packages/table/src/Table.stories.tsx @@ -12,6 +12,7 @@ import Icon from '@leafygreen-ui/icon'; import IconButton from '@leafygreen-ui/icon-button'; import Pagination, { PaginationProps } from '@leafygreen-ui/pagination'; +import { VerticalAlignment } from './Table/Table.types'; import { makeData, makeKitchenSinkData, @@ -42,7 +43,18 @@ const meta: StoryMetaType = { title: 'Components/Table', component: Table, argTypes: { - shouldAlternateRowColor: { control: 'boolean' }, + shouldAlternateRowColor: { control: 'boolean', defaultValue: false }, + shouldTruncate: { control: 'boolean', defaultValue: true }, + verticalAlignment: { + control: { type: 'radio' }, + options: VerticalAlignment, + defaultValue: VerticalAlignment.Top, + }, + }, + args: { + verticalAlignment: VerticalAlignment.Top, + shouldTruncate: true, + shouldAlternateRowColor: false, }, parameters: { default: 'LiveExample', @@ -220,12 +232,6 @@ export const LiveExample: StoryFn = args => { ); }; -LiveExample.argTypes = { - shouldAlternateRowColor: { - control: 'none', - }, -}; - export const HundredsOfRows: StoryFn = args => { const tableContainerRef = React.useRef(null); const [data] = useState(() => makeKitchenSinkData(500)); @@ -353,18 +359,17 @@ export const HundredsOfRows: StoryFn = args => { ); }; -HundredsOfRows.argTypes = { - shouldAlternateRowColor: { - control: 'none', - }, -}; - HundredsOfRows.parameters = { chromatic: { disableSnapshots: true, }, }; +export const NoTruncation = LiveExample.bind({}); +NoTruncation.args = { + shouldTruncate: false, +}; + export const Basic = Template.bind({}); export const ZebraStripes = Template.bind({}); diff --git a/packages/table/src/Table/Table.tsx b/packages/table/src/Table/Table.tsx index c19ad1bf90..50cebfa6dc 100644 --- a/packages/table/src/Table/Table.tsx +++ b/packages/table/src/Table/Table.tsx @@ -17,19 +17,20 @@ import { getTableStyles, tableClassName, } from './Table.styles'; -import { TableProps } from './Table.types'; +import { TableProps, VerticalAlignment } from './Table.types'; // Inferred generic type from component gets used in place of `any` const Table = forwardRef>( ( { + table, children, className, + verticalAlignment = VerticalAlignment.Top, shouldAlternateRowColor = false, shouldTruncate = true, baseFontSize: baseFontSizeProp, darkMode: darkModeProp, - table, 'data-lgid': lgidProp = LGIDS.root, ...rest }: TableProps, @@ -67,6 +68,7 @@ const Table = forwardRef>( isSelectable={isSelectable} shouldTruncate={shouldTruncate} virtualTable={virtualTable} + verticalAlignment={verticalAlignment} >
extends HTMLElementProps<'table'>, DarkModeProps, @@ -30,4 +38,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/Table/TableWithVS.stories.tsx b/packages/table/src/Table/TableWithVS.stories.tsx index 66d2815698..f3dc429bf0 100644 --- a/packages/table/src/Table/TableWithVS.stories.tsx +++ b/packages/table/src/Table/TableWithVS.stories.tsx @@ -1,6 +1,10 @@ import React, { Fragment, useCallback, useMemo, useState } from 'react'; import { faker } from '@faker-js/faker'; -import { storybookArgTypes, StoryMetaType } from '@lg-tools/storybook-utils'; +import { + storybookArgTypes, + storybookExcludedControlParams, + StoryMetaType, +} from '@lg-tools/storybook-utils'; import { StoryFn } from '@storybook/react'; import Badge from '@leafygreen-ui/badge'; @@ -34,6 +38,8 @@ import { useLeafyGreenVirtualTable, } from '..'; +import { VerticalAlignment } from './Table.types'; + type StoryTableProps = TableProps; const meta: StoryMetaType = { @@ -43,12 +49,27 @@ const meta: StoryMetaType = { children: { control: 'none' }, darkMode: storybookArgTypes.darkMode, ref: { control: 'none' }, + shouldAlternateRowColor: { control: 'boolean', defaultValue: false }, + shouldTruncate: { control: 'boolean', defaultValue: true }, + verticalAlignment: { + control: { type: 'radio' }, + options: VerticalAlignment, + defaultValue: VerticalAlignment.Top, + }, + }, + args: { + verticalAlignment: VerticalAlignment.Top, + shouldTruncate: true, + shouldAlternateRowColor: false, }, parameters: { default: 'Basic', chromatic: { disableSnapshot: true, }, + controls: { + exclude: [...storybookExcludedControlParams, 'children'], + }, docs: { source: { type: 'code' }, }, @@ -58,7 +79,6 @@ export default meta; const virtualScrollingContainerHeight = css` max-height: calc(100vh - 200px); - /* height: calc(100vh - 200px); */ `; const basicColumnDefs: Array> = [ @@ -599,7 +619,7 @@ export const TallRows: StoryFn = args => { ); }; -export const DifferentHeights: StoryFn = args => { +export const WithLeafyGreenComponents: StoryFn = args => { const tableContainerRef = React.useRef(null); const [data] = useState(() => makeKitchenSinkData(10_000)); @@ -647,14 +667,7 @@ export const DifferentHeights: StoryFn = args => { // eslint-disable-next-line react/display-name cell: _ => { return ( -
+
@@ -690,7 +703,6 @@ export const DifferentHeights: StoryFn = args => { table={table} ref={tableContainerRef} className={virtualScrollingContainerHeight} - shouldTruncate={false} > {table.getHeaderGroups().map((headerGroup: HeaderGroup) => ( @@ -751,3 +763,8 @@ export const DifferentHeights: StoryFn = args => { ); }; + +export const NoTruncation = WithLeafyGreenComponents.bind({}); +NoTruncation.args = { + shouldTruncate: false, +}; diff --git a/packages/table/src/TableContext/TableContext.tsx b/packages/table/src/TableContext/TableContext.tsx index 4a6af05f40..53d3eee171 100644 --- a/packages/table/src/TableContext/TableContext.tsx +++ b/packages/table/src/TableContext/TableContext.tsx @@ -28,6 +28,7 @@ const TableContextProvider = ({ isSelectable, shouldTruncate, virtualTable, + verticalAlignment, }: PropsWithChildren>>) => { /** The appropriately typed context provider */ const TableProvider = (TableContext as React.Context>) @@ -40,6 +41,7 @@ const TableContextProvider = ({ isVirtual, isSelectable, shouldTruncate, + verticalAlignment, virtualTable, }; }, [ @@ -48,6 +50,7 @@ const TableContextProvider = ({ isVirtual, isSelectable, shouldTruncate, + verticalAlignment, virtualTable, ]); diff --git a/packages/table/src/TableContext/TableContext.types.ts b/packages/table/src/TableContext/TableContext.types.ts index 9a412bb57d..d6905a0f00 100644 --- a/packages/table/src/TableContext/TableContext.types.ts +++ b/packages/table/src/TableContext/TableContext.types.ts @@ -25,7 +25,7 @@ interface BaseTableContextValue { type PartialTableProps = Pick< TableProps, - 'shouldAlternateRowColor' | 'shouldTruncate' + 'shouldAlternateRowColor' | 'shouldTruncate' | 'verticalAlignment' >; export type TableProviderProps = PropsWithChildren<