@builder.io/mitosis 0.0.56-5 → 0.0.56-6

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 (27) hide show
  1. package/dist/src/__tests__/angular.test.js +27 -3
  2. package/dist/src/__tests__/data/basic-for-show.raw.d.ts +1 -0
  3. package/dist/src/__tests__/data/basic-for-show.raw.jsx +21 -0
  4. package/dist/src/__tests__/data/basic-onMount-update.raw.d.ts +1 -0
  5. package/dist/src/__tests__/data/basic-onMount-update.raw.jsx +17 -0
  6. package/dist/src/__tests__/data/blocks/content-slot-html.raw.d.ts +6 -0
  7. package/dist/src/__tests__/data/blocks/content-slot-html.raw.jsx +15 -0
  8. package/dist/src/__tests__/data/blocks/content-slot-jsx.raw.d.ts +5 -0
  9. package/dist/src/__tests__/data/blocks/content-slot-jsx.raw.jsx +12 -0
  10. package/dist/src/__tests__/data/blocks/content-slot.raw.d.ts +6 -0
  11. package/dist/src/__tests__/data/blocks/content-slot.raw.jsx +13 -0
  12. package/dist/src/__tests__/data/blocks/slot-html.raw.d.ts +5 -0
  13. package/dist/src/__tests__/data/blocks/slot-html.raw.jsx +15 -0
  14. package/dist/src/__tests__/data/blocks/slot-jsx.raw.d.ts +5 -0
  15. package/dist/src/__tests__/data/blocks/slot-jsx.raw.jsx +12 -0
  16. package/dist/src/__tests__/data/blocks/slot.raw.jsx +7 -1
  17. package/dist/src/__tests__/react.test.js +24 -0
  18. package/dist/src/__tests__/webcomponent.test.js +12 -0
  19. package/dist/src/flow.d.ts +5 -0
  20. package/dist/src/flow.js +5 -1
  21. package/dist/src/generators/angular.js +31 -3
  22. package/dist/src/generators/html.js +58 -30
  23. package/dist/src/generators/react.d.ts +1 -1
  24. package/dist/src/generators/react.js +42 -3
  25. package/dist/tsconfig.build.tsbuildinfo +1 -1
  26. package/dist/tsconfig.tsbuildinfo +1 -1
  27. package/package.json +2 -2
@@ -2,13 +2,22 @@
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  var angular_1 = require("../generators/angular");
4
4
  var jsx_1 = require("../parsers/jsx");
5
+ var multipleOnUpdate = require('./data/blocks/multiple-onUpdate.raw');
5
6
  var onUpdate = require('./data/blocks/onUpdate.raw');
6
7
  var onMount = require('./data/blocks/onMount.raw');
7
8
  var onInitonMount = require('./data/blocks/onInit-onMount.raw');
8
9
  var onInit = require('./data/blocks/onInit.raw');
9
10
  var basicFor = require('./data/basic-for.raw');
