@geotab/zenith 3.0.1 → 3.1.0-beta.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (262) hide show
  1. package/README.md +17 -0
  2. package/dist/advancedGroupsFilter/advancedGroupsFilter.d.ts +1 -0
  3. package/dist/advancedGroupsFilter/advancedGroupsFilter.js +2 -2
  4. package/dist/advancedGroupsFilter/advancedGroupsFilterFormSection.js +3 -1
  5. package/dist/chip/chip.js +5 -5
  6. package/dist/commonStyles/zIndex.less +5 -0
  7. package/dist/dateInput/dateInput.d.ts +2 -1
  8. package/dist/dateInput/dateInput.js +11 -2
  9. package/dist/dateRange/dateRange.js +9 -8
  10. package/dist/dropdown/dropdown.d.ts +2 -0
  11. package/dist/dropdown/dropdown.js +6 -5
  12. package/dist/dropdown/dropdownHelper.d.ts +4 -4
  13. package/dist/dropdown/dropdownHelper.js +2 -1
  14. package/dist/dropdown/dropdownList.js +2 -2
  15. package/dist/dropdown/dropdownPopup.d.ts +1 -0
  16. package/dist/dropdown/dropdownPopup.js +2 -2
  17. package/dist/dropdown/dropdownSearchableTrigger.js +1 -1
  18. package/dist/dropdown/stateReducer/stateReducer.d.ts +6 -2
  19. package/dist/dropdown/stateReducer/stateReducer.js +28 -42
  20. package/dist/dropdown/stateReducer/stateReducerHelper.d.ts +2 -0
  21. package/dist/dropdown/stateReducer/stateReducerHelper.js +12 -1
  22. package/dist/dropdown/useDropdownState.d.ts +1 -1
  23. package/dist/dropdown/useDropdownState.js +5 -2
  24. package/dist/filters/components/filtersContainer.d.ts +1 -0
  25. package/dist/filters/components/filtersContainer.js +10 -11
  26. package/dist/filters/components/filtersDateInput.d.ts +10 -0
  27. package/dist/filters/components/filtersDateInput.js +27 -0
  28. package/dist/filters/components/filtersDropdown.d.ts +5 -4
  29. package/dist/filters/components/filtersDropdown.js +3 -3
  30. package/dist/filters/components/filtersEmptySelectedList.d.ts +2 -0
  31. package/dist/filters/components/filtersEmptySelectedList.js +11 -0
  32. package/dist/filters/components/filtersItem.d.ts +5 -4
  33. package/dist/filters/components/filtersItem.js +2 -1
  34. package/dist/filters/components/filtersSaveModal.d.ts +3 -1
  35. package/dist/filters/components/filtersSaveModal.js +2 -2
  36. package/dist/filters/components/filtersSavedChipComponent.js +68 -6
  37. package/dist/filters/components/filtersSearch.d.ts +4 -4
  38. package/dist/filters/components/filtersSearch.js +20 -9
  39. package/dist/filters/components/filtersSearchItemData.js +18 -1
  40. package/dist/filters/components/filtersSearchList.d.ts +5 -1
  41. package/dist/filters/components/filtersSearchList.js +155 -27
  42. package/dist/filters/components/filtersSelect.d.ts +1 -0
  43. package/dist/filters/components/filtersSelect.js +35 -7
  44. package/dist/filters/components/filtersSelectListItem.d.ts +21 -15
  45. package/dist/filters/components/filtersSelectListItem.js +13 -3
  46. package/dist/filters/components/filtersSidePanel.d.ts +15 -0
  47. package/dist/filters/components/filtersSidePanel.js +212 -0
  48. package/dist/filters/components/filtersSidePanelChip.d.ts +9 -0
  49. package/dist/filters/components/filtersSidePanelChip.js +13 -0
  50. package/dist/filters/components/filtersSidePanelDropdown.d.ts +6 -0
  51. package/dist/filters/components/filtersSidePanelDropdown.js +85 -0
  52. package/dist/filters/components/filtersSidePanelItem.d.ts +16 -0
  53. package/dist/filters/components/filtersSidePanelItem.js +67 -0
  54. package/dist/filters/components/filtersSidePanelRange.d.ts +6 -0
  55. package/dist/filters/components/filtersSidePanelRange.js +28 -0
  56. package/dist/filters/filters.d.ts +5 -0
  57. package/dist/filters/filters.js +101 -38
  58. package/dist/filters/filtersHelper.d.ts +4 -2
  59. package/dist/filters/filtersHelper.js +40 -1
  60. package/dist/filters/filtersHooks.d.ts +12 -2
  61. package/dist/filters/filtersHooks.js +21 -3
  62. package/dist/formStepper/formStepper.d.ts +1 -1
  63. package/dist/formStepper/formStepper.js +5 -2
  64. package/dist/groupsFilter/groupsFilter.js +72 -37
  65. package/dist/groupsFilter/groupsFilterMenu.d.ts +1 -0
  66. package/dist/groupsFilter/groupsFilterMenu.js +2 -2
  67. package/dist/groupsFilter/groupsFilterTrigger.js +1 -1
  68. package/dist/images/imageLooking.d.ts +4 -0
  69. package/dist/images/imageLooking.js +16 -0
  70. package/dist/index.css +407 -83
  71. package/dist/index.d.ts +7 -4
  72. package/dist/index.js +26 -15
  73. package/dist/list/list.d.ts +3 -1
  74. package/dist/list/list.js +2 -2
  75. package/dist/mobileSheet/mobileSheet.d.ts +2 -0
  76. package/dist/mobileSheet/mobileSheet.js +4 -4
  77. package/dist/modal/modal.d.ts +1 -0
  78. package/dist/modal/modal.js +2 -2
  79. package/dist/radioGroup/radioGroup.d.ts +1 -0
  80. package/dist/radioGroup/radioGroup.js +3 -2
  81. package/dist/range/range.js +29 -10
  82. package/dist/searchInputRaw/searchInputRaw.js +1 -1
  83. package/dist/sidePanel/sidePanel.d.ts +1 -0
  84. package/dist/sidePanel/sidePanel.js +3 -3
  85. package/dist/tabs/tabItem/tabItem.d.ts +1 -0
  86. package/dist/tabs/tabItem/tabItem.js +2 -2
  87. package/dist/tabs/tabs.d.ts +1 -0
  88. package/dist/tabs/tabs.js +1 -1
  89. package/dist/utils/keyboardHelpers.d.ts +2 -0
  90. package/dist/utils/keyboardHelpers.js +49 -0
  91. package/dist/utils/localization/translations/cs-json.d.ts +1 -0
  92. package/dist/utils/localization/translations/cs-json.js +2 -1
  93. package/dist/utils/localization/translations/de-json.d.ts +1 -0
  94. package/dist/utils/localization/translations/de-json.js +2 -1
  95. package/dist/utils/localization/translations/en-json.d.ts +7 -0
  96. package/dist/utils/localization/translations/en-json.js +8 -1
  97. package/dist/utils/localization/translations/es-json.d.ts +1 -0
  98. package/dist/utils/localization/translations/es-json.js +2 -1
  99. package/dist/utils/localization/translations/fr-FR-json.d.ts +1 -0
  100. package/dist/utils/localization/translations/fr-FR-json.js +2 -1
  101. package/dist/utils/localization/translations/fr-json.d.ts +1 -0
  102. package/dist/utils/localization/translations/fr-json.js +2 -1
  103. package/dist/utils/localization/translations/id-json.d.ts +1 -0
  104. package/dist/utils/localization/translations/id-json.js +2 -1
  105. package/dist/utils/localization/translations/it-json.d.ts +1 -0
  106. package/dist/utils/localization/translations/it-json.js +2 -1
  107. package/dist/utils/localization/translations/ja-json.d.ts +1 -0
  108. package/dist/utils/localization/translations/ja-json.js +2 -1
  109. package/dist/utils/localization/translations/ko-KR-json.d.ts +1 -0
  110. package/dist/utils/localization/translations/ko-KR-json.js +2 -1
  111. package/dist/utils/localization/translations/ms-json.d.ts +1 -0
  112. package/dist/utils/localization/translations/ms-json.js +2 -1
  113. package/dist/utils/localization/translations/nl-json.d.ts +1 -0
  114. package/dist/utils/localization/translations/nl-json.js +2 -1
  115. package/dist/utils/localization/translations/pl-json.d.ts +1 -0
  116. package/dist/utils/localization/translations/pl-json.js +2 -1
  117. package/dist/utils/localization/translations/pt-BR-json.d.ts +1 -0
  118. package/dist/utils/localization/translations/pt-BR-json.js +2 -1
  119. package/dist/utils/localization/translations/sv-json.d.ts +1 -0
  120. package/dist/utils/localization/translations/sv-json.js +2 -1
  121. package/dist/utils/localization/translations/th-json.d.ts +1 -0
  122. package/dist/utils/localization/translations/th-json.js +2 -1
  123. package/dist/utils/localization/translations/tr-json.d.ts +1 -0
  124. package/dist/utils/localization/translations/tr-json.js +2 -1
  125. package/dist/utils/localization/translations/zh-Hans-json.d.ts +1 -0
  126. package/dist/utils/localization/translations/zh-Hans-json.js +2 -1
  127. package/dist/utils/localization/translations/zh-TW-json.d.ts +1 -0
  128. package/dist/utils/localization/translations/zh-TW-json.js +2 -1
  129. package/esm/advancedGroupsFilter/advancedGroupsFilter.d.ts +1 -0
  130. package/esm/advancedGroupsFilter/advancedGroupsFilter.js +2 -2
  131. package/esm/advancedGroupsFilter/advancedGroupsFilterFormSection.js +3 -1
  132. package/esm/chip/chip.js +5 -5
  133. package/esm/dateInput/dateInput.d.ts +2 -1
  134. package/esm/dateInput/dateInput.js +11 -2
  135. package/esm/dateRange/dateRange.js +9 -8
  136. package/esm/dropdown/dropdown.d.ts +2 -0
  137. package/esm/dropdown/dropdown.js +5 -4
  138. package/esm/dropdown/dropdownHelper.d.ts +4 -4
  139. package/esm/dropdown/dropdownHelper.js +2 -1
  140. package/esm/dropdown/dropdownList.js +2 -2
  141. package/esm/dropdown/dropdownPopup.d.ts +1 -0
  142. package/esm/dropdown/dropdownPopup.js +2 -2
  143. package/esm/dropdown/dropdownSearchableTrigger.js +1 -1
  144. package/esm/dropdown/stateReducer/stateReducer.d.ts +6 -2
  145. package/esm/dropdown/stateReducer/stateReducer.js +29 -43
  146. package/esm/dropdown/stateReducer/stateReducerHelper.d.ts +2 -0
  147. package/esm/dropdown/stateReducer/stateReducerHelper.js +10 -0
  148. package/esm/dropdown/useDropdownState.d.ts +1 -1
  149. package/esm/dropdown/useDropdownState.js +5 -2
  150. package/esm/filters/components/filtersContainer.d.ts +1 -0
  151. package/esm/filters/components/filtersContainer.js +12 -13
  152. package/esm/filters/components/filtersDateInput.d.ts +10 -0
  153. package/esm/filters/components/filtersDateInput.js +23 -0
  154. package/esm/filters/components/filtersDropdown.d.ts +5 -4
  155. package/esm/filters/components/filtersDropdown.js +3 -3
  156. package/esm/filters/components/filtersEmptySelectedList.d.ts +2 -0
  157. package/esm/filters/components/filtersEmptySelectedList.js +7 -0
  158. package/esm/filters/components/filtersItem.d.ts +5 -4
  159. package/esm/filters/components/filtersItem.js +2 -1
  160. package/esm/filters/components/filtersSaveModal.d.ts +3 -1
  161. package/esm/filters/components/filtersSaveModal.js +2 -2
  162. package/esm/filters/components/filtersSavedChipComponent.js +68 -6
  163. package/esm/filters/components/filtersSearch.d.ts +4 -4
  164. package/esm/filters/components/filtersSearch.js +20 -9
  165. package/esm/filters/components/filtersSearchItemData.js +18 -1
  166. package/esm/filters/components/filtersSearchList.d.ts +5 -1
  167. package/esm/filters/components/filtersSearchList.js +156 -28
  168. package/esm/filters/components/filtersSelect.d.ts +1 -0
  169. package/esm/filters/components/filtersSelect.js +36 -8
  170. package/esm/filters/components/filtersSelectListItem.d.ts +21 -15
  171. package/esm/filters/components/filtersSelectListItem.js +13 -3
  172. package/esm/filters/components/filtersSidePanel.d.ts +15 -0
  173. package/esm/filters/components/filtersSidePanel.js +208 -0
  174. package/esm/filters/components/filtersSidePanelChip.d.ts +9 -0
  175. package/esm/filters/components/filtersSidePanelChip.js +9 -0
  176. package/esm/filters/components/filtersSidePanelDropdown.d.ts +6 -0
  177. package/esm/filters/components/filtersSidePanelDropdown.js +81 -0
  178. package/esm/filters/components/filtersSidePanelItem.d.ts +16 -0
  179. package/esm/filters/components/filtersSidePanelItem.js +63 -0
  180. package/esm/filters/components/filtersSidePanelRange.d.ts +6 -0
  181. package/esm/filters/components/filtersSidePanelRange.js +24 -0
  182. package/esm/filters/filters.d.ts +5 -0
  183. package/esm/filters/filters.js +101 -38
  184. package/esm/filters/filtersHelper.d.ts +4 -2
  185. package/esm/filters/filtersHelper.js +37 -0
  186. package/esm/filters/filtersHooks.d.ts +12 -2
  187. package/esm/filters/filtersHooks.js +19 -2
  188. package/esm/formStepper/formStepper.d.ts +1 -1
  189. package/esm/formStepper/formStepper.js +5 -2
  190. package/esm/groupsFilter/groupsFilter.js +72 -37
  191. package/esm/groupsFilter/groupsFilterMenu.d.ts +1 -0
  192. package/esm/groupsFilter/groupsFilterMenu.js +2 -2
  193. package/esm/groupsFilter/groupsFilterTrigger.js +1 -1
  194. package/esm/images/imageLooking.d.ts +4 -0
  195. package/esm/images/imageLooking.js +12 -0
  196. package/esm/index.d.ts +7 -4
  197. package/esm/index.js +6 -3
  198. package/esm/list/list.d.ts +3 -1
  199. package/esm/list/list.js +2 -2
  200. package/esm/mobileSheet/mobileSheet.d.ts +2 -0
  201. package/esm/mobileSheet/mobileSheet.js +4 -4
  202. package/esm/modal/modal.d.ts +1 -0
  203. package/esm/modal/modal.js +2 -2
  204. package/esm/radioGroup/radioGroup.d.ts +1 -0
  205. package/esm/radioGroup/radioGroup.js +3 -2
  206. package/esm/range/range.js +29 -10
  207. package/esm/searchInputRaw/searchInputRaw.js +1 -1
  208. package/esm/sidePanel/sidePanel.d.ts +1 -0
  209. package/esm/sidePanel/sidePanel.js +3 -3
  210. package/esm/tabs/tabItem/tabItem.d.ts +1 -0
  211. package/esm/tabs/tabItem/tabItem.js +2 -2
  212. package/esm/tabs/tabs.d.ts +1 -0
  213. package/esm/tabs/tabs.js +1 -1
  214. package/esm/utils/keyboardHelpers.d.ts +2 -0
  215. package/esm/utils/keyboardHelpers.js +44 -0
  216. package/esm/utils/localization/translations/cs-json.d.ts +1 -0
  217. package/esm/utils/localization/translations/cs-json.js +2 -1
  218. package/esm/utils/localization/translations/de-json.d.ts +1 -0
  219. package/esm/utils/localization/translations/de-json.js +2 -1
  220. package/esm/utils/localization/translations/en-json.d.ts +7 -0
  221. package/esm/utils/localization/translations/en-json.js +8 -1
  222. package/esm/utils/localization/translations/es-json.d.ts +1 -0
  223. package/esm/utils/localization/translations/es-json.js +2 -1
  224. package/esm/utils/localization/translations/fr-FR-json.d.ts +1 -0
  225. package/esm/utils/localization/translations/fr-FR-json.js +2 -1
  226. package/esm/utils/localization/translations/fr-json.d.ts +1 -0
  227. package/esm/utils/localization/translations/fr-json.js +2 -1
  228. package/esm/utils/localization/translations/id-json.d.ts +1 -0
  229. package/esm/utils/localization/translations/id-json.js +2 -1
  230. package/esm/utils/localization/translations/it-json.d.ts +1 -0
  231. package/esm/utils/localization/translations/it-json.js +2 -1
  232. package/esm/utils/localization/translations/ja-json.d.ts +1 -0
  233. package/esm/utils/localization/translations/ja-json.js +2 -1
  234. package/esm/utils/localization/translations/ko-KR-json.d.ts +1 -0
  235. package/esm/utils/localization/translations/ko-KR-json.js +2 -1
  236. package/esm/utils/localization/translations/ms-json.d.ts +1 -0
  237. package/esm/utils/localization/translations/ms-json.js +2 -1
  238. package/esm/utils/localization/translations/nl-json.d.ts +1 -0
  239. package/esm/utils/localization/translations/nl-json.js +2 -1
  240. package/esm/utils/localization/translations/pl-json.d.ts +1 -0
  241. package/esm/utils/localization/translations/pl-json.js +2 -1
  242. package/esm/utils/localization/translations/pt-BR-json.d.ts +1 -0
  243. package/esm/utils/localization/translations/pt-BR-json.js +2 -1
  244. package/esm/utils/localization/translations/sv-json.d.ts +1 -0
  245. package/esm/utils/localization/translations/sv-json.js +2 -1
  246. package/esm/utils/localization/translations/th-json.d.ts +1 -0
  247. package/esm/utils/localization/translations/th-json.js +2 -1
  248. package/esm/utils/localization/translations/tr-json.d.ts +1 -0
  249. package/esm/utils/localization/translations/tr-json.js +2 -1
  250. package/esm/utils/localization/translations/zh-Hans-json.d.ts +1 -0
  251. package/esm/utils/localization/translations/zh-Hans-json.js +2 -1
  252. package/esm/utils/localization/translations/zh-TW-json.d.ts +1 -0
  253. package/esm/utils/localization/translations/zh-TW-json.js +2 -1
  254. package/package.json +1 -1
  255. package/dist/filters/components/filtersModal.d.ts +0 -17
  256. package/dist/filters/components/filtersModal.js +0 -107
  257. package/dist/filters/components/filtersModalItem.d.ts +0 -9
  258. package/dist/filters/components/filtersModalItem.js +0 -74
  259. package/esm/filters/components/filtersModal.d.ts +0 -17
  260. package/esm/filters/components/filtersModal.js +0 -103
  261. package/esm/filters/components/filtersModalItem.d.ts +0 -9
  262. package/esm/filters/components/filtersModalItem.js +0 -70
