@builder.io/mitosis 0.4.7 → 0.5.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (32) hide show
  1. package/dist/src/generators/angular/index.js +4 -9
  2. package/dist/src/generators/react/generator.js +1 -1
  3. package/dist/src/generators/react/types.d.ts +1 -0
  4. package/dist/src/generators/react-native/extract-css-var-default-value.d.ts +1 -0
  5. package/dist/src/generators/react-native/extract-css-var-default-value.js +15 -0
  6. package/dist/src/generators/react-native/helpers.d.ts +3 -0
  7. package/dist/src/generators/react-native/helpers.js +133 -0
  8. package/dist/src/generators/react-native/index.d.ts +2 -1
  9. package/dist/src/generators/react-native/index.js +3 -3
  10. package/dist/src/generators/react-native/sanitize-react-native-block-styles.d.ts +2 -1
  11. package/dist/src/generators/react-native/sanitize-react-native-block-styles.js +8 -2
  12. package/dist/src/generators/react-native/types.d.ts +1 -0
  13. package/dist/src/generators/stencil/blocks.d.ts +3 -0
  14. package/dist/src/generators/stencil/blocks.js +108 -0
  15. package/dist/src/generators/stencil/component.js +140 -0
  16. package/dist/src/generators/stencil/helpers/collect-class-string.d.ts +2 -0
  17. package/dist/src/generators/stencil/{collect-class-string.js → helpers/collect-class-string.js} +4 -2
  18. package/dist/src/generators/stencil/helpers/index.d.ts +24 -0
  19. package/dist/src/generators/stencil/helpers/index.js +110 -0
  20. package/dist/src/generators/stencil/index.d.ts +1 -1
  21. package/dist/src/generators/stencil/index.js +1 -1
  22. package/dist/src/generators/stencil/plugins/get-code-processor-plugins.d.ts +3 -0
  23. package/dist/src/generators/stencil/plugins/get-code-processor-plugins.js +24 -0
  24. package/dist/src/generators/stencil/types.d.ts +10 -0
  25. package/dist/src/helpers/get-child-components.d.ts +2 -0
  26. package/dist/src/helpers/get-child-components.js +26 -0
  27. package/dist/src/helpers/get-typed-function.js +1 -1
  28. package/dist/src/helpers/render-imports.js +5 -1
  29. package/package.json +1 -3
  30. package/dist/src/generators/stencil/collect-class-string.d.ts +0 -2
  31. package/dist/src/generators/stencil/generate.js +0 -214
  32. /package/dist/src/generators/stencil/{generate.d.ts → component.d.ts} +0 -0
@@ -7,6 +7,7 @@ exports.componentToAngular = exports.blockToAngular = void 0;
7
7
  const html_tags_1 = require("../../constants/html_tags");
8
8
  const dedent_1 = require("../../helpers/dedent");
9
9
  const fast_clone_1 = require("../../helpers/fast-clone");
10
+ const get_child_components_1 = require("../../helpers/get-child-components");
10
11
  const get_components_used_1 = require("../../helpers/get-components-used");
11
12
  const get_custom_imports_1 = require("../../helpers/get-custom-imports");
12
13
  const get_prop_functions_1 = require("../../helpers/get-prop-functions");
