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

Feature/reference same file components #33

Merged
merged 7 commits into from
Nov 21, 2023
Merged
Show file tree
Hide file tree
Changes from 5 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
13 changes: 10 additions & 3 deletions packages/example/app/Input.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -20,10 +20,17 @@ const PasswordInput = styled(Input).attrs({
border: 2px solid #167f8d;
`;

const Centered = styled.div`
const Wrapper = styled.div`
display: flex;
flex-direction: column;
align-items: center;
transition: background-color 0.5s ease-in-out;
&:has(
${Input}:where(:hover, :focus),
${PasswordInput}:where(:hover, :focus)
) {
background-color: #4c4c4cb9;
}
`;

const Headline = styled.h2`
Expand All @@ -49,12 +56,12 @@ const Headline = styled.h2`

export const Inputs = () => {
return (
<Centered>
<Wrapper>
<Headline>Styled Inputs</Headline>
<Input placeholder="A small text input" />
<Input $size="2rem" placeholder="A large text input" />
<PasswordInput placeholder="A password input" />
<PasswordInput $size="2rem" placeholder="A large password input" />
</Centered>
</Wrapper>
);
};
2 changes: 1 addition & 1 deletion packages/next-yak/dist/index.cjs
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
"use strict";var b=Object.create;var l=Object.defineProperty;var h=Object.getOwnPropertyDescriptor;var N=Object.getOwnPropertyNames;var F=Object.getPrototypeOf,w=Object.prototype.hasOwnProperty;var O=(t,e)=>{for(var s in e)l(t,s,{get:e[s],enumerable:!0})},f=(t,e,s,o)=>{if(e&&typeof e=="object"||typeof e=="function")for(let n of N(e))!w.call(t,n)&&n!==s&&l(t,n,{get:()=>e[n],enumerable:!(o=h(e,n))||o.enumerable});return t};var R=(t,e,s)=>(s=t!=null?b(F(t)):{},f(e||!t||!t.__esModule?l(s,"default",{value:t,enumerable:!0}):s,t)),j=t=>f(l({},"__esModule",{value:!0}),t);var X={};O(X,{YakThemeProvider:()=>u.YakThemeProvider,atoms:()=>C,css:()=>y,keyframes:()=>I,styled:()=>k,useTheme:()=>u.useTheme});module.exports=j(X);var v=(...t)=>{let e=[],s=[],o={};for(let n of t)if(typeof n=="string")e.push(n);else if(typeof n=="function")s.push(n);else if(typeof n=="object"&&"style"in n)for(let r in n.style){let a=n.style[r];typeof a=="function"?s.push(i=>({style:{[r]:String(g(i,a))}})):o[r]=a}if(s.length===0){let n=e.join(" ");return()=>({className:n,style:o})}return n=>{let r=[...e],a={...o};for(let i=0;i<s.length;i++)E(n,s[i],r,a);return{className:r.join(" "),style:a}}},E=(t,e,s,o)=>{let n=e(t);for(;n;){if(typeof n=="function"){n=n(t);continue}else if(typeof n=="object"&&("className"in n&&n.className&&s.push(n.className),"style"in n&&n.style))for(let r in n.style)o[r]=n.style[r];break}},g=(t,e)=>{let s=e(t);if(typeof s=="function")return g(t,s);if(process.env.NODE_ENV==="development"&&typeof s!="string"&&typeof s!="number"&&!(s instanceof String))throw new Error(`Dynamic CSS functions must return a string or number but returned ${JSON.stringify(s)}`);return s},y=v;var p=R(require("react"),1),P=require("next-yak/context"),B=t=>Object.assign(p.default.forwardRef(t),{component:t}),M=t=>Object.assign(d(t),{attrs:e=>d(t,e)}),d=(t,e)=>(s,...o)=>{let n=y(s,...o),r=i=>J(i,typeof e=="function"?e(i):e);return B((i,S)=>{let c=r(Object.assign(e||n.length?{theme:(0,P.useTheme)()}:{},i)),m=n(c),T=typeof t=="string"?Y(c):c;return T.className=x(c.className,m.className),T.style="style"in c?{...c.style,...m.style}:m.style,typeof t!="string"&&"yak"in t?t.yak(T,S):(T.ref=S,p.default.createElement(t,{...T}))})},k=new Proxy(M,{get(t,e){return t(e)}});function Y(t){let e={};for(let s in t)!s.startsWith("$")&&s!=="theme"&&(e[s]=t[s]);return e}var x=(t,e)=>t?e?t+" "+e:t:e,A=t=>{let e={};for(let s in t)t[s]!==void 0&&(e[s]=t[s]);return e},J=(t,e)=>e?{..."$__attrs"in t?{...A(e),...t}:{...t,...A(e)},className:x(t.className,e.className),style:{...t.style||{},...e.style||{}},$__attrs:!0}:t;var C=(...t)=>{let e=t.join(" ");return()=>({className:e})};var I=(t,...e)=>t;var u=require("next-yak/context");0&&(module.exports={YakThemeProvider,atoms,css,keyframes,styled,useTheme});
"use strict";var b=Object.create;var l=Object.defineProperty;var h=Object.getOwnPropertyDescriptor;var N=Object.getOwnPropertyNames;var F=Object.getPrototypeOf,w=Object.prototype.hasOwnProperty;var O=(t,e)=>{for(var s in e)l(t,s,{get:e[s],enumerable:!0})},f=(t,e,s,o)=>{if(e&&typeof e=="object"||typeof e=="function")for(let n of N(e))!w.call(t,n)&&n!==s&&l(t,n,{get:()=>e[n],enumerable:!(o=h(e,n))||o.enumerable});return t};var R=(t,e,s)=>(s=t!=null?b(F(t)):{},f(e||!t||!t.__esModule?l(s,"default",{value:t,enumerable:!0}):s,t)),j=t=>f(l({},"__esModule",{value:!0}),t);var J={};O(J,{YakThemeProvider:()=>u.YakThemeProvider,atoms:()=>C,css:()=>y,keyframes:()=>I,styled:()=>k,useTheme:()=>u.useTheme});module.exports=j(J);var v=(...t)=>{let e=[],s=[],o={};for(let n of t)if(typeof n=="string")e.push(n);else if(typeof n=="function")s.push(n);else if(typeof n=="object"&&"style"in n)for(let r in n.style){let a=n.style[r];typeof a=="function"?s.push(i=>({style:{[r]:String(g(i,a))}})):o[r]=a}if(s.length===0){let n=e.join(" ");return()=>({className:n,style:o})}return n=>{let r=[...e],a={...o};for(let i=0;i<s.length;i++)E(n,s[i],r,a);return{className:r.join(" "),style:a}}},E=(t,e,s,o)=>{let n=e(t);for(;n;){if(typeof n=="function"){n=n(t);continue}else if(typeof n=="object"&&("className"in n&&n.className&&s.push(n.className),"style"in n&&n.style))for(let r in n.style)o[r]=n.style[r];break}},g=(t,e)=>{let s=e(t);if(typeof s=="function")return g(t,s);if(process.env.NODE_ENV==="development"&&typeof s!="string"&&typeof s!="number"&&!(s instanceof String))throw new Error(`Dynamic CSS functions must return a string or number but returned ${JSON.stringify(s)}`);return s},y=v;var p=R(require("react"),1),P=require("next-yak/context"),_=t=>Object.assign(p.default.forwardRef(t),{component:t}),B=t=>Object.assign(d(t),{attrs:e=>d(t,e)}),d=(t,e)=>(s,...o)=>{let n=y(s,...o),r=i=>Y(i,typeof e=="function"?e(i):e);return _((i,S)=>{let c=r(Object.assign(e||n.length?{theme:(0,P.useTheme)()}:{},i)),m=n(c),T=typeof t=="string"?M(c):c;return T.className=x(c.className,m.className),T.style="style"in c?{...c.style,...m.style}:m.style,typeof t!="string"&&"yak"in t?t.yak(T,S):(T.ref=S,p.default.createElement(t,{...T}))})},k=new Proxy(B,{get(t,e){return t(e)}});function M(t){let e={};for(let s in t)!s.startsWith("$")&&s!=="theme"&&(e[s]=t[s]);return e}var x=(t,e)=>t?e?t+" "+e:t:e,A=t=>{let e={};for(let s in t)t[s]!==void 0&&(e[s]=t[s]);return e},Y=(t,e)=>e?{..."$__attrs"in t?{...A(e),...t}:{...t,...A(e)},className:x(t.className,e.className),style:{...t.style||{},...e.style||{}},$__attrs:!0}:t;var C=(...t)=>{let e=t.join(" ");return()=>({className:e})};var I=(t,...e)=>t;var u=require("next-yak/context");0&&(module.exports={YakThemeProvider,atoms,css,keyframes,styled,useTheme});
//# sourceMappingURL=index.cjs.map
2 changes: 1 addition & 1 deletion packages/next-yak/dist/index.cjs.map

Large diffs are not rendered by default.

16 changes: 12 additions & 4 deletions packages/next-yak/dist/index.d.cts
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,9 @@ type ComponentStyles<TProps = {}> = (props: TProps) => {
[key: string]: string;
};
};
type CSSInterpolation<TProps = {}> = string | number | undefined | null | false | ComponentStyles<TProps> | ((props: TProps) => CSSInterpolation<TProps>);
type CSSInterpolation<TProps = {}> = string | number | undefined | null | false | ComponentStyles<TProps> | {
__yak: true;
} | ((props: TProps) => CSSInterpolation<TProps>);
type CSSFunction = <TProps = {}>(styles: TemplateStringsArray, ...values: CSSInterpolation<TProps & {
theme: YakTheme;
}>[]) => ComponentStyles<TProps>;
Expand Down Expand Up @@ -51,7 +53,9 @@ type Attrs<TBaseProps, TIn extends object = {}, TOut extends AttrsMerged<TBasePr
*/
type StyledLiteral<T> = <TCSSProps extends Record<string, unknown> = {}>(styles: TemplateStringsArray, ...values: Array<CSSInterpolation<T & TCSSProps & {
theme: YakTheme;
}>>) => FunctionComponent<TCSSProps & T>;
}>>) => FunctionComponent<TCSSProps & T> & {
__yak: true;
};
/**
* The `styled` method works perfectly on all of your own or any third-party component,
* as long as they attach the passed className prop to a DOM element.
Expand All @@ -67,10 +71,14 @@ type StyledLiteral<T> = <TCSSProps extends Record<string, unknown> = {}>(styles:
*/
declare const styled: (<T>(Component: keyof JSX.IntrinsicElements | FunctionComponent<T>) => (<TCSSProps extends Record<string, unknown> = {}>(styles: TemplateStringsArray, ...values: CSSInterpolation<T & TCSSProps & {
theme: YakTheme;
}>[]) => FunctionComponent<FastOmit<TCSSProps & T, never>>) & {
}>[]) => FunctionComponent<FastOmit<TCSSProps & T, never>> & {
__yak: true;
}) & {
attrs: <TAttrsIn extends object = {}, TAttrsOut extends AttrsMerged<T, TAttrsIn> = AttrsMerged<T, TAttrsIn>>(attrs: Attrs<T, TAttrsIn, TAttrsOut>) => <TCSSProps_1 extends Record<string, unknown> = {}>(styles: TemplateStringsArray, ...values: CSSInterpolation<T & TCSSProps_1 & {
theme: YakTheme;
}>[]) => FunctionComponent<Substitute<TCSSProps_1 & T, TAttrsIn>>;
}>[]) => FunctionComponent<Substitute<TCSSProps_1 & T, TAttrsIn>> & {
__yak: true;
};
}) & {
symbol: StyledLiteral<React.SVGProps<SVGSymbolElement>> & {
attrs: <TAttrsIn_1 extends object = {}, TAttrsOut_1 extends AttrsMerged<React.SVGProps<SVGSymbolElement>, TAttrsIn_1> = AttrsMerged<React.SVGProps<SVGSymbolElement>, TAttrsIn_1>>(attrs: Attrs<React.SVGProps<SVGSymbolElement>, TAttrsIn_1, TAttrsOut_1>) => StyledLiteral<Substitute<React.SVGProps<SVGSymbolElement>, TAttrsIn_1>>;
Expand Down
16 changes: 12 additions & 4 deletions packages/next-yak/dist/index.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,9 @@ type ComponentStyles<TProps = {}> = (props: TProps) => {
[key: string]: string;
};
};
type CSSInterpolation<TProps = {}> = string | number | undefined | null | false | ComponentStyles<TProps> | ((props: TProps) => CSSInterpolation<TProps>);
type CSSInterpolation<TProps = {}> = string | number | undefined | null | false | ComponentStyles<TProps> | {
__yak: true;
} | ((props: TProps) => CSSInterpolation<TProps>);
type CSSFunction = <TProps = {}>(styles: TemplateStringsArray, ...values: CSSInterpolation<TProps & {
theme: YakTheme;
}>[]) => ComponentStyles<TProps>;
Expand Down Expand Up @@ -51,7 +53,9 @@ type Attrs<TBaseProps, TIn extends object = {}, TOut extends AttrsMerged<TBasePr
*/
type StyledLiteral<T> = <TCSSProps extends Record<string, unknown> = {}>(styles: TemplateStringsArray, ...values: Array<CSSInterpolation<T & TCSSProps & {
theme: YakTheme;
}>>) => FunctionComponent<TCSSProps & T>;
}>>) => FunctionComponent<TCSSProps & T> & {
__yak: true;
};
/**
* The `styled` method works perfectly on all of your own or any third-party component,
* as long as they attach the passed className prop to a DOM element.
Expand All @@ -67,10 +71,14 @@ type StyledLiteral<T> = <TCSSProps extends Record<string, unknown> = {}>(styles:
*/
declare const styled: (<T>(Component: keyof JSX.IntrinsicElements | FunctionComponent<T>) => (<TCSSProps extends Record<string, unknown> = {}>(styles: TemplateStringsArray, ...values: CSSInterpolation<T & TCSSProps & {
theme: YakTheme;
}>[]) => FunctionComponent<FastOmit<TCSSProps & T, never>>) & {
}>[]) => FunctionComponent<FastOmit<TCSSProps & T, never>> & {
__yak: true;
}) & {
attrs: <TAttrsIn extends object = {}, TAttrsOut extends AttrsMerged<T, TAttrsIn> = AttrsMerged<T, TAttrsIn>>(attrs: Attrs<T, TAttrsIn, TAttrsOut>) => <TCSSProps_1 extends Record<string, unknown> = {}>(styles: TemplateStringsArray, ...values: CSSInterpolation<T & TCSSProps_1 & {
theme: YakTheme;
}>[]) => FunctionComponent<Substitute<TCSSProps_1 & T, TAttrsIn>>;
}>[]) => FunctionComponent<Substitute<TCSSProps_1 & T, TAttrsIn>> & {
__yak: true;
};
}) & {
symbol: StyledLiteral<React.SVGProps<SVGSymbolElement>> & {
attrs: <TAttrsIn_1 extends object = {}, TAttrsOut_1 extends AttrsMerged<React.SVGProps<SVGSymbolElement>, TAttrsIn_1> = AttrsMerged<React.SVGProps<SVGSymbolElement>, TAttrsIn_1>>(attrs: Attrs<React.SVGProps<SVGSymbolElement>, TAttrsIn_1, TAttrsOut_1>) => StyledLiteral<Substitute<React.SVGProps<SVGSymbolElement>, TAttrsIn_1>>;
Expand Down
2 changes: 1 addition & 1 deletion packages/next-yak/dist/index.js.map

Large diffs are not rendered by default.

58 changes: 57 additions & 1 deletion packages/next-yak/loaders/__tests__/cssloader.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -193,7 +193,7 @@ const newHeadline = styled(headline).attrs({
color: red;
}

.yak_1 {
.yak_2 {
color: black;
}"
`);
Expand Down Expand Up @@ -361,3 +361,59 @@ const FadeInButton = styled.button\`
}"
`);
});


it("should allow to target components", async () => {
expect(
await cssloader.call(
loaderContext,
`
import { styled, keyframes } from "next-yak";

const Link = styled.a\`
color: palevioletred;
\`

const Icon = styled.svg\`
fill: currentColor;
width: 1em;
height: 1em;
\${Link}:hover & {
color: red;
}
\${Link}:focus & {
color: red;
}
\`

const Wrapper = styled.div\`
&:has(> \${Link}) {
padding: 10px;
}
\`
`
)
).toMatchInlineSnapshot(`
".yak_0 {
color: palevioletred;
}

.yak_2 {
fill: currentColor;
width: 1em;
height: 1em;
.yak_1:hover & {
color: red;
}
.yak_1:focus & {
color: red;
}
}

.yak_4 {
&:has(> .yak_1) {
padding: 10px;
}
}"
`);
});
53 changes: 47 additions & 6 deletions packages/next-yak/loaders/__tests__/tsloader.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -125,8 +125,8 @@ const FancyButton = styled(Button)\`
import { styled, css } from \\"next-yak\\";
import __styleYak from \\"./page.yak.module.css!=!./page?./page.yak.module.css\\";
const x = Math.random();
const Button = styled.button(__styleYak.yak_0, x > 0.5 && css(__styleYak.yak_1));
const FancyButton = styled(Button)(__styleYak.yak_2);"
const Button = styled.button(__styleYak.yak_0, x > 0.5 && css(__styleYak.yak_2));
const FancyButton = styled(Button)(__styleYak.yak_3);"
`);
});

