Skip to content

Commit fd79299

Browse files
authored
Merge pull request #487 from taro-28/export-encoder-and-decoder
feat: export default encoder/decoder for pre-setting table URL parameters
2 parents 08851e5 + 4558440 commit fd79299

20 files changed

Lines changed: 362 additions & 168 deletions

README.md

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -241,6 +241,26 @@ Create an input that supports IME conversion with a uncontrolled component.
241241

242242
- [sample code](https://github.com/taro-28/tanstack-table-search-params/tree/main/examples/lib/src/components/SearchInput.tsx)
243243

244+
### Q: How can I preset query parameters when navigating to a page that contains a table?
245+
246+
To pass initial table state via the URL, call one of the `encode*` helpers from
247+
`tanstack-table-search-params/encoder-decoder` and assign its return value to your link.
248+
249+
```tsx
250+
import { encodeSorting } from "tanstack-table-search-params/encoder-decoder";
251+
252+
<Link
253+
href={{
254+
pathname: "/some-page-with-table",
255+
query: {
256+
sorting: encodeSorting([{ id: "name", desc: true }]),
257+
},
258+
}}
259+
>
260+
foo
261+
</Link>;
262+
```
263+
244264
## Supported
245265

246266
List of supported TanStack table states
@@ -272,3 +292,7 @@ MIT
272292
[1]: https://www.npmjs.com/package/tanstack-table-search-params
273293
[2]: https://github.com/taro-28/tanstack-table-search-params
274294
[3]: https://bundlephobia.com/package/tanstack-table-search-params
295+
296+
```
297+
298+
```

packages/tanstack-table-search-params/README.md

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -241,6 +241,26 @@ Create an input that supports IME conversion with a uncontrolled component.
241241

242242
- [sample code](https://github.com/taro-28/tanstack-table-search-params/tree/main/examples/lib/src/components/SearchInput.tsx)
243243

244+
### Q: How can I preset query parameters when navigating to a page that contains a table?
245+
246+
To pass initial table state via the URL, call one of the `encode*` helpers from
247+
`tanstack-table-search-params/encoder-decoder` and assign its return value to your link.
248+
249+
```tsx
250+
import { encodeSorting } from "tanstack-table-search-params/encoder-decoder";
251+
252+
<Link
253+
href={{
254+
pathname: "/some-page-with-table",
255+
query: {
256+
sorting: encodeSorting([{ id: "name", desc: true }]),
257+
},
258+
}}
259+
>
260+
foo
261+
</Link>;
262+
```
263+
244264
## Supported
245265

246266
List of supported TanStack table states

packages/tanstack-table-search-params/package.json

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,11 @@
4646
"types": "./dist/index.d.ts",
4747
"require": "./dist/index",
4848
"import": "./dist/index.mjs"
49+
},
50+
"./encoder-decoder": {
51+
"types": "./dist/encoder-decoder/index.d.ts",
52+
"require": "./dist/encoder-decoder/index",
53+
"import": "./dist/encoder-decoder/index.mjs"
4954
}
5055
},
5156
"main": "./dist/index",

packages/tanstack-table-search-params/src/encoder-decoder/columnFilters.test.ts

Lines changed: 14 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,10 @@ import { defaultDefaultColumnFilters } from "../useColumnFilters";
33
import { decodeColumnFilters, encodeColumnFilters } from "./columnFilters";
44
import { noneStringForCustomDefaultValue } from "./noneStringForCustomDefaultValue";
55

