chakra-ui
Version:
Responsive and accessible React UI components built with React and Emotion
150 lines (134 loc) • 4.02 kB
JavaScript
import _extends from "@babel/runtime/helpers/extends";
import _objectWithoutProperties from "@babel/runtime/helpers/objectWithoutProperties";
/** @jsx jsx */
import { jsx } from "@emotion/core";
import propTypes from "prop-types";
import { forwardRef } from "react";
import Icon from "../Icon";
import Spinner from "../Spinner";
import buttonStyle from "./styles";
import PseudoBox from "../PseudoBox";
import { useUIMode, useTheme } from "../ThemeProvider";
import Box from "../Box";
var Button = forwardRef(function (_ref, ref) {
var isDisabled = _ref.isDisabled,
isLoading = _ref.isLoading,
isFullWidth = _ref.isFullWidth,
children = _ref.children,
Comp = _ref.as,
color = _ref.color,
leftIcon = _ref.leftIcon,
rightIcon = _ref.rightIcon,
variant = _ref.variant,
loadingText = _ref.loadingText,
iconSpacing = _ref.iconSpacing,
type = _ref.type,
size = _ref.size,
rest = _objectWithoutProperties(_ref, ["isDisabled", "isLoading", "isFullWidth", "children", "as", "color", "leftIcon", "rightIcon", "variant", "loadingText", "iconSpacing", "type", "size"]);
var _useUIMode = useUIMode(),
mode = _useUIMode.mode;
var theme = useTheme();
var buttonProps = buttonStyle({
color: color,
variant: variant,
size: size,
mode: mode,
theme: theme
});
var _isDisabled = isDisabled || isLoading;
return jsx(PseudoBox, _extends({
disabled: _isDisabled,
"aria-disabled": _isDisabled,
ref: ref,
as: Comp,
type: type,
borderRadius: "md",
fontWeight: "semibold",
width: isFullWidth ? "full" : undefined
}, buttonProps, rest), leftIcon && !isLoading && jsx(Icon, {
focusable: "false",
ml: -1,
mr: iconSpacing,
name: leftIcon,
color: "currentColor",
size: "1em"
}), isLoading && jsx(Spinner, {
position: loadingText ? "relative" : "absolute",
mr: loadingText ? iconSpacing : 0,
color: "currentColor",
size: "1em"
}), isLoading ? loadingText || jsx(Box, {
as: "span",
opacity: "0"
}, children) : children, rightIcon && !isLoading && jsx(Icon, {
focusable: "false",
ml: iconSpacing,
name: rightIcon,
color: "currentColor",
size: "1em"
}));
});
process.env.NODE_ENV !== "production" ? Button.propTypes = {
/**
* The color of the button. Use the colors passed in `theme.colors`.
*/
color: propTypes.string,
/**
* The variant of the button style to use.
*/
variant: propTypes.oneOf(["outline", "ghost", "unstyled", "link", "solid"]),
/**
* If `true`, the button will be disabled.
*/
isDisabled: propTypes.bool,
/**
* If `true`, the button will show a spinner.
*/
isLoading: propTypes.bool,
/**
* The label to show in the button when `isLoading` is true
* If no text is passed, it only shows the spinner
*/
loadingText: propTypes.string,
/**
* If `true`, the button will take up the full width of its container.
*/
isFullWidth: propTypes.bool,
/**
* The html button type to use.
*/
type: propTypes.oneOf(["button", "reset", "submit"]),
/**
* The size of the button. Use the sizes in `theme.sizes.button`
*/
size: propTypes.oneOf(["sm", "md", "lg"]),
/**
* The content of the button.
*/
children: propTypes.node.isRequired,
/**
* If added, the button will show an icon before the button's label.
* Use the icon key in `theme.iconPath`
*/
leftIcon: propTypes.string,
/**
* If added, the button will show an icon after the button's label.
* Use the icon key in `theme.iconPath`
*/
rightIcon: propTypes.string,
/**
* The space between the button icon and label.
* Use the styled-system tokens or add custom values as a string
* @ignore
*/
iconSpacing: propTypes.oneOfType([propTypes.number, propTypes.string])
} : void 0;
Button.defaultProps = {
color: "gray",
size: "md",
variant: "solid",
type: "button",
iconSpacing: 2,
as: "button"
};
export default Button;