-
Notifications
You must be signed in to change notification settings - Fork 45
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat(notification-manager): add component (#565)
* feat(notification): add usePortal prop * feat(notification-manager): add component * feat(notification-manager): add base of component * feat(notification-manager): updates * feat(notification-manager): updates * test(notification-manager): add tests * docs(notification-manager): fix license * test(notification-manager): update snapshot * feat(notification-manager): fix animation duration * feat(notification): change animation-duration to 0.4s
- Loading branch information
Showing
13 changed files
with
662 additions
and
4 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,24 @@ | ||
{ | ||
"name": "@alfalab/core-components-notification-manager", | ||
"version": "1.0.0", | ||
"description": "Notification manager", | ||
"keywords": [], | ||
"license": "MIT", | ||
"main": "dist/index.js", | ||
"module": "./dist/modern/index.js", | ||
"files": [ | ||
"dist" | ||
], | ||
"publishConfig": { | ||
"access": "public" | ||
}, | ||
"peerDependencies": { | ||
"react": "^16.9.0 || ^17.0.1" | ||
}, | ||
"dependencies": { | ||
"@alfalab/core-components-notification": "^2.0.8", | ||
"@alfalab/core-components-portal": "^1.4.2", | ||
"classnames": "^2.2.6", | ||
"react-transition-group": "^4.3.0" | ||
} | ||
} |
163 changes: 163 additions & 0 deletions
163
packages/notification-manager/src/__snapshots__/component.test.tsx.snap
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,163 @@ | ||
// Jest Snapshot v1, https://goo.gl/fbAQLP | ||
|
||
exports[`NotificationManager Snapshots tests should match empty snapshot 1`] = ` | ||
<body> | ||
<div /> | ||
<div | ||
alfa-portal-container="" | ||
> | ||
<div | ||
class="component" | ||
/> | ||
</div> | ||
</body> | ||
`; | ||
|
||
exports[`NotificationManager Snapshots tests should match snapshot 1`] = ` | ||
<body> | ||
<div | ||
alfa-portal-container="" | ||
> | ||
<div | ||
class="component" | ||
> | ||
<div> | ||
<div | ||
class="component hasCloser notificationComponent isVisible notification" | ||
id="1" | ||
role="alert" | ||
style="top: 0px;" | ||
> | ||
<div | ||
class="contentWrap" | ||
> | ||
<div | ||
class="toastContent content" | ||
> | ||
<div> | ||
<div | ||
class="title" | ||
> | ||
title | ||
</div> | ||
</div> | ||
</div> | ||
<button | ||
aria-label="закрыть" | ||
class="component ghost m iconOnly closeButton" | ||
type="button" | ||
> | ||
<span | ||
class="addons" | ||
> | ||
<svg | ||
fill="currentColor" | ||
focusable="false" | ||
height="24" | ||
viewBox="0 0 24 24" | ||
width="24" | ||
> | ||
<path | ||
d="M10.586 12L6 16.5 7.5 18l4.5-4.586L16.5 18l1.5-1.5-4.586-4.5L18 7.5 16.5 6 12 10.586 7.5 6 6 7.5l4.586 4.5z" | ||
/> | ||
</svg> | ||
</span> | ||
</button> | ||
</div> | ||
</div> | ||
</div> | ||
<div> | ||
<div | ||
class="component hasCloser notificationComponent isVisible notification" | ||
id="2" | ||
role="alert" | ||
style="top: 0px;" | ||
> | ||
<div | ||
class="contentWrap" | ||
> | ||
<div | ||
class="toastContent content" | ||
> | ||
<div> | ||
<div | ||
class="title" | ||
> | ||
title | ||
</div> | ||
</div> | ||
</div> | ||
<button | ||
aria-label="закрыть" | ||
class="component ghost m iconOnly closeButton" | ||
type="button" | ||
> | ||
<span | ||
class="addons" | ||
> | ||
<svg | ||
fill="currentColor" | ||
focusable="false" | ||
height="24" | ||
viewBox="0 0 24 24" | ||
width="24" | ||
> | ||
<path | ||
d="M10.586 12L6 16.5 7.5 18l4.5-4.586L16.5 18l1.5-1.5-4.586-4.5L18 7.5 16.5 6 12 10.586 7.5 6 6 7.5l4.586 4.5z" | ||
/> | ||
</svg> | ||
</span> | ||
</button> | ||
</div> | ||
</div> | ||
</div> | ||
<div> | ||
<div | ||
class="component hasCloser notificationComponent isVisible notification" | ||
id="3" | ||
role="alert" | ||
style="top: 0px;" | ||
> | ||
<div | ||
class="contentWrap" | ||
> | ||
<div | ||
class="toastContent content" | ||
> | ||
<div> | ||
<div | ||
class="title" | ||
> | ||
title | ||
</div> | ||
</div> | ||
</div> | ||
<button | ||
aria-label="закрыть" | ||
class="component ghost m iconOnly closeButton" | ||
type="button" | ||
> | ||
<span | ||
class="addons" | ||
> | ||
<svg | ||
fill="currentColor" | ||
focusable="false" | ||
height="24" | ||
viewBox="0 0 24 24" | ||
width="24" | ||
> | ||
<path | ||
d="M10.586 12L6 16.5 7.5 18l4.5-4.586L16.5 18l1.5-1.5-4.586-4.5L18 7.5 16.5 6 12 10.586 7.5 6 6 7.5l4.586 4.5z" | ||
/> | ||
</svg> | ||
</span> | ||
</button> | ||
</div> | ||
</div> | ||
</div> | ||
</div> | ||
</div> | ||
<div /> | ||
</body> | ||
`; |
127 changes: 127 additions & 0 deletions
127
packages/notification-manager/src/component.stories.mdx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,127 @@ | ||
import { Meta, Story, Preview, Props } from '@storybook/addon-docs/blocks'; | ||
import { select, text, boolean, number } from '@storybook/addon-knobs'; | ||
import { ComponentHeader } from 'storybook/blocks/component-header'; | ||
import { Button } from '@alfalab/core-components-button'; | ||
import { Notification } from '@alfalab/core-components-notification'; | ||
|
||
import { NotificationManager } from './component'; | ||
import { name, version } from '../package.json'; | ||
|
||
<Meta title='Компоненты' component={NotificationManager} /> | ||
|
||
<!-- Canvas --> | ||
|
||
<Story name='NotificationManager'> | ||
{React.createElement(() => { | ||
const [notifications, setNotifications] = React.useState([]); | ||
const [count, setCount] = React.useState(0); | ||
const addNotification = () => { | ||
const newNotification = ( | ||
<Notification | ||
badge='positive' | ||
title={`Нотификация #${count}`} | ||
autoCloseDelay={3000} | ||
id={count.toString()} | ||
key={count.toString()} | ||
/> | ||
); | ||
notifications.unshift(newNotification); | ||
setNotifications([...notifications]); | ||
setCount(val => val + 1); | ||
}; | ||
const removeNotification = React.useCallback(id => { | ||
/** | ||
* Обратите внимание, что актуальный массив нотификаций | ||
* нужно брать из аргументов функции обновления состояния. | ||
*/ | ||
setNotifications(actualNotifications => | ||
actualNotifications.filter(notification => notification.props.id !== id), | ||
); | ||
}, []); | ||
return ( | ||
<div> | ||
<Button onClick={addNotification}>Добавить нотификацию</Button> | ||
<NotificationManager | ||
notifications={notifications} | ||
onRemoveNotification={removeNotification} | ||
/> | ||
</div> | ||
); | ||
})} | ||
</Story> | ||
|
||
<!-- Docs --> | ||
|
||
<ComponentHeader | ||
name='NotificationManager' | ||
version={version} | ||
package='@alfalab/core-components-notification-manager' | ||
stage={2} | ||
/> | ||
|
||
```tsx | ||
import { NotificationManager } from '@alfalab/core-components-notification-manager'; | ||
``` | ||
|
||
Менеджер нотификаций. | ||
Рендерит массив нотификаций: | ||
|
||
- Располагает нотификации друг под другом, новые нотификации появляются выше старых | ||
- Скрывает/показывает нотификации с анимацией | ||
- В качестве нотификации может быть прокинут любой компонент со схожим API | ||
|
||
**При реализации функции onRemoveNotification, актуальный массив нотификаций следует брать | ||
из аргументов функции обновления состояния:** | ||
|
||
```tsx | ||
const removeNotification = React.useCallback(id => { | ||
/** | ||
* Обратите внимание, что актуальный массив нотификаций | ||
* нужно брать из аргументов функции обновления состояния. | ||
*/ | ||
setNotifications(actualNotifications => | ||
actualNotifications.filter(notification => notification.props.id !== id), | ||
); | ||
}, []); | ||
``` | ||
|
||
<Preview> | ||
{React.createElement(() => { | ||
const [notifications, setNotifications] = React.useState([]); | ||
const [count, setCount] = React.useState(0); | ||
const addNotification = () => { | ||
const newNotification = ( | ||
<Notification | ||
badge='positive' | ||
title={`Нотификация #${count}`} | ||
autoCloseDelay={3000} | ||
id={count.toString()} | ||
key={count.toString()} | ||
/> | ||
); | ||
notifications.unshift(newNotification); | ||
setNotifications([...notifications]); | ||
setCount(val => val + 1); | ||
}; | ||
const removeNotification = React.useCallback(id => { | ||
/** | ||
* Обратите внимание, что актуальный массив нотификаций | ||
* нужно брать из аргументов функции обновления состояния. | ||
*/ | ||
setNotifications(actualNotifications => | ||
actualNotifications.filter(notification => notification.props.id !== id), | ||
); | ||
}, []); | ||
return ( | ||
<div> | ||
<Button onClick={addNotification}>Добавить нотификацию</Button> | ||
<NotificationManager | ||
notifications={notifications} | ||
onRemoveNotification={removeNotification} | ||
/> | ||
</div> | ||
); | ||
})} | ||
</Preview> | ||
|
||
<Props of={NotificationManager} /> |
Oops, something went wrong.