ics-ui-kit 1.0.0-alpha.1 → 1.0.0-alpha.2
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/CalendarPreviousMonthButton-CHMp8bkd.js +2964 -0
- package/dist/CalendarPreviousMonthButton-CHMp8bkd.js.map +1 -0
- package/dist/components/calendar/components/calendar-dropdown/CalendarDropdown.d.ts +24 -0
- package/dist/components/calendar/styles.d.ts +61 -0
- package/dist/components/calendar-scroll/CalendarScroll.d.ts +21 -0
- package/dist/components/calendar-scroll/CalendarScroll.stories.d.ts +16 -0
- package/dist/components/calendar-scroll/index.d.ts +3 -0
- package/dist/components/calendar-scroll.d.ts +2 -0
- package/dist/components/calendar-scroll.js +181 -0
- package/dist/components/calendar-scroll.js.map +1 -0
- package/dist/components/calendar.js +54 -2968
- package/dist/components/calendar.js.map +1 -1
- package/dist/tailwind.css +13 -15
- package/package.json +208 -207
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import { SelectHTMLAttributes } from 'react';
|
|
2
|
+
import { ClassNames, CustomComponents, DropdownOption } from 'react-day-picker';
|
|
3
|
+
export type CalendarDropdownProps = Omit<SelectHTMLAttributes<HTMLSelectElement>, "children"> & {
|
|
4
|
+
options?: DropdownOption[];
|
|
5
|
+
/** Передаёт react-day-picker: переопределения классов потребителя */
|
|
6
|
+
classNames?: Partial<ClassNames>;
|
|
7
|
+
/** Передаёт react-day-picker: переопределения компонентов потребителя */
|
|
8
|
+
components?: Partial<CustomComponents>;
|
|
9
|
+
};
|
|
10
|
+
/**
|
|
11
|
+
* Селект месяца/года в шапке календаря: прозрачный нативный select поверх подписи с шевроном.
|
|
12
|
+
*
|
|
13
|
+
* В отличие от штатного Dropdown из react-day-picker, подпись резервирует ширину самой длинной
|
|
14
|
+
* опции: все подписи лежат в одной grid-ячейке, видна только выбранная. Иначе при смене месяца
|
|
15
|
+
* («май» → «сентябрь») меняется ширина и шапка, выровненная по центру, дёргается.
|
|
16
|
+
*
|
|
17
|
+
* @param options - Опции селекта
|
|
18
|
+
* @param className - Дополнительные CSS классы для select
|
|
19
|
+
* @param props - Атрибуты нативного select
|
|
20
|
+
*/
|
|
21
|
+
export declare const CalendarDropdown: {
|
|
22
|
+
({ options, className, classNames, components, ...props }: CalendarDropdownProps): import("react/jsx-runtime").JSX.Element;
|
|
23
|
+
displayName: string;
|
|
24
|
+
};
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
import { TVReturnType } from 'tailwind-variants';
|
|
2
|
+
import { ClassNameValue } from 'tailwind-merge';
|
|
3
|
+
/**
|
|
4
|
+
* Селект месяца/года в шапке календаря: прозрачный нативный select поверх подписи с шевроном.
|
|
5
|
+
* Общий для Calendar (через classNames react-day-picker) и CalendarScroll (своя разметка).
|
|
6
|
+
*/
|
|
7
|
+
export declare const calendarDropdownStyles: TVReturnType<{
|
|
8
|
+
[key: string]: {
|
|
9
|
+
[key: string]: ClassNameValue | {
|
|
10
|
+
label?: ClassNameValue;
|
|
11
|
+
select?: ClassNameValue;
|
|
12
|
+
sizer?: ClassNameValue;
|
|
13
|
+
sizerItem?: ClassNameValue;
|
|
14
|
+
sizerItemHidden?: ClassNameValue;
|
|
15
|
+
root?: ClassNameValue;
|
|
16
|
+
};
|
|
17
|
+
};
|
|
18
|
+
} | {
|
|
19
|
+
[x: string]: {
|
|
20
|
+
[x: string]: ClassNameValue | {
|
|
21
|
+
label?: ClassNameValue;
|
|
22
|
+
select?: ClassNameValue;
|
|
23
|
+
sizer?: ClassNameValue;
|
|
24
|
+
sizerItem?: ClassNameValue;
|
|
25
|
+
sizerItemHidden?: ClassNameValue;
|
|
26
|
+
root?: ClassNameValue;
|
|
27
|
+
};
|
|
28
|
+
};
|
|
29
|
+
} | {}, {
|
|
30
|
+
root: string[];
|
|
31
|
+
select: string;
|
|
32
|
+
label: string[];
|
|
33
|
+
sizer: string;
|
|
34
|
+
sizerItem: string;
|
|
35
|
+
sizerItemHidden: string;
|
|
36
|
+
}, undefined, {
|
|
37
|
+
[key: string]: {
|
|
38
|
+
[key: string]: ClassNameValue | {
|
|
39
|
+
label?: ClassNameValue;
|
|
40
|
+
select?: ClassNameValue;
|
|
41
|
+
sizer?: ClassNameValue;
|
|
42
|
+
sizerItem?: ClassNameValue;
|
|
43
|
+
sizerItemHidden?: ClassNameValue;
|
|
44
|
+
root?: ClassNameValue;
|
|
45
|
+
};
|
|
46
|
+
};
|
|
47
|
+
} | {}, {
|
|
48
|
+
root: string[];
|
|
49
|
+
select: string;
|
|
50
|
+
label: string[];
|
|
51
|
+
sizer: string;
|
|
52
|
+
sizerItem: string;
|
|
53
|
+
sizerItemHidden: string;
|
|
54
|
+
}, TVReturnType<unknown, {
|
|
55
|
+
root: string[];
|
|
56
|
+
select: string;
|
|
57
|
+
label: string[];
|
|
58
|
+
sizer: string;
|
|
59
|
+
sizerItem: string;
|
|
60
|
+
sizerItemHidden: string;
|
|
61
|
+
}, undefined, unknown, unknown, undefined>>;
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import { DayPickerProps } from 'react-day-picker';
|
|
2
|
+
type DistributiveOmit<T, K extends PropertyKey> = T extends unknown ? Omit<T, K> : never;
|
|
3
|
+
/** Пропсы DayPicker, которыми управляет сам CalendarScroll */
|
|
4
|
+
type ManagedProps = "month" | "onMonthChange" | "numberOfMonths" | "captionLayout" | "fixedWeeks" | "hideNavigation" | "showOutsideDays" | "pagedNavigation" | "reverseMonths";
|
|
5
|
+
export type CalendarScrollProps = DistributiveOmit<DayPickerProps, ManagedProps>;
|
|
6
|
+
/**
|
|
7
|
+
* CalendarScroll — календарь с вертикальным скроллом месяцев (как в мобильных банках).
|
|
8
|
+
*
|
|
9
|
+
* Месяцы идут друг за другом, сверху общая шапка с селектами месяца и года для быстрого
|
|
10
|
+
* прыжка. Селекты синхронизированы со скроллом. В DOM лежит только окно из нескольких
|
|
11
|
+
* месяцев, поэтому диапазон может быть широким (по умолчанию ±100 лет). Виртуализацию лучше
|
|
12
|
+
* не отключать: без неё DayPicker пересчитывал бы дни всех месяцев диапазона на каждом рендере.
|
|
13
|
+
*
|
|
14
|
+
* Высота задаётся через `className` (по умолчанию 420px). Выбор дат — те же `mode`,
|
|
15
|
+
* `selected`, `onSelect`, что и у Calendar.
|
|
16
|
+
*/
|
|
17
|
+
export declare const CalendarScroll: {
|
|
18
|
+
({ className, classNames, locale, weekStartsOn, startMonth, endMonth, defaultMonth, components, ...props }: CalendarScrollProps): import("react/jsx-runtime").JSX.Element;
|
|
19
|
+
displayName: string;
|
|
20
|
+
};
|
|
21
|
+
export {};
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import { StoryObj } from '@storybook/react';
|
|
2
|
+
import { CalendarScroll, CalendarScrollProps } from './CalendarScroll';
|
|
3
|
+
declare const meta: {
|
|
4
|
+
component: {
|
|
5
|
+
({ className, classNames, locale, weekStartsOn, startMonth, endMonth, defaultMonth, components, ...props }: CalendarScrollProps): import("react/jsx-runtime").JSX.Element;
|
|
6
|
+
displayName: string;
|
|
7
|
+
};
|
|
8
|
+
tags: string[];
|
|
9
|
+
parameters: {
|
|
10
|
+
layout: string;
|
|
11
|
+
};
|
|
12
|
+
};
|
|
13
|
+
export default meta;
|
|
14
|
+
type Story = StoryObj<typeof CalendarScroll>;
|
|
15
|
+
export declare const Default: Story;
|
|
16
|
+
export declare const Range: Story;
|
|
@@ -0,0 +1,181 @@
|
|
|
1
|
+
import { jsx as n, jsxs as E } from "react/jsx-runtime";
|
|
2
|
+
import { useRef as C, useState as A, useCallback as N, useLayoutEffect as ue, useEffect as Z, useMemo as i, Children as he, cloneElement as me, isValidElement as fe } from "react";
|
|
3
|
+
import { T as pe } from "../index-BVqs-uqP.js";
|
|
4
|
+
import { f as H, e as be, s as we, a as xe, C as ye, l as Me, b as P, c as q, d as ve, g as ge, h as De, i as Ee, D as Ne, j as Se, M as Ce } from "../CalendarPreviousMonthButton-CHMp8bkd.js";
|
|
5
|
+
const d = 280, V = 4, G = 1, Fe = 100, ke = 2100, _e = pe({
|
|
6
|
+
slots: {
|
|
7
|
+
root: [
|
|
8
|
+
"flex h-[420px] w-fit flex-col overflow-hidden rounded-md",
|
|
9
|
+
"border border-solid border-secondary-border bg-secondary-bg shadow-soft-sm"
|
|
10
|
+
],
|
|
11
|
+
header: "flex flex-col gap-2 border-b border-secondary-border p-3 pb-2",
|
|
12
|
+
nav: "flex h-9 items-center justify-between gap-1",
|
|
13
|
+
dropdowns: "flex items-center justify-center gap-1.5 text-sm font-medium capitalize",
|
|
14
|
+
weekdays: "flex",
|
|
15
|
+
weekday: "w-9 shrink-0 text-center text-xs font-medium text-muted-foreground opacity-70",
|
|
16
|
+
scroller: "relative flex-1 overflow-y-auto overscroll-contain px-3",
|
|
17
|
+
window: "absolute inset-x-3 top-0"
|
|
18
|
+
}
|
|
19
|
+
}), B = (o) => o.getFullYear() * 12 + o.getMonth(), f = (o) => new Date(Math.floor(o / 12), o % 12, 1), S = (o, s, a) => Math.min(Math.max(o, s), a), Le = ({ modifiers: o, ...s }) => {
|
|
20
|
+
const a = C(null), h = C(!0);
|
|
21
|
+
return Z(() => {
|
|
22
|
+
const F = h.current;
|
|
23
|
+
if (h.current = !1, !o.focused || F)
|
|
24
|
+
return;
|
|
25
|
+
const u = a.current?.querySelector("button"), M = u?.closest("[data-calendar-scroll-scroller]");
|
|
26
|
+
!u || !M || u === document.activeElement || M.contains(document.activeElement) && (u.focus({ preventScroll: !0 }), u.scrollIntoView({ block: "nearest" }));
|
|
27
|
+
}, [o.focused]), /* @__PURE__ */ n("span", { ref: a, className: "contents", children: /* @__PURE__ */ n(Se, { ...s, modifiers: { ...o, focused: !1 } }) });
|
|
28
|
+
}, Te = ({ children: o, ...s }) => /* @__PURE__ */ n(Ce, { ...s, children: he.toArray(o).map(
|
|
29
|
+
(a) => fe(a) && a.props.calendarMonth ? me(a, { key: a.props.calendarMonth.date.getTime() }) : a
|
|
30
|
+
) }), Ae = ({
|
|
31
|
+
className: o,
|
|
32
|
+
classNames: s,
|
|
33
|
+
locale: a = be,
|
|
34
|
+
weekStartsOn: h,
|
|
35
|
+
startMonth: F,
|
|
36
|
+
endMonth: u,
|
|
37
|
+
defaultMonth: M,
|
|
38
|
+
components: R,
|
|
39
|
+
...Y
|
|
40
|
+
}) => {
|
|
41
|
+
const c = _e(), p = C(null), v = C(0), r = B(F ?? new Date((/* @__PURE__ */ new Date()).getFullYear() - Fe, 0, 1)), b = B(u ?? new Date(ke, 11, 1)), l = Math.max(b - r + 1, 1), [J, Q] = A(V), k = Math.min(J, l), w = N(
|
|
42
|
+
(e) => S(e - G, 0, l - k),
|
|
43
|
+
[l, k]
|
|
44
|
+
), _ = S(B(M ?? /* @__PURE__ */ new Date()) - r, 0, l - 1), [x, z] = A(_), [L, W] = A(() => w(_));
|
|
45
|
+
ue(() => {
|
|
46
|
+
const e = p.current;
|
|
47
|
+
if (!e)
|
|
48
|
+
return;
|
|
49
|
+
const t = Math.ceil(e.clientHeight / d) + 1;
|
|
50
|
+
e.scrollTop = _ * d, Q(Math.max(V, t + G));
|
|
51
|
+
}, []), Z(() => () => cancelAnimationFrame(v.current), []);
|
|
52
|
+
const j = N(() => {
|
|
53
|
+
const e = p.current;
|
|
54
|
+
if (!e)
|
|
55
|
+
return;
|
|
56
|
+
const t = e.scrollTop;
|
|
57
|
+
z(S(Math.round(t / d), 0, l - 1)), W(w(Math.floor(t / d)));
|
|
58
|
+
}, [w, l]), X = N(() => {
|
|
59
|
+
v.current || (v.current = requestAnimationFrame(() => {
|
|
60
|
+
v.current = 0, j();
|
|
61
|
+
}));
|
|
62
|
+
}, [j]), T = N(
|
|
63
|
+
(e) => {
|
|
64
|
+
const t = p.current;
|
|
65
|
+
if (!t)
|
|
66
|
+
return;
|
|
67
|
+
const m = S(e - r, 0, l - 1);
|
|
68
|
+
t.scrollTop = m * d, z(m), W(w(m));
|
|
69
|
+
},
|
|
70
|
+
[w, r, l]
|
|
71
|
+
), I = (e) => {
|
|
72
|
+
const t = p.current;
|
|
73
|
+
t && T(r + Math.round(t.scrollTop / d) + e);
|
|
74
|
+
}, g = f(r + x), $ = f(r + x - 1), ee = f(r + x + 1), O = x === 0, K = x === l - 1, te = (e) => {
|
|
75
|
+
T(g.getFullYear() * 12 + Number(e.target.value));
|
|
76
|
+
}, oe = (e) => {
|
|
77
|
+
T(Number(e.target.value) * 12 + g.getMonth());
|
|
78
|
+
}, y = a, D = Y.labels, ne = i(
|
|
79
|
+
() => Array.from({ length: 12 }, (e, t) => ({
|
|
80
|
+
value: t,
|
|
81
|
+
label: H(new Date(2e3, t, 1), "LLLL", { locale: y }),
|
|
82
|
+
disabled: !1
|
|
83
|
+
})),
|
|
84
|
+
[y]
|
|
85
|
+
), re = i(() => {
|
|
86
|
+
const e = we(/* @__PURE__ */ new Date(), { locale: y, weekStartsOn: h });
|
|
87
|
+
return Array.from({ length: 7 }, (t, m) => H(xe(e, m), "EEEEEE", { locale: y }));
|
|
88
|
+
}, [y, h]), ae = i(() => {
|
|
89
|
+
const e = Math.floor(r / 12), t = Math.floor(b / 12);
|
|
90
|
+
return Array.from({ length: t - e + 1 }, (m, U) => ({
|
|
91
|
+
value: e + U,
|
|
92
|
+
label: String(e + U),
|
|
93
|
+
disabled: !1
|
|
94
|
+
}));
|
|
95
|
+
}, [r, b]), le = i(
|
|
96
|
+
() => ({
|
|
97
|
+
months: "flex flex-col",
|
|
98
|
+
month: "flex h-[280px] flex-col gap-1 pb-4",
|
|
99
|
+
month_caption: "flex items-center px-2 capitalize",
|
|
100
|
+
caption_label: "select-none text-sm font-medium",
|
|
101
|
+
month_grid: "w-full border-collapse",
|
|
102
|
+
weekdays: "hidden",
|
|
103
|
+
week: "mt-1 flex h-9",
|
|
104
|
+
day: "size-9 shrink-0 border-0 p-0",
|
|
105
|
+
hidden: "invisible",
|
|
106
|
+
...s
|
|
107
|
+
}),
|
|
108
|
+
[s]
|
|
109
|
+
), se = i(
|
|
110
|
+
() => ({ Months: Te, DayButton: Le, ...R }),
|
|
111
|
+
[R]
|
|
112
|
+
), ce = i(() => f(r), [r]), ie = i(() => f(b), [b]), de = i(() => f(r + L), [r, L]);
|
|
113
|
+
return /* @__PURE__ */ E("div", { className: c.root({ className: o }), children: [
|
|
114
|
+
/* @__PURE__ */ E("div", { className: c.header(), children: [
|
|
115
|
+
/* @__PURE__ */ E("div", { className: c.nav(), children: [
|
|
116
|
+
/* @__PURE__ */ n(
|
|
117
|
+
ye,
|
|
118
|
+
{
|
|
119
|
+
"aria-label": (D?.labelPrevious ?? Me)(O ? void 0 : $),
|
|
120
|
+
disabled: O,
|
|
121
|
+
onClick: () => I(-1),
|
|
122
|
+
children: /* @__PURE__ */ n(P, { orientation: "left" })
|
|
123
|
+
}
|
|
124
|
+
),
|
|
125
|
+
/* @__PURE__ */ E("div", { className: c.dropdowns(), children: [
|
|
126
|
+
/* @__PURE__ */ n(
|
|
127
|
+
q,
|
|
128
|
+
{
|
|
129
|
+
"aria-label": (D?.labelMonthDropdown ?? ve)(),
|
|
130
|
+
options: ne,
|
|
131
|
+
value: g.getMonth(),
|
|
132
|
+
onChange: te
|
|
133
|
+
}
|
|
134
|
+
),
|
|
135
|
+
/* @__PURE__ */ n(
|
|
136
|
+
q,
|
|
137
|
+
{
|
|
138
|
+
"aria-label": (D?.labelYearDropdown ?? ge)(),
|
|
139
|
+
options: ae,
|
|
140
|
+
value: g.getFullYear(),
|
|
141
|
+
onChange: oe
|
|
142
|
+
}
|
|
143
|
+
)
|
|
144
|
+
] }),
|
|
145
|
+
/* @__PURE__ */ n(
|
|
146
|
+
De,
|
|
147
|
+
{
|
|
148
|
+
"aria-label": (D?.labelNext ?? Ee)(K ? void 0 : ee),
|
|
149
|
+
disabled: K,
|
|
150
|
+
onClick: () => I(1),
|
|
151
|
+
children: /* @__PURE__ */ n(P, { orientation: "right" })
|
|
152
|
+
}
|
|
153
|
+
)
|
|
154
|
+
] }),
|
|
155
|
+
/* @__PURE__ */ n("div", { className: c.weekdays(), "aria-hidden": "true", children: re.map((e, t) => /* @__PURE__ */ n("span", { className: c.weekday(), children: e }, t)) })
|
|
156
|
+
] }),
|
|
157
|
+
/* @__PURE__ */ n("div", { ref: p, className: c.scroller(), "data-calendar-scroll-scroller": "", onScroll: X, children: /* @__PURE__ */ n("div", { style: { height: l * d }, children: /* @__PURE__ */ n("div", { className: c.window(), style: { top: L * d }, children: /* @__PURE__ */ n(
|
|
158
|
+
Ne,
|
|
159
|
+
{
|
|
160
|
+
...Y,
|
|
161
|
+
locale: a,
|
|
162
|
+
weekStartsOn: h,
|
|
163
|
+
startMonth: ce,
|
|
164
|
+
endMonth: ie,
|
|
165
|
+
month: de,
|
|
166
|
+
numberOfMonths: k,
|
|
167
|
+
captionLayout: "label",
|
|
168
|
+
fixedWeeks: !0,
|
|
169
|
+
hideNavigation: !0,
|
|
170
|
+
showOutsideDays: !1,
|
|
171
|
+
classNames: le,
|
|
172
|
+
components: se
|
|
173
|
+
}
|
|
174
|
+
) }) }) })
|
|
175
|
+
] });
|
|
176
|
+
};
|
|
177
|
+
Ae.displayName = "CalendarScroll";
|
|
178
|
+
export {
|
|
179
|
+
Ae as CalendarScroll
|
|
180
|
+
};
|
|
181
|
+
//# sourceMappingURL=calendar-scroll.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"calendar-scroll.js","sources":["../../src/components/calendar-scroll/CalendarScroll.tsx"],"sourcesContent":["import { addDays, format, Locale, startOfWeek } from \"date-fns\";\r\nimport {\r\n\tChangeEvent,\r\n\tChildren,\r\n\tcloneElement,\r\n\tisValidElement,\r\n\tuseCallback,\r\n\tuseEffect,\r\n\tuseLayoutEffect,\r\n\tuseMemo,\r\n\tuseRef,\r\n\tuseState\r\n} from \"react\";\r\nimport {\r\n\tDayPicker,\r\n\tDayPickerProps,\r\n\tDropdownOption,\r\n\tlabelMonthDropdown,\r\n\tlabelNext,\r\n\tlabelPrevious,\r\n\tlabelYearDropdown,\r\n\tMonthProps,\r\n\tMonths,\r\n\tMonthsProps\r\n} from \"react-day-picker\";\r\nimport { enUS } from \"react-day-picker/locale\";\r\nimport { tv } from \"tailwind-variants\";\r\nimport { CalendarChevron } from \"../calendar/components/calendar-chevron/CalendarChevron\";\r\nimport {\r\n\tCalendarDayButton,\r\n\tCalendarDayButtonProps\r\n} from \"../calendar/components/calendar-day-button/CalendarDayButton\";\r\nimport { CalendarNextMonthButton } from \"../calendar/components/calendar-next-month-button/CalendarNextMonthButton\";\r\nimport { CalendarPreviousMonthButton } from \"../calendar/components/calendar-previous-month-button/CalendarPreviousMonthButton\";\r\nimport { CalendarDropdown } from \"../calendar/components/calendar-dropdown/CalendarDropdown\";\r\n\r\n/**\r\n * Высота одного месяца в px. Фиксирована (6 недель всегда), поэтому позицию месяца\r\n * в скролле считаем арифметикой, без измерений DOM:\r\n * подпись 20 (text-sm) + gap 4 + 6 недель × (36 + 4) + нижний отступ 16 = 280.\r\n * Если меняете стили месяца ниже — меняйте и эту константу.\r\n */\r\nconst MONTH_HEIGHT = 280;\r\n/**\r\n * Сколько месяцев лежит в DOM до замера высоты скроллера. После монтирования окно\r\n * подгоняется под реальную высоту: видимые месяцы + 1 снизу + BUFFER_BEFORE сверху.\r\n * Каждый лишний месяц — ~42 дня, которые DayPicker пересчитывает на любом рендере.\r\n */\r\nconst DEFAULT_WINDOW_SIZE = 4;\r\n/** Сколько месяцев держим в DOM выше верхнего видимого */\r\nconst BUFFER_BEFORE = 1;\r\nconst DEFAULT_YEARS_BACK = 100;\r\nconst DEFAULT_END_YEAR = 2100;\r\n\r\nconst calendarScrollStyles = tv({\r\n\tslots: {\r\n\t\troot: [\r\n\t\t\t\"flex h-[420px] w-fit flex-col overflow-hidden rounded-md\",\r\n\t\t\t\"border border-solid border-secondary-border bg-secondary-bg shadow-soft-sm\"\r\n\t\t],\r\n\t\theader: \"flex flex-col gap-2 border-b border-secondary-border p-3 pb-2\",\r\n\t\tnav: \"flex h-9 items-center justify-between gap-1\",\r\n\t\tdropdowns: \"flex items-center justify-center gap-1.5 text-sm font-medium capitalize\",\r\n\t\tweekdays: \"flex\",\r\n\t\tweekday: \"w-9 shrink-0 text-center text-xs font-medium text-muted-foreground opacity-70\",\r\n\t\tscroller: \"relative flex-1 overflow-y-auto overscroll-contain px-3\",\r\n\t\twindow: \"absolute inset-x-3 top-0\"\r\n\t}\r\n});\r\n\r\nconst toKey = (date: Date) => date.getFullYear() * 12 + date.getMonth();\r\nconst fromKey = (key: number) => new Date(Math.floor(key / 12), key % 12, 1);\r\nconst clamp = (value: number, min: number, max: number) => Math.min(Math.max(value, min), max);\r\n\r\n/**\r\n * Кнопка дня для вертикального скролла.\r\n *\r\n * Штатный DayButton из react-day-picker зовёт `focus()` без `preventScroll`, когда день\r\n * получает флаг `focused`. В скролл-списке это ломает прокрутку: окно месяцев сдвигается,\r\n * ранее выбранный день снова попадает в DOM, фокус на него утягивает скролл назад.\r\n * Поэтому программный фокус делаем сами: только при клавиатурной навигации (фокус уже\r\n * внутри скроллера), с `preventScroll`, и скроллим к дню лишь если он вне видимой области.\r\n */\r\nconst CalendarScrollDayButton = ({ modifiers, ...props }: CalendarDayButtonProps) => {\r\n\tconst anchorRef = useRef<HTMLSpanElement>(null);\r\n\tconst isFirstRun = useRef(true);\r\n\r\n\tuseEffect(() => {\r\n\t\tconst isMount = isFirstRun.current;\r\n\t\tisFirstRun.current = false;\r\n\t\tif (!modifiers.focused || isMount) {\r\n\t\t\treturn;\r\n\t\t}\r\n\t\tconst button = anchorRef.current?.querySelector(\"button\");\r\n\t\tconst scroller = button?.closest(\"[data-calendar-scroll-scroller]\");\r\n\t\tif (!button || !scroller || button === document.activeElement) {\r\n\t\t\treturn;\r\n\t\t}\r\n\t\tif (scroller.contains(document.activeElement)) {\r\n\t\t\tbutton.focus({ preventScroll: true });\r\n\t\t\tbutton.scrollIntoView({ block: \"nearest\" });\r\n\t\t}\r\n\t}, [modifiers.focused]);\r\n\r\n\treturn (\r\n\t\t<span ref={anchorRef} className=\"contents\">\r\n\t\t\t<CalendarDayButton {...props} modifiers={{ ...modifiers, focused: false }} />\r\n\t\t</span>\r\n\t);\r\n};\r\n\r\n/**\r\n * Контейнер месяцев с ключами по самому месяцу.\r\n *\r\n * DayPicker ключует месяцы по позиции (`displayIndex`), а дни — по дате и месяцу показа.\r\n * При сдвиге окна на месяц каждая позиция получает другой месяц, и React пересоздаёт\r\n * все дни всех месяцев окна. Перекладываем ключ на `yyyy-MM`: месяцы, оставшиеся в окне,\r\n * сохраняют свои узлы, монтируется только вошедший месяц. Заодно не теряется фокус\r\n * на только что нажатом дне.\r\n */\r\nconst CalendarScrollMonths = ({ children, ...props }: MonthsProps) => (\r\n\t<Months {...props}>\r\n\t\t{Children.toArray(children).map((child) =>\r\n\t\t\tisValidElement<MonthProps>(child) && child.props.calendarMonth\r\n\t\t\t\t? cloneElement(child, { key: child.props.calendarMonth.date.getTime() })\r\n\t\t\t\t: child\r\n\t\t)}\r\n\t</Months>\r\n);\r\n\r\ntype DistributiveOmit<T, K extends PropertyKey> = T extends unknown ? Omit<T, K> : never;\r\n\r\n/** Пропсы DayPicker, которыми управляет сам CalendarScroll */\r\ntype ManagedProps =\r\n\t| \"month\"\r\n\t| \"onMonthChange\"\r\n\t| \"numberOfMonths\"\r\n\t| \"captionLayout\"\r\n\t| \"fixedWeeks\"\r\n\t| \"hideNavigation\"\r\n\t| \"showOutsideDays\"\r\n\t| \"pagedNavigation\"\r\n\t| \"reverseMonths\";\r\n\r\nexport type CalendarScrollProps = DistributiveOmit<DayPickerProps, ManagedProps>;\r\n\r\n/**\r\n * CalendarScroll — календарь с вертикальным скроллом месяцев (как в мобильных банках).\r\n *\r\n * Месяцы идут друг за другом, сверху общая шапка с селектами месяца и года для быстрого\r\n * прыжка. Селекты синхронизированы со скроллом. В DOM лежит только окно из нескольких\r\n * месяцев, поэтому диапазон может быть широким (по умолчанию ±100 лет). Виртуализацию лучше\r\n * не отключать: без неё DayPicker пересчитывал бы дни всех месяцев диапазона на каждом рендере.\r\n *\r\n * Высота задаётся через `className` (по умолчанию 420px). Выбор дат — те же `mode`,\r\n * `selected`, `onSelect`, что и у Calendar.\r\n */\r\nexport const CalendarScroll = ({\r\n\tclassName,\r\n\tclassNames,\r\n\tlocale = enUS,\r\n\tweekStartsOn,\r\n\tstartMonth,\r\n\tendMonth,\r\n\tdefaultMonth,\r\n\tcomponents,\r\n\t...props\r\n}: CalendarScrollProps) => {\r\n\tconst styles = calendarScrollStyles();\r\n\tconst scrollerRef = useRef<HTMLDivElement>(null);\r\n\tconst frameRef = useRef(0);\r\n\r\n\tconst startKey = toKey(startMonth ?? new Date(new Date().getFullYear() - DEFAULT_YEARS_BACK, 0, 1));\r\n\tconst endKey = toKey(endMonth ?? new Date(DEFAULT_END_YEAR, 11, 1));\r\n\tconst total = Math.max(endKey - startKey + 1, 1);\r\n\tconst [windowSizeLimit, setWindowSizeLimit] = useState(DEFAULT_WINDOW_SIZE);\r\n\tconst windowSize = Math.min(windowSizeLimit, total);\r\n\r\n\tconst getWindowStart = useCallback(\r\n\t\t(index: number) => clamp(index - BUFFER_BEFORE, 0, total - windowSize),\r\n\t\t[total, windowSize]\r\n\t);\r\n\r\n\tconst initialIndex = clamp(toKey(defaultMonth ?? new Date()) - startKey, 0, total - 1);\r\n\tconst [currentIndex, setCurrentIndex] = useState(initialIndex);\r\n\tconst [windowStart, setWindowStart] = useState(() => getWindowStart(initialIndex));\r\n\r\n\t// Первичная позиция и размер окна — до отрисовки, чтобы не было прыжка и пустоты\r\n\tuseLayoutEffect(() => {\r\n\t\tconst scroller = scrollerRef.current;\r\n\t\tif (!scroller) {\r\n\t\t\treturn;\r\n\t\t}\r\n\t\tconst visibleMonths = Math.ceil(scroller.clientHeight / MONTH_HEIGHT) + 1;\r\n\t\tscroller.scrollTop = initialIndex * MONTH_HEIGHT;\r\n\t\tsetWindowSizeLimit(Math.max(DEFAULT_WINDOW_SIZE, visibleMonths + BUFFER_BEFORE));\r\n\t\t// eslint-disable-next-line react-hooks/exhaustive-deps\r\n\t}, []);\r\n\r\n\tuseEffect(() => () => cancelAnimationFrame(frameRef.current), []);\r\n\r\n\tconst syncWithScroll = useCallback(() => {\r\n\t\tconst scroller = scrollerRef.current;\r\n\t\tif (!scroller) {\r\n\t\t\treturn;\r\n\t\t}\r\n\t\tconst scrollTop = scroller.scrollTop;\r\n\t\tsetCurrentIndex(clamp(Math.round(scrollTop / MONTH_HEIGHT), 0, total - 1));\r\n\t\tsetWindowStart(getWindowStart(Math.floor(scrollTop / MONTH_HEIGHT)));\r\n\t}, [getWindowStart, total]);\r\n\r\n\tconst onScroll = useCallback(() => {\r\n\t\tif (frameRef.current) {\r\n\t\t\treturn;\r\n\t\t}\r\n\t\tframeRef.current = requestAnimationFrame(() => {\r\n\t\t\tframeRef.current = 0;\r\n\t\t\tsyncWithScroll();\r\n\t\t});\r\n\t}, [syncWithScroll]);\r\n\r\n\tconst jumpTo = useCallback(\r\n\t\t(key: number) => {\r\n\t\t\tconst scroller = scrollerRef.current;\r\n\t\t\tif (!scroller) {\r\n\t\t\t\treturn;\r\n\t\t\t}\r\n\t\t\tconst index = clamp(key - startKey, 0, total - 1);\r\n\t\t\tscroller.scrollTop = index * MONTH_HEIGHT;\r\n\t\t\tsetCurrentIndex(index);\r\n\t\t\tsetWindowStart(getWindowStart(index));\r\n\t\t},\r\n\t\t[getWindowStart, startKey, total]\r\n\t);\r\n\r\n\t// Смещение считаем от scrollTop, а не от state: он обновляется синхронно,\r\n\t// поэтому быстрые клики подряд не теряются до перерендера\r\n\tconst jumpBy = (delta: number) => {\r\n\t\tconst scroller = scrollerRef.current;\r\n\t\tif (scroller) {\r\n\t\t\tjumpTo(startKey + Math.round(scroller.scrollTop / MONTH_HEIGHT) + delta);\r\n\t\t}\r\n\t};\r\n\r\n\tconst current = fromKey(startKey + currentIndex);\r\n\tconst previous = fromKey(startKey + currentIndex - 1);\r\n\tconst next = fromKey(startKey + currentIndex + 1);\r\n\tconst isFirst = currentIndex === 0;\r\n\tconst isLast = currentIndex === total - 1;\r\n\r\n\tconst onMonthSelect = (event: ChangeEvent<HTMLSelectElement>) => {\r\n\t\tjumpTo(current.getFullYear() * 12 + Number(event.target.value));\r\n\t};\r\n\r\n\tconst onYearSelect = (event: ChangeEvent<HTMLSelectElement>) => {\r\n\t\tjumpTo(Number(event.target.value) * 12 + current.getMonth());\r\n\t};\r\n\r\n\t// DayPicker типизирует locale как Partial, но на деле это полноценная date-fns Locale\r\n\tconst dateFnsLocale = locale as Locale;\r\n\t// Подписи для a11y берём из тех же labels, что и DayPicker, чтобы переопределялись одним пропсом\r\n\tconst labels = props.labels;\r\n\r\n\tconst monthOptions: DropdownOption[] = useMemo(\r\n\t\t() =>\r\n\t\t\tArray.from({ length: 12 }, (_, month) => ({\r\n\t\t\t\tvalue: month,\r\n\t\t\t\tlabel: format(new Date(2000, month, 1), \"LLLL\", { locale: dateFnsLocale }),\r\n\t\t\t\tdisabled: false\r\n\t\t\t})),\r\n\t\t[dateFnsLocale]\r\n\t);\r\n\r\n\tconst weekdayNames = useMemo(() => {\r\n\t\tconst first = startOfWeek(new Date(), { locale: dateFnsLocale, weekStartsOn });\r\n\t\treturn Array.from({ length: 7 }, (_, day) => format(addDays(first, day), \"EEEEEE\", { locale: dateFnsLocale }));\r\n\t}, [dateFnsLocale, weekStartsOn]);\r\n\r\n\tconst yearOptions: DropdownOption[] = useMemo(() => {\r\n\t\tconst first = Math.floor(startKey / 12);\r\n\t\tconst last = Math.floor(endKey / 12);\r\n\t\treturn Array.from({ length: last - first + 1 }, (_, i) => ({\r\n\t\t\tvalue: first + i,\r\n\t\t\tlabel: String(first + i),\r\n\t\t\tdisabled: false\r\n\t\t}));\r\n\t}, [startKey, endKey]);\r\n\r\n\tconst classNamesMemoized: DayPickerProps[\"classNames\"] = useMemo(\r\n\t\t() => ({\r\n\t\t\tmonths: \"flex flex-col\",\r\n\t\t\tmonth: \"flex h-[280px] flex-col gap-1 pb-4\",\r\n\t\t\tmonth_caption: \"flex items-center px-2 capitalize\",\r\n\t\t\tcaption_label: \"select-none text-sm font-medium\",\r\n\t\t\tmonth_grid: \"w-full border-collapse\",\r\n\t\t\tweekdays: \"hidden\",\r\n\t\t\tweek: \"mt-1 flex h-9\",\r\n\t\t\tday: \"size-9 shrink-0 border-0 p-0\",\r\n\t\t\thidden: \"invisible\",\r\n\t\t\t...classNames\r\n\t\t}),\r\n\t\t[classNames]\r\n\t);\r\n\r\n\tconst componentsMemoized: DayPickerProps[\"components\"] = useMemo(\r\n\t\t() => ({ Months: CalendarScrollMonths, DayButton: CalendarScrollDayButton, ...components }),\r\n\t\t[components]\r\n\t);\r\n\r\n\tconst firstMonth = useMemo(() => fromKey(startKey), [startKey]);\r\n\tconst lastMonth = useMemo(() => fromKey(endKey), [endKey]);\r\n\tconst windowMonth = useMemo(() => fromKey(startKey + windowStart), [startKey, windowStart]);\r\n\r\n\treturn (\r\n\t\t<div className={styles.root({ className })}>\r\n\t\t\t<div className={styles.header()}>\r\n\t\t\t\t<div className={styles.nav()}>\r\n\t\t\t\t\t<CalendarPreviousMonthButton\r\n\t\t\t\t\t\taria-label={(labels?.labelPrevious ?? labelPrevious)(isFirst ? undefined : previous)}\r\n\t\t\t\t\t\tdisabled={isFirst}\r\n\t\t\t\t\t\tonClick={() => jumpBy(-1)}\r\n\t\t\t\t\t>\r\n\t\t\t\t\t\t<CalendarChevron orientation=\"left\" />\r\n\t\t\t\t\t</CalendarPreviousMonthButton>\r\n\t\t\t\t\t<div className={styles.dropdowns()}>\r\n\t\t\t\t\t\t<CalendarDropdown\r\n\t\t\t\t\t\t\taria-label={(labels?.labelMonthDropdown ?? labelMonthDropdown)()}\r\n\t\t\t\t\t\t\toptions={monthOptions}\r\n\t\t\t\t\t\t\tvalue={current.getMonth()}\r\n\t\t\t\t\t\t\tonChange={onMonthSelect}\r\n\t\t\t\t\t\t/>\r\n\t\t\t\t\t\t<CalendarDropdown\r\n\t\t\t\t\t\t\taria-label={(labels?.labelYearDropdown ?? labelYearDropdown)()}\r\n\t\t\t\t\t\t\toptions={yearOptions}\r\n\t\t\t\t\t\t\tvalue={current.getFullYear()}\r\n\t\t\t\t\t\t\tonChange={onYearSelect}\r\n\t\t\t\t\t\t/>\r\n\t\t\t\t\t</div>\r\n\t\t\t\t\t<CalendarNextMonthButton\r\n\t\t\t\t\t\taria-label={(labels?.labelNext ?? labelNext)(isLast ? undefined : next)}\r\n\t\t\t\t\t\tdisabled={isLast}\r\n\t\t\t\t\t\tonClick={() => jumpBy(1)}\r\n\t\t\t\t\t>\r\n\t\t\t\t\t\t<CalendarChevron orientation=\"right\" />\r\n\t\t\t\t\t</CalendarNextMonthButton>\r\n\t\t\t\t</div>\r\n\t\t\t\t<div className={styles.weekdays()} aria-hidden=\"true\">\r\n\t\t\t\t\t{weekdayNames.map((name, index) => (\r\n\t\t\t\t\t\t<span key={index} className={styles.weekday()}>\r\n\t\t\t\t\t\t\t{name}\r\n\t\t\t\t\t\t</span>\r\n\t\t\t\t\t))}\r\n\t\t\t\t</div>\r\n\t\t\t</div>\r\n\t\t\t<div ref={scrollerRef} className={styles.scroller()} data-calendar-scroll-scroller=\"\" onScroll={onScroll}>\r\n\t\t\t\t<div style={{ height: total * MONTH_HEIGHT }}>\r\n\t\t\t\t\t<div className={styles.window()} style={{ top: windowStart * MONTH_HEIGHT }}>\r\n\t\t\t\t\t\t<DayPicker\r\n\t\t\t\t\t\t\t{...props}\r\n\t\t\t\t\t\t\tlocale={locale}\r\n\t\t\t\t\t\t\tweekStartsOn={weekStartsOn}\r\n\t\t\t\t\t\t\tstartMonth={firstMonth}\r\n\t\t\t\t\t\t\tendMonth={lastMonth}\r\n\t\t\t\t\t\t\tmonth={windowMonth}\r\n\t\t\t\t\t\t\tnumberOfMonths={windowSize}\r\n\t\t\t\t\t\t\tcaptionLayout=\"label\"\r\n\t\t\t\t\t\t\tfixedWeeks\r\n\t\t\t\t\t\t\thideNavigation\r\n\t\t\t\t\t\t\tshowOutsideDays={false}\r\n\t\t\t\t\t\t\tclassNames={classNamesMemoized}\r\n\t\t\t\t\t\t\tcomponents={componentsMemoized}\r\n\t\t\t\t\t\t/>\r\n\t\t\t\t\t</div>\r\n\t\t\t\t</div>\r\n\t\t\t</div>\r\n\t\t</div>\r\n\t);\r\n};\r\n\r\nCalendarScroll.displayName = \"CalendarScroll\";\r\n"],"names":["MONTH_HEIGHT","DEFAULT_WINDOW_SIZE","BUFFER_BEFORE","DEFAULT_YEARS_BACK","DEFAULT_END_YEAR","calendarScrollStyles","tv","toKey","date","fromKey","key","clamp","value","min","max","CalendarScrollDayButton","modifiers","props","anchorRef","useRef","isFirstRun","useEffect","isMount","button","scroller","jsx","CalendarDayButton","CalendarScrollMonths","children","Months","Children","child","isValidElement","cloneElement","CalendarScroll","className","classNames","locale","enUS","weekStartsOn","startMonth","endMonth","defaultMonth","components","styles","scrollerRef","frameRef","startKey","endKey","total","windowSizeLimit","setWindowSizeLimit","useState","windowSize","getWindowStart","useCallback","index","initialIndex","currentIndex","setCurrentIndex","windowStart","setWindowStart","useLayoutEffect","visibleMonths","syncWithScroll","scrollTop","onScroll","jumpTo","jumpBy","delta","current","previous","next","isFirst","isLast","onMonthSelect","event","onYearSelect","dateFnsLocale","labels","monthOptions","useMemo","_","month","format","weekdayNames","first","startOfWeek","day","addDays","yearOptions","last","i","classNamesMemoized","componentsMemoized","firstMonth","lastMonth","windowMonth","jsxs","CalendarPreviousMonthButton","labelPrevious","CalendarChevron","CalendarDropdown","labelMonthDropdown","labelYearDropdown","CalendarNextMonthButton","labelNext","name","DayPicker"],"mappings":"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"}
|