@nova-design-system/nova-react 3.2.0 → 3.4.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.
Files changed (49) hide show
  1. package/dist/cjs/{index-B2jv2KXv.js → index-CrgVjOZF.js} +1121 -1100
  2. package/dist/cjs/index.js +1 -1
  3. package/dist/cjs/{nv-alert.entry-pxBJfmIm.js → nv-alert.entry-CW72ajnD.js} +7 -7
  4. package/dist/cjs/{nv-avatar.entry-CHtVctSK.js → nv-avatar.entry-D9wUCu5K.js} +7 -7
  5. package/dist/cjs/{nv-badge_2.entry-BO88KO1O.js → nv-badge_2.entry-CQs2Sf6G.js} +1 -1
  6. package/dist/cjs/{nv-breadcrumb.entry-7azRtyl5.js → nv-breadcrumb.entry-CGrSsjAL.js} +1 -1
  7. package/dist/cjs/{nv-breadcrumbs.entry-DfZVMKpY.js → nv-breadcrumbs.entry-HStUGnwu.js} +1 -1
  8. package/dist/cjs/{nv-button.entry-DW9SblsY.js → nv-button.entry-BJfYc4Ow.js} +7 -7
  9. package/dist/cjs/{nv-calendar.entry-BeayRRor.js → nv-calendar.entry-Co8f_3E5.js} +396 -147
  10. package/dist/cjs/{nv-col.entry-C6oEkSbI.js → nv-col.entry-PJML3P46.js} +1 -1
  11. package/dist/cjs/{nv-datagrid.entry-xhQP6JJP.js → nv-datagrid.entry-Bpwt9yDb.js} +50 -17
  12. package/dist/cjs/{nv-datagridcolumn.entry-CjYmo4fM.js → nv-datagridcolumn.entry-Dfifeiia.js} +1 -1
  13. package/dist/cjs/{nv-dialog.entry-mxETaZbc.js → nv-dialog.entry-eUEzDdrS.js} +3 -3
  14. package/dist/cjs/{nv-dialogfooter_2.entry-DnLg2DHy.js → nv-dialogfooter_2.entry-HQyyE6VN.js} +3 -3
  15. package/dist/cjs/{nv-fieldcheckbox.entry-Be9__i15.js → nv-fieldcheckbox.entry-C5AMgttR.js} +1 -1
  16. package/dist/cjs/nv-fielddate.entry-Dkqz-UqJ.js +303 -0
  17. package/dist/cjs/nv-fielddaterange.entry-D6QmyWHp.js +462 -0
  18. package/dist/cjs/{nv-fielddropdown.entry-BPwviyCp.js → nv-fielddropdown.entry-BpZz90ob.js} +2 -2
  19. package/dist/cjs/{nv-fielddropdownitem.entry-BGuUR9KP.js → nv-fielddropdownitem.entry-BbJ9SKGo.js} +1 -1
  20. package/dist/cjs/{nv-fieldmultiselect.entry-Lrxr1gsi.js → nv-fieldmultiselect.entry-mnYvhkj0.js} +2 -2
  21. package/dist/cjs/nv-fieldnumber.entry-B5ED8fCU.js +130 -0
  22. package/dist/cjs/nv-fieldpassword.entry-ohASip15.js +121 -0
  23. package/dist/cjs/{nv-fieldradio.entry-CDu8xs0p.js → nv-fieldradio.entry-BPipemAC.js} +4 -4
  24. package/dist/cjs/{nv-fieldselect.entry-NEdv8bQK.js → nv-fieldselect.entry-BWZX6L-B.js} +7 -7
  25. package/dist/cjs/{nv-fieldslider.entry-51gF9XPz.js → nv-fieldslider.entry-nmE8TjBA.js} +28 -23
  26. package/dist/cjs/nv-fieldtext.entry-DxoznMYV.js +123 -0
  27. package/dist/cjs/nv-fieldtextarea.entry-BccBiMKe.js +198 -0
  28. package/dist/cjs/{nv-fieldtime.entry-MbaWbVtc.js → nv-fieldtime.entry-BmQ5DFbN.js} +67 -67
  29. package/dist/cjs/{nv-icon.entry-BSSHr-ud.js → nv-icon.entry-DE-sMmDp.js} +8 -8
  30. package/dist/cjs/{nv-iconbutton_2.entry-DMaO-JWz.js → nv-iconbutton_2.entry-DguqeTa3.js} +3 -3
  31. package/dist/cjs/{nv-menu.entry-D5_lj9XB.js → nv-menu.entry-UTPRtlti.js} +2 -2
  32. package/dist/cjs/{nv-menuitem.entry-fhnYI91K.js → nv-menuitem.entry-CaRqhVtk.js} +2 -2
  33. package/dist/cjs/{nv-popover.entry-CYqBaVbr.js → nv-popover.entry-ByFhVB2j.js} +3 -3
  34. package/dist/cjs/{nv-row.entry-BUheLufV.js → nv-row.entry-BIwxIl3Q.js} +2 -2
  35. package/dist/cjs/{nv-stack.entry-DNPce51E.js → nv-stack.entry-xDwyG0Xr.js} +2 -2
  36. package/dist/cjs/{nv-table.entry-DXQM8l3t.js → nv-table.entry-DCMcpbpc.js} +3 -3
  37. package/dist/cjs/{nv-tablecolumn.entry-DROQK_0c.js → nv-tablecolumn.entry-D_kTZ7Mp.js} +1 -1
  38. package/dist/cjs/{nv-toggle.entry-fMzTrdte.js → nv-toggle.entry-tds7tIzF.js} +3 -3
  39. package/dist/cjs/{nv-tooltip.entry-yB2Ek1Cz.js → nv-tooltip.entry-PfQ2HgFG.js} +2 -2
  40. package/dist/generated/components.js +9 -4
  41. package/dist/types/generated/components.d.ts +15 -4
  42. package/package.json +2 -2
  43. package/dist/cjs/nv-fielddate.entry-BlNily-X.js +0 -269
  44. package/dist/cjs/nv-fielddaterange.entry-CycpKoJd.js +0 -408
  45. package/dist/cjs/nv-fieldnumber.entry-B1VySoWj.js +0 -130
  46. package/dist/cjs/nv-fieldpassword.entry-D7Qlx7Bh.js +0 -121
  47. package/dist/cjs/nv-fieldtext.entry-Bug9zMgo.js +0 -123
  48. package/dist/cjs/nv-fieldtextarea.entry-D44HbsVQ.js +0 -198
  49. /package/dist/cjs/{constants-b97e736d-BzFAKCkR.js → constants-4faa1fae-BzFAKCkR.js} +0 -0
@@ -1,7 +1,7 @@
1
1
  'use strict';
2
2
 
3
- var index = require('./index-B2jv2KXv.js');
4
- var constantsB97e736d = require('./constants-b97e736d-BzFAKCkR.js');
3
+ var index = require('./index-CrgVjOZF.js');
4
+ var constants4faa1fae = require('./constants-4faa1fae-BzFAKCkR.js');
5
5
  var _commonjsHelpers1789f0cf = require('./_commonjsHelpers-1789f0cf-BJu3ubxk.js');
6
6
  require('react');
7
7
 