@@ -14,8 +14,12 @@ const modal_1 = require("../../modal/modal");
14
14
  const filtersSavedItemsProvider_1 = require("./filtersSavedItemsProvider");
15
15
  const filtersSaveModal_1 = require("./filtersSaveModal");
16
16
  const useDriveClassName_1 = require("../../utils/theme/useDriveClassName");
17
+ const useMobile_1 = require("../../commonHelpers/hooks/useMobile");
18
+ const mobileSheet_1 = require("../../mobileSheet/mobileSheet");
19
+ const keyboardHelpers_1 = require("../../utils/keyboardHelpers");
17
20
  const FiltersSavedChipComponent = () => {
18
21
  const { translate } = (0, useLanguage_1.useLanguage)();
22
+ const isMobile = (0, useMobile_1.useMobile)();
19
23
  const iconDriveClassName = (0, useDriveClassName_1.useDriveClassName)("icon");
20
24
  const contentDriveClassName = (0, useDriveClassName_1.useDriveClassName)("zen-filters-saved-popup__content");
21
25
  const { items, active, onRemove, onApply, onSave } = (0, filtersSavedItemsProvider_1.useFiltersSavedItems)();
@@ -24,13 +28,17 @@ const FiltersSavedChipComponent = () => {
24
28
  const [saveModalOpen, setSaveModalOpen] = (0, react_1.useState)(false);
25
29
  const savedChipRef = (0, react_1.useRef)(null);
26
30
  const removeChipRef = (0, react_1.useRef)("");
31
+ const savedFiltersRef = (0, react_1.useRef)(null);
27
32
  const handleRemove = (0, react_1.useCallback)((itemKey) => () => {
28
33
  removeChipRef.current = itemKey;
29
34
  setRemoveModalOpen(true);
30
35
  }, []);
31
36
  const toggleSavedChipOpen = (0, react_1.useCallback)(() => {
37
+ if (removeModalOpen || saveModalOpen) {
38
+ return;
39
+ }
32
40
  setSavedChipOpen((prev) => !prev);
33
- }, []);
41
+ }, [removeModalOpen, saveModalOpen]);
34
42
  const toggleRemoveModal = (0, react_1.useCallback)(() => {
35
43
  setRemoveModalOpen((prev) => !prev);
36
44
  }, []);
