From 3e0de2c0035f266f32df8ba0fcfd81aff04e03f1 Mon Sep 17 00:00:00 2001 From: Andrew Holloway Date: Tue, 27 Aug 2024 09:50:45 -0500 Subject: [PATCH] feat(DataTable): introduce 1.0 component - new component for complex data-based table content - add in types, layouts, and test - add in snapshots - make use of newly-added tokens --- .storybook/preview.tsx | 1 + src/components/DataTable/DataTable.module.css | 38 ++++++++ src/components/DataTable/DataTable.stories.ts | 32 +++++++ src/components/DataTable/DataTable.test.ts | 7 ++ src/components/DataTable/DataTable.tsx | 94 +++++++++++++++++++ src/components/DataTable/index.ts | 1 + src/index.ts | 1 + 7 files changed, 174 insertions(+) create mode 100644 src/components/DataTable/DataTable.module.css create mode 100644 src/components/DataTable/DataTable.stories.ts create mode 100644 src/components/DataTable/DataTable.test.ts create mode 100644 src/components/DataTable/DataTable.tsx create mode 100644 src/components/DataTable/index.ts diff --git a/.storybook/preview.tsx b/.storybook/preview.tsx index ccd9cc76a..6afd608e5 100644 --- a/.storybook/preview.tsx +++ b/.storybook/preview.tsx @@ -84,6 +84,7 @@ export const parameters: Preview['parameters'] = { ...createInitialReleaseConfig('1.2'), ...createInitialReleaseConfig('1.1'), ...createInitialReleaseConfig('1.0'), + ...createCurrentReleaseConfig('1.0'), ...createCurrentReleaseConfig('1.3'), ...createCurrentReleaseConfig('2.0'), ...createCurrentReleaseConfig('2.1'), diff --git a/src/components/DataTable/DataTable.module.css b/src/components/DataTable/DataTable.module.css new file mode 100644 index 000000000..e873011ca --- /dev/null +++ b/src/components/DataTable/DataTable.module.css @@ -0,0 +1,38 @@ +/*------------------------------------*\ + # DATA TABLE +\*------------------------------------*/ + +/** + * DataTable + */ + +.data-table__caption { + font: var(--eds-theme-typography-headline-md-bold); +} + +.data-table__subcaption { + font: var(--eds-theme-typography-headline-sm); +} + +.data-table__table { + border: 1px solid; + width: 100%; + + .data-table__caption + &, + .data-table__subcaption + & { + margin-top: calc(var(--eds-size-4) / 16 * 1rem); + } +} + +/** + * Color Tokens + */ + .data-table { + .data-table__caption { + color: var(--eds-theme-color-text-utility-default-primary); + } + + .data-table__subcaption { + color: var(--eds-theme-color-text-utility-default-secondary); + } +} diff --git a/src/components/DataTable/DataTable.stories.ts b/src/components/DataTable/DataTable.stories.ts new file mode 100644 index 000000000..56e35438d --- /dev/null +++ b/src/components/DataTable/DataTable.stories.ts @@ -0,0 +1,32 @@ +import { BADGE } from '@geometricpanda/storybook-addon-badges'; +import type { StoryObj, Meta } from '@storybook/react'; +import type React from 'react'; + +import { DataTable } from './DataTable'; + +export default { + title: 'Components/DataTable', + component: DataTable, + parameters: { + badges: [BADGE.BETA, 'intro-1.0', 'current-1.0'], + }, +} as Meta; + +type Args = React.ComponentProps; + +export const Default: StoryObj = { + args: {}, +}; + +export const WithBasicCaption: StoryObj = { + args: { + caption: 'Test Caption', + }, +}; + +export const WithFullCaption: StoryObj = { + args: { + caption: 'Test Caption', + subcaption: 'Additional Sub-caption text description', + }, +}; diff --git a/src/components/DataTable/DataTable.test.ts b/src/components/DataTable/DataTable.test.ts new file mode 100644 index 000000000..32aca6861 --- /dev/null +++ b/src/components/DataTable/DataTable.test.ts @@ -0,0 +1,7 @@ +import { generateSnapshots } from '@chanzuckerberg/story-utils'; +import * as stories from './DataTable.stories'; +import type { StoryFile } from '../../util/utility-types'; + +describe('', () => { + generateSnapshots(stories as StoryFile); +}); diff --git a/src/components/DataTable/DataTable.tsx b/src/components/DataTable/DataTable.tsx new file mode 100644 index 000000000..2590948aa --- /dev/null +++ b/src/components/DataTable/DataTable.tsx @@ -0,0 +1,94 @@ +import clsx from 'clsx'; +import React from 'react'; + +import type { Status } from '../../util/variant-types'; +import type { IconName } from '../Icon/Icon'; + +import styles from './DataTable.module.css'; + +export type DataTableProps = { + // Component API + /** + * CSS class names that can be appended to the component. + */ + className?: string; + // Design API + caption?: string; + rowStyle?: 'striped' | 'lined'; + subcaption?: string; + tableStyle?: 'basic' | 'border'; + isSelectable?: boolean; + isStatusEligible?: boolean; +}; + +// TODO: DataTableColumnProps + +export type DataTableRowProps = { + isInteractive?: boolean; + isSelectable?: boolean; + status?: Extract; +}; + +// TODO: DataTableTableActionsProps + +export type DataTableHeaderProps = { + initialSortDirection?: 'ascending' | 'descending'; + isSticky?: boolean; + isSelected?: boolean; + isSortable?: boolean; + //textOverflowBehavior handled by tailwind/styles +}; + +export type DataTableHeaderCellProps = { + alignment?: 'leading' | 'trailing'; + /** + * An icon that prefixes the field input. + */ + leadingIcon?: IconName; + sublabel?: string; +}; + +export type DataTableDataCellProps = DataTableHeaderCellProps & { + // dataType?: 'link' | 'number' | 'text' | 'boolean' | 'list'; +}; + +// TODO: TableSectionHeaderProps + +/** + * `import {DataTable} from "@chanzuckerberg/eds";` + * + * DataTable represents a full-featured data view for controlling, sorting, and acting on tabular data. It: + * - handles responsive behaviors + * - allows for showing status for each row + * - sort behavior on individual columns + * - **Soon** search of table content w/ hooks to support + * - **Soon** actions to perform when rows can be selected + * + */ +export const DataTable = ({ + className, + // Add other deferenced props to use + caption, + subcaption, + ...other +}: DataTableProps) => { + const componentClassName = clsx(styles['data-table'], className); + const tableClassName = clsx(styles['data-table__table']); + + return ( +
+ {caption && ( +
{caption}
+ )} + {subcaption && ( +
{subcaption}
+ )} + +
Table Here
+
+ ); +}; diff --git a/src/components/DataTable/index.ts b/src/components/DataTable/index.ts new file mode 100644 index 000000000..cadb02a9a --- /dev/null +++ b/src/components/DataTable/index.ts @@ -0,0 +1 @@ +export { DataTable as default } from './DataTable'; diff --git a/src/index.ts b/src/index.ts index 47b2912b0..e8703047d 100644 --- a/src/index.ts +++ b/src/index.ts @@ -29,6 +29,7 @@ export { default as Button } from './components/Button'; export { default as ButtonGroup } from './components/ButtonGroup'; export { default as Card } from './components/Card'; export { default as Checkbox } from './components/Checkbox'; +export { default as DataTable } from './components/DataTable'; export { default as FieldLabel } from './components/FieldLabel'; export { default as FieldNote } from './components/FieldNote'; export { default as Fieldset } from './components/Fieldset';