Skip to content

Commit

Permalink
feat: Improve AlertProvider
Browse files Browse the repository at this point in the history
BREAKING CHANGE: The `showAlert` function returned by the `useAlert` hook changes signature.

Also, the `variant` was set to `filled`,
it now takes the default value of `Alert`, i.e. `standard`.

Before:
```
const { showAlert } = useAlert()
showAlert(t('foo.bar'), 'error',)
```

Now:
```
const { showAlert } = useAlert()
showAlert({ message: t('foo.bar'), severity: 'error' })
```

Its options now support Alert component props.
Example:
```
showAlert({
   message: t('foo.bar'),
   severity: 'info',
   icon: false,
   color: 'blue',
   square: true
})
```
  • Loading branch information
Merkur39 committed Mar 11, 2024
1 parent c37ad2f commit 723a627
Show file tree
Hide file tree
Showing 3 changed files with 73 additions and 12 deletions.
6 changes: 5 additions & 1 deletion react/Viewer/ViewersByFile/PdfMobileViewer.jsx
Expand Up @@ -36,7 +36,11 @@ export const PdfMobileViewer = ({ file, url, t, gestures }) => {
try {
await client.collection('io.cozy.files').download(file)
} catch (error) {
showAlert(t('Viewer.error.generic'), 'error')
showAlert({
message: t('Viewer.error.generic'),
severity: 'error',
icon: false
})
}
},
[client, showAlert, t]
Expand Down
45 changes: 41 additions & 4 deletions react/providers/Alert/Readme.md
Expand Up @@ -3,23 +3,60 @@ import Variants from 'cozy-ui/docs/components/Variants'
import { BreakpointsProvider } from 'cozy-ui/transpiled/react/providers/Breakpoints'
import AlertProvider, { useAlert } from 'cozy-ui/transpiled/react/providers/Alert'
import Button from 'cozy-ui/transpiled/react/Buttons'
import Icon from 'cozy-ui/transpiled/react/Icon'
import DeviceLaptopIcon from 'cozy-ui/transpiled/react/Icons/DeviceLaptop'

const initialVariants = [{ primary: true, secondary: false, success: false, error: false, warning: false, info: false }]
const initialVariants = [{
title: false,
block: false,
color: false,
largeIcon: false,
noIcon: false,
square: false,
filled: false,
outlined: false,
close: true
}]

const Component = ({ variant }) => {
const { showAlert } = useAlert()

return <Button label="show alert" onClick={() => showAlert('Alert message', variant)}/>
return (
<Button
label="show alert"
onClick={() =>
showAlert({
title: variant.title ? 'Alert title' : undefined,
severity: 'success',
message: 'Alert message',
color: variant.color ? "#EFA82D" : undefined,
variant: variant.filled
? 'filled'
: variant.outlined
? 'outlined'
: undefined,
block: variant.block,
square: variant.square,
icon: variant.noIcon
? false
: variant.largeIcon
? <Icon icon={DeviceLaptopIcon} color="var(--errorColor)" size={32} />
: undefined,
onClose: variant.close ? () => {} : undefined
})
}
/>
)
}

;

<BreakpointsProvider>
<AlertProvider>
<Variants initialVariants={initialVariants} radio>
<Variants initialVariants={initialVariants}>
{variant => (
<>
<Component variant={Object.keys(variant).find(key => variant[key])} />
<Component variant={variant} />
</>
)}
</Variants>
Expand Down
34 changes: 27 additions & 7 deletions react/providers/Alert/index.jsx
Expand Up @@ -2,9 +2,21 @@ import React, { createContext, useState, useContext, useMemo } from 'react'

import Snackbar from '../../Snackbar'
import Alert from '../../Alert'
import AlertTitle from '../../AlertTitle'

/**
* @typedef {import('../../Alert').AlertProps & { message: string, title: string }} ShowAlertArgs
*/
/**
* @typedef {object} UseAlertReturn
* @property {(args: ShowAlertArgs) => void} showAlert
*/

export const AlertContext = createContext()

/**
* @returns {UseAlertReturn}
*/
export const useAlert = () => {
const context = useContext(AlertContext)

Expand All @@ -14,18 +26,26 @@ export const useAlert = () => {
return context
}

const defaultState = { message: '', severity: 'primary', open: false }
const defaultState = {
title: '',
message: '',
open: false
}
const handleClose = (state, setState) => () => {
return setState({ ...state, open: false })
}

const AlertProvider = ({ children }) => {
const [state, setState] = useState(defaultState)
const { open, message, title, ...alertProps } = state

const value = useMemo(
() => ({
showAlert: (message, severity) => {
setState({ message, severity, open: true })
/**
* @param {ShowAlertArgs} args
*/
showAlert: args => {
setState({ open: true, ...args })
}
}),
[]
Expand All @@ -34,14 +54,14 @@ const AlertProvider = ({ children }) => {
return (
<AlertContext.Provider value={value}>
{children}
<Snackbar open={state.open} onClose={handleClose(state, setState)}>
<Snackbar open={open} onClose={handleClose(state, setState)}>
<Alert
variant="filled"
elevation={6}
severity={state.severity}
onClose={handleClose(state, setState)}
{...alertProps}
>
{state.message}
{title && <AlertTitle>{title}</AlertTitle>}
{message}
</Alert>
</Snackbar>
</AlertContext.Provider>
Expand Down

0 comments on commit 723a627

Please sign in to comment.