@@ -48,19 +56,73 @@ const FiltersSavedChipComponent = () => {
48
56
  removeChipRef.current = "";
49
57
  }, [onRemove]);
50
58
  const handleFilterSelect = (0, react_1.useCallback)((e) => {
59
+ var _a;
51
60
  const filterName = e.target.dataset.filterName;
52
- filterName && onApply && onApply(filterName);
61
+ if (!filterName) {
62
+ return;
63
+ }
64
+ onApply && onApply(filterName);
65
+ setSavedChipOpen((prev) => !prev);
66
+ (_a = savedChipRef.current) === null || _a === void 0 ? void 0 : _a.focus();
53
67
  }, [onApply]);
68
+ const handleSaveItemKeyDown = (0, react_1.useCallback)((e) => {
69
+ if (e.key === "ArrowDown") {
70
+ const nextItem = (0, keyboardHelpers_1.getFirstFocusableItem)(savedFiltersRef.current);
71
+ nextItem === null || nextItem === void 0 ? void 0 : nextItem.focus();
72
+ return;
73
+ }
74
+ }, [savedFiltersRef]);
54
75
  const handleItemKeyDown = (0, react_1.useCallback)((e) => {
76
+ var _a;
55
77
  if (e.key === "Enter" || e.key === " ") {
56
78
  const filterName = e.currentTarget.dataset.filterName;
57
- filterName && onApply && onApply(filterName);
79
+ const isRemoveButton = e.target.dataset.removeButton;
80
+ if (isRemoveButton || !filterName) {
81
+ return;
82
+ }
83
+ onApply && onApply(filterName);
84
+ setSavedChipOpen((prev) => !prev);
85
+ (_a = savedChipRef.current) === null || _a === void 0 ? void 0 : _a.focus();
86
+ return;
87
+ }
88
+ const isListItem = e.target instanceof HTMLElement && e.target.dataset.listItem === "true";
89
+ const isButtonItem = e.target instanceof HTMLElement && e.target.dataset.removeButton === "true";
90
+ const getSelector = () => {
91
+ if (isListItem) {
92
+ return `[data-list-item="true"]`;
93
+ }
94
+ if (isButtonItem) {
95
+ return `[data-remove-button="true"]`;
96
+ }
97
+ return undefined;
98
+ };
99
+ if (e.key === "ArrowDown") {
100
+ const nextItem = (0, keyboardHelpers_1.getNewFocusableItem)(1, savedFiltersRef.current, getSelector());
101
+ nextItem === null || nextItem === void 0 ? void 0 : nextItem.focus();
102
+ return;
103
+ }
104
+ if (e.key === "ArrowUp") {
105
+ const prevItem = (0, keyboardHelpers_1.getNewFocusableItem)(-1, savedFiltersRef.current, getSelector());
106
+ prevItem === null || prevItem === void 0 ? void 0 : prevItem.focus();
107
+ return;
108
+ }
109
+ if (e.key === "ArrowRight" && isListItem) {
110
+ const nextItem = (0, keyboardHelpers_1.getNewFocusableItem)(1, savedFiltersRef.current, `[data-remove-button="true"]`);
111
+ nextItem === null || nextItem === void 0 ? void 0 : nextItem.focus();
112
+ return;
113
+ }
114
+ if (e.key === "ArrowLeft" && isButtonItem) {
115
+ const prevItem = (0, keyboardHelpers_1.getNewFocusableItem)(-1, savedFiltersRef.current, `[data-list-item="true"]`);
116
+ prevItem === null || prevItem === void 0 ? void 0 : prevItem.focus();
117
+ return;
58
118
  }
59
119
  }, [onApply]);
60
- const saveButton = (0, react_1.useMemo)(() => (0, jsx_runtime_1.jsxs)("button", { type: "button", onClick: toggleSaveModal, className: "zen-filters-saved-popup__action-button", title: translate("Save new filters"), children: [(0, jsx_runtime_1.jsx)(iconDisk_1.IconDisk, { description: translate("Save"), className: "svgIcon", size: iconDriveClassName ? "huge" : "large" }), (0, jsx_runtime_1.jsx)("div", { className: (0, classNames_1.classNames)(["", "zen-ellipsis"]), children: translate("Save new") })] }), [iconDriveClassName, toggleSaveModal, translate]);
120
+ const saveButton = (0, react_1.useMemo)(() => (0, jsx_runtime_1.jsxs)("button", { type: "button", onKeyDown: handleSaveItemKeyDown, onClick: toggleSaveModal, className: "zen-filters-saved-popup__action-button", title: translate("Save new filters"), children: [(0, jsx_runtime_1.jsx)(iconDisk_1.IconDisk, { description: translate("Save"), className: "svgIcon", size: iconDriveClassName ? "huge" : "large" }), (0, jsx_runtime_1.jsx)("div", { className: (0, classNames_1.classNames)(["", "zen-ellipsis"]), children: translate("Save new") })] }), [iconDriveClassName, toggleSaveModal, translate, handleSaveItemKeyDown]);
61
121
  const memoizedItems = (0, react_1.useMemo)(() => Array.from(items), [items]);
62
- const popupContent = (0, react_1.useMemo)(() => (0, jsx_runtime_1.jsxs)("div", { className: (0, classNames_1.classNames)(["zen-filters-saved-popup__content", contentDriveClassName || ""]), children: [onSave ? saveButton : null, (0, jsx_runtime_1.jsx)("div", { onClick: handleFilterSelect, children: memoizedItems.map((filterName) => ((0, jsx_runtime_1.jsxs)("div", { tabIndex: 0, onKeyDown: handleItemKeyDown, "data-filter-name": filterName, className: (0, classNames_1.classNames)(["zen-filters-saved-popup__item", active.has(filterName) ? "zen-filters-saved-popup__item--active" : ""]), children: [(0, jsx_runtime_1.jsx)("div", { className: "zen-filters-saved-popup__name", "data-filter-name": filterName, children: filterName }), onRemove ? (0, jsx_runtime_1.jsx)(button_1.Button, { type: "tertiary-black", className: "zen-filters-saved-popup__action", onClick: handleRemove(filterName), title: translate("Remove"), "aria-label": translate("Remove"), children: (0, jsx_runtime_1.jsx)(iconClose_1.IconClose, { size: iconDriveClassName ? "huge" : "large", className: "zen-filters-saved-popup__close-icon" }) }) : null] }, filterName))) })] }), [active, contentDriveClassName, handleFilterSelect, handleItemKeyDown, handleRemove, iconDriveClassName, memoizedItems, onRemove, onSave, saveButton, translate]);
122
+ const popupContent = (0, react_1.useMemo)(() => (0, jsx_runtime_1.jsxs)("div", { className: (0, classNames_1.classNames)(["zen-filters-saved-popup__content", contentDriveClassName || ""]), children: [onSave ? saveButton : null, (0, jsx_runtime_1.jsx)("div", { ref: savedFiltersRef, onClick: handleFilterSelect, children: memoizedItems.map((filterName) => ((0, jsx_runtime_1.jsxs)("div", { tabIndex: 0, onKeyDown: handleItemKeyDown, "data-list-item": true, "data-filter-name": filterName, className: (0, classNames_1.classNames)(["zen-filters-saved-popup__item", active.has(filterName) ? "zen-filters-saved-popup__item--active" : ""]), children: [(0, jsx_runtime_1.jsx)("div", { className: "zen-filters-saved-popup__name", "data-filter-name": filterName, children: filterName }), onRemove ? (0, jsx_runtime_1.jsx)(button_1.Button, { "data-remove-button": true, type: "tertiary-black", className: "zen-filters-saved-popup__action", onClick: handleRemove(filterName), title: translate("Remove"), "aria-label": translate("Remove"), children: (0, jsx_runtime_1.jsx)(iconClose_1.IconClose, { size: iconDriveClassName ? "huge" : "large", className: "zen-filters-saved-popup__close-icon" }) }) : null] }, filterName))) })] }), [active, contentDriveClassName, handleFilterSelect, handleItemKeyDown, handleRemove, iconDriveClassName, memoizedItems, onRemove, onSave, saveButton, translate]);
63
123
  const memoizedStatus = (0, react_1.useMemo)(() => (active.size > 0 && Array.from(items).some(item => active.has(item)) ? "active" : undefined), [active, items]);
