UNPKG

@builder.io/mitosis

Version:

Write components once, run everywhere. Compiles to Vue, React, Solid, and Liquid. Import code from Figma and Builder.io

157 lines (156 loc) 7.44 kB
"use strict"; var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); exports.getDefaultImport = exports.getReactVariantStateString = exports.getReactVariantStateImportString = exports.updateStateSettersInCode = exports.updateStateSetters = exports.getUseStateCode = exports.processHookCode = void 0; const capitalize_1 = require("../../../helpers/capitalize"); const get_function_string_1 = require("../../../helpers/get-function-string"); const get_state_object_string_1 = require("../../../helpers/get-state-object-string"); const get_typed_function_1 = require("../../../helpers/get-typed-function"); const is_mitosis_node_1 = require("../../../helpers/is-mitosis-node"); const patterns_1 = require("../../../helpers/patterns"); const transform_state_setters_1 = require("../../../helpers/transform-state-setters"); const core_1 = require("@babel/core"); const function_1 = require("fp-ts/lib/function"); const legacy_1 = __importDefault(require("neotraverse/legacy")); const helpers_1 = require("../helpers"); /** * Removes all `this.` references. */ const stripThisRefs = (str, options) => { if (options.stateType !== 'useState') { return str; } return str.replace(/this\.([a-zA-Z_\$0-9]+)/g, '$1'); }; const processHookCode = ({ str, options }) => (0, helpers_1.processBinding)((0, exports.updateStateSettersInCode)(str, options), options); exports.processHookCode = processHookCode; const valueMapper = (options) => (val) => { const x = (0, exports.processHookCode)({ str: val, options }); return stripThisRefs(x, options); }; const getSetStateFnName = (stateName) => `set${(0, capitalize_1.capitalize)(stateName)}`; const processStateValue = (options) => { const mapValue = valueMapper(options); return ([key, stateVal]) => { if (!stateVal) { return ''; } let value = stateVal.code || ''; const type = stateVal.type; const typeParameter = stateVal.typeParameter; const stateType = options.typescript && stateVal.typeParameter ? `<${stateVal.typeParameter}>` : ''; let result = ''; if (type === 'getter') { result = (0, function_1.pipe)(value, patterns_1.replaceGetterWithFunction, mapValue); } else if (type === 'function') { result = mapValue(value); } else if (type === 'method') { result = (0, function_1.pipe)(value, patterns_1.prefixWithFunction, mapValue); } else { return `const [${key}, ${getSetStateFnName(key)}] = useState${stateType}(() => (${mapValue(value)}))`; } return (0, get_typed_function_1.getTypedFunction)(result, options.typescript, typeParameter); }; }; const getUseStateCode = (json, options) => { const lineItemDelimiter = '\n\n\n'; const stringifiedState = Object.entries(json.state).map(processStateValue(options)); return stringifiedState.join(lineItemDelimiter); }; exports.getUseStateCode = getUseStateCode; const updateStateSetters = (json, options) => { if (options.stateType !== 'useState') { return; } (0, legacy_1.default)(json).forEach(function (item) { if ((0, is_mitosis_node_1.isMitosisNode)(item)) { for (const key in item.bindings) { let values = item.bindings[key]; const newValue = (0, exports.updateStateSettersInCode)(values === null || values === void 0 ? void 0 : values.code, options); if (newValue !== (values === null || values === void 0 ? void 0 : values.code)) { item.bindings[key] = { ...values, code: newValue, }; } } } }); }; exports.updateStateSetters = updateStateSetters; const updateStateSettersInCode = (value, options) => { if (options.stateType !== 'useState') { return value; } return (0, transform_state_setters_1.transformStateSetters)({ value, transformer: ({ path, propertyName }) => core_1.types.callExpression(core_1.types.identifier(getSetStateFnName(propertyName)), [path.node.right]), }); }; exports.updateStateSettersInCode = updateStateSettersInCode; const getReactVariantStateImportString = (hasState, options) => { return !hasState ? '' : options.stateType === 'valtio' ? `import { useLocalProxy } from 'valtio/utils';` : options.stateType === 'solid' ? `import { useMutable } from 'react-solid-state';` : options.stateType === 'mobx' ? `import { useLocalObservable, observer } from 'mobx-react-lite';` : ''; }; exports.getReactVariantStateImportString = getReactVariantStateImportString; const getReactVariantStateString = ({ hasState, options, json, useStateCode, }) => hasState ? options.stateType === 'mobx' ? `const state = useLocalObservable(() => (${(0, get_state_object_string_1.getStateObjectStringFromComponent)(json)}));` : options.stateType === 'useState' ? useStateCode : options.stateType === 'solid' ? `const state = useMutable(${(0, get_state_object_string_1.getStateObjectStringFromComponent)(json)});` : options.stateType === 'builder' ? `const state = useBuilderState(${(0, get_state_object_string_1.getStateObjectStringFromComponent)(json)});` : options.stateType === 'variables' ? (0, get_state_object_string_1.getStateObjectStringFromComponent)(json, { format: 'variables', keyPrefix: 'const', valueMapper: (code, type, _, key) => { if (key) { const constPrefix = !code.startsWith('function') ? `${key} = ` : ''; if (type === 'getter') return `${constPrefix}${(0, get_function_string_1.getFunctionString)(code.replace('get ', ''))}`; if (type === 'function') return code.startsWith('async') ? code : `${constPrefix}${(0, get_function_string_1.getFunctionString)(code)}`; } return code; }, }) : `const state = useLocalProxy(${(0, get_state_object_string_1.getStateObjectStringFromComponent)(json)});` : ''; exports.getReactVariantStateString = getReactVariantStateString; const getDefaultImport = (options) => { const { preact, type } = options; if (preact) { return ` /** @jsx h */ import { h, Fragment } from 'preact'; `; } if (type === 'native') { return ` import * as React from 'react'; import { FlatList, ScrollView, View, StyleSheet, Image, Text, Pressable, TextInput, TouchableOpacity, Button, Linking } from 'react-native'; `; } if (type === 'taro') { return ` import * as React from 'react'; `; } return "import * as React from 'react';"; }; exports.getDefaultImport = getDefaultImport;