@yak/solid 0.0.0 → 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +28 -21
- package/package.json +22 -23
- package/runtime/__tests__/typeTest.tsx +10 -1
package/README.md
CHANGED
|
@@ -1,23 +1,26 @@
|
|
|
1
1
|
# @yak/solid
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
Styled-components syntax for SolidJS, compiled away at build time. Your CSS is extracted by the [yak](https://yak.js.org/) SWC compiler and what's left at runtime is a thin layer that fits Solid's model: components run once, and dynamic styles are driven by signals, not re-renders.
|
|
4
4
|
|
|
5
|
-
> **Status: experimental.** `@yak/solid` targets Solid 2 (currently at RC) and tracks it closely. Expect breaking changes while Solid 2 stabilizes. Solid 1 is not supported
|
|
5
|
+
> **Status: experimental.** `@yak/solid` targets Solid 2 (currently at RC) and tracks it closely. Expect breaking changes while Solid 2 stabilizes. Solid 1 is not supported, and neither is SolidStart v2, which still runs on Solid 1.
|
|
6
6
|
|
|
7
|
-
##
|
|
7
|
+
## Why this fits Solid
|
|
8
8
|
|
|
9
|
-
|
|
9
|
+
Most CSS-in-JS libraries assume a re-rendering component model. `@yak/solid` doesn't. It works the way you'd expect Solid code to work:
|
|
10
10
|
|
|
11
|
-
- Static styles
|
|
12
|
-
- Dynamic
|
|
11
|
+
- **Static styles are just classes.** A `styled.div` with no interpolations compiles to a plain CSS class and a single reactive `class` binding.
|
|
12
|
+
- **Dynamic styles are signals in, CSS variables out.** Interpolations like `${(props) => props.$angle}` become CSS custom properties on the element's inline `style`. All of them are computed in one memo per component. When a prop changes, the element is not re-created, only its `class`/`style` bindings update, and the memo only re-runs for props the CSS actually reads.
|
|
13
|
+
- **No hidden subscriptions.** Reads inside interpolations are tracked like any other reactive read in Solid. If your CSS doesn't read `props.theme()`, it doesn't subscribe to the theme.
|
|
13
14
|
|
|
14
|
-
##
|
|
15
|
+
## Getting started
|
|
15
16
|
|
|
16
17
|
```bash
|
|
17
18
|
pnpm add @yak/solid
|
|
18
19
|
pnpm add -D vite-plugin-solid@next
|
|
19
20
|
```
|
|
20
21
|
|
|
22
|
+
Add the yak plugin before `solid()` in your Vite config:
|
|
23
|
+
|
|
21
24
|
```ts
|
|
22
25
|
// vite.config.ts
|
|
23
26
|
import { defineConfig } from "vite";
|
|
@@ -29,6 +32,8 @@ export default defineConfig({
|
|
|
29
32
|
});
|
|
30
33
|
```
|
|
31
34
|
|
|
35
|
+
Then write styled components the way you'd write them anywhere else. Prop-based interpolations are tracked reactively:
|
|
36
|
+
|
|
32
37
|
```tsx
|
|
33
38
|
import { styled, css, keyframes } from "@yak/solid";
|
|
34
39
|
|
|
@@ -46,9 +51,7 @@ const Hand = styled.div<{ $angle: number }>`
|
|
|
46
51
|
`;
|
|
47
52
|
```
|
|
48
53
|
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
The `css` prop works on all intrinsic elements (uses Solid's `class` attribute):
|
|
54
|
+
The `css` prop works on every intrinsic element and maps to Solid's `class` attribute:
|
|
52
55
|
|
|
53
56
|
```tsx
|
|
54
57
|
<p
|
|
@@ -72,7 +75,7 @@ declare module "@yak/solid" {
|
|
|
72
75
|
}
|
|
73
76
|
```
|
|
74
77
|
|
|
75
|
-
`useTheme()` returns an accessor, like a signal getter. Call it where the value is used. That read subscribes the surrounding scope to theme changes:
|
|
78
|
+
`useTheme()` returns an accessor, like a signal getter. Call it where the value is used. That read is what subscribes the surrounding scope to theme changes:
|
|
76
79
|
|
|
77
80
|
```tsx
|
|
78
81
|
import { styled, useTheme, YakThemeProvider } from "@yak/solid";
|
|
@@ -92,7 +95,7 @@ function Toolbar() {
|
|
|
92
95
|
</YakThemeProvider>;
|
|
93
96
|
```
|
|
94
97
|
|
|
95
|
-
The
|
|
98
|
+
The theme context itself is exported too, so you can compose it natively, e.g. to override the theme for a subtree. In Solid 2 a context is its own provider and takes an accessor:
|
|
96
99
|
|
|
97
100
|
```tsx
|
|
98
101
|
import { createMemo } from "solid-js";
|
|
@@ -105,21 +108,25 @@ function InvertedSection(props) {
|
|
|
105
108
|
}
|
|
106
109
|
```
|
|
107
110
|
|
|
108
|
-
##
|
|
111
|
+
## Coming from next-yak or React?
|
|
109
112
|
|
|
110
|
-
|
|
111
|
-
- `class` instead of `className` (Solid convention), also inside `.attrs({ ... })`.
|
|
112
|
-
- No jsx-runtime export: Solid compiles JSX natively. The css prop types activate by importing `@yak/solid`.
|
|
113
|
-
- Components run once. Solid's reactivity drives dynamic styles instead of re-renders.
|
|
114
|
-
- `foldStatic` is off by default (see [Static folding](#static-folding-opt-in) below).
|
|
113
|
+
If you've used `next-yak`, the API is the same with a few Solid-shaped differences:
|
|
115
114
|
|
|
116
|
-
|
|
115
|
+
- `useTheme()` returns an accessor: read `theme().highContrast`, not `theme.highContrast`. The same applies to `props.theme()` in interpolations and in `.attrs()`.
|
|
116
|
+
- `class` instead of `className`, including inside `.attrs({ ... })`.
|
|
117
|
+
- No jsx-runtime export. Solid compiles JSX natively, which means the `css` prop types activate simply by importing `@yak/solid`.
|
|
118
|
+
- Components run once. There is no re-render to recompute styles and Solid's reactivity handles it.
|
|
117
119
|
|
|
118
|
-
|
|
120
|
+
## How it works
|
|
121
|
+
|
|
122
|
+
Like `next-yak`, the yak SWC compiler extracts your CSS at build time. At runtime only a tiny layer remains that merges class names and feeds dynamic values through CSS custom properties:
|
|
123
|
+
|
|
124
|
+
- Static styles become plain CSS classes. A static `styled.div` never subscribes to the theme and adds a single reactive `class` binding.
|
|
125
|
+
- Dynamic interpolations (`${(props) => ...}`) become CSS variables set on the element's inline `style`. Updates flow through one memo per component: the element is never re-created, only its `class`/`style` bindings change, and only props actually used by the CSS re-run the memo.
|
|
119
126
|
|
|
120
127
|
## Requirements
|
|
121
128
|
|
|
122
|
-
- `solid-js` >= 2.0.0-rc.
|
|
129
|
+
- `solid-js` >= 2.0.0-rc.5 and `@solidjs/web` >= 2.0.0-rc.5
|
|
123
130
|
- `vite-plugin-solid` >= 3.0.0-next (the Solid 2 line, npm tag `next`)
|
|
124
131
|
- `yak-swc` with yak-package auto-detection (bundled as a dependency, version released together with this package or newer)
|
|
125
132
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@yak/solid",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.1.0",
|
|
4
4
|
"description": "SolidJS runtime for yak: styled-components syntax, compiled to plain CSS at build time. Targets Solid 2.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"css-in-js",
|
|
@@ -71,30 +71,23 @@
|
|
|
71
71
|
"publishConfig": {
|
|
72
72
|
"access": "public"
|
|
73
73
|
},
|
|
74
|
-
"scripts": {
|
|
75
|
-
"build": "tsdown",
|
|
76
|
-
"test": "vitest run",
|
|
77
|
-
"test:watch": "vitest",
|
|
78
|
-
"test:types": "tsc -p tsconfig.json && tsc -p runtime/__tests__/tsconfig.json",
|
|
79
|
-
"prepublishOnly": "pnpm build && pnpm test && pnpm test:types"
|
|
80
|
-
},
|
|
81
74
|
"dependencies": {
|
|
82
|
-
"@babel/parser": "
|
|
83
|
-
"@swc/core": "
|
|
84
|
-
"yak-swc": "
|
|
75
|
+
"@babel/parser": "8.0.0",
|
|
76
|
+
"@swc/core": "1.15.43",
|
|
77
|
+
"yak-swc": "9.9.0"
|
|
85
78
|
},
|
|
86
79
|
"devDependencies": {
|
|
87
|
-
"@solidjs/web": "
|
|
88
|
-
"@testing-library/jest-dom": "
|
|
89
|
-
"@types/node": "
|
|
90
|
-
"jsdom": "
|
|
91
|
-
"solid-js": "
|
|
92
|
-
"tsdown": "
|
|
93
|
-
"typescript": "
|
|
94
|
-
"vite": "
|
|
95
|
-
"vite-plugin-solid": "
|
|
96
|
-
"vitest": "
|
|
97
|
-
"yak-internals": "
|
|
80
|
+
"@solidjs/web": "2.0.0-rc.5",
|
|
81
|
+
"@testing-library/jest-dom": "6.9.1",
|
|
82
|
+
"@types/node": "26.0.1",
|
|
83
|
+
"jsdom": "29.1.1",
|
|
84
|
+
"solid-js": "2.0.0-rc.5",
|
|
85
|
+
"tsdown": "0.22.3",
|
|
86
|
+
"typescript": "6.0.3",
|
|
87
|
+
"vite": "8.1.1",
|
|
88
|
+
"vite-plugin-solid": "3.0.0-next.27",
|
|
89
|
+
"vitest": "4.1.9",
|
|
90
|
+
"yak-internals": "0.0.0"
|
|
98
91
|
},
|
|
99
92
|
"peerDependencies": {
|
|
100
93
|
"solid-js": ">=2.0.0-rc.5",
|
|
@@ -104,5 +97,11 @@
|
|
|
104
97
|
"vite": {
|
|
105
98
|
"optional": true
|
|
106
99
|
}
|
|
100
|
+
},
|
|
101
|
+
"scripts": {
|
|
102
|
+
"build": "tsdown",
|
|
103
|
+
"test": "vitest run",
|
|
104
|
+
"test:watch": "vitest",
|
|
105
|
+
"test:types": "tsc -p tsconfig.json && tsc -p runtime/__tests__/tsconfig.json"
|
|
107
106
|
}
|
|
108
|
-
}
|
|
107
|
+
}
|
|
@@ -59,4 +59,13 @@ const override = <YakThemeContext value={() => ({})}>{cssPropUsage}</YakThemeCon
|
|
|
59
59
|
// @ts-expect-error - the context value must be an accessor, not a theme object
|
|
60
60
|
const invalidOverride = <YakThemeContext value={{}}>{cssPropUsage}</YakThemeContext>;
|
|
61
61
|
|
|
62
|
-
export {
|
|
62
|
+
export {
|
|
63
|
+
buttonUsage,
|
|
64
|
+
customUsage,
|
|
65
|
+
withAttrsUsage,
|
|
66
|
+
Spinner,
|
|
67
|
+
provider,
|
|
68
|
+
themeValue,
|
|
69
|
+
override,
|
|
70
|
+
invalidOverride,
|
|
71
|
+
};
|