@srcroot/ui 0.0.55 → 0.0.58

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 (107) hide show
  1. package/README.md +151 -151
  2. package/dist/index.d.ts +0 -0
  3. package/dist/index.js +120 -93
  4. package/package.json +7 -2
  5. package/src/registry/analytics/google-analytics.tsx +36 -39
  6. package/src/registry/analytics/google-tag-manager.tsx +62 -65
  7. package/src/registry/analytics/meta-pixel.tsx +44 -47
  8. package/src/registry/analytics/microsoft-clarity.tsx +31 -34
  9. package/src/registry/analytics/tiktok-pixel.tsx +34 -37
  10. package/src/registry/lib/utils.ts +0 -0
  11. package/src/registry/themes/v3/blue.css +157 -157
  12. package/src/registry/themes/v3/glass.css +153 -153
  13. package/src/registry/themes/v3/gray.css +157 -157
  14. package/src/registry/themes/v3/green.css +157 -157
  15. package/src/registry/themes/v3/neutral.css +157 -157
  16. package/src/registry/themes/v3/orange.css +157 -157
  17. package/src/registry/themes/v3/rose.css +157 -157
  18. package/src/registry/themes/v3/slate.css +157 -157
  19. package/src/registry/themes/v3/stone.css +157 -157
  20. package/src/registry/themes/v3/violet.css +186 -186
  21. package/src/registry/themes/v3/zinc.css +157 -157
  22. package/src/registry/themes/v4/blue.css +184 -184
  23. package/src/registry/themes/v4/glass.css +180 -180
  24. package/src/registry/themes/v4/gray.css +184 -184
  25. package/src/registry/themes/v4/green.css +184 -184
  26. package/src/registry/themes/v4/neutral.css +184 -184
  27. package/src/registry/themes/v4/orange.css +184 -184
  28. package/src/registry/themes/v4/rose.css +184 -184
  29. package/src/registry/themes/v4/slate.css +184 -184
  30. package/src/registry/themes/v4/stone.css +184 -184
  31. package/src/registry/themes/v4/violet.css +184 -184
  32. package/src/registry/themes/v4/zinc.css +184 -184
  33. package/src/registry/ui/accordion.tsx +164 -165
  34. package/src/registry/ui/alert-dialog.tsx +213 -214
  35. package/src/registry/ui/alert.tsx +73 -76
  36. package/src/registry/ui/aspect-ratio.tsx +44 -47
  37. package/src/registry/ui/avatar.tsx +96 -97
  38. package/src/registry/ui/badge.tsx +52 -55
  39. package/src/registry/ui/breadcrumb.tsx +147 -150
  40. package/src/registry/ui/button-group.tsx +64 -67
  41. package/src/registry/ui/button.tsx +71 -72
  42. package/src/registry/ui/calendar.tsx +514 -515
  43. package/src/registry/ui/card.tsx +88 -91
  44. package/src/registry/ui/carousel.tsx +214 -214
  45. package/src/registry/ui/chart.tsx +373 -373
  46. package/src/registry/ui/chatbot.tsx +86 -13
  47. package/src/registry/ui/checkbox.tsx +93 -94
  48. package/src/registry/ui/collapsible.tsx +107 -108
  49. package/src/registry/ui/combobox.tsx +171 -171
  50. package/src/registry/ui/command.tsx +300 -300
  51. package/src/registry/ui/container.tsx +44 -47
  52. package/src/registry/ui/context-menu.tsx +221 -221
  53. package/src/registry/ui/date-picker.tsx +228 -228
  54. package/src/registry/ui/dialog.tsx +269 -270
  55. package/src/registry/ui/drawer.tsx +10 -4
  56. package/src/registry/ui/dropdown-menu.tsx +529 -530
  57. package/src/registry/ui/empty-state.tsx +0 -2
  58. package/src/registry/ui/file-upload.tsx +0 -0
  59. package/src/registry/ui/floating-dock.tsx +0 -0
  60. package/src/registry/ui/form-field.tsx +91 -94
  61. package/src/registry/ui/google-analytics.tsx +38 -0
  62. package/src/registry/ui/google-tag-manager.tsx +64 -0
  63. package/src/registry/ui/hover-card.tsx +223 -223
  64. package/src/registry/ui/image.tsx +144 -147
  65. package/src/registry/ui/input-group.tsx +82 -85
  66. package/src/registry/ui/input.tsx +125 -125
  67. package/src/registry/ui/kbd.tsx +60 -63
  68. package/src/registry/ui/label.tsx +36 -37
  69. package/src/registry/ui/loading-spinner.tsx +108 -111
  70. package/src/registry/ui/map.tsx +0 -0
  71. package/src/registry/ui/marquee.tsx +2 -0
  72. package/src/registry/ui/menubar.tsx +246 -246
  73. package/src/registry/ui/meta-pixel.tsx +46 -0
  74. package/src/registry/ui/microsoft-clarity.tsx +33 -0
  75. package/src/registry/ui/native-select.tsx +49 -52
  76. package/src/registry/ui/otp-input.tsx +163 -155
  77. package/src/registry/ui/pagination.tsx +149 -152
  78. package/src/registry/ui/patterns.tsx +28 -0
  79. package/src/registry/ui/popover.tsx +226 -227
  80. package/src/registry/ui/progress.tsx +51 -52
  81. package/src/registry/ui/radio.tsx +99 -102
  82. package/src/registry/ui/resizable.tsx +314 -314
  83. package/src/registry/ui/scroll-animation.tsx +45 -0
  84. package/src/registry/ui/scroll-area.tsx +121 -122
  85. package/src/registry/ui/scroll-to-top.tsx +0 -0
  86. package/src/registry/ui/search.tsx +162 -150
  87. package/src/registry/ui/select.tsx +292 -293
  88. package/src/registry/ui/separator.tsx +46 -47
  89. package/src/registry/ui/sheet.tsx +6 -3
  90. package/src/registry/ui/sidebar.tsx +628 -628
  91. package/src/registry/ui/skeleton.tsx +26 -29
  92. package/src/registry/ui/slider.tsx +196 -197
  93. package/src/registry/ui/slot.tsx +69 -72
  94. package/src/registry/ui/star-rating.tsx +146 -134
  95. package/src/registry/ui/switch.tsx +72 -73
  96. package/src/registry/ui/table-of-contents.tsx +96 -96
  97. package/src/registry/ui/table.tsx +138 -139
  98. package/src/registry/ui/tabs.tsx +124 -125
  99. package/src/registry/ui/text.tsx +61 -64
  100. package/src/registry/ui/textarea.tsx +41 -42
  101. package/src/registry/ui/theme-switcher.tsx +66 -66
  102. package/src/registry/ui/tiktok-pixel.tsx +36 -0
  103. package/src/registry/ui/toast.tsx +97 -98
  104. package/src/registry/ui/toggle-group.tsx +129 -129
  105. package/src/registry/ui/toggle.tsx +72 -72
  106. package/src/registry/ui/tooltip.tsx +143 -144
  107. package/src/registry/ui/whatsapp.tsx +0 -0
