@pyreon/styler 0.11.4 → 0.11.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.
Files changed (36) hide show
  1. package/README.md +27 -23
  2. package/lib/index.d.ts +9 -2
  3. package/lib/index.js +47 -4
  4. package/package.json +22 -22
  5. package/src/ThemeProvider.ts +10 -3
  6. package/src/__tests__/ThemeProvider.test.ts +21 -21
  7. package/src/__tests__/benchmark.bench.ts +56 -45
  8. package/src/__tests__/composition-chain.test.ts +200 -151
  9. package/src/__tests__/forward.test.ts +122 -122
  10. package/src/__tests__/globalStyle.test.ts +18 -18
  11. package/src/__tests__/hash.test.ts +27 -27
  12. package/src/__tests__/hybrid-injection.test.ts +83 -59
  13. package/src/__tests__/index.ts +10 -10
  14. package/src/__tests__/insertion-effect.test.ts +45 -32
  15. package/src/__tests__/integration.test.ts +81 -51
  16. package/src/__tests__/keyframes.test.ts +13 -13
  17. package/src/__tests__/memory-growth.test.ts +21 -21
  18. package/src/__tests__/p3-features.test.ts +162 -104
  19. package/src/__tests__/shared.test.ts +51 -33
  20. package/src/__tests__/sheet-advanced.test.ts +227 -227
  21. package/src/__tests__/sheet-split-atrules.test.ts +85 -85
  22. package/src/__tests__/sheet.test.ts +69 -69
  23. package/src/__tests__/styled-ssr.test.ts +36 -28
  24. package/src/__tests__/styled.test.ts +214 -145
  25. package/src/__tests__/theme.test.ts +11 -11
  26. package/src/__tests__/useCSS.test.ts +89 -59
  27. package/src/css.ts +1 -1
  28. package/src/forward.ts +187 -187
  29. package/src/globalStyle.ts +5 -5
  30. package/src/index.ts +15 -15
  31. package/src/keyframes.ts +3 -3
  32. package/src/resolve.ts +14 -14
  33. package/src/shared.ts +2 -2
  34. package/src/sheet.ts +26 -26
  35. package/src/styled.tsx +145 -100
  36. package/src/useCSS.ts +4 -4
@@ -8,15 +8,15 @@
8
8
  * and inspect the returned VNode + the sheet's CSSOM.
9
9
  */
10
10
 
11
- import type { VNode } from "@pyreon/core"
12
- import { afterEach, describe, expect, it } from "vitest"
13
- import { createGlobalStyle } from "../globalStyle"
14
- import { sheet } from "../sheet"
15
- import { styled } from "../styled"
11
+ import type { VNode } from '@pyreon/core'
12
+ import { afterEach, describe, expect, it } from 'vitest'
13
+ import { createGlobalStyle } from '../globalStyle'
14
+ import { sheet } from '../sheet'
15
+ import { styled } from '../styled'
16
16
 
17
17
  /** Helper: collect all CSS rule texts from the shared <style data-pyreon-styler> sheet. */
18
18
  const getSheetRules = (): string[] => {
19
- const el = document.querySelector("style[data-pyreon-styler]") as HTMLStyleElement | null
19
+ const el = document.querySelector('style[data-pyreon-styler]') as HTMLStyleElement | null
20
20
  if (!el?.sheet) return []
21
21
  return Array.from(el.sheet.cssRules).map((r) => r.cssText)
22
22
  }
