UNPKG

terra-table

Version:

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

242 lines (236 loc) 9.42 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 _bind = _interopRequireDefault(require("classnames/bind")); var _reactIntl = require("react-intl"); var KeyCode = _interopRequireWildcard(require("keycode-js")); var _propTypes = _interopRequireDefault(require("prop-types")); var _terraThemeContext = _interopRequireDefault(require("terra-theme-context")); var _ColumnContext = _interopRequireDefault(require("../utils/ColumnContext")); var _GridContext = _interopRequireWildcard(require("../utils/GridContext")); var _ColumnResizeHandleModule = _interopRequireDefault(require("./ColumnResizeHandle.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; } var cx = _bind.default.bind(_ColumnResizeHandleModule.default); var propTypes = { /** * Required string representing a unique identifier for the column resize handle. */ id: _propTypes.default.string.isRequired, /** * The cell's column position in the grid. This is zero based. */ columnIndex: _propTypes.default.number, /** * Text of the column associated with the divider. */ columnText: _propTypes.default.string.isRequired, /** * Number that specifies the Width of the associated column in pixels. */ columnWidth: _propTypes.default.number.isRequired, /** * Number that specifies the height of the resize handle in pixels. */ height: _propTypes.default.number.isRequired, /** * String that specifies the initial height for the resize handler to accommodate actions row. */ initialHeight: _propTypes.default.string, /** * Numeric increment in pixels to adjust column width when resizing via the keyboard. */ columnResizeIncrement: _propTypes.default.number, /** * Control is the active element */ isActive: _propTypes.default.bool, /** * Handler function to update isActive for parent. */ setIsActive: _propTypes.default.func, /** * Number that specifies the minimum column width in pixels. */ minimumWidth: _propTypes.default.number.isRequired, /** * Number that specifies the maximum column width in pixels. */ maximumWidth: _propTypes.default.number.isRequired, /** * Function that is called when onMouseDown event is triggered for the resize handle. */ onResizeMouseDown: _propTypes.default.func.isRequired, /** * Function that is called when onMouseDown event is triggered for the resize handle. */ onResizeMouseUp: _propTypes.default.func.isRequired, /** * Function that is called when the the keyboard is used to adjust the column size. */ onResizeHandleChange: _propTypes.default.func, /** * @private * The intl object containing translations. This is retrieved from the context automatically by injectIntl. */ intl: _propTypes.default.shape({ formatMessage: _propTypes.default.func }).isRequired }; var defaultProps = { columnResizeIncrement: 10 }; var ColumnResizeHandle = function ColumnResizeHandle(props) { var id = props.id, columnIndex = props.columnIndex, columnResizeIncrement = props.columnResizeIncrement, columnText = props.columnText, columnWidth = props.columnWidth, height = props.height, intl = props.intl, isActive = props.isActive, maximumWidth = props.maximumWidth, minimumWidth = props.minimumWidth, initialHeight = props.initialHeight, onResizeHandleChange = props.onResizeHandleChange, onResizeMouseDown = props.onResizeMouseDown, onResizeMouseUp = props.onResizeMouseUp, setIsActive = props.setIsActive; var theme = (0, _react.useContext)(_terraThemeContext.default); var gridContext = (0, _react.useContext)(_GridContext.default); var columnContext = (0, _react.useContext)(_ColumnContext.default); var isGridContext = gridContext.role === _GridContext.GridConstants.GRID; // Ref variable for native resize handle element var resizeHandleRef = (0, _react.useRef)(); var _useState = (0, _react.useState)(true), _useState2 = (0, _slicedToArray2.default)(_useState, 2), isNavigationEnabled = _useState2[0], setNavigationEnabled = _useState2[1]; (0, _react.useEffect)(function () { if (isActive) { resizeHandleRef.current.focus(); } }, [isActive]); var onMouseDown = function onMouseDown(event) { // Set focus to resize handle DOM element resizeHandleRef.current.focus(); onResizeMouseDown(event); // Prevent event bubbling since necessary actions are handled by this component event.stopPropagation(); // Prevent default dragging behavior event.preventDefault(); }; var onMouseUp = function onMouseUp() { onResizeMouseUp(); }; var fitToTable = function fitToTable() { // Update resize handle height to match parent table height resizeHandleRef.current.style.height = "".concat(height, "px"); }; var onMouseLeave = function onMouseLeave() { if (document.activeElement !== resizeHandleRef.current) { resizeHandleRef.current.style.height = initialHeight || '100%'; } }; // Handle column resize handle keyboard navigation var onKeyDown = function onKeyDown(event) { var key = event.keyCode; switch (key) { case KeyCode.KEY_SPACE: case KeyCode.KEY_RETURN: setNavigationEnabled(false); // Lock focus into component resizeHandleRef.current.focus(); // Assistive technologies should make announcement for focus locked columnContext.setColumnHeaderAriaLiveMessage(intl.formatMessage({ id: 'Terra.table.cell-focus-trapped' })); event.stopPropagation(); event.preventDefault(); break; case KeyCode.KEY_ESCAPE: // Release focus lock columnContext.setColumnHeaderAriaLiveMessage(intl.formatMessage({ id: 'Terra.table.resume-navigation' })); setNavigationEnabled(true); break; case KeyCode.KEY_RIGHT: if (onResizeHandleChange && !isNavigationEnabled) { // Increase column width onResizeHandleChange(columnIndex, columnResizeIncrement); } break; case KeyCode.KEY_LEFT: if (onResizeHandleChange && !isNavigationEnabled) { // Decrease column width onResizeHandleChange(columnIndex, -columnResizeIncrement); } break; default: } if (!isNavigationEnabled) { event.stopPropagation(); event.preventDefault(); } }; // Prevent click event propagation var onClick = function onClick(event) { // Prevent event bubbling since necessary actions are handled by this component event.stopPropagation(); }; var onBlur = function onBlur() { setNavigationEnabled(true); setIsActive(false); }; return ( /*#__PURE__*/ // eslint-disable-next-line jsx-a11y/no-noninteractive-element-interactions, jsx-a11y/no-static-element-interactions _react.default.createElement("div", { id: id, ref: resizeHandleRef, draggable: true, role: isNavigationEnabled ? null : 'slider', tabIndex: isGridContext ? -1 : 0, "aria-hidden": isGridContext ? !isActive : false, "aria-valuemin": isActive ? minimumWidth : null, "aria-valuenow": isActive ? columnWidth : null, "aria-valuemax": isActive ? maximumWidth : null, "aria-label": isActive && isNavigationEnabled ? intl.formatMessage({ id: 'Terra.table.resize-handle-template' }, { columnText: columnText }) : null, "aria-valuetext": !isNavigationEnabled ? intl.formatMessage({ id: 'Terra.table.resize-handle-value-text' }, { columnWidth: columnWidth }) : null // eslint-disable-next-line react/forbid-dom-props , style: { height: "".concat(height, "px") }, onMouseDown: onMouseDown, onMouseUp: onMouseUp, onMouseEnter: fitToTable, onMouseLeave: onMouseLeave, onKeyDown: onKeyDown, onClick: onClick, onFocus: fitToTable, onBlur: onBlur, className: cx('resize-handle', theme.className, { 'resize-handle-selected': !isNavigationEnabled }) }) ); }; ColumnResizeHandle.propTypes = propTypes; ColumnResizeHandle.defaultProps = defaultProps; var _default = exports.default = (0, _reactIntl.injectIntl)(ColumnResizeHandle);