@lucaismyname/create-l1-stack 0.0.18 → 0.0.19
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/package.json +1 -1
- package/src/index.js +78 -0
package/package.json
CHANGED
package/src/index.js
CHANGED
|
@@ -77,6 +77,39 @@ const THEME_PRESETS = {
|
|
|
77
77
|
},
|
|
78
78
|
}
|
|
79
79
|
|
|
80
|
+
const ICON_SETS = {
|
|
81
|
+
lucide: {
|
|
82
|
+
dependency: { name: 'lucide-react', version: '^0.563.0' },
|
|
83
|
+
tsx: `import * as React from "react"\nimport {\n Check,\n ChevronDown,\n ChevronUp,\n Database,\n NotebookPen,\n Rocket,\n Server,\n} from "lucide-react"\n\ntype IconProps = React.SVGProps<SVGSVGElement>\n\nexport const Icons = {\n Check: (props: IconProps) => <Check {...props} />,\n ChevronDown: (props: IconProps) => <ChevronDown {...props} />,\n ChevronUp: (props: IconProps) => <ChevronUp {...props} />,\n Database: (props: IconProps) => <Database {...props} />,\n NotebookPen: (props: IconProps) => <NotebookPen {...props} />,\n Rocket: (props: IconProps) => <Rocket {...props} />,\n Server: (props: IconProps) => <Server {...props} />,\n}\n`,
|
|
84
|
+
jsx: `import {\n Check,\n ChevronDown,\n ChevronUp,\n Database,\n NotebookPen,\n Rocket,\n Server,\n} from "lucide-react"\n\nexport const Icons = {\n Check: (props) => <Check {...props} />,\n ChevronDown: (props) => <ChevronDown {...props} />,\n ChevronUp: (props) => <ChevronUp {...props} />,\n Database: (props) => <Database {...props} />,\n NotebookPen: (props) => <NotebookPen {...props} />,\n Rocket: (props) => <Rocket {...props} />,\n Server: (props) => <Server {...props} />,\n}\n`,
|
|
85
|
+
},
|
|
86
|
+
heroicons: {
|
|
87
|
+
dependency: { name: '@heroicons/react', version: '^2.2.0' },
|
|
88
|
+
tsx: `import * as React from "react"\nimport {\n CheckIcon,\n ChevronDownIcon,\n ChevronUpIcon,\n CircleStackIcon,\n PencilSquareIcon,\n RocketLaunchIcon,\n ServerIcon,\n} from "@heroicons/react/24/outline"\n\ntype IconProps = React.SVGProps<SVGSVGElement>\n\nexport const Icons = {\n Check: (props: IconProps) => <CheckIcon {...props} />,\n ChevronDown: (props: IconProps) => <ChevronDownIcon {...props} />,\n ChevronUp: (props: IconProps) => <ChevronUpIcon {...props} />,\n Database: (props: IconProps) => <CircleStackIcon {...props} />,\n NotebookPen: (props: IconProps) => <PencilSquareIcon {...props} />,\n Rocket: (props: IconProps) => <RocketLaunchIcon {...props} />,\n Server: (props: IconProps) => <ServerIcon {...props} />,\n}\n`,
|
|
89
|
+
jsx: `import {\n CheckIcon,\n ChevronDownIcon,\n ChevronUpIcon,\n CircleStackIcon,\n PencilSquareIcon,\n RocketLaunchIcon,\n ServerIcon,\n} from "@heroicons/react/24/outline"\n\nexport const Icons = {\n Check: (props) => <CheckIcon {...props} />,\n ChevronDown: (props) => <ChevronDownIcon {...props} />,\n ChevronUp: (props) => <ChevronUpIcon {...props} />,\n Database: (props) => <CircleStackIcon {...props} />,\n NotebookPen: (props) => <PencilSquareIcon {...props} />,\n Rocket: (props) => <RocketLaunchIcon {...props} />,\n Server: (props) => <ServerIcon {...props} />,\n}\n`,
|
|
90
|
+
},
|
|
91
|
+
tabler: {
|
|
92
|
+
dependency: { name: '@tabler/icons-react', version: '^3.31.0' },
|
|
93
|
+
tsx: `import * as React from "react"\nimport {\n IconCheck,\n IconChevronDown,\n IconChevronUp,\n IconDatabase,\n IconNotebook,\n IconRocket,\n IconServer,\n} from "@tabler/icons-react"\n\ntype IconProps = React.SVGProps<SVGSVGElement>\n\nexport const Icons = {\n Check: (props: IconProps) => <IconCheck {...props} />,\n ChevronDown: (props: IconProps) => <IconChevronDown {...props} />,\n ChevronUp: (props: IconProps) => <IconChevronUp {...props} />,\n Database: (props: IconProps) => <IconDatabase {...props} />,\n NotebookPen: (props: IconProps) => <IconNotebook {...props} />,\n Rocket: (props: IconProps) => <IconRocket {...props} />,\n Server: (props: IconProps) => <IconServer {...props} />,\n}\n`,
|
|
94
|
+
jsx: `import {\n IconCheck,\n IconChevronDown,\n IconChevronUp,\n IconDatabase,\n IconNotebook,\n IconRocket,\n IconServer,\n} from "@tabler/icons-react"\n\nexport const Icons = {\n Check: (props) => <IconCheck {...props} />,\n ChevronDown: (props) => <IconChevronDown {...props} />,\n ChevronUp: (props) => <IconChevronUp {...props} />,\n Database: (props) => <IconDatabase {...props} />,\n NotebookPen: (props) => <IconNotebook {...props} />,\n Rocket: (props) => <IconRocket {...props} />,\n Server: (props) => <IconServer {...props} />,\n}\n`,
|
|
95
|
+
},
|
|
96
|
+
radix: {
|
|
97
|
+
dependency: { name: '@radix-ui/react-icons', version: '^1.3.2' },
|
|
98
|
+
tsx: `import * as React from "react"\nimport { CheckIcon, ChevronDownIcon, ChevronUpIcon } from "@radix-ui/react-icons"\n\ntype IconProps = React.SVGProps<SVGSVGElement>\n\nconst FallbackIcon = (props: IconProps) => (\n <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round" {...props}>\n <path d="M12 2l3 7h7l-5.5 4 2 7L12 16l-6.5 4 2-7L2 9h7l3-7z" />\n </svg>\n)\n\nexport const Icons = {\n Check: (props: IconProps) => <CheckIcon {...props} />,\n ChevronDown: (props: IconProps) => <ChevronDownIcon {...props} />,\n ChevronUp: (props: IconProps) => <ChevronUpIcon {...props} />,\n Database: (props: IconProps) => <FallbackIcon {...props} />,\n NotebookPen: (props: IconProps) => <FallbackIcon {...props} />,\n Rocket: (props: IconProps) => <FallbackIcon {...props} />,\n Server: (props: IconProps) => <FallbackIcon {...props} />,\n}\n`,
|
|
99
|
+
jsx: `import { CheckIcon, ChevronDownIcon, ChevronUpIcon } from "@radix-ui/react-icons"\n\nconst FallbackIcon = (props) => (\n <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round" {...props}>\n <path d="M12 2l3 7h7l-5.5 4 2 7L12 16l-6.5 4 2-7L2 9h7l3-7z" />\n </svg>\n)\n\nexport const Icons = {\n Check: (props) => <CheckIcon {...props} />,\n ChevronDown: (props) => <ChevronDownIcon {...props} />,\n ChevronUp: (props) => <ChevronUpIcon {...props} />,\n Database: (props) => <FallbackIcon {...props} />,\n NotebookPen: (props) => <FallbackIcon {...props} />,\n Rocket: (props) => <FallbackIcon {...props} />,\n Server: (props) => <FallbackIcon {...props} />,\n}\n`,
|
|
100
|
+
},
|
|
101
|
+
feather: {
|
|
102
|
+
dependency: { name: 'react-feather', version: '^2.0.10' },
|
|
103
|
+
tsx: `import * as React from "react"\nimport { Check, ChevronDown, ChevronUp, Database, Edit3, Send, Server } from "react-feather"\n\ntype IconProps = React.SVGProps<SVGSVGElement>\n\nexport const Icons = {\n Check: (props: IconProps) => <Check {...props} />,\n ChevronDown: (props: IconProps) => <ChevronDown {...props} />,\n ChevronUp: (props: IconProps) => <ChevronUp {...props} />,\n Database: (props: IconProps) => <Database {...props} />,\n NotebookPen: (props: IconProps) => <Edit3 {...props} />,\n Rocket: (props: IconProps) => <Send {...props} />,\n Server: (props: IconProps) => <Server {...props} />,\n}\n`,
|
|
104
|
+
jsx: `import { Check, ChevronDown, ChevronUp, Database, Edit3, Send, Server } from "react-feather"\n\nexport const Icons = {\n Check: (props) => <Check {...props} />,\n ChevronDown: (props) => <ChevronDown {...props} />,\n ChevronUp: (props) => <ChevronUp {...props} />,\n Database: (props) => <Database {...props} />,\n NotebookPen: (props) => <Edit3 {...props} />,\n Rocket: (props) => <Send {...props} />,\n Server: (props) => <Server {...props} />,\n}\n`,
|
|
105
|
+
},
|
|
106
|
+
materialSymbols: {
|
|
107
|
+
dependency: { name: 'react-material-symbols', version: '^4.1.0' },
|
|
108
|
+
tsx: `import * as React from "react"\nimport { MaterialSymbol } from "react-material-symbols"\n\ntype IconProps = React.SVGProps<SVGSVGElement>\n\ntype MaterialProps = IconProps & { icon: string }\n\nconst MS = ({ icon, className }: MaterialProps) => (\n <MaterialSymbol icon={icon} className={className} size={24} fill={0} grade={0} opticalSize={24} />\n)\n\nexport const Icons = {\n Check: (props: IconProps) => <MS icon="check" {...props} />,\n ChevronDown: (props: IconProps) => <MS icon="keyboard_arrow_down" {...props} />,\n ChevronUp: (props: IconProps) => <MS icon="keyboard_arrow_up" {...props} />,\n Database: (props: IconProps) => <MS icon="database" {...props} />,\n NotebookPen: (props: IconProps) => <MS icon="edit_note" {...props} />,\n Rocket: (props: IconProps) => <MS icon="rocket_launch" {...props} />,\n Server: (props: IconProps) => <MS icon="dns" {...props} />,\n}\n`,
|
|
109
|
+
jsx: `import { MaterialSymbol } from "react-material-symbols"\n\nconst MS = ({ icon, className }) => (\n <MaterialSymbol icon={icon} className={className} size={24} fill={0} grade={0} opticalSize={24} />\n)\n\nexport const Icons = {\n Check: (props) => <MS icon="check" {...props} />,\n ChevronDown: (props) => <MS icon="keyboard_arrow_down" {...props} />,\n ChevronUp: (props) => <MS icon="keyboard_arrow_up" {...props} />,\n Database: (props) => <MS icon="database" {...props} />,\n NotebookPen: (props) => <MS icon="edit_note" {...props} />,\n Rocket: (props) => <MS icon="rocket_launch" {...props} />,\n Server: (props) => <MS icon="dns" {...props} />,\n}\n`,
|
|
110
|
+
},
|
|
111
|
+
}
|
|
112
|
+
|
|
80
113
|
function updateCssVarInBlock(css, blockSelector, varName, value) {
|
|
81
114
|
const blockRe = new RegExp(`(${blockSelector}\\s*\\{)([\\s\\S]*?)(\\})`, 'm')
|
|
82
115
|
const match = css.match(blockRe)
|
|
@@ -112,6 +145,33 @@ async function applyPrimaryTheme(targetDir, preset) {
|
|
|
112
145
|
}
|
|
113
146
|
}
|
|
114
147
|
|
|
148
|
+
async function applyIconSet(targetDir, language, iconSetKey) {
|
|
149
|
+
const iconSet = ICON_SETS[iconSetKey] ?? ICON_SETS.lucide
|
|
150
|
+
|
|
151
|
+
const pkgJsonPath = path.join(targetDir, 'package.json')
|
|
152
|
+
const pkg = await fse.readJson(pkgJsonPath)
|
|
153
|
+
pkg.dependencies ??= {}
|
|
154
|
+
|
|
155
|
+
for (const key of Object.keys(ICON_SETS)) {
|
|
156
|
+
const depName = ICON_SETS[key]?.dependency?.name
|
|
157
|
+
if (depName && pkg.dependencies[depName]) {
|
|
158
|
+
delete pkg.dependencies[depName]
|
|
159
|
+
}
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
pkg.dependencies[iconSet.dependency.name] = iconSet.dependency.version
|
|
163
|
+
await fse.writeJson(pkgJsonPath, pkg, { spaces: 2 })
|
|
164
|
+
|
|
165
|
+
const iconFile = path.join(
|
|
166
|
+
targetDir,
|
|
167
|
+
'src',
|
|
168
|
+
'components',
|
|
169
|
+
language === 'ts' ? 'icons.tsx' : 'icons.jsx'
|
|
170
|
+
)
|
|
171
|
+
await fs.mkdir(path.dirname(iconFile), { recursive: true })
|
|
172
|
+
await fs.writeFile(iconFile, language === 'ts' ? iconSet.tsx : iconSet.jsx, 'utf8')
|
|
173
|
+
}
|
|
174
|
+
|
|
115
175
|
function toKebabCaseName(input) {
|
|
116
176
|
return input
|
|
117
177
|
.trim()
|
|
@@ -257,6 +317,23 @@ async function main() {
|
|
|
257
317
|
process.exit(0)
|
|
258
318
|
}
|
|
259
319
|
|
|
320
|
+
const iconSet = await select({
|
|
321
|
+
message: 'Icon set',
|
|
322
|
+
options: [
|
|
323
|
+
{ value: 'lucide', label: 'Lucide (default)' },
|
|
324
|
+
{ value: 'heroicons', label: 'HeroIcons' },
|
|
325
|
+
{ value: 'materialSymbols', label: 'Material Symbols' },
|
|
326
|
+
{ value: 'tabler', label: 'Tabler Icons' },
|
|
327
|
+
{ value: 'radix', label: 'Radix Icons' },
|
|
328
|
+
{ value: 'feather', label: 'Feather Icons' },
|
|
329
|
+
],
|
|
330
|
+
initialValue: 'lucide',
|
|
331
|
+
})
|
|
332
|
+
if (isCancel(iconSet)) {
|
|
333
|
+
cancel('Cancelled')
|
|
334
|
+
process.exit(0)
|
|
335
|
+
}
|
|
336
|
+
|
|
260
337
|
const targetDir = path.resolve(process.cwd(), projectName)
|
|
261
338
|
// NOTE: npm downloads the CLI package before prompts run.
|
|
262
339
|
// To avoid downloading both templates, we fetch only the chosen template from npm.
|
|
@@ -309,6 +386,7 @@ async function main() {
|
|
|
309
386
|
}
|
|
310
387
|
|
|
311
388
|
await applyPrimaryTheme(targetDir, THEME_PRESETS[primaryColor] ?? THEME_PRESETS.slate)
|
|
389
|
+
await applyIconSet(targetDir, language, iconSet)
|
|
312
390
|
|
|
313
391
|
// Update package name
|
|
314
392
|
const pkgJsonPath = path.join(targetDir, 'package.json')
|