stoop 0.3.0 → 0.4.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 +125 -0
- package/dist/api/core-api.d.ts +34 -0
- package/dist/api/{keyframes.js → core-api.js} +45 -5
- package/dist/api/global-css.js +11 -58
- package/dist/api/styled.d.ts +0 -1
- package/dist/api/styled.js +265 -16
- package/dist/api/theme-provider.d.ts +41 -0
- package/dist/api/theme-provider.js +223 -0
- package/dist/constants.d.ts +11 -1
- package/dist/constants.js +11 -1
- package/dist/core/compiler.d.ts +11 -0
- package/dist/core/compiler.js +15 -7
- package/dist/core/theme-manager.d.ts +34 -3
- package/dist/core/theme-manager.js +55 -45
- package/dist/core/variants.js +9 -3
- package/dist/create-stoop-internal.d.ts +30 -0
- package/dist/create-stoop-internal.js +123 -0
- package/dist/create-stoop-ssr.d.ts +10 -0
- package/dist/create-stoop-ssr.js +26 -0
- package/dist/create-stoop.d.ts +32 -1
- package/dist/create-stoop.js +78 -69
- package/dist/inject.d.ts +113 -0
- package/dist/inject.js +308 -0
- package/dist/types/index.d.ts +147 -12
- package/dist/types/react-polymorphic-types.d.ts +13 -2
- package/dist/utils/auto-preload.d.ts +45 -0
- package/dist/utils/auto-preload.js +167 -0
- package/dist/utils/helpers.d.ts +64 -0
- package/dist/utils/helpers.js +150 -0
- package/dist/utils/storage.d.ts +148 -0
- package/dist/utils/storage.js +396 -0
- package/dist/utils/{string.d.ts → theme-utils.d.ts} +20 -3
- package/dist/utils/{string.js → theme-utils.js} +109 -9
- package/dist/utils/theme.d.ts +14 -2
- package/dist/utils/theme.js +41 -16
- package/package.json +48 -23
- package/dist/api/create-theme.d.ts +0 -13
- package/dist/api/create-theme.js +0 -43
- package/dist/api/css.d.ts +0 -16
- package/dist/api/css.js +0 -20
- package/dist/api/keyframes.d.ts +0 -16
- package/dist/api/provider.d.ts +0 -19
- package/dist/api/provider.js +0 -109
- package/dist/api/use-theme.d.ts +0 -13
- package/dist/api/use-theme.js +0 -21
- package/dist/create-stoop-server.d.ts +0 -33
- package/dist/create-stoop-server.js +0 -130
- package/dist/index.d.ts +0 -6
- package/dist/index.js +0 -5
- package/dist/inject/browser.d.ts +0 -58
- package/dist/inject/browser.js +0 -149
- package/dist/inject/dedup.d.ts +0 -29
- package/dist/inject/dedup.js +0 -38
- package/dist/inject/index.d.ts +0 -40
- package/dist/inject/index.js +0 -75
- package/dist/inject/ssr.d.ts +0 -27
- package/dist/inject/ssr.js +0 -46
- package/dist/ssr.d.ts +0 -21
- package/dist/ssr.js +0 -19
- package/dist/utils/environment.d.ts +0 -6
- package/dist/utils/environment.js +0 -12
- package/dist/utils/theme-map.d.ts +0 -22
- package/dist/utils/theme-map.js +0 -97
- package/dist/utils/theme-validation.d.ts +0 -13
- package/dist/utils/theme-validation.js +0 -36
- package/dist/utils/type-guards.d.ts +0 -26
- package/dist/utils/type-guards.js +0 -38
- package/dist/utils/utilities.d.ts +0 -14
- package/dist/utils/utilities.js +0 -43
package/dist/utils/theme.js
CHANGED
|
@@ -3,24 +3,17 @@
|
|
|
3
3
|
* Converts theme tokens to CSS variables for runtime theme switching.
|
|
4
4
|
* Uses cached token index for efficient lookups and theme comparison.
|
|
5
5
|
*/
|
|
6
|
-
import {
|
|
7
|
-
import { getScaleForProperty } from "./theme-
|
|
8
|
-
import { isCSSObject, isThemeObject } from "./type-guards";
|
|
9
|
-
const tokenIndexCache = new WeakMap();
|
|
6
|
+
import { isCSSObject, isThemeObject, isProduction } from "./helpers";
|
|
7
|
+
import { escapeCSSVariableValue, getScaleForProperty, sanitizeCSSVariableName, } from "./theme-utils";
|
|
10
8
|
// Pre-compiled regex for token replacement (matches $primary, -$medium, $colors.primary, etc.)
|
|
11
9
|
const TOKEN_REGEX = /(-?\$[a-zA-Z][a-zA-Z0-9]*(?:\$[a-zA-Z][a-zA-Z0-9]*)?(?:\.[a-zA-Z][a-zA-Z0-9]*)?)/g;
|
|
12
10
|
/**
|
|
13
11
|
* Builds an index of all tokens in a theme for fast lookups.
|
|
14
|
-
* Caches the result to avoid rebuilding on every token resolution.
|
|
15
12
|
*
|
|
16
13
|
* @param theme - Theme to index
|
|
17
14
|
* @returns Map of token names to their paths in the theme
|
|
18
15
|
*/
|
|
19
16
|
function buildTokenIndex(theme) {
|
|
20
|
-
const cached = tokenIndexCache.get(theme);
|
|
21
|
-
if (cached) {
|
|
22
|
-
return cached;
|
|
23
|
-
}
|
|
24
17
|
const index = new Map();
|
|
25
18
|
function processThemeObject(obj, path = []) {
|
|
26
19
|
const keys = Object.keys(obj);
|
|
@@ -55,7 +48,6 @@ function buildTokenIndex(theme) {
|
|
|
55
48
|
});
|
|
56
49
|
}
|
|
57
50
|
}
|
|
58
|
-
tokenIndexCache.set(theme, index);
|
|
59
51
|
return index;
|
|
60
52
|
}
|
|
61
53
|
/**
|
|
@@ -162,7 +154,7 @@ export function tokenToCSSVar(token, theme, property, themeMap) {
|
|
|
162
154
|
const index = buildTokenIndex(theme);
|
|
163
155
|
const paths = index.get(tokenName);
|
|
164
156
|
if (paths && paths.length > 1) {
|
|
165
|
-
if (
|
|
157
|
+
if (!isProduction()) {
|
|
166
158
|
const scaleInfo = scale
|
|
167
159
|
? `Property "${property}" maps to "${scale}" scale, but token not found there. `
|
|
168
160
|
: `No scale mapping found for property "${property}". `;
|
|
@@ -184,7 +176,7 @@ export function tokenToCSSVar(token, theme, property, themeMap) {
|
|
|
184
176
|
const index = buildTokenIndex(theme);
|
|
185
177
|
const paths = index.get(tokenName);
|
|
186
178
|
if (paths && paths.length > 1) {
|
|
187
|
-
if (
|
|
179
|
+
if (!isProduction()) {
|
|
188
180
|
// eslint-disable-next-line no-console
|
|
189
181
|
console.warn(`[Stoop] Ambiguous token "$${tokenName}" found in multiple categories: ${paths.map((p) => p.join(".")).join(", ")}. ` +
|
|
190
182
|
`Using "${paths[0].join(".")}" (deterministic: shorter paths first, then alphabetical). ` +
|
|
@@ -207,10 +199,11 @@ export function tokenToCSSVar(token, theme, property, themeMap) {
|
|
|
207
199
|
*
|
|
208
200
|
* @param theme - Theme object to convert to CSS variables
|
|
209
201
|
* @param prefix - Optional prefix for CSS variable names
|
|
210
|
-
* @
|
|
202
|
+
* @param attributeSelector - Optional attribute selector (e.g., '[data-theme="light"]'). Defaults to ':root'
|
|
203
|
+
* @returns CSS string with selector and CSS variables
|
|
211
204
|
*/
|
|
212
|
-
export function generateCSSVariables(theme, prefix = "stoop") {
|
|
213
|
-
const rootSelector = ":root";
|
|
205
|
+
export function generateCSSVariables(theme, prefix = "stoop", attributeSelector) {
|
|
206
|
+
const rootSelector = attributeSelector || ":root";
|
|
214
207
|
const variables = [];
|
|
215
208
|
function processThemeObject(obj, path = []) {
|
|
216
209
|
const keys = Object.keys(obj).sort();
|
|
@@ -240,6 +233,27 @@ export function generateCSSVariables(theme, prefix = "stoop") {
|
|
|
240
233
|
}
|
|
241
234
|
return `${rootSelector} {\n${variables.join("\n")}\n}`;
|
|
242
235
|
}
|
|
236
|
+
/**
|
|
237
|
+
* Generates CSS custom properties for all themes using attribute selectors.
|
|
238
|
+
* This allows all themes to be available simultaneously, with theme switching
|
|
239
|
+
* handled by changing the data-theme attribute.
|
|
240
|
+
*
|
|
241
|
+
* @param themes - Map of theme names to theme objects
|
|
242
|
+
* @param prefix - Optional prefix for CSS variable names
|
|
243
|
+
* @param attribute - Attribute name for theme selection (defaults to 'data-theme')
|
|
244
|
+
* @returns CSS string with all theme CSS variables
|
|
245
|
+
*/
|
|
246
|
+
export function generateAllThemeVariables(themes, prefix = "stoop", attribute = "data-theme") {
|
|
247
|
+
const themeBlocks = [];
|
|
248
|
+
for (const [themeName, theme] of Object.entries(themes)) {
|
|
249
|
+
const attributeSelector = `[${attribute}="${themeName}"]`;
|
|
250
|
+
const cssVars = generateCSSVariables(theme, prefix, attributeSelector);
|
|
251
|
+
if (cssVars) {
|
|
252
|
+
themeBlocks.push(cssVars);
|
|
253
|
+
}
|
|
254
|
+
}
|
|
255
|
+
return themeBlocks.join("\n\n");
|
|
256
|
+
}
|
|
243
257
|
/**
|
|
244
258
|
* Recursively replaces theme tokens with CSS variable references in a CSS object.
|
|
245
259
|
*
|
|
@@ -254,13 +268,20 @@ export function replaceThemeTokensWithVars(obj, theme, themeMap, property) {
|
|
|
254
268
|
return obj;
|
|
255
269
|
}
|
|
256
270
|
const result = {};
|
|
271
|
+
let hasTokens = false;
|
|
257
272
|
const keys = Object.keys(obj).sort();
|
|
258
273
|
for (const key of keys) {
|
|
259
274
|
const value = obj[key];
|
|
260
275
|
if (isCSSObject(value)) {
|
|
261
|
-
|
|
276
|
+
const processed = replaceThemeTokensWithVars(value, theme, themeMap, undefined);
|
|
277
|
+
result[key] = processed;
|
|
278
|
+
// Check if processing changed anything (indicates tokens were found)
|
|
279
|
+
if (processed !== value) {
|
|
280
|
+
hasTokens = true;
|
|
281
|
+
}
|
|
262
282
|
}
|
|
263
283
|
else if (typeof value === "string" && value.includes("$")) {
|
|
284
|
+
hasTokens = true;
|
|
264
285
|
const cssProperty = property || key;
|
|
265
286
|
result[key] = value.replace(TOKEN_REGEX, (token) => {
|
|
266
287
|
if (token.startsWith("-$")) {
|
|
@@ -275,5 +296,9 @@ export function replaceThemeTokensWithVars(obj, theme, themeMap, property) {
|
|
|
275
296
|
result[key] = value;
|
|
276
297
|
}
|
|
277
298
|
}
|
|
299
|
+
// Early exit: if no tokens were found, return original object to avoid unnecessary copying
|
|
300
|
+
if (!hasTokens) {
|
|
301
|
+
return obj;
|
|
302
|
+
}
|
|
278
303
|
return result;
|
|
279
304
|
}
|
package/package.json
CHANGED
|
@@ -1,9 +1,10 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "stoop",
|
|
3
3
|
"description": "CSS-in-JS library with type inference, theme creation, and variants support.",
|
|
4
|
-
"version": "0.
|
|
4
|
+
"version": "0.4.0",
|
|
5
5
|
"author": "Jackson Dolman <mail@dolmios.com>",
|
|
6
|
-
"main": "./dist/
|
|
6
|
+
"main": "./dist/create-stoop.js",
|
|
7
|
+
"types": "./dist/create-stoop.d.ts",
|
|
7
8
|
"repository": {
|
|
8
9
|
"type": "git",
|
|
9
10
|
"url": "https://github.com/dolmios/stoop.git"
|
|
@@ -16,24 +17,48 @@
|
|
|
16
17
|
"react-polymorphic-types": "^2.0.0"
|
|
17
18
|
},
|
|
18
19
|
"devDependencies": {
|
|
19
|
-
"@types/node": "^
|
|
20
|
-
"@types/react": "^19.
|
|
21
|
-
"@types/react-dom": "^19.
|
|
22
|
-
"bun-types": "^1.
|
|
23
|
-
"typescript": "^5.
|
|
20
|
+
"@types/node": "^25.0.3",
|
|
21
|
+
"@types/react": "^19.2.7",
|
|
22
|
+
"@types/react-dom": "^19.2.3",
|
|
23
|
+
"bun-types": "^1.3.5",
|
|
24
|
+
"typescript": "^5.9.3"
|
|
24
25
|
},
|
|
25
26
|
"exports": {
|
|
26
27
|
".": {
|
|
27
|
-
"types": "./dist/
|
|
28
|
-
"import": "./dist/
|
|
29
|
-
"require": "./dist/
|
|
30
|
-
"default": "./dist/
|
|
28
|
+
"types": "./dist/create-stoop.d.ts",
|
|
29
|
+
"import": "./dist/create-stoop.js",
|
|
30
|
+
"require": "./dist/create-stoop.js",
|
|
31
|
+
"default": "./dist/create-stoop.js"
|
|
32
|
+
},
|
|
33
|
+
"./utils/storage": {
|
|
34
|
+
"types": "./dist/utils/storage.d.ts",
|
|
35
|
+
"import": "./dist/utils/storage.js",
|
|
36
|
+
"require": "./dist/utils/storage.js",
|
|
37
|
+
"default": "./dist/utils/storage.js"
|
|
38
|
+
},
|
|
39
|
+
"./utils/auto-preload": {
|
|
40
|
+
"types": "./dist/utils/auto-preload.d.ts",
|
|
41
|
+
"import": "./dist/utils/auto-preload.js",
|
|
42
|
+
"require": "./dist/utils/auto-preload.js",
|
|
43
|
+
"default": "./dist/utils/auto-preload.js"
|
|
44
|
+
},
|
|
45
|
+
"./types": {
|
|
46
|
+
"types": "./dist/types/index.d.ts",
|
|
47
|
+
"import": "./dist/types/index.js",
|
|
48
|
+
"require": "./dist/types/index.js",
|
|
49
|
+
"default": "./dist/types/index.js"
|
|
50
|
+
},
|
|
51
|
+
"./inject": {
|
|
52
|
+
"types": "./dist/inject.d.ts",
|
|
53
|
+
"import": "./dist/inject.js",
|
|
54
|
+
"require": "./dist/inject.js",
|
|
55
|
+
"default": "./dist/inject.js"
|
|
31
56
|
},
|
|
32
57
|
"./ssr": {
|
|
33
|
-
"types": "./dist/ssr.d.ts",
|
|
34
|
-
"import": "./dist/ssr.js",
|
|
35
|
-
"require": "./dist/ssr.js",
|
|
36
|
-
"default": "./dist/ssr.js"
|
|
58
|
+
"types": "./dist/create-stoop-ssr.d.ts",
|
|
59
|
+
"import": "./dist/create-stoop-ssr.js",
|
|
60
|
+
"require": "./dist/create-stoop-ssr.js",
|
|
61
|
+
"default": "./dist/create-stoop-ssr.js"
|
|
37
62
|
}
|
|
38
63
|
},
|
|
39
64
|
"files": [
|
|
@@ -71,18 +96,18 @@
|
|
|
71
96
|
"react": ">=16.8.0",
|
|
72
97
|
"react-dom": ">=16.8.0"
|
|
73
98
|
},
|
|
99
|
+
"sideEffects": false,
|
|
100
|
+
"type": "module",
|
|
74
101
|
"scripts": {
|
|
75
|
-
"build": "bun run build:clean && bun run build:types",
|
|
102
|
+
"build": "bun run build:clean && bun run build:js && bun run build:js:ssr && bun run build:types",
|
|
76
103
|
"build:clean": "rm -rf dist",
|
|
77
104
|
"build:copy-declarations": "mkdir -p dist/types && cp src/types/react-polymorphic-types.d.ts dist/types/react-polymorphic-types.d.ts 2>/dev/null || :",
|
|
78
|
-
"build:js": "NODE_ENV=production bun build ./src/
|
|
105
|
+
"build:js": "NODE_ENV=production bun build ./src/create-stoop.ts --outdir ./dist --target node --minify --jsx=automatic --splitting --external react --external react-dom --external react/jsx-runtime --define process.env.NODE_ENV='\"production\"'",
|
|
106
|
+
"build:js:ssr": "NODE_ENV=production bun build ./src/create-stoop-ssr.ts --outdir ./dist --target node --minify --jsx=automatic --external react --external react-dom --external react/jsx-runtime --define process.env.NODE_ENV='\"production\"'",
|
|
79
107
|
"build:types": "bunx tsc --project tsconfig.build.json && bun run build:copy-declarations",
|
|
80
|
-
"
|
|
108
|
+
"lint": "eslint src --fix",
|
|
81
109
|
"test": "bun test",
|
|
82
110
|
"test:coverage": "bun test --coverage",
|
|
83
111
|
"test:watch": "bun test --watch"
|
|
84
|
-
}
|
|
85
|
-
|
|
86
|
-
"type": "module"
|
|
87
|
-
}
|
|
88
|
-
|
|
112
|
+
}
|
|
113
|
+
}
|
|
@@ -1,13 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Theme extension API.
|
|
3
|
-
* Creates a function that deep merges theme overrides with a base theme.
|
|
4
|
-
*/
|
|
5
|
-
import type { Theme } from "../types";
|
|
6
|
-
/**
|
|
7
|
-
* Creates a function that extends a base theme with overrides.
|
|
8
|
-
* The returned function deep merges theme overrides with the base theme.
|
|
9
|
-
*
|
|
10
|
-
* @param baseTheme - Base theme to extend
|
|
11
|
-
* @returns Function that accepts theme overrides and returns a merged theme
|
|
12
|
-
*/
|
|
13
|
-
export declare function createTheme(baseTheme: Theme): (themeOverrides: Partial<Theme>) => Theme;
|
package/dist/api/create-theme.js
DELETED
|
@@ -1,43 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Theme extension API.
|
|
3
|
-
* Creates a function that deep merges theme overrides with a base theme.
|
|
4
|
-
*/
|
|
5
|
-
import { validateTheme } from "../utils/theme-validation";
|
|
6
|
-
import { isThemeObject } from "../utils/type-guards";
|
|
7
|
-
/**
|
|
8
|
-
* Creates a function that extends a base theme with overrides.
|
|
9
|
-
* The returned function deep merges theme overrides with the base theme.
|
|
10
|
-
*
|
|
11
|
-
* @param baseTheme - Base theme to extend
|
|
12
|
-
* @returns Function that accepts theme overrides and returns a merged theme
|
|
13
|
-
*/
|
|
14
|
-
export function createTheme(baseTheme) {
|
|
15
|
-
return function createTheme(themeOverrides) {
|
|
16
|
-
const validatedOverrides = validateTheme(themeOverrides);
|
|
17
|
-
function deepMerge(target, source) {
|
|
18
|
-
const result = { ...target };
|
|
19
|
-
const sourceKeys = Object.keys(source);
|
|
20
|
-
for (const key of sourceKeys) {
|
|
21
|
-
const sourceValue = source[key];
|
|
22
|
-
const targetValue = target[key];
|
|
23
|
-
if (isThemeObject(sourceValue) && isThemeObject(targetValue)) {
|
|
24
|
-
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
25
|
-
result[key] = { ...targetValue, ...sourceValue };
|
|
26
|
-
}
|
|
27
|
-
else if (sourceValue !== undefined) {
|
|
28
|
-
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
29
|
-
result[key] = sourceValue;
|
|
30
|
-
}
|
|
31
|
-
}
|
|
32
|
-
const targetKeys = Object.keys(target);
|
|
33
|
-
for (const key of targetKeys) {
|
|
34
|
-
if (!(key in result)) {
|
|
35
|
-
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
36
|
-
result[key] = target[key];
|
|
37
|
-
}
|
|
38
|
-
}
|
|
39
|
-
return result;
|
|
40
|
-
}
|
|
41
|
-
return deepMerge(baseTheme, validatedOverrides);
|
|
42
|
-
};
|
|
43
|
-
}
|
package/dist/api/css.d.ts
DELETED
|
@@ -1,16 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* CSS class generation API.
|
|
3
|
-
* Creates a function that compiles CSS objects into class names.
|
|
4
|
-
*/
|
|
5
|
-
import type { CSS, Theme, ThemeScale, UtilityFunction } from "../types";
|
|
6
|
-
/**
|
|
7
|
-
* Creates a CSS function that compiles CSS objects into class names.
|
|
8
|
-
*
|
|
9
|
-
* @param defaultTheme - Default theme for token resolution
|
|
10
|
-
* @param prefix - Optional prefix for generated class names
|
|
11
|
-
* @param media - Optional media query breakpoints
|
|
12
|
-
* @param utils - Optional utility functions
|
|
13
|
-
* @param themeMap - Optional theme scale mappings
|
|
14
|
-
* @returns Function that accepts CSS objects and returns class names
|
|
15
|
-
*/
|
|
16
|
-
export declare function createCSSFunction(defaultTheme: Theme, prefix?: string, media?: Record<string, string>, utils?: Record<string, UtilityFunction>, themeMap?: Record<string, ThemeScale>): (styles: CSS) => string;
|
package/dist/api/css.js
DELETED
|
@@ -1,20 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* CSS class generation API.
|
|
3
|
-
* Creates a function that compiles CSS objects into class names.
|
|
4
|
-
*/
|
|
5
|
-
import { compileCSS } from "../core/compiler";
|
|
6
|
-
/**
|
|
7
|
-
* Creates a CSS function that compiles CSS objects into class names.
|
|
8
|
-
*
|
|
9
|
-
* @param defaultTheme - Default theme for token resolution
|
|
10
|
-
* @param prefix - Optional prefix for generated class names
|
|
11
|
-
* @param media - Optional media query breakpoints
|
|
12
|
-
* @param utils - Optional utility functions
|
|
13
|
-
* @param themeMap - Optional theme scale mappings
|
|
14
|
-
* @returns Function that accepts CSS objects and returns class names
|
|
15
|
-
*/
|
|
16
|
-
export function createCSSFunction(defaultTheme, prefix = "stoop", media, utils, themeMap) {
|
|
17
|
-
return function css(styles) {
|
|
18
|
-
return compileCSS(styles, defaultTheme, prefix, media, utils, themeMap);
|
|
19
|
-
};
|
|
20
|
-
}
|
package/dist/api/keyframes.d.ts
DELETED
|
@@ -1,16 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* CSS keyframes animation API.
|
|
3
|
-
* Creates a function that generates and injects @keyframes rules.
|
|
4
|
-
* Caches animations by content hash to prevent duplicates.
|
|
5
|
-
*/
|
|
6
|
-
import type { CSS, Theme, ThemeScale } from "../types";
|
|
7
|
-
/**
|
|
8
|
-
* Creates a keyframes animation function.
|
|
9
|
-
* Generates and injects @keyframes rules with caching to prevent duplicates.
|
|
10
|
-
*
|
|
11
|
-
* @param prefix - Optional prefix for animation names
|
|
12
|
-
* @param theme - Optional theme for token resolution
|
|
13
|
-
* @param themeMap - Optional theme scale mappings
|
|
14
|
-
* @returns Function that accepts keyframes objects and returns animation names
|
|
15
|
-
*/
|
|
16
|
-
export declare function createKeyframesFunction(prefix?: string, theme?: Theme, themeMap?: Record<string, ThemeScale>): (keyframes: Record<string, CSS>) => string;
|
package/dist/api/provider.d.ts
DELETED
|
@@ -1,19 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Theme Provider component.
|
|
3
|
-
* Manages theme state, localStorage persistence, and centralized theme variable updates.
|
|
4
|
-
*/
|
|
5
|
-
import { type ComponentType, type Context } from "react";
|
|
6
|
-
import type { ProviderProps, Theme, ThemeContextValue, ThemeManagementContextValue } from "../types";
|
|
7
|
-
/**
|
|
8
|
-
* Creates a Provider component for theme management.
|
|
9
|
-
*
|
|
10
|
-
* @param themes - Map of theme names to theme objects
|
|
11
|
-
* @param defaultTheme - Default theme object
|
|
12
|
-
* @param prefix - Optional prefix for CSS variable scoping
|
|
13
|
-
* @returns Provider component, theme context, and theme management context
|
|
14
|
-
*/
|
|
15
|
-
export declare function createProvider(themes: Record<string, Theme>, defaultTheme: Theme, prefix?: string): {
|
|
16
|
-
Provider: ComponentType<ProviderProps>;
|
|
17
|
-
ThemeContext: Context<ThemeContextValue | null>;
|
|
18
|
-
ThemeManagementContext: Context<ThemeManagementContextValue | null>;
|
|
19
|
-
};
|
package/dist/api/provider.js
DELETED
|
@@ -1,109 +0,0 @@
|
|
|
1
|
-
"use client";
|
|
2
|
-
import { jsx as _jsx } from "react/jsx-runtime";
|
|
3
|
-
/**
|
|
4
|
-
* Theme Provider component.
|
|
5
|
-
* Manages theme state, localStorage persistence, and centralized theme variable updates.
|
|
6
|
-
*/
|
|
7
|
-
import { createContext, useCallback, useLayoutEffect, useMemo, useState, } from "react";
|
|
8
|
-
import { updateThemeVariables } from "../core/theme-manager";
|
|
9
|
-
import { isBrowser } from "../utils/environment";
|
|
10
|
-
/**
|
|
11
|
-
* Creates a Provider component for theme management.
|
|
12
|
-
*
|
|
13
|
-
* @param themes - Map of theme names to theme objects
|
|
14
|
-
* @param defaultTheme - Default theme object
|
|
15
|
-
* @param prefix - Optional prefix for CSS variable scoping
|
|
16
|
-
* @returns Provider component, theme context, and theme management context
|
|
17
|
-
*/
|
|
18
|
-
export function createProvider(themes, defaultTheme, prefix = "stoop") {
|
|
19
|
-
const ThemeContext = createContext(null);
|
|
20
|
-
const ThemeManagementContext = createContext(null);
|
|
21
|
-
const availableThemeNames = Object.keys(themes);
|
|
22
|
-
const firstThemeName = availableThemeNames[0] || "default";
|
|
23
|
-
function Provider({ attribute = "data-theme", children, defaultTheme: defaultThemeProp, storageKey = "stoop-theme", }) {
|
|
24
|
-
// SSR-safe initialization: always start with default, then hydrate from localStorage
|
|
25
|
-
const [themeName, setThemeNameState] = useState(() => {
|
|
26
|
-
// During SSR, always return the default theme
|
|
27
|
-
if (!isBrowser()) {
|
|
28
|
-
return defaultThemeProp || firstThemeName;
|
|
29
|
-
}
|
|
30
|
-
// On client, try to read from localStorage
|
|
31
|
-
try {
|
|
32
|
-
const stored = localStorage.getItem(storageKey);
|
|
33
|
-
if (stored && themes[stored]) {
|
|
34
|
-
return stored;
|
|
35
|
-
}
|
|
36
|
-
}
|
|
37
|
-
catch {
|
|
38
|
-
// localStorage access failed (e.g., in private browsing mode)
|
|
39
|
-
}
|
|
40
|
-
return defaultThemeProp || firstThemeName;
|
|
41
|
-
});
|
|
42
|
-
// Hydrate from localStorage after mount to prevent hydration mismatch
|
|
43
|
-
useLayoutEffect(() => {
|
|
44
|
-
if (!isBrowser()) {
|
|
45
|
-
return;
|
|
46
|
-
}
|
|
47
|
-
try {
|
|
48
|
-
const stored = localStorage.getItem(storageKey);
|
|
49
|
-
if (stored && themes[stored] && stored !== themeName) {
|
|
50
|
-
setThemeNameState(stored);
|
|
51
|
-
}
|
|
52
|
-
}
|
|
53
|
-
catch {
|
|
54
|
-
// localStorage access failed
|
|
55
|
-
}
|
|
56
|
-
}, [storageKey, themeName]);
|
|
57
|
-
const currentTheme = useMemo(() => {
|
|
58
|
-
return themes[themeName] || themes[defaultThemeProp || firstThemeName] || defaultTheme;
|
|
59
|
-
}, [themeName, defaultThemeProp, firstThemeName, themes]);
|
|
60
|
-
useLayoutEffect(() => {
|
|
61
|
-
if (currentTheme) {
|
|
62
|
-
updateThemeVariables(currentTheme, prefix);
|
|
63
|
-
}
|
|
64
|
-
}, [currentTheme, prefix]);
|
|
65
|
-
useLayoutEffect(() => {
|
|
66
|
-
if (isBrowser() && attribute) {
|
|
67
|
-
document.documentElement.setAttribute(attribute, themeName);
|
|
68
|
-
}
|
|
69
|
-
}, [themeName, attribute]);
|
|
70
|
-
const setTheme = useCallback((newThemeName) => {
|
|
71
|
-
if (themes[newThemeName]) {
|
|
72
|
-
setThemeNameState(newThemeName);
|
|
73
|
-
try {
|
|
74
|
-
localStorage.setItem(storageKey, newThemeName);
|
|
75
|
-
}
|
|
76
|
-
catch {
|
|
77
|
-
// localStorage access failed (e.g., in private browsing mode)
|
|
78
|
-
}
|
|
79
|
-
}
|
|
80
|
-
else if (typeof process !== "undefined" && process.env?.NODE_ENV !== "production") {
|
|
81
|
-
// eslint-disable-next-line no-console
|
|
82
|
-
console.warn(`[Stoop] Theme "${newThemeName}" not found. Available themes: ${availableThemeNames.join(", ")}`);
|
|
83
|
-
}
|
|
84
|
-
}, [storageKey, themes, availableThemeNames]);
|
|
85
|
-
const themeContextValue = useMemo(() => ({
|
|
86
|
-
theme: currentTheme,
|
|
87
|
-
themeName,
|
|
88
|
-
}), [currentTheme, themeName]);
|
|
89
|
-
const toggleTheme = useCallback(() => {
|
|
90
|
-
const currentIndex = availableThemeNames.indexOf(themeName);
|
|
91
|
-
const nextIndex = (currentIndex + 1) % availableThemeNames.length;
|
|
92
|
-
const newTheme = availableThemeNames[nextIndex];
|
|
93
|
-
setTheme(newTheme);
|
|
94
|
-
}, [themeName, setTheme]);
|
|
95
|
-
const managementContextValue = useMemo(() => ({
|
|
96
|
-
availableThemes: availableThemeNames,
|
|
97
|
-
setTheme,
|
|
98
|
-
theme: currentTheme,
|
|
99
|
-
themeName,
|
|
100
|
-
toggleTheme,
|
|
101
|
-
}), [currentTheme, themeName, setTheme, toggleTheme]);
|
|
102
|
-
return (_jsx(ThemeContext.Provider, { value: themeContextValue, children: _jsx(ThemeManagementContext.Provider, { value: managementContextValue, children: children }) }));
|
|
103
|
-
}
|
|
104
|
-
return {
|
|
105
|
-
Provider,
|
|
106
|
-
ThemeContext,
|
|
107
|
-
ThemeManagementContext,
|
|
108
|
-
};
|
|
109
|
-
}
|
package/dist/api/use-theme.d.ts
DELETED
|
@@ -1,13 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Theme management hook.
|
|
3
|
-
* Provides access to theme state and theme switching functions.
|
|
4
|
-
*/
|
|
5
|
-
import { type Context } from "react";
|
|
6
|
-
import type { ThemeManagementContextValue } from "../types";
|
|
7
|
-
/**
|
|
8
|
-
* Creates a useTheme hook for a specific theme management context.
|
|
9
|
-
*
|
|
10
|
-
* @param ThemeManagementContext - React context for theme management
|
|
11
|
-
* @returns Hook function that returns theme management context value
|
|
12
|
-
*/
|
|
13
|
-
export declare function createUseThemeHook(ThemeManagementContext: Context<ThemeManagementContextValue | null>): () => ThemeManagementContextValue;
|
package/dist/api/use-theme.js
DELETED
|
@@ -1,21 +0,0 @@
|
|
|
1
|
-
"use client";
|
|
2
|
-
/**
|
|
3
|
-
* Theme management hook.
|
|
4
|
-
* Provides access to theme state and theme switching functions.
|
|
5
|
-
*/
|
|
6
|
-
import { useContext } from "react";
|
|
7
|
-
/**
|
|
8
|
-
* Creates a useTheme hook for a specific theme management context.
|
|
9
|
-
*
|
|
10
|
-
* @param ThemeManagementContext - React context for theme management
|
|
11
|
-
* @returns Hook function that returns theme management context value
|
|
12
|
-
*/
|
|
13
|
-
export function createUseThemeHook(ThemeManagementContext) {
|
|
14
|
-
return function useTheme() {
|
|
15
|
-
const context = useContext(ThemeManagementContext);
|
|
16
|
-
if (!context) {
|
|
17
|
-
throw new Error("useTheme must be used within a Provider");
|
|
18
|
-
}
|
|
19
|
-
return context;
|
|
20
|
-
};
|
|
21
|
-
}
|
|
@@ -1,33 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Server-safe factory function that creates a Stoop instance.
|
|
3
|
-
* Only includes APIs that work without React: css, globalCss, keyframes, getCssText, etc.
|
|
4
|
-
* Does NOT include: styled, Provider, useTheme
|
|
5
|
-
*
|
|
6
|
-
* This is the entry point for Server Components in Next.js App Router.
|
|
7
|
-
*/
|
|
8
|
-
import type { CSS, StoopConfig, Theme } from "./types";
|
|
9
|
-
/**
|
|
10
|
-
* Server-safe Stoop instance interface.
|
|
11
|
-
* Only includes APIs that work without React dependencies.
|
|
12
|
-
*/
|
|
13
|
-
export interface StoopServerInstance {
|
|
14
|
-
config: StoopConfig & {
|
|
15
|
-
prefix: string;
|
|
16
|
-
};
|
|
17
|
-
createTheme: (themeOverride: Partial<Theme>) => Theme;
|
|
18
|
-
css: (styles: CSS) => string;
|
|
19
|
-
getCssText: (theme?: string | Theme) => string;
|
|
20
|
-
globalCss: (...args: CSS[]) => () => void;
|
|
21
|
-
keyframes: (definition: Record<string, CSS>) => string;
|
|
22
|
-
preloadTheme: (theme: string | Theme) => void;
|
|
23
|
-
theme: Theme;
|
|
24
|
-
warmCache: (styles: CSS[]) => void;
|
|
25
|
-
}
|
|
26
|
-
/**
|
|
27
|
-
* Creates a server-safe Stoop instance with the provided configuration.
|
|
28
|
-
* Only includes APIs that work without React: css, globalCss, keyframes, getCssText, etc.
|
|
29
|
-
*
|
|
30
|
-
* @param config - Configuration object containing theme, media queries, utilities, and optional prefix/themeMap
|
|
31
|
-
* @returns StoopServerInstance with server-safe API functions
|
|
32
|
-
*/
|
|
33
|
-
export declare function createStoop(config: StoopConfig): StoopServerInstance;
|