parent
1e7be73803
commit
5126ccd6a7
1 changed files with 104 additions and 0 deletions
@ -0,0 +1,104 @@ |
||||
import { |
||||
forwardRef, |
||||
useCallback, |
||||
useImperativeHandle, |
||||
useMemo, |
||||
useState, |
||||
} from 'react'; |
||||
import { v4 as uuidv4 } from 'uuid'; |
||||
|
||||
import MessageBox, { Message, MessageBoxProps } from './MessageBox'; |
||||
|
||||
type MessageGroupOptionalProps = { |
||||
defaultMessageType?: MessageBoxProps['type']; |
||||
}; |
||||
|
||||
type MessageGroupProps = MessageGroupOptionalProps & { |
||||
count: number; |
||||
}; |
||||
|
||||
type MessageGroupForwardedRefContent = { |
||||
setMessage?: (index: number, message?: Message) => void; |
||||
}; |
||||
|
||||
const MESSAGE_GROUP_DEFAULT_PROPS: Required<MessageGroupOptionalProps> = { |
||||
defaultMessageType: 'info', |
||||
}; |
||||
|
||||
const MessageGroup = forwardRef< |
||||
MessageGroupForwardedRefContent, |
||||
MessageGroupProps |
||||
>( |
||||
( |
||||
{ |
||||
count, |
||||
defaultMessageType = MESSAGE_GROUP_DEFAULT_PROPS.defaultMessageType, |
||||
}, |
||||
ref, |
||||
) => { |
||||
const { keys: messageKeys, init: initialMessages } = useMemo( |
||||
() => |
||||
Array.from({ length: count }).reduce<{ |
||||
keys: string[]; |
||||
init: undefined[]; |
||||
}>( |
||||
(previous) => { |
||||
const { keys, init } = previous; |
||||
|
||||
keys.push(uuidv4()); |
||||
init.push(undefined); |
||||
|
||||
return previous; |
||||
}, |
||||
{ keys: [], init: [] }, |
||||
), |
||||
[count], |
||||
); |
||||
|
||||
const [messages, setMessages] = |
||||
useState<Array<Message | undefined>>(initialMessages); |
||||
|
||||
const setMessage = useCallback((index: number, message?: Message) => { |
||||
setMessages((previous) => { |
||||
previous.splice(index, 1, message); |
||||
|
||||
return [...previous]; |
||||
}); |
||||
}, []); |
||||
|
||||
const messageElements = useMemo( |
||||
() => |
||||
messages.map((message, messageIndex) => { |
||||
let messageElement; |
||||
|
||||
if (message) { |
||||
const { children: messageChildren, type = defaultMessageType } = |
||||
message; |
||||
|
||||
messageElement = ( |
||||
<MessageBox |
||||
key={`message-${messageKeys[messageIndex]}`} |
||||
type={type} |
||||
> |
||||
{messageChildren} |
||||
</MessageBox> |
||||
); |
||||
} |
||||
|
||||
return messageElement; |
||||
}), |
||||
[defaultMessageType, messages, messageKeys], |
||||
); |
||||
|
||||
useImperativeHandle(ref, () => ({ setMessage }), [setMessage]); |
||||
|
||||
return <>{messageElements}</>; |
||||
}, |
||||
); |
||||
|
||||
MessageGroup.defaultProps = MESSAGE_GROUP_DEFAULT_PROPS; |
||||
MessageGroup.displayName = 'MessageGroup'; |
||||
|
||||
export type { MessageGroupForwardedRefContent }; |
||||
|
||||
export default MessageGroup; |
Loading…
Reference in new issue