Skip to content

Commit 07f90b1

Browse files
authored
feat(HTD-8): adds badge (#9)
- fix styles
1 parent 1fc00c1 commit 07f90b1

File tree

5 files changed

+113
-2
lines changed

5 files changed

+113
-2
lines changed

src/app/page.tsx

+9
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,6 @@
1+
import { Sparkle } from '@phosphor-icons/react/dist/ssr';
2+
3+
import { Badge } from '@/components/elements/badge';
14
import { Container } from '@/components/elements/container';
25
import { Heading } from '@/components/elements/heading';
36
import ShowCase from '@/components/elements/showcase';
@@ -75,6 +78,12 @@ export default async function Home() {
7578
Label M
7679
</Text>
7780
</ShowCase>
81+
<ShowCase title="Badge">
82+
<Badge icon={Sparkle}>Intercept</Badge>
83+
<Badge icon={Sparkle} variant="secondary" additionalText="Edit">
84+
Pro Feature
85+
</Badge>
86+
</ShowCase>
7887
<ShowCase title="Theme toggle">
7988
<ThemeToggle />
8089
</ShowCase>
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
'use client';
2+
3+
import type { BadgeProps } from './badge.types';
4+
5+
import { css, styled } from '@/styles';
6+
7+
export const BadgeWrapper = styled.div`
8+
display: flex;
9+
align-items: center;
10+
width: fit-content;
11+
gap: 16px;
12+
`;
13+
14+
export const AdditionalText = styled.span`
15+
color: ${({ theme }) => theme.colors.lightGrey};
16+
font-size: ${({ theme }) => theme.fontSizes.label.l};
17+
font-weight: ${({ theme }) => theme.fontWeight.bold};
18+
letter-spacing: ${({ theme }) => theme.letterSpacing.label};
19+
text-transform: uppercase;
20+
`;
21+
22+
export const StyledBadge = styled.span<BadgeProps>`
23+
display: flex;
24+
align-items: center;
25+
26+
gap: 6px;
27+
28+
font-size: ${({ theme }) => theme.fontSizes.label.m};
29+
font-weight: ${({ theme }) => theme.fontWeight.bold};
30+
line-height: ${({ theme }) => theme.lineHeight.label};
31+
letter-spacing: ${({ theme }) => theme.letterSpacing.label};
32+
text-transform: uppercase;
33+
34+
${({ variant }) => {
35+
switch (variant) {
36+
case 'primary':
37+
return css`
38+
border-radius: 16px;
39+
padding: 6px 10px;
40+
color: ${({ theme }) => theme.colors.text.lightGrey};
41+
background-color: ${({ theme }) => theme.colors.mediumGrey};
42+
box-shadow: 0 0 0 1px ${({ theme }) => theme.colors.borderGradient};
43+
`;
44+
45+
case 'secondary':
46+
return css`
47+
border-radius: 24px;
48+
padding: 8px 12px;
49+
color: ${({ theme }) => theme.colors.text.alwayLightGrey};
50+
background: ${({ theme }) => theme.colors.blueGradient};
51+
box-shadow:
52+
0px 1.66px 0.83px 0px rgba(201, 212, 251, 0.1) inset,
53+
0px -0.83px 0.83px 0px rgba(16, 46, 151, 0.1) inset;
54+
`;
55+
}
56+
}}
57+
`;
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
import type { Icon, IconWeight } from '@phosphor-icons/react';
2+
3+
export interface BadgeProps {
4+
variant?: 'primary' | 'secondary';
5+
icon?: Icon;
6+
iconWeight?: IconWeight;
7+
additionalText?: string;
8+
}
+22
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
import { AdditionalText, BadgeWrapper, StyledBadge } from './badge.styles';
2+
import type { BadgeProps } from './badge.types';
3+
4+
export const Badge = ({
5+
children,
6+
variant = 'primary',
7+
additionalText,
8+
icon: Icon,
9+
iconWeight = 'fill',
10+
}: Component<BadgeProps>) => {
11+
const hasAdditionalText = variant === 'secondary' && additionalText;
12+
13+
return (
14+
<BadgeWrapper>
15+
{hasAdditionalText && <AdditionalText>{additionalText}</AdditionalText>}
16+
<StyledBadge variant={variant}>
17+
{Icon && <Icon size={16} weight={iconWeight} />}
18+
<h3>{children}</h3>
19+
</StyledBadge>
20+
</BadgeWrapper>
21+
);
22+
};

src/styles/index.ts

+17-2
Original file line numberDiff line numberDiff line change
@@ -82,6 +82,21 @@ export const theme = {
8282
m: '1rem', // 16px / 16px = 1rem
8383
s: '0.875rem', // 14px / 16px = 0.875
8484
},
85+
button: {
86+
default: '1.125rem', // 18px / 16px = 1.125.5rem
87+
small: '1rem', // 16px / 16px = 1rem
88+
},
89+
label: {
90+
xl: '1.5rem', // 24px / 16px = 1.5rem
91+
l: '1rem', // 16px / 16px = 1rem
92+
m: '0.875rem', // 14px / 16px = 0.875
93+
},
94+
},
95+
lineHeight: {
96+
label: '110%',
97+
},
98+
letterSpacing: {
99+
label: '0.06em',
85100
},
86101
space: {
87102
xs: '4px',
@@ -109,7 +124,7 @@ export const GlobalStyles = createGlobalStyle`
109124
--orange-gradient: linear-gradient(to bottom, #D93815, #F65430);
110125
--blue-gradient: linear-gradient(to bottom, #4064E2, #3556CA);
111126
--dark-gradient: linear-gradient(to bottom, #1E2028, #30333E 70%);
112-
--border-gradient: linear-gradient(to bottom, rgba(103, 108, 129, 0.2), rgba(93, 97, 112, 0.04));
127+
--border-gradient: rgba(255, 255, 255, 0.2);
113128
--text-light-grey: #E6E8F2;
114129
--text-dark-grey: #C5C6CA;
115130
--text-cinnabar-red: #EC502D;
@@ -133,7 +148,7 @@ export const GlobalStyles = createGlobalStyle`
133148
--orange-gradient: linear-gradient(to bottom, #F65430, #D93815);
134149
--blue-gradient: linear-gradient(to bottom, #3556CA, #4064E2);
135150
--dark-gradient: linear-gradient(to bottom, #30333E, #1E2028 70%);
136-
--border-gradient: linear-gradient(to bottom, rgba(255, 255, 255, 0.12), rgba(255, 255, 255, 0.04));
151+
--border-gradient: transparent;
137152
--text-light-grey: #16181E;
138153
--text-dark-grey: #595D68;
139154
--text-cinnabar-red: #D93E1C;

0 commit comments

Comments
 (0)