-
Notifications
You must be signed in to change notification settings - Fork 40
/
Copy pathBadge.tsx
96 lines (93 loc) · 2.18 KB
/
Badge.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
89
90
91
92
93
94
95
96
import cl from 'clsx/lite';
import { type HTMLAttributes, type ReactNode, forwardRef } from 'react';
import { Paragraph, type ParagraphProps } from '../Typography';
export type BadgeProps = {
/**
* The color of the badge
*
* @default accent
*/
color?: 'accent' | 'info' | 'success' | 'warning' | 'danger' | 'neutral';
/**
* The size of the badge
*
* @default md
*/
size?: 'sm' | 'md' | 'lg';
/**
* The number to display in the badge
*/
count?: number;
/**
* The maximum number to display in the badge, when the count exceeds this number, the badge will display `{max}+`
*/
maxCount?: number;
/**
* The placement of the badge
*
* @default top-right
*/
placement?: 'top-right' | 'top-left' | 'bottom-right' | 'bottom-left';
/**
* Use when badge is floating to change the position of the badge
*
* @default rectangle
*/
overlap?: 'circle' | 'rectangle';
/**
* The badge will float on top of the children
*/
children?: ReactNode;
} & HTMLAttributes<HTMLSpanElement>;
const paragraphSizeMap: {
[key in NonNullable<BadgeProps['size']>]: NonNullable<ParagraphProps['size']>;
} = {
sm: 'xs',
md: 'sm',
lg: 'md',
};
/**
* `Badge` is a non-interactive component for displaying status with or without numbers.
*
* @example without children
* ```jsx
* <Badge color='accent' size='md' count={5} />
* ```
*
* @example with children
* ```jsx
* <Badge color='accent' size='md'>
* <Icon />
* </Badge>
* ```
*/
export const Badge = forwardRef<HTMLSpanElement, BadgeProps>(function Badge(
{
className,
color = 'accent',
count,
maxCount,
overlap = 'rectangle',
placement = 'top-right',
size = 'md',
...rest
},
ref,
) {
return (
<Paragraph asChild variant='short' size={paragraphSizeMap[size]}>
<span
className={cl('ds-badge', className)}
data-color={color}
data-count={
count && maxCount && count > maxCount ? `${maxCount}+` : count
}
data-overlap={rest.children ? overlap : null}
data-placement={rest.children ? placement : null}
data-size={size}
ref={ref}
{...rest}
/>
</Paragraph>
);
});