@carbon/upgrade 11.38.0 → 11.39.0
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/README.md +2 -0
- package/cli.js +211 -93
- package/package.json +2 -2
- package/transforms/__testfixtures__/ibm-products-update-coachmark.input.js +73 -0
- package/transforms/__testfixtures__/ibm-products-update-coachmark.output.js +66 -0
- package/transforms/__testfixtures__/ibm-products-update-page-header.input.js +17 -0
- package/transforms/__testfixtures__/ibm-products-update-page-header.output.js +13 -0
- package/transforms/__testfixtures__/ibm-products-update-page-header2.input.js +6 -0
- package/transforms/__testfixtures__/ibm-products-update-page-header2.output.js +6 -0
- package/transforms/__testfixtures__/ibm-products-update-page-header3.input.js +3 -0
- package/transforms/__testfixtures__/ibm-products-update-page-header3.output.js +3 -0
- package/transforms/__testfixtures__/ibm-products-update-page-header4.input.js +18 -0
- package/transforms/__testfixtures__/ibm-products-update-page-header4.output.js +18 -0
- package/transforms/__tests__/ibm-products-update-coachmark-test.js +12 -0
- package/transforms/__tests__/ibm-products-update-page-header-test.js +30 -0
- package/transforms/ibm-products-update-coachmark.js +504 -0
- package/transforms/ibm-products-update-page-header.js +233 -0
|
@@ -0,0 +1,504 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Copyright IBM Corp. 2026
|
|
3
|
+
*
|
|
4
|
+
* This source code is licensed under the Apache-2.0 license found in the
|
|
5
|
+
* LICENSE file in the root directory of this source tree.
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* Rewrites old Coachmark to new composable Coachmark
|
|
10
|
+
*
|
|
11
|
+
* Transforms:
|
|
12
|
+
*
|
|
13
|
+
* <Coachmark align='bottom' closeIconDescription='Close' positionTune={{ x: 0, y: 0 }}
|
|
14
|
+
* target={<CoachmarkBeacon label="Show information" kind={BEACON_KIND.DEFAULT} />} theme='dark'>
|
|
15
|
+
* <CoachmarkOverlayElements closeButtonLabel="Done">
|
|
16
|
+
* <CoachmarkOverlayElement title="Hello World" description="this is a description test" />
|
|
17
|
+
* </CoachmarkOverlayElements>
|
|
18
|
+
* </Coachmark>
|
|
19
|
+
*
|
|
20
|
+
* Into:
|
|
21
|
+
*
|
|
22
|
+
* <Theme theme={g90}>
|
|
23
|
+
* <Coachmark align='bottom' position={{ x: 0, y: 0 }}>
|
|
24
|
+
* <CoachmarkBeacon label="Show information" buttonProps={{ onClick: handleBeaconClick, id: 'CoachmarkBtn', ref: beaconButtonRef }} />
|
|
25
|
+
* <Coachmark.Content>
|
|
26
|
+
* <Coachmark.Content.Header closeIconDescription="Close" />
|
|
27
|
+
* <Coachmark.Content.Body>
|
|
28
|
+
* <h2>Hello World</h2>
|
|
29
|
+
* <p>this is a description test</p>
|
|
30
|
+
* <Button size="sm">Done</Button>
|
|
31
|
+
* </Coachmark.Content.Body>
|
|
32
|
+
* </Coachmark.Content>
|
|
33
|
+
* </Coachmark>
|
|
34
|
+
* </Theme>
|
|
35
|
+
*/
|
|
36
|
+
|
|
37
|
+
'use strict';
|
|
38
|
+
|
|
39
|
+
const transform = (fileInfo, api) => {
|
|
40
|
+
const j = api.jscodeshift;
|
|
41
|
+
const root = j(fileInfo.source);
|
|
42
|
+
let shouldImportTheme = false;
|
|
43
|
+
let shouldImportButton = false;
|
|
44
|
+
let shouldImportUseState = false;
|
|
45
|
+
|
|
46
|
+
// Helper to add imports to existing or create new import declarations
|
|
47
|
+
const ensureImport = (source, identifierName) => {
|
|
48
|
+
const existingImport = root
|
|
49
|
+
.find(j.ImportDeclaration, { source: { value: source } })
|
|
50
|
+
.filter((path) =>
|
|
51
|
+
path.node.specifiers.some((s) => s.imported?.name === identifierName)
|
|
52
|
+
);
|
|
53
|
+
|
|
54
|
+
if (existingImport.size() === 0) {
|
|
55
|
+
const reactImport = root.find(j.ImportDeclaration, {
|
|
56
|
+
source: { value: source },
|
|
57
|
+
});
|
|
58
|
+
if (reactImport.size() > 0) {
|
|
59
|
+
reactImport.forEach((path) =>
|
|
60
|
+
path.node.specifiers.push(
|
|
61
|
+
j.importSpecifier(j.identifier(identifierName))
|
|
62
|
+
)
|
|
63
|
+
);
|
|
64
|
+
} else {
|
|
65
|
+
root
|
|
66
|
+
.find(j.Program)
|
|
67
|
+
.get('body', 0)
|
|
68
|
+
.insertBefore(
|
|
69
|
+
j.importDeclaration(
|
|
70
|
+
[j.importSpecifier(j.identifier(identifierName))],
|
|
71
|
+
j.literal(source)
|
|
72
|
+
)
|
|
73
|
+
);
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
};
|
|
77
|
+
|
|
78
|
+
const createJSXElement = (name, attributes, children) => {
|
|
79
|
+
const openingElement = j.jsxOpeningElement(
|
|
80
|
+
j.jsxIdentifier(name),
|
|
81
|
+
attributes,
|
|
82
|
+
children.length === 0
|
|
83
|
+
);
|
|
84
|
+
return children.length === 0
|
|
85
|
+
? j.jsxElement(openingElement, null, [])
|
|
86
|
+
: j.jsxElement(
|
|
87
|
+
openingElement,
|
|
88
|
+
j.jsxClosingElement(j.jsxIdentifier(name)),
|
|
89
|
+
children
|
|
90
|
+
);
|
|
91
|
+
};
|
|
92
|
+
|
|
93
|
+
const createMemberJSXElement = (object, property, attributes, children) => {
|
|
94
|
+
const memberExpression = j.jsxMemberExpression(
|
|
95
|
+
j.jsxIdentifier(object),
|
|
96
|
+
j.jsxIdentifier(property)
|
|
97
|
+
);
|
|
98
|
+
const openingElement = j.jsxOpeningElement(
|
|
99
|
+
memberExpression,
|
|
100
|
+
attributes,
|
|
101
|
+
children.length === 0
|
|
102
|
+
);
|
|
103
|
+
return children.length === 0
|
|
104
|
+
? j.jsxElement(openingElement, null, [])
|
|
105
|
+
: j.jsxElement(
|
|
106
|
+
openingElement,
|
|
107
|
+
j.jsxClosingElement(memberExpression),
|
|
108
|
+
children
|
|
109
|
+
);
|
|
110
|
+
};
|
|
111
|
+
|
|
112
|
+
const createNestedMemberJSXElement = (
|
|
113
|
+
obj1,
|
|
114
|
+
obj2,
|
|
115
|
+
property,
|
|
116
|
+
attributes,
|
|
117
|
+
children
|
|
118
|
+
) => {
|
|
119
|
+
const outerMember = j.jsxMemberExpression(
|
|
120
|
+
j.jsxMemberExpression(j.jsxIdentifier(obj1), j.jsxIdentifier(obj2)),
|
|
121
|
+
j.jsxIdentifier(property)
|
|
122
|
+
);
|
|
123
|
+
const openingElement = j.jsxOpeningElement(
|
|
124
|
+
outerMember,
|
|
125
|
+
attributes,
|
|
126
|
+
children.length === 0
|
|
127
|
+
);
|
|
128
|
+
return children.length === 0
|
|
129
|
+
? j.jsxElement(openingElement, null, [])
|
|
130
|
+
: j.jsxElement(
|
|
131
|
+
openingElement,
|
|
132
|
+
j.jsxClosingElement(outerMember),
|
|
133
|
+
children
|
|
134
|
+
);
|
|
135
|
+
};
|
|
136
|
+
|
|
137
|
+
// Transform target elements (CoachmarkBeacon or CoachmarkButton)
|
|
138
|
+
const processTargetElement = (targetValue) => {
|
|
139
|
+
if (
|
|
140
|
+
targetValue.type !== 'JSXExpressionContainer' ||
|
|
141
|
+
targetValue.expression.type !== 'JSXElement'
|
|
142
|
+
)
|
|
143
|
+
return null;
|
|
144
|
+
|
|
145
|
+
const expression = targetValue.expression;
|
|
146
|
+
const elementName = expression.openingElement.name.name;
|
|
147
|
+
|
|
148
|
+
// Transform CoachmarkBeacon with buttonProps
|
|
149
|
+
if (elementName === 'CoachmarkBeacon') {
|
|
150
|
+
shouldImportUseState = true;
|
|
151
|
+
const label = expression.openingElement.attributes.find(
|
|
152
|
+
(a) => a.name?.name === 'label'
|
|
153
|
+
)?.value;
|
|
154
|
+
const newAttributes = [
|
|
155
|
+
j.jsxAttribute(
|
|
156
|
+
j.jsxIdentifier('buttonProps'),
|
|
157
|
+
j.jsxExpressionContainer(
|
|
158
|
+
j.objectExpression([
|
|
159
|
+
j.property(
|
|
160
|
+
'init',
|
|
161
|
+
j.identifier('onClick'),
|
|
162
|
+
j.identifier('handleBeaconClick')
|
|
163
|
+
),
|
|
164
|
+
j.property('init', j.identifier('id'), j.literal('CoachmarkBtn')),
|
|
165
|
+
])
|
|
166
|
+
)
|
|
167
|
+
),
|
|
168
|
+
];
|
|
169
|
+
if (label)
|
|
170
|
+
newAttributes.unshift(j.jsxAttribute(j.jsxIdentifier('label'), label));
|
|
171
|
+
return createJSXElement('CoachmarkBeacon', newAttributes, []);
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
// Transform CoachmarkButton to regular Button
|
|
175
|
+
if (elementName === 'CoachmarkButton') {
|
|
176
|
+
shouldImportButton = true;
|
|
177
|
+
shouldImportUseState = true;
|
|
178
|
+
const attrs = expression.openingElement.attributes;
|
|
179
|
+
const buttonAttributes = [
|
|
180
|
+
j.jsxAttribute(
|
|
181
|
+
j.jsxIdentifier('id'),
|
|
182
|
+
j.literal('CoachmarkTriggerRefBtn')
|
|
183
|
+
),
|
|
184
|
+
j.jsxAttribute(
|
|
185
|
+
j.jsxIdentifier('onClick'),
|
|
186
|
+
j.jsxExpressionContainer(j.identifier('handleButtonClick'))
|
|
187
|
+
),
|
|
188
|
+
];
|
|
189
|
+
['kind', 'size', 'renderIcon'].forEach((name) => {
|
|
190
|
+
const attr = attrs.find((a) => a.name?.name === name);
|
|
191
|
+
if (attr)
|
|
192
|
+
buttonAttributes.push(
|
|
193
|
+
j.jsxAttribute(j.jsxIdentifier(name), attr.value)
|
|
194
|
+
);
|
|
195
|
+
});
|
|
196
|
+
return createJSXElement(
|
|
197
|
+
'Button',
|
|
198
|
+
buttonAttributes,
|
|
199
|
+
expression.children || []
|
|
200
|
+
);
|
|
201
|
+
}
|
|
202
|
+
return null;
|
|
203
|
+
};
|
|
204
|
+
|
|
205
|
+
// Transform Coachmark components
|
|
206
|
+
root
|
|
207
|
+
.find(j.JSXElement, { openingElement: { name: { name: 'Coachmark' } } })
|
|
208
|
+
.forEach((path) => {
|
|
209
|
+
const attributes = path.node.openingElement.attributes;
|
|
210
|
+
const newAttributes = [];
|
|
211
|
+
let themeValue = null,
|
|
212
|
+
closeIconDescription = null,
|
|
213
|
+
targetElement = null,
|
|
214
|
+
overlayKind = null;
|
|
215
|
+
let closeButtonLabel = null,
|
|
216
|
+
overlayElements = [];
|
|
217
|
+
|
|
218
|
+
// Process and transform attributes
|
|
219
|
+
attributes.forEach((attr) => {
|
|
220
|
+
if (attr.type !== 'JSXAttribute') {
|
|
221
|
+
newAttributes.push(attr);
|
|
222
|
+
return;
|
|
223
|
+
}
|
|
224
|
+
const attrName = attr.name.name;
|
|
225
|
+
|
|
226
|
+
if (attrName === 'theme') {
|
|
227
|
+
if (attr.value.type === 'Literal') {
|
|
228
|
+
themeValue =
|
|
229
|
+
attr.value.value === 'dark'
|
|
230
|
+
? 'g90'
|
|
231
|
+
: attr.value.value === 'light'
|
|
232
|
+
? 'white'
|
|
233
|
+
: null;
|
|
234
|
+
}
|
|
235
|
+
shouldImportTheme = true;
|
|
236
|
+
} else if (attrName === 'positionTune') {
|
|
237
|
+
attr.name.name = 'position';
|
|
238
|
+
newAttributes.push(attr);
|
|
239
|
+
} else if (attrName === 'closeIconDescription') {
|
|
240
|
+
closeIconDescription = attr.value;
|
|
241
|
+
} else if (attrName === 'target') {
|
|
242
|
+
targetElement = attr.value;
|
|
243
|
+
} else if (attrName === 'overlayKind') {
|
|
244
|
+
overlayKind = attr.value;
|
|
245
|
+
} else {
|
|
246
|
+
newAttributes.push(attr);
|
|
247
|
+
}
|
|
248
|
+
});
|
|
249
|
+
|
|
250
|
+
newAttributes.push(
|
|
251
|
+
j.jsxAttribute(
|
|
252
|
+
j.jsxIdentifier('open'),
|
|
253
|
+
j.jsxExpressionContainer(j.identifier('isOpen'))
|
|
254
|
+
)
|
|
255
|
+
);
|
|
256
|
+
if (overlayKind) {
|
|
257
|
+
newAttributes.push(
|
|
258
|
+
j.jsxAttribute(
|
|
259
|
+
j.jsxIdentifier('floating'),
|
|
260
|
+
j.jsxExpressionContainer(j.literal(true))
|
|
261
|
+
)
|
|
262
|
+
);
|
|
263
|
+
}
|
|
264
|
+
|
|
265
|
+
const newChildren = [];
|
|
266
|
+
if (targetElement) {
|
|
267
|
+
const targetChild = processTargetElement(targetElement);
|
|
268
|
+
if (targetChild) newChildren.push(targetChild);
|
|
269
|
+
}
|
|
270
|
+
|
|
271
|
+
if (path.node.children) {
|
|
272
|
+
path.node.children.forEach((child) => {
|
|
273
|
+
if (
|
|
274
|
+
child.type === 'JSXElement' &&
|
|
275
|
+
child.openingElement.name.name === 'CoachmarkOverlayElements'
|
|
276
|
+
) {
|
|
277
|
+
child.openingElement.attributes.forEach((attr) => {
|
|
278
|
+
if (attr.name?.name === 'closeButtonLabel')
|
|
279
|
+
closeButtonLabel = attr.value;
|
|
280
|
+
});
|
|
281
|
+
child.children.forEach((overlayChild) => {
|
|
282
|
+
if (
|
|
283
|
+
overlayChild.type === 'JSXElement' &&
|
|
284
|
+
overlayChild.openingElement.name.name ===
|
|
285
|
+
'CoachmarkOverlayElement'
|
|
286
|
+
) {
|
|
287
|
+
overlayElements.push(overlayChild);
|
|
288
|
+
}
|
|
289
|
+
});
|
|
290
|
+
}
|
|
291
|
+
});
|
|
292
|
+
}
|
|
293
|
+
|
|
294
|
+
// Build content body from overlay elements
|
|
295
|
+
const contentBodyChildren = [];
|
|
296
|
+
overlayElements.forEach((element) => {
|
|
297
|
+
const attrs = element.openingElement.attributes;
|
|
298
|
+
const title = attrs.find((a) => a.name?.name === 'title')?.value;
|
|
299
|
+
const description = attrs.find(
|
|
300
|
+
(a) => a.name?.name === 'description'
|
|
301
|
+
)?.value;
|
|
302
|
+
|
|
303
|
+
if (title) {
|
|
304
|
+
const titleValue = title.type === 'Literal' ? title.value : title;
|
|
305
|
+
contentBodyChildren.push(
|
|
306
|
+
j.jsxElement(
|
|
307
|
+
j.jsxOpeningElement(j.jsxIdentifier('h2'), []),
|
|
308
|
+
j.jsxClosingElement(j.jsxIdentifier('h2')),
|
|
309
|
+
[j.jsxText(typeof titleValue === 'string' ? titleValue : '')]
|
|
310
|
+
)
|
|
311
|
+
);
|
|
312
|
+
}
|
|
313
|
+
if (description) {
|
|
314
|
+
const descValue =
|
|
315
|
+
description.type === 'Literal' ? description.value : description;
|
|
316
|
+
contentBodyChildren.push(
|
|
317
|
+
j.jsxElement(
|
|
318
|
+
j.jsxOpeningElement(j.jsxIdentifier('p'), []),
|
|
319
|
+
j.jsxClosingElement(j.jsxIdentifier('p')),
|
|
320
|
+
[j.jsxText(typeof descValue === 'string' ? descValue : '')]
|
|
321
|
+
)
|
|
322
|
+
);
|
|
323
|
+
}
|
|
324
|
+
});
|
|
325
|
+
|
|
326
|
+
if (closeButtonLabel) {
|
|
327
|
+
shouldImportButton = true;
|
|
328
|
+
const buttonLabel =
|
|
329
|
+
closeButtonLabel.type === 'Literal' ? closeButtonLabel.value : 'Done';
|
|
330
|
+
contentBodyChildren.push(
|
|
331
|
+
j.jsxElement(
|
|
332
|
+
j.jsxOpeningElement(j.jsxIdentifier('Button'), [
|
|
333
|
+
j.jsxAttribute(j.jsxIdentifier('size'), j.literal('sm')),
|
|
334
|
+
]),
|
|
335
|
+
j.jsxClosingElement(j.jsxIdentifier('Button')),
|
|
336
|
+
[j.jsxText(buttonLabel)]
|
|
337
|
+
)
|
|
338
|
+
);
|
|
339
|
+
}
|
|
340
|
+
|
|
341
|
+
const contentBody = createNestedMemberJSXElement(
|
|
342
|
+
'Coachmark',
|
|
343
|
+
'Content',
|
|
344
|
+
'Body',
|
|
345
|
+
[],
|
|
346
|
+
contentBodyChildren
|
|
347
|
+
);
|
|
348
|
+
const headerAttributes = closeIconDescription
|
|
349
|
+
? [
|
|
350
|
+
j.jsxAttribute(
|
|
351
|
+
j.jsxIdentifier('closeIconDescription'),
|
|
352
|
+
closeIconDescription
|
|
353
|
+
),
|
|
354
|
+
]
|
|
355
|
+
: [];
|
|
356
|
+
const contentHeader = createNestedMemberJSXElement(
|
|
357
|
+
'Coachmark',
|
|
358
|
+
'Content',
|
|
359
|
+
'Header',
|
|
360
|
+
headerAttributes,
|
|
361
|
+
[]
|
|
362
|
+
);
|
|
363
|
+
const content = createMemberJSXElement(
|
|
364
|
+
'Coachmark',
|
|
365
|
+
'Content',
|
|
366
|
+
[],
|
|
367
|
+
[contentHeader, contentBody]
|
|
368
|
+
);
|
|
369
|
+
|
|
370
|
+
newChildren.push(content);
|
|
371
|
+
path.node.openingElement.attributes = newAttributes;
|
|
372
|
+
path.node.children = newChildren;
|
|
373
|
+
|
|
374
|
+
if (themeValue) {
|
|
375
|
+
const themeElement = j.jsxElement(
|
|
376
|
+
j.jsxOpeningElement(j.jsxIdentifier('Theme'), [
|
|
377
|
+
j.jsxAttribute(j.jsxIdentifier('theme'), j.literal(themeValue)),
|
|
378
|
+
]),
|
|
379
|
+
j.jsxClosingElement(j.jsxIdentifier('Theme')),
|
|
380
|
+
[
|
|
381
|
+
j.jsxElement(
|
|
382
|
+
path.node.openingElement,
|
|
383
|
+
path.node.closingElement,
|
|
384
|
+
path.node.children
|
|
385
|
+
),
|
|
386
|
+
]
|
|
387
|
+
);
|
|
388
|
+
j(path).replaceWith(themeElement);
|
|
389
|
+
}
|
|
390
|
+
});
|
|
391
|
+
|
|
392
|
+
// Update @carbon/ibm-products imports to preview versions
|
|
393
|
+
root
|
|
394
|
+
.find(j.ImportDeclaration)
|
|
395
|
+
.filter((path) => path.node.source.value === '@carbon/ibm-products')
|
|
396
|
+
.forEach((path) => {
|
|
397
|
+
const removedImports = [
|
|
398
|
+
'CoachmarkOverlayElements',
|
|
399
|
+
'CoachmarkOverlayElement',
|
|
400
|
+
'CoachmarkButton',
|
|
401
|
+
'BEACON_KIND',
|
|
402
|
+
'COACHMARK_OVERLAY_KIND',
|
|
403
|
+
];
|
|
404
|
+
const newSpecifiers = [];
|
|
405
|
+
|
|
406
|
+
path.node.specifiers.forEach((specifier) => {
|
|
407
|
+
if (!specifier.imported) {
|
|
408
|
+
newSpecifiers.push(specifier);
|
|
409
|
+
return;
|
|
410
|
+
}
|
|
411
|
+
|
|
412
|
+
const importedName = specifier.imported.name;
|
|
413
|
+
if (removedImports.includes(importedName)) return;
|
|
414
|
+
|
|
415
|
+
if (importedName === 'Coachmark') {
|
|
416
|
+
newSpecifiers.push(
|
|
417
|
+
j.importSpecifier(
|
|
418
|
+
j.identifier('preview__Coachmark'),
|
|
419
|
+
j.identifier('Coachmark')
|
|
420
|
+
)
|
|
421
|
+
);
|
|
422
|
+
} else if (importedName === 'CoachmarkBeacon') {
|
|
423
|
+
newSpecifiers.push(
|
|
424
|
+
j.importSpecifier(
|
|
425
|
+
j.identifier('preview__CoachmarkBeacon'),
|
|
426
|
+
j.identifier('CoachmarkBeacon')
|
|
427
|
+
)
|
|
428
|
+
);
|
|
429
|
+
} else {
|
|
430
|
+
newSpecifiers.push(specifier);
|
|
431
|
+
}
|
|
432
|
+
});
|
|
433
|
+
|
|
434
|
+
path.node.specifiers = newSpecifiers;
|
|
435
|
+
});
|
|
436
|
+
|
|
437
|
+
// Add required imports
|
|
438
|
+
if (shouldImportTheme) ensureImport('@carbon/react', 'Theme');
|
|
439
|
+
if (shouldImportButton) ensureImport('@carbon/react', 'Button');
|
|
440
|
+
if (shouldImportUseState) ensureImport('react', 'useState');
|
|
441
|
+
|
|
442
|
+
// Inject state management into component functions
|
|
443
|
+
root.find(j.VariableDeclarator).forEach((path) => {
|
|
444
|
+
const init = path.node.init;
|
|
445
|
+
if (
|
|
446
|
+
!init ||
|
|
447
|
+
init.type !== 'ArrowFunctionExpression' ||
|
|
448
|
+
init.body.type !== 'JSXElement'
|
|
449
|
+
)
|
|
450
|
+
return;
|
|
451
|
+
|
|
452
|
+
const jsx = init.body;
|
|
453
|
+
const containsTheme = jsx.openingElement?.name?.name === 'Theme';
|
|
454
|
+
const containsCoachmark = jsx.openingElement?.name?.name === 'Coachmark';
|
|
455
|
+
if (!containsTheme && !containsCoachmark) return;
|
|
456
|
+
|
|
457
|
+
const jsxSource = j(jsx).toSource();
|
|
458
|
+
const usesBeaconHandler = jsxSource.includes('handleBeaconClick');
|
|
459
|
+
const usesButtonHandler = jsxSource.includes('handleButtonClick');
|
|
460
|
+
if (!usesBeaconHandler && !usesButtonHandler) return;
|
|
461
|
+
|
|
462
|
+
shouldImportUseState = true;
|
|
463
|
+
const bodyStatements = [
|
|
464
|
+
j.variableDeclaration('const', [
|
|
465
|
+
j.variableDeclarator(
|
|
466
|
+
j.arrayPattern([j.identifier('isOpen'), j.identifier('setIsOpen')]),
|
|
467
|
+
j.callExpression(j.identifier('useState'), [j.literal(true)])
|
|
468
|
+
),
|
|
469
|
+
]),
|
|
470
|
+
];
|
|
471
|
+
|
|
472
|
+
const createHandler = (name) =>
|
|
473
|
+
j.variableDeclaration('const', [
|
|
474
|
+
j.variableDeclarator(
|
|
475
|
+
j.identifier(name),
|
|
476
|
+
j.arrowFunctionExpression(
|
|
477
|
+
[],
|
|
478
|
+
j.blockStatement([
|
|
479
|
+
j.expressionStatement(
|
|
480
|
+
j.callExpression(j.identifier('setIsOpen'), [
|
|
481
|
+
j.arrowFunctionExpression(
|
|
482
|
+
[j.identifier('isOpen')],
|
|
483
|
+
j.unaryExpression('!', j.identifier('isOpen'))
|
|
484
|
+
),
|
|
485
|
+
])
|
|
486
|
+
),
|
|
487
|
+
])
|
|
488
|
+
)
|
|
489
|
+
),
|
|
490
|
+
]);
|
|
491
|
+
|
|
492
|
+
if (usesBeaconHandler)
|
|
493
|
+
bodyStatements.push(createHandler('handleBeaconClick'));
|
|
494
|
+
if (usesButtonHandler)
|
|
495
|
+
bodyStatements.push(createHandler('handleButtonClick'));
|
|
496
|
+
bodyStatements.push(j.returnStatement(jsx));
|
|
497
|
+
|
|
498
|
+
init.body = j.blockStatement(bodyStatements);
|
|
499
|
+
});
|
|
500
|
+
|
|
501
|
+
return root.toSource();
|
|
502
|
+
};
|
|
503
|
+
|
|
504
|
+
module.exports = transform;
|