coral-spectrum/coral-component-table/src/scripts/TableColumn.js
- /**
- * 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;