64
- return ((0, jsx_runtime_1.jsxs)(jsx_runtime_1.Fragment, { children: [(0, jsx_runtime_1.jsx)(chip_1.Chip, { className: "zen-filters-saved-chip", isOpen: savedChipOpen, status: memoizedStatus, onClick: toggleSavedChipOpen, title: translate("Saved filters"), icon: iconDisk_1.IconDisk, triggerRef: savedChipRef }), (0, jsx_runtime_1.jsx)(controlledPopup_1.ControlledPopup, { isOpen: savedChipOpen, className: (0, classNames_1.classNames)(["zen-filters-saved-popup"]), onOpenChange: toggleSavedChipOpen, useTrapFocusWithTrigger: "on", shouldHoldScroll: true, triggerRef: savedChipRef, ariaLabel: translate("Saved filters"), recalculateOnScroll: true, children: popupContent }), (0, jsx_runtime_1.jsxs)(modal_1.Modal, { isOpen: removeModalOpen, onClose: toggleRemoveModal, title: translate("Remove saved {name} filter?").replace("{name}", removeChipRef.current), children: [(0, jsx_runtime_1.jsx)(modal_1.Modal.SecondaryButton, { onClick: handleCancelRemoveModal, children: translate("Cancel") }), (0, jsx_runtime_1.jsx)(modal_1.Modal.PrimaryButton, { onClick: handleRemoveItem, type: "destructive", children: translate("Confirm") })] }), onSave ? (0, jsx_runtime_1.jsx)(filtersSaveModal_1.FiltersSaveModal, { isOpen: saveModalOpen, onClose: setSaveModalOpen, onSave: onSave }) : null] }));
124
+ const memoizedDesktopView = (0, react_1.useMemo)(() => (0, jsx_runtime_1.jsx)(controlledPopup_1.ControlledPopup, { isOpen: savedChipOpen, className: (0, classNames_1.classNames)(["zen-filters-saved-popup"]), onOpenChange: toggleSavedChipOpen, useTrapFocusWithTrigger: "on", shouldHoldScroll: true, triggerRef: savedChipRef, ariaLabel: translate("Saved filters"), recalculateOnScroll: true, children: popupContent }), [popupContent, savedChipOpen, toggleSavedChipOpen, savedChipRef, translate]);
125
+ const memoizedMobileView = (0, react_1.useMemo)(() => (0, jsx_runtime_1.jsxs)(mobileSheet_1.MobileSheet, { label: translate("Saved filters"), triggerRef: savedChipRef, isOpen: savedChipOpen, onHidePanel: toggleSavedChipOpen, onCloseClick: toggleSavedChipOpen, useTrapFocusWithTrigger: false, children: [(0, jsx_runtime_1.jsx)(mobileSheet_1.MobileSheet.Title, { children: translate("Saved filters") }), (0, jsx_runtime_1.jsx)(mobileSheet_1.MobileSheet.Content, { className: "zen-filters-saved-chip__mobile-sheet", children: popupContent })] }), [popupContent, savedChipOpen, toggleSavedChipOpen, translate]);
126
+ return ((0, jsx_runtime_1.jsxs)(jsx_runtime_1.Fragment, { children: [(0, jsx_runtime_1.jsx)(chip_1.Chip, { className: "zen-filters-saved-chip", isOpen: savedChipOpen, status: memoizedStatus, onClick: toggleSavedChipOpen, title: translate("Saved filters"), icon: iconDisk_1.IconDisk, triggerRef: savedChipRef }), isMobile ? memoizedMobileView : memoizedDesktopView, (0, jsx_runtime_1.jsxs)(modal_1.Modal, { isOpen: removeModalOpen, onClose: toggleRemoveModal, modalContainerClassName: (0, classNames_1.classNames)([isMobile ? "zen-filters-prioritized-modal" : ""]), title: translate("Remove saved {name} filter?").replace("{name}", removeChipRef.current), children: [(0, jsx_runtime_1.jsx)(modal_1.Modal.SecondaryButton, { title: translate("Cancel"), onClick: handleCancelRemoveModal, children: translate("Cancel") }), (0, jsx_runtime_1.jsx)(modal_1.Modal.PrimaryButton, { title: translate("Confirm"), onClick: handleRemoveItem, type: "destructive", children: translate("Confirm") })] }), onSave ? (0, jsx_runtime_1.jsx)(filtersSaveModal_1.FiltersSaveModal, { prioritize: isMobile, isOpen: saveModalOpen, onClose: setSaveModalOpen, onSave: onSave }) : null] }));
65
127
  };
66
128
  exports.FiltersSavedChipComponent = FiltersSavedChipComponent;
@@ -1,4 +1,4 @@
1
- import { RefObject } from "react";
1
+ import React, { RefObject } from "react";
2
2
  import "./filtersSearch.less";
3
3
  import { ISearchItem } from "./filtersSearchList";
4
4
  interface IFiltersSearch {
@@ -6,15 +6,15 @@ interface IFiltersSearch {
6
6
  name: string;
7
7
  value: string;
8
8
  onChange: (newValue: string) => void;
9
- onSearchKeyDown?: (searchValue?: string) => void;
10
- handleSearchFocus: () => void;
9
+ onSearchKeyDown?: (e: React.KeyboardEvent<HTMLInputElement>) => void;
10
+ onOpenPopup?: () => void;
11
11
  searchSelection?: ISearchItem[];
12
12
  handleRemove?: (id: ISearchItem) => void;
13
13
  className?: string;
14
14
  ref?: RefObject<HTMLInputElement | null>;
15
15
  }
16
16
  export declare const FiltersSearch: {
17
- ({ id, name, value, onChange, onSearchKeyDown, handleSearchFocus, searchSelection, handleRemove, className, ref }: IFiltersSearch): import("react/jsx-runtime").JSX.Element;
17
+ ({ id, name, value, onChange, onSearchKeyDown, onOpenPopup, searchSelection, handleRemove, className, ref }: IFiltersSearch): import("react/jsx-runtime").JSX.Element;
18
18
  displayName: string;
19
19
  };
20
20
  export {};
@@ -27,17 +27,12 @@ exports.FiltersSearch = void 0;
27
27
  const jsx_runtime_1 = require("react/jsx-runtime");
28
28
  const react_1 = __importStar(require("react"));
29
29
  const classNames_1 = require("../../commonHelpers/classNames/classNames");
30
- const pillBox_1 = require("../../pillBox/pillBox");
31
30
  const filtersSearchList_1 = require("./filtersSearchList");
32
31
  const searchInputRaw_1 = require("../../searchInputRaw/searchInputRaw");
33
- const FiltersSearch = ({ id, name, value, onChange, onSearchKeyDown, handleSearchFocus, searchSelection, handleRemove, className, ref }) => {
32
+ const pill_1 = require("../../pill/pill");
33
+ const FiltersSearch = ({ id, name, value, onChange, onSearchKeyDown, onOpenPopup, searchSelection, handleRemove, className, ref }) => {
34
34
  const isWithPills = Boolean(searchSelection && handleRemove);
35
35
  const divider = "_divider_";
36
- const handleSearchKeyDown = (0, react_1.useCallback)((event) => {
37
- if (event.code === "Enter") {
38
- onSearchKeyDown === null || onSearchKeyDown === void 0 ? void 0 : onSearchKeyDown(event.currentTarget.value || undefined);
39
- }
40
- }, [onSearchKeyDown]);
41
36
  const memoizedPillsArray = react_1.default.useMemo(() => {
42
37
  if (!isWithPills || !searchSelection || searchSelection.length === 0) {
43
38
  return [];
@@ -58,8 +53,24 @@ const FiltersSearch = ({ id, name, value, onChange, onSearchKeyDown, handleSearc
58
53
  handleRemove === null || handleRemove === void 0 ? void 0 : handleRemove(Object.assign(Object.assign({}, item), { type: type === filtersSearchList_1.NO_TYPED_SEARCH_ITEM ? undefined : type }));
59
54
  }
60
55
  }, [handleRemove, searchSelection]);
61
- const searchComponent = (0, react_1.useMemo)(() => (0, jsx_runtime_1.jsx)(searchInputRaw_1.SearchInputRaw, { id: id, ref: ref, placeholder: name, onChange: onChange, onKeyDown: handleSearchKeyDown, onFocus: handleSearchFocus, value: value, className: (0, classNames_1.classNames)(["zen-filters-search__search-input", "zen-filters__search", className || ""]) }), [id, ref, name, onChange, handleSearchKeyDown, handleSearchFocus, value, className]);
62
- return (0, jsx_runtime_1.jsxs)("div", { className: (0, classNames_1.classNames)(["zen-filters-search", className || ""]), children: [searchComponent, isWithPills && (0, jsx_runtime_1.jsx)("div", { className: "zen-filters-search__selected", children: (0, jsx_runtime_1.jsx)(pillBox_1.PillBox, { hideSelectedLabel: true, maxPills: 3, selectedPills: memoizedPillsArray, onRemove: onRemove }) })] });
56
+ const handleSearchClick = (0, react_1.useCallback)((e) => {
57
+ var _a, _b, _c;
58
+ if (((_a = e.target) === null || _a === void 0 ? void 0 : _a.dataset.name) === "IconClose" || e.target.classList.contains("zen-pill-non-actionable__close-button")
59
+ || ((_b = e.target) === null || _b === void 0 ? void 0 : _b.parentElement.classList.contains("zen-pill-non-actionable__close-button")) || ((_c = e.target) === null || _c === void 0 ? void 0 : _c.parentElement.dataset.name) === "IconClose") {
60
+ return;
61
+ }
62
+ onOpenPopup === null || onOpenPopup === void 0 ? void 0 : onOpenPopup();
63
+ }, [onOpenPopup]);
64
+ const selectedPills = (0, react_1.useMemo)(() => {
65
+ if (memoizedPillsArray.length === 0) {
66
+ return [];
67
+ }
68
+ const pillsForRender = [{ id: memoizedPillsArray[0].id, name: memoizedPillsArray[0].name }, (memoizedPillsArray
69
+ .length > 1 ? { id: "more_pills", name: `+${memoizedPillsArray.length - 1}` } : undefined)].filter(Boolean);
70
+ return pillsForRender.map((pill, ind) => (0, jsx_runtime_1.jsx)(pill_1.Pill, { type: "info", onClose: ind === 0 ? onRemove.bind(null, pill.id) : undefined, className: (0, classNames_1.classNames)(["zen-filters-search__selected-item", ind !== 0 ? "zen-filters-search__selected-item--more" : ""]), children: pill.name }, `${pill.id}_${pill.name}`));
71
+ }, [memoizedPillsArray, onRemove]);
72
+ const searchComponent = (0, react_1.useMemo)(() => (0, jsx_runtime_1.jsx)(searchInputRaw_1.SearchInputRaw, { id: id, ref: ref, placeholder: name, onChange: onChange, onKeyDown: onSearchKeyDown, value: value, className: (0, classNames_1.classNames)(["zen-filters-search__search-input", "zen-filters__search", className || ""]) }), [id, ref, name, onChange, onSearchKeyDown, value, className]);
73
+ return (0, jsx_runtime_1.jsxs)("div", { className: (0, classNames_1.classNames)(["zen-filters-search", className || ""]), onClick: handleSearchClick, children: [searchComponent, selectedPills.length > 0 && (0, jsx_runtime_1.jsx)("div", { className: "zen-filters-search__selected", children: selectedPills })] });
63
74
  };
64
75
  exports.FiltersSearch = FiltersSearch;
65
76
  exports.FiltersSearch.displayName = "FiltersSearch";
@@ -28,15 +28,32 @@ const FiltersSearchItemData = ({ id, icon, isActive, iconClassName, name, second
28
28
  }
29
29
  onClick();
30
30
  }, [onClick]);
31
+ const handleKeyDown = (0, react_1.useCallback)((e) => {
32
+ if (!onClick) {
33
+ return;
34
+ }
35
+ if (e.key === "Enter" || e.key === " ") {
36
+ const isCloseButton = e.target instanceof HTMLElement && (e.target.dataset.closeButton === "true");
37
+ if (isCloseButton) {
38
+ e.preventDefault();
39
+ e.stopPropagation();
40
+ onClose === null || onClose === void 0 ? void 0 : onClose();
41
+ return;
42
+ }
43
+ e.preventDefault();
44
+ onClick();
45
+ }
46
+ }, [onClick, onClose]);
31
47
  const handleClose = (0, react_1.useCallback)((e) => {
32
48
  if (!onClose) {
33
49
  return;
34
50
  }
51
+ console.log("handleClose");
35
52
  e.preventDefault();
36
53
  e.stopPropagation();
37
54
  onClose();
38
55
  }, [onClose]);
39
56
  return (0, jsx_runtime_1.jsx)("li", { tabIndex: 0, className: (0, classNames_1.classNames)(["zen-search-item-data", isActive ? "zen-search-item-data--active" : "",
40
- onClick ? "zen-search-item-data--clickable" : "", driveClassName || ""]), "data-list-item-id": id, onClick: handleClick, children: (0, jsx_runtime_1.jsxs)("div", { className: "zen-search-item-data__main", children: [icon ? (0, jsx_runtime_1.jsx)("div", { className: (0, classNames_1.classNames)(["zen-search-item-data__icon", iconClassName || ""]), children: renderIcon(icon) }) : null, (0, jsx_runtime_1.jsxs)("div", { className: "zen-search-item-data__main-data", children: [(0, jsx_runtime_1.jsxs)("div", { className: "zen-search-item-data__identifier", children: [(0, jsx_runtime_1.jsx)("div", { className: "zen-search-item-data__name", children: name }), secondary ? (0, jsx_runtime_1.jsx)("div", { className: "zen-search-item-data__secondary", children: secondary }) : null] }), onClose ? (0, jsx_runtime_1.jsx)(button_1.Button, { type: "tertiary-black", className: "zen-search-item-data__close", onClick: handleClose, title: translate("Close"), "aria-label": translate("Close"), children: (0, jsx_runtime_1.jsx)(iconClose_1.IconClose, { size: "large", className: "zen-search-item-data__close-icon" }) }) : null] })] }) }, id);
57
+ onClick ? "zen-search-item-data--clickable" : "", driveClassName || ""]), "data-list-item-id": id, onClick: handleClick, onKeyDown: handleKeyDown, "data-list-item": true, children: (0, jsx_runtime_1.jsxs)("div", { className: "zen-search-item-data__main", children: [icon ? (0, jsx_runtime_1.jsx)("div", { className: (0, classNames_1.classNames)(["zen-search-item-data__icon", iconClassName || ""]), children: renderIcon(icon) }) : null, (0, jsx_runtime_1.jsxs)("div", { className: "zen-search-item-data__main-data", children: [(0, jsx_runtime_1.jsxs)("div", { className: "zen-search-item-data__identifier", children: [(0, jsx_runtime_1.jsx)("div", { className: "zen-search-item-data__name", children: name }), secondary ? (0, jsx_runtime_1.jsx)("div", { className: "zen-search-item-data__secondary", children: secondary }) : null] }), onClose ? (0, jsx_runtime_1.jsx)(button_1.Button, { type: "tertiary-black", className: "zen-search-item-data__close", "data-close-button": true, title: translate("Close"), "aria-label": translate("Close"), onClick: handleClose, children: (0, jsx_runtime_1.jsx)(iconClose_1.IconClose, { size: "large", className: "zen-search-item-data__close-icon" }) }) : null] })] }) }, id);
41
58
  };
