Skip to content

Commit

Permalink
Merge pull request #112 from CityOfDetroit/feature.bustable
Browse files Browse the repository at this point in the history
Create responsive stacked table
  • Loading branch information
jedgar1mx authored Nov 14, 2023
2 parents cbfa917 + 5df5a76 commit a03b6e0
Show file tree
Hide file tree
Showing 18 changed files with 615 additions and 74 deletions.
42 changes: 38 additions & 4 deletions src/components/atoms/TableBody/TableBody.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,10 @@
import styles from '!!raw-loader!./TableBody.css';
import varStyles from '!!raw-loader!../../../shared/variables.css';
import bootstrapStyles from '!!raw-loader!../../../shared/themed-bootstrap.css';
import {
cellHeaderBlockClass,
stackedTableClass,
} from '../../../shared/js/utilities';

const template = document.createElement('template');

Expand All @@ -23,6 +27,11 @@ export default class TableBody extends HTMLElement {
// eslint-disable-next-line prefer-const
let tempElements = Array.from(this.children);
tempElements.forEach((node, index) => {
if (index === 0) {
node.setIsFirst();
} else if (index % 2 !== 0) {
node.setIsOdd();
}
// TODO: See CityOfDetroit/detroitmi#1099
// eslint-disable-next-line eqeqeq
this.getAttribute('data-striped-row') == 'true' && index % 2 == 0
Expand All @@ -43,11 +52,14 @@ export default class TableBody extends HTMLElement {
this.getAttribute('data-vertical-align') == 'true'
? node.setAttribute('data-vertical-align', 'true')
: 0;
// TODO: See CityOfDetroit/detroitmi#1099
// eslint-disable-next-line eqeqeq
this.getAttribute('data-legacy-responsive') == 'true'
? node.setAttribute('data-legacy-responsive', 'true')
this.getAttribute('data-scrollable') === 'true'
? node.setAttribute('data-scrollable', 'true')
: 0;

if (this.isStacked()) {
node.setIsStacked(true /* isStacked */, this.isCellHeaderBlock());
}

this.tableBody.append(node);
});
});
Expand All @@ -65,4 +77,26 @@ export default class TableBody extends HTMLElement {

shadow.appendChild(this.tableBody);
}

setIsStacked(isStacked, isCellHeaderBlock) {
if (isStacked) {
this.tableBody.classList.add(stackedTableClass);
} else {
this.tableBody.classList.remove(stackedTableClass);
}

if (isCellHeaderBlock) {
this.tableBody.classList.add(cellHeaderBlockClass);
} else {
this.tableBody.classList.remove(cellHeaderBlockClass);
}
}

isStacked() {
return this.tableBody.classList.contains(stackedTableClass);
}

isCellHeaderBlock() {
return this.tableBody.classList.contains(cellHeaderBlockClass);
}
}
2 changes: 1 addition & 1 deletion src/components/atoms/TableCell/TableCell.css
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,6 @@ td.table-striped-columns {
--bs-table-accent-bg: var(--bs-table-striped-bg);
}

