bestax-migrate 2.20.0 → 2.21.1

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.
@@ -1 +1 @@
1
- {"version":3,"file":"props.d.ts","sourceRoot":"","sources":["../../../src/sources/_shared/props.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,aAAa,CAAC;AAC3C,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,gBAAgB,CAAC;AACjD,OAAO,EAUL,KAAK,gBAAgB,EACtB,MAAM,gBAAgB,CAAC;AAIxB;;;;GAIG;AACH,wBAAgB,YAAY,CAC1B,GAAG,EAAE,gBAAgB,EACrB,IAAI,EAAE,OAAO,CAAC,GAAG,CAAC,EAClB,OAAO,EAAE,GAAG,EACZ,YAAY,EAAE,MAAM,EACpB,IAAI,EAAE,MAAM,EACZ,KAAK,EAAE,MAAM,GAAG,SAAS,GACxB,IAAI,CAEN;AAED;;;GAGG;AACH,wBAAgB,WAAW,CACzB,GAAG,EAAE,gBAAgB,EACrB,IAAI,EAAE,OAAO,CAAC,GAAG,CAAC,EAClB,OAAO,EAAE,GAAG,EACZ,YAAY,EAAE,MAAM,EACpB,IAAI,EAAE,GAAG,GACR,IAAI,CAmBN;AAED;;;;GAIG;AACH,wBAAgB,UAAU,CACxB,GAAG,EAAE,gBAAgB,EACrB,IAAI,EAAE,OAAO,CAAC,GAAG,CAAC,EAClB,OAAO,EAAE,GAAG,EACZ,GAAG,EAAE,MAAM,EACX,YAAY,EAAE,MAAM,GACnB,IAAI,CAoBN;AAED,mDAAmD;AACnD,wBAAgB,eAAe,CAC7B,GAAG,EAAE,gBAAgB,EACrB,IAAI,EAAE,OAAO,CAAC,GAAG,CAAC,EAClB,OAAO,EAAE,GAAG,EACZ,IAAI,EAAE,GAAG,EACT,MAAM,EAAE,UAAU,GACjB,IAAI,CAqLN;AAED;;;;GAIG;AACH,wBAAgB,mBAAmB,CACjC,GAAG,EAAE,gBAAgB,EACrB,IAAI,EAAE,OAAO,CAAC,GAAG,CAAC,EAClB,OAAO,EAAE,GAAG,EACZ,OAAO,EAAE,GAAG,CAAC,MAAM,CAAC,EACpB,cAAc,EAAE,MAAM,CAAC,MAAM,EAAE,UAAU,CAAC,GACzC,IAAI,CAQN"}
1
+ {"version":3,"file":"props.d.ts","sourceRoot":"","sources":["../../../src/sources/_shared/props.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,aAAa,CAAC;AAC3C,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,gBAAgB,CAAC;AACjD,OAAO,EAUL,KAAK,gBAAgB,EACtB,MAAM,gBAAgB,CAAC;AAIxB;;;;GAIG;AACH,wBAAgB,YAAY,CAC1B,GAAG,EAAE,gBAAgB,EACrB,IAAI,EAAE,OAAO,CAAC,GAAG,CAAC,EAClB,OAAO,EAAE,GAAG,EACZ,YAAY,EAAE,MAAM,EACpB,IAAI,EAAE,MAAM,EACZ,KAAK,EAAE,MAAM,GAAG,SAAS,GACxB,IAAI,CAEN;AAED;;;GAGG;AACH,wBAAgB,WAAW,CACzB,GAAG,EAAE,gBAAgB,EACrB,IAAI,EAAE,OAAO,CAAC,GAAG,CAAC,EAClB,OAAO,EAAE,GAAG,EACZ,YAAY,EAAE,MAAM,EACpB,IAAI,EAAE,GAAG,GACR,IAAI,CAmBN;AAED;;;;GAIG;AACH,wBAAgB,UAAU,CACxB,GAAG,EAAE,gBAAgB,EACrB,IAAI,EAAE,OAAO,CAAC,GAAG,CAAC,EAClB,OAAO,EAAE,GAAG,EACZ,GAAG,EAAE,MAAM,EACX,YAAY,EAAE,MAAM,GACnB,IAAI,CAoBN;AAED,mDAAmD;AACnD,wBAAgB,eAAe,CAC7B,GAAG,EAAE,gBAAgB,EACrB,IAAI,EAAE,OAAO,CAAC,GAAG,CAAC,EAClB,OAAO,EAAE,GAAG,EACZ,IAAI,EAAE,GAAG,EACT,MAAM,EAAE,UAAU,GACjB,IAAI,CA8LN;AAED;;;;GAIG;AACH,wBAAgB,mBAAmB,CACjC,GAAG,EAAE,gBAAgB,EACrB,IAAI,EAAE,OAAO,CAAC,GAAG,CAAC,EAClB,OAAO,EAAE,GAAG,EACZ,OAAO,EAAE,GAAG,CAAC,MAAM,CAAC,EACpB,cAAc,EAAE,MAAM,CAAC,MAAM,EAAE,UAAU,CAAC,GACzC,IAAI,CAQN"}
@@ -94,10 +94,17 @@ export function applyPropAction(ctx, path, element, attr, action) {
94
94
  return;
95
95
  }
96
96
  const literal = literalValueOf(attr);
97
+ // A number literal is keyed by its string form (`delta={0}` by `'0'`).
98
+ const todoKey = literal.kind === 'string' || literal.kind === 'number'
99
+ ? String(literal.value)
100
+ : undefined;
97
101
  if (action.valueTodo &&
98
- literal.kind === 'string' &&
99
- action.valueTodo[literal.value]) {
100
- addTodo(ctx, path, `prop:${originalName}`, `\`${originalName}="${literal.value}"\` — ${action.valueTodo[literal.value]}`);
102
+ todoKey !== undefined &&
103
+ Object.hasOwn(action.valueTodo, todoKey)) {
104
+ const written = literal.kind === 'number'
105
+ ? `${originalName}={${todoKey}}`
106
+ : `${originalName}="${todoKey}"`;
107
+ addTodo(ctx, path, `prop:${originalName}`, `\`${written}\` — ${action.valueTodo[todoKey]}`);
101
108
  return;
102
109
  }
103
110
  if (action.valueToProp) {
@@ -58,9 +58,28 @@ export interface Absorbs {
58
58
  * Where the target puts the attributes it is given. On the child
59
59
  * (`SelectBase`): the child's become the target's, and the element may
60
60
  * carry none but a `key`. On the element (`Breadcrumb`): the element's
61
- * stay, and the child may carry none.
61
+ * stay, and the child may carry none. Split (`Menu.Item`): the ones in
62
+ * `elementProps` go on the element and the rest on the child, so each may
63
+ * carry only its own share.
62
64
  */
63
- readonly attributesOn: 'child' | 'element';
65
+ readonly attributesOn: 'child' | 'element' | 'split';
66
+ /**
67
+ * With the attributes split: the ones the target puts on the element. The
68
+ * element's `key` stays with the component in its place.
69
+ */
70
+ readonly elementProps?: readonly string[];
71
+ /**
72
+ * An element the target renders after the child, from among its children
73
+ * (`Menu.Item`'s nested list, a `Menu.List`). The element converts beside
74
+ * one of these after the child, bare, and nothing else: it becomes
75
+ * `target` and moves in after the child's children. That target renders no
76
+ * class of its own only inside another one, so the element converts with
77
+ * it only inside one too.
78
+ */
79
+ readonly after?: {
80
+ readonly tag: string;
81
+ readonly target: string;
82
+ };
64
83
  /**
65
84
  * With the attributes on the element: the child's that the target takes as
66
85
  * props of its own and writes back on the child (`Image`'s `src` and `alt`).
@@ -208,9 +227,10 @@ export interface RootEntry {
208
227
  };
209
228
  /**
210
229
  * Attributes the target types as numbers, among the ones it is given (the
211
- * child's, when it `absorbs` the child and puts them there). A numeric
212
- * string (`value="40"`) becomes a number, which renders the same; any
213
- * other string refuses.
230
+ * child's, when it `absorbs` the child and puts them there), beside
231
+ * `NUMBER_ATTRS`, which every target types that way. A numeric string
232
+ * (`value="40"`) becomes a number, which renders the same; any other
233
+ * string refuses.
214
234
  */
215
235
  readonly numberAttrs?: readonly string[];
216
236
  /** Attributes the target drops: on these tags, or on all tags except these. */
@@ -253,12 +273,25 @@ export declare const VIEWPORTS: readonly ["mobile", "tablet", "tablet-only", "to
253
273
  /** `tablet-only` → `TabletOnly`: the suffix bestax puts on per-viewport props. */
254
274
  export declare function viewportSuffix(viewport: string): string;
255
275
  export declare const ROOTS: Readonly<Record<string, RootEntry>>;
276
+ /**
277
+ * Elements found by where they sit rather than by a class, keyed by the root
278
+ * of the list around them: a `<li>` whose nearest element is a `.menu-list`,
279
+ * a `Menu.List`, or the bare `<ul>` nested in one of its items.
280
+ */
281
+ export declare const PLACED: Readonly<Record<string, RootEntry>>;
256
282
  /**
257
283
  * Which root wins when an element carries two (`column box`): layout before
258
284
  * surface, so the element keeps the role that decides where it sits. The
259
285
  * other root stays in `className`, which renders the same either way.
260
286
  */
261
287
  export declare const PRECEDENCE: readonly string[];
288
+ /**
289
+ * Attributes every target types as a number, as React types them on any
290
+ * element: a `tabIndex="0"` converts as `tabIndex={0}`.
291
+ */
292
+ export declare const NUMBER_ATTRS: readonly string[];
293
+ /** The attributes an entry's target types as numbers. */
294
+ export declare function numberAttrsOf(entry: RootEntry): readonly string[];
262
295
  /** Refs reach the element only through these targets. */
263
296
  export declare const FORWARDS_REF: readonly string[];
264
297
  /**
@@ -302,6 +335,8 @@ export declare const PASSTHROUGH: ReadonlyArray<{
302
335
  export declare function passthroughReason(token: string): string | undefined;
303
336
  /** The table's entry for a class. */
304
337
  export declare function rootFor(token: string): RootEntry | undefined;
338
+ /** The entry for an element found by the root of the list around it. */
339
+ export declare function placedFor(list: string): RootEntry | undefined;
305
340
  /**
306
341
  * A class that decides what its element is, for a TODO: a root the table
307
342
  * converts or a family's outermost class. Parts and `plain` roots are not.
@@ -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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"}
@@ -1313,7 +1313,8 @@ export const ROOTS = {
1313
1313
  ],
1314
1314
  },
1315
1315
  // `Menu`, `Menu.Label` and `Menu.List` take every helper prop, `color` and
1316
- // `backgroundColor` included. The items inside a list stay markup.
1316
+ // `backgroundColor` included. The items inside a list carry no class, so
1317
+ // `PLACED` finds them by where they sit.
1317
1318
  menu: {
1318
1319
  ...BASE,
1319
1320
  target: 'Menu',
@@ -1342,7 +1343,7 @@ export const ROOTS = {
1342
1343
  topLevelOnly: true,
1343
1344
  ownProps: [],
1344
1345
  },
1345
- 'menu-item': todo('Menu.Item', 'bestax `Menu.Item` renders the `<li>` and the `<a>` together'),
1346
+ 'menu-item': todo('Menu.Item', 'bestax `Menu.Item` renders the element inside its `<li>` with no class but `is-active`'),
1346
1347
  message: todo('Message', 'bestax `Message` always wraps its children in `.message-body`'),
1347
1348
  'message-header': part(),
1348
1349
  'message-body': part(),
@@ -1447,6 +1448,13 @@ export const ROOTS = {
1447
1448
  'total',
1448
1449
  'current',
1449
1450
  'onPageChange',
1451
+ 'siblingCount',
1452
+ 'boundaryCount',
1453
+ 'previousLabel',
1454
+ 'nextLabel',
1455
+ 'disabled',
1456
+ 'getPageHref',
1457
+ 'getPageLabel',
1450
1458
  ],
1451
1459
  },
1452
1460
  'pagination-list': {
@@ -1465,7 +1473,6 @@ export const ROOTS = {
1465
1473
  bgColor: null,
1466
1474
  noHelpers: true,
1467
1475
  defaults: { tabIndex: '0' },
1468
- numberAttrs: ['tabIndex'],
1469
1476
  omits: {
1470
1477
  'is-disabled': '`disabled` also writes `aria-disabled` and `tabIndex="-1"`',
1471
1478
  },
@@ -1479,7 +1486,6 @@ export const ROOTS = {
1479
1486
  bgColor: null,
1480
1487
  noHelpers: true,
1481
1488
  defaults: { tabIndex: '0' },
1482
- numberAttrs: ['tabIndex'],
1483
1489
  omits: {
1484
1490
  'is-disabled': '`disabled` also writes `aria-disabled` and `tabIndex="-1"`',
1485
1491
  },
@@ -1633,6 +1639,33 @@ function part() {
1633
1639
  function plain(why) {
1634
1640
  return { status: 'plain', why };
1635
1641
  }
1642
+ /**
1643
+ * Elements found by where they sit rather than by a class, keyed by the root
1644
+ * of the list around them: a `<li>` whose nearest element is a `.menu-list`,
1645
+ * a `Menu.List`, or the bare `<ul>` nested in one of its items.
1646
+ */
1647
+ export const PLACED = {
1648
+ // `Menu.Item` renders the `<li>` and the `<a>` inside it together. Its
1649
+ // helper props go on the `<a>`, so the `<li>`'s classes all stay classes.
1650
+ 'menu-list': {
1651
+ ...BASE,
1652
+ target: 'Menu.Item',
1653
+ tag: 'li',
1654
+ textColor: null,
1655
+ bgColor: null,
1656
+ noHelpers: true,
1657
+ requiresChildren: true,
1658
+ absorbs: {
1659
+ tag: 'a',
1660
+ attributesOn: 'split',
1661
+ elementProps: ['id', 'title', 'role', 'tabIndex', 'style', 'data-testid'],
1662
+ modifiers: flags({ 'is-active': 'active' }),
1663
+ after: { tag: 'ul', target: 'Menu.List' },
1664
+ },
1665
+ ownProps: ['as', 'active'],
1666
+ passThrough: ['id', 'title', 'role', 'tabIndex', 'style', 'data-testid'],
1667
+ },
1668
+ };
1636
1669
  /**
1637
1670
  * Which root wins when an element carries two (`column box`): layout before
1638
1671
  * surface, so the element keeps the role that decides where it sits. The
@@ -1695,10 +1728,20 @@ export const PRECEDENCE = [
1695
1728
  'content',
1696
1729
  'block',
1697
1730
  ];
1731
+ /**
1732
+ * Attributes every target types as a number, as React types them on any
1733
+ * element: a `tabIndex="0"` converts as `tabIndex={0}`.
1734
+ */
1735
+ export const NUMBER_ATTRS = ['tabIndex'];
1736
+ /** The attributes an entry's target types as numbers. */
1737
+ export function numberAttrsOf(entry) {
1738
+ return [...new Set([...NUMBER_ATTRS, ...(entry.numberAttrs ?? [])])];
1739
+ }
1698
1740
  /** Refs reach the element only through these targets. */
1699
1741
  export const FORWARDS_REF = [
1700
1742
  'Button',
1701
1743
  'Link',
1744
+ 'Menu.Item',
1702
1745
  'Navbar',
1703
1746
  'Navbar.Item',
1704
1747
  'Control',
@@ -1902,6 +1945,10 @@ function own(record, key) {
1902
1945
  export function rootFor(token) {
1903
1946
  return own(ROOTS, token);
1904
1947
  }
1948
+ /** The entry for an element found by the root of the list around it. */
1949
+ export function placedFor(list) {
1950
+ return own(PLACED, list);
1951
+ }
1905
1952
  /**
1906
1953
  * A class that decides what its element is, for a TODO: a root the table
1907
1954
  * converts or a family's outermost class. Parts and `plain` roots are not.
@@ -77,6 +77,17 @@ export interface ElementFacts {
77
77
  * reach into it with `cloneElement`.
78
78
  */
79
79
  onlyChildOf?: string;
80
+ /**
81
+ * The root of the list the element is an item of (`menu-list`), when that
82
+ * list is one `PLACED` names: the element converts as that entry, whatever
83
+ * classes it carries.
84
+ */
85
+ itemOf?: string;
86
+ /**
87
+ * The element's `className` holds no class, so it renders `class=""`
88
+ * (`tokens` is empty either way).
89
+ */
90
+ emptyClass?: boolean;
80
91
  }
81
92
  export interface ChildFacts {
82
93
  tag: string;
@@ -127,6 +138,11 @@ export interface Conversion {
127
138
  renames: Array<[from: string, to: string]>;
128
139
  /** Child attributes a prop above renders instead. */
129
140
  drop: string[];
141
+ /**
142
+ * What the element after the child becomes (`Menu.List`), when it has
143
+ * one: it moves in after the child's children.
144
+ */
145
+ after?: string;
130
146
  };
131
147
  /**
132
148
  * The target renders the element's children itself, from a prop above:
@@ -1 +1 @@
1
- {"version":3,"file":"plan.d.ts","sourceRoot":"","sources":["../../../src/sources/bulma-classes/plan.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"plan.d.ts","sourceRoot":"","sources":["../../../src/sources/bulma-classes/plan.ts"],"names":[],"mappings":"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"}
@@ -9,7 +9,7 @@
9
9
  * the whole element with a TODO (an attribute or tag the component would
10
10
  * render differently).
11
11
  */
12
- import { FORWARDS_REF, HELPER_PROPS, HELPER_TOKENS, inTagSet, legacyHint, modifierFor, PRECEDENCE, rootFor, WRAPPER_OWN_PROPS, wrapperFor, } from './class-map.js';
12
+ import { FORWARDS_REF, HELPER_PROPS, HELPER_TOKENS, inTagSet, legacyHint, modifierFor, numberAttrsOf, placedFor, PRECEDENCE, rootFor, WRAPPER_OWN_PROPS, wrapperFor, } from './class-map.js';
13
13
  import { ruleId } from './rules.js';
14
14
  function wrapperEntry(tag) {
15
15
  const target = wrapperFor(tag);
@@ -67,14 +67,24 @@ export function plan(facts) {
67
67
  });
68
68
  return { conversion: null, todos };
69
69
  }
70
- const wrapper = tokens.find(token => rootFor(token)?.status === 'fold');
70
+ // An item of a list is what it is by where it sits, so its own classes all
71
+ // stay: none of them decides what it becomes.
72
+ const placed = facts.itemOf ? placedFor(facts.itemOf) : undefined;
73
+ const wrapper = placed
74
+ ? undefined
75
+ : tokens.find(token => rootFor(token)?.status === 'fold');
71
76
  if (wrapper)
72
77
  return planFold(facts, wrapper, todos);
73
- const root = tokens
74
- .filter(token => rootFor(token)?.status === 'mapped')
75
- .sort((a, b) => precedence(a) - precedence(b))[0];
78
+ const root = placed
79
+ ? undefined
80
+ : tokens
81
+ .filter(token => rootFor(token)?.status === 'mapped')
82
+ .sort((a, b) => precedence(a) - precedence(b))[0];
76
83
  let entry;
77
- if (root) {
84
+ if (placed) {
85
+ entry = placed;
86
+ }
87
+ else if (root) {
78
88
  entry = rootFor(root);
79
89
  }
80
90
  else {
@@ -86,6 +96,12 @@ export function plan(facts) {
86
96
  entry = wrapperEntry(tag);
87
97
  if (!entry)
88
98
  return { conversion: null, todos };
99
+ // A wrapper exists only to carry helper props, so a tag none of whose
100
+ // classes becomes one stays as it is, and nothing else about it is worth
101
+ // a TODO.
102
+ if (propsFrom(entry, tokens, tag, undefined).writes.size === 0) {
103
+ return { conversion: null, todos };
104
+ }
89
105
  }
90
106
  const target = entry.target;
91
107
  const refuse = (kind, token, message) => ({
@@ -102,12 +118,18 @@ export function plan(facts) {
102
118
  if (facts.onlyChildOf) {
103
119
  return refuse('only-child', target, `this element is the only child of \`<${facts.onlyChildOf}>\`, which may hand it props or a ref with \`cloneElement\` (next/link's legacy behavior, a tooltip, a Radix \`asChild\` trigger) that bestax \`${target}\` would not take the same way; convert it by hand if \`<${facts.onlyChildOf}>\` only renders its children`);
104
120
  }
121
+ // An element converts with no class left only when found by where it sits,
122
+ // and then an empty `className` would go with nothing to render it.
123
+ if (placed && facts.emptyClass) {
124
+ return refuse('attr', 'className', `this element has an empty \`className\`, which renders \`class=""\`, and bestax \`${target}\` renders it with no class attribute; drop the empty \`className\`, then re-run`);
125
+ }
105
126
  // The attributes the target is given: the element's, or its only child's
106
127
  // when the target renders that child itself and puts them there.
107
128
  let attributes = facts.attributes;
108
129
  let absorbed;
109
130
  if (entry.absorbs) {
110
- const outcome = absorb(facts, root, entry, target, refuse);
131
+ const where = root ? `\`.${root}\`` : `the <${tag}>`;
132
+ const outcome = absorb(facts, where, entry, target, refuse);
111
133
  if (!('todos' in outcome)) {
112
134
  ({ attributes, absorbed } = outcome);
113
135
  }
@@ -158,7 +180,7 @@ export function plan(facts) {
158
180
  return refuse('attr', name, `bestax \`${target}\`'s props take no \`${name}\`${entry.defaults?.[name] ? `, and it renders \`${name}="${entry.defaults[name]}"\` when none is given` : ''}; keep this element as markup`);
159
181
  }
160
182
  const numbers = [];
161
- for (const name of entry.numberAttrs ?? []) {
183
+ for (const name of numberAttrsOf(entry)) {
162
184
  const value = attributes.get(name);
163
185
  if (typeof value !== 'string')
164
186
  continue;
@@ -252,66 +274,9 @@ export function plan(facts) {
252
274
  }
253
275
  }
254
276
  // ---- Tokens → props ---------------------------------------------------------
255
- // What the root itself needs comes first, so no class can take its prop.
256
- const writes = new Map((entry.writes ?? []).map(write => [write.prop, write.value ?? true]));
257
- /** The tokens each written prop came from, so a group rule can undo it. */
258
- const sourceOf = new Map();
259
- const groupOf = new Map();
260
- const converted = new Set(root ? [root] : []);
261
- for (const token of tokens) {
262
- if (converted.has(token))
263
- continue;
264
- const modifier = modifierFor(entry, token);
265
- if (modifier) {
266
- if (modifier.tagIn && !modifier.tagIn.includes(tag))
267
- continue;
268
- if (modifier.writes.some(write => writes.has(write.prop)))
269
- continue;
270
- for (const write of modifier.writes) {
271
- writes.set(write.prop, write.value ?? true);
272
- sourceOf.set(write.prop, token);
273
- if (write.numeric)
274
- numbers.push(write.prop);
275
- }
276
- converted.add(token);
277
- continue;
278
- }
279
- const helper = entry.noHelpers ? undefined : HELPER_TOKENS.get(token);
280
- if (!helper)
281
- continue;
282
- const prop = helper.group === 'text-color'
283
- ? entry.textColor
284
- : helper.group === 'background'
285
- ? entry.bgColor
286
- : helper.write.prop;
287
- if (!prop || writes.has(prop))
288
- continue;
289
- writes.set(prop, helper.write.value ?? true);
290
- sourceOf.set(prop, token);
291
- groupOf.set(prop, helper.group);
292
- converted.add(token);
293
- }
294
- const undo = (prop) => {
295
- converted.delete(sourceOf.get(prop));
296
- writes.delete(prop);
297
- };
298
- const displayProps = [...writes.keys()].filter(prop => groupOf.get(prop) === 'display');
299
- // bestax drops a base `display` whenever a per-viewport one is set.
300
- if (displayProps.includes('display') && displayProps.length > 1) {
301
- undo('display');
302
- }
303
- // Flex-container helpers only render beside a flex `display`.
304
- const flexDisplay = [...writes].some(([prop, value]) => groupOf.get(prop) === 'display' &&
305
- (value === 'flex' || value === 'inline-flex'));
306
- if (!flexDisplay) {
307
- for (const prop of [...writes.keys()]) {
308
- if (groupOf.get(prop) === 'flex-container')
309
- undo(prop);
310
- }
311
- }
312
- // A wrapper exists only to carry helper props; with none, leave the tag.
313
- if (!root && writes.size === 0)
314
- return { conversion: null, todos };
277
+ const fromTokens = propsFrom(entry, tokens, tag, root);
278
+ const { writes, converted } = fromTokens;
279
+ numbers.push(...fromTokens.numbers);
315
280
  // ---- The tag ------------------------------------------------------------
316
281
  let renders = entry.tag;
317
282
  if (entry.sizeDrivesTag && tag !== 'p' && writes.has('size')) {
@@ -388,25 +353,115 @@ export function plan(facts) {
388
353
  todos,
389
354
  };
390
355
  }
356
+ /**
357
+ * What an element's classes become on `entry`'s target: the props they
358
+ * write, the classes that leave `className`, and the props written as
359
+ * numbers. The group rules apply, so a helper the target would drop (a
360
+ * base `display` beside a per-viewport one, a flex-container helper with no
361
+ * flex `display`) stays a class.
362
+ */
363
+ function propsFrom(entry, tokens, tag, root) {
364
+ const numbers = [];
365
+ // What the root itself needs comes first, so no class can take its prop.
366
+ const writes = new Map((entry.writes ?? []).map(write => [write.prop, write.value ?? true]));
367
+ /** The tokens each written prop came from, so a group rule can undo it. */
368
+ const sourceOf = new Map();
369
+ const groupOf = new Map();
370
+ const converted = new Set(root ? [root] : []);
371
+ for (const token of tokens) {
372
+ if (converted.has(token))
373
+ continue;
374
+ const modifier = modifierFor(entry, token);
375
+ if (modifier) {
376
+ if (modifier.tagIn && !modifier.tagIn.includes(tag))
377
+ continue;
378
+ if (modifier.writes.some(write => writes.has(write.prop)))
379
+ continue;
380
+ for (const write of modifier.writes) {
381
+ writes.set(write.prop, write.value ?? true);
382
+ sourceOf.set(write.prop, token);
383
+ if (write.numeric)
384
+ numbers.push(write.prop);
385
+ }
386
+ converted.add(token);
387
+ continue;
388
+ }
389
+ const helper = entry.noHelpers ? undefined : HELPER_TOKENS.get(token);
390
+ if (!helper)
391
+ continue;
392
+ const prop = helper.group === 'text-color'
393
+ ? entry.textColor
394
+ : helper.group === 'background'
395
+ ? entry.bgColor
396
+ : helper.write.prop;
397
+ if (!prop || writes.has(prop))
398
+ continue;
399
+ writes.set(prop, helper.write.value ?? true);
400
+ sourceOf.set(prop, token);
401
+ groupOf.set(prop, helper.group);
402
+ converted.add(token);
403
+ }
404
+ const undo = (prop) => {
405
+ converted.delete(sourceOf.get(prop));
406
+ writes.delete(prop);
407
+ };
408
+ const displayProps = [...writes.keys()].filter(prop => groupOf.get(prop) === 'display');
409
+ // bestax drops a base `display` whenever a per-viewport one is set.
410
+ if (displayProps.includes('display') && displayProps.length > 1) {
411
+ undo('display');
412
+ }
413
+ // Flex-container helpers only render beside a flex `display`.
414
+ const flexDisplay = [...writes].some(([prop, value]) => groupOf.get(prop) === 'display' &&
415
+ (value === 'flex' || value === 'inline-flex'));
416
+ if (!flexDisplay) {
417
+ for (const prop of [...writes.keys()]) {
418
+ if (groupOf.get(prop) === 'flex-container')
419
+ undo(prop);
420
+ }
421
+ }
422
+ return { writes, converted, numbers };
423
+ }
391
424
  /** `a`, `a or b`, `a, b or c`, each in backticks. */
392
- function orList(names) {
425
+ function orList(names, word = 'or') {
393
426
  const quoted = names.map(name => `\`${name}\``);
394
427
  return quoted.length > 1
395
- ? `${quoted.slice(0, -1).join(', ')} or ${quoted[quoted.length - 1]}`
428
+ ? `${quoted.slice(0, -1).join(', ')} ${word} ${quoted[quoted.length - 1]}`
396
429
  : quoted[0];
397
430
  }
431
+ /** `a`, `a and b`, `a, b and c`, each in backticks. */
432
+ function andList(names) {
433
+ return orList(names, 'and');
434
+ }
398
435
  /**
399
436
  * The only child an entry's target renders itself (`.select`'s `<select>`):
400
437
  * what its classes become, and the attributes the target is given. It
401
438
  * converts with the element only when the target would render it exactly
402
- * as written.
439
+ * as written. `where` names the element for a message.
403
440
  */
404
- function absorb(facts, root, entry, target, refuse) {
441
+ function absorb(facts, where, entry, target, refuse) {
405
442
  const spec = entry.absorbs;
406
- const child = facts.soleChild;
407
- const itself = `bestax \`${target}\` renders the <${spec.tag}> inside \`.${root}\` itself`;
408
- if (child?.tag !== spec.tag) {
409
- return refuse('children', target, `${itself}, so this element converts only around a single <${spec.tag}>, with nothing else beside it`);
443
+ const after = spec.after;
444
+ // With an element after the child, the two are the element's children.
445
+ const [child, next, ...more] = after
446
+ ? (facts.childElements ?? [])
447
+ : [facts.soleChild];
448
+ const itself = `bestax \`${target}\` renders the <${spec.tag}> inside ${where} itself`;
449
+ if (child?.tag !== spec.tag ||
450
+ more.length > 0 ||
451
+ (next && next.tag !== after?.tag)) {
452
+ return refuse('children', target, after
453
+ ? `${itself}, and a \`${after.target}\` after it from among its children, so this element converts only around a single <${spec.tag}>, and at most one <${after.tag}> after it, with nothing else beside them`
454
+ : `${itself}, so this element converts only around a single <${spec.tag}>, with nothing else beside it`);
455
+ }
456
+ if (next &&
457
+ (next.tokens !== undefined ||
458
+ next.attributes.size > 0 ||
459
+ next.hasSpread ||
460
+ next.isEmpty)) {
461
+ return refuse('children', after.target, `${itself}, and the <${after.tag}> after it as a \`${after.target}\`, which this converts only bare and holding its items, as Bulma nests one; keep this element as markup, or convert it by hand`);
462
+ }
463
+ if (entry.requiresChildren && child.isEmpty && !next) {
464
+ return refuse('children', target, `bestax \`${target}\` requires children, and renders the <${spec.tag}>'s as its own, so this element converts only when the <${spec.tag}> inside holds something; keep it as markup`);
410
465
  }
411
466
  if (child.hasSpread) {
412
467
  return refuse('spread', target, `the <${spec.tag}> inside spreads props, which bestax \`${target}\` may read differently than the <${spec.tag}> did; convert the two to \`${target}\` by hand`);
@@ -431,6 +486,38 @@ function absorb(facts, root, entry, target, refuse) {
431
486
  props.push([write.prop, write.value ?? true]);
432
487
  }
433
488
  }
489
+ // A number literal is carried over as written, like any other expression.
490
+ const given = (value) => typeof value === 'number' ? null : value;
491
+ if (spec.attributesOn === 'split') {
492
+ // Each keeps its own share: the target puts `elementProps` on the
493
+ // element, and everything else on the child.
494
+ const onElement = spec.elementProps ?? [];
495
+ const stray = [...facts.attributes.keys()].find(name => name !== 'key' && !onElement.includes(name));
496
+ if (stray !== undefined) {
497
+ return refuse('attr', stray, `bestax \`${target}\` puts ${andList(['className', ...onElement])} on the <${facts.tag}>, and everything else on the <${spec.tag}> inside, so this element's \`${stray}\` would move there; keep this element as markup`);
498
+ }
499
+ const moved = [...child.attributes.keys()].find(name => name === 'key' || onElement.includes(name));
500
+ if (moved !== undefined) {
501
+ return refuse('attr', moved, moved === 'key'
502
+ ? `the <${spec.tag}> inside has a \`key\`, which would move up to bestax \`${target}\` in place of this element's; keep this element as markup`
503
+ : `bestax \`${target}\` puts \`${moved}\` on the <${facts.tag}>, so the <${spec.tag}>'s would move there; keep this element as markup`);
504
+ }
505
+ return {
506
+ attributes: new Map([
507
+ ...facts.attributes,
508
+ ...[...child.attributes].map(([name, value]) => [
509
+ name,
510
+ given(value),
511
+ ]),
512
+ ]),
513
+ absorbed: {
514
+ props,
515
+ renames: [],
516
+ drop: [],
517
+ ...(next && { after: after.target }),
518
+ },
519
+ };
520
+ }
434
521
  if (spec.attributesOn === 'element') {
435
522
  // The ones the target takes as its own props move up with the child's
436
523
  // other props, and it writes them back on the child.
@@ -448,7 +535,7 @@ function absorb(facts, root, entry, target, refuse) {
448
535
  // nothing but its `key`, which stays with the component in its place.
449
536
  const own = [...facts.attributes.keys()].find(name => name !== 'key');
450
537
  if (own !== undefined) {
451
- return refuse('attr', own, `bestax \`${target}\` puts the attributes it is given on the <${spec.tag}> inside \`.${root}\`, so this element's \`${own}\` would move there; move it onto the <${spec.tag}> if that is what you want, then re-run`);
538
+ return refuse('attr', own, `bestax \`${target}\` puts the attributes it is given on the <${spec.tag}> inside ${where}, so this element's \`${own}\` would move there; move it onto the <${spec.tag}> if that is what you want, then re-run`);
452
539
  }
453
540
  if (child.attributes.has('key')) {
454
541
  return refuse('attr', 'key', `the <${spec.tag}> inside has a \`key\`, which would move up to bestax \`${target}\` in place of this element's; keep this element as markup`);
@@ -463,8 +550,6 @@ function absorb(facts, root, entry, target, refuse) {
463
550
  return refuse('attr', name, `bestax \`${target}\` renders \`${name}\` on the <${spec.tag}> and \`.${token}\` on this element together, from one prop, so the two convert only as a pair, with \`${name}\` written bare; keep this element as markup`);
464
551
  }
465
552
  }
466
- // A number literal is carried over as written, like any other expression.
467
- const given = (value) => typeof value === 'number' ? null : value;
468
553
  const attributes = new Map();
469
554
  const renames = [];
470
555
  for (const [name, value] of child.attributes) {
@@ -1 +1 @@
1
- {"version":3,"file":"rules.d.ts","sourceRoot":"","sources":["../../../src/sources/bulma-classes/rules.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAUH,eAAO,MAAM,KAAK,EAAE,WAAW,CAAC,MAAM,CAapC,CAAC;AA2BH,wBAAgB,YAAY,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAEnD;AAED,wBAAgB,MAAM,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,MAAM,CAK1D"}
1
+ {"version":3,"file":"rules.d.ts","sourceRoot":"","sources":["../../../src/sources/bulma-classes/rules.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAYH,eAAO,MAAM,KAAK,EAAE,WAAW,CAAC,MAAM,CAapC,CAAC;AA4BH,wBAAgB,YAAY,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAEnD;AAED,wBAAgB,MAAM,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,MAAM,CAK1D"}
@@ -10,7 +10,7 @@
10
10
  * tests sweep every refusal the table can produce and hold each id to the
11
11
  * vocabulary, so a gap is still caught.
12
12
  */
13
- import { HELPER_PROPS, LEGACY_09, ROOTS, WRAPPERS, WRAPPER_OWN_PROPS, } from './class-map.js';
13
+ import { HELPER_PROPS, LEGACY_09, NUMBER_ATTRS, PLACED, ROOTS, WRAPPERS, WRAPPER_OWN_PROPS, } from './class-map.js';
14
14
  export const KINDS = new Set([
15
15
  'attr',
16
16
  'children',
@@ -28,7 +28,7 @@ export const KINDS = new Set([
28
28
  const VOCABULARY = new Set([
29
29
  ...Object.keys(ROOTS),
30
30
  ...Object.keys(LEGACY_09),
31
- ...Object.values(ROOTS).flatMap(entry => [
31
+ ...[...Object.values(ROOTS), ...Object.values(PLACED)].flatMap(entry => [
32
32
  ...(entry.target ? [entry.target] : []),
33
33
  ...(entry.ownProps ?? []),
34
34
  ...(entry.passThrough ?? []),
@@ -41,6 +41,7 @@ const VOCABULARY = new Set([
41
41
  ...Object.values(WRAPPERS),
42
42
  ...Object.values(WRAPPER_OWN_PROPS).flat(),
43
43
  ...HELPER_PROPS,
44
+ ...NUMBER_ATTRS,
44
45
  // Refused on every target, so no entry lists them.
45
46
  'dangerouslySetInnerHTML',
46
47
  'children',
@@ -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;AA+tBvD,MAAM,CAAC,OAAO,UAAU,SAAS,CAC/B,QAAQ,EAAE,QAAQ,EAClB,GAAG,EAAE,GAAG,EACR,OAAO,GAAE,gBAAqB,GAC7B,MAAM,GAAG,SAAS,CAshBpB"}
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;AA+xBvD,MAAM,CAAC,OAAO,UAAU,SAAS,CAC/B,QAAQ,EAAE,QAAQ,EAClB,GAAG,EAAE,GAAG,EACR,OAAO,GAAE,gBAAqB,GAC7B,MAAM,GAAG,SAAS,CA6nBpB"}
@@ -23,7 +23,7 @@ import { rewriteStylesheetImports } from '../_shared/css-imports.js';
23
23
  import { BESTAX, buildBestaxImport, placeBestaxImport, seedBestaxImport, } from '../_shared/bestax-import.js';
24
24
  import { plan, } from './plan.js';
25
25
  import { REACT_RUNTIMES, } from './project.js';
26
- import { ROOTS, rootFor } from './class-map.js';
26
+ import { PLACED, placedFor, ROOTS, rootFor } from './class-map.js';
27
27
  import { ruleId } from './rules.js';
28
28
  /**
29
29
  * A part imported under its flat export (`MenuList`, `FieldLabel`) is the
@@ -86,6 +86,11 @@ function afterTagName(comment) {
86
86
  function spliceClassName(element, replacement, carried = []) {
87
87
  const attrs = element.openingElement.attributes;
88
88
  const classAttr = findAttr(element, 'className');
89
+ // An element found by where it sits may have no className to replace.
90
+ if (!classAttr) {
91
+ attrs.push(...replacement);
92
+ return;
93
+ }
89
94
  const kept = replacement.includes(classAttr);
90
95
  const moving = [...(kept ? [] : (classAttr.comments ?? [])), ...carried];
91
96
  if (moving.length > 0) {
@@ -549,6 +554,67 @@ function reachesReact(child) {
549
554
  return isContent(child);
550
555
  return /[^ \t\r\n]/.test(child.value) || !/[\r\n]/.test(child.value);
551
556
  }
557
+ /**
558
+ * The string a JSX text renders: each line trimmed where it meets a line
559
+ * break, blank lines dropped, and the rest joined by a space.
560
+ */
561
+ function jsxTextRenders(value) {
562
+ const lines = value.replace(/\t/g, ' ').split(/\r\n|\n|\r/);
563
+ let lastFilled = 0;
564
+ lines.forEach((line, index) => {
565
+ if (/[^ ]/.test(line))
566
+ lastFilled = index;
567
+ });
568
+ let out = '';
569
+ lines.forEach((line, index) => {
570
+ let trimmed = line;
571
+ if (index > 0)
572
+ trimmed = trimmed.replace(/^ +/, '');
573
+ if (index < lines.length - 1)
574
+ trimmed = trimmed.replace(/ +$/, '');
575
+ if (trimmed)
576
+ out += index === lastFilled ? trimmed : `${trimmed} `;
577
+ });
578
+ return out;
579
+ }
580
+ /**
581
+ * `children` with `next` after them, each on a line of its own. The list
582
+ * is new, so recast prints it afresh, and it prints a text with its leading
583
+ * whitespace gone and its entities decoded (`&lt;` as `<`); a text that
584
+ * would render differently that way goes in as the string it renders.
585
+ */
586
+ function withAfter(j, children, next) {
587
+ const line = () => j.jsxText('\n');
588
+ const kept = children.flatMap((child) => {
589
+ if (child.type !== 'JSXText')
590
+ return [child];
591
+ const renders = jsxTextRenders(child.value);
592
+ if (renders === '')
593
+ return /[\r\n]/.test(child.value) ? [line()] : [];
594
+ // No raw text to compare means no telling it holds no entity.
595
+ const plain = child.extra?.raw === child.value &&
596
+ jsxTextRenders(child.value.trim()) === renders;
597
+ return [
598
+ plain
599
+ ? j.jsxText(child.value.trim())
600
+ : j.jsxExpressionContainer(j.stringLiteral(renders)),
601
+ ];
602
+ });
603
+ const blank = (node) => node?.type === 'JSXText' && node.value === '\n';
604
+ while (blank(kept[0]))
605
+ kept.shift();
606
+ while (blank(kept[kept.length - 1]))
607
+ kept.pop();
608
+ return [...(kept.length > 0 ? [line(), ...kept] : []), line(), next, line()];
609
+ }
610
+ /** A call to an array's `map` or `flatMap`, whose results render in place. */
611
+ function isMapCall(call) {
612
+ const callee = call.callee;
613
+ return ((callee?.type === 'MemberExpression' ||
614
+ callee?.type === 'OptionalMemberExpression') &&
615
+ !callee.computed &&
616
+ (callee.property?.name === 'map' || callee.property?.name === 'flatMap'));
617
+ }
552
618
  /** Whitespace React drops, which nothing is lost with. A comment is kept. */
553
619
  function dropped(child) {
554
620
  return child.type === 'JSXText' && !reachesReact(child);
@@ -776,6 +842,51 @@ export default function transform(fileInfo, api, options = {}) {
776
842
  }
777
843
  return { bestax, other, classes };
778
844
  };
845
+ /**
846
+ * The root of the list an element is an item of, when `PLACED` names it:
847
+ * a `<li>` whose nearest element is a `.menu-list`, a `Menu.List` already
848
+ * in the file, or the bare `<ul>` nested directly in one of those items.
849
+ */
850
+ const itemOf = (elementPath) => {
851
+ const name = elementPath.node.openingElement.name;
852
+ if (name.type !== 'JSXIdentifier')
853
+ return undefined;
854
+ let up = elementPath.parent;
855
+ while (up && up.node?.type !== 'JSXElement') {
856
+ // Handed to a function, the element renders wherever that puts it;
857
+ // an array's own `map` renders it in place.
858
+ if (up.node?.type === 'CallExpression' && !isMapCall(up.node)) {
859
+ return undefined;
860
+ }
861
+ up = up.parent;
862
+ }
863
+ const root = up ? listRoot(up) : undefined;
864
+ return root && placedFor(root).tag === name.name ? root : undefined;
865
+ };
866
+ const listRoot = (listPath) => {
867
+ const list = listPath.node;
868
+ const target = bestaxTarget(list, listPath);
869
+ if (target) {
870
+ return Object.keys(PLACED).find(root => rootFor(root)?.target === target);
871
+ }
872
+ const name = list.openingElement.name;
873
+ if (name.type !== 'JSXIdentifier')
874
+ return undefined;
875
+ const classAttr = findAttr(list, 'className');
876
+ if (classAttr) {
877
+ const root = (staticClassName(classAttr) ?? '')
878
+ .split(/\s+/)
879
+ .find(token => placedFor(token));
880
+ return root && rootFor(root)?.tag === name.name ? root : undefined;
881
+ }
882
+ const holder = listPath.parent;
883
+ if (holder?.node?.type !== 'JSXElement')
884
+ return undefined;
885
+ const root = itemOf(holder);
886
+ return root && placedFor(root).absorbs?.after?.tag === name.name
887
+ ? root
888
+ : undefined;
889
+ };
779
890
  // `converts` is whether the element would become a component with its
780
891
  // classes written out, so it holds for a computed className too.
781
892
  const elements = [];
@@ -789,10 +900,11 @@ export default function transform(fileInfo, api, options = {}) {
789
900
  continue;
790
901
  }
791
902
  const classAttr = findAttr(element, 'className');
792
- if (!classAttr)
903
+ const item = itemOf(elementPath);
904
+ if (!classAttr && !item)
793
905
  continue;
794
906
  const attributes = attributesBesides(element, classAttr, attributeValue);
795
- const className = staticClassName(classAttr);
907
+ const className = classAttr ? staticClassName(classAttr) : '';
796
908
  const surrounding = around(elementPath);
797
909
  const sole = soleChild(element);
798
910
  const facts = {
@@ -813,6 +925,8 @@ export default function transform(fileInfo, api, options = {}) {
813
925
  componentsAround: surrounding.other,
814
926
  classesAround: surrounding.classes,
815
927
  onlyChildOf: onlyChildOf(elementPath, bestaxLocals),
928
+ ...(item && { itemOf: item }),
929
+ ...(classAttr && className?.trim() === '' && { emptyClass: true }),
816
930
  };
817
931
  // A joiner call the codemod can read converts exactly: its fixed classes
818
932
  // as for a static className, and each condition on a flag as its prop.
@@ -869,6 +983,44 @@ export default function transform(fileInfo, api, options = {}) {
869
983
  elements.unshift({ path: elementPath, plan: result, converts });
870
984
  }
871
985
  }
986
+ // An item's nested list becomes a list component that renders its root
987
+ // class unless another is around it (`Menu.List`), so an item with one
988
+ // converts only inside a list that is one, or becomes one here. Outermost
989
+ // first: an item that stays markup leaves its nested list a plain one.
990
+ const becomesAfter = new Set();
991
+ for (const found of elements) {
992
+ const conversion = found.plan.conversion;
993
+ const after = conversion?.absorbs?.after;
994
+ if (!after)
995
+ continue;
996
+ let inside = false;
997
+ for (let up = found.path.parent; up && !inside; up = up.parent) {
998
+ if (up.node?.type !== 'JSXElement')
999
+ continue;
1000
+ inside =
1001
+ becomesAfter.has(up.node) ||
1002
+ (bestaxTarget(up.node, up) ??
1003
+ planned.get(up.node)?.conversion?.target) === after;
1004
+ }
1005
+ if (inside) {
1006
+ const [, next] = (found.path.node.children ?? []).filter((node) => node.type === 'JSXElement');
1007
+ becomesAfter.add(next);
1008
+ continue;
1009
+ }
1010
+ const root = Object.keys(ROOTS).find(key => ROOTS[key].target === after);
1011
+ found.plan = {
1012
+ conversion: null,
1013
+ todos: [
1014
+ ...found.plan.todos,
1015
+ {
1016
+ rule: ruleId('context', conversion.target),
1017
+ message: `bestax \`${conversion.target}\` renders the list nested in it as a \`${after}\`, which renders \`.${root}\` unless another \`${after}\` is around it, and no list around this element is one or becomes one here; keep it as markup, or convert the list around it first, then re-run`,
1018
+ },
1019
+ ],
1020
+ };
1021
+ found.converts = false;
1022
+ planned.set(found.path.node, found.plan);
1023
+ }
872
1024
  if (elements.length === 0)
873
1025
  return print();
874
1026
  // ---- 3. File-level gates ------------------------------------------------------
@@ -952,8 +1104,11 @@ export default function transform(fileInfo, api, options = {}) {
952
1104
  continue;
953
1105
  const element = elementPath.node;
954
1106
  // A target that renders the element's only child itself is written in
955
- // that child's place, so the child's children stay where they are.
956
- const child = conversion.absorbs ? soleChild(element) : undefined;
1107
+ // that child's place, so the child's children stay where they are. One
1108
+ // that renders an element after it takes that one in after them.
1109
+ const [child, next] = conversion.absorbs
1110
+ ? (element.children ?? []).filter((node) => node.type === 'JSXElement')
1111
+ : [];
957
1112
  // The element's tags go, and so do the child's tag names: their comments
958
1113
  // move to the name that stays. The child's tags themselves stay, and
959
1114
  // keep their own.
@@ -1032,11 +1187,24 @@ export default function transform(fileInfo, api, options = {}) {
1032
1187
  }
1033
1188
  elementPath.replace(child);
1034
1189
  written = child;
1190
+ const after = conversion.absorbs.after;
1191
+ if (after) {
1192
+ const [listHead, ...listRest] = after.split('.');
1193
+ renameElement(j, next, [ctx.reserve(listHead), ...listRest].join('.'));
1194
+ if (!child.closingElement) {
1195
+ child.openingElement.selfClosing = false;
1196
+ child.closingElement = j.jsxClosingElement(element.closingElement.name);
1197
+ }
1198
+ child.children = withAfter(j, child.children ?? [], next);
1199
+ }
1035
1200
  }
1036
1201
  // After the splice, so a prop the conversion wrote is found as well as
1037
1202
  // an attribute the element already had.
1038
1203
  for (const name of conversion.numbers) {
1039
1204
  const attr = findAttr(written, name);
1205
+ // One the conversion dropped has nothing left to write.
1206
+ if (!attr)
1207
+ continue;
1040
1208
  attr.value = j.jsxExpressionContainer(j.numericLiteral(Number(attributeValue(attr))));
1041
1209
  }
1042
1210
  ctx.dirty = true;
@@ -1 +1 @@
1
- {"version":3,"file":"mapping.d.ts","sourceRoot":"","sources":["../../../src/sources/react-bulma-components/mapping.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAEH,OAAO,KAAK,EAAE,gBAAgB,EAAE,UAAU,EAAE,MAAM,gBAAgB,CAAC;AAOnE;;;;GAIG;AACH,eAAO,MAAM,eAAe,EAAE,MAAM,CAAC,MAAM,EAAE,UAAU,CAgFtD,CAAC;AAEF,gEAAgE;AAChE,eAAO,MAAM,sBAAsB,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI,CAUhE,CAAC;AAIF,eAAO,MAAM,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,gBAAgB,CA6pBpD,CAAC;AAEF;;;;GAIG;AACH,eAAO,MAAM,WAAW,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,EAAE,CAsEhD,CAAC;AAEF,6EAA6E;AAC7E,wBAAgB,cAAc,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,gBAAgB,GAAG,SAAS,CAM3E"}
1
+ {"version":3,"file":"mapping.d.ts","sourceRoot":"","sources":["../../../src/sources/react-bulma-components/mapping.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAEH,OAAO,KAAK,EAAE,gBAAgB,EAAE,UAAU,EAAE,MAAM,gBAAgB,CAAC;AAOnE;;;;GAIG;AACH,eAAO,MAAM,eAAe,EAAE,MAAM,CAAC,MAAM,EAAE,UAAU,CAgFtD,CAAC;AAEF,gEAAgE;AAChE,eAAO,MAAM,sBAAsB,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI,CAUhE,CAAC;AAIF,eAAO,MAAM,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,gBAAgB,CAsqBpD,CAAC;AAEF;;;;GAIG;AACH,eAAO,MAAM,WAAW,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,EAAE,CAsEhD,CAAC;AAEF,6EAA6E;AAC7E,wBAAgB,cAAc,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,gBAAgB,GAAG,SAAS,CAM3E"}
@@ -668,11 +668,20 @@ export const MAPPING = {
668
668
  rounded: {},
669
669
  onChange: { rename: 'onPageChange' },
670
670
  align: { valueMap: { center: 'centered', right: 'right' } },
671
- delta: { todo: 'no delta prop in bestax Pagination' },
672
- next: { todo: 'no custom next label in bestax Pagination' },
673
- previous: { todo: 'no custom previous label in bestax Pagination' },
674
- showPrevNext: { todo: 'no showPrevNext prop in bestax Pagination' },
675
- showFirstLast: { todo: 'no showFirstLast prop in bestax Pagination' },
671
+ delta: {
672
+ rename: 'siblingCount',
673
+ valueTodo: {
674
+ '0': 'RBC renders no page links for it, and bestax Pagination still shows the current, first and last pages from `siblingCount={0}`; compose the parts by hand for a Pagination with no page links',
675
+ },
676
+ },
677
+ next: { rename: 'nextLabel' },
678
+ previous: { rename: 'previousLabel' },
679
+ showPrevNext: {
680
+ todo: 'bestax Pagination always renders Previous and Next from `total`',
681
+ },
682
+ showFirstLast: {
683
+ todo: 'bestax Pagination always shows the first and last pages from `total`, `boundaryCount` of each (1 by default)',
684
+ },
676
685
  autoHide: {
677
686
  todo: 'no autoHide prop in bestax Pagination; render conditionally',
678
687
  },
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "bestax-migrate",
3
- "version": "2.20.0",
3
+ "version": "2.21.1",
4
4
  "description": "Codemods for migrating existing React apps from other Bulma libraries to @allxsmith/bestax-bulma",
5
5
  "type": "module",
6
6
  "bin": {
@@ -38,7 +38,7 @@
38
38
  "chalk": "^6.0.0",
39
39
  "commander": "^15.0.0",
40
40
  "jscodeshift": "^17.3.0",
41
- "@allxsmith/bestax-bulma": "^5.17.0"
41
+ "@allxsmith/bestax-bulma": "^5.18.0"
42
42
  },
43
43
  "devDependencies": {
44
44
  "@jest/globals": "^30.0.0",