From 02cc226ba7bd2added5e1cc8bb8f52567a06f525 Mon Sep 17 00:00:00 2001 From: lytrankieio123 Date: Wed, 29 Sep 2021 13:39:40 +0700 Subject: [PATCH] :art: styles: message common :%s --- pages/test.tsx | 42 +++++++---- src/components/common/Banner/Banner.tsx | 1 + .../MessageCommon/MessageCommon.module.scss | 7 ++ .../common/MessageCommon/MessageCommon.tsx | 26 +++++++ .../MessageItem/MessageItem.module.scss | 64 +++++++++++++++++ .../MessageCommon/MessageItem/MessageItem.tsx | 71 +++++++++++++++++++ src/components/common/index.ts | 4 +- 7 files changed, 201 insertions(+), 14 deletions(-) create mode 100644 src/components/common/MessageCommon/MessageCommon.module.scss create mode 100644 src/components/common/MessageCommon/MessageCommon.tsx create mode 100644 src/components/common/MessageCommon/MessageItem/MessageItem.module.scss create mode 100644 src/components/common/MessageCommon/MessageItem/MessageItem.tsx diff --git a/pages/test.tsx b/pages/test.tsx index b40ad354a..e94bba73d 100644 --- a/pages/test.tsx +++ b/pages/test.tsx @@ -1,19 +1,35 @@ -import { useEffect, useState } from 'react' -import { - ButtonCommon, Layout -} from 'src/components/common' +import { Layout, MessageCommon } from 'src/components/common' +import { MessageItemProps } from 'src/components/common/MessageCommon/MessageItem/MessageItem' + +const data: MessageItemProps[] = [ + { + id: 1, + content: 'Create account successfully', + type: 'error', + }, + { + id: 2, + content: 'Create account successfully', + type: 'success', + }, + { + id: 3, + content: 'Create account successfully', + type: 'warning', + }, + { + id: 4, + content: 'Create account successfully', + type: 'info', + }, +] export default function Test() { - const [isLoading, setisLoading] = useState(false) - useEffect(() => { - setTimeout(() => { - setisLoading(true) - }, 3000) - }, []) return ( <> - Back to home - Back to home - Back to home + + {/* Create account successfully + Create account successfully + Create account successfully */} ) } diff --git a/src/components/common/Banner/Banner.tsx b/src/components/common/Banner/Banner.tsx index dc95c2146..8a98fe3a6 100644 --- a/src/components/common/Banner/Banner.tsx +++ b/src/components/common/Banner/Banner.tsx @@ -41,4 +41,5 @@ const Banner = memo(({ data }: Props) => { ) }) +Banner.displayName = 'Banner' export default Banner diff --git a/src/components/common/MessageCommon/MessageCommon.module.scss b/src/components/common/MessageCommon/MessageCommon.module.scss new file mode 100644 index 000000000..99137e828 --- /dev/null +++ b/src/components/common/MessageCommon/MessageCommon.module.scss @@ -0,0 +1,7 @@ +.messageCommon { + @apply fixed; + top: 2.4rem; + left: 50%; + z-index: 20000; + transform: translateX(-50%); +} diff --git a/src/components/common/MessageCommon/MessageCommon.tsx b/src/components/common/MessageCommon/MessageCommon.tsx new file mode 100644 index 000000000..8ffd62e35 --- /dev/null +++ b/src/components/common/MessageCommon/MessageCommon.tsx @@ -0,0 +1,26 @@ +import React, { memo } from 'react' +import s from './MessageCommon.module.scss' +import MessageItem, { MessageItemProps } from './MessageItem/MessageItem' + +interface Props { + messages: MessageItemProps[] + onRemove?: (id?: number) => void +} + +const MessageCommon = memo(({ messages, onRemove }: Props) => { + return ( +
+ {messages.map((item) => ( + + ))} +
+ ) +}) + +MessageCommon.displayName = 'MessageCommon' +export default MessageCommon diff --git a/src/components/common/MessageCommon/MessageItem/MessageItem.module.scss b/src/components/common/MessageCommon/MessageItem/MessageItem.module.scss new file mode 100644 index 000000000..da9896d05 --- /dev/null +++ b/src/components/common/MessageCommon/MessageItem/MessageItem.module.scss @@ -0,0 +1,64 @@ +@import "../../../../styles/utilities"; + +.messageItem { + @apply shadow-sm flex justify-center items-center cursor-default; + width: fit-content; + padding: 0.8rem 2.4rem; + margin-bottom: .8rem; + border-radius: 0.8rem; + transition: all .5s; + animation: showMessage .5s; + + &.hide { + display: none; + } + .icon { + @apply flex justify-center items-center; + margin-right: 0.8rem; + svg { + width: 2rem; + height: 2rem; + } + } + &.info { + @apply bg-info-light; + color: var(--info-dark); + .icon svg path { + fill: var(--info); + } + } + &.success { + @apply bg-positive-light; + color: var(--positive-dark); + .icon svg path { + fill: var(--positive); + } + } + &.error { + @apply bg-negative-light; + color: var(--negative-dark); + .icon svg path { + fill: var(--negative); + } + } + &.warning { + @apply bg-warning-light; + color: var(--warning-dark); + .icon svg path { + fill: var(--warning); + } + } +} + + +@keyframes showMessage { + 0% { + transform: translateY(-6rem); + opacity: .5; + } + + 100% { + transform: none; + opacity: 1; + } +} diff --git a/src/components/common/MessageCommon/MessageItem/MessageItem.tsx b/src/components/common/MessageCommon/MessageItem/MessageItem.tsx new file mode 100644 index 000000000..38d7ed180 --- /dev/null +++ b/src/components/common/MessageCommon/MessageItem/MessageItem.tsx @@ -0,0 +1,71 @@ +import classNames from 'classnames' +import React, { memo, useEffect, useMemo, useState } from 'react' +import { IconCheck, IconError, IconInfo } from 'src/components/icons' +import s from './MessageItem.module.scss' + +export interface MessageItemProps { + id?: number + content?: React.ReactNode + type?: 'info' | 'success' | 'error' | 'warning' + timeout?: number + onRemove?: (id?: number) => void +} + +const MessageItem = memo( + ({ id, content, type = 'success', timeout = 3000, onRemove }: MessageItemProps) => { + const [isHide, setIsHide] = useState() + const [isMouseOver, setIsMouseOver] = useState(false) + + const iconElement = useMemo(() => { + switch (type) { + case 'info': + return + case 'success': + return + case 'error': + return + case 'warning': + return + default: + return + } + }, [type]) + + useEffect(() => { + setIsHide(false) + setTimeout(() => { + setIsHide(true) + }, timeout) + }, [timeout, isMouseOver]) + + useEffect(() => { + if (isHide && !isMouseOver && onRemove) { + onRemove(id) + } + }, [isHide, isMouseOver, onRemove, id]) + + const onMouseOver = () => { + setIsMouseOver(true) + } + + const onMouseLeave = () => { + setIsMouseOver(false) + } + + return ( +
+ {iconElement} + {content} +
+ ) + } +) + +MessageItem.displayName = 'MessageItem' +export default MessageItem diff --git a/src/components/common/index.ts b/src/components/common/index.ts index 0edc064cc..eaa33176c 100644 --- a/src/components/common/index.ts +++ b/src/components/common/index.ts @@ -1,4 +1,3 @@ -import { InputFiledInForm } from 'src/components/common/InputFiledInForm/InputFiledInForm'; export { default as ButtonCommon } from './ButtonCommon/ButtonCommon' export { default as Layout } from './Layout/Layout' export { default as CarouselCommon } from './CarouselCommon/CarouselCommon' @@ -51,3 +50,6 @@ export { default as RecommendedRecipes} from './RecommendedRecipes/RecommendedRe export { default as LayoutCheckout} from './LayoutCheckout/LayoutCheckout' export { default as InputPasswordFiledInForm} from './InputPasswordFiledInForm/InputPasswordFiledInForm' export { default as InputFiledInForm} from './InputFiledInForm/InputFiledInForm' +export { default as MessageCommon} from './MessageCommon/MessageCommon' + +