UNPKG

chakra-ui

Version:

Responsive and accessible React UI components built with React and Emotion

150 lines (134 loc) 4.02 kB
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;