From 69087c483a86747eb83d8b16ceb1870de5abf9b7 Mon Sep 17 00:00:00 2001 From: Preeti Bansal <146315451+preetibansalui@users.noreply.github.com> Date: Thu, 2 Jan 2025 12:37:00 +0530 Subject: [PATCH] chore: add decorator in dataTable (#18114) * chore: add decorator in dataTable * fix: replace slug with ai-lable * fix: test cases * fix: test case * fix: test cases * fix: changed const name as per PR suggestions * fix: css issues * fix: css * fix: test * fix: removed decorator stories * fix: test * fix: test --------- Co-authored-by: Taylor Jones --- .../__snapshots__/PublicAPI-test.js.snap | 22 ++++ packages/react/src/__tests__/index-test.js | 1 + .../src/components/DataTable/DataTable.tsx | 11 +- .../src/components/DataTable/TableCell.tsx | 6 +- .../DataTable/TableDecoratorRow.tsx | 68 ++++++++++++ .../components/DataTable/TableExpandRow.tsx | 28 +++-- .../src/components/DataTable/TableHeader.tsx | 57 +++++++--- .../src/components/DataTable/TableRow.tsx | 17 ++- .../src/components/DataTable/TableSlugRow.tsx | 10 +- .../DataTable/__tests__/Table-test.js | 2 +- .../__snapshots__/DataTable-test.js.snap | 24 +++++ .../__snapshots__/TableHeader-test.js.snap | 3 + .../react/src/components/DataTable/index.ts | 3 + .../stories/DataTable-ai-label.stories.js | 35 +++--- .../__snapshots__/normalize-test.js.snap | 18 ++-- .../components/DataTable/tools/normalize.js | 6 +- .../src/prop-types/deprecateComponent.js | 28 +++++ .../components/data-table/_data-table.scss | 102 ++++++++++++------ .../expandable/_data-table-expandable.scss | 18 +++- .../data-table/sort/_data-table-sort.scss | 16 ++- 20 files changed, 380 insertions(+), 95 deletions(-) create mode 100644 packages/react/src/components/DataTable/TableDecoratorRow.tsx create mode 100644 packages/react/src/prop-types/deprecateComponent.js diff --git a/packages/react/__tests__/__snapshots__/PublicAPI-test.js.snap b/packages/react/__tests__/__snapshots__/PublicAPI-test.js.snap index 123c4036d672..fb2430d115ee 100644 --- a/packages/react/__tests__/__snapshots__/PublicAPI-test.js.snap +++ b/packages/react/__tests__/__snapshots__/PublicAPI-test.js.snap @@ -1973,6 +1973,17 @@ Map { }, }, }, + "TableDecoratorRow": Object { + "displayName": "TableDecoratorRow", + "propTypes": Object { + "className": Object { + "type": "string", + }, + "decorator": Object { + "type": "node", + }, + }, + }, "TableExpandHeader": Object { "propTypes": Object { "aria-controls": Object { @@ -8058,6 +8069,17 @@ Map { }, }, }, + "TableDecoratorRow" => Object { + "displayName": "TableDecoratorRow", + "propTypes": Object { + "className": Object { + "type": "string", + }, + "decorator": Object { + "type": "node", + }, + }, + }, "TableExpandHeader" => Object { "propTypes": Object { "aria-controls": Object { diff --git a/packages/react/src/__tests__/index-test.js b/packages/react/src/__tests__/index-test.js index 3fc8a6767449..17cd9a659b01 100644 --- a/packages/react/src/__tests__/index-test.js +++ b/packages/react/src/__tests__/index-test.js @@ -205,6 +205,7 @@ describe('Carbon Components React', () => { "TableBody", "TableCell", "TableContainer", + "TableDecoratorRow", "TableExpandHeader", "TableExpandRow", "TableExpandedRow", diff --git a/packages/react/src/components/DataTable/DataTable.tsx b/packages/react/src/components/DataTable/DataTable.tsx index 67999fc93440..275f65481b7e 100644 --- a/packages/react/src/components/DataTable/DataTable.tsx +++ b/packages/react/src/components/DataTable/DataTable.tsx @@ -24,6 +24,7 @@ import TableBatchActions from './TableBatchActions'; import TableBody from './TableBody'; import TableCell from './TableCell'; import TableContainer from './TableContainer'; +import TableDecoratorRow from './TableDecoratorRow'; import TableExpandHeader from './TableExpandHeader'; import TableExpandRow from './TableExpandRow'; import TableExpandedRow from './TableExpandedRow'; @@ -99,6 +100,7 @@ export interface DataTableHeader { key: string; header: React.ReactNode; slug?: React.ReactElement; + decorator?: React.ReactElement; } export interface DataTableRenderProps { @@ -203,7 +205,8 @@ export interface DataTableRenderProps { }; getCellProps: (getCellPropsArgs: { cell: DataTableCell }) => { [key: string]: unknown; - hasSlugHeader?: boolean; + hasAILabelHeader?: boolean; + hasDecoratorHeader?: boolean; }; // Custom event handlers @@ -390,6 +393,7 @@ class DataTable extends React.Component< static TableBody: typeof TableBody; static TableCell: typeof TableCell; static TableContainer: typeof TableContainer; + static TableDecoratorRow: typeof TableDecoratorRow; static TableExpandHeader: typeof TableExpandHeader; static TableExpandRow: typeof TableExpandRow; static TableExpandedRow: typeof TableExpandedRow; @@ -473,6 +477,7 @@ class DataTable extends React.Component< isSortable, isSortHeader: sortHeaderKey === header.key, slug: header.slug, + decorator: header.decorator, onClick: (event) => { const nextSortState = getNextSortState(this.props, this.state, { key: header.key, @@ -747,7 +752,8 @@ class DataTable extends React.Component< getCellProps = ({ cell, ...rest }) => { return { ...rest, - hasSlugHeader: cell.hasSlugHeader, + hasAILabelHeader: cell.hasAILabelHeader, + hasDecoratorHeader: cell.hasDecoratorHeader, }; }; @@ -1035,6 +1041,7 @@ DataTable.TableBatchActions = TableBatchActions; DataTable.TableBody = TableBody; DataTable.TableCell = TableCell; DataTable.TableContainer = TableContainer; +DataTable.TableDecoratorRow = TableDecoratorRow; DataTable.TableExpandHeader = TableExpandHeader; DataTable.TableExpandRow = TableExpandRow; DataTable.TableExpandedRow = TableExpandedRow; diff --git a/packages/react/src/components/DataTable/TableCell.tsx b/packages/react/src/components/DataTable/TableCell.tsx index 1046bd770d2d..114847a14094 100644 --- a/packages/react/src/components/DataTable/TableCell.tsx +++ b/packages/react/src/components/DataTable/TableCell.tsx @@ -29,7 +29,7 @@ interface TableCellProps extends ReactAttr { /** * Specify if the table cell is in an AI column */ - hasSlugHeader?: boolean; + hasAILabelHeader?: 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 @@ -38,11 +38,11 @@ interface TableCellProps extends ReactAttr { } const TableCell = React.forwardRef( - ({ children, className, hasSlugHeader, colSpan, ...rest }, ref) => { + ({ children, className, hasAILabelHeader, colSpan, ...rest }, ref) => { const prefix = usePrefix(); const tableCellClassNames = classNames(className, { - [`${prefix}--table-cell--column-slug`]: hasSlugHeader, + [`${prefix}--table-cell--column-slug`]: hasAILabelHeader, }); return ( { + const prefix = usePrefix(); + const TableDecoratorRowClasses = classNames({ + ...(className && { [className]: true }), + [`${prefix}--table-column-decorator`]: true, + [`${prefix}--table-column-decorator--active`]: decorator, + }); + + let normalizedDecorator = React.isValidElement(decorator) + ? (decorator as ReactNode) + : null; + if ( + normalizedDecorator && + normalizedDecorator['type']?.displayName === 'AILabel' + ) { + normalizedDecorator = React.cloneElement( + normalizedDecorator as React.ReactElement, + { + size: 'mini', + } + ); + } + + return {normalizedDecorator}; +}; + +TableDecoratorRow.displayName = 'TableDecoratorRow'; +TableDecoratorRow.propTypes = { + /** + * The CSS class names of the cell that wraps the underlying input control + */ + className: PropTypes.string, + + /** + * **Experimental**: Provide a `decorator` component to be rendered inside the `TableDecoratorRow` component + */ + decorator: PropTypes.node, +}; + +export default TableDecoratorRow; diff --git a/packages/react/src/components/DataTable/TableExpandRow.tsx b/packages/react/src/components/DataTable/TableExpandRow.tsx index f2d3be5e1a0e..7e5c7d928eb5 100644 --- a/packages/react/src/components/DataTable/TableExpandRow.tsx +++ b/packages/react/src/components/DataTable/TableExpandRow.tsx @@ -73,12 +73,18 @@ const TableExpandRow = React.forwardRef( ) => { const prefix = usePrefix(); - // We need to put the slug before the expansion arrow and all other table cells after the arrow. - let rowHasSlug; - const slug = React.Children.toArray(children).map((child: any) => { - if (child.type?.displayName === 'TableSlugRow') { - if (child.props.slug) { - rowHasSlug = true; + // We need to put the AILabel and Decorator before the expansion arrow and all other table cells after the arrow. + let rowHasAILabel; + const decorator = React.Children.toArray(children).map((child: any) => { + if ( + child.type?.displayName === 'TableSlugRow' || + child.type?.displayName === 'TableDecoratorRow' + ) { + if ( + child.props.slug || + child.props.decorator?.type.displayName === 'AILabel' + ) { + rowHasAILabel = true; } return child; @@ -87,7 +93,10 @@ const TableExpandRow = React.forwardRef( const normalizedChildren = React.Children.toArray(children).map( (child: any) => { - if (child.type?.displayName !== 'TableSlugRow') { + if ( + child.type?.displayName !== 'TableSlugRow' && + child.type?.displayName !== 'TableDecoratorRow' + ) { return child; } } @@ -98,7 +107,8 @@ const TableExpandRow = React.forwardRef( [`${prefix}--parent-row`]: true, [`${prefix}--expandable-row`]: isExpanded, [`${prefix}--data-table--selected`]: isSelected, - [`${prefix}--data-table--slug-row`]: rowHasSlug, + [`${prefix}--data-table--slug-row ${prefix}--data-table--ai-label-row`]: + rowHasAILabel, }, rowClassName ); @@ -106,7 +116,7 @@ const TableExpandRow = React.forwardRef( return ( - {slug} + {decorator} (null); - let normalizedSlug; - if (slug) { - normalizedSlug = React.cloneElement(slug as React.ReactElement, { - size: 'mini', - ref: slugRef, - }); + // AILabel is always size `mini` + const AILableRef = useRef(null); + + let colHasAILabel; + let normalizedDecorator = React.isValidElement(slug ?? decorator) + ? (slug ?? decorator) + : null; + if ( + normalizedDecorator && + normalizedDecorator['type']?.displayName === 'AILabel' + ) { + colHasAILabel = true; + normalizedDecorator = React.cloneElement( + normalizedDecorator as React.ReactElement, + { + size: 'mini', + ref: AILableRef, + } + ); } const headerLabelClassNames = classNames({ [`${prefix}--table-header-label`]: true, - [`${prefix}--table-header-label--slug`]: slug, + [`${prefix}--table-header-label--slug ${prefix}--table-header-label--ai-label`]: + colHasAILabel, + [`${prefix}--table-header-label--decorator`]: decorator, }); if (!isSortable) { @@ -172,7 +192,9 @@ const TableHeader = React.forwardRef(function TableHeader( {children ? (
{children} - {normalizedSlug} +
+ {normalizedDecorator} +
) : null} @@ -198,11 +220,16 @@ const TableHeader = React.forwardRef(function TableHeader( }); const headerClasses = cx(headerClassName, `${prefix}--table-sort__header`, { - [`${prefix}--table-sort__header--slug`]: slug, + [`${prefix}--table-sort__header--ai-label`]: colHasAILabel, + [`${prefix}--table-sort__header--decorator`]: decorator, }); const handleClick = (evt) => { - if (slug && slugRef.current && slugRef.current.contains(evt.target)) { + if ( + colHasAILabel && + AILableRef.current && + AILableRef.current.contains(evt.target) + ) { return; } else if (onClick) { return onClick(evt); @@ -233,7 +260,9 @@ const TableHeader = React.forwardRef(function TableHeader( size={20} className={`${prefix}--table-sort__icon-unsorted`} /> - {normalizedSlug} +
+ {normalizedDecorator} +
diff --git a/packages/react/src/components/DataTable/TableRow.tsx b/packages/react/src/components/DataTable/TableRow.tsx index a55baaf140d3..453b28e69f13 100644 --- a/packages/react/src/components/DataTable/TableRow.tsx +++ b/packages/react/src/components/DataTable/TableRow.tsx @@ -25,12 +25,18 @@ export interface TableRowProps extends ReactAttr { const TableRow = (props: TableRowProps) => { const prefix = usePrefix(); - let rowHasSlug; + let rowHasAILabel; if (props?.children) { React.Children.toArray(props.children).map((child: any) => { - if (child.type?.displayName === 'TableSlugRow') { - if (child.props.slug) { - rowHasSlug = true; + if ( + child.type?.displayName === 'TableSlugRow' || + child.type?.displayName === 'TableDecoratorRow' + ) { + if ( + child.props.slug || + child.props.decorator?.type.displayName === 'AILabel' + ) { + rowHasAILabel = true; } } }); @@ -39,7 +45,8 @@ const TableRow = (props: TableRowProps) => { // only useful in `TableExpandRow` const className = cx(props.className, { [`${prefix}--data-table--selected`]: props.isSelected, - [`${prefix}--data-table--slug-row`]: rowHasSlug, + [`${prefix}--data-table--slug-row ${prefix}--data-table--ai-label-row`]: + rowHasAILabel, }); const { diff --git a/packages/react/src/components/DataTable/TableSlugRow.tsx b/packages/react/src/components/DataTable/TableSlugRow.tsx index 17b3f57de2f4..968ef6da7bff 100644 --- a/packages/react/src/components/DataTable/TableSlugRow.tsx +++ b/packages/react/src/components/DataTable/TableSlugRow.tsx @@ -6,9 +6,10 @@ */ import PropTypes from 'prop-types'; -import React, { ReactNode } from 'react'; +import React, { ReactNode, useEffect } from 'react'; import classNames from 'classnames'; import { usePrefix } from '../../internal/usePrefix'; +import deprecateComponent from '../../prop-types/deprecateComponent'; export interface TableSlugRowProps { /** @@ -23,6 +24,13 @@ export interface TableSlugRowProps { } const TableSlugRow = ({ className, slug }: TableSlugRowProps) => { + useEffect(() => { + deprecateComponent( + 'TableSlugRow', + 'The `TableSlugRow` component has been deprecated and will be removed in the next major version. Use the TableDecoratorRow component instead.' + ); + }, []); + const prefix = usePrefix(); const TableSlugRowClasses = classNames({ ...(className && { [className]: true }), diff --git a/packages/react/src/components/DataTable/__tests__/Table-test.js b/packages/react/src/components/DataTable/__tests__/Table-test.js index 0c7869a376e2..9846e188094f 100644 --- a/packages/react/src/components/DataTable/__tests__/Table-test.js +++ b/packages/react/src/components/DataTable/__tests__/Table-test.js @@ -248,7 +248,7 @@ describe('Table', () => { - Header1 + Header1 diff --git a/packages/react/src/components/DataTable/__tests__/__snapshots__/DataTable-test.js.snap b/packages/react/src/components/DataTable/__tests__/__snapshots__/DataTable-test.js.snap index ed766e80804a..edd5f4ed221b 100644 --- a/packages/react/src/components/DataTable/__tests__/__snapshots__/DataTable-test.js.snap +++ b/packages/react/src/components/DataTable/__tests__/__snapshots__/DataTable-test.js.snap @@ -35,6 +35,9 @@ exports[`DataTable behaves as expected selection -- radio buttons should not hav class="cds--table-header-label" > Field A +
@@ -207,6 +213,9 @@ exports[`DataTable behaves as expected selection -- radio buttons should render class="cds--table-header-label" > Field A +
@@ -664,6 +676,9 @@ exports[`DataTable behaves as expected selection should render and match snapsho class="cds--table-header-label" > Field A +
@@ -1069,6 +1087,9 @@ exports[`DataTable renders as expected - Component API should render and match s class="cds--table-header-label" > Field A +
diff --git a/packages/react/src/components/DataTable/__tests__/__snapshots__/TableHeader-test.js.snap b/packages/react/src/components/DataTable/__tests__/__snapshots__/TableHeader-test.js.snap index b1fe959fc430..dfede01b6f65 100644 --- a/packages/react/src/components/DataTable/__tests__/__snapshots__/TableHeader-test.js.snap +++ b/packages/react/src/components/DataTable/__tests__/__snapshots__/TableHeader-test.js.snap @@ -18,6 +18,9 @@ exports[`TableHeader renders as expected - Component API should render 1`] = ` class="cds--table-header-label" > Header +
diff --git a/packages/react/src/components/DataTable/index.ts b/packages/react/src/components/DataTable/index.ts index f38a32936231..393d215b18bf 100644 --- a/packages/react/src/components/DataTable/index.ts +++ b/packages/react/src/components/DataTable/index.ts @@ -21,6 +21,7 @@ import TableBody from './TableBody'; import TableCell from './TableCell'; import TableContainer from './TableContainer'; import TableExpandHeader from './TableExpandHeader'; +import TableDecoratorRow from './TableDecoratorRow'; import TableExpandRow from './TableExpandRow'; import TableExpandedRow from './TableExpandedRow'; import TableHead from './TableHead'; @@ -46,6 +47,7 @@ DataTable.TableBatchActions = TableBatchActions; DataTable.TableBody = TableBody; DataTable.TableCell = TableCell; DataTable.TableContainer = TableContainer; +DataTable.TableDecoratorRow = TableDecoratorRow; DataTable.TableExpandHeader = TableExpandHeader; DataTable.TableExpandRow = TableExpandRow; DataTable.TableExpandedRow = TableExpandedRow; @@ -77,6 +79,7 @@ export { TableBody, TableCell, TableContainer, + TableDecoratorRow, TableExpandHeader, TableExpandRow, TableExpandedRow, diff --git a/packages/react/src/components/DataTable/stories/DataTable-ai-label.stories.js b/packages/react/src/components/DataTable/stories/DataTable-ai-label.stories.js index 4420a233a33d..348e2501e66e 100644 --- a/packages/react/src/components/DataTable/stories/DataTable-ai-label.stories.js +++ b/packages/react/src/components/DataTable/stories/DataTable-ai-label.stories.js @@ -17,6 +17,7 @@ import DataTable, { TableSelectAll, TableSelectRow, TableSlugRow, + TableDecoratorRow, TableExpandHeader, TableExpandRow, TableExpandedRow, @@ -71,7 +72,7 @@ const columnAILabelHeaders = [ { key: 'attached_groups', header: 'Attached groups', - slug: ( + decorator: ( ( {rows.map((row, i) => ( - + {i === 3 || i === 4 || i === 1 ? ( + + ) : ( + + )} {row.cells.map((cell) => ( {cell.value} @@ -219,9 +222,11 @@ export const AILabelWithRadioSelection = () => ( {rows.map((row, i) => ( - + {i === 3 || i === 4 || i === 1 ? ( + + ) : ( + + )} {row.cells.map((cell) => ( {cell.value} @@ -272,9 +277,11 @@ export const AILabelWithSelectionAndExpansion = () => ( {rows.map((row, i) => ( - + {i === 3 || i === 4 || i === 1 ? ( + + ) : ( + + )} {row.cells.map((cell) => ( {cell.value} @@ -331,9 +338,11 @@ export const AILabelWithExpansion = () => ( {rows.map((row, i) => ( - + {i === 3 || i === 4 || i === 1 ? ( + + ) : ( + + )} {row.cells.map((cell) => ( {cell.value} ))} diff --git a/packages/react/src/components/DataTable/tools/__tests__/__snapshots__/normalize-test.js.snap b/packages/react/src/components/DataTable/tools/__tests__/__snapshots__/normalize-test.js.snap index c7869b02b40f..6e8974538cfc 100644 --- a/packages/react/src/components/DataTable/tools/__tests__/__snapshots__/normalize-test.js.snap +++ b/packages/react/src/components/DataTable/tools/__tests__/__snapshots__/normalize-test.js.snap @@ -4,7 +4,7 @@ exports[`normalize should return a normalized map of cells by id 1`] = ` Object { "a:fieldA": Object { "errors": null, - "hasSlugHeader": false, + "hasAILabelHeader": false, "id": "a:fieldA", "info": Object { "header": "fieldA", @@ -16,7 +16,7 @@ Object { }, "a:fieldB": Object { "errors": null, - "hasSlugHeader": false, + "hasAILabelHeader": false, "id": "a:fieldB", "info": Object { "header": "fieldB", @@ -28,7 +28,7 @@ Object { }, "a:fieldC": Object { "errors": null, - "hasSlugHeader": false, + "hasAILabelHeader": false, "id": "a:fieldC", "info": Object { "header": "fieldC", @@ -40,7 +40,7 @@ Object { }, "b:fieldA": Object { "errors": null, - "hasSlugHeader": false, + "hasAILabelHeader": false, "id": "b:fieldA", "info": Object { "header": "fieldA", @@ -52,7 +52,7 @@ Object { }, "b:fieldB": Object { "errors": null, - "hasSlugHeader": false, + "hasAILabelHeader": false, "id": "b:fieldB", "info": Object { "header": "fieldB", @@ -64,7 +64,7 @@ Object { }, "b:fieldC": Object { "errors": null, - "hasSlugHeader": false, + "hasAILabelHeader": false, "id": "b:fieldC", "info": Object { "header": "fieldC", @@ -76,7 +76,7 @@ Object { }, "c:fieldA": Object { "errors": null, - "hasSlugHeader": false, + "hasAILabelHeader": false, "id": "c:fieldA", "info": Object { "header": "fieldA", @@ -88,7 +88,7 @@ Object { }, "c:fieldB": Object { "errors": null, - "hasSlugHeader": false, + "hasAILabelHeader": false, "id": "c:fieldB", "info": Object { "header": "fieldB", @@ -100,7 +100,7 @@ Object { }, "c:fieldC": Object { "errors": null, - "hasSlugHeader": false, + "hasAILabelHeader": false, "id": "c:fieldC", "info": Object { "header": "fieldC", diff --git a/packages/react/src/components/DataTable/tools/normalize.js b/packages/react/src/components/DataTable/tools/normalize.js index 3a182e6b3f78..eac5e1110e42 100644 --- a/packages/react/src/components/DataTable/tools/normalize.js +++ b/packages/react/src/components/DataTable/tools/normalize.js @@ -45,7 +45,7 @@ const normalize = (rows, headers, prevState = {}) => { rowsById[row.id].isExpanded = prevRowsByIds[row.id].isExpanded; } - headers.forEach(({ key, slug }, i) => { + headers.forEach(({ key, slug, decorator }, i) => { const id = getCellId(row.id, key); // Initialize the cell info and state values, namely for editing cellsById[id] = { @@ -55,7 +55,9 @@ const normalize = (rows, headers, prevState = {}) => { isEditing: false, isValid: true, errors: null, - hasSlugHeader: !!slug, + hasAILabelHeader: !!( + slug || decorator?.type?.displayName === 'AILabel' + ), info: { header: key, }, diff --git a/packages/react/src/prop-types/deprecateComponent.js b/packages/react/src/prop-types/deprecateComponent.js new file mode 100644 index 000000000000..ae74722a0a19 --- /dev/null +++ b/packages/react/src/prop-types/deprecateComponent.js @@ -0,0 +1,28 @@ +/** + * Copyright IBM Corp. 2016, 2023 + * + * This source code is licensed under the Apache-2.0 license found in the + * LICENSE file in the root directory of this source tree. + */ + +import { warning } from '../internal/warning'; + +const didWarnAboutDeprecation = {}; + +export default function deprecateComponent(componentName, message) { + if (!componentName) { + return; + } + + if (!didWarnAboutDeprecation[componentName]) { + didWarnAboutDeprecation[componentName] = true; + + warning( + false, + message || + `The ${componentName} component has been deprecated and will be removed in the next major release.` + ); + } + + return componentName; +} diff --git a/packages/styles/scss/components/data-table/_data-table.scss b/packages/styles/scss/components/data-table/_data-table.scss index 27a7cdb1a6fe..b91b455130c3 100644 --- a/packages/styles/scss/components/data-table/_data-table.scss +++ b/packages/styles/scss/components/data-table/_data-table.scss @@ -941,59 +941,67 @@ // ------------------- // Slug styles // ------------------- - .#{$prefix}--data-table .#{$prefix}--table-column-slug { + .#{$prefix}--data-table .#{$prefix}--table-column-slug, + .#{$prefix}--data-table .#{$prefix}--table-column-decorator { inline-size: $spacing-05; padding-inline-end: 0; } tr.#{$prefix}--data-table--slug-row, - tr.#{$prefix}--data-table--slug-row + .#{$prefix}--expandable-row { + tr.#{$prefix}--data-table--slug-row + .#{$prefix}--expandable-row, + tr.#{$prefix}--data-table--ai-label-row, + tr.#{$prefix}--data-table--ai-label-row + .#{$prefix}--expandable-row { @include ai-table-gradient(); background-attachment: fixed; } - .#{$prefix}--data-table--slug-row { + .#{$prefix}--data-table--slug-row, + .#{$prefix}--data-table--ai-label-row { box-shadow: inset 1px 0 $ai-border-strong; } // Remove table cell backgrounds that are overriding gradient background on row - .#{$prefix}--data-table tbody tr.#{$prefix}--data-table--slug-row:hover td, - tr.#{$prefix}--data-table--slug-row.#{$prefix}--expandable-row:hover + .#{$prefix}--data-table + tbody + tr.#{$prefix}--data-table--ai-label-row:hover + td, + tr.#{$prefix}--data-table--ai-label-row.#{$prefix}--expandable-row:hover + .#{$prefix}--expandable-row[data-child-row] td, - tr.#{$prefix}--data-table--slug-row.#{$prefix}--expandable-row--hover + tr.#{$prefix}--data-table--ai-label-row.#{$prefix}--expandable-row--hover + .#{$prefix}--expandable-row[data-child-row]:hover > td, - tr.#{$prefix}--data-table--slug-row.#{$prefix}--expandable-row--hover > td, - tr.#{$prefix}--data-table--selected.#{$prefix}--data-table--slug-row.#{$prefix}--expandable-row + tr.#{$prefix}--data-table--ai-label-row.#{$prefix}--expandable-row--hover + > td, + tr.#{$prefix}--data-table--selected.#{$prefix}--data-table--ai-label-row.#{$prefix}--expandable-row + tr.#{$prefix}--expandable-row[data-child-row] > td, - tr.#{$prefix}--data-table--slug-row.#{$prefix}--parent-row.#{$prefix}--data-table--selected.#{$prefix}--expandable-row:hover + tr.#{$prefix}--data-table--ai-label-row.#{$prefix}--parent-row.#{$prefix}--data-table--selected.#{$prefix}--expandable-row:hover td, - tr.#{$prefix}--data-table--slug-row.#{$prefix}--parent-row.#{$prefix}--data-table--selected.#{$prefix}--expandable-row:hover + tr.#{$prefix}--data-table--ai-label-row.#{$prefix}--parent-row.#{$prefix}--data-table--selected.#{$prefix}--expandable-row:hover td:first-of-type, - tr.#{$prefix}--data-table--slug-row.#{$prefix}--parent-row.#{$prefix}--data-table--selected:not( + tr.#{$prefix}--data-table--ai-label-row.#{$prefix}--parent-row.#{$prefix}--data-table--selected:not( .#{$prefix}--expandable-row ):hover > td, - tr.#{$prefix}--data-table--slug-row.#{$prefix}--parent-row.#{$prefix}--data-table--selected.#{$prefix}--expandable-row:hover + tr.#{$prefix}--data-table--ai-label-row.#{$prefix}--parent-row.#{$prefix}--data-table--selected.#{$prefix}--expandable-row:hover + tr[data-child-row] > td, - tr.#{$prefix}--data-table--slug-row.#{$prefix}--parent-row.#{$prefix}--data-table--selected.#{$prefix}--expandable-row--hover + tr.#{$prefix}--data-table--ai-label-row.#{$prefix}--parent-row.#{$prefix}--data-table--selected.#{$prefix}--expandable-row--hover > td, - tr.#{$prefix}--data-table--slug-row.#{$prefix}--parent-row.#{$prefix}--data-table--selected.#{$prefix}--expandable-row--hover + tr.#{$prefix}--data-table--ai-label-row.#{$prefix}--parent-row.#{$prefix}--data-table--selected.#{$prefix}--expandable-row--hover > td:first-of-type { background-color: transparent; } - .#{$prefix}--data-table tbody tr.#{$prefix}--data-table--slug-row:hover, - tr.#{$prefix}--data-table--slug-row:hover + .#{$prefix}--data-table tbody tr.#{$prefix}--data-table--ai-label-row:hover, + tr.#{$prefix}--data-table--ai-label-row:hover + .#{$prefix}--expandable-row[data-child-row], - tr.#{$prefix}--data-table--slug-row.#{$prefix}--expandable-row--hover + tr.#{$prefix}--data-table--ai-label-row.#{$prefix}--expandable-row--hover + .#{$prefix}--expandable-row[data-child-row]:hover, - tr.#{$prefix}--expandable-row--hover.#{$prefix}--data-table--slug-row, - tr.#{$prefix}--data-table--selected.#{$prefix}--parent-row.#{$prefix}--expandable-row--hover.#{$prefix}--data-table--slug-row { + tr.#{$prefix}--expandable-row--hover.#{$prefix}--data-table--ai-label-row, + tr.#{$prefix}--data-table--selected.#{$prefix}--parent-row.#{$prefix}--expandable-row--hover.#{$prefix}--data-table--ai-label-row { @include ai-table-gradient('hover'); background-attachment: fixed; @@ -1002,22 +1010,31 @@ tr.#{$prefix}--parent-row.#{$prefix}--data-table--selected.#{$prefix}--data-table--slug-row, .#{$prefix}--data-table--selected.#{$prefix}--data-table--slug-row, tr.#{$prefix}--data-table--selected.#{$prefix}--data-table--slug-row + + .#{$prefix}--expandable-row, + tr.#{$prefix}--parent-row.#{$prefix}--data-table--selected.#{$prefix}--data-table--ai-label-row, + .#{$prefix}--data-table--selected.#{$prefix}--data-table--ai-label-row, + tr.#{$prefix}--data-table--selected.#{$prefix}--data-table--ai-label-row + .#{$prefix}--expandable-row { @include ai-table-gradient('selected'); background-attachment: fixed; } - tr.#{$prefix}--data-table--slug-row.#{$prefix}--data-table--selected td, - tr.#{$prefix}--data-table--slug-row.#{$prefix}--data-table--selected:hover td, - tbody tr.#{$prefix}--data-table--slug-row:hover td, - tr.#{$prefix}--data-table--slug-row.#{$prefix}--parent-row.#{$prefix}--data-table--selected.#{$prefix}--expandable-row:hover + tr.#{$prefix}--data-table--ai-label-row.#{$prefix}--data-table--selected td, + tr.#{$prefix}--data-table--ai-label-row.#{$prefix}--data-table--selected:hover + td, + tbody tr.#{$prefix}--data-table--ai-label-row:hover td, + tr.#{$prefix}--data-table--ai-label-row.#{$prefix}--parent-row.#{$prefix}--data-table--selected.#{$prefix}--expandable-row:hover td:not(.#{$prefix}--table-expand):not( .#{$prefix}--table-column-checkbox ):not(.#{$prefix}--table-column-slug) { border-block-end-color: $border-subtle; } + tr.#{$prefix}--expandable-row.#{$prefix}--data-table--selected.#{$prefix}--data-table--slug-row[data-parent-row] + > td:not(.#{$prefix}--table-expand):not( + .#{$prefix}--table-column-checkbox + ):not(.#{$prefix}--table-column-slug), tr.#{$prefix}--expandable-row.#{$prefix}--data-table--selected.#{$prefix}--data-table--slug-row[data-parent-row] > td:not(.#{$prefix}--table-expand):not( .#{$prefix}--table-column-checkbox @@ -1026,6 +1043,10 @@ } tr.#{$prefix}--parent-row.#{$prefix}--data-table--slug-row.#{$prefix}--expandable-row:hover + td:first-of-type, + tr.#{$prefix}--parent-row.#{$prefix}--data-table--ai-label-row.#{$prefix}--expandable-row:hover + td:first-of-type, + tr.#{$prefix}--parent-row.#{$prefix}--data-table--decoratorß-row.#{$prefix}--expandable-row:hover td:first-of-type { border-block-end: 1px solid transparent; } @@ -1034,14 +1055,20 @@ thead th.#{$prefix}--table-sort__header--slug .#{$prefix}--table-sort, + .#{$prefix}--data-table thead th:has(> .#{$prefix}--table-header-label--slug), + .#{$prefix}--data-table + thead + th.#{$prefix}--table-sort__header--ai-label + .#{$prefix}--table-sort, .#{$prefix}--data-table thead - th:has(> .#{$prefix}--table-header-label--slug) { + th:has(> .#{$prefix}--table-header-label--ai-label) { @include ai-table-gradient(); } .#{$prefix}--table-column-slug .#{$prefix}--ai-label, - .#{$prefix}--table-column-slug .#{$prefix}--slug { + .#{$prefix}--table-column-slug .#{$prefix}--slug, + .#{$prefix}--table-column-decorator .#{$prefix}--decorator { position: absolute; z-index: 2; transform: translateY(-50%); @@ -1050,27 +1077,40 @@ .#{$prefix}--data-table--xl .#{$prefix}--table-column-slug .#{$prefix}--ai-label, - .#{$prefix}--data-table--xl .#{$prefix}--table-column-slug .#{$prefix}--slug { + .#{$prefix}--data-table--xl .#{$prefix}--table-column-slug .#{$prefix}--slug, + .#{$prefix}--data-table--xl + .#{$prefix}--table-column-decorator + .#{$prefix}--decorator { transform: translateY(1px); } // AILabel inside header styles - th .#{$prefix}--table-header-label.#{$prefix}--table-header-label--slug { + th .#{$prefix}--table-header-label.#{$prefix}--table-header-label--slug, + th .#{$prefix}--table-header-label.#{$prefix}--table-header-label--ai-label, + th .#{$prefix}--table-header-label.#{$prefix}--table-header-label--decorator { display: flex; align-items: center; } th - .#{$prefix}--table-header-label.#{$prefix}--table-header-label--slug + .#{$prefix}--table-header-label.#{$prefix}--table-header-label--ai-label .#{$prefix}--ai-label, th - .#{$prefix}--table-header-label.#{$prefix}--table-header-label--slug - .#{$prefix}--slug { + .#{$prefix}--table-header-label.#{$prefix}--table-header-label--ai-label + .#{$prefix}--slug, + th + .#{$prefix}--table-header-label.#{$prefix}--table-header-label--decorator + .#{$prefix}--table-header-label--decorator-inner, + th + .#{$prefix}--table-header-label.#{$prefix}--table-header-label--ai-label + .#{$prefix}--table-header-label--decorator-inner { margin-inline-start: auto; } th.#{$prefix}--table-sort__header--slug, - th:has(.#{$prefix}--table-header-label--slug) { + th:has(.#{$prefix}--table-header-label--slug), + th.#{$prefix}--table-sort__header--ai-label, + th:has(.#{$prefix}--table-header-label--ai-label) { box-shadow: inset 0 1px $ai-border-strong; } diff --git a/packages/styles/scss/components/data-table/expandable/_data-table-expandable.scss b/packages/styles/scss/components/data-table/expandable/_data-table-expandable.scss index 0030fb871966..863e6641db49 100644 --- a/packages/styles/scss/components/data-table/expandable/_data-table-expandable.scss +++ b/packages/styles/scss/components/data-table/expandable/_data-table-expandable.scss @@ -82,6 +82,9 @@ tbody:has(> tr.#{$prefix}--data-table--slug-row) > tr.#{$prefix}--expandable-row[data-child-row] td, + tbody:has(> tr.#{$prefix}--data-table--ai-label-row) + > tr.#{$prefix}--expandable-row[data-child-row] + td, tbody:has(td.#{$prefix}--table-column-checkbox) > tr.#{$prefix}--expandable-row[data-child-row] td { @@ -89,7 +92,7 @@ } // Increase padding inside expandable row when slug AND checkbox is present in row - tbody:has(> tr.#{$prefix}--data-table--slug-row):has( + tbody:has(> tr.#{$prefix}--data-table--ai-label-row):has( td.#{$prefix}--table-column-checkbox ) > tr.#{$prefix}--expandable-row[data-child-row] @@ -474,6 +477,10 @@ .#{$prefix}--parent-row .#{$prefix}--table-column-slug, .#{$prefix}--parent-row .#{$prefix}--table-column-slug + + td.#{$prefix}--table-expand[data-previous-value='collapsed'], + .#{$prefix}--parent-row .#{$prefix}--table-column-decorator, + .#{$prefix}--parent-row + .#{$prefix}--table-column-decorator + td.#{$prefix}--table-expand[data-previous-value='collapsed'] { box-shadow: none; } @@ -482,12 +489,19 @@ .#{$prefix}--table-column-slug, .#{$prefix}--parent-row.#{$prefix}--expandable-row .#{$prefix}--table-column-slug + + td.#{$prefix}--table-expand[data-previous-value='collapsed'], + .#{$prefix}--parent-row.#{$prefix}--expandable-row + .#{$prefix}--table-column-decorator, + .#{$prefix}--parent-row.#{$prefix}--expandable-row + .#{$prefix}--table-column-decorator + td.#{$prefix}--table-expand[data-previous-value='collapsed'] { border-block-end: 1px solid transparent; } .#{$prefix}--data-table--slug-row td, - .#{$prefix}--data-table tr.#{$prefix}--data-table--slug-row:hover td { + .#{$prefix}--data-table tr.#{$prefix}--data-table--slug-row:hover td, + .#{$prefix}--data-table--ai-label-row td, + .#{$prefix}--data-table tr.#{$prefix}--data-table--ai-label-row:hover td { border-block-start: 1px solid transparent; } diff --git a/packages/styles/scss/components/data-table/sort/_data-table-sort.scss b/packages/styles/scss/components/data-table/sort/_data-table-sort.scss index bbd6007a610f..fb32336f097c 100644 --- a/packages/styles/scss/components/data-table/sort/_data-table-sort.scss +++ b/packages/styles/scss/components/data-table/sort/_data-table-sort.scss @@ -245,11 +245,21 @@ // AILabel styles .#{$prefix}--table-sort__header--slug .#{$prefix}--table-sort__icon, - .#{$prefix}--table-sort__header--slug .#{$prefix}--table-sort__icon-unsorted { + .#{$prefix}--table-sort__header--slug .#{$prefix}--table-sort__icon-unsorted, + .#{$prefix}--table-sort__header--ai-label .#{$prefix}--table-sort__icon, + .#{$prefix}--table-sort__header--ai-label + .#{$prefix}--table-sort__icon-unsorted, + .#{$prefix}--table-sort__header--decorator .#{$prefix}--table-sort__icon, + .#{$prefix}--table-sort__header--decorator + .#{$prefix}--table-sort__icon-unsorted { margin-inline: auto convert.to-rem(8px); } - .#{$prefix}--table-sort__header--slug .#{$prefix}--ai-label, - .#{$prefix}--table-sort__header--slug .#{$prefix}--slug { + .#{$prefix}--table-sort__header--ai-label .#{$prefix}--ai-label, + .#{$prefix}--table-sort__header--ai-label .#{$prefix}--slug, + .#{$prefix}--table-sort__header--decorator + .#{$prefix}--table-header-label--decorator-inner, + .#{$prefix}--table-sort__header--ai-label + .#{$prefix}--table-header-label--decorator-inner { margin-inline-end: convert.to-rem(8px); }
Field B +
Field B +
Field B +
Field B +