@srcroot/ui 1.0.0 → 1.0.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (3) hide show
  1. package/README.md +131 -100
  2. package/dist/index.js +94 -3
  3. package/package.json +2 -2
package/README.md CHANGED
@@ -1,151 +1,182 @@
1
1
  # @srcroot/ui
2
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.
3
+ A lightweight UI library with polymorphic, accessible React components for Next.js, Vite, and other React frameworks.
5
4
 
6
5
  ## Features
7
6
 
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`.
7
+ - **Framework-Aware**: Automatically detects Next.js or Vite and uses optimized component variants
8
+ - **Polymorphic**: Most components support an `as` prop to change the underlying HTML element
9
+ - **Accessible**: Built on standard HTML elements and WAI-ARIA patterns
10
+ - **Copy/Paste**: Components are copied directly into your project — you own the code
11
+ - **Styled**: Beautiful defaults using Tailwind CSS and `class-variance-authority`
12
+ - **Zero Runtime Dependencies**: No library bundle — just copy what you need
12
13
 
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.
14
+ ## Install
20
15
 
21
16
  ```bash
22
17
  npx @srcroot/ui init
23
18
  ```
24
19
 
25
- This will ask a few questions to configure your project structure (e.g., where to put components).
26
-
27
- ### 2. Add Components
20
+ ## Add Components
28
21
 
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
22
  ```bash
23
+ # Interactive mode
34
24
  npx @srcroot/ui add
35
- ```
36
25
 
37
- **Specific Components:**
38
- Add one or more components by name.
39
- ```bash
26
+ # Specific components
40
27
  npx @srcroot/ui add button card input
41
- ```
42
28
 
43
- **Add All:**
44
- Install every available component at once.
45
- ```bash
29
+ # Add all components
46
30
  npx @srcroot/ui add --all
47
31
  ```
48
32
 
49
- This will copy the component files to your `components/ui` directory and install any necessary peer dependencies (like `react-icons` or `clsx`).
33
+ ## Supported Package Managers
50
34
 
51
- ### 3. Usage
35
+ The CLI automatically detects and uses your package manager:
52
36
 
53
- Import components directly from your project folder:
37
+ | Manager | Command |
38
+ |---------|---------|
39
+ | npm | `npm install` |
40
+ | Yarn | `yarn add` |
41
+ | pnpm | `pnpm add` |
42
+ | Bun | `bun add` |
43
+ | Deno | `deno add -A` |
54
44
 
55
- ```tsx
56
- import { Button } from "@/components/ui/button"
45
+ ## Framework Detection
57
46
 
