@devjuliovilla/jv-ui 1.11.2 → 1.12.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,194 @@ 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
+ | `dayMeta` | `JvMonthCalendarDayMeta[]` | `[]` | Marker/counter metadata per day |
85
+ | `ariaLabel` | `string` | localized default | Accessible label for the grid |
86
+
87
+ **Outputs:**
88
+
89
+ | Output | Type |
90
+ |---|---|
91
+ | `selectionChange` | `Date` |
92
+ | `visibleMonthChange` | `Date` |
93
+
94
+ **Day metadata:**
95
+
96
+ | Property | Type | Description |
97
+ |---|---|---|
98
+ | `date` | `Date \| string` | Day associated with the marker |
99
+ | `count` | `number` | Optional numeric badge rendered inside the cell |
100
+ | `tone` | `'primary' \| 'secondary' \| 'success' \| 'warning' \| 'danger' \| 'info' \| 'neutral'` | Visual tone for the badge or dot |
101
+ | `label` | `string` | Extra accessibility text appended to the day `aria-label` |
102
+
103
+ **Template hook:**
104
+
105
+ Use `ng-template[jvMonthCalendarDay]` to fully customize the day cell.
106
+
107
+ **Standalone example:**
108
+
109
+ ```typescript
110
+ import { Component, signal } from '@angular/core';
111
+ import { JvMonthCalendarComponent, JvMonthCalendarDayMeta } from '@devjuliovilla/jv-ui';
112
+
113
+ @Component({
114
+ selector: 'app-calendar-only',
115
+ standalone: true,
116
+ imports: [JvMonthCalendarComponent],
117
+ template: `
118
+ <jv-month-calendar
119
+ [value]="selectedDate()"
120
+ [dayMeta]="calendarMeta"
121
+ (selectionChange)="selectedDate.set($event)"
122
+ />
123
+ `,
124
+ })
125
+ export class CalendarOnlyComponent {
126
+ readonly selectedDate = signal(new Date(2026, 5, 15));
127
+ readonly calendarMeta: JvMonthCalendarDayMeta[] = [
128
+ { date: '2026-06-15', count: 2, tone: 'primary', label: '2 activities' },
129
+ { date: '2026-06-16', count: 1, tone: 'secondary', label: '1 activity' },
130
+ ];
131
+ }
132
+ ```
133
+
134
+ ### JvDayPlanner
135
+
136
+ ```typescript
137
+ import {
138
+ JvDayPlannerComponent,
139
+ JvDayPlannerDetailDirective,
140
+ JvDayPlannerItem,
141
+ JvDayPlannerItemDirective,
142
+ } from '@devjuliovilla/jv-ui';
143
+ ```
144
+
145
+ **Inputs:**
146
+
147
+ | Input | Type | Default | Description |
148
+ |---|---|---|---|
149
+ | `items` | `JvDayPlannerItem[]` | `[]` | Agenda items |
150
+ | `groupByDate` | `boolean` | `false` | Group items under a date heading |
151
+ | `emptyMessage` | `string` | localized default | Empty state copy |
152
+ | `ariaLabel` | `string` | localized default | Accessible label for the agenda |
153
+ | `defaultExpandedItemIds` | `(string \| number)[]` | `[]` | Items whose detail should start expanded |
154
+
155
+ **Outputs:**
156
+
157
+ | Output | Type |
158
+ |---|---|
159
+ | `itemSelect` | `JvDayPlannerItem` |
160
+
161
+ **Planner item shape:**
162
+
163
+ | Property | Type | Description |
164
+ |---|---|---|
165
+ | `id` | `string \| number` | Stable identity |
166
+ | `title` | `string` | Primary label |
167
+ | `date` | `Date \| string \| null` | Logical day when start time is not enough |
168
+ | `start` | `Date \| string \| null` | Optional start datetime |
169
+ | `end` | `Date \| string \| null` | Optional end datetime |
170
+ | `status` | `string` | Status badge label |
171
+ | `statusTone` | `JvTone` | Visual tone for status badge |
172
+ | `type` | `string` | Type/category badge label |
173
+ | `typeTone` | `JvTone` | Visual tone for type badge |
174
+ | `responsible` | `string` | Responsible person |
175
+ | `location` | `string` | Location metadata |
176
+ | `details` | `string` | Expandable detail text |
177
+ | `completed` | `boolean` | Reduced emphasis for completed items |
178
+
179
+ **Template hooks:**
180
+
181
+ - `ng-template[jvDayPlannerItem]` customizes the visible item row
182
+ - `ng-template[jvDayPlannerDetail]` customizes the expanded detail panel
183
+
184
+ **Standalone example:**
185
+
186
+ ```typescript
187
+ import { Component } from '@angular/core';
188
+ import { JvDayPlannerComponent, JvDayPlannerItem } from '@devjuliovilla/jv-ui';
189
+
190
+ @Component({
191
+ selector: 'app-planner-only',
192
+ standalone: true,
193
+ imports: [JvDayPlannerComponent],
194
+ template: `
195
+ <jv-day-planner
196
+ [items]="items"
197
+ [groupByDate]="true"
198
+ (itemSelect)="handleSelect($event)"
199
+ />
200
+ `,
201
+ })
202
+ export class PlannerOnlyComponent {
203
+ readonly items: JvDayPlannerItem[] = [
204
+ {
205
+ id: 1,
206
+ title: 'Venue setup',
207
+ start: '2026-06-15T08:30:00',
208
+ end: '2026-06-15T10:00:00',
209
+ status: 'Scheduled',
210
+ statusTone: 'primary',
211
+ type: 'Logistics',
212
+ responsible: 'Ana Lopez',
213
+ location: 'Main hall',
214
+ details: 'Prepare seating and signage.',
215
+ },
216
+ ];
217
+
218
+ handleSelect(item: JvDayPlannerItem) {
219
+ console.log(item);
220
+ }
221
+ }
222
+ ```
223
+
224
+ ### Combined example
225
+
226
+ Use both components together when you need a left-side month selector and a right-side agenda:
227
+
228
+ ```html
229
+ <jv-month-calendar
230
+ [value]="selectedDate()"
231
+ [dayMeta]="calendarMeta()"
232
+ (selectionChange)="selectedDate.set($event)"
233
+ />
234
+
235
+ <jv-day-planner
236
+ [items]="filteredItems()"
237
+ [groupByDate]="showAll()"
238
+ (itemSelect)="selectedItem.set($event)"
239
+ />
240
+ ```
241
+
59
242
  ## Grid Features
