@devjuliovilla/jv-ui 1.5.4 → 1.5.6

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 CHANGED
@@ -8,19 +8,26 @@ Accessibility-first Angular component library built with signals and standalone
8
8
  npm install @devjuliovilla/jv-ui
9
9
  ```
10
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
+
11
16
  ## Quick start
12
17
 
13
18
  ```typescript
14
- import { Component } from '@angular/core';
19
+ import { ApplicationConfig } from '@angular/core';
15
20
  import { provideJvUi } from '@devjuliovilla/jv-ui';
16
- import { JvButtonComponent } from '@devjuliovilla/jv-ui';
17
21
 
18
- // In your app.config.ts:
19
22
  export const appConfig: ApplicationConfig = {
20
23
  providers: [provideJvUi({ locale: 'en' })],
21
24
  };
25
+ ```
26
+
27
+ ```typescript
28
+ import { Component } from '@angular/core';
29
+ import { JvButtonComponent } from '@devjuliovilla/jv-ui';
22
30
 
23
- // In your component:
24
31
  @Component({
25
32
  selector: 'app-root',
26
33
  standalone: true,
@@ -35,56 +42,236 @@ export class App {}
35
42
  | Category | Components |
36
43
  |---|---|
37
44
  | Buttons | `JvButton`, `JvButtonGroup`, `JvIconButton` |
38
- | Forms | `JvInput`, `JvSelect`, `JvCheckbox`, `JvRadio`, `JvSwitch`, `JvFormContainer` |
39
- | Data Grid | `JvGrid` — sortable, searchable, paged, selectable, row actions, density modes, sticky columns, column resize/reorder, grouped headers, per-column filters, inline editing, virtual scrolling, CSV/Excel export, server-side mode |
45
+ | Forms | `JvInput`, `JvTextarea`, `JvSelect`, `JvCheckbox`, `JvRadio`, `JvSwitch`, `JvFormContainer` |
46
+ | Data Grid | `JvGrid` — full-featured data table (see below) |
40
47
  | Containers | `JvCard`, `JvSection`, `JvDivider` |
41
48
  | Feedback | `JvAlert`, `JvBadge`, `JvLoader`, `JvToast` |
42
49
  | Dialogs | `JvDialog`, `JvConfirmDialog` |
43
50
  | Layout | `JvDashboardShell`, `JvSidebar`, `JvTopbar`, `JvBreadcrumb`, `JvPage` |
44
51
  | Auth Pages | `JvLoginPage`, `JvForgotPasswordPage`, `JvChangePasswordPage` |
45
- | Icon | `JvIcon` — Lucide-based icon component with 1500+ icons auto-generated from lucide-static |
46
- | Pagination | `JvPagination` — standalone pagination with page size selector, max visible pages, i18n, and full event handling |
52
+ | Icon | `JvIcon` — Lucide-based icon component with 1500+ auto-generated icons |
53
+ | Pagination | `JvPagination` — standalone pagination with i18n |
47
54
 
48
- ## Services
55
+ ## Grid Features
49
56
 
50
- | Service | Description |
57
+ | Feature | Description |
51
58
  |---|---|
52
- | `JvThemeService` | Light / dark / high-contrast theme switching |
53
- | `JvTranslationService` | Locale switching (es/en) with dictionary-based i18n |
54
- | `JvToastService` | Toast notification system |
55
- | `JvLoaderService` | Full-screen loader overlay |
56
- | `JvDialogService` | Programmatic confirm dialogs |
57
- | `JvAnnouncementService` | Screen-reader live-region announcements |
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 |
58
76
 
59
- ## Grid Features
77
+ ### Grid API
60
78
 
61
- `JvGrid` includes the following capabilities:
79
+ ```typescript
80
+ import { JvGridComponent } from '@devjuliovilla/jv-ui';
81
+ ```
62
82
 
63
- | Feature | Description |
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 |
64
97
  |---|---|
65
- | Sorting | Client-side multi-column sorting with sort icons |
66
- | Search | Global text search across all visible columns |
67
- | Pagination | Built-in pagination with configurable page sizes |
68
- | Selection | Checkbox row selection with `selectedIds` input / `selectionChange` output |
69
- | Row actions | Custom action buttons per row via `rowActions` template |
70
- | Density modes | Compact / comfortable / spacious |
71
- | Sticky columns | Pin columns to left or right via `sticky` column option |
72
- | Column resizing | Drag column header borders to resize (`resizableColumns` option) |
73
- | Column reordering | Drag and drop column headers to reorder (`reorderableColumns` option) |
74
- | Grouped headers | Multi-row header with `colspan` via `children` on column definitions |
75
- | Per-column filters | Filter input row below headers with operator selection (`filterable` option) |
76
- | Inline editing | Edit cells inline with text/number/select/boolean editors (`editable` option) |
77
- | Virtual scrolling | Render only visible rows for large datasets (`virtualScroll` option) |
78
- | CSV/Excel export | Export toolbar buttons (`exportable` option), no external dependencies |
79
- | Server-side mode | Disable client-side sorting/filtering/paging, emit events for server handling |
80
- | TrackBy | Custom trackBy function or property key for optimized rendering |
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 }` |
81
109
 
82
- ## Requirements
110
+ **JvGridColumn options:**
83
111
 
84
- - Angular 21.2+
85
- - TypeScript 5.9+
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
86
200
 
87
- ## Icon generation
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
+ ## Textarea API
218
+
219
+ ```typescript
220
+ import { JvTextareaComponent } from '@devjuliovilla/jv-ui';
221
+ ```
222
+
223
+ | Input | Type | Default | Description |
224
+ |---|---|---|---|
225
+ | `placeholder` | `string` | `''` | Placeholder text |
226
+ | `required` | `boolean` | `false` | Mark field as required |
227
+ | `invalid` | `boolean` | `false` | Show invalid state |
228
+ | `readonly` | `boolean` | `false` | Make textarea read-only |
229
+ | `rows` | `number` | `3` | Visible number of rows |
230
+ | `cols` | `number` | — | Visible width in columns |
231
+ | `maxlength` | `number` | — | Maximum character length |
232
+ | `describedBy` | `string` | `''` | ID of description/error element for aria-describedby |
233
+ | `inputId` | `string` | `jv-textarea-{n}` | Auto-generated unique ID |
234
+
235
+ Implements `ControlValueAccessor` — compatible with `[(ngModel)]` and reactive forms via `formControlName`.
236
+
237
+ ### Example
238
+
239
+ ```typescript
240
+ import { Component } from '@angular/core';
241
+ import { JvTextareaComponent } from '@devjuliovilla/jv-ui';
242
+ import { ReactiveFormsModule, FormBuilder } from '@angular/forms';
243
+
244
+ @Component({
245
+ selector: 'app-profile',
246
+ standalone: true,
247
+ imports: [ReactiveFormsModule, JvTextareaComponent],
248
+ template: `
249
+ <jv-textarea
250
+ formControlName="bio"
251
+ placeholder="Tell us about yourself..."
252
+ [rows]="4"
253
+ [maxlength]="500"
254
+ />
255
+ `,
256
+ })
257
+ export class ProfileComponent {
258
+ form = inject(FormBuilder).group({ bio: [''] });
259
+ }
260
+ ```
261
+
262
+ ## Icon System
263
+
264
+ ```typescript
265
+ import { JvIconComponent, JV_LUCIDE_ICON_REGISTRY } from '@devjuliovilla/jv-ui';
266
+ ```
267
+
268
+ | Input | Type | Default | Description |
269
+ |---|---|---|---|
270
+ | `name` | `string` | — | Icon name (from auto-generated Lucide registry) |
271
+ | `size` | `number` | `24` | Width and height in pixels |
272
+ | `strokeWidth` | `number` | `2` | SVG stroke width |
273
+ | `decorative` | `boolean` | `true` | `aria-hidden="true"` when decorative |
274
+ | `ariaLabel` | `string` | — | Accessible label when not decorative |
88
275
 
89
276
  Icons are auto-generated from [lucide-static](https://www.npmjs.com/package/lucide-static) via:
90
277
 
@@ -92,7 +279,34 @@ Icons are auto-generated from [lucide-static](https://www.npmjs.com/package/luci
92
279
  node tools/generate-icons.mjs
93
280
  ```
94
281
 
95
- The script reads all ~1500 SVG files from `lucide-static/icons` and produces `jv-icon-registry.ts` with the complete set. Run it after updating lucide-static to keep icons in sync.
282
+ 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.
283
+
284
+ ## Services
285
+
286
+ | Service | Import Path | Description |
287
+ |---|---|---|
288
+ | `JvThemeService` | `@devjuliovilla/jv-ui` | Light / dark / high-contrast theme switching |
289
+ | `JvTranslationService` | `@devjuliovilla/jv-ui` | Dictionary-based i18n (en/es) |
290
+ | `JvToastService` | `@devjuliovilla/jv-ui` | Toast notification system |
291
+ | `JvLoaderService` | `@devjuliovilla/jv-ui` | Full-screen loader with request counter |
292
+ | `JvDialogService` | `@devjuliovilla/jv-ui` | Programmatic confirm dialogs |
293
+ | `JvAnnouncementService` | `@devjuliovilla/jv-ui` | Screen-reader live-region announcements |
294
+
295
+ ## Accessibility
296
+
297
+ - WCAG 2.2 AA target
298
+ - Keyboard navigation for all interactive components
299
+ - Focus management with visible focus indicators
300
+ - Screen reader announcements (loading, empty states, page changes)
301
+ - `aria-sort` on sortable grid headers
302
+ - `aria-selected` on selectable grid rows
303
+ - `aria-label` and `aria-labelledby` on interactive controls
304
+ - Supports `prefers-reduced-motion`
305
+
306
+ ## Requirements
307
+
308
+ - Angular 21.2+
309
+ - TypeScript 5.9+
96
310
 
97
311
  ## License
98
312