Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[RFC] Create table v2 to resolve performance issues #207

Merged
merged 3 commits into from
May 1, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
58 changes: 58 additions & 0 deletions src/components/organisms/TableV2/TableV2.css

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions src/components/organisms/TableV2/TableV2.css.map

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

64 changes: 64 additions & 0 deletions src/components/organisms/TableV2/TableV2.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
import styles from '!!raw-loader!./TableV2.css';
import varStyles from '!!raw-loader!../../../shared/variables.css';
import bootstrapStyles from '!!raw-loader!../../../shared/themed-bootstrap.css';

class TableV2 extends HTMLElement {
static observedAttributes = [];

constructor() {
// Always call super first in constructor
super();
// Create a shadow root
const shadow = this.attachShadow({ mode: 'open' });
// Add styles
const bootStyles = document.createElement('style');
bootStyles.textContent = bootstrapStyles;
const variableStyles = document.createElement('style');
variableStyles.textContent = varStyles;
const itemStyles = document.createElement('style');
itemStyles.textContent = styles;
shadow.appendChild(bootStyles);
shadow.appendChild(variableStyles);
shadow.appendChild(itemStyles);
}

connectedCallback() {
// TODO: Add support for: scrollable,
// custom extra classes, dark, hover, and
// striped columns/rows.
this.shadowRoot.append(...this.childNodes);
this._addTableClasses();
this._slotCells();
}

_addTableClasses() {
const table = this.shadowRoot.querySelector('table');
table.classList.add('table');

const isStacked = this.hasAttribute('table-stacked');
if (isStacked) {
table.classList.add('table-stacked');
}
}

_slotCells() {
const cells = this.shadowRoot.querySelectorAll('td');
const cellHeaders = this.shadowRoot.querySelectorAll('th');
[...cells, ...cellHeaders].forEach((cellNode, idx) => {
const children = cellNode.childNodes;
const contentDiv = document.createElement('div');
contentDiv.classList.add('content');
const slotName = `slot-${idx}`;
contentDiv.setAttribute('slot', slotName);
contentDiv.append(...children);

const slot = document.createElement('slot');
slot.setAttribute('name', slotName);
cellNode.appendChild(slot);

this.appendChild(contentDiv);
});
}
}

export { TableV2 as default };
65 changes: 65 additions & 0 deletions src/components/organisms/TableV2/TableV2.scss
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
@use '../../../scss/mixins/table';
@import 'bootstrap/scss/functions';
@import 'bootstrap/scss/variables';
@import 'bootstrap/scss/mixins/breakpoints';

@include media-breakpoint-down(lg) {
table.table-stacked {
& slot {
display: block;
flex: 1 1 0px;
padding: 0.5em 0.5em;
}

// Header & body styles.
& thead {
// Move table header off the screen to hide from
// sited viewers but remain enabled for screen readers
// and other AT.
position: absolute;
left: -10000px;
top: auto;
width: 1px;
height: 1px;
overflow: hidden;
}

// Row styles.
& tr {
display: block;
border-top-width: 0;
width: 100%;
border-bottom: 2px solid var(--bs-black);

&:nth-child(1) {
border-top: 2px solid var(--bs-black);
}
}

// Cell header styles.
& th {
@include table.th-td-stacked-inline-styles;

& div.content {
@include table.cell-content-stacked-inline-styles;
}
}

& th[data-label] {
@include table.th-td-labeled-stacked-inline-styles;
}

// Cell styles.
& td {
@include table.th-td-stacked-inline-styles;

& div.content {
@include table.cell-content-stacked-inline-styles;
}
}

& td[data-label] {
@include table.th-td-labeled-stacked-inline-styles;
}
}
}
2 changes: 2 additions & 0 deletions src/components/organisms/TableV2/cod-table-v2.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
import TableV2 from './TableV2';
customElements.define('cod-table-v2', TableV2);
94 changes: 94 additions & 0 deletions src/stories/table-v2.stories.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,94 @@
import { html } from 'lit-html';
import '../components/organisms/TableV2/cod-table-v2';

export default {
title: 'Components/Organisms/TableV2',
};

export const Basic = () => html`
<cod-table-v2 id="basicTable">
<table>
<thead>
<tr>
<th scope="col">#</th>
<th scope="col">First</th>
<th scope="col">Last</th>
<th scope="col">Handle</th>
</tr>
</thead>
<tbody>
<tr>
<th scope="row">1</th>
<td>Mark</td>
<td>Otto</td>
<td>@mdo</td>
</tr>
<tr>
<th scope="row">2</th>
<td>Jacob</td>
<td>Thornton</td>
<td>@fat</td>
</tr>
<tr>
<th scope="row">3</th>
<td colspan="2">Larry the Bird</td>
<td>@twitter</td>
</tr>
</tbody>
</table>
</cod-table>
`;

export const StackedInline = () => html`
<cod-table-v2 data-id="table-stacked" table-stacked>
<table>
<thead>
<tr>
<th scope="col">Bus Route</th>
<th scope="col">Route Viewer</th>
<th scope="col">Downloadable Schedule</th>
</tr>
</thead>
<tbody>
<tr>
<td data-label="Bus Route">
1 Vernor
</td>
<td data-label="Route Viewer">
<a href="https://example.com">View Route</a>
</td>
<td data-label="Downloadable Schedule">
<a href="https://example.com">Download Schedule</a>
</td>
</tr>
<tr>
<td data-label="Bus Route">
<ul>
<li>2.1 Michigan</li>
<li>2.2 Ohio</li>
<li>2.3 Indiana</li>
<li>2.4 Illinois</li>
</ul>
</td>
<td data-label="Route Viewer">
<a href="https://example.com">View Route</a>
</td>
<td data-label="Downloadable Schedule">
<a href="https://example.com">Download Schedule</a>
</td>
</tr>
<tr>
<td data-label="Bus Route">
3 Gratiot
</td>
<td data-label="Route Viewer">
<a href="https://example.com">View Route</a>
</td>
<td data-label="Downloadable Schedule">
<a href="https://example.com">Download Schedule</a>
</td>
</tr>
</tbody>
</table>
</cod-table>
`;
Loading