lecom-ui 5.4.44 → 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.
- package/dist/components/Accordion/Accordion.js +22 -19
- package/dist/components/Chart/Chart.js +1 -1
- package/dist/components/Combobox/Combobox.js +17 -4
- package/dist/components/CustomTagInput/CustomTagInput.js +107 -33
- package/dist/components/Dialog/Dialog.js +2 -2
- package/dist/components/Input/Input.js +9 -4
- package/dist/components/Label/Label.js +39 -3
- package/dist/components/MultiSelect/MultiSelect.js +190 -161
- package/dist/components/Textarea/Textarea.js +9 -5
- package/dist/hooks/useDynamicMaxHeight.js +49 -0
- package/dist/i18n/locales/en_us.js +4 -0
- package/dist/i18n/locales/es_es.js +4 -0
- package/dist/i18n/locales/pt_br.js +4 -0
- package/dist/index.d.ts +33 -15
- package/dist/index.js +2 -1
- package/dist/style.min.css +1 -1
- package/package.json +1 -1
|
@@ -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
|
|
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
|
|
641
|
+
"p-0 flex flex-col",
|
|
626
642
|
matchTriggerWidth && "w-[var(--radix-popover-trigger-width)]",
|
|
627
643
|
classNameContent
|
|
628
644
|
),
|
|
@@ -646,115 +662,25 @@ const MultiSelect = React.forwardRef(
|
|
|
646
662
|
disabled: readOnly
|
|
647
663
|
}
|
|
648
664
|
),
|
|
649
|
-
/* @__PURE__ */ React.createElement(
|
|
650
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
"
|
|
673
|
-
|
|
674
|
+
"p-4 text-center text-grey-800",
|
|
675
|
+
getFontVariant(size)
|
|
674
676
|
)
|
|
675
677
|
},
|
|
676
|
-
|
|
677
|
-
|
|
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:
|
|
757
|
-
onSelect: readOnly ? void 0 :
|
|
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
|
|
768
|
-
|
|
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(
|
|
711
|
+
/* @__PURE__ */ React.createElement(
|
|
780
712
|
Typography,
|
|
781
713
|
{
|
|
782
714
|
variant: getFontVariant(size),
|
|
783
|
-
className: "text-grey-800
|
|
715
|
+
className: "text-grey-800"
|
|
784
716
|
},
|
|
785
|
-
|
|
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]
|
|
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(
|
|
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(
|
|
843
|
+
))), /* @__PURE__ */ React.createElement(
|
|
822
844
|
"div",
|
|
823
845
|
{
|
|
824
|
-
className:
|
|
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
|
|
835
|
-
|
|
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
|
-
|
|
839
|
-
|
|
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:
|
|
852
|
-
|
|
853
|
-
|
|
854
|
-
|
|
855
|
-
|
|
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
|
-
|
|
858
|
-
|
|
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
|
-
|
|
898
|
+
!treeOptions || treeOptions.length === 0 || treeQuery && displayedTree.length === 0 ? /* @__PURE__ */ React.createElement(
|
|
899
|
+
"div",
|
|
864
900
|
{
|
|
865
|
-
|
|
866
|
-
|
|
901
|
+
className: cn(
|
|
902
|
+
"p-4 text-center text-grey-800",
|
|
903
|
+
getFontVariant(size)
|
|
904
|
+
)
|
|
867
905
|
},
|
|
868
|
-
|
|
869
|
-
)
|
|
870
|
-
)
|
|
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
|
|
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 };
|