lecom-ui 5.4.43 → 5.4.45

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.
Files changed (36) hide show
  1. package/README.md +1 -1
  2. package/dist/components/Accordion/Accordion.js +22 -19
  3. package/dist/components/Chart/Chart.js +1 -1
  4. package/dist/components/Combobox/Combobox.js +17 -4
  5. package/dist/components/CustomTagInput/CustomTagInput.js +107 -33
  6. package/dist/components/Dialog/Dialog.js +2 -2
  7. package/dist/components/Input/Input.js +9 -4
  8. package/dist/components/Label/Label.js +39 -3
  9. package/dist/components/MultiSelect/MultiSelect.js +214 -179
  10. package/dist/components/Textarea/Textarea.js +9 -5
  11. package/dist/hooks/useDynamicMaxHeight.js +49 -0
  12. package/dist/i18n/locales/en_us.js +4 -0
  13. package/dist/i18n/locales/es_es.js +4 -0
  14. package/dist/i18n/locales/pt_br.js +4 -0
  15. package/dist/index.d.ts +31 -13
  16. package/dist/index.js +2 -1
  17. package/dist/plugin/extend.js +79 -79
  18. package/dist/plugin/fontFaces.js +172 -172
  19. package/dist/plugin/general.js +12 -12
  20. package/dist/plugin/pluginDev.cjs +5 -5
  21. package/dist/plugin/pluginNext.cjs +5 -5
  22. package/dist/plugin/pluginNextTurbo.cjs +5 -5
  23. package/dist/plugin/pluginVite.cjs +5 -5
  24. package/dist/plugin/template.js +31 -31
  25. package/dist/plugin/typographies.js +152 -152
  26. package/dist/plugin/varsTheme.js +79 -79
  27. package/dist/style.min.css +1 -1
  28. package/package.json +1 -1
  29. package/dist/components/Collapse/Collapse.js +0 -94
  30. package/dist/components/CustomIcon/Icons/CadastroFacil.js +0 -23
  31. package/dist/components/CustomIcon/Icons/LogoLecom.js +0 -30
  32. package/dist/components/CustomIcon/Icons/LogoLecomBrand.js +0 -23
  33. package/dist/components/CustomIcon/Icons/ModoTeste.js +0 -23
  34. package/dist/components/CustomIcon/Icons/Rpa.js +0 -23
  35. package/dist/components/CustomIcon/Icons/SairModoTeste.js +0 -31
  36. package/dist/components/IconHandler/IconHandler.js +0 -99
@@ -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;
@@ -93,13 +107,14 @@ const MultiSelect = React.forwardRef(
93
107
  setTimeout(() => calculateMaxCount(), 10);
94
108
  return;
95
109
  }
