create-bestax 4.2.19 → 4.3.0
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 -3
- package/dist/cli.d.ts.map +1 -1
- package/dist/cli.js +1 -0
- package/dist/constants.d.ts +12 -0
- package/dist/constants.d.ts.map +1 -1
- package/dist/constants.js +65 -0
- package/dist/project-creator.d.ts +8 -0
- package/dist/project-creator.d.ts.map +1 -1
- package/dist/project-creator.js +58 -2
- package/dist/prompts.d.ts +1 -0
- package/dist/prompts.d.ts.map +1 -1
- package/dist/prompts.js +15 -1
- package/package.json +3 -3
- package/templates/skills/bestax-custom-component/references/component-catalog.md +3 -1
- package/templates/skills/bestax-icons/references/icon-libraries.md +14 -1
- package/templates/skills/bestax-layout-scaffold/SKILL.md +15 -0
- package/templates/skills/bestax-migrate/SKILL.md +10 -4
- package/templates/skills/bestax-migrate/references/bloomer/prop-map.md +1 -1
- package/templates/skills/bestax-migrate/references/bloomer/unmappables.md +4 -1
- package/templates/skills/bestax-migrate/references/bulma-classes/component-map.md +49 -15
- package/templates/skills/bestax-migrate/references/bulma-classes/prop-map.md +4 -2
- package/templates/skills/bestax-migrate/references/bulma-classes/unmappables.md +166 -30
- package/templates/skills/bestax-migrate/references/rbx/prop-map.md +1 -1
- package/templates/skills/bestax-migrate/references/react-bulma-components/unmappables.md +2 -2
- package/templates/skills/bestax-optimize/references/modular-build.md +3 -1
- package/templates/skills/bestax-theming/SKILL.md +13 -10
- package/templates/skills/bestax-theming/examples/dark-mode.tsx +7 -6
- package/templates/skills/bestax-theming/examples/theme-config.tsx +10 -3
- package/templates/skills/bestax-theming/references/css-variables.md +89 -11
- package/templates/skills/bestax-theming/references/themeable-components.md +2 -0
- package/templates/vite/README.md +2 -2
- package/templates/vite/_oxlintrc.json +8 -0
- package/templates/vite/package.json +8 -12
- package/templates/vite/vite.config.js +1 -1
- package/templates/vite-ts/README.md +2 -2
- package/templates/vite-ts/_oxlintrc.json +8 -0
- package/templates/vite-ts/package.json +10 -15
- package/templates/vite/eslint.config.js +0 -29
- package/templates/vite-ts/eslint.config.js +0 -26
|
@@ -6,9 +6,13 @@ wrapper library. The codemod converts an element only when the bestax component
|
|
|
6
6
|
stays as written, with a `TODO(bestax-migrate)` when there is something to decide (see
|
|
7
7
|
[unmappables.md](unmappables.md)). The exceptions are deliberate. Font Awesome's own
|
|
8
8
|
`<i aria-hidden="true">` alone in a `.icon` that carries nothing assistive tech reads becomes
|
|
9
|
-
`Icon`, which puts that attribute on the `.icon` instead, since the glyph is hidden either way
|
|
10
|
-
|
|
11
|
-
|
|
9
|
+
`Icon`, which puts that attribute on the `.icon` instead, since the glyph is hidden either way.
|
|
10
|
+
Such a `.icon` around a bare glyph, in a link or button its own `aria-label` or
|
|
11
|
+
`aria-labelledby` names, becomes `Icon` too, which hides it, since the label is what assistive
|
|
12
|
+
tech reads for the control. Font Awesome 6's long name for a style (`fa-brands`) becomes the
|
|
13
|
+
`bestax-icons` skill's `variant` (`brands`), which renders the short name (`fab`), the same
|
|
14
|
+
style (see `.icon` below). And a Bulma 0.9 helper that v1 removed, which styles nothing now,
|
|
15
|
+
becomes the v1 helper that does its job (the [prop map](prop-map.md) lists them).
|
|
12
16
|
|
|
13
17
|
A class the codemod doesn't know, such as the app's own `pricing-card`, rides along in
|
|
14
18
|
`className`, which every bestax component passes through. So does a Bulma class with no bestax
|
|
@@ -156,16 +160,17 @@ renders its own `<a>` with tab roles and puts its label in a `<span>`, so conver
|
|
|
156
160
|
themselves is by hand (something that sat beside the text in the `<a>`, a `Tag` say, then wants a
|
|
157
161
|
`Span display="flex" alignItems="center"` around it and the label). A `.icon` converts when it
|
|
158
162
|
carries the attribute `Icon` writes otherwise: `aria-hidden` with no name, no `role` and no
|
|
159
|
-
`tabIndex`, and `role="img"` beside an `aria-label` or `aria-labelledby`.
|
|
160
|
-
|
|
161
|
-
|
|
163
|
+
`tabIndex`, and `role="img"` beside an `aria-label` or `aria-labelledby`. Those attributes are
|
|
164
|
+
left out, since `Icon` renders them by itself. When all it holds is a bare, empty `<i>` naming a
|
|
165
|
+
Font Awesome or Material Design Icons glyph, the `<i>` goes and its classes become `Icon`'s
|
|
166
|
+
props, read as `IconText` reads them (below), and the `Icon` closes itself:
|
|
162
167
|
|
|
163
168
|
```jsx
|
|
164
169
|
<span className="icon is-small" aria-hidden="true">
|
|
165
170
|
<i className="fab fa-github fa-lg"></i>
|
|
166
171
|
</span>
|
|
167
|
-
// becomes
|
|
168
|
-
<Icon
|
|
172
|
+
// becomes, rendering aria-hidden="true" on the .icon
|
|
173
|
+
<Icon name="github" variant="brands" features="fa-lg" size="small" />
|
|
169
174
|
```
|
|
170
175
|
|
|
171
176
|
Font Awesome's own markup hides the `<i>` instead, and converts the same way when the `.icon`
|
|
@@ -178,12 +183,39 @@ place a conversion changes the markup, on purpose:
|
|
|
178
183
|
<i className="fas fa-envelope" aria-hidden="true"></i>
|
|
179
184
|
</span>
|
|
180
185
|
// becomes, rendering aria-hidden="true" on the .icon
|
|
181
|
-
<Icon
|
|
186
|
+
<Icon name="envelope" size="small" className="is-left" />
|
|
187
|
+
```
|
|
188
|
+
|
|
189
|
+
A `.icon` with no `aria-hidden` converts the same way when it sits in a `<button>`, or in a link
|
|
190
|
+
(an `<a>` with an `href`), that its own `aria-label` or `aria-labelledby` names. That label is
|
|
191
|
+
what assistive tech reads for the control, in place of what it holds, so the icon is decoration
|
|
192
|
+
there, and `Icon` hides it. That is another place a conversion changes the markup, on purpose,
|
|
193
|
+
held to the same shape: a bare glyph, in a `.icon` that carries nothing but its classes, an `id`,
|
|
194
|
+
a `style` and `data-` attributes.
|
|
195
|
+
|
|
196
|
+
```jsx
|
|
197
|
+
<a className="button" href="https://github.com/" aria-label="GitHub">
|
|
198
|
+
<span className="icon"><i className="fab fa-github"></i></span>
|
|
199
|
+
</a>
|
|
200
|
+
// becomes, rendering aria-hidden="true" on the .icon
|
|
201
|
+
<Button as="a" href="https://github.com/" aria-label="GitHub">
|
|
202
|
+
<Icon name="github" variant="brands" />
|
|
203
|
+
</Button>
|
|
182
204
|
```
|
|
183
205
|
|
|
184
206
|
Around anything else, an `<i>` with an attribute of its own or an `<svg>` say, it converts around
|
|
185
|
-
what it holds, kept as written.
|
|
186
|
-
|
|
207
|
+
what it holds, kept as written.
|
|
208
|
+
|
|
209
|
+
The glyph's props are spelled the way the `bestax-icons` skill writes them. `library` is left out
|
|
210
|
+
for Font Awesome, `Icon`'s default, and written for Material Design Icons. The style is `variant`:
|
|
211
|
+
none for `fas`, and `regular`, `brands`, `light`, `duotone` or `thin` for the others. Font
|
|
212
|
+
Awesome 6's long names for them (`fa-solid`, `fa-brands`, ...) read the same way, and `Icon`
|
|
213
|
+
renders the short name (`fab`), the class Font Awesome 5 knows, which 6 and 7 style the same:
|
|
214
|
+
a third place the markup changes on purpose. Beside `fa-sharp`, whose family Font Awesome 7's
|
|
215
|
+
short name would set back to the classic one, the long name stays as written. Font Awesome 4's
|
|
216
|
+
`fa` reads as `variant="fa"`, which `Icon` renders as written: 4 styles nothing else, and some
|
|
217
|
+
4 names draw another glyph in 5 and later (the `bestax-icons` skill's
|
|
218
|
+
`references/icon-libraries.md` lists them).
|
|
187
219
|
|
|
188
220
|
A `.menu` converts with its `.menu-label`s and `.menu-list`s, and so do the items in a list. An
|
|
189
221
|
item has no class to go by, so the codemod finds it by where it sits: a `<li>` whose nearest
|
|
@@ -314,14 +346,16 @@ as `items`.
|
|
|
314
346
|
<span>Home</span>
|
|
315
347
|
</span>
|
|
316
348
|
// becomes
|
|
317
|
-
<IconText iconProps={{
|
|
349
|
+
<IconText iconProps={{ name: "home" }}>Home</IconText>
|
|
318
350
|
```
|
|
319
351
|
|
|
320
352
|
The glyph is read from the `<i>`: its Font Awesome style class (`fas`, `far`, `fa-solid`, ...) or
|
|
321
353
|
`mdi`, the one class that names the glyph (`fa-home` as `name: "home"`), and the rest as
|
|
322
|
-
`features
|
|
323
|
-
|
|
324
|
-
|
|
354
|
+
`features`, spelled as on `Icon` (above). Like every conversion, this takes the app's
|
|
355
|
+
`ConfigProvider` as unset: one with another `iconLibrary` needs `library: "fa"` written back on
|
|
356
|
+
the Font Awesome ones, as one with a `classPrefix` changes every component's classes. The
|
|
357
|
+
`.icon`'s own classes and attributes join the glyph's props as they would on `Icon`, under their
|
|
358
|
+
own names, but for those `Icon` renders by itself.
|
|
325
359
|
|
|
326
360
|
It converts only when every `.icon` inside converts to `Icon` on its own and holds a bare, empty
|
|
327
361
|
`<i>` naming a Font Awesome or Material Design Icons glyph, and the only other children are those
|
|
@@ -2,7 +2,8 @@
|
|
|
2
2
|
|
|
3
3
|
Which class becomes which prop, per component, then the helper classes every component takes.
|
|
4
4
|
A class that becomes no prop stays in `className`. So does a second class for a prop already
|
|
5
|
-
written (`is-small is-large` keeps `is-large`), so the element still renders both.
|
|
5
|
+
written (`is-small is-large` keeps `is-large`), so the element still renders both. A second
|
|
6
|
+
color gets a `modifier:<root>` TODO (`modifier:button`), since only one of the two may show.
|
|
6
7
|
|
|
7
8
|
`{viewport}` is one of `mobile`, `tablet`, `desktop`, `widescreen`, `fullhd` unless a row says
|
|
8
9
|
otherwise, and the prop takes the matching suffix: `is-6-tablet` → `sizeTablet="6"`.
|
|
@@ -74,7 +75,8 @@ bestax picks the heading from `size` (`size="3"` renders an `<h3>`) unless `as="
|
|
|
74
75
|
`<h2>`, `is-4` stays a class and the element becomes `<Title as="h2" className="is-4">`, which
|
|
75
76
|
renders the same `<h2>`. To write it as a prop, `textSize="4"` keeps the `<h2>` and sizes it the
|
|
76
77
|
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.
|
|
78
|
+
and as a Bulma helper it is `!important`, so check a title the page's own CSS sizes. The
|
|
79
|
+
codemod's `modifier:title` (or `modifier:subtitle`) TODO on the element says the same.
|
|
78
80
|
|
|
79
81
|
### Other components
|
|
80
82
|
|
|
@@ -104,15 +104,21 @@ and beside a `role` or `tabIndex` `Icon` writes no `aria-hidden` at all. Give a
|
|
|
104
104
|
that carries it beside something else,
|
|
105
105
|
an `id` say, keeps its `.icon` as markup too: the `.icon` holds nothing else, so the attribute
|
|
106
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
|
-
|
|
109
|
-
|
|
110
|
-
|
|
107
|
+
`<i>`. An icon around a bare glyph in a `<button>`, or a link, that its own `aria-label` or
|
|
108
|
+
`aria-labelledby` names converts as it is, another exception: the label is what assistive tech
|
|
109
|
+
reads for the control, so the icon is decoration there, and `Icon` hides it. That takes the same
|
|
110
|
+
`.icon` as the move: its classes, an `id`, a `style` and `data-` attributes, and no
|
|
111
|
+
`aria-hidden`. An icon in a control its text names is decoration too, so give it
|
|
112
|
+
`aria-hidden="true"`, and so is one in a named control it doesn't convert in (a `title` on the
|
|
113
|
+
`.icon`, say). An `<a>` with no `href` is no link and has no role, and ARIA lets nothing name it,
|
|
114
|
+
so its `aria-label` does nothing: give it an `href`, or make it a `<button>`, then re-run. One
|
|
115
|
+
that is all a link or button shows names nothing a screen reader can read: give the link or
|
|
116
|
+
button an `aria-label` that says what it does, then re-run, and the icon converts hidden. The
|
|
111
117
|
`<svg class="svg-inline--fa">` Font Awesome's script draws in place of an `<i>` converts as
|
|
112
118
|
`Icon`'s children once its `.icon` is hidden, or write `Icon` with the glyph's `name` in its place,
|
|
113
119
|
which renders the `<i>` the script draws from. Inside a `.control` with `has-icons-left` or
|
|
114
120
|
`has-icons-right`, a hidden `.icon` can go instead, as that `Control`'s `iconLeft` or
|
|
115
|
-
`iconRight` (`iconLeft={{
|
|
121
|
+
`iconRight` (`iconLeft={{ name: "envelope", size: "small" }}`), which renders it
|
|
116
122
|
after the `Control`'s children. Each TODO says which of these applies, and what the icon converts
|
|
117
123
|
to.
|
|
118
124
|
`Pagination` renders Bulma's own `role="navigation"` and `aria-label="pagination"`, and
|
|
@@ -370,13 +376,47 @@ in the browser:
|
|
|
370
376
|
`aria-expanded` and keyboard handling. The codemod turned the `.has-dropdown` item around it
|
|
371
377
|
into a `Navbar.Item` that keeps the class; to get the dropdown behavior, replace that item
|
|
372
378
|
with `Navbar.Dropdown` (`hoverable` for `is-hoverable`) and the link with `Navbar.Link`.
|
|
373
|
-
- **`family:checkbox
|
|
374
|
-
|
|
379
|
+
- **`family:checkbox`**: `Checkbox` renders a `<label class="styled-checkbox checkbox">` around
|
|
380
|
+
its `<input>`, hidden, and draws a box of its own beside it. Write it in place of the element
|
|
381
|
+
that carries `.checkbox`, Bulma's `<label>` or a bare `<input type="checkbox">`:
|
|
382
|
+
- The `<input>`'s attributes go on `Checkbox`, which passes `id`, `name`, `aria-label` and the
|
|
383
|
+
rest to its `<input>`. A `<label>`'s text becomes its children.
|
|
384
|
+
- Drive it with `checked` and `onChange`, and add `indeterminate` for a select-all box that
|
|
385
|
+
shows some of its rows checked.
|
|
386
|
+
- Its `className` goes on its `<label>`, which declares the `--bulma-checkbox-*` variables. For
|
|
387
|
+
the page's colors, set those in a rule for your class beside `.styled-checkbox`, so the rule
|
|
388
|
+
wins whatever order the stylesheets load in, and leave `color` unset.
|
|
389
|
+
- Where the page put `.checkbox` on a bare `<input>`, drop its own rules for that box. bestax
|
|
390
|
+
draws its own, and `.checkbox` is on its `<label>` now, so those rules would land there.
|
|
391
|
+
|
|
392
|
+
```tsx
|
|
393
|
+
<Checkbox
|
|
394
|
+
id="select-all"
|
|
395
|
+
aria-label="Select all guests"
|
|
396
|
+
className="guest-check"
|
|
397
|
+
checked={allChecked}
|
|
398
|
+
indeterminate={someChecked && !allChecked}
|
|
399
|
+
onChange={toggleAll}
|
|
400
|
+
/>
|
|
401
|
+
```
|
|
402
|
+
|
|
403
|
+
```css
|
|
404
|
+
.styled-checkbox.guest-check {
|
|
405
|
+
--bulma-checkbox-active-color: #e8505b;
|
|
406
|
+
}
|
|
407
|
+
```
|
|
408
|
+
|
|
409
|
+
- **`family:radio`**, **`family:checkboxes`**, **`family:radios`**: bestax renders its own
|
|
410
|
+
styled radio markup, and its own `.field` and `.control` around a group, not Bulma's.
|
|
375
411
|
- **`family:modal`**: `Modal` writes a `data-testid` of its own and adds dialog attributes and
|
|
376
412
|
focus handling, so the `.modal` root stays markup while its background, content and card parts
|
|
377
|
-
convert on their own. Rebuild the root with `Modal` around them,
|
|
413
|
+
convert on their own. Rebuild the root with `Modal` around them, drive it with its open prop,
|
|
414
|
+
and pass `onClose`, which Escape and `Modal.Close` call. The converted `Modal.Background`
|
|
415
|
+
doesn't call it on its own: give it `onClick={onClose}` for the background to close the modal.
|
|
378
416
|
A `.modal-close` stays too, since `Modal.Close` renders `.delete` unless it's floating: write
|
|
379
|
-
`<Modal.Close variant="floating" />` in its place.
|
|
417
|
+
`<Modal.Close variant="floating" />` in its place. A card head's `.delete` converts to `Delete`,
|
|
418
|
+
which doesn't call `onClose` either, so write `<Modal.Close />` there instead: it renders the
|
|
419
|
+
same `.delete`. When the
|
|
380
420
|
page has to look the same, keep `Modal` rather than `Dialog` or `Toast`: those render
|
|
381
421
|
bestax's own `.dialog` and `.toast` markup, which Bulma's stylesheet doesn't style.
|
|
382
422
|
- **`family:dropdown`**: `Dropdown` renders its own trigger and menu from props.
|
|
@@ -406,16 +446,35 @@ reason), or beside a class for the same prop (`p-2`, before it or after), which
|
|
|
406
446
|
since it's what the page renders today. Write `m-0` or `p-0` in its place, or drop it if the
|
|
407
447
|
spacing it once removed no longer matters.
|
|
408
448
|
|
|
409
|
-
## A class that
|
|
449
|
+
## A modifier class that needs a look: `modifier:<root>`
|
|
410
450
|
|
|
411
451
|
`modifier:image`: an `.image` size or ratio (`is-64x64`, `is-square`, `is-4by3`) on an element
|
|
412
452
|
without `.image`. Bulma styles them only on the element that carries `.image`, so this one
|
|
413
453
|
sizes nothing, unless the project's own CSS gives the class a rule. If the element is the
|
|
414
454
|
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
|
-
|
|
455
|
+
them), re-run and it can convert; on any other tag it stays markup, and the TODO says so. Where
|
|
456
|
+
the element converted to something else anyway (a `<figure>` to `Figure`), a re-run finds a
|
|
457
|
+
component, so the TODO says to convert it to `Image` by hand. Otherwise drop the class. A computed `className` the codemod can't read whole gets no such TODO, since a class it
|
|
417
458
|
can't see may be the `.image`.
|
|
418
459
|
|
|
460
|
+
`modifier:button` (and `modifier:hero`, `modifier:tag`, `modifier:notification`,
|
|
461
|
+
`modifier:progress`, `modifier:navbar`): a second color on an element that converted
|
|
462
|
+
(`button is-black is-primary`). The component takes one `color`, the first color class on the
|
|
463
|
+
element, and the other stays in `className`, which renders the same. Two colors on one element
|
|
464
|
+
look the way Bulma's stylesheet settles them, not the order they're written in, so one of
|
|
465
|
+
them may be doing nothing. Look at what the page shows, write the color you want as `color`,
|
|
466
|
+
and drop the other class. A color a `clsx` or `classnames` condition adds gets no TODO, since
|
|
467
|
+
that is a state the page asks for.
|
|
468
|
+
|
|
469
|
+
`modifier:title`, `modifier:subtitle`: a heading size on a heading it doesn't name
|
|
470
|
+
(`<h1 className="title is-3">`). bestax picks the heading from `size` (`size="3"` renders an
|
|
471
|
+
`<h3>`), so the size stays in `className` and the element becomes `<Title className="is-3">`,
|
|
472
|
+
the same `<h1>`. To write it as a prop, as the MCP server's `lookup_bulma_classes` says,
|
|
473
|
+
`textSize="3"` in its place keeps the `<h1>` and sizes it the same. It renders Bulma's
|
|
474
|
+
`is-size-3`, which is `!important`, so check a title the page's own CSS sizes. There is no TODO
|
|
475
|
+
when an `is-size-*` beside it writes `textSize` already, or when the element has two size
|
|
476
|
+
classes.
|
|
477
|
+
|
|
419
478
|
## A whole file it left alone
|
|
420
479
|
|
|
421
480
|
These come only when the file has an element the codemod would convert (a computed className
|
|
@@ -511,21 +570,30 @@ neither, so load what the app still needs once for the whole app, from its entry
|
|
|
511
570
|
with `ERESOLVE`.
|
|
512
571
|
- 6 and 7: keep it as it is, or install it and import its `css/all.min.css` from the entry.
|
|
513
572
|
- 5: the CDN link keeps working, since 5 reads the classes `Icon` writes. From npm, take 6 or 7,
|
|
514
|
-
which still read 5's names.
|
|
573
|
+
which still read 5's names, many of them since renamed (`search` is `magnifying-glass`). But
|
|
574
|
+
6 turned the handsets round, so to keep the glyph the page shows, write 5's `phone` and
|
|
575
|
+
`phone-square` as `phone-flip` and `square-phone-flip`, and 5's `phone-alt` and
|
|
576
|
+
`phone-square-alt` as `phone` and `square-phone`.
|
|
515
577
|
- 4: its classes are `fa fa-<name>`. The codemod keeps that `fa` on each icon it converts
|
|
516
578
|
(`variant="fa"`), which 4 styles, but an `Icon` given no `variant` writes `fas fa-<name>`,
|
|
517
579
|
which 4 doesn't, so for the icons written from here on, install 6 or 7 with
|
|
518
580
|
`css/all.min.css`, then either import `css/v4-shims.min.css` beside it so
|
|
519
581
|
the page's 4 names keep working, or move them to the current names (`fa-envelope-o` is
|
|
520
|
-
`envelope` with `variant="regular"`).
|
|
582
|
+
`envelope` with `variant="regular"`). A brand's glyph under `fa` (`fa fa-github`) needs
|
|
583
|
+
`variant="brands"` then: 5 and later draw brands in a style of their own, and without the
|
|
584
|
+
shims show a missing-glyph box for one under `fa`.
|
|
585
|
+
- A URL that doesn't say its version: the TODO points at the `bestax-icons` skill's
|
|
586
|
+
`references/icon-libraries.md`, which lists the older names that draw another glyph in 6
|
|
587
|
+
and 7.
|
|
521
588
|
- A kit (`kit.fontawesome.com`): keep loading it from `index.html`, or install Font Awesome from
|
|
522
589
|
npm instead. A URL with no version: the same, with the v4 shims beside it if the page's names
|
|
523
590
|
are 4's (`fa fa-<name>`).
|
|
524
|
-
- **`html-asset:bulma-extension`**: a `bulma-*` package (or `@creativebulma/bulma-*`).
|
|
525
|
-
|
|
526
|
-
|
|
527
|
-
|
|
528
|
-
|
|
591
|
+
- **`html-asset:bulma-extension`**: a `bulma-*` package (or `@creativebulma/bulma-*`). A file of
|
|
592
|
+
one extension inside the `bulma-extensions` package (`bulma-extensions/bulma-carousel/dist/…`)
|
|
593
|
+
counts as that extension's. An extension's stylesheet and script are one TODO, with both lines.
|
|
594
|
+
Where bestax has a component for what it does, the TODO names it; render that in place of the
|
|
595
|
+
extension's markup and script, whose styles ship in `extras.css` and `bestax.css`, and stop
|
|
596
|
+
loading the extension once nothing the app keeps uses its classes:
|
|
529
597
|
|
|
530
598
|
| Extension | bestax |
|
|
531
599
|
| ------------------------------------------------------- | -------------------------------------------------------------------------------------- |
|
|
@@ -545,6 +613,10 @@ neither, so load what the app still needs once for the whole app, from its entry
|
|
|
545
613
|
| `bulma-quickview` | `Sidebar` |
|
|
546
614
|
| `bulma-toast` | `Toast`: `toast.show()` from code, with a `ToastContainer` once |
|
|
547
615
|
|
|
616
|
+
bulma-carousel's `is-covered` images are the exception: its stylesheet crops them only inside
|
|
617
|
+
its own slides, which `Carousel` doesn't render, so keeping it wouldn't keep them cropped. The
|
|
618
|
+
TODO says so when the page has them, and `html-extension:is-covered` has the rule to add.
|
|
619
|
+
|
|
548
620
|
`bulma-extensions`, the bundle, holds several of these: replace the ones in the table, and keep
|
|
549
621
|
loading the bundle only for the rest. **bulma-social** has no bestax component: keep loading it,
|
|
550
622
|
since its classes (`is-twitter`, `is-github`) style Bulma's `.button`, which `Button` renders,
|
|
@@ -556,6 +628,20 @@ neither, so load what the app still needs once for the whole app, from its entry
|
|
|
556
628
|
</Button>
|
|
557
629
|
```
|
|
558
630
|
|
|
631
|
+
It also ships one stylesheet per brand, `css/single/<brand>/<brand>.min.css`, a few kB each
|
|
632
|
+
against about 100 kB for every brand in `css/all.min.css`. Each holds the brand's button color
|
|
633
|
+
(`is-<brand>`) and its text and background helpers (`has-text-<brand>`,
|
|
634
|
+
`has-background-<brand>`, with `-dark` and `-light`). Every brand has a file from 3.2.0 on
|
|
635
|
+
(`slack`'s came in 2.1.0, `x`'s in 3.1.0 and `twitch`'s in 3.2.0). So with `bulma-social` 3.2.0
|
|
636
|
+
or later installed from npm, import only the brands the app shows, from its entry. The TODO names the files for the brands
|
|
637
|
+
in the page's markup, so an app of several pages imports each brand any of them shows, and one
|
|
638
|
+
a script adds as well:
|
|
639
|
+
|
|
640
|
+
```ts
|
|
641
|
+
import 'bulma-social/css/single/github/github.min.css';
|
|
642
|
+
import 'bulma-social/css/single/twitter/twitter.min.css';
|
|
643
|
+
```
|
|
644
|
+
|
|
559
645
|
Any other extension: keep loading it while the page's markup uses its classes, which go on
|
|
560
646
|
bestax's components through `className`, and under `--css bestax` or `--css bulma` check it
|
|
561
647
|
works with Bulma 1, which an extension can predate.
|
|
@@ -572,9 +658,17 @@ neither, so load what the app still needs once for the whole app, from its entry
|
|
|
572
658
|
- **`html-asset:stylesheet`**: any other stylesheet. The page's own, beside it (in its folder or
|
|
573
659
|
one below), is imported once for the app in the order the page loads it, so its rules still win
|
|
574
660
|
over Bulma's where they did (a module beside the page imports `css/styles.css` as
|
|
575
|
-
`./css/styles.css`), or its rules move into the app's stylesheet.
|
|
576
|
-
|
|
577
|
-
|
|
661
|
+
`./css/styles.css`), or its rules move into the app's stylesheet. A relative URL in it (a
|
|
662
|
+
`url()`, or an `@import` written as a string) resolves against the stylesheet's own folder, not
|
|
663
|
+
the page's, so the TODO names each one it finds: `url('../media/background.webp')` in
|
|
664
|
+
`css/styles.css` points at `media/background.webp` beside the page. Imported where it is, the
|
|
665
|
+
bundler still resolves them. Moved into the app's stylesheet (`src/index.css`), each needs
|
|
666
|
+
rewriting against that file's folder, or copy the files into the app's `public/` folder and
|
|
667
|
+
point at them from the site root (`url('/media/background.webp')`), which the TODO spells out
|
|
668
|
+
for each one inside the page's folder. An `image-set()` that names a file as a bare string
|
|
669
|
+
isn't read, so check those by hand. For a stylesheet that isn't in the page's folder, the TODO
|
|
670
|
+
says only that: the page's `<base href>`, if it has one, may have loaded it from somewhere
|
|
671
|
+
else, so find the one it meant, or drop it.
|
|
578
672
|
- **`html-asset:script`**: any other script. The component runs none: load a library the app still
|
|
579
673
|
needs in `index.html` (or install it), and port what the page's own scripts did into the
|
|
580
674
|
component. A script of the page's own, beside it, is read the way an inline script is, so one
|
|
@@ -620,8 +714,9 @@ read for the burger, a carousel and a theme toggle too, and its TODO names the f
|
|
|
620
714
|
```
|
|
621
715
|
|
|
622
716
|
- **`html-script:modal`** opens or closes a modal. `Modal` shows while `active` is true and calls
|
|
623
|
-
`onClose`
|
|
624
|
-
`
|
|
717
|
+
`onClose` on Escape and from a `Modal.Close` with no `onClick` of its own. `Modal.Background`
|
|
718
|
+
doesn't call it on its own, so give it `onClick={onClose}` for the background to close the
|
|
719
|
+
modal. Keep the open state in `useState` (the `family:modal` TODO covers rebuilding the markup).
|
|
625
720
|
- **`html-script:dismiss`** removes an element when its `.delete` is clicked. `Notification`
|
|
626
721
|
takes `hasDelete` and `onDelete`, `Tag` takes `onDelete` and `Message` takes `onClose`; render
|
|
627
722
|
the element only while it's in state.
|
|
@@ -643,7 +738,8 @@ read for the burger, a carousel and a theme toggle too, and its TODO names the f
|
|
|
643
738
|
window's width in your own code. `Carousel` loops unless `repeat={false}`, while
|
|
644
739
|
bulma-carousel stops at the ends unless `loop` (back to the start) or `infinite` (round
|
|
645
740
|
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.
|
|
741
|
+
bestax's `extras.css` and `bestax.css`, not in Bulma's stylesheet. The element the script
|
|
742
|
+
drives gets `html-extension:carousel`, below, when the codemod can read its selector.
|
|
647
743
|
- **`html-script:theme`** switches Bulma's light and dark schemes. The toggle is `Theme`'s: it
|
|
648
744
|
writes `data-theme` on `<html>` from its `colorMode` (`light`, `dark` or `system`), so keep the
|
|
649
745
|
choice in state, save it in `localStorage`, and pass it. The first paint is `index.html`'s:
|
|
@@ -661,6 +757,40 @@ read for the burger, a carousel and a theme toggle too, and its TODO names the f
|
|
|
661
757
|
- **`html-script`**: any other inline script, or a `<script type>` that isn't code (a template,
|
|
662
758
|
JSON data). Port what it does into the component as state, effects and event handlers.
|
|
663
759
|
|
|
760
|
+
### A Bulma extension's own markup: `html-extension:<name>`
|
|
761
|
+
|
|
762
|
+
A component takes the place of an extension's markup, but nothing converts that markup, so these
|
|
763
|
+
point at the elements to rebuild.
|
|
764
|
+
|
|
765
|
+
- **`html-extension:carousel`**: an element bulma-carousel makes a carousel of. When a script of
|
|
766
|
+
the page's, inline or beside it, attaches bulma-carousel with a selector written as a string of
|
|
767
|
+
tags, ids and classes (`bulmaCarousel.attach('#carousel-demo')`), the codemod finds every
|
|
768
|
+
element that selector matches, the way `querySelectorAll` does, and the TODO lists their
|
|
769
|
+
lines. bulma-carousel makes a carousel of each one, so a page that gives one id to two elements
|
|
770
|
+
has two carousels, and the TODO says so. Render a `Carousel` in the place of each, with a
|
|
771
|
+
`CarouselItem` for each slide (bulma-carousel 4 makes a slide of each child), and carry its
|
|
772
|
+
options over as `html-script:carousel` says. On a page that uses bulma-carousel, an element
|
|
773
|
+
with its `carousel` class that no selector reached gets the TODO too. `carousel` is also bestax
|
|
774
|
+
`Carousel`'s own class, so `bestax.css` and `extras.css` style that markup as `Carousel`'s root
|
|
775
|
+
(`position: relative`, `overflow: hidden`, `width: 100%`) until a `Carousel` takes its place. A
|
|
776
|
+
selector the codemod can't read (a variable, or a selector with a combinator or an attribute)
|
|
777
|
+
gets no TODO of its own: find what it selects by hand.
|
|
778
|
+
- **`html-extension:is-covered`**: bulma-carousel's `is-covered` on an `.image`, on a page that
|
|
779
|
+
loads its stylesheet (the bundle's combined `bulma-extensions.min.css` has no rule for it).
|
|
780
|
+
Inside one of the slides its script builds, that stylesheet makes the `<img>` fill the frame
|
|
781
|
+
and crops it to fit (`object-fit: cover`). Nothing in bestax reads the class: `Image` has no
|
|
782
|
+
prop for it, and the rule reaches only bulma-carousel's own slides, not `Carousel`'s. So in the
|
|
783
|
+
app a ratio image stretches its photo instead. Keep the class and give it the rule in the app's
|
|
784
|
+
stylesheet:
|
|
785
|
+
|
|
786
|
+
```css
|
|
787
|
+
.image.is-covered img {
|
|
788
|
+
width: 100%;
|
|
789
|
+
height: 100%;
|
|
790
|
+
object-fit: cover;
|
|
791
|
+
}
|
|
792
|
+
```
|
|
793
|
+
|
|
664
794
|
### `<html>` and `<body>`: `html-document:<name>`
|
|
665
795
|
|
|
666
796
|
The app's document has its own `<html>` and `<body>`, which a component can't reach.
|
|
@@ -719,9 +849,9 @@ than `this`. A `<body onload>` becomes an effect.
|
|
|
719
849
|
report entry.
|
|
720
850
|
|
|
721
851
|
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
|
|
723
|
-
URL's hash in a small module of its own and install no router package, so
|
|
724
|
-
opens from a static host as it is:
|
|
852
|
+
router's, in an app with one. A multi-page site of static pages, with no router to join, can do
|
|
853
|
+
its routing on the URL's hash in a small module of its own and install no router package, so
|
|
854
|
+
every page still opens from a static host as it is:
|
|
725
855
|
|
|
726
856
|
```ts
|
|
727
857
|
// router.ts: the page the address's hash names (`#/about`).
|
|
@@ -809,8 +939,9 @@ rest.
|
|
|
809
939
|
### The page itself: `html-file:<case>`
|
|
810
940
|
|
|
811
941
|
- **`html-file:exists`**: the module beside the page is already there, and the codemod never
|
|
812
|
-
writes over a file. That makes a second run change nothing.
|
|
813
|
-
the page
|
|
942
|
+
writes over a file. That makes a second run on the page change nothing. To carry on from the
|
|
943
|
+
module's TODOs, run the codemod on the module itself, which is where each TODO from the page
|
|
944
|
+
says to re-run ("re-run on `index.tsx`"). Move or delete the module to convert the page again.
|
|
814
945
|
- **`html-file:not-included`**: a folder walk found the page, and it has Bulma classes, but a walk
|
|
815
946
|
takes a page only when `--extensions` lists its extension, since most `.html` files in a React
|
|
816
947
|
project aren't pages to convert (Vite's `index.html`, `public/`). `-e` matches an extension
|
|
@@ -825,6 +956,11 @@ A page with no Bulma component class writes nothing and reports nothing.
|
|
|
825
956
|
|
|
826
957
|
- Helper classes on a `<div>` (`<div className="is-flex mt-4">`): bestax has no plain `<div>`
|
|
827
958
|
wrapper, and the classes are valid Bulma, so the element stays.
|
|
959
|
+
- Helper classes on a table's rows and cells (`<th className="has-text-centered">`): the codemod
|
|
960
|
+
converts the `.table` and leaves the `<thead>`, `<tbody>`, `<tfoot>`, `<tr>`, `<th>` and `<td>`
|
|
961
|
+
inside it as they are. To write them by hand, `Table.Thead`, `Table.Tbody`, `Table.Tfoot`,
|
|
962
|
+
`Table.Tr`, `Table.Th` and `Table.Td` render each tag as it is and take the helper props, and
|
|
963
|
+
`Table.Th` and `Table.Td` take `isAligned` for their alignment (`<Table.Td isAligned="right">`).
|
|
828
964
|
- `.help`, `.label`, `.loader` and the other classes in the component map's "left alone" list.
|
|
829
965
|
- A class with no bestax prop on a converted element: it stays in `className`. That covers
|
|
830
966
|
v1's `marginless` and `paddingless`, which have the same rules as `m-0` and `p-0` under
|
|
@@ -189,7 +189,7 @@ An existing `ref` is passed through untouched — which is safe only where the b
|
|
|
189
189
|
one. rbx forwards a ref on every component; bestax does so on the form controls, plus `Avatar`,
|
|
190
190
|
`Button`, `Carousel`, `CarouselItem`, `Dialog`, `Dropdown`, `EmptyState`, `Kbd`, `Kbd.Group`,
|
|
191
191
|
`Link`, `LinkButton`, `Loader`, `Menu.Item`, `Modal`, `Navbar`, `Navbar.Burger`, `Navbar.Dropdown`,
|
|
192
|
-
`Navbar.Item`, `Navbar.Link`, `SegmentedControl`, `SegmentedControl.Segment`, `Sidebar`, `Timeline`,
|
|
192
|
+
`Navbar.Item`, `Navbar.Link`, `ScrollArea`, `SegmentedControl`, `SegmentedControl.Segment`, `Sidebar`, `Splitter`, `Splitter.Pane`, `Timeline`,
|
|
193
193
|
`Timeline.Item`, `Toast`, `ToggleButton`, `TreeView` and `TreeView.Item`. "The form controls" there
|
|
194
194
|
means the inputs themselves: the `Field`, `Field.Label`, `Field.Body`, `Checkboxes` and `Radios`
|
|
195
195
|
wrappers around them forward nothing, and `Field` is a target this codemod emits.
|
|
@@ -165,8 +165,8 @@ The same TODO marks a `Heading` that sets `size` and `textSize` both: drop `size
|
|
|
165
165
|
bestax components don't take `domRef`, but many forward a plain `ref` — the form controls, plus
|
|
166
166
|
`Avatar`, `Button`, `Carousel`, `CarouselItem`, `Dialog`, `Dropdown`, `EmptyState`, `Kbd`,
|
|
167
167
|
`Kbd.Group`, `Link`, `LinkButton`, `Loader`, `Menu.Item`, `Modal`, `Navbar`, `Navbar.Burger`,
|
|
168
|
-
`Navbar.Dropdown`, `Navbar.Item`, `Navbar.Link`, `SegmentedControl`, `SegmentedControl.Segment`,
|
|
169
|
-
`Sidebar`, `Timeline`, `Timeline.Item`, `Toast`, `ToggleButton`, `TreeView` and `TreeView.Item`. On
|
|
168
|
+
`Navbar.Dropdown`, `Navbar.Item`, `Navbar.Link`, `ScrollArea`, `SegmentedControl`, `SegmentedControl.Segment`,
|
|
169
|
+
`Sidebar`, `Splitter`, `Splitter.Pane`, `Timeline`, `Timeline.Item`, `Toast`, `ToggleButton`, `TreeView` and `TreeView.Item`. On
|
|
170
170
|
those, rename `domRef` to `ref` and it works; do not restructure the markup. "The form controls"
|
|
171
171
|
means the inputs themselves: the `Field`, `Field.Label`, `Field.Body`, `Checkboxes` and `Radios`
|
|
172
172
|
wrappers around them forward nothing, and `Field` is a target this codemod emits.
|
|
@@ -81,7 +81,9 @@ is **more complete** than the docs page's Option C example, which omits several)
|
|
|
81
81
|
**Components** (`@allxsmith/bestax-bulma/scss/components/<name>`):
|
|
82
82
|
`loading`, `collapse`, `tooltip`, `popover`, `hovercard`, `contextmenu`, `steps`, `sidebar`,
|
|
83
83
|
`toast`, `dialog`, `carousel`, `tabs`, `menu`, `reveal`, `avatar`, `avatars`, `badge`,
|
|
84
|
-
`emptystate`, `timeline`, `treeview`
|
|
84
|
+
`emptystate`, `timeline`, `treeview`, `scrollarea`
|
|
85
|
+
|
|
86
|
+
**Layout** (`@allxsmith/bestax-bulma/scss/layout/<name>`): `splitter`
|
|
85
87
|
|
|
86
88
|
**Form** (`@allxsmith/bestax-bulma/scss/form/<name>`):
|
|
87
89
|
`checkbox`, `radio`, `switch`, `slider`, `numberinput`, `pininput`, `rate`, `autocomplete`,
|
|
@@ -16,9 +16,10 @@ Recolor a brand color by overriding its **hue/saturation/lightness trio**
|
|
|
16
16
|
follow the hue and saturation, at lightnesses the trio doesn't set. Among those, the stylesheet's
|
|
17
17
|
build picked the label on a solid color (`--bulma-<color>-invert-l`) and the color's text on the
|
|
18
18
|
page (`--bulma-<color>-on-scheme-l`, which for `link` is every link) for contrast with the color
|
|
19
|
-
it was built with, so when the new color reads lighter or darker than the built one, set them
|
|
20
|
-
|
|
21
|
-
|
|
19
|
+
it was built with, so when the new color reads lighter or darker than the built one, set them as
|
|
20
|
+
well, or labels and text lose their contrast. `Theme`'s `bulmaVars` takes both, and on an
|
|
21
|
+
`isRoot` `Theme` the on-scheme one takes a value per scheme, `{ light, dark }`
|
|
22
|
+
(`references/css-variables.md`, "Colors").
|
|
22
23
|
|
|
23
24
|
Choose an override path:
|
|
24
25
|
|
|
@@ -36,10 +37,12 @@ For **dark mode**, pass `colorMode` to `Theme` (`'light' | 'dark' | 'system'`).
|
|
|
36
37
|
`data-theme` attribute on `<html>` (plus `data-<prefix>theme` inside a `ConfigProvider` with a
|
|
37
38
|
`classPrefix`, which the prefixed flavors read), flipping the light/dark scheme — global, even on a scoped
|
|
38
39
|
`Theme`; `'system'` follows the OS `prefers-color-scheme`. Drive it from state on the app-root
|
|
39
|
-
`Theme`: `<Theme isRoot colorMode={mode}>`. `Theme` writes the attribute
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
40
|
+
`Theme`: `<Theme isRoot colorMode={mode}>`. `Theme` writes the attribute, and an `isRoot` Theme's
|
|
41
|
+
variables, before the browser paints what it rendered, but the page can paint before the app's
|
|
42
|
+
script runs at all, so the scheme of that first frame comes from `index.html`: `data-theme` on
|
|
43
|
+
the `<html>` for a scheme that never changes, or an inline `<head>` script that writes the
|
|
44
|
+
visitor's saved choice for a toggle (`examples/dark-mode.tsx`). A server render includes neither,
|
|
45
|
+
so a server-rendered page sets what it needs from its first paint in `index.html` and CSS.
|
|
43
46
|
|
|
44
47
|
## Contrast rules (dark mode is on by default)
|
|
45
48
|
|
|
@@ -52,8 +55,8 @@ color tokens or fixed-color surfaces exist:
|
|
|
52
55
|
|
|
53
56
|
- **Single-mode design → pin the scheme on `<html>`.** `<html lang="en" data-theme="light">` (or
|
|
54
57
|
`"dark"`) in `index.html`, so the first paint has it and an OS preference can never invert text
|
|
55
|
-
out from under the fixed palette. `<Theme isRoot colorMode="light">` alone sets it only
|
|
56
|
-
|
|
58
|
+
out from under the fixed palette. `<Theme isRoot colorMode="light">` alone sets it only once
|
|
59
|
+
the app's script runs, and the page can show the OS scheme before that.
|
|
57
60
|
- **Both modes → no exposed fixed tokens.** Derive custom tokens from scheme variables
|
|
58
61
|
(`--my-canvas: var(--bulma-scheme-main)`) — or flip them yourself under **both** dark-mode
|
|
59
62
|
paths: `[data-theme='dark']` **and** `@media (prefers-color-scheme: dark)` scoped to
|
|
@@ -127,7 +130,7 @@ Nest `Theme` and `ConfigProvider` together at the root (order doesn't matter).
|
|
|
127
130
|
|
|
128
131
|
## Checklist
|
|
129
132
|
|
|
130
|
-
- [ ] Recolor brand colors via the HSL trio (`*-h` / `*-s` / `*-l`), not by hard-coding hex on components
|
|
133
|
+
- [ ] Recolor brand colors via the HSL trio (`*-h` / `*-s` / `*-l`), not by hard-coding hex on components. A color that reads lighter or darker than the built one also sets `*-invert-l` and `*-on-scheme-l`, through `Theme bulmaVars` (the on-scheme one per scheme, on an `isRoot` Theme) or CSS.
|
|
131
134
|
- [ ] Apply a global theme once with `<Theme isRoot>` (or `:root`); use scoped `<Theme>` for one-off sections.
|
|
132
135
|
- [ ] Set non-color tokens (radius, fonts, sizes) through `bulmaVars` or `:root`; a custom `--bulma-family-*` needs its font actually loaded (`index.html` `<link>` or an `@fontsource` import).
|
|
133
136
|
- [ ] Implement dark mode with `data-theme` on `<html>` (plus `data-<prefix>theme` inside a `ConfigProvider` with a `classPrefix`, which the prefixed flavors read); do not expect a shipped dark-mode component.
|
|
@@ -2,12 +2,13 @@
|
|
|
2
2
|
// the visitor's choice.
|
|
3
3
|
//
|
|
4
4
|
// Bulma reads the scheme from `data-theme` on <html>. `Theme colorMode` writes
|
|
5
|
-
// that attribute
|
|
6
|
-
//
|
|
7
|
-
//
|
|
8
|
-
//
|
|
9
|
-
//
|
|
10
|
-
// `type="module"`, so it runs before the
|
|
5
|
+
// that attribute before the browser paints what the app rendered, but only
|
|
6
|
+
// once the app's script runs, and the page can paint before that, so on its
|
|
7
|
+
// own it can show the OS scheme for a frame and then flip. The scheme for
|
|
8
|
+
// that first frame comes from a script in index.html, which writes the saved
|
|
9
|
+
// choice, or else the OS preference, before anything renders. Put it inside
|
|
10
|
+
// <head> as a plain inline script, not `type="module"`, so it runs before the
|
|
11
|
+
// body renders:
|
|
11
12
|
//
|
|
12
13
|
// <script>
|
|
13
14
|
// // Bulma's scheme on <html> before the first paint: the saved choice,
|
|
@@ -12,9 +12,10 @@
|
|
|
12
12
|
// Of those built lightnesses, the label on a solid color
|
|
13
13
|
// (--bulma-<color>-invert-l) and the color's text on the page
|
|
14
14
|
// (--bulma-<color>-on-scheme-l, which for `link` is every link) were picked
|
|
15
|
-
// for contrast. A color that reads lighter or
|
|
16
|
-
//
|
|
17
|
-
// references/css-variables.md
|
|
15
|
+
// for contrast with the stylesheet's own color. A color that reads lighter or
|
|
16
|
+
// darker than that one sets them too, through bulmaVars. On an isRoot Theme
|
|
17
|
+
// the on-scheme one takes a value for each scheme. references/css-variables.md
|
|
18
|
+
// ("Colors") says how to pick them.
|
|
18
19
|
import type { ReactNode } from 'react';
|
|
19
20
|
import {
|
|
20
21
|
Theme,
|
|
@@ -37,6 +38,12 @@ export function ThemedApp({ children }: { children: ReactNode }) {
|
|
|
37
38
|
// Anything without a named prop goes through `bulmaVars`, keyed by the real
|
|
38
39
|
// --bulma-* variable names (string values).
|
|
39
40
|
bulmaVars={{
|
|
41
|
+
// Purple text reads darker than the stylesheet's blue at the same
|
|
42
|
+
// lightness, so on a dark page it needs a lighter shade than the one
|
|
43
|
+
// built for the blue. Each scheme gets its own, and these read at 4.5:1
|
|
44
|
+
// or more on Bulma's white and near-black pages. The white label the
|
|
45
|
+
// blue was built with still reads on this purple, so the invert stays.
|
|
46
|
+
'--bulma-primary-on-scheme-l': { light: '41%', dark: '65%' },
|
|
40
47
|
'--bulma-radius': '0.75rem',
|
|
41
48
|
'--bulma-radius-large': '1.25rem',
|
|
42
49
|
// 'Inter' must actually be loaded (index.html <link> or an @fontsource
|