Skip to content

Commit 5cc72d6

Browse files
committed
Reuse search input component
1 parent 8a85b37 commit 5cc72d6

File tree

2 files changed

+68
-92
lines changed

2 files changed

+68
-92
lines changed
Lines changed: 66 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -1,28 +1,71 @@
1-
import { Field, Form, Formik } from 'formik'
1+
import { useEffect, useRef } from 'react'
2+
import { Field, Form, Formik, useFormikContext } from 'formik'
23
import Button from '../button'
34

4-
const SearchInput = ({ onSearch, placeholder, 'data-cy': dataCy }) => (
5-
<Formik
6-
initialValues={{ search: '' }}
7-
onSubmit={({ search }) => onSearch(search)}
8-
>
9-
<Form className='form-control'>
10-
<Field
11-
data-cy={`${dataCy}-search-input`}
12-
type='text'
13-
name='search'
14-
id='search'
15-
placeholder={placeholder}
16-
/>
17-
<Button
18-
data-cy={`${dataCy}-search-submit`}
19-
type='submit'
20-
variant='submit'
5+
/**
6+
* This is a helper component to auto-submit search values after a timeout
7+
*/
8+
const AutoSubmitSearch = () => {
9+
const timerRef = useRef(null)
10+
11+
const { values, touched, submitForm } = useFormikContext()
12+
13+
useEffect(() => {
14+
// Check if input was touched. Formik behavior is to update 'touched'
15+
// flag on input blur or submit, but we want to submit changes also on
16+
// key press. 'touched' is not a useEffect dependency because it is
17+
// constantly updated without value changes.
18+
const isTouched = touched.search || values?.search.length > 0
19+
20+
// If search is touched
21+
if (isTouched) {
22+
// Clear previous timeout, if exists
23+
if (timerRef.current) {
24+
clearTimeout(timerRef.current)
25+
}
26+
// Define new timeout
27+
timerRef.current = setTimeout(submitForm, 1000)
28+
}
29+
30+
// Clear timeout on unmount
31+
return () => timerRef.current && clearTimeout(timerRef.current)
32+
}, [values])
33+
34+
return null
35+
}
36+
37+
/**
38+
* The search input
39+
*/
40+
const SearchInput = ({ onSearch, placeholder, 'data-cy': dataCy }) => {
41+
return (
42+
<Formik
43+
initialValues={{ search: '' }}
44+
onSubmit={({ search }) => onSearch(search)}
45+
>
46+
<Form
47+
className='form-control justify-start'
48+
style={{ alignItems: 'stretch' }}
2149
>
22-
Search
23-
</Button>
24-
</Form>
25-
</Formik>
26-
)
50+
<Field
51+
data-cy={`${dataCy}-search-input`}
52+
type='search'
53+
name='search'
54+
id='search'
55+
placeholder={placeholder}
56+
style={{ width: '12rem' }}
57+
/>
58+
<Button
59+
data-cy={`${dataCy}-search-submit`}
60+
type='submit'
61+
variant='submit'
62+
useIcon='magnifier-left'
63+
flat
64+
/>
65+
<AutoSubmitSearch />
66+
</Form>
67+
</Formik>
68+
)
69+
}
2770

2871
export default SearchInput

src/components/tables/users.js

Lines changed: 2 additions & 69 deletions
Original file line numberDiff line numberDiff line change
@@ -1,77 +1,10 @@
11
import T from 'prop-types'
22
import Table from './table'
33
import { useFetchList } from '../../hooks/use-fetch-list'
4-
import { useEffect, useRef, useState } from 'react'
4+
import { useState } from 'react'
55
import Pagination from '../pagination'
66
import qs from 'qs'
7-
import { Field, Form, Formik, useFormikContext } from 'formik'
8-
import Button from '../button'
9-
10-
/**
11-
* This is a helper component to auto-submit search values after a timeout
12-
*/
13-
const AutoSubmitSearch = () => {
14-
const timerRef = useRef(null)
15-
16-
const { values, touched, submitForm } = useFormikContext()
17-
18-
useEffect(() => {
19-
// Check if input was touched. Formik behavior is to update 'touched'
20-
// flag on input blur or submit, but we want to submit changes also on
21-
// key press. 'touched' is not a useEffect dependency because it is
22-
// constantly updated without value changes.
23-
const isTouched = touched.search || values?.search.length > 0
24-
25-
// If search is touched
26-
if (isTouched) {
27-
// Clear previous timeout, if exists
28-
if (timerRef.current) {
29-
clearTimeout(timerRef.current)
30-
}
31-
// Define new timeout
32-
timerRef.current = setTimeout(submitForm, 1000)
33-
}
34-
35-
// Clear timeout on unmount
36-
return () => timerRef.current && clearTimeout(timerRef.current)
37-
}, [values])
38-
39-
return null
40-
}
41-
42-
/**
43-
* The search input
44-
*/
45-
const SearchInput = ({ onSearch, 'data-cy': dataCy }) => {
46-
return (
47-
<Formik
48-
initialValues={{ search: '' }}
49-
onSubmit={({ search }) => onSearch(search)}
50-
>
51-
<Form
52-
className='form-control justify-start'
53-
style={{ alignItems: 'stretch' }}
54-
>
55-
<Field
56-
data-cy={`${dataCy}-search-input`}
57-
type='search'
58-
name='search'
59-
id='search'
60-
placeholder='Search username...'
61-
style={{ width: '12rem' }}
62-
/>
63-
<Button
64-
data-cy={`${dataCy}-search-submit`}
65-
type='submit'
66-
variant='submit'
67-
useIcon='magnifier-left'
68-
flat
69-
/>
70-
<AutoSubmitSearch />
71-
</Form>
72-
</Formik>
73-
)
74-
}
7+
import SearchInput from './search-input'
758

769
function UsersTable({ type, orgId, onRowClick, isSearchable }) {
7710
const [page, setPage] = useState(1)

0 commit comments

Comments
 (0)