create-bestax 4.2.18 → 4.2.19
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.d.ts.map +1 -1
- package/dist/constants.js +4 -1
- package/dist/file-system.d.ts +5 -1
- package/dist/file-system.d.ts.map +1 -1
- package/dist/file-system.js +11 -1
- package/dist/library-range.d.ts +16 -0
- package/dist/library-range.d.ts.map +1 -0
- package/dist/library-range.js +40 -0
- package/dist/project-creator.d.ts.map +1 -1
- package/dist/project-creator.js +4 -1
- package/package.json +7 -7
- package/templates/skills/bestax-custom-component/references/component-catalog.md +3 -1
- package/templates/skills/bestax-form/SKILL.md +40 -15
- package/templates/skills/bestax-form/references/api.md +10 -8
- package/templates/skills/bestax-form/references/patterns.md +68 -0
- package/templates/skills/bestax-layout-scaffold/SKILL.md +16 -5
- package/templates/skills/bestax-layout-scaffold/references/archetypes.md +2 -2
- package/templates/skills/bestax-layout-scaffold/references/layout-components.md +52 -5
- package/templates/skills/bestax-migrate/SKILL.md +11 -3
- package/templates/skills/bestax-migrate/references/bloomer/component-map.md +1 -1
- package/templates/skills/bestax-migrate/references/bloomer/prop-map.md +8 -5
- package/templates/skills/bestax-migrate/references/bulma-classes/component-map.md +144 -101
- package/templates/skills/bestax-migrate/references/bulma-classes/prop-map.md +47 -16
- package/templates/skills/bestax-migrate/references/bulma-classes/unmappables.md +217 -45
- package/templates/skills/bestax-migrate/references/css-migration.md +12 -5
- package/templates/skills/bestax-migrate/references/rbx/prop-map.md +19 -13
- package/templates/skills/bestax-migrate/references/react-bulma-components/prop-map.md +27 -22
- package/templates/skills/bestax-migrate/references/react-bulma-components/unmappables.md +1 -1
- package/templates/skills/bestax-optimize/references/modular-build.md +57 -17
- package/templates/skills/bestax-theming/SKILL.md +19 -8
- package/templates/skills/bestax-theming/examples/dark-mode.tsx +99 -17
- package/templates/skills/bestax-theming/examples/theme-config.tsx +13 -8
- package/templates/skills/bestax-theming/references/css-variables.md +188 -18
- package/templates/skills/bestax-theming/references/themeable-components.md +2 -0
- package/templates/vite/package.json +1 -1
- package/templates/vite/src/main.jsx +1 -1
- package/templates/vite-ts/package.json +1 -1
- package/templates/vite-ts/src/main.tsx +1 -1
|
@@ -72,7 +72,9 @@ Sizes are `1` to `12`, `full`, `half`, `one-third`, `two-thirds`, `one-quarter`,
|
|
|
72
72
|
|
|
73
73
|
bestax picks the heading from `size` (`size="3"` renders an `<h3>`) unless `as="p"`. So on an
|
|
74
74
|
`<h2>`, `is-4` stays a class and the element becomes `<Title as="h2" className="is-4">`, which
|
|
75
|
-
renders the same `<h2>`.
|
|
75
|
+
renders the same `<h2>`. To write it as a prop, `textSize="4"` keeps the `<h2>` and sizes it the
|
|
76
|
+
same: it renders Bulma's `is-size-4`, which has the font size `is-4` gives a title or subtitle,
|
|
77
|
+
and as a Bulma helper it is `!important`, so check a title the page's own CSS sizes.
|
|
76
78
|
|
|
77
79
|
### Other components
|
|
78
80
|
|
|
@@ -85,6 +87,8 @@ renders the same `<h2>`.
|
|
|
85
87
|
| `.content` → `Content` | `is-small`, `is-medium`, `is-large` | `size` |
|
|
86
88
|
| `.delete` → `Delete` | `is-small`, `is-medium`, `is-large` | `size` |
|
|
87
89
|
| `.field` → `Field` | `is-horizontal`, `is-grouped`, `has-addons`, `is-narrow` | `horizontal`, `grouped`, `hasAddons`, `narrow` |
|
|
90
|
+
| `.field` → `Field` | `has-addons-centered`, `has-addons-right`, beside `has-addons` | `hasAddons="centered"`, `hasAddons="right"`, which render both classes |
|
|
91
|
+
| `.field` → `Field` | `is-grouped-centered`, `is-grouped-right`, `is-grouped-multiline`, beside `is-grouped` | `grouped="centered"`, `grouped="right"`, `grouped="multiline"`, which render both classes |
|
|
88
92
|
| `.grid` → `Grid` | `is-gap-{step}`, `is-column-gap-{step}`, `is-row-gap-{step}`, `0` to `8` in half steps (`is-gap-1.5`) | `gap`, `columnGap`, `rowGap` |
|
|
89
93
|
| `.grid` → `Grid` | `is-col-min-{1-32}` | `minCol` (a number: `minCol={8}`) |
|
|
90
94
|
| `.fixed-grid` → `Grid isFixed` (folded) | `has-{1-12}-cols`, `has-{1-12}-cols-{viewport}`, `has-auto-count` | `fixedCols`, `fixedCols{Viewport}` (numbers: `fixedCols={3}`), `fixedCols="auto"` |
|
|
@@ -103,7 +107,8 @@ renders the same `<h2>`.
|
|
|
103
107
|
| the `<select>` inside `.select` | `is-hovered`, `is-focused` | `isHovered`, `isFocused` |
|
|
104
108
|
| `.hero` → `Hero` | `is-primary`, `is-link`, `is-info`, `is-success`, `is-warning`, `is-danger`, `is-black`, `is-white`, `is-light`, `is-dark` | `color` |
|
|
105
109
|
| `.hero` → `Hero` | `is-small`, `is-medium`, `is-large`, `is-fullheight`, `is-fullheight-with-navbar` | `size` |
|
|
106
|
-
| `.image` → `Image` | `is-16x16`, `is-24x24`, `is-32x32`, `is-48x48`, `is-64x64`, `is-96x96`, `is-128x128`, `is-square` | `size`
|
|
110
|
+
| `.image` → `Image` | `is-16x16`, `is-24x24`, `is-32x32`, `is-48x48`, `is-64x64`, `is-96x96`, `is-128x128`, `is-square` | `size` |
|
|
111
|
+
| `.image` → `Image` | `is-{ratio}`, for each of the Ratios under Helper classes (`is-16by9`), but not `is-square` (see below) | `size`, on the `<figure>` it renders with no `as` (see below) |
|
|
107
112
|
| the `<img>` inside `.image` | `is-rounded` | `isRounded` |
|
|
108
113
|
| `.icon` → `Icon` | `is-small`, `is-medium`, `is-large` | `size` |
|
|
109
114
|
| `.tabs` → `Tabs` | `is-centered`, `is-right`, `is-left` | `align` |
|
|
@@ -116,7 +121,7 @@ renders the same `<h2>`.
|
|
|
116
121
|
| `.level` → `Level` | `is-mobile` | `isMobile` |
|
|
117
122
|
| `.navbar` → `Navbar` | the ten `.hero` colors | `color` |
|
|
118
123
|
| `.navbar` → `Navbar` | `is-fixed-top`, `is-fixed-bottom` | `fixed` (`top`, `bottom`) |
|
|
119
|
-
| `.navbar` → `Navbar` | `is-transparent`
|
|
124
|
+
| `.navbar` → `Navbar` | `is-transparent`, `is-spaced`, `has-shadow` | `transparent`, `isSpaced`, `hasShadow` |
|
|
120
125
|
| `.navbar-menu` → `Navbar.Menu`, `.navbar-item` → `Navbar.Item` | `is-active` | `active` |
|
|
121
126
|
| `.navbar-dropdown` → `Navbar.DropdownMenu` | `is-right`, `is-up` | `right`, `up` |
|
|
122
127
|
| `.notification` → `Notification` | `is-primary`, `is-link`, `is-info`, `is-success`, `is-warning`, `is-danger`, `is-black`, `is-white`, `is-dark` | `color` |
|
|
@@ -130,6 +135,16 @@ renders the same `<h2>`.
|
|
|
130
135
|
| `.tag` → `Tag` | `is-light`, `is-rounded`, `is-hoverable` | `isLight`, `isRounded`, `isHoverable` |
|
|
131
136
|
| `.tag` → `Tag` | `is-medium`, `is-large` | `size` |
|
|
132
137
|
|
|
138
|
+
`is-square` sits with the fixed sizes, not the ratios. Bulma sizes it like `is-1by1`, but `Image`
|
|
139
|
+
renders `size="square"` on a `<div>`, as it does a fixed size. So
|
|
140
|
+
`<figure className="image is-square">` becomes `<Image as="figure" size="square">`, while
|
|
141
|
+
`<figure className="image is-1by1">` becomes `<Image size="1by1">`.
|
|
142
|
+
|
|
143
|
+
A ratio converts to identical markup only on a bestax-bulma whose `Image` writes nothing but the
|
|
144
|
+
ratio class on its container. An older one also writes `has-ratio` there, which Bulma reads only
|
|
145
|
+
on a child, so the page looks the same, unless that `.image` sits inside another ratio `.image`,
|
|
146
|
+
which then stretches it to fill. Upgrade bestax-bulma, or keep that ratio as a class.
|
|
147
|
+
|
|
133
148
|
`Progress` takes `value` and `max` as numbers: `value="40"` becomes `value={40}`. An
|
|
134
149
|
expression (`value={percent}`) carries over as written, so if it holds a string the migrated
|
|
135
150
|
file fails to typecheck while still rendering the same; wrap it in `Number(…)`. `Delete`
|
|
@@ -137,14 +152,14 @@ converts only with `type` and `aria-label` set (see `defaults:<Target>` in the u
|
|
|
137
152
|
and a `type="button"` is dropped, since bestax renders it by itself. `Card.Header.Icon` likewise
|
|
138
153
|
converts only with an `aria-label` and a `type` of `button`, `submit` or `reset`, since it renders
|
|
139
154
|
`aria-label="more options"` and `type="button"` otherwise.
|
|
140
|
-
`.tag`'s `is-delete` stays a class: `isDelete` turns the tag into a `<button>`.
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
`
|
|
144
|
-
`grouped` values that render them render
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
155
|
+
`.tag`'s `is-delete` stays a class: `isDelete` turns the tag into a `<button>`. A
|
|
156
|
+
`.navbar-item`'s `has-dropdown` and `is-hoverable` stay classes too, since bestax has no prop for
|
|
157
|
+
them on that component. So do a `.field`'s `has-addons-centered`, `has-addons-right` and
|
|
158
|
+
`is-grouped-*` without `has-addons` or `is-grouped` beside them, because the `hasAddons` and
|
|
159
|
+
`grouped` values that render them render those as well, and an input's, textarea's or select's
|
|
160
|
+
color, because `color` renders `has-text-<color>` on it too. On a `.columns`, the gap helpers
|
|
161
|
+
(`is-gap-*`, `is-column-gap-*`, `is-row-gap-*`) stay classes as well: `Columns`' own `gap` is its
|
|
162
|
+
gutter (`is-<step>`), and it leaves the column and row gap helpers out.
|
|
148
163
|
|
|
149
164
|
## Helper classes
|
|
150
165
|
|
|
@@ -152,7 +167,10 @@ These convert on every component above and on the plain-tag wrappers.
|
|
|
152
167
|
|
|
153
168
|
Colors are `primary`, `link`, `info`, `success`, `warning`, `danger`, `black`, `black-bis`,
|
|
154
169
|
`black-ter`, `grey-darker`, `grey-dark`, `grey`, `grey-light`, `grey-lighter`, `white`,
|
|
155
|
-
`white-bis`, `white-ter`, `light`, `dark`, `inherit` and `current`.
|
|
170
|
+
`white-bis`, `white-ter`, `light`, `dark`, `inherit` and `current`. Shades are `00` to `95` in
|
|
171
|
+
steps of five, `invert`, `light`, `dark`, `soft`, `bold` and `on-scheme`, on the colors Bulma
|
|
172
|
+
shades: `primary`, `link`, `info`, `success`, `warning`, `danger`, `black`, `white`, `light` and
|
|
173
|
+
`dark`. Gap steps are `0` to `8` in
|
|
156
174
|
half steps (`0`, `0.5`, `1`, … `7.5`, `8`). Overflow values are `auto`, `clip`, `hidden`, `scroll`
|
|
157
175
|
and `visible`. Ratios are `1by1`, `5by4`, `4by3`, `3by2`, `5by3`, `16by9`, `2by1`, `3by1`,
|
|
158
176
|
`4by5`, `3by4`, `2by3`, `3by5`, `9by16`, `1by2` and `1by3`.
|
|
@@ -161,8 +179,10 @@ and `visible`. Ratios are `1by1`, `5by4`, `4by3`, `3by2`, `5by3`, `16by9`, `2by1
|
|
|
161
179
|
| --------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------- |
|
|
162
180
|
| `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` |
|
|
163
181
|
| `p-{n}`, `pt-{n}`, `pr-{n}`, `pb-{n}`, `pl-{n}`, `px-{n}`, `py-{n}` | `p`, `pt`, `pr`, `pb`, `pl`, `px`, `py` |
|
|
182
|
+
| `is-marginless`, `is-paddingless` (Bulma 0.9's, which v1 removed) | `m="0"`, `p="0"`, which render v1's `m-0` and `p-0` |
|
|
164
183
|
| `has-text-{color}` | `textColor` (on `Menu`, `Menu.Label`, `Menu.List` and `Table`, `color`) |
|
|
165
184
|
| `has-background-{color}` | `bgColor` (on `Menu`, `Menu.Label`, `Menu.List`, `Tag`, `File`, `InputBase`, `TextAreaBase` and `SelectBase`, `backgroundColor`) |
|
|
185
|
+
| `has-text-{color}-{shade}`, `has-background-{color}-{shade}` | the same color prop, with `colorShade` or `backgroundColorShade` (`textColor="primary" colorShade="on-scheme"`) |
|
|
166
186
|
| `is-size-1` … `is-size-7`, and `-{viewport}` | `textSize`, `textSize{Viewport}` |
|
|
167
187
|
| `has-text-centered`, `-justified`, `-left`, `-right`, and `-{viewport}` | `textAlign`, `textAlign{Viewport}` |
|
|
168
188
|
| `is-capitalized`, `is-lowercase`, `is-uppercase`, `is-italic` | `textTransform` |
|
|
@@ -221,10 +241,21 @@ Some classes stay put because of how bestax renders them:
|
|
|
221
241
|
instead of as its own class.
|
|
222
242
|
- `is-hidden` becomes `visibility="hidden"`, which renders the same class and doesn't interact
|
|
223
243
|
with `display`.
|
|
244
|
+
- `is-marginless` and `is-paddingless` are the only classes a conversion changes: they style
|
|
245
|
+
nothing under v1, so they become the prop of the v1 helper that does their job. A live class
|
|
246
|
+
for the same prop keeps it, whichever is written first, so beside `p-2` the class stays with a
|
|
247
|
+
`legacy:` TODO, and so it does wherever the element stays markup. Beside a class for another
|
|
248
|
+
prop, such as `px-2`, it still converts: v1 puts every side and axis class after `p-0`, so
|
|
249
|
+
`px-2` keeps its sides.
|
|
224
250
|
|
|
225
251
|
## Classes that stay classes
|
|
226
252
|
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
`is-
|
|
253
|
+
A color shade one color and one shade can't write (`has-text-primary-100`, the `-invert` of a
|
|
254
|
+
shade such as `has-text-primary-30-invert`, a shade of the `text` color), a shade or color for a
|
|
255
|
+
prop another class already wrote (`has-text-primary-30 has-text-info-40` keeps the second), the
|
|
256
|
+
palettes and `is-bold` and `is-soft`, the `-touch` and `-only` breakpoints of text size and
|
|
257
|
+
alignment, Grid and `.image` modifiers away from their own element, v1's `marginless` and
|
|
258
|
+
`paddingless` (the rules of `m-0` and `p-0` under other names), and the Bulma helpers bestax has
|
|
259
|
+
no prop for (`is-display-*`, `is-visibility-*`, `is-float-*`, `is-clear-*`, …) stay in
|
|
260
|
+
`className`. They render exactly as before. An `.image` size or ratio away from its `.image` also
|
|
261
|
+
gets a `modifier:image` TODO, since Bulma styles it only there.
|
|
@@ -92,7 +92,29 @@ give the `<nav>` both, with your own label if you like. `Breadcrumb` renders
|
|
|
92
92
|
makes one named by `aria-label` or `aria-labelledby` an image, with `role="img"`. Give a decorative
|
|
93
93
|
`.icon` `aria-hidden="true"`, and a meaningful one an `aria-label` that says what it means and
|
|
94
94
|
`role="img"`. One whose name is an expression may render with no name, so it needs a `role` of its
|
|
95
|
-
own.
|
|
95
|
+
own. `Icon` writes `aria-hidden` on the `.icon` and never on the `<i>` inside. Font Awesome's own
|
|
96
|
+
markup, `<i class="fas fa-envelope" aria-hidden="true">` alone in a `.icon` that carries
|
|
97
|
+
nothing but its classes, an `id`, a `style` and `data-` attributes, converts anyway, with the
|
|
98
|
+
attribute moved up onto the `.icon`, an exception to identical markup. A `.icon` that
|
|
99
|
+
carries anything more never takes the move. A `role` or `tabIndex` written out converts around
|
|
100
|
+
the `<i>` as it is, since `Icon` then hides nothing itself. Anything else, or either of those as
|
|
101
|
+
an expression, keeps the `.icon` as markup: a `title` or a description would be hidden with it,
|
|
102
|
+
and beside a `role` or `tabIndex` `Icon` writes no `aria-hidden` at all. Give a meaningful one an
|
|
103
|
+
`aria-label` and `role="img"`, or drop the attribute from a decorative one, then re-run. An `<i>`
|
|
104
|
+
that carries it beside something else,
|
|
105
|
+
an `id` say, keeps its `.icon` as markup too: the `.icon` holds nothing else, so the attribute
|
|
106
|
+
hides the same glyph on the `.icon`. Move it up and re-run, and the `.icon` converts around the
|
|
107
|
+
`<i>`. An icon in a link or
|
|
108
|
+
button that its `aria-label` or its text names is decoration there, so give it
|
|
109
|
+
`aria-hidden="true"`. One that is all a link or button shows names nothing a screen reader can
|
|
110
|
+
read: give the link or button an `aria-label` that says what it does, then hide the icon. The
|
|
111
|
+
`<svg class="svg-inline--fa">` Font Awesome's script draws in place of an `<i>` converts as
|
|
112
|
+
`Icon`'s children once its `.icon` is hidden, or write `Icon` with the glyph's `name` in its place,
|
|
113
|
+
which renders the `<i>` the script draws from. Inside a `.control` with `has-icons-left` or
|
|
114
|
+
`has-icons-right`, a hidden `.icon` can go instead, as that `Control`'s `iconLeft` or
|
|
115
|
+
`iconRight` (`iconLeft={{ library: "fa", name: "envelope", size: "small" }}`), which renders it
|
|
116
|
+
after the `Control`'s children. Each TODO says which of these applies, and what the icon converts
|
|
117
|
+
to.
|
|
96
118
|
`Pagination` renders Bulma's own `role="navigation"` and `aria-label="pagination"`, and
|
|
97
119
|
`Pagination.Previous`, `Pagination.Next` and `Pagination.Link` render `tabIndex={0}`, so give each
|
|
98
120
|
element the attribute it's missing.
|
|
@@ -151,6 +173,32 @@ or when what's inside is an expression or text, since `Image` renders an `<img>`
|
|
|
151
173
|
its children come out empty. Keep it as markup, or write the `Image` by hand if the expression
|
|
152
174
|
never is.
|
|
153
175
|
|
|
176
|
+
A `<label>` beside the `<select>` in a `.select` (a visually hidden one, say) is that case too,
|
|
177
|
+
since `SelectBase` renders no label. bestax's convenience `Select` takes it: the label's text as
|
|
178
|
+
`label` and its classes in `labelProps`, and it points the label at the `<select>`'s `id` itself.
|
|
179
|
+
A computed `className` on the label goes in `labelProps` as the same expression, since it may be
|
|
180
|
+
what hides the label, and so does what a spread on it carries. `Select` renders the `.select`
|
|
181
|
+
inside a `Field` and a `Control`, so convert the two by hand and check the layout:
|
|
182
|
+
|
|
183
|
+
```tsx
|
|
184
|
+
<Select
|
|
185
|
+
id="language"
|
|
186
|
+
size="small"
|
|
187
|
+
label="Select language"
|
|
188
|
+
labelProps={{ className: 'is-sr-only' }}
|
|
189
|
+
>
|
|
190
|
+
<option>English</option>
|
|
191
|
+
<option>French</option>
|
|
192
|
+
</Select>
|
|
193
|
+
```
|
|
194
|
+
|
|
195
|
+
That holds only where the `.select` isn't inside a `.field` or a `.control` (or a `Field` or
|
|
196
|
+
`Control`). Inside a `Field`, `Select` renders no label of its own and drops `label` and
|
|
197
|
+
`labelProps`, so the select would lose its name; inside a bare `Control`, it puts its label's
|
|
198
|
+
`.field` inside the `.control`. There, keep the label the page's: move the `<label>` out beside
|
|
199
|
+
the `.select`, its `htmlFor` on the `<select>`'s `id`, or give the `<select>` an `aria-label` in
|
|
200
|
+
its place, then re-run, and the `.select` converts to `SelectBase`.
|
|
201
|
+
|
|
154
202
|
A menu item is the same from the `<li>`'s side: `Menu.Item` renders the `<a>` inside it, and a
|
|
155
203
|
`Menu.List` after that, so an item converts only when its `<li>` holds one `<a>` and at most one
|
|
156
204
|
`<ul>` after it, with nothing else beside them. Text or a comment beside the `<a>` keeps it as
|
|
@@ -164,13 +212,14 @@ element converts only holding exactly that (`…` or the character), and cl
|
|
|
164
212
|
|
|
165
213
|
On an `.icon-text`, `IconText` builds its icons from props and wraps each text in a `<span>` of
|
|
166
214
|
its own, so it converts only when its children are `.icon`s, each followed by at most one bare
|
|
167
|
-
`<span>` of static text. Each `.icon` has to convert to `Icon` on its own, so one with
|
|
168
|
-
`aria-label` gets a `defaults:Icon` TODO of its own first:
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
it
|
|
173
|
-
`
|
|
215
|
+
`<span>` of static text. Each `.icon` has to convert to `Icon` on its own, so one with neither
|
|
216
|
+
`aria-hidden` nor `aria-label` gets a `defaults:Icon` TODO of its own first: hide a decorative one,
|
|
217
|
+
or give a meaningful one a name, then re-run. Its `<i>` has to be empty, carry nothing but Font
|
|
218
|
+
Awesome's own `aria-hidden`, which moves up as it does on a `.icon` alone, and name one Font
|
|
219
|
+
Awesome or Material Design Icons glyph, so another attribute on the `<i>`, another icon font, or
|
|
220
|
+
anything between the children keeps it as markup, and the `.icon`s inside convert on their own. The markup renders the same as it is; to use
|
|
221
|
+
`IconText` anyway, write it by hand with `iconProps={{ name: ... }}` (the `bestax-icons` skill
|
|
222
|
+
covers `Icon`'s library and name props).
|
|
174
223
|
|
|
175
224
|
On a `.file`, `File` renders the whole tree from props, so it converts only when its tree is the one
|
|
176
225
|
`File` renders: one bare `.file-label` `<label>` holding a `.file-input` `<input type="file">`, a
|
|
@@ -286,6 +335,25 @@ in a menu item gets this TODO too. For the `<a>`, a condition on `is-active` is
|
|
|
286
335
|
also writes `aria-current="page"` while `on` holds. Pass an `aria-current` of your own if the item
|
|
287
336
|
marks something other than the current page.
|
|
288
337
|
|
|
338
|
+
## An element it converted: `second-component:<Target>`
|
|
339
|
+
|
|
340
|
+
The element carried a second Bulma component class (`<div className="columns box">`), and an
|
|
341
|
+
element converts to one component. It became the one whose component fits its tag best (the
|
|
342
|
+
tag it renders with the element's classes and no `as`, such as the `<figure>` an `.image`
|
|
343
|
+
ratio picks, then one it reaches through `as`), the layout one or a component's part between
|
|
344
|
+
equals, and the other class stayed in `className`, which renders the same. The TODO names the component that class belongs to. A raw component
|
|
345
|
+
class on a bestax component is what the ESLint plugin's `no-bulma-component-class` reports, so
|
|
346
|
+
move it to a component of its own:
|
|
347
|
+
|
|
348
|
+
- **Most classes**: give `<Target>` an element of its own, around the converted one or inside
|
|
349
|
+
it, and drop the class: `<Box><Columns>…</Columns></Box>`. Two elements space differently
|
|
350
|
+
from one (a `.columns` has negative side margins, which a `.box` on the same element shares
|
|
351
|
+
and one around it doesn't), so check the layout.
|
|
352
|
+
- **`second-component:Container`**: where `.container` is only there to center the element, as
|
|
353
|
+
it often is on a sized `.image`, write `mx="auto"` in its place
|
|
354
|
+
(`<Image size="128x128" mx="auto">`), which centers it and does nothing else `.container`
|
|
355
|
+
does. Otherwise wrap the element in a `Container`. Either way, check the layout.
|
|
356
|
+
|
|
289
357
|
## A family it leaves as markup: `family:<class>`
|
|
290
358
|
|
|
291
359
|
The bestax component renders parts of its own, or adds attributes, so a one-element-at-a-time
|
|
@@ -320,9 +388,9 @@ in the browser:
|
|
|
320
388
|
- **`family:message`**: `Message` always wraps its children in `.message-body`.
|
|
321
389
|
- **`family:panel-icon`**: `Panel.Icon` renders through `Icon`, which always writes an
|
|
322
390
|
`aria-label`, so write `<Panel.Icon>` by hand with the `<i>` inside. The rest of a panel converts,
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
391
|
+
a `<label>` or `<div>` `.panel-block` included, as `Panel.Block` with `as` and its contents as
|
|
392
|
+
written. `Panel.CheckboxBlock`, `Panel.InputBlock` and `Panel.ButtonBlock` build the usual
|
|
393
|
+
checkbox, search and button blocks from props, if you would rather write those by hand.
|
|
326
394
|
|
|
327
395
|
## A class Bulma v1 removed: `legacy:<class>`
|
|
328
396
|
|
|
@@ -330,6 +398,24 @@ in the browser:
|
|
|
330
398
|
0.9 to 1 guide shows the translation. Until then the element has no styles at all under
|
|
331
399
|
Bulma v1.
|
|
332
400
|
|
|
401
|
+
`legacy:is-marginless`, `legacy:is-paddingless`: v1 removed both, so they style nothing.
|
|
402
|
+
Wherever the element converts, the codemod writes them as `m="0"` and `p="0"`, which render
|
|
403
|
+
v1's `m-0` and `p-0`, and says nothing. The TODO comes only where the class stays: on an
|
|
404
|
+
element that stays markup (a `<div>` with no component class, or one refused for another
|
|
405
|
+
reason), or beside a class for the same prop (`p-2`, before it or after), which keeps the prop
|
|
406
|
+
since it's what the page renders today. Write `m-0` or `p-0` in its place, or drop it if the
|
|
407
|
+
spacing it once removed no longer matters.
|
|
408
|
+
|
|
409
|
+
## A class that styles nothing where it is: `modifier:<root>`
|
|
410
|
+
|
|
411
|
+
`modifier:image`: an `.image` size or ratio (`is-64x64`, `is-square`, `is-4by3`) on an element
|
|
412
|
+
without `.image`. Bulma styles them only on the element that carries `.image`, so this one
|
|
413
|
+
sizes nothing, unless the project's own CSS gives the class a rule. If the element is the
|
|
414
|
+
image's box, add `image`. On a tag `Image` renders (the component map's `.image` row lists
|
|
415
|
+
them), re-run and it can convert; on any other tag it stays markup, and the TODO says so.
|
|
416
|
+
Otherwise drop the class. A computed `className` the codemod can't read whole gets no such TODO, since a class it
|
|
417
|
+
can't see may be the `.image`.
|
|
418
|
+
|
|
333
419
|
## A whole file it left alone
|
|
334
420
|
|
|
335
421
|
These come only when the file has an element the codemod would convert (a computed className
|
|
@@ -359,7 +445,8 @@ Run on an HTML page (`bestax-migrate bulma-classes page.html`, or a folder with
|
|
|
359
445
|
codemod writes a module beside the page and runs everything above on it, so a page gets the same
|
|
360
446
|
TODOs its markup would as JSX. What a component can't carry gets an `html-*` rule. TODOs about the
|
|
361
447
|
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)`)
|
|
448
|
+
the line it came from (`(index.html:42)`), or every line, for a TODO several elements share
|
|
449
|
+
(`(index.html:42, 57)`). The page itself stays as it was, so the code a TODO
|
|
363
450
|
points at is still there to read. A rule names only a tag, an attribute or a fixed word, never
|
|
364
451
|
anything the page says.
|
|
365
452
|
|
|
@@ -373,6 +460,11 @@ A component renders into the `<body>` of the app's own document, so nothing in t
|
|
|
373
460
|
it into the head; React 18 leaves it in the body, so use `document.title` in an effect there.
|
|
374
461
|
- **`html-head:meta`**: `charset` and `viewport` go once in the app's `index.html`. A page's own
|
|
375
462
|
(a description, Open Graph tags) go where the app sets each page's head.
|
|
463
|
+
- **`html-head:csp`**: a `<meta http-equiv="Content-Security-Policy">`. Its policy was written for
|
|
464
|
+
what the page loads, and copied into `index.html` as it is, it can block what the app loads
|
|
465
|
+
instead: a Vite dev server runs an inline script for React's fast refresh and opens a socket for
|
|
466
|
+
hot reloading, and the build serves the app's own scripts, styles and fonts. Write the app's own
|
|
467
|
+
policy, best sent as a response header, and try it under both the dev server and the build.
|
|
376
468
|
- **`html-head:link`**: icons, preconnects and preloads are app-wide, so keep them in
|
|
377
469
|
`index.html`; a `canonical` is per page.
|
|
378
470
|
- **`html-head:style`**: the `<style>` block was dropped. Move its rules into the app's stylesheet.
|
|
@@ -412,15 +504,18 @@ neither, so load what the app still needs once for the whole app, from its entry
|
|
|
412
504
|
reported in every mode, since the codemod imports only the standard one. bestax's own builds,
|
|
413
505
|
Bulma with its extras, are under `@allxsmith/bestax-bulma/versions/`.
|
|
414
506
|
- **`html-asset:font-awesome`**: Font Awesome, with the major its URL names. bestax's `Icon`
|
|
415
|
-
writes its classes (`fas fa-<name
|
|
507
|
+
writes its classes (`fas fa-<name>`, or the style its `variant` names) and loads no font of its
|
|
508
|
+
own, so keep loading it, from the
|
|
416
509
|
`<link>` in `index.html` or from npm: bestax-bulma's optional peer range for
|
|
417
510
|
`@fortawesome/fontawesome-free` is `^6.7.2 || ^7.0.0`, and an older one fails `npm install`
|
|
418
511
|
with `ERESOLVE`.
|
|
419
512
|
- 6 and 7: keep it as it is, or install it and import its `css/all.min.css` from the entry.
|
|
420
513
|
- 5: the CDN link keeps working, since 5 reads the classes `Icon` writes. From npm, take 6 or 7,
|
|
421
514
|
which still read 5's names.
|
|
422
|
-
- 4: its classes are `fa fa-<name
|
|
423
|
-
|
|
515
|
+
- 4: its classes are `fa fa-<name>`. The codemod keeps that `fa` on each icon it converts
|
|
516
|
+
(`variant="fa"`), which 4 styles, but an `Icon` given no `variant` writes `fas fa-<name>`,
|
|
517
|
+
which 4 doesn't, so for the icons written from here on, install 6 or 7 with
|
|
518
|
+
`css/all.min.css`, then either import `css/v4-shims.min.css` beside it so
|
|
424
519
|
the page's 4 names keep working, or move them to the current names (`fa-envelope-o` is
|
|
425
520
|
`envelope` with `variant="regular"`).
|
|
426
521
|
- A kit (`kit.fontawesome.com`): keep loading it from `index.html`, or install Font Awesome from
|
|
@@ -432,23 +527,23 @@ neither, so load what the app still needs once for the whole app, from its entry
|
|
|
432
527
|
whose styles ship in `extras.css` and `bestax.css`, and stop loading the extension once nothing
|
|
433
528
|
the app keeps uses its classes:
|
|
434
529
|
|
|
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
|
|
530
|
+
| Extension | bestax |
|
|
531
|
+
| ------------------------------------------------------- | -------------------------------------------------------------------------------------- |
|
|
532
|
+
| `bulma-carousel` | `Carousel`, with a `CarouselItem` for each slide and `itemsToShow` for several in view |
|
|
533
|
+
| `bulma-slider` | `Slider` |
|
|
534
|
+
| `bulma-switch` | `Switch` |
|
|
535
|
+
| `bulma-checkradio` | `Checkbox` and `Radio`, which draw their own box |
|
|
536
|
+
| `bulma-tooltip`, `@creativebulma/bulma-tooltip` | `Tooltip` |
|
|
537
|
+
| `bulma-badge`, `@creativebulma/bulma-badge` | `Badge` |
|
|
538
|
+
| `bulma-steps` | `Steps` |
|
|
539
|
+
| `bulma-timeline` | `Timeline` |
|
|
540
|
+
| `bulma-tagsinput`, `@creativebulma/bulma-tagsinput` | `Taginput` |
|
|
541
|
+
| `bulma-calendar` | `DateInput`, `TimeInput`, `DateTimeInput` and `DateRangeInput` |
|
|
542
|
+
| `bulma-accordion` | `Collapses`, with a `Collapse` for each item |
|
|
543
|
+
| `bulma-collapsible`, `@creativebulma/bulma-collapsible` | `Collapse` (`Collapses` for an accordion) |
|
|
544
|
+
| `bulma-pageloader` | `Loading`, `isFullPage` for one over the whole page |
|
|
545
|
+
| `bulma-quickview` | `Sidebar` |
|
|
546
|
+
| `bulma-toast` | `Toast`: `toast.show()` from code, with a `ToastContainer` once |
|
|
452
547
|
|
|
453
548
|
`bulma-extensions`, the bundle, holds several of these: replace the ones in the table, and keep
|
|
454
549
|
loading the bundle only for the rest. **bulma-social** has no bestax component: keep loading it,
|
|
@@ -531,8 +626,24 @@ read for the burger, a carousel and a theme toggle too, and its TODO names the f
|
|
|
531
626
|
takes `hasDelete` and `onDelete`, `Tag` takes `onDelete` and `Message` takes `onClose`; render
|
|
532
627
|
the element only while it's in state.
|
|
533
628
|
- **`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).
|
|
535
|
-
in
|
|
629
|
+
children and renders its own arrows and indicators (`autoplay` for a timed one). For several
|
|
630
|
+
slides in view, set `itemsToShow`, with a variant per viewport (`itemsToShowMobile`,
|
|
631
|
+
`itemsToShowTablet`, …), and `itemsToScroll`: bulma-carousel calls them `slidesToShow` and
|
|
632
|
+
`slidesToScroll`. bulma-carousel's `breakpoints` replace both at and below pixel widths of its
|
|
633
|
+
own (each entry's `changePoint`), and a page that sets none gets its defaults: 1 slide up to
|
|
634
|
+
480px, 2 up to 640px and 3 up to 768px, each scrolling as many, so `slidesToShow` applies only
|
|
635
|
+
from 769px up. Below that the defaults decide whatever `slidesToShow` says: a phone shows 1
|
|
636
|
+
slide, and a page that sets `slidesToShow: 1` shows 2 or 3 between a phone's width and a
|
|
637
|
+
tablet's. A page's own `breakpoints` replace the defaults, and an empty list turns them off.
|
|
638
|
+
`Carousel` has no pixel widths: `itemsToShowMobile` covers every width below 769px, where all
|
|
639
|
+
of those defaults sit, and the wider variants start at Bulma's breakpoints. So set
|
|
640
|
+
`itemsToShow` to the page's `slidesToShow`, and `itemsToShowMobile` to what the page shows on
|
|
641
|
+
a phone (1 under the defaults) where that differs; one `itemsToScroll` covers every width. To
|
|
642
|
+
keep the steps bulma-carousel takes between those widths, compute `itemsToShow` from the
|
|
643
|
+
window's width in your own code. `Carousel` loops unless `repeat={false}`, while
|
|
644
|
+
bulma-carousel stops at the ends unless `loop` (back to the start) or `infinite` (round
|
|
645
|
+
without a break) is set, so a carousel with neither takes `repeat={false}`. Its styles ship in
|
|
646
|
+
bestax's `extras.css` and `bestax.css`, not in Bulma's stylesheet.
|
|
536
647
|
- **`html-script:theme`** switches Bulma's light and dark schemes. The toggle is `Theme`'s: it
|
|
537
648
|
writes `data-theme` on `<html>` from its `colorMode` (`light`, `dark` or `system`), so keep the
|
|
538
649
|
choice in state, save it in `localStorage`, and pass it. The first paint is `index.html`'s:
|
|
@@ -540,8 +651,11 @@ read for the burger, a carousel and a theme toggle too, and its TODO names the f
|
|
|
540
651
|
from their OS sees the OS's scheme first. A small inline script in the `<head>` of `index.html`
|
|
541
652
|
that reads the saved choice (or the OS's, with none saved) and writes `data-theme` before the
|
|
542
653
|
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
|
-
|
|
654
|
+
bestax-theming skill covers `Theme` and `colorMode`, and its `examples/dark-mode.tsx` has the
|
|
655
|
+
script and the app's side.
|
|
656
|
+
- **`html-script:json-ld`** is structured data for search engines. Data about the whole site, or
|
|
657
|
+
about a single-page app's one page, goes in the app's `index.html` as it is, where a crawler that
|
|
658
|
+
runs no JavaScript still reads it. Data that differs from page to page goes where the app sets
|
|
545
659
|
each page's head, as
|
|
546
660
|
`<script type="application/ld+json" dangerouslySetInnerHTML={{ __html: JSON.stringify(data) }} />`.
|
|
547
661
|
- **`html-script`**: any other inline script, or a `<script type>` that isn't code (a template,
|
|
@@ -558,8 +672,10 @@ The app's document has its own `<html>` and `<body>`, which a component can't re
|
|
|
558
672
|
pads the page for a fixed navbar from it. Put the class on the `<html>` in `index.html`, since
|
|
559
673
|
bestax's `Navbar` adds none there, whatever its `fixed` says.
|
|
560
674
|
- **`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`,
|
|
562
|
-
|
|
675
|
+
the page's color scheme. Put it on the `<html>` in `index.html`, where the first paint has it.
|
|
676
|
+
For a scheme the visitor switches, `Theme colorMode` writes the choice only after that paint,
|
|
677
|
+
so write a saved one before it too, as `html-script:theme` says and the bestax-theming skill's
|
|
678
|
+
`examples/dark-mode.tsx` does.
|
|
563
679
|
- **`html-document:lang`**, **`html-document:dir`**: set them on the `<html>` in `index.html`.
|
|
564
680
|
- **`html-document:class`**: the page's own classes on `<html>` or `<body>`. Put them on the
|
|
565
681
|
app's own `<body>` (or `<html>`), or on an element around the page's content if the styles
|
|
@@ -598,9 +714,51 @@ than `this`. A `<body onload>` becomes an effect.
|
|
|
598
714
|
- **`html-url:relative`**: `img/logo.png` resolved against the page's folder, and in the app it
|
|
599
715
|
resolves against the address the component renders at. The file is there beside the page, so
|
|
600
716
|
copy it into the app's `public/` folder and point at it from the site root (`/img/logo.png`), or
|
|
601
|
-
import it.
|
|
602
|
-
|
|
603
|
-
|
|
717
|
+
import it. Each relative URL in a `srcset` is its own entry, quoted as itself
|
|
718
|
+
(`` `hero@2x.png` in `srcset` ``). Several of these share one TODO line, and each is its own
|
|
719
|
+
report entry.
|
|
720
|
+
|
|
721
|
+
A link to another page beside this one should point at the route that page becomes: the
|
|
722
|
+
router's, in an app with one. A site of static pages, with no router to join, can route on the
|
|
723
|
+
URL's hash in a small module of its own and install no router package, so every page still
|
|
724
|
+
opens from a static host as it is:
|
|
725
|
+
|
|
726
|
+
```ts
|
|
727
|
+
// router.ts: the page the address's hash names (`#/about`).
|
|
728
|
+
import { useEffect, useState } from 'react';
|
|
729
|
+
|
|
730
|
+
export const routes = { home: '#/', about: '#/about' } as const;
|
|
731
|
+
export type Route = keyof typeof routes;
|
|
732
|
+
|
|
733
|
+
function routeOf(hash: string): Route {
|
|
734
|
+
const found = (Object.keys(routes) as Route[]).find(
|
|
735
|
+
route => routes[route] === hash
|
|
736
|
+
);
|
|
737
|
+
return found ?? 'home';
|
|
738
|
+
}
|
|
739
|
+
|
|
740
|
+
export function useRoute(): Route {
|
|
741
|
+
const [route, setRoute] = useState(() => routeOf(window.location.hash));
|
|
742
|
+
useEffect(() => {
|
|
743
|
+
const onHashChange = () => {
|
|
744
|
+
const hash = window.location.hash;
|
|
745
|
+
// Only `#/…` (or no hash) names a page; leave an in-page anchor such
|
|
746
|
+
// as `#features`, or a placeholder `#`, to the browser.
|
|
747
|
+
if (hash !== '' && !hash.startsWith('#/')) return;
|
|
748
|
+
setRoute(routeOf(hash));
|
|
749
|
+
window.scrollTo(0, 0); // a new page starts at the top, as it did
|
|
750
|
+
};
|
|
751
|
+
window.addEventListener('hashchange', onHashChange);
|
|
752
|
+
return () => window.removeEventListener('hashchange', onHashChange);
|
|
753
|
+
}, []);
|
|
754
|
+
return route;
|
|
755
|
+
}
|
|
756
|
+
```
|
|
757
|
+
|
|
758
|
+
The app renders the page the route names, from the modules the pages became
|
|
759
|
+
(`const Page = { home: HomePage, about: AboutPage }[useRoute()]`), with the parts the pages
|
|
760
|
+
share around it, and a link to `about.html` takes `href={routes.about}`.
|
|
761
|
+
|
|
604
762
|
- **`html-url:missing`**: a relative URL whose target isn't beside the page, read the way the
|
|
605
763
|
browser read it, so it was a dead link or a missing file already. Point it somewhere real, or
|
|
606
764
|
drop it.
|
|
@@ -610,6 +768,12 @@ than `this`. A `<body onload>` becomes an effect.
|
|
|
610
768
|
- **`html-attr:name`**: an attribute JSX can't write (`@click`, `:class`, `x-on:click`), or one the
|
|
611
769
|
element already had under another spelling, was left out. A framework's directive is code to port
|
|
612
770
|
into the component.
|
|
771
|
+
- **`html-attr:stray`**: a stray character in a tag, with no letter or digit in it (`\` in
|
|
772
|
+
`<figure class="image" \>`, a typo for `/>`), which the browser read as the name of an empty
|
|
773
|
+
attribute. It was left out, so there is nothing to port; delete it from the page too.
|
|
774
|
+
- **`html-attr:ignored`**: an attribute HTML gives the element no meaning for, so the browser
|
|
775
|
+
ignored it, and React's types reject it there: `type` on a `<textarea>`. It was left out, so the
|
|
776
|
+
module typechecks. Nothing reads it, unless a stylesheet or script of the page's selects on it.
|
|
613
777
|
- **`html-attr:unknown`**: an attribute React has no prop for by that name, written as it was.
|
|
614
778
|
React renders it. Whether a TypeScript build takes it depends on the element (React's types
|
|
615
779
|
list `valign` on a `<td>` and not on a `<th>`), so the TODO doesn't say; what to do depends on
|
|
@@ -632,9 +796,15 @@ than `this`. A `<body onload>` becomes an effect.
|
|
|
632
796
|
|
|
633
797
|
The HTML has an error the browser repaired (`html-parse:duplicate-attribute`,
|
|
634
798
|
`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
|
|
636
|
-
markup meant, so check that part of the page. A code too
|
|
637
|
-
`html-parse`.
|
|
799
|
+
more there are, except a duplicate attribute (below). The module follows the DOM the browser
|
|
800
|
+
builds from it, which may not be what the markup meant, so check that part of the page. A code too
|
|
801
|
+
long for a rule id is reported as the bare `html-parse`.
|
|
802
|
+
|
|
803
|
+
A duplicate attribute on an element gets an entry of its own, naming the attribute, the copy the
|
|
804
|
+
element keeps (the first) and the one the browser drops (`placeholder="Email"` kept,
|
|
805
|
+
`placeholder="Your email"` dropped). The module has the kept one, so if the page meant the other,
|
|
806
|
+
change the value there. One the codemod can't name, such as one on an end tag, is counted with the
|
|
807
|
+
rest.
|
|
638
808
|
|
|
639
809
|
### The page itself: `html-file:<case>`
|
|
640
810
|
|
|
@@ -656,7 +826,9 @@ A page with no Bulma component class writes nothing and reports nothing.
|
|
|
656
826
|
- Helper classes on a `<div>` (`<div className="is-flex mt-4">`): bestax has no plain `<div>`
|
|
657
827
|
wrapper, and the classes are valid Bulma, so the element stays.
|
|
658
828
|
- `.help`, `.label`, `.loader` and the other classes in the component map's "left alone" list.
|
|
659
|
-
- A class with no bestax prop on a converted element: it stays in `className`.
|
|
829
|
+
- A class with no bestax prop on a converted element: it stays in `className`. That covers
|
|
830
|
+
v1's `marginless` and `paddingless`, which have the same rules as `m-0` and `p-0` under
|
|
831
|
+
other names, so they stay as written while the element converts on its other classes.
|
|
660
832
|
|
|
661
833
|
## After the codemod
|
|
662
834
|
|
|
@@ -26,11 +26,18 @@ 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.
|
|
30
|
-
`--bulma-primary-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
29
|
+
`--bulma-primary-*` CSS variables / a Sass build. With the variables, set
|
|
30
|
+
`--bulma-primary-invert-l` and `--bulma-primary-on-scheme-l` along with `--bulma-primary-h`,
|
|
31
|
+
`--bulma-primary-s` and `--bulma-primary-l`. The first is the lightness of the label on a
|
|
32
|
+
primary surface and the second of primary text on the page, and bestax's build fixes both for
|
|
33
|
+
its dark blue, so a light primary set through the trio alone keeps white labels and pale text.
|
|
34
|
+
To get stock Bulma's turquoise back on top of `bestax.css`, copy those five from Bulma's own
|
|
35
|
+
`bulma/css/bulma.css`. The on-scheme lightness differs between its light and dark schemes, so
|
|
36
|
+
set each scheme's value where the app shows both; the `bestax-theming` skill's
|
|
37
|
+
`references/css-variables.md` ("The lightnesses Bulma's build picks for contrast") shows how,
|
|
38
|
+
and what reads each one. Text the page colors with `has-text-primary` converts to
|
|
39
|
+
`textColor="primary"`, which reads the trio's own lightness, under 2:1 on white for turquoise
|
|
40
|
+
(in stock Bulma too); add `colorShade="on-scheme"` to take the shade made for text.
|
|
34
41
|
|
|
35
42
|
- **SCSS files**: Bulma 0.9's `@import 'bulma/bulma.sass'` (plus preceding
|
|
36
43
|
`$var: value !default;` overrides) became Bulma v1 module syntax, with simple literal
|
|
@@ -88,19 +88,25 @@ several of those narrow it to specific tags (`Footer` is `'footer' | 'div'`, `Co
|
|
|
88
88
|
`'div' | 'p'`). The codemod passes `as` through only where bestax really accepts it, and TODOs it
|
|
89
89
|
everywhere else:
|
|
90
90
|
|
|
91
|
-
| bestax component | `as` accepts
|
|
92
|
-
| ---------------------------- |
|
|
93
|
-
| `Button` | any element type
|
|
94
|
-
| `Title`, `SubTitle` | `h1`–`h6`, `p`
|
|
95
|
-
| `Image` | `'figure' \| 'div' \| 'p'`
|
|
96
|
-
| `Footer` | `'footer' \| 'div'`
|
|
97
|
-
| `Media` | `'article' \| 'div'`
|
|
98
|
-
| `Media.Left` | `'figure' \| 'div'`
|
|
99
|
-
| `Level.Item` | `'div' \| 'p' \| 'a'`
|
|
100
|
-
| `Control` | `'div' \| 'p'`
|
|
101
|
-
| `Menu.Item` | any element type
|
|
102
|
-
| `Dropdown.Item` | `'a' \| 'div' \| 'button'`
|
|
103
|
-
| `Navbar.Item`, `Navbar.Link` | any element type
|
|
91
|
+
| bestax component | `as` accepts |
|
|
92
|
+
| ---------------------------- | --------------------------------------------------------------------------------------- |
|
|
93
|
+
| `Button` | any element type |
|
|
94
|
+
| `Title`, `SubTitle` | `h1`–`h6`, `p` |
|
|
95
|
+
| `Image` | `'figure' \| 'div' \| 'p'` |
|
|
96
|
+
| `Footer` | `'footer' \| 'div'` |
|
|
97
|
+
| `Media` | `'article' \| 'div'` |
|
|
98
|
+
| `Media.Left` | `'figure' \| 'div'` |
|
|
99
|
+
| `Level.Item` | `'div' \| 'p' \| 'a'` |
|
|
100
|
+
| `Control` | `'div' \| 'p'` |
|
|
101
|
+
| `Menu.Item` | any element type |
|
|
102
|
+
| `Dropdown.Item` | `'a' \| 'div' \| 'button'` |
|
|
103
|
+
| `Navbar.Item`, `Navbar.Link` | any element type |
|
|
104
|
+
| `Container` | `'div' \| 'main' \| 'section' \| 'article' \| 'aside' \| 'header' \| 'footer' \| 'nav'` |
|
|
105
|
+
| `Hero` | `'section' \| 'div' \| 'main' \| 'header' \| 'footer' \| 'article' \| 'aside'` |
|
|
106
|
+
| `Hero.Head` | `'div' \| 'header' \| 'nav'` |
|
|
107
|
+
| `Hero.Foot` | `'div' \| 'footer' \| 'nav'` |
|
|
108
|
+
| `Panel` | `'nav' \| 'article' \| 'section' \| 'aside' \| 'div'` |
|
|
109
|
+
| `Panel.Block` | `'a' \| 'div' \| 'label'` |
|
|
104
110
|
|
|
105
111
|
Three traps worth naming, because rbx supplies `as` universally and the obvious guesses are
|
|
106
112
|
wrong:
|