forked from vtex-apps/search-result
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathFilterOptionTemplate.js
115 lines (104 loc) · 2.89 KB
/
FilterOptionTemplate.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
import PropTypes from 'prop-types'
import React, { useState, useCallback } from 'react'
import { Collapse } from 'react-collapse'
import classNames from 'classnames'
import { IconCaret } from 'vtex.store-icons'
import searchResult from '../searchResult.css'
/**
* Collapsable filters container
*/
const FilterOptionTemplate = ({
selected = false,
title,
collapsable = true,
children,
filters,
}) => {
const [open, setOpen] = useState(true)
const renderChildren = () => {
if (typeof children !== 'function') {
return children
}
return filters.map(children)
}
const handleKeyDown = useCallback(
e => {
if (e.key === ' ' && collapsable) {
e.preventDefault()
setOpen(!open)
}
},
[collapsable, open]
)
const containerClassName = classNames(searchResult.filter, 'pv5', {
[searchResult.filterSelected]: selected,
[searchResult.filterAvailable]: !selected,
})
const titleClassName = classNames(
searchResult.filterTitle,
'f5 flex items-center justify-between',
{
ttu: selected,
}
)
return (
<div className="bb b--muted-4">
<div className={containerClassName}>
<div
role="button"
tabIndex={collapsable ? 0 : undefined}
className={collapsable ? 'pointer' : ''}
onClick={() => collapsable && setOpen(!open)}
onKeyDown={handleKeyDown}
aria-disabled={!collapsable}
>
<div className={titleClassName}>
{title}
{collapsable && (
<span
className={classNames(
searchResult.filterIcon,
'flex items-center ph5 c-muted-3'
)}
>
<IconCaret orientation={open ? 'up' : 'down'} size={14} />
</span>
)}
</div>
</div>
</div>
<div
className={classNames({
'overflow-y-auto': collapsable,
pb5: !collapsable || open,
})}
style={{ maxHeight: '200px' }}
aria-hidden={!open}
>
{collapsable ? (
<Collapse
isOpened={open}
theme={{ content: searchResult.filterContent }}
>
{renderChildren()}
</Collapse>
) : (
renderChildren()
)}
</div>
</div>
)
}
FilterOptionTemplate.propTypes = {
/** Filters to be shown, if no filter is provided, treat the children as simple node */
filters: PropTypes.arrayOf(PropTypes.object),
/** Function to handle filter rendering or node if no filter is provided */
children: PropTypes.oneOfType([PropTypes.func, PropTypes.node]).isRequired,
/** Title */
title: PropTypes.node,
/** Whether collapsing is enabled */
collapsable: PropTypes.bool,
/** Whether it represents the selected filters */
selected: PropTypes.bool,
}
export default FilterOptionTemplate