create-bestax 4.2.10 → 4.2.12
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 +1 -1
- package/package.json +2 -2
- package/templates/skills/bestax-custom-component/references/library-contributor.md +15 -0
- package/templates/skills/bestax-layout-scaffold/examples/content-page.tsx +5 -1
- package/templates/skills/bestax-migrate/SKILL.md +22 -9
- package/templates/skills/bestax-migrate/references/bloomer/prop-map.md +11 -3
- package/templates/skills/bestax-migrate/references/bulma-classes/component-map.md +93 -0
- package/templates/skills/bestax-migrate/references/bulma-classes/prop-map.md +153 -0
- package/templates/skills/bestax-migrate/references/bulma-classes/unmappables.md +170 -0
- package/templates/skills/bestax-migrate/references/css-migration.md +8 -1
- package/templates/skills/bestax-migrate/references/rbx/prop-map.md +25 -14
- package/templates/skills/bestax-migrate/references/react-bulma-components/unmappables.md +13 -5
- package/templates/skills/bestax-theming/references/css-variables.md +8 -8
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), rbx (v2)
|
|
185
|
+
- **bestax-migrate** — migrate code off react-bulma-components (v4), rbx (v2), bloomer (0.6) or raw Bulma classNames: 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
|
+
"version": "4.2.12",
|
|
4
4
|
"description": "Create a new bestax-bulma project",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"bin": {
|
|
@@ -39,7 +39,7 @@
|
|
|
39
39
|
"figures": "^6.1.0",
|
|
40
40
|
"fs-extra": "^11.4.0",
|
|
41
41
|
"prompts": "^2.4.2",
|
|
42
|
-
"@allxsmith/bestax-bulma": "^5.16.
|
|
42
|
+
"@allxsmith/bestax-bulma": "^5.16.9"
|
|
43
43
|
},
|
|
44
44
|
"devDependencies": {
|
|
45
45
|
"@jest/globals": "^30.0.0",
|
|
@@ -137,6 +137,21 @@ Rules that keep components consistent:
|
|
|
137
137
|
`PolymorphicComponentWithoutRef` and forwards none. That is the exception, not
|
|
138
138
|
a licence to skip refs; everything a consumer might focus or measure should
|
|
139
139
|
forward one.
|
|
140
|
+
- **An own prop the component FORWARDS has to say so.** Subtracting `Own` from the
|
|
141
|
+
target's props is what keeps a Bulma `color` from being shadowed by the DOM
|
|
142
|
+
attribute, but it also lets an OPTIONAL own prop hide a REQUIRED prop of the
|
|
143
|
+
target: `Avatar`'s `href?: string` hid `next/link`'s required one, so
|
|
144
|
+
`<Avatar as={NextLink} name="Ada" />` compiled and the target was handed
|
|
145
|
+
nothing (#665). Name those props in the third type parameter —
|
|
146
|
+
`PolymorphicComponent<FooOwnProps, 'tag', 'href' | 'target'>`, with the
|
|
147
|
+
matching `Exclude`/`Extract` pair written out in the alias the way `Avatar.tsx`
|
|
148
|
+
does — and the target's declaration wins, while the own one still covers a
|
|
149
|
+
target that has no such prop. It defaults to naming none, which is the right
|
|
150
|
+
answer for a prop the component CONSUMES. Withholding an undefined value at
|
|
151
|
+
runtime belongs with it: a key that merely exists reads as a value to a target
|
|
152
|
+
that tests for one, and travels on through its `{...rest}`. Not to a
|
|
153
|
+
destructuring default, which an explicit `undefined` triggers anyway.
|
|
154
|
+
|
|
140
155
|
- **Element sizing uses an inline `'small' | 'medium' | 'large'` union**, mapped to `is-small` /
|
|
141
156
|
`is-medium` / `is-large` (see `Tabs.tsx`, `Control.tsx`). Do **not** reach for the `validSizes`
|
|
142
157
|
constant — that one is `'0'…'6' | 'auto'` and exists for **spacing** helpers, not element size.
|
|
@@ -72,7 +72,11 @@ export default function ContentPage() {
|
|
|
72
72
|
<Card>
|
|
73
73
|
<Card.Content>
|
|
74
74
|
<IconText mb="3">
|
|
75
|
-
<Icon
|
|
75
|
+
<Icon
|
|
76
|
+
name={f.icon}
|
|
77
|
+
textColor="primary"
|
|
78
|
+
aria-hidden="true"
|
|
79
|
+
/>
|
|
76
80
|
<Title size="4" mb="2">
|
|
77
81
|
{f.name}
|
|
78
82
|
</Title>
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: bestax-migrate
|
|
3
|
-
description: Migrate an existing app from an unmaintained React Bulma library
|
|
3
|
+
description: Migrate an existing React app to @allxsmith/bestax-bulma on Bulma v1, from raw Bulma CSS classes on plain JSX (className="button is-primary") or from an unmaintained React Bulma library (react-bulma-components v4, rbx v2, bloomer 0.6). Run the bestax-migrate codemod, then resolve every TODO(bestax-migrate) comment it leaves using the per-source mapping references. Use when a React app styles its markup with Bulma classes and wants bestax components instead, when a repo imports react-bulma-components, rbx or bloomer, when TODO(bestax-migrate) comments are present in a codebase, or when asked to convert Bulma classNames to bestax-bulma.
|
|
4
4
|
license: MIT
|
|
5
5
|
---
|
|
6
6
|
|
|
@@ -15,11 +15,12 @@ this skill drives the codemod and finishes what it flags.
|
|
|
15
15
|
The codemod's first argument names the library you are migrating _from_. Check the app's
|
|
16
16
|
`package.json` and imports:
|
|
17
17
|
|
|
18
|
-
| Source
|
|
19
|
-
|
|
|
20
|
-
| `react-bulma-components` v4 (unmaintained since 2022, Bulma 0.9.x)
|
|
21
|
-
| `rbx` v2 (abandoned 2019, pins Bulma **0.7.5** plus four extensions)
|
|
22
|
-
| `bloomer` 0.6 (archived 2018, Bulma 0.6 era, React 16 + `create-react-class`)
|
|
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
|
+
| `bloomer` 0.6 (archived 2018, Bulma 0.6 era, React 16 + `create-react-class`) | `bloomer` | [`references/bloomer/`](references/bloomer/component-map.md) |
|
|
23
|
+
| Raw Bulma classes on plain JSX (`<div className="box">`), no React Bulma library | `bulma-classes` | [`references/bulma-classes/`](references/bulma-classes/component-map.md) |
|
|
23
24
|
|
|
24
25
|
Everything below is written as `<source>`; substitute the argument from that table. The
|
|
25
26
|
reference paths follow the same split — `references/<source>/component-map.md`,
|
|
@@ -43,7 +44,9 @@ Run these steps in order. Don't hand-convert what the codemod converts automatic
|
|
|
43
44
|
`@allxsmith/bestax-bulma/bestax.css`; SCSS `@import 'bulma/bulma'` + `$var` overrides
|
|
44
45
|
→ `@use 'bulma/sass' with (…)` plus the bestax extras) and **package.json**.
|
|
45
46
|
Flags: `--css bulma|keep` for other stylesheet targets, `--no-deps` to leave
|
|
46
|
-
package.json alone.
|
|
47
|
+
package.json alone. `bulma-classes` is the exception: it defaults to `--css keep`,
|
|
48
|
+
because the app's own Bulma already styles every class it converts, so its stylesheets
|
|
49
|
+
and Bulma version stay unless you pass `--css bestax` or `--css bulma`.
|
|
47
50
|
|
|
48
51
|
3. **Install** — the codemod edits package.json but never runs a package manager. Resolve the
|
|
49
52
|
retained imports first: a component with no bestax equivalent keeps a trimmed,
|
|
@@ -105,6 +108,15 @@ code per the references, or deliberately keep the old markup with `className` st
|
|
|
105
108
|
become real wrapping `<Badge>` / `<Tooltip>` components. Its `as` is universal, bestax's is
|
|
106
109
|
not. Because rbx pinned Bulma 0.7.5, you cross **two** Bulma majors — expect more visual
|
|
107
110
|
drift than the 0.9 → 1 guide alone describes.
|
|
111
|
+
- **bulma-classes**: there is no library to remove. An element converts only when the bestax
|
|
112
|
+
component renders the same markup (tag, classes, attributes), so a converted page renders
|
|
113
|
+
the same HTML; everything else stays as written, with a TODO when there is something to
|
|
114
|
+
decide. Only static class strings convert (`clsx(...)` and ternaries get
|
|
115
|
+
`dynamic-class:<Target>`, naming the component the element would become), files a Next.js
|
|
116
|
+
App Router may render as server components are left alone (`rsc`), and the manifest gains
|
|
117
|
+
`@allxsmith/bestax-bulma` while the app's Bulma and stylesheets stay (the default
|
|
118
|
+
`--css keep`). Its rules are `kind:<name>` shaped; see
|
|
119
|
+
`references/bulma-classes/unmappables.md`.
|
|
108
120
|
- **bloomer**: every export is a flat name and most become dotted bestax compounds
|
|
109
121
|
(`CardHeaderTitle` → `Card.Header.Title`). Most of its `is*` booleans already are bestax's
|
|
110
122
|
(`isActive` becomes `active` where bestax names it so; `isFullWidth` survives only on
|
|
@@ -116,8 +128,9 @@ code per the references, or deliberately keep the old markup with `className` st
|
|
|
116
128
|
|
|
117
129
|
## Rules
|
|
118
130
|
|
|
119
|
-
- The codemod is
|
|
120
|
-
|
|
131
|
+
- The codemod is safe to re-run after partial manual work: a library source only touches files
|
|
132
|
+
that still import the library, and `bulma-classes` skips elements that are already
|
|
133
|
+
components and never repeats a TODO it already wrote.
|
|
121
134
|
- Don't downgrade converted props back to the old names; bestax uses `is*` booleans
|
|
122
135
|
(`isLoading`), string size unions (`textSize="4"`), and `as` rather than `renderAs`.
|
|
123
136
|
- If a component the app uses isn't in the component map, it wasn't part of that library's
|
|
@@ -161,6 +161,14 @@ value is flagged. The same conversion covers the modifiers bestax has no prop fo
|
|
|
161
161
|
|
|
162
162
|
## Refs
|
|
163
163
|
|
|
164
|
-
bloomer forwarded no refs. bestax forwards a ref from the form controls
|
|
165
|
-
`
|
|
166
|
-
`
|
|
164
|
+
bloomer forwarded no refs. bestax forwards a ref from the form controls, plus `Avatar`,
|
|
165
|
+
`Button`, `Carousel`, `CarouselItem`, `Dialog`, `Dropdown`, `Link`, `LinkButton`, `Menu.Item`,
|
|
166
|
+
`Modal`, `Navbar`, `Navbar.Burger`, `Navbar.Dropdown`, `Navbar.Item`, `Navbar.Link`, `Sidebar`
|
|
167
|
+
and `Toast` — pass `ref` directly on those. "The form controls" means the inputs
|
|
168
|
+
themselves: the `Field`, `Field.Label`, `Field.Body`, `Checkboxes` and `Radios` wrappers
|
|
169
|
+
around them forward nothing.
|
|
170
|
+
|
|
171
|
+
A `ref` on anything else is unsupported, and the two React majors fail differently: React 18
|
|
172
|
+
drops it and logs "Function components cannot be given refs", while React 19 hands it to the
|
|
173
|
+
component as an ordinary prop, where it settles wherever the rest props go. bestax supports
|
|
174
|
+
both, so attach the ref to an element you control instead.
|
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
# Bulma classes → bestax-bulma component map
|
|
2
|
+
|
|
3
|
+
For apps that style plain JSX with Bulma's classes (`<div className="columns">`), not a React
|
|
4
|
+
wrapper library. The codemod converts an element only when the bestax component renders
|
|
5
|
+
**exactly the markup the element did**: same tag, same classes, same attributes. Anything else
|
|
6
|
+
stays as written, with a `TODO(bestax-migrate)` when there is something to decide (see
|
|
7
|
+
[unmappables.md](unmappables.md)).
|
|
8
|
+
|
|
9
|
+
A class the codemod doesn't know, such as the app's own `pricing-card`, rides along in
|
|
10
|
+
`className`, which every bestax component passes through. So does a Bulma class with no bestax
|
|
11
|
+
prop. Converting `<a className="button is-primary my-cta">` gives
|
|
12
|
+
`<Button as="a" color="primary" className="my-cta">`, and it renders the same `<a>`.
|
|
13
|
+
|
|
14
|
+
This table mirrors `ROOTS` in `bestax-migrate/src/sources/bulma-classes/class-map.ts`, and a
|
|
15
|
+
test holds it to that table. Render tests hold the table to the library itself.
|
|
16
|
+
|
|
17
|
+
## Components
|
|
18
|
+
|
|
19
|
+
The **Tags** column is what the component can render: an element on any other tag gets a
|
|
20
|
+
`tag:<Target>` TODO instead of a conversion.
|
|
21
|
+
|
|
22
|
+
| Bulma class | bestax-bulma | Tags |
|
|
23
|
+
| ---------------- | --------------- | -------------------------------------------------------------- |
|
|
24
|
+
| `.block` | `Block` | `<div>` only |
|
|
25
|
+
| `.box` | `Box` | `<div>` only |
|
|
26
|
+
| `.button` | `Button` | `<button>`, any tag via `as` |
|
|
27
|
+
| `.buttons` | `Buttons` | `<div>` only |
|
|
28
|
+
| `.columns` | `Columns` | `<div>` only |
|
|
29
|
+
| `.column` | `Column` | `<div>` only |
|
|
30
|
+
| `.container` | `Container` | `<div>` only |
|
|
31
|
+
| `.content` | `Content` | `<div>` only |
|
|
32
|
+
| `.delete` | `Delete` | `<button>` only |
|
|
33
|
+
| `.footer` | `Footer` | `<footer>`, `<div>` via `as` |
|
|
34
|
+
| `.hero` | `Hero` | `<section>` only |
|
|
35
|
+
| `.hero-head` | `Hero.Head` | `<div>` only |
|
|
36
|
+
| `.hero-body` | `Hero.Body` | `<div>` only |
|
|
37
|
+
| `.hero-foot` | `Hero.Foot` | `<div>` only |
|
|
38
|
+
| `.level` | `Level` | `<nav>` only |
|
|
39
|
+
| `.level-left` | `Level.Left` | `<div>` only |
|
|
40
|
+
| `.level-right` | `Level.Right` | `<div>` only |
|
|
41
|
+
| `.level-item` | `Level.Item` | `<div>`, `<p>`, `<a>` via `as` |
|
|
42
|
+
| `.media` | `Media` | `<article>`, `<div>` via `as` |
|
|
43
|
+
| `.media-left` | `Media.Left` | `<figure>`, `<div>` via `as` |
|
|
44
|
+
| `.media-content` | `Media.Content` | `<div>` only |
|
|
45
|
+
| `.media-right` | `Media.Right` | `<div>` only |
|
|
46
|
+
| `.notification` | `Notification` | `<div>` only |
|
|
47
|
+
| `.progress` | `Progress` | `<progress>` only |
|
|
48
|
+
| `.section` | `Section` | `<section>` only |
|
|
49
|
+
| `.subtitle` | `SubTitle` | `<h1>`, `<h2>`, `<h3>`, `<h4>`, `<h5>`, `<h6>`, `<p>` via `as` |
|
|
50
|
+
| `.table` | `Table` | `<table>` only |
|
|
51
|
+
| `.tag` | `Tag` | `<span>` only |
|
|
52
|
+
| `.tags` | `Tags` | `<div>` only |
|
|
53
|
+
| `.title` | `Title` | `<h1>`, `<h2>`, `<h3>`, `<h4>`, `<h5>`, `<h6>`, `<p>` via `as` |
|
|
54
|
+
|
|
55
|
+
An element with two of these (`<div className="column box">`) becomes the layout one
|
|
56
|
+
(`Column`), and the other class stays in `className`.
|
|
57
|
+
|
|
58
|
+
## Plain tags with helper classes
|
|
59
|
+
|
|
60
|
+
A tag bestax wraps becomes that wrapper when at least one of its classes converts to a helper
|
|
61
|
+
prop: `<p className="has-text-centered mt-4">` → `<Paragraph textAlign="centered" mt="4">`.
|
|
62
|
+
|
|
63
|
+
| Tag | bestax-bulma |
|
|
64
|
+
| ---------- | --------------- |
|
|
65
|
+
| `<p>` | `Paragraph` |
|
|
66
|
+
| `<span>` | `Span` |
|
|
67
|
+
| `<strong>` | `Strong` |
|
|
68
|
+
| `<em>` | `Emphasis` |
|
|
69
|
+
| `<code>` | `Code` |
|
|
70
|
+
| `<pre>` | `Pre` |
|
|
71
|
+
| `<a>` | `Link` |
|
|
72
|
+
| `<li>` | `ListItem` |
|
|
73
|
+
| `<ol>` | `OrderedList` |
|
|
74
|
+
| `<ul>` | `UnorderedList` |
|
|
75
|
+
| `<figure>` | `Figure` |
|
|
76
|
+
|
|
77
|
+
bestax has no plain `<div>` wrapper, so `<div className="is-flex mt-4">` stays as it is, with
|
|
78
|
+
no TODO: it is valid Bulma, and nothing unsafe was skipped.
|
|
79
|
+
|
|
80
|
+
## Families this source leaves as markup
|
|
81
|
+
|
|
82
|
+
Their markup doesn't map element by element (the bestax component renders parts of its own, or
|
|
83
|
+
adds attributes), so the family's outermost class gets a `family:<class>` TODO and the markup
|
|
84
|
+
stays. [unmappables.md](unmappables.md) has the recipe for each. The families are Breadcrumb,
|
|
85
|
+
Card, Checkbox, Checkboxes, Dropdown, Field (and Input, TextArea, Select, File), Grid and Cell,
|
|
86
|
+
Icon and IconText, Image, Menu, Message, Modal, Navbar, Pagination, Panel, Radio, Radios,
|
|
87
|
+
Skeleton, `.table-container` and Tabs.
|
|
88
|
+
|
|
89
|
+
## Classes left alone
|
|
90
|
+
|
|
91
|
+
`.help`, `.label`, `.loader`, `.hero-buttons`, `.hero-video`, `.theme-dark`, `.theme-light`,
|
|
92
|
+
`.fa`, `.marginless` and `.paddingless` are valid Bulma with nothing in bestax to convert to.
|
|
93
|
+
An element carrying one stays as written, and gets no TODO.
|
|
@@ -0,0 +1,153 @@
|
|
|
1
|
+
# Bulma classes → bestax-bulma prop map
|
|
2
|
+
|
|
3
|
+
Which class becomes which prop, per component, then the helper classes every component takes.
|
|
4
|
+
A class that becomes no prop stays in `className`. So does a second class for a prop already
|
|
5
|
+
written (`is-small is-large` keeps `is-large`), so the element still renders both.
|
|
6
|
+
|
|
7
|
+
`{viewport}` is one of `mobile`, `tablet`, `desktop`, `widescreen`, `fullhd` unless a row says
|
|
8
|
+
otherwise, and the prop takes the matching suffix: `is-6-tablet` → `sizeTablet="6"`.
|
|
9
|
+
|
|
10
|
+
## Component classes
|
|
11
|
+
|
|
12
|
+
### `.button` → `Button`
|
|
13
|
+
|
|
14
|
+
| Classes | Prop |
|
|
15
|
+
| ------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------- |
|
|
16
|
+
| `is-primary`, `is-link`, `is-info`, `is-success`, `is-warning`, `is-danger`, `is-white`, `is-dark`, `is-black`, `is-text`, `is-ghost` | `color` |
|
|
17
|
+
| `is-small`, `is-normal`, `is-medium`, `is-large` | `size` |
|
|
18
|
+
| `is-light` | `isLight` |
|
|
19
|
+
| `is-rounded`, `is-loading`, `is-static`, `is-outlined`, `is-inverted` | `isRounded`, `isLoading`, `isStatic`, `isOutlined`, `isInverted` |
|
|
20
|
+
| `is-focused`, `is-active`, `is-hovered` | `isFocused`, `isActive`, `isHovered` |
|
|
21
|
+
| `is-fullwidth` | `isFullwidth` |
|
|
22
|
+
|
|
23
|
+
`is-disabled` stays a class: `isDisabled` also writes `disabled` or `aria-disabled`, which the
|
|
24
|
+
element did not have. On any tag but `<button>`, bestax takes the element's `as`
|
|
25
|
+
(`<a className="button">` → `<Button as="a">`).
|
|
26
|
+
|
|
27
|
+
### `.buttons` → `Buttons`, `.tags` → `Tags`
|
|
28
|
+
|
|
29
|
+
| Classes | Prop |
|
|
30
|
+
| -------------------------------------- | ----------------------------------- |
|
|
31
|
+
| `is-centered`, `is-right` (Buttons) | `isCentered`, `isRight` |
|
|
32
|
+
| `has-addons` | `hasAddons` |
|
|
33
|
+
| `are-small`, `are-medium`, `are-large` | `size` (Tags: `medium` and `large`) |
|
|
34
|
+
|
|
35
|
+
### `.columns` → `Columns`
|
|
36
|
+
|
|
37
|
+
| Classes | Prop |
|
|
38
|
+
| ---------------------------------------------------------------------- | ----------------------------------------------------------------- |
|
|
39
|
+
| `is-centered`, `is-gapless`, `is-multiline`, `is-mobile`, `is-desktop` | `isCentered`, `isGapless`, `isMultiline`, `isMobile`, `isDesktop` |
|
|
40
|
+
| `is-vcentered` | `isVCentered` |
|
|
41
|
+
| `is-0` … `is-8` | `gap` |
|
|
42
|
+
| `is-0-{viewport}` … `is-8-{viewport}` | `gap{Viewport}` |
|
|
43
|
+
|
|
44
|
+
### `.column` → `Column`
|
|
45
|
+
|
|
46
|
+
Sizes are `1` to `12`, `full`, `half`, `one-third`, `two-thirds`, `one-quarter`,
|
|
47
|
+
`three-quarters`, `one-fifth`, `two-fifths`, `three-fifths` and `four-fifths`.
|
|
48
|
+
|
|
49
|
+
| Classes | Prop |
|
|
50
|
+
| ----------------------------------------- | ------------------------------------- |
|
|
51
|
+
| `is-{size}` | `size` |
|
|
52
|
+
| `is-{size}-{viewport}` | `size{Viewport}` |
|
|
53
|
+
| `is-offset-{size}` (no `full`) | `offset` |
|
|
54
|
+
| `is-offset-{size}-{viewport}` | `offset{Viewport}` |
|
|
55
|
+
| `is-narrow` | `isNarrow` |
|
|
56
|
+
| `is-narrow-{viewport}`, `is-narrow-touch` | `isNarrow{Viewport}`, `isNarrowTouch` |
|
|
57
|
+
|
|
58
|
+
### `.container` → `Container`
|
|
59
|
+
|
|
60
|
+
| Classes | Prop |
|
|
61
|
+
| ------------------------------------------------------ | ------------------------------- |
|
|
62
|
+
| `is-fluid`, `is-widescreen`, `is-fullhd` | `fluid`, `widescreen`, `fullhd` |
|
|
63
|
+
| `is-max-tablet`, `is-max-desktop`, `is-max-widescreen` | `breakpoint` and `isMax` |
|
|
64
|
+
|
|
65
|
+
### `.title` → `Title`, `.subtitle` → `SubTitle`
|
|
66
|
+
|
|
67
|
+
| Classes | Prop |
|
|
68
|
+
| ------------------- | ---------------------------------------------- |
|
|
69
|
+
| `is-1` … `is-6` | `size`, only on the matching `<hN>` or a `<p>` |
|
|
70
|
+
| `is-spaced` (Title) | `isSpaced` |
|
|
71
|
+
| `has-skeleton` | `hasSkeleton` |
|
|
72
|
+
|
|
73
|
+
bestax picks the heading from `size` (`size="3"` renders an `<h3>`) unless `as="p"`. So on an
|
|
74
|
+
`<h2>`, `is-4` stays a class and the element becomes `<Title as="h2" className="is-4">`, which
|
|
75
|
+
renders the same `<h2>`.
|
|
76
|
+
|
|
77
|
+
### Other components
|
|
78
|
+
|
|
79
|
+
| Component | Classes | Prop |
|
|
80
|
+
| -------------------------------- | -------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------- |
|
|
81
|
+
| `.content` → `Content` | `is-small`, `is-medium`, `is-large` | `size` |
|
|
82
|
+
| `.delete` → `Delete` | `is-small`, `is-medium`, `is-large` | `size` |
|
|
83
|
+
| `.hero` → `Hero` | `is-primary`, `is-link`, `is-info`, `is-success`, `is-warning`, `is-danger`, `is-black`, `is-white`, `is-light`, `is-dark` | `color` |
|
|
84
|
+
| `.hero` → `Hero` | `is-small`, `is-medium`, `is-large`, `is-fullheight`, `is-fullheight-with-navbar` | `size` |
|
|
85
|
+
| `.level` → `Level` | `is-mobile` | `isMobile` |
|
|
86
|
+
| `.notification` → `Notification` | `is-primary`, `is-link`, `is-info`, `is-success`, `is-warning`, `is-danger`, `is-black`, `is-white`, `is-dark` | `color` |
|
|
87
|
+
| `.notification` → `Notification` | `is-light` | `isLight` |
|
|
88
|
+
| `.progress` → `Progress` | the ten `.hero` colors | `color` |
|
|
89
|
+
| `.progress` → `Progress` | `is-small`, `is-medium`, `is-large` | `size` |
|
|
90
|
+
| `.section` → `Section` | `is-medium`, `is-large` | `size` |
|
|
91
|
+
| `.table` → `Table` | `is-bordered`, `is-striped`, `is-narrow`, `is-hoverable`, `is-fullwidth` | `isBordered`, `isStriped`, `isNarrow`, `isHoverable`, `isFullwidth` |
|
|
92
|
+
| `.tag` → `Tag` | `is-primary`, `is-link`, `is-info`, `is-success`, `is-warning`, `is-danger`, `is-black`, `is-dark`, `is-white` | `color` |
|
|
93
|
+
| `.tag` → `Tag` | `is-light`, `is-rounded`, `is-hoverable` | `isLight`, `isRounded`, `isHoverable` |
|
|
94
|
+
| `.tag` → `Tag` | `is-medium`, `is-large` | `size` |
|
|
95
|
+
|
|
96
|
+
`Progress` takes `value` and `max` as numbers: `value="40"` becomes `value={40}`. An
|
|
97
|
+
expression (`value={percent}`) carries over as written, so if it holds a string the migrated
|
|
98
|
+
file fails to typecheck while still rendering the same; wrap it in `Number(…)`. `Delete`
|
|
99
|
+
converts only with `type` and `aria-label` set (see `defaults:<Target>` in the unmappables),
|
|
100
|
+
and a `type="button"` is dropped, since bestax renders it by itself. `.tag`'s `is-delete` stays
|
|
101
|
+
a class: `isDelete` turns the tag into a `<button>`.
|
|
102
|
+
|
|
103
|
+
## Helper classes
|
|
104
|
+
|
|
105
|
+
These convert on every component above and on the plain-tag wrappers.
|
|
106
|
+
|
|
107
|
+
Colors are `primary`, `link`, `info`, `success`, `warning`, `danger`, `black`, `black-bis`,
|
|
108
|
+
`black-ter`, `grey-darker`, `grey-dark`, `grey`, `grey-light`, `grey-lighter`, `white`,
|
|
109
|
+
`white-bis`, `white-ter`, `light`, `dark`, `inherit` and `current`.
|
|
110
|
+
|
|
111
|
+
| Classes | Prop |
|
|
112
|
+
| --------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------- |
|
|
113
|
+
| `m-{n}`, `mt-{n}`, `mr-{n}`, `mb-{n}`, `ml-{n}`, `mx-{n}`, `my-{n}` (`0` to `6`, `auto`) | `m`, `mt`, `mr`, `mb`, `ml`, `mx`, `my` |
|
|
114
|
+
| `p-{n}`, `pt-{n}`, `pr-{n}`, `pb-{n}`, `pl-{n}`, `px-{n}`, `py-{n}` | `p`, `pt`, `pr`, `pb`, `pl`, `px`, `py` |
|
|
115
|
+
| `has-text-{color}` | `textColor` (on `Table`, `color`) |
|
|
116
|
+
| `has-background-{color}` | `bgColor` (on `Tag`, `backgroundColor`) |
|
|
117
|
+
| `is-size-1` … `is-size-7`, and `-{viewport}` | `textSize`, `textSize{Viewport}` |
|
|
118
|
+
| `has-text-centered`, `-justified`, `-left`, `-right`, and `-{viewport}` | `textAlign`, `textAlign{Viewport}` |
|
|
119
|
+
| `is-capitalized`, `is-lowercase`, `is-uppercase`, `is-italic` | `textTransform` |
|
|
120
|
+
| `has-text-weight-light`, `-normal`, `-medium`, `-semibold`, `-bold` | `textWeight` |
|
|
121
|
+
| `is-family-sans-serif`, `-monospace`, `-primary`, `-secondary`, `-code` | `fontFamily` |
|
|
122
|
+
| `is-block`, `is-flex`, `is-inline`, `is-inline-block`, `is-inline-flex`, `is-grid` | `display` |
|
|
123
|
+
| the same with any of the nine viewports, `touch` and the `-only` ones included | `display{Viewport}` |
|
|
124
|
+
| `is-hidden`, `is-invisible`, `is-sr-only` | `visibility` |
|
|
125
|
+
| `is-hidden-{viewport}`, `is-invisible-{viewport}`, all nine viewports | `visibility{Viewport}` |
|
|
126
|
+
| `is-flex-direction-*`, `is-flex-wrap-*`, `is-justify-content-*`, `is-align-content-*`, `is-align-items-*` | `flexDirection`, `flexWrap`, `justifyContent`, `alignContent`, `alignItems` |
|
|
127
|
+
| `is-align-self-*`, `is-flex-grow-*`, `is-flex-shrink-*` | `alignSelf`, `flexGrow`, `flexShrink` |
|
|
128
|
+
| `is-pulled-left`, `is-pulled-right` | `float` |
|
|
129
|
+
| `is-clipped` | `overflow="clipped"` |
|
|
130
|
+
| `is-overlay`, `is-skeleton`, `is-clearfix`, `is-relative` | `overlay`, `skeleton`, `clearfix`, `relative` |
|
|
131
|
+
| `is-unselectable`, `is-clickable` | `interaction` |
|
|
132
|
+
| `is-radiusless`, `is-shadowless` | `radius`, `shadow` |
|
|
133
|
+
| `is-mobile`, `is-narrow` (where the component has no prop of its own for them) | `responsive` |
|
|
134
|
+
|
|
135
|
+
Where a component renders a color class through no typed prop, the class stays: `has-text-*`
|
|
136
|
+
on `Hero`, `Progress`, `Tag` and `Tags`; `has-background-*` on `Notification`, `Progress`,
|
|
137
|
+
`Table` and `Tags`.
|
|
138
|
+
|
|
139
|
+
Some classes stay put because of how bestax renders them:
|
|
140
|
+
|
|
141
|
+
- A base `display` class next to a per-viewport one (`is-flex is-block-mobile`) keeps the base
|
|
142
|
+
class: bestax drops the base `display` whenever a per-viewport one is set.
|
|
143
|
+
- The flex-container classes (`is-justify-content-*` and the others in that row) convert only
|
|
144
|
+
beside a flex `display` prop, the only place bestax renders them.
|
|
145
|
+
- `is-hidden` becomes `visibility="hidden"`, which renders the same class and doesn't interact
|
|
146
|
+
with `display`.
|
|
147
|
+
|
|
148
|
+
## Classes that stay classes
|
|
149
|
+
|
|
150
|
+
Color shades (`has-text-primary-65`), the `-touch` and `-only` breakpoints of text size and
|
|
151
|
+
alignment, Grid and `.image` modifiers, and the Bulma helpers with no bestax prop
|
|
152
|
+
(`is-display-*`, `is-overflow-*`, `is-position-*`, `is-float-*`, `has-radius-*`, …) stay in
|
|
153
|
+
`className`. They render exactly as before.
|
|
@@ -0,0 +1,170 @@
|
|
|
1
|
+
# Bulma classes → bestax-bulma: what the codemod leaves for you
|
|
2
|
+
|
|
3
|
+
Every `TODO(bestax-migrate)` this source writes, by rule, with what to do about it. The markup
|
|
4
|
+
under a TODO is exactly as it was, so the app still renders the same while you work through
|
|
5
|
+
them. The rule after the colon names a Bulma class, a bestax component or prop, or an
|
|
6
|
+
attribute, never one of your own classes.
|
|
7
|
+
|
|
8
|
+
## An element it would not convert
|
|
9
|
+
|
|
10
|
+
### `spread:<Target>`
|
|
11
|
+
|
|
12
|
+
The element spreads props (`<div className="box" {...rest}>`). A spread can carry anything,
|
|
13
|
+
and bestax reads some names as its own props: a spread `className` merges with the component's
|
|
14
|
+
classes, where on the plain element it replaced them. Convert by hand once you know what the
|
|
15
|
+
spread carries, or leave it.
|
|
16
|
+
|
|
17
|
+
### `ref:<Target>`
|
|
18
|
+
|
|
19
|
+
The element has a `ref`, and the bestax component doesn't forward one, so the ref would stop
|
|
20
|
+
reaching the DOM node. Only `Button` and `Link` forward refs among the components this source
|
|
21
|
+
converts. Keep the element as markup.
|
|
22
|
+
|
|
23
|
+
### `tag:<Target>`
|
|
24
|
+
|
|
25
|
+
bestax renders that component on a fixed tag, or a short list of them through `as` (see the
|
|
26
|
+
**Tags** column in [component-map.md](component-map.md)), and this element is on another one:
|
|
27
|
+
`<div className="section">`, `<p className="notification">`. Changing the tag changes the
|
|
28
|
+
markup, so decide whether you want it; if you do, change it and re-run.
|
|
29
|
+
|
|
30
|
+
### `attr:<prop>`
|
|
31
|
+
|
|
32
|
+
An attribute on the element is also a prop of the bestax component, which would read it
|
|
33
|
+
differently: `<div className="box" color="red">` would lose its `color` attribute to Box's text
|
|
34
|
+
color. Rename or drop the attribute, then re-run.
|
|
35
|
+
|
|
36
|
+
It also covers an attribute the component's props type rejects. `Delete` takes no `type`
|
|
37
|
+
(`type="button"` is the one value that converts, because `Delete` renders it anyway), and
|
|
38
|
+
`Progress` types `value` and `max` as numbers, so `value="half"` stays. A number converts only
|
|
39
|
+
when it is spelled the way it renders (`value="40"`, not `value="040"`).
|
|
40
|
+
|
|
41
|
+
`attr:dangerouslySetInnerHTML` is the same kind of refusal: the element sets its own content,
|
|
42
|
+
and some bestax components render content of their own beside `children`, which React
|
|
43
|
+
rejects. Keep the element as markup.
|
|
44
|
+
|
|
45
|
+
### `defaults:<Target>`
|
|
46
|
+
|
|
47
|
+
The component renders attributes of its own when the element doesn't set them. `Delete`
|
|
48
|
+
renders `type="button"` and `aria-label="Close"`. On a bare `<button className="delete">`,
|
|
49
|
+
converting would add both, changing a submit button inside a form into a plain button. Add the
|
|
50
|
+
attributes you want (usually both, with a real label), then re-run.
|
|
51
|
+
|
|
52
|
+
### `drops:<Target>`
|
|
53
|
+
|
|
54
|
+
The component drops an attribute on this tag. Most of these do nothing there anyway: `Button`
|
|
55
|
+
drops `href`, `target` and `rel` on a `<button>`, and `Level.Item` keeps link attributes only
|
|
56
|
+
on an `<a>`. Remove the attribute, then re-run.
|
|
57
|
+
|
|
58
|
+
`disabled` is the exception. `Button` drops it on a tag with no disabled state
|
|
59
|
+
(`<a className="button" disabled>`), but Bulma greys out a disabled `.button` on any tag, so
|
|
60
|
+
dropping it would change how the element looks. Keep that element as markup.
|
|
61
|
+
|
|
62
|
+
### `children:<Target>`
|
|
63
|
+
|
|
64
|
+
The component's props type requires children, and the element has none (`Buttons`). An empty
|
|
65
|
+
`.buttons` does nothing; delete it or give it buttons.
|
|
66
|
+
|
|
67
|
+
### `only-child:<Target>`
|
|
68
|
+
|
|
69
|
+
The element is the only child of another component (`<Link href="/x"><a className="button">`),
|
|
70
|
+
which may reach into it with `cloneElement`: next/link's legacy behavior, a tooltip, a Radix
|
|
71
|
+
`asChild` trigger. A bestax component would not take those props or that ref the same way.
|
|
72
|
+
Convert it by hand if the parent only renders its children.
|
|
73
|
+
|
|
74
|
+
### `dynamic-class:<Target>`
|
|
75
|
+
|
|
76
|
+
The `className` is computed (`clsx(...)`, a ternary, a template with expressions), and with
|
|
77
|
+
its classes written out the element would become bestax `<Target>`. The codemod converts
|
|
78
|
+
static strings only. Convert by hand with the [prop map](prop-map.md), turning each condition
|
|
79
|
+
into the prop:
|
|
80
|
+
|
|
81
|
+
```tsx
|
|
82
|
+
// before
|
|
83
|
+
<button className={clsx('button', busy && 'is-loading')}>Save</button>
|
|
84
|
+
// after
|
|
85
|
+
<Button isLoading={busy}>Save</Button>
|
|
86
|
+
```
|
|
87
|
+
|
|
88
|
+
The classes in a computed `className` still count for every other rule: a `clsx('box')` on a
|
|
89
|
+
`<span>` gets `tag:Box`, and a `clsx('card', …)` gets `family:card`.
|
|
90
|
+
|
|
91
|
+
## A family it leaves as markup: `family:<class>`
|
|
92
|
+
|
|
93
|
+
The bestax component renders parts of its own, or adds attributes, so a one-element-at-a-time
|
|
94
|
+
conversion would change the markup. Convert the whole family by hand, and look at the result
|
|
95
|
+
in the browser:
|
|
96
|
+
|
|
97
|
+
- **`family:card`**: `Card` wraps any child that is not one of its parts in `.card-content`.
|
|
98
|
+
Use its parts, `Card.Header` (with `Card.Header.Title` and `Card.Header.Icon`),
|
|
99
|
+
`Card.Image`, `Card.Content`, `Card.Footer` and `Card.FooterItem`, together.
|
|
100
|
+
- **`family:navbar`**: `Navbar` adds `role="navigation"` and an `aria-label`, and
|
|
101
|
+
`Navbar.Burger` renders its own three spans. Its parts are `Navbar.Brand`, `Navbar.Item`,
|
|
102
|
+
`Navbar.Link`, `Navbar.Burger`, `Navbar.Menu`, `Navbar.Start`, `Navbar.End`,
|
|
103
|
+
`Navbar.Dropdown`, `Navbar.DropdownMenu` and `Navbar.Divider`.
|
|
104
|
+
- **`family:field`**, **`family:input`**, **`family:textarea`**, **`family:select`**,
|
|
105
|
+
**`family:file`**: bestax's form controls render their own `.field` and `.control` wrappers
|
|
106
|
+
(and `File` its whole `.file-label` tree). Replace the whole `.field` block with the
|
|
107
|
+
control, not each element in it. See the `bestax-form` skill.
|
|
108
|
+
- **`family:checkbox`**, **`family:radio`**, **`family:checkboxes`**, **`family:radios`**:
|
|
109
|
+
bestax renders its own styled checkbox and radio markup, not Bulma's.
|
|
110
|
+
- **`family:modal`**: `Modal` renders its own background and content parts, and adds dialog
|
|
111
|
+
attributes. Rebuild it with `Modal` and its parts, and drive it with its open prop.
|
|
112
|
+
- **`family:dropdown`**: `Dropdown` renders its own trigger and menu from props.
|
|
113
|
+
- **`family:icon`**, **`family:icon-text`**: `Icon` renders its own `<i>` and adds an
|
|
114
|
+
`aria-label`. See the `bestax-icons` skill for its library and name props.
|
|
115
|
+
- **`family:image`**: `Image` renders its own `<img>`.
|
|
116
|
+
- **`family:menu`**: `Menu.Item` renders the `<li>` and the `<a>` together.
|
|
117
|
+
- **`family:message`**: `Message` always wraps its children in `.message-body`.
|
|
118
|
+
- **`family:pagination`**, **`family:panel`**, **`family:tabs`**, **`family:breadcrumb`**:
|
|
119
|
+
each renders list items, links or roles of its own. Rebuild them from the component's docs.
|
|
120
|
+
- **`family:grid`**, **`family:cell`**, **`family:fixed-grid`**: this source leaves Grid markup
|
|
121
|
+
as written. `Grid` and `Cell` convert by hand; `Grid isFixed` renders the `.fixed-grid`
|
|
122
|
+
wrapper itself.
|
|
123
|
+
- **`family:table-container`**: bestax renders `.table-container` from `Table isResponsive`.
|
|
124
|
+
- **`family:skeleton-block`**, **`family:skeleton-lines`**: `Skeleton` renders its own markup.
|
|
125
|
+
|
|
126
|
+
## A class Bulma v1 removed: `legacy:<class>`
|
|
127
|
+
|
|
128
|
+
`legacy:tile`: Bulma v1 has no tiles. Rebuild the layout with `Grid` and `Cell`; the Bulma
|
|
129
|
+
0.9 to 1 guide shows the translation. Until then the element has no styles at all under
|
|
130
|
+
Bulma v1.
|
|
131
|
+
|
|
132
|
+
## A whole file it left alone
|
|
133
|
+
|
|
134
|
+
These come only when the file has an element the codemod would convert (a computed className
|
|
135
|
+
counts), so a re-run after the fix has something to do. A non-React file gets `jsx-runtime`
|
|
136
|
+
alone: every other TODO names a React component to use.
|
|
137
|
+
|
|
138
|
+
- **`rsc`**: the file is in a Next.js App Router project (a package with `next` and an
|
|
139
|
+
`app/` directory) and has no `'use client'`, so it may render as a server component, and
|
|
140
|
+
bestax's components are client components. That covers files outside `app/` too: a
|
|
141
|
+
component under `components/` is a server component when a server page renders it. Files
|
|
142
|
+
under `pages/` are always client code and convert. Add `'use client'` if the file can be a
|
|
143
|
+
client module (no `async` component, no server-only calls), then re-run.
|
|
144
|
+
- **`styled-jsx`**: the component scopes its styles with `<style jsx>`, which adds its scoping
|
|
145
|
+
class to plain elements and not to an imported component, so a converted element would lose
|
|
146
|
+
its styles. Move those
|
|
147
|
+
styles out of `<style jsx>`, or scope them with `:global()`, then re-run.
|
|
148
|
+
- **`imports`**: the file is CommonJS (`require` or `module.exports`, no ES `import` or
|
|
149
|
+
`export`), and the codemod adds an ES `import`. Move the file to ES modules, then re-run.
|
|
150
|
+
- **`jsx-runtime`**: the file's JSX isn't React's: a `@jsx` pragma or `@jsxImportSource` naming
|
|
151
|
+
another runtime (Preact, Solid), or a package that sets one in its tsconfig or depends on one
|
|
152
|
+
instead of React. bestax-bulma components are React components.
|
|
153
|
+
|
|
154
|
+
## Things that get no TODO
|
|
155
|
+
|
|
156
|
+
- Helper classes on a `<div>` (`<div className="is-flex mt-4">`): bestax has no plain `<div>`
|
|
157
|
+
wrapper, and the classes are valid Bulma, so the element stays.
|
|
158
|
+
- `.help`, `.label`, `.loader` and the other classes in the component map's "left alone" list.
|
|
159
|
+
- A class with no bestax prop on a converted element: it stays in `className`.
|
|
160
|
+
|
|
161
|
+
## After the codemod
|
|
162
|
+
|
|
163
|
+
Class order changes on converted elements (bestax writes its own classes first), so snapshot
|
|
164
|
+
tests that compare class strings will churn while the rendered page stays the same. Update the
|
|
165
|
+
snapshots after reviewing the diff.
|
|
166
|
+
|
|
167
|
+
If the build runs PurgeCSS, the report says so: a converted element's classes now come from
|
|
168
|
+
bestax's code, some of them built from props at runtime (`mt="4"` renders `mt-4`), so the
|
|
169
|
+
PurgeCSS config has to scan bestax's dist and safelist those patterns. The docs' optimizing CSS
|
|
170
|
+
guide has the config.
|
|
@@ -8,7 +8,14 @@ stylesheet layer; this reference explains what it did and how to finish what it
|
|
|
8
8
|
Coming from rbx or bloomer you are crossing **two** Bulma majors rather than one, so expect more
|
|
9
9
|
visual drift than the 0.9 → 1 notes below describe on their own.
|
|
10
10
|
|
|
11
|
-
|
|
11
|
+
An app that writes Bulma's classes directly (`bulma-classes`) keeps its stylesheet by
|
|
12
|
+
default: that source runs as `--css keep`, because the app's own Bulma already styles every
|
|
13
|
+
class a converted element renders, so its stylesheet imports, Sass and Bulma version stay as
|
|
14
|
+
they were. Moving to Bulma v1 is a separate step, taken with `--css bestax` or `--css bulma`.
|
|
15
|
+
From a 0.9.x it then follows these notes as written; on Bulma v1 already, only the bundle
|
|
16
|
+
choice below applies.
|
|
17
|
+
|
|
18
|
+
## What the codemod already did (`--css bestax`, the library sources' default)
|
|
12
19
|
|
|
13
20
|
- **CSS imports**: `bulma/css/bulma(.min).css` and v3-era
|
|
14
21
|
the source library's own CSS imports (`react-bulma-components/dist/*.css`,
|
|
@@ -151,23 +151,34 @@ The third row is the `Navbar.Dropdown` collision, and it runs both ways. Your rb
|
|
|
151
151
|
`Navbar.Dropdown` is the menu itself (`div.navbar-dropdown`), so it maps to bestax's
|
|
152
152
|
`Navbar.DropdownMenu`, which forwards no ref — `innerRef` there is left alone. bestax reserves
|
|
153
153
|
the name `Navbar.Dropdown` for the outer container, which is what `<Navbar.Item dropdown>`
|
|
154
|
-
becomes
|
|
155
|
-
|
|
154
|
+
becomes. The rename stays conditional on the `dropdown` prop because only that branch knows
|
|
155
|
+
which of the two targets was picked, not because the other branch lacks a ref: a plain
|
|
156
|
+
`<Navbar.Item>` forwards one too since #661, so its `innerRef` is a rename the codemod leaves
|
|
157
|
+
for you (see the gap below).
|
|
156
158
|
|
|
157
159
|
An existing `ref` is passed through untouched — which is safe only where the bestax target
|
|
158
|
-
forwards one. rbx forwards a ref on every component; bestax does so on the form controls plus
|
|
159
|
-
`
|
|
160
|
-
`
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
160
|
+
forwards one. rbx forwards a ref on every component; bestax does so on the form controls, plus
|
|
161
|
+
`Avatar`, `Button`, `Carousel`, `CarouselItem`, `Dialog`, `Dropdown`, `Link`, `LinkButton`,
|
|
162
|
+
`Menu.Item`, `Modal`, `Navbar`, `Navbar.Burger`, `Navbar.Dropdown`, `Navbar.Item`,
|
|
163
|
+
`Navbar.Link`, `Sidebar` and `Toast`. "The form controls" there means the inputs themselves:
|
|
164
|
+
the `Field`, `Field.Label`, `Field.Body`, `Checkboxes` and `Radios` wrappers around them
|
|
165
|
+
forward nothing, and `Field` is a target this codemod emits.
|
|
166
|
+
|
|
167
|
+
Carry a `ref` onto anything else — `Card`, `Box`, `Section`, `Message`, `Tabs` and most of the
|
|
168
|
+
catalogue — and it is unsupported, but the two React majors fail differently. React 18 drops
|
|
169
|
+
it and logs "Function components cannot be given refs". React 19 hands `ref` to the component
|
|
170
|
+
as an ordinary prop, so it lands wherever that component spreads its rest props, silently and
|
|
171
|
+
with no guarantee it is the element you meant. bestax supports both majors, so neither
|
|
172
|
+
outcome is one to build on: put the ref on an element you control.
|
|
164
173
|
|
|
165
174
|
**The codemod does not flag this**, because neither the universal prop table nor any
|
|
166
175
|
per-component table has a `ref` entry, so check every `ref` you carried over against the list
|
|
167
176
|
above rather than assuming the silent pass-through means it works. The renames above are for
|
|
168
|
-
`innerRef`, and apply only on those eight entries.
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
177
|
+
`innerRef`, and apply only on those eight entries.
|
|
178
|
+
|
|
179
|
+
Note the gap that leaves. An rbx `innerRef` can only land on a component rbx itself has, so of
|
|
180
|
+
the ref-forwarding targets above the reachable ones are the form controls, `Menu.Item` and a
|
|
181
|
+
plain `Navbar.Item`. There the codemod leaves `innerRef` in place and flags it rather than
|
|
182
|
+
renaming it, so the rename is yours to make and the target will take it. Everywhere the eight
|
|
183
|
+
renames above do not reach, `innerRef` is flagged the same way — but on a target that forwards
|
|
184
|
+
nothing the answer is a wrapping element you control, not a rename.
|
|
@@ -128,11 +128,19 @@ bestax `Button` colors are the semantic set + `text`/`ghost`. For shades use
|
|
|
128
128
|
|
|
129
129
|
## `domRef`
|
|
130
130
|
|
|
131
|
-
bestax components don't take `domRef`, but many forward a plain `ref` — the form controls
|
|
132
|
-
|
|
133
|
-
`
|
|
134
|
-
`
|
|
135
|
-
|
|
131
|
+
bestax components don't take `domRef`, but many forward a plain `ref` — the form controls,
|
|
132
|
+
plus `Avatar`, `Button`, `Carousel`, `CarouselItem`, `Dialog`, `Dropdown`, `Link`,
|
|
133
|
+
`LinkButton`, `Menu.Item`, `Modal`, `Navbar`, `Navbar.Burger`, `Navbar.Dropdown`,
|
|
134
|
+
`Navbar.Item`, `Navbar.Link`, `Sidebar` and `Toast`. On those, rename `domRef` to
|
|
135
|
+
`ref` and it works; do not restructure the markup. "The form controls" means the inputs
|
|
136
|
+
themselves: the `Field`, `Field.Label`, `Field.Body`, `Checkboxes` and `Radios` wrappers
|
|
137
|
+
around them forward nothing, and `Field` is a target this codemod emits.
|
|
138
|
+
|
|
139
|
+
Everywhere else the rename is not enough, and the two React majors differ: React 18 drops the
|
|
140
|
+
ref and logs "Function components cannot be given refs", while React 19 passes it through as
|
|
141
|
+
an ordinary prop, so it settles wherever the component spreads its rest props with nothing
|
|
142
|
+
logged. bestax supports both, so attach the ref to a DOM element inside, or wrap the component
|
|
143
|
+
in a `<div ref={…}>`.
|
|
136
144
|
|
|
137
145
|
The codemod does not do that rename for you: `domRef` is flagged on every component, so the
|
|
138
146
|
TODO names both cases and you pick. `Navbar.Dropdown` is the trap, and it cuts both ways —
|
|
@@ -92,14 +92,14 @@ and numeric shades `--bulma-<c>-00` … `--bulma-<c>-95`.
|
|
|
92
92
|
|
|
93
93
|
## Radius, typography
|
|
94
94
|
|
|
95
|
-
| Variable | Default | `Theme` prop
|
|
96
|
-
| ----------------------------------------------------------------------------- | --------------------------------- |
|
|
97
|
-
| `--bulma-radius-small` / `--bulma-radius` / `--bulma-radius-large` | 0.25 / 0.375 / 0.75rem | via `bulmaVars`
|
|
98
|
-
| `--bulma-radius-rounded` | 9999px | via `bulmaVars`
|
|
99
|
-
| `--bulma-family-primary` / `--bulma-family-secondary` / `--bulma-family-code` | sans / sans / mono | via `bulmaVars`
|
|
100
|
-
| `--bulma-size-1` … `--bulma-size-7` | 3rem … 0.75rem |
|
|
101
|
-
| `--bulma-size-small` / `-normal` / `-medium` / `-large` | 0.75 / 1 / 1.25 / 1.5rem | via `bulmaVars`
|
|
102
|
-
| `--bulma-weight-light/normal/medium/semibold/bold/extrabold` | 300 / 400 / 500 / 600 / 700 / 800 | via `bulmaVars`
|
|
95
|
+
| Variable | Default | `Theme` prop |
|
|
96
|
+
| ----------------------------------------------------------------------------- | --------------------------------- | ------------------------------- |
|
|
97
|
+
| `--bulma-radius-small` / `--bulma-radius` / `--bulma-radius-large` | 0.25 / 0.375 / 0.75rem | via `bulmaVars` |
|
|
98
|
+
| `--bulma-radius-rounded` | 9999px | via `bulmaVars` |
|
|
99
|
+
| `--bulma-family-primary` / `--bulma-family-secondary` / `--bulma-family-code` | sans / sans / mono | via `bulmaVars` |
|
|
100
|
+
| `--bulma-size-1` … `--bulma-size-7` | 3rem … 0.75rem | CSS only, not a `bulmaVars` key |
|
|
101
|
+
| `--bulma-size-small` / `-normal` / `-medium` / `-large` | 0.75 / 1 / 1.25 / 1.5rem | via `bulmaVars` |
|
|
102
|
+
| `--bulma-weight-light/normal/medium/semibold/bold/extrabold` | 300 / 400 / 500 / 600 / 700 / 800 | via `bulmaVars` |
|
|
103
103
|
|
|
104
104
|
## Shadow — override the upstream token, not the derived one
|
|
105
105
|
|