myoperator-ui 0.0.209 → 0.0.210-beta.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 (3) hide show
  1. package/README.md +394 -394
  2. package/dist/index.js +319 -0
  3. package/package.json +67 -67
package/README.md CHANGED
@@ -1,394 +1,394 @@
1
- # myOperator UI
2
-
3
- CLI for adding myOperator UI components to your React project. Works with both standalone projects and projects that use Bootstrap or other CSS frameworks.
4
-
5
- ## Quick Start
6
-
7
- ```bash
8
- # Initialize your project
9
- npx myoperator-ui init
10
-
11
- # Add a component
12
- npx myoperator-ui add button
13
- ```
14
-
15
- ## Commands
16
-
17
- ### `init` - Initialize Project
18
-
19
- ```bash
20
- npx myoperator-ui init
21
- ```
22
-
23
- This will:
24
- - Create a `components.json` configuration file
25
- - Set up the utils file with the `cn` helper
26
- - Create the components directory
27
- - Create/update your global CSS (`App.scss`) with Tailwind imports
28
- - Create/update `postcss.config.js` with the correct Tailwind CSS PostCSS plugin
29
- - Configure Tailwind with `tw-` prefix by default
30
-
31
- ### `add` - Add Components
32
-
33
- ```bash
34
- # Add a specific component
35
- npx myoperator-ui add button
36
-
37
- # Add multiple components
38
- npx myoperator-ui add button badge table
39
-
40
- # Add all available components at once
41
- npx myoperator-ui add --all
42
-
43
- # Interactive selection (shows all available components)
44
- npx myoperator-ui add
45
- ```
46
-
47
- **Options:**
48
-
49
- | Option | Short | Description |
50
- |--------|-------|-------------|
51
- | `--all` | `-a` | Add all available components |
52
- | `--yes` | `-y` | Skip confirmation prompt |
53
- | `--overwrite` | `-o` | Overwrite existing files |
54
- | `--path <path>` | `-p` | Custom path (default: `src/components/ui`) |
55
-
56
- **Examples:**
57
-
58
- ```bash
59
- # Add all components at once
60
- npx myoperator-ui add --all
61
-
62
- # Add all components, skip confirmation
63
- npx myoperator-ui add --all -y
64
-
65
- # Skip confirmation
66
- npx myoperator-ui add button -y
67
-
68
- # Overwrite existing component
69
- npx myoperator-ui add button --overwrite
70
-
71
- # Add to custom directory
72
- npx myoperator-ui add button -p src/ui
73
- ```
74
-
75
- ### `update` - Update Components
76
-
77
- Safely update installed components to the latest version with diff preview.
78
-
79
- **Important:** Always use `@latest` to ensure you get the newest component code:
80
-
81
- ```bash
82
- # Update a specific component (recommended)
83
- npx myoperator-ui@latest update button
84
-
85
- # Update multiple components
86
- npx myoperator-ui@latest update button badge
87
-
88
- # Interactive selection (shows installed components)
89
- npx myoperator-ui@latest update
90
-
91
- # Update all installed components
92
- npx myoperator-ui@latest update --all
93
- ```
94
-
95
- **Options:**
96
-
97
- | Option | Short | Description |
98
- |--------|-------|-------------|
99
- | `--yes` | `-y` | Skip confirmation prompt |
100
- | `--all` | `-a` | Update all installed components |
101
- | `--dry-run` | `-d` | Preview changes without modifying files |
102
- | `--backup` | `-b` | Create backup files before updating |
103
- | `--path <path>` | `-p` | Custom path (default: `src/components/ui`) |
104
-
105
- **Examples:**
106
-
107
- ```bash
108
- # Preview what would change (safe - no modifications)
109
- npx myoperator-ui@latest update button --dry-run
110
-
111
- # Preview all component updates
112
- npx myoperator-ui@latest update --all --dry-run
113
-
114
- # Update all with backups
115
- npx myoperator-ui@latest update --all --backup
116
-
117
- # Force update without confirmation
118
- npx myoperator-ui@latest update button -y
119
- ```
120
-
121
- > **Note:** If you see "No changes" but expect updates, make sure you're using `@latest` to get the newest package version. NPX may cache older versions.
122
-
123
- **Update Safeguards:**
124
- - Shows diff of changes before applying
125
- - `--dry-run` lets you preview without making changes
126
- - `--backup` creates timestamped backups (e.g., `button.tsx.backup.1700000000`)
127
- - Only updates components that are already installed
128
- - Skips components with no changes
129
-
130
- ### Other Commands
131
-
132
- ```bash
133
- # Check CLI version
134
- npx myoperator-ui --version
135
-
136
- # Get help
137
- npx myoperator-ui --help
138
- npx myoperator-ui add --help
139
- npx myoperator-ui update --help
140
- ```
141
-
142
- ## Available Components
143
-
144
- | Component | Description |
145
- |-----------|-------------|
146
- | `accordion` | Expandable/collapsible accordion component with single or multiple mode support |
147
- | `badge` | Status badge with active, failed, disabled, outline, secondary, destructive variants and asChild support |
148
- | `button` | Customizable button with variants, sizes (including icon-lg), icons, and loading state |
149
- | `checkbox` | Tri-state checkbox built on Radix UI with label support (checked, unchecked, indeterminate) |
150
- | `dropdown-menu` | Dropdown menu for displaying actions and options |
151
- | `input` | Basic input component |
152
- | `multi-select` | Multi-select dropdown with search, tags, and keyboard navigation |
153
- | `select` | Single select dropdown component |
154
- | `select-field` | Select field with label, helper text, and validation states |
155
- | `switch` | Switch component built on Radix UI for boolean inputs with on/off states |
156
- | `table` | Composable table with size variants, loading/empty states, sticky columns |
157
- | `tag` | Tag component for event labels with optional bold label prefix |
158
- | `text-field` | Text input with label, icons, prefix/suffix, validation states, and character count |
159
-
160
- ## Configuration
161
-
162
- After running `init`, a `components.json` file is created:
163
-
164
- ```json
165
- {
166
- "$schema": "https://myoperator.com/schema.json",
167
- "style": "default",
168
- "tailwind": {
169
- "config": "tailwind.config.js",
170
- "css": "src/App.scss",
171
- "baseColor": "slate",
172
- "cssVariables": true,
173
- "prefix": "tw-"
174
- },
175
- "aliases": {
176
- "components": "@/components",
177
- "utils": "@/lib/utils",
178
- "ui": "@/components/ui"
179
- }
180
- }
181
- ```
182
-
183
- ## Tailwind CSS Configuration
184
-
185
- The CLI generates a `tailwind.config.js` with:
186
-
187
- ```javascript
188
- /** @type {import('tailwindcss').Config} */
189
- export default {
190
- darkMode: ["class"],
191
- prefix: "tw-",
192
- content: ["./src/components/ui/**/*.{js,ts,jsx,tsx}"],
193
- theme: {
194
- // ... theme configuration
195
- },
196
- plugins: [require("tailwindcss-animate")],
197
- }
198
- ```
199
-
200
- **Key Features:**
201
- - `prefix: "tw-"` - Avoids conflicts with other CSS frameworks
202
- - Scoped content path - Only scans UI components directory
203
-
204
- ## Bootstrap Compatibility
205
-
206
- myOperator UI automatically detects if your project uses Bootstrap and configures Tailwind CSS to avoid conflicts.
207
-
208
- ### How it works
209
-
210
- When Bootstrap is detected, the CLI uses selective Tailwind imports - importing only theme and utilities, skipping Preflight (Tailwind's CSS reset) which would override Bootstrap's base styles.
211
-
212
- ### Generated CSS for Bootstrap projects
213
-
214
- ```css
215
- /* Selective imports to avoid Preflight conflicts with Bootstrap */
216
- @layer theme, base, components, utilities;
217
- @import "tailwindcss/theme.css" layer(theme);
218
- @import "tailwindcss/utilities.css" layer(utilities);
219
-
220
- /* Tell Tailwind to scan component files for utility classes */
221
- @source "./components/**/*.{js,ts,jsx,tsx}";
222
- @source "./lib/**/*.{js,ts,jsx,tsx}";
223
- ```
224
-
225
- ## Tailwind CSS Version Support
226
-
227
- ### Tailwind CSS v4 (default)
228
-
229
- For v4 projects, the CLI generates CSS-based configuration:
230
-
231
- ```css
232
- @import "tailwindcss";
233
-
234
- @theme {
235
- --color-primary: hsl(222.2 47.4% 11.2%);
236
- /* ... */
237
- }
238
- ```
239
-
240
- ### Tailwind CSS v3
241
-
242
- For v3 projects, the CLI generates the traditional configuration with `tailwind.config.js` and CSS variables.
243
-
244
- ## Requirements
245
-
246
- - React 18+
247
- - Tailwind CSS v3 or v4
248
- - TypeScript (recommended)
249
-
250
- ## Dependencies
251
-
252
- Components use these packages (installed automatically during `init`):
253
-
254
- ```bash
255
- npm install clsx tailwind-merge class-variance-authority @radix-ui/react-slot lucide-react
256
- ```
257
-
258
- For Tailwind v3, you'll also need:
259
- - `tailwindcss-animate`
260
-
261
- ## PostCSS Configuration
262
-
263
- The CLI automatically sets up the correct PostCSS configuration for Tailwind CSS.
264
-
265
- ### For Tailwind v4
266
-
267
- ```javascript
268
- // postcss.config.js
269
- export default {
270
- plugins: {
271
- '@tailwindcss/postcss': {},
272
- },
273
- }
274
- ```
275
-
276
- ### Common Error
277
-
278
- If you see this error:
279
-
280
- ```
281
- [plugin:vite:css] [postcss] It looks like you're trying to use `tailwindcss` directly as a PostCSS plugin.
282
- ```
283
-
284
- **Fix it by:**
285
-
286
- 1. Installing the new plugin:
287
- ```bash
288
- npm install -D @tailwindcss/postcss
289
- ```
290
-
291
- 2. Run `npx myoperator-ui init` to automatically create the correct configuration
292
-
293
- ## Troubleshooting
294
-
295
- ### Component styles not applying
296
-
297
- Make sure you've installed the required dependencies:
298
-
299
- ```bash
300
- npm install clsx tailwind-merge class-variance-authority @radix-ui/react-slot lucide-react
301
- ```
302
-
303
- ### Styles conflict with Bootstrap
304
-
305
- If you're seeing Bootstrap styles override your components, make sure:
306
-
307
- 1. You ran `npx myoperator-ui init` after adding Bootstrap
308
- 2. The CSS file has selective imports (not `@import "tailwindcss"`)
309
-
310
- ### Version mismatch
311
-
312
- To ensure you're using the latest version:
313
-
314
- ```bash
315
- npx myoperator-ui@latest init
316
- ```
317
-
318
- ### Updating components
319
-
320
- To get the latest component updates:
321
-
322
- ```bash
323
- # Preview changes first
324
- npx myoperator-ui update --all --dry-run
325
-
326
- # Then apply updates
327
- npx myoperator-ui update --all
328
- ```
329
-
330
- ## Development Workflow (For Maintainers)
331
-
332
- ### Safe Component Updates
333
-
334
- To ensure changes don't accidentally break other components:
335
-
336
- ```bash
337
- cd packages/cli
338
-
339
- # 1. Create a snapshot BEFORE making changes
340
- npm run integrity:snapshot
341
-
342
- # 2. Make your changes to a component (e.g., button.tsx)
343
-
344
- # 3. Verify only the intended component changed
345
- node scripts/check-integrity.js verify button
346
-
347
- # 4. If check passes, build and publish
348
- npm run build
349
- npm publish
350
- ```
351
-
352
- ### Integrity Check Commands
353
-
354
- ```bash
355
- # Create baseline snapshot of all components
356
- npm run integrity:snapshot
357
-
358
- # Verify no unexpected changes
359
- npm run integrity:verify
360
-
361
- # Verify specific component changed (others unchanged)
362
- node scripts/check-integrity.js verify button
363
-
364
- # Verify multiple components changed
365
- node scripts/check-integrity.js verify button badge
366
-
367
- # Check status of a specific component
368
- node scripts/check-integrity.js diff button
369
- ```
370
-
371
- ### What the Integrity Check Does
372
-
373
- 1. **Creates MD5 hashes** of each component file
374
- 2. **Compares current state** against the snapshot
375
- 3. **Fails if unexpected changes** are detected
376
- 4. **Passes if only expected components** changed
377
-
378
- Example output when an unexpected change is detected:
379
-
380
- ```
381
- Component Status:
382
- ──────────────────────────────────────────────────
383
- ✓ badge - unchanged
384
- ✓ button - changed (expected)
385
- ⚠️ table - CHANGED (unexpected!)
386
- ✓ tag - unchanged
387
-
388
- ❌ INTEGRITY CHECK FAILED
389
- Unexpected changes detected in: table
390
- ```
391
-
392
- ## License
393
-
394
- MIT
1
+ # myOperator UI
2
+
3
+ CLI for adding myOperator UI components to your React project. Works with both standalone projects and projects that use Bootstrap or other CSS frameworks.
4
+
5
+ ## Quick Start
6
+
7
+ ```bash
8
+ # Initialize your project
9
+ npx myoperator-ui init
10
+
11
+ # Add a component
12
+ npx myoperator-ui add button
13
+ ```
14
+
15
+ ## Commands
16
+
17
+ ### `init` - Initialize Project
18
+
19
+ ```bash
20
+ npx myoperator-ui init
21
+ ```
22
+
23
+ This will:
24
+ - Create a `components.json` configuration file
25
+ - Set up the utils file with the `cn` helper
26
+ - Create the components directory
27
+ - Create/update your global CSS (`App.scss`) with Tailwind imports
28
+ - Create/update `postcss.config.js` with the correct Tailwind CSS PostCSS plugin
29
+ - Configure Tailwind with `tw-` prefix by default
30
+
31
+ ### `add` - Add Components
32
+
33
+ ```bash
34
+ # Add a specific component
35
+ npx myoperator-ui add button
36
+
37
+ # Add multiple components
38
+ npx myoperator-ui add button badge table
39
+
40
+ # Add all available components at once
41
+ npx myoperator-ui add --all
42
+
43
+ # Interactive selection (shows all available components)
44
+ npx myoperator-ui add
45
+ ```
46
+
47
+ **Options:**
48
+
49
+ | Option | Short | Description |
50
+ |--------|-------|-------------|
51
+ | `--all` | `-a` | Add all available components |
52
+ | `--yes` | `-y` | Skip confirmation prompt |
53
+ | `--overwrite` | `-o` | Overwrite existing files |
54
+ | `--path <path>` | `-p` | Custom path (default: `src/components/ui`) |
55
+
56
+ **Examples:**
57
+
58
+ ```bash
59
+ # Add all components at once
60
+ npx myoperator-ui add --all
61
+
62
+ # Add all components, skip confirmation
63
+ npx myoperator-ui add --all -y
64
+
65
+ # Skip confirmation
66
+ npx myoperator-ui add button -y
67
+
68
+ # Overwrite existing component
69
+ npx myoperator-ui add button --overwrite
70
+
71
+ # Add to custom directory
72
+ npx myoperator-ui add button -p src/ui
73
+ ```
74
+
75
+ ### `update` - Update Components
76
+
77
+ Safely update installed components to the latest version with diff preview.
78
+
79
+ **Important:** Always use `@latest` to ensure you get the newest component code:
80
+
81
+ ```bash
82
+ # Update a specific component (recommended)
83
+ npx myoperator-ui@latest update button
84
+
85
+ # Update multiple components
86
+ npx myoperator-ui@latest update button badge
87
+
88
+ # Interactive selection (shows installed components)
89
+ npx myoperator-ui@latest update
90
+
91
+ # Update all installed components
92
+ npx myoperator-ui@latest update --all
93
+ ```
94
+
95
+ **Options:**
96
+
97
+ | Option | Short | Description |
98
+ |--------|-------|-------------|
99
+ | `--yes` | `-y` | Skip confirmation prompt |
100
+ | `--all` | `-a` | Update all installed components |
101
+ | `--dry-run` | `-d` | Preview changes without modifying files |
102
+ | `--backup` | `-b` | Create backup files before updating |
103
+ | `--path <path>` | `-p` | Custom path (default: `src/components/ui`) |
104
+
105
+ **Examples:**
106
+
107
+ ```bash
108
+ # Preview what would change (safe - no modifications)
109
+ npx myoperator-ui@latest update button --dry-run
110
+
111
+ # Preview all component updates
112
+ npx myoperator-ui@latest update --all --dry-run
113
+
114
+ # Update all with backups
115
+ npx myoperator-ui@latest update --all --backup
116
+
117
+ # Force update without confirmation
118
+ npx myoperator-ui@latest update button -y
119
+ ```
120
+
121
+ > **Note:** If you see "No changes" but expect updates, make sure you're using `@latest` to get the newest package version. NPX may cache older versions.
122
+
123
+ **Update Safeguards:**
124
+ - Shows diff of changes before applying
125
+ - `--dry-run` lets you preview without making changes
126
+ - `--backup` creates timestamped backups (e.g., `button.tsx.backup.1700000000`)
127
+ - Only updates components that are already installed
128
+ - Skips components with no changes
129
+
130
+ ### Other Commands
131
+
132
+ ```bash
133
+ # Check CLI version
134
+ npx myoperator-ui --version
135
+
136
+ # Get help
137
+ npx myoperator-ui --help
138
+ npx myoperator-ui add --help
139
+ npx myoperator-ui update --help
140
+ ```
141
+
142
+ ## Available Components
143
+
144
+ | Component | Description |
145
+ |-----------|-------------|
146
+ | `accordion` | Expandable/collapsible accordion component with single or multiple mode support |
147
+ | `badge` | Status badge with active, failed, disabled, outline, secondary, destructive variants and asChild support |
148
+ | `button` | Customizable button with variants, sizes (including icon-lg), icons, and loading state |
149
+ | `checkbox` | Tri-state checkbox built on Radix UI with label support (checked, unchecked, indeterminate) |
150
+ | `dropdown-menu` | Dropdown menu for displaying actions and options |
151
+ | `input` | Basic input component |
152
+ | `multi-select` | Multi-select dropdown with search, tags, and keyboard navigation |
153
+ | `select` | Single select dropdown component |
154
+ | `select-field` | Select field with label, helper text, and validation states |
155
+ | `switch` | Switch component built on Radix UI for boolean inputs with on/off states |
156
+ | `table` | Composable table with size variants, loading/empty states, sticky columns |
157
+ | `tag` | Tag component for event labels with optional bold label prefix |
158
+ | `text-field` | Text input with label, icons, prefix/suffix, validation states, and character count |
159
+
160
+ ## Configuration
161
+
162
+ After running `init`, a `components.json` file is created:
163
+
164
+ ```json
165
+ {
166
+ "$schema": "https://myoperator.com/schema.json",
167
+ "style": "default",
168
+ "tailwind": {
169
+ "config": "tailwind.config.js",
170
+ "css": "src/App.scss",
171
+ "baseColor": "slate",
172
+ "cssVariables": true,
173
+ "prefix": "tw-"
174
+ },
175
+ "aliases": {
176
+ "components": "@/components",
177
+ "utils": "@/lib/utils",
178
+ "ui": "@/components/ui"
179
+ }
180
+ }
181
+ ```
182
+
183
+ ## Tailwind CSS Configuration
184
+
185
+ The CLI generates a `tailwind.config.js` with:
186
+
187
+ ```javascript
188
+ /** @type {import('tailwindcss').Config} */
189
+ export default {
190
+ darkMode: ["class"],
191
+ prefix: "tw-",
192
+ content: ["./src/components/ui/**/*.{js,ts,jsx,tsx}"],
193
+ theme: {
194
+ // ... theme configuration
195
+ },
196
+ plugins: [require("tailwindcss-animate")],
197
+ }
198
+ ```
199
+
200
+ **Key Features:**
201
+ - `prefix: "tw-"` - Avoids conflicts with other CSS frameworks
202
+ - Scoped content path - Only scans UI components directory
203
+
204
+ ## Bootstrap Compatibility
205
+
206
+ myOperator UI automatically detects if your project uses Bootstrap and configures Tailwind CSS to avoid conflicts.
207
+
208
+ ### How it works
209
+
210
+ When Bootstrap is detected, the CLI uses selective Tailwind imports - importing only theme and utilities, skipping Preflight (Tailwind's CSS reset) which would override Bootstrap's base styles.
211
+
212
+ ### Generated CSS for Bootstrap projects
213
+
214
+ ```css
215
+ /* Selective imports to avoid Preflight conflicts with Bootstrap */
216
+ @layer theme, base, components, utilities;
217
+ @import "tailwindcss/theme.css" layer(theme);
218
+ @import "tailwindcss/utilities.css" layer(utilities);
219
+
220
+ /* Tell Tailwind to scan component files for utility classes */
221
+ @source "./components/**/*.{js,ts,jsx,tsx}";
222
+ @source "./lib/**/*.{js,ts,jsx,tsx}";
223
+ ```
224
+
225
+ ## Tailwind CSS Version Support
226
+
227
+ ### Tailwind CSS v4 (default)
228
+
229
+ For v4 projects, the CLI generates CSS-based configuration:
230
+
231
+ ```css
232
+ @import "tailwindcss";
233
+
234
+ @theme {
235
+ --color-primary: hsl(222.2 47.4% 11.2%);
236
+ /* ... */
237
+ }
238
+ ```
239
+
240
+ ### Tailwind CSS v3
241
+
242
+ For v3 projects, the CLI generates the traditional configuration with `tailwind.config.js` and CSS variables.
243
+
244
+ ## Requirements
245
+
246
+ - React 18+
247
+ - Tailwind CSS v3 or v4
248
+ - TypeScript (recommended)
249
+
250
+ ## Dependencies
251
+
252
+ Components use these packages (installed automatically during `init`):
253
+
254
+ ```bash
255
+ npm install clsx tailwind-merge class-variance-authority @radix-ui/react-slot lucide-react
256
+ ```
257
+
258
+ For Tailwind v3, you'll also need:
259
+ - `tailwindcss-animate`
260
+
261
+ ## PostCSS Configuration
262
+
263
+ The CLI automatically sets up the correct PostCSS configuration for Tailwind CSS.
264
+
265
+ ### For Tailwind v4
266
+
267
+ ```javascript
268
+ // postcss.config.js
269
+ export default {
270
+ plugins: {
271
+ '@tailwindcss/postcss': {},
272
+ },
273
+ }
274
+ ```
275
+
276
+ ### Common Error
277
+
278
+ If you see this error:
279
+
280
+ ```
281
+ [plugin:vite:css] [postcss] It looks like you're trying to use `tailwindcss` directly as a PostCSS plugin.
282
+ ```
283
+
284
+ **Fix it by:**
285
+
286
+ 1. Installing the new plugin:
287
+ ```bash
288
+ npm install -D @tailwindcss/postcss
289
+ ```
290
+
291
+ 2. Run `npx myoperator-ui init` to automatically create the correct configuration
292
+
293
+ ## Troubleshooting
294
+
295
+ ### Component styles not applying
296
+
297
+ Make sure you've installed the required dependencies:
298
+
299
+ ```bash
300
+ npm install clsx tailwind-merge class-variance-authority @radix-ui/react-slot lucide-react
301
+ ```
302
+
303
+ ### Styles conflict with Bootstrap
304
+
305
+ If you're seeing Bootstrap styles override your components, make sure:
306
+
307
+ 1. You ran `npx myoperator-ui init` after adding Bootstrap
308
+ 2. The CSS file has selective imports (not `@import "tailwindcss"`)
309
+
310
+ ### Version mismatch
311
+
312
+ To ensure you're using the latest version:
313
+
314
+ ```bash
315
+ npx myoperator-ui@latest init
316
+ ```
317
+
318
+ ### Updating components
319
+
320
+ To get the latest component updates:
321
+
322
+ ```bash
323
+ # Preview changes first
324
+ npx myoperator-ui update --all --dry-run
325
+
326
+ # Then apply updates
327
+ npx myoperator-ui update --all
328
+ ```
329
+
330
+ ## Development Workflow (For Maintainers)
331
+
332
+ ### Safe Component Updates
333
+
334
+ To ensure changes don't accidentally break other components:
335
+
336
+ ```bash
337
+ cd packages/cli
338
+
339
+ # 1. Create a snapshot BEFORE making changes
340
+ npm run integrity:snapshot
341
+
342
+ # 2. Make your changes to a component (e.g., button.tsx)
343
+
344
+ # 3. Verify only the intended component changed
345
+ node scripts/check-integrity.js verify button
346
+
347
+ # 4. If check passes, build and publish
348
+ npm run build
349
+ npm publish
350
+ ```
351
+
352
+ ### Integrity Check Commands
353
+
354
+ ```bash
355
+ # Create baseline snapshot of all components
356
+ npm run integrity:snapshot
357
+
358
+ # Verify no unexpected changes
359
+ npm run integrity:verify
360
+
361
+ # Verify specific component changed (others unchanged)
362
+ node scripts/check-integrity.js verify button
363
+
364
+ # Verify multiple components changed
365
+ node scripts/check-integrity.js verify button badge
366
+
367
+ # Check status of a specific component
368
+ node scripts/check-integrity.js diff button
369
+ ```
370
+
371
+ ### What the Integrity Check Does
372
+
373
+ 1. **Creates MD5 hashes** of each component file
374
+ 2. **Compares current state** against the snapshot
375
+ 3. **Fails if unexpected changes** are detected
376
+ 4. **Passes if only expected components** changed
377
+
378
+ Example output when an unexpected change is detected:
379
+
380
+ ```
381
+ Component Status:
382
+ ──────────────────────────────────────────────────
383
+ ✓ badge - unchanged
384
+ ✓ button - changed (expected)
385
+ ⚠️ table - CHANGED (unexpected!)
386
+ ✓ tag - unchanged
387
+
388
+ ❌ INTEGRITY CHECK FAILED
389
+ Unexpected changes detected in: table
390
+ ```
391
+
392
+ ## License
393
+
394
+ MIT
package/dist/index.js CHANGED
@@ -2194,6 +2194,172 @@ export const ReadableField = React.forwardRef<HTMLDivElement, ReadableFieldProps
2194
2194
  );
2195
2195
 
2196
2196
  ReadableField.displayName = "ReadableField";
2197
+ `, prefix)
2198
+ }
2199
+ ]
2200
+ },
2201
+ "textarea": {
2202
+ name: "textarea",
2203
+ description: "A multi-line text area with label, helper text, error state, and character count support",
2204
+ category: "form",
2205
+ dependencies: [
2206
+ "class-variance-authority",
2207
+ "clsx",
2208
+ "tailwind-merge"
2209
+ ],
2210
+ files: [
2211
+ {
2212
+ name: "textarea.tsx",
2213
+ content: prefixTailwindClasses(`import * as React from "react";
2214
+ import { cva, type VariantProps } from "class-variance-authority";
2215
+
2216
+ import { cn } from "../../lib/utils";
2217
+
2218
+ const textAreaVariants = cva(
2219
+ "w-full rounded bg-semantic-bg-primary px-4 py-3 text-base text-semantic-text-primary outline-none transition-all resize-y placeholder:text-semantic-text-placeholder disabled:cursor-not-allowed disabled:opacity-50 disabled:bg-[var(--color-neutral-50)]",
2220
+ {
2221
+ variants: {
2222
+ state: {
2223
+ default:
2224
+ "border border-semantic-border-input focus:outline-none focus:border-semantic-border-input-focus/50 focus:shadow-[0_0_0_1px_rgba(43,188,202,0.15)]",
2225
+ error:
2226
+ "border border-semantic-error-primary/40 focus:outline-none focus:border-semantic-error-primary/60 focus:shadow-[0_0_0_1px_rgba(240,68,56,0.1)]",
2227
+ },
2228
+ },
2229
+ defaultVariants: {
2230
+ state: "default",
2231
+ },
2232
+ }
2233
+ );
2234
+
2235
+ export interface TextAreaProps
2236
+ extends React.ComponentProps<"textarea">,
2237
+ VariantProps<typeof textAreaVariants> {
2238
+ /** Label text displayed above the textarea */
2239
+ label?: string;
2240
+ /** Shows red asterisk next to label when true */
2241
+ required?: boolean;
2242
+ /** Helper text displayed below the textarea */
2243
+ helperText?: string;
2244
+ /** Error message - shows error state with red styling */
2245
+ error?: string;
2246
+ /** Shows character count when maxLength is set */
2247
+ showCount?: boolean;
2248
+ /** Additional class for the wrapper container */
2249
+ wrapperClassName?: string;
2250
+ /** Additional class for the label */
2251
+ labelClassName?: string;
2252
+ }
2253
+
2254
+ const TextArea = React.forwardRef<HTMLTextAreaElement, TextAreaProps>(
2255
+ (
2256
+ {
2257
+ className,
2258
+ wrapperClassName,
2259
+ labelClassName,
2260
+ state,
2261
+ label,
2262
+ required,
2263
+ helperText,
2264
+ error,
2265
+ showCount,
2266
+ maxLength,
2267
+ value,
2268
+ defaultValue,
2269
+ onChange,
2270
+ disabled,
2271
+ id,
2272
+ rows = 4,
2273
+ ...props
2274
+ },
2275
+ ref
2276
+ ) => {
2277
+ const [internalValue, setInternalValue] = React.useState(
2278
+ defaultValue ?? ""
2279
+ );
2280
+
2281
+ const isControlled = value !== undefined;
2282
+ const currentValue = isControlled ? value : internalValue;
2283
+ const derivedState = error ? "error" : (state ?? "default");
2284
+
2285
+ const handleChange = (e: React.ChangeEvent<HTMLTextAreaElement>) => {
2286
+ if (!isControlled) setInternalValue(e.target.value);
2287
+ onChange?.(e);
2288
+ };
2289
+
2290
+ const generatedId = React.useId();
2291
+ const textAreaId = id || generatedId;
2292
+ const helperId = \`\${textAreaId}-helper\`;
2293
+ const errorId = \`\${textAreaId}-error\`;
2294
+ const ariaDescribedBy = error ? errorId : helperText ? helperId : undefined;
2295
+ const charCount = String(currentValue).length;
2296
+
2297
+ return (
2298
+ <div className={cn("flex flex-col gap-1.5", wrapperClassName)}>
2299
+ {label && (
2300
+ <label
2301
+ htmlFor={textAreaId}
2302
+ className={cn(
2303
+ "text-sm font-semibold text-semantic-text-secondary tracking-[0.014px]",
2304
+ labelClassName
2305
+ )}
2306
+ >
2307
+ {label}
2308
+ {required && (
2309
+ <span className="text-semantic-error-primary ml-0.5">*</span>
2310
+ )}
2311
+ </label>
2312
+ )}
2313
+
2314
+ <textarea
2315
+ ref={ref}
2316
+ id={textAreaId}
2317
+ rows={rows}
2318
+ className={cn(textAreaVariants({ state: derivedState, className }))}
2319
+ disabled={disabled}
2320
+ maxLength={maxLength}
2321
+ value={isControlled ? value : undefined}
2322
+ defaultValue={!isControlled ? defaultValue : undefined}
2323
+ onChange={handleChange}
2324
+ aria-invalid={!!error}
2325
+ aria-describedby={ariaDescribedBy}
2326
+ {...props}
2327
+ />
2328
+
2329
+ {(error || helperText || (showCount && maxLength)) && (
2330
+ <div className="flex justify-between items-start gap-2">
2331
+ {error ? (
2332
+ <span id={errorId} className="text-xs text-semantic-error-primary">
2333
+ {error}
2334
+ </span>
2335
+ ) : helperText ? (
2336
+ <span id={helperId} className="text-xs text-semantic-text-muted">
2337
+ {helperText}
2338
+ </span>
2339
+ ) : (
2340
+ <span />
2341
+ )}
2342
+ {showCount && maxLength && (
2343
+ <span
2344
+ className={cn(
2345
+ "text-xs",
2346
+ charCount > maxLength
2347
+ ? "text-semantic-error-primary"
2348
+ : "text-semantic-text-muted"
2349
+ )}
2350
+ >
2351
+ {charCount}/{maxLength}
2352
+ </span>
2353
+ )}
2354
+ </div>
2355
+ )}
2356
+ </div>
2357
+ );
2358
+ }
2359
+ );
2360
+ TextArea.displayName = "TextArea";
2361
+
2362
+ export { TextArea, textAreaVariants };
2197
2363
  `, prefix)
2198
2364
  }
2199
2365
  ]
