office-ui-fabric-react
Version:
Reusable React components for building experiences for Office 365.
239 lines • 12.9 kB
JavaScript
import * as tslib_1 from "tslib";
import * as React from 'react';
import { BaseComponent, classNamesFunction, divProperties, getId, getNativeProps, getRTL, createRef, elementContains, allowScrollOnElement, isIOS } from '../../Utilities';
import { getTheme, IconFontSizes } from '../../Styling';
import { FocusTrapZone } from '../FocusTrapZone/index';
import { PanelType } from './Panel.types';
import { Layer } from '../../Layer';
import { Overlay } from '../../Overlay';
import { Popup } from '../../Popup';
import { IconButton } from '../../Button';
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 () {
_this.dismiss();
};
_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