Skip to content

Commit 1be107e

Browse files
committed
refactor: navigation vanilla extract
1 parent 2eea0ad commit 1be107e

File tree

16 files changed

+1046
-6615
lines changed

16 files changed

+1046
-6615
lines changed

.changeset/all-mugs-hammer.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
"@ultraviolet/plus": minor
3+
---
4+
5+
Refaactor component `Navigation` to use vanilla-extract instead of Emotion

packages/plus/src/components/Navigation/Footer.tsx

Lines changed: 5 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -1,31 +1,13 @@
11
'use client'
22

3-
import styled from '@emotion/styled'
43
import { ArrowLeftDoubleIcon, ArrowRightDoubleIcon } from '@ultraviolet/icons'
54
import { Button, Tooltip } from '@ultraviolet/ui'
65
import type { RefObject } from 'react'
76
import { useCallback, useEffect, useMemo, useState } from 'react'
8-
import { ANIMATION_DURATION } from './constants'
97
import { useNavigation } from './NavigationProvider'
8+
import { navigationStickyFooter } from './styles.css'
109
import type { NavigationProps } from './types'
1110

12-
const StickyFooter = styled.div`
13-
display: flex;
14-
width: 100%;
15-
background: ${({ theme }) => theme.colors.neutral.background};
16-
border-top: 1px solid ${({ theme }) => theme.colors.neutral.borderWeak};
17-
padding: ${({ theme }) => `${theme.space['1']} ${theme.space['2']}`};
18-
transition: justify-content ${ANIMATION_DURATION}ms ease-in-out;
19-
box-shadow: ${({ theme }) => theme.shadows.defaultShadow};
20-
transition: box-shadow 230ms ease-in-out;
21-
justify-content: flex-end;
22-
23-
&[data-has-overflow-style="false"] {
24-
box-shadow: none;
25-
border: none;
26-
}
27-
`
28-
2911
type FooterProps = {
3012
onToggleExpand: NavigationProps['onToggleExpand']
3113
contentRef: RefObject<HTMLDivElement | null>
@@ -93,7 +75,9 @@ export const Footer = ({ onToggleExpand, contentRef }: FooterProps) => {
9375
)
9476

9577
return (
96-
<StickyFooter data-has-overflow-style={footerHasOverflowStyle}>
78+
<div
79+
className={navigationStickyFooter({ overflow: footerHasOverflowStyle })}
80+
>
9781
<Tooltip placement="right" text={label}>
9882
<Button
9983
aria-label={label}
@@ -108,6 +92,6 @@ export const Footer = ({ onToggleExpand, contentRef }: FooterProps) => {
10892
<Icon />
10993
</Button>
11094
</Tooltip>
111-
</StickyFooter>
95+
</div>
11296
)
11397
}
Lines changed: 6 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1,23 +1,11 @@
11
'use client'
22

3-
import styled from '@emotion/styled'
43
import { Stack } from '@ultraviolet/ui'
54
import { memo } from 'react'
65
import { useNavigation } from './NavigationProvider'
6+
import { navigationHeader, navigationLogoContainer } from './styles.css'
77
import type { NavigationProps } from './types'
88

9-
const HeaderContainer = styled.div`
10-
background: ${({ theme }) => theme.colors.neutral.background};
11-
`
12-
13-
const LogoContainer = styled(Stack)`
14-
margin: ${({ theme }) =>
15-
`${theme.space['3']} ${theme.space['3']} ${theme.space['2']} ${theme.space['3']}`};
16-
max-width: 220px;
17-
height: 22px;
18-
overflow: hidden;
19-
`
20-
219
type HeaderProps = {
2210
logo: NavigationProps['logo']
2311
}
@@ -26,13 +14,14 @@ export const Header = memo(({ logo }: HeaderProps) => {
2614
const { animation, expanded } = useNavigation()
2715

2816
return (
29-
<HeaderContainer>
30-
<LogoContainer
17+
<div className={navigationHeader}>
18+
<Stack
3119
alignItems="start"
20+
className={navigationLogoContainer}
3221
justifyContent={!expanded ? 'center' : undefined}
3322
>
3423
{typeof logo === 'function' ? logo(animation ? false : expanded) : logo}
35-
</LogoContainer>
36-
</HeaderContainer>
24+
</Stack>
25+
</div>
3726
)
3827
})

packages/plus/src/components/Navigation/NavigationContent.tsx

Lines changed: 37 additions & 101 deletions
Original file line numberDiff line numberDiff line change
@@ -1,95 +1,22 @@
11
'use client'
22

3-
import styled from '@emotion/styled'
43
import { Stack } from '@ultraviolet/ui'
4+
import { assignInlineVars } from '@vanilla-extract/dynamic'
55
import { useEffect, useRef } from 'react'
6-
import {
7-
ANIMATION_DURATION,
8-
NAVIGATION_COLLASPED_WIDTH,
9-
NAVIGATION_MAX_WIDTH,
10-
NAVIGATION_MIN_WIDTH,
11-
} from './constants'
6+
import { NAVIGATION_COLLASPED_WIDTH, NAVIGATION_MIN_WIDTH } from './constants'
127
import { Footer } from './Footer'
138
import { Header } from './Header'
149
import { useNavigation } from './NavigationProvider'
10+
import {
11+
navigation,
12+
navigationContainer,
13+
navigationContent,
14+
navigationContentContainer,
15+
navigationContentContainerCollapsed,
16+
navigationSlider,
17+
} from './styles.css'
1518
import type { NavigationProps } from './types'
16-
17-
const StyledNav = styled.nav`
18-
display: flex;
19-
flex-direction: row;
20-
position: relative;
21-
border-right: 1px solid ${({ theme }) => theme.colors.neutral.borderWeak};
22-
`
23-
24-
const Container = styled('div', {
25-
shouldForwardProp: prop => !['width'].includes(prop),
26-
})<{
27-
width: number
28-
}>`
29-
background: ${({ theme }) => theme.colors.neutral.background};
30-
display: flex;
31-
flex-direction: column;
32-
33-
width: ${({ width }) => width}px;
34-
35-
&[data-expanded="true"][data-animation="false"] {
36-
max-width: ${NAVIGATION_MAX_WIDTH}px;
37-
min-width: ${NAVIGATION_MIN_WIDTH}px;
38-
}
39-
40-
&[data-expanded="false"] {
41-
width: ${NAVIGATION_COLLASPED_WIDTH}px;
42-
}
43-
44-
&[data-animation="expand"] {
45-
transition: width ${ANIMATION_DURATION}ms ease-in-out;
46-
width: ${({ width }) => width}px;
47-
}
48-
49-
&[data-animation="collapse"] {
50-
transition: width ${ANIMATION_DURATION}ms ease-in-out;
51-
width: ${NAVIGATION_COLLASPED_WIDTH}px;
52-
}
53-
`
54-
55-
const ContentContainer = styled.div`
56-
overflow: hidden;
57-
display: flex;
58-
flex-direction: column;
59-
flex-grow: 1;
60-
`
61-
62-
const Content = styled(Stack)`
63-
overflow-y: auto;
64-
overflow-x: hidden;
65-
flex-grow: 1;
66-
67-
&[data-is-expanded="false"] {
68-
align-items: center;
69-
padding: ${({ theme }) => theme.space['2']};
70-
}
71-
72-
&[data-is-expanded="true"],
73-
&[data-animation="expand"] {
74-
padding: ${({ theme }) => theme.space['2']};
75-
}
76-
`
77-
78-
const Slider = styled.div`
79-
background: transparent;
80-
position: absolute;
81-
top: 0;
82-
bottom: 0;
83-
right: 0;
84-
width: 6px;
85-
cursor: col-resize;
86-
border-right: 2px solid transparent;
87-
display: flex;
88-
89-
&:hover {
90-
border-color: ${({ theme }) => theme.colors.primary.border};
91-
}
92-
`
19+
import { widthNavigationContainer } from './variables.css'
9320

9421
export const NavigationContent = ({
9522
children,
@@ -203,31 +130,40 @@ export const NavigationContent = ({
203130
])
204131

205132
return (
206-
<StyledNav className={className} data-testid={dataTestId} id={id}>
207-
<Container
208-
data-animation={shouldAnimate ? animation : undefined}
209-
data-expanded={expanded}
133+
<nav
134+
className={`${className ? `${className} ` : ''}${navigation}`}
135+
data-testid={dataTestId}
136+
id={id}
137+
>
138+
<div
139+
className={navigationContainer({
140+
animation: shouldAnimate ? animation : undefined,
141+
expanded,
142+
})}
210143
ref={navigationRef}
211-
width={width}
144+
style={assignInlineVars({
145+
[widthNavigationContainer]: `${width}px`,
146+
})}
212147
>
213148
{logo ? <Header logo={logo} /> : null}
214-
<ContentContainer>
215-
<Content
216-
data-animation={shouldAnimate ? animation : undefined}
217-
data-is-expanded={expanded}
218-
gap={0.25}
219-
ref={contentRef}
220-
>
149+
<div
150+
className={`${navigationContentContainer}${expanded ? '' : ` ${navigationContentContainerCollapsed}`}`}
151+
>
152+
<Stack className={navigationContent} gap={0.25} ref={contentRef}>
221153
{children}
222-
</Content>
154+
</Stack>
223155
{allowNavigationResize ? (
224156
<Footer contentRef={contentRef} onToggleExpand={onToggleExpand} />
225157
) : null}
226-
</ContentContainer>
227-
</Container>
158+
</div>
159+
</div>
228160
{allowNavigationResize ? (
229-
<Slider data-testid="slider" ref={sliderRef} />
161+
<div
162+
className={navigationSlider}
163+
data-testid="slider"
164+
ref={sliderRef}
165+
/>
230166
) : null}
231-
</StyledNav>
167+
</nav>
232168
)
233169
}

0 commit comments

Comments
 (0)