2024-11-05 17:36:30 +09:00
|
|
|
import React, { useMemo } from 'react';
|
|
|
|
|
|
2025-01-02 15:33:37 +11:00
|
|
|
import { useLocation, useNavigate } from 'react-router';
|
|
|
|
|
import { useSearchParams } from 'react-router';
|
2024-11-05 17:36:30 +09:00
|
|
|
|
|
|
|
|
import { Select, SelectContent, SelectTrigger, SelectValue } from '@documenso/ui/primitives/select';
|
|
|
|
|
|
|
|
|
|
export type SearchParamSelector = {
|
|
|
|
|
paramKey: string;
|
|
|
|
|
isValueValid: (value: unknown) => boolean;
|
|
|
|
|
children: React.ReactNode;
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
export const SearchParamSelector = ({ children, paramKey, isValueValid }: SearchParamSelector) => {
|
2025-01-02 15:33:37 +11:00
|
|
|
const { pathname } = useLocation();
|
|
|
|
|
const [searchParams] = useSearchParams();
|
2024-11-05 17:36:30 +09:00
|
|
|
|
2025-01-02 15:33:37 +11:00
|
|
|
const navigate = useNavigate();
|
2024-11-05 17:36:30 +09:00
|
|
|
|
|
|
|
|
const value = useMemo(() => {
|
|
|
|
|
const p = searchParams?.get(paramKey) ?? 'all';
|
|
|
|
|
|
|
|
|
|
return isValueValid(p) ? p : 'all';
|
|
|
|
|
}, [searchParams]);
|
|
|
|
|
|
|
|
|
|
const onValueChange = (newValue: string) => {
|
|
|
|
|
if (!pathname) {
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
const params = new URLSearchParams(searchParams?.toString());
|
|
|
|
|
|
|
|
|
|
params.set(paramKey, newValue);
|
|
|
|
|
|
|
|
|
|
if (newValue === '' || newValue === 'all') {
|
|
|
|
|
params.delete(paramKey);
|
|
|
|
|
}
|
|
|
|
|
|
2025-01-02 15:33:37 +11:00
|
|
|
void navigate(`${pathname}?${params.toString()}`, { preventScrollReset: true });
|
2024-11-05 17:36:30 +09:00
|
|
|
};
|
|
|
|
|
|
|
|
|
|
return (
|
|
|
|
|
<Select defaultValue={value} onValueChange={onValueChange}>
|
|
|
|
|
<SelectTrigger className="text-muted-foreground max-w-[200px]">
|
|
|
|
|
<SelectValue />
|
|
|
|
|
</SelectTrigger>
|
|
|
|
|
|
|
|
|
|
<SelectContent position="popper">{children}</SelectContent>
|
|
|
|
|
</Select>
|
|
|
|
|
);
|
|
|
|
|
};
|