UNPKG

nuqs-zod-adapter

Version:

A Nuqs adapter to safely bind Zod schemas with query parameters using type safety, debouncing and auto-reset support.

62 lines (61 loc) 2.08 kB
import { useQueryState, parseAsString, parseAsInteger, parseAsBoolean } from 'nuqs'; import { useDebouncedCallback } from 'use-debounce'; import { useEffect, useState } from 'react'; export function useSafeQueryStateFromZod(key, schema, options) { let baseSchema = schema; let defaultValue = undefined; if (schema._def.typeName === 'ZodDefault') { defaultValue = schema._def.defaultValue(); baseSchema = schema._def.innerType; } const typeName = baseSchema._def.typeName; let parser; switch (typeName) { case 'ZodString': case 'ZodEnum': case 'ZodNativeEnum': case 'ZodLiteral': case 'ZodUnion': parser = parseAsString.withDefault(defaultValue); break; case 'ZodNumber': parser = parseAsInteger.withDefault(defaultValue); break; case 'ZodBoolean': parser = parseAsBoolean.withDefault(defaultValue); break; case 'ZodEffects': if (baseSchema._def.schema?._def?.typeName === 'ZodNumber') { parser = parseAsInteger.withDefault(defaultValue); } else { parser = parseAsString.withDefault(defaultValue); } break; default: } const [rawValue, setRaw] = useQueryState(key, { ...parser, ...options }); const delay = options?.delay; const resetKeys = options?.resetKeys ?? []; if (!delay) return [rawValue ?? defaultValue, setRaw]; const [internalValue, setInternalValue] = useState(rawValue); const debouncedSet = useDebouncedCallback((v) => { setRaw(v); for (const rk of resetKeys) { const [, resetSetter] = useQueryState(rk, parseAsString.withDefault('')); resetSetter(null); } }, delay); const set = (v) => { setInternalValue(v); debouncedSet(v); }; useEffect(() => { setInternalValue(rawValue); }, [rawValue]); return [internalValue ?? defaultValue, set]; }