@builder.io/mitosis 0.9.2 → 0.9.4
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.
- package/dist/src/generators/swift/blocks.d.ts +8 -0
- package/dist/src/generators/swift/blocks.js +304 -0
- package/dist/src/generators/swift/generator.d.ts +1 -1
- package/dist/src/generators/swift/generator.js +256 -303
- package/dist/src/generators/swift/helpers.d.ts +42 -0
- package/dist/src/generators/swift/helpers.js +377 -0
- package/dist/src/generators/swift/types.d.ts +25 -0
- package/dist/src/parsers/builder/builder.js +2 -3
- package/dist/src/parsers/jsx/element-parser.js +9 -0
- package/jsx-runtime.d.ts +5 -0
- package/package.json +1 -1
|
@@ -0,0 +1,377 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.convertJsFunctionToSwift = exports.extractFunctionSignature = exports.getBindingType = exports.camelToSnakeCase = exports.getForEachParams = exports.isForEachBlock = exports.needsScrollView = exports.getEventHandlerName = exports.getStatePropertyTypeAnnotation = exports.cssToSwiftUIModifiers = exports.jsxElementToSwiftUIView = exports.getSwiftType = exports.stripStateAndProps = exports.ensureSwiftStringFormat = exports.convertConsoleLogToPrint = void 0;
|
|
4
|
+
const capitalize_1 = require("../../helpers/capitalize");
|
|
5
|
+
const strip_state_and_props_refs_1 = require("../../helpers/strip-state-and-props-refs");
|
|
6
|
+
// TODO(kyle): use babel here to do ast
|
|
7
|
+
const convertConsoleLogToPrint = (code) => {
|
|
8
|
+
if (!code)
|
|
9
|
+
return code;
|
|
10
|
+
if (code.includes('console.log')) {
|
|
11
|
+
console.log('Converting console.log to print');
|
|
12
|
+
}
|
|
13
|
+
// Match console.log statements with various argument patterns
|
|
14
|
+
return code.replace(/console\.log\s*\(\s*(.*?)\s*\)/g, (match, args) => {
|
|
15
|
+
// Handle empty console.log()
|
|
16
|
+
if (!args.trim()) {
|
|
17
|
+
return 'print()';
|
|
18
|
+
}
|
|
19
|
+
// Simple handling for basic console.log calls
|
|
20
|
+
// For complex cases, we'd need a more sophisticated parser
|
|
21
|
+
return `print(${(0, exports.ensureSwiftStringFormat)(args)})`;
|
|
22
|
+
});
|
|
23
|
+
};
|
|
24
|
+
exports.convertConsoleLogToPrint = convertConsoleLogToPrint;
|
|
25
|
+
// Helper function to ensure Swift strings use double quotes
|
|
26
|
+
const ensureSwiftStringFormat = (code) => {
|
|
27
|
+
if (!code)
|
|
28
|
+
return code;
|
|
29
|
+
// Replace string literals enclosed in single quotes with double quotes
|
|
30
|
+
// This regex looks for single-quoted strings not inside double quotes
|
|
31
|
+
return code.replace(/'([^'\\]*(?:\\.[^'\\]*)*)'(?=(?:[^"]*"[^"]*")*[^"]*$)/g, '"$1"');
|
|
32
|
+
};
|
|
33
|
+
exports.ensureSwiftStringFormat = ensureSwiftStringFormat;
|
|
34
|
+
const stripStateAndProps = ({ json, options, }) => {
|
|
35
|
+
return (code) => {
|
|
36
|
+
// Convert console.log statements to Swift print
|
|
37
|
+
code = (0, exports.convertConsoleLogToPrint)(code);
|
|
38
|
+
// Ensure Swift strings use double quotes
|
|
39
|
+
code = (0, exports.ensureSwiftStringFormat)(code);
|
|
40
|
+
// In Swift, we use self.propertyName for accessing properties
|
|
41
|
+
return (0, strip_state_and_props_refs_1.stripStateAndPropsRefs)(code, {
|
|
42
|
+
includeState: true,
|
|
43
|
+
includeProps: true,
|
|
44
|
+
replaceWith: (name) => {
|
|
45
|
+
// In Swift, we access properties with self.propertyName
|
|
46
|
+
return `self.${name}`;
|
|
47
|
+
},
|
|
48
|
+
});
|
|
49
|
+
};
|
|
50
|
+
};
|
|
51
|
+
exports.stripStateAndProps = stripStateAndProps;
|
|
52
|
+
const getSwiftType = (type) => {
|
|
53
|
+
if (!type)
|
|
54
|
+
return 'Any';
|
|
55
|
+
// Handle array types with proper Swift syntax
|
|
56
|
+
if (type.includes('Array<') || type.includes('[]') || type.toLowerCase().startsWith('array')) {
|
|
57
|
+
// Extract the element type from Array<ElementType>
|
|
58
|
+
let elementType = 'Any';
|
|
59
|
+
// Match different array type patterns
|
|
60
|
+
const arrayMatch = type.match(/Array<([^>]+)>/i) ||
|
|
61
|
+
type.match(/([^[\]]+)\[\]/i) ||
|
|
62
|
+
type.match(/array\s*<([^>]+)>/i);
|
|
63
|
+
if (arrayMatch && arrayMatch[1]) {
|
|
64
|
+
elementType = (0, exports.getSwiftType)(arrayMatch[1].trim());
|
|
65
|
+
}
|
|
66
|
+
// Return Swift array type: [ElementType]
|
|
67
|
+
return `[${elementType}]`;
|
|
68
|
+
}
|
|
69
|
+
// Handle primitive types
|
|
70
|
+
switch (type.toLowerCase()) {
|
|
71
|
+
case 'string':
|
|
72
|
+
return 'String';
|
|
73
|
+
case 'number':
|
|
74
|
+
return 'Double';
|
|
75
|
+
case 'boolean':
|
|
76
|
+
case 'bool':
|
|
77
|
+
return 'Bool';
|
|
78
|
+
case 'any':
|
|
79
|
+
return 'Any';
|
|
80
|
+
case 'void':
|
|
81
|
+
return 'Void';
|
|
82
|
+
case 'object':
|
|
83
|
+
return '[String: Any]';
|
|
84
|
+
case 'null':
|
|
85
|
+
case 'undefined':
|
|
86
|
+
return 'Optional<Any>';
|
|
87
|
+
default:
|
|
88
|
+
// For complex types, return as is with first letter capitalized
|
|
89
|
+
return type.charAt(0).toUpperCase() + type.slice(1);
|
|
90
|
+
}
|
|
91
|
+
};
|
|
92
|
+
exports.getSwiftType = getSwiftType;
|
|
93
|
+
const jsxElementToSwiftUIView = (tagName) => {
|
|
94
|
+
// Map JSX/HTML elements to SwiftUI components
|
|
95
|
+
switch (tagName.toLowerCase()) {
|
|
96
|
+
case 'div':
|
|
97
|
+
return 'VStack';
|
|
98
|
+
case 'span':
|
|
99
|
+
case 'p':
|
|
100
|
+
case 'h1':
|
|
101
|
+
case 'h2':
|
|
102
|
+
case 'h3':
|
|
103
|
+
case 'h4':
|
|
104
|
+
case 'h5':
|
|
105
|
+
case 'h6':
|
|
106
|
+
return 'Text';
|
|
107
|
+
case 'img':
|
|
108
|
+
return 'Image';
|
|
109
|
+
case 'input':
|
|
110
|
+
return 'TextField';
|
|
111
|
+
case 'button':
|
|
112
|
+
return 'Button';
|
|
113
|
+
case 'a':
|
|
114
|
+
return 'Link';
|
|
115
|
+
case 'ul':
|
|
116
|
+
return 'List';
|
|
117
|
+
case 'li':
|
|
118
|
+
return 'Text'; // Will be wrapped in List
|
|
119
|
+
case 'form':
|
|
120
|
+
return 'Form';
|
|
121
|
+
case 'select':
|
|
122
|
+
return 'Picker';
|
|
123
|
+
case 'option':
|
|
124
|
+
return 'Text'; // Options in SwiftUI are part of the Picker content
|
|
125
|
+
default:
|
|
126
|
+
// For custom components or unrecognized tags
|
|
127
|
+
return (0, capitalize_1.capitalize)(tagName);
|
|
128
|
+
}
|
|
129
|
+
};
|
|
130
|
+
exports.jsxElementToSwiftUIView = jsxElementToSwiftUIView;
|
|
131
|
+
const cssToSwiftUIModifiers = (style) => {
|
|
132
|
+
const modifiers = [];
|
|
133
|
+
// Map CSS properties to SwiftUI modifiers
|
|
134
|
+
Object.entries(style).forEach(([key, value]) => {
|
|
135
|
+
switch (key) {
|
|
136
|
+
case 'backgroundColor':
|
|
137
|
+
modifiers.push(`.background(Color("${value}"))`);
|
|
138
|
+
break;
|
|
139
|
+
case 'color':
|
|
140
|
+
modifiers.push(`.foregroundColor(Color("${value}"))`);
|
|
141
|
+
break;
|
|
142
|
+
case 'fontSize':
|
|
143
|
+
const fontSize = parseInt(value);
|
|
144
|
+
if (!isNaN(fontSize)) {
|
|
145
|
+
modifiers.push(`.font(.system(size: ${fontSize}))`);
|
|
146
|
+
}
|
|
147
|
+
break;
|
|
148
|
+
case 'fontWeight':
|
|
149
|
+
modifiers.push(`.fontWeight(.${value})`);
|
|
150
|
+
break;
|
|
151
|
+
case 'padding':
|
|
152
|
+
modifiers.push(`.padding(${value})`);
|
|
153
|
+
break;
|
|
154
|
+
case 'margin':
|
|
155
|
+
// Swift doesn't have direct margin equivalent, we'll use padding
|
|
156
|
+
modifiers.push(`// Note: 'margin' converted to padding: ${value}`);
|
|
157
|
+
modifiers.push(`.padding(${value})`);
|
|
158
|
+
break;
|
|
159
|
+
case 'width':
|
|
160
|
+
modifiers.push(`.frame(width: ${value})`);
|
|
161
|
+
break;
|
|
162
|
+
case 'height':
|
|
163
|
+
modifiers.push(`.frame(height: ${value})`);
|
|
164
|
+
break;
|
|
165
|
+
// Add more CSS to SwiftUI modifier mappings as needed
|
|
166
|
+
default:
|
|
167
|
+
modifiers.push(`// Unmapped style: ${key}: ${value}`);
|
|
168
|
+
}
|
|
169
|
+
});
|
|
170
|
+
return modifiers;
|
|
171
|
+
};
|
|
172
|
+
exports.cssToSwiftUIModifiers = cssToSwiftUIModifiers;
|
|
173
|
+
const getStatePropertyTypeAnnotation = (propertyType, type) => {
|
|
174
|
+
// Use appropriate SwiftUI property wrappers
|
|
175
|
+
switch (propertyType) {
|
|
176
|
+
case 'reactive':
|
|
177
|
+
// For reactive state, use @State for simple values
|
|
178
|
+
// @Observable would be used for classes but requires Swift 5.9+/iOS 17+
|
|
179
|
+
return `@State private var`;
|
|
180
|
+
case 'normal':
|
|
181
|
+
// For normal state, use @State for simple values
|
|
182
|
+
return `@State private var`;
|
|
183
|
+
default:
|
|
184
|
+
// For non-reactive values, use a regular property
|
|
185
|
+
return `var`;
|
|
186
|
+
}
|
|
187
|
+
};
|
|
188
|
+
exports.getStatePropertyTypeAnnotation = getStatePropertyTypeAnnotation;
|
|
189
|
+
const getEventHandlerName = (eventName) => {
|
|
190
|
+
switch (eventName) {
|
|
191
|
+
case 'onClick':
|
|
192
|
+
return 'onTapGesture';
|
|
193
|
+
case 'onChange':
|
|
194
|
+
return 'onChange';
|
|
195
|
+
case 'onInput':
|
|
196
|
+
return 'onEditingChanged';
|
|
197
|
+
case 'onBlur':
|
|
198
|
+
return 'onSubmit';
|
|
199
|
+
case 'onFocus':
|
|
200
|
+
return 'onEditingChanged';
|
|
201
|
+
default:
|
|
202
|
+
return eventName;
|
|
203
|
+
}
|
|
204
|
+
};
|
|
205
|
+
exports.getEventHandlerName = getEventHandlerName;
|
|
206
|
+
const needsScrollView = (json) => {
|
|
207
|
+
// Check if overflow property indicates scrolling
|
|
208
|
+
if (json.properties.style) {
|
|
209
|
+
try {
|
|
210
|
+
const styleObj = JSON.parse(json.properties.style);
|
|
211
|
+
return (styleObj.overflow === 'auto' ||
|
|
212
|
+
styleObj.overflow === 'scroll' ||
|
|
213
|
+
styleObj.overflowY === 'auto' ||
|
|
214
|
+
styleObj.overflowY === 'scroll' ||
|
|
215
|
+
styleObj.overflowX === 'auto' ||
|
|
216
|
+
styleObj.overflowX === 'scroll');
|
|
217
|
+
}
|
|
218
|
+
catch (e) {
|
|
219
|
+
// If style can't be parsed, check for overflow directly in the style string
|
|
220
|
+
const styleStr = json.properties.style;
|
|
221
|
+
return (styleStr.includes('overflow:auto') ||
|
|
222
|
+
styleStr.includes('overflow:scroll') ||
|
|
223
|
+
styleStr.includes('overflow-y:auto') ||
|
|
224
|
+
styleStr.includes('overflow-y:scroll') ||
|
|
225
|
+
styleStr.includes('overflow-x:auto') ||
|
|
226
|
+
styleStr.includes('overflow-x:scroll'));
|
|
227
|
+
}
|
|
228
|
+
}
|
|
229
|
+
return false;
|
|
230
|
+
};
|
|
231
|
+
exports.needsScrollView = needsScrollView;
|
|
232
|
+
const isForEachBlock = (json) => {
|
|
233
|
+
var _a;
|
|
234
|
+
// Check if this is a ForEach binding using the bindings.each pattern
|
|
235
|
+
return !!((_a = json.bindings.each) === null || _a === void 0 ? void 0 : _a.code);
|
|
236
|
+
};
|
|
237
|
+
exports.isForEachBlock = isForEachBlock;
|
|
238
|
+
const getForEachParams = (json, processCode) => {
|
|
239
|
+
var _a, _b;
|
|
240
|
+
if (!((_a = json.bindings.each) === null || _a === void 0 ? void 0 : _a.code)) {
|
|
241
|
+
return { collection: '', itemName: 'item', indexName: null };
|
|
242
|
+
}
|
|
243
|
+
const eachCode = json.bindings.each.code;
|
|
244
|
+
let itemName = 'item';
|
|
245
|
+
let indexName = null;
|
|
246
|
+
// Extract collection, item name, and index name from each binding
|
|
247
|
+
try {
|
|
248
|
+
// Parse expressions like: items.map(item => ...)
|
|
249
|
+
// or items.map((item, index) => ...)
|
|
250
|
+
const match = eachCode.match(/(\w+)\.map\(\s*(?:\()?([^,)]+)(?:,\s*([^)]+))?\)?/);
|
|
251
|
+
if (match) {
|
|
252
|
+
const collection = processCode(match[1]);
|
|
253
|
+
itemName = match[2].trim();
|
|
254
|
+
indexName = ((_b = match[3]) === null || _b === void 0 ? void 0 : _b.trim()) || null;
|
|
255
|
+
return { collection, itemName, indexName };
|
|
256
|
+
}
|
|
257
|
+
// Fallback to the whole code as collection if pattern doesn't match
|
|
258
|
+
return {
|
|
259
|
+
collection: processCode(eachCode),
|
|
260
|
+
itemName,
|
|
261
|
+
indexName,
|
|
262
|
+
};
|
|
263
|
+
}
|
|
264
|
+
catch (e) {
|
|
265
|
+
console.warn('Failed to parse each binding:', eachCode);
|
|
266
|
+
return {
|
|
267
|
+
collection: processCode(eachCode),
|
|
268
|
+
itemName,
|
|
269
|
+
indexName,
|
|
270
|
+
};
|
|
271
|
+
}
|
|
272
|
+
};
|
|
273
|
+
exports.getForEachParams = getForEachParams;
|
|
274
|
+
const camelToSnakeCase = (str) => {
|
|
275
|
+
return str.replace(/[A-Z]/g, (letter) => `_${letter.toLowerCase()}`);
|
|
276
|
+
};
|
|
277
|
+
exports.camelToSnakeCase = camelToSnakeCase;
|
|
278
|
+
const getBindingType = (key) => {
|
|
279
|
+
if (key.startsWith('bind:')) {
|
|
280
|
+
return key.substring(5);
|
|
281
|
+
}
|
|
282
|
+
return key;
|
|
283
|
+
};
|
|
284
|
+
exports.getBindingType = getBindingType;
|
|
285
|
+
/**
|
|
286
|
+
* Extract function signature information from JavaScript function code
|
|
287
|
+
*/
|
|
288
|
+
const extractFunctionSignature = (code) => {
|
|
289
|
+
// Default values
|
|
290
|
+
let name = '';
|
|
291
|
+
let params = [];
|
|
292
|
+
let returnType = 'Void';
|
|
293
|
+
let body = '';
|
|
294
|
+
// Extract function name, parameters, and body
|
|
295
|
+
const funcMatch = code.match(/(?:function\s+)?([a-zA-Z_$][a-zA-Z0-9_$]*)?\s*\(([^)]*)\)\s*(?:=>)?\s*(?:{([\s\S]*)}|(.*))/);
|
|
296
|
+
if (funcMatch) {
|
|
297
|
+
name = funcMatch[1] || '';
|
|
298
|
+
// Extract parameters
|
|
299
|
+
const paramsStr = funcMatch[2].trim();
|
|
300
|
+
if (paramsStr) {
|
|
301
|
+
params = paramsStr.split(',').map((param) => {
|
|
302
|
+
// Handle TypeScript-style parameter types if present
|
|
303
|
+
const paramParts = param.trim().split(':');
|
|
304
|
+
const paramName = paramParts[0].trim();
|
|
305
|
+
const paramType = paramParts.length > 1 ? (0, exports.getSwiftType)(paramParts[1].trim()) : 'Any';
|
|
306
|
+
return { name: paramName, type: paramType };
|
|
307
|
+
});
|
|
308
|
+
}
|
|
309
|
+
// Extract function body
|
|
310
|
+
body = funcMatch[3] || funcMatch[4] || '';
|
|
311
|
+
// Try to determine return type from TypeScript annotations or infer from return statements
|
|
312
|
+
const returnTypeMatch = code.match(/\)\s*:\s*([^{]+)/);
|
|
313
|
+
if (returnTypeMatch) {
|
|
314
|
+
returnType = (0, exports.getSwiftType)(returnTypeMatch[1].trim());
|
|
315
|
+
}
|
|
316
|
+
else if (body.includes('return')) {
|
|
317
|
+
// Try to infer from return statements
|
|
318
|
+
const returnValueMatch = body.match(/return\s+(["'].*["']|true|false|\d+|\d+\.\d+|\[.*\])/);
|
|
319
|
+
if (returnValueMatch) {
|
|
320
|
+
const returnValue = returnValueMatch[1];
|
|
321
|
+
if (returnValue.startsWith('"') || returnValue.startsWith("'")) {
|
|
322
|
+
returnType = 'String';
|
|
323
|
+
}
|
|
324
|
+
else if (returnValue === 'true' || returnValue === 'false') {
|
|
325
|
+
returnType = 'Bool';
|
|
326
|
+
}
|
|
327
|
+
else if (returnValue.match(/^\d+$/)) {
|
|
328
|
+
returnType = 'Int';
|
|
329
|
+
}
|
|
330
|
+
else if (returnValue.match(/^\d+\.\d+$/)) {
|
|
331
|
+
returnType = 'Double';
|
|
332
|
+
}
|
|
333
|
+
else if (returnValue.startsWith('[')) {
|
|
334
|
+
returnType = '[Any]';
|
|
335
|
+
}
|
|
336
|
+
}
|
|
337
|
+
}
|
|
338
|
+
}
|
|
339
|
+
return { name, params, returnType, body };
|
|
340
|
+
};
|
|
341
|
+
exports.extractFunctionSignature = extractFunctionSignature;
|
|
342
|
+
/**
|
|
343
|
+
* Convert JavaScript function code to Swift function syntax
|
|
344
|
+
*/
|
|
345
|
+
const convertJsFunctionToSwift = (code, functionName) => {
|
|
346
|
+
// Extract the function signature
|
|
347
|
+
const { name, params, returnType, body } = (0, exports.extractFunctionSignature)(code);
|
|
348
|
+
// Use provided name or extracted name
|
|
349
|
+
const finalName = functionName || name || 'function';
|
|
350
|
+
// Convert function body to Swift
|
|
351
|
+
let swiftBody = body
|
|
352
|
+
// Convert variable declarations
|
|
353
|
+
.replace(/\bvar\s+(\w+)/g, 'var $1')
|
|
354
|
+
.replace(/\blet\s+(\w+)/g, 'let $1')
|
|
355
|
+
.replace(/\bconst\s+(\w+)/g, 'let $1')
|
|
356
|
+
// Convert common array methods
|
|
357
|
+
.replace(/\.push\(/g, '.append(')
|
|
358
|
+
.replace(/\.map\(/g, '.map(')
|
|
359
|
+
.replace(/\.filter\(/g, '.filter(')
|
|
360
|
+
.replace(/\.includes\(/g, '.contains(')
|
|
361
|
+
.replace(/\.indexOf\(/g, '.firstIndex(of: ')
|
|
362
|
+
// Convert null/undefined checks
|
|
363
|
+
.replace(/=== null/g, '== nil')
|
|
364
|
+
.replace(/!== null/g, '!= nil')
|
|
365
|
+
.replace(/=== undefined/g, '== nil')
|
|
366
|
+
.replace(/!== undefined/g, '!= nil')
|
|
367
|
+
// Convert console.log
|
|
368
|
+
.replace(/console\.log\((.+?)\)/g, 'print($1)');
|
|
369
|
+
// Create parameter list with Swift types
|
|
370
|
+
const paramList = params.map((p) => `${p.name}: ${p.type}`).join(', ');
|
|
371
|
+
// Build the Swift function signature
|
|
372
|
+
const signature = `func ${finalName}(${paramList}) -> ${returnType}`;
|
|
373
|
+
// Build the complete Swift function
|
|
374
|
+
const swiftCode = `${signature} {\n ${swiftBody}\n}`;
|
|
375
|
+
return { swiftCode, signature };
|
|
376
|
+
};
|
|
377
|
+
exports.convertJsFunctionToSwift = convertJsFunctionToSwift;
|
|
@@ -1,4 +1,29 @@
|
|
|
1
1
|
import { BaseTranspilerOptions } from '../../types/transpiler';
|
|
2
2
|
export interface ToSwiftOptions extends BaseTranspilerOptions {
|
|
3
|
+
/**
|
|
4
|
+
* Format generated Swift code
|
|
5
|
+
* @default true
|
|
6
|
+
*/
|
|
7
|
+
formatCode?: boolean;
|
|
8
|
+
/**
|
|
9
|
+
* Include type annotations in Swift code
|
|
10
|
+
* @default true
|
|
11
|
+
*/
|
|
12
|
+
includeTypes?: boolean;
|
|
13
|
+
/**
|
|
14
|
+
* Type of state management to use
|
|
15
|
+
* @default 'state'
|
|
16
|
+
*/
|
|
17
|
+
stateType?: 'state' | 'stateObject' | 'observable';
|
|
18
|
+
/**
|
|
19
|
+
* Prefix for class names
|
|
20
|
+
* @default ''
|
|
21
|
+
*/
|
|
22
|
+
classPrefix?: string;
|
|
23
|
+
/**
|
|
24
|
+
* Whether to include SwiftUI preview code
|
|
25
|
+
* @default true
|
|
26
|
+
*/
|
|
27
|
+
includePreview?: boolean;
|
|
3
28
|
}
|
|
4
29
|
export type SwiftMetadata = {};
|
|
@@ -299,15 +299,14 @@ const getBlockBindings = (block, options) => {
|
|
|
299
299
|
exports.symbolBlocksAsChildren = false;
|
|
300
300
|
const componentMappers = {
|
|
301
301
|
Symbol(block, options) {
|
|
302
|
-
var _a
|
|
302
|
+
var _a;
|
|
303
303
|
let css = getCssFromBlock(block);
|
|
304
304
|
const styleString = getStyleStringFromBlock(block, options);
|
|
305
305
|
const actionBindings = getActionBindingsFromBlock(block, options);
|
|
306
306
|
const bindings = {
|
|
307
307
|
symbol: (0, bindings_1.createSingleBinding)({
|
|
308
308
|
code: JSON.stringify({
|
|
309
|
-
|
|
310
|
-
content: (_b = block.component) === null || _b === void 0 ? void 0 : _b.options.symbol.content,
|
|
309
|
+
...(_a = block.component) === null || _a === void 0 ? void 0 : _a.options.symbol,
|
|
311
310
|
}),
|
|
312
311
|
}),
|
|
313
312
|
...actionBindings,
|
|
@@ -284,6 +284,15 @@ const jsxElementToJson = (node) => {
|
|
|
284
284
|
bindingType: 'function',
|
|
285
285
|
});
|
|
286
286
|
}
|
|
287
|
+
else if (/^on[A-Z]/.test(key) && types.isExpression(expression)) {
|
|
288
|
+
// regex ignores props that happen to start with "on" but are not handlers
|
|
289
|
+
// <Foo onClick={state.handler} />
|
|
290
|
+
const call = types.callExpression(expression, []);
|
|
291
|
+
memo.bindings[key] = (0, bindings_1.createSingleBinding)({
|
|
292
|
+
code: (0, generator_1.default)(call, { compact: true }).code,
|
|
293
|
+
bindingType: 'function',
|
|
294
|
+
});
|
|
295
|
+
}
|
|
287
296
|
else if (types.isJSXElement(expression) || types.isJSXFragment(expression)) {
|
|
288
297
|
// <Foo myProp={<MoreMitosisNode><div /></MoreMitosisNode>} />
|
|
289
298
|
// <Foo myProp={<><Node /><Node /></>} />
|
package/jsx-runtime.d.ts
CHANGED
|
@@ -393,6 +393,9 @@ export declare namespace JSX {
|
|
|
393
393
|
}
|
|
394
394
|
|
|
395
395
|
interface DetailsHtmlAttributes<T> extends HTMLAttributes<T> {
|
|
396
|
+
/** [MDN Reference](https://developer.mozilla.org/docs/Web/API/HTMLDetailsElement/name) */
|
|
397
|
+
name?: string;
|
|
398
|
+
/** [MDN Reference](https://developer.mozilla.org/docs/Web/API/HTMLDetailsElement/open) */
|
|
396
399
|
open?: boolean;
|
|
397
400
|
}
|
|
398
401
|
|
|
@@ -500,6 +503,8 @@ export declare namespace JSX {
|
|
|
500
503
|
// camelcase
|
|
501
504
|
crossOrigin?: HTMLCrossorigin;
|
|
502
505
|
formAction?: string;
|
|
506
|
+
autoComplete?: string;
|
|
507
|
+
autoFocus?: boolean;
|
|
503
508
|
formEnctype?: HTMLFormEncType;
|
|
504
509
|
formMethod?: HTMLFormMethod;
|
|
505
510
|
formNoValidate?: boolean;
|