Skip to content

Commit

Permalink
Merge remote-tracking branch 'origin/main' into fix-nested-css-prop
Browse files Browse the repository at this point in the history
  • Loading branch information
Mad-Kat committed Dec 20, 2024
2 parents d1efb78 + 11261b7 commit c28bd7d
Show file tree
Hide file tree
Showing 15 changed files with 738 additions and 23 deletions.
13 changes: 12 additions & 1 deletion packages/example/app/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -142,7 +142,18 @@ export default function Home() {
>
CSS Prop works if this is green
</p>

<p
css={css`
color: red;
${() =>
true &&
css`
color: green;
`}
`}
>
Conditional CSS Prop works if this is green
</p>
<p
css={css`
color: violet;
Expand Down
9 changes: 9 additions & 0 deletions packages/next-yak/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,14 @@
# next-yak

## 4.0.2

### Patch Changes

- 5ce7f16: Enable css prop support for styled components, not just native HTML elements by fixing a bug in the types
- 2f0ba89: Enable conditional styling for the css prop
- Updated dependencies [2f0ba89][5ce7f16]
- yak-swc@4.0.2

## 4.0.1

### Patch Changes
Expand Down
4 changes: 2 additions & 2 deletions packages/next-yak/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "next-yak",
"version": "4.0.1",
"version": "4.0.2",
"type": "module",
"types": "./dist/",
"license": "MIT",
Expand Down Expand Up @@ -77,7 +77,7 @@
"dependencies": {
"@babel/core": "7.23.2",
"@babel/plugin-syntax-typescript": "7.22.5",
"yak-swc": "4.0.1"
"yak-swc": "4.0.2"
},
"devDependencies": {
"@types/babel__core": "^7.1.14",
Expand Down
78 changes: 77 additions & 1 deletion packages/next-yak/runtime/__tests__/cssPropTest.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
/** @jsxImportSource next-yak */
// this is only a type check file and should not be executed

import { css } from "next-yak";
import { css, styled } from "next-yak";
import { CSSProperties } from "react";

declare module "next-yak" {
Expand Down Expand Up @@ -110,3 +110,79 @@ const ComponentWithInterpolatedCSS = () => {
/>
);
};

const Text = styled.p`
font-size: 20px;
font-weight: bold;
font-family: "Inter";
`;

const StyledComponentWithCSSProp = () => {
<div>
<Text
css={css`
color: red;
`}
>
test
</Text>
</div>;
};

const ComponentWithConditionalCSSButWithoutOwnProps = () => {
const x = Math.random() > 0.5;
return (
<div
css={css`
${() =>
x &&
css`
padding: 20px;
`}
`}
/>
);
};

const ComponentWithConditionalCSSVarsButWithoutOwnProps = () => {
const x = Math.random() > 0.5;
return (
<div
css={css`
padding: ${() => x && "20px"};
`}
/>
);
};

const ComponentWithDynamicCSSShouldGenerateTypeError = () => {
return (
<div
// @ts-expect-error - properties not supported
css={css<{ $primary: boolean }>`
padding: ${({ $primary }) => $primary && "20px"};
`}
/>
);
};

const dynamicMixin = css<{ $primary: boolean }>`
${({ $primary }) =>
$primary &&
css`
font-size: 1.7rem;
`}
`;

const ComponentWithCSSThatUsesDynamicMixinShouldGenerateTypeError = () => {
return (
<div
css={css`
${
// @ts-expect-error - properties not supported
dynamicMixin
}
`}
/>
);
};
9 changes: 5 additions & 4 deletions packages/next-yak/runtime/cssLiteral.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -58,14 +58,13 @@ export type PropsToClassNameFn = (props: unknown) =>
* Therefore this is only an internal function only and it must be cast to any
* before exported to the user.
*/
export function css(styles: TemplateStringsArray, ...values: []): StaticCSSProp;
export function css<TProps = {}>(
export function css<TProps>(
styles: TemplateStringsArray,
...values: CSSInterpolation<NoInfer<TProps> & { theme: YakTheme }>[]
): ComponentStyles<TProps>;
): TProps extends object ? ComponentStyles<TProps> : StaticCSSProp;
export function css<TProps>(
...args: Array<any>
): StaticCSSProp | ComponentStyles<TProps> {
): TProps extends object ? ComponentStyles<TProps> : StaticCSSProp {
const classNames: string[] = [];
const dynamicCssFunctions: PropsToClassNameFn[] = [];
const style: Record<string, string> = {};
Expand Down Expand Up @@ -110,9 +109,11 @@ export function css<TProps>(
// Non Dynamic CSS
if (dynamicCssFunctions.length === 0) {
const className = classNames.join(" ");
// @ts-expect-error - Conditional return types are tricky in the implementation and generate false positives
return () => ({ className, style });
}

// @ts-expect-error - Conditional return types are tricky in the implementation and generate false positives
return (props: unknown) => {
const allClassNames: string[] = [...classNames];
const allStyles: Record<string, string> = { ...style };
Expand Down
15 changes: 12 additions & 3 deletions packages/next-yak/runtime/styled.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,9 @@
import { CSSInterpolation, css, yakComponentSymbol } from "./cssLiteral.js";
import {
CSSInterpolation,
StaticCSSProp,
css,
yakComponentSymbol,
} from "./cssLiteral.js";
import React from "react";

// the following export is not relative as "next-yak/context"
Expand Down Expand Up @@ -84,7 +89,11 @@ type YakComponent<
T,
TAttrsIn extends object = {},
TAttrsOut extends AttrsMerged<T, TAttrsIn> = AttrsMerged<T, TAttrsIn>,
> = FunctionComponent<T> & {
> = FunctionComponent<
T & {
css?: StaticCSSProp;
}
> & {
[yakComponentSymbol]: [
FunctionComponent<T>,
AttrsFunction<T, TAttrsIn, TAttrsOut>,
Expand Down Expand Up @@ -120,7 +129,7 @@ const yakStyled = <
CSSInterpolation<T & NoInfer<TCSSProps> & { theme: YakTheme }>
>
) => {
const getRuntimeStyles = css(styles, ...(values as any));
const getRuntimeStyles = css<object>(styles, ...(values as any));
const yak = (props: Substitute<TCSSProps & T, TAttrsIn>) => {
// if the css component does not require arguments
// it can be called without arguments and we skip calling useTheme()
Expand Down
7 changes: 7 additions & 0 deletions packages/yak-swc/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,12 @@
# yak-swc

## 4.0.2

### Patch Changes

- 5ce7f16: Enable css prop support for styled components, not just native HTML elements by fixing a bug in the types
- 2f0ba89: Enable conditional styling for the css prop

## 4.0.1

### Patch Changes
Expand Down
2 changes: 1 addition & 1 deletion packages/yak-swc/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "yak-swc",
"version": "4.0.1",
"version": "4.0.2",
"description": "next-yak rust based swc plugin to compile styled components at build time",
"homepage": "https://yak.js.org/",
"repository": {
Expand Down
15 changes: 7 additions & 8 deletions packages/yak-swc/yak_swc/src/yak_transforms.rs
Original file line number Diff line number Diff line change
Expand Up @@ -193,17 +193,16 @@ impl YakTransform for TransformCssMixin {
) -> YakTransformResult {
let has_dynamic_content = !runtime_expressions.is_empty() || !runtime_css_variables.is_empty();

if (self.is_exported || self.is_within_jsx_attribute) && has_dynamic_content {
if self.is_exported && has_dynamic_content && !self.is_within_jsx_attribute {
// For now dynamic mixins are not supported cross file
// as the scope handling is quite complicated
let error_msg = if self.is_exported {
"Dynamic mixins must not be exported. Please ensure that this mixin requires no props."
} else {
"Dynamic mixins must not be used within JSX attributes. Please ensure that this mixin requires no props."
};

HANDLER.with(|handler| {
handler.struct_span_err(expression.span, error_msg).emit();
handler
.struct_span_err(
expression.span,
"Dynamic mixins must not be exported. Please ensure that this mixin requires no props.",
)
.emit();
});
}

Expand Down
Loading

0 comments on commit c28bd7d

Please sign in to comment.