@kalyx/core 1.0.0-rc.10 → 1.0.0-rc.12
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 +33 -0
- package/dist/index.cjs +11 -3
- package/dist/index.d.cts +30 -4
- package/dist/index.d.ts +30 -4
- package/dist/index.js +11 -3
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,38 @@
|
|
|
1
1
|
# @kalyx/core
|
|
2
2
|
|
|
3
|
+
## 1.0.0-rc.12
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- 0556886: fix(core): validate inputs to `to12Hour` and `to24Hour`
|
|
8
|
+
|
|
9
|
+
`to12Hour(hours24)` and `to24Hour(hours12, period)` are public exports from `@kalyx/core` but had no input validation. The previous silent arithmetic mapped invalid inputs onto plausible-looking but wrong outputs and hid caller bugs:
|
|
10
|
+
- `to12Hour(24)` returned `{ hours12: 12, period: 'PM' }` (because `24 % 12 = 0` → mapped to 12)
|
|
11
|
+
- `to12Hour(-1)` returned `{ hours12: -1, period: 'AM' }`
|
|
12
|
+
- `to24Hour(13, 'PM')` returned `25`
|
|
13
|
+
- `to24Hour(0, 'AM')` returned `0` (but `0` is not a valid 12-hour clock value — midnight is `12 AM`)
|
|
14
|
+
|
|
15
|
+
Both functions now throw `RangeError` with a clear message when the input is outside its valid integer range (`[0, 23]` for `to12Hour`, `[1, 12]` for `to24Hour`). `Number.isInteger` guards non-integers and `NaN`. No `@kalyx/react` callers ever passed invalid values, so the internal contracts are unchanged; only direct `@kalyx/core` users who relied on the silent-wrong behaviour see the new exception.
|
|
16
|
+
|
|
17
|
+
## 1.0.0-rc.11
|
|
18
|
+
|
|
19
|
+
### Minor Changes
|
|
20
|
+
|
|
21
|
+
- c8a6609: fix(rangepicker): announce next selection target and final range to screen readers
|
|
22
|
+
|
|
23
|
+
`<RangePicker.Calendar>` now announces context-aware messages through its existing `role="status"` live region:
|
|
24
|
+
- After the first click (start), it announces `<formatted-date>. Now select end date.` so screen-reader users know the next click commits the other endpoint.
|
|
25
|
+
- After the second click (end), it announces `Range selected: <start> – <end>` instead of just the bare date — matching the swap-if-before behaviour so the announcement always reflects what was committed.
|
|
26
|
+
- Week-mode commits now share the same `Range selected: ...` prefix for consistency.
|
|
27
|
+
|
|
28
|
+
The two new strings are wired through `RangePickerLabels.selectingEnd` and `RangePickerLabels.rangeSelected` with English defaults, and they are fully overridable via the existing `labels` prop for i18n. `@kalyx/core` gets a `minor` bump because `RangePickerLabels` gained required fields (with defaults supplied by `DEFAULT_RANGEPICKER_LABELS`); any consumer constructing a literal `RangePickerLabels` from scratch will need to add the two keys.
|
|
29
|
+
|
|
30
|
+
### Patch Changes
|
|
31
|
+
|
|
32
|
+
- 19ac1c0: fix(core): allow `generateMinutes` step values up to 60
|
|
33
|
+
|
|
34
|
+
`generateMinutes(step)` rejected any step above 30, which prevented legitimate cases like `step=45` (quarter-and-three-quarters past the hour) and `step=60` (on-the-hour only). The slot-generation loop already works for any 1–60 integer, so the upper bound is now 60 with the same error message format. Steps `0`, `61+`, and negative values still throw. No callers in `@kalyx/react` relied on the previous narrower bound.
|
|
35
|
+
|
|
3
36
|
## 1.0.0-rc.10
|
|
4
37
|
|
|
5
38
|
### Minor Changes
|
package/dist/index.cjs
CHANGED
|
@@ -477,12 +477,18 @@ function formatTimeString(time, withSeconds = false) {
|
|
|
477
477
|
return `${hh}:${mm}`;
|
|
478
478
|
}
|
|
479
479
|
function to12Hour(hours24) {
|
|
480
|
+
if (!Number.isInteger(hours24) || hours24 < 0 || hours24 > 23) {
|
|
481
|
+
throw new RangeError(`[to12Hour] hours24 must be an integer in [0, 23], got ${hours24}`);
|
|
482
|
+
}
|
|
480
483
|
const period = hours24 >= 12 ? "PM" : "AM";
|
|
481
484
|
let hours12 = hours24 % 12;
|
|
482
485
|
if (hours12 === 0) hours12 = 12;
|
|
483
486
|
return { hours12, period };
|
|
484
487
|
}
|
|
485
488
|
function to24Hour(hours12, period) {
|
|
489
|
+
if (!Number.isInteger(hours12) || hours12 < 1 || hours12 > 12) {
|
|
490
|
+
throw new RangeError(`[to24Hour] hours12 must be an integer in [1, 12], got ${hours12}`);
|
|
491
|
+
}
|
|
486
492
|
if (period === "AM") {
|
|
487
493
|
return hours12 === 12 ? 0 : hours12;
|
|
488
494
|
}
|
|
@@ -495,8 +501,8 @@ function generateHours(format = "24h") {
|
|
|
495
501
|
return Array.from({ length: 24 }, (_, i) => i);
|
|
496
502
|
}
|
|
497
503
|
function generateMinutes(step = 1) {
|
|
498
|
-
if (step < 1 || step >
|
|
499
|
-
throw new Error(`[generateMinutes] step must be between 1 and
|
|
504
|
+
if (step < 1 || step > 60) {
|
|
505
|
+
throw new Error(`[generateMinutes] step must be between 1 and 60, got ${step}`);
|
|
500
506
|
}
|
|
501
507
|
const result = [];
|
|
502
508
|
for (let i = 0; i < 60; i += step) {
|
|
@@ -590,7 +596,9 @@ var DEFAULT_RANGEPICKER_LABELS = {
|
|
|
590
596
|
popoverLabel: "Choose date range",
|
|
591
597
|
startInput: "Start date",
|
|
592
598
|
endInput: "End date",
|
|
593
|
-
presetsGroup: "Date range presets"
|
|
599
|
+
presetsGroup: "Date range presets",
|
|
600
|
+
selectingEnd: "Now select end date",
|
|
601
|
+
rangeSelected: "Range selected"
|
|
594
602
|
};
|
|
595
603
|
var DEFAULT_TIMEPICKER_LABELS = {
|
|
596
604
|
timeInput: "Time",
|
package/dist/index.d.cts
CHANGED
|
@@ -218,7 +218,13 @@ declare function parseTimeString(input: string): TimeValue | null;
|
|
|
218
218
|
declare function formatTimeString(time: TimeValue, withSeconds?: boolean): string;
|
|
219
219
|
/**
|
|
220
220
|
* Converts a 24-hour value to 12-hour form.
|
|
221
|
-
*
|
|
221
|
+
*
|
|
222
|
+
* - `0` → `{ hours12: 12, period: 'AM' }` (midnight)
|
|
223
|
+
* - `12` → `{ hours12: 12, period: 'PM' }` (noon)
|
|
224
|
+
*
|
|
225
|
+
* Throws if `hours24` isn't an integer in `[0, 23]`. The previous silent
|
|
226
|
+
* modulo behaviour mapped invalid inputs (e.g. `24`, `25`, `-1`) onto
|
|
227
|
+
* arbitrary valid-looking outputs, which masked caller bugs.
|
|
222
228
|
*/
|
|
223
229
|
declare function to12Hour(hours24: number): {
|
|
224
230
|
hours12: number;
|
|
@@ -226,6 +232,10 @@ declare function to12Hour(hours24: number): {
|
|
|
226
232
|
};
|
|
227
233
|
/**
|
|
228
234
|
* Converts a 12-hour value to 24-hour form.
|
|
235
|
+
*
|
|
236
|
+
* Throws if `hours12` isn't an integer in `[1, 12]`. The previous silent
|
|
237
|
+
* arithmetic produced out-of-range outputs (e.g. `to24Hour(13, 'PM')` → `25`).
|
|
238
|
+
* `period` is constrained at the type level to `'AM' | 'PM'`.
|
|
229
239
|
*/
|
|
230
240
|
declare function to24Hour(hours12: number, period: 'AM' | 'PM'): number;
|
|
231
241
|
/**
|
|
@@ -234,9 +244,15 @@ declare function to24Hour(hours12: number, period: 'AM' | 'PM'): number;
|
|
|
234
244
|
declare function generateHours(format?: '12h' | '24h'): number[];
|
|
235
245
|
/**
|
|
236
246
|
* Builds a minutes list at the given step.
|
|
237
|
-
*
|
|
238
|
-
* step=
|
|
239
|
-
* step=
|
|
247
|
+
*
|
|
248
|
+
* - `step=1` → `[0, 1, 2, ..., 59]`
|
|
249
|
+
* - `step=15` → `[0, 15, 30, 45]`
|
|
250
|
+
* - `step=5` → `[0, 5, 10, ..., 55]`
|
|
251
|
+
* - `step=45` → `[0, 45]`
|
|
252
|
+
* - `step=60` → `[0]` (on-the-hour only)
|
|
253
|
+
*
|
|
254
|
+
* Steps above 60 are rejected because they always collapse to `[0]` — useful UX
|
|
255
|
+
* is impossible past that point.
|
|
240
256
|
*/
|
|
241
257
|
declare function generateMinutes(step?: number): number[];
|
|
242
258
|
/**
|
|
@@ -399,6 +415,16 @@ interface RangePickerLabels extends DatePickerLabels {
|
|
|
399
415
|
startInput: string;
|
|
400
416
|
endInput: string;
|
|
401
417
|
presetsGroup: string;
|
|
418
|
+
/**
|
|
419
|
+
* Screen-reader prompt appended after the start date is picked, telling the user
|
|
420
|
+
* the next click commits the end of the range.
|
|
421
|
+
*/
|
|
422
|
+
selectingEnd: string;
|
|
423
|
+
/**
|
|
424
|
+
* Screen-reader prefix announced when both endpoints are committed, e.g.
|
|
425
|
+
* `"Range selected: Jan 5, 2026 – Jan 12, 2026"`.
|
|
426
|
+
*/
|
|
427
|
+
rangeSelected: string;
|
|
402
428
|
}
|
|
403
429
|
interface TimePickerLabels {
|
|
404
430
|
timeInput: string;
|
package/dist/index.d.ts
CHANGED
|
@@ -218,7 +218,13 @@ declare function parseTimeString(input: string): TimeValue | null;
|
|
|
218
218
|
declare function formatTimeString(time: TimeValue, withSeconds?: boolean): string;
|
|
219
219
|
/**
|
|
220
220
|
* Converts a 24-hour value to 12-hour form.
|
|
221
|
-
*
|
|
221
|
+
*
|
|
222
|
+
* - `0` → `{ hours12: 12, period: 'AM' }` (midnight)
|
|
223
|
+
* - `12` → `{ hours12: 12, period: 'PM' }` (noon)
|
|
224
|
+
*
|
|
225
|
+
* Throws if `hours24` isn't an integer in `[0, 23]`. The previous silent
|
|
226
|
+
* modulo behaviour mapped invalid inputs (e.g. `24`, `25`, `-1`) onto
|
|
227
|
+
* arbitrary valid-looking outputs, which masked caller bugs.
|
|
222
228
|
*/
|
|
223
229
|
declare function to12Hour(hours24: number): {
|
|
224
230
|
hours12: number;
|
|
@@ -226,6 +232,10 @@ declare function to12Hour(hours24: number): {
|
|
|
226
232
|
};
|
|
227
233
|
/**
|
|
228
234
|
* Converts a 12-hour value to 24-hour form.
|
|
235
|
+
*
|
|
236
|
+
* Throws if `hours12` isn't an integer in `[1, 12]`. The previous silent
|
|
237
|
+
* arithmetic produced out-of-range outputs (e.g. `to24Hour(13, 'PM')` → `25`).
|
|
238
|
+
* `period` is constrained at the type level to `'AM' | 'PM'`.
|
|
229
239
|
*/
|
|
230
240
|
declare function to24Hour(hours12: number, period: 'AM' | 'PM'): number;
|
|
231
241
|
/**
|
|
@@ -234,9 +244,15 @@ declare function to24Hour(hours12: number, period: 'AM' | 'PM'): number;
|
|
|
234
244
|
declare function generateHours(format?: '12h' | '24h'): number[];
|
|
235
245
|
/**
|
|
236
246
|
* Builds a minutes list at the given step.
|
|
237
|
-
*
|
|
238
|
-
* step=
|
|
239
|
-
* step=
|
|
247
|
+
*
|
|
248
|
+
* - `step=1` → `[0, 1, 2, ..., 59]`
|
|
249
|
+
* - `step=15` → `[0, 15, 30, 45]`
|
|
250
|
+
* - `step=5` → `[0, 5, 10, ..., 55]`
|
|
251
|
+
* - `step=45` → `[0, 45]`
|
|
252
|
+
* - `step=60` → `[0]` (on-the-hour only)
|
|
253
|
+
*
|
|
254
|
+
* Steps above 60 are rejected because they always collapse to `[0]` — useful UX
|
|
255
|
+
* is impossible past that point.
|
|
240
256
|
*/
|
|
241
257
|
declare function generateMinutes(step?: number): number[];
|
|
242
258
|
/**
|
|
@@ -399,6 +415,16 @@ interface RangePickerLabels extends DatePickerLabels {
|
|
|
399
415
|
startInput: string;
|
|
400
416
|
endInput: string;
|
|
401
417
|
presetsGroup: string;
|
|
418
|
+
/**
|
|
419
|
+
* Screen-reader prompt appended after the start date is picked, telling the user
|
|
420
|
+
* the next click commits the end of the range.
|
|
421
|
+
*/
|
|
422
|
+
selectingEnd: string;
|
|
423
|
+
/**
|
|
424
|
+
* Screen-reader prefix announced when both endpoints are committed, e.g.
|
|
425
|
+
* `"Range selected: Jan 5, 2026 – Jan 12, 2026"`.
|
|
426
|
+
*/
|
|
427
|
+
rangeSelected: string;
|
|
402
428
|
}
|
|
403
429
|
interface TimePickerLabels {
|
|
404
430
|
timeInput: string;
|
package/dist/index.js
CHANGED
|
@@ -426,12 +426,18 @@ function formatTimeString(time, withSeconds = false) {
|
|
|
426
426
|
return `${hh}:${mm}`;
|
|
427
427
|
}
|
|
428
428
|
function to12Hour(hours24) {
|
|
429
|
+
if (!Number.isInteger(hours24) || hours24 < 0 || hours24 > 23) {
|
|
430
|
+
throw new RangeError(`[to12Hour] hours24 must be an integer in [0, 23], got ${hours24}`);
|
|
431
|
+
}
|
|
429
432
|
const period = hours24 >= 12 ? "PM" : "AM";
|
|
430
433
|
let hours12 = hours24 % 12;
|
|
431
434
|
if (hours12 === 0) hours12 = 12;
|
|
432
435
|
return { hours12, period };
|
|
433
436
|
}
|
|
434
437
|
function to24Hour(hours12, period) {
|
|
438
|
+
if (!Number.isInteger(hours12) || hours12 < 1 || hours12 > 12) {
|
|
439
|
+
throw new RangeError(`[to24Hour] hours12 must be an integer in [1, 12], got ${hours12}`);
|
|
440
|
+
}
|
|
435
441
|
if (period === "AM") {
|
|
436
442
|
return hours12 === 12 ? 0 : hours12;
|
|
437
443
|
}
|
|
@@ -444,8 +450,8 @@ function generateHours(format = "24h") {
|
|
|
444
450
|
return Array.from({ length: 24 }, (_, i) => i);
|
|
445
451
|
}
|
|
446
452
|
function generateMinutes(step = 1) {
|
|
447
|
-
if (step < 1 || step >
|
|
448
|
-
throw new Error(`[generateMinutes] step must be between 1 and
|
|
453
|
+
if (step < 1 || step > 60) {
|
|
454
|
+
throw new Error(`[generateMinutes] step must be between 1 and 60, got ${step}`);
|
|
449
455
|
}
|
|
450
456
|
const result = [];
|
|
451
457
|
for (let i = 0; i < 60; i += step) {
|
|
@@ -539,7 +545,9 @@ var DEFAULT_RANGEPICKER_LABELS = {
|
|
|
539
545
|
popoverLabel: "Choose date range",
|
|
540
546
|
startInput: "Start date",
|
|
541
547
|
endInput: "End date",
|
|
542
|
-
presetsGroup: "Date range presets"
|
|
548
|
+
presetsGroup: "Date range presets",
|
|
549
|
+
selectingEnd: "Now select end date",
|
|
550
|
+
rangeSelected: "Range selected"
|
|
543
551
|
};
|
|
544
552
|
var DEFAULT_TIMEPICKER_LABELS = {
|
|
545
553
|
timeInput: "Time",
|
package/package.json
CHANGED