Skip to content

Commit

Permalink
Merge pull request #85 from hufs-sports-live/feat/useFunnel
Browse files Browse the repository at this point in the history
[FEAT] useFunnel hook 함수 생성
  • Loading branch information
seongminn authored Nov 26, 2023
2 parents cf21431 + 242e8b6 commit 5ee3150
Show file tree
Hide file tree
Showing 2 changed files with 71 additions and 2 deletions.
4 changes: 2 additions & 2 deletions src/components/match/MatchList/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -11,9 +11,9 @@ export default function MatchList({
return (
<ul>
{matchList.map(({ gameId, ...match }) => (
<li key={gameId}>
<li key={gameId} className="mb-14">
<Link href={`match/${gameId}`}>
<MatchCard {...match} className="mb-14 flex flex-col">
<MatchCard {...match} className="flex flex-col">
<MatchCard.Label className="mb-2 grid w-full grid-cols-3 border-b-2 border-b-gray-5 px-1 pb-1" />
<div className="flex h-full min-h-[180px] items-center justify-around rounded-xl bg-gray-1 shadow-lg">
<MatchCard.Background
Expand Down
69 changes: 69 additions & 0 deletions src/hooks/useFunnel.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
import { useSearchParams } from 'next/navigation';
import { useRouter } from 'next/router';
import {
Children,
isValidElement,
ReactElement,
ReactNode,
useCallback,
useMemo,
} from 'react';

export interface FunnelProps<T extends string[]> {
steps: T;
step: T[number];
children: Array<ReactElement<StepProps<T>>> | ReactElement<StepProps<T>>;
}

export interface StepProps<T extends string[]> {
name: T[number];
children?: ReactNode;
}

const Funnel = <T extends string[]>({
steps,
step,
children,
}: FunnelProps<T>) => {
const validChildren = Children.toArray(children)
.filter(isValidElement)
.filter(i =>
steps.includes((i.props as Partial<StepProps<T>>).name ?? ''),
) as Array<ReactElement<StepProps<T>>>;

const targetStep = validChildren.find(child => child.props.name === step);

return <>{targetStep || null}</>;
};

const Step = <T extends string[]>({ children }: StepProps<T>) => {
return <>{children}</>;
};

export const useFunnel = <T extends string[]>(
steps: T,
defaultStep: T[number],
) => {
const router = useRouter();
const searchParams = useSearchParams();

const setStep = useCallback(
(step: T[number]) => {
router.push({ query: { step } });
},
[router],
);

const FunnelComponent = useMemo(() => {
return Object.assign(
(props: Omit<FunnelProps<T>, 'step' | 'steps'>) => {
const step = searchParams.get('step') ?? defaultStep;

return <Funnel<T> steps={steps} step={step} {...props} />;
},
{ Step },
);
}, [defaultStep, searchParams, steps]);

return [FunnelComponent, setStep] as const;
};

0 comments on commit 5ee3150

Please sign in to comment.