@hh.ru/magritte-ui-input 9.0.12 → 9.1.1

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.
@@ -722,6 +722,20 @@ function countDigits(str) {
722
722
  return str.replaceAll(/\W/g, '').length;
723
723
  }
724
724
 
725
+ function appendDate(initialDate, { day, month, year } = {}) {
726
+ const date = new Date(initialDate);
727
+ if (day) {
728
+ date.setDate(date.getDate() + day);
729
+ }
730
+ if (month) {
731
+ date.setMonth(date.getMonth() + month);
732
+ }
733
+ if (year) {
734
+ date.setFullYear(date.getFullYear() + year);
735
+ }
736
+ return date;
737
+ }
738
+
725
739
  const getDateSegmentValueLength = (dateString) => {
726
740
  var _a, _b, _c;
727
741
  return ({
@@ -830,6 +844,45 @@ const TIME_SEGMENT_VALUE_LENGTHS = {
830
844
  seconds: 2,
831
845
  milliseconds: 3,
832
846
  };
847
+
848
+ /**
849
+ * {@link https://unicode-table.com/en/00A0/ Non-breaking space}.
850
+ */
851
+ const CHAR_NO_BREAK_SPACE = '\u00A0';
852
+ /**
853
+ * {@link https://unicode-table.com/en/2013/ EN dash}
854
+ * is used to indicate a range of numbers or a span of time.
855
+ * @example 2006–2022
856
+ */
857
+ const CHAR_EN_DASH = '\u2013';
858
+ /**
859
+ * {@link https://unicode-table.com/en/2014/ EM dash}
860
+ * is used to mark a break in a sentence.
861
+ * @example Taiga UI — powerful set of open source components for Angular
862
+ * ___
863
+ * Don't confuse with {@link CHAR_EN_DASH} or {@link CHAR_HYPHEN}!
864
+ */
865
+ const CHAR_EM_DASH = '\u2014';
866
+ /**
867
+ * {@link https://unicode-table.com/en/002D/ Hyphen (minus sign)}
868
+ * is used to combine words.
869
+ * @example well-behaved
870
+ * ___
871
+ * Don't confuse with {@link CHAR_EN_DASH} or {@link CHAR_EM_DASH}!
872
+ */
873
+ const CHAR_HYPHEN = '\u002D';
874
+ /**
875
+ * {@link https://unicode-table.com/en/2212/ Minus}
876
+ * is used as math operator symbol or before negative digits.
877
+ * ---
878
+ * Can be used as `−`. Don't confuse with {@link CHAR_HYPHEN}
879
+ */
880
+ const CHAR_MINUS = '\u2212';
881
+ /**
882
+ * {@link https://symbl.cc/en/30FC/ Katakana-Hiragana Prolonged Sound Mark}
883
+ * is used as prolonged sounds in Japanese.
884
+ */
885
+ const CHAR_JP_HYPHEN = '\u30FC';
833
886
  /**
834
887
  * {@link https://symbl.cc/en/003A/ Colon}
835
888
  * is a punctuation mark that connects parts of a text logically.
@@ -891,6 +944,14 @@ function escapeRegExp(str) {
891
944
  return str && reHasRegExpChar.test(str) ? str.replaceAll(reRegExpChar, '\\$&') : str;
892
945
  }
893
946
 
947
+ function identity(x) {
948
+ return x;
949
+ }
950
+
951
+ function isEmpty(entity) {
952
+ return !entity || (typeof entity === 'object' && Object.keys(entity).length === 0);
953
+ }
954
+
894
955
  function padWithZeroesUntilValid(segmentValue, paddedMaxValue, prefixedZeroesCount = 0) {
895
956
  if (Number(segmentValue.padEnd(paddedMaxValue.length, '0')) <= Number(paddedMaxValue)) {
896
957
  return { validatedSegmentValue: segmentValue, prefixedZeroesCount };
@@ -1270,6 +1331,122 @@ function maskitoDateOptionsGenerator({ mode, separator = '.', max, min, }) {
1270
1331
  ] });
1271
1332
  }
1272
1333
 
1334
+ const POSSIBLE_DATE_RANGE_SEPARATOR = [
1335
+ CHAR_HYPHEN,
1336
+ CHAR_EN_DASH,
1337
+ CHAR_EM_DASH,
1338
+ CHAR_MINUS,
1339
+ CHAR_JP_HYPHEN,
1340
+ ];
1341
+
1342
+ function createMinMaxRangeLengthPostprocessor({ dateModeTemplate, rangeSeparator, minLength, maxLength, max = DEFAULT_MAX_DATE, }) {
1343
+ if (isEmpty(minLength) && isEmpty(maxLength)) {
1344
+ return identity;
1345
+ }
1346
+ return ({ value, selection }) => {
1347
+ const dateStrings = parseDateRangeString(value, dateModeTemplate, rangeSeparator);
1348
+ if (dateStrings.length !== 2 ||
1349
+ dateStrings.some(date => !isDateStringComplete(date, dateModeTemplate))) {
1350
+ return { value, selection };
1351
+ }
1352
+ const [fromDate, toDate] = dateStrings.map(dateString => segmentsToDate(parseDateString(dateString, dateModeTemplate)));
1353
+ const minDistantToDate = appendDate(fromDate, Object.assign(Object.assign({}, minLength), {
1354
+ // 06.02.2023 - 07.02.2023 => {minLength: {day: 3}} => 06.02.2023 - 08.02.2023
1355
+ // "from"-day is included in the range
1356
+ day: (minLength === null || minLength === void 0 ? void 0 : minLength.day) && minLength.day - 1 }));
1357
+ const maxDistantToDate = !isEmpty(maxLength)
1358
+ ? appendDate(fromDate, Object.assign(Object.assign({}, maxLength), { day: (maxLength === null || maxLength === void 0 ? void 0 : maxLength.day) && maxLength.day - 1 }))
1359
+ : max;
1360
+ const minLengthClampedToDate = clamp(toDate, minDistantToDate, max);
1361
+ const minMaxLengthClampedToDate = minLengthClampedToDate > maxDistantToDate
1362
+ ? maxDistantToDate
1363
+ : minLengthClampedToDate;
1364
+ return {
1365
+ selection,
1366
+ value: dateStrings[0] +
1367
+ rangeSeparator +
1368
+ toDateString(dateToSegments(minMaxLengthClampedToDate), {
1369
+ dateMode: dateModeTemplate,
1370
+ }),
1371
+ };
1372
+ };
1373
+ }
1374
+
1375
+ function createSwapDatesPostprocessor({ dateModeTemplate, rangeSeparator, }) {
1376
+ return ({ value, selection }) => {
1377
+ const dateStrings = parseDateRangeString(value, dateModeTemplate, rangeSeparator);
1378
+ const isDateRangeComplete = dateStrings.length === 2 &&
1379
+ dateStrings.every(date => isDateStringComplete(date, dateModeTemplate));
1380
+ const [from, to] = selection;
1381
+ const caretAtTheEnd = from >= value.length;
1382
+ const allValueSelected = from === 0 && to >= value.length; // dropping text inside with a pointer
1383
+ if (!(caretAtTheEnd || allValueSelected) || !isDateRangeComplete) {
1384
+ return { value, selection };
1385
+ }
1386
+ const [fromDate, toDate] = dateStrings.map(dateString => segmentsToDate(parseDateString(dateString, dateModeTemplate)));
1387
+ return {
1388
+ selection,
1389
+ value: fromDate > toDate ? dateStrings.reverse().join(rangeSeparator) : value,
1390
+ };
1391
+ };
1392
+ }
1393
+
1394
+ function maskitoDateRangeOptionsGenerator({ mode, min, max, minLength, maxLength, dateSeparator = '.', rangeSeparator = `${CHAR_NO_BREAK_SPACE}${CHAR_EN_DASH}${CHAR_NO_BREAK_SPACE}`, }) {
1395
+ const dateModeTemplate = mode.split('/').join(dateSeparator);
1396
+ const dateMask = Array.from(dateModeTemplate).map(char => char === dateSeparator ? char : /\d/);
1397
+ return Object.assign(Object.assign({}, MASKITO_DEFAULT_OPTIONS), { mask: [...dateMask, ...Array.from(rangeSeparator), ...dateMask], overwriteMode: 'replace', preprocessors: [
1398
+ createFullWidthToHalfWidthPreprocessor(),
1399
+ createFirstDateEndSeparatorPreprocessor({
1400
+ dateModeTemplate,
1401
+ dateSegmentSeparator: dateSeparator,
1402
+ firstDateEndSeparator: rangeSeparator,
1403
+ pseudoFirstDateEndSeparators: POSSIBLE_DATE_RANGE_SEPARATOR,
1404
+ }),
1405
+ createZeroPlaceholdersPreprocessor(),
1406
+ normalizeDatePreprocessor({
1407
+ dateModeTemplate,
1408
+ rangeSeparator,
1409
+ dateSegmentsSeparator: dateSeparator,
1410
+ }),
1411
+ createValidDatePreprocessor({
1412
+ dateModeTemplate,
1413
+ rangeSeparator,
1414
+ dateSegmentsSeparator: dateSeparator,
1415
+ }),
1416
+ ], postprocessors: [
1417
+ createDateSegmentsZeroPaddingPostprocessor({
1418
+ dateModeTemplate,
1419
+ dateSegmentSeparator: dateSeparator,
1420
+ splitFn: value => ({
1421
+ dateStrings: parseDateRangeString(value, dateModeTemplate, rangeSeparator),
1422
+ }),
1423
+ uniteFn: (validatedDateStrings, initialValue) => validatedDateStrings.reduce((acc, dateString, dateIndex) => acc +
1424
+ dateString +
1425
+ (!dateIndex && initialValue.includes(rangeSeparator)
1426
+ ? rangeSeparator
1427
+ : ''), ''),
1428
+ }),
1429
+ createMinMaxDatePostprocessor({
1430
+ min,
1431
+ max,
1432
+ dateModeTemplate,
1433
+ rangeSeparator,
1434
+ dateSegmentSeparator: dateSeparator,
1435
+ }),
1436
+ createMinMaxRangeLengthPostprocessor({
1437
+ dateModeTemplate,
1438
+ minLength,
1439
+ maxLength,
1440
+ max,
1441
+ rangeSeparator,
1442
+ }),
1443
+ createSwapDatesPostprocessor({
1444
+ dateModeTemplate,
1445
+ rangeSeparator,
1446
+ }),
1447
+ ] });
1448
+ }
1449
+
1273
1450
  function padTimeSegments(timeSegments) {
1274
1451
  return Object.fromEntries(Object.entries(timeSegments).map(([segmentName, segmentValue]) => [
1275
1452
  segmentName,
@@ -1646,5 +1823,5 @@ const useMaskito = ({
1646
1823
  return onRefChange;
1647
1824
  };
1648
1825
 
1649
- export { MASKITO_DEFAULT_OPTIONS as M, maskitoDateTimeOptionsGenerator as a, maskitoTimeOptionsGenerator as b, maskitoDateOptionsGenerator as m, useMaskito as u };
1650
- //# sourceMappingURL=index.esm-LrCm-Ziw.js.map
1826
+ export { MASKITO_DEFAULT_OPTIONS as M, maskitoDateRangeOptionsGenerator as a, maskitoDateTimeOptionsGenerator as b, maskitoTimeOptionsGenerator as c, maskitoDateOptionsGenerator as m, useMaskito as u };
1827
+ //# sourceMappingURL=index.esm-CO13rGcB.js.map