@pyreon/styler 0.24.4 → 0.24.6
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/package.json +5 -7
- package/src/ThemeProvider.ts +0 -65
- package/src/__tests__/ThemeProvider.test.ts +0 -67
- package/src/__tests__/benchmark.bench.ts +0 -200
- package/src/__tests__/composition-chain.test.ts +0 -537
- package/src/__tests__/css.test.ts +0 -70
- package/src/__tests__/dev-gate-treeshake.test.ts +0 -85
- package/src/__tests__/forward.test.ts +0 -282
- package/src/__tests__/globalStyle.test.ts +0 -72
- package/src/__tests__/hash.test.ts +0 -70
- package/src/__tests__/hybrid-injection.test.ts +0 -225
- package/src/__tests__/index.ts +0 -14
- package/src/__tests__/inject-rules.browser.test.ts +0 -40
- package/src/__tests__/insertion-effect.test.ts +0 -119
- package/src/__tests__/integration-dom.test.ts +0 -58
- package/src/__tests__/integration.test.ts +0 -179
- package/src/__tests__/keyframes.test.ts +0 -68
- package/src/__tests__/memory-growth.test.ts +0 -220
- package/src/__tests__/native-marker.test.ts +0 -9
- package/src/__tests__/p3-features.test.ts +0 -316
- package/src/__tests__/resolve-cache.test.ts +0 -94
- package/src/__tests__/resolve.test.ts +0 -308
- package/src/__tests__/shared.test.ts +0 -133
- package/src/__tests__/sheet-advanced.test.ts +0 -659
- package/src/__tests__/sheet-split-atrules.test.ts +0 -410
- package/src/__tests__/sheet.test.ts +0 -250
- package/src/__tests__/static-styler-resolve-cost.test.ts +0 -160
- package/src/__tests__/styled-reactive.test.ts +0 -74
- package/src/__tests__/styled-ssr.test.ts +0 -75
- package/src/__tests__/styled.test.ts +0 -511
- package/src/__tests__/styler.browser.test.tsx +0 -194
- package/src/__tests__/theme.test.ts +0 -33
- package/src/__tests__/useCSS.test.ts +0 -172
- package/src/css.ts +0 -13
- package/src/env.d.ts +0 -6
- package/src/forward.ts +0 -308
- package/src/globalStyle.ts +0 -53
- package/src/hash.ts +0 -28
- package/src/index.ts +0 -15
- package/src/keyframes.ts +0 -36
- package/src/manifest.ts +0 -332
- package/src/resolve.ts +0 -225
- package/src/shared.ts +0 -22
- package/src/sheet.ts +0 -635
- package/src/styled.tsx +0 -503
- package/src/tests/manifest-snapshot.test.ts +0 -51
- package/src/useCSS.ts +0 -20
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@pyreon/styler",
|
|
3
|
-
"version": "0.24.
|
|
3
|
+
"version": "0.24.6",
|
|
4
4
|
"description": "Lightweight CSS-in-JS engine for Pyreon",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"repository": {
|
|
@@ -13,8 +13,7 @@
|
|
|
13
13
|
"!lib/**/*.map",
|
|
14
14
|
"!lib/analysis",
|
|
15
15
|
"README.md",
|
|
16
|
-
"LICENSE"
|
|
17
|
-
"src"
|
|
16
|
+
"LICENSE"
|
|
18
17
|
],
|
|
19
18
|
"type": "module",
|
|
20
19
|
"sideEffects": false,
|
|
@@ -22,7 +21,6 @@
|
|
|
22
21
|
"types": "./lib/index.d.ts",
|
|
23
22
|
"exports": {
|
|
24
23
|
".": {
|
|
25
|
-
"bun": "./src/index.ts",
|
|
26
24
|
"import": "./lib/index.js",
|
|
27
25
|
"types": "./lib/index.d.ts"
|
|
28
26
|
}
|
|
@@ -44,7 +42,7 @@
|
|
|
44
42
|
"devDependencies": {
|
|
45
43
|
"@pyreon/manifest": "0.13.1",
|
|
46
44
|
"@pyreon/test-utils": "^0.13.11",
|
|
47
|
-
"@pyreon/typescript": "^0.24.
|
|
45
|
+
"@pyreon/typescript": "^0.24.6",
|
|
48
46
|
"@vitest/browser-playwright": "^4.1.4",
|
|
49
47
|
"@vitus-labs/tools-rolldown": "^2.4.0"
|
|
50
48
|
},
|
|
@@ -52,7 +50,7 @@
|
|
|
52
50
|
"node": ">= 22"
|
|
53
51
|
},
|
|
54
52
|
"dependencies": {
|
|
55
|
-
"@pyreon/core": "^0.24.
|
|
56
|
-
"@pyreon/reactivity": "^0.24.
|
|
53
|
+
"@pyreon/core": "^0.24.6",
|
|
54
|
+
"@pyreon/reactivity": "^0.24.6"
|
|
57
55
|
}
|
|
58
56
|
}
|
package/src/ThemeProvider.ts
DELETED
|
@@ -1,65 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Theme context for styled components.
|
|
3
|
-
*
|
|
4
|
-
* Extensible theme interface. Consumers can augment this via module
|
|
5
|
-
* declaration merging for full strict types:
|
|
6
|
-
*
|
|
7
|
-
* declare module '@pyreon/styler' {
|
|
8
|
-
* interface DefaultTheme {
|
|
9
|
-
* colors: { primary: string; secondary: string }
|
|
10
|
-
* spacing: (n: number) => string
|
|
11
|
-
* }
|
|
12
|
-
* }
|
|
13
|
-
*/
|
|
14
|
-
import type { VNode, VNodeChild } from '@pyreon/core'
|
|
15
|
-
import { createReactiveContext, nativeCompat, provide, useContext } from '@pyreon/core'
|
|
16
|
-
|
|
17
|
-
export interface DefaultTheme {}
|
|
18
|
-
|
|
19
|
-
type Theme = DefaultTheme & Record<string, unknown>
|
|
20
|
-
|
|
21
|
-
/**
|
|
22
|
-
* Reactive theme context. Consumers get `() => Theme` from useContext.
|
|
23
|
-
*
|
|
24
|
-
* The DIFFERENCE from PR #258: styled components read the theme accessor
|
|
25
|
-
* inside a COMPUTED (not an effect). The computed tracks theme + mode +
|
|
26
|
-
* dimensions simultaneously, and the resolve itself runs untracked.
|
|
27
|
-
* This gives reactive theme/mode/dimension switching with:
|
|
28
|
-
* - Zero per-component effect()
|
|
29
|
-
* - One lightweight computed per component
|
|
30
|
-
* - String-equality memoization (same CSS class = no DOM update)
|
|
31
|
-
* - Untracked resolve (no exponential cascade)
|
|
32
|
-
*/
|
|
33
|
-
export const ThemeContext = createReactiveContext<Theme>({} as Theme)
|
|
34
|
-
|
|
35
|
-
/**
|
|
36
|
-
* Read the current theme. Returns the theme value (calls the accessor).
|
|
37
|
-
* Inside a reactive scope (computed/effect), this tracks theme changes.
|
|
38
|
-
*/
|
|
39
|
-
export const useTheme = <T extends object = Theme>(): T => useContext(ThemeContext)() as T
|
|
40
|
-
|
|
41
|
-
/**
|
|
42
|
-
* Returns the raw `() => Theme` accessor for use inside computeds
|
|
43
|
-
* where you need explicit control over when the read happens.
|
|
44
|
-
*/
|
|
45
|
-
export const useThemeAccessor = <T extends object = Theme>(): (() => T) =>
|
|
46
|
-
useContext(ThemeContext) as () => T
|
|
47
|
-
|
|
48
|
-
/**
|
|
49
|
-
* @internal Low-level provider — use `PyreonUI` from `@pyreon/ui-core` instead.
|
|
50
|
-
* @deprecated Prefer `<PyreonUI theme={theme}>`
|
|
51
|
-
*/
|
|
52
|
-
export function ThemeProvider({
|
|
53
|
-
theme,
|
|
54
|
-
children,
|
|
55
|
-
}: {
|
|
56
|
-
theme: Theme
|
|
57
|
-
children?: VNodeChild
|
|
58
|
-
}): VNode | null {
|
|
59
|
-
provide(ThemeContext, () => theme)
|
|
60
|
-
return (children ?? null) as VNode | null
|
|
61
|
-
}
|
|
62
|
-
|
|
63
|
-
// Mark as native — compat-mode jsx() runtimes skip wrapCompatComponent so
|
|
64
|
-
// provide(ThemeContext, ...) reaches Pyreon's setup frame.
|
|
65
|
-
nativeCompat(ThemeProvider)
|
|
@@ -1,67 +0,0 @@
|
|
|
1
|
-
import { popContext } from '@pyreon/core'
|
|
2
|
-
import { afterEach, describe, expect, it } from 'vitest'
|
|
3
|
-
import { ThemeContext, ThemeProvider, useTheme } from '../ThemeProvider'
|
|
4
|
-
|
|
5
|
-
describe('ThemeContext', () => {
|
|
6
|
-
it('is a Context object with an id', () => {
|
|
7
|
-
expect(ThemeContext).toBeDefined()
|
|
8
|
-
expect(ThemeContext.id).toBeDefined()
|
|
9
|
-
})
|
|
10
|
-
|
|
11
|
-
it('has a symbol id for context identification', () => {
|
|
12
|
-
expect(typeof ThemeContext.id).toBe('symbol')
|
|
13
|
-
})
|
|
14
|
-
})
|
|
15
|
-
|
|
16
|
-
describe('ThemeProvider', () => {
|
|
17
|
-
afterEach(() => {
|
|
18
|
-
try {
|
|
19
|
-
popContext()
|
|
20
|
-
} catch {
|
|
21
|
-
// Ignore if no context was pushed
|
|
22
|
-
}
|
|
23
|
-
})
|
|
24
|
-
|
|
25
|
-
it('returns children when provided', () => {
|
|
26
|
-
const children = 'Hello world'
|
|
27
|
-
const result = ThemeProvider({ theme: {}, children })
|
|
28
|
-
expect(result).toBe('Hello world')
|
|
29
|
-
})
|
|
30
|
-
|
|
31
|
-
it('returns null when no children are provided', () => {
|
|
32
|
-
const result = ThemeProvider({ theme: {} })
|
|
33
|
-
expect(result).toBeNull()
|
|
34
|
-
})
|
|
35
|
-
|
|
36
|
-
it('returns null when children is undefined', () => {
|
|
37
|
-
const result = ThemeProvider({ theme: {}, children: undefined })
|
|
38
|
-
expect(result).toBeNull()
|
|
39
|
-
})
|
|
40
|
-
|
|
41
|
-
it('provides theme via context (useTheme returns it)', () => {
|
|
42
|
-
const theme = { colors: { primary: 'red' }, spacing: 8 }
|
|
43
|
-
ThemeProvider({ theme, children: 'child' })
|
|
44
|
-
const result = useTheme()
|
|
45
|
-
expect(result).toEqual(theme)
|
|
46
|
-
})
|
|
47
|
-
})
|
|
48
|
-
|
|
49
|
-
describe('useTheme', () => {
|
|
50
|
-
it('is a function', () => {
|
|
51
|
-
expect(typeof useTheme).toBe('function')
|
|
52
|
-
})
|
|
53
|
-
|
|
54
|
-
it('returns the default theme (empty object) when called outside a provider', () => {
|
|
55
|
-
const theme = useTheme()
|
|
56
|
-
expect(theme).toEqual({})
|
|
57
|
-
})
|
|
58
|
-
|
|
59
|
-
it('can be called with a type parameter', () => {
|
|
60
|
-
interface MyTheme {
|
|
61
|
-
primary: string
|
|
62
|
-
spacing: number
|
|
63
|
-
}
|
|
64
|
-
const theme = useTheme<MyTheme>()
|
|
65
|
-
expect(theme).toBeDefined()
|
|
66
|
-
})
|
|
67
|
-
})
|
|
@@ -1,200 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Benchmark: @pyreon/styler CSS-in-JS operations
|
|
3
|
-
*
|
|
4
|
-
* Run: bun vitest bench
|
|
5
|
-
*
|
|
6
|
-
* Measures core CSS-in-JS operations:
|
|
7
|
-
* 1. css() tagged template creation
|
|
8
|
-
* 2. css() with interpolations
|
|
9
|
-
* 3. Template resolution to CSS string
|
|
10
|
-
* 4. Dynamic function interpolation
|
|
11
|
-
* 5. Hash function throughput
|
|
12
|
-
* 6. Nested css() composition
|
|
13
|
-
* 7. styled() component factory
|
|
14
|
-
* 8. normalizeCSS — Comment Stripping & Cleanup
|
|
15
|
-
*/
|
|
16
|
-
import { bench, describe } from 'vitest'
|
|
17
|
-
import { css } from '../css'
|
|
18
|
-
import { hash } from '../hash'
|
|
19
|
-
import { normalizeCSS, resolve } from '../resolve'
|
|
20
|
-
import { styled } from '../styled'
|
|
21
|
-
|
|
22
|
-
// ============================================================================
|
|
23
|
-
// 1. CSS Tagged Template — Creation Speed
|
|
24
|
-
// ============================================================================
|
|
25
|
-
describe('css() tagged template creation', () => {
|
|
26
|
-
bench('@pyreon/styler', () => {
|
|
27
|
-
css`
|
|
28
|
-
display: flex;
|
|
29
|
-
align-items: center;
|
|
30
|
-
justify-content: center;
|
|
31
|
-
padding: 16px;
|
|
32
|
-
margin: 8px;
|
|
33
|
-
background-color: #f0f0f0;
|
|
34
|
-
border-radius: 4px;
|
|
35
|
-
box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
|
|
36
|
-
`
|
|
37
|
-
})
|
|
38
|
-
})
|
|
39
|
-
|
|
40
|
-
// ============================================================================
|
|
41
|
-
// 2. CSS Tagged Template with Interpolations
|
|
42
|
-
// ============================================================================
|
|
43
|
-
describe('css() with interpolations', () => {
|
|
44
|
-
const color = '#ff0000'
|
|
45
|
-
const size = '16px'
|
|
46
|
-
|
|
47
|
-
bench('@pyreon/styler', () => {
|
|
48
|
-
css`
|
|
49
|
-
color: ${color};
|
|
50
|
-
font-size: ${size};
|
|
51
|
-
display: flex;
|
|
52
|
-
padding: 8px;
|
|
53
|
-
`
|
|
54
|
-
})
|
|
55
|
-
})
|
|
56
|
-
|
|
57
|
-
// ============================================================================
|
|
58
|
-
// 3. Template Resolution (strings + values -> CSS string)
|
|
59
|
-
// ============================================================================
|
|
60
|
-
describe('template resolution to CSS string', () => {
|
|
61
|
-
const strings = Object.assign(['display: flex; color: ', '; font-size: ', '; padding: 8px;'], {
|
|
62
|
-
raw: ['display: flex; color: ', '; font-size: ', '; padding: 8px;'],
|
|
63
|
-
}) as unknown as TemplateStringsArray
|
|
64
|
-
|
|
65
|
-
const values = ['red', '16px']
|
|
66
|
-
const props = { theme: { primary: 'blue' } }
|
|
67
|
-
|
|
68
|
-
bench('@pyreon/styler resolve()', () => {
|
|
69
|
-
resolve(strings, values, props)
|
|
70
|
-
})
|
|
71
|
-
})
|
|
72
|
-
|
|
73
|
-
// ============================================================================
|
|
74
|
-
// 4. Dynamic Interpolation (function interpolations)
|
|
75
|
-
// ============================================================================
|
|
76
|
-
describe('dynamic function interpolation', () => {
|
|
77
|
-
const props = { theme: { primary: 'blue', size: '14px' }, active: true }
|
|
78
|
-
|
|
79
|
-
const strings = Object.assign(['color: ', '; font-size: ', '; opacity: ', ';'], {
|
|
80
|
-
raw: ['color: ', '; font-size: ', '; opacity: ', ';'],
|
|
81
|
-
}) as unknown as TemplateStringsArray
|
|
82
|
-
|
|
83
|
-
const stylerValues = [
|
|
84
|
-
(p: any) => p.theme.primary,
|
|
85
|
-
(p: any) => p.theme.size,
|
|
86
|
-
(p: any) => (p.active ? '1' : '0.5'),
|
|
87
|
-
]
|
|
88
|
-
|
|
89
|
-
bench('@pyreon/styler resolve()', () => {
|
|
90
|
-
resolve(strings, stylerValues, props)
|
|
91
|
-
})
|
|
92
|
-
})
|
|
93
|
-
|
|
94
|
-
// ============================================================================
|
|
95
|
-
// 5. Hash Function Throughput
|
|
96
|
-
// ============================================================================
|
|
97
|
-
describe('hash function throughput', () => {
|
|
98
|
-
const shortCSS = 'display: flex; color: red;'
|
|
99
|
-
const mediumCSS =
|
|
100
|
-
'display: flex; align-items: center; justify-content: space-between; padding: 16px 24px; margin: 0 auto; max-width: 1200px; background-color: #ffffff; border: 1px solid #e0e0e0; border-radius: 8px; box-shadow: 0 2px 8px rgba(0,0,0,0.12);'
|
|
101
|
-
const longCSS = mediumCSS.repeat(5)
|
|
102
|
-
|
|
103
|
-
bench('@pyreon/styler FNV-1a (short)', () => {
|
|
104
|
-
hash(shortCSS)
|
|
105
|
-
})
|
|
106
|
-
|
|
107
|
-
bench('@pyreon/styler FNV-1a (medium)', () => {
|
|
108
|
-
hash(mediumCSS)
|
|
109
|
-
})
|
|
110
|
-
|
|
111
|
-
bench('@pyreon/styler FNV-1a (long)', () => {
|
|
112
|
-
hash(longCSS)
|
|
113
|
-
})
|
|
114
|
-
})
|
|
115
|
-
|
|
116
|
-
// ============================================================================
|
|
117
|
-
// 6. Nested css() Composition
|
|
118
|
-
// ============================================================================
|
|
119
|
-
describe('nested css() composition', () => {
|
|
120
|
-
bench('@pyreon/styler', () => {
|
|
121
|
-
const base = css`
|
|
122
|
-
display: flex;
|
|
123
|
-
padding: 8px;
|
|
124
|
-
`
|
|
125
|
-
const hover = css`
|
|
126
|
-
background: #eee;
|
|
127
|
-
`
|
|
128
|
-
const result = css`
|
|
129
|
-
${base};
|
|
130
|
-
&:hover {
|
|
131
|
-
${hover};
|
|
132
|
-
}
|
|
133
|
-
color: red;
|
|
134
|
-
`
|
|
135
|
-
result.toString()
|
|
136
|
-
})
|
|
137
|
-
})
|
|
138
|
-
|
|
139
|
-
// ============================================================================
|
|
140
|
-
// 7. Styled Component Creation (factory call)
|
|
141
|
-
// ============================================================================
|
|
142
|
-
describe('styled() component factory', () => {
|
|
143
|
-
bench('@pyreon/styler', () => {
|
|
144
|
-
styled('div')`
|
|
145
|
-
display: flex;
|
|
146
|
-
color: red;
|
|
147
|
-
padding: 8px;
|
|
148
|
-
`
|
|
149
|
-
})
|
|
150
|
-
})
|
|
151
|
-
|
|
152
|
-
// ============================================================================
|
|
153
|
-
// 8. normalizeCSS — Comment Stripping & Cleanup
|
|
154
|
-
// ============================================================================
|
|
155
|
-
describe('normalizeCSS', () => {
|
|
156
|
-
const plain =
|
|
157
|
-
' display: flex; align-items: center; justify-content: center; padding: 16px; margin: 8px; background-color: #f0f0f0; border-radius: 4px; '
|
|
158
|
-
|
|
159
|
-
const withBlockComments = `
|
|
160
|
-
/* -------------------------------------------------------- */
|
|
161
|
-
/* BASE STATE */
|
|
162
|
-
/* -------------------------------------------------------- */
|
|
163
|
-
display: flex; align-items: center; justify-content: center;
|
|
164
|
-
padding: 16px; margin: 8px; background-color: #f0f0f0;
|
|
165
|
-
/* -------------------------------------------------------- */
|
|
166
|
-
/* HOVER STATE */
|
|
167
|
-
/* -------------------------------------------------------- */
|
|
168
|
-
&:hover { color: red; background: blue; }
|
|
169
|
-
/* -------------------------------------------------------- */
|
|
170
|
-
/* ACTIVE STATE */
|
|
171
|
-
/* -------------------------------------------------------- */
|
|
172
|
-
&:active { color: green; }
|
|
173
|
-
`
|
|
174
|
-
|
|
175
|
-
const withLineComments = `
|
|
176
|
-
// base styles
|
|
177
|
-
display: flex; align-items: center;
|
|
178
|
-
// hover override
|
|
179
|
-
&:hover { color: red; }
|
|
180
|
-
background: url(https://example.com/img.png);
|
|
181
|
-
`
|
|
182
|
-
|
|
183
|
-
const withSemicolonJunk = ' ; display: flex;; ; color: red; ; font-size: 1rem;; ; '
|
|
184
|
-
|
|
185
|
-
bench('plain CSS (no comments)', () => {
|
|
186
|
-
normalizeCSS(plain)
|
|
187
|
-
})
|
|
188
|
-
|
|
189
|
-
bench('CSS with /* */ block comments', () => {
|
|
190
|
-
normalizeCSS(withBlockComments)
|
|
191
|
-
})
|
|
192
|
-
|
|
193
|
-
bench('CSS with // line comments', () => {
|
|
194
|
-
normalizeCSS(withLineComments)
|
|
195
|
-
})
|
|
196
|
-
|
|
197
|
-
bench('CSS with semicolon junk', () => {
|
|
198
|
-
normalizeCSS(withSemicolonJunk)
|
|
199
|
-
})
|
|
200
|
-
})
|