@builder.io/mitosis
Version:
Write components once, run everywhere. Compiles to Vue, React, Solid, and Liquid. Import code from Figma and Builder.io
139 lines (138 loc) • 5.71 kB
JavaScript
Object.defineProperty(exports, "__esModule", { value: true });
exports.blockToSolid = void 0;
const babel_transform_1 = require("../../helpers/babel-transform");
const event_handlers_1 = require("../../helpers/event-handlers");
const filter_empty_text_nodes_1 = require("../../helpers/filter-empty-text-nodes");
const is_mitosis_node_1 = require("../../helpers/is-mitosis-node");
const typescript_1 = require("../../helpers/typescript");
const mitosis_node_1 = require("../../types/mitosis-node");
const core_1 = require("@babel/core");
const lodash_1 = require("lodash");
const html_tags_1 = require("../../constants/html_tags");
const styles_1 = require("./helpers/styles");
const ATTTRIBUTE_MAPPERS = {
// for: 'htmlFor',
};
const transformAttributeName = (name) => {
if ((0, typescript_1.objectHasKey)(ATTTRIBUTE_MAPPERS, name))
return ATTTRIBUTE_MAPPERS[name];
return name;
};
const blockToSolid = (json, component, options, insideJsx) => {
var _a, _b, _c, _d;
if (insideJsx) {
if (json.properties._text) {
return json.properties._text;
}
if ((_a = json.bindings._text) === null || _a === void 0 ? void 0 : _a.code) {
return `{${json.bindings._text.code}}`;
}
}
else {
if (json.properties._text) {
return `<>${json.properties._text}</>`;
}
if ((_b = json.bindings._text) === null || _b === void 0 ? void 0 : _b.code) {
return `${json.bindings._text.code}`;
}
}
if ((0, mitosis_node_1.checkIsForNode)(json)) {
const needsWrapper = json.children.length !== 1;
// The SolidJS `<For>` component has a special index() signal function.
// https://www.solidjs.com/docs/latest#%3Cfor%3E
return `<For each={${(_c = json.bindings.each) === null || _c === void 0 ? void 0 : _c.code}}>
{(${json.scope.forName}, _index) => {
const ${json.scope.indexName || 'index'} = _index();
return ${needsWrapper ? '<>' : ''}${json.children
.filter(filter_empty_text_nodes_1.filterEmptyTextNodes)
.map((child) => (0, exports.blockToSolid)(child, component, options, needsWrapper))}}}
${needsWrapper ? '</>' : ''}
</For>`;
}
let str = '';
const isFragment = json.name === 'Fragment';
if (isFragment) {
str += '<';
}
else {
str += `<${json.name} `;
}
if (json.name === 'Show' && (0, is_mitosis_node_1.isMitosisNode)(json.meta.else)) {
str += `fallback={${(0, exports.blockToSolid)(json.meta.else, component, options, false)}}`;
}
const classString = (0, styles_1.collectClassString)(json, options);
if (classString && !isFragment) {
str += ` class=${classString} `;
}
for (const key in json.properties) {
if (isFragment)
continue;
const value = json.properties[key];
const newKey = transformAttributeName(key);
str += ` ${newKey}="${value}" `;
}
for (const key in json.bindings) {
if (isFragment)
continue;
const { code, arguments: cusArg = ['event'], type } = json.bindings[key];
if (!code)
continue;
if (type === 'spread') {
str += ` {...(${code})} `;
}
else if ((0, event_handlers_1.checkIsEvent)(key)) {
const useKey = key === 'onChange' && json.name === 'input' ? 'onInput' : key;
const asyncKeyword = ((_d = json.bindings[key]) === null || _d === void 0 ? void 0 : _d.async) ? 'async ' : '';
str += ` ${useKey}={${asyncKeyword}(${cusArg.join(',')}) => ${code}} `;
}
else if (key === 'ref' && options.typescript) {
str += ` ${key}={${code}!} `;
}
else {
let useValue = code;
if (key === 'style') {
// Convert camelCase keys to kebab-case
// TODO: support more than top level objects, may need
// a runtime helper for expressions that are not a direct
// object literal, such as ternaries and other expression
// types
useValue = (0, babel_transform_1.babelTransformExpression)(code, {
ObjectExpression(path) {
// TODO: limit to top level objects only
for (const property of path.node.properties) {
if (core_1.types.isObjectProperty(property)) {
if (core_1.types.isIdentifier(property.key) || core_1.types.isStringLiteral(property.key)) {
const key = core_1.types.isIdentifier(property.key)
? property.key.name
: property.key.value;
property.key = core_1.types.stringLiteral((0, lodash_1.kebabCase)(key));
}
}
}
},
});
}
const newKey = transformAttributeName(key);
str += ` ${newKey}={${useValue}} `;
}
}
if (html_tags_1.SELF_CLOSING_HTML_TAGS.has(json.name)) {
return str + ' />';
}
str += '>';
if (json.children) {
str += json.children
.filter(filter_empty_text_nodes_1.filterEmptyTextNodes)
.map((item) => (0, exports.blockToSolid)(item, component, options, true))
.join('\n');
}
if (isFragment) {
str += '</>';
}
else {
str += `</${json.name}>`;
}
return str;
};
exports.blockToSolid = blockToSolid;
;