td.table-legacy-responsive {
td.table-scrollable {
width: 5em;
}
65 changes: 46 additions & 19 deletions src/components/atoms/TableCell/TableCell.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,10 @@
import styles from '!!raw-loader!./TableCell.css';
import varStyles from '!!raw-loader!../../../shared/variables.css';
import bootstrapStyles from '!!raw-loader!../../../shared/themed-bootstrap.css';
import {
cellHeaderBlockClass,
stackedTableClass,
} from '../../../shared/js/utilities';

const template = document.createElement('template');

Expand All @@ -19,11 +23,18 @@ export default class TableCell extends HTMLElement {
// TODO: See CityOfDetroit/detroitmi#1099
// eslint-disable-next-line no-unused-vars
shadow.addEventListener('slotchange', (ev) => {
// TODO: See CityOfDetroit/detroitmi#1099
// eslint-disable-next-line prefer-const
let tempElements = Array.from(this.childNodes);
const tempElements = ev.target.assignedNodes();
tempElements.forEach((node) => {
this.tableCell.appendChild(node);
// Only accept HTMLElements or non-empty text nodes.
if (
node.nodeType !== Node.TEXT_NODE ||
!/^\s*$/.test(node.textContent)
) {
const contentDiv = document.createElement('div');
contentDiv.classList.add('content');
contentDiv.appendChild(node);
this.tableCell.appendChild(contentDiv);
}
});
});

Expand Down Expand Up @@ -51,37 +62,53 @@ export default class TableCell extends HTMLElement {
let stripedCol = this.getAttribute('data-striped-col');
// TODO: See CityOfDetroit/detroitmi#1099
// eslint-disable-next-line prefer-const
let legacyResponsive = this.getAttribute('data-legacy-responsive');
// TODO: See CityOfDetroit/detroitmi#1099
// eslint-disable-next-line prefer-const
let verticalAlign = this.getAttribute('data-vertical-align');
// TODO: See CityOfDetroit/detroitmi#1099
// eslint-disable-next-line prefer-const
let extraClasses = this.getAttribute('data-extra-classes');
// TODO: See CityOfDetroit/detroitmi#1099
// eslint-disable-next-line prefer-const
let tableCellClasses = [];
// TODO: See CityOfDetroit/detroitmi#1099
// eslint-disable-next-line eqeqeq
verticalAlign != undefined && verticalAlign != null
? tableCellClasses.push(verticalAlign)
? this.tableCell.classList.add(verticalAlign)
: 0;
// TODO: See CityOfDetroit/detroitmi#1099
// eslint-disable-next-line eqeqeq
legacyResponsive == 'true'
? tableCellClasses.push('table-legacy-responsive')
this.getAttribute('data-scrollable') === 'true'
? this.tableCell.classList.add('table-scrollable')
: 0;
// TODO: See CityOfDetroit/detroitmi#1099
// eslint-disable-next-line eqeqeq
stripedRow == 'true' ? tableCellClasses.push('table-striped') : 0;
stripedRow == 'true' ? this.tableCell.classList.add('table-striped') : 0;
// TODO: See CityOfDetroit/detroitmi#1099
// eslint-disable-next-line eqeqeq
stripedCol == 'true' ? tableCellClasses.push('table-striped-columns') : 0;
stripedCol == 'true'
? this.tableCell.classList.add('table-striped-columns')
: 0;
// TODO: See CityOfDetroit/detroitmi#1099
// eslint-disable-next-line eqeqeq
extraClasses != undefined && extraClasses != null
? tableCellClasses.push(extraClasses)
? this.tableCell.classList.add(extraClasses)
: 0;
this.tableCell.className = tableCellClasses.join(' ');

const dataLabel = this.getAttribute('data-label');
if (dataLabel) {
this.tableCell.setAttribute('data-label', dataLabel);
}
}

setIsStacked(isStacked, isCellHeaderBlock) {
if (isStacked) {
this.tableCell.classList.add(stackedTableClass);
} else {
this.tableCell.classList.remove(stackedTableClass);
}

if (isCellHeaderBlock) {
this.tableCell.classList.add(cellHeaderBlockClass);
} else {
this.tableCell.classList.remove(cellHeaderBlockClass);
}
}

isStacked() {
return this.tableCell.classList.contains(stackedTableClass);
}
}
27 changes: 27 additions & 0 deletions src/components/atoms/TableCell/_table-cell.scss
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
@use '../../../scss/mixins/table';
@import '../../../../node_modules/bootstrap/scss/mixins/breakpoints';
@import '../../../../node_modules/bootstrap/scss/variables';

@include media-breakpoint-down(lg) {
td.table-stacked.cell-header-block {
@include table.th-td-stacked-block-styles;
}

td.table-stacked:not(.cell-header-block) {
@include table.th-td-stacked-inline-styles;

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

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

&:not(.cell-header-block) {
@include table.th-td-labeled-stacked-inline-styles;
}
}
}
2 changes: 1 addition & 1 deletion src/components/atoms/TableCellHeader/TableCellHeader.css
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,6 @@ th.table-striped-columns {
--bs-table-accent-bg: var(--bs-table-striped-bg);
}

th.table-legacy-responsive {
th.table-scrollable {
width: 5em;
}
45 changes: 30 additions & 15 deletions src/components/atoms/TableCellHeader/TableCellHeader.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,10 @@
import styles from '!!raw-loader!./TableCellHeader.css';
import varStyles from '!!raw-loader!../../../shared/variables.css';
import bootstrapStyles from '!!raw-loader!../../../shared/themed-bootstrap.css';
import {
cellHeaderBlockClass,
stackedTableClass,
} from '../../../shared/js/utilities';

const template = document.createElement('template');

Expand Down Expand Up @@ -51,39 +55,50 @@ export default class TableCellHeader extends HTMLElement {
let stripedCol = this.getAttribute('data-striped-col');
// TODO: See CityOfDetroit/detroitmi#1099
// eslint-disable-next-line prefer-const
let legacyResponsive = this.getAttribute('data-legacy-responsive');
// TODO: See CityOfDetroit/detroitmi#1099
// eslint-disable-next-line prefer-const
let verticalAlign = this.getAttribute('data-vertical-align');
// TODO: See CityOfDetroit/detroitmi#1099
// eslint-disable-next-line prefer-const
let extraClasses = this.getAttribute('data-extra-classes');
// TODO: See CityOfDetroit/detroitmi#1099
// eslint-disable-next-line prefer-const
let tableCellHeaderClasses = [];
// TODO: See CityOfDetroit/detroitmi#1099
// eslint-disable-next-line eqeqeq
verticalAlign != undefined && verticalAlign != null
? tableCellHeaderClasses.push(verticalAlign)
? this.tableCellHeader.classList.add(verticalAlign)
: 0;
// TODO: See CityOfDetroit/detroitmi#1099
// eslint-disable-next-line eqeqeq
legacyResponsive == 'true'
? tableCellHeaderClasses.push('table-legacy-responsive')
this.getAttribute('data-scrollable') === 'true'
? this.tableCellHeader.classList.add('table-scrollable')
: 0;
// TODO: See CityOfDetroit/detroitmi#1099
// eslint-disable-next-line eqeqeq
stripedRow == 'true' ? tableCellHeaderClasses.push('table-striped') : 0;
stripedRow == 'true'
? this.tableCellHeader.classList.add('table-striped')
: 0;
// TODO: See CityOfDetroit/detroitmi#1099
// eslint-disable-next-line eqeqeq
stripedCol == 'true'
? tableCellHeaderClasses.push('table-striped-columns')
? this.tableCellHeader.classList.add('table-striped-columns')
: 0;
// TODO: See CityOfDetroit/detroitmi#1099
// eslint-disable-next-line eqeqeq
extraClasses != undefined && extraClasses != null
? tableCellHeaderClasses.push(extraClasses)
? this.tableCellHeader.classList.add(extraClasses)
: 0;
this.tableCellHeader.className = tableCellHeaderClasses.join(' ');
}

setIsStacked(isStacked, isCellHeaderBlock) {
if (isStacked) {
this.tableCellHeader.classList.add(stackedTableClass);
} else {
this.tableCellHeader.classList.remove(stackedTableClass);
}

if (isCellHeaderBlock) {
this.tableCellHeader.classList.add(cellHeaderBlockClass);
} else {
this.tableCellHeader.classList.remove(cellHeaderBlockClass);
}
}

isStacked() {
return this.tableCellHeader.classList.contains(stackedTableClass);
}
}
27 changes: 27 additions & 0 deletions src/components/atoms/TableCellHeader/_table-cell-header.scss
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
@use '../../../scss/mixins/table';
@import '../../../../node_modules/bootstrap/scss/mixins/breakpoints';
@import '../../../../node_modules/bootstrap/scss/variables';

@include media-breakpoint-down(lg) {
th.table-stacked.cell-header-block {
@include table.th-td-stacked-block-styles;
}

th.table-stacked:not(.cell-header-block) {
@include table.th-td-stacked-inline-styles;

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

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

&:not(.cell-header-block) {
@include table.th-td-labeled-stacked-inline-styles;
}
}
}
42 changes: 37 additions & 5 deletions src/components/atoms/TableHeader/TableHeader.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,10 @@
import styles from '!!raw-loader!./TableHeader.css';
import varStyles from '!!raw-loader!../../../shared/variables.css';
import bootstrapStyles from '!!raw-loader!../../../shared/themed-bootstrap.css';
import {
cellHeaderBlockClass,
stackedTableClass,
} from '../../../shared/js/utilities';

const template = document.createElement('template');

Expand All @@ -22,7 +26,10 @@ export default class TableHeader extends HTMLElement {
// TODO: See CityOfDetroit/detroitmi#1099
// eslint-disable-next-line prefer-const
let tempElements = Array.from(this.children);
tempElements.forEach((node) => {
tempElements.forEach((node, index) => {
if (index === 0) {
node.setIsFirst();
}
// TODO: See CityOfDetroit/detroitmi#1099
// eslint-disable-next-line eqeqeq
this.getAttribute('data-striped-col') == 'true'
Expand All @@ -33,11 +40,14 @@ export default class TableHeader extends HTMLElement {
this.getAttribute('data-vertical-align') == 'true'
? node.setAttribute('data-vertical-align', 'true')
: 0;
// TODO: See CityOfDetroit/detroitmi#1099
// eslint-disable-next-line eqeqeq
this.getAttribute('data-legacy-responsive') == 'true'
? node.setAttribute('data-legacy-responsive', 'true')
this.getAttribute('data-scrollable') === 'true'
? node.setAttribute('data-scrollable', 'true')
: 0;

if (this.isStacked()) {
node.setIsStacked(true /* isStacked */, this.isCellHeaderBlock());
}

this.tableHeader.append(node);
});
});
Expand All @@ -55,4 +65,26 @@ export default class TableHeader extends HTMLElement {

shadow.appendChild(this.tableHeader);
}

setIsStacked(isStacked, isCellHeaderBlock) {
if (isStacked) {
this.tableHeader.classList.add(stackedTableClass);
} else {
this.tableHeader.classList.remove(stackedTableClass);
}

if (isCellHeaderBlock) {
this.tableHeader.classList.add(cellHeaderBlockClass);
} else {
this.tableHeader.classList.remove(cellHeaderBlockClass);
}
}

isStacked() {
return this.tableHeader.classList.contains(stackedTableClass);
}

isCellHeaderBlock() {
return this.tableHeader.classList.contains(cellHeaderBlockClass);
}
}
Loading

0 comments on commit a03b6e0

Please sign in to comment.