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.
Files changed (3) hide show
  1. package/README.md +24 -6
  2. package/dist/index.js +98 -5
  3. 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)** — MIT-equivalent freedoms. Use it in personal and commercial projects at no cost; the apps you generate are entirely yours.
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
- <div align="center">
128
+ ## The Lacspace Developer Platform
114
129
 
115
- **Part of the Lacspace ecosystem — 60+ zero-dependency, isomorphic TypeScript packages.**
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
- [All packages ↗](https://lacspace.com/packages) · [Docs ↗](https://lacspace.com/docs) · [npm org ↗](https://www.npmjs.com/org/lacspace) · [GitHub ↗](https://github.com/lacspace/npm-packages)
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
- </div>
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.6.2",
38
+ "@lacspace/seo": "^1.7.0",
39
39
  "@lacspace/headers": "^1.1.2",
40
- "@lacspace/robots": "^1.2.1",
41
- "@lacspace/sitemap": "^1.1.1",
42
- "@lacspace/og": "^1.0.1",
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 template = TEMPLATES.find((t) => t.key === templateKey) ?? TEMPLATES[0];
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.15.0",
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/packages",
37
+ "homepage": "https://templates.lacspace.com",
38
38
  "repository": {
39
39
  "type": "git",
40
40
  "url": "git+https://github.com/lacspace/npm-packages.git",