@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.
- package/README.md +131 -100
- package/dist/index.js +94 -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
|
-
- **
|
|
9
|
-
- **
|
|
10
|
-
- **
|
|
11
|
-
- **
|
|
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
|
-
##
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
33
|
+
## Supported Package Managers
|
|
50
34
|
|
|
51
|
-
|
|
35
|
+
The CLI automatically detects and uses your package manager:
|
|
52
36
|
|
|
53
|
-
|
|
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
|
-
|
|
56
|
-
import { Button } from "@/components/ui/button"
|
|
45
|
+
## Framework Detection
|
|
57
46
|
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
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
|
-
##
|
|
52
|
+
## Components
|
|
68
53
|
|
|
69
|
-
|
|
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
|
|
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
|
|
97
|
-
- `label` - Accessible form label
|
|
98
|
-
- `table` - Responsive data table
|
|
99
|
-
- `
|
|
100
|
-
- `
|
|
101
|
-
- `
|
|
102
|
-
- `
|
|
103
|
-
- `
|
|
104
|
-
- `
|
|
105
|
-
- `
|
|
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
|
-
|
|
163
|
+
Components accept an `as` prop to change the underlying HTML element:
|
|
128
164
|
|
|
129
165
|
```tsx
|
|
130
|
-
|
|
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
|
-
|
|
168
|
+
<Text as="h1" variant="h1">Page Title</Text>
|
|
169
|
+
```
|
|
142
170
|
|
|
143
|
-
|
|
171
|
+
## CLI Reference
|
|
144
172
|
|
|
145
173
|
```bash
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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,
|
|
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.
|
|
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
|
+
}
|