package/README.md CHANGED
@@ -1,151 +1,151 @@
1
- # @srcroot/ui
2
-
3
- A UI library with polymorphic, accessible React components.
4
- This library provides a collection of re-usable components that you can copy and paste into your apps.
5
-
6
- ## Features
7
-
8
- - **Polymorphic**: Most components support an `as` prop (e.g., render a `Button` as an `a` tag).
9
- - **Accessible**: Built on standard HTML elements and WAI-ARIA patterns.
10
- - **Copy/Paste**: Not a dependency you install, but code you own.
11
- - **Styled**: Beautiful defaults using Tailwind CSS and `class-variance-authority`.
12
-
13
- ## Installation
14
-
15
- This library is distributed via a CLI that initializes your project and adds components directly to your source code.
16
-
17
- ### 1. Initialize
18
-
19
- Run the `init` command to set up the necessary dependencies and structural files (like `cn` utility) in your project.
20
-
21
- ```bash
22
- npx @srcroot/ui init
23
- ```
24
-
25
- This will ask a few questions to configure your project structure (e.g., where to put components).
26
-
27
- ### 2. Add Components
28
-
29
- Use the `add` command to install components. You can do this in three ways:
30
-
31
- **Interactive Mode:**
32
- Run without arguments to select components from a list.
33
- ```bash
34
- npx @srcroot/ui add
35
- ```
36
-
37
- **Specific Components:**
38
- Add one or more components by name.
39
- ```bash
40
- npx @srcroot/ui add button card input
41
- ```
42
-
43
- **Add All:**
44
- Install every available component at once.
45
- ```bash
46
- npx @srcroot/ui add --all
47
- ```
48
-
49
- This will copy the component files to your `components/ui` directory and install any necessary peer dependencies (like `react-icons` or `clsx`).
50
-
51
- ### 3. Usage
52
-
53
- Import components directly from your project folder:
54
-
55
- ```tsx
56
- import { Button } from "@/components/ui/button"
57
-
58
- export default function Home() {
59
- return (
60
- <Button variant="destructive" onClick={() => alert("Clicked!")}>
61
- Click Me
62
- </Button>
63
- )
64
- }
65
- ```
66
-
67
- ## Available Components
68
-
69
- run `npx @srcroot/ui list` to see all available components.
70
-
71
- ### Core
72
- - `button` - Polymorphic button with variants.
73
- - `badge` - Status indicators.
74
- - `avatar` - User profile images with fallbacks.
75
- - `separator` - Visual divider.
76
- - `button-group` - Attached or spaced button sets.
77
-
78
- ### Forms
79
- - `input` - Basic text input.
80
- - `textarea` - Multi-line text input.
81
- - `checkbox` - Toggle selection.
82
- - `radio` - Single selection from list.
83
- - `switch` - Toggle switch.
84
- - `select` - Dropdown selection.
85
- - `slider` - Range input.
86
- - `otp-input` - One-time password verification.
87
- - `search` - Search input with debounce support.
88
- - `calendar` - Date and range picker.
89
-
90
- ### Layout
91
- - `card` - Content container with header/content/footer.
92
- - `container` - Centered layout wrapper.
93
- - `aspect-ratio` - Maintain element proportions.
94
-
95
- ### Data Display
96
- - `text` - Polymorphic typography component.
97
- - `label` - Accessible form label.
98
- - `table` - Responsive data table.
99
- - `accordion` - Collapsible content sections.
100
- - `collapsible` - Expandable panel.
101
- - `tabs` - Tabbed content switcher.
102
- - `progress` - Progress bar.
103
- - `skeleton` - Loading placeholder state.
104
- - `image` - Enhanced img with fallback and loading state.
105
- - `carousel` - Content slider with autoplay.
106
-
107
- ### Feedback
108
- - `loading-spinner` - SVG spinner with variants.
109
- - `star-rating` - Interactive rating component.
110
- - `toast` - Transient notifications.
111
- - `alert` - Critical information banner.
112
-
113
- ### Overlays
114
- - `dialog` - Modal dialog.
115
- - `alert-dialog` - Modal for confirming actions.
116
- - `sheet` - Side-panel overlay.
117
- - `popover` - Content appearing over trigger.
118
- - `tooltip` - Hover information.
119
- - `dropdown-menu` - Menu for actions/navigation.
120
-
121
- ### Navigation
122
- - `breadcrumb` - Navigation trail.
123
- - `pagination` - Page navigation controls.
124
-
125
- ## Polymorphism
126
-
127
- Our components accept an `as` prop to change the underlying HTML element while maintaining styles and behavior.
128
-
129
- ```tsx
130
- // Renders as an <a> tag but looks like a button
131
- <Button as="a" href="/login">
132
- Login
133
- </Button>
134
-
135
- // Renders as a specialized text variant
136
- <Text as="h1" variant="h1">
137
- Page Title
138
- </Text>
139
- ```
140
-
141
- ## Local Development
142
-
143
- To run the documentation/playground locally:
144
-
145
- ```bash
146
- cd examples/playground
147
- npm install
148
- npm run dev
149
- ```
150
-
151
- Visit `http://localhost:3001` to view the component showcase.
1
+ # @srcroot/ui
2
+
3
+ A UI library with polymorphic, accessible React components.
4
+ This library provides a collection of re-usable components that you can copy and paste into your apps.
5
+
6
+ ## Features
7
+
8
+ - **Polymorphic**: Most components support an `as` prop (e.g., render a `Button` as an `a` tag).
9
+ - **Accessible**: Built on standard HTML elements and WAI-ARIA patterns.
10
+ - **Copy/Paste**: Not a dependency you install, but code you own.
11
+ - **Styled**: Beautiful defaults using Tailwind CSS and `class-variance-authority`.
12
+
13
+ ## Installation
14
+
15
+ This library is distributed via a CLI that initializes your project and adds components directly to your source code.
16
+
17
+ ### 1. Initialize
18
+
19
+ Run the `init` command to set up the necessary dependencies and structural files (like `cn` utility) in your project.
20
+
21
+ ```bash
22
+ npx @srcroot/ui init
23
+ ```
24
+
25
+ This will ask a few questions to configure your project structure (e.g., where to put components).
26
+
27
+ ### 2. Add Components
28
+
29
+ Use the `add` command to install components. You can do this in three ways:
30
+
31
+ **Interactive Mode:**
32
+ Run without arguments to select components from a list.
33
+ ```bash
34
+ npx @srcroot/ui add
35
+ ```
36
+
37
+ **Specific Components:**
38
+ Add one or more components by name.
39
+ ```bash
40
+ npx @srcroot/ui add button card input
41
+ ```
42
+
43
+ **Add All:**
44
+ Install every available component at once.
45
+ ```bash
46
+ npx @srcroot/ui add --all
47
+ ```
48
+
49
+ This will copy the component files to your `components/ui` directory and install any necessary peer dependencies (like `react-icons` or `clsx`).
50
+
51
+ ### 3. Usage
52
+
53
+ Import components directly from your project folder:
54
+
55
+ ```tsx
56
+ import { Button } from "@/components/ui/button"
57
+
58
+ export default function Home() {
59
+ return (
60
+ <Button variant="destructive" onClick={() => alert("Clicked!")}>
61
+ Click Me
62
+ </Button>
63
+ )
64
+ }
65
+ ```
66
+
67
+ ## Available Components
68
+
69
+ run `npx @srcroot/ui list` to see all available components.
70
+
71
+ ### Core
72
+ - `button` - Polymorphic button with variants.
73
+ - `badge` - Status indicators.
74
+ - `avatar` - User profile images with fallbacks.
75
+ - `separator` - Visual divider.
76
+ - `button-group` - Attached or spaced button sets.
77
+
78
+ ### Forms
79
+ - `input` - Basic text input.
80
+ - `textarea` - Multi-line text input.
81
+ - `checkbox` - Toggle selection.
82
+ - `radio` - Single selection from list.
83
+ - `switch` - Toggle switch.
84
+ - `select` - Dropdown selection.
85
+ - `slider` - Range input.
86
+ - `otp-input` - One-time password verification.
87
+ - `search` - Search input with debounce support.
88
+ - `calendar` - Date and range picker.
89
+
90
+ ### Layout
91
+ - `card` - Content container with header/content/footer.
92
+ - `container` - Centered layout wrapper.
93
+ - `aspect-ratio` - Maintain element proportions.
94
+
95
+ ### Data Display
96
+ - `text` - Polymorphic typography component.
97
+ - `label` - Accessible form label.
98
+ - `table` - Responsive data table.
99
+ - `accordion` - Collapsible content sections.
100
+ - `collapsible` - Expandable panel.
101
+ - `tabs` - Tabbed content switcher.
102
+ - `progress` - Progress bar.
103
+ - `skeleton` - Loading placeholder state.
104
+ - `image` - Enhanced img with fallback and loading state.
105
+ - `carousel` - Content slider with autoplay.
106
+
107
+ ### Feedback
108
+ - `loading-spinner` - SVG spinner with variants.
109
+ - `star-rating` - Interactive rating component.
110
+ - `toast` - Transient notifications.
111
+ - `alert` - Critical information banner.
112
+
113
+ ### Overlays
114
+ - `dialog` - Modal dialog.
115
+ - `alert-dialog` - Modal for confirming actions.
116
+ - `sheet` - Side-panel overlay.
117
+ - `popover` - Content appearing over trigger.
118
+ - `tooltip` - Hover information.
119
+ - `dropdown-menu` - Menu for actions/navigation.
120
+
121
+ ### Navigation
122
+ - `breadcrumb` - Navigation trail.
123
+ - `pagination` - Page navigation controls.
124
+
125
+ ## Polymorphism
126
+
127
+ Our components accept an `as` prop to change the underlying HTML element while maintaining styles and behavior.
128
+
129
+ ```tsx
130
+ // Renders as an <a> tag but looks like a button
131
+ <Button as="a" href="/login">
132
+ Login
133
+ </Button>
134
+
135
+ // Renders as a specialized text variant
136
+ <Text as="h1" variant="h1">
137
+ Page Title
138
+ </Text>
139
+ ```
140
+
141
+ ## Local Development
142
+
143
+ To run the documentation/playground locally:
144
+
145
+ ```bash
146
+ cd examples/playground
147
+ npm install
148
+ npm run dev
149
+ ```
150
+
151
+ Visit `http://localhost:3001` to view the component showcase.
package/dist/index.d.ts CHANGED
File without changes
package/dist/index.js CHANGED
@@ -5,11 +5,11 @@ import { Command } from "commander";
5
5
  import chalk3 from "chalk";
