From 99030998cba981215a56ce260c588385f78b398a Mon Sep 17 00:00:00 2001 From: cassie spain <58054751+dreamwasp@users.noreply.github.com> Date: Wed, 29 Jan 2025 11:44:47 -0500 Subject: [PATCH] fix: DataGrid reformatted to `table` and aria-sort added Refactors the DataTable + DataList components to properly be semantic HTML tables and adds `aria-sort` to the appropriate controls --- .../__snapshots__/gamut.test.ts.snap | 2 +- .../src/DataList/Controls/FilterControl.tsx | 1 - .../src/DataList/Controls/SortControl.tsx | 7 ++ packages/gamut/src/DataList/DataGrid.tsx | 5 +- packages/gamut/src/DataList/EmptyRows.tsx | 43 +++++----- .../Rows/TableHeaderRow.tsx} | 28 +++---- .../Row.tsx => Tables/Rows/TableRow.tsx} | 82 ++++++++++++------- packages/gamut/src/List/List.tsx | 76 ++++++++++------- packages/gamut/src/List/ListCol.tsx | 18 ++-- packages/gamut/src/List/ListHeader.tsx | 25 ------ packages/gamut/src/List/ListProvider.tsx | 6 +- packages/gamut/src/List/ListRow.tsx | 52 +++++++++--- packages/gamut/src/List/TableHeader.tsx | 28 +++++++ packages/gamut/src/List/elements.tsx | 49 +++++++---- packages/gamut/src/List/index.tsx | 2 +- packages/gamut/src/List/types.ts | 4 +- packages/gamut/src/List/utils.tsx | 10 +++ .../DataList/DataList.stories.tsx | 18 ++-- .../DataTable/DataTable.stories.tsx | 21 +++-- 19 files changed, 295 insertions(+), 182 deletions(-) rename packages/gamut/src/DataList/{Rows/HeaderRow.tsx => Tables/Rows/TableHeaderRow.tsx} (80%) rename packages/gamut/src/DataList/{Rows/Row.tsx => Tables/Rows/TableRow.tsx} (57%) delete mode 100644 packages/gamut/src/List/ListHeader.tsx create mode 100644 packages/gamut/src/List/TableHeader.tsx create mode 100644 packages/gamut/src/List/utils.tsx diff --git a/packages/gamut/__tests__/__snapshots__/gamut.test.ts.snap b/packages/gamut/__tests__/__snapshots__/gamut.test.ts.snap index 21c0132482..7e999fd87d 100644 --- a/packages/gamut/__tests__/__snapshots__/gamut.test.ts.snap +++ b/packages/gamut/__tests__/__snapshots__/gamut.test.ts.snap @@ -63,7 +63,6 @@ exports[`Gamut Exported Keys 1`] = ` "LayoutGrid", "List", "ListCol", - "ListHeader", "ListRow", "Logo", "LogoDefault", @@ -99,6 +98,7 @@ exports[`Gamut Exported Keys 1`] = ` "submitSuccessStatus", "Tab", "TabButton", + "TableHeader", "TabList", "TabNav", "TabNavLink", diff --git a/packages/gamut/src/DataList/Controls/FilterControl.tsx b/packages/gamut/src/DataList/Controls/FilterControl.tsx index 85ae96d564..a30fbc5f5b 100644 --- a/packages/gamut/src/DataList/Controls/FilterControl.tsx +++ b/packages/gamut/src/DataList/Controls/FilterControl.tsx @@ -64,7 +64,6 @@ export const FilterControl: React.FC = ({ {menuOpen && ( = ({ return ( onSort?.({ diff --git a/packages/gamut/src/DataList/DataGrid.tsx b/packages/gamut/src/DataList/DataGrid.tsx index 305678143a..0904768fbf 100644 --- a/packages/gamut/src/DataList/DataGrid.tsx +++ b/packages/gamut/src/DataList/DataGrid.tsx @@ -4,8 +4,8 @@ import { List } from '../List'; import { EmptyRows } from './EmptyRows'; import { ListControlContext, useListControls } from './hooks/useListControls'; import { ListStateContext } from './hooks/useListState'; -import { HeaderRow } from './Rows/HeaderRow'; -import { DataRow, MarshaledColProps } from './Rows/Row'; +import { HeaderRow } from './Tables/Rows/TableHeaderRow'; +import { DataRow, MarshaledColProps } from './Tables/Rows/TableRow'; import { ColumnConfig, DataListControls, IdentifiableKeys } from './types'; export interface DataGridProps< @@ -97,6 +97,7 @@ export function DataGrid< } header={ header ? ( diff --git a/packages/gamut/src/DataList/EmptyRows.tsx b/packages/gamut/src/DataList/EmptyRows.tsx index c93f6da2da..3684664b57 100644 --- a/packages/gamut/src/DataList/EmptyRows.tsx +++ b/packages/gamut/src/DataList/EmptyRows.tsx @@ -1,5 +1,3 @@ -import { DotLoose } from '@codecademy/gamut-patterns'; - import { FlexBox } from '../Box'; import { FillButton } from '../Button'; import { Text } from '../Typography'; @@ -9,26 +7,27 @@ export const EmptyRows = () => { const { onResetQuery } = useControlContext(); return ( - <> - - No Results Found - Remove filters to view - Reset Filters - - - + + + + No Results Found + + + Remove filters to view + + + Reset Filters + - + ); }; diff --git a/packages/gamut/src/DataList/Rows/HeaderRow.tsx b/packages/gamut/src/DataList/Tables/Rows/TableHeaderRow.tsx similarity index 80% rename from packages/gamut/src/DataList/Rows/HeaderRow.tsx rename to packages/gamut/src/DataList/Tables/Rows/TableHeaderRow.tsx index cd72074e67..34e6ebf9a6 100644 --- a/packages/gamut/src/DataList/Rows/HeaderRow.tsx +++ b/packages/gamut/src/DataList/Tables/Rows/TableHeaderRow.tsx @@ -1,15 +1,15 @@ import { memo, ReactElement } from 'react'; -import { FlexBox } from '../..'; -import { ListCol, ListHeader } from '../../List'; +import { FlexBox } from '../../..'; +import { ListCol, TableHeader } from '../../../List'; import { ExpandControl, FilterControl, SelectControl, SortControl, -} from '../Controls'; -import { useControlContext } from '../hooks/useListControls'; -import { ColumnConfig, Query } from '../types'; +} from '../../Controls'; +import { useControlContext } from '../../hooks/useListControls'; +import { ColumnConfig, Query } from '../../types'; interface HeaderComponent { (props: { @@ -21,23 +21,17 @@ interface HeaderComponent { }): ReactElement; } -export const Header: HeaderComponent = ({ +export const TableHeaderRow: HeaderComponent = ({ columns, selected = false, empty = false, hideSelectAll, }) => { - const { - expandable, - selectable, - onSelect, - onFilter, - onSort, - prefixId, - } = useControlContext(); + const { expandable, selectable, onSelect, onFilter, onSort, prefixId } = + useControlContext(); return ( - + <> {selectable && ( @@ -86,8 +80,8 @@ export const Header: HeaderComponent = ({ )} - + ); }; -export const HeaderRow = memo(Header) as HeaderComponent; +export const HeaderRow = memo(TableHeaderRow) as HeaderComponent; diff --git a/packages/gamut/src/DataList/Rows/Row.tsx b/packages/gamut/src/DataList/Tables/Rows/TableRow.tsx similarity index 57% rename from packages/gamut/src/DataList/Rows/Row.tsx rename to packages/gamut/src/DataList/Tables/Rows/TableRow.tsx index 856f69b83b..38784942c4 100644 --- a/packages/gamut/src/DataList/Rows/Row.tsx +++ b/packages/gamut/src/DataList/Tables/Rows/TableRow.tsx @@ -1,12 +1,18 @@ -import { memo, ReactElement, ReactNode, useCallback } from 'react'; +import { + isValidElement, + memo, + ReactElement, + useCallback, + useMemo, +} from 'react'; -import { Text } from '../..'; -import { ListCol, ListRow } from '../../List'; -import { ColProps } from '../../List/elements'; -import { Shimmer } from '../../Loading/Shimmer'; -import { ExpandControl, SelectControl } from '../Controls'; -import { useControlContext } from '../hooks/useListControls'; -import { ColumnConfig, IdentifiableKeys } from '../types'; +import { Text } from '../../..'; +import { ListCol, ListRow } from '../../../List'; +import { ColProps } from '../../../List/elements'; +import { Shimmer } from '../../../Loading/Shimmer'; +import { ExpandControl, SelectControl } from '../../Controls'; +import { useControlContext } from '../../hooks/useListControls'; +import { ColumnConfig, IdentifiableKeys } from '../../types'; export type MarshaledColProps = Partial>; @@ -23,7 +29,7 @@ interface DataRow { ): ReactElement; } -export const Row: DataRow = ({ +export const TableRow: DataRow = ({ id, columns, row, @@ -50,8 +56,24 @@ export const Row: DataRow = ({ }); }, [onExpand, expandedContent, id, row]); + const numberOfColumns = useMemo(() => { + return columns.length; + }, [columns]); + + const listRowProps = expandable + ? { + expanded, + renderExpanded: renderExpandedContent, + } + : {}; + return ( - + {selectable && ( )} {columns.map(({ key, render, size, justify, fill, type }) => { + const newKey = prefixId(`${id}-col-${String(key)}`); const colProps = { ...listColProps, size, justify, fill, type, - key: prefixId(`${id}-col-${String(key)}`), }; if (loading) { return ( - + - <> - {render ? ( - render(row) - ) : typeof row[key] === 'string' ? ( - - {row[key] as ReactNode} - - ) : ( - row[key] - )} - + + {render ? ( + render(row) + ) : typeof row[key] === 'string' || typeof row[key] === 'number' ? ( + + {row[key] as string} + + ) : isValidElement(row[key]) ? ( + (row[key] as ReactElement) + ) : !row[key] ? ( + '' + ) : ( + 'Invalid data type' + )} ); })} @@ -125,4 +149,4 @@ export const Row: DataRow = ({ ); }; -export const DataRow = memo(Row) as DataRow; +export const DataRow = memo(TableRow) as DataRow; diff --git a/packages/gamut/src/List/List.tsx b/packages/gamut/src/List/List.tsx index 42353ef9cd..ec822f12d4 100644 --- a/packages/gamut/src/List/List.tsx +++ b/packages/gamut/src/List/List.tsx @@ -1,15 +1,16 @@ +import { DotLoose } from '@codecademy/gamut-patterns'; import isArray from 'lodash/isArray'; import { ComponentProps, forwardRef, useEffect, useRef, useState } from 'react'; import * as React from 'react'; -import { Box, BoxProps } from '../Box'; -import { ListEl } from './elements'; +import { Box, BoxProps, FlexBox } from '../Box'; +import { ListEl, ListWrapper } from './elements'; import { ListProvider, useList } from './ListProvider'; import { AllListProps } from './types'; export interface ListProps extends AllListProps> { - /** Whether List should be an ol or ul element */ - as?: 'ol' | 'ul'; + /** Whether List should be an ol, ul element, or table */ + as?: 'ol' | 'ul' | 'table'; /** Whether a placeholder width should be set when loading */ loading?: boolean; /** Should only be used internally to Gamut */ @@ -58,45 +59,61 @@ export const List = forwardRef( const [isEnd, setIsEnd] = useState(false); const showShadow = shadow && scrollable && !isEnd; const value = useList({ - isOl: as === 'ol', + listType: as, rowBreakpoint, scrollable, spacing, variant, }); - const topOfTable = useRef(null); + const wrapperRef = useRef(null); + const tableRef = useRef(null); useEffect(() => { - if (scrollToTopOnUpdate && topOfTable.current !== null) { - topOfTable.current.scrollTo({ top: 0 }); + const wrapperWidth = + wrapperRef?.current?.getBoundingClientRect()?.width ?? 0; + const tableWidth = tableRef?.current?.getBoundingClientRect().width ?? 0; + + setIsEnd(tableWidth < wrapperWidth); + }, []); + + const isTable = as === 'table'; + useEffect(() => { + if (scrollToTopOnUpdate && tableRef.current !== null) { + tableRef.current.scrollTo({ top: 0 }); } }); const listContent = ( - + {children} ); const scrollHandler = (event: React.UIEvent) => { const { offsetWidth, scrollLeft, scrollWidth } = event.currentTarget; - setIsEnd(offsetWidth + scrollLeft >= scrollWidth); + setIsEnd(offsetWidth + Math.ceil(scrollLeft) >= scrollWidth); }; const listContents = ( <> - {header} {isEmpty ? emptyMessage : listContent} + {header} + {isEmpty ? emptyMessage : listContent} ); const content = isEmpty || loading ? ( {listContents} @@ -106,35 +123,36 @@ export const List = forwardRef( return ( - {content} - {showShadow && ( - + + {isEmpty && ( + + + )} - + ); } diff --git a/packages/gamut/src/List/ListCol.tsx b/packages/gamut/src/List/ListCol.tsx index fbf42d3bbe..7c7164454d 100644 --- a/packages/gamut/src/List/ListCol.tsx +++ b/packages/gamut/src/List/ListCol.tsx @@ -1,6 +1,6 @@ import { ComponentProps, forwardRef } from 'react'; -import { ColEl, StickyColumnWrapper } from './elements'; +import { ColEl, StickyHeaderColWrapper } from './elements'; import { useListContext } from './ListProvider'; import { PublicListProps } from './types'; @@ -9,9 +9,14 @@ export interface ListColProps export const ListCol = forwardRef( ({ type, ...rest }, ref) => { - const { isOl, scrollable, ...activeVariants } = useListContext(); - const sticky = type === 'header' && scrollable; - const isOrderedHeader = isOl && type === 'header'; + const { listType, scrollable, ...activeVariants } = useListContext(); + const isOl = listType === 'ol'; + const isTable = listType === 'table'; + const isHeader = type === 'header'; + const sticky = isHeader && scrollable; + const isOrderedHeader = isOl && isHeader; + const colEl = + isTable && !sticky && isHeader ? 'th' : !isTable || sticky ? 'div' : 'td'; const col = ( ( type={isOrderedHeader ? 'orderedHeader' : type} sticky={sticky} ref={ref} + as={colEl} /> ); if (sticky) { return ( - + {col} - + ); } return <>{col}; diff --git a/packages/gamut/src/List/ListHeader.tsx b/packages/gamut/src/List/ListHeader.tsx deleted file mode 100644 index c40572f18e..0000000000 --- a/packages/gamut/src/List/ListHeader.tsx +++ /dev/null @@ -1,25 +0,0 @@ -import { ComponentProps, forwardRef } from 'react'; - -import { HeaderEl } from './elements'; -import { useListContext } from './ListProvider'; -import { PublicListProps } from './types'; - -export interface ListHeaderProps - extends Partial>> {} - -export const ListHeader = forwardRef( - ({ children, ...rest }, ref) => { - const { spacing, scrollable, variant } = useListContext(); - return ( - - {children} - - ); - } -); diff --git a/packages/gamut/src/List/ListProvider.tsx b/packages/gamut/src/List/ListProvider.tsx index bc56e6b8ce..0d7c2d8fdd 100644 --- a/packages/gamut/src/List/ListProvider.tsx +++ b/packages/gamut/src/List/ListProvider.tsx @@ -20,7 +20,7 @@ export function useListContext() { } export function useList({ - isOl, + listType, rowBreakpoint, scrollable, spacing, @@ -37,13 +37,13 @@ export function useList({ return useMemo( () => ({ depth: depth + 1, - isOl, + listType, root: depth === 0, rowBreakpoint, scrollable, spacing: activeSpacing, variant: activeVariant, }), - [isOl, scrollable, activeVariant, activeSpacing, depth, rowBreakpoint] + [listType, scrollable, activeVariant, activeSpacing, depth, rowBreakpoint] ); } diff --git a/packages/gamut/src/List/ListRow.tsx b/packages/gamut/src/List/ListRow.tsx index 9d78ef93ca..45a86463b8 100644 --- a/packages/gamut/src/List/ListRow.tsx +++ b/packages/gamut/src/List/ListRow.tsx @@ -1,3 +1,5 @@ +import { css } from '@codecademy/gamut-styles'; +import styled from '@emotion/styled'; import { AnimatePresence, motion } from 'framer-motion'; import { ComponentProps, forwardRef, MouseEvent } from 'react'; import * as React from 'react'; @@ -7,10 +9,15 @@ import { WithChildrenProp } from '../utils'; import { RowEl } from './elements'; import { useListContext } from './ListProvider'; import { PublicListProps } from './types'; +import { getGridTemplateColumns } from './utils'; export interface RowProps extends Partial>> { header?: boolean; + /** This is an internal prop that is largely only used for the DataTable component */ + numOfColumns?: number; + /** This is an internal prop that is largely only used for the DataTable component */ + selectable?: boolean; } export interface ExpandableRowProps extends RowProps { @@ -29,13 +36,24 @@ export interface SimpleRowProps extends RowProps { export type ListRowProps = ExpandableRowProps | SimpleRowProps; -const ExpandInCollapseOut: React.FC = ({ children }) => { +const expandStyles = css({ + overflow: 'hidden', + gridColumn: { _: 'span 2', xs: 'span 12' }, +}); + +const DivExpand = styled(motion.div)(expandStyles); +const TDExpand = styled(motion.td)(expandStyles); + +const ExpandInCollapseOut: React.FC< + WithChildrenProp & { as: 'td' | 'div' } +> = ({ as, children }) => { + const ResponsiveExpand = as === 'td' ? TDExpand : DivExpand; + return ( - = ({ children }) => { transition={{ duration: 0.2, ease: 'easeInOut' }} > {children} - + ); }; @@ -55,21 +73,30 @@ export const ListRow = forwardRef( expandedRowAriaLabel, renderExpanded, keepSpacingWhileExpanded, + numOfColumns, + selectable, ...rest }, ref ) => { - const { isOl, rowBreakpoint, scrollable, variant, ...rowConfig } = + const { listType, rowBreakpoint, scrollable, variant, ...rowConfig } = useListContext(); + const isOl = listType === 'ol'; + const isTable = listType === 'table'; const { onClick, role, tabIndex, ...rowProps } = rest; const wrapperProps = - !renderExpanded && !onClick + (!renderExpanded && !onClick) || isTable ? { ...rowConfig, ...rowProps } : { spacing: keepSpacingWhileExpanded ? rowConfig.spacing : undefined }; let content = children; const renderNumbering = isOl && renderExpanded === undefined && !onClick; - if (renderExpanded || Boolean(onClick)) { + const gridTemplateColumns = + isTable && renderExpanded + ? getGridTemplateColumns({ numOfColumns, selectable }) + : 'minmax(0, 1fr) max-content'; + + if ((renderExpanded || Boolean(onClick)) && !isTable) { content = ( ( <> {content} {expanded && ( - + {renderExpanded?.()} diff --git a/packages/gamut/src/List/TableHeader.tsx b/packages/gamut/src/List/TableHeader.tsx new file mode 100644 index 0000000000..be5bf72ae3 --- /dev/null +++ b/packages/gamut/src/List/TableHeader.tsx @@ -0,0 +1,28 @@ +import { ComponentProps, forwardRef } from 'react'; + +import { Box } from '../Box'; +import { HeaderRowEl } from './elements'; +import { useListContext } from './ListProvider'; +import { PublicListProps } from './types'; + +export interface TableHeaderProps + extends Partial>> {} + +export const TableHeader = forwardRef( + ({ children, ...rest }, ref) => { + const { spacing, scrollable, variant } = useListContext(); + return ( + + + {children} + + + ); + } +); diff --git a/packages/gamut/src/List/elements.tsx b/packages/gamut/src/List/elements.tsx index 1bcb1ec90a..3960893655 100644 --- a/packages/gamut/src/List/elements.tsx +++ b/packages/gamut/src/List/elements.tsx @@ -6,9 +6,11 @@ import { theme, variant, } from '@codecademy/gamut-styles'; -import { StyleProps } from '@codecademy/variance'; +import { StyleProps, variance } from '@codecademy/variance'; import styled from '@emotion/styled'; +import { Box } from '../Box'; + const olStyles = { alignItems: 'center', content: 'counters(section, ".") "."', @@ -131,10 +133,6 @@ const rowVariants = variant({ const rowBreakpointVariants = variant({ prop: 'rowBreakpoint', - base: { - gridAutoRows: 'minmax(1.5rem, max-content)', - gridTemplateColumns: 'minmax(0, 1fr) max-content', - }, defaultVariant: 'xs', variants: { xs: { @@ -149,6 +147,7 @@ const rowBreakpointVariants = variant({ display: { _: 'grid', md: 'flex' }, flexDirection: { _: 'column', md: 'row' }, }, + grid: { display: 'grid' }, }, }); @@ -156,13 +155,15 @@ export interface RowProps extends StyleProps, StyleProps, StyleProps, - StyleProps {} + StyleProps, + StyleProps {} export const RowEl = styled('li', styledOptions<'li'>())( css({ py: { _: 8, xs: 0 }, bg: 'inherit', }), + variance.compose(system.grid), rowBreakpointVariants, rowVariants, spacingVariants, @@ -187,9 +188,9 @@ export interface HeaderProps StyleProps, StyleProps {} -export const HeaderEl = styled('div', styledOptions)( +export const HeaderRowEl = styled('tr', styledOptions)( css({ - display: { _: 'none', xs: 'flex' }, + display: 'flex', position: { _: 'initial', xs: 'sticky' }, flexDirection: ['column', 'row'], top: 0, @@ -202,16 +203,13 @@ export const HeaderEl = styled('div', styledOptions)( headerVariants ); -const headerStyles = { gridColumn: 1 } as const; const columnType = variant({ prop: 'type', defaultVariant: 'content', variants: { - header: { - ...headerStyles, - }, + // Keeping this within variants for typing purposes, we use this behaviorally despite it not needing specific styling + header: {}, orderedHeader: { - ...headerStyles, '&::before': { ...olStyles, display: { _: 'flex', xs: 'none' }, @@ -228,7 +226,12 @@ const columnType = variant({ _: 'flex-start', xs: 'center', }, - gridColumn: 2, + justifyItems: { + _: 'end', + xs: undefined, + }, + + gridColumn: { _: 2, xs: 1 }, gridRow: 1, }, expand: { @@ -295,7 +298,7 @@ const columnStates = states({ bg: 'background-current', right: -4, top: 0, - bottom: -2, + bottom: -3, width: 4, position: 'absolute', }, @@ -351,7 +354,7 @@ export interface ColProps StyleProps, StyleProps, StyleProps, - StyleProps {} + StyleProps<(typeof system)['layout']> {} export const ColEl = styled( 'div', @@ -367,6 +370,7 @@ export const ColEl = styled( ]) )( css({ + fontWeight: 400, display: 'inline-flex', alignItems: 'center', whiteSpace: 'nowrap', @@ -381,7 +385,7 @@ export const ColEl = styled( system.layout ); -export const StickyColumnWrapper = styled.div( +export const StickyHeaderColWrapper = styled.th( css({ '&:before': { content: '""', @@ -396,7 +400,7 @@ export const StickyColumnWrapper = styled.div( '&:after': { content: '""', position: 'absolute', - bg: 'inherit', + bg: 'background-current', width: '100%', height: '100%', top: 0, @@ -407,6 +411,7 @@ export const StickyColumnWrapper = styled.div( left: 0, zIndex: 1, bg: 'inherit', + '&:not(:first-of-type)': { left: { xs: 16 }, overflow: 'visible', @@ -422,3 +427,11 @@ export const StickyColumnWrapper = styled.div( }, }) ); + +export const ListWrapper = styled(Box)( + states({ + scrollable: { + boxShadow: { _: undefined, xs: 'inset -24px 0 24px -24px black' }, + }, + }) +); diff --git a/packages/gamut/src/List/index.tsx b/packages/gamut/src/List/index.tsx index 24d4d4bfe0..85e0c33c10 100644 --- a/packages/gamut/src/List/index.tsx +++ b/packages/gamut/src/List/index.tsx @@ -1,5 +1,5 @@ export * from './List'; export * from './ListRow'; export * from './ListCol'; -export * from './ListHeader'; +export * from './TableHeader'; export * from './types'; diff --git a/packages/gamut/src/List/types.ts b/packages/gamut/src/List/types.ts index c3776287f2..90a9ca3856 100644 --- a/packages/gamut/src/List/types.ts +++ b/packages/gamut/src/List/types.ts @@ -1,5 +1,7 @@ +import { ListProps } from './List'; + export interface PrivateListProps { - isOl?: boolean; + listType?: ListProps['as']; rowBreakpoint?: 'xs' | 'sm' | 'md'; scrollable?: boolean; spacing?: 'normal' | 'condensed' | 'compact'; diff --git a/packages/gamut/src/List/utils.tsx b/packages/gamut/src/List/utils.tsx new file mode 100644 index 0000000000..a48edc30b4 --- /dev/null +++ b/packages/gamut/src/List/utils.tsx @@ -0,0 +1,10 @@ +export const getGridTemplateColumns = ({ + numOfColumns, + selectable, +}: { + numOfColumns?: number; + selectable?: boolean; +}) => { + const selectableText = selectable ? 'min-content ' : ''; + return `${selectableText}repeat(${numOfColumns}, minmax(0, min-content) max-content) min-content`; +}; diff --git a/packages/styleguide/src/lib/Organisms/Lists & Tables/DataList/DataList.stories.tsx b/packages/styleguide/src/lib/Organisms/Lists & Tables/DataList/DataList.stories.tsx index f4544f56d3..77d29496ee 100644 --- a/packages/styleguide/src/lib/Organisms/Lists & Tables/DataList/DataList.stories.tsx +++ b/packages/styleguide/src/lib/Organisms/Lists & Tables/DataList/DataList.stories.tsx @@ -4,7 +4,7 @@ import { DataList, DataTable, FlexBox } from '@codecademy/gamut'; import type { Meta, StoryObj } from '@storybook/react'; -import { DataListTemplate } from '../examples' +import { DataListTemplate } from '../examples'; const meta: Meta = { component: DataList, @@ -63,7 +63,7 @@ const meta: Meta = { /> ), - } + }, }; export default meta; @@ -71,7 +71,7 @@ type Story = StoryObj; export const FullDataList: Story = { render: () => , -} +}; export const Default: Story = { args: {}, @@ -79,12 +79,12 @@ export const Default: Story = { export const Expanded: Story = { args: { - expanded: ['Data'] - } -} + expanded: ['Data'], + }, +}; export const Selected: Story = { args: { - selected: ['Data'] - } -} + selected: ['Data'], + }, +}; diff --git a/packages/styleguide/src/lib/Organisms/Lists & Tables/DataTable/DataTable.stories.tsx b/packages/styleguide/src/lib/Organisms/Lists & Tables/DataTable/DataTable.stories.tsx index 75958eb773..32d53adfff 100644 --- a/packages/styleguide/src/lib/Organisms/Lists & Tables/DataTable/DataTable.stories.tsx +++ b/packages/styleguide/src/lib/Organisms/Lists & Tables/DataTable/DataTable.stories.tsx @@ -56,8 +56,6 @@ const meta: Meta = { { label: 'Ship', key: 'ship', size: 'lg', sortable: true, fill: true }, ], spacing: 'condensed', - onRowExpand: undefined, - onRowSelect: undefined, }, }; @@ -69,16 +67,23 @@ export const FullDataTable: Story = { }; export const EmptyState: Story = { - args: { rows: [], shadow: true, scrollable: true } -} + args: { + rows: [], + shadow: true, + scrollable: true, + height: '45vh', + minHeight: '300px', + }, + render: (args) => , +}; export const LoadingRows: Story = { - args: { loading: true, shadow: true } -} + args: { loading: true, shadow: true }, +}; export const Scrollable: Story = { - args: { shadow: true } -} + args: { shadow: true }, +}; export const Default: Story = { args: {},