@devjuliovilla/jv-ui 1.11.2 → 1.13.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 CHANGED
@@ -42,6 +42,7 @@ export class App {}
42
42
  | Category | Components |
43
43
  |---|---|
44
44
  | Buttons | `JvButton`, `JvButtonGroup`, `JvIconButton` |
45
+ | Calendar | `JvMonthCalendar`, `JvDayPlanner` — reusable month view and agenda primitives, usable together or independently |
45
46
  | Forms | `JvInput`, `JvTextarea`, `JvCode`, `JvSelect`, `JvCheckbox`, `JvRadio`, `JvSwitch`, `JvDatePicker`, `JvModalSelector`, `JvFileInput`, `JvFormContainer` |
46
47
  | Data Grid | `JvGrid` — full-featured data table (see below) |
47
48
  | Containers | `JvCard`, `JvSection`, `JvDivider` |
@@ -50,12 +51,200 @@ export class App {}
50
51
  | Slider | `JvImageSlider` — responsive image slider with thumbnails and keyboard navigation |
51
52
  | Gallery | `JvImageGallery` — horizontal image gallery with wheel scrolling and full-screen viewer |
52
53
  | Feedback | `JvAlert`, `JvBadge`, `JvLoader`, `JvToast` |
53
- | Dialogs | `JvDialog`, `JvConfirmDialog` |
54
+ | Dialogs | `JvDialog`, `JvConfirmDialog`, `JvWindowModal` — compact dialogs plus a larger workflow overlay surface |
54
55
  | Layout | `JvDashboardShell`, `JvSidebar`, `JvTopbar`, `JvBreadcrumb`, `JvPage` |
55
56
  | Auth Pages | `JvLoginPage`, `JvForgotPasswordPage`, `JvChangePasswordPage` |
56
57
  | Icon | `JvIcon` — Lucide-based icon component with 1500+ auto-generated icons |
57
58
  | Pagination | `JvPagination` — standalone pagination with i18n |
58
59
 
