@artemy-tech/datepicker 0.1.0 → 0.3.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.js CHANGED
@@ -1,456 +1,37 @@
1
- // src/components/Calendar/Calendar.tsx
2
- import { DayPicker } from "react-day-picker";
3
- import { jsx } from "react/jsx-runtime";
4
- function Calendar({ className, ...props }) {
5
- return /* @__PURE__ */ jsx(
6
- DayPicker,
7
- {
8
- className: ["datepicker-calendar", className].filter(Boolean).join(" "),
9
- ...props
10
- }
11
- );
12
- }
13
-
14
- // src/components/DatePicker/DatePicker.tsx
15
- import { useCallback, useRef, useState } from "react";
16
- import { format, isValid, parse } from "date-fns";
17
- import { ru } from "date-fns/locale";
18
-
19
- // src/hooks/useClickOutside.ts
20
- import { useEffect } from "react";
21
- function useClickOutside(ref, handler) {
22
- useEffect(() => {
23
- function listener(e) {
24
- if (!ref.current || ref.current.contains(e.target)) return;
25
- handler();
26
- }
27
- document.addEventListener("mousedown", listener);
28
- return () => document.removeEventListener("mousedown", listener);
29
- }, [ref, handler]);
30
- }
31
-
32
- // src/components/DatePicker/DatePicker.tsx
33
- import { jsx as jsx2, jsxs } from "react/jsx-runtime";
34
- var DATE_FORMAT = "dd.MM.yyyy";
35
- function applyMask(digits) {
36
- const d = digits.slice(0, 8);
37
- let result = "";
38
- for (let i = 0; i < d.length; i++) {
39
- if (i === 2 || i === 4) result += ".";
40
- result += d[i];
41
- }
42
- return result;
43
- }
44
- function getCursorPos(masked, digitCount) {
45
- if (digitCount === 0) return 0;
46
- let count = 0;
47
- for (let i = 0; i < masked.length; i++) {
48
- if (/\d/.test(masked[i])) {
49
- count++;
50
- if (count === digitCount) return i + 1;
51
- }
52
- }
53
- return masked.length;
54
- }
55
- function parseDate(masked) {
56
- if (masked.replace(/\D/g, "").length !== 8) return void 0;
57
- const date = parse(masked, DATE_FORMAT, /* @__PURE__ */ new Date());
58
- return isValid(date) && format(date, DATE_FORMAT) === masked ? date : void 0;
59
- }
60
- function DatePicker({
61
- value,
62
- defaultValue,
63
- onChange,
64
- label,
65
- placeholder = "\u0434\u0434.\u043C\u043C.\u0433\u0433\u0433\u0433",
66
- fromDate,
67
- toDate,
68
- disabled = false,
69
- failed = false,
70
- className
71
- }) {
72
- const isControlled = value !== void 0;
73
- const [internalDate, setInternalDate] = useState(defaultValue);
74
- const [open, setOpen] = useState(false);
75
- const [focused, setFocused] = useState(false);
76
- const [inputValue, setInputValue] = useState(
77
- () => defaultValue && isValid(defaultValue) ? format(defaultValue, DATE_FORMAT) : ""
78
- );
79
- const [inputInvalid, setInputInvalid] = useState(false);
80
- const inputRef = useRef(null);
81
- const containerRef = useRef(null);
82
- const selected = isControlled ? value : internalDate;
83
- const filled = inputValue.length > 0;
84
- const close = useCallback(() => setOpen(false), []);
85
- useClickOutside(containerRef, close);
86
- function commit(masked) {
87
- const digits = masked.replace(/\D/g, "");
88
- if (digits.length === 0) {
89
- setInputInvalid(false);
90
- if (!isControlled) setInternalDate(void 0);
91
- onChange == null ? void 0 : onChange(void 0);
92
- } else if (digits.length === 8) {
93
- const date = parseDate(masked);
94
- setInputInvalid(!date);
95
- if (!isControlled) setInternalDate(date);
96
- onChange == null ? void 0 : onChange(date);
97
- } else {
98
- setInputInvalid(false);
99
- }
100
- }
101
- function handleChange(e) {
102
- var _a;
103
- const input = e.target;
104
- const cursorPos = (_a = input.selectionStart) != null ? _a : 0;
105
- const raw = input.value;
106
- const digits = raw.replace(/\D/g, "").slice(0, 8);
107
- const masked = applyMask(digits);
108
- const digitsBeforeCursor = raw.slice(0, cursorPos).replace(/\D/g, "").length;
109
- const newCursorPos = getCursorPos(masked, digitsBeforeCursor);
110
- setInputValue(masked);
111
- commit(masked);
112
- requestAnimationFrame(() => {
113
- var _a2;
114
- return (_a2 = inputRef.current) == null ? void 0 : _a2.setSelectionRange(newCursorPos, newCursorPos);
115
- });
116
- }
117
- function handleKeyDown(e) {
118
- var _a;
119
- const input = e.currentTarget;
120
- const pos = (_a = input.selectionStart) != null ? _a : 0;
121
- if (e.key.length === 1 && !/\d/.test(e.key) && !e.ctrlKey && !e.metaKey) {
122
- e.preventDefault();
123
- return;
124
- }
125
- if (e.key === "Backspace" && pos > 0 && input.value[pos - 1] === ".") {
126
- e.preventDefault();
127
- const val = input.value;
128
- const masked = applyMask((val.slice(0, pos - 2) + val.slice(pos)).replace(/\D/g, ""));
129
- setInputValue(masked);
130
- commit(masked);
131
- requestAnimationFrame(() => input.setSelectionRange(pos - 2, pos - 2));
132
- }
133
- }
134
- function handlePaste(e) {
135
- e.preventDefault();
136
- const masked = applyMask(e.clipboardData.getData("text").replace(/\D/g, ""));
137
- setInputValue(masked);
138
- commit(masked);
139
- requestAnimationFrame(() => {
140
- var _a;
141
- return (_a = inputRef.current) == null ? void 0 : _a.setSelectionRange(masked.length, masked.length);
142
- });
143
- }
144
- function handleSelect(date) {
145
- if (!isControlled) setInternalDate(date);
146
- setInputValue(date && isValid(date) ? format(date, DATE_FORMAT) : "");
147
- setInputInvalid(false);
148
- onChange == null ? void 0 : onChange(date);
149
- setOpen(false);
150
- }
151
- return /* @__PURE__ */ jsxs(
152
- "div",
153
- {
154
- ref: containerRef,
155
- className: ["datepicker", className].filter(Boolean).join(" "),
156
- "data-focused": focused || open || void 0,
157
- "data-filled": filled || void 0,
158
- "data-failed": failed || inputInvalid || void 0,
159
- "data-disabled": disabled || void 0,
160
- children: [
161
- /* @__PURE__ */ jsxs("div", { className: "datepicker__field", onClick: () => {
162
- var _a;
163
- return !disabled && ((_a = inputRef.current) == null ? void 0 : _a.focus());
164
- }, children: [
165
- label && /* @__PURE__ */ jsx2("span", { className: "datepicker__label", children: label }),
166
- /* @__PURE__ */ jsx2(
167
- "input",
168
- {
169
- ref: inputRef,
170
- type: "text",
171
- inputMode: "numeric",
172
- className: "datepicker__input",
173
- value: inputValue,
174
- placeholder: label && !focused ? void 0 : placeholder,
175
- disabled,
176
- onChange: handleChange,
177
- onKeyDown: handleKeyDown,
178
- onPaste: handlePaste,
179
- onFocus: () => {
180
- setFocused(true);
181
- if (!disabled) setOpen(true);
182
- },
183
- onBlur: () => setFocused(false),
184
- "aria-label": label != null ? label : "\u0412\u044B\u0431\u0435\u0440\u0438\u0442\u0435 \u0434\u0430\u0442\u0443",
185
- "aria-expanded": open,
186
- "aria-haspopup": "dialog",
187
- "aria-invalid": inputInvalid || void 0
188
- }
189
- )
190
- ] }),
191
- open && /* @__PURE__ */ jsx2("div", { className: "datepicker__popover", role: "dialog", "aria-label": "\u041A\u0430\u043B\u0435\u043D\u0434\u0430\u0440\u044C", children: /* @__PURE__ */ jsx2(
192
- Calendar,
193
- {
194
- mode: "single",
195
- selected,
196
- onSelect: handleSelect,
197
- startMonth: fromDate,
198
- endMonth: toDate,
199
- locale: ru
200
- }
201
- ) })
202
- ]
203
- }
204
- );
205
- }
1
+ import {
2
+ Calendar,
3
+ DatePicker,
4
+ DateRangePicker,
5
+ Spinner
6
+ } from "./chunk-DQSX6QKR.js";
206
7
 
