Skip to content

Commit

Permalink
feat(Alert): Add new Alert and AlertTitle components
Browse files Browse the repository at this point in the history
  • Loading branch information
JF-Cozy committed Jul 25, 2022
1 parent d1e9d81 commit cf5593b
Show file tree
Hide file tree
Showing 9 changed files with 765 additions and 303 deletions.
2 changes: 2 additions & 0 deletions docs/styleguide.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -136,6 +136,8 @@ module.exports = {
{
name: 'Special',
components: () => [
'../react/Alert/index.jsx',
'../react/AlertTitle/index.jsx',
'../react/Alerter/index.jsx',
'../react/AppIcon/index.jsx',
'../react/AppTile/index.jsx',
Expand Down
132 changes: 132 additions & 0 deletions react/Alert/Readme.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,132 @@
```jsx
import Alert from 'cozy-ui/transpiled/react/Alert'
import AlertTitle from 'cozy-ui/transpiled/react/AlertTitle'
import Button from 'cozy-ui/transpiled/react/Buttons'
import Icon from 'cozy-ui/transpiled/react/Icon'
import Variants from 'cozy-ui/docs/components/Variants'
import DeviceLaptopIcon from 'cozy-ui/transpiled/react/Icons/DeviceLaptop'
import DownloadIcon from 'cozy-ui/transpiled/react/Icons/Download'

const initialVariants = [{
longText: false,
title: false,
block: false,
color: false,
largeIcon: false,
noIcon: false,
square: false,
actionOne: false,
actionTwo: false,
close: false
}]

;

<Variants initialVariants={initialVariants} screenshotAllVariants>
{variant => (
<Alert
color={variant.color ? "#EFA82D" : undefined}
block={variant.block}
square={variant.square}
icon={variant.noIcon ? false : variant.largeIcon ? <Icon icon={DeviceLaptopIcon} color="var(--errorColor)" size={32} /> : undefined}
action={(variant.actionOne || variant.actionTwo) ?
<>
{variant.actionOne &&
<Button variant="text" size="small" label="Download" startIcon={<Icon icon={DownloadIcon} />} />
}
{variant.actionTwo &&
<Button variant="text" size="small" label="No, thanks!" />
}
</>
: undefined
}
onClose={variant.close ? () => {} : undefined}
>
{variant.title && <AlertTitle>This is the title</AlertTitle>}
{variant.longText
? content.ada.short
: "Get Cozy Drive for Desktop and synchronise your files safely to make them accessible at all times."
}
</Alert>
)}
</Variants>
```

### Colors

```jsx
import Alert from 'cozy-ui/transpiled/react/Alert'
import AlertTitle from 'cozy-ui/transpiled/react/AlertTitle'
import Button from 'cozy-ui/transpiled/react/Buttons'
import Typography from 'cozy-ui/transpiled/react/Typography'
import Variants from 'cozy-ui/docs/components/Variants'

const colors = ['primary', 'secondary','success', 'error', 'warning', 'info']
const initialVariants = [{ title: true, block: false, close: false }]

const makeButtonColor = color => ['primary', 'secondary'].includes(color) ? undefined : color

;

<Variants initialVariants={initialVariants} screenshotAllVariants>
{variant => (
<>
{colors.map(color =>
<div className="u-mb-1" key={color}>
<Alert
severity={color}
block={variant.block}
action={variant.close ? undefined : (
<Button variant="text" size="small" color={makeButtonColor(color)} label="ACTION" />
)}
onClose={variant.close ? () => {} : undefined}
>
{variant.title && <AlertTitle>{color.toUpperCase()}</AlertTitle>}
This is a {color} alert
</Alert>
</div>
)}

<hr />
<Typography variant="h4" paragraph>Filled variant</Typography>

{colors.map(color =>
<div className="u-mb-1" key={color}>
<Alert
variant="filled"
severity={color}
block={variant.block}
action={variant.close ? undefined : (
<Button variant="primary" size="small" color={makeButtonColor(color)} label="ACTION" />
)}
onClose={variant.close ? () => {} : undefined}
>
{variant.title && <AlertTitle>{color.toUpperCase()}</AlertTitle>}
This is a {color} alert
</Alert>
</div>
)}

<hr />
<Typography variant="h4" paragraph>Outlined variant</Typography>

{colors.map(color =>
<div className="u-mb-1" key={color}>
<Alert
variant="outlined"
severity={color}
block={variant.block}
action={variant.close ? undefined : (
<Button variant="text" size="small" color={makeButtonColor(color)} label="ACTION" />
)}
onClose={variant.close ? () => {} : undefined}
>
{variant.title && <AlertTitle>{color.toUpperCase()}</AlertTitle>}
This is a {color} alert
</Alert>
</div>
)}
</>
)}
</Variants>
```
113 changes: 113 additions & 0 deletions react/Alert/index.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,113 @@
import React, { forwardRef } from 'react'
import PropTypes from 'prop-types'
import cx from 'classnames'
import MuiAlert from '@material-ui/lab/Alert'
import { makeStyles } from '@material-ui/core/styles'

import Icon from '../Icon'
import CheckCircleIcon from '../Icons/CheckCircle'
import WarningIcon from '../Icons/Warning'
import WarningCircleIcon from '../Icons/WarningCircle'
import InfoIcon from '../Icons/Info'

const DEFAULT_ICON_SIZE = 16

const defaultIconMapping = {
success: <Icon icon={CheckCircleIcon} />,
warning: <Icon icon={WarningIcon} />,
error: <Icon icon={WarningCircleIcon} />,
info: <Icon icon={InfoIcon} />
}

const makeIcon = (icon, severity) => {
// used to remove icon
if (icon === false) {
return false
}

return (
icon ||
(['primary', 'secondary'].includes(severity) && <Icon icon={InfoIcon} />) ||
undefined
)
}

const useStyles = makeStyles({
message: {
maxWidth: ({ block, iconSize }) =>
block && `calc(100% - ${iconSize + 16}px)`
}
})

const Alert = forwardRef(
(
{
className,
icon,
severity,
block,
color,
square,
action,
variant,
children,
...props
},
ref
) => {
const madeSeverity = ['primary', 'secondary'].includes(severity)
? 'success'
: severity
const madeIcon = makeIcon(icon, severity)
const iconSize = icon?.props?.size || DEFAULT_ICON_SIZE
const styles = useStyles({ iconSize, block })

return (
<MuiAlert
ref={ref}
style={{ backgroundColor: color, borderRadius: square && 0 }}
className={cx(
className,
`cozyAlert-${severity}-${variant}`,
{ block },
{ action: Boolean(action) }
)}
classes={styles}
variant={variant}
severity={madeSeverity}
iconMapping={defaultIconMapping}
icon={madeIcon}
action={action}
{...props}
>
{children}
</MuiAlert>
)
}
)

Alert.propTypes = {
className: PropTypes.string,
icon: PropTypes.oneOfType([PropTypes.element, PropTypes.bool]),
severity: PropTypes.oneOf([
'primary',
'secondary',
'success',
'error',
'warning',
'info'
]),
block: PropTypes.bool,
color: PropTypes.string,
square: PropTypes.bool,
variant: PropTypes.oneOf(['standard', 'outlined', 'filled'])
}

Alert.defaultProps = {
severity: 'primary',
block: false,
square: false,
variant: 'standard'
}

export default Alert
1 change: 1 addition & 0 deletions react/AlertTitle/Readme.md
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Re-export of @material-ui. See [the official API](https://v4.mui.com/api/alert-title/).
3 changes: 3 additions & 0 deletions react/AlertTitle/index.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
import MuiAlertTitle from '@material-ui/lab/AlertTitle'

export default MuiAlertTitle
110 changes: 109 additions & 1 deletion react/MuiCozyTheme/makeOverrides.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { alpha } from '@material-ui/core/styles'
import { alpha, lighten, darken } from '@material-ui/core/styles'

const SWITCH_BAR_WIDTH = 25

Expand All @@ -9,6 +9,65 @@ export const makeThemeOverrides = theme => {
return createOverrides(theme)
}

const makeAlertColor = (theme, color) => {
const themeColorByColor = {
primary: theme.palette[color].main,
secondary: theme.palette.text.primary
}

// same approach as Mui, see https://github.com/mui/material-ui/blob/v4.x/packages/material-ui-lab/src/Alert/Alert.js#L28
return {
'&-standard': {
color: darken(themeColorByColor[color], 0.6),
backgroundColor: lighten(themeColorByColor[color], 0.9),
'& $icon': {
color: themeColorByColor[color]
},
'& $action': {
'& button[title="Close"]': {
color: theme.palette.text.secondary
}
}
},
'&-outlined': {
color: darken(themeColorByColor[color], 0.6),
border: `1px solid ${themeColorByColor[color]}`,
'& $icon': {
color: themeColorByColor[color]
}
},
'&-filled': {
backgroundColor: themeColorByColor[color]
}
}
}

const makeAlertInvertedColor = (theme, color) => {
return {
'&-standard': {
color: theme.palette.primary.main,
backgroundColor: theme.palette.background.default,
'& $icon': {
color: theme.palette[color].main
}
},
'&-outlined': {
color: theme.palette.primary.main,
border: `1px solid ${theme.palette.primary.main}`,
'& $icon': {
color: theme.palette[color].main
}
},
'&-filled': {
color: theme.palette[color].contrastText,
backgroundColor: theme.palette[color].main,
'& $icon': {
color: theme.palette[color].contrastText
}
}
}
}

const makeChipStyleByColor = (theme, color) => ({
color: theme.palette.text[color] || theme.palette[color].main,
borderColor:
Expand Down Expand Up @@ -822,6 +881,41 @@ const makeOverrides = theme => ({
'&-info': makeChipStyleByColor(theme, 'info')
}
}
},
MuiAlert: {
root: {
padding: '8px 16px',
'&.cozyAlert': {
'&-primary': makeAlertColor(theme, 'primary'),
'&-secondary': makeAlertColor(theme, 'secondary')
},
'& $icon': {
paddingTop: '9px'
},
'&.block': {
flexWrap: 'wrap',
'& $action': {
display: 'block',
width: '100%',
paddingLeft: 0,
textAlign: 'right'
}
}
},
message: {
display: 'flex',
alignItems: 'center',
flexWrap: 'wrap'
},
action: {
marginRight: '-6px'
}
},
MuiAlertTitle: {
root: {
width: '100%',
fontWeight: 'bold'
}
}
})

Expand Down Expand Up @@ -883,6 +977,20 @@ const makeInvertedOverrides = invertedTheme => {
color: invertedTheme.palette.error.main
}
}
},
MuiAlert: {
...makeOverrides(invertedTheme).MuiAlert,
root: {
...makeOverrides(invertedTheme).MuiAlert.root,
'&.cozyAlert': {
'&-primary': makeAlertInvertedColor(invertedTheme, 'primary'),
'&-secondary': makeAlertInvertedColor(invertedTheme, 'primary'),
'&-success': makeAlertInvertedColor(invertedTheme, 'success'),
'&-error': makeAlertInvertedColor(invertedTheme, 'error'),
'&-warning': makeAlertInvertedColor(invertedTheme, 'warning'),
'&-info': makeAlertInvertedColor(invertedTheme, 'info')
}
}
}
}

Expand Down
Loading

0 comments on commit cf5593b

Please sign in to comment.