@gulibs/react-vtable 0.0.12 → 0.0.13

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
@@ -116,8 +116,9 @@ The table provides **default search behavior** that works automatically:
116
116
  - **Remote Data Mode** (with `request` prop): Search triggers a new data fetch with search parameters passed to the backend.
117
117
 
118
118
  The default filter function supports:
119
- - Case-insensitive string matching (contains)
120
- - Array-based multi-select filtering
119
+ - Case-insensitive string matching (contains) for **text-like** fields
120
+ - **Exact match** for **enum/filter** fields (e.g. `valueEnum`, `filters`, `valueType: 'select' | 'status'`)
121
+ - Array-based multi-select filtering (exact match for enum/filter fields, contains match for text fields)
121
122
  - Automatic handling of empty/null values
122
123
 
123
124
  ```tsx
@@ -230,6 +231,86 @@ function Page() {
230
231
  }
231
232
  ```
232
233
 
234
+ #### Server Pagination (NO `request`, you fetch data yourself)
235
+
236
+ If you **do not** use `request`, but you still want **server-side pagination** (i.e. `dataSource` only contains **current page items**),
237
+ set `pagination.mode: 'server'` to prevent TanStack Table from slicing again.
238
+
239
+ ```tsx
240
+ function Page() {
241
+ const [pagination, setPagination] = useState({ current: 1, pageSize: 10, total: 0 })
242
+ const [data, setData] = useState<any[]>([])
243
+
244
+ const fetchPage = async (current: number, pageSize: number) => {
245
+ const res = await fetchUsers({ current, pageSize })
246
+ setData(res.items)
247
+ setPagination((prev) => ({ ...prev, current, pageSize, total: res.total }))
248
+ }
249
+
250
+ useEffect(() => {
251
+ void fetchPage(pagination.current, pagination.pageSize)
252
+ }, [])
253
+
254
+ return (
255
+ <ProTable
256
+ columns={columns}
257
+ rowKey="id"
258
+ dataSource={data}
259
+ pagination={{
260
+ mode: "server",
261
+ current: pagination.current,
262
+ pageSize: pagination.pageSize,
263
+ total: pagination.total,
264
+ onChange: (current, pageSize) => void fetchPage(current, pageSize),
265
+ }}
266
+ />
267
+ )
268
+ }
269
+ ```
270
+
271
+ #### Custom Pagination Rendering (`paginationRender`)
272
+
273
+ Use `paginationRender` when you want to **render your own pagination UI** (in any layout), while still reusing ProTable’s built-in
274
+ pagination state and default Pagination component.
275
+
276
+ Notes:
277
+ - `paginationRender` receives `pagination`, `onChange`, and `defaultDom`.
278
+ - If you are in **server pagination mode** (`pagination.mode: 'server'`) you must also provide `pagination.onChange` to fetch data.
279
+
280
+ ```tsx
281
+ <ProTable
282
+ columns={columns}
283
+ rowKey="id"
284
+ dataSource={data}
285
+ pagination={{
286
+ mode: "server",
287
+ current,
288
+ pageSize,
289
+ total,
290
+ onChange: (page, pageSize) => void fetchPage(page, pageSize),
291
+ }}
292
+ paginationRender={({ pagination, onChange, defaultDom }) => (
293
+ <div className="space-y-2">
294
+ <div className="flex items-center justify-between rounded border p-2">
295
+ <div className="text-sm text-muted-foreground">
296
+ Page {pagination.current} / Size {pagination.pageSize} / Total {pagination.total}
297
+ </div>
298
+ <div className="flex gap-2">
299
+ <button onClick={() => onChange(Math.max(1, pagination.current - 1), pagination.pageSize)}>
300
+ Prev
301
+ </button>
302
+ <button onClick={() => onChange(pagination.current + 1, pagination.pageSize)}>
303
+ Next
304
+ </button>
305
+ </div>
306
+ </div>
307
+ {/* reuse built-in Pagination UI */}
308
+ {defaultDom}
309
+ </div>
310
+ )}
311
+ />
312
+ ```
313
+
233
314
  #### With Internationalization
234
315
 
