@pyreon/styler 0.11.6 → 0.11.8
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/lib/index.js +22 -16
- package/package.json +4 -4
- package/src/styled.tsx +42 -14
package/lib/index.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { createContext, h, provide, useContext } from "@pyreon/core";
|
|
2
|
-
import { effect } from "@pyreon/reactivity";
|
|
2
|
+
import { effect, runUntracked } from "@pyreon/reactivity";
|
|
3
3
|
|
|
4
4
|
//#region src/resolve.ts
|
|
5
5
|
/**
|
|
@@ -799,13 +799,15 @@ const createStyledComponent = (tag, strings, values, options) => {
|
|
|
799
799
|
const DynamicStyled = (rawProps) => {
|
|
800
800
|
const theme = useTheme();
|
|
801
801
|
const $rs = rawProps.$rocketstyle;
|
|
802
|
+
const $rsState = rawProps.$rocketstate;
|
|
802
803
|
const isReactiveRS = typeof $rs === "function";
|
|
804
|
+
const isReactiveState = typeof $rsState === "function";
|
|
803
805
|
const resolvedRS = isReactiveRS ? $rs() : $rs;
|
|
806
|
+
const resolvedState = isReactiveState ? $rsState() : $rsState;
|
|
804
807
|
const cssText = normalizeCSS(resolve(strings, values, {
|
|
805
|
-
...
|
|
806
|
-
|
|
807
|
-
|
|
808
|
-
} : rawProps,
|
|
808
|
+
...rawProps,
|
|
809
|
+
...isReactiveRS ? { $rocketstyle: resolvedRS } : {},
|
|
810
|
+
...isReactiveState ? { $rocketstate: resolvedState } : {},
|
|
809
811
|
theme
|
|
810
812
|
}));
|
|
811
813
|
const initialClassName = cssText.length > 0 ? sheet.insert(cssText, boost) : "";
|
|
@@ -827,17 +829,21 @@ const createStyledComponent = (tag, strings, values, options) => {
|
|
|
827
829
|
}, initialClassName, isDOM, customFilter);
|
|
828
830
|
if (isReactiveRS) effect(() => {
|
|
829
831
|
const newRS = $rs();
|
|
830
|
-
const
|
|
831
|
-
|
|
832
|
-
|
|
833
|
-
|
|
834
|
-
|
|
835
|
-
|
|
836
|
-
|
|
837
|
-
|
|
838
|
-
|
|
839
|
-
|
|
840
|
-
|
|
832
|
+
const newState = isReactiveState ? $rsState() : $rsState;
|
|
833
|
+
runUntracked(() => {
|
|
834
|
+
const newCss = normalizeCSS(resolve(strings, values, {
|
|
835
|
+
...rawProps,
|
|
836
|
+
$rocketstyle: newRS,
|
|
837
|
+
$rocketstate: newState,
|
|
838
|
+
theme
|
|
839
|
+
}));
|
|
840
|
+
const newClass = newCss.length > 0 ? sheet.insert(newCss, boost) : "";
|
|
841
|
+
if (el && newClass !== currentClassName) {
|
|
842
|
+
if (currentClassName) el.classList.remove(currentClassName);
|
|
843
|
+
if (newClass) el.classList.add(newClass);
|
|
844
|
+
currentClassName = newClass;
|
|
845
|
+
}
|
|
846
|
+
});
|
|
841
847
|
});
|
|
842
848
|
return h(finalTag, finalProps, ...Array.isArray(rawProps.children) ? rawProps.children : rawProps.children != null ? [rawProps.children] : []);
|
|
843
849
|
};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@pyreon/styler",
|
|
3
|
-
"version": "0.11.
|
|
3
|
+
"version": "0.11.8",
|
|
4
4
|
"description": "Lightweight CSS-in-JS engine for Pyreon",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"repository": {
|
|
@@ -41,12 +41,12 @@
|
|
|
41
41
|
"typecheck": "tsc --noEmit"
|
|
42
42
|
},
|
|
43
43
|
"devDependencies": {
|
|
44
|
-
"@pyreon/typescript": "^0.11.
|
|
44
|
+
"@pyreon/typescript": "^0.11.8",
|
|
45
45
|
"@vitus-labs/tools-rolldown": "^1.15.3"
|
|
46
46
|
},
|
|
47
47
|
"peerDependencies": {
|
|
48
|
-
"@pyreon/core": "^0.11.
|
|
49
|
-
"@pyreon/reactivity": "^0.11.
|
|
48
|
+
"@pyreon/core": "^0.11.8",
|
|
49
|
+
"@pyreon/reactivity": "^0.11.8"
|
|
50
50
|
},
|
|
51
51
|
"engines": {
|
|
52
52
|
"node": ">= 22"
|
package/src/styled.tsx
CHANGED
|
@@ -17,7 +17,7 @@
|
|
|
17
17
|
*/
|
|
18
18
|
import type { ComponentFn, VNode } from '@pyreon/core'
|
|
19
19
|
import { h } from '@pyreon/core'
|
|
20
|
-
import { effect } from '@pyreon/reactivity'
|
|
20
|
+
import { effect, runUntracked } from '@pyreon/reactivity'
|
|
21
21
|
import { buildProps } from './forward'
|
|
22
22
|
import { type Interpolation, normalizeCSS, resolve } from './resolve'
|
|
23
23
|
import { isDynamic } from './shared'
|
|
@@ -132,11 +132,22 @@ const createStyledComponent = (
|
|
|
132
132
|
const DynamicStyled: ComponentFn = (rawProps: Record<string, any>): VNode | null => {
|
|
133
133
|
const theme = useTheme()
|
|
134
134
|
const $rs = rawProps.$rocketstyle
|
|
135
|
+
const $rsState = rawProps.$rocketstate
|
|
135
136
|
const isReactiveRS = typeof $rs === 'function'
|
|
137
|
+
const isReactiveState = typeof $rsState === 'function'
|
|
136
138
|
|
|
137
|
-
// Resolve initial $rocketstyle
|
|
139
|
+
// Resolve initial accessor values — both $rocketstyle and $rocketstate
|
|
140
|
+
// must be plain objects when passed to resolve(), because .styles()
|
|
141
|
+
// interpolation functions destructure them directly:
|
|
142
|
+
// const { hover, pressed } = $rocketstate.pseudo
|
|
143
|
+
// const { hover: hoverStyles } = $rocketstyle
|
|
138
144
|
const resolvedRS = isReactiveRS ? $rs() : $rs
|
|
139
|
-
const
|
|
145
|
+
const resolvedState = isReactiveState ? $rsState() : $rsState
|
|
146
|
+
const initialProps = {
|
|
147
|
+
...rawProps,
|
|
148
|
+
...(isReactiveRS ? { $rocketstyle: resolvedRS } : {}),
|
|
149
|
+
...(isReactiveState ? { $rocketstate: resolvedState } : {}),
|
|
150
|
+
}
|
|
140
151
|
const cssText = normalizeCSS(resolve(strings, values, { ...initialProps, theme }))
|
|
141
152
|
const initialClassName = cssText.length > 0 ? sheet.insert(cssText, boost) : ''
|
|
142
153
|
|
|
@@ -163,19 +174,36 @@ const createStyledComponent = (
|
|
|
163
174
|
customFilter,
|
|
164
175
|
)
|
|
165
176
|
|
|
166
|
-
// Set up reactive class swap when $rocketstyle is a function accessor
|
|
177
|
+
// Set up reactive class swap when $rocketstyle is a function accessor.
|
|
178
|
+
// CRITICAL: only $rs() is tracked. resolve() and DOM mutations run
|
|
179
|
+
// inside runUntracked() to prevent subscribing to signals read by
|
|
180
|
+
// interpolation functions (theme properties, context getters, etc.).
|
|
181
|
+
// Without this, every styled component's effect subscribes to every
|
|
182
|
+
// signal touched during CSS resolution — causing an exponential
|
|
183
|
+
// cascade across 50+ components on any signal change.
|
|
167
184
|
if (isReactiveRS) {
|
|
168
185
|
effect(() => {
|
|
169
|
-
const newRS = $rs() //
|
|
170
|
-
const
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
186
|
+
const newRS = $rs() // TRACKED: subscribes to mode + dimension signals
|
|
187
|
+
const newState = isReactiveState ? $rsState() : $rsState // TRACKED
|
|
188
|
+
|
|
189
|
+
runUntracked(() => {
|
|
190
|
+
// UNTRACKED: resolve + DOM mutation — no additional subscriptions
|
|
191
|
+
const newResolvedProps = {
|
|
192
|
+
...rawProps,
|
|
193
|
+
$rocketstyle: newRS,
|
|
194
|
+
$rocketstate: newState,
|
|
195
|
+
}
|
|
196
|
+
const newCss = normalizeCSS(
|
|
197
|
+
resolve(strings, values, { ...newResolvedProps, theme }),
|
|
198
|
+
)
|
|
199
|
+
const newClass = newCss.length > 0 ? sheet.insert(newCss, boost) : ''
|
|
200
|
+
|
|
201
|
+
if (el && newClass !== currentClassName) {
|
|
202
|
+
if (currentClassName) el.classList.remove(currentClassName)
|
|
203
|
+
if (newClass) el.classList.add(newClass)
|
|
204
|
+
currentClassName = newClass
|
|
205
|
+
}
|
|
206
|
+
})
|
|
179
207
|
})
|
|
180
208
|
}
|
|
181
209
|
|