From fa9bf16092fe83f3af16becd601d702b5c97031c Mon Sep 17 00:00:00 2001 From: simeng-li Date: Thu, 15 Sep 2022 15:52:36 +0800 Subject: [PATCH] refactor(ui): refactor toast (#1928) refactor taost using react modal --- .../ui/src/components/Input/index.module.scss | 1 + .../ui/src/components/Toast/index.module.scss | 18 +++++-- .../ui/src/components/Toast/index.test.tsx | 6 +-- packages/ui/src/components/Toast/index.tsx | 50 +++++++------------ .../ui/src/containers/AppContent/index.tsx | 2 +- packages/ui/src/scss/normalized.scss | 4 ++ 6 files changed, 41 insertions(+), 40 deletions(-) diff --git a/packages/ui/src/components/Input/index.module.scss b/packages/ui/src/components/Input/index.module.scss index 53c4ca60c..0bbe572e7 100644 --- a/packages/ui/src/components/Input/index.module.scss +++ b/packages/ui/src/components/Input/index.module.scss @@ -54,6 +54,7 @@ input { padding-right: calc(24px + _.unit(4)); + outline: none; } } diff --git a/packages/ui/src/components/Toast/index.module.scss b/packages/ui/src/components/Toast/index.module.scss index 4e9369423..7f8975b2c 100644 --- a/packages/ui/src/components/Toast/index.module.scss +++ b/packages/ui/src/components/Toast/index.module.scss @@ -21,14 +21,26 @@ background: var(--color-toast); box-shadow: var(--shadow-2); text-align: center; - opacity: 0%; - transition: opacity 0.3s ease-in-out; word-break: break-word; + pointer-events: auto; +} - &[data-visible='true'] { +/* stylelint-disable selector-class-pattern */ +:global { + .ReactModal__Content[role='toast'] { + opacity: 0%; + transition: opacity 0.3s ease-in-out; + } + + .ReactModal__Content--after-open[role='toast'] { opacity: 100%; } + + .ReactModal__Content--before-close[role='toast'] { + opacity: 0%; + } } +/* stylelint-enable selector-class-pattern */ :global(body.desktop) { .toast { diff --git a/packages/ui/src/components/Toast/index.test.tsx b/packages/ui/src/components/Toast/index.test.tsx index dc1586abe..944f0b45e 100644 --- a/packages/ui/src/components/Toast/index.test.tsx +++ b/packages/ui/src/components/Toast/index.test.tsx @@ -7,20 +7,20 @@ jest.useFakeTimers(); describe('Toast Component', () => { it('showToast', () => { const message = 'mock toast message'; - const { queryByText } = render(); + const { queryByText } = render(); expect(queryByText(message)).not.toBeNull(); }); it('should not render empty toast', () => { const message = 'mock toast message'; - const { queryByText } = render(); + const { queryByText } = render(); expect(queryByText(message)).toBeNull(); }); it('should run callback method when transition end', () => { const callback = jest.fn(); const message = 'mock toast message'; - const { container } = render(); + const { container } = render(); const toast = container.querySelector('[data-visible=true]'); act(() => { diff --git a/packages/ui/src/components/Toast/index.tsx b/packages/ui/src/components/Toast/index.tsx index 933ed8997..c9eb88d25 100644 --- a/packages/ui/src/components/Toast/index.tsx +++ b/packages/ui/src/components/Toast/index.tsx @@ -1,59 +1,43 @@ -import { useState, useRef, useEffect, useCallback } from 'react'; +import { useEffect, useState } from 'react'; +import ReactModal from 'react-modal'; import * as styles from './index.module.scss'; type Props = { message: string; - isVisible?: boolean; duration?: number; callback?: () => void; }; -const Toast = ({ message, isVisible = false, duration = 3000, callback }: Props) => { - const toastElement = useRef(null); - const [show, setShow] = useState(false); - - const callbackHandler = useCallback(() => { - // Only execute on hide transitionend event - if (toastElement.current?.dataset.visible === 'true') { - return; - } - - callback?.(); - }, [callback]); +const Toast = ({ message, duration = 3000, callback }: Props) => { + const [text, setText] = useState(''); useEffect(() => { - if (!isVisible) { + if (!message) { return; } - setShow(true); + setText(message); const timer = setTimeout(() => { - setShow(false); + callback?.(); }, duration); return () => { clearTimeout(timer); - setShow(false); }; - }, [callback, duration, isVisible]); - - if (!isVisible) { - return null; - } + }, [callback, duration, message, text]); return ( -
-
- {message} -
-
+ + {text} + ); }; diff --git a/packages/ui/src/containers/AppContent/index.tsx b/packages/ui/src/containers/AppContent/index.tsx index ffeed995d..674a7572f 100644 --- a/packages/ui/src/containers/AppContent/index.tsx +++ b/packages/ui/src/containers/AppContent/index.tsx @@ -41,7 +41,7 @@ const AppContent = ({ children }: Props) => { {platform === 'web' &&
}
{children}
{platform === 'web' &&
} - +
); }; diff --git a/packages/ui/src/scss/normalized.scss b/packages/ui/src/scss/normalized.scss index 1378d5e15..13cdd9c19 100644 --- a/packages/ui/src/scss/normalized.scss +++ b/packages/ui/src/scss/normalized.scss @@ -27,3 +27,7 @@ input::-webkit-inner-spin-button { input[type='number'] { -moz-appearance: textfield; } + +:focus-visible { + outline: solid 1px var(--color-primary); +}