lecom-ui 5.4.27 → 5.4.29

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.
@@ -63,7 +63,9 @@ const MultiSelect = React.forwardRef(
63
63
  const [selectedValues, setSelectedValues] = React.useState(value);
64
64
  const [isPopoverOpen, setIsPopoverOpen] = React.useState(false);
65
65
  const [query, setQuery] = React.useState("");
66
- const [dynamicMaxCount, setDynamicMaxCount] = React.useState(selectedValues.length || 1);
66
+ const [dynamicMaxCount, setDynamicMaxCount] = React.useState(
67
+ selectedValues.length || 1
68
+ );
67
69
  const buttonRef = React.useRef(null);
68
70
  React.useEffect(() => {
69
71
  const shallowEqual = (a, b) => {
@@ -341,7 +343,10 @@ const MultiSelect = React.forwardRef(
341
343
  if (!node.children || node.children.length === 0) {
342
344
  return [node.value];
343
345
  }
344
- return [node.value, ...node.children.flatMap((c) => collectAllValues(c))];
346
+ return [
347
+ node.value,
348
+ ...node.children.flatMap((c) => collectAllValues(c))
349
+ ];
345
350
  }
346
351
  };
347
352
  const isNodeFullySelected = (node) => {
@@ -522,35 +527,53 @@ const MultiSelect = React.forwardRef(
522
527
  disabled
523
528
  },
524
529
  selectedValues.length > 0 ? /* @__PURE__ */ React.createElement("div", { className: "flex justify-between items-center w-full" }, /* @__PURE__ */ React.createElement("div", { className: "flex flex-wrap items-center gap-1" }, selectedValues.slice(0, dynamicMaxCount).map((value2) => {
525
- const selectedOption = options.find((option) => option.value === value2);
530
+ const selectedOption = options.find(
531
+ (option) => option.value === value2
532
+ );
526
533
  const label = findTreeLabel(value2) || selectedOption?.label || value2;
527
534
  const prefix = selectedOption?.prefix;
528
- return /* @__PURE__ */ React.createElement(Tag, { key: value2, color: "blue", className: "focus:ring-0 flex items-center gap-2 max-w-[15.625rem]" }, /* @__PURE__ */ React.createElement("div", { className: "flex items-center gap-2 truncate min-w-0" }, prefix && /* @__PURE__ */ React.createElement(
529
- Typography,
530
- {
531
- className: "flex items-center flex-shrink-0 [&_svg]:text-blue-600",
532
- textColor: "text-blue-600"
533
- },
534
- prefix
535
- ), /* @__PURE__ */ React.createElement(
536
- Typography,
535
+ return /* @__PURE__ */ React.createElement(
536
+ Tag,
537
537
  {
538
- variant: getFontVariant(size),
539
- textColor: "text-blue-600",
540
- className: "truncate"
538
+ key: value2,
539
+ color: "blue",
540
+ className: "focus:ring-0 flex items-center gap-2 max-w-[15.625rem]"
541
541
  },
542
- label
543
- )), !disabled && /* @__PURE__ */ React.createElement(
544
- X,
545
- {
546
- className: "h-4 w-4 cursor-pointer flex-shrink-0",
547
- onClick: (event) => {
548
- event.stopPropagation();
549
- toggleOption(value2);
542
+ /* @__PURE__ */ React.createElement("div", { className: "flex items-center gap-2 truncate min-w-0" }, prefix && /* @__PURE__ */ React.createElement(
543
+ Typography,
544
+ {
545
+ className: "flex items-center flex-shrink-0 [&_svg]:text-blue-600",
546
+ textColor: "text-blue-600"
547
+ },
548
+ prefix
549
+ ), /* @__PURE__ */ React.createElement(
550
+ Typography,
551
+ {
552
+ variant: getFontVariant(size),
553
+ textColor: "text-blue-600",
554
+ className: "truncate"
555
+ },
556
+ label
557
+ )),
558
+ !disabled && /* @__PURE__ */ React.createElement(
559
+ X,
560
+ {
561
+ className: "h-4 w-4 cursor-pointer flex-shrink-0",
562
+ onClick: (event) => {
563
+ event.stopPropagation();
564
+ toggleOption(value2);
565
+ }
550
566
  }
551
- }
552
- ));
553
- }), selectedValues.length > dynamicMaxCount && /* @__PURE__ */ React.createElement(Tag, { color: "blue", className: "focus:ring-0" }, /* @__PURE__ */ React.createElement(Typography, { variant: getFontVariant(size), className: "text-blue-600" }, `+ ${selectedValues.length - dynamicMaxCount}`))), /* @__PURE__ */ React.createElement("div", { className: "flex items-center justify-between" }, !disabled && /* @__PURE__ */ React.createElement(React.Fragment, null, /* @__PURE__ */ React.createElement(
567
+ )
568
+ );
569
+ }), selectedValues.length > dynamicMaxCount && /* @__PURE__ */ React.createElement(Tag, { color: "blue", className: "focus:ring-0" }, /* @__PURE__ */ React.createElement(
570
+ Typography,
571
+ {
572
+ variant: getFontVariant(size),
573
+ className: "text-blue-600"
574
+ },
575
+ `+ ${selectedValues.length - dynamicMaxCount}`
576
+ ))), /* @__PURE__ */ React.createElement("div", { className: "flex items-center justify-between" }, !disabled && /* @__PURE__ */ React.createElement(React.Fragment, null, /* @__PURE__ */ React.createElement(
554
577
  X,
555
578
  {
556
579
  className: "h-4 w-4 cursor-pointer text-grey-800",
@@ -569,7 +592,7 @@ const MultiSelect = React.forwardRef(
569
592
  Typography,
570
593
  {
571
594
  variant: getFontVariant(size),
572
- className: "text-grey-800 mx-3"
595
+ className: "text-grey-500 mx-3"
573
596
  },
574
597
  placeholder
575
598
  ), isPopoverOpen ? /* @__PURE__ */ React.createElement(ChevronUp, { className: "h-4 cursor-pointer text-grey-800 mx-2" }) : /* @__PURE__ */ React.createElement(ChevronDown, { className: "h-4 cursor-pointer text-grey-800 mx-2" }))
@@ -586,114 +609,155 @@ const MultiSelect = React.forwardRef(
586
609
  align: "start",
587
610
  onEscapeKeyDown: () => setIsPopoverOpen(false)
588
611
  },
589
- !isTree && /* @__PURE__ */ React.createElement(Command, { shouldFilter: false, className: SEARCH_INPUT_CLASSES[size] }, /* @__PURE__ */ React.createElement(
590
- CommandInput,
591
- {
592
- placeholder: treeSearchPlaceholder || t("multiSelect.search"),
593
- onKeyDown: handleInputKeyDown,
594
- value: query,
595
- onValueChange: (v) => setQuery(v)
596
- }
597
- ), /* @__PURE__ */ React.createElement(CommandList, null, /* @__PURE__ */ React.createElement(CommandGroup, null, (effectiveOptions.length === 0 || query && filteredOptions.length === 0) && /* @__PURE__ */ React.createElement(CommandEmpty, { className: cn("p-4 text-center text-grey-800", getFontVariant(size)) }, t("multiSelect.empty")), !query && effectiveOptions.length > 0 && /* @__PURE__ */ React.createElement(
598
- CommandItem,
612
+ !isTree && /* @__PURE__ */ React.createElement(
613
+ Command,
599
614
  {
600
- key: "all",
601
- onSelect: toggleAll,
602
- className: "cursor-pointer"
615
+ shouldFilter: false,
616
+ className: SEARCH_INPUT_CLASSES[size]
603
617
  },
604
618
  /* @__PURE__ */ React.createElement(
605
- "div",
619
+ CommandInput,
606
620
  {
607
- className: cn(
608
- "flex h-4 w-4 items-center justify-center rounded-sm border border-grey-800",
609
- selectedValues.length > 0 ? "bg-blue-600 border-blue-600 text-primary-foreground" : "opacity-50 [&_svg]:invisible"
610
- )
611
- },
612
- selectedValues.length === effectiveOptions.length ? /* @__PURE__ */ React.createElement(Check, { className: "!h-3 !w-3 !text-white", strokeWidth: 3 }) : /* @__PURE__ */ React.createElement(Minus, { className: "!h-3 !w-3 !text-white", strokeWidth: 3 })
621
+ placeholder: treeSearchPlaceholder || t("multiSelect.search"),
622
+ onKeyDown: handleInputKeyDown,
623
+ value: query,
624
+ onValueChange: (v) => setQuery(v)
625
+ }
613
626
  ),
614
- /* @__PURE__ */ React.createElement(
615
- Typography,
627
+ /* @__PURE__ */ React.createElement(CommandList, null, /* @__PURE__ */ React.createElement(CommandGroup, null, (effectiveOptions.length === 0 || query && filteredOptions.length === 0) && /* @__PURE__ */ React.createElement(
628
+ CommandEmpty,
616
629
  {
617
- variant: getFontVariant(size),
618
- className: "text-grey-800"
619
- },
620
- selectAllLabel ?? t("multiSelect.selectAll")
621
- )
622
- ), isGrouped ? Object.entries(groupedOptions).map(
623
- ([categoryName, categoryOptions]) => {
624
- const filtered = categoryOptions.filter(
625
- (opt) => !query || effectiveOptions.some(
626
- (eff) => eff.value === opt.value && filteredOptions.some(
627
- (filt) => filt.value === opt.value
628
- )
630
+ className: cn(
631
+ "p-4 text-center text-grey-800",
632
+ getFontVariant(size)
629
633
  )
630
- );
631
- if (!filtered.length) return null;
632
- return /* @__PURE__ */ React.createElement("div", { key: categoryName }, /* @__PURE__ */ React.createElement("div", { className: "px-2 py-2 text-xs font-medium text-muted-foreground" }, categoryName), filtered.map((option) => {
633
- const isSelected = selectedValues.includes(
634
- option.value
635
- );
636
- return /* @__PURE__ */ React.createElement(
637
- CommandItem,
638
- {
639
- key: option.value,
640
- onSelect: () => toggleOption(option.value),
641
- className: "cursor-pointer"
642
- },
643
- /* @__PURE__ */ React.createElement(
644
- "div",
645
- {
646
- className: cn(
647
- "flex h-4 w-4 items-center justify-center rounded-sm border-2 border-grey-400 flex-shrink-0",
648
- isSelected ? "bg-blue-600 border-blue-600 text-primary-foreground" : "opacity-50 [&_svg]:invisible"
649
- )
650
- },
651
- /* @__PURE__ */ React.createElement(Check, { className: "!h-3 !w-3 !text-white", strokeWidth: 3 })
652
- ),
653
- /* @__PURE__ */ React.createElement("div", { className: "flex items-center gap-2 truncate min-w-0" }, option.prefix && /* @__PURE__ */ React.createElement(Typography, { className: "flex items-center flex-shrink-0" }, option.prefix), /* @__PURE__ */ React.createElement(
654
- Typography,
655
- {
656
- variant: getFontVariant(size),
657
- className: "text-grey-800 truncate overflow-hidden",
658
- title: option.label
659
- },
660
- highlight(option.label, query)
661
- ))
662
- );
663
- }));
664
- }
665
- ) : filteredOptions.map((option) => {
666
- const isSelected = selectedValues.includes(
667
- option.value
668
- );
669
- return /* @__PURE__ */ React.createElement(
634
+ },
635
+ t("multiSelect.empty")
636
+ ), !query && effectiveOptions.length > 0 && /* @__PURE__ */ React.createElement(
670
637
  CommandItem,
671
638
  {
672
- key: option.value,
673
- onSelect: () => toggleOption(option.value),
639
+ key: "all",
640
+ onSelect: toggleAll,
674
641
  className: "cursor-pointer"
675
642
  },
676
643
  /* @__PURE__ */ React.createElement(
677
644
  "div",
678
645
  {
679
646
  className: cn(
680
- "flex h-4 w-4 items-center justify-center rounded-sm border border-grey-800 flex-shrink-0",
681
- isSelected ? "bg-blue-600 border-blue-600 text-primary-foreground" : "opacity-50 [&_svg]:invisible"
647
+ "flex h-4 w-4 items-center justify-center rounded-sm border border-grey-800",
648
+ selectedValues.length > 0 ? "bg-blue-600 border-blue-600 text-primary-foreground" : "opacity-50 [&_svg]:invisible"
682
649
  )
683
650
  },
684
- /* @__PURE__ */ React.createElement(Check, { className: "!h-3 !w-3 !text-white", strokeWidth: 3 })
651
+ selectedValues.length === effectiveOptions.length ? /* @__PURE__ */ React.createElement(
652
+ Check,
653
+ {
654
+ className: "!h-3 !w-3 !text-white",
655
+ strokeWidth: 3
656
+ }
657
+ ) : /* @__PURE__ */ React.createElement(
658
+ Minus,
659
+ {
660
+ className: "!h-3 !w-3 !text-white",
661
+ strokeWidth: 3
662
+ }
663
+ )
685
664
  ),
686
- /* @__PURE__ */ React.createElement("div", { className: "flex items-center gap-2 truncate min-w-0" }, option.prefix && /* @__PURE__ */ React.createElement(Typography, { className: "flex items-center flex-shrink-0" }, option.prefix), /* @__PURE__ */ React.createElement(
665
+ /* @__PURE__ */ React.createElement(
687
666
  Typography,
688
667
  {
689
668
  variant: getFontVariant(size),
690
- className: "text-grey-800 truncate overflow-hidden",
691
- title: option.label
669
+ className: "text-grey-800"
692
670
  },
693
- highlight(option.label, query)
694
- ))
695
- );
696
- })))),
671
+ selectAllLabel ?? t("multiSelect.selectAll")
672
+ )
673
+ ), isGrouped ? Object.entries(groupedOptions).map(
674
+ ([categoryName, categoryOptions]) => {
675
+ const filtered = categoryOptions.filter(
676
+ (opt) => !query || effectiveOptions.some(
677
+ (eff) => eff.value === opt.value && filteredOptions.some(
678
+ (filt) => filt.value === opt.value
679
+ )
680
+ )
681
+ );
682
+ if (!filtered.length) return null;
683
+ return /* @__PURE__ */ React.createElement("div", { key: categoryName }, /* @__PURE__ */ React.createElement("div", { className: "px-2 py-2 text-xs font-medium text-muted-foreground" }, categoryName), filtered.map((option) => {
684
+ const isSelected = selectedValues.includes(
685
+ option.value
686
+ );
687
+ return /* @__PURE__ */ React.createElement(
688
+ CommandItem,
689
+ {
690
+ key: option.value,
691
+ onSelect: () => toggleOption(option.value),
692
+ className: "cursor-pointer"
693
+ },
694
+ /* @__PURE__ */ React.createElement(
695
+ "div",
696
+ {
697
+ className: cn(
698
+ "flex h-4 w-4 items-center justify-center rounded-sm border-2 border-grey-400 flex-shrink-0",
699
+ isSelected ? "bg-blue-600 border-blue-600 text-primary-foreground" : "opacity-50 [&_svg]:invisible"
700
+ )
701
+ },
702
+ /* @__PURE__ */ React.createElement(
703
+ Check,
704
+ {
705
+ className: "!h-3 !w-3 !text-white",
706
+ strokeWidth: 3
707
+ }
708
+ )
709
+ ),
710
+ /* @__PURE__ */ React.createElement("div", { className: "flex items-center gap-2 truncate min-w-0" }, option.prefix && /* @__PURE__ */ React.createElement(Typography, { className: "flex items-center flex-shrink-0" }, option.prefix), /* @__PURE__ */ React.createElement(
711
+ Typography,
712
+ {
713
+ variant: getFontVariant(size),
714
+ className: "text-grey-800 truncate overflow-hidden",
715
+ title: option.label
716
+ },
717
+ highlight(option.label, query)
718
+ ))
719
+ );
720
+ }));
721
+ }
722
+ ) : filteredOptions.map((option) => {
723
+ const isSelected = selectedValues.includes(
724
+ option.value
725
+ );
726
+ return /* @__PURE__ */ React.createElement(
727
+ CommandItem,
728
+ {
729
+ key: option.value,
730
+ onSelect: () => toggleOption(option.value),
731
+ className: "cursor-pointer"
732
+ },
733
+ /* @__PURE__ */ React.createElement(
734
+ "div",
735
+ {
736
+ className: cn(
737
+ "flex h-4 w-4 items-center justify-center rounded-sm border border-grey-800 flex-shrink-0",
738
+ isSelected ? "bg-blue-600 border-blue-600 text-primary-foreground" : "opacity-50 [&_svg]:invisible"
739
+ )
740
+ },
741
+ /* @__PURE__ */ React.createElement(
742
+ Check,
743
+ {
744
+ className: "!h-3 !w-3 !text-white",
745
+ strokeWidth: 3
746
+ }
747
+ )
748
+ ),
749
+ /* @__PURE__ */ React.createElement("div", { className: "flex items-center gap-2 truncate min-w-0" }, option.prefix && /* @__PURE__ */ React.createElement(Typography, { className: "flex items-center flex-shrink-0" }, option.prefix), /* @__PURE__ */ React.createElement(
750
+ Typography,
751
+ {
752
+ variant: getFontVariant(size),
753
+ className: "text-grey-800 truncate overflow-hidden",
754
+ title: option.label
755
+ },
756
+ highlight(option.label, query)
757
+ ))
758
+ );
759
+ })))
760
+ ),
697
761
  isTree && /* @__PURE__ */ React.createElement("div", { className: "min-w-[260px] max-h-80 overflow-hidden flex flex-col" }, treeSearch && /* @__PURE__ */ React.createElement("div", { className: "px-1 pt-2 pb-0 border-b border-grey-300 flex-shrink-0" }, /* @__PURE__ */ React.createElement("div", { className: "relative" }, /* @__PURE__ */ React.createElement(
698
762
  "svg",
699
763
  {
@@ -748,7 +812,19 @@ const MultiSelect = React.forwardRef(
748
812
  acc += treeSelectionStrategy === "all" ? 1 + countAll(n.children) : countAll(n.children);
749
813
  }
750
814
  return acc;
751
- }(treeOptions) ? /* @__PURE__ */ React.createElement(Check, { className: "!h-3 !w-3 !text-white", strokeWidth: 3 }) : /* @__PURE__ */ React.createElement(Minus, { className: "!h-3 !w-3 !text-white", strokeWidth: 3 })
815
+ }(treeOptions) ? /* @__PURE__ */ React.createElement(
816
+ Check,
817
+ {
818
+ className: "!h-3 !w-3 !text-white",
819
+ strokeWidth: 3
820
+ }
821
+ ) : /* @__PURE__ */ React.createElement(
822
+ Minus,
823
+ {
824
+ className: "!h-3 !w-3 !text-white",
825
+ strokeWidth: 3
826
+ }
827
+ )
752
828
  ),
753
829
  /* @__PURE__ */ React.createElement(
754
830
  Typography,
@@ -758,7 +834,16 @@ const MultiSelect = React.forwardRef(
758
834
  },
759
835
  selectAllLabel ?? t("multiSelect.selectAll")
760
836
  )
761
- ), !treeOptions || treeOptions.length === 0 || treeQuery && displayedTree.length === 0 ? /* @__PURE__ */ React.createElement("div", { className: cn("p-4 text-center text-grey-800", getFontVariant(size)) }, t("multiSelect.empty")) : renderTree(displayedTree)))
837
+ ), !treeOptions || treeOptions.length === 0 || treeQuery && displayedTree.length === 0 ? /* @__PURE__ */ React.createElement(
838
+ "div",
839
+ {
840
+ className: cn(
841
+ "p-4 text-center text-grey-800",
842
+ getFontVariant(size)
843
+ )
844
+ },
845
+ t("multiSelect.empty")
846
+ ) : renderTree(displayedTree)))
762
847
  )
763
848
  );
764
849
  }
@@ -13,15 +13,31 @@ function TagItem({ item, onRemove, readOnly }) {
13
13
  },
14
14
  [item.value, onRemove]
15
15
  );