6+
type DefaultValue = NonNullable<
7+
NonNullable<Parameters<typeof encodeColumnFilters>[1]>["defaultValue"]
8+
>;
9+
610
const customDefaultValue = [
711
{
812
id: "custom",
@@ -12,7 +16,7 @@ const customDefaultValue = [
1216

1317
describe("columnFilters", () => {
1418
describe("encode", () =>
15-
describe.each<Parameters<typeof encodeColumnFilters>[1]>([
19+
describe.each<DefaultValue>([
1620
defaultDefaultColumnFilters,
1721
customDefaultValue,
1822
])("default value: %defaultValue", (...defaultValue) =>
@@ -174,7 +178,7 @@ describe("columnFilters", () => {
174178
want: "foo.%5B%22bar%22%2C42%2Ctrue%2Cnull%2C%7B%22bar%22%3A%22baz%22%7D%2C%5B%22qux%22%5D%5D",
175179
},
176180
])("$name", ({ stateValue, want }) =>
177-
expect(encodeColumnFilters(stateValue, defaultValue)).toEqual(want),
181+
expect(encodeColumnFilters(stateValue, { defaultValue })).toEqual(want),
178182
),
179183
));
180184

@@ -189,7 +193,7 @@ describe("columnFilters", () => {
189193
}>([
190194
{
191195
name: "default value",
192-
queryValue: encodeColumnFilters(defaultValue, defaultValue),
196+
queryValue: encodeColumnFilters(defaultValue, { defaultValue }),
193197
want: defaultValue,
194198
},
195199
{
@@ -363,18 +367,20 @@ describe("columnFilters", () => {
363367
want: defaultValue,
364368
},
365369
])("$name", ({ queryValue, want }) =>
366-
expect(decodeColumnFilters(queryValue, defaultValue)).toEqual(want),
370+
expect(decodeColumnFilters(queryValue, { defaultValue })).toEqual(
371+
want,
372+
),
367373
),
368374
));
369375

370376
describe("encode and decode", () =>
371-
describe.each<Parameters<typeof encodeColumnFilters>[1]>([
377+
describe.each<DefaultValue>([
372378
defaultDefaultColumnFilters,
373379
customDefaultValue,
374380
])("default value: $defaultValue", (...defaultValue) =>
375381
test.each<{
376382
name: string;
377-
stateValue: Parameters<typeof encodeColumnFilters>[1];
383+
stateValue: Parameters<typeof encodeColumnFilters>[0];
378384
}>([
379385
{
380386
name: "default value",
@@ -493,8 +499,8 @@ describe("columnFilters", () => {
493499
])("$name", ({ stateValue }) => {
494500
expect(
495501
decodeColumnFilters(
496-
encodeColumnFilters(stateValue, defaultValue),
497-
defaultValue,
502+
encodeColumnFilters(stateValue, { defaultValue }),
503+
{ defaultValue },
498504
),
499505
).toEqual(stateValue);
500506
}),

packages/tanstack-table-search-params/src/encoder-decoder/columnFilters.ts

Lines changed: 41 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,40 +1,68 @@
1-
import type { State } from "..";
1+
import type { State as TanstackTableState } from "..";
22
import type { Query } from "../types";
33
import { noneStringForCustomDefaultValue } from "./noneStringForCustomDefaultValue";
44

5+
/**
6+
* The default encoder of Tanstack Table's `columnFilters`.
7+
*
8+
* @param value - The value to encode.
9+
* @param options
10+
* @param options.defaultValue
11+
* - If you set [`defaultValues`](https://github.com/taro-28/tanstack-table-search-params?tab=readme-ov-file#custom-default-value) in `useTableSearchParams`,
12+
* you should set the same value.
13+
*
14+
* @returns The encoded query parameter value.
15+
*/
516
export const encodeColumnFilters = (
6-
stateValue: State["columnFilters"],
7-
defaultValue: State["columnFilters"],
17+
value: TanstackTableState["columnFilters"],
18+
options?: {
19+
defaultValue?: TanstackTableState["columnFilters"];
20+
},
821
): Query[string] => {
9-
if (JSON.stringify(stateValue) === JSON.stringify(defaultValue)) {
22+
const defaultValue = options?.defaultValue;
23+
if (JSON.stringify(value) === JSON.stringify(defaultValue)) {
1024
return undefined;
1125
}
1226

1327
// return encoded empty string if stateValue is empty with custom default value
14-
if (stateValue.length === 0) {
28+
if (value.length === 0) {
1529
return noneStringForCustomDefaultValue;
1630
}
1731

18-
return stateValue
32+
return value
1933
.map(
2034
({ id, value }) =>
2135
`${id}.${encodeURIComponent(JSON.stringify(value)).replaceAll(".", "%2E")}`,
2236
)
2337
.join(",");
2438
};
2539

40+
/**
41+
* The default decoder of Tanstack Table's `columnFilters`.
42+
*
43+
* @param value - The encoded query parameter value to decode.
44+
* @param options
45+
* @param options.defaultValue
46+
* - If you set [`defaultValues`](https://github.com/taro-28/tanstack-table-search-params?tab=readme-ov-file#custom-default-value) in `useTableSearchParams`,
47+
* you should set the same value.
48+
*
49+
* @returns The decoded value.
50+
*/
2651
export const decodeColumnFilters = (
27-
queryValue: Query[string],
28-
defaultValue: State["columnFilters"],
29-
): State["columnFilters"] => {
30-
if (typeof queryValue !== "string") return defaultValue;
31-
if (queryValue === "") return defaultValue;
32-
if (queryValue === noneStringForCustomDefaultValue) {
52+
value: Query[string],
53+
options?: {
54+
defaultValue?: TanstackTableState["columnFilters"];
55+
},
56+
): TanstackTableState["columnFilters"] | undefined => {
57+
const defaultValue = options?.defaultValue;
58+
if (typeof value !== "string") return defaultValue;
59+
if (value === "") return defaultValue;
60+
if (value === noneStringForCustomDefaultValue) {
3361
return [];
3462
}
3563

3664
try {
37-
return queryValue
65+
return value
3866
.split(",")
3967
.map((item) => {
4068
const [id, stringValue] = item.split(".");

packages/tanstack-table-search-params/src/encoder-decoder/columnOrder.test.ts

Lines changed: 12 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -3,11 +3,15 @@ import { defaultDefaultColumnOrder } from "../useColumnOrder";
33
import { decodeColumnOrder, encodeColumnOrder } from "./columnOrder";
44
import { noneStringForCustomDefaultValue } from "./noneStringForCustomDefaultValue";
55

6+
type DefaultValue = NonNullable<
7+
NonNullable<Parameters<typeof encodeColumnOrder>[1]>["defaultValue"]
8+
>;
9+
610
const customDefaultValue = ["custom"];
711

812
describe("columnOrder", () => {
913
describe("encode", () =>
10-
describe.each<Parameters<typeof encodeColumnOrder>[1]>([
14+
describe.each<DefaultValue>([
1115
defaultDefaultColumnOrder,
1216
customDefaultValue,
1317
])("default value: %defaultValue", (...defaultValue) =>
@@ -51,7 +55,7 @@ describe("columnOrder", () => {
5155
want: "foo,bar%2Cbaz",
5256
},
5357
])("$name", ({ stateValue, want }) =>
54-
expect(encodeColumnOrder(stateValue, defaultValue)).toEqual(want),
58+
expect(encodeColumnOrder(stateValue, { defaultValue })).toEqual(want),
5559
),
5660
));
5761

@@ -66,7 +70,7 @@ describe("columnOrder", () => {
6670
}>([
6771
{
6872
name: "default value",
69-
queryValue: encodeColumnOrder(defaultValue, defaultValue),
73+
queryValue: encodeColumnOrder(defaultValue, { defaultValue }),
7074
want: defaultValue,
7175
},
7276
{
@@ -110,18 +114,18 @@ describe("columnOrder", () => {
110114
want: defaultValue,
111115
},
112116
])("$name", ({ queryValue, want }) =>
113-
expect(decodeColumnOrder(queryValue, defaultValue)).toEqual(want),
117+
expect(decodeColumnOrder(queryValue, { defaultValue })).toEqual(want),
114118
),
115119
));
116120

117121
describe("encode and decode", () =>
118-
describe.each<Parameters<typeof encodeColumnOrder>[1]>([
122+
describe.each<DefaultValue>([
119123
defaultDefaultColumnOrder,
120124
customDefaultValue,
121125
])("default value: $defaultValue", (...defaultValue) =>
122126
test.each<{
123127
name: string;
124-
stateValue: Parameters<typeof encodeColumnOrder>[1];
128+
stateValue: Parameters<typeof encodeColumnOrder>[0];
125129
}>([
126130
{
127131
name: "default value",
@@ -149,10 +153,9 @@ describe("columnOrder", () => {
149153
},
150154
])("$name", ({ stateValue }) => {
151155
expect(
152-
decodeColumnOrder(
153-
encodeColumnOrder(stateValue, defaultValue),
156+
decodeColumnOrder(encodeColumnOrder(stateValue, { defaultValue }), {
154157
defaultValue,
155-
),
158+
}),
156159
).toEqual(stateValue);
157160
}),
158161
));

packages/tanstack-table-search-params/src/encoder-decoder/columnOrder.ts

Lines changed: 36 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,29 +1,55 @@
1-
import type { State } from "..";
1+
import type { State as TanstackTableState } from "..";
22
import type { Query } from "../types";
33
import { noneStringForCustomDefaultValue } from "./noneStringForCustomDefaultValue";
44

5+
/**
6+
* The default encoder of Tanstack Table's `columnOrder`.
7+
*
8+
* @param value - The value to encode.
9+
* @param options
10+
* @param options.defaultValue
11+
* - If you set [`defaultValues`](https://github.com/taro-28/tanstack-table-search-params?tab=readme-ov-file#custom-default-value) in `useTableSearchParams`,
12+
* you should set the same value.
13+
*
14+
* @returns The encoded query parameter value.
15+
*/
516
export const encodeColumnOrder = (
6-
stateValue: State["columnOrder"],
7-
defaultValue: State["columnOrder"],
17+
value: TanstackTableState["columnOrder"],
18+
options?: {
19+
defaultValue?: TanstackTableState["columnOrder"];
20+
},
821
): Query[string] => {
9-
if (JSON.stringify(stateValue) === JSON.stringify(defaultValue)) {
22+
const defaultValue = options?.defaultValue;
23+
if (JSON.stringify(value) === JSON.stringify(defaultValue)) {
1024
return undefined;
1125
}
1226

1327
// return encoded empty string if stateValue is empty with custom default value
14-
if (stateValue.length === 0) {
28+
if (value.length === 0) {
1529
return noneStringForCustomDefaultValue;
1630
}
1731

18-
return stateValue
19-
.map((v) => v.replaceAll(",", encodeURIComponent(",")))
20-
.join(",");
32+
return value.map((v) => v.replaceAll(",", encodeURIComponent(","))).join(",");
2133
};
2234

35+
/**
36+
* The default decoder of Tanstack Table's `columnOrder`.
37+
*
38+
* @param queryValue - The encoded query parameter value to decode.
39+
* @param options
40+
* @param options.defaultValue
41+
* - If you set [`defaultValues`](https://github.com/taro-28/tanstack-table-search-params?tab=readme-ov-file#custom-default-value) in `useTableSearchParams`,
42+
* you should set the same value.
43+
*
44+
* @returns The decoded value.
45+
*/
2346
export const decodeColumnOrder = (
2447
queryValue: Query[string],
25-
defaultValue: State["columnOrder"],
26-
): State["columnOrder"] => {
48+
options?: {
49+
defaultValue?: TanstackTableState["columnOrder"];
50+
},
51+
): TanstackTableState["columnOrder"] | undefined => {
52+
const defaultValue = options?.defaultValue;
2753
if (typeof queryValue !== "string") return defaultValue;
2854
if (queryValue === "") return defaultValue;
2955
if (queryValue === noneStringForCustomDefaultValue) {

0 commit comments

Comments
 (0)