+
Large Table
+
+
+
+
@@ -209,9 +220,11 @@
const headerButtons = headerCells.map((cell) => cell.querySelector('.sg-large-table__sort-button'));
const rows = Array.from(table.querySelectorAll('[data-component-part="large-table-row"]'));
const headerRow = table.querySelector('[data-component-part="large-table-header-row"]');
+ const searchInput = table.querySelector('[data-large-table-search]');
const state = {
columnIndex: 0,
direction: 'ascending',
+ query: '',
};
function setHeaderState(activeIndex, direction) {
@@ -251,21 +264,33 @@
return direction === 'ascending' ? comparison : -comparison;
}
- function sortRows(columnIndex, direction) {
+ function rowMatchesQuery(row, query) {
+ if (!query) {
+ return true;
+ }
+
+ return Array.from(row.querySelectorAll('[role="cell"]')).some((cell) => {
+ const value = cell.textContent || '';
+ return value.toLowerCase().includes(query);
+ });
+ }
+
+ function renderRows() {
const sortedRows = rows.slice().sort((leftRow, rightRow) => {
- const leftCell = leftRow.querySelectorAll('[role="cell"]')[columnIndex];
- const rightCell = rightRow.querySelectorAll('[role="cell"]')[columnIndex];
+ const leftCell = leftRow.querySelectorAll('[role="cell"]')[state.columnIndex];
+ const rightCell = rightRow.querySelectorAll('[role="cell"]')[state.columnIndex];
const leftValue = leftCell ? leftCell.textContent : '';
const rightValue = rightCell ? rightCell.textContent : '';
- return compareValues(leftValue, rightValue, direction);
+ return compareValues(leftValue, rightValue, state.direction);
});
sortedRows.forEach((row) => {
table.appendChild(row);
+ row.hidden = !rowMatchesQuery(row, state.query);
});
- setHeaderState(columnIndex, direction);
+ setHeaderState(state.columnIndex, state.direction);
}
headerButtons.forEach((button, index) => {
@@ -280,14 +305,21 @@
state.columnIndex = index;
state.direction = direction;
- sortRows(index, direction);
+ renderRows();
});
});
+ if (searchInput) {
+ searchInput.addEventListener('input', () => {
+ state.query = searchInput.value.trim().toLowerCase();
+ renderRows();
+ });
+ }
+
if (headerRow) {
setHeaderState(state.columnIndex, state.direction);
}
- sortRows(state.columnIndex, state.direction);
+ renderRows();
})();
diff --git a/styles/42-components-data-display.css b/styles/42-components-data-display.css
index fc9349d..8b0b8e0 100644
--- a/styles/42-components-data-display.css
+++ b/styles/42-components-data-display.css
@@ -71,6 +71,49 @@
width: 100%;
}
+.sg-large-table__title-segment {
+ flex-direction: row;
+ align-items: center;
+ justify-content: space-between;
+ gap: var(--spacing-large);
+}
+
+.sg-large-table__search {
+ display: flex;
+ align-items: center;
+ justify-content: flex-end;
+ gap: var(--spacing-small);
+ margin-left: auto;
+}
+
+.sg-large-table__search-label {
+ color: var(--text-card-header);
+ font-family: var(--font-family-base);
+ font-size: var(--font-size-small);
+ font-weight: var(--font-weight-semibold);
+ line-height: var(--line-height-base);
+ white-space: nowrap;
+}
+
+.sg-large-table__search-input {
+ width: 14rem;
+ max-width: 100%;
+ box-sizing: border-box;
+ padding: 0.35rem var(--spacing-small);
+ border: var(--border-none);
+ border-radius: var(--radius-card);
+ background: var(--color-white);
+ color: var(--text-control-default);
+ font-family: var(--font-family-base);
+ font-size: var(--font-size-small);
+ line-height: var(--line-height-base);
+}
+
+.sg-large-table__search-input:focus-visible {
+ outline: 2px solid var(--color-white);
+ outline-offset: 2px;
+}
+
.sg-large-table__row {
display: grid;
grid-template-columns: repeat(5, minmax(0, 1fr));