16
- return /* @__PURE__ */ React.createElement(Tag, { "data-tag": "true", color: "blue", className: "max-w-[15.625rem] h-6 !px-2 !py-0.5" }, /* @__PURE__ */ React.createElement(Typography, { variant: "body-small-400", className: "text-blue-600 truncate p-0" }, item.label), !readOnly && /* @__PURE__ */ React.createElement(
17
- X,
16
+ return /* @__PURE__ */ React.createElement(
17
+ Tag,
18
18
  {
19
- className: "w-4 h-4 cursor-pointer flex-shrink-0",
20
- onClick: handleRemove,
21
- "aria-label": `Remover ${item.label}`,
22
- tabIndex: 0
23
- }
24
- ));
19
+ "data-tag": "true",
20
+ color: "blue",
21
+ className: "max-w-[15.625rem] h-6 !px-2 !py-0.5"
22
+ },
23
+ /* @__PURE__ */ React.createElement(
24
+ Typography,
25
+ {
26
+ variant: "body-small-400",
27
+ className: "text-blue-600 truncate p-0"
28
+ },
29
+ item.label
30
+ ),
31
+ !readOnly && /* @__PURE__ */ React.createElement(
32
+ X,
33
+ {
34
+ className: "w-4 h-4 cursor-pointer flex-shrink-0",
35
+ onClick: handleRemove,
36
+ "aria-label": `Remover ${item.label}`,
37
+ tabIndex: 0
38
+ }
39
+ )
40
+ );
25
41
  }
