UNPKG

azure-devops-ui

Version:

React components for building web UI in Azure DevOps

144 lines (143 loc) 7.19 kB
import { __assign, __extends } from "tslib"; import "../../CommonImports"; import "../../Core/core.css"; import * as React from "react"; import { FocusGroupContext } from '../../FocusGroup'; import { FocusZoneContext } from '../../FocusZone'; import { MouseWithin } from '../../MouseWithin'; import { css, getSafeId, KeyCode, setFocusVisible } from '../../Util'; import { getTabIndex } from '../../Utilities/Focus'; var Expandable = /** @class */ (function (_super) { __extends(Expandable, _super); function Expandable() { var _this = _super !== null && _super.apply(this, arguments) || this; _this.state = { expanded: false }; _this.collapse = function () { if (_this.state.expanded) { _this.setState({ expanded: false }); if (_this.props.onCollapse) { _this.props.onCollapse(); } } }; _this.expand = function () { if (!_this.state.expanded) { _this.setState({ expanded: !_this.state.expanded }); if (_this.props.onExpand) { _this.props.onExpand(); } } }; _this.onClick = function (event) { if (!_this.props.disabled) { if (!event.defaultPrevented) { if (!_this.state.expanded && !_this.ignoreClick) { _this.expand(); event.preventDefault(); } } } else { event.preventDefault(); } }; _this.onKeyDown = function (event) { if (!event.defaultPrevented) { // If the control key is pressed we want to navigate in a focus zone and not open the menu if (event.ctrlKey) { return; } if (!_this.state.expanded && _this.isExpandKey(event)) { _this.ignoreClick = false; _this.expand(); event.preventDefault(); } } }; _this.onMouseDown = function () { // If the callout is expanded when we click on it, we want to ignore the click // and let the blur occur and close the callout. _this.ignoreClick = _this.state.expanded; }; return _this; } Expandable.prototype.render = function () { var expanded = this.state.expanded; var child = this.props.children; return (React.createElement(React.Fragment, null, child({ expanded: expanded, onClick: this.onClick, onKeyDown: this.onKeyDown, onMouseDown: this.onMouseDown }), expanded && this.props.renderCallout && this.props.renderCallout())); }; Expandable.prototype.isExpandKey = function (event) { return (Array.isArray(this.props.expandKey) && this.props.expandKey.indexOf(event.which) !== -1) || event.which === this.props.expandKey; }; Expandable.defaultProps = { expandKey: KeyCode.downArrow }; return Expandable; }(React.Component)); export { Expandable }; var expandableContainerId = 1; /** * ExpandableContainer is a specialized form of Expandable and generally shouldn't be used. * It's main goal is to provider mouse enter/leave behavior for collapsing. * * @NOTE: This component MAY be deprecated in the future, use <Expandable /> instead. */ var ExpandableContainer = /** @class */ (function (_super) { __extends(ExpandableContainer, _super); function ExpandableContainer() { var _this = _super !== null && _super.apply(this, arguments) || this; _this.element = React.createRef(); _this.expandedOnHover = false; _this.expandable = React.createRef(); _this.expandableId = "expandableContainer-" + expandableContainerId++; _this.collapse = function () { if (_this.expandable.current) { _this.expandable.current.collapse(); } }; _this.expand = function () { if (_this.expandable.current) { _this.expandable.current.expand(); } }; _this.onFocus = function (event) { // Only call onFocus for the FocusGroup is the expandable itself is getting focus. // Otherwise it is going to a child element and it should manage focus appropriately. if (_this.props.id && (!_this.element.current || _this.element.current === event.target)) { _this.context.onFocus(_this.props.id); } }; _this.onMouseEnter = function () { if (_this.props.expandOnHover) { _this.expandedOnHover = true; setFocusVisible(false); _this.expand(); } }; _this.onMouseLeave = function () { if (_this.expandedOnHover) { _this.collapse(); } }; _this.renderCallout = function () { return _this.props.renderCallout(_this.expandable.current, _this.expandableId, _this.element.current); }; return _this; } ExpandableContainer.prototype.render = function () { var _this = this; return (React.createElement(FocusZoneContext.Consumer, null, function (zoneContext) { return (React.createElement(MouseWithin, { enterDelay: _this.props.expandDelay, leaveDelay: _this.props.collapseDelay, onMouseEnter: _this.onMouseEnter, onMouseLeave: _this.onMouseLeave, updateStateOnMouseChange: false }, function (mouseContext) { return (React.createElement(Expandable, __assign({}, _this.props, { renderCallout: undefined, ref: _this.expandable }), function (expandableProps) { return (React.createElement("div", { "aria-controls": expandableProps.expanded ? getSafeId(_this.props.expandableId) : undefined, "aria-expanded": expandableProps.expanded, "aria-haspopup": true, "aria-label": _this.props.ariaLabel, className: css(_this.props.className, "bolt-expandable-container flex-row flex-center", expandableProps.expanded && "expanded"), "data-focuszone": !_this.props.disabled && !_this.props.excludeFocusZone ? zoneContext.focuszoneId : undefined, id: getSafeId(_this.props.id), onClick: expandableProps.onClick, onFocus: _this.onFocus, onKeyDown: expandableProps.onKeyDown, onMouseDown: expandableProps.onMouseDown, onMouseEnter: mouseContext.onMouseEnter, onMouseLeave: mouseContext.onMouseLeave, role: _this.props.role || "button", tabIndex: getTabIndex(_this.props, _this.context), ref: _this.element }, _this.props.children, expandableProps.expanded && _this.renderCallout())); })); })); })); }; ExpandableContainer.contextType = FocusGroupContext; ExpandableContainer.defaultProps = { collapseDelay: 250, expandDelay: 250, expandKey: [KeyCode.downArrow, KeyCode.enter] }; return ExpandableContainer; }(React.Component)); export { ExpandableContainer };