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.
- package/README.md +79 -1
- package/dist/index.js +221 -5
- 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
|
|
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.
|
|
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");
|