praxys-ui 1.3.1 → 1.3.4
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 +216 -0
- package/dist/index.js +202 -78
- package/package.json +2 -2
- package/CHANGELOG.md +0 -319
package/README.md
ADDED
|
@@ -0,0 +1,216 @@
|
|
|
1
|
+
<div align="center">
|
|
2
|
+
|
|
3
|
+
# praxys-ui
|
|
4
|
+
|
|
5
|
+
**CLI for scaffolding [Praxys UI](https://ui.praxys.xyz) components into your React project.**
|
|
6
|
+
|
|
7
|
+
[](https://www.npmjs.com/package/praxys-ui)
|
|
8
|
+
[](https://www.npmjs.com/package/praxys-ui)
|
|
9
|
+
[](LICENSE)
|
|
10
|
+
|
|
11
|
+
</div>
|
|
12
|
+
|
|
13
|
+
---
|
|
14
|
+
|
|
15
|
+
## Install
|
|
16
|
+
|
|
17
|
+
No global install needed — use `npx`:
|
|
18
|
+
|
|
19
|
+
```bash
|
|
20
|
+
npx praxys-ui init
|
|
21
|
+
```
|
|
22
|
+
|
|
23
|
+
Or install globally:
|
|
24
|
+
|
|
25
|
+
```bash
|
|
26
|
+
npm i -g praxys-ui
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
## Setup
|
|
30
|
+
|
|
31
|
+
```bash
|
|
32
|
+
npx praxys-ui init
|
|
33
|
+
```
|
|
34
|
+
|
|
35
|
+
This will:
|
|
36
|
+
|
|
37
|
+
1. Detect your package manager (npm, pnpm, yarn, bun)
|
|
38
|
+
2. Install core dependencies (`clsx`, `tailwind-merge`, `framer-motion`)
|
|
39
|
+
3. Create `lib/utils.ts` with the `cn()` helper
|
|
40
|
+
4. Write `praxys.config.json` for directory defaults
|
|
41
|
+
|
|
42
|
+
## Adding Components
|
|
43
|
+
|
|
44
|
+
```bash
|
|
45
|
+
# Interactive picker — browse and select from categories
|
|
46
|
+
npx praxys-ui add
|
|
47
|
+
|
|
48
|
+
# Add by name
|
|
49
|
+
npx praxys-ui add animated-button
|
|
50
|
+
|
|
51
|
+
# Add multiple at once
|
|
52
|
+
npx praxys-ui add accordion alert badge tooltip
|
|
53
|
+
|
|
54
|
+
# Add all 100 components
|
|
55
|
+
npx praxys-ui add all
|
|
56
|
+
|
|
57
|
+
# Add and install dependencies
|
|
58
|
+
npx praxys-ui add floating-menu --install-deps
|
|
59
|
+
```
|
|
60
|
+
|
|
61
|
+
## Browsing Components
|
|
62
|
+
|
|
63
|
+
```bash
|
|
64
|
+
# List all components (grouped by category)
|
|
65
|
+
npx praxys-ui list
|
|
66
|
+
|
|
67
|
+
# Filter by category
|
|
68
|
+
npx praxys-ui list --category buttons
|
|
69
|
+
|
|
70
|
+
# Show only new components
|
|
71
|
+
npx praxys-ui list --new
|
|
72
|
+
|
|
73
|
+
# Search by name or description
|
|
74
|
+
npx praxys-ui list --search modal
|
|
75
|
+
|
|
76
|
+
# Show only installed components
|
|
77
|
+
npx praxys-ui list --installed
|
|
78
|
+
|
|
79
|
+
# Component details
|
|
80
|
+
npx praxys-ui info animated-button
|
|
81
|
+
```
|
|
82
|
+
|
|
83
|
+
**Output:**
|
|
84
|
+
|
|
85
|
+
```
|
|
86
|
+
Animated Button
|
|
87
|
+
Category: buttons
|
|
88
|
+
Dependencies: framer-motion, clsx, tailwind-merge
|
|
89
|
+
A button with a shiny border sweep and text reveal effect.
|
|
90
|
+
Docs: https://praxysui.vercel.app/components/animated-button
|
|
91
|
+
```
|
|
92
|
+
|
|
93
|
+
## Inspecting & Comparing
|
|
94
|
+
|
|
95
|
+
```bash
|
|
96
|
+
# View source with syntax highlighting
|
|
97
|
+
npx praxys-ui view switch
|
|
98
|
+
|
|
99
|
+
# Compare local file with latest version
|
|
100
|
+
npx praxys-ui diff accordion
|
|
101
|
+
```
|
|
102
|
+
|
|
103
|
+
## Managing Components
|
|
104
|
+
|
|
105
|
+
```bash
|
|
106
|
+
# Remove a component
|
|
107
|
+
npx praxys-ui remove alert
|
|
108
|
+
npx praxys-ui rm alert --yes # skip confirmation
|
|
109
|
+
|
|
110
|
+
# Update all installed components
|
|
111
|
+
npx praxys-ui update
|
|
112
|
+
|
|
113
|
+
# Update a specific component
|
|
114
|
+
npx praxys-ui update accordion
|
|
115
|
+
|
|
116
|
+
# Check for updates without writing
|
|
117
|
+
npx praxys-ui update --check
|
|
118
|
+
```
|
|
119
|
+
|
|
120
|
+
## Diagnostics
|
|
121
|
+
|
|
122
|
+
```bash
|
|
123
|
+
# Check project setup
|
|
124
|
+
npx praxys-ui doctor
|
|
125
|
+
```
|
|
126
|
+
|
|
127
|
+
```
|
|
128
|
+
✓ praxys.config.json found
|
|
129
|
+
✓ Components directory exists (components/ui)
|
|
130
|
+
✓ Utils file exists (lib/utils.ts)
|
|
131
|
+
✓ Package manager: pnpm
|
|
132
|
+
✓ clsx installed (^2.1.1)
|
|
133
|
+
✓ tailwind-merge installed (^2.6.0)
|
|
134
|
+
✓ framer-motion installed (^12.0.0)
|
|
135
|
+
✓ 12/100 components installed
|
|
136
|
+
|
|
137
|
+
All checks passed!
|
|
138
|
+
```
|
|
139
|
+
|
|
140
|
+
```bash
|
|
141
|
+
# Installed vs available breakdown
|
|
142
|
+
npx praxys-ui stats
|
|
143
|
+
```
|
|
144
|
+
|
|
145
|
+
```
|
|
146
|
+
Category Installed Available
|
|
147
|
+
────────────────────────────────────────
|
|
148
|
+
buttons 5/17 █████░░░░░░░░░░░░
|
|
149
|
+
cards 3/10 ███░░░░░░░
|
|
150
|
+
text 2/8 ██░░░░░░
|
|
151
|
+
navigation 2/18 ██░░░░░░░░░░░░░░░░
|
|
152
|
+
visual 0/12 ░░░░░░░░░░░░
|
|
153
|
+
media 0/6 ░░░░░░
|
|
154
|
+
────────────────────────────────────────
|
|
155
|
+
Total 12/100
|
|
156
|
+
|
|
157
|
+
Coverage: 17% of components installed
|
|
158
|
+
```
|
|
159
|
+
|
|
160
|
+
## Commands Reference
|
|
161
|
+
|
|
162
|
+
| Command | Alias | Description |
|
|
163
|
+
|---------|-------|-------------|
|
|
164
|
+
| `init` | `i` | Initialize project — deps, utils, config |
|
|
165
|
+
| `add [components...]` | | Add components (interactive picker if no args) |
|
|
166
|
+
| `list` | `ls` | List components with filters |
|
|
167
|
+
| `info <component>` | | Show component metadata |
|
|
168
|
+
| `view <component>` | | View source with syntax highlighting |
|
|
169
|
+
| `diff <component>` | | Compare local vs remote |
|
|
170
|
+
| `remove <component>` | `rm` | Remove a component file |
|
|
171
|
+
| `update [component]` | | Update installed components |
|
|
172
|
+
| `doctor` | | Check project health |
|
|
173
|
+
| `stats` | | Installed vs available dashboard |
|
|
174
|
+
|
|
175
|
+
### Global Options
|
|
176
|
+
|
|
177
|
+
| Flag | Commands | Description |
|
|
178
|
+
|------|----------|-------------|
|
|
179
|
+
| `-d, --dir <path>` | add, list, diff, remove, update, stats | Override component directory |
|
|
180
|
+
| `-y, --yes` | add, remove | Skip confirmation prompts |
|
|
181
|
+
| `--install-deps` | add | Install component dependencies |
|
|
182
|
+
| `-c, --category <cat>` | list | Filter by category |
|
|
183
|
+
| `-n, --new` | list | Show only new components |
|
|
184
|
+
| `-s, --search <query>` | list | Search by name/description |
|
|
185
|
+
| `--installed` | list | Show only installed components |
|
|
186
|
+
| `--check` | update | Dry-run — report changes only |
|
|
187
|
+
|
|
188
|
+
## Config File
|
|
189
|
+
|
|
190
|
+
After `init`, a `praxys.config.json` is created:
|
|
191
|
+
|
|
192
|
+
```json
|
|
193
|
+
{
|
|
194
|
+
"componentsDir": "components/ui",
|
|
195
|
+
"utilsDir": "lib"
|
|
196
|
+
}
|
|
197
|
+
```
|
|
198
|
+
|
|
199
|
+
All commands read this file for directory defaults. You can override per-command with `--dir`.
|
|
200
|
+
|
|
201
|
+
## Components
|
|
202
|
+
|
|
203
|
+
100 components across 6 categories:
|
|
204
|
+
|
|
205
|
+
- **Buttons** (17) — Animated Button, Checkbox, Color Picker, Date Picker, File Upload, OTP Input, Rating, Slider, Switch, and more
|
|
206
|
+
- **Cards** (10) — Data Table, Glow Border Card, Spotlight Card, Stats Card, Timeline, and more
|
|
207
|
+
- **Text** (8) — Flip Text, Morphing Text, Typewriter Text, 3D Displacement Text, and more
|
|
208
|
+
- **Navigation** (18) — Accordion, Command Menu, Glass Dock, Combobox, Autocomplete, Floating Menu, and more
|
|
209
|
+
- **Visual** (12) — Liquid Ocean, Gradient Mesh, Parallax Scroll, Toast Notification, and more
|
|
210
|
+
- **Media** (6) — Animated Hero, Interactive Book, Image Comparison, and more
|
|
211
|
+
|
|
212
|
+
Browse all components at [ui.praxys.xyz/docs/components-overview](https://ui.praxys.xyz/docs/components-overview).
|
|
213
|
+
|
|
214
|
+
## License
|
|
215
|
+
|
|
216
|
+
MIT
|
package/dist/index.js
CHANGED
|
@@ -6,7 +6,7 @@ import prompts from "prompts";
|
|
|
6
6
|
import { existsSync, mkdirSync, writeFileSync, readFileSync, unlinkSync } from "fs";
|
|
7
7
|
import { join } from "path";
|
|
8
8
|
import { execSync } from "child_process";
|
|
9
|
-
const VERSION = "1.3.
|
|
9
|
+
const VERSION = "1.3.4";
|
|
10
10
|
// ─── Utility file contents ──────────────────────────────
|
|
11
11
|
const UTILS_CONTENT = `import { clsx, type ClassValue } from "clsx";
|
|
12
12
|
import { twMerge } from "tailwind-merge";
|
|
@@ -89,6 +89,35 @@ const COMPONENT_REGISTRY = {
|
|
|
89
89
|
"toast-notification": { title: "Toast Notification", description: "Stackable animated toast notifications with variants (success, error, warning, info), auto-dismiss, and manual dismiss.", category: "visual", dependencies: ["framer-motion", "clsx", "tailwind-merge"] },
|
|
90
90
|
"tooltip": { title: "Tooltip", description: "A tooltip with 4 positions, configurable delay, direction-aware motion animation, and arrow pointer.", category: "navigation", dependencies: ["framer-motion", "clsx", "tailwind-merge"] },
|
|
91
91
|
"typewriter-text": { title: "Typewriter Text", description: "An animated typing effect that cycles through strings, typing and deleting characters with a blinking cursor.", category: "text", dependencies: ["framer-motion", "clsx", "tailwind-merge"] },
|
|
92
|
+
"toggle-group": { title: "Toggle Group", description: "Segmented control with layoutId spring animation on the selection indicator, three sizes.", category: "buttons", dependencies: ["framer-motion", "clsx", "tailwind-merge"], isNew: true },
|
|
93
|
+
"number-input": { title: "Number Input", description: "Numeric stepper with animated increment/decrement buttons, min/max/step support, three sizes.", category: "buttons", dependencies: ["framer-motion", "clsx", "tailwind-merge"], isNew: true },
|
|
94
|
+
"search-input": { title: "Search Input", description: "Search bar with animated search icon, spinning loading indicator, and AnimatePresence clear button.", category: "buttons", dependencies: ["framer-motion", "clsx", "tailwind-merge"], isNew: true },
|
|
95
|
+
"password-input": { title: "Password Input", description: "Password input with animated show/hide toggle using SVG eye icons and AnimatePresence transitions.", category: "buttons", dependencies: ["framer-motion", "clsx", "tailwind-merge"], isNew: true },
|
|
96
|
+
"range-slider": { title: "Range Slider", description: "Dual-thumb range slider with framer-motion drag interaction, step snapping, and hover/tap animations.", category: "buttons", dependencies: ["framer-motion", "clsx", "tailwind-merge"], isNew: true },
|
|
97
|
+
"copy-button": { title: "Copy Button", description: "Click-to-copy button with animated transition between copy icon and checkmark feedback.", category: "buttons", dependencies: ["framer-motion", "clsx", "tailwind-merge"], isNew: true },
|
|
98
|
+
"mention-input": { title: "Mention Input", description: "Text input with @ mention detection, animated dropdown user list, and keyboard navigation.", category: "buttons", dependencies: ["framer-motion", "clsx", "tailwind-merge"], isNew: true },
|
|
99
|
+
"pricing-card": { title: "Pricing Card", description: "Animated pricing card with feature list, CTA button, popular badge, and hover scale effect.", category: "cards", dependencies: ["framer-motion", "clsx", "tailwind-merge"], isNew: true },
|
|
100
|
+
"profile-card": { title: "Profile Card", description: "Profile card with avatar, online indicator, social links, and staggered entrance animation.", category: "cards", dependencies: ["framer-motion", "clsx", "tailwind-merge"], isNew: true },
|
|
101
|
+
"feature-card": { title: "Feature Card", description: "Feature card with icon, title, description, and 3D tilt effect that follows the cursor.", category: "cards", dependencies: ["framer-motion", "clsx", "tailwind-merge"], isNew: true },
|
|
102
|
+
"comparison-table": { title: "Comparison Table", description: "Side-by-side comparison table with plan columns, check/cross icons, and staggered row animations.", category: "cards", dependencies: ["framer-motion", "clsx", "tailwind-merge"], isNew: true },
|
|
103
|
+
"stat-bar": { title: "Stat Bar", description: "Horizontal progress bar with label, percentage, and scroll-triggered spring fill animation.", category: "cards", dependencies: ["framer-motion", "clsx", "tailwind-merge"], isNew: true },
|
|
104
|
+
"gradient-text": { title: "Gradient Text", description: "Animated gradient text using background-clip with configurable colors and speed.", category: "text", dependencies: ["framer-motion", "clsx", "tailwind-merge"], isNew: true },
|
|
105
|
+
"scramble-text": { title: "Scramble Text", description: "Text decode effect that reveals characters one by one with random character scrambling.", category: "text", dependencies: ["framer-motion", "clsx", "tailwind-merge"], isNew: true },
|
|
106
|
+
"text-reveal": { title: "Text Reveal", description: "Splits text into words and animates each from below with staggered scroll-triggered entrance.", category: "text", dependencies: ["framer-motion", "clsx", "tailwind-merge"], isNew: true },
|
|
107
|
+
"glitch-text": { title: "Glitch Text", description: "RGB split glitch effect with clip-path slicing animation and configurable intensity levels.", category: "text", dependencies: ["framer-motion", "clsx", "tailwind-merge"], isNew: true },
|
|
108
|
+
"sidebar": { title: "Sidebar", description: "Collapsible sidebar navigation with animated width transition, staggered items, and expandable sub-items.", category: "navigation", dependencies: ["framer-motion", "clsx", "tailwind-merge"], isNew: true },
|
|
109
|
+
"bottom-sheet": { title: "Bottom Sheet", description: "Mobile bottom sheet drawer with drag-to-dismiss, snap points, spring animation, and backdrop blur.", category: "navigation", dependencies: ["framer-motion", "clsx", "tailwind-merge"], isNew: true },
|
|
110
|
+
"popover": { title: "Popover", description: "Floating popover with 4 sides, 3 alignments, arrow indicator, click-outside close, and directional animation.", category: "navigation", dependencies: ["framer-motion", "clsx", "tailwind-merge"], isNew: true },
|
|
111
|
+
"context-menu": { title: "Context Menu", description: "Right-click context menu with keyboard navigation, divider support, disabled items, and ARIA roles.", category: "navigation", dependencies: ["framer-motion", "clsx", "tailwind-merge"], isNew: true },
|
|
112
|
+
"mega-menu": { title: "Mega Menu", description: "Large dropdown navigation with hover trigger, multi-column grid sections, and delayed close.", category: "navigation", dependencies: ["framer-motion", "clsx", "tailwind-merge"], isNew: true },
|
|
113
|
+
"confetti": { title: "Confetti", description: "Celebration burst effect with randomized particles, colors, rotation, and physics-based falling animation.", category: "visual", dependencies: ["framer-motion", "clsx", "tailwind-merge"], isNew: true },
|
|
114
|
+
"particles": { title: "Particles", description: "Floating particle background with randomized drift paths, looping animations, and configurable density.", category: "visual", dependencies: ["framer-motion", "clsx", "tailwind-merge"], isNew: true },
|
|
115
|
+
"noise-texture": { title: "Noise Texture", description: "Animated grain overlay using SVG feTurbulence filter for a film-grain effect.", category: "visual", dependencies: ["clsx", "tailwind-merge"], isNew: true },
|
|
116
|
+
"aurora": { title: "Aurora", description: "Aurora borealis gradient background with blurred animated blobs in smooth keyframe paths.", category: "visual", dependencies: ["framer-motion", "clsx", "tailwind-merge"], isNew: true },
|
|
117
|
+
"blur-fade": { title: "Blur Fade", description: "Blur + fade entrance wrapper with configurable direction, delay, and duration.", category: "visual", dependencies: ["framer-motion", "clsx", "tailwind-merge"], isNew: true },
|
|
118
|
+
"carousel": { title: "Carousel", description: "Image carousel with directional slide animation, auto-play, arrow and dot navigation.", category: "media", dependencies: ["framer-motion", "clsx", "tailwind-merge"], isNew: true },
|
|
119
|
+
"avatar": { title: "Avatar", description: "Avatar component with four sizes, status indicators, fallback initials, and animated status dot.", category: "media", dependencies: ["framer-motion", "clsx", "tailwind-merge"], isNew: true },
|
|
120
|
+
"lightbox": { title: "Lightbox", description: "Fullscreen image viewer with zoom, arrow key navigation, thumbnail strip, and backdrop blur.", category: "media", dependencies: ["framer-motion", "clsx", "tailwind-merge"], isNew: true },
|
|
92
121
|
};
|
|
93
122
|
const COMPONENT_LIST = Object.keys(COMPONENT_REGISTRY);
|
|
94
123
|
const CATEGORY_COLORS = {
|
|
@@ -163,7 +192,6 @@ function getComponentsDir(optDir) {
|
|
|
163
192
|
function fuzzyMatch(query, text) {
|
|
164
193
|
const lower = text.toLowerCase();
|
|
165
194
|
const q = query.toLowerCase();
|
|
166
|
-
// simple substring match on slug, title, or description
|
|
167
195
|
return lower.includes(q);
|
|
168
196
|
}
|
|
169
197
|
function truncate(str, max) {
|
|
@@ -171,6 +199,65 @@ function truncate(str, max) {
|
|
|
171
199
|
return str;
|
|
172
200
|
return str.slice(0, max - 1) + "…";
|
|
173
201
|
}
|
|
202
|
+
function levenshtein(a, b) {
|
|
203
|
+
const m = a.length, n = b.length;
|
|
204
|
+
const dp = Array.from({ length: m + 1 }, () => Array(n + 1).fill(0));
|
|
205
|
+
for (let i = 0; i <= m; i++)
|
|
206
|
+
dp[i][0] = i;
|
|
207
|
+
for (let j = 0; j <= n; j++)
|
|
208
|
+
dp[0][j] = j;
|
|
209
|
+
for (let i = 1; i <= m; i++) {
|
|
210
|
+
for (let j = 1; j <= n; j++) {
|
|
211
|
+
dp[i][j] = a[i - 1] === b[j - 1]
|
|
212
|
+
? dp[i - 1][j - 1]
|
|
213
|
+
: 1 + Math.min(dp[i - 1][j], dp[i][j - 1], dp[i - 1][j - 1]);
|
|
214
|
+
}
|
|
215
|
+
}
|
|
216
|
+
return dp[m][n];
|
|
217
|
+
}
|
|
218
|
+
function didYouMean(input) {
|
|
219
|
+
let best = "";
|
|
220
|
+
let bestDist = Infinity;
|
|
221
|
+
for (const slug of COMPONENT_LIST) {
|
|
222
|
+
const dist = levenshtein(input.toLowerCase(), slug.toLowerCase());
|
|
223
|
+
if (dist < bestDist) {
|
|
224
|
+
bestDist = dist;
|
|
225
|
+
best = slug;
|
|
226
|
+
}
|
|
227
|
+
}
|
|
228
|
+
// Only suggest if distance is reasonable (less than ~40% of input length)
|
|
229
|
+
if (bestDist <= Math.max(2, Math.floor(input.length * 0.4))) {
|
|
230
|
+
return best;
|
|
231
|
+
}
|
|
232
|
+
return null;
|
|
233
|
+
}
|
|
234
|
+
function printNotFound(slug) {
|
|
235
|
+
const suggestion = didYouMean(slug);
|
|
236
|
+
if (suggestion) {
|
|
237
|
+
console.log(chalk.red(` Component "${slug}" not found.`) + chalk.dim(` Did you mean ${chalk.bold(suggestion)}?`));
|
|
238
|
+
}
|
|
239
|
+
else {
|
|
240
|
+
console.log(chalk.red(` Component "${slug}" not found.`));
|
|
241
|
+
}
|
|
242
|
+
}
|
|
243
|
+
async function checkForUpdates() {
|
|
244
|
+
try {
|
|
245
|
+
const res = await fetch("https://registry.npmjs.org/praxys-ui/latest", {
|
|
246
|
+
signal: AbortSignal.timeout(3000),
|
|
247
|
+
});
|
|
248
|
+
if (!res.ok)
|
|
249
|
+
return;
|
|
250
|
+
const data = await res.json();
|
|
251
|
+
const latest = data.version;
|
|
252
|
+
if (latest && latest !== VERSION) {
|
|
253
|
+
console.log(chalk.dim(` Update available: ${VERSION} → ${chalk.bold(latest)} Run ${chalk.cyan("npm i -g praxys-ui")} to update.`));
|
|
254
|
+
console.log("");
|
|
255
|
+
}
|
|
256
|
+
}
|
|
257
|
+
catch {
|
|
258
|
+
// Silently ignore — no network, timeout, etc.
|
|
259
|
+
}
|
|
260
|
+
}
|
|
174
261
|
function colorizeSource(source) {
|
|
175
262
|
const lines = source.split("\n");
|
|
176
263
|
return lines
|
|
@@ -222,34 +309,22 @@ program
|
|
|
222
309
|
// ── init ─────────────────────────────────────────────────
|
|
223
310
|
program
|
|
224
311
|
.command("init")
|
|
312
|
+
.alias("i")
|
|
225
313
|
.description("Initialize Praxys UI in your project")
|
|
226
|
-
.
|
|
314
|
+
.option("-d, --dir <directory>", "Component directory", "components/ui")
|
|
315
|
+
.option("--utils-dir <directory>", "Utils directory", "lib")
|
|
316
|
+
.action(async (opts) => {
|
|
317
|
+
const componentDir = opts.dir;
|
|
318
|
+
const utilsDir = opts.utilsDir;
|
|
319
|
+
const pm = detectPackageManager();
|
|
227
320
|
console.log("");
|
|
228
321
|
console.log(chalk.bold(` ${chalk.hex("#E84E2D")("Praxys UI")} — init`));
|
|
229
322
|
console.log("");
|
|
230
|
-
|
|
231
|
-
console.log(chalk.dim(`
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
message: "Where should components be installed?",
|
|
236
|
-
initial: "components/ui",
|
|
237
|
-
});
|
|
238
|
-
if (!componentDir) {
|
|
239
|
-
console.log(chalk.yellow(" Cancelled."));
|
|
240
|
-
return;
|
|
241
|
-
}
|
|
242
|
-
const { utilsDir } = await prompts({
|
|
243
|
-
type: "text",
|
|
244
|
-
name: "utilsDir",
|
|
245
|
-
message: "Where should the utils file be created?",
|
|
246
|
-
initial: "lib",
|
|
247
|
-
});
|
|
248
|
-
if (!utilsDir) {
|
|
249
|
-
console.log(chalk.yellow(" Cancelled."));
|
|
250
|
-
return;
|
|
251
|
-
}
|
|
252
|
-
// Install dependencies
|
|
323
|
+
console.log(chalk.dim(` Package manager ${pm}`));
|
|
324
|
+
console.log(chalk.dim(` Components ${componentDir}/`));
|
|
325
|
+
console.log(chalk.dim(` Utils ${utilsDir}/utils.ts`));
|
|
326
|
+
console.log("");
|
|
327
|
+
// 1. Install dependencies
|
|
253
328
|
const spinner = ora("Installing dependencies...").start();
|
|
254
329
|
try {
|
|
255
330
|
const deps = ["clsx", "tailwind-merge", "framer-motion"];
|
|
@@ -261,27 +336,22 @@ program
|
|
|
261
336
|
console.log(chalk.dim(" Run manually: " +
|
|
262
337
|
installCmd(pm, ["clsx", "tailwind-merge", "framer-motion"])));
|
|
263
338
|
}
|
|
264
|
-
// Create utils file
|
|
265
|
-
const
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
if (existsSync(utilsFile)) {
|
|
271
|
-
utilsSpinner.warn("utils.ts already exists, skipping");
|
|
272
|
-
}
|
|
273
|
-
else {
|
|
274
|
-
writeFileSync(utilsFile, UTILS_CONTENT, "utf-8");
|
|
275
|
-
utilsSpinner.succeed(`Created ${utilsDir}/utils.ts`);
|
|
276
|
-
}
|
|
339
|
+
// 2. Create utils file
|
|
340
|
+
const utilsPath = join(process.cwd(), utilsDir);
|
|
341
|
+
ensureDir(utilsPath);
|
|
342
|
+
const utilsFile = join(utilsPath, "utils.ts");
|
|
343
|
+
if (existsSync(utilsFile)) {
|
|
344
|
+
console.log(chalk.dim(" ○ utils.ts already exists, skipping"));
|
|
277
345
|
}
|
|
278
|
-
|
|
279
|
-
|
|
346
|
+
else {
|
|
347
|
+
writeFileSync(utilsFile, UTILS_CONTENT, "utf-8");
|
|
348
|
+
console.log(chalk.green(` ✓ Created ${utilsDir}/utils.ts`));
|
|
280
349
|
}
|
|
281
|
-
// Create component directory
|
|
350
|
+
// 3. Create component directory
|
|
282
351
|
const compPath = join(process.cwd(), componentDir);
|
|
283
352
|
ensureDir(compPath);
|
|
284
|
-
|
|
353
|
+
console.log(chalk.green(` ✓ Created ${componentDir}/`));
|
|
354
|
+
// 4. Write config file
|
|
285
355
|
const configPath = join(process.cwd(), "praxys.config.json");
|
|
286
356
|
const config = {
|
|
287
357
|
componentsDir: componentDir,
|
|
@@ -290,10 +360,11 @@ program
|
|
|
290
360
|
writeFileSync(configPath, JSON.stringify(config, null, 2) + "\n", "utf-8");
|
|
291
361
|
console.log(chalk.green(" ✓ Created praxys.config.json"));
|
|
292
362
|
console.log("");
|
|
293
|
-
console.log(chalk.green("
|
|
363
|
+
console.log(chalk.green(" Done!"));
|
|
294
364
|
console.log("");
|
|
295
|
-
console.log(chalk.dim(`
|
|
296
|
-
console.log(chalk.dim(` Browse
|
|
365
|
+
console.log(chalk.dim(` npx praxys-ui add animated-button Add a component`));
|
|
366
|
+
console.log(chalk.dim(` npx praxys-ui add Browse & pick`));
|
|
367
|
+
console.log(chalk.dim(` npx praxys-ui list See all 100 components`));
|
|
297
368
|
console.log("");
|
|
298
369
|
});
|
|
299
370
|
// ── add <component> ──────────────────────────────────────
|
|
@@ -358,15 +429,15 @@ async function installDepsForComponents(slugs) {
|
|
|
358
429
|
}
|
|
359
430
|
program
|
|
360
431
|
.command("add")
|
|
361
|
-
.description("Add
|
|
362
|
-
.argument("[
|
|
432
|
+
.description("Add one or more components to your project")
|
|
433
|
+
.argument("[components...]", 'Component slugs (e.g. animated-button alert) or "all". Omit for interactive picker.')
|
|
363
434
|
.option("-d, --dir <directory>", "Component directory")
|
|
364
435
|
.option("-y, --yes", "Skip overwrite prompts (skip existing files)", false)
|
|
365
436
|
.option("--install-deps", "Install component dependencies after adding", false)
|
|
366
|
-
.action(async (
|
|
437
|
+
.action(async (components, opts) => {
|
|
367
438
|
const dir = getComponentsDir(opts.dir);
|
|
368
|
-
// ── interactive picker when no
|
|
369
|
-
if (!
|
|
439
|
+
// ── interactive picker when no args ──────────────────
|
|
440
|
+
if (!components || components.length === 0) {
|
|
370
441
|
console.log("");
|
|
371
442
|
console.log(chalk.bold(` ${chalk.hex("#E84E2D")("Praxys UI")} — add components`));
|
|
372
443
|
console.log("");
|
|
@@ -432,11 +503,12 @@ program
|
|
|
432
503
|
console.log("");
|
|
433
504
|
return;
|
|
434
505
|
}
|
|
506
|
+
const label = components.length === 1 ? chalk.cyan(components[0]) : chalk.cyan(`${components.length} components`);
|
|
435
507
|
console.log("");
|
|
436
|
-
console.log(chalk.bold(` ${chalk.hex("#E84E2D")("Praxys UI")} — add ${
|
|
508
|
+
console.log(chalk.bold(` ${chalk.hex("#E84E2D")("Praxys UI")} — add ${label}`));
|
|
437
509
|
console.log("");
|
|
438
510
|
// ── add all ──────────────────────────────────────────
|
|
439
|
-
if (
|
|
511
|
+
if (components.includes("all")) {
|
|
440
512
|
const { confirm } = await prompts({
|
|
441
513
|
type: "confirm",
|
|
442
514
|
name: "confirm",
|
|
@@ -447,14 +519,19 @@ program
|
|
|
447
519
|
console.log(chalk.yellow(" Cancelled."));
|
|
448
520
|
return;
|
|
449
521
|
}
|
|
522
|
+
// Parallel fetch in batches of 6
|
|
450
523
|
let added = 0;
|
|
451
524
|
let failed = 0;
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
|
|
525
|
+
const batchSize = 6;
|
|
526
|
+
for (let i = 0; i < COMPONENT_LIST.length; i += batchSize) {
|
|
527
|
+
const batch = COMPONENT_LIST.slice(i, i + batchSize);
|
|
528
|
+
const results = await Promise.allSettled(batch.map((slug) => addSingleComponent(slug, dir, opts.yes)));
|
|
529
|
+
for (const r of results) {
|
|
530
|
+
if (r.status === "fulfilled" && r.value)
|
|
531
|
+
added++;
|
|
532
|
+
else
|
|
533
|
+
failed++;
|
|
534
|
+
}
|
|
458
535
|
}
|
|
459
536
|
console.log("");
|
|
460
537
|
console.log(chalk.green(` ✓ ${added} components added`) +
|
|
@@ -465,31 +542,67 @@ program
|
|
|
465
542
|
console.log("");
|
|
466
543
|
return;
|
|
467
544
|
}
|
|
468
|
-
// ──
|
|
469
|
-
|
|
470
|
-
|
|
471
|
-
|
|
472
|
-
|
|
473
|
-
|
|
474
|
-
|
|
545
|
+
// ── validate all slugs first ─────────────────────────
|
|
546
|
+
const invalidSlugs = components.filter((c) => !COMPONENT_LIST.includes(c));
|
|
547
|
+
if (invalidSlugs.length > 0) {
|
|
548
|
+
for (const bad of invalidSlugs) {
|
|
549
|
+
const suggestion = didYouMean(bad);
|
|
550
|
+
if (suggestion) {
|
|
551
|
+
console.log(chalk.red(` Component "${bad}" not found.`) + chalk.dim(` Did you mean ${chalk.bold(suggestion)}?`));
|
|
552
|
+
}
|
|
553
|
+
else {
|
|
554
|
+
console.log(chalk.red(` Component "${bad}" not found.`));
|
|
555
|
+
}
|
|
556
|
+
}
|
|
557
|
+
console.log(chalk.dim(`\n Run ${chalk.bold("praxys-ui list")} to see available components.`));
|
|
475
558
|
console.log("");
|
|
476
559
|
return;
|
|
477
560
|
}
|
|
478
|
-
|
|
479
|
-
if (
|
|
480
|
-
|
|
561
|
+
// ── add single or multiple ───────────────────────────
|
|
562
|
+
if (components.length === 1) {
|
|
563
|
+
const slug = components[0];
|
|
564
|
+
const ok = await addSingleComponent(slug, dir, false);
|
|
565
|
+
if (ok && opts.installDeps) {
|
|
566
|
+
await installDepsForComponents([slug]);
|
|
567
|
+
}
|
|
568
|
+
console.log("");
|
|
569
|
+
console.log(chalk.dim(` Import: ${chalk.bold(`import ${toPascalCase(slug)} from '@/${dir}/${slug}'`)}`));
|
|
570
|
+
console.log("");
|
|
571
|
+
}
|
|
572
|
+
else {
|
|
573
|
+
// Parallel fetch in batches of 6
|
|
574
|
+
let added = 0;
|
|
575
|
+
let failed = 0;
|
|
576
|
+
const batchSize = 6;
|
|
577
|
+
for (let i = 0; i < components.length; i += batchSize) {
|
|
578
|
+
const batch = components.slice(i, i + batchSize);
|
|
579
|
+
const results = await Promise.allSettled(batch.map((slug) => addSingleComponent(slug, dir, opts.yes)));
|
|
580
|
+
for (const r of results) {
|
|
581
|
+
if (r.status === "fulfilled" && r.value)
|
|
582
|
+
added++;
|
|
583
|
+
else
|
|
584
|
+
failed++;
|
|
585
|
+
}
|
|
586
|
+
}
|
|
587
|
+
console.log("");
|
|
588
|
+
console.log(chalk.green(` ✓ ${added} components added`) +
|
|
589
|
+
(failed > 0 ? chalk.red(`, ${failed} failed`) : ""));
|
|
590
|
+
if (opts.installDeps) {
|
|
591
|
+
await installDepsForComponents(components);
|
|
592
|
+
}
|
|
593
|
+
console.log("");
|
|
481
594
|
}
|
|
482
|
-
console.log("");
|
|
483
|
-
console.log(chalk.dim(` Import: ${chalk.bold(`import ${toPascalCase(component)} from '@/${dir}/${component}'`)}`));
|
|
484
|
-
console.log("");
|
|
485
595
|
});
|
|
486
596
|
// ── list ─────────────────────────────────────────────────
|
|
487
597
|
program
|
|
488
598
|
.command("list")
|
|
599
|
+
.alias("ls")
|
|
489
600
|
.description("List all available components")
|
|
490
601
|
.option("-c, --category <category>", "Filter by category (buttons, cards, text, navigation, visual, media)")
|
|
491
602
|
.option("-n, --new", "Show only new components", false)
|
|
492
603
|
.option("-s, --search <query>", "Search components by name or description")
|
|
604
|
+
.option("--installed", "Show only locally installed components", false)
|
|
605
|
+
.option("-d, --dir <directory>", "Component directory (used with --installed)")
|
|
493
606
|
.action((opts) => {
|
|
494
607
|
console.log("");
|
|
495
608
|
console.log(chalk.bold(` ${chalk.hex("#E84E2D")("Praxys UI")} — components`));
|
|
@@ -506,6 +619,16 @@ program
|
|
|
506
619
|
return;
|
|
507
620
|
}
|
|
508
621
|
}
|
|
622
|
+
// Filter by installed
|
|
623
|
+
if (opts.installed) {
|
|
624
|
+
const compPath = join(process.cwd(), getComponentsDir(opts.dir));
|
|
625
|
+
entries = entries.filter(([slug]) => existsSync(join(compPath, `${slug}.tsx`)));
|
|
626
|
+
if (entries.length === 0) {
|
|
627
|
+
console.log(chalk.yellow(` No installed components found.`));
|
|
628
|
+
console.log("");
|
|
629
|
+
return;
|
|
630
|
+
}
|
|
631
|
+
}
|
|
509
632
|
// Filter by new
|
|
510
633
|
if (opts.new) {
|
|
511
634
|
entries = entries.filter(([, meta]) => meta.isNew);
|
|
@@ -558,7 +681,7 @@ program
|
|
|
558
681
|
const meta = COMPONENT_REGISTRY[component];
|
|
559
682
|
if (!meta) {
|
|
560
683
|
console.log("");
|
|
561
|
-
|
|
684
|
+
printNotFound(component);
|
|
562
685
|
console.log(chalk.dim(` Run ${chalk.bold("praxys-ui list")} to see available components.`));
|
|
563
686
|
console.log("");
|
|
564
687
|
return;
|
|
@@ -580,7 +703,7 @@ program
|
|
|
580
703
|
.action(async (component) => {
|
|
581
704
|
if (!COMPONENT_REGISTRY[component]) {
|
|
582
705
|
console.log("");
|
|
583
|
-
|
|
706
|
+
printNotFound(component);
|
|
584
707
|
console.log(chalk.dim(` Run ${chalk.bold("praxys-ui list")} to see available components.`));
|
|
585
708
|
console.log("");
|
|
586
709
|
return;
|
|
@@ -611,7 +734,7 @@ program
|
|
|
611
734
|
const dir = getComponentsDir(opts.dir);
|
|
612
735
|
if (!COMPONENT_REGISTRY[component]) {
|
|
613
736
|
console.log("");
|
|
614
|
-
|
|
737
|
+
printNotFound(component);
|
|
615
738
|
console.log("");
|
|
616
739
|
return;
|
|
617
740
|
}
|
|
@@ -666,6 +789,7 @@ program
|
|
|
666
789
|
// ── remove <component> ───────────────────────────────────
|
|
667
790
|
program
|
|
668
791
|
.command("remove")
|
|
792
|
+
.alias("rm")
|
|
669
793
|
.description("Remove a component from your project")
|
|
670
794
|
.argument("<component>", "Component slug")
|
|
671
795
|
.option("-d, --dir <directory>", "Component directory")
|
|
@@ -674,7 +798,7 @@ program
|
|
|
674
798
|
const dir = getComponentsDir(opts.dir);
|
|
675
799
|
if (!COMPONENT_REGISTRY[component]) {
|
|
676
800
|
console.log("");
|
|
677
|
-
|
|
801
|
+
printNotFound(component);
|
|
678
802
|
console.log("");
|
|
679
803
|
return;
|
|
680
804
|
}
|
|
@@ -727,7 +851,7 @@ program
|
|
|
727
851
|
let slugsToCheck;
|
|
728
852
|
if (component) {
|
|
729
853
|
if (!COMPONENT_REGISTRY[component]) {
|
|
730
|
-
|
|
854
|
+
printNotFound(component);
|
|
731
855
|
console.log("");
|
|
732
856
|
return;
|
|
733
857
|
}
|
|
@@ -946,4 +1070,4 @@ program
|
|
|
946
1070
|
console.log("");
|
|
947
1071
|
});
|
|
948
1072
|
// ── run ──────────────────────────────────────────────────
|
|
949
|
-
program.
|
|
1073
|
+
program.parseAsync().then(() => checkForUpdates());
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "praxys-ui",
|
|
3
|
-
"version": "1.3.
|
|
3
|
+
"version": "1.3.4",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"description": "CLI for scaffolding Praxys UI components into your project",
|
|
6
6
|
"bin": {
|
|
@@ -8,7 +8,7 @@
|
|
|
8
8
|
},
|
|
9
9
|
"files": [
|
|
10
10
|
"dist",
|
|
11
|
-
"
|
|
11
|
+
"README.md"
|
|
12
12
|
],
|
|
13
13
|
"scripts": {
|
|
14
14
|
"build": "tsc",
|
package/CHANGELOG.md
DELETED
|
@@ -1,319 +0,0 @@
|
|
|
1
|
-
# Changelog
|
|
2
|
-
|
|
3
|
-
All notable changes to Praxys UI are documented here.
|
|
4
|
-
|
|
5
|
-
## [1.2.6] — Feb 15, 2026
|
|
6
|
-
|
|
7
|
-
**Color Customization & Enhanced Studio**
|
|
8
|
-
|
|
9
|
-
Added comprehensive color customization to Animation Studio and Theme Customizer with random palette generation and per-color editing.
|
|
10
|
-
|
|
11
|
-
### Added
|
|
12
|
-
|
|
13
|
-
- Color Scheme Customization — 10 pre-made color schemes (Ocean, Forest, Sunset, Purple, Rose Gold, Mint, Fire, Cyberpunk, Monochrome)
|
|
14
|
-
- Theme Customizer Panel — "Make it yours" section with individual color editing (Primary, Secondary, Accent, Background, Text)
|
|
15
|
-
- Random Palette Generator — 🎲 Generate harmonious color palettes with one click in both Studio and /customize
|
|
16
|
-
- Per-Color Randomization — Random button (🎲) for each individual color property
|
|
17
|
-
- Color Pickers — Visual color selection with hex/HSL text input support
|
|
18
|
-
|
|
19
|
-
### Fixed
|
|
20
|
-
|
|
21
|
-
- React Style Warning — Changed background to backgroundImage to avoid conflicts with backgroundClip
|
|
22
|
-
- HSL to Hex Conversion — All colors properly converted for CSS compatibility
|
|
23
|
-
|
|
24
|
-
### Improved
|
|
25
|
-
|
|
26
|
-
- Random Color Algorithm — Uses color theory (analogous + complementary hues) for harmonious palettes
|
|
27
|
-
- Color Contrast — Fixed lightness/saturation values ensure readable, professional themes
|
|
28
|
-
- Live Preview Updates — All component previews dynamically use selected color scheme
|
|
29
|
-
|
|
30
|
-
## [1.2.5] — Feb 15, 2026
|
|
31
|
-
|
|
32
|
-
**Animation Studio — Visual Animation Builder**
|
|
33
|
-
|
|
34
|
-
Introducing the Animation Studio, a killer feature that sets PraxysUI apart. Visually design animations for any component with live preview, presets, and instant code generation.
|
|
35
|
-
|
|
36
|
-
### Added
|
|
37
|
-
|
|
38
|
-
- Animation Studio (/studio) — Interactive visual playground for designing component animations
|
|
39
|
-
- Live Preview Canvas — See animations play in real-time as you adjust parameters
|
|
40
|
-
- Animation Controls — Fine-tune initial state, animate state, and transitions with intuitive sliders
|
|
41
|
-
- 30+ Animation Presets — Pre-built entrance, attention, exit, and loop animations (fade, slide, bounce, scale, flip, rotate, etc.)
|
|
42
|
-
- Component Selector — Search and filter through all 69 components with category filters
|
|
43
|
-
- Code Generator — Instantly copy Framer Motion or CSS @keyframes code for your custom animations
|
|
44
|
-
- Auto-Play Mode — Automatically replay animations when changing parameters or components
|
|
45
|
-
- Category-Specific Previews — Realistic mockups for buttons, cards, text, navigation, and visual components
|
|
46
|
-
|
|
47
|
-
### Improved
|
|
48
|
-
|
|
49
|
-
- Mobile Responsive — Compact dropdown component selector on mobile, full experience preserved
|
|
50
|
-
- Navbar — Added "Studio" link for easy access
|
|
51
|
-
|
|
52
|
-
## [1.2.2] — Feb 15, 2026
|
|
53
|
-
|
|
54
|
-
**Autocomplete API Fix**
|
|
55
|
-
|
|
56
|
-
Fixed Autocomplete component API to use onSelect callback instead of onChange for better clarity and type safety.
|
|
57
|
-
|
|
58
|
-
### Fixed
|
|
59
|
-
|
|
60
|
-
- Autocomplete — changed API from onChange to onSelect, now passes full option object instead of just value string
|
|
61
|
-
- Autocomplete demo and documentation updated to reflect new API
|
|
62
|
-
- TypeScript errors resolved in Autocomplete component
|
|
63
|
-
|
|
64
|
-
## [1.2.1] — Feb 15, 2026
|
|
65
|
-
|
|
66
|
-
**6 New Components — Essential UI Elements**
|
|
67
|
-
|
|
68
|
-
Essential interactive components: Switch, Slider, File Upload, OTP Input, Rating, and Autocomplete with async search — bringing the total to 69 components.
|
|
69
|
-
|
|
70
|
-
### Added
|
|
71
|
-
|
|
72
|
-
- Switch — simple on/off toggle with spring animation, 3 sizes, optional label, keyboard accessible
|
|
73
|
-
- Slider — range input with draggable thumb, animated track fill, value tooltip, min/max labels, step support, keyboard navigation
|
|
74
|
-
- File Upload — drag-and-drop zone with animated borders, file list with remove buttons, progress bars, file type and size validation, multiple file support
|
|
75
|
-
- OTP Input — PIN/verification code input with auto-focus next/prev, paste support, animated focus rings, configurable length (4-6)
|
|
76
|
-
- Rating — interactive star rating with half-star support, hover preview, animated fill, read-only mode, 3 sizes, custom icon support
|
|
77
|
-
- Autocomplete — async search input with debouncing, loading state, keyboard navigation, highlighted matching text, empty state
|
|
78
|
-
|
|
79
|
-
### Improved
|
|
80
|
-
|
|
81
|
-
- CLI updated to v1.2.1 with all 69 components
|
|
82
|
-
- Component count updated from 63 to 69 across site
|
|
83
|
-
|
|
84
|
-
## [1.2.0] — Feb 15, 2026
|
|
85
|
-
|
|
86
|
-
**3 New Form Components — Complete Your Forms**
|
|
87
|
-
|
|
88
|
-
Essential form components to complete your UI toolkit: Date Picker with range selection, Combobox with search, and Color Picker with HSL controls — bringing the total to 63 components.
|
|
89
|
-
|
|
90
|
-
### Added
|
|
91
|
-
|
|
92
|
-
- Date Picker — animated calendar popup with month/year navigation, single/range selection, keyboard navigation, disabled dates support
|
|
93
|
-
- Combobox — searchable select with filtering, single/multi-select modes, keyboard navigation, search highlighting, loading state
|
|
94
|
-
- Color Picker — HSL sliders, hex input, preset swatches, alpha channel, format toggle (HEX/RGB/HSL), copy to clipboard
|
|
95
|
-
|
|
96
|
-
### Fixed
|
|
97
|
-
|
|
98
|
-
- Skip-to-content accessibility link — now only appears on real keyboard Tab, never on route navigation
|
|
99
|
-
- AnimatedInput and AnimatedTextarea — support both controlled and uncontrolled usage for Playground compatibility
|
|
100
|
-
|
|
101
|
-
### Improved
|
|
102
|
-
|
|
103
|
-
- CLI updated to v1.2.0 with all 63 components
|
|
104
|
-
- Component count updated from 60 to 63 across site
|
|
105
|
-
|
|
106
|
-
## [1.1.0] — Feb 14, 2026
|
|
107
|
-
|
|
108
|
-
**11 New Components — Forms, Layout & Data**
|
|
109
|
-
|
|
110
|
-
11 new components covering forms (Input, Select, Textarea, Checkbox, Radio), feedback (Alert, Sheet), data display (Pagination, Timeline, Stats Card), and layout (Divider) — bringing the total to 60. CLI updated to v1.1.0.
|
|
111
|
-
|
|
112
|
-
### Added
|
|
113
|
-
|
|
114
|
-
- Animated Input — floating label, animated focus ring, left/right icons, error state, 3 sizes
|
|
115
|
-
- Animated Select — custom dropdown with keyboard navigation, spring animations, click-outside close
|
|
116
|
-
- Animated Textarea — floating label, auto-resize, character counter, animated focus ring
|
|
117
|
-
- Checkbox — animated SVG checkmark with pathLength draw, spring scale, error state, ARIA checkbox role
|
|
118
|
-
- Radio Group — animated dot selection, horizontal/vertical layout, keyboard navigation, ARIA radiogroup
|
|
119
|
-
- Alert — 4 variants (info/success/warning/error) with auto-icons, dismissible with animated exit
|
|
120
|
-
- Pagination — sliding active indicator with layoutId, ellipsis, prev/next, 2 sizes
|
|
121
|
-
- Sheet — slide-in drawer from 4 sides, backdrop blur, Escape close, scroll lock
|
|
122
|
-
- Divider — horizontal/vertical with optional label, gradient mode, animated entrance
|
|
123
|
-
- Timeline — alternating two-column layout, staggered scroll animations, active/completed states
|
|
124
|
-
- Stats Card — animated counter with useSpring, trend indicator, icon slot
|
|
125
|
-
|
|
126
|
-
### Fixed
|
|
127
|
-
|
|
128
|
-
- Navbar — replaced useEffect setState with React-idiomatic derived state pattern for route change detection
|
|
129
|
-
- Sidebar — same derived state fix to comply with react-hooks/set-state-in-effect rule
|
|
130
|
-
- Header inconsistency — docs pages now use the shared Navbar instead of a separate custom header
|
|
131
|
-
|
|
132
|
-
### Improved
|
|
133
|
-
|
|
134
|
-
- CLI updated to v1.1.0 with all 60 components published to npm
|
|
135
|
-
- Component count updated from 50 to 60 across landing page and registry
|
|
136
|
-
- Navbar — active link highlighting, skip-to-content accessibility link
|
|
137
|
-
- Docs — breadcrumbs on all pages, slim footer, back-to-top button
|
|
138
|
-
- Changelog — extracted data to single source of truth, auto-generates CHANGELOG.md
|
|
139
|
-
- ComponentPreview — proper ARIA tab roles (tablist, tab, tabpanel)
|
|
140
|
-
- 404 page — now has Navbar/Footer, fixed stale template count
|
|
141
|
-
- Loading skeletons added to changelog, templates, examples, and customize pages
|
|
142
|
-
|
|
143
|
-
## [0.9.0] — Feb 10, 2026
|
|
144
|
-
|
|
145
|
-
**10 New Components & CLI v0.3.0**
|
|
146
|
-
|
|
147
|
-
10 new interactive components spanning modals, tooltips, dropdowns, progress indicators, and more — bringing the total to 50. CLI updated to v0.3.0.
|
|
148
|
-
|
|
149
|
-
### Added
|
|
150
|
-
|
|
151
|
-
- Modal Dialog — animated modal with backdrop blur, spring scale, Escape key, scroll lock, and ARIA attributes
|
|
152
|
-
- Tooltip — 4-position tooltip with configurable delay, direction-aware animation, and arrow pointer
|
|
153
|
-
- Dropdown Menu — full keyboard navigation, click-outside close, divider and disabled item support
|
|
154
|
-
- Progress Bar — animated bar with sm/md/lg sizes, candy-stripe overlay, custom colors, and label/value display
|
|
155
|
-
- Stepper — horizontal/vertical multi-step indicator with animated check icons and connector fill
|
|
156
|
-
- Image Comparison — before/after slider with pointer-capture drag, clip-based reveal, and animated handle
|
|
157
|
-
- Animated Counter — spring-physics number counter triggered on scroll into view with prefix/suffix/decimals
|
|
158
|
-
- Infinite Scroll — Intersection Observer-based with configurable threshold and animated loader
|
|
159
|
-
- Command Menu — search-filtered palette with grouped items, keyboard nav, match highlighting, and shortcut badges
|
|
160
|
-
- Animated Toggle — switch with spring-animated knob, 3 sizes, ARIA role="switch", and disabled state
|
|
161
|
-
|
|
162
|
-
### Improved
|
|
163
|
-
|
|
164
|
-
- CLI updated to v0.3.0 with all 50 components published to npm
|
|
165
|
-
- Component count updated from 34 to 50 across landing page and registry
|
|
166
|
-
|
|
167
|
-
## [0.8.0] — Feb 2, 2026
|
|
168
|
-
|
|
169
|
-
**New Components, Theme Customizer & Open Source**
|
|
170
|
-
|
|
171
|
-
10 new components, interactive theme customizer with export, Props Playground for all components, and full open-source community setup.
|
|
172
|
-
|
|
173
|
-
### Added
|
|
174
|
-
|
|
175
|
-
- Typewriter Text — animated typing effect with cursor and configurable speed
|
|
176
|
-
- Toast Notification — stackable toast system with multiple variants
|
|
177
|
-
- Accordion — smooth expand/collapse with icon rotation
|
|
178
|
-
- Animated Tabs — tab switcher with sliding indicator and content transitions
|
|
179
|
-
- Magnetic Cursor — element that pulls toward the mouse pointer
|
|
180
|
-
- Parallax Scroll — depth-based scroll animations for layered content
|
|
181
|
-
- Gradient Mesh — animated multi-point gradient background
|
|
182
|
-
- Skeleton Loader — pulsing placeholder for loading states
|
|
183
|
-
- Morphing Text — smooth text transitions between words
|
|
184
|
-
- Spotlight Card — card with mouse-following light effect
|
|
185
|
-
- Theme Customizer page (/customize) with color pickers, 6 presets, live preview, and CSS export
|
|
186
|
-
- Interactive Props Playground with live controls for all 34 components
|
|
187
|
-
- Live interactive demos on component showcase (landing page)
|
|
188
|
-
- 6 interactive template pages with preview toolbar and responsive viewport switcher
|
|
189
|
-
- CONTRIBUTING.md, CODE_OF_CONDUCT.md, issue templates, and PR template for open source
|
|
190
|
-
|
|
191
|
-
### Fixed
|
|
192
|
-
|
|
193
|
-
- Nested <a> tags in ComponentShowcase — replaced Link with div + useRouter
|
|
194
|
-
- ToastContainer crash when toasts/onDismiss are undefined in playground
|
|
195
|
-
- LogoSlider animation shorthand/longhand conflict in React 19
|
|
196
|
-
- Missing playground defaults for glass-dock and logo-slider
|
|
197
|
-
- CopyButton invisible on touch devices — now always visible on mobile
|
|
198
|
-
|
|
199
|
-
### Improved
|
|
200
|
-
|
|
201
|
-
- CLI updated to v0.2.0 with all 34 components
|
|
202
|
-
- Component showcase redesigned with live demos instead of placeholder cards
|
|
203
|
-
- Dark mode text contrast improved (--color-text-faint bumped to #6b6560)
|
|
204
|
-
- Comprehensive responsive design fixes across all components and pages
|
|
205
|
-
|
|
206
|
-
## [0.7.0] — Jan 11, 2026
|
|
207
|
-
|
|
208
|
-
**SEO, Accessibility & Polish**
|
|
209
|
-
|
|
210
|
-
Comprehensive SEO metadata, accessibility audit fixes, and public assets.
|
|
211
|
-
|
|
212
|
-
### Added
|
|
213
|
-
|
|
214
|
-
- Open Graph and Twitter Card metadata across all pages
|
|
215
|
-
- Dynamic generateMetadata for all /docs/[slug] pages
|
|
216
|
-
- SVG favicon, robots.txt, and sitemap.xml
|
|
217
|
-
|
|
218
|
-
### Fixed
|
|
219
|
-
|
|
220
|
-
- suppressHydrationWarning on body to handle browser extension attributes
|
|
221
|
-
|
|
222
|
-
### Improved
|
|
223
|
-
|
|
224
|
-
- ARIA labels, roles, and keyboard navigation on Navbar, CommandPalette, Sidebar
|
|
225
|
-
- Focus trap in command palette dialog
|
|
226
|
-
- aria-current="page" on active sidebar links
|
|
227
|
-
|
|
228
|
-
## [0.6.0] — Jan 8, 2026
|
|
229
|
-
|
|
230
|
-
**Bug Fix Pass**
|
|
231
|
-
|
|
232
|
-
Major audit fixing 10 issues across the docs — broken links, duplicate pages, layout problems, and error handling.
|
|
233
|
-
|
|
234
|
-
### Fixed
|
|
235
|
-
|
|
236
|
-
- Broken /docs/components links across 5 files — now points to /docs/components-overview
|
|
237
|
-
- Mobile menu not closing on link click in Navbar
|
|
238
|
-
- Duplicate IntroductionPage — single source of truth now
|
|
239
|
-
- ComponentPageClient dynamic import error handling with .catch() and error state
|
|
240
|
-
- Sidebar slug extraction for trailing slashes
|
|
241
|
-
- ComponentsOverviewPage uses sidebar order, removed dead code
|
|
242
|
-
- Component count corrected to 24, added missing Logo Slider
|
|
243
|
-
- GitHub links in Footer now point to actual repository
|
|
244
|
-
|
|
245
|
-
### Improved
|
|
246
|
-
|
|
247
|
-
- Docs layout.tsx extracted to server component + DocsShell client component
|
|
248
|
-
|
|
249
|
-
## [0.5.0] — Jan 7, 2026
|
|
250
|
-
|
|
251
|
-
**CLI Tool & Templates**
|
|
252
|
-
|
|
253
|
-
Added a CLI for scaffolding components and a templates gallery page.
|
|
254
|
-
|
|
255
|
-
### Added
|
|
256
|
-
|
|
257
|
-
- npx praxys-ui CLI with init, add, and list commands
|
|
258
|
-
- Templates gallery page with 6 template previews
|
|
259
|
-
- CLI docs page at /docs/cli
|
|
260
|
-
|
|
261
|
-
## [0.4.0] — Jan 4, 2026
|
|
262
|
-
|
|
263
|
-
**Command Palette**
|
|
264
|
-
|
|
265
|
-
Ctrl+K fuzzy search across all components and documentation pages.
|
|
266
|
-
|
|
267
|
-
### Added
|
|
268
|
-
|
|
269
|
-
- Ctrl+K / Cmd+K keyboard shortcut to open search
|
|
270
|
-
- Fuzzy matching with scoring (exact > starts with > contains > fuzzy)
|
|
271
|
-
- Arrow key navigation and Enter to select
|
|
272
|
-
|
|
273
|
-
## [0.3.0] — Jan 2, 2026
|
|
274
|
-
|
|
275
|
-
**Complete Component Library**
|
|
276
|
-
|
|
277
|
-
All 24 components implemented with live previews, code examples, and props tables.
|
|
278
|
-
|
|
279
|
-
### Added
|
|
280
|
-
|
|
281
|
-
- Interactive Book — 3D page-flip book component
|
|
282
|
-
- Logo Slider — infinite marquee logo carousel
|
|
283
|
-
- Animated Hero — cinematic hero section with parallax
|
|
284
|
-
- Masked Avatars — overlapping avatar stack with hover reveal
|
|
285
|
-
- Folder Preview — macOS-style folder with hover preview
|
|
286
|
-
- Liquid Ocean, Liquid Metal, Reveal Loader — visual effects
|
|
287
|
-
- Spotlight Navbar, Glass Dock — navigation components
|
|
288
|
-
- Flip Fade Text, 3D Displacement Text — text effects
|
|
289
|
-
- Testimonials Card, Staggered Grid, Expandable Bento Grid, Perspective Grid — cards & layout
|
|
290
|
-
- Creepy Button, Social Flip Button — button variants
|
|
291
|
-
|
|
292
|
-
## [0.2.0] — Dec 22, 2025
|
|
293
|
-
|
|
294
|
-
**Theme System & First Components**
|
|
295
|
-
|
|
296
|
-
Light/dark mode with CSS custom properties and the first 6 animated components.
|
|
297
|
-
|
|
298
|
-
### Added
|
|
299
|
-
|
|
300
|
-
- Light/dark theme toggle with localStorage persistence and FOUC prevention
|
|
301
|
-
- Animated Button, Flip Text, Glow Border Card, Animated Number, Line Hover Link, Light Lines
|
|
302
|
-
- Shiki dual-theme code blocks (vitesse-dark + vitesse-light)
|
|
303
|
-
- Component preview with Preview/Code tab switcher
|
|
304
|
-
|
|
305
|
-
## [0.1.0] — Dec 15, 2025
|
|
306
|
-
|
|
307
|
-
**Initial Release**
|
|
308
|
-
|
|
309
|
-
Project scaffolding, design system, landing page, and docs infrastructure.
|
|
310
|
-
|
|
311
|
-
### Added
|
|
312
|
-
|
|
313
|
-
- Next.js 16 project with React 19, Tailwind CSS 4, Framer Motion 12
|
|
314
|
-
- Praxys brand palette — Void, Obsidian, Ignite, Blush, Chalk
|
|
315
|
-
- Font stack — Geist Pixel Square, Satoshi, JetBrains Mono
|
|
316
|
-
- Landing page with 7 sections (Navbar, Hero, Showcase, Features, Grid, CTA, Footer)
|
|
317
|
-
- Docs with sidebar navigation and dynamic [slug] routing
|
|
318
|
-
- Getting Started pages (Installation, Tailwind, Utilities)
|
|
319
|
-
- Component registry architecture with lazy-loaded demos
|