lecom-ui 5.4.46 → 5.4.48
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 +39 -17
- package/dist/components/Button/Button.js +5 -5
- package/dist/components/Combobox/Combobox.js +114 -52
- package/dist/components/CustomTagInput/CustomTagInput.js +5 -1
- package/dist/components/MultiSelect/MultiSelect.js +16 -13
- package/dist/components/Tooltip/Tooltip.js +3 -3
- package/dist/hooks/useDynamicMaxHeight.js +92 -23
- package/dist/index.d.ts +12 -10
- package/dist/style.min.css +1 -1
- package/package.json +134 -134
|
@@ -31,7 +31,7 @@ const accordionVariants = cva(
|
|
|
31
31
|
const Accordion = AccordionPrimitive.Root;
|
|
32
32
|
const AccordionItem = React.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ React.createElement(AccordionPrimitive.Item, { ref, className: cn(className), ...props }));
|
|
33
33
|
AccordionItem.displayName = "AccordionItem";
|
|
34
|
-
const AccordionIcon = ({ disabled }) => {
|
|
34
|
+
const AccordionIcon = ({ disabled, isOpen }) => {
|
|
35
35
|
const { t } = useTranslation();
|
|
36
36
|
const icon = /* @__PURE__ */ React.createElement(
|
|
37
37
|
ChevronDown,
|
|
@@ -42,7 +42,7 @@ const AccordionIcon = ({ disabled }) => {
|
|
|
42
42
|
)
|
|
43
43
|
}
|
|
44
44
|
);
|
|
45
|
-
return /* @__PURE__ */ React.createElement(TooltipProvider, null, /* @__PURE__ */ React.createElement(Tooltip, null, /* @__PURE__ */ React.createElement(TooltipTrigger, { asChild: true }, /* @__PURE__ */ React.createElement(Typography, { className: "inline-flex" }, icon)), /* @__PURE__ */ React.createElement(TooltipContent, { color: "black" },
|
|
45
|
+
return /* @__PURE__ */ React.createElement(TooltipProvider, null, /* @__PURE__ */ React.createElement(Tooltip, null, /* @__PURE__ */ React.createElement(TooltipTrigger, { asChild: true }, /* @__PURE__ */ React.createElement(Typography, { className: "inline-flex" }, icon)), /* @__PURE__ */ React.createElement(TooltipContent, { color: "black" }, isOpen ? t("accordion.collapse") : t("accordion.expand"))));
|
|
46
46
|
};
|
|
47
47
|
AccordionIcon.displayName = "AccordionIcon";
|
|
48
48
|
const AccordionTrigger = React.forwardRef(
|
|
@@ -56,21 +56,43 @@ const AccordionTrigger = React.forwardRef(
|
|
|
56
56
|
iconPosition = "right",
|
|
57
57
|
iconDirection = "down-to-up",
|
|
58
58
|
...props
|
|
59
|
-
}, ref) =>
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
)
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
},
|
|
72
|
-
|
|
73
|
-
|
|
59
|
+
}, ref) => {
|
|
60
|
+
const triggerRef = React.useRef(null);
|
|
61
|
+
const [isOpen, setIsOpen] = React.useState(false);
|
|
62
|
+
React.useEffect(() => {
|
|
63
|
+
const element = triggerRef.current;
|
|
64
|
+
if (!element) return;
|
|
65
|
+
const observer = new MutationObserver(() => {
|
|
66
|
+
setIsOpen(element.dataset.state === "open");
|
|
67
|
+
});
|
|
68
|
+
observer.observe(element, { attributes: true, attributeFilter: ["data-state"] });
|
|
69
|
+
setIsOpen(element.dataset.state === "open");
|
|
70
|
+
return () => observer.disconnect();
|
|
71
|
+
}, []);
|
|
72
|
+
return /* @__PURE__ */ React.createElement(AccordionPrimitive.Header, null, /* @__PURE__ */ React.createElement(
|
|
73
|
+
AccordionPrimitive.Trigger,
|
|
74
|
+
{
|
|
75
|
+
ref: (node) => {
|
|
76
|
+
triggerRef.current = node;
|
|
77
|
+
if (typeof ref === "function") {
|
|
78
|
+
ref(node);
|
|
79
|
+
} else if (ref) {
|
|
80
|
+
ref.current = node;
|
|
81
|
+
}
|
|
82
|
+
},
|
|
83
|
+
className: cn(
|
|
84
|
+
"group",
|
|
85
|
+
accordionVariants({ variant, size, className }),
|
|
86
|
+
iconDirection === "down-to-up" && "[&[data-state=open]_svg]:rotate-180",
|
|
87
|
+
iconDirection === "right-to-down" && "[&_svg]:rotate-[-90deg] [&[data-state=open]_svg]:rotate-0"
|
|
88
|
+
),
|
|
89
|
+
...props,
|
|
90
|
+
disabled,
|
|
91
|
+
asChild
|
|
92
|
+
},
|
|
93
|
+
asChild ? children : /* @__PURE__ */ React.createElement(React.Fragment, null, iconPosition === "left" && /* @__PURE__ */ React.createElement(AccordionIcon, { disabled, isOpen }), children, iconPosition === "right" && /* @__PURE__ */ React.createElement(AccordionIcon, { disabled, isOpen }))
|
|
94
|
+
));
|
|
95
|
+
}
|
|
74
96
|
);
|
|
75
97
|
AccordionTrigger.displayName = AccordionPrimitive.Trigger.displayName;
|
|
76
98
|
const AccordionContent = React.forwardRef(({ className, children, disabled = false, ...props }, ref) => /* @__PURE__ */ React.createElement(
|
|
@@ -5,7 +5,7 @@ import { Spin } from '../Spin/Spin.js';
|
|
|
5
5
|
import { CustomButton } from './CustomButton.js';
|
|
6
6
|
|
|
7
7
|
const buttonVariants = cva(
|
|
8
|
-
"flex items-center justify-center gap-2 rounded-full
|
|
8
|
+
"flex items-center justify-center gap-2 rounded-full shadow-sm outline-none transition-all duration-300",
|
|
9
9
|
{
|
|
10
10
|
variants: {
|
|
11
11
|
variant: {
|
|
@@ -15,10 +15,10 @@ const buttonVariants = cva(
|
|
|
15
15
|
ghost: ""
|
|
16
16
|
},
|
|
17
17
|
size: {
|
|
18
|
-
small: "h-8 px-3 py-2 text-sm leading-none [&>svg]:w-5 [&>svg]:h-5",
|
|
19
|
-
medium: "h-10 px-4 py-3 text-sm leading-none [&>svg]:w-5 [&>svg]:h-5",
|
|
20
|
-
large: "h-12 px-5 py-4 text-base leading-none [&>svg]:w-5 [&>svg]:h-5",
|
|
21
|
-
extraLarge: "h-14 px-6 py-5 text-base leading-none [&>svg]:w-6 [&>svg]:h-6"
|
|
18
|
+
small: "h-8 px-3 py-2 text-sm leading-none [&>svg]:w-5 [&>svg]:h-5 body-medium-500",
|
|
19
|
+
medium: "h-10 px-4 py-3 text-sm leading-none [&>svg]:w-5 [&>svg]:h-5 body-medium-500",
|
|
20
|
+
large: "h-12 px-5 py-4 text-base leading-none [&>svg]:w-5 [&>svg]:h-5 body-large-500",
|
|
21
|
+
extraLarge: "h-14 px-6 py-5 text-base leading-none [&>svg]:w-6 [&>svg]:h-6 body-large-500"
|
|
22
22
|
},
|
|
23
23
|
color: {
|
|
24
24
|
blue: "",
|
|
@@ -57,7 +57,7 @@ const getFontVariant = (size) => {
|
|
|
57
57
|
return sizeMap[size ?? "medium"];
|
|
58
58
|
};
|
|
59
59
|
const comboboxItemVariants = cva(
|
|
60
|
-
"text-grey-800 flex items-center justify-start gap-2 hover:bg-grey-50 hover:cursor-pointer py-1 w-full",
|
|
60
|
+
"text-grey-800 flex items-center justify-start gap-2 hover:bg-grey-50 hover:cursor-pointer py-1 w-full min-w-0",
|
|
61
61
|
{
|
|
62
62
|
variants: {
|
|
63
63
|
size: {
|
|
@@ -140,7 +140,7 @@ const ComboboxItemContent = ({
|
|
|
140
140
|
variant: fontVariant,
|
|
141
141
|
className: cn(
|
|
142
142
|
textColor,
|
|
143
|
-
"whitespace-normal
|
|
143
|
+
"whitespace-normal min-w-0 break-words"
|
|
144
144
|
)
|
|
145
145
|
},
|
|
146
146
|
option.label
|
|
@@ -394,6 +394,84 @@ const ComboboxTriggerButton = React.forwardRef(
|
|
|
394
394
|
}
|
|
395
395
|
);
|
|
396
396
|
ComboboxTriggerButton.displayName = "ComboboxTriggerButton";
|
|
397
|
+
function ComboboxPopoverContent({
|
|
398
|
+
dynamicHeightRef,
|
|
399
|
+
dynamicHeightStyle,
|
|
400
|
+
contentClassName,
|
|
401
|
+
side,
|
|
402
|
+
preferredSide,
|
|
403
|
+
dynamicHeight,
|
|
404
|
+
showSearch,
|
|
405
|
+
searchTerm,
|
|
406
|
+
t,
|
|
407
|
+
size,
|
|
408
|
+
search,
|
|
409
|
+
setSearch,
|
|
410
|
+
commandListRef,
|
|
411
|
+
showCreateOption,
|
|
412
|
+
onCreateOption,
|
|
413
|
+
handleClose,
|
|
414
|
+
notFoundContent,
|
|
415
|
+
filteredOptions,
|
|
416
|
+
value,
|
|
417
|
+
onChange,
|
|
418
|
+
itemsClassName,
|
|
419
|
+
matchTriggerWidth
|
|
420
|
+
}) {
|
|
421
|
+
return /* @__PURE__ */ React.createElement(
|
|
422
|
+
PopoverContent,
|
|
423
|
+
{
|
|
424
|
+
ref: dynamicHeightRef,
|
|
425
|
+
style: dynamicHeightStyle,
|
|
426
|
+
className: cn(
|
|
427
|
+
" pt-0 px-1 pb-1 flex flex-col",
|
|
428
|
+
matchTriggerWidth && "w-[var(--radix-popover-trigger-width)]",
|
|
429
|
+
contentClassName
|
|
430
|
+
),
|
|
431
|
+
side: side ?? (dynamicHeight ? preferredSide : "bottom"),
|
|
432
|
+
avoidCollisions: true,
|
|
433
|
+
onWheel: (e) => e.stopPropagation()
|
|
434
|
+
},
|
|
435
|
+
/* @__PURE__ */ React.createElement(Command, { shouldFilter: false, className: cn(SEARCH_INPUT_CLASSES[size], "max-h-full flex flex-col") }, showSearch && /* @__PURE__ */ React.createElement(
|
|
436
|
+
CommandInput,
|
|
437
|
+
{
|
|
438
|
+
placeholder: searchTerm || t("multiSelect.search"),
|
|
439
|
+
value: search,
|
|
440
|
+
onValueChange: setSearch
|
|
441
|
+
}
|
|
442
|
+
), /* @__PURE__ */ React.createElement(
|
|
443
|
+
CommandList,
|
|
444
|
+
{
|
|
445
|
+
ref: commandListRef,
|
|
446
|
+
key: search,
|
|
447
|
+
className: cn(
|
|
448
|
+
"flex-1 overflow-y-auto overflow-x-hidden",
|
|
449
|
+
"[&::-webkit-scrollbar]:w-1.5",
|
|
450
|
+
"[&::-webkit-scrollbar-track]:bg-transparent",
|
|
451
|
+
"[&::-webkit-scrollbar-thumb]:bg-grey-300",
|
|
452
|
+
"[&::-webkit-scrollbar-thumb]:rounded-full",
|
|
453
|
+
"[&::-webkit-scrollbar-thumb]:hover:bg-grey-400",
|
|
454
|
+
dynamicHeight ? "max-h-none" : "max-h-44"
|
|
455
|
+
)
|
|
456
|
+
},
|
|
457
|
+
/* @__PURE__ */ React.createElement(
|
|
458
|
+
ComboboxContent,
|
|
459
|
+
{
|
|
460
|
+
showCreateOption,
|
|
461
|
+
search,
|
|
462
|
+
onCreateOption,
|
|
463
|
+
onClose: handleClose,
|
|
464
|
+
size,
|
|
465
|
+
notFoundContent,
|
|
466
|
+
filteredOptions,
|
|
467
|
+
value,
|
|
468
|
+
onChange,
|
|
469
|
+
itemsClassName
|
|
470
|
+
}
|
|
471
|
+
)
|
|
472
|
+
))
|
|
473
|
+
);
|
|
474
|
+
}
|
|
397
475
|
function Combobox({
|
|
398
476
|
options,
|
|
399
477
|
value,
|
|
@@ -411,19 +489,23 @@ function Combobox({
|
|
|
411
489
|
size = "medium",
|
|
412
490
|
allowCreate = false,
|
|
413
491
|
onCreateOption,
|
|
492
|
+
matchTriggerWidth = true,
|
|
493
|
+
modalPopover = false,
|
|
494
|
+
side,
|
|
414
495
|
dynamicHeight = true,
|
|
415
|
-
dynamicHeightBottomPadding
|
|
416
|
-
dynamicHeightMinHeight
|
|
417
|
-
modalPopover = false
|
|
496
|
+
dynamicHeightBottomPadding,
|
|
497
|
+
dynamicHeightMinHeight
|
|
418
498
|
}) {
|
|
419
499
|
const { t } = useTranslation();
|
|
420
500
|
const [open, setOpen] = React.useState(false);
|
|
421
501
|
const [search, setSearch] = React.useState("");
|
|
422
502
|
const commandListRef = React.useRef(null);
|
|
423
|
-
const
|
|
503
|
+
const triggerRef = React.useRef(null);
|
|
504
|
+
const { ref: dynamicHeightRef, style: dynamicHeightStyle, preferredSide } = useDynamicMaxHeight({
|
|
424
505
|
enabled: open && dynamicHeight,
|
|
425
506
|
bottomPadding: dynamicHeightBottomPadding,
|
|
426
|
-
minHeight: dynamicHeightMinHeight
|
|
507
|
+
minHeight: dynamicHeightMinHeight,
|
|
508
|
+
triggerRef
|
|
427
509
|
});
|
|
428
510
|
const lastOpenOptionsRef = React.useRef(options);
|
|
429
511
|
React.useEffect(() => {
|
|
@@ -455,6 +537,7 @@ function Combobox({
|
|
|
455
537
|
return /* @__PURE__ */ React.createElement(Popover, { open, onOpenChange: handleOpenChange, modal: modalPopover }, /* @__PURE__ */ React.createElement(PopoverTrigger, { asChild: true }, /* @__PURE__ */ React.createElement(
|
|
456
538
|
ComboboxTriggerButton,
|
|
457
539
|
{
|
|
540
|
+
ref: triggerRef,
|
|
458
541
|
open,
|
|
459
542
|
disabled,
|
|
460
543
|
value,
|
|
@@ -466,52 +549,31 @@ function Combobox({
|
|
|
466
549
|
size
|
|
467
550
|
}
|
|
468
551
|
)), /* @__PURE__ */ React.createElement(
|
|
469
|
-
|
|
552
|
+
ComboboxPopoverContent,
|
|
470
553
|
{
|
|
471
|
-
|
|
472
|
-
|
|
473
|
-
|
|
474
|
-
|
|
475
|
-
|
|
476
|
-
|
|
477
|
-
|
|
478
|
-
|
|
479
|
-
|
|
480
|
-
|
|
481
|
-
|
|
482
|
-
|
|
483
|
-
|
|
484
|
-
|
|
485
|
-
|
|
486
|
-
|
|
487
|
-
|
|
488
|
-
|
|
489
|
-
|
|
490
|
-
|
|
491
|
-
|
|
492
|
-
|
|
493
|
-
|
|
494
|
-
"[&::-webkit-scrollbar-thumb]:bg-grey-300",
|
|
495
|
-
"[&::-webkit-scrollbar-thumb]:rounded-full",
|
|
496
|
-
"[&::-webkit-scrollbar-thumb]:hover:bg-grey-400"
|
|
497
|
-
)
|
|
498
|
-
},
|
|
499
|
-
/* @__PURE__ */ React.createElement(
|
|
500
|
-
ComboboxContent,
|
|
501
|
-
{
|
|
502
|
-
showCreateOption,
|
|
503
|
-
search,
|
|
504
|
-
onCreateOption,
|
|
505
|
-
onClose: handleClose,
|
|
506
|
-
size,
|
|
507
|
-
notFoundContent,
|
|
508
|
-
filteredOptions,
|
|
509
|
-
value,
|
|
510
|
-
onChange,
|
|
511
|
-
itemsClassName
|
|
512
|
-
}
|
|
513
|
-
)
|
|
514
|
-
))
|
|
554
|
+
dynamicHeightRef,
|
|
555
|
+
dynamicHeightStyle,
|
|
556
|
+
contentClassName,
|
|
557
|
+
side,
|
|
558
|
+
preferredSide,
|
|
559
|
+
dynamicHeight,
|
|
560
|
+
showSearch,
|
|
561
|
+
searchTerm,
|
|
562
|
+
t,
|
|
563
|
+
size,
|
|
564
|
+
search,
|
|
565
|
+
setSearch,
|
|
566
|
+
commandListRef,
|
|
567
|
+
showCreateOption,
|
|
568
|
+
onCreateOption,
|
|
569
|
+
handleClose,
|
|
570
|
+
notFoundContent,
|
|
571
|
+
filteredOptions,
|
|
572
|
+
value,
|
|
573
|
+
onChange,
|
|
574
|
+
itemsClassName,
|
|
575
|
+
matchTriggerWidth
|
|
576
|
+
}
|
|
515
577
|
));
|
|
516
578
|
}
|
|
517
579
|
|
|
@@ -54,6 +54,10 @@ const CustomTagItemComponent = React.memo(function CustomTagItemComponent2({
|
|
|
54
54
|
}, [editValue, item.id, item.label, onEdit]);
|
|
55
55
|
const handleKeyDown = React.useCallback(
|
|
56
56
|
(e) => {
|
|
57
|
+
if (e.key === ";") {
|
|
58
|
+
e.preventDefault();
|
|
59
|
+
return;
|
|
60
|
+
}
|
|
57
61
|
if (e.key === "Enter") {
|
|
58
62
|
e.preventDefault();
|
|
59
63
|
handleSave();
|
|
@@ -90,7 +94,7 @@ const CustomTagItemComponent = React.memo(function CustomTagItemComponent2({
|
|
|
90
94
|
type: "text",
|
|
91
95
|
value: editValue,
|
|
92
96
|
onChange: (e) => {
|
|
93
|
-
let newValue = e.target.value;
|
|
97
|
+
let newValue = e.target.value.replace(/;/g, "");
|
|
94
98
|
if (maxEditLength !== void 0 && newValue.length > maxEditLength) {
|
|
95
99
|
newValue = newValue.slice(0, maxEditLength);
|
|
96
100
|
}
|
|
@@ -47,7 +47,7 @@ const MultiSelect = React.forwardRef(
|
|
|
47
47
|
maxCount,
|
|
48
48
|
modalPopover = false,
|
|
49
49
|
className,
|
|
50
|
-
side
|
|
50
|
+
side,
|
|
51
51
|
treeOptions,
|
|
52
52
|
treeSelectionStrategy = "leaf",
|
|
53
53
|
selectAllLabel,
|
|
@@ -66,8 +66,8 @@ const MultiSelect = React.forwardRef(
|
|
|
66
66
|
readOnly = false,
|
|
67
67
|
status = "default",
|
|
68
68
|
dynamicHeight = true,
|
|
69
|
-
dynamicHeightBottomPadding
|
|
70
|
-
dynamicHeightMinHeight
|
|
69
|
+
dynamicHeightBottomPadding,
|
|
70
|
+
dynamicHeightMinHeight
|
|
71
71
|
}, ref) => {
|
|
72
72
|
const { t } = useTranslation();
|
|
73
73
|
const [selectedValues, setSelectedValues] = React.useState(value);
|
|
@@ -77,10 +77,11 @@ const MultiSelect = React.forwardRef(
|
|
|
77
77
|
selectedValues.length || 1
|
|
78
78
|
);
|
|
79
79
|
const buttonRef = React.useRef(null);
|
|
80
|
-
const { ref: dynamicHeightRef, style: dynamicHeightStyle } = useDynamicMaxHeight({
|
|
80
|
+
const { ref: dynamicHeightRef, style: dynamicHeightStyle, preferredSide } = useDynamicMaxHeight({
|
|
81
81
|
enabled: dynamicHeight && isPopoverOpen,
|
|
82
82
|
bottomPadding: dynamicHeightBottomPadding,
|
|
83
|
-
minHeight: dynamicHeightMinHeight
|
|
83
|
+
minHeight: dynamicHeightMinHeight,
|
|
84
|
+
triggerRef: buttonRef
|
|
84
85
|
});
|
|
85
86
|
React.useEffect(() => {
|
|
86
87
|
const shallowEqual = (a, b) => {
|
|
@@ -638,19 +639,21 @@ const MultiSelect = React.forwardRef(
|
|
|
638
639
|
ref: dynamicHeightRef,
|
|
639
640
|
style: dynamicHeightStyle,
|
|
640
641
|
className: cn(
|
|
641
|
-
"p-0 flex flex-col overflow-hidden
|
|
642
|
+
"p-0 flex flex-col overflow-hidden",
|
|
642
643
|
matchTriggerWidth && "w-[var(--radix-popover-trigger-width)]",
|
|
644
|
+
!dynamicHeight && "max-h-80",
|
|
643
645
|
classNameContent
|
|
644
646
|
),
|
|
645
|
-
side,
|
|
647
|
+
side: side ?? (dynamicHeight ? preferredSide : "bottom"),
|
|
646
648
|
align: "start",
|
|
649
|
+
avoidCollisions: true,
|
|
647
650
|
onEscapeKeyDown: () => setIsPopoverOpen(false)
|
|
648
651
|
},
|
|
649
652
|
!isTree && /* @__PURE__ */ React.createElement(
|
|
650
653
|
Command,
|
|
651
654
|
{
|
|
652
655
|
shouldFilter: false,
|
|
653
|
-
className: cn(
|
|
656
|
+
className: cn("max-h-full flex flex-col", SEARCH_INPUT_CLASSES[size])
|
|
654
657
|
},
|
|
655
658
|
/* @__PURE__ */ React.createElement(
|
|
656
659
|
CommandInput,
|
|
@@ -665,7 +668,7 @@ const MultiSelect = React.forwardRef(
|
|
|
665
668
|
/* @__PURE__ */ React.createElement(
|
|
666
669
|
CommandList,
|
|
667
670
|
{
|
|
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"
|
|
671
|
+
className: cn("flex-1 [&::-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", dynamicHeight && "max-h-none")
|
|
669
672
|
},
|
|
670
673
|
/* @__PURE__ */ React.createElement(CommandGroup, null, (effectiveOptions.length === 0 || query && filteredOptions.length === 0) && /* @__PURE__ */ React.createElement(
|
|
671
674
|
CommandEmpty,
|
|
@@ -756,11 +759,11 @@ const MultiSelect = React.forwardRef(
|
|
|
756
759
|
}
|
|
757
760
|
)
|
|
758
761
|
),
|
|
759
|
-
/* @__PURE__ */ React.createElement("div", { className: "flex items-center gap-2
|
|
762
|
+
/* @__PURE__ */ React.createElement("div", { className: "flex items-center gap-2 min-w-0" }, option.prefix && /* @__PURE__ */ React.createElement(Typography, { className: "flex items-center flex-shrink-0" }, option.prefix), /* @__PURE__ */ React.createElement(
|
|
760
763
|
Typography,
|
|
761
764
|
{
|
|
762
765
|
variant: getFontVariant(size),
|
|
763
|
-
className: "text-grey-800 break-words"
|
|
766
|
+
className: "text-grey-800 whitespace-normal min-w-0 break-words"
|
|
764
767
|
},
|
|
765
768
|
highlight(option.label, query)
|
|
766
769
|
))
|
|
@@ -801,7 +804,7 @@ const MultiSelect = React.forwardRef(
|
|
|
801
804
|
Typography,
|
|
802
805
|
{
|
|
803
806
|
variant: getFontVariant(size),
|
|
804
|
-
className: "text-grey-800 break-words"
|
|
807
|
+
className: "text-grey-800 whitespace-normal min-w-0 break-words"
|
|
805
808
|
},
|
|
806
809
|
highlight(option.label, query)
|
|
807
810
|
))
|
|
@@ -809,7 +812,7 @@ const MultiSelect = React.forwardRef(
|
|
|
809
812
|
}))
|
|
810
813
|
)
|
|
811
814
|
),
|
|
812
|
-
isTree && /* @__PURE__ */ React.createElement("div", { className: "min-w-[260px] overflow-hidden flex flex-col max-h-full
|
|
815
|
+
isTree && /* @__PURE__ */ React.createElement("div", { className: cn("min-w-[260px] overflow-hidden flex flex-col flex-1", dynamicHeight ? "max-h-full" : "max-h-80") }, 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(
|
|
813
816
|
"svg",
|
|
814
817
|
{
|
|
815
818
|
className: "absolute left-3 top-1/2 -translate-y-1/2 h-4 w-4 text-muted-foreground",
|
|
@@ -9,7 +9,7 @@ const TooltipTrigger = TooltipPrimitive.Trigger;
|
|
|
9
9
|
const TooltipArrow = TooltipPrimitive.Arrow;
|
|
10
10
|
const TooltipPortal = TooltipPrimitive.Portal;
|
|
11
11
|
const tooltipContentVariants = cva(
|
|
12
|
-
"z-
|
|
12
|
+
"z-[100] overflow-hidden rounded-lg px-3 py-2 max-w-80 body-small-500 shadow-md animate-in fade-in-0 zoom-in-95 data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=closed]:zoom-out-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2",
|
|
13
13
|
{
|
|
14
14
|
variants: {
|
|
15
15
|
color: {
|
|
@@ -45,7 +45,7 @@ const TooltipContent = React.forwardRef(
|
|
|
45
45
|
className,
|
|
46
46
|
children,
|
|
47
47
|
...props
|
|
48
|
-
}, ref) => /* @__PURE__ */ React.createElement(
|
|
48
|
+
}, ref) => /* @__PURE__ */ React.createElement(TooltipPortal, null, /* @__PURE__ */ React.createElement(
|
|
49
49
|
TooltipPrimitive.Content,
|
|
50
50
|
{
|
|
51
51
|
ref,
|
|
@@ -58,7 +58,7 @@ const TooltipContent = React.forwardRef(
|
|
|
58
58
|
},
|
|
59
59
|
children,
|
|
60
60
|
arrow && /* @__PURE__ */ React.createElement(TooltipArrow, { className: "tooltip-arrow", width: 12, height: 6 })
|
|
61
|
-
)
|
|
61
|
+
))
|
|
62
62
|
);
|
|
63
63
|
TooltipContent.displayName = TooltipPrimitive.Content.displayName;
|
|
64
64
|
|
|
@@ -1,50 +1,119 @@
|
|
|
1
1
|
import * as React from 'react';
|
|
2
2
|
|
|
3
|
-
const DEFAULT_BOTTOM_PADDING =
|
|
3
|
+
const DEFAULT_BOTTOM_PADDING = 25;
|
|
4
4
|
const DEFAULT_MIN_HEIGHT = 120;
|
|
5
|
+
function findDialogContainer(element) {
|
|
6
|
+
if (!element) return null;
|
|
7
|
+
let current = element;
|
|
8
|
+
while (current) {
|
|
9
|
+
if (current.hasAttribute("data-radix-dialog-content")) {
|
|
10
|
+
return current;
|
|
11
|
+
}
|
|
12
|
+
if (current.getAttribute("role") === "dialog") {
|
|
13
|
+
const isInsidePopover = current.closest("[data-radix-popper-content-wrapper]");
|
|
14
|
+
if (!isInsidePopover) {
|
|
15
|
+
return current;
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
if (current.classList.contains("dialog-content") || current.classList.contains("modal-content")) {
|
|
19
|
+
return current;
|
|
20
|
+
}
|
|
21
|
+
current = current.parentElement;
|
|
22
|
+
}
|
|
23
|
+
return null;
|
|
24
|
+
}
|
|
5
25
|
function useDynamicMaxHeight(options = {}) {
|
|
6
26
|
const {
|
|
7
27
|
enabled = false,
|
|
8
28
|
bottomPadding = DEFAULT_BOTTOM_PADDING,
|
|
9
|
-
minHeight = DEFAULT_MIN_HEIGHT
|
|
29
|
+
minHeight = DEFAULT_MIN_HEIGHT,
|
|
30
|
+
triggerRef,
|
|
31
|
+
detectDialogContainer = true
|
|
10
32
|
} = options;
|
|
33
|
+
const minHeightToFlip = minHeight ?? DEFAULT_MIN_HEIGHT;
|
|
11
34
|
const ref = React.useRef(null);
|
|
12
35
|
const [maxHeight, setMaxHeight] = React.useState(
|
|
13
36
|
void 0
|
|
14
37
|
);
|
|
38
|
+
const [preferredSide, setPreferredSide] = React.useState("bottom");
|
|
39
|
+
const [isInsideDialog, setIsInsideDialog] = React.useState(false);
|
|
15
40
|
const lastCalculatedHeight = React.useRef(void 0);
|
|
16
|
-
React.
|
|
17
|
-
|
|
18
|
-
|
|
41
|
+
const cachedDialogRef = React.useRef(null);
|
|
42
|
+
const initialHeightRef = React.useRef(void 0);
|
|
43
|
+
const calculateHeight = React.useCallback(() => {
|
|
44
|
+
const triggerElement = triggerRef?.current;
|
|
45
|
+
if (!triggerElement) return;
|
|
46
|
+
let dialogElement = null;
|
|
47
|
+
if (detectDialogContainer) {
|
|
48
|
+
if (!cachedDialogRef.current) {
|
|
49
|
+
cachedDialogRef.current = findDialogContainer(triggerElement);
|
|
50
|
+
}
|
|
51
|
+
dialogElement = cachedDialogRef.current;
|
|
52
|
+
}
|
|
53
|
+
const triggerRect = triggerElement.getBoundingClientRect();
|
|
54
|
+
let boundaryTop;
|
|
55
|
+
let boundaryBottom;
|
|
56
|
+
let boundaryHeight;
|
|
57
|
+
if (dialogElement) {
|
|
58
|
+
const containerRect = dialogElement.getBoundingClientRect();
|
|
59
|
+
const dialogPadding = 24;
|
|
60
|
+
boundaryTop = containerRect.top + dialogPadding;
|
|
61
|
+
boundaryBottom = containerRect.bottom - dialogPadding;
|
|
62
|
+
boundaryHeight = boundaryBottom - boundaryTop;
|
|
63
|
+
} else {
|
|
64
|
+
boundaryTop = 0;
|
|
65
|
+
boundaryBottom = window.innerHeight;
|
|
66
|
+
boundaryHeight = window.innerHeight;
|
|
19
67
|
}
|
|
20
|
-
const
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
68
|
+
const triggerBottom = triggerRect.bottom;
|
|
69
|
+
const triggerTop = triggerRect.top;
|
|
70
|
+
const insideDialog = !!dialogElement;
|
|
71
|
+
setIsInsideDialog(insideDialog);
|
|
72
|
+
const effectiveBottomPadding = insideDialog ? 0 : bottomPadding;
|
|
73
|
+
const adjustedBottomPadding = boundaryHeight < 500 ? 10 : effectiveBottomPadding;
|
|
74
|
+
const adjustedMinBeforeFlip = insideDialog ? 0 : minHeightToFlip;
|
|
75
|
+
const spaceBelow = boundaryBottom - triggerBottom;
|
|
76
|
+
const spaceAbove = triggerTop - boundaryTop;
|
|
77
|
+
let finalHeight;
|
|
78
|
+
if (spaceBelow >= adjustedMinBeforeFlip + adjustedBottomPadding) {
|
|
79
|
+
setPreferredSide("bottom");
|
|
80
|
+
const availableHeight = spaceBelow - adjustedBottomPadding;
|
|
81
|
+
finalHeight = Math.max(availableHeight, minHeight);
|
|
82
|
+
} else {
|
|
83
|
+
setPreferredSide("top");
|
|
84
|
+
const availableHeight = spaceAbove - adjustedBottomPadding;
|
|
85
|
+
finalHeight = Math.max(availableHeight, minHeight);
|
|
86
|
+
}
|
|
87
|
+
if (initialHeightRef.current === void 0) {
|
|
88
|
+
initialHeightRef.current = finalHeight;
|
|
28
89
|
lastCalculatedHeight.current = finalHeight;
|
|
29
90
|
setMaxHeight(finalHeight);
|
|
30
|
-
}
|
|
31
|
-
|
|
32
|
-
|
|
91
|
+
}
|
|
92
|
+
}, [triggerRef, detectDialogContainer, bottomPadding, minHeight, minHeightToFlip]);
|
|
93
|
+
React.useLayoutEffect(() => {
|
|
94
|
+
if (!enabled) {
|
|
95
|
+
cachedDialogRef.current = null;
|
|
96
|
+
initialHeightRef.current = void 0;
|
|
97
|
+
setMaxHeight(void 0);
|
|
98
|
+
return;
|
|
99
|
+
}
|
|
100
|
+
cachedDialogRef.current = null;
|
|
101
|
+
initialHeightRef.current = void 0;
|
|
102
|
+
calculateHeight();
|
|
103
|
+
const rafId = requestAnimationFrame(() => {
|
|
104
|
+
if (initialHeightRef.current === void 0) {
|
|
33
105
|
calculateHeight();
|
|
34
|
-
}
|
|
106
|
+
}
|
|
35
107
|
});
|
|
36
|
-
window.addEventListener("resize", calculateHeight);
|
|
37
|
-
window.addEventListener("scroll", calculateHeight, true);
|
|
38
108
|
return () => {
|
|
39
|
-
|
|
40
|
-
window.removeEventListener("scroll", calculateHeight, true);
|
|
109
|
+
cancelAnimationFrame(rafId);
|
|
41
110
|
};
|
|
42
|
-
}, [enabled,
|
|
111
|
+
}, [enabled, calculateHeight]);
|
|
43
112
|
const style = React.useMemo(() => {
|
|
44
113
|
if (maxHeight === void 0) return {};
|
|
45
114
|
return { maxHeight: `${maxHeight}px` };
|
|
46
115
|
}, [maxHeight]);
|
|
47
|
-
return { ref, maxHeight, style };
|
|
116
|
+
return { ref, maxHeight, style, preferredSide, isInsideDialog };
|
|
48
117
|
}
|
|
49
118
|
|
|
50
119
|
export { useDynamicMaxHeight };
|