@izumisy-tailor/tailor-data-viewer 0.3.0-preview.0 → 0.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -5,8 +5,8 @@ A low-level React component library for building data table interfaces with Tail
5
5
  ## Features
6
6
 
7
7
  - **Separation of Concerns**: Data fetching, query parameter management, and UI are fully decoupled
8
- - **`useCollection` Hook**: Manages filter, sort, and pagination state; outputs Tailor Platform-compatible GraphQL variables
9
- - **`Collection.Provider`**: Shares query parameters via React Context across sibling components
8
+ - **`useCollectionVariables` Hook**: Manages filter, sort, and pagination state; outputs Tailor Platform-compatible GraphQL variables
9
+ - **`CollectionVariablesProvider`**: Shares query parameters via React Context across sibling components
10
10
  - **`Table.*` Compound Components**: Static, unstyled table primitives (`<table>`, `<thead>`, `<tbody>`, `<tr>`, `<th>`, `<td>`)
11
11
  - **`DataTable.*` Compound Components**: Data-bound table with sort indicators, cell renderers, and `useDataTable` integration
12
12
  - **`useDataTable` Hook**: Integrates data, column visibility, row operations (optimistic updates), and props generators
@@ -15,7 +15,7 @@ A low-level React component library for building data table interfaces with Tail
15
15
  - **Utility Components**: `ColumnSelector`, `CsvButton`, `SearchFilterForm`, `Pagination` — all props-based, spreadable from hooks
16
16
  - **Multi-sort Support**: Multiple simultaneous sort fields
17
17
  - **Optimistic Updates**: `updateRow`, `deleteRow`, `insertRow` with rollback
18
- - **Presentation Agnostic**: Same `useCollection` can drive tables, kanbans, calendars, etc.
18
+ - **Presentation Agnostic**: Same `useCollectionVariables` can drive tables, kanbans, calendars, etc.
19
19
 
20
20
  ## Installation
21
21
 
@@ -47,7 +47,7 @@ npm install react react-dom
47
47
 
48
48
  ```tsx
49
49
  import {
50
- useCollection,
50
+ useCollectionVariables,
51
51
  useDataTable,
52
52
  DataTable,
53
53
  Pagination,
@@ -95,8 +95,15 @@ const columns = [
95
95
 
96
96
  // 2. Build a page
97
97
  function OrdersPage() {
98
- const collection = useCollection({ params: { pageSize: 20 } });
99
- const [result] = useQuery({ query: GET_ORDERS, variables: { ...collection.variables.pagination, query: collection.variables.query, order: collection.variables.order } });
98
+ const { variables } = useCollectionVariables({ params: { pageSize: 20 } });
99
+ const [result] = useQuery({
100
+ query: GET_ORDERS,
101
+ variables: {
102
+ ...variables.pagination,
103
+ query: variables.query,
104
+ order: variables.order
105
+ }
106
+ });
100
107
 
101
108
  const table = useDataTable<Order>({
102
109
  columns,
@@ -119,12 +126,12 @@ function OrdersPage() {
119
126
 
120
127
  ## API Overview
121
128
 
122
- ### `useCollection(options)`
129
+ ### `useCollectionVariables(options)`
123
130
 
124
131
  Manages filter, sort, and pagination state. Returns `variables` containing `query`, `order`, and `pagination` sub-properties in Tailor Platform-compatible format.
125
132
 
126
133
  ```tsx
