UNPKG

office-ui-fabric-react

Version:

Reusable React components for building experiences for Office 365.

285 lines • 15.7 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); var tslib_1 = require("tslib"); var React = require("react"); var Button_1 = require("../../Button"); var Layer_1 = require("../../Layer"); var Overlay_1 = require("../../Overlay"); var Popup_1 = require("../../Popup"); var Styling_1 = require("../../Styling"); var Utilities_1 = require("../../Utilities"); var index_1 = require("../FocusTrapZone/index"); var Panel_types_1 = require("./Panel.types"); var getClassNames = Utilities_1.classNamesFunction(); var PanelVisibilityState; (function (PanelVisibilityState) { PanelVisibilityState[PanelVisibilityState["closed"] = 0] = "closed"; PanelVisibilityState[PanelVisibilityState["animatingOpen"] = 1] = "animatingOpen"; PanelVisibilityState[PanelVisibilityState["open"] = 2] = "open"; PanelVisibilityState[PanelVisibilityState["animatingClosed"] = 3] = "animatingClosed"; })(PanelVisibilityState || (PanelVisibilityState = {})); var PanelBase = /** @class */ (function (_super) { tslib_1.__extends(PanelBase, _super); function PanelBase(props) { var _this = _super.call(this, props) || this; _this._panel = React.createRef(); _this._animationCallback = null; _this.dismiss = function (ev) { if (_this.props.onDismiss) { _this.props.onDismiss(ev); } if (!ev || (ev && !ev.defaultPrevented)) { _this.close(); } }; // Allow the user to scroll within the panel but not on the body _this._allowScrollOnPanel = function (elt) { if (elt) { Utilities_1.allowScrollOnElement(elt, _this._events); } else { _this._events.off(_this._scrollableContent); } _this._scrollableContent = elt; }; _this._onRenderNavigation = function (props) { if (!_this.props.onRenderNavigationContent && !_this.props.onRenderNavigation && !_this.props.hasCloseButton) { return null; } var _a = _this.props.onRenderNavigationContent, onRenderNavigationContent = _a === void 0 ? _this._onRenderNavigationContent : _a; return React.createElement("div", { className: _this._classNames.navigation }, onRenderNavigationContent(props, _this._onRenderNavigationContent)); }; _this._onRenderNavigationContent = function (props) { var closeButtonAriaLabel = props.closeButtonAriaLabel, hasCloseButton = props.hasCloseButton; var theme = Styling_1.getTheme(); if (hasCloseButton) { // TODO -Issue #5689: Comment in once Button is converted to mergeStyles // const iconButtonStyles = this._classNames.subComponentStyles // ? (this._classNames.subComponentStyles.iconButton as IStyleFunctionOrObject<IButtonStyleProps, IButtonStyles>) // : undefined; return (React.createElement(Button_1.IconButton // TODO -Issue #5689: Comment in once Button is converted to mergeStyles // className={iconButtonStyles} , { // TODO -Issue #5689: Comment in once Button is converted to mergeStyles // className={iconButtonStyles} styles: { root: { height: 'auto', width: '44px', color: theme.palette.neutralSecondary, fontSize: Styling_1.IconFontSizes.large }, rootHovered: { color: theme.palette.neutralPrimary } }, className: _this._classNames.closeButton, onClick: _this._onPanelClick, ariaLabel: closeButtonAriaLabel, title: closeButtonAriaLabel, "data-is-visible": true, iconProps: { iconName: 'Cancel' } })); } return null; }; _this._onRenderHeader = function (props, defaultRender, headerTextId) { var headerText = props.headerText; if (headerText) { return (React.createElement("div", { className: _this._classNames.header }, React.createElement("p", { className: _this._classNames.headerText, id: headerTextId, role: "heading", "aria-level": 2 }, headerText))); } return null; }; _this._onRenderBody = function (props) { return React.createElement("div", { className: _this._classNames.content }, props.children); }; _this._onRenderFooter = function (props) { var _a = _this.props.onRenderFooterContent, onRenderFooterContent = _a === void 0 ? null : _a; if (onRenderFooterContent) { return (React.createElement("div", { className: _this._classNames.footer }, React.createElement("div", { className: _this._classNames.footerInner }, onRenderFooterContent()))); } return null; }; _this._animateTo = function (newVisibilityState) { _this._animationCallback = _this._async.setTimeout(function () { _this.setState({ visibility: newVisibilityState }); _this._onTransitionComplete(); }, 200); }; _this._clearExistingAnimationTimer = function () { if (_this._animationCallback !== null) { _this._async.clearTimeout(_this._animationCallback); } }; _this._onPanelClick = function (ev) { _this.dismiss(ev); }; _this._onTransitionComplete = function () { _this._updateFooterPosition(); if (_this.state.visibility === PanelVisibilityState.open && _this.props.onOpened) { _this.props.onOpened(); } if (_this.state.visibility === PanelVisibilityState.closed && _this.props.onDismissed) { _this.props.onDismissed(); } }; _this._warnDeprecations({ ignoreExternalFocusing: 'focusTrapZoneProps', forceFocusInsideTrap: 'focusTrapZoneProps', firstFocusableSelector: 'focusTrapZoneProps' }); _this.state = { isFooterSticky: false, visibility: PanelVisibilityState.closed, id: Utilities_1.getId('Panel') }; return _this; } PanelBase.getDerivedStateFromProps = function (props, state) { if (props.isOpen === undefined) { return state; } if (props.isOpen && (state.visibility === PanelVisibilityState.closed || state.visibility === PanelVisibilityState.animatingClosed)) { return tslib_1.__assign({}, state, { visibility: PanelVisibilityState.animatingOpen }); } if (!props.isOpen && (state.visibility === PanelVisibilityState.open || state.visibility === PanelVisibilityState.animatingOpen)) { return tslib_1.__assign({}, state, { visibility: PanelVisibilityState.animatingClosed }); } return state; }; PanelBase.prototype.componentDidMount = function () { this._events.on(window, 'resize', this._updateFooterPosition); if (this._shouldListenForOuterClick(this.props)) { this._events.on(document.body, 'mousedown', this._dismissOnOuterClick, true); } if (this.props.isOpen) { this.setState({ visibility: PanelVisibilityState.animatingOpen }); } }; PanelBase.prototype.componentDidUpdate = function (previousProps, previousState) { var shouldListenOnOuterClick = this._shouldListenForOuterClick(this.props); var previousShouldListenOnOuterClick = this._shouldListenForOuterClick(previousProps); if (this.state.visibility !== previousState.visibility) { this._clearExistingAnimationTimer(); if (this.state.visibility === PanelVisibilityState.animatingOpen) { this._animateTo(PanelVisibilityState.open); } else if (this.state.visibility === PanelVisibilityState.animatingClosed) { this._animateTo(PanelVisibilityState.closed); } } if (shouldListenOnOuterClick && !previousShouldListenOnOuterClick) { this._events.on(document.body, 'mousedown', this._dismissOnOuterClick, true); } else if (!shouldListenOnOuterClick && previousShouldListenOnOuterClick) { this._events.off(document.body, 'mousedown', this._dismissOnOuterClick, true); } }; PanelBase.prototype.render = function () { var _a = this.props, _b = _a.className, className = _b === void 0 ? '' : _b, elementToFocusOnDismiss = _a.elementToFocusOnDismiss, firstFocusableSelector = _a.firstFocusableSelector, focusTrapZoneProps = _a.focusTrapZoneProps, forceFocusInsideTrap = _a.forceFocusInsideTrap, hasCloseButton = _a.hasCloseButton, headerText = _a.headerText, _c = _a.headerClassName, headerClassName = _c === void 0 ? '' : _c, ignoreExternalFocusing = _a.ignoreExternalFocusing, isBlocking = _a.isBlocking, isFooterAtBottom = _a.isFooterAtBottom, isLightDismiss = _a.isLightDismiss, isHiddenOnDismiss = _a.isHiddenOnDismiss, layerProps = _a.layerProps, overlayProps = _a.overlayProps, type = _a.type, styles = _a.styles, theme = _a.theme, customWidth = _a.customWidth, _d = _a.onLightDismissClick, onLightDismissClick = _d === void 0 ? this._onPanelClick : _d, _e = _a.onRenderNavigation, onRenderNavigation = _e === void 0 ? this._onRenderNavigation : _e, _f = _a.onRenderHeader, onRenderHeader = _f === void 0 ? this._onRenderHeader : _f, _g = _a.onRenderBody, onRenderBody = _g === void 0 ? this._onRenderBody : _g, _h = _a.onRenderFooter, onRenderFooter = _h === void 0 ? this._onRenderFooter : _h; var _j = this.state, isFooterSticky = _j.isFooterSticky, visibility = _j.visibility, id = _j.id; var isLeft = type === Panel_types_1.PanelType.smallFixedNear || type === Panel_types_1.PanelType.customNear ? true : false; var isRTL = Utilities_1.getRTL(); var isOnRightSide = isRTL ? isLeft : !isLeft; var headerTextId = headerText && id + '-headerText'; var customWidthStyles = type === Panel_types_1.PanelType.custom || type === Panel_types_1.PanelType.customNear ? { width: customWidth } : {}; var nativeProps = Utilities_1.getNativeProps(this.props, Utilities_1.divProperties); var isOpen = this.isActive; var isAnimating = visibility === PanelVisibilityState.animatingClosed || visibility === PanelVisibilityState.animatingOpen; if (!isOpen && !isAnimating && !isHiddenOnDismiss) { return null; } this._classNames = getClassNames(styles, { theme: theme, className: className, focusTrapZoneClassName: focusTrapZoneProps ? focusTrapZoneProps.className : undefined, hasCloseButton: hasCloseButton, headerClassName: headerClassName, isAnimating: isAnimating, isFooterSticky: isFooterSticky, isFooterAtBottom: isFooterAtBottom, isOnRightSide: isOnRightSide, isOpen: isOpen, isHiddenOnDismiss: isHiddenOnDismiss, type: type }); var _classNames = this._classNames; var overlay; if (isBlocking && isOpen) { overlay = (React.createElement(Overlay_1.Overlay, tslib_1.__assign({ className: _classNames.overlay, isDarkThemed: false, onClick: isLightDismiss ? onLightDismissClick : undefined }, overlayProps))); } var header = onRenderHeader(this.props, this._onRenderHeader, headerTextId); return (React.createElement(Layer_1.Layer, tslib_1.__assign({}, layerProps), React.createElement(Popup_1.Popup, { role: "dialog", "aria-modal": "true", ariaLabelledBy: header ? headerTextId : undefined, onDismiss: this.dismiss, className: _classNames.hiddenPanel }, React.createElement("div", tslib_1.__assign({ "aria-hidden": !isOpen && isAnimating }, nativeProps, { ref: this._panel, className: _classNames.root }), overlay, React.createElement(index_1.FocusTrapZone, tslib_1.__assign({ ignoreExternalFocusing: ignoreExternalFocusing, forceFocusInsideTrap: !isBlocking || (isHiddenOnDismiss && !isOpen) ? false : forceFocusInsideTrap, firstFocusableSelector: firstFocusableSelector, isClickableOutsideFocusTrap: true }, focusTrapZoneProps, { className: _classNames.main, style: customWidthStyles, elementToFocusOnDismiss: elementToFocusOnDismiss }), React.createElement("div", { className: _classNames.commands, "data-is-visible": true }, onRenderNavigation(this.props, this._onRenderNavigation)), React.createElement("div", { className: _classNames.contentInner }, header, React.createElement("div", { ref: this._allowScrollOnPanel, className: _classNames.scrollableContent, "data-is-scrollable": true }, onRenderBody(this.props, this._onRenderBody)), onRenderFooter(this.props, this._onRenderFooter))))))); }; PanelBase.prototype.open = function () { if (this.props.isOpen !== undefined) { return; } if (this.isActive) { return; } if (this.props.onOpen) { this.props.onOpen(); } this.setState({ visibility: PanelVisibilityState.animatingOpen }); }; PanelBase.prototype.close = function () { if (this.props.isOpen !== undefined) { return; } if (!this.isActive) { return; } this.setState({ visibility: PanelVisibilityState.animatingClosed }); }; Object.defineProperty(PanelBase.prototype, "isActive", { /** isActive is true when panel is open or opening. */ get: function () { return this.state.visibility === PanelVisibilityState.open || this.state.visibility === PanelVisibilityState.animatingOpen; }, enumerable: true, configurable: true }); PanelBase.prototype._shouldListenForOuterClick = function (props) { return !!props.isBlocking && !!props.isOpen; }; PanelBase.prototype._updateFooterPosition = function () { var scrollableContent = this._scrollableContent; if (scrollableContent) { var height = scrollableContent.clientHeight; var innerHeight_1 = scrollableContent.scrollHeight; this.setState({ isFooterSticky: height < innerHeight_1 ? true : false }); } }; PanelBase.prototype._dismissOnOuterClick = function (ev) { var panel = this._panel.current; if (this.isActive && panel) { if (!Utilities_1.elementContains(panel, ev.target)) { if (this.props.onOuterClick) { this.props.onOuterClick(); ev.preventDefault(); } else { this.dismiss(); } } } }; PanelBase.defaultProps = { isHiddenOnDismiss: false, isOpen: undefined, isBlocking: true, hasCloseButton: true, type: Panel_types_1.PanelType.smallFixedFar }; return PanelBase; }(Utilities_1.BaseComponent)); exports.PanelBase = PanelBase; //# sourceMappingURL=Panel.base.js.map