UNPKG

@adobe/coral-spectrum

Version:

Coral Spectrum is a JavaScript library of Web Components following Spectrum design patterns.

380 lines (303 loc) 9.96 kB
/** * Copyright 2019 Adobe. All rights reserved. * This file is licensed to you under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. You may obtain a copy * of the License at http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software distributed under * the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS * OF ANY KIND, either express or implied. See the License for the specific language * governing permissions and limitations under the License. */ import {BaseComponent} from '../../../coral-base-component'; import {alignment} from './TableUtil'; import {commons, transform, validate} from '../../../coral-utils'; import {Decorator} from '../../../coral-decorator'; const CLASSNAME = '_coral-Table-column'; /** Enumeration for {@link TableColumn} sortable direction options. @typedef {Object} TableColumnSortableDirectionEnum @property {String} DEFAULT Default. No sorting applied. @property {String} ASCENDING Ascending sort. @property {String} DESCENDING Descending sort. */ const sortableDirection = { DEFAULT: 'default', ASCENDING: 'ascending', DESCENDING: 'descending' }; /** Enumeration for {@link TableColumn} sortable type options. @typedef {Object} TableColumnSortableTypeEnum @property {String} ALPHANUMERIC Alphanumeric type. If sorting is based on {@link TableCell#value}, use {String}. @property {String} NUMBER Number type. If sorting is based on {@link TableCell#value}, use {Number}. @property {String} DATE Date type. If sorting is based on {@link TableCell#value}, use {Date} in milliseconds. @property {String} CUSTOM Custom type. Sorting is based on user defined sorting. */ const sortableType = { ALPHANUMERIC: 'alphanumeric', NUMBER: 'number', DATE: 'date', CUSTOM: 'custom' }; /** @class Coral.Table.Column @classdesc A Table column component @htmltag coral-table-column @htmlbasetag col @extends {HTMLTableColElement} @extends {BaseComponent} */ const TableColumn = Decorator(class extends BaseComponent(HTMLTableColElement) { /** The column cells alignment. The alignment should take the {@link i18n} configuration into account. @type {String} @default TableColumnAlignmentEnum.LEFT @htmlattribute alignment @htmlattributereflected */ get alignment() { return this._alignment || alignment.LEFT; } set alignment(value) { const oldValue = this._alignment; value = transform.string(value).toLowerCase(); this._alignment = validate.enumeration(alignment)(value) && value || alignment.LEFT; this._reflectAttribute('alignment', this._alignment); // Don't trigger on initialization if alignment is LEFT to improve performance if (!(typeof oldValue === 'undefined' && this._alignment === alignment.LEFT)) { window.requestAnimationFrame(() => { this.trigger('coral-table-column:_alignmentchanged'); }); } } /** Whether the column has a fixed width. @type {Boolean} @default false @htmlattribute fixedwidth @htmlattributereflected */ get fixedWidth() { return this._fixedWidth || false; } set fixedWidth(value) { this._fixedWidth = transform.booleanAttr(value); this._reflectAttribute('fixedwidth', this._fixedWidth); window.requestAnimationFrame(() => { this.trigger('coral-table-column:_fixedwidthchanged'); }); } /** Whether the column is hidden. @type {Boolean} @default false @htmlattribute hidden @htmlattributereflected */ get hidden() { return this._hidden || false; } set hidden(value) { this._hidden = transform.booleanAttr(value); this._reflectAttribute('hidden', this._hidden); window.requestAnimationFrame(() => { this.trigger('coral-table-column:_hiddenchanged'); }); } /** Whether the table column is orderable. Note that this does not affect the underlying data, only presentation. @type {Boolean} @default false @htmlattribute orderable @htmlattributereflected */ get orderable() { return this._orderable || false; } set orderable(value) { this._orderable = transform.booleanAttr(value); this._reflectAttribute('orderable', this._orderable); window.requestAnimationFrame(() => { this.trigger('coral-table-column:_orderablechanged'); }); } /** Whether the column is sortable by user interaction. @type {Boolean} @default false @htmlattribute sortable @htmlattributereflected */ get sortable() { return this._sortable || false; } set sortable(value) { this._sortable = transform.booleanAttr(value); this._reflectAttribute('sortable', this._sortable); window.requestAnimationFrame(() => { this.trigger('coral-table-column:_sortablechanged'); }); } /** The sorting type. See {@link TableColumnSortableTypeEnum}. If setting to <code>custom</code>, columns won't sort based on the default table sorting. Instead, a custom sorting can be performed when triggered by user interaction. This can be defined by listening to the {@link coral-table:beforecolumnsort} event. @type {String} @default TableColumnSortableTypeEnum.ALPHANUMERIC @htmlattribute sortabletype @htmlattributereflected */ get sortableType() { return this._sortableType || sortableType.ALPHANUMERIC; } set sortableType(value) { value = transform.string(value).toLowerCase(); this._sortableType = validate.enumeration(sortableType)(value) && value || sortableType.ALPHANUMERIC; this._reflectAttribute('sortabletype', this._sortableType); } /** The sorting direction. Sorts the column cells based on {@link TableCell#value}. If not present, the sort is based on the cell text content. See {@link TableColumnSortableDirectionEnum}. @type {String} @default TableColumnSortableDirectionEnum.DEFAULT @htmlattribute sortabledirection @htmlattributereflected */ get sortableDirection() { return this._sortableDirection || sortableDirection.DEFAULT; } set sortableDirection(value) { value = transform.string(value).toLowerCase(); this._sortableDirection = validate.enumeration(sortableDirection)(value) && value || sortableDirection.DEFAULT; this._reflectAttribute('sortabledirection', this._sortableDirection); // Prevent sorting if unnecessary if (!this._preventSort) { this._doSort(); window.requestAnimationFrame(() => { this.trigger('coral-table-column:_sortabledirectionchanged'); }); } } /** @private */ _sort() { let newSortableDirection; if (this.sortableDirection === sortableDirection.DEFAULT) { newSortableDirection = sortableDirection.ASCENDING; } else if (this.sortableDirection === sortableDirection.ASCENDING) { newSortableDirection = sortableDirection.DESCENDING; } else if (this.sortableDirection === sortableDirection.DESCENDING) { newSortableDirection = sortableDirection.DEFAULT; } this.trigger('coral-table-column:_beforecolumnsort', {newSortableDirection}); } /** @private */ _doSort(onInitialization) { this.trigger('coral-table-column:_sort', {onInitialization, sortableDirection, sortableType}); } /** Returns {@link TableColumn} sortable direction options. @return {TableColumnSortableDirectionEnum} */ static get sortableDirection() { return sortableDirection; } /** Returns {@link TableColumn} sortable type options. @return {TableColumnSortableTypeEnum} */ static get sortableType() { return sortableType; } /** Returns {@link TableColumn} alignment options. @return {TableColumnAlignmentEnum} */ static get alignment() { return alignment; } static get _attributePropertyMap() { return commons.extend(super._attributePropertyMap, { fixedwidth: 'fixedWidth', sortabletype: 'sortableType', sortabledirection: 'sortableDirection' }); } /** @ignore */ static get observedAttributes() { return super.observedAttributes.concat([ 'fixedwidth', 'hidden', 'alignment', 'orderable', 'sortable', 'sortabletype', 'sortabledirection', ]); } /** @ignore */ render() { super.render(); this.classList.add(CLASSNAME); // Default reflected attributes if (!this._sortableType) { this.sortableType = sortableType.ALPHANUMERIC; } if (!this._sortableDirection) { this.sortableDirection = sortableDirection.DEFAULT; } if (!this._alignment) { this.alignment = alignment.LEFT; } } /** Triggered when {@link TableColumn#alignment} changed. @typedef {CustomEvent} coral-table-column:_alignmentchanged @private */ /** Triggered when {@link TableColumn#fixedWidth} changed. @typedef {CustomEvent} coral-table-column:_fixedwidthchanged @private */ /** Triggered when {@link TableColumn#orderable} changed. @typedef {CustomEvent} coral-table-column:_orderablechanged @private */ /** Triggered when {@link TableColumn#sortable} changed. @typedef {CustomEvent} coral-table-column:_sortablechanged @private */ /** Triggered when {@link TableColumn#sortableDirection} changed. @typedef {CustomEvent} coral-table-column:_sortabledirectionchanged @private */ /** Triggered when {@link TableColumn#hidden} changed. @typedef {CustomEvent} coral-table-column:_hiddenchanged @private */ /** Triggered before {@link TableColumn#sortableDirection} changed. @typedef {CustomEvent} coral-table-column:_beforecolumnsort @private */ /** Triggered when {@link TableColumn#sortableDirection} changed. @typedef {CustomEvent} coral-table-column:_sort @private */ }); export default TableColumn;