127
- const collection = useCollection({
134
+ const { variables, ...collection } = useCollectionVariables({
128
135
  params: {
129
136
  pageSize: 20,
130
137
  initialSort: [{ field: "createdAt", direction: "Desc" }],
@@ -135,9 +142,9 @@ const collection = useCollection({
135
142
  const [result] = useQuery({
136
143
  query: GET_ORDERS,
137
144
  variables: {
138
- ...collection.variables.pagination,
139
- query: collection.variables.query,
140
- order: collection.variables.order,
145
+ ...variables.pagination,
146
+ query: variables.query,
147
+ order: variables.order,
141
148
  },
142
149
  });
143
150
 
@@ -163,15 +170,15 @@ collection.hasPrevPage; // boolean
163
170
  collection.hasNextPage; // boolean
164
171
  ```
165
172
 
166
- ### `DataTable.Provider` / `useDataTableContext()` / `useCollectionContext()`
173
+ ### `DataTable.Provider` / `useDataTableContext()` / `useCollectionVariablesContext()`
167
174
 
168
175
  `DataTable.Provider` wraps the table UI and provides both data table and collection context. All utility components (`Pagination`, `ColumnSelector`, `CsvButton`, `SearchFilterForm`) read from this context — no prop spreading needed.
169
176
 
170
- When `collection` is passed to `useDataTable`, `DataTable.Provider` automatically wraps a `Collection.Provider` so child components can use `useCollectionContext()`.
177
+ When `collection` is passed to `useDataTable`, `DataTable.Provider` automatically wraps a `CollectionVariablesProvider` so child components can use `useCollectionVariablesContext()`.
171
178
 
172
179
  ```tsx
173
180
  <DataTable.Provider value={table}>
174
- <StatusFilter /> {/* useCollectionContext() inside */}
181
+ <StatusFilter /> {/* useCollectionVariablesContext() inside */}
175
182
  <DataTable.Root>
176
183
  <DataTable.Headers />
177
184
  <DataTable.Body />
@@ -180,13 +187,13 @@ When `collection` is passed to `useDataTable`, `DataTable.Provider` automaticall
180
187
  </DataTable.Provider>
181
188
  ```
182
189
 
183
- For cases where you need `Collection.Provider` without `DataTable.Provider` (e.g., non-table UIs), you can use it standalone:
190
+ For cases where you need `CollectionVariablesProvider` without `DataTable.Provider` (e.g., non-table UIs), you can use it standalone:
184
191
 
185
192
  ```tsx
186
- <Collection.Provider value={collection}>
193
+ <CollectionVariablesProvider value={collection}>
187
194
  <StatusFilter />
188
195
  <CustomKanbanBoard />
189
- </Collection.Provider>
196
+ </CollectionVariablesProvider>
190
197
  ```
191
198
 
192
199
  ### Column Definition Helper
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@izumisy-tailor/tailor-data-viewer",
3
3
  "private": false,
4
- "version": "0.3.0-preview.0",
4
+ "version": "0.3.0",
5
5
  "type": "module",
6
6
  "description": "Flexible data viewer component for Tailor Platform",
7
7
  "files": [
@@ -1,7 +1,7 @@
1
1
  import { createContext, useContext, type ReactNode } from "react";
2
2
  import type { UseCollectionReturn } from "../types";
3
3
 
4
- const CollectionContext = createContext<UseCollectionReturn<
4
+ const CollectionVariablesContext = createContext<UseCollectionReturn<
5
5
  string,
6
6
  unknown
7
7
  > | null>(null);
@@ -9,14 +9,18 @@ const CollectionContext = createContext<UseCollectionReturn<
9
9
  /**
10
10
  * Provider that shares collection query parameters via React Context.
11
11
  *
12
- * @example\n * ```tsx\n * const collection = useCollection({ params: { pageSize: 20 } });\n *\n * <CollectionProvider value={collection}>", "oldString": " * @example\n * ```tsx\n * const collection = useCollection({ params: { pageSize: 20 } });\n *\n * <CollectionProvider value={collection}>
12
+ * @example
13
+ * ```tsx
14
+ * const { variables, ...collection } = useCollectionVariables({ params: { pageSize: 20 } });
15
+ *
16
+ * <CollectionVariablesProvider value={collection}>
13
17
  * <FilterPanel />
14
18
  * <DataTable.Root>...</DataTable.Root>
15
- * <Pagination {...table} />
16
- * </CollectionProvider>
19
+ * <Pagination />
20
+ * </CollectionVariablesProvider>
17
21
  * ```
18
22
  */
19
- export function CollectionProvider({
23
+ export function CollectionVariablesProvider({
20
24
  value,
21
25
  children,
22
26
  }: {
@@ -24,56 +28,42 @@ export function CollectionProvider({
24
28
  children: ReactNode;
25
29
  }) {
26
30
  return (
27
- <CollectionContext.Provider value={value}>
31
+ <CollectionVariablesContext.Provider value={value}>
28
32
  {children}
29
- </CollectionContext.Provider>
33
+ </CollectionVariablesContext.Provider>
30
34
  );
31
35
  }
32
36
 
33
37
  /**
34
- * Hook to access collection state from the nearest `Collection.Provider`.
38
+ * Hook to access collection state from the nearest `CollectionVariablesProvider`.
35
39
  *
36
- * Returns the same interface as `useCollection()`. Pass a `TFieldName`
40
+ * Returns the same interface as `useCollectionVariables()`. Pass a `TFieldName`
37
41
  * type parameter to narrow method arguments like `addFilter` / `setSort`.
38
42
  *
39
43
  * @typeParam TFieldName - Union of allowed field name strings (default: `string`).
40
44
  *
41
- * @throws Error if used outside of `Collection.Provider`.
45
+ * @throws Error if used outside of `CollectionVariablesProvider`.
42
46
  *
43
47
  * @example
44
48
  * ```tsx
45
49
  * function StatusFilter() {
46
- * const { filters, addFilter, removeFilter } = useCollectionContext();
50
+ * const { filters, addFilter, removeFilter } = useCollectionVariablesContext();
47
51
  * // ...
48
52
  * }
49
53
  *
50
54
  * // With typed field names:
51
55
  * type TaskField = FieldName<typeof tableMetadata, "task">;
52
- * const { addFilter } = useCollectionContext<TaskField>();
56
+ * const { addFilter } = useCollectionVariablesContext<TaskField>();
53
57
  * ```
54
58
  */
55
- export function useCollectionContext<
59
+ export function useCollectionVariablesContext<
56
60
  TFieldName extends string = string,
57
61
  >(): UseCollectionReturn<TFieldName> {
58
- const ctx = useContext(CollectionContext);
62
+ const ctx = useContext(CollectionVariablesContext);
59
63
  if (!ctx) {
60
64
  throw new Error(
61
- "useCollectionContext must be used within <Collection.Provider>",
65
+ "useCollectionVariablesContext must be used within <CollectionVariablesProvider>",
62
66
  );
63
67
  }
64
68
  return ctx as UseCollectionReturn<TFieldName>;
65
69
  }
66
-
67
- /**
68
- * `Collection` namespace object providing the Provider component.
69
- *
70
- * @example
71
- * ```tsx
72
- * <Collection.Provider value={collection}>
73
- * ...
74
- * </Collection.Provider>
75
- * ```
76
- */
77
- export const Collection = {
78
- Provider: CollectionProvider,
79
- } as const;
@@ -1,15 +1,15 @@
1
1
  import { renderHook, act } from "@testing-library/react";
2
2
  import { describe, it, expect } from "vitest";
3
3
  import type { TableMetadataMap } from "../../generator/metadata-generator";
4
- import { useCollection } from "./use-collection";
4
+ import { useCollectionVariables } from "./use-collection";
5
5
 
6
- describe("useCollection", () => {
6
+ describe("useCollectionVariables", () => {
7
7
  // ---------------------------------------------------------------------------
8
8
  // Initial state
9
9
  // ---------------------------------------------------------------------------
10
10
  describe("initial state", () => {
11
11
  it("returns default variables with pageSize 20", () => {
12
- const { result } = renderHook(() => useCollection({}));
12
+ const { result } = renderHook(() => useCollectionVariables({}));
13
13
  expect(result.current.variables.pagination).toEqual({ first: 20 });
14
14
  expect(result.current.variables.query).toBeUndefined();
15
15
  expect(result.current.variables.order).toBeUndefined();
@@ -21,14 +21,14 @@ describe("useCollection", () => {
21
21
 
22
22
  it("uses custom pageSize", () => {
23
23
  const { result } = renderHook(() =>
24
- useCollection({ params: { pageSize: 50 } }),
24
+ useCollectionVariables({ params: { pageSize: 50 } }),
25
25
  );
26
26
  expect(result.current.variables.pagination.first).toBe(50);
27
27
  });
28
28
 
29
29
  it("applies initial sort", () => {
30
30
  const { result } = renderHook(() =>
31
- useCollection({
31
+ useCollectionVariables({
32
32
  params: {
33
33
  initialSort: [{ field: "createdAt", direction: "Desc" }],
34
34
  },
@@ -44,7 +44,7 @@ describe("useCollection", () => {
44
44
 
45
45
  it("applies initial filters", () => {
46
46
  const { result } = renderHook(() =>
47
- useCollection({
47
+ useCollectionVariables({
48
48
  params: {
49
49
  initialFilters: [
50
50
  {
@@ -68,7 +68,7 @@ describe("useCollection", () => {
68
68
  // ---------------------------------------------------------------------------
69
69
  describe("filter operations", () => {
70
70
  it("adds a filter", () => {
71
- const { result } = renderHook(() => useCollection({}));
71
+ const { result } = renderHook(() => useCollectionVariables({}));
72
72
 
73
73
  act(() => {
74
74
  result.current.addFilter("status", "eq", "ACTIVE");
@@ -86,7 +86,7 @@ describe("useCollection", () => {
86
86
  });
87
87
 
88
88
  it("replaces filter for same field", () => {
89
- const { result } = renderHook(() => useCollection({}));
89
+ const { result } = renderHook(() => useCollectionVariables({}));
90
90
 
91
91
  act(() => {
92
92
  result.current.addFilter("status", "eq", "ACTIVE");
@@ -100,7 +100,7 @@ describe("useCollection", () => {
100
100
  });
101
101
 
102
102
  it("sets filters in bulk", () => {
103
- const { result } = renderHook(() => useCollection({}));
103
+ const { result } = renderHook(() => useCollectionVariables({}));
104
104
 
105
105
  act(() => {
106
106
  result.current.setFilters([
@@ -125,7 +125,7 @@ describe("useCollection", () => {
125
125
  });
126
126
 
127
127
  it("removes a filter", () => {
128
- const { result } = renderHook(() => useCollection({}));
128
+ const { result } = renderHook(() => useCollectionVariables({}));
129
129
 
130
130
  act(() => {
131
131
  result.current.addFilter("status", "eq", "ACTIVE");
@@ -140,7 +140,7 @@ describe("useCollection", () => {
140
140
  });
141
141
 
142
142
  it("clears all filters", () => {
143
- const { result } = renderHook(() => useCollection({}));
143
+ const { result } = renderHook(() => useCollectionVariables({}));
144
144
 
145
145
  act(() => {
146
146
  result.current.addFilter("status", "eq", "ACTIVE");
@@ -155,7 +155,7 @@ describe("useCollection", () => {
155
155
  });
156
156
 
157
157
  it("resets pagination when filters change", () => {
158
- const { result } = renderHook(() => useCollection({}));
158
+ const { result } = renderHook(() => useCollectionVariables({}));
159
159
 
160
160
  // Navigate to next page
161
161
  act(() => {
@@ -177,7 +177,7 @@ describe("useCollection", () => {
177
177
  // ---------------------------------------------------------------------------
178
178
  describe("sort operations", () => {
179
179
  it("sets sort", () => {
180
- const { result } = renderHook(() => useCollection({}));
180
+ const { result } = renderHook(() => useCollectionVariables({}));
181
181
 
182
182
  act(() => {
183
183
  result.current.setSort("createdAt", "Desc");
@@ -192,7 +192,7 @@ describe("useCollection", () => {
192
192
  });
193
193
 
194
194
  it("appends sort for different fields", () => {
195
- const { result } = renderHook(() => useCollection({}));
195
+ const { result } = renderHook(() => useCollectionVariables({}));
196
196
 
197
197
  act(() => {
198
198
  result.current.setSort("createdAt", "Desc");
@@ -208,7 +208,7 @@ describe("useCollection", () => {
208
208
  });
209
209
 
210
210
  it("replaces direction for existing field", () => {
211
- const { result } = renderHook(() => useCollection({}));
211
+ const { result } = renderHook(() => useCollectionVariables({}));
212
212
 
213
213
  act(() => {
214
214
  result.current.setSort("createdAt", "Desc");
@@ -227,7 +227,7 @@ describe("useCollection", () => {
227
227
  });
228
228
 
229
229
  it("removes sort when direction is undefined", () => {
230
- const { result } = renderHook(() => useCollection({}));
230
+ const { result } = renderHook(() => useCollectionVariables({}));
231
231
 
232
232
  act(() => {
233
233
  result.current.setSort("createdAt", "Desc");
@@ -245,7 +245,7 @@ describe("useCollection", () => {
245
245
  });
246
246
 
247
247
  it("clears sort", () => {
248
- const { result } = renderHook(() => useCollection({}));
248
+ const { result } = renderHook(() => useCollectionVariables({}));
249
249
 
250
250
  act(() => {
251
251
  result.current.setSort("createdAt", "Desc");
@@ -264,7 +264,7 @@ describe("useCollection", () => {
264
264
  // ---------------------------------------------------------------------------
265
265
  describe("pagination operations", () => {
266
266
  it("navigates to next page (forward)", () => {
267
- const { result } = renderHook(() => useCollection({}));
267
+ const { result } = renderHook(() => useCollectionVariables({}));
268
268
 
269
269
  act(() => {
270
270
  result.current.nextPage("cursor1");
@@ -279,7 +279,7 @@ describe("useCollection", () => {
279
279
  });
280
280
 
281
281
  it("navigates to previous page (backward)", () => {
282
- const { result } = renderHook(() => useCollection({}));
282
+ const { result } = renderHook(() => useCollectionVariables({}));
283
283
 
284
284
  act(() => {
285
285
  result.current.prevPage("cursor1");
@@ -294,7 +294,7 @@ describe("useCollection", () => {
294
294
  });
295
295
 
296
296
  it("switches direction on nextPage after prevPage", () => {
297
- const { result } = renderHook(() => useCollection({}));
297
+ const { result } = renderHook(() => useCollectionVariables({}));
298
298
 
299
299
  act(() => {
300
300
  result.current.prevPage("cursorB");
@@ -310,7 +310,7 @@ describe("useCollection", () => {
310
310
  });
311
311
 
312
312
  it("resets page to forward direction", () => {
313
- const { result } = renderHook(() => useCollection({}));
313
+ const { result } = renderHook(() => useCollectionVariables({}));
314
314
 
315
315
  act(() => {
316
316
  result.current.prevPage("cursor1");
@@ -324,7 +324,7 @@ describe("useCollection", () => {
324
324
  });
325
325
 
326
326
  it("tracks hasPrevPage from currentPage and hasNextPage from setPageInfo", () => {
327
- const { result } = renderHook(() => useCollection({}));
327
+ const { result } = renderHook(() => useCollectionVariables({}));
328
328
 
329
329
  // Initially on page 1: no prev, no next
330
330
  expect(result.current.hasPrevPage).toBe(false);
@@ -357,7 +357,7 @@ describe("useCollection", () => {
357
357
  describe("variables", () => {
358
358
  it("generates complete variables with filters, sort, and cursor", () => {
359
359
  const { result } = renderHook(() =>
360
- useCollection({
360
+ useCollectionVariables({
361
361
  params: {
362
362
  pageSize: 10,
363
363
  initialFilters: [
@@ -387,7 +387,7 @@ describe("useCollection", () => {
387
387
  });
388
388
 
389
389
  it("omits undefined fields from pagination", () => {
390
- const { result } = renderHook(() => useCollection({}));
390
+ const { result } = renderHook(() => useCollectionVariables({}));
391
391
  const { pagination } = result.current.variables;
392
392
  expect(pagination).toEqual({ first: 20 });
393
393
  expect("after" in pagination).toBe(false);
@@ -397,7 +397,7 @@ describe("useCollection", () => {
397
397
 
398
398
  it("returns undefined for query and order when empty", () => {
399
399
  const { result } = renderHook(() =>
400
- useCollection({ params: { pageSize: 10 } }),
400
+ useCollectionVariables({ params: { pageSize: 10 } }),
401
401
  );
402
402
 
403
403
  expect(result.current.variables.query).toBeUndefined();
@@ -432,7 +432,7 @@ describe("useCollection", () => {
432
432
 
433
433
  it("works with tableMetadata", () => {
434
434
  const { result } = renderHook(() =>
435
- useCollection({
435
+ useCollectionVariables({
436
436
  tableMetadata: testMetadata.task,
437
437
  params: { pageSize: 10 },
438
438
  }),
@@ -442,7 +442,7 @@ describe("useCollection", () => {
442
442
 
443
443
  it("applies typed initialSort", () => {
444
444
  const { result } = renderHook(() =>
445
- useCollection({
445
+ useCollectionVariables({
446
446
  tableMetadata: testMetadata.task,
447
447
  params: {
448
448
  initialSort: [{ field: "dueDate", direction: "Desc" }],
@@ -29,18 +29,18 @@ import type { TableFieldName, TableOrderableFieldName } from "../types";
29
29
  * ```tsx
30
30
  * import { tableMetadata } from "./generated/data-viewer-metadata.generated";
31
31
  *
32
- * const collection = useCollection({
32
+ * const { variables } = useCollectionVariables({
33
33
  * tableMetadata: tableMetadata.task,
34
34
  * params: { pageSize: 20 },
35
35
  * });
36
- * const { query, order, pagination } = collection.variables;
36
+ * const { query, order, pagination } = variables;
37
37
  * const [result] = useQuery({
38
38
  * query: GET_TASKS,
39
39
  * variables: { ...pagination, query, order },
40
40
  * });
41
41
  * ```
42
42
  */
43
- export function useCollection<const TTable extends TableMetadata>(
43
+ export function useCollectionVariables<const TTable extends TableMetadata>(
44
44
  options: UseCollectionOptions<
45
45
  TableFieldName<TTable>,
46
46
  TableMetadataFilter<TTable>
@@ -70,15 +70,15 @@ export function useCollection<const TTable extends TableMetadata>(
70
70
  *
71
71
  * @example
72
72
  * ```tsx
73
- * const collection = useCollection({ params: { pageSize: 20 } });
74
- * const { query, order, pagination } = collection.variables;
73
+ * const { variables } = useCollectionVariables({ params: { pageSize: 20 } });
74
+ * const { query, order, pagination } = variables;
75
75
  * const [result] = useQuery({
76
76
  * query: GET_ORDERS,
77
77
  * variables: { ...pagination, query, order },
78
78
  * });
79
79
  * ```
80
80
  */
81
- export function useCollection(
81
+ export function useCollectionVariables(
82
82
  options: UseCollectionOptions & {
83
83
  tableMetadata?: never;
84
84
  },
@@ -87,7 +87,7 @@ export function useCollection(
87
87
  // -----------------------------------------------------------------------------
88
88
  // Implementation
89
89
  // -----------------------------------------------------------------------------
90
- export function useCollection(
90
+ export function useCollectionVariables(
91
91
  options: UseCollectionOptions & {
92
92
  tableMetadata?: TableMetadata;
93
93
  },
@@ -8,7 +8,7 @@ import {
8
8
  type ReactNode,
9
9
  } from "react";
10
10
  import { cn } from "../lib/utils";
11
- import { CollectionProvider } from "../collection/collection-provider";
11
+ import { CollectionVariablesProvider } from "../collection/collection-provider";
12
12
  import { Table } from "../table";
13
13
  import type { RowAction, SortConfig, UseDataTableReturn } from "../types";
14
14
  import {
@@ -53,14 +53,14 @@ function DataTableRoot({
53
53
  /**
54
54
  * Provider that shares `useDataTable()` state via React Context.
55
55
  *
56
- * Internally provides both `DataTableContext` and `CollectionContext`
56
+ * Internally provides both `DataTableContext` and `CollectionVariablesContext`
57
57
  * so that utility components (`Pagination`, `ColumnSelector`,
58
58
  * `SearchFilterForm`, `CsvButton`) can consume data without explicit props.
59
59
  *
60
60
  * @example
61
61
  * ```tsx
62
- * const collection = useCollection({ params: { pageSize: 20 } });
63
- * const [result] = useQuery({ query: GET_ORDERS, variables: { ...collection.variables.pagination, query: collection.variables.query, order: collection.variables.order } });
62
+ * const { variables, ...collection } = useCollectionVariables({ params: { pageSize: 20 } });
63
+ * const [result] = useQuery({ query: GET_ORDERS, variables: { ...variables.pagination, query: variables.query, order: variables.order } });
64
64
  * const table = useDataTable({ columns, data: result.data?.orders, collection });
65
65
  *
66
66
  * <DataTable.Provider value={table}>
@@ -110,10 +110,12 @@ function DataTableProviderComponent<TRow extends Record<string, unknown>>({
110
110
  </DataTableContext.Provider>
111
111
  );
112
112
 
113
- // Wrap with CollectionContext when collection is available
113
+ // Wrap with CollectionVariablesContext when collection is available
114
114
  if (collectionValue) {
115
115
  return (
116
- <CollectionProvider value={collectionValue}>{inner}</CollectionProvider>
116
+ <CollectionVariablesProvider value={collectionValue}>
117
+ {inner}
118
+ </CollectionVariablesProvider>
117
119
  );
118
120
  }
119
121
 
@@ -1,5 +1,5 @@
1
1
  import { useDataTableContext } from "./data-table-context";
2
- import { useCollectionContext } from "../collection/collection-provider";
2
+ import { useCollectionVariablesContext } from "../collection/collection-provider";
3
3
  import { getLabels } from "./i18n";
4
4
 
5
5
  // =============================================================================
@@ -112,7 +112,7 @@ const btnClass =
112
112
  /**
113
113
  * Pagination controls with first/prev/next/last navigation and page indicator.
114
114
  *
115
- * Reads pagination state from `DataTableContext` and `CollectionContext`.
115
+ * Reads pagination state from `DataTableContext` and `CollectionVariablesContext`.
116
116
  * Must be rendered inside `DataTable.Provider` but **outside** `DataTable.Root`.
117
117
  *
118
118
  * @example
@@ -139,7 +139,7 @@ export function Pagination({ labels, pageSizeOptions }: PaginationProps = {}) {
139
139
  goToLastPage,
140
140
  pageSize,
141
141
  setPageSize,
142
- } = useCollectionContext();
142
+ } = useCollectionVariablesContext();
143
143
 
144
144
  const pl = getLabels(locale).pagination;
145
145
  const firstLabel = labels?.first ?? pl.first;
@@ -14,7 +14,7 @@ import type {
14
14
  } from "../types";
15
15
  import { OPERATORS_BY_FILTER_TYPE } from "../types";
16
16
  import { useDataTableContext } from "./data-table-context";
17
- import { useCollectionContext } from "../collection/collection-provider";
17
+ import { useCollectionVariablesContext } from "../collection/collection-provider";
18
18
  import { getLabels } from "./i18n";
19
19
 
20
20
  /**
@@ -22,7 +22,7 @@ import { getLabels } from "./i18n";
22
22
  *
23
23
  * Renders a dropdown panel with type-specific filter inputs, operator
24
24
  * selectors, and active filter badges. Reads `columns` from
25
- * `DataTableContext` and filter state from `CollectionContext`.
25
+ * `DataTableContext` and filter state from `CollectionVariablesContext`.
26
26
  * Must be rendered inside `DataTable.Provider`.
27
27
  *
28
28
  * All text is customisable through the optional `labels` prop (defaults
@@ -46,7 +46,7 @@ export function SearchFilterForm({
46
46
  } = {}) {
47
47
  const { columns, locale } = useDataTableContext();
48
48
  const { filters, addFilter, removeFilter, clearFilters } =
49
- useCollectionContext();
49
+ useCollectionVariablesContext();
50
50
  const sf = getLabels(locale).searchFilter;
51
51
  const filterableColumns = columns.filter((col) => !!col.filter);
52
52
 
@@ -13,8 +13,8 @@ import type {
13
13
  *
14
14
  * @example
15
15
  * ```tsx
16
- * const collection = useCollection({ params: { pageSize: 20 } });
17
- * const { query, order, pagination } = collection.variables;
16
+ * const { variables, ...collection } = useCollectionVariables({ params: { pageSize: 20 } });
17
+ * const { query, order, pagination } = variables;
18
18
  * const [result] = useQuery({
19
19
  * query: GET_ORDERS,
20
20
  * variables: { ...pagination, query, order },
@@ -42,11 +42,10 @@ export {
42
42
  } from "./types";
43
43
 
44
44
  // Collection
45
- export { useCollection } from "./collection/use-collection";
45
+ export { useCollectionVariables } from "./collection/use-collection";
46
46
  export {
47
- Collection,
48
- CollectionProvider,
49
- useCollectionContext,
47
+ CollectionVariablesProvider,
48
+ useCollectionVariablesContext,
50
49
  } from "./collection/collection-provider";
51
50
 
52
51
  // Table (static)
@@ -219,13 +219,13 @@ export interface PageInfo {
219
219
  * GraphQL query variables in Tailor Platform format.
220
220
  *
221
221
  * Field-level type safety for `query` and `order` is not enforced here.
222
- * When `useCollection` is called with metadata, `BuildQueryVariables`
222
+ * When `useCollectionVariables` is called with metadata, `BuildQueryVariables`
223
223
  * produces precise per-field filter types at compile time.
224
224
  */
225
225
  export interface QueryVariables {
226
- /** Filter object built at runtime by `useCollection`. */
226
+ /** Filter object built at runtime by `useCollectionVariables`. */
227
227
  query?: Record<string, unknown>;
228
- /** Sort order built at runtime by `useCollection`. */
228
+ /** Sort order built at runtime by `useCollectionVariables`. */
229
229
  order?: { field: string; direction: "Asc" | "Desc" }[];
230
230
  /** Forward pagination: number of items to fetch */
231
231
  first?: number | null;
@@ -425,11 +425,11 @@ export type ColumnDefinition<TRow extends Record<string, unknown>> =
425
425
  Column<TRow>;
426
426
 
427
427
  // =============================================================================
428
- // useCollection Types
428
+ // useCollectionVariables Types
429
429
  // =============================================================================
430
430
 
431
431
  /**
432
- * Options for `useCollection` hook.
432
+ * Options for `useCollectionVariables` hook.
433
433
  *
434
434
  * @typeParam TFieldName - Union of allowed field name strings (default: `string`).
435
435
  */
@@ -449,7 +449,7 @@ export interface UseCollectionOptions<
449
449
  }
450
450
 
451
451
  /**
452
- * Return type of `useCollection` hook.
452
+ * Return type of `useCollectionVariables` hook.
453
453
  *
454
454
  * Methods that accept a field name are typed with `TFieldName` so that
455
455
  * auto-completion works when a concrete union is supplied.
@@ -3,7 +3,7 @@ import { vi } from "vitest";
3
3
  import type { Column, UseCollectionReturn } from "../component/types";
4
4
  import { DataTableContext } from "../component/data-table/data-table-context";
5
5
  import type { DataTableContextValue } from "../component/data-table/data-table-context";
6
- import { CollectionProvider } from "../component/collection/collection-provider";
6
+ import { CollectionVariablesProvider } from "../component/collection/collection-provider";
7
7
 
8
8
  // =============================================================================
9
9
  // Mock factory: DataTableContext
@@ -43,7 +43,7 @@ export function createMockDataTableContext<T extends Record<string, unknown>>(
43
43
  }
44
44
 
45
45
  // =============================================================================
46
- // Mock factory: CollectionContext
46
+ // Mock factory: CollectionVariablesContext
47
47
  // =============================================================================
48
48
 
49
49
  export function createMockCollectionContext(
@@ -122,7 +122,7 @@ export function createTestProviders<
122
122
  collection?: Partial<UseCollectionReturn<string, unknown>>;
123
123
  }) {
124
124
  return (
125
- <CollectionProvider
125
+ <CollectionVariablesProvider
126
126
  value={createMockCollectionContext({
127
127
  ...defaults.collectionDefaults,
128
128
  ...collection,
@@ -136,7 +136,7 @@ export function createTestProviders<
136
136
  >
137
137
  {children}
138
138
  </DataTableContext.Provider>
139
- </CollectionProvider>
139
+ </CollectionVariablesProvider>
140
140
  );
141
141
  };
142
142
  }