@konce-pt/datetime 0.9.1 → 0.10.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/dist/index.d.ts +1 -0
- package/dist/index.js +1 -0
- package/dist/keys.d.ts +28 -0
- package/dist/keys.js +102 -0
- package/dist/range.d.ts +4 -1
- package/dist/range.js +2 -2
- package/package.json +1 -1
package/dist/index.d.ts
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
export { datePart, formatDate, formatTime, from12h, pad, parseDate, parseDateTime, parseTime, timePart, toIso, } from './iso.ts';
|
|
2
2
|
export { KPT_CALENDAR_LEVELS, buildDayGrid, buildDecadeCells, buildMonthCells, buildYearCells, canPageBack, canPageForward, centuryStart, commitLevelFor, decadeStart, initialPage, isMonthYearDisabled, isYearDisabled, pageBy, resolveStartView, selectedYearMonth, topLevelFor, } from './calendar.ts';
|
|
3
3
|
export type { DayGridOptions, KptCalendarPage, KptCalendarView, KptDateSelectionMode, KptDayCell, KptGridCell, MonthCellsOptions, YearCellsOptions, } from './calendar.ts';
|
|
4
|
+
export { KPT_DAY_GRID_KEYS, clampIso, initialFocusDate, moveCellIndex, moveFocusDate } from './keys.ts';
|
|
4
5
|
export { buildRangeGrid, clampVisibleMonths, pickRangeDay } from './range.ts';
|
|
5
6
|
export type { KptDateRangeMode, KptDateRangeValue, KptMonthPanel, KptRangeDayCell, RangeGridOptions, } from './range.ts';
|
|
6
7
|
export { KPT_CLOCK_R_INNER, KPT_CLOCK_R_OUTER, handAngle, handIsInner, hourFromAngle, hourMarks, markPosition, minuteFromAngle, minuteMarks, } from './clock.ts';
|
package/dist/index.js
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
export { datePart, formatDate, formatTime, from12h, pad, parseDate, parseDateTime, parseTime, timePart, toIso, } from "./iso.js";
|
|
2
2
|
export { KPT_CALENDAR_LEVELS, buildDayGrid, buildDecadeCells, buildMonthCells, buildYearCells, canPageBack, canPageForward, centuryStart, commitLevelFor, decadeStart, initialPage, isMonthYearDisabled, isYearDisabled, pageBy, resolveStartView, selectedYearMonth, topLevelFor, } from "./calendar.js";
|
|
3
|
+
export { KPT_DAY_GRID_KEYS, clampIso, initialFocusDate, moveCellIndex, moveFocusDate } from "./keys.js";
|
|
3
4
|
export { buildRangeGrid, clampVisibleMonths, pickRangeDay } from "./range.js";
|
|
4
5
|
export { KPT_CLOCK_R_INNER, KPT_CLOCK_R_OUTER, handAngle, handIsInner, hourFromAngle, hourMarks, markPosition, minuteFromAngle, minuteMarks, } from "./clock.js";
|
package/dist/keys.d.ts
ADDED
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
/** Klawisze przesuwające skupiony dzień w siatce dni. */
|
|
2
|
+
export declare const KPT_DAY_GRID_KEYS: Set<string>;
|
|
3
|
+
/**
|
|
4
|
+
* Nowy skupiony dzień po klawiszu. `←`/`→` ±1 dzień, `↑`/`↓` ±7, `Home`/`End` poniedziałek
|
|
5
|
+
* i niedziela tego tygodnia, `PageUp`/`PageDown` ±1 miesiąc (z `shift` ±1 rok) — dzień miesiąca
|
|
6
|
+
* jest przycinany do długości docelowego miesiąca (31 stycznia → 28/29 lutego). W RTL strzałki
|
|
7
|
+
* w poziomie są odwrócone. Wynik nie wychodzi poza `minDate`/`maxDate`. `null` dla innego klawisza
|
|
8
|
+
* albo niepoprawnej daty.
|
|
9
|
+
*/
|
|
10
|
+
export declare function moveFocusDate(iso: string, key: string, options?: {
|
|
11
|
+
shift?: boolean;
|
|
12
|
+
rtl?: boolean;
|
|
13
|
+
minDate?: string | null;
|
|
14
|
+
maxDate?: string | null;
|
|
15
|
+
}): string | null;
|
|
16
|
+
/** Data przycięta do zakresu `[minDate, maxDate]` (porównanie napisów ISO). */
|
|
17
|
+
export declare function clampIso(iso: string, minDate: string | null, maxDate: string | null): string;
|
|
18
|
+
/**
|
|
19
|
+
* Pierwszy dzień do skupienia po otwarciu kalendarza: wybrany, a bez niego dzisiejszy — oba
|
|
20
|
+
* przycięte do zakresu.
|
|
21
|
+
*/
|
|
22
|
+
export declare function initialFocusDate(selectedIso: string, todayIso: string, minDate: string | null, maxDate: string | null): string;
|
|
23
|
+
/**
|
|
24
|
+
* Nowy indeks w siatce komórek (miesiące, lata, dekady) o `columns` kolumnach: `←`/`→` ±1,
|
|
25
|
+
* `↑`/`↓` ±kolumna, `Home`/`End` pierwsza i ostatnia. Bez przechodzenia na sąsiednią stronę —
|
|
26
|
+
* od tego są przyciski ‹ ›. Pomija komórki wyłączone w kierunku ruchu.
|
|
27
|
+
*/
|
|
28
|
+
export declare function moveCellIndex(disabled: readonly boolean[], current: number, key: string, columns: number, rtl?: boolean): number | null;
|
package/dist/keys.js
ADDED
|
@@ -0,0 +1,102 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Klawiatura siatek kalendarza (wzorzec WAI-ARIA „date picker dialog”). Czysta arytmetyka na
|
|
3
|
+
* napisach ISO — komponenty obu portów trzymają tylko „skupiony dzień” i wołają te funkcje.
|
|
4
|
+
*/
|
|
5
|
+
import { parseDate, toIso } from "./iso.js";
|
|
6
|
+
/** Klawisze przesuwające skupiony dzień w siatce dni. */
|
|
7
|
+
export const KPT_DAY_GRID_KEYS = new Set([
|
|
8
|
+
'ArrowLeft',
|
|
9
|
+
'ArrowRight',
|
|
10
|
+
'ArrowUp',
|
|
11
|
+
'ArrowDown',
|
|
12
|
+
'Home',
|
|
13
|
+
'End',
|
|
14
|
+
'PageUp',
|
|
15
|
+
'PageDown',
|
|
16
|
+
]);
|
|
17
|
+
/**
|
|
18
|
+
* Nowy skupiony dzień po klawiszu. `←`/`→` ±1 dzień, `↑`/`↓` ±7, `Home`/`End` poniedziałek
|
|
19
|
+
* i niedziela tego tygodnia, `PageUp`/`PageDown` ±1 miesiąc (z `shift` ±1 rok) — dzień miesiąca
|
|
20
|
+
* jest przycinany do długości docelowego miesiąca (31 stycznia → 28/29 lutego). W RTL strzałki
|
|
21
|
+
* w poziomie są odwrócone. Wynik nie wychodzi poza `minDate`/`maxDate`. `null` dla innego klawisza
|
|
22
|
+
* albo niepoprawnej daty.
|
|
23
|
+
*/
|
|
24
|
+
export function moveFocusDate(iso, key, options = {}) {
|
|
25
|
+
const date = parseDate(iso);
|
|
26
|
+
if (!date || !KPT_DAY_GRID_KEYS.has(key))
|
|
27
|
+
return null;
|
|
28
|
+
const y = date.getFullYear();
|
|
29
|
+
const m = date.getMonth();
|
|
30
|
+
const d = date.getDate();
|
|
31
|
+
const horizontal = options.rtl ? -1 : 1;
|
|
32
|
+
let next;
|
|
33
|
+
switch (key) {
|
|
34
|
+
case 'ArrowLeft':
|
|
35
|
+
next = new Date(y, m, d - horizontal);
|
|
36
|
+
break;
|
|
37
|
+
case 'ArrowRight':
|
|
38
|
+
next = new Date(y, m, d + horizontal);
|
|
39
|
+
break;
|
|
40
|
+
case 'ArrowUp':
|
|
41
|
+
next = new Date(y, m, d - 7);
|
|
42
|
+
break;
|
|
43
|
+
case 'ArrowDown':
|
|
44
|
+
next = new Date(y, m, d + 7);
|
|
45
|
+
break;
|
|
46
|
+
case 'Home':
|
|
47
|
+
next = new Date(y, m, d - ((date.getDay() + 6) % 7));
|
|
48
|
+
break;
|
|
49
|
+
case 'End':
|
|
50
|
+
next = new Date(y, m, d + (6 - ((date.getDay() + 6) % 7)));
|
|
51
|
+
break;
|
|
52
|
+
default: {
|
|
53
|
+
const dir = key === 'PageDown' ? 1 : -1;
|
|
54
|
+
const months = options.shift ? 12 * dir : dir;
|
|
55
|
+
const target = new Date(y, m + months, 1);
|
|
56
|
+
const days = new Date(target.getFullYear(), target.getMonth() + 1, 0).getDate();
|
|
57
|
+
next = new Date(target.getFullYear(), target.getMonth(), Math.min(d, days));
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
return clampIso(toIso(next), options.minDate ?? null, options.maxDate ?? null);
|
|
61
|
+
}
|
|
62
|
+
/** Data przycięta do zakresu `[minDate, maxDate]` (porównanie napisów ISO). */
|
|
63
|
+
export function clampIso(iso, minDate, maxDate) {
|
|
64
|
+
if (minDate && iso < minDate)
|
|
65
|
+
return minDate;
|
|
66
|
+
if (maxDate && iso > maxDate)
|
|
67
|
+
return maxDate;
|
|
68
|
+
return iso;
|
|
69
|
+
}
|
|
70
|
+
/**
|
|
71
|
+
* Pierwszy dzień do skupienia po otwarciu kalendarza: wybrany, a bez niego dzisiejszy — oba
|
|
72
|
+
* przycięte do zakresu.
|
|
73
|
+
*/
|
|
74
|
+
export function initialFocusDate(selectedIso, todayIso, minDate, maxDate) {
|
|
75
|
+
return clampIso(parseDate(selectedIso) ? selectedIso : todayIso, minDate, maxDate);
|
|
76
|
+
}
|
|
77
|
+
/**
|
|
78
|
+
* Nowy indeks w siatce komórek (miesiące, lata, dekady) o `columns` kolumnach: `←`/`→` ±1,
|
|
79
|
+
* `↑`/`↓` ±kolumna, `Home`/`End` pierwsza i ostatnia. Bez przechodzenia na sąsiednią stronę —
|
|
80
|
+
* od tego są przyciski ‹ ›. Pomija komórki wyłączone w kierunku ruchu.
|
|
81
|
+
*/
|
|
82
|
+
export function moveCellIndex(disabled, current, key, columns, rtl = false) {
|
|
83
|
+
const count = disabled.length;
|
|
84
|
+
const horizontal = rtl ? -1 : 1;
|
|
85
|
+
const step = {
|
|
86
|
+
ArrowLeft: -horizontal,
|
|
87
|
+
ArrowRight: horizontal,
|
|
88
|
+
ArrowUp: -columns,
|
|
89
|
+
ArrowDown: columns,
|
|
90
|
+
};
|
|
91
|
+
if (key === 'Home' || key === 'End') {
|
|
92
|
+
const order = key === 'Home' ? [...Array(count).keys()] : [...Array(count).keys()].reverse();
|
|
93
|
+
return order.find((i) => !disabled[i]) ?? null;
|
|
94
|
+
}
|
|
95
|
+
const delta = step[key];
|
|
96
|
+
if (delta === undefined)
|
|
97
|
+
return null;
|
|
98
|
+
for (let i = current + delta; i >= 0 && i < count; i += delta)
|
|
99
|
+
if (!disabled[i])
|
|
100
|
+
return i;
|
|
101
|
+
return current;
|
|
102
|
+
}
|
package/dist/range.d.ts
CHANGED
|
@@ -33,13 +33,16 @@ export interface RangeGridOptions {
|
|
|
33
33
|
todayIso: string;
|
|
34
34
|
/** Ukrywa dni sąsiednich miesięcy — konieczne, gdy paneli jest kilka. */
|
|
35
35
|
hideOutside?: boolean;
|
|
36
|
+
/** Granice wyboru 'RRRR-MM-DD' (włącznie); dni poza nimi są wyłączone. */
|
|
37
|
+
minDate?: string | null;
|
|
38
|
+
maxDate?: string | null;
|
|
36
39
|
}
|
|
37
40
|
/**
|
|
38
41
|
* Siatka dni z pasmem zakresu. Przy kilku panelach dni sąsiednich miesięcy stają się pustymi
|
|
39
42
|
* slotami: inaczej ta sama data byłaby klikalna dwa razy — jako wygaszona w jednym panelu
|
|
40
43
|
* i właściwa w drugim — a pasmo malowałoby się w obu miejscach.
|
|
41
44
|
*/
|
|
42
|
-
export declare function buildRangeGrid({ page, start, end, todayIso, hideOutside, }: RangeGridOptions): KptRangeDayCell[][];
|
|
45
|
+
export declare function buildRangeGrid({ page, start, end, todayIso, hideOutside, minDate, maxDate, }: RangeGridOptions): KptRangeDayCell[][];
|
|
43
46
|
/**
|
|
44
47
|
* Kolejny klik w zakresie: pierwszy ustawia początek, drugi koniec, trzeci zaczyna od nowa.
|
|
45
48
|
* Klik przed początkiem nie tworzy odwróconego zakresu — kolejność jest normalizowana.
|
package/dist/range.js
CHANGED
|
@@ -4,7 +4,7 @@ import { toIso } from "./iso.js";
|
|
|
4
4
|
* slotami: inaczej ta sama data byłaby klikalna dwa razy — jako wygaszona w jednym panelu
|
|
5
5
|
* i właściwa w drugim — a pasmo malowałoby się w obu miejscach.
|
|
6
6
|
*/
|
|
7
|
-
export function buildRangeGrid({ page, start, end, todayIso, hideOutside = false, }) {
|
|
7
|
+
export function buildRangeGrid({ page, start, end, todayIso, hideOutside = false, minDate = null, maxDate = null, }) {
|
|
8
8
|
const { y, m } = page;
|
|
9
9
|
const hasBand = !!start && !!end && start < end;
|
|
10
10
|
const first = new Date(y, m, 1);
|
|
@@ -28,7 +28,7 @@ export function buildRangeGrid({ page, start, end, todayIso, hideOutside = false
|
|
|
28
28
|
rangeStart: hasBand && iso === start,
|
|
29
29
|
rangeEnd: hasBand && iso === end,
|
|
30
30
|
blank: hideOutside && !inMonth,
|
|
31
|
-
disabled:
|
|
31
|
+
disabled: (!!minDate && iso < minDate) || (!!maxDate && iso > maxDate),
|
|
32
32
|
});
|
|
33
33
|
}
|
|
34
34
|
weeks.push(row);
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@konce-pt/datetime",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.10.0",
|
|
4
4
|
"description": "Calendar and clock core for Koncept UI date controls — day/month/year/decade grids, ranges, dial marks. Framework-free TypeScript, zero runtime dependencies.",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"author": "konce.pt",
|