myoperator-ui 0.0.1 → 0.0.2

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 (3) hide show
  1. package/README.md +79 -1
  2. package/dist/index.js +221 -5
  3. package/package.json +1 -1
package/README.md CHANGED
@@ -20,6 +20,9 @@ This will:
20
20
  - Create a `components.json` configuration file
21
21
  - Set up the utils file with the `cn` helper
22
22
  - Create the components directory
23
+ - Create/update your global CSS with theme CSS variables
24
+ - Create/update `tailwind.config.js` with theme color mappings
25
+ - Create/update `postcss.config.js` with the correct Tailwind CSS PostCSS plugin
23
26
 
24
27
  ### Add components
25
28
 
@@ -59,12 +62,87 @@ npx myoperator-ui add button -p src/ui
59
62
 
60
63
  ## Dependencies
61
64
 
62
- Components use these packages (installed automatically):
65
+ Components use these packages:
63
66
  - `@radix-ui/react-slot`
64
67
  - `class-variance-authority`
65
68
  - `clsx`
66
69
  - `tailwind-merge`
67
70
  - `lucide-react`
71
+ - `tailwindcss-animate`
72
+
73
+ ## CSS Variables & Theming
74
+
75
+ Components use CSS variables for theming. The `init` command automatically sets up these variables in your global CSS file.
76
+
77
+ ### Theme Colors
78
+
79
+ The following semantic colors are available:
80
+
81
+ | Variable | Description |
82
+ |----------|-------------|
83
+ | `--background` | Page background |
84
+ | `--foreground` | Default text color |
85
+ | `--primary` | Primary brand color |
86
+ | `--secondary` | Secondary color |
87
+ | `--destructive` | Error/danger color |
88
+ | `--muted` | Muted backgrounds |
89
+ | `--accent` | Accent color |
90
+ | `--border` | Border color |
91
+ | `--ring` | Focus ring color |
92
+
93
+ ### Dark Mode
94
+
95
+ Dark mode is supported via the `.dark` class on the root element. The CSS variables automatically switch to dark theme values.
96
+
97
+ ### Customizing Theme
98
+
99
+ To customize colors, edit the CSS variables in your global CSS file:
100
+
101
+ ```css
102
+ :root {
103
+ --primary: 222.2 47.4% 11.2%;
104
+ --destructive: 0 84.2% 60.2%;
105
+ /* ... other variables */
106
+ }
107
+ ```
108
+
109
+ Colors use HSL format without the `hsl()` wrapper (e.g., `222.2 47.4% 11.2%`).
110
+
111
+ ## PostCSS Configuration
112
+
113
+ This CLI automatically sets up the correct PostCSS configuration for Tailwind CSS. The new Tailwind CSS versions require the `@tailwindcss/postcss` plugin instead of the old `tailwindcss` plugin.
114
+
115
+ ### Correct PostCSS Config
116
+
117
+ ```javascript
118
+ // postcss.config.js
119
+ module.exports = {
120
+ plugins: {
121
+ '@tailwindcss/postcss': {},
122
+ },
123
+ }
124
+ ```
125
+
126
+ ### Common Error
127
+
128
+ If you see this error:
129
+
130
+ ```
131
+ [plugin:vite:css] [postcss] It looks like you're trying to use `tailwindcss` directly as a PostCSS plugin.
132
+ The PostCSS plugin has moved to a separate package, so to continue using Tailwind CSS with PostCSS
133
+ you'll need to install `@tailwindcss/postcss` and update your PostCSS configuration.
134
+ ```
135
+
136
+ **Fix it by:**
137
+
138
+ 1. Installing the new plugin:
139
+ ```bash
140
+ npm install -D @tailwindcss/postcss
141
+ ```
142
+
143
+ 2. Updating your `postcss.config.js` to use the new plugin (see above)
144
+
145
+ Running `npx myoperator-ui init` will automatically create the correct configuration for you.
68
146
 
69
147
  ## License
70
148
 
package/dist/index.js CHANGED
@@ -220,6 +220,141 @@ import fs2 from "fs-extra";
220
220
  import path2 from "path";
221
221
  import prompts2 from "prompts";
222
222
  import ora2 from "ora";
