fui-material 2.7.10 → 2.7.11

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.
@@ -3446,24 +3446,24 @@ const FTooltip = ({
3446
3446
  tooltipElement && createPortal(tooltipElement, document.body)
3447
3447
  ] });
3448
3448
  };
3449
- const rotate = "_rotate_fq6h3_43";
3450
- const focused = "_focused_fq6h3_94";
3451
- const selected = "_selected_fq6h3_97";
3449
+ const rotate = "_rotate_1kvw2_38";
3450
+ const focused = "_focused_1kvw2_87";
3451
+ const selected = "_selected_1kvw2_90";
3452
3452
  const styles$6 = {
3453
- "f-search-select": "_f-search-select_fq6h3_3",
3454
- "f-select-native-hidden": "_f-select-native-hidden_fq6h3_8",
3455
- "f-select-actions": "_f-select-actions_fq6h3_25",
3456
- "f-select-icon": "_f-select-icon_fq6h3_34",
3453
+ "f-search-select": "_f-search-select_1kvw2_3",
3454
+ "f-select-native-hidden": "_f-select-native-hidden_1kvw2_9",
3455
+ "f-select-actions": "_f-select-actions_1kvw2_20",
3456
+ "f-select-icon": "_f-select-icon_1kvw2_29",
3457
3457
  rotate,
3458
- "f-select-dropdown": "_f-select-dropdown_fq6h3_48",
3459
- "f-select-list": "_f-select-list_fq6h3_62",
3460
- "f-select-option": "_f-select-option_fq6h3_81",
3458
+ "f-select-dropdown": "_f-select-dropdown_1kvw2_43",
3459
+ "f-select-list": "_f-select-list_1kvw2_54",
3460
+ "f-select-option": "_f-select-option_1kvw2_75",
3461
3461
  focused,
3462
3462
  selected,
3463
- "f-select-create": "_f-select-create_fq6h3_102",
3464
- "f-select-no-results": "_f-select-no-results_fq6h3_108",
3465
- "f-select-highlight": "_f-select-highlight_fq6h3_128",
3466
- "has-icons": "_has-icons_fq6h3_135"
3463
+ "f-select-create": "_f-select-create_1kvw2_95",
3464
+ "f-select-no-results": "_f-select-no-results_1kvw2_101",
3465
+ "f-select-highlight": "_f-select-highlight_1kvw2_121",
3466
+ "has-icons": "_has-icons_1kvw2_128"
3467
3467
  };
3468
3468
  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
3469
  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 +3525,11 @@ const FSearchableSelect = forwardRef(
3525
3525
  const [searchQuery, setSearchQuery] = useState("");
3526
3526
  const [highlightedIndex, setHighlightedIndex] = useState(0);
3527
3527
  const [isTyping, setIsTyping] = useState(false);
3528
+ const [dropdownStyle, setDropdownStyle] = useState({});
3529
+ const [listMaxHeight, setListMaxHeight] = useState(300);
3528
3530
  const containerRef = useRef(null);
3531
+ const controlRef = useRef(null);
3532
+ const dropdownRef = useRef(null);
3529
3533
  const visibleInputRef = useRef(null);
3530
3534
  const listRef = useRef(null);
3531
3535
  const lastValueRef = useRef(restProps.value !== void 0 ? String(restProps.value) : "");
@@ -3543,11 +3547,48 @@ const FSearchableSelect = forwardRef(
3543
3547
  return;
3544
3548
  }
3545
3549
  setIsTyping(true);
3546
- const timeoutId = setTimeout(() => {
3547
- setIsTyping(false);
3548
- }, 1e3);
3550
+ const timeoutId = setTimeout(() => setIsTyping(false), 1e3);
3549
3551
  return () => clearTimeout(timeoutId);
3550
3552
  }, [searchQuery, isOpen]);
