fui-material 2.7.9 → 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.
@@ -1,5 +1,5 @@
1
1
  import { jsx, jsxs, Fragment } from "react/jsx-runtime";
2
- import React, { forwardRef, useRef, useState, useEffect, useMemo, useCallback, useLayoutEffect, Fragment as Fragment$1, isValidElement, cloneElement, Children, useDeferredValue, createContext, useContext } from "react";
2
+ import React, { forwardRef, useRef, useState, useEffect, useMemo, useCallback, useLayoutEffect, Fragment as Fragment$1, isValidElement, cloneElement, createContext, useContext, useDeferredValue } from "react";
3
3
  import ReactDOM, { createPortal } from "react-dom";
4
4
  import JSZip from "jszip";
5
5
  import initializeModule from "allorion-exporting-html-to-docx";
@@ -3147,6 +3147,7 @@ const styles$8 = {
3147
3147
  badge,
3148
3148
  disabled
3149
3149
  };
3150
+ const MenuSearchContext = createContext("");
3150
3151
  const FMenuBlockLinks = ({
3151
3152
  children,
3152
3153
  className,
@@ -3160,14 +3161,6 @@ const FMenuBlockLinks = ({
3160
3161
  ...columns ? { "--cols": columns } : {},
3161
3162
  ...st
3162
3163
  };
3163
- const enhancedChildren = Children.map(children, (child) => {
3164
- if (isValidElement(child)) {
3165
- return cloneElement(child, {
3166
- searchTerm: searchValue
3167
- });
3168
- }
3169
- return child;
3170
- });
3171
3164
  return /* @__PURE__ */ jsxs("div", { className: `${styles$8.reportsPageContainer} ${className ?? ""}`.trim(), id, children: [
3172
3165
  withSearch && /* @__PURE__ */ jsx("div", { className: styles$8.searchBar, children: /* @__PURE__ */ jsx(
3173
3166
  "input",
@@ -3178,7 +3171,7 @@ const FMenuBlockLinks = ({
3178
3171
  onChange: (e) => setSearchValue(e.target.value)
3179
3172
  }
3180
3173
  ) }),
3181
- /* @__PURE__ */ jsx("div", { className: styles$8.reportsGrid, style: layoutStyle, children: enhancedChildren })
3174
+ /* @__PURE__ */ jsx(MenuSearchContext.Provider, { value: searchValue, children: /* @__PURE__ */ jsx("div", { className: styles$8.reportsGrid, style: layoutStyle, children }) })
3182
3175
  ] });
3183
3176
  };
3184
3177
  const getElementText = (node) => {
@@ -3194,9 +3187,9 @@ const FMenuLinks = ({
3194
3187
  id,
3195
3188
  disabled: disabled2 = [],
3196
3189
  badges = [],
3197
- title: title2,
3198
- searchTerm = ""
3190
+ title: title2
3199
3191
  }) => {
3192
+ const searchTerm = useContext(MenuSearchContext);
3200
3193
  const originalArray = React.Children.toArray(children);
3201
3194
  const filteredChildren = originalArray.filter((child) => {
3202
3195
  if (!searchTerm) return true;
@@ -3453,24 +3446,24 @@ const FTooltip = ({
3453
3446
  tooltipElement && createPortal(tooltipElement, document.body)
3454
3447
  ] });
3455
3448
  };
3456
- const rotate = "_rotate_fq6h3_43";
3457
- const focused = "_focused_fq6h3_94";
3458
- const selected = "_selected_fq6h3_97";
3449
+ const rotate = "_rotate_1kvw2_38";
3450
+ const focused = "_focused_1kvw2_87";
3451
+ const selected = "_selected_1kvw2_90";
3459
3452
  const styles$6 = {
3460
- "f-search-select": "_f-search-select_fq6h3_3",
3461
- "f-select-native-hidden": "_f-select-native-hidden_fq6h3_8",
3462
- "f-select-actions": "_f-select-actions_fq6h3_25",
3463
- "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",
3464
3457
  rotate,
3465
- "f-select-dropdown": "_f-select-dropdown_fq6h3_48",
3466
- "f-select-list": "_f-select-list_fq6h3_62",
3467
- "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",
3468
3461
  focused,
3469
3462
  selected,
3470
- "f-select-create": "_f-select-create_fq6h3_102",
3471
- "f-select-no-results": "_f-select-no-results_fq6h3_108",
3472
- "f-select-highlight": "_f-select-highlight_fq6h3_128",
3473
- "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"
3474
3467
  };
3475
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" }) });
3476
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: [
@@ -3532,7 +3525,11 @@ const FSearchableSelect = forwardRef(
3532
3525
  const [searchQuery, setSearchQuery] = useState("");
3533
3526
  const [highlightedIndex, setHighlightedIndex] = useState(0);
3534
3527
  const [isTyping, setIsTyping] = useState(false);
3528
+ const [dropdownStyle, setDropdownStyle] = useState({});
3529
+ const [listMaxHeight, setListMaxHeight] = useState(300);
3535
3530
  const containerRef = useRef(null);
3531
+ const controlRef = useRef(null);
3532
+ const dropdownRef = useRef(null);
3536
3533
  const visibleInputRef = useRef(null);
3537
3534
  const listRef = useRef(null);
3538
3535
  const lastValueRef = useRef(restProps.value !== void 0 ? String(restProps.value) : "");
@@ -3550,11 +3547,48 @@ const FSearchableSelect = forwardRef(
3550
3547
  return;
3551
3548
  }
3552
3549
  setIsTyping(true);
3553
- const timeoutId = setTimeout(() => {
3554
- setIsTyping(false);
3555
- }, 1e3);
3550
+ const timeoutId = setTimeout(() => setIsTyping(false), 1e3);
3556
3551
  return () => clearTimeout(timeoutId);
3557
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]);
3558
3592
  const deferredQuery = useDeferredValue(searchQuery);
3559
3593
  const filteredOptions = useMemo(() => {
3560
3594
  if (!isOpen) return options;
@@ -3574,6 +3608,14 @@ const FSearchableSelect = forwardRef(
3574
3608
  }
3575
3609
  return list;
3576
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]);
3577
3619
  const triggerChange = (newValue) => {
3578
3620
  lastValueRef.current = newValue;
3579
3621
  if (restProps.onChange) {
@@ -3598,7 +3640,10 @@ const FSearchableSelect = forwardRef(
3598
3640
  };
3599
3641
  useEffect(() => {
3600
3642
  const handleClickOutside = (event) => {
3601
- 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) {
3602
3647
  setIsOpen(false);
3603
3648
  const effectiveValue = restProps.value !== void 0 ? String(restProps.value) : lastValueRef.current;
3604
3649
  if (effectiveValue) {
@@ -3676,7 +3721,7 @@ const FSearchableSelect = forwardRef(
3676
3721
  "aria-hidden": "true"
3677
3722
  }
3678
3723
  ),
3679
- /* @__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: [
3680
3725
  /* @__PURE__ */ jsx(
3681
3726
  "input",
3682
3727
  {
@@ -3720,29 +3765,48 @@ const FSearchableSelect = forwardRef(
3720
3765
  /* @__PURE__ */ jsx("div", { className: `${styles$6["f-select-icon"]} ${isOpen ? styles$6["rotate"] : ""}`, children: /* @__PURE__ */ jsx(ChevronIcon, {}) })
3721
3766
  ] })
3722
3767
  ] }),
3723
- 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(
3724
- "li",
3725
- {
3726
- 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: `
3727
3785
  ${styles$6["f-select-option"]}
3728
3786
  ${option.isNew ? styles$6["f-select-create"] : ""}
3729
3787
  ${index === highlightedIndex ? styles$6["focused"] : ""}
3730
3788
  ${currentValStr === option.value ? styles$6["selected"] : ""}
3731
3789
  `,
3732
- onMouseDown: (e) => e.preventDefault(),
3733
- onClick: (e) => {
3734
- e.stopPropagation();
3735
- handleSelect(option);
3736
- },
3737
- onMouseEnter: () => setHighlightedIndex(index),
3738
- children: /* @__PURE__ */ jsxs("div", { style: { overflow: "hidden", textOverflow: "ellipsis" }, children: [
3739
- option.isNew && /* @__PURE__ */ jsx("span", { style: { marginRight: 4 }, children: /* @__PURE__ */ jsx(PlusIcon, {}) }),
3740
- /* @__PURE__ */ jsx(HighlightedText, { text: option.label, highlight: deferredQuery }),
3741
- option.isNew && /* @__PURE__ */ jsx("span", { style: { opacity: 0.6, fontSize: "0.85em", marginLeft: 6 }, children: "(Создать)" })
3742
- ] })
3743
- },
3744
- option.value + index
3745
- )) }) }),
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
+ ),
3746
3810
  helpText && /* @__PURE__ */ jsx(
3747
3811
  "p",
3748
3812
  {