chaincss 2.0.7 → 2.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.
Files changed (159) hide show
  1. package/CHANGELOG.md +30 -0
  2. package/CODE_OF_CONDUCT.md +21 -0
  3. package/CONTRIBUTING.md +28 -0
  4. package/README.md +455 -226
  5. package/demo/demo/node_modules/caniuse-db/fulldata-json/data-2.0.json +1 -0
  6. package/demo/index.html +16 -0
  7. package/demo/package.json +20 -0
  8. package/demo/src/App.tsx +117 -0
  9. package/demo/src/chaincss-barrel.ts +9 -0
  10. package/demo/src/main.tsx +8 -0
  11. package/demo/src/styles.chain.ts +300 -0
  12. package/demo/vite.config.ts +46 -0
  13. package/dist/cli/commands/build.d.ts +0 -1
  14. package/dist/cli/commands/cache.d.ts +1 -0
  15. package/dist/cli/commands/init.d.ts +6 -3
  16. package/dist/cli/commands/timeline.d.ts +0 -1
  17. package/dist/cli/commands/watch.d.ts +0 -1
  18. package/dist/cli/index.d.ts +0 -1
  19. package/dist/cli/index.js +3213 -5296
  20. package/dist/cli/types.d.ts +51 -20
  21. package/dist/cli/utils/config-loader.d.ts +0 -1
  22. package/dist/cli/utils/file-utils.d.ts +27 -3
  23. package/dist/cli/utils/logger.d.ts +0 -1
  24. package/dist/compiler/Chain.d.ts +215 -0
  25. package/dist/compiler/animations.d.ts +76 -0
  26. package/dist/compiler/atomic-optimizer.d.ts +47 -12
  27. package/dist/compiler/breakpoints.d.ts +46 -0
  28. package/dist/compiler/btt.d.ts +36 -60
  29. package/dist/compiler/cache-manager.d.ts +58 -4
  30. package/dist/compiler/commonProps.d.ts +0 -1
  31. package/dist/compiler/content-addressable-cache.d.ts +78 -0
  32. package/dist/compiler/helpers.d.ts +54 -0
  33. package/dist/compiler/index.d.ts +16 -9
  34. package/dist/compiler/index.js +4450 -4316
  35. package/dist/compiler/prefixer.d.ts +17 -1
  36. package/dist/compiler/shorthands.d.ts +28 -0
  37. package/dist/compiler/suggestions.d.ts +43 -0
  38. package/dist/compiler/theme-contract.d.ts +16 -27
  39. package/dist/compiler/token-resolver.d.ts +69 -0
  40. package/dist/compiler/tokens.d.ts +33 -8
  41. package/dist/core/auto-detector.d.ts +34 -0
  42. package/dist/core/common-utils.d.ts +97 -0
  43. package/dist/core/compiler.d.ts +63 -23
  44. package/dist/core/constants.d.ts +137 -36
  45. package/dist/core/smart-chain.d.ts +3 -0
  46. package/dist/core/types.d.ts +122 -15
  47. package/dist/core/utils.d.ts +134 -17
  48. package/dist/index.d.ts +52 -8
  49. package/dist/index.js +7090 -5578
  50. package/dist/plugins/vite.d.ts +7 -5
  51. package/dist/plugins/vite.js +2964 -25641
  52. package/dist/plugins/webpack.d.ts +24 -1
  53. package/dist/plugins/webpack.js +209 -72
  54. package/dist/runtime/Chain.d.ts +32 -0
  55. package/dist/runtime/auto-hooks.d.ts +11 -0
  56. package/dist/runtime/hmr.d.ts +22 -2
  57. package/dist/runtime/index.d.ts +3 -2
  58. package/dist/runtime/index.js +3648 -301
  59. package/dist/runtime/injector.d.ts +39 -72
  60. package/dist/runtime/react.d.ts +17 -12
  61. package/dist/runtime/svelte.d.ts +15 -0
  62. package/dist/runtime/types.d.ts +126 -4
  63. package/dist/runtime/utils.d.ts +0 -1
  64. package/dist/runtime/vue.d.ts +34 -14
  65. package/package.json +59 -66
  66. package/src/cli/commands/build.ts +133 -0
  67. package/src/cli/commands/cache.ts +371 -0
  68. package/src/cli/commands/init.ts +230 -0
  69. package/src/cli/commands/timeline.ts +435 -0
  70. package/src/cli/commands/watch.ts +211 -0
  71. package/src/cli/index.ts +226 -0
  72. package/src/cli/types.ts +100 -0
  73. package/src/cli/utils/config-loader.ts +174 -0
  74. package/src/cli/utils/file-utils.ts +139 -0
  75. package/src/cli/utils/logger.ts +74 -0
  76. package/src/compiler/Chain.ts +831 -0
  77. package/src/compiler/animations.ts +517 -0
  78. package/src/compiler/atomic-optimizer.ts +786 -0
  79. package/src/compiler/breakpoints.ts +347 -0
  80. package/src/compiler/btt.ts +1147 -0
  81. package/src/compiler/cache-manager.ts +446 -0
  82. package/src/compiler/commonProps.ts +18 -0
  83. package/src/compiler/content-addressable-cache.ts +478 -0
  84. package/src/compiler/helpers.ts +407 -0
  85. package/src/compiler/index.ts +72 -0
  86. package/src/compiler/prefixer.ts +724 -0
  87. package/src/compiler/shorthands.ts +558 -0
  88. package/src/compiler/suggestions.ts +436 -0
  89. package/src/compiler/theme-contract.ts +197 -0
  90. package/src/compiler/token-resolver.ts +241 -0
  91. package/src/compiler/tokens.ts +612 -0
  92. package/src/core/auto-detector.ts +187 -0
  93. package/src/core/common-utils.ts +423 -0
  94. package/src/core/compiler.ts +835 -0
  95. package/src/core/constants.ts +424 -0
  96. package/src/core/index.ts +107 -0
  97. package/src/core/smart-chain.ts +163 -0
  98. package/src/core/types.ts +257 -0
  99. package/src/core/utils.ts +598 -0
  100. package/src/index.ts +208 -0
  101. package/src/plugins/vite.d.ts +316 -0
  102. package/src/plugins/vite.ts +424 -0
  103. package/src/plugins/webpack.d.ts +289 -0
  104. package/src/plugins/webpack.ts +416 -0
  105. package/src/runtime/Chain.ts +242 -0
  106. package/src/runtime/auto-hooks.tsx +127 -0
  107. package/src/runtime/auto-vue.ts +72 -0
  108. package/src/runtime/hmr.ts +212 -0
  109. package/src/runtime/index.ts +82 -0
  110. package/src/runtime/injector.ts +273 -0
  111. package/src/runtime/react.tsx +269 -0
  112. package/src/runtime/svelte.ts +15 -0
  113. package/src/runtime/types.ts +256 -0
  114. package/src/runtime/utils.ts +128 -0
  115. package/src/runtime/vite-env.d.ts +120 -0
  116. package/src/runtime/vue.ts +231 -0
  117. package/tsconfig.build.json +41 -0
  118. package/tsconfig.json +25 -0
  119. package/tsconfig.runtimes.json +18 -0
  120. package/dist/cli/cli.cjs +0 -7
  121. package/dist/cli/commands/build.d.ts.map +0 -1
  122. package/dist/cli/commands/compile.d.ts +0 -3
  123. package/dist/cli/commands/compile.d.ts.map +0 -1
  124. package/dist/cli/commands/init.d.ts.map +0 -1
  125. package/dist/cli/commands/timeline.d.ts.map +0 -1
  126. package/dist/cli/commands/watch.d.ts.map +0 -1
  127. package/dist/cli/index.d.ts.map +0 -1
  128. package/dist/cli/types.d.ts.map +0 -1
  129. package/dist/cli/utils/config-loader.d.ts.map +0 -1
  130. package/dist/cli/utils/file-utils.d.ts.map +0 -1
  131. package/dist/cli/utils/logger.d.ts.map +0 -1
  132. package/dist/compiler/atomic-optimizer.d.ts.map +0 -1
  133. package/dist/compiler/btt.d.ts.map +0 -1
  134. package/dist/compiler/cache-manager.d.ts.map +0 -1
  135. package/dist/compiler/commonProps.d.ts.map +0 -1
  136. package/dist/compiler/index.d.ts.map +0 -1
  137. package/dist/compiler/prefixer.d.ts.map +0 -1
  138. package/dist/compiler/theme-contract.d.ts.map +0 -1
  139. package/dist/compiler/tokens.d.ts.map +0 -1
  140. package/dist/compiler/types.d.ts +0 -57
  141. package/dist/compiler/types.d.ts.map +0 -1
  142. package/dist/core/compiler.d.ts.map +0 -1
  143. package/dist/core/constants.d.ts.map +0 -1
  144. package/dist/core/index.d.ts +0 -4
  145. package/dist/core/index.d.ts.map +0 -1
  146. package/dist/core/types.d.ts.map +0 -1
  147. package/dist/core/utils.d.ts.map +0 -1
  148. package/dist/index.d.ts.map +0 -1
  149. package/dist/plugins/vite.d.ts.map +0 -1
  150. package/dist/plugins/webpack.d.ts.map +0 -1
  151. package/dist/runtime/hmr.d.ts.map +0 -1
  152. package/dist/runtime/index.d.ts.map +0 -1
  153. package/dist/runtime/injector.d.ts.map +0 -1
  154. package/dist/runtime/react.d.ts.map +0 -1
  155. package/dist/runtime/react.js +0 -324
  156. package/dist/runtime/types.d.ts.map +0 -1
  157. package/dist/runtime/utils.d.ts.map +0 -1
  158. package/dist/runtime/vue.d.ts.map +0 -1
  159. package/dist/runtime/vue.js +0 -286
