mirror of
https://github.com/vercel/commerce.git
synced 2025-07-22 20:26:49 +00:00
✨ feat: show message common
:%s
This commit is contained in:
@@ -1,35 +1,16 @@
|
||||
import { Layout, MessageCommon } from 'src/components/common'
|
||||
import { MessageItemProps } from 'src/components/common/MessageCommon/MessageItem/MessageItem'
|
||||
import { Layout } from 'src/components/common'
|
||||
import { useMessage } from 'src/components/contexts'
|
||||
|
||||
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 { showMessageSuccess } = useMessage()
|
||||
|
||||
const handleClick = () => {
|
||||
showMessageSuccess("Create account successfully")
|
||||
}
|
||||
|
||||
return (
|
||||
<>
|
||||
<MessageCommon messages={data} />
|
||||
{/* <MessageCommon type='error'>Create account successfully</MessageCommon>
|
||||
<MessageCommon type='info'>Create account successfully</MessageCommon>
|
||||
<MessageCommon type='warning'>Create account successfully</MessageCommon> */}
|
||||
<button onClick={handleClick}>Click me</button>
|
||||
</>
|
||||
)
|
||||
}
|
||||
|
@@ -1,25 +1,24 @@
|
||||
import { CommerceProvider } from '@framework'
|
||||
import { useRouter } from 'next/router'
|
||||
import { FC } from 'react'
|
||||
import { CartDrawerProvider } from 'src/components/contexts'
|
||||
import { CartDrawerProvider, MessageProvider } from 'src/components/contexts'
|
||||
import LayoutContent from './LayoutContent/LayoutContent'
|
||||
interface Props {
|
||||
className?: string
|
||||
children?: any
|
||||
className?: string
|
||||
children?: any
|
||||
}
|
||||
|
||||
const Layout: FC<Props> = ({ children }) => {
|
||||
const { locale = 'en-US' } = useRouter()
|
||||
return (
|
||||
<CommerceProvider locale={locale}>
|
||||
<CartDrawerProvider>
|
||||
<LayoutContent>
|
||||
{children}
|
||||
</LayoutContent>
|
||||
</CartDrawerProvider>
|
||||
</CommerceProvider>
|
||||
|
||||
)
|
||||
const { locale = 'en-US' } = useRouter()
|
||||
return (
|
||||
<CommerceProvider locale={locale}>
|
||||
<CartDrawerProvider>
|
||||
<MessageProvider>
|
||||
<LayoutContent>{children}</LayoutContent>
|
||||
</MessageProvider>
|
||||
</CartDrawerProvider>
|
||||
</CommerceProvider>
|
||||
)
|
||||
}
|
||||
|
||||
export default Layout
|
||||
|
@@ -1,8 +1,9 @@
|
||||
import { useRouter } from 'next/router'
|
||||
import { FC } from 'react'
|
||||
import { useMessage } from 'src/components/contexts'
|
||||
import { useModalCommon } from 'src/components/hooks'
|
||||
import { BRAND, CATEGORY, FEATURED, FILTER_PAGE, ROUTE } from 'src/utils/constanst.utils'
|
||||
import { CartDrawer, Footer, ScrollToTop } from '../..'
|
||||
import { CartDrawer, Footer, MessageCommon, ScrollToTop } from '../..'
|
||||
import Header from '../../Header/Header'
|
||||
import MenuNavigationProductList from '../../MenuNavigationProductList/MenuNavigationProductList'
|
||||
import s from './LayoutContent.module.scss'
|
||||
@@ -16,6 +17,7 @@ const LayoutContent: FC<Props> = ({ children }) => {
|
||||
const { pathname } = useRouter()
|
||||
const { visible: visibleFilter, openModal: openFilter, closeModal: closeFilter } = useModalCommon({ initialValue: false })
|
||||
const router = useRouter()
|
||||
const {messages, removeMessage} = useMessage()
|
||||
|
||||
const toggleFilter = () => {
|
||||
if (visibleFilter) {
|
||||
@@ -44,6 +46,7 @@ const LayoutContent: FC<Props> = ({ children }) => {
|
||||
<Footer />
|
||||
</div>
|
||||
<CartDrawer />
|
||||
<MessageCommon messages={messages} onRemove={removeMessage}/>
|
||||
</>
|
||||
|
||||
)
|
||||
|
@@ -1,21 +1,29 @@
|
||||
import React, { memo } from 'react'
|
||||
import React, { memo, useEffect } from 'react'
|
||||
import s from './MessageCommon.module.scss'
|
||||
import MessageItem, { MessageItemProps } from './MessageItem/MessageItem'
|
||||
|
||||
interface Props {
|
||||
messages: MessageItemProps[]
|
||||
onRemove?: (id?: number) => void
|
||||
onRemove?: (id: number) => void
|
||||
}
|
||||
|
||||
const MessageCommon = memo(({ messages, onRemove }: Props) => {
|
||||
useEffect(() => {
|
||||
console.log("this fun change; onRemove")
|
||||
}, [onRemove])
|
||||
|
||||
const handleRemove = (id: number) => {
|
||||
onRemove && onRemove(id)
|
||||
}
|
||||
|
||||
return (
|
||||
<div className={s.messageCommon}>
|
||||
{messages.map((item) => (
|
||||
{messages.reverse().map((item) => (
|
||||
<MessageItem
|
||||
key={item.id}
|
||||
id={item.id}
|
||||
content={item.content}
|
||||
onRemove={onRemove}
|
||||
onRemove={handleRemove}
|
||||
/>
|
||||
))}
|
||||
</div>
|
||||
|
@@ -53,7 +53,7 @@
|
||||
|
||||
@keyframes showMessage {
|
||||
0% {
|
||||
transform: translateY(-6rem);
|
||||
transform: translateY(-2rem);
|
||||
opacity: .5;
|
||||
}
|
||||
|
||||
|
@@ -8,7 +8,7 @@ export interface MessageItemProps {
|
||||
content?: React.ReactNode
|
||||
type?: 'info' | 'success' | 'error' | 'warning'
|
||||
timeout?: number
|
||||
onRemove?: (id?: number) => void
|
||||
onRemove?: (id: number) => void
|
||||
}
|
||||
|
||||
const MessageItem = memo(
|
||||
@@ -40,7 +40,7 @@ const MessageItem = memo(
|
||||
|
||||
useEffect(() => {
|
||||
if (isHide && !isMouseOver && onRemove) {
|
||||
onRemove(id)
|
||||
onRemove(id || 0)
|
||||
}
|
||||
}, [isHide, isMouseOver, onRemove, id])
|
||||
|
||||
|
27
src/components/contexts/Message/MessageContext.tsx
Normal file
27
src/components/contexts/Message/MessageContext.tsx
Normal file
@@ -0,0 +1,27 @@
|
||||
import { createContext, useContext } from 'react'
|
||||
import { MessageItemProps } from 'src/components/common/MessageCommon/MessageItem/MessageItem'
|
||||
|
||||
export type MessageContextType = {
|
||||
messages: MessageItemProps[]
|
||||
removeMessage: (id: number) => void
|
||||
showMessageSuccess: (content: string, timeout?: number) => void
|
||||
showMessageInfo: (content: string, timeout?: number) => void
|
||||
showMessageError: (content: string, timeout?: number) => void
|
||||
showMessageWarning: (content: string, timeout?: number) => void
|
||||
}
|
||||
export const DEFAULT_MESSAGE_CONTEXT: MessageContextType = {
|
||||
messages: [],
|
||||
removeMessage: () => {},
|
||||
showMessageSuccess: () => {},
|
||||
showMessageInfo: () => {},
|
||||
showMessageError: () => {},
|
||||
showMessageWarning: () => {},
|
||||
}
|
||||
|
||||
export const MessageContext = createContext<MessageContextType>(
|
||||
DEFAULT_MESSAGE_CONTEXT
|
||||
)
|
||||
|
||||
export function useMessage() {
|
||||
return useContext(MessageContext)
|
||||
}
|
67
src/components/contexts/Message/MessageProvider.tsx
Normal file
67
src/components/contexts/Message/MessageProvider.tsx
Normal file
@@ -0,0 +1,67 @@
|
||||
import { ReactNode, useCallback, useState } from 'react'
|
||||
import { MessageItemProps } from 'src/components/common/MessageCommon/MessageItem/MessageItem'
|
||||
import { MessageContext } from './MessageContext'
|
||||
|
||||
type Props = {
|
||||
children: ReactNode
|
||||
}
|
||||
|
||||
export function MessageProvider({ children }: Props) {
|
||||
const [currentId, setCurrentId] = useState<number>(0)
|
||||
const [messages, setMessages] = useState<MessageItemProps[]>([])
|
||||
|
||||
const createNewMessage = (
|
||||
content: string,
|
||||
timeout?: number,
|
||||
type?: 'info' | 'success' | 'error' | 'warning'
|
||||
) => {
|
||||
const item: MessageItemProps = {
|
||||
id: currentId + 1,
|
||||
content: currentId + 1 + content,
|
||||
type,
|
||||
timeout,
|
||||
}
|
||||
setCurrentId(currentId + 1)
|
||||
setMessages([...messages, item])
|
||||
}
|
||||
|
||||
const showMessageSuccess = (content: string, timeout?: number) => {
|
||||
createNewMessage(content, timeout, 'success')
|
||||
}
|
||||
|
||||
const showMessageInfo = (content: string, timeout?: number) => {
|
||||
createNewMessage(content, timeout, 'info')
|
||||
}
|
||||
|
||||
const showMessageError = (content: string, timeout?: number) => {
|
||||
createNewMessage(content, timeout, 'error')
|
||||
}
|
||||
|
||||
const showMessageWarning = (content: string, timeout?: number) => {
|
||||
createNewMessage(content, timeout, 'warning')
|
||||
}
|
||||
|
||||
const removeMessage = (id: number) => {
|
||||
const newMessages = messages.filter((item) => item.id !== id)
|
||||
setMessages(newMessages)
|
||||
|
||||
if (newMessages.length === 0) {
|
||||
setCurrentId(0)
|
||||
}
|
||||
}
|
||||
|
||||
return (
|
||||
<MessageContext.Provider
|
||||
value={{
|
||||
messages,
|
||||
removeMessage,
|
||||
showMessageSuccess,
|
||||
showMessageInfo,
|
||||
showMessageError,
|
||||
showMessageWarning,
|
||||
}}
|
||||
>
|
||||
{children}
|
||||
</MessageContext.Provider>
|
||||
)
|
||||
}
|
@@ -1,2 +1,5 @@
|
||||
export * from './CartDrawer/CartDrawerContext'
|
||||
export * from './CartDrawer/CartDrawerProvider'
|
||||
export * from './CartDrawer/CartDrawerProvider'
|
||||
|
||||
export * from './Message/MessageContext'
|
||||
export * from './Message/MessageProvider'
|
||||
|
Reference in New Issue
Block a user