235
316
  ```tsx
@@ -687,8 +768,9 @@ function App() {
687
768
  - **远程数据模式**(有 `request` 属性):搜索会触发新的数据获取,搜索参数会传递给后端。
688
769
 
689
770
  默认过滤函数支持:
690
- - 不区分大小写的字符串匹配(包含)
691
- - 基于数组的多选过滤
771
+ - **文本类字段**:不区分大小写的字符串匹配(包含)
772
+ - **枚举 / 筛选类字段**:精确匹配(例如 `valueEnum`、`filters`、`valueType: 'select' | 'status'`)
773
+ - 基于数组的多选过滤(枚举 / 筛选类字段为精确匹配;文本类字段为包含匹配)
692
774
  - 自动处理空值 /null 值
693
775
 
694
776
  ```tsx
@@ -801,6 +883,83 @@ function Page() {
801
883
  }
802
884
  ```
803
885
 
886
+ #### 服务端分页(不传 `request`,外部自行请求)
887
+
888
+ 如果你**不使用** `request`,但希望实现**服务端分页**(也就是 `dataSource` 只提供“当前页 items”),请设置
889
+ `pagination.mode: 'server'`,避免 TanStack Table 再次 slice 导致第 2 页为空 / 数据错乱。
890
+
891
+ ```tsx
892
+ function Page() {
893
+ const [pagination, setPagination] = useState({ current: 1, pageSize: 10, total: 0 })
894
+ const [data, setData] = useState<any[]>([])
895
+
896
+ const fetchPage = async (current: number, pageSize: number) => {
897
+ const res = await fetchUsers({ current, pageSize })
898
+ setData(res.items)
899
+ setPagination((prev) => ({ ...prev, current, pageSize, total: res.total }))
900
+ }
901
+
902
+ useEffect(() => {
903
+ void fetchPage(pagination.current, pagination.pageSize)
904
+ }, [])
905
+
906
+ return (
907
+ <ProTable
908
+ columns={columns}
909
+ rowKey="id"
910
+ dataSource={data}
911
+ pagination={{
912
+ mode: "server",
913
+ current: pagination.current,
914
+ pageSize: pagination.pageSize,
915
+ total: pagination.total,
916
+ onChange: (current, pageSize) => void fetchPage(current, pageSize),
917
+ }}
918
+ />
919
+ )
920
+ }
921
+ ```
922
+
923
+ #### 自定义分页渲染(`paginationRender`)
924
+
925
+ 当你想把分页 UI 放到任意布局 / 卡片里,并且仍复用 ProTable 内置分页状态 / 逻辑时,使用 `paginationRender`:
926
+
927
+ - `paginationRender` 会拿到 `pagination`、`onChange`、`defaultDom`
928
+ - 如果你是 **服务端分页模式**(`pagination.mode: 'server'`),务必同时提供 `pagination.onChange` 去请求数据
929
+
930
+ ```tsx
931
+ <ProTable
932
+ columns={columns}
933
+ rowKey="id"
934
+ dataSource={data}
935
+ pagination={{
936
+ mode: "server",
937
+ current,
938
+ pageSize,
939
+ total,
940
+ onChange: (page, pageSize) => void fetchPage(page, pageSize),
941
+ }}
942
+ paginationRender={({ pagination, onChange, defaultDom }) => (
943
+ <div className="space-y-2">
944
+ <div className="flex items-center justify-between rounded border p-2">
945
+ <div className="text-sm text-muted-foreground">
946
+ 自定义分页:第 {pagination.current} 页 / 每页 {pagination.pageSize} 条 / 共 {pagination.total} 条
947
+ </div>
948
+ <div className="flex gap-2">
949
+ <button onClick={() => onChange(Math.max(1, pagination.current - 1), pagination.pageSize)}>
950
+ 上一页
951
+ </button>
952
+ <button onClick={() => onChange(pagination.current + 1, pagination.pageSize)}>
953
+ 下一页
954
+ </button>
955
+ </div>
956
+ </div>
957
+ {defaultDom}
958
+ </div>
959
+ )}
960
+ />
961
+ ```
962
+
804
963
  #### 带国际化
805
964
 
806
965
  ```tsx
@@ -5,7 +5,7 @@ interface LoadingStateProps {
5
5
  draggable?: boolean;
6
6
  /** 是否显示选择列 */
7
7
  rowSelection?: boolean;
8
- /** 加载行数,默认 5 */
8
+ /** 加载行数,默认 10(更贴近常用 pageSize,减少翻页加载时的高度跳动) */
9
9
  rowCount?: number;
10
10
  }
11
11
  export declare function LoadingState({ columnCount, draggable, rowSelection, rowCount, }: LoadingStateProps): import("react/jsx-runtime").JSX.Element;
