@kne/react-filter 1.0.7 → 1.0.9

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,8 +1,9 @@
1
1
  import classnames from 'classnames';
2
- import { useContext as useContext$1, createContext, useState, useEffect, useRef, useCallback, useLayoutEffect, useMemo, createElement } from 'react';
2
+ import { useContext as useContext$1, createContext, useEffect, useRef, useState, useCallback, useLayoutEffect, useMemo, createElement } from 'react';
3
3
  import { Space, Row, Col, Tag, Button, Dropdown, Input, InputNumber, DatePicker, Flex, Select, App } from 'antd';
4
4
  import { useIntl, createWithIntlProvider } from '@kne/react-intl';
5
5
  import get from 'lodash/get';
6
+ import { useResponsiveContext, useMediaQuery, IS_MOBILE_QUERY, MOBILE_BREAKPOINT, useScrollElement, resetViewportCssVars, applyViewportCssVars, RESPONSIVE_BOUNDARY_CLASS, usePopupContainer } from '@kne/responsive-utils';
6
7
  import { jsxs, Fragment, jsx } from 'react/jsx-runtime';
7
8
  import { UpOutlined, DownOutlined } from '@ant-design/icons';
8
9
  import clone from 'lodash/clone';
@@ -36,7 +37,7 @@ function _objectWithoutPropertiesLoose(r, e) {
36
37
  return t;
37
38
  }
38
39
 
