UNPKG

@kuma-ui/compiler

Version:

🐻 Kuma UI is a utility-first, zero-runtime CSS-in-JS library that offers an outstanding developer experience and optimized performance.

100 lines (98 loc) 3.28 kB
// src/extractor/extract.ts import { Node } from "ts-morph"; import { isStyledProp, isPseudoProps, StyleGenerator } from "@kuma-ui/system"; import { componentDefaultProps, isComponentProps, componentHandler } from "@kuma-ui/core/components/componentList"; import { theme } from "@kuma-ui/sheet"; var extractProps = (componentName, jsx, propsMap) => { const styledProps = {}; const pseudoProps = {}; const componentProps = {}; const variant = theme.getVariants(componentName); const baseStyleProps = { ...variant?.baseStyle }; const systemDefaultProps = componentDefaultProps(componentName); const userDefaultProps = variant?.defaultProps; let isDefault = false; for (const [propName, propValue] of Object.entries({ ...systemDefaultProps, ...userDefaultProps, ...propsMap })) { if (isStyledProp(propName)) { styledProps[propName] = propValue; } else if (isPseudoProps(propName)) { pseudoProps[propName] = propValue; } else if (isComponentProps(componentName)(propName)) { componentProps[propName] = propValue; } else if (propName === "variant") { Object.assign(baseStyleProps, variant?.variants?.[propValue]); jsx.getAttribute("variant")?.remove(); } else if (propName === "IS_KUMA_DEFAULT") { isDefault = true; } } if (!(!!Object.keys(styledProps).length || !!Object.keys(pseudoProps).length || !!Object.keys(componentProps))) { return; } const specificProps = componentHandler(componentName)(componentProps); if (componentName === "Box" && isDefault) { for (const prop in baseStyleProps) { if (Object.hasOwn(baseStyleProps, prop)) { delete baseStyleProps[prop]; } } } const combinedProps = { ...baseStyleProps, ...specificProps, ...styledProps, ...pseudoProps }; const { className: generatedClassName, css } = new StyleGenerator( combinedProps ).getStyle(); if (!generatedClassName) return { css }; const classNameAttr = jsx.getAttribute("className"); let newClassName = generatedClassName; let newClassNameInitializer = ""; if (classNameAttr && Node.isJsxAttribute(classNameAttr)) { const initializer = classNameAttr.getInitializer(); if (Node.isStringLiteral(initializer)) { const existingClassName = initializer.getLiteralText(); if (existingClassName) newClassName += " " + existingClassName; newClassNameInitializer = `"${newClassName}"`; } else if (Node.isJsxExpression(initializer)) { const expression = initializer.getExpression(); if (expression) { newClassNameInitializer = `\`${newClassName} \${${expression.getText()}}\``; } } classNameAttr.remove(); } else { newClassNameInitializer = `"${newClassName}"`; } for (const styledPropKey of Object.keys(styledProps)) { jsx.getAttribute(styledPropKey)?.remove(); } for (const pseudoPropKey of Object.keys(pseudoProps)) { jsx.getAttribute(pseudoPropKey)?.remove(); } for (const componentPropsKey of Object.keys(componentProps)) { jsx.getAttribute(componentPropsKey)?.remove(); } jsx.addAttribute({ name: "className", initializer: `{${newClassNameInitializer}}` }); return { css }; }; export { extractProps };