Skip to content

Commit

Permalink
feat #174 - NotificationsV2 updates
Browse files Browse the repository at this point in the history
  • Loading branch information
sam-dassana committed Dec 10, 2020
1 parent 98e7532 commit 8e692f0
Show file tree
Hide file tree
Showing 9 changed files with 221 additions and 61 deletions.
29 changes: 29 additions & 0 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 3 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,9 @@
"dependencies": {
"@ant-design/icons": "^4.2.2",
"@dassana-io/web-utils": "^0.7.2",
"@fortawesome/fontawesome-svg-core": "^1.2.32",
"@fortawesome/free-solid-svg-icons": "^5.15.1",
"@fortawesome/react-fontawesome": "^0.1.13",
"@storybook/addon-cssresources": "^6.0.28",
"@testing-library/jest-dom": "^4.2.4",
"@testing-library/react": "^9.5.0",
Expand Down
9 changes: 8 additions & 1 deletion rollup.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,14 @@ const rootImport = options => ({
})

export default {
external: ['antd', 'react', 'uuid'],
external: [
'antd',
'@fortawesome/fontawesome-svg-core',
'@fortawesome/free-solid-svg-icons',
'@fortawesome/react-fontawesome',
'react',
'uuid'
],
input: 'src/components/index.ts',
output: [
{
Expand Down
58 changes: 56 additions & 2 deletions src/__snapshots__/storybook.test.ts.snap
Original file line number Diff line number Diff line change
Expand Up @@ -369,7 +369,7 @@ exports[`Storyshots Link Href 1`] = `
</div>
`;

exports[`Storyshots Notification Default 1`] = `
exports[`Storyshots Notification Error 1`] = `
<div
className="light storyWrapper-0-1-2"
>
Expand All @@ -381,7 +381,61 @@ exports[`Storyshots Notification Default 1`] = `
type="button"
>
<span>
Click
Error
</span>
</button>
</div>
`;

exports[`Storyshots Notification Info 1`] = `
<div
className="light storyWrapper-0-1-2"
>
<button
className="ant-btn ant-btn-default"
data-test="button"
disabled={false}
onClick={[Function]}
type="button"
>
<span>
Info
</span>
</button>
</div>
`;

exports[`Storyshots Notification Success 1`] = `
<div
className="light storyWrapper-0-1-2"
>
<button
className="ant-btn ant-btn-default"
data-test="button"
disabled={false}
onClick={[Function]}
type="button"
>
<span>
Success
</span>
</button>
</div>
`;

exports[`Storyshots Notification Warning 1`] = `
<div
className="light storyWrapper-0-1-2"
>
<button
className="ant-btn ant-btn-default"
data-test="button"
disabled={false}
onClick={[Function]}
type="button"
>
<span>
Warning
</span>
</button>
</div>
Expand Down
71 changes: 43 additions & 28 deletions src/components/NotificationV2/Notification.tsx
Original file line number Diff line number Diff line change
@@ -1,42 +1,45 @@
import cn from 'classnames'
import { createUseStyles } from 'react-jss'
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'
import { IconButton } from 'components/IconButton'
import { motion } from 'framer-motion'
import { generateNotificationStyles, ProcessedNotification } from './utils'

import {
generateNotificationStyles,
mappedTypesToIcons,
NotificationTypes,
ProcessedNotification
} from './utils'
import React, { FC } from 'react'
import { styleguide, ThemeType } from 'components/assets/styles'
import { styleguide, themedStyles, ThemeType } from 'components/assets/styles'

const {
colors: { blacks },
colors: { oranges, reds, greens },
font,
spacing
} = styleguide

const { dark, light } = ThemeType

const useStyles = createUseStyles({
closeButton: {
...font.label,
'&:hover': {
color: blacks['lighten-30']
},
alignSelf: 'flex-end',
color: blacks['lighten-70'],
cursor: 'pointer',
lineHeight: 1,
position: 'absolute',
right: spacing.s,
top: spacing.s
},
container: generateNotificationStyles(light),
error: { color: reds.base },
icon: {
...font.h2
},
info: { color: themedStyles[light].base.color },
message: {
alignSelf: 'center',
padding: `0 ${spacing.m}px`,
width: '100%'
},
success: { color: greens.base },
warning: { color: oranges.base },
// eslint-disable-next-line sort-keys
'@global': {
[`.${dark}`]: {
'& $closeButton': {
'&:hover': {
color: blacks['lighten-40']
},
color: blacks['lighten-20']
},
'& $container': generateNotificationStyles(dark)
'& $container': generateNotificationStyles(dark),
'& $info': { color: themedStyles[dark].base.color }
}
}
})
Expand All @@ -46,9 +49,19 @@ export type NotificationProps = ProcessedNotification
export const Notification: FC<NotificationProps> = (
props: NotificationProps
) => {
const { message, onClose } = props
const { error, info, success, warning } = NotificationTypes

const { message, onClose, type } = props
const classes = useStyles(props)

const iconClasses = cn({
[classes.error]: type === error,
[classes.icon]: true,
[classes.info]: type === info,
[classes.success]: type === success,
[classes.warning]: type === warning
})

return (
<motion.div
animate={{ opacity: 1, scale: 1, x: 0 }}
Expand All @@ -61,10 +74,12 @@ export const Notification: FC<NotificationProps> = (
type: 'spring'
}}
>
{message}
<div className={classes.closeButton} onClick={onClose}>
X
</div>
<FontAwesomeIcon
className={iconClasses}
icon={mappedTypesToIcons[type].icon}
/>
<div className={classes.message}>{message}</div>
<IconButton onClick={onClose} />
</motion.div>
)
}
14 changes: 6 additions & 8 deletions src/components/NotificationV2/NotificationContext.ts
Original file line number Diff line number Diff line change
@@ -1,15 +1,13 @@
import { createCtx } from '@dassana-io/web-utils'
import { NotificationConfig } from './utils'
import { createContext, useContext } from 'react'

export interface NotificationContextProps {
generateNotification: (notification: NotificationConfig) => void
}

const NotificationCtx = createContext<NotificationContextProps>(
{} as NotificationContextProps
)
const [useNotificationContext, NotificationCtxProvider] = createCtx<
NotificationContextProps
>()

const useNotification = (): NotificationContextProps =>
useContext(NotificationCtx)
const useNotification = (): NotificationContextProps => useNotificationContext()

export { NotificationCtx, useNotification }
export { NotificationCtxProvider, useNotification }
57 changes: 47 additions & 10 deletions src/components/NotificationV2/NotificationV2.stories.tsx
Original file line number Diff line number Diff line change
@@ -1,18 +1,37 @@
import { Button } from '../Button'
import { generatePopupSelector } from '../utils'
import omit from 'lodash/omit'
import React from 'react'
import { SbTheme } from '../../../.storybook/preview'
import startCase from 'lodash/startCase'
import { useTheme } from 'react-jss'
import { Meta, Story } from '@storybook/react/types-6-0'
import {
NotificationConfig,
NotificationProvider,
NotificationTypes,
useNotification
} from './index'

const { error, info, success, warning } = NotificationTypes

export default {
argTypes: {
children: { control: 'text' }
duration: {
control: { max: 10000, min: 1000, step: 500, type: 'range' },
defaultValue: 3000,
description:
'Optional time in miliseconds before the Notification dissapears'
},
message: { description: 'Notification message to display' },
type: {
control: {
options: [error, info, success, warning],
type: 'select'
},
description:
'Notification type which can either be error, info, success or warning. Each type renders a different icon'
}
},
decorators: [
Story => {
Expand All @@ -30,21 +49,39 @@ export default {
title: 'Notification'
} as Meta

const Template: Story = () => {
const Template: Story<NotificationConfig> = args => {
const { generateNotification } = useNotification()

return (
<Button
onClick={() => {
generateNotification({
message: 'Notification Message',
type: NotificationTypes.success
})
}}
{...args}
onClick={() => generateNotification(omit(args, 'children'))}
>
Click
{startCase(args.type)}
</Button>
)
}

export const Default = Template.bind({})
export const Error = Template.bind({})
Error.args = {
message: 'Message for error notification',
type: error
}

export const Info = Template.bind({})
Info.args = {
message: 'Message for info notification',
type: info
}

export const Success = Template.bind({})
Success.args = {
message: 'Message for success notification',
type: success
}

export const Warning = Template.bind({})
Warning.args = {
message: 'Message for warning notification',
type: warning
}
10 changes: 5 additions & 5 deletions src/components/NotificationV2/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -10,16 +10,16 @@ import {
useCreateDomElement,
useNotifications
} from './utils'
import { NotificationCtx, useNotification } from './NotificationContext'
import { NotificationCtxProvider, useNotification } from './NotificationContext'
import React, { FC, ReactNode } from 'react'

const { spacing } = styleguide
const { spacing, topNavHeight } = styleguide

const useStyles = createUseStyles({
container: {
position: 'fixed',
right: spacing.m,
top: 64
top: topNavHeight
}
})

Expand All @@ -42,9 +42,9 @@ const NotificationProvider: FC<NotificationProviderProps> = ({

return (
<>
<NotificationCtx.Provider value={{ generateNotification }}>
<NotificationCtxProvider value={{ generateNotification }}>
{children}
</NotificationCtx.Provider>
</NotificationCtxProvider>
{rootElement &&
createPortal(
<div className={classes.container}>
Expand Down
Loading

0 comments on commit 8e692f0

Please sign in to comment.