@yak/react 0.0.0-stage → 10.0.0-rc.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.
Files changed (118) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +102 -2
  3. package/dist/context/baseContext.cjs +9 -0
  4. package/dist/context/baseContext.cjs.map +1 -0
  5. package/dist/context/baseContext.d.cts +6 -0
  6. package/dist/context/baseContext.d.ts +6 -0
  7. package/dist/context/baseContext.js +8 -0
  8. package/dist/context/baseContext.js.map +1 -0
  9. package/dist/context/index.cjs +45 -0
  10. package/dist/context/index.cjs.map +1 -0
  11. package/dist/context/index.d.cts +21 -0
  12. package/dist/context/index.d.ts +21 -0
  13. package/dist/context/index.js +15 -0
  14. package/dist/context/index.js.map +1 -0
  15. package/dist/context/index.server.cjs +47 -0
  16. package/dist/context/index.server.cjs.map +1 -0
  17. package/dist/context/index.server.d.cts +10 -0
  18. package/dist/context/index.server.d.ts +10 -0
  19. package/dist/context/index.server.js +17 -0
  20. package/dist/context/index.server.js.map +1 -0
  21. package/dist/cross-file-resolver/index.d.ts +199 -0
  22. package/dist/cross-file-resolver/index.js +535 -0
  23. package/dist/cross-file-resolver/index.js.map +1 -0
  24. package/dist/index.cjs +2 -0
  25. package/dist/index.cjs.map +1 -0
  26. package/dist/index.d.cts +320 -0
  27. package/dist/index.d.ts +320 -0
  28. package/dist/index.js +2 -0
  29. package/dist/index.js.map +1 -0
  30. package/dist/internal.cjs +544 -0
  31. package/dist/internal.cjs.map +1 -0
  32. package/dist/internal.d.cts +452 -0
  33. package/dist/internal.d.ts +452 -0
  34. package/dist/internal.js +363 -0
  35. package/dist/internal.js.map +1 -0
  36. package/dist/isolated-source-eval/index.d.ts +30 -0
  37. package/dist/isolated-source-eval/index.js +317 -0
  38. package/dist/isolated-source-eval/index.js.map +1 -0
  39. package/dist/isolated-source-eval/worker.js +59 -0
  40. package/dist/isolated-source-eval/worker.js.map +1 -0
  41. package/dist/jsx-dev-runtime.cjs +2 -0
  42. package/dist/jsx-dev-runtime.cjs.map +1 -0
  43. package/dist/jsx-dev-runtime.d.cts +7 -0
  44. package/dist/jsx-dev-runtime.d.ts +7 -0
  45. package/dist/jsx-dev-runtime.js +2 -0
  46. package/dist/jsx-dev-runtime.js.map +1 -0
  47. package/dist/jsx-runtime.cjs +2 -0
  48. package/dist/jsx-runtime.cjs.map +1 -0
  49. package/dist/jsx-runtime.d.cts +38 -0
  50. package/dist/jsx-runtime.d.ts +38 -0
  51. package/dist/jsx-runtime.js +2 -0
  52. package/dist/jsx-runtime.js.map +1 -0
  53. package/dist/loaders/turbo-loader.cjs +803 -0
  54. package/dist/loaders/turbo-loader.cjs.map +1 -0
  55. package/dist/loaders/turbo-loader.d.cts +15 -0
  56. package/dist/loaders/vite-plugin.d.ts +111 -0
  57. package/dist/loaders/vite-plugin.js +878 -0
  58. package/dist/loaders/vite-plugin.js.map +1 -0
  59. package/dist/loaders/webpack-loader.cjs +697 -0
  60. package/dist/loaders/webpack-loader.cjs.map +1 -0
  61. package/dist/loaders/webpack-loader.d.cts +12 -0
  62. package/dist/rsbuild/index.d.ts +29 -0
  63. package/dist/rsbuild/index.js +52 -0
  64. package/dist/rsbuild/index.js.map +1 -0
  65. package/dist/static/chunk-DK3Fl9T5.js +1 -0
  66. package/dist/static/index.cjs +2 -0
  67. package/dist/static/index.cjs.map +1 -0
  68. package/dist/static/index.d.cts +28 -0
  69. package/dist/static/index.d.ts +28 -0
  70. package/dist/static/index.js +2 -0
  71. package/dist/static/index.js.map +1 -0
  72. package/dist/withYak/index.cjs +208 -0
  73. package/dist/withYak/index.cjs.map +1 -0
  74. package/dist/withYak/index.d.cts +121 -0
  75. package/dist/withYak/index.d.ts +121 -0
  76. package/dist/withYak/index.js +177 -0
  77. package/dist/withYak/index.js.map +1 -0
  78. package/loaders/lib/resolveCrossFileSelectors.ts +162 -0
  79. package/loaders/turbo-evaluator.ts +134 -0
  80. package/loaders/turbo-loader.ts +180 -0
  81. package/loaders/vite-plugin.ts +28 -0
  82. package/loaders/webpack-loader.ts +44 -0
  83. package/package.json +214 -3
  84. package/rsbuild/index.ts +92 -0
  85. package/runtime/__tests__/atoms.test.tsx +48 -0
  86. package/runtime/__tests__/attrs.test.tsx +490 -0
  87. package/runtime/__tests__/cssLiteral.test.tsx +503 -0
  88. package/runtime/__tests__/cssProp.test.tsx +392 -0
  89. package/runtime/__tests__/cssPropTest.tsx +227 -0
  90. package/runtime/__tests__/foldedJsxParity.test.tsx +117 -0
  91. package/runtime/__tests__/styled.test.tsx +653 -0
  92. package/runtime/__tests__/tsconfig.json +18 -0
  93. package/runtime/__tests__/typeTest.tsx +374 -0
  94. package/runtime/atoms.tsx +36 -0
  95. package/runtime/context/README.md +84 -0
  96. package/runtime/context/baseContext.tsx +5 -0
  97. package/runtime/context/index.server.tsx +22 -0
  98. package/runtime/context/index.tsx +36 -0
  99. package/runtime/cssLiteral.tsx +214 -0
  100. package/runtime/globalStyle.tsx +54 -0
  101. package/runtime/index.ts +37 -0
  102. package/runtime/internal.ts +42 -0
  103. package/runtime/internals/mergeClassNames.ts +23 -0
  104. package/runtime/internals/mergeCssProp.ts +69 -0
  105. package/runtime/internals/propMarkers.ts +20 -0
  106. package/runtime/internals/unitPostFix.ts +34 -0
  107. package/runtime/jsx-dev-runtime.ts +6 -0
  108. package/runtime/jsx-runtime.ts +48 -0
  109. package/runtime/keyframes.tsx +30 -0
  110. package/runtime/mocks/cssLiteral.ts +74 -0
  111. package/runtime/mocks/globalStyle.ts +14 -0
  112. package/runtime/mocks/keyframes.ts +29 -0
  113. package/runtime/mocks/styled.ts +8 -0
  114. package/runtime/publicStyledApi.ts +159 -0
  115. package/runtime/styled.tsx +372 -0
  116. package/runtime/styledDom.tsx +139 -0
  117. package/withYak/allow-global-css.ts +94 -0
  118. package/withYak/index.ts +282 -0
@@ -0,0 +1,392 @@
1
+ // @ts-nocheck
2
+ import { it, expect, describe, beforeEach, afterEach } from "vitest";
3
+ import { mergeCssProp } from "../internals/mergeCssProp";
4
+ import { css } from "../cssLiteral";
5
+ import { atoms } from "../atoms";
6
+
7
+ it("forwards foreign props alongside the merged className", async () => {
8
+ const onClick = () => {};
9
+ const result = mergeCssProp(css("yakCss1"), {
10
+ onClick,
11
+ "aria-label": "Save",
12
+ disabled: true,
13
+ className: "btn",
14
+ });
15
+ // toEqual (not toMatchObject) also pins that no stray keys leak, e.g. an empty style
16
+ expect(result).toEqual({
17
+ onClick,
18
+ "aria-label": "Save",
19
+ disabled: true,
20
+ className: "btn yakCss1",
21
+ });
22
+ });
23
+
24
+ it("merge properties when className is set", async () => {
25
+ expect(
26
+ mergeCssProp(
27
+ css("yakCss1", () => ({
28
+ style: { "--yak-var1": "0.5rem" },
29
+ })),
30
+ { className: "btn btn-primary" },
31
+ ),
32
+ ).toMatchObject({
33
+ className: "btn btn-primary yakCss1",
34
+ style: { "--yak-var1": "0.5rem" },
35
+ });
36
+ });
37
+
38
+ it("merge properties when style is set", async () => {
39
+ expect(
40
+ mergeCssProp(
41
+ css(() => ({
42
+ className: "yakClass1",
43
+ style: { "--yak-var1": "#ffffff" },
44
+ })),
45
+ { style: { padding: "8px", margin: "4px" } },
46
+ ),
47
+ ).toMatchObject({
48
+ className: "yakClass1",
49
+ style: { padding: "8px", margin: "4px", "--yak-var1": "#ffffff" },
50
+ });
51
+ });
52
+
53
+ it("merge properties when spreaded property is set", async () => {
54
+ expect(
55
+ mergeCssProp(
56
+ css(() => ({
57
+ className: "yakClass1 yakClass2",
58
+ style: { "--yak-var1": "1200px" },
59
+ })),
60
+ { className: "container mx-auto" },
61
+ ),
62
+ ).toMatchObject({
63
+ className: "container mx-auto yakClass1 yakClass2",
64
+ style: { "--yak-var1": "1200px" },
65
+ });
66
+ });
67
+
68
+ it("merge properties when class name and style is set", async () => {
69
+ expect(
70
+ mergeCssProp(
71
+ css(() => ({
72
+ className: "yakClass1 yakClass2",
73
+ style: { "--yak-var1": "#1f2937" },
74
+ })),
75
+ { className: "text-lg font-semibold", style: { lineHeight: "1.6" } },
76
+ ),
77
+ ).toMatchObject({
78
+ className: "text-lg font-semibold yakClass1 yakClass2",
79
+ style: { lineHeight: "1.6", "--yak-var1": "#1f2937" },
80
+ });
81
+ });
82
+
83
+ it("merge properties when class name, style and spreaded property is set", async () => {
84
+ expect(
85
+ mergeCssProp(
86
+ css(() => ({
87
+ className: "yakClass1 yakClass2",
88
+ style: { "--yak-var1": "4rem" },
89
+ })),
90
+ { className: "flex items-center", style: { gap: "1rem" } },
91
+ ),
92
+ ).toMatchObject({
93
+ className: "flex items-center yakClass1 yakClass2",
94
+ style: { gap: "1rem", "--yak-var1": "4rem" },
95
+ });
96
+ });
97
+
98
+ it("merge properties with atoms using conditional classes", async () => {
99
+ expect(
100
+ mergeCssProp(atoms("p-4 rounded-md", false && "hidden", true && "bg-white shadow-sm"), {
101
+ className: "w-full",
102
+ }),
103
+ ).toMatchObject({
104
+ className: "w-full p-4 rounded-md bg-white shadow-sm",
105
+ });
106
+ });
107
+
108
+ it("merge properties with atoms using callback and conditional classes", async () => {
109
+ expect(
110
+ mergeCssProp(
111
+ atoms(
112
+ "border border-gray-200",
113
+ true && "hover:border-gray-300",
114
+ false && "opacity-50",
115
+ (_, classNames, style) => {
116
+ classNames.add("focus:ring-2 focus:ring-blue-500");
117
+ style["--ring-offset"] = "2px";
118
+ },
119
+ ),
120
+ { className: "relative" },
121
+ ),
122
+ ).toMatchObject({
123
+ className:
124
+ "relative border border-gray-200 hover:border-gray-300 focus:ring-2 focus:ring-blue-500",
125
+ style: { "--ring-offset": "2px" },
126
+ });
127
+ });
128
+
129
+ it("merge properties with atoms callback only", async () => {
130
+ expect(
131
+ mergeCssProp(
132
+ atoms((_, classNames, style) => {
133
+ classNames.add("grid-cols-3 gap-4");
134
+ classNames.add("md:grid-cols-6");
135
+ style["--grid-gap"] = "1rem";
136
+ }),
137
+ { className: "grid" },
138
+ ),
139
+ ).toMatchObject({
140
+ className: "grid grid-cols-3 gap-4 md:grid-cols-6",
141
+ style: { "--grid-gap": "1rem" },
142
+ });
143
+ });
144
+
145
+ it("merge properties with css wrapping atoms", async () => {
146
+ expect(
147
+ mergeCssProp(
148
+ css(
149
+ "yakClass1",
150
+ atoms("bg-white rounded-lg shadow-md", (_, classNames, style) => {
151
+ classNames.add("p-6 hover:shadow-lg");
152
+ style["--card-transition"] = "all 0.2s ease";
153
+ }),
154
+ ),
155
+ { className: "card" },
156
+ ),
157
+ ).toMatchObject({
158
+ className: "card yakClass1 bg-white rounded-lg shadow-md p-6 hover:shadow-lg",
159
+ style: { "--card-transition": "all 0.2s ease" },
160
+ });
161
+ });
162
+
163
+ it("merge properties with css, atoms, and function combination", async () => {
164
+ expect(
165
+ mergeCssProp(
166
+ css(
167
+ "yakClass1",
168
+ atoms("px-4 py-2 rounded-md", true && "text-white bg-blue-600", (_, classNames, style) => {
169
+ classNames.add("hover:bg-blue-700 focus:outline-none");
170
+ style["--btn-focus-ring"] = "0 0 0 3px rgba(59, 130, 246, 0.1)";
171
+ }),
172
+ () => ({
173
+ className: "yakClass2 yakClass3",
174
+ style: { "--yak-var1": "500" },
175
+ }),
176
+ ),
177
+ { className: "btn", style: { cursor: "pointer" } },
178
+ ),
179
+ ).toMatchObject({
180
+ className:
181
+ "btn yakClass1 px-4 py-2 rounded-md text-white bg-blue-600 hover:bg-blue-700 focus:outline-none yakClass2 yakClass3",
182
+ style: {
183
+ cursor: "pointer",
184
+ "--btn-focus-ring": "0 0 0 3px rgba(59, 130, 246, 0.1)",
185
+ "--yak-var1": "500",
186
+ },
187
+ });
188
+ });
189
+
190
+ it("merge properties with nested css and atoms removing classes", async () => {
191
+ expect(
192
+ mergeCssProp(
193
+ css(
194
+ "yakClass1",
195
+ atoms("border border-gray-300 rounded-md", (_, classNames, style) => {
196
+ classNames.delete("input");
197
+ classNames.delete("yakClass1");
198
+ classNames.add("focus:border-blue-500 focus:ring-1 focus:ring-blue-500");
199
+ style["--input-padding"] = "0.75rem";
200
+ }),
201
+ () => ({ style: { "--yak-var1": "1rem" } }),
202
+ ),
203
+ { className: "input base-input" },
204
+ ),
205
+ ).toMatchObject({
206
+ className:
207
+ "base-input border border-gray-300 rounded-md focus:border-blue-500 focus:ring-1 focus:ring-blue-500",
208
+ style: {
209
+ "--input-padding": "0.75rem",
210
+ "--yak-var1": "1rem",
211
+ },
212
+ });
213
+ });
214
+
215
+ it("merge properties with complex atoms manipulation", async () => {
216
+ expect(
217
+ mergeCssProp(
218
+ atoms(
219
+ "fixed inset-0 z-50",
220
+ true && "bg-black bg-opacity-50",
221
+ false && "hidden",
222
+ (_, classNames, style) => {
223
+ classNames.add("flex items-center justify-center");
224
+ classNames.add("animate-fadeIn");
225
+ style["--modal-backdrop-blur"] = "blur(4px)";
226
+ style.backdropFilter = "blur(4px)";
227
+ },
228
+ ),
229
+ { className: "modal" },
230
+ ),
231
+ ).toMatchObject({
232
+ className:
233
+ "modal fixed inset-0 z-50 bg-black bg-opacity-50 flex items-center justify-center animate-fadeIn",
234
+ style: {
235
+ "--modal-backdrop-blur": "blur(4px)",
236
+ backdropFilter: "blur(4px)",
237
+ },
238
+ });
239
+ });
240
+
241
+ it("merge properties with responsive design classes", async () => {
242
+ expect(
243
+ mergeCssProp(
244
+ atoms(
245
+ "sm:w-1/2 md:w-1/3 lg:w-1/4",
246
+ true && "p-4",
247
+ false && "hidden",
248
+ (_, classNames, style) => {
249
+ classNames.add("xl:w-1/5 2xl:w-1/6");
250
+ style["--responsive-padding"] = "clamp(0.5rem, 2vw, 1rem)";
251
+ },
252
+ ),
253
+ { className: "w-full" },
254
+ ),
255
+ ).toMatchObject({
256
+ className: "w-full sm:w-1/2 md:w-1/3 lg:w-1/4 p-4 xl:w-1/5 2xl:w-1/6",
257
+ style: { "--responsive-padding": "clamp(0.5rem, 2vw, 1rem)" },
258
+ });
259
+ });
260
+
261
+ it("merge properties with form styling", async () => {
262
+ expect(
263
+ mergeCssProp(
264
+ css(
265
+ "yakClass1",
266
+ atoms(
267
+ "w-full px-3 py-2",
268
+ "border border-gray-300 rounded-md",
269
+ true && "focus:outline-none focus:ring-2 focus:ring-blue-500",
270
+ (_, classNames, style) => {
271
+ classNames.add("placeholder-gray-400 text-gray-900");
272
+ style["--input-transition"] =
273
+ "border-color 0.15s ease-in-out, box-shadow 0.15s ease-in-out";
274
+ },
275
+ ),
276
+ () => ({ style: { "--yak-var1": "1.5" } }),
277
+ ),
278
+ { className: "form-control", style: { minHeight: "40px" } },
279
+ ),
280
+ ).toMatchObject({
281
+ className:
282
+ "form-control yakClass1 w-full px-3 py-2 border border-gray-300 rounded-md focus:outline-none focus:ring-2 focus:ring-blue-500 placeholder-gray-400 text-gray-900",
283
+ style: {
284
+ minHeight: "40px",
285
+ "--input-transition": "border-color 0.15s ease-in-out, box-shadow 0.15s ease-in-out",
286
+ "--yak-var1": "1.5",
287
+ },
288
+ });
289
+ });
290
+
291
+ it("merge properties with dark mode and state variants", async () => {
292
+ expect(
293
+ mergeCssProp(
294
+ css(
295
+ "yakClass1",
296
+ atoms(
297
+ "bg-white dark:bg-gray-800",
298
+ "text-gray-900 dark:text-white",
299
+ true && "hover:bg-gray-50 dark:hover:bg-gray-700",
300
+ false && "opacity-50",
301
+ (_, classNames, style) => {
302
+ classNames.add("transition-all duration-200");
303
+ classNames.add("border border-gray-200 dark:border-gray-700");
304
+ style["--card-shadow"] =
305
+ "0 1px 3px 0 rgba(0, 0, 0, 0.1), 0 1px 2px 0 rgba(0, 0, 0, 0.06)";
306
+ style["--card-shadow-dark"] =
307
+ "0 1px 3px 0 rgba(255, 255, 255, 0.1), 0 1px 2px 0 rgba(255, 255, 255, 0.06)";
308
+ },
309
+ ),
310
+ ),
311
+ { className: "theme-card" },
312
+ ),
313
+ ).toMatchObject({
314
+ className:
315
+ "theme-card yakClass1 bg-white dark:bg-gray-800 text-gray-900 dark:text-white hover:bg-gray-50 dark:hover:bg-gray-700 transition-all duration-200 border border-gray-200 dark:border-gray-700",
316
+ style: {
317
+ "--card-shadow": "0 1px 3px 0 rgba(0, 0, 0, 0.1), 0 1px 2px 0 rgba(0, 0, 0, 0.06)",
318
+ "--card-shadow-dark":
319
+ "0 1px 3px 0 rgba(255, 255, 255, 0.1), 0 1px 2px 0 rgba(255, 255, 255, 0.06)",
320
+ },
321
+ });
322
+ });
323
+
324
+ // a falsy css prop applies no styles - the swc plugin folds the statically known
325
+ // cases, so these cover the shapes that stay on the runtime path
326
+ it.each([
327
+ ["false", false],
328
+ ["null", null],
329
+ ["undefined", undefined],
330
+ ])("applies no styles for a %s css prop", (_label, cssProp) => {
331
+ expect(mergeCssProp(cssProp, {})).toEqual({});
332
+ });
333
+
334
+ it("keeps the relevant props when the css prop is falsy", async () => {
335
+ expect(mergeCssProp(false, { className: "btn", style: { padding: "8px" } })).toMatchObject({
336
+ className: "btn",
337
+ style: { padding: "8px" },
338
+ });
339
+ });
340
+
341
+ describe("a css prop which can not apply styles", () => {
342
+ const originalNodeEnv = process.env.NODE_ENV;
343
+
344
+ beforeEach(() => {
345
+ // errors are only thrown in development mode
346
+ process.env.NODE_ENV = "development";
347
+ });
348
+
349
+ afterEach(() => {
350
+ process.env.NODE_ENV = originalNodeEnv;
351
+ });
352
+
353
+ it("throws for an array instead of calling it", () => {
354
+ expect(() => mergeCssProp([css("yakCss1")], {})).toThrowError(/but received an array/);
355
+ });
356
+
357
+ it("throws for an object instead of calling it", () => {
358
+ expect(() => mergeCssProp({ color: "red" }, {})).toThrowError(
359
+ /but received a value of type object/,
360
+ );
361
+ });
362
+
363
+ it("throws for a plain string instead of calling it", () => {
364
+ expect(() => mergeCssProp("yakCss1", {})).toThrowError(/but received a value of type string/);
365
+ });
366
+
367
+ it("renders unstyled in production instead of taking the page down", () => {
368
+ process.env.NODE_ENV = "production";
369
+ expect(mergeCssProp([css("yakCss1")], { className: "btn" })).toEqual({ className: "btn" });
370
+ });
371
+ });
372
+
373
+ describe("sources in JSX order", () => {
374
+ it("lets a later source win and appends the css classes", () => {
375
+ expect(mergeCssProp(css("yakCss1"), { className: "a" }, { className: "b" })).toEqual({
376
+ className: "b yakCss1",
377
+ });
378
+ });
379
+
380
+ it("keeps the order across a spread and forwards its other props", () => {
381
+ const onClick = () => {};
382
+ const spread = { className: "b", onClick };
383
+ expect(mergeCssProp(css("yakCss1"), { className: "a" }, spread, { className: "c" })).toEqual({
384
+ className: "c yakCss1",
385
+ onClick,
386
+ });
387
+ });
388
+
389
+ it("works without any source", () => {
390
+ expect(mergeCssProp(css("yakCss1"))).toEqual({ className: "yakCss1" });
391
+ });
392
+ });
@@ -0,0 +1,227 @@
1
+ /** @jsxImportSource @yak/react */
2
+ // this is only a type check file and should not be executed
3
+
4
+ import { css, styled } from "@yak/react";
5
+ import { ComponentProps, CSSProperties } from "react";
6
+
7
+ declare module "@yak/react" {
8
+ export interface YakTheme {
9
+ primaryColor: "red" | "blue";
10
+ }
11
+ }
12
+
13
+ const ComponentWithCssProp = () => {
14
+ return <div css={css``} />;
15
+ };
16
+
17
+ const ComponentWithEmptyCssPropAndClassName = () => {
18
+ return <div css={css``} className="static" />;
19
+ };
20
+
21
+ const ComponentWithEmptyCssPropInTernary = () => {
22
+ const on = Math.random() > 0.5;
23
+ return (
24
+ <div
25
+ css={
26
+ on
27
+ ? css``
28
+ : css`
29
+ padding: 10px;
30
+ `
31
+ }
32
+ />
33
+ );
34
+ };
35
+
36
+ const NestedComponentWithCssProp = () => (
37
+ <div>
38
+ <p>
39
+ <div
40
+ css={css`
41
+ padding: 10px;
42
+ `}
43
+ >
44
+ anything
45
+ </div>
46
+ </p>
47
+ </div>
48
+ );
49
+
50
+ const ComponentThatTakesCssProp = (p: {
51
+ className?: string;
52
+ style?: ComponentProps<"div">["style"];
53
+ }) => <div {...p}>anything</div>;
54
+
55
+ const ComponentThatTakesCssProp2 = (p: { className?: string | string[]; style?: {} }) => (
56
+ <div {...(p as any)}>anything</div>
57
+ );
58
+
59
+ const ComponentThatTakesCssProp3 = (p: { className: string; style?: Record<string, unknown> }) => (
60
+ <div {...p}>anything</div>
61
+ );
62
+
63
+ const ComponentThatTakesCssProp4 = (p: { className?: unknown; style?: unknown }) => (
64
+ <div {...(p as any)}>anything</div>
65
+ );
66
+
67
+ const ComponentWithCssPropAsProp = () => {
68
+ return (
69
+ <>
70
+ <ComponentThatTakesCssProp css={css``} />
71
+ <ComponentThatTakesCssProp2 css={css``} />
72
+ <ComponentThatTakesCssProp3 css={css``} className="" />
73
+ <ComponentThatTakesCssProp4 css={css``} />
74
+ </>
75
+ );
76
+ };
77
+
78
+ const ObjectWithComponent = {
79
+ ComponentThatTakesCssProp,
80
+ nested: {
81
+ ComponentThatTakesCssProp,
82
+ },
83
+ };
84
+ const ComponentThatUsesObjectWithComponent = () => (
85
+ <ObjectWithComponent.ComponentThatTakesCssProp
86
+ css={css`
87
+ padding: 10px;
88
+ `}
89
+ />
90
+ );
91
+
92
+ const ComponentThatUsesNestedObjectWithComponent = () => (
93
+ <ObjectWithComponent.nested.ComponentThatTakesCssProp
94
+ css={css`
95
+ padding: 10px;
96
+ `}
97
+ />
98
+ );
99
+
100
+ const ComponentWithCSSPropString = () => (
101
+ <div
102
+ // @ts-expect-error shouldn't allow strings as css prop
103
+ css={`
104
+ padding: 10px;
105
+ `}
106
+ >
107
+ anything
108
+ </div>
109
+ );
110
+
111
+ const padding = css`
112
+ padding: 10px;
113
+ `;
114
+ const ComponentThatReusesCSS = () => <div css={padding} />;
115
+
116
+ const ComponentWithConditionalCSSProp = () => (
117
+ <div
118
+ css={
119
+ true &&
120
+ css`
121
+ padding: 10px;
122
+ `
123
+ }
124
+ >
125
+ anything
126
+ </div>
127
+ );
128
+
129
+ const ComponentWithConditionalCSSProp2 = () => (
130
+ <div
131
+ css={
132
+ true
133
+ ? padding
134
+ : css`
135
+ padding: 20px;
136
+ `
137
+ }
138
+ />
139
+ );
140
+
141
+ const ComponentWithInterpolatedCSS = () => {
142
+ const x = Math.random() > 0.5;
143
+ return (
144
+ <div
145
+ // @ts-expect-error shouldn't allow interpolated css prop
146
+ css={(x) => css`
147
+ padding: 20px;
148
+ `}
149
+ />
150
+ );
151
+ };
152
+
153
+ const Text = styled.p`
154
+ font-size: 20px;
155
+ font-weight: bold;
156
+ font-family: "Inter";
157
+ `;
158
+
159
+ const StyledComponentWithCSSProp = () => {
160
+ <div>
161
+ <Text
162
+ css={css`
163
+ color: red;
164
+ `}
165
+ >
166
+ test
167
+ </Text>
168
+ </div>;
169
+ };
170
+
171
+ const ComponentWithConditionalCSSButWithoutOwnProps = () => {
172
+ const x = Math.random() > 0.5;
173
+ return (
174
+ <div
175
+ css={css`
176
+ ${() =>
177
+ x &&
178
+ css`
179
+ padding: 20px;
180
+ `}
181
+ `}
182
+ />
183
+ );
184
+ };
185
+
186
+ const ComponentWithConditionalCSSVarsButWithoutOwnProps = () => {
187
+ const x = Math.random() > 0.5;
188
+ return (
189
+ <div
190
+ css={css`
191
+ padding: ${() => x && "20px"};
192
+ `}
193
+ />
194
+ );
195
+ };
196
+
197
+ const ComponentWithDynamicCSSShouldGenerateTypeError = () => {
198
+ return (
199
+ <div
200
+ // @ts-expect-error - properties not supported
201
+ css={css<{ $primary: boolean }>`
202
+ padding: ${({ $primary }) => $primary && "20px"};
203
+ `}
204
+ />
205
+ );
206
+ };
207
+
208
+ const dynamicMixin = css<{ $primary: boolean }>`
209
+ ${({ $primary }) =>
210
+ $primary &&
211
+ css`
212
+ font-size: 1.7rem;
213
+ `}
214
+ `;
215
+
216
+ const ComponentWithCSSThatUsesDynamicMixinShouldGenerateTypeError = () => {
217
+ return (
218
+ <div
219
+ css={css`
220
+ ${
221
+ // @ts-expect-error - properties not supported
222
+ dynamicMixin
223
+ }
224
+ `}
225
+ />
226
+ );
227
+ };