@cbpds/web-components
Version:
Web components for the CBP Design System.
280 lines (279 loc) • 10.9 kB
JavaScript
/*!
* CPB Design System web components - built with Stencil
*/
import { Host, h } from "@stencil/core";
import { setCSSProps } from "../../utils/utils";
export class CbpTable {
constructor() {
this.sortableColumns = [];
this.striped = undefined;
this.hover = 'row';
this.columnHover = undefined;
this.context = undefined;
this.sx = {};
this.sort = undefined;
}
addScope() {
const columnHeadings = Array.from(this.host.querySelectorAll('thead th'));
const rowHeadings = Array.from(this.host.querySelectorAll('tbody th'));
columnHeadings.forEach(item => {
item.setAttribute('scope', 'col');
});
rowHeadings.forEach(item => {
item.setAttribute('scope', 'row');
});
}
makeSortable() {
this.columnHeadings = Array.from(this.host.querySelectorAll('thead th'));
this.columnHeadings.forEach(item => {
const control = item.querySelector('cbp-button');
if (control) {
this.sortableColumns = [...this.sortableColumns, item];
const icon = control.querySelector('button cbp-icon');
if (item.getAttribute('aria-sort') == "ascending")
icon.rotate = 270;
if (item.getAttribute('aria-sort') == "descending")
icon.rotate = 90;
if (!item.getAttribute('aria-sort')) {
item.setAttribute("aria-sort", "none");
icon.setAttribute('hidden', '');
control.pressed = "false";
}
else {
icon.name = "arrow-right";
control.pressed = "true";
}
control.addEventListener("buttonClick", e => {
this.doSort(this.columnHeadings.indexOf(item), e);
});
}
});
const sortedColumn = this.host.querySelector('th[aria-sort]');
if (sortedColumn) {
this.sort = {
columnHeading: sortedColumn,
direction: sortedColumn.getAttribute('aria-sort')
};
}
}
async doSort(column, e = undefined) {
const ColumnHeading = this.columnHeadings[column];
const CbpButton = ColumnHeading.querySelector('cbp-button');
const Icon = ColumnHeading.querySelector('button cbp-icon');
let direction = "ascending";
if (ColumnHeading == this.sort.columnHeading) {
ColumnHeading.getAttribute('aria-sort') == "ascending"
? direction = "descending"
: direction = "ascending";
}
else {
this.sort.columnHeading.setAttribute('aria-sort', 'none');
this.sort.columnHeading.querySelector('cbp-button').pressed = "false";
this.sort.columnHeading.querySelector('button cbp-icon').name = undefined;
(this.sort.columnHeading.querySelector('button cbp-icon')).setAttribute('hidden', '');
CbpButton.pressed = "true";
}
Icon.removeAttribute('hidden');
Icon.rotate = (direction == 'descending') ? 90 : 270;
Icon.name = "arrow-right";
ColumnHeading.setAttribute('aria-sort', direction);
let newSort = {
columnHeading: ColumnHeading,
direction: direction
};
this.sort = newSort;
this.tableSort.emit({
host: this.host,
column: column,
direction: direction,
nativeEvent: e
});
}
componentWillLoad() {
var _a;
this.table = this.host.querySelector('table');
this.caption = (_a = this.table) === null || _a === void 0 ? void 0 : _a.querySelector('caption');
if (!this.caption)
console.warn(`cbp-table: A caption tag is required for accessibility. If you don't want a visible caption, add a 'hidden' attribute to it.`);
this.columnHeadings = Array.from(this.host.querySelectorAll('thead > th'));
if (typeof this.sx == 'string') {
this.sx = JSON.parse(this.sx) || {};
}
setCSSProps(this.host, Object.assign({}, this.sx));
}
componentDidLoad() {
this.addScope();
this.makeSortable();
}
render() {
return (h(Host, { key: 'e1e51fea95c6c985962c46057b59a775f3473d24' }, h("slot", { key: '8d4ee921236d6b99a5a0bcf51b7f1130587d68d8', name: "cbp-table-toolbar" }), h("slot", { key: '8f275deb9b7b3938075815c30c171cecd0821967' })));
}
static get is() { return "cbp-table"; }
static get originalStyleUrls() {
return {
"$": ["cbp-table.scss"]
};
}
static get styleUrls() {
return {
"$": ["cbp-table.css"]
};
}
static get properties() {
return {
"striped": {
"type": "string",
"mutable": false,
"complexType": {
"original": "\"odd\" | \"even\"",
"resolved": "\"even\" | \"odd\"",
"references": {}
},
"required": false,
"optional": false,
"docs": {
"tags": [],
"text": "Specifies whether the table is striped, designating whether the colored rows are the odd or even rows (CBP DS standard is even when used)."
},
"attribute": "striped",
"reflect": true
},
"hover": {
"type": "string",
"mutable": false,
"complexType": {
"original": "'row' | 'cell'",
"resolved": "\"cell\" | \"row\"",
"references": {}
},
"required": false,
"optional": false,
"docs": {
"tags": [],
"text": "Specifies whether the mouse cursor highlights the table row or cell on hover. Defaults to \"row\"."
},
"attribute": "hover",
"reflect": true,
"defaultValue": "'row'"
},
"columnHover": {
"type": "boolean",
"mutable": false,
"complexType": {
"original": "boolean",
"resolved": "boolean",
"references": {}
},
"required": false,
"optional": false,
"docs": {
"tags": [],
"text": "Specifies whether a hover effect is applied to columns when the column header is hovered. This feature is opt-in."
},
"attribute": "column-hover",
"reflect": true
},
"context": {
"type": "string",
"mutable": false,
"complexType": {
"original": "'light-inverts' | 'light-always' | 'dark-inverts' | 'dark-always'",
"resolved": "\"dark-always\" | \"dark-inverts\" | \"light-always\" | \"light-inverts\"",
"references": {}
},
"required": false,
"optional": false,
"docs": {
"tags": [],
"text": "Specifies the context of the component as it applies to the visual design and whether it inverts when light/dark mode is toggled. Default behavior is \"light-inverts\" and does not have to be specified."
},
"attribute": "context",
"reflect": true
},
"sx": {
"type": "any",
"mutable": false,
"complexType": {
"original": "any",
"resolved": "any",
"references": {}
},
"required": false,
"optional": false,
"docs": {
"tags": [],
"text": "Supports adding inline styles as an object"
},
"attribute": "sx",
"reflect": false,
"defaultValue": "{}"
}
};
}
static get states() {
return {
"sort": {}
};
}
static get events() {
return [{
"method": "tableSort",
"name": "tableSort",
"bubbles": true,
"cancelable": true,
"composed": true,
"docs": {
"tags": [],
"text": "An event emitted when the table is sorted via user interaction activating a table header control."
},
"complexType": {
"original": "any",
"resolved": "any",
"references": {}
}
}];
}
static get methods() {
return {
"doSort": {
"complexType": {
"signature": "(column: number, e?: any) => Promise<void>",
"parameters": [{
"name": "column",
"type": "number",
"docs": ""
}, {
"name": "e",
"type": "any",
"docs": ""
}],
"references": {
"Promise": {
"location": "global",
"id": "global::Promise"
},
"HTMLTableCellElement": {
"location": "global",
"id": "global::HTMLTableCellElement"
},
"HTMLCbpButtonElement": {
"location": "global",
"id": "global::HTMLCbpButtonElement"
},
"HTMLCbpIconElement": {
"location": "global",
"id": "global::HTMLCbpIconElement"
}
},
"return": "Promise<void>"
},
"docs": {
"text": "Updates the UI statefullness (`aria-pressed`, `aria-sort`, and visual arrow icon) and \nemits a custom event to hook up to application logic for the actual sorting",
"tags": []
}
}
};
}
static get elementRef() { return "host"; }
}
//# sourceMappingURL=cbp-table.js.map