stoop 0.6.0 → 0.6.2
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/dist/api/core-api.d.ts +2 -0
- package/dist/api/core-api.js +171 -0
- package/dist/api/styled.d.ts +3 -0
- package/dist/api/styled.js +467 -0
- package/dist/api/theme-provider.d.ts +3 -0
- package/dist/api/theme-provider.js +199 -0
- package/dist/constants.js +154 -0
- package/dist/core/cache.js +66 -0
- package/dist/core/compiler.js +408 -0
- package/dist/core/stringify.js +150 -0
- package/dist/core/theme-manager.js +97 -0
- package/dist/create-stoop-internal.d.ts +2 -2
- package/dist/create-stoop-internal.js +119 -0
- package/dist/create-stoop-ssr.d.ts +2 -0
- package/dist/create-stoop-ssr.js +22 -16
- package/dist/create-stoop.d.ts +6 -26
- package/dist/create-stoop.js +48 -17
- package/dist/index.d.ts +6 -0
- package/dist/index.js +5 -0
- package/dist/inject.js +293 -0
- package/dist/types/index.d.ts +4 -4
- package/dist/types/index.js +5 -0
- package/dist/utils/helpers.js +157 -0
- package/dist/utils/storage.js +130 -0
- package/dist/utils/theme-utils.js +328 -0
- package/dist/utils/theme.js +430 -0
- package/package.json +14 -28
|
@@ -0,0 +1,119 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Internal implementation for creating Stoop instances.
|
|
3
|
+
* SERVER-SAFE: No "use client" dependencies, no React imports.
|
|
4
|
+
* This file is used by both client (create-stoop.ts) and server (create-stoop-ssr.ts) entry points.
|
|
5
|
+
*/
|
|
6
|
+
import { createTheme as createThemeFactory, createCSSFunction, createKeyframesFunction, createGlobalCSSFunction, } from "./api/core-api";
|
|
7
|
+
import { DEFAULT_THEME_MAP } from "./constants";
|
|
8
|
+
import { compileCSS, cssObjectToString } from "./core/compiler";
|
|
9
|
+
import { mergeWithDefaultTheme, registerDefaultTheme, injectAllThemes } from "./core/theme-manager";
|
|
10
|
+
import { getCssText as getCssTextBase, removeThemeVariableBlocks } from "./inject";
|
|
11
|
+
import { validateTheme, applyUtilities } from "./utils/helpers";
|
|
12
|
+
import { generateAllThemeVariables, generateCSSVariables, replaceThemeTokensWithVars } from "./utils/theme";
|
|
13
|
+
import { sanitizePrefix } from "./utils/theme-utils";
|
|
14
|
+
/**
|
|
15
|
+
* Shared implementation for creating Stoop instances.
|
|
16
|
+
* Handles common setup logic for both client and server instances.
|
|
17
|
+
*/
|
|
18
|
+
export function createStoopBase(config) {
|
|
19
|
+
const { globalCss: globalCssConfig, media: configMedia, prefix = "stoop", theme, themeMap: userThemeMap, utils, } = config;
|
|
20
|
+
const sanitizedPrefix = sanitizePrefix(prefix);
|
|
21
|
+
const validatedTheme = validateTheme(theme);
|
|
22
|
+
const media = validatedTheme.media || configMedia;
|
|
23
|
+
const mergedThemeMap = {
|
|
24
|
+
...DEFAULT_THEME_MAP,
|
|
25
|
+
...userThemeMap,
|
|
26
|
+
};
|
|
27
|
+
registerDefaultTheme(validatedTheme, sanitizedPrefix);
|
|
28
|
+
const css = createCSSFunction(validatedTheme, sanitizedPrefix, media, utils, mergedThemeMap);
|
|
29
|
+
const createTheme = createThemeFactory(validatedTheme);
|
|
30
|
+
const globalCss = createGlobalCSSFunction(validatedTheme, sanitizedPrefix, media, utils, mergedThemeMap);
|
|
31
|
+
const keyframes = createKeyframesFunction(sanitizedPrefix, validatedTheme, mergedThemeMap);
|
|
32
|
+
const themeObject = Object.freeze({ ...validatedTheme });
|
|
33
|
+
/**
|
|
34
|
+
* Pre-compiles CSS objects to warm the cache.
|
|
35
|
+
* Useful for eliminating FOUC by pre-compiling common styles.
|
|
36
|
+
*
|
|
37
|
+
* @param styles - Array of CSS objects to pre-compile
|
|
38
|
+
*/
|
|
39
|
+
function warmCache(styles) {
|
|
40
|
+
for (const style of styles) {
|
|
41
|
+
try {
|
|
42
|
+
compileCSS(style, validatedTheme, sanitizedPrefix, media, utils, mergedThemeMap);
|
|
43
|
+
}
|
|
44
|
+
catch {
|
|
45
|
+
// Skip invalid styles
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
/**
|
|
50
|
+
* Preloads themes by injecting CSS variables before React renders.
|
|
51
|
+
* Useful for preventing FOUC when loading a non-default theme from localStorage.
|
|
52
|
+
*/
|
|
53
|
+
function preloadTheme() {
|
|
54
|
+
if (!config.themes || Object.keys(config.themes).length === 0) {
|
|
55
|
+
return;
|
|
56
|
+
}
|
|
57
|
+
injectAllThemes(config.themes, sanitizedPrefix);
|
|
58
|
+
}
|
|
59
|
+
/**
|
|
60
|
+
* Gets all injected CSS text for server-side rendering.
|
|
61
|
+
* Includes all theme CSS variables using attribute selectors.
|
|
62
|
+
* Includes global CSS config for SSR (prevents FOUC in Pages Router).
|
|
63
|
+
*
|
|
64
|
+
* @returns CSS text string with theme variables, global CSS, and component styles
|
|
65
|
+
*/
|
|
66
|
+
function getCssText() {
|
|
67
|
+
let result = "";
|
|
68
|
+
if (config.themes && Object.keys(config.themes).length > 0) {
|
|
69
|
+
const mergedThemes = {};
|
|
70
|
+
for (const [themeName, theme] of Object.entries(config.themes)) {
|
|
71
|
+
mergedThemes[themeName] = mergeWithDefaultTheme(theme, sanitizedPrefix);
|
|
72
|
+
}
|
|
73
|
+
const allThemeVars = generateAllThemeVariables(mergedThemes, sanitizedPrefix, "data-theme");
|
|
74
|
+
if (allThemeVars) {
|
|
75
|
+
result += allThemeVars + "\n";
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
else {
|
|
79
|
+
const themeVars = generateCSSVariables(validatedTheme, sanitizedPrefix);
|
|
80
|
+
if (themeVars) {
|
|
81
|
+
result += themeVars + "\n";
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
// Include global CSS from config for SSR
|
|
85
|
+
// This ensures global styles are present in initial HTML (prevents FOUC)
|
|
86
|
+
// Provider will call globalCss() on mount but it's deduplicated automatically
|
|
87
|
+
if (globalCssConfig) {
|
|
88
|
+
const stylesWithUtils = applyUtilities(globalCssConfig, utils);
|
|
89
|
+
const themedStyles = replaceThemeTokensWithVars(stylesWithUtils, validatedTheme, mergedThemeMap);
|
|
90
|
+
const globalCssText = cssObjectToString(themedStyles, "", 0, media);
|
|
91
|
+
if (globalCssText) {
|
|
92
|
+
result += (result ? "\n" : "") + globalCssText;
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
const baseCss = getCssTextBase();
|
|
96
|
+
const cleanedCss = removeThemeVariableBlocks(baseCss).trim();
|
|
97
|
+
if (cleanedCss) {
|
|
98
|
+
result += (result ? "\n" : "") + cleanedCss;
|
|
99
|
+
}
|
|
100
|
+
return result;
|
|
101
|
+
}
|
|
102
|
+
return {
|
|
103
|
+
config: { ...config, prefix: sanitizedPrefix },
|
|
104
|
+
createTheme,
|
|
105
|
+
css,
|
|
106
|
+
getCssText,
|
|
107
|
+
globalCss,
|
|
108
|
+
globalCssConfig,
|
|
109
|
+
keyframes,
|
|
110
|
+
media,
|
|
111
|
+
mergedThemeMap,
|
|
112
|
+
preloadTheme,
|
|
113
|
+
sanitizedPrefix,
|
|
114
|
+
theme: themeObject,
|
|
115
|
+
utils,
|
|
116
|
+
validatedTheme,
|
|
117
|
+
warmCache,
|
|
118
|
+
};
|
|
119
|
+
}
|
|
@@ -2,6 +2,8 @@
|
|
|
2
2
|
* SSR-safe entry point for Stoop.
|
|
3
3
|
* Exports only server-safe APIs that don't require React.
|
|
4
4
|
* Use this import in Server Components: import { createStoop } from "stoop/ssr"
|
|
5
|
+
*
|
|
6
|
+
* SERVER-ONLY: No "use client" modules imported. Safe for React Server Components.
|
|
5
7
|
*/
|
|
6
8
|
import type { StoopConfig, StoopServerInstance } from "./types";
|
|
7
9
|
export type { CSS, Theme, StoopConfig, StoopServerInstance, UtilityFunction, ThemeScale, DefaultTheme, } from "./types";
|
package/dist/create-stoop-ssr.js
CHANGED
|
@@ -1,16 +1,22 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
1
|
+
/**
|
|
2
|
+
* SSR-safe entry point for Stoop.
|
|
3
|
+
* Exports only server-safe APIs that don't require React.
|
|
4
|
+
* Use this import in Server Components: import { createStoop } from "stoop/ssr"
|
|
5
|
+
*
|
|
6
|
+
* SERVER-ONLY: No "use client" modules imported. Safe for React Server Components.
|
|
7
|
+
*/
|
|
8
|
+
import { createStoopBase } from "./create-stoop-internal";
|
|
9
|
+
export function createStoop(config) {
|
|
10
|
+
const base = createStoopBase(config);
|
|
11
|
+
return {
|
|
12
|
+
config: { ...base.config, prefix: base.sanitizedPrefix },
|
|
13
|
+
createTheme: base.createTheme,
|
|
14
|
+
css: base.css,
|
|
15
|
+
getCssText: base.getCssText,
|
|
16
|
+
globalCss: base.globalCss,
|
|
17
|
+
keyframes: base.keyframes,
|
|
18
|
+
preloadTheme: base.preloadTheme,
|
|
19
|
+
theme: base.theme,
|
|
20
|
+
warmCache: base.warmCache,
|
|
21
|
+
};
|
|
22
|
+
}
|
package/dist/create-stoop.d.ts
CHANGED
|
@@ -1,30 +1,11 @@
|
|
|
1
1
|
/**
|
|
2
|
-
*
|
|
3
|
-
*
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
/**
|
|
8
|
-
* Shared implementation for creating Stoop instances.
|
|
9
|
-
* Handles common setup logic for both client and server instances.
|
|
2
|
+
* Client-side entry point for creating Stoop instances.
|
|
3
|
+
* Includes React-based APIs: styled(), Provider, useTheme.
|
|
4
|
+
*
|
|
5
|
+
* NOTE: This file imports from "use client" modules (api/styled, api/theme-provider)
|
|
6
|
+
* making it client-side only. For server-side usage, import from "stoop/ssr".
|
|
10
7
|
*/
|
|
11
|
-
|
|
12
|
-
config: StoopConfig;
|
|
13
|
-
createTheme: (overrides?: Partial<Theme>) => Theme;
|
|
14
|
-
css: ReturnType<typeof createCSSFunction>;
|
|
15
|
-
getCssText: () => string;
|
|
16
|
-
globalCss: ReturnType<typeof createGlobalCSSFunction>;
|
|
17
|
-
globalCssConfig: StoopConfig["globalCss"];
|
|
18
|
-
keyframes: ReturnType<typeof createKeyframesFunction>;
|
|
19
|
-
media: StoopConfig["media"];
|
|
20
|
-
mergedThemeMap: Record<string, ThemeScale>;
|
|
21
|
-
preloadTheme: () => void;
|
|
22
|
-
sanitizedPrefix: string;
|
|
23
|
-
theme: Theme;
|
|
24
|
-
utils: StoopConfig["utils"];
|
|
25
|
-
validatedTheme: Theme;
|
|
26
|
-
warmCache: (styles: CSS[]) => void;
|
|
27
|
-
};
|
|
8
|
+
import type { StoopConfig, StoopInstance } from "./types";
|
|
28
9
|
/**
|
|
29
10
|
* Creates a Stoop instance with the provided configuration.
|
|
30
11
|
* Includes all APIs: styled, Provider, useTheme, etc.
|
|
@@ -32,5 +13,4 @@ export declare function createStoopBase(config: StoopConfig): {
|
|
|
32
13
|
* @param config - Configuration object containing theme, media queries, utilities, and optional prefix/themeMap
|
|
33
14
|
* @returns StoopInstance with all API functions
|
|
34
15
|
*/
|
|
35
|
-
export type { CSS, ComponentProps, DefaultTheme, StoopConfig, StoopInstance, Theme, ThemeScale, UtilityFunction, } from "./types";
|
|
36
16
|
export declare function createStoop(config: StoopConfig): StoopInstance;
|
package/dist/create-stoop.js
CHANGED
|
@@ -1,17 +1,48 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
`)}function C(J,$,q,X){if(!J||typeof J!=="object")return J;let Y=Object.keys(J),Z=!1;for(let Q of Y){let W=J[Q];if(typeof W==="string"&&W.includes("$")){Z=!0;break}}if(!Z&&!$)return J;let G={},D=!1;for(let Q of Y){let W=J[Q];if(e(W)){let H=C(W,$,q,void 0);if(G[Q]=H,H!==W)D=!0}else if(typeof W==="string"&&W.includes("$")){D=!0;let H=X||Q;if(W.startsWith("$")&&!W.includes(" ")&&!W.includes("calc(")&&W===W.trim())if(W.startsWith("-$")){let U=W.slice(1);if(U.includes(".")||U.includes("$")){let L=U.includes("$")?U.split("$"):U.split("."),_=!1;for(let w=0;w<L.length;w++){let B=L[w];for(let I=0;I<B.length;I++){let A=B.charCodeAt(I);if(!(A>=48&&A<=57||A>=65&&A<=90||A>=97&&A<=122||A===45||A===95)){_=!0;break}}if(_)break}if(_){let B=`--${L.map((I)=>T(I)).join("-")}`;G[Q]=`calc(-1 * var(${B}))`}else{let w=`--${L.join("-")}`;G[Q]=`calc(-1 * var(${w}))`}}else{let L=GJ(U,$,H,q);G[Q]=`calc(-1 * ${L})`}}else{let U=W.slice(1);if(U.includes(".")||U.includes("$")){let L=U.includes("$")?U.split("$"):U.split("."),_=!1;for(let w=0;w<L.length;w++){let B=L[w];for(let I=0;I<B.length;I++){let A=B.charCodeAt(I);if(!(A>=48&&A<=57||A>=65&&A<=90||A>=97&&A<=122||A===45||A===95)){_=!0;break}}if(_)break}if(_){let B=`--${L.map((I)=>T(I)).join("-")}`;G[Q]=`var(${B})`}else{let w=`--${L.join("-")}`;G[Q]=`var(${w})`}}else G[Q]=GJ(W,$,H,q)}else G[Q]=W.replace(x0,(U)=>{if(U.startsWith("-$")){let L=U.slice(1);return`calc(-1 * ${GJ(L,$,H,q)})`}return GJ(U,$,H,q)})}else G[Q]=W}if(!D)return J;return G}var v=new j(y);function v0(J){return J.replace(/([A-Z])/g,"-$1").toLowerCase()}function T0(J){if(J===J.toUpperCase()&&J.length>1)return J.charAt(0)+J.slice(1).toLowerCase();return J}function ZJ(J){if(!J)return"";return J.charAt(0).toLowerCase()+J.slice(1).replace(/([A-Z])/g,"-$1").toLowerCase()}function i(J){if(!J||typeof J!=="string")return"";let $=v.get(J);if($!==void 0)return $;if(/^-[a-z]+-/.test(J))return v.set(J,J),J;let q=T0(J);if(/^[Mm]oz/i.test(q)){if(q.length===3||q.toLowerCase()==="moz")return v.set(J,"-moz"),"-moz";let G=q.match(/^[Mm]oz(.+)$/i);if(G&&G[1]){let[,D]=G,Q=ZJ(D);if(Q){let W=`-moz-${Q}`;return v.set(J,W),W}}}if(/^[Ww]ebkit/i.test(q)){if(q.length===6||q.toLowerCase()==="webkit")return v.set(J,"-webkit"),"-webkit";let G=q.match(/^[Ww]ebkit(.+)$/i);if(G&&G[1]){let[,D]=G,Q=ZJ(D);if(Q){let W=`-webkit-${Q}`;return v.set(J,W),W}}}if(/^[Mm]s/i.test(q)){if(q.length===2||q.toLowerCase()==="ms")return v.set(J,"-ms"),"-ms";let G=q.match(/^[Mm]s(.+)$/i);if(G&&G[1]){let[,D]=G,Q=ZJ(D);if(Q){let W=`-ms-${Q}`;return v.set(J,W),W}}}if(/^O/i.test(q)){if(q.length===1||q.toLowerCase()==="o")return v.set(J,"-o"),"-o";if(/^O[A-Z]/.test(q)){let G=q.substring(1),D=ZJ(G);if(D){let Q=`-o-${D}`;return v.set(J,Q),Q}}}let Z=v0(q).replace(/[^a-zA-Z0-9-]/g,"").replace(/^-+|-+$/g,"").replace(/^\d+/,"")||"";return v.set(J,Z),Z}var f0=new Set(["width","height","min-width","min-height","max-width","max-height","top","right","bottom","left","margin","margin-top","margin-right","margin-bottom","margin-left","padding","padding-top","padding-right","padding-bottom","padding-left","border-width","border-top-width","border-right-width","border-bottom-width","border-left-width","border-radius","border-top-left-radius","border-top-right-radius","border-bottom-left-radius","border-bottom-right-radius","font-size","letter-spacing","word-spacing","text-indent","flex-basis","gap","row-gap","column-gap","grid-template-rows","grid-template-columns","grid-auto-rows","grid-auto-columns","perspective","outline-width","outline-offset","clip","vertical-align","object-position","background-position","background-size","mask-position","mask-size","scroll-margin","scroll-padding","shape-margin"]);function Q0(J){return f0.has(J)}function Z0(J,$){if(typeof $==="string"){if(Q0(J)&&/^-?\d+\.?\d*$/.test($.trim()))return`${$}px`;return $}if(typeof $==="number"&&Q0(J))return`${$}px`;return String($)}function D0(J,$){if(typeof J==="symbol"&&J===t)return!0;if(o($))return!0;if(typeof J==="string"&&J.startsWith("__STOOP_COMPONENT_"))return!0;return!1}function b0(J,$){if(typeof $==="object"&&$!==null&&"__stoopClassName"in $&&typeof $.__stoopClassName==="string")return $.__stoopClassName;if(typeof J==="string"&&J.startsWith("__STOOP_COMPONENT_"))return J.replace("__STOOP_COMPONENT_","");return""}function K(J,$="",q=0,X){if(!J||typeof J!=="object")return"";if(q>SJ)return"";let Y=[],Z=[],G=$===""?Object.keys(J).sort():Object.keys(J);for(let Q of G){let W=J[Q];if(D0(Q,W)){let H=b0(Q,W);if(!H)continue;let F=b(H);if(!F)continue;let U=$?`${$} .${F}`:`.${F}`,L=JJ(W)?K(W,U,q+1,X):"";if(L)Z.push(L);continue}if(JJ(W))if(X&&Q in X){let H=iJ(X[Q]);if(H){let F=K(W,$,q+1,X);if(F)Z.push(`${H} { ${F} }`)}}else if(Q.startsWith("@")){let H=b(Q);if(H){let F=K(W,$,q+1,X);if(F)Z.push(`${H} { ${F} }`)}}else if(Q.includes("&")){let H=b(Q);if(H){let F=H.split("&");if($.includes(",")){let _=$.split(",").map((B)=>B.trim()).map((B)=>F.join(B)).join(", "),w=K(W,_,q+1,X);if(w)Z.push(w)}else{let U=F.join($),L=K(W,U,q+1,X);if(L)Z.push(L)}}}else if(Q.startsWith(":")){let H=b(Q);if(H){let F=`${$}${H}`,U=K(W,F,q+1,X);if(U)Z.push(U)}}else if(Q.includes(",")){let F=Q.split(",").map((U)=>U.trim()).map((U)=>b(U)).filter((U)=>U);if(F.length>0){let U=F.join(", "),L=K(W,U,q+1,X);if(L)Z.push(L)}}else if(Q.includes(" ")||Q.includes(">")||Q.includes("+")||Q.includes("~")){let H=b(Q);if(H){let U=/^[\s>+~]/.test(H.trim())?`${$}${H}`:`${$} ${H}`,L=K(W,U,q+1,X);if(L)Z.push(L)}}else{let H=b(Q);if(H){let F=$?`${$} ${H}`:H,U=K(W,F,q+1,X);if(U)Z.push(U)}}else if(W!==void 0){let H=i(Q);if(H&&(typeof W==="string"||typeof W==="number")){let F=Z0(H,W);if(H==="content"&&F==="")Y.push(`${H}: "";`);else{let U=BJ(F);Y.push(`${H}: ${U};`)}}}}let D=[];if(Y.length>0)D.push(`${$} { ${Y.join(" ")} }`);return D.push(...Z),D.join("")}function C0(J,$){if(!J||typeof J!=="object")return"";let q=[],X=Object.keys(J).sort();for(let Y of X){let Z=J[Y];if(JJ(Z))return"";if($&&Y in $)return"";if(Y.startsWith("@")||Y.includes("&")||Y.startsWith(":")||Y.includes(" ")||Y.includes(">")||Y.includes("+")||Y.includes("~"))return"";if(Z!==void 0&&!D0(Y,Z)){let G=i(Y);if(G&&(typeof Z==="string"||typeof Z==="number")){let D=Z0(G,Z);if(G==="content"&&D==="")q.push(`${G}: "";`);else{let Q=BJ(D);q.push(`${G}: ${Q};`)}}}}return q.join(" ")}function n(J,$,q="stoop",X,Y,Z){let G=z(q),D=S(J,Y),Q=C(D,$,Z),W=C0(Q,X),H,F;if(W)H=W,F=d(H);else H=K(Q,"",0,X),F=d(H);let U=G?`${G}-${F}`:`css-${F}`,L=`${G}:${U}`,_=UJ.get(L);if(_)return c(_,G,L),U;let w;if(W)w=`.${U} { ${W} }`;else w=K(Q,`.${U}`,0,X);return UJ.set(L,w),hJ.set(L,U),c(w,G,L),U}var W0=new Map;function H0(J,$="stoop"){let q=$||"";W0.set(q,J)}function k0(J="stoop"){let $=J||"";return W0.get($)||null}function MJ(J,$){let q={...J},X=Object.keys($);for(let Y of X){if(Y==="media")continue;let Z=$[Y],G=J[Y];if(Z&&typeof Z==="object"&&!Array.isArray(Z)&&G&&typeof G==="object"&&!Array.isArray(G))q[Y]={...G,...Z};else if(Z!==void 0)q[Y]=Z}return q}function EJ(J,$="stoop"){let q=k0($);if(!q)return J;if(G0(J,q))return J;return MJ(q,J)}function DJ(J,$="stoop",q="data-theme"){if(!O())return;let X={};for(let[Z,G]of Object.entries(J))X[Z]=EJ(G,$);let Y=QJ(X,$,q);q0(Y,$)}function U0(J){return function $(q={}){let X=$J(q);return MJ(J,X)}}function F0(J,$="stoop",q,X,Y){return function Z(G){return n(G,J,$,q,X,Y)}}function S0(J,$,q,X){let Y=`@keyframes ${$} {`,Z=Object.keys(J).sort((G,D)=>{let Q=parseFloat(G.replace("%","")),W=parseFloat(D.replace("%",""));if(G==="from")return-1;if(D==="from")return 1;if(G==="to")return 1;if(D==="to")return-1;return Q-W});for(let G of Z){if(!rJ(G))continue;let D=J[G];if(!D||typeof D!=="object")continue;Y+=` ${G} {`;let Q=C(D,q,X),W=Object.keys(Q).sort();for(let H of W){let F=Q[H];if(F!==void 0&&(typeof F==="string"||typeof F==="number")){let U=i(H);if(U){let L=String(F);Y+=` ${U}: ${L};`}}}Y+=" }"}return Y+=" }",Y}function L0(J="stoop",$,q){let X=z(J),Y=new j(dJ);return function Z(G){let D=wJ(G),Q=Y.get(D);if(Q)return Q;let W=D.slice(0,8),H=X?`${X}-${W}`:`stoop-${W}`,F=S0(G,H,$,q),U=`__keyframes_${H}`;return c(F,X,U),Y.set(D,H),H}}var KJ=new Set;function w0(J,$="stoop",q,X,Y){return function Z(G){let D=wJ(G);if(KJ.has(D))return()=>{};KJ.add(D);let Q=z($),W=S(G,X),H=C(W,J,Y),F=K(H,"",0,q);return c(F,Q,`__global_${D}`),()=>{KJ.delete(D)}}}import{useMemo as WJ,forwardRef as d0,createElement as u0,useContext as y0,createContext as h0}from"react";function c0(J,$,q){let X=[];for(let Z in J){let G=$[Z];if(G===void 0)continue;let D=J[Z],Q=G===!0?"true":G===!1?"false":String(G);if(D[Q])X.push(D[Q])}if(X.length===0)return q;if(X.length===1)return{...q,...X[0]};let Y={...X[0]};for(let Z=1;Z<X.length;Z++)Object.assign(Y,X[Z]);return{...q,...Y}}var VJ=null;function n0(){if(!VJ)VJ=h0(null);return VJ}function p0(J){return{__isStoopStyled:!0,__stoopClassName:J,[t]:J,toString:()=>`__STOOP_COMPONENT_${J}`}}function m0(J){return o(J)}var o0=new Set(["alignContent","alignItems","alignSelf","animation","animationDelay","animationDirection","animationDuration","animationFillMode","animationIterationCount","animationName","animationPlayState","animationTimingFunction","aspectRatio","backdropFilter","backfaceVisibility","background","backgroundAttachment","backgroundBlendMode","backgroundClip","backgroundColor","backgroundImage","backgroundOrigin","backgroundPosition","backgroundRepeat","backgroundSize","border","borderBottom","borderBottomColor","borderBottomLeftRadius","borderBottomRightRadius","borderBottomStyle","borderBottomWidth","borderCollapse","borderColor","borderImage","borderImageOutset","borderImageRepeat","borderImageSlice","borderImageSource","borderImageWidth","borderLeft","borderLeftColor","borderLeftStyle","borderLeftWidth","borderRadius","borderRight","borderRightColor","borderRightStyle","borderRightWidth","borderSpacing","borderStyle","borderTop","borderTopColor","borderTopLeftRadius","borderTopRightRadius","borderTopStyle","borderTopWidth","borderWidth","bottom","boxShadow","boxSizing","captionSide","caretColor","clear","clip","clipPath","color","columnCount","columnFill","columnGap","columnRule","columnRuleColor","columnRuleStyle","columnRuleWidth","columnSpan","columnWidth","columns","content","counterIncrement","counterReset","cursor","direction","display","emptyCells","filter","flex","flexBasis","flexDirection","flexFlow","flexGrow","flexShrink","flexWrap","float","font","fontFamily","fontFeatureSettings","fontKerning","fontLanguageOverride","fontSize","fontSizeAdjust","fontStretch","fontStyle","fontSynthesis","fontVariant","fontVariantAlternates","fontVariantCaps","fontVariantEastAsian","fontVariantLigatures","fontVariantNumeric","fontVariantPosition","fontWeight","gap","grid","gridArea","gridAutoColumns","gridAutoFlow","gridAutoRows","gridColumn","gridColumnEnd","gridColumnGap","gridColumnStart","gridGap","gridRow","gridRowEnd","gridRowGap","gridRowStart","gridTemplate","gridTemplateAreas","gridTemplateColumns","gridTemplateRows","height","hyphens","imageOrientation","imageRendering","imageResolution","imeMode","inlineSize","isolation","justifyContent","justifyItems","justifySelf","left","letterSpacing","lineHeight","listStyle","listStyleImage","listStylePosition","listStyleType","margin","marginBottom","marginLeft","marginRight","marginTop","maxHeight","maxWidth","minHeight","minWidth","objectFit","objectPosition","opacity","order","orphans","outline","outlineColor","outlineOffset","outlineStyle","outlineWidth","overflow","overflowWrap","overflowX","overflowY","padding","paddingBottom","paddingLeft","paddingRight","paddingTop","pageBreakAfter","pageBreakBefore","pageBreakInside","perspective","perspectiveOrigin","placeContent","placeItems","placeSelf","pointerEvents","position","quotes","resize","right","rowGap","scrollBehavior","tabSize","tableLayout","textAlign","textAlignLast","textDecoration","textDecorationColor","textDecorationLine","textDecorationStyle","textIndent","textJustify","textOverflow","textShadow","textTransform","textUnderlinePosition","top","transform","transformOrigin","transformStyle","transition","transitionDelay","transitionDuration","transitionProperty","transitionTimingFunction","unicodeBidi","userSelect","verticalAlign","visibility","whiteSpace","width","wordBreak","wordSpacing","wordWrap","writingMode","zIndex"]);function i0(J){return o0.has(J)}function l0(J,$){let q=$?new Set(Object.keys($)):new Set,X={},Y={},Z={};for(let G in J)if(q.has(G))X[G]=J[G];else if(i0(G))Y[G]=J[G];else Z[G]=J[G];return{cssProps:Y,elementProps:Z,variantProps:X}}function B0(J,$="stoop",q,X,Y,Z){return function G(D,Q){let W=Q||s,H;if(Q&&"variants"in Q&&typeof Q.variants==="object"&&Q.variants!==null&&!Array.isArray(Q.variants)){let B=Q.variants;if(Object.keys(B).length>0&&Object.values(B).every((A)=>typeof A==="object"&&A!==null&&!Array.isArray(A))){H=Q.variants;let{variants:A,...R}=Q;W=R}}let F;if(typeof D!=="string"&&m0(D))F=D.__stoopClassName;let U=d0(function B(I,A){let{as:R,className:x,css:N,...V}=I,f=R||D,g=WJ(()=>N&&typeof N==="object"&&N!==null?N:s,[N]),{cssProps:k,elementProps:M,variantProps:P}=l0(V,H),r=y0(Z||n0())?.theme||J,TJ=r.media?{...q,...r.media}:q,fJ=WJ(()=>{if(!H)return"";let E=Object.entries(P);if(E.length===0)return"";return E.sort(([u],[p])=>u.localeCompare(p)).map(([u,p])=>`${u}:${String(p)}`).join("|")},[P]),bJ=WJ(()=>{let E=W;if(H&&fJ)E=c0(H,P,W);if(Object.keys(k).length>0)E=Object.assign({},E,k);if(g!==s)E=Object.assign({},E,g);return E},[fJ,g,k,W,H,P]),E0=WJ(()=>{let E=[];if(F)E.push(F);let u=n(bJ,r,$,TJ,X,Y);if(u)E.push(u);if(x){let p=typeof x==="string"?x:String(x),CJ=lJ(p);if(CJ)E.push(CJ)}return E.length>0?E.join(" "):void 0},[bJ,x,F,r,$,TJ,X,Y]);return u0(f,{...M,className:E0,ref:A})}),L=d(JSON.stringify(W)),_=`${$}-${L}`,w=U;return w.selector=p0(_),w}}import{createContext as _0,useCallback as O0,useContext as r0,useLayoutEffect as l,useMemo as xJ,useRef as NJ,useState as s0}from"react";function zJ(J){if(!O())return{error:"Not in browser environment",success:!1,value:null};try{return{source:"localStorage",success:!0,value:localStorage.getItem(J)}}catch($){return{error:$ instanceof Error?$.message:"localStorage access failed",success:!1,value:null}}}function PJ(J,$){if(!O())return{error:"Not in browser environment",success:!1,value:void 0};try{return localStorage.setItem(J,$),{success:!0,value:void 0}}catch(q){return{error:q instanceof Error?q.message:"localStorage write failed",success:!1,value:void 0}}}function jJ(J){if(!O())return null;let q=`; ${document.cookie}`.split(`; ${J}=`);if(q.length===2)return q.pop()?.split(";").shift()||null;return null}function A0(J,$,q={}){if(!O())return!1;let{maxAge:X=uJ,path:Y=yJ,secure:Z=!1}=q;try{return document.cookie=`${J}=${$}; path=${Y}; max-age=${X}${Z?"; secure":""}`,!0}catch{return!1}}import{jsx as I0}from"react/jsx-runtime";function gJ(J,$,q){if(!O())return;let X=$?jJ($):null,Y=zJ(q),Z=Y.success?Y.value:null;if(X===J&&Z!==J)PJ(q,J);if(Z===J&&$&&X!==J)A0($,J)}function a0(J,$,q){if(!O())return null;if(J!==void 0){let Z=jJ(J);if(Z&&q[Z])return Z}let X=zJ($),Y=X.success?X.value:null;if(Y&&q[Y])return Y;return null}function R0(J,$,q="stoop",X,Y){let Z=_0(null),G=_0(null),D=Object.keys(J),Q=D[0]||"default",W=X&&Y?Y(X):void 0;function H({attribute:F="data-theme",children:U,cookieKey:L,defaultTheme:_,storageKey:w="stoop-theme"}){let[B,I]=s0(_||Q),A=NJ(!1);l(()=>{if(!O()||A.current)return;let M=a0(L,w,J);if(M){if(gJ(M,L,w),M!==B)I(M)}A.current=!0},[L,w,J]),l(()=>{if(!O())return;let M=(P)=>{if(P.key===w&&P.newValue&&J[P.newValue]&&P.newValue!==B)I(P.newValue),gJ(P.newValue,L,w)};return window.addEventListener("storage",M),()=>{window.removeEventListener("storage",M)}},[w,L,B,J]);let R=xJ(()=>{return J[B]||J[_||Q]||$},[B,_,Q,J,$]),x=NJ(!1),N=NJ(!1);l(()=>{if(!O()||x.current)return;DJ(J,q,F),x.current=!0},[J,q,F]),l(()=>{if(!O()||N.current)return;if(W)W(),N.current=!0},[W]),l(()=>{if(!O())return;if(F)document.documentElement.setAttribute(F,B)},[B,F]);let V=O0((M)=>{if(J[M])I(M),PJ(w,M),gJ(M,L,w);else if(!h())console.warn(`[Stoop] Theme "${M}" not found. Available themes: ${D.join(", ")}`)},[w,L,J,D,B]),f=xJ(()=>({theme:R,themeName:B}),[R,B]),g=O0(()=>{let P=(D.indexOf(B)+1)%D.length,vJ=D[P];V(vJ)},[B,V,D]),k=xJ(()=>({availableThemes:D,setTheme:V,theme:R,themeName:B,toggleTheme:g}),[R,B,V,g]);return I0(Z.Provider,{value:f,children:I0(G.Provider,{value:k,children:U})})}return{Provider:H,ThemeContext:Z,ThemeManagementContext:G}}function M0(J){return function $(){let q=r0(J);if(!q)throw new Error("useTheme must be used within a Provider");return q}}function t0(J){let{globalCss:$,media:q,prefix:X="stoop",theme:Y,themeMap:Z,utils:G}=J,D=z(X),Q=$J(Y),W=Q.media||q,H={...m,...Z};H0(Q,D);let F=F0(Q,D,W,G,H),U=U0(Q),L=w0(Q,D,W,G,H),_=L0(D,Q,H),w=Object.freeze({...Q});function B(R){for(let x of R)try{n(x,Q,D,W,G,H)}catch{}}function I(){if(!J.themes||Object.keys(J.themes).length===0)return;DJ(J.themes,D)}function A(){let R="";if(J.themes&&Object.keys(J.themes).length>0){let V={};for(let[g,k]of Object.entries(J.themes))V[g]=EJ(k,D);let f=QJ(V,D,"data-theme");if(f)R+=f+`
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
1
|
+
/**
|
|
2
|
+
* Client-side entry point for creating Stoop instances.
|
|
3
|
+
* Includes React-based APIs: styled(), Provider, useTheme.
|
|
4
|
+
*
|
|
5
|
+
* NOTE: This file imports from "use client" modules (api/styled, api/theme-provider)
|
|
6
|
+
* making it client-side only. For server-side usage, import from "stoop/ssr".
|
|
7
|
+
*/
|
|
8
|
+
import { createStyledFunction } from "./api/styled"; // "use client" module
|
|
9
|
+
import { createProvider, createUseThemeHook } from "./api/theme-provider"; // "use client" module
|
|
10
|
+
import { createStoopBase } from "./create-stoop-internal"; // Server-safe module
|
|
11
|
+
/**
|
|
12
|
+
* Creates a Stoop instance with the provided configuration.
|
|
13
|
+
* Includes all APIs: styled, Provider, useTheme, etc.
|
|
14
|
+
*
|
|
15
|
+
* @param config - Configuration object containing theme, media queries, utilities, and optional prefix/themeMap
|
|
16
|
+
* @returns StoopInstance with all API functions
|
|
17
|
+
*/
|
|
18
|
+
export function createStoop(config) {
|
|
19
|
+
const base = createStoopBase(config);
|
|
20
|
+
let Provider;
|
|
21
|
+
let useTheme;
|
|
22
|
+
let themeContext;
|
|
23
|
+
if (config.themes) {
|
|
24
|
+
const mergedThemesForProvider = {};
|
|
25
|
+
for (const [themeName, themeOverride] of Object.entries(config.themes)) {
|
|
26
|
+
mergedThemesForProvider[themeName] = base.createTheme(themeOverride);
|
|
27
|
+
}
|
|
28
|
+
const { Provider: ProviderComponent, ThemeContext, ThemeManagementContext, } = createProvider(mergedThemesForProvider, base.validatedTheme, base.sanitizedPrefix, base.globalCssConfig, base.globalCss);
|
|
29
|
+
themeContext = ThemeContext;
|
|
30
|
+
Provider = ProviderComponent;
|
|
31
|
+
useTheme = createUseThemeHook(ThemeManagementContext);
|
|
32
|
+
}
|
|
33
|
+
const styled = createStyledFunction(base.validatedTheme, base.sanitizedPrefix, base.media, base.utils, base.mergedThemeMap, themeContext);
|
|
34
|
+
return {
|
|
35
|
+
config: base.config,
|
|
36
|
+
createTheme: base.createTheme,
|
|
37
|
+
css: base.css,
|
|
38
|
+
getCssText: base.getCssText,
|
|
39
|
+
globalCss: base.globalCss,
|
|
40
|
+
keyframes: base.keyframes,
|
|
41
|
+
preloadTheme: base.preloadTheme,
|
|
42
|
+
Provider,
|
|
43
|
+
styled,
|
|
44
|
+
theme: base.theme,
|
|
45
|
+
useTheme,
|
|
46
|
+
warmCache: base.warmCache,
|
|
47
|
+
};
|
|
48
|
+
}
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Main entry point for Stoop
|
|
3
|
+
* Re-exports createStoop and all types
|
|
4
|
+
*/
|
|
5
|
+
export { createStoop } from "./create-stoop";
|
|
6
|
+
export type { CSS, ComponentProps, DefaultTheme, StoopConfig, StoopInstance, Theme, ThemeScale, UtilityFunction, VariantProps, StyledComponent, StyledFunction, CSSFunction, GlobalCSSFunction, KeyframesFunction, CreateThemeFunction, ProviderProps, ThemeManagementContextValue, ThemeContextValue, } from "./types";
|