glide-design-system
Version:
Glide design system is an open-source React component library. It offers numerous benefits that make them essential tools for design and development teams.
169 lines (163 loc) • 4.64 kB
JavaScript
import React from "react";
import PropTypes from "prop-types";
import "./button.css";
// /**
// * Button component
// * @param {*} children content to be displayed inside the button. It can be any valid React elements or components.
// * @param {*} loading A boolean flag to indicate if the button is in a loading state. When loading is true, the button displays a loading spinner or the loadingIcon.
// * @param {*} icon An icon element to be displayed before the button's content.
// * @param {*} disabled A boolean flag to disable the button if set to true.
// * @param {*} variant The variant style of the button
// * @param {*} onClick A function to be called when the button is clicked. It is typically used to handle click events on the button.
// * @param {*} style An object containing custom styles to be applied to the button.
// * @param {*} iconPosition The position of the icon relative to the button's content. It can be set to "start" (before the content) or "end" (after the content).
// * @param {*} color The color of the button.
// * @param {*} loadingIcon An optional custom loading icon to be displayed when loading is true.
// * @param {*} size The size of the button.
// */
/**
* Buttons communicate actions that users can take. They are typically placed throughout your UI, in places like:
* - Modal windows
* - Forms
*/
export const Button = ({
children,
loading,
icon,
disabled,
variant,
onClick,
style,
iconPosition,
color,
loadingIcon,
size,
className,
containerStyle,
buttonContentClass,
id,
name,
title,
type,
}) => {
const combinedStyle = {
flexDirection: iconPosition === "end" ? "row-reverse" : "",
border:
variant === "outlined"
? color === "secondary"
? "1px solid #F2F2F2"
: "1px solid #0a5b99"
: "none",
backgroundColor:
variant === "outlined" || variant === "text"
? "#ffffff"
: color === "secondary"
? "#F2F2F2"
: "#0a5b99",
color:
variant === "outlined" || variant === "text"
? color === "secondary"
? "#7f7f7f"
: "#0a5b99"
: color === "secondary"
? "#7f7f7f"
: "#ffffff",
height: size === "large" ? "48px" : size === "small" ? "24px" : "36px",
fontSize: size === "large" ? "16px" : size === "small" ? "12px" : "14px",
...style,
};
const buttonContainerStyle = {
...containerStyle,
};
return (
<div className="buttonParentContainer" style={buttonContainerStyle}>
<button
id={id}
data-testid={id}
name={name}
disabled={disabled}
onClick={(e) => onClick && onClick(e)}
style={combinedStyle}
type={type ? type : ""}
className={
color === "secondary"
? `buttonSecondary ${className ? className : ""}`
: `buttonPrimary ${className ? className : ""}`
}
>
{loading ? (
loadingIcon ? (
loadingIcon
) : (
<div className="loaderParent">
<div
className={
color === "secondary" ? "secondaryLoader" : "primaryLoader"
}
></div>
</div>
)
) : (
<div
className={`buttonChildren ${
buttonContentClass ? buttonContentClass : ""
}`}
style={{
flexDirection: iconPosition === "end" ? "row-reverse" : "",
}}
>
{icon && <div className="buttonIcon">{icon}</div>}
{children || title}
</div>
)}
</button>
</div>
);
};
Button.propTypes = {
/**
* If true, the loading indicator is shown.
*/
loading: PropTypes.bool,
/**
* Variant of the button
*/
variant: PropTypes.oneOf(["outlined", "contained"]),
/**
* Button disabled or not.
*/
disabled: PropTypes.bool,
/**
* Icon to be display in button.
*/
icon: PropTypes.object,
/**
* Position of Icon.
*/
iconPosition: PropTypes.string,
/**
* Optional click handler.
*/
onClick: PropTypes.func,
/**
* Color of the Button.
*/
color: PropTypes.string,
/**
* Loading Icon of the button.
*/
loadingIcon: PropTypes.oneOfType([PropTypes.string, PropTypes.elementType]),
/**
* How large should the button be?
*/
size: PropTypes.oneOf(["small", "medium", "large"]),
};
Button.defaultProps = {
variant: "contained",
size: "medium",
onClick: undefined,
loading: false,
disabled: false,
icon: null,
iconPosition: null,
};