-
Notifications
You must be signed in to change notification settings - Fork 2
/
Copy pathAlert.tsx
88 lines (78 loc) · 2.32 KB
/
Alert.tsx
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
import { Close } from '@carbon/icons-react';
import styled from '@emotion/styled';
import { alert } from '@tablecheck/tablekit-core';
import * as React from 'react';
import { getConfigDefault, getSentimentIcon } from '../config';
export type Props = alert.Props;
export const AlertCore = styled.div<Props>`
${alert.fullStyles}
`;
export const AlertTitle = styled.h5`
grid-area: title;
`;
export const AlertDescription = styled.div`
grid-area: description;
font: var(--body-2);
`;
export const AlertCloseButton = styled.button`
grid-area: close;
color: currentColor;
cursor: pointer;
`;
export const AlertIconWrapper = React.forwardRef<
HTMLSpanElement,
React.HTMLAttributes<HTMLSpanElement>
>((props, ref) => (
<span
{...props}
ref={ref}
style={{ ...(props.style || {}), gridArea: 'icon' }}
className={`${props.className || ''} alert-icon`}
/>
));
interface ComposedProps extends Omit<Props, 'data-layout' | 'children'> {
/**
* Icon to display in the alert. Pass `null` to hide the icon.
*/
icon?: React.ReactNode;
title?: React.ReactNode;
children: React.ReactNode;
onClose?: VoidFunction;
/**
* @deprecated if you need to manually set the layout, use the `AlertCore` component instead
*/
'data-layout'?: never;
}
function getLayout(props: ComposedProps): Props['data-layout'] {
const checks = [
[props.icon !== null, 'icon'],
[props.title, 'title'],
[props.onClose, 'close']
].filter((check) => check[0]);
if (checks.length === 0) {
return 'text-only';
}
return checks.map((check) => check[1]).join('-') as Props['data-layout'];
}
export const Alert = React.forwardRef<
HTMLDivElement,
ComposedProps & React.HTMLAttributes<HTMLDivElement>
>((props, ref) => {
const { icon, title, children, onClose, ...passthrough } = props;
return (
<AlertCore {...passthrough} data-layout={getLayout(props)} ref={ref}>
{icon !== null ? (
<AlertIconWrapper>
{icon ?? getSentimentIcon(passthrough['data-variant'])}
</AlertIconWrapper>
) : null}
{title ? <AlertTitle>{title}</AlertTitle> : null}
<AlertDescription>{children}</AlertDescription>
{onClose ? (
<AlertCloseButton onClick={onClose}>
<Close size={getConfigDefault('iconSize')} />
</AlertCloseButton>
) : null}
</AlertCore>
);
});