UNPKG

office-ui-fabric-react

Version:

Reusable React components for building experiences for Office 365.

239 lines • 12.9 kB
import * as tslib_1 from "tslib"; import * as React from 'react'; import { IconButton } from '../../Button'; import { Layer } from '../../Layer'; import { Overlay } from '../../Overlay'; import { Popup } from '../../Popup'; import { getTheme, IconFontSizes } from '../../Styling'; import { allowScrollOnElement, BaseComponent, classNamesFunction, createRef, divProperties, elementContains, getId, getNativeProps, getRTL, isIOS } from '../../Utilities'; import { FocusTrapZone } from '../FocusTrapZone/index'; import { PanelType } from './Panel.types'; var getClassNames = classNamesFunction(); var PanelBase = /** @class */ (function (_super) { tslib_1.__extends(PanelBase, _super); function PanelBase(props) { var _this = _super.call(this, props) || this; _this._panel = createRef(); _this._content = createRef(); _this.dismiss = function (ev) { if (_this.state.isOpen) { if (_this.props.onDismiss) { _this.props.onDismiss(ev); } if (!ev || (ev && !ev.defaultPrevented)) { _this.setState({ isOpen: false, isAnimating: true }, function () { _this._async.setTimeout(_this._onTransitionComplete, 200); }); } } }; // Allow the user to scroll within the panel but not on the body _this._allowScrollOnPanel = function (elt) { if (elt) { allowScrollOnElement(elt, _this._events); if (isIOS()) { elt.style.height = window.innerHeight + 'px'; } } else { _this._events.off(_this._scrollableContent); } _this._scrollableContent = elt; }; _this._onRenderNavigation = function (props) { var closeButtonAriaLabel = props.closeButtonAriaLabel, hasCloseButton = props.hasCloseButton; var theme = 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("div", { className: _this._classNames.navigation }, React.createElement(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: IconFontSizes.large }, rootHovered: { color: theme.palette.neutralPrimary } }, className: _this._classNames.closeButton, onClick: _this._onPanelClick, ariaLabel: 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", { ref: _this._content, className: _this._classNames.content, "data-is-scrollable": true }, 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._onPanelClick = function (ev) { _this.dismiss(ev); }; _this._onTransitionComplete = function () { _this.setState({ isAnimating: false }); if (!_this.state.isOpen && _this.props.onDismissed) { _this.props.onDismissed(); } }; _this._warnDeprecations({ ignoreExternalFocusing: 'focusTrapZoneProps', forceFocusInsideTrap: 'focusTrapZoneProps', firstFocusableSelector: 'focusTrapZoneProps' }); _this.state = { isFooterSticky: false, isOpen: false, isAnimating: false, id: getId('Panel') }; return _this; } 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.open(); } }; PanelBase.prototype.componentDidUpdate = function (previousProps) { var shouldListenOnOuterClick = this._shouldListenForOuterClick(this.props); var previousShouldListenOnOuterClick = this._shouldListenForOuterClick(previousProps); 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.componentWillReceiveProps = function (newProps) { if (newProps.isOpen !== this.state.isOpen) { if (newProps.isOpen) { this.open(); } else { this.dismiss(); } } }; 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, 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, isOpen = _j.isOpen, isAnimating = _j.isAnimating, id = _j.id; var isLeft = type === PanelType.smallFixedNear ? true : false; var isRTL = getRTL(); var isOnRightSide = isRTL ? isLeft : !isLeft; var headerTextId = headerText && id + '-headerText'; var customWidthStyles = type === PanelType.custom ? { width: customWidth } : {}; var nativeProps = getNativeProps(this.props, divProperties); if (!isOpen && !isAnimating && !isHiddenOnDismiss) { return null; } this._classNames = getClassNames(styles, { theme: theme, className: className, focusTrapZoneClassName: focusTrapZoneProps ? focusTrapZoneProps.className : undefined, hasCloseButton: hasCloseButton, headerClassName: headerClassName, isAnimating: this.state.isAnimating, isFooterAtBottom: isFooterAtBottom, isFooterSticky: isFooterSticky, isOnRightSide: isOnRightSide, isOpen: this.state.isOpen, isHiddenOnDismiss: isHiddenOnDismiss, type: type }); var _classNames = this._classNames; var overlay; if (isBlocking && isOpen) { overlay = React.createElement(Overlay, { className: _classNames.overlay, isDarkThemed: false, onClick: isLightDismiss ? onLightDismissClick : undefined }); } var header = onRenderHeader(this.props, this._onRenderHeader, headerTextId); return (React.createElement(Layer, tslib_1.__assign({}, layerProps), React.createElement(Popup, { role: "dialog", ariaLabelledBy: header ? headerTextId : undefined, onDismiss: this.dismiss, className: _classNames.hiddenPanel }, React.createElement("div", tslib_1.__assign({}, nativeProps, { ref: this._panel, className: _classNames.root }), overlay, React.createElement(FocusTrapZone, tslib_1.__assign({ ignoreExternalFocusing: ignoreExternalFocusing, forceFocusInsideTrap: isHiddenOnDismiss && !isOpen ? false : forceFocusInsideTrap, firstFocusableSelector: firstFocusableSelector }, focusTrapZoneProps, { className: _classNames.main, style: customWidthStyles, elementToFocusOnDismiss: elementToFocusOnDismiss, isClickableOutsideFocusTrap: focusTrapZoneProps && !focusTrapZoneProps.isClickableOutsideFocusTrap ? false : true }), React.createElement("div", { ref: this._allowScrollOnPanel, className: _classNames.scrollableContent }, React.createElement("div", { className: _classNames.commands, "data-is-visible": true }, onRenderNavigation(this.props, this._onRenderNavigation)), React.createElement("div", { className: _classNames.contentInner }, header, onRenderBody(this.props, this._onRenderBody), onRenderFooter(this.props, this._onRenderFooter)))))))); }; PanelBase.prototype.open = function () { var _this = this; if (!this.state.isOpen) { this.setState({ isOpen: true, isAnimating: true }, function () { _this._async.setTimeout(_this._onTransitionComplete, 200); }); } }; PanelBase.prototype._shouldListenForOuterClick = function (props) { return !!props.isBlocking && !!props.isOpen; }; PanelBase.prototype._updateFooterPosition = function () { var _content = this._content.current; if (_content) { var height = _content.clientHeight; var innerHeight_1 = _content.scrollHeight; this.setState({ isFooterSticky: height < innerHeight_1 ? true : false }); } }; PanelBase.prototype._dismissOnOuterClick = function (ev) { var panel = this._panel.current; if (this.state.isOpen && panel) { if (!elementContains(panel, ev.target)) { if (this.props.onOuterClick) { this.props.onOuterClick(); ev.preventDefault(); } else { this.dismiss(); } } } }; PanelBase.defaultProps = { isHiddenOnDismiss: false, isOpen: false, isBlocking: true, hasCloseButton: true, type: PanelType.smallFixedFar }; return PanelBase; }(BaseComponent)); export { PanelBase }; //# sourceMappingURL=Panel.base.js.map