@csszyx/dynamic 0.6.2 → 0.8.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/dist/index.d.mts +92 -0
- package/dist/index.mjs +2 -0
- package/dist/react.d.mts +86 -0
- package/dist/react.mjs +37 -0
- package/dist/shared/dynamic.BLXLKBNg.mjs +1149 -0
- package/package.json +22 -8
- package/src/css-generator.ts +0 -1003
- package/src/index.ts +0 -122
- package/src/injector.ts +0 -226
- package/src/manifest.ts +0 -119
- package/src/react.ts +0 -166
- package/src/ssr.ts +0 -5
- package/tests/css-generator.test.ts +0 -339
- package/tests/injector.test.ts +0 -222
- package/tests/manifest.test.ts +0 -177
- package/tests/react.test.ts +0 -221
- package/tsconfig.json +0 -10
- package/vitest.config.ts +0 -8
package/dist/index.d.mts
ADDED
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
import { SzObject, ReadonlySzObject } from '@csszyx/compiler/browser';
|
|
2
|
+
export { ReadonlySzObject, SzObject } from '@csszyx/compiler/browser';
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
*
|
|
6
|
+
*/
|
|
7
|
+
type Tier = 'base' | 'sm' | 'md' | 'lg' | 'xl' | '2xl' | 'max-2xl' | 'max-xl' | 'max-lg' | 'max-md' | 'max-sm' | '@sm' | '@md' | '@lg' | '@xl' | '@2xl' | '@max-2xl' | '@max-xl' | '@max-lg' | '@max-md' | '@max-sm';
|
|
8
|
+
|
|
9
|
+
/**
|
|
10
|
+
* Manifest loading and caching.
|
|
11
|
+
*
|
|
12
|
+
* The manifest is a JSON file generated at build time by @csszyx/unplugin.
|
|
13
|
+
* It lists all original class names present in the built CSS so runtime
|
|
14
|
+
* dynamic() can skip injection for classes already covered.
|
|
15
|
+
*
|
|
16
|
+
* The manifest is fetched lazily on first dynamic() call (Qwik surgical pattern).
|
|
17
|
+
* Never inlined into HTML — each page only pays the cost if dynamic() is used.
|
|
18
|
+
*/
|
|
19
|
+
/**
|
|
20
|
+
*
|
|
21
|
+
*/
|
|
22
|
+
interface CSSManifest {
|
|
23
|
+
version: string;
|
|
24
|
+
buildId: string;
|
|
25
|
+
/** Original (non-mangled) class names present in built CSS. */
|
|
26
|
+
classes: string[];
|
|
27
|
+
/** Original → mangled map. Present only when production mangling is enabled. */
|
|
28
|
+
mangleMap?: Record<string, string>;
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
/**
|
|
32
|
+
* @csszyx/dynamic — Runtime CSS injection with delta check.
|
|
33
|
+
*
|
|
34
|
+
* Converts sz objects to Tailwind class strings at runtime, injecting CSS
|
|
35
|
+
* only for classes not already present in the pre-built stylesheet.
|
|
36
|
+
*
|
|
37
|
+
* Architecture:
|
|
38
|
+
* Layer 1 (manifest): Lazy-fetched JSON of all classes in built CSS.
|
|
39
|
+
* Layer 2 (generator): Tailwind class → CSS rule using v4 CSS var patterns.
|
|
40
|
+
* Layer 3 (injector): 21-tier CSSStyleSheet for correct breakpoint cascade.
|
|
41
|
+
*
|
|
42
|
+
* SSR-safe: on server, returns class names only — no CSSOM access.
|
|
43
|
+
*
|
|
44
|
+
* @example
|
|
45
|
+
* // Framework-agnostic usage
|
|
46
|
+
* import { dynamic, preloadManifest } from '@csszyx/dynamic';
|
|
47
|
+
*
|
|
48
|
+
* await preloadManifest('/csszyx-manifest.json'); // optional: eagerly load
|
|
49
|
+
* const cls = dynamic({ p: 4, bg: 'blue-500' }); // → "p-4 bg-blue-500"
|
|
50
|
+
*/
|
|
51
|
+
|
|
52
|
+
/**
|
|
53
|
+
* Transforms sz props at runtime and injects CSS only for classes not already
|
|
54
|
+
* in the pre-built stylesheet. Lazy-loads manifest on first call.
|
|
55
|
+
*
|
|
56
|
+
* SSR-safe: on server, returns class names without CSSOM access.
|
|
57
|
+
*
|
|
58
|
+
* @param szProps - sz object (e.g. { p: 4, bg: 'blue-500', hover: { bg: 'blue-600' } }). Accepts both mutable and `as const` objects.
|
|
59
|
+
* @returns space-separated class string (e.g. "p-4 bg-blue-500 hover:bg-blue-600")
|
|
60
|
+
*
|
|
61
|
+
* @example
|
|
62
|
+
* const cls = dynamic({ p: 4, bg: 'blue-500' });
|
|
63
|
+
* // → "p-4 bg-blue-500" (injects CSS for classes not in built stylesheet)
|
|
64
|
+
*/
|
|
65
|
+
declare function dynamic(szProps: SzObject | ReadonlySzObject): string;
|
|
66
|
+
/**
|
|
67
|
+
* Eagerly preloads the CSS manifest.
|
|
68
|
+
* Without this, the manifest is lazy-loaded on the first dynamic() call.
|
|
69
|
+
* Call at app startup or on route enter for zero-latency first inject.
|
|
70
|
+
*
|
|
71
|
+
* @param url - manifest URL (default: '/csszyx-manifest.json')
|
|
72
|
+
* @returns promise that resolves when the manifest has been fetched and cached
|
|
73
|
+
* @example
|
|
74
|
+
* await preloadManifest('/csszyx-manifest.json');
|
|
75
|
+
*/
|
|
76
|
+
declare function preloadManifest(url?: string): Promise<void>;
|
|
77
|
+
/**
|
|
78
|
+
* Releases all CSSStyleSheet tiers from adoptedStyleSheets, clears the
|
|
79
|
+
* injected class cache, and resets the manifest reference.
|
|
80
|
+
*
|
|
81
|
+
* Call on route unmount when the dynamic-styled component tree is destroyed.
|
|
82
|
+
* Next dynamic() call will re-fetch the manifest and re-init sheets.
|
|
83
|
+
*
|
|
84
|
+
* @example
|
|
85
|
+
* useEffect(() => {
|
|
86
|
+
* return () => cleanup();
|
|
87
|
+
* }, []);
|
|
88
|
+
*/
|
|
89
|
+
declare function cleanup(): void;
|
|
90
|
+
|
|
91
|
+
export { cleanup, dynamic, preloadManifest };
|
|
92
|
+
export type { CSSManifest, Tier };
|
package/dist/index.mjs
ADDED
package/dist/react.d.mts
ADDED
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
import { SzObject } from '@csszyx/compiler/browser';
|
|
2
|
+
import { ReactNode, ReactElement } from 'react';
|
|
3
|
+
import { dynamic } from './index.mjs';
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* React integration for @csszyx/dynamic.
|
|
7
|
+
*
|
|
8
|
+
* Provides:
|
|
9
|
+
* - sz: direct alias for dynamic() (cleaner import in React files)
|
|
10
|
+
* - useSz(): hook returning stable { sz } object with cleanup on unmount
|
|
11
|
+
* - CsszyxProvider: optional context for custom manifest URL
|
|
12
|
+
*
|
|
13
|
+
* @example
|
|
14
|
+
* // Simple usage
|
|
15
|
+
* import { sz } from '@csszyx/dynamic/react';
|
|
16
|
+
* const cls = sz({ p: 4, bg: 'blue-500' });
|
|
17
|
+
*
|
|
18
|
+
* @example
|
|
19
|
+
* // Hook usage (recommended — handles manifest + cleanup automatically)
|
|
20
|
+
* import { useSz } from '@csszyx/dynamic/react';
|
|
21
|
+
* function FormField({ schema }) {
|
|
22
|
+
* const { sz } = useSz();
|
|
23
|
+
* return <div className={sz(schema.style)}>{schema.label}</div>;
|
|
24
|
+
* }
|
|
25
|
+
*
|
|
26
|
+
* @example
|
|
27
|
+
* // Custom manifest URL
|
|
28
|
+
* import { CsszyxProvider } from '@csszyx/dynamic/react';
|
|
29
|
+
* <CsszyxProvider manifest="/assets/csszyx-manifest.json">
|
|
30
|
+
* <App />
|
|
31
|
+
* </CsszyxProvider>
|
|
32
|
+
*/
|
|
33
|
+
|
|
34
|
+
/**
|
|
35
|
+
* Runtime alias for dynamic(). Use in React files for consistency with
|
|
36
|
+
* the build-time `sz` prop: `sz={{ p: 4 }}` at build, `sz({ p: 4 })` at runtime.
|
|
37
|
+
*/
|
|
38
|
+
declare const sz: typeof dynamic;
|
|
39
|
+
/**
|
|
40
|
+
*
|
|
41
|
+
*/
|
|
42
|
+
interface UseSzReturn {
|
|
43
|
+
/**
|
|
44
|
+
* Converts sz props to a class string, injecting CSS for new classes.
|
|
45
|
+
* Stable reference — safe to pass as a prop without useMemo.
|
|
46
|
+
*/
|
|
47
|
+
sz: (props: SzObject) => string;
|
|
48
|
+
}
|
|
49
|
+
/**
|
|
50
|
+
* React hook for runtime dynamic styling.
|
|
51
|
+
*
|
|
52
|
+
* Returns a stable `{ sz }` object. Preloads the manifest on mount.
|
|
53
|
+
* On unmount, releases CSSStyleSheet tiers and manifest cache — deferred
|
|
54
|
+
* to survive React 18 StrictMode's double-mount/unmount cycle.
|
|
55
|
+
*
|
|
56
|
+
* @returns stable object containing the sz function for converting sz props to class strings
|
|
57
|
+
* @example
|
|
58
|
+
* const { sz } = useSz();
|
|
59
|
+
* return <div className={sz(apiResponse.field.style)} />;
|
|
60
|
+
*/
|
|
61
|
+
declare function useSz(): UseSzReturn;
|
|
62
|
+
/**
|
|
63
|
+
*
|
|
64
|
+
*/
|
|
65
|
+
interface CsszyxProviderProps {
|
|
66
|
+
/** Custom manifest URL (default: '/csszyx-manifest.json'). */
|
|
67
|
+
manifest: string;
|
|
68
|
+
children: ReactNode;
|
|
69
|
+
}
|
|
70
|
+
/**
|
|
71
|
+
* Optional React context for custom manifest path or non-root deployments.
|
|
72
|
+
* Without Provider, dynamic() defaults to fetching /csszyx-manifest.json.
|
|
73
|
+
*
|
|
74
|
+
* @param props - component props
|
|
75
|
+
* @param props.manifest - URL to the csszyx manifest JSON file
|
|
76
|
+
* @param props.children - child React nodes to render within the provider
|
|
77
|
+
* @returns React element wrapping children in a CsszyxContext.Provider
|
|
78
|
+
* @example
|
|
79
|
+
* <CsszyxProvider manifest="/api/assets/csszyx-manifest.json">
|
|
80
|
+
* <App />
|
|
81
|
+
* </CsszyxProvider>
|
|
82
|
+
*/
|
|
83
|
+
declare function CsszyxProvider({ manifest, children }: CsszyxProviderProps): ReactElement;
|
|
84
|
+
|
|
85
|
+
export { CsszyxProvider, sz, useSz };
|
|
86
|
+
export type { UseSzReturn };
|
package/dist/react.mjs
ADDED
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import { createContext, useEffect, createElement, useContext, useCallback } from 'react';
|
|
2
|
+
import { d as dynamic, p as preloadManifest, c as cleanup, r as resetManifest, s as setManifestUrl } from './shared/dynamic.BLXLKBNg.mjs';
|
|
3
|
+
import '@csszyx/compiler/browser';
|
|
4
|
+
|
|
5
|
+
const CsszyxContext = createContext({
|
|
6
|
+
manifestUrl: "/csszyx-manifest.json"
|
|
7
|
+
});
|
|
8
|
+
const sz = dynamic;
|
|
9
|
+
let _cleanupTimer = null;
|
|
10
|
+
function useSz() {
|
|
11
|
+
const { manifestUrl } = useContext(CsszyxContext);
|
|
12
|
+
const stableSz = useCallback((props) => dynamic(props), []);
|
|
13
|
+
useEffect(() => {
|
|
14
|
+
if (_cleanupTimer !== null) {
|
|
15
|
+
clearTimeout(_cleanupTimer);
|
|
16
|
+
_cleanupTimer = null;
|
|
17
|
+
}
|
|
18
|
+
preloadManifest(manifestUrl);
|
|
19
|
+
return () => {
|
|
20
|
+
_cleanupTimer = setTimeout(() => {
|
|
21
|
+
cleanup();
|
|
22
|
+
resetManifest();
|
|
23
|
+
_cleanupTimer = null;
|
|
24
|
+
}, 0);
|
|
25
|
+
};
|
|
26
|
+
}, [manifestUrl]);
|
|
27
|
+
return { sz: stableSz };
|
|
28
|
+
}
|
|
29
|
+
function CsszyxProvider({ manifest, children }) {
|
|
30
|
+
useEffect(() => {
|
|
31
|
+
setManifestUrl(manifest);
|
|
32
|
+
preloadManifest(manifest);
|
|
33
|
+
}, [manifest]);
|
|
34
|
+
return createElement(CsszyxContext.Provider, { value: { manifestUrl: manifest } }, children);
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
export { CsszyxProvider, sz, useSz };
|