UNPKG

terra-table

Version:

The Terra Table component provides user a way to display data in an accessible table format.

209 lines (202 loc) 9.49 kB
"use strict"; var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault"); var _typeof = require("@babel/runtime/helpers/typeof"); Object.defineProperty(exports, "__esModule", { value: true }); exports.default = void 0; var _slicedToArray2 = _interopRequireDefault(require("@babel/runtime/helpers/slicedToArray")); var _react = _interopRequireWildcard(require("react")); var _propTypes = _interopRequireDefault(require("prop-types")); var _bind = _interopRequireDefault(require("classnames/bind")); var _resizeObserverPolyfill = _interopRequireDefault(require("resize-observer-polyfill")); var _ColumnHeaderCell = _interopRequireDefault(require("./ColumnHeaderCell")); var _columnShape = _interopRequireDefault(require("../proptypes/columnShape")); var _ColumnHeaderModule = _interopRequireDefault(require("./ColumnHeader.module.scss")); function _getRequireWildcardCache(e) { if ("function" != typeof WeakMap) return null; var r = new WeakMap(), t = new WeakMap(); return (_getRequireWildcardCache = function _getRequireWildcardCache(e) { return e ? t : r; })(e); } function _interopRequireWildcard(e, r) { if (!r && e && e.__esModule) return e; if (null === e || "object" != _typeof(e) && "function" != typeof e) return { default: e }; var t = _getRequireWildcardCache(r); if (t && t.has(e)) return t.get(e); var n = { __proto__: null }, a = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var u in e) if ("default" !== u && {}.hasOwnProperty.call(e, u)) { var i = a ? Object.getOwnPropertyDescriptor(e, u) : null; i && (i.get || i.set) ? Object.defineProperty(n, u, i) : n[u] = e[u]; } return n.default = e, t && t.set(e, n), n; } /* eslint-disable react-hooks/exhaustive-deps */ var cx = _bind.default.bind(_ColumnHeaderModule.default); var propTypes = { /** * Unique identifier for the parent table */ tableId: _propTypes.default.string.isRequired, /** * Data for columns. By default, columns will be presented in the order given. */ columns: _propTypes.default.arrayOf(_columnShape.default).isRequired, /** * String that specifies the column header height. Any valid CSS height value accepted. */ headerHeight: _propTypes.default.string.isRequired, /** * Number that specifies the height of the table in pixels. */ tableHeight: _propTypes.default.number, /** * Column index for cell that can receive tab focus. */ activeColumnIndex: _propTypes.default.number, /** * Row index for cell that can receive tab focus. */ focusedRowIndex: _propTypes.default.number, /** * CallBack to trigger re-focusing when focused row or col didn't change, but focus update is needed */ triggerFocus: _propTypes.default.func, /** * Specifies if resize handle should be active. */ isActiveColumnResizing: _propTypes.default.bool, /** * Numeric increment in pixels to adjust column width when resizing via the keyboard. */ columnResizeIncrement: _propTypes.default.number, /** * Function that is called when a selectable header cell is selected. Parameters: * @param {string} columnId columnId */ onColumnSelect: _propTypes.default.func, /** * Function that is called when the mouse down event is triggered on the column resize handle. */ onResizeMouseDown: _propTypes.default.func, /** * Function that is called when the the keyboard is used to adjust the column size. */ onResizeHandleChange: _propTypes.default.func, /** * Boolean indicating whether or not the table columns should be displayed. */ hasVisibleColumnHeaders: _propTypes.default.bool, /** * A Boolean value specifying whether the table has actions in column headers. */ hasColumnHeaderActions: _propTypes.default.bool }; var defaultProps = { hasVisibleColumnHeaders: true }; var ColumnHeader = function ColumnHeader(props) { var tableId = props.tableId, activeColumnIndex = props.activeColumnIndex, focusedRowIndex = props.focusedRowIndex, triggerFocus = props.triggerFocus, isActiveColumnResizing = props.isActiveColumnResizing, columnResizeIncrement = props.columnResizeIncrement, columns = props.columns, headerHeight = props.headerHeight, tableHeight = props.tableHeight, onColumnSelect = props.onColumnSelect, onResizeMouseDown = props.onResizeMouseDown, onResizeHandleChange = props.onResizeHandleChange, hasVisibleColumnHeaders = props.hasVisibleColumnHeaders, hasColumnHeaderActions = props.hasColumnHeaderActions; // Header container height observer --------------- var headerRef = (0, _react.useRef)(); var _useState = (0, _react.useState)(0), _useState2 = (0, _slicedToArray2.default)(_useState, 2), headerContainerHeight = _useState2[0], setHeaderContainerHeight = _useState2[1]; (0, _react.useEffect)(function () { var resizeObserver = new _resizeObserverPolyfill.default(function () { var heightOffset = hasColumnHeaderActions ? 2 : 1; // needs 2 pixels if actions row exists in headers to avoid scroll setHeaderContainerHeight(headerRef.current.offsetHeight - heightOffset); }); resizeObserver.observe(headerRef.current); return function () { resizeObserver.disconnect(); }; }, [headerRef]); // Active resize handle management ------------------- // The active column and neighbour cell have to be known to both header and action cells as they share resize handle. var _useState3 = (0, _react.useState)(), _useState4 = (0, _slicedToArray2.default)(_useState3, 2), activeResizeHandlerColumnId = _useState4[0], setActiveResizeHandlerColumnId = _useState4[1]; var resizeHandleStateSetter = (0, _react.useCallback)(function (columnId) { if (columnId !== activeResizeHandlerColumnId) { setActiveResizeHandlerColumnId(columnId); } }, [activeResizeHandlerColumnId]); // Is needed to adjust the header column resize handler to accommodate actions header height var initialHeight = hasColumnHeaderActions ? "".concat(headerContainerHeight, "px") : undefined; return /*#__PURE__*/_react.default.createElement("thead", { ref: headerRef }, /*#__PURE__*/_react.default.createElement("tr", { "aria-rowindex": 1, "data-row-id": "".concat(tableId, "-header-row"), className: cx('column-header-row', { hidden: !hasVisibleColumnHeaders }), height: hasVisibleColumnHeaders ? headerHeight : undefined }, columns.map(function (column, columnIndex) { return /*#__PURE__*/_react.default.createElement(_ColumnHeaderCell.default, { key: "".concat(column.id, "-headerCell"), id: "".concat(column.id, "-headerCell"), tableId: tableId, columnId: column.id, columnIndex: columnIndex, columnSpan: column.columnSpan, displayName: column.displayName, isDisplayVisible: column.isDisplayVisible, width: column.width, minimumWidth: column.minimumWidth, maximumWidth: column.maximumWidth, headerHeight: headerHeight, isResizable: hasVisibleColumnHeaders && column.isResizable, initialHeight: initialHeight, isResizeHandleActive: activeResizeHandlerColumnId === column.id, resizeHandleStateSetter: resizeHandleStateSetter, isSelectable: hasVisibleColumnHeaders && column.isSelectable, tableHeight: tableHeight, triggerFocus: triggerFocus, isActive: activeColumnIndex === columnIndex && focusedRowIndex === 0 // can be 2 rows in header , isResizeActive: activeColumnIndex === columnIndex && isActiveColumnResizing, columnResizeIncrement: columnResizeIncrement, hasError: column.hasError, sortIndicator: column.sortIndicator, onColumnSelect: onColumnSelect, onResizeMouseDown: onResizeMouseDown, onResizeHandleChange: onResizeHandleChange, columnHighlightColor: column.columnHighlightColor, columnHighlightDescription: column.columnHighlightDescription }); })), hasColumnHeaderActions && hasVisibleColumnHeaders && /*#__PURE__*/_react.default.createElement("tr", { "aria-rowindex": 2, "data-row-id": "".concat(tableId, "-header-actions-row"), className: cx('column-actions-row', { hidden: !hasVisibleColumnHeaders }) }, columns.map(function (column, columnIndex) { return /*#__PURE__*/_react.default.createElement(_ColumnHeaderCell.default, { key: "".concat(column.id, "-actionCell"), id: "".concat(column.id, "-actionCell"), tableId: tableId, columnId: column.id, isActionCell: true, action: column.action, columnIndex: columnIndex, columnSpan: column.columnSpan, isDisplayVisible: column.isDisplayVisible, width: column.isResizable && column.width, minimumWidth: column.minimumWidth, maximumWidth: column.maximumWidth, headerHeight: headerHeight, isResizable: hasVisibleColumnHeaders && column.isResizable, ownsResizeHandle: focusedRowIndex === 1, isResizeHandleActive: activeResizeHandlerColumnId === column.id, resizeHandleStateSetter: resizeHandleStateSetter // does not need isSelectable prop for actions row , isActive: activeColumnIndex === columnIndex && focusedRowIndex === 1, isResizeActive: activeColumnIndex === columnIndex && isActiveColumnResizing }); }))); }; ColumnHeader.propTypes = propTypes; ColumnHeader.defaultProps = defaultProps; var _default = exports.default = /*#__PURE__*/_react.default.memo(ColumnHeader);