veloria-ui 0.1.4 → 0.1.5

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 (56) hide show
  1. package/CHANGELOG.md +718 -67
  2. package/README.md +70 -200
  3. package/dist/cli/index.js +896 -268
  4. package/dist/index.d.mts +137 -1
  5. package/dist/index.d.ts +137 -1
  6. package/dist/index.js +1852 -353
  7. package/dist/index.js.map +1 -1
  8. package/dist/index.mjs +1832 -350
  9. package/dist/index.mjs.map +1 -1
  10. package/dist/motion.d.mts +286 -0
  11. package/dist/motion.d.ts +286 -0
  12. package/dist/motion.js +655 -0
  13. package/dist/motion.js.map +1 -0
  14. package/dist/motion.mjs +601 -0
  15. package/dist/motion.mjs.map +1 -0
  16. package/dist/rhf.d.mts +202 -0
  17. package/dist/rhf.d.ts +202 -0
  18. package/dist/rhf.js +1598 -0
  19. package/dist/rhf.js.map +1 -0
  20. package/dist/rhf.mjs +1561 -0
  21. package/dist/rhf.mjs.map +1 -0
  22. package/package.json +112 -47
  23. package/src/cli/index.ts +962 -91
  24. package/src/cli/registry.ts +144 -142
  25. package/src/components/advanced-forms/MultiStepForm.tsx +445 -0
  26. package/src/components/advanced-forms/RichTextEditor.tsx +461 -0
  27. package/src/components/advanced-forms/index.tsx +6 -0
  28. package/src/components/data-display/DataGrid.tsx +381 -0
  29. package/src/components/data-display/index.tsx +3 -0
  30. package/src/components/forms/DateRangePicker.tsx +355 -0
  31. package/src/components/forms/index.tsx +3 -0
  32. package/src/components/overlay/CommandBar.tsx +241 -0
  33. package/src/components/overlay/index.tsx +3 -0
  34. package/src/index.ts +18 -1
  35. package/src/motion/Animated.tsx +77 -0
  36. package/src/motion/MotionPresence.tsx +144 -0
  37. package/src/motion/components.tsx +203 -0
  38. package/src/motion/engine.ts +150 -0
  39. package/src/motion/index.ts +57 -0
  40. package/src/motion/presets.ts +220 -0
  41. package/src/motion/types.ts +117 -0
  42. package/src/motion/useMotion.ts +120 -0
  43. package/src/motion/withMotion.tsx +133 -0
  44. package/src/rhf/RhfCheckbox.tsx +49 -0
  45. package/src/rhf/RhfCombobox.tsx +52 -0
  46. package/src/rhf/RhfInput.tsx +44 -0
  47. package/src/rhf/RhfMultiSelect.tsx +43 -0
  48. package/src/rhf/RhfOTPInput.tsx +43 -0
  49. package/src/rhf/RhfRadioGroup.tsx +48 -0
  50. package/src/rhf/RhfRatingInput.tsx +43 -0
  51. package/src/rhf/RhfSelect.tsx +85 -0
  52. package/src/rhf/RhfSlider.tsx +68 -0
  53. package/src/rhf/RhfSwitch.tsx +48 -0
  54. package/src/rhf/RhfTextArea.tsx +44 -0
  55. package/src/rhf/index.ts +38 -0
  56. package/dist/tailwind.d.ts +0 -21
package/CHANGELOG.md CHANGED
@@ -1,97 +1,609 @@
1
1
  # Changelog
2
2
 
