UNPKG

@salesforce/design-system-react

Version:

Salesforce Lightning Design System for React

266 lines (219 loc) 11.2 kB
function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; } function _typeof(obj) { "@babel/helpers - typeof"; if (typeof Symbol === "function" && typeof Symbol.iterator === "symbol") { _typeof = function _typeof(obj) { return typeof obj; }; } else { _typeof = function _typeof(obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }; } return _typeof(obj); } function _slicedToArray(arr, i) { return _arrayWithHoles(arr) || _iterableToArrayLimit(arr, i) || _unsupportedIterableToArray(arr, i) || _nonIterableRest(); } function _nonIterableRest() { throw new TypeError("Invalid attempt to destructure non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); } function _unsupportedIterableToArray(o, minLen) { if (!o) return; if (typeof o === "string") return _arrayLikeToArray(o, minLen); var n = Object.prototype.toString.call(o).slice(8, -1); if (n === "Object" && o.constructor) n = o.constructor.name; if (n === "Map" || n === "Set") return Array.from(o); if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _arrayLikeToArray(o, minLen); } function _arrayLikeToArray(arr, len) { if (len == null || len > arr.length) len = arr.length; for (var i = 0, arr2 = new Array(len); i < len; i++) { arr2[i] = arr[i]; } return arr2; } function _iterableToArrayLimit(arr, i) { var _i = arr && (typeof Symbol !== "undefined" && arr[Symbol.iterator] || arr["@@iterator"]); if (_i == null) return; var _arr = []; var _n = true; var _d = false; var _s, _e; try { for (_i = _i.call(arr); !(_n = (_s = _i.next()).done); _n = true) { _arr.push(_s.value); if (i && _arr.length === i) break; } } catch (err) { _d = true; _e = err; } finally { try { if (!_n && _i["return"] != null) _i["return"](); } finally { if (_d) throw _e; } } return _arr; } function _arrayWithHoles(arr) { if (Array.isArray(arr)) return arr; } /* Copyright (c) 2015-present, salesforce.com, inc. All rights reserved */ /* Licensed under BSD 3-Clause - see LICENSE.txt or git.io/sfdc-license */ // ### React import React, { useContext, useEffect, useRef, useState } from 'react'; import PropTypes from 'prop-types'; // ### classNames import classNames from 'classnames'; // ### isFunction import isFunction from 'lodash.isfunction'; // ## Children import CellFixed from './cell-fixed'; import Icon from '../../icon'; // This component's `checkProps` which issues warnings to developers about properties when in development mode (similar to React's built in development tools) import checkProps from '../column-check-props'; import Link from './link'; import InteractiveLink from '../interactive-link'; import CellContext from '../private/cell-context'; import TableContext from '../private/table-context'; import useContextHelper from './context-helper'; // ## Constants import { DATA_TABLE_HEADER_CELL, DATA_TABLE_COLUMN } from '../../../utilities/constants'; // ### Prop Types var propTypes = { assistiveText: PropTypes.shape({ actionsHeader: PropTypes.string, columnSort: PropTypes.string, columnSortedAscending: PropTypes.string, columnSortedDescending: PropTypes.string, selectAllRows: PropTypes.string, selectRow: PropTypes.string }), cellRef: PropTypes.func, fixedHeader: PropTypes.bool, id: PropTypes.string.isRequired, /** * Some columns, such as "date last viewed" or "date recently updated," should sort descending first, since that is what the user probably wants. How often does one want to see their oldest files first in a table? If sortable and the `DataTable`'s parent has not defined the sort order, then ascending (A at the top to Z at the bottom) is the default sort order on first click. */ isDefaultSortDescending: PropTypes.bool, /** * Indicates if column is sorted. */ isSorted: PropTypes.bool, /** * The column label. */ label: PropTypes.oneOfType([PropTypes.string, PropTypes.node]), /** * The function to execute on sort. */ onSort: PropTypes.func, /** * The property which corresponds to this column. */ property: PropTypes.string, /** * Whether or not the column is sortable. */ sortable: PropTypes.bool, /** * The current sort direction. */ sortDirection: PropTypes.oneOf(['desc', 'asc']), /** * Width of column. This is required for advanced/fixed layout tables. Please provide units. (`rems` are recommended) */ width: PropTypes.string }; /** * Used internally, renders each individual column heading. */ var DataTableHeaderCell = function DataTableHeaderCell(props) { var _classNames; var _useState = useState(null), _useState2 = _slicedToArray(_useState, 2), sortDirection = _useState2[0], setSortDirection = _useState2[1]; var prevIsSorted = useRef(null); var tableContext = useContext(TableContext); var cellContext = useContext(CellContext); var _useContextHelper = useContextHelper(tableContext, cellContext, props.fixedLayout), tabIndex = _useContextHelper.tabIndex, hasFocus = _useContextHelper.hasFocus, handleFocus = _useContextHelper.handleFocus, handleKeyDown = _useContextHelper.handleKeyDown; useEffect(function () { checkProps(DATA_TABLE_COLUMN, props); // eslint-disable-next-line react-hooks/exhaustive-deps }, []); useEffect(function () { if (prevIsSorted.current === true && props.isSorted === false) { setSortDirection(null); } prevIsSorted.current = props.isSorted; }, [props.isSorted]); var handleSort = function handleSort(e) { e.preventDefault(); var oldSortDirection = props.sortDirection || sortDirection; // UX pattern: If sortable, and the DataTable's parent has not defined the sort order, then ascending (that is A->Z) is the default sort order on first click. Some columns, such as "last viewed" or "recently updated," should sort descending first, since that is what the user probably wants. Who wants to see the oldest files first? var newSortDirection = function sortDirectionFunction(direction, isDefaultSortDescending) { switch (direction) { case 'asc': return 'desc'; case 'desc': return 'asc'; case null: return isDefaultSortDescending ? 'desc' : 'asc'; default: return 'asc'; } }(oldSortDirection, props.isDefaultSortDescending); var data = { property: props.property, sortDirection: newSortDirection }; setSortDirection(newSortDirection); if (isFunction(props.onSort)) { props.onSort(data, e); } }; var fixedHeader = props.fixedHeader, isSorted = props.isSorted, label = props.label, sortable = props.sortable, width = props.width, property = props.property; var labelType = _typeof(label); // This decides which arrow to render--which is current sort order if the column is sorted OR the future sort order if the arrow is clicked in the future. var effectiveSortDirection = props.sortDirection || sortDirection || props.isDefaultSortDescending && 'desc'; var expandedSortDirection = effectiveSortDirection === 'desc' ? 'descending' : 'ascending'; var ariaSort = isSorted ? expandedSortDirection : 'none'; var getFixedLayoutSubRenders = function getFixedLayoutSubRenders(isHidden) { if (sortable) { // Don't make the anchor interactable when it's hidden var SortLink = isHidden ? Link : InteractiveLink; return /*#__PURE__*/React.createElement(SortLink, { href: "#", className: "slds-th__action slds-text-link_reset", onClick: handleSort, role: "button" }, /*#__PURE__*/React.createElement("span", { className: "slds-assistive-text" }, props.assistiveTextForColumnSort || props.assistiveText.columnSort, ' '), /*#__PURE__*/React.createElement("span", { className: "slds-truncate", title: labelType === 'string' ? label : undefined }, label), /*#__PURE__*/React.createElement(Icon, { className: "slds-is-sortable__icon", category: "utility", name: effectiveSortDirection === 'desc' ? 'arrowdown' : 'arrowup', size: "x-small" }), effectiveSortDirection ? /*#__PURE__*/React.createElement("span", { className: "slds-assistive-text", "aria-atomic": "true" }, effectiveSortDirection === 'asc' ? props.assistiveTextForColumnSortedAscending || props.assistiveText.columnSortedAscending : props.assistiveTextForColumnSortedDescending || props.assistiveText.columnSortedDescending) : null); } return /*#__PURE__*/React.createElement("span", { className: "slds-p-horizontal_x-small slds-th__action", style: { display: 'flex' } }, /*#__PURE__*/React.createElement("span", { className: "slds-truncate", title: labelType === 'string' ? label : undefined }, label)); }; var getHeaderCellContent = function getHeaderCellContent(isHidden) { return props.fixedLayout ? getFixedLayoutSubRenders(isHidden) : /*#__PURE__*/React.createElement("div", { className: "slds-truncate", title: labelType === 'string' ? label : undefined }, label); }; return /*#__PURE__*/React.createElement("th", { id: "".concat(props.id, "-").concat(property, "-th"), "aria-label": labelType === 'string' ? label : undefined, "aria-sort": ariaSort, className: classNames((_classNames = { 'slds-is-sortable': sortable, 'slds-is-sorted': isSorted }, _defineProperty(_classNames, "slds-is-sorted_".concat(effectiveSortDirection), effectiveSortDirection), _defineProperty(_classNames, 'slds-is-sorted_asc', isSorted && !effectiveSortDirection), _classNames)), onFocus: handleFocus, onKeyDown: handleKeyDown, ref: function ref(_ref) { if (props.cellRef) { props.cellRef(_ref); if (_ref && hasFocus) { _ref.focus(); } } }, scope: "col", style: fixedHeader || width ? { height: fixedHeader ? 0 : null, lineHeight: fixedHeader ? 0 : null, width: width || null } : null, tabIndex: tabIndex }, fixedHeader ? /*#__PURE__*/React.cloneElement(getHeaderCellContent(true), { style: { display: 'flex', height: 0, overflow: 'hidden', paddingBottom: 0, paddingTop: 0, visibility: 'hidden' } }) : getHeaderCellContent(), fixedHeader ? /*#__PURE__*/React.createElement(CellFixed, null, /*#__PURE__*/React.cloneElement(getHeaderCellContent(), { style: { alignItems: 'center', display: 'flex', flex: '1 1 auto', lineHeight: 1.25, width: '100%' }, tabIndex: sortable ? 0 : null })) : null); }; // ### Display Name // Always use the canonical component name as the React display name. DataTableHeaderCell.displayName = DATA_TABLE_HEADER_CELL; DataTableHeaderCell.propTypes = propTypes; export default DataTableHeaderCell; //# sourceMappingURL=header-cell.js.map