SearchField.tsx 1.2 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950
  1. import React, { useState, useRef } from 'react';
  2. import { useDebounce } from 'react-use';
  3. import { FilterInput } from '@grafana/ui';
  4. interface Props {
  5. value?: string;
  6. onSearch: (value: string) => void;
  7. }
  8. // useDebounce has a bug which causes it to fire on first render. This wrapper prevents that.
  9. // https://github.com/streamich/react-use/issues/759
  10. const useDebounceWithoutFirstRender = (callBack: () => any, delay = 0, deps: React.DependencyList = []) => {
  11. const isFirstRender = useRef(true);
  12. const debounceDeps = [...deps, isFirstRender];
  13. return useDebounce(
  14. () => {
  15. if (isFirstRender.current) {
  16. isFirstRender.current = false;
  17. return;
  18. }
  19. return callBack();
  20. },
  21. delay,
  22. debounceDeps
  23. );
  24. };
  25. export const SearchField = ({ value, onSearch }: Props) => {
  26. const [query, setQuery] = useState(value);
  27. useDebounceWithoutFirstRender(() => onSearch(query ?? ''), 500, [query]);
  28. return (
  29. <FilterInput
  30. value={query}
  31. onKeyDown={(e) => {
  32. if (e.key === 'Enter' || e.keyCode === 13) {
  33. onSearch(e.currentTarget.value);
  34. }
  35. }}
  36. placeholder="Search Grafana plugins"
  37. onChange={(value) => {
  38. setQuery(value);
  39. }}
  40. width={46}
  41. />
  42. );
  43. };