Skip to content

Commit

Permalink
feat(DataTable): Update DataTable to phase 2 spec (#15662)
Browse files Browse the repository at this point in the history
* feat(DataTable): start work on updating DataTable to phase 2 spec

* style(Table): refactor styles

* style(Table): add in selected styles

* style(Table): fix edge cases, add dark theme

* feat(Table): add in column gradient styles and support

* fix(DataTable): conditionally render td className

* refactor(DataTable): rework how slug is handled in TableHeader

* style(DataTable): adjust column gradient styles

* fix(DataTable): fix old class reference

* fix(DataTable): adjust sort + slug styles, fix issue with callout mixin

* style(DataTable): adjust gradient, move column slug

* test(Slug): add more VRT
  • Loading branch information
tw15egan authored Feb 8, 2024
1 parent 8d775dd commit 421dbc4
Show file tree
Hide file tree
Showing 25 changed files with 370 additions and 78 deletions.
32 changes: 32 additions & 0 deletions e2e/components/Slug/Slug-test.e2e.js
Original file line number Diff line number Diff line change
Expand Up @@ -22,13 +22,45 @@ test.describe('Slug', () => {
});
});

test('slug callout @vrt', async ({ page }) => {
await snapshotStory(page, {
component: 'Slug',
id: 'experimental-unstable-slug--callout',
theme,
});
});

test('slug inside form @vrt', async ({ page }) => {
await snapshotStory(page, {
component: 'Slug',
id: 'experimental-unstable-slug-form--form-example',
theme,
});
});

test('slug inside DataTable column @vrt', async ({ page }) => {
await snapshotStory(page, {
component: 'Slug',
id: 'experimental-unstable-slug-datatable--column-slug-sort',
theme,
});
});

test('slug inside DataTable row @vrt', async ({ page }) => {
await snapshotStory(page, {
component: 'Slug',
id: 'experimental-unstable-slug-datatable--slug-with-selection-and-expansion',
theme,
});
});