26
42
  function HiddenCountTag({ count }) {
27
43
  return /* @__PURE__ */ React.createElement(Tag, { color: "blue", "data-tag": "true" }, /* @__PURE__ */ React.createElement(Typography, { variant: "body-small-400", className: "text-blue-600" }, "+", count));
@@ -69,7 +85,8 @@ function useDynamicMaxCount(ref, value, maxDisplayCount) {
69
85
  const [maxLines, setMaxLines] = React.useState(null);
70
86
  const hasCalculatedMaxLines = React.useRef(false);
71
87
  React.useEffect(() => {
72
- if (hasCalculatedMaxLines.current || !ref.current || value.length === 0) return;
88
+ if (hasCalculatedMaxLines.current || !ref.current || value.length === 0)
89
+ return;
73
90
  const calculateMaxLines = () => {
74
91
  if (!ref.current) {
75
92
  setTimeout(calculateMaxLines, 10);
@@ -83,7 +100,10 @@ function useDynamicMaxCount(ref, value, maxDisplayCount) {
83
100
  const TAG_HEIGHT = 24;
84
101
  const CONTAINER_PADDING_VERTICAL = 4;
85
102
  const availableHeight = containerHeight - CONTAINER_PADDING_VERTICAL * 2;
86
- const calculatedMaxLines = Math.max(1, Math.floor(availableHeight / TAG_HEIGHT));
103
+ const calculatedMaxLines = Math.max(
104
+ 1,
105
+ Math.floor(availableHeight / TAG_HEIGHT)
106
+ );
87
107
  setMaxLines(calculatedMaxLines);
88
108
  hasCalculatedMaxLines.current = true;
89
109
  };
@@ -126,7 +146,11 @@ function useDynamicMaxCount(ref, value, maxDisplayCount) {
126
146
  setDynamicMaxCount(value.length);
127
147
  return;
128
148
  }
129
- const count = simulateTagLayout(estimatedWidths, availableWidth, maxLines);
149
+ const count = simulateTagLayout(
150
+ estimatedWidths,
151
+ availableWidth,
152
+ maxLines
153
+ );
130
154
  setDynamicMaxCount(count);
131
155
  };
132
156
  const rafId = requestAnimationFrame(() => {
@@ -192,7 +216,7 @@ function TagInput(props) {
192
216
  style: containerStyles,
193
217
  ...restProps
194
218
  },
195
- value.length === 0 && /* @__PURE__ */ React.createElement(Typography, { variant: "body-small-400", className: "text-grey-400" }, placeholder),
219
+ value.length === 0 && /* @__PURE__ */ React.createElement(Typography, { variant: "body-small-400", className: "text-grey-500" }, placeholder),
196
220
  displayTags.map((item) => /* @__PURE__ */ React.createElement(
197
221
  TagItem,
198
222
  {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "lecom-ui",
3
- "version": "5.4.27",
3
+ "version": "5.4.29",
4
4
  "license": "MIT",
5
5
  "type": "module",
6
6
  "module": "dist/index.js",
@@ -50,7 +50,7 @@
50
50
  "hex-color-opacity": "^0.4.2",
51
51
  "i18next": "^24.2.2",
52
52
  "lucide-react": "^0.488.0",
53
- "next": "^15.1.4",
53
+ "next": "15.5.9",
54
54
  "react": ">=18.0.0",
55
55
  "react-colorful": "^5.6.1",
56
56
  "react-day-picker": "^9.8.0",