veloria-ui 0.1.3 → 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.
- package/CHANGELOG.md +596 -0
- package/README.md +72 -78
- package/dist/cli/index.js +946 -228
- package/dist/index.d.mts +419 -60
- package/dist/index.d.ts +419 -60
- package/dist/index.js +4604 -1510
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +4574 -1509
- package/dist/index.mjs.map +1 -1
- package/dist/motion.d.mts +286 -0
- package/dist/motion.d.ts +286 -0
- package/dist/motion.js +655 -0
- package/dist/motion.js.map +1 -0
- package/dist/motion.mjs +601 -0
- package/dist/motion.mjs.map +1 -0
- package/dist/provider.js +288 -209
- package/dist/provider.js.map +1 -1
- package/dist/provider.mjs +288 -209
- package/dist/provider.mjs.map +1 -1
- package/dist/rhf.d.mts +202 -0
- package/dist/rhf.d.ts +202 -0
- package/dist/rhf.js +1598 -0
- package/dist/rhf.js.map +1 -0
- package/dist/rhf.mjs +1561 -0
- package/dist/rhf.mjs.map +1 -0
- package/dist/tailwind.js +9 -4
- package/package.json +216 -29
- package/src/cli/index.ts +962 -91
- package/src/cli/registry.ts +147 -103
- package/src/components/advanced-forms/MultiStepForm.tsx +445 -0
- package/src/components/advanced-forms/RichTextEditor.tsx +461 -0
- package/src/components/advanced-forms/index.tsx +6 -0
- package/src/components/basic/Button.tsx +13 -7
- package/src/components/basic/IconButton.tsx +8 -1
- package/src/components/basic/index.tsx +120 -92
- package/src/components/data-display/AuroraCard.tsx +117 -0
- package/src/components/data-display/DataGrid.tsx +381 -0
- package/src/components/data-display/FileCard.tsx +231 -0
- package/src/components/data-display/GaugeChart.tsx +254 -0
- package/src/components/data-display/PricingCard.tsx +181 -0
- package/src/components/data-display/RadialProgressChart.tsx +175 -0
- package/src/components/data-display/SparklineChart.tsx +139 -0
- package/src/components/data-display/index.tsx +470 -470
- package/src/components/feedback/StepProgress.tsx +96 -0
- package/src/components/feedback/index.tsx +194 -144
- package/src/components/forms/AvatarUpload.tsx +251 -0
- package/src/components/forms/DateRangePicker.tsx +355 -0
- package/src/components/forms/NumberInput.tsx +181 -0
- package/src/components/forms/index.tsx +296 -100
- package/src/components/overlay/CommandBar.tsx +241 -0
- package/src/components/overlay/index.tsx +3 -0
- package/src/components/utility/TypewriterText.tsx +121 -0
- package/src/components/utility/index.tsx +108 -95
- package/src/index.ts +53 -1
- package/src/motion/Animated.tsx +77 -0
- package/src/motion/MotionPresence.tsx +144 -0
- package/src/motion/components.tsx +203 -0
- package/src/motion/engine.ts +150 -0
- package/src/motion/index.ts +57 -0
- package/src/motion/presets.ts +220 -0
- package/src/motion/types.ts +117 -0
- package/src/motion/useMotion.ts +120 -0
- package/src/motion/withMotion.tsx +133 -0
- package/src/rhf/RhfCheckbox.tsx +49 -0
- package/src/rhf/RhfCombobox.tsx +52 -0
- package/src/rhf/RhfInput.tsx +44 -0
- package/src/rhf/RhfMultiSelect.tsx +43 -0
- package/src/rhf/RhfOTPInput.tsx +43 -0
- package/src/rhf/RhfRadioGroup.tsx +48 -0
- package/src/rhf/RhfRatingInput.tsx +43 -0
- package/src/rhf/RhfSelect.tsx +85 -0
- package/src/rhf/RhfSlider.tsx +68 -0
- package/src/rhf/RhfSwitch.tsx +48 -0
- package/src/rhf/RhfTextArea.tsx +44 -0
- package/src/rhf/index.ts +38 -0
- package/src/styles/veloria.css +93 -82
- package/src/tailwind.ts +45 -23
- package/dist/tailwind.d.ts +0 -25
package/CHANGELOG.md
CHANGED
|
@@ -7,6 +7,602 @@ This project follows [Semantic Versioning](https://semver.org).
|
|
|
7
7
|
|
|
8
8
|
---
|
|
9
9
|
|
|
10
|
+
## [0.1.5] — 2026-03-17
|
|
11
|
+
|
|
12
|
+
### `veloria-ui/motion` — Animated presence system
|
|
13
|
+
|
|
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.
|
|
15
|
+
|
|
16
|
+
Import from `veloria-ui/motion`:
|
|
17
|
+
|
|
18
|
+
```ts
|
|
19
|
+
import {
|
|
20
|
+
Animated, MotionPresence, withMotion, useMotion,
|
|
21
|
+
MotionModal, MotionDrawer, MotionCard, MotionToast,
|
|
22
|
+
stagger, PRESETS, DURATIONS,
|
|
23
|
+
} from "veloria-ui/motion";
|
|
24
|
+
```
|
|
25
|
+
|
|
26
|
+
---
|
|
27
|
+
|
|
28
|
+
#### Architecture — 9 files, one entry point
|
|
29
|
+
|
|
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
|
+
---
|
|
270
|
+
|
|
271
|
+
#### `veloria-ui remove` — Uninstall components
|
|
272
|
+
|
|
273
|
+
New command (alias: `rm`) to remove installed components cleanly.
|
|
274
|
+
|
|
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:**
|
|
396
|
+
|
|
397
|
+
```tsx
|
|
398
|
+
import { useForm } from "react-hook-form";
|
|
399
|
+
import { RhfInput, RhfSelect, RhfCheckbox } from "veloria-ui/rhf";
|
|
400
|
+
|
|
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 |
|
|
544
|
+
|
|
545
|
+
```bash
|
|
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
|
|
560
|
+
```
|
|
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
|
+
|
|
574
|
+
---
|
|
575
|
+
|
|
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.
|
|
592
|
+
|
|
593
|
+
```bash
|
|
594
|
+
# Basic usage
|
|
595
|
+
npx veloria-ui diff button
|
|
596
|
+
|
|
597
|
+
# More context around changes
|
|
598
|
+
npx veloria-ui diff modal --context 6
|
|
599
|
+
|
|
600
|
+
# CI-friendly JSON output
|
|
601
|
+
npx veloria-ui diff input --json
|
|
602
|
+
```
|
|
603
|
+
|
|
604
|
+
---
|
|
605
|
+
|
|
10
606
|
## [0.1.3] — 2026-03-16 (Edited)
|
|
11
607
|
|
|
12
608
|
### Branding & Naming
|