create-template-html-css 2.0.3 → 2.1.0

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 (74) hide show
  1. package/CHANGELOG.md +305 -0
  2. package/HTML-VS-REACT.md +289 -0
  3. package/QUICKSTART-REACT.md +293 -0
  4. package/REACT-SUPPORT-SUMMARY.md +235 -0
  5. package/README.md +193 -12
  6. package/bin/cli.js +98 -759
  7. package/bin/commands/create.js +272 -0
  8. package/bin/commands/gallery.js +42 -0
  9. package/bin/commands/insert.js +123 -0
  10. package/bin/commands/list.js +73 -0
  11. package/package.json +10 -3
  12. package/src/component-choices.js +7 -0
  13. package/src/components-registry.js +112 -0
  14. package/src/format-utils.js +49 -0
  15. package/src/generator.js +83 -594
  16. package/src/generators/color-schemes.js +78 -0
  17. package/src/generators/color-utils.js +108 -0
  18. package/src/generators/component-filters.js +151 -0
  19. package/src/generators/html-generators.js +180 -0
  20. package/src/generators/validation.js +43 -0
  21. package/src/index.js +2 -1
  22. package/src/inserter.js +55 -233
  23. package/src/inserters/backup-utils.js +20 -0
  24. package/src/inserters/component-loader.js +68 -0
  25. package/src/inserters/html-utils.js +31 -0
  26. package/src/inserters/indentation-utils.js +90 -0
  27. package/src/inserters/validation-utils.js +49 -0
  28. package/src/react-component-choices.js +45 -0
  29. package/src/react-file-operations.js +172 -0
  30. package/src/react-generator.js +208 -0
  31. package/src/react-templates.js +350 -0
  32. package/src/utils/file-utils.js +97 -0
  33. package/src/utils/path-utils.js +32 -0
  34. package/src/utils/string-utils.js +51 -0
  35. package/src/utils/template-loader.js +91 -0
  36. package/templates/_shared/PATTERNS.md +246 -0
  37. package/templates/_shared/README.md +74 -0
  38. package/templates/_shared/base.css +18 -0
  39. package/templates/blackjack/index.html +1 -1
  40. package/templates/blackjack/script.js +9 -9
  41. package/templates/breakout/index.html +1 -1
  42. package/templates/breakout/script.js +6 -6
  43. package/templates/connect-four/index.html +1 -1
  44. package/templates/connect-four/script.js +5 -5
  45. package/templates/dice-game/index.html +1 -1
  46. package/templates/dice-game/script.js +20 -20
  47. package/templates/flappy-bird/index.html +1 -1
  48. package/templates/flappy-bird/script.js +10 -10
  49. package/templates/pong/index.html +1 -1
  50. package/templates/pong/script.js +8 -8
  51. package/templates/skeleton/index.html +4 -4
  52. package/templates/slot-machine/index.html +1 -1
  53. package/templates/slot-machine/script.js +6 -6
  54. package/templates/tetris/index.html +1 -1
  55. package/templates/tetris/script.js +5 -5
  56. package/templates-react/README.md +126 -0
  57. package/templates-react/button/Button.css +88 -0
  58. package/templates-react/button/Button.example.jsx +40 -0
  59. package/templates-react/button/Button.jsx +29 -0
  60. package/templates-react/card/Card.css +86 -0
  61. package/templates-react/card/Card.example.jsx +49 -0
  62. package/templates-react/card/Card.jsx +35 -0
  63. package/templates-react/counter/Counter.css +99 -0
  64. package/templates-react/counter/Counter.example.jsx +45 -0
  65. package/templates-react/counter/Counter.jsx +70 -0
  66. package/templates-react/form/Form.css +128 -0
  67. package/templates-react/form/Form.example.jsx +65 -0
  68. package/templates-react/form/Form.jsx +125 -0
  69. package/templates-react/modal/Modal.css +152 -0
  70. package/templates-react/modal/Modal.example.jsx +90 -0
  71. package/templates-react/modal/Modal.jsx +46 -0
  72. package/templates-react/todo-list/TodoList.css +236 -0
  73. package/templates-react/todo-list/TodoList.example.jsx +15 -0
  74. package/templates-react/todo-list/TodoList.jsx +84 -0
