@srcroot/ui 1.0.0 → 1.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +117 -92
- package/dist/index.js +94 -3
- package/package.json +2 -2
package/README.md
CHANGED
|
@@ -1,146 +1,171 @@
|
|
|
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 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 your framework (Next.js, Vite, etc.) and uses the right component variants
|
|
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**: Components are copied directly into your project — you own the code
|
|
11
|
+
- **Styled**: Beautiful defaults using Tailwind CSS and `class-variance-authority`
|
|
12
|
+
- **Multi-Platform**: Supports npm, Yarn, pnpm, Bun, and Deno
|
|
12
13
|
|
|
13
|
-
##
|
|
14
|
-
|
|
15
|
-
This library is distributed via a CLI that initializes your project and adds components directly to your source code.
|
|
14
|
+
## Quick Start
|
|
16
15
|
|
|
17
16
|
### 1. Initialize
|
|
18
17
|
|
|
19
|
-
Run the `init` command to set up the necessary dependencies and structural files (like `cn` utility) in your project.
|
|
20
|
-
|
|
21
18
|
```bash
|
|
22
19
|
npx @srcroot/ui init
|
|
23
20
|
```
|
|
24
21
|
|
|
25
|
-
This
|
|
22
|
+
This sets up your project with the `cn` utility, theme configuration, and creates the necessary structure.
|
|
26
23
|
|
|
27
24
|
### 2. Add Components
|
|
28
25
|
|
|
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
26
|
```bash
|
|
27
|
+
# Interactive mode
|
|
34
28
|
npx @srcroot/ui add
|
|
35
|
-
```
|
|
36
29
|
|
|
37
|
-
|
|
38
|
-
Add one or more components by name.
|
|
39
|
-
```bash
|
|
30
|
+
# Specific components
|
|
40
31
|
npx @srcroot/ui add button card input
|
|
41
|
-
```
|
|
42
32
|
|
|
43
|
-
|
|
44
|
-
Install every available component at once.
|
|
45
|
-
```bash
|
|
33
|
+
# Add all components
|
|
46
34
|
npx @srcroot/ui add --all
|
|
47
35
|
```
|
|
48
36
|
|
|
49
|
-
|
|
37
|
+
Components are installed to `src/components/ui/` (or `components/ui/` depending on your structure).
|
|
50
38
|
|
|
51
|
-
|
|
39
|
+
## Supported Package Managers
|
|
52
40
|
|
|
53
|
-
|
|
41
|
+
The CLI automatically detects and uses your package manager:
|
|
54
42
|
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
43
|
+
- **npm** - `npm install`
|
|
44
|
+
- **Yarn** - `yarn add`
|
|
45
|
+
- **pnpm** - `pnpm add`
|
|
46
|
+
- **Bun** - `bun add`
|
|
47
|
+
- **Deno** - `deno add -A`
|
|
48
|
+
|
|
49
|
+
## Framework Detection
|
|
50
|
+
|
|
51
|
+
The CLI automatically detects your framework:
|
|
52
|
+
|
|
53
|
+
| Framework | Detection | Notes |
|
|
54
|
+
|-----------|-----------|-------|
|
|
55
|
+
| Next.js | `next.config.ts/js/mjs` or `src/app` directory | Uses `next/script` for analytics |
|
|
56
|
+
| Vite | `vite.config.ts/js/mjs` | Uses `useEffect` for analytics, localStorage for themes |
|
|
66
57
|
|
|
67
58
|
## Available Components
|
|
68
59
|
|
|
69
|
-
|
|
60
|
+
Run `npx @srcroot/ui list` to see all available components.
|
|
61
|
+
|
|
62
|
+
### Analytics
|
|
63
|
+
- `google-analytics` - Google Analytics 4 integration
|
|
64
|
+
- `google-tag-manager` - Google Tag Manager container
|
|
65
|
+
- `meta-pixel` - Meta/Facebook Pixel tracking
|
|
66
|
+
- `microsoft-clarity` - Microsoft Clarity analytics
|
|
67
|
+
- `tiktok-pixel` - TikTok Pixel tracking
|
|
70
68
|
|
|
71
69
|
### 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
|
|
70
|
+
- `button` - Polymorphic button with variants
|
|
71
|
+
- `badge` - Status indicators
|
|
72
|
+
- `avatar` - User profile images with fallbacks
|
|
73
|
+
- `separator` - Visual divider
|
|
74
|
+
- `button-group` - Attached or spaced button sets
|
|
75
|
+
- `slot` - Polymorphic slot for component composition
|
|
77
76
|
|
|
78
77
|
### 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
|
|
78
|
+
- `input` - Basic text input
|
|
79
|
+
- `textarea` - Multi-line text input
|
|
80
|
+
- `checkbox` - Toggle selection
|
|
81
|
+
- `radio` - Single selection from list
|
|
82
|
+
- `switch` - Toggle switch
|
|
83
|
+
- `select` - Dropdown selection
|
|
84
|
+
- `slider` - Range input
|
|
85
|
+
- `otp-input` - One-time password verification
|
|
86
|
+
- `search` - Search input with debounce
|
|
87
|
+
- `calendar` - Date and range picker
|
|
88
|
+
- `date-picker` - Date selection component
|
|
89
|
+
- `form-field` - Form field wrapper with label and validation
|
|
90
|
+
- `input-group` - Input with attached elements
|
|
89
91
|
|
|
90
92
|
### Layout
|
|
91
|
-
- `card` - Content container with header/content/footer
|
|
92
|
-
- `container` - Centered layout wrapper
|
|
93
|
-
- `aspect-ratio` - Maintain element proportions
|
|
93
|
+
- `card` - Content container with header/content/footer
|
|
94
|
+
- `container` - Centered layout wrapper
|
|
95
|
+
- `aspect-ratio` - Maintain element proportions
|
|
96
|
+
- `resizable` - Resizable panel groups
|
|
94
97
|
|
|
95
98
|
### Data Display
|
|
96
|
-
- `text` - Polymorphic typography
|
|
97
|
-
- `label` - Accessible form label
|
|
98
|
-
- `table` - Responsive data table
|
|
99
|
-
- `
|
|
100
|
-
- `
|
|
101
|
-
- `
|
|
102
|
-
- `
|
|
103
|
-
- `
|
|
104
|
-
- `
|
|
105
|
-
- `
|
|
99
|
+
- `text` - Polymorphic typography
|
|
100
|
+
- `label` - Accessible form label
|
|
101
|
+
- `table` - Responsive data table
|
|
102
|
+
- `table-of-contents` - Auto-generated TOC
|
|
103
|
+
- `accordion` - Collapsible content sections
|
|
104
|
+
- `collapsible` - Expandable panel
|
|
105
|
+
- `tabs` - Tabbed content switcher
|
|
106
|
+
- `progress` - Progress bar
|
|
107
|
+
- `skeleton` - Loading placeholder
|
|
108
|
+
- `image` - Enhanced image with fallback
|
|
109
|
+
- `carousel` - Content slider with autoplay
|
|
110
|
+
- `marquee` - Scrolling marquee animation
|
|
106
111
|
|
|
107
112
|
### Feedback
|
|
108
|
-
- `loading-spinner` - SVG spinner with variants
|
|
109
|
-
- `star-rating` - Interactive rating component
|
|
110
|
-
- `toast` - Transient notifications
|
|
111
|
-
- `alert` - Critical information banner
|
|
113
|
+
- `loading-spinner` - SVG spinner with variants
|
|
114
|
+
- `star-rating` - Interactive rating component
|
|
115
|
+
- `toast` - Transient notifications
|
|
116
|
+
- `alert` - Critical information banner
|
|
117
|
+
- `scroll-to-top` - Scroll to top button
|
|
118
|
+
- `scroll-animation` - Scroll-triggered animations
|
|
112
119
|
|
|
113
120
|
### 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
|
|
121
|
+
- `dialog` - Modal dialog
|
|
122
|
+
- `alert-dialog` - Modal for confirming actions
|
|
123
|
+
- `sheet` - Side-panel overlay
|
|
124
|
+
- `popover` - Content appearing over trigger
|
|
125
|
+
- `tooltip` - Hover information
|
|
126
|
+
- `dropdown-menu` - Menu for actions/navigation
|
|
127
|
+
- `context-menu` - Right-click context menu
|
|
120
128
|
|
|
121
129
|
### Navigation
|
|
122
|
-
- `breadcrumb` - Navigation trail
|
|
123
|
-
- `pagination` - Page navigation controls
|
|
130
|
+
- `breadcrumb` - Navigation trail
|
|
131
|
+
- `pagination` - Page navigation controls
|
|
132
|
+
- `sidebar` - Collapsible sidebar with navigation
|
|
133
|
+
- `menubar` - Menu bar component
|
|
134
|
+
|
|
135
|
+
### Specialized
|
|
136
|
+
- `chatbot` - Chat interface widget
|
|
137
|
+
- `chart` - Recharts-based chart component
|
|
138
|
+
- `map` - Google Maps embed
|
|
139
|
+
- `combobox` - Searchable dropdown (Command menu pattern)
|
|
140
|
+
- `command` - Command menu (Cmdk-style)
|
|
141
|
+
- `file-upload` - Drag-and-drop file upload
|
|
142
|
+
- `hover-card` - Hover-triggered card
|
|
143
|
+
- `native-select` - Native select wrapper
|
|
144
|
+
- `patterns` - Decorative background patterns
|
|
145
|
+
- `theme-switcher` - Light/dark/system theme toggle
|
|
146
|
+
- `whatsapp` - WhatsApp floating button
|
|
147
|
+
- `floating-dock` - macOS-style floating dock
|
|
124
148
|
|
|
125
149
|
## Polymorphism
|
|
126
150
|
|
|
127
|
-
|
|
151
|
+
Components accept an `as` prop to change the underlying HTML element:
|
|
128
152
|
|
|
129
153
|
```tsx
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
</Button>
|
|
134
|
-
|
|
135
|
-
// Renders as a specialized text variant
|
|
136
|
-
<Text as="h1" variant="h1">
|
|
137
|
-
Page Title
|
|
138
|
-
</Text>
|
|
154
|
+
<Button as="a" href="/login">Login</Button>
|
|
155
|
+
|
|
156
|
+
<Text as="h1" variant="h1">Page Title</Text>
|
|
139
157
|
```
|
|
140
158
|
|
|
141
|
-
##
|
|
159
|
+
## CLI Options
|
|
142
160
|
|
|
143
|
-
|
|
161
|
+
```
|
|
162
|
+
npx @srcroot/ui init Initialize project structure
|
|
163
|
+
npx @srcroot/ui add [comps] Add component(s)
|
|
164
|
+
npx @srcroot/ui add --all Add all components
|
|
165
|
+
npx @srcroot/ui list List available components
|
|
166
|
+
```
|
|
167
|
+
|
|
168
|
+
## Local Development
|
|
144
169
|
|
|
145
170
|
```bash
|
|
146
171
|
cd examples/playground
|
|
@@ -148,4 +173,4 @@ npm install
|
|
|
148
173
|
npm run dev
|
|
149
174
|
```
|
|
150
175
|
|
|
151
|
-
Visit `http://localhost:3001` to view the component showcase.
|
|
176
|
+
Visit `http://localhost:3001` to view the component showcase.
|
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.1",
|
|
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
|
+
}
|