Skip to content

Commit e9ce762

Browse files
committed
feat: add component badge
1 parent 7dfc0d7 commit e9ce762

File tree

9 files changed

+259
-2
lines changed

9 files changed

+259
-2
lines changed

packages/ui-variants/src/index.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ export * from './shared';
22

33
export * from './types';
44

5+
export * from './variants/badge';
56
export * from './variants/button';
67
export * from './variants/button-group';
78
export * from './variants/card';
Lines changed: 132 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,132 @@
1+
import { tv } from 'tailwind-variants';
2+
import type { VariantProps } from 'tailwind-variants';
3+
4+
export const badgeVariants = tv({
5+
base: 'inline-flex items-center border font-semibold',
6+
variants: {
7+
color: {
8+
primary: 'border-primary text-primary',
9+
destructive: 'border-destructive text-destructive',
10+
success: 'border-success text-success',
11+
warning: 'border-warning text-warning',
12+
info: 'border-info text-info',
13+
carbon: 'border-carbon text-carbon',
14+
secondary: 'border-secondary-foreground/50 text-secondary-foreground',
15+
accent: 'border-accent-foreground/50 text-accent-foreground'
16+
},
17+
variant: {
18+
solid: '',
19+
pure: 'bg-background text-foreground border-border',
20+
outline: 'bg-background',
21+
soft: 'border-0',
22+
ghost: '',
23+
raw: 'bg-transparent border-0'
24+
},
25+
size: {
26+
xs: 'gap-0.5 h-3.5 px-1 text-4xs',
27+
sm: 'gap-0.75 h-4 px-1.5 text-3xs',
28+
md: 'gap-1 h-4.5 px-2 text-2xs',
29+
lg: 'gap-1.25 h-5 px-2.5 text-xs',
30+
xl: 'gap-1.5 h-6 px-3 text-sm',
31+
'2xl': 'gap-2 h-7 px-4 text-base'
32+
},
33+
shape: {
34+
auto: 'rounded-md',
35+
rounded: 'rounded-full'
36+
}
37+
},
38+
compoundVariants: [
39+
{
40+
color: 'primary',
41+
variant: 'solid',
42+
class: `bg-primary text-primary-foreground`
43+
},
44+
{
45+
color: 'destructive',
46+
variant: 'solid',
47+
class: `bg-destructive text-destructive-foreground`
48+
},
49+
{
50+
color: 'success',
51+
variant: 'solid',
52+
class: `bg-success text-success-foreground`
53+
},
54+
{
55+
color: 'warning',
56+
variant: 'solid',
57+
class: `bg-warning text-warning-foreground`
58+
},
59+
{
60+
color: 'info',
61+
variant: 'solid',
62+
class: `bg-info text-info-foreground`
63+
},
64+
{
65+
color: 'carbon',
66+
variant: 'solid',
67+
class: `bg-carbon text-carbon-foreground`
68+
},
69+
{
70+
color: 'secondary',
71+
variant: 'solid',
72+
class: `bg-secondary text-secondary-foreground`
73+
},
74+
{
75+
color: 'accent',
76+
variant: 'solid',
77+
class: `bg-accent text-accent-foreground`
78+
},
79+
{
80+
color: 'primary',
81+
variant: ['soft', 'ghost'],
82+
class: 'bg-primary/10'
83+
},
84+
{
85+
color: 'destructive',
86+
variant: ['soft', 'ghost'],
87+
class: 'bg-destructive/10'
88+
},
89+
{
90+
color: 'success',
91+
variant: ['soft', 'ghost'],
92+
class: 'bg-success/10'
93+
},
94+
{
95+
color: 'warning',
96+
variant: ['soft', 'ghost'],
97+
class: 'bg-warning/10'
98+
},
99+
{
100+
color: 'info',
101+
variant: ['soft', 'ghost'],
102+
class: 'bg-info/10'
103+
},
104+
{
105+
color: 'carbon',
106+
variant: ['soft', 'ghost'],
107+
class: 'bg-carbon/10'
108+
},
109+
{
110+
color: 'secondary',
111+
variant: ['soft', 'ghost'],
112+
class: 'bg-secondary-foreground/5'
113+
},
114+
{
115+
color: 'accent',
116+
variant: ['soft', 'ghost'],
117+
class: 'bg-accent-foreground/5'
118+
}
119+
],
120+
defaultVariants: {
121+
color: 'primary',
122+
variant: 'solid',
123+
size: 'md',
124+
shape: 'auto'
125+
}
126+
});
127+
128+
type BadgeVariants = VariantProps<typeof badgeVariants>;
129+
130+
export type BadgeVariant = NonNullable<BadgeVariants['variant']>;
131+
132+
export type BadgeShape = NonNullable<BadgeVariants['shape']>;
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
export { default as Badge } from './source/Badge';
2+
3+
export * from './types';
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
import { badgeVariants, cn } from '@soybean-react-ui/variants';
2+
3+
import type { BadgeProps } from '../types';
4+
5+
const Badge = (props: BadgeProps) => {
6+
const { className, color, shape, size, variant, ...rest } = props;
7+
8+
const mergedCls = cn(badgeVariants({ color, shape, size, variant }), className);
9+
10+
return (
11+
<div
12+
{...rest}
13+
className={mergedCls}
14+
/>
15+
);
16+
};
17+
18+
export default Badge;
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
import type { BadgeShape, BadgeVariant, ThemeColor } from '@soybean-react-ui/variants';
2+
3+
import type { BaseNodeProps } from '../../types/other';
4+
5+
export interface BadgeProps extends BaseNodeProps<React.ComponentProps<'div'>> {
6+
/** The color of the badge. */
7+
color?: ThemeColor;
8+
/** The shape of the badge. */
9+
shape?: BadgeShape;
10+
/** The variant of the badge. */
11+
variant?: BadgeVariant;
12+
}
13+
14+
export type { BadgeShape, BadgeVariant };