@@ -174,7 +175,8 @@ const stringifyBinding = (node, options, blockOptions) => ([key, binding]) => {
174
175
  // TODO: proper babel transform to replace. Util for this
175
176
  if (keyToUse.startsWith('on')) {
176
177
  const { event, value } = processEventBinding(keyToUse, code, node.name, cusArgs[0]);
177
- return ` (${event})="${value}"`;
178
+ // Angular events are all lowerCased
179
+ return ` (${event.toLowerCase()})="${value}"`;
178
180
  }
179
181
  else if (keyToUse === 'class') {
180
182
  return ` [class]="${code}" `;
@@ -638,15 +640,8 @@ const componentToAngular = (userOptions = {}) => ({ component: _component }) =>
638
640
  json = (0, plugins_1.runPreJsonPlugins)({ json, plugins: options.plugins });
639
641
  }
640
642
  const [forwardProp, hasPropRef] = (0, get_props_ref_1.getPropsRef)(json, true);
641
- const childComponents = [json.name]; // a component can be recursively used in itself
642
643
  const propsTypeRef = json.propsTypeRef !== 'any' ? json.propsTypeRef : undefined;
643
- json.imports.forEach(({ imports }) => {
644
- Object.keys(imports).forEach((key) => {
645
- if (imports[key] === 'default') {
646
- childComponents.push(key);
647
- }
648
- });
649
- });
644
+ const childComponents = (0, get_child_components_1.getChildComponents)(json);
650
645
  const customImports = (0, get_custom_imports_1.getCustomImports)(json);
651
646
  const { exports: localExports = {} } = json;
652
647
  const localExportVars = Object.keys(localExports)
@@ -342,7 +342,7 @@ const _componentToReact = (json, options, isSubComponent = false) => {
342
342
  // NOTE: `collectReactNativeStyles` must run before style generation in the component generation body, as it has
343
343
  // side effects that delete styles bindings from the JSON.
344
344
  const reactNativeStyles = options.stylesType === 'react-native' && componentHasStyles
345
- ? (0, react_native_1.collectReactNativeStyles)(json)
345
+ ? (0, react_native_1.collectReactNativeStyles)(json, options)
346
346
  : undefined;
347
347
  const propType = json.propsTypeRef || 'any';
348
348
  const componentArgs = [`props${options.typescript ? `:${propType}` : ''}`, options.forwardRef]
@@ -5,6 +5,7 @@ export interface ToReactOptions extends BaseTranspilerOptions {
5
5
  format?: 'lite' | 'safe';
6
6
  type: 'dom' | 'native' | 'taro';
7
7
  preact?: boolean;
8
+ sanitizeReactNative?: boolean;
8
9
  rsc?: boolean;
9
10
  forwardRef?: string;
10
11
  experimental?: any;
@@ -0,0 +1 @@
1
+ export declare function extractCssVarDefaultValue(value: string): string;
@@ -0,0 +1,15 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.extractCssVarDefaultValue = void 0;
4
+ function extractCssVarDefaultValue(value) {
5
+ // Regular expression to find var() expressions
6
+ const varRegex = /var\(--[^,]+?,\s*([^)]+)\)/;
7
+ // Function to replace var() with its fallback
8
+ let newValue = value;
9
+ let match;
10
+ while ((match = newValue.match(varRegex))) {
11
+ newValue = newValue.replace(match[0], match[1].trim());
12
+ }
13
+ return newValue;
14
+ }
15
+ exports.extractCssVarDefaultValue = extractCssVarDefaultValue;
@@ -0,0 +1,3 @@
1
+ type Styles = Record<string, string | number>;
2
+ export declare function cleanReactNativeBlockStyles(styles: Styles): Styles;
3
+ export {};
@@ -0,0 +1,133 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.cleanReactNativeBlockStyles = void 0;
4
+ const extract_css_var_default_value_1 = require("./extract-css-var-default-value");
5
+ const lengthPattern = /^-?\d*\.?\d+(px|%)?$/;
6
+ const pixelPattern = /^-?\d*\.?\d+(px)?$/;
7
+ const numberPattern = /^-?\d*\.?\d+$/;
8
+ const colorPattern = /^(#[0-9A-Fa-f]{3,8}|(rgb|hsl)a?\(.*\)|[a-zA-Z]+)$/;
9
+ // List of unsupported properties in React Native
10
+ const unsupportedProps = [
11
+ 'textShadow',
12
+ 'boxShadow',
13
+ 'transition',
14
+ 'cursor',
15
+ 'filter',
16
+ 'overflowX',
17
+ 'overflowY',
18
+ 'animation',
19
+ 'backgroundImage',
20
+ 'backgroundPosition',
21
+ 'backgroundSize',
22
+ 'backgroundRepeat',
23
+ 'whiteSpace',
24
+ ];
25
+ // Ensure CSS property value is valid for React Native
26
+ function validateReactNativeCssProperty(key, value) {
27
+ const cssProperties = {
28
+ width: (value) => lengthPattern.test(value),
29
+ height: (value) => lengthPattern.test(value),
30
+ backgroundColor: (value) => pixelPattern.test(value) || /^#[0-9A-Fa-f]{6}/.test(value),
31
+ minWidth: (value) => lengthPattern.test(value) || value === 'auto',
32
+ maxWidth: (value) => lengthPattern.test(value) || value === 'auto',
33
+ minHeight: (value) => lengthPattern.test(value) || value === 'auto',
34
+ maxHeight: (value) => lengthPattern.test(value) || value === 'auto',
35
+ aspectRatio: (value) => numberPattern.test(value) || /^\d+\/\d+$/.test(value),
36
+ // Flexbox Properties
37
+ flex: (value) => numberPattern.test(value),
38
+ flexBasis: (value) => lengthPattern.test(value) || value === 'auto',
39
+ flexDirection: (value) => ['row', 'row-reverse', 'column', 'column-reverse'].includes(value),
40
+ flexGrow: (value) => numberPattern.test(value),
41
+ flexShrink: (value) => numberPattern.test(value),
42
+ flexWrap: (value) => ['wrap', 'nowrap', 'wrap-reverse'].includes(value),
43
+ // Alignment Properties
44
+ alignContent: (value) => ['flex-start', 'flex-end', 'center', 'stretch', 'space-between', 'space-around'].includes(value),
45
+ alignItems: (value) => ['flex-start', 'flex-end', 'center', 'stretch', 'baseline'].includes(value),
46
+ alignSelf: (value) => ['auto', 'flex-start', 'flex-end', 'center', 'stretch', 'baseline'].includes(value),
47
+ justifyContent: (value) => [
48
+ 'flex-start',
49
+ 'flex-end',
50
+ 'center',
51
+ 'space-between',
52
+ 'space-around',
53
+ 'space-evenly',
54
+ ].includes(value),
55
+ // Text Properties
56
+ color: (value) => colorPattern.test(value),
57
+ fontFamily: () => true, // Any string is valid
58
+ fontSize: (value) => pixelPattern.test(value),
59
+ fontStyle: (value) => ['normal', 'italic'].includes(value),
60
+ fontWeight: (value) => ['normal', 'bold', '100', '200', '300', '400', '500', '600', '700', '800', '900'].includes(value),
61
+ display: (value) => ['none', 'flex'].includes(value),
62
+ };
63
+ // If the property is not explicitly defined, consider it valid
64
+ if (!cssProperties[key])
65
+ return true;
66
+ // Convert number to string for validation
67
+ const stringValue = typeof value === 'number' ? value.toString() : value;
68
+ return cssProperties[key](stringValue);
69
+ }
70
+ // Clean up shorthand and unsupported styles for React Native
71
+ function cleanReactNativeBlockStyles(styles) {
72
+ return Object.entries(styles).reduce((acc, [key, value]) => {
73
+ var _a;
74
+ // Remove unsupported properties
75
+ if (unsupportedProps.includes(key))
76
+ return acc;
77
+ // Handle CSS variables
78
+ if (typeof value === 'string' && value.includes('var(')) {
79
+ value = (_a = (0, extract_css_var_default_value_1.extractCssVarDefaultValue)(value)) !== null && _a !== void 0 ? _a : value;
80
+ }
81
+ // Parse pixel units
82
+ if (typeof value === 'string') {
83
+ const pixelMatch = value.match(/^(-?\d+(\.\d+)?)px$/);
84
+ if (pixelMatch)
85
+ value = parseFloat(pixelMatch[1]);
86
+ }
87
+ // Handle shorthand properties
88
+ if (key === 'margin' || key === 'padding') {
89
+ return { ...acc, ...expandShorthand(key, value) };
90
+ }
91
+ // Convert 'background' to 'backgroundColor'
92
+ if (key === 'background' && typeof value === 'string') {
93
+ acc.backgroundColor = value;
94
+ return { ...acc, backgroundColor: value };
95
+ }
96
+ // Handle borderRadius
97
+ if (key === 'borderRadius' && typeof value === 'string') {
98
+ return { ...acc, ...expandBorderRadius(value) };
99
+ }
100
+ // Handle invalid display values
101
+ if (key === 'display' && value !== 'flex' && value !== 'none') {
102
+ return acc;
103
+ }
104
+ // Validate and add the property
105
+ if (validateReactNativeCssProperty(key, value)) {
106
+ acc[key] = value;
107
+ }
108
+ return acc;
109
+ }, {});
110
+ }
111
+ exports.cleanReactNativeBlockStyles = cleanReactNativeBlockStyles;
112
+ function expandShorthand(property, value) {
113
+ if (typeof value !== 'string')
114
+ return { [property]: value };
115
+ const values = value.split(' ').map((v) => parseFloat(v) || 0);
116
+ const [top, right = top, bottom = top, left = right] = values;
117
+ return {
118
+ [`${property}Top`]: top,
119
+ [`${property}Right`]: right,
120
+ [`${property}Bottom`]: bottom,
121
+ [`${property}Left`]: left,
122
+ };
123
+ }
124
+ function expandBorderRadius(value) {
125
+ const values = value.split(' ').map((v) => parseInt(v, 10));
126
+ const [topLeft, topRight = topLeft, bottomRight = topLeft, bottomLeft = topRight] = values;
127
+ return {
128
+ borderTopLeftRadius: topLeft,
129
+ borderTopRightRadius: topRight,
130
+ borderBottomRightRadius: bottomRight,
131
+ borderBottomLeftRadius: bottomLeft,
132
+ };
133
+ }
@@ -2,5 +2,6 @@ import { ToReactNativeOptions } from '../../generators/react-native/types';
2
2
  import { ClassStyleMap } from '../../helpers/styles/helpers';
3
3
  import { MitosisComponent } from '../../types/mitosis-component';
4
4
  import { TranspilerGenerator } from '../../types/transpiler';
5
- export declare const collectReactNativeStyles: (json: MitosisComponent) => ClassStyleMap;
5
+ import { ToReactOptions } from '../react';
6
+ export declare const collectReactNativeStyles: (json: MitosisComponent, options: ToReactOptions) => ClassStyleMap;
6
7
  export declare const componentToReactNative: TranspilerGenerator<Partial<ToReactNativeOptions>>;
@@ -25,7 +25,7 @@ const sanitizeStyle = (obj) => (key, value) => {
25
25
  return;
26
26
  }
27
27
  };
28
- const collectReactNativeStyles = (json) => {
28
+ const collectReactNativeStyles = (json, options) => {
29
29
  const styleMap = {};
30
30
  const componentIndexes = {};
31
31
  const getStyleSheetName = (item) => {
@@ -45,7 +45,7 @@ const collectReactNativeStyles = (json) => {
45
45
  // Style properties like `"20px"` need to be numbers like `20` for react native
46
46
  for (const key in cssValue) {
47
47
  sanitizeStyle(cssValue)(key, cssValue[key]);
48
- cssValue = (0, sanitize_react_native_block_styles_1.sanitizeReactNativeBlockStyles)(cssValue);
48
+ cssValue = (0, sanitize_react_native_block_styles_1.sanitizeReactNativeBlockStyles)(cssValue, options);
49
49
  }
50
50
  }
51
51
  try {
@@ -54,7 +54,7 @@ const collectReactNativeStyles = (json) => {
54
54
  // Style properties like `"20px"` need to be numbers like `20` for react native
55
55
  for (const key in styleValue) {
56
56
  sanitizeStyle(styleValue)(key, styleValue[key]);
57
- styleValue = (0, sanitize_react_native_block_styles_1.sanitizeReactNativeBlockStyles)(styleValue);
57
+ styleValue = (0, sanitize_react_native_block_styles_1.sanitizeReactNativeBlockStyles)(styleValue, options);
58
58
  }
59
59
  item.bindings.style.code = json5_1.default.stringify(styleValue);
60
60
  }
@@ -1,3 +1,4 @@
1
+ import { ToReactOptions } from '../react/types';
1
2
  type Styles = Record<string, string | number>;
2
- export declare const sanitizeReactNativeBlockStyles: (styles: Styles) => Styles;
3
+ export declare const sanitizeReactNativeBlockStyles: (styles: Styles, options: ToReactOptions) => Styles;
3
4
  export {};
@@ -1,6 +1,7 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.sanitizeReactNativeBlockStyles = void 0;
4
+ const helpers_1 = require("./helpers");
4
5
  const propertiesThatMustBeNumber = new Set(['lineHeight']);
5
6
  const displayValues = new Set(['flex', 'none']);
6
7
  const normalizeNumber = (value) => {
@@ -15,10 +16,15 @@ const normalizeNumber = (value) => {
15
16
  return value;
16
17
  }
17
18
  };
18
- const sanitizeReactNativeBlockStyles = (styles) => {
19
+ const sanitizeReactNativeBlockStyles = (styles, options) => {
20
+ if (options.sanitizeReactNative) {
21
+ return (0, helpers_1.cleanReactNativeBlockStyles)(styles);
22
+ }
19
23
  return Object.keys(styles).reduce((acc, key) => {
20
24
  const propertyValue = styles[key];
21
- if (key === 'display' && !displayValues.has(propertyValue)) {
25
+ if (typeof propertyValue === 'string' &&
26
+ key === 'display' &&
27
+ !displayValues.has(propertyValue)) {
22
28
  console.warn(`Style value for key "display" must be "flex" or "none" but had ${propertyValue}`);
23
29
  return acc;
24
30
  }
@@ -1,5 +1,6 @@
1
1
  import { BaseTranspilerOptions } from '../../types/transpiler';
2
2
  export interface ToReactNativeOptions extends BaseTranspilerOptions {
3
+ sanitizeReactNative?: boolean;
3
4
  stylesType: 'emotion' | 'react-native' | 'twrnc' | 'native-wind';
4
5
  stateType: 'useState' | 'mobx' | 'valtio' | 'solid' | 'builder';
5
6
  }
@@ -0,0 +1,3 @@
1
+ import { ToStencilOptions } from '../../generators/stencil/types';
2
+ import { MitosisNode } from '../../types/mitosis-node';
3
+ export declare const blockToStencil: (json: MitosisNode, options: ToStencilOptions | undefined, insideJsx: boolean, childComponents: string[]) => string;
@@ -0,0 +1,108 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.blockToStencil = void 0;
4
+ const html_tags_1 = require("../../constants/html_tags");
5
+ const helpers_1 = require("../../generators/stencil/helpers");
6
+ const collect_class_string_1 = require("../../generators/stencil/helpers/collect-class-string");
7
+ const filter_empty_text_nodes_1 = require("../../helpers/filter-empty-text-nodes");
8
+ const for_1 = require("../../helpers/nodes/for");
9
+ const mitosis_node_1 = require("../../types/mitosis-node");
10
+ const blockToStencil = (json, options = {}, insideJsx, childComponents) => {
11
+ var _a, _b, _c, _d, _e, _f;
12
+ let blockName = childComponents.find((impName) => impName === json.name)
13
+ ? (0, helpers_1.getTagName)(json.name, options)
14
+ : json.name;
15
+ if (json.properties._text) {
16
+ return json.properties._text;
17
+ }
18
+ if ((_a = json.bindings._text) === null || _a === void 0 ? void 0 : _a.code) {
19
+ if (((_b = json.bindings._text) === null || _b === void 0 ? void 0 : _b.code) === 'this.children') {
20
+ // Replace this.children with default <slot>
21
+ return '<slot></slot>';
22
+ }
23
+ let code = json.bindings._text.code;
24
+ if (insideJsx) {
25
+ return `{${code}}`;
26
+ }
27
+ return code;
28
+ }
29
+ if ((0, mitosis_node_1.checkIsForNode)(json) && ((_c = json.bindings.each) === null || _c === void 0 ? void 0 : _c.code)) {
30
+ const wrap = json.children.length !== 1;
31
+ const forArgs = (0, for_1.getForArguments)(json).join(', ');
32
+ const expression = `${(_d = json.bindings.each) === null || _d === void 0 ? void 0 : _d.code}?.map((${forArgs}) => (
33
+ ${wrap ? '<Fragment>' : ''}
34
+ ${json.children
35
+ .filter(filter_empty_text_nodes_1.filterEmptyTextNodes)
36
+ .map((item) => (0, exports.blockToStencil)(item, options, wrap, childComponents))
37
+ .join('\n')}
38
+ ${wrap ? '</Fragment>' : ''}
39
+ ))`;
40
+ if (insideJsx) {
41
+ return `{${expression}}`;
42
+ }
43
+ else {
44
+ return expression;
45
+ }
46
+ }
47
+ else if (blockName === 'Show' && ((_e = json.bindings.when) === null || _e === void 0 ? void 0 : _e.code)) {
48
+ const wrap = json.children.length !== 1;
49
+ const expression = `${(_f = json.bindings.when) === null || _f === void 0 ? void 0 : _f.code} ? (
50
+ ${wrap ? '<Fragment>' : ''}
51
+ ${json.children
52
+ .filter(filter_empty_text_nodes_1.filterEmptyTextNodes)
53
+ .map((item) => (0, exports.blockToStencil)(item, options, wrap, childComponents))
54
+ .join('\n')}
55
+ ${wrap ? '</Fragment>' : ''}
56
+ ) : ${!json.meta.else
57
+ ? 'null'
58
+ : `(${(0, exports.blockToStencil)(json.meta.else, options, false, childComponents)})`}`;
59
+ if (insideJsx) {
60
+ return `{${expression}}`;
61
+ }
62
+ else {
63
+ return expression;
64
+ }
65
+ }
66
+ else if (blockName === 'Slot') {
67
+ blockName = 'slot';
68
+ }
69
+ let str = '';
70
+ str += `<${blockName} `;
71
+ const classString = (0, collect_class_string_1.collectClassString)(json);
72
+ if (classString) {
73
+ str += ` class=${classString} `;
74
+ }
75
+ for (const key in json.properties) {
76
+ const value = json.properties[key];
77
+ str += ` ${key}="${value}" `;
78
+ }
79
+ for (const key in json.bindings) {
80
+ const { code, arguments: cusArgs = [], type } = json.bindings[key];
81
+ if (type === 'spread') {
82
+ str += ` {...(${code})} `;
83
+ }
84
+ else if (key === 'ref') {
85
+ // TODO: Add correct type here
86
+ str += ` ref={(el) => ${code.startsWith('this.') ? code : `this.${code}`} = el} `;
87
+ }
88
+ else if ((0, helpers_1.isEvent)(key)) {
89
+ const useKey = key === 'onChange' && blockName === 'input' ? 'onInput' : key;
90
+ str += ` ${useKey}={(${cusArgs.join(',')}) => ${code}} `;
91
+ }
92
+ else {
93
+ str += ` ${key}={${code}} `;
94
+ }
95
+ }
96
+ if (html_tags_1.SELF_CLOSING_HTML_TAGS.has(blockName)) {
97
+ return str + ' />';
98
+ }
99
+ str += '>';
100
+ if (json.children) {
101
+ str += json.children
102
+ .map((item) => (0, exports.blockToStencil)(item, options, true, childComponents))
103
+ .join('\n');
104
+ }
105
+ str += `</${blockName}>`;
106
+ return str;
107
+ };
108
+ exports.blockToStencil = blockToStencil;
@@ -0,0 +1,140 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.componentToStencil = void 0;
4
+ const on_mount_1 = require("../../generators/helpers/on-mount");
5
+ const blocks_1 = require("../../generators/stencil/blocks");
6
+ const helpers_1 = require("../../generators/stencil/helpers");
7
+ const get_code_processor_plugins_1 = require("../../generators/stencil/plugins/get-code-processor-plugins");
8
+ const dedent_1 = require("../../helpers/dedent");
9
+ const fast_clone_1 = require("../../helpers/fast-clone");
10
+ const get_child_components_1 = require("../../helpers/get-child-components");
11
+ const get_props_1 = require("../../helpers/get-props");
12
+ const get_state_object_string_1 = require("../../helpers/get-state-object-string");
13
+ const indent_1 = require("../../helpers/indent");
14
+ const map_refs_1 = require("../../helpers/map-refs");
15
+ const merge_options_1 = require("../../helpers/merge-options");
16
+ const strip_meta_properties_1 = require("../../helpers/strip-meta-properties");
17
+ const collect_css_1 = require("../../helpers/styles/collect-css");
18
+ const plugins_1 = require("../../modules/plugins");
19
+ const standalone_1 = require("prettier/standalone");
20
+ const componentToStencil = (_options = {
21
+ typescript: true, // Stencil is uses .tsx always
22
+ }) => ({ component }) => {
23
+ var _a, _b, _c, _d, _e;
24
+ let json = (0, fast_clone_1.fastClone)(component);
25
+ const options = (0, merge_options_1.initializeOptions)({
26
+ target: 'stencil',
27
+ component,
28
+ defaults: _options,
29
+ });
30
+ if (options.plugins) {
31
+ json = (0, plugins_1.runPreJsonPlugins)({ json, plugins: options.plugins });
32
+ }
33
+ (0, map_refs_1.mapRefs)(json, (refName) => `this.${refName}`);
34
+ let css = (0, collect_css_1.collectCss)(json);
35
+ const props = Array.from((0, get_props_1.getProps)(json));
36
+ const events = props.filter((prop) => (0, helpers_1.isEvent)(prop));
37
+ const defaultProps = json.defaultProps;
38
+ const childComponents = (0, get_child_components_1.getChildComponents)(json);
39
+ const processBindingOptions = { events };
40
+ options.plugins = (0, get_code_processor_plugins_1.getCodeProcessorPlugins)(options, processBindingOptions);
41
+ if (options.plugins) {
42
+ json = (0, plugins_1.runPostJsonPlugins)({ json, plugins: options.plugins });
43
+ }
44
+ (0, strip_meta_properties_1.stripMetaProperties)(json);
45
+ const dataString = (0, get_state_object_string_1.getStateObjectStringFromComponent)(json, {
46
+ format: 'class',
47
+ data: true,
48
+ functions: false,
49
+ getters: false,
50
+ keyPrefix: '@State() ',
51
+ });
52
+ const methodsString = (0, get_state_object_string_1.getStateObjectStringFromComponent)(json, {
53
+ format: 'class',
54
+ data: false,
55
+ functions: true,
56
+ getters: true,
57
+ });
58
+ const refs = json.refs
59
+ ? Object.entries(json.refs)
60
+ .map(([key, value]) => {
61
+ var _a;
62
+ return `private ${key}!: ${(_a = value.typeParameter) !== null && _a !== void 0 ? _a : 'HTMLElement'}`;
63
+ })
64
+ .join('\n')
65
+ : '';
66
+ const wrap = (0, helpers_1.needsWrap)(json.children);
67
+ if (options.prettier !== false) {
68
+ try {
69
+ css = (0, standalone_1.format)(css, {
70
+ parser: 'css',
71
+ plugins: [require('prettier/parser-postcss')],
72
+ });
73
+ }
74
+ catch (err) {
75
+ console.warn('Could not format css', err);
76
+ }
77
+ }
78
+ let tagName = (0, helpers_1.getTagName)(json.name, options);
79
+ if ((_a = json.meta.useMetadata) === null || _a === void 0 ? void 0 : _a.tagName) {
80
+ // Deprecated option, we shouldn't use this, instead change the name of your Mitosis component
81
+ tagName = (_b = json.meta.useMetadata) === null || _b === void 0 ? void 0 : _b.tagName;
82
+ }
83
+ const coreImports = (0, helpers_1.getStencilCoreImportsAsString)(wrap, events, props, dataString);
84
+ let str = (0, dedent_1.dedent) `
85
+ ${(0, helpers_1.getImports)(json, options, childComponents)}
86
+
87
+ import { ${coreImports} } from '@stencil/core';
88
+
89
+ ${json.types ? json.types.join('\n') : ''}
90
+
91
+ @Component({
92
+ tag: '${tagName}',
93
+ ${((_c = json.meta.useMetadata) === null || _c === void 0 ? void 0 : _c.isAttachedToShadowDom) ? 'shadow: true,' : ''}
94
+ ${css.length
95
+ ? `styles: \`
96
+ ${(0, indent_1.indent)(css, 8)}\`,`
97
+ : ''}
98
+ })
99
+ export class ${json.name} {
100
+ ${refs}
101
+ ${(0, helpers_1.getPropsAsCode)(props, defaultProps, json.propsTypeRef)}
102
+ ${dataString}
103
+ ${methodsString}
104
+
105
+ ${!json.hooks.onMount.length
106
+ ? ''
107
+ : `componentDidLoad() { ${(0, on_mount_1.stringifySingleScopeOnMount)(json)} }`}
108
+ ${!((_d = json.hooks.onUnMount) === null || _d === void 0 ? void 0 : _d.code)
109
+ ? ''
110
+ : `disconnectedCallback() { ${json.hooks.onUnMount.code} }`}
111
+ ${!((_e = json.hooks.onUpdate) === null || _e === void 0 ? void 0 : _e.length)
112
+ ? ''
113
+ : `componentDidUpdate() { ${json.hooks.onUpdate.map((hook) => hook.code).join('\n')} }`}
114
+
115
+ render() {
116
+ return (${wrap ? '<Host>' : ''}
117
+
118
+ ${json.children
119
+ .map((item) => (0, blocks_1.blockToStencil)(item, options, true, childComponents))
120
+ .join('\n')}
121
+
122
+ ${wrap ? '</Host>' : ''})
123
+ }
124
+ }
125
+ `;
126
+ if (options.plugins) {
127
+ str = (0, plugins_1.runPreCodePlugins)({ json, code: str, plugins: options.plugins });
128
+ }
129
+ if (options.prettier !== false) {
130
+ str = (0, standalone_1.format)(str, {
131
+ parser: 'typescript',
132
+ plugins: [require('prettier/parser-typescript')],
133
+ });
134
+ }
135
+ if (options.plugins) {
136
+ str = (0, plugins_1.runPostCodePlugins)({ json, code: str, plugins: options.plugins });
137
+ }
138
+ return str;
139
+ };
140
+ exports.componentToStencil = componentToStencil;
@@ -0,0 +1,2 @@
1
+ import { MitosisNode } from '../../../types/mitosis-node';
2
+ export declare const collectClassString: (json: MitosisNode) => string | null;
@@ -1,9 +1,11 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.collectClassString = void 0;
4
+ const bindingOpenChar = '{';
5
+ const bindingCloseChar = '}';
4
6
  // This should really be a preprocessor mapping the `class` attribute binding based on what other values have
5
7
  // to make this more pluggable
6
- function collectClassString(json, bindingOpenChar = '{', bindingCloseChar = '}') {
8
+ const collectClassString = (json) => {
7
9
  var _a, _b;
8
10
  const staticClasses = [];
9
11
  if (json.properties.class) {
@@ -37,5 +39,5 @@ function collectClassString(json, bindingOpenChar = '{', bindingCloseChar = '}')
37
39
  return `${bindingOpenChar}"${staticClassesString} " + ${dynamicClassesString}${bindingCloseChar}`;
38
40
  }
39
41
  return null;
40
- }
42
+ };
41
43
  exports.collectClassString = collectClassString;
@@ -0,0 +1,24 @@
1
+ import { ToStencilOptions } from '../../../generators/stencil/types';
2
+ import { MitosisComponent, MitosisState } from '../../../types/mitosis-component';
3
+ import { MitosisNode } from '../../../types/mitosis-node';
4
+ export declare const isEvent: (key: string) => boolean;
5
+ export type ProcessBindingOptions = {
6
+ events: string[];
7
+ };
8
+ export declare const processBinding: (code: string, { events }: ProcessBindingOptions) => string;
9
+ export declare const getTagName: (name: string, { prefix }: ToStencilOptions) => string;
10
+ export declare const getPropsAsCode: (props: string[], defaultProps?: MitosisState | undefined, propsTypeRef?: string) => string;
11
+ /**
12
+ * Check for root element if it needs a wrapping <Host>
13
+ * @param children
14
+ */
15
+ export declare const needsWrap: (children: MitosisNode[]) => boolean;
16
+ /**
17
+ * Dynamically creates all imports from `@stencil/core`
18
+ * @param wrap
19
+ * @param events
20
+ * @param props
21
+ * @param dataString
22
+ */
23
+ export declare const getStencilCoreImportsAsString: (wrap: boolean, events: string[], props: string[], dataString: string) => string;
24
+ export declare const getImports: (json: MitosisComponent, options: ToStencilOptions, childComponents: string[]) => string;
@@ -0,0 +1,110 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.getImports = exports.getStencilCoreImportsAsString = exports.needsWrap = exports.getPropsAsCode = exports.getTagName = exports.processBinding = exports.isEvent = void 0;
4
+ const dash_case_1 = require("../../../helpers/dash-case");
5
+ const render_imports_1 = require("../../../helpers/render-imports");
6
+ const strip_state_and_props_refs_1 = require("../../../helpers/strip-state-and-props-refs");
7
+ const isEvent = (key) => key.startsWith('on');
8
+ exports.isEvent = isEvent;
9
+ /**
10
+ * We need to "emit" events those can be on multiple places, so we do it as post step
11
+ */
12
+ const appendEmits = (str, events) => {
13
+ let code = str;
14
+ if (events.length) {
15
+ for (const event of events) {
16
+ code = code.replaceAll(`props.${event}(`, `props.${event}.emit(`);
17
+ }
18
+ }
19
+ return code;
20
+ };
21
+ const processBinding = (code, { events }) => {
22
+ return (0, strip_state_and_props_refs_1.stripStateAndPropsRefs)(appendEmits(code, events), { replaceWith: 'this.' });
23
+ };
24
+ exports.processBinding = processBinding;
25
+ const getTagName = (name, { prefix }) => {
26
+ const dashName = (0, dash_case_1.dashCase)(name);
27
+ if (prefix) {
28
+ const dashPrefix = prefix.endsWith('-') ? prefix : `${prefix}-`;
29
+ if (!dashName.startsWith(dashPrefix)) {
30
+ return `${dashPrefix}${dashName}`;
31
+ }
32
+ }
33
+ return dashName;
34
+ };
35
+ exports.getTagName = getTagName;
36
+ const getPropsAsCode = (props, defaultProps, propsTypeRef) => {
37
+ return props
38
+ .map((item) => {
39
+ var _a;
40
+ const defaultProp = defaultProps ? (_a = defaultProps[item]) === null || _a === void 0 ? void 0 : _a.code : undefined;
41
+ const defaultPropString = defaultProp ? ` = ${defaultProp}` : '';
42
+ if ((0, exports.isEvent)(item)) {
43
+ return `@Event() ${item}: any${defaultPropString}`;
44
+ }
45
+ const type = propsTypeRef &&
46
+ propsTypeRef !== 'any' &&
47
+ propsTypeRef !== 'unknown' &&
48
+ propsTypeRef !== 'never'
49
+ ? `${propsTypeRef}["${item}"]`
50
+ : 'any';
51
+ return `@Prop() ${item}: ${type}${defaultPropString}`;
52
+ })
53
+ .join(';\n');
54
+ };
55
+ exports.getPropsAsCode = getPropsAsCode;
56
+ /**
57
+ * Check for root element if it needs a wrapping <Host>
58
+ * @param children
59
+ */
60
+ const needsWrap = (children) => {
61
+ if (children.length !== 1) {
62
+ return true;
63
+ }
64
+ else if (children.length === 1) {
65
+ const firstChild = children.at(0);
66
+ if ((firstChild === null || firstChild === void 0 ? void 0 : firstChild.name) === 'Show' || (firstChild === null || firstChild === void 0 ? void 0 : firstChild.name) === 'For') {
67
+ return true;
68
+ }
69
+ }
70
+ return false;
71
+ };
72
+ exports.needsWrap = needsWrap;
73
+ /**
74
+ * Dynamically creates all imports from `@stencil/core`
75
+ * @param wrap
76
+ * @param events
77
+ * @param props
78
+ * @param dataString
79
+ */
80
+ const getStencilCoreImportsAsString = (wrap, events, props, dataString) => {
81
+ const stencilCoreImports = {
82
+ Component: true,
83
+ h: true,
84
+ Fragment: true,
85
+ Host: wrap,
86
+ Event: events.length > 0,
87
+ Prop: props.length > 0,
88
+ State: dataString.length > 0,
89
+ };
90
+ return Object.entries(stencilCoreImports)
91
+ .map(([key, bool]) => (bool ? key : ''))
92
+ .filter((key) => !!key)
93
+ .join(', ');
94
+ };
95
+ exports.getStencilCoreImportsAsString = getStencilCoreImportsAsString;
96
+ const getImports = (json, options, childComponents) => {
97
+ return (0, render_imports_1.renderPreComponent)({
98
+ explicitImportFileExtension: options.explicitImportFileExtension,
99
+ component: json,
100
+ target: 'stencil',
101
+ importMapper: (_, theImport, importedValues) => {
102
+ const childImport = importedValues.defaultImport;
103
+ if (childImport && childComponents.includes(childImport)) {
104
+ return `import {${childImport}} from '${theImport.path}';`;
105
+ }
106
+ return undefined;
107
+ },
108
+ });
109
+ };
110
+ exports.getImports = getImports;
@@ -1 +1 @@
1
- export * from './generate';
1
+ export * from './component';
@@ -14,4 +14,4 @@ var __exportStar = (this && this.__exportStar) || function(m, exports) {
14
14
  for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
15
15
  };
16
16
  Object.defineProperty(exports, "__esModule", { value: true });
17
- __exportStar(require("./generate"), exports);
17
+ __exportStar(require("./component"), exports);
@@ -0,0 +1,3 @@
1
+ import { ProcessBindingOptions } from '../../../generators/stencil/helpers/index';
2
+ import { ToStencilOptions } from '../../../generators/stencil/types';
3
+ export declare const getCodeProcessorPlugins: (options: ToStencilOptions, processBindingOptions: ProcessBindingOptions) => import("../../..").Plugin[];
@@ -0,0 +1,24 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.getCodeProcessorPlugins = void 0;
4
+ const index_1 = require("../../../generators/stencil/helpers/index");
5
+ const process_code_1 = require("../../../helpers/plugins/process-code");
6
+ const getCodeProcessorPlugins = (options, processBindingOptions) => {
7
+ return [
8
+ ...(options.plugins || []),
9
+ (0, process_code_1.CODE_PROCESSOR_PLUGIN)((codeType) => {
10
+ switch (codeType) {
11
+ case 'bindings':
12
+ case 'properties':
13
+ case 'hooks':
14
+ case 'hooks-deps':
15
+ case 'state':
16
+ case 'context-set':
17
+ case 'dynamic-jsx-elements':
18
+ case 'types':
19
+ return (code) => (0, index_1.processBinding)(code, processBindingOptions);
20
+ }
21
+ }),
22
+ ];
23
+ };
24
+ exports.getCodeProcessorPlugins = getCodeProcessorPlugins;
@@ -1,4 +1,14 @@
1
1
  import { BaseTranspilerOptions } from '../../types/transpiler';
2
2
  export interface ToStencilOptions extends BaseTranspilerOptions {
3
+ /**
4
+ * Add a prefix for every component like `my`.
5
+ * A Stencil component needs a prefix with a dash.
6
+ * You don't need this option if your Mitosis component includes the prefix already:
7
+ *
8
+ * Error: `export default function Button ...` -> tag: 'button'
9
+ * Success: `export default function MyButton ...` -> tag: 'my-button'
10
+ * Success: prefix="my" + `export default function Button ...` -> tag: 'my-button'
11
+ */
12
+ prefix?: string;
3
13
  }
4
14
  export type StencilMetadata = {};
@@ -0,0 +1,2 @@
1
+ import { MitosisComponent } from '../types/mitosis-component';
2
+ export declare const getChildComponents: (json: MitosisComponent) => string[];
@@ -0,0 +1,26 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.getChildComponents = void 0;
7
+ const is_mitosis_node_1 = require("../helpers/is-mitosis-node");
8
+ const legacy_1 = __importDefault(require("neotraverse/legacy"));
9
+ const getChildComponents = (json) => {
10
+ const nodes = [];
11
+ const childComponents = [json.name]; // a component can be recursively used in itself
12
+ (0, legacy_1.default)(json).forEach(function (item) {
13
+ if ((0, is_mitosis_node_1.isMitosisNode)(item)) {
14
+ nodes.push(item.name);
15
+ }
16
+ });
17
+ for (const { imports } of json.imports) {
18
+ for (const key of Object.keys(imports)) {
19
+ if (nodes.includes(key)) {
20
+ childComponents.push(key);
21
+ }
22
+ }
23
+ }
24
+ return childComponents;
25
+ };
26
+ exports.getChildComponents = getChildComponents;
@@ -15,6 +15,6 @@ const getTypedFunction = (code, typescript, typeParameter) => {
15
15
  }
16
16
  const preType = code.slice(0, firstParenthesisIndex - 1);
17
17
  const postType = code.slice(firstParenthesisIndex, code.length);
18
- return [preType, ': ', typeParameter, postType].join('');
18
+ return [preType, ': ', `ReturnType<${typeParameter}>`, postType].join('');
19
19
  };
20
20
  exports.getTypedFunction = getTypedFunction;
@@ -105,7 +105,11 @@ const renderImport = ({ theImport, target, asyncComponentImports, preserveFileEx
105
105
  }
106
106
  }
107
107
  if (importMapper) {
108
- return importMapper(component, theImport, importedValues, componentsUsed);
108
+ const importMapperResult = importMapper(component, theImport, importedValues, componentsUsed);
109
+ // If import mapper has no result we skip this
110
+ if (importMapperResult) {
111
+ return importMapperResult;
112
+ }
109
113
  }
110
114
  return importValue
111
115
  ? `import ${isTypeImport ? 'type' : ''} ${importValue} from '${path}';`
package/package.json CHANGED
@@ -22,7 +22,7 @@
22
22
  "name": "Builder.io",
23
23
  "url": "https://www.builder.io"
24
24
  },
25
- "version": "0.4.7",
25
+ "version": "0.5.1",
26
26
  "homepage": "https://github.com/BuilderIO/mitosis",
27
27
  "main": "./dist/src/index.js",
28
28
  "exports": {
@@ -96,8 +96,6 @@
96
96
  "@types/rollup__plugin-virtual": "^2.0.1",
97
97
  "concurrently": "^8.2.2",
98
98
  "fs-extra-promise": "^1.0.1",
99
- "nx": "^19.0.8",
100
- "nx-cloud": "^19.0.0",
101
99
  "rimraf": "^5.0.5",
102
100
  "rollup": "^2.70.1",
103
101
  "strip-ansi": "^6.0.1",
@@ -1,2 +0,0 @@
1
- import { MitosisNode } from '../../types/mitosis-node';
2
- export declare function collectClassString(json: MitosisNode, bindingOpenChar?: string, bindingCloseChar?: string): string | null;
@@ -1,214 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.componentToStencil = void 0;
4
- const dash_case_1 = require("../../helpers/dash-case");
5
- const dedent_1 = require("../../helpers/dedent");
6
- const fast_clone_1 = require("../../helpers/fast-clone");
7
- const filter_empty_text_nodes_1 = require("../../helpers/filter-empty-text-nodes");
8
- const get_props_1 = require("../../helpers/get-props");
9
- const get_state_object_string_1 = require("../../helpers/get-state-object-string");
10
- const indent_1 = require("../../helpers/indent");
11
- const map_refs_1 = require("../../helpers/map-refs");
12
- const merge_options_1 = require("../../helpers/merge-options");
13
- const for_1 = require("../../helpers/nodes/for");
14
- const render_imports_1 = require("../../helpers/render-imports");
15
- const strip_meta_properties_1 = require("../../helpers/strip-meta-properties");
16
- const strip_state_and_props_refs_1 = require("../../helpers/strip-state-and-props-refs");
17
- const collect_css_1 = require("../../helpers/styles/collect-css");
18
- const mitosis_node_1 = require("../../types/mitosis-node");
19
- const standalone_1 = require("prettier/standalone");
20
- const html_tags_1 = require("../../constants/html_tags");
21
- const plugins_1 = require("../../modules/plugins");
22
- const on_mount_1 = require("../helpers/on-mount");
23
- const collect_class_string_1 = require("./collect-class-string");
24
- const blockToStencil = (json, options = {}, insideJsx) => {
25
- var _a, _b, _c, _d;
26
- if (json.properties._text) {
27
- return json.properties._text;
28
- }
29
- if ((_a = json.bindings._text) === null || _a === void 0 ? void 0 : _a.code) {
30
- if (insideJsx) {
31
- return `{${processBinding(json.bindings._text.code)}}`;
32
- }
33
- return processBinding((_b = json.bindings) === null || _b === void 0 ? void 0 : _b._text.code);
34
- }
35
- if ((0, mitosis_node_1.checkIsForNode)(json)) {
36
- const wrap = json.children.length !== 1;
37
- const forArgs = (0, for_1.getForArguments)(json).join(', ');
38
- const expression = `${processBinding((_c = json.bindings.each) === null || _c === void 0 ? void 0 : _c.code)}?.map((${forArgs}) => (
39
- ${wrap ? '<>' : ''}${json.children
40
- .filter(filter_empty_text_nodes_1.filterEmptyTextNodes)
41
- .map((item) => blockToStencil(item, options, wrap))
42
- .join('\n')}${wrap ? '</>' : ''}
43
- ))`;
44
- if (insideJsx) {
45
- return `{${expression}}`;
46
- }
47
- else {
48
- return expression;
49
- }
50
- }
51
- else if (json.name === 'Show') {
52
- const wrap = json.children.length !== 1;
53
- const expression = `${processBinding((_d = json.bindings.when) === null || _d === void 0 ? void 0 : _d.code)} ? (
54
- ${wrap ? '<>' : ''}${json.children
55
- .filter(filter_empty_text_nodes_1.filterEmptyTextNodes)
56
- .map((item) => blockToStencil(item, options, wrap))
57
- .join('\n')}${wrap ? '</>' : ''}
58
- ) : ${!json.meta.else ? 'null' : blockToStencil(json.meta.else, options, false)}`;
59
- if (insideJsx) {
60
- return `{${expression}}`;
61
- }
62
- else {
63
- return expression;
64
- }
65
- }
66
- let str = '';
67
- str += `<${json.name} `;
68
- const classString = (0, collect_class_string_1.collectClassString)(json);
69
- if (classString) {
70
- str += ` class=${classString} `;
71
- }
72
- for (const key in json.properties) {
73
- const value = json.properties[key];
74
- str += ` ${key}="${value}" `;
75
- }
76
- for (const key in json.bindings) {
77
- const { code, arguments: cusArgs = ['event'], type } = json.bindings[key];
78
- if (type === 'spread') {
79
- str += ` {...(${code})} `;
80
- }
81
- else if (key === 'ref') {
82
- str += ` ref={(el) => this.${code} = el} `;
83
- }
84
- else if (key.startsWith('on')) {
85
- const useKey = key === 'onChange' && json.name === 'input' ? 'onInput' : key;
86
- str += ` ${useKey}={${cusArgs.join(',')} => ${processBinding(code)}} `;
87
- }
88
- else {
89
- str += ` ${key}={${processBinding(code)}} `;
90
- }
91
- }
92
- if (html_tags_1.SELF_CLOSING_HTML_TAGS.has(json.name)) {
93
- return str + ' />';
94
- }
95
- str += '>';
96
- if (json.children) {
97
- str += json.children.map((item) => blockToStencil(item, options, true)).join('\n');
98
- }
99
- str += `</${json.name}>`;
100
- return str;
101
- };
102
- function processBinding(code) {
103
- return (0, strip_state_and_props_refs_1.stripStateAndPropsRefs)(code, { replaceWith: 'this.' });
104
- }
105
- const componentToStencil = (_options = {}) => ({ component }) => {
106
- var _a, _b, _c;
107
- const options = (0, merge_options_1.initializeOptions)({ target: 'stencil', component, defaults: _options });
108
- let json = (0, fast_clone_1.fastClone)(component);
109
- if (options.plugins) {
110
- json = (0, plugins_1.runPreJsonPlugins)({ json, plugins: options.plugins });
111
- }
112
- const props = (0, get_props_1.getProps)(component);
113
- let css = (0, collect_css_1.collectCss)(json);
114
- (0, map_refs_1.mapRefs)(component, (refName) => `this.${refName}`);
115
- if (options.plugins) {
116
- json = (0, plugins_1.runPostJsonPlugins)({ json, plugins: options.plugins });
117
- }
118
- (0, strip_meta_properties_1.stripMetaProperties)(json);
119
- const dataString = (0, get_state_object_string_1.getStateObjectStringFromComponent)(json, {
120
- format: 'class',
121
- data: true,
122
- functions: false,
123
- getters: false,
124
- keyPrefix: '@State() ',
125
- valueMapper: (code) => processBinding(code),
126
- });
127
- const methodsString = (0, get_state_object_string_1.getStateObjectStringFromComponent)(json, {
128
- format: 'class',
129
- data: false,
130
- functions: true,
131
- getters: true,
132
- valueMapper: (code) => processBinding(code),
133
- });
134
- const wrap = json.children.length !== 1;
135
- if (options.prettier !== false) {
136
- try {
137
- css = (0, standalone_1.format)(css, {
138
- parser: 'css',
139
- plugins: [require('prettier/parser-postcss')],
140
- });
141
- }
142
- catch (err) {
143
- console.warn('Could not format css', err);
144
- }
145
- }
146
- let str = (0, dedent_1.dedent) `
147
- ${(0, render_imports_1.renderPreComponent)({
148
- explicitImportFileExtension: options.explicitImportFileExtension,
149
- component: json,
150
- target: 'stencil',
151
- })}
152
-
153
- import { Component, Prop, h, State, Fragment } from '@stencil/core';
154
-
155
- @Component({
156
- tag: '${
157
- /**
158
- * You can set the tagName in your Mitosis component as
159
- *
160
- * useMetadata({
161
- * tagName: 'my-tag
162
- * })
163
- *
164
- * export default function ...
165
- */
166
- ((_a = json.meta.useMetadata) === null || _a === void 0 ? void 0 : _a.tagName) || (0, dash_case_1.dashCase)(json.name)}',
167
- ${css.length
168
- ? `styles: \`
169
- ${(0, indent_1.indent)(css, 8)}\`,`
170
- : ''}
171
- })
172
- export default class ${json.name} {
173
-
174
- ${Array.from(props)
175
- .map((item) => `@Prop() ${item}: any`)
176
- .join('\n')}
177
-
178
- ${dataString}
179
- ${methodsString}
180
-
181
- ${!json.hooks.onMount.length
182
- ? ''
183
- : `componentDidLoad() { ${processBinding((0, on_mount_1.stringifySingleScopeOnMount)(json))} }`}
184
- ${!((_b = json.hooks.onUnMount) === null || _b === void 0 ? void 0 : _b.code)
185
- ? ''
186
- : `disconnectedCallback() { ${processBinding(json.hooks.onUnMount.code)} }`}
187
- ${!((_c = json.hooks.onUpdate) === null || _c === void 0 ? void 0 : _c.length)
188
- ? ''
189
- : json.hooks.onUpdate.map((hook) => `componentDidUpdate() { ${processBinding(hook.code)} }`)}
190
-
191
- render() {
192
- return (${wrap ? '<>' : ''}
193
-
194
- ${json.children.map((item) => blockToStencil(item, options, true)).join('\n')}
195
-
196
- ${wrap ? '</>' : ''})
197
- }
198
- }
199
- `;
200
- if (options.plugins) {
201
- str = (0, plugins_1.runPreCodePlugins)({ json, code: str, plugins: options.plugins });
202
- }
203
- if (options.prettier !== false) {
204
- str = (0, standalone_1.format)(str, {
205
- parser: 'typescript',
206
- plugins: [require('prettier/parser-typescript')],
207
- });
208
- }
209
- if (options.plugins) {
210
- str = (0, plugins_1.runPostCodePlugins)({ json, code: str, plugins: options.plugins });
211
- }
212
- return str;
213
- };
214
- exports.componentToStencil = componentToStencil;