Skip to content

Commit b6aea68

Browse files
committed
refactor: migrate styled-components to vanilla-extract
1 parent 795ba95 commit b6aea68

File tree

10 files changed

+493
-74
lines changed

10 files changed

+493
-74
lines changed

apps/storybook/.storybook/main.ts

Lines changed: 11 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,25 +1,26 @@
1-
import type { StorybookConfig } from "@storybook/react-vite";
2-
3-
import { join, dirname } from "path";
1+
import type { StorybookConfig } from '@storybook/react-vite';
2+
import { join, dirname } from 'path';
43

54
/**
65
* This function is used to resolve the absolute path of a package.
76
* It is needed in projects that use Yarn PnP or are set up within a monorepo.
87
*/
98
function getAbsolutePath(value: string): any {
10-
return dirname(require.resolve(join(value, "package.json")));
9+
return dirname(require.resolve(join(value, 'package.json')));
1110
}
11+
1212
const config: StorybookConfig = {
13-
stories: ["../src/**/*.mdx", "../src/**/*.stories.@(js|jsx|mjs|ts|tsx)"],
13+
stories: ['../src/**/*.mdx', '../src/**/*.stories.@(js|jsx|mjs|ts|tsx)'],
1414
addons: [
15-
getAbsolutePath("@storybook/addon-onboarding"),
16-
getAbsolutePath("@storybook/addon-essentials"),
17-
getAbsolutePath("@chromatic-com/storybook"),
18-
getAbsolutePath("@storybook/addon-interactions"),
15+
getAbsolutePath('@storybook/addon-onboarding'),
16+
getAbsolutePath('@storybook/addon-essentials'),
17+
getAbsolutePath('@chromatic-com/storybook'),
18+
getAbsolutePath('@storybook/addon-interactions'),
1919
],
2020
framework: {
21-
name: getAbsolutePath("@storybook/react-vite"),
21+
name: getAbsolutePath('@storybook/react-vite'),
2222
options: {},
2323
},
2424
};
25+
2526
export default config;

apps/storybook/package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@
2727
"@storybook/test": "8.6.0-alpha.0",
2828
"@types/react": "^18.3.18",
2929
"@types/react-dom": "^18.3.5",
30+
"@vanilla-extract/vite-plugin": "^5.0.1",
3031
"@vitejs/plugin-react": "^4.3.4",
3132
"eslint": "^9.17.0",
3233
"eslint-plugin-react-hooks": "^5.0.0",

apps/storybook/vite.config.ts

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,8 @@
1-
import { defineConfig } from 'vite'
2-
import react from '@vitejs/plugin-react'
1+
import { defineConfig } from 'vite';
2+
import react from '@vitejs/plugin-react';
3+
import { vanillaExtractPlugin } from '@vanilla-extract/vite-plugin';
34

45
// https://vite.dev/config/
56
export default defineConfig({
6-
plugins: [react()],
7-
})
7+
plugins: [react(), vanillaExtractPlugin()],
8+
});

packages/notion-to-jsx/package.json

Lines changed: 10 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -35,17 +35,21 @@
3535
"styled-components": "^6.0.0"
3636
},
3737
"dependencies": {
38-
"prismjs": "^1.29.0",
39-
"notion-to-utils": "workspace:*"
38+
"@vanilla-extract/css": "^1.17.1",
39+
"@vanilla-extract/recipes": "^0.5.5",
40+
"@vanilla-extract/sprinkles": "^1.6.3",
41+
"notion-to-utils": "workspace:*",
42+
"prismjs": "^1.29.0"
4043
},
4144
"devDependencies": {
45+
"@repo/eslint-config": "workspace:*",
46+
"@repo/typescript-config": "workspace:*",
4247
"@types/prismjs": "^1.26.5",
4348
"@types/react": "^18.3.18",
4449
"@types/react-dom": "^18.3.5",
4550
"@types/styled-components": "^5.1.34",
46-
"typescript": "^5.6.3",
47-
"@repo/eslint-config": "workspace:*",
48-
"@repo/typescript-config": "workspace:*",
49-
"tsup": "^8.0.0"
51+
"@vanilla-extract/esbuild-plugin": "^2.3.15",
52+
"tsup": "^8.0.0",
53+
"typescript": "^5.6.3"
5054
}
5155
}

packages/notion-to-jsx/src/components/Renderer/index.tsx

