fui-material 2.7.10 → 2.7.12
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/f-ui-kit.es.js +177 -65
- package/dist/f-ui-kit.es.js.map +1 -1
- package/dist/f-ui-kit.umd.js +2 -2
- package/dist/f-ui-kit.umd.js.map +1 -1
- package/dist/index.css +1 -1
- package/dist/types/material/Dialog/FDialog/FDialog.d.ts +2 -0
- package/dist/types/material/FSearchableSelect/FSearchableSelect.d.ts +1 -38
- package/package.json +1 -1
package/dist/f-ui-kit.es.js
CHANGED
|
@@ -1009,20 +1009,22 @@ const FTableFooter = ({
|
|
|
1009
1009
|
}
|
|
1010
1010
|
);
|
|
1011
1011
|
};
|
|
1012
|
-
const
|
|
1013
|
-
const
|
|
1012
|
+
const entering = "_entering_dwagt_17";
|
|
1013
|
+
const exiting = "_exiting_dwagt_23";
|
|
1014
|
+
const hide = "_hide_dwagt_45";
|
|
1014
1015
|
const styles$r = {
|
|
1015
|
-
"f-dialog": "_f-
|
|
1016
|
-
|
|
1017
|
-
"f-dialog__content": "_f-
|
|
1018
|
-
|
|
1016
|
+
"f-dialog": "_f-dialog_dwagt_1",
|
|
1017
|
+
entering,
|
|
1018
|
+
"f-dialog__content": "_f-dialog__content_dwagt_20",
|
|
1019
|
+
exiting,
|
|
1019
1020
|
hide,
|
|
1020
|
-
"f-dialog__header": "_f-
|
|
1021
|
-
"f-dialog__header_title": "_f-
|
|
1022
|
-
"f-dialog__header_close": "_f-
|
|
1023
|
-
"f-dialog__body": "_f-
|
|
1024
|
-
"f-dialog__footer": "_f-
|
|
1021
|
+
"f-dialog__header": "_f-dialog__header_dwagt_49",
|
|
1022
|
+
"f-dialog__header_title": "_f-dialog__header_title_dwagt_61",
|
|
1023
|
+
"f-dialog__header_close": "_f-dialog__header_close_dwagt_72",
|
|
1024
|
+
"f-dialog__body": "_f-dialog__body_dwagt_87",
|
|
1025
|
+
"f-dialog__footer": "_f-dialog__footer_dwagt_92"
|
|
1025
1026
|
};
|
|
1027
|
+
let openDialogsCount = 0;
|
|
1026
1028
|
const FDialog = ({
|
|
1027
1029
|
openAndClose,
|
|
1028
1030
|
closeButtonBackPage,
|
|
@@ -1033,22 +1035,55 @@ const FDialog = ({
|
|
|
1033
1035
|
st,
|
|
1034
1036
|
width = "lg"
|
|
1035
1037
|
}) => {
|
|
1038
|
+
const [isMounted, setIsMounted] = useState(openAndClose);
|
|
1039
|
+
const [isClosing, setIsClosing] = useState(false);
|
|
1036
1040
|
useEffect(() => {
|
|
1037
|
-
if (
|
|
1038
|
-
|
|
1039
|
-
|
|
1040
|
-
|
|
1041
|
-
|
|
1042
|
-
document.body.classList.remove("open-dialog");
|
|
1041
|
+
if (openAndClose) {
|
|
1042
|
+
setIsMounted(true);
|
|
1043
|
+
setIsClosing(false);
|
|
1044
|
+
} else if (isMounted) {
|
|
1045
|
+
setIsClosing(true);
|
|
1043
1046
|
}
|
|
1044
|
-
return () => {
|
|
1045
|
-
const updatedCount = document.querySelectorAll(".active-dialog").length;
|
|
1046
|
-
if (updatedCount === 0) {
|
|
1047
|
-
document.body.classList.remove("open-dialog");
|
|
1048
|
-
}
|
|
1049
|
-
};
|
|
1050
1047
|
}, [openAndClose]);
|
|
1051
|
-
|
|
1048
|
+
const handleAnimationEnd = (e) => {
|
|
1049
|
+
if (isClosing && e.target === e.currentTarget) {
|
|
1050
|
+
setIsMounted(false);
|
|
1051
|
+
setIsClosing(false);
|
|
1052
|
+
}
|
|
1053
|
+
};
|
|
1054
|
+
useEffect(() => {
|
|
1055
|
+
if (isClosing) {
|
|
1056
|
+
const timer = setTimeout(() => {
|
|
1057
|
+
setIsMounted(false);
|
|
1058
|
+
setIsClosing(false);
|
|
1059
|
+
}, 300);
|
|
1060
|
+
return () => clearTimeout(timer);
|
|
1061
|
+
}
|
|
1062
|
+
}, [isClosing]);
|
|
1063
|
+
useEffect(() => {
|
|
1064
|
+
if (isMounted && !isClosing) {
|
|
1065
|
+
openDialogsCount += 1;
|
|
1066
|
+
document.body.classList.add("open-dialog");
|
|
1067
|
+
return () => {
|
|
1068
|
+
openDialogsCount = Math.max(0, openDialogsCount - 1);
|
|
1069
|
+
if (openDialogsCount === 0) {
|
|
1070
|
+
document.body.classList.remove("open-dialog");
|
|
1071
|
+
}
|
|
1072
|
+
};
|
|
1073
|
+
}
|
|
1074
|
+
}, [isMounted, isClosing]);
|
|
1075
|
+
const handleKeyDown = useCallback((e) => {
|
|
1076
|
+
if (e.key === "Escape" && openAndClose && !isClosing) {
|
|
1077
|
+
closeButtonBackPage == null ? void 0 : closeButtonBackPage(false);
|
|
1078
|
+
}
|
|
1079
|
+
}, [openAndClose, isClosing, closeButtonBackPage]);
|
|
1080
|
+
useEffect(() => {
|
|
1081
|
+
if (isMounted && !isClosing) {
|
|
1082
|
+
window.addEventListener("keydown", handleKeyDown);
|
|
1083
|
+
return () => window.removeEventListener("keydown", handleKeyDown);
|
|
1084
|
+
}
|
|
1085
|
+
}, [isMounted, isClosing, handleKeyDown]);
|
|
1086
|
+
if (!isMounted) return null;
|
|
1052
1087
|
const widthStyles = {
|
|
1053
1088
|
xs: "50vw",
|
|
1054
1089
|
md: "65vw",
|
|
@@ -1057,22 +1092,28 @@ const FDialog = ({
|
|
|
1057
1092
|
adaptive: "fit-content"
|
|
1058
1093
|
};
|
|
1059
1094
|
const contentWidth = widthStyles[width];
|
|
1095
|
+
const animationClass = isClosing ? styles$r["exiting"] : styles$r["entering"];
|
|
1060
1096
|
return ReactDOM.createPortal(
|
|
1061
1097
|
/* @__PURE__ */ jsx(
|
|
1062
1098
|
"div",
|
|
1063
1099
|
{
|
|
1064
1100
|
id,
|
|
1065
1101
|
style: st,
|
|
1066
|
-
className: `${styles$r["f-dialog"]} ${
|
|
1067
|
-
|
|
1102
|
+
className: `${styles$r["f-dialog"]} ${animationClass} ${className || ""}`,
|
|
1103
|
+
onMouseDown: (e) => {
|
|
1104
|
+
if (e.target === e.currentTarget) {
|
|
1105
|
+
closeButtonBackPage == null ? void 0 : closeButtonBackPage(false);
|
|
1106
|
+
}
|
|
1107
|
+
},
|
|
1108
|
+
onAnimationEnd: handleAnimationEnd,
|
|
1068
1109
|
children: /* @__PURE__ */ jsx(
|
|
1069
1110
|
"div",
|
|
1070
1111
|
{
|
|
1071
|
-
className: `${styles$r["f-dialog__content"]} ${
|
|
1112
|
+
className: `${styles$r["f-dialog__content"]} ${hide2 ? styles$r["hide"] : ""}`,
|
|
1072
1113
|
style: {
|
|
1073
1114
|
width: contentWidth
|
|
1074
1115
|
},
|
|
1075
|
-
|
|
1116
|
+
onMouseDown: (e) => e.stopPropagation(),
|
|
1076
1117
|
children
|
|
1077
1118
|
}
|
|
1078
1119
|
)
|
|
@@ -3446,24 +3487,24 @@ const FTooltip = ({
|
|
|
3446
3487
|
tooltipElement && createPortal(tooltipElement, document.body)
|
|
3447
3488
|
] });
|
|
3448
3489
|
};
|
|
3449
|
-
const rotate = "
|
|
3450
|
-
const focused = "
|
|
3451
|
-
const selected = "
|
|
3490
|
+
const rotate = "_rotate_1kvw2_38";
|
|
3491
|
+
const focused = "_focused_1kvw2_87";
|
|
3492
|
+
const selected = "_selected_1kvw2_90";
|
|
3452
3493
|
const styles$6 = {
|
|
3453
|
-
"f-search-select": "_f-search-
|
|
3454
|
-
"f-select-native-hidden": "_f-select-native-
|
|
3455
|
-
"f-select-actions": "_f-select-
|
|
3456
|
-
"f-select-icon": "_f-select-
|
|
3494
|
+
"f-search-select": "_f-search-select_1kvw2_3",
|
|
3495
|
+
"f-select-native-hidden": "_f-select-native-hidden_1kvw2_9",
|
|
3496
|
+
"f-select-actions": "_f-select-actions_1kvw2_20",
|
|
3497
|
+
"f-select-icon": "_f-select-icon_1kvw2_29",
|
|
3457
3498
|
rotate,
|
|
3458
|
-
"f-select-dropdown": "_f-select-
|
|
3459
|
-
"f-select-list": "_f-select-
|
|
3460
|
-
"f-select-option": "_f-select-
|
|
3499
|
+
"f-select-dropdown": "_f-select-dropdown_1kvw2_43",
|
|
3500
|
+
"f-select-list": "_f-select-list_1kvw2_54",
|
|
3501
|
+
"f-select-option": "_f-select-option_1kvw2_75",
|
|
3461
3502
|
focused,
|
|
3462
3503
|
selected,
|
|
3463
|
-
"f-select-create": "_f-select-
|
|
3464
|
-
"f-select-no-results": "_f-select-no-
|
|
3465
|
-
"f-select-highlight": "_f-select-
|
|
3466
|
-
"has-icons": "_has-
|
|
3504
|
+
"f-select-create": "_f-select-create_1kvw2_95",
|
|
3505
|
+
"f-select-no-results": "_f-select-no-results_1kvw2_101",
|
|
3506
|
+
"f-select-highlight": "_f-select-highlight_1kvw2_121",
|
|
3507
|
+
"has-icons": "_has-icons_1kvw2_128"
|
|
3467
3508
|
};
|
|
3468
3509
|
const ChevronIcon = ({ className }) => /* @__PURE__ */ jsx("svg", { width: "16", height: "16", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", className, children: /* @__PURE__ */ jsx("polyline", { points: "6 9 12 15 18 9" }) });
|
|
3469
3510
|
const CloseIcon = () => /* @__PURE__ */ jsxs("svg", { width: "14", height: "14", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", children: [
|
|
@@ -3525,7 +3566,11 @@ const FSearchableSelect = forwardRef(
|
|
|
3525
3566
|
const [searchQuery, setSearchQuery] = useState("");
|
|
3526
3567
|
const [highlightedIndex, setHighlightedIndex] = useState(0);
|
|
3527
3568
|
const [isTyping, setIsTyping] = useState(false);
|
|
3569
|
+
const [dropdownStyle, setDropdownStyle] = useState({});
|
|
3570
|
+
const [listMaxHeight, setListMaxHeight] = useState(300);
|
|
3528
3571
|
const containerRef = useRef(null);
|
|
3572
|
+
const controlRef = useRef(null);
|
|
3573
|
+
const dropdownRef = useRef(null);
|
|
3529
3574
|
const visibleInputRef = useRef(null);
|
|
3530
3575
|
const listRef = useRef(null);
|
|
3531
3576
|
const lastValueRef = useRef(restProps.value !== void 0 ? String(restProps.value) : "");
|
|
@@ -3543,11 +3588,48 @@ const FSearchableSelect = forwardRef(
|
|
|
3543
3588
|
return;
|
|
3544
3589
|
}
|
|
3545
3590
|
setIsTyping(true);
|
|
3546
|
-
const timeoutId = setTimeout(() =>
|
|
3547
|
-
setIsTyping(false);
|
|
3548
|
-
}, 1e3);
|
|
3591
|
+
const timeoutId = setTimeout(() => setIsTyping(false), 1e3);
|
|
3549
3592
|
return () => clearTimeout(timeoutId);
|
|
3550
3593
|
}, [searchQuery, isOpen]);
|
|
3594
|
+
const updateDropdownPosition = () => {
|
|
3595
|
+
if (!controlRef.current || !isOpen) return;
|
|
3596
|
+
const rect = controlRef.current.getBoundingClientRect();
|
|
3597
|
+
const viewportHeight = window.innerHeight;
|
|
3598
|
+
const spaceBelow = viewportHeight - rect.bottom;
|
|
3599
|
+
const spaceAbove = rect.top;
|
|
3600
|
+
let top, bottom, maxHeight;
|
|
3601
|
+
const gap = 4;
|
|
3602
|
+
if (spaceBelow < 250 && spaceAbove > spaceBelow) {
|
|
3603
|
+
bottom = viewportHeight - rect.top + gap;
|
|
3604
|
+
top = "auto";
|
|
3605
|
+
maxHeight = Math.min(spaceAbove - 20, 350);
|
|
3606
|
+
} else {
|
|
3607
|
+
top = rect.bottom + gap;
|
|
3608
|
+
bottom = "auto";
|
|
3609
|
+
maxHeight = Math.min(spaceBelow - 20, 350);
|
|
3610
|
+
}
|
|
3611
|
+
setDropdownStyle({
|
|
3612
|
+
position: "fixed",
|
|
3613
|
+
top,
|
|
3614
|
+
bottom,
|
|
3615
|
+
left: rect.left,
|
|
3616
|
+
width: rect.width,
|
|
3617
|
+
zIndex: 999999
|
|
3618
|
+
// Поверх модалок
|
|
3619
|
+
});
|
|
3620
|
+
setListMaxHeight(maxHeight);
|
|
3621
|
+
};
|
|
3622
|
+
useLayoutEffect(() => {
|
|
3623
|
+
if (isOpen) {
|
|
3624
|
+
updateDropdownPosition();
|
|
3625
|
+
window.addEventListener("scroll", updateDropdownPosition, true);
|
|
3626
|
+
window.addEventListener("resize", updateDropdownPosition);
|
|
3627
|
+
}
|
|
3628
|
+
return () => {
|
|
3629
|
+
window.removeEventListener("scroll", updateDropdownPosition, true);
|
|
3630
|
+
window.removeEventListener("resize", updateDropdownPosition);
|
|
3631
|
+
};
|
|
3632
|
+
}, [isOpen]);
|
|
3551
3633
|
const deferredQuery = useDeferredValue(searchQuery);
|
|
3552
3634
|
const filteredOptions = useMemo(() => {
|
|
3553
3635
|
if (!isOpen) return options;
|
|
@@ -3567,6 +3649,14 @@ const FSearchableSelect = forwardRef(
|
|
|
3567
3649
|
}
|
|
3568
3650
|
return list;
|
|
3569
3651
|
}, [filteredOptions, showCreateOption, deferredQuery]);
|
|
3652
|
+
useEffect(() => {
|
|
3653
|
+
if (isOpen && listRef.current) {
|
|
3654
|
+
const activeItem = listRef.current.children[highlightedIndex];
|
|
3655
|
+
if (activeItem) {
|
|
3656
|
+
activeItem.scrollIntoView({ block: "nearest" });
|
|
3657
|
+
}
|
|
3658
|
+
}
|
|
3659
|
+
}, [highlightedIndex, isOpen]);
|
|
3570
3660
|
const triggerChange = (newValue) => {
|
|
3571
3661
|
lastValueRef.current = newValue;
|
|
3572
3662
|
if (restProps.onChange) {
|
|
@@ -3591,7 +3681,10 @@ const FSearchableSelect = forwardRef(
|
|
|
3591
3681
|
};
|
|
3592
3682
|
useEffect(() => {
|
|
3593
3683
|
const handleClickOutside = (event) => {
|
|
3594
|
-
|
|
3684
|
+
var _a, _b;
|
|
3685
|
+
const isClickInContainer = (_a = containerRef.current) == null ? void 0 : _a.contains(event.target);
|
|
3686
|
+
const isClickInDropdown = (_b = dropdownRef.current) == null ? void 0 : _b.contains(event.target);
|
|
3687
|
+
if (!isClickInContainer && !isClickInDropdown) {
|
|
3595
3688
|
setIsOpen(false);
|
|
3596
3689
|
const effectiveValue = restProps.value !== void 0 ? String(restProps.value) : lastValueRef.current;
|
|
3597
3690
|
if (effectiveValue) {
|
|
@@ -3669,7 +3762,7 @@ const FSearchableSelect = forwardRef(
|
|
|
3669
3762
|
"aria-hidden": "true"
|
|
3670
3763
|
}
|
|
3671
3764
|
),
|
|
3672
|
-
/* @__PURE__ */ jsxs("div", { className: `f-form-element__control ${load ? "is-loading" : ""}`, children: [
|
|
3765
|
+
/* @__PURE__ */ jsxs("div", { ref: controlRef, className: `f-form-element__control ${load ? "is-loading" : ""}`, children: [
|
|
3673
3766
|
/* @__PURE__ */ jsx(
|
|
3674
3767
|
"input",
|
|
3675
3768
|
{
|
|
@@ -3713,29 +3806,48 @@ const FSearchableSelect = forwardRef(
|
|
|
3713
3806
|
/* @__PURE__ */ jsx("div", { className: `${styles$6["f-select-icon"]} ${isOpen ? styles$6["rotate"] : ""}`, children: /* @__PURE__ */ jsx(ChevronIcon, {}) })
|
|
3714
3807
|
] })
|
|
3715
3808
|
] }),
|
|
3716
|
-
isOpen && !disabled2 && !load &&
|
|
3717
|
-
|
|
3718
|
-
|
|
3719
|
-
|
|
3809
|
+
isOpen && !disabled2 && !load && typeof document !== "undefined" && createPortal(
|
|
3810
|
+
/* @__PURE__ */ jsx(
|
|
3811
|
+
"div",
|
|
3812
|
+
{
|
|
3813
|
+
className: styles$6["f-select-dropdown"],
|
|
3814
|
+
style: dropdownStyle,
|
|
3815
|
+
ref: dropdownRef,
|
|
3816
|
+
children: /* @__PURE__ */ jsx(
|
|
3817
|
+
"ul",
|
|
3818
|
+
{
|
|
3819
|
+
ref: listRef,
|
|
3820
|
+
className: styles$6["f-select-list"],
|
|
3821
|
+
style: { maxHeight: `${listMaxHeight}px` },
|
|
3822
|
+
children: isTyping ? /* @__PURE__ */ jsx("li", { className: styles$6["f-select-no-results"], children: "Ожидается окончание ввода..." }) : renderList.length === 0 ? /* @__PURE__ */ jsx("li", { className: styles$6["f-select-no-results"], children: allowCreate ? "Нет данных" : "Совпадений не найдено" }) : renderList.map((option, index) => /* @__PURE__ */ jsx(
|
|
3823
|
+
"li",
|
|
3824
|
+
{
|
|
3825
|
+
className: `
|
|
3720
3826
|
${styles$6["f-select-option"]}
|
|
3721
3827
|
${option.isNew ? styles$6["f-select-create"] : ""}
|
|
3722
3828
|
${index === highlightedIndex ? styles$6["focused"] : ""}
|
|
3723
3829
|
${currentValStr === option.value ? styles$6["selected"] : ""}
|
|
3724
3830
|
`,
|
|
3725
|
-
|
|
3726
|
-
|
|
3727
|
-
|
|
3728
|
-
|
|
3729
|
-
|
|
3730
|
-
|
|
3731
|
-
|
|
3732
|
-
|
|
3733
|
-
|
|
3734
|
-
|
|
3735
|
-
|
|
3736
|
-
|
|
3737
|
-
|
|
3738
|
-
|
|
3831
|
+
onMouseDown: (e) => e.preventDefault(),
|
|
3832
|
+
onClick: (e) => {
|
|
3833
|
+
e.stopPropagation();
|
|
3834
|
+
handleSelect(option);
|
|
3835
|
+
},
|
|
3836
|
+
onMouseEnter: () => setHighlightedIndex(index),
|
|
3837
|
+
children: /* @__PURE__ */ jsxs("div", { style: { overflow: "hidden", textOverflow: "ellipsis" }, children: [
|
|
3838
|
+
option.isNew && /* @__PURE__ */ jsx("span", { style: { marginRight: 4 }, children: /* @__PURE__ */ jsx(PlusIcon, {}) }),
|
|
3839
|
+
/* @__PURE__ */ jsx(HighlightedText, { text: option.label, highlight: deferredQuery }),
|
|
3840
|
+
option.isNew && /* @__PURE__ */ jsx("span", { style: { opacity: 0.6, fontSize: "0.85em", marginLeft: 6 }, children: "(Создать)" })
|
|
3841
|
+
] })
|
|
3842
|
+
},
|
|
3843
|
+
option.value + index
|
|
3844
|
+
))
|
|
3845
|
+
}
|
|
3846
|
+
)
|
|
3847
|
+
}
|
|
3848
|
+
),
|
|
3849
|
+
document.body
|
|
3850
|
+
),
|
|
3739
3851
|
helpText && /* @__PURE__ */ jsx(
|
|
3740
3852
|
"p",
|
|
3741
3853
|
{
|