Skip to content

Commit

Permalink
[TS] Add types to flash, clean up some logic (#1824)
Browse files Browse the repository at this point in the history
* feat: add types to flash, clean up some logic

* feat: set allowJs to false in web

* Update packages/web/src/flash/FlashContext.tsx

Co-authored-by: Tobbe Lundberg <[email protected]>

* Update packages/web/src/flash/FlashReducer.ts

Co-authored-by: Tobbe Lundberg <[email protected]>

* Update packages/web/src/flash/FlashReducer.ts

Co-authored-by: Tobbe Lundberg <[email protected]>

* Update packages/web/src/flash/FlashReducer.ts

Co-authored-by: Tobbe Lundberg <[email protected]>

* clarify type import

* remove unnecessary comment

* remove unnecessary style assignment

* Update packages/web/src/flash/FlashContext.tsx

Co-authored-by: Tobbe Lundberg <[email protected]>

* Update packages/web/src/flash/FlashContext.tsx

Co-authored-by: Tobbe Lundberg <[email protected]>

* Update packages/web/src/flash/FlashContext.tsx

Co-authored-by: Tobbe Lundberg <[email protected]>

* Update packages/web/src/flash/FlashContext.tsx

Co-authored-by: Tobbe Lundberg <[email protected]>

* Update packages/web/src/flash/FlashContext.tsx

Co-authored-by: Tobbe Lundberg <[email protected]>

* Update packages/web/src/flash/Flash.tsx

Co-authored-by: Tobbe Lundberg <[email protected]>

* Update packages/web/src/flash/FlashReducer.ts

Co-authored-by: Tobbe Lundberg <[email protected]>

* Update packages/web/tsconfig.json

Co-authored-by: Tobbe Lundberg <[email protected]>

Co-authored-by: Tobbe Lundberg <[email protected]>
Co-authored-by: Daniel Choudhury <[email protected]>
Co-authored-by: David Price <[email protected]>
  • Loading branch information
4 people authored Feb 23, 2021
1 parent 40e145d commit 53bcdb2
Show file tree
Hide file tree
Showing 7 changed files with 135 additions and 123 deletions.
Original file line number Diff line number Diff line change
@@ -1,24 +1,31 @@
import { useEffect, useState } from 'react'

import { useFlash } from 'src/flash/FlashContext'
import type { FlashMessage } from 'src/flash/FlashReducer'

const FlashMessage = ({ message, timeout }) => {
type FlashMessageProps = {
message: FlashMessage
timeout?: number
}

const FlashMessageComponent = ({ message, timeout }: FlashMessageProps) => {
const { dismissMessage, cycleMessage } = useFlash()
const [classes, setClasses] = useState('')

useEffect(() => {
cycleMessage(message.id)
// cycleMessage should not trigger update
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [message.id])
}, [cycleMessage, message.id])

useEffect(() => {
let fadeOutTimer
if (timeout) {
fadeOutTimer = setTimeout(() => {
setClasses('rw-slide-up')
}, timeout)
if (timeout === undefined) {
return
}

const fadeOutTimer = setTimeout(() => {
setClasses('rw-slide-up')
}, timeout)

return () => clearTimeout(fadeOutTimer)
}, [timeout])

Expand All @@ -40,7 +47,7 @@ const FlashMessage = ({ message, timeout }) => {
)
}

const Flash = ({ timeout }) => {
const Flash = ({ timeout }: { timeout?: number }) => {
const { messages } = useFlash()

if (!messages.length) {
Expand All @@ -50,7 +57,7 @@ const Flash = ({ timeout }) => {
return (
<div className="rw-flash" data-testid="flash">
{messages.map((msg) => (
<FlashMessage key={msg.id} message={msg} timeout={timeout} />
<FlashMessageComponent key={msg.id} message={msg} timeout={timeout} />
))}
</div>
)
Expand Down
59 changes: 0 additions & 59 deletions packages/web/src/flash/FlashContext.js

This file was deleted.

64 changes: 64 additions & 0 deletions packages/web/src/flash/FlashContext.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
import React, { createContext, useReducer, useMemo } from 'react'

import type { FlashMessage } from 'src/flash/FlashReducer'
import FlashReducer from 'src/flash/FlashReducer'

type Message = { id: number; text: string }
type MessageOptions = Omit<FlashMessage, 'text' | 'id'>

type FlashContext = {
messages: Message[]
addMessage(text: string, options?: MessageOptions): void
dismissMessage(messageId: number): void
cycleMessage(messageId: number): void
}

export const FlashContext = createContext<FlashContext | null>(null)

export const FlashProvider: React.FunctionComponent = ({ children }) => {
const [messages, dispatch] = useReducer(FlashReducer, [])

const actions = useMemo(() => {
function addMessage(text: string, options: MessageOptions = {}) {
const message = { text, ...options }
dispatch({
type: 'ADD_MESSAGE',
message,
})
}

function dismissMessage(messageId: number) {
dispatch({
type: 'DISMISS_MESSAGE',
messageId,
})
}

function cycleMessage(messageId: number) {
dispatch({
type: 'CYCLE_MESSAGE',
messageId,
})
}
return { addMessage, dismissMessage, cycleMessage }
}, [dispatch])

const flashContextValue = useMemo(() => ({ messages, ...actions }), [
messages,
actions,
])

return (
<FlashContext.Provider value={flashContextValue}>
{children}
</FlashContext.Provider>
)
}

export const useFlash = () => {
const flash = React.useContext(FlashContext)
if (!flash) {
throw Error('useFlash must be used within a FlashProvider')
}
return flash
}
53 changes: 0 additions & 53 deletions packages/web/src/flash/FlashReducer.js

This file was deleted.

54 changes: 54 additions & 0 deletions packages/web/src/flash/FlashReducer.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
export interface FlashMessage {
id: number
text: string
style?: React.HTMLAttributes<HTMLDivElement>['style']
classes?: string
persist?: boolean
viewed?: boolean
}

type FlashAction =
| {
type: 'ADD_MESSAGE'
message: Omit<FlashMessage, 'id'>
}
| {
type: 'DISMISS_MESSAGE'
messageId: number
}
| {
type: 'CYCLE_MESSAGE'
messageId: number
}

export default (messages: FlashMessage[] = [], action: FlashAction) => {
switch (action.type) {
case 'ADD_MESSAGE': {
const newMessage = {
...action.message,
id: messages.length,
}

return [...messages, newMessage]
}
case 'DISMISS_MESSAGE': {
return messages.filter((msg) => msg.id !== action.messageId)
}
case 'CYCLE_MESSAGE': {
// find the message
// if viewed and not persist, remove it
// else mark as viewed
return messages.reduce<FlashMessage[]>((acc, msg) => {
if (msg.id !== action.messageId) {
return [...acc, msg]
}

if (msg.viewed && !msg.persist) {
return acc
}

return [...acc, { ...msg, viewed: true }]
}, [])
}
}
}
File renamed without changes.
1 change: 0 additions & 1 deletion packages/web/tsconfig.json
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@
"paths": {
"src/*": ["./src/*"]
},
"allowJs": true
},
"include": ["./src/**/*", "./global.d.ts"],
"references": [
Expand Down

0 comments on commit 53bcdb2

Please sign in to comment.