39
- var style$1 = {"filter":"kne-react-filter_b3gMw","filter-item-icon":"kne-react-filter_e3V6h","filter-item-option-icon":"kne-react-filter_dLoYj","filter-title":"kne-react-filter_khFt2","filter-title-hidden":"kne-react-filter_j2mP1","ad-filter-title":"kne-react-filter_HptIY","ad-filter-line":"kne-react-filter_7Ob6-","filter-line":"kne-react-filter_Y9XTa","clean-btn":"kne-react-filter_CJ935","filter-item":"kne-react-filter_JpaMr","un-expand":"kne-react-filter_LfQME","ad-filter-selected":"kne-react-filter_pBsaE","filter-label":"kne-react-filter_Bx3s8","filter-line-nowrap":"kne-react-filter_Ccx24","filter-line-measure":"kne-react-filter_uMXzo","filter-item-wrap":"kne-react-filter_Co4Pg","option":"kne-react-filter_G1cRp","is-active":"kne-react-filter_Aab98","is-visited":"kne-react-filter_Ww12R","un-expand-shadow":"kne-react-filter_2ExqW","filter-item-label":"kne-react-filter_JAmeE","filter-item-field":"kne-react-filter_WvRvl","filter-drop-tag":"kne-react-filter_dG8rq","filter-list":"kne-react-filter_qlWu6","filter-list-scroll-wrap":"kne-react-filter_oaIF4","filter-list-constrained":"kne-react-filter_3gXxO","filter-list-scroll":"kne-react-filter_Jq43Q","filter-scroll-next":"kne-react-filter_BdfSI","filter-list-tag":"kne-react-filter_LV2VI","filter-tag":"kne-react-filter_yyR3u","filter-tag-value":"kne-react-filter_8nm8n","filter-value-tag":"kne-react-filter_tWyCr","filter-value-tag-label":"kne-react-filter_XPzrL","filter-value-tag-content":"kne-react-filter_6e79l","filter-value-display-content":"kne-react-filter_v2dnw","filter-value-tags-wrap":"kne-react-filter_J1wBU","filter-value-tags":"kne-react-filter_rRhFE","filter-value-actions":"kne-react-filter_-Brt9","filter-value-toggle":"kne-react-filter_WuL0c","pop-util-content":"kne-react-filter_g-hXk","pop-util-body":"kne-react-filter_4n4MP","date-range-picker-popup":"kne-react-filter_6Zx60","pop-util-overlay":"kne-react-filter_m7Csi","pop-util-mask":"kne-react-filter_o2B3k","pop-util-mask-fade-in":"kne-react-filter_oCXiX","pop-util-mask-leave":"kne-react-filter_qGnRO","pop-util-mask-fade-out":"kne-react-filter_cDx1y","field-item-mobile-popup":"kne-react-filter_wq5nf","pop-util-mobile-expand-down":"kne-react-filter_6RxjE","date-picker-popup":"kne-react-filter_iwLs2","pop-util-mobile-collapse-up":"kne-react-filter_009r-","pop-util-footer":"kne-react-filter_iqe8W","pop-util-text":"kne-react-filter_72gGQ","filter-item-inner":"kne-react-filter_cYX12","filter-item-text":"kne-react-filter_cnMY-","filter-item-number-range":"kne-react-filter_Cv2Bw","filter-item-custom":"kne-react-filter_CBczA","filter-item-custom-active":"kne-react-filter_ldxUR","filter-item-number-range-split":"kne-react-filter_4p3C9","filter-item-number-input":"kne-react-filter_yy1y1","range-picker":"kne-react-filter_81zQn","cascader-select-wrap":"kne-react-filter_UHBfi","cascader-dropdown-menu":"kne-react-filter_bY8JQ","filter-advanced":"kne-react-filter_rg45N","filter-advanced-item-other":"kne-react-filter_HcsA8","filter-advanced-item-other-inner":"kne-react-filter_4Bqtz","filter-advanced-more":"kne-react-filter_jVH7z","filter-value-display":"kne-react-filter_8-R34","is-not-overflow":"kne-react-filter_TM1E2","is-expand":"kne-react-filter_7aclr","filter-value-scroll-prev-shadow":"kne-react-filter_C1t-q","filter-value-scroll-next-shadow":"kne-react-filter_ZFoeL","is-overflow":"kne-react-filter_GhFCl","filter-value-action-placeholder":"kne-react-filter_wGZp6","filter-value-action-right":"kne-react-filter_vyPwo","filter-scroll-prev-shadow":"kne-react-filter_fyhz3","filter-scroll-next-icon":"kne-react-filter_Fd6ab"};
40
+ var style$1 = {"kne-responsive-boundary":"kne-react-filter_gh14z","kne-responsive-scroll":"kne-react-filter_Kfn6L","filter":"kne-react-filter_b3gMw","filter-item-icon":"kne-react-filter_e3V6h","filter-item-option-icon":"kne-react-filter_dLoYj","filter-title":"kne-react-filter_khFt2","filter-title-hidden":"kne-react-filter_j2mP1","ad-filter-title":"kne-react-filter_HptIY","ad-filter-line":"kne-react-filter_7Ob6-","filter-line":"kne-react-filter_Y9XTa","clean-btn":"kne-react-filter_CJ935","filter-item":"kne-react-filter_JpaMr","un-expand":"kne-react-filter_LfQME","ad-filter-selected":"kne-react-filter_pBsaE","filter-label":"kne-react-filter_Bx3s8","filter-line-nowrap":"kne-react-filter_Ccx24","filter-line-measure":"kne-react-filter_uMXzo","filter-item-wrap":"kne-react-filter_Co4Pg","option":"kne-react-filter_G1cRp","is-active":"kne-react-filter_Aab98","is-visited":"kne-react-filter_Ww12R","un-expand-shadow":"kne-react-filter_2ExqW","filter-item-label":"kne-react-filter_JAmeE","filter-item-field":"kne-react-filter_WvRvl","filter-drop-tag":"kne-react-filter_dG8rq","filter-list":"kne-react-filter_qlWu6","filter-list-scroll-wrap":"kne-react-filter_oaIF4","filter-list-constrained":"kne-react-filter_3gXxO","filter-list-scroll":"kne-react-filter_Jq43Q","filter-scroll-next":"kne-react-filter_BdfSI","filter-list-tag":"kne-react-filter_LV2VI","filter-tag":"kne-react-filter_yyR3u","filter-tag-value":"kne-react-filter_8nm8n","filter-value-tag":"kne-react-filter_tWyCr","filter-value-tag-label":"kne-react-filter_XPzrL","filter-value-tag-content":"kne-react-filter_6e79l","filter-value-display-content":"kne-react-filter_v2dnw","filter-value-display":"kne-react-filter_8-R34","is-hide-label":"kne-react-filter_zpGJE","is-flush":"kne-react-filter_z8bDM","filter-value-tags-wrap":"kne-react-filter_J1wBU","filter-value-tags":"kne-react-filter_rRhFE","filter-value-actions":"kne-react-filter_-Brt9","filter-value-toggle":"kne-react-filter_WuL0c","pop-util-content":"kne-react-filter_g-hXk","pop-util-body":"kne-react-filter_4n4MP","date-range-picker-popup":"kne-react-filter_6Zx60","pop-util-overlay":"kne-react-filter_m7Csi","pop-util-mask":"kne-react-filter_o2B3k","pop-util-mask-fade-in":"kne-react-filter_oCXiX","is-viewport":"kne-react-filter_3Wr-x","is-boundary":"kne-react-filter_pPiQ8","pop-util-mask-leave":"kne-react-filter_qGnRO","pop-util-mask-fade-out":"kne-react-filter_cDx1y","field-item-mobile-popup":"kne-react-filter_wq5nf","pop-util-mobile-expand-down":"kne-react-filter_6RxjE","date-picker-popup":"kne-react-filter_iwLs2","pop-util-mobile-collapse-up":"kne-react-filter_009r-","pop-util-footer":"kne-react-filter_iqe8W","pop-util-text":"kne-react-filter_72gGQ","filter-item-inner":"kne-react-filter_cYX12","filter-item-text":"kne-react-filter_cnMY-","filter-item-number-range":"kne-react-filter_Cv2Bw","filter-item-custom":"kne-react-filter_CBczA","filter-item-custom-active":"kne-react-filter_ldxUR","filter-item-number-range-split":"kne-react-filter_4p3C9","filter-item-number-input":"kne-react-filter_yy1y1","range-picker":"kne-react-filter_81zQn","cascader-select-wrap":"kne-react-filter_UHBfi","cascader-dropdown-menu":"kne-react-filter_bY8JQ","filter-advanced":"kne-react-filter_rg45N","filter-advanced-item-other":"kne-react-filter_HcsA8","filter-advanced-item-other-inner":"kne-react-filter_4Bqtz","filter-advanced-more":"kne-react-filter_jVH7z","is-mobile":"kne-react-filter_LtgJz","is-not-overflow":"kne-react-filter_TM1E2","is-expand":"kne-react-filter_7aclr","filter-value-scroll-prev-shadow":"kne-react-filter_C1t-q","filter-value-scroll-next-shadow":"kne-react-filter_ZFoeL","is-overflow":"kne-react-filter_GhFCl","filter-value-action-placeholder":"kne-react-filter_wGZp6","filter-value-action-right":"kne-react-filter_vyPwo","filter-scroll-prev-shadow":"kne-react-filter_fyhz3","filter-scroll-next-icon":"kne-react-filter_Fd6ab"};
40
41
 
41
42
  const context = /*#__PURE__*/createContext({});
