@kne/react-filter 0.1.27 → 1.0.0

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/index.js CHANGED
@@ -1,1006 +1,2356 @@
1
- var React = require('react');
2
- var antd = require('antd');
3
- var useEvent = require('@kne/use-event');
4
1
  var classnames = require('classnames');
5
- var reactCitySelect = require('@kne/react-city-select');
6
- var lodash = require('lodash');
7
- var useSimulationBlur = require('@kne/use-simulation-blur');
8
- var moment = require('moment');
2
+ var react = require('react');
3
+ var antd = require('antd');
4
+ var reactIntl = require('@kne/react-intl');
5
+ var get = require('lodash/get');
6
+ var jsxRuntime = require('react/jsx-runtime');
7
+ var clone = require('lodash/clone');
8
+ var reactDom = require('react-dom');
9
+ var isNumber = require('lodash/isNumber');
10
+ var SuperSelect = require('@kne/super-select');
11
+ var superSelectPlus = require('@kne/super-select-plus');
12
+ require('@kne/super-select-plus/dist/index.css');
13
+ var dayjs = require('dayjs');
14
+ var transform = require('lodash/transform');
15
+ var reactRouterDom = require('react-router-dom');
16
+ var isEqual = require('lodash/isEqual');
9
17
 
10
18
  function _interopDefaultLegacy (e) { return e && typeof e === 'object' && 'default' in e ? e : { 'default': e }; }
11
19
 
12
- var React__default = /*#__PURE__*/_interopDefaultLegacy(React);
13
- var useEvent__default = /*#__PURE__*/_interopDefaultLegacy(useEvent);
14
20
  var classnames__default = /*#__PURE__*/_interopDefaultLegacy(classnames);
15
- var useSimulationBlur__default = /*#__PURE__*/_interopDefaultLegacy(useSimulationBlur);
16
- var moment__default = /*#__PURE__*/_interopDefaultLegacy(moment);
17
-
18
- var context$1 = React.createContext({});
19
- var Provider$1 = context$1.Provider;
20
- var useConsumer = function useConsumer() {
21
- return React.useContext(context$1);
22
- };
21
+ var get__default = /*#__PURE__*/_interopDefaultLegacy(get);
22
+ var clone__default = /*#__PURE__*/_interopDefaultLegacy(clone);
23
+ var isNumber__default = /*#__PURE__*/_interopDefaultLegacy(isNumber);
24
+ var SuperSelect__default = /*#__PURE__*/_interopDefaultLegacy(SuperSelect);
25
+ var dayjs__default = /*#__PURE__*/_interopDefaultLegacy(dayjs);
26
+ var transform__default = /*#__PURE__*/_interopDefaultLegacy(transform);
27
+ var isEqual__default = /*#__PURE__*/_interopDefaultLegacy(isEqual);
23
28
 
