main
ts 68 lines 2.54 KB
Raw
1 import { state, useSnapState } from './state'
2 import { createElement as h, useEffect, useState } from 'react'
3 import { useDebounce } from 'usehooks-ts'
4 import { Checkbox, CustomCode } from './components'
5 import { usePath } from './useFetchList'
6 import { onHfsEvent, with_ } from './misc'
7 import i18n from './i18n'
8 const { useI18N } = i18n
9
10 export function FilterBar() {
11 const { list, filteredList, selected, patternFilter, showFilter } = useSnapState()
12 const [all, setAll] = useState(false)
13 const [filter, setFilter] = useState(patternFilter)
14 useEffect(() => setAll(false), [patternFilter, usePath()]) // reset on change
15 const {t} = useI18N()
16
17 state.patternFilter = useDebounce(showFilter ? filter : '', 300)
18 useEffect(() => onHfsEvent('', 'entryToggleSelection', () => setAll(false)), [])
19
20 const tabIndex = showFilter ? undefined : -1
21 return h('div', { id: 'filter-bar', style: { display: showFilter ? undefined : 'none' } },
22 h(Checkbox, {
23 value: all,
24 tabIndex,
25 'aria-hidden': !showFilter,
26 'aria-label': t`Select all`,
27 onContextMenu(ev) {
28 ev.preventDefault()
29 select(undefined)
30 },
31 onChange(v, ev){
32 const toggle = with_(ev.nativeEvent as any, v => v.ctrlKey || v.metaKey)
33 select(toggle ? undefined : v)
34 },
35 }),
36 h('input', {
37 id: 'filter',
38 placeholder: t('filter_placeholder', "Type here to filter the list below"),
39 autoComplete: 'off',
40 value: filter,
41 tabIndex,
42 autoFocus: true,
43 onChange(ev) {
44 setFilter(ev.target.value)
45 }
46 }),
47 h(CustomCode, { name: 'afterFilter' }),
48 h('span', {}, [
49 with_(Object.keys(selected).length, n => n && t('select_count', { n }, "{n} selected")),
50 with_(filteredList?.length, n => n !== undefined && n < list.length && t('filter_count', {n}, "{n} filtered")),
51 ].filter(Boolean).join(', ') ),
52 )
53
54 function select(will: boolean | undefined) { // undefined will cause toggle of each element
55 const sel = state.selected
56 for (const e of state.filteredList || state.list) {
57 const { uri } = e
58 const was = sel[uri] || false
59 if (was === will) continue
60 if (was)
61 delete sel[uri]
62 else if (e.canSelect())
63 sel[uri] = true
64 }
65 if (will !== undefined)
66 setAll(will)
67 }
68 }