3
- All notable changes to Veloria UI are documented here.
3
+ All notable changes to Veloria UI are documented here.
4
4
  Project by [JohnDev19](https://github.com/JohnDev19) · [GitHub](https://github.com/JohnDev19/Veloria-UI) · [ui-veloria.vercel.app](https://ui-veloria.vercel.app/)
5
5
 
6
6
  This project follows [Semantic Versioning](https://semver.org).
7
7
 
8
8
  ---
9
9
 
10
- ## [0.1.4] — 2026-03-16
10
+ ## [0.1.5] — 2026-03-17
11
11
 
12
- ### New Components (10)
12
+ ### `veloria-ui/motion` Animated presence system
13
13
 
14
- **Charts**
15
- - `SparklineChart` — zero-dependency SVG inline trend line with optional area fill, animated draw-on, and end-point dot. Designed to slot directly into `StatsCard` or any compact metric surface. No external chart library needed.
16
- - `RadialProgressChart` — multi-segment animated SVG donut ring. Each arc is independently sized via `stroke-dasharray`, eased in on mount, with a customizable center label slot and an optional colour legend below.
17
- - `GaugeChart` — half-circle SVG gauge with a `requestAnimationFrame`-driven animated needle, configurable colour zones (green → amber → red by default), per-zone stroke arcs, and rendered min/max/value labels. Fully controlled via `value`, `min`, `max`, and `zones` props.
14
+ A new zero-dependency animation sub-path built entirely on the **Web Animations API**. No additional `npm install` required — it ships inside the `veloria-ui` package and adds `0 bytes` to your bundle unless you actually import it.
18
15
 
19
- **Modern & Unique**
20
- - `AuroraCard` — dark-surface card with three aurora gradient blobs that track mouse position via `onMouseMove` offset math. Each blob moves at a different speed and direction, creating a parallax aurora effect. The content renders inside a relative `z-10` panel on top. Zero external dependencies — pure CSS transforms + inline style.
21
- - `TypewriterText` — cycles through a `strings[]` array, typing each character-by-character then erasing, with configurable `speed`, `deleteSpeed`, `pause`, `cursor`, and `loop` props. Cursor blinks independently of the typing loop via a separate `setInterval`. Accessible with `aria-live="polite"`.
16
+ Import from `veloria-ui/motion`:
22
17
 
23
- **Data Display**
24
- - `FileCard` — file attachment surface with auto-derived type badge (colour-coded per extension), formatted file size, optional upload/download progress bar that turns green on completion, and download/remove action buttons. Two layout variants: `compact` (inline pill) and `full` (card with icon block).
25
- - `PricingCard` — structured pricing tier with plan name, price + billing period, optional description, feature list with check/cross icons and optional notes, a CTA button that highlights when `popular` is set, and a "Most popular" ribbon badge. Supports `classic` bevel variant.
18
+ ```ts
19
+ import {
20
+ Animated, MotionPresence, withMotion, useMotion,
21
+ MotionModal, MotionDrawer, MotionCard, MotionToast,
22
+ stagger, PRESETS, DURATIONS,
23
+ } from "veloria-ui/motion";
24
+ ```
26
25
 
27
- **Forms**
28
- - `NumberInput` — stepper input flanked by − and + buttons. Clamps to `min`/`max`, steps by configurable `step` amount, increments on `ArrowUp`/`ArrowDown` keyboard events, and adjusts on mouse scroll when focused. Hides native browser spinners. Supports controlled and uncontrolled modes. Sizes `xs`–`lg`.
29
- - `AvatarUpload` — avatar circle with a camera overlay that appears on hover, a hidden `<input type="file">` triggered on click or keyboard, instant `FileReader` base64 preview, max-size validation with an error message, and a "Remove photo" link. Sizes `sm`–`xl`. Fully accessible with `role="button"` and `aria-label`.
26
+ ---
30
27
 
31
- **Feedback**
32
- - `StepProgress` — animated segmented progress bar. Each segment fills left-to-right with a staggered CSS `scaleX` transition (40ms per-segment delay). Props: `steps`, `current`, `color`, `animated`, `showLabel`, `size`. Renders a `role="progressbar"` with correct ARIA attributes.
28
+ #### Architecture — 9 files, one entry point
33
29
 
34
- **Utility**
35
- - `TypewriterText` — see Modern & Unique above (also exported from `utility`).
30
+ | File | Purpose |
31
+ |------|---------|
32
+ | `types.ts` | All TypeScript types — `MotionPreset`, `MotionConfig`, `MotionProps` |
33
+ | `presets.ts` | 16 named presets as WAAPI keyframe arrays. Each preset < 200 bytes. |
34
+ | `engine.ts` | Core runner — resolves config, checks `prefers-reduced-motion`, runs `element.animate()`, handles abort/cancel |
35
+ | `useMotion.ts` | React hook — attach enter/exit to a ref, tracks visible state, fires `onExitComplete` |
36
+ | `Animated.tsx` | `<Animated show motion>` — conditional element with animated enter/exit |
37
+ | `MotionPresence.tsx` | `<MotionPresence motion>` — manages enter/exit for children that mount/unmount |
38
+ | `withMotion.ts` | HOC — wraps any component to add a `motion` prop, watches `open` prop or runs on mount |
39
+ | `components.tsx` | Pre-wrapped `MotionModal`, `MotionDrawer`, `MotionToast`, `MotionCard`, etc. |
40
+ | `index.ts` | Single barrel export |
41
+
42
+ ---
43
+
44
+ #### 16 animation presets
45
+
46
+ | Preset | Description |
47
+ |--------|-------------|
48
+ | `fade` | Simple opacity fade |
49
+ | `fade-up` | Fade in from below |
50
+ | `fade-down` | Fade in from above |
51
+ | `fade-left` | Fade in from the right |
52
+ | `fade-right` | Fade in from the left |
53
+ | `fade-scale` | Fade + scale from 95% |
54
+ | `slide-up` | Translate from 100% below, no fade |
55
+ | `slide-down` | Translate from 100% above |
56
+ | `slide-left` | Translate from 100% right |
57
+ | `slide-right` | Translate from 100% left |
58
+ | `zoom` | Scale from 50% with fade |
59
+ | `zoom-out` | Scale from 110% with fade |
60
+ | `flip` | 3D Y-axis perspective flip |
61
+ | `flip-x` | 3D X-axis perspective flip |
62
+ | `bounce` | Elastic entrance with spring easing overshoot |
63
+ | `none` | No animation (useful for `prefers-reduced-motion` overrides) |
64
+
65
+ ---
66
+
67
+ #### `prefers-reduced-motion` — automatic
68
+
69
+ The engine checks `window.matchMedia("(prefers-reduced-motion: reduce)")` before every animation. When the user has requested reduced motion:
70
+
71
+ - All keyframe animations are skipped entirely
72
+ - Elements are made immediately visible/hidden instead
73
+ - No JavaScript timing or RAF overhead
74
+ - SSR-safe (returns `false` on the server)
75
+
76
+ ---
77
+
78
+ #### Pre-wrapped components
79
+
80
+ Ready-to-use `Motion*` variants of the most common Veloria UI components. Import and use as drop-in replacements — the `motion` prop is the only addition:
81
+
82
+ ```tsx
83
+ import {
84
+ MotionModal, MotionDrawer, MotionSheet, MotionDialog,
85
+ MotionPopover, MotionHoverCard,
86
+ MotionToast, MotionSnackbar, MotionBannerAlert,
87
+ MotionCard, MotionAlert,
88
+ } from "veloria-ui/motion";
89
+ ```
90
+
91
+ All wrappers are lazy — unused ones are fully tree-shaken from your bundle.
92
+
93
+ ---
94
+
95
+ #### `<Animated>` — conditional presence
96
+
97
+ ```tsx
98
+ import { Animated } from "veloria-ui/motion";
99
+
100
+ // Shorthand preset
101
+ <Animated show={isVisible} motion="fade-up">
102
+ <p>Animates in and out</p>
103
+ </Animated>
104
+
105
+ // Full config
106
+ <Animated show={isVisible} motion={{ preset: "fade-scale", duration: 300, delay: 100 }}>
107
+ <Card>Delayed entrance</Card>
108
+ </Animated>
109
+
110
+ // keepMounted — stays in DOM, just hidden
111
+ <Animated show={isVisible} motion="fade" keepMounted>
112
+ <ExpensivePanel />
113
+ </Animated>
114
+ ```
115
+
116
+ ---
117
+
118
+ #### `<MotionPresence>` — unmount with exit animation
119
+
120
+ ```tsx
121
+ import { MotionPresence } from "veloria-ui/motion";
122
+
123
+ <MotionPresence motion="zoom" onExitComplete={() => console.log("gone")}>
124
+ {isOpen && <Panel key="panel" />}
125
+ </MotionPresence>
126
+ ```
127
+
128
+ The child must have a stable `key` prop. When the child is removed from the tree, `MotionPresence` plays its exit animation before removing it from the DOM.
129
+
130
+ ---
131
+
132
+ #### `withMotion()` — HOC for your local components
133
+
134
+ ```tsx
135
+ import { withMotion } from "veloria-ui/motion";
136
+ import { Modal } from "@/components/ui/modal"; // your local copy
137
+
138
+ const MotionModal = withMotion(Modal, { visibleProp: "open" });
139
+
140
+ <MotionModal motion="fade-scale" open={isOpen} onOpenChange={setOpen} title="Hello" />
141
+ ```
142
+
143
+ `withMotion` watches the `visibleProp` (default `"open"`) and plays enter/exit when it changes. For non-overlay components, pass `{ visibleProp: null }` to animate only on mount.
144
+
145
+ ---
146
+
147
+ #### `stagger()` — staggered list animations
148
+
149
+ ```tsx
150
+ import { Animated, stagger } from "veloria-ui/motion";
151
+
152
+ {items.map((item, i) => (
153
+ <Animated key={item.id} motion={{ preset: "fade-up", delay: stagger(i, 60) }}>
154
+ <Card>{item.name}</Card>
155
+ </Animated>
156
+ ))}
157
+ // item 0: delay 0ms, item 1: delay 60ms, item 2: delay 120ms…
158
+ ```
159
+
160
+ ---
161
+
162
+ #### `useMotion()` — hook for custom elements
163
+
164
+ ```tsx
165
+ import { useMotion } from "veloria-ui/motion";
166
+
167
+ function MyPanel({ show }: { show: boolean }) {
168
+ const { ref, isVisible } = useMotion({
169
+ show,
170
+ motion: "slide-up",
171
+ onExitComplete: () => console.log("exit done"),
172
+ });
173
+
174
+ if (!isVisible) return null;
175
+
176
+ return <div ref={ref as React.RefObject<HTMLDivElement>}>Content</div>;
177
+ }
178
+ ```
179
+
180
+ ---
181
+
182
+ #### Imperative API
183
+
184
+ ```tsx
185
+ import { animate, resolveConfig } from "veloria-ui/motion";
186
+
187
+ // Run an animation directly on a DOM element — no React required
188
+ const config = resolveConfig("slide-up");
189
+ await animate({ el: document.getElementById("my-div")!, config, phase: "enter" });
190
+ ```
191
+
192
+ ---
193
+
194
+ #### `tsup.config.ts` — new motion entry
195
+
196
+ A dedicated tsup entry `{ motion: "src/motion/index.ts" }` produces `dist/motion.mjs` and `dist/motion.js`. The entry is completely separate from the main bundle so projects that don't use it pay zero cost.
197
+
198
+ ---
199
+
200
+ #### `package.json` — new `./motion` export
201
+
202
+ ```json
203
+ "./motion": {
204
+ "types": "./dist/motion.d.ts",
205
+ "import": "./dist/motion.mjs",
206
+ "require": "./dist/motion.js"
207
+ }
208
+ ```
209
+
210
+ No new `dependencies` or `peerDependencies` added — the motion system has zero runtime dependencies beyond React.
211
+
212
+ ### CLI — Three major UX enhancements
213
+
214
+ ---
215
+
216
+ #### `veloria-ui add` — Interactive component picker
217
+
218
+ Running `veloria-ui add` with no component names now launches a full interactive picker instead of printing a usage hint. The picker is a two-step flow built on `prompts` multiselect:
219
+
220
+ **Step 1 — Category select**
221
+
222
+ A multiselect showing all 10 categories with a live `installed/total` counter so you can see at a glance which areas of your project already have components:
223
+
224
+ ```
225
+ ? Which categories do you want to browse?
226
+ ❯ ◉ Basic 2/11 installed
227
+ ◯ Forms 0/14 installed
228
+ ◉ Feedback 1/16 installed
229
+ ◯ Data Display 0/22 installed
230
+ ```
231
+
232
+ **Step 2 — Component select per category**
233
+
234
+ For each chosen category, a multiselect shows every component with:
235
+ - A `✓` prefix on components that are already installed in your project
236
+ - A truncated description so you know what you're selecting
237
+ - A `[+deps]` hint on components that will auto-pull registry dependencies
238
+
239
+ ```
240
+ ? Basic components
241
+ ❯ ✓ button Solid, outline, ghost, soft, link, classic variants…
242
+ ◯ badge Compact label — solid, outline, soft, classic…
243
+ ◯ avatar-group Stacked avatars with overflow count [+deps]
244
+ ✓ tooltip Radix tooltip, all four sides…
245
+ ```
246
+
247
+ Already-installed components are pre-ticked but will be skipped (not re-copied) unless `--force` is passed. A summary line at the end tells you exactly which components were skipped and why.
248
+
249
+ **New `--dry-run` flag for `add`**
250
+
251
+ Added to both the interactive and direct modes. Shows what files would be written and which npm packages would be installed, without touching anything:
252
+
253
+ ```bash
254
+ npx veloria-ui add button modal --dry-run
255
+ npx veloria-ui add --dry-run # works with interactive picker too
256
+ ```
257
+
258
+ Output:
259
+ ```
260
+ Dry run — no files written.
261
+
262
+ Would copy to: components/ui/
263
+ button/index.tsx
264
+ modal/index.tsx
265
+
266
+ Would install: @radix-ui/react-slot, @radix-ui/react-dialog, clsx, …
267
+ ```
268
+
269
+ ---
36
270
 
37
- ### Architecture
271
+ #### `veloria-ui remove` — Uninstall components
38
272
 
39
- All 10 new components are **standalone files** — each lives in its own `.tsx` file alongside the relevant `index.tsx`. This means `index.tsx` re-exports them without duplicating implementation, tree-shaking works per-component, and diffs stay minimal when individual components change.
273
+ New command (alias: `rm`) to remove installed components cleanly.
40
274
 
41
- - `src/components/data-display/SparklineChart.tsx`
42
- - `src/components/data-display/RadialProgressChart.tsx`
43
- - `src/components/data-display/GaugeChart.tsx`
44
- - `src/components/data-display/AuroraCard.tsx`
45
- - `src/components/data-display/FileCard.tsx`
46
- - `src/components/data-display/PricingCard.tsx`
47
- - `src/components/forms/NumberInput.tsx`
48
- - `src/components/forms/AvatarUpload.tsx`
49
- - `src/components/feedback/StepProgress.tsx`
50
- - `src/components/utility/TypewriterText.tsx`
275
+ ```bash
276
+ npx veloria-ui remove button
277
+ npx veloria-ui remove button card modal
278
+ npx veloria-ui rm avatar-group # alias
279
+ ```
280
+
281
+ **Dependent check** — before removing, the CLI scans your other installed components for `registryDeps` entries that point to what you are about to remove. If any are found, it warns you:
282
+
283
+ ```
284
+ ⚠ The following installed components depend on what you're removing:
285
+
286
+ avatar-group → depends on avatar
287
+ command-palette → depends on command-dialog
288
+
289
+ Remove anyway? (dependents may break) › No
290
+ ```
291
+
292
+ Pass `--force` to skip the warning and remove unconditionally.
293
+
294
+ **File preview** — shows exactly which files and directories will be deleted before asking for confirmation:
295
+
296
+ ```
297
+ Files to be removed:
298
+ components/ui/button/index.tsx
299
+ components/ui/button/ (directory)
300
+ ```
301
+
302
+ **Lock cleanup** — removes the component entry from `veloria.lock.json` automatically, keeping your lock file accurate.
303
+
304
+ **Flags:**
305
+
306
+ | Flag | Description |
307
+ |------|-------------|
308
+ | `<components...>` | One or more component names to remove |
309
+ | `-y, --yes` | Skip confirmation prompt |
310
+ | `--force` | Remove even if other components depend on it |
311
+
312
+ ```bash
313
+ # Remove a single component
314
+ npx veloria-ui remove button
315
+
316
+ # Remove multiple at once
317
+ npx veloria-ui remove button card modal
318
+
319
+ # Remove without confirmation
320
+ npx veloria-ui remove skeleton --yes
321
+
322
+ # Remove even if dependents exist
323
+ npx veloria-ui remove avatar --force
324
+ ```
325
+
326
+ ---
327
+
328
+ #### `add` — Dependency graph display
329
+
330
+ Every `veloria-ui add` invocation (interactive or direct) now prints a structured dependency tree before the confirmation prompt. The tree shows:
331
+
332
+ - Which components you explicitly selected
333
+ - Which components are being auto-pulled via `registryDeps` (shown in yellow with an `(auto — registry dep)` label)
334
+ - Which npm packages will be installed as peer dependencies
335
+
336
+ ```
337
+ Adding 3 components (2 selected + 1 auto)
338
+
339
+ ├── command-bar
340
+ │ └── command-dialog (auto — registry dep)
341
+ └── avatar-group
342
+ └── avatar (auto — registry dep)
343
+
344
+ npm peer deps
345
+ ├── cmdk
346
+ ├── @radix-ui/react-dialog
347
+ └── @radix-ui/react-avatar
348
+ ```
349
+
350
+ For components with no registry deps or npm deps, the output is minimal:
351
+
352
+ ```
353
+ Adding 1 component
354
+
355
+ └── button
356
+
357
+ npm peer deps
358
+ ├── @radix-ui/react-slot
359
+ ├── class-variance-authority
360
+ ├── clsx
361
+ └── tailwind-merge
362
+ ```
363
+
364
+ This replaces the previous flat `Peer deps: …` line and makes the install plan fully transparent before anything is written to disk.
365
+
366
+ ---
367
+
368
+ ### Bug Fixes
369
+
370
+ - `add` with `--force` on a component that pulls `registryDeps` now correctly overwrites the dep files too, not only the top-level component.
371
+ - `upgrade` hint at the bottom of `list` now correctly says `npx veloria-ui add` (not `add <n>`) to reflect the new interactive mode.
372
+
373
+ ### React Hook Form Adapter — `veloria-ui/rhf`
374
+
375
+ A new optional sub-path export that provides zero-boilerplate `Controller` wrappers for every Veloria UI form component. Import from `veloria-ui/rhf` — requires `react-hook-form ^7.0.0` as an optional peer dependency.
376
+
377
+ **11 wrappers shipped:**
378
+
379
+ | Wrapper | Wraps | Notes |
380
+ |---------|-------|-------|
381
+ | `RhfInput` | `Input` + `FormField` | All `InputProps` forwarded (size, leftElement, rightElement…) |
382
+ | `RhfTextArea` | `TextArea` + `FormField` | Full resize/rows control |
383
+ | `RhfSelect` | Radix `Select` + `FormField` | `onValueChange` bridged to `field.onChange` |
384
+ | `RhfCheckbox` | `Checkbox` + `FormField` | Boolean field — `checked` ↔ `field.value` |
385
+ | `RhfSwitch` | `Switch` + `FormField` | Same boolean mapping as `RhfCheckbox` |
386
+ | `RhfRadioGroup` | `RadioGroup` + `FormField` | `onValueChange` → `field.onChange` |
387
+ | `RhfSlider` | `Slider` + `FormField` | Stores plain `number`, converts to `number[]` internally |
388
+ | `RhfCombobox` | `Combobox` + `FormField` | `onChange` bridged to `field.onChange` |
389
+ | `RhfMultiSelect` | `MultiSelect` + `FormField` | Field value is `string[]` |
390
+ | `RhfRatingInput` | `RatingInput` + `FormField` | Numeric value |
391
+ | `RhfOTPInput` | `OTPInput` + `FormField` | String value |
392
+
393
+ Every wrapper automatically maps `fieldState.error` to the component's `invalid` prop and renders `<FormError>` with the message. All original visual props (`size`, `placeholder`, `disabled`, `label`, etc.) pass straight through — no new API surface to learn.
394
+
395
+ **Usage:**
51
396
 
52
- ### CLI Registry
397
+ ```tsx
398
+ import { useForm } from "react-hook-form";
399
+ import { RhfInput, RhfSelect, RhfCheckbox } from "veloria-ui/rhf";
53
400
 
54
- All 10 new components are registered in `src/cli/registry.ts` and are available via:
401
+ const { control, handleSubmit } = useForm<{ email: string; role: string; agree: boolean }>();
402
+
403
+ <form onSubmit={handleSubmit(onSubmit)}>
404
+ <RhfInput name="email" control={control} label="Email" type="email" />
405
+ <RhfSelect name="role" control={control} label="Role" options={roles} />
406
+ <RhfCheckbox name="agree" control={control} label="I agree to the terms" />
407
+ </form>
408
+ ```
409
+
410
+ ### Build
411
+
412
+ - `veloria-ui/rhf` entry added to `exports` map in `package.json`
413
+ - New tsup build target for `src/rhf/index.ts` (CJS + ESM + DTS)
414
+ - `react-hook-form` added to `sharedExternal` — never bundled
415
+ - `veloria-ui` itself added to `sharedExternal` — prevents self-resolution error during the RHF build pass
416
+ - All `Rhf*.tsx` files import from `../index` (relative source path) rather than `"veloria-ui"` package name — eliminates circular resolve during build
417
+
418
+ ### Infrastructure
419
+
420
+ - `.npmrc` added with `public-hoist-pattern[]=tsup` and `public-hoist-pattern[]=typescript` so `pnpm install` always hoists build tool binaries to `node_modules/.bin` — fixes `tsup: not found` on Replit and similar isolated-store environments
421
+ - `react-hook-form ^7.0.0` added as optional peer dependency
422
+
423
+ ### New Components (5)
424
+
425
+ **`DataGrid`** (`data-display`)
426
+ A spreadsheet-grade table built entirely without external grid libraries. Implements row virtualisation with a configurable overscan so 100k-row datasets render at 60fps. Columns are resizable by dragging the right edge of any header. Cells are editable on double-click with Tab-to-next-cell navigation and Enter/Escape to commit/cancel. Supports multi-column sorting (click header to cycle asc/desc), row selection via a `selectedRows` Set, right-click-to-copy on any cell, a `render` slot per column for custom cell content, and animated skeleton loading rows. Zero external dependencies beyond React.
427
+
428
+ ```tsx
429
+ <DataGrid
430
+ columns={[
431
+ { key: "name", header: "Name", sortable: true, editable: true, width: 200 },
432
+ { key: "email", header: "Email", sortable: true, width: 260 },
433
+ { key: "role", header: "Role", editable: true },
434
+ { key: "status", header: "Status", render: (v) => <Badge>{String(v)}</Badge> },
435
+ ]}
436
+ rows={users}
437
+ height={480}
438
+ onChange={setUsers}
439
+ selectedRows={selected}
440
+ onRowSelect={setSelected}
441
+ />
442
+ ```
443
+
444
+ **`RichTextEditor`** (`advanced-forms`)
445
+ A Tiptap-based editor styled to match the design system. Toolbar covers headings (H1–H3), bold, italic, underline, strikethrough, inline code, text alignment (left/center/right), bullet list, ordered list, blockquote, code block with syntax highlighting via `lowlight`, link, undo/redo. A `BubbleMenu` appears on text selection for quick bold/italic/link access. Controlled via `value`/`onChange` (HTML string). Supports `minHeight`, `maxHeight` (scrollable), `disabled`, `placeholder`, and `autofocus`. All toolbar icons are inline SVG — no icon library dependency.
446
+
447
+ ```tsx
448
+ <RichTextEditor
449
+ value={html}
450
+ onChange={setHtml}
451
+ placeholder="Write something…"
452
+ minHeight={300}
453
+ />
454
+ ```
455
+
456
+ **`DateRangePicker`** (`forms`)
457
+ A full custom two-calendar date range popover — not a wrapper around a native `<input type="date">`. Renders two side-by-side month grids (configurable to one with `numberOfMonths={1}`). Selection is two-click: first click sets the anchor, second sets the end. Hover preview shows the in-range highlight as you move the cursor. Edge days (from/to) get a filled primary circle; in-range days get a tinted background strip with squared-off edges connecting to the edge circles. Supports `minDate`, `maxDate`, a `disabledDates` predicate, and a `format` override for the trigger label. Clear button appears once a range is set.
458
+
459
+ ```tsx
460
+ <DateRangePicker
461
+ value={range}
462
+ onChange={setRange}
463
+ numberOfMonths={2}
464
+ placeholder="Select date range"
465
+ />
466
+ ```
467
+
468
+ **`CommandBar`** (`overlay`)
469
+ A persistent ⌘K command bar in the style of Linear/Vercel. Renders as a floating dialog at 20% from the top. Registers `Cmd+K` / `Ctrl+K` globally via a `useCommandBar` hook that can also be called standalone. Actions are grouped, searchable by label/description/keywords, and can carry keyboard shortcut hints rendered as `<kbd>` chips. The empty-state query shows recent actions (passed as `recentIds`). Built on cmdk + Radix Dialog. Footer row shows ↑↓ navigate, ↵ select, ⌘K to open.
470
+
471
+ ```tsx
472
+ <CommandBar
473
+ actions={actions}
474
+ recentIds={recentActionIds}
475
+ open={open}
476
+ onOpenChange={setOpen}
477
+ />
478
+ ```
479
+
480
+ **`MultiStepForm`** (`advanced-forms`)
481
+ A compound component that wires Stepper + form state + per-step async validation + animated slide transitions into a single coherent API. Each step definition can include a `validate` function returning an error map; the nav button won't advance until it resolves cleanly. Shared form data accumulates across steps and is handed to `onComplete` at the end. The `useMultiStepForm` hook exposes `setField`, `setError`, `clearError`, `next`, `back`, `goTo`, and `progress` to any child. The stepper renders in two layouts: `"top"` (horizontal with connector lines) and `"left"` (vertical sidebar). Completed steps are clickable to jump back. `MultiStepFormNav` renders the Back/Continue buttons with a progress bar above them.
482
+
483
+ ```tsx
484
+ <MultiStepForm steps={steps} onComplete={handleSubmit} stepperPosition="top">
485
+ <MultiStepFormStepPanel>
486
+ <AccountFields />
487
+ </MultiStepFormStepPanel>
488
+ <MultiStepFormStepPanel>
489
+ <ProfileFields />
490
+ </MultiStepFormStepPanel>
491
+ <MultiStepFormStepPanel>
492
+ <ReviewStep />
493
+ </MultiStepFormStepPanel>
494
+ <MultiStepFormNav />
495
+ </MultiStepForm>
496
+ ```
497
+
498
+ ### Registry
499
+
500
+ Five new entries added to `src/cli/registry.ts` under `// ── v0.1.7 additions`. See `registry-additions.ts` for the exact entries to splice in.
501
+
502
+ ### Dependencies added (peer, optional per component)
503
+
504
+ | Component | New deps |
505
+ |-----------|----------|
506
+ | `RichTextEditor` | `@tiptap/react`, `@tiptap/starter-kit`, `@tiptap/extension-placeholder`, `@tiptap/extension-link`, `@tiptap/extension-underline`, `@tiptap/extension-text-align`, `@tiptap/extension-code-block-lowlight`, `lowlight` |
507
+ | `DateRangePicker` | `@radix-ui/react-popover` (already peer dep) |
508
+ | `CommandBar` | `cmdk`, `@radix-ui/react-dialog` (already peer deps) |
509
+ | `DataGrid` | none |
510
+ | `MultiStepForm` | none |
511
+
512
+ ---
513
+
514
+ ## [0.1.4] — 2026-03-17
515
+
516
+ ### CLI
517
+
518
+ #### `veloria-ui upgrade` — new command
519
+
520
+ Reads `veloria.config.json`, discovers every component you have installed, checks each one against the latest upstream source on GitHub, and prompts you to upgrade those that have changed. Modelled on `npm outdated` but for copied source files — the first component library to ship this natively.
521
+
522
+ **Discovery** — scans your components directory for sub-folders matching registry names, then cross-references `veloria.lock.json` to catch any components stored at non-standard paths. No manual component list needed.
523
+
524
+ **Three-state staleness model** powered by `veloria.lock.json` (written/updated by `add` and `upgrade`):
525
+
526
+ | State | Meaning |
527
+ |-------|---------|
528
+ | `up-to-date` | Upstream hash matches the hash recorded at install time |
529
+ | `upstream-changed` | Upstream changed since install, but your local file is unmodified — safe to auto-upgrade |
530
+ | `diverged` | Both upstream and your local file have changed — warned before overwriting |
531
+ | `no-lock` | Component pre-dates the lock file; falls back to raw content comparison |
532
+
533
+ **Interactive prompt per outdated component** — shows `+N -N` change counts and offers three choices: upgrade, show full diff first (then decide), or skip.
534
+
535
+ **Flags:**
536
+
537
+ | Flag | Description |
538
+ |------|-------------|
539
+ | `[component]` | Upgrade a single named component |
540
+ | `-y, --yes` / `--all` | Upgrade all outdated non-interactively (skips diverged unless `--force`) |
541
+ | `--check` | Dry-run — report status only, make no changes |
542
+ | `--force` | Overwrite even diverged (locally modified) components |
543
+ | `--json` | Machine-readable JSON status report |
55
544
 
56
545
  ```bash
57
- npx veloria-ui add sparkline-chart
58
- npx veloria-ui add radial-progress-chart
59
- npx veloria-ui add gauge-chart
60
- npx veloria-ui add aurora-card
61
- npx veloria-ui add pricing-card
62
- npx veloria-ui add file-card
63
- npx veloria-ui add number-input
64
- npx veloria-ui add avatar-upload
65
- npx veloria-ui add step-progress
66
- npx veloria-ui add typewriter-text
546
+ # Check what's outdated (no changes)
547
+ npx veloria-ui upgrade --check
548
+
549
+ # Interactive upgrade — prompts per component
550
+ npx veloria-ui upgrade
551
+
552
+ # Upgrade a single component
553
+ npx veloria-ui upgrade button
554
+
555
+ # Upgrade everything non-interactively
556
+ npx veloria-ui upgrade --all
557
+
558
+ # CI status report
559
+ npx veloria-ui upgrade --check --json
67
560
  ```
68
561
 
562
+ **`veloria.lock.json`** — new file written by `add` and updated by `upgrade`. Records the SHA-256 of each component's upstream source at install time, the upstream URL, and timestamps. Commit this file — it's what makes three-state upgrade detection possible.
563
+
564
+ #### `add` — updated
565
+
566
+ - Now fetches and writes real upstream source (not stubs) when GitHub is reachable.
567
+ - Records the upstream content hash and URL in `veloria.lock.json` at add time.
568
+ - Added `--force` flag to overwrite existing local files.
569
+
570
+ #### `diff` — updated
571
+
572
+ - The "To update" hint at the end of diff output now points to `npx veloria-ui upgrade <component>` instead of `add --force`.
573
+
69
574
  ---
70
575
 
71
- ## [0.1.3] — 2026-03-16
576
+ ## [0.1.4] — 2026-03-17
577
+
578
+ ### CLI
579
+
580
+ #### `veloria-ui diff <component>` — now fully implemented
581
+
582
+ Previously this command printed a "not implemented yet" warning. It is now a fully working line-by-line diff engine:
583
+
584
+ - **Fetches upstream source** directly from the GitHub raw API (`raw.githubusercontent.com`) — no npm registry round-trip needed.
585
+ - **Locates your local copy** automatically by reading `veloria.config.json` (falls back to `components/ui/<n>/index.tsx` and several other candidate paths).
586
+ - **Myers diff algorithm** — the same LCS-based algorithm used by Git. Produces the minimal edit set between your local file and the upstream source.
587
+ - **Unified-style terminal output** — colour-coded hunks (`+` in green, `-` in red) with configurable context lines, summary counts, and `···` separators between hunks.
588
+ - **`--json` flag** — machine-readable JSON output containing the full diff array and summary, suitable for CI pipelines or editor integrations.
589
+ - **`--context <n>` flag** — control how many context lines appear around each change (default: 3).
590
+ - **Graceful error handling** — clear messages when the component is not found locally (with an `add` hint), when the upstream fetch fails (with the checked URLs listed), or when the component name is unknown.
591
+ - **Multi-path resolution** — tries both a dedicated `<Component>.tsx` file and the category `index.tsx` to handle components that are co-located with siblings.
72
592
 
73
- ### Classic Variant
593
+ ```bash
594
+ # Basic usage
595
+ npx veloria-ui diff button
74
596
 
75
- Added `classic` variant across **Button**, **IconButton**, **Badge**, **Tag**, **Chip**, and **Card** components. The classic style uses beveled inset box-shadows to mimic the tactile feel of physical plastic or rubber:
76
- - Top-left inset highlight (`rgba(255,255,255,0.72)` light mode, `rgba(255,255,255,0.10)` dark)
77
- - Bottom-right inset shadow (`rgba(0,0,0,0.14)` light mode, `rgba(0,0,0,0.50)` dark)
78
- - Active/pressed state inverts the bevel to simulate a physical click-down
597
+ # More context around changes
598
+ npx veloria-ui diff modal --context 6
79
599
 
80
- New CSS utilities added to `veloria.css`:
81
- - `.veloria-classic` applies the raised bevel shadow
82
- - `.veloria-classic-pressed` — applies the pressed/inverted bevel shadow
83
- - CSS custom properties `--classic-highlight`, `--classic-shadow`, `--classic-bevel`, `--classic-bevel-pressed` — all responsive to dark mode
600
+ # CI-friendly JSON output
601
+ npx veloria-ui diff input --json
602
+ ```
84
603
 
85
- ### Select Dropdown Redesign
604
+ ---
86
605
 
87
- Replaced the system-native OS picker with a fully custom animated dropdown:
88
- - Layered `box-shadow` (soft ambient + key shadow, separate dark mode values)
89
- - Open animation: `fade-in-0` + `zoom-in-[0.97]` + directional slide from trigger
90
- - Close animation: `fade-out-0` + `zoom-out-95` + reverse slide
91
- - `SelectScrollUpButton` / `SelectScrollDownButton` — appear when list overflows, replacing the OS scrollbar
92
- - Chevron icon rotates 180° when dropdown is open (CSS rule on `.atlas-select-trigger[data-state="open"] svg`)
93
- - `SelectLabel` styled as uppercase tracking-widened group headers
94
- - Max height capped to `min(available-height, 18rem)` to prevent off-screen overflow
606
+ ## [0.1.3] — 2026-03-16 (Edited)
95
607
 
96
608
  ### Branding & Naming
97
609
 
@@ -105,16 +617,15 @@ Replaced the system-native OS picker with a fully custom animated dropdown:
105
617
  - Renamed localStorage theme key from `atlas-theme` to `veloria-theme`
106
618
  - Removed legacy `atlas` bin alias from `package.json`
107
619
  - Updated all homepage and docs URLs to `https://ui-veloria.vercel.app/`
620
+ - Removed hardcoded component count from descriptions and CLI copy
108
621
 
109
622
  ### Bug Fixes
110
623
 
111
624
  - Fixed `TypeError: Cannot read properties of null (reading 'matches')` — `window.matchMedia` now uses optional chaining (`?.`) in `useTheme` and an explicit null guard in `useMediaQuery`, preventing crashes in jsdom and certain SSR environments
112
- - Fixed `TS2430` on `StatisticProps` — added `Omit<..., "prefix">` to resolve conflict with `HTMLAttributes.prefix`
113
- - Fixed `TS2430` on `CalendarProps` — added `Omit<..., "onChange">` to resolve conflict with `HTMLAttributes.onChange`
114
625
 
115
626
  ---
116
627
 
117
- ## [0.1.2] — 2026-03-15
628
+ ## [0.1.2] — 2026-03-15 (UPDATED)
118
629
 
119
630
  ### New Components (20)
120
631
 
@@ -153,7 +664,7 @@ Replaced the system-native OS picker with a fully custom animated dropdown:
153
664
 
154
665
  ---
155
666
 
156
- ## [0.1.1] — 2026-03-13
667
+ ## [0.1.1] — 2026-03-13 (UPDATED)
157
668
 
158
669
  ### Build fixes
159
670
 
@@ -171,3 +682,143 @@ Replaced the system-native OS picker with a fully custom animated dropdown:
171
682
  ### Initial Release
172
683
 
173
684
  First public release of Veloria UI. A full CLI, hooks, a Tailwind plugin, and a complete CSS token system with light + dark mode.
685
+
686
+ ---
687
+
688
+ #### veloria-ui
689
+
690
+ **Basic (10)**
691
+ - `Button` — solid, outline, ghost, soft, link, danger variants · sizes xs–xl · loading state · left/right icon slots
692
+ - `IconButton` — square or circular icon-only button with all button variants
693
+ - `Link` — anchor with external link indicator and underline control
694
+ - `Badge` — compact label with 5 color variants and optional dot
695
+ - `Avatar` — image with fallback initials, online/offline status ring, 6 sizes
696
+ - `AvatarGroup` — stacked avatar row with overflow count
697
+ - `Divider` — horizontal/vertical with optional center label
698
+ - `Tag` — closable colored tag with icon slot
699
+ - `Chip` — toggleable with avatar/icon support and remove button
700
+ - `Tooltip` — Radix-powered, all four sides, configurable delay
701
+
702
+ **Layout (10)**
703
+ - `Container` — responsive max-width wrapper with padding control
704
+ - `Stack` — flex column/row with gap, align, justify, and divider support
705
+ - `Grid` — CSS Grid with column/row/gap config
706
+ - `Flex` — inline flex with full directional control
707
+ - `Section` — semantic `<section>` with vertical padding presets
708
+ - `Spacer` — invisible spacer
709
+ - `AspectRatio` — Radix aspect-ratio wrapper
710
+ - `Center` — flex centering helper
711
+ - `ScrollArea` — custom scrollbar via Radix ScrollArea
712
+ - `Masonry` — CSS multi-column masonry grid
713
+
714
+ **Navigation (10)**
715
+ - `Navbar` — sticky + glass-blur top bar
716
+ - `Sidebar` — collapsible with width transition
717
+ - `Menu` / `MenuItem` — vertical nav with active/disabled states
718
+ - `DropdownMenu` — full Radix Dropdown with all sub-primitives
719
+ - `Breadcrumb` — accessible trail with custom separator
720
+ - `Pagination` — page numbers, ellipsis, prev/next
721
+ - `Tabs` — line, pills, enclosed variants · Radix powered
722
+ - `Stepper` — horizontal/vertical multi-step progress indicator
723
+ - `CommandDialog` — ⌘K command palette via cmdk
724
+
725
+ **Forms (10)**
726
+ - `Input` — left/right icon slots, sizes, error state
727
+ - `TextArea` — resize control, error state
728
+ - `Select` — full Radix Select with all sub-primitives
729
+ - `Checkbox` — with label, description, error state
730
+ - `RadioGroup` — per-option labels and descriptions
731
+ - `Switch` — three sizes, label, description
732
+ - `Slider` — range slider
733
+ - `RangeSlider` — dual-thumb slider
734
+ - `DatePicker` — calendar popover with keyboard navigation
735
+ - `TimePicker` — hour/minute/second with AM/PM toggle
736
+
737
+ **Advanced Forms (10)**
738
+ - `FileUpload` — drag-and-drop with preview, size limit, MIME type filter
739
+ - `OTPInput` — SMS-style one-time-password input
740
+ - `ColorPicker` — HEX/RGB/HSL input with swatch palette
741
+ - `SearchInput` — debounced search with clear button
742
+ - `PasswordInput` — toggle visibility with strength meter
743
+ - `Combobox` — searchable dropdown with keyboard navigation
744
+ - `MultiSelect` — tag-style multi-value select
745
+ - `FormField` — label + input + error wrapper
746
+ - `FormLabel` — accessible label
747
+ - `FormError` — error message slot
748
+
749
+ **Data Display (10)**
750
+ - `Card` / `CardHeader` / `CardContent` / `CardFooter`
751
+ - `Table` — sortable columns, sticky header
752
+ - `DataTable` — full-featured table with pagination and row selection
753
+ - `List` / `ListItem`
754
+ - `Statistic` — large number with label and trend
755
+ - `Timeline` — vertical event list
756
+ - `Calendar` — month grid with event dots
757
+ - `Chart` — wrapper around Recharts with theme tokens
758
+ - `CodeBlock` — syntax-highlighted code with copy button
759
+
760
+ **Feedback (10)**
761
+ - `Alert` — inline alert with 5 variants and icon slot
762
+ - `Toast` — Radix Toast with 5 variants · programmatic via `useToast`
763
+ - `Snackbar` — bottom-anchored status message
764
+ - `Progress` — linear with animated fill
765
+ - `CircularProgress` — SVG ring with percentage label
766
+ - `Skeleton` — text, rect, circle variants
767
+ - `LoadingSpinner` — 4 sizes · 3 variants
768
+ - `EmptyState` — icon + title + description + action slot
769
+ - `StatusIndicator` — colored dot with pulse animation
770
+ - `Notification` — card-style notification with timestamp
771
+
772
+ **Overlay (10)**
773
+ - `Modal` — centered dialog with close button
774
+ - `Dialog` — full Radix Dialog with all sub-primitives
775
+ - `Drawer` — side-sheet with 4 sides
776
+ - `Sheet` — lightweight Drawer alias
777
+ - `Popover` — Radix Popover
778
+ - `HoverCard` — hover-triggered card
779
+ - `ContextMenu` — right-click menu via Radix
780
+ - `CommandDialog` — ⌘K palette
781
+ - `Lightbox` — full-screen image viewer with zoom
782
+ - `ImageViewer` — in-place image pan and zoom
783
+
784
+ **Media (5)**
785
+ - `Image` — next/image wrapper with blur placeholder and fallback
786
+ - `VideoPlayer` — custom controls, poster, autoplay, loop, track support
787
+ - `AudioPlayer` — custom UI with seek bar, cover art
788
+ - `Carousel` — autoplay, dots, arrows, loop, slidesPerView
789
+ - `Gallery` — responsive image grid with click handler
790
+
791
+ **Utility (5)**
792
+ - `ThemeSwitcher` — icon / toggle / select variants
793
+ - `CopyButton` — icon or labelled button with success feedback
794
+ - `KeyboardShortcut` — styled `<kbd>` shortcut display
795
+ - `ResizablePanel` — drag-to-resize with min/max constraints
796
+ - `DragDropArea` — accessible file drop zone
797
+
798
+ #### Hooks
799
+ - `useDisclosure` — open/close state management
800
+ - `useMediaQuery` — window media query subscription
801
+ - `useBreakpoint` — Tailwind breakpoint helper
802
+ - `useClipboard` — clipboard copy with timeout feedback
803
+ - `useLocalStorage` — persistent state
804
+ - `useTheme` — theme switching (persists to localStorage)
805
+ - `useDebounce` — debounced value
806
+ - `useOnClickOutside` — outside click detection
807
+ - `useKeydown` — keyboard shortcut listener with modifier support
808
+ - `useMounted` — SSR-safe mount check
809
+ - `useToast` — programmatic toast notifications
810
+
811
+ #### Infrastructure
812
+ - Tailwind CSS plugin + preset (`veloriaPlugin`, `veloriaPreset`)
813
+ - Full CSS design token system — light and dark themes
814
+ - `VeloriaProvider` for Next.js App Router
815
+ - TypeScript strict throughout — full named type exports
816
+ - Tree-shakeable ESM + CJS dual build via tsup
817
+ - Turbo monorepo setup
818
+
819
+ #### veloria-ui CLI
820
+ - `init` — project setup wizard (detects Next.js, writes veloria.config.json)
821
+ - `add` — copies components + installs npm deps, resolves Veloria UI peer deps
822
+ - `list` — browse all components filtered by category
823
+ - `diff` — compare local copy to latest (registry fetch, coming soon)
824
+ - Auto-detects npm / pnpm / yarn / bun