panda-plugin-crv
Version:
A Panda CSS plugin for responsive variants
138 lines (114 loc) • 7.61 kB
JavaScript
;var y=Object.defineProperty;var h=Object.getOwnPropertyDescriptor;var V=Object.getOwnPropertyNames;var W=Object.prototype.hasOwnProperty;var D=(t,e)=>{for(var n in e)y(t,n,{get:e[n],enumerable:!0})},H=(t,e,n,s)=>{if(e&&typeof e=="object"||typeof e=="function")for(let r of V(e))!W.call(t,r)&&r!==n&&y(t,r,{get:()=>e[r],enumerable:!(s=h(e,r))||s.enumerable});return t};var I=t=>H(y({},"__esModule",{value:!0}),t);var z={};D(z,{pluginResponsiveVariants:()=>_});module.exports=I(z);var v=require("ts-morph");var P=`
const groupByBreakpoint = (variants) => {
const result = {};
for (const bp of crvBreakpoints) {
let renamed = {};
for (const [key, value] of Object.entries(variants)) {
renamed[makeKey(key, bp)] = value;
}
result[bp] = renamed;
}
return Object.entries(result);
};
export const ccv = (args) => {
const { css, ...variants } = args;
if (!variants || !css) return [];
const compoundVariants = [{ ...variants, css }];
for (const [bp, keys] of groupByBreakpoint(variants)) {
compoundVariants.push({ ...keys, css: { [bp]: css } });
}
return compoundVariants;
};`,T=`
/**
* Create compound variants
*
* @example
* variants: {
* crv({
* variants: {
* ...crv('prop', {
* variant1: { color: 'red' },
* variant2: { color: 'blue' }
* })
* })
* },
* compoundVariants: [
* ...ccv({
* variant1: 'red',
* variant2: 'blue',
* css: {
* bg: 'green'
* }
* })
* ]
*/
export declare const ccv: <T extends Record<any, any> & { css: SystemStyleObject }>(
args: T,
) => Array<{ css: T['css'] } & Record<keyof T, any>>;
`;var x=(t,e)=>`${t}_${e}`,S=t=>`
const crvBreakpoints = [${t.map(e=>`'${e}'`).join(", ")}];
const makeKey = (name, bp) => {
return \`\${name}_\${bp}\`;
}
const injectBreakpoint = (styles, breakpoint) => {
return Object.fromEntries(
Object.entries(styles).map(([key, css]) => [[key], { [breakpoint]: css }]),
);
};
export const crv = (name, styles) => {
if (!name) return;
const variants = {
[name]: styles,
};
for (const bp of crvBreakpoints) {
variants[makeKey(name, bp)] = injectBreakpoint(styles, bp);
}
return variants;
};
export const splitResponsiveVariant = (name, value) => {
if (typeof value !== 'object') {
return { [name]: value };
}
const { base, ...rest } = value;
let variants = { [name]: base };
for (const bp of crvBreakpoints) {
if (!(bp in rest)) continue;
variants[makeKey(name, bp)] = rest[bp];
}
return variants;
};
export const splitCrv = splitResponsiveVariant;
${P}
`,$=t=>`/* eslint-disable */
import type { SystemStyleObject } from '../types/system-types';
type CrvBreakpoints = ${t.map(e=>`'${e}'`).join(" | ")};
/**
* Create responsive variants
*
* @example
* cva({
* variants: {
* ...crv('prop', {
* variant1: { color: 'red' },
* variant2: { color: 'blue' }
* })
* })
*/
export declare const crv: <T extends string, P extends Record<any, SystemStyleObject>>(
name: T,
styles: P
) => Record<\`\${T}_\${CrvBreakpoints}\` | T, P>;
/**
* Splits responsive objects into \`crv\` variants
*/
type SplitResponsiveVariant = <T extends string>(
name: T,
value: any
) => Record<\`\${T}_\${CrvBreakpoints}\` | T, any>;
export declare const splitCrv: SplitResponsiveVariant;
export declare const splitResponsiveVariant: SplitResponsiveVariant;
export type ResponsiveVariant<T> = Partial<Record<'base' | CrvBreakpoints, T>> | T;
${T}
`;var j=t=>t.replace(/^\s+|\s+$|\s+(?=\s)/g,""),C=t=>{let{writer:e,key:n,value:s,bp:r}=t;e.write(`${n}: {`);for(let i of s.getProperties()){if(!i.isKind(v.ts.SyntaxKind.PropertyAssignment))continue;let o=i.getInitializer()?.getText()??"";r?(e.write(`${i.getName()}: {`),e.write(`'${r}':`),e.write(`${j(o)},`),e.write("},")):e.write(`${j(i.getText())},`)}e.write("},")},A=(t,e,n,s="crv")=>{let{breakpoints:r,debug:i}=e,o=n.getDescendantsOfKind(v.ts.SyntaxKind.CallExpression).filter(c=>c.getExpression().getText()===s);if(o.length){for(let c of o){let f=c.getArguments()[0],p=c.getArguments()[1],a=f?.getText()??"";f&&f.isKind(v.ts.SyntaxKind.StringLiteral)&&(a=f.getLiteralValue()),!(!p||!p.isKind(v.ts.SyntaxKind.ObjectLiteralExpression))&&(c.replaceWithText(l=>{l.write("{"),C({writer:l,key:a,value:p});for(let d of r)C({writer:l,key:x(a,d),value:p,bp:d});l.write("}")}),i?.("plugin:crv",`crv: '${a}': ${t.filePath.split("/").at(-1)}`))}return n.getText()}};var u=require("ts-morph");var b=t=>t.replace(/^\s+|\s+$|\s+(?=\s)/g,""),K=t=>{let{writer:e,variants:n,value:s,bp:r,isLast:i}=t;e.write("{");for(let o of n){if(!o.isKind(u.ts.SyntaxKind.PropertyAssignment))continue;let c=o.getInitializer()?.getText()??"";r?(e.write(`${x(o.getName(),r)}: `),e.write(`${b(c)},`)):e.write(`${b(o.getText())},`)}e.write("css: {"),r&&e.write(`'${r}': {`);for(let o of s.getProperties())e.write(`${b(o.getText())},`);r&&e.write("}},"),r||e.write("},"),e.write(i?"}":"},")},B=(t,e,n,s="ccv")=>{let{breakpoints:r,debug:i}=e,o=n.getDescendantsOfKind(u.ts.SyntaxKind.SpreadElement).filter(c=>c.getExpression()?.getText().startsWith(s));if(o.length){for(let c of o){let f=c.getExpressionIfKind(u.ts.SyntaxKind.CallExpression);if(!f)continue;let p=f.getArguments().at(0);if(!p||!p.isKind(u.ts.SyntaxKind.ObjectLiteralExpression))continue;let a=p.getProperties(),l,d=a.filter(m=>m.isKind(u.ts.SyntaxKind.PropertyAssignment)?m.getName()!=="css":!1);for(let m of a)m.isKind(u.ts.SyntaxKind.PropertyAssignment)&&m.getName()==="css"&&(l=m.getInitializer());if(!l||!l.isKind(u.ts.SyntaxKind.ObjectLiteralExpression))continue;let E=c.replaceWithText(m=>{K({writer:m,variants:d,value:l});for(let[O,L]of r.entries())K({writer:m,variants:d,value:l,bp:L,isLast:O===r.length-1})});i?.("plugin:crv",`ccv: '${E.getText()}': ${t.filePath.split("/").at(-1)}`)}return n.getText()}};var k=["crv","ccv"],N=t=>{let e={};for(let n of t.getImportDeclarations())if(!(!n.getText().includes(k[0])&&!n.getText().includes(k[1])))for(let s of n.getNamedImports())for(let r of k)(s.getText()===r||s.getText().startsWith(`${r} as`))&&(e[r]=s.getAliasNode()?.getText()??r);return e},F=(t,e)=>{let{project:n}=e,s,r=n.createSourceFile("__crv-parser.tsx",t.content,{overwrite:!0}),i=N(r);if(i.crv&&(s=A(t,e,r,i.crv)),i.ccv&&(s=B(t,e,r,i.ccv)??s),!!s)return r.getText()};var R=(t,e)=>{let n=t.artifacts.find(a=>a.id==="css-fn"),s=t.artifacts.find(a=>a.id==="css-index"),r=s?.files.find(a=>a.file.match(/^index\.(mjs|js)/)),i=s?.files.find(a=>a.file.includes("index.d.")),o=r?.file.split(".").at(-1),c=i?.file.split(".").at(-1);if(!n||!r||!i)return t.artifacts;let f={file:`crv.${o}`,code:S(e.breakpoints)},p={file:`crv.d.${c}`,code:$(e.breakpoints)};return n.files.push(f,p),r.code+=`
export * from './crv.${o}';`,i.code+=`
export * from './crv';`,e.debug&&e.debug("plugin:crv","codegen complete"),t.artifacts};var g=require("ts-morph"),w=()=>({project:new g.Project({compilerOptions:{jsx:g.ts.JsxEmit.React,jsxFactory:"React.createElement",jsxFragmentFactory:"React.Fragment",module:g.ts.ModuleKind.ESNext,target:g.ts.ScriptTarget.ESNext,noUnusedParameters:!1,noEmit:!0,useVirtualFileSystem:!0,allowJs:!0},skipAddingFilesFromTsConfig:!0,skipFileDependencyResolution:!0,skipLoadingLibFiles:!0,manipulationSettings:{indentationText:g.IndentationText.TwoSpaces}}),breakpoints:[]});var _=()=>{let t=w();return{name:"panda-plugin-crv",hooks:{"context:created":e=>{t.debug=e.logger?.debug,t.breakpoints=Object.keys(e.ctx.config.theme?.breakpoints??{})},"parser:before":e=>F(e,t),"codegen:prepare":e=>R(e,t)}}};0&&(module.exports={pluginResponsiveVariants});