@pyreon/unistyle 0.11.0 → 0.11.2
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 +14 -12
- package/src/__tests__/alignContent.test.ts +121 -0
- package/src/__tests__/borderRadius.test.ts +125 -0
- package/src/__tests__/camelToKebab.test.ts +44 -0
- package/src/__tests__/context.test.ts +147 -0
- package/src/__tests__/createMediaQueries.test.ts +98 -0
- package/src/__tests__/edge.test.ts +164 -0
- package/src/__tests__/enrichTheme.test.ts +56 -0
- package/src/__tests__/extendCss.test.ts +45 -0
- package/src/__tests__/index.test.ts +79 -0
- package/src/__tests__/makeItResponsive.test.ts +171 -0
- package/src/__tests__/processDescriptor.test.ts +320 -0
- package/src/__tests__/responsive.test.ts +177 -0
- package/src/__tests__/styles.test.ts +119 -0
- package/src/__tests__/units.test.ts +134 -0
- package/src/context.tsx +34 -0
- package/src/enrichTheme.ts +42 -0
- package/src/index.ts +89 -0
- package/src/responsive/breakpoints.ts +15 -0
- package/src/responsive/createMediaQueries.ts +43 -0
- package/src/responsive/index.ts +14 -0
- package/src/responsive/makeItResponsive.ts +118 -0
- package/src/responsive/normalizeTheme.ts +65 -0
- package/src/responsive/optimizeTheme.ts +39 -0
- package/src/responsive/sortBreakpoints.ts +10 -0
- package/src/responsive/transformTheme.ts +48 -0
- package/src/styles/alignContent.ts +58 -0
- package/src/styles/extendCss.ts +26 -0
- package/src/styles/index.ts +16 -0
- package/src/styles/shorthands/borderRadius.ts +89 -0
- package/src/styles/shorthands/edge.ts +108 -0
- package/src/styles/shorthands/index.ts +4 -0
- package/src/styles/styles/camelToKebab.ts +3 -0
- package/src/styles/styles/index.ts +33 -0
- package/src/styles/styles/processDescriptor.ts +100 -0
- package/src/styles/styles/propertyMap.ts +436 -0
- package/src/styles/styles/types.ts +366 -0
- package/src/styles/styles/utils.ts +62 -0
- package/src/types.ts +175 -0
- package/src/units/index.ts +6 -0
- package/src/units/stripUnit.ts +25 -0
- package/src/units/value.ts +47 -0
- package/src/units/values.ts +40 -0
|
@@ -0,0 +1,164 @@
|
|
|
1
|
+
import { describe, expect, it } from "vitest"
|
|
2
|
+
import edge from "../styles/shorthands/edge"
|
|
3
|
+
|
|
4
|
+
const empty = {
|
|
5
|
+
full: undefined,
|
|
6
|
+
x: undefined,
|
|
7
|
+
y: undefined,
|
|
8
|
+
top: undefined,
|
|
9
|
+
left: undefined,
|
|
10
|
+
right: undefined,
|
|
11
|
+
bottom: undefined,
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
const e = edge()
|
|
15
|
+
|
|
16
|
+
describe("edge", () => {
|
|
17
|
+
it("returns null when no values provided", () => {
|
|
18
|
+
expect(e("margin", empty)).toBeNull()
|
|
19
|
+
})
|
|
20
|
+
|
|
21
|
+
describe("full shorthand (all same)", () => {
|
|
22
|
+
it("margin with single value", () => {
|
|
23
|
+
expect(e("margin", { ...empty, full: 16 })).toBe("margin: 1rem;")
|
|
24
|
+
})
|
|
25
|
+
|
|
26
|
+
it("padding with single value", () => {
|
|
27
|
+
expect(e("padding", { ...empty, full: 32 })).toBe("padding: 2rem;")
|
|
28
|
+
})
|
|
29
|
+
|
|
30
|
+
it("inset with single value", () => {
|
|
31
|
+
expect(e("inset", { ...empty, full: 16 })).toBe("inset: 1rem;")
|
|
32
|
+
})
|
|
33
|
+
})
|
|
34
|
+
|
|
35
|
+
describe("two-value shorthand", () => {
|
|
36
|
+
it("top===bottom and right===left", () => {
|
|
37
|
+
const result = e("margin", { ...empty, y: 16, x: 32 })
|
|
38
|
+
expect(result).toBe("margin: 1rem 2rem;")
|
|
39
|
+
})
|
|
40
|
+
})
|
|
41
|
+
|
|
42
|
+
describe("three-value shorthand", () => {
|
|
43
|
+
it("top, right===left, bottom", () => {
|
|
44
|
+
const result = e("padding", {
|
|
45
|
+
...empty,
|
|
46
|
+
top: 16,
|
|
47
|
+
right: 32,
|
|
48
|
+
bottom: 48,
|
|
49
|
+
left: 32,
|
|
50
|
+
})
|
|
51
|
+
expect(result).toBe("padding: 1rem 2rem 3rem;")
|
|
52
|
+
})
|
|
53
|
+
})
|
|
54
|
+
|
|
55
|
+
describe("four-value shorthand", () => {
|
|
56
|
+
it("all different sides", () => {
|
|
57
|
+
const result = e("margin", {
|
|
58
|
+
...empty,
|
|
59
|
+
top: 16,
|
|
60
|
+
right: 32,
|
|
61
|
+
bottom: 48,
|
|
62
|
+
left: 64,
|
|
63
|
+
})
|
|
64
|
+
expect(result).toBe("margin: 1rem 2rem 3rem 4rem;")
|
|
65
|
+
})
|
|
66
|
+
})
|
|
67
|
+
|
|
68
|
+
describe("x and y values", () => {
|
|
69
|
+
it("x sets left and right", () => {
|
|
70
|
+
const result = e("margin", { ...empty, x: 16 })
|
|
71
|
+
expect(result).toBe("margin-left: 1rem;margin-right: 1rem;")
|
|
72
|
+
})
|
|
73
|
+
|
|
74
|
+
it("y sets top and bottom", () => {
|
|
75
|
+
const result = e("margin", { ...empty, y: 16 })
|
|
76
|
+
expect(result).toBe("margin-top: 1rem;margin-bottom: 1rem;")
|
|
77
|
+
})
|
|
78
|
+
})
|
|
79
|
+
|
|
80
|
+
describe("individual sides override x/y/full", () => {
|
|
81
|
+
it("top overrides y", () => {
|
|
82
|
+
const result = e("margin", { ...empty, y: 16, top: 32, x: 16 })
|
|
83
|
+
// t=32, r=16, b=16, l=16 → r===l so 3-value shorthand
|
|
84
|
+
expect(result).toBe("margin: 2rem 1rem 1rem;")
|
|
85
|
+
})
|
|
86
|
+
|
|
87
|
+
it("left overrides x", () => {
|
|
88
|
+
const result = e("padding", { ...empty, full: 16, left: 32 })
|
|
89
|
+
expect(result).toBe("padding: 1rem 1rem 1rem 2rem;")
|
|
90
|
+
})
|
|
91
|
+
})
|
|
92
|
+
|
|
93
|
+
describe("border-width uses px unit", () => {
|
|
94
|
+
it("border-width with full value", () => {
|
|
95
|
+
expect(e("border-width", { ...empty, full: 1 })).toBe("border-width: 1px;")
|
|
96
|
+
})
|
|
97
|
+
|
|
98
|
+
it("border-width individual sides", () => {
|
|
99
|
+
const result = e("border-width", { ...empty, top: 1, bottom: 2 })
|
|
100
|
+
expect(result).toBe("border-top-width: 1px;border-bottom-width: 2px;")
|
|
101
|
+
})
|
|
102
|
+
})
|
|
103
|
+
|
|
104
|
+
describe("border-style does not use units", () => {
|
|
105
|
+
it("border-style with full value", () => {
|
|
106
|
+
expect(e("border-style", { ...empty, full: "solid" })).toBe("border-style: solid;")
|
|
107
|
+
})
|
|
108
|
+
|
|
109
|
+
it("border-style individual sides", () => {
|
|
110
|
+
const result = e("border-style", { ...empty, top: "solid", bottom: "dashed" })
|
|
111
|
+
expect(result).toBe("border-top-style: solid;border-bottom-style: dashed;")
|
|
112
|
+
})
|
|
113
|
+
})
|
|
114
|
+
|
|
115
|
+
describe("border-color does not use units", () => {
|
|
116
|
+
it("border-color with full value", () => {
|
|
117
|
+
expect(e("border-color", { ...empty, full: "red" })).toBe("border-color: red;")
|
|
118
|
+
})
|
|
119
|
+
|
|
120
|
+
it("border-color individual sides", () => {
|
|
121
|
+
const result = e("border-color", { ...empty, top: "red", left: "blue" })
|
|
122
|
+
expect(result).toBe("border-top-color: red;border-left-color: blue;")
|
|
123
|
+
})
|
|
124
|
+
})
|
|
125
|
+
|
|
126
|
+
describe("individual format when not all sides have values", () => {
|
|
127
|
+
it("only top is set", () => {
|
|
128
|
+
expect(e("margin", { ...empty, top: 16 })).toBe("margin-top: 1rem;")
|
|
129
|
+
})
|
|
130
|
+
|
|
131
|
+
it("only left and right are set", () => {
|
|
132
|
+
const result = e("padding", { ...empty, left: 16, right: 32 })
|
|
133
|
+
expect(result).toBe("padding-left: 1rem;padding-right: 2rem;")
|
|
134
|
+
})
|
|
135
|
+
|
|
136
|
+
it("inset individual sides", () => {
|
|
137
|
+
const result = e("inset", { ...empty, top: 0, left: 16 })
|
|
138
|
+
expect(result).toBe("top: 0;left: 1rem;")
|
|
139
|
+
})
|
|
140
|
+
})
|
|
141
|
+
|
|
142
|
+
describe("zero values are valid", () => {
|
|
143
|
+
it("zero full value", () => {
|
|
144
|
+
expect(e("margin", { ...empty, full: 0 })).toBe("margin: 0;")
|
|
145
|
+
})
|
|
146
|
+
|
|
147
|
+
it("zero individual side", () => {
|
|
148
|
+
expect(e("padding", { ...empty, top: 0 })).toBe("padding-top: 0;")
|
|
149
|
+
})
|
|
150
|
+
})
|
|
151
|
+
|
|
152
|
+
describe("custom rootSize", () => {
|
|
153
|
+
it("uses custom rootSize for conversion", () => {
|
|
154
|
+
const eCustom = edge(10)
|
|
155
|
+
expect(eCustom("margin", { ...empty, full: 20 })).toBe("margin: 2rem;")
|
|
156
|
+
})
|
|
157
|
+
})
|
|
158
|
+
|
|
159
|
+
describe("string values", () => {
|
|
160
|
+
it("passes through string values like auto", () => {
|
|
161
|
+
expect(e("margin", { ...empty, full: "auto" })).toBe("margin: auto;")
|
|
162
|
+
})
|
|
163
|
+
})
|
|
164
|
+
})
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
import { describe, expect, it } from "vitest"
|
|
2
|
+
import { enrichTheme } from "../enrichTheme"
|
|
3
|
+
|
|
4
|
+
describe("enrichTheme", () => {
|
|
5
|
+
it("adds __PYREON__ with sortedBreakpoints and media", () => {
|
|
6
|
+
const theme = { rootSize: 16, breakpoints: { xs: 0, sm: 576, md: 768 } }
|
|
7
|
+
const result = enrichTheme(theme)
|
|
8
|
+
|
|
9
|
+
expect(result.__PYREON__).toBeDefined()
|
|
10
|
+
expect(result.__PYREON__.sortedBreakpoints).toEqual(["xs", "sm", "md"])
|
|
11
|
+
expect(result.__PYREON__.media).toBeDefined()
|
|
12
|
+
expect(typeof result.__PYREON__.media?.sm).toBe("function")
|
|
13
|
+
})
|
|
14
|
+
|
|
15
|
+
it("preserves custom theme properties", () => {
|
|
16
|
+
const theme = { rootSize: 16, colors: { primary: "blue" } }
|
|
17
|
+
const result = enrichTheme(theme)
|
|
18
|
+
|
|
19
|
+
expect(result.colors).toEqual({ primary: "blue" })
|
|
20
|
+
expect(result.rootSize).toBe(16)
|
|
21
|
+
})
|
|
22
|
+
|
|
23
|
+
it("handles theme without breakpoints", () => {
|
|
24
|
+
const theme = { rootSize: 16 }
|
|
25
|
+
const result = enrichTheme(theme)
|
|
26
|
+
|
|
27
|
+
expect(result.__PYREON__).toBeDefined()
|
|
28
|
+
expect(result.__PYREON__.sortedBreakpoints).toBeUndefined()
|
|
29
|
+
expect(result.__PYREON__.media).toBeUndefined()
|
|
30
|
+
})
|
|
31
|
+
|
|
32
|
+
it("handles empty breakpoints", () => {
|
|
33
|
+
const theme = { rootSize: 16, breakpoints: {} }
|
|
34
|
+
const result = enrichTheme(theme)
|
|
35
|
+
|
|
36
|
+
expect(result.__PYREON__.sortedBreakpoints).toBeUndefined()
|
|
37
|
+
expect(result.__PYREON__.media).toBeUndefined()
|
|
38
|
+
})
|
|
39
|
+
|
|
40
|
+
it("defaults rootSize to 16", () => {
|
|
41
|
+
const theme = { breakpoints: { sm: 576 } }
|
|
42
|
+
const result = enrichTheme(theme)
|
|
43
|
+
|
|
44
|
+
// Media queries should be created (breakpoints present)
|
|
45
|
+
expect(result.__PYREON__.media).toBeDefined()
|
|
46
|
+
})
|
|
47
|
+
|
|
48
|
+
it("is a pure function — does not mutate input", () => {
|
|
49
|
+
const theme = { rootSize: 16, breakpoints: { xs: 0, md: 768 } }
|
|
50
|
+
const copy = { ...theme }
|
|
51
|
+
enrichTheme(theme)
|
|
52
|
+
|
|
53
|
+
expect(theme).toEqual(copy)
|
|
54
|
+
expect((theme as any).__PYREON__).toBeUndefined()
|
|
55
|
+
})
|
|
56
|
+
})
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
import { describe, expect, it } from "vitest"
|
|
2
|
+
import extendCss from "../styles/extendCss"
|
|
3
|
+
|
|
4
|
+
describe("extendCss", () => {
|
|
5
|
+
it("returns empty string for null input", () => {
|
|
6
|
+
expect(extendCss(null)).toBe("")
|
|
7
|
+
})
|
|
8
|
+
|
|
9
|
+
it("returns empty string for undefined input", () => {
|
|
10
|
+
expect(extendCss(undefined)).toBe("")
|
|
11
|
+
})
|
|
12
|
+
|
|
13
|
+
it("returns the string as-is for string input", () => {
|
|
14
|
+
expect(extendCss("color: red;")).toBe("color: red;")
|
|
15
|
+
})
|
|
16
|
+
|
|
17
|
+
it("returns empty string for empty string input", () => {
|
|
18
|
+
expect(extendCss("")).toBe("")
|
|
19
|
+
})
|
|
20
|
+
|
|
21
|
+
it("calls function with simpleCss tagged template and returns result", () => {
|
|
22
|
+
const result = extendCss((css) => css`color: red; font-size: 16px;`)
|
|
23
|
+
expect(result).toBe("color: red; font-size: 16px;")
|
|
24
|
+
})
|
|
25
|
+
|
|
26
|
+
it("handles function with interpolated values", () => {
|
|
27
|
+
const size = 16
|
|
28
|
+
const result = extendCss((css) => css`font-size: ${size}px;`)
|
|
29
|
+
expect(result).toBe("font-size: 16px;")
|
|
30
|
+
})
|
|
31
|
+
|
|
32
|
+
it("handles function with multiple interpolated values", () => {
|
|
33
|
+
const color = "red"
|
|
34
|
+
const size = 14
|
|
35
|
+
const result = extendCss((css) => css`color: ${color}; font-size: ${size}px;`)
|
|
36
|
+
expect(result).toBe("color: red; font-size: 14px;")
|
|
37
|
+
})
|
|
38
|
+
|
|
39
|
+
it("handles function with null/undefined interpolated values as empty string", () => {
|
|
40
|
+
const nullVal = null as string | null
|
|
41
|
+
const undefVal = undefined as string | undefined
|
|
42
|
+
const result = extendCss((css) => css`color: ${nullVal}; font-size: ${undefVal}px;`)
|
|
43
|
+
expect(result).toBe("color: ; font-size: px;")
|
|
44
|
+
})
|
|
45
|
+
})
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
import { describe, expect, it } from "vitest"
|
|
2
|
+
import * as unistyle from "../index"
|
|
3
|
+
|
|
4
|
+
describe("index exports", () => {
|
|
5
|
+
it("exports breakpoints", () => {
|
|
6
|
+
expect(unistyle.breakpoints).toBeDefined()
|
|
7
|
+
expect(typeof unistyle.breakpoints).toBe("object")
|
|
8
|
+
})
|
|
9
|
+
|
|
10
|
+
it("exports sortBreakpoints", () => {
|
|
11
|
+
expect(unistyle.sortBreakpoints).toBeDefined()
|
|
12
|
+
expect(typeof unistyle.sortBreakpoints).toBe("function")
|
|
13
|
+
})
|
|
14
|
+
|
|
15
|
+
it("exports createMediaQueries", () => {
|
|
16
|
+
expect(unistyle.createMediaQueries).toBeDefined()
|
|
17
|
+
expect(typeof unistyle.createMediaQueries).toBe("function")
|
|
18
|
+
})
|
|
19
|
+
|
|
20
|
+
it("exports makeItResponsive", () => {
|
|
21
|
+
expect(unistyle.makeItResponsive).toBeDefined()
|
|
22
|
+
expect(typeof unistyle.makeItResponsive).toBe("function")
|
|
23
|
+
})
|
|
24
|
+
|
|
25
|
+
it("exports normalizeTheme", () => {
|
|
26
|
+
expect(unistyle.normalizeTheme).toBeDefined()
|
|
27
|
+
expect(typeof unistyle.normalizeTheme).toBe("function")
|
|
28
|
+
})
|
|
29
|
+
|
|
30
|
+
it("exports transformTheme", () => {
|
|
31
|
+
expect(unistyle.transformTheme).toBeDefined()
|
|
32
|
+
expect(typeof unistyle.transformTheme).toBe("function")
|
|
33
|
+
})
|
|
34
|
+
|
|
35
|
+
it("exports styles", () => {
|
|
36
|
+
expect(unistyle.styles).toBeDefined()
|
|
37
|
+
expect(typeof unistyle.styles).toBe("function")
|
|
38
|
+
})
|
|
39
|
+
|
|
40
|
+
it("exports alignContent", () => {
|
|
41
|
+
expect(unistyle.alignContent).toBeDefined()
|
|
42
|
+
expect(typeof unistyle.alignContent).toBe("function")
|
|
43
|
+
})
|
|
44
|
+
|
|
45
|
+
it("exports extendCss", () => {
|
|
46
|
+
expect(unistyle.extendCss).toBeDefined()
|
|
47
|
+
expect(typeof unistyle.extendCss).toBe("function")
|
|
48
|
+
})
|
|
49
|
+
|
|
50
|
+
it("exports stripUnit", () => {
|
|
51
|
+
expect(unistyle.stripUnit).toBeDefined()
|
|
52
|
+
expect(typeof unistyle.stripUnit).toBe("function")
|
|
53
|
+
})
|
|
54
|
+
|
|
55
|
+
it("exports value", () => {
|
|
56
|
+
expect(unistyle.value).toBeDefined()
|
|
57
|
+
expect(typeof unistyle.value).toBe("function")
|
|
58
|
+
})
|
|
59
|
+
|
|
60
|
+
it("exports values", () => {
|
|
61
|
+
expect(unistyle.values).toBeDefined()
|
|
62
|
+
expect(typeof unistyle.values).toBe("function")
|
|
63
|
+
})
|
|
64
|
+
|
|
65
|
+
it("exports Provider", () => {
|
|
66
|
+
expect(unistyle.Provider).toBeDefined()
|
|
67
|
+
expect(typeof unistyle.Provider).toBe("function")
|
|
68
|
+
})
|
|
69
|
+
|
|
70
|
+
it("exports context", () => {
|
|
71
|
+
expect(unistyle.context).toBeDefined()
|
|
72
|
+
})
|
|
73
|
+
|
|
74
|
+
it("exports align content constants", () => {
|
|
75
|
+
expect(unistyle.ALIGN_CONTENT_DIRECTION).toBeDefined()
|
|
76
|
+
expect(unistyle.ALIGN_CONTENT_MAP_X).toBeDefined()
|
|
77
|
+
expect(unistyle.ALIGN_CONTENT_MAP_Y).toBeDefined()
|
|
78
|
+
})
|
|
79
|
+
})
|
|
@@ -0,0 +1,171 @@
|
|
|
1
|
+
import { describe, expect, it, vi } from "vitest"
|
|
2
|
+
|
|
3
|
+
vi.mock("@pyreon/ui-core", () => ({
|
|
4
|
+
isEmpty: (val: unknown) =>
|
|
5
|
+
val == null || (typeof val === "object" && Object.keys(val as object).length === 0),
|
|
6
|
+
set: (obj: any, path: (string | number)[], value: unknown) => {
|
|
7
|
+
let current = obj
|
|
8
|
+
for (let i = 0; i < path.length - 1; i++) {
|
|
9
|
+
const key = path[i] as string | number
|
|
10
|
+
if (current[key] == null || typeof current[key] !== "object") {
|
|
11
|
+
current[key] = {}
|
|
12
|
+
}
|
|
13
|
+
current = current[key]
|
|
14
|
+
}
|
|
15
|
+
const lastKey = path[path.length - 1] as string | number
|
|
16
|
+
current[lastKey] = value
|
|
17
|
+
},
|
|
18
|
+
}))
|
|
19
|
+
|
|
20
|
+
import makeItResponsive from "../responsive/makeItResponsive"
|
|
21
|
+
|
|
22
|
+
const mockCss = (strings: TemplateStringsArray, ...vals: any[]) => {
|
|
23
|
+
let r = ""
|
|
24
|
+
for (let i = 0; i < strings.length; i++) {
|
|
25
|
+
r += strings[i]
|
|
26
|
+
if (i < vals.length) r += String(vals[i])
|
|
27
|
+
}
|
|
28
|
+
return r
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
const mockStyles = ({ theme }: { theme: Record<string, unknown> }) => {
|
|
32
|
+
return Object.entries(theme)
|
|
33
|
+
.map(([k, v]) => `${k}: ${v};`)
|
|
34
|
+
.join(" ")
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
describe("makeItResponsive", () => {
|
|
38
|
+
it("returns empty string when customTheme is empty/undefined", () => {
|
|
39
|
+
const responsive = makeItResponsive({
|
|
40
|
+
key: "styles",
|
|
41
|
+
css: mockCss,
|
|
42
|
+
styles: mockStyles,
|
|
43
|
+
})
|
|
44
|
+
|
|
45
|
+
const result = responsive({ theme: {} })
|
|
46
|
+
expect(result).toBe("")
|
|
47
|
+
})
|
|
48
|
+
|
|
49
|
+
it("returns empty string when customTheme is empty object", () => {
|
|
50
|
+
const responsive = makeItResponsive({
|
|
51
|
+
theme: {},
|
|
52
|
+
key: "styles",
|
|
53
|
+
css: mockCss,
|
|
54
|
+
styles: mockStyles,
|
|
55
|
+
})
|
|
56
|
+
|
|
57
|
+
const result = responsive({ theme: {} })
|
|
58
|
+
expect(result).toBe("")
|
|
59
|
+
})
|
|
60
|
+
|
|
61
|
+
it("without breakpoints: wraps styles output in css template", () => {
|
|
62
|
+
const responsive = makeItResponsive({
|
|
63
|
+
theme: { color: "red" },
|
|
64
|
+
css: mockCss,
|
|
65
|
+
styles: mockStyles,
|
|
66
|
+
})
|
|
67
|
+
|
|
68
|
+
const result = responsive({ theme: {} })
|
|
69
|
+
expect(result).toContain("color: red;")
|
|
70
|
+
})
|
|
71
|
+
|
|
72
|
+
it("uses props[key] when theme is not provided", () => {
|
|
73
|
+
const responsive = makeItResponsive({
|
|
74
|
+
key: "myStyles",
|
|
75
|
+
css: mockCss,
|
|
76
|
+
styles: mockStyles,
|
|
77
|
+
})
|
|
78
|
+
|
|
79
|
+
const result = responsive({
|
|
80
|
+
theme: {},
|
|
81
|
+
myStyles: { fontSize: "16px" },
|
|
82
|
+
})
|
|
83
|
+
|
|
84
|
+
expect(result).toContain("fontSize: 16px;")
|
|
85
|
+
})
|
|
86
|
+
|
|
87
|
+
it("with breakpoints and __PYREON__: returns array of media-wrapped styles per breakpoint", () => {
|
|
88
|
+
const sortedBreakpoints = ["xs", "sm"]
|
|
89
|
+
const media: Record<string, (strings: TemplateStringsArray, ...vals: any[]) => string> = {
|
|
90
|
+
xs: mockCss,
|
|
91
|
+
sm: (strings: TemplateStringsArray, ...vals: any[]) => {
|
|
92
|
+
let r = "@media (min-width: 36em) {"
|
|
93
|
+
for (let i = 0; i < strings.length; i++) {
|
|
94
|
+
r += strings[i]
|
|
95
|
+
if (i < vals.length) r += String(vals[i])
|
|
96
|
+
}
|
|
97
|
+
r += "}"
|
|
98
|
+
return r
|
|
99
|
+
},
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
const responsive = makeItResponsive({
|
|
103
|
+
theme: { color: { xs: "red", sm: "blue" } },
|
|
104
|
+
css: mockCss,
|
|
105
|
+
styles: mockStyles,
|
|
106
|
+
normalize: true,
|
|
107
|
+
})
|
|
108
|
+
|
|
109
|
+
const result = responsive({
|
|
110
|
+
theme: {
|
|
111
|
+
breakpoints: { xs: 0, sm: 576 },
|
|
112
|
+
__PYREON__: { sortedBreakpoints, media },
|
|
113
|
+
},
|
|
114
|
+
})
|
|
115
|
+
|
|
116
|
+
expect(Array.isArray(result)).toBe(true)
|
|
117
|
+
expect(result).toHaveLength(2)
|
|
118
|
+
})
|
|
119
|
+
|
|
120
|
+
it("caching: second call with same internalTheme object returns same result", () => {
|
|
121
|
+
const sortedBreakpoints = ["xs", "sm"]
|
|
122
|
+
const media: Record<string, (strings: TemplateStringsArray, ...vals: any[]) => string> = {
|
|
123
|
+
xs: mockCss,
|
|
124
|
+
sm: mockCss,
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
const themeObj = { color: { xs: "red", sm: "blue" } }
|
|
128
|
+
|
|
129
|
+
const responsive = makeItResponsive({
|
|
130
|
+
theme: themeObj,
|
|
131
|
+
css: mockCss,
|
|
132
|
+
styles: mockStyles,
|
|
133
|
+
})
|
|
134
|
+
|
|
135
|
+
const globalTheme = {
|
|
136
|
+
breakpoints: { xs: 0, sm: 576 },
|
|
137
|
+
__PYREON__: { sortedBreakpoints, media },
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
const result1 = responsive({ theme: globalTheme })
|
|
141
|
+
const result2 = responsive({ theme: globalTheme })
|
|
142
|
+
|
|
143
|
+
expect(result1).toEqual(result2)
|
|
144
|
+
})
|
|
145
|
+
|
|
146
|
+
it("normalize=false skips normalizeTheme step", () => {
|
|
147
|
+
const sortedBreakpoints = ["xs", "sm"]
|
|
148
|
+
const media: Record<string, (strings: TemplateStringsArray, ...vals: any[]) => string> = {
|
|
149
|
+
xs: mockCss,
|
|
150
|
+
sm: mockCss,
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
// When normalize=false, object values are not expanded across breakpoints.
|
|
154
|
+
// Provide a pre-normalized theme (object keyed by breakpoint names).
|
|
155
|
+
const responsive = makeItResponsive({
|
|
156
|
+
theme: { color: { xs: "red", sm: "blue" } },
|
|
157
|
+
css: mockCss,
|
|
158
|
+
styles: mockStyles,
|
|
159
|
+
normalize: false,
|
|
160
|
+
})
|
|
161
|
+
|
|
162
|
+
const result = responsive({
|
|
163
|
+
theme: {
|
|
164
|
+
breakpoints: { xs: 0, sm: 576 },
|
|
165
|
+
__PYREON__: { sortedBreakpoints, media },
|
|
166
|
+
},
|
|
167
|
+
})
|
|
168
|
+
|
|
169
|
+
expect(Array.isArray(result)).toBe(true)
|
|
170
|
+
})
|
|
171
|
+
})
|