scaff-ui 0.1.2 → 0.1.4

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 CHANGED
@@ -1,44 +1,57 @@
1
1
  # scaff-ui
2
2
 
3
- Scaffold the UI. Make it yours.
3
+ Scaffold the UI. Make it your design.
4
4
 
5
- `scaff-ui` is a minimalistic CLI-based frontend component generator for developers who want to speed up development without dropping pre-made, highly opinionated UI into their projects. It generates responsive, customizable implementations of common UI patterns across multiple frontend frameworks, giving developers a practical starting point they can adapt to their project's requirements
5
+ Scaff UI is a CLI for generating minimalistic, customizable Tailwind CSS components for frontend projects.
6
+
7
+ Generate ready-made UI components directly into your project, then modify the source code and make each component fit your own design.
8
+
9
+ <!-- [Website](https://scaff-ui-site.jimroep.workers.dev) · [GitHub](https://github.com/carleoj/scaff-ui) -->
6
10
 
7
11
  ## Features
8
12
 
9
- * Generate ready-made frontend components
10
- * Supports HTML and React
11
- * Multiple variants for each component
12
- * Uses Tailwind CSS utility classes
13
- * Generates directly into `src/components`
14
- * No project setup or configuration required
15
- * No unnecessary abstractions
13
+ - Generate ready-made frontend components
14
+ - Supports React and HTML
15
+ - Multiple variants for each component
16
+ - Built with Tailwind CSS
17
+ - Generates directly into `src/components`
18
+ - No unnecessary abstractions
16
19
 
17
20
  ## Requirements
18
21
 
19
- * Node.js 20 or later
20
- * An existing frontend project
21
- * Tailwind CSS already installed and configured
22
+ - Node.js 20+
23
+ - An existing frontend project
24
+ - Tailwind CSS installed and configured
22
25
 
23
26
  `scaff-ui` does not install or configure Tailwind CSS, React, Vite, or other build tools.
24
27
 
25
28
  ## Installation
26
29
 
27
- Install `scaff-ui` in your existing frontend project:
30
+ ### Local installation
31
+
32
+ Install `scaff-ui` in your existing project:
28
33
 
29
34
  ```bash
30
35
  npm install scaff-ui
31
36
  ```
32
37
 
38
+ ### Global installation
39
+
40
+ Install scaff-ui globally to use the scf command directly:
41
+
42
+ ```bash
43
+ npm install -g scaff-ui
44
+ ```
45
+
33
46
  ## Usage
34
47
 
35
- Run the interactive component generator from your project's root directory:
48
+ Run the interactive generator:
36
49
 
37
50
  ```bash
38
51
  npx scf add
39
52
  ```
40
53
 
41
- You will be prompted to select a framework, component, and variant:
54
+ Select a framework, component, and variant:
42
55
 
43
56
  ```text
44
57
  ? Select Framework
@@ -49,6 +62,8 @@ You will be prompted to select a framework, component, and variant:
49
62
  ❯ Header
50
63
  Hero
51
64
  Footer
65
+ Text Area
66
+ Newsletter
52
67
 
53
68
  ? Select Variant
54
69
  ❯ Logo + Navigation Links
@@ -56,15 +71,17 @@ You will be prompted to select a framework, component, and variant:
56
71
  Navigation Links Only
57
72
  ```
58
73
 
59
- You can also specify a component directly:
74
+ You can also generate a specific component directly:
60
75
 
61
76
  ```bash
62
77
  npx scf add header
63
78
  npx scf add hero
64
79
  npx scf add footer
80
+ npx scf add text-area
81
+ npx scf add newsletter
65
82
  ```
66
83
 
67
- To view available components:
84
+ View available components:
68
85
 
69
86
  ```bash
70
87
  npx scf list
@@ -72,7 +89,7 @@ npx scf list
72
89
 
73
90
  ## Generated Files
74
91
 
75
- Components are generated inside your project's `src/components` directory.
92
+ Components are generated into your project's `src/components` directory.
76
93
 
77
94
  ### React
78
95
 
@@ -100,46 +117,59 @@ src/
100
117
 
101
118
  Available variants:
102
119
 
103
- * Logo + Navigation Links
104
- * Logo + Navigation Links + CTA Button
105
- * Navigation Links Only
120
+ - Logo + Navigation Links
121
+ - Logo + Navigation Links + CTA Button
122
+ - Navigation Links Only
106
123
 
107
124
  ### Hero
108
125
 
109
126
  Available variants:
110
127
 
111
- * Heading + Description + Button
112
- * Heading + Description + Button + Image
113
- * Heading + Description Only
128
+ - Heading + Description + Button
129
+ - Heading + Description + Button + Image
130
+ - Heading + Description Only
114
131
 
115
132
  ### Footer
116
133
 
117
134
  Available variants:
118
135
 
119
- * Copyright Only
120
- * Copyright + Navigation Links
121
- * Copyright + Social Links
136
+ - Copyright Only
137
+ - Copyright + Navigation Links
138
+ - Copyright + Social Links
139
+
140
+ ### Text Area
141
+
142
+ Available variants:
143
+
144
+ - Actions Inside
145
+ - Actions Outside
146
+
147
+ ### Newsletter
148
+
149
+ Available variants:
150
+
151
+ - Basic Newsletter
122
152
 
123
153
  ## Tailwind CSS
124
154
 
125
155
  Generated components use Tailwind CSS utility classes.
126
156
 
127
- `scaff-ui` assumes Tailwind CSS is already installed and configured in your project.
157
+ Scaff UI assumes Tailwind CSS is already installed and configured in your project.
128
158
 
129
159
  It does not:
130
160
 
131
- * Install Tailwind CSS
132
- * Configure Tailwind CSS
133
- * Install React
134
- * Configure Vite
135
- * Create a project
136
- * Manage build tools
161
+ - Install Tailwind CSS
162
+ - Configure Tailwind CSS
163
+ - Install React
164
+ - Configure Vite
165
+ - Create a project
166
+ - Manage build tools
137
167
 
138
- This keeps `scaff-ui` focused on generating frontend source code.
168
+ Scaff UI focuses on generating frontend source code that you can modify freely.
139
169
 
140
170
  ## Development
141
171
 
142
- Clone the repository and install dependencies:
172
+ Clone the repository:
143
173
 
144
174
  ```bash
145
175
  git clone https://github.com/carleoj/scaff-ui.git
@@ -153,13 +183,13 @@ Link the package locally:
153
183
  npm link
154
184
  ```
155
185
 
156
- You can then use the `scf` command while developing:
186
+ Run the CLI:
157
187
 
158
188
  ```bash
159
189
  scf add
160
190
  ```
161
191
 
162
- Run tests with:
192
+ Run tests:
163
193
 
164
194
  ```bash
165
195
  npm test
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "scaff-ui",
3
- "version": "0.1.2",
4
- "description": "A lightweight CLI for generating simple, ready-made frontend components.",
3
+ "version": "0.1.4",
4
+ "description": "A minimalistic CLI for generating customizable Tailwind CSS components directly into your project.",
5
5
  "type": "module",
6
6
  "bin": {
7
7
  "scf": "./bin/scf.js"
@@ -27,7 +27,7 @@
27
27
  "bugs": {
28
28
  "url": "https://github.com/carleoj/scaff-ui/issues"
29
29
  },
30
- "homepage": "https://github.com/carleoj/scaff-ui#readme",
30
+ "homepage": "https://scaff-ui-site.jimroep.workers.dev",
31
31
  "engines": {
32
32
  "node": ">=20"
33
33
  },
@@ -9,9 +9,11 @@ const FRAMEWORKS = [
9
9
  ];
10
10
 
11
11
  const COMPONENTS = [
12
- { name: "Header", value: "header" },
13
- { name: "Hero", value: "hero" },
14
- { name: "Footer", value: "footer" },
12
+ { name: "Header", value: "header", frameworks: ["html", "react"] },
13
+ { name: "Hero", value: "hero", frameworks: ["html", "react"] },
14
+ { name: "Footer", value: "footer", frameworks: ["html", "react"] },
15
+ { name: "Text Area", value: "text-area", frameworks: ["html", "react"] },
16
+ { name: "Newsletter", value: "newsletter", frameworks: ["html", "react"] },
15
17
  ];
16
18
 
17
19
  const VARIANTS = {
@@ -44,6 +46,15 @@ const VARIANTS = {
44
46
  },
45
47
  { name: "Copyright + Social Links", value: "copyright-social" },
46
48
  ],
49
+
50
+ "text-area": [
51
+ { name: "Actions Inside", value: "actions-inside" },
52
+ { name: "Actions Outside", value: "actions-outside" },
53
+ ],
54
+
55
+ newsletter: [
56
+ { name: "Basic Newsletter", value: "basic-newsletter" },
57
+ ],
47
58
  };
48
59
 
49
60
  const requestedComponent = process.argv[3];
@@ -67,16 +78,26 @@ async function addComponent() {
67
78
  process.exit(1);
68
79
  }
69
80
 
81
+ const requestedDefinition = COMPONENTS.find(
82
+ (component) => component.value === requestedComponent,
83
+ );
84
+
70
85
  const framework = await select({
71
86
  message: "Select Framework",
72
- choices: FRAMEWORKS,
87
+ choices: requestedDefinition
88
+ ? FRAMEWORKS.filter((frameworkOption) =>
89
+ requestedDefinition.frameworks.includes(frameworkOption.value),
90
+ )
91
+ : FRAMEWORKS,
73
92
  });
74
93
 
75
94
  const type =
76
95
  requestedComponent ??
77
96
  (await select({
78
97
  message: "Select Component",
79
- choices: COMPONENTS,
98
+ choices: COMPONENTS.filter((component) =>
99
+ component.frameworks.includes(framework),
100
+ ),
80
101
  }));
81
102
 
82
103
  if (!VARIANTS[type]) {
@@ -14,6 +14,13 @@ const components = {
14
14
  "Copyright + Navigation Links",
15
15
  "Copyright + Social Links",
16
16
  ],
17
+ "Text Area": [
18
+ "Actions Inside",
19
+ "Actions Outside",
20
+ ],
21
+ Newsletter: [
22
+ "Basic Newsletter",
23
+ ],
17
24
  };
18
25
 
19
26
  console.log("Available components:");
@@ -10,11 +10,15 @@ const FILE_NAMES = {
10
10
  header: "header.html",
11
11
  hero: "hero.html",
12
12
  footer: "footer.html",
13
+ "text-area": "text-area.html",
14
+ newsletter: "newsletter.html",
13
15
  },
14
16
  react: {
15
17
  header: "Header.jsx",
16
18
  hero: "Hero.jsx",
17
19
  footer: "Footer.jsx",
20
+ "text-area": "TextArea.jsx",
21
+ newsletter: "Newsletter.jsx",
18
22
  },
19
23
  };
