@devjuliovilla/jv-ui 1.13.0 → 1.14.0
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 +347 -308
- package/fesm2022/devjuliovilla-jv-ui.mjs +413 -127
- package/fesm2022/devjuliovilla-jv-ui.mjs.map +1 -1
- package/package.json +1 -1
- package/types/devjuliovilla-jv-ui.d.ts +42 -6
package/README.md
CHANGED
|
@@ -9,6 +9,7 @@ npm install @devjuliovilla/jv-ui
|
|
|
9
9
|
```
|
|
10
10
|
|
|
11
11
|
Import the theme CSS in your `angular.json` or `styles` array:
|
|
12
|
+
|
|
12
13
|
```json
|
|
13
14
|
"styles": ["@devjuliovilla/jv-ui/styles/jv-theme.css"]
|
|
14
15
|
```
|
|
@@ -39,23 +40,23 @@ export class App {}
|
|
|
39
40
|
|
|
40
41
|
## Components
|
|
41
42
|
|
|
42
|
-
| Category
|
|
43
|
-
|
|
44
|
-
| Buttons
|
|
45
|
-
| Calendar
|
|
46
|
-
| Forms
|
|
47
|
-
| Data Grid
|
|
48
|
-
| Containers | `JvCard`, `JvSection`, `JvDivider`
|
|
49
|
-
| List
|
|
50
|
-
| Tabs
|
|
51
|
-
| Slider
|
|
52
|
-
| Gallery
|
|
53
|
-
| Feedback
|
|
54
|
-
| Dialogs
|
|
55
|
-
| Layout
|
|
56
|
-
| Auth Pages | `JvLoginPage`, `JvForgotPasswordPage`, `JvChangePasswordPage`
|
|
57
|
-
| Icon
|
|
58
|
-
| Pagination | `JvPagination` — standalone pagination with i18n
|
|
43
|
+
| Category | Components |
|
|
44
|
+
| ---------- | ------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
45
|
+
| Buttons | `JvButton`, `JvButtonGroup`, `JvIconButton` |
|
|
46
|
+
| Calendar | `JvMonthCalendar`, `JvDayPlanner` — reusable month view and agenda primitives, usable together or independently |
|
|
47
|
+
| Forms | `JvInput`, `JvTextarea`, `JvCode`, `JvSelect`, `JvCheckbox`, `JvRadio`, `JvSwitch`, `JvDatePicker`, `JvModalSelector`, `JvFileInput`, `JvFormContainer` |
|
|
48
|
+
| Data Grid | `JvGrid` — full-featured data table (see below) |
|
|
49
|
+
| Containers | `JvCard`, `JvSection`, `JvDivider` |
|
|
50
|
+
| List | `JvList`, `JvListItem` — list with title, description, icons, badges, and interactive items |
|
|
51
|
+
| Tabs | `JvTabs`, `JvTabPanelDirective` — horizontal tabs with keyboard navigation and animated transitions |
|
|
52
|
+
| Slider | `JvImageSlider` — responsive image slider with thumbnails and keyboard navigation |
|
|
53
|
+
| Gallery | `JvImageGallery` — horizontal image gallery with wheel scrolling and full-screen viewer |
|
|
54
|
+
| Feedback | `JvAlert`, `JvBadge`, `JvLoader`, `JvToast` |
|
|
55
|
+
| Dialogs | `JvDialog`, `JvConfirmDialog`, `JvWindowModal` — compact dialogs plus a larger workflow overlay surface |
|
|
56
|
+
| Layout | `JvDashboardShell`, `JvSidebar`, `JvTopbar`, `JvBreadcrumb`, `JvPage` |
|
|
57
|
+
| Auth Pages | `JvLoginPage`, `JvForgotPasswordPage`, `JvChangePasswordPage` |
|
|
58
|
+
| Icon | `JvIcon` — Lucide-based icon component with 1500+ auto-generated icons |
|
|
59
|
+
| Pagination | `JvPagination` — standalone pagination with i18n |
|
|
59
60
|
|
|
60
61
|
## Calendar API
|
|
61
62
|
|
|
@@ -78,33 +79,33 @@ import {
|
|
|
78
79
|
|
|
79
80
|
**Inputs:**
|
|
80
81
|
|
|
81
|
-
| Input
|
|
82
|
-
|
|
83
|
-
| `value`
|
|
84
|
-
| `visibleMonth` | `Date \| string \| null`
|
|
85
|
-
| `dayMeta`
|
|
86
|
-
| `ariaLabel`
|
|
87
|
-
| `monthLabel`
|
|
88
|
-
| `yearLabel`
|
|
89
|
-
| `minYear`
|
|
90
|
-
| `maxYear`
|
|
91
|
-
| `navigation`
|
|
82
|
+
| Input | Type | Default | Description |
|
|
83
|
+
| -------------- | ---------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------- | ---------------------------------------------------------- |
|
|
84
|
+
| `value` | `Date \| string \| null` | `undefined` | Selected day |
|
|
85
|
+
| `visibleMonth` | `Date \| string \| null` | `undefined` | Controlled visible month independent from the selected day |
|
|
86
|
+
| `dayMeta` | `JvMonthCalendarDayMeta[]` | `[]` | Marker/counter metadata per day |
|
|
87
|
+
| `ariaLabel` | `string` | localized default | Accessible label for the grid |
|
|
88
|
+
| `monthLabel` | `string` | `Month` | Accessible label for the month selector |
|
|
89
|
+
| `yearLabel` | `string` | `Year` | Accessible label for the year selector |
|
|
90
|
+
| `minYear` | `number` | current year - 10 | Lower year bound for the year selector |
|
|
91
|
+
| `maxYear` | `number` | current year + 10 | Upper year bound for the year selector |
|
|
92
|
+
| `navigation` | `{ previousMonth?: boolean; nextMonth?: boolean; previousYear?: boolean; nextYear?: boolean }` | `{ previousMonth: true, nextMonth: true, previousYear: false, nextYear: false }` | Controls which month/year navigation buttons are rendered |
|
|
92
93
|
|
|
93
94
|
**Outputs:**
|
|
94
95
|
|
|
95
|
-
| Output
|
|
96
|
-
|
|
97
|
-
| `selectionChange`
|
|
96
|
+
| Output | Type |
|
|
97
|
+
| -------------------- | ------ |
|
|
98
|
+
| `selectionChange` | `Date` |
|
|
98
99
|
| `visibleMonthChange` | `Date` |
|
|
99
100
|
|
|
100
101
|
**Day metadata:**
|
|
101
102
|
|
|
102
|
-
| Property | Type
|
|
103
|
-
|
|
104
|
-
| `date`
|
|
105
|
-
| `count`
|
|
106
|
-
| `tone`
|
|
107
|
-
| `label`
|
|
103
|
+
| Property | Type | Description |
|
|
104
|
+
| -------- | --------------------------------------------------------------------------------------- | --------------------------------------------------------- |
|
|
105
|
+
| `date` | `Date \| string` | Day associated with the marker |
|
|
106
|
+
| `count` | `number` | Optional numeric badge rendered inside the cell |
|
|
107
|
+
| `tone` | `'primary' \| 'secondary' \| 'success' \| 'warning' \| 'danger' \| 'info' \| 'neutral'` | Visual tone for the badge or dot |
|
|
108
|
+
| `label` | `string` | Extra accessibility text appended to the day `aria-label` |
|
|
108
109
|
|
|
109
110
|
**Template hook:**
|
|
110
111
|
|
|
@@ -150,37 +151,37 @@ import {
|
|
|
150
151
|
|
|
151
152
|
**Inputs:**
|
|
152
153
|
|
|
153
|
-
| Input
|
|
154
|
-
|
|
155
|
-
| `items`
|
|
156
|
-
| `groupByDate`
|
|
157
|
-
| `emptyMessage`
|
|
158
|
-
| `ariaLabel`
|
|
159
|
-
| `defaultExpandedItemIds` | `(string \| number)[]` | `[]`
|
|
154
|
+
| Input | Type | Default | Description |
|
|
155
|
+
| ------------------------ | ---------------------- | ----------------- | ---------------------------------------- |
|
|
156
|
+
| `items` | `JvDayPlannerItem[]` | `[]` | Agenda items |
|
|
157
|
+
| `groupByDate` | `boolean` | `false` | Group items under a date heading |
|
|
158
|
+
| `emptyMessage` | `string` | localized default | Empty state copy |
|
|
159
|
+
| `ariaLabel` | `string` | localized default | Accessible label for the agenda |
|
|
160
|
+
| `defaultExpandedItemIds` | `(string \| number)[]` | `[]` | Items whose detail should start expanded |
|
|
160
161
|
|
|
161
162
|
**Outputs:**
|
|
162
163
|
|
|
163
|
-
| Output
|
|
164
|
-
|
|
164
|
+
| Output | Type |
|
|
165
|
+
| ------------ | ------------------ |
|
|
165
166
|
| `itemSelect` | `JvDayPlannerItem` |
|
|
166
167
|
|
|
167
168
|
**Planner item shape:**
|
|
168
169
|
|
|
169
|
-
| Property
|
|
170
|
-
|
|
171
|
-
| `id`
|
|
172
|
-
| `title`
|
|
173
|
-
| `date`
|
|
174
|
-
| `start`
|
|
175
|
-
| `end`
|
|
176
|
-
| `status`
|
|
177
|
-
| `statusTone`
|
|
178
|
-
| `type`
|
|
179
|
-
| `typeTone`
|
|
180
|
-
| `responsible` | `string`
|
|
181
|
-
| `location`
|
|
182
|
-
| `details`
|
|
183
|
-
| `completed`
|
|
170
|
+
| Property | Type | Description |
|
|
171
|
+
| ------------- | ------------------------ | ----------------------------------------- |
|
|
172
|
+
| `id` | `string \| number` | Stable identity |
|
|
173
|
+
| `title` | `string` | Primary label |
|
|
174
|
+
| `date` | `Date \| string \| null` | Logical day when start time is not enough |
|
|
175
|
+
| `start` | `Date \| string \| null` | Optional start datetime |
|
|
176
|
+
| `end` | `Date \| string \| null` | Optional end datetime |
|
|
177
|
+
| `status` | `string` | Status badge label |
|
|
178
|
+
| `statusTone` | `JvTone` | Visual tone for status badge |
|
|
179
|
+
| `type` | `string` | Type/category badge label |
|
|
180
|
+
| `typeTone` | `JvTone` | Visual tone for type badge |
|
|
181
|
+
| `responsible` | `string` | Responsible person |
|
|
182
|
+
| `location` | `string` | Location metadata |
|
|
183
|
+
| `details` | `string` | Expandable detail text |
|
|
184
|
+
| `completed` | `boolean` | Reduced emphasis for completed items |
|
|
184
185
|
|
|
185
186
|
**Template hooks:**
|
|
186
187
|
|
|
@@ -198,11 +199,7 @@ import { JvDayPlannerComponent, JvDayPlannerItem } from '@devjuliovilla/jv-ui';
|
|
|
198
199
|
standalone: true,
|
|
199
200
|
imports: [JvDayPlannerComponent],
|
|
200
201
|
template: `
|
|
201
|
-
<jv-day-planner
|
|
202
|
-
[items]="items"
|
|
203
|
-
[groupByDate]="true"
|
|
204
|
-
(itemSelect)="handleSelect($event)"
|
|
205
|
-
/>
|
|
202
|
+
<jv-day-planner [items]="items" [groupByDate]="true" (itemSelect)="handleSelect($event)" />
|
|
206
203
|
`,
|
|
207
204
|
})
|
|
208
205
|
export class PlannerOnlyComponent {
|
|
@@ -247,25 +244,25 @@ Use both components together when you need a left-side month selector and a righ
|
|
|
247
244
|
|
|
248
245
|
## Grid Features
|
|
249
246
|
|
|
250
|
-
| Feature
|
|
251
|
-
|
|
252
|
-
| Sorting
|
|
253
|
-
| Search
|
|
254
|
-
| Pagination
|
|
255
|
-
| Selection
|
|
256
|
-
| Row actions
|
|
257
|
-
| Density modes
|
|
258
|
-
| Sticky columns
|
|
259
|
-
| Column resizing
|
|
260
|
-
| Column reordering
|
|
261
|
-
| Grouped headers
|
|
262
|
-
| Per-column filters | Filter input row with operators
|
|
263
|
-
| Inline editing
|
|
264
|
-
| Virtual scrolling
|
|
265
|
-
| CSV/Excel export
|
|
266
|
-
| Server-side mode
|
|
267
|
-
| TrackBy
|
|
268
|
-
| i18n
|
|
247
|
+
| Feature | Description |
|
|
248
|
+
| ------------------ | ---------------------------------------------------------------- |
|
|
249
|
+
| Sorting | Client-side multi-column sorting with sort icons and `aria-sort` |
|
|
250
|
+
| Search | Global text search across visible columns |
|
|
251
|
+
| Pagination | Configurable page size, page range buttons, first/last/prev/next |
|
|
252
|
+
| Selection | Checkbox row selection with `selectedIds` / `selectionChange` |
|
|
253
|
+
| Row actions | Custom action buttons per row |
|
|
254
|
+
| Density modes | Compact, normal, comfortable |
|
|
255
|
+
| Sticky columns | Pin columns to left or right |
|
|
256
|
+
| Column resizing | Drag column header borders to resize |
|
|
257
|
+
| Column reordering | Drag & drop column headers |
|
|
258
|
+
| Grouped headers | Multi-row header with `colspan` via `children` |
|
|
259
|
+
| Per-column filters | Filter input row with operators |
|
|
260
|
+
| Inline editing | Double-click or Enter to edit: text, number, select, boolean |
|
|
261
|
+
| Virtual scrolling | Render only visible rows for large datasets |
|
|
262
|
+
| CSV/Excel export | Built-in toolbar buttons, no external deps |
|
|
263
|
+
| Server-side mode | Delegate sort/filter/page to parent component |
|
|
264
|
+
| TrackBy | Custom trackBy key or function |
|
|
265
|
+
| i18n | All labels configurable via translation dictionary |
|
|
269
266
|
|
|
270
267
|
### Grid API
|
|
271
268
|
|
|
@@ -275,81 +272,82 @@ import { JvGridComponent } from '@devjuliovilla/jv-ui';
|
|
|
275
272
|
|
|
276
273
|
**Inputs:**
|
|
277
274
|
|
|
278
|
-
| Input
|
|
279
|
-
|
|
280
|
-
| `data`
|
|
281
|
-
| `columns`
|
|
282
|
-
| `actions`
|
|
283
|
-
| `options`
|
|
284
|
-
| `trackBy`
|
|
285
|
-
| `selectedIds` | `(string \| number)[]`
|
|
275
|
+
| Input | Type | Default | Description |
|
|
276
|
+
| ------------- | ----------------------------- | ------- | -------------------------- |
|
|
277
|
+
| `data` | `T[]` | `[]` | Row data array |
|
|
278
|
+
| `columns` | `JvGridColumn<T>[]` | `[]` | Column definitions |
|
|
279
|
+
| `actions` | `JvGridAction<T>[]` | `[]` | Row action button configs |
|
|
280
|
+
| `options` | `Partial<JvGridOptions>` | `{}` | Feature toggles and config |
|
|
281
|
+
| `trackBy` | `keyof T \| Function \| null` | `null` | Row identity |
|
|
282
|
+
| `selectedIds` | `(string \| number)[]` | `[]` | Controlled selection IDs |
|
|
286
283
|
|
|
287
284
|
**Outputs:**
|
|
288
285
|
|
|
289
|
-
| Output
|
|
290
|
-
|
|
291
|
-
| `rowClick`
|
|
292
|
-
| `rowDoubleClick`
|
|
293
|
-
| `actionClick`
|
|
294
|
-
| `selectionChange` | `(string \| number)[]`
|
|
295
|
-
| `pageChange`
|
|
296
|
-
| `searchChange`
|
|
297
|
-
| `sortChange`
|
|
298
|
-
| `columnFilter`
|
|
299
|
-
| `columnResize`
|
|
300
|
-
| `columnReorder`
|
|
301
|
-
| `rowEdit`
|
|
286
|
+
| Output | Type |
|
|
287
|
+
| ----------------- | ----------------------------------------------------------- |
|
|
288
|
+
| `rowClick` | `T` |
|
|
289
|
+
| `rowDoubleClick` | `T` |
|
|
290
|
+
| `actionClick` | `{ actionId: string; row: T }` |
|
|
291
|
+
| `selectionChange` | `(string \| number)[]` |
|
|
292
|
+
| `pageChange` | `{ pageIndex: number; pageSize: number }` |
|
|
293
|
+
| `searchChange` | `string` |
|
|
294
|
+
| `sortChange` | `{ columnKey: string; direction: 'asc' \| 'desc' \| null }` |
|
|
295
|
+
| `columnFilter` | `{ columnKey: string; value: string }` |
|
|
296
|
+
| `columnResize` | `{ columnKey: string; width: string }` |
|
|
297
|
+
| `columnReorder` | `{ columnKey: string; newIndex: number }` |
|
|
298
|
+
| `rowEdit` | `{ row: T; column: JvGridColumn<T>; value: unknown }` |
|
|
302
299
|
|
|
303
300
|
**JvGridColumn options:**
|
|
304
301
|
|
|
305
|
-
| Property
|
|
306
|
-
|
|
307
|
-
| `key`
|
|
308
|
-
| `header`
|
|
309
|
-
| `sortable`
|
|
310
|
-
| `searchable`
|
|
311
|
-
| `filterable`
|
|
312
|
-
| `hidden`
|
|
313
|
-
| `sticky`
|
|
314
|
-
| `editable`
|
|
315
|
-
| `editType`
|
|
316
|
-
| `editOptions`
|
|
317
|
-
| `width`
|
|
318
|
-
| `align`
|
|
319
|
-
| `type`
|
|
320
|
-
| `formatOptions` | `Intl.NumberFormatOptions & Intl.DateTimeFormatOptions`
|
|
321
|
-
| `format`
|
|
322
|
-
| `children`
|
|
323
|
-
| `resizable`
|
|
324
|
-
| `cellClass`
|
|
325
|
-
| `headerClass`
|
|
302
|
+
| Property | Type | Description |
|
|
303
|
+
| --------------- | ----------------------------------------------------------------------------------------------------------- | --------------------------------- |
|
|
304
|
+
| `key` | `keyof T \| string` | Data field key |
|
|
305
|
+
| `header` | `string` | Column display header |
|
|
306
|
+
| `sortable` | `boolean` | Enable column sorting |
|
|
307
|
+
| `searchable` | `boolean` | Include in global search |
|
|
308
|
+
| `filterable` | `boolean` | Show per-column filter input |
|
|
309
|
+
| `hidden` | `boolean` | Hide column from display |
|
|
310
|
+
| `sticky` | `'left' \| 'right'` | Pin column position |
|
|
311
|
+
| `editable` | `boolean` | Allow inline cell editing |
|
|
312
|
+
| `editType` | `'text' \| 'number' \| 'select' \| 'boolean'` | Editor type |
|
|
313
|
+
| `editOptions` | `{ label: string; value: unknown }[]` | Options for select editor |
|
|
314
|
+
| `width` | `string` | Column width (e.g. '8rem') |
|
|
315
|
+
| `align` | `'start' \| 'center' \| 'end'` | Text alignment |
|
|
316
|
+
| `type` | `'text' \| 'integer' \| 'number' \| 'currency' \| 'percent' \| 'date' \| 'time' \| 'datetime' \| 'boolean'` | Data type for formatting |
|
|
317
|
+
| `formatOptions` | `Intl.NumberFormatOptions & Intl.DateTimeFormatOptions` | Per-column formatting overrides |
|
|
318
|
+
| `format` | `(value, row) => string` | Custom display formatter |
|
|
319
|
+
| `children` | `JvGridColumn<T>[]` | Child columns for grouped headers |
|
|
320
|
+
| `resizable` | `boolean` | Allow column resize |
|
|
321
|
+
| `cellClass` | `string` | CSS class for cells |
|
|
322
|
+
| `headerClass` | `string` | CSS class for header |
|
|
326
323
|
|
|
327
324
|
**JvGridOptions:**
|
|
328
325
|
|
|
329
|
-
| Option
|
|
330
|
-
|
|
331
|
-
| `searchable`
|
|
332
|
-
| `sortable`
|
|
333
|
-
| `pageable`
|
|
334
|
-
| `selectable`
|
|
335
|
-
| `pageSize`
|
|
336
|
-
| `pageSizeOptions`
|
|
337
|
-
| `density`
|
|
338
|
-
| `loading`
|
|
339
|
-
| `emptyMessage`
|
|
340
|
-
| `exportable`
|
|
341
|
-
| `exportFileName`
|
|
342
|
-
| `serverSide`
|
|
343
|
-
| `totalItems`
|
|
344
|
-
| `stickyColumns`
|
|
345
|
-
| `resizableColumns`
|
|
346
|
-
| `reorderableColumns`
|
|
347
|
-
| `editable`
|
|
348
|
-
| `virtualScroll`
|
|
349
|
-
| `virtualScrollRowHeight` | `number`
|
|
350
|
-
| `columnFilters`
|
|
351
|
-
| `rowDoubleClick`
|
|
352
|
-
| `
|
|
326
|
+
| Option | Type | Default | Description |
|
|
327
|
+
| ------------------------ | ---------------------------------------- | ------------------- | ------------------------------------------------------------------------------------- |
|
|
328
|
+
| `searchable` | `boolean` | `true` | Show search bar |
|
|
329
|
+
| `sortable` | `boolean` | `true` | Enable column sorting |
|
|
330
|
+
| `pageable` | `boolean` | `true` | Enable pagination |
|
|
331
|
+
| `selectable` | `boolean` | `false` | Show selection checkboxes |
|
|
332
|
+
| `pageSize` | `number` | `20` | Default page size |
|
|
333
|
+
| `pageSizeOptions` | `number[]` | `[10, 20, 50, 100]` | Page size selector options |
|
|
334
|
+
| `density` | `'compact' \| 'normal' \| 'comfortable'` | `'normal'` | Row density |
|
|
335
|
+
| `loading` | `boolean` | `false` | Show loading spinner |
|
|
336
|
+
| `emptyMessage` | `string` | — | Empty state message |
|
|
337
|
+
| `exportable` | `boolean` | `false` | Show CSV/Excel export buttons |
|
|
338
|
+
| `exportFileName` | `string` | `''` | Base filename used for CSV/Excel exports; the component applies the correct extension |
|
|
339
|
+
| `serverSide` | `boolean` | `false` | Disable client-side processing |
|
|
340
|
+
| `totalItems` | `number` | `0` | Total items for server-side mode |
|
|
341
|
+
| `stickyColumns` | `boolean` | `false` | Enable sticky column support |
|
|
342
|
+
| `resizableColumns` | `boolean` | `false` | Enable column resizing |
|
|
343
|
+
| `reorderableColumns` | `boolean` | `false` | Enable column reordering |
|
|
344
|
+
| `editable` | `boolean` | `false` | Enable inline editing |
|
|
345
|
+
| `virtualScroll` | `boolean` | `false` | Enable virtual scrolling |
|
|
346
|
+
| `virtualScrollRowHeight` | `number` | `48` | Row height for virtual scroll |
|
|
347
|
+
| `columnFilters` | `boolean` | `false` | Show filter row below headers |
|
|
348
|
+
| `rowDoubleClick` | `boolean` | `false` | Enable row double-click event |
|
|
349
|
+
| `keyboardNavigation` | `boolean` | `false` | Enable arrow-key cell navigation and `F2` editing flow |
|
|
350
|
+
| `ariaLabel` | `string` | — | Accessible label for the grid |
|
|
353
351
|
|
|
354
352
|
### Grid example
|
|
355
353
|
|
|
@@ -380,7 +378,9 @@ interface Product {
|
|
|
380
378
|
`,
|
|
381
379
|
})
|
|
382
380
|
export class ProductsComponent {
|
|
383
|
-
products: Product[] = [
|
|
381
|
+
products: Product[] = [
|
|
382
|
+
/* ... */
|
|
383
|
+
];
|
|
384
384
|
selectedIds: (string | number)[] = [];
|
|
385
385
|
columns: JvGridColumn<Product>[] = [
|
|
386
386
|
{ key: 'id', header: 'ID', width: '4rem' },
|
|
@@ -391,6 +391,51 @@ export class ProductsComponent {
|
|
|
391
391
|
}
|
|
392
392
|
```
|
|
393
393
|
|
|
394
|
+
### Grid behavior notes
|
|
395
|
+
|
|
396
|
+
- **Row identity:** when `trackBy` is not provided, rows with an `id` property use that value as their identity. Provide `[trackBy]` when the row identity uses another field or a custom function.
|
|
397
|
+
- **Controlled selection:** use `[selectedIds]` together with `(selectionChange)` when the parent owns selection state. The component accepts an empty array, so selection can start fully controlled without special initialization.
|
|
398
|
+
- **Pagination:** `pageSize` is clamped to the configured `pageSizeOptions`, and page indexes are clamped when the data or page size changes. Use `(pageChange)` to synchronize server-side pagination.
|
|
399
|
+
- **Grouped headers:** define parent columns with `children`. The grouped header is rendered with `colspan`, while sorting, filtering, editing, resizing, reordering, and export operate on the leaf columns.
|
|
400
|
+
- **Virtual scrolling:** place the grid inside a container with a constrained height and set `virtualScroll: true`. The default row height is `48`; set `virtualScrollRowHeight` to the actual rendered row height when it differs.
|
|
401
|
+
- **Formatting:** column `type` and `formatOptions` affect display only. Sorting and export use the raw field value, not the localized text shown in the cell.
|
|
402
|
+
- **Inline editing:** set both `editable: true` in `options` and `editable: true` on the column. `select` editors emit the configured option value, while `boolean` editors emit a boolean. Press `F2` to start, `Enter` to commit, and `Escape` to cancel when keyboard navigation is enabled.
|
|
403
|
+
|
|
404
|
+
### Keyboard navigation example
|
|
405
|
+
|
|
406
|
+
```typescript
|
|
407
|
+
const gridOptions: JvGridOptions = {
|
|
408
|
+
keyboardNavigation: true,
|
|
409
|
+
editable: true,
|
|
410
|
+
pageable: false,
|
|
411
|
+
};
|
|
412
|
+
|
|
413
|
+
const columns: JvGridColumn<Product>[] = [
|
|
414
|
+
{ key: 'name', header: 'Product', editable: true, editType: 'text' },
|
|
415
|
+
{
|
|
416
|
+
key: 'status',
|
|
417
|
+
header: 'Status',
|
|
418
|
+
editable: true,
|
|
419
|
+
editType: 'select',
|
|
420
|
+
editOptions: [
|
|
421
|
+
{ label: 'Active', value: 'active' },
|
|
422
|
+
{ label: 'Paused', value: 'paused' },
|
|
423
|
+
],
|
|
424
|
+
},
|
|
425
|
+
];
|
|
426
|
+
```
|
|
427
|
+
|
|
428
|
+
```html
|
|
429
|
+
<jv-grid
|
|
430
|
+
[data]="products"
|
|
431
|
+
[columns]="columns"
|
|
432
|
+
[options]="gridOptions"
|
|
433
|
+
(rowEdit)="onRowEdit($event)"
|
|
434
|
+
/>
|
|
435
|
+
```
|
|
436
|
+
|
|
437
|
+
With `keyboardNavigation` enabled, arrow keys move between data cells without trapping row action buttons. `Tab` continues to the row actions, `F2` starts editing, `Enter` commits, and `Escape` cancels.
|
|
438
|
+
|
|
394
439
|
## List API
|
|
395
440
|
|
|
396
441
|
```typescript
|
|
@@ -399,26 +444,26 @@ import { JvListComponent, JvListItemComponent } from '@devjuliovilla/jv-ui';
|
|
|
399
444
|
|
|
400
445
|
**JvList inputs:**
|
|
401
446
|
|
|
402
|
-
| Input
|
|
403
|
-
|
|
404
|
-
| `role`
|
|
405
|
-
| `variant`
|
|
406
|
-
| `ariaLabel` | `string`
|
|
447
|
+
| Input | Type | Default | Description |
|
|
448
|
+
| ----------- | ------------------------ | -------- | ------------------------------------------------------------------------------ |
|
|
449
|
+
| `role` | `'list' \| 'navigation'` | `'list'` | ARIA role for the list |
|
|
450
|
+
| `variant` | `'bordered' \| null` | `null` | Outer border + border-radius around the list (items always have bottom border) |
|
|
451
|
+
| `ariaLabel` | `string` | `''` | Accessible label |
|
|
407
452
|
|
|
408
453
|
**JvListItem inputs:**
|
|
409
454
|
|
|
410
|
-
| Input
|
|
411
|
-
|
|
412
|
-
| `title`
|
|
413
|
-
| `description` | `string`
|
|
414
|
-
| `leadingIcon` | `string \| null`
|
|
415
|
-
| `disabled`
|
|
416
|
-
| `active`
|
|
455
|
+
| Input | Type | Default | Description |
|
|
456
|
+
| ------------- | ------------------- | ------- | -------------------------------------------- |
|
|
457
|
+
| `title` | `string` (required) | — | Primary text |
|
|
458
|
+
| `description` | `string` | `''` | Secondary text below title |
|
|
459
|
+
| `leadingIcon` | `string \| null` | `null` | Lucide icon name on the left |
|
|
460
|
+
| `disabled` | `boolean` | `false` | Gray out and block interaction |
|
|
461
|
+
| `active` | `boolean` | `false` | Highlight with primary color and left border |
|
|
417
462
|
|
|
418
463
|
**JvListItem outputs:**
|
|
419
464
|
|
|
420
|
-
| Output
|
|
421
|
-
|
|
465
|
+
| Output | Type |
|
|
466
|
+
| ----------- | ------ |
|
|
422
467
|
| `activated` | `void` |
|
|
423
468
|
|
|
424
469
|
**Content projection:** use the `meta` attribute selector for badges, icons, or any content on the right side:
|
|
@@ -448,23 +493,17 @@ import { JvListComponent, JvListItemComponent, JvBadgeComponent } from '@devjuli
|
|
|
448
493
|
leadingIcon="layout-dashboard"
|
|
449
494
|
[active]="true"
|
|
450
495
|
/>
|
|
451
|
-
<jv-list-item
|
|
452
|
-
title="Notifications"
|
|
453
|
-
description="3 pending"
|
|
454
|
-
(activated)="onOpen()"
|
|
455
|
-
>
|
|
496
|
+
<jv-list-item title="Notifications" description="3 pending" (activated)="onOpen()">
|
|
456
497
|
<jv-badge tone="primary" meta>3</jv-badge>
|
|
457
498
|
</jv-list-item>
|
|
458
|
-
<jv-list-item
|
|
459
|
-
title="Reports"
|
|
460
|
-
description="Coming soon"
|
|
461
|
-
[disabled]="true"
|
|
462
|
-
/>
|
|
499
|
+
<jv-list-item title="Reports" description="Coming soon" [disabled]="true" />
|
|
463
500
|
</jv-list>
|
|
464
501
|
`,
|
|
465
502
|
})
|
|
466
503
|
export class NavListComponent {
|
|
467
|
-
onOpen() {
|
|
504
|
+
onOpen() {
|
|
505
|
+
/* handle activation */
|
|
506
|
+
}
|
|
468
507
|
}
|
|
469
508
|
```
|
|
470
509
|
|
|
@@ -474,16 +513,16 @@ export class NavListComponent {
|
|
|
474
513
|
import { JvPaginationComponent } from '@devjuliovilla/jv-ui';
|
|
475
514
|
```
|
|
476
515
|
|
|
477
|
-
| Input
|
|
478
|
-
|
|
479
|
-
| `totalItems`
|
|
480
|
-
| `pageSize`
|
|
481
|
-
| `pageSizeOptions` | `number[]` | `[10, 20, 50, 100]` | Page size options
|
|
482
|
-
| `pageIndex`
|
|
483
|
-
| `maxVisiblePages` | `number`
|
|
516
|
+
| Input | Type | Default | Description |
|
|
517
|
+
| ----------------- | ---------- | ------------------- | ------------------------ |
|
|
518
|
+
| `totalItems` | `number` | `0` | Total items |
|
|
519
|
+
| `pageSize` | `number` | `20` | Items per page |
|
|
520
|
+
| `pageSizeOptions` | `number[]` | `[10, 20, 50, 100]` | Page size options |
|
|
521
|
+
| `pageIndex` | `number` | `0` | Current page (0-based) |
|
|
522
|
+
| `maxVisiblePages` | `number` | `5` | Max page buttons to show |
|
|
484
523
|
|
|
485
|
-
| Output
|
|
486
|
-
|
|
524
|
+
| Output | Type |
|
|
525
|
+
| ------------ | ----------------------------------------- |
|
|
487
526
|
| `pageChange` | `{ pageIndex: number; pageSize: number }` |
|
|
488
527
|
|
|
489
528
|
## Tabs API
|
|
@@ -494,17 +533,17 @@ import { JvTabsComponent, JvTabPanelDirective, JvTabItem } from '@devjuliovilla/
|
|
|
494
533
|
|
|
495
534
|
**Inputs:**
|
|
496
535
|
|
|
497
|
-
| Input
|
|
498
|
-
|
|
499
|
-
| `tabs`
|
|
500
|
-
| `activeTabId` | `string \| null`
|
|
501
|
-
| `keepMounted` | `boolean`
|
|
502
|
-
| `transition`
|
|
536
|
+
| Input | Type | Default | Description |
|
|
537
|
+
| ------------- | ------------------------------------- | ------- | --------------------------------------------------------- |
|
|
538
|
+
| `tabs` | `JvTabItem[]` | `[]` | Tab definitions (`{ id, label, icon?, disabled? }`) |
|
|
539
|
+
| `activeTabId` | `string \| null` | `null` | Controlled active tab ID |
|
|
540
|
+
| `keepMounted` | `boolean` | `true` | Keep all panels in DOM; `false` renders only active panel |
|
|
541
|
+
| `transition` | `'none' \| 'fade' \| 'slide' \| null` | `null` | Panel transition animation (falls back to global config) |
|
|
503
542
|
|
|
504
543
|
**Outputs:**
|
|
505
544
|
|
|
506
|
-
| Output
|
|
507
|
-
|
|
545
|
+
| Output | Type |
|
|
546
|
+
| ----------------- | -------- |
|
|
508
547
|
| `activeTabChange` | `string` |
|
|
509
548
|
|
|
510
549
|
**Content projection:** use `jvTabPanel` directive on `ng-template` to define panel content:
|
|
@@ -526,7 +565,7 @@ Tabs support animated transitions between panels. Configure globally via `provid
|
|
|
526
565
|
|
|
527
566
|
```typescript
|
|
528
567
|
// Global default
|
|
529
|
-
provideJvUi({ tabsTransition: 'fade' })
|
|
568
|
+
provideJvUi({ tabsTransition: 'fade' });
|
|
530
569
|
```
|
|
531
570
|
|
|
532
571
|
```typescript
|
|
@@ -534,11 +573,11 @@ provideJvUi({ tabsTransition: 'fade' })
|
|
|
534
573
|
<jv-tabs transition="slide" [keepMounted]="false">...</jv-tabs>
|
|
535
574
|
```
|
|
536
575
|
|
|
537
|
-
| Transition | `keepMounted=true`
|
|
538
|
-
|
|
539
|
-
| `'none'`
|
|
540
|
-
| `'fade'`
|
|
541
|
-
| `'slide'`
|
|
576
|
+
| Transition | `keepMounted=true` | `keepMounted=false` | Description |
|
|
577
|
+
| ---------- | ---------------------- | ------------------- | ------------------------------------ |
|
|
578
|
+
| `'none'` | Instant switch | Instant switch | No animation |
|
|
579
|
+
| `'fade'` | Opacity cross-fade | Opacity cross-fade | Smooth fade between panels |
|
|
580
|
+
| `'slide'` | Falls back to `'fade'` | Directional slide | Slides left/right based on tab index |
|
|
542
581
|
|
|
543
582
|
**Note:** `slide` requires `keepMounted=false` because it needs to animate both entering and exiting panels simultaneously. When used with `keepMounted=true`, it automatically falls back to `fade`.
|
|
544
583
|
|
|
@@ -584,35 +623,35 @@ import { JvImageSliderComponent, JvSliderImage } from '@devjuliovilla/jv-ui';
|
|
|
584
623
|
|
|
585
624
|
**JvSliderImage:**
|
|
586
625
|
|
|
587
|
-
| Property
|
|
588
|
-
|
|
589
|
-
| `src`
|
|
590
|
-
| `alt`
|
|
591
|
-
| `description` | `string` | No
|
|
592
|
-
| `thumbnail`
|
|
626
|
+
| Property | Type | Required | Description |
|
|
627
|
+
| ------------- | -------- | -------- | ---------------------------------------- |
|
|
628
|
+
| `src` | `string` | Yes | Image URL |
|
|
629
|
+
| `alt` | `string` | Yes | Alternative text for accessibility |
|
|
630
|
+
| `description` | `string` | No | Caption displayed below the image |
|
|
631
|
+
| `thumbnail` | `string` | No | Custom thumbnail URL (defaults to `src`) |
|
|
593
632
|
|
|
594
633
|
**Inputs:**
|
|
595
634
|
|
|
596
|
-
| Input
|
|
597
|
-
|
|
598
|
-
| `images`
|
|
599
|
-
| `showThumbnails`
|
|
600
|
-
| `showDescription` | `boolean`
|
|
635
|
+
| Input | Type | Default | Description |
|
|
636
|
+
| ----------------- | ----------------- | ------- | --------------------------------- |
|
|
637
|
+
| `images` | `JvSliderImage[]` | `[]` | Array of images to display |
|
|
638
|
+
| `showThumbnails` | `boolean` | `true` | Show thumbnail strip below slider |
|
|
639
|
+
| `showDescription` | `boolean` | `true` | Show image description |
|
|
601
640
|
|
|
602
641
|
**Outputs:**
|
|
603
642
|
|
|
604
|
-
| Output
|
|
605
|
-
|
|
643
|
+
| Output | Type | Description |
|
|
644
|
+
| ------------- | -------- | ------------------------------------- |
|
|
606
645
|
| `imageChange` | `number` | Emits index when active image changes |
|
|
607
646
|
|
|
608
647
|
**i18n support:**
|
|
609
648
|
|
|
610
649
|
The component automatically translates aria labels using `JvTranslationService`:
|
|
611
650
|
|
|
612
|
-
| Key
|
|
613
|
-
|
|
614
|
-
| `slider.prevImage`
|
|
615
|
-
| `slider.nextImage`
|
|
651
|
+
| Key | English | Spanish |
|
|
652
|
+
| ---------------------- | ---------------- | ---------------------- |
|
|
653
|
+
| `slider.prevImage` | Previous image | Imagen anterior |
|
|
654
|
+
| `slider.nextImage` | Next image | Imagen siguiente |
|
|
616
655
|
| `slider.thumbnailList` | Image thumbnails | Miniaturas de imagenes |
|
|
617
656
|
|
|
618
657
|
### Features
|
|
@@ -663,34 +702,34 @@ import { JvImageGalleryComponent, JvGalleryImage, JvGalleryAction } from '@devju
|
|
|
663
702
|
|
|
664
703
|
**JvGalleryImage:**
|
|
665
704
|
|
|
666
|
-
| Property
|
|
667
|
-
|
|
668
|
-
| `src`
|
|
669
|
-
| `alt`
|
|
670
|
-
| `thumbnail` | `string` | No
|
|
705
|
+
| Property | Type | Required | Description |
|
|
706
|
+
| ----------- | -------- | -------- | ---------------------------------------- |
|
|
707
|
+
| `src` | `string` | Yes | Image URL |
|
|
708
|
+
| `alt` | `string` | Yes | Alternative text for accessibility |
|
|
709
|
+
| `thumbnail` | `string` | No | Custom thumbnail URL (defaults to `src`) |
|
|
671
710
|
|
|
672
711
|
**JvGalleryAction:**
|
|
673
712
|
|
|
674
|
-
| Property | Type
|
|
675
|
-
|
|
676
|
-
| `id`
|
|
677
|
-
| `label`
|
|
678
|
-
| `icon`
|
|
679
|
-
| `tone`
|
|
713
|
+
| Property | Type | Required | Description |
|
|
714
|
+
| -------- | ---------- | -------- | ------------------------ |
|
|
715
|
+
| `id` | `string` | Yes | Unique action identifier |
|
|
716
|
+
| `label` | `string` | Yes | Button label text |
|
|
717
|
+
| `icon` | `string` | No | Lucide icon name |
|
|
718
|
+
| `tone` | `JvIntent` | No | Button variant |
|
|
680
719
|
|
|
681
720
|
**Inputs:**
|
|
682
721
|
|
|
683
|
-
| Input
|
|
684
|
-
|
|
685
|
-
| `images`
|
|
686
|
-
| `stripHeightVh` | `number`
|
|
687
|
-
| `actions`
|
|
722
|
+
| Input | Type | Default | Description |
|
|
723
|
+
| --------------- | ------------------- | ------- | ------------------------------------------------------------------------------------- |
|
|
724
|
+
| `images` | `JvGalleryImage[]` | `[]` | Array of images to display |
|
|
725
|
+
| `stripHeightVh` | `number` | `25` | Height of the thumbnail strip in viewport-height units, clamped between `0` and `100` |
|
|
726
|
+
| `actions` | `JvGalleryAction[]` | `[]` | Action buttons shown in dialog footer |
|
|
688
727
|
|
|
689
728
|
**Outputs:**
|
|
690
729
|
|
|
691
|
-
| Output
|
|
692
|
-
|
|
693
|
-
| `imageClick`
|
|
730
|
+
| Output | Type | Description |
|
|
731
|
+
| ------------- | --------------------------------------------- | -------------------------------------- |
|
|
732
|
+
| `imageClick` | `JvGalleryImage` | Emits when an image is clicked |
|
|
694
733
|
| `actionClick` | `{ actionId: string; image: JvGalleryImage }` | Emits when an action button is clicked |
|
|
695
734
|
|
|
696
735
|
### Features
|
|
@@ -751,17 +790,17 @@ export class GalleryComponent {
|
|
|
751
790
|
import { JvTextareaComponent } from '@devjuliovilla/jv-ui';
|
|
752
791
|
```
|
|
753
792
|
|
|
754
|
-
| Input
|
|
755
|
-
|
|
756
|
-
| `placeholder` | `string`
|
|
757
|
-
| `required`
|
|
758
|
-
| `invalid`
|
|
759
|
-
| `readonly`
|
|
760
|
-
| `rows`
|
|
761
|
-
| `cols`
|
|
762
|
-
| `maxlength`
|
|
763
|
-
| `describedBy` | `string`
|
|
764
|
-
| `inputId`
|
|
793
|
+
| Input | Type | Default | Description |
|
|
794
|
+
| ------------- | --------- | ----------------- | ---------------------------------------------------- |
|
|
795
|
+
| `placeholder` | `string` | `''` | Placeholder text |
|
|
796
|
+
| `required` | `boolean` | `false` | Mark field as required |
|
|
797
|
+
| `invalid` | `boolean` | `false` | Show invalid state |
|
|
798
|
+
| `readonly` | `boolean` | `false` | Make textarea read-only |
|
|
799
|
+
| `rows` | `number` | `3` | Visible number of rows |
|
|
800
|
+
| `cols` | `number` | — | Visible width in columns |
|
|
801
|
+
| `maxlength` | `number` | — | Maximum character length |
|
|
802
|
+
| `describedBy` | `string` | `''` | ID of description/error element for aria-describedby |
|
|
803
|
+
| `inputId` | `string` | `jv-textarea-{n}` | Auto-generated unique ID |
|
|
765
804
|
|
|
766
805
|
Implements `ControlValueAccessor` — compatible with `[(ngModel)]` and reactive forms via `formControlName`.
|
|
767
806
|
|
|
@@ -796,15 +835,15 @@ export class ProfileComponent {
|
|
|
796
835
|
import { JvCodeComponent } from '@devjuliovilla/jv-ui';
|
|
797
836
|
```
|
|
798
837
|
|
|
799
|
-
| Input
|
|
800
|
-
|
|
801
|
-
| `code`
|
|
802
|
-
| `language` | `string`
|
|
803
|
-
| `title`
|
|
804
|
-
| `font`
|
|
805
|
-
| `editable` | `boolean`
|
|
806
|
-
| `width`
|
|
807
|
-
| `height`
|
|
838
|
+
| Input | Type | Default | Description |
|
|
839
|
+
| ---------- | ------------------------------------------------------------------------- | ------------------ | --------------------------------------------------------------------- |
|
|
840
|
+
| `code` | `string` | — | Code or text content to render |
|
|
841
|
+
| `language` | `string` | `''` | Optional language badge |
|
|
842
|
+
| `title` | `string` | `''` | Optional header title |
|
|
843
|
+
| `font` | `'jetbrains-mono' \| 'fira-code' \| 'cascadia' \| 'consolas' \| 'system'` | `'jetbrains-mono'` | Mono font preset for the rendered block |
|
|
844
|
+
| `editable` | `boolean` | `false` | Renders a textarea-style editing surface instead of read-only preview |
|
|
845
|
+
| `width` | `string` | `'100%'` | CSS width applied to the component |
|
|
846
|
+
| `height` | `string` | `'auto'` | CSS height for the editable surface or minimum preview height |
|
|
808
847
|
|
|
809
848
|
Use `JvCode` for read-only payloads or long single-line content where horizontal scrolling should be preserved instead of wrapping.
|
|
810
849
|
The library does not bundle font files. `JvCode` references common mono families and will use any web font you load at the application level.
|
|
@@ -885,13 +924,13 @@ await dialogService.confirm({
|
|
|
885
924
|
import { JvIconComponent, JV_LUCIDE_ICON_REGISTRY } from '@devjuliovilla/jv-ui';
|
|
886
925
|
```
|
|
887
926
|
|
|
888
|
-
| Input
|
|
889
|
-
|
|
890
|
-
| `name`
|
|
891
|
-
| `size`
|
|
892
|
-
| `strokeWidth` | `number`
|
|
893
|
-
| `decorative`
|
|
894
|
-
| `ariaLabel`
|
|
927
|
+
| Input | Type | Default | Description |
|
|
928
|
+
| ------------- | --------- | ------- | ----------------------------------------------- |
|
|
929
|
+
| `name` | `string` | — | Icon name (from auto-generated Lucide registry) |
|
|
930
|
+
| `size` | `number` | `24` | Width and height in pixels |
|
|
931
|
+
| `strokeWidth` | `number` | `2` | SVG stroke width |
|
|
932
|
+
| `decorative` | `boolean` | `true` | `aria-hidden="true"` when decorative |
|
|
933
|
+
| `ariaLabel` | `string` | — | Accessible label when not decorative |
|
|
895
934
|
|
|
896
935
|
Icons are auto-generated from [lucide-static](https://www.npmjs.com/package/lucide-static) via:
|
|
897
936
|
|
|
@@ -901,7 +940,7 @@ node tools/generate-icons.mjs
|
|
|
901
940
|
|
|
902
941
|
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.
|
|
903
942
|
|
|
904
|
-
|
|
943
|
+
## Layout API
|
|
905
944
|
|
|
906
945
|
### JvDashboardShell
|
|
907
946
|
|
|
@@ -909,47 +948,47 @@ This reads all SVG files from `lucide-static/icons` and produces `jv-icon-regist
|
|
|
909
948
|
import { JvDashboardShellComponent } from '@devjuliovilla/jv-ui';
|
|
910
949
|
```
|
|
911
950
|
|
|
912
|
-
| Input
|
|
913
|
-
|
|
914
|
-
| `title`
|
|
915
|
-
| `sidebarSubtitle`
|
|
916
|
-
| `brandIcon`
|
|
917
|
-
| `navItems`
|
|
918
|
-
| `sidebarCollapsed`
|
|
919
|
-
| `mobileSidebarOpen` | `boolean`
|
|
920
|
-
| `topbarTitle`
|
|
921
|
-
| `topbarSubtitle`
|
|
922
|
-
| `currentTheme`
|
|
923
|
-
| `themeOptions`
|
|
924
|
-
| `topbarActions`
|
|
925
|
-
| `showThemeSelector` | `boolean`
|
|
926
|
-
|
|
927
|
-
| Output
|
|
928
|
-
|
|
929
|
-
| `menuClick`
|
|
930
|
-
| `mobileClose`
|
|
931
|
-
| `sidebarCollapseToggle` | Collapse toggle clicked — collapse/expand sidebar
|
|
932
|
-
| `themeChange`
|
|
933
|
-
| `topbarActionClick`
|
|
951
|
+
| Input | Type | Default | Description |
|
|
952
|
+
| ------------------- | ------------------ | ----------- | ------------------------------------------- |
|
|
953
|
+
| `title` | `string` | — | App / brand title |
|
|
954
|
+
| `sidebarSubtitle` | `string` | `''` | Subtitle below brand |
|
|
955
|
+
| `brandIcon` | `string` | `'monitor'` | Brand Lucide icon |
|
|
956
|
+
| `navItems` | `JvNavItem[]` | `[]` | Navigation items (supports nested children) |
|
|
957
|
+
| `sidebarCollapsed` | `boolean` | `false` | Desktop sidebar collapsed state |
|
|
958
|
+
| `mobileSidebarOpen` | `boolean` | `false` | Mobile sidebar open/closed |
|
|
959
|
+
| `topbarTitle` | `string` | `''` | Topbar page title |
|
|
960
|
+
| `topbarSubtitle` | `string` | `''` | Topbar subtitle |
|
|
961
|
+
| `currentTheme` | `JvTheme` | `'light'` | Active theme value |
|
|
962
|
+
| `themeOptions` | `JvThemeOption[]` | `[]` | Theme selector options |
|
|
963
|
+
| `topbarActions` | `JvTopbarAction[]` | `[]` | Icon buttons in topbar |
|
|
964
|
+
| `showThemeSelector` | `boolean` | `true` | Show theme pills |
|
|
965
|
+
|
|
966
|
+
| Output | Description |
|
|
967
|
+
| ----------------------- | -------------------------------------------------------------- |
|
|
968
|
+
| `menuClick` | Hamburger button clicked — toggle mobile sidebar |
|
|
969
|
+
| `mobileClose` | Backdrop clicked or navigation selected — close mobile sidebar |
|
|
970
|
+
| `sidebarCollapseToggle` | Collapse toggle clicked — collapse/expand sidebar |
|
|
971
|
+
| `themeChange` | Theme pill clicked |
|
|
972
|
+
| `topbarActionClick` | Topbar action button clicked |
|
|
934
973
|
|
|
935
974
|
**Mobile behavior:** at viewports ≤ 900px the sidebar becomes a fixed overlay with slide-in animation (`transform: translateX`) and a semi-transparent backdrop. The sidebar emits `mobileClose` when the backdrop is clicked or a nav link is followed.
|
|
936
975
|
|
|
937
976
|
### JvSidebar
|
|
938
977
|
|
|
939
|
-
| Input
|
|
940
|
-
|
|
941
|
-
| `title`
|
|
942
|
-
| `subtitle`
|
|
943
|
-
| `brandIcon`
|
|
944
|
-
| `items`
|
|
945
|
-
| `collapsed`
|
|
946
|
-
| `mobileOpen` | `boolean`
|
|
947
|
-
| `ariaLabel`
|
|
948
|
-
|
|
949
|
-
| Output
|
|
950
|
-
|
|
951
|
-
| `collapseToggle` | Collapse button clicked
|
|
952
|
-
| `mobileClose`
|
|
978
|
+
| Input | Type | Default | Description |
|
|
979
|
+
| ------------ | ------------- | ---------------------- | --------------------- |
|
|
980
|
+
| `title` | `string` | — | Brand title |
|
|
981
|
+
| `subtitle` | `string` | `''` | Brand subtitle |
|
|
982
|
+
| `brandIcon` | `string` | `'monitor'` | Brand icon |
|
|
983
|
+
| `items` | `JvNavItem[]` | `[]` | Navigation items |
|
|
984
|
+
| `collapsed` | `boolean` | `false` | Collapse to icon-only |
|
|
985
|
+
| `mobileOpen` | `boolean` | `false` | Show on mobile |
|
|
986
|
+
| `ariaLabel` | `string` | `'Sidebar navigation'` | Accessible label |
|
|
987
|
+
|
|
988
|
+
| Output | Description |
|
|
989
|
+
| ---------------- | ------------------------------------------------ |
|
|
990
|
+
| `collapseToggle` | Collapse button clicked |
|
|
991
|
+
| `mobileClose` | Backdrop or nav item interaction — request close |
|
|
953
992
|
|
|
954
993
|
## Responsive Design
|
|
955
994
|
|
|
@@ -964,14 +1003,14 @@ The library includes basic responsive behavior:
|
|
|
964
1003
|
|
|
965
1004
|
## Services
|
|
966
1005
|
|
|
967
|
-
| Service
|
|
968
|
-
|
|
969
|
-
| `JvThemeService`
|
|
970
|
-
| `JvTranslationService`
|
|
971
|
-
| `JvToastService`
|
|
972
|
-
| `JvLoaderService`
|
|
973
|
-
| `JvDialogService`
|
|
974
|
-
| `JvAnnouncementService` | `@devjuliovilla/jv-ui` | Screen-reader live-region announcements
|
|
1006
|
+
| Service | Import Path | Description |
|
|
1007
|
+
| ----------------------- | ---------------------- | -------------------------------------------- |
|
|
1008
|
+
| `JvThemeService` | `@devjuliovilla/jv-ui` | Light / dark / high-contrast theme switching |
|
|
1009
|
+
| `JvTranslationService` | `@devjuliovilla/jv-ui` | Dictionary-based i18n (en/es) |
|
|
1010
|
+
| `JvToastService` | `@devjuliovilla/jv-ui` | Toast notification system |
|
|
1011
|
+
| `JvLoaderService` | `@devjuliovilla/jv-ui` | Full-screen loader with request counter |
|
|
1012
|
+
| `JvDialogService` | `@devjuliovilla/jv-ui` | Programmatic confirm dialogs |
|
|
1013
|
+
| `JvAnnouncementService` | `@devjuliovilla/jv-ui` | Screen-reader live-region announcements |
|
|
975
1014
|
|
|
976
1015
|
## Accessibility
|
|
977
1016
|
|