create-bestax 4.2.3 → 4.2.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/constants.js CHANGED
@@ -182,7 +182,7 @@ automatically when the task matches:
182
182
  - **bestax-layout-scaffold** — scaffold full pages (app shell, landing, centered, card grid).
183
183
  - **bestax-icons** — icons via \`Icon\`/\`IconText\`: library setup, name formats, variants, a11y.
184
184
  - **bestax-optimize** — shrink the built CSS: measure raw+gzip, then flavor switch or a modular Sass build.
185
- - **bestax-migrate** — migrate code off react-bulma-components (v4): run the codemod, resolve its TODOs.
185
+ - **bestax-migrate** — migrate code off react-bulma-components (v4) or rbx (v2): run the codemod, resolve its TODOs.
186
186
 
187
187
  Prefer the library's components and these skills over hand-written Bulma markup or custom CSS.
188
188
  Read skill \`references/\` files with absolute paths — the shell's cwd is not stable between commands.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "create-bestax",
3
- "version": "4.2.3",
3
+ "version": "4.2.4",
4
4
  "description": "Create a new bestax-bulma project",
5
5
  "type": "module",
6
6
  "bin": {
@@ -42,10 +42,10 @@
42
42
  },
43
43
  "devDependencies": {
44
44
  "@jest/globals": "^30.0.0",
45
- "@playwright/test": "^1.62.0",
45
+ "@playwright/test": "^1.62.1",
46
46
  "@types/fs-extra": "^11.0.4",
47
47
  "@types/jest": "^30.0.0",
48
- "@types/node": "^26.1.2",
48
+ "@types/node": "^26.3.0",
49
49
  "@types/prompts": "^2.4.9",
50
50
  "@types/wait-on": "^5.3.4",
51
51
  "jest": "^30.2.0",
@@ -1,15 +1,30 @@
1
1
  ---
2
2
  name: bestax-migrate
3
- description: Migrate an existing app from react-bulma-components (v4) to @allxsmith/bestax-bulma on Bulma v1 run the bestax-migrate codemod, then resolve every TODO(bestax-migrate) comment it leaves using the mapping references. Use when a repo imports react-bulma-components and wants to move to bestax-bulma, when TODO(bestax-migrate) comments are present in a codebase, or when asked to migrate off an unmaintained React Bulma library.
3
+ description: Migrate an existing app from an unmaintained React Bulma library — react-bulma-components (v4) or rbx (v2) — to @allxsmith/bestax-bulma on Bulma v1. Run the bestax-migrate codemod, then resolve every TODO(bestax-migrate) comment it leaves using the per-source mapping references. Use when a repo imports react-bulma-components or rbx and wants to move to bestax-bulma, when TODO(bestax-migrate) comments are present in a codebase, or when asked to migrate off an unmaintained React Bulma library.
4
4
  license: MIT
5
5
  ---
6
6
 
7
- # Migrating from react-bulma-components to bestax-bulma
7
+ # Migrating to bestax-bulma
8
8
 
9
- `react-bulma-components` is unmaintained (last release 2022, Bulma 0.9.x).
10
9
  `@allxsmith/bestax-bulma` is an actively maintained React library for **Bulma v1**. The
11
- `bestax-migrate` codemod automates most of the conversion; this skill drives the codemod and
12
- finishes what it flags.
10
+ `bestax-migrate` codemod automates most of the conversion from an unmaintained predecessor;
11
+ this skill drives the codemod and finishes what it flags.
12
+
13
+ ## Pick the source
14
+
15
+ The codemod's first argument names the library you are migrating _from_. Check the app's
16
+ `package.json` and imports:
17
+
18
+ | Source | Argument | References |
19
+ | -------------------------------------------------------------------- | ------------------------ | ------------------------------------------------------------------------------------------ |
20
+ | `react-bulma-components` v4 (unmaintained since 2022, Bulma 0.9.x) | `react-bulma-components` | [`references/react-bulma-components/`](references/react-bulma-components/component-map.md) |
21
+ | `rbx` v2 (abandoned 2019, pins Bulma **0.7.5** plus four extensions) | `rbx` | [`references/rbx/`](references/rbx/component-map.md) |
22
+
23
+ Everything below is written as `<source>`; substitute the argument from that table. The
24
+ reference paths follow the same split — `references/<source>/component-map.md`,
25
+ `prop-map.md`, `unmappables.md` — while
26
+ [`references/css-migration.md`](references/css-migration.md) is shared, because the stylesheet
27
+ work is about Bulma, not about which wrapper you came from.
13
28
 
14
29
  ## Workflow
15
30
 
@@ -18,15 +33,14 @@ Run these steps in order. Don't hand-convert what the codemod converts automatic
18
33
  1. **Dry-run the codemod** on the source directory and review the report:
19
34
 
20
35
  ```sh
21
- pnpm dlx bestax-migrate react-bulma-components src/ --dry
36
+ pnpm dlx bestax-migrate <source> src/ --dry
22
37
  ```
23
38
 
24
39
  2. **Apply it** (same command without `--dry`), then run the project's formatter — the
25
40
  codemod preserves surrounding formatting but doesn't prettify what it rewrites.
26
41
  Besides the components, it also migrates **stylesheets** (CSS imports →
27
42
  `@allxsmith/bestax-bulma/bestax.css`; SCSS `@import 'bulma/bulma'` + `$var` overrides
28
- → `@use 'bulma/sass' with (…)` plus the bestax extras) and **package.json**
29
- (react-bulma-components removed, bestax-bulma added, bulma → ^1, node-sass → sass).
43
+ → `@use 'bulma/sass' with (…)` plus the bestax extras) and **package.json**.
30
44
  Flags: `--css bulma|keep` for other stylesheet targets, `--no-deps` to leave
31
45
  package.json alone.
32
46
 
@@ -36,16 +50,25 @@ Run these steps in order. Don't hand-convert what the codemod converts automatic
36
50
  npm install # or pnpm/yarn
37
51
  ```