42
59
  exports.FiltersSearchItemData = FiltersSearchItemData;
@@ -17,14 +17,18 @@ export interface IRecentSearchItem extends Omit<ISearchItem, "type"> {
17
17
  }
18
18
  export interface IRecentSearchItemWithoutId extends Omit<IRecentSearchItem, "id"> {
19
19
  }
20
+ export declare const NOT_POPULATED_NAME = "...";
20
21
  export interface ISearchList {
21
22
  searchData?: IFetchState<ISearchItem[]>;
22
23
  recentSearches?: IFetchState<IRecentSearchItem[]>;
23
24
  searchSelection?: ISearchItem[];
24
25
  handleSearchItemClick?: (searchItem: ISearchItem) => void;
26
+ handleClearSearchSelection?: () => void;
25
27
  handleRecentSearchItemClick?: (recentSearchItem: IRecentSearchItem) => void;
26
28
  onRemoveRecentSearchItem?: (itemIds: string[]) => void;
27
29
  searchValue: string;
28
30
  getIconByType: (type?: string) => React.FC<IIcon>;
31
+ onlyOneType?: string;
32
+ searchListRef: React.RefObject<HTMLDivElement>;
29
33
  }
30
- export declare const FiltersSearchList: ({ searchValue, searchData, recentSearches, searchSelection, handleSearchItemClick, onRemoveRecentSearchItem, handleRecentSearchItemClick, getIconByType }: ISearchList) => import("react/jsx-runtime").JSX.Element;
34
+ export declare const FiltersSearchList: ({ searchValue, searchData, recentSearches, searchSelection, onlyOneType, handleSearchItemClick, onRemoveRecentSearchItem, handleRecentSearchItemClick, getIconByType, handleClearSearchSelection, searchListRef }: ISearchList) => import("react/jsx-runtime").JSX.Element;
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.FiltersSearchList = exports.KEYWORD_TYPE = exports.KEYWORD_ID = exports.NO_TYPED_SEARCH_ITEM = void 0;
3
+ exports.FiltersSearchList = exports.NOT_POPULATED_NAME = exports.KEYWORD_TYPE = exports.KEYWORD_ID = exports.NO_TYPED_SEARCH_ITEM = void 0;
4
4
  const jsx_runtime_1 = require("react/jsx-runtime");
5
5
  const react_1 = require("react");
6
6
  const list_1 = require("../../list/list");
@@ -14,62 +14,190 @@ const useMobile_1 = require("../../commonHelpers/hooks/useMobile");
14
14
  const useDrive_1 = require("../../utils/theme/useDrive");
15
15
  const classNames_1 = require("../../commonHelpers/classNames/classNames");
16
16
  const filtersHelper_1 = require("../filtersHelper");
17
+ const emptySearchList_1 = require("../../dataGrid/emptySearchList/emptySearchList");
18
+ const keyboardHelpers_1 = require("../../utils/keyboardHelpers");
19
+ const focusableSelector_1 = require("../../utils/focusableSelector");
17
20
  exports.NO_TYPED_SEARCH_ITEM = "noTypedSearchItem";
18
21
  exports.KEYWORD_ID = "keywordId";
19
22
  exports.KEYWORD_TYPE = "keyword";
