Skip to content

Commit 82e05fa

Browse files
feat: enhance navigation with new badge
1 parent 687f815 commit 82e05fa

File tree

5 files changed

+105
-17
lines changed

5 files changed

+105
-17
lines changed

src/components/nav/DrawerGlobalStyle.ts

+12
Original file line numberDiff line numberDiff line change
@@ -111,6 +111,18 @@ const DrawerGlobalStyle = createGlobalStyle`
111111
font-weight: 500;
112112
}
113113
114+
.menu-item .menu-item__title{
115+
position: relative;
116+
}
117+
118+
.menu-item .menu-item__title .icon-wrapper{
119+
position: absolute;
120+
top: -6px;
121+
right: -4px;
122+
width: 8px;
123+
height: 8px;
124+
}
125+
114126
.drawer-menu .menu-item:hover {
115127
background: #efefef;
116128
}

src/components/nav/DrawerNav.tsx

+43-10
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,17 @@ const SubLink = styled(Link)`
1919
}
2020
`
2121

22+
const Badge = styled.p`
23+
padding: 1px 5px;
24+
font-weight: 600;
25+
font-size: 12px;
26+
line-height: 16px;
27+
background-color: #d5ea48;
28+
border-radius: 9999px;
29+
display: inline;
30+
margin-left: 8px;
31+
`
32+
2233
const DrawerNav = ({ isDrawerOpen }: Props) => {
2334
return (
2435
<div className={'drawer-menu pull-left ' + (isDrawerOpen ? 'open' : '')}>
@@ -39,22 +50,44 @@ const DrawerNav = ({ isDrawerOpen }: Props) => {
3950
</div>
4051

4152
<div className="menu-item-wrapper menu-item-wrapper--expandable" onClick={(e) => toggleMenu(e)}>
42-
<span className="menu-item menu-item--with-icon">
43-
<span className="title">Solutions</span>
53+
<div className="menu-item menu-item--with-icon">
54+
<div className="menu-item__title">
55+
<span className="title">Solutions</span>
56+
<div className="icon-wrapper">
57+
<svg width="10" height="10" viewBox="0 0 10 10">
58+
<g transform="translate(-502 -16)" stroke="#AABB39" fill="none" fill-rule="evenodd">
59+
<circle stroke-opacity=".5" stroke-width="2" fill="#D5EA48" cx="507" cy="21" r="4"></circle>
60+
<circle cx="507" cy="21" r="3.5"></circle>
61+
</g>
62+
</svg>
63+
</div>
64+
</div>
65+
4466
<span className="icon">
4567
<Chevron />
4668
</span>
47-
</span>
69+
</div>
4870
<div className="sub-menu">
49-
<SubLink href="https://traefik.io/solutions/kubernetes-ingress/">Kubernetes Ingress</SubLink>
50-
<SubLink href="https://traefik.io/solutions/docker-swarm-ingress/">Docker Swarm Ingress</SubLink>
71+
<SubLink href="https://traefik.io/solutions/ai-gateway/">
72+
AI Gateway
73+
<Badge>New!</Badge>
74+
</SubLink>
5175
<SubLink href="https://traefik.io/solutions/api-gateway/">Modern API Gateway</SubLink>
52-
<SubLink href="https://traefik.io/solutions/waf/">Web Application Firewall</SubLink>
53-
<SubLink href="https://traefik.io/solutions/hashicorp-and-traefik/">Traefik & HashiCrop</SubLink>
54-
<SubLink href="https://traefik.io/solutions/ai-gateway/">AI Gateway</SubLink>
76+
<SubLink href="https://traefik.io/solutions/api-mocking/">
77+
API Mocking <Badge>New!</Badge>
78+
</SubLink>
5579
<SubLink href="https://traefik.io/solutions/api-management/">GitOps-Driven API Management</SubLink>
56-
<SubLink href="https://traefik.io/solutions/api-governance/">Runtime API Governance</SubLink>
57-
<SubLink href="https://traefik.io/solutions/api-mocking/">API Mocking</SubLink>
80+
<SubLink href="https://traefik.io/solutions/waf/">
81+
Web Application Firewall <Badge>New!</Badge>
82+
</SubLink>
83+
<SubLink href="https://traefik.io/solutions/api-governance/">
84+
Runtime API Governance <Badge>New!</Badge>
85+
</SubLink>
86+
<SubLink href="https://traefik.io/solutions/kubernetes-ingress/">Kubernetes Ingress</SubLink>
87+
<SubLink href="https://traefik.io/solutions/docker-swarm-ingress/">Docker Swarm Ingress</SubLink>
88+
<SubLink href="https://traefik.io/solutions/hashicorp-and-traefik/">
89+
Traefik & HashiCrop <Badge>New!</Badge>
90+
</SubLink>
5891
</div>
5992
</div>
6093

src/components/nav/MainNav.tsx

+10-5
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ import { ReactComponent as EnterpriseIcon } from '../../images/menu_icons_traefi
2929
import { ReactComponent as HubIcon } from '../../images/menu_icons_traefik_hub.svg'
3030
import { ReactComponent as WafIcon } from '../../images/menu_icons_waf.svg'
3131
import { ReactComponent as HashicorpIcon } from '../../images/menu_icons_hashicorp.svg'
32-
import { ReactComponent as AIGatewayIcon } from '../../images/menu_icons_ai_gateway.svg'
32+
import { ReactComponent as AiGatewayIcon } from '../../images/menu_icons_ai_gateway.svg'
3333
import PostCard from './PostCard'
3434

3535
const Wrapper = styled(Flex)`
@@ -105,7 +105,7 @@ const MainNav = () => {
105105
</NavItem>
106106

107107
{/* Solutions */}
108-
<NavItem name="Solutions" hasSubmenu position={{ marginLeft: '-25%' }}>
108+
<NavItem name="Solutions" hasSubmenu position={{ marginLeft: '-25%' }} heighlight={true}>
109109
<Grid
110110
sx={{
111111
display: 'grid',
@@ -148,20 +148,23 @@ const MainNav = () => {
148148
external: true,
149149
description: 'Protect your APIs from threats with speed and efficiency',
150150
icon: <WafIcon />,
151+
badge: 'New!',
151152
},
152153
{
153154
title: 'Traefik & HashiCorp',
154155
url: 'https://traefik.io/solutions/hashicorp-and-traefik/',
155156
external: true,
156157
description: 'A comprehensive and powerful API Gateway for HashiCorp stack.',
157158
icon: <HashicorpIcon />,
159+
badge: 'New!',
158160
},
159161
{
160162
title: 'AI Gateway',
161163
url: 'https://traefik.io/solutions/ai-gateway/',
162164
external: true,
163-
description: 'Tranform Traefik into a flexible egress AI proxy & egress AI gateway.',
164-
icon: <AIGatewayIcon />,
165+
description: 'Transform Traefik into a flexible egress gateway.',
166+
icon: <AiGatewayIcon />,
167+
badge: 'New!',
165168
},
166169
]}
167170
bgImage={'https://traefik.io/images/site-nav/[email protected]'}
@@ -182,13 +185,15 @@ const MainNav = () => {
182185
external: true,
183186
description: 'Enforce critical runtime API policies for secure, reliable, and compliant API management.',
184187
icon: <ApiGovernanceIcon />,
188+
badge: 'New!',
185189
},
186190
{
187191
title: 'API Mocking',
188192
url: 'https://traefik.io/solutions/api-mocking/',
189193
external: true,
190194
description: 'Create, publish, and consume mock APIs with production-like UX and SLAs.',
191-
icon: <ApiMockingIcon/>,
195+
icon: <ApiMockingIcon />,
196+
badge: 'New!',
192197
},
193198
]}
194199
bgImage={'https://traefik.io/images/site-nav/[email protected]'}

