-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathBaseDropdown.tsx
More file actions
105 lines (94 loc) · 3.69 KB
/
BaseDropdown.tsx
File metadata and controls
105 lines (94 loc) · 3.69 KB
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
import React, { useContext, useState } from 'react';
import { Expander, ExpanderType } from '@ids-components/Expander';
import { ItemsContainer } from './components/ItemsContainer';
import { TranslatorContext } from '@ids-context/Translator';
import { createCssClassNames } from '@ids-core';
import { useKeyDown } from '@ids-hooks/useKeyEvent';
import { BaseDropdownItem, BaseDropdownProps } from './BaseDropdown.types';
const MAX_VISIBLE_ITEMS = 10;
export const BaseDropdown = <T extends BaseDropdownItem>({
children,
isEmpty = true,
isItemSelected,
items,
disabled = false,
error = false,
filterFunction = (item, searchTerm) => item.label.toLowerCase().includes(searchTerm.toLowerCase()),
getItemAttributes = () => ({}),
getNextFocusableItem = () => null,
maxVisibleItems = MAX_VISIBLE_ITEMS,
onDropdownItemClick,
renderEmptySelectionInfo,
renderItem = (item) => item.label,
renderSelectedItems = () => null,
renderSource = () => null,
className = '',
}: BaseDropdownProps<T>) => {
const Translator = useContext(TranslatorContext);
const [referenceElement, setReferenceElement] = useState<HTMLDivElement | null>(null);
const [isOpen, setIsOpen] = useState(false);
const dropdownClassName = createCssClassNames({
'ids-dropdown': true,
'ids-dropdown--disabled': disabled,
'ids-dropdown--error': error,
[className]: !!className,
});
const dropdownWidgetClassName = createCssClassNames({
'ids-dropdown__widget ids-input': true,
'ids-input--disabled': disabled,
'ids-input--error': error,
});
const toggleDropdown = () => {
setIsOpen(!isOpen);
};
const renderSelectionInfo = () => {
if (children) {
return children;
}
if (isEmpty) {
if (renderEmptySelectionInfo) {
return renderEmptySelectionInfo();
}
const placeholder = Translator.trans(/*@Desc("Select an item")*/ 'ids.dropdown.placeholder');
return <div className="ids-dropdown__placeholder">{placeholder}</div>;
}
return <div className="ids-dropdown__selection-info-items">{renderSelectedItems()}</div>;
};
useKeyDown(
['Enter', ' '],
(event) => {
const { activeElement } = window.document;
if (activeElement === referenceElement) {
event.preventDefault();
toggleDropdown();
}
},
referenceElement,
);
return (
<div className={dropdownClassName}>
<div className="ids-dropdown__source">{renderSource()}</div>
<div className={dropdownWidgetClassName} onClick={toggleDropdown} ref={setReferenceElement} role="button" tabIndex={0}>
<div className="ids-dropdown__selection-info">{renderSelectionInfo()}</div>
<div className="ids-dropdown__expander">
<Expander isExpanded={isOpen} isFocusable={false} onClick={toggleDropdown} type={ExpanderType.Chevron} />
</div>
</div>
<ItemsContainer
closeDropdown={() => {
setIsOpen(false);
}}
filterFunction={filterFunction}
getItemAttributes={getItemAttributes}
getNextFocusableItem={getNextFocusableItem}
isItemSelected={isItemSelected}
isOpen={isOpen}
items={items}
maxVisibleItems={maxVisibleItems}
onDropdownItemClick={onDropdownItemClick}
referenceElement={referenceElement}
renderItem={renderItem}
/>
</div>
);
};