20
- const FiltersSearchList = ({ searchValue, searchData, recentSearches, searchSelection, handleSearchItemClick, onRemoveRecentSearchItem, handleRecentSearchItemClick, getIconByType }) => {
23
+ exports.NOT_POPULATED_NAME = "...";
24
+ const FiltersSearchList = ({ searchValue, searchData, recentSearches, searchSelection, onlyOneType, handleSearchItemClick, onRemoveRecentSearchItem, handleRecentSearchItemClick, getIconByType, handleClearSearchSelection, searchListRef }) => {
21
25
  const { translate } = (0, useLanguage_1.useLanguage)();
22
- const isSearchMode = Boolean(handleSearchItemClick && searchSelection);
26
+ const isSearchModeAvailable = Boolean(handleSearchItemClick && searchSelection);
27
+ const isRecentSearchesModeAvailable = Boolean(recentSearches && handleRecentSearchItemClick && onRemoveRecentSearchItem);
23
28
  const isMobile = (0, useMobile_1.useMobile)();
24
29
  const isDrive = (0, useDrive_1.useDrive)();
25
30
  const [removedItems, setRemovedItems] = (0, react_1.useState)([]);
26
- const [historyMode, setHistoryMode] = (0, react_1.useState)(false);
31
+ const initialSearchSelectionRef = (0, react_1.useRef)(searchSelection || []);
32
+ const hasNotPopulatedName = initialSearchSelectionRef.current.length === 0 ? false : initialSearchSelectionRef.current.some(el => el.name === exports.NOT_POPULATED_NAME);
33
+ const getCurrentMode = (0, react_1.useCallback)(() => {
34
+ if (searchValue) {
35
+ return "search";
36
+ }
37
+ if (isSearchModeAvailable && initialSearchSelectionRef.current.length > 0) {
38
+ return "selected";
39
+ }
40
+ if (isRecentSearchesModeAvailable && (recentSearches === null || recentSearches === void 0 ? void 0 : recentSearches.data) && recentSearches.data.length > 0) {
41
+ return "recent";
42
+ }
43
+ return "";
44
+ }, [searchValue, isSearchModeAvailable, isRecentSearchesModeAvailable, recentSearches === null || recentSearches === void 0 ? void 0 : recentSearches.data]);
45
+ const [currentMode, setCurrentMode] = (0, react_1.useState)(getCurrentMode());
27
46
  const waitingItemsLimit = 5;
28
- const isRecentSearchesMode = Boolean(recentSearches && handleRecentSearchItemClick && onRemoveRecentSearchItem);
29
47
  // Handle React Query errors
30
48
  (0, react_1.useEffect)(() => {
31
- if (isSearchMode && (searchData === null || searchData === void 0 ? void 0 : searchData.error)) {
49
+ if (currentMode === "search" && (searchData === null || searchData === void 0 ? void 0 : searchData.error)) {
32
50
  console.error("Failed to fetch search results. Error:", searchData.error);
33
51
  }
34
- }, [isSearchMode, searchData === null || searchData === void 0 ? void 0 : searchData.error]);
52
+ }, [currentMode, searchData === null || searchData === void 0 ? void 0 : searchData.error]);
53
+ (0, react_1.useEffect)(() => {
54
+ if (currentMode !== "search" && searchValue) {
55
+ setCurrentMode("search");
56
+ }
57
+ }, [searchValue, currentMode]);
58
+ (0, react_1.useEffect)(() => {
59
+ if (currentMode === "recent" && searchSelection && searchSelection.length === 0) {
60
+ initialSearchSelectionRef.current = [];
61
+ }
62
+ }, [isSearchModeAvailable, isRecentSearchesModeAvailable, currentMode, searchSelection]);
35
63
  // Reset history mode when search value changes
36
64
  (0, react_1.useEffect)(() => {
37
- if (historyMode && searchValue) {
38
- setHistoryMode(false);
39
- }
40
- }, [historyMode, searchValue]);
41
- const searchItems = (0, react_1.useMemo)(() => isSearchMode ? (searchData === null || searchData === void 0 ? void 0 : searchData.data) || [] : [], [isSearchMode, searchData === null || searchData === void 0 ? void 0 : searchData.data]);
42
- const recentItems = (0, react_1.useMemo)(() => isRecentSearchesMode ? (recentSearches === null || recentSearches === void 0 ? void 0 : recentSearches.data) || [] : [], [isRecentSearchesMode, recentSearches === null || recentSearches === void 0 ? void 0 : recentSearches.data]);
43
- const isLoading = searchValue && isSearchMode && (searchData === null || searchData === void 0 ? void 0 : searchData.isLoading) || (isRecentSearchesMode ? recentSearches === null || recentSearches === void 0 ? void 0 : recentSearches.isLoading : false) || false;
44
- const changeMode = (0, react_1.useCallback)(() => {
45
- setHistoryMode(prev => !prev);
65
+ if (currentMode === "history" && searchValue) {
66
+ setCurrentMode(isSearchModeAvailable ? "search" : "");
67
+ }
68
+ else if (currentMode === "search" && !searchValue) {
69
+ setCurrentMode(getCurrentMode());
70
+ }
71
+ }, [currentMode, getCurrentMode, isRecentSearchesModeAvailable, isSearchModeAvailable, searchValue]);
72
+ (0, react_1.useEffect)(() => {
73
+ if (searchSelection && searchSelection.length === 0) {
74
+ return;
75
+ }
76
+ searchSelection === null || searchSelection === void 0 ? void 0 : searchSelection.forEach(item => {
77
+ const existingItem = initialSearchSelectionRef.current.find(el => (onlyOneType ? el.id === item.id : el.id === item.id && el.type === item.type));
78
+ if (!existingItem) {
79
+ initialSearchSelectionRef.current = [...initialSearchSelectionRef.current, item];
80
+ }
81
+ else if (hasNotPopulatedName) {
82
+ existingItem.name = item.name;
83
+ existingItem.description = item.description;
84
+ existingItem.type = item.type;
85
+ }
86
+ });
87
+ }, [hasNotPopulatedName, onlyOneType, searchSelection]);
88
+ const searchItems = (0, react_1.useMemo)(() => currentMode === "search" || currentMode === "" ? (searchData === null || searchData === void 0 ? void 0 : searchData.data) || [] : [], [currentMode, searchData === null || searchData === void 0 ? void 0 : searchData.data]);
89
+ const recentItems = (0, react_1.useMemo)(() => currentMode === "recent" || currentMode === "history" ? (recentSearches === null || recentSearches === void 0 ? void 0 : recentSearches.data) || [] : [], [currentMode, recentSearches === null || recentSearches === void 0 ? void 0 : recentSearches.data]);
90
+ const isLoading = currentMode === "search" && (searchData === null || searchData === void 0 ? void 0 : searchData.isLoading) || (currentMode === "recent" || currentMode === "history" ? recentSearches === null || recentSearches === void 0 ? void 0 : recentSearches.isLoading : false) || false;
91
+ const changeMode = (0, react_1.useCallback)((newVal) => {
92
+ setCurrentMode(newVal);
46
93
  setRemovedItems([]);
47
94
  // Note: In React Query implementation, the parent component should handle
48
95
  // refetching data when switching between modes
49
96
  }, []);
50
97
  const handleRemove = (0, react_1.useCallback)((itemId) => () => {
98
+ var _a;
51
99
  setRemovedItems(prev => [...prev, itemId]);
52
100
  onRemoveRecentSearchItem && onRemoveRecentSearchItem([itemId]);
53
- }, [onRemoveRecentSearchItem]);
101
+ // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition
102
+ const firstItem = (_a = searchListRef.current) === null || _a === void 0 ? void 0 : _a.querySelector(focusableSelector_1.FOCUSABLE_SELECTOR);
103
+ firstItem === null || firstItem === void 0 ? void 0 : firstItem.focus();
104
+ }, [onRemoveRecentSearchItem, searchListRef]);
54
105
  const handleRemoveAll = (0, react_1.useCallback)(() => {
55
106
  setRemovedItems(recentItems.map(item => item.id));
56
107
  onRemoveRecentSearchItem && onRemoveRecentSearchItem(recentItems.map(item => item.id));
57
- changeMode();
58
- }, [onRemoveRecentSearchItem, recentItems, changeMode]);
108
+ changeMode(getCurrentMode());
109
+ }, [recentItems, onRemoveRecentSearchItem, changeMode, getCurrentMode]);
59
110
  const memoizedSearchItemClick = (0, react_1.useCallback)((itemId, itemType) => () => {
60
- const currentSearchItem = searchItems.find(item => item.id === itemId && item.type === itemType);
111
+ const currentSearchItem = onlyOneType && !itemType ? searchItems.find(item => item.id === itemId)
112
+ : searchItems.find(item => item.id === itemId && item.type === itemType);
61
113
  currentSearchItem && handleSearchItemClick && handleSearchItemClick(currentSearchItem);
62
- }, [handleSearchItemClick, searchItems]);
114
+ }, [handleSearchItemClick, onlyOneType, searchItems]);
115
+ const memoizedSelectedItemClick = (0, react_1.useCallback)((itemId, itemType) => () => {
116
+ const currentSelectedItem = onlyOneType && !itemType ? initialSearchSelectionRef.current.find(item => item.id === itemId)
117
+ : initialSearchSelectionRef.current.find(item => item.id === itemId && item.type === itemType);
118
+ currentSelectedItem && handleSearchItemClick && handleSearchItemClick(currentSelectedItem);
119
+ }, [handleSearchItemClick, onlyOneType]);
63
120
  const memoizedRecentSearchItemClick = (0, react_1.useCallback)((itemId, itemType) => () => {
64
121
  const currentSearchItem = recentItems.find(item => item.id === itemId && item.type === itemType);
65
122
  currentSearchItem && handleRecentSearchItemClick && handleRecentSearchItemClick(currentSearchItem);
66
123
  }, [handleRecentSearchItemClick, recentItems]);
124
+ const memoizedClearSelectedItems = (0, react_1.useCallback)(() => {
125
+ var _a;
126
+ handleClearSearchSelection === null || handleClearSearchSelection === void 0 ? void 0 : handleClearSearchSelection();
127
+ initialSearchSelectionRef.current = [];
128
+ setCurrentMode(isRecentSearchesModeAvailable && ((_a = recentSearches === null || recentSearches === void 0 ? void 0 : recentSearches.data) === null || _a === void 0 ? void 0 : _a.length) ? "recent" : "");
129
+ }, [handleClearSearchSelection, isRecentSearchesModeAvailable, recentSearches]);
130
+ const handleKeyDown = (0, react_1.useCallback)((event) => {
131
+ const isListItem = event.target instanceof HTMLElement && event.target.dataset.listItem === "true";
132
+ const isButtonItem = event.target instanceof HTMLElement && event.target.dataset.closeButton === "true";
133
+ const getSelector = () => {
134
+ if (isListItem) {
135
+ return `[data-list-item="true"]`;
136
+ }
137
+ if (isButtonItem) {
138
+ return `[data-close-button="true"]`;
139
+ }
140
+ return undefined;
141
+ };
142
+ if (event.key === "ArrowDown") {
143
+ const nextItem = (0, keyboardHelpers_1.getNewFocusableItem)(1, searchListRef.current, getSelector());
144
+ nextItem === null || nextItem === void 0 ? void 0 : nextItem.focus();
145
+ return;
146
+ }
147
+ if (event.key === "ArrowUp") {
148
+ const prevItem = (0, keyboardHelpers_1.getNewFocusableItem)(-1, searchListRef.current, getSelector());
149
+ prevItem === null || prevItem === void 0 ? void 0 : prevItem.focus();
150
+ return;
151
+ }
152
+ if (event.key === "ArrowRight" && isListItem) {
153
+ const nextItem = (0, keyboardHelpers_1.getNewFocusableItem)(1, searchListRef.current, `[data-close-button="true"]`);
154
+ nextItem === null || nextItem === void 0 ? void 0 : nextItem.focus();
155
+ return;
156
+ }
157
+ if (event.key === "ArrowLeft" && isButtonItem) {
158
+ const prevItem = (0, keyboardHelpers_1.getNewFocusableItem)(-1, searchListRef.current, `[data-list-item="true"]`);
159
+ prevItem === null || prevItem === void 0 ? void 0 : prevItem.focus();
160
+ return;
161
+ }
162
+ }, [searchListRef]);
67
163
  const memoizedRecentDataArr = (0, react_1.useMemo)(() => recentItems.filter(item => !removedItems.includes(item.id)).reverse(), [recentItems, removedItems]);