src/components/nav/NavItem.tsx

+28-2
Original file line numberDiff line numberDiff line change
@@ -10,14 +10,27 @@ type NavItemProps = SpaceProps & {
1010
url?: string
1111
position?: React.CSSProperties
1212
children?: React.ReactNode
13+
heighlight?: boolean
1314
}
1415

15-
const NavItem = ({ name, hasSubmenu, url, children, position, ...props }: NavItemProps) => {
16+
const NavItem = ({ name, hasSubmenu, url, children, position, heighlight, ...props }: NavItemProps) => {
1617
if (hasSubmenu) {
1718
return (
1819
<Wrapper {...props}>
1920
<Title aria-haspopup="menu" aria-expanded={false}>
20-
<Text sx={{ fontSize: '14.5px', lineHeight: '14.5px', fontWeight: '500' }}>{name}</Text>
21+
<TitleWrapper>
22+
<Text sx={{ fontSize: '14.5px', lineHeight: '14.5px', fontWeight: '500' }}>{name}</Text>
23+
{heighlight && (
24+
<IconDot>
25+
<svg width="10" height="10" viewBox="0 0 10 10">
26+
<g transform="translate(-502 -16)" stroke="#AABB39" fill="none" fill-rule="evenodd">
27+
<circle stroke-opacity=".5" stroke-width="2" fill="#D5EA48" cx="507" cy="21" r="4"></circle>
28+
<circle cx="507" cy="21" r="3.5"></circle>
29+
</g>
30+
</svg>
31+
</IconDot>
32+
)}
33+
</TitleWrapper>
2134
<Box
2235
as="span"
2336
sx={{
@@ -48,6 +61,19 @@ const NavItem = ({ name, hasSubmenu, url, children, position, ...props }: NavIte
4861
)
4962
}
5063

64+
const TitleWrapper = styled.div`
65+
position: relative;
66+
`
67+
68+
const IconDot = styled.div`
69+
position: absolute;
70+
top: -6px;
71+
right: -5px;
72+
width: 8px;
73+
height: 8px;
74+
}
75+
`
76+
5177
const Title = styled.button`
5278
color: ${theme.colors.dark};
5379
background: none;

src/components/nav/Product.tsx

+12
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ type NavProductProps = {
1414
tagColor?: string
1515
tag?: string
1616
external: boolean
17+
badge?: string
1718
}[]
1819
bgImage: string
1920
}
@@ -67,6 +68,7 @@ const Product = ({ bgImage, title, description, links }: NavProductProps) => (
6768
<NavLinkTitle>
6869
<span>{link.title}</span>
6970
{link.tag && <NavLinkTag tagColor={link.tagColor}>{link.tag}</NavLinkTag>}
71+
{link.badge && <NavLinkBadge>{link.badge}</NavLinkBadge>}
7072
</NavLinkTitle>
7173
<NavLinkDescription>{link.description}</NavLinkDescription>
7274
</div>
@@ -130,6 +132,16 @@ const NavLinkIcon = styled.div`
130132
border-radius: 6px;
131133
`
132134

135+
const NavLinkBadge = styled.p`
136+
font-size: 12px;
137+
font-weight: 600;
138+
color: rgb(10, 25, 46);
139+
background-color: rgb(213, 234, 72);
140+
padding: 1px 5px;
141+
border-radius: 20px;
142+
margin: 0 0 0 8px;
143+
`
144+
133145
const NavLinkTitle = styled.div`
134146
display: flex;
135147
gap: 2px;

0 commit comments

Comments
 (0)