38
52
 
53
+ The report groups its entries by rule. `deps` covers every package.json edit —
54
+ what was removed, added, or left for you to decide; `imports` covers a source
55
+ import the codemod could not rewrite and left in place; `unsupported-file` names
56
+ a file type it cannot parse (`.vue`, `.astro`) that still imports the source;
57
+ `value-reference` marks a component used as a value rather than as JSX. Rules
58
+ named `component:X` and `prop:y` are per-component and per-prop, and each is
59
+ documented in the per-source `references/` pages.
60
+
39
61
  The report's `peer-deps` entries predict install failures: bestax-bulma needs
40
- **React 18/19** (RBC also ran on 17 upgrade react/react-dom first) and its optional
41
- Font Awesome peer wants **FA 6.7** (an app pinned to FA 5 either upgrades or
42
- installs with `npm install --legacy-peer-deps`).
62
+ **React 18/19** (react-bulma-components also ran on 17, and rbx peer-depended on
63
+ **React 16** upgrade react/react-dom first) and its optional Font Awesome peer wants
64
+ **FA 6.7** (an app pinned to FA 5 either upgrades or installs with
65
+ `npm install --legacy-peer-deps`).
43
66
 
44
67
  4. **Resolve every TODO**: `grep -rn "TODO(bestax-migrate)" src/`. Each comment names the
45
68
  prop/component and a hint. Recipes for every recurring case are in
46
- [references/unmappables.md](references/unmappables.md); the full component and prop
47
- tables are in [references/component-map.md](references/component-map.md) and
48
- [references/prop-map.md](references/prop-map.md). Delete each comment as you resolve it.
69
+ `references/<source>/unmappables.md`; the full tables are in
70
+ `references/<source>/component-map.md` and `references/<source>/prop-map.md`. Delete each
71
+ comment as you resolve it.
49
72
 
50
73
  5. **Finish the stylesheet layer** — flagged Sass cases (computed variables,
51
74
  indented-syntax `.sass` files), CSS flavor choice, and Bulma 0.9→1 styling changes:
@@ -56,23 +79,34 @@ Run these steps in order. Don't hand-convert what the codemod converts automatic
56
79
 
57
80
  ## What the codemod handles vs. flags
58
81
 
59
- All 32 react-bulma-components v4 components have a mapping. Imports (named, namespace, and
60
- `const { Input } = Form` destructuring), component renames, prop renames/value conversions,
61
- responsive breakpoint objects, CSS/SCSS stylesheet imports, and package.json dependencies
62
- convert automatically. It flags with
63
- `TODO(bestax-migrate)` instead of guessing: `Element` and `Tile` (no bestax equivalent —
64
- Tile is replaced by Bulma v1's Grid), controlled `Dropdown`/`Dropdown.Item value`,
65
- `touch`/`until*` breakpoints, dynamic prop values it can't rewrite, and props with no
66
- bestax counterpart. Files in formats it can't parse (`.astro`, `.vue`, `.svelte`, `.mdx`)
67
- that import react-bulma-components are reported as `unsupported-file` — migrate those by
68
- hand with the component map. Never "fix" a TODO by silencing it — convert the code per the
69
- references, or deliberately keep the old markup with `className` styling.
82
+ Every export of every supported source has a mapping entry, held to that library's real export
83
+ surface by a coverage test. Imports (named, namespace, and destructuring), component renames,
84
+ prop renames and value conversions, breakpoint objects, CSS/SCSS stylesheet imports, and
85
+ package.json dependencies convert automatically.
86
+
87
+ It flags with `TODO(bestax-migrate)` instead of guessing: components with no bestax equivalent,
88
+ controlled APIs whose shape differs, breakpoints bestax has no prop for, dynamic prop values it
89
+ can't rewrite, and props with no counterpart. Files in formats it can't parse (`.astro`,
90
+ `.vue`, `.svelte`, `.mdx`) that import the source library are reported as `unsupported-file` —
91
+ migrate those by hand with the component map. Never "fix" a TODO by silencing it — convert the
92
+ code per the references, or deliberately keep the old markup with `className` styling.
93
+
94
+ ### Source-specific headlines
95
+
96
+ - **react-bulma-components**: all 32 v4 components are mapped. `Element` and `Tile` have no
97
+ bestax equivalent; `renderAs` becomes `as` where supported.
98
+ - **rbx**: migrating removes rbx itself — it pinned `bulma@0.7.5` as a direct
99
+ dependency plus `bulma-badge`, `bulma-divider`, `bulma-pageloader` and `bulma-tooltip`, so
100
+ the app can finally choose its own Bulma version. rbx's badge and tooltip _helper props_
101
+ become real wrapping `<Badge>` / `<Tooltip>` components. Its `as` is universal, bestax's is
102
+ not. Because rbx pinned Bulma 0.7.5, you cross **two** Bulma majors — expect more visual
103
+ drift than the 0.9 → 1 guide alone describes.
70
104
 
71
105
  ## Rules
72
106
 
73
- - The codemod is idempotent on already-migrated files (it only touches files importing
74
- `react-bulma-components`) — safe to re-run after partial manual work.
75
- - Don't downgrade converted props back to RBC names; bestax uses `is*` booleans
76
- (`isLoading`), string size unions (`textSize="4"`), and `as` instead of `renderAs`.
77
- - If a component the app uses isn't in the component map, it wasn't part of RBC v4 —
78
- check for a local wrapper component and migrate its internals instead.
107
+ - The codemod is idempotent on already-migrated files (it only touches files importing the
108
+ source library) — safe to re-run after partial manual work.
109
+ - Don't downgrade converted props back to the old names; bestax uses `is*` booleans
110
+ (`isLoading`), string size unions (`textSize="4"`), and `as` rather than `renderAs`.
111
+ - If a component the app uses isn't in the component map, it wasn't part of that library's
112
+ public API — check for a local wrapper component and migrate its internals instead.
@@ -1,13 +1,17 @@
1
- # Stylesheets: Bulma 0.9 → Bulma v1 + bestax
1
+ # Stylesheets: pre-1 Bulma → Bulma v1 + bestax
2
2
 
3
- react-bulma-components apps style with Bulma 0.9.x; bestax-bulma targets Bulma v1. The
4
- codemod automates most of this layer this reference explains what it did and how to
5
- finish what it flagged.
3
+ Every library `bestax-migrate` migrates from is pinned to a pre-1 Bulma: react-bulma-components
4
+ to 0.9.x, rbx to 0.7.5. bestax-bulma targets Bulma v1. The codemod automates most of that
5
+ stylesheet layer; this reference explains what it did and how to finish what it flagged.
6
+
7
+ Coming from rbx you are crossing **two** Bulma majors rather than one, so expect more visual
8
+ drift than the 0.9 → 1 notes below describe on their own.
6
9
 
7
10
  ## What the codemod already did (default `--css bestax`)
8
11
 
9
12
  - **CSS imports**: `bulma/css/bulma(.min).css` and v3-era
10
- `react-bulma-components/dist/*.css` imports became the recommended combined bundle
13
+ the source library's own CSS imports (`react-bulma-components/dist/*.css`,
14
+ `rbx/index.css`) became the recommended combined bundle
11
15
  `@allxsmith/bestax-bulma/bestax.css` (Bulma v1 + the bestax extras that themed
12
16
  Radio/Checkbox and the advanced form controls need). A separate `extras.css` import
