create-bestax 4.2.12 → 4.2.13

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.
Files changed (47) hide show
  1. package/README.md +11 -2
  2. package/dist/cli.d.ts +2 -2
  3. package/dist/cli.d.ts.map +1 -1
  4. package/dist/cli.js +3 -2
  5. package/dist/constants.d.ts +7 -1
  6. package/dist/constants.d.ts.map +1 -1
  7. package/dist/constants.js +18 -3
  8. package/dist/file-system.d.ts +7 -0
  9. package/dist/file-system.d.ts.map +1 -1
  10. package/dist/file-system.js +15 -0
  11. package/dist/project-creator.d.ts +21 -1
  12. package/dist/project-creator.d.ts.map +1 -1
  13. package/dist/project-creator.js +84 -51
  14. package/dist/prompts.d.ts +7 -2
  15. package/dist/prompts.d.ts.map +1 -1
  16. package/dist/prompts.js +8 -3
  17. package/dist/validators.d.ts +7 -0
  18. package/dist/validators.d.ts.map +1 -1
  19. package/dist/validators.js +13 -1
  20. package/package.json +6 -3
  21. package/templates/skills/bestax-custom-component/SKILL.md +21 -4
  22. package/templates/skills/bestax-custom-component/examples/stat-card.tsx +1 -2
  23. package/templates/skills/bestax-custom-component/references/api.md +103 -11
  24. package/templates/skills/bestax-custom-component/references/component-catalog.md +12 -5
  25. package/templates/skills/bestax-custom-component/references/library-contributor.md +23 -0
  26. package/templates/skills/bestax-form/SKILL.md +28 -17
  27. package/templates/skills/bestax-form/references/api.md +83 -23
  28. package/templates/skills/bestax-form/references/patterns.md +19 -0
  29. package/templates/skills/bestax-layout-scaffold/SKILL.md +17 -4
  30. package/templates/skills/bestax-layout-scaffold/references/layout-components.md +22 -15
  31. package/templates/skills/bestax-migrate/SKILL.md +12 -7
  32. package/templates/skills/bestax-migrate/references/bloomer/prop-map.md +9 -9
  33. package/templates/skills/bestax-migrate/references/bloomer/unmappables.md +19 -2
  34. package/templates/skills/bestax-migrate/references/bulma-classes/component-map.md +285 -41
  35. package/templates/skills/bestax-migrate/references/bulma-classes/prop-map.md +125 -48
  36. package/templates/skills/bestax-migrate/references/bulma-classes/unmappables.md +217 -39
  37. package/templates/skills/bestax-migrate/references/rbx/component-map.md +15 -15
  38. package/templates/skills/bestax-migrate/references/rbx/prop-map.md +17 -19
  39. package/templates/skills/bestax-migrate/references/rbx/unmappables.md +17 -0
  40. package/templates/skills/bestax-migrate/references/react-bulma-components/component-map.md +34 -34
  41. package/templates/skills/bestax-migrate/references/react-bulma-components/unmappables.md +34 -7
  42. package/templates/skills/bestax-optimize/SKILL.md +3 -2
  43. package/templates/skills/bestax-optimize/references/modular-build.md +25 -5
  44. package/templates/skills/bestax-theming/SKILL.md +4 -3
  45. package/templates/skills/bestax-theming/examples/dark-mode.tsx +4 -3
  46. package/templates/skills/bestax-theming/references/css-variables.md +49 -8
  47. package/templates/skills/bestax-theming/references/themeable-components.md +12 -10
@@ -142,21 +142,21 @@ test holds to rbx's own export surface in both directions.
142
142
 
143
143
  ## The renames worth memorising
144
144
 
145
- | rbx | bestax-bulma |
146
- | ---------------------------------- | ---------------------------------------------------------------------------------------------------------- |
147
- | `Tag.Group` | `Tags` |
148
- | `Button.Group` | `Buttons` |
149
- | `Column.Group` | `Columns` |
150
- | `Card.Footer.Item` | `Card.FooterItem` |
151
- | `Table.Head` / `.Body` / `.Foot` | `Table.Thead` / `.Tbody` / `.Tfoot` |
152
- | `Table.Row` / `.Cell` / `.Heading` | `Table.Tr` / `.Td` / `.Th` |
153
- | `Textarea` | `TextArea` |
154
- | `PageLoader` | `Loading` with `isFullPage` |
155
- | `Loader` | a plain `<div className="loader">` — bestax's `Loading` is an overlay that renders nothing unless `active` |
156
- | `Menu.List.Item` | `Menu.Item` |
157
- | `Tab` / `Tab.Group` | `Tabs.Item` / `Tabs` |
158
- | `Panel.Tab.Group` | `Panel.Tabs` |
159
- | `Title subtitle` | `SubTitle` |
145
+ | rbx | bestax-bulma |
146
+ | ---------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
147
+ | `Tag.Group` | `Tags` |
148
+ | `Button.Group` | `Buttons` |
149
+ | `Column.Group` | `Columns` |
150
+ | `Card.Footer.Item` | `Card.FooterItem` |
151
+ | `Table.Head` / `.Body` / `.Foot` | `Table.Thead` / `.Tbody` / `.Tfoot` |
152
+ | `Table.Row` / `.Cell` / `.Heading` | `Table.Tr` / `.Td` / `.Th` |
153
+ | `Textarea` | `TextArea` |
154
+ | `PageLoader` | `Loading` with `isFullPage` |
155
+ | `Loader` | a plain `<div className="loader">` — bestax's `Loading` is an overlay that renders nothing unless `active`; bestax's `Loader` renders the same ring as a named progressbar, so swap it in by hand |
156
+ | `Menu.List.Item` | `Menu.Item` |
157
+ | `Tab` / `Tab.Group` | `Tabs.Item` / `Tabs` |
158
+ | `Panel.Tab.Group` | `Panel.Tabs` |
159
+ | `Title subtitle` | `SubTitle` |
160
160
 
161
161
  ## Value-chosen targets
162
162
 
@@ -140,26 +140,26 @@ that is what keeps the `href`. Dropping the `as` does not, on this component.
140
140
  rbx reaches a component's rendered element with `innerRef`. bestax uses a plain forwarded
141
141
  `ref` on the roots that support one, so the codemod renames the prop:
142
142
 
143
- | rbx | bestax-bulma | note |
144
- | ----------------------------------------------------- | ------------ | ------------------------------------------- |
145
- | `innerRef` on `Button`, `Dropdown`, `Modal`, `Navbar` | `ref` | same node — each root's own element |
146
- | `innerRef` on `Navbar.Burger`, `Navbar.Link` | `ref` | these two sub-components forward one too |
147
- | `innerRef` on `Navbar.Item` **with `dropdown`** | `ref` | that one becomes bestax's `Navbar.Dropdown` |
148
- | `innerRef` on `Modal.Container` | `ref` | that one becomes bestax's `Modal` root |
143
+ | rbx | bestax-bulma | note |
144
+ | ----------------------------------------------------- | ------------ | -------------------------------------------- |
145
+ | `innerRef` on `Button`, `Dropdown`, `Modal`, `Navbar` | `ref` | same node — each root's own element |
146
+ | `innerRef` on `Navbar.Burger`, `Navbar.Link` | `ref` | these two sub-components forward one too |
147
+ | `innerRef` on `Navbar.Item` | `ref` | with `dropdown` it becomes `Navbar.Dropdown` |
148
+ | `innerRef` on `Modal.Container` | `ref` | that one becomes bestax's `Modal` root |
149
149
 
150
150
  The third row is the `Navbar.Dropdown` collision, and it runs both ways. Your rbx
151
151
  `Navbar.Dropdown` is the menu itself (`div.navbar-dropdown`), so it maps to bestax's
152
152
  `Navbar.DropdownMenu`, which forwards no ref — `innerRef` there is left alone. bestax reserves
153
153
  the name `Navbar.Dropdown` for the outer container, which is what `<Navbar.Item dropdown>`
154
- becomes. The rename stays conditional on the `dropdown` prop because only that branch knows
155
- which of the two targets was picked, not because the other branch lacks a ref: a plain
156
- `<Navbar.Item>` forwards one too since #661, so its `innerRef` is a rename the codemod leaves
157
- for you (see the gap below).
154
+ becomes.
155
+
156
+ Beside a `ref` the element already has, a rename leaves `innerRef` in place with a `prop:innerRef`
157
+ TODO rather than write a second `ref`; keep whichever one you meant.
158
158
 
159
159
  An existing `ref` is passed through untouched — which is safe only where the bestax target
160
160
  forwards one. rbx forwards a ref on every component; bestax does so on the form controls, plus
161
161
  `Avatar`, `Button`, `Carousel`, `CarouselItem`, `Dialog`, `Dropdown`, `Link`, `LinkButton`,
162
- `Menu.Item`, `Modal`, `Navbar`, `Navbar.Burger`, `Navbar.Dropdown`, `Navbar.Item`,
162
+ `Loader`, `Menu.Item`, `Modal`, `Navbar`, `Navbar.Burger`, `Navbar.Dropdown`, `Navbar.Item`,
163
163
  `Navbar.Link`, `Sidebar` and `Toast`. "The form controls" there means the inputs themselves:
164
164
  the `Field`, `Field.Label`, `Field.Body`, `Checkboxes` and `Radios` wrappers around them
165
165
  forward nothing, and `Field` is a target this codemod emits.
@@ -174,11 +174,9 @@ outcome is one to build on: put the ref on an element you control.
174
174
  **The codemod does not flag this**, because neither the universal prop table nor any
175
175
  per-component table has a `ref` entry, so check every `ref` you carried over against the list
176
176
  above rather than assuming the silent pass-through means it works. The renames above are for
177
- `innerRef`, and apply only on those eight entries.
178
-
179
- Note the gap that leaves. An rbx `innerRef` can only land on a component rbx itself has, so of
180
- the ref-forwarding targets above the reachable ones are the form controls, `Menu.Item` and a
181
- plain `Navbar.Item`. There the codemod leaves `innerRef` in place and flags it rather than
182
- renaming it, so the rename is yours to make and the target will take it. Everywhere the eight
183
- renames above do not reach, `innerRef` is flagged the same way — but on a target that forwards
184
- nothing the answer is a wrapping element you control, not a rename.
177
+ `innerRef`, and apply only where the table says.
178
+
179
+ Note the gap that leaves. Where no row above reaches, `innerRef` stays in place and is flagged.
180
+ On a target that forwards a ref (the form controls, `Menu.Item`) the rename is yours to make and
181
+ the target will take it. On one that forwards nothing, the answer is a wrapping element you
182
+ control, not a rename.
@@ -95,6 +95,23 @@ these either. `Level.Item` is not narrower: it declares the anchor's whole attri
95
95
  every `as` and forwards it only on the `<a>`, so all of these survive at `as="a"` and none of
96
96
  them reaches a `<p>` or a `<div>`.
97
97
 
98
+ ## `prop:type` — a `<button>` item that no longer submits its form
99
+
100
+ `Navbar.Item`, `Navbar.Link`, `Menu.Item` and `Dropdown.Item` write `type="button"` on the
101
+ `<button>` an `as` makes them render, whenever the element sets no `type` or one HTML doesn't
102
+ define. A plain `<button>` with neither submits the form around it, so an item you rendered as a
103
+ button with `as="button"` stops submitting once migrated. The codemod can't tell whether one sits
104
+ in a form, so each gets a TODO:
105
+
106
+ ```jsx
107
+ <Navbar.Item as="button">Search</Navbar.Item>
108
+ <Navbar.Item as="button">Search</Navbar.Item>
109
+ ```
110
+
111
+ Add `type="submit"` if it should still submit, or `type="button"` to say it shouldn't, then
112
+ delete the comment. An item whose `type` is written out as `button`, `submit` or `reset`, or
113
+ comes from a spread or an expression, gets no TODO.
114
+
98
115
  ## `component:Generic` — rbx's base element
