@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
JavaScript
// 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
};