lecom-ui 5.4.44 → 5.4.46

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.
@@ -7,6 +7,7 @@ import { Tag } from '../Tag/Tag.js';
7
7
  import { Typography } from '../Typography/Typography.js';
8
8
  import { cn } from '../../lib/utils.js';
9
9
  import { X, ChevronUp, ChevronDown, Check, Minus } from 'lucide-react';
10
+ import { useDynamicMaxHeight } from '../../hooks/useDynamicMaxHeight.js';
10
11
  import { initializeI18n } from '../../i18n/index.js';
11
12
 
12
13
  initializeI18n();
@@ -15,6 +16,10 @@ const TRIGGER_HEIGHT_CLASSES = {
15
16
  medium: "!h-10",
16
17
  large: "!h-12"
17
18
  };
19
+ const STATUS_STYLES = {
20
+ default: "border-grey-400 hover:border-grey-500 focus:border-grey-400 focus:ring-grey-600",
21
+ error: "border-red-600 hover:border-red-600 focus:border-red-600 focus:ring-0"
22
+ };
18
23
  const SEARCH_INPUT_HEIGHT_CLASSES = {
19
24
  small: "h-7",
20
25
  medium: "h-8",
@@ -58,7 +63,11 @@ const MultiSelect = React.forwardRef(
58
63
  classNameContent,
59
64
  size = "medium",
60
65
  disabled = false,
61
- readOnly = false
66
+ readOnly = false,
67
+ status = "default",
68
+ dynamicHeight = true,
69
+ dynamicHeightBottomPadding = 50,
70
+ dynamicHeightMinHeight = 120
62
71
  }, ref) => {
63
72
  const { t } = useTranslation();
64
73
  const [selectedValues, setSelectedValues] = React.useState(value);
@@ -68,6 +77,11 @@ const MultiSelect = React.forwardRef(
68
77
  selectedValues.length || 1
69
78
  );
70
79
  const buttonRef = React.useRef(null);
80
+ const { ref: dynamicHeightRef, style: dynamicHeightStyle } = useDynamicMaxHeight({
81
+ enabled: dynamicHeight && isPopoverOpen,
82
+ bottomPadding: dynamicHeightBottomPadding,
83
+ minHeight: dynamicHeightMinHeight
84
+ });
71
85
  React.useEffect(() => {
72
86
  const shallowEqual = (a, b) => {
73
87
  if (a === b) return true;
@@ -535,10 +549,10 @@ const MultiSelect = React.forwardRef(
535
549
  onClick: handleTogglePopover,
536
550
  className: cn(
537
551
  `flex w-full p-1 rounded-sm h-auto items-center justify-between bg-background
538
- border border-grey-400
539
- hover:border-grey-500 focus:border-grey-400 focus:ring-grey-600 focus:ring-opacity-15 focus:ring-4
552
+ border focus:ring-opacity-15 focus:ring-4
540
553
  transition-all duration-300 outline-none
541
554
  [&_svg]:pointer-events-auto`,
555
+ STATUS_STYLES[status],
542
556
  maxCount === void 0 && TRIGGER_HEIGHT_CLASSES[size],
543
557
  disabled && "opacity-50 cursor-not-allowed pointer-events-none",
544
558
  readOnly && !disabled && "opacity-50 hover:border-grey-400",
@@ -621,8 +635,10 @@ const MultiSelect = React.forwardRef(
621
635
  /* @__PURE__ */ React.createElement(
622
636
  PopoverContent,
623
637
  {
638
+ ref: dynamicHeightRef,
639
+ style: dynamicHeightStyle,
624
640
  className: cn(
625
- "p-0 max-h-80",
641
+ "p-0 flex flex-col overflow-hidden z-40",
626
642
  matchTriggerWidth && "w-[var(--radix-popover-trigger-width)]",
627
643
  classNameContent
628
644
  ),
@@ -634,7 +650,7 @@ const MultiSelect = React.forwardRef(
634
650
  Command,
635
651
  {
636
652
  shouldFilter: false,
637
- className: SEARCH_INPUT_CLASSES[size]
653
+ className: cn(SEARCH_INPUT_CLASSES[size], "max-h-full flex flex-col")
638
654
  },
639
655
  /* @__PURE__ */ React.createElement(
640
656
  CommandInput,
@@ -646,115 +662,25 @@ const MultiSelect = React.forwardRef(
646
662
  disabled: readOnly
647
663
  }
648
664
  ),
649
- /* @__PURE__ */ React.createElement(CommandList, null, /* @__PURE__ */ React.createElement(CommandGroup, null, (effectiveOptions.length === 0 || query && filteredOptions.length === 0) && /* @__PURE__ */ React.createElement(
650
- CommandEmpty,
651
- {
652
- className: cn(
653
- "p-4 text-center text-grey-800",
654
- getFontVariant(size)
655
- )
656
- },
657
- t("multiSelect.empty")
658
- ), !query && effectiveOptions.length > 0 && /* @__PURE__ */ React.createElement(
659
- CommandItem,
665
+ /* @__PURE__ */ React.createElement(
666
+ CommandList,
660
667
  {
661
- key: "all",
662
- onSelect: readOnly ? void 0 : toggleAll,
663
- className: cn(
664
- "cursor-pointer",
665
- readOnly && "cursor-default pointer-events-none hover:bg-transparent"
666
- )
668
+ className: "[&::-webkit-scrollbar]:w-1.5 [&::-webkit-scrollbar-track]:bg-transparent [&::-webkit-scrollbar-thumb]:bg-grey-300 [&::-webkit-scrollbar-thumb]:rounded-full [&::-webkit-scrollbar-thumb:hover]:bg-grey-400"
667
669
  },
668
- /* @__PURE__ */ React.createElement(
669
- "div",
670
+ /* @__PURE__ */ React.createElement(CommandGroup, null, (effectiveOptions.length === 0 || query && filteredOptions.length === 0) && /* @__PURE__ */ React.createElement(
671
+ CommandEmpty,
670
672
  {
671
673
  className: cn(
672
- "flex h-4 w-4 items-center justify-center rounded-sm border border-grey-800",
673
- selectedValues.length > 0 ? "bg-blue-600 border-blue-600 text-primary-foreground" : "opacity-50 [&_svg]:invisible"
674
+ "p-4 text-center text-grey-800",
675
+ getFontVariant(size)
674
676
  )
675
677
  },
676
- selectedValues.length === effectiveOptions.length ? /* @__PURE__ */ React.createElement(
677
- Check,
678
- {
679
- className: "!h-3 !w-3 !text-white",
680
- strokeWidth: 3
681
- }
682
- ) : /* @__PURE__ */ React.createElement(
683
- Minus,
684
- {
685
- className: "!h-3 !w-3 !text-white",
686
- strokeWidth: 3
687
- }
688
- )
689
- ),
690
- /* @__PURE__ */ React.createElement(
691
- Typography,
692
- {
693
- variant: getFontVariant(size),
694
- className: "text-grey-800"
695
- },
696
- selectAllLabel ?? t("multiSelect.selectAll")
697
- )
698
- ), isGrouped ? Object.entries(groupedOptions).map(
699
- ([categoryName, categoryOptions]) => {
700
- const filtered = categoryOptions.filter(
701
- (opt) => !query || effectiveOptions.some(
702
- (eff) => eff.value === opt.value && filteredOptions.some(
703
- (filt) => filt.value === opt.value
704
- )
705
- )
706
- );
707
- if (!filtered.length) return null;
708
- 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) => {
709
- const isSelected = selectedValues.includes(
710
- option.value
711
- );
712
- return /* @__PURE__ */ React.createElement(
713
- CommandItem,
714
- {
715
- key: option.value,
716
- onSelect: readOnly ? void 0 : () => toggleOption(option.value),
717
- className: cn(
718
- "cursor-pointer",
719
- readOnly && "cursor-default pointer-events-none hover:bg-transparent"
720
- )
721
- },
722
- /* @__PURE__ */ React.createElement(
723
- "div",
724
- {
725
- className: cn(
726
- "flex h-4 w-4 items-center justify-center rounded-sm border-2 border-grey-400 flex-shrink-0",
727
- isSelected ? "bg-blue-600 border-blue-600 text-primary-foreground" : "opacity-50 [&_svg]:invisible"
728
- )
729
- },
730
- /* @__PURE__ */ React.createElement(
731
- Check,
732
- {
733
- className: "!h-3 !w-3 !text-white",
734
- strokeWidth: 3
735
- }
736
- )
737
- ),
738
- /* @__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(
739
- Typography,
740
- {
741
- variant: getFontVariant(size),
742
- className: "text-grey-800 break-words"
743
- },
744
- highlight(option.label, query)
745
- ))
746
- );
747
- }));
748
- }
749
- ) : filteredOptions.map((option) => {
750
- const isSelected = selectedValues.includes(
751
- option.value
752
- );
753
- return /* @__PURE__ */ React.createElement(
678
+ t("multiSelect.empty")
679
+ ), !query && effectiveOptions.length > 0 && /* @__PURE__ */ React.createElement(
754
680
  CommandItem,
755
681
  {
756
- key: option.value,
757
- onSelect: readOnly ? void 0 : () => toggleOption(option.value),
682
+ key: "all",
683
+ onSelect: readOnly ? void 0 : toggleAll,
758
684
  className: cn(
759
685
  "cursor-pointer",
760
686
  readOnly && "cursor-default pointer-events-none hover:bg-transparent"
@@ -764,30 +690,126 @@ const MultiSelect = React.forwardRef(
764
690
  "div",
765
691
  {
766
692
  className: cn(
767
- "flex h-4 w-4 items-center justify-center rounded-sm border border-grey-800 flex-shrink-0",
768
- isSelected ? "bg-blue-600 border-blue-600 text-primary-foreground" : "opacity-50 [&_svg]:invisible"
693
+ "flex h-4 w-4 items-center justify-center rounded-sm border border-grey-800",
694
+ selectedValues.length > 0 ? "bg-blue-600 border-blue-600 text-primary-foreground" : "opacity-50 [&_svg]:invisible"
769
695
  )
770
696
  },
771
- /* @__PURE__ */ React.createElement(
697
+ selectedValues.length === effectiveOptions.length ? /* @__PURE__ */ React.createElement(
772
698
  Check,
773
699
  {
774
700
  className: "!h-3 !w-3 !text-white",
775
701
  strokeWidth: 3
776
702
  }
703
+ ) : /* @__PURE__ */ React.createElement(
704
+ Minus,
705
+ {
706
+ className: "!h-3 !w-3 !text-white",
707
+ strokeWidth: 3
708
+ }
777
709
  )
778
710
  ),
779
- /* @__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
+ /* @__PURE__ */ React.createElement(
780
712
  Typography,
781
713
  {
782
714
  variant: getFontVariant(size),
783
- className: "text-grey-800 break-words"
715
+ className: "text-grey-800"
784
716
  },
785
- highlight(option.label, query)
786
- ))
787
- );
788
- })))
717
+ selectAllLabel ?? t("multiSelect.selectAll")
718
+ )
719
+ ), isGrouped ? Object.entries(groupedOptions).map(
720
+ ([categoryName, categoryOptions]) => {
721
+ const filtered = categoryOptions.filter(
722
+ (opt) => !query || effectiveOptions.some(
723
+ (eff) => eff.value === opt.value && filteredOptions.some(
724
+ (filt) => filt.value === opt.value
725
+ )
726
+ )
727
+ );
728
+ if (!filtered.length) return null;
729
+ 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) => {
730
+ const isSelected = selectedValues.includes(
731
+ option.value
732
+ );
733
+ return /* @__PURE__ */ React.createElement(
734
+ CommandItem,
735
+ {
736
+ key: option.value,
737
+ onSelect: readOnly ? void 0 : () => toggleOption(option.value),
738
+ className: cn(
739
+ "cursor-pointer",
740
+ readOnly && "cursor-default pointer-events-none hover:bg-transparent"
741
+ )
742
+ },
743
+ /* @__PURE__ */ React.createElement(
744
+ "div",
745
+ {
746
+ className: cn(
747
+ "flex h-4 w-4 items-center justify-center rounded-sm border-2 border-grey-400 flex-shrink-0",
748
+ isSelected ? "bg-blue-600 border-blue-600 text-primary-foreground" : "opacity-50 [&_svg]:invisible"
749
+ )
750
+ },
751
+ /* @__PURE__ */ React.createElement(
752
+ Check,
753
+ {
754
+ className: "!h-3 !w-3 !text-white",
755
+ strokeWidth: 3
756
+ }
757
+ )
758
+ ),
759
+ /* @__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(
760
+ Typography,
761
+ {
762
+ variant: getFontVariant(size),
763
+ className: "text-grey-800 break-words"
764
+ },
765
+ highlight(option.label, query)
766
+ ))
767
+ );
768
+ }));
769
+ }
770
+ ) : filteredOptions.map((option) => {
771
+ const isSelected = selectedValues.includes(
772
+ option.value
773
+ );
774
+ return /* @__PURE__ */ React.createElement(
775
+ CommandItem,
776
+ {
777
+ key: option.value,
778
+ onSelect: readOnly ? void 0 : () => toggleOption(option.value),
779
+ className: cn(
780
+ "cursor-pointer",
781
+ readOnly && "cursor-default pointer-events-none hover:bg-transparent"
782
+ )
783
+ },
784
+ /* @__PURE__ */ React.createElement(
785
+ "div",
786
+ {
787
+ className: cn(
788
+ "flex h-4 w-4 items-center justify-center rounded-sm border border-grey-800 flex-shrink-0",
789
+ isSelected ? "bg-blue-600 border-blue-600 text-primary-foreground" : "opacity-50 [&_svg]:invisible"
790
+ )
791
+ },
792
+ /* @__PURE__ */ React.createElement(
793
+ Check,
794
+ {
795
+ className: "!h-3 !w-3 !text-white",
796
+ strokeWidth: 3
797
+ }
798
+ )
799
+ ),
800
+ /* @__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(
801
+ Typography,
802
+ {
803
+ variant: getFontVariant(size),
804
+ className: "text-grey-800 break-words"
805
+ },
806
+ highlight(option.label, query)
807
+ ))
808
+ );
809
+ }))
810
+ )
789
811
  ),
790
- 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(
812
+ isTree && /* @__PURE__ */ React.createElement("div", { className: "min-w-[260px] overflow-hidden flex flex-col max-h-full flex-1" }, 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(
791
813
  "svg",
792
814
  {
793
815
  className: "absolute left-3 top-1/2 -translate-y-1/2 h-4 w-4 text-muted-foreground",
@@ -818,65 +840,72 @@ const MultiSelect = React.forwardRef(
818
840
  SEARCH_INPUT_HEIGHT_CLASSES[size]
819
841
  )
820
842
  }
821
- ))), /* @__PURE__ */ React.createElement("div", { className: "px-2 pb-1 overflow-y-auto overflow-x-hidden [&::-webkit-scrollbar]:w-1.5 [&::-webkit-scrollbar-track]:bg-transparent [&::-webkit-scrollbar-thumb]:bg-grey-300 [&::-webkit-scrollbar-thumb]:rounded-full [&::-webkit-scrollbar-thumb:hover]:bg-grey-400" }, !treeQuery && treeOptions && treeOptions.length > 0 && /* @__PURE__ */ React.createElement(
843
+ ))), /* @__PURE__ */ React.createElement(
822
844
  "div",
823
845
  {
824
- className: cn(
825
- "flex items-center gap-2 px-2 py-1 cursor-pointer rounded-sm hover:bg-accent",
826
- readOnly && "cursor-default hover:bg-transparent pointer-events-none"
827
- ),
828
- onClick: readOnly ? void 0 : toggleAll
846
+ className: "px-2 pb-1 flex-1 overflow-y-auto overflow-x-hidden [&::-webkit-scrollbar]:w-1.5 [&::-webkit-scrollbar-track]:bg-transparent [&::-webkit-scrollbar-thumb]:bg-grey-300 [&::-webkit-scrollbar-thumb]:rounded-full [&::-webkit-scrollbar-thumb:hover]:bg-grey-400"
829
847
  },
830
- /* @__PURE__ */ React.createElement(
848
+ !treeQuery && treeOptions && treeOptions.length > 0 && /* @__PURE__ */ React.createElement(
831
849
  "div",
832
850
  {
833
851
  className: cn(
834
- "flex h-4 w-4 items-center justify-center rounded-sm border border-grey-800",
835
- selectedValues.length > 0 ? "bg-blue-600 border-blue-600 text-primary-foreground" : "opacity-50 [&_svg]:invisible"
836
- )
852
+ "flex items-center gap-2 px-2 py-1 cursor-pointer rounded-sm hover:bg-accent",
853
+ readOnly && "cursor-default hover:bg-transparent pointer-events-none"
854
+ ),
855
+ onClick: readOnly ? void 0 : toggleAll
837
856
  },
838
- treeOptions && selectedValues.length === function countAll(nodes) {
839
- if (!nodes) return 0;
840
- let acc = 0;
841
- for (const n of nodes) {
842
- const hasChildren = !!(n.children && n.children.length);
843
- if (!hasChildren) acc += 1;
844
- else
845
- acc += treeSelectionStrategy === "all" ? 1 + countAll(n.children) : countAll(n.children);
846
- }
847
- return acc;
848
- }(treeOptions) ? /* @__PURE__ */ React.createElement(
849
- Check,
857
+ /* @__PURE__ */ React.createElement(
858
+ "div",
850
859
  {
851
- className: "!h-3 !w-3 !text-white",
852
- strokeWidth: 3
853
- }
854
- ) : /* @__PURE__ */ React.createElement(
855
- Minus,
860
+ className: cn(
861
+ "flex h-4 w-4 items-center justify-center rounded-sm border border-grey-800",
862
+ selectedValues.length > 0 ? "bg-blue-600 border-blue-600 text-primary-foreground" : "opacity-50 [&_svg]:invisible"
863
+ )
864
+ },
865
+ treeOptions && selectedValues.length === function countAll(nodes) {
866
+ if (!nodes) return 0;
867
+ let acc = 0;
868
+ for (const n of nodes) {
869
+ const hasChildren = !!(n.children && n.children.length);
870
+ if (!hasChildren) acc += 1;
871
+ else
872
+ acc += treeSelectionStrategy === "all" ? 1 + countAll(n.children) : countAll(n.children);
873
+ }
874
+ return acc;
875
+ }(treeOptions) ? /* @__PURE__ */ React.createElement(
876
+ Check,
877
+ {
878
+ className: "!h-3 !w-3 !text-white",
879
+ strokeWidth: 3
880
+ }
881
+ ) : /* @__PURE__ */ React.createElement(
882
+ Minus,
883
+ {
884
+ className: "!h-3 !w-3 !text-white",
885
+ strokeWidth: 3
886
+ }
887
+ )
888
+ ),
889
+ /* @__PURE__ */ React.createElement(
890
+ Typography,
856
891
  {
857
- className: "!h-3 !w-3 !text-white",
858
- strokeWidth: 3
859
- }
892
+ variant: getFontVariant(size),
893
+ className: "text-grey-800"
894
+ },
895
+ selectAllLabel ?? t("multiSelect.selectAll")
860
896
  )
861
897
  ),
862
- /* @__PURE__ */ React.createElement(
863
- Typography,
898
+ !treeOptions || treeOptions.length === 0 || treeQuery && displayedTree.length === 0 ? /* @__PURE__ */ React.createElement(
899
+ "div",
864
900
  {
865
- variant: getFontVariant(size),
866
- className: "text-grey-800"
901
+ className: cn(
902
+ "p-4 text-center text-grey-800",
903
+ getFontVariant(size)
904
+ )
867
905
  },
868
- selectAllLabel ?? t("multiSelect.selectAll")
869
- )
870
- ), !treeOptions || treeOptions.length === 0 || treeQuery && displayedTree.length === 0 ? /* @__PURE__ */ React.createElement(
871
- "div",
872
- {
873
- className: cn(
874
- "p-4 text-center text-grey-800",
875
- getFontVariant(size)
876
- )
877
- },
878
- t("multiSelect.empty")
879
- ) : renderTree(displayedTree)))
906
+ t("multiSelect.empty")
907
+ ) : renderTree(displayedTree)
908
+ ))
880
909
  )
881
910
  );
882
911
  }
@@ -3,9 +3,8 @@ import { cn } from '../../lib/utils.js';
3
3
  import { cva } from 'class-variance-authority';
4
4
 
5
5
  const textareaVariants = cva(
6
- `flex h-20 w-full rounded-sm border border-grey-400 bg-background px-3 py-2 text-grey-800
6
+ `flex h-20 w-full rounded-sm border bg-background px-3 py-2 text-grey-800
7
7
  placeholder:text-grey-500 outline-none
8
- hover:border-grey-500 focus:bg-background focus:border-grey-400 focus:ring-grey-600 focus:ring-opacity-15 focus:ring-4
9
8
  disabled:cursor-not-allowed disabled:opacity-50
10
9
  transition-[border-color,box-shadow,background-color] duration-300`,
11
10
  {
@@ -32,22 +31,27 @@ const textareaVariants = cva(
32
31
  horizontal: "resize-x",
33
32
  vertical: "resize-y",
34
33
  "vertical-limited": "resize-y min-h-[40px] max-h-[480px]"
34
+ },
35
+ status: {
36
+ default: "border-grey-400 hover:border-grey-500 focus:bg-background focus:border-grey-400 focus:ring-grey-600 focus:ring-opacity-15 focus:ring-4",
37
+ error: "border-red-600 hover:border-red-600 focus:border-red-600 focus:ring-0"
35
38
  }
36
39
  },
37
40
  defaultVariants: {
38
41
  variant: "default",
39
42
  size: "default",
40
43
  radius: "default",
41
- resize: "default"
44
+ resize: "default",
45
+ status: "default"
42
46
  }
43
47
  }
44
48
  );
45
49
  const Textarea = React.forwardRef(
46
- ({ className, variant, size, radius, resize, ...props }, ref) => /* @__PURE__ */ React.createElement(
50
+ ({ className, variant, size, radius, resize, status, ...props }, ref) => /* @__PURE__ */ React.createElement(
47
51
  "textarea",
48
52
  {
49
53
  className: cn(
50
- textareaVariants({ variant, size, radius, resize, className })
54
+ textareaVariants({ variant, size, radius, resize, status, className })
51
55
  ),
52
56
  ref,
53
57
  ...props
@@ -0,0 +1,50 @@
1
+ import * as React from 'react';
2
+
3
+ const DEFAULT_BOTTOM_PADDING = 50;
4
+ const DEFAULT_MIN_HEIGHT = 120;
5
+ function useDynamicMaxHeight(options = {}) {
6
+ const {
7
+ enabled = false,
8
+ bottomPadding = DEFAULT_BOTTOM_PADDING,
9
+ minHeight = DEFAULT_MIN_HEIGHT
10
+ } = options;
11
+ const ref = React.useRef(null);
12
+ const [maxHeight, setMaxHeight] = React.useState(
13
+ void 0
14
+ );
15
+ const lastCalculatedHeight = React.useRef(void 0);
16
+ React.useEffect(() => {
17
+ if (!enabled) {
18
+ return;
19
+ }
20
+ const calculateHeight = () => {
21
+ if (!ref.current) return;
22
+ const rect = ref.current.getBoundingClientRect();
23
+ const viewportHeight = window.innerHeight;
24
+ const elementTop = rect.top;
25
+ const adjustedBottomPadding = viewportHeight < 500 ? 10 : bottomPadding;
26
+ const availableHeight = viewportHeight - elementTop - adjustedBottomPadding;
27
+ const finalHeight = Math.max(availableHeight, minHeight);
28
+ lastCalculatedHeight.current = finalHeight;
29
+ setMaxHeight(finalHeight);
30
+ };
31
+ requestAnimationFrame(() => {
32
+ requestAnimationFrame(() => {
33
+ calculateHeight();
34
+ });
35
+ });
36
+ window.addEventListener("resize", calculateHeight);
37
+ window.addEventListener("scroll", calculateHeight, true);
38
+ return () => {
39
+ window.removeEventListener("resize", calculateHeight);
40
+ window.removeEventListener("scroll", calculateHeight, true);
41
+ };
42
+ }, [enabled, bottomPadding, minHeight]);
43
+ const style = React.useMemo(() => {
44
+ if (maxHeight === void 0) return {};
45
+ return { maxHeight: `${maxHeight}px` };
46
+ }, [maxHeight]);
47
+ return { ref, maxHeight, style };
48
+ }
49
+
50
+ export { useDynamicMaxHeight };
@@ -35,6 +35,10 @@ const language = {
35
35
  sortAscendingText: "Sort A-Z",
36
36
  sortDescendingText: "Sort Z-A",
37
37
  sortDefault: "Restore default"
38
+ },
39
+ accordion: {
40
+ expand: "Expand",
41
+ collapse: "Collapse"
38
42
  }
39
43
  }
40
44
  };
@@ -35,6 +35,10 @@ const language = {
35
35
  sortAscendingText: "Ordenar A-Z",
36
36
  sortDescendingText: "Ordenar Z-A",
37
37
  sortDefault: "Restaurar predeterminado"
38
+ },
39
+ accordion: {
40
+ expand: "Expandir",
41
+ collapse: "Contraer"
38
42
  }
39
43
  }
40
44
  };
@@ -35,6 +35,10 @@ const language = {
35
35
  sortAscendingText: "Ordenar A-Z",
36
36
  sortDescendingText: "Ordenar Z-A",
37
37
  sortDefault: "Restaurar padr\xE3o"
38
+ },
39
+ accordion: {
40
+ expand: "Expandir",
41
+ collapse: "Retrair"
38
42
  }
39
43
  }
40
44
  };