@@ -1 +1 @@
1
- {"version":3,"file":"loading-state.d.ts","sourceRoot":"","sources":["../../lib/components/loading-state.tsx"],"names":[],"mappings":"AAGA,UAAU,iBAAiB;IACzB,SAAS;IACT,WAAW,EAAE,MAAM,CAAC;IACpB,cAAc;IACd,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,cAAc;IACd,YAAY,CAAC,EAAE,OAAO,CAAC;IACvB,gBAAgB;IAChB,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AAED,wBAAgB,YAAY,CAAC,EAC3B,WAAW,EACX,SAAiB,EACjB,YAAoB,EACpB,QAAY,GACb,EAAE,iBAAiB,2CAwBnB"}
1
+ {"version":3,"file":"loading-state.d.ts","sourceRoot":"","sources":["../../lib/components/loading-state.tsx"],"names":[],"mappings":"AAGA,UAAU,iBAAiB;IACzB,SAAS;IACT,WAAW,EAAE,MAAM,CAAC;IACpB,cAAc;IACd,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,cAAc;IACd,YAAY,CAAC,EAAE,OAAO,CAAC;IACvB,8CAA8C;IAC9C,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AAED,wBAAgB,YAAY,CAAC,EAC3B,WAAW,EACX,SAAiB,EACjB,YAAoB,EACpB,QAAa,GACd,EAAE,iBAAiB,2CAwBnB"}
@@ -1 +1 @@
1
- {"version":3,"file":"use-pro-table.d.ts","sourceRoot":"","sources":["../../lib/hooks/use-pro-table.ts"],"names":[],"mappings":"AAaA,OAAO,EAAiE,KAAK,GAAG,EAAE,MAAM,OAAO,CAAA;AAC/F,OAAO,KAAK,EACR,cAAc,EACd,aAAa,EAEhB,MAAM,SAAS,CAAA;AAGhB,UAAU,aAAa,CAAC,CAAC;IACrB,OAAO,EAAE,OAAO,CAAA;IAChB,IAAI,EAAE,CAAC,EAAE,CAAA;IACT,KAAK,EAAE,MAAM,CAAA;IACb,OAAO,EAAE,MAAM,CAAA;IACf,QAAQ,EAAE,MAAM,CAAA;IAChB,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAA;IAC5B,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAA;IAC3B,eAAe,EAAE,GAAG,EAAE,CAAA;IACtB,YAAY,EAAE,CAAC,EAAE,CAAA;IACjB,UAAU,EAAE,GAAG,GAAG,IAAI,CAAA;IACtB,aAAa,EAAE,CAAC,GAAG,IAAI,CAAA;CAC1B;AAED,KAAK,kBAAkB,CAAC,CAAC,IACnB;IAAE,IAAI,EAAE,aAAa,CAAC;IAAC,OAAO,EAAE,OAAO,CAAA;CAAE,GACzC;IAAE,IAAI,EAAE,UAAU,CAAC;IAAC,OAAO,EAAE;QAAE,IAAI,EAAE,CAAC,EAAE,CAAC;QAAC,KAAK,CAAC,EAAE,MAAM,CAAA;KAAE,CAAA;CAAE,GAC5D;IAAE,IAAI,EAAE,WAAW,CAAC;IAAC,OAAO,EAAE,MAAM,CAAA;CAAE,GACtC;IAAE,IAAI,EAAE,gBAAgB,CAAC;IAAC,OAAO,EAAE;QAAE,OAAO,CAAC,EAAE,MAAM,CAAC;QAAC,QAAQ,CAAC,EAAE,MAAM,CAAA;KAAE,CAAA;CAAE,GAC5E;IAAE,IAAI,EAAE,aAAa,CAAC;IAAC,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAA;CAAE,GACrD;IAAE,IAAI,EAAE,YAAY,CAAC;IAAC,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAA;CAAE,GACpD;IAAE,IAAI,EAAE,eAAe,CAAC;IAAC,OAAO,EAAE;QAAE,IAAI,EAAE,GAAG,EAAE,CAAC;QAAC,IAAI,EAAE,CAAC,EAAE,CAAA;KAAE,CAAA;CAAE,GAC9D;IAAE,IAAI,EAAE,YAAY,CAAC;IAAC,OAAO,EAAE;QAAE,GAAG,EAAE,GAAG,CAAC;QAAC,MAAM,EAAE,CAAC,CAAA;KAAE,CAAA;CAAE,GACxD;IAAE,IAAI,EAAE,aAAa,CAAA;CAAE,GACvB;IAAE,IAAI,EAAE,WAAW,CAAC;IAAC,OAAO,EAAE,CAAC,CAAA;CAAE,GACjC;IAAE,IAAI,EAAE,OAAO,CAAA;CAAE,CAAA;AAyEvB,wBAAgB,WAAW,CAAC,CAAC,SAAS,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,EACrD,KAAK,EAAE,aAAa,CAAC,CAAC,CAAC;;;;;;0CAsV8B,MAAM,YAAY,MAAM;+BAUnC,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC;;;EA2HhE"}
1
+ {"version":3,"file":"use-pro-table.d.ts","sourceRoot":"","sources":["../../lib/hooks/use-pro-table.ts"],"names":[],"mappings":"AAaA,OAAO,EAAiE,KAAK,GAAG,EAAE,MAAM,OAAO,CAAA;AAC/F,OAAO,KAAK,EACR,cAAc,EACd,aAAa,EAEhB,MAAM,SAAS,CAAA;AAGhB,UAAU,aAAa,CAAC,CAAC;IACrB,OAAO,EAAE,OAAO,CAAA;IAChB,IAAI,EAAE,CAAC,EAAE,CAAA;IACT,KAAK,EAAE,MAAM,CAAA;IACb,OAAO,EAAE,MAAM,CAAA;IACf,QAAQ,EAAE,MAAM,CAAA;IAChB,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAA;IAC5B,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAA;IAC3B,eAAe,EAAE,GAAG,EAAE,CAAA;IACtB,YAAY,EAAE,CAAC,EAAE,CAAA;IACjB,UAAU,EAAE,GAAG,GAAG,IAAI,CAAA;IACtB,aAAa,EAAE,CAAC,GAAG,IAAI,CAAA;CAC1B;AAED,KAAK,kBAAkB,CAAC,CAAC,IACnB;IAAE,IAAI,EAAE,aAAa,CAAC;IAAC,OAAO,EAAE,OAAO,CAAA;CAAE,GACzC;IAAE,IAAI,EAAE,UAAU,CAAC;IAAC,OAAO,EAAE;QAAE,IAAI,EAAE,CAAC,EAAE,CAAC;QAAC,KAAK,CAAC,EAAE,MAAM,CAAA;KAAE,CAAA;CAAE,GAC5D;IAAE,IAAI,EAAE,WAAW,CAAC;IAAC,OAAO,EAAE,MAAM,CAAA;CAAE,GACtC;IAAE,IAAI,EAAE,gBAAgB,CAAC;IAAC,OAAO,EAAE;QAAE,OAAO,CAAC,EAAE,MAAM,CAAC;QAAC,QAAQ,CAAC,EAAE,MAAM,CAAA;KAAE,CAAA;CAAE,GAC5E;IAAE,IAAI,EAAE,aAAa,CAAC;IAAC,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAA;CAAE,GACrD;IAAE,IAAI,EAAE,YAAY,CAAC;IAAC,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAA;CAAE,GACpD;IAAE,IAAI,EAAE,eAAe,CAAC;IAAC,OAAO,EAAE;QAAE,IAAI,EAAE,GAAG,EAAE,CAAC;QAAC,IAAI,EAAE,CAAC,EAAE,CAAA;KAAE,CAAA;CAAE,GAC9D;IAAE,IAAI,EAAE,YAAY,CAAC;IAAC,OAAO,EAAE;QAAE,GAAG,EAAE,GAAG,CAAC;QAAC,MAAM,EAAE,CAAC,CAAA;KAAE,CAAA;CAAE,GACxD;IAAE,IAAI,EAAE,aAAa,CAAA;CAAE,GACvB;IAAE,IAAI,EAAE,WAAW,CAAC;IAAC,OAAO,EAAE,CAAC,CAAA;CAAE,GACjC;IAAE,IAAI,EAAE,OAAO,CAAA;CAAE,CAAA;AAyEvB,wBAAgB,WAAW,CAAC,CAAC,SAAS,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,EACrD,KAAK,EAAE,aAAa,CAAC,CAAC,CAAC;;;;;;0CA6W8B,MAAM,YAAY,MAAM;+BAUnC,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC;;;EA2HhE"}