99
116
 
100
117
  `Generic` is rbx's untyped passthrough. Render the underlying tag, and move its helper props to
@@ -6,40 +6,40 @@ codemod converts it; **Flagged** = it leaves a `TODO(bestax-migrate)` comment (s
6
6
 
7
7
  ## Top-level components
8
8
 
9
- | RBC | bestax | Notes |
10
- | -------------- | -------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------- |
11
- | `Block` | `Block` | Auto |
12
- | `Box` | `Box` | Auto |
13
- | `Breadcrumb` | `Breadcrumb` | Auto; `align` → `alignment` (`center`→`centered`) |
14
- | `Button` | `Button` | Auto for literal `remove` (by value, not presence — truthy → `<Delete/>`, `remove={false}` stays `Button`); dynamic flagged |
15
- | `Card` | `Card` | Auto |
16
- | `Columns` | `Columns` | Auto; `breakpoint="mobile"`→`isMobile`, `multiline`→`isMultiline`, … |
17
- | `Container` | `Container` | Auto; `breakpoint="fluid"`→`fluid`, `max`→`isMax` |
18
- | `Content` | `Content` | Auto |
19
- | `Dropdown` | `Dropdown` | Structure auto; controlled `value`/`onChange` flagged |
20
- | `Element` | — | Flagged: no generic element; use a semantic component + helper props |
21
- | `Footer` | `Footer` | Auto |
22
- | `Form.*` | flat imports | See Form table below |
23
- | `Heading` | `Title` / `SubTitle` / `<p class="heading">` | Auto for literal `subtitle`/`heading` (by value, not presence — `subtitle={false}` is `Title`); dynamic value flagged |
24
- | `Hero` | `Hero` | Auto; `hasNavbar`→`fullheightWithNavbar`; `halfheight`/`gradient` flagged |
25
- | `Icon` | `Icon` | `<i class="fas fa-x">` children → `name`/`library`/`variant` props; else flagged |
26
- | `Image` | `Image` | Auto; numeric `size={128}` → `size="128x128"`, `rounded`→`isRounded` |
27
- | `Level` | `Level` | Auto; `breakpoint="mobile"`→`isMobile` |
28
- | `Loader` | plain `<div className="loader">` | Auto (Bulma v1 still ships the class) |
29
- | `Media` | `Media` | Auto |
30
- | `Menu` | `Menu` | Auto |
31
- | `Message` | `Message` | Auto; `size` flagged |
32
- | `Modal` | `Modal` | `show`→`active`, `closeOnEsc`→`closeOnEscape`; `closeOnBlur`/`showClose` flagged (compound form renders neither) |
33
- | `Navbar` | `Navbar` | Auto; see dropdown note below |
34
- | `Notification` | `Notification` | Auto; `light`→`isLight` |
35
- | `Pagination` | `Pagination` | `onChange`→`onPageChange`; `delta`/labels/`showFirstLast`/`autoHide` flagged |
36
- | `Panel` | `Panel` | Auto |
37
- | `Progress` | `Progress` | Auto |
38
- | `Section` | `Section` | Auto |
39
- | `Table` | `Table` | Auto; `size="fullwidth"`→`isFullwidth`, `striped`→`isStriped`, … |
40
- | `Tabs` | `Tabs` | Auto; children wrapped in `Tabs.List`; `type="toggle-rounded"`→`toggle rounded` |
41
- | `Tag` | `Tag` | Auto; `remove`→`isDelete`, `rounded`→`isRounded` |
42
- | `Tile` | — | Flagged: Bulma v1 replaced tiles with `Grid`/`Cell` |
9
+ | RBC | bestax | Notes |
10
+ | -------------- | -------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------- |
11
+ | `Block` | `Block` | Auto |
12
+ | `Box` | `Box` | Auto |
13
+ | `Breadcrumb` | `Breadcrumb` | Auto; `align` → `alignment` (`center`→`centered`) |
14
+ | `Button` | `Button` | Auto for literal `remove` (by value, not presence — truthy → `<Delete/>`, `remove={false}` stays `Button`); dynamic flagged |
15
+ | `Card` | `Card` | Auto |
16
+ | `Columns` | `Columns` | Auto; `breakpoint="mobile"`→`isMobile`, `multiline`→`isMultiline`, … |
17
+ | `Container` | `Container` | Auto; `breakpoint="fluid"`→`fluid`, `max`→`isMax` |
18
+ | `Content` | `Content` | Auto |
19
+ | `Dropdown` | `Dropdown` | Structure auto; controlled `value`/`onChange` flagged |
20
+ | `Element` | — | Flagged: no generic element; use a semantic component + helper props |
21
+ | `Footer` | `Footer` | Auto |
22
+ | `Form.*` | flat imports | See Form table below |
23
+ | `Heading` | `Title` / `SubTitle` / `<p class="heading">` | Auto for literal `subtitle`/`heading` (by value, not presence — `subtitle={false}` is `Title`); dynamic value flagged |
24
+ | `Hero` | `Hero` | Auto; `hasNavbar`→`fullheightWithNavbar`; `halfheight`/`gradient` flagged |
25
+ | `Icon` | `Icon` | `<i class="fas fa-x">` children → `name`/`library`/`variant` props; else flagged |
26
+ | `Image` | `Image` | Auto; numeric `size={128}` → `size="128x128"`, `rounded`→`isRounded` |
27
+ | `Level` | `Level` | Auto; `breakpoint="mobile"`→`isMobile` |
28
+ | `Loader` | plain `<div className="loader">` | Auto (Bulma v1 still ships the class); swap in bestax's `Loader` by hand for its progressbar role and accessible name |
29
+ | `Media` | `Media` | Auto |
30
+ | `Menu` | `Menu` | Auto |
31
+ | `Message` | `Message` | Auto; `size` flagged |
32
+ | `Modal` | `Modal` | `show`→`active`, `closeOnEsc`→`closeOnEscape`; `closeOnBlur`/`showClose` flagged (compound form renders neither) |
33
+ | `Navbar` | `Navbar` | Auto; see dropdown note below |
34
+ | `Notification` | `Notification` | Auto; `light`→`isLight` |
35
+ | `Pagination` | `Pagination` | `onChange`→`onPageChange`, `delta`→`siblingCount`, `next`/`previous`→`nextLabel`/`previousLabel`; `showFirstLast`/`showPrevNext`/`autoHide` flagged |
36
+ | `Panel` | `Panel` | Auto |
37
+ | `Progress` | `Progress` | Auto |
38
+ | `Section` | `Section` | Auto |
39
+ | `Table` | `Table` | Auto; `size="fullwidth"`→`isFullwidth`, `striped`→`isStriped`, … |
40
+ | `Tabs` | `Tabs` | Auto; children wrapped in `Tabs.List`; `type="toggle-rounded"`→`toggle rounded` |
41
+ | `Tag` | `Tag` | Auto; `remove`→`isDelete`, `rounded`→`isRounded` |
42
+ | `Tile` | — | Flagged: Bulma v1 replaced tiles with `Grid`/`Cell` |
43
43
 
44
44
  ## Compound sub-components
45
45
 
@@ -59,12 +59,22 @@ const [choice, setChoice] = useState('a');
59
59
  </Dropdown>;
60
60
  ```
61
61
 
62
- ## `Pagination` extras (`delta`, `next`/`previous`, `showFirstLast`, `showPrevNext`, `autoHide`)
63
-
64
- bestax `Pagination` renders from `total`/`current`/`onPageChange` with its own windowing.
65
- Drop `delta` (built-in), render conditionally instead of `autoHide`
66
- (`{total > 1 && <Pagination …/>}`), and compose `Pagination.Previous`/`Pagination.Next`
67
- manually if custom labels are essential.
62
+ ## `Pagination` extras (`showFirstLast`, `showPrevNext`, `autoHide`)
63
+
64
+ bestax `Pagination` renders from `total`/`current`/`onPageChange` when it has no children:
65
+ Previous, Next and the page links, with an ellipsis for each run it skips. The codemod writes
66
+ `delta` as `siblingCount` (the pages on each side of the current one) and `next`/`previous` as
67
+ `nextLabel`/`previousLabel`. It always shows Previous and Next, and the first and last pages
68
+ (`boundaryCount` of each, 1 by default), so drop `showPrevNext` and `showFirstLast`, or compose
69
+ the parts (`Pagination.Previous`, `Pagination.List`, `Pagination.Link`) by hand for a
70
+ different layout. Render conditionally instead of `autoHide` (`{total > 1 && <Pagination …/>}`).
71
+
72
+ Two of RBC's defaults differ, and a Pagination that doesn't write them gets no TODO: RBC hides
73
+ itself at a `total` of 1 (`autoHide` is on by default), and shows no first and last pages unless
74
+ `showFirstLast` is set. bestax renders a one-page Pagination with both ends disabled, and shows
75
+ the first and last pages, so check pagination that relied on either. RBC's `delta={0}` renders
76
+ no page links at all, while `siblingCount={0}` still shows the current, first and last pages, so
77
+ that one value gets a `prop:delta` TODO rather than converting.
68
78
 
69
79
  ## `Modal` (`closeOnBlur`, `showClose`)
70
80
 
@@ -130,7 +140,7 @@ bestax `Button` colors are the semantic set + `text`/`ghost`. For shades use
130
140
 
131
141
  bestax components don't take `domRef`, but many forward a plain `ref` — the form controls,
132
142
  plus `Avatar`, `Button`, `Carousel`, `CarouselItem`, `Dialog`, `Dropdown`, `Link`,
133
- `LinkButton`, `Menu.Item`, `Modal`, `Navbar`, `Navbar.Burger`, `Navbar.Dropdown`,
143
+ `LinkButton`, `Loader`, `Menu.Item`, `Modal`, `Navbar`, `Navbar.Burger`, `Navbar.Dropdown`,
134
144
  `Navbar.Item`, `Navbar.Link`, `Sidebar` and `Toast`. On those, rename `domRef` to
135
145
  `ref` and it works; do not restructure the markup. "The form controls" means the inputs
136
146
  themselves: the `Field`, `Field.Label`, `Field.Body`, `Checkboxes` and `Radios` wrappers
@@ -201,6 +211,23 @@ these either. `Level.Item` is not narrower: it declares the anchor's whole attri
201
211
  every `as` and forwards it only on the `<a>`, so all of these survive at `as="a"` and none of
202
212
  them reaches a `<p>` or a `<div>`.
203
213
 
214
+ ## `prop:type` — a `<button>` item that no longer submits its form
215
+
216
+ `Navbar.Item`, `Navbar.Link`, `Menu.Item` and `Dropdown.Item` write `type="button"` on the
217
+ `<button>` an `as` makes them render, whenever the element sets no `type` or one HTML doesn't
218
+ define. A plain `<button>` with neither submits the form around it, so an item you rendered as a
219
+ button with `renderAs="button"` stops submitting once migrated. The codemod can't tell whether one sits
220
+ in a form, so each gets a TODO:
221
+
222
+ ```jsx
223
+ <Navbar.Item renderAs="button">Search</Navbar.Item>
224
+ <Navbar.Item as="button">Search</Navbar.Item>
225
+ ```
226
+
227
+ Add `type="submit"` if it should still submit, or `type="button"` to say it shouldn't, then
228
+ delete the comment. An item whose `type` is written out as `button`, `submit` or `reset`, or
229
+ comes from a spread or an expression, gets no TODO.
230
+
204
231
  ## Helper props dropped from plain-element replacements
205
232
 
206
233
  Where the codemod produced a plain element (`Form.Label` → `<label>`, `Breadcrumb.Item` →
@@ -64,14 +64,15 @@ helper props compile to — components still render, but the props silently do n
64
64
  recommending it, grep the app's source for helper props on bestax components:
65
65
 
66
66
  - spacing: `m`, `mt`, `mr`, `mb`, `ml`, `mx`, `my`, `p`, `pt`, `pr`, `pb`, `pl`, `px`, `py`
67
+ - gap: `gap`, `columnGap`, `rowGap`, `gapless`, on any component, `Grid` included: its gap props render the same helper classes
67
68
  - color: `color`, `backgroundColor` (+ `colorShade`/`backgroundColorShade`), `textColor`, `bgColor`
68
69
  - typography: `textSize`, `textAlign`, `textTransform`, `textWeight`, `fontFamily`
69
70
  - display/visibility: `display`, `visibility` (+ `displayMobile`…`visibilityFullhd` viewport variants)
70
71
  - flexbox: `flexDirection`, `flexWrap`, `justifyContent`, `alignContent`, `alignItems`, `alignSelf`, `flexGrow`, `flexShrink`
71
- - misc: `float`, `overflow`, `overlay`, `interaction`, `cursor`, `radius`, `shadow`, `skeleton`, `clearfix`, `relative`, `fullHeight`
72
+ - misc: `float`, `overflow`, `overflowX`, `overflowY`, `overlay`, `interaction`, `cursor`, `radius`, `shadow`, `skeleton`, `clearfix`, `pos`, `relative`, `fullHeight`, `aspectRatio`
72
73
 
73
74
  …and for raw Bulma helper classes in `className` strings (`is-*`, `has-*`, `m*-*`, `p*-*`,
74
- `is-size-*`, `is-hidden*`, `is-flex*`). **Any hit → do not use `no-helpers`**; fall back to
75
+ `is-size-*`, `is-hidden*`, `is-flex*`, `is-gap-*`). **Any hit → do not use `no-helpers`**; fall back to
75
76
  `no-dark-mode` or Lever 2. The bestax extras helpers (`is-cursor-*`, sizing) are dropped too.
76
77
 
77
78
  ## Lever 2 — modular Sass build
@@ -70,14 +70,15 @@ Every extras partial that exists (from the library's `src/scss/**/_index.scss`
70
70
  is **more complete** than the docs page's Option C example, which omits several):
71
71
 
72
72
  **Components** (`@allxsmith/bestax-bulma/scss/components/<name>`):
73
- `loading`, `collapse`, `tooltip`, `steps`, `sidebar`, `toast`, `dialog`, `carousel`, `tabs`,
74
- `reveal`, `avatar`, `avatars`, `badge`
73
+ `loading`, `collapse`, `tooltip`, `popover`, `steps`, `sidebar`, `toast`, `dialog`, `carousel`,
74
+ `tabs`, `reveal`, `avatar`, `avatars`, `badge`
75
75
 
76
76
  **Form** (`@allxsmith/bestax-bulma/scss/form/<name>`):
77
77
  `checkbox`, `radio`, `switch`, `slider`, `numberinput`, `rate`, `autocomplete`, `taginput`,
78
- `picker-popover`, `dateinput`, `timeinput`, `datetimeinput`
78
+ `picker-popover`, `dateinput`, `timeinput`, `datetimeinput`, `daterangeinput`
79
79
 
80
- **Elements** (`@allxsmith/bestax-bulma/scss/elements/<name>`): `linkbutton`
80
+ **Elements** (`@allxsmith/bestax-bulma/scss/elements/<name>`): `linkbutton`, `loader`,
81
+ `progress`, `skeleton`
81
82
 
82
83
  **Helpers** (`@allxsmith/bestax-bulma/scss/helpers/<name>`): `cursor`, `sizing`
83
84
 
@@ -88,6 +89,19 @@ Notes:
88
89
  - Extras `Tabs` **extends** stock Bulma tabs (vertical variant) — an app using `Tabs` needs
89
90
  both `bulma/sass/components/tabs` and `@allxsmith/bestax-bulma/scss/components/tabs`.
90
91
  - `DateInput`/`TimeInput`/`DateTimeInput` also need `picker-popover`.
92
+ - `DateRangeInput` needs `daterangeinput` for its field and `dateinput` for its calendar, and
93
+ `picker-popover` too.
94
+ - `Popover.Close` renders a Bulma button, so an app using it needs `bulma/sass/elements/button`
95
+ next to `scss/components/popover`.
96
+ - `Loader` is stock Bulma styled by `bulma/sass/elements/loader`, and the `isLoading`
97
+ spinners on `Button`, `Control` and `Select` are Bulma's too. The `loader` extras partial
98
+ stops all of them under `prefers-reduced-motion: reduce`, so include it next to the Bulma
99
+ modules in any build that shows one. Its rules are `!important`, so the order of the two
100
+ `@use` lines does not matter.
101
+ - `Progress` and the skeletons are stock Bulma too (`bulma/sass/elements/progress`,
102
+ `bulma/sass/base/skeleton`). The `progress` and `skeleton` extras partials stop the
103
+ indeterminate bar's sweep and the skeleton pulse (`Skeleton`, the `skeleton` prop,
104
+ `hasSkeleton`) under `prefers-reduced-motion: reduce`, the same way and in either order.
91
105
  - Stock-Bulma form controls still need their Bulma module (`bulma/sass/form/…`); the extras
92
106
  form partials above style only the bestax-specific behavior.
93
107
  - Bulma component modules pull their own internal sub-elements — e.g.
@@ -104,11 +118,17 @@ not `flexbox` — `flexbox` holds only the alignment props. Verified failure mod
104
118
 
105
119
  ```scss
106
120
  @use 'bulma/sass/helpers/spacing'; // m*/p* props
121
+ @use 'bulma/sass/helpers/gap'; // gap/columnGap/rowGap/gapless props, Grid's gap props included
107
122
  @use 'bulma/sass/helpers/color'; // color/backgroundColor props, has-text-*/has-background-*
108
123
  @use 'bulma/sass/helpers/typography'; // textSize/textAlign/textTransform/textWeight/fontFamily
109
124
  @use 'bulma/sass/helpers/visibility'; // display/visibility props incl. display="flex" (is-flex/is-block/is-hidden*)
110
125
  @use 'bulma/sass/helpers/flexbox'; // flex* alignment props (justifyContent/alignItems/flexGrow…) — NOT display="flex"
111
- @use 'bulma/sass/helpers/other'; // overlay/interaction/radius/shadow/clearfix/relative…
126
+ @use 'bulma/sass/helpers/float'; // float/clearfix props
127
+ @use 'bulma/sass/helpers/overflow'; // overflow/overflowX/overflowY props
128
+ @use 'bulma/sass/helpers/position'; // pos/relative/overlay props
129
+ @use 'bulma/sass/helpers/border'; // radius sizes (small/normal/large/rounded)
130
+ @use 'bulma/sass/helpers/aspect-ratio'; // aspectRatio prop
131
+ @use 'bulma/sass/helpers/other'; // interaction, radius="radiusless", shadow="shadowless"
112
132
  ```
113
133
 
114
134
  ## Procedure
@@ -25,7 +25,8 @@ Choose an override path:
25
25
  - **Build-time Sass.** `@use 'bulma/sass' with ($primary: #1e6b99)` when compiling Bulma's Sass.
26
26
 
27
27
  For **dark mode**, pass `colorMode` to `Theme` (`'light' | 'dark' | 'system'`). It writes Bulma's
28
- `data-theme` attribute on `<html>`, flipping the light/dark scheme — global, even on a scoped
28
+ `data-theme` attribute on `<html>` (plus `data-<prefix>theme` inside a `ConfigProvider` with a
29
+ `classPrefix`, which the prefixed flavors read), flipping the light/dark scheme — global, even on a scoped
29
30
  `Theme`; `'system'` follows the OS `prefers-color-scheme`. Drive it from state on the app-root
30
31
  `Theme`: `<Theme isRoot colorMode={mode}>`.
31
32
 
@@ -109,13 +110,13 @@ Nest `Theme` and `ConfigProvider` together at the root (order doesn't matter).
109
110
  ## Examples
110
111
 
111
112
  - `examples/theme-config.tsx` — a custom brand theme at the app root, plus a scoped override.
112
- - `examples/dark-mode.tsx` — a light/dark toggle using Bulma's `data-theme`.
113
+ - `examples/dark-mode.tsx` — a light/dark toggle using Bulma's `data-theme` (plus `data-<prefix>theme` inside a `ConfigProvider` with a `classPrefix`).
113
114
 
114
115
  ## Checklist
115
116
 
116
117
  - [ ] Recolor brand colors via the HSL trio (`*-h` / `*-s` / `*-l`), not by hard-coding hex on components.
117
118
  - [ ] Apply a global theme once with `<Theme isRoot>` (or `:root`); use scoped `<Theme>` for one-off sections.
118
119
  - [ ] 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).
119
- - [ ] Implement dark mode with `data-theme` on `<html>`; do not expect a shipped dark-mode component.
120
+ - [ ] 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.
120
121
  - [ ] Pass `color`/`textColor`/`bgColor` (not custom CSS) to color individual components.
121
122
  - [ ] Set the icon library once with `<ConfigProvider iconLibrary="…">` at the root, not `library` on every `<Icon>`.
@@ -1,9 +1,10 @@
1
1
  // Dark mode for an app built on @allxsmith/bestax-bulma.
2
2
  //
3
3
  // The Theme component drives the light/dark scheme: pass `colorMode` and it
4
- // writes Bulma's `data-theme` attribute on <html>. This is global (even on a
5
- // scoped Theme); `'system'` removes the attribute so Bulma follows the OS
6
- // `prefers-color-scheme`. Wrap the app once at the root.
4
+ // writes Bulma's `data-theme` attribute on <html>, plus `data-<prefix>theme`
5
+ // under a ConfigProvider `classPrefix`, which the prefixed flavors read. This
6
+ // is global (even on a scoped Theme); `'system'` removes the attributes so
7
+ // Bulma follows the OS `prefers-color-scheme`. Wrap the app once at the root.
7
8
  import React, { useState } from 'react';
8
9
  import {
9
10
  Theme,
@@ -145,10 +145,11 @@ lone class or the `style` prop cannot outrank:
145
145
  styles with a selector that matches or exceeds the compound:
146
146
  `.button.link-button { --bulma-link-button-ghost-color: … }`.
147
147
  - **Constituent elements** — Tooltip's variables (all but `--bulma-tooltip-dashed-color`)
148
- are declared on `.tooltip-content`, and Sidebar's `--bulma-sidebar-overlay-background` on
149
- `.sidebar-background`. Values set via `className` or `style` land on the component root and
150
- are only inherited by the constituent, so they lose to its own declaration — target the
151
- declaring element in your CSS: `.tooltip-content { --bulma-tooltip-background: … }`.
148
+ are declared on `.tooltip-content`, Popover's on its panel, `.popover-content`, and Sidebar's
149
+ `--bulma-sidebar-overlay-background` on `.sidebar-background`. Values set via `className` or
150
+ `style` land on the component root and are only inherited by the constituent, so they lose to
151
+ its own declaration — target the declaring element in your CSS:
152
+ `.tooltip-content { --bulma-tooltip-background: … }`.
152
153
 
153
154
  ### Avatar / Avatars / Badge
154
155
 
@@ -225,15 +226,33 @@ own-selector override rule applies.
225
226
  `--bulma-collapse-margin-bottom`, `--bulma-collapse-radius`,
226
227
  `--bulma-collapse-trigger-icon-margin`, `--bulma-collapse-trigger-icon-size`
227
228
 
229
+ `--bulma-collapse-group-gap` is the exception to the own-selector rule above. It spaces the
230
+ items of a `Collapses` group, which reads it with a 0.5rem fallback and declares no value itself,
231
+ so set it on the group or on any ancestor, `:root` included. (`Theme`'s `bulmaVars` does not
232
+ list it, so set it in your CSS or through a `style` prop.)
233
+
228
234
  ### DateInput
229
235
 
230
236
  `--bulma-dateinput-cell-color`, `--bulma-dateinput-cell-disabled-color`,
231
237
  `--bulma-dateinput-cell-hover-bg`, `--bulma-dateinput-cell-other-month-color`,
232
- `--bulma-dateinput-cell-radius`, `--bulma-dateinput-cell-selected-bg`,
238
+ `--bulma-dateinput-cell-radius`, `--bulma-dateinput-cell-range-bg`,
239
+ `--bulma-dateinput-cell-range-preview-bg`, `--bulma-dateinput-cell-selected-bg`,
233
240
  `--bulma-dateinput-cell-selected-color`, `--bulma-dateinput-cell-size`,
234
241
  `--bulma-dateinput-cell-today-color`, `--bulma-dateinput-day-name-color`,
235
- `--bulma-dateinput-day-name-size`, `--bulma-dateinput-header-padding`,
236
- `--bulma-dateinput-min-width`, `--bulma-dateinput-nav-button-size`
242
+ `--bulma-dateinput-day-name-size`, `--bulma-dateinput-focus-ring-color`,
243
+ `--bulma-dateinput-header-padding`, `--bulma-dateinput-min-width`,
244
+ `--bulma-dateinput-nav-button-size`
245
+
246
+ The two `range` variables paint a range calendar (`DateRangeInput`): the band between a range's
247
+ ends, and the fainter band shown while the end is still being picked. Both are mixed from
248
+ `--bulma-dateinput-cell-selected-bg`, so `color` and an override of the selected fill re-tint
249
+ them too.
250
+
251
+ ### DateRangeInput
252
+
253
+ The field around the two inputs. Its calendar is the `DateInput` one, with the variables above.
254
+
255
+ `--bulma-daterangeinput-gap`, `--bulma-daterangeinput-separator-color`
237
256
 
238
257
  ### DateTimeInput
239
258
 
@@ -281,7 +300,7 @@ Declared on the compound `.button.link-button` — see the compound-selector exc
281
300
  `--bulma-numberinput-stepper-button-hover-bg`, `--bulma-numberinput-stepper-button-hover-color`,
282
301
  `--bulma-numberinput-stepper-width`
283
302
 
284
- ### Picker popover (DateInput / TimeInput / DateTimeInput)
303
+ ### Picker popover (DateInput / TimeInput / DateTimeInput / DateRangeInput)
285
304
 
286
305
  `--bulma-picker-popover-animation-duration`, `--bulma-picker-popover-background`,
287
306
  `--bulma-picker-popover-border-color`, `--bulma-picker-popover-offset`,
@@ -290,6 +309,18 @@ Declared on the compound `.button.link-button` — see the compound-selector exc
290
309
  `--bulma-picker-trigger-color`, `--bulma-picker-trigger-hover-color`,
291
310
  `--bulma-picker-trigger-width`
292
311
 
312
+ ### Popover
313
+
314
+ All are declared on the panel, `.popover-content`, so a panel rendered with `appendToBody` keeps
315
+ them. See the constituent-element exception above.
316
+
317
+ `--bulma-popover-animation-duration`, `--bulma-popover-background`,
318
+ `--bulma-popover-body-padding`, `--bulma-popover-border-color`, `--bulma-popover-color`,
319
+ `--bulma-popover-footer-gap`, `--bulma-popover-footer-padding`, `--bulma-popover-header-color`,
320
+ `--bulma-popover-header-padding`, `--bulma-popover-header-weight`, `--bulma-popover-max-width`,
321
+ `--bulma-popover-min-width`, `--bulma-popover-offset`, `--bulma-popover-radius`,
322
+ `--bulma-popover-shadow`, `--bulma-popover-z-index`
323
+
293
324
  ### Radio
294
325
 
295
326
  `--bulma-radio-active-color`, `--bulma-radio-background`, `--bulma-radio-border-color`,
@@ -385,6 +416,9 @@ Declared on the compound `.button.link-button` — see the compound-selector exc
385
416
  `--bulma-timeinput-wheel-radius`, `--bulma-timeinput-wheel-selected-bg`,
386
417
  `--bulma-timeinput-wheel-selected-color`, `--bulma-timeinput-wheel-width`
387
418
 
419
+ `--bulma-timeinput-wheel-item-height` is registered but has no effect: the component sets each
420
+ wheel item's height inline.
421
+
388
422
  ### Toast
389
423
 
390
424
  `--bulma-toast-action-hover-opacity`, `--bulma-toast-action-radius`,
@@ -423,6 +457,13 @@ Under the hood this is Bulma 1.x's own mechanism — `[data-theme="dark"]` / `.t
423
457
  (plus the `prefers-color-scheme` media query). Setting the attribute by hand still works
424
458
  (`document.documentElement.setAttribute('data-theme', 'dark')`); `colorMode` just does it for you.
425
459
 
460
+ A prefixed flavor names the attribute after its prefix: `bestax-prefixed.css` and
461
+ `bestax-no-helpers-prefixed.css` read `data-bestax-theme` (and `.bestax-theme-dark`), never
462
+ `data-theme`. Under `<ConfigProvider classPrefix="bestax-">`, `colorMode` writes both attributes,
463
+ so it works with those flavors. Setting it by hand there means setting `data-bestax-theme`, and
464
+ custom dark-mode CSS keyed off `[data-theme='dark']` still matches, because `colorMode` writes
465
+ `data-theme` too.
466
+
426
467
  Under dark mode Bulma flips the scheme/text/border/background lightness variables (e.g.
427
468
  `--bulma-scheme-main-l` 100% → 9%, `--bulma-text-l` 29% → 71%). Your brand color overrides from
428
469
  `Theme isRoot` or `:root` still apply on top, because they set the hue/saturation/lightness
@@ -61,10 +61,12 @@ Shades (`colorShade` / `backgroundColorShade`): `00, 05, 10, … 95, invert, lig
61
61
  | `Autocomplete` | `primary \| link \| info \| success \| warning \| danger` | `small \| medium \| large` | the 6 only |
62
62
  | `Checkbox` | `primary \| link \| info \| success \| warning \| danger` | `small \| normal \| medium \| large` | the 6 only |
63
63
  | `DateInput` | `primary \| link \| info \| success \| warning \| danger` | `small \| medium \| large` | also `isRounded` |
64
+ | `DateRangeInput` | `primary \| link \| info \| success \| warning \| danger` | `small \| medium \| large` | also `isRounded`; `color` also fills the calendar range |
64
65
  | `DateTimeInput` | `primary \| link \| info \| success \| warning \| danger` | `small \| medium \| large` | also `isRounded` |
65
66
  | `File` | `primary \| link \| info \| success \| warning \| danger \| black \| dark \| light \| white` | `small \| medium \| large` | also `isBoxed`, `isFullwidth` |
66
67
  | `Hero` | every `validColors` member + `inherit`/`current` (the `-bis`/`-ter` shades, the greys, `inherit` and `current` deprecated: no CSS, dev-warn, removed next major — see ⚠️) | `small \| medium \| large \| fullheight \| fullheight-with-navbar` | section background |
67
68
  | `LinkButton` | `primary \| link \| info \| success \| warning \| danger \| white \| light \| dark \| black` | — | button-styled link; emits `link-button-<color>` — **no `isLight`/`isOutlined`/`isInverted`** |
69
+ | `Loader` | — (no color props: the ring is drawn in `--bulma-border`) | — (the ring is `1em`; size it with `textSize`) | for a colored spinner over a region, use `Loading` |
68
70
  | `Loading` | `primary \| link \| info \| success \| warning \| danger` | `small \| medium \| large` | spinner color; default light grey |
69
71
  | `Navbar` | `primary \| link \| info \| success \| warning \| danger \| black \| dark \| light \| white` | — | — |
70
72
  | `Numberinput` | `primary \| link \| info \| success \| warning \| danger \| light \| dark` | `small \| medium \| large` | also `inputColor` (the 6) for the inner input |
@@ -79,7 +81,7 @@ Shades (`colorShade` / `backgroundColorShade`): `00, 05, 10, … 95, invert, lig
79
81
  | `Switch` | `primary \| link \| info \| success \| warning \| danger` | `small \| normal \| medium \| large` | also `isRounded`, `isThin`, `isOutlined` |
80
82
  | `Tabs` | `primary \| link \| info \| success \| warning \| danger \| black \| dark \| light \| white` | `small \| medium \| large` | **entire `color` prop deprecated** (no CSS ships; dev-warn; removal next major) |
81
83
  | `Taginput` | `primary \| link \| info \| success \| warning \| danger` | `small \| medium \| large` | also `tagColor` (the 6 + `dark \| light`) for the tags |
82
- | `TextArea` | `primary \| link \| info \| success \| warning \| danger \| black \| dark \| light \| white` | `small \| medium \| large` | also `isRounded`, `isStatic` |
84
+ | `TextArea` | `primary \| link \| info \| success \| warning \| danger \| black \| dark \| light \| white` | `small \| medium \| large` | — |
83
85
  | `TimeInput` | `primary \| link \| info \| success \| warning \| danger` | `small \| medium \| large` | — |
84
86
  | `Tooltip` | `primary \| link \| info \| success \| warning \| danger \| dark \| light` | `small \| medium \| large` | — |
85
87
  | `Tr` / `Td` / `Th` | `primary \| link \| info \| success \| warning \| danger \| black \| dark \| light \| white` | — | cell background; cells take `textAlign`/`textWeight`/`textSize` directly |
@@ -90,15 +92,15 @@ entries follow the scheme variables.
90
92
 
91
93
  ## Typography & misc helper props (on most components)
92
94
 
93
- | Prop | Accepts | Class |
94
- | -------------------------------------------- | --------------------------------------------------------- | ---------------------- |
95
- | `textSize` | `1 \| 2 \| 3 \| 4 \| 5 \| 6 \| 7` | `is-size-<n>` |
96
- | `textWeight` | `light \| normal \| medium \| semibold \| bold` | `has-text-weight-<w>` |
97
- | `fontFamily` | `sans-serif \| monospace \| primary \| secondary \| code` | `is-family-<f>` |
98
- | `textAlign` | `centered \| justified \| left \| right` | `has-text-<a>` |
99
- | `radius` | `radiusless` | `is-radiusless` |
100
- | `shadow` | `shadowless` | `is-shadowless` |
101
- | `m` / `p` (+ `mt/mr/mb/ml/mx/my`, `pt/…/py`) | `0 \| 1 \| 2 \| 3 \| 4 \| 5 \| 6 \| auto` | `m-<n>` / `p-<n>` etc. |
95
+ | Prop | Accepts | Class |
96
+ | -------------------------------------------- | --------------------------------------------------------- | --------------------------------- |
97
+ | `textSize` | `1 \| 2 \| 3 \| 4 \| 5 \| 6 \| 7` | `is-size-<n>` |
98
+ | `textWeight` | `light \| normal \| medium \| semibold \| bold` | `has-text-weight-<w>` |
99
+ | `fontFamily` | `sans-serif \| monospace \| primary \| secondary \| code` | `is-family-<f>` |
100
+ | `textAlign` | `centered \| justified \| left \| right` | `has-text-<a>` |
101
+ | `radius` | `radiusless \| small \| normal \| large \| rounded` | `is-radiusless`, `has-radius-<r>` |
102
+ | `shadow` | `shadowless` | `is-shadowless` |
103
+ | `m` / `p` (+ `mt/mr/mb/ml/mx/my`, `pt/…/py`) | `0 \| 1 \| 2 \| 3 \| 4 \| 5 \| 6 \| auto` | `m-<n>` / `p-<n>` etc. |
102
104
 
103
105
  These map to Bulma utility classes that read the same `--bulma-*` variables, so a custom theme
104
106
  flows through them automatically.