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
JavaScript
"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);