create-bestax 4.0.2 → 4.1.1
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/LICENSE +21 -0
- package/dist/constants.d.ts.map +1 -1
- package/dist/constants.js +3 -1
- package/dist/display.d.ts.map +1 -1
- package/dist/display.js +6 -2
- package/dist/file-system.d.ts +1 -1
- package/dist/file-system.d.ts.map +1 -1
- package/dist/file-system.js +11 -1
- package/dist/index.js +0 -0
- package/dist/package-manager.d.ts +5 -0
- package/dist/package-manager.d.ts.map +1 -0
- package/dist/package-manager.js +9 -0
- package/dist/project-creator.d.ts.map +1 -1
- package/dist/project-creator.js +7 -1
- package/package.json +23 -24
- package/templates/skills/bestax-custom-component/SKILL.md +4 -3
- package/templates/skills/bestax-custom-component/references/api.md +28 -9
- package/templates/skills/bestax-custom-component/references/component-catalog.md +3 -3
- package/templates/skills/bestax-form/SKILL.md +7 -2
- package/templates/skills/bestax-form/references/api.md +1 -1
- package/templates/skills/bestax-layout-scaffold/SKILL.md +12 -8
- package/templates/skills/bestax-layout-scaffold/examples/centered.tsx +1 -1
- package/templates/skills/bestax-layout-scaffold/references/archetypes.md +5 -2
- package/templates/skills/bestax-layout-scaffold/references/layout-components.md +17 -3
- package/templates/skills/bestax-migrate/references/prop-map.md +1 -1
- package/templates/skills/bestax-theming/SKILL.md +7 -3
- package/templates/skills/bestax-theming/references/css-variables.md +8 -7
- package/templates/skills/bestax-theming/references/themeable-components.md +3 -3
- package/templates/vite/_gitignore +25 -0
- package/templates/vite-ts/_gitignore +25 -0
- package/templates/vite-ts/tsconfig.json +1 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2025 Alex Smith
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/dist/constants.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"constants.d.ts","sourceRoot":"","sources":["../src/constants.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAC;AAE1B,MAAM,WAAW,QAAQ;IACvB,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,CAAC;IAChB,KAAK,EAAE,OAAO,KAAK,CAAC,MAAM,CAAC;CAC5B;AAED,eAAO,MAAM,SAAS,EAAE,QAAQ,EAG/B,CAAC;AAEF,eAAO,MAAM,oBAAoB,kBAAkB,CAAC;AACpD,eAAO,MAAM,uBAAuB,MAAM,CAAC;AAC3C,eAAO,MAAM,kBAAkB,QAAsB,CAAC;AAEtD,eAAO,MAAM,QAAQ;;;;;;;wCAaQ,MAAM;uCAEP,MAAM;sCACP,MAAM;4CAEA,MAAM;;;;;CAM7B,CAAC;AASX,eAAO,MAAM,WAAW,QAed,CAAC;AAEX,eAAO,MAAM,OAAO;;;;;;CAOV,CAAC;AAOX,eAAO,MAAM,2BAA2B,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAK9D,CAAC;AAKF,MAAM,WAAW,eAAe;IAC9B,WAAW,EAAE,MAAM,CAAC;IACpB,WAAW,EAAE,MAAM,CAAC;CACrB;AAED,eAAO,MAAM,SAAS,GACpB,aAAa,MAAM,EACnB,8BAA8B,eAAe,KAC5C,
|
|
1
|
+
{"version":3,"file":"constants.d.ts","sourceRoot":"","sources":["../src/constants.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAC;AAE1B,MAAM,WAAW,QAAQ;IACvB,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,CAAC;IAChB,KAAK,EAAE,OAAO,KAAK,CAAC,MAAM,CAAC;CAC5B;AAED,eAAO,MAAM,SAAS,EAAE,QAAQ,EAG/B,CAAC;AAEF,eAAO,MAAM,oBAAoB,kBAAkB,CAAC;AACpD,eAAO,MAAM,uBAAuB,MAAM,CAAC;AAC3C,eAAO,MAAM,kBAAkB,QAAsB,CAAC;AAEtD,eAAO,MAAM,QAAQ;;;;;;;wCAaQ,MAAM;uCAEP,MAAM;sCACP,MAAM;4CAEA,MAAM;;;;;CAM7B,CAAC;AASX,eAAO,MAAM,WAAW,QAed,CAAC;AAEX,eAAO,MAAM,OAAO;;;;;;CAOV,CAAC;AAOX,eAAO,MAAM,2BAA2B,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAK9D,CAAC;AAKF,MAAM,WAAW,eAAe;IAC9B,WAAW,EAAE,MAAM,CAAC;IACpB,WAAW,EAAE,MAAM,CAAC;CACrB;AAED,eAAO,MAAM,SAAS,GACpB,aAAa,MAAM,EACnB,8BAA8B,eAAe,KAC5C,MAoIF,CAAC;AAEF,MAAM,WAAW,WAAW;IAC1B,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,CAAC;IAChB,KAAK,EAAE,OAAO,KAAK,CAAC,MAAM,CAAC;IAC3B,WAAW,CAAC,EAAE,MAAM,CAAC;IAIrB,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,iBAAiB,CAAC,EAAE,MAAM,CAAC;CAC5B;AAED,eAAO,MAAM,cAAc,EAAE,WAAW,EA6CvC,CAAC;AAEF,MAAM,WAAW,WAAW;IAC1B,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,CAAC;IAChB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,KAAK,EAAE,OAAO,KAAK,CAAC,MAAM,CAAC;IAC3B,eAAe,EAAE,MAAM,CAAC;IACxB,WAAW,CAAC,EAAE,OAAO,CAAC;CACvB;AAED,eAAO,MAAM,aAAa,EAAE,WAAW,EA4CtC,CAAC"}
|
package/dist/constants.js
CHANGED
|
@@ -179,7 +179,9 @@ Read skill \`references/\` files with absolute paths — the shell's cwd is not
|
|
|
179
179
|
|
|
180
180
|
\`.claude/launch.json\` declares this app's dev server for Claude Code's browser preview
|
|
181
181
|
(\`npm run dev\` on port 5173, \`--strictPort\`) — start it from there rather than rediscovering
|
|
182
|
-
the command.
|
|
182
|
+
the command. \`--strictPort\` failing because 5173 is busy means an orphaned dev server from an
|
|
183
|
+
earlier session owns the port — kill the listener (\`lsof -tiTCP:5173 -sTCP:LISTEN | xargs kill\`)
|
|
184
|
+
and relaunch; don't move the app to another port.
|
|
183
185
|
|
|
184
186
|
## Docs
|
|
185
187
|
|
package/dist/display.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"display.d.ts","sourceRoot":"","sources":["../src/display.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"display.d.ts","sourceRoot":"","sources":["../src/display.ts"],"names":[],"mappings":"AAKA,wBAAgB,aAAa,IAAI,IAAI,CAMpC;AAED,wBAAgB,cAAc,CAAC,SAAS,EAAE,MAAM,GAAG,IAAI,CA2BtD;AAED,wBAAgB,YAAY,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI,CAElD;AAED,wBAAgB,WAAW,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI,CAEjD;AAED,wBAAgB,gBAAgB,IAAI,IAAI,CAEvC"}
|
package/dist/display.js
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import chalk from 'chalk';
|
|
2
2
|
import figures from 'figures';
|
|
3
3
|
import { MESSAGES } from './constants.js';
|
|
4
|
+
import { detectPackageManager } from './package-manager.js';
|
|
4
5
|
export function displayHeader() {
|
|
5
6
|
console.log();
|
|
6
7
|
console.log(chalk.cyan('━'.repeat(50)));
|
|
@@ -14,9 +15,12 @@ export function displaySuccess(targetDir) {
|
|
|
14
15
|
console.log();
|
|
15
16
|
console.log(chalk.bold(MESSAGES.NEXT_STEPS));
|
|
16
17
|
console.log();
|
|
18
|
+
// Mirror the package manager that invoked the CLI — `<pm> install` and
|
|
19
|
+
// `<pm> run dev` are valid for all four supported PMs.
|
|
20
|
+
const pm = detectPackageManager();
|
|
17
21
|
console.log(chalk.cyan(` cd ${targetDir}`));
|
|
18
|
-
console.log(chalk.cyan(
|
|
19
|
-
console.log(chalk.cyan(
|
|
22
|
+
console.log(chalk.cyan(` ${pm} install`));
|
|
23
|
+
console.log(chalk.cyan(` ${pm} run dev`));
|
|
20
24
|
console.log();
|
|
21
25
|
console.log(chalk.gray(' Your app includes a beautiful logo-centric homepage'));
|
|
22
26
|
console.log(chalk.gray(' showcasing Bestax, Vite, and React branding.'));
|
package/dist/file-system.d.ts
CHANGED
|
@@ -2,7 +2,7 @@ export declare function checkDirectoryExists(targetPath: string): Promise<boolea
|
|
|
2
2
|
export declare function isDirectoryEmpty(targetPath: string): Promise<boolean>;
|
|
3
3
|
export declare function emptyDirectory(targetPath: string): Promise<void>;
|
|
4
4
|
export declare function ensureDirectory(targetPath: string): Promise<void>;
|
|
5
|
-
export declare function copyDirectory(source: string, destination: string): Promise<void>;
|
|
5
|
+
export declare function copyDirectory(source: string, destination: string, renames?: Record<string, string>): Promise<void>;
|
|
6
6
|
export declare function readJsonFile<T = unknown>(filePath: string): Promise<T>;
|
|
7
7
|
export declare function writeJsonFile(filePath: string, data: unknown, spaces?: number): Promise<void>;
|
|
8
8
|
export declare function updatePackageJson(targetPath: string, projectName: string): Promise<void>;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"file-system.d.ts","sourceRoot":"","sources":["../src/file-system.ts"],"names":[],"mappings":"AAIA,wBAAsB,oBAAoB,CACxC,UAAU,EAAE,MAAM,GACjB,OAAO,CAAC,OAAO,CAAC,CAElB;AAED,wBAAsB,gBAAgB,CAAC,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAM3E;AAED,wBAAsB,cAAc,CAAC,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAEtE;AAED,wBAAsB,eAAe,CAAC,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAEvE;AAED,wBAAsB,aAAa,CACjC,MAAM,EAAE,MAAM,EACd,WAAW,EAAE,MAAM,
|
|
1
|
+
{"version":3,"file":"file-system.d.ts","sourceRoot":"","sources":["../src/file-system.ts"],"names":[],"mappings":"AAIA,wBAAsB,oBAAoB,CACxC,UAAU,EAAE,MAAM,GACjB,OAAO,CAAC,OAAO,CAAC,CAElB;AAED,wBAAsB,gBAAgB,CAAC,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAM3E;AAED,wBAAsB,cAAc,CAAC,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAEtE;AAED,wBAAsB,eAAe,CAAC,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAEvE;AAED,wBAAsB,aAAa,CACjC,MAAM,EAAE,MAAM,EACd,WAAW,EAAE,MAAM,EACnB,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GAC/B,OAAO,CAAC,IAAI,CAAC,CAef;AAED,wBAAsB,YAAY,CAAC,CAAC,GAAG,OAAO,EAAE,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,CAAC,CAAC,CAE5E;AAED,wBAAsB,aAAa,CACjC,QAAQ,EAAE,MAAM,EAChB,IAAI,EAAE,OAAO,EACb,MAAM,SAAI,GACT,OAAO,CAAC,IAAI,CAAC,CAEf;AAED,wBAAsB,iBAAiB,CACrC,UAAU,EAAE,MAAM,EAClB,WAAW,EAAE,MAAM,GAClB,OAAO,CAAC,IAAI,CAAC,CAQf"}
|
package/dist/file-system.js
CHANGED
|
@@ -17,11 +17,21 @@ export async function emptyDirectory(targetPath) {
|
|
|
17
17
|
export async function ensureDirectory(targetPath) {
|
|
18
18
|
await fs.ensureDir(targetPath);
|
|
19
19
|
}
|
|
20
|
-
export async function copyDirectory(source, destination) {
|
|
20
|
+
export async function copyDirectory(source, destination, renames) {
|
|
21
21
|
if (!(await checkDirectoryExists(source))) {
|
|
22
22
|
throw new Error(MESSAGES.TEMPLATE_NOT_FOUND(source));
|
|
23
23
|
}
|
|
24
24
|
await fs.copy(source, destination);
|
|
25
|
+
if (renames) {
|
|
26
|
+
for (const [from, to] of Object.entries(renames)) {
|
|
27
|
+
const copiedPath = path.join(destination, from);
|
|
28
|
+
if (fs.existsSync(copiedPath)) {
|
|
29
|
+
await fs.move(copiedPath, path.join(destination, to), {
|
|
30
|
+
overwrite: true,
|
|
31
|
+
});
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
}
|
|
25
35
|
}
|
|
26
36
|
export async function readJsonFile(filePath) {
|
|
27
37
|
return fs.readJson(filePath);
|
package/dist/index.js
CHANGED
|
File without changes
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
export type PackageManager = 'npm' | 'pnpm' | 'yarn' | 'bun';
|
|
2
|
+
/** Detect the package manager that invoked the CLI from npm_config_user_agent
|
|
3
|
+
* (e.g. "pnpm/9.12.0 npm/? node/v22 darwin arm64"). Falls back to npm. */
|
|
4
|
+
export declare function detectPackageManager(userAgent?: string | undefined): PackageManager;
|
|
5
|
+
//# sourceMappingURL=package-manager.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"package-manager.d.ts","sourceRoot":"","sources":["../src/package-manager.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,cAAc,GAAG,KAAK,GAAG,MAAM,GAAG,MAAM,GAAG,KAAK,CAAC;AAI7D;2EAC2E;AAC3E,wBAAgB,oBAAoB,CAClC,SAAS,GAAE,MAAM,GAAG,SAA6C,GAChE,cAAc,CAKhB"}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
const KNOWN = ['npm', 'pnpm', 'yarn', 'bun'];
|
|
2
|
+
/** Detect the package manager that invoked the CLI from npm_config_user_agent
|
|
3
|
+
* (e.g. "pnpm/9.12.0 npm/? node/v22 darwin arm64"). Falls back to npm. */
|
|
4
|
+
export function detectPackageManager(userAgent = process.env.npm_config_user_agent) {
|
|
5
|
+
const name = userAgent?.split('/')[0] ?? '';
|
|
6
|
+
return KNOWN.includes(name)
|
|
7
|
+
? name
|
|
8
|
+
: 'npm';
|
|
9
|
+
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"project-creator.d.ts","sourceRoot":"","sources":["../src/project-creator.ts"],"names":[],"mappings":"AA2BA,OAAO,EAOL,KAAK,eAAe,EACrB,MAAM,gBAAgB,CAAC;
|
|
1
|
+
{"version":3,"file":"project-creator.d.ts","sourceRoot":"","sources":["../src/project-creator.ts"],"names":[],"mappings":"AA2BA,OAAO,EAOL,KAAK,eAAe,EACrB,MAAM,gBAAgB,CAAC;AAWxB,MAAM,WAAW,aAAa;IAC5B,WAAW,EAAE,MAAM,CAAC;IACpB,QAAQ,EAAE,MAAM,CAAC;IACjB,UAAU,EAAE,MAAM,CAAC;IACnB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB;AAED,MAAM,WAAW,UAAU;IACzB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,GAAG,CAAC,EAAE,OAAO,CAAC;CACf;AAED,qBAAa,cAAc;IACzB,OAAO,CAAC,YAAY,CAAS;gBAEjB,YAAY,CAAC,EAAE,MAAM;IAI3B,cAAc,CAAC,UAAU,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC;IAa3D,sBAAsB,CAC1B,UAAU,EAAE,MAAM,EAClB,SAAS,EAAE,MAAM,GAChB,OAAO,CAAC,OAAO,CAAC;IAkBnB,eAAe,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM;IAInC,YAAY,CAAC,QAAQ,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAMjE,oBAAoB,CACxB,UAAU,EAAE,MAAM,EAClB,WAAW,EAAE,MAAM,GAClB,OAAO,CAAC,IAAI,CAAC;IAgBV,WAAW,CACf,UAAU,EAAE,MAAM,EAClB,WAAW,EAAE,MAAM,EACnB,OAAO,EAAE,eAAe,GACvB,OAAO,CAAC,IAAI,CAAC;IAqBV,gBAAgB,CACpB,UAAU,EAAE,MAAM,EAClB,WAAW,EAAE,MAAM,EACnB,QAAQ,EAAE,MAAM,GACf,OAAO,CAAC,IAAI,CAAC;IAmDhB,OAAO,CAAC,WAAW;IA2BnB,OAAO,CAAC,YAAY;IAYd,gBAAgB,CACpB,UAAU,EAAE,MAAM,EAClB,WAAW,EAAE,MAAM,EACnB,QAAQ,EAAE,MAAM,GACf,OAAO,CAAC,IAAI,CAAC;IAgJV,mBAAmB,CACvB,UAAU,EAAE,MAAM,EAClB,WAAW,EAAE,MAAM,EACnB,WAAW,EAAE,MAAM,EACnB,QAAQ,EAAE,MAAM,GACf,OAAO,CAAC,IAAI,CAAC;IAmEV,MAAM,CAAC,UAAU,CAAC,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,UAAU,GAAG,OAAO,CAAC,IAAI,CAAC;CAyIvE"}
|
package/dist/project-creator.js
CHANGED
|
@@ -8,6 +8,12 @@ import { displayHeader, displaySuccess, displayError, displayCancelled, } from '
|
|
|
8
8
|
import { validateProjectName } from './validators.js';
|
|
9
9
|
import { MESSAGES, ICON_LIBRARIES, BULMA_FLAVORS, CLAUDE_MD, LAUNCH_JSON, CONFIG_PROVIDER_ICON_VALUES, } from './constants.js';
|
|
10
10
|
const __dirname = path.dirname(fileURLToPath(import.meta.url));
|
|
11
|
+
// npm strips literal `.gitignore` files from published tarballs, so the
|
|
12
|
+
// templates track `_gitignore` instead and the scaffolder renames it back
|
|
13
|
+
// on copy — otherwise published scaffolds would ship with no .gitignore.
|
|
14
|
+
const TEMPLATE_RENAMES = {
|
|
15
|
+
_gitignore: '.gitignore',
|
|
16
|
+
};
|
|
11
17
|
export class ProjectCreator {
|
|
12
18
|
templatesDir;
|
|
13
19
|
constructor(templatesDir) {
|
|
@@ -43,7 +49,7 @@ export class ProjectCreator {
|
|
|
43
49
|
async copyTemplate(template, targetPath) {
|
|
44
50
|
const templatePath = this.getTemplatePath(template);
|
|
45
51
|
await ensureDirectory(targetPath);
|
|
46
|
-
await copyDirectory(templatePath, targetPath);
|
|
52
|
+
await copyDirectory(templatePath, targetPath, TEMPLATE_RENAMES);
|
|
47
53
|
}
|
|
48
54
|
async updateIndexHtmlTitle(targetPath, projectName) {
|
|
49
55
|
const indexHtmlPath = path.join(targetPath, 'index.html');
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "create-bestax",
|
|
3
|
-
"version": "4.
|
|
3
|
+
"version": "4.1.1",
|
|
4
4
|
"description": "Create a new bestax-bulma project",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"bin": {
|
|
@@ -10,25 +10,6 @@
|
|
|
10
10
|
"dist",
|
|
11
11
|
"templates"
|
|
12
12
|
],
|
|
13
|
-
"scripts": {
|
|
14
|
-
"build": "node scripts/sync-skills.mjs && tsc",
|
|
15
|
-
"prepack": "node scripts/sync-skills.mjs",
|
|
16
|
-
"dev": "tsc --watch",
|
|
17
|
-
"test": "NODE_OPTIONS=\"--experimental-vm-modules\" jest",
|
|
18
|
-
"test:watch": "NODE_OPTIONS=\"--experimental-vm-modules\" jest --watch",
|
|
19
|
-
"test:coverage": "NODE_OPTIONS=\"--experimental-vm-modules\" jest --coverage",
|
|
20
|
-
"test:e2e": "playwright test --config=e2e/playwright.config.ts",
|
|
21
|
-
"test:e2e:ui": "playwright test --config=e2e/playwright.config.ts --ui",
|
|
22
|
-
"test:e2e:headed": "playwright test --config=e2e/playwright.config.ts --headed",
|
|
23
|
-
"test:e2e:update": "playwright test --config=e2e/playwright.config.ts --update-snapshots",
|
|
24
|
-
"test:e2e:report": "playwright show-report e2e/playwright-report",
|
|
25
|
-
"lint": "eslint src e2e/tests e2e/utils",
|
|
26
|
-
"typecheck": "tsc --noEmit",
|
|
27
|
-
"format": "prettier --write \"src/**/*.{ts,tsx}\"",
|
|
28
|
-
"format:check": "prettier --check \"src/**/*.{ts,tsx}\"",
|
|
29
|
-
"clean": "rimraf dist",
|
|
30
|
-
"release": "npx semantic-release"
|
|
31
|
-
},
|
|
32
13
|
"keywords": [
|
|
33
14
|
"bestax",
|
|
34
15
|
"bulma",
|
|
@@ -73,7 +54,25 @@
|
|
|
73
54
|
"wait-on": "^9.1.0"
|
|
74
55
|
},
|
|
75
56
|
"publishConfig": {
|
|
76
|
-
"access": "public"
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
57
|
+
"access": "public"
|
|
58
|
+
},
|
|
59
|
+
"scripts": {
|
|
60
|
+
"build": "node scripts/sync-skills.mjs && tsc",
|
|
61
|
+
"dev": "tsc --watch",
|
|
62
|
+
"test": "NODE_OPTIONS=\"--experimental-vm-modules\" jest",
|
|
63
|
+
"test:watch": "NODE_OPTIONS=\"--experimental-vm-modules\" jest --watch",
|
|
64
|
+
"test:coverage": "NODE_OPTIONS=\"--experimental-vm-modules\" jest --coverage",
|
|
65
|
+
"test:e2e": "playwright test --config=e2e/playwright.config.ts",
|
|
66
|
+
"test:e2e:ui": "playwright test --config=e2e/playwright.config.ts --ui",
|
|
67
|
+
"test:e2e:headed": "playwright test --config=e2e/playwright.config.ts --headed",
|
|
68
|
+
"test:e2e:update": "playwright test --config=e2e/playwright.config.ts --update-snapshots",
|
|
69
|
+
"test:e2e:report": "playwright show-report e2e/playwright-report",
|
|
70
|
+
"lint": "eslint src e2e/tests e2e/utils",
|
|
71
|
+
"typecheck": "tsc --noEmit",
|
|
72
|
+
"format": "prettier --write \"src/**/*.{ts,tsx}\"",
|
|
73
|
+
"format:check": "prettier --check \"src/**/*.{ts,tsx}\"",
|
|
74
|
+
"clean": "rimraf dist",
|
|
75
|
+
"release": "npx semantic-release"
|
|
76
|
+
},
|
|
77
|
+
"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://socket.dev/npm/package/create-bestax/overview)\n[](https://scorecard.dev/viewer/?uri=github.com/allxsmith/bestax)\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## 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"
|
|
78
|
+
}
|
|
@@ -50,11 +50,12 @@ label — use that instead"_ or _"No `ProfileCard` exists; I'll build one compos
|
|
|
50
50
|
|
|
51
51
|
Build from existing components before writing any CSS: `Box`, `Card`, `Title`, `SubTitle`,
|
|
52
52
|
`Icon`, `Block`, `Content`, `Tag`, plus the shared Bulma helper props (spacing, color,
|
|
53
|
-
typography, flexbox).
|
|
54
|
-
`
|
|
53
|
+
typography, flexbox). Some compound sub-parts are the exception — `Modal.Card`, `Tabs.Tab`,
|
|
54
|
+
`Message.Body` take **no Bulma helper props**, just `className` + HTML attributes
|
|
55
55
|
plus their own few (`Tabs.Tab` requires `index={i}` and has built-in `disabled` and
|
|
56
56
|
`icon`/`iconLibrary`/`iconVariant`/`iconSize`/`iconFeatures` — don't nest an `<Icon>` there) —
|
|
57
|
-
so put helper props on the parent or on an element inside them, never invent them there.
|
|
57
|
+
so put helper props on the parent or on an element inside them, never invent them there.
|
|
58
|
+
(`Card.*` sub-parts do take helper props, like `Table.*`/`Menu.*`/`Hero.*`.) Most "custom components" are a composition function — zero new styles.
|
|
58
59
|
See `examples/stat-card.tsx` for a complete worked example.
|
|
59
60
|
|
|
60
61
|
## The component spine
|
|
@@ -12,11 +12,23 @@ Everything below is public API. Where to import from depends on your context:
|
|
|
12
12
|
Turns Bulma helper props into a class string and returns the leftover (non-helper) props.
|
|
13
13
|
|
|
14
14
|
```ts
|
|
15
|
-
const { bulmaHelperClasses, rest } = useBulmaClasses(props);
|
|
15
|
+
const { bulmaHelperClasses, bulmaHelperStyles, rest } = useBulmaClasses(props);
|
|
16
16
|
// bulmaHelperClasses: e.g. 'has-text-primary is-size-3 m-3'
|
|
17
|
-
//
|
|
17
|
+
// bulmaHelperStyles: inline styles for scheme-aware values, or undefined (see below)
|
|
18
|
+
// rest: every prop that was NOT a recognized helper; destructure your own
|
|
19
|
+
// component props and `style` before spreading it on a DOM element
|
|
18
20
|
```
|
|
19
21
|
|
|
22
|
+
`bulmaHelperStyles` is `undefined` unless `backgroundColor` is one of the six
|
|
23
|
+
`validSchemeColors` values (`scheme-main`, `scheme-main-bis`, `scheme-main-ter`,
|
|
24
|
+
`scheme-invert`, `scheme-invert-bis`, `scheme-invert-ter`). Bulma ships no
|
|
25
|
+
`has-background-scheme-*` classes, so those values emit no class; the hook returns
|
|
26
|
+
`{ backgroundColor: 'var(--bulma-<value>)' }` instead — a dark-mode-safe inline style. Put it
|
|
27
|
+
on the root element with `mergeBulmaStyles(bulmaHelperStyles, style)`
|
|
28
|
+
(`helpers/mergeBulmaStyles.ts`): the user's `style` prop wins on conflicts, and the result is
|
|
29
|
+
`undefined` when both are absent so unaffected components keep an attribute-free DOM.
|
|
30
|
+
(`useColorStyles` is the underlying per-concern hook.)
|
|
31
|
+
|
|
20
32
|
`BulmaClassesProps` is the union of all helper prop groups, composed from per-concern hooks
|
|
21
33
|
that can also be used on their own:
|
|
22
34
|
|
|
@@ -31,9 +43,10 @@ that can also be used on their own:
|
|
|
31
43
|
|
|
32
44
|
Because the component destructures these into `bulmaHelperClasses`, callers get the full Bulma
|
|
33
45
|
helper surface for free on every component built this way, and `rest` stays clean for DOM
|
|
34
|
-
spreading. (
|
|
46
|
+
spreading. (Some library compound sub-parts — `Modal.Card`, `Tabs.Tab`,
|
|
35
47
|
`Message.Body` — do **not** take helper props: just `className`, HTML attributes, and their own
|
|
36
|
-
few, e.g. `Tabs.Tab`'s required `index` and its built-in `icon`/`disabled` props.
|
|
48
|
+
few, e.g. `Tabs.Tab`'s required `index` and its built-in `icon`/`disabled` props. `Card.*`
|
|
49
|
+
sub-parts do take them.)
|
|
37
50
|
|
|
38
51
|
## `classNames(...)` and friends — `helpers/classNames.ts`
|
|
39
52
|
|
|
@@ -55,16 +68,22 @@ de-dupes. Related exports:
|
|
|
55
68
|
Re-exported through `useBulmaClasses`. Use them to type component-specific props and to drive
|
|
56
69
|
Storybook `argTypes`/tests:
|
|
57
70
|
|
|
58
|
-
`validColors`, `validColorShades`, `
|
|
59
|
-
`validTextTransforms`, `validTextWeights`, `validFontFamilies`,
|
|
60
|
-
`validVisibilities`, `validFlexDirections`, `validFlexWraps`,
|
|
61
|
-
`validAlignContents`, `validAlignItems`, `validAlignSelfs`,
|
|
62
|
-
`validViewports`.
|
|
71
|
+
`validColors`, `validColorShades`, `validSchemeColors`, `validSizes`, `validTextSizes`,
|
|
72
|
+
`validAlignments`, `validTextTransforms`, `validTextWeights`, `validFontFamilies`,
|
|
73
|
+
`validDisplays`, `validVisibilities`, `validFlexDirections`, `validFlexWraps`,
|
|
74
|
+
`validJustifyContents`, `validAlignContents`, `validAlignItems`, `validAlignSelfs`,
|
|
75
|
+
`validFlexGrowShrink`, `validViewports`.
|
|
63
76
|
|
|
64
77
|
```ts
|
|
65
78
|
export type MyColor = (typeof validColors)[number];
|
|
66
79
|
```
|
|
67
80
|
|
|
81
|
+
`validSchemeColors` is the scheme-background tuple consumed by `bulmaHelperStyles` (above).
|
|
82
|
+
Components that support scheme backgrounds widen their own `bgColor` union with
|
|
83
|
+
`(typeof validSchemeColors)[number]` — the widening is deliberate and per-component, so a
|
|
84
|
+
component that has not wired `bulmaHelperStyles` onto its root element must keep the narrow
|
|
85
|
+
union (a compile error beats a silent no-op).
|
|
86
|
+
|
|
68
87
|
## `ConfigProvider` / `Theme` — `helpers/Config.tsx`, `helpers/Theme.tsx`
|
|
69
88
|
|
|
70
89
|
`ConfigProvider` provides the runtime `classPrefix` (and `iconLibrary`) consumed via `useConfig`;
|
|
@@ -24,8 +24,8 @@ instead of hand-writing markup.
|
|
|
24
24
|
- **Compound components** expose sub-parts via dot access (e.g. `Card.Header`,
|
|
25
25
|
`Navbar.Item`, `Tabs.Tab`, `Hero.Body`, `Columns.Column`, `Table.Tr`); see the
|
|
26
26
|
component's linked page for the full set. Sub-parts do **not** all take helper
|
|
27
|
-
props: the `Table.*`, `Menu.*`, and `Hero.*` families do (most
|
|
28
|
-
too), but `
|
|
27
|
+
props: the `Card.*`, `Table.*`, `Menu.*`, and `Hero.*` families do (most
|
|
28
|
+
`Navbar.*` too), but `Modal.*`, `Tabs.*`, and `Message.*` sub-parts take none —
|
|
29
29
|
just `className`, HTML attributes, and their own few (`Tabs.Tab` requires
|
|
30
30
|
`index` and has built-in `icon`/`disabled` props). Put helper props on the
|
|
31
31
|
parent or on an element inside (`Span`, `Paragraph`, …) instead.
|
|
@@ -143,7 +143,7 @@ component is guaranteed to appear (the generator fails if one lacks an API page)
|
|
|
143
143
|
|
|
144
144
|
- [ConfigProvider](https://bestax.io/docs/api/helpers/config) — The `ConfigProvider` component provides a React context for configuring global settings across all Bulma UI components.
|
|
145
145
|
- [Theme](https://bestax.io/docs/api/helpers/theme) — The `Theme` component provides a powerful way to customize Bulma's appearance using CSS custom properties (CSS variables).
|
|
146
|
-
- [Valid value constants](https://bestax.io/docs/api/helpers/valid-values) — The `valid*`
|
|
146
|
+
- [Valid value constants](https://bestax.io/docs/api/helpers/valid-values) — The `valid*` tuples enumerate the core accepted values for the shared Bulma helper props — public API for building prop types and validation.
|
|
147
147
|
- [classNames](https://bestax.io/docs/api/helpers/classnames) — `classNames` is a utility function for conditionally joining class names together.
|
|
148
148
|
- [useBulmaClasses](https://bestax.io/docs/api/helpers/usebulmaclasses) — `useBulmaClasses` is a custom React hook that generates Bulma helper class strings from a set of props.
|
|
149
149
|
- [usePrefixedClassNames](https://bestax.io/docs/api/helpers/useprefixedclassnames) — `usePrefixedClassNames` builds a component class string that honors the `classPrefix` from `ConfigProvider` — the hook every bestax component uses for its own…
|
|
@@ -96,6 +96,9 @@ All import from `@allxsmith/bestax-bulma`. Convenience components auto-wrap Fiel
|
|
|
96
96
|
| `Taginput` | Tag/chip input; suggestions, confirm keys, closable tags. |
|
|
97
97
|
| `DateInput` / `TimeInput` / `DateTimeInput` (+ `*Base`) | Date / time / datetime pickers. |
|
|
98
98
|
|
|
99
|
+
(`NumberInput` and `TagInput` also exist as deprecated aliases of `Numberinput`/`Taginput` —
|
|
100
|
+
same components; prefer the lowercase-second-word spellings.)
|
|
101
|
+
|
|
99
102
|
## Common props
|
|
100
103
|
|
|
101
104
|
Across the convenience inputs (`Input`, `Select`, `TextArea`, and similar):
|
|
@@ -116,8 +119,10 @@ Across the convenience inputs (`Input`, `Select`, `TextArea`, and similar):
|
|
|
116
119
|
Plus the full Bulma **helper props** (`m`, `p`, `textColor`, `display`, …) on every component
|
|
117
120
|
via `useBulmaClasses`.
|
|
118
121
|
|
|
119
|
-
|
|
120
|
-
`
|
|
122
|
+
Full-width is `isFullwidth` on every component that supports it (`Button`, `LinkButton`,
|
|
123
|
+
`Select`, `File`, `Table`, `Tabs`, `Sidebar`) — always write `isFullwidth`. The deprecated
|
|
124
|
+
spellings compile only where they historically existed: `isFullWidth` everywhere except
|
|
125
|
+
`Sidebar`, `fullwidth` on `Tabs` only, `fullWidth` on `Sidebar` only.
|
|
121
126
|
|
|
122
127
|
The `label` prop on the single-control convenience inputs (`Input`, `Select`, `TextArea`,
|
|
123
128
|
`File`, `Numberinput`, `Slider`, `DateInput`, `TimeInput`, `DateTimeInput`, `Autocomplete`,
|
|
@@ -59,7 +59,7 @@ Wraps a single input; adds icons and loading.
|
|
|
59
59
|
## Select / SelectBase, TextArea / TextAreaBase
|
|
60
60
|
|
|
61
61
|
Same convenience/raw split as Input. `Select` supports `isLoading` (on the control), `color`,
|
|
62
|
-
`size`, `isRounded`, `isFullwidth
|
|
62
|
+
`size`, `isRounded`, `isFullwidth`, `multiple` +
|
|
63
63
|
`multipleSize`, plus the Field/Control/message props. `TextArea` adds `rows` and
|
|
64
64
|
`hasFixedSize`.
|
|
65
65
|
|
|
@@ -70,10 +70,15 @@ Centered; a collection of items → Card grid. For mixed requests, pick the domi
|
|
|
70
70
|
`textWeight`, `textSize` directly (their `color` prop colors the cell; for muted cell text
|
|
71
71
|
wrap content in `Span textColor="grey"`). Set the app-wide icon library once with
|
|
72
72
|
`<ConfigProvider iconLibrary="…">` at the root rather than `library` on every `<Icon>`.
|
|
73
|
-
- **
|
|
73
|
+
- **Alternating section bands are a prop, not CSS: `bgColor="scheme-main-bis"` on every
|
|
74
|
+
other `Section` (next band `scheme-main-ter`).** The scheme values render as a
|
|
75
|
+
dark-mode-safe inline `background-color: var(--bulma-scheme-*)` — zero custom CSS — and
|
|
76
|
+
still never `bgColor="light"`/`"white"`: those are fixed colors that stay light when dark
|
|
77
|
+
mode flips the text.
|
|
78
|
+
- **Decorative CSS is budgeted: two compact rules, ≤10 lines per app — comments count:
|
|
74
79
|
at most one short inline note, never a file-header comment block — every value derived
|
|
75
|
-
from `--bulma-*`.** A marketing page gets at most one hero wash
|
|
76
|
-
|
|
80
|
+
from `--bulma-*`.** A marketing page gets at most one hero wash and one featured-card
|
|
81
|
+
ring, applied via `className` — no resets (Bulma ships one;
|
|
77
82
|
body/list margins are already zero) and no grid textures, masks, or multi-layer backdrops;
|
|
78
83
|
the components carry the design:
|
|
79
84
|
|
|
@@ -85,9 +90,6 @@ Centered; a collection of items → Card grid. For mixed requests, pick the domi
|
|
|
85
90
|
transparent 60%
|
|
86
91
|
);
|
|
87
92
|
}
|
|
88
|
-
.section-alt {
|
|
89
|
-
background: var(--bulma-scheme-main-bis); /* next band: -ter */
|
|
90
|
-
}
|
|
91
93
|
.featured-ring {
|
|
92
94
|
--bulma-shadow: 0 0 0 2px var(--bulma-primary);
|
|
93
95
|
}
|
|
@@ -188,8 +190,10 @@ inline `style`.
|
|
|
188
190
|
- [ ] Style with helper props, not inline `style` — translate via the mapping table; values
|
|
189
191
|
with no helper get a named class in the stylesheet, never `style={{}}`. No raw Bulma
|
|
190
192
|
`className`s either (`Span`/`Paragraph` wrap bare text; `Th`/`Td` take `textAlign`/`textWeight`).
|
|
191
|
-
- [ ]
|
|
192
|
-
|
|
193
|
+
- [ ] Alternating bands are `bgColor="scheme-main-bis"` (next band `scheme-main-ter`) on
|
|
194
|
+
every other `Section` — never band CSS, never `bgColor="light"`/`"white"`.
|
|
195
|
+
- [ ] Decorative CSS ≤10 lines total incl. comments — no file-header comment (hero wash +
|
|
196
|
+
featured-card ring), `--bulma-*`-derived; no resets — Bulma ships one.
|
|
193
197
|
The ring sets `--bulma-shadow` in a CSS rule; `Theme bulmaVars` has no such key.
|
|
194
198
|
- [ ] Set the icon library once via `<ConfigProvider iconLibrary="…">` at the root.
|
|
195
199
|
- [ ] Site built? ~800 KB raw / ~82 KB gzip CSS is the expected default-flavor size — to shrink
|
|
@@ -155,8 +155,11 @@ the `Hero`; if it's `fixed="top"`, the same `<html class="has-navbar-fixed-top">
|
|
|
155
155
|
applies here too.
|
|
156
156
|
|
|
157
157
|
**Alternating section bands:** tint every other `Section` with a scheme step —
|
|
158
|
-
|
|
159
|
-
|
|
158
|
+
`bgColor="scheme-main-bis"` (next step `scheme-main-ter`) — not `bgColor="light"`/`"white"`:
|
|
159
|
+
those are fixed colors that stay light when dark mode flips the text. Scheme values emit no
|
|
160
|
+
class; the component renders a dark-mode-safe inline `background-color: var(--bulma-scheme-*)`
|
|
161
|
+
style, so bands cost zero custom CSS. The same values work on `Hero` (and its
|
|
162
|
+
`Head`/`Body`/`Foot`), `Footer`, `Container`, `Box`, and `Card`.
|
|
160
163
|
|
|
161
164
|
**Hero CTAs:** on a colored hero use **filled** buttons only — `color="light"` for the primary
|
|
162
165
|
CTA and `color="primary" isInverted` (solid white, primary text) for a secondary. A thin
|
|
@@ -118,6 +118,18 @@ The responsive grid. `Columns` is the row; `Column` is a cell (also reachable as
|
|
|
118
118
|
```ts
|
|
119
119
|
type BulmaColumnSize =
|
|
120
120
|
| number // 1–12
|
|
121
|
+
| '1'
|
|
122
|
+
| '2'
|
|
123
|
+
| '3'
|
|
124
|
+
| '4'
|
|
125
|
+
| '5'
|
|
126
|
+
| '6'
|
|
127
|
+
| '7'
|
|
128
|
+
| '8'
|
|
129
|
+
| '9'
|
|
130
|
+
| '10'
|
|
131
|
+
| '11'
|
|
132
|
+
| '12' // string form, equivalent
|
|
121
133
|
| 'full'
|
|
122
134
|
| 'half'
|
|
123
135
|
| 'one-third'
|
|
@@ -130,8 +142,8 @@ type BulmaColumnSize =
|
|
|
130
142
|
| 'four-fifths';
|
|
131
143
|
```
|
|
132
144
|
|
|
133
|
-
Numeric sizes
|
|
134
|
-
|
|
145
|
+
Numeric sizes accept a number **or** its string form — `sizeDesktop={7}` and
|
|
146
|
+
`sizeDesktop="7"` are equivalent, and the fraction names are strings.
|
|
135
147
|
|
|
136
148
|
> Columns **stack on mobile** by default and go side-by-side at the tablet breakpoint and up.
|
|
137
149
|
> Use the per-breakpoint `size*` props to control how many cells share a row at each width.
|
|
@@ -157,7 +169,9 @@ the column's auto height). Make the `Column` a flex container and let the card g
|
|
|
157
169
|
```
|
|
158
170
|
|
|
159
171
|
`display`, `flexDirection`, and `flexGrow` are helper props every component accepts;
|
|
160
|
-
`flexGrow` takes a string (`"1"`).
|
|
172
|
+
`flexGrow` takes a string (`"1"`). `Card.*` sub-parts accept helper props too, so pinning a
|
|
173
|
+
footer inside a card is `<Card display="flex" flexDirection="column">` +
|
|
174
|
+
`<Card.Content flexGrow="1">` — no `Box` swap needed.
|
|
161
175
|
|
|
162
176
|
## Grid / Cell
|
|
163
177
|
|
|
@@ -32,7 +32,7 @@ this automatically for literal values; dynamic values get TODOs.
|
|
|
32
32
|
## Boolean modifier convention
|
|
33
33
|
|
|
34
34
|
RBC uses bare booleans (`loading`, `outlined`, `rounded`, `fullwidth`); bestax prefixes
|
|
35
|
-
with `is`/`has` (`isLoading`, `isOutlined`, `isRounded`, `
|
|
35
|
+
with `is`/`has` (`isLoading`, `isOutlined`, `isRounded`, `isFullwidth`). Per-component
|
|
36
36
|
tables live in [component-map.md](component-map.md).
|
|
37
37
|
|
|
38
38
|
## Responsive breakpoint objects → flat per-viewport props
|
|
@@ -44,9 +44,13 @@ color tokens or fixed-color surfaces exist:
|
|
|
44
44
|
(`--my-canvas: var(--bulma-scheme-main)`) — or flip them yourself under **both** dark-mode
|
|
45
45
|
paths: `[data-theme='dark']` **and** `@media (prefers-color-scheme: dark)` scoped to
|
|
46
46
|
`:root:not([data-theme])`, since `colorMode="system"` removes the attribute (snippets in
|
|
47
|
-
`references/css-variables.md`). Alternating/tinted section bands are
|
|
48
|
-
`
|
|
49
|
-
`
|
|
47
|
+
`references/css-variables.md`). Alternating/tinted section bands are first-class props:
|
|
48
|
+
`bgColor="scheme-main-bis"` (then `"scheme-main-ter"`) on `Section` (also `Hero`, `Footer`,
|
|
49
|
+
`Container`, `Box`, `Card`) renders a scheme-tracking inline background — never
|
|
50
|
+
`bgColor="light"`: `light`/`white`/grey helper backgrounds are fixed colors that fight
|
|
51
|
+
dark mode. Keep the derive-from-scheme-vars CSS for other custom surfaces. `Theme
|
|
52
|
+
bulmaVars` now accepts `--bulma-scheme-main`/`-bis`/`-ter` (and the `-invert` trio)
|
|
53
|
+
overrides, so one Theme re-tints every band at once.
|
|
50
54
|
- **Fixed-color surface → fixed-color content.** On a surface that never changes (a dark hero,
|
|
51
55
|
a brand banner), pin the content's colors too: solid/filled buttons and explicit text colors,
|
|
52
56
|
never scheme-derived defaults or thin outlines that depend on the flipping scheme.
|
|
@@ -81,13 +81,14 @@ and numeric shades `--bulma-<c>-00` … `--bulma-<c>-95`.
|
|
|
81
81
|
|
|
82
82
|
## Scheme, text, background, border (light/dark surfaces)
|
|
83
83
|
|
|
84
|
-
| Variable
|
|
85
|
-
|
|
|
86
|
-
| `--bulma-scheme-h`, `--bulma-scheme-s`
|
|
87
|
-
| `--bulma-scheme-main`, `--bulma-scheme-main-bis`, `--bulma-scheme-main-ter`
|
|
88
|
-
| `--bulma-
|
|
89
|
-
| `--bulma-
|
|
90
|
-
| `--bulma-
|
|
84
|
+
| Variable | Role |
|
|
85
|
+
| --------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
86
|
+
| `--bulma-scheme-h`, `--bulma-scheme-s` | scheme hue/saturation (`Theme`: `schemeH`, `schemeS`) |
|
|
87
|
+
| `--bulma-scheme-main`, `--bulma-scheme-main-bis`, `--bulma-scheme-main-ter` | page/surface backgrounds (main + subtle steps); `Theme bulmaVars`-overridable, and the scheme `bgColor` values render them inline |
|
|
88
|
+
| `--bulma-scheme-invert`, `--bulma-scheme-invert-bis`, `--bulma-scheme-invert-ter` | inverted scheme surfaces; `Theme bulmaVars`-overridable, and the scheme `bgColor` values render them inline (pair with a foreground — see the color guide) |
|
|
89
|
+
| `--bulma-background` | secondary background |
|
|
90
|
+
| `--bulma-text`, `--bulma-text-strong`, `--bulma-text-weak` | body / emphasized / muted text |
|
|
91
|
+
| `--bulma-border`, `--bulma-border-weak` | borders |
|
|
91
92
|
|
|
92
93
|
## Radius, typography
|
|
93
94
|
|
|
@@ -50,14 +50,14 @@ Shades (`colorShade` / `backgroundColorShade`): `00, 05, 10, … 95, invert, lig
|
|
|
50
50
|
| ------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------ | ------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
51
51
|
| `Button` | `primary \| link \| info \| success \| warning \| danger \| white \| light \| dark \| black \| text \| ghost` | `small \| normal \| medium \| large` | adds `text`, `ghost`; also `isLight`, `isOutlined`, `isInverted`, `isRounded` |
|
|
52
52
|
| `Notification` | the 17 `validColors` (`black-bis`, `black-ter`, and greys deprecated: no CSS, dev-warn, removed next major — see ⚠️) | — | also `isLight` |
|
|
53
|
-
| `Tag` | `primary \| link \| info \| success \| warning \| danger \| black \| dark \| light \| white` | `normal \| medium \| large` | also `isRounded`, `isDelete`, `isHoverable`
|
|
53
|
+
| `Tag` | `primary \| link \| info \| success \| warning \| danger \| black \| dark \| light \| white` | `normal \| medium \| large` | also `isLight`, `isRounded`, `isDelete`, `isHoverable` |
|
|
54
54
|
| `Box` | `primary \| link \| info \| success \| warning \| danger` | — | `color` renders `has-text-<color>`, same as `textColor` (which wins when both are set; no `.box.is-*` ships — tint via `bgColor`); also `hasShadow` |
|
|
55
55
|
| `Message` | `primary \| link \| info \| success \| warning \| danger` | — | the 6 only |
|
|
56
56
|
| `Input` | `primary \| link \| info \| success \| warning \| danger \| black \| dark \| light \| white` | `small \| medium \| large` | also `isRounded`, `isStatic` |
|
|
57
57
|
| `Avatar` | `primary \| link \| info \| success \| warning \| danger \| black \| dark \| light \| white` | `16x16 \| 24x24 \| 32x32 \| 48x48 \| 64x64 \| 96x96 \| 128x128 \| number` | initials/icon background (auto-derived from `name` when unset); also `shape` |
|
|
58
58
|
| `Badge` | `primary \| link \| info \| success \| warning \| danger \| black \| dark \| light \| white` | — | pill background; default `danger` |
|
|
59
|
-
| `Title` | — (no `color`; use `textColor`) | `1
|
|
60
|
-
| `SubTitle` | — (no `color`; use `textColor`) | `1
|
|
59
|
+
| `Title` | — (no `color`; use `textColor`) | `1`–`6` (string or number) | also `isSpaced` |
|
|
60
|
+
| `SubTitle` | — (no `color`; use `textColor`) | `1`–`6` (string or number) | — |
|
|
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` |
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
# Logs
|
|
2
|
+
logs
|
|
3
|
+
*.log
|
|
4
|
+
npm-debug.log*
|
|
5
|
+
yarn-debug.log*
|
|
6
|
+
yarn-error.log*
|
|
7
|
+
pnpm-debug.log*
|
|
8
|
+
lerna-debug.log*
|
|
9
|
+
|
|
10
|
+
node_modules
|
|
11
|
+
dist
|
|
12
|
+
dist-ssr
|
|
13
|
+
*.local
|
|
14
|
+
*.tsbuildinfo
|
|
15
|
+
|
|
16
|
+
# Editor directories and files
|
|
17
|
+
.vscode/*
|
|
18
|
+
!.vscode/extensions.json
|
|
19
|
+
.idea
|
|
20
|
+
.DS_Store
|
|
21
|
+
*.suo
|
|
22
|
+
*.ntvs*
|
|
23
|
+
*.njsproj
|
|
24
|
+
*.sln
|
|
25
|
+
*.sw?
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
# Logs
|
|
2
|
+
logs
|
|
3
|
+
*.log
|
|
4
|
+
npm-debug.log*
|
|
5
|
+
yarn-debug.log*
|
|
6
|
+
yarn-error.log*
|
|
7
|
+
pnpm-debug.log*
|
|
8
|
+
lerna-debug.log*
|
|
9
|
+
|
|
10
|
+
node_modules
|
|
11
|
+
dist
|
|
12
|
+
dist-ssr
|
|
13
|
+
*.local
|
|
14
|
+
*.tsbuildinfo
|
|
15
|
+
|
|
16
|
+
# Editor directories and files
|
|
17
|
+
.vscode/*
|
|
18
|
+
!.vscode/extensions.json
|
|
19
|
+
.idea
|
|
20
|
+
.DS_Store
|
|
21
|
+
*.suo
|
|
22
|
+
*.ntvs*
|
|
23
|
+
*.njsproj
|
|
24
|
+
*.sln
|
|
25
|
+
*.sw?
|