Notifications: Add showcase story, fix types & icon alignment (#1474)

This commit is contained in:
Rafał Cieślak 2023-01-04 10:50:10 +01:00 committed by GitHub
parent a5cbd0a8b7
commit de66460718
3 changed files with 147 additions and 10 deletions

View file

@ -17,7 +17,7 @@ limitations under the License.
import React from 'react';
import styled from 'styled-components';
import { space, color } from 'design/system';
import { space, color, alignSelf } from 'design/system';
import Icon from '../Icon';
@ -95,5 +95,6 @@ const StyledButtonIcon = styled.button`
${size}
${space}
${color}
${alignSelf}
`;
export default ButtonIcon;

View file

@ -16,6 +16,7 @@ limitations under the License.
import React, { useState } from 'react';
import { Info, Warning } from 'design/Icon';
import Flex from 'design/Flex';
import { Notification } from './Notification';
@ -23,15 +24,143 @@ export default {
title: 'Shared/Notification',
};
export const Notifications = () => {
return (
<Flex gap={8}>
<Flex flexDirection="column" gap={4}>
<Notification
item={{
id: crypto.randomUUID(),
severity: 'info',
content: {
title: 'Info with title and description',
description: loremIpsum,
},
}}
Icon={Info}
getColor={theme => theme.colors.info}
onRemove={() => {}}
isAutoRemovable={false}
/>
<Notification
item={{
id: crypto.randomUUID(),
severity: 'warn',
content: {
title: 'Warning with title and description',
description: loremIpsum,
},
}}
Icon={Warning}
getColor={theme => theme.colors.warning}
onRemove={() => {}}
isAutoRemovable={false}
/>
<Notification
item={{
id: crypto.randomUUID(),
severity: 'error',
content: {
title: 'Error with title and description',
description: loremIpsum,
},
}}
Icon={Warning}
getColor={theme => theme.colors.danger}
onRemove={() => {}}
isAutoRemovable={false}
/>
</Flex>
<Flex flexDirection="column" gap={4}>
<Notification
item={{
id: crypto.randomUUID(),
severity: 'info',
content: 'Multiline info without title. ' + loremIpsum,
}}
Icon={Info}
getColor={theme => theme.colors.info}
onRemove={() => {}}
isAutoRemovable={false}
/>
<Notification
item={{
id: crypto.randomUUID(),
severity: 'warn',
content: 'Multiline warning without title. ' + loremIpsum,
}}
Icon={Warning}
getColor={theme => theme.colors.warning}
onRemove={() => {}}
isAutoRemovable={false}
/>
<Notification
item={{
id: crypto.randomUUID(),
severity: 'error',
content: 'Multiline error without title. ' + loremIpsum,
}}
Icon={Warning}
getColor={theme => theme.colors.danger}
onRemove={() => {}}
isAutoRemovable={false}
/>
</Flex>
<Flex flexDirection="column" gap={4}>
<Notification
item={{
id: crypto.randomUUID(),
severity: 'info',
content: 'Info without title',
}}
Icon={Info}
getColor={theme => theme.colors.info}
onRemove={() => {}}
isAutoRemovable={false}
/>
<Notification
item={{
id: crypto.randomUUID(),
severity: 'warn',
content: 'Warning without title',
}}
Icon={Warning}
getColor={theme => theme.colors.warning}
onRemove={() => {}}
isAutoRemovable={false}
/>
<Notification
item={{
id: crypto.randomUUID(),
severity: 'error',
content: 'Error without title',
}}
Icon={Warning}
getColor={theme => theme.colors.danger}
onRemove={() => {}}
isAutoRemovable={false}
/>
</Flex>
</Flex>
);
};
export const AutoRemovable = () => {
const [showInfo, setShowInfo] = useState(true);
const [showWarning, setShowWarning] = useState(true);
const [showError, setShowError] = useState(true);
return (
<>
<Flex flexDirection="column" gap={4}>
{showInfo ? (
<Notification
mt={4}
item={{
id: crypto.randomUUID(),
severity: 'info',
@ -49,7 +178,6 @@ export const AutoRemovable = () => {
)}
{showWarning ? (
<Notification
mt={4}
item={{
id: crypto.randomUUID(),
severity: 'warn',
@ -67,7 +195,6 @@ export const AutoRemovable = () => {
)}
{showError ? (
<Notification
mt={4}
item={{
id: crypto.randomUUID(),
severity: 'error',
@ -82,6 +209,9 @@ export const AutoRemovable = () => {
) : (
<div>Error notification has been removed</div>
)}
</>
</Flex>
);
};
const loremIpsum =
'Lorem ipsum dolor sit amet, consectetur adipiscing elit. Ut non ipsum dignissim, dignissim est vitae, facilisis nunc.';

View file

@ -19,8 +19,6 @@ import styled, { css, useTheme } from 'styled-components';
import { ButtonIcon, Flex, Text } from 'design';
import { Close } from 'design/Icon';
import type { propTypes } from 'design/system';
import type { NotificationItem, NotificationItemContent } from './types';
interface NotificationProps {
@ -30,11 +28,18 @@ interface NotificationProps {
getColor(theme): string;
isAutoRemovable: boolean;
autoRemoveDurationMs?: number;
// Workaround until `styled` gets types.
// Once the types are available, we can switch the type of Notification props to:
//
// NotificationProps & React.ComponentProps<typeof Container>
//
// and remove the next line.
[key: string]: any;
}
const defaultAutoRemoveDurationMs = 10_000; // 10s
export function Notification(props: NotificationProps & propTypes) {
export function Notification(props: NotificationProps) {
const {
item,
onRemove,
@ -73,6 +78,7 @@ export function Notification(props: NotificationProps & propTypes) {
size={0}
ml={1}
mr={-1}
alignSelf="baseline"
style={{ visibility: isHovered ? 'visible' : 'hidden' }}
onClick={e => {
e.stopPropagation();
@ -118,7 +124,7 @@ function getRenderedContent(
if (typeof content === 'string') {
return (
<Flex justifyContent="space-between" width="100%">
<Flex alignItems="center" justifyContent="space-between" width="100%">
<Text
typography="body1"
fontSize={13}