Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

add error messages for simple cases #45

Merged
merged 4 commits into from
Jan 17, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 7 additions & 5 deletions packages/next-yak/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,7 @@
- **Standard CSS Syntax**: Write styles in familiar, easy-to-use CSS
- **Integrates with Atomic CSS**: Easily combines with atomic CSS frameworks like Tailwind CSS for more design options

<video width="630" height="300" src="https://github.com/jantimon/next-yak/assets/4113649/cfacb70e-1b42-4a41-9706-f5e4da1fe8cd" alt="Code example"></video>

[Preview (Video)](https://github.com/jantimon/next-yak/assets/4113649/5383f60c-3bab-4aba-906c-d66070b6116c)

## Installation

Expand Down Expand Up @@ -90,7 +89,7 @@ const ToggleButton = styled.button`
`;
```

<video width="630" height="300" src="https://github.com/jantimon/next-yak/assets/4113649/9065d0a0-f839-4d91-b05e-b3e72c7c2bb0" alt="Dynamic Styles example"></video>
[Dynamic Styles (Video)](https://github.com/jantimon/next-yak/assets/4113649/c5f52846-33e4-4058-9c78-efd98197d75f)

### Dynamic Properties

Expand Down Expand Up @@ -121,7 +120,8 @@ const ExampleComponent = () => {
};
```

<video width="630" height="300" src="https://github.com/jantimon/next-yak/assets/4113649/11e9aca7-f5c8-416b-bb67-67e180be81e8" alt="Dynamic Styles example"></video>
[Dynamic Props (video)](https://github.com/jantimon/next-yak/assets/4113649/2fa78f82-382c-465f-b294-2504739ea168)


### Targeting Components

Expand Down Expand Up @@ -158,7 +158,7 @@ const ExampleComponent = () => {
## Nesting

`next-yak` supports nesting out of the box.
Next.js 13 supports nesting only with the `postcss-nested` plugin.
[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.
Therefore you have to create a `postcss.config.js` file in your project root:

```js
Expand All @@ -170,6 +170,8 @@ module.exports = {
};
```

[Nesting Example (video)](https://github.com/jantimon/next-yak/assets/4113649/33eeeb13-b0cf-499f-a1d3-ba6f51cf4308)

## Motivation

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.
Expand Down
42 changes: 34 additions & 8 deletions packages/next-yak/loaders/__tests__/tsloader.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -356,8 +356,7 @@ const Wrapper = styled.div\`
`);
});

// TODO: this test was temporarily disabled because it was failing when inline css literals were introduced
it.skip("should show error when mixin is used in nested selector", async () => {
it("should show error when mixin is used in nested selector", async () => {
await expect(() =>
tsloader.call(
loaderContext,
Expand All @@ -378,9 +377,36 @@ const Icon = styled.div\`
`
)
).rejects.toThrowErrorMatchingInlineSnapshot(`
"/some/special/path/page.tsx: line 11: Expressions are not allowed inside nested selectors:
\\"bold\\" inside \\"@media (min-width: 640px) { .bar {\\"
found: \${bold}"
"/some/special/path/page.tsx: line 11: Mixins are not allowed inside nested selectors
found: \${bold}
Use an inline css literal instead or move the selector into the mixin"
`);
});

it("should show error when a mixin function is used in nested selector", async () => {
await expect(() =>
tsloader.call(
loaderContext,
`
import { styled, css } from "next-yak";

const bold = () => css\`
font-weight: bold;
\`

const Icon = styled.div\`
@media (min-width: 640px) {
.bar {
\${bold()}
}
}
\`
`
)
).rejects.toThrowErrorMatchingInlineSnapshot(`
"/some/special/path/page.tsx: line 11: Mixins are not allowed inside nested selectors
found: \${bold()}
Use an inline css literal instead or move the selector into the mixin"
`);
});

Expand All @@ -406,9 +432,9 @@ const Icon = styled.div\`
`
)
).rejects.toThrowErrorMatchingInlineSnapshot(`
"/some/special/path/page.tsx: line 11: Expressions are not allowed inside nested selectors:
Expression inside \\"@media (min-width: 640px) { .bar {\\"
found: \${() => css\`\${bold}\`}"
"/some/special/path/page.tsx: line 11: Mixins are not allowed inside nested selectors
found: \${bold}
Use an inline css literal instead or move the selector into the mixin"
`);
});
it("should show error when a dynamic selector is used", async () => {
Expand Down
24 changes: 16 additions & 8 deletions packages/next-yak/loaders/babel-yak-plugin.cjs
Original file line number Diff line number Diff line change
Expand Up @@ -340,13 +340,17 @@ module.exports = function (babel, options) {
wasInsideCssValue = false;
if (expression) {
if (quasiTypes[i].currentNestingScopes.length > 0) {
// TODO: inside a nested scope a foreign css literal must not be used
// as we can not forward the scope.
// Therefore the following code must throw an error:
// import { mixin } from "./some-file";
// const Button = styled.button`
// &:focus { ${mixin} }
// `
// inside a nested scope a foreign css literal must not be used
// as we can not forward the scope
const isReferenceToMixin = t.isIdentifier(expression) || t.isCallExpression(expression);
if (isReferenceToMixin) {
throw new InvalidPositionError(
`Mixins are not allowed inside nested selectors`,
expression,
this.file,
"Use an inline css literal instead or move the selector into the mixin"
);
}
}
newArguments.add(expression);
}
Expand Down Expand Up @@ -393,8 +397,9 @@ class InvalidPositionError extends Error {
* @param {string} message
* @param {import("@babel/types").Expression} expression
* @param {import("@babel/core").BabelFile} file
* @param {string} [recommendedFix]
*/
constructor(message, expression, file) {
constructor(message, expression, file, recommendedFix) {
let errorText = message;
const line = expression.loc?.start.line ?? -1;
if (line !== -1) {
Expand All @@ -406,6 +411,9 @@ class InvalidPositionError extends Error {
expression.end
)}}`;
}
if (recommendedFix) {
errorText += `\n${recommendedFix}`;
}
super(errorText);
}
}
Expand Down
2 changes: 1 addition & 1 deletion packages/next-yak/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "next-yak",
"version": "0.0.21",
"version": "0.0.22",
"type": "module",
"types": "./dist/",
"exports": {
Expand Down
Loading