From ff0be8db491c00ee06794e15934d72040f3dda66 Mon Sep 17 00:00:00 2001 From: Tobias Date: Wed, 8 Jun 2022 10:54:06 +0200 Subject: [PATCH] fix(Table): align HTML/CSS classes and types --- .../src/components/table/Table.tsx | 55 ++++++++----------- .../src/components/table/TableTd.tsx | 18 +++--- .../src/components/table/TableTh.tsx | 25 ++++++--- .../src/components/table/TableTr.tsx | 17 +++--- .../components/table/__tests__/Table.test.tsx | 24 ++++---- .../__tests__/TableStickyHeader.test.tsx | 14 +++-- .../__snapshots__/Table.test.tsx.snap | 41 +++++++------- .../src/components/table/style/_table.scss | 1 - .../style/themes/dnb-table-theme-ui.scss | 39 ++++++++----- 9 files changed, 128 insertions(+), 106 deletions(-) diff --git a/packages/dnb-eufemia/src/components/table/Table.tsx b/packages/dnb-eufemia/src/components/table/Table.tsx index 2fcda25ff22..489fc58ae5a 100644 --- a/packages/dnb-eufemia/src/components/table/Table.tsx +++ b/packages/dnb-eufemia/src/components/table/Table.tsx @@ -26,19 +26,16 @@ export { StickyHelper } export interface TableProps extends StickyTableHeaderProps { /** * The content of the component. - * Default: null */ - children?: React.ReactNode + children: React.ReactNode /** * Custom className on the component root - * Default: null */ className?: string /** * Skeleton should be applied when loading content - * Default: null */ skeleton?: SkeletonShow @@ -60,7 +57,11 @@ export const defaultProps = { variant: 'basis', } -const Table = (componentProps: TableProps & ISpacingProps) => { +const Table = ( + componentProps: TableProps & + React.TableHTMLAttributes & + ISpacingProps +) => { const context = React.useContext(Context) const allProps = usePropsWithContext( @@ -91,33 +92,25 @@ const Table = (componentProps: TableProps & ISpacingProps) => { validateDOMAttributes(allProps, props) - const Element = () => ( - - {children} -
+ return ( + + + {children} +
+
) - - if (skeleton) { - return ( - - - - ) - } - - return } export default Table diff --git a/packages/dnb-eufemia/src/components/table/TableTd.tsx b/packages/dnb-eufemia/src/components/table/TableTd.tsx index 7237af33deb..ff8f333ba4c 100644 --- a/packages/dnb-eufemia/src/components/table/TableTd.tsx +++ b/packages/dnb-eufemia/src/components/table/TableTd.tsx @@ -1,7 +1,7 @@ import React from 'react' import classnames from 'classnames' -type TableTdProps = { +export type TableTdProps = { /** * The content of the component. * Default: null @@ -13,11 +13,12 @@ type TableTdProps = { * Default: null */ className?: string -} & React.TdHTMLAttributes - -export const defaultProps = {} +} -const Td = (componentProps: TableTdProps) => { +const Td = ( + componentProps: TableTdProps & + React.TdHTMLAttributes +) => { const { className, children, @@ -26,8 +27,11 @@ const Td = (componentProps: TableTdProps) => { } = componentProps return ( - - {children} + ) } diff --git a/packages/dnb-eufemia/src/components/table/TableTh.tsx b/packages/dnb-eufemia/src/components/table/TableTh.tsx index 7509ffa1d61..4e0d69f06fc 100644 --- a/packages/dnb-eufemia/src/components/table/TableTh.tsx +++ b/packages/dnb-eufemia/src/components/table/TableTh.tsx @@ -1,23 +1,23 @@ import React from 'react' import classnames from 'classnames' -type TableThProps = { +export type TableThProps = { /** - * The content of the component. - * Default: null + * The content of the table header given as Tr. */ - children?: React.ReactNode + children: React.ReactNode /** * Custom className on the component root * Default: null */ className?: string -} & React.ThHTMLAttributes - -export const defaultProps = {} +} -const Th = (componentProps: TableThProps) => { +const Th = ( + componentProps: TableThProps & + React.ThHTMLAttributes +) => { const { className, children, @@ -26,7 +26,14 @@ const Th = (componentProps: TableThProps) => { } = componentProps return ( - + {children} ) diff --git a/packages/dnb-eufemia/src/components/table/TableTr.tsx b/packages/dnb-eufemia/src/components/table/TableTr.tsx index ed4f4f3cfbd..d3ec08713dc 100644 --- a/packages/dnb-eufemia/src/components/table/TableTr.tsx +++ b/packages/dnb-eufemia/src/components/table/TableTr.tsx @@ -1,23 +1,24 @@ import React from 'react' import classnames from 'classnames' +import { TableTdProps } from './TableTd' -type TableTrProps = { +export type TableTrProps = { /** * The content of the component. - * Default: null */ - children?: React.ReactNode + children: Array> /** * Custom className on the component root * Default: null */ className?: string -} & React.TableHTMLAttributes - -export const defaultProps = {} +} -const Tr = (componentProps: TableTrProps) => { +const Tr = ( + componentProps: TableTrProps & + React.TableHTMLAttributes +) => { const { className, children, @@ -26,7 +27,7 @@ const Tr = (componentProps: TableTrProps) => { } = componentProps return ( - + {children} ) diff --git a/packages/dnb-eufemia/src/components/table/__tests__/Table.test.tsx b/packages/dnb-eufemia/src/components/table/__tests__/Table.test.tsx index 680f7577918..b909e0e44e6 100644 --- a/packages/dnb-eufemia/src/components/table/__tests__/Table.test.tsx +++ b/packages/dnb-eufemia/src/components/table/__tests__/Table.test.tsx @@ -39,8 +39,8 @@ describe('Table', () => { expect(Array.from(screen.queryByRole('table').classList)).toEqual([ 'dnb-table', - 'dnb-table--basis', - 'dnb-table--size-large', + 'dnb-table__variant--basis', + 'dnb-table__size--large', ]) }) @@ -53,8 +53,8 @@ describe('Table', () => { expect(Array.from(screen.queryByRole('table').classList)).toEqual([ 'dnb-table', - 'dnb-table--not-defined-yet', - 'dnb-table--size-large', + 'dnb-table__variant--not-defined-yet', + 'dnb-table__size--large', ]) }) @@ -67,8 +67,8 @@ describe('Table', () => { expect(Array.from(screen.queryByRole('table').classList)).toEqual([ 'dnb-table', - 'dnb-table--basis', - 'dnb-table--size-medium', + 'dnb-table__variant--basis', + 'dnb-table__size--medium', ]) }) @@ -81,8 +81,8 @@ describe('Table', () => { expect(Array.from(screen.queryByRole('table').classList)).toEqual([ 'dnb-table', - 'dnb-table--basis', - 'dnb-table--size-large', + 'dnb-table__variant--basis', + 'dnb-table__size--large', 'dnb-table--fixed', ]) @@ -106,8 +106,8 @@ describe('Table', () => { expect(attributes).toEqual(['class']) expect(Array.from(element.classList)).toEqual([ 'dnb-table', - 'dnb-table--basis', - 'dnb-table--size-large', + 'dnb-table__variant--basis', + 'dnb-table__size--large', 'dnb-space__top--large', ]) }) @@ -127,8 +127,8 @@ describe('Table', () => { expect(attributes).toEqual(['class']) expect(Array.from(element.classList)).toEqual([ 'dnb-table', - 'dnb-table--basis', - 'dnb-table--size-large', + 'dnb-table__variant--basis', + 'dnb-table__size--large', 'dnb-skeleton', 'dnb-skeleton--font', ]) diff --git a/packages/dnb-eufemia/src/components/table/__tests__/TableStickyHeader.test.tsx b/packages/dnb-eufemia/src/components/table/__tests__/TableStickyHeader.test.tsx index d558f19675d..1247fd63ade 100644 --- a/packages/dnb-eufemia/src/components/table/__tests__/TableStickyHeader.test.tsx +++ b/packages/dnb-eufemia/src/components/table/__tests__/TableStickyHeader.test.tsx @@ -61,8 +61,8 @@ describe('useStickyHeader', () => { ]) expect(Array.from(screen.queryByRole('table').classList)).toEqual([ 'dnb-table', - 'dnb-table--basis', - 'dnb-table--size-large', + 'dnb-table__variant--basis', + 'dnb-table__size--large', 'dnb-table--sticky', ]) }) @@ -77,15 +77,19 @@ describe('useStickyHeader', () => { ) - expect(getTrClasses()).toEqual(['dnb-tr', 'sticky']) + expect(getTrClasses()).toEqual(['dnb-table__tr', 'sticky']) simulateEntry([{ isIntersecting: false }]) - expect(getTrClasses()).toEqual(['dnb-tr', 'sticky', 'show-shadow']) + expect(getTrClasses()).toEqual([ + 'dnb-table__tr', + 'sticky', + 'show-shadow', + ]) simulateEntry([{ isIntersecting: true }]) - expect(getTrClasses()).toEqual(['dnb-tr', 'sticky']) + expect(getTrClasses()).toEqual(['dnb-table__tr', 'sticky']) }) it('should use default stickyOffset when not given', () => { diff --git a/packages/dnb-eufemia/src/components/table/__tests__/__snapshots__/Table.test.tsx.snap b/packages/dnb-eufemia/src/components/table/__tests__/__snapshots__/Table.test.tsx.snap index 4e6ee863cba..163ffd86ae7 100644 --- a/packages/dnb-eufemia/src/components/table/__tests__/__snapshots__/Table.test.tsx.snap +++ b/packages/dnb-eufemia/src/components/table/__tests__/__snapshots__/Table.test.tsx.snap @@ -23,17 +23,14 @@ exports[`Table scss have to match default theme snapshot 1`] = ` .dnb-table > tr > th, .dnb-table > tr > td, .dnb-table > thead > tr > th, - .dnb-table > tbody > tr > td, - .dnb-table .dnb-table__th, - .dnb-table .dnb-table__td { + .dnb-table > tbody > tr > td, .dnb-table__th, .dnb-table__td { border-bottom: 1px solid transparent; font-size: var(--font-size-basis); line-height: var(--line-height-basis); border-spacing: 0; word-break: keep-all; } .dnb-table > tr > th, - .dnb-table > thead > tr > th, - .dnb-table .dnb-table__th { + .dnb-table > thead > tr > th, .dnb-table__th { padding: var(--spacing-x-large) var(--spacing-small) var(--spacing-x-small); font-weight: var(--font-weight-medium); color: var(--color-emerald-green); @@ -41,34 +38,38 @@ exports[`Table scss have to match default theme snapshot 1`] = ` background-color: var(--color-mint-green-50); border-bottom: 1px solid var(--color-mint-green); } .dnb-table > tr > th:not([align]):not(.dnb-table--left):not(.dnb-table--right):not(.dnb-table--center), - .dnb-table > thead > tr > th:not([align]):not(.dnb-table--left):not(.dnb-table--right):not(.dnb-table--center), - .dnb-table .dnb-table__th:not([align]):not(.dnb-table--left):not(.dnb-table--right):not(.dnb-table--center) { + .dnb-table > thead > tr > th:not([align]):not(.dnb-table--left):not(.dnb-table--right):not(.dnb-table--center), .dnb-table__th:not([align]):not(.dnb-table--left):not(.dnb-table--right):not(.dnb-table--center) { text-align: inherit; } @supports (-moz-appearance: meterbar) and (background-blend-mode: difference, normal) { .dnb-table > tr > th, - .dnb-table > thead > tr > th, - .dnb-table .dnb-table__th { + .dnb-table > thead > tr > th, .dnb-table__th { padding-bottom: calc(var(--spacing-x-small) - 0.5px); } } .dnb-table > tr > td, - .dnb-table > tbody > tr > td, - .dnb-table .dnb-table__td, + .dnb-table > tbody > tr > td, .dnb-table__td, .dnb-table > tr > th[scope='row'] { padding: var(--spacing-small); padding-top: calc(var(--spacing-small) * 1.25); padding-bottom: calc(var(--spacing-small) * 1.188); /* 19/16 */ color: var(--theme-color-black-80, currentColor); } - .dnb-table > tbody > tr:not(.dnb-table--ignore), - .dnb-table .dnb-table__tr:not(.dnb-table--ignore), - .dnb-table .dnb-table--odd:not(.dnb-table--ignore) { + .dnb-table > tbody > tr, + .dnb-table .dnb-table__tr, + .dnb-table .dnb-table__tr--odd { background-color: var(--color-white); } - .dnb-table > tbody > tr:not(.dnb-table--odd):nth-of-type(2n):not(.dnb-table--ignore), - .dnb-table .dnb-table__tr:not(.dnb-table--odd):nth-of-type(2n):not(.dnb-table--ignore), - .dnb-table .dnb-table--even:not(.dnb-table--ignore) { + .dnb-table > tbody > tr:not(.dnb-table__tr--odd):nth-of-type(2n), + .dnb-table .dnb-table__tr:not(.dnb-table__tr--odd):nth-of-type(2n), + .dnb-table .dnb-table__tr--even { background-color: var(--color-mint-green-12); } - .dnb-table > tbody > tr:last-of-type > td, - .dnb-table .dnb-table__tr:last-of-type .dnb-table__td { - border-bottom: 1px solid var(--color-mint-green-50); } + .dnb-table > tbody > tr:last-of-type::after, + .dnb-table > tbody > .dnb-table__tr:last-of-type::after { + content: ''; + position: absolute; + left: 0; + right: 0; + bottom: 0; + z-index: 2; + height: 1px; + background-color: var(--color-mint-green-50); } .dnb-table > thead > tr > th.dnb-table--sortable, .dnb-table .dnb-table__th.dnb-table--sortable { color: var(--color-emerald-green); } diff --git a/packages/dnb-eufemia/src/components/table/style/_table.scss b/packages/dnb-eufemia/src/components/table/style/_table.scss index 9258e43c1bd..df4024df45a 100644 --- a/packages/dnb-eufemia/src/components/table/style/_table.scss +++ b/packages/dnb-eufemia/src/components/table/style/_table.scss @@ -3,7 +3,6 @@ * */ -// @import '../../button/style/themes/button-mixins.scss'; .dnb-table { display: table; diff --git a/packages/dnb-eufemia/src/components/table/style/themes/dnb-table-theme-ui.scss b/packages/dnb-eufemia/src/components/table/style/themes/dnb-table-theme-ui.scss index f9c2bd7ceac..98d44bfcfbf 100644 --- a/packages/dnb-eufemia/src/components/table/style/themes/dnb-table-theme-ui.scss +++ b/packages/dnb-eufemia/src/components/table/style/themes/dnb-table-theme-ui.scss @@ -13,8 +13,8 @@ & > tr > td, & > thead > tr > th, & > tbody > tr > td, - & &__th, - & &__td { + &__th, + &__td { // to make sure we have the ability to have a border where ever we want border-bottom: 1px solid transparent; @@ -27,7 +27,7 @@ /* stylelint-disable-next-line */ & > tr > th, & > thead > tr > th, - & &__th { + &__th { padding: var(--spacing-x-large) var(--spacing-small) var(--spacing-x-small); @@ -53,7 +53,7 @@ /* stylelint-disable-next-line */ & > tr > td, & > tbody > tr > td, - & &__td, + &__td, & > tr > th[scope='row'] { padding: var(--spacing-small); padding-top: calc(var(--spacing-small) * 1.25); @@ -61,19 +61,32 @@ color: var(--theme-color-black-80, currentColor); } - & > tbody > tr:not(#{&}--ignore), - & &__tr:not(#{&}--ignore), - & &--odd:not(#{&}--ignore) { + + // Needs a double & & for specificity + & > tbody > tr, + & &__tr, + & &__tr--odd { background-color: var(--color-white); } - & > tbody > tr:not(#{&}--odd):nth-of-type(2n):not(#{&}--ignore), - & &__tr:not(#{&}--odd):nth-of-type(2n):not(#{&}--ignore), - & &--even:not(#{&}--ignore) { + + // Needs a double & & for specificity + & > tbody > tr:not(#{&}__tr--odd):nth-of-type(2n), + & &__tr:not(#{&}__tr--odd):nth-of-type(2n), + & &__tr--even { background-color: var(--color-mint-green-12); } - & > tbody > tr:last-of-type > td, - & &__tr:last-of-type &__td { - border-bottom: 1px solid var(--color-mint-green-50); + + & > tbody > tr:last-of-type::after, + & > tbody > &__tr:last-of-type::after { + content: ''; + position: absolute; + left: 0; + right: 0; + bottom: 0; + z-index: 2; + + height: 1px; + background-color: var(--color-mint-green-50); } @include basisTableSortable();