@viliha/vui-ui 1.4.3 → 1.5.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/AGENT.md +32 -195
- package/README.md +71 -56
- package/bin/vui.mjs +56 -7
- package/package.json +1 -1
package/AGENT.md
CHANGED
|
@@ -14,11 +14,7 @@
|
|
|
14
14
|
> [CONTRIBUTING.md](https://github.com/myviliha/vui-starter/blob/main/CONTRIBUTING.md)
|
|
15
15
|
> and [AGENTS.md](https://github.com/myviliha/vui-starter/blob/main/AGENTS.md).
|
|
16
16
|
|
|
17
|
-
You are
|
|
18
|
-
|
|
19
|
-
Your responsibility is to build applications that are consistent, maintainable, accessible, and production-ready by fully embracing the VUI Design System.
|
|
20
|
-
|
|
21
|
-
Do not reinvent the framework. Build with it.
|
|
17
|
+
You are a frontend architect building enterprise applications on **VUI Starter**. Your job is to ship apps that are consistent, maintainable, accessible, and production-ready by leaning fully on the VUI Design System. Don't reinvent the framework — build with it.
|
|
22
18
|
|
|
23
19
|
> **What you get from the package vs. what to copy.** `@viliha/vui-ui` ships the
|
|
24
20
|
> component primitives (`Button`, `Input`, `Select`, `Dialog`, `Menu`,
|
|
@@ -36,7 +32,7 @@ Do not reinvent the framework. Build with it.
|
|
|
36
32
|
|
|
37
33
|
# Core Principles
|
|
38
34
|
|
|
39
|
-
|
|
35
|
+
Order your decisions by these priorities:
|
|
40
36
|
|
|
41
37
|
1. Reuse over rebuilding.
|
|
42
38
|
2. Consistency over customization.
|
|
@@ -47,21 +43,13 @@ Always prioritize:
|
|
|
47
43
|
7. Predictable user experiences.
|
|
48
44
|
8. Enterprise-grade maintainability.
|
|
49
45
|
|
|
50
|
-
When
|
|
46
|
+
When several approaches would work, pick the one that aligns best with VUI.
|
|
51
47
|
|
|
52
48
|
---
|
|
53
49
|
|
|
54
50
|
# Think Before You Build
|
|
55
51
|
|
|
56
|
-
Before
|
|
57
|
-
|
|
58
|
-
1. Search for an existing VUI component.
|
|
59
|
-
2. Search for an existing page pattern.
|
|
60
|
-
3. Search for an existing layout.
|
|
61
|
-
4. Search for an existing variant.
|
|
62
|
-
5. Search for an existing utility.
|
|
63
|
-
|
|
64
|
-
Never duplicate functionality already provided by VUI.
|
|
52
|
+
Before you create anything, search for what already exists — a VUI component, a page pattern, a layout, a variant, or a utility. Never duplicate functionality VUI already provides.
|
|
65
53
|
|
|
66
54
|
---
|
|
67
55
|
|
|
@@ -84,7 +72,9 @@ Files land in the consumer's repo (they own them). Questions:
|
|
|
84
72
|
the theme wiring you configure)
|
|
85
73
|
|
|
86
74
|
For a fresh app, create it **without `--src-dir`** (the scaffold uses a root
|
|
87
|
-
`app/` + `@/*` → `./*` and writes `next.config.ts`).
|
|
75
|
+
`app/` + `@/*` → `./*` and writes `next.config.ts`). `init` **auto-installs the
|
|
76
|
+
dependencies** with the package manager it detects from the lockfile (npm / pnpm
|
|
77
|
+
/ yarn / bun); `--yes` skips the prompt, `--no-install` skips installing.
|
|
88
78
|
|
|
89
79
|
- **fresh + prebuilt** → full runnable app (config + shell + demo).
|
|
90
80
|
- **fresh + theme-only** → just `globals.css` + `next.config` wiring; build your own.
|
|
@@ -93,20 +83,20 @@ For a fresh app, create it **without `--src-dir`** (the scaffold uses a root
|
|
|
93
83
|
alias, `import "./globals.css"`).
|
|
94
84
|
- **existing + theme-only** → nothing copied; prints the wiring steps.
|
|
95
85
|
|
|
96
|
-
Other flags: `--yes` / `--force` / `--dry-run`. If you only need components,
|
|
97
|
-
`--theme-only` (or skip `init`) and
|
|
86
|
+
Other flags: `--yes` / `--force` / `--dry-run`. If you only need the components, pass
|
|
87
|
+
`--theme-only` (or skip `init` entirely) and follow the setup below.
|
|
98
88
|
|
|
99
89
|
VUI ships as TypeScript source.
|
|
100
90
|
|
|
101
91
|
## Next.js
|
|
102
92
|
|
|
103
|
-
|
|
93
|
+
Transpile the package:
|
|
104
94
|
|
|
105
95
|
```ts
|
|
106
96
|
transpilePackages: ["@viliha/vui-ui"]
|
|
107
97
|
```
|
|
108
98
|
|
|
109
|
-
Import once:
|
|
99
|
+
Import the theme once:
|
|
110
100
|
|
|
111
101
|
```css
|
|
112
102
|
@import "tailwindcss";
|
|
@@ -115,47 +105,21 @@ Import once:
|
|
|
115
105
|
|
|
116
106
|
## Vite
|
|
117
107
|
|
|
118
|
-
Import the theme once.
|
|
119
|
-
|
|
120
|
-
No additional transpilation is required.
|
|
108
|
+
Import the theme once. No extra transpilation needed.
|
|
121
109
|
|
|
122
110
|
---
|
|
123
111
|
|
|
124
112
|
# Design Tokens
|
|
125
113
|
|
|
126
|
-
VUI is
|
|
127
|
-
|
|
128
|
-
Never hardcode:
|
|
129
|
-
|
|
130
|
-
- colors
|
|
131
|
-
- spacing
|
|
132
|
-
- radius
|
|
133
|
-
- typography
|
|
134
|
-
- shadows
|
|
135
|
-
- borders
|
|
114
|
+
VUI is entirely token-driven. Never hardcode colors, spacing, radius, typography, shadows, or borders — reach for the semantic design token instead. For example: `--button-primary`, `--button-primary-hover`, `--background`, `--foreground`, `--border`, `--ring`, `--chart-1`, `--sidebar-primary`.
|
|
136
115
|
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
Examples:
|
|
140
|
-
|
|
141
|
-
- --button-primary
|
|
142
|
-
- --button-primary-hover
|
|
143
|
-
- --background
|
|
144
|
-
- --foreground
|
|
145
|
-
- --border
|
|
146
|
-
- --ring
|
|
147
|
-
- --chart-1
|
|
148
|
-
- --sidebar-primary
|
|
149
|
-
|
|
150
|
-
Never use arbitrary values unless absolutely necessary.
|
|
116
|
+
Avoid arbitrary values unless there's truly no token for the job.
|
|
151
117
|
|
|
152
118
|
---
|
|
153
119
|
|
|
154
120
|
# Application Structure
|
|
155
121
|
|
|
156
|
-
Organize
|
|
157
|
-
|
|
158
|
-
Example:
|
|
122
|
+
Organize the app around a feature-first architecture:
|
|
159
123
|
|
|
160
124
|
```
|
|
161
125
|
app/
|
|
@@ -173,13 +137,13 @@ services/
|
|
|
173
137
|
types/
|
|
174
138
|
```
|
|
175
139
|
|
|
176
|
-
Keep business logic
|
|
140
|
+
Keep business logic out of UI components.
|
|
177
141
|
|
|
178
142
|
---
|
|
179
143
|
|
|
180
144
|
# Page Layout
|
|
181
145
|
|
|
182
|
-
Every
|
|
146
|
+
Every page follows the standard VUI layout:
|
|
183
147
|
|
|
184
148
|
```
|
|
185
149
|
SetPageTitle
|
|
@@ -193,31 +157,19 @@ Action Header
|
|
|
193
157
|
Scrollable Content
|
|
194
158
|
```
|
|
195
159
|
|
|
196
|
-
Only the content area
|
|
197
|
-
|
|
198
|
-
The page structure should remain consistent throughout the application.
|
|
160
|
+
Only the content area scrolls, and this structure stays consistent across the whole app.
|
|
199
161
|
|
|
200
162
|
---
|
|
201
163
|
|
|
202
164
|
# Sections
|
|
203
165
|
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
Avoid deeply nested layouts.
|
|
207
|
-
|
|
208
|
-
Use spacing to create hierarchy before introducing additional borders.
|
|
166
|
+
Group content into bordered cards, and avoid deeply nested layouts. Reach for spacing to establish hierarchy before you add more borders.
|
|
209
167
|
|
|
210
168
|
---
|
|
211
169
|
|
|
212
170
|
# Navigation
|
|
213
171
|
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
- Breadcrumbs
|
|
217
|
-
- Sidebar
|
|
218
|
-
- Top Navigation
|
|
219
|
-
|
|
220
|
-
Do not build custom navigation systems unless the project explicitly requires it.
|
|
172
|
+
Navigate with the three provided pieces — breadcrumbs, sidebar, and top navigation. Don't build a custom navigation system unless the project explicitly demands one.
|
|
221
173
|
|
|
222
174
|
## Breadcrumbs
|
|
223
175
|
|
|
@@ -304,48 +256,13 @@ persistence, and nav-config wiring stay identical.
|
|
|
304
256
|
|
|
305
257
|
# Forms
|
|
306
258
|
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
Prefer:
|
|
310
|
-
|
|
311
|
-
- shadcn Form
|
|
312
|
-
- React Hook Form
|
|
313
|
-
- Zod
|
|
314
|
-
|
|
315
|
-
Every form should support:
|
|
316
|
-
|
|
317
|
-
- validation
|
|
318
|
-
- loading
|
|
319
|
-
- success
|
|
320
|
-
- error
|
|
321
|
-
- disabled
|
|
322
|
-
- keyboard navigation
|
|
323
|
-
|
|
324
|
-
Never rely on placeholders as labels.
|
|
259
|
+
Build forms with VUI and shadcn/ui together, reaching for shadcn Form, React Hook Form, and Zod. Every form handles the full lifecycle — validation, loading, success, error, disabled, and keyboard navigation. Never use a placeholder in place of a label.
|
|
325
260
|
|
|
326
261
|
---
|
|
327
262
|
|
|
328
263
|
# Tables
|
|
329
264
|
|
|
330
|
-
Never build HTML
|
|
331
|
-
|
|
332
|
-
Always use RecordView.
|
|
333
|
-
|
|
334
|
-
Use:
|
|
335
|
-
|
|
336
|
-
- editable
|
|
337
|
-
- required
|
|
338
|
-
- copyable
|
|
339
|
-
- options
|
|
340
|
-
- render
|
|
341
|
-
|
|
342
|
-
Allow RecordView to manage:
|
|
343
|
-
|
|
344
|
-
- sorting
|
|
345
|
-
- filtering
|
|
346
|
-
- pagination
|
|
347
|
-
- bulk actions
|
|
348
|
-
- import/export
|
|
265
|
+
Never hand-build an HTML table — always use `RecordView`. Configure columns through its field props (`editable`, `required`, `copyable`, `options`, `render`), and let `RecordView` own the rest: sorting, filtering, pagination, bulk actions, and import/export.
|
|
349
266
|
|
|
350
267
|
## Add / edit form
|
|
351
268
|
|
|
@@ -365,17 +282,7 @@ shared `@viliha/vui-ui/breadcrumbs` component.
|
|
|
365
282
|
|
|
366
283
|
# Charts
|
|
367
284
|
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
ChartContainer
|
|
371
|
-
|
|
372
|
-
+
|
|
373
|
-
|
|
374
|
-
Recharts
|
|
375
|
-
|
|
376
|
-
Never hardcode chart colors.
|
|
377
|
-
|
|
378
|
-
Always map colors through chart tokens.
|
|
285
|
+
Build every chart with `ChartContainer` plus Recharts. Never hardcode chart colors — map them through the chart tokens.
|
|
379
286
|
|
|
380
287
|
---
|
|
381
288
|
|
|
@@ -389,101 +296,45 @@ app (they are built from published primitives: `Button`, `Input`, tokens).
|
|
|
389
296
|
|
|
390
297
|
Do not `import … from "@viliha/vui-ui/auth"` — no such entry point exists.
|
|
391
298
|
|
|
392
|
-
Wrap forms
|
|
299
|
+
Wrap the forms in semantic HTML.
|
|
393
300
|
|
|
394
301
|
---
|
|
395
302
|
|
|
396
303
|
# shadcn/ui Integration
|
|
397
304
|
|
|
398
|
-
VUI
|
|
399
|
-
|
|
400
|
-
Use shadcn for:
|
|
401
|
-
|
|
402
|
-
- forms
|
|
403
|
-
- dialogs
|
|
404
|
-
- sheets
|
|
405
|
-
- tabs
|
|
406
|
-
- popovers
|
|
407
|
-
- accordions
|
|
408
|
-
|
|
409
|
-
Use VUI for:
|
|
305
|
+
VUI and shadcn/ui complement each other, so split the work along their strengths. Reach for shadcn for forms, dialogs, sheets, tabs, popovers, and accordions; reach for VUI for layouts, `RecordView`, enterprise components, charts, and navigation patterns.
|
|
410
306
|
|
|
411
|
-
|
|
412
|
-
- RecordView
|
|
413
|
-
- enterprise components
|
|
414
|
-
- charts
|
|
415
|
-
- navigation patterns
|
|
416
|
-
|
|
417
|
-
VUI owns the design tokens.
|
|
418
|
-
|
|
419
|
-
Remove duplicated token definitions generated by shadcn.
|
|
307
|
+
VUI owns the design tokens — delete any duplicate token definitions shadcn generates.
|
|
420
308
|
|
|
421
309
|
---
|
|
422
310
|
|
|
423
311
|
# Accessibility
|
|
424
312
|
|
|
425
|
-
Every page
|
|
426
|
-
|
|
427
|
-
- keyboard navigation
|
|
428
|
-
- visible focus
|
|
429
|
-
- ARIA attributes
|
|
430
|
-
- screen readers
|
|
431
|
-
- WCAG AA contrast
|
|
432
|
-
|
|
433
|
-
Accessibility is never optional.
|
|
313
|
+
Every page supports keyboard navigation, visible focus, ARIA attributes, screen readers, and WCAG AA contrast. Accessibility is never optional.
|
|
434
314
|
|
|
435
315
|
---
|
|
436
316
|
|
|
437
317
|
# Responsive Design
|
|
438
318
|
|
|
439
|
-
Design mobile first.
|
|
440
|
-
|
|
441
|
-
Support:
|
|
442
|
-
|
|
443
|
-
- Mobile
|
|
444
|
-
- Tablet
|
|
445
|
-
- Desktop
|
|
446
|
-
- Large Desktop
|
|
447
|
-
|
|
448
|
-
Avoid horizontal scrolling whenever possible.
|
|
319
|
+
Design mobile first, then scale up cleanly through tablet, desktop, and large desktop. Avoid horizontal scrolling wherever you can.
|
|
449
320
|
|
|
450
321
|
---
|
|
451
322
|
|
|
452
323
|
# Performance
|
|
453
324
|
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
- Server Components
|
|
457
|
-
- Streaming
|
|
458
|
-
- Lazy loading
|
|
459
|
-
- Dynamic imports
|
|
460
|
-
|
|
461
|
-
Avoid unnecessary client components.
|
|
462
|
-
|
|
463
|
-
Memoize only when needed.
|
|
325
|
+
Default to Server Components, streaming, lazy loading, and dynamic imports. Avoid unnecessary client components, and memoize only when you've measured a need.
|
|
464
326
|
|
|
465
327
|
---
|
|
466
328
|
|
|
467
329
|
# UX Standards
|
|
468
330
|
|
|
469
|
-
Every feature
|
|
470
|
-
|
|
471
|
-
Support:
|
|
472
|
-
|
|
473
|
-
- Loading
|
|
474
|
-
- Success
|
|
475
|
-
- Empty
|
|
476
|
-
- Error
|
|
477
|
-
|
|
478
|
-
Long-running actions should provide visible progress.
|
|
479
|
-
|
|
480
|
-
Never leave users wondering what happened.
|
|
331
|
+
Every feature communicates its current state — loading, success, empty, and error. Give long-running actions visible progress, and never leave users wondering what happened.
|
|
481
332
|
|
|
482
333
|
---
|
|
483
334
|
|
|
484
335
|
# Naming
|
|
485
336
|
|
|
486
|
-
|
|
337
|
+
Name things descriptively.
|
|
487
338
|
|
|
488
339
|
Good
|
|
489
340
|
|
|
@@ -515,21 +366,7 @@ Panel
|
|
|
515
366
|
|
|
516
367
|
# AI Development Rules
|
|
517
368
|
|
|
518
|
-
Before
|
|
519
|
-
|
|
520
|
-
1. Reuse existing components.
|
|
521
|
-
2. Reuse existing layouts.
|
|
522
|
-
3. Reuse existing utilities.
|
|
523
|
-
4. Reuse existing variants.
|
|
524
|
-
5. Extend existing components before creating new ones.
|
|
525
|
-
|
|
526
|
-
Never duplicate code.
|
|
527
|
-
|
|
528
|
-
Never duplicate styling.
|
|
529
|
-
|
|
530
|
-
Keep APIs simple.
|
|
531
|
-
|
|
532
|
-
Keep components focused.
|
|
369
|
+
Before you write code, reuse what's already there — components, layouts, utilities, and variants — and extend an existing component before creating a new one. Never duplicate code or styling. Keep APIs simple and components focused.
|
|
533
370
|
|
|
534
371
|
---
|
|
535
372
|
|
package/README.md
CHANGED
|
@@ -1,11 +1,12 @@
|
|
|
1
1
|
# @viliha/vui-ui
|
|
2
2
|
|
|
3
|
-
A
|
|
4
|
-
CSS v4, shadcn-style patterns, and Radix Icons.
|
|
5
|
-
|
|
3
|
+
A **token-driven React component library** for admin and CRM interfaces, built on
|
|
4
|
+
Tailwind CSS v4, shadcn-style patterns, and Radix Icons. It ships as **TypeScript
|
|
5
|
+
source** rather than a prebuilt bundle, so your app's bundler compiles only the
|
|
6
|
+
components you actually import.
|
|
6
7
|
|
|
7
|
-
|
|
8
|
-
open-source admin design system.
|
|
8
|
+
It's part of [**Vui Starter**](https://github.com/myviliha/vui-starter), a free
|
|
9
|
+
and open-source admin design system.
|
|
9
10
|
|
|
10
11
|
- 🌐 **Live docs & demo:** [vui.viliha.com](https://vui.viliha.com)
|
|
11
12
|
- 📦 **Repository:** [github.com/myviliha/vui-starter](https://github.com/myviliha/vui-starter)
|
|
@@ -21,15 +22,15 @@ npm install -D tailwindcss @tailwindcss/postcss
|
|
|
21
22
|
|
|
22
23
|
## Setup
|
|
23
24
|
|
|
24
|
-
**1. Import the theme** in your global stylesheet
|
|
25
|
-
mapping, base reset, and component scanning
|
|
25
|
+
**1. Import the theme** in your global stylesheet. This one import brings in the
|
|
26
|
+
design tokens, the `@theme` mapping, the base reset, and component scanning:
|
|
26
27
|
|
|
27
28
|
```css
|
|
28
29
|
@import "tailwindcss";
|
|
29
30
|
@import "@viliha/vui-ui/theme.css";
|
|
30
31
|
```
|
|
31
32
|
|
|
32
|
-
**2. Next.js only
|
|
33
|
+
**2. Next.js only.** Transpile the source package in `next.config.ts`:
|
|
33
34
|
|
|
34
35
|
```ts
|
|
35
36
|
const nextConfig = { transpilePackages: ["@viliha/vui-ui"] };
|
|
@@ -40,29 +41,30 @@ export default nextConfig;
|
|
|
40
41
|
|
|
41
42
|
## Scaffold the full app + demo (`init`)
|
|
42
43
|
|
|
43
|
-
The package ships the **components
|
|
44
|
+
The package itself ships the **components**. The **app shell** (layout, sidebar,
|
|
44
45
|
browser-style **open tabs**, command palette, nav config, logo) and the **demo
|
|
45
|
-
pages**
|
|
46
|
+
pages** come from a one-shot scaffolder:
|
|
46
47
|
|
|
47
48
|
```bash
|
|
48
49
|
npx @viliha/vui-ui init
|
|
49
50
|
```
|
|
50
51
|
|
|
51
|
-
It's **interactive**
|
|
52
|
+
It's **interactive** and walks through a short decision tree:
|
|
52
53
|
|
|
53
|
-
1. **Fresh project?** (fresh vs existing)
|
|
54
|
-
2. **Pre-built theme?** — the full shell
|
|
55
|
-
|
|
54
|
+
1. **Fresh project?** (fresh vs. existing)
|
|
55
|
+
2. **Pre-built theme?** — the full shell plus demo pages, or just the theme wiring
|
|
56
|
+
for you to build on.
|
|
56
57
|
|
|
57
|
-
|
|
58
|
+
Everything it generates is copied into *your* repo, so you own and edit it.
|
|
58
59
|
|
|
59
60
|
| | **Pre-built** (shell + demo) | **Theme-only** (you configure) |
|
|
60
61
|
| --- | --- | --- |
|
|
61
62
|
| **Fresh** | full runnable app: config + shell + demo pages | just the theme wiring (`globals.css`, `next.config`) — build your own pages |
|
|
62
63
|
| **Existing** | shell + demo added; your config is **never** overwritten (prints merge steps) | nothing copied; prints the wiring steps |
|
|
63
64
|
|
|
64
|
-
|
|
65
|
-
|
|
65
|
+
Before that, it asks whether this is a standalone **Next.js** app or a
|
|
66
|
+
**Turborepo**; for a monorepo it scaffolds into a target app dir, such as
|
|
67
|
+
`apps/web`.
|
|
66
68
|
|
|
67
69
|
```
|
|
68
70
|
Flags (for CI / agents, skip the prompts):
|
|
@@ -75,32 +77,44 @@ Flags (for CI / agents, skip the prompts):
|
|
|
75
77
|
--dry-run preview without writing
|
|
76
78
|
```
|
|
77
79
|
|
|
78
|
-
|
|
79
|
-
|
|
80
|
+
`init` **installs the dependencies for you** using the package manager it detects
|
|
81
|
+
from your lockfile (npm, pnpm, yarn, or bun). It prompts before doing so; pass
|
|
82
|
+
`--yes` to skip the prompt, or `--no-install` to handle it yourself.
|
|
80
83
|
|
|
81
84
|
### Fresh + pre-built (recommended for new apps)
|
|
82
85
|
|
|
83
|
-
Start from a `create-next-app` base **without `--src-dir`**
|
|
84
|
-
root `app/`
|
|
86
|
+
Start from a `create-next-app` base **without `--src-dir`** — the scaffold expects
|
|
87
|
+
a root `app/` with `@/*` → `./*` — then run `init`. It scaffolds the app, installs
|
|
88
|
+
the dependencies, and leaves you ready to run `dev`. Any package manager works:
|
|
85
89
|
|
|
86
90
|
```bash
|
|
91
|
+
# npm
|
|
87
92
|
npx create-next-app@latest my-app --ts --tailwind --app --no-src-dir --use-npm
|
|
88
|
-
cd my-app
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
93
|
+
cd my-app && npx @viliha/vui-ui init && npm run dev
|
|
94
|
+
|
|
95
|
+
# pnpm
|
|
96
|
+
pnpm create next-app my-app --ts --tailwind --app --no-src-dir
|
|
97
|
+
cd my-app && pnpm dlx @viliha/vui-ui init && pnpm dev
|
|
98
|
+
|
|
99
|
+
# yarn
|
|
100
|
+
yarn create next-app my-app --ts --tailwind --app --no-src-dir
|
|
101
|
+
cd my-app && yarn dlx @viliha/vui-ui init && yarn dev
|
|
102
|
+
|
|
103
|
+
# bun
|
|
104
|
+
bun create next-app my-app --ts --tailwind --app --no-src-dir
|
|
105
|
+
cd my-app && bunx @viliha/vui-ui init && bun dev
|
|
92
106
|
```
|
|
93
107
|
|
|
94
|
-
`init` writes `next.config.ts`, `tsconfig.json`, `app/globals.css`, the shell,
|
|
95
|
-
|
|
96
|
-
runs out of the box
|
|
108
|
+
`init` writes `next.config.ts`, `tsconfig.json`, `app/globals.css`, the shell, and
|
|
109
|
+
the demo pages, overwriting the create-next-app boilerplate, and installs the
|
|
110
|
+
dependencies. The demo then runs out of the box at `/dashboard`.
|
|
97
111
|
|
|
98
112
|
### ⚠️ Existing project — read this first
|
|
99
113
|
|
|
100
|
-
Adding VUI to an app you already have
|
|
101
|
-
overwrites your config.**
|
|
102
|
-
`app/(app)/` and `app/_components/`, or theme-only to copy nothing
|
|
103
|
-
prints the four things to wire up:
|
|
114
|
+
Adding VUI to an app you already have takes a little care. **`init --existing`
|
|
115
|
+
never overwrites your config.** Choose pre-built to add the shell and pages under
|
|
116
|
+
`app/(app)/` and `app/_components/`, or theme-only to copy nothing. Either way, it
|
|
117
|
+
prints the four things you need to wire up:
|
|
104
118
|
|
|
105
119
|
1. **`next.config`** — add `transpilePackages: ["@viliha/vui-ui"]`.
|
|
106
120
|
(Optional, for the open-tabs *keep-alive*: `output: "export"`,
|
|
@@ -115,19 +129,19 @@ prints the four things to wire up:
|
|
|
115
129
|
4. **Root `app/layout.tsx`** — `import "./globals.css"` (and mount fonts to match
|
|
116
130
|
the demo's look).
|
|
117
131
|
|
|
118
|
-
Run **`npx @viliha/vui-ui init --existing --prebuilt --dry-run`** first to
|
|
132
|
+
Run **`npx @viliha/vui-ui init --existing --prebuilt --dry-run`** first to preview
|
|
119
133
|
exactly what it will add. If you only want the components, choose **theme-only**
|
|
120
|
-
(or skip `init` and follow the [Setup](#setup) above), then import from
|
|
134
|
+
(or skip `init` entirely and follow the [Setup](#setup) above), then import from
|
|
121
135
|
`@viliha/vui-ui/*`.
|
|
122
136
|
|
|
123
|
-
> **
|
|
124
|
-
> `theme.css`. If your app already defines shadcn/ui or other CSS variables
|
|
125
|
-
> the same names, import `theme.css` **last** and remove the duplicates
|
|
126
|
-
>
|
|
137
|
+
> **A note on theming an existing app:** VUI owns its design tokens in
|
|
138
|
+
> `theme.css`. If your app already defines shadcn/ui or other CSS variables under
|
|
139
|
+
> the same names, import `theme.css` **last** and remove the duplicates so the two
|
|
140
|
+
> token sets don't collide. On a fresh project this never comes up.
|
|
127
141
|
|
|
128
142
|
## Usage
|
|
129
143
|
|
|
130
|
-
|
|
144
|
+
Every component has its own entry point, so you ship only what you use:
|
|
131
145
|
|
|
132
146
|
```tsx
|
|
133
147
|
import { Button } from "@viliha/vui-ui/button";
|
|
@@ -146,11 +160,11 @@ export function Example() {
|
|
|
146
160
|
|
|
147
161
|
### Datatables & forms
|
|
148
162
|
|
|
149
|
-
`RecordView`
|
|
150
|
-
editable cells, sorting, filtering, pagination, row
|
|
151
|
-
CSV / JSON / Excel / PDF import
|
|
152
|
-
form (slide-over or full-page). Required fields render a `*`, alignment and
|
|
153
|
-
colors come from the tokens
|
|
163
|
+
`RecordView` builds a complete admin datatable from a single `fields` array:
|
|
164
|
+
editable cells, sorting, filtering, pagination, row and bulk actions,
|
|
165
|
+
CSV / JSON / Excel / PDF import and export, and a buffered **Add / Edit / View**
|
|
166
|
+
form (slide-over or full-page). Required fields render a `*`, and alignment and
|
|
167
|
+
colors come from the tokens, so you never style a field by hand.
|
|
154
168
|
|
|
155
169
|
```tsx
|
|
156
170
|
import { RecordView, type RecordField } from "@viliha/vui-ui/record-view";
|
|
@@ -171,9 +185,9 @@ const fields: RecordField<Customer>[] = [
|
|
|
171
185
|
/>;
|
|
172
186
|
```
|
|
173
187
|
|
|
174
|
-
|
|
175
|
-
Info panel (from `formDescription`
|
|
176
|
-
[Data table docs](https://vui.viliha.com/docs/data-table).
|
|
188
|
+
That same `fields` array also drives `RecordForm`, the Add/Edit/View screen, along
|
|
189
|
+
with its Info panel (built from `formDescription` and each field's `description`).
|
|
190
|
+
See the [Data table docs](https://vui.viliha.com/docs/data-table) for the details.
|
|
177
191
|
|
|
178
192
|
## Patterns
|
|
179
193
|
|
|
@@ -193,14 +207,14 @@ The reference app composes these primitives into the conventions documented at
|
|
|
193
207
|
|
|
194
208
|
Copy them from the
|
|
195
209
|
[backoffice demo](https://github.com/myviliha/vui-starter/tree/main/apps/backoffice)
|
|
196
|
-
and adapt.
|
|
210
|
+
and adapt them to your app.
|
|
197
211
|
|
|
198
212
|
## Building with an AI agent
|
|
199
213
|
|
|
200
214
|
This package ships an **AI-agent usage guide** at
|
|
201
|
-
`node_modules/@viliha/vui-ui/AGENT.md
|
|
202
|
-
UI with VUI
|
|
203
|
-
|
|
215
|
+
`node_modules/@viliha/vui-ui/AGENT.md`. It captures the standards to follow when
|
|
216
|
+
generating UI with VUI: token discipline, reuse-first, page layout, RecordView,
|
|
217
|
+
forms, accessibility, and dark mode. The quickest way to load it is the shipped
|
|
204
218
|
`CLAUDE.template.md`:
|
|
205
219
|
|
|
206
220
|
```bash
|
|
@@ -208,8 +222,9 @@ cp node_modules/@viliha/vui-ui/CLAUDE.template.md ./CLAUDE.md # Claude Code
|
|
|
208
222
|
# or ./AGENTS.md for Cursor / Copilot
|
|
209
223
|
```
|
|
210
224
|
|
|
211
|
-
|
|
212
|
-
verbatim copy
|
|
225
|
+
That file is a one-line `@import` of `AGENT.md`, so the rules stay in a single
|
|
226
|
+
place. If you'd rather keep a verbatim copy, run
|
|
227
|
+
`cp node_modules/@viliha/vui-ui/AGENT.md AGENTS.md`.
|
|
213
228
|
|
|
214
229
|
## Components
|
|
215
230
|
|
|
@@ -222,9 +237,9 @@ wrapper) · `checkbox` · `command-palette` (⌘K launcher) · `dialog` ·
|
|
|
222
237
|
|
|
223
238
|
## Theming
|
|
224
239
|
|
|
225
|
-
Every design decision lives in `@viliha/vui-ui/theme.css` as CSS variables
|
|
226
|
-
|
|
227
|
-
to rebrand the
|
|
240
|
+
Every design decision lives in `@viliha/vui-ui/theme.css` as CSS variables —
|
|
241
|
+
colors, radius, typography, and dark mode. Override any token **after** the import
|
|
242
|
+
to rebrand the entire system:
|
|
228
243
|
|
|
229
244
|
```css
|
|
230
245
|
@import "@viliha/vui-ui/theme.css";
|
package/bin/vui.mjs
CHANGED
|
@@ -16,6 +16,7 @@ import { dirname, join, relative, sep } from "node:path";
|
|
|
16
16
|
import { fileURLToPath } from "node:url";
|
|
17
17
|
import { createInterface } from "node:readline/promises";
|
|
18
18
|
import { stdin, stdout } from "node:process";
|
|
19
|
+
import { execSync } from "node:child_process";
|
|
19
20
|
|
|
20
21
|
const TEMPLATE = fileURLToPath(new URL("../template/", import.meta.url));
|
|
21
22
|
const args = process.argv.slice(2);
|
|
@@ -121,6 +122,21 @@ function category(rel) {
|
|
|
121
122
|
return "shell";
|
|
122
123
|
}
|
|
123
124
|
|
|
125
|
+
// Detect the package manager from lockfiles (falls back to npm).
|
|
126
|
+
function detectPM(root) {
|
|
127
|
+
if (existsSync(join(root, "pnpm-lock.yaml"))) return "pnpm";
|
|
128
|
+
if (existsSync(join(root, "yarn.lock"))) return "yarn";
|
|
129
|
+
if (existsSync(join(root, "bun.lockb")) || existsSync(join(root, "bun.lock")))
|
|
130
|
+
return "bun";
|
|
131
|
+
return "npm";
|
|
132
|
+
}
|
|
133
|
+
const ADD_CMD = {
|
|
134
|
+
npm: "npm install",
|
|
135
|
+
pnpm: "pnpm add",
|
|
136
|
+
yarn: "yarn add",
|
|
137
|
+
bun: "bun add",
|
|
138
|
+
};
|
|
139
|
+
|
|
124
140
|
function allFiles(dir, out = []) {
|
|
125
141
|
for (const entry of readdirSync(dir, { withFileTypes: true })) {
|
|
126
142
|
const abs = join(dir, entry.name);
|
|
@@ -223,12 +239,46 @@ async function main() {
|
|
|
223
239
|
`\nDone — ${created} file(s) ${dry ? "would be added" : "added"}, ${skipped} skipped.`,
|
|
224
240
|
);
|
|
225
241
|
|
|
242
|
+
// Install dependencies. Turborepo installs are workspace-specific, so we only
|
|
243
|
+
// auto-install for a standalone Next.js app; turbo gets manual instructions.
|
|
244
|
+
const pm = detectPM(targetRoot);
|
|
245
|
+
const installList = `@viliha/vui-ui ${DEPS}`;
|
|
246
|
+
let installed = false;
|
|
247
|
+
if (!turbo) {
|
|
248
|
+
let doInstall = has("--no-install")
|
|
249
|
+
? false
|
|
250
|
+
: has("--yes") || has("-y")
|
|
251
|
+
? true
|
|
252
|
+
: null;
|
|
253
|
+
if (doInstall === null) {
|
|
254
|
+
const a = await ask(`Install dependencies now with ${pm}? [Y/n] `, "y");
|
|
255
|
+
doInstall = !a.startsWith("n");
|
|
256
|
+
}
|
|
257
|
+
if (doInstall && !dry) {
|
|
258
|
+
console.log(`\nInstalling dependencies with ${pm}…\n`);
|
|
259
|
+
try {
|
|
260
|
+
execSync(`${ADD_CMD[pm]} ${installList}`, {
|
|
261
|
+
cwd: targetRoot,
|
|
262
|
+
stdio: "inherit",
|
|
263
|
+
});
|
|
264
|
+
installed = true;
|
|
265
|
+
} catch {
|
|
266
|
+
console.error(
|
|
267
|
+
`\nInstall failed — run it manually:\n ${ADD_CMD[pm]} ${installList}\n`,
|
|
268
|
+
);
|
|
269
|
+
}
|
|
270
|
+
}
|
|
271
|
+
}
|
|
272
|
+
|
|
226
273
|
// Per-leaf next steps.
|
|
274
|
+
const installStep = installed
|
|
275
|
+
? ""
|
|
276
|
+
: ` 1. ${ADD_CMD[pm]} ${installList}\n`;
|
|
277
|
+
const devStepNum = installed ? "1" : "2";
|
|
227
278
|
if (fresh && prebuilt) {
|
|
228
279
|
console.log(`
|
|
229
280
|
Next steps:
|
|
230
|
-
|
|
231
|
-
2. npm run dev -> http://localhost:3000 (redirects to /dashboard)
|
|
281
|
+
${installStep} ${devStepNum}. ${pm === "npm" ? "npm run dev" : `${pm} dev`} -> http://localhost:3000 (redirects to /dashboard)
|
|
232
282
|
|
|
233
283
|
Everything is in YOUR repo — edit app/_components/nav-config.ts, set your logo
|
|
234
284
|
(NEXT_PUBLIC_LOGO_URL in .env), and delete demo pages you don't need.
|
|
@@ -238,8 +288,7 @@ Everything is in YOUR repo — edit app/_components/nav-config.ts, set your logo
|
|
|
238
288
|
Theme wired (globals.css + next.config). No shell or demo pages — build your own.
|
|
239
289
|
|
|
240
290
|
Next steps:
|
|
241
|
-
|
|
242
|
-
2. Import components from @viliha/vui-ui/* in your pages, then: npm run dev
|
|
291
|
+
${installStep} ${devStepNum}. Import components from @viliha/vui-ui/* in your pages, then run dev.
|
|
243
292
|
`);
|
|
244
293
|
} else {
|
|
245
294
|
// existing + prebuilt
|
|
@@ -258,10 +307,10 @@ The shell + demo were added under app/(app)/ and app/_components/ — review the
|
|
|
258
307
|
|
|
259
308
|
if (turbo) {
|
|
260
309
|
console.log(`Turborepo notes (target: ${appDir}):
|
|
261
|
-
• Add
|
|
310
|
+
• Add the deps to that app: ${ADD_CMD[pm]} ${installList}
|
|
311
|
+
(from the app dir, or with your PM's workspace filter).
|
|
262
312
|
• Ensure your workspace globs include this app (pnpm-workspace.yaml / workspaces).
|
|
263
|
-
• Run
|
|
264
|
-
pnpm --filter <app-name> dev
|
|
313
|
+
• Run dev with a filter, e.g. ${pm} --filter <app-name> dev
|
|
265
314
|
`);
|
|
266
315
|
}
|
|
267
316
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@viliha/vui-ui",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.5.1",
|
|
4
4
|
"description": "Vui UI — a clean, token-driven React admin/CRM component library built on Tailwind CSS v4, shadcn-style patterns, and Radix Icons. Ships as TypeScript source (Just-in-Time), compiled by the consuming app.",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"author": "Suman Bonakurthi",
|