207
- // src/components/DateRangePicker/DateRangePicker.tsx
208
- import { useCallback as useCallback2, useRef as useRef2, useState as useState2 } from "react";
209
- import { format as format2, isValid as isValid2, parse as parse2 } from "date-fns";
210
- import { ru as ru2 } from "date-fns/locale";
211
- import { jsx as jsx3, jsxs as jsxs2 } from "react/jsx-runtime";
212
- var DATE_FORMAT2 = "dd.MM.yyyy";
213
- function applyDateMask(digits) {
214
- const d = digits.slice(0, 8);
215
- let result = "";
216
- for (let i = 0; i < d.length; i++) {
217
- if (i === 2 || i === 4) result += ".";
218
- result += d[i];
219
- }
220
- return result;
221
- }
222
- function applyRangeMask(digits) {
223
- const all = digits.slice(0, 16);
224
- const fromMasked = applyDateMask(all.slice(0, 8));
225
- const toDigits = all.slice(8);
226
- if (toDigits.length === 0) return fromMasked;
227
- return `${fromMasked} \u2014 ${applyDateMask(toDigits)}`;
228
- }
229
- function getRangeCursorPos(masked, digitCount) {
230
- if (digitCount === 0) return 0;
231
- let count = 0;
232
- for (let i = 0; i < masked.length; i++) {
233
- if (/\d/.test(masked[i])) {
234
- count++;
235
- if (count === digitCount) return i + 1;
236
- }
237
- }
238
- return masked.length;
239
- }
240
- function parseDate2(masked) {
241
- if (masked.replace(/\D/g, "").length !== 8) return void 0;
242
- const date = parse2(masked, DATE_FORMAT2, /* @__PURE__ */ new Date());
243
- return isValid2(date) && format2(date, DATE_FORMAT2) === masked ? date : void 0;
244
- }
245
- function formatRange(from, to) {
246
- if (!from) return "";
247
- const fromStr = format2(from, DATE_FORMAT2);
248
- if (!to) return fromStr;
249
- return `${fromStr} \u2014 ${format2(to, DATE_FORMAT2)}`;
250
- }
251
- function DateRangePicker({
252
- value,
253
- defaultValue,
254
- onChange,
255
- label,
256
- fromDate: fromConstraint,
257
- toDate: toConstraint,
258
- disabled = false,
259
- failed = false,
260
- className
8
+ // src/components/Button/Button.tsx
9
+ import { jsx, jsxs } from "react/jsx-runtime";
10
+ function Button({
11
+ variant = "primary",
12
+ size = "m",
13
+ loading = false,
14
+ disabled,
15
+ className,
16
+ children,
17
+ ...rest
261
18
  }) {
262
- const isControlled = value !== void 0;
263
- const [internalFrom, setInternalFrom] = useState2(defaultValue == null ? void 0 : defaultValue.from);
264
- const [internalTo, setInternalTo] = useState2(defaultValue == null ? void 0 : defaultValue.to);
265
- const [inputValue, setInputValue] = useState2(
266
- () => formatRange(defaultValue == null ? void 0 : defaultValue.from, defaultValue == null ? void 0 : defaultValue.to)
267
- );
268
- const [inputInvalid, setInputInvalid] = useState2(false);
269
- const [open, setOpen] = useState2(false);
270
- const [focused, setFocused] = useState2(false);
271
- const [anchorDate, setAnchorDate] = useState2(void 0);
272
- const [hoveredDate, setHoveredDate] = useState2(void 0);
273
- const inputRef = useRef2(null);
274
- const containerRef = useRef2(null);
275
- const confirmedFrom = isControlled ? value == null ? void 0 : value.from : internalFrom;
276
- const confirmedTo = isControlled ? value == null ? void 0 : value.to : internalTo;
277
- const filled = inputValue.length > 0;
278
- const close = useCallback2(() => {
279
- setOpen(false);
280
- setAnchorDate(void 0);
281
- setHoveredDate(void 0);
282
- }, []);
283
- useClickOutside(containerRef, close);
284
- const calendarSelected = anchorDate ? hoveredDate ? anchorDate <= hoveredDate ? { from: anchorDate, to: hoveredDate } : { from: hoveredDate, to: anchorDate } : { from: anchorDate, to: void 0 } : { from: confirmedFrom, to: confirmedTo };
285
- function handleDayClick(day) {
286
- if (!anchorDate) {
287
- setAnchorDate(day);
288
- if (!isControlled) {
289
- setInternalFrom(day);
290
- setInternalTo(void 0);
291
- }
292
- setInputValue(format2(day, DATE_FORMAT2));
293
- setInputInvalid(false);
294
- onChange == null ? void 0 : onChange(day ? { from: day, to: void 0 } : void 0);
295
- } else {
296
- let from = anchorDate, to = day;
297
- if (day < anchorDate) {
298
- from = day;
299
- to = anchorDate;
300
- }
301
- if (!isControlled) {
302
- setInternalFrom(from);
303
- setInternalTo(to);
304
- }
305
- setInputValue(formatRange(from, to));
306
- setInputInvalid(false);
307
- onChange == null ? void 0 : onChange({ from, to });
308
- close();
309
- }
310
- }
311
- function handleDayMouseEnter(day) {
312
- if (anchorDate) setHoveredDate(day);
313
- }
314
- function handleChange(e) {
315
- var _a;
316
- const input = e.target;
317
- const cursorPos = (_a = input.selectionStart) != null ? _a : 0;
318
- const raw = input.value;
319
- const digits = raw.replace(/\D/g, "").slice(0, 16);
320
- const masked = applyRangeMask(digits);
321
- const digitsBeforeCursor = raw.slice(0, cursorPos).replace(/\D/g, "").length;
322
- setInputValue(masked);
323
- setAnchorDate(void 0);
324
- setHoveredDate(void 0);
325
- const fromDigits = digits.slice(0, 8);
326
- const toDigits = digits.slice(8);
327
- const parsedFrom = fromDigits.length === 8 ? parseDate2(applyDateMask(fromDigits)) : void 0;
328
- const parsedTo = toDigits.length === 8 ? parseDate2(applyDateMask(toDigits)) : void 0;
329
- const fromComplete = fromDigits.length === 8;
330
- const toComplete = toDigits.length === 8;
331
- setInputInvalid(fromComplete && !parsedFrom || toComplete && !parsedTo);
332
- if (!isControlled) {
333
- setInternalFrom(parsedFrom);
334
- setInternalTo(parsedTo);
335
- }
336
- onChange == null ? void 0 : onChange(parsedFrom || parsedTo ? { from: parsedFrom, to: parsedTo } : void 0);
337
- requestAnimationFrame(
338
- () => {
339
- var _a2;
340
- return (_a2 = inputRef.current) == null ? void 0 : _a2.setSelectionRange(
341
- getRangeCursorPos(masked, digitsBeforeCursor),
342
- getRangeCursorPos(masked, digitsBeforeCursor)
343
- );
344
- }
345
- );
346
- }
347
- function handleKeyDown(e) {
348
- var _a, _b, _c;
349
- const input = e.currentTarget;
350
- const pos = (_a = input.selectionStart) != null ? _a : 0;
351
- if (e.key.length === 1 && !/\d/.test(e.key) && !e.ctrlKey && !e.metaKey) {
352
- e.preventDefault();
353
- return;
354
- }
355
- if (e.key === "Backspace" && pos > 0 && /[\s—]/.test(input.value[pos - 1])) {
356
- e.preventDefault();
357
- const val = input.value;
358
- const charsToSkip = (_c = (_b = val.slice(0, pos).match(/[\s—]+$/)) == null ? void 0 : _b[0].length) != null ? _c : 1;
359
- const newPos = pos - charsToSkip;
360
- const masked = applyRangeMask((val.slice(0, newPos - 1) + val.slice(newPos)).replace(/\D/g, ""));
361
- setInputValue(masked);
362
- requestAnimationFrame(() => input.setSelectionRange(newPos - 1, newPos - 1));
363
- }
364
- }
365
- function handlePaste(e) {
366
- e.preventDefault();
367
- const text = e.clipboardData.getData("text");
368
- const digits = text.replace(/\D/g, "").slice(0, 16);
369
- const masked = applyRangeMask(digits);
370
- setInputValue(masked);
371
- setAnchorDate(void 0);
372
- setHoveredDate(void 0);
373
- const parsedFrom = digits.length >= 8 ? parseDate2(applyDateMask(digits.slice(0, 8))) : void 0;
374
- const parsedTo = digits.length >= 16 ? parseDate2(applyDateMask(digits.slice(8, 16))) : void 0;
375
- setInputInvalid(digits.length >= 8 && !parsedFrom || digits.length >= 16 && !parsedTo);
376
- if (!isControlled) {
377
- setInternalFrom(parsedFrom);
378
- setInternalTo(parsedTo);
379
- }
380
- onChange == null ? void 0 : onChange(parsedFrom || parsedTo ? { from: parsedFrom, to: parsedTo } : void 0);
381
- requestAnimationFrame(() => {
382
- var _a;
383
- return (_a = inputRef.current) == null ? void 0 : _a.setSelectionRange(masked.length, masked.length);
384
- });
385
- }
386
- const placeholder = label && !focused && !filled ? void 0 : "\u0434\u0434.\u043C\u043C.\u0433\u0433\u0433\u0433 \u2014 \u0434\u0434.\u043C\u043C.\u0433\u0433\u0433\u0433";
387
- return /* @__PURE__ */ jsxs2(
388
- "div",
389
- {
390
- ref: containerRef,
391
- className: ["datepicker", "daterangepicker", className].filter(Boolean).join(" "),
392
- "data-focused": focused || open || void 0,
393
- "data-filled": filled || void 0,
394
- "data-failed": failed || inputInvalid || void 0,
395
- "data-disabled": disabled || void 0,
396
- children: [
397
- /* @__PURE__ */ jsxs2("div", { className: "datepicker__field", onClick: () => {
398
- var _a;
399
- return !disabled && ((_a = inputRef.current) == null ? void 0 : _a.focus());
400
- }, children: [
401
- label && /* @__PURE__ */ jsx3("span", { className: "datepicker__label", children: label }),
402
- /* @__PURE__ */ jsx3(
403
- "input",
404
- {
405
- ref: inputRef,
406
- type: "text",
407
- inputMode: "numeric",
408
- className: "datepicker__input",
409
- value: inputValue,
410
- placeholder,
411
- disabled,
412
- onChange: handleChange,
413
- onKeyDown: handleKeyDown,
414
- onPaste: handlePaste,
415
- onFocus: () => {
416
- setFocused(true);
417
- if (!disabled) setOpen(true);
418
- },
419
- onBlur: () => setFocused(false),
420
- "aria-label": label != null ? label : "\u0412\u044B\u0431\u0435\u0440\u0438\u0442\u0435 \u043F\u0435\u0440\u0438\u043E\u0434",
421
- "aria-expanded": open,
422
- "aria-haspopup": "dialog",
423
- "aria-invalid": inputInvalid || void 0
424
- }
425
- )
426
- ] }),
427
- open && /* @__PURE__ */ jsx3("div", { className: "datepicker__popover", role: "dialog", "aria-label": "\u0412\u044B\u0431\u0435\u0440\u0438\u0442\u0435 \u043F\u0435\u0440\u0438\u043E\u0434", children: /* @__PURE__ */ jsx3(
428
- Calendar,
429
- {
430
- mode: "range",
431
- selected: calendarSelected,
432
- onSelect: () => {
433
- },
434
- onDayClick: handleDayClick,
435
- onDayMouseEnter: handleDayMouseEnter,
436
- onDayMouseLeave: () => setHoveredDate(void 0),
437
- startMonth: fromConstraint,
438
- endMonth: toConstraint,
439
- numberOfMonths: 2,
440
- locale: ru2
441
- }
442
- ) })
443
- ]
444
- }
445
- );
19
+ const classes = [
20
+ "dp-btn",
21
+ `dp-btn--${variant}`,
22
+ `dp-btn--${size}`,
23
+ loading && "dp-btn--loading",
24
+ className
25
+ ].filter(Boolean).join(" ");
26
+ return /* @__PURE__ */ jsxs("button", { ...rest, className: classes, disabled: disabled || loading, children: [
27
+ children,
28
+ loading && /* @__PURE__ */ jsx(Spinner, {})
29
+ ] });
446
30
  }
447
-
448
- // src/index.ts
449
- var VERSION = "0.0.1";
450
31
  export {
32
+ Button,
451
33
  Calendar,
452
34
  DatePicker,
453
- DateRangePicker,
454
- VERSION
35
+ DateRangePicker
455
36
  };
456
37
  //# sourceMappingURL=index.js.map
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/components/Calendar/Calendar.tsx","../src/components/DatePicker/DatePicker.tsx","../src/hooks/useClickOutside.ts","../src/components/DateRangePicker/DateRangePicker.tsx","../src/index.ts"],"sourcesContent":["import { DayPicker, DayPickerProps } from 'react-day-picker'\n\nexport type CalendarProps = DayPickerProps & {\n className?: string\n}\n\nexport function Calendar({ className, ...props }: CalendarProps) {\n return (\n <DayPicker\n className={['datepicker-calendar', className].filter(Boolean).join(' ')}\n {...props}\n />\n )\n}\n","import { useCallback, useRef, useState } from 'react'\nimport { format, isValid, parse } from 'date-fns'\nimport { ru } from 'date-fns/locale'\nimport { useClickOutside } from '../../hooks/useClickOutside'\nimport { Calendar } from '../Calendar'\n\nconst DATE_FORMAT = 'dd.MM.yyyy'\n\nfunction applyMask(digits: string): string {\n const d = digits.slice(0, 8)\n let result = ''\n for (let i = 0; i < d.length; i++) {\n if (i === 2 || i === 4) result += '.'\n result += d[i]\n }\n return result\n}\n\nfunction getCursorPos(masked: string, digitCount: number): number {\n if (digitCount === 0) return 0\n let count = 0\n for (let i = 0; i < masked.length; i++) {\n if (/\\d/.test(masked[i])) {\n count++\n if (count === digitCount) return i + 1\n }\n }\n return masked.length\n}\n\nfunction parseDate(masked: string): Date | undefined {\n if (masked.replace(/\\D/g, '').length !== 8) return undefined\n const date = parse(masked, DATE_FORMAT, new Date())\n // round-trip check prevents day-overflow (e.g. 32.01 → Jan 32 → Feb 1)\n return isValid(date) && format(date, DATE_FORMAT) === masked ? date : undefined\n}\n\nexport interface DatePickerProps {\n value?: Date\n defaultValue?: Date\n onChange?: (date: Date | undefined) => void\n label?: string\n placeholder?: string\n fromDate?: Date\n toDate?: Date\n disabled?: boolean\n failed?: boolean\n className?: string\n}\n\nexport function DatePicker({\n value,\n defaultValue,\n onChange,\n label,\n placeholder = 'дд.мм.гггг',\n fromDate,\n toDate,\n disabled = false,\n failed = false,\n className,\n}: DatePickerProps) {\n const isControlled = value !== undefined\n const [internalDate, setInternalDate] = useState<Date | undefined>(defaultValue)\n const [open, setOpen] = useState(false)\n const [focused, setFocused] = useState(false)\n const [inputValue, setInputValue] = useState(() =>\n defaultValue && isValid(defaultValue) ? format(defaultValue, DATE_FORMAT) : '',\n )\n const [inputInvalid, setInputInvalid] = useState(false)\n\n const inputRef = useRef<HTMLInputElement>(null)\n const containerRef = useRef<HTMLDivElement>(null)\n const selected = isControlled ? value : internalDate\n const filled = inputValue.length > 0\n\n const close = useCallback(() => setOpen(false), [])\n useClickOutside(containerRef, close)\n\n function commit(masked: string) {\n const digits = masked.replace(/\\D/g, '')\n if (digits.length === 0) {\n setInputInvalid(false)\n if (!isControlled) setInternalDate(undefined)\n onChange?.(undefined)\n } else if (digits.length === 8) {\n const date = parseDate(masked)\n setInputInvalid(!date)\n if (!isControlled) setInternalDate(date)\n onChange?.(date)\n } else {\n setInputInvalid(false)\n }\n }\n\n function handleChange(e: React.ChangeEvent<HTMLInputElement>) {\n const input = e.target\n const cursorPos = input.selectionStart ?? 0\n const raw = input.value\n const digits = raw.replace(/\\D/g, '').slice(0, 8)\n const masked = applyMask(digits)\n const digitsBeforeCursor = raw.slice(0, cursorPos).replace(/\\D/g, '').length\n const newCursorPos = getCursorPos(masked, digitsBeforeCursor)\n setInputValue(masked)\n commit(masked)\n requestAnimationFrame(() => inputRef.current?.setSelectionRange(newCursorPos, newCursorPos))\n }\n\n function handleKeyDown(e: React.KeyboardEvent<HTMLInputElement>) {\n const input = e.currentTarget\n const pos = input.selectionStart ?? 0\n\n if (e.key.length === 1 && !/\\d/.test(e.key) && !e.ctrlKey && !e.metaKey) {\n e.preventDefault()\n return\n }\n\n if (e.key === 'Backspace' && pos > 0 && input.value[pos - 1] === '.') {\n e.preventDefault()\n const val = input.value\n const masked = applyMask((val.slice(0, pos - 2) + val.slice(pos)).replace(/\\D/g, ''))\n setInputValue(masked)\n commit(masked)\n requestAnimationFrame(() => input.setSelectionRange(pos - 2, pos - 2))\n }\n }\n\n function handlePaste(e: React.ClipboardEvent<HTMLInputElement>) {\n e.preventDefault()\n const masked = applyMask(e.clipboardData.getData('text').replace(/\\D/g, ''))\n setInputValue(masked)\n commit(masked)\n requestAnimationFrame(() => inputRef.current?.setSelectionRange(masked.length, masked.length))\n }\n\n function handleSelect(date: Date | undefined) {\n if (!isControlled) setInternalDate(date)\n setInputValue(date && isValid(date) ? format(date, DATE_FORMAT) : '')\n setInputInvalid(false)\n onChange?.(date)\n setOpen(false)\n }\n\n return (\n <div\n ref={containerRef}\n className={['datepicker', className].filter(Boolean).join(' ')}\n data-focused={focused || open || undefined}\n data-filled={filled || undefined}\n data-failed={failed || inputInvalid || undefined}\n data-disabled={disabled || undefined}\n >\n <div className=\"datepicker__field\" onClick={() => !disabled && inputRef.current?.focus()}>\n {label && <span className=\"datepicker__label\">{label}</span>}\n <input\n ref={inputRef}\n type=\"text\"\n inputMode=\"numeric\"\n className=\"datepicker__input\"\n value={inputValue}\n placeholder={label && !focused ? undefined : placeholder}\n disabled={disabled}\n onChange={handleChange}\n onKeyDown={handleKeyDown}\n onPaste={handlePaste}\n onFocus={() => { setFocused(true); if (!disabled) setOpen(true) }}\n onBlur={() => setFocused(false)}\n aria-label={label ?? 'Выберите дату'}\n aria-expanded={open}\n aria-haspopup=\"dialog\"\n aria-invalid={inputInvalid || undefined}\n />\n </div>\n {open && (\n <div className=\"datepicker__popover\" role=\"dialog\" aria-label=\"Календарь\">\n <Calendar\n mode=\"single\"\n selected={selected}\n onSelect={handleSelect}\n startMonth={fromDate}\n endMonth={toDate}\n locale={ru}\n />\n </div>\n )}\n </div>\n )\n}\n","import { RefObject, useEffect } from 'react'\n\nexport function useClickOutside(ref: RefObject<HTMLElement | null>, handler: () => void) {\n useEffect(() => {\n function listener(e: MouseEvent) {\n if (!ref.current || ref.current.contains(e.target as Node)) return\n handler()\n }\n document.addEventListener('mousedown', listener)\n return () => document.removeEventListener('mousedown', listener)\n }, [ref, handler])\n}\n","import { useCallback, useRef, useState } from 'react'\nimport { format, isValid, parse } from 'date-fns'\nimport { ru } from 'date-fns/locale'\nimport type { DateRange } from 'react-day-picker'\nimport { useClickOutside } from '../../hooks/useClickOutside'\nimport { Calendar } from '../Calendar'\n\nconst DATE_FORMAT = 'dd.MM.yyyy'\n\nfunction applyDateMask(digits: string): string {\n const d = digits.slice(0, 8)\n let result = ''\n for (let i = 0; i < d.length; i++) {\n if (i === 2 || i === 4) result += '.'\n result += d[i]\n }\n return result\n}\n\nfunction applyRangeMask(digits: string): string {\n const all = digits.slice(0, 16)\n const fromMasked = applyDateMask(all.slice(0, 8))\n const toDigits = all.slice(8)\n if (toDigits.length === 0) return fromMasked\n return `${fromMasked} — ${applyDateMask(toDigits)}`\n}\n\nfunction getRangeCursorPos(masked: string, digitCount: number): number {\n if (digitCount === 0) return 0\n let count = 0\n for (let i = 0; i < masked.length; i++) {\n if (/\\d/.test(masked[i])) {\n count++\n if (count === digitCount) return i + 1\n }\n }\n return masked.length\n}\n\nfunction parseDate(masked: string): Date | undefined {\n if (masked.replace(/\\D/g, '').length !== 8) return undefined\n const date = parse(masked, DATE_FORMAT, new Date())\n return isValid(date) && format(date, DATE_FORMAT) === masked ? date : undefined\n}\n\nfunction formatRange(from: Date | undefined, to: Date | undefined): string {\n if (!from) return ''\n const fromStr = format(from, DATE_FORMAT)\n if (!to) return fromStr\n return `${fromStr} — ${format(to, DATE_FORMAT)}`\n}\n\nexport type { DateRange }\n\nexport interface DateRangePickerProps {\n value?: DateRange\n defaultValue?: DateRange\n onChange?: (range: DateRange | undefined) => void\n label?: string\n fromDate?: Date\n toDate?: Date\n disabled?: boolean\n failed?: boolean\n className?: string\n}\n\nexport function DateRangePicker({\n value,\n defaultValue,\n onChange,\n label,\n fromDate: fromConstraint,\n toDate: toConstraint,\n disabled = false,\n failed = false,\n className,\n}: DateRangePickerProps) {\n const isControlled = value !== undefined\n\n const [internalFrom, setInternalFrom] = useState<Date | undefined>(defaultValue?.from)\n const [internalTo, setInternalTo] = useState<Date | undefined>(defaultValue?.to)\n const [inputValue, setInputValue] = useState(() =>\n formatRange(defaultValue?.from, defaultValue?.to),\n )\n const [inputInvalid, setInputInvalid] = useState(false)\n const [open, setOpen] = useState(false)\n const [focused, setFocused] = useState(false)\n\n // Calendar picking state — managed separately from confirmed dates\n const [anchorDate, setAnchorDate] = useState<Date | undefined>(undefined)\n const [hoveredDate, setHoveredDate] = useState<Date | undefined>(undefined)\n\n const inputRef = useRef<HTMLInputElement>(null)\n const containerRef = useRef<HTMLDivElement>(null)\n\n const confirmedFrom = isControlled ? value?.from : internalFrom\n const confirmedTo = isControlled ? value?.to : internalTo\n const filled = inputValue.length > 0\n\n const close = useCallback(() => {\n setOpen(false)\n setAnchorDate(undefined)\n setHoveredDate(undefined)\n }, [])\n useClickOutside(containerRef, close)\n\n // Visual range shown in calendar\n const calendarSelected: DateRange | undefined = anchorDate\n ? hoveredDate\n ? anchorDate <= hoveredDate\n ? { from: anchorDate, to: hoveredDate }\n : { from: hoveredDate, to: anchorDate }\n : { from: anchorDate, to: undefined }\n : { from: confirmedFrom, to: confirmedTo }\n\n // ── Calendar handlers ─────────────────────────────────────────\n\n // All selection logic lives here. onSelect is a no-op so calendar display is fully controlled.\n function handleDayClick(day: Date) {\n if (!anchorDate) {\n // Phase 1: pick the \"from\" anchor\n setAnchorDate(day)\n if (!isControlled) { setInternalFrom(day); setInternalTo(undefined) }\n setInputValue(format(day, DATE_FORMAT))\n setInputInvalid(false)\n onChange?.(day ? { from: day, to: undefined } : undefined)\n } else {\n // Phase 2: pick \"to\" and close\n let from = anchorDate, to = day\n if (day < anchorDate) { from = day; to = anchorDate }\n if (!isControlled) { setInternalFrom(from); setInternalTo(to) }\n setInputValue(formatRange(from, to))\n setInputInvalid(false)\n onChange?.({ from, to })\n close()\n }\n }\n\n function handleDayMouseEnter(day: Date) {\n if (anchorDate) setHoveredDate(day)\n }\n\n // ── Text input handlers ───────────────────────────────────────\n\n function handleChange(e: React.ChangeEvent<HTMLInputElement>) {\n const input = e.target\n const cursorPos = input.selectionStart ?? 0\n const raw = input.value\n const digits = raw.replace(/\\D/g, '').slice(0, 16)\n const masked = applyRangeMask(digits)\n const digitsBeforeCursor = raw.slice(0, cursorPos).replace(/\\D/g, '').length\n\n setInputValue(masked)\n setAnchorDate(undefined)\n setHoveredDate(undefined)\n\n const fromDigits = digits.slice(0, 8)\n const toDigits = digits.slice(8)\n const parsedFrom = fromDigits.length === 8 ? parseDate(applyDateMask(fromDigits)) : undefined\n const parsedTo = toDigits.length === 8 ? parseDate(applyDateMask(toDigits)) : undefined\n const fromComplete = fromDigits.length === 8\n const toComplete = toDigits.length === 8\n setInputInvalid((fromComplete && !parsedFrom) || (toComplete && !parsedTo))\n\n if (!isControlled) { setInternalFrom(parsedFrom); setInternalTo(parsedTo) }\n onChange?.(parsedFrom || parsedTo ? { from: parsedFrom, to: parsedTo } : undefined)\n\n requestAnimationFrame(() =>\n inputRef.current?.setSelectionRange(\n getRangeCursorPos(masked, digitsBeforeCursor),\n getRangeCursorPos(masked, digitsBeforeCursor),\n ),\n )\n }\n\n function handleKeyDown(e: React.KeyboardEvent<HTMLInputElement>) {\n const input = e.currentTarget\n const pos = input.selectionStart ?? 0\n\n if (e.key.length === 1 && !/\\d/.test(e.key) && !e.ctrlKey && !e.metaKey) {\n e.preventDefault()\n return\n }\n if (e.key === 'Backspace' && pos > 0 && /[\\s—]/.test(input.value[pos - 1])) {\n // skip over separator characters\n e.preventDefault()\n const val = input.value\n const charsToSkip = val.slice(0, pos).match(/[\\s—]+$/)?.[0].length ?? 1\n const newPos = pos - charsToSkip\n const masked = applyRangeMask((val.slice(0, newPos - 1) + val.slice(newPos)).replace(/\\D/g, ''))\n setInputValue(masked)\n requestAnimationFrame(() => input.setSelectionRange(newPos - 1, newPos - 1))\n }\n }\n\n function handlePaste(e: React.ClipboardEvent<HTMLInputElement>) {\n e.preventDefault()\n const text = e.clipboardData.getData('text')\n const digits = text.replace(/\\D/g, '').slice(0, 16)\n const masked = applyRangeMask(digits)\n setInputValue(masked)\n setAnchorDate(undefined)\n setHoveredDate(undefined)\n\n const parsedFrom = digits.length >= 8 ? parseDate(applyDateMask(digits.slice(0, 8))) : undefined\n const parsedTo = digits.length >= 16 ? parseDate(applyDateMask(digits.slice(8, 16))) : undefined\n setInputInvalid((digits.length >= 8 && !parsedFrom) || (digits.length >= 16 && !parsedTo))\n if (!isControlled) { setInternalFrom(parsedFrom); setInternalTo(parsedTo) }\n onChange?.(parsedFrom || parsedTo ? { from: parsedFrom, to: parsedTo } : undefined)\n\n requestAnimationFrame(() => inputRef.current?.setSelectionRange(masked.length, masked.length))\n }\n\n const placeholder = label && !focused && !filled ? undefined : 'дд.мм.гггг — дд.мм.гггг'\n\n return (\n <div\n ref={containerRef}\n className={['datepicker', 'daterangepicker', className].filter(Boolean).join(' ')}\n data-focused={focused || open || undefined}\n data-filled={filled || undefined}\n data-failed={failed || inputInvalid || undefined}\n data-disabled={disabled || undefined}\n >\n <div className=\"datepicker__field\" onClick={() => !disabled && inputRef.current?.focus()}>\n {label && <span className=\"datepicker__label\">{label}</span>}\n <input\n ref={inputRef}\n type=\"text\"\n inputMode=\"numeric\"\n className=\"datepicker__input\"\n value={inputValue}\n placeholder={placeholder}\n disabled={disabled}\n onChange={handleChange}\n onKeyDown={handleKeyDown}\n onPaste={handlePaste}\n onFocus={() => { setFocused(true); if (!disabled) setOpen(true) }}\n onBlur={() => setFocused(false)}\n aria-label={label ?? 'Выберите период'}\n aria-expanded={open}\n aria-haspopup=\"dialog\"\n aria-invalid={inputInvalid || undefined}\n />\n </div>\n {open && (\n <div className=\"datepicker__popover\" role=\"dialog\" aria-label=\"Выберите период\">\n <Calendar\n mode=\"range\"\n selected={calendarSelected}\n onSelect={() => {}}\n onDayClick={handleDayClick}\n onDayMouseEnter={handleDayMouseEnter}\n onDayMouseLeave={() => setHoveredDate(undefined)}\n startMonth={fromConstraint}\n endMonth={toConstraint}\n numberOfMonths={2}\n locale={ru}\n />\n </div>\n )}\n </div>\n )\n}\n","export { Calendar } from './components/Calendar'\nexport type { CalendarProps } from './components/Calendar'\n\nexport { DatePicker } from './components/DatePicker'\nexport type { DatePickerProps } from './components/DatePicker'\n\nexport { DateRangePicker } from './components/DateRangePicker'\nexport type { DateRangePickerProps, DateRange } from './components/DateRangePicker'\n\nexport const VERSION = '0.0.1'\n"],"mappings":"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","names":["jsx","_a","useCallback","useRef","useState","format","isValid","parse","ru","jsx","jsxs","DATE_FORMAT","parseDate","parse","isValid","format","useState","useRef","useCallback","_a","ru"]}
1
+ {"version":3,"sources":["../src/components/Button/Button.tsx"],"sourcesContent":["import type { ButtonProps } from './Button.types'\nimport { Spinner } from '../icons/Spinner'\n\nexport function Button({\n variant = 'primary',\n size = 'm',\n loading = false,\n disabled,\n className,\n children,\n ...rest\n}: ButtonProps) {\n const classes = [\n 'dp-btn',\n `dp-btn--${variant}`,\n `dp-btn--${size}`,\n loading && 'dp-btn--loading',\n className,\n ].filter(Boolean).join(' ')\n\n return (\n <button {...rest} className={classes} disabled={disabled || loading}>\n {children}\n {loading && <Spinner />}\n </button>\n )\n}\n"],"mappings":";;;;;;;;AAqBI,SAEc,KAFd;AAlBG,SAAS,OAAO;AAAA,EACrB,UAAU;AAAA,EACV,OAAO;AAAA,EACP,UAAU;AAAA,EACV;AAAA,EACA;AAAA,EACA;AAAA,EACA,GAAG;AACL,GAAgB;AACd,QAAM,UAAU;AAAA,IACd;AAAA,IACA,WAAW,OAAO;AAAA,IAClB,WAAW,IAAI;AAAA,IACf,WAAW;AAAA,IACX;AAAA,EACF,EAAE,OAAO,OAAO,EAAE,KAAK,GAAG;AAE1B,SACE,qBAAC,YAAQ,GAAG,MAAM,WAAW,SAAS,UAAU,YAAY,SACzD;AAAA;AAAA,IACA,WAAW,oBAAC,WAAQ;AAAA,KACvB;AAEJ;","names":[]}