60
243
 
61
244
  | Feature | Description |
@@ -147,10 +330,10 @@ import { JvGridComponent } from '@devjuliovilla/jv-ui';
147
330
  | `pageSizeOptions` | `number[]` | `[10, 20, 50, 100]` | Page size selector options |
148
331
  | `density` | `'compact' \| 'normal' \| 'comfortable'` | `'normal'` | Row density |
149
332
  | `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 |
333
+ | `emptyMessage` | `string` | — | Empty state message |
334
+ | `exportable` | `boolean` | `false` | Show CSV/Excel export buttons |
335
+ | `exportFileName` | `string` | `''` | Base filename used for CSV/Excel exports; the component applies the correct extension |
336
+ | `serverSide` | `boolean` | `false` | Disable client-side processing |
154
337
  | `totalItems` | `number` | `0` | Total items for server-side mode |
155
338
  | `stickyColumns` | `boolean` | `false` | Enable sticky column support |
156
339
  | `resizableColumns` | `boolean` | `false` | Enable column resizing |
@@ -183,7 +366,7 @@ interface Product {
183
366
  <jv-grid
184
367
  [data]="products"
185
368
  [columns]="columns"
186
- [options]="{ selectable: true, exportable: true, exportFileName: 'products', pageSize: 10 }"
369
+ [options]="{ selectable: true, exportable: true, exportFileName: 'products', pageSize: 10 }"
187
370
  [trackBy]="'id'"
188
371
  [selectedIds]="selectedIds"
189
372
  (selectionChange)="selectedIds = $event"