58
- export default function Home() {
59
- return (
60
- <Button variant="destructive" onClick={() => alert("Clicked!")}>
61
- Click Me
62
- </Button>
63
- )
64
- }
65
- ```
47
+ | Framework | Detection | Notes |
48
+ |-----------|-----------|-------|
49
+ | Next.js | `next.config.ts/js/mjs` or `src/app` | Uses `next/script` for analytics |
50
+ | Vite | `vite.config.ts/js/mjs` | Uses `useEffect` for analytics, localStorage for themes |
66
51
 
67
- ## Available Components
52
+ ## Components
68
53
 
69
- run `npx @srcroot/ui list` to see all available components.
54
+ ### Analytics
55
+ - `google-analytics` - Google Analytics 4 integration
56
+ - `google-tag-manager` - Google Tag Manager container
57
+ - `meta-pixel` - Meta/Facebook Pixel tracking
58
+ - `microsoft-clarity` - Microsoft Clarity analytics
59
+ - `tiktok-pixel` - TikTok Pixel tracking
70
60
 
71
61
  ### 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.
62
+ - `button` - Polymorphic button with variants
63
+ - `badge` - Status indicators
64
+ - `avatar` - User profile images with fallbacks
65
+ - `separator` - Visual divider
66
+ - `button-group` - Attached or spaced button sets
67
+ - `slot` - Polymorphic slot for component composition
77
68
 
78
69
  ### 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.
70
+ - `input` - Basic text input
71
+ - `textarea` - Multi-line text input
72
+ - `checkbox` - Toggle selection
73
+ - `radio` - Single selection from list
74
+ - `switch` - Toggle switch
75
+ - `select` - Dropdown selection
76
+ - `slider` - Range input
77
+ - `otp-input` - One-time password verification
78
+ - `search` - Search input with debounce
79
+ - `calendar` - Date and range picker
80
+ - `date-picker` - Date selection component
81
+ - `form-field` - Form field wrapper with label and validation
82
+ - `input-group` - Input with attached elements
89
83
 
90
84
  ### Layout
91
- - `card` - Content container with header/content/footer.
92
- - `container` - Centered layout wrapper.
93
- - `aspect-ratio` - Maintain element proportions.
85
+ - `card` - Content container with header/content/footer
86
+ - `container` - Centered layout wrapper
87
+ - `aspect-ratio` - Maintain element proportions
88
+ - `resizable` - Resizable panel groups
94
89
 
95
90
  ### 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.
91
+ - `text` - Polymorphic typography
92
+ - `label` - Accessible form label
93
+ - `table` - Responsive data table
94
+ - `table-of-contents` - Auto-generated TOC
95
+ - `accordion` - Collapsible content sections
96
+ - `collapsible` - Expandable panel
97
+ - `tabs` - Tabbed content switcher
98
+ - `progress` - Progress bar
99
+ - `skeleton` - Loading placeholder
100
+ - `image` - Enhanced image with fallback
101
+ - `carousel` - Content slider with autoplay
102
+ - `marquee` - Scrolling marquee animation
106
103
 
107
104
  ### Feedback
108
- - `loading-spinner` - SVG spinner with variants.
109
- - `star-rating` - Interactive rating component.
110
- - `toast` - Transient notifications.
111
- - `alert` - Critical information banner.
105
+ - `loading-spinner` - SVG spinner with variants
106
+ - `star-rating` - Interactive rating component
107
+ - `toast` - Transient notifications
108
+ - `alert` - Critical information banner
109
+ - `scroll-to-top` - Scroll to top button
110
+ - `scroll-animation` - Scroll-triggered animations
112
111
 
113
112
  ### 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.
113
+ - `dialog` - Modal dialog
114
+ - `alert-dialog` - Modal for confirming actions
115
+ - `sheet` - Side-panel overlay
116
+ - `popover` - Content appearing over trigger
117
+ - `tooltip` - Hover information
118
+ - `dropdown-menu` - Menu for actions/navigation
119
+ - `context-menu` - Right-click context menu
120
120
 
121
121
  ### Navigation
122
- - `breadcrumb` - Navigation trail.
123
- - `pagination` - Page navigation controls.
122
+ - `breadcrumb` - Navigation trail
123
+ - `pagination` - Page navigation controls
124
+ - `sidebar` - Collapsible sidebar with navigation
125
+ - `menubar` - Menu bar component
126
+
127
+ ### Specialized
128
+ - `chatbot` - Chat interface widget
129
+ - `chart` - Recharts-based chart component
130
+ - `map` - Google Maps embed
131
+ - `combobox` - Searchable dropdown (Command menu pattern)
132
+ - `command` - Command menu (Cmd+k style)
133
+ - `file-upload` - Drag-and-drop file upload
134
+ - `hover-card` - Hover-triggered card
135
+ - `native-select` - Native select wrapper
136
+ - `patterns` - Decorative background patterns
137
+ - `theme-switcher` - Light/dark/system theme toggle
138
+ - `whatsapp` - WhatsApp floating button
139
+ - `floating-dock` - macOS-style floating dock
140
+
141
+ ## Usage
142
+
143
+ ```tsx
144
+ import { Button } from "@/components/ui/button"
145
+ import { Card, CardHeader, CardContent } from "@/components/ui/card"
146
+
147
+ export default function Home() {
148
+ return (
149
+ <Card>
150
+ <CardHeader>Welcome</CardHeader>
151
+ <CardContent>
152
+ <Button variant="destructive" onClick={() => alert("Clicked!")}>
153
+ Get Started
154
+ </Button>
155
+ </CardContent>
156
+ </Card>
157
+ )
158
+ }
159
+ ```
124
160
 
125
161
  ## Polymorphism
126
162
 
127
- Our components accept an `as` prop to change the underlying HTML element while maintaining styles and behavior.
163
+ Components accept an `as` prop to change the underlying HTML element:
128
164
 
129
165
  ```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
- ```
166
+ <Button as="a" href="/login">Login</Button>
140
167
 
141
- ## Local Development
168
+ <Text as="h1" variant="h1">Page Title</Text>
169
+ ```
142
170
 
143
- To run the documentation/playground locally:
171
+ ## CLI Reference
144
172
 
145
173
  ```bash
146
- cd examples/playground
147
- npm install
148
- npm run dev
174
+ npx @srcroot/ui init Initialize project structure
175
+ npx @srcroot/ui add [comps] Add component(s)
176
+ npx @srcroot/ui add --all Add all components
177
+ npx @srcroot/ui list List available components
149
178
  ```
150
179
 
151
- Visit `http://localhost:3001` to view the component showcase.
180
+ ## License
181
+
182
+ MIT
package/dist/index.js CHANGED
@@ -179,6 +179,7 @@ import fs3 from "fs";
179
179
  import path3 from "path";
180
180
  function getPackageManager(cwd) {
181
181
  const dir = cwd || process.cwd();
182
+ if (fs3.existsSync(path3.join(dir, "deno.json")) || fs3.existsSync(path3.join(dir, "deno.jsonc"))) return "deno";
182
183
  if (fs3.existsSync(path3.join(dir, "bun.lockb"))) return "bun";
183
184
  if (fs3.existsSync(path3.join(dir, "pnpm-lock.yaml"))) return "pnpm";
184
185
  if (fs3.existsSync(path3.join(dir, "yarn.lock"))) return "yarn";
@@ -189,6 +190,8 @@ function getPackageManager(cwd) {
189
190
  if (userAgent.startsWith("pnpm")) return "pnpm";
190
191
  if (userAgent.startsWith("bun")) return "bun";
191
192
  }
193
+ const denoAgent = process.env.DENO_ENV;
194
+ if (denoAgent) return "deno";
192
195
  return "npm";
193
196
  }
