-
Notifications
You must be signed in to change notification settings - Fork 16
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
[PBNTR-702] Create a "stickyLeftcolumn" prop for the Table kit - RAIL…
…S only (#3970) **What does this PR do?** A clear and concise description with your runway ticket url. As a Playbook user, I want to create a "stickyLeftcolumn" prop for our [Rails Table kit](https://playbook.powerapp.cloud/kits/table/rails), so that I can begin implementing a Frozen column for our Table kits. **Screenshots:** Screenshots to visualize your addition/change ![Screenshot 2024-12-03 at 8 15 05 AM](https://github.com/user-attachments/assets/78dc4640-c43f-4e81-b7e1-4a52d6a93e7c) #### Checklist: - [x] **LABELS** Add a label: `enhancement`, `bug`, `improvement`, `new kit`, `deprecated`, or `breaking`. See [Changelog & Labels](https://github.com/powerhome/playbook/wiki/Changelog-&-Labels) for details. - [x] **DEPLOY** I have added the `milano` label to show I'm ready for a review. - [x] **TESTS** I have added test coverage to my code.
- Loading branch information
Showing
5 changed files
with
214 additions
and
29 deletions.
There are no files selected for viewing
95 changes: 95 additions & 0 deletions
95
playbook/app/pb_kits/playbook/pb_table/docs/_table_sticky_left_columns.html.erb
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,95 @@ | ||
<%= pb_rails("table", props: { size: "md", responsive: "scroll", sticky_left_column: ["1", "2", "3"] }) do %> | ||
<thead> | ||
<tr> | ||
<th id="1">Column 1</th> | ||
<th id="2">Column 2</th> | ||
<th id="3">Column 3</th> | ||
<th>Column 4</th> | ||
<th>Column 5</th> | ||
<th>Column 6</th> | ||
<th>Column 7</th> | ||
<th>Column 8</th> | ||
<th>Column 9</th> | ||
<th>Column 10</th> | ||
<th>Column 11</th> | ||
<th>Column 12</th> | ||
<th>Column 13</th> | ||
<th>Column 14</th> | ||
<th>Column 15</th> | ||
</tr> | ||
</thead> | ||
<tbody> | ||
<tr> | ||
<td id="1">Value 1</td> | ||
<td id="2">Value 2</td> | ||
<td id="3">Value 3</td> | ||
<td>Value 4</td> | ||
<td>Value 5</td> | ||
<td>Column 6</td> | ||
<td>Column 7</td> | ||
<td>Column 8</td> | ||
<td>Column 9</td> | ||
<td>Column 10</td> | ||
<td>Column 11</td> | ||
<td>Column 12</td> | ||
<td>Column 13</td> | ||
<td>Column 14</td> | ||
<td>Column 15</td> | ||
|
||
</tr> | ||
<tr> | ||
<td id="1">Value 1</td> | ||
<td id="2">Value 2</td> | ||
<td id="3">Value 3</td> | ||
<td>Value 4</td> | ||
<td>Value 5</td> | ||
<td>Column 6</td> | ||
<td>Column 7</td> | ||
<td>Column 8</td> | ||
<td>Column 9</td> | ||
<td>Column 10</td> | ||
<td>Column 11</td> | ||
<td>Column 12</td> | ||
<td>Column 13</td> | ||
<td>Column 14</td> | ||
<td>Column 15</td> | ||
|
||
</tr> | ||
<tr> | ||
<td id="1">Value 1</td> | ||
<td id="2">Value 2</td> | ||
<td id="3">Value 3</td> | ||
<td>Value 4</td> | ||
<td>Value 5</td> | ||
<td>Column 6</td> | ||
<td>Column 7</td> | ||
<td>Column 8</td> | ||
<td>Column 9</td> | ||
<td>Column 10</td> | ||
<td>Column 11</td> | ||
<td>Column 12</td> | ||
<td>Column 13</td> | ||
<td>Column 14</td> | ||
<td>Column 15</td> | ||
|
||
</tr> | ||
<tr> | ||
<td id="1">Value 1</td> | ||
<td id="2">Value 2</td> | ||
<td id="3">Value 3</td> | ||
<td>Value 4</td> | ||
<td>Value 5</td> | ||
<td>Column 6</td> | ||
<td>Column 7</td> | ||
<td>Column 8</td> | ||
<td>Column 9</td> | ||
<td>Column 10</td> | ||
<td>Column 11</td> | ||
<td>Column 12</td> | ||
<td>Column 13</td> | ||
<td>Column 14</td> | ||
<td>Column 15</td> | ||
|
||
</tr> | ||
</tbody> | ||
<% end %> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,32 +1,106 @@ | ||
import PbEnhancedElement from '../pb_enhanced_element' | ||
|
||
export default class PbTable extends PbEnhancedElement { | ||
static get selector(): string { | ||
return '.table-responsive-collapse' | ||
} | ||
|
||
connect(): void { | ||
const tables = document.querySelectorAll('.table-responsive-collapse'); | ||
|
||
// Each Table | ||
[].forEach.call(tables, (table: HTMLTableElement) => { | ||
// Header Titles | ||
const headers: string[] = []; | ||
[].forEach.call(table.querySelectorAll('th'), (header: HTMLTableCellElement) => { | ||
const colSpan = header.colSpan | ||
for (let i = 0; i < colSpan; i++) { | ||
headers.push(header.textContent.replace(/\r?\n|\r/, '')); | ||
private stickyLeftColumns: string[] = []; | ||
private handleStickyColumnsRef: () => void; | ||
|
||
static get selector(): string { | ||
return '.table-responsive-collapse' | ||
} | ||
|
||
connect(): void { | ||
const tables = document.querySelectorAll('.table-responsive-collapse'); | ||
// Each Table | ||
[].forEach.call(tables, (table: HTMLTableElement) => { | ||
// Header Titles | ||
const headers: string[] = []; | ||
[].forEach.call(table.querySelectorAll('th'), (header: HTMLTableCellElement) => { | ||
const colSpan = header.colSpan | ||
for (let i = 0; i < colSpan; i++) { | ||
headers.push(header.textContent.replace(/\r?\n|\r/, '')); | ||
} | ||
}); | ||
// for each row in tbody | ||
[].forEach.call(table.querySelectorAll('tbody tr'), (row: HTMLTableRowElement) => { | ||
// for each cell | ||
[].forEach.call(row.cells, (cell: HTMLTableCellElement, headerIndex: number) => { | ||
// apply the attribute | ||
cell.setAttribute('data-title', headers[headerIndex]) | ||
}) | ||
}) | ||
}); | ||
|
||
// New sticky columns logic | ||
this.initStickyColumns(); | ||
} | ||
|
||
private initStickyColumns(): void { | ||
// Find tables with sticky-left-column class | ||
const tables = document.querySelectorAll('.sticky-left-column'); | ||
|
||
tables.forEach((table) => { | ||
// Extract sticky left column IDs by looking at the component's class | ||
const classList = Array.from(table.classList); | ||
|
||
// Look for classes in the format sticky-left-column-{ids} | ||
const stickyColumnClass = classList.find(cls => cls.startsWith('sticky-columns-')); | ||
if (stickyColumnClass) { | ||
// Extract the IDs from the class name | ||
this.stickyLeftColumns = stickyColumnClass | ||
.replace('sticky-columns-', '') | ||
.split('-'); | ||
|
||
if (this.stickyLeftColumns.length > 0) { | ||
this.handleStickyColumnsRef = this.handleStickyColumns.bind(this); | ||
this.handleStickyColumns(); | ||
window.addEventListener('resize', this.handleStickyColumnsRef); | ||
} | ||
} | ||
}); | ||
} | ||
|
||
// for each row in tbody | ||
[].forEach.call(table.querySelectorAll('tbody tr'), (row: HTMLTableRowElement) => { | ||
// for each cell | ||
[].forEach.call(row.cells, (cell: HTMLTableCellElement, headerIndex: number) => { | ||
// apply the attribute | ||
cell.setAttribute('data-title', headers[headerIndex]) | ||
}) | ||
}) | ||
}) | ||
} | ||
} | ||
private handleStickyColumns(): void { | ||
let accumulatedWidth = 0; | ||
|
||
this.stickyLeftColumns.forEach((colId, index) => { | ||
const isLastColumn = index === this.stickyLeftColumns.length - 1; | ||
const header = document.querySelector(`th[id="${colId}"]`); | ||
const cells = document.querySelectorAll(`td[id="${colId}"]`); | ||
|
||
if (header) { | ||
header.classList.add('sticky'); | ||
(header as HTMLElement).style.left = `${accumulatedWidth}px`; | ||
|
||
if (!isLastColumn) { | ||
header.classList.add('with-border'); | ||
header.classList.remove('sticky-shadow'); | ||
} else { | ||
header.classList.remove('with-border'); | ||
header.classList.add('sticky-shadow'); | ||
} | ||
|
||
accumulatedWidth += (header as HTMLElement).offsetWidth; | ||
} | ||
|
||
cells.forEach((cell) => { | ||
cell.classList.add('sticky'); | ||
(cell as HTMLElement).style.left = `${accumulatedWidth - (header as HTMLElement).offsetWidth}px`; | ||
|
||
if (!isLastColumn) { | ||
cell.classList.add('with-border'); | ||
cell.classList.remove('sticky-shadow'); | ||
} else { | ||
cell.classList.remove('with-border'); | ||
cell.classList.add('sticky-shadow'); | ||
} | ||
}); | ||
}); | ||
} | ||
|
||
// Cleanup method to remove event listener | ||
disconnect(): void { | ||
if (this.handleStickyColumnsRef) { | ||
window.removeEventListener('resize', this.handleStickyColumnsRef); | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -18,4 +18,4 @@ | |
<%= content.presence %> | ||
<% end %> | ||
<% end %> | ||
<% end %> | ||
<% end %> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters