next-yak 0.0.21 → 0.0.22

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/README.md CHANGED
@@ -16,8 +16,7 @@
16
16
  - **Standard CSS Syntax**: Write styles in familiar, easy-to-use CSS
17
17
  - **Integrates with Atomic CSS**: Easily combines with atomic CSS frameworks like Tailwind CSS for more design options
18
18
 
19
- <video width="630" height="300" src="https://github.com/jantimon/next-yak/assets/4113649/cfacb70e-1b42-4a41-9706-f5e4da1fe8cd" alt="Code example"></video>
20
-
19
+ [Preview (Video)](https://github.com/jantimon/next-yak/assets/4113649/5383f60c-3bab-4aba-906c-d66070b6116c)
21
20
 
22
21
  ## Installation
23
22
 
@@ -90,7 +89,7 @@ const ToggleButton = styled.button`
90
89
  `;
91
90
  ```
92
91
 
93
- <video width="630" height="300" src="https://github.com/jantimon/next-yak/assets/4113649/9065d0a0-f839-4d91-b05e-b3e72c7c2bb0" alt="Dynamic Styles example"></video>
92
+ [Dynamic Styles (Video)](https://github.com/jantimon/next-yak/assets/4113649/c5f52846-33e4-4058-9c78-efd98197d75f)
94
93
 
95
94
  ### Dynamic Properties
96
95
 
@@ -121,7 +120,8 @@ const ExampleComponent = () => {
121
120
  };
122
121
  ```
123
122
 
124
- <video width="630" height="300" src="https://github.com/jantimon/next-yak/assets/4113649/11e9aca7-f5c8-416b-bb67-67e180be81e8" alt="Dynamic Styles example"></video>
123
+ [Dynamic Props (video)](https://github.com/jantimon/next-yak/assets/4113649/2fa78f82-382c-465f-b294-2504739ea168)
124
+
125
125
 
126
126
  ### Targeting Components
127
127
 
@@ -158,7 +158,7 @@ const ExampleComponent = () => {
158
158
  ## Nesting
159
159
 
160
160
  `next-yak` supports nesting out of the box.
161
- Next.js 13 supports nesting only with the `postcss-nested` plugin.
161
+ [For now](https://github.com/css-modules/postcss-modules-local-by-default/pull/64) Next.js 13 supports nesting only with the `postcss-nested` plugin.
162
162
  Therefore you have to create a `postcss.config.js` file in your project root:
163
163
 
164
164
  ```js
@@ -170,6 +170,8 @@ module.exports = {
170
170
  };
171
171
  ```
172
172
 
173
+ [Nesting Example (video)](https://github.com/jantimon/next-yak/assets/4113649/33eeeb13-b0cf-499f-a1d3-ba6f51cf4308)
174
+
173
175
  ## Motivation
174
176
 
175
177
  Most of the existing CSS-in-JS libraries are either slow or have a complex api. This project tries to find a middle ground between speed and api complexity.
@@ -356,8 +356,7 @@ const Wrapper = styled.div\`
356
356
  `);
357
357
  });
358
358
 
359
- // TODO: this test was temporarily disabled because it was failing when inline css literals were introduced
360
- it.skip("should show error when mixin is used in nested selector", async () => {
359
+ it("should show error when mixin is used in nested selector", async () => {
361
360
  await expect(() =>
362
361
  tsloader.call(
363
362
  loaderContext,
@@ -378,9 +377,36 @@ const Icon = styled.div\`
378
377
  `
379
378
  )
380
379
  ).rejects.toThrowErrorMatchingInlineSnapshot(`
381
- "/some/special/path/page.tsx: line 11: Expressions are not allowed inside nested selectors:
382
- \\"bold\\" inside \\"@media (min-width: 640px) { .bar {\\"
383
- found: \${bold}"
380
+ "/some/special/path/page.tsx: line 11: Mixins are not allowed inside nested selectors
381
+ found: \${bold}
382
+ Use an inline css literal instead or move the selector into the mixin"
383
+ `);
384
+ });
385
+
386
+ it("should show error when a mixin function is used in nested selector", async () => {
387
+ await expect(() =>
388
+ tsloader.call(
389
+ loaderContext,
390
+ `
391
+ import { styled, css } from "next-yak";
392
+
393
+ const bold = () => css\`
394
+ font-weight: bold;
395
+ \`
396
+
397
+ const Icon = styled.div\`
398
+ @media (min-width: 640px) {
399
+ .bar {
400
+ \${bold()}
401
+ }
402
+ }
403
+ \`
404
+ `
405
+ )
406
+ ).rejects.toThrowErrorMatchingInlineSnapshot(`
407
+ "/some/special/path/page.tsx: line 11: Mixins are not allowed inside nested selectors
408
+ found: \${bold()}
409
+ Use an inline css literal instead or move the selector into the mixin"
384
410
  `);
385
411
  });
386
412
 
@@ -406,9 +432,9 @@ const Icon = styled.div\`
406
432
  `
407
433
  )
408
434
  ).rejects.toThrowErrorMatchingInlineSnapshot(`
409
- "/some/special/path/page.tsx: line 11: Expressions are not allowed inside nested selectors:
410
- Expression inside \\"@media (min-width: 640px) { .bar {\\"
411
- found: \${() => css\`\${bold}\`}"
435
+ "/some/special/path/page.tsx: line 11: Mixins are not allowed inside nested selectors
436
+ found: \${bold}
437
+ Use an inline css literal instead or move the selector into the mixin"
412
438
  `);
413
439
  });
414
440
  it("should show error when a dynamic selector is used", async () => {
@@ -340,13 +340,17 @@ module.exports = function (babel, options) {
340
340
  wasInsideCssValue = false;
341
341
  if (expression) {
342
342
  if (quasiTypes[i].currentNestingScopes.length > 0) {
343
- // TODO: inside a nested scope a foreign css literal must not be used
344
- // as we can not forward the scope.
345
- // Therefore the following code must throw an error:
346
- // import { mixin } from "./some-file";
347
- // const Button = styled.button`
348
- // &:focus { ${mixin} }
349
- // `
343
+ // inside a nested scope a foreign css literal must not be used
344
+ // as we can not forward the scope
345
+ const isReferenceToMixin = t.isIdentifier(expression) || t.isCallExpression(expression);
346
+ if (isReferenceToMixin) {
347
+ throw new InvalidPositionError(
348
+ `Mixins are not allowed inside nested selectors`,
349
+ expression,
350
+ this.file,
351
+ "Use an inline css literal instead or move the selector into the mixin"
352
+ );
353
+ }
350
354
  }
351
355
  newArguments.add(expression);
352
356
  }
@@ -393,8 +397,9 @@ class InvalidPositionError extends Error {
393
397
  * @param {string} message
394
398
  * @param {import("@babel/types").Expression} expression
395
399
  * @param {import("@babel/core").BabelFile} file
400
+ * @param {string} [recommendedFix]
396
401
  */
397
- constructor(message, expression, file) {
402
+ constructor(message, expression, file, recommendedFix) {
398
403
  let errorText = message;
399
404
  const line = expression.loc?.start.line ?? -1;
400
405
  if (line !== -1) {
@@ -406,6 +411,9 @@ class InvalidPositionError extends Error {
406
411
  expression.end
407
412
  )}}`;
408
413
  }
414
+ if (recommendedFix) {
415
+ errorText += `\n${recommendedFix}`;
416
+ }
409
417
  super(errorText);
410
418
  }
411
419
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "next-yak",
3
- "version": "0.0.21",
3
+ "version": "0.0.22",
4
4
  "type": "module",
5
5
  "types": "./dist/",
6
6
  "exports": {