create-lacspace-app 1.15.0 → 1.16.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 +24 -6
- package/dist/index.js +98 -5
- package/package.json +2 -2
package/README.md
CHANGED
|
@@ -99,23 +99,41 @@ Every template is Next.js 15 App Router + React 19 + Tailwind v4 — dark, moder
|
|
|
99
99
|
| Flag | Meaning |
|
|
100
100
|
| --- | --- |
|
|
101
101
|
| `-t, --template <key>` | `personal` · `business` · `ecommerce` · `saas` · `blog` · `docs` · `dashboard` · `restaurant` |
|
|
102
|
+
| `--theme <name\|hex>` | accent gradient — a preset, a `"#hex"`, or `"from,to"` (see below) |
|
|
102
103
|
| `--pm <npm\|pnpm\|yarn\|bun>` | package manager (default `npm`) |
|
|
103
104
|
| `--no-install` | skip installing dependencies |
|
|
104
105
|
| `--no-git` | skip git init |
|
|
105
106
|
| `-y, --yes` | accept defaults (needs a project name) |
|
|
106
107
|
|
|
108
|
+
### 🎨 Themes
|
|
109
|
+
|
|
110
|
+
Recolour the whole app — gradient, OG images, favicon and PWA theme colour — at scaffold time with `--theme`:
|
|
111
|
+
|
|
112
|
+
```bash
|
|
113
|
+
npx create-lacspace-app my-app --template saas --theme lacspace # a named preset
|
|
114
|
+
npx create-lacspace-app my-app --theme "#ff6a00" # one colour → auto gradient
|
|
115
|
+
npx create-lacspace-app my-app --theme "#0bb9d9,#7c3aed" # an exact from → to pair
|
|
116
|
+
```
|
|
117
|
+
|
|
118
|
+
**Presets:** `lacspace` · `violet` · `indigo` · `blue` · `cyan` · `sky` · `teal` · `emerald` · `green` · `lime` · `amber` · `orange` · `red` · `rose` · `pink` · `fuchsia` · `purple` · `slate` · `sunset` · `ocean` · `forest` · `aurora` · `gold`. Give a single hex and the CLI derives a matching second stop for you.
|
|
119
|
+
|
|
107
120
|
## Licensing
|
|
108
121
|
|
|
109
|
-
Free under the **[Lacspace Free Licence](https://lacspace.com/licenses/lacspace-free-1.0)** —
|
|
122
|
+
Free under the **[Lacspace Free Licence](https://lacspace.com/licenses/lacspace-free-1.0)** — permissive freedoms. Use it in personal and commercial projects at no cost; the apps you generate are entirely yours.
|
|
123
|
+
|
|
124
|
+
<!-- LACSPACE-DEV-PLATFORM -->
|
|
110
125
|
|
|
111
126
|
---
|
|
112
127
|
|
|
113
|
-
|
|
128
|
+
## The Lacspace Developer Platform
|
|
114
129
|
|
|
115
|
-
|
|
130
|
+
`create-lacspace-app` is part of **63 zero-dependency, isomorphic TypeScript packages** — one standard library for the modern web. Explore the ecosystem:
|
|
116
131
|
|
|
117
|
-
|
|
132
|
+
- 🗂️ **All 63 packages** — https://developer.lacspace.com/packages
|
|
133
|
+
- 🧭 **Developer handbook** — guides & runnable recipes — https://developer.lacspace.com/handbook
|
|
134
|
+
- 🧪 **Live playground** — run any package in your browser — https://developer.lacspace.com/playground
|
|
135
|
+
- 🖥️ **Finished app templates** — https://templates.lacspace.com
|
|
136
|
+
- 🚀 **Scaffold a full app** — `npm create lacspace-app@latest`
|
|
118
137
|
|
|
119
|
-
|
|
138
|
+
Free under the **[Lacspace Free Licence](https://lacspace.com/licenses/lacspace-free-1.0)** — a permissive, free-to-use licence.
|
|
120
139
|
|
|
121
|
-
<div align="center"><sub>Built with care by <a href="https://lacspace.com">Lacspace</a> · Lacspace Free Licence</sub></div>
|
package/dist/index.js
CHANGED
|
@@ -35,11 +35,11 @@ var pkgJson = (ctx) => JSON.stringify({
|
|
|
35
35
|
next: "^15.1.0",
|
|
36
36
|
react: "^19.0.0",
|
|
37
37
|
"react-dom": "^19.0.0",
|
|
38
|
-
"@lacspace/seo": "^1.
|
|
38
|
+
"@lacspace/seo": "^1.7.0",
|
|
39
39
|
"@lacspace/headers": "^1.1.2",
|
|
40
|
-
"@lacspace/robots": "^1.
|
|
41
|
-
"@lacspace/sitemap": "^1.
|
|
42
|
-
"@lacspace/og": "^1.0
|
|
40
|
+
"@lacspace/robots": "^1.3.0",
|
|
41
|
+
"@lacspace/sitemap": "^1.2.0",
|
|
42
|
+
"@lacspace/og": "^1.1.0",
|
|
43
43
|
"@lacspace/ui": "^1.0.1",
|
|
44
44
|
"@lacspace/form": "^1.0.1",
|
|
45
45
|
"@lacspace/validate": "^1.0.1",
|
|
@@ -3450,12 +3450,92 @@ function parseArgs(list) {
|
|
|
3450
3450
|
else if (arg === "--no-install") a.install = false;
|
|
3451
3451
|
else if (arg === "--no-git") a.git = false;
|
|
3452
3452
|
else if (arg === "--pm") a.pm = next();
|
|
3453
|
+
else if (arg === "--theme" || arg === "--accent") a.theme = next();
|
|
3453
3454
|
else if (arg === "-h" || arg === "--help") a.help = true;
|
|
3454
3455
|
else if (arg.startsWith("--template=")) a.template = arg.slice(11);
|
|
3456
|
+
else if (arg.startsWith("--theme=")) a.theme = arg.slice(8);
|
|
3457
|
+
else if (arg.startsWith("--accent=")) a.theme = arg.slice(9);
|
|
3455
3458
|
else if (!arg.startsWith("-") && !a.name) a.name = arg;
|
|
3456
3459
|
}
|
|
3457
3460
|
return a;
|
|
3458
3461
|
}
|
|
3462
|
+
var THEMES = {
|
|
3463
|
+
lacspace: ["#0bb9d9", "#7c3aed"],
|
|
3464
|
+
violet: ["#7c3aed", "#ec4899"],
|
|
3465
|
+
indigo: ["#6366f1", "#a855f7"],
|
|
3466
|
+
blue: ["#2563eb", "#06b6d4"],
|
|
3467
|
+
cyan: ["#0891b2", "#22d3ee"],
|
|
3468
|
+
sky: ["#0ea5e9", "#38bdf8"],
|
|
3469
|
+
teal: ["#0d9488", "#22c55e"],
|
|
3470
|
+
emerald: ["#10b981", "#14b8a6"],
|
|
3471
|
+
green: ["#16a34a", "#4ade80"],
|
|
3472
|
+
lime: ["#65a30d", "#a3e635"],
|
|
3473
|
+
amber: ["#f59e0b", "#f97316"],
|
|
3474
|
+
orange: ["#ea580c", "#f59e0b"],
|
|
3475
|
+
red: ["#dc2626", "#f97316"],
|
|
3476
|
+
rose: ["#e11d48", "#fb7185"],
|
|
3477
|
+
pink: ["#db2777", "#f472b6"],
|
|
3478
|
+
fuchsia: ["#c026d3", "#f0abfc"],
|
|
3479
|
+
purple: ["#9333ea", "#d946ef"],
|
|
3480
|
+
slate: ["#475569", "#94a3b8"],
|
|
3481
|
+
sunset: ["#f97316", "#db2777"],
|
|
3482
|
+
ocean: ["#0ea5e9", "#6366f1"],
|
|
3483
|
+
forest: ["#16a34a", "#65a30d"],
|
|
3484
|
+
aurora: ["#22d3ee", "#a855f7"],
|
|
3485
|
+
gold: ["#d97706", "#facc15"]
|
|
3486
|
+
};
|
|
3487
|
+
var normHex = (h) => {
|
|
3488
|
+
let s = h.trim().replace(/^#/, "");
|
|
3489
|
+
if (/^[0-9a-fA-F]{3}$/.test(s)) s = s.split("").map((ch) => ch + ch).join("");
|
|
3490
|
+
return /^[0-9a-fA-F]{6}$/.test(s) ? "#" + s.toLowerCase() : null;
|
|
3491
|
+
};
|
|
3492
|
+
var hexToRgb = (h) => {
|
|
3493
|
+
const n = parseInt(h.slice(1), 16);
|
|
3494
|
+
return [n >> 16 & 255, n >> 8 & 255, n & 255];
|
|
3495
|
+
};
|
|
3496
|
+
var rgbToHex = (r, g, b) => "#" + [r, g, b].map((x) => Math.max(0, Math.min(255, Math.round(x))).toString(16).padStart(2, "0")).join("");
|
|
3497
|
+
var rgbToHsl = (r, g, b) => {
|
|
3498
|
+
r /= 255;
|
|
3499
|
+
g /= 255;
|
|
3500
|
+
b /= 255;
|
|
3501
|
+
const max = Math.max(r, g, b), min = Math.min(r, g, b);
|
|
3502
|
+
let h = 0, s = 0;
|
|
3503
|
+
const l = (max + min) / 2;
|
|
3504
|
+
if (max !== min) {
|
|
3505
|
+
const d = max - min;
|
|
3506
|
+
s = l > 0.5 ? d / (2 - max - min) : d / (max + min);
|
|
3507
|
+
h = max === r ? (g - b) / d + (g < b ? 6 : 0) : max === g ? (b - r) / d + 2 : (r - g) / d + 4;
|
|
3508
|
+
h /= 6;
|
|
3509
|
+
}
|
|
3510
|
+
return [h * 360, s, l];
|
|
3511
|
+
};
|
|
3512
|
+
var hslToRgb = (h, s, l) => {
|
|
3513
|
+
h = (h % 360 + 360) % 360 / 360;
|
|
3514
|
+
const q = l < 0.5 ? l * (1 + s) : l + s - l * s, p = 2 * l - q;
|
|
3515
|
+
const hue = (t) => {
|
|
3516
|
+
t = (t + 1) % 1;
|
|
3517
|
+
return t < 1 / 6 ? p + (q - p) * 6 * t : t < 1 / 2 ? q : t < 2 / 3 ? p + (q - p) * (2 / 3 - t) * 6 : p;
|
|
3518
|
+
};
|
|
3519
|
+
return [hue(h + 1 / 3) * 255, hue(h) * 255, hue(h - 1 / 3) * 255];
|
|
3520
|
+
};
|
|
3521
|
+
var hexPair = (hex) => {
|
|
3522
|
+
const [h, s, l] = rgbToHsl(...hexToRgb(hex));
|
|
3523
|
+
const [r2, g2, b2] = hslToRgb(h + 28, Math.min(1, s + 0.05), Math.min(0.72, l + 0.1));
|
|
3524
|
+
return [hex, rgbToHex(r2, g2, b2)];
|
|
3525
|
+
};
|
|
3526
|
+
function resolveAccent(theme) {
|
|
3527
|
+
if (!theme) return null;
|
|
3528
|
+
const key = theme.toLowerCase().trim();
|
|
3529
|
+
if (THEMES[key]) return THEMES[key];
|
|
3530
|
+
if (key.includes(",")) {
|
|
3531
|
+
const [a, b] = key.split(",").map((p) => normHex(p));
|
|
3532
|
+
if (a && b) return [a, b];
|
|
3533
|
+
if (a) return hexPair(a);
|
|
3534
|
+
return null;
|
|
3535
|
+
}
|
|
3536
|
+
const one = normHex(key);
|
|
3537
|
+
return one ? hexPair(one) : null;
|
|
3538
|
+
}
|
|
3459
3539
|
var HELP = `
|
|
3460
3540
|
${c("bold", "create-lacspace-app")} \u2014 scaffold a beautiful Next.js app, Lacspace-wired
|
|
3461
3541
|
|
|
@@ -3469,12 +3549,17 @@ ${TEMPLATES.map((t) => ` ${t.key.padEnd(10)} ${t.description}`).join("\n")}
|
|
|
3469
3549
|
|
|
3470
3550
|
${c("bold", "Options")}
|
|
3471
3551
|
-t, --template <key> Template (${TEMPLATES.map((t) => t.key).join(" | ")})
|
|
3552
|
+
--theme <name|hex> Accent: a preset, a "#hex", or "from,to" (e.g. --theme lacspace)
|
|
3472
3553
|
--pm <npm|pnpm|yarn|bun> Package manager (default npm)
|
|
3473
3554
|
--no-install Skip installing dependencies
|
|
3474
3555
|
--no-git Skip git init
|
|
3475
3556
|
-y, --yes Accept defaults (needs <name>)
|
|
3476
3557
|
-h, --help Show this help
|
|
3477
3558
|
|
|
3559
|
+
${c("bold", "Themes")} ${c("dim", "(--theme)")}
|
|
3560
|
+
${Object.keys(THEMES).join(" \xB7 ")}
|
|
3561
|
+
${c("dim", 'or a custom colour: --theme "#ff6a00" \xB7 --theme "#0bb9d9,#7c3aed"')}
|
|
3562
|
+
|
|
3478
3563
|
${c("bold", "Add sections to an existing app")}
|
|
3479
3564
|
npx create-lacspace-app add pricing faq testimonials
|
|
3480
3565
|
${c("dim", "Drops prebuilt, themed sections into components/sections/ (and the UI kit if missing).")}
|
|
@@ -3770,7 +3855,15 @@ ${c("green", "?")} Template ${c("dim", "(1)")}: `)).trim() || "1";
|
|
|
3770
3855
|
}
|
|
3771
3856
|
}
|
|
3772
3857
|
name = name ?? "my-app";
|
|
3773
|
-
const
|
|
3858
|
+
const base = TEMPLATES.find((t) => t.key === templateKey) ?? TEMPLATES[0];
|
|
3859
|
+
const accent = resolveAccent(args.theme);
|
|
3860
|
+
if (args.theme && !accent) {
|
|
3861
|
+
stdout.write(c("yellow", ` ! Unknown theme "${args.theme}" \u2014 using the ${base.key} default. Try a preset (${Object.keys(THEMES).slice(0, 6).join(", ")}\u2026) or a hex like "#ff6a00".
|
|
3862
|
+
`));
|
|
3863
|
+
}
|
|
3864
|
+
const template = accent ? { ...base, accent } : base;
|
|
3865
|
+
if (accent) stdout.write(` ${c("dim", "theme")} ${c("bold", args.theme)} ${c("dim", `\u2192 ${accent[0]} \u2192 ${accent[1]}`)}
|
|
3866
|
+
`);
|
|
3774
3867
|
const dir = resolve(cwd(), name);
|
|
3775
3868
|
const projectName = basename(dir).toLowerCase().replace(/[^a-z0-9-_]/g, "-");
|
|
3776
3869
|
if (existsSync(dir) && readdirSync(dir).length > 0) {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "create-lacspace-app",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.16.1",
|
|
4
4
|
"description": "Scaffold a beautiful, production-ready Next.js app from a Lacspace template — portfolio, business, e-commerce, SaaS, blog, docs, dashboard or restaurant — pre-wired with SEO, security headers, sitemap and robots. Like create-next-app, but you start gorgeous.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"bin": {
|
|
@@ -34,7 +34,7 @@
|
|
|
34
34
|
],
|
|
35
35
|
"author": "Lacspace <contact@lacspace.com>",
|
|
36
36
|
"license": "SEE LICENSE IN LICENSE",
|
|
37
|
-
"homepage": "https://lacspace.com
|
|
37
|
+
"homepage": "https://templates.lacspace.com",
|
|
38
38
|
"repository": {
|
|
39
39
|
"type": "git",
|
|
40
40
|
"url": "git+https://github.com/lacspace/npm-packages.git",
|