bestax-migrate 2.8.0 → 2.9.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.
@@ -35,8 +35,11 @@ export interface Modifier {
35
35
  * - `todo`: bestax has a component, but the markup does not map element by
36
36
  * element yet; the family's outermost class gets a TODO.
37
37
  * - `plain`: valid Bulma with nothing to convert to; left alone, no TODO.
38
+ * - `fold`: a wrapper the `target` renders itself from a prop, so the element
39
+ * folds into the one `target` inside it (`.table-container` into
40
+ * `Table isResponsive`).
38
41
  */
39
- export type RootStatus = 'mapped' | 'todo' | 'plain';
42
+ export type RootStatus = 'mapped' | 'todo' | 'plain' | 'fold';
40
43
  export interface RootEntry {
41
44
  readonly status: RootStatus;
42
45
  /**
@@ -89,6 +92,11 @@ export interface RootEntry {
89
92
  * takes a generated `id` when the element has none of its own.
90
93
  */
91
94
  readonly adoptsIdFrom?: readonly string[];
95
+ /**
96
+ * For a `fold` root: the props that render it on the target inside. Its
97
+ * modifiers add their props beside these.
98
+ */
99
+ readonly folds?: readonly PropWrite[];
92
100
  /** The target takes no helper props, so every helper class stays a class. */
93
101
  readonly noHelpers?: boolean;
94
102
  /**
@@ -1 +1 @@
1
- {"version":3,"file":"class-map.d.ts","sourceRoot":"","sources":["../../../src/sources/bulma-classes/class-map.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"class-map.d.ts","sourceRoot":"","sources":["../../../src/sources/bulma-classes/class-map.ts"],"names":[],"mappings":"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"}
@@ -185,10 +185,13 @@ const flag = (prop) => ({ writes: [{ prop }] });
185
185
  const set = (prop, value) => ({
186
186
  writes: [{ prop, value }],
187
187
  });
188
- /** `prefix + n` → `prop={n}` for `n` from 1 to `max`, for a prop typed as a number. */
189
- function numbers(prefix, max, prop) {
188
+ /**
189
+ * `prefix + n + suffix` → `prop={n}` for `n` from 1 to `max`, for a prop
190
+ * typed as a number.
191
+ */
192
+ function numbers(prefix, max, prop, suffix = '') {
190
193
  return Object.fromEntries(Array.from({ length: max }, (_, i) => String(i + 1)).map(value => [
191
- `${prefix}${value}`,
194
+ `${prefix}${value}${suffix}`,
192
195
  { writes: [{ prop, value, numeric: true }] },
193
196
  ]));
194
197
  }
@@ -1087,7 +1090,6 @@ export const ROOTS = {
1087
1090
  },
1088
1091
  // ---- Families bestax has but that do not map element by element yet ------
1089
1092
  breadcrumb: todo('Breadcrumb', 'bestax `Breadcrumb` renders the `<ul>` itself and adds an `aria-label`'),
1090
- 'fixed-grid': todo('Grid', '`Grid isFixed` renders the `.fixed-grid` wrapper itself, from `fixedCols`; replace the wrapper and its `.grid` with one `Grid`, by hand'),
1091
1093
  checkbox: todo('Checkbox', "bestax `Checkbox` renders its own styled markup, not Bulma's"),
1092
1094
  checkboxes: todo('Checkboxes', 'bestax `Checkboxes` renders its own `.field` and `.control` wrappers'),
1093
1095
  radio: todo('Radio', "bestax `Radio` renders its own styled markup, not Bulma's"),
@@ -1138,9 +1140,28 @@ export const ROOTS = {
1138
1140
  'panel-icon': part(),
1139
1141
  'panel-list': part(),
1140
1142
  tabs: todo('Tabs', "bestax `Tabs` renders each tab's `<li>` and `<a>` together, with tab roles"),
1141
- 'table-container': todo('Table', 'bestax renders `.table-container` from `Table isResponsive`'),
1142
1143
  'skeleton-block': todo('Skeleton', 'bestax `Skeleton` renders its own markup'),
1143
1144
  'skeleton-lines': todo('Skeleton', 'bestax `Skeleton` renders its own markup'),
1145
+ // ---- Wrappers a component renders from a prop ---------------------------------
1146
+ // Each renders the wrapper with its own class and nothing else, so the
1147
+ // element folds only when it carries no attribute and no other class.
1148
+ 'table-container': {
1149
+ status: 'fold',
1150
+ target: 'Table',
1151
+ tag: 'div',
1152
+ folds: [{ prop: 'isResponsive' }],
1153
+ },
1154
+ 'fixed-grid': {
1155
+ status: 'fold',
1156
+ target: 'Grid',
1157
+ tag: 'div',
1158
+ folds: [{ prop: 'isFixed' }],
1159
+ modifiers: {
1160
+ ...numbers('has-', 12, 'fixedCols', '-cols'),
1161
+ ...Object.assign({}, ...SIZE_VIEWPORTS.map(viewport => numbers('has-', 12, `fixedCols${viewportSuffix(viewport)}`, `-cols-${viewport}`))),
1162
+ 'has-auto-count': set('fixedCols', 'auto'),
1163
+ },
1164
+ },
1144
1165
  // ---- Valid Bulma, nothing to convert to --------------------------------------
1145
1166
  // The other sources emit these on purpose where bestax has no component.
1146
1167
  help: plain('bestax renders `.help` only inside its form controls'),
@@ -1387,8 +1408,8 @@ export const PASSTHROUGH = [
1387
1408
  match: /^(?:is-(?:col|row)-.+|is-(?:column|row)-gap-\d+|is-gap-\d+|is-auto-fill)$/,
1388
1409
  },
1389
1410
  {
1390
- why: 'a `.fixed-grid` column count, which stays with its `.fixed-grid` (a family this source leaves as markup)',
1391
- match: /^has-\d+-cols(?:-.+)?$/,
1411
+ why: 'a `.fixed-grid` column count, which converts only on its own `.fixed-grid`',
1412
+ match: /^(?:has-\d+-cols(?:-.+)?|has-auto-count)$/,
1392
1413
  },
1393
1414
  {
1394
1415
  why: 'an `.image` modifier; `.image` stays as markup',
@@ -1400,7 +1421,7 @@ export const PASSTHROUGH = [
1400
1421
  },
1401
1422
  {
1402
1423
  why: 'a modifier of markup this source leaves alone, or one bestax has no prop for',
1403
- match: /^(?:has-addons-.+|has-[a-z]+-separator|has-dropdown(?:-up)?|has-fixed-size|has-icons-(?:left|right)|has-name|has-(?:spaced-)?navbar-fixed-(?:top|bottom)(?:-desktop)?|has-shadow|has-auto-count|is-arrowless|is-boxed|is-center|is-current|is-delete|is-disabled|is-empty|is-expanded|is-fixed-(?:top|bottom)(?:-desktop)?|is-flexible|is-grouped(?:-.+)?|is-halfheight|is-horizontal|is-left|is-(?:lower|upper)-(?:alpha|roman)|is-multiple|is-responsive|is-selected|is-tab|is-toggle(?:-rounded)?|is-transparent|is-underlined|is-up|is-wrapped)$/,
1424
+ match: /^(?:has-addons-.+|has-[a-z]+-separator|has-dropdown(?:-up)?|has-fixed-size|has-icons-(?:left|right)|has-name|has-(?:spaced-)?navbar-fixed-(?:top|bottom)(?:-desktop)?|has-shadow|is-arrowless|is-boxed|is-center|is-current|is-delete|is-disabled|is-empty|is-expanded|is-fixed-(?:top|bottom)(?:-desktop)?|is-flexible|is-grouped(?:-.+)?|is-halfheight|is-horizontal|is-left|is-(?:lower|upper)-(?:alpha|roman)|is-multiple|is-responsive|is-selected|is-tab|is-toggle(?:-rounded)?|is-transparent|is-underlined|is-up|is-wrapped)$/,
1404
1425
  },
1405
1426
  ];
1406
1427
  /**
@@ -28,6 +28,11 @@ export interface ElementFacts {
28
28
  * counts: one in an expression may not render.
29
29
  */
30
30
  childTargets?: readonly string[];
31
+ /**
32
+ * What the element's only child converts to, when the element holds one
33
+ * element and nothing else (not even whitespace React would render).
34
+ */
35
+ soleChildTarget?: string;
31
36
  /** The bestax components already in the file inside this element. */
32
37
  bestaxInside?: readonly string[];
33
38
  /** The bestax components already in the file around this element. */
@@ -65,6 +70,15 @@ export interface Conversion {
65
70
  }
66
71
  export interface Plan {
67
72
  conversion: Conversion | null;
73
+ /**
74
+ * The element is a wrapper its only child's component renders from these
75
+ * props: they join that child's conversion, and the element goes.
76
+ */
77
+ fold?: {
78
+ target: string;
79
+ props: Array<[name: string, value: string | true]>;
80
+ numbers: string[];
81
+ };
68
82
  todos: Todo[];
69
83
  }
70
84
  export declare function plan(facts: ElementFacts): Plan;
@@ -1 +1 @@
1
- {"version":3,"file":"plan.d.ts","sourceRoot":"","sources":["../../../src/sources/bulma-classes/plan.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAiBH,MAAM,WAAW,YAAY;IAC3B,GAAG,EAAE,MAAM,CAAC;IACZ,2DAA2D;IAC3D,MAAM,EAAE,SAAS,MAAM,EAAE,CAAC;IAC1B;;;OAGG;IACH,UAAU,EAAE,WAAW,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI,GAAG,IAAI,CAAC,CAAC;IACtD,SAAS,EAAE,OAAO,CAAC;IACnB,MAAM,EAAE,OAAO,CAAC;IAChB,4EAA4E;IAC5E,WAAW,EAAE,OAAO,CAAC;IACrB;;;;OAIG;IACH,YAAY,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;IACjC,qEAAqE;IACrE,YAAY,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;IACjC,qEAAqE;IACrE,YAAY,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;IACjC;;;OAGG;IACH,gBAAgB,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;IACrC;;;;OAIG;IACH,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB;AAED,MAAM,WAAW,IAAI;IACnB,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,CAAC;CACjB;AAED,MAAM,WAAW,UAAU;IACzB,0CAA0C;IAC1C,MAAM,EAAE,MAAM,CAAC;IACf,6DAA6D;IAC7D,KAAK,EAAE,KAAK,CAAC,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC,CAAC,CAAC;IACnD,4DAA4D;IAC5D,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;IACzB,mEAAmE;IACnE,IAAI,EAAE,MAAM,EAAE,CAAC;IACf;;;OAGG;IACH,OAAO,EAAE,MAAM,EAAE,CAAC;CACnB;AAED,MAAM,WAAW,IAAI;IACnB,UAAU,EAAE,UAAU,GAAG,IAAI,CAAC;IAC9B,KAAK,EAAE,IAAI,EAAE,CAAC;CACf;AA+BD,wBAAgB,IAAI,CAAC,KAAK,EAAE,YAAY,GAAG,IAAI,CA+R9C"}
1
+ {"version":3,"file":"plan.d.ts","sourceRoot":"","sources":["../../../src/sources/bulma-classes/plan.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAiBH,MAAM,WAAW,YAAY;IAC3B,GAAG,EAAE,MAAM,CAAC;IACZ,2DAA2D;IAC3D,MAAM,EAAE,SAAS,MAAM,EAAE,CAAC;IAC1B;;;OAGG;IACH,UAAU,EAAE,WAAW,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI,GAAG,IAAI,CAAC,CAAC;IACtD,SAAS,EAAE,OAAO,CAAC;IACnB,MAAM,EAAE,OAAO,CAAC;IAChB,4EAA4E;IAC5E,WAAW,EAAE,OAAO,CAAC;IACrB;;;;OAIG;IACH,YAAY,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;IACjC;;;OAGG;IACH,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,qEAAqE;IACrE,YAAY,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;IACjC,qEAAqE;IACrE,YAAY,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;IACjC;;;OAGG;IACH,gBAAgB,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;IACrC;;;;OAIG;IACH,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB;AAED,MAAM,WAAW,IAAI;IACnB,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,CAAC;CACjB;AAED,MAAM,WAAW,UAAU;IACzB,0CAA0C;IAC1C,MAAM,EAAE,MAAM,CAAC;IACf,6DAA6D;IAC7D,KAAK,EAAE,KAAK,CAAC,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC,CAAC,CAAC;IACnD,4DAA4D;IAC5D,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;IACzB,mEAAmE;IACnE,IAAI,EAAE,MAAM,EAAE,CAAC;IACf;;;OAGG;IACH,OAAO,EAAE,MAAM,EAAE,CAAC;CACnB;AAED,MAAM,WAAW,IAAI;IACnB,UAAU,EAAE,UAAU,GAAG,IAAI,CAAC;IAC9B;;;OAGG;IACH,IAAI,CAAC,EAAE;QACL,MAAM,EAAE,MAAM,CAAC;QACf,KAAK,EAAE,KAAK,CAAC,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC,CAAC,CAAC;QACnD,OAAO,EAAE,MAAM,EAAE,CAAC;KACnB,CAAC;IACF,KAAK,EAAE,IAAI,EAAE,CAAC;CACf;AA+BD,wBAAgB,IAAI,CAAC,KAAK,EAAE,YAAY,GAAG,IAAI,CAkS9C"}
@@ -61,6 +61,9 @@ export function plan(facts) {
61
61
  });
62
62
  return { conversion: null, todos };
63
63
  }
64
+ const wrapper = tokens.find(token => rootFor(token)?.status === 'fold');
65
+ if (wrapper)
66
+ return planFold(facts, wrapper, todos);
64
67
  const root = tokens
65
68
  .filter(token => rootFor(token)?.status === 'mapped')
66
69
  .sort((a, b) => precedence(a) - precedence(b))[0];
@@ -257,3 +260,57 @@ export function plan(facts) {
257
260
  todos,
258
261
  };
259
262
  }
263
+ /**
264
+ * A wrapper the component inside it renders from a prop (`.table-container`
265
+ * from `Table isResponsive`). It folds into that component only when it is
266
+ * exactly what the component renders for it: its own tag and class, its own
267
+ * modifiers, no attribute, and one child that becomes the component.
268
+ */
269
+ function planFold(facts, wrapper, todos) {
270
+ const entry = rootFor(wrapper);
271
+ const target = entry.target;
272
+ if (!target)
273
+ return { conversion: null, todos };
274
+ const folds = entry.folds ?? [];
275
+ const renders = `\`${target} ${folds.map(write => write.prop).join(' ')}\``;
276
+ const refuse = (kind, token, message) => ({
277
+ conversion: null,
278
+ todos: [...todos, { rule: ruleId(kind, token), message }],
279
+ });
280
+ if (facts.tag !== entry.tag) {
281
+ return refuse('tag', target, `bestax ${renders} renders \`.${wrapper}\` on a <${entry.tag}>, not a <${facts.tag}>; keep the markup, or change the tag and re-run`);
282
+ }
283
+ if (facts.hasSpread) {
284
+ return refuse('spread', target, `this element spreads props, and bestax ${renders} renders \`.${wrapper}\` with none of its own; keep it as markup`);
285
+ }
286
+ if (facts.onlyChildOf) {
287
+ return refuse('only-child', target, `this element is the only child of \`<${facts.onlyChildOf}>\`, which may hand it props or a ref with \`cloneElement\`, and folding it would move those onto the \`${target}\` inside; convert it by hand if \`<${facts.onlyChildOf}>\` only renders its children`);
288
+ }
289
+ const attribute = [...facts.attributes.keys()][0];
290
+ if (attribute) {
291
+ return refuse('attr', attribute, `bestax ${renders} renders \`.${wrapper}\` with no attributes, so this element's \`${attribute}\` would be lost; keep it as markup`);
292
+ }
293
+ const props = folds.map(write => [
294
+ write.prop,
295
+ write.value ?? true,
296
+ ]);
297
+ const numbers = [];
298
+ for (const token of facts.tokens) {
299
+ if (token === wrapper)
300
+ continue;
301
+ const modifier = modifierFor(entry, token);
302
+ const taken = modifier?.writes.some(write => props.some(([prop]) => prop === write.prop));
303
+ if (!modifier || taken) {
304
+ return refuse('attr', 'className', `bestax ${renders} renders \`.${wrapper}\` with no class but its own and one of each of its modifiers, so \`${token}\` would be lost; keep this element as markup`);
305
+ }
306
+ for (const write of modifier.writes) {
307
+ props.push([write.prop, write.value ?? true]);
308
+ if (write.numeric)
309
+ numbers.push(write.prop);
310
+ }
311
+ }
312
+ if (facts.soleChildTarget !== target) {
313
+ return refuse('children', target, `bestax ${renders} renders \`.${wrapper}\` itself, so this element converts only around a single element that becomes a \`${target}\`, with nothing else beside it`);
314
+ }
315
+ return { conversion: null, fold: { target, props, numbers }, todos };
316
+ }
@@ -1 +1 @@
1
- {"version":3,"file":"transform.d.ts","sourceRoot":"","sources":["../../../src/sources/bulma-classes/transform.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;GAiBG;AAEH,OAAO,KAAK,EAAE,GAAG,EAAW,QAAQ,EAAE,MAAM,aAAa,CAAC;AAE1D,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,gBAAgB,CAAC;AAmSvD,MAAM,CAAC,OAAO,UAAU,SAAS,CAC/B,QAAQ,EAAE,QAAQ,EAClB,GAAG,EAAE,GAAG,EACR,OAAO,GAAE,gBAAqB,GAC7B,MAAM,GAAG,SAAS,CA8VpB"}
1
+ {"version":3,"file":"transform.d.ts","sourceRoot":"","sources":["../../../src/sources/bulma-classes/transform.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;GAiBG;AAEH,OAAO,KAAK,EAAE,GAAG,EAAW,QAAQ,EAAE,MAAM,aAAa,CAAC;AAE1D,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,gBAAgB,CAAC;AAoTvD,MAAM,CAAC,OAAO,UAAU,SAAS,CAC/B,QAAQ,EAAE,QAAQ,EAClB,GAAG,EAAE,GAAG,EACR,OAAO,GAAE,gBAAqB,GAC7B,MAAM,GAAG,SAAS,CAqYpB"}
@@ -47,6 +47,22 @@ const JSX_FACTORY = /^\s*\*?\s*@jsx\s+(\S+)/m;
47
47
  const HEADER_PRAGMA = /^[\s*]*(?:@ts-(?:no)?check|@flow|@noflow|eslint-disable(?!-)|@jsx|@jsxImportSource|@jsxRuntime|@license|@preserve)\b/;
48
48
  /** Directives that act on the line after them, so must stay above it. */
49
49
  const NEXT_LINE_DIRECTIVE = /^[\s*]*(?:eslint-disable-next-line|@ts-expect-error|@ts-ignore|prettier-ignore)\b/;
50
+ /**
51
+ * A comment moved to sit after a JSX tag name. It has to be a block comment
52
+ * there: recast prints a line comment as `<// …`, which TypeScript reads as a
53
+ * closing tag.
54
+ */
55
+ function afterTagName(comment) {
56
+ if (comment.type !== 'CommentLine') {
57
+ return { ...comment, leading: false, trailing: true };
58
+ }
59
+ return {
60
+ type: 'CommentBlock',
61
+ value: ` ${comment.value.trim().replace(/\*\//g, '*\\/')} `,
62
+ leading: false,
63
+ trailing: true,
64
+ };
65
+ }
50
66
  /** A lowercase intrinsic tag: not a component, not a custom element. */
51
67
  const INTRINSIC = /^[a-z][a-z0-9]*$/;
52
68
  /** Subtrees whose tags are not HTML. */
@@ -325,10 +341,21 @@ export default function transform(fileInfo, api, options = {}) {
325
341
  if (child.type !== 'JSXElement')
326
342
  return [];
327
343
  const target = planned.get(child)?.conversion?.target ??
344
+ planned.get(child)?.fold?.target ??
328
345
  // A direct child is looked up in the element's own scope, the child's.
329
346
  bestaxTarget(child, elementPath);
330
347
  return target ? [target] : [];
331
348
  });
349
+ /**
350
+ * The one element an element holds, when it holds nothing else: no text
351
+ * React renders, and no comment, which folding the element would drop.
352
+ */
353
+ const soleChild = (element) => {
354
+ const content = (element.children ?? []).filter((child) => child.type !== 'JSXText' || reachesReact(child));
355
+ return content.length === 1 && content[0].type === 'JSXElement'
356
+ ? content[0]
357
+ : undefined;
358
+ };
332
359
  // For each element, the bestax components already in the file inside it:
333
360
  // `Field` and `Control` change how bestax's form controls render.
334
361
  const bestaxInside = new Map();
@@ -399,17 +426,19 @@ export default function transform(fileInfo, api, options = {}) {
399
426
  hasRef: attributes.has('ref'),
400
427
  hasChildren: (element.children ?? []).some(reachesReact),
401
428
  childTargets: childTargets(elementPath),
429
+ soleChildTarget: planned.get(soleChild(element))?.conversion?.target,
402
430
  bestaxInside: bestaxInside.get(element) ?? [],
403
431
  bestaxAround: surrounding.bestax,
404
432
  componentsAround: surrounding.other,
405
433
  onlyChildOf: onlyChildOf(elementPath, bestaxLocals),
406
434
  };
407
435
  let result = plan(facts);
408
- const converts = result.conversion !== null;
409
- if (className === null && result.conversion) {
436
+ const converts = result.conversion !== null || result.fold !== undefined;
437
+ const becomes = result.conversion?.target ?? result.fold?.target;
438
+ if (className === null && becomes) {
410
439
  // The same element with a static className would convert; with a
411
440
  // computed one, only a person can turn each condition into its prop.
412
- const target = result.conversion.target;
441
+ const target = becomes;
413
442
  result = {
414
443
  conversion: null,
415
444
  todos: [
@@ -421,8 +450,15 @@ export default function transform(fileInfo, api, options = {}) {
421
450
  ],
422
451
  };
423
452
  }
453
+ if (result.fold) {
454
+ // The wrapper's props join its child's conversion, which has not been
455
+ // applied yet: conversions are applied after every element is planned.
456
+ const inner = planned.get(soleChild(element)).conversion;
457
+ inner.props.push(...result.fold.props);
458
+ inner.numbers.push(...result.fold.numbers);
459
+ }
424
460
  planned.set(element, result);
425
- if (result.conversion || result.todos.length > 0) {
461
+ if (result.conversion || result.fold || result.todos.length > 0) {
426
462
  elements.unshift({ path: elementPath, plan: result, converts });
427
463
  }
428
464
  }
@@ -436,7 +472,7 @@ export default function transform(fileInfo, api, options = {}) {
436
472
  if (converting)
437
473
  addTodo(ctx, elements[0].path, rule, message);
438
474
  for (const element of elements) {
439
- element.plan = { ...element.plan, conversion: null };
475
+ element.plan = { ...element.plan, conversion: null, fold: undefined };
440
476
  }
441
477
  };
442
478
  const runtime = fileJsxRuntime(root, j) ??
@@ -482,6 +518,32 @@ export default function transform(fileInfo, api, options = {}) {
482
518
  }
483
519
  }
484
520
  for (const { path: elementPath, plan: result } of [...elements].reverse()) {
521
+ if (result.fold) {
522
+ // The child inside has converted already (innermost first), with the
523
+ // wrapper's props on it; the wrapper itself goes, its comments with the
524
+ // child: one on the wrapper moves to the child, and one inside the
525
+ // wrapper's tags moves inside the child's opening tag.
526
+ const wrapper = elementPath.node;
527
+ const inner = soleChild(wrapper);
528
+ const { openingElement, closingElement } = wrapper;
529
+ const inTags = [
530
+ openingElement,
531
+ openingElement.name,
532
+ ...(openingElement.attributes ?? []),
533
+ closingElement,
534
+ closingElement?.name,
535
+ ].flatMap((node) => node?.comments ?? []);
536
+ if (inTags.length) {
537
+ const name = inner.openingElement.name;
538
+ name.comments = [...(name.comments ?? []), ...inTags.map(afterTagName)];
539
+ }
540
+ if (wrapper.comments?.length) {
541
+ inner.comments = [...wrapper.comments, ...(inner.comments ?? [])];
542
+ }
543
+ elementPath.replace(inner);
544
+ ctx.dirty = true;
545
+ continue;
546
+ }
485
547
  const conversion = result.conversion;
486
548
  if (!conversion)
487
549
  continue;
@@ -506,19 +568,7 @@ export default function transform(fileInfo, api, options = {}) {
506
568
  const carrier = replacement[0] ?? attrs.find((attr) => attr !== classAttr) ?? name;
507
569
  carrier.comments = [
508
570
  ...(carrier.comments ?? []),
509
- ...classAttr.comments.map((comment) => {
510
- if (carrier !== name)
511
- return comment;
512
- if (comment.type !== 'CommentLine') {
513
- return { ...comment, leading: false, trailing: true };
514
- }
515
- return {
516
- type: 'CommentBlock',
517
- value: ` ${comment.value.trim().replace(/\*\//g, '*\\/')} `,
518
- leading: false,
519
- trailing: true,
520
- };
521
- }),
571
+ ...classAttr.comments.map((comment) => carrier === name ? afterTagName(comment) : comment),
522
572
  ];
523
573
  }
524
574
  attrs.splice(attrs.indexOf(classAttr), 1, ...replacement);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "bestax-migrate",
3
- "version": "2.8.0",
3
+ "version": "2.9.0",
4
4
  "description": "Codemods for migrating existing React apps from other Bulma libraries to @allxsmith/bestax-bulma",
5
5
  "type": "module",
6
6
  "bin": {