Skip to content

Commit bc3baa8

Browse files
matthprostlisalupi
authored andcommitted
refactor(carousel): use vanilla extract (#5664)
* refactor(carousel): use vanilla extract * fix: feedback lisa
1 parent 38d6b69 commit bc3baa8

File tree

4 files changed

+106
-149
lines changed

4 files changed

+106
-149
lines changed

.changeset/salty-toys-laugh.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
"@ultraviolet/ui": minor
3+
---
4+
5+
Refactor `<Carousel />` to use vanilla extract

packages/ui/src/components/Carousel/__tests__/__snapshots__/index.test.tsx.snap

Lines changed: 17 additions & 80 deletions
Original file line numberDiff line numberDiff line change
@@ -2,129 +2,66 @@
22

33
exports[`carousel > renders correctly with default props 1`] = `
44
<DocumentFragment>
5-
.emotion-0 {
6-
position: relative;
7-
margin-left: -100px;
8-
margin-right: -100px;
9-
}
10-
11-
.emotion-2 {
12-
position: absolute;
13-
width: 100px;
14-
height: 100%;
15-
content: '';
16-
background: linear-gradient(
17-
-90deg,
18-
#ffffffff,
19-
#ffffff
20-
);
21-
cursor: w-resize;
22-
z-index: auto;
23-
}
24-
25-
.emotion-4 {
26-
overflow-x: scroll;
27-
overflow-y: hidden;
28-
white-space: nowrap;
29-
display: -webkit-box;
30-
display: -webkit-flex;
31-
display: -ms-flexbox;
32-
display: flex;
33-
padding: 0 100px;
34-
gap: 1rem;
35-
}
36-
37-
.emotion-6 {
38-
display: -webkit-box;
39-
display: -webkit-flex;
40-
display: -ms-flexbox;
41-
display: flex;
42-
-webkit-align-items: stretch;
43-
-webkit-box-align: stretch;
44-
-ms-flex-align: stretch;
45-
align-items: stretch;
46-
width: 240px;
47-
max-width: 240px;
48-
overflow-wrap: break-word;
49-
white-space: normal;
50-
height: auto;
51-
cursor: -webkit-grab;
52-
cursor: grab;
53-
-webkit-flex-shrink: 0;
54-
-ms-flex-negative: 0;
55-
flex-shrink: 0;
56-
}
57-
58-
.emotion-18 {
59-
position: absolute;
60-
bottom: 0;
61-
right: 0;
62-
width: 100px;
63-
height: 100%;
64-
content: '';
65-
cursor: e-resize;
66-
z-index: auto;
67-
background: linear-gradient(
68-
-90deg,
69-
#ffffff,
70-
#ffffffff
71-
);
72-
}
73-
74-
<div
5+
<div
756
data-testid="testing"
767
>
778
<div
78-
class="emotion-0 emotion-1"
9+
class="styles__ztme1b1"
7910
data-testid="scrollbar"
8011
>
8112
<span
82-
class="emotion-2 emotion-3"
13+
class="styles__ztme1b2"
8314
data-testid="scrollbar-before"
8415
/>
8516
<div
86-
class="emotion-4 emotion-5"
17+
class="styles__ztme1b3"
8718
data-testid="scrollbar-wrapper"
8819
>
8920
<div
90-
class="emotion-6 emotion-7"
21+
class="styles__ztme1b5"
9122
draggable="true"
23+
style="--ztme1b0: 240px;"
9224
>
9325
Item 1
9426
</div>
9527
<div
96-
class="emotion-6 emotion-7"
28+
class="styles__ztme1b5"
9729
draggable="true"
30+
style="--ztme1b0: 240px;"
9831
>
9932
Item 2
10033
</div>
10134
<div
102-
class="emotion-6 emotion-7"
35+
class="styles__ztme1b5"
10336
draggable="true"
37+
style="--ztme1b0: 240px;"
10438
>
10539
Item 3
10640
</div>
10741
<div
108-
class="emotion-6 emotion-7"
42+
class="styles__ztme1b5"
10943
draggable="true"
44+
style="--ztme1b0: 240px;"
11045
>
11146
Item 4
11247
</div>
11348
<div
114-
class="emotion-6 emotion-7"
49+
class="styles__ztme1b5"
11550
draggable="true"
51+
style="--ztme1b0: 240px;"
11652
>
11753
Item 5
11854
</div>
11955
<div
120-
class="emotion-6 emotion-7"
56+
class="styles__ztme1b5"
12157
draggable="true"
58+
style="--ztme1b0: 240px;"
12259
>
12360
Item 6
12461
</div>
12562
</div>
12663
<span
127-
class="emotion-18 emotion-19"
64+
class="styles__ztme1b4"
12865
data-testid="scrollbar-after"
12966
/>
13067
</div>

packages/ui/src/components/Carousel/index.tsx

Lines changed: 31 additions & 69 deletions
Original file line numberDiff line numberDiff line change
@@ -1,67 +1,16 @@
11
'use client'
22

3-
import styled from '@emotion/styled'
3+
import { assignInlineVars } from '@vanilla-extract/dynamic'
44
import type { ReactNode } from 'react'
55
import { useEffect, useRef, useState } from 'react'
6-
7-
const StyledWrapper = styled.div`
8-
position: relative;
9-
margin-left: -100px;
10-
margin-right: -100px;
11-
`
12-
13-
const StyledBeforeScroll = styled.span`
14-
position: absolute;
15-
width: 100px;
16-
height: 100%;
17-
content: '';
18-
background: linear-gradient(
19-
-90deg,
20-
${({ theme }) => theme.colors.neutral.background}ff,
21-
${({ theme }) => theme.colors.neutral.background}
22-
);
23-
cursor: w-resize;
24-
z-index: auto;
25-
`
26-
27-
const StyledScrollableWrapper = styled.div`
28-
overflow-x: scroll;
29-
overflow-y: hidden;
30-
white-space: nowrap;
31-
display: flex;
32-
padding: 0 100px;
33-
gap: ${({ theme }) => theme.space['2']};
34-
`
35-
36-
const StyledAfterScroll = styled.span`
37-
position: absolute;
38-
bottom: 0;
39-
right: 0;
40-
width: 100px;
41-
height: 100%;
42-
content: '';
43-
cursor: e-resize;
44-
z-index: auto;
45-
background: linear-gradient(
46-
-90deg,
47-
${({ theme }) => theme.colors.neutral.background},
48-
${({ theme }) => theme.colors.neutral.background}ff
49-
);
50-
`
51-
52-
const StyledBorderWrapper = styled('div', {
53-
shouldForwardProp: prop => !['width'].includes(prop),
54-
})<{ width: string }>`
55-
display: flex;
56-
align-items: stretch;
57-
width: ${({ width }) => width};
58-
max-width: ${({ width }) => width};
59-
overflow-wrap: break-word;
60-
white-space: normal;
61-
height: auto;
62-
cursor: grab;
63-
flex-shrink: 0;
64-
`
6+
import {
7+
afterScroll,
8+
beforeScroll,
9+
borderWrapper,
10+
scrollableWrapper,
11+
widthVar,
12+
wrapper,
13+
} from './styles.css'
6514

6615
type CarouselItemProps = {
6716
children: ReactNode
@@ -71,9 +20,15 @@ export const CarouselItem = ({
7120
children,
7221
width = '240px',
7322
}: CarouselItemProps) => (
74-
<StyledBorderWrapper draggable="true" width={width}>
23+
<div
24+
className={borderWrapper}
25+
draggable="true"
26+
style={assignInlineVars({
27+
[widthVar]: width,
28+
})}
29+
>
7530
{children}
76-
</StyledBorderWrapper>
31+
</div>
7732
)
7833

7934
type CarouselProps = {
@@ -125,14 +80,19 @@ export const Carousel = ({
12580
const [deltaX, setDeltaX] = useState(0)
12681

12782
return (
128-
<StyledWrapper className={className} data-testid={dataTestId}>
129-
<StyledBeforeScroll
83+
<div
84+
className={`${className ? `${className} ` : ''}${wrapper}`}
85+
data-testid={dataTestId}
86+
>
87+
<span
88+
className={beforeScroll}
13089
data-testid={`${dataTestId}-before`}
90+
onFocus={handleScrollRight}
13191
onMouseLeave={() => clearInterval(intervalRight)}
13292
onMouseOver={handleScrollRight}
13393
/>
134-
<StyledScrollableWrapper
135-
className={className}
94+
<div
95+
className={`${className ? `${className} ` : ''}${scrollableWrapper}`}
13696
data-testid={`${dataTestId}-wrapper`}
13797
onDrag={() => handleScrollX(deltaX)}
13898
onDragEnd={() => {
@@ -158,14 +118,16 @@ export const Carousel = ({
158118
ref={scrollRef}
159119
>
160120
{children}
161-
</StyledScrollableWrapper>
121+
</div>
162122

163-
<StyledAfterScroll
123+
<span
124+
className={afterScroll}
164125
data-testid={`${dataTestId}-after`}
126+
onFocus={handleScrollLeft}
165127
onMouseLeave={() => clearInterval(intervalLeft)}
166128
onMouseOver={handleScrollLeft}
167129
/>
168-
</StyledWrapper>
130+
</div>
169131
)
170132
}
171133

Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
import { createVar, style } from '@vanilla-extract/css'
2+
import { theme } from '@ultraviolet/themes'
3+
4+
export const widthVar = createVar()
5+
6+
export const wrapper = style({
7+
position: 'relative',
8+
marginLeft: '-100px',
9+
marginRight: '-100px',
10+
})
11+
12+
export const beforeScroll = style({
13+
position: 'absolute',
14+
width: '100px',
15+
height: '100%',
16+
content: "''",
17+
background: `linear-gradient(-90deg, transparent, ${theme.colors.neutral.background})`,
18+
cursor: 'w-resize',
19+
zIndex: 'auto',
20+
})
21+
22+
export const scrollableWrapper = style({
23+
overflowX: 'scroll',
24+
overflowY: 'hidden',
25+
whiteSpace: 'nowrap',
26+
display: 'flex',
27+
padding: '0 100px',
28+
gap: theme.space['2'],
29+
})
30+
31+
export const afterScroll = style({
32+
position: 'absolute',
33+
bottom: '0',
34+
right: '0',
35+
width: '100px',
36+
height: '100%',
37+
content: "''",
38+
cursor: 'e-resize',
39+
zIndex: 'auto',
40+
background: `linear-gradient(-90deg, ${theme.colors.neutral.background}, transparent)`,
41+
})
42+
43+
export const borderWrapper = style({
44+
display: 'flex',
45+
alignItems: 'stretch',
46+
width: widthVar,
47+
maxWidth: widthVar,
48+
overflowWrap: 'break-word',
49+
whiteSpace: 'normal',
50+
height: 'auto',
51+
cursor: 'grab',
52+
flexShrink: '0',
53+
})

0 commit comments

Comments
 (0)