2020-08-10 04:54:33 +00:00
|
|
|
import React from "react";
|
2020-11-24 07:01:37 +00:00
|
|
|
import {
|
|
|
|
|
CommonComponentProps,
|
|
|
|
|
hexToRgba,
|
|
|
|
|
ThemeProp,
|
|
|
|
|
Classes,
|
|
|
|
|
Variant,
|
|
|
|
|
} from "./common";
|
2020-10-12 07:15:35 +00:00
|
|
|
import styled, { css } from "styled-components";
|
2020-08-31 04:59:18 +00:00
|
|
|
import Icon, { IconName, IconSize } from "./Icon";
|
2020-08-10 04:54:33 +00:00
|
|
|
import Spinner from "./Spinner";
|
2020-08-28 10:51:41 +00:00
|
|
|
import { mediumButton, smallButton, largeButton } from "constants/DefaultTheme";
|
2020-08-10 04:54:33 +00:00
|
|
|
|
|
|
|
|
export enum Category {
|
|
|
|
|
primary = "primary",
|
|
|
|
|
secondary = "secondary",
|
|
|
|
|
tertiary = "tertiary",
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
export enum Size {
|
2021-02-04 07:02:36 +00:00
|
|
|
xxs = "xxs",
|
|
|
|
|
xs = "xs",
|
2020-08-10 04:54:33 +00:00
|
|
|
small = "small",
|
|
|
|
|
medium = "medium",
|
|
|
|
|
large = "large",
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
type stateStyleType = {
|
|
|
|
|
bgColorPrimary: string;
|
|
|
|
|
borderColorPrimary: string;
|
|
|
|
|
txtColorPrimary: string;
|
|
|
|
|
bgColorSecondary: string;
|
|
|
|
|
borderColorSecondary: string;
|
|
|
|
|
txtColorSecondary: string;
|
|
|
|
|
bgColorTertiary: string;
|
|
|
|
|
borderColorTertiary: string;
|
|
|
|
|
txtColorTertiary: string;
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
type BtnColorType = {
|
|
|
|
|
bgColor: string;
|
|
|
|
|
txtColor: string;
|
|
|
|
|
border: string;
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
type BtnFontType = {
|
|
|
|
|
buttonFont: any;
|
|
|
|
|
padding: string;
|
2020-09-02 08:58:49 +00:00
|
|
|
height: number;
|
2020-08-10 04:54:33 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
|
|
type ButtonProps = CommonComponentProps & {
|
|
|
|
|
onClick?: (event: React.MouseEvent<HTMLElement>) => void;
|
|
|
|
|
text?: string;
|
|
|
|
|
category?: Category;
|
|
|
|
|
variant?: Variant;
|
2020-09-16 11:50:47 +00:00
|
|
|
className?: string;
|
2020-08-10 04:54:33 +00:00
|
|
|
icon?: IconName;
|
|
|
|
|
size?: Size;
|
2020-09-01 07:24:53 +00:00
|
|
|
fill?: boolean;
|
2020-09-16 11:50:47 +00:00
|
|
|
href?: string;
|
2020-10-12 07:15:35 +00:00
|
|
|
tag?: "a" | "button";
|
2021-01-27 06:12:32 +00:00
|
|
|
type?: "submit" | "reset" | "button";
|
2021-02-04 07:02:36 +00:00
|
|
|
target?: string;
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
const defaultProps = {
|
|
|
|
|
category: Category.primary,
|
|
|
|
|
variant: Variant.info,
|
|
|
|
|
size: Size.small,
|
|
|
|
|
isLoading: false,
|
|
|
|
|
disabled: false,
|
|
|
|
|
fill: false,
|
|
|
|
|
tag: "a",
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
const getDisabledStyles = (props: ThemeProp & ButtonProps) => {
|
|
|
|
|
const variant = props.variant || defaultProps.variant;
|
|
|
|
|
const category = props.category || defaultProps.category;
|
|
|
|
|
|
|
|
|
|
const stylesByCategory = {
|
|
|
|
|
[Category.primary]: {
|
|
|
|
|
txtColorPrimary: props.theme.colors.button.disabledText,
|
|
|
|
|
bgColorPrimary: props.theme.colors[variant].darkest,
|
|
|
|
|
borderColorPrimary: props.theme.colors[variant].darkest,
|
|
|
|
|
},
|
|
|
|
|
[Category.secondary]: {
|
|
|
|
|
txtColorSecondary: props.theme.colors.button.disabledText,
|
|
|
|
|
bgColorSecondary: props.theme.colors[variant].darkest,
|
|
|
|
|
borderColorSecondary: props.theme.colors[variant].darker,
|
|
|
|
|
},
|
|
|
|
|
[Category.tertiary]: {
|
|
|
|
|
txtColorTertiary: props.theme.colors.button.disabledText,
|
|
|
|
|
bgColorTertiary: props.theme.colors.tertiary.darker,
|
|
|
|
|
borderColorTertiary: props.theme.colors.tertiary.dark,
|
|
|
|
|
},
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
return stylesByCategory[category];
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
const getMainStateStyles = (props: ThemeProp & ButtonProps) => {
|
|
|
|
|
const variant = props.variant || defaultProps.variant;
|
|
|
|
|
const category = props.category || defaultProps.category;
|
|
|
|
|
|
|
|
|
|
const stylesByCategory = {
|
|
|
|
|
[Category.primary]: {
|
|
|
|
|
bgColorPrimary: props.theme.colors[variant].main,
|
|
|
|
|
borderColorPrimary: props.theme.colors[variant].main,
|
|
|
|
|
txtColorPrimary: "#fff",
|
|
|
|
|
},
|
|
|
|
|
[Category.secondary]: {
|
|
|
|
|
borderColorSecondary: props.theme.colors[variant].main,
|
|
|
|
|
txtColorSecondary: props.theme.colors[variant].main,
|
|
|
|
|
bgColorSecondary: "transparent",
|
|
|
|
|
},
|
|
|
|
|
[Category.tertiary]: {
|
|
|
|
|
bgColorTertiary: "transparent",
|
|
|
|
|
borderColorTertiary: props.theme.colors.tertiary.main,
|
|
|
|
|
txtColorTertiary: props.theme.colors.tertiary.main,
|
|
|
|
|
},
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
return stylesByCategory[category];
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
const getHoverStateStyles = (props: ThemeProp & ButtonProps) => {
|
|
|
|
|
const variant = props.variant || defaultProps.variant;
|
|
|
|
|
const category = props.category || defaultProps.category;
|
|
|
|
|
|
|
|
|
|
const stylesByCategory = {
|
|
|
|
|
[Category.primary]: {
|
|
|
|
|
bgColorPrimary: props.theme.colors[variant].dark,
|
|
|
|
|
borderColorPrimary: props.theme.colors[variant].dark,
|
|
|
|
|
txtColorPrimary: "#fff",
|
|
|
|
|
},
|
|
|
|
|
[Category.secondary]: {
|
|
|
|
|
bgColorSecondary: hexToRgba(props.theme.colors[variant].main, 0.1),
|
|
|
|
|
txtColorSecondary: props.theme.colors[variant].main,
|
|
|
|
|
borderColorSecondary: props.theme.colors[variant].main,
|
|
|
|
|
},
|
|
|
|
|
[Category.tertiary]: {
|
|
|
|
|
bgColorTertiary: hexToRgba(props.theme.colors.tertiary.main, 0.1),
|
|
|
|
|
borderColorTertiary: props.theme.colors.tertiary.main,
|
|
|
|
|
txtColorTertiary: props.theme.colors.tertiary.main,
|
|
|
|
|
},
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
return stylesByCategory[category];
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
const getActiveStateStyles = (props: ThemeProp & ButtonProps) => {
|
|
|
|
|
const variant = props.variant || defaultProps.variant;
|
|
|
|
|
const category = props.category || defaultProps.category;
|
|
|
|
|
|
|
|
|
|
const stylesByCategory = {
|
|
|
|
|
[Category.primary]: {
|
|
|
|
|
bgColorPrimary: props.theme.colors[variant].dark,
|
|
|
|
|
borderColorPrimary: props.theme.colors[variant].main,
|
|
|
|
|
txtColorPrimary: "#fff",
|
|
|
|
|
},
|
|
|
|
|
[Category.secondary]: {
|
|
|
|
|
bgColorSecondary: hexToRgba(props.theme.colors[variant].main, 0.1),
|
|
|
|
|
txtColorSecondary: props.theme.colors[variant].light,
|
|
|
|
|
borderColorSecondary: props.theme.colors[variant].light,
|
|
|
|
|
},
|
|
|
|
|
[Category.tertiary]: {
|
|
|
|
|
bgColorTertiary: hexToRgba(props.theme.colors.tertiary.main, 0.1),
|
|
|
|
|
borderColorTertiary: props.theme.colors.tertiary.light,
|
|
|
|
|
txtColorTertiary: props.theme.colors.tertiary.light,
|
|
|
|
|
},
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
return stylesByCategory[category];
|
2020-08-10 04:54:33 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
|
|
const stateStyles = (
|
|
|
|
|
props: ThemeProp & ButtonProps,
|
2021-02-04 07:02:36 +00:00
|
|
|
stateArg: string,
|
2020-08-10 04:54:33 +00:00
|
|
|
): stateStyleType => {
|
2021-02-04 07:02:36 +00:00
|
|
|
const styles = {
|
|
|
|
|
bgColorPrimary: "",
|
|
|
|
|
borderColorPrimary: "",
|
|
|
|
|
txtColorPrimary: "",
|
|
|
|
|
bgColorSecondary: "",
|
|
|
|
|
borderColorSecondary: "",
|
|
|
|
|
txtColorSecondary: "",
|
|
|
|
|
bgColorTertiary: "",
|
|
|
|
|
borderColorTertiary: "",
|
|
|
|
|
txtColorTertiary: "",
|
|
|
|
|
};
|
|
|
|
|
const state =
|
|
|
|
|
props.isLoading || props.disabled
|
|
|
|
|
? "disabled"
|
|
|
|
|
: (stateArg as keyof typeof stylesByState);
|
|
|
|
|
const stylesByState = {
|
|
|
|
|
disabled: getDisabledStyles(props),
|
|
|
|
|
main: getMainStateStyles(props),
|
|
|
|
|
hover: getHoverStateStyles(props),
|
|
|
|
|
active: getActiveStateStyles(props),
|
|
|
|
|
};
|
2020-08-10 04:54:33 +00:00
|
|
|
|
|
|
|
|
return {
|
2021-02-04 07:02:36 +00:00
|
|
|
...styles,
|
|
|
|
|
...stylesByState[state],
|
2020-08-10 04:54:33 +00:00
|
|
|
};
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
const btnColorStyles = (
|
|
|
|
|
props: ThemeProp & ButtonProps,
|
|
|
|
|
state: string,
|
|
|
|
|
): BtnColorType => {
|
|
|
|
|
let bgColor = "",
|
|
|
|
|
txtColor = "",
|
|
|
|
|
border = "";
|
|
|
|
|
switch (props.category) {
|
|
|
|
|
case Category.primary:
|
|
|
|
|
bgColor = stateStyles(props, state).bgColorPrimary;
|
|
|
|
|
txtColor = stateStyles(props, state).txtColorPrimary;
|
|
|
|
|
border = `2px solid ${stateStyles(props, state).borderColorPrimary}`;
|
|
|
|
|
break;
|
|
|
|
|
case Category.secondary:
|
|
|
|
|
bgColor = stateStyles(props, state).bgColorSecondary;
|
|
|
|
|
txtColor = stateStyles(props, state).txtColorSecondary;
|
|
|
|
|
border = `2px solid ${stateStyles(props, state).borderColorSecondary}`;
|
|
|
|
|
break;
|
|
|
|
|
case Category.tertiary:
|
|
|
|
|
bgColor = stateStyles(props, state).bgColorTertiary;
|
|
|
|
|
txtColor = stateStyles(props, state).txtColorTertiary;
|
|
|
|
|
border = `2px solid ${stateStyles(props, state).borderColorTertiary}`;
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
return { bgColor, txtColor, border };
|
|
|
|
|
};
|
|
|
|
|
|
2021-02-04 07:02:36 +00:00
|
|
|
const getPaddingBySize = (props: ThemeProp & ButtonProps) => {
|
|
|
|
|
const paddingBySize = {
|
|
|
|
|
[Size.small]: `0px ${props.theme.spaces[3]}px`,
|
|
|
|
|
[Size.medium]: `0px ${props.theme.spaces[7]}px`,
|
|
|
|
|
[Size.large]: `0px ${props.theme.spaces[12] - 4}px`,
|
|
|
|
|
};
|
|
|
|
|
const paddingBySizeForJustIcon = {
|
|
|
|
|
[Size.small]: `0px ${props.theme.spaces[1]}px`,
|
|
|
|
|
[Size.medium]: `0px ${props.theme.spaces[2]}px`,
|
|
|
|
|
[Size.large]: `0px ${props.theme.spaces[3]}px`,
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
const isIconOnly = !props.text && props.icon;
|
|
|
|
|
const paddingConfig = isIconOnly ? paddingBySizeForJustIcon : paddingBySize;
|
|
|
|
|
|
|
|
|
|
const iSizeInConfig =
|
|
|
|
|
Object.keys(paddingConfig).indexOf(props.size || "") !== -1;
|
|
|
|
|
const size: any = props.size && iSizeInConfig ? props.size : Size.small;
|
|
|
|
|
|
|
|
|
|
return paddingConfig[size as keyof typeof paddingConfig];
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
const getHeightBySize = (props: ThemeProp & ButtonProps) => {
|
|
|
|
|
const heightBySize = {
|
|
|
|
|
[Size.small]: 20,
|
|
|
|
|
[Size.medium]: 30,
|
|
|
|
|
[Size.large]: 38,
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
const iSizeInConfig =
|
|
|
|
|
Object.keys(heightBySize).indexOf(props.size || "") !== -1;
|
|
|
|
|
const size: any = props.size && iSizeInConfig ? props.size : Size.small;
|
|
|
|
|
|
|
|
|
|
return heightBySize[size as keyof typeof heightBySize];
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
const getBtnFontBySize = (props: ThemeProp & ButtonProps) => {
|
|
|
|
|
const fontBySize = {
|
|
|
|
|
[Size.small]: smallButton,
|
|
|
|
|
[Size.medium]: mediumButton,
|
|
|
|
|
[Size.large]: largeButton,
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
const iSizeInConfig =
|
|
|
|
|
Object.keys(fontBySize).indexOf(props.size || "") !== -1;
|
|
|
|
|
const size: any = props.size && iSizeInConfig ? props.size : Size.small;
|
|
|
|
|
|
|
|
|
|
return fontBySize[size as keyof typeof fontBySize];
|
|
|
|
|
};
|
|
|
|
|
|
2020-08-10 04:54:33 +00:00
|
|
|
const btnFontStyles = (props: ThemeProp & ButtonProps): BtnFontType => {
|
2021-02-04 07:02:36 +00:00
|
|
|
const padding = getPaddingBySize(props);
|
|
|
|
|
const height = getHeightBySize(props);
|
|
|
|
|
const buttonFont = getBtnFontBySize(props);
|
|
|
|
|
|
2020-09-02 08:58:49 +00:00
|
|
|
return { buttonFont, padding, height };
|
2020-08-10 04:54:33 +00:00
|
|
|
};
|
|
|
|
|
|
2020-10-12 07:15:35 +00:00
|
|
|
const ButtonStyles = css<ThemeProp & ButtonProps>`
|
2020-12-24 04:32:25 +00:00
|
|
|
width: ${(props) => (props.fill ? "100%" : "auto")};
|
|
|
|
|
height: ${(props) => btnFontStyles(props).height}px;
|
2020-08-10 04:54:33 +00:00
|
|
|
border: none;
|
2020-09-16 11:50:47 +00:00
|
|
|
text-decoration: none;
|
2020-08-10 04:54:33 +00:00
|
|
|
outline: none;
|
|
|
|
|
text-transform: uppercase;
|
2020-12-24 04:32:25 +00:00
|
|
|
background-color: ${(props) => btnColorStyles(props, "main").bgColor};
|
|
|
|
|
color: ${(props) => btnColorStyles(props, "main").txtColor};
|
|
|
|
|
border: ${(props) => btnColorStyles(props, "main").border};
|
|
|
|
|
border-radius: ${(props) => props.theme.radii[0]};
|
|
|
|
|
${(props) => btnFontStyles(props).buttonFont};
|
|
|
|
|
padding: ${(props) => btnFontStyles(props).padding};
|
2020-09-01 07:24:53 +00:00
|
|
|
.${Classes.ICON} {
|
2020-12-24 04:32:25 +00:00
|
|
|
margin-right: ${(props) =>
|
2020-09-28 05:06:06 +00:00
|
|
|
props.text && props.icon ? `${props.theme.spaces[2] - 1}px` : `0`};
|
2020-09-01 07:24:53 +00:00
|
|
|
path {
|
2020-12-24 04:32:25 +00:00
|
|
|
fill: ${(props) => btnColorStyles(props, "main").txtColor};
|
2020-08-10 04:54:33 +00:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
&:hover {
|
2020-09-16 11:50:47 +00:00
|
|
|
text-decoration: none;
|
2020-12-24 04:32:25 +00:00
|
|
|
background-color: ${(props) => btnColorStyles(props, "hover").bgColor};
|
|
|
|
|
color: ${(props) => btnColorStyles(props, "hover").txtColor};
|
|
|
|
|
border: ${(props) => btnColorStyles(props, "hover").border};
|
|
|
|
|
cursor: ${(props) =>
|
2020-08-14 04:58:03 +00:00
|
|
|
props.isLoading || props.disabled ? `not-allowed` : `pointer`};
|
2020-09-01 07:24:53 +00:00
|
|
|
.${Classes.ICON} {
|
2020-12-24 04:32:25 +00:00
|
|
|
margin-right: ${(props) =>
|
2020-09-28 05:06:06 +00:00
|
|
|
props.text && props.icon ? `${props.theme.spaces[2] - 1}px` : `0`};
|
2020-09-01 07:24:53 +00:00
|
|
|
path {
|
2020-12-24 04:32:25 +00:00
|
|
|
fill: ${(props) => btnColorStyles(props, "hover").txtColor};
|
2020-08-10 04:54:33 +00:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
font-style: normal;
|
|
|
|
|
&:active {
|
2020-12-24 04:32:25 +00:00
|
|
|
background-color: ${(props) => btnColorStyles(props, "active").bgColor};
|
|
|
|
|
color: ${(props) => btnColorStyles(props, "active").txtColor};
|
|
|
|
|
border: ${(props) => btnColorStyles(props, "active").border};
|
|
|
|
|
cursor: ${(props) =>
|
2020-08-14 04:58:03 +00:00
|
|
|
props.isLoading || props.disabled ? `not-allowed` : `pointer`};
|
2020-09-01 07:24:53 +00:00
|
|
|
.${Classes.ICON} {
|
2020-08-10 04:54:33 +00:00
|
|
|
path {
|
2020-12-24 04:32:25 +00:00
|
|
|
fill: ${(props) => btnColorStyles(props, "active").txtColor};
|
2020-08-10 04:54:33 +00:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
display: flex;
|
2020-08-31 04:59:18 +00:00
|
|
|
align-items: center;
|
2020-09-01 07:24:53 +00:00
|
|
|
justify-content: center;
|
2020-08-10 04:54:33 +00:00
|
|
|
position: relative;
|
2020-10-12 07:15:35 +00:00
|
|
|
.${Classes.SPINNER} {
|
2020-08-10 04:54:33 +00:00
|
|
|
position: absolute;
|
|
|
|
|
left: 0;
|
|
|
|
|
right: 0;
|
|
|
|
|
margin-left: auto;
|
|
|
|
|
margin-right: auto;
|
|
|
|
|
}
|
|
|
|
|
`;
|
|
|
|
|
|
2020-10-12 07:15:35 +00:00
|
|
|
const StyledButton = styled("button")`
|
|
|
|
|
${ButtonStyles}
|
|
|
|
|
`;
|
|
|
|
|
|
|
|
|
|
const StyledLinkButton = styled("a")`
|
|
|
|
|
${ButtonStyles}
|
|
|
|
|
`;
|
|
|
|
|
|
2020-08-31 04:59:18 +00:00
|
|
|
export const VisibilityWrapper = styled.div`
|
|
|
|
|
visibility: hidden;
|
|
|
|
|
`;
|
|
|
|
|
|
|
|
|
|
const IconSizeProp = (size?: Size) => {
|
2021-02-04 07:02:36 +00:00
|
|
|
const sizeMapping = {
|
|
|
|
|
[Size.xxs]: IconSize.XXS,
|
|
|
|
|
[Size.xs]: IconSize.XS,
|
|
|
|
|
[Size.small]: IconSize.SMALL,
|
|
|
|
|
[Size.medium]: IconSize.MEDIUM,
|
|
|
|
|
[Size.large]: IconSize.LARGE,
|
|
|
|
|
};
|
2020-08-31 04:59:18 +00:00
|
|
|
|
2021-02-04 07:02:36 +00:00
|
|
|
return size ? sizeMapping[size] : IconSize.SMALL;
|
2020-08-10 04:54:33 +00:00
|
|
|
};
|
|
|
|
|
|
2021-02-04 07:02:36 +00:00
|
|
|
const TextLoadingState = ({ text }: { text?: string }) => (
|
|
|
|
|
<VisibilityWrapper>{text}</VisibilityWrapper>
|
|
|
|
|
);
|
2020-08-10 04:54:33 +00:00
|
|
|
|
2021-02-04 07:02:36 +00:00
|
|
|
const IconLoadingState = ({ size, icon }: { size?: Size; icon?: IconName }) => (
|
|
|
|
|
<Icon name={icon} size={IconSizeProp(size)} invisible={true} />
|
|
|
|
|
);
|
2020-08-10 04:54:33 +00:00
|
|
|
|
2021-02-04 07:02:36 +00:00
|
|
|
const getIconContent = (props: ButtonProps) =>
|
|
|
|
|
props.icon ? (
|
|
|
|
|
props.isLoading ? (
|
|
|
|
|
<IconLoadingState {...props} />
|
|
|
|
|
) : (
|
|
|
|
|
<Icon name={props.icon} size={IconSizeProp(props.size)} />
|
|
|
|
|
)
|
|
|
|
|
) : null;
|
2020-08-10 04:54:33 +00:00
|
|
|
|
2021-02-04 07:02:36 +00:00
|
|
|
const getTextContent = (props: ButtonProps) =>
|
|
|
|
|
props.text ? (
|
|
|
|
|
props.isLoading ? (
|
|
|
|
|
<TextLoadingState text={props.text} />
|
|
|
|
|
) : (
|
|
|
|
|
props.text
|
|
|
|
|
)
|
|
|
|
|
) : null;
|
2020-08-10 04:54:33 +00:00
|
|
|
|
2021-02-04 07:02:36 +00:00
|
|
|
const getButtonContent = (props: ButtonProps) => (
|
|
|
|
|
<>
|
|
|
|
|
{getIconContent(props)}
|
|
|
|
|
{getTextContent(props)}
|
|
|
|
|
{props.isLoading ? <Spinner size={IconSizeProp(props.size)} /> : null}
|
|
|
|
|
</>
|
|
|
|
|
);
|
2020-10-12 07:15:35 +00:00
|
|
|
|
2021-02-04 07:02:36 +00:00
|
|
|
const ButtonComponent = (props: ButtonProps) => (
|
|
|
|
|
<StyledButton
|
|
|
|
|
className={props.className}
|
|
|
|
|
data-cy={props.cypressSelector}
|
|
|
|
|
{...props}
|
|
|
|
|
onClick={(e: React.MouseEvent<HTMLElement>) =>
|
|
|
|
|
props.onClick && props.onClick(e)
|
|
|
|
|
}
|
|
|
|
|
>
|
|
|
|
|
{getButtonContent(props)}
|
|
|
|
|
</StyledButton>
|
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
const LinkButtonComponent = (props: ButtonProps) => (
|
|
|
|
|
<StyledLinkButton
|
|
|
|
|
href={props.href}
|
|
|
|
|
className={props.className}
|
|
|
|
|
data-cy={props.cypressSelector}
|
|
|
|
|
{...props}
|
|
|
|
|
onClick={(e: React.MouseEvent<HTMLElement>) =>
|
|
|
|
|
props.onClick && props.onClick(e)
|
|
|
|
|
}
|
|
|
|
|
>
|
|
|
|
|
{getButtonContent(props)}
|
|
|
|
|
</StyledLinkButton>
|
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
const Button = (props: ButtonProps) =>
|
|
|
|
|
props.tag === "button" ? (
|
|
|
|
|
<ButtonComponent {...props} />
|
|
|
|
|
) : (
|
|
|
|
|
<LinkButtonComponent {...props} />
|
|
|
|
|
);
|
2020-08-10 04:54:33 +00:00
|
|
|
|
|
|
|
|
export default Button;
|
2021-02-04 07:02:36 +00:00
|
|
|
|
|
|
|
|
Button.defaultProps = defaultProps;
|