@@ -0,0 +1,272 @@
1
+ /**
2
+ * Create command implementation
3
+ */
4
+ import inquirer from "inquirer";
5
+ import chalk from "chalk";
6
+ import { generateTemplate, COLOR_SCHEMES } from "../../src/generator.js";
7
+ import { generateReactTemplate, addReactComponentOnly } from "../../src/react-generator.js";
8
+ import { COMPONENT_CHOICES } from "../../src/component-choices.js";
9
+ import { REACT_COMPONENT_CHOICES } from "../../src/react-component-choices.js";
10
+
11
+ async function createCommand(options) {
12
+ try {
13
+ if (options.verbose) {
14
+ console.log(chalk.gray("[DEBUG] Options:"), options);
15
+ }
16
+
17
+ // Determine if React mode is requested
18
+ const isReactMode = options.react || false;
19
+
20
+ // If flags are provided, use them directly
21
+ // For component-only mode, name is not required
22
+ if (options.component && (options.name || options.componentOnly)) {
23
+ if (options.verbose) {
24
+ console.log(chalk.gray("[INFO] Using provided options..."));
25
+ }
26
+
27
+ // Validate name for security (skip for component-only mode)
28
+ if (!options.componentOnly) {
29
+ if (
30
+ options.name.includes("/") ||
31
+ options.name.includes("\\") ||
32
+ options.name === ".." ||
33
+ options.name.startsWith("../") ||
34
+ options.name.startsWith("..\\") ||
35
+ options.name.includes("/../") ||
36
+ options.name.includes("\\..\\")
37
+ ) {
38
+ console.error(
39
+ chalk.red("✗ Error:"),
40
+ "Name cannot contain path separators or parent directory references"
41
+ );
42
+ process.exit(1);
43
+ }
44
+
45
+ if (options.name.length > 100) {
46
+ console.error(chalk.red("✗ Error:"), "Name is too long (max 100 characters)");
47
+ process.exit(1);
48
+ }
49
+ }
50
+
51
+ const createOptions = {
52
+ component: options.component,
53
+ name: options.name,
54
+ includeJs: options.includeJs,
55
+ darkMode: options.darkMode,
56
+ colorScheme: options.colorScheme,
57
+ primaryColor: options.primaryColor,
58
+ secondaryColor: options.secondaryColor,
59
+ };
60
+
61
+ if (isReactMode) {
62
+ // Check if component-only mode is enabled (React only)
63
+ if (options.componentOnly) {
64
+ await addReactComponentOnly({
65
+ component: options.component,
66
+ outputDir: process.cwd(),
67
+ colorScheme: options.colorScheme,
68
+ primaryColor: options.primaryColor,
69
+ secondaryColor: options.secondaryColor,
70
+ });
71
+ console.log("\n" + chalk.green("✓ React component added successfully!"));
72
+ } else {
73
+ await generateReactTemplate(createOptions);
74
+ console.log("\n" + chalk.green("✓ React component created successfully!"));
75
+ console.log(chalk.gray(` Location: ./${options.name}/`));
76
+ }
77
+ } else {
78
+ if (options.componentOnly) {
79
+ console.error(
80
+ chalk.red("✗ Error:"),
81
+ "--component-only flag is only supported for React components (use --react)"
82
+ );
83
+ process.exit(1);
84
+ }
85
+ await generateTemplate(createOptions);
86
+ console.log("\n" + chalk.green("✓ Template created successfully!"));
87
+ console.log(chalk.gray(` Location: ./${options.name}/`));
88
+ }
89
+
90
+ console.log(chalk.gray(` Component: ${chalk.bold(options.component)}`));
91
+ return;
92
+ }
93
+
94
+ // Interactive mode
95
+ console.log(chalk.cyan("\n✨ Creating a new template component...\n"));
96
+
97
+ const answers = await inquirer.prompt([
98
+ {
99
+ type: "list",
100
+ name: "framework",
101
+ message: "What framework would you like to use?",
102
+ choices: [
103
+ { name: "HTML + CSS + JavaScript (Vanilla)", value: "html" },
104
+ { name: "React (JSX + CSS)", value: "react" },
105
+ ],
106
+ default: "html",
107
+ },
108
+ {
109
+ type: "list",
110
+ name: "projectType",
111
+ message: "What would you like to create?",
112
+ choices: [
113
+ { name: "Full React project (with Vite, package.json, etc.)", value: "full" },
114
+ { name: "Component only (just JSX + CSS files)", value: "component-only" },
115
+ ],
116
+ default: "full",
117
+ when: (answers) => answers.framework === "react",
118
+ },
119
+ {
120
+ type: "list",
121
+ name: "component",
122
+ message: "What component would you like to create?",
123
+ choices: (answers) =>
124
+ answers.framework === "react" ? REACT_COMPONENT_CHOICES : COMPONENT_CHOICES,
125
+ },
126
+ {
127
+ type: "input",
128
+ name: "name",
129
+ message: (answers) =>
130
+ answers.projectType === "component-only"
131
+ ? "This will create a component folder in the current directory. Continue?"
132
+ : "Enter a name for your component:",
133
+ default: (answers) =>
134
+ answers.projectType === "component-only" ? "yes" : answers.component,
135
+ validate: (input, answers) => {
136
+ if (answers.projectType === "component-only") {
137
+ return true; // Skip validation for component-only
138
+ }
139
+ if (!input || input.trim().length === 0) {
140
+ return "Please enter a valid name";
141
+ }
142
+ if (
143
+ input.includes("/") ||
144
+ input.includes("\\") ||
145
+ input === ".." ||
146
+ input.startsWith("../") ||
147
+ input.startsWith("..\\") ||
148
+ input.includes("/../") ||
149
+ input.includes("\\..\\")
150
+ ) {
151
+ return "Name cannot contain path separators or parent directory references";
152
+ }
153
+ if (input.length > 100) {
154
+ return "Name is too long (max 100 characters)";
155
+ }
156
+ return true;
157
+ },
158
+ when: (answers) => answers.projectType !== "component-only",
159
+ },
160
+ {
161
+ type: "confirm",
162
+ name: "darkMode",
163
+ message: "Add dark mode support (prefers-color-scheme)?",
164
+ default: false,
165
+ },
166
+ {
167
+ type: "list",
168
+ name: "colorOption",
169
+ message: "How would you like to choose colors?",
170
+ choices: [
171
+ { name: "Use a preset color scheme", value: "preset" },
172
+ { name: "Enter custom hex colors", value: "custom" },
173
+ { name: "Skip color customization", value: "skip" },
174
+ ],
175
+ },
176
+ {
177
+ type: "list",
178
+ name: "colorScheme",
179
+ message: "Choose a color scheme:",
180
+ choices: Object.entries(COLOR_SCHEMES).map(([key, scheme]) => ({
181
+ name: `${scheme.name} - ${scheme.description}`,
182
+ value: key,
183
+ })),
184
+ when: (answers) => answers.colorOption === "preset",
185
+ },
186
+ {
187
+ type: "input",
188
+ name: "primaryColor",
189
+ message: "Primary color (hex format, e.g., #667eea) [skip for default]:",
190
+ default: "",
191
+ when: (answers) => answers.colorOption === "custom",
192
+ validate: (input) => {
193
+ if (!input) return true;
194
+ if (!/^#[0-9A-Fa-f]{6}$/.test(input)) {
195
+ return "Please enter a valid hex color (e.g., #667eea)";
196
+ }
197
+ return true;
198
+ },
199
+ },
200
+ {
201
+ type: "input",
202
+ name: "secondaryColor",
203
+ message: "Secondary color (hex format, e.g., #764ba2) [skip for default]:",
204
+ default: "",
205
+ when: (answers) => answers.colorOption === "custom",
206
+ validate: (input) => {
207
+ if (!input) return true;
208
+ if (!/^#[0-9A-Fa-f]{6}$/.test(input)) {
209
+ return "Please enter a valid hex color (e.g., #764ba2)";
210
+ }
211
+ return true;
212
+ },
213
+ },
214
+ ]);
215
+
216
+ answers.includeJs = true;
217
+
218
+ // Generate template based on framework choice
219
+ if (answers.framework === "react") {
220
+ if (answers.projectType === "component-only") {
221
+ // Add component only (no full project)
222
+ await addReactComponentOnly({
223
+ component: answers.component,
224
+ outputDir: process.cwd(),
225
+ colorScheme: answers.colorScheme,
226
+ primaryColor: answers.primaryColor || undefined,
227
+ secondaryColor: answers.secondaryColor || undefined,
228
+ });
229
+
230
+ console.log("\n" + chalk.green("✓ React component added successfully!"));
231
+ console.log(chalk.gray(` Component created in current directory`));
232
+ } else {
233
+ // Create full React project
234
+ await generateReactTemplate(answers);
235
+
236
+ console.log("\n" + chalk.green("✓ React component created successfully!"));
237
+ console.log(chalk.gray(` Location: ./${answers.name}/`));
238
+ console.log(chalk.gray(` Structure:`));
239
+ console.log(chalk.gray(` src/`));
240
+ console.log(chalk.gray(` ├── components/`));
241
+ console.log(chalk.gray(` ├── App.jsx`));
242
+ console.log(chalk.gray(` └── index.jsx`));
243
+ console.log(chalk.gray(` index.html`));
244
+ console.log(chalk.gray(` package.json`));
245
+ console.log("");
246
+ console.log(chalk.cyan("📦 Next steps:"));
247
+ console.log(chalk.gray(` cd ${answers.name}`));
248
+ console.log(chalk.gray(` npm install`));
249
+ console.log(chalk.gray(` npm run dev`));
250
+ }
251
+ } else {
252
+ await generateTemplate(answers);
253
+
254
+ console.log("\n" + chalk.green("✓ Template created successfully!"));
255
+ console.log(chalk.gray(` Location: ./${answers.name}/`));
256
+ console.log(chalk.gray(` Structure:`));
257
+ console.log(chalk.gray(` index.html`));
258
+ console.log(chalk.gray(` css/`));
259
+ console.log(chalk.gray(` └── style.css`));
260
+ if (answers.includeJs) {
261
+ console.log(chalk.gray(` js/`));
262
+ console.log(chalk.gray(` └── script.js`));
263
+ }
264
+ }
265
+ console.log("");
266
+ } catch (error) {
267
+ console.error(chalk.red("✗ Error:"), error.message);
268
+ process.exit(1);
269
+ }
270
+ }
271
+
272
+ export { createCommand };
@@ -0,0 +1,42 @@
1
+ /**
2
+ * Gallery command implementation
3
+ */
4
+ import path from "path";
5
+ import { exec } from "child_process";
6
+ import chalk from "chalk";
7
+ import { getDirname } from "../../src/utils/path-utils.js";
8
+
9
+ const __dirname = getDirname(import.meta.url);
10
+
11
+ function galleryCommand() {
12
+ try {
13
+ const galleryPath = path.join(__dirname, "..", "..", "COMPONENTS-GALLERY.html");
14
+ const fileUrl = `file:///${galleryPath.replace(/\\/g, "/")}`;
15
+
16
+ console.log(chalk.cyan("\n🎨 Opening Component Gallery...\n"));
17
+
18
+ // Cross-platform: open file in default browser
19
+ let command;
20
+ if (process.platform === "win32") {
21
+ command = `start "" "${galleryPath}"`;
22
+ } else if (process.platform === "darwin") {
23
+ command = `open "${galleryPath}"`;
24
+ } else {
25
+ command = `xdg-open "${galleryPath}"`;
26
+ }
27
+
28
+ exec(command, (error) => {
29
+ if (error) {
30
+ console.error(chalk.red("✗ Could not open gallery:"), error.message);
31
+ console.log(chalk.gray(`Try opening manually: ${galleryPath}`));
32
+ } else {
33
+ console.log(chalk.green("✓ Gallery opened in your browser!"));
34
+ console.log(chalk.gray(`Location: ${galleryPath}\n`));
35
+ }
36
+ });
37
+ } catch (error) {
38
+ console.error(chalk.red("✗ Error:"), error.message);
39
+ }
40
+ }
41
+
42
+ export { galleryCommand };
@@ -0,0 +1,123 @@
1
+ /**
2
+ * Insert command implementation
3
+ */
4
+ import inquirer from "inquirer";
5
+ import path from "path";
6
+ import { promises as fs } from "fs";
7
+ import chalk from "chalk";
8
+ import { insertComponent } from "../../src/inserter.js";
9
+ import { COMPONENT_CHOICES } from "../../src/component-choices.js";
10
+
11
+ async function insertCommand(options) {
12
+ try {
13
+ if (options.verbose) {
14
+ console.log(chalk.gray("[DEBUG] Options:"), options);
15
+ }
16
+
17
+ // If flags are provided, use them directly
18
+ if (options.file && options.component) {
19
+ if (options.verbose) {
20
+ console.log(chalk.gray("[INFO] Using provided options..."));
21
+ }
22
+
23
+ const insertOptions = {
24
+ targetFile: options.file,
25
+ component: options.component,
26
+ scriptMode: options.script || "separate",
27
+ styleMode: "separate",
28
+ createBackup: options.backup || false,
29
+ };
30
+
31
+ const result = await insertComponent(insertOptions);
32
+
33
+ console.log("\n" + chalk.green("✓ Component inserted successfully!"));
34
+ console.log(chalk.cyan(" Summary:"));
35
+ console.log(
36
+ chalk.gray(
37
+ ` File: ${path.relative(process.cwd(), result.targetFile)}`,
38
+ ),
39
+ );
40
+ console.log(chalk.gray(` Component: ${chalk.bold(result.component)}`));
41
+ console.log(chalk.gray(` CSS: ${chalk.yellow("external file")}`));
42
+ console.log(chalk.gray(` JS: ${chalk.yellow(result.scriptMode)}`));
43
+ console.log(
44
+ chalk.gray(
45
+ `\n Component IDs: ${result.component}-styles, ${result.component}-script`,
46
+ ),
47
+ );
48
+ console.log("");
49
+ return;
50
+ }
51
+
52
+ // Interactive mode
53
+ console.log(chalk.cyan("\n🚀 Inserting component into HTML file...\n"));
54
+
55
+ const answers = await inquirer.prompt([
56
+ {
57
+ type: "input",
58
+ name: "targetFile",
59
+ message: "Enter the path to your HTML file:",
60
+ default: "index.html",
61
+ validate: async (input) => {
62
+ if (!input || input.trim().length === 0) {
63
+ return "Please enter a file path";
64
+ }
65
+ if (!input.toLowerCase().endsWith(".html")) {
66
+ return "File must be an HTML file (.html)";
67
+ }
68
+
69
+ // Check if file exists
70
+ try {
71
+ await fs.access(path.resolve(process.cwd(), input));
72
+ return true;
73
+ } catch {
74
+ return `File not found: ${input}`;
75
+ }
76
+ },
77
+ },
78
+ {
79
+ type: "list",
80
+ name: "component",
81
+ message: "Which component would you like to insert?",
82
+ choices: COMPONENT_CHOICES,
83
+ },
84
+ {
85
+ type: "list",
86
+ name: "scriptMode",
87
+ message: "How should the JavaScript be added?",
88
+ choices: [
89
+ { name: "Separate file (recommended)", value: "separate" },
90
+ { name: "Inline (inside <script> tag)", value: "inline" },
91
+ { name: "Skip (I'll add it manually)", value: "skip" },
92
+ ],
93
+ default: "separate",
94
+ },
95
+ ]);
96
+
97
+ answers.styleMode = "separate";
98
+
99
+ const result = await insertComponent(answers);
100
+
101
+ console.log("\n" + chalk.green("✓ Component inserted successfully!"));
102
+ console.log(chalk.cyan(" Summary:"));
103
+ console.log(
104
+ chalk.gray(
105
+ ` File: ${path.relative(process.cwd(), result.targetFile)}`,
106
+ ),
107
+ );
108
+ console.log(chalk.gray(` Component: ${chalk.bold(result.component)}`));
109
+ console.log(chalk.gray(` CSS: ${chalk.yellow("external file")}`));
110
+ console.log(chalk.gray(` JS: ${chalk.yellow(result.scriptMode)}`));
111
+ console.log(
112
+ chalk.gray(
113
+ `\n Component IDs: ${result.component}-styles, ${result.component}-script`,
114
+ ),
115
+ );
116
+ console.log("");
117
+ } catch (error) {
118
+ console.error("\n" + chalk.red("✗ Error:"), error.message);
119
+ process.exit(1);
120
+ }
121
+ }
122
+
123
+ export { insertCommand };
@@ -0,0 +1,73 @@
1
+ /**
2
+ * List command implementation
3
+ */
4
+ import chalk from "chalk";
5
+
6
+ function listCommand() {
7
+ console.log("\n" + chalk.blue("📦 Available Components (46 total)\n"));
8
+
9
+ console.log(chalk.yellow("━ Basic Components (9)"));
10
+ console.log(" button Styled button component");
11
+ console.log(" card Card component with image and content");
12
+ console.log(" form Form with input fields and validation");
13
+ console.log(" navigation Responsive navigation bar");
14
+ console.log(" modal Modal dialog component");
15
+ console.log(" footer Footer section");
16
+ console.log(" hero Hero section with CTA button");
17
+ console.log(" slider Image carousel with navigation");
18
+ console.log(" table Data table with search and filtering");
19
+
20
+ console.log("\n" + chalk.green("━ Authentication Forms (2)"));
21
+ console.log(" login Login form with validation");
22
+ console.log(" register Register form with password requirements");
23
+
24
+ console.log("\n" + chalk.cyan("━ Loading Placeholders (1)"));
25
+ console.log(" skeleton Skeleton loading placeholder with shimmer animation");
26
+
27
+ console.log("\n" + chalk.magenta("━ Animation Templates (4)"));
28
+ console.log(" spinner 5 loading spinner variations");
29
+ console.log(" animated-card 6 interactive card animations");
30
+ console.log(" typing-effect Text typing animations");
31
+ console.log(" fade-gallery Image gallery with fade effects");
32
+
33
+ console.log("\n" + chalk.cyan("━ Grid Layouts (3)"));
34
+ console.log(" grid-layout CSS Grid patterns and examples");
35
+ console.log(" masonry-grid Pinterest-style masonry layout");
36
+ console.log(" dashboard-grid Complete admin dashboard (Grid)");
37
+
38
+ console.log("\n" + chalk.blue("━ Flexbox Layouts (3)"));
39
+ console.log(" flex-layout Flexbox patterns and examples");
40
+ console.log(" flex-cards Equal-height card layouts");
41
+ console.log(" flex-dashboard Complete admin dashboard (Flexbox)");
42
+
43
+ console.log("\n" + chalk.red("━ DOM Manipulation Examples (4)"));
44
+ console.log(" todo-list Interactive todo list with add/remove");
45
+ console.log(" counter Click counter with history tracking");
46
+ console.log(" accordion Collapsible accordion component");
47
+ console.log(" tabs Tabbed content switcher");
48
+
49
+ console.log("\n" + chalk.green("━ Interactive Games (16)"));
50
+ console.log(" tic-tac-toe Classic Tic-Tac-Toe game with score tracking");
51
+ console.log(" memory-game Memory card matching game with difficulty levels");
52
+ console.log(" snake-game Classic Snake game with keyboard controls");
53
+ console.log(" guess-number Number guessing game with hints and scoring");
54
+ console.log(" game-2048 2048 puzzle game with touch & keyboard controls");
55
+ console.log(" whack-a-mole Whack-A-Mole arcade game with difficulty levels");
56
+ console.log(" simon-says Simon Says memory pattern game");
57
+ console.log(" rock-paper-scissors Rock Paper Scissors vs AI");
58
+ console.log(" breakout Brick breaker arcade game with levels");
59
+ console.log(" tetris Classic Tetris with piece preview");
60
+ console.log(" flappy-bird Flappy Bird obstacle avoidance game");
61
+ console.log(" connect-four Connect 4 strategy game vs AI");
62
+ console.log(" blackjack Blackjack card game with betting");
63
+ console.log(" slot-machine 3-reel slot machine with jackpots");
64
+ console.log(" dice-game Dice race to 100 strategy game");
65
+ console.log(" pong Classic Pong paddle game vs AI");
66
+
67
+ console.log("\n" + chalk.gray("Usage:"));
68
+ console.log(" create-template create Create a new component");
69
+ console.log(" create-template insert Insert into HTML file");
70
+ console.log("");
71
+ }
72
+
73
+ export { listCommand };
package/package.json CHANGED
@@ -1,7 +1,8 @@
1
1
  {
2
2
  "name": "create-template-html-css",
3
- "version": "2.0.3",
4
- "description": "CLI tool to generate HTML and CSS templates for common UI elements",
3
+ "version": "2.1.0",
4
+ "type": "module",
5
+ "description": "CLI tool to generate HTML/CSS and React templates for common UI elements",
5
6
  "main": "src/index.js",
6
7
  "bin": {
7
8
  "create-template": "bin/cli.js"
@@ -19,10 +20,14 @@
19
20
  "html",
20
21
  "css",
21
22
  "javascript",
23
+ "react",
24
+ "jsx",
25
+ "react-components",
22
26
  "generator",
23
27
  "ui-components",
24
28
  "html-template",
25
29
  "css-template",
30
+ "react-template",
26
31
  "component-generator",
27
32
  "ui-generator",
28
33
  "animations",
@@ -38,7 +43,9 @@
38
43
  "modern-ui",
39
44
  "flexbox",
40
45
  "flex-layout",
41
- "flex-dashboard"
46
+ "flex-dashboard",
47
+ "vite",
48
+ "react-vite"
42
49
  ],
43
50
  "author": "Ben Shabbat <benshabbat@example.com> (https://github.com/benshabbat)",
44
51
  "license": "MIT",
@@ -0,0 +1,7 @@
1
+ /**
2
+ * Component choices for CLI prompts
3
+ * Shared between create and insert commands
4
+ *
5
+ * @deprecated This file is deprecated. Import COMPONENT_CHOICES from components-registry.js instead.
6
+ */
7
+ export { COMPONENT_CHOICES } from "./components-registry.js";
@@ -0,0 +1,112 @@
1
+ /**
2
+ * Central registry for all available components
3
+ * This is the single source of truth for component names
4
+ */
5
+ import chalk from "chalk";
6
+ import inquirer from "inquirer";
7
+
8
+ /**
9
+ * List of all valid component names (alphabetically sorted)
10
+ * Used for validation in both create and insert commands
11
+ */
12
+ export const VALID_COMPONENTS = [
13
+ "accordion",
14
+ "animated-card",
15
+ "blackjack",
16
+ "breakout",
17
+ "button",
18
+ "card",
19
+ "connect-four",
20
+ "counter",
21
+ "dashboard-grid",
22
+ "dice-game",
23
+ "fade-gallery",
24
+ "flappy-bird",
25
+ "flex-cards",
26
+ "flex-dashboard",
27
+ "flex-layout",
28
+ "footer",
29
+ "form",
30
+ "game-2048",
31
+ "grid-layout",
32
+ "guess-number",
33
+ "hero",
34
+ "login",
35
+ "masonry-grid",
36
+ "memory-game",
37
+ "modal",
38
+ "navigation",
39
+ "pong",
40
+ "register",
41
+ "rock-paper-scissors",
42
+ "simon-says",
43
+ "skeleton",
44
+ "slider",
45
+ "slot-machine",
46
+ "snake-game",
47
+ "spinner",
48
+ "table",
49
+ "tabs",
50
+ "tetris",
51
+ "tic-tac-toe",
52
+ "todo-list",
53
+ "typing-effect",
54
+ "whack-a-mole",
55
+ ];
56
+
57
+ /**
58
+ * Component choices for CLI prompts with categories and descriptions
59
+ * Used in interactive mode for create and insert commands
60
+ */
61
+ export const COMPONENT_CHOICES = [
62
+ new inquirer.Separator(chalk.gray("─ Basic Components")),
63
+ { name: "Button", value: "button" },
64
+ { name: "Card", value: "card" },
65
+ { name: "Form", value: "form" },
66
+ { name: "Navigation", value: "navigation" },
67
+ { name: "Modal", value: "modal" },
68
+ { name: "Footer", value: "footer" },
69
+ { name: "Hero Section", value: "hero" },
70
+ { name: "Slider", value: "slider" },
71
+ { name: "Table", value: "table" },
72
+ new inquirer.Separator(chalk.gray("─ Authentication Forms")),
73
+ { name: "Login Form", value: "login" },
74
+ { name: "Register Form", value: "register" },
75
+ new inquirer.Separator(chalk.gray("─ Loading Placeholders")),
76
+ { name: "Skeleton (Loading Placeholders)", value: "skeleton" },
77
+ new inquirer.Separator(chalk.gray("─ Animation Templates")),
78
+ { name: "Spinner (Loading Animations)", value: "spinner" },
79
+ { name: "Animated Card (Interactive Cards)", value: "animated-card" },
80
+ { name: "Typing Effect (Text Animations)", value: "typing-effect" },
81
+ { name: "Fade Gallery (Image Gallery)", value: "fade-gallery" },
82
+ new inquirer.Separator(chalk.gray("─ Grid Layouts (CSS Grid)")),
83
+ { name: "Grid Layout", value: "grid-layout" },
84
+ { name: "Masonry Grid (Pinterest-style)", value: "masonry-grid" },
85
+ { name: "Dashboard Grid (Admin Panel)", value: "dashboard-grid" },
86
+ new inquirer.Separator(chalk.gray("─ Flexbox Layouts")),
87
+ { name: "Flex Layout (Flexbox Patterns)", value: "flex-layout" },
88
+ { name: "Flex Cards (Equal-height cards)", value: "flex-cards" },
89
+ { name: "Flex Dashboard (Flexbox Admin)", value: "flex-dashboard" },
90
+ new inquirer.Separator(chalk.gray("─ DOM Manipulation Examples")),
91
+ { name: "Todo List (Add/Remove Items)", value: "todo-list" },
92
+ { name: "Counter (Click Handlers)", value: "counter" },
93
+ { name: "Accordion (Toggle Content)", value: "accordion" },
94
+ { name: "Tabs (Switch Sections)", value: "tabs" },
95
+ new inquirer.Separator(chalk.gray("─ Interactive Games")),
96
+ { name: "🎮 Tic-Tac-Toe", value: "tic-tac-toe" },
97
+ { name: "🎮 Memory Game", value: "memory-game" },
98
+ { name: "🎮 Snake Game", value: "snake-game" },
99
+ { name: "🎮 Guess Number", value: "guess-number" },
100
+ { name: "🎮 2048", value: "game-2048" },
101
+ { name: "🎮 Whack-a-Mole", value: "whack-a-mole" },
102
+ { name: "🎮 Simon Says", value: "simon-says" },
103
+ { name: "🎮 Rock-Paper-Scissors", value: "rock-paper-scissors" },
104
+ { name: "🎮 Breakout", value: "breakout" },
105
+ { name: "🎮 Tetris", value: "tetris" },
106
+ { name: "🎮 Flappy Bird", value: "flappy-bird" },
107
+ { name: "🎮 Connect Four", value: "connect-four" },
108
+ { name: "🎮 Blackjack", value: "blackjack" },
109
+ { name: "🎮 Slot Machine", value: "slot-machine" },
110
+ { name: "🎮 Dice Game", value: "dice-game" },
111
+ { name: "🎮 Pong", value: "pong" },
112
+ ];