@ahoo-wang/fetcher-viewer 3.15.2 → 3.15.3

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
@@ -166,10 +166,10 @@ import { NumberRange } from '@ahoo-wang/fetcher-viewer';
166
166
 
167
167
  #### FilterPanel
168
168
 
169
- A comprehensive filter panel with dynamic filter management.
169
+ A comprehensive filter panel with dynamic filter management. The panel uses `TypedFilter` components registered in the `filterRegistry` to render filters based on their type string.
170
170
 
171
171
  ```tsx
172
- import { FilterPanel, useFilterState } from '@ahoo-wang/fetcher-viewer';
172
+ import { FilterPanel, useFilterState, filterRegistry } from '@ahoo-wang/fetcher-viewer';
173
173
 
174
174
  function MyFilterComponent() {
175
175
  const { filters, addFilter, removeFilter, updateFilter } = useFilterState();
@@ -177,11 +177,6 @@ function MyFilterComponent() {
177
177
  return (
178
178
  <FilterPanel
179
179
  filters={filters}
180
- availableFilters={[
181
- { name: 'name', label: 'Name', type: 'text' },
182
- { name: 'age', label: 'Age', type: 'number' },
183
- { name: 'status', label: 'Status', type: 'select' },
184
- ]}
185
180
  onAddFilter={addFilter}
186
181
  onRemoveFilter={removeFilter}
187
182
  onUpdateFilter={updateFilter}
@@ -190,6 +185,30 @@ function MyFilterComponent() {
190
185
  }
191
186
  ```
192
187
 
188
+ **How Filter Resolution Works:**
189
+
190
+ The `filterRegistry` maps filter type strings to their corresponding `TypedFilter` components:
191
+
192
+ - `'id'` - IdFilter
193
+ - `'text'` - TextFilter
194
+ - `'number'` - NumberFilter
195
+ - `'select'` - SelectFilter
196
+ - `'bool'` - BoolFilter
197
+ - `'dateTime'` - DateTimeFilter
198
+
199
+ When a filter with an unknown type is encountered, `FallbackFilter` is rendered instead, displaying a warning message.
200
+
201
+ #### FallbackFilter
202
+
203
+ Rendered when a filter type is not registered in the `filterRegistry`. It displays a warning alert indicating the unsupported filter type.
204
+
205
+ ```tsx
206
+ import { FallbackFilter } from '@ahoo-wang/fetcher-viewer';
207
+
208
+ // FallbackFilter automatically displays for unknown filter types
209
+ // e.g., when a filter with type: 'customType' is used but no handler is registered
210
+ ```
211
+
193
212
  #### useFilterState Hook
194
213
 
195
214
  State management hook for filter operations.
@@ -217,7 +236,8 @@ The library provides several built-in filter types:
217
236
  - **NumberFilter**: Number input with comparison operators
218
237
  - **SelectFilter**: Dropdown selection filter
219
238
  - **IdFilter**: ID-based filter
220
- - **AssemblyFilter**: Composite filter combining multiple conditions
239
+ - **BoolFilter**: Boolean filter with true/false operators
240
+ - **DateTimeFilter**: Date/time filter with date-specific operators
221
241
 
222
242
  #### Custom Filters
223
243
 
@@ -245,6 +265,218 @@ function CustomFilter({ field, onChange, value }: FilterProps) {
245
265
  }
