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