Skip to content

Commit 18ceefc

Browse files
committed
πŸ§‘β€πŸ’» Add createComponent script
1 parent 03f4fa7 commit 18ceefc

File tree

2 files changed

+149
-1
lines changed

2 files changed

+149
-1
lines changed

β€Žpackage.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,8 @@
66
"dev": "astro dev",
77
"build": "astro check && astro build",
88
"build:package": "node scripts/build.js",
9-
"test": "echo \"Error: no test specified\""
9+
"test": "echo \"Error: no test specified\"",
10+
"create-component": "node scripts/createComponent.js"
1011
},
1112
"dependencies": {
1213
"@astrojs/check": "0.7.0",

β€Žscripts/createComponent.js

Lines changed: 147 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,147 @@
1+
import fs from 'fs'
2+
3+
const componentFlag = process.argv[2]
4+
5+
if (!componentFlag) {
6+
console.log("⚠️ Component name is missing. Use npm run create-component MyComponent.")
7+
process.exit()
8+
}
9+
10+
const capitalize = string => string.charAt(0).toUpperCase() + string.slice(1)
11+
12+
const component = capitalize(componentFlag)
13+
const lowerCaseComponent = component.toLowerCase()
14+
const rootPath = 'src/components'
15+
16+
if (fs.existsSync(`${rootPath}/${component}`)) {
17+
console.log(`⚠️ Component ${component} already exists. Please choose another name.`)
18+
process.exit()
19+
}
20+
21+
const format = template => template.trim().replace(new RegExp('^[ \\t]{8}', 'gm'), '')
22+
23+
const templates = {
24+
astro: `
25+
---
26+
import type { ${component}Props } from './${lowerCaseComponent}'
27+
import './${lowerCaseComponent}.scss'
28+
29+
interface Props extends ${component}Props {}
30+
31+
const {
32+
className
33+
} = Astro.props
34+
35+
const classes = [
36+
'w-${lowerCaseComponent}',
37+
className
38+
]
39+
---
40+
`,
41+
svelte: `
42+
<script lang="ts">
43+
import type { ${component}Props } from './${lowerCaseComponent}'
44+
import './${lowerCaseComponent}.scss'
45+
46+
export let className: ${component}Props['className'] = ''
47+
48+
const classes = [
49+
'w-${lowerCaseComponent}',
50+
className
51+
].filter(Boolean).join(' ')
52+
</script>
53+
`,
54+
react: `
55+
import React from 'react'
56+
import type { ${component}Props } from './${lowerCaseComponent}'
57+
58+
import './${lowerCaseComponent}.scss'
59+
60+
const ${component} = ({
61+
className
62+
}: ${component}Props) => {
63+
const classes = [
64+
'w-${lowerCaseComponent}',
65+
className
66+
].filter(Boolean).join(' ')
67+
68+
return <div>${component}</div>
69+
}
70+
71+
export default ${component}
72+
`,
73+
types: `
74+
export type ${component}Props = {
75+
className?: string
76+
}
77+
`,
78+
styles: `
79+
@import '../../scss/config.scss';
80+
81+
.w-${lowerCaseComponent} {
82+
83+
}
84+
`,
85+
page: `
86+
---
87+
import Layout from '@static/Layout.astro'
88+
import ComponentWrapper from '@static/ComponentWrapper.astro'
89+
90+
import Astro${component} from '@components/${component}/${component}.astro'
91+
import Svelte${component} from '@components/${component}/${component}.svelte'
92+
import React${component} from '@components/${component}/${component}.tsx'
93+
94+
const sections = [
95+
{
96+
title: 'Astro ${lowerCaseComponent}s',
97+
component: Astro${component}
98+
},
99+
{
100+
title: 'Svelte ${lowerCaseComponent}s',
101+
component: Svelte${component}
102+
},
103+
{
104+
title: 'React ${lowerCaseComponent}s',
105+
component: React${component}
106+
}
107+
]
108+
---
109+
110+
<Layout>
111+
<h1>${component}</h1>
112+
<div class="grid md-2 lg-3">
113+
<ComponentWrapper type="Astro">
114+
<Astro${component} />
115+
</ComponentWrapper>
116+
117+
<ComponentWrapper type="Svelte">
118+
<Svelte${component} />
119+
</ComponentWrapper>
120+
121+
<ComponentWrapper type="React">
122+
<React${component} />
123+
</ComponentWrapper>
124+
</div>
125+
126+
{sections.map(section => (
127+
<h1>{section.title}</h1>
128+
<div class="grid md-2 lg-3">
129+
<ComponentWrapper title="Default">
130+
<section.component />
131+
</ComponentWrapper>
132+
</div>
133+
))}
134+
</Layout>
135+
`
136+
}
137+
138+
fs.mkdirSync(`${rootPath}/${component}`)
139+
140+
fs.writeFileSync(`${rootPath}/${component}/${component}.astro`, format(templates.astro))
141+
fs.writeFileSync(`${rootPath}/${component}/${component}.svelte`, format(templates.svelte))
142+
fs.writeFileSync(`${rootPath}/${component}/${component}.tsx`, format(templates.react))
143+
fs.writeFileSync(`${rootPath}/${component}/${lowerCaseComponent}.ts`, format(templates.types))
144+
fs.writeFileSync(`${rootPath}/${component}/${lowerCaseComponent}.scss`, format(templates.styles))
145+
fs.writeFileSync(`src/pages/${lowerCaseComponent}.astro`, format(templates.page))
146+
147+
console.log(`βœ… Component ${component} created at ${rootPath}/${component}.`)

0 commit comments

Comments
Β (0)