@artemy-tech/datepicker 0.6.0 → 0.7.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.
@@ -12,7 +12,7 @@ function Calendar({ className, ...props }) {
12
12
  }
13
13
 
14
14
  // src/components/DatePicker/DatePicker.tsx
15
- import { useCallback, useEffect as useEffect3, useRef as useRef2, useState } from "react";
15
+ import { useCallback, useEffect as useEffect3, useMemo, useRef as useRef2, useState } from "react";
16
16
  import { format as format2, isValid as isValid2, startOfDay } from "date-fns";
17
17
  import { ru } from "date-fns/locale";
18
18
 
@@ -88,34 +88,137 @@ function Spinner() {
88
88
 
89
89
  // src/utils/date-mask.ts
90
90
  import { format, isValid, parse } from "date-fns";
91
- var DATE_FORMAT = "dd.MM.yyyy";
92
- function resolveTimeFormat(showTime) {
93
- if (!showTime) return null;
94
- if (showTime === true) return "HH:mm:ss";
95
- return showTime.format;
91
+
92
+ // src/utils/format-schema.ts
93
+ var DATE_TOKENS = ["yyyy", "dd", "MM"];
94
+ var TIME_TOKENS = ["HH", "mm", "ss"];
95
+ var ALL_TOKENS = [...DATE_TOKENS, ...TIME_TOKENS];
96
+ var TOKEN_LENGTH = {
97
+ yyyy: 4,
98
+ dd: 2,
99
+ MM: 2,
100
+ HH: 2,
101
+ mm: 2,
102
+ ss: 2
103
+ };
104
+ var RU_TOKEN_PLACEHOLDER = {
105
+ yyyy: "\u0433\u0433\u0433\u0433",
106
+ dd: "\u0434\u0434",
107
+ MM: "\u043C\u043C",
108
+ HH: "\u0447\u0447",
109
+ mm: "\u043C\u043C",
110
+ ss: "\u0441\u0441"
111
+ };
112
+ var EN_TOKEN_PLACEHOLDER = {
113
+ yyyy: "yyyy",
114
+ dd: "dd",
115
+ MM: "mm",
116
+ HH: "hh",
117
+ mm: "mm",
118
+ ss: "ss"
119
+ };
120
+ function tokenize(format4, allowTime) {
121
+ const parts = [];
122
+ let i = 0;
123
+ while (i < format4.length) {
124
+ let matched = null;
125
+ for (const token of ALL_TOKENS) {
126
+ if (format4.startsWith(token, i)) {
127
+ matched = token;
128
+ break;
129
+ }
130
+ }
131
+ if (matched) {
132
+ if (!allowTime && TIME_TOKENS.includes(matched)) {
133
+ throw new Error(
134
+ `dateFormat must not contain time tokens (got "${matched}"). Use the "showTime" prop instead.`
135
+ );
136
+ }
137
+ parts.push({ kind: "token", token: matched });
138
+ i += matched.length;
139
+ continue;
140
+ }
141
+ parts.push({ kind: "sep", char: format4[i] });
142
+ i++;
143
+ }
144
+ return parts;
145
+ }
146
+ function validateDateParts(parts) {
147
+ var _a, _b;
148
+ const counts = {};
149
+ for (const p of parts) {
150
+ if (p.kind === "token") counts[p.token] = ((_a = counts[p.token]) != null ? _a : 0) + 1;
151
+ }
152
+ for (const token of DATE_TOKENS) {
153
+ if (counts[token] !== 1) {
154
+ throw new Error(
155
+ `dateFormat must contain "${token}" exactly once. Supported tokens: dd, MM, yyyy. Got: ${(_b = counts[token]) != null ? _b : 0}`
156
+ );
157
+ }
158
+ }
96
159
  }
97
- function buildDateFormat(timeFormat) {
98
- return timeFormat ? `${DATE_FORMAT} ${timeFormat}` : DATE_FORMAT;
160
+ function buildSchemaFromParts(parts, isRu) {
161
+ const placeholderMap = isRu ? RU_TOKEN_PLACEHOLDER : EN_TOKEN_PLACEHOLDER;
162
+ const separators = [];
163
+ let digitCount = 0;
164
+ let format4 = "";
165
+ let placeholder = "";
166
+ let pendingSep = "";
167
+ for (const part of parts) {
168
+ if (part.kind === "sep") {
169
+ pendingSep += part.char;
170
+ format4 += part.char;
171
+ placeholder += part.char;
172
+ continue;
173
+ }
174
+ if (pendingSep) {
175
+ separators.push({ afterDigit: digitCount, chars: pendingSep });
176
+ pendingSep = "";
177
+ }
178
+ digitCount += TOKEN_LENGTH[part.token];
179
+ format4 += part.token;
180
+ placeholder += placeholderMap[part.token];
181
+ }
182
+ return { format: format4, digitCount, separators, placeholder };
99
183
  }
100
- function buildMaxDigits(timeFormat) {
101
- if (!timeFormat) return 8;
102
- return timeFormat === "HH:mm" ? 12 : 14;
184
+ function isRuLocale(locale) {
185
+ if (!locale) return true;
186
+ return locale.code === "ru";
103
187
  }
104
- function buildPlaceholder(timeFormat) {
105
- if (!timeFormat) return "\u0434\u0434.\u043C\u043C.\u0433\u0433\u0433\u0433";
106
- return timeFormat === "HH:mm" ? "\u0434\u0434.\u043C\u043C.\u0433\u0433\u0433\u0433 \u0447\u0447:\u043C\u043C" : "\u0434\u0434.\u043C\u043C.\u0433\u0433\u0433\u0433 \u0447\u0447:\u043C\u043C:\u0441\u0441";
188
+ function buildFormatSchema(dateFormat, timeFormat, locale) {
189
+ const dateParts = tokenize(dateFormat, false);
190
+ validateDateParts(dateParts);
191
+ const parts = [...dateParts];
192
+ if (timeFormat) {
193
+ parts.push({ kind: "sep", char: " " });
194
+ parts.push(...tokenize(timeFormat, true));
195
+ }
196
+ return buildSchemaFromParts(parts, isRuLocale(locale));
107
197
  }
108
- function applyMask(digits, maxDigits) {
109
- const d = digits.slice(0, maxDigits);
198
+ function applySchemaMask(digits, schema) {
199
+ const d = digits.slice(0, schema.digitCount);
110
200
  let result = "";
201
+ let sepIdx = 0;
111
202
  for (let i = 0; i < d.length; i++) {
112
- if (i === 2 || i === 4) result += ".";
113
- else if (i === 8) result += " ";
114
- else if (i === 10 || i === 12) result += ":";
203
+ while (sepIdx < schema.separators.length && schema.separators[sepIdx].afterDigit === i) {
204
+ result += schema.separators[sepIdx].chars;
205
+ sepIdx++;
206
+ }
115
207
  result += d[i];
116
208
  }
117
209
  return result;
118
210
  }
211
+
212
+ // src/utils/date-mask.ts
213
+ var DEFAULT_DATE_FORMAT = "dd.MM.yyyy";
214
+ function resolveTimeFormat(showTime) {
215
+ if (!showTime) return null;
216
+ if (showTime === true) return "HH:mm:ss";
217
+ return showTime.format;
218
+ }
219
+ function applyMask(digits, schema) {
220
+ return applySchemaMask(digits, schema);
221
+ }
119
222
  function getCursorPos(masked, digitCount) {
120
223
  if (digitCount === 0) return 0;
121
224
  let count = 0;
@@ -130,11 +233,11 @@ function getCursorPos(masked, digitCount) {
130
233
  function toDateOnly(date) {
131
234
  return new Date(date.getFullYear(), date.getMonth(), date.getDate(), 12, 0, 0);
132
235
  }
133
- function parseDateTime(masked, dateFormat, maxDigits) {
134
- if (masked.replace(/\D/g, "").length !== maxDigits) return void 0;
135
- const date = parse(masked, dateFormat, /* @__PURE__ */ new Date());
136
- if (!isValid(date) || format(date, dateFormat) !== masked) return void 0;
137
- return maxDigits === 8 ? toDateOnly(date) : date;
236
+ function parseDateTime(masked, schema) {
237
+ if (masked.replace(/\D/g, "").length !== schema.digitCount) return void 0;
238
+ const date = parse(masked, schema.format, /* @__PURE__ */ new Date());
239
+ if (!isValid(date) || format(date, schema.format) !== masked) return void 0;
240
+ return schema.digitCount === 8 ? toDateOnly(date) : date;
138
241
  }
139
242
 
140
243
  // src/components/DatePicker/DatePicker.tsx
@@ -157,12 +260,18 @@ function DatePicker({
157
260
  iconPosition = "end",
158
261
  className,
159
262
  renderInput,
160
- customTrigger
263
+ customTrigger,
264
+ locale = ru,
265
+ dateFormat: dateFormatProp = DEFAULT_DATE_FORMAT
161
266
  }) {
162
267
  const timeFormat = resolveTimeFormat(showTime);
163
- const dateFormat = buildDateFormat(timeFormat);
164
- const maxDigits = buildMaxDigits(timeFormat);
165
- const defaultPlaceholder = placeholder != null ? placeholder : buildPlaceholder(timeFormat);
268
+ const schema = useMemo(
269
+ () => buildFormatSchema(dateFormatProp, timeFormat, locale),
270
+ [dateFormatProp, timeFormat, locale]
271
+ );
272
+ const dateFormat = schema.format;
273
+ const maxDigits = schema.digitCount;
274
+ const defaultPlaceholder = placeholder != null ? placeholder : schema.placeholder;
166
275
  const showSeconds = timeFormat === "HH:mm:ss";
167
276
  const fromDay = fromDate ? startOfDay(fromDate) : void 0;
168
277
  const toDay = toDate ? startOfDay(toDate) : void 0;
@@ -226,7 +335,7 @@ function DatePicker({
226
335
  if (!isControlled) setInternalDate(void 0);
227
336
  onChange == null ? void 0 : onChange(void 0);
228
337
  } else if (digits.length === maxDigits) {
229
- const date = parseDateTime(masked, dateFormat, maxDigits);
338
+ const date = parseDateTime(masked, schema);
230
339
  lastEmittedRef.current = date;
231
340
  if (date) lastValidRef.current = masked;
232
341
  setInputInvalid(!date);
@@ -250,7 +359,7 @@ function DatePicker({
250
359
  const cursorPos = (_a = input.selectionStart) != null ? _a : 0;
251
360
  const raw = input.value;
252
361
  const digits = raw.replace(/\D/g, "").slice(0, maxDigits);
253
- const masked = applyMask(digits, maxDigits);
362
+ const masked = applyMask(digits, schema);
254
363
  const digitsBeforeCursor = raw.slice(0, cursorPos).replace(/\D/g, "").length;
255
364
  const newCursorPos = getCursorPos(masked, digitsBeforeCursor);
256
365
  setInputValue(masked);
@@ -268,10 +377,14 @@ function DatePicker({
268
377
  e.preventDefault();
269
378
  return;
270
379
  }
271
- if (e.key === "Backspace" && pos > 0 && /[.: ]/.test(input.value[pos - 1])) {
380
+ const separatorChars = /* @__PURE__ */ new Set();
381
+ schema.separators.forEach((s) => {
382
+ for (const ch of s.chars) separatorChars.add(ch);
383
+ });
384
+ if (e.key === "Backspace" && pos > 0 && separatorChars.has(input.value[pos - 1])) {
272
385
  e.preventDefault();
273
386
  const val = input.value;
274
- const masked = applyMask((val.slice(0, pos - 2) + val.slice(pos)).replace(/\D/g, ""), maxDigits);
387
+ const masked = applyMask((val.slice(0, pos - 2) + val.slice(pos)).replace(/\D/g, ""), schema);
275
388
  setInputValue(masked);
276
389
  commit(masked);
277
390
  requestAnimationFrame(() => input.setSelectionRange(pos - 2, pos - 2));
@@ -279,7 +392,7 @@ function DatePicker({
279
392
  }
280
393
  function handlePaste(e) {
281
394
  e.preventDefault();
282
- const masked = applyMask(e.clipboardData.getData("text").replace(/\D/g, ""), maxDigits);
395
+ const masked = applyMask(e.clipboardData.getData("text").replace(/\D/g, ""), schema);
283
396
  setInputValue(masked);
284
397
  commit(masked);
285
398
  requestAnimationFrame(() => {
@@ -393,7 +506,7 @@ function DatePicker({
393
506
  endMonth: toDay,
394
507
  disabled: disabledDays.length ? disabledDays : void 0,
395
508
  navLayout: "around",
396
- locale: ru
509
+ locale
397
510
  }
398
511
  ) }),
399
512
  /* @__PURE__ */ jsx5("div", { className: "datepicker__time-separator" }),
@@ -427,7 +540,7 @@ function DatePicker({
427
540
  endMonth: toDay,
428
541
  disabled: disabledDays.length ? disabledDays : void 0,
429
542
  navLayout: "around",
430
- locale: ru
543
+ locale
431
544
  }
432
545
  )
433
546
  }
@@ -441,6 +554,7 @@ function DatePicker({
441
554
  import {
442
555
  useCallback as useCallback2,
443
556
  useEffect as useEffect4,
557
+ useMemo as useMemo2,
444
558
  useRef as useRef3,
445
559
  useState as useState2
446
560
  } from "react";
@@ -449,22 +563,16 @@ import { ru as ru2 } from "date-fns/locale";
449
563
 
450
564
  // src/utils/range-mask.ts
451
565
  import { format as format3, isValid as isValid3, parse as parse2 } from "date-fns";
452
- var DATE_FORMAT2 = "dd.MM.yyyy";
453
- function applyDateMask(digits) {
454
- const d = digits.slice(0, 8);
455
- let result = "";
456
- for (let i = 0; i < d.length; i++) {
457
- if (i === 2 || i === 4) result += ".";
458
- result += d[i];
459
- }
460
- return result;
566
+ function applyDateMask(digits, schema) {
567
+ return applySchemaMask(digits, schema);
461
568
  }
462
- function applyRangeMask(digits) {
463
- const all = digits.slice(0, 16);
464
- const fromMasked = applyDateMask(all.slice(0, 8));
465
- const toDigits = all.slice(8);
569
+ function applyRangeMask(digits, schema) {
570
+ const total = schema.digitCount * 2;
571
+ const all = digits.slice(0, total);
572
+ const fromMasked = applyDateMask(all.slice(0, schema.digitCount), schema);
573
+ const toDigits = all.slice(schema.digitCount);
466
574
  if (toDigits.length === 0) return fromMasked;
467
- return `${fromMasked} \u2014 ${applyDateMask(toDigits)}`;
575
+ return `${fromMasked} \u2014 ${applyDateMask(toDigits, schema)}`;
468
576
  }
469
577
  function getRangeCursorPos(masked, digitCount) {
470
578
  if (digitCount === 0) return 0;
@@ -480,17 +588,17 @@ function getRangeCursorPos(masked, digitCount) {
480
588
  function toDateOnly2(date) {
481
589
  return new Date(date.getFullYear(), date.getMonth(), date.getDate(), 12, 0, 0);
482
590
  }
483
- function parseDate(masked) {
484
- if (masked.replace(/\D/g, "").length !== 8) return void 0;
485
- const date = parse2(masked, DATE_FORMAT2, /* @__PURE__ */ new Date());
486
- if (!isValid3(date) || format3(date, DATE_FORMAT2) !== masked) return void 0;
591
+ function parseDate(masked, schema) {
592
+ if (masked.replace(/\D/g, "").length !== schema.digitCount) return void 0;
593
+ const date = parse2(masked, schema.format, /* @__PURE__ */ new Date());
594
+ if (!isValid3(date) || format3(date, schema.format) !== masked) return void 0;
487
595
  return toDateOnly2(date);
488
596
  }
489
- function formatRange(from, to) {
597
+ function formatRange(from, to, schema) {
490
598
  if (!from) return "";
491
- const fromStr = format3(from, DATE_FORMAT2);
599
+ const fromStr = format3(from, schema.format);
492
600
  if (!to) return fromStr;
493
- return `${fromStr} \u2014 ${format3(to, DATE_FORMAT2)}`;
601
+ return `${fromStr} \u2014 ${format3(to, schema.format)}`;
494
602
  }
495
603
  function resolveShowSeconds(showTime) {
496
604
  if (!showTime) return false;
@@ -515,8 +623,16 @@ function DateRangePicker({
515
623
  showTime,
516
624
  icon,
517
625
  iconPosition = "end",
518
- className
626
+ className,
627
+ locale = ru2,
628
+ dateFormat: dateFormatProp = DEFAULT_DATE_FORMAT
519
629
  }) {
630
+ const schema = useMemo2(
631
+ () => buildFormatSchema(dateFormatProp, null, locale),
632
+ [dateFormatProp, locale]
633
+ );
634
+ const maxDigits = schema.digitCount;
635
+ const totalDigits = maxDigits * 2;
520
636
  const resolvedIcon = loading ? /* @__PURE__ */ jsx6(Spinner, {}) : icon === false ? null : icon != null ? icon : /* @__PURE__ */ jsx6(CalendarIcon, {});
521
637
  const isControlled = value !== void 0;
522
638
  const showSeconds = resolveShowSeconds(showTime);
@@ -534,7 +650,7 @@ function DateRangePicker({
534
650
  );
535
651
  const [inputValue, setInputValue] = useState2(() => {
536
652
  const initial = value != null ? value : defaultValue;
537
- return formatRange(initial == null ? void 0 : initial.from, initial == null ? void 0 : initial.to);
653
+ return formatRange(initial == null ? void 0 : initial.from, initial == null ? void 0 : initial.to, schema);
538
654
  });
539
655
  const [inputInvalid, setInputInvalid] = useState2(false);
540
656
  const [open, setOpen] = useState2(false);
@@ -578,7 +694,7 @@ function DateRangePicker({
578
694
  const lastToTime = (_f = (_e = lastEmittedToRef.current) == null ? void 0 : _e.getTime()) != null ? _f : null;
579
695
  if (fromTime === lastFromTime && toTime === lastToTime) return;
580
696
  if (!wasControlledRef.current && value === void 0) return;
581
- setInputValue(formatRange(newFrom, newTo));
697
+ setInputValue(formatRange(newFrom, newTo, schema));
582
698
  setInputInvalid(false);
583
699
  if (!isControlled) {
584
700
  setInternalFrom(newFrom);
@@ -606,7 +722,7 @@ function DateRangePicker({
606
722
  setInternalFrom(from);
607
723
  setInternalTo(void 0);
608
724
  }
609
- setInputValue(formatRange(from, void 0));
725
+ setInputValue(formatRange(from, void 0, schema));
610
726
  setInputInvalid(false);
611
727
  lastEmittedFromRef.current = from;
612
728
  lastEmittedToRef.current = void 0;
@@ -629,7 +745,7 @@ function DateRangePicker({
629
745
  setInternalFrom(from);
630
746
  setInternalTo(to);
631
747
  }
632
- setInputValue(formatRange(from, to));
748
+ setInputValue(formatRange(from, to, schema));
633
749
  setInputInvalid(false);
634
750
  lastEmittedFromRef.current = from;
635
751
  lastEmittedToRef.current = to;
@@ -674,18 +790,18 @@ function DateRangePicker({
674
790
  const input = e.target;
675
791
  const cursorPos = (_a = input.selectionStart) != null ? _a : 0;
676
792
  const raw = input.value;
677
- const digits = raw.replace(/\D/g, "").slice(0, 16);
678
- const masked = applyRangeMask(digits);
793
+ const digits = raw.replace(/\D/g, "").slice(0, totalDigits);
794
+ const masked = applyRangeMask(digits, schema);
679
795
  const digitsBeforeCursor = raw.slice(0, cursorPos).replace(/\D/g, "").length;
680
796
  setInputValue(masked);
681
797
  setAnchorDate(void 0);
682
798
  setHoveredDate(void 0);
683
- const fromDigits = digits.slice(0, 8);
684
- const toDigits = digits.slice(8);
685
- const parsedFrom = fromDigits.length === 8 ? parseDate(applyDateMask(fromDigits)) : void 0;
686
- const parsedTo = toDigits.length === 8 ? parseDate(applyDateMask(toDigits)) : void 0;
687
- const fromComplete = fromDigits.length === 8;
688
- const toComplete = toDigits.length === 8;
799
+ const fromDigits = digits.slice(0, maxDigits);
800
+ const toDigits = digits.slice(maxDigits);
801
+ const parsedFrom = fromDigits.length === maxDigits ? parseDate(applyDateMask(fromDigits, schema), schema) : void 0;
802
+ const parsedTo = toDigits.length === maxDigits ? parseDate(applyDateMask(toDigits, schema), schema) : void 0;
803
+ const fromComplete = fromDigits.length === maxDigits;
804
+ const toComplete = toDigits.length === maxDigits;
689
805
  setInputInvalid(fromComplete && !parsedFrom || toComplete && !parsedTo);
690
806
  if (!isControlled) {
691
807
  setInternalFrom(parsedFrom);
@@ -714,13 +830,18 @@ function DateRangePicker({
714
830
  e.preventDefault();
715
831
  return;
716
832
  }
717
- if (e.key === "Backspace" && pos > 0 && /[\s—]/.test(input.value[pos - 1])) {
833
+ const separatorChars = /* @__PURE__ */ new Set([" ", "\u2014"]);
834
+ schema.separators.forEach((s) => {
835
+ for (const ch of s.chars) separatorChars.add(ch);
836
+ });
837
+ if (e.key === "Backspace" && pos > 0 && separatorChars.has(input.value[pos - 1])) {
718
838
  e.preventDefault();
719
839
  const val = input.value;
720
840
  const charsToSkip = (_c = (_b = val.slice(0, pos).match(/[\s—]+$/)) == null ? void 0 : _b[0].length) != null ? _c : 1;
721
841
  const newPos = pos - charsToSkip;
722
842
  const masked = applyRangeMask(
723
- (val.slice(0, newPos - 1) + val.slice(newPos)).replace(/\D/g, "")
843
+ (val.slice(0, newPos - 1) + val.slice(newPos)).replace(/\D/g, ""),
844
+ schema
724
845
  );
725
846
  setInputValue(masked);
726
847
  requestAnimationFrame(
@@ -731,15 +852,18 @@ function DateRangePicker({
731
852
  function handlePaste(e) {
732
853
  e.preventDefault();
733
854
  const text = e.clipboardData.getData("text");
734
- const digits = text.replace(/\D/g, "").slice(0, 16);
735
- const masked = applyRangeMask(digits);
855
+ const digits = text.replace(/\D/g, "").slice(0, totalDigits);
856
+ const masked = applyRangeMask(digits, schema);
736
857
  setInputValue(masked);
737
858
  setAnchorDate(void 0);
738
859
  setHoveredDate(void 0);
739
- const parsedFrom = digits.length >= 8 ? parseDate(applyDateMask(digits.slice(0, 8))) : void 0;
740
- const parsedTo = digits.length >= 16 ? parseDate(applyDateMask(digits.slice(8, 16))) : void 0;
860
+ const parsedFrom = digits.length >= maxDigits ? parseDate(applyDateMask(digits.slice(0, maxDigits), schema), schema) : void 0;
861
+ const parsedTo = digits.length >= totalDigits ? parseDate(
862
+ applyDateMask(digits.slice(maxDigits, totalDigits), schema),
863
+ schema
864
+ ) : void 0;
741
865
  setInputInvalid(
742
- digits.length >= 8 && !parsedFrom || digits.length >= 16 && !parsedTo
866
+ digits.length >= maxDigits && !parsedFrom || digits.length >= totalDigits && !parsedTo
743
867
  );
744
868
  if (!isControlled) {
745
869
  setInternalFrom(parsedFrom);
@@ -757,7 +881,7 @@ function DateRangePicker({
757
881
  }
758
882
  );
759
883
  }
760
- const placeholder = label && !focused && !filled ? void 0 : "\u0434\u0434.\u043C\u043C.\u0433\u0433\u0433\u0433 \u2014 \u0434\u0434.\u043C\u043C.\u0433\u0433\u0433\u0433";
884
+ const placeholder = label && !focused && !filled ? void 0 : `${schema.placeholder} \u2014 ${schema.placeholder}`;
761
885
  const interactive = !disabled && !loading;
762
886
  return /* @__PURE__ */ jsxs4(
763
887
  "div",
@@ -843,7 +967,7 @@ function DateRangePicker({
843
967
  endMonth: toDay,
844
968
  disabled: disabledDays.length ? disabledDays : void 0,
845
969
  numberOfMonths: 2,
846
- locale: ru2
970
+ locale
847
971
  }
848
972
  ) }) }),
849
973
  /* @__PURE__ */ jsxs4("div", { className: "datepicker__time-row", children: [
@@ -895,7 +1019,7 @@ function DateRangePicker({
895
1019
  startMonth: fromConstraint,
896
1020
  endMonth: toConstraint,
897
1021
  numberOfMonths: 2,
898
- locale: ru2
1022
+ locale
899
1023
  }
900
1024
  )
901
1025
  }
@@ -911,4 +1035,4 @@ export {
911
1035
  DatePicker,
912
1036
  DateRangePicker
913
1037
  };
914
- //# sourceMappingURL=chunk-I3ID2PSC.js.map
1038
+ //# sourceMappingURL=chunk-66Q5CMWV.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/components/Calendar/Calendar.tsx","../src/components/DatePicker/DatePicker.tsx","../src/hooks/useClickOutside.ts","../src/components/TimePanel/TimePanel.tsx","../src/components/icons/CalendarIcon.tsx","../src/components/icons/Spinner.tsx","../src/utils/date-mask.ts","../src/utils/format-schema.ts","../src/components/DateRangePicker/DateRangePicker.tsx","../src/utils/range-mask.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, useEffect, useMemo, useRef, useState, type ReactNode } from 'react'\nimport { format, isValid, startOfDay } from 'date-fns'\nimport { ru, type Locale } from 'date-fns/locale'\nimport { useClickOutside } from '../../hooks/useClickOutside'\nimport { Calendar } from '../Calendar'\nimport { TimePanel } from '../TimePanel'\nimport { CalendarIcon } from '../icons/CalendarIcon'\nimport { Spinner } from '../icons/Spinner'\nimport {\n applyMask,\n DEFAULT_DATE_FORMAT,\n getCursorPos,\n parseDateTime,\n resolveTimeFormat,\n toDateOnly,\n} from '../../utils/date-mask'\nimport { buildFormatSchema } from '../../utils/format-schema'\n\nexport type DatePickerSize = 's' | 'm' | 'l'\nexport type DatePickerShowTime = boolean | { format: 'HH:mm' | 'HH:mm:ss' }\n\nexport interface DatePickerInputProps {\n ref: React.Ref<HTMLInputElement>\n type: 'text'\n inputMode: 'numeric'\n className: string\n value: string\n placeholder: string | undefined\n disabled: boolean\n onChange: React.ChangeEventHandler<HTMLInputElement>\n onKeyDown: React.KeyboardEventHandler<HTMLInputElement>\n onPaste: React.ClipboardEventHandler<HTMLInputElement>\n onFocus: React.FocusEventHandler<HTMLInputElement>\n onBlur: React.FocusEventHandler<HTMLInputElement>\n 'aria-label': string\n 'aria-expanded': boolean | undefined\n 'aria-haspopup': 'dialog' | undefined\n 'aria-invalid': true | 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 loading?: boolean\n size?: DatePickerSize\n noCalendar?: boolean\n showTime?: DatePickerShowTime\n icon?: ReactNode | false\n iconPosition?: 'start' | 'end'\n className?: string\n renderInput?: (props: DatePickerInputProps) => ReactNode\n customTrigger?: (value: string, onClick: () => void) => ReactNode\n locale?: Locale\n dateFormat?: 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 loading = false,\n size = 'm',\n noCalendar = false,\n showTime,\n icon,\n iconPosition = 'end',\n className,\n renderInput,\n customTrigger,\n locale = ru,\n dateFormat: dateFormatProp = DEFAULT_DATE_FORMAT,\n}: DatePickerProps) {\n const timeFormat = resolveTimeFormat(showTime)\n const schema = useMemo(\n () => buildFormatSchema(dateFormatProp, timeFormat, locale),\n [dateFormatProp, timeFormat, locale],\n )\n const dateFormat = schema.format\n const maxDigits = schema.digitCount\n const defaultPlaceholder = placeholder ?? schema.placeholder\n const showSeconds = timeFormat === 'HH:mm:ss'\n\n const fromDay = fromDate ? startOfDay(fromDate) : undefined\n const toDay = toDate ? startOfDay(toDate) : undefined\n const disabledDays = [\n ...(fromDay ? [{ before: fromDay }] : []),\n ...(toDay ? [{ after: toDay }] : []),\n ]\n\n const resolvedIcon = loading ? <Spinner /> : icon === false ? null : (icon ?? <CalendarIcon />)\n\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 const initial = value ?? defaultValue\n return initial && isValid(initial) ? format(initial, dateFormat) : ''\n })\n const [inputInvalid, setInputInvalid] = useState(false)\n\n const inputRef = useRef<HTMLInputElement>(null)\n const containerRef = useRef<HTMLDivElement>(null)\n const lastValidRef = useRef(inputValue)\n // Track what we last emitted via onChange so we can ignore parent echoing it back\n const lastEmittedRef = useRef<Date | undefined>(value !== undefined ? value : defaultValue)\n // Once we see a defined value, we always sync external changes (handles RHF reset)\n const wasControlledRef = useRef(value !== undefined)\n\n const selected = isControlled ? value : internalDate\n const [month, setMonth] = useState<Date>(\n () => (selected && isValid(selected) ? selected : new Date()),\n )\n const filled = inputValue.length > 0\n\n useEffect(() => {\n if (selected && isValid(selected)) setMonth(selected)\n }, [selected?.getFullYear(), selected?.getMonth()]) // eslint-disable-line react-hooks/exhaustive-deps\n\n const close = useCallback(() => setOpen(false), [])\n useClickOutside(containerRef, close)\n\n // Sync inputValue when value changes externally (e.g. form reset)\n useEffect(() => {\n if (value !== undefined) wasControlledRef.current = true\n const lastTime = lastEmittedRef.current?.getTime() ?? null\n const valueTime = value?.getTime() ?? null\n if (valueTime === lastTime) return\n if (!wasControlledRef.current && value === undefined) return\n\n const formatted = value && isValid(value) ? format(value, dateFormat) : ''\n setInputValue(formatted)\n lastValidRef.current = formatted\n setInputInvalid(false)\n if (!isControlled) setInternalDate(value)\n lastEmittedRef.current = value\n }, [value]) // eslint-disable-line react-hooks/exhaustive-deps\n\n function applyValid(masked: string, date: Date | undefined) {\n lastEmittedRef.current = date\n lastValidRef.current = masked\n setInputValue(masked)\n setInputInvalid(false)\n if (!isControlled) setInternalDate(date)\n onChange?.(date)\n }\n\n function commit(masked: string) {\n const digits = masked.replace(/\\D/g, '')\n if (digits.length === 0) {\n lastEmittedRef.current = undefined\n lastValidRef.current = ''\n setInputInvalid(false)\n if (!isControlled) setInternalDate(undefined)\n onChange?.(undefined)\n } else if (digits.length === maxDigits) {\n const date = parseDateTime(masked, schema)\n lastEmittedRef.current = date\n if (date) lastValidRef.current = masked\n setInputInvalid(!date)\n if (!isControlled) setInternalDate(date)\n onChange?.(date)\n } else {\n setInputInvalid(false)\n }\n }\n\n function handleBlur() {\n setFocused(false)\n const digits = inputValue.replace(/\\D/g, '')\n if ((digits.length > 0 && digits.length < maxDigits) || inputInvalid) {\n setInputValue(lastValidRef.current)\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, maxDigits)\n const masked = applyMask(digits, schema)\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 const separatorChars = new Set<string>()\n schema.separators.forEach((s) => {\n for (const ch of s.chars) separatorChars.add(ch)\n })\n if (e.key === 'Backspace' && pos > 0 && separatorChars.has(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, ''), schema)\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, ''), schema)\n setInputValue(masked)\n commit(masked)\n requestAnimationFrame(() => inputRef.current?.setSelectionRange(masked.length, masked.length))\n }\n\n function handleCalendarSelect(date: Date | undefined) {\n if (!date || !isValid(date)) {\n applyValid('', undefined)\n if (!timeFormat) setOpen(false)\n return\n }\n\n let dateToCommit: Date\n if (timeFormat) {\n const base = selected && isValid(selected) ? selected : new Date(0)\n dateToCommit = new Date(\n date.getFullYear(), date.getMonth(), date.getDate(),\n base.getHours(), base.getMinutes(), base.getSeconds(),\n )\n } else {\n dateToCommit = toDateOnly(date)\n }\n\n applyValid(format(dateToCommit, dateFormat), dateToCommit)\n if (!timeFormat) setOpen(false)\n }\n\n function handleTimeChange(h: number, m: number, s: number) {\n const base = selected && isValid(selected) ? selected : new Date()\n const newDate = new Date(base.getFullYear(), base.getMonth(), base.getDate(), h, m, s)\n applyValid(format(newDate, dateFormat), newDate)\n }\n\n const interactive = !disabled && !loading\n\n return (\n <div\n ref={containerRef}\n className={['datepicker', `datepicker--${size}`, className].filter(Boolean).join(' ')}\n data-focused={focused || open || undefined}\n data-filled={filled || undefined}\n data-failed={failed || inputInvalid || undefined}\n data-disabled={!interactive || undefined}\n >\n {customTrigger\n ? customTrigger(inputValue, () => interactive && setOpen(prev => !prev))\n : (\n <div\n className={['datepicker__field', renderInput ? 'datepicker__field--custom' : ''].filter(Boolean).join(' ')}\n data-icon-start={resolvedIcon && iconPosition === 'start' ? true : undefined}\n data-icon-end={resolvedIcon && iconPosition === 'end' ? true : undefined}\n onClick={() => interactive && inputRef.current?.focus()}\n >\n {resolvedIcon && iconPosition === 'start' && (\n <span className=\"datepicker__icon datepicker__icon--start\">{resolvedIcon}</span>\n )}\n {label && <span className=\"datepicker__label\">{label}</span>}\n {(() => {\n const inputProps: DatePickerInputProps = {\n ref: inputRef,\n type: 'text',\n inputMode: 'numeric',\n className: 'datepicker__input',\n value: inputValue,\n placeholder: label && !focused ? undefined : defaultPlaceholder,\n disabled: !interactive,\n onChange: handleChange,\n onKeyDown: handleKeyDown,\n onPaste: handlePaste,\n onFocus: () => { setFocused(true); if (interactive && !noCalendar) setOpen(true) },\n onBlur: handleBlur,\n 'aria-label': label ?? 'Выберите дату',\n 'aria-expanded': !noCalendar ? open : undefined,\n 'aria-haspopup': !noCalendar ? 'dialog' : undefined,\n 'aria-invalid': inputInvalid || undefined,\n }\n if (renderInput) return renderInput(inputProps)\n const { ref, ...rest } = inputProps\n return <input ref={ref as React.RefObject<HTMLInputElement>} {...rest} />\n })()}\n {resolvedIcon && iconPosition === 'end' && (\n <span className=\"datepicker__icon datepicker__icon--end\">{resolvedIcon}</span>\n )}\n </div>\n )\n }\n {!noCalendar && open && (\n <div\n className={[\n 'datepicker__popover',\n `datepicker__popover--${size}`,\n timeFormat && 'datepicker__popover--with-time',\n ].filter(Boolean).join(' ')}\n role=\"dialog\"\n aria-label=\"Календарь\"\n >\n {timeFormat ? (\n <>\n <div className=\"datepicker__popover-body\">\n <div className=\"datepicker__popover-calendar\">\n <Calendar\n mode=\"single\"\n selected={selected}\n month={month}\n onMonthChange={setMonth}\n onSelect={handleCalendarSelect}\n startMonth={fromDay}\n endMonth={toDay}\n disabled={disabledDays.length ? disabledDays : undefined}\n navLayout=\"around\"\n locale={locale}\n />\n </div>\n <div className=\"datepicker__time-separator\" />\n <div className=\"datepicker__popover-time\">\n <TimePanel\n value={selected}\n showSeconds={showSeconds}\n onChange={handleTimeChange}\n />\n </div>\n </div>\n <div className=\"datepicker__popover-footer\">\n <button\n className=\"datepicker__ok-btn\"\n type=\"button\"\n onClick={() => setOpen(false)}\n >\n OK\n </button>\n </div>\n </>\n ) : (\n <Calendar\n mode=\"single\"\n selected={selected}\n month={month}\n onMonthChange={setMonth}\n onSelect={handleCalendarSelect}\n startMonth={fromDay}\n endMonth={toDay}\n disabled={disabledDays.length ? disabledDays : undefined}\n navLayout=\"around\"\n locale={locale}\n />\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 { useEffect, useRef } from 'react'\n\nconst HOURS = Array.from({ length: 24 }, (_, i) => i)\nconst MINUTES = Array.from({ length: 60 }, (_, i) => i)\nconst SECONDS = Array.from({ length: 60 }, (_, i) => i)\n\nfunction pad2(n: number) {\n return String(n).padStart(2, '0')\n}\n\ninterface ColumnProps {\n values: number[]\n selected: number\n onSelect: (v: number) => void\n}\n\nfunction Column({ values, selected, onSelect }: ColumnProps) {\n const selectedRef = useRef<HTMLButtonElement>(null)\n\n useEffect(() => {\n selectedRef.current?.scrollIntoView({ block: 'center', behavior: 'instant' })\n }, [selected])\n\n return (\n <div className=\"time-panel__column\">\n {values.map((v) => (\n <button\n key={v}\n ref={v === selected ? selectedRef : undefined}\n className=\"time-panel__item\"\n data-selected={v === selected || undefined}\n onClick={() => onSelect(v)}\n type=\"button\"\n tabIndex={-1}\n >\n {pad2(v)}\n </button>\n ))}\n </div>\n )\n}\n\nexport interface TimePanelProps {\n value: Date | undefined\n showSeconds: boolean\n onChange: (h: number, m: number, s: number) => void\n}\n\nexport function TimePanel({ value, showSeconds, onChange }: TimePanelProps) {\n const h = value?.getHours() ?? 0\n const m = value?.getMinutes() ?? 0\n const s = value?.getSeconds() ?? 0\n\n return (\n <div className=\"time-panel\">\n <Column values={HOURS} selected={h} onSelect={(v) => onChange(v, m, s)} />\n <Column values={MINUTES} selected={m} onSelect={(v) => onChange(h, v, s)} />\n {showSeconds && (\n <Column values={SECONDS} selected={s} onSelect={(v) => onChange(h, m, v)} />\n )}\n </div>\n )\n}\n","export function CalendarIcon() {\n return (\n <svg width=\"16\" height=\"16\" viewBox=\"0 0 16 16\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\">\n <rect x=\"1\" y=\"2.5\" width=\"14\" height=\"12\" rx=\"1.5\" stroke=\"currentColor\" strokeWidth=\"1.5\" />\n <path d=\"M1 6.5H15\" stroke=\"currentColor\" strokeWidth=\"1.5\" />\n <path d=\"M5 1V4M11 1V4\" stroke=\"currentColor\" strokeWidth=\"1.5\" strokeLinecap=\"round\" />\n </svg>\n )\n}\n","export function Spinner() {\n return <span className=\"datepicker-spinner\" aria-hidden=\"true\" />\n}\n","import { format, isValid, parse } from 'date-fns'\nimport type { DatePickerShowTime } from '../components/DatePicker/DatePicker'\nimport { applySchemaMask, type FormatSchema, type TimeFormat } from './format-schema'\n\nexport const DEFAULT_DATE_FORMAT = 'dd.MM.yyyy'\n\nexport function resolveTimeFormat(showTime?: DatePickerShowTime): TimeFormat {\n if (!showTime) return null\n if (showTime === true) return 'HH:mm:ss'\n return showTime.format\n}\n\nexport function applyMask(digits: string, schema: FormatSchema): string {\n return applySchemaMask(digits, schema)\n}\n\nexport function 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\nexport function toDateOnly(date: Date): Date {\n return new Date(date.getFullYear(), date.getMonth(), date.getDate(), 12, 0, 0)\n}\n\nexport function parseDateTime(masked: string, schema: FormatSchema): Date | undefined {\n if (masked.replace(/\\D/g, '').length !== schema.digitCount) return undefined\n const date = parse(masked, schema.format, new Date())\n if (!isValid(date) || format(date, schema.format) !== masked) return undefined\n return schema.digitCount === 8 ? toDateOnly(date) : date\n}\n","import type { Locale } from 'date-fns'\n\nexport interface FormatSeparator {\n afterDigit: number\n chars: string\n}\n\nexport interface FormatSchema {\n format: string\n digitCount: number\n separators: FormatSeparator[]\n placeholder: string\n}\n\nconst DATE_TOKENS = ['yyyy', 'dd', 'MM'] as const\nconst TIME_TOKENS = ['HH', 'mm', 'ss'] as const\nconst ALL_TOKENS = [...DATE_TOKENS, ...TIME_TOKENS] as const\n\ntype Token = (typeof ALL_TOKENS)[number]\n\nconst TOKEN_LENGTH: Record<Token, number> = {\n yyyy: 4,\n dd: 2,\n MM: 2,\n HH: 2,\n mm: 2,\n ss: 2,\n}\n\nconst RU_TOKEN_PLACEHOLDER: Record<Token, string> = {\n yyyy: 'гггг',\n dd: 'дд',\n MM: 'мм',\n HH: 'чч',\n mm: 'мм',\n ss: 'сс',\n}\n\nconst EN_TOKEN_PLACEHOLDER: Record<Token, string> = {\n yyyy: 'yyyy',\n dd: 'dd',\n MM: 'mm',\n HH: 'hh',\n mm: 'mm',\n ss: 'ss',\n}\n\ntype ParsedPart = { kind: 'token'; token: Token } | { kind: 'sep'; char: string }\n\nfunction tokenize(format: string, allowTime: boolean): ParsedPart[] {\n const parts: ParsedPart[] = []\n let i = 0\n while (i < format.length) {\n let matched: Token | null = null\n for (const token of ALL_TOKENS) {\n if (format.startsWith(token, i)) {\n matched = token\n break\n }\n }\n if (matched) {\n if (!allowTime && TIME_TOKENS.includes(matched as (typeof TIME_TOKENS)[number])) {\n throw new Error(\n `dateFormat must not contain time tokens (got \"${matched}\"). Use the \"showTime\" prop instead.`,\n )\n }\n parts.push({ kind: 'token', token: matched })\n i += matched.length\n continue\n }\n parts.push({ kind: 'sep', char: format[i] })\n i++\n }\n return parts\n}\n\nfunction validateDateParts(parts: ParsedPart[]) {\n const counts: Partial<Record<Token, number>> = {}\n for (const p of parts) {\n if (p.kind === 'token') counts[p.token] = (counts[p.token] ?? 0) + 1\n }\n for (const token of DATE_TOKENS) {\n if (counts[token] !== 1) {\n throw new Error(\n `dateFormat must contain \"${token}\" exactly once. Supported tokens: dd, MM, yyyy. Got: ${\n counts[token] ?? 0\n }`,\n )\n }\n }\n}\n\nfunction buildSchemaFromParts(parts: ParsedPart[], isRu: boolean): FormatSchema {\n const placeholderMap = isRu ? RU_TOKEN_PLACEHOLDER : EN_TOKEN_PLACEHOLDER\n const separators: FormatSeparator[] = []\n let digitCount = 0\n let format = ''\n let placeholder = ''\n let pendingSep = ''\n\n for (const part of parts) {\n if (part.kind === 'sep') {\n pendingSep += part.char\n format += part.char\n placeholder += part.char\n continue\n }\n if (pendingSep) {\n separators.push({ afterDigit: digitCount, chars: pendingSep })\n pendingSep = ''\n }\n digitCount += TOKEN_LENGTH[part.token]\n format += part.token\n placeholder += placeholderMap[part.token]\n }\n\n return { format, digitCount, separators, placeholder }\n}\n\nfunction isRuLocale(locale?: Locale): boolean {\n if (!locale) return true\n return locale.code === 'ru'\n}\n\nexport type TimeFormat = 'HH:mm' | 'HH:mm:ss' | null\n\nexport function buildFormatSchema(\n dateFormat: string,\n timeFormat: TimeFormat,\n locale?: Locale,\n): FormatSchema {\n const dateParts = tokenize(dateFormat, false)\n validateDateParts(dateParts)\n\n const parts: ParsedPart[] = [...dateParts]\n if (timeFormat) {\n parts.push({ kind: 'sep', char: ' ' })\n parts.push(...tokenize(timeFormat, true))\n }\n\n return buildSchemaFromParts(parts, isRuLocale(locale))\n}\n\nexport function applySchemaMask(digits: string, schema: FormatSchema): string {\n const d = digits.slice(0, schema.digitCount)\n let result = ''\n let sepIdx = 0\n for (let i = 0; i < d.length; i++) {\n while (sepIdx < schema.separators.length && schema.separators[sepIdx].afterDigit === i) {\n result += schema.separators[sepIdx].chars\n sepIdx++\n }\n result += d[i]\n }\n return result\n}\n","import {\n useCallback,\n useEffect,\n useMemo,\n useRef,\n useState,\n type ReactNode,\n} from 'react';\nimport { isValid, startOfDay } from 'date-fns';\nimport { ru, type Locale } from 'date-fns/locale';\nimport type { DateRange } from 'react-day-picker';\nimport type { DatePickerShowTime } from '../DatePicker/DatePicker';\nimport { useClickOutside } from '../../hooks/useClickOutside';\nimport { Calendar } from '../Calendar';\nimport { TimePanel } from '../TimePanel';\nimport { CalendarIcon } from '../icons/CalendarIcon';\nimport { Spinner } from '../icons/Spinner';\nimport {\n applyDateMask,\n applyRangeMask,\n formatRange,\n getRangeCursorPos,\n parseDate,\n resolveShowSeconds,\n toDateOnly,\n} from '../../utils/range-mask';\nimport { DEFAULT_DATE_FORMAT } from '../../utils/date-mask';\nimport { buildFormatSchema } from '../../utils/format-schema';\n\nexport type { DateRange };\nexport type { DatePickerShowTime };\n\nexport type DateRangePickerSize = 's' | 'm' | 'l';\nexport type DateRangePickerCalendarLayout = 'vertical' | 'horizontal';\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 loading?: boolean;\n size?: DateRangePickerSize;\n calendarLayout?: DateRangePickerCalendarLayout;\n showTime?: DatePickerShowTime;\n icon?: ReactNode | false;\n iconPosition?: 'start' | 'end';\n className?: string;\n locale?: Locale;\n dateFormat?: 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 loading = false,\n size = 'm',\n calendarLayout = 'horizontal',\n showTime,\n icon,\n iconPosition = 'end',\n className,\n locale = ru,\n dateFormat: dateFormatProp = DEFAULT_DATE_FORMAT,\n}: DateRangePickerProps) {\n const schema = useMemo(\n () => buildFormatSchema(dateFormatProp, null, locale),\n [dateFormatProp, locale],\n );\n const maxDigits = schema.digitCount;\n const totalDigits = maxDigits * 2;\n const resolvedIcon = loading ? (\n <Spinner />\n ) : icon === false ? null : (\n icon ?? <CalendarIcon />\n );\n\n const isControlled = value !== undefined;\n const showSeconds = resolveShowSeconds(showTime);\n\n const fromDay = fromConstraint ? startOfDay(fromConstraint) : undefined;\n const toDay = toConstraint ? startOfDay(toConstraint) : undefined;\n const disabledDays = [\n ...(fromDay ? [{ before: fromDay }] : []),\n ...(toDay ? [{ after: toDay }] : []),\n ];\n\n const [internalFrom, setInternalFrom] = useState<Date | undefined>(\n defaultValue?.from,\n );\n const [internalTo, setInternalTo] = useState<Date | undefined>(\n defaultValue?.to,\n );\n const [inputValue, setInputValue] = useState(() => {\n const initial = value ?? defaultValue;\n return formatRange(initial?.from, initial?.to, schema);\n });\n const [inputInvalid, setInputInvalid] = useState(false);\n const [open, setOpen] = useState(false);\n const [focused, setFocused] = useState(false);\n\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 // Track last emitted range to ignore parent echoing it back\n const lastEmittedFromRef = useRef<Date | undefined>(\n value !== undefined ? value?.from : defaultValue?.from,\n );\n const lastEmittedToRef = useRef<Date | undefined>(\n value !== undefined ? value?.to : defaultValue?.to,\n );\n const wasControlledRef = useRef(value !== undefined);\n\n const confirmedFrom = isControlled ? value?.from : internalFrom;\n const confirmedTo = isControlled ? value?.to : internalTo;\n const filled = inputValue.length > 0;\n\n const [month, setMonth] = useState<Date>(() => {\n const init = confirmedFrom ?? confirmedTo;\n return init && isValid(init) ? init : new Date();\n });\n const monthAnchor = confirmedFrom ?? confirmedTo;\n useEffect(() => {\n if (monthAnchor && isValid(monthAnchor)) setMonth(monthAnchor);\n }, [monthAnchor?.getFullYear(), monthAnchor?.getMonth()]); // eslint-disable-line react-hooks/exhaustive-deps\n\n const close = useCallback(() => {\n setOpen(false);\n setAnchorDate(undefined);\n setHoveredDate(undefined);\n }, []);\n useClickOutside(containerRef, close);\n\n // Sync inputValue when value changes externally (e.g. form reset)\n useEffect(() => {\n if (value !== undefined) wasControlledRef.current = true;\n const newFrom = value?.from;\n const newTo = value?.to;\n const fromTime = newFrom?.getTime() ?? null;\n const toTime = newTo?.getTime() ?? null;\n const lastFromTime = lastEmittedFromRef.current?.getTime() ?? null;\n const lastToTime = lastEmittedToRef.current?.getTime() ?? null;\n if (fromTime === lastFromTime && toTime === lastToTime) return;\n if (!wasControlledRef.current && value === undefined) return;\n\n setInputValue(formatRange(newFrom, newTo, schema));\n setInputInvalid(false);\n if (!isControlled) {\n setInternalFrom(newFrom);\n setInternalTo(newTo);\n }\n setAnchorDate(undefined);\n setHoveredDate(undefined);\n lastEmittedFromRef.current = newFrom;\n lastEmittedToRef.current = newTo;\n }, [value]); // eslint-disable-line react-hooks/exhaustive-deps\n\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 function handleDayClick(day: Date) {\n if (!anchorDate) {\n const from = showTime\n ? new Date(\n day.getFullYear(),\n day.getMonth(),\n day.getDate(),\n confirmedFrom?.getHours() ?? 0,\n confirmedFrom?.getMinutes() ?? 0,\n confirmedFrom?.getSeconds() ?? 0,\n )\n : toDateOnly(day);\n setAnchorDate(from);\n if (!isControlled) {\n setInternalFrom(from);\n setInternalTo(undefined);\n }\n setInputValue(formatRange(from, undefined, schema));\n setInputInvalid(false);\n lastEmittedFromRef.current = from;\n lastEmittedToRef.current = undefined;\n onChange?.({ from, to: undefined });\n } else {\n let from = anchorDate,\n to = showTime\n ? new Date(\n day.getFullYear(),\n day.getMonth(),\n day.getDate(),\n confirmedTo?.getHours() ?? 0,\n confirmedTo?.getMinutes() ?? 0,\n confirmedTo?.getSeconds() ?? 0,\n )\n : toDateOnly(day);\n if (day < anchorDate) {\n const tmp = from;\n from = to;\n to = tmp;\n }\n if (!isControlled) {\n setInternalFrom(from);\n setInternalTo(to);\n }\n setInputValue(formatRange(from, to, schema));\n setInputInvalid(false);\n lastEmittedFromRef.current = from;\n lastEmittedToRef.current = to;\n onChange?.({ from, to });\n if (!showTime) close();\n else setAnchorDate(undefined);\n }\n }\n\n function handleDayMouseEnter(day: Date) {\n if (anchorDate) setHoveredDate(day);\n }\n\n function handleFromTimeChange(h: number, m: number, s: number) {\n const base = confirmedFrom ?? new Date();\n const newDate = new Date(\n base.getFullYear(),\n base.getMonth(),\n base.getDate(),\n h,\n m,\n s,\n );\n if (!isControlled) setInternalFrom(newDate);\n lastEmittedFromRef.current = newDate;\n onChange?.({ from: newDate, to: confirmedTo });\n }\n\n function handleToTimeChange(h: number, m: number, s: number) {\n const base = confirmedTo ?? new Date();\n const newDate = new Date(\n base.getFullYear(),\n base.getMonth(),\n base.getDate(),\n h,\n m,\n s,\n );\n if (!isControlled) setInternalTo(newDate);\n lastEmittedToRef.current = newDate;\n onChange?.({ from: confirmedFrom, to: newDate });\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, totalDigits);\n const masked = applyRangeMask(digits, schema);\n const digitsBeforeCursor = raw\n .slice(0, cursorPos)\n .replace(/\\D/g, '').length;\n\n setInputValue(masked);\n setAnchorDate(undefined);\n setHoveredDate(undefined);\n\n const fromDigits = digits.slice(0, maxDigits);\n const toDigits = digits.slice(maxDigits);\n const parsedFrom =\n fromDigits.length === maxDigits\n ? parseDate(applyDateMask(fromDigits, schema), schema)\n : undefined;\n const parsedTo =\n toDigits.length === maxDigits\n ? parseDate(applyDateMask(toDigits, schema), schema)\n : undefined;\n const fromComplete = fromDigits.length === maxDigits;\n const toComplete = toDigits.length === maxDigits;\n setInputInvalid((fromComplete && !parsedFrom) || (toComplete && !parsedTo));\n\n if (!isControlled) {\n setInternalFrom(parsedFrom);\n setInternalTo(parsedTo);\n }\n lastEmittedFromRef.current = parsedFrom;\n lastEmittedToRef.current = parsedTo;\n onChange?.(\n parsedFrom || parsedTo ? { from: parsedFrom, to: parsedTo } : undefined,\n );\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 const separatorChars = new Set<string>([' ', '—']);\n schema.separators.forEach((s) => {\n for (const ch of s.chars) separatorChars.add(ch);\n });\n if (\n e.key === 'Backspace' &&\n pos > 0 &&\n separatorChars.has(input.value[pos - 1])\n ) {\n e.preventDefault();\n const val = input.value;\n const charsToSkip =\n val.slice(0, pos).match(/[\\s—]+$/)?.[0].length ?? 1;\n const newPos = pos - charsToSkip;\n const masked = applyRangeMask(\n (val.slice(0, newPos - 1) + val.slice(newPos)).replace(/\\D/g, ''),\n schema,\n );\n setInputValue(masked);\n requestAnimationFrame(() =>\n input.setSelectionRange(newPos - 1, newPos - 1),\n );\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, totalDigits);\n const masked = applyRangeMask(digits, schema);\n setInputValue(masked);\n setAnchorDate(undefined);\n setHoveredDate(undefined);\n\n const parsedFrom =\n digits.length >= maxDigits\n ? parseDate(applyDateMask(digits.slice(0, maxDigits), schema), schema)\n : undefined;\n const parsedTo =\n digits.length >= totalDigits\n ? parseDate(\n applyDateMask(digits.slice(maxDigits, totalDigits), schema),\n schema,\n )\n : undefined;\n setInputInvalid(\n (digits.length >= maxDigits && !parsedFrom) ||\n (digits.length >= totalDigits && !parsedTo),\n );\n if (!isControlled) {\n setInternalFrom(parsedFrom);\n setInternalTo(parsedTo);\n }\n lastEmittedFromRef.current = parsedFrom;\n lastEmittedToRef.current = parsedTo;\n onChange?.(\n parsedFrom || parsedTo ? { from: parsedFrom, to: parsedTo } : undefined,\n );\n\n requestAnimationFrame(() =>\n inputRef.current?.setSelectionRange(masked.length, masked.length),\n );\n }\n\n const placeholder =\n label && !focused && !filled\n ? undefined\n : `${schema.placeholder} — ${schema.placeholder}`;\n const interactive = !disabled && !loading;\n\n return (\n <div\n ref={containerRef}\n className={[\n 'datepicker',\n 'daterangepicker',\n `datepicker--${size}`,\n className,\n ]\n .filter(Boolean)\n .join(' ')}\n data-focused={focused || open || undefined}\n data-filled={filled || undefined}\n data-failed={failed || inputInvalid || undefined}\n data-disabled={!interactive || undefined}\n >\n <div\n className=\"datepicker__field\"\n data-icon-start={\n resolvedIcon && iconPosition === 'start' ? true : undefined\n }\n data-icon-end={\n resolvedIcon && iconPosition === 'end' ? true : undefined\n }\n onClick={() => interactive && inputRef.current?.focus()}\n >\n {resolvedIcon && iconPosition === 'start' && (\n <span className=\"datepicker__icon datepicker__icon--start\">\n {resolvedIcon}\n </span>\n )}\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={!interactive}\n onChange={handleChange}\n onKeyDown={handleKeyDown}\n onPaste={handlePaste}\n onFocus={() => {\n setFocused(true);\n if (interactive) setOpen(true);\n }}\n onBlur={() => setFocused(false)}\n aria-label={label ?? 'Выберите период'}\n aria-expanded={open}\n aria-haspopup=\"dialog\"\n aria-invalid={inputInvalid || undefined}\n />\n {resolvedIcon && iconPosition === 'end' && (\n <span className=\"datepicker__icon datepicker__icon--end\">\n {resolvedIcon}\n </span>\n )}\n </div>\n {open && (\n <div\n className={[\n 'datepicker__popover',\n `datepicker__popover--${size}`,\n calendarLayout === 'horizontal' &&\n 'datepicker__popover--horizontal',\n showTime && 'datepicker__popover--with-time',\n ]\n .filter(Boolean)\n .join(' ')}\n role=\"dialog\"\n aria-label=\"Выберите период\"\n >\n {showTime ? (\n <>\n <div className=\"datepicker__popover-body\">\n <div className=\"datepicker__popover-calendar\">\n <Calendar\n mode=\"range\"\n selected={calendarSelected}\n month={month}\n onMonthChange={setMonth}\n onSelect={() => {}}\n onDayClick={handleDayClick}\n onDayMouseEnter={handleDayMouseEnter}\n onDayMouseLeave={() => setHoveredDate(undefined)}\n startMonth={fromDay}\n endMonth={toDay}\n disabled={disabledDays.length ? disabledDays : undefined}\n numberOfMonths={2}\n locale={locale}\n />\n </div>\n </div>\n <div className=\"datepicker__time-row\">\n <div className=\"datepicker__time-col\">\n <span className=\"datepicker__time-label\">Начало</span>\n <TimePanel\n value={confirmedFrom}\n showSeconds={showSeconds}\n onChange={handleFromTimeChange}\n />\n </div>\n <div className=\"datepicker__time-separator\" />\n <div className=\"datepicker__time-col\">\n <span className=\"datepicker__time-label\">Конец</span>\n <TimePanel\n value={confirmedTo}\n showSeconds={showSeconds}\n onChange={handleToTimeChange}\n />\n </div>\n </div>\n <div className=\"datepicker__popover-footer\">\n <button\n className=\"datepicker__ok-btn\"\n type=\"button\"\n onClick={close}\n >\n OK\n </button>\n </div>\n </>\n ) : (\n <Calendar\n mode=\"range\"\n selected={calendarSelected}\n month={month}\n onMonthChange={setMonth}\n onSelect={() => {}}\n onDayClick={handleDayClick}\n onDayMouseEnter={handleDayMouseEnter}\n onDayMouseLeave={() => setHoveredDate(undefined)}\n startMonth={fromConstraint}\n endMonth={toConstraint}\n numberOfMonths={2}\n locale={locale}\n />\n )}\n </div>\n )}\n </div>\n );\n}\n","import { format, isValid, parse } from 'date-fns'\nimport type { DatePickerShowTime } from '../components/DatePicker/DatePicker'\nimport { applySchemaMask, type FormatSchema } from './format-schema'\n\nexport function applyDateMask(digits: string, schema: FormatSchema): string {\n return applySchemaMask(digits, schema)\n}\n\nexport function applyRangeMask(digits: string, schema: FormatSchema): string {\n const total = schema.digitCount * 2\n const all = digits.slice(0, total)\n const fromMasked = applyDateMask(all.slice(0, schema.digitCount), schema)\n const toDigits = all.slice(schema.digitCount)\n if (toDigits.length === 0) return fromMasked\n return `${fromMasked} — ${applyDateMask(toDigits, schema)}`\n}\n\nexport function 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\nexport function toDateOnly(date: Date): Date {\n return new Date(date.getFullYear(), date.getMonth(), date.getDate(), 12, 0, 0)\n}\n\nexport function parseDate(masked: string, schema: FormatSchema): Date | undefined {\n if (masked.replace(/\\D/g, '').length !== schema.digitCount) return undefined\n const date = parse(masked, schema.format, new Date())\n if (!isValid(date) || format(date, schema.format) !== masked) return undefined\n return toDateOnly(date)\n}\n\nexport function formatRange(\n from: Date | undefined,\n to: Date | undefined,\n schema: FormatSchema,\n): string {\n if (!from) return ''\n const fromStr = format(from, schema.format)\n if (!to) return fromStr\n return `${fromStr} — ${format(to, schema.format)}`\n}\n\nexport function resolveShowSeconds(showTime?: DatePickerShowTime): boolean {\n if (!showTime) return false\n if (showTime === true) return true\n return showTime.format === 'HH:mm:ss'\n}\n"],"mappings":"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","names":["useEffect","useRef","format","isValid","useEffect","jsx","jsx","jsxs","jsx","format","jsx","jsxs","isValid","format","useRef","useEffect","_a","useCallback","useEffect","useMemo","useRef","useState","isValid","startOfDay","ru","format","isValid","parse","toDateOnly","parse","isValid","format","Fragment","jsx","jsxs","ru","useMemo","startOfDay","useState","useRef","isValid","useEffect","useCallback","toDateOnly","_a"]}