optimizely-oui
Version:
Optimizely's Component Library.
193 lines (160 loc) • 7.46 kB
JavaScript
function _extends() { _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; return _extends.apply(this, arguments); }
function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }
function _objectWithoutProperties(source, excluded) { if (source == null) return {}; var target = _objectWithoutPropertiesLoose(source, excluded); var key, i; if (Object.getOwnPropertySymbols) { var sourceSymbolKeys = Object.getOwnPropertySymbols(source); for (i = 0; i < sourceSymbolKeys.length; i++) { key = sourceSymbolKeys[i]; if (excluded.indexOf(key) >= 0) continue; if (!Object.prototype.propertyIsEnumerable.call(source, key)) continue; target[key] = source[key]; } } return target; }
function _objectWithoutPropertiesLoose(source, excluded) { if (source == null) return {}; var target = {}; var sourceKeys = Object.keys(source); var key, i; for (i = 0; i < sourceKeys.length; i++) { key = sourceKeys[i]; if (excluded.indexOf(key) >= 0) continue; target[key] = source[key]; } return target; }
import React from "react";
import PropTypes from "prop-types";
import classNames from "classnames";
import Spinner from "../Spinner";
import Icon from "react-oui-icons";
/**
* @param {Object} props - Properties passed to component
* @returns {ReactElement}
*/
var Button = function Button(_ref) {
var _classNames;
var ariaLabel = _ref.ariaLabel,
ariaHasPopup = _ref.ariaHasPopup,
buttonRef = _ref.buttonRef,
children = _ref.children,
className = _ref.className,
isActive = _ref.isActive,
isDisabled = _ref.isDisabled,
isLink = _ref.isLink,
isLoading = _ref.isLoading,
isSubmit = _ref.isSubmit,
leftIcon = _ref.leftIcon,
loadingText = _ref.loadingText,
onBlur = _ref.onBlur,
onClick = _ref.onClick,
onMouseDown = _ref.onMouseDown,
rightIcon = _ref.rightIcon,
size = _ref.size,
style = _ref.style,
testSection = _ref.testSection,
title = _ref.title,
_ref$width = _ref.width,
width = _ref$width === void 0 ? "default" : _ref$width,
props = _objectWithoutProperties(_ref, ["ariaLabel", "ariaHasPopup", "buttonRef", "children", "className", "isActive", "isDisabled", "isLink", "isLoading", "isSubmit", "leftIcon", "loadingText", "onBlur", "onClick", "onMouseDown", "rightIcon", "size", "style", "testSection", "title", "width"]);
var buttonClassNames = classNames("oui-button", (_classNames = {}, _defineProperty(_classNames, "oui-button--".concat(style), style), _defineProperty(_classNames, "oui-button--".concat(size), size), _defineProperty(_classNames, "oui-button--".concat(width), width), _defineProperty(_classNames, "is-active", isActive), _defineProperty(_classNames, "oui-button--loading", isLoading), _defineProperty(_classNames, "flex--inline flex-justified--center flex-align--center", leftIcon || rightIcon), _classNames), className);
var type = isSubmit ? "submit" : "button";
function handleOnClick(event) {
if (isDisabled || isLoading) {
return;
}
onClick(event);
}
var leftIconClasses = classNames("flex", "flex-self--center", {
"push--right": size !== "small",
"push-half--right": size === "small"
});
var leftIconComp = leftIcon ? React.createElement("div", {
className: leftIconClasses
}, React.createElement(Icon, {
name: leftIcon,
size: size === "large" ? "medium" : "small"
})) : "";
var rightIconClasses = classNames("flex", "flex-self--center", {
"push--left": size !== "small",
"push-half--left": size === "small"
});
var rightIconComp = rightIcon ? React.createElement("div", {
className: rightIconClasses
}, React.createElement(Icon, {
name: rightIcon,
size: size === "large" ? "medium" : "small"
})) : "";
if (isLink) {
return React.createElement("div", _extends({
"data-oui-component": true,
className: buttonClassNames,
disabled: isDisabled,
onBlur: onBlur,
"data-test-section": testSection,
ref: buttonRef
}, props), leftIcon && leftIconComp, children, rightIcon && rightIconComp);
}
return React.createElement("button", _extends({
"data-oui-component": true,
className: buttonClassNames,
disabled: isDisabled || isLoading,
type: type,
onBlur: onBlur,
onClick: handleOnClick,
onMouseDown: onMouseDown,
"data-test-section": testSection,
"aria-label": ariaLabel,
"aria-haspopup": ariaHasPopup,
"aria-live": "polite",
title: title,
ref: buttonRef
}, props), isLoading ? React.createElement(Spinner, {
"data-test-section": "button-spinner",
size: "tiny"
}) : leftIcon && leftIconComp, isLoading ? loadingText || "Processing" : children, !isLoading && rightIcon && rightIconComp);
};
Button.propTypes = {
/** Should be true if this button displays a menu or tooltip */
ariaHasPopup: PropTypes.bool,
/** Describes buttons that have an icon but no text */
ariaLabel: PropTypes.string,
/** React ref to the underlying button component */
buttonRef: PropTypes.oneOfType([PropTypes.func, PropTypes.shape({
current: PropTypes.instanceOf(Element)
})]),
/** Text within the button */
children: PropTypes.node.isRequired,
/** CSS class names. */
className: PropTypes.string,
/** Render button with active state */
isActive: PropTypes.bool,
/** Prevent users from interacting with the button */
isDisabled: PropTypes.bool,
/** Changes the button to a div for insertion within a Link component */
isLink: PropTypes.bool,
/** When true, adds a spinner to the button and disables the button */
isLoading: PropTypes.bool,
/** Make the button act as a submit button */
isSubmit: PropTypes.bool,
/** Icon to display on the left */
leftIcon: PropTypes.node,
/** When the button adds a spinner, it displays this text */
loadingText: PropTypes.string,
/** Function that fires when the button loses focus */
onBlur: PropTypes.func,
/** Function that fires when the button is clicked on */
onClick: PropTypes.func,
/** Function that fires when the button is mouse downed */
onMouseDown: PropTypes.func,
/** Icon to display on the right */
rightIcon: PropTypes.node,
/** Various height and width options */
size: PropTypes.oneOf(["tiny", "small", "large", "narrow", "tight"]),
/** Various color options */
style: PropTypes.oneOf(["highlight", "danger", "danger-outline", "outline", "outline-reverse", "plain", "toggle", "underline", "unstyled"]),
/** Hook for automated JavaScript tests */
testSection: PropTypes.string,
/** Title of the button shown as tooltip text when the button is hovered */
title: PropTypes.string,
/** Various height and width options */
width: PropTypes.oneOf(["default", "full"])
};
Button.defaultProps = {
isLink: false,
isLoading: false,
isDisabled: false,
isSubmit: false,
loadingText: "",
onBlur: function onBlur() {
return null;
},
onClick: function onClick() {
return null;
},
onMouseDown: function onMouseDown() {
return null;
},
width: "default"
};
Button.displayName = "Button";
export default Button;