diff --git a/src/components-examples/material/table/index.ts b/src/components-examples/material/table/index.ts
index dba3386450d4..9d40b1f958a3 100644
--- a/src/components-examples/material/table/index.ts
+++ b/src/components-examples/material/table/index.ts
@@ -1,5 +1,6 @@
export {TableFlexBasicExample} from './table-flex-basic/table-flex-basic-example';
export {TableBasicExample} from './table-basic/table-basic-example';
+export {TableRowspanExample} from './table-rowspan/table-rowspan-example';
export {TableDynamicColumnsExample} from './table-dynamic-columns/table-dynamic-columns-example';
export {TableExpandableRowsExample} from './table-expandable-rows/table-expandable-rows-example';
export {TableFilteringExample} from './table-filtering/table-filtering-example';
diff --git a/src/components-examples/material/table/table-rowspan/table-rowspan-example.css b/src/components-examples/material/table/table-rowspan/table-rowspan-example.css
new file mode 100644
index 000000000000..c564ca85b4f6
--- /dev/null
+++ b/src/components-examples/material/table/table-rowspan/table-rowspan-example.css
@@ -0,0 +1,8 @@
+table {
+ width: 100%;
+}
+
+th,
+td {
+ vertical-align: top;
+}
diff --git a/src/components-examples/material/table/table-rowspan/table-rowspan-example.html b/src/components-examples/material/table/table-rowspan/table-rowspan-example.html
new file mode 100644
index 000000000000..41538e5dc362
--- /dev/null
+++ b/src/components-examples/material/table/table-rowspan/table-rowspan-example.html
@@ -0,0 +1,38 @@
+
+
+
+
+ | Element |
+
+
+
+ {{row.element}}
+ |
+
+
+
+
+ Isotope |
+
+
+ {{row.isotope}}
+ |
+
+
+
+
+ Weight |
+
+
+ {{row.weight}}
+ |
+
+
+
+
+
+
diff --git a/src/components-examples/material/table/table-rowspan/table-rowspan-example.ts b/src/components-examples/material/table/table-rowspan/table-rowspan-example.ts
new file mode 100644
index 000000000000..4f88397ad546
--- /dev/null
+++ b/src/components-examples/material/table/table-rowspan/table-rowspan-example.ts
@@ -0,0 +1,66 @@
+import {Component} from '@angular/core';
+import {MatTableModule} from '@angular/material/table';
+
+export interface IsotopeData {
+ position: number;
+ element: string;
+ isotope: string;
+ weight: number;
+}
+
+const ISOTOPE_DATA: IsotopeData[] = [
+ {position: 1, element: 'Hydrogen', isotope: 'Protium', weight: 1.0078},
+ {position: 2, element: 'Hydrogen', isotope: 'Deuterium', weight: 2.0141},
+ {position: 3, element: 'Hydrogen', isotope: 'Tritium', weight: 3.016},
+ {position: 4, element: 'Helium', isotope: 'Helium-3', weight: 3.016},
+ {position: 5, element: 'Helium', isotope: 'Helium-4', weight: 4.0026},
+];
+
+/**
+ * @title Table with merged rows using rowspan
+ */
+@Component({
+ selector: 'table-rowspan-example',
+ styleUrl: 'table-rowspan-example.css',
+ templateUrl: 'table-rowspan-example.html',
+ imports: [MatTableModule],
+})
+export class TableRowspanExample {
+ displayedColumns: string[] = ['element', 'isotope', 'weight'];
+
+ dataSource: IsotopeData[] = ISOTOPE_DATA;
+
+ spans: Record[] = [];
+
+ constructor() {
+ this._cacheSpan('element', row => row.element);
+ }
+
+ /** Caches rowspan values for a column. */
+ private _cacheSpan(key: string, accessor: (row: IsotopeData) => string): void {
+ for (let i = 0; i < this.dataSource.length;) {
+ const currentValue = accessor(this.dataSource[i]);
+ let count = 1;
+
+ for (let j = i + 1; j < this.dataSource.length; j++) {
+ if (currentValue !== accessor(this.dataSource[j])) {
+ break;
+ }
+
+ count++;
+ }
+
+ if (!this.spans[i]) {
+ this.spans[i] = {};
+ }
+
+ this.spans[i][key] = count;
+ i += count;
+ }
+ }
+
+ /** Returns the rowspan for an element cell. */
+ getRowSpan(column: 'element', index: number): number | undefined {
+ return this.spans[index]?.[column];
+ }
+}
diff --git a/src/dev-app/table/table-demo.html b/src/dev-app/table/table-demo.html
index 3d1e98d2ccc4..41fffb28d572 100644
--- a/src/dev-app/table/table-demo.html
+++ b/src/dev-app/table/table-demo.html
@@ -46,6 +46,9 @@ Table with multiple headers and footers
Table overview
+Table with rowspan
+
+
Table row context
diff --git a/src/dev-app/table/table-demo.ts b/src/dev-app/table/table-demo.ts
index 392101493ad8..766595cf7630 100644
--- a/src/dev-app/table/table-demo.ts
+++ b/src/dev-app/table/table-demo.ts
@@ -31,6 +31,7 @@ import {
TableRecycleRowsExample,
TableReorderableExample,
TableRowContextExample,
+ TableRowspanExample,
TableSelectionExample,
TableSortingExample,
TableStickyColumnsExample,
@@ -65,6 +66,7 @@ import {
TablePaginationExample,
TableVirtualScrollExample,
TableRowContextExample,
+ TableRowspanExample,
TableSelectionExample,
TableSortingExample,
TableStickyColumnsExample,