10
- var slot = require('./data/blocks/slot.raw');
11
+ var contentSlotHtml = require('./data/blocks/content-slot-html.raw');
12
+ var contentSlotJsx = require('./data/blocks/content-slot-jsx.raw');
13
+ var slotJsx = require('./data/blocks/slot-jsx.raw');
14
+ // const slotHtml = require('./data/blocks/slot-html.raw');
11
15
  describe('Angular', function () {
16
+ test('multiple onUpdate', function () {
17
+ var component = (0, jsx_1.parseJsx)(multipleOnUpdate);
18
+ var output = (0, angular_1.componentToAngular)()({ component: component });
19
+ expect(output).toMatchSnapshot();
20
+ });
12
21
  test('onUpdate', function () {
13
22
  var component = (0, jsx_1.parseJsx)(onUpdate);
14
23
  var output = (0, angular_1.componentToAngular)()({ component: component });
@@ -34,9 +43,24 @@ describe('Angular', function () {
34
43
  var output = (0, angular_1.componentToAngular)()({ component: component });
35
44
  expect(output).toMatchSnapshot();
36
45
  });
37
- test('ng-content', function () {
38
- var component = (0, jsx_1.parseJsx)(slot);
46
+ test('ng-content and Slot', function () {
47
+ var component = (0, jsx_1.parseJsx)(contentSlotHtml);
48
+ var output = (0, angular_1.componentToAngular)()({ component: component });
49
+ expect(output).toMatchSnapshot();
50
+ });
51
+ test('ng-content and Slot jsx-props', function () {
52
+ var component = (0, jsx_1.parseJsx)(contentSlotJsx);
53
+ var output = (0, angular_1.componentToAngular)()({ component: component });
54
+ expect(output).toMatchSnapshot();
55
+ });
56
+ test('Slot Jsx', function () {
57
+ var component = (0, jsx_1.parseJsx)(slotJsx);
39
58
  var output = (0, angular_1.componentToAngular)()({ component: component });
40
59
  expect(output).toMatchSnapshot();
41
60
  });
61
+ // test('Slot Html', () => {
62
+ // const component = parseJsx(slotHtml);
63
+ // const output = componentToAngular()({ component });
64
+ // expect(output).toMatchSnapshot();
65
+ // });
42
66
  });
@@ -0,0 +1 @@
1
+ export default function MyBasicForShowComponent(): JSX.Element;
@@ -0,0 +1,21 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ var mitosis_1 = require("@builder.io/mitosis");
4
+ function MyBasicForShowComponent() {
5
+ var state = (0, mitosis_1.useState)({
6
+ name: 'PatrickJS',
7
+ names: ['Steve', 'PatrickJS'],
8
+ });
9
+ return (<div>
10
+ <mitosis_1.For each={state.names}>
11
+ {function (person) { return (<mitosis_1.Show when={person === state.name}>
12
+ <input value={state.name} onChange={function (event) {
13
+ state.name = event.target.value + ' and ' + person;
14
+ }}/>
15
+ Hello {person}! I can run in Qwik, Web Component, React, Vue, Solid,
16
+ or Liquid!
17
+ </mitosis_1.Show>); }}
18
+ </mitosis_1.For>
19
+ </div>);
20
+ }
21
+ exports.default = MyBasicForShowComponent;
@@ -0,0 +1 @@
1
+ export default function MyBasicOnMountUpdateComponent(): JSX.Element;
@@ -0,0 +1,17 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ var mitosis_1 = require("@builder.io/mitosis");
4
+ function MyBasicOnMountUpdateComponent() {
5
+ var state = (0, mitosis_1.useState)({
6
+ name: 'PatrickJS',
7
+ names: ['Steve', 'PatrickJS'],
8
+ });
9
+ (0, mitosis_1.onInit)(function () {
10
+ state.name = 'PatrickJS onInit';
11
+ });
12
+ (0, mitosis_1.onMount)(function () {
13
+ state.name = 'PatrickJS onMount';
14
+ });
15
+ return <div>Hello {state.name}</div>;
16
+ }
17
+ exports.default = MyBasicOnMountUpdateComponent;
@@ -0,0 +1,6 @@
1
+ declare type Props = {
2
+ [key: string]: string | JSX.Element;
3
+ slotTesting: JSX.Element;
4
+ };
5
+ export default function ContentSlotCode(props: Props): JSX.Element;
6
+ export {};
@@ -0,0 +1,15 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ var mitosis_1 = require("@builder.io/mitosis");
4
+ function ContentSlotCode(props) {
5
+ return (<div>
6
+ <mitosis_1.Slot name={props.slotTesting}/>
7
+ <div>
8
+ <hr />
9
+ </div>
10
+ <div>
11
+ <mitosis_1.Slot />
12
+ </div>
13
+ </div>);
14
+ }
15
+ exports.default = ContentSlotCode;
@@ -0,0 +1,5 @@
1
+ declare type Props = {
2
+ [key: string]: string | JSX.Element;
3
+ };
4
+ export default function ContentSlotJsxCode(props: Props): JSX.Element;
5
+ export {};
@@ -0,0 +1,12 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ function ContentSlotJsxCode(props) {
4
+ return (<div>
5
+ {props.slotTesting}
6
+ <div>
7
+ <hr />
8
+ </div>
9
+ <div>{props.children}</div>
10
+ </div>);
11
+ }
12
+ exports.default = ContentSlotJsxCode;
@@ -0,0 +1,6 @@
1
+ declare type Props = {
2
+ [key: string]: string | JSX.Element;
3
+ slotTesting: JSX.Element;
4
+ };
5
+ export default function ContentSlotCode(props: Props): JSX.Element;
6
+ export {};
@@ -0,0 +1,13 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ var mitosis_1 = require("@builder.io/mitosis");
4
+ function ContentSlotCode(props) {
5
+ return (<div>
6
+ <mitosis_1.Slot name={props.slotTesting}/>
7
+ <div>
8
+ <hr />
9
+ </div>
10
+ <div>{props.children}</div>
11
+ </div>);
12
+ }
13
+ exports.default = ContentSlotCode;
@@ -0,0 +1,5 @@
1
+ declare type Props = {
2
+ [key: string]: string;
3
+ };
4
+ export default function SlotCode(props: Props): JSX.Element;
5
+ export {};
@@ -0,0 +1,15 @@
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
+ var mitosis_1 = require("@builder.io/mitosis");
7
+ var content_slot_jsx_raw_1 = __importDefault(require("./content-slot-jsx.raw"));
8
+ function SlotCode(props) {
9
+ return (<div>
10
+ <content_slot_jsx_raw_1.default>
11
+ <mitosis_1.Slot testing={<div>Hello</div>}></mitosis_1.Slot>
12
+ </content_slot_jsx_raw_1.default>
13
+ </div>);
14
+ }
15
+ exports.default = SlotCode;
@@ -0,0 +1,5 @@
1
+ declare type Props = {
2
+ [key: string]: string;
3
+ };
4
+ export default function SlotCode(props: Props): JSX.Element;
5
+ export {};
@@ -0,0 +1,12 @@
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
+ var content_slot_jsx_raw_1 = __importDefault(require("./content-slot-jsx.raw"));
7
+ function SlotCode(props) {
8
+ return (<div>
9
+ <content_slot_jsx_raw_1.default slotTesting={<div>Hello</div>}/>
10
+ </div>);
11
+ }
12
+ exports.default = SlotCode;
@@ -1,6 +1,12 @@
1
1
  "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
2
5
  Object.defineProperty(exports, "__esModule", { value: true });
6
+ var content_slot_raw_1 = __importDefault(require("./content-slot.raw"));
3
7
  function SlotCode(props) {
4
- return <div>{props.children}</div>;
8
+ return (<div>
9
+ <content_slot_raw_1.default slotTesting={<div>Hello</div>}/>
10
+ </div>);
5
11
  }
6
12
  exports.default = SlotCode;
@@ -27,7 +27,31 @@ var multipleOnUpdate = require('./data/blocks/multiple-onUpdate.raw');
27
27
  var multipleOnUpdateWithDeps = require('./data/blocks/multiple-onUpdateWithDeps.raw');
28
28
  var onMount = require('./data/blocks/onMount.raw');
29
29
  var rootShow = require('./data/blocks/rootShow.raw');
30
+ var contentSlotHtml = require('./data/blocks/content-slot-html.raw');
31
+ var contentSlotJsx = require('./data/blocks/content-slot-jsx.raw');
32
+ var slotJsx = require('./data/blocks/slot-jsx.raw');
33
+ var slotHtml = require('./data/blocks/slot-html.raw');
30
34
  describe('React', function () {
35
+ test('ContentSlotJSX', function () {
36
+ var component = (0, jsx_1.parseJsx)(contentSlotJsx);
37
+ var output = (0, react_1.componentToReact)()({ component: component });
38
+ expect(output).toMatchSnapshot();
39
+ });
40
+ test('ContentSlotHtml', function () {
41
+ var component = (0, jsx_1.parseJsx)(contentSlotHtml);
42
+ var output = (0, react_1.componentToReact)()({ component: component });
43
+ expect(output).toMatchSnapshot();
44
+ });
45
+ test('SlotJsx', function () {
46
+ var component = (0, jsx_1.parseJsx)(slotJsx);
47
+ var output = (0, react_1.componentToReact)()({ component: component });
48
+ expect(output).toMatchSnapshot();
49
+ });
50
+ test('SlotHtml', function () {
51
+ var component = (0, jsx_1.parseJsx)(slotHtml);
52
+ var output = (0, react_1.componentToReact)()({ component: component });
53
+ expect(output).toMatchSnapshot();
54
+ });
31
55
  test('Basic', function () {
32
56
  var component = (0, jsx_1.parseJsx)(basic);
33
57
  var output = (0, react_1.componentToReact)()({ component: component });
@@ -4,6 +4,8 @@ var html_1 = require("../generators/html");
4
4
  var jsx_1 = require("../parsers/jsx");
5
5
  var basic = require('./data/basic.raw');
6
6
  var basicFor = require('./data/basic-for.raw');
7
+ var basicForShow = require('./data/basic-for-show.raw');
8
+ var basicOnMountUpdate = require('./data/basic-onMount-update.raw');
7
9
  var submitButtonBlock = require('./data/blocks/submit-button.raw');
8
10
  var inputBlock = require('./data/blocks/input.raw');
9
11
  var selectBlock = require('./data/blocks/select.raw');
@@ -38,6 +40,16 @@ describe('webcomponent', function () {
38
40
  var output = (0, html_1.componentToCustomElement)()({ component: component });
39
41
  expect(output).toMatchSnapshot();
40
42
  });
43
+ test('BasicForShow', function () {
44
+ var component = (0, jsx_1.parseJsx)(basicForShow);
45
+ var output = (0, html_1.componentToCustomElement)()({ component: component });
46
+ expect(output).toMatchSnapshot();
47
+ });
48
+ test('BasicOnMountUpdate', function () {
49
+ var component = (0, jsx_1.parseJsx)(basicOnMountUpdate);
50
+ var output = (0, html_1.componentToCustomElement)()({ component: component });
51
+ expect(output).toMatchSnapshot();
52
+ });
41
53
  test('Input block', function () {
42
54
  var component = (0, jsx_1.parseJsx)(inputBlock);
43
55
  var output = (0, html_1.componentToCustomElement)()({ component: component });
@@ -10,6 +10,11 @@ export declare function For<T, U extends JSX.Element>(props: {
10
10
  each?: readonly T[];
11
11
  children: (item: T, index: number) => U;
12
12
  }): any;
13
+ export declare function Slot<T, U extends JSX.Element>(props: {
14
+ name?: JSX.Element;
15
+ } | {
16
+ [key: string]: any;
17
+ }): any;
13
18
  export declare function Show<T>(props: {
14
19
  when: T | undefined | null | false;
15
20
  else?: JSX.Element;
package/dist/src/flow.js CHANGED
@@ -8,11 +8,15 @@
8
8
  * These elements all compile away so they return `null`
9
9
  */
10
10
  Object.defineProperty(exports, "__esModule", { value: true });
11
- exports.Show = exports.For = void 0;
11
+ exports.Show = exports.Slot = exports.For = void 0;
12
12
  function For(props) {
13
13
  return null;
14
14
  }
15
15
  exports.For = For;
16
+ function Slot(props) {
17
+ return null;
18
+ }
19
+ exports.Slot = Slot;
16
20
  function Show(props) {
17
21
  return null;
18
22
  }
@@ -31,8 +31,21 @@ var mappers = {
31
31
  .map(function (item) { return (0, exports.blockToAngular)(item, options); })
32
32
  .join('\n'), "</div>");
33
33
  },
34
+ Slot: function (json, options) {
35
+ return "<ng-content ".concat(Object.keys(json.bindings)
36
+ .map(function (binding) {
37
+ var _a;
38
+ if (binding === 'name') {
39
+ var selector = (0, lodash_1.kebabCase)((_a = json.bindings.name) === null || _a === void 0 ? void 0 : _a.replace('props.slot', ''));
40
+ return "select=\"[".concat(selector, "]\"");
41
+ }
42
+ return "".concat(json.bindings[binding]);
43
+ })
44
+ .join('\n'), "></ng-content>");
45
+ },
34
46
  };
35
47
  var blockToAngular = function (json, options) {
48
+ var _a;
36
49
  if (options === void 0) { options = {}; }
37
50
  if (mappers[json.name]) {
38
51
  return mappers[json.name](json, options);
@@ -43,10 +56,15 @@ var blockToAngular = function (json, options) {
43
56
  if (json.properties._text) {
44
57
  return json.properties._text;
45
58
  }
59
+ if (/props\.slot/.test(json.bindings._text)) {
60
+ var selector = (0, lodash_1.kebabCase)((_a = json.bindings._text) === null || _a === void 0 ? void 0 : _a.replace('props.slot', ''));
61
+ return "<ng-content select=\"[".concat(selector, "]\"></ng-content>");
62
+ }
46
63
  if (json.bindings._text) {
47
64
  return "{{".concat((0, strip_state_and_props_refs_1.stripStateAndPropsRefs)(json.bindings._text), "}}");
48
65
  }
49
66
  var str = '';
67
+ var needsToRenderSlots = [];
50
68
  if (json.name === 'For') {
51
69
  str += "<ng-container *ngFor=\"let ".concat(json.properties._forName, " of ").concat((0, strip_state_and_props_refs_1.stripStateAndPropsRefs)(json.bindings.each), "\">");
52
70
  str += json.children
@@ -99,6 +117,11 @@ var blockToAngular = function (json, options) {
99
117
  else if (key === 'ref') {
100
118
  str += " #".concat(useValue, " ");
101
119
  }
120
+ else if (key.startsWith('slot')) {
121
+ var lowercaseKey = key.replace('slot', '')[0].toLowerCase() +
122
+ key.replace('slot', '').substring(1);
123
+ needsToRenderSlots.push("".concat(useValue.replace(/(\/\>)|\>/, " ".concat(lowercaseKey, ">"))));
124
+ }
102
125
  else {
103
126
  str += " [".concat(key, "]=\"").concat(useValue, "\" ");
104
127
  }
@@ -107,6 +130,9 @@ var blockToAngular = function (json, options) {
107
130
  return str + ' />';
108
131
  }
109
132
  str += '>';
133
+ if (needsToRenderSlots.length > 0) {
134
+ str += needsToRenderSlots.map(function (el) { return el; }).join('');
135
+ }
110
136
  if (json.children) {
111
137
  str += json.children
112
138
  .map(function (item) { return (0, exports.blockToAngular)(item, options); })
@@ -152,6 +178,7 @@ var componentToAngular = function (options) {
152
178
  var str = (0, dedent_1.default)(templateObject_1 || (templateObject_1 = __makeTemplateObject(["\n import { Component ", "", " } from '@angular/core';\n ", "\n\n @Component({\n selector: '", "',\n template: `\n ", "\n `,\n ", "\n })\n export default class ", " {\n ", "\n\n ", "\n\n ", "\n\n ", "\n\n ", "\n\n ", "\n }\n "], ["\n import { Component ", "", " } from '@angular/core';\n ", "\n\n @Component({\n selector: '", "',\n template: \\`\n ", "\n \\`,\n ", "\n })\n export default class ", " {\n ", "\n\n ", "\n\n ", "\n\n ", "\n\n ", "\n\n ", "\n }\n "])), refs.length ? ', ViewChild, ElementRef' : '', props.size ? ', Input' : '', (0, render_imports_1.renderPreComponent)(json), (0, lodash_1.kebabCase)(json.name || 'my-component'), (0, indent_1.indent)(template, 8).replace(/`/g, '\\`').replace(/\$\{/g, '\\${'), css.length
153
179
  ? "styles: [\n `".concat((0, indent_1.indent)(css, 8), "`\n ],")
154
180
  : '', component.name, Array.from(props)
181
+ .filter(function (item) { return !item.startsWith('slot'); })
155
182
  .map(function (item) { return "@Input() ".concat(item, ": any"); })
156
183
  .join('\n'), refs
157
184
  .map(function (refName) { return "@ViewChild('".concat(refName, "') ").concat(refName, ": ElementRef"); })
@@ -167,11 +194,12 @@ var componentToAngular = function (options) {
167
194
  replaceWith: 'this.',
168
195
  }), "\n "), "\n }"), !((_h = component.hooks.onUpdate) === null || _h === void 0 ? void 0 : _h.length)
169
196
  ? ''
170
- : "ngAfterContentChecked() {\n ".concat(component.hooks.onUpdate.map(function (hook) {
171
- return (0, strip_state_and_props_refs_1.stripStateAndPropsRefs)(hook.code, {
197
+ : "ngAfterContentChecked() {\n ".concat(component.hooks.onUpdate.reduce(function (code, hook) {
198
+ code += (0, strip_state_and_props_refs_1.stripStateAndPropsRefs)(hook.code, {
172
199
  replaceWith: 'this.',
173
200
  });
174
- }), "\n }"), !component.hooks.onUnMount
201
+ return code + '\n';
202
+ }, ''), "\n }"), !component.hooks.onUnMount
175
203
  ? ''
176
204
  : "ngOnDestroy() {\n ".concat((0, strip_state_and_props_refs_1.stripStateAndPropsRefs)(component.hooks.onUnMount.code, {
177
205
  replaceWith: 'this.',
@@ -76,11 +76,16 @@ var addUpdateAfterSet = function (json, options) {
76
76
  }
77
77
  });
78
78
  };
79
- var addScopeVars = function (parentScopeVars, value, fn) {
80
- return "".concat(parentScopeVars
81
- .filter(function (scopeVar) {
79
+ var getScopeVars = function (parentScopeVars, value) {
80
+ return parentScopeVars.filter(function (scopeVar) {
81
+ if (typeof value === 'boolean') {
82
+ return value;
83
+ }
82
84
  return new RegExp(scopeVar).test(value);
83
- })
85
+ });
86
+ };
87
+ var addScopeVars = function (parentScopeVars, value, fn) {
88
+ return "".concat(getScopeVars(parentScopeVars, value)
84
89
  .map(function (scopeVar) {
85
90
  return fn(scopeVar);
86
91
  })
@@ -193,7 +198,10 @@ var blockToHtml = function (json, options, parentScopeVars) {
193
198
  str += '</template>';
194
199
  }
195
200
  else if (json.name === 'Show') {
196
- addOnChangeJs(elId, options, "\n const whenCondition = ".concat(json.bindings.when.replace(/;$/, ''), ";\n if (whenCondition) {\n ").concat(options.format === 'class' ? 'this.' : '', "showContent(el)\n }\n "));
201
+ var whenCondition = json.bindings.when.replace(/;$/, '');
202
+ addOnChangeJs(elId, options, "\n ".concat(addScopeVars(parentScopeVars, whenCondition, function (scopeVar) {
203
+ return "const ".concat(scopeVar, " = ").concat(options.format === 'class' ? 'this.' : '', "getContext(el, \"").concat(scopeVar, "\");");
204
+ }), "\n const whenCondition = ").concat(whenCondition, ";\n if (whenCondition) {\n ").concat(options.format === 'class' ? 'this.' : '', "showContent(el)\n }\n "));
197
205
  str += "<template data-name=\"".concat(elId, "\">");
198
206
  if (json.children) {
199
207
  str += json.children
@@ -224,6 +232,10 @@ var blockToHtml = function (json, options, parentScopeVars) {
224
232
  .replace(/\n/g, '\\n');
225
233
  str += " ".concat(key, "=\"").concat(value, "\" ");
226
234
  }
235
+ // batch all local vars within the bindings
236
+ var batchScopeVars_1 = {};
237
+ var injectOnce = false;
238
+ var startInjectVar = '%%START_VARS%%';
227
239
  for (var key in json.bindings) {
228
240
  if (key === '_spread' || key === 'ref' || key === 'css') {
229
241
  continue;
@@ -253,13 +265,27 @@ var blockToHtml = function (json, options, parentScopeVars) {
253
265
  }), "\n ;Object.assign(el.style, ").concat(useValue, ");"));
254
266
  }
255
267
  else {
256
- addOnChangeJs(elId, options, "\n ".concat(addScopeVars(parentScopeVars, useValue, function (scopeVar) {
257
- // TODO: multiple loops may duplicate variable declarations
258
- return ";var ".concat(scopeVar, " = ").concat(options.format === 'class' ? 'this.' : '', "getContext(el, \"").concat(scopeVar, "\");");
259
- }), "\n ").concat(generateSetElementAttributeCode(key, useValue, options), "\n "));
268
+ // gather all local vars to inject later
269
+ getScopeVars(parentScopeVars, useValue).forEach(function (key) {
270
+ // unique keys
271
+ batchScopeVars_1[key] = true;
272
+ });
273
+ addOnChangeJs(elId, options, "\n ".concat(injectOnce ? '' : startInjectVar, "\n ").concat(generateSetElementAttributeCode(key, useValue, options), "\n "));
274
+ if (!injectOnce) {
275
+ injectOnce = true;
276
+ }
260
277
  }
261
278
  }
262
279
  }
280
+ // batch inject local vars in the beginning of the function block
281
+ var codeBlock = options.onChangeJsById[elId];
282
+ var testInjectVar = new RegExp(startInjectVar);
283
+ if (codeBlock && testInjectVar.test(codeBlock)) {
284
+ var localScopeVars = Object.keys(batchScopeVars_1);
285
+ options.onChangeJsById[elId] = codeBlock.replace(startInjectVar, "\n ".concat(addScopeVars(localScopeVars, true, function (scopeVar) {
286
+ return "const ".concat(scopeVar, " = ").concat(options.format === 'class' ? 'this.' : '', "getContext(el, \"").concat(scopeVar, "\");");
287
+ }), "\n "));
288
+ }
263
289
  if (jsx_1.selfClosingTags.has(json.name)) {
264
290
  return str + ' />';
265
291
  }
@@ -359,28 +385,29 @@ var componentToHtml = function (options) {
359
385
  valueMapper: function (value) {
360
386
  return addUpdateAfterSetInCode(updateReferencesInCode(value, useOptions), useOptions);
361
387
  },
362
- }), ";\n ").concat(componentHasProps ? "let props = {};" : '', "\n let nodesToDestroy = [];\n ").concat(!((_d = (_c = json.hooks) === null || _c === void 0 ? void 0 : _c.onInit) === null || _d === void 0 ? void 0 : _d.code) ? '' : 'let onInitOnce = false;', "\n\n function destroyAnyNodes() {\n // destroy current view template refs before rendering again\n nodesToDestroy.forEach(el => el.remove());\n nodesToDestroy = [];\n }\n ").concat(!hasChangeListeners
388
+ }), ";\n ").concat(componentHasProps ? "let props = {};" : '', "\n let nodesToDestroy = [];\n let pendingUpdate = false;\n ").concat(!((_d = (_c = json.hooks) === null || _c === void 0 ? void 0 : _c.onInit) === null || _d === void 0 ? void 0 : _d.code) ? '' : 'let onInitOnce = false;', "\n\n function destroyAnyNodes() {\n // destroy current view template refs before rendering again\n nodesToDestroy.forEach(el => el.remove());\n nodesToDestroy = [];\n }\n ").concat(!hasChangeListeners
363
389
  ? ''
364
- : "\n \n // Function to update data bindings and loops\n // call update() when you mutate state and need the updates to reflect\n // in the dom\n function update() {\n ".concat(Object.keys(useOptions.onChangeJsById)
390
+ : "\n \n // Function to update data bindings and loops\n // call update() when you mutate state and need the updates to reflect\n // in the dom\n function update() {\n if (pendingUpdate === true) {\n return;\n }\n pendingUpdate = true;\n ".concat(Object.keys(useOptions.onChangeJsById)
365
391
  .map(function (key) {
366
392
  var value = useOptions.onChangeJsById[key];
367
393
  if (!value) {
368
394
  return '';
369
395
  }
370
- return "\n document.querySelectorAll(\"[data-name='".concat(key, "']\").forEach((el, index) => {\n ").concat(value, "\n })\n ");
396
+ return "\n document.querySelectorAll(\"[data-name='".concat(key, "']\").forEach((el) => {\n ").concat(value, "\n });\n ");
371
397
  })
372
- .join('\n\n'), "\n\n destroyAnyNodes();\n\n ").concat(!((_e = json.hooks.onUpdate) === null || _e === void 0 ? void 0 : _e.length)
398
+ .join('\n\n'), "\n\n destroyAnyNodes();\n\n ").concat(!((_e = json.hooks.onUpdate) === null || _e === void 0 ? void 0 : _e.length)
373
399
  ? ''
374
- : "\n ".concat(json.hooks.onUpdate.map(function (hook) {
375
- return updateReferencesInCode(hook.code, useOptions);
376
- }), " \n "), "\n }\n\n ").concat(useOptions.js, "\n\n // Update with initial state on first load\n update();\n "), "\n\n ").concat(!((_g = (_f = json.hooks) === null || _f === void 0 ? void 0 : _f.onInit) === null || _g === void 0 ? void 0 : _g.code)
400
+ : "\n ".concat(json.hooks.onUpdate.reduce(function (code, hook) {
401
+ code += addUpdateAfterSetInCode(updateReferencesInCode(hook.code, useOptions), useOptions);
402
+ return code + '\n';
403
+ }, ''), " \n "), "\n\n pendingUpdate = false;\n }\n\n ").concat(useOptions.js, "\n\n // Update with initial state on first load\n update();\n "), "\n\n ").concat(!((_g = (_f = json.hooks) === null || _f === void 0 ? void 0 : _f.onInit) === null || _g === void 0 ? void 0 : _g.code)
377
404
  ? ''
378
- : "\n if (!onInitOnce) {\n ".concat(updateReferencesInCode((_j = (_h = json.hooks) === null || _h === void 0 ? void 0 : _h.onInit) === null || _j === void 0 ? void 0 : _j.code, useOptions), "\n onInitOnce = true;\n }\n "), "\n\n ").concat(!((_k = json.hooks.onMount) === null || _k === void 0 ? void 0 : _k.code)
405
+ : "\n if (!onInitOnce) {\n ".concat(updateReferencesInCode(addUpdateAfterSetInCode((_j = (_h = json.hooks) === null || _h === void 0 ? void 0 : _h.onInit) === null || _j === void 0 ? void 0 : _j.code, useOptions), useOptions), "\n onInitOnce = true;\n }\n "), "\n\n ").concat(!((_k = json.hooks.onMount) === null || _k === void 0 ? void 0 : _k.code)
379
406
  ? ''
380
407
  : // TODO: make prettier by grabbing only the function body
381
408
  "\n // onMount\n ".concat(updateReferencesInCode(addUpdateAfterSetInCode(json.hooks.onMount.code, useOptions), useOptions), " \n "), "\n\n ").concat(!hasShow
382
409
  ? ''
383
- : "\n function showContent(el) {\n // https://developer.mozilla.org/en-US/docs/Web/API/HTMLTemplateElement/content\n // grabs the content of a node that is between <template> tags\n // iterates through child nodes to register all content including text elements\n // attaches the content after the template\n \n \n const elementFragment = el.content.cloneNode(true);\n const children = Array.from(elementFragment.childNodes)\n children.forEach(child => {\n ".concat(options.format === 'class' ? 'this.' : '', "nodesToDestroy.push(child);\n });\n el.after(elementFragment);\n }\n \n "), "\n ").concat(!hasLoop
410
+ : "\n function showContent(el) {\n // https://developer.mozilla.org/en-US/docs/Web/API/HTMLTemplateElement/content\n // grabs the content of a node that is between <template> tags\n // iterates through child nodes to register all content including text elements\n // attaches the content after the template\n \n \n const elementFragment = el.content.cloneNode(true);\n const children = Array.from(elementFragment.childNodes)\n children.forEach(child => {\n nodesToDestroy.push(child);\n });\n el.after(elementFragment);\n }\n \n ", "\n ").concat(!hasLoop
384
411
  ? ''
385
412
  : "\n // Helper to render loops\n function renderLoop(el, array, template, itemName, itemIndex, collectionName) {\n el.innerHTML = \"\";\n for (let [index, value] of array.entries()) {\n let tmp = document.createElement(\"span\");\n tmp.innerHTML = template.innerHTML;\n Array.from(tmp.children).forEach((child) => {\n if (itemName !== undefined) {\n child['__' + itemName] = value;\n }\n if (itemIndex !== undefined) {\n child['__' + itemIndex] = index;\n }\n if (collectionName !== undefined) {\n child['__' + collectionName] = array;\n }\n el.appendChild(child);\n });\n }\n }\n\n function getContext(el, name) {\n do {\n let value = el['__' + name]\n if (value !== undefined) {\n return value\n }\n } while ((el = el.parentNode));\n }\n ", "\n })()\n </script>\n ");
386
413
  }
@@ -417,7 +444,10 @@ var componentToCustomElement = function (options) {
417
444
  return function (_a) {
418
445
  var _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o, _p, _q, _r, _s, _t, _u, _v, _w, _x, _y, _z, _0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15, _16;
419
446
  var component = _a.component;
420
- var useOptions = __assign(__assign({}, options), { onChangeJsById: {}, js: '', namesMap: {}, format: 'class' });
447
+ var kebabName = component.name
448
+ .replace(/([a-z])([A-Z])/g, '$1-$2')
449
+ .toLowerCase();
450
+ var useOptions = __assign(__assign({ prefix: kebabName }, options), { onChangeJsById: {}, js: '', namesMap: {}, format: 'class' });
421
451
  var json = (0, fast_clone_1.fastClone)(component);
422
452
  if (options.plugins) {
423
453
  json = (0, plugins_1.runPreJsonPlugins)(json, options.plugins);
@@ -446,7 +476,7 @@ var componentToCustomElement = function (options) {
446
476
  .map(function (item) { return blockToHtml(item, useOptions); })
447
477
  .join('\n');
448
478
  if ((_d = useOptions === null || useOptions === void 0 ? void 0 : useOptions.experimental) === null || _d === void 0 ? void 0 : _d.childrenHtml) {
449
- html = (_e = useOptions === null || useOptions === void 0 ? void 0 : useOptions.experimental) === null || _e === void 0 ? void 0 : _e.childrenHtml(html, json, useOptions);
479
+ html = (_e = useOptions === null || useOptions === void 0 ? void 0 : useOptions.experimental) === null || _e === void 0 ? void 0 : _e.childrenHtml(html, kebabName, json, useOptions);
450
480
  }
451
481
  if ((_f = useOptions === null || useOptions === void 0 ? void 0 : useOptions.experimental) === null || _f === void 0 ? void 0 : _f.cssHtml) {
452
482
  html += (_g = useOptions === null || useOptions === void 0 ? void 0 : useOptions.experimental) === null || _g === void 0 ? void 0 : _g.cssHtml(css);
@@ -473,9 +503,6 @@ var componentToCustomElement = function (options) {
473
503
  console.warn('Could not prettify', { string: html }, err);
474
504
  }
475
505
  }
476
- var kebabName = component.name
477
- .replace(/([a-z])([A-Z])/g, '$1-$2')
478
- .toLowerCase();
479
506
  var str = "\n ".concat((0, render_imports_1.renderPreComponent)(json), "\n /**\n * Usage:\n * \n * <").concat(kebabName, "></").concat(kebabName, ">\n * \n */\n class ").concat(component.name, " extends ").concat(((_h = useOptions === null || useOptions === void 0 ? void 0 : useOptions.experimental) === null || _h === void 0 ? void 0 : _h.classExtends)
480
507
  ? (_j = useOptions === null || useOptions === void 0 ? void 0 : useOptions.experimental) === null || _j === void 0 ? void 0 : _j.classExtends(json, useOptions)
481
508
  : 'HTMLElement', " {\n constructor() {\n super();\n const self = this;\n ").concat(!((_l = (_k = json.hooks) === null || _k === void 0 ? void 0 : _k.onInit) === null || _l === void 0 ? void 0 : _l.code) ? '' : 'this.onInitOnce = false;', "\n this.state = ").concat((0, get_state_object_string_1.getStateObjectStringFromComponent)(json, {
@@ -494,7 +521,7 @@ var componentToCustomElement = function (options) {
494
521
  },
495
522
  }), ";\n ").concat(componentHasProps /* TODO: accept these as attributes/properties on the custom element */
496
523
  ? "this.props = {};"
497
- : '', "\n\n\n // used to keep track of all nodes created by show/for\n this.nodesToDestroy = [];\n ").concat(((_m = useOptions === null || useOptions === void 0 ? void 0 : useOptions.experimental) === null || _m === void 0 ? void 0 : _m.componentConstructor)
524
+ : '', "\n\n\n // used to keep track of all nodes created by show/for\n this.nodesToDestroy = [];\n // batch updates\n this.pendingUpdate = false;\n ").concat(((_m = useOptions === null || useOptions === void 0 ? void 0 : useOptions.experimental) === null || _m === void 0 ? void 0 : _m.componentConstructor)
498
525
  ? (_o = useOptions === null || useOptions === void 0 ? void 0 : useOptions.experimental) === null || _o === void 0 ? void 0 : _o.componentConstructor(json, useOptions)
499
526
  : '', "\n\n ").concat(useOptions.js, "\n\n if (").concat((_p = json.meta.useMetadata) === null || _p === void 0 ? void 0 : _p.isAttachedToShadowDom, ") {\n this.attachShadow({ mode: 'open' })\n }\n }\n\n\n ").concat(!((_q = json.hooks.onUnMount) === null || _q === void 0 ? void 0 : _q.code)
500
527
  ? ''
@@ -502,11 +529,11 @@ var componentToCustomElement = function (options) {
502
529
  ? (_s = useOptions === null || useOptions === void 0 ? void 0 : useOptions.experimental) === null || _s === void 0 ? void 0 : _s.disconnectedCallback(json, useOptions)
503
530
  : "\n // onUnMount\n ".concat(updateReferencesInCode(addUpdateAfterSetInCode(json.hooks.onUnMount.code, useOptions), useOptions), "\n this.destroyAnyNodes(); // clean up nodes when component is destroyed\n ").concat(!((_u = (_t = json.hooks) === null || _t === void 0 ? void 0 : _t.onInit) === null || _u === void 0 ? void 0 : _u.code) ? '' : 'this.onInitOnce = false;', "\n "), "\n }\n "), "\n\n destroyAnyNodes() {\n // destroy current view template refs before rendering again\n this.nodesToDestroy.forEach(el => el.remove());\n this.nodesToDestroy = [];\n }\n\n get _root() {\n return this.shadowRoot || this;\n }\n\n connectedCallback() {\n ").concat(((_v = useOptions === null || useOptions === void 0 ? void 0 : useOptions.experimental) === null || _v === void 0 ? void 0 : _v.connectedCallbackUpdate)
504
531
  ? (_w = useOptions === null || useOptions === void 0 ? void 0 : useOptions.experimental) === null || _w === void 0 ? void 0 : _w.connectedCallbackUpdate(json, html, useOptions)
505
- : "\n this._root.innerHTML = `\n ".concat(html, "`;\n this.render();\n ").concat(!((_y = (_x = json.hooks) === null || _x === void 0 ? void 0 : _x.onInit) === null || _y === void 0 ? void 0 : _y.code) ? '' : 'this.onInit();', "\n this.onMount();\n this.onUpdate();\n "), "\n }\n ").concat(!((_0 = (_z = json.hooks) === null || _z === void 0 ? void 0 : _z.onInit) === null || _0 === void 0 ? void 0 : _0.code)
532
+ : "\n this._root.innerHTML = `\n ".concat(html, "`;\n this.pendingUpdate = true;\n this.render();\n ").concat(!((_y = (_x = json.hooks) === null || _x === void 0 ? void 0 : _x.onInit) === null || _y === void 0 ? void 0 : _y.code) ? '' : 'this.onInit();', "\n this.onMount();\n this.pendingUpdate = false;\n this.update();\n "), "\n }\n ").concat(!((_0 = (_z = json.hooks) === null || _z === void 0 ? void 0 : _z.onInit) === null || _0 === void 0 ? void 0 : _0.code)
506
533
  ? ''
507
534
  : "\n onInit() {\n ".concat(!((_2 = (_1 = json.hooks) === null || _1 === void 0 ? void 0 : _1.onInit) === null || _2 === void 0 ? void 0 : _2.code)
508
535
  ? ''
509
- : "\n if (!this.onInitOnce) {\n ".concat(updateReferencesInCode((_4 = (_3 = json.hooks) === null || _3 === void 0 ? void 0 : _3.onInit) === null || _4 === void 0 ? void 0 : _4.code, useOptions), "\n this.onInitOnce = true;\n }"), "\n }\n "), "\n\n ").concat(!hasShow
536
+ : "\n if (!this.onInitOnce) {\n ".concat(updateReferencesInCode(addUpdateAfterSetInCode((_4 = (_3 = json.hooks) === null || _3 === void 0 ? void 0 : _3.onInit) === null || _4 === void 0 ? void 0 : _4.code, useOptions), useOptions), "\n this.onInitOnce = true;\n }"), "\n }\n "), "\n\n ").concat(!hasShow
510
537
  ? ''
511
538
  : "\n showContent(el) {\n // https://developer.mozilla.org/en-US/docs/Web/API/HTMLTemplateElement/content\n // grabs the content of a node that is between <template> tags\n // iterates through child nodes to register all content including text elements\n // attaches the content after the template\n \n \n const elementFragment = el.content.cloneNode(true);\n const children = Array.from(elementFragment.childNodes)\n children.forEach(child => {\n this.nodesToDestroy.push(child);\n });\n el.after(elementFragment);\n }", "\n ").concat(!((_5 = useOptions === null || useOptions === void 0 ? void 0 : useOptions.experimental) === null || _5 === void 0 ? void 0 : _5.attributeChangedCallback)
512
539
  ? ''
@@ -515,13 +542,14 @@ var componentToCustomElement = function (options) {
515
542
  : // TODO: make prettier by grabbing only the function body
516
543
  "\n // onMount\n ".concat(updateReferencesInCode(addUpdateAfterSetInCode(json.hooks.onMount.code, useOptions), useOptions), "\n "), "\n }\n\n onUpdate() {\n ").concat(!((_8 = json.hooks.onUpdate) === null || _8 === void 0 ? void 0 : _8.length)
517
544
  ? ''
518
- : "\n ".concat(json.hooks.onUpdate.map(function (hook) {
519
- return updateReferencesInCode(hook.code, useOptions);
520
- }), " \n "), " \n }\n\n update() {\n ").concat(!((_9 = useOptions === null || useOptions === void 0 ? void 0 : useOptions.experimental) === null || _9 === void 0 ? void 0 : _9.shouldComponentUpdateStart)
545
+ : "\n ".concat(json.hooks.onUpdate.reduce(function (code, hook) {
546
+ code += updateReferencesInCode(hook.code, useOptions);
547
+ return code + '\n';
548
+ }, ''), " \n "), "\n }\n\n update() {\n if (this.pendingUpdate === true) {\n return;\n }\n this.pendingUpdate = true;\n ").concat(!((_9 = useOptions === null || useOptions === void 0 ? void 0 : useOptions.experimental) === null || _9 === void 0 ? void 0 : _9.shouldComponentUpdateStart)
521
549
  ? ''
522
550
  : "\n ".concat((_10 = useOptions === null || useOptions === void 0 ? void 0 : useOptions.experimental) === null || _10 === void 0 ? void 0 : _10.shouldComponentUpdateStart(json, useOptions), "\n "), "\n this.render();\n this.onUpdate();\n ").concat(!((_11 = useOptions === null || useOptions === void 0 ? void 0 : useOptions.experimental) === null || _11 === void 0 ? void 0 : _11.shouldComponentUpdateEnd)
523
551
  ? ''
524
- : "\n ".concat((_12 = useOptions === null || useOptions === void 0 ? void 0 : useOptions.experimental) === null || _12 === void 0 ? void 0 : _12.shouldComponentUpdateEnd(json, useOptions), "\n "), "\n }\n\n render() {\n // re-rendering needs to ensure that all nodes generated by for/show are refreshed\n this.destroyAnyNodes();\n ").concat(((_13 = useOptions === null || useOptions === void 0 ? void 0 : useOptions.experimental) === null || _13 === void 0 ? void 0 : _13.updateBindings)
552
+ : "\n ".concat((_12 = useOptions === null || useOptions === void 0 ? void 0 : useOptions.experimental) === null || _12 === void 0 ? void 0 : _12.shouldComponentUpdateEnd(json, useOptions), "\n "), "\n this.pendingUpdate = false;\n }\n\n render() {\n // re-rendering needs to ensure that all nodes generated by for/show are refreshed\n this.destroyAnyNodes();\n ").concat(((_13 = useOptions === null || useOptions === void 0 ? void 0 : useOptions.experimental) === null || _13 === void 0 ? void 0 : _13.updateBindings)
525
553
  ? (_14 = useOptions === null || useOptions === void 0 ? void 0 : useOptions.experimental) === null || _14 === void 0 ? void 0 : _14.updateBindings(json, useOptions)
526
554
  : 'this.updateBindings();', "\n }\n\n updateBindings() {\n ").concat(Object.keys(useOptions.onChangeJsById)
527
555
  .map(function (key) {
@@ -6,5 +6,5 @@ export interface ToReactOptions extends BaseTranspilerOptions {
6
6
  format?: 'lite' | 'safe';
7
7
  type?: 'dom' | 'native';
8
8
  }
9
- export declare const blockToReact: (json: MitosisNode, options: ToReactOptions) => string;
9
+ export declare const blockToReact: (json: MitosisNode, options: ToReactOptions, parentSlots?: any[] | undefined) => string;
10
10
  export declare const componentToReact: (reactOptions?: ToReactOptions) => Transpiler;