42
43
  const {
@@ -44,21 +45,52 @@ const {
44
45
  } = context;
45
46
  const useContext = () => useContext$1(context);
46
47
 
47
- const useMobile = () => {
48
- const [isMobile, setIsMobile] = useState(false);
48
+ /**
49
+ * Filter 移动端判定:默认按视口宽度,仅在 ResponsiveProvider container 模式下按预览容器宽度。
50
+ * 避免 Filter 嵌入窄列时误用移动端布局。
51
+ */
52
+ const useFilterIsMobile = () => {
53
+ const {
54
+ mode,
55
+ containerWidth
56
+ } = useResponsiveContext();
57
+ const viewportIsMobile = useMediaQuery(IS_MOBILE_QUERY);
58
+ if (mode === 'container' && typeof containerWidth === 'number') {
59
+ return containerWidth < MOBILE_BREAKPOINT;
60
+ }
61
+ return viewportIsMobile;
62
+ };
63
+
64
+ const useResponsiveScrollListener = (callback, enabled = true) => {
65
+ const getScrollElement = useScrollElement();
49
66
  useEffect(() => {
50
- if (typeof window === 'undefined') return;
51
- const mediaQuery = window.matchMedia('(max-width: 768px)');
52
- const updateIsMobile = () => {
53
- setIsMobile(mediaQuery.matches);
67
+ if (!enabled || typeof callback !== 'function') {
68
+ return undefined;
69
+ }
70
+ const scrollEl = getScrollElement();
71
+ if (!scrollEl) {
72
+ return undefined;
73
+ }
74
+ callback();
75
+ const handleChange = () => {
76
+ callback();
54
77
  };
55
- updateIsMobile();
56
- mediaQuery.addEventListener ? mediaQuery.addEventListener('change', updateIsMobile) : mediaQuery.addListener(updateIsMobile);
78
+ scrollEl.addEventListener('scroll', handleChange, {
79
+ passive: true
80
+ });
81
+ window.addEventListener('resize', handleChange);
82
+ let resizeObserver;
83
+ if (typeof ResizeObserver !== 'undefined') {
84
+ resizeObserver = new ResizeObserver(handleChange);
85
+ resizeObserver.observe(scrollEl);
86
+ }
57
87
  return () => {
58
- mediaQuery.removeEventListener ? mediaQuery.removeEventListener('change', updateIsMobile) : mediaQuery.removeListener(updateIsMobile);
88
+ var _resizeObserver;
89
+ scrollEl.removeEventListener('scroll', handleChange);
90
+ window.removeEventListener('resize', handleChange);
91
+ (_resizeObserver = resizeObserver) == null || _resizeObserver.disconnect();
59
92
  };
60
- }, []);
61
- return isMobile;
93
+ }, [callback, enabled, getScrollElement]);
62
94
  };
63
95
 
64
96
  const useHorizontalScrollShadows = ({
@@ -99,14 +131,13 @@ const useHorizontalScrollShadows = ({
99
131
  }
100
132
  update();
101
133
  el.addEventListener('scroll', update);
102
- window.addEventListener('resize', update);
103
134
  const rafId = window.requestAnimationFrame(update);
104
135
  return () => {
105
136
  el.removeEventListener('scroll', update);
106
- window.removeEventListener('resize', update);
107
137
  window.cancelAnimationFrame(rafId);
108
138
  };
109
139
  }, [enabled, refreshKey, _suspend, update]);
140
+ useResponsiveScrollListener(update, enabled && !_suspend);
110
141
  return {
111
142
  scrollRef,
112
143
  isOverflow,
@@ -253,16 +284,15 @@ const useVisibleItemCount = ({
253
284
  });
254
285
  lastWidthRef.current = containerEl.clientWidth;
255
286
  observer.observe(containerEl);
256
- window.addEventListener('resize', scheduleCalculate);
257
287
  return () => {
258
288
  observer.disconnect();
259
- window.removeEventListener('resize', scheduleCalculate);
260
289
  if (rafRef.current) {
261
290
  window.cancelAnimationFrame(rafRef.current);
262
291
  rafRef.current = null;
263
292
  }
264
293
  };
265
294
  }, [containerEl, enabled, scheduleCalculate]);
295
+ useResponsiveScrollListener(scheduleCalculate, enabled && !!containerEl);
266
296
  return {
267
297
  setContainerRef,
268
298
  setMeasureRef,
@@ -404,7 +434,7 @@ const FilterLines = ({
404
434
  const mobileList = useMemo(() => getMobileFilterList(_list), [_list]);
405
435
  const isFlatMode = mode === 'flat';
406
436
  const [isExpand, setIsExpand] = useState(false);
407
- const isMobile = useMobile();
437
+ const isMobile = useFilterIsMobile();
408
438
  const {
409
439
  scrollRef,
410
440
  showScrollPrev,
@@ -681,7 +711,10 @@ const withLocale = createWithIntlProvider({
681
711
  const FilterValueDisplay = withLocale(({
682
712
  value: filterValue,
683
713
  extraExpand,
684
- onChange
714
+ onChange,
715
+ className,
716
+ hideLabel,
717
+ flush
685
718
  }) => {
686
719
  const {
687
720
  formatMessage
@@ -689,7 +722,7 @@ const FilterValueDisplay = withLocale(({
689
722
  moduleName: 'Filter'
690
723
  });
691
724
  const [isExpand, setIsExpand] = useState(false);
692
- const isMobile = useMobile();
725
+ const isMobile = useFilterIsMobile();
693
726
  const {
694
727
  scrollRef,
695
728
  isOverflow,
@@ -725,10 +758,13 @@ const FilterValueDisplay = withLocale(({
725
758
  }, name);
726
759
  });
727
760
  return /*#__PURE__*/jsxs(Space, {
728
- className: classnames(style$1['filter-title'], style$1['filter-value-display']),
761
+ className: classnames(style$1['filter-title'], style$1['filter-value-display'], 'filter-value-display-root', {
762
+ [style$1['is-hide-label']]: hideLabel,
763
+ [style$1['is-flush']]: flush
764
+ }, className),
729
765
  align: "top",
730
- size: 16,
731
- children: [/*#__PURE__*/jsx("span", {
766
+ size: hideLabel ? 0 : 16,
767
+ children: [hideLabel ? null : /*#__PURE__*/jsx("span", {
732
768
  className: style$1['filter-label'],
733
769
  children: formatMessage({
734
770
  id: 'selectedText'
@@ -843,6 +879,34 @@ const FilterProvider = ({
843
879
  });
844
880
  };
845
881
 
882
+ const useFilterViewportVars = () => {
883
+ const boundaryRef = useRef(null);
884
+ const {
885
+ mode
886
+ } = useResponsiveContext();
887
+ useEffect(() => {
888
+ const el = boundaryRef.current;
889
+ if (!el || typeof window === 'undefined' || mode === 'container') {
890
+ return undefined;
891
+ }
892
+ const update = () => {
893
+ applyViewportCssVars(el, {
894
+ width: window.innerWidth,
895
+ height: window.innerHeight
896
+ });
897
+ };
898
+ update();
899
+ window.addEventListener('resize', update, {
900
+ passive: true
901
+ });
902
+ return () => {
903
+ window.removeEventListener('resize', update);
904
+ resetViewportCssVars(el);
905
+ };
906
+ }, [mode]);
907
+ return boundaryRef;
908
+ };
909
+
846
910
  const _excluded$f = ["children", "className"];
847
911
  const FilterOuter = _ref => {
848
912
  let {
@@ -850,9 +914,12 @@ const FilterOuter = _ref => {
850
914
  className
851
915
  } = _ref,
852
916
  props = _objectWithoutPropertiesLoose(_ref, _excluded$f);
917
+ const isMobile = useFilterIsMobile();
918
+ const boundaryRef = useFilterViewportVars();
853
919
  return /*#__PURE__*/jsx(FilterProvider, _extends({}, props, {
854
920
  children: context => /*#__PURE__*/jsx("div", {
855
- className: classnames(style$1['filter'], 'filter', className),
921
+ ref: boundaryRef,
922
+ className: classnames(style$1['filter'], 'filter', RESPONSIVE_BOUNDARY_CLASS, isMobile && style$1['is-mobile'], className),
856
923
  children: children(_extends({}, context, {
857
924
  props
858
925
  }))
@@ -889,6 +956,25 @@ const Filter = withLocale(_ref => {
889
956
  }));
890
957
  });
891
958
 
959
+ /**
960
+ * 与 system-layout Toolbar 一致:
961
+ * - container 模式(example 手机预览):absolute + boundary 挂载
962
+ * - viewport 模式(真实移动端):fixed + 视口坐标
963
+ */
964
+ const useMobileFixedMode = () => {
965
+ const isMobile = useFilterIsMobile();
966
+ const {
967
+ mode
968
+ } = useResponsiveContext();
969
+ const useBoundaryMount = isMobile && mode === 'container';
970
+ const useViewportFixed = isMobile && mode !== 'container';
971
+ return {
972
+ isMobile,
973
+ useBoundaryMount,
974
+ useViewportFixed
975
+ };
976
+ };
977
+
892
978
  const FilterItem = withLocale(({
893
979
  open,
894
980
  active,
@@ -919,6 +1005,48 @@ const FilterItem = withLocale(({
919
1005
  });
920
1006
  });
921
1007
 
1008
+ const getMobilePopupMetrics = (triggerEl, {
1009
+ scrollEl,
1010
+ boundaryEl,
1011
+ useBoundaryMount,
1012
+ offset: _offset = 4
1013
+ } = {}) => {
1014
+ var _scrollRect$top, _scrollRect$bottom, _scrollRect$width;
1015
+ if (typeof window === 'undefined' || !triggerEl) {
1016
+ return {
1017
+ top: 0,
1018
+ left: 0,
1019
+ height: 0,
1020
+ width: 0
1021
+ };
1022
+ }
1023
+ const rect = triggerEl.getBoundingClientRect();
1024
+ if (useBoundaryMount && boundaryEl) {
1025
+ const boundaryRect = boundaryEl.getBoundingClientRect();
1026
+ const _top = Math.max(rect.bottom - boundaryRect.top + _offset, 0);
1027
+ return {
1028
+ top: _top,
1029
+ left: 0,
1030
+ height: Math.max(boundaryRect.height - _top, 0),
1031
+ width: boundaryRect.width
1032
+ };
1033
+ }
1034
+ const scrollRect = scrollEl == null || scrollEl.getBoundingClientRect == null ? void 0 : scrollEl.getBoundingClientRect();
1035
+ const visibleTop = (_scrollRect$top = scrollRect == null ? void 0 : scrollRect.top) != null ? _scrollRect$top : 0;
1036
+ const visibleBottom = (_scrollRect$bottom = scrollRect == null ? void 0 : scrollRect.bottom) != null ? _scrollRect$bottom : window.innerHeight;
1037
+ const width = (_scrollRect$width = scrollRect == null ? void 0 : scrollRect.width) != null ? _scrollRect$width : window.innerWidth;
1038
+ const top = Math.max(rect.bottom + _offset, visibleTop);
1039
+ return {
1040
+ top,
1041
+ left: 0,
1042
+ height: Math.max(visibleBottom - top, 0),
1043
+ width
1044
+ };
1045
+ };
1046
+
1047
+ const MOBILE_MASK_Z_INDEX = 1000;
1048
+ const MOBILE_POPUP_Z_INDEX = 1050;
1049
+
922
1050
  const _excluded$d = ["value", "onChange", "interceptor", "label", "render"];
923
1051
  const isNotEmpty$1 = value => {
924
1052
  if (value === null || value === undefined) return false;
@@ -926,9 +1054,10 @@ const isNotEmpty$1 = value => {
926
1054
  return !(Array.isArray(value) && value.length === 0);
927
1055
  };
928
1056
  const MASK_ANIMATION_DURATION$1 = 180;
929
- const FIELD_MOBILE_POPUP_CLASS = 'react-filter-field-mobile-popup';
1057
+ const FIELD_MOBILE_POPUP_CLASS$1 = 'react-filter-field-mobile-popup';
930
1058
  const MOBILE_POPUP_OFFSET$1 = 4;
931
1059
  const withFieldItem = (WrappedComponent, options = {}) => _ref => {
1060
+ var _popupMetrics$left;
932
1061
  let {
933
1062
  value,
934
1063
  onChange,
@@ -938,7 +1067,11 @@ const withFieldItem = (WrappedComponent, options = {}) => _ref => {
938
1067
  } = _ref,
939
1068
  props = _objectWithoutPropertiesLoose(_ref, _excluded$d);
940
1069
  const [open, setOpen] = useState(false);
941
- const [isMobile, setIsMobile] = useState(false);
1070
+ const {
1071
+ isMobile,
1072
+ useBoundaryMount
1073
+ } = useMobileFixedMode();
1074
+ const fixedModeClass = useBoundaryMount ? style$1['is-boundary'] : style$1['is-viewport'];
942
1075
  const [renderMask, setRenderMask] = useState(false);
943
1076
  const [maskClosing, setMaskClosing] = useState(false);
944
1077
  const [popupMetrics, setPopupMetrics] = useState({
@@ -947,6 +1080,24 @@ const withFieldItem = (WrappedComponent, options = {}) => _ref => {
947
1080
  height: 0
948
1081
  });
949
1082
  const triggerRef = useRef(null);
1083
+ const getBoundaryElement = usePopupContainer();
1084
+ const getScrollElement = useScrollElement();
1085
+ const resolveGetPopupContainer = useCallback(triggerNode => {
1086
+ if (typeof props.getPopupContainer === 'function') {
1087
+ const customContainer = props.getPopupContainer(triggerNode);
1088
+ if (customContainer) {
1089
+ return customContainer;
1090
+ }
1091
+ }
1092
+ if (!isMobile) {
1093
+ return getBoundaryElement();
1094
+ }
1095
+ if (useBoundaryMount) {
1096
+ return getBoundaryElement();
1097
+ }
1098
+ return typeof document !== 'undefined' ? document.body : null;
1099
+ }, [getBoundaryElement, isMobile, props.getPopupContainer, useBoundaryMount]);
1100
+ const popupMountNode = typeof document !== 'undefined' ? isMobile ? useBoundaryMount ? getBoundaryElement() || document.body : document.body : getBoundaryElement() || document.body : null;
950
1101
  const setMobilePopupVariables = useCallback(metrics => {
951
1102
  if (typeof document === 'undefined') return;
952
1103
  document.body.style.setProperty('--react-filter-field-mobile-height', `${metrics.height}px`);
@@ -955,37 +1106,16 @@ const withFieldItem = (WrappedComponent, options = {}) => _ref => {
955
1106
  }, []);
956
1107
  const updatePopupMetrics = useCallback(() => {
957
1108
  if (typeof window === 'undefined' || !triggerRef.current) return;
958
- const rect = triggerRef.current.getBoundingClientRect();
959
- const top = Math.max(rect.bottom + MOBILE_POPUP_OFFSET$1, 0);
960
- const metrics = {
961
- top,
962
- height: Math.max(window.innerHeight - top, 0)
963
- };
1109
+ const metrics = getMobilePopupMetrics(triggerRef.current, {
1110
+ scrollEl: getScrollElement(),
1111
+ boundaryEl: getBoundaryElement(),
1112
+ useBoundaryMount,
1113
+ offset: MOBILE_POPUP_OFFSET$1
1114
+ });
964
1115
  setPopupMetrics(metrics);
965
1116
  setMobilePopupVariables(metrics);
966
- }, [setMobilePopupVariables]);
967
- useEffect(() => {
968
- if (typeof window === 'undefined') return;
969
- const mediaQuery = window.matchMedia('(max-width: 768px)');
970
- const updateIsMobile = () => {
971
- setIsMobile(mediaQuery.matches);
972
- };
973
- updateIsMobile();
974
- mediaQuery.addEventListener ? mediaQuery.addEventListener('change', updateIsMobile) : mediaQuery.addListener(updateIsMobile);
975
- return () => {
976
- mediaQuery.removeEventListener ? mediaQuery.removeEventListener('change', updateIsMobile) : mediaQuery.removeListener(updateIsMobile);
977
- };
978
- }, []);
979
- useEffect(() => {
980
- if (!open || !isMobile) return;
981
- updatePopupMetrics();
982
- window.addEventListener('resize', updatePopupMetrics);
983
- window.addEventListener('scroll', updatePopupMetrics, true);
984
- return () => {
985
- window.removeEventListener('resize', updatePopupMetrics);
986
- window.removeEventListener('scroll', updatePopupMetrics, true);
987
- };
988
- }, [isMobile, open, updatePopupMetrics]);
1117
+ }, [getBoundaryElement, getScrollElement, setMobilePopupVariables, useBoundaryMount]);
1118
+ useResponsiveScrollListener(updatePopupMetrics, open && isMobile);
989
1119
  useEffect(() => {
990
1120
  if (typeof document === 'undefined' || !isMobile || popupMetrics.height <= 0) return;
991
1121
  setMobilePopupVariables(popupMetrics);
@@ -1029,14 +1159,15 @@ const withFieldItem = (WrappedComponent, options = {}) => _ref => {
1029
1159
  '--react-filter-popover-mobile-height': `${popupMetrics.height}px`,
1030
1160
  '--react-filter-field-mobile-top': `${popupMetrics.top}px`,
1031
1161
  top: popupMetrics.top,
1032
- left: 0
1162
+ left: (_popupMetrics$left = popupMetrics.left) != null ? _popupMetrics$left : 0,
1163
+ zIndex: MOBILE_POPUP_Z_INDEX
1033
1164
  } : undefined;
1034
1165
  const mergePopupClassNames = classNames => {
1035
1166
  var _classNames$popup;
1036
1167
  if (!isMobile) return classNames;
1037
1168
  return Object.assign({}, classNames, {
1038
1169
  popup: Object.assign({}, classNames == null ? void 0 : classNames.popup, {
1039
- root: classnames(classNames == null || (_classNames$popup = classNames.popup) == null ? void 0 : _classNames$popup.root, style$1['field-item-mobile-popup'], FIELD_MOBILE_POPUP_CLASS)
1170
+ root: classnames(classNames == null || (_classNames$popup = classNames.popup) == null ? void 0 : _classNames$popup.root, style$1['field-item-mobile-popup'], FIELD_MOBILE_POPUP_CLASS$1, fixedModeClass)
1040
1171
  })
1041
1172
  });
1042
1173
  };
@@ -1061,9 +1192,10 @@ const withFieldItem = (WrappedComponent, options = {}) => _ref => {
1061
1192
  valueType: "all",
1062
1193
  onOpenChange: handleOpenChange,
1063
1194
  onDropdownVisibleChange: handleOpenChange,
1064
- popupClassName: classnames(props.popupClassName, isMobile && style$1['field-item-mobile-popup'], isMobile && FIELD_MOBILE_POPUP_CLASS),
1065
- dropdownClassName: classnames(props.dropdownClassName, isMobile && style$1['field-item-mobile-popup'], isMobile && FIELD_MOBILE_POPUP_CLASS),
1066
- overlayClassName: classnames(props.overlayClassName, isMobile && style$1['field-item-mobile-popup'], isMobile && FIELD_MOBILE_POPUP_CLASS),
1195
+ getPopupContainer: resolveGetPopupContainer,
1196
+ popupClassName: classnames(props.popupClassName, isMobile && style$1['field-item-mobile-popup'], isMobile && FIELD_MOBILE_POPUP_CLASS$1, isMobile && fixedModeClass),
1197
+ dropdownClassName: classnames(props.dropdownClassName, isMobile && style$1['field-item-mobile-popup'], isMobile && FIELD_MOBILE_POPUP_CLASS$1, isMobile && fixedModeClass),
1198
+ overlayClassName: classnames(props.overlayClassName, isMobile && style$1['field-item-mobile-popup'], isMobile && FIELD_MOBILE_POPUP_CLASS$1, isMobile && fixedModeClass),
1067
1199
  overlayStyle: Object.assign({}, props.overlayStyle, mobilePopupStyle),
1068
1200
  popupStyle: Object.assign({}, props.popupStyle, mobilePopupStyle),
1069
1201
  dropdownStyle: Object.assign({}, props.dropdownStyle, mobilePopupStyle),
@@ -1075,21 +1207,27 @@ const withFieldItem = (WrappedComponent, options = {}) => _ref => {
1075
1207
  offset: [0, 0]
1076
1208
  } : props.align,
1077
1209
  isPopup: options.forcePopup ? true : props.isPopup,
1078
- overlayWidth: isMobile && options.forcePopup ? typeof window === 'undefined' ? props.overlayWidth : window.innerWidth : props.overlayWidth
1210
+ zIndex: isMobile ? MOBILE_POPUP_Z_INDEX : props.zIndex,
1211
+ overlayWidth: isMobile && options.forcePopup ? typeof window === 'undefined' ? props.overlayWidth : getMobilePopupMetrics(triggerRef.current, {
1212
+ scrollEl: getScrollElement(),
1213
+ boundaryEl: getBoundaryElement(),
1214
+ useBoundaryMount
1215
+ }).width || window.innerWidth : props.overlayWidth
1079
1216
  }));
1080
1217
  };
1081
1218
  return /*#__PURE__*/jsxs(Fragment, {
1082
- children: [renderMask && typeof document !== 'undefined' && /*#__PURE__*/createPortal(/*#__PURE__*/jsx("div", {
1083
- className: classnames(style$1['pop-util-mask'], maskClosing && style$1['pop-util-mask-leave']),
1219
+ children: [renderMask && popupMountNode && /*#__PURE__*/createPortal(/*#__PURE__*/jsx("div", {
1220
+ className: classnames(style$1['pop-util-mask'], maskClosing && style$1['pop-util-mask-leave'], fixedModeClass),
1084
1221
  style: {
1085
1222
  top: popupMetrics.top,
1086
- height: popupMetrics.height
1223
+ height: popupMetrics.height,
1224
+ zIndex: MOBILE_MASK_Z_INDEX
1087
1225
  },
1088
1226
  onClick: closeFieldItem,
1089
1227
  onTouchMove: e => {
1090
1228
  e.preventDefault();
1091
1229
  }
1092
- }), document.body), /*#__PURE__*/jsx("span", {
1230
+ }), popupMountNode), /*#__PURE__*/jsx("span", {
1093
1231
  ref: triggerRef,
1094
1232
  children: /*#__PURE__*/jsx(FilterItem, {
1095
1233
  label: label,
@@ -1119,11 +1257,35 @@ const PopoverItem = withLocale(({
1119
1257
  placement: _placement = 'bottomLeft',
1120
1258
  onOpenChange,
1121
1259
  onChange,
1260
+ getPopupContainer: customGetPopupContainer,
1122
1261
  children
1123
1262
  }) => {
1263
+ var _popupMetrics$left;
1124
1264
  const [state, setState] = useState(value);
1125
1265
  const [open, setOpen] = useState(false);
1126
- const [isMobile, setIsMobile] = useState(false);
1266
+ const {
1267
+ isMobile,
1268
+ useBoundaryMount
1269
+ } = useMobileFixedMode();
1270
+ const fixedModeClass = useBoundaryMount ? style$1['is-boundary'] : style$1['is-viewport'];
1271
+ const getBoundaryElement = usePopupContainer();
1272
+ const getScrollElement = useScrollElement();
1273
+ const resolveGetPopupContainer = useCallback(triggerNode => {
1274
+ if (typeof customGetPopupContainer === 'function') {
1275
+ const customContainer = customGetPopupContainer(triggerNode);
1276
+ if (customContainer) {
1277
+ return customContainer;
1278
+ }
1279
+ }
1280
+ if (!isMobile) {
1281
+ return getBoundaryElement();
1282
+ }
1283
+ if (useBoundaryMount) {
1284
+ return getBoundaryElement();
1285
+ }
1286
+ return typeof document !== 'undefined' ? document.body : null;
1287
+ }, [customGetPopupContainer, getBoundaryElement, isMobile, useBoundaryMount]);
1288
+ const popupMountNode = typeof document !== 'undefined' ? isMobile ? useBoundaryMount ? getBoundaryElement() || document.body : document.body : getBoundaryElement() || document.body : null;
1127
1289
  const [renderMask, setRenderMask] = useState(false);
1128
1290
  const [maskClosing, setMaskClosing] = useState(false);
1129
1291
  const [popupMetrics, setPopupMetrics] = useState({
@@ -1140,37 +1302,17 @@ const PopoverItem = withLocale(({
1140
1302
  } = useIntl({
1141
1303
  moduleName: 'Filter'
1142
1304
  });
1143
- useEffect(() => {
1144
- if (typeof window === 'undefined') return;
1145
- const mediaQuery = window.matchMedia('(max-width: 768px)');
1146
- const updateIsMobile = () => {
1147
- setIsMobile(mediaQuery.matches);
1148
- };
1149
- updateIsMobile();
1150
- mediaQuery.addEventListener ? mediaQuery.addEventListener('change', updateIsMobile) : mediaQuery.addListener(updateIsMobile);
1151
- return () => {
1152
- mediaQuery.removeEventListener ? mediaQuery.removeEventListener('change', updateIsMobile) : mediaQuery.removeListener(updateIsMobile);
1153
- };
1154
- }, []);
1155
1305
  const updatePopupMetrics = useCallback(() => {
1156
1306
  if (typeof window === 'undefined' || !triggerRef.current) return;
1157
- const rect = triggerRef.current.getBoundingClientRect();
1158
- const top = Math.max(rect.bottom + MOBILE_POPUP_OFFSET, 0);
1159
- setPopupMetrics({
1160
- top,
1161
- height: Math.max(window.innerHeight - top, 0)
1307
+ const metrics = getMobilePopupMetrics(triggerRef.current, {
1308
+ scrollEl: getScrollElement(),
1309
+ boundaryEl: getBoundaryElement(),
1310
+ useBoundaryMount,
1311
+ offset: MOBILE_POPUP_OFFSET
1162
1312
  });
1163
- }, []);
1164
- useEffect(() => {
1165
- if (!open || !isMobile) return;
1166
- updatePopupMetrics();
1167
- window.addEventListener('resize', updatePopupMetrics);
1168
- window.addEventListener('scroll', updatePopupMetrics, true);
1169
- return () => {
1170
- window.removeEventListener('resize', updatePopupMetrics);
1171
- window.removeEventListener('scroll', updatePopupMetrics, true);
1172
- };
1173
- }, [isMobile, open, updatePopupMetrics]);
1313
+ setPopupMetrics(metrics);
1314
+ }, [getBoundaryElement, getScrollElement, useBoundaryMount]);
1315
+ useResponsiveScrollListener(updatePopupMetrics, open && isMobile);
1174
1316
  useEffect(() => {
1175
1317
  if (open && isMobile) {
1176
1318
  setRenderMask(true);
@@ -1202,7 +1344,8 @@ const PopoverItem = withLocale(({
1202
1344
  const mobileOverlayStyle = isMobile ? {
1203
1345
  '--react-filter-popover-mobile-height': `${popupMetrics.height}px`,
1204
1346
  top: popupMetrics.top,
1205
- left: 0
1347
+ left: (_popupMetrics$left = popupMetrics.left) != null ? _popupMetrics$left : 0,
1348
+ zIndex: MOBILE_POPUP_Z_INDEX
1206
1349
  } : undefined;
1207
1350
  const overlayContent = /*#__PURE__*/jsxs("div", {
1208
1351
  className: style$1['pop-util-body'],
@@ -1244,17 +1387,18 @@ const PopoverItem = withLocale(({
1244
1387
  })]
1245
1388
  });
1246
1389
  return /*#__PURE__*/jsxs(Fragment, {
1247
- children: [renderMask && typeof document !== 'undefined' && /*#__PURE__*/createPortal(/*#__PURE__*/jsx("div", {
1248
- className: classnames(style$1['pop-util-mask'], maskClosing && style$1['pop-util-mask-leave']),
1390
+ children: [renderMask && popupMountNode && /*#__PURE__*/createPortal(/*#__PURE__*/jsx("div", {
1391
+ className: classnames(style$1['pop-util-mask'], maskClosing && style$1['pop-util-mask-leave'], fixedModeClass),
1249
1392
  style: {
1250
1393
  top: popupMetrics.top,
1251
- height: popupMetrics.height
1394
+ height: popupMetrics.height,
1395
+ zIndex: MOBILE_MASK_Z_INDEX
1252
1396
  },
1253
1397
  onClick: closeDropdown,
1254
1398
  onTouchMove: e => {
1255
1399
  e.preventDefault();
1256
1400
  }
1257
- }), document.body), /*#__PURE__*/jsx(Dropdown, {
1401
+ }), popupMountNode), /*#__PURE__*/jsx(Dropdown, {
1258
1402
  open: open,
1259
1403
  trigger: ['click'],
1260
1404
  placement: isMobile ? 'bottomLeft' : _placement,
@@ -1262,7 +1406,9 @@ const PopoverItem = withLocale(({
1262
1406
  align: isMobile ? {
1263
1407
  offset: [0, 0]
1264
1408
  } : undefined,
1265
- overlayClassName: classnames(style$1['pop-util-overlay'], overlayClassName),
1409
+ getPopupContainer: resolveGetPopupContainer,
1410
+ zIndex: isMobile ? MOBILE_POPUP_Z_INDEX : undefined,
1411
+ overlayClassName: classnames(style$1['pop-util-overlay'], overlayClassName, isMobile && fixedModeClass),
1266
1412
  overlayStyle: mobileOverlayStyle,
1267
1413
  onOpenChange: handleOpenChange,
1268
1414
  menu: {
@@ -1496,7 +1642,9 @@ const DateRangePickerFilterItem = withLocale(withFieldItem(_ref => {
1496
1642
  var style = {"shortcuts-container":"kne-react-filter_3w4Bb","shortcut-item":"kne-react-filter_myRhG","is-active":"kne-react-filter_FowoG"};
1497
1643
 
1498
1644
  const _excluded$8 = ["value", "onChange", "defaultValue", "shortcuts", "shortcutOptions"];
1645
+ const FIELD_MOBILE_POPUP_CLASS = 'react-filter-field-mobile-popup';
1499
1646
  const TypeDateRangePickerField = _ref => {
1647
+ var _props$classNames, _props$classNames2, _props$styles, _props$styles2;
1500
1648
  let {
1501
1649
  value: valueProp,
1502
1650
  onChange: onChangeProp,
@@ -1510,6 +1658,16 @@ const TypeDateRangePickerField = _ref => {
1510
1658
  } = useIntl({
1511
1659
  moduleName: 'Filter'
1512
1660
  });
1661
+ const getPopupContainer = usePopupContainer();
1662
+ const {
1663
+ isMobile,
1664
+ useBoundaryMount
1665
+ } = useMobileFixedMode();
1666
+ const fixedModeClass = useBoundaryMount ? style['is-boundary'] : style['is-viewport'];
1667
+ const nestedPopupClassName = classnames(style['field-item-mobile-popup'], FIELD_MOBILE_POPUP_CLASS, fixedModeClass);
1668
+ const nestedPopupStyle = isMobile ? {
1669
+ zIndex: MOBILE_POPUP_Z_INDEX
1670
+ } : undefined;
1513
1671
  const typeList = new Map([['date', formatMessage({
1514
1672
  id: 'customTime'
1515
1673
  })], ['month', formatMessage({
@@ -1599,6 +1757,19 @@ const TypeDateRangePickerField = _ref => {
1599
1757
  style: {
1600
1758
  width: '120px'
1601
1759
  },
1760
+ getPopupContainer: getPopupContainer,
1761
+ popupClassName: isMobile ? nestedPopupClassName : undefined,
1762
+ classNames: isMobile ? {
1763
+ popup: {
1764
+ root: nestedPopupClassName
1765
+ }
1766
+ } : undefined,
1767
+ popupStyle: nestedPopupStyle,
1768
+ styles: isMobile ? {
1769
+ popup: {
1770
+ root: nestedPopupStyle
1771
+ }
1772
+ } : undefined,
1602
1773
  value: (value == null ? void 0 : value.type) || 'date',
1603
1774
  onChange: typeValue => {
1604
1775
  onChange(currentValue => {
@@ -1622,6 +1793,18 @@ const TypeDateRangePickerField = _ref => {
1622
1793
  value: val
1623
1794
  }))
1624
1795
  }), /*#__PURE__*/jsx(DatePicker.RangePicker, _extends({}, props, {
1796
+ getPopupContainer: getPopupContainer,
1797
+ classNames: isMobile ? _extends({}, props.classNames, {
1798
+ popup: _extends({}, (_props$classNames = props.classNames) == null ? void 0 : _props$classNames.popup, {
1799
+ root: classnames((_props$classNames2 = props.classNames) == null || (_props$classNames2 = _props$classNames2.popup) == null ? void 0 : _props$classNames2.root, nestedPopupClassName)
1800
+ })
1801
+ }) : props.classNames,
1802
+ styles: isMobile ? _extends({}, props.styles, {
1803
+ popup: _extends({}, (_props$styles = props.styles) == null ? void 0 : _props$styles.popup, {
1804
+ root: Object.assign({}, (_props$styles2 = props.styles) == null || (_props$styles2 = _props$styles2.popup) == null ? void 0 : _props$styles2.root, nestedPopupStyle)
1805
+ })
1806
+ }) : props.styles,
1807
+ popupStyle: nestedPopupStyle,
1625
1808
  picker: (value == null ? void 0 : value.type) || 'date',
1626
1809
  value: Array.isArray(value == null ? void 0 : value.value) && value.value.length === 2 ? value.value.map(item => item && dayjs(item)) : null,
1627
1810
  onChange: dateValue => {
@@ -2578,6 +2761,7 @@ const CityFilterItemInner = _ref => {
2578
2761
  const {
2579
2762
  message
2580
2763
  } = App.useApp();
2764
+ const getPopupContainer = usePopupContainer();
2581
2765
  const {
2582
2766
  locale
2583
2767
  } = useIntl();
@@ -2650,6 +2834,7 @@ const CityFilterItemInner = _ref => {
2650
2834
  children: [formatMessage({
2651
2835
  id: 'otherText'
2652
2836
  }), /*#__PURE__*/jsx(SelectAddress, _extends({}, props, {
2837
+ getPopupContainer: getPopupContainer,
2653
2838
  className: style$1['filter-advanced-item-other-inner'],
2654
2839
  maxLength: maxLength,
2655
2840
  allowClear: false,
@@ -2768,6 +2953,7 @@ Filter.useFilter = useContext;
2768
2953
  Filter.SearchInput = SearchInput;
2769
2954
  Filter.withFilterValue = withFilterValue;
2770
2955
  Filter.FilterProvider = FilterProvider;
2956
+ Filter.FilterOuter = FilterOuter;
2771
2957
  Filter.pickSelectValues = pickSelectValues;
2772
2958
  Filter.createFilterValueMapper = createFilterValueMapper;
2773
2959
  Filter.useUrlFilter = useUrlFilter;
@@ -2782,5 +2968,5 @@ Filter.filterInterceptors = filterInterceptors;
2782
2968
  Filter.singleSelectInterceptor = singleSelectInterceptor;
2783
2969
  Filter.multiSelectInterceptor = multiSelectInterceptor;
2784
2970
 
2785
- export { AdvancedFilter, DatePickerFilterItem, DateRangePickerFilterItem, FilterItem, FilterItemContainer, FilterLines, FilterProvider, FilterValueDisplay, InputFilterItem$1 as InputFilterItem, NumberRangeFilterItem, PopoverItem, SearchInput, SelectAddressFilterItem, SelectCascaderFilterItem, SelectFunctionFilterItem, SelectIndustryFilterItem, SelectTableListFilterItem, SelectTreeFilterItem, SuperSelectFilterItem, TypeDateRangePickerField, TypeDateRangePickerFilterItem, createFilterValueMapper, createUrlFilterReader, createUrlParamsReader, Filter as default, fields$1 as fields, filterInterceptors, filterToUrlParams, getFilterValue, multiSelectInterceptor, parseFilterEntry, pickSelectValues, singleSelectInterceptor, stripConsumedUrlParams, takeFilterEntry, useContext as useFilter, useUrlFilter, useUrlFilterValue, withFieldItem, withFilterValue };
2971
+ export { AdvancedFilter, DatePickerFilterItem, DateRangePickerFilterItem, FilterItem, FilterItemContainer, FilterLines, FilterOuter, FilterProvider, FilterValueDisplay, InputFilterItem$1 as InputFilterItem, NumberRangeFilterItem, PopoverItem, SearchInput, SelectAddressFilterItem, SelectCascaderFilterItem, SelectFunctionFilterItem, SelectIndustryFilterItem, SelectTableListFilterItem, SelectTreeFilterItem, SuperSelectFilterItem, TypeDateRangePickerField, TypeDateRangePickerFilterItem, createFilterValueMapper, createUrlFilterReader, createUrlParamsReader, Filter as default, fields$1 as fields, filterInterceptors, filterToUrlParams, getFilterValue, multiSelectInterceptor, parseFilterEntry, pickSelectValues, singleSelectInterceptor, stripConsumedUrlParams, takeFilterEntry, useContext as useFilter, useUrlFilter, useUrlFilterValue, withFieldItem, withFilterValue };
2786
2972
  //# sourceMappingURL=index.modern.js.map