6
6
 
7
7
  // src/cli/services/project-initializer.ts
8
- import fs3 from "fs-extra";
9
- import path3 from "path";
8
+ import fs4 from "fs-extra";
9
+ import path4 from "path";
10
10
  import ora from "ora";
11
11
  import prompts from "prompts";
12
- import { fileURLToPath as fileURLToPath2 } from "url";
12
+ import { fileURLToPath as fileURLToPath3 } from "url";
13
13
  import { execa } from "execa";
14
14
 
15
15
  // src/cli/services/theme-service.ts
@@ -167,6 +167,25 @@ function getPackageManager(cwd) {
167
167
  return "npm";
168
168
  }
169
169
 
170
+ // src/cli/utils/get-package-info.ts
171
+ import path3 from "path";
172
+ import fs3 from "fs-extra";
173
+ import { fileURLToPath as fileURLToPath2 } from "url";
174
+ function getPackageInfo() {
175
+ const __filename2 = fileURLToPath2(import.meta.url);
176
+ const __dirname5 = path3.dirname(__filename2);
177
+ const pathsToCheck = [
178
+ path3.resolve(__dirname5, "..", "package.json"),
179
+ path3.resolve(__dirname5, "..", "..", "..", "package.json")
180
+ ];
181
+ for (const pkgPath of pathsToCheck) {
182
+ if (fs3.existsSync(pkgPath)) {
183
+ return fs3.readJSONSync(pkgPath);
184
+ }
185
+ }
186
+ return { version: "0.0.0" };
187
+ }
188
+
170
189
  // src/cli/utils/logger.ts