@@ -25,68 +25,78 @@ const getSheetRules = (): string[] => {
25
25
  const findRulesFor = (className: string): string[] =>
26
26
  getSheetRules().filter((r) => r.includes(`.${className}`))
27
27
 
28
- describe("hybrid injection — CSS in shared sheet", () => {
28
+ describe('hybrid injection — CSS in shared sheet', () => {
29
29
  afterEach(() => {
30
30
  sheet.clearAll()
31
31
  })
32
32
 
33
- describe("static styled components", () => {
34
- it("injects CSS rules into the shared <style data-pyreon-styler> element", () => {
35
- const Comp = styled("div")`color: red;`
33
+ describe('static styled components', () => {
34
+ it('injects CSS rules into the shared <style data-pyreon-styler> element', () => {
35
+ const Comp = styled('div')`
36
+ color: red;
37
+ `
36
38
  const vnode = Comp({}) as VNode
37
39
  const className = vnode.props.class as string
38
40
 
39
41
  const rules = findRulesFor(className)
40
42
  expect(rules.length).toBeGreaterThanOrEqual(1)
41
- expect(rules.some((r) => r.includes("color: red"))).toBe(true)
43
+ expect(rules.some((r) => r.includes('color: red'))).toBe(true)
42
44
  })
43
45
 
44
- it("multiple static components share the same <style> element", () => {
45
- const A = styled("div")`color: red;`
46
- const B = styled("span")`font-size: 20px;`
46
+ it('multiple static components share the same <style> element', () => {
47
+ const A = styled('div')`
48
+ color: red;
49
+ `
50
+ const B = styled('span')`
51
+ font-size: 20px;
52
+ `
47
53
 
48
54
  A({})
49
55
  B({})
50
56
 
51
57
  // Both should be in the same sheet
52
- const styleEls = document.querySelectorAll("style[data-pyreon-styler]")
58
+ const styleEls = document.querySelectorAll('style[data-pyreon-styler]')
53
59
  expect(styleEls.length).toBe(1)
54
60
 
55
61
  const rules = getSheetRules()
56
- expect(rules.some((r) => r.includes("color: red"))).toBe(true)
57
- expect(rules.some((r) => r.includes("font-size: 20px"))).toBe(true)
62
+ expect(rules.some((r) => r.includes('color: red'))).toBe(true)
63
+ expect(rules.some((r) => r.includes('font-size: 20px'))).toBe(true)
58
64
  })
59
65
  })
60
66
 
61
- describe("dynamic styled components", () => {
62
- it("injects CSS into the shared sheet", () => {
63
- const Comp = styled("div")`color: ${(p: any) => p.$color};`
64
- const vnode = Comp({ $color: "blue" }) as VNode
67
+ describe('dynamic styled components', () => {
68
+ it('injects CSS into the shared sheet', () => {
69
+ const Comp = styled('div')`
70
+ color: ${(p: any) => p.$color};
71
+ `
72
+ const vnode = Comp({ $color: 'blue' }) as VNode
65
73
  const className = vnode.props.class as string
66
74
 
67
75
  const rules = findRulesFor(className)
68
76
  expect(rules.length).toBeGreaterThanOrEqual(1)
69
- expect(rules.some((r) => r.includes("color: blue"))).toBe(true)
77
+ expect(rules.some((r) => r.includes('color: blue'))).toBe(true)
70
78
  })
71
79
 
72
- it("different prop values inject different CSS rules into the sheet", () => {
73
- const Comp = styled("div")`color: ${(p: any) => p.$color};`
74
- const vnode1 = Comp({ $color: "red" }) as VNode
80
+ it('different prop values inject different CSS rules into the sheet', () => {
81
+ const Comp = styled('div')`
82
+ color: ${(p: any) => p.$color};
83
+ `
84
+ const vnode1 = Comp({ $color: 'red' }) as VNode
75
85
  const cls1 = vnode1.props.class as string
76
86
 
77
- const vnode2 = Comp({ $color: "green" }) as VNode
87
+ const vnode2 = Comp({ $color: 'green' }) as VNode
78
88
  const cls2 = vnode2.props.class as string
79
89
 
80
90
  expect(cls1).not.toBe(cls2)
81
91
 
82
92
  // Both rules should be in the sheet
83
- expect(findRulesFor(cls1).some((r) => r.includes("color: red"))).toBe(true)
84
- expect(findRulesFor(cls2).some((r) => r.includes("color: green"))).toBe(true)
93
+ expect(findRulesFor(cls1).some((r) => r.includes('color: red'))).toBe(true)
94
+ expect(findRulesFor(cls2).some((r) => r.includes('color: green'))).toBe(true)
85
95
  })
86
96
  })
87
97
 
88
- describe("createGlobalStyle", () => {
89
- it("static global styles are injected into the shared sheet", () => {
98
+ describe('createGlobalStyle', () => {
99
+ it('static global styles are injected into the shared sheet', () => {
90
100
  const GlobalStyle = createGlobalStyle`
91
101
  body { margin: 0; }
92
102
  `
@@ -94,46 +104,54 @@ describe("hybrid injection — CSS in shared sheet", () => {
94
104
  GlobalStyle({})
95
105
 
96
106
  const rules = getSheetRules()
97
- expect(rules.some((r) => r.includes("margin") && r.includes("0"))).toBe(true)
107
+ expect(rules.some((r) => r.includes('margin') && r.includes('0'))).toBe(true)
98
108
  })
99
109
  })
100
110
  })
101
111
 
102
- describe("hybrid injection — VNode output (no <style> in tree)", () => {
112
+ describe('hybrid injection — VNode output (no <style> in tree)', () => {
103
113
  afterEach(() => {
104
114
  sheet.clearAll()
105
115
  })
106
116
 
107
- describe("styled components", () => {
108
- it("static component returns a VNode of the correct tag", () => {
109
- const Comp = styled("div")`color: red;`
117
+ describe('styled components', () => {
118
+ it('static component returns a VNode of the correct tag', () => {
119
+ const Comp = styled('div')`
120
+ color: red;
121
+ `
110
122
  const vnode = Comp({}) as VNode
111
123
 
112
124
  // Should return a VNode for <div>, not a <style>
113
- expect(vnode.type).toBe("div")
125
+ expect(vnode.type).toBe('div')
114
126
  })
115
127
 
116
- it("dynamic component returns a VNode of the correct tag", () => {
117
- const Comp = styled("div")`color: ${(p: any) => p.$color};`
118
- const vnode = Comp({ $color: "red" }) as VNode
128
+ it('dynamic component returns a VNode of the correct tag', () => {
129
+ const Comp = styled('div')`
130
+ color: ${(p: any) => p.$color};
131
+ `
132
+ const vnode = Comp({ $color: 'red' }) as VNode
119
133
 
120
- expect(vnode.type).toBe("div")
134
+ expect(vnode.type).toBe('div')
121
135
  })
122
136
 
123
- it("multiple styled components produce correct VNode types", () => {
124
- const A = styled("div")`color: red;`
125
- const B = styled("span")`color: blue;`
137
+ it('multiple styled components produce correct VNode types', () => {
138
+ const A = styled('div')`
139
+ color: red;
140
+ `
141
+ const B = styled('span')`
142
+ color: blue;
143
+ `
126
144
 
127
145
  const vnodeA = A({}) as VNode
128
146
  const vnodeB = B({}) as VNode
129
147
 
130
- expect(vnodeA.type).toBe("div")
131
- expect(vnodeB.type).toBe("span")
148
+ expect(vnodeA.type).toBe('div')
149
+ expect(vnodeB.type).toBe('span')
132
150
  })
133
151
  })
134
152
 
135
- describe("createGlobalStyle", () => {
136
- it("static global style returns null", () => {
153
+ describe('createGlobalStyle', () => {
154
+ it('static global style returns null', () => {
137
155
  const GlobalStyle = createGlobalStyle`body { margin: 0; }`
138
156
  const result = GlobalStyle({})
139
157
 
@@ -142,13 +160,15 @@ describe("hybrid injection — VNode output (no <style> in tree)", () => {
142
160
  })
143
161
  })
144
162
 
145
- describe("hybrid injection — boost option at component level", () => {
163
+ describe('hybrid injection — boost option at component level', () => {
146
164
  afterEach(() => {
147
165
  sheet.clearAll()
148
166
  })
149
167
 
150
- it("static boosted component produces doubled selector in CSSOM", () => {
151
- const Comp = styled("div", { boost: true })`color: red;`
168
+ it('static boosted component produces doubled selector in CSSOM', () => {
169
+ const Comp = styled('div', { boost: true })`
170
+ color: red;
171
+ `
152
172
  const vnode = Comp({}) as VNode
153
173
  const className = vnode.props.class as string
154
174
 
@@ -158,11 +178,11 @@ describe("hybrid injection — boost option at component level", () => {
158
178
  expect(rules.some((r) => r.includes(`.${className}.${className}`))).toBe(true)
159
179
  })
160
180
 
161
- it("dynamic boosted component produces doubled selector in CSSOM", () => {
162
- const Comp = styled("div", { boost: true })`
181
+ it('dynamic boosted component produces doubled selector in CSSOM', () => {
182
+ const Comp = styled('div', { boost: true })`
163
183
  color: ${(p: any) => p.$color};
164
184
  `
165
- const vnode = Comp({ $color: "blue" }) as VNode
185
+ const vnode = Comp({ $color: 'blue' }) as VNode
166
186
  const className = vnode.props.class as string
167
187
 
168
188
  const rules = findRulesFor(className)
@@ -170,8 +190,10 @@ describe("hybrid injection — boost option at component level", () => {
170
190
  expect(rules.some((r) => r.includes(`.${className}.${className}`))).toBe(true)
171
191
  })
172
192
 
173
- it("non-boosted component produces single selector", () => {
174
- const Comp = styled("div")`color: green;`
193
+ it('non-boosted component produces single selector', () => {
194
+ const Comp = styled('div')`
195
+ color: green;
196
+ `
175
197
  const vnode = Comp({}) as VNode
176
198
  const className = vnode.props.class as string
177
199
 
@@ -181,15 +203,17 @@ describe("hybrid injection — boost option at component level", () => {
181
203
  const baseRule = rules[0] as string
182
204
  expect(baseRule).toContain(`.${className}`)
183
205
  // Count occurrences of the className in the selector portion
184
- const selectorPart = baseRule.split("{")[0] as string
206
+ const selectorPart = baseRule.split('{')[0] as string
185
207
  const occurrences = selectorPart.split(`.${className}`).length - 1
186
208
  expect(occurrences).toBe(1)
187
209
  })
188
210
 
189
- it("boosted component with @media splits correctly", () => {
190
- const Comp = styled("div", { boost: true })`
211
+ it('boosted component with @media splits correctly', () => {
212
+ const Comp = styled('div', { boost: true })`
191
213
  color: red;
192
- @media (min-width: 768px) { font-size: 20px; }
214
+ @media (min-width: 768px) {
215
+ font-size: 20px;
216
+ }
193
217
  `
194
218
  const vnode = Comp({}) as VNode
195
219
  const className = vnode.props.class as string
@@ -2,13 +2,13 @@
2
2
  * Test barrel / helper file.
3
3
  * Re-exports commonly used test utilities from the styler source.
4
4
  */
5
- export { css } from "../css"
6
- export { createGlobalStyle } from "../globalStyle"
7
- export { HASH_INIT, hash, hashFinalize, hashUpdate } from "../hash"
8
- export { keyframes } from "../keyframes"
9
- export type { CSSResult, Interpolation } from "../resolve"
10
- export { clearNormCache, normalizeCSS, resolve, resolveValue } from "../resolve"
11
- export type { StyleSheetOptions } from "../sheet"
12
- export { createSheet, StyleSheet, sheet } from "../sheet"
13
- export { styled } from "../styled"
14
- export { ThemeContext, ThemeProvider, useTheme } from "../ThemeProvider"
5
+ export { css } from '../css'
6
+ export { createGlobalStyle } from '../globalStyle'
7
+ export { HASH_INIT, hash, hashFinalize, hashUpdate } from '../hash'
8
+ export { keyframes } from '../keyframes'
9
+ export type { CSSResult, Interpolation } from '../resolve'
10
+ export { clearNormCache, normalizeCSS, resolve, resolveValue } from '../resolve'
11
+ export type { StyleSheetOptions } from '../sheet'
12
+ export { createSheet, StyleSheet, sheet } from '../sheet'
13
+ export { styled } from '../styled'
14
+ export { ThemeContext, ThemeProvider, useTheme } from '../ThemeProvider'
@@ -1,36 +1,42 @@
1
- import type { VNode } from "@pyreon/core"
2
- import { describe, expect, it } from "vitest"
3
- import { styled } from "../styled"
4
-
5
- describe("style injection (className generation)", () => {
6
- describe("dynamic styled components", () => {
7
- it("generates a proper className for dynamic CSS", () => {
8
- const Comp = styled("div")`
1
+ import type { VNode } from '@pyreon/core'
2
+ import { describe, expect, it } from 'vitest'
3
+ import { styled } from '../styled'
4
+
5
+ describe('style injection (className generation)', () => {
6
+ describe('dynamic styled components', () => {
7
+ it('generates a proper className for dynamic CSS', () => {
8
+ const Comp = styled('div')`
9
9
  color: ${(props: any) => props.$color};
10
10
  `
11
11
 
12
- const vnode = Comp({ $color: "red" }) as VNode
12
+ const vnode = Comp({ $color: 'red' }) as VNode
13
13
 
14
14
  // Class should be present and properly generated
15
15
  expect(vnode.props.class).toMatch(/^pyr-[0-9a-z]+$/)
16
16
  })
17
17
 
18
- it("works with multiple dynamic components", () => {
19
- const Comp1 = styled("div")`color: ${(p: any) => p.$c};`
20
- const Comp2 = styled("span")`font-size: ${(p: any) => p.$s};`
18
+ it('works with multiple dynamic components', () => {
19
+ const Comp1 = styled('div')`
20
+ color: ${(p: any) => p.$c};
21
+ `
22
+ const Comp2 = styled('span')`
23
+ font-size: ${(p: any) => p.$s};
24
+ `
21
25
 
22
- const vnode1 = Comp1({ $c: "red" }) as VNode
23
- const vnode2 = Comp2({ $s: "16px" }) as VNode
26
+ const vnode1 = Comp1({ $c: 'red' }) as VNode
27
+ const vnode2 = Comp2({ $s: '16px' }) as VNode
24
28
 
25
29
  expect(vnode1.props.class).toMatch(/^pyr-/)
26
30
  expect(vnode2.props.class).toMatch(/^pyr-/)
27
31
  expect(vnode1.props.class).not.toBe(vnode2.props.class)
28
32
  })
29
33
 
30
- it("handles different prop values producing different classNames", () => {
31
- const Comp = styled("div")`color: ${(p: any) => p.$color};`
34
+ it('handles different prop values producing different classNames', () => {
35
+ const Comp = styled('div')`
36
+ color: ${(p: any) => p.$color};
37
+ `
32
38
 
33
- const colors = ["blue", "green", "yellow", "purple", "orange"]
39
+ const colors = ['blue', 'green', 'yellow', 'purple', 'orange']
34
40
  const classNames = new Set<string>()
35
41
 
36
42
  for (const color of colors) {
@@ -43,15 +49,17 @@ describe("style injection (className generation)", () => {
43
49
  expect(classNames.size).toBe(colors.length)
44
50
  })
45
51
 
46
- it("same dynamic CSS produces same className", () => {
47
- const Comp = styled("div")`color: ${(p: any) => p.$color};`
52
+ it('same dynamic CSS produces same className', () => {
53
+ const Comp = styled('div')`
54
+ color: ${(p: any) => p.$color};
55
+ `
48
56
 
49
- const vnode1 = Comp({ $color: "red" }) as VNode
57
+ const vnode1 = Comp({ $color: 'red' }) as VNode
50
58
  const cls1 = vnode1.props.class as string
51
59
 
52
- const _vnode2 = Comp({ $color: "blue" }) as VNode
60
+ const _vnode2 = Comp({ $color: 'blue' }) as VNode
53
61
 
54
- const vnode3 = Comp({ $color: "red" }) as VNode // back to red
62
+ const vnode3 = Comp({ $color: 'red' }) as VNode // back to red
55
63
  const cls3 = vnode3.props.class as string
56
64
 
57
65
  // Same resolved CSS -> same className
@@ -59,18 +67,23 @@ describe("style injection (className generation)", () => {
59
67
  })
60
68
  })
61
69
 
62
- describe("static styled components", () => {
63
- it("static components compute class at creation time", () => {
70
+ describe('static styled components', () => {
71
+ it('static components compute class at creation time', () => {
64
72
  // Static components compute class at creation time
65
- const Comp = styled("div")`display: flex; color: red;`
73
+ const Comp = styled('div')`
74
+ display: flex;
75
+ color: red;
76
+ `
66
77
 
67
78
  const vnode = Comp({}) as VNode
68
79
 
69
80
  expect(vnode.props.class).toMatch(/^pyr-[0-9a-z]+$/)
70
81
  })
71
82
 
72
- it("static className is stable across calls", () => {
73
- const Comp = styled("div")`display: flex;`
83
+ it('static className is stable across calls', () => {
84
+ const Comp = styled('div')`
85
+ display: flex;
86
+ `
74
87
 
75
88
  const vnode1 = Comp({}) as VNode
76
89
  const cls1 = vnode1.props.class as string
@@ -83,19 +96,19 @@ describe("style injection (className generation)", () => {
83
96
  })
84
97
  })
85
98
 
86
- describe("theme-dependent components", () => {
87
- it("produces different className for different resolved CSS", () => {
99
+ describe('theme-dependent components', () => {
100
+ it('produces different className for different resolved CSS', () => {
88
101
  // In Pyreon, theme is accessed via useTheme() inside the component.
89
102
  // Without ThemeProvider context, theme is {} (default).
90
103
  // We test via direct prop-based dynamic interpolation instead.
91
- const Comp = styled("div")`
104
+ const Comp = styled('div')`
92
105
  background: ${(p: any) => p.$bg};
93
106
  `
94
107
 
95
- const vnode1 = Comp({ $bg: "white" }) as VNode
108
+ const vnode1 = Comp({ $bg: 'white' }) as VNode
96
109
  const cls1 = vnode1.props.class as string
97
110
 
98
- const vnode2 = Comp({ $bg: "black" }) as VNode
111
+ const vnode2 = Comp({ $bg: 'black' }) as VNode
99
112
  const cls2 = vnode2.props.class as string
100
113
 
101
114
  expect(cls1).not.toBe(cls2)
@@ -1,13 +1,15 @@
1
- import type { VNode } from "@pyreon/core"
2
- import { describe, expect, it } from "vitest"
3
- import { css } from "../css"
4
- import { styled } from "../styled"
5
-
6
- describe("integration", () => {
7
- describe("nested css results", () => {
8
- it("resolves nested css tagged templates", () => {
9
- const flexCSS = css`display: flex;`
10
- const Comp = styled("div")`
1
+ import type { VNode } from '@pyreon/core'
2
+ import { describe, expect, it } from 'vitest'
3
+ import { css } from '../css'
4
+ import { styled } from '../styled'
5
+
6
+ describe('integration', () => {
7
+ describe('nested css results', () => {
8
+ it('resolves nested css tagged templates', () => {
9
+ const flexCSS = css`
10
+ display: flex;
11
+ `
12
+ const Comp = styled('div')`
11
13
  ${flexCSS}
12
14
  color: red;
13
15
  `
@@ -15,20 +17,26 @@ describe("integration", () => {
15
17
  expect(vnode.props.class).toMatch(/^pyr-/)
16
18
  })
17
19
 
18
- it("resolves conditional css (logical AND pattern)", () => {
20
+ it('resolves conditional css (logical AND pattern)', () => {
19
21
  const isWeb = true
20
- const Comp = styled("div")`
21
- ${isWeb && css`box-sizing: border-box;`};
22
+ const Comp = styled('div')`
23
+ ${isWeb &&
24
+ css`
25
+ box-sizing: border-box;
26
+ `};
22
27
  display: flex;
23
28
  `
24
29
  const vnode = Comp({}) as VNode
25
30
  expect(vnode.props.class).toMatch(/^pyr-/)
26
31
  })
27
32
 
28
- it("handles false conditional css", () => {
33
+ it('handles false conditional css', () => {
29
34
  const isWeb = false
30
- const Comp = styled("div")`
31
- ${isWeb && css`box-sizing: border-box;`};
35
+ const Comp = styled('div')`
36
+ ${isWeb &&
37
+ css`
38
+ box-sizing: border-box;
39
+ `};
32
40
  display: flex;
33
41
  `
34
42
  const vnode = Comp({}) as VNode
@@ -36,16 +44,26 @@ describe("integration", () => {
36
44
  })
37
45
  })
38
46
 
39
- describe("array interpolations (makeItResponsive pattern)", () => {
40
- it("resolves array of css results (simulating breakpoints)", () => {
47
+ describe('array interpolations (makeItResponsive pattern)', () => {
48
+ it('resolves array of css results (simulating breakpoints)', () => {
41
49
  // Simulates what makeItResponsive returns: array of css results per breakpoint
42
50
  const breakpointStyles = [
43
- css`color: red;`,
44
- css`@media (min-width: 48em) { color: blue; }`,
45
- css`@media (min-width: 62em) { color: green; }`,
51
+ css`
52
+ color: red;
53
+ `,
54
+ css`
55
+ @media (min-width: 48em) {
56
+ color: blue;
57
+ }
58
+ `,
59
+ css`
60
+ @media (min-width: 62em) {
61
+ color: green;
62
+ }
63
+ `,
46
64
  ]
47
65
 
48
- const Comp = styled("div")`
66
+ const Comp = styled('div')`
49
67
  display: flex;
50
68
  ${breakpointStyles};
51
69
  `
@@ -53,41 +71,53 @@ describe("integration", () => {
53
71
  expect(vnode.props.class).toMatch(/^pyr-/)
54
72
  })
55
73
 
56
- it("resolves function returning array (makeItResponsive full pattern)", () => {
74
+ it('resolves function returning array (makeItResponsive full pattern)', () => {
57
75
  // makeItResponsive returns a function (props) => CSSResult[]
58
76
  const responsiveFn = (props: any) => {
59
77
  const theme = props.$element || {}
60
78
  return [
61
- css`color: ${theme.color || "black"};`,
62
- theme.breakpoint ? css`@media (min-width: 48em) { color: ${theme.breakpoint}; }` : "",
79
+ css`
80
+ color: ${theme.color || 'black'};
81
+ `,
82
+ theme.breakpoint
83
+ ? css`
84
+ @media (min-width: 48em) {
85
+ color: ${theme.breakpoint};
86
+ }
87
+ `
88
+ : '',
63
89
  ]
64
90
  }
65
91
 
66
- const Comp = styled("div")`
92
+ const Comp = styled('div')`
67
93
  display: flex;
68
94
  ${responsiveFn};
69
95
  `
70
- const vnode = Comp({ $element: { color: "red", breakpoint: "blue" } }) as VNode
96
+ const vnode = Comp({ $element: { color: 'red', breakpoint: 'blue' } }) as VNode
71
97
  expect(vnode.props.class).toMatch(/^pyr-/)
72
98
  })
73
99
  })
74
100
 
75
- describe("createMediaQueries pattern", () => {
76
- it("css called as function (css(...args)) wrapping in @media", () => {
101
+ describe('createMediaQueries pattern', () => {
102
+ it('css called as function (css(...args)) wrapping in @media', () => {
77
103
  // Simulates createMediaQueries: builds functions that call css(...args)
78
104
  const createMedia = (breakpoint: number, rootSize: number) => {
79
105
  const emSize = breakpoint / rootSize
80
106
  return (...args: any[]) =>
81
- css`@media only screen and (min-width: ${emSize}em) {
82
- ${css(...(args as [TemplateStringsArray, ...any[]]))};
83
- }`
107
+ css`
108
+ @media only screen and (min-width: ${emSize}em) {
109
+ ${css(...(args as [TemplateStringsArray, ...any[]]))};
110
+ }
111
+ `
84
112
  }
85
113
 
86
114
  const md = createMedia(768, 16)
87
- const result = md`color: blue;`
115
+ const result = md`
116
+ color: blue;
117
+ `
88
118
 
89
119
  // Wrap in a styled component
90
- const Comp = styled("div")`
120
+ const Comp = styled('div')`
91
121
  color: red;
92
122
  ${result};
93
123
  `
@@ -95,13 +125,13 @@ describe("integration", () => {
95
125
  expect(vnode.props.class).toMatch(/^pyr-/)
96
126
  })
97
127
 
98
- it("zero-breakpoint passthrough (css(...args) without @media)", () => {
128
+ it('zero-breakpoint passthrough (css(...args) without @media)', () => {
99
129
  // Breakpoint 0 means no @media wrapper
100
130
  const passthrough = (...args: any[]) => css(...(args as [TemplateStringsArray, ...any[]]))
101
131
 
102
132
  const result = passthrough`color: red;`
103
133
 
104
- const Comp = styled("div")`
134
+ const Comp = styled('div')`
105
135
  ${result};
106
136
  `
107
137
  const vnode = Comp({}) as VNode
@@ -109,21 +139,21 @@ describe("integration", () => {
109
139
  })
110
140
  })
111
141
 
112
- describe("complex styled patterns", () => {
113
- it("function interpolation with prop-based conditional", () => {
114
- const Comp = styled("div")`
142
+ describe('complex styled patterns', () => {
143
+ it('function interpolation with prop-based conditional', () => {
144
+ const Comp = styled('div')`
115
145
  display: flex;
116
- ${({ $contentType }: any) => $contentType === "content" && "flex: 1;"};
146
+ ${({ $contentType }: any) => $contentType === 'content' && 'flex: 1;'};
117
147
  `
118
- const vnode = Comp({ $contentType: "content" }) as VNode
148
+ const vnode = Comp({ $contentType: 'content' }) as VNode
119
149
  expect(vnode.props.class).toMatch(/^pyr-/)
120
150
  })
121
151
 
122
- it("platform-specific CSS (compile-time constant)", () => {
152
+ it('platform-specific CSS (compile-time constant)', () => {
123
153
  const __WEB__ = true
124
- const platformCSS = __WEB__ ? "box-sizing: border-box;" : ""
154
+ const platformCSS = __WEB__ ? 'box-sizing: border-box;' : ''
125
155
 
126
- const Comp = styled("div")`
156
+ const Comp = styled('div')`
127
157
  ${platformCSS};
128
158
  display: flex;
129
159
  `
@@ -131,17 +161,17 @@ describe("integration", () => {
131
161
  expect(vnode.props.class).toMatch(/^pyr-/)
132
162
  })
133
163
 
134
- it("multiple function interpolations", () => {
135
- const Comp = styled("div")`
136
- color: ${(p: any) => p.$color || "black"};
137
- font-size: ${(p: any) => p.$size || "16px"};
164
+ it('multiple function interpolations', () => {
165
+ const Comp = styled('div')`
166
+ color: ${(p: any) => p.$color || 'black'};
167
+ font-size: ${(p: any) => p.$size || '16px'};
138
168
  `
139
- const vnode = Comp({ $color: "red", $size: "20px" }) as VNode
169
+ const vnode = Comp({ $color: 'red', $size: '20px' }) as VNode
140
170
  expect(vnode.props.class).toMatch(/^pyr-/)
141
171
  })
142
172
 
143
- it("empty template produces no className", () => {
144
- const Comp = styled("div")``
173
+ it('empty template produces no className', () => {
174
+ const Comp = styled('div')``
145
175
  const vnode = Comp({}) as VNode
146
176
  expect(vnode.props.class).toBeFalsy()
147
177
  })