Expand Down Expand Up @@ -163,8 +163,8 @@ const FancyButton = styled(Button)\`
const x = Math.random();
const Button = styled.button(__styleYak.yak_0, ({
theme
}) => theme.mode === \\"dark\\" && css(__styleYak.yak_1));
const FancyButton = styled(Button)(__styleYak.yak_2);"
}) => theme.mode === \\"dark\\" && css(__styleYak.yak_2));
const FancyButton = styled(Button)(__styleYak.yak_3);"
`);
});
});
Expand Down Expand Up @@ -216,7 +216,7 @@ const newHeadline = styled(headline).attrs({
const headline = styled.input(__styleYak.yak_0);
const newHeadline = styled(headline).attrs({
type: \\"text\\"
})(__styleYak.yak_1);"
})(__styleYak.yak_2);"
`);
});

Expand Down Expand Up @@ -286,4 +286,45 @@ const FadeInButton = styled.button\`
}
});"
`);
});
});


it("should allow to target components", async () => {
expect(
await tsloader.call(
loaderContext,
`
import { styled, keyframes } from "next-yak";

const Link = styled.a\`
color: palevioletred;
\`

const Icon = styled.svg\`
fill: currentColor;
width: 1em;
height: 1em;
\${Link}:hover & {
color: red;
}
\${Link}:focus & {
color: red;
}
\`

const Wrapper = styled.div\`
&:has(> \${Link}) {
padding: 10px;
}
\`

`
)
).toMatchInlineSnapshot(`
"import { styled, keyframes } from \\"next-yak\\";
import __styleYak from \\"./page.yak.module.css!=!./page?./page.yak.module.css\\";
const Link = styled.a(__styleYak.yak_0, __styleYak.yak_1);
const Icon = styled.svg(__styleYak.yak_2);
const Wrapper = styled.div(__styleYak.yak_4);"
`);
});
39 changes: 37 additions & 2 deletions packages/next-yak/loaders/babel-yak-plugin.cjs
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ const replaceQuasiExpressionTokens = require("./lib/replaceQuasiExpressionTokens
const murmurhash2_32_gc = require("./lib/hash.cjs");
const { relative, resolve, basename } = require("path");
const localIdent = require("./lib/localIdent.cjs");
const getStyledComponentName = require("./lib/getStyledComponentName.cjs");

/** @typedef {{replaces: Record<string, unknown>, rootContext?: string}} YakBabelPluginOptions */

Expand All @@ -14,7 +15,7 @@ const localIdent = require("./lib/localIdent.cjs");
*
* @param {import("@babel/core")} babel
* @param {YakBabelPluginOptions} options
* @returns {babel.PluginObj<import("@babel/core").PluginPass & {localVarNames: {css?: string, styled?: string, keyframes?: string}, isImportedInCurrentFile: boolean, classNameCount: number, varIndex: number}>}
* @returns {babel.PluginObj<import("@babel/core").PluginPass & {localVarNames: {css?: string, styled?: string, keyframes?: string}, isImportedInCurrentFile: boolean, classNameCount: number, varIndex: number, variableNameToStyledCall: Map<string, {wasAdded: boolean, className: string, astNode: import("@babel/types").CallExpression}>}>}
*/
module.exports = function (babel, options) {
const { replaces } = options;
Expand All @@ -36,6 +37,7 @@ module.exports = function (babel, options) {
this.isImportedInCurrentFile = false;
this.classNameCount = 0;
this.varIndex = 0;
this.variableNameToStyledCall = new Map();
},
visitor: {
/**
Expand Down Expand Up @@ -143,7 +145,28 @@ module.exports = function (babel, options) {
return;
}

replaceQuasiExpressionTokens(path.node.quasi, replaces, t);
replaceQuasiExpressionTokens(path.node.quasi, (name) => {
if (name in replaces) {
return replaces[name];
}
const styledCall = this.variableNameToStyledCall.get(name);
if (styledCall) {
const { wasAdded, className, astNode } = styledCall;
// on first usage of another styled component, add a
// the className to it so it can be targeted
if (!wasAdded) {
styledCall.wasAdded = true;
astNode.arguments.push(
t.memberExpression(
t.identifier("__styleYak"),
t.identifier(className)
)
);
}
return className;
}
return false;
}, t);

// Keep the same selector for all quasis belonging to the same css block
const classNameExpression = t.memberExpression(
Expand Down Expand Up @@ -246,6 +269,18 @@ module.exports = function (babel, options) {

const styledCall = t.callExpression(tag, [...newArguments]);
path.replaceWith(styledCall);

// Store reference to AST node to allow other components to target the styled literal inside css like
// e.g. `& ${Button} { ... }`
if (isStyledLiteral || isStyledCall || isAttrsCall) {
const variableName = getStyledComponentName(path);
// TODO: reuse existing class name if possible
this.variableNameToStyledCall.set(variableName, {
wasAdded: false,
className: localIdent(this.classNameCount++, "className"),
astNode: styledCall,
});
}
},
},
};
Expand Down
27 changes: 25 additions & 2 deletions packages/next-yak/loaders/cssloader.cjs
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ const babel = require("@babel/core");
const quasiClassifier = require("./lib/quasiClassifier.cjs");
const localIdent = require("./lib/localIdent.cjs");
const replaceQuasiExpressionTokens = require("./lib/replaceQuasiExpressionTokens.cjs");
const getStyledComponentName = require("./lib/getStyledComponentName.cjs");
const murmurhash2_32_gc = require("./lib/hash.cjs");
const { relative } = require("path");

Expand Down Expand Up @@ -65,6 +66,9 @@ module.exports = async function cssLoader(source) {
/** @type {string | null} */
let hashedFile = null;

/** @type {Map<string, string>} */
const variableNameToStyledClassName = new Map();

/**
* find all css template literals in ast
* @type {{ code: string, loc: number }[]}
Expand Down Expand Up @@ -151,8 +155,15 @@ module.exports = async function cssLoader(source) {
) {
return;
}

replaceQuasiExpressionTokens(path.node.quasi, replaces, t);
replaceQuasiExpressionTokens(path.node.quasi, (name) => {
if (name in replaces) {
return replaces[name];
}
if (variableNameToStyledClassName.has(name)) {
return variableNameToStyledClassName.get(name)
}
return false;
}, t);

// Keep the same selector for all quasis belonging to the same css block
const literalSelector = localIdent(
Expand Down Expand Up @@ -209,6 +220,18 @@ module.exports = async function cssLoader(source) {
loc: quasi.loc?.start.line || 0,
});
}

// Store reference to AST node to allow other components to target the styled literal inside css like
// e.g. `& ${Button} { ... }`
jantimon marked this conversation as resolved.
Show resolved Hide resolved
if (isStyledLiteral || isStyledCall || isAttrsCall) {
const variableName = getStyledComponentName(path);
// TODO: reuse existing class name if possible
variableNameToStyledClassName.set(variableName, localIdent(
index++,
"selector"
));
}

},
});

Expand Down
Loading
Loading