@@ -159,9 +159,18 @@ function isSameOrAfter(date, compareDate, options) {
159
159
  * @returns {number} Week number
160
160
  */
161
161
  function getWeekNumber(date) {
162
- const startOfYear = new Date(date.getFullYear(), 0, 1);
163
- const pastDaysOfYear = (date.getTime() - startOfYear.getTime()) / 86400000;
164
- return Math.ceil((pastDaysOfYear + startOfYear.getDay() + 1) / 7);
162
+ // Create a copy of the date to avoid modifying the original
163
+ const d = new Date(Date.UTC(date.getFullYear(), date.getMonth(), date.getDate()));
164
+ // Adjust to the same week Thursday (ISO 8601)
165
+ d.setUTCDate(d.getUTCDate() + 3 - ((d.getUTCDay() + 6) % 7));
166
+ // Calculate the first Thursday of the year
167
+ const week1 = new Date(Date.UTC(d.getUTCFullYear(), 0, 4));
168
+ // Calculate the week number
169
+ return (1 +
170
+ Math.round(((d.getTime() - week1.getTime()) / 86400000 -
171
+ 3 +
172
+ ((week1.getUTCDay() + 6) % 7)) /
173
+ 7));
165
174
  }
166
175
  /**
167
176
  * Convert a date string/Date to a Date without timezone offset
@@ -226,15 +235,200 @@ function parseDate(dateInput, dateFormat) {
226
235
  parsed = dayjs(dateInput, dateFormat, true);
227
236
  }
228
237
  if (!parsed.isValid()) {
229
- console.error(`Parsing error:`, {
230
- dateInput,
231
- dateFormat: dateFormat,
232
- });
238
+ // Check if the date input contains placeholder characters (incomplete input from Inputmask)
239
+ // This specifically targets partial dates being typed with placeholder characters
240
+ const hasPlaceholderChars = typeof dateInput === 'string' &&
241
+ (dateInput.includes('_') ||
242
+ dateInput.includes('-_') ||
243
+ dateInput.includes('/_') ||
244
+ dateInput.includes('._'));
245
+ // Check if it looks like a partial date being typed (starts with valid pattern)
246
+ const looksLikePartialDate = typeof dateInput === 'string' &&
247
+ dateInput.length < dateFormat.length &&
248
+ /^[\d\-/.]*$/.test(dateInput) && // Only contains digits and date separators
249
+ dateInput.length > 0;
250
+ const isIncompleteInput = hasPlaceholderChars || looksLikePartialDate;
251
+ // Only log error if it's not an incomplete input (to avoid spam during typing)
252
+ if (!isIncompleteInput) {
253
+ console.error(`Parsing error:`, {
254
+ dateInput,
255
+ dateFormat: dateFormat,
256
+ });
257
+ }
233
258
  return null;
234
259
  }
235
260
  return parsed.toDate();
236
261
  }
237
262
 
263
+ /**
264
+ * Renders a single day cell in the calendar grid
265
+ * @param {DayCellProps} props - Component properties
266
+ * @returns {JSX.Element} JSX element representing a day cell
267
+ */
268
+ const DayCell = props => {
269
+ const { date, dayOfMonth, isCurrentMonth, isSelected, isInRange, isStart, isEnd, isToday, isDisabled, onClick, } = props;
270
+ // Build CSS classes for the day cell
271
+ const dayClasses = [
272
+ 'day',
273
+ isSelected ? 'selected' : '',
274
+ isStart ? 'range-start' : '',
275
+ isEnd ? 'range-end' : '',
276
+ isInRange ? 'in-range' : '',
277
+ isDisabled ? 'disabled' : '',
278
+ !isCurrentMonth ? 'outside-month' : '',
279
+ isToday ? 'is-today' : '',
280
+ ]
281
+ .filter(Boolean)
282
+ .join(' ');
283
+ const handleClick = () => {
284
+ if (!isDisabled && onClick) {
285
+ onClick(date);
286
+ }
287
+ };
288
+ return (
289
+ // eslint-disable-next-line react/jsx-no-bind
290
+ index.h("div", { class: dayClasses, onClick: handleClick, "aria-disabled": isDisabled }, dayOfMonth));
291
+ };
292
+
293
+ /**
294
+ * Renders the action buttons for the calendar (Cancel/OK)
295
+ * @param {CalendarActionsProps} props - Component properties
296
+ * @returns {JSX.Element} JSX element representing the action buttons
297
+ */
298
+ const CalendarActions = props => {
299
+ const { onReset, onConfirm, useSlot = false } = props;
300
+ return (index.h("div", { class: "datepicker-actions" }, useSlot ? (index.h("slot", { name: "actions" },
301
+ index.h("nv-button", { emphasis: "low", size: "xs", onClick: onReset }, "Cancel"),
302
+ index.h("nv-button", { size: "xs", onClick: onConfirm }, "OK"))) : (index.h("div", null,
303
+ index.h("nv-button", { emphasis: "low", size: "xs", onClick: onReset }, "Cancel"),
304
+ index.h("nv-button", { size: "xs", onClick: onConfirm }, "OK")))));
305
+ };
306
+
307
+ /**
308
+ * Renders the week numbers column for the calendar
309
+ * @param {WeekNumbersProps} props - Component properties
310
+ * @returns {JSX.Element} JSX element representing the week numbers
311
+ */
312
+ const WeekNumbers = props => {
313
+ const { weeks, localizedWeekText, selectionType, onWeekSelect, calendarIndex, } = props;
314
+ /**
315
+ * Handles click on a week number for range selection
316
+ * @param {Array<WeekData>} week - Week data
317
+ */
318
+ const handleWeekClick = (week) => {
319
+ if (selectionType === 'range') {
320
+ const dates = week.map(d => d.date);
321
+ onWeekSelect(dates, calendarIndex);
322
+ }
323
+ };
324
+ /**
325
+ * Creates a click handler for a specific week
326
+ * @param {Array<WeekData>} week - Week data
327
+ * @returns {() => void} Click handler function
328
+ */
329
+ const createWeekHandler = (week) => {
330
+ return () => handleWeekClick(week);
331
+ };
332
+ return (index.h("div", { class: "week-numbers" },
333
+ index.h("div", { class: "week-header" }, localizedWeekText),
334
+ weeks.map((week, weekIndex) => {
335
+ var _a;
336
+ const firstDayWithDate = ((_a = week.find(d => d.date)) === null || _a === void 0 ? void 0 : _a.date) || new Date();
337
+ const weekNumber = getWeekNumber(firstDayWithDate);
338
+ const isClickable = selectionType === 'range';
339
+ return (index.h("div", { class: `week-number ${isClickable ? 'clickable' : ''}`, onClick: createWeekHandler(week), key: `week-${weekIndex}`, role: isClickable ? 'button' : undefined, tabindex: isClickable ? 0 : undefined }, weekNumber));
340
+ })));
341
+ };
342
+
343
+ /**
344
+ * Renders the shortcuts for quick date selection
345
+ * @param {CalendarShortcutsProps} props - Component properties
346
+ * @returns {JSX.Element | null} JSX element representing the shortcuts or null if no shortcuts
347
+ */
348
+ const CalendarShortcuts = props => {
349
+ const { shortcuts, placement, onShortcutClick } = props;
350
+ if (!shortcuts || shortcuts.length === 0) {
351
+ return null;
352
+ }
353
+ /**
354
+ * Creates a click handler for a specific shortcut
355
+ * @param {ShortcutData} shortcut - The shortcut data
356
+ * @returns {() => void} Click handler function
357
+ */
358
+ const createShortcutHandler = (shortcut) => {
359
+ return () => onShortcutClick(shortcut);
360
+ };
361
+ return (index.h("div", { class: `shortcuts-container shortcuts-placement-${placement}` }, shortcuts.map((shortcut, index$1) => (index.h("nv-button", { key: `shortcut-${index$1}`, emphasis: "lower", size: "xs", "aria-label": shortcut.label, onClick: createShortcutHandler(shortcut) }, shortcut.label)))));
362
+ };
363
+
364
+ /**
365
+ * Renders the calendar header with navigation and date controls
366
+ * @param {CalendarHeaderProps} props - Component properties
367
+ * @returns {JSX.Element} JSX element representing the calendar header
368
+ */
369
+ const CalendarHeader = props => {
370
+ const { currentDate, months, numberOfCalendars, calendarIndex, monthOffset, onMonthChange, onMonthSelect, onYearChange, } = props;
371
+ /**
372
+ * Creates navigation handler for month change
373
+ * @param {number} direction - Direction of navigation (-1 or 1)
374
+ * @returns {() => void} Navigation handler function
375
+ */
376
+ const createNavigationHandler = (direction) => {
377
+ return () => onMonthChange(direction);
378
+ };
379
+ /**
380
+ * Creates month selection handler
381
+ * @param {number} offset - Month offset
382
+ * @returns {(event: Event) => void} Month selection handler function
383
+ */
384
+ const createMonthSelectHandler = (offset) => {
385
+ return (event) => onMonthSelect(event, offset);
386
+ };
387
+ /**
388
+ * Creates year change handler
389
+ * @param {number} offset - Month offset
390
+ * @returns {(event: Event) => void} Year change handler function
391
+ */
392
+ const createYearChangeHandler = (offset) => {
393
+ return (event) => onYearChange(event, offset);
394
+ };
395
+ const currentMonth = (currentDate.getUTCMonth() + monthOffset) % 12;
396
+ const currentYear = currentDate.getUTCFullYear() +
397
+ Math.floor((currentDate.getUTCMonth() + monthOffset) / 12);
398
+ return (index.h("div", { class: "header" },
399
+ numberOfCalendars > 1 && calendarIndex === 0 && (index.h("nv-iconbutton", { class: "nav-left", emphasis: "lower", name: "chevron-left", onClick: createNavigationHandler(-1) })),
400
+ index.h("div", { class: "date-controls" },
401
+ index.h("select", { class: "month-select mr-4", onChange: createMonthSelectHandler(monthOffset) }, months.map(month => (index.h("option", { key: month.value, value: month.value, selected: month.value === currentMonth }, month.label)))),
402
+ index.h("input", { type: "number", class: "year-input", min: "1950", max: "2100", value: currentYear, onChange: createYearChangeHandler(monthOffset) })),
403
+ numberOfCalendars === 1 && (index.h("div", { class: "nav-buttons" },
404
+ index.h("nv-iconbutton", { emphasis: "lower", name: "chevron-left", onClick: createNavigationHandler(-1) }),
405
+ index.h("nv-iconbutton", { emphasis: "lower", name: "chevron-right", onClick: createNavigationHandler(1) }))),
406
+ numberOfCalendars > 1 && calendarIndex === numberOfCalendars - 1 && (index.h("nv-iconbutton", { emphasis: "lower", name: "chevron-right", onClick: createNavigationHandler(1), class: "nav-right" }))));
407
+ };
408
+
409
+ /**
410
+ * Renders the calendar grid with day headers and day cells
411
+ * @param {CalendarGridProps} props - Component properties
412
+ * @returns {JSX.Element} JSX element representing the calendar grid
413
+ */
414
+ const CalendarGrid = props => {
415
+ const { days, dayNames, selectionType, selectedDate, startDate, endDate, isUTCMode, onDayClick, isDateInRange, isToday, } = props;
416
+ return (index.h("div", { class: "days-container" },
417
+ index.h("div", { class: "days-header" }, dayNames.map((day, index$1) => (index.h("div", { class: "day-header", key: `day-header-${index$1}` }, day)))),
418
+ index.h("div", { class: "days-grid" }, days.map(day => {
419
+ const date = day.date;
420
+ if (!date)
421
+ return null;
422
+ const isSelected = selectionType === 'single' &&
423
+ isSameDate(date, selectedDate, { isUTCMode });
424
+ const isInRange = isDateInRange(date);
425
+ const isStart = isSameDate(date, startDate, { isUTCMode });
426
+ const isEnd = isSameDate(date, endDate, { isUTCMode });
427
+ const isTodayDate = isToday(date);
428
+ return (index.h(DayCell, { date: date, dayOfMonth: day.dayOfMonth, isCurrentMonth: day.isCurrentMonth, isSelected: isSelected, isInRange: isInRange, isStart: isStart, isEnd: isEnd, isToday: isTodayDate, isDisabled: day.isDisabled, selectionType: selectionType, onClick: onDayClick }));
429
+ }))));
430
+ };
431
+
238
432
  const nvCalendarCss = "nv-calendar{display:block}.datepicker-root{display:flex;justify-content:center;align-items:flex-start;width:auto}.datepicker-container{font-family:system-ui, sans-serif;display:flex;flex-direction:column;align-items:stretch;background:var(--components-calendar-background);border-radius:var(--calendar-radius);padding:var(--calendar-padding);box-shadow:0px var(--shadow-y-axis-md-1) var(--shadow-blur-md-1) var(--shadow-spread-md, 0) var(--shadow-color-opacity-0), 0px var(--shadow-y-axis-md-2) var(--shadow-blur-md-2) var(--shadow-spread-md, 0) var(--shadow-color-opacity-2);border:1px solid var(--components-calendar-border);width:auto;max-width:100%}.datepicker-container-single{max-width:300px}.datepicker-container-single .datepicker-wrapper:has(.shortcuts-placement-left),.datepicker-container-single .datepicker-wrapper:has(.shortcuts-placement-right){max-width:410px !important}.datepicker-container-single:has(.shortcuts-placement-left),.datepicker-container-single:has(.shortcuts-placement-right){max-width:410px !important}.datepicker-wrapper{display:flex;justify-content:center;align-items:flex-start;gap:var(--calendar-gap-x);width:auto;overflow-x:hidden}.datepicker-wrapper::-webkit-scrollbar{width:6px;height:6px}.datepicker-wrapper::-webkit-scrollbar-track{background-color:var(--color-level-10-background);border-radius:9999px}.datepicker-wrapper::-webkit-scrollbar-thumb{background-color:var(--color-gray-200);border-radius:9999px}.datepicker-wrapper.single{justify-content:center}.calendar-container{display:flex;flex-direction:column;align-items:center;padding:var(--calendar-padding);width:auto;position:relative}.calendar-separator{width:1px;background:var(--components-calendar-border);height:auto;min-height:100%;margin:0 10px}.header{display:flex;justify-content:start;align-items:center;margin-bottom:var(--calendar-header-margin-bottom);width:100%}.header nv-iconbutton{width:var(--calendar-header-button-size);height:var(--calendar-header-button-size)}.nav-buttons{display:flex;gap:var(--spacing-0);margin-left:auto}.nav-left{order:-1}.date-controls{display:flex;gap:var(--spacing-1);align-items:center;min-height:34px;justify-content:center}.datepicker-container-single .date-controls{justify-content:flex-start}.datepicker-container:not(.datepicker-container-single) .date-controls{justify-content:start;flex-grow:1}.date-controls .month-select,.date-controls .year-input{background:transparent !important}.calendar-wrapper:nth-child(n+2) .datepicker-container{margin-left:42px}.calendar-grid{display:grid;grid-template-columns:auto 1fr;column-gap:var(--calendar-weeks-calendar-gap-x);position:relative}.calendar-grid.slide-left{animation:slideLeft 0.3s ease-out}.calendar-grid.slide-right{animation:slideRight 0.3s ease-out}.week-numbers{display:grid;grid-template-rows:var(--calendar-cell-size) repeat(6, var(--calendar-cell-size));background:var(--components-calendar-weeks-background);color:var(--components-calendar-weeks-text);border-radius:var(--calendar-weeks-radius);width:var(--calendar-weeks-size);row-gap:var(--calendar-grid-gap-y)}.week-numbers .clickable{cursor:pointer}.week-numbers .clickable:hover{background-color:var(--components-calendar-weeks-background-hover);color:var(--components-calendar-weeks-text-hover);border-radius:var(--calendar-radius)}.week-header,.week-number{display:grid;place-items:center;font-size:var(--calendar-cell-font-size)}.week-header{font-weight:700;color:var(--components-calendar-weeks-text)}.week-number{color:var(--components-calendar-cell-text)}.days-container{display:grid;grid-template-rows:auto 1fr;row-gap:var(--calendar-grid-gap-y)}.days-header{display:grid;grid-template-columns:repeat(7, var(--calendar-cell-size));height:var(--calendar-cell-size)}.day-header{display:grid;place-items:center;font-size:var(--calendar-cell-font-size);color:var(--components-calendar-cell-text)}.days-grid{display:grid;grid-template-columns:repeat(7, var(--calendar-cell-size));grid-template-rows:repeat(6, var(--calendar-cell-size));animation:fadeIn 0.2s ease-in;row-gap:var(--calendar-grid-gap-y);z-index:0}.day{display:grid;place-items:center;width:var(--calendar-cell-size);height:var(--calendar-cell-size);font-size:var(--calendar-cell-font-size);border-radius:var(--calendar-cell-radius);cursor:pointer;border:none;background:transparent;transition:all 0.2s ease;text-align:center;animation:scaleIn 0.2s ease-out}.day:hover:not(.disabled,.empty,.selected){background:var(--components-calendar-cell-background-hover);color:var(--components-calendar-cell-text-hover)}.day.selected,.day.selected:hover .day.is-today.selected,.day.is-today.selected:hover{background:var(--components-calendar-cell-background-selected);color:var(--components-calendar-cell-text-selected) !important}.day.disabled{opacity:var(--opacity-disabled);cursor:not-allowed}.day.outside-month{color:var(--components-calendar-cell-text);opacity:var(--opacity-disabled)}.day.outside-month.selected{opacity:1 !important;color:var(--components-calendar-cell-text-selected)}.day.outside-month.in-range{opacity:0.5 !important;background-color:var(--components-calendar-cell-background-in-range);color:var(--components-calendar-cell-text-in-range)}.day.outside-month.in-range:hover{opacity:0.7 !important;background-color:var(--components-calendar-cell-background-in-range)}.day.in-range{background:var(--components-calendar-cell-background-in-range);color:var(--components-calendar-cell-text-in-range);border-radius:0;position:relative}.day.range-start,.day.range-start:focus,.day.range-start:hover,.day.range-end,.day.range-end:focus,.day.range-end:hover{background-color:var(--components-calendar-cell-background-selected) !important;color:var(--components-calendar-cell-text-selected) !important}.day.range-start,.day.range-end,.day.range-start.is-today,.day.range-end.is-today{background:var(--components-calendar-cell-background-selected);color:var(--components-calendar-cell-text-selected);position:relative;border-radius:var(--radius-rounded-full)}.day.range-start:hover,.day.range-end:hover,.day.range-start.is-today:hover,.day.range-end.is-today:hover{color:var(--components-calendar-cell-text-today)}.day.range-start:before,.day.range-end:before,.day.range-start.is-today:before,.day.range-end.is-today:before{content:\"\";position:absolute;bottom:0;left:0;right:0;top:0;z-index:-1;background-color:var(--components-calendar-cell-background-in-range);border-radius:var(--radius-rounded-full);width:auto;height:auto}.day.range-start:has(~.range-end):before,.day.range-start:has(+.in-range):before{border-top-right-radius:0;border-bottom-right-radius:0}.day.range-end:before{border-top-left-radius:0 !important;border-bottom-left-radius:0 !important}.day.outside-month.range-start,.day.outside-month.range-end{opacity:1 !important;background:var(--components-calendar-cell-background-selected) !important;color:var(--components-calendar-cell-text-selected)}.day.is-today{font-weight:700;position:relative;color:var(--components-calendar-cell-text-today)}.day.is-today.range-start,.day.is-today.range-end{color:var(--components-calendar-cell-text-selected)}.day.is-today.range-start:hover,.day.is-today.range-end:hover{color:var(--components-calendar-cell-text-today)}.day.is-today::after{content:\"\";position:absolute;bottom:var(--spacing-1);left:50%;transform:translateX(-50%);width:var(--calendar-cell-dot-size);height:var(--calendar-cell-dot-size);background-color:currentColor;border-radius:50%}.day.is-today.selected::after{color:var(--components-calendar-cell-text-selected)}.day.is-today.selected::after::after{background-color:var(--components-calendar-cell-dot-selected)}.calendar-footer{display:flex;gap:var(--spacing-1);justify-content:flex-start;width:100%;flex-wrap:wrap}.footer-placement-left{justify-content:flex-start}.footer-placement-right{justify-content:flex-end}.footer-placement-center{justify-content:center}.datepicker-controls{display:flex;flex-direction:column;border-top:1px solid var(--components-calendar-border);padding:var(--calendar-controls-padding-top) var(--calendar-padding) var(--calendar-padding);gap:var(--calendar-grid-gap-y);margin-top:var(--calendar-controls-margin-top)}.datepicker-actions{display:flex;justify-content:flex-end;gap:var(--spacing-1);width:100%}.datepicker-actions slot-fb{display:contents !important}.calendar-footer+.datepicker-actions{margin-top:0}.shortcuts-placement-left,.shortcuts-placement-right{display:flex;flex-direction:column;gap:var(--spacing-1);margin-top:var(--spacing-4)}.shortcuts-placement-left{align-items:flex-end}.shortcuts-placement-right{align-items:flex-start}@keyframes slideLeft{from{opacity:0;transform:translateX(20px)}to{opacity:1;transform:translateX(0)}}@keyframes slideRight{from{opacity:0;transform:translateX(-20px)}to{opacity:1;transform:translateX(0)}}@keyframes fadeIn{from{opacity:0;transform:translateY(10px)}to{opacity:1;transform:translateY(0)}}@keyframes scaleIn{from{opacity:0;transform:scale(0.9)}to{opacity:1;transform:scale(1)}}";
239
433
  const NvCalendarStyle0 = nvCalendarCss;
240
434
 
@@ -243,18 +437,28 @@ const NvCalendar = class {
243
437
  index.registerInstance(this, hostRef);
244
438
  this.singleDateChange = index.createEvent(this, "singleDateChange");
245
439
  this.rangeDateChange = index.createEvent(this, "rangeDateChange");
440
+ this.valueChanged = index.createEvent(this, "valueChanged");
246
441
  /****************************************************************************/
247
442
  //#region PROPERTIES
248
443
  /**
249
444
  * First day of the week (0 = Sunday, 1 = Monday, etc.)
250
- * @default 0
445
+ * @default 1
251
446
  */
252
- this.firstDayOfWeek = 0;
447
+ this.firstDayOfWeek = 1;
253
448
  /**
254
449
  * Number of calendars to display
255
450
  * @default 1
256
451
  */
257
452
  this.numberOfCalendars = 1;
453
+ /**
454
+ * Selected date value. For single mode: ISO date string. For range mode: comma-separated ISO date strings.
455
+ * Examples:
456
+ * - Single: "2025-03-15"
457
+ * - Range: "2025-03-15,2025-03-20"
458
+ * @default ""
459
+ */
460
+ // eslint-disable-next-line @stencil-community/strict-mutable
461
+ this.value = '';
258
462
  /**
259
463
  * Locale for date formatting
260
464
  * @default 'en-BE'
@@ -292,6 +496,75 @@ const NvCalendar = class {
292
496
  this.endDate = null;
293
497
  /** List of formatted months for the selector */
294
498
  this.months = [];
499
+ /**
500
+ * Parses the unified value prop and synchronizes with internal state
501
+ * @param {string} value - Value to parse
502
+ */
503
+ this.parseUnifiedValue = (value) => {
504
+ if (!value) {
505
+ // Reset all selections
506
+ this.selectedDate = null;
507
+ this.startDate = null;
508
+ this.endDate = null;
509
+ return;
510
+ }
511
+ const values = value
512
+ .split(',')
513
+ .map(v => v.trim())
514
+ .filter(Boolean);
515
+ if (this.selectionType === 'single' && values.length >= 1) {
516
+ const parsedDate = parseDate(values[0], this.dateFormat);
517
+ if (parsedDate) {
518
+ this.selectedDate = parsedDate;
519
+ // Only sync with legacy prop if not using actions (immediate mode)
520
+ if (!this.showActions) {
521
+ this.singleValue = values[0];
522
+ }
523
+ // Navigate to the date if not prevented
524
+ const preventNavigation = this.el.getAttribute('data-prevent-navigation') === 'true';
525
+ if (!preventNavigation) {
526
+ this.currentDate = parsedDate;
527
+ }
528
+ }
529
+ else {
530
+ // Handle malformed date gracefully - reset state
531
+ console.warn(`Invalid date format: ${values[0]}`);
532
+ this.selectedDate = null;
533
+ if (!this.showActions) {
534
+ this.singleValue = '';
535
+ }
536
+ }
537
+ }
538
+ else if (this.selectionType === 'range' && values.length >= 2) {
539
+ const startDate = parseDate(values[0], this.dateFormat);
540
+ const endDate = parseDate(values[1], this.dateFormat);
541
+ if (startDate && endDate) {
542
+ this.startDate = startDate;
543
+ this.endDate = endDate;
544
+ // Only sync with legacy prop if not using actions (immediate mode)
545
+ if (!this.showActions) {
546
+ this.rangeValue = {
547
+ start: values[0],
548
+ end: values[1],
549
+ };
550
+ }
551
+ // Navigate to start date if not prevented
552
+ const preventNavigation = this.el.getAttribute('data-prevent-navigation') === 'true';
553
+ if (!preventNavigation) {
554
+ this.currentDate = startDate;
555
+ }
556
+ }
557
+ else {
558
+ // Handle malformed dates gracefully - reset state
559
+ console.warn(`Invalid date range format: ${values[0]}, ${values[1]}`);
560
+ this.startDate = null;
561
+ this.endDate = null;
562
+ if (!this.showActions) {
563
+ this.rangeValue = { start: '', end: '' };
564
+ }
565
+ }
566
+ }
567
+ };
295
568
  /**
296
569
  * Change the displayed month
297
570
  * @param {number} offset - Month offset (-1 for previous, 1 for next)
@@ -339,7 +612,14 @@ const NvCalendar = class {
339
612
  return;
340
613
  const formattedDate = formatDate(date, { dateFormat: this.dateFormat });
341
614
  this.selectedDate = date;
342
- this.singleDateChange.emit(formattedDate);
615
+ // Update the unified value prop (like nv-fieldslider)
616
+ this.value = formattedDate;
617
+ this.valueChanged.emit(formattedDate);
618
+ // Legacy support (deprecated) - only sync props if not using actions
619
+ if (!this.showActions) {
620
+ this.singleValue = formattedDate;
621
+ this.singleDateChange.emit(formattedDate);
622
+ }
343
623
  };
344
624
  /**
345
625
  * Handles range date selection
@@ -347,18 +627,32 @@ const NvCalendar = class {
347
627
  */
348
628
  this.handleRangeSelection = (date) => {
349
629
  if (!this.startDate || (this.startDate && this.endDate)) {
630
+ // Start new range selection
350
631
  this.startDate = date;
351
632
  this.endDate = null;
352
633
  }
353
634
  else {
635
+ // Complete range selection
354
636
  this.endDate = date;
637
+ // Ensure correct order
355
638
  if (this.startDate > this.endDate) {
356
639
  [this.startDate, this.endDate] = [this.endDate, this.startDate];
357
640
  }
358
- this.rangeDateChange.emit({
359
- start: formatDate(this.startDate, { dateFormat: this.dateFormat }),
360
- end: formatDate(this.endDate, { dateFormat: this.dateFormat }),
641
+ const startFormatted = formatDate(this.startDate, {
642
+ dateFormat: this.dateFormat,
643
+ });
644
+ const endFormatted = formatDate(this.endDate, {
645
+ dateFormat: this.dateFormat,
361
646
  });
647
+ // Update the unified value prop (like nv-fieldslider)
648
+ this.value = `${startFormatted},${endFormatted}`;
649
+ this.valueChanged.emit(this.value);
650
+ // Legacy support (deprecated) - only sync props if not using actions
651
+ if (!this.showActions) {
652
+ const legacyRange = { start: startFormatted, end: endFormatted };
653
+ this.rangeDateChange.emit(legacyRange);
654
+ this.rangeValue = legacyRange;
655
+ }
362
656
  }
363
657
  };
364
658
  /**
@@ -417,23 +711,35 @@ const NvCalendar = class {
417
711
  * @returns {string[]} Array of short day names
418
712
  */
419
713
  this.getDayNames = () => {
714
+ let days;
420
715
  // If we have custom day names for this locale
421
- if (constantsB97e736d.CUSTOM_DAY_NAMES[this.locale]) {
422
- const days = [...constantsB97e736d.CUSTOM_DAY_NAMES[this.locale]];
423
- // Reorganize the days based on the first day of the week
424
- const firstDays = days.slice(0, this.firstDayOfWeek);
425
- const remainingDays = days.slice(this.firstDayOfWeek);
426
- return [...remainingDays, ...firstDays];
716
+ if (constants4faa1fae.CUSTOM_DAY_NAMES[this.locale]) {
717
+ // Custom day names are expected to start with Monday (index 0 = Monday)
718
+ days = [...constants4faa1fae.CUSTOM_DAY_NAMES[this.locale]];
719
+ }
720
+ else {
721
+ // Generate days using Intl.DateTimeFormat, starting from Monday
722
+ const formatter = new Intl.DateTimeFormat(this.locale, {
723
+ weekday: 'short',
724
+ });
725
+ // Generate days starting from Monday (2023-01-02 was a Monday)
726
+ days = [...Array(7)].map((_, i) => formatter.format(new Date(2023, 0, i + 2)).toUpperCase());
727
+ }
728
+ // Now reorganize based on firstDayOfWeek
729
+ // 0 = Sunday, 1 = Monday (default), 2 = Tuesday, etc.
730
+ if (this.firstDayOfWeek === 0) {
731
+ // If Sunday is first day, move Sunday (last element) to the beginning
732
+ return [days[6], ...days.slice(0, 6)];
733
+ }
734
+ else if (this.firstDayOfWeek === 1) {
735
+ // If Monday is first day, return as-is (since our array starts with Monday)
736
+ return days;
737
+ }
738
+ else {
739
+ // For other first days (Tuesday=2, Wednesday=3, etc.)
740
+ const offset = this.firstDayOfWeek - 1; // Convert to 0-based offset from Monday
741
+ return [...days.slice(offset), ...days.slice(0, offset)];
427
742
  }
428
- // Otherwise, use the default behavior
429
- const formatter = new Intl.DateTimeFormat(this.locale, {
430
- weekday: 'short',
431
- });
432
- const days = [...Array(7)].map((_, i) => formatter.format(new Date(2023, 0, i + 1)).toUpperCase());
433
- // Reorganize the days based on the first day of the week
434
- const firstDays = days.slice(0, this.firstDayOfWeek);
435
- const remainingDays = days.slice(this.firstDayOfWeek);
436
- return [...remainingDays, ...firstDays];
437
743
  };
438
744
  /**
439
745
  * Generates the days of the current month
@@ -493,8 +799,8 @@ const NvCalendar = class {
493
799
  /** Initializes the list of formatted months according to the locale */
494
800
  this.initializeMonths = () => {
495
801
  // If we have custom month names for this locale
496
- if (constantsB97e736d.CUSTOM_MONTH_NAMES[this.locale]) {
497
- this.months = constantsB97e736d.CUSTOM_MONTH_NAMES[this.locale].map((label, value) => ({
802
+ if (constants4faa1fae.CUSTOM_MONTH_NAMES[this.locale]) {
803
+ this.months = constants4faa1fae.CUSTOM_MONTH_NAMES[this.locale].map((label, value) => ({
498
804
  value,
499
805
  label,
500
806
  }));
@@ -512,7 +818,7 @@ const NvCalendar = class {
512
818
  * @returns {string} Localized abbreviation for "week"
513
819
  */
514
820
  this.getLocalizedWeekText = () => {
515
- return constantsB97e736d.WEEK_ABBREVIATIONS[this.locale] || 'W';
821
+ return constants4faa1fae.WEEK_ABBREVIATIONS[this.locale] || 'W';
516
822
  };
517
823
  /**
518
824
  * Handles month change in the selector
@@ -614,8 +920,15 @@ const NvCalendar = class {
614
920
  if (shortcut.singleValue) {
615
921
  const newDate = parseDate(shortcut.singleValue, this.dateFormat);
616
922
  this.selectedDate = newDate;
617
- this.singleDateChange.emit(formatDate(newDate, { dateFormat: this.dateFormat }));
618
- this.singleValue = formatDate(newDate, { dateFormat: this.dateFormat });
923
+ const formattedDate = formatDate(newDate, {
924
+ dateFormat: this.dateFormat,
925
+ });
926
+ // Update the unified value prop (like nv-fieldslider)
927
+ this.value = formattedDate;
928
+ this.valueChanged.emit(formattedDate);
929
+ // Legacy support (deprecated) - sync props
930
+ this.singleValue = formattedDate;
931
+ this.singleDateChange.emit(formattedDate);
619
932
  if (!this.showActions) {
620
933
  const event = new CustomEvent('closePopover', {
621
934
  bubbles: true,
@@ -630,14 +943,18 @@ const NvCalendar = class {
630
943
  const end = parseDate(shortcut.rangeValue.end, this.dateFormat);
631
944
  this.startDate = start;
632
945
  this.endDate = end;
633
- this.rangeDateChange.emit({
634
- start: formatDate(start, { dateFormat: this.dateFormat }),
635
- end: formatDate(end, { dateFormat: this.dateFormat }),
946
+ const startFormatted = formatDate(start, {
947
+ dateFormat: this.dateFormat,
636
948
  });
637
- this.rangeValue = {
638
- start: formatDate(start, { dateFormat: this.dateFormat }),
639
- end: formatDate(end, { dateFormat: this.dateFormat }),
640
- };
949
+ const endFormatted = formatDate(end, { dateFormat: this.dateFormat });
950
+ // Update the unified value prop (like nv-fieldslider)
951
+ this.value = `${startFormatted},${endFormatted}`;
952
+ this.valueChanged.emit(this.value);
953
+ // Legacy support (deprecated) - sync props
954
+ const legacyRange = { start: startFormatted, end: endFormatted };
955
+ this.rangeDateChange.emit(legacyRange);
956
+ // eslint-disable-next-line @stencil-community/strict-mutable
957
+ this.rangeValue = legacyRange;
641
958
  if (!this.showActions) {
642
959
  const event = new CustomEvent('closePopover', {
643
960
  bubbles: true,
@@ -655,79 +972,28 @@ const NvCalendar = class {
655
972
  this.forceCalendarUpdate = newDate => {
656
973
  this.currentDate = new Date(newDate);
657
974
  };
658
- /**
659
- * Handles month change with an offset
660
- * @param {number} direction - Direction (-1 for previous, 1 for next)
661
- * @returns {Function} Change month handler
662
- */
663
- this.getChangeMonthHandler = (direction) => {
664
- return () => this.changeMonth(direction);
665
- };
666
- /**
667
- * Handles month change from an event (ex: dropdown)
668
- * @param {number} offset - Month offset (0 by default)
669
- * @returns {Function} Change month handler
670
- */
671
- this.getHandleMonthChange = (offset) => {
672
- return (event) => this.handleMonthChange(event, offset);
673
- };
674
- /**
675
- * Handles year change from an event (ex: dropdown)
676
- * @param {number} offset - Year offset (0 by default)
677
- * @returns {Function} Change year handler
678
- */
679
- this.getHandleYearChange = (offset) => {
680
- return (event) => this.handleYearChange(event, offset);
681
- };
682
- /**
683
- * Handles day click
684
- * @param {Date} date - Date to handle
685
- * @param {boolean} isDisabled - Whether the date is disabled
686
- * @returns {Function} Day click handler
687
- */
688
- this.getDayClickHandler = (date, isDisabled) => {
689
- return isDisabled ? undefined : () => this.handleDateSelection(date);
690
- };
691
- /**
692
- * Handles shortcut selection
693
- * @param {Object} shortcut - Shortcut to handle
694
- * @param {string | Date} shortcut.singleValue - Selected date value
695
- * @param {Object} shortcut.rangeValue - Start and end date values
696
- * @param {string | Date} shortcut.rangeValue.start - Start date value
697
- * @param {string | Date} shortcut.rangeValue.end - End date value
698
- * @param {string} shortcut.label - Label
699
- * @returns {Function} Shortcut selection handler
700
- */
701
- this.getShortcutHandler = (shortcut) => {
702
- return () => this.applyShortcut(shortcut);
703
- };
704
- /**
705
- * Handles week selection
706
- * @param {Date[]} dates - Dates to handle
707
- * @param {number} index - Calendar index
708
- * @returns {Function} Week selection handler
709
- */
710
- this.getWeekSelectionHandler = (dates, index) => {
711
- return () => {
712
- if (this.selectionType === 'range') {
713
- this.handleWeekSelection(dates, index);
714
- }
715
- };
716
- };
717
975
  /**
718
976
  * Resets the current selection
719
977
  */
720
978
  this.resetSelection = () => {
721
979
  if (this.selectionType === 'single') {
722
980
  this.selectedDate = null;
981
+ // eslint-disable-next-line @stencil-community/strict-mutable
723
982
  this.singleValue = null;
983
+ // eslint-disable-next-line @stencil-community/strict-mutable
984
+ this.value = '';
724
985
  this.singleDateChange.emit('');
986
+ this.valueChanged.emit('');
725
987
  }
726
988
  else {
727
989
  this.startDate = null;
728
990
  this.endDate = null;
991
+ // eslint-disable-next-line @stencil-community/strict-mutable
729
992
  this.rangeValue = null;
993
+ // eslint-disable-next-line @stencil-community/strict-mutable
994
+ this.value = '';
730
995
  this.rangeDateChange.emit({ start: '', end: '' });
996
+ this.valueChanged.emit('');
731
997
  }
732
998
  };
733
999
  /**
@@ -739,6 +1005,7 @@ const NvCalendar = class {
739
1005
  dateFormat: this.dateFormat,
740
1006
  });
741
1007
  this.singleDateChange.emit(dateStr);
1008
+ // eslint-disable-next-line @stencil-community/strict-mutable
742
1009
  this.singleValue = dateStr;
743
1010
  const event = new CustomEvent('closePopover', {
744
1011
  bubbles: true,
@@ -753,6 +1020,7 @@ const NvCalendar = class {
753
1020
  start: formatDate(this.startDate, { dateFormat: this.dateFormat }),
754
1021
  end: formatDate(this.endDate, { dateFormat: this.dateFormat }),
755
1022
  });
1023
+ // eslint-disable-next-line @stencil-community/strict-mutable
756
1024
  this.rangeValue = {
757
1025
  start: formatDate(this.startDate, { dateFormat: this.dateFormat }),
758
1026
  end: formatDate(this.endDate, { dateFormat: this.dateFormat }),
@@ -775,8 +1043,7 @@ const NvCalendar = class {
775
1043
  * @description Renders the header of the calendar
776
1044
  */
777
1045
  this.renderHeader = (offset, index$1) => {
778
- return (index.h("div", { class: "header" }, this.numberOfCalendars > 1 && index$1 === 0 && (index.h("nv-iconbutton", { class: "nav-left", emphasis: "lower", name: "chevron-left", onClick: this.getChangeMonthHandler(-1) })), index.h("div", { class: "date-controls" }, index.h("select", { class: "month-select mr-4", onChange: this.getHandleMonthChange(offset) }, this.months.map(month => (index.h("option", { key: month.value, value: month.value, selected: month.value === (this.currentDate.getUTCMonth() + offset) % 12 }, month.label)))), index.h("input", { type: "number", class: "year-input", min: "1950", max: "2100", value: this.currentDate.getUTCFullYear() +
779
- Math.floor((this.currentDate.getUTCMonth() + offset) / 12), onChange: this.getHandleYearChange(offset) })), this.numberOfCalendars === 1 && (index.h("div", { class: "nav-buttons" }, index.h("nv-iconbutton", { emphasis: "lower", name: "chevron-left", onClick: this.getChangeMonthHandler(-1) }), index.h("nv-iconbutton", { emphasis: "lower", name: "chevron-right", onClick: this.getChangeMonthHandler(1) }))), this.numberOfCalendars > 1 && index$1 === this.numberOfCalendars - 1 && (index.h("nv-iconbutton", { emphasis: "lower", name: "chevron-right", onClick: this.getChangeMonthHandler(1), class: "nav-right" }))));
1046
+ return (index.h(CalendarHeader, { currentDate: this.currentDate, months: this.months, numberOfCalendars: this.numberOfCalendars, calendarIndex: index$1, monthOffset: offset, onMonthChange: this.changeMonth, onMonthSelect: this.handleMonthChange, onYearChange: this.handleYearChange }));
780
1047
  };
781
1048
  /**
782
1049
  * Renders the week numbers
@@ -790,42 +1057,7 @@ const NvCalendar = class {
790
1057
  weeks,
791
1058
  /** Calendar index */
792
1059
  index$1) => {
793
- return (index.h("div", { class: "week-numbers" }, index.h("div", { class: "week-header" }, this.getLocalizedWeekText()), weeks.map((week, weekIndex) => {
794
- var _a;
795
- const dates = week.map(d => d.date);
796
- return (index.h("div", { class: `week-number ${this.selectionType === 'range' ? 'clickable' : ''}`, onClick: this.getWeekSelectionHandler(dates, index$1), key: `week-${weekIndex}` }, getWeekNumber(((_a = week.find(d => d.date)) === null || _a === void 0 ? void 0 : _a.date) || new Date())));
797
- })));
798
- };
799
- this.renderDaysGrid = (
800
- /** Days to render */
801
- days) => {
802
- return (index.h("div", { class: "days-grid" }, days.map(day => {
803
- const date = day.date;
804
- if (!date)
805
- return null;
806
- const isSelected = this.selectionType === 'single' &&
807
- isSameDate(date, this.selectedDate, { isUTCMode: this.isUTCMode });
808
- const isInRange = this.isDateInRange(date);
809
- const isStart = isSameDate(date, this.startDate, {
810
- isUTCMode: this.isUTCMode,
811
- });
812
- const isEnd = isSameDate(date, this.endDate, {
813
- isUTCMode: this.isUTCMode,
814
- });
815
- const isToday = this.isToday(date);
816
- const isOutsideMonth = !day.isCurrentMonth;
817
- const dayClasses = [
818
- 'day',
819
- isSelected ? 'selected' : '',
820
- isStart ? 'range-start' : '',
821
- isEnd ? 'range-end' : '',
822
- isInRange ? 'in-range' : '',
823
- day.isDisabled ? 'disabled' : '',
824
- isOutsideMonth ? 'outside-month' : '',
825
- isToday ? 'is-today' : '',
826
- ];
827
- return (index.h("div", { class: dayClasses.filter(Boolean).join(' '), onClick: this.getDayClickHandler(date, day.isDisabled), "aria-disabled": day.isDisabled, key: `day-${date.toISOString()}` }, day.dayOfMonth));
828
- })));
1060
+ return (index.h(WeekNumbers, { weeks: weeks, localizedWeekText: this.getLocalizedWeekText(), selectionType: this.selectionType, onWeekSelect: this.handleWeekSelection, calendarIndex: index$1 }));
829
1061
  };
830
1062
  /**
831
1063
  * Renders the calendar
@@ -844,7 +1076,7 @@ const NvCalendar = class {
844
1076
  for (let i = 0; i < days.length; i += 7) {
845
1077
  weeks.push(days.slice(i, i + 7));
846
1078
  }
847
- return (index.h("div", { class: "calendar-wrapper" }, index.h("div", { class: "calendar-container", key: `calendar-${index$1}` }, this.renderHeader(offset, index$1), index.h("div", { class: "calendar-grid" }, this.showWeekNumbers && this.renderWeekNumbers(weeks, index$1), index.h("div", { class: "days-container" }, index.h("div", { class: "days-header" }, this.getDayNames().map(day => (index.h("div", { class: "day-header" }, day)))), this.renderDaysGrid(days)))), index$1 < this.numberOfCalendars - 1 && (index.h("div", { class: "calendar-separator" }))));
1079
+ return (index.h("div", { class: "calendar-wrapper" }, index.h("div", { class: "calendar-container", key: `calendar-${index$1}` }, this.renderHeader(offset, index$1), index.h("div", { class: "calendar-grid" }, this.showWeekNumbers && this.renderWeekNumbers(weeks, index$1), index.h(CalendarGrid, { days: days, dayNames: this.getDayNames(), selectionType: this.selectionType, selectedDate: this.selectedDate, startDate: this.startDate, endDate: this.endDate, isUTCMode: this.isUTCMode, onDayClick: this.handleDateSelection, isDateInRange: this.isDateInRange, isToday: this.isToday }))), index$1 < this.numberOfCalendars - 1 && (index.h("div", { class: "calendar-separator" }))));
848
1080
  };
849
1081
  /**
850
1082
  * Renders the shortcuts
@@ -855,7 +1087,7 @@ const NvCalendar = class {
855
1087
  if (!this.hasShortcuts) {
856
1088
  return null;
857
1089
  }
858
- return (index.h("div", { class: `shortcuts-container shortcuts-placement-${this.shortcutsPlacement}` }, this.shortcuts.map(shortcut => (index.h("nv-button", { emphasis: "lower", size: "xs", "aria-label": shortcut.label, onClick: this.getShortcutHandler(shortcut) }, shortcut.label)))));
1090
+ return (index.h(CalendarShortcuts, { shortcuts: this.shortcuts, placement: this.shortcutsPlacement, onShortcutClick: this.applyShortcut }));
859
1091
  };
860
1092
  /**
861
1093
  * Renders the actions
@@ -864,7 +1096,7 @@ const NvCalendar = class {
864
1096
  * @slot actions - Child content of the component.
865
1097
  */
866
1098
  this.renderActions = () => {
867
- return (index.h("div", { class: "datepicker-actions" }, index.h("slot", { name: "actions" }, index.h("nv-button", { emphasis: "low", size: "xs", onClick: this.resetSelection }, "Cancel"), index.h("nv-button", { size: "xs", onClick: this.confirmSelection }, "OK"))));
1099
+ return (index.h("div", { class: "datepicker-actions" }, index.h("slot", { name: "actions" }, index.h(CalendarActions, { onReset: this.resetSelection, onConfirm: this.confirmSelection, useSlot: false }))));
868
1100
  };
869
1101
  }
870
1102
  //#endregion EVENTS
@@ -928,12 +1160,26 @@ const NvCalendar = class {
928
1160
  }
929
1161
  }
930
1162
  }
1163
+ /**
1164
+ * Watches the changes of the unified value prop
1165
+ * @param {string} newValue - New value
1166
+ * @param {string} oldValue - Old value
1167
+ */
1168
+ onValueChange(newValue, oldValue) {
1169
+ if (newValue !== oldValue) {
1170
+ this.parseUnifiedValue(newValue);
1171
+ }
1172
+ }
931
1173
  //#endregion WATCHERS
932
1174
  /****************************************************************************/
933
1175
  //#region LIFECYCLE
934
1176
  componentWillLoad() {
935
1177
  this.parseDisabledDates();
936
- if (this.selectionType === 'single' && this.singleValue) {
1178
+ // Initialize from unified value prop if provided
1179
+ if (this.value) {
1180
+ this.parseUnifiedValue(this.value);
1181
+ }
1182
+ else if (this.selectionType === 'single' && this.singleValue) {
937
1183
  this.selectedDate = parseDate(this.singleValue, this.dateFormat);
938
1184
  this.currentDate = this.selectedDate;
939
1185
  }
@@ -946,6 +1192,7 @@ const NvCalendar = class {
946
1192
  this.currentDate = startDate;
947
1193
  if (swapped) {
948
1194
  // If dates were swapped, update the rangeValue property
1195
+ // eslint-disable-next-line @stencil-community/strict-mutable
949
1196
  this.rangeValue = {
950
1197
  start: formatDate(startDate, { dateFormat: this.dateFormat }),
951
1198
  end: formatDate(endDate, { dateFormat: this.dateFormat }),
@@ -957,7 +1204,8 @@ const NvCalendar = class {
957
1204
  console.error('Invalid rangeValue:', error);
958
1205
  }
959
1206
  }
960
- else {
1207
+ // Ensure currentDate is always initialized
1208
+ if (!this.currentDate) {
961
1209
  this.currentDate = new Date();
962
1210
  }
963
1211
  this.initializeMonths();
@@ -1027,15 +1275,16 @@ const NvCalendar = class {
1027
1275
  * @slot default - Child content of the component.
1028
1276
  */
1029
1277
  render() {
1030
- return (index.h(index.Host, { key: '9804c486acf32e12f2d88f932a54ca6260365887' }, index.h("div", { key: '8503f585401191b904f2de248ed0c24b1fed1505', class: "datepicker-root" }, index.h("div", { key: '9da71618bd2031b44f5a3fd889d40b2580fcca58', class: `datepicker-container ${this.numberOfCalendars === 1 ? 'datepicker-container-single' : ''}` }, index.h("div", { key: 'fbf71a34b520ca48f1440d8caeec442773b1e57a', class: `datepicker-wrapper ${this.numberOfCalendars === 1 ? 'single' : ''}` }, this.shortcutsPlacement === 'left' && this.renderShortcuts(), Array.from({ length: this.numberOfCalendars }, (_, index) => this.renderCalendar(index, index)), this.shortcutsPlacement === 'right' && this.renderShortcuts()), ((this.hasShortcuts && this.shortcutsPlacement === 'bottom') ||
1031
- this.hasActions) && (index.h("div", { key: '4431e3f1221e9d47807d58af380dcaa91bf05c48', class: "datepicker-controls" }, this.shortcutsPlacement === 'bottom' && this.renderShortcuts(), this.hasActions && this.renderActions())))), index.h("slot", { key: '30386356bda72f4f12a28351084ab498ec95f5b9' })));
1278
+ return (index.h(index.Host, { key: '43d4f3ab9199e9c5f15e853f15283fa59e4a436d' }, index.h("div", { key: 'b9956225cb2c16d997aa44266af8f8c8222ea968', class: "datepicker-root" }, index.h("div", { key: '05b63935bc5ebf500bb52d10688385f994b47fb4', class: `datepicker-container ${this.numberOfCalendars === 1 ? 'datepicker-container-single' : ''}` }, index.h("div", { key: 'd7af15b9ce051026cf841b3be361b32d8db41fc1', class: `datepicker-wrapper ${this.numberOfCalendars === 1 ? 'single' : ''}` }, this.shortcutsPlacement === 'left' && this.renderShortcuts(), Array.from({ length: this.numberOfCalendars }, (_, index) => this.renderCalendar(index, index)), this.shortcutsPlacement === 'right' && this.renderShortcuts()), ((this.hasShortcuts && this.shortcutsPlacement === 'bottom') ||
1279
+ this.hasActions) && (index.h("div", { key: '1765334bf15564bc9886b210c54bddba64c7042e', class: "datepicker-controls" }, this.shortcutsPlacement === 'bottom' && this.renderShortcuts(), this.hasActions && this.renderActions())))), index.h("slot", { key: '0ac3446394b8c23b859e5f0065370b95b6fd05d2' })));
1032
1280
  }
1033
1281
  get el() { return index.getElement(this); }
1034
1282
  static get watchers() { return {
1035
1283
  "numberOfCalendars": ["validateNumberOfCalendars"],
1036
1284
  "rangeValue": ["onRangeValueChange"],
1037
1285
  "disabledDates": ["handleDisabledDatesChange"],
1038
- "singleValue": ["onSingleValueChange"]
1286
+ "singleValue": ["onSingleValueChange"],
1287
+ "value": ["onValueChange"]
1039
1288
  }; }
1040
1289
  };
1041
1290
  NvCalendar.style = NvCalendarStyle0;