mirror of
https://github.com/Cockatrice/Cockatrice.git
synced 2026-07-15 23:12:14 -07:00
Webatrice: Registration toasts (#4566)
* wip * Registration Success Toast * remove debugging code * remove unused field * Show toast on successful password reset * Toast on account activation success * lint and PR feedback * Rework interface names to avoid collision * Move CssBaseline to sibling of ToastProvider Co-authored-by: Brent Clark <brent@backboneiq.com>
This commit is contained in:
parent
88b861d632
commit
4c04b4ef5a
11 changed files with 164 additions and 13 deletions
71
webclient/src/components/Toast/ToastContext.tsx
Normal file
71
webclient/src/components/Toast/ToastContext.tsx
Normal file
|
|
@ -0,0 +1,71 @@
|
|||
import { createContext, FC, ReactChild, ReactNode, useContext, useEffect, useReducer, ContextType, Context } from 'react'
|
||||
|
||||
import { ACTIONS, initialState, reducer } from './reducer';
|
||||
import Toast from './Toast'
|
||||
|
||||
interface ToastEntry {
|
||||
isOpen: boolean,
|
||||
children: ReactChild,
|
||||
}
|
||||
|
||||
interface ToastState {
|
||||
toasts: Map<string, ToastEntry>,
|
||||
addToast: (key, children) => void,
|
||||
openToast: (key) => void,
|
||||
closeToast: (key) => void,
|
||||
removeToast: (key) => void,
|
||||
}
|
||||
|
||||
const ToastContext: Context<any> = createContext<ToastState>({
|
||||
toasts: new Map<string, ToastEntry>(),
|
||||
addToast: (key, children) => {},
|
||||
openToast: (key) => {},
|
||||
closeToast: (key) => {},
|
||||
removeToast: (key) => {},
|
||||
});
|
||||
|
||||
export const ToastProvider: FC<ReactNode> = (props) => {
|
||||
const { children } = props
|
||||
const [state, dispatch] = useReducer(reducer, initialState)
|
||||
const providerState = {
|
||||
toasts: state.toasts,
|
||||
addToast: (key, children) => dispatch({ type: ACTIONS.ADD_TOAST, payload: { key, children } }),
|
||||
openToast: key => dispatch({ type: ACTIONS.OPEN_TOAST, payload: key }),
|
||||
closeToast: key => dispatch({ type: ACTIONS.CLOSE_TOAST, payload: key }),
|
||||
removeToast: key => dispatch({ type: ACTIONS.REMOVE_TOAST, payload: key }),
|
||||
}
|
||||
return (
|
||||
<ToastContext.Provider value={providerState}>
|
||||
{children}
|
||||
<div>
|
||||
{Array.from(state.toasts).map(([key, value]) => {
|
||||
const { isOpen, children } = value;
|
||||
return (
|
||||
<Toast key={key} open={isOpen} onClose={() => dispatch({ type: ACTIONS.CLOSE_TOAST, payload: key })}>
|
||||
{children}
|
||||
</Toast>
|
||||
)
|
||||
})}
|
||||
</div>
|
||||
</ToastContext.Provider>
|
||||
)
|
||||
}
|
||||
|
||||
export interface ToastHookOptions {
|
||||
key: string,
|
||||
children: ReactNode
|
||||
}
|
||||
|
||||
export function useToast<ToastHookOptions>({ key, children }) {
|
||||
const { addToast, openToast, closeToast, removeToast } = useContext(ToastContext)
|
||||
|
||||
useEffect(() => {
|
||||
addToast(key, children)
|
||||
}, [])
|
||||
|
||||
return {
|
||||
openToast: () => openToast(key),
|
||||
closeToast: () => closeToast(key),
|
||||
removeToast: () => removeToast(key),
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue