bestax-mcp 0.0.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 +90 -0
- package/data/catalog.json +1869 -0
- package/data/components/Autocomplete.json +604 -0
- package/data/components/Avatar.json +220 -0
- package/data/components/Avatars.json +294 -0
- package/data/components/Badge.json +261 -0
- package/data/components/Block.json +105 -0
- package/data/components/Box.json +157 -0
- package/data/components/Breadcrumb.json +155 -0
- package/data/components/Button.json +599 -0
- package/data/components/Buttons.json +533 -0
- package/data/components/Card.json +506 -0
- package/data/components/Carousel.json +512 -0
- package/data/components/Cell.json +154 -0
- package/data/components/Checkbox.json +176 -0
- package/data/components/Checkboxes.json +240 -0
- package/data/components/Code.json +128 -0
- package/data/components/Collapse.json +218 -0
- package/data/components/Column.json +284 -0
- package/data/components/Columns.json +542 -0
- package/data/components/ConfigProvider.json +16 -0
- package/data/components/Container.json +149 -0
- package/data/components/Content.json +228 -0
- package/data/components/Control.json +484 -0
- package/data/components/DateInput.json +872 -0
- package/data/components/DateTimeInput.json +952 -0
- package/data/components/Delete.json +153 -0
- package/data/components/Dialog.json +285 -0
- package/data/components/Divider.json +68 -0
- package/data/components/Dropdown.json +353 -0
- package/data/components/Emphasis.json +99 -0
- package/data/components/Field.json +539 -0
- package/data/components/Figure.json +143 -0
- package/data/components/File.json +403 -0
- package/data/components/Footer.json +109 -0
- package/data/components/Grid.json +357 -0
- package/data/components/Hero.json +340 -0
- package/data/components/Icon.json +232 -0
- package/data/components/IconText.json +307 -0
- package/data/components/Image.json +166 -0
- package/data/components/Input.json +583 -0
- package/data/components/Level.json +332 -0
- package/data/components/Link.json +154 -0
- package/data/components/LinkButton.json +247 -0
- package/data/components/ListItem.json +101 -0
- package/data/components/Loading.json +323 -0
- package/data/components/Media.json +345 -0
- package/data/components/Menu.json +317 -0
- package/data/components/Message.json +303 -0
- package/data/components/Modal.json +444 -0
- package/data/components/Navbar.json +996 -0
- package/data/components/Notification.json +165 -0
- package/data/components/Numberinput.json +364 -0
- package/data/components/OrderedList.json +189 -0
- package/data/components/Pagination.json +619 -0
- package/data/components/Panel.json +582 -0
- package/data/components/Paragraph.json +107 -0
- package/data/components/Pre.json +114 -0
- package/data/components/Progress.json +137 -0
- package/data/components/Radio.json +164 -0
- package/data/components/Radios.json +240 -0
- package/data/components/Rate.json +466 -0
- package/data/components/Reveal.json +177 -0
- package/data/components/Section.json +123 -0
- package/data/components/Select.json +526 -0
- package/data/components/Sidebar.json +488 -0
- package/data/components/Skeleton.json +162 -0
- package/data/components/Slider.json +534 -0
- package/data/components/Span.json +100 -0
- package/data/components/Steps.json +452 -0
- package/data/components/Strong.json +105 -0
- package/data/components/SubTitle.json +233 -0
- package/data/components/Switch.json +291 -0
- package/data/components/Table.json +490 -0
- package/data/components/Tabs.json +592 -0
- package/data/components/Tag.json +197 -0
- package/data/components/Taginput.json +587 -0
- package/data/components/Tags.json +181 -0
- package/data/components/TextArea.json +483 -0
- package/data/components/Theme.json +65 -0
- package/data/components/TimeInput.json +906 -0
- package/data/components/Title.json +240 -0
- package/data/components/Toast.json +308 -0
- package/data/components/Tooltip.json +212 -0
- package/data/components/UnorderedList.json +149 -0
- package/data/components/Valid value constants.json +16 -0
- package/data/components/classNames.json +65 -0
- package/data/components/useBulmaClasses.json +169 -0
- package/data/components/usePrefixedClassNames.json +25 -0
- package/data/skills/bestax-custom-component/SKILL.md +196 -0
- package/data/skills/bestax-custom-component/examples/stat-card.tsx +105 -0
- package/data/skills/bestax-custom-component/references/api.md +90 -0
- package/data/skills/bestax-custom-component/references/component-catalog.md +149 -0
- package/data/skills/bestax-custom-component/references/library-contributor.md +395 -0
- package/data/skills/bestax-custom-component/references/patterns.md +136 -0
- package/data/skills/bestax-form/SKILL.md +254 -0
- package/data/skills/bestax-form/references/api.md +103 -0
- package/data/skills/bestax-form/references/patterns.md +210 -0
- package/data/skills/bestax-icons/SKILL.md +80 -0
- package/data/skills/bestax-icons/examples/icon-usage.tsx +80 -0
- package/data/skills/bestax-icons/references/icon-libraries.md +131 -0
- package/data/skills/bestax-layout-scaffold/SKILL.md +196 -0
- package/data/skills/bestax-layout-scaffold/examples/app-shell.tsx +86 -0
- package/data/skills/bestax-layout-scaffold/examples/card-grid.tsx +106 -0
- package/data/skills/bestax-layout-scaffold/examples/centered.tsx +56 -0
- package/data/skills/bestax-layout-scaffold/examples/content-page.tsx +90 -0
- package/data/skills/bestax-layout-scaffold/examples/landing.tsx +122 -0
- package/data/skills/bestax-layout-scaffold/references/archetypes.md +246 -0
- package/data/skills/bestax-layout-scaffold/references/layout-components.md +269 -0
- package/data/skills/bestax-migrate/SKILL.md +78 -0
- package/data/skills/bestax-migrate/references/component-map.md +91 -0
- package/data/skills/bestax-migrate/references/css-migration.md +100 -0
- package/data/skills/bestax-migrate/references/prop-map.md +48 -0
- package/data/skills/bestax-migrate/references/unmappables.md +124 -0
- package/data/skills/bestax-optimize/SKILL.md +131 -0
- package/data/skills/bestax-optimize/references/modular-build.md +173 -0
- package/data/skills/bestax-theming/SKILL.md +117 -0
- package/data/skills/bestax-theming/examples/dark-mode.tsx +38 -0
- package/data/skills/bestax-theming/examples/theme-config.tsx +60 -0
- package/data/skills/bestax-theming/references/css-variables.md +466 -0
- package/data/skills/bestax-theming/references/themeable-components.md +119 -0
- package/data/skills.json +148 -0
- package/dist/data.d.ts +131 -0
- package/dist/data.d.ts.map +1 -0
- package/dist/data.js +111 -0
- package/dist/format.d.ts +37 -0
- package/dist/format.d.ts.map +1 -0
- package/dist/format.js +178 -0
- package/dist/helper-props.d.ts +57 -0
- package/dist/helper-props.d.ts.map +1 -0
- package/dist/helper-props.js +249 -0
- package/dist/index.d.ts +3 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +18 -0
- package/dist/search.d.ts +32 -0
- package/dist/search.d.ts.map +1 -0
- package/dist/search.js +194 -0
- package/dist/server.d.ts +28 -0
- package/dist/server.d.ts.map +1 -0
- package/dist/server.js +616 -0
- package/dist/version.d.ts +29 -0
- package/dist/version.d.ts.map +1 -0
- package/dist/version.js +147 -0
- package/package.json +70 -0
|
@@ -0,0 +1,124 @@
|
|
|
1
|
+
# Recipes for every TODO(bestax-migrate) the codemod leaves
|
|
2
|
+
|
|
3
|
+
Work through `grep -rn "TODO(bestax-migrate)" src/` with these. Delete each comment once
|
|
4
|
+
the site is converted.
|
|
5
|
+
|
|
6
|
+
## `unsupported-file` — `.astro` / `.vue` / `.svelte` / `.mdx` imports
|
|
7
|
+
|
|
8
|
+
The codemod can't parse these formats, so files in them that import
|
|
9
|
+
react-bulma-components are reported (not rewritten). Migrate them by hand: swap the
|
|
10
|
+
import to `@allxsmith/bestax-bulma` and apply the same renames the component/prop maps
|
|
11
|
+
describe — the mapping is identical, only the rewriting is manual.
|
|
12
|
+
|
|
13
|
+
## `peer-deps` — install-blocking version conflicts
|
|
14
|
+
|
|
15
|
+
Reported from package.json, not a code TODO. bestax-bulma's peers: **React ^18 || ^19**
|
|
16
|
+
(upgrade react/react-dom before installing — RBC v4 also ran on 17) and optional
|
|
17
|
+
**@fortawesome/fontawesome-free ^6.7 || ^7** (FA 5 apps: upgrade, or
|
|
18
|
+
`npm install --legacy-peer-deps` and keep FA 5 for your own `<i>` tags).
|
|
19
|
+
|
|
20
|
+
## `Element` — no generic element
|
|
21
|
+
|
|
22
|
+
bestax has no `Element`. Pick the semantic component (`Block`, `Box`, `Content`, …) that
|
|
23
|
+
matches the usage, or plain JSX with classes:
|
|
24
|
+
|
|
25
|
+
```tsx
|
|
26
|
+
// Before
|
|
27
|
+
<Element renderAs="span" textColor="grey" m={2}>…</Element>
|
|
28
|
+
// After
|
|
29
|
+
<Span textColor="grey" m="2">…</Span> // bestax exports Span/Paragraph/Strong/etc.
|
|
30
|
+
```
|
|
31
|
+
|
|
32
|
+
## `Tile` — Bulma v1 replaced tiles with Grid
|
|
33
|
+
|
|
34
|
+
Convert ancestor/parent/child tile trees to `Grid`/`Cell` (docs:
|
|
35
|
+
https://bestax.io/docs/api/grid/grid):
|
|
36
|
+
|
|
37
|
+
```tsx
|
|
38
|
+
// Before
|
|
39
|
+
<Tile kind="ancestor"><Tile kind="parent" size={8}><Tile kind="child">A</Tile></Tile></Tile>
|
|
40
|
+
// After
|
|
41
|
+
<Grid><Cell colSpan={8}>A</Cell></Grid>
|
|
42
|
+
```
|
|
43
|
+
|
|
44
|
+
Match the old proportions with `Cell` span props; tiles' `vertical` becomes grid flow.
|
|
45
|
+
|
|
46
|
+
## Controlled `Dropdown` (`value` / `onChange`, `Dropdown.Item value`)
|
|
47
|
+
|
|
48
|
+
bestax `Dropdown` is compositional — you own the selection state:
|
|
49
|
+
|
|
50
|
+
```tsx
|
|
51
|
+
const [choice, setChoice] = useState('a');
|
|
52
|
+
<Dropdown label={labels[choice]} closeOnClick>
|
|
53
|
+
<Dropdown.Item active={choice === 'a'} onClick={() => setChoice('a')}>
|
|
54
|
+
First
|
|
55
|
+
</Dropdown.Item>
|
|
56
|
+
<Dropdown.Item active={choice === 'b'} onClick={() => setChoice('b')}>
|
|
57
|
+
Second
|
|
58
|
+
</Dropdown.Item>
|
|
59
|
+
</Dropdown>;
|
|
60
|
+
```
|
|
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.
|
|
68
|
+
|
|
69
|
+
## `Modal` (`closeOnEsc`, `closeOnBlur`, `showClose`)
|
|
70
|
+
|
|
71
|
+
bestax `Modal` already closes on Esc and background click and shows the close button
|
|
72
|
+
whenever `onClose` is set — usually just delete these props. To hide the close button,
|
|
73
|
+
omit `onClose` and render your own close control.
|
|
74
|
+
|
|
75
|
+
## `touch` / `untilWidescreen` / `untilFullhd` / `{ only: true }` breakpoints
|
|
76
|
+
|
|
77
|
+
No bestax helper-prop variants exist. Use Bulma classes directly:
|
|
78
|
+
`className="is-hidden-touch"`, `is-flex-tablet-only`, etc. (all still exist in Bulma v1).
|
|
79
|
+
|
|
80
|
+
## Icon children the parser couldn't read
|
|
81
|
+
|
|
82
|
+
bestax `Icon` renders from `name` + `library` (+ `variant` for Font Awesome styles):
|
|
83
|
+
|
|
84
|
+
```tsx
|
|
85
|
+
<Icon name="github" library="fa" variant="brands" ariaLabel="GitHub" />
|
|
86
|
+
```
|
|
87
|
+
|
|
88
|
+
For icon fonts other than Font Awesome/MDI, see the `bestax-icons` skill.
|
|
89
|
+
|
|
90
|
+
## Dynamic values (`state={x}`, `textSize={n}`, `align={side}`, …)
|
|
91
|
+
|
|
92
|
+
The codemod only rewrites literals. Convert the expression at its source, e.g.:
|
|
93
|
+
|
|
94
|
+
```tsx
|
|
95
|
+
// Before: <Button state={hovered ? 'hover' : undefined}>
|
|
96
|
+
<Button isHovered={hovered}>
|
|
97
|
+
// Before: <Block textSize={n}>
|
|
98
|
+
<Block textSize={String(n) as '1' | '2' | '3' | '4' | '5' | '6' | '7'}>
|
|
99
|
+
```
|
|
100
|
+
|
|
101
|
+
## Button shade colors (`black-bis`, `grey-light`, …) and `isSelected`
|
|
102
|
+
|
|
103
|
+
bestax `Button` colors are the semantic set + `text`/`ghost`. For shades use
|
|
104
|
+
`bgColor`/`textColor` (they accept the full palette incl. shades), and replace
|
|
105
|
+
`isSelected` with `className="is-selected"` inside grouped buttons.
|
|
106
|
+
|
|
107
|
+
## `colorVariant` / Hero `gradient` / Hero `halfheight`
|
|
108
|
+
|
|
109
|
+
- `colorVariant="light"` → `isLight` where supported (Button, Notification), otherwise a
|
|
110
|
+
shade: `bgColor="primary-90"`.
|
|
111
|
+
- Bulma v1 removed `is-bold` hero gradients — delete `gradient` or restyle with CSS.
|
|
112
|
+
- `halfheight` has no bestax size; use `size="medium"` or a CSS height.
|
|
113
|
+
|
|
114
|
+
## `domRef`
|
|
115
|
+
|
|
116
|
+
bestax components don't take `domRef`. Most don't forward refs either — attach the ref to
|
|
117
|
+
a DOM element inside, or wrap the component in a `<div ref={…}>`.
|
|
118
|
+
|
|
119
|
+
## Helper props dropped from plain-element replacements
|
|
120
|
+
|
|
121
|
+
Where the codemod produced a plain element (`Form.Label` → `<label>`, `Breadcrumb.Item` →
|
|
122
|
+
`<li>`, `Table.Container` fallback `<div>`), Bulma helper props were dropped with a TODO.
|
|
123
|
+
Re-express them as classes: `m={2}` → `className="m-2"`, `textAlign="center"` →
|
|
124
|
+
`className="has-text-centered"`.
|
|
@@ -0,0 +1,131 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: bestax-optimize
|
|
3
|
+
description: Reduce the built CSS size of an app using @allxsmith/bestax-bulma — measure raw and gzip size, then apply the cheapest lever that fits (lighter prebuilt CSS flavor, hand-rolled modular Sass build, import and icon-asset hygiene). Use when the CSS bundle looks too big, a size budget or Lighthouse audit flags stylesheet weight, switching bestax.css to a versions/*.css flavor, or setting up a modular @use Bulma/Sass build.
|
|
4
|
+
license: MIT
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
# Optimizing CSS size with @allxsmith/bestax-bulma
|
|
8
|
+
|
|
9
|
+
The JS side is tree-shakable (the **entire** library is ~49 KB min+gzip). The stylesheet is
|
|
10
|
+
not: a prebuilt flavor ships all of Bulma + the bestax extras regardless of which components
|
|
11
|
+
the app renders. Judge stylesheet weight by the **gzipped** transfer size — never the raw
|
|
12
|
+
`dist/` number.
|
|
13
|
+
|
|
14
|
+
## Always measure first
|
|
15
|
+
|
|
16
|
+
Run the production build, then measure the built CSS — raw and gzip:
|
|
17
|
+
|
|
18
|
+
```sh
|
|
19
|
+
npm run build
|
|
20
|
+
wc -c dist/assets/*.css # raw bytes (what Vite reports)
|
|
21
|
+
gzip -c dist/assets/*.css | wc -c # transfer bytes (what users download)
|
|
22
|
+
```
|
|
23
|
+
|
|
24
|
+
Re-measure after **every** step below and report the before/after delta (raw + gzip). Never
|
|
25
|
+
claim a saving without a number.
|
|
26
|
+
|
|
27
|
+
⚠️ **~800 KB raw is ~82 KB over the wire.** Seeing ~800 KB of CSS in `dist/` is expected
|
|
28
|
+
with the default flavor, not a build misconfiguration — servers and CDNs gzip/brotli by
|
|
29
|
+
default. If the gzip number is already within the app's budget, say so and stop: "your CSS is
|
|
30
|
+
already fine" is a valid, honest outcome.
|
|
31
|
+
|
|
32
|
+
## Decision flow
|
|
33
|
+
|
|
34
|
+
Cheapest first. Use only the library's own shipped CSS builds and SCSS sources — do not add
|
|
35
|
+
third-party build plugins (no CSS purgers/post-processors).
|
|
36
|
+
|
|
37
|
+
1. **Flavor switch** — one-line import change, minutes (up to ~15 KB gzip).
|
|
38
|
+
2. **Modular Sass build** — small `@use` file, the biggest honest win.
|
|
39
|
+
3. **Import & icon-asset hygiene** — minor; JS and icon fonts, not the Bulma CSS.
|
|
40
|
+
|
|
41
|
+
## Lever 1 — lighter prebuilt flavor
|
|
42
|
+
|
|
43
|
+
Swap the single CSS import (in `src/main.tsx` / `src/main.jsx`) between the shipped flavors.
|
|
44
|
+
Measured sizes drift slightly between releases — hence measure:
|
|
45
|
+
|
|
46
|
+
| Flavor | Import | Raw | Gzip |
|
|
47
|
+
| ------------ | -------------------------------------------------------------------- | -----: | -----: |
|
|
48
|
+
| complete | `import '@allxsmith/bestax-bulma/bestax.css';` | ~800KB | ~82 KB |
|
|
49
|
+
| no-dark-mode | `import '@allxsmith/bestax-bulma/versions/bestax-no-dark-mode.css';` | ~680KB | ~70 KB |
|
|
50
|
+
| no-helpers | `import '@allxsmith/bestax-bulma/versions/bestax-no-helpers.css';` | ~595KB | ~67 KB |
|
|
51
|
+
|
|
52
|
+
Prefixed variants (`versions/bestax-prefixed.css` ~875 KB/~84 KB,
|
|
53
|
+
`versions/bestax-no-helpers-prefixed.css` ~655 KB/~69 KB) exist for CSS-collision
|
|
54
|
+
**compatibility, not size** — a prefixed flavor must pair with
|
|
55
|
+
`<ConfigProvider classPrefix="bestax-">` at the app root, and switching a non-prefixed app to
|
|
56
|
+
one is never a size optimization.
|
|
57
|
+
|
|
58
|
+
- `no-dark-mode` (~12 KB gzip saved) — only when the app pins a single color scheme (a fixed
|
|
59
|
+
`Theme colorMode` / `data-theme`).
|
|
60
|
+
- `no-helpers` (~15 KB gzip saved) — **hard gate below**.
|
|
61
|
+
|
|
62
|
+
⚠️ **The `no-helpers` gate: check for helper props first.** That flavor drops every class the
|
|
63
|
+
helper props compile to — components still render, but the props silently do nothing. Before
|
|
64
|
+
recommending it, grep the app's source for helper props on bestax components:
|
|
65
|
+
|
|
66
|
+
- spacing: `m`, `mt`, `mr`, `mb`, `ml`, `mx`, `my`, `p`, `pt`, `pr`, `pb`, `pl`, `px`, `py`
|
|
67
|
+
- color: `color`, `backgroundColor` (+ `colorShade`/`backgroundColorShade`), `textColor`, `bgColor`
|
|
68
|
+
- typography: `textSize`, `textAlign`, `textTransform`, `textWeight`, `fontFamily`
|
|
69
|
+
- display/visibility: `display`, `visibility` (+ `displayMobile`…`visibilityFullhd` viewport variants)
|
|
70
|
+
- flexbox: `flexDirection`, `flexWrap`, `justifyContent`, `alignContent`, `alignItems`, `alignSelf`, `flexGrow`, `flexShrink`
|
|
71
|
+
- misc: `float`, `overflow`, `overlay`, `interaction`, `cursor`, `radius`, `shadow`, `skeleton`, `clearfix`, `relative`, `fullHeight`
|
|
72
|
+
|
|
73
|
+
…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
|
+
`no-dark-mode` or Lever 2. The bestax extras helpers (`is-cursor-*`, sizing) are dropped too.
|
|
76
|
+
|
|
77
|
+
## Lever 2 — modular Sass build
|
|
78
|
+
|
|
79
|
+
Compile only the Bulma modules + bestax extras partials the app actually uses. Needs the
|
|
80
|
+
`sass` compiler as a dev dependency (Bulma's own build tool — Vite compiles `.scss` natively):
|
|
81
|
+
|
|
82
|
+
```sh
|
|
83
|
+
npm install -D sass
|
|
84
|
+
```
|
|
85
|
+
|
|
86
|
+
Create `src/styles.scss` — base + themes always come first:
|
|
87
|
+
|
|
88
|
+
```scss
|
|
89
|
+
// Configure shared variables FIRST (before anything loads utilities) —
|
|
90
|
+
// the prebuilt flavors set this brand primary; omit it and buttons revert
|
|
91
|
+
// to Bulma's default turquoise:
|
|
92
|
+
@use 'bulma/sass/utilities' with (
|
|
93
|
+
$primary: #1e6b99
|
|
94
|
+
);
|
|
95
|
+
|
|
96
|
+
// Required base: reset + CSS variable definitions
|
|
97
|
+
@use 'bulma/sass/base';
|
|
98
|
+
@use 'bulma/sass/themes';
|
|
99
|
+
|
|
100
|
+
// One line per stock Bulma component the app imports…
|
|
101
|
+
@use 'bulma/sass/elements/button';
|
|
102
|
+
@use 'bulma/sass/components/navbar';
|
|
103
|
+
// …and per bestax extras component:
|
|
104
|
+
@use '@allxsmith/bestax-bulma/scss/components/dialog';
|
|
105
|
+
// Helper categories only if the app uses those helper props:
|
|
106
|
+
@use 'bulma/sass/helpers/spacing';
|
|
107
|
+
```
|
|
108
|
+
|
|
109
|
+
Then replace the prebuilt CSS import in `src/main.tsx` with `import './styles.scss';`,
|
|
110
|
+
build, and measure. Derive the `@use` list from the components the app imports from
|
|
111
|
+
`@allxsmith/bestax-bulma` — the full component→partial mapping, the authoritative extras
|
|
112
|
+
partial inventory, and a worked example are in `references/modular-build.md`.
|
|
113
|
+
|
|
114
|
+
## Lever 3 — import & icon-asset hygiene (minor)
|
|
115
|
+
|
|
116
|
+
- **Named imports.** `import * as Bestax from '@allxsmith/bestax-bulma'` defeats tree
|
|
117
|
+
shaking. Convert to named imports (`import { Button, Card } from …`) — a JS-side saving
|
|
118
|
+
(whole library ≈ 49 KB min+gzip), so report it honestly as minor.
|
|
119
|
+
- **Unused icon libraries.** Scaffolded apps may carry an icon library the app never uses:
|
|
120
|
+
icon-font packages in `package.json` (`@fortawesome/fontawesome-free`, `@mdi/font`,
|
|
121
|
+
`material-icons`, `material-symbols`) with their CSS imports in `src/main.*`, or Ionicons
|
|
122
|
+
CDN `<script>` tags in `index.html`. Icon fonts often outweigh Bulma itself — if no
|
|
123
|
+
`<Icon>` uses that library, delete the dependency/import/script. Pure win, no tooling.
|
|
124
|
+
|
|
125
|
+
## References
|
|
126
|
+
|
|
127
|
+
- `references/modular-build.md` — full Lever 2 procedure: component→partial mapping, the
|
|
128
|
+
authoritative extras partial inventory, helper categories, and a worked `styles.scss`.
|
|
129
|
+
- Docs: [Optimizing CSS Size](https://bestax.io/docs/guides/getting-started/optimizing-css) ·
|
|
130
|
+
[Modular — Option C](https://bestax.io/docs/guides/getting-started/modular#option-c--hand-rolled-modular-scss-advanced) ·
|
|
131
|
+
[CSS Variations](https://bestax.io/docs/guides/getting-started/variations#file-size-comparison)
|
|
@@ -0,0 +1,173 @@
|
|
|
1
|
+
# Modular Sass build — component→partial mapping and procedure
|
|
2
|
+
|
|
3
|
+
Build a stylesheet containing only what the app uses, from the library's own SCSS sources.
|
|
4
|
+
This is the "Option C" pattern from the
|
|
5
|
+
[Modular guide](https://bestax.io/docs/guides/getting-started/modular#option-c--hand-rolled-modular-scss-advanced).
|
|
6
|
+
|
|
7
|
+
## Prerequisites
|
|
8
|
+
|
|
9
|
+
```sh
|
|
10
|
+
npm install -D sass
|
|
11
|
+
```
|
|
12
|
+
|
|
13
|
+
`sass` is Bulma's own compiler, dev-only. Vite compiles `.scss` out of the box — no plugin.
|
|
14
|
+
`bulma` is already present as a dependency of `@allxsmith/bestax-bulma`, and the library
|
|
15
|
+
publishes its SCSS sources (`src/scss` ships in the npm package, exposed via the
|
|
16
|
+
`@allxsmith/bestax-bulma/scss/*` export).
|
|
17
|
+
|
|
18
|
+
## The required base — always first
|
|
19
|
+
|
|
20
|
+
```scss
|
|
21
|
+
// Configure shared variables FIRST — a Sass module can only be configured on
|
|
22
|
+
// its first load, and every Bulma module loads utilities internally. The
|
|
23
|
+
// prebuilt bestax flavors set this brand primary; omit it and is-primary
|
|
24
|
+
// reverts to Bulma's default turquoise (verified failure mode).
|
|
25
|
+
@use 'bulma/sass/utilities' with (
|
|
26
|
+
$primary: #1e6b99
|
|
27
|
+
);
|
|
28
|
+
|
|
29
|
+
// Required: reset + CSS variable definitions
|
|
30
|
+
@use 'bulma/sass/base';
|
|
31
|
+
@use 'bulma/sass/themes';
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
- `base` — minireset, generic element styles, keyframes.
|
|
35
|
+
- `themes` — registers the `--bulma-*` custom properties (colors, radii, schemes) and
|
|
36
|
+
light/dark setup. Without it, components render unstyled-looking because every color
|
|
37
|
+
resolves to nothing.
|
|
38
|
+
- Exception: `bulma/sass/grid/columns` and `bulma/sass/grid/grid` register their own CSS
|
|
39
|
+
vars and can technically stand alone — include base + themes anyway; it is the safe
|
|
40
|
+
default.
|
|
41
|
+
|
|
42
|
+
## Component → partial mapping
|
|
43
|
+
|
|
44
|
+
**Rule:** stock Bulma components map to `bulma/sass/<category>/<lowercased-name>`; bestax
|
|
45
|
+
extras map to `@allxsmith/bestax-bulma/scss/<category>/<lowercased-name>`. Components that
|
|
46
|
+
are pure stock Bulma (Button, Box, Card, Navbar, Modal, Hero, …) have **no** extras partial —
|
|
47
|
+
Bulma's own module is all they need.
|
|
48
|
+
|
|
49
|
+
Stock Bulma examples:
|
|
50
|
+
|
|
51
|
+
```scss
|
|
52
|
+
@use 'bulma/sass/elements/button'; // Button, Buttons
|
|
53
|
+
@use 'bulma/sass/elements/box'; // Box
|
|
54
|
+
@use 'bulma/sass/elements/notification'; // Notification
|
|
55
|
+
@use 'bulma/sass/elements/title'; // Title, SubTitle
|
|
56
|
+
@use 'bulma/sass/form/input'; // Input
|
|
57
|
+
@use 'bulma/sass/form/select'; // Select
|
|
58
|
+
@use 'bulma/sass/components/card'; // Card
|
|
59
|
+
@use 'bulma/sass/components/modal'; // Modal
|
|
60
|
+
@use 'bulma/sass/components/navbar'; // Navbar
|
|
61
|
+
@use 'bulma/sass/grid/columns'; // Columns, Column
|
|
62
|
+
@use 'bulma/sass/grid/grid'; // Grid, Cell
|
|
63
|
+
@use 'bulma/sass/layout/container'; // Container
|
|
64
|
+
@use 'bulma/sass/layout/section'; // Section
|
|
65
|
+
```
|
|
66
|
+
|
|
67
|
+
## Authoritative bestax extras inventory
|
|
68
|
+
|
|
69
|
+
Every extras partial that exists (from the library's `src/scss/**/_index.scss` — this list
|
|
70
|
+
is **more complete** than the docs page's Option C example, which omits several):
|
|
71
|
+
|
|
72
|
+
**Components** (`@allxsmith/bestax-bulma/scss/components/<name>`):
|
|
73
|
+
`loading`, `collapse`, `tooltip`, `steps`, `sidebar`, `toast`, `dialog`, `carousel`, `tabs`,
|
|
74
|
+
`reveal`, `avatar`, `avatars`, `badge`
|
|
75
|
+
|
|
76
|
+
**Form** (`@allxsmith/bestax-bulma/scss/form/<name>`):
|
|
77
|
+
`checkbox`, `radio`, `switch`, `slider`, `numberinput`, `rate`, `autocomplete`, `taginput`,
|
|
78
|
+
`picker-popover`, `dateinput`, `timeinput`, `datetimeinput`
|
|
79
|
+
|
|
80
|
+
**Elements** (`@allxsmith/bestax-bulma/scss/elements/<name>`): `linkbutton`
|
|
81
|
+
|
|
82
|
+
**Helpers** (`@allxsmith/bestax-bulma/scss/helpers/<name>`): `cursor`, `sizing`
|
|
83
|
+
|
|
84
|
+
Notes:
|
|
85
|
+
|
|
86
|
+
- The extras partial name is the component name lowercased (`Dialog` →
|
|
87
|
+
`scss/components/dialog`; `NumberInput` → `scss/form/numberinput`).
|
|
88
|
+
- Extras `Tabs` **extends** stock Bulma tabs (vertical variant) — an app using `Tabs` needs
|
|
89
|
+
both `bulma/sass/components/tabs` and `@allxsmith/bestax-bulma/scss/components/tabs`.
|
|
90
|
+
- `DateInput`/`TimeInput`/`DateTimeInput` also need `picker-popover`.
|
|
91
|
+
- Stock-Bulma form controls still need their Bulma module (`bulma/sass/form/…`); the extras
|
|
92
|
+
form partials above style only the bestax-specific behavior.
|
|
93
|
+
- Bulma component modules pull their own internal sub-elements — e.g.
|
|
94
|
+
`elements/notification` styles its `delete` close button itself (verified). No extra
|
|
95
|
+
`@use` lines are needed for pieces rendered _inside_ a component you've already included.
|
|
96
|
+
|
|
97
|
+
## Bulma helper categories
|
|
98
|
+
|
|
99
|
+
Include a helper module **only if the app's helper props (or `className` strings) need it**:
|
|
100
|
+
|
|
101
|
+
⚠️ The `display` prop (`display="flex"`, `is-flex`, `is-block`, …) lives in **`visibility`**,
|
|
102
|
+
not `flexbox` — `flexbox` holds only the alignment props. Verified failure mode: omit
|
|
103
|
+
`visibility` and every `display="flex"` silently renders `block`.
|
|
104
|
+
|
|
105
|
+
```scss
|
|
106
|
+
@use 'bulma/sass/helpers/spacing'; // m*/p* props
|
|
107
|
+
@use 'bulma/sass/helpers/color'; // color/backgroundColor props, has-text-*/has-background-*
|
|
108
|
+
@use 'bulma/sass/helpers/typography'; // textSize/textAlign/textTransform/textWeight/fontFamily
|
|
109
|
+
@use 'bulma/sass/helpers/visibility'; // display/visibility props incl. display="flex" (is-flex/is-block/is-hidden*)
|
|
110
|
+
@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…
|
|
112
|
+
```
|
|
113
|
+
|
|
114
|
+
## Procedure
|
|
115
|
+
|
|
116
|
+
1. **Inventory** — list every component the app imports from `@allxsmith/bestax-bulma`
|
|
117
|
+
(grep the import statements; remember re-exports through local files).
|
|
118
|
+
2. **Map** — one `@use` line per component via the rule above; add the helper categories the
|
|
119
|
+
app's helper props require; dedupe.
|
|
120
|
+
3. **Write `src/styles.scss`** — the `utilities` config first, then base + themes, then the
|
|
121
|
+
mapped lines.
|
|
122
|
+
4. **Swap the import** — in `src/main.tsx`/`src/main.jsx`, replace the prebuilt CSS import
|
|
123
|
+
(`bestax.css` or `versions/*.css`) with `import './styles.scss';`.
|
|
124
|
+
5. **Build and measure** — raw + gzip, compare against the prebuilt baseline, report the
|
|
125
|
+
delta.
|
|
126
|
+
6. **Verify visually** — open the app; a missing partial shows up as an unstyled component,
|
|
127
|
+
an omitted helper module as ignored spacing/color props. Add the missing `@use` line —
|
|
128
|
+
never paper over it with custom CSS.
|
|
129
|
+
|
|
130
|
+
## Worked example — the create-bestax starter app
|
|
131
|
+
|
|
132
|
+
The `npm create bestax` starter renders `Container`, `Section`, `Columns`/`Column`, `Image`,
|
|
133
|
+
`Title`/`SubTitle`, `Box`, `Card`, `Buttons`/`Button`, and `Notification` — all stock Bulma,
|
|
134
|
+
no bestax extras. Its helper props are `display`/`justifyContent` (visibility + flexbox),
|
|
135
|
+
`textAlign` (typography), and `textColor` (color); it uses no spacing props. That inventory
|
|
136
|
+
compiles to the following — verified pixel-equivalent to the prebuilt `complete` flavor in
|
|
137
|
+
headless Chromium (light and dark), at 453 KB raw / 40 KB gzip vs 813 KB / 83 KB:
|
|
138
|
+
|
|
139
|
+
```scss
|
|
140
|
+
// src/styles.scss
|
|
141
|
+
@use 'bulma/sass/utilities' with (
|
|
142
|
+
$primary: #1e6b99
|
|
143
|
+
);
|
|
144
|
+
|
|
145
|
+
@use 'bulma/sass/base';
|
|
146
|
+
@use 'bulma/sass/themes';
|
|
147
|
+
|
|
148
|
+
@use 'bulma/sass/elements/box';
|
|
149
|
+
@use 'bulma/sass/elements/button'; // Button + Buttons
|
|
150
|
+
@use 'bulma/sass/elements/image';
|
|
151
|
+
@use 'bulma/sass/elements/notification';
|
|
152
|
+
@use 'bulma/sass/elements/title'; // Title + SubTitle
|
|
153
|
+
@use 'bulma/sass/components/card';
|
|
154
|
+
@use 'bulma/sass/grid/columns';
|
|
155
|
+
@use 'bulma/sass/layout/container';
|
|
156
|
+
@use 'bulma/sass/layout/section';
|
|
157
|
+
|
|
158
|
+
@use 'bulma/sass/helpers/visibility'; // display="flex"
|
|
159
|
+
@use 'bulma/sass/helpers/flexbox'; // justifyContent/flexGrow/flexShrink
|
|
160
|
+
@use 'bulma/sass/helpers/typography'; // textAlign
|
|
161
|
+
@use 'bulma/sass/helpers/color'; // textColor
|
|
162
|
+
```
|
|
163
|
+
|
|
164
|
+
```tsx
|
|
165
|
+
// src/main.tsx — before
|
|
166
|
+
import '@allxsmith/bestax-bulma/bestax.css';
|
|
167
|
+
// after
|
|
168
|
+
import './styles.scss';
|
|
169
|
+
```
|
|
170
|
+
|
|
171
|
+
A custom class prefix is `$class-prefix` in the same `with (…)` block as `$primary`, paired
|
|
172
|
+
with `<ConfigProvider classPrefix="my-">` at the app root (the library's own
|
|
173
|
+
`src/scss/versions/*.scss` flavor builds use exactly this mechanism).
|
|
@@ -0,0 +1,117 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: bestax-theming
|
|
3
|
+
description: Customize colors, branding, dark mode, and visual tokens of an app built with @allxsmith/bestax-bulma. Use when changing the primary/brand color, recoloring components, overriding Bulma --bulma-* CSS variables, setting fonts/radius/spacing tokens, adding light/dark mode, or configuring the app-wide icon library / class prefix via ConfigProvider.
|
|
4
|
+
license: MIT
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
# Theming @allxsmith/bestax-bulma
|
|
8
|
+
|
|
9
|
+
`@allxsmith/bestax-bulma` wraps Bulma 1.x, which is themed through `--bulma-*` CSS custom
|
|
10
|
+
properties. Theme an app by overriding the right variables — no component re-styling required.
|
|
11
|
+
|
|
12
|
+
## Approach
|
|
13
|
+
|
|
14
|
+
Recolor a brand color by overriding its **hue/saturation/lightness trio** — Bulma derives every
|
|
15
|
+
shade, light/dark, and invert variant from `--bulma-<color>-h` / `-s` / `-l`. Override the trio and
|
|
16
|
+
the whole palette follows.
|
|
17
|
+
|
|
18
|
+
Choose an override path:
|
|
19
|
+
|
|
20
|
+
- **`Theme` component (runtime, preferred).** Exported from the package. Pass named HSL props
|
|
21
|
+
(`primaryH`, `primaryS`, `primaryL`, …) and/or `bulmaVars={{ '--bulma-*': '…' }}` for everything
|
|
22
|
+
else. Add `isRoot` to inject the variables globally at `:root` (once, at the app root); omit it to
|
|
23
|
+
scope the variables to the wrapped subtree.
|
|
24
|
+
- **Plain CSS.** Set `:root { --bulma-primary-h: …; }` (or any selector) directly.
|
|
25
|
+
- **Build-time Sass.** `@use 'bulma/sass' with ($primary: #1e6b99)` when compiling Bulma's Sass.
|
|
26
|
+
|
|
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
|
|
29
|
+
`Theme`; `'system'` follows the OS `prefers-color-scheme`. Drive it from state on the app-root
|
|
30
|
+
`Theme`: `<Theme isRoot colorMode={mode}>`.
|
|
31
|
+
|
|
32
|
+
## Contrast rules (dark mode is on by default)
|
|
33
|
+
|
|
34
|
+
When nothing sets a `data-theme` attribute (omitting `colorMode` preserves an existing one, but
|
|
35
|
+
apps that never configured it have none), Bulma follows the visitor's OS: `--bulma-text`,
|
|
36
|
+
`--bulma-scheme-main`, etc. flip on a dark-mode machine even if the design never intended a dark
|
|
37
|
+
theme. Custom fixed tokens (`--my-canvas: #f6f4ec`) do **not** flip — producing near-white Bulma
|
|
38
|
+
text on the author's fixed light background. Apply exactly one of these rules whenever custom
|
|
39
|
+
color tokens or fixed-color surfaces exist:
|
|
40
|
+
|
|
41
|
+
- **Single-mode design → pin the scheme.** `<Theme isRoot colorMode="light">` (or `"dark"`), so
|
|
42
|
+
an OS preference can never invert text out from under the fixed palette.
|
|
43
|
+
- **Both modes → no exposed fixed tokens.** Derive custom tokens from scheme variables
|
|
44
|
+
(`--my-canvas: var(--bulma-scheme-main)`) — or flip them yourself under **both** dark-mode
|
|
45
|
+
paths: `[data-theme='dark']` **and** `@media (prefers-color-scheme: dark)` scoped to
|
|
46
|
+
`:root:not([data-theme])`, since `colorMode="system"` removes the attribute (snippets in
|
|
47
|
+
`references/css-variables.md`). Alternating/tinted section bands are this case:
|
|
48
|
+
`background: var(--bulma-scheme-main-bis)` (then `-ter`), never `bgColor="light"` —
|
|
49
|
+
`light`/`white`/grey helper backgrounds are fixed colors that fight dark mode.
|
|
50
|
+
- **Fixed-color surface → fixed-color content.** On a surface that never changes (a dark hero,
|
|
51
|
+
a brand banner), pin the content's colors too: solid/filled buttons and explicit text colors,
|
|
52
|
+
never scheme-derived defaults or thin outlines that depend on the flipping scheme.
|
|
53
|
+
|
|
54
|
+
Reach for the helper props (`color` / `textColor` / `bgColor` / `colorShade`, `textSize`,
|
|
55
|
+
`textWeight`, `fontFamily`) to apply themed colors and type to individual components.
|
|
56
|
+
Variant flags and value unions are component-specific — never carry one over by analogy:
|
|
57
|
+
`isLight` exists on `Button` and `Notification` **only** (`Tag` has none, and `LinkButtonProps`
|
|
58
|
+
omits it);
|
|
59
|
+
`Tag size` is `normal | medium | large` (no `small`, unlike `Button`); `Buttons` has
|
|
60
|
+
`isCentered`, `Tags` does not (center tags with `justifyContent="center"`); the verbatim
|
|
61
|
+
truth table is `references/themeable-components.md`.
|
|
62
|
+
|
|
63
|
+
## Quick start
|
|
64
|
+
|
|
65
|
+
```tsx
|
|
66
|
+
import { Theme, Button } from '@allxsmith/bestax-bulma';
|
|
67
|
+
|
|
68
|
+
// Global brand theme at the app root.
|
|
69
|
+
<Theme isRoot primaryH="265" primaryS="65%" primaryL="55%">
|
|
70
|
+
<App />
|
|
71
|
+
</Theme>;
|
|
72
|
+
|
|
73
|
+
// Themed components recolor automatically.
|
|
74
|
+
<Button color="primary">Save</Button>;
|
|
75
|
+
```
|
|
76
|
+
|
|
77
|
+
## App-wide config (icons & class prefix)
|
|
78
|
+
|
|
79
|
+
`ConfigProvider` sets app-wide options once at the root, separate from `Theme`. Wrap the app so
|
|
80
|
+
you don't repeat the same prop on every component:
|
|
81
|
+
|
|
82
|
+
```tsx
|
|
83
|
+
import { ConfigProvider } from '@allxsmith/bestax-bulma';
|
|
84
|
+
|
|
85
|
+
// Set the icon library once — <Icon> no longer needs a `library` prop.
|
|
86
|
+
<ConfigProvider iconLibrary="fa">
|
|
87
|
+
<App />
|
|
88
|
+
</ConfigProvider>;
|
|
89
|
+
// now <Icon name="check" /> resolves as Font Awesome; no per-icon library="fa".
|
|
90
|
+
```
|
|
91
|
+
|
|
92
|
+
- `iconLibrary` — `'fa' | 'mdi' | 'ion' | 'material-icons' | 'material-symbols'`. `Icon` reads it
|
|
93
|
+
(`library || iconLibrary || 'fa'`), so set it here instead of on each `<Icon>`.
|
|
94
|
+
- `classPrefix` — namespaces every Bulma class (e.g. `bulma-`) to avoid collisions with other CSS.
|
|
95
|
+
|
|
96
|
+
Nest `Theme` and `ConfigProvider` together at the root (order doesn't matter).
|
|
97
|
+
|
|
98
|
+
## References
|
|
99
|
+
|
|
100
|
+
- `references/css-variables.md` — the `--bulma-*` variable map (colors, scheme/text/border, radius,
|
|
101
|
+
fonts, sizes, weights, dark mode) and all three override mechanisms.
|
|
102
|
+
- `references/themeable-components.md` — which components take `color`/`size` props, the real
|
|
103
|
+
accepted values, and the shared helper props.
|
|
104
|
+
|
|
105
|
+
## Examples
|
|
106
|
+
|
|
107
|
+
- `examples/theme-config.tsx` — a custom brand theme at the app root, plus a scoped override.
|
|
108
|
+
- `examples/dark-mode.tsx` — a light/dark toggle using Bulma's `data-theme`.
|
|
109
|
+
|
|
110
|
+
## Checklist
|
|
111
|
+
|
|
112
|
+
- [ ] Recolor brand colors via the HSL trio (`*-h` / `*-s` / `*-l`), not by hard-coding hex on components.
|
|
113
|
+
- [ ] Apply a global theme once with `<Theme isRoot>` (or `:root`); use scoped `<Theme>` for one-off sections.
|
|
114
|
+
- [ ] 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).
|
|
115
|
+
- [ ] Implement dark mode with `data-theme` on `<html>`; do not expect a shipped dark-mode component.
|
|
116
|
+
- [ ] Pass `color`/`textColor`/`bgColor` (not custom CSS) to color individual components.
|
|
117
|
+
- [ ] Set the icon library once with `<ConfigProvider iconLibrary="…">` at the root, not `library` on every `<Icon>`.
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
// Dark mode for an app built on @allxsmith/bestax-bulma.
|
|
2
|
+
//
|
|
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.
|
|
7
|
+
import React, { useState } from 'react';
|
|
8
|
+
import {
|
|
9
|
+
Theme,
|
|
10
|
+
Box,
|
|
11
|
+
Button,
|
|
12
|
+
Title,
|
|
13
|
+
Notification,
|
|
14
|
+
} from '@allxsmith/bestax-bulma';
|
|
15
|
+
|
|
16
|
+
type Mode = 'light' | 'dark' | 'system';
|
|
17
|
+
|
|
18
|
+
export function DarkModeToggle() {
|
|
19
|
+
const [mode, setMode] = useState<Mode>('system');
|
|
20
|
+
|
|
21
|
+
return (
|
|
22
|
+
<Theme isRoot colorMode={mode}>
|
|
23
|
+
<Box>
|
|
24
|
+
<Title size="5">Color mode: {mode}</Title>
|
|
25
|
+
<Notification color="info">
|
|
26
|
+
Components below follow the current Bulma color scheme.
|
|
27
|
+
</Notification>
|
|
28
|
+
<Button color="primary" onClick={() => setMode('light')}>
|
|
29
|
+
Light
|
|
30
|
+
</Button>
|
|
31
|
+
<Button color="primary" onClick={() => setMode('dark')}>
|
|
32
|
+
Dark
|
|
33
|
+
</Button>
|
|
34
|
+
<Button onClick={() => setMode('system')}>System</Button>
|
|
35
|
+
</Box>
|
|
36
|
+
</Theme>
|
|
37
|
+
);
|
|
38
|
+
}
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
// Custom brand theme for an app built on @allxsmith/bestax-bulma.
|
|
2
|
+
// Copy this to your app and adjust the HSL values to your brand.
|
|
3
|
+
//
|
|
4
|
+
// Bulma 1.x derives every shade of a color from its hue/saturation/lightness
|
|
5
|
+
// trio (--bulma-<color>-h / -s / -l), so overriding the trio recolors the whole
|
|
6
|
+
// palette. The <Theme> component writes those CSS variables for you:
|
|
7
|
+
// - isRoot -> inject the variables globally at :root (use once, at the app root)
|
|
8
|
+
// - without isRoot -> wrap children in a <div> and scope the variables to it
|
|
9
|
+
import React from 'react';
|
|
10
|
+
import {
|
|
11
|
+
Theme,
|
|
12
|
+
Button,
|
|
13
|
+
Notification,
|
|
14
|
+
Box,
|
|
15
|
+
Title,
|
|
16
|
+
} from '@allxsmith/bestax-bulma';
|
|
17
|
+
|
|
18
|
+
// 1) Global brand theme at the app root.
|
|
19
|
+
// Hue is unitless; saturation and lightness are percentages.
|
|
20
|
+
export function ThemedApp({ children }: { children: React.ReactNode }) {
|
|
21
|
+
return (
|
|
22
|
+
<Theme
|
|
23
|
+
isRoot
|
|
24
|
+
// Brand primary (HSL trio) — recolors every `is-primary` / `has-text-primary`.
|
|
25
|
+
primaryH="265"
|
|
26
|
+
primaryS="65%"
|
|
27
|
+
primaryL="55%"
|
|
28
|
+
// A matching link color.
|
|
29
|
+
linkH="200"
|
|
30
|
+
linkS="80%"
|
|
31
|
+
linkL="45%"
|
|
32
|
+
// Anything without a named prop goes through `bulmaVars`, keyed by the real
|
|
33
|
+
// --bulma-* variable names (string values).
|
|
34
|
+
bulmaVars={{
|
|
35
|
+
'--bulma-radius': '0.75rem',
|
|
36
|
+
'--bulma-radius-large': '1.25rem',
|
|
37
|
+
// 'Inter' must actually be loaded (index.html <link> or an @fontsource
|
|
38
|
+
// import) — declaring the family var alone falls back to system-ui.
|
|
39
|
+
'--bulma-family-primary': "'Inter', system-ui, sans-serif",
|
|
40
|
+
}}
|
|
41
|
+
>
|
|
42
|
+
{children}
|
|
43
|
+
</Theme>
|
|
44
|
+
);
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
// 2) Scoped override — theme just one section; the rest of the app is untouched.
|
|
48
|
+
export function PromoPanel() {
|
|
49
|
+
return (
|
|
50
|
+
<Theme primaryH="16" primaryS="85%" primaryL="55%">
|
|
51
|
+
<Box>
|
|
52
|
+
<Title size="4">Limited offer</Title>
|
|
53
|
+
<Notification color="primary">
|
|
54
|
+
This panel uses a warm primary; the rest of the app is unaffected.
|
|
55
|
+
</Notification>
|
|
56
|
+
<Button color="primary">Claim it</Button>
|
|
57
|
+
</Box>
|
|
58
|
+
</Theme>
|
|
59
|
+
);
|
|
60
|
+
}
|