create-bearnie 0.2.0 → 0.3.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/README.md +25 -6
- package/dist/index.js +155 -2
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -12,15 +12,25 @@ npx create-bearnie
|
|
|
12
12
|
npm create bearnie my-app
|
|
13
13
|
```
|
|
14
14
|
|
|
15
|
-
##
|
|
15
|
+
## Options
|
|
16
16
|
|
|
17
|
-
|
|
17
|
+
### `--full`
|
|
18
|
+
|
|
19
|
+
Include all components from the start:
|
|
18
20
|
|
|
19
21
|
```bash
|
|
20
|
-
|
|
22
|
+
npx create-bearnie my-app --full
|
|
21
23
|
```
|
|
22
24
|
|
|
23
|
-
This
|
|
25
|
+
This fetches all components from the registry and installs them in your project.
|
|
26
|
+
|
|
27
|
+
### `--theme`
|
|
28
|
+
|
|
29
|
+
Apply a custom theme from the [theme builder](https://bearnie.dev/create-bearnie-theme):
|
|
30
|
+
|
|
31
|
+
```bash
|
|
32
|
+
npx create-bearnie my-app --theme="https://bearnie.dev/create-bearnie-theme#..."
|
|
33
|
+
```
|
|
24
34
|
|
|
25
35
|
## What's included
|
|
26
36
|
|
|
@@ -30,18 +40,27 @@ This applies your custom colors, radius, and font to the project's CSS.
|
|
|
30
40
|
- Simple landing page to get started
|
|
31
41
|
- Ready for components via `npx bearnie add`
|
|
32
42
|
|
|
43
|
+
With `--full` flag:
|
|
44
|
+
- All Bearnie UI components
|
|
45
|
+
- Utility functions (`cn`, `focus-trap`)
|
|
46
|
+
- Additional dependencies (`clsx`, `tailwind-merge`)
|
|
47
|
+
|
|
33
48
|
## After creating your project
|
|
34
49
|
|
|
35
50
|
```bash
|
|
36
51
|
cd my-app
|
|
37
52
|
npm install
|
|
38
|
-
npx bearnie add button card dialog
|
|
39
53
|
npm run dev
|
|
40
54
|
```
|
|
41
55
|
|
|
56
|
+
Without `--full`, add components as needed:
|
|
57
|
+
|
|
58
|
+
```bash
|
|
59
|
+
npx bearnie add button card dialog
|
|
60
|
+
```
|
|
61
|
+
|
|
42
62
|
## Learn more
|
|
43
63
|
|
|
44
64
|
- [Bearnie Documentation](https://bearnie.dev/docs)
|
|
45
|
-
- [Theme Builder](https://bearnie.dev/create)
|
|
46
65
|
- [Browse Components](https://bearnie.dev/docs/components)
|
|
47
66
|
- [GitHub](https://github.com/michael-andreuzza/bearnie)
|
package/dist/index.js
CHANGED
|
@@ -13,7 +13,83 @@ var link = (text, url) => `\x1B]8;;${url}\x07${pc.cyan(text)}\x1B]8;;\x07`;
|
|
|
13
13
|
function parseThemeArg() {
|
|
14
14
|
const themeArg = process.argv.find((arg) => arg.startsWith("--theme="));
|
|
15
15
|
if (!themeArg) return null;
|
|
16
|
-
|
|
16
|
+
const equalIndex = themeArg.indexOf("=");
|
|
17
|
+
let value = themeArg.slice(equalIndex + 1);
|
|
18
|
+
if (value.startsWith('"') && value.endsWith('"') || value.startsWith("'") && value.endsWith("'")) {
|
|
19
|
+
value = value.slice(1, -1);
|
|
20
|
+
}
|
|
21
|
+
return value;
|
|
22
|
+
}
|
|
23
|
+
function parseFullArg() {
|
|
24
|
+
return process.argv.includes("--full");
|
|
25
|
+
}
|
|
26
|
+
var REGISTRY_URL = "https://bearnie.dev/registry";
|
|
27
|
+
var COMPONENT_NAMES = [
|
|
28
|
+
"accordion",
|
|
29
|
+
"alert",
|
|
30
|
+
"alert-dialog",
|
|
31
|
+
"aspect-ratio",
|
|
32
|
+
"avatar",
|
|
33
|
+
"badge",
|
|
34
|
+
"breadcrumb",
|
|
35
|
+
"button",
|
|
36
|
+
"button-group",
|
|
37
|
+
"card",
|
|
38
|
+
"carousel",
|
|
39
|
+
"checkbox",
|
|
40
|
+
"collapsible",
|
|
41
|
+
"command",
|
|
42
|
+
"context-menu",
|
|
43
|
+
"dialog",
|
|
44
|
+
"dropdown-menu",
|
|
45
|
+
"empty",
|
|
46
|
+
"file-upload",
|
|
47
|
+
"hover-card",
|
|
48
|
+
"input",
|
|
49
|
+
"input-group",
|
|
50
|
+
"input-otp",
|
|
51
|
+
"kbd",
|
|
52
|
+
"label",
|
|
53
|
+
"menubar",
|
|
54
|
+
"pagination",
|
|
55
|
+
"popover",
|
|
56
|
+
"progress",
|
|
57
|
+
"radio",
|
|
58
|
+
"scroll-area",
|
|
59
|
+
"select",
|
|
60
|
+
"separator",
|
|
61
|
+
"sheet",
|
|
62
|
+
"sidebar",
|
|
63
|
+
"skeleton",
|
|
64
|
+
"slider",
|
|
65
|
+
"spinner",
|
|
66
|
+
"stepper",
|
|
67
|
+
"switch",
|
|
68
|
+
"table",
|
|
69
|
+
"tabs",
|
|
70
|
+
"textarea",
|
|
71
|
+
"toast",
|
|
72
|
+
"toggle",
|
|
73
|
+
"tooltip",
|
|
74
|
+
"tree"
|
|
75
|
+
];
|
|
76
|
+
async function fetchComponent(name) {
|
|
77
|
+
try {
|
|
78
|
+
const response = await fetch(`${REGISTRY_URL}/${name}.json`);
|
|
79
|
+
if (!response.ok) return null;
|
|
80
|
+
return await response.json();
|
|
81
|
+
} catch {
|
|
82
|
+
return null;
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
async function fetchUtility(name) {
|
|
86
|
+
try {
|
|
87
|
+
const response = await fetch(`${REGISTRY_URL}/${name}.json`);
|
|
88
|
+
if (!response.ok) return null;
|
|
89
|
+
return await response.json();
|
|
90
|
+
} catch {
|
|
91
|
+
return null;
|
|
92
|
+
}
|
|
17
93
|
}
|
|
18
94
|
function extractThemeHash(themeUrl) {
|
|
19
95
|
try {
|
|
@@ -204,6 +280,7 @@ function generateThemeCSS(config) {
|
|
|
204
280
|
}
|
|
205
281
|
async function main() {
|
|
206
282
|
const themeUrl = parseThemeArg();
|
|
283
|
+
const fullInstall = parseFullArg();
|
|
207
284
|
let themeConfig = null;
|
|
208
285
|
if (themeUrl) {
|
|
209
286
|
const hash = extractThemeHash(themeUrl);
|
|
@@ -216,6 +293,7 @@ async function main() {
|
|
|
216
293
|
|
|
217
294
|
${amber("Hey!")} Let's create your Bearnie project.
|
|
218
295
|
${themeConfig ? ` ${pc.dim("Using custom theme from URL")}
|
|
296
|
+
` : ""}${fullInstall ? ` ${pc.dim("Full install: including all components")}
|
|
219
297
|
` : ""}
|
|
220
298
|
`);
|
|
221
299
|
let projectName = process.argv.find(
|
|
@@ -274,6 +352,60 @@ ${themeConfig ? ` ${pc.dim("Using custom theme from URL")}
|
|
|
274
352
|
await fs.writeFile(globalCssPath, customCSS);
|
|
275
353
|
console.log(` ${pc.green("\u2713")} Applied custom theme`);
|
|
276
354
|
}
|
|
355
|
+
if (fullInstall) {
|
|
356
|
+
console.log(`
|
|
357
|
+
${pc.dim("Fetching components from registry...")}
|
|
358
|
+
`);
|
|
359
|
+
await fs.ensureDir(path.join(targetDir, "src", "components", "ui"));
|
|
360
|
+
await fs.ensureDir(path.join(targetDir, "src", "utils"));
|
|
361
|
+
const focusTrap = await fetchUtility("focus-trap");
|
|
362
|
+
if (focusTrap?.files) {
|
|
363
|
+
for (const file of focusTrap.files) {
|
|
364
|
+
const filePath = path.join(targetDir, "src", file.name);
|
|
365
|
+
await fs.ensureDir(path.dirname(filePath));
|
|
366
|
+
await fs.writeFile(filePath, file.content);
|
|
367
|
+
}
|
|
368
|
+
console.log(` ${pc.green("\u2713")} Added focus-trap utility`);
|
|
369
|
+
}
|
|
370
|
+
const cnContent = `import { clsx, type ClassValue } from "clsx";
|
|
371
|
+
import { twMerge } from "tailwind-merge";
|
|
372
|
+
|
|
373
|
+
export function cn(...inputs: ClassValue[]) {
|
|
374
|
+
return twMerge(clsx(inputs));
|
|
375
|
+
}
|
|
376
|
+
`;
|
|
377
|
+
await fs.writeFile(path.join(targetDir, "src", "utils", "cn.ts"), cnContent);
|
|
378
|
+
console.log(` ${pc.green("\u2713")} Added cn utility`);
|
|
379
|
+
let installed = 0;
|
|
380
|
+
let failed = 0;
|
|
381
|
+
for (const componentName of COMPONENT_NAMES) {
|
|
382
|
+
const component = await fetchComponent(componentName);
|
|
383
|
+
if (component?.files) {
|
|
384
|
+
for (const file of component.files) {
|
|
385
|
+
const filePath = path.join(targetDir, "src", file.name);
|
|
386
|
+
await fs.ensureDir(path.dirname(filePath));
|
|
387
|
+
await fs.writeFile(filePath, file.content);
|
|
388
|
+
}
|
|
389
|
+
installed++;
|
|
390
|
+
process.stdout.write(`\r ${pc.green("\u2713")} Installed ${installed}/${COMPONENT_NAMES.length} components`);
|
|
391
|
+
} else {
|
|
392
|
+
failed++;
|
|
393
|
+
}
|
|
394
|
+
}
|
|
395
|
+
console.log("");
|
|
396
|
+
if (failed > 0) {
|
|
397
|
+
console.log(` ${pc.yellow("!")} ${failed} components failed to fetch`);
|
|
398
|
+
}
|
|
399
|
+
const pkgPath2 = path.join(targetDir, "package.json");
|
|
400
|
+
const pkg2 = await fs.readJson(pkgPath2);
|
|
401
|
+
pkg2.dependencies = {
|
|
402
|
+
...pkg2.dependencies,
|
|
403
|
+
"clsx": "^2.1.1",
|
|
404
|
+
"tailwind-merge": "^3.3.0"
|
|
405
|
+
};
|
|
406
|
+
await fs.writeJson(pkgPath2, pkg2, { spaces: 2 });
|
|
407
|
+
console.log(` ${pc.green("\u2713")} Added component dependencies`);
|
|
408
|
+
}
|
|
277
409
|
await fs.writeFile(
|
|
278
410
|
path.join(targetDir, ".gitignore"),
|
|
279
411
|
`# Dependencies
|
|
@@ -300,7 +432,24 @@ Thumbs.db
|
|
|
300
432
|
`
|
|
301
433
|
);
|
|
302
434
|
console.log(` ${pc.green("\u2713")} Created project files`);
|
|
303
|
-
|
|
435
|
+
if (fullInstall) {
|
|
436
|
+
console.log(`
|
|
437
|
+
${pc.green("Done!")} Your Bearnie project is ready with all components.
|
|
438
|
+
|
|
439
|
+
${pc.bold("Next steps:")}
|
|
440
|
+
|
|
441
|
+
${pc.dim("1.")} cd ${pc.cyan(finalName)}
|
|
442
|
+
${pc.dim("2.")} npm install
|
|
443
|
+
${pc.dim("3.")} npm run dev
|
|
444
|
+
|
|
445
|
+
${pc.dim("All components are in")} ${pc.cyan("src/components/ui/")}
|
|
446
|
+
|
|
447
|
+
${pc.dim("Browse components at")} ${link("bearnie.dev/docs/components", "https://bearnie.dev/docs/components")}
|
|
448
|
+
|
|
449
|
+
${pc.dim("Made by")} ${link("Michael", "https://michaelandreuzza.com")} ${pc.dim("at")} ${link("Lexington Themes", "https://lexingtonthemes.com")}
|
|
450
|
+
`);
|
|
451
|
+
} else {
|
|
452
|
+
console.log(`
|
|
304
453
|
${pc.green("Done!")} Your Bearnie project is ready.
|
|
305
454
|
|
|
306
455
|
${pc.bold("Next steps:")}
|
|
@@ -310,10 +459,14 @@ Thumbs.db
|
|
|
310
459
|
${pc.dim("3.")} npx bearnie add button card
|
|
311
460
|
${pc.dim("4.")} npm run dev
|
|
312
461
|
|
|
462
|
+
${pc.dim("Or use")} ${pc.cyan("--full")} ${pc.dim("to include all components:")}
|
|
463
|
+
npx create-bearnie my-app --full
|
|
464
|
+
|
|
313
465
|
${pc.dim("Browse components at")} ${link("bearnie.dev/docs/components", "https://bearnie.dev/docs/components")}
|
|
314
466
|
|
|
315
467
|
${pc.dim("Made by")} ${link("Michael", "https://michaelandreuzza.com")} ${pc.dim("at")} ${link("Lexington Themes", "https://lexingtonthemes.com")}
|
|
316
468
|
`);
|
|
469
|
+
}
|
|
317
470
|
}
|
|
318
471
|
main().catch((err) => {
|
|
319
472
|
console.error(`
|