60
+ ## Calendar API
61
+
62
+ The scheduling primitives are split into **two separate components**:
63
+
64
+ - `JvMonthCalendar`: inline month grid with selection, navigation, and day markers
65
+ - `JvDayPlanner`: agenda / list view for scheduled items with optional grouping and expandable details
66
+
67
+ You can use either one on its own, or compose both together in a master-detail scheduling layout.
68
+
69
+ ### JvMonthCalendar
70
+
71
+ ```typescript
72
+ import {
73
+ JvMonthCalendarComponent,
74
+ JvMonthCalendarDayDirective,
75
+ JvMonthCalendarDayMeta,
76
+ } from '@devjuliovilla/jv-ui';
77
+ ```
78
+
79
+ **Inputs:**
80
+
81
+ | Input | Type | Default | Description |
82
+ |---|---|---|---|
83
+ | `value` | `Date \| string \| null` | `undefined` | Selected day |
84
+ | `visibleMonth` | `Date \| string \| null` | `undefined` | Controlled visible month independent from the selected day |
85
+ | `dayMeta` | `JvMonthCalendarDayMeta[]` | `[]` | Marker/counter metadata per day |
86
+ | `ariaLabel` | `string` | localized default | Accessible label for the grid |
87
+ | `monthLabel` | `string` | `Month` | Accessible label for the month selector |
88
+ | `yearLabel` | `string` | `Year` | Accessible label for the year selector |
89
+ | `minYear` | `number` | current year - 10 | Lower year bound for the year selector |
90
+ | `maxYear` | `number` | current year + 10 | Upper year bound for the year selector |
91
+ | `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
+ **Outputs:**
94
+
95
+ | Output | Type |
96
+ |---|---|
97
+ | `selectionChange` | `Date` |
98
+ | `visibleMonthChange` | `Date` |
99
+
100
+ **Day metadata:**
101
+
102
+ | Property | Type | Description |
103
+ |---|---|---|
104
+ | `date` | `Date \| string` | Day associated with the marker |
105
+ | `count` | `number` | Optional numeric badge rendered inside the cell |
106
+ | `tone` | `'primary' \| 'secondary' \| 'success' \| 'warning' \| 'danger' \| 'info' \| 'neutral'` | Visual tone for the badge or dot |
107
+ | `label` | `string` | Extra accessibility text appended to the day `aria-label` |
108
+
109
+ **Template hook:**
110
+
111
+ Use `ng-template[jvMonthCalendarDay]` to fully customize the day cell.
112
+
113
+ **Standalone example:**
114
+
115
+ ```typescript
116
+ import { Component, signal } from '@angular/core';
117
+ import { JvMonthCalendarComponent, JvMonthCalendarDayMeta } from '@devjuliovilla/jv-ui';
118
+
119
+ @Component({
120
+ selector: 'app-calendar-only',
121
+ standalone: true,
122
+ imports: [JvMonthCalendarComponent],
123
+ template: `
124
+ <jv-month-calendar
125
+ [value]="selectedDate()"
126
+ [dayMeta]="calendarMeta"
127
+ (selectionChange)="selectedDate.set($event)"
128
+ />
129
+ `,
130
+ })
131
+ export class CalendarOnlyComponent {
132
+ readonly selectedDate = signal(new Date(2026, 5, 15));
133
+ readonly calendarMeta: JvMonthCalendarDayMeta[] = [
134
+ { date: '2026-06-15', count: 2, tone: 'primary', label: '2 activities' },
135
+ { date: '2026-06-16', count: 1, tone: 'secondary', label: '1 activity' },
136
+ ];
137
+ }
138
+ ```
139
+
140
+ ### JvDayPlanner
141
+
142
+ ```typescript
143
+ import {
144
+ JvDayPlannerComponent,
145
+ JvDayPlannerDetailDirective,
146
+ JvDayPlannerItem,
147
+ JvDayPlannerItemDirective,
148
+ } from '@devjuliovilla/jv-ui';
149
+ ```
150
+
151
+ **Inputs:**
152
+
153
+ | Input | Type | Default | Description |
154
+ |---|---|---|---|
155
+ | `items` | `JvDayPlannerItem[]` | `[]` | Agenda items |
156
+ | `groupByDate` | `boolean` | `false` | Group items under a date heading |
157
+ | `emptyMessage` | `string` | localized default | Empty state copy |
158
+ | `ariaLabel` | `string` | localized default | Accessible label for the agenda |
159
+ | `defaultExpandedItemIds` | `(string \| number)[]` | `[]` | Items whose detail should start expanded |
160
+
161
+ **Outputs:**
162
+
163
+ | Output | Type |
164
+ |---|---|
165
+ | `itemSelect` | `JvDayPlannerItem` |
166
+
167
+ **Planner item shape:**
168
+
169
+ | Property | Type | Description |
170
+ |---|---|---|
171
+ | `id` | `string \| number` | Stable identity |
172
+ | `title` | `string` | Primary label |
173
+ | `date` | `Date \| string \| null` | Logical day when start time is not enough |
174
+ | `start` | `Date \| string \| null` | Optional start datetime |
175
+ | `end` | `Date \| string \| null` | Optional end datetime |
176
+ | `status` | `string` | Status badge label |
177
+ | `statusTone` | `JvTone` | Visual tone for status badge |
178
+ | `type` | `string` | Type/category badge label |
179
+ | `typeTone` | `JvTone` | Visual tone for type badge |
180
+ | `responsible` | `string` | Responsible person |
181
+ | `location` | `string` | Location metadata |
182
+ | `details` | `string` | Expandable detail text |
183
+ | `completed` | `boolean` | Reduced emphasis for completed items |
184
+
185
+ **Template hooks:**
186
+
187
+ - `ng-template[jvDayPlannerItem]` customizes the visible item row
188
+ - `ng-template[jvDayPlannerDetail]` customizes the expanded detail panel
189
+
190
+ **Standalone example:**
191
+
192
+ ```typescript
193
+ import { Component } from '@angular/core';
194
+ import { JvDayPlannerComponent, JvDayPlannerItem } from '@devjuliovilla/jv-ui';
195
+
196
+ @Component({
197
+ selector: 'app-planner-only',
198
+ standalone: true,
199
+ imports: [JvDayPlannerComponent],
200
+ template: `
201
+ <jv-day-planner
202
+ [items]="items"
203
+ [groupByDate]="true"
204
+ (itemSelect)="handleSelect($event)"
205
+ />
206
+ `,
207
+ })
208
+ export class PlannerOnlyComponent {
209
+ readonly items: JvDayPlannerItem[] = [
210
+ {
211
+ id: 1,
212
+ title: 'Venue setup',
213
+ start: '2026-06-15T08:30:00',
214
+ end: '2026-06-15T10:00:00',
215
+ status: 'Scheduled',
216
+ statusTone: 'primary',
217
+ type: 'Logistics',
218
+ responsible: 'Ana Lopez',
219
+ location: 'Main hall',
220
+ details: 'Prepare seating and signage.',
221
+ },
222
+ ];
223
+
224
+ handleSelect(item: JvDayPlannerItem) {
225
+ console.log(item);
226
+ }
227
+ }
228
+ ```
229
+
230
+ ### Combined example
231
+
232
+ Use both components together when you need a left-side month selector and a right-side agenda:
233
+
234
+ ```html
235
+ <jv-month-calendar
236
+ [value]="selectedDate()"
237
+ [dayMeta]="calendarMeta()"
238
+ (selectionChange)="selectedDate.set($event)"
239
+ />
240
+
241
+ <jv-day-planner
242
+ [items]="filteredItems()"
243
+ [groupByDate]="showAll()"
244
+ (itemSelect)="selectedItem.set($event)"
245
+ />
246
+ ```
247
+
59
248
  ## Grid Features
60
249
 
61
250
  | Feature | Description |
@@ -147,10 +336,10 @@ import { JvGridComponent } from '@devjuliovilla/jv-ui';
147
336
  | `pageSizeOptions` | `number[]` | `[10, 20, 50, 100]` | Page size selector options |
148
337
  | `density` | `'compact' \| 'normal' \| 'comfortable'` | `'normal'` | Row density |
149
338
  | `loading` | `boolean` | `false` | Show loading spinner |
150
- | `emptyMessage` | `string` | — | Empty state message |
151
- | `exportable` | `boolean` | `false` | Show CSV/Excel export buttons |
152
- | `exportFileName` | `string` | `''` | Base filename used for CSV/Excel exports; the component applies the correct extension |
153
- | `serverSide` | `boolean` | `false` | Disable client-side processing |
339
+ | `emptyMessage` | `string` | — | Empty state message |
340
+ | `exportable` | `boolean` | `false` | Show CSV/Excel export buttons |
341
+ | `exportFileName` | `string` | `''` | Base filename used for CSV/Excel exports; the component applies the correct extension |
342
+ | `serverSide` | `boolean` | `false` | Disable client-side processing |
154
343
  | `totalItems` | `number` | `0` | Total items for server-side mode |
155
344
  | `stickyColumns` | `boolean` | `false` | Enable sticky column support |
156
345
  | `resizableColumns` | `boolean` | `false` | Enable column resizing |
@@ -183,7 +372,7 @@ interface Product {
183
372
  <jv-grid
184
373
  [data]="products"
185
374
  [columns]="columns"
186
- [options]="{ selectable: true, exportable: true, exportFileName: 'products', pageSize: 10 }"
375
+ [options]="{ selectable: true, exportable: true, exportFileName: 'products', pageSize: 10 }"
187
376
  [trackBy]="'id'"
188
377
  [selectedIds]="selectedIds"
189
378
  (selectionChange)="selectedIds = $event"