From 6bf3bebb4066e47a939c65b7e95476cc08e2075d Mon Sep 17 00:00:00 2001 From: Xiao Yijun Date: Fri, 12 Jul 2024 21:51:10 +0800 Subject: [PATCH] feat(experience): support loading state for buttons (#6232) --- .../src/assets/icons/loading-ring.svg | 3 ++ .../Button/RotatingRingIcon.module.scss | 14 ++++++++ .../components/Button/RotatingRingIcon.tsx | 7 ++++ .../Button/SocialLinkButton.module.scss | 9 +++++ .../components/Button/SocialLinkButton.tsx | 24 +++++++++++-- .../src/components/Button/index.module.scss | 34 +++++++++++++++---- .../src/components/Button/index.tsx | 22 +++++++++--- packages/experience/src/scss/_colors.scss | 1 + 8 files changed, 101 insertions(+), 13 deletions(-) create mode 100644 packages/experience/src/assets/icons/loading-ring.svg create mode 100644 packages/experience/src/components/Button/RotatingRingIcon.module.scss create mode 100644 packages/experience/src/components/Button/RotatingRingIcon.tsx diff --git a/packages/experience/src/assets/icons/loading-ring.svg b/packages/experience/src/assets/icons/loading-ring.svg new file mode 100644 index 000000000..6e05dc9be --- /dev/null +++ b/packages/experience/src/assets/icons/loading-ring.svg @@ -0,0 +1,3 @@ + + + diff --git a/packages/experience/src/components/Button/RotatingRingIcon.module.scss b/packages/experience/src/components/Button/RotatingRingIcon.module.scss new file mode 100644 index 000000000..a2af2a979 --- /dev/null +++ b/packages/experience/src/components/Button/RotatingRingIcon.module.scss @@ -0,0 +1,14 @@ +.icon { + animation: rotating 1s linear infinite; +} + + +@keyframes rotating { + from { + transform: rotate(0deg); + } + + to { + transform: rotate(360deg); + } +} diff --git a/packages/experience/src/components/Button/RotatingRingIcon.tsx b/packages/experience/src/components/Button/RotatingRingIcon.tsx new file mode 100644 index 000000000..ef29529fe --- /dev/null +++ b/packages/experience/src/components/Button/RotatingRingIcon.tsx @@ -0,0 +1,7 @@ +import Ring from '@/assets/icons/loading-ring.svg'; + +import * as RotatingRingIconStyles from './RotatingRingIcon.module.scss'; + +const RotatingRingIcon = () => ; + +export default RotatingRingIcon; diff --git a/packages/experience/src/components/Button/SocialLinkButton.module.scss b/packages/experience/src/components/Button/SocialLinkButton.module.scss index aeb4c59da..8ae94cfe7 100644 --- a/packages/experience/src/components/Button/SocialLinkButton.module.scss +++ b/packages/experience/src/components/Button/SocialLinkButton.module.scss @@ -12,6 +12,15 @@ overflow: hidden; } +.loadingIcon { + display: block; + // To avoid the layout shift, add padding manually (keep the same size as the icon) + padding: 0 1.5px; + color: var(--color-brand-70); + font-size: 0; + line-height: normal; +} + .name { flex: 1; overflow: hidden; diff --git a/packages/experience/src/components/Button/SocialLinkButton.tsx b/packages/experience/src/components/Button/SocialLinkButton.tsx index 0b732ed8e..ddfec5661 100644 --- a/packages/experience/src/components/Button/SocialLinkButton.tsx +++ b/packages/experience/src/components/Button/SocialLinkButton.tsx @@ -1,11 +1,14 @@ import classNames from 'classnames'; import { useTranslation } from 'react-i18next'; +import { useDebouncedLoader } from 'use-debounced-loader'; +import RotatingRingIcon from './RotatingRingIcon'; import * as socialLinkButtonStyles from './SocialLinkButton.module.scss'; import * as styles from './index.module.scss'; export type Props = { readonly isDisabled?: boolean; + readonly isLoading?: boolean; readonly className?: string; readonly target: string; readonly logo: string; @@ -13,7 +16,15 @@ export type Props = { readonly onClick?: () => void; }; -const SocialLinkButton = ({ isDisabled, className, target, name, logo, onClick }: Props) => { +const SocialLinkButton = ({ + isDisabled, + isLoading = false, + className, + target, + name, + logo, + onClick, +}: Props) => { const { t, i18n: { language }, @@ -21,6 +32,8 @@ const SocialLinkButton = ({ isDisabled, className, target, name, logo, onClick } const localName = name[language] ?? name.en; + const isLoadingActive = useDebouncedLoader(isLoading, 300); + return ( ); }; diff --git a/packages/experience/src/scss/_colors.scss b/packages/experience/src/scss/_colors.scss index b1d1e4b00..2952cb391 100644 --- a/packages/experience/src/scss/_colors.scss +++ b/packages/experience/src/scss/_colors.scss @@ -38,6 +38,7 @@ --color-brand-30: #4300da; --color-brand-40: #5d34f2; --color-brand-50: #7958ff; + --color-brand-70: #af9eff; --color-alert-60: #ca8000; --color-alert-70: #eb9918;