create-bestax 4.2.9 → 4.2.11
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 +1 -1
- package/package.json +3 -3
- package/templates/skills/bestax-custom-component/references/library-contributor.md +15 -0
- package/templates/skills/bestax-layout-scaffold/examples/content-page.tsx +5 -1
- package/templates/skills/bestax-migrate/references/bloomer/prop-map.md +11 -3
- package/templates/skills/bestax-migrate/references/rbx/prop-map.md +25 -14
- package/templates/skills/bestax-migrate/references/react-bulma-components/unmappables.md +13 -5
- package/templates/skills/bestax-theming/references/css-variables.md +8 -8
package/README.md
CHANGED
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
[](https://www.npmjs.com/package/create-bestax)
|
|
4
4
|
[](https://www.npmjs.com/package/create-bestax)
|
|
5
5
|
[](https://opensource.org/licenses/MIT)
|
|
6
|
-
[](https://socket.dev/npm/package/create-bestax/overview)
|
|
7
7
|
[](https://scorecard.dev/viewer/?uri=github.com/allxsmith/bestax)
|
|
8
8
|
[](https://www.bestpractices.dev/projects/14361)
|
|
9
9
|
[](https://www.npmjs.com/package/create-bestax#provenance)
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "create-bestax",
|
|
3
|
-
"version": "4.2.
|
|
3
|
+
"version": "4.2.11",
|
|
4
4
|
"description": "Create a new bestax-bulma project",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"bin": {
|
|
@@ -39,7 +39,7 @@
|
|
|
39
39
|
"figures": "^6.1.0",
|
|
40
40
|
"fs-extra": "^11.4.0",
|
|
41
41
|
"prompts": "^2.4.2",
|
|
42
|
-
"@allxsmith/bestax-bulma": "^5.16.
|
|
42
|
+
"@allxsmith/bestax-bulma": "^5.16.9"
|
|
43
43
|
},
|
|
44
44
|
"devDependencies": {
|
|
45
45
|
"@jest/globals": "^30.0.0",
|
|
@@ -75,5 +75,5 @@
|
|
|
75
75
|
"clean": "rimraf dist",
|
|
76
76
|
"release": "npx semantic-release"
|
|
77
77
|
},
|
|
78
|
-
"readme": "# create-bestax\n\n[](https://www.npmjs.com/package/create-bestax)\n[](https://www.npmjs.com/package/create-bestax)\n[](https://opensource.org/licenses/MIT)\n[](https://www.npmjs.com/package/create-bestax)\n[](https://www.npmjs.com/package/create-bestax)\n[](https://opensource.org/licenses/MIT)\n[](https://socket.dev/npm/package/create-bestax/overview)\n[](https://scorecard.dev/viewer/?uri=github.com/allxsmith/bestax)\n[](https://www.bestpractices.dev/projects/14361)\n[](https://www.npmjs.com/package/create-bestax#provenance)\n[](https://github.com/allxsmith/bestax/blob/main/SECURITY.md)\n\nThe scaffolder for [`@allxsmith/bestax-bulma`](https://www.npmjs.com/package/@allxsmith/bestax-bulma) — spin up a Vite app pre-wired for the **Bulma v1** React component library in one command. Picks your framework (JS or TypeScript), CSS flavor, and icon library, and can drop in the bestax **AI skills** so an agent like Claude Code knows the library from the first prompt.\n\nPart of the [bestax monorepo](https://github.com/allxsmith/bestax) — see also [`@allxsmith/bestax-bulma`](https://www.npmjs.com/package/@allxsmith/bestax-bulma) for the components themselves.\n\n## Requirements\n\n- **Node.js 22 or newer.** Node 18 and 20 are both past end-of-life. On an older runtime the\n CLI exits immediately with an explicit upgrade message.\n- npm 10 or newer (ships with Node 22), or yarn/pnpm.\n\n## Usage\n\n### Quick Start\n\n```bash\n# Using npm\nnpm create bestax@latest my-app\n\n# Using npx\nnpx create-bestax@latest my-app\n\n# Alternative naming\nnpm create bestax-bulma@latest my-app\n```\n\n### Interactive Mode\n\nRunning without arguments will prompt you for all options:\n\n```bash\nnpm create bestax@latest\n```\n\nYou'll be asked to:\n\n1. Enter a project name\n2. Select a framework (Vite or Vite + TypeScript)\n3. Choose a Bulma CSS flavor (Complete or Minimal)\n4. Select an icon library (Font Awesome, Material Icons, etc.)\n5. Choose whether to install the bestax AI skills into `.claude/skills/`\n\nEvery prompt has a flag equivalent, so the whole flow is scriptable and CI-friendly — see the options below.\n\n### Command Line Options\n\n```bash\nnpm create bestax@latest [project-directory] [options]\n```\n\n**Arguments:**\n\n- `[project-directory]` - Optional project directory name\n\n**Options:**\n\n- `-t, --template <template>` - Template to use: `vite` or `vite-ts` \n **Default:** `vite`\n- `-b, --bulma <flavor>` - Bulma CSS flavor:\n - `complete` - Full Bulma CSS with all components and helpers\n - `prefixed` - Prefixed version for compatibility\n - `no-helpers` - Without helper classes\n - `no-helpers-prefixed` - Prefixed without helpers\n - `no-dark-mode` - Without dark mode support \n **Default:** `complete`\n- `-i, --icon <library>` - Icon library:\n - `none` - No icon library\n - `fontawesome` - Font Awesome\n - `mdi` - Material Design Icons\n - `ionicons` - Ionicons\n - `material-icons` - Material Icons\n - `material-symbols` - Material Symbols \n **Default:** `none`\n- `--skills` / `--no-skills` - Install (or skip) the bestax AI skills into\n `.claude/skills/` (with a `CLAUDE.md`) so a Claude Code session picks them up\n automatically. When omitted you're prompted; with `-y` the default is to install.\n- `-y, --yes` - Skip prompts and use defaults or provided options. \n When used, the following defaults are selected unless overridden by flags:\n - Template: `vite`\n - Bulma flavor: `complete`\n - Icon library: `none`\n - AI skills: installed (pass `--no-skills` to opt out)\n\n**Example:**\n\n```bash\n# Create a TypeScript project with Font Awesome icons\nnpm create bestax@latest my-app -t vite-ts -i fontawesome -b complete\n\n# Use all defaults (skip prompts)\nnpm create bestax@latest my-app -y\n```\n\n## Templates\n\nAvailable templates:\n\n- `vite` - Vite + JavaScript\n- `vite-ts` - Vite + TypeScript\n\nEach template includes:\n\n- Pre-configured bestax-bulma integration (React 19)\n- The latest `@allxsmith/bestax-bulma`, which ships Bulma v1 automatically\n- Icon library support (Font Awesome, Material Design, etc.)\n- Sample components demonstrating library usage\n- Development and build scripts\n\n## For AI Tools\n\nScaffolding for an AI agent? Pass `--skills` (or accept the prompt) to drop the bestax\nAgent Skills and a `CLAUDE.md` into the new project so Claude Code, Cursor, or Copilot\nbuild the bestax way from the start. The library also ships LLM-optimized docs:\n\n- [LLMs guide](https://bestax.io/docs/guides/llms) — using bestax with Claude Code, Cursor, Copilot\n- [Agent Skills](https://bestax.io/docs/skills/intro) — teach your agent the bestax conventions\n- [llms.txt](https://bestax.io/llms.txt) (curated index) · [llms-full.txt](https://bestax.io/llms-full.txt) (full docs)\n\n## Development\n\n```bash\nnpm run build # Build the CLI\nnpm run dev # Watch mode\nnpm test # Run tests\nnpm run lint # Lint CLI source code\nnpm run typecheck # Type check CLI source code\n```\n\n**Note on Templates:** Template files in `templates/` are excluded from linting. They should be manually validated by scaffolding a test project and running lint/build there before releasing.\n\n## Hardened by default\n\nA scaffolder runs with write access to your filesystem and picks your starting dependencies, so how it is built and published matters:\n\n- **Signed provenance** — every release carries a sigstore attestation linking the tarball to the exact commit and CI run that built it. Check the **Provenance** section on the [npm page](https://www.npmjs.com/package/create-bestax#provenance), or run `npm audit signatures`.\n- **npm OIDC trusted publishing** — short-lived, per-run credentials; no long-lived `NPM_TOKEN` exists to be stolen. Release commits and tags are GPG-signed.\n- **Socket.dev scans every PR** for malware, install scripts, obfuscated code, and privilege escalation before it can reach `main`.\n- **Dependencies are a deliberate act** — install scripts are blocked unless individually allow-listed, freshly published versions are refused for 3 days, and CI installs only what the reviewed lockfile resolves.\n- **Every GitHub Action is pinned to a full commit SHA**, so a compromised action release can't roll silently into a build of this CLI.\n- **CodeQL, Dependency Review, and Dependabot** run continuously, alongside a high-severity `pnpm audit` gate.\n- **Layered AI review before merge** — [CodeRabbit](https://coderabbit.ai) plus an independent adversarial Claude review (a different model from the one writing AI-authored changes), on top of required green CI, an approving review, and a human merge.\n\nFull detail: [`SECURITY.md`](https://github.com/allxsmith/bestax/blob/main/SECURITY.md) · [Security guide](https://bestax.io/docs/guides/security)\n\n## Telemetry\n\n`create-bestax` can send one **anonymous** usage event after a successful\nscaffold — only if you opt in when asked (once, at the end of a scaffold). The\nevent is just the choices you made — template, Bulma flavor, icon library,\nskills, package manager — plus the CLI version, Node major version, and OS\nplatform; never names, IPs, machine IDs, paths, or file contents, and no\nidentifier exists that could link two events together. Opt out any time with\n`--no-telemetry`, `BESTAX_TELEMETRY=0`, or `DO_NOT_TRACK=1`.\n\nFull disclosure of every field and control: [Telemetry guide](https://bestax.io/docs/guides/telemetry)\n\n## Publishing\n\nThis package uses semantic-release with scope-based rules. Only commits with `feat(create-bestax)` or `fix(create-bestax)` will trigger releases.\n"
|
|
79
79
|
}
|
|
@@ -137,6 +137,21 @@ Rules that keep components consistent:
|
|
|
137
137
|
`PolymorphicComponentWithoutRef` and forwards none. That is the exception, not
|
|
138
138
|
a licence to skip refs; everything a consumer might focus or measure should
|
|
139
139
|
forward one.
|
|
140
|
+
- **An own prop the component FORWARDS has to say so.** Subtracting `Own` from the
|
|
141
|
+
target's props is what keeps a Bulma `color` from being shadowed by the DOM
|
|
142
|
+
attribute, but it also lets an OPTIONAL own prop hide a REQUIRED prop of the
|
|
143
|
+
target: `Avatar`'s `href?: string` hid `next/link`'s required one, so
|
|
144
|
+
`<Avatar as={NextLink} name="Ada" />` compiled and the target was handed
|
|
145
|
+
nothing (#665). Name those props in the third type parameter —
|
|
146
|
+
`PolymorphicComponent<FooOwnProps, 'tag', 'href' | 'target'>`, with the
|
|
147
|
+
matching `Exclude`/`Extract` pair written out in the alias the way `Avatar.tsx`
|
|
148
|
+
does — and the target's declaration wins, while the own one still covers a
|
|
149
|
+
target that has no such prop. It defaults to naming none, which is the right
|
|
150
|
+
answer for a prop the component CONSUMES. Withholding an undefined value at
|
|
151
|
+
runtime belongs with it: a key that merely exists reads as a value to a target
|
|
152
|
+
that tests for one, and travels on through its `{...rest}`. Not to a
|
|
153
|
+
destructuring default, which an explicit `undefined` triggers anyway.
|
|
154
|
+
|
|
140
155
|
- **Element sizing uses an inline `'small' | 'medium' | 'large'` union**, mapped to `is-small` /
|
|
141
156
|
`is-medium` / `is-large` (see `Tabs.tsx`, `Control.tsx`). Do **not** reach for the `validSizes`
|
|
142
157
|
constant — that one is `'0'…'6' | 'auto'` and exists for **spacing** helpers, not element size.
|
|
@@ -72,7 +72,11 @@ export default function ContentPage() {
|
|
|
72
72
|
<Card>
|
|
73
73
|
<Card.Content>
|
|
74
74
|
<IconText mb="3">
|
|
75
|
-
<Icon
|
|
75
|
+
<Icon
|
|
76
|
+
name={f.icon}
|
|
77
|
+
textColor="primary"
|
|
78
|
+
aria-hidden="true"
|
|
79
|
+
/>
|
|
76
80
|
<Title size="4" mb="2">
|
|
77
81
|
{f.name}
|
|
78
82
|
</Title>
|
|
@@ -161,6 +161,14 @@ value is flagged. The same conversion covers the modifiers bestax has no prop fo
|
|
|
161
161
|
|
|
162
162
|
## Refs
|
|
163
163
|
|
|
164
|
-
bloomer forwarded no refs. bestax forwards a ref from the form controls
|
|
165
|
-
`
|
|
166
|
-
`
|
|
164
|
+
bloomer forwarded no refs. bestax forwards a ref from the form controls, plus `Avatar`,
|
|
165
|
+
`Button`, `Carousel`, `CarouselItem`, `Dialog`, `Dropdown`, `Link`, `LinkButton`, `Menu.Item`,
|
|
166
|
+
`Modal`, `Navbar`, `Navbar.Burger`, `Navbar.Dropdown`, `Navbar.Item`, `Navbar.Link`, `Sidebar`
|
|
167
|
+
and `Toast` — pass `ref` directly on those. "The form controls" means the inputs
|
|
168
|
+
themselves: the `Field`, `Field.Label`, `Field.Body`, `Checkboxes` and `Radios` wrappers
|
|
169
|
+
around them forward nothing.
|
|
170
|
+
|
|
171
|
+
A `ref` on anything else is unsupported, and the two React majors fail differently: React 18
|
|
172
|
+
drops it and logs "Function components cannot be given refs", while React 19 hands it to the
|
|
173
|
+
component as an ordinary prop, where it settles wherever the rest props go. bestax supports
|
|
174
|
+
both, so attach the ref to an element you control instead.
|
|
@@ -151,23 +151,34 @@ The third row is the `Navbar.Dropdown` collision, and it runs both ways. Your rb
|
|
|
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
|
|
155
|
-
|
|
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).
|
|
156
158
|
|
|
157
159
|
An existing `ref` is passed through untouched — which is safe only where the bestax target
|
|
158
|
-
forwards one. rbx forwards a ref on every component; bestax does so on the form controls plus
|
|
159
|
-
`
|
|
160
|
-
`
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
160
|
+
forwards one. rbx forwards a ref on every component; bestax does so on the form controls, plus
|
|
161
|
+
`Avatar`, `Button`, `Carousel`, `CarouselItem`, `Dialog`, `Dropdown`, `Link`, `LinkButton`,
|
|
162
|
+
`Menu.Item`, `Modal`, `Navbar`, `Navbar.Burger`, `Navbar.Dropdown`, `Navbar.Item`,
|
|
163
|
+
`Navbar.Link`, `Sidebar` and `Toast`. "The form controls" there means the inputs themselves:
|
|
164
|
+
the `Field`, `Field.Label`, `Field.Body`, `Checkboxes` and `Radios` wrappers around them
|
|
165
|
+
forward nothing, and `Field` is a target this codemod emits.
|
|
166
|
+
|
|
167
|
+
Carry a `ref` onto anything else — `Card`, `Box`, `Section`, `Message`, `Tabs` and most of the
|
|
168
|
+
catalogue — and it is unsupported, but the two React majors fail differently. React 18 drops
|
|
169
|
+
it and logs "Function components cannot be given refs". React 19 hands `ref` to the component
|
|
170
|
+
as an ordinary prop, so it lands wherever that component spreads its rest props, silently and
|
|
171
|
+
with no guarantee it is the element you meant. bestax supports both majors, so neither
|
|
172
|
+
outcome is one to build on: put the ref on an element you control.
|
|
164
173
|
|
|
165
174
|
**The codemod does not flag this**, because neither the universal prop table nor any
|
|
166
175
|
per-component table has a `ref` entry, so check every `ref` you carried over against the list
|
|
167
176
|
above rather than assuming the silent pass-through means it works. The renames above are for
|
|
168
|
-
`innerRef`, and apply only on those eight entries.
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
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.
|
|
@@ -128,11 +128,19 @@ bestax `Button` colors are the semantic set + `text`/`ghost`. For shades use
|
|
|
128
128
|
|
|
129
129
|
## `domRef`
|
|
130
130
|
|
|
131
|
-
bestax components don't take `domRef`, but many forward a plain `ref` — the form controls
|
|
132
|
-
|
|
133
|
-
`
|
|
134
|
-
`
|
|
135
|
-
|
|
131
|
+
bestax components don't take `domRef`, but many forward a plain `ref` — the form controls,
|
|
132
|
+
plus `Avatar`, `Button`, `Carousel`, `CarouselItem`, `Dialog`, `Dropdown`, `Link`,
|
|
133
|
+
`LinkButton`, `Menu.Item`, `Modal`, `Navbar`, `Navbar.Burger`, `Navbar.Dropdown`,
|
|
134
|
+
`Navbar.Item`, `Navbar.Link`, `Sidebar` and `Toast`. On those, rename `domRef` to
|
|
135
|
+
`ref` and it works; do not restructure the markup. "The form controls" means the inputs
|
|
136
|
+
themselves: the `Field`, `Field.Label`, `Field.Body`, `Checkboxes` and `Radios` wrappers
|
|
137
|
+
around them forward nothing, and `Field` is a target this codemod emits.
|
|
138
|
+
|
|
139
|
+
Everywhere else the rename is not enough, and the two React majors differ: React 18 drops the
|
|
140
|
+
ref and logs "Function components cannot be given refs", while React 19 passes it through as
|
|
141
|
+
an ordinary prop, so it settles wherever the component spreads its rest props with nothing
|
|
142
|
+
logged. bestax supports both, so attach the ref to a DOM element inside, or wrap the component
|
|
143
|
+
in a `<div ref={…}>`.
|
|
136
144
|
|
|
137
145
|
The codemod does not do that rename for you: `domRef` is flagged on every component, so the
|
|
138
146
|
TODO names both cases and you pick. `Navbar.Dropdown` is the trap, and it cuts both ways —
|
|
@@ -92,14 +92,14 @@ and numeric shades `--bulma-<c>-00` … `--bulma-<c>-95`.
|
|
|
92
92
|
|
|
93
93
|
## Radius, typography
|
|
94
94
|
|
|
95
|
-
| Variable | Default | `Theme` prop
|
|
96
|
-
| ----------------------------------------------------------------------------- | --------------------------------- |
|
|
97
|
-
| `--bulma-radius-small` / `--bulma-radius` / `--bulma-radius-large` | 0.25 / 0.375 / 0.75rem | via `bulmaVars`
|
|
98
|
-
| `--bulma-radius-rounded` | 9999px | via `bulmaVars`
|
|
99
|
-
| `--bulma-family-primary` / `--bulma-family-secondary` / `--bulma-family-code` | sans / sans / mono | via `bulmaVars`
|
|
100
|
-
| `--bulma-size-1` … `--bulma-size-7` | 3rem … 0.75rem |
|
|
101
|
-
| `--bulma-size-small` / `-normal` / `-medium` / `-large` | 0.75 / 1 / 1.25 / 1.5rem | via `bulmaVars`
|
|
102
|
-
| `--bulma-weight-light/normal/medium/semibold/bold/extrabold` | 300 / 400 / 500 / 600 / 700 / 800 | via `bulmaVars`
|
|
95
|
+
| Variable | Default | `Theme` prop |
|
|
96
|
+
| ----------------------------------------------------------------------------- | --------------------------------- | ------------------------------- |
|
|
97
|
+
| `--bulma-radius-small` / `--bulma-radius` / `--bulma-radius-large` | 0.25 / 0.375 / 0.75rem | via `bulmaVars` |
|
|
98
|
+
| `--bulma-radius-rounded` | 9999px | via `bulmaVars` |
|
|
99
|
+
| `--bulma-family-primary` / `--bulma-family-secondary` / `--bulma-family-code` | sans / sans / mono | via `bulmaVars` |
|
|
100
|
+
| `--bulma-size-1` … `--bulma-size-7` | 3rem … 0.75rem | CSS only, not a `bulmaVars` key |
|
|
101
|
+
| `--bulma-size-small` / `-normal` / `-medium` / `-large` | 0.75 / 1 / 1.25 / 1.5rem | via `bulmaVars` |
|
|
102
|
+
| `--bulma-weight-light/normal/medium/semibold/bold/extrabold` | 300 / 400 / 500 / 600 / 700 / 800 | via `bulmaVars` |
|
|
103
103
|
|
|
104
104
|
## Shadow — override the upstream token, not the derived one
|
|
105
105
|
|