@devjuliovilla/jv-ui 1.5.3 → 1.5.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/README.md +268 -65
- package/fesm2022/devjuliovilla-jv-ui.mjs +881 -323
- package/fesm2022/devjuliovilla-jv-ui.mjs.map +1 -1
- package/package.json +1 -1
- package/types/devjuliovilla-jv-ui.d.ts +114 -5
package/README.md
CHANGED
|
@@ -1,65 +1,268 @@
|
|
|
1
|
-
# @devjuliovilla/jv-ui
|
|
2
|
-
|
|
3
|
-
Accessibility-first Angular component library built with signals and standalone APIs. Includes components, forms, data grids, dialogs, layout primitives, services, and i18n infrastructure.
|
|
4
|
-
|
|
5
|
-
## Installation
|
|
6
|
-
|
|
7
|
-
```bash
|
|
8
|
-
npm install @devjuliovilla/jv-ui
|
|
9
|
-
```
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
}
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
|
43
|
-
|
|
44
|
-
|
|
|
45
|
-
|
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
|
50
|
-
|
|
51
|
-
|
|
|
52
|
-
| `
|
|
53
|
-
| `
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
1
|
+
# @devjuliovilla/jv-ui
|
|
2
|
+
|
|
3
|
+
Accessibility-first Angular component library built with signals and standalone APIs. Includes components, forms, data grids, dialogs, layout primitives, services, and i18n infrastructure.
|
|
4
|
+
|
|
5
|
+
## Installation
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
npm install @devjuliovilla/jv-ui
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
Import the theme CSS in your `angular.json` or `styles` array:
|
|
12
|
+
```json
|
|
13
|
+
"styles": ["@devjuliovilla/jv-ui/styles/jv-theme.css"]
|
|
14
|
+
```
|
|
15
|
+
|
|
16
|
+
## Quick start
|
|
17
|
+
|
|
18
|
+
```typescript
|
|
19
|
+
import { ApplicationConfig } from '@angular/core';
|
|
20
|
+
import { provideJvUi } from '@devjuliovilla/jv-ui';
|
|
21
|
+
|
|
22
|
+
export const appConfig: ApplicationConfig = {
|
|
23
|
+
providers: [provideJvUi({ locale: 'en' })],
|
|
24
|
+
};
|
|
25
|
+
```
|
|
26
|
+
|
|
27
|
+
```typescript
|
|
28
|
+
import { Component } from '@angular/core';
|
|
29
|
+
import { JvButtonComponent } from '@devjuliovilla/jv-ui';
|
|
30
|
+
|
|
31
|
+
@Component({
|
|
32
|
+
selector: 'app-root',
|
|
33
|
+
standalone: true,
|
|
34
|
+
imports: [JvButtonComponent],
|
|
35
|
+
template: '<jv-button variant="primary">Hello</jv-button>',
|
|
36
|
+
})
|
|
37
|
+
export class App {}
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
## Components
|
|
41
|
+
|
|
42
|
+
| Category | Components |
|
|
43
|
+
|---|---|
|
|
44
|
+
| Buttons | `JvButton`, `JvButtonGroup`, `JvIconButton` |
|
|
45
|
+
| Forms | `JvInput`, `JvSelect`, `JvCheckbox`, `JvRadio`, `JvSwitch`, `JvFormContainer` |
|
|
46
|
+
| Data Grid | `JvGrid` — full-featured data table (see below) |
|
|
47
|
+
| Containers | `JvCard`, `JvSection`, `JvDivider` |
|
|
48
|
+
| Feedback | `JvAlert`, `JvBadge`, `JvLoader`, `JvToast` |
|
|
49
|
+
| Dialogs | `JvDialog`, `JvConfirmDialog` |
|
|
50
|
+
| Layout | `JvDashboardShell`, `JvSidebar`, `JvTopbar`, `JvBreadcrumb`, `JvPage` |
|
|
51
|
+
| Auth Pages | `JvLoginPage`, `JvForgotPasswordPage`, `JvChangePasswordPage` |
|
|
52
|
+
| Icon | `JvIcon` — Lucide-based icon component with 1500+ auto-generated icons |
|
|
53
|
+
| Pagination | `JvPagination` — standalone pagination with i18n |
|
|
54
|
+
|
|
55
|
+
## Grid Features
|
|
56
|
+
|
|
57
|
+
| Feature | Description |
|
|
58
|
+
|---|---|
|
|
59
|
+
| Sorting | Client-side multi-column sorting with sort icons and `aria-sort` |
|
|
60
|
+
| Search | Global text search across visible columns |
|
|
61
|
+
| Pagination | Configurable page size, page range buttons, first/last/prev/next |
|
|
62
|
+
| Selection | Checkbox row selection with `selectedIds` / `selectionChange` |
|
|
63
|
+
| Row actions | Custom action buttons per row |
|
|
64
|
+
| Density modes | Compact, normal, comfortable |
|
|
65
|
+
| Sticky columns | Pin columns to left or right |
|
|
66
|
+
| Column resizing | Drag column header borders to resize |
|
|
67
|
+
| Column reordering | Drag & drop column headers |
|
|
68
|
+
| Grouped headers | Multi-row header with `colspan` via `children` |
|
|
69
|
+
| Per-column filters | Filter input row with operators |
|
|
70
|
+
| Inline editing | Double-click or Enter to edit: text, number, select, boolean |
|
|
71
|
+
| Virtual scrolling | Render only visible rows for large datasets |
|
|
72
|
+
| CSV/Excel export | Built-in toolbar buttons, no external deps |
|
|
73
|
+
| Server-side mode | Delegate sort/filter/page to parent component |
|
|
74
|
+
| TrackBy | Custom trackBy key or function |
|
|
75
|
+
| i18n | All labels configurable via translation dictionary |
|
|
76
|
+
|
|
77
|
+
### Grid API
|
|
78
|
+
|
|
79
|
+
```typescript
|
|
80
|
+
import { JvGridComponent } from '@devjuliovilla/jv-ui';
|
|
81
|
+
```
|
|
82
|
+
|
|
83
|
+
**Inputs:**
|
|
84
|
+
|
|
85
|
+
| Input | Type | Default | Description |
|
|
86
|
+
|---|---|---|---|
|
|
87
|
+
| `data` | `T[]` | `[]` | Row data array |
|
|
88
|
+
| `columns` | `JvGridColumn<T>[]` | `[]` | Column definitions |
|
|
89
|
+
| `actions` | `JvGridAction<T>[]` | `[]` | Row action button configs |
|
|
90
|
+
| `options` | `Partial<JvGridOptions>` | `{}` | Feature toggles and config |
|
|
91
|
+
| `trackBy` | `keyof T \| Function \| null` | `null` | Row identity |
|
|
92
|
+
| `selectedIds` | `(string \| number)[]` | `[]` | Controlled selection IDs |
|
|
93
|
+
|
|
94
|
+
**Outputs:**
|
|
95
|
+
|
|
96
|
+
| Output | Type |
|
|
97
|
+
|---|---|
|
|
98
|
+
| `rowClick` | `T` |
|
|
99
|
+
| `rowDoubleClick` | `T` |
|
|
100
|
+
| `actionClick` | `{ actionId: string; row: T }` |
|
|
101
|
+
| `selectionChange` | `(string \| number)[]` |
|
|
102
|
+
| `pageChange` | `{ pageIndex: number; pageSize: number }` |
|
|
103
|
+
| `searchChange` | `string` |
|
|
104
|
+
| `sortChange` | `{ columnKey: string; direction: 'asc' \| 'desc' \| null }` |
|
|
105
|
+
| `columnFilter` | `{ columnKey: string; value: string }` |
|
|
106
|
+
| `columnResize` | `{ columnKey: string; width: string }` |
|
|
107
|
+
| `columnReorder` | `{ columnKey: string; newIndex: number }` |
|
|
108
|
+
| `rowEdit` | `{ row: T; column: JvGridColumn<T>; value: unknown }` |
|
|
109
|
+
|
|
110
|
+
**JvGridColumn options:**
|
|
111
|
+
|
|
112
|
+
| Property | Type | Description |
|
|
113
|
+
|---|---|---|
|
|
114
|
+
| `key` | `keyof T \| string` | Data field key |
|
|
115
|
+
| `header` | `string` | Column display header |
|
|
116
|
+
| `sortable` | `boolean` | Enable column sorting |
|
|
117
|
+
| `searchable` | `boolean` | Include in global search |
|
|
118
|
+
| `filterable` | `boolean` | Show per-column filter input |
|
|
119
|
+
| `hidden` | `boolean` | Hide column from display |
|
|
120
|
+
| `sticky` | `'left' \| 'right'` | Pin column position |
|
|
121
|
+
| `editable` | `boolean` | Allow inline cell editing |
|
|
122
|
+
| `editType` | `'text' \| 'number' \| 'select' \| 'boolean'` | Editor type |
|
|
123
|
+
| `editOptions` | `{ label: string; value: unknown }[]` | Options for select editor |
|
|
124
|
+
| `width` | `string` | Column width (e.g. '8rem') |
|
|
125
|
+
| `align` | `'start' \| 'center' \| 'end'` | Text alignment |
|
|
126
|
+
| `type` | `'text' \| 'number' \| 'currency' \| 'date' \| 'datetime' \| 'boolean'` | Data type for formatting |
|
|
127
|
+
| `format` | `(value, row) => string` | Custom display formatter |
|
|
128
|
+
| `children` | `JvGridColumn<T>[]` | Child columns for grouped headers |
|
|
129
|
+
| `resizable` | `boolean` | Allow column resize |
|
|
130
|
+
| `cellClass` | `string` | CSS class for cells |
|
|
131
|
+
| `headerClass` | `string` | CSS class for header |
|
|
132
|
+
|
|
133
|
+
**JvGridOptions:**
|
|
134
|
+
|
|
135
|
+
| Option | Type | Default | Description |
|
|
136
|
+
|---|---|---|---|
|
|
137
|
+
| `searchable` | `boolean` | `true` | Show search bar |
|
|
138
|
+
| `sortable` | `boolean` | `true` | Enable column sorting |
|
|
139
|
+
| `pageable` | `boolean` | `true` | Enable pagination |
|
|
140
|
+
| `selectable` | `boolean` | `false` | Show selection checkboxes |
|
|
141
|
+
| `pageSize` | `number` | `20` | Default page size |
|
|
142
|
+
| `pageSizeOptions` | `number[]` | `[10, 20, 50, 100]` | Page size selector options |
|
|
143
|
+
| `density` | `'compact' \| 'normal' \| 'comfortable'` | `'normal'` | Row density |
|
|
144
|
+
| `loading` | `boolean` | `false` | Show loading spinner |
|
|
145
|
+
| `emptyMessage` | `string` | — | Empty state message |
|
|
146
|
+
| `exportable` | `boolean` | `false` | Show CSV/Excel export buttons |
|
|
147
|
+
| `serverSide` | `boolean` | `false` | Disable client-side processing |
|
|
148
|
+
| `totalItems` | `number` | `0` | Total items for server-side mode |
|
|
149
|
+
| `stickyColumns` | `boolean` | `false` | Enable sticky column support |
|
|
150
|
+
| `resizableColumns` | `boolean` | `false` | Enable column resizing |
|
|
151
|
+
| `reorderableColumns` | `boolean` | `false` | Enable column reordering |
|
|
152
|
+
| `editable` | `boolean` | `false` | Enable inline editing |
|
|
153
|
+
| `virtualScroll` | `boolean` | `false` | Enable virtual scrolling |
|
|
154
|
+
| `virtualScrollRowHeight` | `number` | `48` | Row height for virtual scroll |
|
|
155
|
+
| `columnFilters` | `boolean` | `false` | Show filter row below headers |
|
|
156
|
+
| `rowDoubleClick` | `boolean` | `false` | Enable row double-click event |
|
|
157
|
+
| `ariaLabel` | `string` | — | Accessible label for the grid |
|
|
158
|
+
|
|
159
|
+
### Grid example
|
|
160
|
+
|
|
161
|
+
```typescript
|
|
162
|
+
import { Component } from '@angular/core';
|
|
163
|
+
import { JvGridComponent, JvGridColumn, JvGridOptions } from '@devjuliovilla/jv-ui';
|
|
164
|
+
|
|
165
|
+
interface Product {
|
|
166
|
+
id: number;
|
|
167
|
+
name: string;
|
|
168
|
+
price: number;
|
|
169
|
+
status: string;
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
@Component({
|
|
173
|
+
selector: 'app-products',
|
|
174
|
+
standalone: true,
|
|
175
|
+
imports: [JvGridComponent],
|
|
176
|
+
template: `
|
|
177
|
+
<jv-grid
|
|
178
|
+
[data]="products"
|
|
179
|
+
[columns]="columns"
|
|
180
|
+
[options]="{ selectable: true, exportable: true, pageSize: 10 }"
|
|
181
|
+
[trackBy]="'id'"
|
|
182
|
+
[selectedIds]="selectedIds"
|
|
183
|
+
(selectionChange)="selectedIds = $event"
|
|
184
|
+
/>
|
|
185
|
+
`,
|
|
186
|
+
})
|
|
187
|
+
export class ProductsComponent {
|
|
188
|
+
products: Product[] = [ /* ... */ ];
|
|
189
|
+
selectedIds: (string | number)[] = [];
|
|
190
|
+
columns: JvGridColumn<Product>[] = [
|
|
191
|
+
{ key: 'id', header: 'ID', width: '4rem' },
|
|
192
|
+
{ key: 'name', header: 'Product', sortable: true, filterable: true },
|
|
193
|
+
{ key: 'price', header: 'Price', type: 'number', align: 'end', format: (v) => '$' + v },
|
|
194
|
+
{ key: 'status', header: 'Status', sortable: true },
|
|
195
|
+
];
|
|
196
|
+
}
|
|
197
|
+
```
|
|
198
|
+
|
|
199
|
+
## Pagination API
|
|
200
|
+
|
|
201
|
+
```typescript
|
|
202
|
+
import { JvPaginationComponent } from '@devjuliovilla/jv-ui';
|
|
203
|
+
```
|
|
204
|
+
|
|
205
|
+
| Input | Type | Default | Description |
|
|
206
|
+
|---|---|---|---|
|
|
207
|
+
| `totalItems` | `number` | `0` | Total items |
|
|
208
|
+
| `pageSize` | `number` | `20` | Items per page |
|
|
209
|
+
| `pageSizeOptions` | `number[]` | `[10, 20, 50, 100]` | Page size options |
|
|
210
|
+
| `pageIndex` | `number` | `0` | Current page (0-based) |
|
|
211
|
+
| `maxVisiblePages` | `number` | `5` | Max page buttons to show |
|
|
212
|
+
|
|
213
|
+
| Output | Type |
|
|
214
|
+
|---|---|
|
|
215
|
+
| `pageChange` | `{ pageIndex: number; pageSize: number }` |
|
|
216
|
+
|
|
217
|
+
## Icon System
|
|
218
|
+
|
|
219
|
+
```typescript
|
|
220
|
+
import { JvIconComponent, JV_LUCIDE_ICON_REGISTRY } from '@devjuliovilla/jv-ui';
|
|
221
|
+
```
|
|
222
|
+
|
|
223
|
+
| Input | Type | Default | Description |
|
|
224
|
+
|---|---|---|---|
|
|
225
|
+
| `name` | `string` | — | Icon name (from auto-generated Lucide registry) |
|
|
226
|
+
| `size` | `number` | `24` | Width and height in pixels |
|
|
227
|
+
| `strokeWidth` | `number` | `2` | SVG stroke width |
|
|
228
|
+
| `decorative` | `boolean` | `true` | `aria-hidden="true"` when decorative |
|
|
229
|
+
| `ariaLabel` | `string` | — | Accessible label when not decorative |
|
|
230
|
+
|
|
231
|
+
Icons are auto-generated from [lucide-static](https://www.npmjs.com/package/lucide-static) via:
|
|
232
|
+
|
|
233
|
+
```bash
|
|
234
|
+
node tools/generate-icons.mjs
|
|
235
|
+
```
|
|
236
|
+
|
|
237
|
+
This reads all SVG files from `lucide-static/icons` and produces `jv-icon-registry.ts` with the complete set (~1500 icons). Run it after updating `lucide-static` to keep icons in sync.
|
|
238
|
+
|
|
239
|
+
## Services
|
|
240
|
+
|
|
241
|
+
| Service | Import Path | Description |
|
|
242
|
+
|---|---|---|
|
|
243
|
+
| `JvThemeService` | `@devjuliovilla/jv-ui` | Light / dark / high-contrast theme switching |
|
|
244
|
+
| `JvTranslationService` | `@devjuliovilla/jv-ui` | Dictionary-based i18n (en/es) |
|
|
245
|
+
| `JvToastService` | `@devjuliovilla/jv-ui` | Toast notification system |
|
|
246
|
+
| `JvLoaderService` | `@devjuliovilla/jv-ui` | Full-screen loader with request counter |
|
|
247
|
+
| `JvDialogService` | `@devjuliovilla/jv-ui` | Programmatic confirm dialogs |
|
|
248
|
+
| `JvAnnouncementService` | `@devjuliovilla/jv-ui` | Screen-reader live-region announcements |
|
|
249
|
+
|
|
250
|
+
## Accessibility
|
|
251
|
+
|
|
252
|
+
- WCAG 2.2 AA target
|
|
253
|
+
- Keyboard navigation for all interactive components
|
|
254
|
+
- Focus management with visible focus indicators
|
|
255
|
+
- Screen reader announcements (loading, empty states, page changes)
|
|
256
|
+
- `aria-sort` on sortable grid headers
|
|
257
|
+
- `aria-selected` on selectable grid rows
|
|
258
|
+
- `aria-label` and `aria-labelledby` on interactive controls
|
|
259
|
+
- Supports `prefers-reduced-motion`
|
|
260
|
+
|
|
261
|
+
## Requirements
|
|
262
|
+
|
|
263
|
+
- Angular 21.2+
|
|
264
|
+
- TypeScript 5.9+
|
|
265
|
+
|
|
266
|
+
## License
|
|
267
|
+
|
|
268
|
+
MIT
|