diff --git a/src/components/organisms/TableV2/TableV2.css b/src/components/organisms/TableV2/TableV2.css new file mode 100644 index 00000000..bab29448 --- /dev/null +++ b/src/components/organisms/TableV2/TableV2.css @@ -0,0 +1,58 @@ +@media (max-width: 991.98px) { + table.table-stacked slot { + display: block; + flex: 1 1 0px; + padding: 0.5em 0.5em; + } + table.table-stacked thead { + position: absolute; + left: -10000px; + top: auto; + width: 1px; + height: 1px; + overflow: hidden; + } + table.table-stacked tr { + display: block; + border-top-width: 0; + width: 100%; + border-bottom: 2px solid var(--bs-black); + } + table.table-stacked tr:nth-child(1) { + border-top: 2px solid var(--bs-black); + } + table.table-stacked th { + padding: 0; + border-bottom-width: 0; + display: flex; + } + table.table-stacked th div.content { + flex: 1 1 0px; + padding: 0.5em 0.5em; + } + table.table-stacked th[data-label]:before { + content: attr(data-label); + font-weight: bold; + background-color: #f2f2f2; + flex: 1 1 0px; + padding: 0.5em 0.5em; + } + table.table-stacked td { + padding: 0; + border-bottom-width: 0; + display: flex; + } + table.table-stacked td div.content { + flex: 1 1 0px; + padding: 0.5em 0.5em; + } + table.table-stacked td[data-label]:before { + content: attr(data-label); + font-weight: bold; + background-color: #f2f2f2; + flex: 1 1 0px; + padding: 0.5em 0.5em; + } +} + +/*# sourceMappingURL=TableV2.css.map */ diff --git a/src/components/organisms/TableV2/TableV2.css.map b/src/components/organisms/TableV2/TableV2.css.map new file mode 100644 index 00000000..15957502 --- /dev/null +++ b/src/components/organisms/TableV2/TableV2.css.map @@ -0,0 +1 @@ +{"version":3,"sourceRoot":"","sources":["../../../../node_modules/bootstrap/scss/mixins/_breakpoints.scss","TableV2.scss","../../../scss/mixins/_table.scss"],"names":[],"mappings":"AA4EI;ECpEA;IACE;IACA;IACA;;EAIF;IAIE;IACA;IACA;IACA;IACA;IACA;;EAIF;IACE;IACA;IACA;IACA;;EAEA;IACE;;EAKJ;ICjCF;IACA;IACA;;EDkCI;IC9BJ;IACA;;EAiBA;IACE;IACA;IACA;IACA;IACA;;EDiBA;IC9CF;IACA;IACA;;ED+CI;IC3CJ;IACA;;EAiBA;IACE;IACA;IACA;IACA;IACA","file":"TableV2.css"} \ No newline at end of file diff --git a/src/components/organisms/TableV2/TableV2.js b/src/components/organisms/TableV2/TableV2.js new file mode 100644 index 00000000..d0b0e0b2 --- /dev/null +++ b/src/components/organisms/TableV2/TableV2.js @@ -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 }; diff --git a/src/components/organisms/TableV2/TableV2.scss b/src/components/organisms/TableV2/TableV2.scss new file mode 100644 index 00000000..228fed7d --- /dev/null +++ b/src/components/organisms/TableV2/TableV2.scss @@ -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; + } + } +} diff --git a/src/components/organisms/TableV2/cod-table-v2.js b/src/components/organisms/TableV2/cod-table-v2.js new file mode 100644 index 00000000..d1f38414 --- /dev/null +++ b/src/components/organisms/TableV2/cod-table-v2.js @@ -0,0 +1,2 @@ +import TableV2 from './TableV2'; +customElements.define('cod-table-v2', TableV2); diff --git a/src/stories/table-v2.stories.js b/src/stories/table-v2.stories.js new file mode 100644 index 00000000..4fc369da --- /dev/null +++ b/src/stories/table-v2.stories.js @@ -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` + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
#FirstLastHandle
1MarkOtto@mdo
2JacobThornton@fat
3Larry the Bird@twitter
+ +`; + +export const StackedInline = () => html` + + + + + + + + + + + + + + + + + + + + + + + + + + +
Bus RouteRoute ViewerDownloadable Schedule
+ 1 Vernor + + View Route + + Download Schedule +
+
    +
  • 2.1 Michigan
  • +
  • 2.2 Ohio
  • +
  • 2.3 Indiana
  • +
  • 2.4 Illinois
  • +
+
+ View Route + + Download Schedule +
+ 3 Gratiot + + View Route + + Download Schedule +
+ +`;