13
17
  next to it is collapsed.
@@ -43,9 +47,9 @@ finish what it flagged.
43
47
  **dart-sass ≥ 1.79** — the codemod's node-sass replacement installs that, but check
44
48
  bundler-pinned older versions (Parcel's sass transformer pins 1.66).
45
49
 
46
- react-bulma-components' own stylesheet — any `react-bulma-components/…` specifier,
50
+ the source library's own stylesheet — any `react-bulma-components/…` or `rbx/…` specifier,
47
51
  bare, `~`-prefixed, or a relative `node_modules/` path, covering the documented v3
48
- entry points (`src/index.sass`, `dist/react-bulma-components(.min).css`) as well as
52
+ entry points (`src/index.sass`, `dist/react-bulma-components(.min).css`, `rbx/rbx`) as well as
49
53
  deep partials and extensionless forms — is not a third-party extension; it's the
50
54
  library being migrated away from. It targets Bulma 0.9, not the v1 your components now
51
55
  use, and (unless `--no-deps` is passed) `package.json` no longer lists it, so the
@@ -68,8 +72,11 @@ finish what it flagged.
68
72
  given partial's styles, so it gets a `// TODO(bestax-migrate)` and a report entry
69
73
  ("port any styles it carried beyond Bulma's own by hand") rather than vanishing silently.
70
74
 
71
- - **package.json**: `react-bulma-components` removed, `@allxsmith/bestax-bulma` added,
72
- `bulma` bumped to `^1.0.4` (or added when sources still import `bulma/…` directly),
75
+ - **package.json**: the source library removed, `@allxsmith/bestax-bulma` added, a declared
76
+ pre-1.0 `bulma` raised to `^1.0.4` (or `bulma` added when sources still import `bulma/…`
77
+ directly). For rbx, the four `bulma-*` extensions it pinned are **reported** for you to
78
+ remove, not deleted — a manifest entry is a deliberate declaration, and the same goes for
79
+ their CSS imports in source files (kept, with a TODO each),
73
80
  and dead `node-sass` replaced with dart `sass`. Run the package manager's install
74
81
  afterwards — the codemod never installs anything.
75
82
 
@@ -93,7 +100,7 @@ elements,form,components,grid,layout,helpers,themes}` with leaf partials like
93
100
  compatibility. Class-based usage (`className="is-checkradio"`) keeps needing the
94
101
  extension; usage that migrated to bestax components (Radio, Checkbox, the advanced
95
102
  form controls) is already styled by the bestax extras, so the import can go.
96
- react-bulma-components' own stylesheet is never flagged this way (see above) — only
103
+ the source library's own stylesheet is never flagged this way (see above) — only
97
104
  packages actually named `bulma-*` are.
98
105
 
99
106
  ## Choosing a CSS flavor (optional)
@@ -0,0 +1,171 @@
1
+ # rbx → bestax-bulma component map
2
+
3
+ Every rbx v2 export and its dot-notation compounds. `structural` means the codemod rewrites the
4
+ element's shape rather than renaming it (see [unmappables.md](unmappables.md) for what each one
5
+ produces). A `todo` row has no bestax counterpart — the codemod keeps the rbx import, annotated,
6
+ so the app still runs while you convert it.
7
+
8
+ This table mirrors `MAPPING` in `bestax-migrate/src/sources/rbx/mapping.ts`, which a coverage
9
+ test holds to rbx's own export surface in both directions.
10
+
11
+ | rbx | bestax-bulma | status |
12
+ | -------------------------- | --------------------- | ------- |
13
+ | `Block` | `Block` | mapped |
14
+ | `Box` | `Box` | mapped |
15
+ | `Breadcrumb` | `Breadcrumb` | mapped |
16
+ | `Breadcrumb.Item` | _structural_ | mapped |
17
+ | `Button` | `Button` | mapped |
18
+ | `Button.Group` | `Buttons` | mapped |
19
+ | `Card` | `Card` | mapped |
20
+ | `Card.Content` | `Card.Content` | mapped |
21
+ | `Card.Image` | `Card.Image` | mapped |
22
+ | `Card.Header` | `Card.Header` | mapped |
23
+ | `Card.Header.Title` | `Card.Header.Title` | mapped |
24
+ | `Card.Header.Icon` | `Card.Header.Icon` | mapped |
25
+ | `Card.Footer` | `Card.Footer` | mapped |
26
+ | `Card.Footer.Item` | `Card.FooterItem` | mapped |
27
+ | `Checkbox` | `Checkbox` | mapped |
28
+ | `Column` | `Column` | mapped |
29
+ | `Column.Group` | `Columns` | mapped |
30
+ | `Container` | `Container` | mapped |
31
+ | `Content` | `Content` | mapped |
32
+ | `Content.OrderedList` | `OrderedList` | mapped |
33
+ | `Content.OrderedList.Item` | `OrderedList.Item` | mapped |
34
+ | `Control` | `Control` | mapped |
35
+ | `Delete` | `Delete` | mapped |
36
+ | `Divider` | `Divider` | partial |
37
+ | `Dropdown` | `Dropdown` | partial |
38
+ | `Dropdown.Container` | _structural_ | mapped |
39
+ | `Dropdown.Content` | _structural_ | mapped |
40
+ | `Dropdown.Menu` | _structural_ | mapped |
41
+ | `Dropdown.Trigger` | _structural_ | mapped |
42
+ | `Dropdown.Item` | `Dropdown.Item` | mapped |
43
+ | `Dropdown.Divider` | `Dropdown.Divider` | mapped |
44
+ | `Dropdown.Context` | — _(see unmappables)_ | todo |
45
+ | `Field` | `Field` | mapped |
46
+ | `Field.Label` | `Field.Label` | mapped |
47
+ | `Field.Body` | `Field.Body` | mapped |
48
+ | `Fieldset` | — _(see unmappables)_ | todo |
49
+ | `File` | `File` | mapped |
50
+ | `File.CTA` | — _(see unmappables)_ | todo |
51
+ | `File.Icon` | — _(see unmappables)_ | todo |
52
+ | `File.Input` | — _(see unmappables)_ | todo |
53
+ | `File.Label` | — _(see unmappables)_ | todo |
54
+ | `File.Name` | — _(see unmappables)_ | todo |
55
+ | `Footer` | `Footer` | mapped |
56
+ | `Generic` | — _(see unmappables)_ | todo |
57
+ | `Heading` | _structural_ | mapped |
58
+ | `Help` | _structural_ | mapped |
59
+ | `Hero` | `Hero` | mapped |
60
+ | `Hero.Body` | `Hero.Body` | mapped |
61
+ | `Hero.Foot` | `Hero.Foot` | mapped |
62
+ | `Hero.Head` | `Hero.Head` | mapped |
63
+ | `Highlight` | — _(see unmappables)_ | todo |
64
+ | `Icon` | `Icon` | partial |
65
+ | `Image` | `Image` | mapped |
66
+ | `Image.Container` | _structural_ | mapped |
67
+ | `Input` | `Input` | mapped |
68
+ | `Label` | _structural_ | mapped |
69
+ | `Level` | `Level` | mapped |
70
+ | `Level.Item` | _structural_ | mapped |
71
+ | `List` | — _(see unmappables)_ | todo |
72
+ | `List.Item` | — _(see unmappables)_ | todo |
73
+ | `Loader` | _structural_ | mapped |
74
+ | `Media` | `Media` | mapped |
75
+ | `Media.Item` | _structural_ | mapped |
76
+ | `Menu` | `Menu` | mapped |
77
+ | `Menu.Label` | `Menu.Label` | mapped |
78
+ | `Menu.List` | `Menu.List` | mapped |
79
+ | `Menu.List.Item` | `Menu.Item` | mapped |
80
+ | `Message` | `Message` | mapped |
81
+ | `Message.Body` | `Message.Body` | mapped |
82
+ | `Message.Header` | `Message.Header` | mapped |
83
+ | `Modal` | `Modal` | partial |
84
+ | `Modal.Background` | `Modal.Background` | mapped |
85
+ | `Modal.Close` | `Modal.Close` | mapped |
86
+ | `Modal.Content` | `Modal.Content` | mapped |
87
+ | `Modal.Container` | _structural_ | mapped |
88
+ | `Modal.Card` | `Modal.Card` | mapped |
89
+ | `Modal.Card.Body` | `Modal.Card.Body` | mapped |
90
+ | `Modal.Card.Foot` | `Modal.Card.Foot` | mapped |
91
+ | `Modal.Card.Head` | `Modal.Card.Head` | mapped |
92
+ | `Modal.Card.Title` | `Modal.Card.Title` | mapped |
93
+ | `Modal.Context` | — _(see unmappables)_ | todo |
94
+ | `Modal.Portal` | — _(see unmappables)_ | todo |
95
+ | `Navbar` | `Navbar` | mapped |
96
+ | `Navbar.Brand` | `Navbar.Brand` | mapped |
97
+ | `Navbar.Burger` | `Navbar.Burger` | mapped |
98
+ | `Navbar.Divider` | `Navbar.Divider` | mapped |
99
+ | `Navbar.Menu` | `Navbar.Menu` | mapped |
100
+ | `Navbar.Link` | `Navbar.Link` | mapped |
101
+ | `Navbar.Item` | _structural_ | mapped |
102
+ | `Navbar.Item.Container` | _structural_ | mapped |
103
+ | `Navbar.Dropdown` | _structural_ | mapped |
104
+ | `Navbar.Segment` | _structural_ | mapped |
105
+ | `Navbar.Container` | _structural_ | mapped |
106
+ | `Navbar.Context` | — _(see unmappables)_ | todo |
107
+ | `Notification` | `Notification` | mapped |
108
+ | `Numeric` | — _(see unmappables)_ | todo |
109
+ | `PageLoader` | `Loading` | mapped |
110
+ | `Pagination` | `Pagination` | mapped |
111
+ | `Pagination.Link` | `Pagination.Link` | mapped |
112
+ | `Pagination.List` | `Pagination.List` | mapped |
113
+ | `Pagination.Ellipsis` | `Pagination.Ellipsis` | mapped |
114
+ | `Pagination.Step` | _structural_ | mapped |
115
+ | `Panel` | `Panel` | mapped |
116
+ | `Panel.Heading` | `Panel.Heading` | mapped |
117
+ | `Panel.Block` | `Panel.Block` | mapped |
118
+ | `Panel.Icon` | `Panel.Icon` | partial |
119
+ | `Panel.Tab` | _structural_ | mapped |
120
+ | `Panel.Tab.Group` | `Panel.Tabs` | mapped |
121
+ | `Progress` | `Progress` | mapped |
122
+ | `Radio` | `Radio` | mapped |
123
+ | `Section` | `Section` | mapped |
124
+ | `Select` | `Select` | mapped |
125
+ | `Select.Container` | _structural_ | mapped |
126
+ | `Select.Option` | _structural_ | mapped |
127
+ | `Tab` | `Tabs.Item` | mapped |
128
+ | `Tab.Group` | `Tabs` | mapped |
129
+ | `Table` | `Table` | mapped |
130
+ | `Table.Body` | `Table.Tbody` | mapped |
131
+ | `Table.Cell` | `Table.Td` | mapped |
132
+ | `Table.Foot` | `Table.Tfoot` | mapped |
133
+ | `Table.Head` | `Table.Thead` | mapped |
134
+ | `Table.Heading` | `Table.Th` | mapped |
135
+ | `Table.Row` | `Table.Tr` | mapped |
136
+ | `Tag` | `Tag` | mapped |
137
+ | `Tag.Group` | `Tags` | mapped |
138
+ | `Textarea` | `TextArea` | mapped |
139
+ | `Tile` | — _(see unmappables)_ | todo |
140
+ | `Title` | _structural_ | mapped |
141
+ | `forwardRefAs` | — _(see unmappables)_ | todo |
142
+
143
+ ## The renames worth memorising
144
+
145
+ | rbx | bestax-bulma |
146
+ | ---------------------------------- | ---------------------------------------------------------------------------------------------------------- |
147
+ | `Tag.Group` | `Tags` |
148
+ | `Button.Group` | `Buttons` |
149
+ | `Column.Group` | `Columns` |
150
+ | `Card.Footer.Item` | `Card.FooterItem` |
151
+ | `Table.Head` / `.Body` / `.Foot` | `Table.Thead` / `.Tbody` / `.Tfoot` |
152
+ | `Table.Row` / `.Cell` / `.Heading` | `Table.Tr` / `.Td` / `.Th` |
153
+ | `Textarea` | `TextArea` |
154
+ | `PageLoader` | `Loading` with `isFullPage` |
155
+ | `Loader` | a plain `<div className="loader">` — bestax's `Loading` is an overlay that renders nothing unless `active` |
156
+ | `Menu.List.Item` | `Menu.Item` |
157
+ | `Tab` / `Tab.Group` | `Tabs.Item` / `Tabs` |
158
+ | `Panel.Tab.Group` | `Panel.Tabs` |
159
+ | `Title subtitle` | `SubTitle` |
160
+
161
+ ## Value-chosen targets
162
+
163
+ These pick a bestax component from a literal prop value; a dynamic value gets a TODO instead.
164
+
165
+ | rbx | value | bestax-bulma |
166
+ | ----------------- | ---------------------------------------- | ---------------------------------------------- |
167
+ | `Level.Item` | `align="left"` / `"right"` | `Level.Left` / `Level.Right` |
168
+ | `Media.Item` | `align="left"` / `"content"` / `"right"` | `Media.Left` / `Media.Content` / `Media.Right` |
169
+ | `Navbar.Segment` | `align="start"` / `"end"` | `Navbar.Start` / `Navbar.End` |
170
+ | `Pagination.Step` | `align="previous"` / `"next"` | `Pagination.Previous` / `Pagination.Next` |
171
+ | `Navbar.Item` | `dropdown` | `Navbar.Dropdown` |
@@ -0,0 +1,116 @@
1
+ # rbx → bestax-bulma prop map
2
+
3
+ rbx and bestax both target Bulma, so most helper _values_ are already identical — the shapes
4
+ differ, not the vocabulary. What follows is only what actually changes.
5
+
6
+ ## Universal helper props
7
+
8
+ rbx mixes these into every component via `HelpersProps`.
9
+
10
+ | rbx | bestax-bulma | note |
11
+ | --------------------------------- | ---------------------------- | ---------------------------------------------------------- |
12
+ | `backgroundColor` | `bgColor` | rename only |
13
+ | `textColor` | `textColor` | unchanged |
14
+ | `textAlign` | `textAlign` | unchanged — both use `centered`/`justified`/`left`/`right` |
15
+ | `textWeight` | `textWeight` | unchanged |
16
+ | `textTransform` | `textTransform` | unchanged |
17
+ | `textSize={4}` | `textSize="4"` | number → string |
18
+ | `italic` | `textTransform="italic"` | |
19
+ | `pull="left"` | `float="left"` | |
20
+ | `clearfix`, `overlay`, `relative` | same | unchanged booleans |
21
+ | `clipped` | `overflow="clipped"` | |
22
+ | `hidden` | `visibility="hidden"` | |
23
+ | `invisible` | `visibility="invisible"` | |
24
+ | `srOnly` | `visibility="sr-only"` | |
25
+ | `marginless` | `m="0"` | Bulma v1 removed `is-marginless` |
26
+ | `paddingless` | `p="0"` | Bulma v1 removed `is-paddingless` |
27
+ | `radiusless` | `radius="radiusless"` | |
28
+ | `shadowless` | `shadow="shadowless"` | |
29
+ | `unselectable` | `interaction="unselectable"` | |
30
+
31
+ Two rbx colour names have no bestax equivalent: **`white-ter`** and **`white-bis`**. Everything
32
+ else in rbx's `colors` and `shades` unions exists in bestax verbatim.
33
+
34
+ ## Bare boolean modifiers → `is*`
35
+
36
+ `outlined` → `isOutlined`, `rounded` → `isRounded`, `inverted` → `isInverted`,
37
+ `fullwidth` → `isFullwidth`, `static` → `isStatic`, `narrow` → `isNarrow`,
38
+ `bordered`/`striped`/`hoverable` on `Table` → `isBordered`/`isStriped`/`isHoverable`,
39
+ `delete` on `Tag` → `isDelete`.
40
+
41
+ ## State props → booleans
42
+
43
+ | rbx | bestax-bulma |
44
+ | --------------------------------------------------- | -------------------------------------- |
45
+ | `Button state="loading"` | `isLoading` |
46
+ | `Button state="hovered"` / `"focused"` / `"active"` | `isHovered` / `isFocused` / `isActive` |
47
+ | `Input state="focused"` / `"hovered"` | `isFocused` / `isHovered` |
48
+ | `Select.Container state="loading"` | `isLoading` |
49
+
50
+ ## Form grouping
51
+
52
+ bestax folds rbx's `kind` + `multiline` + `align` into two value-taking props.
53
+
54
+ | rbx | bestax-bulma |
55
+ | --------------------------------------- | ----------------------------------------------------------------------------------------------------------------------- |
56
+ | `Field kind="addons"` | `hasAddons` |
57
+ | `Field kind="group"` | `grouped` |
58
+ | `Field multiline` (with `kind="group"`) | `grouped="multiline"` |
59
+ | `Field align="centered"` | ambiguous — TODO; set `grouped`/`hasAddons` to `"centered"` by hand |
60
+ | `Control expanded` / `loading` | `isExpanded` / `isLoading` |
61
+ | `Control iconLeft` / `iconRight` | `hasIconsLeft` / `hasIconsRight` — note bestax's own `iconLeft` takes an `IconProps` object, which is a different thing |
62
+ | `Textarea fixedSize` | `hasFixedSize` |
63
+
64
+ ## Breakpoint objects
65
+
66
+ rbx has three shapes; all three flatten to bestax's per-viewport props.
67
+
68
+ ```jsx
69
+ // 1. the universal `responsive` helper prop
70
+ <Box responsive={{ tablet: { display: { value: "flex" }, textSize: { value: 5 } } }} />
71
+ <Box displayTablet="flex" textSizeTablet="5" />
72
+
73
+ // 2. Column sizing
74
+ <Column tablet={{ size: 6, narrow: true }} />
75
+ <Column sizeTablet={6} isNarrowTablet />
76
+
77
+ // 3. Column.Group gaps
78
+ <Column.Group tablet={{ gapSize: 2 }} />
79
+ <Columns gapTablet={2} />
80
+ ```
81
+
82
+ `hide: { value: true }` becomes `visibility<Viewport>="hidden"`. The **`touch`** breakpoint and
83
+ `{ only: true }` have no bestax props — both are TODOs.
84
+
85
+ ## `as`
86
+
87
+ rbx's `forwardRefAs` puts `as` on **every** component. bestax declares it on a smaller set, and
88
+ several of those narrow it to specific tags (`Footer` is `'footer' | 'div'`, `Control` is
89
+ `'div'`). The codemod passes `as` through only where bestax really accepts it, and TODOs it
90
+ everywhere else:
91
+
92
+ | bestax component | `as` accepts |
93
+ | ---------------------------- | -------------------------- |
94
+ | `Button` | any element type |
95
+ | `Title`, `SubTitle` | `h1`–`h6`, `p` |
96
+ | `Image` | `'figure' \| 'div' \| 'p'` |
97
+ | `Footer` | `'footer' \| 'div'` |
98
+ | `Media` | `'article' \| 'div'` |
99
+ | `Media.Left` | `'figure' \| 'div'` |
100
+ | `Level.Item` | `'div' \| 'p' \| 'a'` |
101
+ | `Control` | `'div'` |
102
+ | `Menu.Item` | any element type |
103
+ | `Dropdown.Item` | `'a' \| 'div' \| 'button'` |
104
+ | `Navbar.Item`, `Navbar.Link` | any element type |
105
+
106
+ Three traps worth naming, because rbx supplies `as` universally and the obvious guesses are
107
+ wrong:
108
+
109
+ - The **`Dropdown` and `Navbar` roots do not take `as`** — only their `.Item` / `.Link`
110
+ sub-components do.
111
+ - **`Media.Item` depends on its `align`.** It resolves to `Media.Left`, `Media.Content` or
112
+ `Media.Right`, and only `Media.Left` declares `as`; the codemod drops it with a TODO on the
113
+ other two.
114
+ - Several of the accepted props are **narrow literal unions**, so `as={SomeComponent}` still
115
+ fails to typecheck even where `as` is allowed — which is deliberate: a visible type error
116
+ beats a silent rewrite.
@@ -0,0 +1,169 @@
1
+ # Recipes for every TODO(bestax-migrate) the rbx codemod leaves
2
+
3
+ Ordered by how often they appear when the codemod runs over rbx's own documentation examples.
4
+ Resolve the comment, then delete it. Never silence a TODO without converting the code.
5
+
6
+ ## `component:Icon` — the icon child
7
+
8
+ bestax's `Icon` takes a **required `name`** instead of an icon child, and rbx's docs teach the
9
+ FontAwesome component form, which carries no readable name.
10
+
11
+ ```jsx
12
+ <Icon size="small"><FontAwesomeIcon icon={faHome} /></Icon>
13
+ <Icon name="home" library="fa" variant="solid" size="small" />
14
+ ```
15
+
16
+ `library` is `fa` | `mdi` | `ion` | `material-icons` | `material-symbols`; `variant` is the style
17
+ (`solid`, `regular`, `brands`, …). Icon-font children the parser _can_ read
18
+ (`<i className="fas fa-home" />`) are converted automatically.
19
+
20
+ ## `component:Tile` — Bulma v1 removed tiles
21
+
22
+ Use Grid and Cell. `Tile kind="ancestor"` becomes `<Grid>`, `kind="parent"`/`kind="child"`
23
+ become `<Cell>`, and `size={n}` becomes a column span.
24
+
25
+ ```jsx
26
+ <Tile kind="ancestor"><Tile kind="parent" size={4}><Tile kind="child">x</Tile></Tile></Tile>
27
+ <Grid><Cell colSpan={4}>x</Cell></Grid>
28
+ ```
29
+
30
+ ## `component:File.*` — the file-input parts
31
+
32
+ bestax's `<File>` renders the whole Bulma structure itself, so `File.Label`, `File.Input`,
33
+ `File.CTA`, `File.Icon` and `File.Name` have nothing to become.
34
+
35
+ ```jsx
36
+ <File hasName>
37
+ <File.Label>
38
+ <File.Input name="upload" />
39
+ <File.CTA><File.Label>Choose…</File.Label></File.CTA>
40
+ <File.Name>none</File.Name>
41
+ </File.Label>
42
+ </File>
43
+
44
+ <File name="upload" label="Choose…" hasName />
45
+ ```
46
+
47
+ ## `prop:as` — polymorphism
48
+
49
+ rbx puts `as` on everything; bestax does not. Either render the tag directly, or restructure.
50
+ See the `as` section of [prop-map.md](prop-map.md) for the components that do accept it.
51
+
52
+ ## `component:Generic` — rbx's base element
53
+
54
+ `Generic` is rbx's untyped passthrough. Render the underlying tag, and move its helper props to
55
+ the nearest bestax component (or a `className`).
56
+
57
+ ## `component:Dropdown` and its parts
58
+
59
+ bestax's `Dropdown` takes a `label` and renders its own trigger and menu, so rbx's four-element
60
+ structure collapses to one.
61
+
62
+ ```jsx
63
+ <Dropdown>
64
+ <Dropdown.Trigger>Open</Dropdown.Trigger>
65
+ <Dropdown.Menu><Dropdown.Content>
66
+ <Dropdown.Item active>one</Dropdown.Item>
67
+ </Dropdown.Content></Dropdown.Menu>
68
+ </Dropdown>
69
+
70
+ <Dropdown label="Open">
71
+ <Dropdown.Item active>one</Dropdown.Item>
72
+ </Dropdown>
73
+ ```
74
+
75
+ ## `Navbar.Item dropdown` — open/close state is not carried over
76
+
77
+ The structural rewrite is automatic (`<Navbar.Item dropdown>` becomes
78
+ `<Navbar.Dropdown>`, and rbx's `<Navbar.Dropdown>` becomes `<Navbar.DropdownMenu>`), but the
79
+ **behaviour is not the same**. rbx's dropdown owns its own click and outside-click state; bestax's
80
+ `Navbar.Dropdown` is presentational and opens from `hoverable` or a controlled `active`.
81
+
82
+ So a migrated dropdown renders correctly and does nothing on click. Pick one:
83
+
84
+ ```jsx
85
+ <Navbar.Dropdown hoverable>…</Navbar.Dropdown> // opens on hover
86
+ <Navbar.Dropdown active={open}>…</Navbar.Dropdown> // you own the state
87
+ ```
88
+
89
+ Nothing flags this — the markup is valid either way — so audit your navbars after migrating.
90
+
91
+ ## `component:List` — the bulma-list extension
92
+
93
+ Bulma v1 does not ship it. Use `<UnorderedList>`/`<UnorderedList.Item>` for a plain list, or
94
+ `<Menu>`/`<Menu.Item>` when the items are navigation.
95
+
96
+ ## `component:Fieldset`, `component:Numeric`, `component:Highlight`
97
+
98
+ No bestax equivalents, and none needed: render a plain `<fieldset>` (its `disabled` attribute
99
+ works natively), use `Intl.NumberFormat` directly, and use `<Pre>` with your own highlighter.
100
+
101
+ ## `responsive` — `touch` and `{ only: true }`
102
+
103
+ bestax's viewports are `mobile`/`tablet`/`desktop`/`widescreen`/`fullhd`, with no `touch` and no
104
+ `-only` variants. Reach for a `className` with the Bulma class, or restyle in CSS.
105
+
106
+ The codemod always removes the whole `responsive` prop, even when part of it could not be
107
+ converted — bestax has its own unrelated `responsive` prop (`'mobile' | 'narrow'`), so leaving a
108
+ half-emptied rbx object behind would be a type error rather than a leftover. The TODO names
109
+ which breakpoints did not carry.
110
+
111
+ ## Props with no counterpart
112
+
113
+ | TODO | What to do |
114
+ | -------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
115
+ | `prop:closeOnEsc` on `Modal` | bestax implements no Escape handling at all; add your own keydown listener, or drop the prop |
116
+ | `prop:closeOnBlur` on `Modal` | the migrated compound form renders `Modal.Background` as you wrote it; wire its `onClick` to your `onClose` |
117
+ | `prop:selected`, `prop:text` on `Button` | `className="is-selected"`; for `is-text` use `color="ghost"` or a link |
118
+ | `prop:size` on `Button.Group` / `Tags` / `Message` | set `size` on each child instead |
119
+ | `prop:gradient` on `Hero` | Bulma v1 removed `is-bold` gradients; use `bgColor` or a custom class |
120
+ | `prop:color`, `prop:vertical` on `Divider` | bestax's `Divider` takes only `bgColor` and renders an `<hr>` |
121
+ | `component:Divider` (a labelled divider) | rbx rendered `<Divider>OR</Divider>`'s children as a centred label via `data-content`; bestax's `Divider` is a bare `<hr>` and takes no children -- React rejects children on a void element at runtime. Put the label in surrounding markup, or drop it |
122
+ | `prop:direction` on `PageLoader` | no directional variant; drop it or add a class |
123
+ | `prop:innerRef` | the affected roots (`Dropdown`, `Modal`, `Navbar`) are plain function components and forward no ref — drop it, or put the ref on a wrapping element you control |
124
+ | `prop:managed` | bestax components are uncontrolled; drive the `Modal` with `active` and `onClose` |
125
+ | `prop:document` on `Modal` | bestax renders the Modal inline rather than portalling into any document — see [Modal behaviours bestax does not implement](#modal-behaviours-bestax-does-not-implement) |
126
+ | `prop:document` on `Navbar` | bestax's `Navbar` has no `document` prop; drop it |
127
+ | `badgeOutlined`, `badgeRounded`, `badgeSize` | bestax's `Badge` has no outline, pill or size variant |
128
+ | `tooltipResponsive` | bestax's `Tooltip` has one `position` for all viewports |
129
+
130
+ ## Modal behaviours bestax does not implement
131
+
132
+ `component:Modal` — emitted on **every** Modal the codemod converts, whether or not you passed
133
+ any of the props above.
134
+
135
+ rbx's Modal did three things by default that bestax's does not do at all:
136
+
137
+ | rbx default | bestax |
138
+ | -------------------------------- | --------------------------------------------------- |
139
+ | portals into `document.body` | renders inline, exactly where you place it |
140
+ | closes on Escape | no keydown handling of any kind |
141
+ | clips document scroll while open | no scroll locking; the page behind stays scrollable |
142
+
143
+ The markup migrates cleanly, so nothing fails to compile and nothing looks wrong in a
144
+ screenshot — which is why this one is flagged unconditionally rather than left to review. Re-add
145
+ whichever your UI actually relied on:
146
+
147
+ - **Portal** — wrap the render in `createPortal(…, document.body)` yourself. This matters most if
148
+ an ancestor has `overflow: hidden`, `filter`, or a `transform`, any of which will now clip or
149
+ re-parent the modal that used to escape them.
150
+ - **Escape** — add a `keydown` listener while the modal is open and call your `onClose`.
151
+ - **Scroll lock** — Bulma still ships `.is-clipped`; put it on `<html>` while the modal is open.
152
+
153
+ Background click is the one that does carry over, but only because you write it: the migrated
154
+ compound form renders your `Modal.Background`, so wire its `onClick` to the same `onClose`.
155
+
156
+ ## `prop:textColor="white-ter"` / `"white-bis"`
157
+
158
+ The only two rbx colour names bestax does not carry. Use `white`, or a custom class.
159
+
160
+ ## `value-reference` — a component used as a value
161
+
162
+ `const X = Card.Header;` and similar. The codemod rewrites what it can prove safe and flags the
163
+ rest; convert the usage by hand.
164
+
165
+ ## Dynamic values
166
+
167
+ Anything the codemod cannot read statically (`state={x}`, `align={side}`,
168
+ `subtitle={isSub}`) is left in place with a TODO. Split the branch by hand — the codemod never
169
+ guesses at a runtime value.