@builder.io/mitosis 0.5.23 → 0.5.25

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 (49) hide show
  1. package/dist/src/generators/alpine/generate.js +4 -3
  2. package/dist/src/generators/angular/helpers.d.ts +6 -0
  3. package/dist/src/generators/angular/helpers.js +14 -1
  4. package/dist/src/generators/angular/index.js +53 -41
  5. package/dist/src/generators/angular/types.d.ts +12 -0
  6. package/dist/src/generators/helpers/functions.d.ts +2 -2
  7. package/dist/src/generators/helpers/rsc.js +2 -1
  8. package/dist/src/generators/html/generator.js +8 -7
  9. package/dist/src/generators/liquid/generator.js +2 -1
  10. package/dist/src/generators/lit/generate.js +2 -1
  11. package/dist/src/generators/marko/generate.js +2 -1
  12. package/dist/src/generators/mitosis/generator.js +6 -5
  13. package/dist/src/generators/qwik/helpers/add-prevent-default.js +3 -2
  14. package/dist/src/generators/qwik/helpers/handlers.js +2 -1
  15. package/dist/src/generators/qwik/src-generator.js +2 -1
  16. package/dist/src/generators/react/blocks.js +2 -1
  17. package/dist/src/generators/react/helpers.js +3 -2
  18. package/dist/src/generators/solid/blocks.js +2 -1
  19. package/dist/src/generators/stencil/helpers/index.js +2 -1
  20. package/dist/src/generators/stencil/plugins/get-code-processor-plugins.d.ts +1 -1
  21. package/dist/src/generators/svelte/blocks.js +3 -2
  22. package/dist/src/generators/swift/generator.js +2 -1
  23. package/dist/src/generators/template/generator.js +2 -1
  24. package/dist/src/generators/vue/blocks.js +3 -2
  25. package/dist/src/helpers/component-file-extensions.js +21 -5
  26. package/dist/src/helpers/event-handlers.d.ts +2 -1
  27. package/dist/src/helpers/event-handlers.js +110 -3
  28. package/dist/src/helpers/on-event.d.ts +2 -2
  29. package/dist/src/helpers/plugins/process-code/index.d.ts +2 -2
  30. package/dist/src/helpers/plugins/process-signals.d.ts +3 -3
  31. package/dist/src/helpers/plugins/process-target-blocks.d.ts +2 -2
  32. package/dist/src/modules/plugins.d.ts +6 -6
  33. package/dist/src/parsers/jsx/helpers.d.ts +6 -0
  34. package/dist/src/parsers/jsx/helpers.js +28 -4
  35. package/dist/src/parsers/jsx/hooks/index.d.ts +4 -3
  36. package/dist/src/parsers/jsx/hooks/index.js +37 -26
  37. package/dist/src/parsers/jsx/hooks/use-metadata.d.ts +9 -0
  38. package/dist/src/parsers/jsx/hooks/use-metadata.js +184 -0
  39. package/dist/src/parsers/jsx/imports.d.ts +0 -2
  40. package/dist/src/parsers/jsx/imports.js +8 -26
  41. package/dist/src/parsers/jsx/jsx.js +87 -106
  42. package/dist/src/parsers/jsx/types.d.ts +7 -1
  43. package/dist/src/parsers/svelte/helpers/post-process.d.ts +1 -1
  44. package/dist/src/plugins/compile-away-builder-components.d.ts +2 -2
  45. package/dist/src/types/config.d.ts +11 -2
  46. package/dist/src/types/mitosis-component.d.ts +9 -0
  47. package/dist/src/types/plugins.d.ts +17 -9
  48. package/dist/src/types/transpiler.d.ts +12 -2
  49. package/package.json +1 -1
@@ -1,8 +1,10 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.componentToAlpine = exports.isValidAlpineBinding = exports.checkIsComponentNode = void 0;
4
+ const html_tags_1 = require("../../constants/html_tags");
4
5
  const babel_transform_1 = require("../../helpers/babel-transform");
5
6
  const dash_case_1 = require("../../helpers/dash-case");
7
+ const event_handlers_1 = require("../../helpers/event-handlers");
6
8
  const fast_clone_1 = require("../../helpers/fast-clone");
7
9
  const get_refs_1 = require("../../helpers/get-refs");
8
10
  const get_state_object_string_1 = require("../../helpers/get-state-object-string");
@@ -12,11 +14,10 @@ const replace_identifiers_1 = require("../../helpers/replace-identifiers");
12
14
  const strip_meta_properties_1 = require("../../helpers/strip-meta-properties");
13
15
  const strip_state_and_props_refs_1 = require("../../helpers/strip-state-and-props-refs");
14
16
  const collect_css_1 = require("../../helpers/styles/collect-css");
17
+ const plugins_1 = require("../../modules/plugins");
15
18
  const mitosis_node_1 = require("../../types/mitosis-node");
16
19
  const lodash_1 = require("lodash");
17
20
  const standalone_1 = require("prettier/standalone");
18
- const html_tags_1 = require("../../constants/html_tags");
19
- const plugins_1 = require("../../modules/plugins");
20
21
  const render_mount_hook_1 = require("./render-mount-hook");
21
22
  const render_update_hooks_1 = require("./render-update-hooks");
22
23
  const checkIsComponentNode = (node) => node.name === '@builder.io/mitosis/component';
