myoperator-ui 0.0.1

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 ADDED
@@ -0,0 +1,71 @@
1
+ # myOperator UI
2
+
3
+ CLI for adding myOperator UI components to your React project.
4
+
5
+ ## Installation
6
+
7
+ ```bash
8
+ npx myoperator-ui init
9
+ ```
10
+
11
+ ## Usage
12
+
13
+ ### Initialize your project
14
+
15
+ ```bash
16
+ npx myoperator-ui init
17
+ ```
18
+
19
+ This will:
20
+ - Create a `components.json` configuration file
21
+ - Set up the utils file with the `cn` helper
22
+ - Create the components directory
23
+
24
+ ### Add components
25
+
26
+ ```bash
27
+ # Add a specific component
28
+ npx myoperator-ui add button
29
+
30
+ # Add multiple components
31
+ npx myoperator-ui add button input card
32
+
33
+ # Interactive selection
34
+ npx myoperator-ui add
35
+ ```
36
+
37
+ ### Options
38
+
39
+ ```bash
40
+ # Skip confirmation
41
+ npx myoperator-ui add button -y
42
+
43
+ # Overwrite existing files
44
+ npx myoperator-ui add button --overwrite
45
+
46
+ # Custom path
47
+ npx myoperator-ui add button -p src/ui
48
+ ```
49
+
50
+ ## Available Components
51
+
52
+ - `button` - A customizable button with variants, sizes, icons, and loading state
53
+
54
+ ## Requirements
55
+
56
+ - React 18+
57
+ - Tailwind CSS
58
+ - TypeScript (recommended)
59
+
60
+ ## Dependencies
61
+
62
+ Components use these packages (installed automatically):
63
+ - `@radix-ui/react-slot`
64
+ - `class-variance-authority`
65
+ - `clsx`
66
+ - `tailwind-merge`
67
+ - `lucide-react`
68
+
69
+ ## License
70
+
71
+ MIT
@@ -0,0 +1 @@
1
+ #!/usr/bin/env node
package/dist/index.js ADDED
@@ -0,0 +1,333 @@
1
+ #!/usr/bin/env node
2
+
3
+ // src/index.ts
4
+ import { Command } from "commander";
5
+
6
+ // src/commands/add.ts
7
+ import chalk from "chalk";
8
+ import fs from "fs-extra";
9
+ import path from "path";
10
+ import prompts from "prompts";
11
+ import ora from "ora";
12
+
13
+ // src/utils/registry.ts
14
+ async function getRegistry() {
15
+ return {
16
+ button: {
17
+ name: "button",
18
+ description: "A customizable button component with variants, sizes, and icons",
19
+ dependencies: [
20
+ "@radix-ui/react-slot",
21
+ "class-variance-authority",
22
+ "clsx",
23
+ "tailwind-merge",
24
+ "lucide-react"
25
+ ],
26
+ files: [
27
+ {
28
+ name: "button.tsx",
29
+ content: `import * as React from "react"
30
+ import { Slot } from "@radix-ui/react-slot"
31
+ import { cva, type VariantProps } from "class-variance-authority"
32
+ import { Loader2 } from "lucide-react"
33
+
34
+ import { cn } from "@/lib/utils"
35
+
36
+ const buttonVariants = cva(
37
+ "inline-flex items-center justify-center gap-2 whitespace-nowrap rounded text-sm font-medium transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:pointer-events-none disabled:opacity-50 [&_svg]:pointer-events-none [&_svg]:size-4 [&_svg]:shrink-0",
38
+ {
39
+ variants: {
40
+ variant: {
41
+ default: "bg-[#343E55] text-white hover:bg-[#343E55]/90",
42
+ destructive:
43
+ "bg-destructive text-destructive-foreground hover:bg-destructive/90",
44
+ outline:
45
+ "border border-[#343E55] bg-transparent text-[#343E55] hover:bg-[#343E55] hover:text-white",
46
+ secondary:
47
+ "bg-[#343E55]/20 text-[#343E55] hover:bg-[#343E55]/30",
48
+ ghost: "hover:bg-[#343E55]/10 hover:text-[#343E55]",
49
+ link: "text-[#343E55] underline-offset-4 hover:underline",
50
+ },
51
+ size: {
52
+ default: "py-2.5 px-4",
53
+ sm: "py-2 px-3 text-xs",
54
+ lg: "py-3 px-6",
55
+ icon: "p-2.5",
56
+ },
57
+ },
58
+ defaultVariants: {
59
+ variant: "default",
60
+ size: "default",
61
+ },
62
+ }
63
+ )
64
+
65
+ export interface ButtonProps
66
+ extends React.ButtonHTMLAttributes<HTMLButtonElement>,
67
+ VariantProps<typeof buttonVariants> {
68
+ asChild?: boolean
69
+ leftIcon?: React.ReactNode
70
+ rightIcon?: React.ReactNode
71
+ loading?: boolean
72
+ loadingText?: string
73
+ }
74
+
75
+ const Button = React.forwardRef<HTMLButtonElement, ButtonProps>(
76
+ ({
77
+ className,
78
+ variant,
79
+ size,
80
+ asChild = false,
81
+ leftIcon,
82
+ rightIcon,
83
+ loading = false,
84
+ loadingText,
85
+ children,
86
+ disabled,
87
+ ...props
88
+ }, ref) => {
89
+ const Comp = asChild ? Slot : "button"
90
+
91
+ return (
92
+ <Comp
93
+ className={cn(buttonVariants({ variant, size, className }))}
94
+ ref={ref}
95
+ disabled={disabled || loading}
96
+ {...props}
97
+ >
98
+ {loading ? (
99
+ <>
100
+ <Loader2 className="animate-spin" />
101
+ {loadingText || children}
102
+ </>
103
+ ) : (
104
+ <>
105
+ {leftIcon}
106
+ {children}
107
+ {rightIcon}
108
+ </>
109
+ )}
110
+ </Comp>
111
+ )
112
+ }
113
+ )
114
+ Button.displayName = "Button"
115
+
116
+ export { Button, buttonVariants }
117
+ `
118
+ }
119
+ ]
120
+ }
121
+ };
122
+ }
123
+
124
+ // src/commands/add.ts
125
+ async function add(components, options) {
126
+ const cwd = process.cwd();
127
+ const configPath = path.join(cwd, "components.json");
128
+ if (!await fs.pathExists(configPath)) {
129
+ console.log(chalk.red("\n Error: Project not initialized."));
130
+ console.log(chalk.yellow(" Run `npx myoperator-ui init` first.\n"));
131
+ process.exit(1);
132
+ }
133
+ const registry = await getRegistry();
134
+ const availableComponents = Object.keys(registry);
135
+ if (!components || components.length === 0) {
136
+ const { selectedComponents } = await prompts({
137
+ type: "multiselect",
138
+ name: "selectedComponents",
139
+ message: "Which components would you like to add?",
140
+ choices: availableComponents.map((name) => ({
141
+ title: name,
142
+ value: name,
143
+ description: registry[name].description
144
+ })),
145
+ min: 1
146
+ });
147
+ if (!selectedComponents || selectedComponents.length === 0) {
148
+ console.log(chalk.yellow("\n No components selected.\n"));
149
+ process.exit(0);
150
+ }
151
+ components = selectedComponents;
152
+ }
153
+ const invalidComponents = components.filter((c) => !availableComponents.includes(c));
154
+ if (invalidComponents.length > 0) {
155
+ console.log(chalk.red(`
156
+ Error: Unknown components: ${invalidComponents.join(", ")}`));
157
+ console.log(chalk.yellow(` Available: ${availableComponents.join(", ")}
158
+ `));
159
+ process.exit(1);
160
+ }
161
+ const config = await fs.readJson(configPath);
162
+ const componentsDir = path.join(cwd, options.path);
163
+ if (!options.yes) {
164
+ const { confirm } = await prompts({
165
+ type: "confirm",
166
+ name: "confirm",
167
+ message: `Add ${components.length} component(s) to ${options.path}?`,
168
+ initial: true
169
+ });
170
+ if (!confirm) {
171
+ console.log(chalk.yellow("\n Installation cancelled.\n"));
172
+ process.exit(0);
173
+ }
174
+ }
175
+ console.log("");
176
+ const spinner = ora("Installing components...").start();
177
+ try {
178
+ const installed = [];
179
+ const dependencies = /* @__PURE__ */ new Set();
180
+ for (const componentName of components) {
181
+ const component = registry[componentName];
182
+ for (const file of component.files) {
183
+ const filePath = path.join(componentsDir, file.name);
184
+ if (await fs.pathExists(filePath)) {
185
+ if (!options.overwrite) {
186
+ spinner.warn(`${file.name} already exists. Use --overwrite to replace.`);
187
+ continue;
188
+ }
189
+ }
190
+ await fs.ensureDir(path.dirname(filePath));
191
+ await fs.writeFile(filePath, file.content);
192
+ installed.push(file.name);
193
+ }
194
+ if (component.dependencies) {
195
+ component.dependencies.forEach((dep) => dependencies.add(dep));
196
+ }
197
+ }
198
+ spinner.succeed("Components installed successfully!");
199
+ if (installed.length > 0) {
200
+ console.log(chalk.green("\n Installed files:"));
201
+ installed.forEach((file) => {
202
+ console.log(chalk.green(` \u2713 ${options.path}/${file}`));
203
+ });
204
+ }
205
+ if (dependencies.size > 0) {
206
+ console.log(chalk.yellow("\n Required dependencies:"));
207
+ console.log(chalk.cyan(` npm install ${Array.from(dependencies).join(" ")}`));
208
+ }
209
+ console.log("");
210
+ } catch (error) {
211
+ spinner.fail("Failed to install components");
212
+ console.error(error);
213
+ process.exit(1);
214
+ }
215
+ }
216
+
217
+ // src/commands/init.ts
218
+ import chalk2 from "chalk";
219
+ import fs2 from "fs-extra";
220
+ import path2 from "path";
221
+ import prompts2 from "prompts";
222
+ import ora2 from "ora";
223
+ var DEFAULT_CONFIG = {
224
+ $schema: "https://myoperator.com/schema.json",
225
+ style: "default",
226
+ tailwind: {
227
+ config: "tailwind.config.js",
228
+ css: "src/index.css",
229
+ baseColor: "slate",
230
+ cssVariables: true
231
+ },
232
+ aliases: {
233
+ components: "@/components",
234
+ utils: "@/lib/utils",
235
+ ui: "@/components/ui"
236
+ }
237
+ };
238
+ async function init() {
239
+ console.log(chalk2.bold("\n Welcome to myOperator UI!\n"));
240
+ const cwd = process.cwd();
241
+ const configPath = path2.join(cwd, "components.json");
242
+ if (await fs2.pathExists(configPath)) {
243
+ const { overwrite } = await prompts2({
244
+ type: "confirm",
245
+ name: "overwrite",
246
+ message: "components.json already exists. Overwrite?",
247
+ initial: false
248
+ });
249
+ if (!overwrite) {
250
+ console.log(chalk2.yellow(" Initialization cancelled.\n"));
251
+ process.exit(0);
252
+ }
253
+ }
254
+ const response = await prompts2([
255
+ {
256
+ type: "text",
257
+ name: "componentsPath",
258
+ message: "Where would you like to install components?",
259
+ initial: "src/components/ui"
260
+ },
261
+ {
262
+ type: "text",
263
+ name: "utilsPath",
264
+ message: "Where is your utils file?",
265
+ initial: "src/lib/utils.ts"
266
+ },
267
+ {
268
+ type: "text",
269
+ name: "tailwindConfig",
270
+ message: "Where is your tailwind.config.js?",
271
+ initial: "tailwind.config.js"
272
+ },
273
+ {
274
+ type: "text",
275
+ name: "globalCss",
276
+ message: "Where is your global CSS file?",
277
+ initial: "src/index.css"
278
+ }
279
+ ]);
280
+ const spinner = ora2("Initializing project...").start();
281
+ try {
282
+ const config = {
283
+ ...DEFAULT_CONFIG,
284
+ tailwind: {
285
+ ...DEFAULT_CONFIG.tailwind,
286
+ config: response.tailwindConfig,
287
+ css: response.globalCss
288
+ },
289
+ aliases: {
290
+ ...DEFAULT_CONFIG.aliases,
291
+ ui: `@/${response.componentsPath.replace("src/", "")}`
292
+ }
293
+ };
294
+ await fs2.writeJson(configPath, config, { spaces: 2 });
295
+ const utilsPath = path2.join(cwd, response.utilsPath);
296
+ if (!await fs2.pathExists(utilsPath)) {
297
+ await fs2.ensureDir(path2.dirname(utilsPath));
298
+ await fs2.writeFile(
299
+ utilsPath,
300
+ `import { type ClassValue, clsx } from "clsx"
301
+ import { twMerge } from "tailwind-merge"
302
+
303
+ export function cn(...inputs: ClassValue[]) {
304
+ return twMerge(clsx(inputs))
305
+ }
306
+ `
307
+ );
308
+ }
309
+ const componentsPath = path2.join(cwd, response.componentsPath);
310
+ await fs2.ensureDir(componentsPath);
311
+ spinner.succeed("Project initialized successfully!");
312
+ console.log(chalk2.green("\n \u2713 Created components.json"));
313
+ console.log(chalk2.green(` \u2713 Created ${response.utilsPath}`));
314
+ console.log(chalk2.green(` \u2713 Created ${response.componentsPath}
315
+ `));
316
+ 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:");
320
+ console.log(chalk2.cyan(" npx myoperator-ui add button\n"));
321
+ } catch (error) {
322
+ spinner.fail("Failed to initialize project");
323
+ console.error(error);
324
+ process.exit(1);
325
+ }
326
+ }
327
+
328
+ // src/index.ts
329
+ var program = new Command();
330
+ program.name("myoperator-ui").description("CLI for adding myOperator UI components to your project").version("0.0.1");
331
+ program.command("init").description("Initialize your project with myOperator UI").action(init);
332
+ program.command("add").description("Add a component to your project").argument("[components...]", "Components to add").option("-y, --yes", "Skip confirmation prompt", false).option("-o, --overwrite", "Overwrite existing files", false).option("-p, --path <path>", "Path to add components to", "src/components/ui").action(add);
333
+ program.parse();
package/package.json ADDED
@@ -0,0 +1,45 @@
1
+ {
2
+ "name": "myoperator-ui",
3
+ "version": "0.0.1",
4
+ "description": "CLI for adding myOperator UI components to your project",
5
+ "type": "module",
6
+ "exports": "./dist/index.js",
7
+ "bin": {
8
+ "myoperator-ui": "./dist/index.js"
9
+ },
10
+ "files": [
11
+ "dist"
12
+ ],
13
+ "scripts": {
14
+ "build": "tsup src/index.ts --format esm --dts",
15
+ "dev": "tsup src/index.ts --format esm --watch",
16
+ "typecheck": "tsc --noEmit"
17
+ },
18
+ "dependencies": {
19
+ "chalk": "^5.3.0",
20
+ "commander": "^12.1.0",
21
+ "fs-extra": "^11.2.0",
22
+ "ora": "^8.0.1",
23
+ "prompts": "^2.4.2"
24
+ },
25
+ "devDependencies": {
26
+ "@types/fs-extra": "^11.0.4",
27
+ "@types/node": "^20.11.0",
28
+ "@types/prompts": "^2.4.9",
29
+ "tsup": "^8.0.1",
30
+ "typescript": "^5.3.3"
31
+ },
32
+ "keywords": [
33
+ "myoperator",
34
+ "ui",
35
+ "components",
36
+ "cli",
37
+ "react"
38
+ ],
39
+ "author": "",
40
+ "license": "MIT",
41
+ "repository": {
42
+ "type": "git",
43
+ "url": "https://github.com/Ankish8/storybook-npm.git"
44
+ }
45
+ }