diff --git a/packages/dnb-design-system-portal/src/docs/uilib/components/table/Examples.tsx b/packages/dnb-design-system-portal/src/docs/uilib/components/table/Examples.tsx index 26a599cacbc..5a3bd58fec9 100644 --- a/packages/dnb-design-system-portal/src/docs/uilib/components/table/Examples.tsx +++ b/packages/dnb-design-system-portal/src/docs/uilib/components/table/Examples.tsx @@ -214,7 +214,7 @@ export const TableVariantComplex = () => ( A Table Caption - + Column 2
newline @@ -224,13 +224,14 @@ export const TableVariantComplex = () => ( - Row 1 Header + + Row 1+2 Header + Row 1 that spans Row 1 Row 1 - Row 2 Header Row 2 Row 2 @@ -258,6 +259,28 @@ export const TableVariantComplex = () => ( ) +export const TableRowScopeOnly = () => ( + + + + + + + + + + + + + + + + +
A Table Caption
Header ARow 1Row 1
Header BRow 2Row 2
+
+
+) + export const TableVariantFixed = () => ( {() => { @@ -381,19 +404,18 @@ export const TableStackedContainer = () => { min-width: 800px; } table { - thead { - th:nth-of-type(1) { - width: 30%; - } - th:nth-of-type(2) { - width: 30%; - } - th:nth-of-type(3) { - width: 20%; - } - th:nth-of-type(4) { - width: 20%; - } + th:nth-of-type(1), + td:nth-of-type(1) { + width: 30%; + } + th:nth-of-type(2) { + width: 30%; + } + th:nth-of-type(3) { + width: 20%; + } + th:nth-of-type(4) { + width: 20%; } } ` @@ -478,6 +500,22 @@ export const TableStackedContainer = () => { + + + + + + + + + + + + + +
+ Row Header Group + Row 1Row 1
Row 2Row 2
@@ -634,7 +672,7 @@ export const TableAccordion = () => ( return ( <> - diff --git a/packages/dnb-design-system-portal/src/docs/uilib/components/table/demos.md b/packages/dnb-design-system-portal/src/docs/uilib/components/table/demos.md index 2f4988640cb..28191f989df 100644 --- a/packages/dnb-design-system-portal/src/docs/uilib/components/table/demos.md +++ b/packages/dnb-design-system-portal/src/docs/uilib/components/table/demos.md @@ -5,6 +5,7 @@ showTabs: true import { TableVariantBasic, TableVariantComplex, +TableRowScopeOnly, TableVariantFixed, TableStackedContainer, TableContainerEmptyHeaderFooter, @@ -30,8 +31,16 @@ TableAccordion, You can force a row to overwrite the automated odd/even counting by providing e.g. `variant="even"` to a ``. You can use this in combination with `rowSpan`. +**NB:** The table header in the first column needs to have `scope="row"`! + +### Row scope headers only + +This table has only `scope="row"` and `scope="rowgroup"` headers – without the default `scope="col"`. + + + ### Fixed table diff --git a/packages/dnb-eufemia/src/components/table/TableTh.tsx b/packages/dnb-eufemia/src/components/table/TableTh.tsx index 142cd100df1..e22f6763ee6 100644 --- a/packages/dnb-eufemia/src/components/table/TableTh.tsx +++ b/packages/dnb-eufemia/src/components/table/TableTh.tsx @@ -53,8 +53,11 @@ export default function Th( ...props } = componentProps - const role = props.scope === 'row' ? 'rowheader' : 'columnheader' - const scope = props.scope === 'row' ? 'row' : 'col' + const role = + props.scope === 'row' || props.scope === 'rowgroup' + ? 'rowheader' + : 'columnheader' + const scope = props.scope === 'row' ? 'row' : props.scope || 'col' const ariaSort = sortable ? reversed ? 'descending' diff --git a/packages/dnb-eufemia/src/components/table/__tests__/Table.screenshot.test.tsx b/packages/dnb-eufemia/src/components/table/__tests__/Table.screenshot.test.tsx index d880c5183b6..09b72c0a00f 100644 --- a/packages/dnb-eufemia/src/components/table/__tests__/Table.screenshot.test.tsx +++ b/packages/dnb-eufemia/src/components/table/__tests__/Table.screenshot.test.tsx @@ -31,6 +31,13 @@ describe('Table screenshot', () => { expect(screenshot).toMatchImageSnapshot() }) + it('have to match a row scope only table layout', async () => { + const screenshot = await testPageScreenshot({ + selector: '[data-visual-test="table-row-scope-only"] .dnb-table', + }) + expect(screenshot).toMatchImageSnapshot() + }) + it('have to match a fixed table layout', async () => { const screenshot = await testPageScreenshot({ selector: '[data-visual-test="table-fixed"]', diff --git a/packages/dnb-eufemia/src/components/table/__tests__/TableTh.test.tsx b/packages/dnb-eufemia/src/components/table/__tests__/TableTh.test.tsx index eaeea938861..3226e9ba84d 100644 --- a/packages/dnb-eufemia/src/components/table/__tests__/TableTh.test.tsx +++ b/packages/dnb-eufemia/src/components/table/__tests__/TableTh.test.tsx @@ -90,6 +90,23 @@ describe('TableTh', () => { expect(element.getAttribute('scope')).toBe('row') }) + it('should set correct role when scope is rowgroup', () => { + render( + + + + th content + + +
+ ) + + const element = document.querySelector('th') + + expect(element.getAttribute('role')).toBe('rowheader') + expect(element.getAttribute('scope')).toBe('rowgroup') + }) + it('should set correct sortable class', () => { render( 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 d5c24c1f7da..4f28a4788b4 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 @@ -57,6 +57,7 @@ exports[`Table scss have to match default theme snapshot 1`] = ` font-size: var(--font-size-small); line-height: var(--line-height-small); } .dnb-table:not(.dnb-table--outline) > tbody > .dnb-table__tr:last-of-type > .dnb-table__td::after, + .dnb-table:not(.dnb-table--outline) > tbody > .dnb-table__tr:last-of-type > .dnb-table__th::after, .dnb-table:not(.dnb-table--outline) > tbody > .dnb-table__tr.dnb-table__tr--has-accordion-content:not(.dnb-table__tr--expanded):nth-last-child(2) td::after { content: ''; @@ -172,8 +173,23 @@ exports[`Table scss have to match snapshot 1`] = ` white-space: nowrap; } .dnb-table > caption { caption-side: bottom; - margin-top: 0.5rem; - font-size: var(--font-size-basis); } + padding: 0.5rem 0 0.5rem 1rem; + font-size: var(--font-size-basis); + background-color: var(--color-white); + text-align: left; } + .dnb-table--border > caption:not(.dnb-sr-only) { + position: relative; } + .dnb-table--border > caption:not(.dnb-sr-only)::after { + content: ''; + position: absolute; + top: 0; + left: 0; + right: 0; + bottom: 0; + z-index: 1; + pointer-events: none; + top: -0.0625rem; + border-top: var(--border); } .dnb-table.dnb-skeleton > * { -webkit-text-fill-color: var(--skeleton-color); } .dnb-table > thead > tr > th.dnb-table--sortable, @@ -437,30 +453,7 @@ thead > tr > th.dnb-table--active .dnb-table__sort-button.dnb-button:hover:focus display: flex; align-items: flex-end; } -.dnb-table--outline thead .dnb-table__th::after { - content: ''; - position: absolute; - top: 0; - left: 0; - right: 0; - bottom: 0; - z-index: 1; - pointer-events: none; - border-top: var(--outline); } - -.dnb-table--outline thead .dnb-table__th:first-of-type::after { - border-left: var(--outline); } - -.dnb-table--outline thead .dnb-table__th:last-of-type::after { - border-right: var(--outline); } - -.dnb-table--outline thead .dnb-table__th:first-of-type, .dnb-table--outline thead .dnb-table__th:first-of-type::after { - border-radius: 0.5rem 0 0 0; } - -.dnb-table--outline thead .dnb-table__th:last-of-type, .dnb-table--outline thead .dnb-table__th:last-of-type::after { - border-radius: 0 0.5rem 0 0; } - -.dnb-table--outline tbody .dnb-table__th:first-of-type::after { +.dnb-table--border tbody .dnb-table__th::after { content: ''; position: absolute; top: 0; @@ -469,43 +462,16 @@ thead > tr > th.dnb-table--active .dnb-table__sort-button.dnb-button:hover:focus bottom: 0; z-index: 1; pointer-events: none; - border-left: var(--outline); } - -.dnb-table--outline tbody .dnb-table__tr:last-of-type .dnb-table__th::after { - content: ''; - position: absolute; - top: 0; - left: 0; - right: 0; - bottom: 0; - z-index: 1; - pointer-events: none; - border-bottom: var(--outline); } - -.dnb-table--outline tbody .dnb-table__tr:last-of-type .dnb-table__th:first-of-type::after { - border-radius: 0 0 0 0.5rem; } + border-top: var(--border); } /* * Table component * */ -.dnb-table--border tbody .dnb-table__td::after { - content: ''; - position: absolute; - top: 0; - left: 0; - right: 0; - bottom: 0; - z-index: 1; - pointer-events: none; - border: var(--border); - border-right: none; - border-bottom: none; } - -.dnb-table--outline tbody .dnb-table__td { +.dnb-table { /* stylelint-disable */ /* stylelint-enable */ } - .dnb-table--outline tbody .dnb-table__td:first-of-type::after, .dnb-table--outline tbody .dnb-table__td:last-of-type::after { + .dnb-table--border tbody .dnb-table__td::after { content: ''; position: absolute; top: 0; @@ -513,71 +479,55 @@ thead > tr > th.dnb-table--active .dnb-table__sort-button.dnb-button:hover:focus right: 0; bottom: 0; z-index: 1; - pointer-events: none; } - .dnb-table--outline tbody .dnb-table__td:first-of-type::after { - border-left: var(--outline); } - .dnb-table--outline tbody .dnb-table__td:last-of-type::after { - border-right: var(--outline); } - .dnb-table--outline tbody .dnb-table__td, .dnb-table--outline tbody .dnb-table__td::before, .dnb-table--outline tbody .dnb-table__td::after { - transition: border-radius 400ms var(--easing-default); } - -.dnb-table--outline tbody .dnb-table__tr:last-of-type .dnb-table__td::after, -.dnb-table--outline tbody -.dnb-table__tr.dnb-table__tr--has-accordion-content:not(.dnb-table__tr--expanded):nth-last-child(2) .dnb-table__td::after { - content: ''; - position: absolute; - top: 0; - left: 0; - right: 0; - bottom: 0; - z-index: 1; - pointer-events: none; - border-bottom: var(--outline); } - -.dnb-table--outline thead .dnb-table__th:first-of-type, .dnb-table--outline thead .dnb-table__th:first-of-type::after { - border-radius: 0.5rem 0 0 0; } - -.dnb-table--outline thead .dnb-table__th:last-of-type, .dnb-table--outline thead .dnb-table__th:last-of-type::after { - border-radius: 0 0.5rem 0 0; } - -.dnb-table--outline tbody .dnb-table__tr:last-of-type .dnb-table__td:first-of-type, .dnb-table--outline tbody .dnb-table__tr:last-of-type .dnb-table__td:first-of-type::before, .dnb-table--outline tbody .dnb-table__tr:last-of-type .dnb-table__td:first-of-type::after, -.dnb-table--outline tbody -.dnb-table__tr.dnb-table__tr--has-accordion-content:not(.dnb-table__tr--expanded):nth-last-child(2) .dnb-table__td:first-of-type, -.dnb-table--outline tbody -.dnb-table__tr.dnb-table__tr--has-accordion-content:not(.dnb-table__tr--expanded):nth-last-child(2) .dnb-table__td:first-of-type::before, -.dnb-table--outline tbody -.dnb-table__tr.dnb-table__tr--has-accordion-content:not(.dnb-table__tr--expanded):nth-last-child(2) .dnb-table__td:first-of-type::after { - border-radius: 0 0 0 0.5rem; } - -.dnb-table--outline tbody .dnb-table__tr:last-of-type .dnb-table__td:last-of-type, .dnb-table--outline tbody .dnb-table__tr:last-of-type .dnb-table__td:last-of-type::before, .dnb-table--outline tbody .dnb-table__tr:last-of-type .dnb-table__td:last-of-type::after, -.dnb-table--outline tbody -.dnb-table__tr.dnb-table__tr--has-accordion-content:not(.dnb-table__tr--expanded):nth-last-child(2) .dnb-table__td:last-of-type, -.dnb-table--outline tbody -.dnb-table__tr.dnb-table__tr--has-accordion-content:not(.dnb-table__tr--expanded):nth-last-child(2) .dnb-table__td:last-of-type::before, -.dnb-table--outline tbody -.dnb-table__tr.dnb-table__tr--has-accordion-content:not(.dnb-table__tr--expanded):nth-last-child(2) .dnb-table__td:last-of-type::after { - border-radius: 0 0 0.5rem 0; } - -.dnb-table--outline tbody .dnb-table__tr.dnb-table__tr__accordion_content:last-of-type .dnb-table__td, .dnb-table--outline tbody .dnb-table__tr.dnb-table__tr__accordion_content:last-of-type .dnb-table__td::before, .dnb-table--outline tbody .dnb-table__tr.dnb-table__tr__accordion_content:last-of-type .dnb-table__td::after { - border-radius: 0 0 0.5rem 0.5rem; } - -.dnb-table--outline tbody .dnb-table__tr .dnb-table__th ~ .dnb-table__td:first-of-type:first-of-type::after { - border-left: none; } - -.dnb-table--border tbody .dnb-table__tr .dnb-table__th ~ .dnb-table__td:first-of-type:first-of-type::after { - border-left: var(--border); } - -.dnb-table--outline tbody .dnb-table__tr:last-of-type .dnb-table__th ~ .dnb-table__td:first-of-type, .dnb-table--outline tbody .dnb-table__tr:last-of-type .dnb-table__th ~ .dnb-table__td:first-of-type::before, .dnb-table--outline tbody .dnb-table__tr:last-of-type .dnb-table__th ~ .dnb-table__td:first-of-type::after { - border-radius: 0 0 0 0; } - -.dnb-table__td--no-spacing, -.dnb-table td.dnb-table__td--no-spacing { - padding: 0; } - -.dnb-table__td--spacing-horizontal, -.dnb-table td.dnb-table__td--spacing-horizontal { - padding-top: 0; - padding-bottom: 0; } + pointer-events: none; + border: var(--border); + border-right: none; + border-bottom: none; } + .dnb-table--outline { + position: relative; } + .dnb-table--outline, .dnb-table--outline::after { + border-radius: 0.5rem; } + .dnb-table--outline::after { + content: ''; + position: absolute; + top: 0; + left: 0; + right: 0; + bottom: 0; + z-index: 1; + pointer-events: none; + z-index: 3; + border: var(--outline); } + .dnb-table--outline tbody .dnb-table__tr .dnb-table__th ~ .dnb-table__td:first-of-type:first-of-type::after { + border-left: none; } + .dnb-table--border tbody .dnb-table__tr .dnb-table__th ~ .dnb-table__td:first-of-type:first-of-type::after { + border-left: var(--border); } + .dnb-table--outline tbody .dnb-table__tr:last-of-type .dnb-table__th ~ .dnb-table__td:first-of-type, .dnb-table--outline tbody .dnb-table__tr:last-of-type .dnb-table__th ~ .dnb-table__td:first-of-type::before, .dnb-table--outline tbody .dnb-table__tr:last-of-type .dnb-table__th ~ .dnb-table__td:first-of-type::after { + border-radius: 0 0 0 0; } + .dnb-table--outline tbody:first-child .dnb-table__tr:first-of-type .dnb-table__th::after, + .dnb-table--outline > :not(thead) + tbody .dnb-table__tr:first-of-type .dnb-table__th::after { + border-top: var(--outline); } + .dnb-table--outline tbody:first-child .dnb-table__tr:first-of-type .dnb-table__th:first-of-type, .dnb-table--outline tbody:first-child .dnb-table__tr:first-of-type .dnb-table__th:first-of-type::after, + .dnb-table--outline > :not(thead) + tbody .dnb-table__tr:first-of-type .dnb-table__th:first-of-type, + .dnb-table--outline > :not(thead) + tbody .dnb-table__tr:first-of-type .dnb-table__th:first-of-type::after { + border-radius: 0.5rem 0 0 0; } + .dnb-table--outline > tbody:first-child .dnb-table__tr:first-of-type .dnb-table__td::after, + .dnb-table--outline > :not(thead) + tbody .dnb-table__tr:first-of-type .dnb-table__td::after { + border-top: var(--outline); } + .dnb-table--outline > tbody:first-child .dnb-table__tr:first-of-type .dnb-table__td:last-of-type, .dnb-table--outline > tbody:first-child .dnb-table__tr:first-of-type .dnb-table__td:last-of-type::after, + .dnb-table--outline > :not(thead) + tbody .dnb-table__tr:first-of-type .dnb-table__td:last-of-type, + .dnb-table--outline > :not(thead) + tbody .dnb-table__tr:first-of-type .dnb-table__td:last-of-type::after { + border-radius: 0 0.5rem 0 0; } + .dnb-table:not(.dnb-table--outline).dnb-table--border > tbody:first-child .dnb-table__td:last-of-type::after, + .dnb-table:not(.dnb-table--outline).dnb-table--border > :not(thead) + tbody .dnb-table__td:last-of-type::after { + border-right: var(--border); } + .dnb-table__td--no-spacing, + .dnb-table td.dnb-table__td--no-spacing { + padding: 0; } + .dnb-table__td--spacing-horizontal, + .dnb-table td.dnb-table__td--spacing-horizontal { + padding-top: 0; + padding-bottom: 0; } /* * Table component @@ -666,7 +616,9 @@ thead > tr > th.dnb-table--active .dnb-table__sort-button.dnb-button:hover:focus display: flex; flex-direction: column; } .dnb-table__container__body .dnb-table { - position: relative; } + position: relative; + /* stylelint-disable */ + /* stylelint-enable */ } .dnb-table__container__body .dnb-table:not([class*='space__bottom']) { margin-bottom: 0; } .dnb-table__container__body .dnb-table__size--large .dnb-table__th { @@ -681,6 +633,11 @@ thead > tr > th.dnb-table--active .dnb-table__sort-button.dnb-button:hover:focus z-index: 1; pointer-events: none; border-bottom: var(--border); } + .dnb-table__container__body .dnb-table tbody:first-child .dnb-table__tr:first-of-type .dnb-table__th::after, + .dnb-table__container__body .dnb-table tbody:first-child .dnb-table__tr:first-of-type .dnb-table__td::after, + .dnb-table__container__body .dnb-table > :not(thead) + tbody .dnb-table__tr:first-of-type .dnb-table__th::after, + .dnb-table__container__body .dnb-table > :not(thead) + tbody .dnb-table__tr:first-of-type .dnb-table__td::after { + border-top: none; } .dnb-table__container__head { padding: 2rem 1rem 0; } .dnb-table__container__head--empty { @@ -785,8 +742,11 @@ thead > tr > th.dnb-table--active .dnb-table__sort-button.dnb-button:hover:focus .dnb-table__tr--has-accordion-content, .dnb-table__tr__accordion_content { position: relative; z-index: 2; } - .dnb-table__tr--has-accordion-content:hover, .dnb-table__tr--has-accordion-content:active, .dnb-table__tr--has-accordion-content:focus, .dnb-table__tr--has-accordion-content.dnb-table__tr--expanded, .dnb-table__tr__accordion_content { + .dnb-table__tr--has-accordion-content.dnb-table__tr--expanded, .dnb-table__tr__accordion_content { z-index: 3; } + .dnb-table__tr--has-accordion-content:hover, .dnb-table__tr--has-accordion-content:active, + html[data-whatinput='keyboard'] .dnb-table__tr--has-accordion-content:focus { + z-index: 5; } .dnb-table__tr--has-accordion-content.dnb-table__tr--expanded .dnb-table__toggle-button .dnb-icon { transform: rotate(180deg); } .dnb-table--border .dnb-table__tr--has-accordion-content.dnb-table__tr--expanded td::after { @@ -812,6 +772,9 @@ thead > tr > th.dnb-table--active .dnb-table__sort-button.dnb-button:hover:focus border-color: var(--color-emerald-green); } html:not([data-whatintent='touch']) .dnb-table__tr--has-accordion-content.dnb-table__tr:not(.dnb-table__tr--disabled):hover:not([disabled]) .dnb-table__td__accordion-icon .dnb-icon { color: var(--color-emerald-green); } + .dnb-table--outline tbody +.dnb-table__tr--has-accordion-content:not(.dnb-table__tr--expanded):not(:nth-last-child(2)) .dnb-table__td::before { + bottom: -0.0625rem; } .dnb-table__tr--has-accordion-content.dnb-table__tr--expanded:not(.dnb-table__tr--disabled):hover .dnb-table__td { background-color: var(--color-white); } html[data-whatinput='keyboard'] .dnb-table__tr--has-accordion-content.dnb-table__tr:not(.dnb-table__tr--disabled):not(:active):not(:hover):focus td::before { @@ -845,11 +808,12 @@ thead > tr > th.dnb-table--active .dnb-table__sort-button.dnb-button:hover:focus @supports (-webkit-appearance: none) and (stroke-color: transparent) and (not (-webkit-touch-callout: none)) { .dnb-table__tr__accordion_content[hidden] { /** - * By reverting the display from "none" to "block", - * we trick VoiceOver to not make this row as the end of the table. We still need "hidden" to get the correct number of rows (childCount). - */ + * By reverting the display from "none" to "block", + * we trick VoiceOver to not make this row as the end of the table. We still need "hidden" to get the correct number of rows (childCount). + */ display: block; } } .dnb-table__tr__accordion_content td { + padding: 0 !important; width: calc(100% - 3.5rem); } .dnb-table__size--medium .dnb-table__tr__accordion_content td { width: calc(100% - 3rem); } @@ -894,6 +858,21 @@ thead > tr > th.dnb-table--active .dnb-table__sort-button.dnb-button:hover:focus * But we do not need baseline in this tr > td, so we reset it. */ vertical-align: top; } + .dnb-table--outline tbody +.dnb-table__tr.dnb-table__tr--has-accordion-content:not(.dnb-table__tr--expanded):nth-last-child(2) .dnb-table__td:first-of-type, .dnb-table--outline tbody +.dnb-table__tr.dnb-table__tr--has-accordion-content:not(.dnb-table__tr--expanded):nth-last-child(2) .dnb-table__td:first-of-type::before, .dnb-table--outline tbody +.dnb-table__tr.dnb-table__tr--has-accordion-content:not(.dnb-table__tr--expanded):nth-last-child(2) .dnb-table__td:first-of-type::after { + border-radius: 0 0 0 0.5rem; } + .dnb-table--outline tbody .dnb-table__tr:last-of-type .dnb-table__td:last-of-type, .dnb-table--outline tbody .dnb-table__tr:last-of-type .dnb-table__td:last-of-type::before, .dnb-table--outline tbody .dnb-table__tr:last-of-type .dnb-table__td:last-of-type::after, + .dnb-table--outline tbody +.dnb-table__tr.dnb-table__tr--has-accordion-content:not(.dnb-table__tr--expanded):nth-last-child(2) .dnb-table__td:last-of-type, + .dnb-table--outline tbody +.dnb-table__tr.dnb-table__tr--has-accordion-content:not(.dnb-table__tr--expanded):nth-last-child(2) .dnb-table__td:last-of-type::before, + .dnb-table--outline tbody +.dnb-table__tr.dnb-table__tr--has-accordion-content:not(.dnb-table__tr--expanded):nth-last-child(2) .dnb-table__td:last-of-type::after { + border-radius: 0 0 0.5rem 0; } + .dnb-table--outline tbody .dnb-table__tr.dnb-table__tr__accordion_content:last-of-type .dnb-table__td, .dnb-table--outline tbody .dnb-table__tr.dnb-table__tr__accordion_content:last-of-type .dnb-table__td::before, .dnb-table--outline tbody .dnb-table__tr.dnb-table__tr__accordion_content:last-of-type .dnb-table__td::after { + border-radius: 0 0 0.5rem 0.5rem; } .dnb-table__tr--has-accordion-content:not(.dnb-table__tr--disabled) { cursor: pointer; } .dnb-table__td-wrapper { diff --git a/packages/dnb-eufemia/src/components/table/__tests__/__snapshots__/table-screenshot-test-tsx-table-screenshot-have-to-match-a-complex-table-layout-1-c8007.snap.png b/packages/dnb-eufemia/src/components/table/__tests__/__snapshots__/table-screenshot-test-tsx-table-screenshot-have-to-match-a-complex-table-layout-1-c8007.snap.png index 9031439679f..8a48bfb392f 100644 Binary files a/packages/dnb-eufemia/src/components/table/__tests__/__snapshots__/table-screenshot-test-tsx-table-screenshot-have-to-match-a-complex-table-layout-1-c8007.snap.png and b/packages/dnb-eufemia/src/components/table/__tests__/__snapshots__/table-screenshot-test-tsx-table-screenshot-have-to-match-a-complex-table-layout-1-c8007.snap.png differ diff --git a/packages/dnb-eufemia/src/components/table/__tests__/__snapshots__/table-screenshot-test-tsx-table-screenshot-have-to-match-a-row-scope-only-table-layout-1-d0bac.snap.png b/packages/dnb-eufemia/src/components/table/__tests__/__snapshots__/table-screenshot-test-tsx-table-screenshot-have-to-match-a-row-scope-only-table-layout-1-d0bac.snap.png new file mode 100644 index 00000000000..caeba5e3217 Binary files /dev/null and b/packages/dnb-eufemia/src/components/table/__tests__/__snapshots__/table-screenshot-test-tsx-table-screenshot-have-to-match-a-row-scope-only-table-layout-1-d0bac.snap.png differ diff --git a/packages/dnb-eufemia/src/components/table/__tests__/__snapshots__/table-screenshot-test-tsx-table-screenshot-have-to-match-table-container-1-805c6.snap.png b/packages/dnb-eufemia/src/components/table/__tests__/__snapshots__/table-screenshot-test-tsx-table-screenshot-have-to-match-table-container-1-805c6.snap.png index 60700e92bfc..d1fd906e91c 100644 Binary files a/packages/dnb-eufemia/src/components/table/__tests__/__snapshots__/table-screenshot-test-tsx-table-screenshot-have-to-match-table-container-1-805c6.snap.png and b/packages/dnb-eufemia/src/components/table/__tests__/__snapshots__/table-screenshot-test-tsx-table-screenshot-have-to-match-table-container-1-805c6.snap.png differ diff --git a/packages/dnb-eufemia/src/components/table/__tests__/__snapshots__/table-screenshot-test-tsx-table-with-accordion-screenshot-have-to-match-expanded-state-on-first-row-1-4133b.snap.png b/packages/dnb-eufemia/src/components/table/__tests__/__snapshots__/table-screenshot-test-tsx-table-with-accordion-screenshot-have-to-match-expanded-state-on-first-row-1-4133b.snap.png index 3e0806fcfbe..d483730fc6a 100644 Binary files a/packages/dnb-eufemia/src/components/table/__tests__/__snapshots__/table-screenshot-test-tsx-table-with-accordion-screenshot-have-to-match-expanded-state-on-first-row-1-4133b.snap.png and b/packages/dnb-eufemia/src/components/table/__tests__/__snapshots__/table-screenshot-test-tsx-table-with-accordion-screenshot-have-to-match-expanded-state-on-first-row-1-4133b.snap.png differ diff --git a/packages/dnb-eufemia/src/components/table/__tests__/__snapshots__/table-screenshot-test-tsx-table-with-accordion-screenshot-have-to-match-hover-state-on-first-row-1-0a3aa.snap.png b/packages/dnb-eufemia/src/components/table/__tests__/__snapshots__/table-screenshot-test-tsx-table-with-accordion-screenshot-have-to-match-hover-state-on-first-row-1-0a3aa.snap.png index 3e187b74f2d..18ad5e76850 100644 Binary files a/packages/dnb-eufemia/src/components/table/__tests__/__snapshots__/table-screenshot-test-tsx-table-with-accordion-screenshot-have-to-match-hover-state-on-first-row-1-0a3aa.snap.png and b/packages/dnb-eufemia/src/components/table/__tests__/__snapshots__/table-screenshot-test-tsx-table-with-accordion-screenshot-have-to-match-hover-state-on-first-row-1-0a3aa.snap.png differ diff --git a/packages/dnb-eufemia/src/components/table/style/_table-accordion.scss b/packages/dnb-eufemia/src/components/table/style/_table-accordion.scss index 00a91139b50..99084fa54fb 100644 --- a/packages/dnb-eufemia/src/components/table/style/_table-accordion.scss +++ b/packages/dnb-eufemia/src/components/table/style/_table-accordion.scss @@ -72,13 +72,17 @@ position: relative; z-index: 2; } - &__tr--has-accordion-content:hover, - &__tr--has-accordion-content:active, - &__tr--has-accordion-content:focus, &__tr--has-accordion-content#{&}__tr--expanded, &__tr__accordion_content { - // ensure borders are visible in certain states - z-index: 3; + z-index: 3; // ensure borders are visible in certain states + } + + &__tr--has-accordion-content { + &:hover, + &:active, + html[data-whatinput='keyboard'] &:focus { + z-index: 5; // over table outline border + } } &__tr--has-accordion-content#{&}__tr--expanded @@ -129,6 +133,13 @@ } } + &--outline + tbody + &__tr--has-accordion-content:not(#{&}__tr--expanded):not(:nth-last-child(2)) + &__td::before { + bottom: -0.0625rem; + } + &__tr--has-accordion-content#{&}__tr--expanded:not(&__tr--disabled):hover &__td { background-color: var(--color-white); @@ -193,14 +204,16 @@ @include IS_SAFARI_DESKTOP { &[hidden] { /** - * By reverting the display from "none" to "block", - * we trick VoiceOver to not make this row as the end of the table. We still need "hidden" to get the correct number of rows (childCount). - */ + * By reverting the display from "none" to "block", + * we trick VoiceOver to not make this row as the end of the table. We still need "hidden" to get the correct number of rows (childCount). + */ display: block; } } td { + padding: 0 !important; // medium and small size sets padding – but we never want a padding on this td + width: calc(100% - 3.5rem); .dnb-table__size--medium & { @@ -279,9 +292,40 @@ vertical-align: top; } + &--outline + tbody + &__tr#{&}__tr--has-accordion-content:not(#{&}__tr--expanded):nth-last-child(2) + &__td:first-of-type { + &, + &::before, + &::after { + border-radius: 0 0 0 0.5rem; + } + } + &--outline tbody &__tr:last-of-type &__td:last-of-type, + &--outline + tbody + &__tr#{&}__tr--has-accordion-content:not(#{&}__tr--expanded):nth-last-child(2) + &__td:last-of-type { + &, + &::before, + &::after { + border-radius: 0 0 0.5rem 0; + } + } + &--outline tbody &__tr#{&}__tr__accordion_content:last-of-type &__td { + &, + &::before, + &::after { + border-radius: 0 0 0.5rem 0.5rem; + } + } + + // stylelint-disable-next-line &__tr--has-accordion-content:not(&__tr--disabled) { cursor: pointer; } + // prevent selection while animating – useful when user double-clicks // TODO: Our SASS version does not support :has – so we may use this in future // &__tr--has-accordion-content:has(& + &__tr__accordion_content--animating) { diff --git a/packages/dnb-eufemia/src/components/table/style/_table-container.scss b/packages/dnb-eufemia/src/components/table/style/_table-container.scss index 51e9e51de27..1ff9f0b06ce 100644 --- a/packages/dnb-eufemia/src/components/table/style/_table-container.scss +++ b/packages/dnb-eufemia/src/components/table/style/_table-container.scss @@ -40,6 +40,16 @@ @include tableBorder(); border-bottom: var(--border); } + + /* stylelint-disable */ + & tbody:first-child, + & > :not(thead) + tbody { + .dnb-table__tr:first-of-type .dnb-table__th::after, + .dnb-table__tr:first-of-type .dnb-table__td::after { + border-top: none; + } + } + /* stylelint-enable */ } } diff --git a/packages/dnb-eufemia/src/components/table/style/_table-td.scss b/packages/dnb-eufemia/src/components/table/style/_table-td.scss index f3ae13d3637..0dd5289384f 100644 --- a/packages/dnb-eufemia/src/components/table/style/_table-td.scss +++ b/packages/dnb-eufemia/src/components/table/style/_table-td.scss @@ -18,75 +18,16 @@ } // table outline - &--outline tbody &__td { - &:first-of-type::after, - &:last-of-type::after { - @include tableBorder(); - } - - &:first-of-type::after { - border-left: var(--outline); - } - &:last-of-type::after { - border-right: var(--outline); - } - - /* stylelint-disable */ - &, - &::before, - &::after { - transition: border-radius 400ms var(--easing-default); - } - /* stylelint-enable */ - } - &--outline tbody &__tr:last-of-type &__td::after, - &--outline - tbody - &__tr#{&}__tr--has-accordion-content:not(#{&}__tr--expanded):nth-last-child(2) - &__td::after { - @include tableBorder(); - - border-bottom: var(--outline); - } - &--outline thead &__th:first-of-type { - &, - &::after { - border-radius: 0.5rem 0 0 0; - } - } - &--outline thead &__th:last-of-type { - &, - &::after { - border-radius: 0 0.5rem 0 0; - } - } - &--outline tbody &__tr:last-of-type &__td:first-of-type, - &--outline - tbody - &__tr#{&}__tr--has-accordion-content:not(#{&}__tr--expanded):nth-last-child(2) - &__td:first-of-type { + &--outline { + position: relative; &, - &::before, &::after { - border-radius: 0 0 0 0.5rem; + border-radius: 0.5rem; } - } - &--outline tbody &__tr:last-of-type &__td:last-of-type, - &--outline - tbody - &__tr#{&}__tr--has-accordion-content:not(#{&}__tr--expanded):nth-last-child(2) - &__td:last-of-type { - &, - &::before, &::after { - border-radius: 0 0 0.5rem 0; - } - } - &--outline tbody &__tr#{&}__tr__accordion_content:last-of-type &__td { - &, - &::before, - &::after { - border-radius: 0 0 0.5rem 0.5rem; + @include tableBorder(); + z-index: 3; + border: var(--outline); } } @@ -109,6 +50,36 @@ } } + // no thead, should have th in body + /* stylelint-disable */ + &--outline tbody:first-child &__tr:first-of-type &__th, + &--outline > :not(thead) + tbody &__tr:first-of-type &__th { + &::after { + border-top: var(--outline); + } + &:first-of-type, + &:first-of-type::after { + border-radius: 0.5rem 0 0 0; + } + } + &--outline > tbody:first-child &__tr:first-of-type &__td, + &--outline > :not(thead) + tbody &__tr:first-of-type &__td { + &::after { + border-top: var(--outline); + } + &:last-of-type, + &:last-of-type::after { + border-radius: 0 0.5rem 0 0; + } + } + &:not(&--outline)#{&}--border > tbody:first-child &__td:last-of-type, + &:not(&--outline)#{&}--border > :not(thead) + tbody &__td:last-of-type { + &::after { + border-right: var(--border); + } + } + /* stylelint-enable */ + // spacing &__td--no-spacing, td#{&}__td--no-spacing { diff --git a/packages/dnb-eufemia/src/components/table/style/_table-th.scss b/packages/dnb-eufemia/src/components/table/style/_table-th.scss index 0acaff450bc..c4c10368806 100644 --- a/packages/dnb-eufemia/src/components/table/style/_table-th.scss +++ b/packages/dnb-eufemia/src/components/table/style/_table-th.scss @@ -12,46 +12,53 @@ } // table border - &--outline thead &__th { + &--border tbody &__th { &::after { @include tableBorder(); - border-top: var(--outline); - } - - &:first-of-type::after { - border-left: var(--outline); - } - &:last-of-type::after { - border-right: var(--outline); - } - } - &--outline thead &__th:first-of-type { - &, - &::after { - border-radius: 0.5rem 0 0 0; - } - } - &--outline thead &__th:last-of-type { - &, - &::after { - border-radius: 0 0.5rem 0 0; + border-top: var(--border); } } - &--outline tbody &__th:first-of-type::after { - @include tableBorder(); + // &--outline thead &__th { + // &::after { + // @include tableBorder(); - border-left: var(--outline); - } - &--outline tbody &__tr:last-of-type &__th { - &::after { - @include tableBorder(); + // border-top: var(--outline); + // } - border-bottom: var(--outline); - } + // &:first-of-type::after { + // border-left: var(--outline); + // } + // &:last-of-type::after { + // border-right: var(--outline); + // } + // } + // &--outline thead &__th:first-of-type { + // &, + // &::after { + // border-radius: 0.5rem 0 0 0; + // } + // } + // &--outline thead &__th:last-of-type { + // &, + // &::after { + // border-radius: 0 0.5rem 0 0; + // } + // } + // &--outline tbody &__th:first-of-type::after { + // @include tableBorder(); - &:first-of-type::after { - border-radius: 0 0 0 0.5rem; - } - } + // border-left: var(--outline); + // } + // &--outline tbody &__tr:last-of-type &__th { + // &::after { + // @include tableBorder(); + + // border-bottom: var(--outline); + // } + + // &:first-of-type::after { + // border-radius: 0 0 0 0.5rem; + // } + // } } diff --git a/packages/dnb-eufemia/src/components/table/style/_table.scss b/packages/dnb-eufemia/src/components/table/style/_table.scss index 85e7f64f9d7..97e7668f070 100644 --- a/packages/dnb-eufemia/src/components/table/style/_table.scss +++ b/packages/dnb-eufemia/src/components/table/style/_table.scss @@ -28,9 +28,19 @@ & > caption { caption-side: bottom; - margin-top: 0.5rem; + padding: 0.5rem 0 0.5rem 1rem; font-size: var(--font-size-basis); + background-color: var(--color-white); + text-align: left; + } + &--border > caption:not(.dnb-sr-only) { + position: relative; + &::after { + @include tableBorder(); + top: -0.0625rem; // so we are behind the border-bottom (end of table) + border-top: var(--border); + } } &.dnb-skeleton { 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 03e8679749f..d0d31684def 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 @@ -100,6 +100,7 @@ // border &:not(&--outline) > tbody > &__tr:last-of-type > &__td::after, + &:not(&--outline) > tbody > &__tr:last-of-type > &__th::after, &:not(&--outline) > tbody > &__tr#{&}__tr--has-accordion-content:not(#{&}__tr--expanded):nth-last-child(2)