@ahoo-wang/fetcher-viewer 2.15.1 โ 2.15.2
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 +413 -49
- package/README.zh-CN.md +412 -0
- package/dist/components/RemoteSelect.d.ts +22 -0
- package/dist/components/RemoteSelect.d.ts.map +1 -0
- package/dist/components/index.d.ts +1 -0
- package/dist/components/index.d.ts.map +1 -1
- package/dist/index.es.js +500 -1513
- package/dist/index.es.js.map +1 -1
- package/dist/index.umd.js +1 -59
- package/dist/index.umd.js.map +1 -1
- package/package.json +10 -10
package/README.md
CHANGED
|
@@ -1,49 +1,413 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
-
|
|
7
|
-
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
##
|
|
14
|
-
|
|
15
|
-
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
-
|
|
19
|
-
-
|
|
20
|
-
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
1
|
+
# @ahoo-wang/fetcher-viewer
|
|
2
|
+
|
|
3
|
+
[](https://www.npmjs.com/package/@ahoo-wang/fetcher-viewer)
|
|
4
|
+
[](https://github.com/Ahoo-Wang/fetcher/actions)
|
|
5
|
+
[](https://codecov.io/gh/Ahoo-Wang/fetcher)
|
|
6
|
+
[](https://github.com/Ahoo-Wang/fetcher/blob/main/LICENSE)
|
|
7
|
+
[](https://www.npmjs.com/package/@ahoo-wang/fetcher-viewer)
|
|
8
|
+
[](https://www.npmjs.com/package/@ahoo-wang/fetcher-viewer)
|
|
9
|
+
[](https://deepwiki.com/Ahoo-Wang/fetcher)
|
|
10
|
+
|
|
11
|
+
A comprehensive React component library for data visualization and filtering, built on top of Ant Design and the Fetcher ecosystem. Provides reusable UI components for building rich data-driven applications with advanced filtering capabilities.
|
|
12
|
+
|
|
13
|
+
## โจ Features
|
|
14
|
+
|
|
15
|
+
- **๐ Advanced Filtering System**: Complete filter panel with dynamic filter types, operators, and state management
|
|
16
|
+
- **๐ Data Components**: Remote search select, tag input, number range inputs
|
|
17
|
+
- **๐จ Ant Design Integration**: Seamless integration with Ant Design components
|
|
18
|
+
- **๐ง TypeScript First**: Full TypeScript support with comprehensive type definitions
|
|
19
|
+
- **โก Performance Optimized**: Debounced search, efficient rendering, and optimized state management
|
|
20
|
+
- **๐งช Well Tested**: Comprehensive test coverage with Vitest and React Testing Library
|
|
21
|
+
|
|
22
|
+
## ๐ฆ Installation
|
|
23
|
+
|
|
24
|
+
```bash
|
|
25
|
+
# Using npm
|
|
26
|
+
npm install @ahoo-wang/fetcher-viewer
|
|
27
|
+
|
|
28
|
+
# Using yarn
|
|
29
|
+
yarn add @ahoo-wang/fetcher-viewer
|
|
30
|
+
|
|
31
|
+
# Using pnpm
|
|
32
|
+
pnpm add @ahoo-wang/fetcher-viewer
|
|
33
|
+
```
|
|
34
|
+
|
|
35
|
+
## ๐ Quick Start
|
|
36
|
+
|
|
37
|
+
```tsx
|
|
38
|
+
import {
|
|
39
|
+
RemoteSelect,
|
|
40
|
+
TagInput,
|
|
41
|
+
NumberRange,
|
|
42
|
+
FilterPanel,
|
|
43
|
+
} from '@ahoo-wang/fetcher-viewer';
|
|
44
|
+
import { useFilterState } from '@ahoo-wang/fetcher-viewer';
|
|
45
|
+
|
|
46
|
+
// Basic usage
|
|
47
|
+
function App() {
|
|
48
|
+
const { filters, addFilter, removeFilter, updateFilter } = useFilterState();
|
|
49
|
+
|
|
50
|
+
return (
|
|
51
|
+
<div>
|
|
52
|
+
{/* Remote search select */}
|
|
53
|
+
<RemoteSelect
|
|
54
|
+
search={async query => {
|
|
55
|
+
const response = await fetch(`/api/search?q=${query}`);
|
|
56
|
+
return response.json();
|
|
57
|
+
}}
|
|
58
|
+
placeholder="Search for items..."
|
|
59
|
+
/>
|
|
60
|
+
|
|
61
|
+
{/* Tag input */}
|
|
62
|
+
<TagInput value={['tag1', 'tag2']} onChange={tags => console.log(tags)} />
|
|
63
|
+
|
|
64
|
+
{/* Number range */}
|
|
65
|
+
<NumberRange value={[100, 500]} onChange={range => console.log(range)} />
|
|
66
|
+
|
|
67
|
+
{/* Advanced filter panel */}
|
|
68
|
+
<FilterPanel
|
|
69
|
+
filters={filters}
|
|
70
|
+
onAddFilter={addFilter}
|
|
71
|
+
onRemoveFilter={removeFilter}
|
|
72
|
+
onUpdateFilter={updateFilter}
|
|
73
|
+
/>
|
|
74
|
+
</div>
|
|
75
|
+
);
|
|
76
|
+
}
|
|
77
|
+
```
|
|
78
|
+
|
|
79
|
+
## ๐ API Reference
|
|
80
|
+
|
|
81
|
+
### Components
|
|
82
|
+
|
|
83
|
+
#### RemoteSelect
|
|
84
|
+
|
|
85
|
+
A debounced search select component that fetches options from a remote API.
|
|
86
|
+
|
|
87
|
+
```tsx
|
|
88
|
+
import { RemoteSelect } from '@ahoo-wang/fetcher-viewer';
|
|
89
|
+
|
|
90
|
+
<RemoteSelect
|
|
91
|
+
search={async (query: string) => {
|
|
92
|
+
// Return array of options
|
|
93
|
+
return [
|
|
94
|
+
{ label: 'Option 1', value: '1' },
|
|
95
|
+
{ label: 'Option 2', value: '2' },
|
|
96
|
+
];
|
|
97
|
+
}}
|
|
98
|
+
debounce={{ delay: 300 }}
|
|
99
|
+
placeholder="Search..."
|
|
100
|
+
onChange={value => console.log(value)}
|
|
101
|
+
/>;
|
|
102
|
+
```
|
|
103
|
+
|
|
104
|
+
**Props:**
|
|
105
|
+
|
|
106
|
+
- `search: (query: string) => Promise<RemoteSelectOption[]>` - Search function
|
|
107
|
+
- `debounce?: UseDebouncedCallbackOptions` - Debounce configuration
|
|
108
|
+
- `...SelectProps` - All Ant Design Select props
|
|
109
|
+
|
|
110
|
+
#### TagInput
|
|
111
|
+
|
|
112
|
+
A tag input component with serialization support for different value types.
|
|
113
|
+
|
|
114
|
+
```tsx
|
|
115
|
+
import { TagInput, StringTagValueItemSerializer, NumberTagValueItemSerializer } from '@ahoo-wang/fetcher-viewer';
|
|
116
|
+
|
|
117
|
+
// String tags
|
|
118
|
+
<TagInput
|
|
119
|
+
value={['tag1', 'tag2']}
|
|
120
|
+
onChange={(tags) => console.log(tags)}
|
|
121
|
+
/>
|
|
122
|
+
|
|
123
|
+
// Number tags
|
|
124
|
+
<TagInput<number>
|
|
125
|
+
value={[1, 2, 3]}
|
|
126
|
+
serializer={NumberTagValueItemSerializer}
|
|
127
|
+
onChange={(tags) => console.log(tags)}
|
|
128
|
+
/>
|
|
129
|
+
```
|
|
130
|
+
|
|
131
|
+
**Props:**
|
|
132
|
+
|
|
133
|
+
- `value?: ValueItemType[]` - Current tag values
|
|
134
|
+
- `serializer?: TagValueItemSerializer` - Value serializer
|
|
135
|
+
- `onChange?: (value: ValueItemType[]) => void` - Change handler
|
|
136
|
+
- `...SelectProps` - Additional Ant Design Select props
|
|
137
|
+
|
|
138
|
+
#### NumberRange
|
|
139
|
+
|
|
140
|
+
A number range input component with min/max validation.
|
|
141
|
+
|
|
142
|
+
```tsx
|
|
143
|
+
import { NumberRange } from '@ahoo-wang/fetcher-viewer';
|
|
144
|
+
|
|
145
|
+
<NumberRange
|
|
146
|
+
value={[100, 500]}
|
|
147
|
+
min={0}
|
|
148
|
+
max={1000}
|
|
149
|
+
precision={2}
|
|
150
|
+
placeholder={['Min', 'Max']}
|
|
151
|
+
onChange={range => console.log(range)}
|
|
152
|
+
/>;
|
|
153
|
+
```
|
|
154
|
+
|
|
155
|
+
**Props:**
|
|
156
|
+
|
|
157
|
+
- `value?: number | NumberRangeValue` - Current range value
|
|
158
|
+
- `min?: number` - Minimum allowed value
|
|
159
|
+
- `max?: number` - Maximum allowed value
|
|
160
|
+
- `precision?: number` - Decimal precision
|
|
161
|
+
- `placeholder?: string[]` - Input placeholders
|
|
162
|
+
- `onChange?: (value: NumberRangeValue) => void` - Change handler
|
|
163
|
+
|
|
164
|
+
### Filter System
|
|
165
|
+
|
|
166
|
+
#### FilterPanel
|
|
167
|
+
|
|
168
|
+
A comprehensive filter panel with dynamic filter management.
|
|
169
|
+
|
|
170
|
+
```tsx
|
|
171
|
+
import { FilterPanel, useFilterState } from '@ahoo-wang/fetcher-viewer';
|
|
172
|
+
|
|
173
|
+
function MyFilterComponent() {
|
|
174
|
+
const { filters, addFilter, removeFilter, updateFilter } = useFilterState();
|
|
175
|
+
|
|
176
|
+
return (
|
|
177
|
+
<FilterPanel
|
|
178
|
+
filters={filters}
|
|
179
|
+
availableFilters={[
|
|
180
|
+
{ name: 'name', label: 'Name', type: 'text' },
|
|
181
|
+
{ name: 'age', label: 'Age', type: 'number' },
|
|
182
|
+
{ name: 'status', label: 'Status', type: 'select' },
|
|
183
|
+
]}
|
|
184
|
+
onAddFilter={addFilter}
|
|
185
|
+
onRemoveFilter={removeFilter}
|
|
186
|
+
onUpdateFilter={updateFilter}
|
|
187
|
+
/>
|
|
188
|
+
);
|
|
189
|
+
}
|
|
190
|
+
```
|
|
191
|
+
|
|
192
|
+
#### useFilterState Hook
|
|
193
|
+
|
|
194
|
+
State management hook for filter operations.
|
|
195
|
+
|
|
196
|
+
```tsx
|
|
197
|
+
import { useFilterState } from '@ahoo-wang/fetcher-viewer';
|
|
198
|
+
|
|
199
|
+
const {
|
|
200
|
+
filters, // Current filters array
|
|
201
|
+
addFilter, // Add new filter
|
|
202
|
+
removeFilter, // Remove filter
|
|
203
|
+
updateFilter, // Update filter
|
|
204
|
+
clearFilters, // Clear all filters
|
|
205
|
+
getFilterValue, // Get filter value
|
|
206
|
+
setFilterValue, // Set filter value
|
|
207
|
+
resetFilters, // Reset to initial state
|
|
208
|
+
} = useFilterState(initialFilters);
|
|
209
|
+
```
|
|
210
|
+
|
|
211
|
+
#### Filter Types
|
|
212
|
+
|
|
213
|
+
The library provides several built-in filter types:
|
|
214
|
+
|
|
215
|
+
- **TextFilter**: Text input with various operators (=, !=, contains, etc.)
|
|
216
|
+
- **NumberFilter**: Number input with comparison operators
|
|
217
|
+
- **SelectFilter**: Dropdown selection filter
|
|
218
|
+
- **IdFilter**: ID-based filter
|
|
219
|
+
- **AssemblyFilter**: Composite filter combining multiple conditions
|
|
220
|
+
|
|
221
|
+
#### Custom Filters
|
|
222
|
+
|
|
223
|
+
Create custom filter components by implementing the `FilterProps` interface:
|
|
224
|
+
|
|
225
|
+
```tsx
|
|
226
|
+
import { FilterProps, FilterValue } from '@ahoo-wang/fetcher-viewer';
|
|
227
|
+
|
|
228
|
+
function CustomFilter({ field, onChange, value }: FilterProps) {
|
|
229
|
+
return (
|
|
230
|
+
<div>
|
|
231
|
+
<label>{field.label}</label>
|
|
232
|
+
<input
|
|
233
|
+
value={value?.value || ''}
|
|
234
|
+
onChange={e =>
|
|
235
|
+
onChange?.({
|
|
236
|
+
field: field.name,
|
|
237
|
+
operator: 'eq',
|
|
238
|
+
value: e.target.value,
|
|
239
|
+
})
|
|
240
|
+
}
|
|
241
|
+
/>
|
|
242
|
+
</div>
|
|
243
|
+
);
|
|
244
|
+
}
|
|
245
|
+
```
|
|
246
|
+
|
|
247
|
+
## ๐จ Theming & Styling
|
|
248
|
+
|
|
249
|
+
The components inherit Ant Design's theming system. You can customize the appearance using Ant Design's theme configuration:
|
|
250
|
+
|
|
251
|
+
```tsx
|
|
252
|
+
import { ConfigProvider } from 'antd';
|
|
253
|
+
|
|
254
|
+
<ConfigProvider
|
|
255
|
+
theme={
|
|
256
|
+
{
|
|
257
|
+
/* your theme config */
|
|
258
|
+
}
|
|
259
|
+
}
|
|
260
|
+
>
|
|
261
|
+
<RemoteSelect search={searchFunction} />
|
|
262
|
+
</ConfigProvider>;
|
|
263
|
+
```
|
|
264
|
+
|
|
265
|
+
## ๐ Internationalization
|
|
266
|
+
|
|
267
|
+
The filter system supports multiple languages. Currently supported locales:
|
|
268
|
+
|
|
269
|
+
- **English** (default)
|
|
270
|
+
- **Chinese** (`zh_CN`)
|
|
271
|
+
|
|
272
|
+
```tsx
|
|
273
|
+
import { FilterPanel } from '@ahoo-wang/fetcher-viewer';
|
|
274
|
+
import { zh_CN } from '@ahoo-wang/fetcher-viewer/locale';
|
|
275
|
+
|
|
276
|
+
<FilterPanel
|
|
277
|
+
locale={zh_CN}
|
|
278
|
+
// ... other props
|
|
279
|
+
/>;
|
|
280
|
+
```
|
|
281
|
+
|
|
282
|
+
## ๐งช Testing
|
|
283
|
+
|
|
284
|
+
The library includes comprehensive tests. Run tests with:
|
|
285
|
+
|
|
286
|
+
```bash
|
|
287
|
+
# Run all tests
|
|
288
|
+
npm test
|
|
289
|
+
|
|
290
|
+
# Run tests with coverage
|
|
291
|
+
npm run test:coverage
|
|
292
|
+
|
|
293
|
+
# Run tests in UI mode
|
|
294
|
+
npm run test:ui
|
|
295
|
+
```
|
|
296
|
+
|
|
297
|
+
## ๐ Examples
|
|
298
|
+
|
|
299
|
+
### Basic Data Table with Filters
|
|
300
|
+
|
|
301
|
+
```tsx
|
|
302
|
+
import React, { useState, useEffect } from 'react';
|
|
303
|
+
import {
|
|
304
|
+
FilterPanel,
|
|
305
|
+
useFilterState,
|
|
306
|
+
RemoteSelect,
|
|
307
|
+
} from '@ahoo-wang/fetcher-viewer';
|
|
308
|
+
import { Table } from 'antd';
|
|
309
|
+
|
|
310
|
+
function DataTable() {
|
|
311
|
+
const [data, setData] = useState([]);
|
|
312
|
+
const [loading, setLoading] = useState(false);
|
|
313
|
+
const { filters, addFilter, removeFilter, updateFilter } = useFilterState();
|
|
314
|
+
|
|
315
|
+
useEffect(() => {
|
|
316
|
+
fetchData();
|
|
317
|
+
}, [filters]);
|
|
318
|
+
|
|
319
|
+
const fetchData = async () => {
|
|
320
|
+
setLoading(true);
|
|
321
|
+
try {
|
|
322
|
+
const query = buildQueryFromFilters(filters);
|
|
323
|
+
const response = await fetch(`/api/data?${query}`);
|
|
324
|
+
const result = await response.json();
|
|
325
|
+
setData(result);
|
|
326
|
+
} finally {
|
|
327
|
+
setLoading(false);
|
|
328
|
+
}
|
|
329
|
+
};
|
|
330
|
+
|
|
331
|
+
return (
|
|
332
|
+
<div>
|
|
333
|
+
<FilterPanel
|
|
334
|
+
filters={filters}
|
|
335
|
+
availableFilters={FILTER_CONFIG}
|
|
336
|
+
onAddFilter={addFilter}
|
|
337
|
+
onRemoveFilter={removeFilter}
|
|
338
|
+
onUpdateFilter={updateFilter}
|
|
339
|
+
/>
|
|
340
|
+
|
|
341
|
+
<Table dataSource={data} loading={loading} columns={COLUMNS} />
|
|
342
|
+
</div>
|
|
343
|
+
);
|
|
344
|
+
}
|
|
345
|
+
```
|
|
346
|
+
|
|
347
|
+
### Advanced Search Component
|
|
348
|
+
|
|
349
|
+
```tsx
|
|
350
|
+
import { RemoteSelect, TagInput } from '@ahoo-wang/fetcher-viewer';
|
|
351
|
+
|
|
352
|
+
function AdvancedSearch() {
|
|
353
|
+
const [selectedTags, setSelectedTags] = useState([]);
|
|
354
|
+
const [selectedItems, setSelectedItems] = useState([]);
|
|
355
|
+
|
|
356
|
+
return (
|
|
357
|
+
<div className="search-container">
|
|
358
|
+
<RemoteSelect
|
|
359
|
+
search={async query => {
|
|
360
|
+
const response = await api.search(query);
|
|
361
|
+
return response.map(item => ({
|
|
362
|
+
label: item.name,
|
|
363
|
+
value: item.id,
|
|
364
|
+
}));
|
|
365
|
+
}}
|
|
366
|
+
mode="multiple"
|
|
367
|
+
placeholder="Search items..."
|
|
368
|
+
value={selectedItems}
|
|
369
|
+
onChange={setSelectedItems}
|
|
370
|
+
/>
|
|
371
|
+
|
|
372
|
+
<TagInput
|
|
373
|
+
placeholder="Add tags..."
|
|
374
|
+
value={selectedTags}
|
|
375
|
+
onChange={setSelectedTags}
|
|
376
|
+
/>
|
|
377
|
+
</div>
|
|
378
|
+
);
|
|
379
|
+
}
|
|
380
|
+
```
|
|
381
|
+
|
|
382
|
+
## ๐ค Contributing
|
|
383
|
+
|
|
384
|
+
We welcome contributions! Please see our [Contributing Guide](../../CONTRIBUTING.md) for details.
|
|
385
|
+
|
|
386
|
+
1. Fork the repository
|
|
387
|
+
2. Create your feature branch (`git checkout -b feature/amazing-feature`)
|
|
388
|
+
3. Commit your changes (`git commit -m 'Add some amazing feature'`)
|
|
389
|
+
4. Push to the branch (`git push origin feature/amazing-feature`)
|
|
390
|
+
5. Open a Pull Request
|
|
391
|
+
|
|
392
|
+
## ๐ License
|
|
393
|
+
|
|
394
|
+
This project is licensed under the Apache License 2.0 - see the [LICENSE](../../LICENSE) file for details.
|
|
395
|
+
|
|
396
|
+
## ๐ Acknowledgments
|
|
397
|
+
|
|
398
|
+
- [Ant Design](https://ant.design/) - UI component library
|
|
399
|
+
- [Fetcher](https://github.com/Ahoo-Wang/fetcher) - HTTP client ecosystem
|
|
400
|
+
- [React](https://reactjs.org/) - UI framework
|
|
401
|
+
- [TypeScript](https://www.typescriptlang.org/) - Type safety
|
|
402
|
+
|
|
403
|
+
## ๐ Support
|
|
404
|
+
|
|
405
|
+
- ๐ [Documentation](https://github.com/Ahoo-Wang/fetcher/tree/master/packages/fetcher-viewer)
|
|
406
|
+
- ๐ [Issues](https://github.com/Ahoo-Wang/fetcher/issues)
|
|
407
|
+
- ๐ฌ [Discussions](https://github.com/Ahoo-Wang/fetcher/discussions)
|
|
408
|
+
|
|
409
|
+
---
|
|
410
|
+
|
|
411
|
+
Made with โค๏ธ by the Fetcher team</content>
|
|
412
|
+
</xai:function_call">Now I need to create the Chinese version of the README as well. Let me create README.zh-CN.md</content>
|
|
413
|
+
</xai:function_call">Now I need to create the Chinese version of the README as well. Let me create README.zh-CN.md
|