68
- const memoizedRecentData = (0, react_1.useMemo)(() => (historyMode ? memoizedRecentDataArr : (searchValue && isSearchMode ? [] : memoizedRecentDataArr.slice(0, waitingItemsLimit))).map(item => ((0, jsx_runtime_1.jsx)(filtersSearchItemData_1.FiltersSearchItemData, { id: item.id, name: item.name, isActive: false, secondary: item.description, onClose: handleRemove(item.id), onClick: memoizedRecentSearchItemClick(item.id, item.type || exports.NO_TYPED_SEARCH_ITEM), icon: getIconByType(item.type), isMobile: isMobile, isDrive: isDrive }, `recent-${item.id}`))), [historyMode, memoizedRecentDataArr, searchValue, isSearchMode, handleRemove, memoizedRecentSearchItemClick, getIconByType, isMobile, isDrive]);
69
- const memoizedSearchData = (0, react_1.useMemo)(() => historyMode || !searchValue && isRecentSearchesMode ? [] : searchItems.slice(0, filtersHelper_1.MAX_TOTAL_RESULTS).map(item => ((0, jsx_runtime_1.jsx)(filtersSearchItemData_1.FiltersSearchItemData, { id: item.id, name: item.name, isActive: isSearchMode ? searchSelection.filter(el => el.id === item.id).some(el => el.type === (item.type || exports.NO_TYPED_SEARCH_ITEM)) || false : false, secondary: item.description, onClose: undefined, onClick: isSearchMode ? memoizedSearchItemClick(item.id, item.type || exports.NO_TYPED_SEARCH_ITEM) : undefined, icon: getIconByType(item.type), isMobile: isMobile, isDrive: isDrive }, `search-${item.id}-${item.type || exports.NO_TYPED_SEARCH_ITEM}`))), [historyMode, searchValue, isRecentSearchesMode, searchItems, isSearchMode, searchSelection, memoizedSearchItemClick, getIconByType, isMobile, isDrive]);
70
- const resultsToShow = (0, react_1.useMemo)(() => isRecentSearchesMode ? [...memoizedRecentData, ...memoizedSearchData]
71
- : memoizedSearchData, [isRecentSearchesMode, memoizedRecentData, memoizedSearchData]);
72
- return (0, jsx_runtime_1.jsxs)("div", { className: "zen-filters-search-list", children: [searchValue ? null : (0, jsx_runtime_1.jsxs)("div", { className: (0, classNames_1.classNames)(["zen-filters-search-list__header", isDrive ? (isMobile ? "zen-filters-search-list__header--drive" : "zen-filters-search-list__header--drive-tablet") : ""]), children: [historyMode ? (0, jsx_runtime_1.jsx)(textIconButton_1.TextIconButton, { className: "zen-filters-search-list__header-back-button", title: translate("Back"), type: "tertiary", onClick: changeMode, icon: iconChevronLeft_1.IconChevronLeft, iconPosition: textIconButton_2.ButtonIconPosition.Start })
73
- : null, isRecentSearchesMode ? (0, jsx_runtime_1.jsx)("div", { className: "zen-filters-search-list__header-title", children: translate("Recent searches") }) : null, historyMode || !isRecentSearchesMode ? null : (0, jsx_runtime_1.jsx)(button_1.Button, { type: "tertiary", onClick: changeMode, children: translate("View history") }), historyMode && isRecentSearchesMode ? (0, jsx_runtime_1.jsx)(button_1.Button, { type: "tertiary", onClick: handleRemoveAll, children: translate("Clear all") }) : null] }), (0, jsx_runtime_1.jsx)(list_1.List, { className: "zen-filters-search-list__data", isLoading: isLoading, type: "data", waitingItems: waitingItemsLimit, children: resultsToShow })] });
164
+ const memoizedRecentData = (0, react_1.useMemo)(() => {
165
+ if (currentMode !== "recent" && currentMode !== "history") {
166
+ return [];
167
+ }
168
+ const recentDataArr = currentMode === "history" ? memoizedRecentDataArr : memoizedRecentDataArr.slice(0, waitingItemsLimit);
169
+ return recentDataArr.map(item => ((0, jsx_runtime_1.jsx)(filtersSearchItemData_1.FiltersSearchItemData, { id: item.id, name: item.name, isActive: false, secondary: item.description, onClose: handleRemove(item.id), onClick: memoizedRecentSearchItemClick(item.id, item.type), icon: getIconByType(item.type || onlyOneType), isMobile: isMobile, isDrive: isDrive }, `${currentMode}-${item.id}`)));
170
+ }, [currentMode, memoizedRecentDataArr, handleRemove, memoizedRecentSearchItemClick, getIconByType, onlyOneType, isMobile, isDrive]);
171
+ const memoizedSearchData = (0, react_1.useMemo)(() => currentMode !== "search" && currentMode !== "" ? [] : searchItems.slice(0, filtersHelper_1.MAX_TOTAL_RESULTS).map(item => ((0, jsx_runtime_1.jsx)(filtersSearchItemData_1.FiltersSearchItemData, { id: item.id, name: item.name, isActive: isSearchModeAvailable ? (onlyOneType ? searchSelection.some(el => el.id === item.id) : searchSelection.filter(el => el.id === item.id)
172
+ .some(el => el.type === (item.type || exports.NO_TYPED_SEARCH_ITEM)) || false) : false, secondary: item.description, onClose: undefined, onClick: isSearchModeAvailable ? memoizedSearchItemClick(item.id, item.type) : undefined, icon: getIconByType(item.type || onlyOneType), isMobile: isMobile, isDrive: isDrive }, `search-${item.id}-${item.type || exports.NO_TYPED_SEARCH_ITEM}`))), [currentMode, searchItems, isSearchModeAvailable, searchSelection, memoizedSearchItemClick, getIconByType, onlyOneType, isMobile, isDrive]);
173
+ const memoizedSelectedData = (0, react_1.useMemo)(() => currentMode !== "selected" || initialSearchSelectionRef.current.length === 0 ? [] : initialSearchSelectionRef.current.slice(0, filtersHelper_1.MAX_TOTAL_RESULTS)
174
+ .map(item => ((0, jsx_runtime_1.jsx)(filtersSearchItemData_1.FiltersSearchItemData, { id: item.id, name: item.name, isActive: onlyOneType ? (searchSelection || []).some(el => el.id === item.id)
175
+ : (searchSelection || []).filter(el => el.id === item.id).some(el => el.type === (item.type || exports.NO_TYPED_SEARCH_ITEM)) || false, secondary: item.description, onClose: undefined, onClick: memoizedSelectedItemClick(item.id, item.type), icon: getIconByType(item.type || onlyOneType), isMobile: isMobile, isDrive: isDrive }, `selected-${item.id}-${item.type || onlyOneType || exports.NO_TYPED_SEARCH_ITEM}-${item.name}-${hasNotPopulatedName ? "notPopulated" : ""}`))), [currentMode, onlyOneType, searchSelection, memoizedSelectedItemClick, getIconByType, isMobile, isDrive, hasNotPopulatedName]);
176
+ const resultsToShow = (0, react_1.useMemo)(() => {
177
+ if (currentMode === "search") {
178
+ return memoizedSearchData;
179
+ }
180
+ if (currentMode === "recent" || currentMode === "history") {
181
+ return memoizedRecentData;
182
+ }
183
+ if (currentMode === "selected") {
184
+ return memoizedSelectedData;
185
+ }
186
+ return memoizedSearchData;
187
+ }, [currentMode, memoizedSearchData, memoizedRecentData, memoizedSelectedData]);
188
+ const getSearchHeaderContent = () => {
189
+ if (currentMode === "history") {
190
+ return (0, jsx_runtime_1.jsxs)(jsx_runtime_1.Fragment, { children: [(0, jsx_runtime_1.jsx)(textIconButton_1.TextIconButton, { className: "zen-filters-search-list__header-back-button", title: translate("Back"), type: "tertiary", onClick: changeMode.bind(null, "recent"), icon: iconChevronLeft_1.IconChevronLeft, iconPosition: textIconButton_2.ButtonIconPosition.Start }), (0, jsx_runtime_1.jsx)(button_1.Button, { type: "tertiary", onClick: handleRemoveAll, children: translate("Clear all") })] });
191
+ }
192
+ if (currentMode === "recent" || currentMode === "selected") {
193
+ return (0, jsx_runtime_1.jsxs)(jsx_runtime_1.Fragment, { children: [(0, jsx_runtime_1.jsxs)("div", { className: "zen-filters-search-list__header-title", children: [(0, jsx_runtime_1.jsx)(button_1.Button, { type: currentMode === "recent" ? "tertiary" : "tertiary-black", className: currentMode === "recent" ? "zen-filters-search-list__header-button--active" : "", title: translate("Recent searches"), onClick: changeMode.bind(null, "recent"), children: translate("Recent searches") }), (0, jsx_runtime_1.jsx)(button_1.Button, { type: currentMode === "selected" ? "tertiary" : "tertiary-black", className: currentMode === "selected" ? "zen-filters-search-list__header-button--active" : "", title: translate("Currently selected"), onClick: changeMode.bind(null, "selected"), children: translate("Currently selected") })] }), currentMode === "recent" && recentItems.length > resultsToShow.length && (0, jsx_runtime_1.jsx)(button_1.Button, { type: "tertiary", onClick: changeMode.bind(null, "history"), children: translate("View history") }), currentMode === "selected" && resultsToShow.length > 0 && (0, jsx_runtime_1.jsx)(button_1.Button, { type: "tertiary", onClick: memoizedClearSelectedItems, children: translate("Clear") })] });
194
+ }
195
+ if (currentMode === "search" && resultsToShow.length > 0) {
196
+ return (0, jsx_runtime_1.jsx)("div", { className: "zen-filters-search-list__header-title", children: translate("Top results") });
197
+ }
198
+ return undefined;
199
+ };
200
+ const searchHeaderContent = getSearchHeaderContent();
201
+ return (0, jsx_runtime_1.jsxs)("div", { className: "zen-filters-search-list", children: [searchHeaderContent ? (0, jsx_runtime_1.jsx)("div", { className: (0, classNames_1.classNames)(["zen-filters-search-list__header", isDrive ? (isMobile ? "zen-filters-search-list__header--drive" : "zen-filters-search-list__header--drive-tablet") : ""]), children: searchHeaderContent }) : null, (0, jsx_runtime_1.jsx)("div", { ref: searchListRef, children: (0, jsx_runtime_1.jsx)(list_1.List, { className: "zen-filters-search-list__data", onKeyDown: handleKeyDown, isLoading: currentMode === "selected" ? false : isLoading, type: "data", waitingItems: waitingItemsLimit, children: resultsToShow }) }), !isLoading && resultsToShow.length === 0 ? (0, jsx_runtime_1.jsx)(emptySearchList_1.EmptySearchList, { children: translate("No data available") }) : null] });
74
202
  };
