@@ -33,6 +33,25 @@ const useCommitEffect = typeof window === 'undefined'
3333 ? useEffect
3434 : useLayoutEffect
3535const CSS_VARIABLE_NAME_RE = / ^ - - [ A - Z a - z 0 - 9 _ - ] + $ /
36+ const EMPTY_METADATA = {
37+ hasVars : false ,
38+ vars : [ ] ,
39+ hasMedia : false ,
40+ hasViewportUnits : false ,
41+ hasInterpolations : false ,
42+ hasDynamicRuntimeDependencies : false ,
43+ hasAnimations : false ,
44+ hasTransitions : false
45+ }
46+ const EMPTY_LAYER_SHEET : CompiledCssSheet = {
47+ version : 1 ,
48+ id : 'cssx_empty_layer' ,
49+ contentHash : 'cssx_empty_layer' ,
50+ rules : [ ] ,
51+ keyframes : { } ,
52+ metadata : EMPTY_METADATA ,
53+ diagnostics : [ ]
54+ }
3655
3756export type CssxLayerHookInput =
3857 | string
@@ -67,14 +86,10 @@ export function useCssxSheet (
6786 ...context ,
6887 ...options
6988 }
70-
71- if ( trackerRef . current == null ) {
72- trackerRef . current = new TrackedCssxSheet ( sheet , mergedOptions )
73- } else {
74- trackerRef . current . update ( sheet , mergedOptions )
75- }
76-
77- const tracker = trackerRef . current
89+ const committedTracker = trackerRef . current
90+ const tracker = committedTracker ?. matches ( sheet , mergedOptions )
91+ ? committedTracker
92+ : new TrackedCssxSheet ( sheet , mergedOptions )
7893 const renderDependencies = tracker . startRender ( )
7994
8095 useSyncExternalStore (
@@ -85,6 +100,7 @@ export function useCssxSheet (
85100
86101 useCommitEffect ( ( ) => {
87102 tracker . commitRender ( renderDependencies )
103+ trackerRef . current = tracker
88104 } )
89105
90106 return tracker
@@ -119,30 +135,42 @@ export function useCssxLayer (
119135 input : CssxLayerHookInput ,
120136 options : CssxReactConfig = { }
121137) : CssxLayerHookOutput {
122- if ( ! input ) return input
123-
124- if ( typeof input === 'string' ) return useRuntimeCss ( input , options )
125- if ( input instanceof TrackedCssxSheet ) return input
126- if ( isCompiledSheet ( input ) ) return useCssxSheet ( input , options )
138+ const context = useCssxConfig ( )
139+ const target = options . target ?? context . target
140+ const normalized = useMemo (
141+ ( ) => normalizeLayerHookInput ( input , target ) ,
142+ [ input , target ]
143+ )
144+ const tracker = useCssxSheet ( normalized . sheet , {
145+ ...options ,
146+ values : normalized . values
147+ } )
127148
128- if ( isLayerObject ( input ) ) {
129- const sheet = input . sheet
130- if ( typeof sheet === 'string' ) {
131- return {
132- ...input ,
133- sheet : useRuntimeCss ( sheet , options )
149+ switch ( normalized . kind ) {
150+ case 'empty' :
151+ return input as null | undefined | false
152+ case 'tracked' :
153+ return input as CssxLayerHookOutput
154+ case 'layerTracked' :
155+ return input as CssxLayerHookOutput
156+ case 'layerString' : {
157+ const layerInput = input as {
158+ sheet : string | CompiledCssSheet | TrackedCssxSheet
159+ values ?: readonly unknown [ ]
134160 }
161+ return {
162+ ...layerInput ,
163+ sheet : tracker
164+ } as CssxLayerHookOutput
135165 }
136- if ( sheet instanceof TrackedCssxSheet ) return input as CssxLayerHookOutput
137- if ( isCompiledSheet ( sheet ) ) {
138- return useCssxSheet ( sheet , {
139- ... options ,
140- values : input . values
141- } )
142- }
166+ case 'compiled' :
167+ case 'string' :
168+ case 'layerCompiled' :
169+ return tracker
170+ case 'unknown' :
171+ default :
172+ return input as CssxLayerHookOutput
143173 }
144-
145- return input as CssxLayerHookOutput
146174}
147175
148176export function useCssVariableRaw (
@@ -151,16 +179,20 @@ export function useCssVariableRaw (
151179) : string | undefined {
152180 assertCssVariableName ( name )
153181 const context = useCssxRuntimeContext ( )
154- const dependenciesRef = useRef < CssxDependencySnapshot > ( createDependencySnapshot ( ) )
182+ const committedDependenciesRef = useRef < CssxDependencySnapshot > ( createDependencySnapshot ( ) )
155183 const result = resolveCssVariableRaw ( name , fallback , context . scopedVariables )
156- dependenciesRef . current = createVariableDependencySnapshot ( result )
184+ const renderDependencies = createVariableDependencySnapshot ( result )
157185
158186 useSyncExternalStore (
159- listener => subscribeRuntimeStore ( listener , ( ) => dependenciesRef . current ) ,
187+ listener => subscribeRuntimeStore ( listener , ( ) => committedDependenciesRef . current ) ,
160188 getRuntimeVersion ,
161189 getRuntimeVersion
162190 )
163191
192+ useCommitEffect ( ( ) => {
193+ committedDependenciesRef . current = renderDependencies
194+ } )
195+
164196 return result . value
165197}
166198
@@ -208,6 +240,80 @@ function isLayerObject (value: unknown): value is {
208240 )
209241}
210242
243+ type NormalizedLayerHookInput =
244+ | {
245+ kind : 'empty' | 'unknown' | 'tracked' | 'layerTracked'
246+ sheet : CompiledCssSheet
247+ values ?: readonly unknown [ ]
248+ }
249+ | {
250+ kind : 'string' | 'compiled' | 'layerString' | 'layerCompiled'
251+ sheet : CompiledCssSheet
252+ values ?: readonly unknown [ ]
253+ }
254+
255+ function normalizeLayerHookInput (
256+ input : CssxLayerHookInput ,
257+ target : CssxReactConfig [ 'target' ]
258+ ) : NormalizedLayerHookInput {
259+ if ( ! input ) {
260+ return {
261+ kind : 'empty' ,
262+ sheet : EMPTY_LAYER_SHEET
263+ }
264+ }
265+
266+ if ( typeof input === 'string' ) {
267+ return {
268+ kind : 'string' ,
269+ sheet : compileCss ( input , { target } )
270+ }
271+ }
272+
273+ if ( input instanceof TrackedCssxSheet ) {
274+ return {
275+ kind : 'tracked' ,
276+ sheet : EMPTY_LAYER_SHEET
277+ }
278+ }
279+
280+ if ( isCompiledSheet ( input ) ) {
281+ return {
282+ kind : 'compiled' ,
283+ sheet : input
284+ }
285+ }
286+
287+ if ( isLayerObject ( input ) ) {
288+ const sheet = input . sheet
289+ if ( typeof sheet === 'string' ) {
290+ return {
291+ kind : 'layerString' ,
292+ sheet : compileCss ( sheet , { target } ) ,
293+ values : input . values
294+ }
295+ }
296+ if ( sheet instanceof TrackedCssxSheet ) {
297+ return {
298+ kind : 'layerTracked' ,
299+ sheet : EMPTY_LAYER_SHEET
300+ }
301+ }
302+ if ( isCompiledSheet ( sheet ) ) {
303+ return {
304+ kind : 'layerCompiled' ,
305+ sheet,
306+ values : input . values
307+ }
308+ }
309+ }
310+
311+ return {
312+ kind : 'unknown' ,
313+ sheet : EMPTY_LAYER_SHEET
314+ }
315+ }
316+
211317function resolveCssVariableRaw (
212318 name : string ,
213319 fallback ?: unknown ,
0 commit comments