@lucaismyname/create-l1-stack 0.0.16 → 0.0.18

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 (2) hide show
  1. package/package.json +1 -1
  2. package/src/index.js +116 -0
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@lucaismyname/create-l1-stack",
3
- "version": "0.0.16",
3
+ "version": "0.0.18",
4
4
  "type": "module",
5
5
  "publishConfig": {
6
6
  "access": "public"
package/src/index.js CHANGED
@@ -14,6 +14,104 @@ const TEMPLATE_PKG_TS = '@lucaismyname/l1-template-ts'
14
14
  const TEMPLATE_PKG_JS = '@lucaismyname/l1-template-js'
15
15
  const TEMPLATE_PATH_PREFIX = 'package/template/'
16
16
 
17
+ const THEME_PRESETS = {
18
+ slate: {
19
+ light: {
20
+ primary: 'oklch(0.205 0 0)',
21
+ primaryForeground: 'oklch(0.985 0 0)',
22
+ ring: 'oklch(0.708 0 0)',
23
+ },
24
+ dark: {
25
+ primary: 'oklch(0.922 0 0)',
26
+ primaryForeground: 'oklch(0.205 0 0)',
27
+ ring: 'oklch(0.556 0 0)',
28
+ },
29
+ },
30
+ blue: {
31
+ light: {
32
+ primary: 'oklch(0.62 0.19 255)',
33
+ primaryForeground: 'oklch(0.98 0 0)',
34
+ ring: 'oklch(0.62 0.19 255)',
35
+ },
36
+ dark: {
37
+ primary: 'oklch(0.78 0.14 255)',
38
+ primaryForeground: 'oklch(0.18 0 0)',
39
+ ring: 'oklch(0.78 0.14 255)',
40
+ },
41
+ },
42
+ emerald: {
43
+ light: {
44
+ primary: 'oklch(0.67 0.17 155)',
45
+ primaryForeground: 'oklch(0.98 0 0)',
46
+ ring: 'oklch(0.67 0.17 155)',
47
+ },
48
+ dark: {
49
+ primary: 'oklch(0.78 0.14 155)',
50
+ primaryForeground: 'oklch(0.18 0 0)',
51
+ ring: 'oklch(0.78 0.14 155)',
52
+ },
53
+ },
54
+ violet: {
55
+ light: {
56
+ primary: 'oklch(0.62 0.23 300)',
57
+ primaryForeground: 'oklch(0.98 0 0)',
58
+ ring: 'oklch(0.62 0.23 300)',
59
+ },
60
+ dark: {
61
+ primary: 'oklch(0.75 0.18 300)',
62
+ primaryForeground: 'oklch(0.18 0 0)',
63
+ ring: 'oklch(0.75 0.18 300)',
64
+ },
65
+ },
66
+ rose: {
67
+ light: {
68
+ primary: 'oklch(0.62 0.24 20)',
69
+ primaryForeground: 'oklch(0.98 0 0)',
70
+ ring: 'oklch(0.62 0.24 20)',
71
+ },
72
+ dark: {
73
+ primary: 'oklch(0.74 0.18 20)',
74
+ primaryForeground: 'oklch(0.18 0 0)',
75
+ ring: 'oklch(0.74 0.18 20)',
76
+ },
77
+ },
78
+ }
79
+
80
+ function updateCssVarInBlock(css, blockSelector, varName, value) {
81
+ const blockRe = new RegExp(`(${blockSelector}\\s*\\{)([\\s\\S]*?)(\\})`, 'm')
82
+ const match = css.match(blockRe)
83
+ if (!match) return css
84
+
85
+ const [full, open, body, close] = match
86
+ const varRe = new RegExp(`(^\\s*${varName}:\\s*)([^;]+)(;\\s*$)`, 'm')
87
+ if (!varRe.test(body)) return css
88
+
89
+ const nextBody = body.replace(varRe, `$1${value}$3`)
90
+ return css.replace(full, `${open}${nextBody}${close}`)
91
+ }
92
+
93
+ async function applyPrimaryTheme(targetDir, preset) {
94
+ const indexCssPath = path.join(targetDir, 'src', 'index.css')
95
+ try {
96
+ const css = await fs.readFile(indexCssPath, 'utf8')
97
+ let next = css
98
+
99
+ next = updateCssVarInBlock(next, ':root', '--primary', preset.light.primary)
100
+ next = updateCssVarInBlock(next, ':root', '--primary-foreground', preset.light.primaryForeground)
101
+ next = updateCssVarInBlock(next, ':root', '--ring', preset.light.ring)
102
+
103
+ next = updateCssVarInBlock(next, '\\.dark', '--primary', preset.dark.primary)
104
+ next = updateCssVarInBlock(next, '\\.dark', '--primary-foreground', preset.dark.primaryForeground)
105
+ next = updateCssVarInBlock(next, '\\.dark', '--ring', preset.dark.ring)
106
+
107
+ if (next !== css) {
108
+ await fs.writeFile(indexCssPath, next, 'utf8')
109
+ }
110
+ } catch {
111
+ // ignore if index.css doesn't exist
112
+ }
113
+ }
114
+
17
115
  function toKebabCaseName(input) {
18
116
  return input
19
117
  .trim()
@@ -143,6 +241,22 @@ async function main() {
143
241
  process.exit(0)
144
242
  }
145
243
 
244
+ const primaryColor = await select({
245
+ message: 'Primary color',
246
+ options: [
247
+ { value: 'slate', label: 'Slate (default)' },
248
+ { value: 'blue', label: 'Blue' },
249
+ { value: 'emerald', label: 'Emerald' },
250
+ { value: 'violet', label: 'Violet' },
251
+ { value: 'rose', label: 'Rose' },
252
+ ],
253
+ initialValue: 'slate',
254
+ })
255
+ if (isCancel(primaryColor)) {
256
+ cancel('Cancelled')
257
+ process.exit(0)
258
+ }
259
+
146
260
  const targetDir = path.resolve(process.cwd(), projectName)
147
261
  // NOTE: npm downloads the CLI package before prompts run.
148
262
  // To avoid downloading both templates, we fetch only the chosen template from npm.
@@ -194,6 +308,8 @@ async function main() {
194
308
  }
195
309
  }
196
310
 
311
+ await applyPrimaryTheme(targetDir, THEME_PRESETS[primaryColor] ?? THEME_PRESETS.slate)
312
+
197
313
  // Update package name
198
314
  const pkgJsonPath = path.join(targetDir, 'package.json')
199
315
  const pkg = await fse.readJson(pkgJsonPath)