react-router-dom#useSearchParams TypeScript Examples

The following examples show how to use react-router-dom#useSearchParams. You can vote up the ones you like or vote down the ones you don't like, and go to the original project or source file by following the links above each example. You may check out the related API usage on the sidebar.
Example #1
Source File: Header.tsx    From gear-js with GNU General Public License v3.0 7 votes vote down vote up
Header = ({ closeSidebar, selectedNode }: Props) => {
  const [searchParams, setSearchParams] = useSearchParams();

  const removeNodeFromUrl = () => {
    searchParams.delete(NODE_ADRESS_URL_PARAM);
    // push instead of replace to preserve previous node param history
    setSearchParams(searchParams);
  };

  const switchNode = () => {
    // remove param to update it during nodeApi init
    removeNodeFromUrl();
    localStorage.setItem(LOCAL_STORAGE.NODE_ADDRESS, selectedNode);
    window.location.reload();
  };

  return (
    <header className={styles.header}>
      <Button
        text="Switch"
        size="small"
        icon={refresh}
        onClick={switchNode}
        disabled={selectedNode === nodeApi.address}
      />
      <Button aria-label="Close sidebar" icon={cross} color="transparent" onClick={closeSidebar} />
    </header>
  );
}
Example #2
Source File: GameWithReactRedux.test.tsx    From minesweeper with MIT License 7 votes vote down vote up
jest.mock('react-router-dom', () => ({
  useSearchParams: jest.fn(),
}));
Example #3
Source File: hooks.ts    From your_spotify with GNU General Public License v3.0 7 votes vote down vote up
export function useNavigateAndSearch() {
  const navigate = useNavigate();
  const [query] = useSearchParams();

  return useCallback(
    (url: string, params: Record<string, string | undefined>) => {
      Object.entries(params).forEach(([key, value]) => {
        if (value !== undefined) {
          query.set(key, value);
        }
      });
      navigate(`${url}?${query.toString()}`);
    },
    [navigate, query],
  );
}
Example #4
Source File: intervals.ts    From your_spotify with GNU General Public License v3.0 6 votes vote down vote up
export function useOldestListenedAtFromUsers(userIds: string[], prefix: string): RawIntervalDetail {
  const user = useSelector(selectUser);
  const users = useSelector(selectAccounts);
  const [query] = useSearchParams();

  const detail = useMemo(() => queryToIntervalDetail(query, prefix), [prefix, query]);

  const filtered = users.filter((us) => [user?._id, ...userIds].includes(us.id));
  const mins = getMinOfArray(filtered, (item) => new Date(item.firstListenedAt).getTime());
  const account = filtered[mins?.minIndex ?? 0];
  const accountInterval = useMemo(() => getRawIntervalDetail(detail, account), [account, detail]);

  if (!account && detail.type === 'userbased') {
    return getRawIntervalDetail(presetIntervals[0], null);
  }
  return accountInterval;
}
Example #5
Source File: Pagination.tsx    From gear-js with GNU General Public License v3.0 6 votes vote down vote up
Pagination = ({ page, pagesAmount }: Props) => {
  const [searchParams] = useSearchParams();
  const totalPages = Math.ceil(pagesAmount / INITIAL_LIMIT_BY_PAGE);
  const prevPage = page - 1;
  const nextPage = page + 1;
  const prevPageClasses = clsx('pagination--box', page === 1 && 'disabled');
  const nextPageClasses = clsx('pagination--box', page === totalPages && 'disabled');

  const getTo = (pageValue: number) => {
    searchParams.set(URL_PARAMS.PAGE, String(pageValue));

    return { search: searchParams.toString() };
  };

  return (
    <div className="pagination">
      <Link className={prevPageClasses} to={getTo(prevPage)}>
        <img className="pagination--img-prev" src={arrow} alt="arrow" />
      </Link>
      <button type="button" className="pagination--box selected">
        {page}
      </button>
      <p className="pagination__total">of {totalPages}</p>
      <Link className={nextPageClasses} to={getTo(nextPage)}>
        <img className="pagination--img" src={arrow} alt="arrow" />
      </Link>
    </div>
  );
}
Example #6
Source File: GameWithReactRedux.test.tsx    From minesweeper with MIT License 6 votes vote down vote up
(useSearchParams as jest.Mock).mockReturnValue([
  { get: () => null },
  jest.fn(),
]);
Example #7
Source File: deepLink.ts    From celo-web-wallet with MIT License 6 votes vote down vote up
export function useDeepLinkHandler() {
  const [searchParams] = useSearchParams()
  const dispatch = useAppDispatch()
  const navigate = useNavigate()
  const location = useLocation()

  useEffect(() => {
    // WalletConnect URI
    const path = trimSlashes(location.pathname)
    if (path === 'wc' && searchParams.has('uri')) {
      logger.info('WalletConnect URI found in URL')
      const uri = decodeURIComponent(searchParams.get('uri') || '')
      const validation = validateWalletConnectForm({ uri })
      if (validation.isValid) dispatch(initializeWcClient(uri))
      // For now, the app doesn't use search params for anything else
      // so it's safe to clear them. This may need to change eventually
      // Note, not using setSearchParams here because it leaves a ? in the url
      navigate('/', { replace: true })
    }
  }, [])
}
Example #8
Source File: useQueryParamState.ts    From backstage with Apache License 2.0 6 votes vote down vote up
export function useQueryParamState<T>(
  stateName: string,
  /** @deprecated Don't configure a custom debouceTime */
  debounceTime: number = 250,
): [T | undefined, SetQueryParams<T>] {
  const [searchParams, setSearchParams] = useSearchParams();
  const searchParamsString = searchParams.toString();
  const [queryParamState, setQueryParamState] = useState<T>(
    extractState(searchParamsString, stateName),
  );

  useEffect(() => {
    const newState = extractState(searchParamsString, stateName);

    setQueryParamState(oldState =>
      isEqual(newState, oldState) ? oldState : newState,
    );
  }, [searchParamsString, setQueryParamState, stateName]);

  useDebouncedEffect(
    () => {
      const queryString = joinQueryString(
        searchParamsString,
        stateName,
        queryParamState,
      );

      if (searchParamsString !== queryString) {
        setSearchParams(queryString, { replace: true });
      }
    },
    [setSearchParams, queryParamState, searchParamsString, stateName],
    debounceTime,
  );

  return [queryParamState, setQueryParamState];
}
Example #9
Source File: MinesweeperWithHooks.tsx    From minesweeper with MIT License 6 votes vote down vote up
MinesweeperWithHooks: FC = () => {
  const [searchParams] = useSearchParams();
  const { username } = useParams<{ username?: string }>();

  const id = searchParams.get('id');

  return (
    <GameLayout
      top={
        <Top feature="Flag" firstAction="right click">
          Minesweeper with ReactHooks special for you
          {username && `, ${username}`}
          {id && `; userId: ${id}`}
        </Top>
      }
    >
      <GameWithHooks />
    </GameLayout>
  );
}
Example #10
Source File: useSkeletonMenu.tsx    From OpenBA-NextGenTV with MIT License 6 votes vote down vote up
useSkeletonMenu = () => {
  const [searchParams, setSearchParams] = useSearchParams();
  const getComponentKey = (param: MenuPosition) => searchParams.get(param) as SkeletonMenuElement;

  const getSkeletonComponent = (param: MenuPosition): ReactElement => {
    const elementKey = getComponentKey(param);

    return elementKey && skeletonMenuComponentsMap[elementKey];
  };

  const setMenuComponent = (params: { [key in MenuPosition]?: string }) => {
    const allParams: Record<string, string> = {};

    searchParams.forEach((value, key) => {
      allParams[key] = value;
    });

    setSearchParams({ ...allParams, ...params });
  };

  return { getSkeletonComponent, setMenuComponent, getComponentKey };
}
Example #11
Source File: ApiContext.tsx    From contracts-ui with GNU General Public License v3.0 6 votes vote down vote up
ApiContextProvider = ({ children }: React.PropsWithChildren<Partial<ApiState>>) => {
  const [searchParams] = useSearchParams();
  const rpcUrl = searchParams.get('rpc');
  const [preferredEndpoint, setPreferredEndpoint] = useLocalStorage<string>(
    'preferredEndpoint',
    RPC.LOCAL
  );
  const [state, dispatch] = useReducer(apiReducer, { ...INIT_STATE, endpoint: preferredEndpoint });
  const { endpoint, keyringStatus, status } = state;

  useEffect(() => {
    if (rpcUrl && isValidWsUrl(rpcUrl) && rpcUrl !== preferredEndpoint) {
      dispatch({ type: 'SET_ENDPOINT', payload: rpcUrl });
      setPreferredEndpoint(rpcUrl);
      window.location.reload();
    }
  }, [preferredEndpoint, rpcUrl, searchParams, setPreferredEndpoint]);

  useEffect((): void => {
    connect(endpoint, dispatch);
  }, [endpoint]);

  useEffect(() => {
    if (status === 'READY' && !keyringStatus && !keyringLoadAll) {
      keyringLoadAll = true;
      loadAccounts(state, dispatch);
    }
  }, [state, dispatch, status, keyringStatus]);

  return <ApiContext.Provider value={state}>{children}</ApiContext.Provider>;
}
Example #12
Source File: GameWithHooks.snap.test.tsx    From minesweeper with MIT License 5 votes vote down vote up
(useSearchParams as jest.Mock).mockReturnValue([
  { get: () => null },
  mockSetSearchParams,
]);
Example #13
Source File: GameWithHooks.test.tsx    From minesweeper with MIT License 5 votes vote down vote up
(useSearchParams as jest.Mock).mockReturnValue([
  { get: () => null },
  mockSetSearchParams,
]);
Example #14
Source File: GameWithHooks.test.tsx    From minesweeper with MIT License 5 votes vote down vote up
describe('GameWithHooks test cases', () => {
  it('Render game field by default', () => {
    const { asFragment } = render(<GameWithHooks />);
    expect(asFragment()).toMatchSnapshot();
  });
  it('Cell click works fine', () => {
    render(<GameWithHooks />);
    userEvent.click(screen.getByTestId('0,0'));
    expect(mockOnClick).toHaveBeenCalled();
  });
  it('Context menu handler on a cell works fine', () => {
    render(<GameWithHooks />);
    userEvent.click(screen.getByTestId('0,0'), { button: 2 });
    expect(mockOnContextMenu).toHaveBeenCalled();
  });
  it('Reset handler works fine', () => {
    render(<GameWithHooks />);
    userEvent.click(screen.getByRole('button'));
    expect(mockOnReset).toHaveBeenCalled();
  });
  it('Change level works fine', () => {
    render(<GameWithHooks />);
    userEvent.selectOptions(screen.getByRole('combobox'), 'intermediate');
    expect(mockOnChangeLevel).toHaveBeenCalled();
    expect(mockSetSearchParams).toHaveBeenCalledWith({ level: 'intermediate' });
  });
  it('Level in search params works fine', () => {
    (useSearchParams as jest.Mock).mockReturnValue([
      { get: () => 'intermediate' },
    ]);
    render(<GameWithHooks />);
    const intermediateOption = screen.queryByText('intermediate');
    expect(intermediateOption).toBeInTheDocument();
  });
  it('Game over reset the game state', () => {
    render(<GameWithHooks />);
    userEvent.click(screen.getByText('?'));
    expect(mockOnReset).toHaveBeenCalled();
  });
});
Example #15
Source File: GameWithHooks.tsx    From minesweeper with MIT License 5 votes vote down vote up
GameWithHooks: FC = () => {
  const [searchParams, setSearchParams] = useSearchParams();

  const urlLevelParam = (searchParams.get('level') || undefined) as LevelNames;

  const {
    level,
    time,
    isGameOver,
    isWin,
    settings,
    playerField,
    flagCounter,
    onClick,
    onContextMenu,
    onChangeLevel,
    onReset,
  } = useGame(urlLevelParam);

  const [, bombs] = settings;

  const onChangeLevelHandler = useCallback(
    ({ target: { value: level } }: React.ChangeEvent<HTMLSelectElement>) => {
      setSearchParams({ level });
      onChangeLevel(level as LevelNames);
    },
    // Stryker disable next-line ArrayDeclaration
    []
  );

  return (
    <>
      <Scoreboard
        time={String(time)}
        bombs={String(bombs - flagCounter)}
        levels={GameLevels as unknown as string[]}
        defaultLevel={level}
        onChangeLevel={onChangeLevelHandler}
        onReset={onReset}
      />
      {isGameOver && <GameOver onClick={onReset} isWin={isWin} />}
      <Grid onClick={onClick} onContextMenu={onContextMenu}>
        {playerField}
      </Grid>
    </>
  );
}
Example #16
Source File: GameWithHooks.test.tsx    From minesweeper with MIT License 5 votes vote down vote up
jest.mock('react-router-dom', () => ({
  useSearchParams: jest.fn(),
}));
Example #17
Source File: Recent.tsx    From gear-js with GNU General Public License v3.0 5 votes vote down vote up
Recent = () => {
  const [searchParams, setSearchParams] = useSearchParams();
  const { account } = useAccount();

  const page = searchParams.has(URL_PARAMS.PAGE) ? Number(searchParams.get(URL_PARAMS.PAGE)) : 1;
  const query = searchParams.has(URL_PARAMS.QUERY) ? String(searchParams.get(URL_PARAMS.QUERY)) : '';

  const [programs, setPrograms] = useState<ProgramModel[]>([]);
  const [programsCount, setProgramsCount] = useState(0);

  useChangeEffect(() => {
    searchParams.set(URL_PARAMS.PAGE, String(1));
    searchParams.set(URL_PARAMS.QUERY, '');
    setSearchParams(searchParams);
  }, [account]);

  useEffect(() => {
    if (account) {
      const params = {
        query,
        owner: GearKeyring.decodeAddress(account.address),
        limit: INITIAL_LIMIT_BY_PAGE,
        offset: (page - 1) * INITIAL_LIMIT_BY_PAGE,
      };

      getUserPrograms(params).then(({ result }) => {
        setPrograms(result.programs);
        setProgramsCount(result.count);
      });
    }
  }, [page, query, account]);

  return (
    <div className={styles.blockList}>
      <div className={styles.paginationWrapper}>
        <span>Total results: {programsCount || 0}</span>
        <Pagination page={page} pagesAmount={programsCount || 1} />
      </div>
      <SearchForm placeholder="Find program" />
      <ProgramsLegend />
      <div>
        {programs.map((program: ProgramModel) => (
          <UserProgram key={program.id} program={program} />
        ))}
      </div>
      {programsCount > 0 && (
        <div className={styles.paginationBottom}>
          <Pagination page={page} pagesAmount={programsCount || 1} />
        </div>
      )}
    </div>
  );
}
Example #18
Source File: Scoreboard.test.tsx    From minesweeper with MIT License 5 votes vote down vote up
jest.mock('react-router-dom', () => ({
  useSearchParams: jest.fn(),
}));
Example #19
Source File: Scoreboard.test.tsx    From minesweeper with MIT License 5 votes vote down vote up
(useSearchParams as jest.Mock).mockReturnValue([
  { get: () => null },
  mockSetSearchParams,
]);
Example #20
Source File: Scoreboard.tsx    From minesweeper with MIT License 5 votes vote down vote up
Scoreboard: FC = () => {
  const [searchParams, setSearchParams] = useSearchParams();
  const dispatch = useDispatch();

  useEffect(() => {
    const urlLevelParam = (searchParams.get('level') ||
      undefined) as LevelNames;
    if (urlLevelParam) {
      dispatch(actions.changeLevel(urlLevelParam as LevelNames));
    }
  }, []);

  const { level, time, bombs, flagCounter } = useSelector(
    ({ game: { level, time, bombs, flagCounter } }: RootState) => ({
      level,
      time,
      bombs,
      flagCounter,
    })
  );

  const onChangeLevel = useCallback(
    ({ target: { value: level } }: React.ChangeEvent<HTMLSelectElement>) => {
      setSearchParams({ level });
      dispatch(actions.changeLevel(level as LevelNames));
    },
    // Stryker disable next-line ArrayDeclaration
    []
  );

  const onReset = useCallback(
    () => dispatch(actions.reset()),
    // Stryker disable next-line ArrayDeclaration
    []
  );

  return (
    <ScoreboardComponent
      time={String(time)}
      bombs={String(bombs - flagCounter)}
      levels={GameLevels as unknown as string[]}
      defaultLevel={level}
      onChangeLevel={onChangeLevel}
      onReset={onReset}
    />
  );
}
Example #21
Source File: GameWithUseReducer.test.tsx    From minesweeper with MIT License 5 votes vote down vote up
jest.mock('react-router-dom', () => ({
  useSearchParams: jest.fn(),
}));
Example #22
Source File: GameWithUseReducer.test.tsx    From minesweeper with MIT License 5 votes vote down vote up
(useSearchParams as jest.Mock).mockReturnValue([
  { get: () => null },
  mockSetSearchParams,
]);
Example #23
Source File: GameWithUseReducer.tsx    From minesweeper with MIT License 5 votes vote down vote up
GameWithUseReducer: FC = () => {
  const [searchParams, setSearchParams] = useSearchParams();
  const urlLevelParam = (searchParams.get('level') || undefined) as LevelNames;

  const [
    { level, time, isGameOver, isWin, settings, playerField, flagCounter },
    dispatch,
  ] = useReducer(reducer, getInitialState(urlLevelParam));

  const [, bombs] = settings;

  const onClick = useCallback(
    (coords: Coords) => dispatch(actions.openCell(coords)),
    // Stryker disable next-line ArrayDeclaration
    []
  );

  const onContextMenu = useCallback(
    (coords: Coords) => dispatch(actions.setFlag(coords)),
    // Stryker disable next-line ArrayDeclaration
    []
  );

  const onReset = useCallback(
    () => dispatch(actions.reset()),
    // Stryker disable next-line ArrayDeclaration
    []
  );

  const onChangeLevel = useCallback(
    ({ target: { value: level } }: React.ChangeEvent<HTMLSelectElement>) => {
      setSearchParams({ level });
      dispatch(actions.changeLevel(level as LevelNames));
    },
    // Stryker disable next-line ArrayDeclaration
    []
  );

  return (
    <>
      <Scoreboard
        time={String(time)}
        bombs={String(bombs - flagCounter)}
        levels={GameLevels as unknown as string[]}
        defaultLevel={level}
        onChangeLevel={onChangeLevel}
        onReset={onReset}
      />
      {isGameOver && <GameOver onClick={onReset} isWin={isWin} />}
      <Grid onClick={onClick} onContextMenu={onContextMenu}>
        {playerField}
      </Grid>
    </>
  );
}
Example #24
Source File: App.tsx    From minesweeper with MIT License 5 votes vote down vote up
Navigation: FC = () => {
  const [searchParams] = useSearchParams();
  const level = searchParams.get('level') || '';

  const getLocationObjWithSearchParams = (
    pathname: string
  ): Partial<Location> => ({
    pathname,
    search: `${
      level &&
      `?${new URLSearchParams({
        level,
      }).toString()}`
    }`,
  });

  return (
    <nav>
      <ul>
        <li>
          <Link to={getLocationObjWithSearchParams('/')}>Home</Link>
        </li>
        <li>
          <Link to={getLocationObjWithSearchParams('/minesweeper/hooks')}>
            Game With Hooks
          </Link>
        </li>
        <li>
          <Link to={getLocationObjWithSearchParams('/minesweeper/usereducer')}>
            Game With useReducer
          </Link>
        </li>
        <li>
          <Link to={getLocationObjWithSearchParams('/minesweeper/reactredux')}>
            Game With ReactRedux
          </Link>
        </li>
      </ul>
    </nav>
  );
}
Example #25
Source File: AppWrapper.tsx    From flood with GNU General Public License v3.0 5 votes vote down vote up
AppWrapper: FC<AppWrapperProps> = observer(({children, className}: AppWrapperProps) => {
  const navigate = useNavigate();

  const [searchParams] = useSearchParams();

  useEffectOnce(() => {
    AuthActions.verify().then(
      ({initialUser}: {initialUser?: boolean}): void => {
        if (initialUser) {
          navigate('/register', {replace: true});
        } else {
          navigate('/overview', {replace: true});
        }
      },
      (): void => {
        navigate('/login', {replace: true});
      },
    );
  });

  if (searchParams.has('action')) {
    if (searchParams.get('action') === 'add-urls') {
      if (searchParams.has('url')) {
        UIStore.setActiveModal({
          id: 'add-torrents',
          tab: 'by-url',
          urls: [{id: 0, value: searchParams.get('url') as string}],
        });
      }
    }
  }

  let overlay: ReactNode = null;
  if (!AuthStore.isAuthenticating || (AuthStore.isAuthenticated && !UIStore.haveUIDependenciesResolved)) {
    overlay = <LoadingOverlay dependencies={UIStore.dependencies} />;
  }

  if (AuthStore.isAuthenticated && !ClientStatusStore.isConnected && ConfigStore.authMethod !== 'none') {
    overlay = (
      <div className="application__loading-overlay">
        <div className="application__entry-barrier">
          <LogoutButton className={css({position: 'absolute', left: '5px', top: '5px'})} />
          <ClientConnectionInterruption />
        </div>
      </div>
    );
  }

  return (
    <div className={classnames('application', className)}>
      <WindowTitle />
      <TransitionGroup>
        {overlay != null ? (
          <CSSTransition timeout={{enter: 1000, exit: 1000}} classNames="application__loading-overlay">
            {overlay}
          </CSSTransition>
        ) : null}
      </TransitionGroup>
      {children}
    </div>
  );
})
Example #26
Source File: GameWithHooks.snap.test.tsx    From minesweeper with MIT License 5 votes vote down vote up
jest.mock('react-router-dom', () => ({
  useSearchParams: jest.fn(),
}));
Example #27
Source File: All.tsx    From gear-js with GNU General Public License v3.0 5 votes vote down vote up
All = () => {
  const [searchParams] = useSearchParams();
  const { account } = useAccount();
  const accountDecodedAddress = GearKeyring.decodeAddress(account?.address || '0x00');

  const page = searchParams.has(URL_PARAMS.PAGE) ? Number(searchParams.get(URL_PARAMS.PAGE)) : 1;
  const query = searchParams.has(URL_PARAMS.QUERY) ? String(searchParams.get(URL_PARAMS.QUERY)) : '';

  const [programs, setPrograms] = useState<ProgramModel[]>([]);
  const [programsCount, setProgramsCount] = useState(0);

  useEffect(() => {
    const programParams = { limit: INITIAL_LIMIT_BY_PAGE, offset: (page - 1) * INITIAL_LIMIT_BY_PAGE, query };

    getPrograms(programParams).then(({ result }) => {
      setPrograms(result.programs);
      setProgramsCount(result.count);
    });
  }, [page, query]);

  return (
    <div className="all-programs">
      <div className={styles.paginationWrapper}>
        <span>Total results: {programsCount || 0}</span>
        <Pagination page={page} pagesAmount={programsCount || 1} />
      </div>
      <SearchForm placeholder="Find program" />
      <ProgramsLegend />
      <div className={styles.allProgramsList}>
        {programs.map((program: ProgramModel) => (
          <UserProgram key={program.id} program={program} isMetaLinkActive={accountDecodedAddress === program.owner} />
        ))}
      </div>
      {programsCount > 0 && (
        <div className={styles.paginationBottom}>
          <Pagination page={page} pagesAmount={programsCount || 1} />
        </div>
      )}
    </div>
  );
}
Example #28
Source File: Messages.tsx    From gear-js with GNU General Public License v3.0 5 votes vote down vote up
Messages = () => {
  const [searchParams, setSearchParams] = useSearchParams();
  const { account } = useAccount();

  const page = searchParams.has(URL_PARAMS.PAGE) ? Number(searchParams.get(URL_PARAMS.PAGE)) : 1;
  const query = searchParams.has(URL_PARAMS.QUERY) ? String(searchParams.get(URL_PARAMS.QUERY)) : '';

  const [messages, setMessages] = useState<MessageModel[]>([]);
  const [messagesCount, setMessagesCount] = useState(0);

  useChangeEffect(() => {
    searchParams.set(URL_PARAMS.PAGE, String(1));
    searchParams.set(URL_PARAMS.QUERY, '');
    setSearchParams(searchParams);
  }, [account]);

  useEffect(() => {
    if (account) {
      const messageParams = {
        destination: GearKeyring.decodeAddress(account.address),
        limit: INITIAL_LIMIT_BY_PAGE,
        offset: (page - 1) * INITIAL_LIMIT_BY_PAGE,
        query,
      };

      getMessages(messageParams).then(({ result }) => {
        setMessages(result.messages);
        setMessagesCount(result.count);
      });
    }
  }, [page, query, account]);

  return (
    <div className="messages">
      <div className="pagination__wrapper">
        <span className="pagination__wrapper-caption">Total results: {messagesCount || 0}</span>
        <Pagination page={page} pagesAmount={messagesCount || 1} />
      </div>
      <SearchForm placeholder="Find message by ID" />
      <MessagesList messages={messages} />
      {messagesCount > 0 && (
        <div className="pagination_bottom">
          <Pagination page={page} pagesAmount={messagesCount || 1} />
        </div>
      )}
    </div>
  );
}
Example #29
Source File: SearchForm.tsx    From gear-js with GNU General Public License v3.0 5 votes vote down vote up
SearchForm = ({ placeholder }: Props) => {
  const linkClasses = clsx(buttonStyles.button, buttonStyles.secondary, buttonStyles.small);
  const [searchParams, setSearchParams] = useSearchParams();
  const [value, setValue] = useState('');

  const handleChange = ({ target }: ChangeEvent<HTMLInputElement>) => {
    setValue(target.value);
  };

  const setUrlParams = () => {
    searchParams.set(URL_PARAMS.PAGE, String(1));
    searchParams.set(URL_PARAMS.QUERY, value);
  };

  const getTo = () => {
    setUrlParams();

    return { search: searchParams.toString() };
  };

  const resetSearch = () => {
    setValue('');
    searchParams.delete(URL_PARAMS.QUERY);
    setSearchParams(searchParams);
  };

  const handleSubmit = (event: FormEvent) => {
    event.preventDefault();

    setUrlParams();
    setSearchParams(searchParams);
  };

  return (
    <form onSubmit={handleSubmit}>
      <div className={styles.searchForm}>
        <Input
          icon={searchIcon}
          className={styles.inputWrapper}
          type="text"
          placeholder={placeholder}
          name={URL_PARAMS.QUERY}
          value={value}
          onChange={handleChange}
        />
        <Link className={linkClasses} to={getTo()}>
          <img className={buttonStyles.icon} src={searchIcon} alt="search icon" />
          Search
        </Link>
        <Button
          className={styles.resetButton}
          text="Reset search"
          type="reset"
          color="transparent"
          onClick={resetSearch}
        />
      </div>
    </form>
  );
}