3553
+ const updateDropdownPosition = () => {
3554
+ if (!controlRef.current || !isOpen) return;
3555
+ const rect = controlRef.current.getBoundingClientRect();
3556
+ const viewportHeight = window.innerHeight;
3557
+ const spaceBelow = viewportHeight - rect.bottom;
3558
+ const spaceAbove = rect.top;
3559
+ let top, bottom, maxHeight;
3560
+ const gap = 4;
3561
+ if (spaceBelow < 250 && spaceAbove > spaceBelow) {
3562
+ bottom = viewportHeight - rect.top + gap;
3563
+ top = "auto";
3564
+ maxHeight = Math.min(spaceAbove - 20, 350);
3565
+ } else {
3566
+ top = rect.bottom + gap;
3567
+ bottom = "auto";
3568
+ maxHeight = Math.min(spaceBelow - 20, 350);
3569
+ }
3570
+ setDropdownStyle({
3571
+ position: "fixed",
3572
+ top,
3573
+ bottom,
3574
+ left: rect.left,
3575
+ width: rect.width,
3576
+ zIndex: 999999
3577
+ // Поверх модалок
3578
+ });
3579
+ setListMaxHeight(maxHeight);
3580
+ };
3581
+ useLayoutEffect(() => {
3582
+ if (isOpen) {
3583
+ updateDropdownPosition();
3584
+ window.addEventListener("scroll", updateDropdownPosition, true);
3585
+ window.addEventListener("resize", updateDropdownPosition);
3586
+ }
3587
+ return () => {
3588
+ window.removeEventListener("scroll", updateDropdownPosition, true);
3589
+ window.removeEventListener("resize", updateDropdownPosition);
3590
+ };
3591
+ }, [isOpen]);
3551
3592
  const deferredQuery = useDeferredValue(searchQuery);
3552
3593
  const filteredOptions = useMemo(() => {
3553
3594
  if (!isOpen) return options;
@@ -3567,6 +3608,14 @@ const FSearchableSelect = forwardRef(
3567
3608
  }
3568
3609
  return list;
3569
3610
  }, [filteredOptions, showCreateOption, deferredQuery]);