@@ -128,7 +129,7 @@ const blockToAlpine = (json, options = {}) => {
128
129
  const { code: value, type: bindingType } = json.bindings[key];
129
130
  // TODO: proper babel transform to replace. Util for this
130
131
  const useValue = (0, strip_state_and_props_refs_1.stripStateAndPropsRefs)(value);
131
- if (key.startsWith('on')) {
132
+ if ((0, event_handlers_1.checkIsEvent)(key)) {
132
133
  str += bindEventHandler(options)(key, value);
133
134
  }
134
135
  else if (key === 'ref') {
@@ -1,4 +1,5 @@
1
1
  import { type MitosisComponent } from '../../types/mitosis-component';
2
+ import { MitosisNode } from '../../types/mitosis-node';
2
3
  export declare const HELPER_FUNCTIONS: (isTs?: boolean) => {
3
4
  [key: string]: string;
4
5
  };
@@ -33,3 +34,8 @@ export declare const getDefaultProps: ({ defaultProps }: MitosisComponent) => st
33
34
  * @param json The MitosisComponent.
34
35
  */
35
36
  export declare const transformState: (json: MitosisComponent) => void;
37
+ /**
38
+ * Checks if the first child has a "key" attribute - used for "For" elements
39
+ * @param node The node which should be "For"
40
+ */
41
+ export declare const hasFirstChildKeyAttribute: (node: MitosisNode) => boolean;
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.transformState = exports.getDefaultProps = exports.makeReactiveState = exports.addCodeToOnInit = exports.addCodeToOnUpdate = exports.getAppropriateTemplateFunctionKeys = exports.HELPER_FUNCTIONS = void 0;
3
+ exports.hasFirstChildKeyAttribute = exports.transformState = exports.getDefaultProps = exports.makeReactiveState = exports.addCodeToOnInit = exports.addCodeToOnUpdate = exports.getAppropriateTemplateFunctionKeys = exports.HELPER_FUNCTIONS = void 0;
4
4
  const strip_state_and_props_refs_1 = require("../../helpers/strip-state-and-props-refs");
5
5
  const HELPER_FUNCTIONS = (isTs) => ({
6
6
  useObjectWrapper: `useObjectWrapper(...args${isTs ? ': any[]' : ''}) {
@@ -120,3 +120,16 @@ const transformState = (json) => {
120
120
  });
121
121
  };
122
122
  exports.transformState = transformState;
123
+ /**
124
+ * Checks if the first child has a "key" attribute - used for "For" elements
125
+ * @param node The node which should be "For"
126
+ */
127
+ const hasFirstChildKeyAttribute = (node) => {
128
+ var _a;
129
+ if (!node.children || node.children.length === 0) {
130
+ return false;
131
+ }
132
+ const firstChildBinding = node.children[0].bindings;
133
+ return Boolean(firstChildBinding && ((_a = firstChildBinding.key) === null || _a === void 0 ? void 0 : _a.code));
134
+ };
135
+ exports.hasFirstChildKeyAttribute = hasFirstChildKeyAttribute;
@@ -67,6 +67,7 @@ const is_children_1 = __importDefault(require("../../helpers/is-children"));
67
67
  const on_mount_1 = require("../helpers/on-mount");
68
68
  const helpers_2 = require("./helpers");
69
69
  const types_1 = require("./types");
70
+ const event_handlers_1 = require("../../helpers/event-handlers");
70
71
  const parse_selector_1 = require("./parse-selector");
71
72
  const { types } = babel;
72
73
  const mappers = {
@@ -187,7 +188,7 @@ const processEventBinding = (key, code, nodeName, customArg) => {
187
188
  };
188
189
  };
189
190
  const stringifyBinding = (node, options, blockOptions) => ([key, binding]) => {
190
- var _a;
191
+ var _a, _b;
191
192
  if (key.startsWith('$') || key.startsWith('"') || key === 'key') {
192
193
  return;
193
194
  }
@@ -197,10 +198,15 @@ const stringifyBinding = (node, options, blockOptions) => ([key, binding]) => {
197
198
  const keyToUse = BINDINGS_MAPPER[key] || key;
198
199
  const { code, arguments: cusArgs = ['event'] } = binding;
199
200
  // TODO: proper babel transform to replace. Util for this
200
- if (keyToUse.startsWith('on')) {
201
+ if ((0, event_handlers_1.checkIsEvent)(keyToUse)) {
201
202
  const { event, value } = processEventBinding(keyToUse, code, node.name, cusArgs[0]);
202
- // Angular events are all lowerCased
203
- return ` (${event.toLowerCase()})="${value}"`;
203
+ // native events are all lowerCased
204
+ const lowerCaseEvent = event.toLowerCase();
205
+ const eventKey = (0, event_handlers_1.checkIsBindingNativeEvent)(event) ||
206
+ ((_a = blockOptions.nativeEvents) === null || _a === void 0 ? void 0 : _a.find((nativeEvent) => nativeEvent === keyToUse || nativeEvent === event || nativeEvent === lowerCaseEvent))
207
+ ? lowerCaseEvent
208
+ : event;
209
+ return ` (${eventKey})="${value}"`;
204
210
  }
205
211
  else if (keyToUse === 'class') {
206
212
  return ` [class]="${code}" `;
@@ -209,7 +215,7 @@ const stringifyBinding = (node, options, blockOptions) => ([key, binding]) => {
209
215
  return ` #${code} `;
210
216
  }
211
217
  else if ((html_tags_1.VALID_HTML_TAGS.includes(node.name.trim()) || keyToUse.includes('-')) &&
212
- !((_a = blockOptions.nativeAttributes) === null || _a === void 0 ? void 0 : _a.includes(keyToUse)) &&
218
+ !((_b = blockOptions.nativeAttributes) === null || _b === void 0 ? void 0 : _b.includes(keyToUse)) &&
213
219
  !Object.values(BINDINGS_MAPPER).includes(keyToUse)) {
214
220
  // standard html elements need the attr to satisfy the compiler in many cases: eg: svg elements and [fill]
215
221
  return ` [attr.${keyToUse}]="${code}" `;
@@ -249,7 +255,7 @@ const handleNgOutletBindings = (node, options) => {
249
255
  }
250
256
  let keyToUse = key.includes('-') ? `'${key}'` : key;
251
257
  keyToUse = keyToUse.replace('state.', '').replace('props.', '');
252
- if (key.startsWith('on')) {
258
+ if ((0, event_handlers_1.checkIsEvent)(key)) {
253
259
  const { event, value } = processEventBinding(key, code, node.name, cusArgs[0]);
254
260
  allProps += `on${event.charAt(0).toUpperCase() + event.slice(1)}: ${value.replace(/\(.*?\)/g, '')}.bind(this), `;
255
261
  }
@@ -268,8 +274,9 @@ const handleNgOutletBindings = (node, options) => {
268
274
  };
269
275
  const blockToAngular = ({ root, json, options = {}, blockOptions = {
270
276
  nativeAttributes: [],
277
+ nativeEvents: [],
271
278
  }, }) => {
272
- var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o, _p, _q, _r;
279
+ var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o, _p, _q;
273
280
  const childComponents = (blockOptions === null || blockOptions === void 0 ? void 0 : blockOptions.childComponents) || [];
274
281
  if (mappers[json.name]) {
275
282
  return mappers[json.name](root, json, options, blockOptions);
@@ -296,19 +303,19 @@ const blockToAngular = ({ root, json, options = {}, blockOptions = {
296
303
  const indexName = json.scope.indexName;
297
304
  const forName = json.scope.forName;
298
305
  // Check if "key" is present for the first child of the for loop
299
- if (json.children[0].bindings && ((_b = json.children[0].bindings.key) === null || _b === void 0 ? void 0 : _b.code)) {
300
- const fnIndex = ((_c = root.meta) === null || _c === void 0 ? void 0 : _c._trackByForIndex) || 0;
306
+ if ((0, helpers_2.hasFirstChildKeyAttribute)(json)) {
307
+ const fnIndex = ((_b = root.meta) === null || _b === void 0 ? void 0 : _b._trackByForIndex) || 0;
301
308
  const trackByFnName = `trackBy${forName ? forName.charAt(0).toUpperCase() + forName.slice(1) : ''}${fnIndex}`;
302
309
  root.meta._trackByForIndex = fnIndex + 1;
303
- let code = (_d = json.children[0].bindings.key) === null || _d === void 0 ? void 0 : _d.code;
310
+ let code = (_c = json.children[0].bindings.key) === null || _c === void 0 ? void 0 : _c.code;
304
311
  root.state[trackByFnName] = {
305
312
  code: `${trackByFnName}(${indexName !== null && indexName !== void 0 ? indexName : '_'}, ${forName}) { return ${code}; }`,
306
313
  type: 'method',
307
314
  };
308
- str += `<ng-container *ngFor="let ${forName !== null && forName !== void 0 ? forName : '_'} of ${(_e = json.bindings.each) === null || _e === void 0 ? void 0 : _e.code}${indexName ? `; index as ${indexName}` : ''}; trackBy: ${trackByFnName}">`;
315
+ str += `<ng-container *ngFor="let ${forName !== null && forName !== void 0 ? forName : '_'} of ${(_d = json.bindings.each) === null || _d === void 0 ? void 0 : _d.code}${indexName ? `; index as ${indexName}` : ''}; trackBy: ${trackByFnName}">`;
309
316
  }
310
317
  else {
311
- str += `<ng-container *ngFor="let ${forName !== null && forName !== void 0 ? forName : '_'} of ${(_f = json.bindings.each) === null || _f === void 0 ? void 0 : _f.code}${indexName ? `; index as ${indexName}` : ''}">`;
318
+ str += `<ng-container *ngFor="let ${forName !== null && forName !== void 0 ? forName : '_'} of ${(_e = json.bindings.each) === null || _e === void 0 ? void 0 : _e.code}${indexName ? `; index as ${indexName}` : ''}">`;
312
319
  }
313
320
  str += json.children
314
321
  .map((item) => (0, exports.blockToAngular)({ root, json: item, options, blockOptions }))
@@ -316,7 +323,7 @@ const blockToAngular = ({ root, json, options = {}, blockOptions = {
316
323
  str += `</ng-container>`;
317
324
  }
318
325
  else if (json.name === 'Show') {
319
- let condition = (_g = json.bindings.when) === null || _g === void 0 ? void 0 : _g.code;
326
+ let condition = (_f = json.bindings.when) === null || _f === void 0 ? void 0 : _f.code;
320
327
  if (options.state === 'inline-with-wrappers' && (condition === null || condition === void 0 ? void 0 : condition.includes('typeof'))) {
321
328
  let wordAfterTypeof = condition.split('typeof')[1].trim().split(' ')[0];
322
329
  condition = condition.replace(`typeof ${wordAfterTypeof}`, `useTypeOf(${wordAfterTypeof})`);
@@ -327,7 +334,7 @@ const blockToAngular = ({ root, json, options = {}, blockOptions = {
327
334
  .join('\n');
328
335
  str += `</ng-container>`;
329
336
  // else condition
330
- if ((0, is_mitosis_node_1.isMitosisNode)((_h = json.meta) === null || _h === void 0 ? void 0 : _h.else)) {
337
+ if ((0, is_mitosis_node_1.isMitosisNode)((_g = json.meta) === null || _g === void 0 ? void 0 : _g.else)) {
331
338
  str += `<ng-container *ngIf="!(${condition})">`;
332
339
  str += (0, exports.blockToAngular)({ root, json: json.meta.else, options, blockOptions });
333
340
  str += `</ng-container>`;
@@ -344,10 +351,10 @@ const blockToAngular = ({ root, json, options = {}, blockOptions = {
344
351
  code: '{}' + (options.typescript ? ' as any' : ''),
345
352
  type: 'property',
346
353
  };
347
- if (!((_j = root.hooks.onInit) === null || _j === void 0 ? void 0 : _j.code.includes(inputsPropsStateName))) {
354
+ if (!((_h = root.hooks.onInit) === null || _h === void 0 ? void 0 : _h.code.includes(inputsPropsStateName))) {
348
355
  (0, helpers_2.addCodeToOnInit)(root, `this.${inputsPropsStateName} = {${allProps}};`);
349
356
  }
350
- if (!((_k = root.hooks.onUpdate) === null || _k === void 0 ? void 0 : _k.map((hook) => hook.code).join('').includes(inputsPropsStateName))) {
357
+ if (!((_j = root.hooks.onUpdate) === null || _j === void 0 ? void 0 : _j.map((hook) => hook.code).join('').includes(inputsPropsStateName))) {
351
358
  (0, helpers_2.addCodeToOnUpdate)(root, `this.${inputsPropsStateName} = {${allProps}};`);
352
359
  }
353
360
  allProps = `${inputsPropsStateName}`;
@@ -371,7 +378,7 @@ const blockToAngular = ({ root, json, options = {}, blockOptions = {
371
378
  try {
372
379
  ({ element, classNames, attributes } = (0, parse_selector_1.parse)(`${selector}`));
373
380
  }
374
- catch (_s) {
381
+ catch (_r) {
375
382
  element = (0, lodash_1.kebabCase)(json.name);
376
383
  }
377
384
  }
@@ -406,13 +413,13 @@ const blockToAngular = ({ root, json, options = {}, blockOptions = {
406
413
  str += ` ${key}="${value}" `;
407
414
  }
408
415
  for (const key in json.bindings) {
409
- if (((_l = json.bindings[key]) === null || _l === void 0 ? void 0 : _l.type) === 'spread' && html_tags_1.VALID_HTML_TAGS.includes(json.name.trim())) {
410
- if (((_m = json.bindings[key]) === null || _m === void 0 ? void 0 : _m.code) === 'this') {
416
+ if (((_k = json.bindings[key]) === null || _k === void 0 ? void 0 : _k.type) === 'spread' && html_tags_1.VALID_HTML_TAGS.includes(json.name.trim())) {
417
+ if (((_l = json.bindings[key]) === null || _l === void 0 ? void 0 : _l.code) === 'this') {
411
418
  // if its an arbitrary { ...props } spread then we skip because Angular needs a named prop to be defined
412
419
  continue;
413
420
  }
414
421
  let refName = '';
415
- if ((_o = json.bindings['spreadRef']) === null || _o === void 0 ? void 0 : _o.code) {
422
+ if ((_m = json.bindings['spreadRef']) === null || _m === void 0 ? void 0 : _m.code) {
416
423
  refName = json.bindings['spreadRef'].code;
417
424
  }
418
425
  else {
@@ -427,16 +434,16 @@ const blockToAngular = ({ root, json, options = {}, blockOptions = {
427
434
  root.meta.onViewInit = (root.meta.onViewInit || { code: '' });
428
435
  let spreadCode = '';
429
436
  let changesCode = '';
430
- if ((_p = json.bindings[key]) === null || _p === void 0 ? void 0 : _p.code.startsWith('{')) {
437
+ if ((_o = json.bindings[key]) === null || _o === void 0 ? void 0 : _o.code.startsWith('{')) {
431
438
  json.meta._spreadStateRef = json.meta._spreadStateRef || 0;
432
439
  const name = `${refName}_state_${json.meta._spreadStateRef}`;
433
440
  json.meta._spreadStateRef = json.meta._spreadStateRef + 1;
434
- (0, helpers_2.makeReactiveState)(root, name, `this.${name} = ${(_q = json.bindings[key]) === null || _q === void 0 ? void 0 : _q.code};`);
441
+ (0, helpers_2.makeReactiveState)(root, name, `this.${name} = ${(_p = json.bindings[key]) === null || _p === void 0 ? void 0 : _p.code};`);
435
442
  spreadCode = `this.${name}`;
436
443
  changesCode = `changes['${spreadCode.replace('this.', '')}']?.currentValue`;
437
444
  }
438
445
  else {
439
- spreadCode = `${(_r = json.bindings[key]) === null || _r === void 0 ? void 0 : _r.code}`;
446
+ spreadCode = `${(_q = json.bindings[key]) === null || _q === void 0 ? void 0 : _q.code}`;
440
447
  changesCode = `changes['${spreadCode.replace('this.', '')}']?.currentValue`;
441
448
  }
442
449
  if (!root.compileContext) {
@@ -542,7 +549,7 @@ const handleBindings = (json, item, index, forName, indexName) => {
542
549
  continue;
543
550
  if (key === 'key')
544
551
  continue;
545
- if (key.startsWith('on')) {
552
+ if ((0, event_handlers_1.checkIsEvent)(key)) {
546
553
  const { arguments: cusArgs = ['event'] } = item.bindings[key];
547
554
  const eventBindingName = `${generateNewBindingName(index, item.name)}_event`;
548
555
  if (((_a = item.bindings[key]) === null || _a === void 0 ? void 0 : _a.code.trim().startsWith('{')) &&
@@ -570,12 +577,12 @@ const handleBindings = (json, item, index, forName, indexName) => {
570
577
  }
571
578
  }
572
579
  else if ((_c = item.bindings[key]) === null || _c === void 0 ? void 0 : _c.code) {
573
- if (((_d = item.bindings[key]) === null || _d === void 0 ? void 0 : _d.type) !== 'spread' && !key.startsWith('on')) {
580
+ if (((_d = item.bindings[key]) === null || _d === void 0 ? void 0 : _d.type) !== 'spread' && !(0, event_handlers_1.checkIsEvent)(key)) {
574
581
  json.state[newBindingName] = { code: 'null', type: 'property' };
575
582
  (0, helpers_2.makeReactiveState)(json, newBindingName, `this.${newBindingName} = ${item.bindings[key].code}`);
576
583
  item.bindings[key].code = `state.${newBindingName}`;
577
584
  }
578
- else if (key.startsWith('on')) {
585
+ else if ((0, event_handlers_1.checkIsEvent)(key)) {
579
586
  const { arguments: cusArgs = ['event'] } = item.bindings[key];
580
587
  if (((_e = item.bindings[key]) === null || _e === void 0 ? void 0 : _e.code.trim().startsWith('{')) &&
581
588
  ((_f = item.bindings[key]) === null || _f === void 0 ? void 0 : _f.code.trim().endsWith('}'))) {
@@ -646,7 +653,7 @@ const classPropertiesPlugin = () => ({
646
653
  },
647
654
  });
648
655
  const componentToAngular = (userOptions = {}) => ({ component: _component }) => {
649
- var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o, _p, _q, _r, _s, _t;
656
+ var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o, _p, _q, _r, _s, _t, _u, _v;
650
657
  // Make a copy we can safely mutate, similar to babel's toolchain
651
658
  let json = (0, fast_clone_1.fastClone)(_component);
652
659
  const useMetadata = (_a = json.meta) === null || _a === void 0 ? void 0 : _a.useMetadata;
@@ -687,11 +694,14 @@ const componentToAngular = (userOptions = {}) => ({ component: _component }) =>
687
694
  // so we need to use `this.` inside the class to access state and props
688
695
  const isSpreadAttributeBinding = ((_a = node === null || node === void 0 ? void 0 : node.bindings[key]) === null || _a === void 0 ? void 0 : _a.type) === 'spread' &&
689
696
  html_tags_1.VALID_HTML_TAGS.includes(node.name.trim());
697
+ // If we have a For loop with "key" it will be transformed to
698
+ // trackOfXXX, we need to use "this" for state properties
699
+ const isKey = key === 'key';
690
700
  const newLocal = processAngularCode({
691
701
  contextVars: [],
692
702
  outputVars,
693
703
  domRefs: [], // the template doesn't need the this keyword.
694
- replaceWith: isSpreadAttributeBinding ? 'this' : undefined,
704
+ replaceWith: isKey || isSpreadAttributeBinding ? 'this' : undefined,
695
705
  })(code);
696
706
  return newLocal.replace(/"/g, '&quot;');
697
707
  };
@@ -767,7 +777,7 @@ const componentToAngular = (userOptions = {}) => ({ component: _component }) =>
767
777
  const helperFunctions = new Set();
768
778
  let template = json.children
769
779
  .map((item) => {
770
- var _a, _b;
780
+ var _a, _b, _c, _d;
771
781
  const tmpl = (0, exports.blockToAngular)({
772
782
  root: json,
773
783
  json: item,
@@ -775,6 +785,7 @@ const componentToAngular = (userOptions = {}) => ({ component: _component }) =>
775
785
  blockOptions: {
776
786
  childComponents,
777
787
  nativeAttributes: (_b = (_a = useMetadata === null || useMetadata === void 0 ? void 0 : useMetadata.angular) === null || _a === void 0 ? void 0 : _a.nativeAttributes) !== null && _b !== void 0 ? _b : [],
788
+ nativeEvents: (_d = (_c = useMetadata === null || useMetadata === void 0 ? void 0 : useMetadata.angular) === null || _c === void 0 ? void 0 : _c.nativeEvents) !== null && _d !== void 0 ? _d : [],
778
789
  },
779
790
  });
780
791
  if (options.state === 'inline-with-wrappers') {
@@ -790,6 +801,7 @@ const componentToAngular = (userOptions = {}) => ({ component: _component }) =>
790
801
  const { components: dynamicComponents, dynamicTemplate } = traverseToGetAllDynamicComponents(json, options, {
791
802
  childComponents,
792
803
  nativeAttributes: (_d = (_c = useMetadata === null || useMetadata === void 0 ? void 0 : useMetadata.angular) === null || _c === void 0 ? void 0 : _c.nativeAttributes) !== null && _d !== void 0 ? _d : [],
804
+ nativeEvents: (_f = (_e = useMetadata === null || useMetadata === void 0 ? void 0 : useMetadata.angular) === null || _e === void 0 ? void 0 : _e.nativeEvents) !== null && _f !== void 0 ? _f : [],
793
805
  });
794
806
  (0, helpers_2.transformState)(json);
795
807
  const dataString = (0, get_state_object_string_1.getStateObjectStringFromComponent)(json, {
@@ -813,8 +825,8 @@ const componentToAngular = (userOptions = {}) => ({ component: _component }) =>
813
825
  const styles = css.length ? [hostDisplayCss, css].join('\n') : hostDisplayCss;
814
826
  // Preparing built in component metadata parameters
815
827
  const componentMetadata = {
816
- selector: ((_e = useMetadata === null || useMetadata === void 0 ? void 0 : useMetadata.angular) === null || _e === void 0 ? void 0 : _e.selector)
817
- ? `'${(_f = useMetadata === null || useMetadata === void 0 ? void 0 : useMetadata.angular) === null || _f === void 0 ? void 0 : _f.selector}'`
828
+ selector: ((_g = useMetadata === null || useMetadata === void 0 ? void 0 : useMetadata.angular) === null || _g === void 0 ? void 0 : _g.selector)
829
+ ? `'${(_h = useMetadata === null || useMetadata === void 0 ? void 0 : useMetadata.angular) === null || _h === void 0 ? void 0 : _h.selector}'`
818
830
  : `'${(0, lodash_1.kebabCase)(json.name || 'my-component')}'`,
819
831
  template: `\`
820
832
  ${(0, indent_1.indent)(dynamicTemplate, 8).replace(/`/g, '\\`').replace(/\$\{/g, '\\${')}
@@ -840,7 +852,7 @@ const componentToAngular = (userOptions = {}) => ({ component: _component }) =>
840
852
  const hasConstructor = Boolean(injectables.length) || dynamicComponents.size || refsForObjSpread.size;
841
853
  const angularCoreImports = [
842
854
  ...(outputs.length ? ['Output', 'EventEmitter'] : []),
843
- ...(((_g = options === null || options === void 0 ? void 0 : options.experimental) === null || _g === void 0 ? void 0 : _g.inject) ? ['Inject', 'forwardRef'] : []),
855
+ ...(((_j = options === null || options === void 0 ? void 0 : options.experimental) === null || _j === void 0 ? void 0 : _j.inject) ? ['Inject', 'forwardRef'] : []),
844
856
  'Component',
845
857
  ...(domRefs.size || dynamicComponents.size || refsForObjSpread.size
846
858
  ? ['ViewChild', 'ElementRef']
@@ -848,7 +860,7 @@ const componentToAngular = (userOptions = {}) => ({ component: _component }) =>
848
860
  ...(refsForObjSpread.size ? ['Renderer2'] : []),
849
861
  ...(props.size ? ['Input'] : []),
850
862
  ...(dynamicComponents.size ? ['ViewContainerRef', 'TemplateRef'] : []),
851
- ...(((_h = json.hooks.onUpdate) === null || _h === void 0 ? void 0 : _h.length) && options.typescript ? ['SimpleChanges'] : []),
863
+ ...(((_k = json.hooks.onUpdate) === null || _k === void 0 ? void 0 : _k.length) && options.typescript ? ['SimpleChanges'] : []),
852
864
  ].join(', ');
853
865
  let str = (0, dedent_1.dedent) `
854
866
  import { ${angularCoreImports} } from '@angular/core';
@@ -937,13 +949,13 @@ const componentToAngular = (userOptions = {}) => ({ component: _component }) =>
937
949
  ? `\nprivate renderer${options.typescript ? ': Renderer2' : ''},\n`
938
950
  : ''}) {}
939
951
  `}
940
- ${!json.hooks.onMount.length && !dynamicComponents.size && !((_j = json.hooks.onInit) === null || _j === void 0 ? void 0 : _j.code)
952
+ ${!json.hooks.onMount.length && !dynamicComponents.size && !((_l = json.hooks.onInit) === null || _l === void 0 ? void 0 : _l.code)
941
953
  ? ''
942
954
  : `ngOnInit() {
943
- ${!((_k = json.hooks) === null || _k === void 0 ? void 0 : _k.onInit)
955
+ ${!((_m = json.hooks) === null || _m === void 0 ? void 0 : _m.onInit)
944
956
  ? ''
945
957
  : `
946
- ${(_l = json.hooks.onInit) === null || _l === void 0 ? void 0 : _l.code}
958
+ ${(_o = json.hooks.onInit) === null || _o === void 0 ? void 0 : _o.code}
947
959
  `}
948
960
  ${json.hooks.onMount.length > 0
949
961
  ? `
@@ -965,19 +977,19 @@ const componentToAngular = (userOptions = {}) => ({ component: _component }) =>
965
977
 
966
978
  ${
967
979
  // hooks specific to Angular
968
- ((_o = (_m = json.compileContext) === null || _m === void 0 ? void 0 : _m.angular) === null || _o === void 0 ? void 0 : _o.hooks)
969
- ? Object.entries((_q = (_p = json.compileContext) === null || _p === void 0 ? void 0 : _p.angular) === null || _q === void 0 ? void 0 : _q.hooks).map(([key, value]) => {
980
+ ((_q = (_p = json.compileContext) === null || _p === void 0 ? void 0 : _p.angular) === null || _q === void 0 ? void 0 : _q.hooks)
981
+ ? Object.entries((_s = (_r = json.compileContext) === null || _r === void 0 ? void 0 : _r.angular) === null || _s === void 0 ? void 0 : _s.hooks).map(([key, value]) => {
970
982
  return `${key}() {
971
983
  ${value.code}
972
984
  }`;
973
985
  })
974
986
  : ''}
975
987
 
976
- ${!((_r = json.hooks.onUpdate) === null || _r === void 0 ? void 0 : _r.length)
988
+ ${!((_t = json.hooks.onUpdate) === null || _t === void 0 ? void 0 : _t.length)
977
989
  ? ''
978
990
  : `ngOnChanges(changes${options.typescript ? ': SimpleChanges' : ''}) {
979
991
  if (typeof window !== 'undefined') {
980
- ${(_s = json.hooks.onUpdate) === null || _s === void 0 ? void 0 : _s.reduce((code, hook) => {
992
+ ${(_u = json.hooks.onUpdate) === null || _u === void 0 ? void 0 : _u.reduce((code, hook) => {
981
993
  code += hook.code;
982
994
  return code + '\n';
983
995
  }, '')}
@@ -988,7 +1000,7 @@ const componentToAngular = (userOptions = {}) => ({ component: _component }) =>
988
1000
  ${!json.hooks.onUnMount && !refsForObjSpread.size
989
1001
  ? ''
990
1002
  : `ngOnDestroy() {
991
- ${((_t = json.hooks.onUnMount) === null || _t === void 0 ? void 0 : _t.code) || ''}
1003
+ ${((_v = json.hooks.onUnMount) === null || _v === void 0 ? void 0 : _v.code) || ''}
992
1004
  ${refsForObjSpread.size
993
1005
  ? `for (const fn of this._listenerFns.values()) { fn(); }`
994
1006
  : ''}
@@ -17,7 +17,19 @@ export interface ToAngularOptions extends BaseTranspilerOptions {
17
17
  }
18
18
  export declare const DEFAULT_ANGULAR_OPTIONS: ToAngularOptions;
19
19
  export type AngularMetadata = {
20
+ /**
21
+ * Mitosis uses `attr.XXX` as default see https://angular.io/guide/attribute-binding.
22
+ * If you want to skip some you can use the 'nativeAttributes'.
23
+ */
20
24
  nativeAttributes?: string[];
25
+ /**
26
+ * If you encounter some native events which aren't generated in lower-case.
27
+ * Create a new PR inside [event-handlers.ts](https://github.com/BuilderIO/mitosis/blob/main/packages/core/src/helpers/event-handlers.ts) to fix it for all.
28
+ */
29
+ nativeEvents?: string[];
30
+ /**
31
+ * Overwrite default selector for component. Default will be kebab case (MyComponent -> my-component)
32
+ */
21
33
  selector?: string;
22
34
  };
23
35
  export type AngularBlockOptions = {
@@ -1,2 +1,2 @@
1
- import { Plugin } from '../../modules/plugins';
2
- export declare const FUNCTION_HACK_PLUGIN: Plugin;
1
+ import { MitosisPlugin } from '../../modules/plugins';
2
+ export declare const FUNCTION_HACK_PLUGIN: MitosisPlugin;
@@ -4,6 +4,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
4
4
  };
5
5
  Object.defineProperty(exports, "__esModule", { value: true });
6
6
  exports.checkIfIsClientComponent = void 0;
7
+ const event_handlers_1 = require("../../helpers/event-handlers");
7
8
  const is_mitosis_node_1 = require("../../helpers/is-mitosis-node");
8
9
  const legacy_1 = __importDefault(require("neotraverse/legacy"));
9
10
  const checkIsNodeAMitosisComponent = (node) => node.name[0] === node.name[0].toUpperCase();
@@ -26,7 +27,7 @@ const checkIfIsClientComponent = (json) => {
26
27
  let foundEventListener = false;
27
28
  (0, legacy_1.default)(json).forEach(function (node) {
28
29
  if ((0, is_mitosis_node_1.isMitosisNode)(node) && !checkIsNodeAMitosisComponent(node)) {
29
- if (Object.keys(node.bindings).filter((item) => item.startsWith('on')).length) {
30
+ if (Object.keys(node.bindings).filter((item) => (0, event_handlers_1.checkIsEvent)(item)).length) {
30
31
  foundEventListener = true;
31
32
  this.stop();
32
33
  }
@@ -4,14 +4,10 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
4
4
  };
5
5
  Object.defineProperty(exports, "__esModule", { value: true });
6
6
  exports.componentToCustomElement = exports.componentToHtml = void 0;
7
- const core_1 = require("@babel/core");
8
- const function_1 = require("fp-ts/lib/function");
9
- const lodash_1 = require("lodash");
10
- const legacy_1 = __importDefault(require("neotraverse/legacy"));
11
- const standalone_1 = require("prettier/standalone");
12
7
  const html_tags_1 = require("../../constants/html_tags");
13
8
  const babel_transform_1 = require("../../helpers/babel-transform");
14
9
  const dash_case_1 = require("../../helpers/dash-case");
10
+ const event_handlers_1 = require("../../helpers/event-handlers");
15
11
  const fast_clone_1 = require("../../helpers/fast-clone");
16
12
  const get_prop_functions_1 = require("../../helpers/get-prop-functions");
17
13
  const get_props_1 = require("../../helpers/get-props");
@@ -22,7 +18,6 @@ const has_bindings_text_1 = require("../../helpers/has-bindings-text");
22
18
  const has_component_1 = require("../../helpers/has-component");
23
19
  const has_props_1 = require("../../helpers/has-props");
24
20
  const has_stateful_dom_1 = require("../../helpers/has-stateful-dom");
25
- const is_children_1 = __importDefault(require("../../helpers/is-children"));
26
21
  const is_html_attribute_1 = require("../../helpers/is-html-attribute");
27
22
  const is_mitosis_node_1 = require("../../helpers/is-mitosis-node");
28
23
  const map_refs_1 = require("../../helpers/map-refs");
@@ -35,6 +30,12 @@ const strip_state_and_props_refs_1 = require("../../helpers/strip-state-and-prop
35
30
  const collect_css_1 = require("../../helpers/styles/collect-css");
36
31
  const plugins_1 = require("../../modules/plugins");
37
32
  const mitosis_node_1 = require("../../types/mitosis-node");
33
+ const core_1 = require("@babel/core");
34
+ const function_1 = require("fp-ts/lib/function");
35
+ const lodash_1 = require("lodash");
36
+ const legacy_1 = __importDefault(require("neotraverse/legacy"));
37
+ const is_children_1 = __importDefault(require("../../helpers/is-children"));
38
+ const standalone_1 = require("prettier/standalone");
38
39
  const on_mount_1 = require("../helpers/on-mount");
39
40
  const isAttribute = (key) => {
40
41
  return /-/.test(key);
@@ -295,7 +296,7 @@ const blockToHtml = (json, options, blockOptions = {}) => {
295
296
  const cusArg = ((_g = json.bindings[key]) === null || _g === void 0 ? void 0 : _g.arguments) || ['event'];
296
297
  // TODO: proper babel transform to replace. Util for this
297
298
  const useValue = value;
298
- if (key.startsWith('on')) {
299
+ if ((0, event_handlers_1.checkIsEvent)(key)) {
299
300
  let event = key.replace('on', '').toLowerCase();
300
301
  const fnName = (0, lodash_1.camelCase)(`on-${elId}-${event}`);
301
302
  const codeContent = (0, remove_surrounding_block_1.removeSurroundingBlock)(updateReferencesInCode(useValue, options, blockOptions));
@@ -1,6 +1,7 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.componentToLiquid = exports.isValidLiquidBinding = void 0;
4
+ const event_handlers_1 = require("../../helpers/event-handlers");
4
5
  const standalone_1 = require("prettier/standalone");
5
6
  const html_tags_1 = require("../../constants/html_tags");
6
7
  const fast_clone_1 = require("../../helpers/fast-clone");
@@ -89,7 +90,7 @@ const blockToLiquid = (json, options = {}) => {
89
90
  const { code: value } = json.bindings[key];
90
91
  // TODO: proper babel transform to replace. Util for this
91
92
  const useValue = (0, strip_state_and_props_refs_1.stripStateAndPropsRefs)(value);
92
- if (key.startsWith('on')) {
93
+ if ((0, event_handlers_1.checkIsEvent)(key)) {
93
94
  // Do nothing
94
95
  }
95
96
  else if ((0, exports.isValidLiquidBinding)(useValue)) {
@@ -3,6 +3,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.componentToLit = void 0;
4
4
  const dash_case_1 = require("../../helpers/dash-case");
5
5
  const dedent_1 = require("../../helpers/dedent");
6
+ const event_handlers_1 = require("../../helpers/event-handlers");
6
7
  const fast_clone_1 = require("../../helpers/fast-clone");
7
8
  const filter_empty_text_nodes_1 = require("../../helpers/filter-empty-text-nodes");
8
9
  const get_props_1 = require("../../helpers/get-props");
@@ -80,7 +81,7 @@ const blockToLit = (json, options = {}) => {
80
81
  // https://lit.dev/docs/templates/directives/#ref
81
82
  str += ` ref="${code}" `;
82
83
  }
83
- else if (key.startsWith('on')) {
84
+ else if ((0, event_handlers_1.checkIsEvent)(key)) {
84
85
  const asyncKeyword = ((_g = json.bindings[key]) === null || _g === void 0 ? void 0 : _g.async) ? 'async ' : '';
85
86
  const useKey = '@' + key.substring(2).toLowerCase();
86
87
  str += ` ${useKey}=\${${asyncKeyword}(${cusArgs.join(',')}) => ${processBinding(code)}} `;
@@ -7,6 +7,7 @@ exports.markoFormatHtml = exports.postprocessHtml = exports.preprocessHtml = exp
7
7
  const html_tags_1 = require("../../constants/html_tags");
8
8
  const dash_case_1 = require("../../helpers/dash-case");
9
9
  const dedent_1 = require("../../helpers/dedent");
10
+ const event_handlers_1 = require("../../helpers/event-handlers");
10
11
  const fast_clone_1 = require("../../helpers/fast-clone");
11
12
  const filter_empty_text_nodes_1 = require("../../helpers/filter-empty-text-nodes");
12
13
  const get_refs_1 = require("../../helpers/get-refs");
@@ -76,7 +77,7 @@ const blockToMarko = (json, options) => {
76
77
  else if (key === 'ref') {
77
78
  str += ` key="${(0, lodash_1.camelCase)(code)}" `;
78
79
  }
79
- else if (key.startsWith('on')) {
80
+ else if ((0, event_handlers_1.checkIsEvent)(key)) {
80
81
  const asyncKeyword = async ? 'async ' : '';
81
82
  const useKey = key === 'onChange' && json.name === 'input' ? 'onInput' : key;
82
83
  str += ` ${(0, dash_case_1.dashCase)(useKey)}=(${asyncKeyword}(${cusArgs.join(',')}) => ${processBinding(options.component, code)}) `;
@@ -4,22 +4,23 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
4
4
  };
5
5
  Object.defineProperty(exports, "__esModule", { value: true });
6
6
  exports.componentToMitosis = exports.blockToMitosis = exports.DEFAULT_FORMAT = void 0;
7
- const is_mitosis_node_1 = require("../../helpers/is-mitosis-node");
8
- const plugins_1 = require("../../modules/plugins");
9
- const json5_1 = __importDefault(require("json5"));
10
- const standalone_1 = require("prettier/standalone");
11
7
  const hooks_1 = require("../../constants/hooks");
12
8
  const html_tags_1 = require("../../constants/html_tags");
13
9
  const dedent_1 = require("../../helpers/dedent");
10
+ const event_handlers_1 = require("../../helpers/event-handlers");
14
11
  const fast_clone_1 = require("../../helpers/fast-clone");
15
12
  const get_components_1 = require("../../helpers/get-components");
16
13
  const get_refs_1 = require("../../helpers/get-refs");
17
14
  const get_state_object_string_1 = require("../../helpers/get-state-object-string");
15
+ const is_mitosis_node_1 = require("../../helpers/is-mitosis-node");
18
16
  const is_root_text_node_1 = require("../../helpers/is-root-text-node");
19
17
  const map_refs_1 = require("../../helpers/map-refs");
20
18
  const render_imports_1 = require("../../helpers/render-imports");
21
19
  const state_1 = require("../../helpers/state");
20
+ const plugins_1 = require("../../modules/plugins");
22
21
  const mitosis_node_1 = require("../../types/mitosis-node");
22
+ const json5_1 = __importDefault(require("json5"));
23
+ const standalone_1 = require("prettier/standalone");
23
24
  const react_1 = require("../react");
24
25
  exports.DEFAULT_FORMAT = 'legacy';
25
26
  // Special isValidAttributeName for Mitosis so we can allow for $ in names
@@ -120,7 +121,7 @@ const blockToMitosis = (json, toMitosisOptions = {}, component, insideJsx) => {
120
121
  if (((_g = json.bindings[key]) === null || _g === void 0 ? void 0 : _g.type) === 'spread') {
121
122
  str += ` {...(${(_h = json.bindings[key]) === null || _h === void 0 ? void 0 : _h.code})} `;
122
123
  }
123
- else if (key.startsWith('on')) {
124
+ else if ((0, event_handlers_1.checkIsEvent)(key)) {
124
125
  const { arguments: cusArgs = ['event'], async } = json.bindings[key];
125
126
  const asyncKeyword = async ? 'async ' : '';
126
127
  str += ` ${key}={${asyncKeyword}(${cusArgs.join(',')}) => ${value.replace(/\s*;$/, '')}} `;
@@ -4,8 +4,9 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
4
4
  };
5
5
  Object.defineProperty(exports, "__esModule", { value: true });
6
6
  exports.addPreventDefault = void 0;
7
- const legacy_1 = __importDefault(require("neotraverse/legacy"));
7
+ const event_handlers_1 = require("../../../helpers/event-handlers");
8
8
  const is_mitosis_node_1 = require("../../../helpers/is-mitosis-node");
9
+ const legacy_1 = __importDefault(require("neotraverse/legacy"));
9
10
  /**
10
11
  * Find event handlers that explicitly call .preventDefault() and
11
12
  * add preventdefault:event
@@ -17,7 +18,7 @@ function addPreventDefault(json) {
17
18
  if ((0, is_mitosis_node_1.isMitosisNode)(node)) {
18
19
  if (node.bindings) {
19
20
  for (const key of Object.keys(node.bindings)) {
20
- if (key.startsWith('on')) {
21
+ if ((0, event_handlers_1.checkIsEvent)(key)) {
21
22
  if ((_a = node.bindings[key]) === null || _a === void 0 ? void 0 : _a.code.includes('.preventDefault()')) {
22
23
  const event = key.slice(2).toLowerCase();
23
24
  node.properties['preventdefault:' + event] = '';
@@ -1,6 +1,7 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.renderHandlers = void 0;
4
+ const event_handlers_1 = require("../../../helpers/event-handlers");
4
5
  const component_1 = require("../component");
5
6
  const src_generator_1 = require("../src-generator");
6
7
  const IIF_START = '(() => {';
@@ -55,5 +56,5 @@ function renderHandler(file, symbol, code) {
55
56
  });
56
57
  }
57
58
  function isEventName(name) {
58
- return name.startsWith('on') && name.charAt(2).toUpperCase() == name.charAt(2);
59
+ return (0, event_handlers_1.checkIsEvent)(name) && name.charAt(2).toUpperCase() == name.charAt(2);
59
60
  }