@pyreon/styler 0.16.0 → 0.18.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/lib/index.d.ts +8 -0
- package/lib/index.js +16 -4
- package/package.json +5 -5
- package/src/forward.ts +24 -5
package/lib/index.d.ts
CHANGED
|
@@ -99,6 +99,14 @@ declare const filterProps: (props: Record<string, unknown>) => Record<string, un
|
|
|
99
99
|
* Build final props for a styled component in a single pass.
|
|
100
100
|
* Combines className merging, ref injection, and prop filtering into one
|
|
101
101
|
* allocation and one iteration.
|
|
102
|
+
*
|
|
103
|
+
* Copies own property DESCRIPTORS rather than values for forwarded
|
|
104
|
+
* props — getter-shaped reactive props (compiler-emitted `_rp(() =>
|
|
105
|
+
* signal())` converted to getters by `makeReactiveProps`) survive the
|
|
106
|
+
* copy with their reactive subscription intact. A bare `result[key] =
|
|
107
|
+
* rawProps[key]` fires the getter at setup time and stores a static
|
|
108
|
+
* value, breaking signal-driven reactivity for any consumer that reads
|
|
109
|
+
* `props.x` in a reactive scope downstream.
|
|
102
110
|
*/
|
|
103
111
|
declare const buildProps: (rawProps: Record<string, any>, generatedCls: string, isDOM: boolean, customFilter?: (prop: string) => boolean) => Record<string, any>;
|
|
104
112
|
//#endregion
|
package/lib/index.js
CHANGED
|
@@ -331,24 +331,36 @@ const filterProps = (props) => {
|
|
|
331
331
|
* Build final props for a styled component in a single pass.
|
|
332
332
|
* Combines className merging, ref injection, and prop filtering into one
|
|
333
333
|
* allocation and one iteration.
|
|
334
|
+
*
|
|
335
|
+
* Copies own property DESCRIPTORS rather than values for forwarded
|
|
336
|
+
* props — getter-shaped reactive props (compiler-emitted `_rp(() =>
|
|
337
|
+
* signal())` converted to getters by `makeReactiveProps`) survive the
|
|
338
|
+
* copy with their reactive subscription intact. A bare `result[key] =
|
|
339
|
+
* rawProps[key]` fires the getter at setup time and stores a static
|
|
340
|
+
* value, breaking signal-driven reactivity for any consumer that reads
|
|
341
|
+
* `props.x` in a reactive scope downstream.
|
|
334
342
|
*/
|
|
335
343
|
const buildProps = (rawProps, generatedCls, isDOM, customFilter) => {
|
|
336
344
|
const result = {};
|
|
337
345
|
const userCls = rawProps.class || rawProps.className;
|
|
338
346
|
if (generatedCls) result.class = userCls ? `${generatedCls} ${userCls}` : generatedCls;
|
|
339
347
|
else if (userCls) result.class = userCls;
|
|
348
|
+
const copyDescriptor = (key) => {
|
|
349
|
+
const d = Object.getOwnPropertyDescriptor(rawProps, key);
|
|
350
|
+
if (d) Object.defineProperty(result, key, d);
|
|
351
|
+
};
|
|
340
352
|
if (!isDOM) {
|
|
341
353
|
for (const key in rawProps) {
|
|
342
354
|
if (key === "as" || key === "className" || key === "class") continue;
|
|
343
355
|
if (key.charCodeAt(0) === 36) continue;
|
|
344
|
-
|
|
356
|
+
copyDescriptor(key);
|
|
345
357
|
}
|
|
346
358
|
return result;
|
|
347
359
|
}
|
|
348
360
|
if (customFilter) {
|
|
349
361
|
for (const key in rawProps) {
|
|
350
362
|
if (key === "as" || key === "className" || key === "class") continue;
|
|
351
|
-
if (customFilter(key))
|
|
363
|
+
if (customFilter(key)) copyDescriptor(key);
|
|
352
364
|
}
|
|
353
365
|
return result;
|
|
354
366
|
}
|
|
@@ -356,10 +368,10 @@ const buildProps = (rawProps, generatedCls, isDOM, customFilter) => {
|
|
|
356
368
|
if (key === "as" || key === "className" || key === "class") continue;
|
|
357
369
|
if (key.charCodeAt(0) === 36) continue;
|
|
358
370
|
if (key.startsWith("data-") || key.startsWith("aria-")) {
|
|
359
|
-
|
|
371
|
+
copyDescriptor(key);
|
|
360
372
|
continue;
|
|
361
373
|
}
|
|
362
|
-
if (HTML_PROPS.has(key))
|
|
374
|
+
if (HTML_PROPS.has(key)) copyDescriptor(key);
|
|
363
375
|
}
|
|
364
376
|
return result;
|
|
365
377
|
};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@pyreon/styler",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.18.0",
|
|
4
4
|
"description": "Lightweight CSS-in-JS engine for Pyreon",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"repository": {
|
|
@@ -42,8 +42,8 @@
|
|
|
42
42
|
"typecheck": "tsc --noEmit"
|
|
43
43
|
},
|
|
44
44
|
"devDependencies": {
|
|
45
|
-
"@pyreon/test-utils": "^0.13.
|
|
46
|
-
"@pyreon/typescript": "^0.
|
|
45
|
+
"@pyreon/test-utils": "^0.13.5",
|
|
46
|
+
"@pyreon/typescript": "^0.18.0",
|
|
47
47
|
"@vitest/browser-playwright": "^4.1.4",
|
|
48
48
|
"@vitus-labs/tools-rolldown": "^2.3.0"
|
|
49
49
|
},
|
|
@@ -51,7 +51,7 @@
|
|
|
51
51
|
"node": ">= 22"
|
|
52
52
|
},
|
|
53
53
|
"dependencies": {
|
|
54
|
-
"@pyreon/core": "^0.
|
|
55
|
-
"@pyreon/reactivity": "^0.
|
|
54
|
+
"@pyreon/core": "^0.18.0",
|
|
55
|
+
"@pyreon/reactivity": "^0.18.0"
|
|
56
56
|
}
|
|
57
57
|
}
|
package/src/forward.ts
CHANGED
|
@@ -225,6 +225,14 @@ export const filterProps = (props: Record<string, unknown>): Record<string, unkn
|
|
|
225
225
|
* Build final props for a styled component in a single pass.
|
|
226
226
|
* Combines className merging, ref injection, and prop filtering into one
|
|
227
227
|
* allocation and one iteration.
|
|
228
|
+
*
|
|
229
|
+
* Copies own property DESCRIPTORS rather than values for forwarded
|
|
230
|
+
* props — getter-shaped reactive props (compiler-emitted `_rp(() =>
|
|
231
|
+
* signal())` converted to getters by `makeReactiveProps`) survive the
|
|
232
|
+
* copy with their reactive subscription intact. A bare `result[key] =
|
|
233
|
+
* rawProps[key]` fires the getter at setup time and stores a static
|
|
234
|
+
* value, breaking signal-driven reactivity for any consumer that reads
|
|
235
|
+
* `props.x` in a reactive scope downstream.
|
|
228
236
|
*/
|
|
229
237
|
export const buildProps = (
|
|
230
238
|
rawProps: Record<string, any>,
|
|
@@ -234,7 +242,11 @@ export const buildProps = (
|
|
|
234
242
|
): Record<string, any> => {
|
|
235
243
|
const result: Record<string, any> = {}
|
|
236
244
|
|
|
237
|
-
// Merge generated + user className
|
|
245
|
+
// Merge generated + user className. Reading `rawProps.class` /
|
|
246
|
+
// `.className` synchronously is fine — `class` is consumed at this
|
|
247
|
+
// boundary (merged with the generated class), never forwarded
|
|
248
|
+
// reactively. The string we write is consumed by the DOM at apply
|
|
249
|
+
// time, not stored as a getter.
|
|
238
250
|
const userCls = rawProps.class || rawProps.className
|
|
239
251
|
if (generatedCls) {
|
|
240
252
|
result.class = userCls ? `${generatedCls} ${userCls}` : generatedCls
|
|
@@ -242,12 +254,19 @@ export const buildProps = (
|
|
|
242
254
|
result.class = userCls
|
|
243
255
|
}
|
|
244
256
|
|
|
257
|
+
// Helper: copy a prop's OWN descriptor (preserves getters) into result.
|
|
258
|
+
// Falls back to a no-op if the source has no own descriptor for the key.
|
|
259
|
+
const copyDescriptor = (key: string): void => {
|
|
260
|
+
const d = Object.getOwnPropertyDescriptor(rawProps, key)
|
|
261
|
+
if (d) Object.defineProperty(result, key, d)
|
|
262
|
+
}
|
|
263
|
+
|
|
245
264
|
// Component target — forward all props except as/className/class and $-prefixed
|
|
246
265
|
if (!isDOM) {
|
|
247
266
|
for (const key in rawProps) {
|
|
248
267
|
if (key === 'as' || key === 'className' || key === 'class') continue
|
|
249
268
|
if (key.charCodeAt(0) === 36) continue // $-prefixed transient
|
|
250
|
-
|
|
269
|
+
copyDescriptor(key)
|
|
251
270
|
}
|
|
252
271
|
return result
|
|
253
272
|
}
|
|
@@ -256,7 +275,7 @@ export const buildProps = (
|
|
|
256
275
|
if (customFilter) {
|
|
257
276
|
for (const key in rawProps) {
|
|
258
277
|
if (key === 'as' || key === 'className' || key === 'class') continue
|
|
259
|
-
if (customFilter(key))
|
|
278
|
+
if (customFilter(key)) copyDescriptor(key)
|
|
260
279
|
}
|
|
261
280
|
return result
|
|
262
281
|
}
|
|
@@ -266,10 +285,10 @@ export const buildProps = (
|
|
|
266
285
|
if (key === 'as' || key === 'className' || key === 'class') continue
|
|
267
286
|
if (key.charCodeAt(0) === 36) continue // $-prefixed transient
|
|
268
287
|
if (key.startsWith('data-') || key.startsWith('aria-')) {
|
|
269
|
-
|
|
288
|
+
copyDescriptor(key)
|
|
270
289
|
continue
|
|
271
290
|
}
|
|
272
|
-
if (HTML_PROPS.has(key))
|
|
291
|
+
if (HTML_PROPS.has(key)) copyDescriptor(key)
|
|
273
292
|
}
|
|
274
293
|
return result
|
|
275
294
|
}
|