2021-02-03 13:47:01 +00:00
|
|
|
import React from "react";
|
|
|
|
import styled, { css } from "styled-components";
|
|
|
|
|
2023-12-15 13:32:37 +00:00
|
|
|
import { NoUserSelect } from "../../utils";
|
2023-12-05 16:52:30 +00:00
|
|
|
import { Base, TTheme } from "../../themes";
|
2023-11-30 10:26:53 +00:00
|
|
|
import { ButtonProps, ButtonThemeProps } from "./Button.types";
|
|
|
|
import { ButtonSize } from "./Button.enums";
|
|
|
|
|
|
|
|
const activeCss = css<ButtonProps>`
|
2021-02-03 13:47:01 +00:00
|
|
|
background-color: ${(props) =>
|
|
|
|
props.primary
|
|
|
|
? props.theme.button.backgroundColor.primaryActive
|
|
|
|
: props.theme.button.backgroundColor.baseActive};
|
|
|
|
|
|
|
|
color: ${(props) =>
|
|
|
|
props.primary
|
2021-12-12 11:41:50 +00:00
|
|
|
? props.theme.button.color.primaryActive
|
|
|
|
: props.theme.button.color.baseActive};
|
2021-02-03 13:47:01 +00:00
|
|
|
|
|
|
|
${(props) =>
|
2021-12-12 11:41:50 +00:00
|
|
|
!props.primary
|
|
|
|
? css`
|
2023-11-30 10:26:53 +00:00
|
|
|
border: ${props.theme.button.border.baseActive};
|
|
|
|
box-sizing: ${props.theme.button.boxSizing};
|
2021-12-12 11:41:50 +00:00
|
|
|
`
|
|
|
|
: css`
|
2023-11-30 10:26:53 +00:00
|
|
|
border: ${props.theme.button.border.primaryActive};
|
|
|
|
box-sizing: ${props.theme.button.boxSizing};
|
2021-12-12 11:41:50 +00:00
|
|
|
`}
|
2021-12-15 08:17:36 +00:00
|
|
|
|
|
|
|
.btnIcon {
|
|
|
|
svg {
|
|
|
|
path {
|
|
|
|
fill: ${(props) =>
|
|
|
|
props.primary
|
|
|
|
? props.theme.button.color.primaryActive
|
|
|
|
: props.theme.button.color.baseActive};
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2021-02-03 13:47:01 +00:00
|
|
|
`;
|
|
|
|
|
2023-11-30 10:26:53 +00:00
|
|
|
const hoverCss = css<ButtonProps>`
|
2021-02-03 13:47:01 +00:00
|
|
|
background-color: ${(props) =>
|
|
|
|
props.primary
|
|
|
|
? props.theme.button.backgroundColor.primaryHover
|
|
|
|
: props.theme.button.backgroundColor.baseHover};
|
|
|
|
|
|
|
|
color: ${(props) =>
|
|
|
|
props.primary
|
2021-12-12 11:41:50 +00:00
|
|
|
? props.theme.button.color.primaryHover
|
|
|
|
: props.theme.button.color.baseHover};
|
2021-02-03 13:47:01 +00:00
|
|
|
|
|
|
|
${(props) =>
|
2021-12-12 11:41:50 +00:00
|
|
|
!props.primary
|
|
|
|
? css`
|
2023-11-30 10:26:53 +00:00
|
|
|
border: ${props.theme.button.border.baseHover};
|
|
|
|
box-sizing: ${props.theme.button.boxSizing};
|
2021-12-12 11:41:50 +00:00
|
|
|
`
|
|
|
|
: css`
|
2023-11-30 10:26:53 +00:00
|
|
|
border: ${props.theme.button.border.primaryHover};
|
|
|
|
box-sizing: ${props.theme.button.boxSizing};
|
2021-12-12 11:41:50 +00:00
|
|
|
`}
|
2021-12-15 08:17:36 +00:00
|
|
|
|
|
|
|
.btnIcon {
|
|
|
|
svg {
|
|
|
|
path {
|
|
|
|
fill: ${(props) =>
|
|
|
|
props.primary
|
|
|
|
? props.theme.button.color.primaryHover
|
|
|
|
: props.theme.button.color.baseHover};
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2021-12-12 11:41:50 +00:00
|
|
|
`;
|
|
|
|
|
2023-11-30 10:26:53 +00:00
|
|
|
const disableCss = css<ButtonProps>`
|
2021-12-12 11:41:50 +00:00
|
|
|
background-color: ${(props) =>
|
|
|
|
props.primary
|
|
|
|
? props.theme.button.backgroundColor.primaryDisabled
|
|
|
|
: props.theme.button.backgroundColor.baseDisabled};
|
|
|
|
|
|
|
|
color: ${(props) =>
|
|
|
|
props.primary
|
|
|
|
? props.theme.button.color.primaryDisabled
|
|
|
|
: props.theme.button.color.baseDisabled};
|
2021-02-03 13:47:01 +00:00
|
|
|
|
|
|
|
${(props) =>
|
2021-12-12 11:41:50 +00:00
|
|
|
!props.primary
|
|
|
|
? css`
|
2023-11-30 10:26:53 +00:00
|
|
|
border: ${props.theme.button.border.baseDisabled};
|
|
|
|
box-sizing: ${props.theme.button.boxSizing};
|
2021-12-12 11:41:50 +00:00
|
|
|
`
|
|
|
|
: css`
|
2023-11-30 10:26:53 +00:00
|
|
|
border: ${props.theme.button.border.primaryDisabled};
|
|
|
|
box-sizing: ${props.theme.button.boxSizing};
|
2021-12-12 11:41:50 +00:00
|
|
|
`}
|
2021-12-15 08:17:36 +00:00
|
|
|
|
|
|
|
.btnIcon {
|
|
|
|
svg {
|
|
|
|
path {
|
|
|
|
fill: ${(props) =>
|
|
|
|
props.primary
|
|
|
|
? props.theme.button.color.primaryDisabled
|
|
|
|
: props.theme.button.color.baseDisabled};
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2021-02-03 13:47:01 +00:00
|
|
|
`;
|
|
|
|
|
2023-12-20 09:14:18 +00:00
|
|
|
const heightStyle = (props: { size?: ButtonSize; theme: TTheme }) =>
|
|
|
|
props.theme.button.height[props.size || ButtonSize.normal];
|
|
|
|
const fontSizeStyle = (props: { size?: ButtonSize; theme: TTheme }) =>
|
|
|
|
props.theme.button.fontSize[props.size || ButtonSize.normal];
|
2021-02-03 13:47:01 +00:00
|
|
|
|
2023-12-28 08:46:16 +00:00
|
|
|
const ButtonWrapper = React.forwardRef<
|
|
|
|
HTMLButtonElement,
|
|
|
|
ButtonProps & {
|
|
|
|
interfaceDirection?: boolean | string;
|
|
|
|
}
|
|
|
|
>(
|
|
|
|
(
|
|
|
|
{
|
|
|
|
primary,
|
|
|
|
scale,
|
|
|
|
size,
|
|
|
|
isHovered,
|
|
|
|
isClicked,
|
|
|
|
isDisabled,
|
|
|
|
disableHover,
|
|
|
|
isLoading,
|
|
|
|
label,
|
|
|
|
minWidth,
|
|
|
|
...props
|
|
|
|
},
|
|
|
|
ref,
|
|
|
|
) => {
|
|
|
|
return <button ref={ref} type="button" {...props} />;
|
|
|
|
},
|
|
|
|
);
|
|
|
|
|
|
|
|
ButtonWrapper.displayName = "ButtonWrapper";
|
2021-02-03 13:47:01 +00:00
|
|
|
|
2023-11-30 10:26:53 +00:00
|
|
|
const StyledButton = styled(ButtonWrapper).attrs((props: ButtonProps) => ({
|
2021-02-03 13:47:01 +00:00
|
|
|
disabled: props.isDisabled || props.isLoading ? "disabled" : "",
|
|
|
|
tabIndex: props.tabIndex,
|
|
|
|
}))`
|
2022-11-04 07:51:23 +00:00
|
|
|
position: relative;
|
2023-11-30 10:26:53 +00:00
|
|
|
direction: ${(props) => props?.interfaceDirection && "rtl"};
|
2021-02-03 13:47:01 +00:00
|
|
|
height: ${(props) => heightStyle(props)};
|
2023-11-09 16:43:16 +00:00
|
|
|
font-size: ${(props) => props.theme.getCorrectFontSize(fontSizeStyle(props))};
|
2021-02-03 13:47:01 +00:00
|
|
|
|
|
|
|
color: ${(props) =>
|
2021-12-12 11:41:50 +00:00
|
|
|
!props.primary
|
2021-02-03 13:47:01 +00:00
|
|
|
? props.theme.button.color.base
|
2021-12-12 11:41:50 +00:00
|
|
|
: props.theme.button.color.primary};
|
2021-02-03 13:47:01 +00:00
|
|
|
|
|
|
|
background-color: ${(props) =>
|
2021-12-12 11:41:50 +00:00
|
|
|
props.primary
|
|
|
|
? props.theme.button.backgroundColor.primary
|
2021-02-03 13:47:01 +00:00
|
|
|
: props.theme.button.backgroundColor.base};
|
|
|
|
|
2021-12-12 11:41:50 +00:00
|
|
|
border: ${(props) =>
|
|
|
|
props.primary
|
|
|
|
? props.theme.button.border.primary
|
|
|
|
: props.theme.button.border.base};
|
|
|
|
|
2022-03-14 16:18:17 +00:00
|
|
|
${(props) => props.scale && `width: 100%;`};
|
2023-11-30 10:26:53 +00:00
|
|
|
min-width: ${(props) => props.minWidth && props.minWidth};
|
2022-03-14 16:22:18 +00:00
|
|
|
|
2023-12-20 09:14:18 +00:00
|
|
|
padding: ${(props) =>
|
|
|
|
`${props.theme.button.padding[props.size || ButtonSize.normal]}`};
|
2022-03-14 16:10:10 +00:00
|
|
|
|
2021-02-03 13:47:01 +00:00
|
|
|
cursor: ${(props) =>
|
|
|
|
props.isDisabled || props.isLoading ? "default !important" : "pointer"};
|
|
|
|
|
|
|
|
font-family: ${(props) => props.theme.fontFamily};
|
2023-11-30 10:26:53 +00:00
|
|
|
margin: ${(props) => props.theme.button.margin};
|
2021-02-03 13:47:01 +00:00
|
|
|
display: ${(props) => props.theme.button.display};
|
|
|
|
font-weight: ${(props) => props.theme.button.fontWeight};
|
|
|
|
text-align: ${(props) => props.theme.button.textAlign};
|
|
|
|
text-decoration: ${(props) => props.theme.button.textDecoration};
|
2023-11-30 10:26:53 +00:00
|
|
|
vertical-align: ${(props) => props.theme.button.topVerticalAlign};
|
2021-02-03 13:47:01 +00:00
|
|
|
border-radius: ${(props) => props.theme.button.borderRadius};
|
|
|
|
-moz-border-radius: ${(props) => props.theme.button.borderRadius};
|
|
|
|
-webkit-border-radius: ${(props) => props.theme.button.borderRadius};
|
|
|
|
|
|
|
|
${NoUserSelect};
|
|
|
|
|
|
|
|
stroke: ${(props) => props.theme.button.stroke};
|
|
|
|
overflow: ${(props) => props.theme.button.overflow};
|
|
|
|
text-overflow: ${(props) => props.theme.button.textOverflow};
|
|
|
|
white-space: ${(props) => props.theme.button.whiteSpace};
|
|
|
|
-webkit-tap-highlight-color: rgba(0, 0, 0, 0);
|
|
|
|
|
|
|
|
${(props) =>
|
|
|
|
!props.isDisabled &&
|
|
|
|
!props.isLoading &&
|
|
|
|
(props.isHovered
|
|
|
|
? hoverCss
|
|
|
|
: !props.disableHover &&
|
|
|
|
css`
|
|
|
|
&:hover {
|
|
|
|
${hoverCss}
|
|
|
|
}
|
|
|
|
`)}
|
2021-12-12 11:41:50 +00:00
|
|
|
|
|
|
|
${(props) =>
|
2021-02-03 13:47:01 +00:00
|
|
|
!props.isDisabled &&
|
|
|
|
!props.isLoading &&
|
|
|
|
(props.isClicked
|
|
|
|
? activeCss
|
|
|
|
: css`
|
|
|
|
&:active {
|
|
|
|
${activeCss}
|
|
|
|
}
|
|
|
|
`)}
|
2021-12-12 11:41:50 +00:00
|
|
|
|
2022-11-11 10:17:17 +00:00
|
|
|
${(props) => (props.isDisabled || props.isLoading) && disableCss}
|
2021-12-12 11:41:50 +00:00
|
|
|
|
2022-11-11 10:17:17 +00:00
|
|
|
&:focus {
|
2021-02-03 13:47:01 +00:00
|
|
|
outline: ${(props) => props.theme.button.outline};
|
|
|
|
}
|
|
|
|
|
2022-11-04 14:29:42 +00:00
|
|
|
.loader {
|
|
|
|
display: flex;
|
|
|
|
justify-content: center;
|
|
|
|
align-items: center;
|
|
|
|
|
|
|
|
position: absolute;
|
|
|
|
|
|
|
|
top: 0;
|
|
|
|
left: 0;
|
|
|
|
right: 0;
|
|
|
|
bottom: 0;
|
|
|
|
|
|
|
|
width: 100%;
|
|
|
|
height: 100%;
|
|
|
|
|
2022-11-11 10:17:17 +00:00
|
|
|
background-color: transparent;
|
|
|
|
}
|
|
|
|
|
|
|
|
.button-content {
|
|
|
|
width: 100%;
|
|
|
|
height: 100%;
|
|
|
|
display: flex;
|
|
|
|
justify-content: center;
|
|
|
|
align-items: center;
|
|
|
|
gap: 8px;
|
|
|
|
visibility: ${(props) => (props.isLoading ? "hidden" : "visible")};
|
2022-11-04 14:29:42 +00:00
|
|
|
}
|
2022-03-11 16:43:17 +00:00
|
|
|
|
|
|
|
.icon {
|
|
|
|
width: auto;
|
2022-03-14 15:26:13 +00:00
|
|
|
display: flex;
|
|
|
|
align-items: center;
|
2022-03-11 14:21:52 +00:00
|
|
|
}
|
2021-02-03 13:47:01 +00:00
|
|
|
`;
|
|
|
|
|
2023-11-30 10:26:53 +00:00
|
|
|
StyledButton.defaultProps = { theme: Base };
|
|
|
|
|
|
|
|
const themeActiveCss = css<ButtonThemeProps>`
|
|
|
|
border-color: ${(props) => props.$currentColorScheme?.main?.buttons};
|
2022-03-14 15:26:13 +00:00
|
|
|
|
2023-11-30 10:26:53 +00:00
|
|
|
background: ${(props) =>
|
|
|
|
props.primary && props.$currentColorScheme?.main?.buttons};
|
2022-03-14 15:26:13 +00:00
|
|
|
|
2023-11-30 10:26:53 +00:00
|
|
|
opacity: ${(props) => !props.isDisabled && "1"};
|
2022-03-14 15:26:13 +00:00
|
|
|
|
2023-11-30 10:26:53 +00:00
|
|
|
filter: ${(props) =>
|
|
|
|
props.primary &&
|
|
|
|
(props.theme.isBase ? "brightness(90%)" : "brightness(82%)")};
|
|
|
|
|
|
|
|
color: ${(props) => props.$currentColorScheme?.text?.buttons};
|
|
|
|
`;
|
|
|
|
|
|
|
|
const themeHoverCss = css<ButtonThemeProps>`
|
|
|
|
border-color: ${(props) => props.$currentColorScheme?.main?.buttons};
|
|
|
|
|
|
|
|
background: ${(props) =>
|
|
|
|
props.primary && props.$currentColorScheme?.main?.buttons};
|
|
|
|
|
|
|
|
opacity: ${(props) => props.primary && !props.isDisabled && "0.85"};
|
|
|
|
|
|
|
|
color: ${(props) =>
|
|
|
|
props.primary && props.$currentColorScheme?.text?.buttons};
|
|
|
|
`;
|
|
|
|
|
|
|
|
const getDefaultStyles = ({
|
|
|
|
primary,
|
|
|
|
$currentColorScheme,
|
|
|
|
isDisabled,
|
|
|
|
isLoading,
|
|
|
|
isClicked,
|
|
|
|
isHovered,
|
|
|
|
disableHover,
|
|
|
|
title,
|
|
|
|
}: ButtonThemeProps) =>
|
|
|
|
$currentColorScheme &&
|
|
|
|
!title &&
|
|
|
|
css`
|
|
|
|
${primary &&
|
|
|
|
css`
|
|
|
|
background: ${$currentColorScheme.main?.buttons};
|
|
|
|
opacity: ${isDisabled && "0.6"};
|
|
|
|
border: ${`1px solid`} ${$currentColorScheme.main?.buttons};
|
|
|
|
color: ${$currentColorScheme.text?.buttons};
|
|
|
|
|
|
|
|
.loader {
|
|
|
|
svg {
|
|
|
|
color: ${$currentColorScheme.text?.buttons};
|
|
|
|
}
|
|
|
|
background-color: ${$currentColorScheme.main?.buttons};
|
|
|
|
}
|
|
|
|
`}
|
|
|
|
|
|
|
|
${!isDisabled &&
|
|
|
|
!isLoading &&
|
|
|
|
(isHovered && primary
|
|
|
|
? themeHoverCss
|
|
|
|
: !disableHover &&
|
|
|
|
primary &&
|
|
|
|
css`
|
|
|
|
&:hover,
|
|
|
|
&:focus {
|
|
|
|
${themeHoverCss}
|
|
|
|
}
|
|
|
|
`)}
|
|
|
|
|
|
|
|
${!isDisabled &&
|
|
|
|
!isLoading &&
|
|
|
|
(isClicked
|
|
|
|
? primary && themeActiveCss
|
|
|
|
: primary &&
|
|
|
|
css`
|
|
|
|
&:active {
|
|
|
|
${themeActiveCss}
|
|
|
|
}
|
|
|
|
`)}
|
|
|
|
`;
|
2022-03-14 15:26:13 +00:00
|
|
|
|
2021-02-03 13:47:01 +00:00
|
|
|
StyledButton.defaultProps = { theme: Base };
|
|
|
|
|
2023-11-30 10:26:53 +00:00
|
|
|
const StyledThemeButton = styled(StyledButton)(getDefaultStyles);
|
|
|
|
|
|
|
|
export { StyledThemeButton };
|
|
|
|
|
2021-02-03 13:47:01 +00:00
|
|
|
export default StyledButton;
|