@kalyx/react 1.0.0-rc.5 → 1.0.0-rc.7

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/CHANGELOG.md CHANGED
@@ -1,5 +1,71 @@
1
1
  # @kalyx/react
2
2
 
3
+ ## 1.0.0-rc.7
4
+
5
+ ### Minor Changes
6
+
7
+ - 0eca2e8: Two new `DatePicker.Calendar` / `RangePicker.Calendar` props plus an ISO-week utility:
8
+ - **`showWeekNumber`** — render an ISO 8601 week-number column (1–53) on the left of the grid. The column uses `<th scope="row" aria-hidden="true">` so it doesn't participate in the WAI-ARIA grid data region; keyboard navigation across date cells is unchanged. New className slots: `weekNumberHeader`, `weekNumber`.
9
+ - **`fixedWeeks`** — when true, always render 6 rows (42 cells) regardless of the month. Useful for popover layouts that need a stable height across month navigation.
10
+
11
+ Both also accepted on `CalendarOptions` (the `getCalendarDays` core util gains `fixedWeeks`).
12
+
13
+ New core export: **`getISOWeekNumber(iso)`** — pure UTC computation, no date-fns dep. Anchored to the Thursday of the week (so the same week always returns the same number regardless of `weekStartsOn`).
14
+
15
+ ```tsx
16
+ <DatePicker value={date} onChange={setDate}>
17
+ <DatePicker.Input />
18
+ <DatePicker.Popover>
19
+ <DatePicker.Calendar showWeekNumber fixedWeeks />
20
+ </DatePicker.Popover>
21
+ </DatePicker>
22
+ ```
23
+
24
+ Bundle impact: +0.46 KB ESM gzip (13.96 → 14.42 KB). Still well under the 15 KB ceiling.
25
+
26
+ - d62c84e: `DisabledRule` gains a programmatic `filter` variant — pass any predicate `(iso: ISODateString) => boolean` to disable arbitrary days that don't fit the declarative `before` / `after` / `dayOfWeek` / `date` rules.
27
+
28
+ ```tsx
29
+ const holidays = new Set(['2026-01-01T00:00:00.000Z', '2026-12-25T00:00:00.000Z']);
30
+
31
+ <DatePicker
32
+ disabled={[
33
+ { dayOfWeek: [0, 6] }, // weekends
34
+ { filter: (iso) => holidays.has(iso) }, // holidays
35
+ ]}
36
+ >
37
+
38
+ </DatePicker>;
39
+ ```
40
+
41
+ The new variant slots into the existing `isDateDisabled` evaluation (short-circuits on first match) and works with keyboard-navigation disabled-skip in `DatePicker.Calendar` / `RangePicker.Calendar` with no further changes. Equivalent to `react-datepicker`'s `filterDate` prop and MUI X DatePicker's `shouldDisableDate`. Bundle impact: 0 KB (still 13.96 KB ESM gzip).
42
+
43
+ ### Patch Changes
44
+
45
+ - b40080d: Internal: sync the `tsup` onSuccess bundle-size budget from `13 KB` to `15 KB` so the per-build warning matches the actual CI gate (`scripts/check-bundle-size.js`, `pr-check.yml`, `release.yml`). No runtime change; the published artifact is byte-identical.
46
+
47
+ This was a leftover from the 13 → 14 → 15 KB ceiling raises during RC (PR #46 / PR #48); only the tsup-side TARGET_KB was missed during those bumps, so local `pnpm build` printed a spurious `⚠️` even though CI passed.
48
+
49
+ - Updated dependencies [0eca2e8]
50
+ - Updated dependencies [d62c84e]
51
+ - @kalyx/core@1.0.0-rc.7
52
+
53
+ ## 1.0.0-rc.6
54
+
55
+ ### Patch Changes
56
+
57
+ - abc56ac: Security: pin transitive `fast-uri` to `>=3.1.2` and `@babel/plugin-transform-modules-systemjs` to `>=7.29.4` via `pnpm.overrides`.
58
+
59
+ Resolves three Code Scanning alerts on `pnpm-lock.yaml`:
60
+ - `fast-uri@3.1.0` — [GHSA-v39h-62p7-jpjc](https://osv.dev/GHSA-v39h-62p7-jpjc) (CVE-2026-6322), first patched in `3.1.2`.
61
+ - `fast-uri@3.1.0` — [GHSA-q3j6-qgpj-74h6](https://osv.dev/GHSA-q3j6-qgpj-74h6) (CVE-2026-6321), first patched in `3.1.1`.
62
+ - `@babel/plugin-transform-modules-systemjs@7.29.0` — [GHSA-fv7c-fp4j-7gwp](https://osv.dev/GHSA-fv7c-fp4j-7gwp) (CVE-2026-44728), first patched in `7.29.4` on the 7.x line.
63
+
64
+ All three packages are transitive build-time dependencies (ajv → fast-uri, Babel preset-env → systemjs plugin); no public API impact.
65
+
66
+ - Updated dependencies [abc56ac]
67
+ - @kalyx/core@1.0.0-rc.6
68
+
3
69
  ## 1.0.0-rc.5
4
70
 
5
71
  ### Patch Changes
package/dist/index.cjs CHANGED
@@ -465,6 +465,8 @@ var srOnly = {
465
465
  function DatePickerCalendar({
466
466
  classNames,
467
467
  onTitleClick,
468
+ showWeekNumber = false,
469
+ fixedWeeks = false,
468
470
  ...props
469
471
  }) {
470
472
  const ctx = useDatePickerContext("DatePicker.Calendar");
@@ -478,10 +480,21 @@ function DatePickerCalendar({
478
480
  selected: ctx.value,
479
481
  focusedDate,
480
482
  disabled,
481
- timezone: displayTimezone
483
+ timezone: displayTimezone,
484
+ fixedWeeks
482
485
  }),
483
- [viewMonth, adapter, weekStartsOn, ctx.value, focusedDate, disabled, displayTimezone]
486
+ [
487
+ viewMonth,
488
+ adapter,
489
+ weekStartsOn,
490
+ ctx.value,
491
+ focusedDate,
492
+ disabled,
493
+ displayTimezone,
494
+ fixedWeeks
495
+ ]
484
496
  );
497
+ const thursdayIndex = weekStartsOn === 0 ? 4 : 3;
485
498
  const year = adapter.getYear(viewMonth);
486
499
  const month = adapter.getMonth(viewMonth);
487
500
  const title = core.formatMonthYear(year, month, locale);
@@ -622,61 +635,76 @@ function DatePickerCalendar({
622
635
  className: classNames?.grid,
623
636
  onKeyDown: handleKeyDown,
624
637
  children: [
625
- /* @__PURE__ */ jsxRuntime.jsx("thead", { children: /* @__PURE__ */ jsxRuntime.jsx("tr", { role: "row", "aria-rowindex": 1, children: weekdays.map((day, colIndex) => /* @__PURE__ */ jsxRuntime.jsx(
626
- "th",
627
- {
628
- role: "columnheader",
629
- abbr: day.full,
630
- scope: "col",
631
- "aria-colindex": colIndex + 1,
632
- className: classNames?.weekdayHeader,
633
- children: day.short
634
- },
635
- day.short
636
- )) }) }),
637
- /* @__PURE__ */ jsxRuntime.jsx("tbody", { children: weeks.map((week, weekIndex) => /* @__PURE__ */ jsxRuntime.jsx(
638
+ /* @__PURE__ */ jsxRuntime.jsx("thead", { children: /* @__PURE__ */ jsxRuntime.jsxs("tr", { role: "row", "aria-rowindex": 1, children: [
639
+ showWeekNumber ? /* @__PURE__ */ jsxRuntime.jsx("th", { scope: "col", "aria-hidden": "true", className: classNames?.weekNumberHeader, children: "#" }) : null,
640
+ weekdays.map((day, colIndex) => /* @__PURE__ */ jsxRuntime.jsx(
641
+ "th",
642
+ {
643
+ role: "columnheader",
644
+ abbr: day.full,
645
+ scope: "col",
646
+ "aria-colindex": colIndex + 1,
647
+ className: classNames?.weekdayHeader,
648
+ children: day.short
649
+ },
650
+ day.short
651
+ ))
652
+ ] }) }),
653
+ /* @__PURE__ */ jsxRuntime.jsx("tbody", { children: weeks.map((week, weekIndex) => /* @__PURE__ */ jsxRuntime.jsxs(
638
654
  "tr",
639
655
  {
640
656
  role: "row",
641
657
  "aria-rowindex": weekIndex + 2,
642
658
  className: classNames?.gridRow,
643
- children: week.map((day, colIndex) => {
644
- const dayClasses = [
645
- classNames?.day,
646
- day.isSelected && classNames?.daySelected,
647
- day.isToday && classNames?.dayToday,
648
- day.isDisabled && classNames?.dayDisabled,
649
- !day.isCurrentMonth && classNames?.dayOutsideMonth
650
- ].filter(Boolean).join(" ") || void 0;
651
- return /* @__PURE__ */ jsxRuntime.jsx(
652
- "td",
659
+ children: [
660
+ showWeekNumber ? /* @__PURE__ */ jsxRuntime.jsx(
661
+ "th",
653
662
  {
654
- role: "gridcell",
655
- "aria-colindex": colIndex + 1,
656
- "aria-selected": day.isSelected || void 0,
657
- "aria-disabled": day.isDisabled || void 0,
658
- "aria-current": day.isToday ? "date" : void 0,
659
- className: classNames?.gridCell,
660
- children: /* @__PURE__ */ jsxRuntime.jsx(
661
- "button",
662
- {
663
- type: "button",
664
- tabIndex: day.isFocused ? 0 : -1,
665
- disabled: day.isDisabled,
666
- "data-focused": day.isFocused || void 0,
667
- "data-selected": day.isSelected || void 0,
668
- "data-today": day.isToday || void 0,
669
- "data-outside-month": !day.isCurrentMonth || void 0,
670
- className: dayClasses,
671
- onClick: () => handleDayClick(day),
672
- "aria-label": safeFormatFullDate(day.isoString, locale),
673
- children: day.dayNumber
674
- }
675
- )
676
- },
677
- day.isoString
678
- );
679
- })
663
+ scope: "row",
664
+ "aria-hidden": "true",
665
+ className: classNames?.weekNumber,
666
+ "data-week-number": true,
667
+ children: core.getISOWeekNumber(week[thursdayIndex].isoString)
668
+ }
669
+ ) : null,
670
+ week.map((day, colIndex) => {
671
+ const dayClasses = [
672
+ classNames?.day,
673
+ day.isSelected && classNames?.daySelected,
674
+ day.isToday && classNames?.dayToday,
675
+ day.isDisabled && classNames?.dayDisabled,
676
+ !day.isCurrentMonth && classNames?.dayOutsideMonth
677
+ ].filter(Boolean).join(" ") || void 0;
678
+ return /* @__PURE__ */ jsxRuntime.jsx(
679
+ "td",
680
+ {
681
+ role: "gridcell",
682
+ "aria-colindex": colIndex + 1,
683
+ "aria-selected": day.isSelected || void 0,
684
+ "aria-disabled": day.isDisabled || void 0,
685
+ "aria-current": day.isToday ? "date" : void 0,
686
+ className: classNames?.gridCell,
687
+ children: /* @__PURE__ */ jsxRuntime.jsx(
688
+ "button",
689
+ {
690
+ type: "button",
691
+ tabIndex: day.isFocused ? 0 : -1,
692
+ disabled: day.isDisabled,
693
+ "data-focused": day.isFocused || void 0,
694
+ "data-selected": day.isSelected || void 0,
695
+ "data-today": day.isToday || void 0,
696
+ "data-outside-month": !day.isCurrentMonth || void 0,
697
+ className: dayClasses,
698
+ onClick: () => handleDayClick(day),
699
+ "aria-label": safeFormatFullDate(day.isoString, locale),
700
+ children: day.dayNumber
701
+ }
702
+ )
703
+ },
704
+ day.isoString
705
+ );
706
+ })
707
+ ]
680
708
  },
681
709
  weekIndex
682
710
  )) })
@@ -1339,6 +1367,8 @@ var srOnly2 = {
1339
1367
  function RangePickerCalendar({
1340
1368
  classNames,
1341
1369
  selectionMode = "range",
1370
+ showWeekNumber = false,
1371
+ fixedWeeks = false,
1342
1372
  ...props
1343
1373
  }) {
1344
1374
  const ctx = useRangePickerContext("RangePicker.Calendar");
@@ -1364,10 +1394,22 @@ function RangePickerCalendar({
1364
1394
  disabled,
1365
1395
  range: value,
1366
1396
  rangeHover: hoverDate,
1367
- timezone: displayTimezone
1397
+ timezone: displayTimezone,
1398
+ fixedWeeks
1368
1399
  }),
1369
- [viewMonth, adapter, weekStartsOn, focusedDate, disabled, value, hoverDate, displayTimezone]
1400
+ [
1401
+ viewMonth,
1402
+ adapter,
1403
+ weekStartsOn,
1404
+ focusedDate,
1405
+ disabled,
1406
+ value,
1407
+ hoverDate,
1408
+ displayTimezone,
1409
+ fixedWeeks
1410
+ ]
1370
1411
  );
1412
+ const thursdayIndex = weekStartsOn === 0 ? 4 : 3;
1371
1413
  const year = adapter.getYear(viewMonth);
1372
1414
  const month = adapter.getMonth(viewMonth);
1373
1415
  const title = core.formatMonthYear(year, month, locale);
@@ -1531,67 +1573,82 @@ function RangePickerCalendar({
1531
1573
  className: classNames?.grid,
1532
1574
  onKeyDown: handleKeyDown,
1533
1575
  children: [
1534
- /* @__PURE__ */ jsxRuntime.jsx("thead", { children: /* @__PURE__ */ jsxRuntime.jsx("tr", { role: "row", "aria-rowindex": 1, children: weekdays.map((day, colIndex) => /* @__PURE__ */ jsxRuntime.jsx(
1535
- "th",
1536
- {
1537
- role: "columnheader",
1538
- abbr: day.full,
1539
- scope: "col",
1540
- "aria-colindex": colIndex + 1,
1541
- className: classNames?.weekdayHeader,
1542
- children: day.short
1543
- },
1544
- day.short
1545
- )) }) }),
1546
- /* @__PURE__ */ jsxRuntime.jsx("tbody", { children: weeks.map((week, weekIndex) => /* @__PURE__ */ jsxRuntime.jsx(
1576
+ /* @__PURE__ */ jsxRuntime.jsx("thead", { children: /* @__PURE__ */ jsxRuntime.jsxs("tr", { role: "row", "aria-rowindex": 1, children: [
1577
+ showWeekNumber ? /* @__PURE__ */ jsxRuntime.jsx("th", { scope: "col", "aria-hidden": "true", className: classNames?.weekNumberHeader, children: "#" }) : null,
1578
+ weekdays.map((day, colIndex) => /* @__PURE__ */ jsxRuntime.jsx(
1579
+ "th",
1580
+ {
1581
+ role: "columnheader",
1582
+ abbr: day.full,
1583
+ scope: "col",
1584
+ "aria-colindex": colIndex + 1,
1585
+ className: classNames?.weekdayHeader,
1586
+ children: day.short
1587
+ },
1588
+ day.short
1589
+ ))
1590
+ ] }) }),
1591
+ /* @__PURE__ */ jsxRuntime.jsx("tbody", { children: weeks.map((week, weekIndex) => /* @__PURE__ */ jsxRuntime.jsxs(
1547
1592
  "tr",
1548
1593
  {
1549
1594
  role: "row",
1550
1595
  "aria-rowindex": weekIndex + 2,
1551
1596
  className: classNames?.gridRow,
1552
- children: week.map((day, colIndex) => {
1553
- const dayClasses = [
1554
- classNames?.day,
1555
- day.isRangeStart && classNames?.dayRangeStart,
1556
- day.isRangeEnd && classNames?.dayRangeEnd,
1557
- day.isInRange && classNames?.dayInRange,
1558
- day.isToday && classNames?.dayToday,
1559
- day.isDisabled && classNames?.dayDisabled,
1560
- !day.isCurrentMonth && classNames?.dayOutsideMonth
1561
- ].filter(Boolean).join(" ") || void 0;
1562
- const isSelected = selectionMode === "week" ? day.isRangeStart || day.isRangeEnd || day.isInRange : day.isRangeStart || day.isRangeEnd;
1563
- return /* @__PURE__ */ jsxRuntime.jsx(
1564
- "td",
1597
+ children: [
1598
+ showWeekNumber ? /* @__PURE__ */ jsxRuntime.jsx(
1599
+ "th",
1565
1600
  {
1566
- role: "gridcell",
1567
- "aria-colindex": colIndex + 1,
1568
- "aria-selected": isSelected || void 0,
1569
- "aria-disabled": day.isDisabled || void 0,
1570
- "aria-current": day.isToday ? "date" : void 0,
1571
- className: classNames?.gridCell,
1572
- children: /* @__PURE__ */ jsxRuntime.jsx(
1573
- "button",
1574
- {
1575
- type: "button",
1576
- tabIndex: day.isFocused ? 0 : -1,
1577
- disabled: day.isDisabled,
1578
- "data-focused": day.isFocused || void 0,
1579
- "data-range-start": day.isRangeStart || void 0,
1580
- "data-range-end": day.isRangeEnd || void 0,
1581
- "data-in-range": day.isInRange || void 0,
1582
- "data-today": day.isToday || void 0,
1583
- "data-outside-month": !day.isCurrentMonth || void 0,
1584
- className: dayClasses,
1585
- onClick: () => handleDayClick(day),
1586
- onMouseEnter: () => handleDayMouseEnter(day),
1587
- "aria-label": safeFormatFullDate2(day.isoString, locale),
1588
- children: day.dayNumber
1589
- }
1590
- )
1591
- },
1592
- day.isoString
1593
- );
1594
- })
1601
+ scope: "row",
1602
+ "aria-hidden": "true",
1603
+ className: classNames?.weekNumber,
1604
+ "data-week-number": true,
1605
+ children: core.getISOWeekNumber(week[thursdayIndex].isoString)
1606
+ }
1607
+ ) : null,
1608
+ week.map((day, colIndex) => {
1609
+ const dayClasses = [
1610
+ classNames?.day,
1611
+ day.isRangeStart && classNames?.dayRangeStart,
1612
+ day.isRangeEnd && classNames?.dayRangeEnd,
1613
+ day.isInRange && classNames?.dayInRange,
1614
+ day.isToday && classNames?.dayToday,
1615
+ day.isDisabled && classNames?.dayDisabled,
1616
+ !day.isCurrentMonth && classNames?.dayOutsideMonth
1617
+ ].filter(Boolean).join(" ") || void 0;
1618
+ const isSelected = selectionMode === "week" ? day.isRangeStart || day.isRangeEnd || day.isInRange : day.isRangeStart || day.isRangeEnd;
1619
+ return /* @__PURE__ */ jsxRuntime.jsx(
1620
+ "td",
1621
+ {
1622
+ role: "gridcell",
1623
+ "aria-colindex": colIndex + 1,
1624
+ "aria-selected": isSelected || void 0,
1625
+ "aria-disabled": day.isDisabled || void 0,
1626
+ "aria-current": day.isToday ? "date" : void 0,
1627
+ className: classNames?.gridCell,
1628
+ children: /* @__PURE__ */ jsxRuntime.jsx(
1629
+ "button",
1630
+ {
1631
+ type: "button",
1632
+ tabIndex: day.isFocused ? 0 : -1,
1633
+ disabled: day.isDisabled,
1634
+ "data-focused": day.isFocused || void 0,
1635
+ "data-range-start": day.isRangeStart || void 0,
1636
+ "data-range-end": day.isRangeEnd || void 0,
1637
+ "data-in-range": day.isInRange || void 0,
1638
+ "data-today": day.isToday || void 0,
1639
+ "data-outside-month": !day.isCurrentMonth || void 0,
1640
+ className: dayClasses,
1641
+ onClick: () => handleDayClick(day),
1642
+ onMouseEnter: () => handleDayMouseEnter(day),
1643
+ "aria-label": safeFormatFullDate2(day.isoString, locale),
1644
+ children: day.dayNumber
1645
+ }
1646
+ )
1647
+ },
1648
+ day.isoString
1649
+ );
1650
+ })
1651
+ ]
1595
1652
  },
1596
1653
  weekIndex
1597
1654
  )) })