From 4a7832fc9346b74904d2de029dd480a6c5a1dd6f Mon Sep 17 00:00:00 2001 From: IvanHoncharenko Date: Wed, 12 Apr 2023 13:33:18 +0300 Subject: [PATCH] REACT-326 Button loader added + fixes --- .eslintrc.json | 4 +- src/components/Button/Button.tsx | 65 +++++++++++------ src/components/Button/interfaces/IButton.ts | 19 +++-- src/components/Button/sass/Button.module.scss | 29 +++++--- .../Loaders/BallPulse/BallPulse.tsx | 17 +++++ .../BallPulse/interfaces/IBallPulse.ts | 6 ++ .../BallPulse/sass/BallPulse.module.scss | 69 +++++++++++++++++++ src/constants/tsConstants.ts | 30 ++++++++ src/sass/main.scss | 3 + src/stories/Button.stories.tsx | 2 +- 10 files changed, 204 insertions(+), 40 deletions(-) create mode 100644 src/components/Loaders/BallPulse/BallPulse.tsx create mode 100644 src/components/Loaders/BallPulse/interfaces/IBallPulse.ts create mode 100644 src/components/Loaders/BallPulse/sass/BallPulse.module.scss create mode 100644 src/constants/tsConstants.ts create mode 100644 src/sass/main.scss diff --git a/.eslintrc.json b/.eslintrc.json index 8373694..f31aa4c 100644 --- a/.eslintrc.json +++ b/.eslintrc.json @@ -34,9 +34,7 @@ } ], "jsx-a11y/label-has-for": "off", - "react/jsx-props-no-spreading": ["error", { - "exceptions": ["input"] - }], + "react/jsx-props-no-spreading": "off", "react/jsx-uses-react": "off", "react/react-in-jsx-scope": "off", "react/function-component-definition": [ diff --git a/src/components/Button/Button.tsx b/src/components/Button/Button.tsx index fbceaa7..cb85c42 100644 --- a/src/components/Button/Button.tsx +++ b/src/components/Button/Button.tsx @@ -1,35 +1,58 @@ -import React, { FC, memo } from 'react'; +import React, { FC, memo, useMemo } from 'react'; import { IButtonProps } from './interfaces/IButton'; +import { EColors, ESizes, EVariants } from '../../constants/tsConstants'; import styles from './sass/Button.module.scss'; +import BallPulse from '../Loaders/BallPulse/BallPulse'; const Button: FC = ({ - label = '', + text = '', + aliaLabel = '', disabled = false, - onPress, - variant = 'contained', - color = 'primary', - size = 'medium', + isLoading = false, + onClick, + onMouseEnter, + onMouseLeave, + variant = EVariants.CONTAINED, + color = EColors.PRIMARY, + size = ESizes.MEDIUM, iconLeft = null, iconRight = null, - buttonClass = '', -}) => ( - -); - + disabled={disabled || isLoading} + onClick={onClick} + onMouseEnter={onMouseEnter} + onMouseLeave={onMouseLeave} + > + {iconLeft && {text}} + {text && {text}} + {loader} + {iconRight && {text}} + + ); +}; export default memo(Button); diff --git a/src/components/Button/interfaces/IButton.ts b/src/components/Button/interfaces/IButton.ts index c1dac51..fb6fa66 100644 --- a/src/components/Button/interfaces/IButton.ts +++ b/src/components/Button/interfaces/IButton.ts @@ -1,12 +1,17 @@ +import { EColors, EVariants, EButtonSizes } from '../../../constants/tsConstants'; + export interface IButtonProps { - label?: string, - onPress: () => void, + text?: string, + aliaLabel?: string, disabled?: boolean, - styles?: string, - variant: 'text' | 'contained' | 'outlined', - color: 'primary' | 'warning' | 'error', - size: 'small' | 'medium' | 'big' | 'large', + isLoading?: boolean, + onClick?: () => void, + onMouseEnter?: () => void, + onMouseLeave?: () => void, + variant: EVariants, + color: EColors, + size: EButtonSizes, iconLeft?: string, iconRight?: string, - buttonClass?: string, + className?: string, } diff --git a/src/components/Button/sass/Button.module.scss b/src/components/Button/sass/Button.module.scss index ed96975..b2eb259 100644 --- a/src/components/Button/sass/Button.module.scss +++ b/src/components/Button/sass/Button.module.scss @@ -1,9 +1,10 @@ @import "../../../sass/colors"; +@import "../../../sass/main"; .button { + position: relative; color: $white; background-color: $primary; - font-family: 'Inter', sans-serif; font-weight: 600; font-size: 14px; cursor: pointer; @@ -18,18 +19,18 @@ &.contained { &.primary { background-color: $primary; + transition: all .3s; &:hover { - transition: background-color .5s,color .5s,border .5s; background-color: $primary-hover; } } &.warning { background-color: $warning; + transition: all .3s; &:hover { - transition: background-color .5s,color .5s,border .5s; background-color: $warning-hover; } } @@ -62,9 +63,9 @@ &.primary { border-color: $light-gray; color: $primary; + transition: all .3s; &:hover { - transition: background-color .5s,color .5s,border .5s; background-color: $light-blue; } } @@ -72,20 +73,19 @@ &.warning { border-color: $warning; color: $warning; + transition: all .3s; &:hover { - transition: background-color .5s,color .5s,border .5s; background: $warning-hover; - opacity: 70%; } } &.error { border-color: $error; color: $error; + transition: all .3s; &:hover { - transition: background-color .5s,color .5s,border .5s; background-color: $error-background; } } @@ -106,9 +106,22 @@ } &.disabled { - cursor: default; + transition: initial; + cursor: not-allowed; background: $light-gray!important; color: $gray!important; + border: none; + } + + .loaderText { + visibility: hidden; + } + + .loader { + position: absolute; + left: 50%; + top: 50%; + transform: translate(-50%,-50%); } .iconLeft { diff --git a/src/components/Loaders/BallPulse/BallPulse.tsx b/src/components/Loaders/BallPulse/BallPulse.tsx new file mode 100644 index 0000000..688b2b3 --- /dev/null +++ b/src/components/Loaders/BallPulse/BallPulse.tsx @@ -0,0 +1,17 @@ +import React, { FC } from 'react'; +import { IBallPulseProps } from './interfaces/IBallPulse'; +import { EBallPulseColorsExtender } from '../../../constants/tsConstants'; +import styles from './sass/BallPulse.module.scss'; + +const BallPulse: FC = ({ + className = '', + color = EBallPulseColorsExtender.WHITE, +}) => ( +
+
+
+
+
+); + +export default BallPulse; diff --git a/src/components/Loaders/BallPulse/interfaces/IBallPulse.ts b/src/components/Loaders/BallPulse/interfaces/IBallPulse.ts new file mode 100644 index 0000000..79c681f --- /dev/null +++ b/src/components/Loaders/BallPulse/interfaces/IBallPulse.ts @@ -0,0 +1,6 @@ +import { EBallPulseColors } from '../../../../constants/tsConstants'; + +export interface IBallPulseProps { + className?: string, + color?: EBallPulseColors, +} diff --git a/src/components/Loaders/BallPulse/sass/BallPulse.module.scss b/src/components/Loaders/BallPulse/sass/BallPulse.module.scss new file mode 100644 index 0000000..895afe2 --- /dev/null +++ b/src/components/Loaders/BallPulse/sass/BallPulse.module.scss @@ -0,0 +1,69 @@ +@import '../../../../sass/colors'; + +.wrapper { + display: flex; + + &.white { + > div { + background-color: $white; + } + } + + &.primary { + > div { + background-color: $primary; + } + } + + &.success { + > div { + background-color: $success; + } + } + + &.warning { + > div { + background-color: $warning; + } + } + + &.error { + > div { + background-color: $error; + } + } + + > div { + width: 8px; + height: 8px; + + border-radius: 100%; + margin: 2px; + display: inline-block; + -webkit-animation-fill-mode: both; + animation-fill-mode: both; + + &:nth-child(1) { + animation: scale .75s -.24s infinite cubic-bezier(.2,.68,.18,1.08); + } + + &:nth-child(2) { + animation: scale .75s -.12s infinite cubic-bezier(.2,.68,.18,1.08); + } + + &:nth-child(3) { + animation: scale .75s 0s infinite cubic-bezier(.2,.68,.18,1.08); + } + } +} + +@keyframes scale { + 30% { + -webkit-transform: scale(.3); + transform: scale(.3); + } + 100% { + -webkit-transform: scale(1); + transform: scale(1); + } +} diff --git a/src/constants/tsConstants.ts b/src/constants/tsConstants.ts new file mode 100644 index 0000000..d915f51 --- /dev/null +++ b/src/constants/tsConstants.ts @@ -0,0 +1,30 @@ +export enum ESizes { + SMALL = 'small', + MEDIUM = 'medium', + BIG = 'big', +} + +export enum EVariants { + TEXT = 'text', + CONTAINED = 'contained', + OUTLINED = 'outlined', +} + +export enum EColors { + PRIMARY = 'primary', + WARNING = 'warning', + ERROR = 'error', +} + +enum EButtonSizesExtender { + LARGE = 'large', +} + +export type EButtonSizes = ESizes | EButtonSizesExtender; + +export enum EBallPulseColorsExtender { + WHITE = 'white', + SUCCESS = 'success', +} + +export type EBallPulseColors = EColors | EBallPulseColorsExtender; diff --git a/src/sass/main.scss b/src/sass/main.scss new file mode 100644 index 0000000..3686a00 --- /dev/null +++ b/src/sass/main.scss @@ -0,0 +1,3 @@ +* { + font-family: -apple-system,Inter,BlinkMacSystemFont,Segoe UI,Roboto,Oxygen,Ubuntu,Cantarell,Fira Sans,Droid Sans,Helvetica Neue,sans-serif; +} diff --git a/src/stories/Button.stories.tsx b/src/stories/Button.stories.tsx index 5ad5e8c..759c442 100644 --- a/src/stories/Button.stories.tsx +++ b/src/stories/Button.stories.tsx @@ -11,5 +11,5 @@ const Template: ComponentStory = (args) =>