75
203
  exports.FiltersSearchList = FiltersSearchList;
@@ -15,6 +15,7 @@ export interface IFiltersSelect extends IFiltersSelectProps {
15
15
  value: IFiltersSearchType;
16
16
  onChange: (newValue: IFiltersSearchType) => void;
17
17
  className?: string;
18
+ selectListRef: React.RefObject<HTMLDivElement>;
18
19
  }
19
20
  export declare const ALL_SELECT_OPTION_ID: string;
20
21
  export interface IFiltersSearchType {
@@ -7,6 +7,7 @@ const classNames_1 = require("../../commonHelpers/classNames/classNames");
7
7
  const useLanguage_1 = require("../../utils/localization/useLanguage");
8
8
  const useUniqueId_1 = require("../../commonHelpers/useUniqueId");
9
9
  const filtersSelectListItem_1 = require("./filtersSelectListItem");
10
+ const keyboardHelpers_1 = require("../../utils/keyboardHelpers");
10
11
  exports.ALL_SELECT_OPTION_ID = "All";
11
12
  exports.FiltersSelectDisplayName = "FiltersSelect";
12
13
  const getFiltersSearchTypeAllOption = () => ({
@@ -18,7 +19,7 @@ const getAllOption = (translate) => ({
18
19
  name: translate("All")
19
20
  });
20
21
  exports.getAllOption = getAllOption;
21
- const FiltersSelect = ({ value, name, onChange, id, items, className }) => {
22
+ const FiltersSelect = ({ value, onChange, items, className, selectListRef }) => {
22
23
  const { translate } = (0, useLanguage_1.useLanguage)();
23
24
  const [activeId, setActiveId] = (0, react_1.useState)("");
24
25
  const filtersSelectListId = (0, useUniqueId_1.useUniqueId)();
@@ -33,19 +34,46 @@ const FiltersSelect = ({ value, name, onChange, id, items, className }) => {
33
34
  return;
34
35
  }
35
36
  setActiveId(clickedId);
36
- onChange({ [clickedId]: undefined });
37
- }, [activeId, onChange]);
37
+ }, [activeId]);
38
38
  const handleItemClick = (0, react_1.useCallback)((clickedId, parentId) => () => {
39
+ if (!clickedId) {
40
+ parentId && onChange({ [parentId]: undefined });
41
+ return;
42
+ }
39
43
  if (parentId) {
40
44
  onChange({ [parentId]: clickedId });
41
45
  return;
42
46
  }
43
- setActiveId("");
44
47
  onChange(Object.keys(value).includes(clickedId) ? (0, exports.getFiltersSearchTypeAllOption)() : { [clickedId]: undefined });
45
48
  }, [onChange, value]);
46
- const selectListComponent = (0, react_1.useMemo)(() => preparedItems.map(el => el.subItems ?
47
- (0, jsx_runtime_1.jsx)(filtersSelectListItem_1.FiltersSelectListExpandableItem, { id: `${filtersSelectListId}-${el.id}`, name: el.name, isActive: el.id === activeId, className: (0, classNames_1.classNames)([value.hasOwnProperty(el.id) ? "zen-filters-select__list-item--active" : ""]), onClick: handleExpandableItemClick(el.id), content: el.id === activeId ? el.subItems.map(subEl => (0, jsx_runtime_1.jsx)(filtersSelectListItem_1.FiltersSelectListItem, { className: (0, classNames_1.classNames)(["zen-filters-select__sub-item"]), id: `${filtersSelectListId}-${el.id}-${subEl.id}`, name: subEl.name, isActive: value[el.id] === subEl.id, onClick: handleItemClick(subEl.id, el.id) }, `${el.id}-${subEl.id}`)) : (0, jsx_runtime_1.jsx)(jsx_runtime_1.Fragment, {}) }, el.id) : (0, jsx_runtime_1.jsx)(filtersSelectListItem_1.FiltersSelectListItem, { id: `${filtersSelectListId}-${el.id}`, name: el.name, isActive: Object.keys(value).includes(el.id), onClick: handleItemClick(el.id) }, el.id)), [activeId, filtersSelectListId, handleExpandableItemClick, handleItemClick, preparedItems, value]);
48
- return (0, jsx_runtime_1.jsxs)("div", { className: "zen-filters-select", children: [id && name ? (0, jsx_runtime_1.jsx)("div", { className: "zen-filters-select__label", id: id, children: name }) : null, (0, jsx_runtime_1.jsx)("div", { className: (0, classNames_1.classNames)(["zen-filters-select__list", className || ""]), children: selectListComponent })] });
49
+ const handleKeyDown = (0, react_1.useCallback)((event) => {
50
+ var _a, _b, _c, _d;
51
+ if (event.key === "ArrowDown") {
52
+ const nextElement = ((_a = document.activeElement) === null || _a === void 0 ? void 0 : _a.nextElementSibling) ? (_b = document.activeElement) === null || _b === void 0 ? void 0 : _b.nextElementSibling
53
+ : (0, keyboardHelpers_1.getNewFocusableItem)(1, selectListRef.current);
54
+ nextElement === null || nextElement === void 0 ? void 0 : nextElement.focus();
55
+ return;
56
+ }
57
+ if (event.key === "ArrowUp") {
58
+ const nextElement = ((_c = document.activeElement) === null || _c === void 0 ? void 0 : _c.previousElementSibling) ? (_d = document.activeElement) === null || _d === void 0 ? void 0 : _d.previousElementSibling
59
+ : (0, keyboardHelpers_1.getNewFocusableItem)(-1, selectListRef.current);
60
+ nextElement === null || nextElement === void 0 ? void 0 : nextElement.focus();
61
+ return;
62
+ }
63
+ if (event.key === "ArrowLeft") {
64
+ const nextElement = (0, keyboardHelpers_1.getNewFocusableItem)(-1, selectListRef.current);
65
+ nextElement === null || nextElement === void 0 ? void 0 : nextElement.focus();
66
+ return;
67
+ }
68
+ if (event.key === "ArrowRight") {
69
+ const nextElement = (0, keyboardHelpers_1.getNewFocusableItem)(1, selectListRef.current);
70
+ nextElement === null || nextElement === void 0 ? void 0 : nextElement.focus();
71
+ return;
72
+ }
73
+ }, [selectListRef]);
74
+ const selectListComponent = (0, react_1.useMemo)(() => preparedItems.map(el => el.subItems && el.subItems.length > 0 ?
75
+ (0, jsx_runtime_1.jsx)(filtersSelectListItem_1.FiltersSelectListExpandableItem, { id: `${filtersSelectListId}-${el.id}`, name: el.name, isExpanded: el.id === activeId, isActive: Object.keys(value).includes(el.id) && Boolean(value[el.id]), className: (0, classNames_1.classNames)([value.hasOwnProperty(el.id) ? "zen-filters-select__list-item-wrapper--active" : ""]), onExpandItem: handleExpandableItemClick(el.id), onClick: handleItemClick(undefined, el.id), content: el.id === activeId ? el.subItems.map(subEl => (0, jsx_runtime_1.jsx)(filtersSelectListItem_1.FiltersSelectListItem, { className: (0, classNames_1.classNames)(["zen-filters-select__sub-item"]), id: `${filtersSelectListId}-${el.id}-${subEl.id}`, name: subEl.name, isActive: value[el.id] === subEl.id, onClick: handleItemClick(subEl.id, el.id) }, `${el.id}-${subEl.id}`)) : (0, jsx_runtime_1.jsx)(jsx_runtime_1.Fragment, {}) }, `${filtersSelectListId}-${el.id}`) : (0, jsx_runtime_1.jsx)(filtersSelectListItem_1.FiltersSelectListItem, { id: `${filtersSelectListId}-${el.id}`, name: el.name, className: "zen-filters-select__list-item--not-expandable", isActive: Object.keys(value).includes(el.id), onClick: handleItemClick(el.id) }, `${filtersSelectListId}-${el.id}`)), [activeId, filtersSelectListId, handleExpandableItemClick, handleItemClick, preparedItems, value]);
76
+ return (0, jsx_runtime_1.jsx)("div", { className: "zen-filters-select", ref: selectListRef, onKeyDown: handleKeyDown, children: (0, jsx_runtime_1.jsx)("div", { className: (0, classNames_1.classNames)(["zen-filters-select__list", className || ""]), children: selectListComponent }) });
49
77
  };
50
78
  exports.FiltersSelect = FiltersSelect;
51
79
  exports.FiltersSelect.displayName = exports.FiltersSelectDisplayName;