From a917e607abf6dce0c4870d43a8c6eda51a368cdc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fran=C3=A7ois=20Chalifour?= Date: Thu, 9 Apr 2020 17:58:15 +0200 Subject: [PATCH] feat(docsearch): animate cards on action --- src/Results.tsx | 208 +++++++++++++++++++++++++++----------------- src/StartScreen.tsx | 31 +++++-- src/style.css | 14 +++ 3 files changed, 164 insertions(+), 89 deletions(-) diff --git a/src/Results.tsx b/src/Results.tsx index 83ca0b206..1e1319df9 100644 --- a/src/Results.tsx +++ b/src/Results.tsx @@ -21,7 +21,11 @@ interface ResultsProps title: string; suggestion: AutocompleteState['suggestions'][0]; renderIcon(props: { item: TItem; index: number }): React.ReactNode; - renderAction(props: { item: TItem }): React.ReactNode; + renderAction(props: { + item: TItem; + runDeleteTransition: (cb: () => void) => void; + runFavoriteTransition: (cb: () => void) => void; + }): React.ReactNode; onItemClick(item: TItem): void; hitComponent(props: { hit: DocSearchHit; @@ -36,8 +40,6 @@ export function Results( return null; } - const Hit = props.hitComponent; - return (
{props.title}
@@ -45,86 +47,132 @@ export function Results(
    {props.suggestion.items.map((item, index) => { return ( -
  • - -
    - {props.renderIcon({ item, index })} - - {item.hierarchy[item.type] && item.type === 'lvl1' && ( -
    - - {item.content && ( - - )} -
    - )} - - {item.hierarchy[item.type] && - (item.type === 'lvl2' || - item.type === 'lvl3' || - item.type === 'lvl4' || - item.type === 'lvl5' || - item.type === 'lvl6') && ( -
    - - -
    - )} - - {item.type === 'content' && ( -
    - - -
    - )} - - {props.renderAction({ item })} -
    -
    -
  • + ); })}
); } + +interface ResultProps extends ResultsProps { + item: TItem; + index: number; +} + +function Result({ + item, + index, + renderIcon, + renderAction, + getItemProps, + onItemClick, + suggestion, + hitComponent, +}: ResultProps) { + const [isDeleting, setIsDeleting] = React.useState(false); + const [isFavoriting, setIsFavoriting] = React.useState(false); + const action = React.useRef<(() => void) | null>(null); + const Hit = hitComponent; + + function runDeleteTransition(cb: () => void) { + setIsDeleting(true); + action.current = cb; + } + + function runFavoriteTransition(cb: () => void) { + setIsFavoriting(true); + action.current = cb; + } + + return ( +
  • { + if (action.current) { + action.current(); + } + }} + {...getItemProps({ + item, + source: suggestion.source, + onClick() { + onItemClick(item); + }, + })} + > + +
    + {renderIcon({ item, index })} + + {item.hierarchy[item.type] && item.type === 'lvl1' && ( +
    + + {item.content && ( + + )} +
    + )} + + {item.hierarchy[item.type] && + (item.type === 'lvl2' || + item.type === 'lvl3' || + item.type === 'lvl4' || + item.type === 'lvl5' || + item.type === 'lvl6') && ( +
    + + +
    + )} + + {item.type === 'content' && ( +
    + + +
    + )} + + {renderAction({ item, runDeleteTransition, runFavoriteTransition })} +
    +
    +
  • + ); +} diff --git a/src/StartScreen.tsx b/src/StartScreen.tsx index bb78efac3..12bc73aa4 100644 --- a/src/StartScreen.tsx +++ b/src/StartScreen.tsx @@ -47,7 +47,11 @@ export function StartScreen(props: StartScreenProps) { )} - renderAction={({ item }) => ( + renderAction={({ + item, + runFavoriteTransition, + runDeleteTransition, + }) => ( <>
    )} - renderAction={({ item }) => ( + renderAction={({ item, runDeleteTransition }) => (