Skip to content

Commit 919c546

Browse files
committed
refactor: table
1 parent 99a45e9 commit 919c546

File tree

10 files changed

+2335
-3079
lines changed

10 files changed

+2335
-3079
lines changed

.changeset/true-bugs-go.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 component `Table` to use vanilla extract instead of Emotion
Lines changed: 23 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -1,22 +1,14 @@
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 type { Color } from '../../theme'
6+
import { useColumnProvider } from '../List/ColumnProvider'
7+
import { tableCell } from './styles.css'
8+
import { maxWidthCell, minWidthCell, widthCell } from './variables.css'
69

710
type Align = 'left' | 'center' | 'right'
811

9-
const StyledCell = styled('td', {
10-
shouldForwardProp: prop => !['sentiment', 'align'].includes(prop),
11-
})<{ sentiment?: Color; align: Align }>`
12-
display: table-cell;
13-
vertical-align: middle;
14-
padding: ${({ theme }) => theme.space['1']};
15-
font-size: ${({ theme }) => theme.typography.bodySmall.fontSize};
16-
background-color: ${({ sentiment, theme }) => (sentiment ? theme.colors[sentiment].background : null)};
17-
text-align: ${({ align }) => align};
18-
`
19-
2012
type CellProps = {
2113
children?: ReactNode
2214
className?: string
@@ -33,14 +25,22 @@ export const Cell = ({
3325
rowSpan,
3426
sentiment,
3527
align = 'left',
36-
}: CellProps) => (
37-
<StyledCell
38-
align={align}
39-
className={className}
40-
colSpan={colSpan}
41-
rowSpan={rowSpan}
42-
sentiment={sentiment}
43-
>
44-
{children}
45-
</StyledCell>
46-
)
28+
}: CellProps) => {
29+
const { maxWidth, minWidth, width } = useColumnProvider()
30+
31+
return (
32+
<td
33+
align={align}
34+
className={`${className ? `${className} ` : ''}${tableCell({ align, sentiment })}`}
35+
colSpan={colSpan}
36+
rowSpan={rowSpan}
37+
style={assignInlineVars({
38+
[widthCell]: width,
39+
[minWidthCell]: minWidth,
40+
[maxWidthCell]: maxWidth,
41+
})}
42+
>
43+
{children}
44+
</td>
45+
)
46+
}
Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,12 @@
11
'use client'
22

3-
import styled from '@emotion/styled'
43
import type { ReactNode } from 'react'
5-
6-
const StyledHeader = styled('thead')`
7-
border-bottom: 1px solid ${({ theme }) => theme.colors.neutral.border};
8-
`
4+
import { tableHeader } from './styles.css'
95

106
type HeaderProps = {
117
children: ReactNode
128
}
139

1410
export const Header = ({ children }: HeaderProps) => (
15-
<StyledHeader>{children}</StyledHeader>
11+
<thead className={tableHeader}>{children}</thead>
1612
)
Lines changed: 20 additions & 59 deletions
Original file line numberDiff line numberDiff line change
@@ -1,70 +1,29 @@
11
'use client'
22

3-
import styled from '@emotion/styled'
43
import {
54
InformationOutlineIcon,
65
SortIcon as SortIconUV,
76
SouthShortIcon,
87
} from '@ultraviolet/icons'
8+
import { assignInlineVars } from '@vanilla-extract/dynamic'
99
import type { ReactNode } from 'react'
10+
import { listSortIcon } from '../List/styles.css'
1011
import { Text } from '../Text'
1112
import { Tooltip } from '../Tooltip'
12-
13-
const StyledSortIcon = styled(SouthShortIcon, {
14-
shouldForwardProp: prop => !['order'].includes(prop),
15-
})<{ order: 'ascending' | 'descending' }>`
16-
transform: ${({ order }) =>
17-
order === 'ascending' ? 'rotate(-180deg)' : 'none'};
18-
transition: transform 0.2s;
19-
`
13+
import { headerCellText, tableHeaderCell } from './styles.css'
14+
import {
15+
headerCellMaxWidth,
16+
headerCellMinWidth,
17+
headerCellWidth,
18+
} from './variables.css'
2019

2120
const SortIcon = ({ order }: { order?: 'ascending' | 'descending' }) =>
2221
order ? (
23-
<StyledSortIcon order={order} sentiment="primary" />
22+
<SouthShortIcon className={listSortIcon[order]} sentiment="primary" />
2423
) : (
2524
<SortIconUV sentiment="neutral" />
2625
)
2726

28-
type StyledHeaderCellProps = Pick<
29-
HeaderCellProps,
30-
'width' | 'maxWidth' | 'minWidth'
31-
> & {
32-
align?: 'left' | 'center' | 'right'
33-
}
34-
35-
const StyledHeaderCell = styled('th', {
36-
shouldForwardProp: prop =>
37-
!['align', 'width', 'maxWidth', 'minWidth'].includes(prop),
38-
})<StyledHeaderCellProps>`
39-
${({ width, maxWidth, minWidth }) => `
40-
${width ? `width: ${width};` : ''}
41-
${maxWidth ? `max-width: ${maxWidth};` : ''}
42-
${minWidth ? `min-width: ${minWidth};` : ''}
43-
`}
44-
display: table-cell;
45-
vertical-align: middle;
46-
text-align: ${({ align }) => align};
47-
padding: ${({ theme }) => theme.space['1']};
48-
49-
&[role*='button'] {
50-
cursor: pointer;
51-
user-select: none;
52-
}
53-
54-
&:first-of-type {
55-
&[data-checkbox="true"] {
56-
padding-left: ${({ theme }) => theme.space['2']};
57-
}
58-
}
59-
`
60-
61-
const StyledText = styled(Text)`
62-
display: flex;
63-
flex-direction: row;
64-
align-items: center;
65-
gap: ${({ theme }) => theme.space['1']};
66-
`
67-
6827
type HeaderCellProps = {
6928
children: ReactNode
7029
className?: string
@@ -104,13 +63,10 @@ export const HeaderCell = ({
10463
: undefined
10564

10665
return (
107-
<StyledHeaderCell
66+
<th
10867
align={align}
10968
aria-sort={order}
110-
className={className}
111-
data-checkbox={isCheckbox}
112-
maxWidth={maxWidth}
113-
minWidth={minWidth}
69+
className={`${className ? `${className} ` : ''}${tableHeaderCell({ align, checked: isCheckbox })}`}
11470
onClick={handleOrder}
11571
onKeyDown={
11672
handleOrder
@@ -126,11 +82,16 @@ export const HeaderCell = ({
12682
: undefined
12783
}
12884
role={onOrder ? 'button columnheader' : undefined}
85+
style={assignInlineVars({
86+
[headerCellWidth]: width ?? 'auto',
87+
[headerCellMaxWidth]: maxWidth ?? 'none',
88+
[headerCellMinWidth]: minWidth ?? 'auto',
89+
})}
12990
tabIndex={handleOrder ? 0 : -1}
130-
width={width}
13191
>
132-
<StyledText
92+
<Text
13393
as="div"
94+
className={headerCellText}
13495
sentiment={order !== undefined ? 'primary' : 'neutral'}
13596
variant="bodySmall"
13697
>
@@ -147,7 +108,7 @@ export const HeaderCell = ({
147108
{orderDirection !== undefined && isOrdered !== undefined ? (
148109
<SortIcon aria-disabled={!onOrder} order={order} />
149110
) : null}
150-
</StyledText>
151-
</StyledHeaderCell>
111+
</Text>
112+
</th>
152113
)
153114
}

0 commit comments

Comments
 (0)