223
+ var CSS_VARIABLES = `@tailwind base;
224
+ @tailwind components;
225
+ @tailwind utilities;
226
+
227
+ @layer base {
228
+ :root {
229
+ --background: 0 0% 100%;
230
+ --foreground: 222.2 84% 4.9%;
231
+ --card: 0 0% 100%;
232
+ --card-foreground: 222.2 84% 4.9%;
233
+ --popover: 0 0% 100%;
234
+ --popover-foreground: 222.2 84% 4.9%;
235
+ --primary: 222.2 47.4% 11.2%;
236
+ --primary-foreground: 210 40% 98%;
237
+ --secondary: 210 40% 96.1%;
238
+ --secondary-foreground: 222.2 47.4% 11.2%;
239
+ --muted: 210 40% 96.1%;
240
+ --muted-foreground: 215.4 16.3% 46.9%;
241
+ --accent: 210 40% 96.1%;
242
+ --accent-foreground: 222.2 47.4% 11.2%;
243
+ --destructive: 0 84.2% 60.2%;
244
+ --destructive-foreground: 210 40% 98%;
245
+ --border: 214.3 31.8% 91.4%;
246
+ --input: 214.3 31.8% 91.4%;
247
+ --ring: 222.2 84% 4.9%;
248
+ --radius: 0.5rem;
249
+ }
250
+
251
+ .dark {
252
+ --background: 222.2 84% 4.9%;
253
+ --foreground: 210 40% 98%;
254
+ --card: 222.2 84% 4.9%;
255
+ --card-foreground: 210 40% 98%;
256
+ --popover: 222.2 84% 4.9%;
257
+ --popover-foreground: 210 40% 98%;
258
+ --primary: 210 40% 98%;
259
+ --primary-foreground: 222.2 47.4% 11.2%;
260
+ --secondary: 217.2 32.6% 17.5%;
261
+ --secondary-foreground: 210 40% 98%;
262
+ --muted: 217.2 32.6% 17.5%;
263
+ --muted-foreground: 215 20.2% 65.1%;
264
+ --accent: 217.2 32.6% 17.5%;
265
+ --accent-foreground: 210 40% 98%;
266
+ --destructive: 0 62.8% 30.6%;
267
+ --destructive-foreground: 210 40% 98%;
268
+ --border: 217.2 32.6% 17.5%;
269
+ --input: 217.2 32.6% 17.5%;
270
+ --ring: 212.7 26.8% 83.9%;
271
+ }
272
+ }
273
+
274
+ @layer base {
275
+ * {
276
+ @apply border-border;
277
+ }
278
+ body {
279
+ @apply bg-background text-foreground;
280
+ }
281
+ }
282
+ `;
283
+ var TAILWIND_CONFIG = `/** @type {import('tailwindcss').Config} */
284
+ export default {
285
+ darkMode: ["class"],
286
+ content: [
287
+ "./index.html",
288
+ "./src/**/*.{js,ts,jsx,tsx}",
289
+ ],
290
+ theme: {
291
+ container: {
292
+ center: true,
293
+ padding: "2rem",
294
+ screens: {
295
+ "2xl": "1400px",
296
+ },
297
+ },
298
+ extend: {
299
+ colors: {
300
+ border: "hsl(var(--border))",
301
+ input: "hsl(var(--input))",
302
+ ring: "hsl(var(--ring))",
303
+ background: "hsl(var(--background))",
304
+ foreground: "hsl(var(--foreground))",
305
+ primary: {
306
+ DEFAULT: "hsl(var(--primary))",
307
+ foreground: "hsl(var(--primary-foreground))",
308
+ },
309
+ secondary: {
310
+ DEFAULT: "hsl(var(--secondary))",
311
+ foreground: "hsl(var(--secondary-foreground))",
312
+ },
313
+ destructive: {
314
+ DEFAULT: "hsl(var(--destructive))",
315
+ foreground: "hsl(var(--destructive-foreground))",
316
+ },
317
+ muted: {
318
+ DEFAULT: "hsl(var(--muted))",
319
+ foreground: "hsl(var(--muted-foreground))",
320
+ },
321
+ accent: {
322
+ DEFAULT: "hsl(var(--accent))",
323
+ foreground: "hsl(var(--accent-foreground))",
324
+ },
325
+ popover: {
326
+ DEFAULT: "hsl(var(--popover))",
327
+ foreground: "hsl(var(--popover-foreground))",
328
+ },
329
+ card: {
330
+ DEFAULT: "hsl(var(--card))",
331
+ foreground: "hsl(var(--card-foreground))",
332
+ },
333
+ },
334
+ borderRadius: {
335
+ lg: "var(--radius)",
336
+ md: "calc(var(--radius) - 2px)",
337
+ sm: "calc(var(--radius) - 4px)",
338
+ },
339
+ keyframes: {
340
+ "accordion-down": {
341
+ from: { height: "0" },
342
+ to: { height: "var(--radix-accordion-content-height)" },
343
+ },
344
+ "accordion-up": {
345
+ from: { height: "var(--radix-accordion-content-height)" },
346
+ to: { height: "0" },
347
+ },
348
+ },
349
+ animation: {
350
+ "accordion-down": "accordion-down 0.2s ease-out",
351
+ "accordion-up": "accordion-up 0.2s ease-out",
352
+ },
353
+ },
354
+ },
355
+ plugins: [require("tailwindcss-animate")],
356
+ }
357
+ `;
223
358
  var DEFAULT_CONFIG = {
224
359
  $schema: "https://myoperator.com/schema.json",
225
360
  style: "default",
@@ -308,15 +443,96 @@ export function cn(...inputs: ClassValue[]) {
308
443
  }
309
444
  const componentsPath = path2.join(cwd, response.componentsPath);
310
445
  await fs2.ensureDir(componentsPath);
446
+ const globalCssPath = path2.join(cwd, response.globalCss);
447
+ let cssUpdated = false;
448
+ if (!await fs2.pathExists(globalCssPath)) {
449
+ await fs2.ensureDir(path2.dirname(globalCssPath));
450
+ await fs2.writeFile(globalCssPath, CSS_VARIABLES);
451
+ cssUpdated = true;
452
+ } else {
453
+ const existingCss = await fs2.readFile(globalCssPath, "utf-8");
454
+ if (!existingCss.includes("--background:") && !existingCss.includes("--destructive:")) {
455
+ spinner.stop();
456
+ const { updateCss } = await prompts2({
457
+ type: "confirm",
458
+ name: "updateCss",
459
+ message: `${response.globalCss} exists. Add myOperator UI CSS variables?`,
460
+ initial: true
461
+ });
462
+ spinner.start("Initializing project...");
463
+ if (updateCss) {
464
+ await fs2.writeFile(globalCssPath, CSS_VARIABLES);
465
+ cssUpdated = true;
466
+ }
467
+ }
468
+ }
469
+ const tailwindConfigPath = path2.join(cwd, response.tailwindConfig);
470
+ let tailwindUpdated = false;
471
+ if (!await fs2.pathExists(tailwindConfigPath)) {
472
+ await fs2.writeFile(tailwindConfigPath, TAILWIND_CONFIG);
473
+ tailwindUpdated = true;
474
+ } else {
475
+ const existingConfig = await fs2.readFile(tailwindConfigPath, "utf-8");
476
+ if (!existingConfig.includes("hsl(var(--destructive))") && !existingConfig.includes("hsl(var(--ring))")) {
477
+ spinner.stop();
478
+ const { updateTailwind } = await prompts2({
479
+ type: "confirm",
480
+ name: "updateTailwind",
481
+ message: `${response.tailwindConfig} exists. Update with myOperator UI theme colors?`,
482
+ initial: true
483
+ });
484
+ spinner.start("Initializing project...");
485
+ if (updateTailwind) {
486
+ await fs2.writeFile(tailwindConfigPath, TAILWIND_CONFIG);
487
+ tailwindUpdated = true;
488
+ }
489
+ }
490
+ }
491
+ const postcssConfigPath = path2.join(cwd, "postcss.config.js");
492
+ const postcssConfigContent = `module.exports = {
493
+ plugins: {
494
+ '@tailwindcss/postcss': {},
495
+ },
496
+ }
497
+ `;
498
+ let postcssCreated = false;
499
+ if (!await fs2.pathExists(postcssConfigPath)) {
500
+ await fs2.writeFile(postcssConfigPath, postcssConfigContent);
501
+ postcssCreated = true;
502
+ } else {
503
+ spinner.stop();
504
+ const { updatePostcss } = await prompts2({
505
+ type: "confirm",
506
+ name: "updatePostcss",
507
+ message: "postcss.config.js exists. Update to use @tailwindcss/postcss?",
508
+ initial: true
509
+ });
510
+ spinner.start("Initializing project...");
511
+ if (updatePostcss) {
512
+ await fs2.writeFile(postcssConfigPath, postcssConfigContent);
513
+ postcssCreated = true;
514
+ }
515
+ }
311
516
  spinner.succeed("Project initialized successfully!");
312
517
  console.log(chalk2.green("\n \u2713 Created components.json"));
313
518
  console.log(chalk2.green(` \u2713 Created ${response.utilsPath}`));
314
- console.log(chalk2.green(` \u2713 Created ${response.componentsPath}
315
- `));
519
+ console.log(chalk2.green(` \u2713 Created ${response.componentsPath}`));
520
+ if (cssUpdated) {
521
+ console.log(chalk2.green(` \u2713 Updated ${response.globalCss} with CSS variables`));
522
+ }
523
+ if (tailwindUpdated) {
524
+ console.log(chalk2.green(` \u2713 Updated ${response.tailwindConfig} with theme colors`));
525
+ }
526
+ if (postcssCreated) {
527
+ console.log(chalk2.green(" \u2713 Created postcss.config.js"));
528
+ }
529
+ console.log("");
316
530
  console.log(chalk2.bold(" Next steps:\n"));
317
- console.log(" 1. Install dependencies:");
318
- console.log(chalk2.cyan(" npm install clsx tailwind-merge class-variance-authority\n"));
319
- console.log(" 2. Add your first component:");
531
+ console.log(" 1. Install core dependencies:");
532
+ console.log(chalk2.cyan(" npm install clsx tailwind-merge class-variance-authority @radix-ui/react-slot lucide-react tailwindcss-animate\n"));
533
+ console.log(" 2. Install PostCSS plugin (if not already installed):");
534
+ console.log(chalk2.cyan(" npm install -D @tailwindcss/postcss\n"));
535
+ console.log(" 3. Add your first component:");
320
536
  console.log(chalk2.cyan(" npx myoperator-ui add button\n"));
321
537
  } catch (error) {
322
538
  spinner.fail("Failed to initialize project");
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "myoperator-ui",
3
- "version": "0.0.1",
3
+ "version": "0.0.2",
4
4
  "description": "CLI for adding myOperator UI components to your project",
5
5
  "type": "module",
6
6
  "exports": "./dist/index.js",