Files
spacedrive/interface/hooks/useZodSearchParams.ts
Brendan Allan 59d3994ad1 zod-powered search params (#790)
* zod-powered search params

* fix ci

* fix context menu

* fix the *other* context menu

---------

Co-authored-by: Utku Bakir <74243531+utkubakir@users.noreply.github.com>
2023-05-05 05:39:52 +00:00

40 lines
1.1 KiB
TypeScript

import { useCallback, useMemo } from 'react';
import { NavigateOptions, useSearchParams } from 'react-router-dom';
import { getParams } from 'remix-params-helper';
import { z } from 'zod';
export function useZodSearchParams<Z extends z.ZodType<Record<string, any>>>(schema: Z) {
// eslint-disable-next-line no-restricted-syntax
const [searchParams, setSearchParams] = useSearchParams();
const typedSearchParams = useMemo(
() => getParams(searchParams, schema),
[searchParams, schema]
);
if (!typedSearchParams.success) throw typedSearchParams.errors;
return [
typedSearchParams.data,
useCallback(
(
data: z.input<Z> | ((data: z.input<Z>) => z.infer<Z>),
navigateOpts?: NavigateOptions
) => {
if (typeof data === 'function') {
setSearchParams((params) => {
const typedPrevParams = getParams(params, schema);
if (!typedPrevParams.success) throw typedPrevParams.errors;
return data(typedPrevParams.data);
}, navigateOpts);
} else {
setSearchParams(data as any, navigateOpts);
}
},
[setSearchParams, schema]
)
] as const;
}