Skip to content

Commit 91cfeaf

Browse files
authored
refactor(components): use vanilla-extract for styles (#1124)
* refactor(components): use vanilla-extract for styles * docs: add dark mode var override example * chore: add changeset * fix: remove style * chore: remove skipLibCheck
1 parent 79c98f0 commit 91cfeaf

File tree

15 files changed

+220
-244
lines changed

15 files changed

+220
-244
lines changed
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
---
2+
"@launchpad-ui/components": patch
3+
"@launchpad-ui/tokens": patch
4+
---
5+
6+
Use Vanilla Extract for component styles

.eslintrc.js

Lines changed: 1 addition & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -20,14 +20,7 @@ module.exports = {
2020
jsx: true,
2121
},
2222
},
23-
plugins: [
24-
'react',
25-
'@typescript-eslint',
26-
'testing-library',
27-
'functional',
28-
'jsx-a11y',
29-
'@stylexjs',
30-
],
23+
plugins: ['react', '@typescript-eslint', 'testing-library', 'functional', 'jsx-a11y'],
3124
settings: {
3225
react: {
3326
version: 'detect',
@@ -102,7 +95,6 @@ module.exports = {
10295
],
10396
},
10497
],
105-
'@stylexjs/valid-styles': 'error',
10698
},
10799
overrides: [
108100
{

.storybook/main.ts

Lines changed: 0 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,6 @@ import type { StorybookConfig } from '@storybook/react-vite';
33
import path from 'path';
44
import fs from 'fs';
55
import fg from 'fast-glob';
6-
import stylexPlugin from '@stylexjs/rollup-plugin';
76
import { mergeConfig } from 'vite';
87
import turbosnap from 'vite-plugin-turbosnap';
98

@@ -54,20 +53,6 @@ const config: StorybookConfig = {
5453
configType === 'PRODUCTION'
5554
? {
5655
plugins: [turbosnap({ rootDir: config.root || process.cwd() })],
57-
build: {
58-
rollupOptions: {
59-
plugins: [
60-
stylexPlugin({
61-
// Required for CSS variable support
62-
unstable_moduleResolution: {
63-
type: 'commonJS',
64-
rootDir: __dirname,
65-
},
66-
useCSSLayers: true,
67-
}),
68-
],
69-
},
70-
},
7156
}
7257
: {}
7358
);
@@ -76,10 +61,6 @@ const config: StorybookConfig = {
7661
autodocs: true,
7762
defaultName: 'Docs',
7863
},
79-
previewHead: (head) => `
80-
${head}
81-
${process.env.NODE_ENV === 'production' ? '<link href="./stylex.css" rel="stylesheet" />' : ''}
82-
`,
8364
};
8465

8566
const getPackageStatusEnvVars = () => {

apps/remix/remix.config.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,6 @@
33
*/
44
module.exports = {
55
ignoredRouteFiles: ['**/.*'],
6-
serverDependenciesToBundle: [/^@launchpad-ui/, 'marked', '@stylexjs/stylex'],
6+
serverDependenciesToBundle: [/^@launchpad-ui/, 'marked'],
77
serverModuleFormat: 'cjs',
88
};

package.json

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -65,9 +65,6 @@
6565
"@storybook/testing-library": "^0.2.2",
6666
"@storybook/theming": "^7.6.3",
6767
"@storybook/types": "^7.6.3",
68-
"@stylexjs/babel-plugin": "^0.4.1",
69-
"@stylexjs/eslint-plugin": "^0.4.1",
70-
"@stylexjs/rollup-plugin": "^0.4.1",
7168
"@testing-library/dom": "^9.3.0",
7269
"@testing-library/jest-dom": "^6.1.2",
7370
"@testing-library/react": "^14.1.0",
@@ -79,7 +76,7 @@
7976
"@typescript-eslint/parser": "^6.17.0",
8077
"@vanilla-extract/css": "^1.14.0",
8178
"@vanilla-extract/vite-plugin": "^3.9.2",
82-
"@vitejs/plugin-react": "^4.2.0",
79+
"@vitejs/plugin-react-swc": "^3.5.0",
8380
"@vitest/coverage-v8": "^1.1.1",
8481
"@vitest/ui": "^1.1.1",
8582
"chromatic": "^10.2.0",

packages/components/.gitignore

Lines changed: 0 additions & 1 deletion
This file was deleted.

packages/components/package.json

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -28,16 +28,18 @@
2828
"scripts": {
2929
"build": "vite build -c ../../vite.config.mts && tsc --project tsconfig.build.json",
3030
"clean": "rm -rf dist",
31-
"lint": "eslint '**/*.{ts,tsx,js}' --ignore-pattern 'tokens.stylex.ts'",
31+
"lint": "eslint '**/*.{ts,tsx,js}'",
3232
"test": "vitest run --coverage"
3333
},
3434
"dependencies": {
3535
"@launchpad-ui/tokens": "workspace:~",
36-
"@stylexjs/stylex": "0.4.1",
36+
"@launchpad-ui/vars": "workspace:~",
37+
"@vanilla-extract/recipes": "0.5.1",
3738
"react-aria-components": "1.0.0",
3839
"clsx": "2.1.0"
3940
},
4041
"peerDependencies": {
42+
"@vanilla-extract/css": "^1.14.0",
4143
"react": "18.2.0",
4244
"react-dom": "18.2.0"
4345
},

packages/components/src/ProgressBar.tsx

Lines changed: 8 additions & 55 deletions
Original file line numberDiff line numberDiff line change
@@ -1,89 +1,42 @@
1-
import type { StyleXStyles } from '@stylexjs/stylex';
1+
import type { ProgressBarVariants } from './styles/ProgressBar.css';
22
import type { ForwardedRef } from 'react';
33
import type { ProgressBarProps as AriaProgressBarProps } from 'react-aria-components';
44

5-
import * as stylex from '@stylexjs/stylex';
65
import { clsx } from 'clsx';
76
import { forwardRef } from 'react';
87
import { ProgressBar as AriaProgressBar } from 'react-aria-components';
98

10-
import { tokens } from './tokens.stylex';
9+
import { base, indeterminate, outerCircle, innerCircle, variants } from './styles/ProgressBar.css';
1110

12-
const spin = stylex.keyframes({
13-
from: { transform: 'rotate(0deg)' },
14-
to: { transform: 'rotate(359deg)' },
15-
});
16-
17-
const styles = stylex.create({
18-
base: {
19-
display: 'inline-block',
20-
transformOrigin: '0 0',
21-
},
22-
indeterminate: {
23-
animationName: spin,
24-
animationDuration: tokens['duration.350'],
25-
animationTimingFunction: 'linear',
26-
animationIterationCount: 'infinite',
27-
},
28-
outerCircle: {
29-
stroke: tokens['color.white.100'],
30-
},
31-
innerCircle: {
32-
stroke: tokens['color.gray.500'],
33-
},
34-
});
35-
36-
const variants = stylex.create({
37-
small: {
38-
transform: 'scale(0.25)',
39-
},
40-
medium: {
41-
transform: 'scale(0.375)',
42-
},
43-
large: {
44-
transform: 'scale(0.5)',
45-
},
46-
});
47-
48-
interface ProgressBarProps extends Omit<AriaProgressBarProps, 'style'> {
49-
style?: StyleXStyles;
50-
size?: keyof typeof variants;
51-
}
11+
type ProgressBarProps = AriaProgressBarProps & ProgressBarVariants;
5212

5313
const ProgressBar = forwardRef(
5414
(
55-
{ style, size = 'small', className, ...props }: ProgressBarProps,
15+
{ size = 'small', className, ...props }: ProgressBarProps,
5616
ref: ForwardedRef<HTMLDivElement>
5717
) => {
5818
const center = 16;
5919
const strokeWidth = 4;
6020
const r = 16 - strokeWidth;
6121
const c = 2 * r * Math.PI;
6222

63-
const stylexProps = stylex.props(styles.base, variants[size], style);
64-
6523
return (
66-
<AriaProgressBar
67-
{...props}
68-
ref={ref}
69-
className={clsx(stylexProps.className, className)}
70-
style={stylexProps.style}
71-
>
24+
<AriaProgressBar {...props} ref={ref} className={clsx(base, variants({ size }), className)}>
7225
{({ percentage }) => (
7326
<svg
7427
width={64}
7528
height={64}
7629
viewBox="0 0 32 32"
7730
fill="none"
7831
strokeWidth={strokeWidth}
79-
{...stylex.props(props.isIndeterminate && styles.indeterminate)}
32+
className={clsx(props.isIndeterminate && indeterminate)}
8033
>
8134
<circle
8235
cx={center}
8336
cy={center}
8437
r={r}
8538
strokeWidth={strokeWidth}
86-
{...stylex.props(styles.outerCircle)}
39+
className={outerCircle}
8740
/>
8841
<circle
8942
cx={center}
@@ -92,7 +45,7 @@ const ProgressBar = forwardRef(
9245
strokeDasharray={`${c} ${c}`}
9346
strokeDashoffset={c - (props.isIndeterminate ? 0.34 : percentage! / 100) * c}
9447
transform="rotate(-90 16 16)"
95-
{...stylex.props(styles.innerCircle)}
48+
className={innerCircle}
9649
/>
9750
</svg>
9851
)}
Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
import type { RecipeVariants } from '@vanilla-extract/recipes';
2+
3+
import { vars } from '@launchpad-ui/vars';
4+
import { keyframes, style } from '@vanilla-extract/css';
5+
import { recipe } from '@vanilla-extract/recipes';
6+
7+
const base = style({
8+
display: 'inline-block',
9+
transformOrigin: '0 0',
10+
});
11+
12+
const outerCircle = style({
13+
stroke: vars.color.white[100],
14+
});
15+
16+
const innerCircle = style({
17+
stroke: vars.color.gray[500],
18+
});
19+
20+
const variants = recipe({
21+
variants: {
22+
size: {
23+
small: {
24+
transform: 'scale(0.25)',
25+
},
26+
medium: {
27+
transform: 'scale(0.375)',
28+
},
29+
large: {
30+
transform: 'scale(0.5)',
31+
},
32+
},
33+
},
34+
});
35+
36+
const spin = keyframes({
37+
'0%': { transform: 'rotate(0deg)' },
38+
'100%': { transform: 'rotate(360deg)' },
39+
});
40+
41+
const indeterminate = style({
42+
animationName: spin,
43+
animationDuration: vars.duration[350],
44+
animationTimingFunction: 'linear',
45+
animationIterationCount: 'infinite',
46+
});
47+
48+
type ProgressBarVariants = RecipeVariants<typeof variants>;
49+
50+
export { base, indeterminate, outerCircle, innerCircle, variants };
51+
export type { ProgressBarVariants };

packages/components/stories/ProgressBar.stories.tsx

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,19 @@
1-
import type { StoryObj } from '@storybook/react';
1+
import type { Meta, StoryObj } from '@storybook/react';
22

33
import { ProgressBar } from '../src';
44

5-
export default {
5+
const meta: Meta<typeof ProgressBar> = {
66
component: ProgressBar,
77
title: 'React Aria Components/ProgressBar',
8-
description:
9-
"An implementation of LaunchDarkly's LaunchPad Design System using React Aria Components.",
108
parameters: {
119
status: {
1210
type: import.meta.env.STORYBOOK_PACKAGE_STATUS__COMPONENTS,
1311
},
1412
},
1513
};
1614

15+
export default meta;
16+
1717
type Story = StoryObj<typeof ProgressBar>;
1818

1919
export const Example: Story = {

0 commit comments

Comments
 (0)