Lines changed: 48 additions & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,13 @@
11
// import { Client } from 'notion-to-utils';
22
import React, { useEffect, useState, useMemo, useCallback } from 'react';
3-
import { ThemeProvider } from 'styled-components';
4-
import { Container } from './styles';
3+
import { container } from './styles.css';
54

6-
import { lightTheme, darkTheme, Theme } from '../../styles/theme';
75
import { NotionBlock } from '../../types';
86
import testData from '../../constants/test.json';
97
import { useKeyboardNavigation } from '../../hooks/useKeyboardNavigation';
10-
import { BlockRenderer } from './components/Block';
11-
import { List, ListBlocksRenderer } from './components/List';
8+
import { darkTheme, lightTheme } from '../../styles/theme.css';
9+
// import { BlockRenderer } from './components/Block';
10+
// import { List, ListBlocksRenderer } from './components/List';
1211

1312
const notion = {
1413
getPageBlocks: async () => {
@@ -66,21 +65,22 @@ export const Renderer: React.FC<Props> = React.memo(
6665
block.type === 'bulleted_list_item' &&
6766
(i === 0 || blocks[i - 1]?.type !== 'bulleted_list_item')
6867
) {
69-
result.push(
70-
<List
71-
as="ul"
72-
type="bulleted"
73-
role="list"
74-
aria-label="Bulleted list"
75-
key={block.id}
76-
>
77-
<ListBlocksRenderer
78-
blocks={blocks}
79-
startIndex={i}
80-
type="bulleted"
81-
/>
82-
</List>
83-
);
68+
result
69+
.push
70+
// <List
71+
// as="ul"
72+
// type="bulleted"
73+
// role="list"
74+
// aria-label="Bulleted list"
75+
// key={block.id}
76+
// >
77+
// <ListBlocksRenderer
78+
// blocks={blocks}
79+
// startIndex={i}
80+
// type="bulleted"
81+
// />
82+
// </List>
83+
();
8484
while (
8585
i + 1 < blocks.length &&
8686
blocks[i + 1] &&
@@ -92,21 +92,22 @@ export const Renderer: React.FC<Props> = React.memo(
9292
block.type === 'numbered_list_item' &&
9393
(i === 0 || blocks[i - 1]?.type !== 'numbered_list_item')
9494
) {
95-
result.push(
96-
<List
97-
as="ol"
98-
type="1"
99-
role="list"
100-
aria-label="Numbered list"
101-
key={block.id}
102-
>
103-
<ListBlocksRenderer
104-
blocks={blocks}
105-
startIndex={i}
106-
type="numbered"
107-
/>
108-
</List>
109-
);
95+
result
96+
.push
97+
// <List
98+
// as="ol"
99+
// type="1"
100+
// role="list"
101+
// aria-label="Numbered list"
102+
// key={block.id}
103+
// >
104+
// <ListBlocksRenderer
105+
// blocks={blocks}
106+
// startIndex={i}
107+
// type="numbered"
108+
// />
109+
// </List>
110+
();
110111
while (
111112
i + 1 < blocks.length &&
112113
blocks[i + 1] &&
@@ -118,27 +119,25 @@ export const Renderer: React.FC<Props> = React.memo(
118119
block.type !== 'bulleted_list_item' &&
119120
block.type !== 'numbered_list_item'
120121
) {
121-
result.push(
122-
<BlockRenderer
123-
key={block.id}
124-
block={block}
125-
index={i}
126-
onFocus={() => handleBlockFocus(i)}
127-
/>
128-
);
122+
result
123+
.push
124+
// <BlockRenderer
125+
// key={block.id}
126+
// block={block}
127+
// index={i}
128+
// onFocus={() => handleBlockFocus(i)}
129+
// />
130+
();
129131
}
130132
}
131133

132134
return result;
133135
}, [blocks, handleBlockFocus]);
134136

135137
return (
136-
<ThemeProvider theme={theme}>
137-
{/* <GlobalStyle /> */}
138-
<Container role="main" aria-label="Notion page content">
139-
{renderedBlocks}
140-
</Container>
141-
</ThemeProvider>
138+
<div className={container} role="main" aria-label="Notion page content">
139+
{renderedBlocks}
140+
</div>
142141
);
143142
}
144143
);
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
import { style } from '@vanilla-extract/css';
2+
import { vars } from '../../styles/theme.css';
3+
4+
export const container = style({
5+
maxWidth: '900px',
6+
margin: '0 auto',
7+
padding: vars.spacing.xl,
8+
});

packages/notion-to-jsx/src/index.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
11
export * from './components/Renderer';
2-
export * from './components/MemoizedComponents';
2+
// export * from './components/MemoizedComponents';
33
export * from './types';
4-
export * from './styles/theme';
4+
// export * from './styles/theme';
Lines changed: 151 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,151 @@
1+
import { createTheme, createThemeContract } from '@vanilla-extract/css';
2+
3+
export const vars = createThemeContract({
4+
colors: {
5+
background: null,
6+
text: null,
7+
primary: null,
8+
secondary: null,
9+
border: null,
10+
code: {
11+
background: null,
12+
text: null,
13+
},
14+
},
15+
typography: {
16+
fontFamily: {
17+
base: null,
18+
code: null,
19+
},
20+
fontSize: {
21+
small: null,
22+
base: null,
23+
large: null,
24+
h1: null,
25+
h2: null,
26+
h3: null,
27+
},
28+
lineHeight: {
29+
tight: null,
30+
base: null,
31+
relaxed: null,
32+
},
33+
},
34+
spacing: {
35+
xs: null,
36+
sm: null,
37+
md: null,
38+
lg: null,
39+
xl: null,
40+
},
41+
borderRadius: {
42+
sm: null,
43+
md: null,
44+
lg: null,
45+
},
46+
shadows: {
47+
sm: null,
48+
md: null,
49+
lg: null,
50+
},
51+
});
52+
53+
export const lightTheme = createTheme(vars, {
54+
colors: {
55+
background: '#ffffff',
56+
text: '#24292e',
57+
primary: '#0366d6',
58+
secondary: '#586069',
59+
border: '#e1e4e8',
60+
code: {
61+
background: '#f6f8fa',
62+
text: '#24292e',
63+
},
64+
},
65+
typography: {
66+
fontFamily: {
67+
base: '-apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif',
68+
code: 'SFMono-Regular, Consolas, "Liberation Mono", Menlo, monospace',
69+
},
70+
fontSize: {
71+
small: '0.875rem',
72+
base: '1rem',
73+
large: '1.25rem',
74+
h1: '2rem',
75+
h2: '1.5rem',
76+
h3: '1.25rem',
77+
},
78+
lineHeight: {
79+
tight: '1.25',
80+
base: '1.5',
81+
relaxed: '1.75',
82+
},
83+
},
84+
spacing: {
85+
xs: '0.25rem',
86+
sm: '0.5rem',
87+
md: '1rem',
88+
lg: '1.5rem',
89+
xl: '2rem',
90+
},
91+
borderRadius: {
92+
sm: '0.25rem',
93+
md: '0.375rem',
94+
lg: '0.5rem',
95+
},
96+
shadows: {
97+
sm: '0 1px 2px 0 rgba(0, 0, 0, 0.05)',
98+
md: '0 4px 6px -1px rgba(0, 0, 0, 0.1)',
99+
lg: '0 10px 15px -3px rgba(0, 0, 0, 0.1)',
100+
},
101+
});
102+
103+
export const darkTheme = createTheme(vars, {
104+
colors: {
105+
background: '#0d1117',
106+
text: '#c9d1d9',
107+
primary: '#58a6ff',
108+
secondary: '#8b949e',
109+
border: '#30363d',
110+
code: {
111+
background: '#161b22',
112+
text: '#c9d1d9',
113+
},
114+
},
115+
typography: {
116+
fontFamily: {
117+
base: '-apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif',
118+
code: 'SFMono-Regular, Consolas, "Liberation Mono", Menlo, monospace',
119+
},
120+
fontSize: {
121+
small: '0.875rem',
122+
base: '1rem',
123+
large: '1.25rem',
124+
h1: '2rem',
125+
h2: '1.5rem',
126+
h3: '1.25rem',
127+
},
128+
lineHeight: {
129+
tight: '1.25',
130+
base: '1.5',
131+
relaxed: '1.75',
132+
},
133+
},
134+
spacing: {
135+
xs: '0.25rem',
136+
sm: '0.5rem',
137+
md: '1rem',
138+
lg: '1.5rem',
139+
xl: '2rem',
140+
},
141+
borderRadius: {
142+
sm: '0.25rem',
143+
md: '0.375rem',
144+
lg: '0.5rem',
145+
},
146+
shadows: {
147+
sm: '0 1px 2px 0 rgba(0, 0, 0, 0.05)',
148+
md: '0 4px 6px -1px rgba(0, 0, 0, 0.1)',
149+
lg: '0 10px 15px -3px rgba(0, 0, 0, 0.1)',
150+
},
151+
});

0 commit comments

Comments
 (0)