3611
+ useEffect(() => {
3612
+ if (isOpen && listRef.current) {
3613
+ const activeItem = listRef.current.children[highlightedIndex];
3614
+ if (activeItem) {
3615
+ activeItem.scrollIntoView({ block: "nearest" });
3616
+ }
3617
+ }
3618
+ }, [highlightedIndex, isOpen]);
3570
3619
  const triggerChange = (newValue) => {
3571
3620
  lastValueRef.current = newValue;
3572
3621
  if (restProps.onChange) {
@@ -3591,7 +3640,10 @@ const FSearchableSelect = forwardRef(
3591
3640
  };
3592
3641
  useEffect(() => {
3593
3642
  const handleClickOutside = (event) => {
3594
- if (containerRef.current && !containerRef.current.contains(event.target)) {
3643
+ var _a, _b;
3644
+ const isClickInContainer = (_a = containerRef.current) == null ? void 0 : _a.contains(event.target);
3645
+ const isClickInDropdown = (_b = dropdownRef.current) == null ? void 0 : _b.contains(event.target);
3646
+ if (!isClickInContainer && !isClickInDropdown) {
3595
3647
  setIsOpen(false);
3596
3648
  const effectiveValue = restProps.value !== void 0 ? String(restProps.value) : lastValueRef.current;
3597
3649
  if (effectiveValue) {
@@ -3669,7 +3721,7 @@ const FSearchableSelect = forwardRef(
3669
3721
  "aria-hidden": "true"
3670
3722
  }
3671
3723
  ),
3672
- /* @__PURE__ */ jsxs("div", { className: `f-form-element__control ${load ? "is-loading" : ""}`, children: [
3724
+ /* @__PURE__ */ jsxs("div", { ref: controlRef, className: `f-form-element__control ${load ? "is-loading" : ""}`, children: [
3673
3725
  /* @__PURE__ */ jsx(
3674
3726
  "input",
3675
3727
  {
@@ -3713,29 +3765,48 @@ const FSearchableSelect = forwardRef(
3713
3765
  /* @__PURE__ */ jsx("div", { className: `${styles$6["f-select-icon"]} ${isOpen ? styles$6["rotate"] : ""}`, children: /* @__PURE__ */ jsx(ChevronIcon, {}) })
3714
3766
  ] })
3715
3767
  ] }),
3716
- isOpen && !disabled2 && !load && /* @__PURE__ */ jsx("div", { className: styles$6["f-select-dropdown"], children: /* @__PURE__ */ jsx("ul", { ref: listRef, className: styles$6["f-select-list"], 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(
3717
- "li",
3718
- {
3719
- className: `
3768
+ isOpen && !disabled2 && !load && typeof document !== "undefined" && createPortal(
3769
+ /* @__PURE__ */ jsx(
3770
+ "div",
3771
+ {
3772
+ className: styles$6["f-select-dropdown"],
3773
+ style: dropdownStyle,
3774
+ ref: dropdownRef,
3775
+ children: /* @__PURE__ */ jsx(
3776
+ "ul",
3777
+ {
3778
+ ref: listRef,
3779
+ className: styles$6["f-select-list"],
3780
+ style: { maxHeight: `${listMaxHeight}px` },
3781
+ 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(
3782
+ "li",
3783
+ {
3784
+ className: `
3720
3785
  ${styles$6["f-select-option"]}
3721
3786
  ${option.isNew ? styles$6["f-select-create"] : ""}
3722
3787
  ${index === highlightedIndex ? styles$6["focused"] : ""}
3723
3788
  ${currentValStr === option.value ? styles$6["selected"] : ""}
3724
3789
  `,
3725
- onMouseDown: (e) => e.preventDefault(),
3726
- onClick: (e) => {
3727
- e.stopPropagation();
3728
- handleSelect(option);
3729
- },
3730
- onMouseEnter: () => setHighlightedIndex(index),
3731
- children: /* @__PURE__ */ jsxs("div", { style: { overflow: "hidden", textOverflow: "ellipsis" }, children: [
3732
- option.isNew && /* @__PURE__ */ jsx("span", { style: { marginRight: 4 }, children: /* @__PURE__ */ jsx(PlusIcon, {}) }),
3733
- /* @__PURE__ */ jsx(HighlightedText, { text: option.label, highlight: deferredQuery }),
3734
- option.isNew && /* @__PURE__ */ jsx("span", { style: { opacity: 0.6, fontSize: "0.85em", marginLeft: 6 }, children: "(Создать)" })
3735
- ] })
3736
- },
3737
- option.value + index
3738
- )) }) }),
3790
+ onMouseDown: (e) => e.preventDefault(),
3791
+ onClick: (e) => {
3792
+ e.stopPropagation();
3793
+ handleSelect(option);
3794
+ },
3795
+ onMouseEnter: () => setHighlightedIndex(index),
3796
+ children: /* @__PURE__ */ jsxs("div", { style: { overflow: "hidden", textOverflow: "ellipsis" }, children: [
3797
+ option.isNew && /* @__PURE__ */ jsx("span", { style: { marginRight: 4 }, children: /* @__PURE__ */ jsx(PlusIcon, {}) }),
3798
+ /* @__PURE__ */ jsx(HighlightedText, { text: option.label, highlight: deferredQuery }),
3799
+ option.isNew && /* @__PURE__ */ jsx("span", { style: { opacity: 0.6, fontSize: "0.85em", marginLeft: 6 }, children: "(Создать)" })
3800
+ ] })
3801
+ },
3802
+ option.value + index
3803
+ ))
3804
+ }
3805
+ )
3806
+ }
3807
+ ),
3808
+ document.body
3809
+ ),
3739
3810
  helpText && /* @__PURE__ */ jsx(
3740
3811
  "p",
3741
3812
  {