@kne/react-filter 1.0.4 → 1.0.6

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -95,6 +95,9 @@ function MyComponent() {
95
95
  | `DateRangePickerFilterItem` | 日期范围筛选 |
96
96
  | `TypeDateRangePickerFilterItem` | 类型日期范围筛选(日/周/月切换) |
97
97
  | `SuperSelectFilterItem` | 通用选择器筛选(单选/多选/搜索/全选) |
98
+ | `SelectTableListFilterItem` | 表格选择器筛选(多列数据展示) |
99
+ | `SelectTreeFilterItem` | 树形选择器筛选(层级数据) |
100
+ | `SelectCascaderFilterItem` | 级联选择器筛选(父子关联、搜索过滤) |
98
101
  | `SelectFunctionFilterItem` | 职能筛选(多级数据、拼音搜索) |
99
102
  | `SelectIndustryFilterItem` | 行业筛选(多级数据、拼音搜索) |
100
103
  | `SelectAddressFilterItem` | 城市筛选(国内外城市搜索) |
@@ -140,7 +143,7 @@ const {
140
143
  SelectIndustryFilterItem, SelectAddressFilterItem
141
144
  } = fields;
142
145
  const { Flex, Button, message } = antd;
143
- const { useState } = React;
146
+ const { useState, useRef, useEffect } = React;
144
147
 
145
148
  const departmentOptions = [
146
149
  { value: 'tech', label: '技术研发部' },
@@ -151,8 +154,70 @@ const departmentOptions = [
151
154
  { value: 'marketing', label: '市场营销部' }
152
155
  ];
153
156
 
157
+ const filterList = [
158
+ {
159
+ type: InputFilterItem,
160
+ props: { name: 'keyword', label: '关键词', placeholder: '请输入关键词搜索' }
161
+ },
162
+ {
163
+ type: NumberRangeFilterItem,
164
+ props: { name: 'amount', label: '金额', unit: '元', min: 0, max: 999999 }
165
+ },
166
+ {
167
+ type: DatePickerFilterItem,
168
+ props: { name: 'createTime', label: '创建时间', format: 'YYYY-MM-DD' }
169
+ },
170
+ {
171
+ type: DateRangePickerFilterItem,
172
+ props: { name: 'dateRange', label: '日期范围', format: 'YYYY-MM-DD' }
173
+ },
174
+ {
175
+ type: TypeDateRangePickerFilterItem,
176
+ props: { name: 'typeDateRange', label: '快捷日期' }
177
+ },
178
+ {
179
+ type: SuperSelectFilterItem,
180
+ props: { name: 'department', label: '部门', options: departmentOptions }
181
+ },
182
+ {
183
+ type: SelectFunctionFilterItem,
184
+ props: { name: 'function', label: '职能' }
185
+ },
186
+ {
187
+ type: SelectIndustryFilterItem,
188
+ props: { name: 'industry', label: '行业' }
189
+ },
190
+ {
191
+ type: SelectAddressFilterItem,
192
+ props: { name: 'city', label: '城市' }
193
+ }
194
+ ];
195
+
196
+ const ContainerWidthIndicator = ({ containerRef }) => {
197
+ const [width, setWidth] = useState(0);
198
+
199
+ useEffect(() => {
200
+ const el = containerRef.current;
201
+ if (!el) return undefined;
202
+
203
+ const update = () => setWidth(Math.round(el.clientWidth));
204
+ update();
205
+
206
+ const observer = new ResizeObserver(update);
207
+ observer.observe(el);
208
+ return () => observer.disconnect();
209
+ }, [containerRef]);
210
+
211
+ return (
212
+ <div style={{ fontSize: 12, color: '#999', marginBottom: 4 }}>
213
+ 中间容器宽度: {width}px(观察收起/更多时是否持续增大或跳动)
214
+ </div>
215
+ );
216
+ };
217
+
154
218
  const BaseExample = () => {
155
219
  const [filterValue, setFilterValue] = useState([]);
220
+ const filterContainerRef = useRef(null);
156
221
 
157
222
  const handleSearch = () => {
158
223
  const params = Filter.getFilterValue(filterValue);
@@ -161,54 +226,35 @@ const BaseExample = () => {
161
226
  };
162
227
 
163
228
  return (
164
- <Flex vertical gap={16}>
165
- <Filter
166
- value={filterValue}
167
- onChange={setFilterValue}
168
- list={[
169
- [
170
- {
171
- type: InputFilterItem,
172
- props: { name: 'keyword', label: '关键词', placeholder: '请输入关键词搜索' }
173
- },
174
- {
175
- type: NumberRangeFilterItem,
176
- props: { name: 'amount', label: '金额', unit: '元', min: 0, max: 999999 }
177
- },
178
- {
179
- type: DatePickerFilterItem,
180
- props: { name: 'createTime', label: '创建时间', format: 'YYYY-MM-DD' }
181
- },
182
- {
183
- type: DateRangePickerFilterItem,
184
- props: { name: 'dateRange', label: '日期范围', format: 'YYYY-MM-DD' }
185
- },
186
- {
187
- type: TypeDateRangePickerFilterItem,
188
- props: { name: 'typeDateRange', label: '快捷日期' }
189
- }
190
- ],
191
- [
192
- {
193
- type: SuperSelectFilterItem,
194
- props: { name: 'department', label: '部门', options: departmentOptions }
195
- },
196
- {
197
- type: SelectFunctionFilterItem,
198
- props: { name: 'function', label: '职能' }
199
- },
200
- {
201
- type: SelectIndustryFilterItem,
202
- props: { name: 'industry', label: '行业' }
203
- },
204
- {
205
- type: SelectAddressFilterItem,
206
- props: { name: 'city', label: '城市' }
207
- }
208
- ]
209
- ]}
210
- displayLine={1}
211
- />
229
+ <Flex vertical gap={16} style={{ width: '100%' }}>
230
+ <div style={{ width: '100%' }}>
231
+ <ContainerWidthIndicator containerRef={filterContainerRef} />
232
+ <div
233
+ style={{
234
+ width: '100%',
235
+ display: 'flex',
236
+ alignItems: 'flex-start',
237
+ gap: 8
238
+ }}
239
+ >
240
+ <Button>左侧操作</Button>
241
+ <div
242
+ ref={filterContainerRef}
243
+ style={{
244
+ flex: 1,
245
+ minWidth: 0,
246
+ overflow: 'hidden',
247
+ border: '1px dashed #d9d9d9',
248
+ borderRadius: 4
249
+ }}
250
+ >
251
+ <Filter value={filterValue} onChange={setFilterValue} list={filterList} />
252
+ </div>
253
+ <Button type="primary" onClick={handleSearch}>
254
+ 搜索
255
+ </Button>
256
+ </div>
257
+ </div>
212
258
  <Flex gap={8}>
213
259
  <span>当前筛选值:</span>
214
260
  <pre style={{ margin: 0, background: '#f5f5f5', padding: 8, borderRadius: 4, flex: 1 }}>{JSON.stringify(filterValue, null, 2)}</pre>
@@ -333,7 +379,7 @@ render(<AdvancedFilterExample />);
333
379
  ```
334
380
 
335
381
  - 筛选字段组件
336
- - 展示所有筛选字段组件类型,包括输入筛选、数字区间、日期选择、下拉选择以及 SuperSelect 业务选择器(职能/行业/城市)
382
+ - 展示所有筛选字段组件类型,包括输入筛选、数字区间、日期选择、下拉选择以及 SuperSelect 选择器(列表/表格/树形/级联)和业务选择器(职能/行业/城市)
337
383
  - _ReactFilter(@kne/current-lib_react-filter)[import * as _ReactFilter from "@kne/react-filter"],(@kne/current-lib_react-filter/dist/index.css),antd(antd)
338
384
 
339
385
  ```jsx
@@ -341,8 +387,8 @@ const { fields, PopoverItem } = _ReactFilter;
341
387
  const {
342
388
  InputFilterItem, NumberRangeFilterItem, DatePickerFilterItem,
343
389
  DateRangePickerFilterItem, TypeDateRangePickerFilterItem,
344
- SuperSelectFilterItem, SelectFunctionFilterItem,
345
- SelectIndustryFilterItem, SelectAddressFilterItem
390
+ SuperSelectFilterItem, SelectTableListFilterItem, SelectTreeFilterItem, SelectCascaderFilterItem,
391
+ SelectFunctionFilterItem, SelectIndustryFilterItem, SelectAddressFilterItem
346
392
  } = fields;
347
393
  const { Input, InputNumber, Space, Flex, Select, Divider, Tag } = antd;
348
394
  const { useState } = React;
@@ -512,6 +558,120 @@ const SuperSelectExample = () => {
512
558
  );
513
559
  };
514
560
 
561
+ // SuperSelect 其他选择组件示例(表格/树形/级联)
562
+ const employeeOptions = [
563
+ { id: 'emp_1', name: '张三', department: '技术研发部', position: '工程师' },
564
+ { id: 'emp_2', name: '李四', department: '产品设计部', position: '设计师' },
565
+ { id: 'emp_3', name: '王五', department: '运营部', position: '经理' },
566
+ { id: 'emp_4', name: '赵六', department: '市场部', position: '专员' },
567
+ { id: 'emp_5', name: '钱七', department: '技术研发部', position: '工程师' }
568
+ ];
569
+
570
+ const employeeColumns = [
571
+ { name: 'name', title: '姓名', span: 8 },
572
+ { name: 'department', title: '部门', span: 8 },
573
+ { name: 'position', title: '职位', span: 8 }
574
+ ];
575
+
576
+ const organizationTree = [
577
+ { id: 'root', parentId: null, name: '集团总部' },
578
+ { id: 'tech', parentId: 'root', name: '技术中心' },
579
+ { id: 'tech-fe', parentId: 'tech', name: '前端开发组' },
580
+ { id: 'tech-be', parentId: 'tech', name: '后端开发组' },
581
+ { id: 'product', parentId: 'root', name: '产品中心' },
582
+ { id: 'product-design', parentId: 'product', name: '产品设计组' }
583
+ ];
584
+
585
+ const regionData = [
586
+ {
587
+ id: 'beijing',
588
+ name: '北京市',
589
+ children: [
590
+ { id: 'haidian', name: '海淀区' },
591
+ { id: 'chaoyang', name: '朝阳区' }
592
+ ]
593
+ },
594
+ {
595
+ id: 'guangdong',
596
+ name: '广东省',
597
+ children: [
598
+ {
599
+ id: 'guangzhou',
600
+ name: '广州市',
601
+ children: [
602
+ { id: 'tianhe', name: '天河区' },
603
+ { id: 'yuexiu', name: '越秀区' }
604
+ ]
605
+ },
606
+ {
607
+ id: 'shenzhen',
608
+ name: '深圳市',
609
+ children: [
610
+ { id: 'nanshan', name: '南山区' },
611
+ { id: 'futian', name: '福田区' }
612
+ ]
613
+ }
614
+ ]
615
+ }
616
+ ];
617
+
618
+ const SuperSelectVariantsExample = () => {
619
+ const [values, setValues] = useState({});
620
+
621
+ return (
622
+ <Flex vertical gap={24}>
623
+ <Flex align="center" gap={8}>
624
+ <h4 style={{ margin: 0 }}>SuperSelect 其他选择组件</h4>
625
+ <Tag color="blue">表格</Tag>
626
+ <Tag color="blue">树形</Tag>
627
+ <Tag color="blue">级联</Tag>
628
+ </Flex>
629
+ <p style={{ margin: 0, color: '#666', fontSize: 12 }}>
630
+ 基于 @kne/super-select 的表格、树形、级联选择器筛选项,适用于多列数据、层级结构、级联数据等场景
631
+ </p>
632
+ <Flex wrap gap={16}>
633
+ <SelectTableListFilterItem
634
+ label="员工(表格多选)"
635
+ value={values.employee}
636
+ onChange={(val) => setValues(prev => ({ ...prev, employee: val }))}
637
+ options={employeeOptions}
638
+ columns={employeeColumns}
639
+ valueKey="id"
640
+ labelKey="name"
641
+ />
642
+ <SelectTreeFilterItem
643
+ label="部门(树形多选)"
644
+ value={values.department}
645
+ onChange={(val) => setValues(prev => ({ ...prev, department: val }))}
646
+ options={organizationTree}
647
+ valueKey="id"
648
+ labelKey="name"
649
+ />
650
+ <SelectCascaderFilterItem
651
+ label="地区(级联多选)"
652
+ value={values.region}
653
+ onChange={(val) => setValues(prev => ({ ...prev, region: val }))}
654
+ options={regionData}
655
+ valueKey="id"
656
+ labelKey="name"
657
+ />
658
+ <SelectCascaderFilterItem
659
+ label="地区(级联单选)"
660
+ single
661
+ value={values.singleRegion}
662
+ onChange={(val) => setValues(prev => ({ ...prev, singleRegion: val }))}
663
+ options={regionData}
664
+ valueKey="id"
665
+ labelKey="name"
666
+ />
667
+ </Flex>
668
+ <pre style={{ margin: 0, background: '#f5f5f5', padding: 8, borderRadius: 4 }}>
669
+ {JSON.stringify(values, null, 2)}
670
+ </pre>
671
+ </Flex>
672
+ );
673
+ };
674
+
515
675
  // 业务选择器示例(职能/行业/城市)
516
676
  const BusinessSelectExample = () => {
517
677
  const [values, setValues] = useState({});
@@ -554,11 +714,63 @@ const BusinessSelectExample = () => {
554
714
  );
555
715
  };
556
716
 
557
- render(<FilterFieldsExample />);
558
- render(<Divider />);
559
- render(<SuperSelectExample />);
560
- render(<Divider />);
561
- render(<BusinessSelectExample />);
717
+ const FilterFieldsDemo = () => (
718
+ <Flex vertical>
719
+ <FilterFieldsExample />
720
+ <Divider />
721
+ <SuperSelectExample />
722
+ <Divider />
723
+ <SuperSelectVariantsExample />
724
+ <Divider />
725
+ <BusinessSelectExample />
726
+ </Flex>
727
+ );
728
+
729
+ render(<FilterFieldsDemo />);
730
+
731
+ ```
732
+
733
+ - 搜索输入
734
+ - 使用 SearchInput 实现顶部关键词搜索,输入停止 500ms 后自动提交筛选值,输入法组合输入完成后才开始触发搜索
735
+ - _ReactFilter(@kne/current-lib_react-filter)[import * as _ReactFilter from "@kne/react-filter"],(@kne/current-lib_react-filter/dist/index.css),antd(antd)
736
+
737
+ ```jsx
738
+ const { SearchInput, FilterProvider, getFilterValue } = _ReactFilter;
739
+ const { Flex, Button, Typography, message } = antd;
740
+ const { useState } = React;
741
+
742
+ const SearchInputExample = () => {
743
+ const [filterValue, setFilterValue] = useState([]);
744
+
745
+ const handleSearch = () => {
746
+ const params = getFilterValue(filterValue);
747
+ message.info(&#96;搜索参数: ${JSON.stringify(params)}&#96;);
748
+ console.log('搜索参数:', params);
749
+ };
750
+
751
+ return (
752
+ <Flex vertical gap={16}>
753
+ <Typography.Title level={4}>SearchInput 搜索输入</Typography.Title>
754
+ <Typography.Paragraph style={{ margin: 0 }}>
755
+ 输入停止 500ms 后自动写入筛选值并触发搜索;中文等输入法组合输入期间不会触发搜索,确认文本后才开始计时。按回车或点击搜索按钮会立即提交。 清空后也会在 500ms 后移除该筛选条件。
756
+ </Typography.Paragraph>
757
+ <FilterProvider value={filterValue} onChange={setFilterValue}>
758
+ <Flex gap={8} align="center">
759
+ <SearchInput name="keyword" label="关键词" placeholder="请输入关键词" style={{ width: 320 }} allowClear />
760
+ <Button type="primary" onClick={handleSearch}>
761
+ 查看搜索参数
762
+ </Button>
763
+ </Flex>
764
+ </FilterProvider>
765
+ <Flex gap={8}>
766
+ <span>当前筛选值:</span>
767
+ <pre style={{ margin: 0, background: '#f5f5f5', padding: 8, borderRadius: 4, flex: 1 }}>{JSON.stringify(filterValue, null, 2)}</pre>
768
+ </Flex>
769
+ </Flex>
770
+ );
771
+ };
772
+
773
+ render(<SearchInputExample />);
562
774
 
563
775
  ```
564
776
 
@@ -759,36 +971,36 @@ render(<PopoverItemExample />);
759
971
 
760
972
  #### 属性
761
973
 
762
- | 属性 | 类型 | 默认值 | 说明 |
763
- |--------------|------------------------------------------------------|--------|-----------------|
764
- | value | `Array<{ name: string, label: string, value: any }>` | - | 筛选值数组 |
765
- | defaultValue | `Array<{ name: string, label: string, value: any }>` | `[]` | 默认筛选值 |
766
- | onChange | `(value: Array) => void` | - | 筛选值变化回调 |
767
- | list | `Array<Array>` | `[]` | 筛选项配置数组,支持多行 |
768
- | displayLine | `number` | `1` | 默认展示的行数,超出部分折叠 |
769
- | label | `string` | `'筛选'` | 筛选区域标题 |
770
- | extra | `ReactNode` | - | 额外操作区域,通常放置搜索按钮 |
771
- | extraExpand | `ReactNode` | - | 已选区域额外内容 |
772
- | className | `string` | - | 自定义类名 |
974
+ | 属性 | 类型 | 默认值 | 说明 |
975
+ | ------------ | ---------------------------------------------------- | -------- | ------------------------------ |
976
+ | value | `Array<{ name: string, label: string, value: any }>` | - | 筛选值数组 |
977
+ | defaultValue | `Array<{ name: string, label: string, value: any }>` | `[]` | 默认筛选值 |
978
+ | onChange | `(value: Array) => void` | - | 筛选值变化回调 |
979
+ | list | `Array<Array>` | `[]` | 筛选项配置数组,支持多行 |
980
+ | displayLine | `number` | `1` | 默认展示的行数,超出部分折叠 |
981
+ | label | `string` | `'筛选'` | 筛选区域标题 |
982
+ | extra | `ReactNode` | - | 额外操作区域,通常放置搜索按钮 |
983
+ | extraExpand | `ReactNode` | - | 已选区域额外内容 |
984
+ | className | `string` | - | 自定义类名 |
773
985
 
774
986
  #### 静态方法
775
987
 
776
- | 方法 | 说明 |
777
- |-------------------------------------------------|-----------------------------------------------------------------------|
778
- | `Filter.getFilterValue(filterValue)` | 将筛选值数组转换为参数对象,如 `{ name: value }` |
779
- | `Filter.useFilter()` | 获取 Filter Context,返回 `{ value, onChange }` |
780
- | `Filter.pickSelectValues(value)` | 从筛选值中提取原始值数组,支持 `{ value }`、`{ id }` 格式 |
781
- | `Filter.createFilterValueMapper(fieldMappers)` | 声明式创建 mapFilterValue 函数,按字段映射转换规则 |
782
- | `Filter.filterToUrlParams(filterValue, options)`| 将筛选值数组序列化为 URLSearchParams,保留 label 信息 |
783
- | `Filter.parseFilterEntry(str)` | 解析 URL 参数中的单个筛选值项为 `{ label, value }` |
784
- | `Filter.takeFilterEntry(searchParams, key, options)` | 从 URL 参数中读取筛选值项,支持单选/多选 |
785
- | `Filter.createUrlFilterReader(searchParams)` | 创建 URL 筛选参数读取器,自动追踪已消费的参数 key |
786
- | `Filter.useUrlFilter(options)` | 从 URL 参数初始化 Filter 状态的 hook(React Router 环境) |
787
- | `Filter.useUrlFilterValue(mapping)` | useUrlFilter 的简化版,基于 filterParams[key] 格式自动解析 URL 参数 |
788
- | `Filter.createUrlParamsReader(searchParams)` | 创建通用 URL 参数读取器,自动追踪已消费的参数 key |
789
- | `Filter.stripConsumedUrlParams(searchParams, consumedKeys)` | 从 URL 参数中移除已消费的 key,返回新的 URLSearchParams 或 null |
790
- | `Filter.filterInterceptors.single` | 单选拦截器:`{id, name}` ↔ `{label, value}` 数据格式转换 |
791
- | `Filter.filterInterceptors.multi` | 多选拦截器:`[{id, name}]` ↔ `[{label, value}]` 数据格式转换 |
988
+ | 方法 | 说明 |
989
+ | ----------------------------------------------------------- | ------------------------------------------------------------------- |
990
+ | `Filter.getFilterValue(filterValue)` | 将筛选值数组转换为参数对象,如 `{ name: value }` |
991
+ | `Filter.useFilter()` | 获取 Filter Context,返回 `{ value, onChange }` |
992
+ | `Filter.pickSelectValues(value)` | 从筛选值中提取原始值数组,支持 `{ value }`、`{ id }` 格式 |
993
+ | `Filter.createFilterValueMapper(fieldMappers)` | 声明式创建 mapFilterValue 函数,按字段映射转换规则 |
994
+ | `Filter.filterToUrlParams(filterValue, options)` | 将筛选值数组序列化为 URLSearchParams,保留 label 信息 |
995
+ | `Filter.parseFilterEntry(str)` | 解析 URL 参数中的单个筛选值项为 `{ label, value }` |
996
+ | `Filter.takeFilterEntry(searchParams, key, options)` | 从 URL 参数中读取筛选值项,支持单选/多选 |
997
+ | `Filter.createUrlFilterReader(searchParams)` | 创建 URL 筛选参数读取器,自动追踪已消费的参数 key |
998
+ | `Filter.useUrlFilter(options)` | 从 URL 参数初始化 Filter 状态的 hook(React Router 环境) |
999
+ | `Filter.useUrlFilterValue(mapping)` | useUrlFilter 的简化版,基于 filterParams[key] 格式自动解析 URL 参数 |
1000
+ | `Filter.createUrlParamsReader(searchParams)` | 创建通用 URL 参数读取器,自动追踪已消费的参数 key |
1001
+ | `Filter.stripConsumedUrlParams(searchParams, consumedKeys)` | 从 URL 参数中移除已消费的 key,返回新的 URLSearchParams 或 null |
1002
+ | `Filter.filterInterceptors.single` | 单选拦截器:`{id, name}` ↔ `{label, value}` 数据格式转换 |
1003
+ | `Filter.filterInterceptors.multi` | 多选拦截器:`[{id, name}]` ↔ `[{label, value}]` 数据格式转换 |
792
1004
 
793
1005
  #### 使用示例
794
1006
 
@@ -808,7 +1020,7 @@ const { InputFilterItem, NumberRangeFilterItem } = fields;
808
1020
  ]}
809
1021
  displayLine={1}
810
1022
  extra={<Button type="primary">搜索</Button>}
811
- />
1023
+ />;
812
1024
  ```
813
1025
 
814
1026
  ---
@@ -819,29 +1031,21 @@ const { InputFilterItem, NumberRangeFilterItem } = fields;
819
1031
 
820
1032
  #### 属性
821
1033
 
822
- | 属性 | 类型 | 默认值 | 说明 |
823
- |--------------|------------------------------------------------------|------|----------|
824
- | value | `Array<{ name: string, label: string, value: any }>` | - | 筛选值数组 |
825
- | defaultValue | `Array<{ name: string, label: string, value: any }>` | `[]` | 默认筛选值 |
826
- | onChange | `(value: Array) => void` | - | 筛选值变化回调 |
827
- | list | `Array<Array>` | `[]` | 筛选项配置数组 |
828
- | more | `Array` | - | 额外折叠的筛选项 |
829
- | className | `string` | - | 自定义类名 |
1034
+ | 属性 | 类型 | 默认值 | 说明 |
1035
+ | ------------ | ---------------------------------------------------- | ------ | ---------------- |
1036
+ | value | `Array<{ name: string, label: string, value: any }>` | - | 筛选值数组 |
1037
+ | defaultValue | `Array<{ name: string, label: string, value: any }>` | `[]` | 默认筛选值 |
1038
+ | onChange | `(value: Array) => void` | - | 筛选值变化回调 |
1039
+ | list | `Array<Array>` | `[]` | 筛选项配置数组 |
1040
+ | more | `Array` | - | 额外折叠的筛选项 |
1041
+ | className | `string` | - | 自定义类名 |
830
1042
 
831
1043
  #### 使用示例
832
1044
 
833
1045
  ```javascript
834
1046
  import { AdvancedFilter, fields } from '@kne/react-filter';
835
1047
 
836
- <AdvancedFilter
837
- value={filterValue}
838
- onChange={setFilterValue}
839
- list={[
840
- [
841
- { type: InputFilterItem, props: { name: 'name', label: '姓名' } }
842
- ]
843
- ]}
844
- />
1048
+ <AdvancedFilter value={filterValue} onChange={setFilterValue} list={[[{ type: InputFilterItem, props: { name: 'name', label: '姓名' } }]]} />;
845
1049
  ```
846
1050
 
847
1051
  ---
@@ -852,11 +1056,11 @@ import { AdvancedFilter, fields } from '@kne/react-filter';
852
1056
 
853
1057
  #### 属性
854
1058
 
855
- | 属性 | 类型 | 默认值 | 说明 |
856
- |-------------|------------------------------------------------------|-----|---------|
857
- | value | `Array<{ name: string, label: string, value: any }>` | - | 筛选值数组 |
858
- | onChange | `(value: Array) => void` | - | 筛选值变化回调 |
859
- | extraExpand | `ReactNode` | - | 额外展示内容 |
1059
+ | 属性 | 类型 | 默认值 | 说明 |
1060
+ | ----------- | ---------------------------------------------------- | ------ | -------------- |
1061
+ | value | `Array<{ name: string, label: string, value: any }>` | - | 筛选值数组 |
1062
+ | onChange | `(value: Array) => void` | - | 筛选值变化回调 |
1063
+ | extraExpand | `ReactNode` | - | 额外展示内容 |
860
1064
 
861
1065
  ---
862
1066
 
@@ -866,34 +1070,25 @@ import { AdvancedFilter, fields } from '@kne/react-filter';
866
1070
 
867
1071
  #### 属性
868
1072
 
869
- | 属性 | 类型 | 默认值 | 说明 |
870
- |------------------|---------------------------------------------|----------------|-----------|
871
- | label | `string` | - | 筛选项标签 |
872
- | value | `{ label: string, value: any }` | - | 当前值 |
873
- | onChange | `(value: object) => void` | - | 值变化回调 |
874
- | onValidate | `(value: object) => boolean` | - | 确认按钮校验函数 |
1073
+ | 属性 | 类型 | 默认值 | 说明 |
1074
+ | ---------------- | ------------------------------------------- | -------------- | ------------------ |
1075
+ | label | `string` | - | 筛选项标签 |
1076
+ | value | `{ label: string, value: any }` | - | 当前值 |
1077
+ | onChange | `(value: object) => void` | - | 值变化回调 |
1078
+ | onValidate | `(value: object) => boolean` | - | 确认按钮校验函数 |
875
1079
  | onOpenChange | `(open: boolean) => void` | - | 弹出层状态变化回调 |
876
- | placement | `string` | `'bottomLeft'` | 弹出层位置 |
877
- | overlayClassName | `string` | - | 弹出层自定义类名 |
878
- | children | `(props: { value, onChange }) => ReactNode` | - | 内容渲染函数 |
1080
+ | placement | `string` | `'bottomLeft'` | 弹出层位置 |
1081
+ | overlayClassName | `string` | - | 弹出层自定义类名 |
1082
+ | children | `(props: { value, onChange }) => ReactNode` | - | 内容渲染函数 |
879
1083
 
880
1084
  #### 使用示例
881
1085
 
882
1086
  ```javascript
883
1087
  import { PopoverItem } from '@kne/react-filter';
884
1088
 
885
- <PopoverItem
886
- label="文本输入"
887
- value={inputValue}
888
- onChange={setInputValue}
889
- >
890
- {({ value, onChange }) => (
891
- <Input
892
- value={value?.value}
893
- onChange={(e) => onChange({ label: e.target.value, value: e.target.value })}
894
- />
895
- )}
896
- </PopoverItem>
1089
+ <PopoverItem label="文本输入" value={inputValue} onChange={setInputValue}>
1090
+ {({ value, onChange }) => <Input value={value?.value} onChange={e => onChange({ label: e.target.value, value: e.target.value })} />}
1091
+ </PopoverItem>;
897
1092
  ```
898
1093
 
899
1094
  ---
@@ -904,12 +1099,12 @@ import { PopoverItem } from '@kne/react-filter';
904
1099
 
905
1100
  #### 属性
906
1101
 
907
- | 属性 | 类型 | 默认值 | 说明 |
908
- |----------|-------------|-----|------------|
909
- | label | `string` | - | 筛选项标签 |
910
- | open | `boolean` | - | 是否展开状态 |
911
- | active | `boolean` | - | 是否激活状态(有值) |
912
- | children | `ReactNode` | - | 子元素 |
1102
+ | 属性 | 类型 | 默认值 | 说明 |
1103
+ | -------- | ----------- | ------ | -------------------- |
1104
+ | label | `string` | - | 筛选项标签 |
1105
+ | open | `boolean` | - | 是否展开状态 |
1106
+ | active | `boolean` | - | 是否激活状态(有值) |
1107
+ | children | `ReactNode` | - | 子元素 |
913
1108
 
914
1109
  ---
915
1110
 
@@ -919,13 +1114,14 @@ import { PopoverItem } from '@kne/react-filter';
919
1114
 
920
1115
  #### 属性
921
1116
 
922
- | 属性 | 类型 | 默认值 | 说明 |
923
- |-------------|----------------|--------|---------|
924
- | list | `Array<Array>` | `[]` | 筛选项配置数组 |
925
- | displayLine | `number` | `1` | 默认展示行数 |
926
- | label | `string` | `'筛选'` | 标题 |
927
- | extra | `ReactNode` | - | 额外操作区域 |
928
- | className | `string` | - | 自定义类名 |
1117
+ | 属性 | 类型 | 默认值 | 说明 |
1118
+ | ----------- | -------------- | -------- | -------------- |
1119
+ | list | `Array` | `[]` | 筛选项配置数组,默认支持单层数组,也兼容双层数组 |
1120
+ | displayLine | `number` | `1` | 双层数组模式下默认展示行数 |
1121
+ | visibleCountStrategy | `'asc' \| 'desc'` | `'asc'` | 单层数组模式下可见项计算策略,`asc` 从少往多累加,`desc` 从多往少递减 |
1122
+ | label | `string` | `'筛选'` | 标题 |
1123
+ | extra | `ReactNode` | - | 额外操作区域 |
1124
+ | className | `string` | - | 自定义类名 |
929
1125
 
930
1126
  ---
931
1127
 
@@ -935,12 +1131,12 @@ Filter 状态管理组件,用于自定义 Filter 结构。
935
1131
 
936
1132
  #### 属性
937
1133
 
938
- | 属性 | 类型 | 默认值 | 说明 |
939
- |--------------|---------------------------------------|------|----------|
940
- | value | `Array` | - | 筛选值数组 |
941
- | defaultValue | `Array` | `[]` | 默认筛选值 |
942
- | onChange | `(value: Array) => void` | - | 筛选值变化回调 |
943
- | children | `ReactNode \| (context) => ReactNode` | - | 子元素或渲染函数 |
1134
+ | 属性 | 类型 | 默认值 | 说明 |
1135
+ | ------------ | ------------------------------------- | ------ | ---------------- |
1136
+ | value | `Array` | - | 筛选值数组 |
1137
+ | defaultValue | `Array` | `[]` | 默认筛选值 |
1138
+ | onChange | `(value: Array) => void` | - | 筛选值变化回调 |
1139
+ | children | `ReactNode \| (context) => ReactNode` | - | 子元素或渲染函数 |
944
1140
 
945
1141
  ---
946
1142
 
@@ -954,7 +1150,7 @@ Filter 状态管理组件,用于自定义 Filter 结构。
954
1150
  import { withFilterValue } from '@kne/react-filter';
955
1151
 
956
1152
  const MyFilterItem = withFilterValue(({ name, label, value, onChange, ...props }) => {
957
- return <Component value={value} onChange={onChange}/>;
1153
+ return <Component value={value} onChange={onChange} />;
958
1154
  });
959
1155
  ```
960
1156
 
@@ -976,45 +1172,45 @@ const MyFieldItem = withFieldItem(MyComponent);
976
1172
 
977
1173
  弹出层形式的输入框筛选组件。
978
1174
 
979
- | 属性 | 类型 | 默认值 | 说明 |
980
- |-------------|----------------------|-----|--------|
981
- | name | `string` | - | 字段名称 |
982
- | label | `string` | - | 标签 |
983
- | placeholder | `string` | - | 占位符 |
984
- | onValidate | `(value) => boolean` | - | 确认校验函数 |
1175
+ | 属性 | 类型 | 默认值 | 说明 |
1176
+ | ----------- | -------------------- | ------ | ------------ |
1177
+ | name | `string` | - | 字段名称 |
1178
+ | label | `string` | - | 标签 |
1179
+ | placeholder | `string` | - | 占位符 |
1180
+ | onValidate | `(value) => boolean` | - | 确认校验函数 |
985
1181
 
986
1182
  #### NumberRangeFilterItem 数字区间筛选
987
1183
 
988
1184
  数字区间输入筛选组件。
989
1185
 
990
- | 属性 | 类型 | 默认值 | 说明 |
991
- |-------------|----------|-----|------|
992
- | name | `string` | - | 字段名称 |
993
- | label | `string` | - | 标签 |
994
- | unit | `string` | - | 单位 |
995
- | min | `number` | - | 最小值 |
996
- | max | `number` | - | 最大值 |
997
- | placeholder | `string` | - | 占位符 |
1186
+ | 属性 | 类型 | 默认值 | 说明 |
1187
+ | ----------- | -------- | ------ | -------- |
1188
+ | name | `string` | - | 字段名称 |
1189
+ | label | `string` | - | 标签 |
1190
+ | unit | `string` | - | 单位 |
1191
+ | min | `number` | - | 最小值 |
1192
+ | max | `number` | - | 最大值 |
1193
+ | placeholder | `string` | - | 占位符 |
998
1194
 
999
1195
  #### DatePickerFilterItem 日期筛选
1000
1196
 
1001
1197
  日期选择筛选组件。
1002
1198
 
1003
- | 属性 | 类型 | 默认值 | 说明 |
1004
- |--------|------------------------------------------------------|----------------|-------|
1005
- | name | `string` | - | 字段名称 |
1006
- | label | `string` | - | 标签 |
1199
+ | 属性 | 类型 | 默认值 | 说明 |
1200
+ | ------ | ---------------------------------------------------- | -------------- | ---------- |
1201
+ | name | `string` | - | 字段名称 |
1202
+ | label | `string` | - | 标签 |
1007
1203
  | picker | `'date' \| 'week' \| 'month' \| 'quarter' \| 'year'` | `'date'` | 选择器类型 |
1008
- | format | `string` | `'YYYY-MM-DD'` | 日期格式 |
1204
+ | format | `string` | `'YYYY-MM-DD'` | 日期格式 |
1009
1205
 
1010
1206
  #### DateRangePickerFilterItem 日期范围筛选
1011
1207
 
1012
1208
  日期范围选择筛选组件。
1013
1209
 
1014
- | 属性 | 类型 | 默认值 | 说明 |
1015
- |--------|-------------------------------------|----------------|------|
1210
+ | 属性 | 类型 | 默认值 | 说明 |
1211
+ | ------ | ----------------------------------- | -------------- | -------- |
1016
1212
  | name | `string` | - | 字段名称 |
1017
- | label | `string` | - | 标签 |
1213
+ | label | `string` | - | 标签 |
1018
1214
  | format | `string` | `'YYYY-MM-DD'` | 日期格式 |
1019
1215
  | header | `ReactNode \| (props) => ReactNode` | - | 头部内容 |
1020
1216
 
@@ -1022,24 +1218,24 @@ const MyFieldItem = withFieldItem(MyComponent);
1022
1218
 
1023
1219
  支持按日/周/月切换的日期范围选择筛选组件。
1024
1220
 
1025
- | 属性 | 类型 | 默认值 | 说明 |
1026
- |--------|----------|----------------|------|
1221
+ | 属性 | 类型 | 默认值 | 说明 |
1222
+ | ------ | -------- | -------------- | -------- |
1027
1223
  | name | `string` | - | 字段名称 |
1028
- | label | `string` | - | 标签 |
1224
+ | label | `string` | - | 标签 |
1029
1225
  | format | `string` | `'YYYY-MM-DD'` | 日期格式 |
1030
1226
 
1031
1227
  #### SuperSelectFilterItem 通用选择器筛选
1032
1228
 
1033
1229
  基于 `@kne/super-select` 的通用选择器筛选项,支持单选/多选、搜索、全选等功能。
1034
1230
 
1035
- | 属性 | 类型 | 默认值 | 说明 |
1036
- |------------------|-----------------------------|---------|----------|
1037
- | name | `string` | - | 字段名称 |
1038
- | label | `string` | - | 标签 |
1039
- | options | `Array<{ value, label }>` | - | 选项数据 |
1040
- | single | `boolean` | `false` | 是否单选 |
1041
- | allowSelectedAll | `boolean` | `false` | 是否支持全选 |
1042
- | maxLength | `number` | - | 最多可选数量 |
1231
+ | 属性 | 类型 | 默认值 | 说明 |
1232
+ | ---------------- | ------------------------- | ------- | ------------ |
1233
+ | name | `string` | - | 字段名称 |
1234
+ | label | `string` | - | 标签 |
1235
+ | options | `Array<{ value, label }>` | - | 选项数据 |
1236
+ | single | `boolean` | `false` | 是否单选 |
1237
+ | allowSelectedAll | `boolean` | `false` | 是否支持全选 |
1238
+ | maxLength | `number` | - | 最多可选数量 |
1043
1239
 
1044
1240
  **使用示例:**
1045
1241
 
@@ -1068,16 +1264,65 @@ import { SuperSelectFilterItem } from '@kne/react-filter';
1068
1264
 
1069
1265
  > 注意:需要安装 `@kne/super-select` 依赖。
1070
1266
 
1267
+ #### SelectTableListFilterItem 表格选择器筛选
1268
+
1269
+ 基于 `@kne/super-select` 的 `SelectTableList` 组件,适用于需要展示多列数据的筛选场景。
1270
+
1271
+ | 属性 | 类型 | 默认值 | 说明 |
1272
+ | --------- | ---------- | ------- | ------------ |
1273
+ | name | `string` | - | 字段名称 |
1274
+ | label | `string` | - | 标签 |
1275
+ | options | `Array` | - | 选项数据 |
1276
+ | columns | `Array` | - | 表格列配置 |
1277
+ | valueKey | `string` | `'id'` | 值字段名 |
1278
+ | labelKey | `string` | `'name'`| 标签字段名 |
1279
+ | single | `boolean` | `false` | 是否单选 |
1280
+ | maxLength | `number` | - | 最多可选数量 |
1281
+
1282
+ > 注意:需要安装 `@kne/super-select` 依赖。
1283
+
1284
+ #### SelectTreeFilterItem 树形选择器筛选
1285
+
1286
+ 基于 `@kne/super-select` 的 `SelectTree` 组件,适用于组织架构、分类等层级数据筛选。
1287
+
1288
+ | 属性 | 类型 | 默认值 | 说明 |
1289
+ | --------- | ---------- | ------- | ------------ |
1290
+ | name | `string` | - | 字段名称 |
1291
+ | label | `string` | - | 标签 |
1292
+ | options | `Array` | - | 树形数据(含 `parentId`) |
1293
+ | valueKey | `string` | `'id'` | 值字段名 |
1294
+ | labelKey | `string` | `'name'`| 标签字段名 |
1295
+ | single | `boolean` | `false` | 是否单选 |
1296
+ | maxLength | `number` | - | 最多可选数量 |
1297
+
1298
+ > 注意:需要安装 `@kne/super-select` 依赖。
1299
+
1300
+ #### SelectCascaderFilterItem 级联选择器筛选
1301
+
1302
+ 基于 `@kne/super-select` 的 `SelectCascader` 组件,支持多列菜单展示、父子关联选择、搜索过滤。
1303
+
1304
+ | 属性 | 类型 | 默认值 | 说明 |
1305
+ | --------- | ---------- | ------- | ------------ |
1306
+ | name | `string` | - | 字段名称 |
1307
+ | label | `string` | - | 标签 |
1308
+ | options | `Array` | - | 级联数据(含 `children`) |
1309
+ | valueKey | `string` | `'id'` | 值字段名 |
1310
+ | labelKey | `string` | `'name'`| 标签字段名 |
1311
+ | single | `boolean` | `false` | 是否单选 |
1312
+ | maxLength | `number` | - | 最多可选数量 |
1313
+
1314
+ > 注意:需要安装 `@kne/super-select` 依赖。
1315
+
1071
1316
  #### SelectFunctionFilterItem 职能筛选
1072
1317
 
1073
1318
  基于 `@kne/super-select-plus` 的职能选择器筛选项,支持多级职能数据选择、拼音搜索。
1074
1319
 
1075
- | 属性 | 类型 | 默认值 | 说明 |
1076
- |-----------|-----------|---------|----------|
1320
+ | 属性 | 类型 | 默认值 | 说明 |
1321
+ | --------- | --------- | ------- | ------------ |
1077
1322
  | name | `string` | - | 字段名称 |
1078
- | label | `string` | - | 标签 |
1323
+ | label | `string` | - | 标签 |
1079
1324
  | single | `boolean` | `false` | 是否单选 |
1080
- | maxLength | `number` | - | 最多可选数量 |
1325
+ | maxLength | `number` | - | 最多可选数量 |
1081
1326
 
1082
1327
  > 注意:需要安装 `@kne/super-select-plus` 依赖。
1083
1328
 
@@ -1085,12 +1330,12 @@ import { SuperSelectFilterItem } from '@kne/react-filter';
1085
1330
 
1086
1331
  基于 `@kne/super-select-plus` 的行业选择器筛选项,支持多级行业数据选择、拼音搜索。
1087
1332
 
1088
- | 属性 | 类型 | 默认值 | 说明 |
1089
- |-----------|-----------|---------|----------|
1333
+ | 属性 | 类型 | 默认值 | 说明 |
1334
+ | --------- | --------- | ------- | ------------ |
1090
1335
  | name | `string` | - | 字段名称 |
1091
- | label | `string` | - | 标签 |
1336
+ | label | `string` | - | 标签 |
1092
1337
  | single | `boolean` | `false` | 是否单选 |
1093
- | maxLength | `number` | - | 最多可选数量 |
1338
+ | maxLength | `number` | - | 最多可选数量 |
1094
1339
 
1095
1340
  > 注意:需要安装 `@kne/super-select-plus` 依赖。
1096
1341
 
@@ -1098,12 +1343,12 @@ import { SuperSelectFilterItem } from '@kne/react-filter';
1098
1343
 
1099
1344
  基于 `@kne/super-select-plus` 的城市选择器筛选项,支持国内外城市搜索选择。
1100
1345
 
1101
- | 属性 | 类型 | 默认值 | 说明 |
1102
- |-----------|-----------|---------|----------|
1346
+ | 属性 | 类型 | 默认值 | 说明 |
1347
+ | --------- | --------- | ------- | ------------ |
1103
1348
  | name | `string` | - | 字段名称 |
1104
- | label | `string` | - | 标签 |
1349
+ | label | `string` | - | 标签 |
1105
1350
  | single | `boolean` | `false` | 是否单选 |
1106
- | maxLength | `number` | - | 最多可选数量 |
1351
+ | maxLength | `number` | - | 最多可选数量 |
1107
1352
 
1108
1353
  > 注意:需要安装 `@kne/super-select-plus` 依赖。
1109
1354
 
@@ -1111,10 +1356,10 @@ import { SuperSelectFilterItem } from '@kne/react-filter';
1111
1356
 
1112
1357
  城市选择器的高级筛选版本,用于 `AdvancedFilter` 组件的 `list` 配置中。展示热门城市标签,支持搜索选择其他城市。
1113
1358
 
1114
- | 属性 | 类型 | 默认值 | 说明 |
1115
- |-----------|-----------|---------|------------|
1116
- | single | `boolean` | `false` | 是否单选 |
1117
- | maxLength | `number` | `5` | 最多可选数量 |
1359
+ | 属性 | 类型 | 默认值 | 说明 |
1360
+ | --------- | --------- | ------- | ------------ |
1361
+ | single | `boolean` | `false` | 是否单选 |
1362
+ | maxLength | `number` | `5` | 最多可选数量 |
1118
1363
 
1119
1364
  **在高级筛选中使用:**
1120
1365
 
@@ -1122,11 +1367,7 @@ import { SuperSelectFilterItem } from '@kne/react-filter';
1122
1367
  import { AdvancedFilter } from '@kne/react-filter';
1123
1368
  import { CityFilterItem } from './AdvancedFilter/fields';
1124
1369
 
1125
- <AdvancedFilter
1126
- list={[
1127
- [{ type: CityFilterItem, props: { label: '城市', single: true } }]
1128
- ]}
1129
- />
1370
+ <AdvancedFilter list={[[{ type: CityFilterItem, props: { label: '城市', single: true } }]]} />;
1130
1371
  ```
1131
1372
 
1132
1373
  ---
@@ -1135,20 +1376,20 @@ import { CityFilterItem } from './AdvancedFilter/fields';
1135
1376
 
1136
1377
  支持按日/周/月切换的日期范围选择器基础组件。
1137
1378
 
1138
- | 属性 | 类型 | 默认值 | 说明 |
1139
- |-----------------|------------------------------------------------------------|---------------------------------|----------|
1140
- | value | `{ type: string, value: [Date, Date] }` | - | 当前值 |
1141
- | defaultValue | `{ type: string, value: [Date, Date] }` | `{ type: 'date', value: null }` | 默认值 |
1142
- | onChange | `(value: object) => void` | - | 值变化回调 |
1379
+ | 属性 | 类型 | 默认值 | 说明 |
1380
+ | --------------- | ---------------------------------------------------------- | ------------------------------- | ---------------- |
1381
+ | value | `{ type: string, value: [Date, Date] }` | - | 当前值 |
1382
+ | defaultValue | `{ type: string, value: [Date, Date] }` | `{ type: 'date', value: null }` | 默认值 |
1383
+ | onChange | `(value: object) => void` | - | 值变化回调 |
1143
1384
  | shortcuts | `boolean` | `true` | 是否显示快捷选项 |
1144
- | shortcutOptions | `Array<{ label: string, getValue: () => [Dayjs, Dayjs] }>` | - | 自定义快捷选项 |
1385
+ | shortcutOptions | `Array<{ label: string, getValue: () => [Dayjs, Dayjs] }>` | - | 自定义快捷选项 |
1145
1386
 
1146
1387
  **value 结构:**
1147
1388
 
1148
1389
  ```typescript
1149
1390
  interface TypeDateRangeValue {
1150
- type: 'date' | 'week' | 'month'; // 日期类型
1151
- value: [Date, Date] | null; // 日期范围 [开始时间, 结束时间]
1391
+ type: 'date' | 'week' | 'month'; // 日期类型
1392
+ value: [Date, Date] | null; // 日期范围 [开始时间, 结束时间]
1152
1393
  }
1153
1394
  ```
1154
1395
 
@@ -1176,20 +1417,38 @@ import { TypeDateRangePickerField } from '@kne/react-filter';
1176
1417
  getValue: () => [dayjs().subtract(1, 'month').startOf('day'), dayjs().endOf('day')]
1177
1418
  }
1178
1419
  ]}
1179
- />
1420
+ />;
1180
1421
  ```
1181
1422
 
1182
1423
  ---
1183
1424
 
1184
1425
  ### SearchInput 搜索输入
1185
1426
 
1186
- 搜索输入组件。
1427
+ 搜索输入组件,适合放在列表顶部做关键词搜索。输入过程中维护本地输入值,停止输入 500ms 后自动提交筛选值;中文等输入法组合输入期间不会触发搜索,确认文本后才开始计时。按回车或点击搜索按钮会立即提交。清空后搜索会提交 `null`,用于移除该筛选条件。
1428
+
1429
+ | 属性 | 类型 | 默认值 | 说明 |
1430
+ | ----------- | ---------------------------------- | ------ | ------------------------------------ |
1431
+ | name | `string` | - | 字段名称,用于写入筛选值 |
1432
+ | label | `string` | - | 标签,用于展示已选筛选条件 |
1433
+ | value | `{ label: string, value: string }` | - | 当前搜索值 |
1434
+ | onChange | `(value: object \| null) => void` | - | 搜索提交回调,清空搜索时返回 `null` |
1435
+ | placeholder | `string` | - | 占位符 |
1436
+ | searchDelay | `number` | `500` | 自动提交搜索的防抖等待时间,单位毫秒 |
1437
+
1438
+ #### 使用示例
1439
+
1440
+ ```javascript
1441
+ import { SearchInput, FilterProvider, getFilterValue } from '@kne/react-filter';
1442
+
1443
+ const [filterValue, setFilterValue] = useState([]);
1444
+
1445
+ <FilterProvider value={filterValue} onChange={setFilterValue}>
1446
+ <SearchInput name="keyword" label="关键词" placeholder="请输入关键词" searchDelay={500} allowClear />
1447
+ </FilterProvider>;
1187
1448
 
1188
- | 属性 | 类型 | 默认值 | 说明 |
1189
- |-------------|----------|-----|------|
1190
- | name | `string` | - | 字段名称 |
1191
- | label | `string` | - | 标签 |
1192
- | placeholder | `string` | - | 占位符 |
1449
+ const params = getFilterValue(filterValue);
1450
+ // { keyword: 'React' }
1451
+ ```
1193
1452
 
1194
1453
  ---
1195
1454
 
@@ -1219,15 +1478,20 @@ const params = getFilterValue(filterValue);
1219
1478
 
1220
1479
  ```typescript
1221
1480
  interface FilterValueItem {
1222
- name: string; // 字段名称
1223
- label: string; // 字段标签(用于展示)
1224
- value: { // 单个值
1225
- label: string; // 显示文本
1226
- value: any; // 实际值
1227
- } | Array<{ // 或多个值
1228
- label: string;
1229
- value: any;
1230
- }> | null; // 或空值
1481
+ name: string; // 字段名称
1482
+ label: string; // 字段标签(用于展示)
1483
+ value:
1484
+ | {
1485
+ // 单个值
1486
+ label: string; // 显示文本
1487
+ value: any; // 实际值
1488
+ }
1489
+ | Array<{
1490
+ // 或多个值
1491
+ label: string;
1492
+ value: any;
1493
+ }>
1494
+ | null; // 或空值
1231
1495
  }
1232
1496
  ```
1233
1497
 
@@ -1239,12 +1503,13 @@ interface FilterValueItem {
1239
1503
 
1240
1504
  将筛选值数组序列化为 URLSearchParams,保留 label 信息以便反序列化还原完整筛选状态。
1241
1505
 
1242
- | 参数 | 类型 | 默认值 | 说明 |
1243
- |----------------|----------------|-----------------|--------------------------|
1244
- | filterValue | `Array` | - | 筛选值数组 |
1245
- | options.prefix | `string` | `'filterParams'` | URL 参数前缀,设为空字符串则不加前缀 |
1506
+ | 参数 | 类型 | 默认值 | 说明 |
1507
+ | -------------- | -------- | ---------------- | ------------------------------------ |
1508
+ | filterValue | `Array` | - | 筛选值数组 |
1509
+ | options.prefix | `string` | `'filterParams'` | URL 参数前缀,设为空字符串则不加前缀 |
1246
1510
 
1247
1511
  **序列化格式**:
1512
+
1248
1513
  - 单值且 `label === value`:`prefix[name]=value`(如输入框)
1249
1514
  - 单值且 `label !== value`:`prefix[name]=label:value`
1250
1515
  - 多值:`prefix[name]=label1:value1,label2:value2`
@@ -1256,7 +1521,14 @@ import { filterToUrlParams } from '@kne/react-filter';
1256
1521
 
1257
1522
  const params = filterToUrlParams([
1258
1523
  { name: 'keyword', label: '关键词', value: { label: '测试', value: '测试' } },
1259
- { name: 'city', label: '城市', value: [{ label: '上海', value: '010' }, { label: '北京', value: '020' }] },
1524
+ {
1525
+ name: 'city',
1526
+ label: '城市',
1527
+ value: [
1528
+ { label: '上海', value: '010' },
1529
+ { label: '北京', value: '020' }
1530
+ ]
1531
+ }
1260
1532
  ]);
1261
1533
  // params.toString() => 'filterParams[keyword]=测试&filterParams[city]=上海:010,北京:020'
1262
1534
 
@@ -1275,11 +1547,12 @@ filterToUrlParams(filterValue, { prefix: '' });
1275
1547
 
1276
1548
  解析 URL 参数中的单个筛选值项,反序列化为 `{ label, value }` 对象。
1277
1549
 
1278
- | 参数 | 类型 | 说明 |
1279
- |-----|----------|---------------|
1280
- | str | `string` | URL 参数中的原始字符串 |
1550
+ | 参数 | 类型 | 说明 |
1551
+ | ---- | -------- | ---------------------- |
1552
+ | str | `string` | URL 参数中的原始字符串 |
1281
1553
 
1282
1554
  **解析规则**:
1555
+
1283
1556
  - 无冒号:label 和 value 相同,如 `"测试"` → `{ label: '测试', value: '测试' }`
1284
1557
  - 有冒号:冒号前为 label,冒号后为 value,如 `"启用:active"` → `{ label: '启用', value: 'active' }`
1285
1558
 
@@ -1299,12 +1572,12 @@ parseFilterEntry('启用:active');
1299
1572
 
1300
1573
  从 URL 参数中读取筛选值项,返回单选 `{ label, value }` 或多选数组。
1301
1574
 
1302
- | 参数 | 类型 | 默认值 | 说明 |
1303
- |-----------------|-------------------|-----------------|------------------|
1304
- | searchParams | `URLSearchParams` | - | URL 参数对象 |
1305
- | key | `string` | - | 参数名(不含前缀) |
1306
- | options.multi | `boolean` | `false` | 是否多选 |
1307
- | options.prefix | `string` | `'filterParams'` | URL 参数前缀 |
1575
+ | 参数 | 类型 | 默认值 | 说明 |
1576
+ | -------------- | ----------------- | ---------------- | ------------------ |
1577
+ | searchParams | `URLSearchParams` | - | URL 参数对象 |
1578
+ | key | `string` | - | 参数名(不含前缀) |
1579
+ | options.multi | `boolean` | `false` | 是否多选 |
1580
+ | options.prefix | `string` | `'filterParams'` | URL 参数前缀 |
1308
1581
 
1309
1582
  ```javascript
1310
1583
  import { takeFilterEntry } from '@kne/react-filter';
@@ -1323,10 +1596,10 @@ takeFilterEntry(searchParams, 'keyword', { prefix: '' });
1323
1596
 
1324
1597
  创建 URL 筛选参数读取器,自动追踪已消费的参数 key。配合 `useUrlFilter` 使用,readUrlParams 返回的 consumedKeys 可被自动清除。
1325
1598
 
1326
- | 参数 | 类型 | 默认值 | 说明 |
1327
- |-----------------|-------------------|-----------------|----------|
1328
- | searchParams | `URLSearchParams` | - | URL 参数对象 |
1329
- | options.prefix | `string` | `'filterParams'` | URL 参数前缀 |
1599
+ | 参数 | 类型 | 默认值 | 说明 |
1600
+ | -------------- | ----------------- | ---------------- | ------------ |
1601
+ | searchParams | `URLSearchParams` | - | URL 参数对象 |
1602
+ | options.prefix | `string` | `'filterParams'` | URL 参数前缀 |
1330
1603
 
1331
1604
  **返回值**:`{ takeFilterEntry, getConsumedKeys }`
1332
1605
 
@@ -1347,10 +1620,10 @@ const city = takeFilterEntry('city', { multi: true });
1347
1620
 
1348
1621
  > 需要 React Router 环境支持 `useSearchParams`。
1349
1622
 
1350
- | 参数 | 类型 | 说明 |
1351
- |---------------------|------------|----------------------------------------------|
1623
+ | 参数 | 类型 | 说明 |
1624
+ | --------------------- | ---------- | --------------------------------------------------------- |
1352
1625
  | options.readUrlParams | `Function` | 读取 URL 参数并返回 `{ consumedKeys: string[], ...data }` |
1353
- | options.buildFilter | `Function` | 接收 readUrlParams 的返回值,构建初始 filter 数组 |
1626
+ | options.buildFilter | `Function` | 接收 readUrlParams 的返回值,构建初始 filter 数组 |
1354
1627
 
1355
1628
  **返回值**:`[filter, setFilter]`
1356
1629
 
@@ -1358,15 +1631,12 @@ const city = takeFilterEntry('city', { multi: true });
1358
1631
  import { useUrlFilter, createUrlParamsReader } from '@kne/react-filter';
1359
1632
 
1360
1633
  const [filter, setFilter] = useUrlFilter({
1361
- readUrlParams: (searchParams) => {
1634
+ readUrlParams: searchParams => {
1362
1635
  const { take, getConsumedKeys } = createUrlParamsReader(searchParams);
1363
1636
  const orgId = take('tenantOrgId');
1364
1637
  return { consumedKeys: getConsumedKeys(), orgId };
1365
1638
  },
1366
- buildFilter: ({ orgId }) => [
1367
- { name: 'status', value: { label: '开启', value: 'open' } },
1368
- ...(orgId ? [{ name: 'tenantOrgId', value: { label: orgId, value: orgId } }] : [])
1369
- ]
1639
+ buildFilter: ({ orgId }) => [{ name: 'status', value: { label: '开启', value: 'open' } }, ...(orgId ? [{ name: 'tenantOrgId', value: { label: orgId, value: orgId } }] : [])]
1370
1640
  });
1371
1641
  ```
1372
1642
 
@@ -1376,11 +1646,12 @@ const [filter, setFilter] = useUrlFilter({
1376
1646
 
1377
1647
  `useUrlFilter` 的简化版,基于 `filterParams[key]` 格式自动解析 URL 参数,支持单选和多选。
1378
1648
 
1379
- | 参数 | 类型 | 说明 |
1380
- |---------|------------------------|--------------------------------|
1381
- | mapping | `string[] \| Object` | URL 参数映射,支持数组、对象两种格式 |
1649
+ | 参数 | 类型 | 说明 |
1650
+ | ------- | -------------------- | ------------------------------------ |
1651
+ | mapping | `string[] \| Object` | URL 参数映射,支持数组、对象两种格式 |
1382
1652
 
1383
1653
  **数组形式(默认单选):**
1654
+
1384
1655
  ```javascript
1385
1656
  import { useUrlFilterValue } from '@kne/react-filter';
1386
1657
 
@@ -1393,11 +1664,13 @@ const [filter, setFilter] = useUrlFilterValue(['keyword', 'status']);
1393
1664
  ```
1394
1665
 
1395
1666
  **对象形式(多选 + 自定义):**
1667
+
1396
1668
  ```javascript
1397
1669
  const [filter, setFilter] = useUrlFilterValue({
1398
- keyword: true, // 单选
1399
- city: { multi: true }, // 多选
1400
- status: (parsed) => { // 自定义转换
1670
+ keyword: true, // 单选
1671
+ city: { multi: true }, // 多选
1672
+ status: parsed => {
1673
+ // 自定义转换
1401
1674
  return parsed ? { name: 'status', value: parsed } : null;
1402
1675
  }
1403
1676
  });
@@ -1410,11 +1683,12 @@ const [filter, setFilter] = useUrlFilterValue({
1410
1683
 
1411
1684
  创建通用 URL 参数读取器,自动追踪已消费的参数 key。
1412
1685
 
1413
- | 参数 | 类型 | 说明 |
1414
- |--------------|-------------------|----------|
1686
+ | 参数 | 类型 | 说明 |
1687
+ | ------------ | ----------------- | ------------ |
1415
1688
  | searchParams | `URLSearchParams` | URL 参数对象 |
1416
1689
 
1417
1690
  **返回值**:`{ take, getConsumedKeys }`
1691
+
1418
1692
  - `take(key)` - 读取参数值,记录已消费
1419
1693
  - `getConsumedKeys()` - 返回已消费的 key 列表
1420
1694
 
@@ -1433,10 +1707,10 @@ const orgName = take('orgName');
1433
1707
 
1434
1708
  从 URL 参数中移除已消费的 key,返回新的 URLSearchParams 或 null(无变化时)。
1435
1709
 
1436
- | 参数 | 类型 | 说明 |
1437
- |--------------|-------------------|-------------------|
1438
- | searchParams | `URLSearchParams` | 当前 URL 参数 |
1439
- | consumedKeys | `string[]` | 需要移除的 key 列表 |
1710
+ | 参数 | 类型 | 说明 |
1711
+ | ------------ | ----------------- | ------------------- |
1712
+ | searchParams | `URLSearchParams` | 当前 URL 参数 |
1713
+ | consumedKeys | `string[]` | 需要移除的 key 列表 |
1440
1714
 
1441
1715
  **返回值**:`URLSearchParams | null`
1442
1716
 
@@ -1459,19 +1733,19 @@ if (nextParams) {
1459
1733
 
1460
1734
  单选拦截器:`{id, name}` ↔ `{label, value}`。
1461
1735
 
1462
- | 属性 | 类型 | 说明 |
1463
- |---------|------------|---------------------------------------|
1464
- | input | `Function` | `{id, name}` → `{label, value}` 的转换 |
1465
- | output | `Function` | `{label, value}` → `{id, name}` 的转换 |
1736
+ | 属性 | 类型 | 说明 |
1737
+ | ------ | ---------- | -------------------------------------- |
1738
+ | input | `Function` | `{id, name}` → `{label, value}` 的转换 |
1739
+ | output | `Function` | `{label, value}` → `{id, name}` 的转换 |
1466
1740
 
1467
1741
  #### multiSelectInterceptor
1468
1742
 
1469
1743
  多选拦截器:`[{id, name}]` ↔ `[{label, value}]`。
1470
1744
 
1471
- | 属性 | 类型 | 说明 |
1472
- |---------|------------|-------------------------------------------|
1473
- | input | `Function` | `[{id, name}]` → `[{label, value}]` 的转换 |
1474
- | output | `Function` | `[{label, value}]` → `[{id, name}]` 的转换 |
1745
+ | 属性 | 类型 | 说明 |
1746
+ | ------ | ---------- | ------------------------------------------ |
1747
+ | input | `Function` | `[{id, name}]` → `[{label, value}]` 的转换 |
1748
+ | output | `Function` | `[{label, value}]` → `[{id, name}]` 的转换 |
1475
1749
 
1476
1750
  #### filterInterceptors
1477
1751
 
@@ -1482,7 +1756,7 @@ import { filterInterceptors, singleSelectInterceptor, multiSelectInterceptor } f
1482
1756
 
1483
1757
  // 两种引用方式等价
1484
1758
  filterInterceptors.single === singleSelectInterceptor; // true
1485
- filterInterceptors.multi === multiSelectInterceptor; // true
1759
+ filterInterceptors.multi === multiSelectInterceptor; // true
1486
1760
  ```
1487
1761
 
1488
1762
  **使用示例:**
@@ -1515,8 +1789,8 @@ import { filterInterceptors } from '@kne/react-filter';
1515
1789
 
1516
1790
  从筛选值中提取原始值数组。支持原始值、`{ value }` 对象、`{ id }` 对象以及它们的数组。
1517
1791
 
1518
- | 参数 | 类型 | 说明 |
1519
- |-------|-------|-------------|
1792
+ | 参数 | 类型 | 说明 |
1793
+ | ----- | ----- | -------------------- |
1520
1794
  | value | `any` | 筛选值,支持多种格式 |
1521
1795
 
1522
1796
  ```javascript
@@ -1536,17 +1810,17 @@ pickSelectValues(null);
1536
1810
 
1537
1811
  声明式创建 mapFilterValue 函数。`Filter.getFilterValue` 默认只读取 `{ value }`,而 SuperSelectFilterItem 等组件使用 `{ id, name }` 格式,需要额外处理。此工具通过声明字段映射规则,自动生成转换函数。
1538
1812
 
1539
- | 参数 | 类型 | 说明 |
1540
- |--------------|----------|-------------------|
1541
- | fieldMappers | `Object` | 字段名到映射规则的映射 |
1813
+ | 参数 | 类型 | 说明 |
1814
+ | ------------ | -------- | ---------------------- |
1815
+ | fieldMappers | `Object` | 字段名到映射规则的映射 |
1542
1816
 
1543
1817
  **映射规则类型:**
1544
1818
 
1545
- | 规则 | 说明 |
1546
- |-----------|----------------------------------------|
1547
- | `'string'` | 确保值为字符串类型 |
1548
- | `'multi'` | 多选,从 filter entry 提取值数组 |
1549
- | `'single'` | 单选,从 filter entry 提取第一个值 |
1819
+ | 规则 | 说明 |
1820
+ | ---------- | ------------------------------------------------------- |
1821
+ | `'string'` | 确保值为字符串类型 |
1822
+ | `'multi'` | 多选,从 filter entry 提取值数组 |
1823
+ | `'single'` | 单选,从 filter entry 提取第一个值 |
1550
1824
  | `Function` | 自定义转换,接收 `(rawValue, { entry, filter, value })` |
1551
1825
 
1552
1826
  ```javascript
@@ -1556,7 +1830,7 @@ const mapFilterValue = createFilterValueMapper({
1556
1830
  id: 'string',
1557
1831
  roles: 'multi',
1558
1832
  tenantOrgId: 'single',
1559
- status: (rawValue) => normalizeStatus(rawValue)
1833
+ status: rawValue => normalizeStatus(rawValue)
1560
1834
  });
1561
1835
 
1562
1836
  const filterValue = mapFilterValue(filter, Filter.getFilterValue);