UNPKG

office-ui-fabric-react

Version:

Reusable React components for building experiences for Office 365.

275 lines • 14.1 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); var tslib_1 = require("tslib"); var React = require("react"); var Utilities_1 = require("../../Utilities"); var index_1 = require("../FocusTrapZone/index"); var Modal_styles_1 = require("./Modal.styles"); var Overlay_1 = require("../../Overlay"); var Layer_1 = require("../../Layer"); var index_2 = require("../Popup/index"); var withResponsiveMode_1 = require("../../utilities/decorators/withResponsiveMode"); var index_3 = require("../Callout/index"); var index_4 = require("../Icon/index"); var index_5 = require("../../utilities/DraggableZone/index"); // @TODO - need to change this to a panel whenever the breakpoint is under medium (verify the spec) var DefaultLayerProps = { eventBubblingEnabled: false }; var getClassNames = Utilities_1.classNamesFunction(); var ModalBase = /** @class */ (function (_super) { tslib_1.__extends(ModalBase, _super); function ModalBase(props) { var _this = _super.call(this, props) || this; _this._focusTrapZone = React.createRef(); // Allow the user to scroll within the modal but not on the body _this._allowScrollOnModal = function (elt) { if (elt) { Utilities_1.allowScrollOnElement(elt, _this._events); } else { _this._events.off(_this._scrollableContent); } _this._scrollableContent = elt; }; _this._onModalContextMenuClose = function () { _this.setState({ isModalMenuOpen: false }); }; _this._onModalClose = function () { _this._lastSetX = 0; _this._lastSetY = 0; _this.setState({ isModalMenuOpen: false, isInKeyboardMoveMode: false, isOpen: false, x: 0, y: 0 }); // Call the onDismiss callback if (_this.props.onDismissed) { _this.props.onDismissed(); } }; _this._onDragStart = function () { _this.setState({ isModalMenuOpen: false, isInKeyboardMoveMode: false }); }; _this._onDrag = function (_, ui) { var _a = _this.state, x = _a.x, y = _a.y; _this.setState({ x: x + ui.delta.x, y: y + ui.delta.y }); }; _this._onDragStop = function () { _this.focus(); }; _this._onDialogKeyUp = function (event) { // Need to handle the CTRL + ALT + SPACE key during keyup due to FireFox bug: // https://bugzilla.mozilla.org/show_bug.cgi?id=1220143 // Otherwise it would continue to fire a click even if the event was cancelled // during mouseDown. if (event.altKey && event.ctrlKey && event.keyCode === Utilities_1.KeyCodes.space) { _this.setState({ isModalMenuOpen: !_this.state.isModalMenuOpen }); event.preventDefault(); event.stopPropagation(); } }; _this._onDialogKeyDown = function (event) { if (event.altKey && event.ctrlKey && event.keyCode === Utilities_1.KeyCodes.space) { // CTRL + ALT + SPACE is handled during keyUp event.preventDefault(); event.stopPropagation(); return; } if (_this.state.isModalMenuOpen && (event.altKey || event.keyCode === Utilities_1.KeyCodes.escape)) { _this.setState({ isModalMenuOpen: false }); } if (_this.state.isInKeyboardMoveMode && (event.keyCode === Utilities_1.KeyCodes.escape || event.keyCode === Utilities_1.KeyCodes.enter)) { _this.setState({ isInKeyboardMoveMode: false }); event.preventDefault(); event.stopPropagation(); } if (_this.state.isInKeyboardMoveMode) { var handledEvent = true; var delta = _this._getMoveDelta(event); switch (event.keyCode) { case Utilities_1.KeyCodes.escape: _this.setState({ x: _this._lastSetX, y: _this._lastSetY }); case Utilities_1.KeyCodes.enter: { _this._lastSetX = 0; _this._lastSetY = 0; _this.setState({ isInKeyboardMoveMode: false }); break; } case Utilities_1.KeyCodes.up: { _this.setState({ y: _this.state.y - delta }); break; } case Utilities_1.KeyCodes.down: { _this.setState({ y: _this.state.y + delta }); break; } case Utilities_1.KeyCodes.left: { _this.setState({ x: _this.state.x - delta }); break; } case Utilities_1.KeyCodes.right: { _this.setState({ x: _this.state.x + delta }); break; } default: { handledEvent = false; } } if (handledEvent) { event.preventDefault(); event.stopPropagation(); } } }; _this._onEnterKeyboardMoveMode = function () { _this._lastSetX = _this.state.x; _this._lastSetY = _this.state.y; _this.setState({ isInKeyboardMoveMode: true, isModalMenuOpen: false }); }; _this._onExitKeyboardMoveMode = function () { _this._lastSetX = 0; _this._lastSetY = 0; _this.setState({ isInKeyboardMoveMode: false }); }; _this.state = { id: Utilities_1.getId('Modal'), isOpen: props.isOpen, isVisible: props.isOpen, hasBeenOpened: props.isOpen, x: 0, y: 0 }; _this._lastSetX = 0; _this._lastSetY = 0; _this._warnDeprecations({ onLayerDidMount: 'layerProps.onLayerDidMount' }); return _this; } // tslint:disable-next-line function-name ModalBase.prototype.UNSAFE_componentWillReceiveProps = function (newProps) { clearTimeout(this._onModalCloseTimer); // Opening the dialog if (newProps.isOpen) { if (!this.state.isOpen) { // First Open this.setState({ isOpen: true }); } else { // Modal has been opened // Reopen during closing this.setState({ hasBeenOpened: true, isVisible: true }); if (newProps.topOffsetFixed) { var dialogMain = document.getElementsByClassName('ms-Dialog-main'); var modalRectangle = void 0; if (dialogMain.length > 0) { modalRectangle = dialogMain[0].getBoundingClientRect(); this.setState({ modalRectangleTop: modalRectangle.top }); } } } } // Closing the dialog if (!newProps.isOpen && this.state.isOpen) { this._onModalCloseTimer = this._async.setTimeout(this._onModalClose, parseFloat(Modal_styles_1.animationDuration) * 1000); this.setState({ isVisible: false }); } }; ModalBase.prototype.componentDidUpdate = function (prevProps, prevState) { if (!prevProps.isOpen && !prevState.isVisible) { this.setState({ isVisible: true }); } }; ModalBase.prototype.render = function () { var _a = this.props, className = _a.className, containerClassName = _a.containerClassName, scrollableContentClassName = _a.scrollableContentClassName, elementToFocusOnDismiss = _a.elementToFocusOnDismiss, firstFocusableSelector = _a.firstFocusableSelector, forceFocusInsideTrap = _a.forceFocusInsideTrap, ignoreExternalFocusing = _a.ignoreExternalFocusing, isBlocking = _a.isBlocking, isClickableOutsideFocusTrap = _a.isClickableOutsideFocusTrap, isDarkOverlay = _a.isDarkOverlay, onDismiss = _a.onDismiss, layerProps = _a.layerProps, overlay = _a.overlay, responsiveMode = _a.responsiveMode, titleAriaId = _a.titleAriaId, styles = _a.styles, subtitleAriaId = _a.subtitleAriaId, theme = _a.theme, topOffsetFixed = _a.topOffsetFixed, onLayerDidMount = _a.onLayerDidMount, isModeless = _a.isModeless, dragOptions = _a.dragOptions; var _b = this.state, isOpen = _b.isOpen, isVisible = _b.isVisible, hasBeenOpened = _b.hasBeenOpened, modalRectangleTop = _b.modalRectangleTop, x = _b.x, y = _b.y, isInKeyboardMoveMode = _b.isInKeyboardMoveMode; if (!isOpen) { return null; } var layerClassName = layerProps === undefined ? '' : layerProps.className; var classNames = getClassNames(styles, { theme: theme, className: className, containerClassName: containerClassName, scrollableContentClassName: scrollableContentClassName, isOpen: isOpen, isVisible: isVisible, hasBeenOpened: hasBeenOpened, modalRectangleTop: modalRectangleTop, topOffsetFixed: topOffsetFixed, isModeless: isModeless, layerClassName: layerClassName, isDefaultDragHandle: dragOptions && !dragOptions.dragHandleSelector }); var mergedLayerProps = tslib_1.__assign({}, DefaultLayerProps, this.props.layerProps, { onLayerDidMount: layerProps && layerProps.onLayerDidMount ? layerProps.onLayerDidMount : onLayerDidMount, insertFirst: isModeless, className: classNames.layer }); var modalContent = (React.createElement(index_1.FocusTrapZone, { componentRef: this._focusTrapZone, className: classNames.main, elementToFocusOnDismiss: elementToFocusOnDismiss, isClickableOutsideFocusTrap: isModeless || isClickableOutsideFocusTrap || !isBlocking, ignoreExternalFocusing: ignoreExternalFocusing, forceFocusInsideTrap: isModeless ? !isModeless : forceFocusInsideTrap, firstFocusableSelector: firstFocusableSelector, focusPreviouslyFocusedInnerElement: true, onKeyDown: dragOptions ? this._onDialogKeyDown : undefined, onKeyUp: dragOptions ? this._onDialogKeyUp : undefined, onBlur: isInKeyboardMoveMode ? this._onExitKeyboardMoveMode : undefined }, dragOptions && isInKeyboardMoveMode && (React.createElement("div", { className: classNames.keyboardMoveIconContainer }, dragOptions.keyboardMoveIconProps ? (React.createElement(index_4.Icon, tslib_1.__assign({}, dragOptions.keyboardMoveIconProps))) : (React.createElement(index_4.Icon, { iconName: "move", className: classNames.keyboardMoveIcon })))), React.createElement("div", { ref: this._allowScrollOnModal, className: classNames.scrollableContent, "data-is-scrollable": true }, dragOptions && this.state.isModalMenuOpen && (React.createElement(dragOptions.menu, { items: [ { key: 'move', text: dragOptions.moveMenuItemText, onClick: this._onEnterKeyboardMoveMode }, { key: 'close', text: dragOptions.closeMenuItemText, onClick: this._onModalClose } ], onDismiss: this._onModalContextMenuClose, alignTargetEdge: true, coverTarget: true, directionalHint: index_3.DirectionalHint.topLeftEdge, directionalHintFixed: true, shouldFocusOnMount: true, target: this._scrollableContent })), this.props.children))); // @temp tuatology - Will adjust this to be a panel at certain breakpoints if (responsiveMode >= withResponsiveMode_1.ResponsiveMode.small) { return (React.createElement(Layer_1.Layer, tslib_1.__assign({}, mergedLayerProps), React.createElement(index_2.Popup, { role: isModeless || !isBlocking ? 'dialog' : 'alertdialog', "aria-modal": !isModeless, ariaLabelledBy: titleAriaId, ariaDescribedBy: subtitleAriaId, onDismiss: onDismiss }, React.createElement("div", { className: classNames.root }, !isModeless && React.createElement(Overlay_1.Overlay, tslib_1.__assign({ isDarkThemed: isDarkOverlay, onClick: isBlocking ? undefined : onDismiss }, overlay)), dragOptions ? (React.createElement(index_5.DraggableZone, { handleSelector: dragOptions.dragHandleSelector || "." + classNames.main.split(' ')[0], preventDragSelector: "button", onStart: this._onDragStart, onDragChange: this._onDrag, onStop: this._onDragStop, position: { x: x, y: y } }, modalContent)) : (modalContent))))); } return null; }; ModalBase.prototype.focus = function () { if (this._focusTrapZone.current) { this._focusTrapZone.current.focus(); } }; ModalBase.prototype._getMoveDelta = function (event) { var delta = 10; if (event.shiftKey) { if (!event.ctrlKey) { delta = 50; } } else if (event.ctrlKey) { delta = 1; } return delta; }; ModalBase.defaultProps = { isOpen: false, isDarkOverlay: true, isBlocking: false, className: '', containerClassName: '' }; ModalBase = tslib_1.__decorate([ withResponsiveMode_1.withResponsiveMode ], ModalBase); return ModalBase; }(Utilities_1.BaseComponent)); exports.ModalBase = ModalBase; //# sourceMappingURL=Modal.base.js.map