194
197
 
@@ -971,7 +974,81 @@ var ComponentAdder = class {
971
974
  content = content.replace(/^"use client"[;\n\r]*/m, "");
972
975
  content = content.replace(/import\s*{\s*useTheme\s*}\s*from\s*"next-themes"\s*;?\n?/g, "");
973
976
  content = content.replace(/import\s*{\s*ThemeProvider\s*}\s*from\s*"next-themes"\s*;?\n?/g, "");
974
- if (name === "theme-switcher") {
977
+ content = content.replace(/import\s*{\s*cn\s*}\s*from\s*"@\/lib\/utils"\s*;?\n?/g, 'import { cn } from "../../lib/utils"\n');
978
+ content = content.replace(/import\s*{\s*Slot\s*}\s*from\s*"@\/components\/ui\/slot"\s*;?\n?/g, 'import { Slot } from "./slot"\n');
979
+ const otherUiImports = [
980
+ "accordion",
981
+ "alert-dialog",
982
+ "alert",
983
+ "aspect-ratio",
984
+ "avatar",
985
+ "badge",
986
+ "breadcrumb",
987
+ "button",
988
+ "button-group",
989
+ "calendar",
990
+ "card",
991
+ "carousel",
992
+ "chart",
993
+ "chatbot",
994
+ "checkbox",
995
+ "collapsible",
996
+ "combobox",
997
+ "command",
998
+ "container",
999
+ "context-menu",
1000
+ "date-picker",
1001
+ "dialog",
1002
+ "drawer",
1003
+ "dropdown-menu",
1004
+ "empty-state",
1005
+ "file-upload",
1006
+ "floating-dock",
1007
+ "form-field",
1008
+ "hover-card",
1009
+ "image",
1010
+ "input",
1011
+ "input-group",
1012
+ "kbd",
1013
+ "label",
1014
+ "loading-spinner",
1015
+ "map",
1016
+ "marquee",
1017
+ "menubar",
1018
+ "native-select",
1019
+ "otp-input",
1020
+ "pagination",
1021
+ "patterns",
1022
+ "popover",
1023
+ "progress",
1024
+ "radio",
1025
+ "resizable",
1026
+ "scroll-animation",
1027
+ "scroll-area",
1028
+ "scroll-to-top",
1029
+ "search",
1030
+ "select",
1031
+ "separator",
1032
+ "sheet",
1033
+ "sidebar",
1034
+ "skeleton",
1035
+ "slider",
1036
+ "star-rating",
1037
+ "switch",
1038
+ "table",
1039
+ "table-of-contents",
1040
+ "tabs",
1041
+ "text",
1042
+ "textarea",
1043
+ "toast",
1044
+ "toggle",
1045
+ "toggle-group",
1046
+ "tooltip",
1047
+ "whatsapp"
1048
+ ];
1049
+ for (const comp of otherUiImports) {
1050
+ const regex = new RegExp(`from\\s+"@/components/ui/${comp}"`, "g");
1051
+ content = content.replace(regex, `from "./${comp}"`);
975
1052
  }
976
1053
  return content.trimStart();
977
1054
  }
@@ -1072,9 +1149,23 @@ var ComponentAdder = class {
1072
1149
  async installPackages(packages) {
1073
1150
  const packageManager = getPackageManager(this.cwd);
1074
1151
  const spinner = ora2("Installing dependencies...").start();
1075
- const installCmd = packageManager === "npm" ? "install" : "add";
1152
+ let installCmd;
1153
+ switch (packageManager) {
1154
+ case "deno":
1155
+ installCmd = ["add", "-A", ...packages];
1156
+ break;
1157
+ case "bun":
1158
+ installCmd = ["add", ...packages];
1159
+ break;
1160
+ case "pnpm":
1161
+ case "yarn":
1162
+ installCmd = ["add", ...packages];
1163
+ break;
1164
+ default:
1165
+ installCmd = ["install", ...packages];
1166
+ }
1076
1167
  try {
1077
- await execa2(packageManager, [installCmd, ...packages], {
1168
+ await execa2(packageManager, installCmd, {
1078
1169
  cwd: this.cwd
1079
1170
  });
1080
1171
  spinner.succeed("Dependencies installed");
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@srcroot/ui",
3
- "version": "1.0.0",
3
+ "version": "1.0.2",
4
4
  "description": "A UI library with polymorphic, accessible React components",
5
5
  "author": "Shifaul Islam",
6
6
  "license": "MIT",
@@ -71,4 +71,4 @@
71
71
  "optional": true
72
72
  }
73
73
  }
74
- }
74
+ }