diff --git a/packages/main/src/Table.ts b/packages/main/src/Table.ts index 4b91bfd81c99..de3357696984 100644 --- a/packages/main/src/Table.ts +++ b/packages/main/src/Table.ts @@ -178,7 +178,14 @@ class Table extends UI5Element { * * @public */ - @slot({ type: HTMLElement, "default": true }) + @slot({ + type: HTMLElement, + "default": true, + invalidateOnChildChange: { + properties: ["navigated"], + slots: false, + }, + }) rows!: Array; /** @@ -275,6 +282,9 @@ class Table extends UI5Element { @property({ type: Number, noAttribute: true }) _invalidate = 0; + @property({ type: Boolean, noAttribute: true }) + _renderNavigated = false; + static i18nBundle: I18nBundle; static async onDefine() { Table.i18nBundle = await getI18nBundle("@ui5/webcomponents"); @@ -313,6 +323,12 @@ class Table extends UI5Element { } onBeforeRendering(): void { + const renderNavigated = this._renderNavigated; + this._renderNavigated = this.rows.some(row => row.navigated); + if (renderNavigated !== this._renderNavigated) { + this.rows.forEach(row => row._renderNavigated = this._renderNavigated); + } + this.style.setProperty(getScopedVarName("--ui5_grid_sticky_top"), this.stickyTop); this._refreshPopinState(); } @@ -487,6 +503,9 @@ class Table extends UI5Element { } return `minmax(${cell.width}, ${cell.width})`; })); + if (this._renderNavigated) { + widths.push(`var(${getScopedVarName("--_ui5_table_navigated_cell_width")})`); + } return widths.join(" "); } diff --git a/packages/main/src/TableRow.hbs b/packages/main/src/TableRow.hbs index 00e559424f79..9ce5f7951a41 100644 --- a/packages/main/src/TableRow.hbs +++ b/packages/main/src/TableRow.hbs @@ -21,6 +21,10 @@ {{/each}} +{{#if _renderNavigated}} + +{{/if}} + {{#if _popinCells.length}} {{#each _popinCells}} diff --git a/packages/main/src/TableRow.ts b/packages/main/src/TableRow.ts index 8699c6313561..15a5a9a9bc0c 100644 --- a/packages/main/src/TableRow.ts +++ b/packages/main/src/TableRow.ts @@ -69,6 +69,18 @@ class TableRow extends TableRowBase { @property({ type: Boolean }) interactive = false; + /** + * Defines the navigated state of the row. + * + * @default false + * @public + */ + @property({ type: Boolean }) + navigated = false; + + @property({ type: Boolean, noAttribute: true }) + _renderNavigated = false; + static async onDefine() { await super.onDefine(); if (isSafari() && isIOS()) { @@ -80,6 +92,11 @@ class TableRow extends TableRowBase { onBeforeRendering() { super.onBeforeRendering(); this.toggleAttribute("_interactive", this._isInteractive); + if (this._renderNavigated && this.navigated) { + this.setAttribute("aria-current", "true"); + } else { + this.removeAttribute("aria-current"); + } } async focus(focusOptions?: FocusOptions | undefined): Promise { diff --git a/packages/main/src/themes/TableRow.css b/packages/main/src/themes/TableRow.css index a858ce1f6863..27e968660340 100644 --- a/packages/main/src/themes/TableRow.css +++ b/packages/main/src/themes/TableRow.css @@ -31,4 +31,18 @@ align-content: initial; flex-direction: column; grid-column: 1 / -1; -} \ No newline at end of file +} + +#navigated-cell { + grid-row: span 2; + min-width: 0; + padding: 0; +} + +:host([navigated]) #navigated-cell { + background-color: var(--sapList_SelectionBorderColor); +} + +:host([navigated]) #popin-cell { + grid-column: 1 / -2; +} diff --git a/packages/main/src/themes/base/Table-parameters.css b/packages/main/src/themes/base/Table-parameters.css index b085a711c09e..970efb577542 100644 --- a/packages/main/src/themes/base/Table-parameters.css +++ b/packages/main/src/themes/base/Table-parameters.css @@ -1,4 +1,5 @@ :root { --_ui5_table_cell_valign: center; --_ui5_table_cell_min_width: 2.75rem; + --_ui5_table_navigated_cell_width: 0.25rem; } \ No newline at end of file diff --git a/packages/main/test/pages/Table.html b/packages/main/test/pages/Table.html index 7161e69e3d2f..4f61319ca860 100644 --- a/packages/main/test/pages/Table.html +++ b/packages/main/test/pages/Table.html @@ -35,7 +35,7 @@ Weight Price - + Notebook Basic 15
HT-1000
Very Best Screens 30 x 18 x 3 cm diff --git a/packages/main/test/pages/TableLoading.html b/packages/main/test/pages/TableLoading.html index 645d5ed276b7..8239b788ed24 100644 --- a/packages/main/test/pages/TableLoading.html +++ b/packages/main/test/pages/TableLoading.html @@ -14,7 +14,10 @@ ColumnA - + + Cell A + + Cell A diff --git a/packages/main/test/specs/Table.spec.js b/packages/main/test/specs/Table.spec.js index edb09264ae7f..632e779b698e 100644 --- a/packages/main/test/specs/Table.spec.js +++ b/packages/main/test/specs/Table.spec.js @@ -196,4 +196,41 @@ describe("Table - Fixed Header", async () => { assert.isAbove(headerYPosition, 50, "Header is above the viewport and above the toolbar"); assert.ok(headerRow.isDisplayedInViewport(), "Header is displayed in the viewport"); }); +}); + +// Tests navigated property of rows +describe("Table - Navigated Rows", async () => { + before(async () => { + await browser.url(`test/pages/TableLoading.html`); + }); + + it("Navigated cell is rendered", async () => { + await browser.executeAsync(done => { + document.getElementById("row1").navigated = true; + done(); + }); + + const row1 = await browser.$("#row1"); + const row2 = await browser.$("#row1"); + const navigatedCell1 = await row1.shadow$("#navigated-cell"); + const navigatedCell2 = await row1.shadow$("#navigated-cell"); + + assert.ok(await navigatedCell1.isExisting(), "The navigated cell is rendered for the row with navigated=true"); + assert.ok(await navigatedCell2.isExisting(), "The navigated cell is also rendered for the row with navigated=false"); + assert.strictEqual(await navigatedCell1.getAttribute("excluded-from-navigation"), "", "The navigated cell is excluded from item navigation"); + assert.strictEqual(await navigatedCell2.getAttribute("excluded-from-navigation"), "", "The navigated cell is excluded from item navigation"); + + const navigatedCell1BG = await browser.executeAsync(done => { + done(getComputedStyle(document.getElementById("row1").shadowRoot.querySelector("#navigated-cell")).backgroundColor); + }); + const navigatedCell2BG = await browser.executeAsync(done => { + done(getComputedStyle(document.getElementById("row2").shadowRoot.querySelector("#navigated-cell")).backgroundColor); + }); + assert.notEqual(navigatedCell1BG, navigatedCell2BG, "Background color of navigated cell is different from the one of non-navigated cell"); + + const gridTemplateColumns = await browser.executeAsync(done => { + done(document.getElementById("table1").shadowRoot.querySelector("#table").style.gridTemplateColumns); + }); + assert.ok(gridTemplateColumns.endsWith("table_navigated_cell_width)"), "gridTemplateColumns is correct"); + }); }); \ No newline at end of file