UNPKG

panda-plugin-crv

Version:

A Panda CSS plugin for responsive variants

138 lines (114 loc) 7.61 kB
"use strict";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});