diff --git a/src/components/form/button/button.component.tsx b/src/components/form/button/button.component.tsx index 720df97..0edb5ed 100644 --- a/src/components/form/button/button.component.tsx +++ b/src/components/form/button/button.component.tsx @@ -3,7 +3,11 @@ import * as React from "react"; // @ts-ignore import styles from "./button.module.scss"; import { cn } from "../../../utils"; -import { BoxComponent, extractBoxProps } from "../../../components"; +import { + BoxComponent, + extractBoxProps, + LoadingIconComponent, +} from "../../../components"; import type { BoxProps } from "../../../components"; type Props = { @@ -11,6 +15,7 @@ type Props = { color?: "blue" | "yellow" | "grey" | "dark" | "light"; className?: string; fullWidth?: boolean; + loading?: boolean; } & Partial & React.DetailedHTMLProps< React.ButtonHTMLAttributes, @@ -22,6 +27,9 @@ export const ButtonComponent: React.FC = ({ variant = "plain", color = "blue", fullWidth, + loading = false, + disabled = false, + children, ...props }) => { const [otherProps, boxProps] = extractBoxProps(props); @@ -40,11 +48,25 @@ export const ButtonComponent: React.FC = ({ [styles.colorDark]: color === "dark", [styles.colorLight]: color === "light", [styles.fullWidth]: !!fullWidth, + [styles.loading]: loading, + [styles.disabled]: disabled, }, className, )} {...otherProps} - /> + disabled={disabled} + > + {loading ? ( + <> +
{children}
+
+ +
+ + ) : ( + children + )} + ); }; diff --git a/src/components/form/button/button.module.scss b/src/components/form/button/button.module.scss index 28b0339..0872f2a 100644 --- a/src/components/form/button/button.module.scss +++ b/src/components/form/button/button.module.scss @@ -15,6 +15,25 @@ cursor: pointer; user-select: none; outline: none; + position: relative; + + &.loading, + &.disabled { + background-color: var(--btn-grey-bg); + border-color: var(--btn-grey-bd); + color: var(--btn-grey-c); + cursor: auto !important; + + .content { + opacity: 0; + } + .loadingIcon { + position: absolute; + left: 50%; + top: 50%; + transform: translate(-50%, -50%); + } + } @include textEllipsis(); @@ -44,24 +63,26 @@ } } - &.colorBlue { - @include btn-color("btn-blue"); - } + &:not(&.loading):not(&.disabled) { + &.colorBlue { + @include btn-color("btn-blue"); + } - &.colorYellow { - @include btn-color("btn-yellow"); - } + &.colorYellow { + @include btn-color("btn-yellow"); + } - &.colorGrey { - @include btn-color("btn-grey"); - } + &.colorGrey { + @include btn-color("btn-grey"); + } - &.colorDark { - @include btn-color("btn-dark"); - } + &.colorDark { + @include btn-color("btn-dark"); + } - &.colorLight { - @include btn-color("btn-light"); + &.colorLight { + @include btn-color("btn-light"); + } } } } diff --git a/src/components/form/button/button.stories.ts b/src/components/form/button/button.stories.ts index 35ccb75..a083b6d 100644 --- a/src/components/form/button/button.stories.ts +++ b/src/components/form/button/button.stories.ts @@ -30,3 +30,17 @@ export const FullWidth = { fullWidth: true, }, }; + +export const Disabled = { + args: { + children: "Button", + disabled: true, + }, +}; + +export const Loading = { + args: { + children: "Button", + loading: true, + }, +}; diff --git a/src/components/icons/icons.stories.tsx b/src/components/icons/icons.stories.tsx index 8bb23a8..957ccf8 100644 --- a/src/components/icons/icons.stories.tsx +++ b/src/components/icons/icons.stories.tsx @@ -30,6 +30,7 @@ import { KeysIconComponent } from "./keys-icon.component"; import { BurgerIconComponent } from "./burger-icon.component"; import { BurgerCrossIconComponent } from "./burger-cross-icon.component"; import { BurgerArrowIconComponent } from "./burger-arrow-icon.component"; +import { LoadingIconComponent } from "./loading-icon.component"; export default { title: "Components/Icons", @@ -71,3 +72,5 @@ export const LowSignal = () => ; export const MediumSignal = () => ; export const HighSignal = () => ; export const FullSignal = () => ; + +export const LoadingIcon = () => ; diff --git a/src/components/icons/index.ts b/src/components/icons/index.ts index e85f159..67b54ba 100644 --- a/src/components/icons/index.ts +++ b/src/components/icons/index.ts @@ -21,6 +21,7 @@ export * from "./keys-icon.component"; export * from "./burger-icon.component"; export * from "./burger-cross-icon.component"; export * from "./burger-arrow-icon.component"; +export * from "./loading-icon.component"; export * from "./cc"; export * from "./signal"; diff --git a/src/components/icons/loading-icon.component.tsx b/src/components/icons/loading-icon.component.tsx new file mode 100644 index 0000000..caffdb6 --- /dev/null +++ b/src/components/icons/loading-icon.component.tsx @@ -0,0 +1,28 @@ +import React from "react"; +import { IconComponent } from "./icon.component"; +import type { IconProps } from "./icon.component"; +//@ts-ignore +import styles from "./loading-icon.module.scss"; +import { cn } from "../../utils"; + +export const LoadingIconComponent: React.FC = ({ + fill = "white", + ...props +}) => ( + + + + +); diff --git a/src/components/icons/loading-icon.module.scss b/src/components/icons/loading-icon.module.scss new file mode 100644 index 0000000..d842443 --- /dev/null +++ b/src/components/icons/loading-icon.module.scss @@ -0,0 +1,19 @@ +@keyframes spin { + from { + transform: rotate(0deg); + } + to { + transform: rotate(360deg); + } +} + +.animateSpin { + animation: spin 1s linear infinite; + + .circle { + opacity: 25%; + } + .move { + opacity: 75%; + } +}