@@ -16465,6 +16631,159 @@ export interface WalletTopupProps {
16465
16631
  name: "index.ts",
16466
16632
  content: prefixTailwindClasses(`export { WalletTopup } from "./wallet-topup";
16467
16633
  export type { WalletTopupProps, AmountOption } from "./types";
16634
+ `, prefix)
16635
+ }
16636
+ ]
16637
+ },
16638
+ "fallback-prompts-panel": {
16639
+ name: "fallback-prompts-panel",
16640
+ description: "An accordion card for configuring IVR bot fallback prompt messages (agent busy and no extension found)",
16641
+ category: "custom",
16642
+ dependencies: [
16643
+ "clsx",
16644
+ "tailwind-merge",
16645
+ "lucide-react"
16646
+ ],
16647
+ internalDependencies: [
16648
+ "accordion",
16649
+ "textarea"
16650
+ ],
16651
+ isMultiFile: true,
16652
+ directory: "fallback-prompts-panel",
16653
+ mainFile: "fallback-prompts-panel.tsx",
16654
+ files: [
16655
+ {
16656
+ name: "fallback-prompts-panel.tsx",
16657
+ content: prefixTailwindClasses(`import * as React from "react";
16658
+ import { Info } from "lucide-react";
16659
+ import { cn } from "../../../lib/utils";
16660
+ import { TextArea } from "../textarea";
16661
+ import {
16662
+ Accordion,
16663
+ AccordionItem,
16664
+ AccordionTrigger,
16665
+ AccordionContent,
16666
+ } from "../accordion";
16667
+ import type { FallbackPromptsBaseProps } from "./types";
16668
+
16669
+ export interface FallbackPromptsPanelProps
16670
+ extends Omit<React.HTMLAttributes<HTMLDivElement>, "onChange">,
16671
+ FallbackPromptsBaseProps {}
16672
+
16673
+ const AGENT_BUSY_PLACEHOLDER =
16674
+ "Executives are busy at the moment, we will connect you soon.";
16675
+ const NO_EXTENSION_PLACEHOLDER =
16676
+ "Sorry, the requested extension is currently unavailable. Let me help you directly.";
16677
+
16678
+ const FallbackPromptsPanel = React.forwardRef<
16679
+ HTMLDivElement,
16680
+ FallbackPromptsPanelProps
16681
+ >(
16682
+ (
16683
+ {
16684
+ data,
16685
+ onChange,
16686
+ tooltipContent = "Configure the messages your bot speaks when it cannot reach an agent or extension.",
16687
+ defaultOpen = true,
16688
+ disabled,
16689
+ className,
16690
+ ...rest
16691
+ },
16692
+ ref
16693
+ ) => {
16694
+ return (
16695
+ <div
16696
+ ref={ref}
16697
+ className={cn(
16698
+ "bg-semantic-bg-primary border border-semantic-border-layout rounded-lg overflow-hidden",
16699
+ className
16700
+ )}
16701
+ {...rest}
16702
+ >
16703
+ <Accordion
16704
+ type="single"
16705
+ defaultValue={defaultOpen ? ["fallback-prompts"] : []}
16706
+ >
16707
+ <AccordionItem value="fallback-prompts">
16708
+ <AccordionTrigger className="px-4 py-4 border-b border-semantic-border-layout hover:no-underline hover:bg-transparent sm:px-6 sm:py-5">
16709
+ <div className="flex items-center gap-1.5">
16710
+ <span className="text-base font-semibold text-semantic-text-primary">
16711
+ Fallback Prompts
16712
+ </span>
16713
+ <span
16714
+ title={tooltipContent}
16715
+ className="flex items-center text-semantic-text-muted cursor-default"
16716
+ aria-label={tooltipContent}
16717
+ >
16718
+ <Info className="size-3.5" />
16719
+ </span>
16720
+ </div>
16721
+ </AccordionTrigger>
16722
+
16723
+ <AccordionContent>
16724
+ <div className="flex flex-col gap-4 px-4 pt-4 sm:gap-6 sm:px-6 sm:pt-6">
16725
+ <TextArea
16726
+ label="Agent Busy Prompt"
16727
+ placeholder={AGENT_BUSY_PLACEHOLDER}
16728
+ value={data.agentBusyPrompt ?? ""}
16729
+ onChange={(e) =>
16730
+ onChange({ agentBusyPrompt: e.target.value })
16731
+ }
16732
+ rows={3}
16733
+ disabled={disabled}
16734
+ />
16735
+
16736
+ <TextArea
16737
+ label="No Extension Found"
16738
+ placeholder={NO_EXTENSION_PLACEHOLDER}
16739
+ value={data.noExtensionFound ?? ""}
16740
+ onChange={(e) =>
16741
+ onChange({ noExtensionFound: e.target.value })
16742
+ }
16743
+ rows={3}
16744
+ disabled={disabled}
16745
+ />
16746
+ </div>
16747
+ </AccordionContent>
16748
+ </AccordionItem>
16749
+ </Accordion>
16750
+ </div>
16751
+ );
16752
+ }
16753
+ );
16754
+ FallbackPromptsPanel.displayName = "FallbackPromptsPanel";
16755
+
16756
+ export { FallbackPromptsPanel };
16757
+ `, prefix)
16758
+ },
16759
+ {
16760
+ name: "types.ts",
16761
+ content: prefixTailwindClasses(`export interface FallbackPromptsData {
16762
+ /** Text spoken when all agents are busy */
16763
+ agentBusyPrompt: string;
16764
+ /** Text spoken when a dialed extension is not found */
16765
+ noExtensionFound: string;
16766
+ }
16767
+
16768
+ export interface FallbackPromptsBaseProps {
16769
+ /** Current prompt values */
16770
+ data: Partial<FallbackPromptsData>;
16771
+ /** Callback fired when any prompt value changes */
16772
+ onChange: (patch: Partial<FallbackPromptsData>) => void;
16773
+ /** Tooltip content shown next to the title */
16774
+ tooltipContent?: string;
16775
+ /** Opens the panel expanded by default */
16776
+ defaultOpen?: boolean;
16777
+ /** Disables all textareas */
16778
+ disabled?: boolean;
16779
+ }
16780
+ `, prefix)
16781
+ },
16782
+ {
16783
+ name: "index.ts",
16784
+ content: prefixTailwindClasses(`export { FallbackPromptsPanel } from "./fallback-prompts-panel";
16785
+ export type { FallbackPromptsPanelProps } from "./fallback-prompts-panel";
16786
+ export type { FallbackPromptsData, FallbackPromptsBaseProps } from "./types";
16468
16787
  `, prefix)
16469
16788
  }
16470
16789
  ]
package/package.json CHANGED
@@ -1,67 +1,67 @@
1
- {
2
- "name": "myoperator-ui",
3
- "version": "0.0.209",
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
- "generate-registry": "node scripts/generate-registry.js",
15
- "validate-registry": "node scripts/validate-registry.js",
16
- "validate:prefix": "node scripts/validate-prefix-output.js",
17
- "validate:coverage": "node scripts/validate-prefix-coverage.js",
18
- "validate:bootstrap": "node scripts/validate-bootstrap-resets.js",
19
- "validate:multifile": "node scripts/validate-multifile-components.js",
20
- "verify-build": "node scripts/verify-build.js",
21
- "integrity:snapshot": "node scripts/check-integrity.js snapshot",
22
- "integrity:verify": "node scripts/check-integrity.js verify",
23
- "validate-types": "node scripts/validate-types.js",
24
- "validate:source-types": "node scripts/validate-source-types.js",
25
- "validate:imports": "node scripts/validate-imports.js",
26
- "validate:prefix-sync": "node scripts/sync-prefix-utils.js --check",
27
- "build": "npm run validate:source-types && npm run validate:imports && npm run generate-registry && npm run validate:prefix && npm run validate:coverage && npm run validate:bootstrap && npm run validate:multifile && npm run validate:prefix-sync && tsup src/index.ts --format esm --dts && npm run verify-build",
28
- "build:safe": "npm run integrity:snapshot && npm run build",
29
- "dev": "tsup src/index.ts --format esm --watch",
30
- "typecheck": "tsc --noEmit",
31
- "test": "vitest run",
32
- "test:e2e": "vitest run src/__tests__/e2e.test.ts --testTimeout 180000",
33
- "test:e2e:smoke": "E2E_SMOKE=1 vitest run src/__tests__/e2e.test.ts --testTimeout 60000",
34
- "test:watch": "vitest",
35
- "prepublishOnly": "node scripts/check-publish-allowed.js && npm run validate-types && npm run build && npm run validate-registry && npm run test:e2e"
36
- },
37
- "dependencies": {
38
- "chalk": "^5.3.0",
39
- "commander": "^12.1.0",
40
- "fs-extra": "^11.2.0",
41
- "ora": "^8.0.1",
42
- "prompts": "^2.4.2"
43
- },
44
- "devDependencies": {
45
- "@types/fs-extra": "^11.0.4",
46
- "@types/js-yaml": "^4.0.9",
47
- "@types/node": "^20.11.0",
48
- "@types/prompts": "^2.4.9",
49
- "js-yaml": "^4.1.0",
50
- "tsup": "^8.0.1",
51
- "typescript": "^5.3.3",
52
- "vitest": "^1.0.0"
53
- },
54
- "keywords": [
55
- "myoperator",
56
- "ui",
57
- "components",
58
- "cli",
59
- "react"
60
- ],
61
- "author": "",
62
- "license": "MIT",
63
- "repository": {
64
- "type": "git",
65
- "url": "https://github.com/Ankish8/storybook-npm.git"
66
- }
67
- }
1
+ {
2
+ "name": "myoperator-ui",
3
+ "version": "0.0.210-beta.0",
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
+ "generate-registry": "node scripts/generate-registry.js",
15
+ "validate-registry": "node scripts/validate-registry.js",
16
+ "validate:prefix": "node scripts/validate-prefix-output.js",
17
+ "validate:coverage": "node scripts/validate-prefix-coverage.js",
18
+ "validate:bootstrap": "node scripts/validate-bootstrap-resets.js",
19
+ "validate:multifile": "node scripts/validate-multifile-components.js",
20
+ "verify-build": "node scripts/verify-build.js",
21
+ "integrity:snapshot": "node scripts/check-integrity.js snapshot",
22
+ "integrity:verify": "node scripts/check-integrity.js verify",
23
+ "validate-types": "node scripts/validate-types.js",
24
+ "validate:source-types": "node scripts/validate-source-types.js",
25
+ "validate:imports": "node scripts/validate-imports.js",
26
+ "validate:prefix-sync": "node scripts/sync-prefix-utils.js --check",
27
+ "build": "npm run validate:source-types && npm run validate:imports && npm run generate-registry && npm run validate:prefix && npm run validate:coverage && npm run validate:bootstrap && npm run validate:multifile && npm run validate:prefix-sync && tsup src/index.ts --format esm --dts && npm run verify-build",
28
+ "build:safe": "npm run integrity:snapshot && npm run build",
29
+ "dev": "tsup src/index.ts --format esm --watch",
30
+ "typecheck": "tsc --noEmit",
31
+ "test": "vitest run",
32
+ "test:e2e": "vitest run src/__tests__/e2e.test.ts --testTimeout 180000",
33
+ "test:e2e:smoke": "E2E_SMOKE=1 vitest run src/__tests__/e2e.test.ts --testTimeout 60000",
34
+ "test:watch": "vitest",
35
+ "prepublishOnly": "node scripts/check-publish-allowed.js && npm run validate-types && npm run build && npm run validate-registry && npm run test:e2e"
36
+ },
37
+ "dependencies": {
38
+ "chalk": "^5.3.0",
39
+ "commander": "^12.1.0",
40
+ "fs-extra": "^11.2.0",
41
+ "ora": "^8.0.1",
42
+ "prompts": "^2.4.2"
43
+ },
44
+ "devDependencies": {
45
+ "@types/fs-extra": "^11.0.4",
46
+ "@types/js-yaml": "^4.0.9",
47
+ "@types/node": "^20.11.0",
48
+ "@types/prompts": "^2.4.9",
49
+ "js-yaml": "^4.1.0",
50
+ "tsup": "^8.0.1",
51
+ "typescript": "^5.3.3",
52
+ "vitest": "^1.0.0"
53
+ },
54
+ "keywords": [
55
+ "myoperator",
56
+ "ui",
57
+ "components",
58
+ "cli",
59
+ "react"
60
+ ],
61
+ "author": "",
62
+ "license": "MIT",
63
+ "repository": {
64
+ "type": "git",
65
+ "url": "https://github.com/Ankish8/storybook-npm.git"
66
+ }
67
+ }