create-bestax 4.2.17 → 4.2.18
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/README.md +13 -5
- package/dist/cli.d.ts.map +1 -1
- package/dist/cli.js +1 -1
- package/dist/constants.d.ts +2 -0
- package/dist/constants.d.ts.map +1 -1
- package/dist/constants.js +6 -1
- package/dist/display.d.ts +9 -0
- package/dist/display.d.ts.map +1 -1
- package/dist/display.js +19 -1
- package/dist/file-system.d.ts +16 -3
- package/dist/file-system.d.ts.map +1 -1
- package/dist/file-system.js +41 -5
- package/dist/project-creator.d.ts +16 -1
- package/dist/project-creator.d.ts.map +1 -1
- package/dist/project-creator.js +35 -6
- package/dist/prompts.d.ts +1 -0
- package/dist/prompts.d.ts.map +1 -1
- package/dist/prompts.js +3 -2
- package/dist/validators.d.ts +8 -0
- package/dist/validators.d.ts.map +1 -1
- package/dist/validators.js +18 -1
- package/package.json +3 -3
- package/templates/skills/bestax-custom-component/references/component-catalog.md +3 -1
- package/templates/skills/bestax-form/SKILL.md +6 -2
- package/templates/skills/bestax-form/references/api.md +3 -0
- package/templates/skills/bestax-form/references/patterns.md +7 -3
- package/templates/skills/bestax-layout-scaffold/SKILL.md +20 -3
- package/templates/skills/bestax-layout-scaffold/references/layout-components.md +3 -3
- package/templates/skills/bestax-migrate/SKILL.md +23 -2
- package/templates/skills/bestax-migrate/references/bloomer/prop-map.md +4 -4
- package/templates/skills/bestax-migrate/references/bulma-classes/component-map.md +9 -4
- package/templates/skills/bestax-migrate/references/bulma-classes/prop-map.md +1 -1
- package/templates/skills/bestax-migrate/references/bulma-classes/unmappables.md +317 -4
- package/templates/skills/bestax-migrate/references/css-migration.md +5 -1
- package/templates/skills/bestax-migrate/references/rbx/prop-map.md +4 -4
- package/templates/skills/bestax-migrate/references/react-bulma-components/unmappables.md +4 -4
- package/templates/skills/bestax-optimize/references/modular-build.md +5 -3
- package/templates/skills/bestax-theming/references/css-variables.md +43 -0
- package/templates/skills/bestax-theming/references/themeable-components.md +2 -0
|
@@ -70,6 +70,9 @@ Field/Control/message props. `TextArea` adds `rows` and `hasFixedSize`.
|
|
|
70
70
|
|
|
71
71
|
- `Checkbox` / `Radio` — single controls with `color`, `size`, `checked`/`defaultChecked`,
|
|
72
72
|
`onChange`, `disabled`.
|
|
73
|
+
- `Checkbox` also takes `indeterminate`, the mixed state of a "Select all" box over a partly
|
|
74
|
+
checked list. It changes the look and the announcement, not the value: `checked` stays the
|
|
75
|
+
value, so set both from the list.
|
|
73
76
|
- `Checkboxes` — group wrapper managing an **array** value.
|
|
74
77
|
- `Radios` — group wrapper managing a **single** selected value.
|
|
75
78
|
|
|
@@ -131,7 +131,7 @@ Notes:
|
|
|
131
131
|
// Search box: input + button attached.
|
|
132
132
|
<Field hasAddons>
|
|
133
133
|
<Control isExpanded>
|
|
134
|
-
<InputBase placeholder="Search" />
|
|
134
|
+
<InputBase placeholder="Search" aria-label="Search" />
|
|
135
135
|
</Control>
|
|
136
136
|
<Control>
|
|
137
137
|
<Button color="primary">Search</Button>
|
|
@@ -141,14 +141,18 @@ Notes:
|
|
|
141
141
|
// Two controls on one row.
|
|
142
142
|
<Field grouped>
|
|
143
143
|
<Control>
|
|
144
|
-
<InputBase placeholder="First" />
|
|
144
|
+
<InputBase placeholder="First" aria-label="First name" />
|
|
145
145
|
</Control>
|
|
146
146
|
<Control>
|
|
147
|
-
<InputBase placeholder="Last" />
|
|
147
|
+
<InputBase placeholder="Last" aria-label="Last name" />
|
|
148
148
|
</Control>
|
|
149
149
|
</Field>
|
|
150
150
|
```
|
|
151
151
|
|
|
152
|
+
A `grouped` or `hasAddons` Field names none of the controls it holds, and a placeholder
|
|
153
|
+
disappears once the user types, so each input above carries an `aria-label`. For a visible
|
|
154
|
+
label instead, see the last item below.
|
|
155
|
+
|
|
152
156
|
Recipes built on addons, each written out in full in the docs:
|
|
153
157
|
|
|
154
158
|
- **Password reveal** ([docs](https://bestax.io/docs/api/form/input#password-reveal)): the
|
|
@@ -97,6 +97,21 @@ Centered; a collection of items → Card grid. For mixed requests, pick the domi
|
|
|
97
97
|
"Clear search" put focus back in the field. While data loads show a `Skeleton` or a `Loader`,
|
|
98
98
|
and a failed load is a `Message` or a `Notification`, never an EmptyState. The archetypes
|
|
99
99
|
reference has the full pattern under Card grid.
|
|
100
|
+
- **An order's history, a ticket's activity, a changelog or an activity feed is `Timeline`**,
|
|
101
|
+
not a hand-built list with a border down the side: `<Timeline titleAs="h3">` with a
|
|
102
|
+
`<Timeline.Item title="Shipped" time="14 October 2026" dateTime="2026-10-14">` per event, any
|
|
103
|
+
detail as its children, and the whole date in `time`. `titleAs` is the level under the
|
|
104
|
+
section's heading, or `"p"` in a busy feed. For something that moves along on its own, like a
|
|
105
|
+
parcel or a deployment, `active={i}` marks progress and `pending="Out for delivery"` ends it on
|
|
106
|
+
what's under way, oldest first. A journey the user moves through, like a wizard or a checkout,
|
|
107
|
+
stays `Steps`.
|
|
108
|
+
- **A file browser, a checkbox tree (permissions, filters) or an outline you browse is
|
|
109
|
+
`TreeView`**, with `<TreeView.Item value="…" label="…" icon="folder">` items nested inside each
|
|
110
|
+
other: `<TreeView aria-label="Files" selectionMode="single">` with `selected`/`onSelectedChange`
|
|
111
|
+
picks one, and `selectionMode="checkbox"` with `checked`/`onCheckedChange` draws boxes with
|
|
112
|
+
mixed parents, where a parent's value checks its whole branch. Map the data with a recursive
|
|
113
|
+
function, and render an item's children whether it's open or not. Its items aren't links, so
|
|
114
|
+
the app's sidebar and any list of pages stay on `Menu` with `Menu.Item href`.
|
|
100
115
|
- Link lists (footer nav, sidebars): a bare `UnorderedList` of `ListItem`s is already
|
|
101
116
|
marker-less and flush — Bulma's reset unstyles `ul` — so no prop or CSS is needed;
|
|
102
117
|
bullets appear only inside `Content`.
|
|
@@ -199,9 +214,11 @@ background comes from the semantic `color` prop, not `bgColor`.
|
|
|
199
214
|
| `display: 'none'` | `visibility="hidden"`, or responsive `display*` props (`displayMobile`, `displayTablet`, …) |
|
|
200
215
|
| `gap: '1rem'` (flex or grid) | `gap="2"`, or one axis: `columnGap`, `rowGap`; gap scale: `1`=0.5rem, `2`=1rem, `4`=2rem, half steps (`"1.5"`) |
|
|
201
216
|
|
|
202
|
-
No helper matches (e.g. `maxWidth`, a one-off gradient)? Add a named class to the project
|
|
203
|
-
stylesheet
|
|
204
|
-
|
|
217
|
+
No helper matches (e.g. `maxWidth`, a one-off gradient)? Add a named class to the project's
|
|
218
|
+
global stylesheet and pass it via `className` — still never inline `style`. In a create-bestax
|
|
219
|
+
app that is `src/index.css`, which its entry file imports after bestax's stylesheet, so the
|
|
220
|
+
class wins over a Bulma rule of the same weight. The starter page's `src/App.css` loads after
|
|
221
|
+
bestax's too, but only while the starter's `App` imports it.
|
|
205
222
|
|
|
206
223
|
## References
|
|
207
224
|
|
|
@@ -252,9 +252,9 @@ https://bestax.io/docs/guides/features/routing.
|
|
|
252
252
|
|
|
253
253
|
`<Menu>` is a vertical sidebar menu. Subcomponents: `Menu.Label`, `Menu.List`, `Menu.Item`.
|
|
254
254
|
|
|
255
|
-
| Prop | Type
|
|
256
|
-
| ----------- |
|
|
257
|
-
| `Menu.Item` | `active
|
|
255
|
+
| Prop | Type |
|
|
256
|
+
| ----------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
257
|
+
| `Menu.Item` | `active?` (the current page: `is-active` plus `aria-current="page"`, so don't add your own), `href?`, `as?` (custom link component); nest a `Menu.List` inside an item for submenus |
|
|
258
258
|
|
|
259
259
|
```tsx
|
|
260
260
|
<Menu>
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: bestax-migrate
|
|
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.
|
|
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 in static HTML pages and templates styled with Bulma, 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 static HTML pages or templates styled with Bulma should become React components, 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
|
|
|
@@ -21,6 +21,7 @@ The codemod's first argument names the library you are migrating _from_. Check t
|
|
|
21
21
|
| `rbx` v2 (abandoned 2019, pins Bulma **0.7.5** plus four extensions) | `rbx` | [`references/rbx/`](references/rbx/component-map.md) |
|
|
22
22
|
| `bloomer` 0.6 (archived 2018, Bulma 0.6 era, React 16 + `create-react-class`) | `bloomer` | [`references/bloomer/`](references/bloomer/component-map.md) |
|
|
23
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) |
|
|
24
|
+
| Static HTML pages or templates styled with Bulma (`<div class="box">`) | `bulma-classes` | [`references/bulma-classes/`](references/bulma-classes/unmappables.md) |
|
|
24
25
|
|
|
25
26
|
Everything below is written as `<source>`; substitute the argument from that table. The
|
|
26
27
|
reference paths follow the same split — `references/<source>/component-map.md`,
|
|
@@ -38,6 +39,24 @@ Run these steps in order. Don't hand-convert what the codemod converts automatic
|
|
|
38
39
|
pnpm dlx bestax-migrate <source> src/ --dry
|
|
39
40
|
```
|
|
40
41
|
|
|
42
|
+
For HTML pages, name a page, or walk a folder with `-e html` (`-e html,htm` for `.htm` pages
|
|
43
|
+
too; a plain walk skips them,
|
|
44
|
+
since most of it in a React project isn't a page to convert, and reports the Bulma pages it
|
|
45
|
+
skipped as `html-file:not-included`):
|
|
46
|
+
|
|
47
|
+
```sh
|
|
48
|
+
pnpm dlx bestax-migrate bulma-classes src/pages/login/index.html --dry
|
|
49
|
+
pnpm dlx bestax-migrate bulma-classes -e html src/pages/ --dry
|
|
50
|
+
```
|
|
51
|
+
|
|
52
|
+
Each page becomes a module beside it (`index.tsx`, or `.jsx` when the package isn't
|
|
53
|
+
TypeScript) whose default export is `<Name>Page`, named from the file (its folder's for an
|
|
54
|
+
`index.html`). The page stays as it was, and the codemod never writes over a module that's
|
|
55
|
+
already there, so a re-run writes nothing. Its head, its `<html>` and `<body>` attributes and
|
|
56
|
+
its scripts become `html-*` TODOs: put the app-wide parts in the app's `index.html` and
|
|
57
|
+
entry, and port each script's work into the component. Under `--css bestax` or `--css bulma`
|
|
58
|
+
the module imports the stylesheet in place of the page's Bulma `<link>`.
|
|
59
|
+
|
|
41
60
|
2. **Apply it** (same command without `--dry`), then run the project's formatter — the
|
|
42
61
|
codemod preserves surrounding formatting but doesn't prettify what it rewrites.
|
|
43
62
|
Besides the components, it also migrates **stylesheets** (CSS imports →
|
|
@@ -121,7 +140,9 @@ code per the references, or deliberately keep the old markup with `className` st
|
|
|
121
140
|
App Router may render as server components are left alone (`rsc`), and the manifest gains
|
|
122
141
|
`@allxsmith/bestax-bulma` while the app's Bulma and stylesheets stay (the default
|
|
123
142
|
`--css keep`). Its rules are `kind:<name>` shaped; see
|
|
124
|
-
`references/bulma-classes/unmappables.md`.
|
|
143
|
+
`references/bulma-classes/unmappables.md`. An HTML page converts the same way once it is JSX,
|
|
144
|
+
and what a component can't carry (the head, scripts, inline handlers, `<html>` and `<body>`
|
|
145
|
+
classes such as `has-navbar-fixed-top`) gets an `html-*` rule with its recipe there.
|
|
125
146
|
- **bloomer**: every export is a flat name and most become dotted bestax compounds
|
|
126
147
|
(`CardHeaderTitle` → `Card.Header.Title`). Most of its `is*` booleans already are bestax's
|
|
127
148
|
(`isActive` becomes `active` where bestax names it so; `isFullWidth` becomes `isFullwidth`
|
|
@@ -189,10 +189,10 @@ value is flagged. The same conversion covers the modifiers bestax has no prop fo
|
|
|
189
189
|
bloomer forwarded no refs. bestax forwards a ref from the form controls, plus `Avatar`, `Button`,
|
|
190
190
|
`Carousel`, `CarouselItem`, `Dialog`, `Dropdown`, `EmptyState`, `Kbd`, `Kbd.Group`, `Link`,
|
|
191
191
|
`LinkButton`, `Loader`, `Menu.Item`, `Modal`, `Navbar`, `Navbar.Burger`, `Navbar.Dropdown`,
|
|
192
|
-
`Navbar.Item`, `Navbar.Link`, `SegmentedControl`, `SegmentedControl.Segment`, `Sidebar`, `
|
|
193
|
-
`ToggleButton` — pass `ref` directly on
|
|
194
|
-
`Field`, `Field.Label`, `Field.Body`,
|
|
195
|
-
nothing.
|
|
192
|
+
`Navbar.Item`, `Navbar.Link`, `SegmentedControl`, `SegmentedControl.Segment`, `Sidebar`, `Timeline`,
|
|
193
|
+
`Timeline.Item`, `Toast`, `ToggleButton`, `TreeView` and `TreeView.Item` — pass `ref` directly on
|
|
194
|
+
those. "The form controls" means the inputs themselves: the `Field`, `Field.Label`, `Field.Body`,
|
|
195
|
+
`Checkboxes` and `Radios` wrappers around them forward nothing.
|
|
196
196
|
|
|
197
197
|
A `ref` on anything else is unsupported, and the two React majors fail differently: React 18
|
|
198
198
|
drops it and logs "Function components cannot be given refs", while React 19 hands it to the
|
|
@@ -154,11 +154,16 @@ element is a `.menu-list`, a bestax `Menu.List`, or the bare `<ul>` nested in on
|
|
|
154
154
|
so the `<li>`s a `.map()` renders count too. One handed to any other function doesn't, since that
|
|
155
155
|
function could render it anywhere. `Menu.Item` renders the `<li>` and its `<a>`
|
|
156
156
|
together, so an item converts when its `<li>` holds one `<a>` and at most one bare `<ul>` after
|
|
157
|
-
it, which becomes a `Menu.List`. `is-active` on the `<a>` becomes `active
|
|
157
|
+
it, which becomes a `Menu.List`. `is-active` on the `<a>` becomes `active` beside an
|
|
158
|
+
`aria-current` of the `<a>`'s own, since `active` writes `aria-current="page"` otherwise; without
|
|
159
|
+
one, the item stays markup with an `attr:aria-current` TODO. If the item is the current page, add
|
|
160
|
+
`aria-current="page"` to the `<a>` and re-run. The `<li>`'s own
|
|
158
161
|
classes stay in `className`, which `Menu.Item` puts on the `<li>`. It puts `id`, `title`, `role`,
|
|
159
162
|
`tabIndex`, `style` and `data-testid` there too, and everything else on the `<a>`, so an item
|
|
160
163
|
converts only when its attributes already sit that way. A `.menu-item` gets a
|
|
161
|
-
`family:menu-item` TODO. `Menu.List`
|
|
164
|
+
`family:menu-item` TODO. `Menu.List` writes `role="list"` on its `<ul>`, which is the role a
|
|
165
|
+
list already has, so a `.menu-list` with no `role` converts, and one with another `role` stays
|
|
166
|
+
markup with an `attr:role` TODO. `Menu.List` drops `.menu-list` on a list inside another, so a
|
|
162
167
|
`.menu-list` inside another, or around a bestax `Menu.List`, stays markup with a
|
|
163
168
|
`context:Menu.List` TODO, and an item's nested list converts only inside a list that is a
|
|
164
169
|
`Menu.List` or becomes one.
|
|
@@ -166,7 +171,7 @@ converts only when its attributes already sit that way. A `.menu-item` gets a
|
|
|
166
171
|
```tsx
|
|
167
172
|
<ul className="menu-list">
|
|
168
173
|
<li>
|
|
169
|
-
<a className="is-active" href="/team">Team</a>
|
|
174
|
+
<a className="is-active" href="/team" aria-current="page">Team</a>
|
|
170
175
|
<ul>
|
|
171
176
|
<li><a href="/team/members">Members</a></li>
|
|
172
177
|
</ul>
|
|
@@ -174,7 +179,7 @@ converts only when its attributes already sit that way. A `.menu-item` gets a
|
|
|
174
179
|
</ul>
|
|
175
180
|
// becomes
|
|
176
181
|
<Menu.List>
|
|
177
|
-
<Menu.Item active href="/team">
|
|
182
|
+
<Menu.Item active href="/team" aria-current="page">
|
|
178
183
|
Team
|
|
179
184
|
<Menu.List>
|
|
180
185
|
<Menu.Item href="/team/members">Members</Menu.Item>
|
|
@@ -109,7 +109,7 @@ renders the same `<h2>`.
|
|
|
109
109
|
| `.tabs` → `Tabs` | `is-centered`, `is-right`, `is-left` | `align` |
|
|
110
110
|
| `.tabs` → `Tabs` | `is-small`, `is-medium`, `is-large` | `size` |
|
|
111
111
|
| `.tabs` → `Tabs` | `is-fullwidth`, `is-boxed`, `is-toggle`, `is-toggle-rounded` | `isFullwidth`, `boxed`, `toggle`, `rounded` (`is-<color>` stays a class: `color` is deprecated) |
|
|
112
|
-
| the `<a>` in a menu item → `Menu.Item` | `is-active`
|
|
112
|
+
| the `<a>` in a menu item → `Menu.Item` | `is-active`, beside an `aria-current` of the `<a>`'s own | `active` (without one, the item stays markup with an `attr:aria-current` TODO) |
|
|
113
113
|
| `.pagination` → `Pagination` | `is-small`, `is-medium`, `is-large` | `size` |
|
|
114
114
|
| `.pagination` → `Pagination` | `is-centered`, `is-right`, `is-rounded` | `align`, `rounded` (`is-<color>` stays a class: `color` is deprecated) |
|
|
115
115
|
| `.pagination-link` → `Pagination.Link` | `is-current`, beside an `aria-current` of the element's own | `active` (without one, it stays a class; `is-disabled` stays a class) |
|
|
@@ -36,9 +36,10 @@ color. Rename or drop the attribute, then re-run.
|
|
|
36
36
|
|
|
37
37
|
It also covers an attribute the component's props type rejects. `Delete` takes no `type`
|
|
38
38
|
(`type="button"` is the one value that converts, because `Delete` renders it anyway), and
|
|
39
|
-
`Progress` types `value` and `max` as numbers, so `value="half"` stays.
|
|
40
|
-
`
|
|
41
|
-
|
|
39
|
+
`Progress` types `value` and `max` as numbers, so `value="half"` stays. `InputBase` and
|
|
40
|
+
`TextAreaBase` type `maxLength` and `minLength` as numbers, and `TextAreaBase` `rows` and `cols`
|
|
41
|
+
too. Every component types `tabIndex` as a number, so `tabIndex="0"` converts as `tabIndex={0}`.
|
|
42
|
+
A number converts only when it is spelled the way it renders (`value="40"`, not `value="040"`).
|
|
42
43
|
|
|
43
44
|
`attr:dangerouslySetInnerHTML` is the same kind of refusal: the element sets its own content,
|
|
44
45
|
and some bestax components render content of their own beside `children`, which React
|
|
@@ -67,6 +68,17 @@ empty one, keeps the item as markup too, and so does an empty `className` on the
|
|
|
67
68
|
nothing is left to render its `class=""`. Move the attribute to where `Menu.Item` puts it if
|
|
68
69
|
that's what you want, then re-run.
|
|
69
70
|
|
|
71
|
+
`attr:role` on a `.menu-list` is a `role` other than `list`. `Menu.List` writes `role="list"` on
|
|
72
|
+
its `<ul>` whatever it's given, for Safari, which stops treating a list as one once its markers are
|
|
73
|
+
hidden, so that role would be lost. Keep the list as markup. One with no `role`, or `role="list"`,
|
|
74
|
+
converts, since that's the role a `<ul>` already has.
|
|
75
|
+
|
|
76
|
+
`attr:aria-current` is the `<a>`'s `is-active` with no `aria-current` beside it. `Menu.Item`'s
|
|
77
|
+
`active` writes `aria-current="page"` on the `<a>` unless it has one of its own, so the item would
|
|
78
|
+
gain it. If the item marks the page you're on, which is what `is-active` usually means in a menu,
|
|
79
|
+
add `aria-current="page"` to the `<a>` and re-run, and the item converts with it. If it marks
|
|
80
|
+
something else, keep the markup, or convert it by hand and pass the `aria-current` you want.
|
|
81
|
+
|
|
70
82
|
### `defaults:<Target>`
|
|
71
83
|
|
|
72
84
|
The component renders attributes of its own when the element doesn't set them. `Delete`
|
|
@@ -270,7 +282,9 @@ The classes in a computed `className` still count for every other rule: a `clsx(
|
|
|
270
282
|
`<span>` gets `tag:Box`, and a `clsx('dropdown', …)` gets `family:dropdown`. A computed
|
|
271
283
|
`className` on the `<select>` inside a `.select`, the `<ul>` inside a `.breadcrumb` or the `<a>`
|
|
272
284
|
in a menu item gets this TODO too. For the `<a>`, a condition on `is-active` is `Menu.Item`'s
|
|
273
|
-
`active`: `<a className={on ? 'is-active' : undefined}>` becomes `<Menu.Item active={on}
|
|
285
|
+
`active`: `<a className={on ? 'is-active' : undefined}>` becomes `<Menu.Item active={on}>`, which
|
|
286
|
+
also writes `aria-current="page"` while `on` holds. Pass an `aria-current` of your own if the item
|
|
287
|
+
marks something other than the current page.
|
|
274
288
|
|
|
275
289
|
## A family it leaves as markup: `family:<class>`
|
|
276
290
|
|
|
@@ -338,6 +352,305 @@ alone: every other TODO names a React component to use.
|
|
|
338
352
|
another runtime (Preact, Solid), or a package that sets one in its tsconfig or depends on one
|
|
339
353
|
instead of React. bestax-bulma components are React components.
|
|
340
354
|
|
|
355
|
+
## A page converted from HTML: `html-*`
|
|
356
|
+
|
|
357
|
+
Run on an HTML page (`bestax-migrate bulma-classes page.html`, or a folder with `-e html`, or
|
|
358
|
+
`-e html,htm` to take `.htm` pages too), the
|
|
359
|
+
codemod writes a module beside the page and runs everything above on it, so a page gets the same
|
|
360
|
+
TODOs its markup would as JSX. What a component can't carry gets an `html-*` rule. TODOs about the
|
|
361
|
+
whole page sit above the component, the rest above its `return`, and each ends with the page and
|
|
362
|
+
the line it came from (`(index.html:42)`). The page itself stays as it was, so the code a TODO
|
|
363
|
+
points at is still there to read. A rule names only a tag, an attribute or a fixed word, never
|
|
364
|
+
anything the page says.
|
|
365
|
+
|
|
366
|
+
### The page's head: `html-head:<tag>`
|
|
367
|
+
|
|
368
|
+
A component renders into the `<body>` of the app's own document, so nothing in the page's
|
|
369
|
+
`<head>` comes with it.
|
|
370
|
+
|
|
371
|
+
- **`html-head:title`**: set the title where the app sets each page's title (its router's or
|
|
372
|
+
framework's head API). Under React 19 the component can render `<title>` itself and React moves
|
|
373
|
+
it into the head; React 18 leaves it in the body, so use `document.title` in an effect there.
|
|
374
|
+
- **`html-head:meta`**: `charset` and `viewport` go once in the app's `index.html`. A page's own
|
|
375
|
+
(a description, Open Graph tags) go where the app sets each page's head.
|
|
376
|
+
- **`html-head:link`**: icons, preconnects and preloads are app-wide, so keep them in
|
|
377
|
+
`index.html`; a `canonical` is per page.
|
|
378
|
+
- **`html-head:style`**: the `<style>` block was dropped. Move its rules into the app's stylesheet.
|
|
379
|
+
- **`html-head:base`**: `<base href>` changed how the page's relative URLs resolved, and the app
|
|
380
|
+
has one document for every route. Make those URLs absolute instead (see `html-url:relative`).
|
|
381
|
+
- **`html-head`**: anything else in the head (a `<noscript>`, a `<template>`). Move it into
|
|
382
|
+
`index.html` if the app needs it.
|
|
383
|
+
|
|
384
|
+
### Stylesheets and scripts it loads: `html-asset:<kind>`
|
|
385
|
+
|
|
386
|
+
Each `<link rel="stylesheet">` and `<script src>`, by what its URL says it is. A component loads
|
|
387
|
+
neither, so load what the app still needs once for the whole app, from its entry module or
|
|
388
|
+
`index.html`. The TODO quotes the URL.
|
|
389
|
+
|
|
390
|
+
- **`html-asset:bulma`**: Bulma's own stylesheet, with the version its URL names
|
|
391
|
+
(`bulma@0.9.4`, or none for a copy of the page's own).
|
|
392
|
+
- Under the default `--css keep` it is only reported: keep loading Bulma
|
|
393
|
+
(`import 'bulma/css/bulma.min.css'` in the entry, with that version of `bulma` installed, or the
|
|
394
|
+
CDN `<link>` in `index.html`).
|
|
395
|
+
- Under `--css bestax` the module imports `@allxsmith/bestax-bulma/bestax.css` in the link's
|
|
396
|
+
place, and under `--css bulma` it imports `bulma/css/bulma.min.css` and
|
|
397
|
+
`@allxsmith/bestax-bulma/extras.css`, the way the same import in a JSX file is retargeted, so the
|
|
398
|
+
package.json step sees the module's `bulma` import too. One import from each page module is
|
|
399
|
+
fine, since the bundler loads it once. What is left gets the TODO: a page made for Bulma 0.9, or
|
|
400
|
+
one whose URL doesn't say, moves to Bulma 1 (the docs' Bulma 0.9 to 1 guide), and under
|
|
401
|
+
`--css bestax` a page with a primary color class (`is-primary`, `has-text-primary`) changes
|
|
402
|
+
color, since `bestax.css` builds Bulma with bestax's own primary. To keep it, set the
|
|
403
|
+
`--bulma-primary-*` variables as [css-migration.md](../css-migration.md) says, or use
|
|
404
|
+
`--css bulma`. A Bulma 1 page with no primary class gets the import and no TODO. A TypeScript
|
|
405
|
+
build resolves the import through the bundler's CSS types (Vite's `vite/client`), as it does
|
|
406
|
+
every stylesheet import.
|
|
407
|
+
- No import is written in a Next.js app, whose Pages Router takes a global stylesheet only in
|
|
408
|
+
`pages/_app`, nor for a link with a media query (`media="print"`), since an import applies to
|
|
409
|
+
every medium. The TODO says where it goes instead: the root layout or `pages/_app`, or a
|
|
410
|
+
`<link>` with the same `media` in `index.html`.
|
|
411
|
+
- One of Bulma's other builds (`bulma-no-dark-mode`, `bulma-prefixed`, 0.9's `bulma-rtl`) is
|
|
412
|
+
reported in every mode, since the codemod imports only the standard one. bestax's own builds,
|
|
413
|
+
Bulma with its extras, are under `@allxsmith/bestax-bulma/versions/`.
|
|
414
|
+
- **`html-asset:font-awesome`**: Font Awesome, with the major its URL names. bestax's `Icon`
|
|
415
|
+
writes its classes (`fas fa-<name>`) and loads no font of its own, so keep loading it, from the
|
|
416
|
+
`<link>` in `index.html` or from npm: bestax-bulma's optional peer range for
|
|
417
|
+
`@fortawesome/fontawesome-free` is `^6.7.2 || ^7.0.0`, and an older one fails `npm install`
|
|
418
|
+
with `ERESOLVE`.
|
|
419
|
+
- 6 and 7: keep it as it is, or install it and import its `css/all.min.css` from the entry.
|
|
420
|
+
- 5: the CDN link keeps working, since 5 reads the classes `Icon` writes. From npm, take 6 or 7,
|
|
421
|
+
which still read 5's names.
|
|
422
|
+
- 4: its classes are `fa fa-<name>`, and `Icon` writes `fas fa-<name>`, which 4 doesn't style.
|
|
423
|
+
Install 6 or 7 with `css/all.min.css`, then either import `css/v4-shims.min.css` beside it so
|
|
424
|
+
the page's 4 names keep working, or move them to the current names (`fa-envelope-o` is
|
|
425
|
+
`envelope` with `variant="regular"`).
|
|
426
|
+
- A kit (`kit.fontawesome.com`): keep loading it from `index.html`, or install Font Awesome from
|
|
427
|
+
npm instead. A URL with no version: the same, with the v4 shims beside it if the page's names
|
|
428
|
+
are 4's (`fa fa-<name>`).
|
|
429
|
+
- **`html-asset:bulma-extension`**: a `bulma-*` package (or `@creativebulma/bulma-*`). An
|
|
430
|
+
extension's stylesheet and script are one TODO, with both lines. Where bestax has a component
|
|
431
|
+
for what it does, the TODO names it; render that in place of the extension's markup and script,
|
|
432
|
+
whose styles ship in `extras.css` and `bestax.css`, and stop loading the extension once nothing
|
|
433
|
+
the app keeps uses its classes:
|
|
434
|
+
|
|
435
|
+
| Extension | bestax |
|
|
436
|
+
| ------------------------------------------------------- | --------------------------------------------------------------- |
|
|
437
|
+
| `bulma-carousel` | `Carousel`, with a `CarouselItem` for each slide |
|
|
438
|
+
| `bulma-slider` | `Slider` |
|
|
439
|
+
| `bulma-switch` | `Switch` |
|
|
440
|
+
| `bulma-checkradio` | `Checkbox` and `Radio`, which draw their own box |
|
|
441
|
+
| `bulma-tooltip`, `@creativebulma/bulma-tooltip` | `Tooltip` |
|
|
442
|
+
| `bulma-badge`, `@creativebulma/bulma-badge` | `Badge` |
|
|
443
|
+
| `bulma-steps` | `Steps` |
|
|
444
|
+
| `bulma-timeline` | `Timeline` |
|
|
445
|
+
| `bulma-tagsinput`, `@creativebulma/bulma-tagsinput` | `Taginput` |
|
|
446
|
+
| `bulma-calendar` | `DateInput`, `TimeInput`, `DateTimeInput` and `DateRangeInput` |
|
|
447
|
+
| `bulma-accordion` | `Collapses`, with a `Collapse` for each item |
|
|
448
|
+
| `bulma-collapsible`, `@creativebulma/bulma-collapsible` | `Collapse` (`Collapses` for an accordion) |
|
|
449
|
+
| `bulma-pageloader` | `Loading`, `isFullPage` for one over the whole page |
|
|
450
|
+
| `bulma-quickview` | `Sidebar` |
|
|
451
|
+
| `bulma-toast` | `Toast`: `toast.show()` from code, with a `ToastContainer` once |
|
|
452
|
+
|
|
453
|
+
`bulma-extensions`, the bundle, holds several of these: replace the ones in the table, and keep
|
|
454
|
+
loading the bundle only for the rest. **bulma-social** has no bestax component: keep loading it,
|
|
455
|
+
since its classes (`is-twitter`, `is-github`) style Bulma's `.button`, which `Button` renders,
|
|
456
|
+
so they go on `Button` through `className`:
|
|
457
|
+
|
|
458
|
+
```tsx
|
|
459
|
+
<Button as="a" className="is-github" href="https://github.com/example">
|
|
460
|
+
<Icon name="github" variant="brands" />
|
|
461
|
+
</Button>
|
|
462
|
+
```
|
|
463
|
+
|
|
464
|
+
Any other extension: keep loading it while the page's markup uses its classes, which go on
|
|
465
|
+
bestax's components through `className`, and under `--css bestax` or `--css bulma` check it
|
|
466
|
+
works with Bulma 1, which an extension can predate.
|
|
467
|
+
|
|
468
|
+
- **`html-asset:jquery`**: jQuery itself (a plugin such as jQuery UI is `html-asset:script`).
|
|
469
|
+
React renders the page now, so what the page's scripts did with jQuery (toggling classes,
|
|
470
|
+
handlers, showing and hiding) becomes state and event props; load jQuery only if a library the
|
|
471
|
+
app keeps still needs it.
|
|
472
|
+
- **`html-asset:webfont`**: a web font's stylesheet (Google Fonts, Bunny Fonts, Adobe Fonts).
|
|
473
|
+
Keep the `<link>` in `index.html` with its preconnects, or self-host the font and import it from
|
|
474
|
+
the entry. Google's Material Icons and Material Symbols are icon fonts, which `Icon` writes with
|
|
475
|
+
`library="material-icons"` or `library="material-symbols"`; keep the link, or install the
|
|
476
|
+
`material-icons` or `material-symbols` package.
|
|
477
|
+
- **`html-asset:stylesheet`**: any other stylesheet. The page's own, beside it (in its folder or
|
|
478
|
+
one below), is imported once for the app in the order the page loads it, so its rules still win
|
|
479
|
+
over Bulma's where they did (a module beside the page imports `css/styles.css` as
|
|
480
|
+
`./css/styles.css`), or its rules move into the app's stylesheet. For one that isn't in the
|
|
481
|
+
page's folder, the TODO says only that: the page's `<base href>`, if it has one, may have loaded
|
|
482
|
+
it from somewhere else, so find the one it meant, or drop it.
|
|
483
|
+
- **`html-asset:script`**: any other script. The component runs none: load a library the app still
|
|
484
|
+
needs in `index.html` (or install it), and port what the page's own scripts did into the
|
|
485
|
+
component. A script of the page's own, beside it, is read the way an inline script is, so one
|
|
486
|
+
that toggles the burger, drives a carousel or switches the theme gets that `html-script:<pattern>`
|
|
487
|
+
TODO instead, quoting the file. One a `../` reaches outside the page's folder isn't read. A
|
|
488
|
+
`<script src>` of a type a browser loads nothing for (`text/template`, `application/json`) isn't
|
|
489
|
+
code: it gets the `html-script` TODO for data (`html-script:json-ld` for JSON-LD), naming its
|
|
490
|
+
file.
|
|
491
|
+
|
|
492
|
+
### Inline scripts: `html-script:<pattern>`
|
|
493
|
+
|
|
494
|
+
Every inline `<script>` is dropped, and its TODO gives the lines in the page where its code still
|
|
495
|
+
is. One that does something bestax has a component for gets that pattern's rule, and a script
|
|
496
|
+
can get more than one. A script of the page's own, beside it (`<script src="js/scripts.js">`), is
|
|
497
|
+
read for the burger, a carousel and a theme toggle too, and its TODO names the file:
|
|
498
|
+
|
|
499
|
+
- **`html-script:burger`** toggles the navbar burger (`.navbar-burger`, or the `.burger` class
|
|
500
|
+
Bulma 0.x's docs put beside it). Keep the open state in `useState` and pass it to
|
|
501
|
+
`Navbar.Burger` and `Navbar.Menu` (the `family:navbar-burger` TODO on the burger says why the
|
|
502
|
+
markup stays):
|
|
503
|
+
|
|
504
|
+
```tsx
|
|
505
|
+
function SiteNavbar() {
|
|
506
|
+
const [open, setOpen] = useState(false);
|
|
507
|
+
return (
|
|
508
|
+
<Navbar role="navigation" aria-label="main navigation">
|
|
509
|
+
<Navbar.Brand>
|
|
510
|
+
<Navbar.Item href="/">Home</Navbar.Item>
|
|
511
|
+
<Navbar.Burger
|
|
512
|
+
active={open}
|
|
513
|
+
onClick={() => setOpen(!open)}
|
|
514
|
+
aria-label="menu"
|
|
515
|
+
/>
|
|
516
|
+
</Navbar.Brand>
|
|
517
|
+
<Navbar.Menu active={open}>
|
|
518
|
+
<Navbar.Start>
|
|
519
|
+
<Navbar.Item href="/docs">Docs</Navbar.Item>
|
|
520
|
+
</Navbar.Start>
|
|
521
|
+
</Navbar.Menu>
|
|
522
|
+
</Navbar>
|
|
523
|
+
);
|
|
524
|
+
}
|
|
525
|
+
```
|
|
526
|
+
|
|
527
|
+
- **`html-script:modal`** opens or closes a modal. `Modal` shows while `active` is true and calls
|
|
528
|
+
`onClose` from its background, its close button and Escape, so keep the open state in
|
|
529
|
+
`useState` (the `family:modal` TODO covers rebuilding the markup).
|
|
530
|
+
- **`html-script:dismiss`** removes an element when its `.delete` is clicked. `Notification`
|
|
531
|
+
takes `hasDelete` and `onDelete`, `Tag` takes `onDelete` and `Message` takes `onClose`; render
|
|
532
|
+
the element only while it's in state.
|
|
533
|
+
- **`html-script:carousel`** drives a carousel. `Carousel` takes its slides as `CarouselItem`
|
|
534
|
+
children and renders its own arrows and indicators (`autoplay` for a timed one). Its styles ship
|
|
535
|
+
in bestax's `extras.css` and `bestax.css`, not in Bulma's stylesheet.
|
|
536
|
+
- **`html-script:theme`** switches Bulma's light and dark schemes. The toggle is `Theme`'s: it
|
|
537
|
+
writes `data-theme` on `<html>` from its `colorMode` (`light`, `dark` or `system`), so keep the
|
|
538
|
+
choice in state, save it in `localStorage`, and pass it. The first paint is `index.html`'s:
|
|
539
|
+
`Theme` writes from an effect, after the first paint, so a visitor whose saved choice differs
|
|
540
|
+
from their OS sees the OS's scheme first. A small inline script in the `<head>` of `index.html`
|
|
541
|
+
that reads the saved choice (or the OS's, with none saved) and writes `data-theme` before the
|
|
542
|
+
app loads paints the right one, and the toggle's state starts from what it wrote. The
|
|
543
|
+
bestax-theming skill covers `Theme` and `colorMode`.
|
|
544
|
+
- **`html-script:json-ld`** is structured data for search engines. Render it where the app sets
|
|
545
|
+
each page's head, as
|
|
546
|
+
`<script type="application/ld+json" dangerouslySetInnerHTML={{ __html: JSON.stringify(data) }} />`.
|
|
547
|
+
- **`html-script`**: any other inline script, or a `<script type>` that isn't code (a template,
|
|
548
|
+
JSON data). Port what it does into the component as state, effects and event handlers.
|
|
549
|
+
|
|
550
|
+
### `<html>` and `<body>`: `html-document:<name>`
|
|
551
|
+
|
|
552
|
+
The app's document has its own `<html>` and `<body>`, which a component can't reach.
|
|
553
|
+
|
|
554
|
+
- **`html-document:has-navbar-fixed-top`**, and the same for `has-navbar-fixed-bottom`,
|
|
555
|
+
`has-navbar-fixed-top-desktop`, `has-navbar-fixed-top-touch`, `has-navbar-fixed-bottom-desktop`,
|
|
556
|
+
`has-navbar-fixed-bottom-touch`, `has-spaced-navbar-fixed-top` and
|
|
557
|
+
`has-spaced-navbar-fixed-bottom` (`html-document:has-navbar-fixed-bottom` and so on): Bulma
|
|
558
|
+
pads the page for a fixed navbar from it. Put the class on the `<html>` in `index.html`, since
|
|
559
|
+
bestax's `Navbar` adds none there, whatever its `fixed` says.
|
|
560
|
+
- **`html-document:data-theme`**, **`html-document:theme-dark`**, **`html-document:theme-light`**:
|
|
561
|
+
the page's color scheme. Put it on the `<html>` in `index.html`, or render
|
|
562
|
+
`<Theme colorMode="dark">`, which writes `data-theme` on `<html>`.
|
|
563
|
+
- **`html-document:lang`**, **`html-document:dir`**: set them on the `<html>` in `index.html`.
|
|
564
|
+
- **`html-document:class`**: the page's own classes on `<html>` or `<body>`. Put them on the
|
|
565
|
+
app's own `<body>` (or `<html>`), or on an element around the page's content if the styles
|
|
566
|
+
allow it.
|
|
567
|
+
- **`html-document:id`**, **`html-document:style`**, **`html-document`**: any other attribute
|
|
568
|
+
there, which moves the same way.
|
|
569
|
+
|
|
570
|
+
### Event handlers: `html-event:<attribute>`
|
|
571
|
+
|
|
572
|
+
An `onclick="…"` and its kind, on any element or on `<body>` (`onload`). React takes a function,
|
|
573
|
+
not code in a string, so the attribute was dropped; the TODO quotes the code and names the prop
|
|
574
|
+
that takes it (`onClick`). Port the code into a handler, reading the element from the event rather
|
|
575
|
+
than `this`. A `<body onload>` becomes an effect.
|
|
576
|
+
|
|
577
|
+
### Elements: `html-element:<kind>`
|
|
578
|
+
|
|
579
|
+
- **`html-element:custom`**: a custom element (`<my-widget>`) renders as written, but the script
|
|
580
|
+
that defines it isn't loaded by the module: import its definition in the app. A TypeScript
|
|
581
|
+
build also needs the tag declared in `JSX.IntrinsicElements`.
|
|
582
|
+
- **`html-element:obsolete`**: `<center>`, `<font>`, `<marquee>` and their kind still render, but
|
|
583
|
+
React's types list few of them. Replace each with current markup (`has-text-centered` for
|
|
584
|
+
`<center>`, a class for `<font>`).
|
|
585
|
+
- **`html-element:unknown`**: a tag that isn't HTML renders as an unknown inline element, and
|
|
586
|
+
TypeScript rejects it. Replace it with the element it stands for.
|
|
587
|
+
- **`html-element:template`**: `<template>` holds markup for a script to clone. Render that
|
|
588
|
+
markup from the component where the script used it.
|
|
589
|
+
- **`html-element:name`**: a tag JSX can't write (`<o:p>`, from Word), so its children were
|
|
590
|
+
written in its place. Put back the element it stood for, if it mattered.
|
|
591
|
+
- **`html-element:conditional-comment`**: an Internet Explorer conditional comment was dropped;
|
|
592
|
+
no browser React supports reads one.
|
|
593
|
+
|
|
594
|
+
### URLs: `html-url:<kind>`
|
|
595
|
+
|
|
596
|
+
- **`html-url:javascript`**: a `javascript:` URL won't run (React 19 replaces it with one that
|
|
597
|
+
throws, and React 18 warns). Move the code into an `onClick` handler.
|
|
598
|
+
- **`html-url:relative`**: `img/logo.png` resolved against the page's folder, and in the app it
|
|
599
|
+
resolves against the address the component renders at. The file is there beside the page, so
|
|
600
|
+
copy it into the app's `public/` folder and point at it from the site root (`/img/logo.png`), or
|
|
601
|
+
import it. A link to another page beside this one should point at the route that page becomes.
|
|
602
|
+
Each relative URL in a `srcset` is its own entry, quoted as itself (`` `hero@2x.png` in `srcset` ``).
|
|
603
|
+
Several of these share one TODO line, and each is its own report entry.
|
|
604
|
+
- **`html-url:missing`**: a relative URL whose target isn't beside the page, read the way the
|
|
605
|
+
browser read it, so it was a dead link or a missing file already. Point it somewhere real, or
|
|
606
|
+
drop it.
|
|
607
|
+
|
|
608
|
+
### Attributes: `html-attr:<kind>`
|
|
609
|
+
|
|
610
|
+
- **`html-attr:name`**: an attribute JSX can't write (`@click`, `:class`, `x-on:click`), or one the
|
|
611
|
+
element already had under another spelling, was left out. A framework's directive is code to port
|
|
612
|
+
into the component.
|
|
613
|
+
- **`html-attr:unknown`**: an attribute React has no prop for by that name, written as it was.
|
|
614
|
+
React renders it. Whether a TypeScript build takes it depends on the element (React's types
|
|
615
|
+
list `valign` on a `<td>` and not on a `<th>`), so the TODO doesn't say; what to do depends on
|
|
616
|
+
the attribute, and the TODO says which:
|
|
617
|
+
- React's own prop in the wrong case (`defaultvalue`, `defaultchecked`), which the page never
|
|
618
|
+
read since it isn't HTML: rename it to the prop (`defaultValue`), or drop it if it isn't
|
|
619
|
+
meant.
|
|
620
|
+
- An obsolete presentational attribute (`valign`, `bgcolor`, `nowrap`), which CSS replaced:
|
|
621
|
+
write it as CSS or a class.
|
|
622
|
+
- Anything else: drop it if nothing reads it, make it a `data-` attribute if a script of the
|
|
623
|
+
page's reads it, and if React's types don't list it on that element, declare it for a
|
|
624
|
+
TypeScript build.
|
|
625
|
+
- **`html-attr:style`**: a `style` declaration a browser can't read (`*zoom: 1`) was left out, as a
|
|
626
|
+
browser leaves it out. Delete it, or rewrite it if it meant something.
|
|
627
|
+
- **`html-attr:important`**: React sets a style without a priority, so the declaration is written
|
|
628
|
+
without its `!important`. If a stylesheet rule beats it now, move it into a class in the app's
|
|
629
|
+
stylesheet.
|
|
630
|
+
|
|
631
|
+
### Parse errors: `html-parse:<code>`
|
|
632
|
+
|
|
633
|
+
The HTML has an error the browser repaired (`html-parse:duplicate-attribute`,
|
|
634
|
+
`html-parse:end-tag-without-matching-open-element`), reported once for each kind, with how many
|
|
635
|
+
more there are. The module follows the DOM the browser builds from it, which may not be what the
|
|
636
|
+
markup meant, so check that part of the page. A code too long for a rule id is reported as the bare
|
|
637
|
+
`html-parse`.
|
|
638
|
+
|
|
639
|
+
### The page itself: `html-file:<case>`
|
|
640
|
+
|
|
641
|
+
- **`html-file:exists`**: the module beside the page is already there, and the codemod never
|
|
642
|
+
writes over a file. That makes a second run change nothing. Move or delete the module to convert
|
|
643
|
+
the page again.
|
|
644
|
+
- **`html-file:not-included`**: a folder walk found the page, and it has Bulma classes, but a walk
|
|
645
|
+
takes a page only when `--extensions` lists its extension, since most `.html` files in a React
|
|
646
|
+
project aren't pages to convert (Vite's `index.html`, `public/`). `-e` matches an extension
|
|
647
|
+
exactly, as it does for every file, so `-e html` takes no `.htm` page; the TODO names the one
|
|
648
|
+
the page needs. Name the page, or add its extension to `--extensions` (`-e html,htm` for both).
|
|
649
|
+
- **`html-file:template-syntax`**: the page is a server template (`{{`, `{%`, `<?php`, `<%`), which
|
|
650
|
+
isn't HTML a browser reads as written. Convert the HTML it renders, or the template by hand.
|
|
651
|
+
|
|
652
|
+
A page with no Bulma component class writes nothing and reports nothing.
|
|
653
|
+
|
|
341
654
|
## Things that get no TODO
|
|
342
655
|
|
|
343
656
|
- Helper classes on a `<div>` (`<div className="is-flex mt-4">`): bestax has no plain `<div>`
|
|
@@ -26,7 +26,11 @@ choice below applies.
|
|
|
26
26
|
**Visual note**: `bestax.css` ships with `$primary` set to bestax blue (`#1e6b99`),
|
|
27
27
|
not Bulma's stock turquoise — `is-primary` surfaces (hero, navbar, buttons) change
|
|
28
28
|
color. Keep the stock Bulma look with `--css bulma`, or set your own brand color via
|
|
29
|
-
`--bulma-primary-*` CSS variables / a Sass build.
|
|
29
|
+
`--bulma-primary-*` CSS variables / a Sass build. Set `--bulma-primary-invert-l` along with
|
|
30
|
+
`--bulma-primary-h`, `--bulma-primary-s` and `--bulma-primary-l`: it is the lightness of the
|
|
31
|
+
text on a primary surface, and bestax's build fixes it for its dark blue, so a light primary set
|
|
32
|
+
through the other three alone keeps white labels. To get stock Bulma's turquoise back on top of
|
|
33
|
+
`bestax.css`, copy those four from Bulma's own `bulma/css/bulma.css`.
|
|
30
34
|
|
|
31
35
|
- **SCSS files**: Bulma 0.9's `@import 'bulma/bulma.sass'` (plus preceding
|
|
32
36
|
`$var: value !default;` overrides) became Bulma v1 module syntax, with simple literal
|
|
@@ -183,10 +183,10 @@ An existing `ref` is passed through untouched — which is safe only where the b
|
|
|
183
183
|
one. rbx forwards a ref on every component; bestax does so on the form controls, plus `Avatar`,
|
|
184
184
|
`Button`, `Carousel`, `CarouselItem`, `Dialog`, `Dropdown`, `EmptyState`, `Kbd`, `Kbd.Group`,
|
|
185
185
|
`Link`, `LinkButton`, `Loader`, `Menu.Item`, `Modal`, `Navbar`, `Navbar.Burger`, `Navbar.Dropdown`,
|
|
186
|
-
`Navbar.Item`, `Navbar.Link`, `SegmentedControl`, `SegmentedControl.Segment`, `Sidebar`, `
|
|
187
|
-
`ToggleButton`. "The form controls" there
|
|
188
|
-
`Field.Body`, `Checkboxes` and `Radios`
|
|
189
|
-
target this codemod emits.
|
|
186
|
+
`Navbar.Item`, `Navbar.Link`, `SegmentedControl`, `SegmentedControl.Segment`, `Sidebar`, `Timeline`,
|
|
187
|
+
`Timeline.Item`, `Toast`, `ToggleButton`, `TreeView` and `TreeView.Item`. "The form controls" there
|
|
188
|
+
means the inputs themselves: the `Field`, `Field.Label`, `Field.Body`, `Checkboxes` and `Radios`
|
|
189
|
+
wrappers around them forward nothing, and `Field` is a target this codemod emits.
|
|
190
190
|
|
|
191
191
|
Carry a `ref` onto anything else — `Card`, `Box`, `Section`, `Message`, `Tabs` and most of the
|
|
192
192
|
catalogue — and it is unsupported, but the two React majors fail differently. React 18 drops
|
|
@@ -166,10 +166,10 @@ bestax components don't take `domRef`, but many forward a plain `ref` — the fo
|
|
|
166
166
|
`Avatar`, `Button`, `Carousel`, `CarouselItem`, `Dialog`, `Dropdown`, `EmptyState`, `Kbd`,
|
|
167
167
|
`Kbd.Group`, `Link`, `LinkButton`, `Loader`, `Menu.Item`, `Modal`, `Navbar`, `Navbar.Burger`,
|
|
168
168
|
`Navbar.Dropdown`, `Navbar.Item`, `Navbar.Link`, `SegmentedControl`, `SegmentedControl.Segment`,
|
|
169
|
-
`Sidebar`, `
|
|
170
|
-
restructure the markup. "The form controls"
|
|
171
|
-
`Field.Body`, `Checkboxes` and `Radios`
|
|
172
|
-
target this codemod emits.
|
|
169
|
+
`Sidebar`, `Timeline`, `Timeline.Item`, `Toast`, `ToggleButton`, `TreeView` and `TreeView.Item`. On
|
|
170
|
+
those, rename `domRef` to `ref` and it works; do not restructure the markup. "The form controls"
|
|
171
|
+
means the inputs themselves: the `Field`, `Field.Label`, `Field.Body`, `Checkboxes` and `Radios`
|
|
172
|
+
wrappers around them forward nothing, and `Field` is a target this codemod emits.
|
|
173
173
|
|
|
174
174
|
Everywhere else the rename is not enough, and the two React majors differ: React 18 drops the
|
|
175
175
|
ref and logs "Function components cannot be given refs", while React 19 passes it through as
|