-
Notifications
You must be signed in to change notification settings - Fork 37
/
MultiSelectOptionsList.js
121 lines (114 loc) · 3.13 KB
/
MultiSelectOptionsList.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
116
117
118
119
120
121
import React from 'react';
import PropTypes from 'prop-types';
import css from './MultiSelect.css';
import Popper from '../Popper';
import Icon from '../Icon';
const getMenuStyle = (atSmallMedia, containerWidth) => {
return atSmallMedia ?
{ width: '100%' } :
{ width: `${containerWidth}px` }
}
const getListStyle = (atSmallMedia, maxHeight) => {
return atSmallMedia ?
{ maxHeight: '60vh' } :
{ maxHeight: `${maxHeight}px` }
};
const getPortal = (renderToOverlay, usePortal) => {
return (renderToOverlay || usePortal) ? document.getElementById('OverlayContainer') : undefined;
}
const MultiSelectOptionsList = ({
asyncFiltering,
atSmallMedia,
containerWidth,
controlRef,
emptyMessage,
error,
getMenuProps,
id,
isOpen,
labelId,
maxHeight,
modifiers,
renderActions,
renderedItems,
renderFilterInput,
renderOptions,
renderToOverlay,
usePortal,
warning,
}) => {
const control = (
<>
{atSmallMedia && renderFilterInput()}
<div role="alert" className={css.multiSelectFeedback}>
{error && <div className={css.multiSelectError}>{error}</div>}
{warning && <div className={css.multiSelectWarning}>{warning}</div>}
{renderedItems && renderedItems?.length === 0 &&
<div className={css.multiSelectEmptyMessage}>{emptyMessage}</div>
}
{asyncFiltering && renderedItems.length === 0 && (<Icon icon="spinner-ellipsis" />)}
</div>
<ul
style={getListStyle(atSmallMedia, maxHeight)}
{...getMenuProps({ id })}
aria-labelledby={labelId}
className={css.multiSelectOptionList}
>
{renderOptions()}
{renderActions()}
</ul>
</>
);
if (atSmallMedia) {
return (
<div
className={css.multiSelectMenu}
style={getMenuStyle(atSmallMedia, containerWidth)}
>
{ control}
</div>
)
}
return (
<Popper
anchorRef={controlRef}
overlayProps={{
className: css.multiSelectMenu,
style: getMenuStyle(atSmallMedia, containerWidth)
}}
modifiers={modifiers}
isOpen={isOpen}
portal={getPortal(renderToOverlay, usePortal)}
placement="bottom-start"
hideIfClosed
>
{control}
</Popper>
);
};
MultiSelectOptionsList.propTypes = {
asyncFiltering: PropTypes.bool,
atSmallMedia: PropTypes.bool,
containerWidth: PropTypes.number,
controlRef: PropTypes.object,
emptyMessage: PropTypes.node,
error: PropTypes.node,
getMenuProps: PropTypes.func,
id: PropTypes.string,
isOpen: PropTypes.bool,
labelId: PropTypes.string,
maxHeight: PropTypes.number,
modifiers: PropTypes.object,
renderActions: PropTypes.func,
renderedItems: PropTypes.oneOfType([
PropTypes.arrayOf(PropTypes.string),
PropTypes.arrayOf(PropTypes.object)
]),
renderFilterInput: PropTypes.func,
renderOptions: PropTypes.func,
renderToOverlay: PropTypes.bool,
useLegacy: PropTypes.bool,
usePortal: PropTypes.bool,
warning: PropTypes.node,
};
export default MultiSelectOptionsList;