20
24
 
@@ -0,0 +1,30 @@
1
+ <section class="mx-auto w-full max-w-xl rounded-2xl border border-gray-200 bg-zinc-50 p-8 text-center sm:p-10">
2
+ <h2 class="text-3xl font-bold tracking-tight text-gray-950">
3
+ Stay in the loop
4
+ </h2>
5
+
6
+ <p class="mx-auto mt-4 max-w-lg text-lg leading-7 text-gray-700">
7
+ Subscribe to our newsletter for updates, new releases, and useful resources.
8
+ </p>
9
+
10
+ <form class="mt-8">
11
+ <label for="email" class="sr-only">Email address</label>
12
+
13
+ <input
14
+ id="email"
15
+ type="email"
16
+ placeholder="Enter your email"
17
+ class="w-full rounded-lg border border-gray-300 bg-white px-5 py-4 text-base text-gray-950 outline-none transition focus:border-gray-950 focus:ring-1 focus:ring-gray-950"
18
+ required
19
+ />
20
+
21
+ <button
22
+ type="submit"
23
+ class="mt-3 w-full rounded-lg bg-zinc-600 px-5 py-4 text-base font-semibold text-white transition hover:bg-zinc-700"
24
+ >
25
+ Subscribe
26
+ </button>
27
+ </form>
28
+
29
+ <p class="mt-6 text-sm text-gray-600">No spam. Unsubscribe anytime.</p>
30
+ </section>
@@ -0,0 +1,29 @@
1
+ <div class="mx-auto max-w-sm">
2
+ <label for="Notes">
3
+ <span class="text-sm font-medium text-gray-700">Notes</span>
4
+
5
+ <div class="relative mt-0.5 overflow-hidden rounded border border-gray-300 shadow-sm focus-within:ring focus-within:ring-blue-600">
6
+ <textarea
7
+ id="Notes"
8
+ class="w-full resize-none border-none outline-none focus:ring-0 sm:text-sm"
9
+ rows="4"
10
+ ></textarea>
11
+
12
+ <div class="flex items-center justify-end gap-2 p-1.5">
13
+ <button
14
+ type="button"
15
+ class="rounded border border-transparent px-3 py-1.5 text-sm font-medium text-gray-700 transition-colors hover:text-gray-900"
16
+ >
17
+ Clear
18
+ </button>
19
+
20
+ <button
21
+ type="button"
22
+ class="rounded border border-gray-300 px-3 py-1.5 text-sm font-medium text-gray-900 shadow-sm transition-colors hover:bg-gray-100"
23
+ >
24
+ Save
25
+ </button>
26
+ </div>
27
+ </div>
28
+ </label>
29
+ </div>
@@ -0,0 +1,29 @@
1
+ <div class="mx-auto max-w-sm">
2
+ <label for="Notes">
3
+ <span class="text-sm font-medium text-gray-700">Notes</span>
4
+
5
+ <div class="relative mt-0.5 overflow-hidden rounded border border-gray-300 shadow-sm focus-within:ring focus-within:ring-blue-600">
6
+ <textarea
7
+ id="Notes"
8
+ class="w-full resize-none border-none outline-none focus:ring-0 sm:text-sm"
9
+ rows="4"
10
+ ></textarea>
11
+ </div>
12
+ </label>
13
+
14
+ <div class="mt-2 flex items-center justify-end gap-2">
15
+ <button
16
+ type="button"
17
+ class="rounded border border-transparent px-3 py-1.5 text-sm font-medium text-gray-700 transition-colors hover:text-gray-900"
18
+ >
19
+ Clear
20
+ </button>
21
+
22
+ <button
23
+ type="button"
24
+ class="rounded border border-gray-300 px-3 py-1.5 text-sm font-medium text-gray-900 shadow-sm transition-colors hover:bg-gray-100"
25
+ >
26
+ Save
27
+ </button>
28
+ </div>
29
+ </div>
@@ -2,14 +2,27 @@ export default function Header() {
2
2
  return (
3
3
  <header className="border-b border-gray-200">
4
4
  <nav className="mx-auto flex max-w-7xl items-center justify-between px-6 py-4">
5
- <a href="/" className="text-xl font-semibold">Logo</a>
5
+ <a href="/" className="text-xl font-semibold">
6
+ Logo
7
+ </a>
6
8
 
7
9
  <div className="flex items-center gap-6">
8
- <a href="#" className="text-sm text-gray-700 hover:text-black">Home</a>
9
- <a href="#" className="text-sm text-gray-700 hover:text-black">About</a>
10
- <a href="#" className="text-sm text-gray-700 hover:text-black">Projects</a>
11
- <a href="#" className="text-sm text-gray-700 hover:text-black">Contact</a>
12
- <a href="#" className="rounded-lg bg-black px-4 py-2 text-sm font-medium text-white">
10
+ <a href="#" className="text-sm text-gray-700 hover:text-black">
11
+ Home
12
+ </a>
13
+ <a href="#" className="text-sm text-gray-700 hover:text-black">
14
+ About
15
+ </a>
16
+ <a href="#" className="text-sm text-gray-700 hover:text-black">
17
+ Projects
18
+ </a>
19
+ <a href="#" className="text-sm text-gray-700 hover:text-black">
20
+ Contact
21
+ </a>
22
+ <a
23
+ href="#"
24
+ className="rounded-lg bg-black px-4 py-2 text-sm font-medium text-white"
25
+ >
13
26
  Get Started
14
27
  </a>
15
28
  </div>
@@ -0,0 +1,39 @@
1
+ export default function Newsletter() {
2
+ return (
3
+ <section className="mx-auto w-full max-w-xl rounded-2xl border border-gray-200 bg-zinc-50 p-8 text-center sm:p-10">
4
+ <h2 className="text-3xl font-bold tracking-tight text-gray-950">
5
+ Stay in the loop
6
+ </h2>
7
+
8
+ <p className="mx-auto mt-4 max-w-lg text-lg leading-7 text-gray-700">
9
+ Subscribe to our newsletter for updates, new releases, and useful
10
+ resources.
11
+ </p>
12
+
13
+ <form className="mt-8">
14
+ <label htmlFor="email" className="sr-only">
15
+ Email address
16
+ </label>
17
+
18
+ <input
19
+ id="email"
20
+ type="email"
21
+ placeholder="Enter your email"
22
+ className="w-full rounded-lg border border-gray-300 bg-white px-5 py-4 text-base text-gray-950 outline-none transition focus:border-gray-950 focus:ring-1 focus:ring-gray-950"
23
+ required
24
+ />
25
+
26
+ <button
27
+ type="submit"
28
+ className="mt-3 w-full rounded-lg bg-zinc-600 px-5 py-4 text-base font-semibold text-white transition hover:bg-zinc-700"
29
+ >
30
+ Subscribe
31
+ </button>
32
+ </form>
33
+
34
+ <p className="mt-6 text-sm text-gray-600">
35
+ No spam. Unsubscribe anytime.
36
+ </p>
37
+ </section>
38
+ );
39
+ }
@@ -0,0 +1,35 @@
1
+ import React from "react";
2
+
3
+ export default function TextArea() {
4
+ return (
5
+ <div className="mx-auto max-w-sm">
6
+ <label htmlFor="Notes">
7
+ <span className="text-sm font-medium text-gray-700">Notes</span>
8
+
9
+ <div className="relative mt-0.5 overflow-hidden rounded border border-gray-300 shadow-sm focus-within:ring focus-within:ring-blue-600">
10
+ <textarea
11
+ id="Notes"
12
+ className="w-full resize-none border-none outline-none focus:ring-0 sm:text-sm"
13
+ rows="4"
14
+ />
15
+
16
+ <div className="flex items-center justify-end gap-2 p-1.5">
17
+ <button
18
+ type="button"
19
+ className="rounded border border-transparent px-3 py-1.5 text-sm font-medium text-gray-700 transition-colors hover:text-gray-900"
20
+ >
21
+ Clear
22
+ </button>
23
+
24
+ <button
25
+ type="button"
26
+ className="rounded border border-gray-300 px-3 py-1.5 text-sm font-medium text-gray-900 shadow-sm transition-colors hover:bg-gray-100"
27
+ >
28
+ Save
29
+ </button>
30
+ </div>
31
+ </div>
32
+ </label>
33
+ </div>
34
+ );
35
+ }
@@ -0,0 +1,35 @@
1
+ import React from "react";
2
+
3
+ export default function TextArea() {
4
+ return (
5
+ <div className="mx-auto max-w-sm">
6
+ <label htmlFor="Notes">
7
+ <span className="text-sm font-medium text-gray-700">Notes</span>
8
+
9
+ <div className="relative mt-0.5 overflow-hidden rounded border border-gray-300 shadow-sm focus-within:ring focus-within:ring-blue-600">
10
+ <textarea
11
+ id="Notes"
12
+ className="w-full resize-none border-none outline-none focus:ring-0 sm:text-sm"
13
+ rows="4"
14
+ />
15
+ </div>
16
+ </label>
17
+
18
+ <div className="mt-2 flex items-center justify-end gap-2">
19
+ <button
20
+ type="button"
21
+ className="rounded border border-transparent px-3 py-1.5 text-sm font-medium text-gray-700 transition-colors hover:text-gray-900"
22
+ >
23
+ Clear
24
+ </button>
25
+
26
+ <button
27
+ type="button"
28
+ className="rounded border border-gray-300 px-3 py-1.5 text-sm font-medium text-gray-900 shadow-sm transition-colors hover:bg-gray-100"
29
+ >
30
+ Save
31
+ </button>
32
+ </div>
33
+ </div>
34
+ );
35
+ }