UNPKG

office-ui-fabric-react

Version:

Reusable React components for building experiences for Office 365.

245 lines • 15.3 kB
define(["require", "exports", "tslib", "react", "../../Utilities", "../../Styling", "../../Icon", "../../common/DirectionalHint", "../../ContextualMenu", "./BaseButton.classNames", "./SplitButton/SplitButton.classNames"], function (require, exports, tslib_1, React, Utilities_1, Styling_1, Icon_1, DirectionalHint_1, ContextualMenu_1, BaseButton_classNames_1, SplitButton_classNames_1) { "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); var BaseButton = (function (_super) { tslib_1.__extends(BaseButton, _super); function BaseButton(props, rootClassName) { var _this = _super.call(this, props) || this; _this._warnConditionallyRequiredProps(['menuProps', 'onClick'], 'split', _this.props.split); _this._warnDeprecations({ rootProps: undefined, icon: 'iconProps', menuIconName: 'menuIconProps', toggled: 'checked' }); _this._labelId = Utilities_1.getId(); _this._descriptionId = Utilities_1.getId(); _this._ariaDescriptionId = Utilities_1.getId(); _this.state = { menuProps: null }; return _this; } Object.defineProperty(BaseButton.prototype, "_isSplitButton", { get: function () { return (!!this.props.menuProps && !!this.props.onClick) && this.props.split === true; }, enumerable: true, configurable: true }); Object.defineProperty(BaseButton.prototype, "_isExpanded", { get: function () { return !!this.state.menuProps; }, enumerable: true, configurable: true }); BaseButton.prototype.render = function () { var _a = this.props, ariaDescription = _a.ariaDescription, ariaLabel = _a.ariaLabel, className = _a.className, description = _a.description, disabled = _a.disabled, href = _a.href, iconProps = _a.iconProps, styles = _a.styles, text = _a.text, checked = _a.checked, variantClassName = _a.variantClassName; this._classNames = BaseButton_classNames_1.getClassNames(styles, className, variantClassName, iconProps && iconProps.className, disabled, checked, !!this.state.menuProps && !this.props.split); var _b = this, _ariaDescriptionId = _b._ariaDescriptionId, _labelId = _b._labelId, _descriptionId = _b._descriptionId; // Anchor tag cannot be disabled hence in disabled state rendering // anchor button as normal button var renderAsAnchor = !disabled && !!href; var tag = renderAsAnchor ? 'a' : 'button'; var nativeProps = Utilities_1.getNativeProps(Utilities_1.assign(renderAsAnchor ? {} : { type: 'button' }, this.props.rootProps, this.props), renderAsAnchor ? Utilities_1.anchorProperties : Utilities_1.buttonProperties, [ 'disabled' // Let disabled buttons be focused and styled as disabled. ]); // Check for ariaDescription, description or aria-describedby in the native props to determine source of aria-describedby // otherwise default to null. var ariaDescribedBy; if (ariaDescription) { ariaDescribedBy = _ariaDescriptionId; } else if (description) { ariaDescribedBy = _descriptionId; } else if (nativeProps['aria-describedby']) { ariaDescribedBy = nativeProps['aria-describedby']; } else { ariaDescribedBy = null; } // If an explicit ariaLabel is given, use that as the label and we're done. // If an explicit aria-labelledby is given, use that and we're done. // If any kind of description is given (which will end up as an aria-describedby attribute), // set the labelledby element. Otherwise, the button is labeled implicitly by the descendent // text on the button (if it exists). Never set both aria-label and aria-labelledby. var ariaLabelledBy = null; if (!ariaLabel) { if (nativeProps['aria-labelledby']) { ariaLabelledBy = nativeProps['aria-labelledby']; } else if (ariaDescribedBy) { ariaLabelledBy = text ? _labelId : null; } } var tabIndex = (this.props.tabIndex === undefined) ? (this._isSplitButton ? -1 : 0) : this.props.tabIndex; var buttonProps = Utilities_1.assign(nativeProps, { className: this._classNames.root, ref: this._resolveRef('_buttonElement'), 'disabled': disabled, tabIndex: tabIndex, 'aria-label': ariaLabel, 'aria-labelledby': ariaLabelledBy, 'aria-describedby': ariaDescribedBy, 'data-is-focusable': (this.props['data-is-focusable'] === false || disabled) ? false : true, 'aria-pressed': checked }); if (this._isSplitButton) { return (this._onRenderSplitButtonContent(tag, buttonProps)); } else if (this.props.menuProps) { Utilities_1.assign(buttonProps, { 'onClick': this._onToggleMenu, 'aria-expanded': this._isExpanded, 'aria-owns': this.state.menuProps ? this._labelId + '-menu' : null, 'aria-haspopup': true }); } return this._onRenderContent(tag, buttonProps); }; BaseButton.prototype.focus = function () { if (this._buttonElement) { this._buttonElement.focus(); } }; BaseButton.prototype._onRenderContent = function (tag, buttonProps) { var props = this.props; var baseClassName = props.baseClassName, styles = props.styles, menuIconName = props.menuIconName, menuIconProps = props.menuIconProps, menuProps = props.menuProps, _a = props.onRenderIcon, onRenderIcon = _a === void 0 ? this._onRenderIcon : _a, _b = props.onRenderText, onRenderText = _b === void 0 ? this._onRenderText : _b, _c = props.onRenderDescription, onRenderDescription = _c === void 0 ? this._onRenderDescription : _c, _d = props.onRenderAriaDescription, onRenderAriaDescription = _d === void 0 ? this._onRenderAriaDescription : _d, _e = props.onRenderChildren, onRenderChildren = _e === void 0 ? this._onRenderChildren : _e, _f = props.onRenderMenu, onRenderMenu = _f === void 0 ? this._onRenderMenu : _f, _g = props.onRenderMenuIcon, onRenderMenuIcon = _g === void 0 ? this._onRenderMenuIcon : _g; return React.createElement(tag, buttonProps, React.createElement('div', { className: this._classNames.flexContainer }, onRenderIcon(props, this._onRenderIcon), onRenderText(props, this._onRenderText), onRenderDescription(props, this._onRenderDescription), onRenderAriaDescription(props, this._onRenderAriaDescription), onRenderChildren(props, this._onRenderChildren), !this._isSplitButton && (menuProps || menuIconName || menuIconProps || this.props.onRenderMenuIcon) && onRenderMenuIcon(this.props, this._onRenderMenuIcon), this.state.menuProps && onRenderMenu(menuProps, this._onRenderMenu))); }; BaseButton.prototype._onRenderIcon = function (buttonProps, defaultRender) { var _a = this.props, baseClassName = _a.baseClassName, disabled = _a.disabled, icon = _a.icon, iconProps = _a.iconProps, styles = _a.styles, checked = _a.checked; if (icon || iconProps) { iconProps = iconProps || { iconName: icon }; } if (iconProps) { return Icon_1.Icon(tslib_1.__assign({}, iconProps, { className: this._classNames.icon })); } return null; }; BaseButton.prototype._onRenderText = function () { var _a = this.props, children = _a.children, disabled = _a.disabled, styles = _a.styles, text = _a.text; // For backwards compat, we should continue to take in the text content from children. if (text === undefined && typeof (children) === 'string') { text = children; } if (text) { return (React.createElement("span", { className: this._classNames.label, id: this._labelId }, text)); } return null; }; BaseButton.prototype._onRenderChildren = function () { var children = this.props.children; // If children is just a string, either it or the text will be rendered via onRenderLabel // If children is another component, it will be rendered after text if (typeof (children) === 'string') { return null; } return children; }; BaseButton.prototype._onRenderDescription = function (props) { var description = this.props.description; // ms-Button-description is only shown when the button type is compound. // In other cases it will not be displayed. return description ? (React.createElement("span", { className: this._classNames.description, id: this._descriptionId }, description)) : (null); }; BaseButton.prototype._onRenderAriaDescription = function () { var _a = this.props, ariaDescription = _a.ariaDescription, styles = _a.styles; // If ariaDescription is given, descriptionId will be assigned to ariaDescriptionSpan, // otherwise it will be assigned to descriptionSpan. return ariaDescription ? (React.createElement("span", { className: "" + (styles.screenReaderText || Styling_1.mergeStyles(Styling_1.hideText)), id: this._ariaDescriptionId }, ariaDescription)) : (null); }; BaseButton.prototype._onRenderMenuIcon = function (props) { var _a = this.props, baseClassName = _a.baseClassName, checked = _a.checked, disabled = _a.disabled, menuIconName = _a.menuIconName, menuIconProps = _a.menuIconProps; if (menuIconProps === undefined) { menuIconProps = { iconName: menuIconName === undefined ? 'ChevronDown' : menuIconName }; } return (menuIconProps ? React.createElement(Icon_1.Icon, tslib_1.__assign({}, menuIconProps, { className: this._classNames.menuIcon })) : null); }; BaseButton.prototype._onRenderMenu = function (menuProps) { return (React.createElement(ContextualMenu_1.ContextualMenu, tslib_1.__assign({ id: this._labelId + '-menu', directionalHint: DirectionalHint_1.DirectionalHint.bottomLeftEdge }, menuProps, { className: 'ms-BaseButton-menuhost ' + menuProps.className, target: this._buttonElement, labelElementId: this._labelId, onDismiss: this._onToggleMenu }))); }; BaseButton.prototype._onToggleMenu = function () { var menuProps = this.props.menuProps; var currentMenuProps = this.state.menuProps; this.setState({ menuProps: currentMenuProps ? null : menuProps }); }; BaseButton.prototype._onRenderSplitButtonContent = function (tag, buttonProps) { var _a = this.props, styles = _a.styles, disabled = _a.disabled; return (React.createElement("div", { "aria-labelledby": buttonProps.ariaLabel, "aria-disabled": disabled, "aria-haspopup": true, "aria-expanded": this._isExpanded, "aria-pressed": this.props.checked, "aria-describedby": buttonProps.ariaDescription, className: Utilities_1.css(disabled ? styles.splitButtonContainerDisabled : styles.splitButtonContainer), tabIndex: 0, onKeyDown: this.props.disabled ? undefined : this._onSplitButtonKeyDown }, React.createElement("span", { "aria-hidden": true, style: { 'display': 'flex' } }, this._onRenderContent(tag, buttonProps), this._onRenderSplitButtonMenuButton()))); }; BaseButton.prototype._onRenderSplitButtonMenuButton = function () { var _a = this.props, menuIconName = _a.menuIconName, menuIconProps = _a.menuIconProps, styles = _a.styles, disabled = _a.disabled, checked = _a.checked; if (menuIconProps === undefined) { menuIconProps = { iconName: menuIconName === undefined ? 'ChevronDown' : menuIconName }; } var classNames = styles ? SplitButton_classNames_1.getClassNames(styles, disabled || false, !!this.state.menuProps, checked || false) : undefined; return (React.createElement(BaseButton, { tabIndex: -1, styles: classNames, checked: this.props.checked, disabled: this.props.disabled, onClick: this._onToggleMenu, menuProps: undefined, iconProps: menuIconProps })); }; BaseButton.prototype._onSplitButtonKeyDown = function (ev) { switch (ev.which) { case 13 /* enter */: case 32 /* space */: this.props.onClick(null); return; } if (ev.altKey) { switch (ev.which) { case 40 /* down */: this._onToggleMenu(); return; } } }; BaseButton.defaultProps = { baseClassName: 'ms-Button', classNames: {}, styles: {}, split: false }; tslib_1.__decorate([ Utilities_1.autobind ], BaseButton.prototype, "_onRenderIcon", null); tslib_1.__decorate([ Utilities_1.autobind ], BaseButton.prototype, "_onRenderText", null); tslib_1.__decorate([ Utilities_1.autobind ], BaseButton.prototype, "_onRenderChildren", null); tslib_1.__decorate([ Utilities_1.autobind ], BaseButton.prototype, "_onRenderDescription", null); tslib_1.__decorate([ Utilities_1.autobind ], BaseButton.prototype, "_onRenderAriaDescription", null); tslib_1.__decorate([ Utilities_1.autobind ], BaseButton.prototype, "_onRenderMenuIcon", null); tslib_1.__decorate([ Utilities_1.autobind ], BaseButton.prototype, "_onRenderMenu", null); tslib_1.__decorate([ Utilities_1.autobind ], BaseButton.prototype, "_onToggleMenu", null); tslib_1.__decorate([ Utilities_1.autobind ], BaseButton.prototype, "_onSplitButtonKeyDown", null); return BaseButton; }(Utilities_1.BaseComponent)); exports.BaseButton = BaseButton; }); //# sourceMappingURL=BaseButton.js.map