Instantly share code, notes, and snippets.
-
Save tanvirraj/54ccf7ed27085057710df22bcc103690 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// @flow | |
import React, { PureComponent } from "react"; | |
import styles from "./Button.module.scss"; | |
import cx from "classnames"; | |
import { Link } from "react-router-dom"; | |
import { Button as AntDesignButton } from "antd"; | |
import { type Node } from "react"; | |
/** | |
* Enum with all the button types. | |
* @readonly | |
* @enum {string} | |
*/ | |
const ButtonType = Object.freeze({ | |
PRIMARY: "primary", | |
SECONDARY: "secondary", | |
TERTIARY: "tertiary", | |
DEFAULT: "default" | |
}); | |
/** | |
* Enum with all the button sizes. | |
* @readonly | |
* @enum {string} | |
*/ | |
const ButtonSize = Object.freeze({ | |
XSMALL: "xsmall", | |
SMALL: "small", | |
MEDIUM: "medium", | |
LARGE: "large", | |
DEFAULT: "default" | |
}); | |
/** | |
* Enum with all the button shapes. | |
* @readonly | |
* @enum {string} | |
*/ | |
const ButtonShape = Object.freeze({ | |
CIRCLE: "circle", | |
ROUND: "round" | |
}); | |
/** | |
* Enum with all the icon positions. | |
* @readonly | |
* @enum {string} | |
*/ | |
const IconPosition = Object.freeze({ | |
LEFT: "left", | |
RIGHT: "right" | |
}); | |
type Props = { | |
/** Text shown as button title */ | |
text?: string | Node, | |
/** Link associated with the button */ | |
link?: string, | |
/** Icon shown before or after button text */ | |
icon?: Node, | |
/** Used to set button status if its disabled or not */ | |
disabled?: boolean, | |
/** Class name attached with the button component */ | |
className?: any, | |
/** Type of the button ex- Primary or Secondary */ | |
type: $Values<typeof ButtonType>, | |
/** Size of the button ex- small or large (default: large) */ | |
size: $Values<typeof ButtonSize>, | |
/** Used to set icon position ex- left or right (default: left) */ | |
iconPosition: $Values<typeof IconPosition>, | |
/** Set to true if the button should not have a border (default: has border) */ | |
borderless?: boolean, | |
/** Set to true if the button should have a transparent background (default: has background color) */ | |
transparent?: boolean, | |
/** Call the function when user clicks the button */ | |
onClick?: Function, | |
loading?: boolean | |
}; | |
/** | |
* Custom Ant Design button | |
*/ | |
class Button extends PureComponent<Props> { | |
static defaultProps = { | |
type: ButtonType.DEFAULT, | |
size: ButtonSize.DEFAULT, | |
iconPosition: IconPosition.LEFT, | |
loading: false | |
}; | |
render() { | |
const { | |
text, | |
link, | |
icon, | |
type, | |
size, | |
disabled, | |
iconPosition, | |
className, | |
borderless, | |
transparent, | |
onClick, | |
loading, | |
...rest | |
} = this.props; | |
const classNames = cx( | |
{ | |
[styles.primaryButton]: type === ButtonType.PRIMARY, | |
[styles.secondaryButton]: type === ButtonType.SECONDARY, | |
[styles.tertiaryButton]: type === ButtonType.TERTIARY, | |
[styles.defaultButton]: type === ButtonType.DEFAULT, | |
[styles.xsmallButton]: size === ButtonSize.XSMALL, | |
[styles.smallButton]: size === ButtonSize.SMALL, | |
[styles.mediumButton]: size === ButtonSize.MEDIUM, | |
[styles.largeButton]: size === ButtonSize.LARGE, | |
[styles.borderless]: borderless, | |
[styles.transparentBg]: transparent | |
}, | |
className | |
); | |
const button = ( | |
<AntDesignButton | |
className={classNames} | |
disabled={disabled} | |
onClick={onClick} | |
loading={loading} | |
{...rest} | |
> | |
<span className={styles.buttonContent}> | |
{!loading && iconPosition === IconPosition.LEFT && icon} | |
{text && ( | |
<span | |
className={cx({ | |
[styles.iconLeft]: icon && iconPosition === IconPosition.LEFT, | |
[styles.iconRight]: icon && iconPosition === IconPosition.RIGHT | |
})} | |
> | |
{text} | |
</span> | |
)} | |
{!loading && iconPosition === IconPosition.RIGHT && icon} | |
</span> | |
</AntDesignButton> | |
); | |
return link ? <Link to={link}>{button}</Link> : button; | |
} | |
} | |
export default Button; | |
export { ButtonType, ButtonSize, ButtonShape, IconPosition }; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment