diff --git a/packages/main/src/Table.ts b/packages/main/src/Table.ts
index 709c3a65c792..1a03806967c8 100644
--- a/packages/main/src/Table.ts
+++ b/packages/main/src/Table.ts
@@ -465,9 +465,16 @@ class Table extends UI5Element {
}
get styles() {
+ const headerStyleMap = this.headerRow?.[0]?.cells?.reduce((headerStyles, headerCell) => {
+ if (headerCell.horizontalAlign !== undefined) {
+ headerStyles[`--horizontal-align-${headerCell._individualSlot}`] = headerCell.horizontalAlign;
+ }
+ return headerStyles;
+ }, {} as { [key: string]: string });
return {
table: {
"grid-template-columns": this._gridTemplateColumns,
+ ...headerStyleMap,
},
};
}
diff --git a/packages/main/src/TableCell.ts b/packages/main/src/TableCell.ts
index f749d1ff591b..68725811ad8b 100644
--- a/packages/main/src/TableCell.ts
+++ b/packages/main/src/TableCell.ts
@@ -30,6 +30,15 @@ import { LABEL_COLON } from "./generated/i18n/i18n-defaults.js";
template: TableCellTemplate,
})
class TableCell extends TableCellBase {
+ onBeforeRendering() {
+ super.onBeforeRendering();
+ if (this.horizontalAlign) {
+ this.style.justifyContent = this.horizontalAlign;
+ } else {
+ this.style.justifyContent = `var(--horizontal-align-${(this as any)._individualSlot})`;
+ }
+ }
+
get _popinHeader() {
const row = this.parentElement as TableRow;
const table = row.parentElement as Table;
diff --git a/packages/main/src/TableCellBase.ts b/packages/main/src/TableCellBase.ts
index 6abffab2b098..ffaf468087ae 100644
--- a/packages/main/src/TableCellBase.ts
+++ b/packages/main/src/TableCellBase.ts
@@ -6,6 +6,7 @@ import property from "@ui5/webcomponents-base/dist/decorators/property.js";
import type I18nBundle from "@ui5/webcomponents-base/dist/i18nBundle.js";
import { getI18nBundle } from "@ui5/webcomponents-base/dist/i18nBundle.js";
import TableCellBaseStyles from "./generated/themes/TableCellBase.css.js";
+import type TableCellHorizontalAlign from "./types/TableCellHorizontalAlign.js";
/**
* @class
@@ -31,6 +32,17 @@ abstract class TableCellBase extends UI5Element {
@property({ type: Boolean })
_popin = false;
+ /**
+ * Determines the horizontal alignment of table cells.
+ * Note: All values valid for justify-content can be used not just the ones inside the enum.
+ * @default undefined
+ * @public
+ */
+ @property()
+ horizontalAlign?: `${TableCellHorizontalAlign}`;
+
+ _individualSlot?: string;
+
protected ariaRole: string = "gridcell";
static i18nBundle: I18nBundle;
diff --git a/packages/main/src/TableHeaderCell.ts b/packages/main/src/TableHeaderCell.ts
index bd9e89328fc8..0c318c1291a4 100644
--- a/packages/main/src/TableHeaderCell.ts
+++ b/packages/main/src/TableHeaderCell.ts
@@ -85,6 +85,12 @@ class TableHeaderCell extends TableCellBase {
this.style.maxWidth = this.maxWidth;
this.style.width = this.width;
}
+
+ onBeforeRendering() {
+ super.onBeforeRendering();
+ // overwrite setting of TableCellBase so that the TableHeaderCell always uses the slot variable
+ this.style.justifyContent = `var(--horizontal-align-${this._individualSlot})`;
+ }
}
TableHeaderCell.define();
diff --git a/packages/main/src/TableHeaderRow.ts b/packages/main/src/TableHeaderRow.ts
index f2f68090f859..c839e7977c1e 100644
--- a/packages/main/src/TableHeaderRow.ts
+++ b/packages/main/src/TableHeaderRow.ts
@@ -56,7 +56,7 @@ class TableHeaderRow extends TableRowBase {
type: HTMLElement,
"default": true,
invalidateOnChildChange: {
- properties: ["width", "_popin"],
+ properties: ["width", "_popin", "horizontalAlign"],
slots: false,
},
individualSlots: true,
diff --git a/packages/main/src/types/TableCellHorizontalAlign.ts b/packages/main/src/types/TableCellHorizontalAlign.ts
new file mode 100644
index 000000000000..06b39225fd37
--- /dev/null
+++ b/packages/main/src/types/TableCellHorizontalAlign.ts
@@ -0,0 +1,33 @@
+/**
+ * Alignment of the <ui5-table-cell> component.
+ *
+ * @public
+ */
+enum TableCellHorizontalAlign {
+ /**
+ * @public
+ */
+ Left = "Left",
+
+ /**
+ * @public
+ */
+ Start = "Start",
+
+ /**
+ * @public
+ */
+ Right = "Right",
+
+ /**
+ * @public
+ */
+ End = "End",
+
+ /**
+ * @public
+ */
+ Center = "Center",
+}
+
+export default TableCellHorizontalAlign;
diff --git a/packages/main/test/pages/HAlignTable.html b/packages/main/test/pages/HAlignTable.html
new file mode 100644
index 000000000000..1a64c4933b0e
--- /dev/null
+++ b/packages/main/test/pages/HAlignTable.html
@@ -0,0 +1,46 @@
+
+
+
+
+
+
+
+ Table (horizontal alignment)
+
+
+
+
+
+
+ Product
+ Supplier
+ Dimensions
+ Weight
+ Price
+
+
+ Notebook Basic 15
HT-1000
+ Very Best Screens
+ 30 x 18 x 3 cm
+ 4.2 KG
+ 956 EUR
+
+
+ Notebook Basic 17
HT-1001
+ Smartcards
+ 29 x 17 x 3.1 cm
+ 4.5 KG
+ 1249 EUR
+
+
+ Notebook Basic 18
HT-1002
+ Technocom
+ 32 x 21 x 4 cm
+ 3.7 KG
+ 29 EUR
+
+
+
+
+
+
diff --git a/packages/main/test/specs/Table.spec.js b/packages/main/test/specs/Table.spec.js
index 508d5467c4db..69325edaf986 100644
--- a/packages/main/test/specs/Table.spec.js
+++ b/packages/main/test/specs/Table.spec.js
@@ -156,6 +156,248 @@ describe("Table - Popin Mode", async () => {
});
});
+describe("Table - Horizontal alignment of cells", async () => {
+ beforeEach(async () => {
+ await browser.url(`test/pages/HAlignTable.html`);
+ });
+
+ it("default alignment when horizontalAlign is not set", async () => {
+ let table = await browser.$("#table");
+ assert.ok(table.isExisting(), "Table exists");
+
+ const headerRow = await table.$("ui5-table-header-row");
+ const headerCells = await headerRow.$$("ui5-table-header-cell");
+ assert.equal(headerCells.length, 5, "5 columns exist");
+
+ const index = 0;
+ const headerCell = headerCells[index];
+ const alignment = "normal";
+ assert.equal(await headerCell.getAttribute("id"), "productCol", "Correct cell");
+ assert.equal(await headerCell.getAttribute("horizontal-align"), undefined, "horizontalAlign not set");
+
+ const justifyContentHeaderCell = await headerCell.getCSSProperty("justify-content");
+ const style = await headerCell.getAttribute("style");
+ const justifyContentHeaderCellUncomputed = style.match(/justify-content: ([^;]+)/)[1];
+ const cssVariable = "var(--horizontal-align-default-1)";
+ assert.equal(justifyContentHeaderCell.value, alignment, "justify-content correctly set.");
+ assert.equal(justifyContentHeaderCellUncomputed, cssVariable, "horizontalAlign not set");
+
+ const tableRows = await table.$$("ui5-table-row");
+ for (const row of tableRows) {
+ const rowCells = await row.$$("ui5-table-cell");
+ const justifyContent = await rowCells[3].getCSSProperty("justify-content");
+
+ assert.equal(justifyContent.value, alignment, "justify-content correctly set.");
+ }
+ });
+
+ it("horizontal alignment if horizontalAlign is set to a value not defined in TableCellHorizontalAlign", async () => {
+ let table = await browser.$("#table");
+ assert.ok(table.isExisting(), "Table exists");
+
+ const headerRow = await table.$("ui5-table-header-row");
+ const headerCells = await headerRow.$$("ui5-table-header-cell");
+ assert.equal(headerCells.length, 5, "5 columns exist");
+
+ const index = 0;
+ const headerCell = headerCells[index];
+ assert.equal(await headerCell.getAttribute("id"), "productCol", "Correct cell");
+
+ let alignment = "right";
+ await headerCell.setAttribute("horizontal-align", "Right");
+
+ let justifyContentHeaderCell = await headerCell.getCSSProperty("justify-content");
+ let style = await headerCell.getAttribute("style");
+ let justifyContentHeaderCellUncomputed = style.match(/justify-content: ([^;]+)/)[1];
+ const cssVariable = "var(--horizontal-align-default-1)";
+ assert.equal(justifyContentHeaderCell.value, alignment, "justify-content correctly set.");
+ assert.equal(justifyContentHeaderCellUncomputed, cssVariable, "horizontalAlign set to css variable");
+
+ alignment = "normal";
+ let hAlign = "valueNotDefinedInEnum";
+ await headerCell.setAttribute("horizontal-align", hAlign);
+
+ assert.equal(await headerCell.getAttribute("horizontal-align"), hAlign, "horizontalAlign correctly set");
+ justifyContentHeaderCell = await headerCell.getCSSProperty("justify-content");
+ assert.equal(justifyContentHeaderCell.value, alignment, "justify-content correctly set.");
+ style = await headerCell.getAttribute("style");
+ justifyContentHeaderCellUncomputed = style.match(/justify-content: ([^;]+)/)[1];
+ assert.equal(justifyContentHeaderCellUncomputed, cssVariable, "horizontalAlign set to css variable");
+
+ const tableRows = await table.$$("ui5-table-row");
+ for (const row of tableRows) {
+ const rowCells = await row.$$("ui5-table-cell");
+ const justifyContent = await rowCells[3].getCSSProperty("justify-content");
+
+ assert.equal(justifyContent.value, alignment, "justify-content correctly set.");
+ }
+ });
+
+ it("cells have same alignment as their headerCell", async () => {
+ let table = await browser.$("#table");
+ assert.ok(table.isExisting(), "Table exists");
+
+ const headerRow = await table.$("ui5-table-header-row");
+ const headerCells = await headerRow.$$("ui5-table-header-cell");
+ assert.equal(headerCells.length, 5, "5 columns exist");
+
+ const cellIndex = 1; // second row is supplier row
+ const headerCell = headerCells[cellIndex];
+ const id = await headerCell.getAttribute("id");
+ const hAlign = await headerCell.getAttribute("horizontal-align");
+ assert.equal(id, "supplierCol", "Correct cell");
+ assert.ok(hAlign, "horizontalAlign set");
+
+ const alignment = `center`; // alignment set to center in table example
+ const justifyContentHeaderCell = await headerCell.getCSSProperty("justify-content");
+ assert.equal(justifyContentHeaderCell.value, alignment, "justify-content correctly set.");
+
+ const tableRows = await table.$$("ui5-table-row");
+ for (const row of tableRows) {
+ const rowCells = await row.$$("ui5-table-cell");
+ const justifyContent = await rowCells[cellIndex].getCSSProperty("justify-content");
+
+ assert.equal(justifyContent.value, alignment, "justify-content correctly set.");
+ }
+ });
+
+ it("on changing the horizontal-alignment of the headerCell, the horizontal-alignment of subsequent cells must change as well", async () => {
+ let table = await browser.$("#table");
+ assert.ok(table.isExisting(), "Table exists");
+
+ const headerRow = await table.$("ui5-table-header-row");
+ const headerCells = await headerRow.$$("ui5-table-header-cell");
+ assert.equal(headerCells.length, 5, "5 columns exist");
+
+ // test setup
+ const cellIndex = 1; // second row is supplier row
+ const headerCell = headerCells[cellIndex];
+ const id = await headerCell.getAttribute("id");
+ let hAlign = await headerCell.getAttribute("horizontal-align");
+ assert.equal(id, "supplierCol", "Correct cell");
+ assert.ok(hAlign, "horizontalAlign set");
+
+ let alignment = `center`; // alignment set to center in table example
+ let justifyContentHeaderCell = await headerCell.getCSSProperty("justify-content");
+ assert.equal(justifyContentHeaderCell.value, alignment, "justify-content correctly set.");
+
+ // update the values
+ alignment = "left";
+ await headerCell.setAttribute("horizontal-align", "Left");
+ hAlign = await headerCell.getAttribute("horizontal-align");
+ justifyContentHeaderCell = await headerCell.getCSSProperty("justify-content");
+
+ assert.equal(id, "supplierCol", "Correct cell");
+ assert.ok(hAlign, "horizontalAlign set");
+ assert.equal(justifyContentHeaderCell.value, alignment, "justify-content value updated.");
+
+ const tableRows = await table.$$("ui5-table-row");
+ for (const row of tableRows) {
+ const rowCells = await row.$$("ui5-table-cell");
+ const justifyContent = await rowCells[cellIndex].getCSSProperty("justify-content");
+
+ assert.equal(justifyContent.value, alignment, "justify-content correctly set.");
+ }
+ });
+
+ it("on changing the horizontal-alignment of a cell, the horizontal-alignment of other cells must not change", async () => {
+ let table = await browser.$("#table");
+ assert.ok(table.isExisting(), "Table exists");
+
+ const headerRow = await table.$("ui5-table-header-row");
+ const headerCells = await headerRow.$$("ui5-table-header-cell");
+ assert.equal(headerCells.length, 5, "5 columns exist");
+
+ const cellIndex = 1; // second row is supplier row
+ const headerCell = headerCells[cellIndex];
+ const id = await headerCell.getAttribute("id");
+ const hAlign = await headerCell.getAttribute("horizontal-align");
+ assert.equal(id, "supplierCol", "Correct cell");
+ assert.ok(hAlign, "horizontalAlign set");
+
+ const alignment = `center`; // alignment set to center in table example
+ const justifyContentHeaderCell = await headerCell.getCSSProperty("justify-content");
+ assert.equal(justifyContentHeaderCell.value, alignment, "justify-content value of the headerCell is correct.");
+
+ const tableRows = await table.$$("ui5-table-row");
+ const rowWithChangedCell = 0;
+ const cell = await tableRows[rowWithChangedCell].$$("ui5-table-cell")[cellIndex];
+ let hAlignCell = await cell.getAttribute("horizontal-align");
+ assert.equal(hAlignCell, null, "horizontalAlign property of the cell is not set.");
+
+ let justifyContentCell = await cell.getCSSProperty("justify-content");
+ assert.equal(justifyContentCell.value, alignment, "justify-content of the cell matches the headerCell");
+
+ const customAlignmentCell = "left"; // alignment used for a single cell
+ await cell.setAttribute("horizontal-align", "Left");
+ hAlignCell = await cell.getAttribute("horizontal-align");
+ assert.notEqual(hAlignCell, null, "horizontalAlign property of the cell is set now.");
+
+ justifyContentCell = await cell.getCSSProperty("justify-content");
+ assert.equal(justifyContentCell.value, customAlignmentCell, "justify-content was changed and now matches the custom cell alignment value.");
+
+ for (const [index, row] of tableRows.entries()) {
+ const rowCells = await row.$$("ui5-table-cell");
+ const justifyContent = await rowCells[cellIndex].getCSSProperty("justify-content");
+
+ // the alignment of every cell but the changed one still has to match the headerCell alignment
+ assert.equal(justifyContent.value, index === rowWithChangedCell ? customAlignmentCell : alignment, "justify-content correctly set.");
+ }
+ });
+
+ it("the horizontal-alignment of a cell differs from the others, on changing the horizontal-alignment of the headerCell, the horizontal-alignment of other cells must change as well except of this one custom aligned cell", async () => {
+ let table = await browser.$("#table");
+ assert.ok(table.isExisting(), "Table exists");
+
+ const headerRow = await table.$("ui5-table-header-row");
+ const headerCells = await headerRow.$$("ui5-table-header-cell");
+ assert.equal(headerCells.length, 5, "5 columns exist");
+
+ const cellIndex = 1; // second row is supplier row
+ const headerCell = headerCells[cellIndex];
+ const id = await headerCell.getAttribute("id");
+ const hAlign = await headerCell.getAttribute("horizontal-align");
+ assert.equal(id, "supplierCol", "Correct cell");
+ assert.ok(hAlign, "horizontalAlign set");
+
+ let alignment = "center"; // alignment set to center in table example
+ let justifyContent = await headerCell.getCSSProperty("justify-content");
+ assert.equal(justifyContent.value, alignment, "justify-content correctly set.");
+
+ const tableRows = await table.$$("ui5-table-row");
+ const rowWithChangedCell = 0;
+ const cell = await tableRows[rowWithChangedCell].$$("ui5-table-cell")[cellIndex];
+ let justifyContentCell = await cell.getCSSProperty("justify-content");
+ let hAlignCell = await cell.getAttribute("horizontal-align");
+ assert.equal(hAlignCell, null, "horizontalAlign property of the cell is not set.");
+ assert.equal(justifyContentCell.value, alignment, "justify-content value matches headerCell alignment");
+
+ const customAlignmentCell = "left"; // alignment used for a single cell
+ await cell.setAttribute("horizontal-align", "Left");
+ hAlignCell = await cell.getAttribute("horizontal-align");
+
+ assert.notEqual(hAlignCell, null, "horizontalAlign property of the cell is set now.");
+
+ justifyContentCell = await cell.getCSSProperty("justify-content");
+ assert.equal(justifyContentCell.value, customAlignmentCell, "justify-content of cell adjusted correctly.");
+
+ alignment = "right"
+ await headerCell.setAttribute("horizontal-align", "Right");
+ hAlignCell = await cell.getAttribute("horizontal-align");
+ justifyContent = await headerCell.getCSSProperty("justify-content");
+
+ assert.ok(hAlign, "horizontalAlign set");
+ assert.equal(justifyContent.value, alignment, "justify-content of headerCell changed correctly.");
+
+ for (const [index, row] of tableRows.entries()) {
+ const rowCells = await row.$$("ui5-table-cell");
+ const justifyContent = await rowCells[cellIndex].getCSSProperty("justify-content");
+
+ assert.equal(justifyContent.value, index === rowWithChangedCell ? customAlignmentCell : alignment, "justify-content correctly set.");
+ }
+ });
+});
+
// Tests for the fixed header, whether it is shown correctly and behaves as expected
describe("Table - Fixed Header", async () => {
before(async () => {
diff --git a/packages/website/docs/_components_pages/main/Table/TableCell.mdx b/packages/website/docs/_components_pages/main/Table/TableCell.mdx
index 18de9948c7b7..77c222924066 100644
--- a/packages/website/docs/_components_pages/main/Table/TableCell.mdx
+++ b/packages/website/docs/_components_pages/main/Table/TableCell.mdx
@@ -3,6 +3,22 @@ slug: ../../TableCell
sidebar_class_name: newComponentBadge expComponentBadge
---
+import HAlign from "../../../_samples/main/Table/HAlign/HAlign.md";
+
<%COMPONENT_OVERVIEW%>
<%COMPONENT_METADATA%>
+
+### Horizontal cell alignment
+
+Control the horizontal alignment of cells by utilizing the `horizontalAlign` property.
+
+Please note that the behaviour of `horizontalAlign` depends on where you set it:
+1. `horizontalAlign` is set on `TableHeaderCell` level
+Changes the horizontal alignment of the `TableHeaderCell` and their corresponding `TableCells`.
+2. `horizontalAlign` is set on `TableCell` level only
+The horizontal alignment is only changed for this one `TableCell`
+3. `horizontalAlign` is set on `TableHeaderCell` and `TableCell` level
+Changing the `horizontalAlign` property on `TableHeaderCell` level changes only the `TableHeaderCell` itself and those `TableCells` without a `horizontalAlign` property.
+
+
\ No newline at end of file
diff --git a/packages/website/docs/_components_pages/main/Table/TableHeaderCell.mdx b/packages/website/docs/_components_pages/main/Table/TableHeaderCell.mdx
index c91da75d5a9f..053c39cda2da 100644
--- a/packages/website/docs/_components_pages/main/Table/TableHeaderCell.mdx
+++ b/packages/website/docs/_components_pages/main/Table/TableHeaderCell.mdx
@@ -5,6 +5,7 @@ sidebar_class_name: newComponentBadge expComponentBadge
import Popin from "../../../_samples/main/Table/Popin/Popin.md";
import ColumnWidths from "../../../_samples/main/Table/ColumnWidths/ColumnWidths.md";
+import HAlign from "../../../_samples/main/Table/HAlign/HAlign.md";
<%COMPONENT_OVERVIEW%>
@@ -16,4 +17,18 @@ import ColumnWidths from "../../../_samples/main/Table/ColumnWidths/ColumnWidths
## Popin Configuration
-
\ No newline at end of file
+
+
+### Horizontal cell alignment
+
+Control the horizontal alignment of cells by utilizing the `horizontalAlign` property.
+
+Please note that the behaviour of `horizontalAlign` depends on where you set it:
+1. `horizontalAlign` is set on `TableHeaderCell` level
+Changes the horizontal alignment of the `TableHeaderCell` and their corresponding `TableCells`.
+2. `horizontalAlign` is set on `TableCell` level only
+The horizontal alignment is only changed for this one `TableCell`
+3. `horizontalAlign` is set on `TableHeaderCell` and `TableCell` level
+Changing the `horizontalAlign` property on `TableHeaderCell` level changes only the `TableHeaderCell` itself and those `TableCells` without a `horizontalAlign` property.
+
+
\ No newline at end of file
diff --git a/packages/website/docs/_samples/main/Table/HAlign/HAlign.md b/packages/website/docs/_samples/main/Table/HAlign/HAlign.md
new file mode 100644
index 000000000000..17798ecc59ab
--- /dev/null
+++ b/packages/website/docs/_samples/main/Table/HAlign/HAlign.md
@@ -0,0 +1,4 @@
+import html from '!!raw-loader!./sample.html';
+import js from '!!raw-loader!./main.js';
+
+
diff --git a/packages/website/docs/_samples/main/Table/HAlign/main.js b/packages/website/docs/_samples/main/Table/HAlign/main.js
new file mode 100644
index 000000000000..5eef1b6cc847
--- /dev/null
+++ b/packages/website/docs/_samples/main/Table/HAlign/main.js
@@ -0,0 +1,4 @@
+import "@ui5/webcomponents/dist/Table.js";
+import "@ui5/webcomponents/dist/TableHeaderRow.js";
+import "@ui5/webcomponents/dist/TableHeaderCell.js";
+import "@ui5/webcomponents/dist/Label.js";
\ No newline at end of file
diff --git a/packages/website/docs/_samples/main/Table/HAlign/sample.html b/packages/website/docs/_samples/main/Table/HAlign/sample.html
new file mode 100644
index 000000000000..fbe97336c48d
--- /dev/null
+++ b/packages/website/docs/_samples/main/Table/HAlign/sample.html
@@ -0,0 +1,50 @@
+
+
+
+
+
+
+
+ Sample
+
+
+
+
+
+
+
+ Product
+ Supplier
+ Dimensions
+ Weight
+ Price
+
+
+ Notebook Basic 15
HT-1000
+ Very Best Screens
+ 30 x 18 x 3 cm
+ 4.2 KG
+ 956 EUR
+
+
+ Notebook Basic 17
HT-1001
+ Smartcards
+ 29 x 17 x 3.1 cm
+ 4.5 KG
+ 1249 EUR
+
+
+ Notebook Basic 18
HT-1002
+ Technocom
+ 32 x 21 x 4 cm
+ 3.7 KG
+ 29 EUR
+
+
+
+
+
+
+
+
+