246
266
  ```
247
267
 
268
+ ### Cell Components
269
+
270
+ The library provides various cell components for rendering different data types in tables. All cell components accept a `CellProps` structure with `data` (containing `value`, `record`, and `index`) and optional `attributes`.
271
+
272
+ #### TextCell
273
+
274
+ Renders plain text with optional ellipsis truncation.
275
+
276
+ ```tsx
277
+ import { TextCell, TEXT_CELL_TYPE } from '@ahoo-wang/fetcher-viewer';
278
+
279
+ <TextCell
280
+ data={{ value: 'Hello', record: { id: 1 }, index: 0 }}
281
+ attributes={{ ellipsis: true }}
282
+ />
283
+ ```
284
+
285
+ #### TagCell
286
+
287
+ Renders a single tag with customizable color.
288
+
289
+ ```tsx
290
+ import { TagCell, TAG_CELL_TYPE } from '@ahoo-wang/fetcher-viewer';
291
+
292
+ <TagCell
293
+ data={{ value: 'urgent', record: { id: 1 }, index: 0 }}
294
+ attributes={{ color: 'red' }}
295
+ />
296
+ ```
297
+
298
+ #### TagsCell
299
+
300
+ Renders multiple tags with customizable color.
301
+
302
+ ```tsx
303
+ import { TagsCell, TAGS_CELL_TYPE } from '@ahoo-wang/fetcher-viewer';
304
+
305
+ <TagsCell
306
+ data={{ value: ['urgent', 'high'], record: { id: 1 }, index: 0 }}
307
+ attributes={{ color: 'blue' }}
308
+ />
309
+ ```
310
+
311
+ #### ActionCell
312
+
313
+ Renders a clickable action button. The `onClick` handler receives the full record.
314
+
315
+ ```tsx
316
+ import { ActionCell, ACTION_CELL_TYPE } from '@ahoo-wang/fetcher-viewer';
317
+
318
+ <ActionCell
319
+ data={{
320
+ value: 'Edit',
321
+ record: { id: 1, name: 'Item' },
322
+ index: 0
323
+ }}
324
+ attributes={{
325
+ onClick: (record) => console.log('Edit:', record),
326
+ danger: true
327
+ }}
328
+ />
329
+ ```
330
+
331
+ #### ActionsCell
332
+
333
+ Renders multiple actions with a primary action and a dropdown menu for secondary actions.
334
+
335
+ ```tsx
336
+ import { ActionsCell, ACTIONS_CELL_TYPE } from '@ahoo-wang/fetcher-viewer';
337
+
338
+ <ActionsCell
339
+ data={{
340
+ value: {
341
+ primaryAction: {
342
+ data: { value: 'Edit', record: item, index: 0 },
343
+ attributes: { onClick: () => editItem(item.id) }
344
+ },
345
+ moreActionTitle: 'More',
346
+ secondaryActions: [
347
+ {
348
+ data: { value: 'Delete', record: item, index: 0 },
349
+ attributes: { onClick: () => deleteItem(item.id), danger: true }
350
+ }
351
+ ]
352
+ },
353
+ record: item,
354
+ index: 0
355
+ }}
356
+ attributes={{
357
+ onClick: (actionKey, record) => console.log(actionKey, record)
358
+ }}
359
+ />
360
+ ```
361
+
362
+ #### AvatarCell
363
+
364
+ Renders an avatar image or initials fallback.
365
+
366
+ ```tsx
367
+ import { AvatarCell, AVATAR_CELL_TYPE } from '@ahoo-wang/fetcher-viewer';
368
+
369
+ // With image URL
370
+ <AvatarCell
371
+ data={{
372
+ value: 'https://example.com/avatar.jpg',
373
+ record: { id: 1, name: 'John' },
374
+ index: 0
375
+ }}
376
+ attributes={{ size: 40 }}
377
+ />
378
+
379
+ // With initials fallback
380
+ <AvatarCell
381
+ data={{
382
+ value: 'John Doe',
383
+ record: { id: 1, name: 'John Doe' },
384
+ index: 0
385
+ }}
386
+ attributes={{ size: 40, style: { backgroundColor: '#1890ff' } }}
387
+ />
388
+ ```
389
+
390
+ #### CurrencyCell
391
+
392
+ Renders formatted currency values.
393
+
394
+ ```tsx
395
+ import { CurrencyCell, CURRENCY_CELL_TYPE } from '@ahoo-wang/fetcher-viewer';
396
+
397
+ <CurrencyCell
398
+ data={{
399
+ value: 1234.56,
400
+ record: { id: 1, amount: 1234.56 },
401
+ index: 0
402
+ }}
403
+ attributes={{
404
+ format: { currency: 'USD', locale: 'en-US', decimals: 2 },
405
+ style: { fontWeight: 'bold' }
406
+ }}
407
+ />
408
+ ```
409
+
410
+ #### DateTimeCell
411
+
412
+ Renders formatted datetime values with customizable format.
413
+
414
+ ```tsx
415
+ import { DateTimeCell, DATETIME_CELL_TYPE } from '@ahoo-wang/fetcher-viewer';
416
+
417
+ <DateTimeCell
418
+ data={{
419
+ value: '2024-01-15T10:30:00Z',
420
+ record: { id: 1, createdAt: '2024-01-15T10:30:00Z' },
421
+ index: 0
422
+ }}
423
+ attributes={{
424
+ format: 'YYYY-MM-DD HH:mm:ss'
425
+ }}
426
+ />
427
+ ```
428
+
429
+ #### ImageCell
430
+
431
+ Renders an image with preview support.
432
+
433
+ ```tsx
434
+ import { ImageCell, IMAGE_CELL_TYPE } from '@ahoo-wang/fetcher-viewer';
435
+
436
+ <ImageCell
437
+ data={{
438
+ value: 'https://example.com/image.jpg',
439
+ record: { id: 1, image: 'https://example.com/image.jpg' },
440
+ index: 0
441
+ }}
442
+ attributes={{ width: 80, height: 80, preview: true }}
443
+ />
444
+ ```
445
+
446
+ #### ImageGroupCell
447
+
448
+ Renders a group of images with badge count and preview support.
449
+
450
+ ```tsx
451
+ import { ImageGroupCell, IMAGE_GROUP_CELL_TYPE } from '@ahoo-wang/fetcher-viewer';
452
+
453
+ <ImageGroupCell
454
+ data={{
455
+ value: ['https://example.com/1.jpg', 'https://example.com/2.jpg'],
456
+ record: { id: 1, images: ['https://example.com/1.jpg', 'https://example.com/2.jpg'] },
457
+ index: 0
458
+ }}
459
+ attributes={{ width: 80, height: 80, preview: true }}
460
+ />
461
+ ```
462
+
463
+ #### LinkCell
464
+
465
+ Renders a clickable link with email auto-detection.
466
+
467
+ ```tsx
468
+ import { LinkCell, LINK_CELL_TYPE } from '@ahoo-wang/fetcher-viewer';
469
+
470
+ <LinkCell
471
+ data={{
472
+ value: 'Visit Website',
473
+ record: { id: 1, url: 'https://example.com' },
474
+ index: 0
475
+ }}
476
+ attributes={{ href: 'https://example.com', target: '_blank' }}
477
+ />
478
+ ```
479
+
248
480
  ## 🎨 Theming & Styling
249
481
 
250
482
  The components inherit Ant Design's theming system. You can customize the appearance using Ant Design's theme configuration:
@@ -333,7 +565,6 @@ function DataTable() {
333
565
  <div>
334
566
  <FilterPanel
335
567
  filters={filters}
336
- availableFilters={FILTER_CONFIG}
337
568
  onAddFilter={addFilter}
338
569
  onRemoveFilter={removeFilter}
339
570
  onUpdateFilter={updateFilter}
package/README.zh-CN.md CHANGED
@@ -166,10 +166,10 @@ import { NumberRange } from '@ahoo-wang/fetcher-viewer';
166
166
 
167
167
  #### FilterPanel
168
168
 
169
- 具有动态过滤器管理的综合过滤面板。
169
+ 具有动态过滤器管理的综合过滤面板。面板使用在 `filterRegistry` 中注册的 `TypedFilter` 组件根据类型字符串渲染过滤器。
170
170
 
171
171
  ```tsx