packages/ui/src/index.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
export * from './components/badge';
2+
13
export * from './components/button';
24

35
export * from './components/card';
Lines changed: 88 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,88 @@
1+
import { Badge, type BadgeShape, type BadgeVariant, Card, type ThemeColor, type ThemeSize } from 'soybean-react-ui';
2+
3+
const colors: ThemeColor[] = ['primary', 'destructive', 'success', 'warning', 'info', 'carbon', 'secondary', 'accent'];
4+
const variants: BadgeVariant[] = ['solid', 'pure', 'outline', 'soft', 'ghost', 'raw'];
5+
const sizes: ThemeSize[] = ['xs', 'sm', 'md', 'lg', 'xl', '2xl'];
6+
const shapes: BadgeShape[] = ['auto', 'rounded'];
7+
8+
const BadgeDemo = () => {
9+
return (
10+
<div className="flex-c gap-4">
11+
<Card
12+
split
13+
title="Color"
14+
>
15+
<div className="flex flex-wrap gap-[12px]">
16+
{colors.map(color => (
17+
<Badge
18+
color={color}
19+
key={color}
20+
>
21+
{color}
22+
</Badge>
23+
))}
24+
</div>
25+
</Card>
26+
27+
<Card
28+
split
29+
title="Variant"
30+
>
31+
<div className="flex-c-stretch gap-[12px]">
32+
{colors.map(color => (
33+
<div
34+
className="flex flex-wrap gap-[12px]"
35+
key={color}
36+
>
37+
{variants.map(variant => (
38+
<Badge
39+
color={color}
40+
key={variant}
41+
variant={variant}
42+
>
43+
{variant}
44+
</Badge>
45+
))}
46+
</div>
47+
))}
48+
</div>
49+
</Card>
50+
51+
<Card
52+
split
53+
title="Size"
54+
>
55+
<div className="flex flex-wrap gap-[12px]">
56+
{sizes.map(size => (
57+
<Badge
58+
key={size}
59+
size={size}
60+
variant="soft"
61+
>
62+
{size}
63+
</Badge>
64+
))}
65+
</div>
66+
</Card>
67+
68+
<Card
69+
split
70+
title="Shape"
71+
>
72+
<div className="flex flex-wrap gap-[12px]">
73+
{shapes.map(shape => (
74+
<Badge
75+
key={shape}
76+
shape={shape}
77+
variant="ghost"
78+
>
79+
{shape}
80+
</Badge>
81+
))}
82+
</div>
83+
</Card>
84+
</div>
85+
);
86+
};
87+
88+
export default BadgeDemo;

playground/src/app/(demo)/card/page.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ const DemoCard: React.FC = () => {
1616
split
1717
title="Size"
1818
>
19-
<div className="w-1/2 i-flex-c pr-10px lt-sm:w-full lt-sm:pr-0">
19+
<div className="w-1/2 i-flex-c pr-[10px] lt-sm:w-full lt-sm:pr-0">
2020
{sizes.map(size => (
2121
<Card
2222
className="mb-12px"

pnpm-workspace.yaml

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,4 +2,3 @@ packages:
22
- "apps/*"
33
- "packages/*"
44
- "playground"
5-
- "primitives/*"

0 commit comments

Comments
 (0)