171
190
  import chalk from "chalk";
172
191
  var logger = {
@@ -185,7 +204,7 @@ var logger = {
185
204
  };
186
205
 
187
206
  // src/cli/services/project-initializer.ts
188
- var __dirname3 = path3.dirname(fileURLToPath2(import.meta.url));
207
+ var __dirname3 = path4.dirname(fileURLToPath3(import.meta.url));
189
208
  var ProjectInitializer = class {
190
209
  options;
191
210
  config = {};
@@ -204,13 +223,13 @@ var ProjectInitializer = class {
204
223
  this.printSuccess();
205
224
  }
206
225
  async validateEnvironment() {
207
- const cwd = path3.resolve(this.options.cwd);
208
- const packageJsonPath = path3.join(cwd, "package.json");
209
- if (!fs3.existsSync(packageJsonPath)) {
226
+ const cwd = path4.resolve(this.options.cwd);
227
+ const packageJsonPath = path4.join(cwd, "package.json");
228
+ if (!fs4.existsSync(packageJsonPath)) {
210
229
  logger.error("Error: No package.json found. Please run this in a project directory.");
211
230
  process.exit(1);
212
231
  }
213
- const pkg = await fs3.readJson(packageJsonPath);
232
+ const pkg = await fs4.readJson(packageJsonPath);
214
233
  const allDeps = { ...pkg.dependencies, ...pkg.devDependencies };
215
234
  if (!allDeps["react"]) {
216
235
  logger.error("Error: React not found in dependencies. Please initialize this in a React project.");
@@ -218,33 +237,33 @@ var ProjectInitializer = class {
218
237
  }
219
238
  }
220
239
  async detectConfiguration() {
221
- const cwd = path3.resolve(this.options.cwd);
240
+ const cwd = path4.resolve(this.options.cwd);
222
241
  const packageManager = getPackageManager(cwd);
223
242
  const installCmd = packageManager === "npm" ? "install" : "add";
224
- const pkg = await fs3.readJson(path3.join(cwd, "package.json"));
243
+ const pkg = await fs4.readJson(path4.join(cwd, "package.json"));
225
244
  const allDeps = { ...pkg.dependencies, ...pkg.devDependencies };
226
245
  const tailwindVersion = allDeps["tailwindcss"] || "";
227
246
  const isTailwind4 = tailwindVersion.includes("^4") || tailwindVersion.startsWith("4") || allDeps["@tailwindcss/postcss"];
228
- const hasSrc = fs3.existsSync(path3.join(cwd, "src"));
229
- const srcPath = hasSrc ? path3.join(cwd, "src") : cwd;
230
- const appPath = path3.join(srcPath, "app");
231
- const pagesPath = path3.join(srcPath, "pages");
232
- const hasAppDir = fs3.existsSync(appPath);
233
- const hasPagesDir = fs3.existsSync(pagesPath);
234
- const libDir = path3.join(srcPath, "lib");
235
- const componentsDir = path3.join(srcPath, "components", "ui");
247
+ const hasSrc = fs4.existsSync(path4.join(cwd, "src"));
248
+ const srcPath = hasSrc ? path4.join(cwd, "src") : cwd;
249
+ const appPath = path4.join(srcPath, "app");
250
+ const pagesPath = path4.join(srcPath, "pages");
251
+ const hasAppDir = fs4.existsSync(appPath);
252
+ const hasPagesDir = fs4.existsSync(pagesPath);
253
+ const libDir = path4.join(srcPath, "lib");
254
+ const componentsDir = path4.join(srcPath, "components", "ui");
236
255
  let globalsPath = "";
237
256
  if (hasAppDir) {
238
- if (fs3.existsSync(path3.join(appPath, "globals.css"))) globalsPath = path3.join(appPath, "globals.css");
239
- else if (fs3.existsSync(path3.join(appPath, "global.css"))) globalsPath = path3.join(appPath, "global.css");
240
- else globalsPath = path3.join(appPath, "globals.css");
257
+ if (fs4.existsSync(path4.join(appPath, "globals.css"))) globalsPath = path4.join(appPath, "globals.css");
258
+ else if (fs4.existsSync(path4.join(appPath, "global.css"))) globalsPath = path4.join(appPath, "global.css");
259
+ else globalsPath = path4.join(appPath, "globals.css");
241
260
  } else if (hasPagesDir) {
242
- const stylesPath = path3.join(srcPath, "styles");
243
- if (fs3.existsSync(path3.join(stylesPath, "globals.css"))) globalsPath = path3.join(stylesPath, "globals.css");
244
- else if (fs3.existsSync(path3.join(stylesPath, "global.css"))) globalsPath = path3.join(stylesPath, "global.css");
245
- else globalsPath = path3.join(stylesPath, "globals.css");
261
+ const stylesPath = path4.join(srcPath, "styles");
262
+ if (fs4.existsSync(path4.join(stylesPath, "globals.css"))) globalsPath = path4.join(stylesPath, "globals.css");
263
+ else if (fs4.existsSync(path4.join(stylesPath, "global.css"))) globalsPath = path4.join(stylesPath, "global.css");
264
+ else globalsPath = path4.join(stylesPath, "globals.css");
246
265
  } else {
247
- globalsPath = path3.join(srcPath, "globals.css");
266
+ globalsPath = path4.join(srcPath, "globals.css");
248
267
  }
249
268
  this.config = {
250
269
  cwd,
@@ -292,13 +311,13 @@ var ProjectInitializer = class {
292
311
  const spinner = ora("Creating project structure...").start();
293
312
  const cfg = this.config;
294
313
  try {
295
- await fs3.ensureDir(cfg.libDir);
296
- await fs3.ensureDir(cfg.componentsDir);
297
- const utilsPath = path3.join(cfg.libDir, "utils.ts");
298
- const registryUtilsPath = path3.resolve(__dirname3, "..", "src", "registry", "lib", "utils.ts");
314
+ await fs4.ensureDir(cfg.libDir);
315
+ await fs4.ensureDir(cfg.componentsDir);
316
+ const utilsPath = path4.join(cfg.libDir, "utils.ts");
317
+ const registryUtilsPath = path4.resolve(__dirname3, "..", "src", "registry", "lib", "utils.ts");
299
318
  let utilsContent = "";
300
- if (fs3.existsSync(registryUtilsPath)) {
301
- utilsContent = await fs3.readFile(registryUtilsPath, "utf-8");
319
+ if (fs4.existsSync(registryUtilsPath)) {
320
+ utilsContent = await fs4.readFile(registryUtilsPath, "utf-8");
302
321
  } else {
303
322
  utilsContent = `import { type ClassValue, clsx } from "clsx"
304
323
  import { twMerge } from "tailwind-merge"
@@ -309,15 +328,15 @@ export function cn(...inputs: ClassValue[]) {
309
328
  `;
310
329
  spinner.warn(`Could not find registry/utils.ts, using fallback content.`);
311
330
  }
312
- await fs3.writeFile(utilsPath, utilsContent);
313
- spinner.succeed(`Created ${path3.relative(cfg.cwd, utilsPath)}`);
331
+ await fs4.writeFile(utilsPath, utilsContent);
332
+ spinner.succeed(`Created ${path4.relative(cfg.cwd, utilsPath)}`);
314
333
  spinner.start(`Setting up ${cfg.selectedTheme} theme...`);
315
- const stylesDir = path3.dirname(cfg.globalsPath);
316
- await fs3.ensureDir(stylesDir);
334
+ const stylesDir = path4.dirname(cfg.globalsPath);
335
+ await fs4.ensureDir(stylesDir);
317
336
  try {
318
337
  const cssContent = await this.themeService.getThemeCss(cfg.selectedTheme, cfg.isTailwind4);
319
- await fs3.writeFile(cfg.globalsPath, cssContent);
320
- spinner.succeed(`Updated ${path3.relative(cfg.cwd, cfg.globalsPath)} with ${cfg.selectedTheme} theme (${cfg.isTailwind4 ? "Tailwind 4" : "Tailwind 3"})`);
338
+ await fs4.writeFile(cfg.globalsPath, cssContent);
339
+ spinner.succeed(`Updated ${path4.relative(cfg.cwd, cfg.globalsPath)} with ${cfg.selectedTheme} theme (${cfg.isTailwind4 ? "Tailwind 4" : "Tailwind 3"})`);
321
340
  } catch (error) {
322
341
  spinner.fail(`Failed to load theme: ${cfg.selectedTheme}`);
323
342
  console.error(error);
@@ -325,10 +344,21 @@ export function cn(...inputs: ClassValue[]) {
325
344
  }
326
345
  if (!cfg.isTailwind4) {
327
346
  spinner.start("Setting up Tailwind config...");
328
- const tailwindConfigPath = path3.join(cfg.cwd, "tailwind.config.ts");
329
- await fs3.writeFile(tailwindConfigPath, TAILWIND_CONFIG);
347
+ const tailwindConfigPath = path4.join(cfg.cwd, "tailwind.config.ts");
348
+ await fs4.writeFile(tailwindConfigPath, TAILWIND_CONFIG);
330
349
  spinner.succeed(`Created tailwind.config.ts`);
331
350
  }
351
+ const packageInfo = getPackageInfo();
352
+ const configObj = {
353
+ version: packageInfo.version || "0.0.0",
354
+ theme: cfg.selectedTheme,
355
+ paths: {
356
+ components: path4.relative(cfg.cwd, cfg.componentsDir),
357
+ utils: path4.relative(cfg.cwd, utilsPath)
358
+ }
359
+ };
360
+ await fs4.writeJSON(path4.join(cfg.cwd, "srcroot.config.json"), configObj, { spaces: 2 });
361
+ spinner.succeed("Created srcroot.config.json");
332
362
  } catch (error) {
333
363
  spinner.fail("Failed to initialize project");
334
364
  console.error(error);
@@ -348,8 +378,8 @@ export function cn(...inputs: ClassValue[]) {
348
378
  deps.push("tailwindcss-animate");
349
379
  }
350
380
  try {
351
- const packageJsonPath = path3.join(cfg.cwd, "package.json");
352
- const pkg = await fs3.readJson(packageJsonPath);
381
+ const packageJsonPath = path4.join(cfg.cwd, "package.json");
382
+ const pkg = await fs4.readJson(packageJsonPath);
353
383
  const allDeps = { ...pkg.dependencies, ...pkg.devDependencies };
354
384
  const missingDeps = deps.filter((dep) => !allDeps[dep]);
355
385
  if (missingDeps.length === 0) {
@@ -384,12 +414,12 @@ async function init(options) {
384
414
  }
385
415
 
386
416
  // src/cli/services/component-adder.ts
387
- import fs4 from "fs-extra";
388
- import path4 from "path";
417
+ import fs5 from "fs-extra";
418
+ import path5 from "path";
389
419
  import ora2 from "ora";
390
420
  import prompts2 from "prompts";
391
421
  import { execa as execa2 } from "execa";
392
- import { fileURLToPath as fileURLToPath3 } from "url";
422
+ import { fileURLToPath as fileURLToPath4 } from "url";
393
423
 
394
424
  // src/cli/registry.ts
395
425
  var REGISTRY = {
@@ -696,7 +726,8 @@ var REGISTRY = {
696
726
  file: "ui/file-upload.tsx",
697
727
  description: "Drag-and-drop file upload",
698
728
  category: "Forms",
699
- dependencies: ["button"]
729
+ dependencies: ["button"],
730
+ registryDependencies: ["react-dropzone", "react-icons"]
700
731
  },
701
732
  "hover-card": {
702
733
  file: "ui/hover-card.tsx",
@@ -801,48 +832,63 @@ var REGISTRY = {
801
832
  category: "Navigation",
802
833
  dependencies: []
803
834
  },
835
+ map: {
836
+ file: "ui/map.tsx",
837
+ description: "Interactive map with Leaflet/Google",
838
+ category: "Data Display",
839
+ dependencies: [],
840
+ registryDependencies: ["leaflet", "react-leaflet"]
841
+ },
804
842
  "empty-state": {
805
843
  file: "ui/empty-state.tsx",
806
- description: "Placeholder for empty states",
807
- category: "Feedback",
844
+ description: "Placeholder for empty data",
845
+ category: "Data Display",
808
846
  dependencies: []
809
847
  },
810
848
  "floating-dock": {
811
849
  file: "ui/floating-dock.tsx",
812
- description: "Floating action container",
813
- category: "Layout",
814
- dependencies: []
815
- },
816
- "map": {
817
- file: "ui/map.tsx",
818
- description: "Leaflet/Google map integration",
819
- category: "Data Display",
850
+ description: "Mac-style floating dock",
851
+ category: "Navigation",
820
852
  dependencies: [],
821
- registryDependencies: ["react-leaflet", "leaflet"]
853
+ registryDependencies: ["framer-motion"]
822
854
  },
823
855
  marquee: {
824
856
  file: "ui/marquee.tsx",
825
- description: "Scrolling marquee text",
857
+ description: "Infinite scrolling marquee",
826
858
  category: "Data Display",
827
859
  dependencies: []
828
860
  },
829
861
  "scroll-to-top": {
830
862
  file: "ui/scroll-to-top.tsx",
831
- description: "Scroll to top button",
863
+ description: "Button to scroll to top",
832
864
  category: "Navigation",
833
- dependencies: ["button"]
865
+ dependencies: ["button"],
866
+ registryDependencies: ["framer-motion"]
867
+ },
868
+ "scroll-animation": {
869
+ file: "ui/scroll-animation.tsx",
870
+ description: "Scroll-triggered animations",
871
+ category: "Layout",
872
+ dependencies: [],
873
+ registryDependencies: ["framer-motion"]
834
874
  },
835
875
  whatsapp: {
836
876
  file: "ui/whatsapp.tsx",
837
- description: "WhatsApp floating button",
838
- category: "Feedback",
877
+ description: "WhatsApp chat button",
878
+ category: "Data Display",
839
879
  dependencies: ["button"],
840
880
  registryDependencies: ["react-icons"]
881
+ },
882
+ patterns: {
883
+ file: "ui/patterns.tsx",
884
+ description: "Background patterns",
885
+ category: "Layout",
886
+ dependencies: []
841
887
  }
842
888
  };
843
889
 
844
890
  // src/cli/services/component-adder.ts
845
- var __dirname4 = path4.dirname(fileURLToPath3(import.meta.url));
891
+ var __dirname4 = path5.dirname(fileURLToPath4(import.meta.url));
846
892
  var ComponentAdder = class {
847
893
  cwd;
848
894
  options;
@@ -964,16 +1010,16 @@ Please manually install: ${packages.join(" ")}`);
964
1010
  }
965
1011
  async copyComponents(components) {
966
1012
  const spinner = ora2("Adding components...").start();
967
- const hasSrc = fs4.existsSync(path4.join(this.cwd, "src"));
968
- const srcPath = hasSrc ? path4.join(this.cwd, "src") : this.cwd;
969
- const componentsDir = path4.join(srcPath, "components", "ui");
1013
+ const hasSrc = fs5.existsSync(path5.join(this.cwd, "src"));
1014
+ const srcPath = hasSrc ? path5.join(this.cwd, "src") : this.cwd;
1015
+ const componentsDir = path5.join(srcPath, "components", "ui");
970
1016
  try {
971
- await fs4.ensureDir(componentsDir);
1017
+ await fs5.ensureDir(componentsDir);
972
1018
  for (const name of components) {
973
1019
  const comp = REGISTRY[name];
974
- const fileName = path4.basename(comp.file);
975
- const targetPath = path4.join(componentsDir, fileName);
976
- if (fs4.existsSync(targetPath) && !this.options.overwrite) {
1020
+ const fileName = path5.basename(comp.file);
1021
+ const targetPath = path5.join(componentsDir, fileName);
1022
+ if (fs5.existsSync(targetPath) && !this.options.overwrite) {
977
1023
  spinner.stop();
978
1024
  const { overwrite } = await prompts2({
979
1025
  type: "confirm",
@@ -988,13 +1034,13 @@ Please manually install: ${packages.join(" ")}`);
988
1034
  }
989
1035
  spinner.start("Adding components...");
990
1036
  }
991
- const registryPath = path4.resolve(__dirname4, "..", "src", "registry", comp.file);
992
- if (!fs4.existsSync(registryPath)) {
1037
+ const registryPath = path5.resolve(__dirname4, "..", "src", "registry", comp.file);
1038
+ if (!fs5.existsSync(registryPath)) {
993
1039
  spinner.warn(`Registry file not found for ${name}: ${registryPath}`);
994
1040
  continue;
995
1041
  }
996
- const content = await fs4.readFile(registryPath, "utf-8");
997
- await fs4.writeFile(targetPath, content);
1042
+ const content = await fs5.readFile(registryPath, "utf-8");
1043
+ await fs5.writeFile(targetPath, content);
998
1044
  if (components.length > 10) {
999
1045
  spinner.text = `Adding ${fileName}...`;
1000
1046
  } else {
@@ -1050,25 +1096,6 @@ async function list() {
1050
1096
  console.log(chalk2.dim("Usage: npx @srcroot/ui add <component>\n"));
1051
1097
  }
1052
1098
 
1053
- // src/cli/utils/get-package-info.ts
1054
- import path5 from "path";
1055
- import fs5 from "fs-extra";
1056
- import { fileURLToPath as fileURLToPath4 } from "url";
1057
- function getPackageInfo() {
1058
- const __filename2 = fileURLToPath4(import.meta.url);
1059
- const __dirname5 = path5.dirname(__filename2);
1060
- const pathsToCheck = [
1061
- path5.resolve(__dirname5, "..", "package.json"),
1062
- path5.resolve(__dirname5, "..", "..", "..", "package.json")
1063
- ];
1064
- for (const pkgPath of pathsToCheck) {
1065
- if (fs5.existsSync(pkgPath)) {
1066
- return fs5.readJSONSync(pkgPath);
1067
- }
1068
- }
1069
- return { version: "0.0.0" };
1070
- }
1071
-
1072
1099
  // src/cli/index.ts
1073
1100
  process.on("SIGINT", () => process.exit(0));
1074
1101
  process.on("SIGTERM", () => process.exit(0));