172
- import { FilterPanel, useFilterState } from '@ahoo-wang/fetcher-viewer';
172
+ import { FilterPanel, useFilterState, filterRegistry } from '@ahoo-wang/fetcher-viewer';
173
173
 
174
174
  function MyFilterComponent() {
175
175
  const { filters, addFilter, removeFilter, updateFilter } = useFilterState();
@@ -177,11 +177,6 @@ function MyFilterComponent() {
177
177
  return (
178
178
  <FilterPanel
179
179
  filters={filters}
180
- availableFilters={[
181
- { name: 'name', label: '名称', type: 'text' },
182
- { name: 'age', label: '年龄', type: 'number' },
183
- { name: 'status', label: '状态', type: 'select' },
184
- ]}
185
180
  onAddFilter={addFilter}
186
181
  onRemoveFilter={removeFilter}
187
182
  onUpdateFilter={updateFilter}
@@ -190,6 +185,30 @@ function MyFilterComponent() {
190
185
  }
191
186
  ```
192
187
 
188
+ **过滤器解析工作原理:**
189
+
190
+ `filterRegistry` 将过滤器类型字符串映射到对应的 `TypedFilter` 组件:
191
+
192
+ - `'id'` - IdFilter
193
+ - `'text'` - TextFilter
194
+ - `'number'` - NumberFilter
195
+ - `'select'` - SelectFilter
196
+ - `'bool'` - BoolFilter
197
+ - `'dateTime'` - DateTimeFilter
198
+
199
+ 当遇到未知类型的过滤器时,将渲染 `FallbackFilter` 并显示警告提示。
200
+
201
+ #### FallbackFilter
202
+
203
+ 当过滤器类型未在 `filterRegistry` 中注册时渲染。它显示一个警告提示,表示不支持该过滤器类型。
204
+
205
+ ```tsx
206
+ import { FallbackFilter } from '@ahoo-wang/fetcher-viewer';
207
+
208
+ // FallbackFilter 会自动为未知过滤器类型显示
209
+ // 例如,当使用 type: 'customType' 的过滤器但没有注册处理器时
210
+ ```
211
+
193
212
  #### useFilterState Hook
194
213
 
195
214
  过滤器操作的状态管理 hook。
@@ -217,7 +236,8 @@ const {
217
236
  - **NumberFilter**: 数字输入,支持比较操作符
218
237
  - **SelectFilter**: 下拉选择过滤器
219
238
  - **IdFilter**: 基于 ID 的过滤器
220
- - **AssemblyFilter**: 组合多个条件的复合过滤器
239
+ - **BoolFilter**: 布尔过滤器,支持 true/false 操作符
240
+ - **DateTimeFilter**: 日期/时间过滤器,支持日期特定的操作符
221
241
 
222
242
  #### 自定义过滤器
223
243
 
@@ -245,6 +265,218 @@ function CustomFilter({ field, onChange, value }: FilterProps) {
245
265
  }
246
266
  ```
247
267
 
268
+ ### Cell 组件
269
+
270
+ 库提供了多种单元格组件,用于在表格中渲染不同数据类型。所有单元格组件都接受包含 `data`(包含 `value`、`record` 和 `index`)和可选 `attributes` 的 `CellProps` 结构。
271
+
272
+ #### TextCell
273
+
274
+ 渲染纯文本,可选省略号截断。
275
+
276
+ ```tsx
277
+ import { TextCell, TEXT_CELL_TYPE } from '@ahoo-wang/fetcher-viewer';
278
+
279
+ <TextCell
280
+ data={{ value: 'Hello', record: { id: 1 }, index: 0 }}
281
+ attributes={{ ellipsis: true }}
282
+ />
283
+ ```
284
+
285
+ #### TagCell
286
+
287
+ 渲染具有可自定义颜色的单个标签。
288
+
289
+ ```tsx
290
+ import { TagCell, TAG_CELL_TYPE } from '@ahoo-wang/fetcher-viewer';
291
+
292
+ <TagCell
293
+ data={{ value: 'urgent', record: { id: 1 }, index: 0 }}
294
+ attributes={{ color: 'red' }}
295
+ />
296
+ ```
297
+
298
+ #### TagsCell
299
+
300
+ 渲染具有可自定义颜色的多个标签。
301
+
302
+ ```tsx
303
+ import { TagsCell, TAGS_CELL_TYPE } from '@ahoo-wang/fetcher-viewer';
304
+
305
+ <TagsCell
306
+ data={{ value: ['urgent', 'high'], record: { id: 1 }, index: 0 }}
307
+ attributes={{ color: 'blue' }}
308
+ />
309
+ ```
310
+
311
+ #### ActionCell
312
+
313
+ 渲染可点击的操作按钮。`onClick` 处理器接收完整记录。
314
+
315
+ ```tsx
316
+ import { ActionCell, ACTION_CELL_TYPE } from '@ahoo-wang/fetcher-viewer';
317
+
318
+ <ActionCell
319
+ data={{
320
+ value: 'Edit',
321
+ record: { id: 1, name: 'Item' },
322
+ index: 0
323
+ }}
324
+ attributes={{
325
+ onClick: (record) => console.log('Edit:', record),
326
+ danger: true
327
+ }}
328
+ />
329
+ ```
330
+
331
+ #### ActionsCell
332
+
333
+ 渲染多个操作,包含一个主要操作和一个用于次要操作的下拉菜单。
334
+
335
+ ```tsx
336
+ import { ActionsCell, ACTIONS_CELL_TYPE } from '@ahoo-wang/fetcher-viewer';
337
+
338
+ <ActionsCell
339
+ data={{
340
+ value: {
341
+ primaryAction: {
342
+ data: { value: 'Edit', record: item, index: 0 },
343
+ attributes: { onClick: () => editItem(item.id) }
344
+ },
345
+ moreActionTitle: '更多',
346
+ secondaryActions: [
347
+ {
348
+ data: { value: 'Delete', record: item, index: 0 },
349
+ attributes: { onClick: () => deleteItem(item.id), danger: true }
350
+ }
351
+ ]
352
+ },
353
+ record: item,
354
+ index: 0
355
+ }}
356
+ attributes={{
357
+ onClick: (actionKey, record) => console.log(actionKey, record)
358
+ }}
359
+ />
360
+ ```
361
+
362
+ #### AvatarCell
363
+
364
+ 渲染头像图片或姓名首字母后备。
365
+
366
+ ```tsx
367
+ import { AvatarCell, AVATAR_CELL_TYPE } from '@ahoo-wang/fetcher-viewer';
368
+
369
+ // 带图片 URL
370
+ <AvatarCell
371
+ data={{
372
+ value: 'https://example.com/avatar.jpg',
373
+ record: { id: 1, name: 'John' },
374
+ index: 0
375
+ }}
376
+ attributes={{ size: 40 }}
377
+ />
378
+
379
+ // 带首字母后备
380
+ <AvatarCell
381
+ data={{
382
+ value: 'John Doe',
383
+ record: { id: 1, name: 'John Doe' },
384
+ index: 0
385
+ }}
386
+ attributes={{ size: 40, style: { backgroundColor: '#1890ff' } }}
387
+ />
388
+ ```
389
+
390
+ #### CurrencyCell
391
+
392
+ 渲染格式化货币值。
393
+
394
+ ```tsx
395
+ import { CurrencyCell, CURRENCY_CELL_TYPE } from '@ahoo-wang/fetcher-viewer';
396
+
397
+ <CurrencyCell
398
+ data={{
399
+ value: 1234.56,
400
+ record: { id: 1, amount: 1234.56 },
401
+ index: 0
402
+ }}
403
+ attributes={{
404
+ format: { currency: 'USD', locale: 'en-US', decimals: 2 },
405
+ style: { fontWeight: 'bold' }
406
+ }}
407
+ />
408
+ ```
409
+
410
+ #### DateTimeCell
411
+
412
+ 渲染具有可自定义格式的格式化日期时间值。
413
+
414
+ ```tsx
415
+ import { DateTimeCell, DATETIME_CELL_TYPE } from '@ahoo-wang/fetcher-viewer';
416
+
417
+ <DateTimeCell
418
+ data={{
419
+ value: '2024-01-15T10:30:00Z',
420
+ record: { id: 1, createdAt: '2024-01-15T10:30:00Z' },
421
+ index: 0
422
+ }}
423
+ attributes={{
424
+ format: 'YYYY-MM-DD HH:mm:ss'
425
+ }}
426
+ />
427
+ ```
428
+
429
+ #### ImageCell
430
+
431
+ 渲染带预览支持的图片。
432
+
433
+ ```tsx
434
+ import { ImageCell, IMAGE_CELL_TYPE } from '@ahoo-wang/fetcher-viewer';
435
+
436
+ <ImageCell
437
+ data={{
438
+ value: 'https://example.com/image.jpg',
439
+ record: { id: 1, image: 'https://example.com/image.jpg' },
440
+ index: 0
441
+ }}
442
+ attributes={{ width: 80, height: 80, preview: true }}
443
+ />
444
+ ```
445
+
446
+ #### ImageGroupCell
447
+
448
+ 渲染图片组,带徽章计数和预览支持。
449
+
450
+ ```tsx
451
+ import { ImageGroupCell, IMAGE_GROUP_CELL_TYPE } from '@ahoo-wang/fetcher-viewer';
452
+
453
+ <ImageGroupCell
454
+ data={{
455
+ value: ['https://example.com/1.jpg', 'https://example.com/2.jpg'],
456
+ record: { id: 1, images: ['https://example.com/1.jpg', 'https://example.com/2.jpg'] },
457
+ index: 0
458
+ }}
459
+ attributes={{ width: 80, height: 80, preview: true }}
460
+ />
461
+ ```
462
+
463
+ #### LinkCell
464
+
465
+ 渲染可点击链接,支持邮箱自动检测。
466
+
467
+ ```tsx
468
+ import { LinkCell, LINK_CELL_TYPE } from '@ahoo-wang/fetcher-viewer';
469
+
470
+ <LinkCell
471
+ data={{
472
+ value: 'Visit Website',
473
+ record: { id: 1, url: 'https://example.com' },
474
+ index: 0
475
+ }}
476
+ attributes={{ href: 'https://example.com', target: '_blank' }}
477
+ />
478
+ ```
479
+
248
480
  ## 🎨 主题和样式
249
481
 
250
482
  组件继承 Ant Design 的主题系统。您可以使用 Ant Design 的主题配置自定义外观:
@@ -333,7 +565,6 @@ function DataTable() {
333
565
  <div>
334
566
  <FilterPanel
335
567
  filters={filters}
336
- availableFilters={FILTER_CONFIG}
337
568
  onAddFilter={addFilter}
338
569
  onRemoveFilter={removeFilter}
339
570
  onUpdateFilter={updateFilter}