lecom-ui 5.4.46 → 5.4.47
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/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 +9 -7
- package/dist/style.min.css +1 -1
- package/package.json +134 -134
|
@@ -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 };
|
package/dist/index.d.ts
CHANGED
|
@@ -792,8 +792,8 @@ interface HeaderProps extends React$1.HTMLAttributes<HTMLElement>, VariantProps<
|
|
|
792
792
|
|
|
793
793
|
declare const inputVariants: (props?: ({
|
|
794
794
|
variant?: "default" | "filled" | "borderless" | null | undefined;
|
|
795
|
-
size?: "
|
|
796
|
-
radius?: "
|
|
795
|
+
size?: "default" | "small" | "large" | null | undefined;
|
|
796
|
+
radius?: "default" | "small" | "large" | "full" | null | undefined;
|
|
797
797
|
status?: "default" | "error" | null | undefined;
|
|
798
798
|
} & class_variance_authority_types.ClassProp) | undefined) => string;
|
|
799
799
|
interface InputProps extends Omit<React$1.InputHTMLAttributes<HTMLInputElement>, 'size' | 'sufix' | 'prefix'>, VariantProps<typeof inputVariants> {
|
|
@@ -1010,7 +1010,7 @@ declare const RadioGroup: React$1.ForwardRefExoticComponent<Omit<RadioGroupPrimi
|
|
|
1010
1010
|
declare const RadioGroupItem: React$1.ForwardRefExoticComponent<Omit<RadioGroupPrimitive.RadioGroupItemProps & React$1.RefAttributes<HTMLButtonElement>, "ref"> & React$1.RefAttributes<HTMLButtonElement>>;
|
|
1011
1011
|
|
|
1012
1012
|
declare const ResizablePanelGroup: ({ className, ...props }: React$1.ComponentProps<typeof ResizablePrimitive.PanelGroup>) => React$1.JSX.Element;
|
|
1013
|
-
declare const ResizablePanel: React$1.ForwardRefExoticComponent<Omit<React$1.HTMLAttributes<HTMLDivElement | HTMLElement | HTMLButtonElement | HTMLOListElement | HTMLLIElement | HTMLAnchorElement | HTMLSpanElement |
|
|
1013
|
+
declare const ResizablePanel: React$1.ForwardRefExoticComponent<Omit<React$1.HTMLAttributes<HTMLDivElement | HTMLElement | HTMLButtonElement | HTMLOListElement | HTMLLIElement | HTMLAnchorElement | HTMLSpanElement | HTMLLabelElement | HTMLParagraphElement | HTMLHeadingElement | HTMLInputElement | HTMLObjectElement | HTMLAreaElement | HTMLAudioElement | HTMLBaseElement | HTMLQuoteElement | HTMLBodyElement | HTMLBRElement | HTMLCanvasElement | HTMLTableCaptionElement | HTMLTableColElement | HTMLDataElement | HTMLDataListElement | HTMLModElement | HTMLDetailsElement | HTMLDialogElement | HTMLDListElement | HTMLEmbedElement | HTMLFieldSetElement | HTMLFormElement | HTMLHeadElement | HTMLHRElement | HTMLHtmlElement | HTMLIFrameElement | HTMLImageElement | HTMLLegendElement | HTMLLinkElement | HTMLMapElement | HTMLMenuElement | HTMLMetaElement | HTMLMeterElement | HTMLOptGroupElement | HTMLOptionElement | HTMLOutputElement | HTMLPictureElement | HTMLPreElement | HTMLProgressElement | HTMLScriptElement | HTMLSelectElement | HTMLSlotElement | HTMLSourceElement | HTMLStyleElement | HTMLTableElement | HTMLTableSectionElement | HTMLTableCellElement | HTMLTemplateElement | HTMLTextAreaElement | HTMLTimeElement | HTMLTitleElement | HTMLTableRowElement | HTMLTrackElement | HTMLUListElement | HTMLVideoElement>, "id" | "onResize"> & {
|
|
1014
1014
|
className?: string;
|
|
1015
1015
|
collapsedSize?: number | undefined;
|
|
1016
1016
|
collapsible?: boolean | undefined;
|
|
@@ -1177,8 +1177,8 @@ declare const TabsContent: React$1.ForwardRefExoticComponent<Omit<TabsPrimitive.
|
|
|
1177
1177
|
|
|
1178
1178
|
declare const textareaVariants: (props?: ({
|
|
1179
1179
|
variant?: "default" | "filled" | "borderless" | null | undefined;
|
|
1180
|
-
size?: "
|
|
1181
|
-
radius?: "
|
|
1180
|
+
size?: "default" | "small" | "large" | null | undefined;
|
|
1181
|
+
radius?: "default" | "small" | "large" | "full" | null | undefined;
|
|
1182
1182
|
resize?: "default" | "both" | "horizontal" | "vertical" | "vertical-limited" | null | undefined;
|
|
1183
1183
|
status?: "default" | "error" | null | undefined;
|
|
1184
1184
|
} & class_variance_authority_types.ClassProp) | undefined) => string;
|
|
@@ -1251,12 +1251,14 @@ type ComboboxProps = {
|
|
|
1251
1251
|
size?: ComboboxSize;
|
|
1252
1252
|
allowCreate?: boolean;
|
|
1253
1253
|
onCreateOption?: (inputValue: string) => void;
|
|
1254
|
+
matchTriggerWidth?: boolean;
|
|
1255
|
+
modalPopover?: boolean;
|
|
1256
|
+
side?: 'top' | 'right' | 'bottom' | 'left';
|
|
1254
1257
|
dynamicHeight?: boolean;
|
|
1255
1258
|
dynamicHeightBottomPadding?: number;
|
|
1256
1259
|
dynamicHeightMinHeight?: number;
|
|
1257
|
-
modalPopover?: boolean;
|
|
1258
1260
|
};
|
|
1259
|
-
declare function Combobox({ options, value, onChange, placeholder, disabled, notFoundContent, status, searchTerm, triggerClassName, contentClassName, itemsClassName, rounded, showSearch, size, allowCreate, onCreateOption, dynamicHeight, dynamicHeightBottomPadding, dynamicHeightMinHeight,
|
|
1261
|
+
declare function Combobox({ options, value, onChange, placeholder, disabled, notFoundContent, status, searchTerm, triggerClassName, contentClassName, itemsClassName, rounded, showSearch, size, allowCreate, onCreateOption, matchTriggerWidth, modalPopover, side, dynamicHeight, dynamicHeightBottomPadding, dynamicHeightMinHeight, }: ComboboxProps): React$1.JSX.Element;
|
|
1260
1262
|
|
|
1261
1263
|
interface TagItem {
|
|
1262
1264
|
label: string;
|