@@ -0,0 +1,273 @@
1
+ // src/runtime/injector.ts (fixed version)
2
+
3
+ import { shorthandMap, macros } from '../compiler/shorthands.js';
4
+ import { processStyleObject } from '../core/common-utils.js';
5
+
6
+ const TOKEN_V2_KEY = '__CHAINCSS_V2_TOKENS__';
7
+
8
+ export interface StyleDefinition {
9
+ selectors?: string[];
10
+ hover?: Record<string, string | number>;
11
+ [key: string]: any;
12
+ }
13
+
14
+ export interface TokenStore {
15
+ colors?: Record<string, string>;
16
+ spacing?: Record<string, string>;
17
+ typography?: Record<string, any>;
18
+ [key: string]: any;
19
+ }
20
+
21
+ class StyleInjector {
22
+ private styleElement: HTMLStyleElement | null = null;
23
+ private injectedHashes = new Set<string>();
24
+ private moduleMap = new Map<string, Set<string>>();
25
+ private debugMode = false;
26
+
27
+ private get tokenStore(): TokenStore {
28
+ // Handle non-browser environments (SSR)
29
+ if (typeof window === 'undefined') {
30
+ return (this as any)._internalFallbackStore || {};
31
+ }
32
+
33
+ // Defensive initialization
34
+ if (!(window as any)[TOKEN_V2_KEY]) {
35
+ Object.defineProperty(window, TOKEN_V2_KEY, {
36
+ value: {},
37
+ writable: true,
38
+ enumerable: false,
39
+ configurable: true
40
+ });
41
+ }
42
+
43
+ return (window as any)[TOKEN_V2_KEY];
44
+ }
45
+
46
+ constructor() {
47
+ if (typeof document !== 'undefined') {
48
+ const existing = document.getElementById('chaincss-runtime-styles');
49
+ if (existing) {
50
+ this.styleElement = existing as HTMLStyleElement;
51
+ } else {
52
+ const style = document.createElement('style');
53
+ style.id = 'chaincss-runtime-styles';
54
+ style.setAttribute('data-chaincss', 'runtime');
55
+ document.head.appendChild(style);
56
+ this.styleElement = style;
57
+ }
58
+ }
59
+ }
60
+
61
+ /**
62
+ * Enable debug logging
63
+ */
64
+ enableDebug(enable: boolean = true): void {
65
+ this.debugMode = enable;
66
+ }
67
+
68
+ /**
69
+ * Set global tokens (e.g., brand colors, spacing scales)
70
+ */
71
+ setTokens(tokens: TokenStore): void {
72
+ if (this.debugMode) {
73
+ console.log('[ChainCSS] Tokens set:', Object.keys(tokens));
74
+ }
75
+ Object.assign(this.tokenStore, tokens);
76
+ }
77
+
78
+ /**
79
+ * Get a token value by path
80
+ */
81
+ getToken(path: string): any {
82
+ const parts = path.split('.');
83
+ let current: any = this.tokenStore;
84
+ for (const part of parts) {
85
+ if (current && current[part] !== undefined) {
86
+ current = current[part];
87
+ } else {
88
+ return undefined;
89
+ }
90
+ }
91
+ return current;
92
+ }
93
+
94
+ /**
95
+ * Resolves $variables within a string using the tokenStore
96
+ */
97
+ resolveToken(value: any): any {
98
+ if (typeof value !== 'string') return value;
99
+
100
+ // Exact match: "$colors.primary"
101
+ if (value.startsWith('$')) {
102
+ const tokenValue = this.getToken(value.slice(1));
103
+ return tokenValue !== undefined ? tokenValue : value;
104
+ }
105
+
106
+ // Partial match: "1px solid $colors.primary"
107
+ return value.replace(/\$([a-zA-Z0-9.-]+)/g, (match, path) => {
108
+ const tokenValue = this.getToken(path);
109
+ return tokenValue !== undefined ? String(tokenValue) : match;
110
+ });
111
+ }
112
+
113
+ private generateCSS(style: StyleDefinition, className: string): string {
114
+ let css = '';
115
+ const selector = `.${className}`;
116
+
117
+ // Process style object (handles shorthands and tokens)
118
+ const mainBody = processStyleObject(style, this.tokenStore, { useTokens: true, debug: false });
119
+ if (mainBody && Object.keys(mainBody).length > 0) {
120
+ let rules = '';
121
+ for (const [prop, val] of Object.entries(mainBody)) {
122
+ rules += ` ${prop}: ${val};\n`;
123
+ }
124
+ css += `${selector} {\n${rules}}\n`;
125
+ }
126
+
127
+ // Handle Hover
128
+ if (style.hover) {
129
+ const hoverBody = processStyleObject(style.hover, this.tokenStore, { useTokens: true, debug: false });
130
+ if (hoverBody && Object.keys(hoverBody).length > 0) {
131
+ let rules = '';
132
+ for (const [prop, val] of Object.entries(hoverBody)) {
133
+ rules += ` ${prop}: ${val};\n`;
134
+ }
135
+ css += `${selector}:hover {\n${rules}}\n`;
136
+ }
137
+ }
138
+
139
+ return css;
140
+ }
141
+
142
+ injectMultiple(styles: Record<string, StyleDefinition>, moduleId?: string): Record<string, string> {
143
+ const result: Record<string, string> = {};
144
+ let newCSS = '';
145
+ const moduleClasses = new Set<string>();
146
+
147
+ for (const [name, style] of Object.entries(styles)) {
148
+ const className = name;
149
+ result[name] = className;
150
+
151
+ if (!this.injectedHashes.has(className)) {
152
+ const generatedCSS = this.generateCSS(style, className);
153
+ if (generatedCSS) {
154
+ newCSS += generatedCSS;
155
+ this.injectedHashes.add(className);
156
+ }
157
+ }
158
+ moduleClasses.add(className);
159
+ }
160
+
161
+ if (moduleId && moduleClasses.size > 0) {
162
+ this.moduleMap.set(moduleId, moduleClasses);
163
+ }
164
+
165
+ if (newCSS) {
166
+ this.writeToDOM(newCSS);
167
+ if (this.debugMode) {
168
+ console.log(`[ChainCSS] Injected ${newCSS.length} bytes of CSS (${moduleId || 'anonymous'})`);
169
+ }
170
+ }
171
+
172
+ return result;
173
+ }
174
+
175
+ writeToDOM(css: string): void {
176
+ if (css && this.styleElement) {
177
+ this.styleElement.textContent += css;
178
+ }
179
+ }
180
+
181
+ removeModule(moduleId: string): void {
182
+ const classes = this.moduleMap.get(moduleId);
183
+ if (!classes || !this.styleElement?.sheet) return;
184
+
185
+ const sheet = this.styleElement.sheet;
186
+ let removedCount = 0;
187
+
188
+ for (let i = sheet.cssRules.length - 1; i >= 0; i--) {
189
+ const rule = sheet.cssRules[i] as CSSStyleRule;
190
+ if (rule.selectorText) {
191
+ const match = rule.selectorText.match(/\.([a-zA-Z0-9_-]+)/);
192
+ if (match && classes.has(match[1])) {
193
+ sheet.deleteRule(i);
194
+ this.injectedHashes.delete(match[1]);
195
+ removedCount++;
196
+ }
197
+ }
198
+ }
199
+
200
+ this.moduleMap.delete(moduleId);
201
+
202
+ if (this.debugMode) {
203
+ console.log(`[ChainCSS] Removed ${removedCount} rules for module ${moduleId}`);
204
+ }
205
+ }
206
+
207
+ removeAll(): void {
208
+ if (this.styleElement) {
209
+ this.styleElement.textContent = '';
210
+ this.injectedHashes.clear();
211
+ this.moduleMap.clear();
212
+
213
+ if (this.debugMode) {
214
+ console.log('[ChainCSS] All runtime styles removed');
215
+ }
216
+ }
217
+ }
218
+
219
+ getStyleElement(): HTMLStyleElement | null {
220
+ return this.styleElement;
221
+ }
222
+
223
+ getStats(): { injectedStyles: number; modules: number } {
224
+ return {
225
+ injectedStyles: this.injectedHashes.size,
226
+ modules: this.moduleMap.size
227
+ };
228
+ }
229
+ }
230
+
231
+ // --- SINGLETON INSTANCE ---
232
+ export const styleInjector = new StyleInjector();
233
+
234
+ // --- PUBLIC API ---
235
+ export const setTokens = (t: TokenStore) => styleInjector.setTokens(t);
236
+ export const compileRuntime = (s: Record<string, StyleDefinition>, moduleId?: string) =>
237
+ styleInjector.injectMultiple(s, moduleId);
238
+ export const removeRuntimeModule = (moduleId: string) => styleInjector.removeModule(moduleId);
239
+ export const clearRuntimeStyles = () => styleInjector.removeAll();
240
+ export const enableRuntimeDebug = (enabled: boolean) => styleInjector.enableDebug(enabled);
241
+
242
+ export function runRuntime(...styles: StyleDefinition[]): string {
243
+ let css = '';
244
+ for (const style of styles) {
245
+ if (style.selectors && style.selectors.length > 0) {
246
+ const combinedSelector = style.selectors.join(', ');
247
+
248
+ // Use styleInjector directly instead of 'this'
249
+ const mainBody = processStyleObject(style, styleInjector['tokenStore'], { useTokens: true, debug: false });
250
+
251
+ if (mainBody && Object.keys(mainBody).length > 0) {
252
+ let rules = '';
253
+ for (const [prop, val] of Object.entries(mainBody)) {
254
+ rules += ` ${prop}: ${val};\n`;
255
+ }
256
+ css += `${combinedSelector} {\n${rules}}\n`;
257
+ }
258
+
259
+ if (style.hover) {
260
+ const hoverBody = processStyleObject(style.hover, styleInjector['tokenStore'], { useTokens: true, debug: false });
261
+ if (hoverBody && Object.keys(hoverBody).length > 0) {
262
+ let rules = '';
263
+ for (const [prop, val] of Object.entries(hoverBody)) {
264
+ rules += ` ${prop}: ${val};\n`;
265
+ }
266
+ css += `${combinedSelector}:hover {\n${rules}}\n`;
267
+ }
268
+ }
269
+ }
270
+ }
271
+ styleInjector.writeToDOM(css);
272
+ return css;
273
+ }
@@ -0,0 +1,269 @@
1
+ // src/runtime/react.tsx (fixed version)
2
+
3
+ import React, { useMemo, useRef, useState, useEffect } from 'react';
4
+ import { compileRuntime, setTokens as setGlobalTokens, removeRuntimeModule } from './injector.js';
5
+ import { RuntimeChain } from './Chain.js';
6
+
7
+ export interface UseChainStylesOptions {
8
+ cache?: boolean;
9
+ namespace?: string;
10
+ watch?: boolean;
11
+ debug?: boolean;
12
+ ssr?: boolean;
13
+ }
14
+
15
+ // Better hash function with lower collision risk
16
+ function hashStyleObject(obj: Record<string, any>): string {
17
+ const str = JSON.stringify(obj);
18
+ let hash = 0;
19
+ for (let i = 0; i < str.length; i++) {
20
+ const char = str.charCodeAt(i);
21
+ hash = ((hash << 5) - hash) + char;
22
+ hash = hash & hash; // Convert to 32-bit integer
23
+ }
24
+ return Math.abs(hash).toString(36);
25
+ }
26
+
27
+ /**
28
+ * React hook for ChainCSS runtime styles
29
+ */
30
+ export function useChainStyles(
31
+ styles: Record<string, any>,
32
+ deps: any[] = [],
33
+ options: UseChainStylesOptions = {}
34
+ ): Record<string, string> {
35
+ const { namespace = 'c', debug = false, ssr = false } = options;
36
+ const instanceId = useRef(Math.random().toString(36).substring(2, 7));
37
+ const moduleId = useRef(`chaincss-module-${instanceId.current}`);
38
+ const [forceUpdate, setForceUpdate] = useState(0);
39
+
40
+ // Cleanup on unmount
41
+ useEffect(() => {
42
+ return () => {
43
+ if (!ssr && moduleId.current) {
44
+ removeRuntimeModule(moduleId.current);
45
+ if (debug) {
46
+ console.log(`[ChainCSS] Cleaned up module: ${moduleId.current}`);
47
+ }
48
+ }
49
+ };
50
+ }, [ssr]);
51
+
52
+ return useMemo(() => {
53
+ const finalClassMap: Record<string, string> = {};
54
+ const injectionBundle: Record<string, any> = {};
55
+
56
+ for (const [key, styleDef] of Object.entries(styles)) {
57
+ let styleObject: Record<string, any> = {};
58
+
59
+ if (styleDef && typeof (styleDef as any).$el === 'function') {
60
+ styleObject = (styleDef as any).$el();
61
+ if (debug) {
62
+ console.log(`[ChainCSS] Processing style: ${key}`, styleObject);
63
+ }
64
+ } else if (styleDef && typeof styleDef === 'object') {
65
+ styleObject = { ...styleDef };
66
+ }
67
+
68
+ // Remove internal keys
69
+ const staticClasses = Array.isArray(styleObject._classes) ? styleObject._classes : [];
70
+ const internalKeys = ['catcher', 'proxy', 'useTokens', 'componentName', '_isChain', '_classes', '_name'];
71
+ internalKeys.forEach(k => delete styleObject[k]);
72
+
73
+ // Generate stable hash
74
+ const hash = hashStyleObject(styleObject);
75
+ const dynamicClassName = `${namespace}-${key}-${hash}`;
76
+
77
+ // Check if there are actual styles
78
+ const hasStyles = Object.keys(styleObject).length > 0;
79
+
80
+ if (!ssr && hasStyles) {
81
+ injectionBundle[dynamicClassName] = styleObject;
82
+ }
83
+
84
+ // Combine static and dynamic classes
85
+ const classParts = [...staticClasses];
86
+ if (hasStyles) {
87
+ classParts.push(dynamicClassName);
88
+ }
89
+ finalClassMap[key] = classParts.join(' ').trim();
90
+ }
91
+
92
+ // Inject all styles at once
93
+ if (!ssr && Object.keys(injectionBundle).length > 0) {
94
+ compileRuntime(injectionBundle, moduleId.current);
95
+ if (debug) {
96
+ console.log(`[ChainCSS] Injected ${Object.keys(injectionBundle).length} styles for module ${moduleId.current}`);
97
+ }
98
+ }
99
+
100
+ return finalClassMap;
101
+ }, [forceUpdate, ...deps]);
102
+ }
103
+
104
+ /**
105
+ * Dynamic styles hook - re-runs when deps change
106
+ */
107
+ export function useDynamicChainStyles(
108
+ styleFactory: () => Record<string, any>,
109
+ deps: any[] = [],
110
+ options?: UseChainStylesOptions
111
+ ): Record<string, string> {
112
+ const styles = useMemo(() => styleFactory(), deps);
113
+ return useChainStyles(styles, deps, options);
114
+ }
115
+
116
+ /**
117
+ * Theme-aware styles hook
118
+ */
119
+ export function useThemeChainStyles(
120
+ styles: Record<string, any> | ((theme: any) => Record<string, any>),
121
+ theme: any,
122
+ options?: UseChainStylesOptions
123
+ ): Record<string, string> {
124
+ const themedStyles = useMemo(() => {
125
+ if (typeof styles === 'function') return styles(theme);
126
+ return styles;
127
+ }, [styles, theme]);
128
+ return useChainStyles(themedStyles, [theme], options);
129
+ }
130
+
131
+ /**
132
+ * Global style injection component
133
+ */
134
+ export function ChainCSSGlobal({ styles, tokens, children }: {
135
+ styles?: Record<string, any>;
136
+ tokens?: any;
137
+ children?: React.ReactNode;
138
+ }) {
139
+ if (tokens) {
140
+ setGlobalTokens(tokens);
141
+ }
142
+
143
+ if (styles) {
144
+ useChainStyles(styles, [], { watch: true });
145
+ }
146
+
147
+ return <>{children}</>;
148
+ }
149
+
150
+ /**
151
+ * Class name utility (like clsx)
152
+ */
153
+ export function cx(...classes: (string | undefined | null | false | Record<string, boolean>)[]): string {
154
+ const result: string[] = [];
155
+
156
+ for (const cls of classes) {
157
+ if (!cls) continue;
158
+ if (typeof cls === 'string') {
159
+ result.push(cls);
160
+ } else if (typeof cls === 'object') {
161
+ for (const [key, value] of Object.entries(cls)) {
162
+ if (value) result.push(key);
163
+ }
164
+ }
165
+ }
166
+
167
+ return result.join(' ');
168
+ }
169
+
170
+ /**
171
+ * HOC for class components
172
+ */
173
+ export function withChainStyles<P extends object>(
174
+ styles: Record<string, any> | ((props: P) => Record<string, any>),
175
+ options?: UseChainStylesOptions
176
+ ) {
177
+ return function WrappedComponent(props: P & { chainStyles?: Record<string, string> }) {
178
+ const styleProps = typeof styles === 'function' ? styles(props) : styles;
179
+ const classNames = useChainStyles(styleProps, [], options);
180
+ const Component = (props as any).component || (props as any).wrappedComponent;
181
+ return <Component {...props} chainStyles={classNames} />;
182
+ };
183
+ }
184
+
185
+ /**
186
+ * Create a styled component (React)
187
+ */
188
+ export function createStyledComponent<T extends keyof React.JSX.IntrinsicElements = "div">(
189
+ elementType: T,
190
+ styles: Record<string, any> | (() => Record<string, any>),
191
+ options?: UseChainStylesOptions
192
+ ): React.FC<React.ComponentProps<T> & { className?: string }> {
193
+ const StyledComponent: React.FC<any> = (props) => {
194
+ const { className: additionalClassName, ...rest } = props;
195
+ const styleDef = typeof styles === 'function' ? styles() : styles;
196
+ const classNames = useChainStyles({ root: styleDef }, [], options);
197
+
198
+ const combinedClassName = cx(classNames.root, additionalClassName);
199
+
200
+ return React.createElement(elementType, {
201
+ ...rest,
202
+ className: combinedClassName
203
+ });
204
+ };
205
+
206
+ const displayName = typeof elementType === 'string' ? elementType : (elementType as any).displayName || 'Component';
207
+ StyledComponent.displayName = `ChainCSS.${displayName}`;
208
+
209
+ return StyledComponent;
210
+ }
211
+
212
+ /**
213
+ * Create multiple styled components at once
214
+ */
215
+ export function createStyledComponents(components: Record<string, any>): Record<string, React.FC> {
216
+ const result: Record<string, React.FC> = {};
217
+
218
+ for (const [name, config] of Object.entries(components)) {
219
+ const { element = 'div', styles, options } = config as any;
220
+ result[name] = createStyledComponent(element, styles, options);
221
+ }
222
+
223
+ return result;
224
+ }
225
+
226
+ /**
227
+ * CSS-in-JS hook with computed styles
228
+ */
229
+ export function useComputedStyles<T extends Record<string, any>>(
230
+ styles: (props: T) => Record<string, any>,
231
+ props: T,
232
+ deps: any[] = [],
233
+ options?: UseChainStylesOptions
234
+ ): Record<string, string> {
235
+ const computedStyles = useMemo(() => styles(props), [props, ...deps]);
236
+ return useChainStyles(computedStyles, deps, options);
237
+ }
238
+
239
+ /**
240
+ * Set global tokens from React
241
+ */
242
+ export function setTokens(tokens: any): void {
243
+ setGlobalTokens(tokens);
244
+ }
245
+
246
+ /**
247
+ * Debug utilities
248
+ */
249
+ let debugEnabled = false;
250
+
251
+ export function enableChainCSSDebug(): void {
252
+ debugEnabled = true;
253
+ if (typeof window !== 'undefined') {
254
+ (window as any).__CHAINCSS_DEBUG__ = true;
255
+ console.log('🔍 ChainCSS Debug Mode Enabled');
256
+ }
257
+ }
258
+
259
+ export function disableChainCSSDebug(): void {
260
+ debugEnabled = false;
261
+ if (typeof window !== 'undefined') {
262
+ (window as any).__CHAINCSS_DEBUG__ = false;
263
+ console.log('🔍 ChainCSS Debug Mode Disabled');
264
+ }
265
+ }
266
+
267
+ export function isDebugEnabled(): boolean {
268
+ return debugEnabled || (typeof window !== 'undefined' && (window as any).__CHAINCSS_DEBUG__);
269
+ }
@@ -0,0 +1,15 @@
1
+ // Svelte integration — optional peer dependency
2
+ // @ts-nocheck
3
+ import { onDestroy, getContext, setContext } from 'svelte';
4
+ import { writable, derived, type Writable, type Readable, get } from 'svelte/store';
5
+ import { compileRuntime, styleInjector, removeRuntimeModule } from './injector.js';
6
+
7
+ export function useAtomicClasses() { return { subscribe: () => {}, get: () => ({}) }; }
8
+ export function cx(...args: any[]) { return args.filter(Boolean).join(' '); }
9
+ export function ChainCSSGlobal() { return null; }
10
+ export function createStyledComponent() { return () => null; }
11
+ export function createStyledComponents() { return {}; }
12
+ export function useComputedStyles() { return { subscribe: () => {}, get: () => '' }; }
13
+ export function provideStyleContext() {}
14
+ export function injectStyleContext() { return {}; }
15
+ export function chainStyles() { return {}; }