test('slug inside Tile @vrt', async ({ page }) => {
await snapshotStory(page, {
component: 'Slug',
id: 'experimental-unstable-slug-examples--tile',
theme,
});
});
});
});
});
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ Array [
"aiAuraHoverEnd",
"aiAuraHoverStart",
"aiAuraStart",
"aiAuraStartTable",
"aiBorderEnd",
"aiBorderStart",
"aiBorderStrong",
Expand Down
10 changes: 0 additions & 10 deletions packages/react/__tests__/__snapshots__/PublicAPI-test.js.snap
Original file line number Diff line number Diff line change
Expand Up @@ -1938,11 +1938,6 @@ Map {
},
"TableCell": Object {
"displayName": "TableCell",
"propTypes": Object {
"className": Object {
"type": "string",
},
},
},
"TableContainer": Object {
"propTypes": Object {
Expand Down Expand Up @@ -7725,11 +7720,6 @@ Map {
},
"TableCell" => Object {
"displayName": "TableCell",
"propTypes": Object {
"className": Object {
"type": "string",
},
},
},
"TableContainer" => Object {
"propTypes": Object {
Expand Down
21 changes: 21 additions & 0 deletions packages/react/src/components/DataTable/DataTable.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,7 @@ export interface DataTableRow<ColTypes extends any[]> {
export interface DataTableHeader {
key: string;
header: React.ReactNode;
slug: React.ReactElement;
}

export interface DataTableRenderProps<RowType, ColTypes extends any[]> {
Expand Down Expand Up @@ -189,6 +190,10 @@ export interface DataTableRenderProps<RowType, ColTypes extends any[]> {
stickyHeader?: boolean;
useStaticWidth?: boolean;
};
getCellProps: (getCellPropsArgs: { cell: DataTableCell<ColTypes> }) => {
[key: string]: unknown;
hasSlugHeader?: boolean;
};

// Custom event handlers
onInputChange: (
Expand Down Expand Up @@ -456,6 +461,7 @@ class DataTable<RowType, ColTypes extends any[]> extends React.Component<
sortDirection,
isSortable,
isSortHeader: sortHeaderKey === header.key,
slug: header.slug,
onClick: (event) => {
const nextSortState = getNextSortState(this.props, this.state, {
key: header.key,
Expand Down Expand Up @@ -715,6 +721,20 @@ class DataTable<RowType, ColTypes extends any[]> extends React.Component<
};
};

/**
* Get the props associated with the given table cell.
*
* @param {object} config
* @param {object} config.cell the cell we want the props for
* @returns {object}
*/
getCellProps = ({ cell, ...rest }) => {
return {
...rest,
hasSlugHeader: cell.hasSlugHeader,
};
};

/**
* Helper utility to get all the currently selected rows
* @returns {Array<string>} the array of rowIds that are currently selected
Expand Down Expand Up @@ -966,6 +986,7 @@ class DataTable<RowType, ColTypes extends any[]> extends React.Component<
getBatchActionProps: this.getBatchActionProps,
getTableProps: this.getTableProps,
getTableContainerProps: this.getTableContainerProps,
getCellProps: this.getCellProps,

// Custom event handlers
onInputChange: this.handleOnInputValueChange,
Expand Down
59 changes: 52 additions & 7 deletions packages/react/src/components/DataTable/TableCell.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,14 +5,59 @@
* LICENSE file in the root directory of this source tree.
*/

import { TdHTMLAttributes } from 'react';
import wrapComponent from '../../tools/wrapComponent';
import React from 'react';
import classNames from 'classnames';
import { usePrefix } from '../../internal/usePrefix';
import { ReactAttr } from '../../types/common';

export type TableCellProps = TdHTMLAttributes<HTMLTableCellElement>;
interface TableCellProps extends ReactAttr<HTMLTableCellElement> {
/**
* Pass in children that will be embedded in the table header label
*/
children?: React.ReactNode;

const TableCell: React.FC<TableCellProps> = wrapComponent({
name: 'TableCell',
type: 'td',
});
/**
* Specify an optional className to be applied to the container node
*/
className?: string;

/**
* The width of the expanded row's internal cell
*/
colSpan?: number;

/**
* Specify if the table cell is in an AI column
*/
hasSlugHeader?: boolean;

/**
* The id of the matching th node in the table head. Addresses a11y concerns outlined here: https://www.ibm.com/able/guidelines/ci162/info_and_relationships.html and https://www.w3.org/TR/WCAG20-TECHS/H43
*/
headers?: string;
}

const TableCell = ({
children,
className,
hasSlugHeader,
colSpan,
...rest
}: TableCellProps) => {
const prefix = usePrefix();

const tableCellClassNames = classNames(className, {
[`${prefix}--table-cell--column-slug`]: hasSlugHeader,
});
return (
<td
className={tableCellClassNames ? tableCellClassNames : undefined}
colSpan={colSpan}
{...rest}>
{children}
</td>
);
};

TableCell.displayName = 'TableCell';
export default TableCell;
2 changes: 1 addition & 1 deletion packages/react/src/components/DataTable/TableExpandRow.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -98,7 +98,7 @@ const TableExpandRow = React.forwardRef(
[`${prefix}--parent-row`]: true,
[`${prefix}--expandable-row`]: isExpanded,
[`${prefix}--data-table--selected`]: isSelected,
[`${prefix}--parent-row--slug`]: rowHasSlug,
[`${prefix}--data-table--slug-row`]: rowHasSlug,
},
rowClassName
);
Expand Down
2 changes: 1 addition & 1 deletion packages/react/src/components/DataTable/TableHeader.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -234,12 +234,12 @@ const TableHeader = React.forwardRef(function TableHeader(
{...rest}>
<span className={`${prefix}--table-sort__flex`}>
<div className={`${prefix}--table-header-label`}>{children}</div>
{normalizedSlug}
<Arrow size={20} className={`${prefix}--table-sort__icon`} />
<Arrows
size={20}
className={`${prefix}--table-sort__icon-unsorted`}
/>
{normalizedSlug}
</span>
</button>
</th>
Expand Down
13 changes: 13 additions & 0 deletions packages/react/src/components/DataTable/TableRow.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -25,11 +25,24 @@ export interface TableRowProps extends ReactAttr<HTMLTableRowElement> {

const TableRow = (props: TableRowProps) => {
const prefix = usePrefix();

let rowHasSlug;
if (props?.children) {
React.Children.toArray(props.children).map((child: any) => {
if (child.type?.displayName === 'TableSlugRow') {
if (child.props.slug) {
rowHasSlug = true;
}
}
});
}
// Remove unnecessary props if provided to this component, these are
// only useful in `TableExpandRow`
const className = cx(props.className, {
[`${prefix}--data-table--selected`]: props.isSelected,
[`${prefix}--data-table--slug-row`]: rowHasSlug,
});

const cleanProps = {
...omit(props, [
'ariaLabel',
Expand Down
Loading

0 comments on commit 421dbc4

Please sign in to comment.