96
- const CONTROLS_WIDTH = 60;
97
- const COUNTER_TAG_WIDTH = 50;
98
- const TAG_GAP = 4;
99
- const CONTAINER_PADDING = 8;
100
- const AVG_CHAR_WIDTH = 10;
101
- const TAG_PADDING = 16;
102
- const availableWidth = buttonWidth - CONTAINER_PADDING * 2 - CONTROLS_WIDTH;
110
+ const CONTAINER_PADDING = 16;
111
+ const TAG_GAP = 2;
112
+ const COUNTER_TAG_WIDTH = 60;
113
+ const ICONS_WIDTH = 50;
114
+ const AVG_CHAR_WIDTH = 7;
115
+ const MAX_TAG_WIDTH = 250;
116
+ const TAG_BASE_WIDTH = 24;
117
+ const availableWidth = buttonWidth - CONTAINER_PADDING - ICONS_WIDTH;
103
118
  if (availableWidth <= 0) {
104
119
  setDynamicMaxCount(1);
105
120
  return;
@@ -116,28 +131,33 @@ const MultiSelect = React.forwardRef(
116
131
  };
117
132
  const estimatedWidths = [];
118
133
  for (let i = 0; i < selectedValues.length; i++) {
119
- const label = getTreeLabel(selectedValues[i]) || options.find((o) => o.value === selectedValues[i])?.label || selectedValues[i];
134
+ const option = options.find((option2) => option2.value === selectedValues[i]);
135
+ const label = getTreeLabel(selectedValues[i]) || option?.label || selectedValues[i];
136
+ const prefixWidth = option?.prefix ? 24 : 0;
137
+ const textWidth = label.length * AVG_CHAR_WIDTH;
138
+ const closeButtonWidth = 16;
120
139
  const estimatedWidth = Math.min(
121
- label.length * AVG_CHAR_WIDTH + TAG_PADDING,
122
- 250
140
+ TAG_BASE_WIDTH + textWidth + prefixWidth + closeButtonWidth,
141
+ MAX_TAG_WIDTH
123
142
  );
124
143
  estimatedWidths.push(estimatedWidth);
125
144
  }
126
- let totalWidth = 0;
145
+ let totalWidthWithoutCounter = 0;
127
146
  for (let i = 0; i < estimatedWidths.length; i++) {
128
- totalWidth += estimatedWidths[i] + (i > 0 ? TAG_GAP : 0);
147
+ totalWidthWithoutCounter += estimatedWidths[i];
148
+ if (i > 0) totalWidthWithoutCounter += TAG_GAP;
129
149
  }
130
- if (totalWidth <= availableWidth) {
150
+ if (totalWidthWithoutCounter <= availableWidth) {
131
151
  setDynamicMaxCount(selectedValues.length);
132
152
  return;
133
153
  }
134
- const availableWithCounter = availableWidth - COUNTER_TAG_WIDTH - TAG_GAP;
154
+ const availableForTagsWithCounter = availableWidth - COUNTER_TAG_WIDTH - TAG_GAP;
135
155
  let count = 0;
136
- totalWidth = 0;
156
+ let accumulatedWidth = 0;
137
157
  for (let i = 0; i < estimatedWidths.length; i++) {
138
- const tagWidth = estimatedWidths[i] + (i > 0 ? TAG_GAP : 0);
139
- if (totalWidth + tagWidth <= availableWithCounter) {
140
- totalWidth += tagWidth;
158
+ const nextTagWidth = estimatedWidths[i] + (i > 0 ? TAG_GAP : 0);
159
+ if (accumulatedWidth + nextTagWidth <= availableForTagsWithCounter) {
160
+ accumulatedWidth += nextTagWidth;
141
161
  count++;
142
162
  } else {
143
163
  break;
@@ -529,10 +549,10 @@ const MultiSelect = React.forwardRef(
529
549
  onClick: handleTogglePopover,
530
550
  className: cn(
531
551
  `flex w-full p-1 rounded-sm h-auto items-center justify-between bg-background
532
- border border-grey-400
533
- 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
534
553
  transition-all duration-300 outline-none
535
554
  [&_svg]:pointer-events-auto`,
555
+ STATUS_STYLES[status],
536
556
  maxCount === void 0 && TRIGGER_HEIGHT_CLASSES[size],
537
557
  disabled && "opacity-50 cursor-not-allowed pointer-events-none",
538
558
  readOnly && !disabled && "opacity-50 hover:border-grey-400",
@@ -615,8 +635,10 @@ const MultiSelect = React.forwardRef(
615
635
  /* @__PURE__ */ React.createElement(
616
636
  PopoverContent,
617
637
  {
638
+ ref: dynamicHeightRef,
639
+ style: dynamicHeightStyle,
618
640
  className: cn(
619
- "p-0 max-h-80",
641
+ "p-0 flex flex-col",
620
642
  matchTriggerWidth && "w-[var(--radix-popover-trigger-width)]",
621
643
  classNameContent
622
644
  ),
@@ -640,115 +662,25 @@ const MultiSelect = React.forwardRef(
640
662
  disabled: readOnly
641
663
  }
642
664
  ),
643
- /* @__PURE__ */ React.createElement(CommandList, null, /* @__PURE__ */ React.createElement(CommandGroup, null, (effectiveOptions.length === 0 || query && filteredOptions.length === 0) && /* @__PURE__ */ React.createElement(
644
- CommandEmpty,
645
- {
646
- className: cn(
647
- "p-4 text-center text-grey-800",
648
- getFontVariant(size)
649
- )
650
- },
651
- t("multiSelect.empty")
652
- ), !query && effectiveOptions.length > 0 && /* @__PURE__ */ React.createElement(
653
- CommandItem,
665
+ /* @__PURE__ */ React.createElement(
666
+ CommandList,
654
667
  {
655
- key: "all",
656
- onSelect: readOnly ? void 0 : toggleAll,
657
- className: cn(
658
- "cursor-pointer",
659
- readOnly && "cursor-default pointer-events-none hover:bg-transparent"
660
- )
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"
661
669
  },
662
- /* @__PURE__ */ React.createElement(
663
- "div",
670
+ /* @__PURE__ */ React.createElement(CommandGroup, null, (effectiveOptions.length === 0 || query && filteredOptions.length === 0) && /* @__PURE__ */ React.createElement(
671
+ CommandEmpty,
664
672
  {
665
673
  className: cn(
666
- "flex h-4 w-4 items-center justify-center rounded-sm border border-grey-800",
667
- 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)
668
676
  )
669
677
  },
670
- selectedValues.length === effectiveOptions.length ? /* @__PURE__ */ React.createElement(
671
- Check,
672
- {
673
- className: "!h-3 !w-3 !text-white",
674
- strokeWidth: 3
675
- }
676
- ) : /* @__PURE__ */ React.createElement(
677
- Minus,
678
- {
679
- className: "!h-3 !w-3 !text-white",
680
- strokeWidth: 3
681
- }
682
- )
683
- ),
684
- /* @__PURE__ */ React.createElement(
685
- Typography,
686
- {
687
- variant: getFontVariant(size),
688
- className: "text-grey-800"
689
- },
690
- selectAllLabel ?? t("multiSelect.selectAll")
691
- )
692
- ), isGrouped ? Object.entries(groupedOptions).map(
693
- ([categoryName, categoryOptions]) => {
694
- const filtered = categoryOptions.filter(
695
- (opt) => !query || effectiveOptions.some(
696
- (eff) => eff.value === opt.value && filteredOptions.some(
697
- (filt) => filt.value === opt.value
698
- )
699
- )
700
- );
701
- if (!filtered.length) return null;
702
- 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) => {
703
- const isSelected = selectedValues.includes(
704
- option.value
705
- );
706
- return /* @__PURE__ */ React.createElement(
707
- CommandItem,
708
- {
709
- key: option.value,
710
- onSelect: readOnly ? void 0 : () => toggleOption(option.value),
711
- className: cn(
712
- "cursor-pointer",
713
- readOnly && "cursor-default pointer-events-none hover:bg-transparent"
714
- )
715
- },
716
- /* @__PURE__ */ React.createElement(
717
- "div",
718
- {
719
- className: cn(
720
- "flex h-4 w-4 items-center justify-center rounded-sm border-2 border-grey-400 flex-shrink-0",
721
- isSelected ? "bg-blue-600 border-blue-600 text-primary-foreground" : "opacity-50 [&_svg]:invisible"
722
- )
723
- },
724
- /* @__PURE__ */ React.createElement(
725
- Check,
726
- {
727
- className: "!h-3 !w-3 !text-white",
728
- strokeWidth: 3
729
- }
730
- )
731
- ),
732
- /* @__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(
733
- Typography,
734
- {
735
- variant: getFontVariant(size),
736
- className: "text-grey-800 break-words"
737
- },
738
- highlight(option.label, query)
739
- ))
740
- );
741
- }));
742
- }
743
- ) : filteredOptions.map((option) => {
744
- const isSelected = selectedValues.includes(
745
- option.value
746
- );
747
- return /* @__PURE__ */ React.createElement(
678
+ t("multiSelect.empty")
679
+ ), !query && effectiveOptions.length > 0 && /* @__PURE__ */ React.createElement(
748
680
  CommandItem,
749
681
  {
750
- key: option.value,
751
- onSelect: readOnly ? void 0 : () => toggleOption(option.value),
682
+ key: "all",
683
+ onSelect: readOnly ? void 0 : toggleAll,
752
684
  className: cn(
753
685
  "cursor-pointer",
754
686
  readOnly && "cursor-default pointer-events-none hover:bg-transparent"
@@ -758,30 +690,126 @@ const MultiSelect = React.forwardRef(
758
690
  "div",
759
691
  {
760
692
  className: cn(
761
- "flex h-4 w-4 items-center justify-center rounded-sm border border-grey-800 flex-shrink-0",
762
- 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"
763
695
  )
764
696
  },
765
- /* @__PURE__ */ React.createElement(
697
+ selectedValues.length === effectiveOptions.length ? /* @__PURE__ */ React.createElement(
766
698
  Check,
767
699
  {
768
700
  className: "!h-3 !w-3 !text-white",
769
701
  strokeWidth: 3
770
702
  }
703
+ ) : /* @__PURE__ */ React.createElement(
704
+ Minus,
705
+ {
706
+ className: "!h-3 !w-3 !text-white",
707
+ strokeWidth: 3
708
+ }
771
709
  )
772
710
  ),
773
- /* @__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(
774
712
  Typography,
775
713
  {
776
714
  variant: getFontVariant(size),
777
- className: "text-grey-800 break-words"
715
+ className: "text-grey-800"
778
716
  },
779
- highlight(option.label, query)
780
- ))
781
- );
782
- })))
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
+ )
783
811
  ),
784
- 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" }, 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(
785
813
  "svg",
786
814
  {
787
815
  className: "absolute left-3 top-1/2 -translate-y-1/2 h-4 w-4 text-muted-foreground",
@@ -812,65 +840,72 @@ const MultiSelect = React.forwardRef(
812
840
  SEARCH_INPUT_HEIGHT_CLASSES[size]
813
841
  )
814
842
  }
815
- ))), /* @__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(
816
844
  "div",
817
845
  {
818
- className: cn(
819
- "flex items-center gap-2 px-2 py-1 cursor-pointer rounded-sm hover:bg-accent",
820
- readOnly && "cursor-default hover:bg-transparent pointer-events-none"
821
- ),
822
- 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"
823
847
  },
824
- /* @__PURE__ */ React.createElement(
848
+ !treeQuery && treeOptions && treeOptions.length > 0 && /* @__PURE__ */ React.createElement(
825
849
  "div",
826
850
  {
827
851
  className: cn(
828
- "flex h-4 w-4 items-center justify-center rounded-sm border border-grey-800",
829
- selectedValues.length > 0 ? "bg-blue-600 border-blue-600 text-primary-foreground" : "opacity-50 [&_svg]:invisible"
830
- )
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
831
856
  },
832
- treeOptions && selectedValues.length === function countAll(nodes) {
833
- if (!nodes) return 0;
834
- let acc = 0;
835
- for (const n of nodes) {
836
- const hasChildren = !!(n.children && n.children.length);
837
- if (!hasChildren) acc += 1;
838
- else
839
- acc += treeSelectionStrategy === "all" ? 1 + countAll(n.children) : countAll(n.children);
840
- }
841
- return acc;
842
- }(treeOptions) ? /* @__PURE__ */ React.createElement(
843
- Check,
857
+ /* @__PURE__ */ React.createElement(
858
+ "div",
844
859
  {
845
- className: "!h-3 !w-3 !text-white",
846
- strokeWidth: 3
847
- }
848
- ) : /* @__PURE__ */ React.createElement(
849
- 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,
850
891
  {
851
- className: "!h-3 !w-3 !text-white",
852
- strokeWidth: 3
853
- }
892
+ variant: getFontVariant(size),
893
+ className: "text-grey-800"
894
+ },
895
+ selectAllLabel ?? t("multiSelect.selectAll")
854
896
  )
855
897
  ),
856
- /* @__PURE__ */ React.createElement(
857
- Typography,
898
+ !treeOptions || treeOptions.length === 0 || treeQuery && displayedTree.length === 0 ? /* @__PURE__ */ React.createElement(
899
+ "div",
858
900
  {
859
- variant: getFontVariant(size),
860
- className: "text-grey-800"
901
+ className: cn(
902
+ "p-4 text-center text-grey-800",
903
+ getFontVariant(size)
904
+ )
861
905
  },
862
- selectAllLabel ?? t("multiSelect.selectAll")
863
- )
864
- ), !treeOptions || treeOptions.length === 0 || treeQuery && displayedTree.length === 0 ? /* @__PURE__ */ React.createElement(
865
- "div",
866
- {
867
- className: cn(
868
- "p-4 text-center text-grey-800",
869
- getFontVariant(size)
870
- )
871
- },
872
- t("multiSelect.empty")
873
- ) : renderTree(displayedTree)))
906
+ t("multiSelect.empty")
907
+ ) : renderTree(displayedTree)
908
+ ))
874
909
  )
875
910
  );
876
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,49 @@
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 availableHeight = viewportHeight - elementTop - bottomPadding;
26
+ const finalHeight = Math.max(availableHeight, minHeight);
27
+ lastCalculatedHeight.current = finalHeight;
28
+ setMaxHeight(finalHeight);
29
+ };
30
+ requestAnimationFrame(() => {
31
+ requestAnimationFrame(() => {
32
+ calculateHeight();
33
+ });
34
+ });
35
+ window.addEventListener("resize", calculateHeight);
36
+ window.addEventListener("scroll", calculateHeight, true);
37
+ return () => {
38
+ window.removeEventListener("resize", calculateHeight);
39
+ window.removeEventListener("scroll", calculateHeight, true);
40
+ };
41
+ }, [enabled, bottomPadding, minHeight]);
42
+ const style = React.useMemo(() => {
43
+ if (maxHeight === void 0) return {};
44
+ return { maxHeight: `${maxHeight}px` };
45
+ }, [maxHeight]);
46
+ return { ref, maxHeight, style };
47
+ }
48
+
49
+ 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
  };