UNPKG

@builder.io/mitosis

Version:

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

200 lines (191 loc) 9.09 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.componentToStencil = void 0; const on_mount_1 = require("../../generators/helpers/on-mount"); const blocks_1 = require("../../generators/stencil/blocks"); const helpers_1 = require("../../generators/stencil/helpers"); const get_code_processor_plugins_1 = require("../../generators/stencil/plugins/get-code-processor-plugins"); const dash_case_1 = require("../../helpers/dash-case"); const dedent_1 = require("../../helpers/dedent"); const event_handlers_1 = require("../../helpers/event-handlers"); const fast_clone_1 = require("../../helpers/fast-clone"); const get_child_components_1 = require("../../helpers/get-child-components"); const get_props_1 = require("../../helpers/get-props"); const get_state_object_string_1 = require("../../helpers/get-state-object-string"); const indent_1 = require("../../helpers/indent"); const map_refs_1 = require("../../helpers/map-refs"); const merge_options_1 = require("../../helpers/merge-options"); const strip_meta_properties_1 = require("../../helpers/strip-meta-properties"); const collect_css_1 = require("../../helpers/styles/collect-css"); const attribute_passing_1 = require("../../helpers/web-components/attribute-passing"); const plugins_1 = require("../../modules/plugins"); const standalone_1 = require("prettier/standalone"); const componentToStencil = (_options = { typescript: true, // Stencil is uses .tsx always }) => { return ({ component }) => { var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k; let json = (0, fast_clone_1.fastClone)(component); const options = (0, merge_options_1.initializeOptions)({ target: 'stencil', component, defaults: _options, }); if (options.plugins) { json = (0, plugins_1.runPreJsonPlugins)({ json, plugins: options.plugins }); } (0, map_refs_1.mapRefs)(json, (refName) => `this.${refName}`); let css = (0, collect_css_1.collectCss)(json); let props = Array.from((0, get_props_1.getProps)(json)); const events = props.filter((prop) => (0, event_handlers_1.checkIsEvent)(prop)); const defaultProps = json.defaultProps; const childComponents = (0, get_child_components_1.getChildComponents)(json); props = props.filter((prop) => { // Stencil doesn't need children as a prop return prop !== 'children'; }); const processBindingOptions = { events, props, target: 'stencil' }; options.plugins = (0, get_code_processor_plugins_1.getCodeProcessorPlugins)(json, options, processBindingOptions); if (options.plugins) { json = (0, plugins_1.runPostJsonPlugins)({ json, plugins: options.plugins }); } (0, strip_meta_properties_1.stripMetaProperties)(json); const dataString = (0, get_state_object_string_1.getStateObjectStringFromComponent)(json, { format: 'class', data: true, functions: false, getters: false, keyPrefix: '@State() ', }); const methodsString = (0, get_state_object_string_1.getStateObjectStringFromComponent)(json, { format: 'class', data: false, functions: true, getters: true, }); let refs = json.refs ? Object.entries(json.refs) .map(([key, value]) => { var _a; return `private ${key}!: ${(_a = value.typeParameter) !== null && _a !== void 0 ? _a : 'HTMLElement'};`; }) .join('\n') : ''; const wrap = (0, helpers_1.needsWrap)(json.children); const withAttributePassing = !wrap && (0, attribute_passing_1.shouldAddAttributePassing)(json, options); const rootRef = (0, attribute_passing_1.getAddAttributePassingRef)(json, options); if (withAttributePassing && !refs.includes(rootRef)) { refs += `\nprivate ${rootRef}!: HTMLElement;`; } if (options.prettier !== false) { try { css = (0, standalone_1.format)(css, { parser: 'css', plugins: [require('prettier/parser-postcss')], }); } catch (err) { console.warn('Could not format css', err); } } let tagName = (0, helpers_1.getTagName)(json.name, options); if ((_a = json.meta.useMetadata) === null || _a === void 0 ? void 0 : _a.tagName) { // Deprecated option, we shouldn't use this, instead change the name of your Mitosis component tagName = (_b = json.meta.useMetadata) === null || _b === void 0 ? void 0 : _b.tagName; } const noDependencyOnUpdateHooks = (_d = (_c = json.hooks.onUpdate) === null || _c === void 0 ? void 0 : _c.filter((hook) => !hook.deps)) !== null && _d !== void 0 ? _d : []; /* * We want to create a function for every onUpdate hook that has dependencies. * We call the function once in "componentDidLoad" * And we create "Watch" decorators for every dependency */ const dependencyOnUpdateHooks = (_f = (_e = json.hooks.onUpdate) === null || _e === void 0 ? void 0 : _e.filter((hook) => hook.deps)) !== null && _f !== void 0 ? _f : []; const coreImports = (0, helpers_1.getStencilCoreImportsAsString)({ wrap, events, props, dataString, watch: Boolean(dependencyOnUpdateHooks === null || dependencyOnUpdateHooks === void 0 ? void 0 : dependencyOnUpdateHooks.length), }); const propOptions = { ...options.propOptions, ...(_h = (_g = json.meta.useMetadata) === null || _g === void 0 ? void 0 : _g.stencil) === null || _h === void 0 ? void 0 : _h.propOptions, }; let str = (0, dedent_1.dedent) ` ${(0, helpers_1.getImports)(json, options, childComponents)} import { ${coreImports} } from '@stencil/core'; @Component({ tag: '${tagName}', ${((_j = json.meta.useMetadata) === null || _j === void 0 ? void 0 : _j.isAttachedToShadowDom) ? 'shadow: true,' : ''} ${css.length ? `styles: \` ${(0, indent_1.indent)(css, 8)}\`,` : ''} }) export class ${json.name} { ${refs} ${(0, helpers_1.getPropsAsCode)({ props, json, defaultProps, propOptions })} ${dataString} ${methodsString} ${(0, helpers_1.getExportsAndLocal)(json)} ${withAttributePassing ? (0, attribute_passing_1.getAttributePassingString)(true) : ''} ${dependencyOnUpdateHooks .map((hook, index) => { return ` watch${index}Fn() { ${hook.code} } ${(0, helpers_1.getDepsAsArray)(hook.deps) .map((dep) => `@Watch("${dep}")`) .join('\n')} watch${index}(){ this.watch${index}Fn(); } `; }) .join('\n')} ${`componentDidLoad() { ${withAttributePassing ? `this.enableAttributePassing(this.${rootRef}, "${(0, dash_case_1.dashCase)(json.name)}");` : ''} ${json.hooks.onMount.length ? (0, on_mount_1.stringifySingleScopeOnMount)(json) : ''} ${dependencyOnUpdateHooks .map((_, index) => `this.watch${index}Fn();`) .join('\n')} }`} ${!((_k = json.hooks.onUnMount) === null || _k === void 0 ? void 0 : _k.code) ? '' : `disconnectedCallback() { ${json.hooks.onUnMount.code} }`} ${noDependencyOnUpdateHooks.length ? `componentDidUpdate() { ${noDependencyOnUpdateHooks .map((hook) => hook.code) .join('\n')} }` : ''} render() { return (${wrap ? '<Host>' : ''} ${json.children .map((item) => (0, blocks_1.blockToStencil)({ json: item, options, insideJsx: true, childComponents, rootRef: withAttributePassing && rootRef === attribute_passing_1.ROOT_REF ? rootRef : undefined, // only pass rootRef if it's not the default })) .join('\n')} ${wrap ? '</Host>' : ''}) } } `; if (options.plugins) { str = (0, plugins_1.runPreCodePlugins)({ json, code: str, plugins: options.plugins }); } if (options.prettier !== false) { str = (0, standalone_1.format)(str, { parser: 'typescript', plugins: [require('prettier/parser-typescript')], }); } if (options.plugins) { str = (0, plugins_1.runPostCodePlugins)({ json, code: str, plugins: options.plugins }); } return str; }; }; exports.componentToStencil = componentToStencil;