UNPKG

@carbon/react

Version:

React components for the Carbon Design System

201 lines (194 loc) 7.06 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'); var useId = require('../../internal/useId.js'); var usePrefix = require('../../internal/usePrefix.js'); var sortStates = require('./state/sortStates.js'); var index = require('../AILabel/index.js'); var utils = require('../../internal/utils.js'); const defaultScope = 'col'; const translationIds = { 'carbon.table.header.icon.description': 'carbon.table.header.icon.description' }; const defaultTranslations = { [translationIds['carbon.table.header.icon.description']]: 'Click to sort rows by header in ascending order' }; const defaultTranslateWithId = (messageId, args) => { if (args && messageId === translationIds['carbon.table.header.icon.description']) { 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 defaultTranslations[messageId]; }; const sortDirections = { [sortStates.sortStates.NONE]: 'none', [sortStates.sortStates.ASC]: 'ascending', [sortStates.sortStates.DESC]: 'descending' }; const frFn = React.forwardRef; const TableHeader = frFn((props, ref) => { const { className: headerClassName, children, colSpan, decorator, isSortable = false, isSortHeader, onClick, scope = defaultScope, sortDirection, translateWithId: t = defaultTranslateWithId, slug, id, ...rest } = props; 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 }) : candidate; 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)), /** * Translates component strings using your i18n tool. */ translateWithId: PropTypes.func }; TableHeader.displayName = 'TableHeader'; exports.default = TableHeader;