bestax-migrate 2.2.1 → 2.2.2

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":"mapping.d.ts","sourceRoot":"","sources":["../../../src/sources/rbx/mapping.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAEH,OAAO,KAAK,EAAE,gBAAgB,EAAE,UAAU,EAAE,MAAM,gBAAgB,CAAC;AAuCnE;;;;;;;;;GASG;AACH,eAAO,MAAM,eAAe,EAAE,MAAM,CAAC,MAAM,EAAE,UAAU,CAiCtD,CAAC;AAEF,uDAAuD;AACvD,eAAO,MAAM,WAAW,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI,CAOrD,CAAC;AAEF,2DAA2D;AAC3D,eAAO,MAAM,aAAa,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI,CAQvD,CAAC;AAEF;;;;GAIG;AACH,eAAO,MAAM,sBAAsB,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI,CAShE,CAAC;AAEF,eAAO,MAAM,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,gBAAgB,CAosBpD,CAAC;AAEF;;;;;;;GAOG;AACH,eAAO,MAAM,WAAW,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,EAAE,CA2FhD,CAAC;AAEF,sDAAsD;AACtD,wBAAgB,cAAc,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,gBAAgB,GAAG,SAAS,CAM3E"}
1
+ {"version":3,"file":"mapping.d.ts","sourceRoot":"","sources":["../../../src/sources/rbx/mapping.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAEH,OAAO,KAAK,EAAE,gBAAgB,EAAE,UAAU,EAAE,MAAM,gBAAgB,CAAC;AAuCnE;;;;;;;;;GASG;AACH,eAAO,MAAM,eAAe,EAAE,MAAM,CAAC,MAAM,EAAE,UAAU,CAiCtD,CAAC;AAEF,uDAAuD;AACvD,eAAO,MAAM,WAAW,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI,CAOrD,CAAC;AAEF,2DAA2D;AAC3D,eAAO,MAAM,aAAa,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI,CAQvD,CAAC;AAEF;;;;GAIG;AACH,eAAO,MAAM,sBAAsB,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI,CAShE,CAAC;AAEF,eAAO,MAAM,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,gBAAgB,CAssBpD,CAAC;AAEF;;;;;;;GAOG;AACH,eAAO,MAAM,WAAW,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,EAAE,CA2FhD,CAAC;AAEF,sDAAsD;AACtD,wBAAgB,cAAc,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,gBAAgB,GAAG,SAAS,CAM3E"}
@@ -126,7 +126,7 @@ export const MAPPING = {
126
126
  },
127
127
  forwardRefAs: {
128
128
  status: 'todo',
129
- todo: '`forwardRefAs` is rbx-internal and has no counterpart. Only the bestax form controls and a few components (Dialog, Sidebar, Toast, Carousel) forward refs; most, Button and Box included, are plain function components that do not — put the ref on a wrapping element you control',
129
+ todo: '`forwardRefAs` is rbx-internal and has no counterpart. bestax forwards a ref from the form controls and from `Button`, `LinkButton`, `Modal`, `Dropdown`, `Navbar` (plus `Navbar.Burger` and `Navbar.Link`), `Dialog`, `Sidebar`, `Toast` and `Carousel` — pass `ref` directly on those. Mind the `Navbar.Dropdown` collision: your rbx `Navbar.Dropdown` is the menu and becomes `Navbar.DropdownMenu`, which forwards no ref, while bestax `Navbar.Dropdown` — the container your `<Navbar.Item dropdown>` becomes — does. The rest, `Box` included, are plain function components that forward no ref; put the ref on a wrapping element you control',
130
130
  },
131
131
  // ---- elements -----------------------------------------------------------
132
132
  Block: { status: 'mapped', target: 'Block' },
@@ -136,6 +136,7 @@ export const MAPPING = {
136
136
  target: 'Button',
137
137
  props: {
138
138
  as: AS_OK,
139
+ innerRef: { rename: 'ref' },
139
140
  color: {},
140
141
  size: {},
141
142
  outlined: { booleanToProp: { name: 'isOutlined' } },
@@ -497,9 +498,7 @@ export const MAPPING = {
497
498
  managed: {
498
499
  todo: 'bestax `Dropdown` is uncontrolled by default; use `active` + `onActiveChange` for controlled behaviour',
499
500
  },
500
- innerRef: {
501
- todo: 'this bestax component is a plain function component and forwards no ref; drop `innerRef`, or put the ref on a wrapping element you control',
502
- },
501
+ innerRef: { rename: 'ref' },
503
502
  },
504
503
  subs: {
505
504
  Container: { status: 'mapped', special: 'dropdown-container' },
@@ -606,25 +605,25 @@ export const MAPPING = {
606
605
  props: {
607
606
  active: {},
608
607
  onClose: {},
609
- closeOnEsc: {
610
- todo: 'bestax `Modal` implements no Escape handling at all; add your own keydown listener, or drop the prop if the behaviour is not needed',
611
- },
608
+ closeOnEsc: { rename: 'closeOnEscape' },
612
609
  closeOnBlur: {
613
- todo: "bestax `Modal` has no built-in background-click close; wire it through `Modal.Background`'s onClick and `onClose`",
610
+ todo: 'bestax `Modal` closes on background click in its legacy form, where it renders its own background wired to `onClose`; a `Modal.Content` or `Modal.Card` child selects the compound form, which renders only the children you wrote — there, add a `<Modal.Background>` whose `onClick` calls your close handler, or drop the prop if you passed false',
614
611
  },
615
612
  document: {
616
- todo: 'bestax `Modal` renders inline where you place it rather than portalling into a document at all; drop this prop, and see the advisory the codemod adds on every Modal',
613
+ todo: 'bestax `Modal` portals via `portal`, but that takes `true`, a selector or an element — not a `Document`. Pass an element from the document you targeted, or drop the prop if you were passing the default document',
617
614
  },
618
615
  containerClassName: { rename: 'className' },
619
- innerRef: {
620
- todo: 'this bestax component is a plain function component and forwards no ref; drop `innerRef`, or put the ref on a wrapping element you control',
621
- },
616
+ innerRef: { rename: 'ref' },
622
617
  },
623
618
  subs: {
624
619
  Background: { status: 'mapped', target: 'Modal.Background' },
625
620
  Close: { status: 'mapped', target: 'Modal.Close' },
626
621
  Content: { status: 'mapped', target: 'Modal.Content' },
627
- Container: { status: 'mapped', special: 'modal-container' },
622
+ Container: {
623
+ status: 'mapped',
624
+ special: 'modal-container',
625
+ props: { innerRef: { rename: 'ref' } },
626
+ },
628
627
  Card: {
629
628
  status: 'mapped',
630
629
  target: 'Modal.Card',
@@ -641,7 +640,7 @@ export const MAPPING = {
641
640
  },
642
641
  Portal: {
643
642
  status: 'todo',
644
- todo: '`Modal.Portal` is rbx-internal; bestax `<Modal>` renders inline and does not portal at all — wrap it in `createPortal` yourself if you relied on that (see the advisory the codemod adds on every Modal)',
643
+ todo: '`Modal.Portal` is rbx-internal; set `portal` on the `<Modal>` instead — it takes `true`, a selector or an element',
645
644
  },
646
645
  },
647
646
  },
@@ -659,13 +658,15 @@ export const MAPPING = {
659
658
  todo: 'bestax `Navbar` is uncontrolled; drop `managed`',
660
659
  },
661
660
  document: { todo: 'bestax `Navbar` has no `document` prop; drop it' },
662
- innerRef: {
663
- todo: 'this bestax component is a plain function component and forwards no ref; drop `innerRef`, or put the ref on a wrapping element you control',
664
- },
661
+ innerRef: { rename: 'ref' },
665
662
  },
666
663
  subs: {
667
664
  Brand: { status: 'mapped', target: 'Navbar.Brand' },
668
- Burger: { status: 'mapped', target: 'Navbar.Burger' },
665
+ Burger: {
666
+ status: 'mapped',
667
+ target: 'Navbar.Burger',
668
+ props: { innerRef: { rename: 'ref' } },
669
+ },
669
670
  Divider: { status: 'mapped', target: 'Navbar.Divider' },
670
671
  Menu: { status: 'mapped', target: 'Navbar.Menu' },
671
672
  Link: {
@@ -673,6 +674,7 @@ export const MAPPING = {
673
674
  target: 'Navbar.Link',
674
675
  props: {
675
676
  as: AS_OK,
677
+ innerRef: { rename: 'ref' },
676
678
  arrowless: {},
677
679
  onClick: {},
678
680
  },
@@ -1 +1 @@
1
- {"version":3,"file":"specials.d.ts","sourceRoot":"","sources":["../../../src/sources/rbx/specials.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAEH,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,aAAa,CAAC;AAO3C,OAAO,EAYL,KAAK,gBAAgB,EACtB,MAAM,yBAAyB,CAAC;AACjC,OAAO,EAML,KAAK,aAAa,EACnB,MAAM,8BAA8B,CAAC;AAEtC,YAAY,EAAE,aAAa,EAAE,CAAC;AAy8B9B,wBAAgB,UAAU,CACxB,IAAI,EAAE,MAAM,EACZ,GAAG,EAAE,gBAAgB,EACrB,IAAI,EAAE,OAAO,CAAC,GAAG,CAAC,EAClB,OAAO,EAAE,GAAG,GACX,aAAa,CAIf"}
1
+ {"version":3,"file":"specials.d.ts","sourceRoot":"","sources":["../../../src/sources/rbx/specials.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAEH,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,aAAa,CAAC;AAO3C,OAAO,EAYL,KAAK,gBAAgB,EACtB,MAAM,yBAAyB,CAAC;AACjC,OAAO,EAML,KAAK,aAAa,EACnB,MAAM,8BAA8B,CAAC;AAEtC,YAAY,EAAE,aAAa,EAAE,CAAC;AAw9B9B,wBAAgB,UAAU,CACxB,IAAI,EAAE,MAAM,EACZ,GAAG,EAAE,gBAAgB,EACrB,IAAI,EAAE,OAAO,CAAC,GAAG,CAAC,EAClB,OAAO,EAAE,GAAG,GACX,aAAa,CAIf"}
@@ -538,15 +538,14 @@ const SPECIALS = {
538
538
  return { ...result, handledProps: ['align', 'as'] };
539
539
  },
540
540
  /**
541
- * The markup maps cleanly, but three rbx behaviours do not exist in bestax
542
- * and none of them fail loudly: rbx portals the modal into `document.body`,
543
- * closes it on Escape by default, and clips document scroll while it is
544
- * open. bestax renders inline and implements none of the three. An
545
- * unmodified `<Modal>` therefore migrates to something that looks right and
546
- * behaves differently, so every conversion is flagged.
541
+ * rbx's Modal portals into `document.body`, closes on Escape and clips
542
+ * document scroll, all by default. bestax matches two of those since #633 —
543
+ * `closeOnEscape` and `lockScroll` both default to `true` — but still
544
+ * renders inline unless `portal` is set. That last difference does not fail
545
+ * loudly, so every conversion is still flagged, now about the portal alone.
547
546
  */
548
547
  modal(ctx, path, _element) {
549
- addTodo(ctx, path, 'component:Modal', 'bestax `Modal` renders inline rather than portalling into document.body, and implements neither Escape-to-close nor scroll locking — rbx did all three by default. Re-add whichever your UI relied on');
548
+ addTodo(ctx, path, 'component:Modal', 'bestax `Modal` closes on Escape and locks body scroll by default, matching rbx, but it renders inline: set `portal` if you relied on rbx portalling into document.body');
550
549
  return {};
551
550
  },
552
551
  /** rbx Modal.Container is the modal itself in bestax. */
@@ -588,6 +587,21 @@ const SPECIALS = {
588
587
  addTodo(ctx, path, `prop:${prop}`, `bestax \`Navbar.Item\` has no \`${prop}\` prop; restructure or add a class by hand`);
589
588
  ctx.dirty = true;
590
589
  }
590
+ // bestax's `Navbar.Dropdown` forwards a ref, but it is the one such target
591
+ // the `innerRef: { rename: 'ref' }` entries in mapping.ts cannot reach:
592
+ // that table is keyed on the rbx name (`Navbar.Item`), and only this
593
+ // handler knows which of the two targets was picked. A plain
594
+ // `Navbar.Item` is still a function component, so the rename is
595
+ // conditional — there, `innerRef` is left alone.
596
+ const renamedInnerRef = [];
597
+ if (target === 'Navbar.Dropdown') {
598
+ const innerRefAttr = findAttr(element, 'innerRef');
599
+ if (innerRefAttr) {
600
+ innerRefAttr.name = ctx.j.jsxIdentifier('ref');
601
+ renamedInnerRef.push('innerRef');
602
+ ctx.dirty = true;
603
+ }
604
+ }
591
605
  restrictAsToTargets(ctx, path, element, target ?? 'Navbar.Item', [
592
606
  'Navbar.Item',
593
607
  ]);
@@ -601,6 +615,7 @@ const SPECIALS = {
601
615
  'expanded',
602
616
  'hoverable',
603
617
  'managed',
618
+ ...renamedInnerRef,
604
619
  ],
605
620
  };
606
621
  },
@@ -26,7 +26,7 @@ export const UNIVERSAL_PROPS = {
26
26
  todo: 'this bestax component has no `as` prop; restructure the element instead',
27
27
  },
28
28
  domRef: {
29
- todo: 'bestax-bulma components do not take domRef; use a ref on a DOM child or wrap the component',
29
+ todo: 'bestax-bulma has no `domRef`. The form controls and `Button`, `LinkButton`, `Modal`, `Dropdown`, `Navbar` (plus `Navbar.Burger` and `Navbar.Link`), `Dialog`, `Sidebar`, `Toast` and `Carousel` forward a ref — on those, rename `domRef` to `ref`. Mind the `Navbar.Dropdown` collision: the `Navbar.Item` that wrapped your dropdown became bestax `Navbar.Dropdown` and forwards one, while your `Navbar.Dropdown` became `Navbar.DropdownMenu` and does not. The rest forward no ref: put the ref on a DOM child or wrap the component',
30
30
  },
31
31
  // ColorProps
32
32
  backgroundColor: { rename: 'bgColor' },
@@ -555,12 +555,12 @@ export const MAPPING = {
555
555
  props: {
556
556
  show: { rename: 'active' },
557
557
  onClose: {},
558
- closeOnEsc: { todo: 'bestax Modal closes on Esc by default; remove' },
558
+ closeOnEsc: { rename: 'closeOnEscape' },
559
559
  closeOnBlur: {
560
- todo: 'bestax Modal background click closes when onClose is set; remove',
560
+ todo: 'bestax Modal closes on background click only in its legacy form; the Modal.Content/Modal.Card child selects the compound form, which renders only the children you wrote — add a `<Modal.Background>` whose `onClick` calls your close handler, or drop the prop if you passed false',
561
561
  },
562
562
  showClose: {
563
- todo: 'bestax Modal renders the close button when onClose is set; remove',
563
+ todo: 'bestax Modal renders a close button only in its legacy form; the Modal.Content/Modal.Card child selects the compound form, which renders only the children you wrote — add a `<Modal.Close variant="floating">` whose `onClick` calls your close handler, or drop the prop if you passed false',
564
564
  },
565
565
  document: { drop: true },
566
566
  },
@@ -1 +1 @@
1
- {"version":3,"file":"specials.d.ts","sourceRoot":"","sources":["../../../src/sources/react-bulma-components/specials.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,aAAa,CAAC;AAE3C,OAAO,EAWL,KAAK,gBAAgB,EACtB,MAAM,yBAAyB,CAAC;AACjC,OAAO,EAML,KAAK,aAAa,EACnB,MAAM,8BAA8B,CAAC;AAEtC,YAAY,EAAE,aAAa,EAAE,CAAC;AAsvB9B,wBAAgB,UAAU,CACxB,IAAI,EAAE,MAAM,EACZ,GAAG,EAAE,gBAAgB,EACrB,IAAI,EAAE,OAAO,CAAC,GAAG,CAAC,EAClB,OAAO,EAAE,GAAG,GACX,aAAa,CAIf;AAED,kEAAkE;AAClE,eAAO,MAAM,gBAAgB,EAAE,MAAM,CAAC,MAAM,EAAE,SAAS,GAAG,QAAQ,CAGjE,CAAC"}
1
+ {"version":3,"file":"specials.d.ts","sourceRoot":"","sources":["../../../src/sources/react-bulma-components/specials.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,aAAa,CAAC;AAE3C,OAAO,EAWL,KAAK,gBAAgB,EACtB,MAAM,yBAAyB,CAAC;AACjC,OAAO,EAML,KAAK,aAAa,EACnB,MAAM,8BAA8B,CAAC;AAEtC,YAAY,EAAE,aAAa,EAAE,CAAC;AAqwB9B,wBAAgB,UAAU,CACxB,IAAI,EAAE,MAAM,EACZ,GAAG,EAAE,gBAAgB,EACrB,IAAI,EAAE,OAAO,CAAC,GAAG,CAAC,EAClB,OAAO,EAAE,GAAG,GACX,aAAa,CAIf;AAED,kEAAkE;AAClE,eAAO,MAAM,gBAAgB,EAAE,MAAM,CAAC,MAAM,EAAE,SAAS,GAAG,QAAQ,CAGjE,CAAC"}
@@ -61,7 +61,18 @@ const SPECIALS = {
61
61
  // (`remove={false}`, `remove=""`, `remove={0}`) → just drop the prop.
62
62
  removeAttr(element, attr);
63
63
  ctx.dirty = true;
64
- return resolved === 'truthy' ? { target: 'Delete' } : {};
64
+ if (resolved !== 'truthy')
65
+ return {};
66
+ // The universal `domRef` advice lists `Button` among the components that
67
+ // forward a ref, but this element is no longer a Button: `Delete` is a
68
+ // plain function component. Claim the prop so that advice cannot fire
69
+ // here, and say what actually applies to the target we picked.
70
+ const handledProps = [];
71
+ if (findAttr(element, 'domRef')) {
72
+ addTodo(ctx, path, 'prop:domRef', 'this `<Button remove>` became bestax `<Delete>`, which forwards no ref — the general `domRef` advice does not apply here; put the ref on a DOM child or wrap the component');
73
+ handledProps.push('domRef');
74
+ }
75
+ return { target: 'Delete', handledProps };
65
76
  }
66
77
  addTodo(ctx, path, 'prop:remove', '`remove` has a dynamic value; this can render as either a Button or a Delete cross — split the branch by hand');
67
78
  return {};
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "bestax-migrate",
3
- "version": "2.2.1",
3
+ "version": "2.2.2",
4
4
  "description": "Codemods for migrating existing React apps from other Bulma libraries to @allxsmith/bestax-bulma",
5
5
  "type": "module",
6
6
  "bin": {
@@ -51,7 +51,7 @@
51
51
  "react-dom": "^19.2.8",
52
52
  "ts-jest": "^29.4.12",
53
53
  "typescript": "^6.0.3",
54
- "@allxsmith/bestax-bulma": "^5.12.0"
54
+ "@allxsmith/bestax-bulma": "^5.15.0"
55
55
  },
56
56
  "publishConfig": {
57
57
  "access": "public"