@yak/solid 0.0.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.
Files changed (49) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +126 -0
  3. package/dist/context/baseContext.d.ts +7 -0
  4. package/dist/context/baseContext.js +8 -0
  5. package/dist/context/baseContext.js.map +1 -0
  6. package/dist/context/index.d.ts +29 -0
  7. package/dist/context/index.js +17 -0
  8. package/dist/context/index.js.map +1 -0
  9. package/dist/index.d.ts +352 -0
  10. package/dist/index.js +2 -0
  11. package/dist/index.js.map +1 -0
  12. package/dist/internal.d.ts +473 -0
  13. package/dist/internal.js +382 -0
  14. package/dist/internal.js.map +1 -0
  15. package/dist/isolated-source-eval/index.d.ts +30 -0
  16. package/dist/isolated-source-eval/index.js +315 -0
  17. package/dist/isolated-source-eval/index.js.map +1 -0
  18. package/dist/isolated-source-eval/worker.js +59 -0
  19. package/dist/isolated-source-eval/worker.js.map +1 -0
  20. package/dist/loaders/vite-plugin.d.ts +116 -0
  21. package/dist/loaders/vite-plugin.js +862 -0
  22. package/dist/loaders/vite-plugin.js.map +1 -0
  23. package/loaders/vite-plugin.ts +29 -0
  24. package/package.json +108 -0
  25. package/runtime/__tests__/mergeClasses.test.ts +22 -0
  26. package/runtime/__tests__/reactivity.test.tsx +157 -0
  27. package/runtime/__tests__/styled.test.tsx +270 -0
  28. package/runtime/__tests__/testUtils.tsx +25 -0
  29. package/runtime/__tests__/tsconfig.json +9 -0
  30. package/runtime/__tests__/typeTest.tsx +62 -0
  31. package/runtime/atoms.ts +44 -0
  32. package/runtime/context/baseContext.ts +5 -0
  33. package/runtime/context/index.ts +37 -0
  34. package/runtime/cssLiteral.ts +215 -0
  35. package/runtime/cssProp.ts +26 -0
  36. package/runtime/globalStyle.ts +54 -0
  37. package/runtime/index.ts +39 -0
  38. package/runtime/internal.ts +41 -0
  39. package/runtime/internals/mergeClasses.ts +36 -0
  40. package/runtime/internals/mergeCssProp.ts +54 -0
  41. package/runtime/internals/unitPostFix.ts +34 -0
  42. package/runtime/keyframes.ts +30 -0
  43. package/runtime/mocks/cssLiteral.ts +74 -0
  44. package/runtime/mocks/globalStyle.ts +14 -0
  45. package/runtime/mocks/keyframes.ts +29 -0
  46. package/runtime/mocks/styled.ts +8 -0
  47. package/runtime/publicStyledApi.ts +177 -0
  48. package/runtime/styled.ts +393 -0
  49. package/runtime/styledDom.ts +139 -0
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Digitec Galaxus AG
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,126 @@
1
+ # @yak/solid
2
+
3
+ SolidJS runtime for [yak](https://yak.js.org/): styled-components syntax, compiled to plain CSS at build time, with dynamic values driven by Solid's fine-grained reactivity.
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. This includes SolidStart v2, which runs on Solid 1.
6
+
7
+ ## How it works
8
+
9
+ 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:
10
+
11
+ - Static styles become plain CSS classes. A static `styled.div` never subscribes to the theme and adds a single reactive `class` binding.
12
+ - 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.
13
+
14
+ ## Usage
15
+
16
+ ```bash
17
+ pnpm add @yak/solid
18
+ pnpm add -D vite-plugin-solid@next
19
+ ```
20
+
21
+ ```ts
22
+ // vite.config.ts
23
+ import { defineConfig } from "vite";
24
+ import solid from "vite-plugin-solid";
25
+ import { yak } from "@yak/solid/vite";
26
+
27
+ export default defineConfig({
28
+ plugins: [yak(), solid()],
29
+ });
30
+ ```
31
+
32
+ ```tsx
33
+ import { styled, css, keyframes } from "@yak/solid";
34
+
35
+ const Button = styled.button<{ $primary?: boolean }>`
36
+ color: #009688;
37
+ ${(props) =>
38
+ props.$primary &&
39
+ css`
40
+ border-width: 2px;
41
+ `}
42
+ `;
43
+
44
+ const Hand = styled.div<{ $angle: number }>`
45
+ transform: rotate(${(props) => props.$angle}deg);
46
+ `;
47
+ ```
48
+
49
+ Interpolation functions re-run inside the component's style memo, so destructuring their parameter (`${({ $angle }) => ...}`) is also safe. These docs use the `props` style because it matches Solid's conventions.
50
+
51
+ The `css` prop works on all intrinsic elements (uses Solid's `class` attribute):
52
+
53
+ ```tsx
54
+ <p
55
+ css={css`
56
+ color: green;
57
+ `}
58
+ />
59
+ ```
60
+
61
+ ### Theming
62
+
63
+ Create a `yak.context.ts` next to your `vite.config.ts` (picked up automatically) and augment the `YakTheme` interface:
64
+
65
+ ```ts
66
+ export function getYakThemeContext() {
67
+ return { highContrast: false };
68
+ }
69
+
70
+ declare module "@yak/solid" {
71
+ export interface YakTheme extends ReturnType<typeof getYakThemeContext> {}
72
+ }
73
+ ```
74
+
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:
76
+
77
+ ```tsx
78
+ import { styled, useTheme, YakThemeProvider } from "@yak/solid";
79
+
80
+ const Button = styled.button`
81
+ color: ${(props) => (props.theme().highContrast ? "#000" : "#555")};
82
+ `;
83
+
84
+ function Toolbar() {
85
+ const theme = useTheme();
86
+ return <span>{theme().highContrast ? "High contrast" : "Default"}</span>;
87
+ }
88
+
89
+ // app root: the theme prop is reactive, signal reads inside it stay live
90
+ <YakThemeProvider theme={{ highContrast: highContrast() }}>
91
+ <App />
92
+ </YakThemeProvider>;
93
+ ```
94
+
95
+ The package also exports the context itself for native composition, e.g. overriding the theme for a subtree. In Solid 2 a context is its own provider and takes an accessor:
96
+
97
+ ```tsx
98
+ import { createMemo } from "solid-js";
99
+ import { YakThemeContext, useTheme } from "@yak/solid";
100
+
101
+ function InvertedSection(props) {
102
+ const parent = useTheme();
103
+ const inverted = createMemo(() => ({ ...parent(), highContrast: true }));
104
+ return <YakThemeContext value={inverted}>{props.children}</YakThemeContext>;
105
+ }
106
+ ```
107
+
108
+ ## Differences to next-yak (React)
109
+
110
+ - `useTheme()` returns an accessor: read `theme().highContrast`, not `theme.highContrast`. The same applies to `props.theme()` in interpolations and `.attrs()`.
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).
115
+
116
+ ## Static folding (opt-in)
117
+
118
+ `yak({ foldStatic: true })` additionally folds usages of fully static components into plain elements at build time, removing their wrapper components. It is off by default as we didn't test all the edge-cases and can't guarantee it works correctly everywhere.
119
+
120
+ ## Requirements
121
+
122
+ - `solid-js` >= 2.0.0-rc.0 and `@solidjs/web` >= 2.0.0-rc.0
123
+ - `vite-plugin-solid` >= 3.0.0-next (the Solid 2 line, npm tag `next`)
124
+ - `yak-swc` with yak-package auto-detection (bundled as a dependency, version released together with this package or newer)
125
+
126
+ See the [`examples/vite-solid`](https://github.com/DigitecGalaxus/next-yak/tree/main/examples/vite-solid) app for a full setup.
@@ -0,0 +1,7 @@
1
+ import { YakTheme } from "@yak/solid";
2
+
3
+ //#region runtime/context/baseContext.d.ts
4
+ declare function getYakThemeContext(): YakTheme | undefined;
5
+ //#endregion
6
+ export { getYakThemeContext };
7
+ //# sourceMappingURL=baseContext.d.ts.map
@@ -0,0 +1,8 @@
1
+ //#region runtime/context/baseContext.ts
2
+ function getYakThemeContext() {
3
+ return {};
4
+ }
5
+
6
+ //#endregion
7
+ export { getYakThemeContext };
8
+ //# sourceMappingURL=baseContext.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"baseContext.js","names":[],"sources":["../../runtime/context/baseContext.ts"],"sourcesContent":["import type { YakTheme } from \"@yak/solid\";\n\nexport function getYakThemeContext() {\n return {} as YakTheme | undefined;\n}\n"],"mappings":";AAEA,SAAgB,qBAAqB;CACnC,OAAO,CAAC;AACV"}
@@ -0,0 +1,29 @@
1
+ import { Accessor } from "solid-js";
2
+ import { JSX } from "@solidjs/web";
3
+
4
+ //#region runtime/context/index.d.ts
5
+ interface YakTheme {}
6
+ /**
7
+ * The yak theme context
8
+ *
9
+ * @see https://github.com/DigitecGalaxus/next-yak/blob/main/packages/next-yak/runtime/context/README.md
10
+ */
11
+ declare const YakThemeContext: import("solid-js").Context<Accessor<YakTheme>>;
12
+ /**
13
+ * Returns an accessor to the current yak theme
14
+ */
15
+ declare const useTheme: () => Accessor<YakTheme>;
16
+ /**
17
+ * Yak theme context provider
18
+ *
19
+ * ```tsx
20
+ * <YakThemeProvider theme={{ highContrast: highContrast() }}>
21
+ * ```
22
+ */
23
+ declare const YakThemeProvider: (props: {
24
+ children?: JSX.Element;
25
+ theme?: YakTheme;
26
+ }) => JSX.Element;
27
+ //#endregion
28
+ export { YakTheme, YakThemeContext, YakThemeProvider, useTheme };
29
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1,17 @@
1
+ import { createComponent, createContext, createMemo, useContext } from "solid-js";
2
+
3
+ //#region runtime/context/index.ts
4
+ const YakThemeContext = /* @__PURE__ */ createContext(() => ({}));
5
+ const useTheme = () => useContext(YakThemeContext);
6
+ const YakThemeProvider = (props) => {
7
+ return createComponent(YakThemeContext, {
8
+ value: createMemo(() => props.theme ?? {}),
9
+ get children() {
10
+ return props.children;
11
+ }
12
+ });
13
+ };
14
+
15
+ //#endregion
16
+ export { YakThemeContext, YakThemeProvider, useTheme };
17
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","names":[],"sources":["../../runtime/context/index.ts"],"sourcesContent":["import { createComponent, createContext, createMemo, useContext } from \"solid-js\";\nimport type { Accessor } from \"solid-js\";\nimport type { JSX } from \"@solidjs/web\";\n\nexport interface YakTheme {}\n\n/**\n * The yak theme context\n *\n * @see https://github.com/DigitecGalaxus/next-yak/blob/main/packages/next-yak/runtime/context/README.md\n */\nexport const YakThemeContext = /* @__PURE__ */ createContext<Accessor<YakTheme>>(() => ({}));\n\n/**\n * Returns an accessor to the current yak theme\n */\nexport const useTheme = (): Accessor<YakTheme> => useContext(YakThemeContext);\n\n/**\n * Yak theme context provider\n *\n * ```tsx\n * <YakThemeProvider theme={{ highContrast: highContrast() }}>\n * ```\n */\nexport const YakThemeProvider = (props: {\n children?: JSX.Element;\n theme?: YakTheme;\n}): JSX.Element => {\n const theme = createMemo<YakTheme>(() => props.theme ?? {});\n return createComponent(YakThemeContext, {\n value: theme,\n get children() {\n return props.children;\n },\n });\n};\n"],"mappings":";;;AAWA,MAAa,kBAAkC,qCAAyC,CAAC,EAAE;AAK3F,MAAa,iBAAqC,WAAW,eAAe;AAS5E,MAAa,oBAAoB,UAGd;CAEjB,OAAO,gBAAgB,iBAAiB;EACtC,OAFY,iBAA2B,MAAM,SAAS,CAAC,CAE5C;EACX,IAAI,WAAW;GACb,OAAO,MAAM;EACf;CACF,CAAC;AACH"}
@@ -0,0 +1,352 @@
1
+ import { Accessor } from "solid-js";
2
+ import { JSX } from "@solidjs/web";
3
+
4
+ //#region runtime/context/index.d.ts
5
+ interface YakTheme {}
6
+ /**
7
+ * The yak theme context
8
+ *
9
+ * @see https://github.com/DigitecGalaxus/next-yak/blob/main/packages/next-yak/runtime/context/README.md
10
+ */
11
+ declare const YakThemeContext: import("solid-js").Context<Accessor<YakTheme>>;
12
+ /**
13
+ * Returns an accessor to the current yak theme
14
+ */
15
+ declare const useTheme: () => Accessor<YakTheme>;
16
+ /**
17
+ * Yak theme context provider
18
+ *
19
+ * ```tsx
20
+ * <YakThemeProvider theme={{ highContrast: highContrast() }}>
21
+ * ```
22
+ */
23
+ declare const YakThemeProvider: (props: {
24
+ children?: JSX.Element;
25
+ theme?: YakTheme;
26
+ }) => JSX.Element;
27
+ //#endregion
28
+ //#region runtime/publicStyledApi.d.ts
29
+ /**
30
+ * Component signature accepted and produced by `styled`.
31
+ *
32
+ * Intentionally NOT Solid 2's `Component` type: that alias constrains props
33
+ * to `Record<string, any>` which does not compose with the `object`-based
34
+ * generics of the styled API (kept in sync with the React runtime).
35
+ */
36
+ type AnyComponent<T> = (props: T) => JSX.Element;
37
+ /**
38
+ * Style object the runtime writes CSS custom properties into.
39
+ * Solid also allows string styles on elements; the runtime normalizes
40
+ * those to objects before processing (see `unwrapStyle` in styled.ts).
41
+ */
42
+ type StyleObject = JSX.CSSProperties & Record<`--${string}`, string | number | undefined>;
43
+ /**
44
+ * Main styled interface that combines HTML tag mappings with the styled function.
45
+ * This is the primary entry point for creating styled components.
46
+ */
47
+ interface Styled extends MappedHtmlTags, StyledFn {}
48
+ /**
49
+ * Function interface for creating styled components from any component or HTML tag.
50
+ * Supports Solid components, HTML tags, and custom web components.
51
+ */
52
+ interface StyledFn {
53
+ <TProps extends object = JSX.ElementAttributes<Element>>(Component: HtmlTags | AnyComponent<TProps> | CustomWebComponentTag): LiteralWithAttrs<TProps>;
54
+ }
55
+ /**
56
+ * A yak component with a special symbol that allows component targeting
57
+ * and proper attrs function handling.
58
+ * @example styled.svg`${Button}:hover & { fill: red; }` or styled(Button)`color: red;`
59
+ */
60
+ interface YakComponent<T> extends AnyComponent<T> {
61
+ [yakComponentSymbol]: [unknown, unknown, unknown, unknown];
62
+ }
63
+ /**
64
+ * Styled component with attrs method for adding default props.
65
+ * Extends StyledLiteral with the ability to specify default attributes.
66
+ */
67
+ interface LiteralWithAttrs<T extends object> extends StyledLiteral<T> {
68
+ attrs: <TAttrsIn extends object = {}, TAttrsOut extends AttrsMerged<T, TAttrsIn> = AttrsMerged<T, TAttrsIn>>(attrs: Attrs<T, TAttrsIn, TAttrsOut>) => StyledLiteral<Substitute<T, TAttrsIn>>;
69
+ }
70
+ /**
71
+ * Template literal function for defining CSS styles with interpolation support.
72
+ * Accepts CSS template strings and interpolated values with proper typing.
73
+ */
74
+ interface StyledLiteral<T> {
75
+ <TCSSProps>(styles: TemplateStringsArray, ...values: Array<CSSInterpolation<T & NoInfer<TCSSProps> & {
76
+ theme: Accessor<YakTheme>;
77
+ }>>): YakComponent<TCSSProps & T>;
78
+ }
79
+ /**
80
+ * Function variant of attrs that receives current props and returns additional props.
81
+ * Allows for dynamic prop generation based on component state.
82
+ */
83
+ interface AttrsFunction<TBaseProps, TIn extends object = {}, TOut extends AttrsMerged<TBaseProps, TIn> = AttrsMerged<TBaseProps, TIn>> {
84
+ (p: Substitute<TBaseProps & {
85
+ theme: Accessor<YakTheme>;
86
+ }, TIn>): Partial<TOut>;
87
+ }
88
+ /**
89
+ * Merges provided props with initial props, making specified props optional.
90
+ * Includes theme support for styled components.
91
+ */
92
+ type AttrsMerged<TBaseProps, TIn extends object = {}> = Substitute<TBaseProps & {
93
+ theme?: Accessor<YakTheme>;
94
+ }, TIn>;
95
+ /**
96
+ * Maps all HTML tag names to their corresponding styled component types with attributes support.
97
+ * Provides typed access to all standard HTML elements through the styled interface.
98
+ */
99
+ type MappedHtmlTags = { [Tag in HtmlTags]: LiteralWithAttrs<JSX.IntrinsicElements[Tag]> };
100
+ /**
101
+ * The attrs function allows adding additional props to a styled component.
102
+ * Props can be specified as an object or as a function that receives current props.
103
+ */
104
+ type Attrs<TBaseProps, TIn extends object = {}, TOut extends AttrsMerged<TBaseProps, TIn> = AttrsMerged<TBaseProps, TIn>> = Partial<TOut> | AttrsFunction<TBaseProps, TIn, TOut>;
105
+ /**
106
+ * Utility type to merge two object types, with properties from B taking precedence.
107
+ * If a property exists in both A and B, the property from B is used.
108
+ */
109
+ type Substitute<A extends object, B extends object> = FastOmit<A, keyof B> & B;
110
+ /**
111
+ * Union type of all valid HTML element tag names.
112
+ * Derived from Solid's JSX intrinsic elements.
113
+ */
114
+ type HtmlTags = keyof JSX.IntrinsicElements;
115
+ /**
116
+ * Custom web component tag pattern that must contain at least one hyphen.
117
+ * Follows the web component naming convention.
118
+ */
119
+ type CustomWebComponentTag = `${string}-${string}`;
120
+ /**
121
+ * Utility type to efficiently remove properties from an object type.
122
+ * More performant than the built-in Omit type for large object types.
123
+ */
124
+ type FastOmit<T extends object, U extends string | number | symbol> = { [K in keyof T as K extends U ? never : K]: T[K] };
125
+ /**
126
+ * Set-like collector for class names.
127
+ *
128
+ * Implemented as a string builder in the runtime (a Set<string>
129
+ * split → Set → Array.from → join round-trip dominates render cost);
130
+ * a real Set<string> also satisfies this interface.
131
+ */
132
+ type ClassCollector = {
133
+ add(name: string): void;
134
+ has(name: string): boolean;
135
+ delete(name: string): void;
136
+ };
137
+ /**
138
+ * Type of all functions that can be passed to manipulate styles
139
+ *
140
+ * `$dynamic` marks processors that execute user functions or write style
141
+ * values at render time; purely static processors (class names only) can
142
+ * skip theme lookup and style-object allocation.
143
+ */
144
+ type RuntimeStyleProcessor<T> = ((props: T, classes: ClassCollector, style: StyleObject) => void) & {
145
+ $dynamic?: boolean;
146
+ };
147
+ /**
148
+ * Utility type to keep the generic API of a component while still being able to use it in a selector
149
+ */
150
+ type GenericYakComponentOf<T, P = {}> = T & YakComponent<P> & {
151
+ <G = {}>(props: P & G): JSX.Element;
152
+ };
153
+ //#endregion
154
+ //#region runtime/cssLiteral.d.ts
155
+ declare const yakComponentSymbol: unique symbol;
156
+ type ComponentStyles<TProps> = (props: TProps) => {
157
+ class: string;
158
+ style?: {
159
+ [key: string]: string;
160
+ };
161
+ };
162
+ type CSSInterpolation<TProps> = string | number | undefined | null | false | ComponentStyles<TProps> | {
163
+ [yakComponentSymbol]: any;
164
+ } | ((props: TProps) => CSSInterpolation<TProps>);
165
+ /**
166
+ * css() runtime factory of css``
167
+ *
168
+ * /!\ @yak/solid transpiles css`` and styled``
169
+ *
170
+ * This changes the typings of the css`` and styled`` functions.
171
+ * During development the user of @yak/solid wants to work with the
172
+ * typings BEFORE compilation.
173
+ *
174
+ * Therefore this is only an internal function only and it must be cast to any
175
+ * before exported to the user.
176
+ *
177
+ * The internal functioning of css`` is to return a single callback function that runs all functions
178
+ * (or creates new ones if needed) that are passed as arguments. These functions receive the props, classes, and style object as arguments
179
+ * and operate directly on the classes and style objects.
180
+ */
181
+ declare function css$1<TProps>(styles: TemplateStringsArray, ...values: CSSInterpolation<NoInfer<TProps> & {
182
+ theme: Accessor<YakTheme>;
183
+ }>[]): ComponentStyles<TProps>;
184
+ //#endregion
185
+ //#region runtime/cssProp.d.ts
186
+ declare module "@solidjs/web" {
187
+ namespace JSX {
188
+ interface ElementAttributes<T> {
189
+ css?: ComponentStyles<{}>;
190
+ }
191
+ }
192
+ }
193
+ //#endregion
194
+ //#region runtime/atoms.d.ts
195
+ /**
196
+ * Allows to use atomic CSS classes in a styled or css block
197
+ *
198
+ * @usage
199
+ *
200
+ * ```tsx
201
+ * import { styled, atoms } from "@yak/solid";
202
+ *
203
+ * const Button = styled.button<{ $primary?: boolean }>`
204
+ * ${atoms("text-teal-600", "text-base", "rounded-md")}
205
+ * ${props => props.$primary && atoms("shadow-md")}
206
+ * `;
207
+ * ```
208
+ */
209
+ declare const atoms: <T>(...atoms: (string | RuntimeStyleProcessor<T> | false)[]) => ComponentStyles<T>;
210
+ //#endregion
211
+ //#region runtime/mocks/cssLiteral.d.ts
212
+ /**
213
+ * Allows to use CSS styles in a styled or css block
214
+ *
215
+ * e.g.
216
+ *
217
+ * ```tsx
218
+ * const Component = styled.div`
219
+ * color: black;
220
+ * ${({$active}) => $active && css`color: red;`}
221
+ * `;
222
+ * ```
223
+ */
224
+ declare const css: typeof css$1;
225
+ //#endregion
226
+ //#region runtime/keyframes.d.ts
227
+ /**
228
+ * Allows to use CSS keyframe animations in a styled or css block
229
+ *
230
+ * @usage
231
+ *
232
+ * ```tsx
233
+ * import { styled, keyframes } from "@yak/solid";
234
+ *
235
+ * const rotate = keyframes`
236
+ * from {
237
+ * transform: rotate(0deg);
238
+ * }
239
+ * to {
240
+ * transform: rotate(360deg);
241
+ * }
242
+ * `;
243
+ *
244
+ * const Spinner = styled.div`
245
+ * animation: ${rotate} 1s linear infinite;
246
+ * `;
247
+ * ```
248
+ */
249
+ declare const keyframes$1: <T extends (string | number | bigint)[] = never>(styles: TemplateStringsArray, ..._dynamic: T) => string;
250
+ //#endregion
251
+ //#region runtime/mocks/keyframes.d.ts
252
+ /**
253
+ * Allows to use CSS keyframe animations in a styled or css block
254
+ *
255
+ * @usage
256
+ *
257
+ * ```tsx
258
+ * import { styled, keyframes } from "@yak/solid";
259
+ *
260
+ * const rotate = keyframes`
261
+ * from {
262
+ * transform: rotate(0deg);
263
+ * }
264
+ * to {
265
+ * transform: rotate(360deg);
266
+ * }
267
+ * `;
268
+ *
269
+ * const Spinner = styled.div`
270
+ * animation: ${rotate} 1s linear infinite;
271
+ * `;
272
+ * ```
273
+ */
274
+ declare const keyframes: typeof keyframes$1;
275
+ //#endregion
276
+ //#region runtime/styled.d.ts
277
+ /**
278
+ * The `styled` method works perfectly on all of your own or any third-party component,
279
+ * as long as they attach the passed `class` prop to a DOM element.
280
+ *
281
+ * @usage
282
+ *
283
+ * ```tsx
284
+ * const StyledLink = styled(Link)`
285
+ * color: #BF4F74;
286
+ * font-weight: bold;
287
+ * `;
288
+ * ```
289
+ */
290
+ declare const styled$1: Styled;
291
+ //#endregion
292
+ //#region runtime/mocks/styled.d.ts
293
+ declare const styled: typeof styled$1;
294
+ //#endregion
295
+ //#region runtime/globalStyle.d.ts
296
+ /**
297
+ * Values that may be interpolated into a `globalStyle` template.
298
+ *
299
+ * Only build-time values are allowed: constants, `keyframes` animation names,
300
+ * static `css` mixins and styled-component selectors. Runtime functions
301
+ * (`${(props) => ...}`) are intentionally excluded: a global rule has no element
302
+ * to attach a CSS variable to. Declare a CSS custom property instead and toggle
303
+ * it via an attribute/class on the root element.
304
+ */
305
+ type GlobalStyleInterpolation = string | number | ComponentStyles<{}> | YakComponent<any>;
306
+ /**
307
+ * Declares global, unscoped styles that ride the same zero-runtime extraction
308
+ * pipeline as `styled` and `keyframes`.
309
+ *
310
+ * Global styles are **part of the stylesheet, not part of the render tree**.
311
+ * They apply exactly when the module declaring them is included in the bundle,
312
+ * typically by importing it from a layout or entry point. They cannot be
313
+ * conditionally mounted; express conditions in CSS (`@media`, `@supports`,
314
+ * `:root[data-theme]`, `:has()`) or through CSS custom properties.
315
+ *
316
+ * @usage
317
+ *
318
+ * ```tsx
319
+ * import { globalStyle, keyframes } from "@yak/solid";
320
+ *
321
+ * const fadeIn = keyframes`
322
+ * from { opacity: 0; }
323
+ * `;
324
+ *
325
+ * globalStyle`
326
+ * :root {
327
+ * --spacing: 4px;
328
+ * }
329
+ *
330
+ * body {
331
+ * margin: 0;
332
+ * }
333
+ *
334
+ * ::view-transition-new(root) {
335
+ * animation: ${fadeIn} 200ms ease;
336
+ * }
337
+ * `;
338
+ * ```
339
+ */
340
+ declare const globalStyle$1: (_styles: TemplateStringsArray, ..._values: Array<GlobalStyleInterpolation>) => void;
341
+ //#endregion
342
+ //#region runtime/mocks/globalStyle.d.ts
343
+ /**
344
+ * Test-friendly mock of `globalStyle`.
345
+ *
346
+ * `globalStyle` has no runtime behaviour: the SWC plugin extracts its CSS at
347
+ * build time and replaces the call with a no-op. The mock mirrors that: it does
348
+ * nothing so yak files can be imported in Jest/Vitest without the compiler.
349
+ */
350
+ declare const globalStyle: typeof globalStyle$1;
351
+ //#endregion
352
+ export { type GenericYakComponentOf, type GlobalStyleInterpolation, type YakComponent, type YakTheme, YakThemeContext, YakThemeProvider, atoms, css, globalStyle, keyframes, styled, useTheme };
package/dist/index.js ADDED
@@ -0,0 +1,2 @@
1
+ import{YakThemeContext as e,YakThemeProvider as t,useTheme as n,useTheme as r}from"@yak/solid/context";import{createMemo as i,merge as a}from"solid-js";import{Dynamic as o,createComponent as s}from"@solidjs/web";const c=Symbol(`yak`);var l=class{value;constructor(e){this.value=e||``}add(e){this.value?this.has(e)||(this.value+=` `+e):this.value=e}has(e){return(` `+this.value+` `).includes(` `+e+` `)}delete(e){this.has(e)&&(this.value=this.value.split(` `).filter(t=>t!==e).join(` `))}};function u(...e){let t,n=[];for(let r of e)typeof r==`string`?t=r:typeof r==`function`?n.push(r):typeof r==`object`&&`style`in r&&n.push((e,t,n)=>{for(let t in r.style){let i=r.style[t];typeof i==`function`?n[t]=String(f(e,i)):n[t]=String(i)}});return n.length===0?Object.assign((e,n)=>{t&&n.add(t)},{$dynamic:!1}):Object.assign((e,r,i)=>{t&&r.add(t);for(let t=0;t<n.length;t++)d(e,n[t],r,i)},{$dynamic:!0})}const d=(e,t,n,r)=>{let i=t(e,n,r);for(;i;){if(typeof i==`function`){i=i(e,n,r);continue}else if(typeof i==`object`){let e=`class`in i?i.class:void 0;if(e&&n.add(e),`style`in i&&i.style)for(let e in i.style)r[e]=i.style[e]}break}},f=(e,t)=>{let n=t(e);if(typeof n==`function`)return f(e,n);if(typeof n!=`string`&&typeof n!=`number`&&!(n instanceof String)&&process.env.NODE_ENV===`development`)throw Error(`Dynamic CSS functions must return a string or number but returned ${JSON.stringify(n)}\n\nDynamic CSS function: ${t.toString()}\n`);return n},p=(...e)=>{let t=[],n=[];for(let r of e)typeof r==`string`?t.push(...r.split(` `)):typeof r==`function`&&n.push(r);return u(...t.length>0?[(e,n)=>{t.forEach(e=>n.add(e))},...n]:n)},m=(e,...t)=>{if(Array.isArray(e)&&`raw`in e){let n=e[0];for(let r=0;r<t.length;r++){let i=t[r];n+=i&&typeof i==`object`&&`__yak`in i?i.__yak:String(i),n+=e[r+1]}return{__yak:n}}let n=[];for(let e of t)typeof e==`function`&&n.push(e);return n.length===0?{class:``,style:void 0}:(e=>{for(let t=0;t<n.length;t++)h(e,n[t]);return{class:``,style:void 0}})};function h(e,t){let n=new Set,r={},i=t(e,n,r);for(;typeof i==`function`;)i=i(e,n,r);return i}const g=(e,...t)=>``,_=e=>e?typeof e==`string`?e:Array.isArray(e)?e.map(_).filter(Boolean).join(` `):typeof e==`object`?Object.keys(e).filter(t=>e[t]).join(` `):String(e):``,v=e=>s(o,e),y=e=>Object.assign(b(e),{attrs:t=>b(e,t)}),b=(e,t)=>{let n=typeof e==`function`&&e[c]!==void 0,[,o,d,f]=n?e[c]:[],p=n?f:e,m=E(t,o);return(e,...t)=>{let n=D(u(e,...t),d),o=typeof p==`string`,f=o?{component:p}:{},h=o?v:e=>s(p,e),g=!m&&!n.$dynamic?e=>h(C(a(e,f,{get class(){let t=new l(_(e.class));return n(e,t,void 0),t.value||void 0}}))):e=>{let t=r(),o=a({theme:t},e),s=m?i(()=>m(o)):void 0,c=s?a(o,s):o,u=i(()=>{let t=s?.(),r=new l(_(e.class)),i=_(t?.class);i&&r.add(i);let a=n.$dynamic||t?.style?{...x(e.style),...x(t?.style)}:x(e.style);return n(c,r,a),{class:r.value||void 0,style:a&&Object.keys(a).length>0?a:void 0}});return h(C(a(a(e,s??{},{get class(){return u().class},get style(){return u().style}}),f),()=>{let e=s?.();return!!e&&`theme`in e&&e.theme!==t}))};return Object.assign(g,{[c]:[g,m,n,p]})}},x=e=>{if(typeof e!=`string`)return e;let t={};for(let n of e.split(`;`)){let e=n.indexOf(`:`);if(e===-1)continue;let r=n.slice(0,e).trim(),i=n.slice(e+1).trim();r&&i&&(t[r]=i)}return t},S=(e,t)=>typeof e==`string`&&(e.startsWith(`$`)||e===`theme`&&!(t&&t())),C=(e,t)=>new Proxy(e,{get:(e,n)=>S(n,t)?void 0:Reflect.get(e,n),has:(e,n)=>!S(n,t)&&Reflect.has(e,n),ownKeys:e=>Reflect.ownKeys(e).filter(e=>!S(e,t)),getOwnPropertyDescriptor:(e,n)=>S(n,t)?void 0:Reflect.getOwnPropertyDescriptor(e,n)}),w=(e,t)=>{if(!(!e&&!t))return e?t?e+` `+t:e:t},T=(e,t)=>t?(e.class===t.class||!t.class)&&(e.style===t.style||!t.style)?{...e,...t}:{...e,...t,class:w(e.class,t.class),style:{...x(e.style),...x(t.style)}}:e,E=(e,t)=>{let n=e&&(typeof e==`function`?e:()=>e);return n&&t?e=>{let r=t(e);return T(r,n(T(e,r)))}:n||t},D=(e,t)=>e&&t?Object.assign((n,r,i)=>{t(n,r,i),e(n,r,i)},{$dynamic:e.$dynamic||t.$dynamic}):e||t,O=new Proxy(y,{get(e,t){return e(t)}}),k=(e,...t)=>{};export{e as YakThemeContext,t as YakThemeProvider,p as atoms,m as css,k as globalStyle,g as keyframes,O as styled,n as useTheme};
2
+ //# sourceMappingURL=index.js.map