UNPKG

@carbon/react

Version:

React components for the Carbon Design System

200 lines (193 loc) 6.99 kB
/** * Copyright IBM Corp. 2016, 2023 * * This source code is licensed under the Apache-2.0 license found in the * LICENSE file in the root directory of this source tree. */ 'use strict'; Object.defineProperty(exports, '__esModule', { value: true }); var _rollupPluginBabelHelpers = require('../../_virtual/_rollupPluginBabelHelpers.js'); var cx = require('classnames'); var PropTypes = require('prop-types'); var React = require('react'); var iconsReact = require('@carbon/icons-react'); require('./state/sorting.js'); var useId = require('../../internal/useId.js'); var usePrefix = require('../../internal/usePrefix.js'); var index = require('../AILabel/index.js'); var utils = require('../../internal/utils.js'); var sortStates = require('./state/sortStates.js'); const defaultScope = 'col'; const translationKeys = { buttonDescription: 'carbon.table.header.icon.description' }; const translateWithId = (key, args) => { if (args && key === translationKeys.buttonDescription) { if (args.isSortHeader && sortStates.sortStates) { // When transitioning, we know that the sequence of states is as follows: // NONE -> ASC -> DESC -> NONE if (args.sortDirection === sortStates.sortStates.NONE) { return `Click to sort rows by ${args.header} header in ascending order`; } if (args.sortDirection === sortStates.sortStates.ASC) { return `Click to sort rows by ${args.header} header in descending order`; } return `Click to unsort rows by ${args.header} header`; } return `Click to sort rows by ${args.header} header in ascending order`; } return ''; }; const sortDirections = { [sortStates.sortStates.NONE]: 'none', [sortStates.sortStates.ASC]: 'ascending', [sortStates.sortStates.DESC]: 'descending' }; const TableHeader = /*#__PURE__*/React.forwardRef(function TableHeader({ className: headerClassName, children, colSpan, decorator, isSortable = false, isSortHeader, onClick, scope = defaultScope, sortDirection, translateWithId: t = translateWithId, slug, id, ...rest }, ref) { const prefix = usePrefix.usePrefix(); const uniqueId = useId.useId('table-sort'); // AILabel is always size `mini` const AILableRef = React.useRef(null); const candidate = slug ?? decorator; const candidateIsAILabel = utils.isComponentElement(candidate, index.AILabel); const colHasAILabel = candidateIsAILabel; const normalizedDecorator = candidateIsAILabel ? /*#__PURE__*/React.cloneElement(candidate, { size: 'mini', ref: AILableRef }) : null; const headerLabelClassNames = cx({ [`${prefix}--table-header-label`]: true, [`${prefix}--table-header-label--slug ${prefix}--table-header-label--ai-label`]: colHasAILabel, [`${prefix}--table-header-label--decorator`]: decorator }); if (!isSortable) { return /*#__PURE__*/React.createElement("th", _rollupPluginBabelHelpers.extends({}, rest, { id: id, className: headerClassName, scope: scope, colSpan: colSpan, ref: ref }), children ? /*#__PURE__*/React.createElement("div", { className: headerLabelClassNames }, children, /*#__PURE__*/React.createElement("div", { className: `${prefix}--table-header-label--decorator-inner` }, normalizedDecorator)) : null); } const className = cx(headerClassName, { [`${prefix}--table-sort`]: true, [`${prefix}--table-sort--active`]: isSortHeader && sortDirection !== sortStates.sortStates.NONE, [`${prefix}--table-sort--descending`]: isSortHeader && sortDirection === sortStates.sortStates.DESC }); const ariaSort = !isSortHeader || !sortDirection ? 'none' : sortDirections[sortDirection]; const sortDescription = t && t('carbon.table.header.icon.description', { header: children, sortDirection, isSortHeader, sortStates: sortStates.sortStates }); const headerClasses = cx(headerClassName, `${prefix}--table-sort__header`, { [`${prefix}--table-sort__header--ai-label`]: colHasAILabel, [`${prefix}--table-sort__header--decorator`]: decorator }); const handleClick = evt => { if (colHasAILabel && AILableRef.current && AILableRef.current.contains(evt.target)) { return; } else if (onClick) { return onClick(evt); } }; return /*#__PURE__*/React.createElement("th", { id: id, "aria-sort": ariaSort, className: headerClasses, colSpan: colSpan, ref: ref, scope: scope }, /*#__PURE__*/React.createElement("div", { className: `${prefix}--table-sort__description`, id: uniqueId }, sortDescription), /*#__PURE__*/React.createElement("button", _rollupPluginBabelHelpers.extends({ type: "button", "aria-describedby": uniqueId, className: className, onClick: handleClick }, rest), /*#__PURE__*/React.createElement("span", { className: `${prefix}--table-sort__flex` }, /*#__PURE__*/React.createElement("div", { className: `${prefix}--table-header-label` }, children), /*#__PURE__*/React.createElement(iconsReact.ArrowUp, { size: 20, className: `${prefix}--table-sort__icon` }), /*#__PURE__*/React.createElement(iconsReact.ArrowsVertical, { size: 20, className: `${prefix}--table-sort__icon-unsorted` }), /*#__PURE__*/React.createElement("div", { className: `${prefix}--table-header-label--decorator-inner` }, normalizedDecorator)))); }); TableHeader.propTypes = { /** * Pass in children that will be embedded in the table header label */ children: PropTypes.node, /** * Specify an optional className to be applied to the container node */ className: PropTypes.string, /** * Specify `colSpan` as a non-negative integer value to indicate how * many columns the TableHeader cell extends in a table */ colSpan: PropTypes.number, /** * Supply an id to the th element. */ id: PropTypes.string, /** * Specify whether this header is the header by which a table is being sorted * by */ isSortHeader: PropTypes.bool, /** * Specify whether this header is one through which a user can sort the table */ isSortable: PropTypes.bool, /** * Hook that is invoked when the header is clicked */ onClick: PropTypes.func, /** * Specify the scope of this table header. You can find more info about this * attribute at the following URL: * https://developer.mozilla.org/en-US/docs/Web/HTML/Element/th#attr-scope */ scope: PropTypes.string, /** * Specify which direction we are currently sorting by, should be one of DESC, * NONE, or ASC. */ sortDirection: PropTypes.oneOf(Object.values(sortStates.sortStates)), /** * Supply a method to translate internal strings with your i18n tool of * choice. Translation keys are available on the `translationKeys` field for * this component. */ translateWithId: PropTypes.func }; TableHeader.translationKeys = Object.values(translationKeys); TableHeader.displayName = 'TableHeader'; exports.default = TableHeader;