24
29
  function _extends() {
25
- _extends = Object.assign ? Object.assign.bind() : function (target) {
26
- for (var i = 1; i < arguments.length; i++) {
27
- var source = arguments[i];
28
-
29
- for (var key in source) {
30
- if (Object.prototype.hasOwnProperty.call(source, key)) {
31
- target[key] = source[key];
32
- }
33
- }
30
+ return _extends = Object.assign ? Object.assign.bind() : function (n) {
31
+ for (var e = 1; e < arguments.length; e++) {
32
+ var t = arguments[e];
33
+ for (var r in t) ({}).hasOwnProperty.call(t, r) && (n[r] = t[r]);
34
34
  }
35
-
36
- return target;
37
- };
38
- return _extends.apply(this, arguments);
35
+ return n;
36
+ }, _extends.apply(null, arguments);
39
37
  }
40
-
41
- function _objectWithoutPropertiesLoose(source, excluded) {
42
- if (source == null) return {};
43
- var target = {};
44
- var sourceKeys = Object.keys(source);
45
- var key, i;
46
-
47
- for (i = 0; i < sourceKeys.length; i++) {
48
- key = sourceKeys[i];
49
- if (excluded.indexOf(key) >= 0) continue;
50
- target[key] = source[key];
38
+ function _objectWithoutPropertiesLoose(r, e) {
39
+ if (null == r) return {};
40
+ var t = {};
41
+ for (var n in r) if ({}.hasOwnProperty.call(r, n)) {
42
+ if (-1 !== e.indexOf(n)) continue;
43
+ t[n] = r[n];
51
44
  }
52
-
53
- return target;
45
+ return t;
54
46
  }
55
47
 
56
- var _excluded$9 = ["label", "labelHidden", "isMore", "moreTrigger"];
57
-
58
- var PopContent = function PopContent(props) {
59
- var _useState = React.useState(false),
60
- visible = _useState[0],
61
- setVisible = _useState[1];
62
-
63
- var _useConsumer = useConsumer(),
64
- emitter = _useConsumer.emitter;
65
-
66
- React.useEffect(function () {
67
- emitter.addListener('change', function () {
68
- setVisible(false);
48
+ 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-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-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","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-scroll-next-icon":"kne-react-filter_Fd6ab"};
49
+
50
+ const context = /*#__PURE__*/react.createContext({});
51
+ const Provider = context.Provider;
52
+ const useContext = () => react.useContext(context);
53
+
54
+ const Line$1 = _ref => {
55
+ let list = _ref.list,
56
+ children = _ref.children;
57
+ const _useContext = useContext(),
58
+ value = _useContext.value,
59
+ onChange = _useContext.onChange;
60
+ return /*#__PURE__*/jsxRuntime.jsxs("div", {
61
+ className: style$1['filter-line'],
62
+ children: [list.filter(item => !!item.type).map((item, index) => {
63
+ if (typeof item === 'function') {
64
+ return item(props => {
65
+ return {
66
+ index,
67
+ value: value ? get__default["default"](value.get(props == null ? void 0 : props.name), 'value') : props == null ? void 0 : props.value,
68
+ onChange: onChange ? value => onChange({
69
+ name: props == null ? void 0 : props.name,
70
+ label: props == null ? void 0 : props.label,
71
+ value
72
+ }) : props == null ? void 0 : props.onChange
73
+ };
74
+ });
75
+ }
76
+ const ComponentItem = item.type;
77
+ return /*#__PURE__*/react.createElement(ComponentItem, _extends({}, Object.assign({}, item.props, {
78
+ value: value ? get__default["default"](value.get(item.props.name), 'value') : item.props.value,
79
+ onChange: onChange ? value => onChange({
80
+ name: item.props.name,
81
+ label: item.props.label,
82
+ value
83
+ }) : item.props.onChange
84
+ }), {
85
+ key: item.key || item.props.name || index
86
+ }));
87
+ }), children]
88
+ });
89
+ };
90
+ const FilterLines = _ref2 => {
91
+ let className = _ref2.className,
92
+ _ref2$list = _ref2.list,
93
+ list = _ref2$list === void 0 ? [] : _ref2$list,
94
+ _ref2$displayLine = _ref2.displayLine,
95
+ displayLine = _ref2$displayLine === void 0 ? 1 : _ref2$displayLine,
96
+ label = _ref2.label,
97
+ extra = _ref2.extra,
98
+ children = _ref2.children;
99
+ const hasMore = list.length > displayLine;
100
+ const mobileList = list.reduce((result, item) => result.concat(Array.isArray(item) ? item : [item]), []);
101
+ const _useState = react.useState(false),
102
+ isExpand = _useState[0],
103
+ setIsExpand = _useState[1];
104
+ const _useState2 = react.useState(false),
105
+ isMobile = _useState2[0],
106
+ setIsMobile = _useState2[1];
107
+ const _useState3 = react.useState(false),
108
+ showScrollNext = _useState3[0],
109
+ setShowScrollNext = _useState3[1];
110
+ const scrollRef = react.useRef(null);
111
+ const _useIntl = reactIntl.useIntl({
112
+ moduleName: 'Filter'
113
+ }),
114
+ formatMessage = _useIntl.formatMessage;
115
+ const updateScrollNextVisible = react.useCallback(() => {
116
+ const el = scrollRef.current;
117
+ if (!el) {
118
+ setShowScrollNext(false);
119
+ return;
120
+ }
121
+ setShowScrollNext(el.scrollWidth > el.clientWidth && el.scrollLeft + el.clientWidth < el.scrollWidth - 1);
122
+ }, []);
123
+ react.useEffect(() => {
124
+ if (typeof window === 'undefined') return;
125
+ const mediaQuery = window.matchMedia('(max-width: 768px)');
126
+ const updateIsMobile = () => {
127
+ setIsMobile(mediaQuery.matches);
128
+ };
129
+ updateIsMobile();
130
+ mediaQuery.addEventListener ? mediaQuery.addEventListener('change', updateIsMobile) : mediaQuery.addListener(updateIsMobile);
131
+ return () => {
132
+ mediaQuery.removeEventListener ? mediaQuery.removeEventListener('change', updateIsMobile) : mediaQuery.removeListener(updateIsMobile);
133
+ };
134
+ }, []);
135
+ react.useEffect(() => {
136
+ if (!isMobile) {
137
+ setShowScrollNext(false);
138
+ return;
139
+ }
140
+ const el = scrollRef.current;
141
+ if (!el) return;
142
+ updateScrollNextVisible();
143
+ const update = () => {
144
+ updateScrollNextVisible();
145
+ };
146
+ el.addEventListener('scroll', update);
147
+ window.addEventListener('resize', update);
148
+ const rafId = window.requestAnimationFrame(update);
149
+ return () => {
150
+ el.removeEventListener('scroll', update);
151
+ window.removeEventListener('resize', update);
152
+ window.cancelAnimationFrame(rafId);
153
+ };
154
+ }, [isMobile, list, updateScrollNextVisible]);
155
+ const scrollToNext = react.useCallback(() => {
156
+ const el = scrollRef.current;
157
+ if (!el) return;
158
+ el.scrollTo({
159
+ left: el.scrollLeft + el.clientWidth * 0.8,
160
+ behavior: 'smooth'
69
161
  });
70
162
  }, []);
71
- return /*#__PURE__*/React__default["default"].createElement(antd.Popover, _extends({}, props, {
72
- visible: visible,
73
- onVisibleChange: setVisible
74
- }));
163
+ const scrollItemIntoView = react.useCallback(e => {
164
+ if (!isMobile) return;
165
+ const container = scrollRef.current;
166
+ const item = e.target.closest("." + style$1['filter-item-wrap']) || e.target.closest("." + style$1['filter-item']);
167
+ if (!container || !item) return;
168
+ item.scrollIntoView({
169
+ behavior: 'smooth',
170
+ block: 'nearest',
171
+ inline: 'center'
172
+ });
173
+ }, [isMobile]);
174
+ return /*#__PURE__*/jsxRuntime.jsxs(jsxRuntime.Fragment, {
175
+ children: [/*#__PURE__*/jsxRuntime.jsxs(antd.Space, {
176
+ className: classnames__default["default"](style$1['filter-title'], 'filter-title', className),
177
+ align: "top",
178
+ size: 16,
179
+ children: [/*#__PURE__*/jsxRuntime.jsx("span", {
180
+ className: style$1['filter-label'],
181
+ children: list && list.length > 0 && (label || formatMessage({
182
+ id: 'filterText'
183
+ }))
184
+ }), /*#__PURE__*/jsxRuntime.jsxs(antd.Row, {
185
+ justify: "space-between",
186
+ wrap: false,
187
+ align: "top",
188
+ children: [/*#__PURE__*/jsxRuntime.jsx(antd.Col, {
189
+ className: style$1['filter-list'],
190
+ flex: 1,
191
+ children: /*#__PURE__*/jsxRuntime.jsxs("div", {
192
+ className: style$1['filter-list-scroll-wrap'],
193
+ children: [/*#__PURE__*/jsxRuntime.jsx("div", {
194
+ className: style$1['filter-list-scroll'],
195
+ ref: scrollRef,
196
+ onClick: scrollItemIntoView,
197
+ children: (isMobile ? mobileList : list.slice(0, displayLine)).map((item, index) => /*#__PURE__*/jsxRuntime.jsx(Line$1, {
198
+ list: isMobile ? [item] : item,
199
+ children: !isMobile && hasMore && isExpand === false && index === displayLine - 1 ? /*#__PURE__*/jsxRuntime.jsxs(antd.Space, {
200
+ size: 4,
201
+ className: classnames__default["default"](style$1['filter-item'], style$1['option']),
202
+ onClick: () => {
203
+ setIsExpand(value => !value);
204
+ },
205
+ children: [formatMessage({
206
+ id: 'moreText'
207
+ }), /*#__PURE__*/jsxRuntime.jsx("span", {
208
+ className: style$1['filter-item-option-icon'],
209
+ children: "\u25BC"
210
+ })]
211
+ }) : null
212
+ }, index))
213
+ }), isMobile && showScrollNext ? /*#__PURE__*/jsxRuntime.jsx("button", {
214
+ type: "button",
215
+ className: style$1['filter-scroll-next'],
216
+ onClick: scrollToNext,
217
+ "aria-label": "scroll next",
218
+ children: /*#__PURE__*/jsxRuntime.jsx("span", {
219
+ className: style$1['filter-scroll-next-icon'],
220
+ children: "\u203A"
221
+ })
222
+ }) : null]
223
+ })
224
+ }), /*#__PURE__*/jsxRuntime.jsx(antd.Col, {
225
+ children: extra
226
+ })]
227
+ })]
228
+ }), /*#__PURE__*/jsxRuntime.jsx(antd.Space, {
229
+ className: classnames__default["default"](style$1['filter-title'], 'filter-title-wrap'),
230
+ align: "center",
231
+ size: 16,
232
+ children: children
233
+ }), /*#__PURE__*/jsxRuntime.jsxs(antd.Space, {
234
+ className: classnames__default["default"](style$1['filter-title'], 'filter-title-wrap', {
235
+ [style$1['filter-title-hidden']]: isMobile || !(hasMore && isExpand)
236
+ }),
237
+ align: "top",
238
+ size: 16,
239
+ children: [/*#__PURE__*/jsxRuntime.jsx("span", {
240
+ className: style$1['filter-label'],
241
+ children: formatMessage({
242
+ id: 'moreText'
243
+ })
244
+ }), /*#__PURE__*/jsxRuntime.jsx("div", {
245
+ className: style$1['filter-list'],
246
+ children: list.slice(displayLine).map((item, index) => /*#__PURE__*/jsxRuntime.jsx(Line$1, {
247
+ list: item,
248
+ children: index === list.length - displayLine - 1 && /*#__PURE__*/jsxRuntime.jsxs(jsxRuntime.Fragment, {
249
+ children: [/*#__PURE__*/jsxRuntime.jsx(antd.Space, {
250
+ size: 4,
251
+ className: classnames__default["default"](style$1['un-expand-shadow']),
252
+ children: /*#__PURE__*/jsxRuntime.jsxs(antd.Space, {
253
+ size: 4,
254
+ className: classnames__default["default"](style$1['option'], style$1['filter-item']),
255
+ children: [formatMessage({
256
+ id: 'toggleUpText'
257
+ }), /*#__PURE__*/jsxRuntime.jsx("span", {
258
+ className: style$1['filter-item-option-icon'],
259
+ children: "\u25B2"
260
+ })]
261
+ })
262
+ }), /*#__PURE__*/jsxRuntime.jsx(antd.Space, {
263
+ size: 4,
264
+ className: classnames__default["default"](style$1['un-expand']),
265
+ onClick: () => {
266
+ setIsExpand(value => !value);
267
+ },
268
+ children: /*#__PURE__*/jsxRuntime.jsxs(antd.Space, {
269
+ size: 4,
270
+ className: classnames__default["default"](style$1['option'], style$1['filter-item']),
271
+ children: [formatMessage({
272
+ id: 'toggleUpText'
273
+ }), /*#__PURE__*/jsxRuntime.jsx("span", {
274
+ className: style$1['filter-item-option-icon'],
275
+ children: "\u25B2"
276
+ })]
277
+ })
278
+ })]
279
+ })
280
+ }, index))
281
+ })]
282
+ })]
283
+ });
75
284
  };
76
285
 
77
- var FilterItem = function FilterItem(_ref) {
78
- var className = _ref.className,
79
- label = _ref.label,
80
- labelHidden = _ref.labelHidden,
81
- isMore = _ref.isMore,
82
- moreTrigger = _ref.moreTrigger,
83
- onClick = _ref.onClick,
84
- children = _ref.children;
85
-
86
- if (isMore) {
87
- return /*#__PURE__*/React__default["default"].createElement("div", {
88
- className: classnames__default["default"]("react-filter-item-label", "is-more", className)
89
- }, children ? /*#__PURE__*/React__default["default"].createElement(PopContent, {
90
- content: children,
91
- trigger: moreTrigger,
92
- placement: "bottom",
93
- overlayClassName: "react-filter-item-popover"
94
- }, /*#__PURE__*/React__default["default"].createElement("a", {
95
- className: "react-filter-item-more"
96
- }, label)) : /*#__PURE__*/React__default["default"].createElement("a", {
97
- className: "react-filter-item-more",
98
- onClick: onClick
99
- }, label));
100
- }
101
-
102
- return /*#__PURE__*/React__default["default"].createElement(antd.Space, {
103
- className: classnames__default["default"]('react-filter-item', className)
104
- }, labelHidden ? null : /*#__PURE__*/React__default["default"].createElement("div", {
105
- className: "react-filter-item-label"
106
- }, label, ":"), /*#__PURE__*/React__default["default"].createElement("div", {
107
- className: "react-filter-item-children"
108
- }, children));
286
+ const message$1 = {
287
+ filterText: '筛选',
288
+ moreText: '更多',
289
+ selectedText: '您已选择',
290
+ clearAllText: '清空全部',
291
+ toggleUpText: '收起',
292
+ selectedTextAdvanced: '已选',
293
+ clearText: '清空筛选',
294
+ otherText: '其他',
295
+ cancelText: '取消',
296
+ determineText: '确定',
297
+ year: '年',
298
+ over: '{count}{unit}以上',
299
+ lessThan: '{count}{unit}以下',
300
+ inputPlaceholder: '请输入{label}',
301
+ pleaseInput: '请输入',
302
+ defaultInputPlaceholder: '请输入{label}',
303
+ maxSelectedCount: '最多选择{count}项',
304
+ customTime: '自定义时间',
305
+ monthly: '按月',
306
+ weekly: '按周',
307
+ last7Days: '近7天',
308
+ thisMonth: '本月',
309
+ last3Months: '近三个月',
310
+ thisYear: '当年',
311
+ fullYear: '本年度',
312
+ pleaseSelect: '请选择'
109
313
  };
110
314
 
111
- var withFilterItem = function withFilterItem(WrappedComponent) {
112
- return function (_ref2) {
113
- var label = _ref2.label,
114
- labelHidden = _ref2.labelHidden,
115
- isMore = _ref2.isMore,
116
- moreTrigger = _ref2.moreTrigger,
117
- props = _objectWithoutPropertiesLoose(_ref2, _excluded$9);
118
-
119
- return /*#__PURE__*/React__default["default"].createElement(FilterItem, {
120
- label: label,
121
- labelHidden: labelHidden,
122
- isMore: isMore,
123
- moreTrigger: moreTrigger
124
- }, /*#__PURE__*/React__default["default"].createElement(WrappedComponent, _extends({}, props, {
125
- label: label,
126
- isMore: isMore
127
- })));
128
- };
315
+ const message = {
316
+ filterText: 'Filter',
317
+ moreText: 'More',
318
+ selectedText: 'Selected',
319
+ clearAllText: 'Clear All',
320
+ toggleUpText: 'Pack Up',
321
+ selectedTextAdvanced: 'Selected',
322
+ clearText: 'Clear Filter',
323
+ otherText: 'Other',
324
+ cancelText: 'Cancel',
325
+ determineText: 'Determine',
326
+ year: 'year',
327
+ over: 'over {count} {unit}s',
328
+ lessThan: 'less than {count} {unit}s',
329
+ inputPlaceholder: 'Please enter {label}',
330
+ pleaseInput: 'Please enter ',
331
+ defaultInputPlaceholder: 'Please enter {label}',
332
+ maxSelectedCount: 'Select up to {count} items',
333
+ customTime: 'Custom Time',
334
+ monthly: 'Monthly',
335
+ weekly: 'Weekly',
336
+ last7Days: 'Last 7 Days',
337
+ thisMonth: 'This Month',
338
+ last3Months: 'Last 3 Months',
339
+ thisYear: 'Year to Date',
340
+ fullYear: 'Full Year',
341
+ pleaseSelect: 'Please Select'
129
342
  };
130
343
 
131
- var _excluded$8 = ["value", "label"];
132
- var CheckableTag = antd.Tag.CheckableTag;
133
- var context = React.createContext({});
134
- var Provider = context.Provider;
135
-
136
- var List = function List(_ref) {
137
- var label = _ref.label,
138
- labelHidden = _ref.labelHidden,
139
- name = _ref.name,
140
- size = _ref.size,
141
- children = _ref.children,
142
- options = _ref.options,
143
- more = _ref.more;
344
+ const withLocale = reactIntl.createWithIntlProvider({
345
+ defaultLocale: 'zh-CN',
346
+ messages: {
347
+ 'zh-CN': message$1,
348
+ 'en-US': message
349
+ },
350
+ namespace: 'react-filter'
351
+ });
144
352
 
145
- var _useConsumer = useConsumer(),
146
- value = _useConsumer.value,
147
- onChange = _useConsumer.onChange;
353
+ const FilterValueDisplay = withLocale(_ref => {
354
+ let filterValue = _ref.value,
355
+ extraExpand = _ref.extraExpand,
356
+ onChange = _ref.onChange;
357
+ const _useIntl = reactIntl.useIntl({
358
+ moduleName: 'Filter'
359
+ }),
360
+ formatMessage = _useIntl.formatMessage;
361
+ return /*#__PURE__*/jsxRuntime.jsxs(antd.Space, {
362
+ className: style$1['filter-title'],
363
+ align: "top",
364
+ size: 16,
365
+ children: [/*#__PURE__*/jsxRuntime.jsx("span", {
366
+ className: style$1['filter-label'],
367
+ children: formatMessage({
368
+ id: 'selectedText'
369
+ })
370
+ }), /*#__PURE__*/jsxRuntime.jsxs("div", {
371
+ className: style$1['filter-line'],
372
+ children: [filterValue.map((_ref2, index) => {
373
+ let name = _ref2.name,
374
+ label = _ref2.label,
375
+ value = _ref2.value;
376
+ const valueLabel = Array.isArray(value) ? value.map(item => item.label).join(',') : value == null ? void 0 : value.label;
377
+ return /*#__PURE__*/jsxRuntime.jsxs(antd.Tag, {
378
+ closable: true,
379
+ className: style$1['filter-value-tag'],
380
+ onClose: () => {
381
+ const newValue = filterValue.slice(0);
382
+ newValue.splice(index, 1);
383
+ onChange(newValue);
384
+ },
385
+ children: [/*#__PURE__*/jsxRuntime.jsxs("span", {
386
+ className: style$1['filter-value-tag-label'],
387
+ children: [label, ":"]
388
+ }), /*#__PURE__*/jsxRuntime.jsx("span", {
389
+ className: style$1['filter-value-tag-content'],
390
+ children: valueLabel
391
+ })]
392
+ }, name);
393
+ }), /*#__PURE__*/jsxRuntime.jsxs(antd.Space, {
394
+ size: 4,
395
+ className: classnames__default["default"](style$1['un-expand-shadow']),
396
+ children: [extraExpand, /*#__PURE__*/jsxRuntime.jsx(antd.Button, {
397
+ size: "small",
398
+ children: formatMessage({
399
+ id: 'clearAllText'
400
+ })
401
+ })]
402
+ }), /*#__PURE__*/jsxRuntime.jsxs(antd.Space, {
403
+ size: 4,
404
+ className: classnames__default["default"](style$1['un-expand']),
405
+ children: [extraExpand, /*#__PURE__*/jsxRuntime.jsx(antd.Button, {
406
+ size: "small",
407
+ onClick: () => {
408
+ onChange([]);
409
+ },
410
+ children: formatMessage({
411
+ id: 'clearAllText'
412
+ })
413
+ })]
414
+ })]
415
+ })]
416
+ });
417
+ });
148
418
 
149
- var currentValue = function () {
150
- var originValue = lodash.get(value, name);
419
+ const isNotEmpty$2 = value => {
420
+ if (value === null || value === undefined) return false;
421
+ if (typeof value === 'string' && value.trim() === '') return false;
422
+ if (Array.isArray(value) && value.length === 0) return false;
423
+ return true;
424
+ };
425
+ const FilterProvider = _ref => {
426
+ let children = _ref.children,
427
+ valueBase = _ref.value,
428
+ onChange = _ref.onChange,
429
+ _ref$defaultValue = _ref.defaultValue,
430
+ defaultValue = _ref$defaultValue === void 0 ? [] : _ref$defaultValue;
431
+ const value = react.useMemo(() => {
432
+ return (valueBase || defaultValue).filter(item => isNotEmpty$2(item.value));
433
+ }, [valueBase, defaultValue]);
434
+ const filterValue = react.useMemo(() => {
435
+ return new Map(value.map(item => [item.name, item]));
436
+ }, [value]);
437
+ return /*#__PURE__*/jsxRuntime.jsx(Provider, {
438
+ value: {
439
+ value: filterValue,
440
+ onChange: item => {
441
+ const newFilterValue = clone__default["default"](filterValue);
442
+ item.value ? newFilterValue.set(item.name, item) : newFilterValue.delete(item.name);
443
+ onChange == null || onChange(Array.from(newFilterValue.values()));
444
+ }
445
+ },
446
+ children: typeof children === 'function' ? children({
447
+ value,
448
+ onChange
449
+ }) : children
450
+ });
451
+ };
151
452
 
152
- if (size === 1) {
153
- return originValue !== void 0 ? [originValue] : [];
154
- } else {
155
- return originValue || [];
156
- }
157
- }();
453
+ const FilterOuter = ({
454
+ children,
455
+ className,
456
+ ...props
457
+ }) => {
458
+ return /*#__PURE__*/jsxRuntime.jsx(FilterProvider, {
459
+ ...props,
460
+ children: context => /*#__PURE__*/jsxRuntime.jsx("div", {
461
+ className: classnames__default["default"](style$1['filter'], 'filter', className),
462
+ children: children({
463
+ ...context,
464
+ props
465
+ })
466
+ })
467
+ });
468
+ };
158
469
 
159
- var changeHandler = function changeHandler(value) {
160
- if (size === 1) {
161
- return onChange(name, value[0]);
162
- } else {
163
- return onChange(name, value);
470
+ const _excluded$7 = ["defaultValue"],
471
+ _excluded2 = ["extraExpand"];
472
+ const Filter = withLocale(_ref => {
473
+ let _ref$defaultValue = _ref.defaultValue,
474
+ defaultValue = _ref$defaultValue === void 0 ? [] : _ref$defaultValue,
475
+ props = _objectWithoutPropertiesLoose(_ref, _excluded$7);
476
+ return /*#__PURE__*/jsxRuntime.jsx(FilterOuter, _extends({}, props, {
477
+ defaultValue: defaultValue,
478
+ children: _ref2 => {
479
+ let _ref2$props = _ref2.props,
480
+ filterProps = _ref2$props === void 0 ? {} : _ref2$props,
481
+ value = _ref2.value,
482
+ onChange = _ref2.onChange;
483
+ const extraExpand = filterProps.extraExpand,
484
+ others = _objectWithoutPropertiesLoose(filterProps, _excluded2);
485
+ return /*#__PURE__*/jsxRuntime.jsxs(jsxRuntime.Fragment, {
486
+ children: [/*#__PURE__*/jsxRuntime.jsx(FilterLines, _extends({}, others)), value && value.length > 0 && /*#__PURE__*/jsxRuntime.jsx(FilterValueDisplay, {
487
+ value: value,
488
+ onChange: onChange,
489
+ extraExpand: extraExpand
490
+ })]
491
+ });
164
492
  }
165
- };
166
-
167
- var createCheckedChangeHandler = function createCheckedChangeHandler(value) {
168
- return function (checked) {
169
- if (checked) {
170
- var newList = currentValue.slice(0);
171
-
172
- if (currentValue.length < size) {
173
- newList.push(value);
174
- }
175
-
176
- if (currentValue.length === size && size === 1) {
177
- newList = [value];
178
- }
179
-
180
- if (currentValue.length >= size && size > 1) {
181
- antd.message.error("\u6700\u591A\u9009\u62E9" + size + "\u4E2A");
182
- return;
183
- }
184
-
185
- changeHandler(newList);
186
- } else {
187
- var _newList = currentValue.slice(0);
493
+ }));
494
+ });
188
495
 
189
- _newList.splice(lodash.findIndex(currentValue, function (item) {
190
- return item.value === value.value;
191
- }), 1);
496
+ const FilterItem = withLocale(_ref => {
497
+ let open = _ref.open,
498
+ active = _ref.active,
499
+ label = _ref.label,
500
+ children = _ref.children;
501
+ return /*#__PURE__*/jsxRuntime.jsx(antd.Space, {
502
+ className: style$1['filter-item-wrap'],
503
+ children: /*#__PURE__*/jsxRuntime.jsxs("div", {
504
+ className: classnames__default["default"](style$1['filter-item'], {
505
+ [style$1['is-active']]: active,
506
+ [style$1['is-visited']]: open
507
+ }),
508
+ children: [/*#__PURE__*/jsxRuntime.jsxs(antd.Space, {
509
+ className: style$1['filter-item-label'],
510
+ size: 4,
511
+ children: [/*#__PURE__*/jsxRuntime.jsx("div", {
512
+ children: label
513
+ }), /*#__PURE__*/jsxRuntime.jsx("span", {
514
+ className: style$1['filter-item-icon'],
515
+ children: "\u25BC"
516
+ })]
517
+ }), /*#__PURE__*/jsxRuntime.jsx("div", {
518
+ className: style$1['filter-item-field'],
519
+ children: children
520
+ })]
521
+ })
522
+ });
523
+ });
192
524
 
193
- changeHandler(_newList);
525
+ const _excluded$6 = ["value", "onChange", "interceptor", "label", "render"];
526
+ const isNotEmpty$1 = value => {
527
+ if (value === null || value === undefined) return false;
528
+ if (typeof value === 'string' && value.trim() === '') return false;
529
+ return !(Array.isArray(value) && value.length === 0);
530
+ };
531
+ const MASK_ANIMATION_DURATION$1 = 180;
532
+ const FIELD_MOBILE_POPUP_CLASS = 'react-filter-field-mobile-popup';
533
+ const MOBILE_POPUP_OFFSET$1 = 4;
534
+ const withFieldItem = function (WrappedComponent, options) {
535
+ if (options === void 0) {
536
+ options = {};
537
+ }
538
+ return _ref => {
539
+ let value = _ref.value,
540
+ onChange = _ref.onChange,
541
+ interceptor = _ref.interceptor,
542
+ label = _ref.label,
543
+ render = _ref.render,
544
+ props = _objectWithoutPropertiesLoose(_ref, _excluded$6);
545
+ const _useState = react.useState(false),
546
+ open = _useState[0],
547
+ setOpen = _useState[1];
548
+ const _useState2 = react.useState(false),
549
+ isMobile = _useState2[0],
550
+ setIsMobile = _useState2[1];
551
+ const _useState3 = react.useState(false),
552
+ renderMask = _useState3[0],
553
+ setRenderMask = _useState3[1];
554
+ const _useState4 = react.useState(false),
555
+ maskClosing = _useState4[0],
556
+ setMaskClosing = _useState4[1];
557
+ const _useState5 = react.useState({
558
+ top: 0,
559
+ pageTop: 0,
560
+ height: 0
561
+ }),
562
+ popupMetrics = _useState5[0],
563
+ setPopupMetrics = _useState5[1];
564
+ const triggerRef = react.useRef(null);
565
+ const updatePopupMetrics = react.useCallback(() => {
566
+ if (typeof window === 'undefined' || !triggerRef.current) return;
567
+ const rect = triggerRef.current.getBoundingClientRect();
568
+ const top = Math.max(rect.bottom + MOBILE_POPUP_OFFSET$1, 0);
569
+ setPopupMetrics({
570
+ top,
571
+ pageTop: top + window.scrollY,
572
+ height: Math.max(window.innerHeight - top, 0)
573
+ });
574
+ }, []);
575
+ react.useEffect(() => {
576
+ if (typeof window === 'undefined') return;
577
+ const mediaQuery = window.matchMedia('(max-width: 768px)');
578
+ const updateIsMobile = () => {
579
+ setIsMobile(mediaQuery.matches);
580
+ };
581
+ updateIsMobile();
582
+ mediaQuery.addEventListener ? mediaQuery.addEventListener('change', updateIsMobile) : mediaQuery.addListener(updateIsMobile);
583
+ return () => {
584
+ mediaQuery.removeEventListener ? mediaQuery.removeEventListener('change', updateIsMobile) : mediaQuery.removeListener(updateIsMobile);
585
+ };
586
+ }, []);
587
+ react.useEffect(() => {
588
+ if (!open || !isMobile) return;
589
+ updatePopupMetrics();
590
+ window.addEventListener('resize', updatePopupMetrics);
591
+ window.addEventListener('scroll', updatePopupMetrics, true);
592
+ return () => {
593
+ window.removeEventListener('resize', updatePopupMetrics);
594
+ window.removeEventListener('scroll', updatePopupMetrics, true);
595
+ };
596
+ }, [isMobile, open, updatePopupMetrics]);
597
+ react.useEffect(() => {
598
+ if (typeof document === 'undefined' || !isMobile) return;
599
+ document.body.style.setProperty('--react-filter-field-mobile-height', popupMetrics.height + "px");
600
+ document.body.style.setProperty('--react-filter-popover-mobile-height', popupMetrics.height + "px");
601
+ document.body.style.setProperty('--react-filter-field-mobile-top', popupMetrics.pageTop + "px");
602
+ return () => {
603
+ document.body.style.removeProperty('--react-filter-field-mobile-height');
604
+ document.body.style.removeProperty('--react-filter-popover-mobile-height');
605
+ document.body.style.removeProperty('--react-filter-field-mobile-top');
606
+ };
607
+ }, [isMobile, popupMetrics.height, popupMetrics.pageTop]);
608
+ react.useEffect(() => {
609
+ if (open && isMobile) {
610
+ setRenderMask(true);
611
+ setMaskClosing(false);
612
+ return;
613
+ }
614
+ if (!renderMask) return;
615
+ setMaskClosing(true);
616
+ const timer = setTimeout(() => {
617
+ setRenderMask(false);
618
+ setMaskClosing(false);
619
+ }, MASK_ANIMATION_DURATION$1);
620
+ return () => {
621
+ clearTimeout(timer);
622
+ };
623
+ }, [isMobile, open, renderMask]);
624
+ const closeFieldItem = react.useCallback(() => {
625
+ setOpen(false);
626
+ props.onOpenChange && props.onOpenChange(false);
627
+ props.onDropdownVisibleChange && props.onDropdownVisibleChange(false);
628
+ }, [props]);
629
+ const handleOpenChange = react.useCallback(open => {
630
+ if (open && isMobile) {
631
+ updatePopupMetrics();
194
632
  }
633
+ setOpen(open);
634
+ props.onOpenChange && props.onOpenChange(open);
635
+ props.onDropdownVisibleChange && props.onDropdownVisibleChange(open);
636
+ }, [isMobile, props, updatePopupMetrics]);
637
+ const mobilePopupStyle = isMobile ? {
638
+ '--react-filter-field-mobile-height': popupMetrics.height + "px",
639
+ '--react-filter-popover-mobile-height': popupMetrics.height + "px",
640
+ '--react-filter-field-mobile-top': popupMetrics.pageTop + "px"
641
+ } : undefined;
642
+ const mergePopupClassNames = classNames => {
643
+ var _classNames$popup;
644
+ if (!isMobile) return classNames;
645
+ return Object.assign({}, classNames, {
646
+ popup: Object.assign({}, classNames == null ? void 0 : classNames.popup, {
647
+ root: classnames__default["default"](classNames == null || (_classNames$popup = classNames.popup) == null ? void 0 : _classNames$popup.root, style$1['field-item-mobile-popup'], FIELD_MOBILE_POPUP_CLASS)
648
+ })
649
+ });
195
650
  };
651
+ const mergePopupStyles = styles => {
652
+ var _styles$popup;
653
+ if (!isMobile) return styles;
654
+ return Object.assign({}, styles, {
655
+ popup: Object.assign({}, styles == null ? void 0 : styles.popup, {
656
+ root: Object.assign({}, styles == null || (_styles$popup = styles.popup) == null ? void 0 : _styles$popup.root, mobilePopupStyle)
657
+ })
658
+ });
659
+ };
660
+ const renderChildren = otherProps => /*#__PURE__*/jsxRuntime.jsx(WrappedComponent, _extends({
661
+ allowClear: false
662
+ }, Object.assign({}, props, otherProps), {
663
+ className: style$1['filter-item-inner'],
664
+ value: typeof (interceptor == null ? void 0 : interceptor.input) === 'function' ? interceptor.input(value) : value,
665
+ onChange: typeof (interceptor == null ? void 0 : interceptor.output) === 'function' ? function () {
666
+ return onChange(interceptor.output(...[].slice.call(arguments)));
667
+ } : onChange,
668
+ valueType: "all",
669
+ onOpenChange: handleOpenChange,
670
+ onDropdownVisibleChange: handleOpenChange,
671
+ popupClassName: classnames__default["default"](props.popupClassName, isMobile && style$1['field-item-mobile-popup'], isMobile && FIELD_MOBILE_POPUP_CLASS),
672
+ dropdownClassName: classnames__default["default"](props.dropdownClassName, isMobile && style$1['field-item-mobile-popup'], isMobile && FIELD_MOBILE_POPUP_CLASS),
673
+ overlayClassName: classnames__default["default"](props.overlayClassName, isMobile && style$1['field-item-mobile-popup'], isMobile && FIELD_MOBILE_POPUP_CLASS),
674
+ popupStyle: Object.assign({}, props.popupStyle, mobilePopupStyle),
675
+ dropdownStyle: Object.assign({}, props.dropdownStyle, mobilePopupStyle),
676
+ classNames: mergePopupClassNames(props.classNames),
677
+ styles: mergePopupStyles(props.styles),
678
+ transitionName: isMobile ? '' : props.transitionName,
679
+ isPopup: options.forcePopup ? true : props.isPopup,
680
+ overlayWidth: isMobile && options.forcePopup ? typeof window === 'undefined' ? props.overlayWidth : window.innerWidth : props.overlayWidth
681
+ }));
682
+ return /*#__PURE__*/jsxRuntime.jsxs(jsxRuntime.Fragment, {
683
+ children: [renderMask && typeof document !== 'undefined' && /*#__PURE__*/reactDom.createPortal(/*#__PURE__*/jsxRuntime.jsx("div", {
684
+ className: classnames__default["default"](style$1['pop-util-mask'], maskClosing && style$1['pop-util-mask-leave']),
685
+ style: {
686
+ top: popupMetrics.top,
687
+ height: popupMetrics.height
688
+ },
689
+ onClick: closeFieldItem
690
+ }), document.body), /*#__PURE__*/jsxRuntime.jsx("span", {
691
+ ref: triggerRef,
692
+ children: /*#__PURE__*/jsxRuntime.jsx(FilterItem, {
693
+ label: label,
694
+ open: open,
695
+ active: isNotEmpty$1(value),
696
+ children: typeof render === 'function' ? render({
697
+ children: renderChildren
698
+ }) : renderChildren()
699
+ })
700
+ })]
701
+ });
196
702
  };
703
+ };
197
704
 
198
- var computedChildren = function () {
199
- if (Array.isArray(options)) {
200
- return options.map(function (_ref2) {
201
- var label = _ref2.label,
202
- value = _ref2.value;
203
- return /*#__PURE__*/React__default["default"].createElement(List.Item, {
204
- key: value,
205
- value: value,
206
- label: label
207
- });
208
- });
705
+ const isNotEmpty = value => {
706
+ if (value === null || value === undefined) return false;
707
+ if (typeof value === 'string' && value.trim() === '') return false;
708
+ if (Array.isArray(value) && value.length === 0) return false;
709
+ return true;
710
+ };
711
+ const MASK_ANIMATION_DURATION = 180;
712
+ const MOBILE_POPUP_OFFSET = 4;
713
+ const PopoverItem = withLocale(_ref => {
714
+ let value = _ref.value,
715
+ label = _ref.label,
716
+ onValidate = _ref.onValidate,
717
+ overlayClassName = _ref.overlayClassName,
718
+ _ref$placement = _ref.placement,
719
+ placement = _ref$placement === void 0 ? 'bottomLeft' : _ref$placement,
720
+ onOpenChange = _ref.onOpenChange,
721
+ onChange = _ref.onChange,
722
+ children = _ref.children;
723
+ const _useState = react.useState(value),
724
+ state = _useState[0],
725
+ setState = _useState[1];
726
+ const _useState2 = react.useState(false),
727
+ open = _useState2[0],
728
+ setOpen = _useState2[1];
729
+ const _useState3 = react.useState(false),
730
+ isMobile = _useState3[0],
731
+ setIsMobile = _useState3[1];
732
+ const _useState4 = react.useState(false),
733
+ renderMask = _useState4[0],
734
+ setRenderMask = _useState4[1];
735
+ const _useState5 = react.useState(false),
736
+ maskClosing = _useState5[0],
737
+ setMaskClosing = _useState5[1];
738
+ const _useState6 = react.useState({
739
+ top: 0,
740
+ pageTop: 0,
741
+ height: 0
742
+ }),
743
+ popupMetrics = _useState6[0],
744
+ setPopupMetrics = _useState6[1];
745
+ const triggerRef = react.useRef(null);
746
+ const disabled = react.useMemo(() => {
747
+ return onValidate && !onValidate(state);
748
+ }, [onValidate, state]);
749
+ const _useIntl = reactIntl.useIntl({
750
+ moduleName: 'Filter'
751
+ }),
752
+ formatMessage = _useIntl.formatMessage;
753
+ react.useEffect(() => {
754
+ if (typeof window === 'undefined') return;
755
+ const mediaQuery = window.matchMedia('(max-width: 768px)');
756
+ const updateIsMobile = () => {
757
+ setIsMobile(mediaQuery.matches);
758
+ };
759
+ updateIsMobile();
760
+ mediaQuery.addEventListener ? mediaQuery.addEventListener('change', updateIsMobile) : mediaQuery.addListener(updateIsMobile);
761
+ return () => {
762
+ mediaQuery.removeEventListener ? mediaQuery.removeEventListener('change', updateIsMobile) : mediaQuery.removeListener(updateIsMobile);
763
+ };
764
+ }, []);
765
+ const updatePopupMetrics = react.useCallback(() => {
766
+ if (typeof window === 'undefined' || !triggerRef.current) return;
767
+ const rect = triggerRef.current.getBoundingClientRect();
768
+ const top = Math.max(rect.bottom + MOBILE_POPUP_OFFSET, 0);
769
+ setPopupMetrics({
770
+ top,
771
+ pageTop: top + window.scrollY,
772
+ height: Math.max(window.innerHeight - top, 0)
773
+ });
774
+ }, []);
775
+ react.useEffect(() => {
776
+ if (!open || !isMobile) return;
777
+ updatePopupMetrics();
778
+ window.addEventListener('resize', updatePopupMetrics);
779
+ window.addEventListener('scroll', updatePopupMetrics, true);
780
+ return () => {
781
+ window.removeEventListener('resize', updatePopupMetrics);
782
+ window.removeEventListener('scroll', updatePopupMetrics, true);
783
+ };
784
+ }, [isMobile, open, updatePopupMetrics]);
785
+ react.useEffect(() => {
786
+ if (open && isMobile) {
787
+ setRenderMask(true);
788
+ setMaskClosing(false);
789
+ return;
209
790
  }
210
-
211
- if (lodash.isFunction(children)) {
212
- return children({
213
- value: currentValue,
214
- onChange: changeHandler
215
- });
791
+ if (!renderMask) return;
792
+ setMaskClosing(true);
793
+ const timer = setTimeout(() => {
794
+ setRenderMask(false);
795
+ setMaskClosing(false);
796
+ }, MASK_ANIMATION_DURATION);
797
+ return () => {
798
+ clearTimeout(timer);
799
+ };
800
+ }, [isMobile, open, renderMask]);
801
+ const closeDropdown = react.useCallback(() => {
802
+ setOpen(false);
803
+ onOpenChange && onOpenChange(false);
804
+ }, [onOpenChange]);
805
+ const handleOpenChange = react.useCallback(open => {
806
+ if (open && isMobile) {
807
+ updatePopupMetrics();
216
808
  }
809
+ setOpen(open);
810
+ setState(value);
811
+ onOpenChange && onOpenChange(open);
812
+ }, [isMobile, onOpenChange, updatePopupMetrics, value]);
813
+ const mobileOverlayStyle = isMobile ? {
814
+ '--react-filter-popover-mobile-height': popupMetrics.height + "px",
815
+ top: popupMetrics.pageTop,
816
+ left: 0
817
+ } : undefined;
818
+ const overlayContent = /*#__PURE__*/jsxRuntime.jsxs("div", {
819
+ className: style$1['pop-util-body'],
820
+ onClick: e => {
821
+ e.stopPropagation();
822
+ },
823
+ children: [/*#__PURE__*/jsxRuntime.jsx("div", {
824
+ className: style$1['pop-util-content'],
825
+ children: children({
826
+ value: state,
827
+ onChange: setState
828
+ })
829
+ }), /*#__PURE__*/jsxRuntime.jsxs(antd.Row, {
830
+ className: style$1['pop-util-footer'],
831
+ justify: "end",
832
+ gutter: 8,
833
+ children: [/*#__PURE__*/jsxRuntime.jsx(antd.Col, {
834
+ children: /*#__PURE__*/jsxRuntime.jsx(antd.Button, {
835
+ size: "small",
836
+ onClick: closeDropdown,
837
+ children: formatMessage({
838
+ id: 'cancelText'
839
+ })
840
+ })
841
+ }), /*#__PURE__*/jsxRuntime.jsx(antd.Col, {
842
+ children: /*#__PURE__*/jsxRuntime.jsx(antd.Button, {
843
+ size: "small",
844
+ type: "primary",
845
+ disabled: disabled,
846
+ onClick: () => {
847
+ closeDropdown();
848
+ onChange && onChange(state);
849
+ },
850
+ children: formatMessage({
851
+ id: 'determineText'
852
+ })
853
+ })
854
+ })]
855
+ })]
856
+ });
857
+ return /*#__PURE__*/jsxRuntime.jsxs(jsxRuntime.Fragment, {
858
+ children: [renderMask && typeof document !== 'undefined' && /*#__PURE__*/reactDom.createPortal(/*#__PURE__*/jsxRuntime.jsx("div", {
859
+ className: classnames__default["default"](style$1['pop-util-mask'], maskClosing && style$1['pop-util-mask-leave']),
860
+ style: {
861
+ top: popupMetrics.top,
862
+ height: popupMetrics.height
863
+ },
864
+ onClick: closeDropdown
865
+ }), document.body), /*#__PURE__*/jsxRuntime.jsx(antd.Dropdown, {
866
+ open: open,
867
+ trigger: ['click'],
868
+ placement: isMobile ? 'bottomLeft' : placement,
869
+ autoAdjustOverflow: !isMobile,
870
+ align: isMobile ? {
871
+ offset: [0, 0]
872
+ } : undefined,
873
+ overlayClassName: classnames__default["default"](style$1['pop-util-overlay'], overlayClassName),
874
+ overlayStyle: mobileOverlayStyle,
875
+ onOpenChange: handleOpenChange,
876
+ menu: {
877
+ items: [{
878
+ key: 'content',
879
+ label: null
880
+ }]
881
+ },
882
+ dropdownRender: () => overlayContent,
883
+ children: /*#__PURE__*/jsxRuntime.jsx("span", {
884
+ ref: triggerRef,
885
+ children: /*#__PURE__*/jsxRuntime.jsx(FilterItem, {
886
+ open: open,
887
+ active: isNotEmpty(value),
888
+ label: label
889
+ })
890
+ })
891
+ })]
892
+ });
893
+ });
217
894
 
218
- return children;
219
- }();
895
+ const InputFilterItem$2 = withLocale(({
896
+ label,
897
+ value,
898
+ onChange,
899
+ placeholder,
900
+ onValidate,
901
+ overlayClassName,
902
+ placement,
903
+ onOpenChange,
904
+ ...props
905
+ }) => {
906
+ return /*#__PURE__*/jsxRuntime.jsx(PopoverItem, {
907
+ label: label,
908
+ value: value,
909
+ onChange: onChange,
910
+ onValidate,
911
+ overlayClassName,
912
+ placement,
913
+ onOpenChange,
914
+ children: ({
915
+ value,
916
+ onChange
917
+ }) => /*#__PURE__*/jsxRuntime.jsx(antd.Input, {
918
+ ...props,
919
+ placeholder: placeholder || `请输入${label}`,
920
+ className: style$1['filter-item-text'],
921
+ value: get__default["default"](value, 'value', ''),
922
+ onChange: e => onChange(e.target.value ? {
923
+ label: e.target.value,
924
+ value: e.target.value
925
+ } : null)
926
+ })
927
+ });
928
+ });
220
929
 
221
- return /*#__PURE__*/React__default["default"].createElement(FilterItem, {
930
+ const computedFilterValue = (range, unit, formatMessage) => {
931
+ if (!isNumber__default["default"](range[0]) && !isNumber__default["default"](range[1])) {
932
+ return null;
933
+ }
934
+ return {
935
+ label: (range => {
936
+ if (isNumber__default["default"](range[0]) && isNumber__default["default"](range[1])) {
937
+ return `${range[0]}-${range[1]}${unit || ''}`;
938
+ }
939
+ if (isNumber__default["default"](range[0])) {
940
+ return formatMessage({
941
+ id: 'over'
942
+ }, {
943
+ count: range[0],
944
+ unit
945
+ });
946
+ }
947
+ if (isNumber__default["default"](range[1])) {
948
+ return formatMessage({
949
+ id: 'lessThan'
950
+ }, {
951
+ count: range[1],
952
+ unit
953
+ });
954
+ }
955
+ })(range),
956
+ value: [range[0] || null, range[1] || null]
957
+ };
958
+ };
959
+ const defaultPropsOnValidate = value => {
960
+ const range = get__default["default"](value, 'value');
961
+ return !(range && isNumber__default["default"](range[0]) && isNumber__default["default"](range[1]) && range[1] < range[0]);
962
+ };
963
+ const NumberRangeFilterItem$1 = withLocale(({
964
+ label,
965
+ value,
966
+ onChange,
967
+ placeholder,
968
+ onValidate = defaultPropsOnValidate,
969
+ overlayClassName,
970
+ placement,
971
+ onOpenChange,
972
+ unit,
973
+ ...props
974
+ }) => {
975
+ const {
976
+ formatMessage
977
+ } = reactIntl.useIntl({
978
+ moduleName: 'Filter'
979
+ });
980
+ return /*#__PURE__*/jsxRuntime.jsx(PopoverItem, {
222
981
  label: label,
223
- labelHidden: labelHidden
224
- }, /*#__PURE__*/React__default["default"].createElement(Provider, {
225
- value: {
226
- currentValue: currentValue,
227
- createCheckedChangeHandler: createCheckedChangeHandler
228
- }
229
- }, computedChildren, more ? function () {
230
- if (lodash.isFunction(more)) {
231
- return more({
232
- name: name,
233
- size: size,
234
- label: label,
235
- value: currentValue,
236
- onChange: changeHandler
982
+ value: value,
983
+ onChange: onChange,
984
+ onValidate,
985
+ overlayClassName,
986
+ placement,
987
+ onOpenChange,
988
+ children: ({
989
+ value,
990
+ onChange
991
+ }) => /*#__PURE__*/jsxRuntime.jsxs(antd.Space.Compact, {
992
+ children: [/*#__PURE__*/jsxRuntime.jsx(antd.InputNumber, {
993
+ ...props,
994
+ placeholder: placeholder || `${formatMessage({
995
+ id: 'pleaseInput'
996
+ })}${label}`,
997
+ className: style$1['filter-item-number-range'],
998
+ value: get__default["default"](value, 'value[0]', ''),
999
+ onChange: target => {
1000
+ onChange(computedFilterValue([target, get__default["default"](value, 'value[1]')], unit, formatMessage));
1001
+ }
1002
+ }), /*#__PURE__*/jsxRuntime.jsx(antd.Input, {
1003
+ style: {
1004
+ width: 30,
1005
+ borderLeft: 0,
1006
+ borderRight: 0,
1007
+ pointerEvents: 'none'
1008
+ },
1009
+ placeholder: "~",
1010
+ disabled: true
1011
+ }), /*#__PURE__*/jsxRuntime.jsx(antd.InputNumber, {
1012
+ ...props,
1013
+ placeholder: placeholder || `${formatMessage({
1014
+ id: 'pleaseInput'
1015
+ })}${label}`,
1016
+ className: style$1['filter-item-number-range'],
1017
+ value: get__default["default"](value, 'value[1]', ''),
1018
+ onChange: target => {
1019
+ onChange(computedFilterValue([get__default["default"](value, 'value[0]'), target], unit, formatMessage));
1020
+ }
1021
+ }), unit && /*#__PURE__*/jsxRuntime.jsx(antd.Input, {
1022
+ style: {
1023
+ width: 50,
1024
+ borderLeft: 0
1025
+ },
1026
+ value: unit,
1027
+ disabled: true
1028
+ })]
1029
+ })
1030
+ });
1031
+ });
1032
+
1033
+ const DatePickerFilterItem = withLocale(withFieldItem(({
1034
+ value,
1035
+ onChange,
1036
+ picker = 'date',
1037
+ ...props
1038
+ }) => {
1039
+ return /*#__PURE__*/jsxRuntime.jsx(antd.DatePicker, {
1040
+ ...props,
1041
+ picker: picker,
1042
+ classNames: {
1043
+ ...props.classNames,
1044
+ popup: {
1045
+ ...props.classNames?.popup,
1046
+ root: classnames__default["default"](props.classNames?.popup?.root, style$1['date-picker-popup'])
1047
+ }
1048
+ },
1049
+ value: value && dayjs__default["default"](value.value),
1050
+ onChange: value => {
1051
+ const {
1052
+ format
1053
+ } = Object.assign({
1054
+ format: 'YYYY-MM-DD'
1055
+ }, props);
1056
+ value && onChange({
1057
+ label: picker !== 'date' ? `${value.startOf(picker).format(format)}~${value.endOf(picker).format(format)}` : value.format(format),
1058
+ value: new Date(value.startOf(picker).valueOf())
237
1059
  });
238
1060
  }
1061
+ });
1062
+ }));
239
1063
 
240
- var children = more.children,
241
- _onClick = more.onClick;
242
- return /*#__PURE__*/React__default["default"].createElement(List.Item, _extends({}, more, {
243
- onClick: function onClick(e) {
244
- _onClick({
245
- name: name,
246
- label: label,
247
- value: currentValue,
248
- onChange: changeHandler
249
- }, e);
1064
+ const DateRangePickerFilterItem = withLocale(withFieldItem(({
1065
+ value,
1066
+ onChange,
1067
+ header,
1068
+ ...props
1069
+ }) => {
1070
+ return /*#__PURE__*/jsxRuntime.jsxs(antd.Flex, {
1071
+ vertical: true,
1072
+ children: [typeof header === 'function' ? header({
1073
+ value,
1074
+ onChange
1075
+ }) : header, /*#__PURE__*/jsxRuntime.jsx(antd.DatePicker.RangePicker, {
1076
+ ...props,
1077
+ allowEmpty: [false, false],
1078
+ classNames: {
1079
+ ...props.classNames,
1080
+ popup: {
1081
+ ...props.classNames?.popup,
1082
+ root: classnames__default["default"](props.classNames?.popup?.root, style$1['date-range-picker-popup'])
1083
+ }
250
1084
  },
251
- label: children || "其他"
252
- }));
253
- }() : null));
254
- };
1085
+ value: value && Array.isArray(value.value) && value.value.length === 2 && value.value.map(item => dayjs__default["default"](item)),
1086
+ onChange: value => {
1087
+ const {
1088
+ format
1089
+ } = Object.assign({
1090
+ format: 'YYYY-MM-DD'
1091
+ }, props);
1092
+ onChange({
1093
+ label: value.map(item => item.format(format)).join('~'),
1094
+ value: value.map(item => new Date(item.valueOf()))
1095
+ });
1096
+ }
1097
+ })]
1098
+ });
1099
+ }));
255
1100
 
256
- List.Item = function (_ref3) {
257
- var value = _ref3.value,
258
- label = _ref3.label,
259
- props = _objectWithoutPropertiesLoose(_ref3, _excluded$8);
1101
+ var style = {"shortcuts-container":"kne-react-filter_3w4Bb","shortcut-item":"kne-react-filter_myRhG","is-active":"kne-react-filter_FowoG"};
1102
+
1103
+ const _excluded$5 = ["value", "onChange", "defaultValue", "shortcuts", "shortcutOptions"];
1104
+ const TypeDateRangePickerField = _ref => {
1105
+ let valueProp = _ref.value,
1106
+ onChangeProp = _ref.onChange,
1107
+ defaultValue = _ref.defaultValue,
1108
+ _ref$shortcuts = _ref.shortcuts,
1109
+ shortcuts = _ref$shortcuts === void 0 ? true : _ref$shortcuts,
1110
+ shortcutOptions = _ref.shortcutOptions,
1111
+ props = _objectWithoutPropertiesLoose(_ref, _excluded$5);
1112
+ const _useIntl = reactIntl.useIntl({
1113
+ moduleName: 'Filter'
1114
+ }),
1115
+ formatMessage = _useIntl.formatMessage;
1116
+ const typeList = new Map([['date', formatMessage({
1117
+ id: 'customTime'
1118
+ })], ['month', formatMessage({
1119
+ id: 'monthly'
1120
+ })], ['week', formatMessage({
1121
+ id: 'weekly'
1122
+ })]]);
1123
+ const defaultShortcuts = react.useMemo(() => [{
1124
+ label: formatMessage({
1125
+ id: 'last7Days'
1126
+ }),
1127
+ getValue: () => [dayjs__default["default"]().subtract(7, 'day').startOf('day'), dayjs__default["default"]().endOf('day')]
1128
+ }, {
1129
+ label: formatMessage({
1130
+ id: 'thisMonth'
1131
+ }),
1132
+ getValue: () => [dayjs__default["default"]().startOf('month'), dayjs__default["default"]().endOf('month')]
1133
+ }, {
1134
+ label: formatMessage({
1135
+ id: 'last3Months'
1136
+ }),
1137
+ getValue: () => [dayjs__default["default"]().subtract(3, 'month').startOf('day'), dayjs__default["default"]().endOf('day')]
1138
+ }, {
1139
+ label: formatMessage({
1140
+ id: 'thisYear'
1141
+ }),
1142
+ getValue: () => [dayjs__default["default"]().startOf('year'), dayjs__default["default"]().endOf('day')]
1143
+ }, {
1144
+ label: formatMessage({
1145
+ id: 'fullYear'
1146
+ }),
1147
+ getValue: () => [dayjs__default["default"]().startOf('year'), dayjs__default["default"]().endOf('year')]
1148
+ }], [formatMessage]);
1149
+ const currentShortcuts = shortcutOptions !== undefined ? shortcutOptions : shortcuts ? defaultShortcuts : null;
1150
+ const isControlled = valueProp !== undefined;
1151
+ const innerValueRef = react.useRef(defaultValue || {
1152
+ type: 'date',
1153
+ value: null
1154
+ });
1155
+ const value = isControlled ? valueProp : innerValueRef.current;
1156
+ const onChange = react.useCallback(newValue => {
1157
+ if (!isControlled) {
1158
+ innerValueRef.current = typeof newValue === 'function' ? newValue(innerValueRef.current) : newValue;
1159
+ }
1160
+ onChangeProp == null || onChangeProp(typeof newValue === 'function' ? newValue(value) : newValue);
1161
+ }, [isControlled, onChangeProp, value]);
1162
+ const handleShortcutClick = react.useCallback(shortcut => {
1163
+ const _shortcut$getValue = shortcut.getValue(),
1164
+ start = _shortcut$getValue[0],
1165
+ end = _shortcut$getValue[1];
1166
+ const type = 'date';
1167
+ onChange({
1168
+ type,
1169
+ value: [start.startOf(type).toDate(), end.endOf(type).toDate()]
1170
+ });
1171
+ }, [onChange]);
1172
+ const isShortcutActive = react.useCallback(shortcut => {
1173
+ if (!(value != null && value.value) || !Array.isArray(value.value) || value.value.length !== 2) {
1174
+ return false;
1175
+ }
1176
+ const _shortcut$getValue2 = shortcut.getValue(),
1177
+ start = _shortcut$getValue2[0],
1178
+ end = _shortcut$getValue2[1];
1179
+ const type = (value == null ? void 0 : value.type) || 'date';
1180
+ const valueStart = dayjs__default["default"](value.value[0]).startOf(type);
1181
+ const valueEnd = dayjs__default["default"](value.value[1]).endOf(type);
1182
+ const shortcutStart = start.startOf(type);
1183
+ const shortcutEnd = end.endOf(type);
1184
+ return valueStart.isSame(shortcutStart, type) && valueEnd.isSame(shortcutEnd, type);
1185
+ }, [value]);
1186
+ const renderShortcuts = react.useMemo(() => {
1187
+ if (!currentShortcuts || currentShortcuts.length === 0) {
1188
+ return null;
1189
+ }
1190
+ return /*#__PURE__*/jsxRuntime.jsx("div", {
1191
+ className: style['shortcuts-container'],
1192
+ children: currentShortcuts.map((shortcut, index) => /*#__PURE__*/jsxRuntime.jsx("span", {
1193
+ className: classnames__default["default"](style['shortcut-item'], {
1194
+ [style['is-active']]: isShortcutActive(shortcut)
1195
+ }),
1196
+ onClick: () => handleShortcutClick(shortcut),
1197
+ children: shortcut.label
1198
+ }, index))
1199
+ });
1200
+ }, [currentShortcuts, handleShortcutClick, isShortcutActive]);
1201
+ return /*#__PURE__*/jsxRuntime.jsxs(antd.Flex, {
1202
+ vertical: true,
1203
+ gap: 0,
1204
+ children: [/*#__PURE__*/jsxRuntime.jsxs(antd.Space.Compact, {
1205
+ children: [/*#__PURE__*/jsxRuntime.jsx(antd.Select, {
1206
+ style: {
1207
+ width: '120px'
1208
+ },
1209
+ value: (value == null ? void 0 : value.type) || 'date',
1210
+ onChange: typeValue => {
1211
+ onChange(currentValue => {
1212
+ var _currentValue$value;
1213
+ if (!(currentValue != null && (_currentValue$value = currentValue.value) != null && _currentValue$value.length)) {
1214
+ return {
1215
+ value: null,
1216
+ type: typeValue || 'date'
1217
+ };
1218
+ }
1219
+ const startTime = dayjs__default["default"](currentValue.value[0]);
1220
+ const endTime = dayjs__default["default"](currentValue.value[1]);
1221
+ return {
1222
+ value: [startTime.isValid() ? startTime.startOf(typeValue || 'date').toDate() : null, endTime.isValid() ? endTime.endOf(typeValue || 'date').toDate() : null],
1223
+ type: typeValue || 'date'
1224
+ };
1225
+ });
1226
+ },
1227
+ options: Array.from(typeList).map(_ref2 => {
1228
+ let val = _ref2[0],
1229
+ label = _ref2[1];
1230
+ return {
1231
+ label,
1232
+ value: val
1233
+ };
1234
+ })
1235
+ }), /*#__PURE__*/jsxRuntime.jsx(antd.DatePicker.RangePicker, _extends({}, props, {
1236
+ picker: (value == null ? void 0 : value.type) || 'date',
1237
+ value: Array.isArray(value == null ? void 0 : value.value) && value.value.length === 2 ? value.value.map(item => item && dayjs__default["default"](item)) : null,
1238
+ onChange: dateValue => {
1239
+ onChange(currentValue => {
1240
+ return Object.assign({
1241
+ type: 'date'
1242
+ }, currentValue, {
1243
+ value: dateValue && dateValue[0] && dateValue[1] ? [dateValue[0].startOf((currentValue == null ? void 0 : currentValue.type) || 'date').toDate(), dateValue[1].endOf((currentValue == null ? void 0 : currentValue.type) || 'date').toDate()] : null
1244
+ });
1245
+ });
1246
+ }
1247
+ }))]
1248
+ }), renderShortcuts]
1249
+ });
1250
+ };
260
1251
 
261
- var _useContext = React.useContext(context),
262
- currentValue = _useContext.currentValue,
263
- createCheckedChangeHandler = _useContext.createCheckedChangeHandler;
1252
+ const TypeDateRangePickerFilterItem = withLocale(({
1253
+ label,
1254
+ value,
1255
+ onChange,
1256
+ ...props
1257
+ }) => {
1258
+ return /*#__PURE__*/jsxRuntime.jsx(PopoverItem, {
1259
+ label: label,
1260
+ value: value,
1261
+ onChange: onChange,
1262
+ onValidate: item => {
1263
+ const itemValue = item?.value;
1264
+ return itemValue?.type && Array.isArray(itemValue?.value) && itemValue.value.length === 2;
1265
+ },
1266
+ children: ({
1267
+ value,
1268
+ onChange
1269
+ }) => /*#__PURE__*/jsxRuntime.jsx(TypeDateRangePickerField, {
1270
+ ...props,
1271
+ className: style$1['filter-item-text'],
1272
+ value: get__default["default"](value, 'value'),
1273
+ onChange: pickerValue => {
1274
+ const {
1275
+ format = 'YYYY-MM-DD'
1276
+ } = props;
1277
+ const val = pickerValue?.value || [];
1278
+ let displayLabel = '';
1279
+ if (val[0] && !val[1]) {
1280
+ displayLabel = `${dayjs__default["default"](val[0]).format(format)}以后`;
1281
+ } else if (!val[0] && val[1]) {
1282
+ displayLabel = `${dayjs__default["default"](val[1]).format(format)}以前`;
1283
+ } else if (val[0] && val[1]) {
1284
+ displayLabel = `${dayjs__default["default"](val[0]).format(format)}~${dayjs__default["default"](val[1]).format(format)}`;
1285
+ }
1286
+ onChange({
1287
+ label: displayLabel,
1288
+ value: pickerValue
1289
+ });
1290
+ }
1291
+ })
1292
+ });
1293
+ });
264
1294
 
265
- var itemProps = {};
1295
+ const _excluded$4 = ["placeholder", "label"];
1296
+ const withInputDefaultPlaceholder = WrappedComponent => withLocale(_ref => {
1297
+ let placeholder = _ref.placeholder,
1298
+ label = _ref.label,
1299
+ props = _objectWithoutPropertiesLoose(_ref, _excluded$4);
1300
+ const _useIntl = reactIntl.useIntl({
1301
+ moduleName: 'Filter'
1302
+ }),
1303
+ formatMessage = _useIntl.formatMessage;
1304
+ return /*#__PURE__*/jsxRuntime.jsx(WrappedComponent, _extends({}, props, {
1305
+ label: label,
1306
+ placeholder: placeholder || formatMessage({
1307
+ id: 'defaultInputPlaceholder'
1308
+ }, {
1309
+ label
1310
+ })
1311
+ }));
1312
+ });
1313
+ const InputFilterItem$1 = withInputDefaultPlaceholder(InputFilterItem$2);
1314
+ const NumberRangeFilterItem = withInputDefaultPlaceholder(NumberRangeFilterItem$1);
1315
+ const SuperSelectFilterItem = withFieldItem(SuperSelect__default["default"], {
1316
+ forcePopup: true
1317
+ });
1318
+ const SelectFunctionFilterItem = withFieldItem(superSelectPlus.SelectFunction, {
1319
+ forcePopup: true
1320
+ });
1321
+ const SelectIndustryFilterItem = withFieldItem(superSelectPlus.SelectIndustry, {
1322
+ forcePopup: true
1323
+ });
1324
+ const SelectAddressFilterItem = withFieldItem(superSelectPlus.SelectAddress, {
1325
+ forcePopup: true
1326
+ });
266
1327
 
267
- if (value !== void 0) {
268
- itemProps.checked = currentValue.findIndex(function (item) {
269
- return lodash.isEqual(lodash.get(item, 'value'), value);
270
- }) > -1;
271
- itemProps.onChange = createCheckedChangeHandler({
272
- label: label,
273
- value: value
274
- });
275
- }
1328
+ var fields$1 = {
1329
+ __proto__: null,
1330
+ InputFilterItem: InputFilterItem$1,
1331
+ NumberRangeFilterItem: NumberRangeFilterItem,
1332
+ SuperSelectFilterItem: SuperSelectFilterItem,
1333
+ SelectFunctionFilterItem: SelectFunctionFilterItem,
1334
+ SelectIndustryFilterItem: SelectIndustryFilterItem,
1335
+ SelectAddressFilterItem: SelectAddressFilterItem,
1336
+ DatePickerFilterItem: DatePickerFilterItem,
1337
+ DateRangePickerFilterItem: DateRangePickerFilterItem,
1338
+ TypeDateRangePickerFilterItem: TypeDateRangePickerFilterItem
1339
+ };
276
1340
 
277
- return /*#__PURE__*/React__default["default"].createElement(CheckableTag, _extends({}, props, itemProps), label);
1341
+ const getFilterValue = filterValue => {
1342
+ return transform__default["default"](filterValue, (result, _ref) => {
1343
+ let name = _ref.name,
1344
+ value = _ref.value;
1345
+ result[name] = Array.isArray(value) ? value.map(_ref2 => {
1346
+ let value = _ref2.value;
1347
+ return value;
1348
+ }) : value == null ? void 0 : value.value;
1349
+ }, {});
278
1350
  };
279
1351
 
280
- List.defaultProps = {
281
- size: 2
1352
+ const _excluded$3 = ["name", "label"];
1353
+ const withFilterValue = WrappedComponent => {
1354
+ return _ref => {
1355
+ let name = _ref.name,
1356
+ label = _ref.label,
1357
+ props = _objectWithoutPropertiesLoose(_ref, _excluded$3);
1358
+ const _useContext = useContext(),
1359
+ value = _useContext.value,
1360
+ onChange = _useContext.onChange;
1361
+ return /*#__PURE__*/jsxRuntime.jsx(WrappedComponent, _extends({}, props, {
1362
+ label: label,
1363
+ onChange: onChange ? value => onChange({
1364
+ name,
1365
+ label,
1366
+ value
1367
+ }) : props.onChange,
1368
+ value: value ? get__default["default"](value.get(name), 'value') : props.value
1369
+ }));
1370
+ };
282
1371
  };
283
1372
 
284
- var _excluded$7 = ["label", "labelHidden", "name", "size", "isMore"];
285
- var Item = List.Item;
1373
+ const _excluded$2 = ["label", "onChange", "value", "placeholder"];
1374
+ const Search = antd.Input.Search;
1375
+ const SearchInput = withFilterValue(_ref => {
1376
+ let label = _ref.label,
1377
+ onChange = _ref.onChange,
1378
+ value = _ref.value,
1379
+ placeholder = _ref.placeholder,
1380
+ props = _objectWithoutPropertiesLoose(_ref, _excluded$2);
1381
+ const _useIntl = reactIntl.useIntl({
1382
+ moduleName: 'Filter'
1383
+ }),
1384
+ formatMessage = _useIntl.formatMessage;
1385
+ return /*#__PURE__*/jsxRuntime.jsx(Search, _extends({}, props, {
1386
+ placeholder: placeholder || formatMessage({
1387
+ id: 'inputPlaceholder'
1388
+ }, {
1389
+ label
1390
+ }),
1391
+ value: (value == null ? void 0 : value.value) || '',
1392
+ onSearch: value => {
1393
+ onChange({
1394
+ label: value,
1395
+ value
1396
+ });
1397
+ }
1398
+ }));
1399
+ });
286
1400
 
287
- var City = function City(_ref) {
288
- var label = _ref.label,
289
- labelHidden = _ref.labelHidden,
290
- name = _ref.name,
291
- size = _ref.size;
292
- _objectWithoutPropertiesLoose(_ref, _excluded$7);
1401
+ /**
1402
+ * 从筛选值中提取原始值数组。
1403
+ * 支持:原始值、{ value } 对象、{ id } 对象、以及它们的数组。
1404
+ *
1405
+ * @example
1406
+ * pickSelectValues([{ value: 1 }, { id: 2 }, '3'])
1407
+ * // => ['1', '2', '3']
1408
+ *
1409
+ * pickSelectValues({ value: 'open' })
1410
+ * // => ['open']
1411
+ *
1412
+ * pickSelectValues(null)
1413
+ * // => []
1414
+ */
1415
+ const pickSelectValues = value => {
1416
+ if (value == null || value === '') {
1417
+ return [];
1418
+ }
1419
+ const list = Array.isArray(value) ? value : [value];
1420
+ return list.map(item => {
1421
+ if (item == null) {
1422
+ return null;
1423
+ }
1424
+ if (typeof item !== 'object') {
1425
+ return String(item);
1426
+ }
1427
+ if (item.value != null && item.value !== '') {
1428
+ return String(item.value);
1429
+ }
1430
+ if (item.id != null && item.id !== '') {
1431
+ return String(item.id);
1432
+ }
1433
+ return null;
1434
+ }).filter(Boolean);
1435
+ };
293
1436
 
294
- return /*#__PURE__*/React__default["default"].createElement(List, {
295
- labelHidden: labelHidden,
296
- label: label,
297
- name: name,
298
- size: size,
299
- more: {
300
- children: "其他",
301
- onClick: function onClick(_ref2) {
302
- var value = _ref2.value,
303
- _onChange = _ref2.onChange;
304
- reactCitySelect.createCitySelect({
305
- size: size,
306
- defaultValue: value.map(function (_ref3) {
307
- var value = _ref3.value;
308
- return value;
309
- }),
310
- onChange: function onChange(value) {
311
- Promise.all(value.map(function (id) {
312
- return reactCitySelect.apis.getCity(id).then(function (_ref4) {
313
- var city = _ref4.city;
314
- return {
315
- label: city.name,
316
- value: city.code
317
- };
318
- });
319
- })).then(function (value) {
320
- return _onChange(value);
321
- });
1437
+ /**
1438
+ * 声明式创建 mapFilterValue 函数。
1439
+ *
1440
+ * Filter.getFilterValue 默认只读取 { value },而 SuperSelectFilterItem 等
1441
+ * 组件使用 { id, name } 格式,需要额外处理。此工具通过声明字段映射规则,
1442
+ * 自动生成符合 (filter, getFilterValue) => value 签名的函数。
1443
+ *
1444
+ * @param {Object} fieldMappers - 字段名到映射规则的映射
1445
+ * @param {'string'} fieldMappers[field] - 确保值为字符串类型
1446
+ * @param {'multi'} fieldMappers[field] - 多选,从 filter entry 提取值数组
1447
+ * @param {'single'} fieldMappers[field] - 单选,从 filter entry 提取第一个值
1448
+ * @param {Function} fieldMappers[field] - 自定义转换,接收 (rawValue, { entry, filter, value }) 返回新值
1449
+ *
1450
+ * @example
1451
+ * const mapFilterValue = createFilterValueMapper({
1452
+ * id: 'string',
1453
+ * roles: 'multi',
1454
+ * tenantOrgId: 'single',
1455
+ * status: (rawValue) => normalizeStatus(rawValue)
1456
+ * });
1457
+ *
1458
+ * // 使用方式与手写 mapFilterValue 一致
1459
+ * const filterValue = mapFilterValue(filter, Filter.getFilterValue);
1460
+ *
1461
+ * // 也可直接传给 BizUnit 的 options.mapFilterValue
1462
+ * <BizUnit options={{ mapFilterValue }} />
1463
+ */
1464
+ const createFilterValueMapper = fieldMappers => {
1465
+ return (filter, getFilterValue) => {
1466
+ const value = getFilterValue(filter);
1467
+ Object.entries(fieldMappers).forEach(_ref => {
1468
+ let fieldName = _ref[0],
1469
+ mapper = _ref[1];
1470
+ const entry = filter.find(item => item.name === fieldName);
1471
+ if (mapper === 'string') {
1472
+ if (value[fieldName] != null && value[fieldName] !== '') {
1473
+ value[fieldName] = String(value[fieldName]);
1474
+ }
1475
+ } else if (mapper === 'multi') {
1476
+ if (entry) {
1477
+ const values = pickSelectValues(entry.value);
1478
+ if (values.length) {
1479
+ value[fieldName] = values;
1480
+ } else {
1481
+ delete value[fieldName];
322
1482
  }
323
- });
324
- }
325
- }
326
- }, function (_ref5) {
327
- var currentValue = _ref5.value;
328
- return /*#__PURE__*/React__default["default"].createElement(React__default["default"].Fragment, null, /*#__PURE__*/React__default["default"].createElement(reactCitySelect.RemoteData, {
329
- loader: reactCitySelect.apis.getChinaHotCities
330
- }, function (data) {
331
- var otherList = currentValue.filter(function (_ref6) {
332
- var code = _ref6.value;
333
- return !data.find(function (item) {
334
- return item.code === code;
335
- });
336
- });
337
- var extraLength = 0;
338
- data.forEach(function (item, index) {
339
- if (currentValue.findIndex(function (_ref7) {
340
- var value = _ref7.value;
341
- return value === item.code;
342
- }) > -1 && index >= data.length - otherList.length) {
343
- extraLength += 1;
344
1483
  }
345
- });
346
- return /*#__PURE__*/React__default["default"].createElement(React__default["default"].Fragment, null, otherList.map(function (_ref8) {
347
- var code = _ref8.value;
348
- return /*#__PURE__*/React__default["default"].createElement(reactCitySelect.DisplayCity, {
349
- id: code,
350
- key: code
351
- }, function (_ref9) {
352
- var item = _ref9.city;
353
- return /*#__PURE__*/React__default["default"].createElement(Item, {
354
- value: code,
355
- label: item.name
1484
+ } else if (mapper === 'single') {
1485
+ if (entry) {
1486
+ const values = pickSelectValues(entry.value);
1487
+ if (values[0] != null) {
1488
+ value[fieldName] = values[0];
1489
+ } else {
1490
+ delete value[fieldName];
1491
+ }
1492
+ } else if (value[fieldName] != null && typeof value[fieldName] === 'object') {
1493
+ const values = pickSelectValues(value[fieldName]);
1494
+ if (values.length) {
1495
+ value[fieldName] = values[0];
1496
+ } else {
1497
+ delete value[fieldName];
1498
+ }
1499
+ }
1500
+ } else if (typeof mapper === 'function') {
1501
+ let rawValue = value[fieldName];
1502
+ if (rawValue != null && typeof rawValue === 'object' && 'value' in rawValue) {
1503
+ rawValue = rawValue.value;
1504
+ }
1505
+ if (rawValue != null && rawValue !== '') {
1506
+ const result = mapper(rawValue, {
1507
+ entry,
1508
+ filter,
1509
+ value
356
1510
  });
357
- });
358
- }), data.filter(function (item, index) {
359
- return currentValue.findIndex(function (_ref10) {
360
- var value = _ref10.value;
361
- return value === item.code;
362
- }) > -1 || index < data.length - otherList.length - extraLength;
363
- }).map(function (item) {
364
- return /*#__PURE__*/React__default["default"].createElement(Item, {
365
- key: item.code,
366
- value: item.code,
367
- label: item.name
368
- });
369
- }));
370
- }));
371
- });
1511
+ if (result != null && result !== '') {
1512
+ value[fieldName] = result;
1513
+ } else {
1514
+ delete value[fieldName];
1515
+ }
1516
+ }
1517
+ }
1518
+ });
1519
+ return value;
1520
+ };
372
1521
  };
373
1522
 
374
- var SearchButton = function SearchButton(_ref) {
375
- var name = _ref.name,
376
- isMore = _ref.isMore,
377
- template = _ref.template,
378
- children = _ref.children,
379
- defaultValue = _ref.defaultValue,
380
- defaultActive = _ref.defaultActive,
381
- onBlur = _ref.onBlur,
382
- onSearch = _ref.onSearch,
383
- onBeforeSearch = _ref.onBeforeSearch,
384
- onActiveChange = _ref.onActiveChange,
385
- buttonText = _ref.buttonText;
386
-
387
- var _useConsumer = useConsumer(),
388
- aValue = _useConsumer.value,
389
- onChange = _useConsumer.onChange;
390
-
391
- var currentValue = aValue[name];
392
- var initCurrentValue = lodash.get(currentValue, "value");
393
-
394
- var _useState = React.useState(defaultValue || initCurrentValue),
395
- value = _useState[0],
396
- setValue = _useState[1];
397
-
398
- var _useState2 = React.useState(defaultActive),
399
- active = _useState2[0],
400
- setActive = _useState2[1];
401
-
402
- var withTemplate = function withTemplate(value) {
403
- if (value === void 0) {
404
- value = '';
405
- }
406
-
407
- return {
408
- value: value,
409
- label: lodash.isFunction(template) ? template(value) : value.toString()
410
- };
1523
+ /**
1524
+ * 创建 URL 参数读取器,自动追踪已消费的参数 key。
1525
+ *
1526
+ * @param {URLSearchParams} searchParams - React Router 的 searchParams 对象
1527
+ * @returns {{ take: (key: string) => string|null, getConsumedKeys: () => string[] }}
1528
+ *
1529
+ * @example
1530
+ * const { take, getConsumedKeys } = createUrlParamsReader(searchParams);
1531
+ * const orgId = take('tenantOrgId');
1532
+ * const orgName = take('orgName');
1533
+ * // getConsumedKeys() => ['tenantOrgId', 'orgName']
1534
+ */
1535
+ const createUrlParamsReader = searchParams => {
1536
+ const consumedKeys = [];
1537
+ const take = key => {
1538
+ if (!searchParams.has(key)) return null;
1539
+ consumedKeys.push(key);
1540
+ return searchParams.get(key);
411
1541
  };
1542
+ const getConsumedKeys = () => consumedKeys;
1543
+ return {
1544
+ take,
1545
+ getConsumedKeys
1546
+ };
1547
+ };
412
1548
 
413
- React.useEffect(function () {
414
- setValue(initCurrentValue);
415
- }, [initCurrentValue]);
416
- var ref = useSimulationBlur__default["default"](function () {
417
- setValue(initCurrentValue);
418
- setActive(false);
419
- onBlur && onBlur();
420
- });
421
- var activeChangeRef = React.useRef(onActiveChange);
422
- activeChangeRef.current = onActiveChange;
423
- React.useEffect(function () {
424
- activeChangeRef.current && activeChangeRef.current(active);
425
- }, [active]);
426
- return /*#__PURE__*/React__default["default"].createElement("div", {
427
- className: classnames__default["default"]("react-filter-search-button", {
428
- "is-active": active && !isMore
429
- }),
430
- ref: ref,
431
- onMouseEnter: function onMouseEnter() {
432
- !active && setActive(true);
433
- },
434
- onMouseLeave: function onMouseLeave() {
435
- active && initCurrentValue === value && setActive(false);
1549
+ /**
1550
+ * 从 URL 参数中移除已消费的 key,返回新的 URLSearchParams 或 null(无变化时)。
1551
+ *
1552
+ * @param {URLSearchParams} searchParams - 当前 URL 参数
1553
+ * @param {string[]} consumedKeys - 需要移除的 key 列表
1554
+ * @returns {URLSearchParams|null}
1555
+ */
1556
+ const stripConsumedUrlParams = (searchParams, consumedKeys) => {
1557
+ if (!(consumedKeys != null && consumedKeys.length)) return null;
1558
+ const next = new URLSearchParams(searchParams);
1559
+ let changed = false;
1560
+ consumedKeys.forEach(key => {
1561
+ if (next.has(key)) {
1562
+ next.delete(key);
1563
+ changed = true;
436
1564
  }
437
- }, /*#__PURE__*/React__default["default"].createElement(antd.Space, {
438
- className: "inner",
439
- size: 0
440
- }, /*#__PURE__*/React__default["default"].createElement("div", null, children({
441
- value: value,
442
- setValue: setValue,
443
- setActive: setActive
444
- })), active || isMore ? /*#__PURE__*/React__default["default"].createElement(antd.Button, {
445
- className: classnames__default["default"]("react-filter-search-confirm", {
446
- "is-more": isMore
447
- }),
448
- size: "small",
449
- type: "primary",
450
- onClick: function onClick(e) {
451
- e.stopPropagation();
452
-
453
- if (onBeforeSearch && onBeforeSearch(value) === false) {
454
- return;
455
- }
1565
+ });
1566
+ return changed ? next : null;
1567
+ };
456
1568
 
457
- onChange(name, withTemplate(value));
458
- setActive(false);
459
- onSearch && onSearch({
460
- value: value
1569
+ /**
1570
+ * 从 URL 参数初始化 Filter 状态的 hook。
1571
+ *
1572
+ * 读取 URL 参数构建初始筛选值,并在挂载后自动清除已消费的 URL 参数。
1573
+ *
1574
+ * @param {Object} options
1575
+ * @param {Function} options.readUrlParams - 读取 URL 参数并返回 { consumedKeys: string[], ...data }
1576
+ * @param {Function} options.buildFilter - 接收 readUrlParams 的返回值,构建初始 filter 数组
1577
+ * @returns {[Array, Function]} - [filter, setFilter]
1578
+ *
1579
+ * @example
1580
+ * const [filter, setFilter] = useUrlFilter({
1581
+ * readUrlParams: (searchParams) => {
1582
+ * const { take, getConsumedKeys } = createUrlParamsReader(searchParams);
1583
+ * const orgId = take('tenantOrgId');
1584
+ * return { consumedKeys: getConsumedKeys(), orgId };
1585
+ * },
1586
+ * buildFilter: ({ orgId }) => [
1587
+ * { name: 'status', value: { label: '开启', value: 'open' } },
1588
+ * ...(orgId ? [{ name: 'tenantOrgId', value: { label: orgId, value: orgId } }] : [])
1589
+ * ]
1590
+ * });
1591
+ */
1592
+ const useUrlFilter = _ref => {
1593
+ let readUrlParams = _ref.readUrlParams,
1594
+ buildFilter = _ref.buildFilter;
1595
+ const _useSearchParams = reactRouterDom.useSearchParams(),
1596
+ searchParams = _useSearchParams[0],
1597
+ setSearchParams = _useSearchParams[1];
1598
+ const urlFilterSnapshotRef = react.useRef(null);
1599
+ if (urlFilterSnapshotRef.current === null) {
1600
+ urlFilterSnapshotRef.current = readUrlParams(searchParams);
1601
+ }
1602
+ const _useState = react.useState(() => buildFilter(urlFilterSnapshotRef.current)),
1603
+ filter = _useState[0],
1604
+ setFilter = _useState[1];
1605
+ const urlStrippedRef = react.useRef(false);
1606
+ react.useEffect(() => {
1607
+ var _urlFilterSnapshotRef;
1608
+ if (urlStrippedRef.current) return;
1609
+ urlStrippedRef.current = true;
1610
+ const nextParams = stripConsumedUrlParams(searchParams, (_urlFilterSnapshotRef = urlFilterSnapshotRef.current) == null ? void 0 : _urlFilterSnapshotRef.consumedKeys);
1611
+ if (nextParams) {
1612
+ setSearchParams(nextParams, {
1613
+ replace: true
461
1614
  });
462
1615
  }
463
- }, buttonText) : null));
1616
+ }, [searchParams, setSearchParams]);
1617
+ return [filter, setFilter];
464
1618
  };
465
1619
 
466
- SearchButton.defaultProps = {
467
- defaultActive: false,
468
- buttonText: "确定"
1620
+ /**
1621
+ * 将筛选值数组序列化为 URLSearchParams,保留 label 信息以便反序列化还原完整筛选状态。
1622
+ *
1623
+ * 序列化格式(使用冒号分隔 label 和 value,逗号分隔多值):
1624
+ * - 单值且 label === value:prefix[name]=value(如输入框)
1625
+ * - 单值且 label !== value:prefix[name]=label:value
1626
+ * - 多值:prefix[name]=label1:value1,label2:value2
1627
+ *
1628
+ * @param {Array} filterValue - 筛选值数组,格式为 [{ name, label, value }, ...]
1629
+ * @param {Object} [options] - 选项
1630
+ * @param {string} [options.prefix='filterParams'] - URL 参数前缀,设为空字符串则不加前缀
1631
+ * @returns {URLSearchParams}
1632
+ *
1633
+ * @example
1634
+ * const params = filterToUrlParams([
1635
+ * { name: 'keyword', label: '关键词', value: { label: '测试', value: '测试' } },
1636
+ * { name: 'city', label: '城市', value: [{ label: '上海', value: '010' }, { label: '北京', value: '020' }] },
1637
+ * { name: 'status', label: '状态', value: { label: '启用', value: 'active' } },
1638
+ * ]);
1639
+ * // params.toString() => 'filterParams[keyword]=测试&filterParams[city]=上海:010,北京:020&filterParams[status]=启用:active'
1640
+ *
1641
+ * // 自定义前缀
1642
+ * filterToUrlParams(filterValue, { prefix: 'f' })
1643
+ * // => 'f[keyword]=测试&f[city]=上海:010,北京:020'
1644
+ *
1645
+ * // 无前缀(直接平铺)
1646
+ * filterToUrlParams(filterValue, { prefix: '' })
1647
+ * // => 'keyword=测试&city=上海:010,北京:020'
1648
+ */
1649
+ const filterToUrlParams = function (filterValue, _temp) {
1650
+ let _ref = _temp === void 0 ? {} : _temp,
1651
+ _ref$prefix = _ref.prefix,
1652
+ prefix = _ref$prefix === void 0 ? 'filterParams' : _ref$prefix;
1653
+ const params = new URLSearchParams();
1654
+ if (!Array.isArray(filterValue)) return params;
1655
+ filterValue.forEach(_ref2 => {
1656
+ let name = _ref2.name,
1657
+ value = _ref2.value;
1658
+ if (value == null || value === '') return;
1659
+ const key = prefix ? prefix + "[" + name + "]" : name;
1660
+ if (Array.isArray(value)) {
1661
+ if (value.length === 0) return;
1662
+ const serialized = value.map(item => serializeEntry(item)).filter(Boolean).join(',');
1663
+ if (serialized) params.set(key, serialized);
1664
+ } else {
1665
+ const serialized = serializeEntry(value);
1666
+ if (serialized) params.set(key, serialized);
1667
+ }
1668
+ });
1669
+ return params;
469
1670
  };
470
1671
 
471
- var RangeInner = function RangeInner(_ref) {
472
- var name = _ref.name,
473
- isMore = _ref.isMore,
474
- defaultActive = _ref.defaultActive,
475
- template = _ref.template,
476
- onBlur = _ref.onBlur,
477
- onSearch = _ref.onSearch,
478
- _onActiveChange = _ref.onActiveChange,
479
- onBeforeSearch = _ref.onBeforeSearch,
480
- startProps = _ref.startProps,
481
- endProps = _ref.endProps,
482
- placeholder = _ref.placeholder;
483
-
484
- var _useState = React.useState(null),
485
- error = _useState[0],
486
- setError = _useState[1];
1672
+ /**
1673
+ * 序列化单个筛选值项。
1674
+ * - label === value 时返回 value(简化格式)
1675
+ * - 否则返回 label:value
1676
+ */
1677
+ const serializeEntry = item => {
1678
+ var _item$label, _item$value;
1679
+ if (item == null) return null;
1680
+ if (typeof item !== 'object') return String(item);
1681
+ const label = (_item$label = item.label) != null ? _item$label : item.name;
1682
+ const value = (_item$value = item.value) != null ? _item$value : item.id;
1683
+ if (value == null || value === '') return null;
1684
+ if (label === value) return String(value);
1685
+ return label + ":" + value;
1686
+ };
487
1687
 
488
- var check = function check(value) {
489
- setError(null);
1688
+ /**
1689
+ * 解析 URL 参数中的单个筛选值项,反序列化为 { label, value } 对象。
1690
+ * 与 filterToUrlParams 配合使用。
1691
+ *
1692
+ * 解析规则:
1693
+ * - 无冒号:label 和 value 相同,如 "测试" → { label: '测试', value: '测试' }
1694
+ * - 有冒号:冒号前为 label,冒号后为 value,如 "启用:active" → { label: '启用', value: 'active' }
1695
+ *
1696
+ * @param {string} str - URL 参数中的原始字符串
1697
+ * @returns {{ label: string, value: string }}
1698
+ *
1699
+ * @example
1700
+ * parseFilterEntry('测试')
1701
+ * // => { label: '测试', value: '测试' }
1702
+ *
1703
+ * parseFilterEntry('启用:active')
1704
+ * // => { label: '启用', value: 'active' }
1705
+ */
1706
+ const parseFilterEntry = str => {
1707
+ const colonIndex = str.indexOf(':');
1708
+ if (colonIndex === -1) {
1709
+ return {
1710
+ label: str,
1711
+ value: str
1712
+ };
1713
+ }
1714
+ return {
1715
+ label: str.slice(0, colonIndex),
1716
+ value: str.slice(colonIndex + 1)
1717
+ };
1718
+ };
490
1719
 
491
- if (!Array.isArray(value)) {
492
- return false;
493
- }
1720
+ /**
1721
+ * 从 URL 参数中读取筛选值项,返回单选 { label, value } 或多选数组。
1722
+ *
1723
+ * @param {URLSearchParams} searchParams - URL 参数对象
1724
+ * @param {string} key - 参数名(不含前缀)
1725
+ * @param {Object} [options] - 选项
1726
+ * @param {boolean} [options.multi=false] - 是否多选,多选返回数组
1727
+ * @param {string} [options.prefix='filterParams'] - URL 参数前缀,设为空字符串则不加前缀
1728
+ * @returns {{ label: string, value: string } | { label: string, value: string }[] | null}
1729
+ *
1730
+ * @example
1731
+ * // URL: ?filterParams[city]=上海:010,北京:020&filterParams[status]=启用:active
1732
+ * takeFilterEntry(searchParams, 'city', { multi: true })
1733
+ * // => [{ label: '上海', value: '010' }, { label: '北京', value: '020' }]
1734
+ *
1735
+ * // 无前缀
1736
+ * takeFilterEntry(searchParams, 'keyword', { prefix: '' })
1737
+ * // => { label: '测试', value: '测试' }
1738
+ */
1739
+ const takeFilterEntry = function (searchParams, key, _temp2) {
1740
+ let _ref3 = _temp2 === void 0 ? {} : _temp2,
1741
+ _ref3$multi = _ref3.multi,
1742
+ multi = _ref3$multi === void 0 ? false : _ref3$multi,
1743
+ _ref3$prefix = _ref3.prefix,
1744
+ prefix = _ref3$prefix === void 0 ? 'filterParams' : _ref3$prefix;
1745
+ const fullKey = prefix ? prefix + "[" + key + "]" : key;
1746
+ if (!searchParams.has(fullKey)) return null;
1747
+ const raw = searchParams.get(fullKey);
1748
+ if (!raw) return null;
1749
+ if (multi) {
1750
+ return raw.split(',').map(parseFilterEntry);
1751
+ }
494
1752
 
495
- if (lodash.isNumber(value[1]) && value[0] > value[1]) {
496
- setError("最大值不能小于最小值");
497
- return false;
498
- }
1753
+ // 单选时,如果包含逗号,只取第一个
1754
+ const firstEntry = raw.includes(',') ? raw.split(',')[0] : raw;
1755
+ return parseFilterEntry(firstEntry);
1756
+ };
499
1757
 
500
- if (onBeforeSearch) {
501
- return onBeforeSearch(value);
1758
+ /**
1759
+ * 创建 URL 筛选参数读取器,自动追踪已消费的参数 key。
1760
+ * 配合 useUrlFilter 使用,readUrlParams 返回的 consumedKeys 可被自动清除。
1761
+ *
1762
+ * @param {URLSearchParams} searchParams - React Router 的 searchParams 对象
1763
+ * @param {Object} [options] - 选项
1764
+ * @param {string} [options.prefix='filterParams'] - URL 参数前缀
1765
+ * @returns {{ takeFilterEntry, getConsumedKeys }}
1766
+ *
1767
+ * @example
1768
+ * const { takeFilterEntry, getConsumedKeys } = createUrlFilterReader(searchParams);
1769
+ * const keyword = takeFilterEntry('keyword');
1770
+ * const city = takeFilterEntry('city', { multi: true });
1771
+ * const status = takeFilterEntry('status');
1772
+ * // getConsumedKeys() => ['filterParams[keyword]', 'filterParams[city]', 'filterParams[status]']
1773
+ *
1774
+ * // 配合 useUrlFilter 使用
1775
+ * const [filter, setFilter] = useUrlFilter({
1776
+ * readUrlParams: (searchParams) => {
1777
+ * const { takeFilterEntry, getConsumedKeys } = createUrlFilterReader(searchParams);
1778
+ * const keyword = takeFilterEntry('keyword');
1779
+ * const city = takeFilterEntry('city', { multi: true });
1780
+ * return { consumedKeys: getConsumedKeys(), keyword, city };
1781
+ * },
1782
+ * buildFilter: ({ keyword, city }) => [
1783
+ * ...(keyword ? [{ name: 'keyword', label: '关键词', value: keyword }] : []),
1784
+ * ...(city ? [{ name: 'city', label: '城市', value: city }] : []),
1785
+ * ],
1786
+ * });
1787
+ */
1788
+ const createUrlFilterReader = function (searchParams, _temp3) {
1789
+ let _ref4 = _temp3 === void 0 ? {} : _temp3,
1790
+ _ref4$prefix = _ref4.prefix,
1791
+ prefix = _ref4$prefix === void 0 ? 'filterParams' : _ref4$prefix;
1792
+ const consumedKeys = [];
1793
+ const takeFilterEntry = function (key, _temp4) {
1794
+ let _ref5 = _temp4 === void 0 ? {} : _temp4,
1795
+ _ref5$multi = _ref5.multi,
1796
+ multi = _ref5$multi === void 0 ? false : _ref5$multi;
1797
+ const fullKey = prefix ? prefix + "[" + key + "]" : key;
1798
+ if (!searchParams.has(fullKey)) return null;
1799
+ consumedKeys.push(fullKey);
1800
+ const raw = searchParams.get(fullKey);
1801
+ if (!raw) return null;
1802
+ if (multi) {
1803
+ return raw.split(',').map(parseFilterEntry);
502
1804
  }
503
-
504
- return true;
1805
+ const firstEntry = raw.includes(',') ? raw.split(',')[0] : raw;
1806
+ return parseFilterEntry(firstEntry);
505
1807
  };
1808
+ const getConsumedKeys = () => consumedKeys;
1809
+ return {
1810
+ takeFilterEntry,
1811
+ getConsumedKeys
1812
+ };
1813
+ };
506
1814
 
507
- return /*#__PURE__*/React__default["default"].createElement(SearchButton, {
508
- template: template,
509
- isMore: isMore,
510
- onBlur: onBlur,
511
- defaultActive: defaultActive,
512
- name: name,
513
- onSearch: onSearch,
514
- onBeforeSearch: function onBeforeSearch(value) {
515
- return check(value);
1815
+ const _excluded$1 = ["consumedKeys"];
1816
+
1817
+ /**
1818
+ * 从 URL 参数初始化 Filter 状态的 hook(简化版)。
1819
+ *
1820
+ * 基于 useUrlFilter 封装,使用 createUrlFilterReader 解析 filterParams[key] 格式的 URL 参数,
1821
+ * 自动解析 label:value 格式,支持单选和多选。
1822
+ *
1823
+ * @param {string[]|Object} mapping - URL 参数映射
1824
+ * - 数组: ['tenantOrgId', 'orgName'],默认单选,自动创建 { name: key, value: { label, value } }
1825
+ * - 对象:
1826
+ * - 值为 true: 单选,使用默认转换 { name: key, value: { label, value } }
1827
+ * - 值为 { multi: true }: 多选,value 为 [{ label, value }, ...] 数组
1828
+ * - 值为函数: 自定义转换,接收解析后的值(单选为 { label, value },多选为数组),返回 filter 项或 null/falsy 跳过
1829
+ * @returns {[Array, Function]} - [filter, setFilter]
1830
+ *
1831
+ * @example
1832
+ * // 数组形式(默认单选)
1833
+ * const [filter, setFilter] = useUrlFilterValue(['keyword', 'status']);
1834
+ * // URL: ?filterParams[keyword]=前端开发&filterParams[status]=招聘中:active
1835
+ * // → filter: [
1836
+ * // { name: 'keyword', value: { label: '前端开发', value: '前端开发' } },
1837
+ * // { name: 'status', value: { label: '招聘中', value: 'active' } }
1838
+ * // ]
1839
+ *
1840
+ * @example
1841
+ * // 对象形式(多选 + 自定义)
1842
+ * const [filter, setFilter] = useUrlFilterValue({
1843
+ * keyword: true,
1844
+ * city: { multi: true },
1845
+ * status: (parsed) => parsed ? { name: 'status', value: parsed } : null
1846
+ * });
1847
+ * // URL: ?filterParams[keyword]=测试&filterParams[city]=上海:010,北京:020
1848
+ * // → keyword: { label: '测试', value: '测试' }
1849
+ * // → city: [{ label: '上海', value: '010' }, { label: '北京', value: '020' }]
1850
+ */
1851
+ const useUrlFilterValue = mapping => {
1852
+ const normalizedMapping = Array.isArray(mapping) ? mapping.reduce((acc, item) => {
1853
+ const key = typeof item === 'string' ? item : item.name;
1854
+ acc[key] = typeof item === 'string' ? true : item;
1855
+ return acc;
1856
+ }, {}) : mapping;
1857
+ return useUrlFilter({
1858
+ readUrlParams: searchParams => {
1859
+ const _createUrlFilterReade = createUrlFilterReader(searchParams),
1860
+ takeFilterEntry = _createUrlFilterReade.takeFilterEntry,
1861
+ getConsumedKeys = _createUrlFilterReade.getConsumedKeys;
1862
+ const data = {};
1863
+ Object.entries(normalizedMapping).forEach(_ref => {
1864
+ let key = _ref[0],
1865
+ config = _ref[1];
1866
+ const multi = typeof config === 'object' && config !== null && config.multi;
1867
+ const val = takeFilterEntry(key, {
1868
+ multi
1869
+ });
1870
+ if (val !== null) data[key] = val;
1871
+ });
1872
+ return _extends({
1873
+ consumedKeys: getConsumedKeys()
1874
+ }, data);
516
1875
  },
517
- onActiveChange: function onActiveChange(active) {
518
- if (!active) {
519
- setError(null);
520
- }
521
-
522
- _onActiveChange && _onActiveChange(active);
1876
+ buildFilter: data => {
1877
+ const values = _objectWithoutPropertiesLoose(data, _excluded$1);
1878
+ const filters = [];
1879
+ Object.entries(normalizedMapping).forEach(_ref2 => {
1880
+ let key = _ref2[0],
1881
+ config = _ref2[1];
1882
+ if (values[key] === undefined) return;
1883
+ const parsedValue = values[key];
1884
+ if (typeof config === 'function') {
1885
+ const result = config(parsedValue);
1886
+ if (result) filters.push(result);
1887
+ } else {
1888
+ const label = typeof config === 'object' && config !== null ? config.label : key;
1889
+ filters.push({
1890
+ name: key,
1891
+ label,
1892
+ value: parsedValue
1893
+ });
1894
+ }
1895
+ });
1896
+ return filters;
523
1897
  }
524
- }, function (_ref2) {
525
- var value = _ref2.value,
526
- setValue = _ref2.setValue,
527
- setActive = _ref2.setActive;
528
- return /*#__PURE__*/React__default["default"].createElement(antd.Tooltip, {
529
- visible: !!error,
530
- title: error,
531
- placement: "bottomRight"
532
- }, /*#__PURE__*/React__default["default"].createElement(antd.Space, {
533
- size: "small",
534
- className: "react-filter-range"
535
- }, /*#__PURE__*/React__default["default"].createElement(antd.InputNumber, _extends({
536
- size: "small"
537
- }, startProps, {
538
- value: lodash.get(value, 0),
539
- onChange: function onChange(inputValue) {
540
- var target = [inputValue, lodash.get(value, 1)];
541
- check(target);
542
- setValue(target);
543
- },
544
- onFocus: function onFocus() {
545
- setActive(true);
546
- },
547
- placeholder: Array.isArray(placeholder) ? placeholder[0] : placeholder || "请输入"
548
- })), "~", /*#__PURE__*/React__default["default"].createElement(antd.InputNumber, _extends({
549
- size: "small"
550
- }, endProps, {
551
- value: lodash.get(value, 1),
552
- onChange: function onChange(inputValue) {
553
- var target = [lodash.get(value, 0), inputValue];
554
- check(target);
555
- setValue(target);
556
- },
557
- onFocus: function onFocus() {
558
- setActive(true);
559
- },
560
- placeholder: Array.isArray(placeholder) ? placeholder[0] : placeholder || "请输入"
561
- }))));
562
1898
  });
563
1899
  };
564
- var Range = withFilterItem(RangeInner);
565
-
566
- var _excluded$6 = ["name", "label", "isMore", "template", "defaultActive", "onBlur", "onSearch", "onBeforeSearch", "onActiveChange", "placeholder"];
567
1900
 
568
- var withValue$1 = function withValue(WrappedComponent, options) {
569
- if (options === void 0) {
570
- options = {};
1901
+ const toIdName = item => {
1902
+ if (!item) {
1903
+ return null;
571
1904
  }
572
-
573
- return function (_ref) {
574
- var name = _ref.name,
575
- label = _ref.label,
576
- isMore = _ref.isMore,
577
- template = _ref.template,
578
- defaultActive = _ref.defaultActive,
579
- onBlur = _ref.onBlur,
580
- onSearch = _ref.onSearch,
581
- onBeforeSearch = _ref.onBeforeSearch,
582
- _onActiveChange = _ref.onActiveChange,
583
- placeholder = _ref.placeholder,
584
- props = _objectWithoutPropertiesLoose(_ref, _excluded$6);
585
-
586
- return /*#__PURE__*/React__default["default"].createElement(SearchButton, {
587
- defaultActive: defaultActive,
588
- isMore: isMore,
589
- onBlur: onBlur,
590
- template: template,
591
- name: name,
592
- onSearch: onSearch,
593
- onBeforeSearch: onBeforeSearch,
594
- onActiveChange: function onActiveChange(active) {
595
- _onActiveChange && _onActiveChange(active);
596
- }
597
- }, function (_ref2) {
598
- var value = _ref2.value,
599
- setValue = _ref2.setValue,
600
- setActive = _ref2.setActive;
601
- return /*#__PURE__*/React__default["default"].createElement(React__default["default"].Fragment, null, /*#__PURE__*/React__default["default"].createElement(WrappedComponent, _extends({
602
- size: "small"
603
- }, props, {
604
- placeholder: placeholder || label,
605
- value: value,
606
- onChange: function onChange(e) {
607
- setValue(options.getValue ? options.getValue(e) : e.target.value);
608
- },
609
- onFocus: function onFocus() {
610
- setActive(true);
611
- }
612
- })));
613
- });
614
- };
1905
+ if (item.id != null) {
1906
+ return item;
1907
+ }
1908
+ if (item.value != null) {
1909
+ return {
1910
+ id: item.value,
1911
+ name: item.label
1912
+ };
1913
+ }
1914
+ return item;
615
1915
  };
616
-
617
- var TextInner = withValue$1(antd.Input);
618
- var Text = withFilterItem(withValue$1(antd.Input));
619
- Text.Number = withFilterItem(withValue$1(antd.InputNumber, {
620
- getValue: function getValue(value) {
621
- return value;
1916
+ const toLabelValue = item => {
1917
+ var _item$name, _item$id;
1918
+ if (!item) {
1919
+ return null;
622
1920
  }
623
- }));
1921
+ return {
1922
+ label: (_item$name = item.name) != null ? _item$name : item.label,
1923
+ value: (_item$id = item.id) != null ? _item$id : item.value
1924
+ };
1925
+ };
624
1926
 
625
- var _excluded$5 = ["name", "label", "placeholder", "isMore"];
626
- var SelectorInner = function SelectorInner(_ref) {
627
- var name = _ref.name,
628
- label = _ref.label,
629
- placeholder = _ref.placeholder,
630
- props = _objectWithoutPropertiesLoose(_ref, _excluded$5);
631
-
632
- var _useConsumer = useConsumer(),
633
- aValue = _useConsumer.value,
634
- _onChange = _useConsumer.onChange;
635
-
636
- var currentValue = aValue[name];
637
- return /*#__PURE__*/React__default["default"].createElement(antd.Select, _extends({}, props, {
638
- placeholder: label || placeholder,
639
- size: "small",
640
- value: currentValue,
641
- onChange: function onChange(value, item) {
642
- _onChange(name, item);
1927
+ /**
1928
+ * 单选 SuperSelect interceptor:{id, name} ↔ {label, value}
1929
+ * 适用于 valueKey="id" labelKey="name" 的单选场景
1930
+ */
1931
+ const singleSelectInterceptor = {
1932
+ input: value => {
1933
+ if (!value) {
1934
+ return value;
643
1935
  }
644
- }));
1936
+ const item = Array.isArray(value) ? value[0] : value;
1937
+ const result = toIdName(item);
1938
+ return result;
1939
+ },
1940
+ output: selected => {
1941
+ if (!selected) {
1942
+ return selected;
1943
+ }
1944
+ const item = Array.isArray(selected) ? selected[0] : selected;
1945
+ return toLabelValue(item);
1946
+ }
645
1947
  };
646
- var Selector = withFilterItem(SelectorInner);
647
-
648
- var _excluded$4 = ["name", "label", "className", "isMore"];
649
1948
 
650
- var Check = function Check(_ref) {
651
- var name = _ref.name,
652
- label = _ref.label,
653
- className = _ref.className,
654
- props = _objectWithoutPropertiesLoose(_ref, _excluded$4);
655
-
656
- var _useConsumer = useConsumer(),
657
- aValue = _useConsumer.value,
658
- _onChange = _useConsumer.onChange;
659
-
660
- var currentValue = aValue[name];
661
- return /*#__PURE__*/React__default["default"].createElement(antd.Checkbox, _extends({}, props, {
662
- className: classnames__default["default"]('react-filter-item', className),
663
- size: "small",
664
- checked: currentValue,
665
- onChange: function onChange(e) {
666
- _onChange(name, e.target.checked ? {
667
- value: true,
668
- label: label
669
- } : null);
1949
+ /**
1950
+ * 多选 SuperSelect interceptor:[{id, name}] [{label, value}]
1951
+ * 适用于 valueKey="id" labelKey="name" 的多选场景
1952
+ */
1953
+ const multiSelectInterceptor = {
1954
+ input: value => {
1955
+ if (!value) {
1956
+ return value;
670
1957
  }
671
- }), label);
1958
+ const list = Array.isArray(value) ? value : [value];
1959
+ return list.map(toIdName).filter(Boolean);
1960
+ },
1961
+ output: selected => {
1962
+ if (!selected) {
1963
+ return selected;
1964
+ }
1965
+ const list = Array.isArray(selected) ? selected : [selected];
1966
+ return list.map(toLabelValue).filter(Boolean);
1967
+ }
1968
+ };
1969
+ var filterInterceptors = {
1970
+ single: singleSelectInterceptor,
1971
+ multi: multiSelectInterceptor
672
1972
  };
673
1973
 
674
- var _excluded$3 = ["label", "name", "options", "isMore"];
675
- var RadioList = withFilterItem(function (_ref) {
676
- var name = _ref.name,
677
- options = _ref.options,
678
- props = _objectWithoutPropertiesLoose(_ref, _excluded$3);
679
-
680
- var _useConsumer = useConsumer(),
681
- aValue = _useConsumer.value,
682
- _onChange = _useConsumer.onChange;
683
-
684
- var currentValue = aValue[name];
685
- return /*#__PURE__*/React__default["default"].createElement(antd.Radio.Group, _extends({}, props, {
686
- options: options,
687
- value: lodash.get(currentValue, 'value'),
688
- onChange: function onChange(e) {
689
- var item = options.find(function (item) {
690
- return item.value === e.target.value;
691
- });
692
-
693
- _onChange(name, item);
1974
+ const InputFilterItem = withLocale(({
1975
+ value,
1976
+ label,
1977
+ onChange,
1978
+ ...props
1979
+ }) => {
1980
+ const propsValue = value?.value;
1981
+ const [inputValue, setInputValue] = react.useState(propsValue || '');
1982
+ const [active, setActive] = react.useState(false);
1983
+ const {
1984
+ formatMessage
1985
+ } = reactIntl.useIntl({
1986
+ moduleName: 'Filter'
1987
+ });
1988
+ const searchHandler = () => {
1989
+ onChange(inputValue ? {
1990
+ label: inputValue,
1991
+ value: inputValue
1992
+ } : null);
1993
+ };
1994
+ const handleBlur = () => {
1995
+ setActive(false);
1996
+ searchHandler();
1997
+ };
1998
+ const inputValueRef = react.useRef('');
1999
+ inputValueRef.current = inputValue;
2000
+ react.useEffect(() => {
2001
+ if (propsValue !== inputValueRef.current) {
2002
+ setInputValue(propsValue);
694
2003
  }
695
- }));
2004
+ }, [propsValue]);
2005
+ return /*#__PURE__*/jsxRuntime.jsxs(antd.Space.Compact, {
2006
+ children: [/*#__PURE__*/jsxRuntime.jsx(antd.Input, {
2007
+ placeholder: `${formatMessage({
2008
+ id: 'pleaseInput'
2009
+ })}${label}`,
2010
+ ...props,
2011
+ size: "small",
2012
+ value: inputValue,
2013
+ onFocus: () => {
2014
+ setActive(true);
2015
+ },
2016
+ onBlur: handleBlur,
2017
+ onChange: e => {
2018
+ setInputValue(e.target.value);
2019
+ },
2020
+ onPressEnter: searchHandler
2021
+ }), active && /*#__PURE__*/jsxRuntime.jsx(antd.Button, {
2022
+ size: "small",
2023
+ type: "primary",
2024
+ onClick: searchHandler,
2025
+ children: formatMessage({
2026
+ id: 'determineText'
2027
+ })
2028
+ })]
2029
+ });
696
2030
  });
697
2031
 
698
- var _excluded$2 = ["label", "name", "options", "isMore"];
699
- var CheckboxList = withFilterItem(function (_ref) {
700
- var name = _ref.name,
701
- options = _ref.options,
702
- props = _objectWithoutPropertiesLoose(_ref, _excluded$2);
703
-
704
- var _useConsumer = useConsumer(),
705
- aValue = _useConsumer.value,
706
- _onChange = _useConsumer.onChange;
707
-
708
- var currentValue = aValue[name];
709
- return /*#__PURE__*/React__default["default"].createElement(antd.Checkbox.Group, _extends({}, props, {
710
- value: (currentValue || []).map(function (_ref2) {
711
- var value = _ref2.value;
712
- return value;
713
- }),
714
- onChange: function onChange(value) {
715
- var item = value.map(function (value) {
716
- return options.find(function (item) {
717
- return item.value === value;
718
- });
719
- });
720
- console.log(item);
721
-
722
- _onChange(name, item);
723
- },
724
- options: options
725
- }));
2032
+ const {
2033
+ CheckableTag: CheckableTag$1
2034
+ } = antd.Tag;
2035
+ const ListFilterItem = withLocale(({
2036
+ value,
2037
+ onChange,
2038
+ label,
2039
+ single = false,
2040
+ maxLength = 5,
2041
+ items = []
2042
+ }) => {
2043
+ const {
2044
+ message
2045
+ } = antd.App.useApp();
2046
+ const {
2047
+ formatMessage
2048
+ } = reactIntl.useIntl({
2049
+ moduleName: 'Filter'
2050
+ });
2051
+ return /*#__PURE__*/jsxRuntime.jsx(antd.Space, {
2052
+ size: 4,
2053
+ wrap: true,
2054
+ block: true,
2055
+ children: items.map(({
2056
+ label: itemLabel,
2057
+ value: itemValue
2058
+ }) => {
2059
+ return /*#__PURE__*/jsxRuntime.jsx(CheckableTag$1, {
2060
+ size: "small",
2061
+ checked: single ? isEqual__default["default"](itemValue, value?.value) : !!(value || []).find(({
2062
+ value
2063
+ }) => isEqual__default["default"](itemValue, value)),
2064
+ onChange: checked => {
2065
+ if (single) {
2066
+ onChange(checked ? {
2067
+ value: itemValue,
2068
+ label: itemLabel
2069
+ } : null);
2070
+ return;
2071
+ }
2072
+ const newValue = (value || []).slice(0);
2073
+ if (checked) {
2074
+ newValue.push({
2075
+ value: itemValue,
2076
+ label: itemLabel
2077
+ });
2078
+ } else {
2079
+ const index = newValue.findIndex(({
2080
+ value
2081
+ }) => isEqual__default["default"](itemValue, value));
2082
+ if (index > -1) {
2083
+ newValue.splice(index, 1);
2084
+ }
2085
+ }
2086
+ if (newValue.length > maxLength) {
2087
+ message.error(formatMessage({
2088
+ id: 'maxSelectedCount'
2089
+ }, {
2090
+ count: maxLength
2091
+ }));
2092
+ return;
2093
+ }
2094
+ onChange(newValue);
2095
+ },
2096
+ children: itemLabel
2097
+ }, itemLabel);
2098
+ })
2099
+ });
726
2100
  });
727
2101
 
728
- var _excluded$1 = ["name", "label", "placeholder", "template", "isMore"];
729
-
730
- var withValue = function withValue(WrappedComponent, options) {
731
- if (options === void 0) {
732
- options = {};
2102
+ const {
2103
+ CheckableTag
2104
+ } = antd.Tag;
2105
+ const getLabelForLocal = (item, locale) => {
2106
+ if (locale === 'en-US') {
2107
+ return item?.enName || item?.name;
733
2108
  }
734
-
735
- return function (_ref) {
736
- var name = _ref.name,
737
- label = _ref.label,
738
- placeholder = _ref.placeholder,
739
- template = _ref.template,
740
- props = _objectWithoutPropertiesLoose(_ref, _excluded$1);
741
-
742
- var _useConsumer = useConsumer(),
743
- aValue = _useConsumer.value,
744
- _onChange = _useConsumer.onChange;
745
-
746
- var currentValue = aValue[name];
747
- return /*#__PURE__*/React__default["default"].createElement(WrappedComponent, _extends({}, props, {
748
- placeholder: options.range ? placeholder || [label, label] : placeholder || label,
749
- size: "small",
750
- value: currentValue && moment__default["default"](currentValue),
751
- onChange: function onChange(value, item) {
752
- _onChange(name, {
753
- label: lodash.isFunction(template) ? template(item) : options.range ? item.join('~') : item,
754
- value: item
755
- });
756
- }
757
- }));
758
- };
2109
+ return item?.name;
759
2110
  };
760
-
761
- var DateTime = withFilterItem(withValue(antd.DatePicker));
762
- DateTime.Month = withFilterItem(withValue(antd.DatePicker.MonthPicker));
763
- DateTime.Week = withFilterItem(withValue(antd.DatePicker.WeekPicker));
764
- DateTime.Time = withFilterItem(withValue(antd.DatePicker.TimePicker));
765
- DateTime.YearPicker = withFilterItem(withValue(antd.DatePicker.YearPicker));
766
- DateTime.Range = withFilterItem(withValue(antd.DatePicker.RangePicker, {
767
- range: true
768
- }));
769
-
770
- var filterNull = function filterNull(item) {
771
- var target = Object.assign({}, item);
772
- Object.keys(target).forEach(function (key) {
773
- var item = target[key];
774
-
775
- (function () {
776
- if (Array.isArray(item) && item.length > 0 && item.every(function (item) {
777
- return item.value === void 0 || item.value === null || item.value === "";
778
- })) {
779
- delete target[key];
780
- return;
781
- }
782
-
783
- if (Array.isArray(item) && item.length === 0) {
784
- delete target[key];
785
- return;
786
- }
787
-
788
- if (item && Array.isArray(item.value) && (item.value.length === 0 || item.value.every(function (item) {
789
- return item === void 0 || item === null || item === "";
790
- }))) {
791
- delete target[key];
792
- return;
793
- }
794
-
795
- if (item === void 0 || item === null || !Array.isArray(item) && item && (item.value === void 0 || item.value === null || item.value === "")) {
796
- delete target[key];
797
- return;
2111
+ const CityFilterItemInner = ({
2112
+ value,
2113
+ onChange,
2114
+ single = false,
2115
+ maxLength = 5,
2116
+ ...props
2117
+ }) => {
2118
+ const {
2119
+ message
2120
+ } = antd.App.useApp();
2121
+ const {
2122
+ locale
2123
+ } = reactIntl.useIntl();
2124
+ const {
2125
+ formatMessage
2126
+ } = reactIntl.useIntl({
2127
+ moduleName: 'Filter'
2128
+ });
2129
+ const [addressApi, setAddressApi] = react.useState(null);
2130
+ react.useEffect(() => {
2131
+ let cancelled = false;
2132
+ superSelectPlus.SelectAddress.defaultData().then(data => {
2133
+ if (!cancelled && data) {
2134
+ setAddressApi(superSelectPlus.createAddressApi(data));
798
2135
  }
799
- })();
2136
+ });
2137
+ return () => {
2138
+ cancelled = true;
2139
+ };
2140
+ }, []);
2141
+ const cityList = react.useMemo(() => {
2142
+ return addressApi ? addressApi.getChinaHotCities() : [];
2143
+ }, [addressApi]);
2144
+ return /*#__PURE__*/jsxRuntime.jsxs(antd.Space, {
2145
+ size: 4,
2146
+ wrap: true,
2147
+ block: true,
2148
+ children: [cityList.map(city => {
2149
+ const label = getLabelForLocal(city, locale);
2150
+ return /*#__PURE__*/jsxRuntime.jsx(CheckableTag, {
2151
+ size: "small",
2152
+ checked: single ? value?.value === city.code : !!(value || []).find(({
2153
+ value
2154
+ }) => value === city.code),
2155
+ onChange: checked => {
2156
+ if (single) {
2157
+ onChange(checked ? city : null);
2158
+ return;
2159
+ }
2160
+ const newValue = (value || []).slice(0);
2161
+ checked ? newValue.push(Object.assign({}, city, {
2162
+ label,
2163
+ value: city.code
2164
+ })) : (() => {
2165
+ const index = newValue.findIndex(({
2166
+ value
2167
+ }) => value === city.code);
2168
+ newValue.splice(index, 1);
2169
+ })();
2170
+ if (newValue.length > maxLength) {
2171
+ message.error(formatMessage({
2172
+ id: 'maxSelectedCount'
2173
+ }, {
2174
+ count: maxLength
2175
+ }));
2176
+ return;
2177
+ }
2178
+ onChange(newValue);
2179
+ },
2180
+ children: label
2181
+ }, city.code);
2182
+ }), /*#__PURE__*/jsxRuntime.jsxs(CheckableTag, {
2183
+ className: style$1['filter-advanced-item-other'],
2184
+ size: "small",
2185
+ checked: (single ? value?.value : value?.length > 0) && !cityList.find(({
2186
+ code
2187
+ }) => single ? value?.value === code : !!(value || []).find(({
2188
+ value
2189
+ }) => value === code)),
2190
+ children: [formatMessage({
2191
+ id: 'otherText'
2192
+ }), /*#__PURE__*/jsxRuntime.jsx(superSelectPlus.SelectAddress, {
2193
+ ...props,
2194
+ className: style$1['filter-advanced-item-other-inner'],
2195
+ maxLength: maxLength,
2196
+ allowClear: false,
2197
+ value: value,
2198
+ single: single,
2199
+ onChange: value => {
2200
+ if (value.length > maxLength) {
2201
+ message.error(formatMessage({
2202
+ id: 'maxSelectedCount'
2203
+ }, {
2204
+ count: maxLength
2205
+ }));
2206
+ return;
2207
+ }
2208
+ onChange(value);
2209
+ }
2210
+ })]
2211
+ })]
800
2212
  });
801
- return target;
802
2213
  };
2214
+ const CityFilterItem = withLocale(CityFilterItemInner);
803
2215
 
804
- var Filter = function Filter(_ref) {
805
- var displayLine = _ref.displayLine,
806
- defaultDisplay = _ref.defaultDisplay,
807
- isExtra = _ref.isExtra,
808
- list = _ref.list,
809
- label = _ref.label,
810
- labelHidden = _ref.labelHidden,
811
- itemLabelHidden = _ref.itemLabelHidden,
812
- unfoldText = _ref.unfoldText,
813
- foldText = _ref.foldText,
814
- extra = _ref.extra,
815
- more = _ref.more,
816
- moreTrigger = _ref.moreTrigger,
817
- moreLabel = _ref.moreLabel,
818
- originValue = _ref.value,
819
- onChange = _ref.onChange;
820
- var value = React.useMemo(function () {
821
- return filterNull(originValue);
822
- }, [originValue]);
823
- var emitter = useEvent__default["default"]();
824
-
825
- var _useState = React.useState(defaultDisplay),
826
- display = _useState[0],
827
- setDisplay = _useState[1];
828
-
829
- var basicList = list.slice(0, displayLine),
830
- moreList = list.slice(displayLine);
831
-
832
- var renderList = function renderList(list) {
833
- return list.map(function (item, index) {
834
- return /*#__PURE__*/React__default["default"].createElement(antd.Space, {
835
- key: index,
836
- className: "react-filter-line"
837
- }, item.map(function (item, index) {
838
- return React.cloneElement(item, {
839
- key: index,
840
- labelHidden: itemLabelHidden
841
- });
842
- }));
843
- });
844
- };
845
-
846
- var changeHandler = function changeHandler(name, item) {
847
- var _Object$assign;
848
-
849
- var target = Object.assign({}, value, (_Object$assign = {}, _Object$assign[name] = item, _Object$assign));
850
- var output = filterNull(target);
851
- emitter.emit('change', output);
852
- onChange(output);
853
- };
2216
+ const fields = {
2217
+ InputFilterItem,
2218
+ ListFilterItem,
2219
+ CityFilterItem
2220
+ };
854
2221
 
855
- var moreFilter = more && more.length > 0 ? /*#__PURE__*/React__default["default"].createElement(antd.Space, {
856
- className: "react-filter-line is-more"
857
- }, /*#__PURE__*/React__default["default"].createElement(antd.Space, {
858
- className: "react-filter-item"
859
- }, /*#__PURE__*/React__default["default"].createElement("div", {
860
- className: "react-filter-item-label"
861
- }, moreLabel, ":"), /*#__PURE__*/React__default["default"].createElement(antd.Space, {
862
- className: "react-filter-item-children",
863
- split: /*#__PURE__*/React__default["default"].createElement(antd.Divider, {
864
- type: "vertical"
2222
+ const Line = _ref => {
2223
+ let list = _ref.list;
2224
+ const _useContext = useContext(),
2225
+ value = _useContext.value,
2226
+ onChange = _useContext.onChange;
2227
+ return /*#__PURE__*/jsxRuntime.jsx(antd.Flex, {
2228
+ gap: 8,
2229
+ children: list.map((item, index) => {
2230
+ const ComponentItem = item.type;
2231
+ return /*#__PURE__*/jsxRuntime.jsxs(antd.Flex, {
2232
+ gap: 16,
2233
+ align: "center",
2234
+ children: [/*#__PURE__*/jsxRuntime.jsxs("div", {
2235
+ className: style$1['filter-label'],
2236
+ children: [item.props.label, ":"]
2237
+ }), /*#__PURE__*/jsxRuntime.jsx(antd.Flex, {
2238
+ wrap: true,
2239
+ align: "center",
2240
+ children: /*#__PURE__*/jsxRuntime.jsx(ComponentItem, _extends({}, item.props, {
2241
+ value: value ? get__default["default"](value.get(item.props.name), 'value') : item.props.value,
2242
+ onChange: onChange ? value => onChange({
2243
+ name: item.props.name,
2244
+ label: item.props.label,
2245
+ value
2246
+ }) : item.props.onChange
2247
+ }))
2248
+ })]
2249
+ }, item.key || item.props.name || index);
865
2250
  })
866
- }, more.map(function (item, index) {
867
- return React.cloneElement(item, {
868
- key: index,
869
- isMore: true,
870
- moreTrigger: moreTrigger
871
- });
872
- })))) : null;
873
- return /*#__PURE__*/React__default["default"].createElement(Provider$1, {
874
- value: {
875
- value: value,
876
- onChange: changeHandler,
877
- emitter: emitter
878
- }
879
- }, /*#__PURE__*/React__default["default"].createElement("div", {
880
- className: "react-filter"
881
- }, /*#__PURE__*/React__default["default"].createElement("div", {
882
- className: "react-filter-inner"
883
- }, /*#__PURE__*/React__default["default"].createElement("div", null, labelHidden ? null : /*#__PURE__*/React__default["default"].createElement(antd.Space, null, /*#__PURE__*/React__default["default"].createElement(FilterItem, {
884
- className: "react-filter-selected",
885
- label: label
886
- }, Object.keys(value).map(function (key) {
887
- var item = value[key];
888
- if (!item) return null;
889
- if (Array.isArray(item) && item.length === 0) return null;
890
- return /*#__PURE__*/React__default["default"].createElement(antd.Tag, {
891
- key: key,
892
- closable: true,
893
- onClose: function onClose() {
894
- changeHandler(key, null);
895
- }
896
- }, Array.isArray(item) ? item.map(function (_ref2) {
897
- var label = _ref2.label;
898
- return label;
899
- }).join(",") : item.label);
900
- })), /*#__PURE__*/React__default["default"].createElement("div", null, extra))), renderList(isExtra ? basicList : list), moreList.length === 0 || isExtra === false ? moreFilter : null), display && isExtra ? /*#__PURE__*/React__default["default"].createElement(React__default["default"].Fragment, null, /*#__PURE__*/React__default["default"].createElement(antd.Divider, {
901
- className: "react-filter-divider"
902
- }), /*#__PURE__*/React__default["default"].createElement("div", {
903
- className: "react-filter-inner"
904
- }, renderList(moreList)), moreList.length > 0 ? moreFilter : null) : /*#__PURE__*/React__default["default"].createElement("div", {
905
- className: "react-filter-divider-close"
906
- }), isExtra && list.length > displayLine ? /*#__PURE__*/React__default["default"].createElement(antd.Row, {
907
- className: "react-filter-switch-btn",
908
- justify: "end"
909
- }, /*#__PURE__*/React__default["default"].createElement(antd.Col, null, /*#__PURE__*/React__default["default"].createElement(antd.Button, {
910
- type: "link",
911
- onClick: function onClick() {
912
- setDisplay(function (display) {
913
- return !display;
914
- });
915
- }
916
- }, display ? foldText : unfoldText))) : null));
917
- };
918
-
919
- Filter.type = {
920
- City: City,
921
- List: List,
922
- Range: Range,
923
- Text: Text,
924
- Selector: Selector,
925
- Check: Check,
926
- RadioList: RadioList,
927
- CheckboxList: CheckboxList,
928
- DateTime: DateTime
929
- };
930
- Filter.defaultProps = {
931
- label: '筛选项',
932
- labelHidden: false,
933
- itemLabelHidden: false,
934
- unfoldText: '展开',
935
- foldText: '收起',
936
- displayLine: 2,
937
- defaultDisplay: false,
938
- isExtra: true,
939
- list: [[]],
940
- more: [],
941
- moreTrigger: 'hover',
942
- moreLabel: '更多',
943
- value: {},
944
- extra: null,
945
- onChange: function onChange() {}
946
- };
947
-
948
- var _excluded = ["name", "value", "children"],
949
- _excluded2 = ["type"];
950
- var withMoreExtraButton = function withMoreExtraButton(WrappedComponent) {
951
- return function (_ref) {
952
- var name = _ref.name,
953
- children = _ref.children,
954
- props = _objectWithoutPropertiesLoose(_ref, _excluded);
955
-
956
- var _useState = React.useState(false),
957
- isEdit = _useState[0],
958
- setIsEdit = _useState[1];
959
-
960
- return isEdit ? /*#__PURE__*/React__default["default"].createElement(WrappedComponent, _extends({
961
- defaultActive: true
962
- }, props, {
963
- name: name,
964
- onBlur: function onBlur() {
965
- setIsEdit(false);
966
- }
967
- })) : /*#__PURE__*/React__default["default"].createElement(List.Item, {
968
- onClick: function onClick(e) {
969
- e.stopPropagation();
970
- setIsEdit(true);
971
- },
972
- label: children || "其他"
973
- });
974
- };
2251
+ });
975
2252
  };
976
- var RangeButton = withMoreExtraButton(RangeInner);
977
- var TextButton = withMoreExtraButton(TextInner);
978
- var SelectorButton = withMoreExtraButton(SelectorInner);
979
- var createExtraButton = function createExtraButton(_ref2) {
980
- var type = _ref2.type,
981
- props = _objectWithoutPropertiesLoose(_ref2, _excluded2);
982
-
983
- return function (innerProps) {
984
- var mapping = {
985
- range: RangeButton,
986
- text: TextButton,
987
- selector: SelectorButton
988
- };
989
- var ExtraButtonComponent = mapping[type];
990
-
991
- if (!ExtraButtonComponent) {
992
- return null;
2253
+ const AdvancedFilter = withLocale(props => {
2254
+ const _useIntl = reactIntl.useIntl({
2255
+ moduleName: 'Filter'
2256
+ }),
2257
+ formatMessage = _useIntl.formatMessage;
2258
+ return /*#__PURE__*/jsxRuntime.jsx(FilterOuter, _extends({}, props, {
2259
+ children: _ref2 => {
2260
+ let value = _ref2.value,
2261
+ onChange = _ref2.onChange,
2262
+ _ref2$props = _ref2.props,
2263
+ filterProps = _ref2$props === void 0 ? {} : _ref2$props;
2264
+ const list = filterProps.list,
2265
+ more = filterProps.more;
2266
+ return /*#__PURE__*/jsxRuntime.jsxs("div", {
2267
+ children: [/*#__PURE__*/jsxRuntime.jsxs(antd.Flex, {
2268
+ gap: 8,
2269
+ vertical: true,
2270
+ className: style$1['filter-advanced'],
2271
+ children: [list && list.map((item, index) => {
2272
+ return /*#__PURE__*/jsxRuntime.jsx(Line, {
2273
+ list: item
2274
+ }, index);
2275
+ }), more && /*#__PURE__*/jsxRuntime.jsx(FilterLines, {
2276
+ className: style$1['filter-advanced-more'],
2277
+ label: formatMessage({
2278
+ id: 'moreText'
2279
+ }) + ":",
2280
+ list: [more]
2281
+ })]
2282
+ }), value && value.length > 0 && /*#__PURE__*/jsxRuntime.jsx(FilterValueDisplay, {
2283
+ value: value,
2284
+ onChange: onChange
2285
+ })]
2286
+ });
993
2287
  }
2288
+ }));
2289
+ });
2290
+ AdvancedFilter.fields = fields;
994
2291
 
995
- return /*#__PURE__*/React__default["default"].createElement(ExtraButtonComponent, _extends({}, props, innerProps));
996
- };
2292
+ const _excluded = ["children"];
2293
+ const FilterItemContainer = _ref => {
2294
+ let children = _ref.children,
2295
+ props = _objectWithoutPropertiesLoose(_ref, _excluded);
2296
+ return children(props);
997
2297
  };
998
2298
 
2299
+ Filter.fields = fields$1;
2300
+ Filter.getFilterValue = getFilterValue;
2301
+ Filter.useFilter = useContext;
2302
+ Filter.SearchInput = SearchInput;
2303
+ Filter.withFilterValue = withFilterValue;
2304
+ Filter.FilterProvider = FilterProvider;
2305
+ Filter.pickSelectValues = pickSelectValues;
2306
+ Filter.createFilterValueMapper = createFilterValueMapper;
2307
+ Filter.useUrlFilter = useUrlFilter;
2308
+ Filter.useUrlFilterValue = useUrlFilterValue;
2309
+ Filter.createUrlParamsReader = createUrlParamsReader;
2310
+ Filter.stripConsumedUrlParams = stripConsumedUrlParams;
2311
+ Filter.filterToUrlParams = filterToUrlParams;
2312
+ Filter.parseFilterEntry = parseFilterEntry;
2313
+ Filter.takeFilterEntry = takeFilterEntry;
2314
+ Filter.createUrlFilterReader = createUrlFilterReader;
2315
+ Filter.filterInterceptors = filterInterceptors;
2316
+ Filter.singleSelectInterceptor = singleSelectInterceptor;
2317
+ Filter.multiSelectInterceptor = multiSelectInterceptor;
2318
+
2319
+ exports.AdvancedFilter = AdvancedFilter;
2320
+ exports.DatePickerFilterItem = DatePickerFilterItem;
2321
+ exports.DateRangePickerFilterItem = DateRangePickerFilterItem;
999
2322
  exports.FilterItem = FilterItem;
1000
- exports.SearchButton = SearchButton;
1001
- exports.createExtraButton = createExtraButton;
2323
+ exports.FilterItemContainer = FilterItemContainer;
2324
+ exports.FilterLines = FilterLines;
2325
+ exports.FilterProvider = FilterProvider;
2326
+ exports.FilterValueDisplay = FilterValueDisplay;
2327
+ exports.InputFilterItem = InputFilterItem$1;
2328
+ exports.NumberRangeFilterItem = NumberRangeFilterItem;
2329
+ exports.PopoverItem = PopoverItem;
2330
+ exports.SearchInput = SearchInput;
2331
+ exports.SelectAddressFilterItem = SelectAddressFilterItem;
2332
+ exports.SelectFunctionFilterItem = SelectFunctionFilterItem;
2333
+ exports.SelectIndustryFilterItem = SelectIndustryFilterItem;
2334
+ exports.SuperSelectFilterItem = SuperSelectFilterItem;
2335
+ exports.TypeDateRangePickerField = TypeDateRangePickerField;
2336
+ exports.TypeDateRangePickerFilterItem = TypeDateRangePickerFilterItem;
2337
+ exports.createFilterValueMapper = createFilterValueMapper;
2338
+ exports.createUrlFilterReader = createUrlFilterReader;
2339
+ exports.createUrlParamsReader = createUrlParamsReader;
1002
2340
  exports["default"] = Filter;
1003
- exports.useFilterContext = useConsumer;
1004
- exports.withFilterItem = withFilterItem;
1005
- exports.withMoreExtraButton = withMoreExtraButton;
2341
+ exports.fields = fields$1;
2342
+ exports.filterInterceptors = filterInterceptors;
2343
+ exports.filterToUrlParams = filterToUrlParams;
2344
+ exports.getFilterValue = getFilterValue;
2345
+ exports.multiSelectInterceptor = multiSelectInterceptor;
2346
+ exports.parseFilterEntry = parseFilterEntry;
2347
+ exports.pickSelectValues = pickSelectValues;
2348
+ exports.singleSelectInterceptor = singleSelectInterceptor;
2349
+ exports.stripConsumedUrlParams = stripConsumedUrlParams;
2350
+ exports.takeFilterEntry = takeFilterEntry;
2351
+ exports.useFilter = useContext;
2352
+ exports.useUrlFilter = useUrlFilter;
2353
+ exports.useUrlFilterValue = useUrlFilterValue;
2354
+ exports.withFieldItem = withFieldItem;
2355
+ exports.withFilterValue = withFilterValue;
1006
2356
  //# sourceMappingURL=index.js.map