@geotab/zenith 3.0.1 → 3.1.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
@@ -0,0 +1,9 @@
1
+ import React from "react";
2
+ interface IFiltersSidePanelChip {
3
+ currentState: boolean;
4
+ handleStateChange: (newState: boolean) => void;
5
+ children: string;
6
+ id: string;
7
+ }
8
+ export declare const FiltersSidePanelChip: React.FC<IFiltersSidePanelChip>;
9
+ export {};
@@ -0,0 +1,9 @@
1
+ import { jsx as _jsx } from "react/jsx-runtime";
2
+ import { useCallback } from "react";
3
+ import { Checkbox } from "../../checkbox/checkbox";
4
+ export const FiltersSidePanelChip = ({ currentState, handleStateChange, id, children }) => {
5
+ const handleChange = useCallback((e) => {
6
+ handleStateChange(e.target.checked);
7
+ }, [handleStateChange]);
8
+ return _jsx(Checkbox, { fullWidth: true, id: id, onChange: handleChange, checked: currentState, children: children });
9
+ };
@@ -0,0 +1,6 @@
1
+ /// <reference types="react" />
2
+ import { TFiltersDropdownAllStates } from "./filtersDropdown";
3
+ import { IFiltersSidePanelComponentProps } from "./filtersSidePanelItem";
4
+ type IFiltersSidePanelDropdown = IFiltersSidePanelComponentProps<TFiltersDropdownAllStates>;
5
+ export declare const FiltersSidePanelDropdown: React.FC<IFiltersSidePanelDropdown>;
6
+ export {};
@@ -0,0 +1,81 @@
1
+ var __rest = (this && this.__rest) || function (s, e) {
2
+ var t = {};
3
+ for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)
4
+ t[p] = s[p];
5
+ if (s != null && typeof Object.getOwnPropertySymbols === "function")
6
+ for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {
7
+ if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i]))
8
+ t[p[i]] = s[p[i]];
9
+ }
10
+ return t;
11
+ };
12
+ import { jsx as _jsx } from "react/jsx-runtime";
13
+ import { useCallback, useEffect, useMemo, useRef, useState } from "react";
14
+ import { classNames } from "../../commonHelpers/classNames/classNames";
15
+ import { Dropdown } from "../../dropdown/dropdown";
16
+ import { getDropdownStateType, prepareDefaultDropdownState } from "../filtersHelper";
17
+ import { FiltersChip } from "./filtersChip";
18
+ import { Skeleton } from "../../skeleton/skeleton";
19
+ import { sortDropdownItemArray } from "../../dropdown/dropdownHelper";
20
+ import { RadioGroup } from "../../radioGroup/radioGroup";
21
+ import { getGroupDescription } from "../../groupsFilter/groupsHelper";
22
+ import { useLanguage } from "../../utils/localization/useLanguage";
23
+ import { SkeletonList } from "../../skeletonList/skeletonList";
24
+ export const FiltersSidePanelDropdown = ({ elemProps, currentState, handleStateChange }) => {
25
+ const simpleViewLimit = 7;
26
+ const _a = elemProps, { id, name, state: _globalState, onChange: _globalOnChange, defaultState, fetchState, dataItems, isLoading, classNamePopup } = _a, otherProps = __rest(_a, ["id", "name", "state", "onChange", "defaultState", "fetchState", "dataItems", "isLoading", "classNamePopup"]);
27
+ const dropdownDataRef = useRef(null);
28
+ const { translate } = useLanguage();
29
+ const dropdownStateType = useMemo(() => getDropdownStateType(currentState), [currentState]);
30
+ const isMultiselect = useMemo(() => dropdownStateType === "fullSelection" || dropdownStateType === "fullSelectionWithCheckbox" ? true
31
+ : (elemProps.multiselect === undefined ? true : elemProps.multiselect), [dropdownStateType, elemProps]);
32
+ const [componentType, setComponentType] = useState(dropdownStateType !== "base" ? "popup" : undefined);
33
+ const sortFn = useMemo(() => otherProps.sortFn, [otherProps]);
34
+ useEffect(() => {
35
+ const dropdownData = dataItems && dataItems.length ? dataItems : (fetchState === null || fetchState === void 0 ? void 0 : fetchState.data) || [];
36
+ if (dataItems && dataItems.length || fetchState && fetchState.data && !fetchState.isLoading && !componentType && dropdownDataRef.current === null) {
37
+ setComponentType(dropdownData.length > simpleViewLimit ? "popup" : (isMultiselect ? "chip" : "radio"));
38
+ dropdownDataRef.current = sortDropdownItemArray(dropdownData, sortFn);
39
+ }
40
+ else if ((componentType === "chip" || componentType === "radio") && dropdownData.length > simpleViewLimit) {
41
+ setComponentType("popup");
42
+ }
43
+ }, [componentType, fetchState, dataItems, isMultiselect, sortFn]);
44
+ const prepareValue = (value) => {
45
+ if (Array.isArray(value)) {
46
+ return value.map((el) => el.id);
47
+ }
48
+ return Object.assign(Object.assign({}, value), { selected: value.selected.map((el) => el.id) });
49
+ };
50
+ const preparedDefaultState = defaultState !== undefined ? defaultState : prepareDefaultDropdownState(dropdownStateType);
51
+ const dropdownProps = Object.assign(Object.assign({}, otherProps), { id: `${id}-side-panel`, fetchState: fetchState, dataItems: dataItems, isLoading: dataItems !== undefined ? isLoading : undefined, classNamePopup: classNames(["zen-side-panel-filters__item-popup", classNamePopup || ""]), multiselect: isMultiselect, selectAllButton: dropdownStateType === "fullSelection" || dropdownStateType === "fullSelectionWithCheckbox" ? true : otherProps.selectAllButton, fullWidthTriggerButton: true, errorHandler: (() => { }), placeholder: otherProps.placeholder || name, showSelection: true, value: currentState, onChange: (newValue) => {
52
+ const preparedValue = prepareValue(newValue);
53
+ handleStateChange(preparedValue);
54
+ }, defaultValue: preparedDefaultState, chip: false });
55
+ const handleChipChange = useCallback((itemId) => (value) => {
56
+ const newValue = () => value ? [...currentState, itemId] : currentState.filter(elId => elId !== itemId);
57
+ handleStateChange(newValue());
58
+ }, [currentState, handleStateChange]);
59
+ const handleRadioChange = useCallback((e) => {
60
+ const value = e.target.checked;
61
+ const itemId = e.target.value;
62
+ const newValue = () => value ? [itemId] : currentState.filter(elId => elId !== itemId);
63
+ handleStateChange(newValue());
64
+ }, [currentState, handleStateChange]);
65
+ if (!componentType && (dataItems !== undefined && isLoading || fetchState && fetchState.isLoading)) {
66
+ return isMultiselect ? _jsx(Skeleton, { width: 328, height: 32 }) : _jsx(SkeletonList, { className: "zen-side-panel-filters__dropdown-skeleton", size: "small" });
67
+ }
68
+ if (componentType === "chip" && dropdownDataRef.current) {
69
+ const dropdownChips = dropdownDataRef.current.map((item) => (_jsx(FiltersChip, { id: `${id}-side-panel-chip-${item.id}`, name: item.name || item.id, state: currentState.includes(item.id), onChange: handleChipChange(item.id), icon: elemProps.chipIcon }, `${id}-side-panel-chip-${item.id}-${item.name || ""}`)));
70
+ return _jsx("div", { className: classNames(["zen-side-panel-filters__dropdown-item-chips-container"]), children: dropdownChips });
71
+ }
72
+ if (componentType === "radio" && dropdownDataRef.current) {
73
+ const dropdownRadioGroup = _jsx(RadioGroup, { direction: "vertical", size: "small", id: `${id}-side-panel-dropdown-radio-group`, className: "zen-side-panel-radio-group__filter-item", items: dropdownDataRef.current.map((item) => ({
74
+ id: `${id}_radio-group-item_${item.id}`,
75
+ value: item.id,
76
+ children: _jsx("span", { children: getGroupDescription(item, translate) })
77
+ })), fullWidth: true, name: name, onChange: handleRadioChange, value: currentState[0] });
78
+ return _jsx("div", { className: classNames(["zen-side-panel-filters__dropdown-item-radio-group-container"]), children: dropdownRadioGroup });
79
+ }
80
+ return _jsx(Dropdown, Object.assign({}, dropdownProps));
81
+ };
@@ -0,0 +1,16 @@
1
+ import { ReactElement } from "react";
2
+ import { TFiltersComponentsItemState, TFiltersComponentsProps } from "./filtersItem";
3
+ import "./filtersSidePanelItem.less";
4
+ interface IFiltersSidePanelItem {
5
+ item: ReactElement<TFiltersComponentsProps>;
6
+ itemState: TFiltersComponentsItemState;
7
+ changeHandler: (newState: TFiltersComponentsItemState) => void;
8
+ errorCheck: (isError: boolean) => void;
9
+ }
10
+ export interface IFiltersSidePanelComponentProps<T> {
11
+ elemProps: TFiltersComponentsProps;
12
+ currentState: T;
13
+ handleStateChange: (newState: T) => void;
14
+ }
15
+ export declare const FiltersSidePanelItem: React.FC<IFiltersSidePanelItem>;
16
+ export {};
@@ -0,0 +1,63 @@
1
+ var __rest = (this && this.__rest) || function (s, e) {
2
+ var t = {};
3
+ for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)
4
+ t[p] = s[p];
5
+ if (s != null && typeof Object.getOwnPropertySymbols === "function")
6
+ for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {
7
+ if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i]))
8
+ t[p[i]] = s[p[i]];
9
+ }
10
+ return t;
11
+ };
12
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
13
+ /* eslint-disable complexity */
14
+ import { useCallback, useMemo } from "react";
15
+ import { FiltersChip } from "./filtersChip";
16
+ import { FiltersRange } from "./filtersRange";
17
+ import { classNames } from "../../commonHelpers/classNames/classNames";
18
+ import { FiltersDropdown } from "./filtersDropdown";
19
+ import { FiltersGroups } from "./filtersGroups";
20
+ import { GroupsFilter } from "../../groupsFilter/groupsFilter";
21
+ import { FiltersDateRange } from "./filtersDateRange";
22
+ import { DateRange } from "../../dateRange/dateRange";
23
+ import { FiltersDateInput } from "./filtersDateInput";
24
+ import { DateInput } from "../../dateInput/dateInput";
25
+ import { FiltersSidePanelDropdown } from "./filtersSidePanelDropdown";
26
+ import { FiltersSidePanelChip } from "./filtersSidePanelChip";
27
+ import { useUniqueId } from "../../commonHelpers/useUniqueId";
28
+ import { FiltersSidePanelRange } from "./filtersSidePanelRange";
29
+ export const FiltersSidePanelItem = ({ item, itemState, changeHandler, errorCheck }) => {
30
+ const labelledId = useUniqueId();
31
+ const getComponent = useCallback((elem, currentState, handleStateChange) => {
32
+ const { type, props } = elem;
33
+ switch (type) {
34
+ case FiltersChip: {
35
+ const { id, state: _globalState, name, onChange: _globalOnChange } = props;
36
+ return _jsx(FiltersSidePanelChip, { id: `${id}-side-panel`, currentState: currentState, handleStateChange: handleStateChange, children: name });
37
+ }
38
+ case FiltersRange: {
39
+ const _a = props, { id, state: _globalState, name, onChange: _globalOnChange, defaultState, className } = _a, otherProps = __rest(_a, ["id", "state", "name", "onChange", "defaultState", "className"]);
40
+ return _jsx(FiltersSidePanelRange, Object.assign({}, otherProps, { id: `${id}-side-panel`, onChange: handleStateChange, value: currentState, errorCheck: errorCheck, className: classNames(["zen-side-panel-filters__item-element", className || ""]) }));
41
+ }
42
+ case FiltersDropdown: {
43
+ return _jsx(FiltersSidePanelDropdown, { elemProps: props, currentState: currentState, handleStateChange: handleStateChange });
44
+ }
45
+ case FiltersGroups: {
46
+ const _b = props, { id, state: _globalState, onChange: _globalOnChange } = _b, otherProps = __rest(_b, ["id", "state", "onChange"]);
47
+ return _jsx(GroupsFilter, Object.assign({ initialFilterState: currentState, onChange: handleStateChange }, otherProps, { chip: false, fullSize: true }));
48
+ }
49
+ case FiltersDateRange: {
50
+ const _c = props, { id, state: _globalState, onChange: _globalOnChange, defaultState, allowUnsetValue, className, classNamePopup } = _c, otherProps = __rest(_c, ["id", "state", "onChange", "defaultState", "allowUnsetValue", "className", "classNamePopup"]);
51
+ return allowUnsetValue ? _jsx(DateRange, Object.assign({}, otherProps, { id: `${id}-side-panel`, classNamePopup: classNames([classNamePopup || "", "zen-side-panel-filters__date-popup--full-width"]), className: classNames(["zen-side-panel-filters__item-element", "zen-side-panel-filters__item-element--centred", className || ""]), value: currentState, onChange: handleStateChange, defaultValue: defaultState, allowUnsetValue: true, chip: false })) : _jsx(DateRange, Object.assign({}, otherProps, { id: `${id}-side-panel`, classNamePopup: classNames([classNamePopup || "", "zen-side-panel-filters__date-popup--full-width"]), className: classNames(["zen-side-panel-filters__item-element", "zen-side-panel-filters__item-element--centred", className || ""]), value: currentState, onChange: handleStateChange, defaultValue: defaultState, allowUnsetValue: false, chip: false }));
52
+ }
53
+ case FiltersDateInput: {
54
+ const _d = props, { id, state: _globalState, name, onChange: _globalOnChange, defaultState, className, classNamePopup } = _d, otherProps = __rest(_d, ["id", "state", "name", "onChange", "defaultState", "className", "classNamePopup"]);
55
+ return _jsx(DateInput, Object.assign({}, otherProps, { id: `${id}-side-panel`, classNamePopup: classNames([classNamePopup || "", "zen-side-panel-filters__date-popup--full-width"]), className: classNames(["zen-side-panel-filters__item-element", "zen-side-panel-filters__item-element--centred", className || ""]), buttonLabel: name, value: currentState, onChange: handleStateChange, defaultValue: defaultState, chip: false }));
56
+ }
57
+ default:
58
+ return null;
59
+ }
60
+ }, [errorCheck]);
61
+ const memoizedItem = useMemo(() => getComponent(item, itemState, changeHandler), [getComponent, item, itemState, changeHandler]);
62
+ return (_jsxs("div", { className: "zen-side-panel-filters__item", role: "group", "aria-labelledby": labelledId, children: [_jsx("div", { className: "zen-side-panel-filters__item-label", id: labelledId, children: item.props.name }), _jsx("div", { children: memoizedItem })] }));
63
+ };
@@ -0,0 +1,6 @@
1
+ import { IFiltersBarSidePanelRange } from "../../filtersBar/filtersBarSidePanel/components/filtersBarSidePanelRange/filtersBarSidePanelRange";
2
+ interface IFiltersSidePanelRangeProps extends IFiltersBarSidePanelRange {
3
+ errorCheck: (isError: boolean) => void;
4
+ }
5
+ export declare const FiltersSidePanelRange: ({ errorCheck, ...otherProps }: IFiltersSidePanelRangeProps) => import("react/jsx-runtime").JSX.Element;
6
+ export {};
@@ -0,0 +1,24 @@
1
+ var __rest = (this && this.__rest) || function (s, e) {
2
+ var t = {};
3
+ for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)
4
+ t[p] = s[p];
5
+ if (s != null && typeof Object.getOwnPropertySymbols === "function")
6
+ for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {
7
+ if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i]))
8
+ t[p[i]] = s[p[i]];
9
+ }
10
+ return t;
11
+ };
12
+ import { jsx as _jsx } from "react/jsx-runtime";
13
+ import { useEffect, useMemo } from "react";
14
+ import { FiltersBarSidePanelRange } from "../../filtersBar/filtersBarSidePanel/components/filtersBarSidePanelRange/filtersBarSidePanelRange";
15
+ import { checkErrorType } from "../../range/rangeHelper";
16
+ export const FiltersSidePanelRange = (_a) => {
17
+ var { errorCheck } = _a, otherProps = __rest(_a, ["errorCheck"]);
18
+ const { value } = otherProps;
19
+ const hasError = useMemo(() => checkErrorType(value.min, value.max, otherProps.fullBounded, otherProps.allowEqualMinMax, otherProps.min, otherProps.max) !== undefined, [value, otherProps.fullBounded, otherProps.allowEqualMinMax, otherProps.min, otherProps.max]);
20
+ useEffect(() => {
21
+ errorCheck(hasError);
22
+ }, [errorCheck, hasError]);
23
+ return _jsx(FiltersBarSidePanelRange, Object.assign({}, otherProps));
24
+ };
@@ -10,6 +10,7 @@ import { IFiltersChip } from "./components/filtersChip";
10
10
  import { FiltersDateRange } from "./components/filtersDateRange";
11
11
  import { IRecentSearchItem, IRecentSearchItemWithoutId, ISearchItem } from "./components/filtersSearchList";
12
12
  import { IIcon } from "../icons/icon";
13
+ import { IFiltersDateInput } from "./components/filtersDateInput";
13
14
  export interface ISavedFilters {
14
15
  id: string;
15
16
  name: string;
@@ -91,9 +92,13 @@ export declare const FiltersDisplayName = "Filters";
91
92
  interface IFiltersComponents {
92
93
  Chip: React.FC<IFiltersChip>;
93
94
  DateRange: typeof FiltersDateRange;
95
+ DateInput: React.FC<IFiltersDateInput>;
94
96
  Dropdown: React.FC<IFiltersDropdown<TFiltersDropdownAllStates>>;
95
97
  Groups: React.FC<IFiltersGroups>;
96
98
  Range: React.FC<IFiltersRange>;
97
99
  }
100
+ /**
101
+ * @beta This component is currently in beta.
102
+ */
98
103
  export declare const Filters: React.FC<IFilters> & IFiltersComponents;
99
104
  export {};
@@ -1,6 +1,7 @@
1
1
  import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
2
  /* eslint-disable @typescript-eslint/no-explicit-any */
3
3
  import { useCallback, useEffect, useMemo, useState } from "react";
4
+ import { flushSync } from "react-dom";
4
5
  import { getArrayOfChildren } from "../header/headerHelpers";
5
6
  import React from "react";
6
7
  import { ALL_SELECT_OPTION_ID, FiltersSelect, getAllOption } from "./components/filtersSelect";
@@ -16,7 +17,6 @@ import { FiltersGroups } from "./components/filtersGroups";
16
17
  import { FiltersRange } from "./components/filtersRange";
17
18
  import { FiltersChip } from "./components/filtersChip";
18
19
  import { FiltersDateRange } from "./components/filtersDateRange";
19
- import { FiltersModal } from "./components/filtersModal";
20
20
  import { FiltersSearchList, KEYWORD_ID, KEYWORD_TYPE, NO_TYPED_SEARCH_ITEM } from "./components/filtersSearchList";
21
21
  import { ChipStatusProvider } from "../chip/chipStatusProvider";
22
22
  import { FiltersSavedItemsProvider } from "./components/filtersSavedItemsProvider";
@@ -25,20 +25,34 @@ import { FiltersSearch } from "./components/filtersSearch";
25
25
  import { useUniqueId } from "../commonHelpers/useUniqueId";
26
26
  import { isElementsEqual } from "../utils/compareElementsUtils/isElementsEqual";
27
27
  import { IconFilter } from "../icons/iconFilter";
28
+ import { FiltersSidePanel } from "./components/filtersSidePanel";
29
+ import { FiltersDateInput } from "./components/filtersDateInput";
30
+ import { useMobile } from "../commonHelpers/hooks/useMobile";
31
+ import { IconChevronTopSmall } from "../icons/iconChevronTopSmall";
32
+ import { FOCUSABLE_SELECTOR } from "../utils/focusableSelector";
28
33
  export const FiltersDisplayName = "Filters";
34
+ /**
35
+ * @beta This component is currently in beta.
36
+ */
29
37
  export const Filters = ({ className, children, isPinned, onPinChange, keyword, setKeyword, searchTypes, searchType, setSearchType, allFiltersState, setAllFiltersState, onToggleView, searchSelection, setSearchSelection, recentSearches, onRemoveRecentSearchItem, onSaveRecentSearch, savedFilters, onRemoveSavedFilter, onSaveFilter }) => {
30
38
  const [isOpen, setIsOpen] = useState(false);
31
39
  const isSavedFiltersMode = Boolean(savedFilters && onRemoveSavedFilter && onSaveFilter);
32
40
  const isPinMode = Boolean(typeof isPinned === "boolean" && onPinChange);
33
41
  const isRecentSearchesMode = Boolean(recentSearches && onRemoveRecentSearchItem && onSaveRecentSearch);
34
42
  const uniqueKey = useUniqueId();
35
- const [isModalOpen, setIsModalOpen] = useState(false);
43
+ const isMobile = useMobile();
44
+ const [isSidePanelOpen, setIsSidePanelOpen] = useState(false);
36
45
  const triggerRef = React.useRef(null);
46
+ const sidePanelTriggerRef = React.useRef(null);
47
+ const searchPopupTriggerRef = React.useRef(null);
48
+ const searchListRef = React.useRef(null);
49
+ const selectListRef = React.useRef(null);
37
50
  const searchTriggerRef = React.useRef(null);
38
51
  const prevIsOpenRef = React.useRef(isOpen);
39
52
  const [savedFiltersStates, setSavedFiltersStates] = useState(new Map());
40
53
  const { translate } = useLanguage();
41
54
  const searchTypesArray = useMemo(() => getArrayOfElements(searchTypes), [searchTypes]);
55
+ const searchOnlyOneType = useMemo(() => searchTypesArray.length === 1 ? searchTypesArray[0].id : undefined, [searchTypesArray]);
42
56
  const searchTypesMap = useMemo(() => {
43
57
  const map = new Map();
44
58
  searchTypesArray.forEach(el => {
@@ -82,19 +96,19 @@ export const Filters = ({ className, children, isPinned, onPinChange, keyword, s
82
96
  const newRecentSearchName = newRecentSearchNamesArr.join(", ");
83
97
  const newRecentSearch = { name: newRecentSearchName, type: isTyped ? preparedItemsArray[0].type : NO_TYPED_SEARCH_ITEM,
84
98
  description: Array.from(new Set(entries.filter(el => el.type && el.type !== NO_TYPED_SEARCH_ITEM && el.type !== KEYWORD_TYPE)
85
- .map(el => searchTypesMap.get(el.type) || el))).join(", "),
99
+ .map(el => searchTypesMap.get(el.type) || ""))).join(", "),
86
100
  itemsArray: [...preparedItemsArray] };
87
101
  onSaveRecentSearch(Object.assign({}, newRecentSearch));
88
102
  }, [onSaveRecentSearch, searchSelection, searchTypesMap]);
89
- const handleSearchFocus = useCallback(() => {
90
- if (!isOpen) {
91
- setIsOpen(true);
92
- }
93
- }, [isOpen]);
94
103
  useEffect(() => {
95
- var _a;
96
- isOpen && ((_a = searchTriggerRef.current) === null || _a === void 0 ? void 0 : _a.focus());
97
- }, [isOpen, searchTriggerRef]);
104
+ var _a, _b;
105
+ if (isOpen) {
106
+ (_a = searchPopupTriggerRef.current) === null || _a === void 0 ? void 0 : _a.focus();
107
+ }
108
+ else {
109
+ prevIsOpenRef.current && ((_b = searchTriggerRef.current) === null || _b === void 0 ? void 0 : _b.focus());
110
+ }
111
+ }, [isOpen, searchPopupTriggerRef, searchTriggerRef]);
98
112
  useEffect(() => {
99
113
  if (!isOpen && prevIsOpenRef.current) {
100
114
  prevIsOpenRef.current = false;
@@ -105,31 +119,53 @@ export const Filters = ({ className, children, isPinned, onPinChange, keyword, s
105
119
  }
106
120
  }, [isOpen, isRecentSearchesMode, handleSaveRecentSearch]);
107
121
  const selectState = useMemo(() => Object.keys(searchType), [searchType]);
122
+ const onClearSearchSelection = useCallback(() => {
123
+ setSearchSelection && setSearchSelection([]);
124
+ }, [setSearchSelection]);
108
125
  const onSearchItemClick = useCallback((item) => {
109
126
  if (!(searchSelection && setSearchSelection)) {
110
127
  return;
111
128
  }
112
129
  const typeKey = item.type || NO_TYPED_SEARCH_ITEM;
113
- const currentItem = searchSelection.find(el => el.id === item.id && (el.type || NO_TYPED_SEARCH_ITEM) === typeKey);
130
+ const currentItem = searchOnlyOneType ? searchSelection.find(el => el.id === item.id)
131
+ : searchSelection.find(el => el.id === item.id && (el.type || NO_TYPED_SEARCH_ITEM) === typeKey);
114
132
  if (currentItem) {
115
- const newValue = searchSelection.filter(el => !(el.id === currentItem.id && (el.type || NO_TYPED_SEARCH_ITEM) === typeKey));
133
+ const newValue = searchOnlyOneType ? searchSelection.filter(el => el.id !== currentItem.id)
134
+ : searchSelection.filter(el => !(el.id === currentItem.id && (el.type || NO_TYPED_SEARCH_ITEM) === typeKey));
135
+ currentItem.id === KEYWORD_ID && setKeyword("");
116
136
  setSearchSelection(newValue);
117
137
  }
118
138
  else {
119
- setSearchSelection([...searchSelection, item]);
139
+ setSearchSelection([...searchSelection, Object.assign(Object.assign({}, item), { type: item.type || searchOnlyOneType || NO_TYPED_SEARCH_ITEM })]);
120
140
  }
121
- }, [searchSelection, setSearchSelection]);
141
+ }, [searchOnlyOneType, searchSelection, setKeyword, setSearchSelection]);
122
142
  const handleTriggerClick = useCallback(() => {
123
- setIsOpen(prevState => !prevState);
143
+ if (!document.startViewTransition) {
144
+ setIsOpen(prevState => !prevState);
145
+ return;
146
+ }
147
+ document.startViewTransition(() => {
148
+ flushSync(() => {
149
+ setIsOpen(prevState => !prevState);
150
+ });
151
+ });
124
152
  }, []);
125
- const handleModalState = useCallback(() => {
126
- onToggleView && onToggleView(!isModalOpen);
127
- setIsModalOpen(val => !val);
128
- }, [isModalOpen, onToggleView]);
153
+ const handleViewState = useCallback(() => {
154
+ onToggleView && onToggleView(!isSidePanelOpen);
155
+ setIsSidePanelOpen(val => !val);
156
+ }, [isSidePanelOpen, onToggleView]);
129
157
  const handleOpenChange = useCallback((open) => {
130
- setIsOpen(open);
158
+ if (!document.startViewTransition) {
159
+ setIsOpen(open);
160
+ return;
161
+ }
162
+ document.startViewTransition(() => {
163
+ flushSync(() => {
164
+ setIsOpen(open);
165
+ });
166
+ });
131
167
  }, []);
132
- const handleModalApply = useCallback((state) => {
168
+ const handleSidePanelApply = useCallback((state) => {
133
169
  filters.forEach((filter) => {
134
170
  const filterProps = filter.props;
135
171
  const newState = state[filterProps.id];
@@ -154,11 +190,29 @@ export const Filters = ({ className, children, isPinned, onPinChange, keyword, s
154
190
  setSearchSelection === null || setSearchSelection === void 0 ? void 0 : setSearchSelection([...newSearchSelection]);
155
191
  }
156
192
  newItemSearch && setKeyword(newItemSearch.name);
157
- setIsOpen(false);
158
- }, [setKeyword, setSearchSelection]);
193
+ handleOpenChange(false);
194
+ }, [handleOpenChange, setKeyword, setSearchSelection]);
159
195
  const handlePinChange = useCallback(() => {
160
196
  onPinChange && onPinChange(!isPinned);
161
197
  }, [onPinChange, isPinned]);
198
+ const handleSearchKeyDown = useCallback((event) => {
199
+ var _a, _b;
200
+ if (event.code === "Enter") {
201
+ isRecentSearchesMode && handleSaveRecentSearch(event.currentTarget.value);
202
+ !isOpen && handleTriggerClick();
203
+ }
204
+ if (event.code === "ArrowDown" && !isOpen) {
205
+ handleTriggerClick();
206
+ }
207
+ if (event.code === "ArrowDown" && isOpen) {
208
+ const firstItem = (_a = searchListRef.current) === null || _a === void 0 ? void 0 : _a.querySelector(FOCUSABLE_SELECTOR);
209
+ firstItem === null || firstItem === void 0 ? void 0 : firstItem.focus();
210
+ }
211
+ if (event.code === "ArrowLeft" && isOpen && event.currentTarget.value === "") {
212
+ const firstItem = (_b = selectListRef.current) === null || _b === void 0 ? void 0 : _b.querySelector(FOCUSABLE_SELECTOR);
213
+ firstItem === null || firstItem === void 0 ? void 0 : firstItem.focus();
214
+ }
215
+ }, [isOpen, isRecentSearchesMode, handleSaveRecentSearch, handleTriggerClick]);
162
216
  const getIconByType = useCallback((type) => {
163
217
  if (!type) {
164
218
  return IconFilter;
@@ -166,24 +220,32 @@ export const Filters = ({ className, children, isPinned, onPinChange, keyword, s
166
220
  const foundType = searchTypesArray.find((item) => item.id === type);
167
221
  return foundType && foundType.icon ? foundType.icon : IconFilter;
168
222
  }, [searchTypesArray]);
169
- const memoizedSelect = useMemo(() => _jsx(FiltersSelect, { id: `filtersSelect_${uniqueKey}`,
170
- // name={translate("Search by")}
171
- value: searchType, onChange: setSearchType, items: searchTypesToSelect }), [searchType, searchTypesToSelect, setSearchType, uniqueKey]);
172
- const memoizedSearch = useMemo(() => _jsx(FiltersSearch, { id: `filtersSearch_${uniqueKey}`, ref: isOpen ? searchTriggerRef : undefined, name: translate("Search page"), value: keyword, onChange: setKeyword, onSearchKeyDown: isRecentSearchesMode ? handleSaveRecentSearch : undefined, handleSearchFocus: handleSearchFocus, handleRemove: onSearchItemClick, searchSelection: searchSelection, className: "zen-filters-popup__search-with-pills" }), [uniqueKey, isOpen, translate, keyword, setKeyword, isRecentSearchesMode, handleSaveRecentSearch, handleSearchFocus, onSearchItemClick, searchSelection]);
223
+ const combinedData = useCombineData(searchTypesArray);
224
+ const memoizedSelect = useMemo(() => _jsx(FiltersSelect, { value: searchType, selectListRef: selectListRef, onChange: setSearchType, items: searchTypesToSelect }), [searchType, searchTypesToSelect, setSearchType]);
225
+ const handleSearchKeywordChange = useCallback((newKeyword) => {
226
+ setKeyword(newKeyword);
227
+ !isOpen && handleOpenChange(true);
228
+ }, [setKeyword, isOpen, handleOpenChange]);
229
+ const memoizedSearch = useMemo(() => _jsx(FiltersSearch, { id: `filtersSearch_${uniqueKey}`, ref: searchTriggerRef, name: translate("Search page"), value: keyword, onSearchKeyDown: handleSearchKeyDown, onOpenPopup: isOpen ? undefined : handleTriggerClick, onChange: handleSearchKeywordChange, handleRemove: onSearchItemClick, searchSelection: searchSelection, className: "zen-filters__search-with-pills" }), [uniqueKey, translate, keyword, handleSearchKeyDown, isOpen, handleTriggerClick, handleSearchKeywordChange, onSearchItemClick, searchSelection]);
230
+ const memoizedSearchPopup = useMemo(() => _jsx(FiltersSearch, { id: `filtersSearch_${uniqueKey}_popup`, ref: searchPopupTriggerRef, name: translate("Search page"), value: keyword, onChange: setKeyword, onSearchKeyDown: handleSearchKeyDown, handleRemove: onSearchItemClick, searchSelection: searchSelection, className: "zen-filters-popup__search-with-pills" }), [uniqueKey, translate, keyword, setKeyword, handleSearchKeyDown, onSearchItemClick, searchSelection]);
231
+ const memoizedSearchList = useMemo(() => !isOpen ? null :
232
+ _jsx(FiltersSearchList, { searchValue: keyword, searchListRef: searchListRef, searchData: combinedData, searchSelection: searchSelection, onlyOneType: searchOnlyOneType, getIconByType: getIconByType, handleSearchItemClick: onSearchItemClick, handleClearSearchSelection: onClearSearchSelection, recentSearches: isRecentSearchesMode ? recentSearches : undefined, onRemoveRecentSearchItem: isRecentSearchesMode ? onRemoveRecentSearchItem : undefined, handleRecentSearchItemClick: isRecentSearchesMode ? handleRecentSearchItemClick : undefined }), [isOpen, keyword, combinedData, searchSelection, getIconByType, onSearchItemClick, onClearSearchSelection, isRecentSearchesMode, recentSearches,
233
+ onRemoveRecentSearchItem, handleRecentSearchItemClick, searchOnlyOneType, searchListRef]);
173
234
  const allOption = useMemo(() => getAllOption(translate), [translate]);
235
+ const selectTriggerPopup = useMemo(() => _jsx(TextIconButton, { className: "zen-filters__select-trigger", iconClasses: "zen-filters__select-trigger-icon", contentClasses: "zen-filters__select-trigger-content", title: translate("Close setting conditions popup"), onClick: handleTriggerClick, icon: IconChevronTopSmall, iconPosition: "end", children: translate("Search by") }), [handleTriggerClick, translate]);
236
+ // added onMouseDown to prevent focus
174
237
  const selectTrigger = useMemo(() => {
175
238
  var _a;
176
- return _jsx(TextIconButton, { className: "zen-filters__select-trigger", iconClasses: "zen-filters__select-trigger-icon", contentClasses: "zen-filters__select-trigger-content", onClick: handleTriggerClick, icon: IconChevronDownSmall, iconPosition: "end", children: !isOpen ? selectState[0] === ALL_SELECT_OPTION_ID ? allOption.name :
177
- (_a = searchTypesArray.find((item) => item.id === selectState[0])) === null || _a === void 0 ? void 0 : _a.name : translate("Search by") });
178
- }, [handleTriggerClick, selectState, isOpen, allOption.name, translate, searchTypesArray]);
179
- const combinedData = useCombineData(searchTypesArray);
180
- const memoizedPopup = useMemo(() => _jsx(ControlledPopup, { paddingY: -28, isOpen: isOpen, className: classNames(["zen-filters-popup"]), onOpenChange: handleOpenChange, useTrapFocusWithTrigger: "withTrigger", alignment: "bottom", shouldHoldScroll: true, triggerRef: triggerRef, ariaLabel: translate("Setting conditions"), recalculateOnScroll: true, children: _jsxs("div", { className: "zen-filters-popup__content", children: [_jsxs("div", { className: "zen-filters-popup__left-panel", children: [selectTrigger, memoizedSelect] }), _jsxs("div", { className: "zen-filters-popup__right-panel", children: [memoizedSearch, _jsx(FiltersSearchList, { searchValue: keyword, searchData: combinedData, searchSelection: searchSelection, getIconByType: getIconByType, handleSearchItemClick: onSearchItemClick, recentSearches: isRecentSearchesMode ? recentSearches : undefined, onRemoveRecentSearchItem: isRecentSearchesMode ? onRemoveRecentSearchItem : undefined, handleRecentSearchItemClick: isRecentSearchesMode ? handleRecentSearchItemClick : undefined })] })] }) }), [isOpen, handleOpenChange, selectTrigger, memoizedSelect, memoizedSearch, keyword, combinedData, searchSelection, getIconByType, onSearchItemClick, isRecentSearchesMode, recentSearches, translate, onRemoveRecentSearchItem, handleRecentSearchItemClick]);
239
+ return isMobile ? null : _jsx(TextIconButton, { tabIndex: -1, onMouseDown: e => e.preventDefault(), className: "zen-filters__select-trigger", iconClasses: "zen-filters__select-trigger-icon", contentClasses: "zen-filters__select-trigger-content", title: translate("Open setting conditions popup"), onClick: handleTriggerClick, icon: IconChevronDownSmall, iconPosition: "end", children: selectState[0] === ALL_SELECT_OPTION_ID ? allOption.name :
240
+ (_a = searchTypesArray.find((item) => item.id === selectState[0])) === null || _a === void 0 ? void 0 : _a.name });
241
+ }, [translate, handleTriggerClick, selectState, allOption.name, searchTypesArray, isMobile]);
242
+ const memoizedPopup = useMemo(() => _jsx(ControlledPopup, { paddingY: -34, isOpen: isOpen, className: classNames(["zen-filters-popup"]), onOpenChange: handleOpenChange, useTrapFocusWithTrigger: "on", alignment: "bottom", shouldHoldScroll: true, triggerRef: triggerRef, ariaLabel: translate("Setting conditions"), recalculateOnScroll: true, children: _jsxs("div", { className: "zen-filters-popup__content", children: [_jsxs("div", { className: "zen-filters-popup__left-panel", children: [selectTriggerPopup, memoizedSelect] }), _jsxs("div", { className: "zen-filters-popup__right-panel", children: [memoizedSearchPopup, memoizedSearchList] })] }) }), [isOpen, handleOpenChange, translate, selectTriggerPopup, memoizedSelect, memoizedSearchPopup, memoizedSearchList]);
181
243
  const filtersForRender = useMemo(() => filters.filter(el => {
182
244
  const elProps = el.props;
183
245
  return typeof elProps.visible === "boolean" ? elProps.visible
184
246
  : elProps.visible === undefined ? false : elProps.visible(Array.from(selectState), undefined);
185
247
  }), [filters, selectState]);
186
- // The modal has a full set of filters, so we need to calculate the number of changed filters based on all filters, not just the visible ones
248
+ // The sidePanel has a full set of filters, so we need to calculate the number of changed filters based on all filters, not just the visible ones
187
249
  const filtersForCalculation = useMemo(() => {
188
250
  const stateObj = createStateObject(filters, "state");
189
251
  return filters.filter(el => {
@@ -193,9 +255,9 @@ export const Filters = ({ className, children, isPinned, onPinChange, keyword, s
193
255
  });
194
256
  }, [filters, selectState]);
195
257
  const hasSavedFilters = savedFiltersStates.size > 0;
196
- const memoizedFiltersContainer = useMemo(() => _jsx(FiltersContainer, { filtersClickHandler: handleModalState, filtersForCalculation: filtersForCalculation, isPinned: isPinMode ? isPinned : undefined, onPinChange: isPinMode ? onPinChange : undefined, hasSavedFilters: hasSavedFilters, children: filtersForRender }), [handleModalState, filtersForCalculation, isPinMode, isPinned, onPinChange, hasSavedFilters, filtersForRender]);
197
- const tabItems = useMemo(() => searchTypesArray.map((item) => ({ id: item.id, name: item.name })), [searchTypesArray]);
198
- const memoizedModal = useMemo(() => _jsx(FiltersModal, { isOpen: isModalOpen, onApply: handleModalApply, onClose: handleModalState, onPin: isPinMode ? handlePinChange : undefined, isPinned: isPinMode ? isPinned : undefined, filters: filters, tabItems: tabItems, externalModalState: allFiltersState, setExternalModalState: setAllFiltersState }), [isModalOpen, handleModalApply, handleModalState, handlePinChange, isPinned, isPinMode, filters, tabItems, allFiltersState, setAllFiltersState]);
258
+ const hasFilters = filtersForCalculation.length > 0;
259
+ const memoizedFiltersContainer = useMemo(() => hasFilters ? _jsx(FiltersContainer, { filtersChipRef: sidePanelTriggerRef, filtersClickHandler: handleViewState, filtersForCalculation: filtersForCalculation, isPinned: isPinMode ? isPinned : undefined, onPinChange: isPinMode ? onPinChange : undefined, hasSavedFilters: hasSavedFilters, children: filtersForRender }) : null, [handleViewState, filtersForCalculation, isPinMode, isPinned, onPinChange, hasSavedFilters, filtersForRender, hasFilters]);
260
+ const memoizedSidePanel = useMemo(() => _jsx(FiltersSidePanel, { isOpen: isSidePanelOpen, onApply: handleSidePanelApply, onClose: handleViewState, onPin: isPinMode ? handlePinChange : undefined, isPinned: isPinMode ? isPinned : undefined, filters: filters, externalState: allFiltersState, setExternalState: setAllFiltersState, triggerRef: sidePanelTriggerRef }), [isSidePanelOpen, handleSidePanelApply, handleViewState, handlePinChange, isPinned, isPinMode, filters, allFiltersState, setAllFiltersState, sidePanelTriggerRef]);
199
261
  const memoizedStatus = useMemo(() => isPinned && isPinMode ? "accent" : undefined, [isPinned, isPinMode]);
200
262
  const memoizedSavedFiltersItems = useMemo(() => new Set(savedFiltersStates.keys()), [savedFiltersStates]);
201
263
  const memoizedSavedFiltersActive = useMemo(() => {
@@ -237,10 +299,11 @@ export const Filters = ({ className, children, isPinned, onPinChange, keyword, s
237
299
  });
238
300
  }
239
301
  }, [filters, savedFiltersStates]);
240
- return _jsxs("div", { className: classNames(["zen-filters", className || ""]), children: [isOpen ? null : _jsxs("div", { className: "zen-filters__main-row", children: [selectTrigger, memoizedSearch] }), _jsx("div", { className: "zen-filters__trigger", ref: triggerRef, role: "button", tabIndex: 0, "aria-label": translate("Open search") }), _jsx(FiltersSavedItemsProvider, { items: memoizedSavedFiltersItems, active: memoizedSavedFiltersActive, onRemove: isSavedFiltersMode ? removeSavedFiltersState : undefined, onApply: isSavedFiltersMode ? applySavedFiltersState : undefined, onSave: isSavedFiltersMode ? handleSaveFilters : undefined, children: _jsx(ChipStatusProvider, { status: memoizedStatus, children: memoizedFiltersContainer }) }), memoizedPopup, isModalOpen ? _jsx(FiltersSavedItemsProvider, { items: memoizedSavedFiltersItems, active: memoizedSavedFiltersActive, onRemove: isSavedFiltersMode ? removeSavedFiltersState : undefined, onApply: isSavedFiltersMode ? applySavedFiltersState : undefined, onSave: isSavedFiltersMode ? handleSaveFilters : undefined, children: _jsx(ChipStatusProvider, { status: memoizedStatus, children: memoizedModal }) }) : null] });
302
+ return _jsxs("div", { className: classNames(["zen-filters", className || ""]), children: [_jsxs("div", { className: classNames(["zen-filters__main-row", isOpen ? "" : "zen-filters__main-row--initial"]), ref: triggerRef, role: "combobox", "aria-label": translate("Open setting conditions popup"), children: [selectTrigger, memoizedSearch] }), _jsx(FiltersSavedItemsProvider, { items: memoizedSavedFiltersItems, active: memoizedSavedFiltersActive, onRemove: isSavedFiltersMode ? removeSavedFiltersState : undefined, onApply: isSavedFiltersMode ? applySavedFiltersState : undefined, onSave: isSavedFiltersMode ? handleSaveFilters : undefined, children: _jsx(ChipStatusProvider, { status: memoizedStatus, children: memoizedFiltersContainer }) }), memoizedPopup, _jsx(FiltersSavedItemsProvider, { items: memoizedSavedFiltersItems, active: memoizedSavedFiltersActive, onRemove: isSavedFiltersMode ? removeSavedFiltersState : undefined, onApply: isSavedFiltersMode ? applySavedFiltersState : undefined, onSave: isSavedFiltersMode ? handleSaveFilters : undefined, children: _jsx(ChipStatusProvider, { status: memoizedStatus, children: memoizedSidePanel }) })] });
241
303
  };
242
304
  Filters.Chip = FiltersChip;
243
305
  Filters.DateRange = FiltersDateRange;
306
+ Filters.DateInput = FiltersDateInput;
244
307
  Filters.Dropdown = FiltersDropdown;
245
308
  Filters.Groups = FiltersGroups;
246
309
  Filters.Range = FiltersRange;
@@ -1,8 +1,8 @@
1
1
  import { ReactElement } from "react";
2
2
  import React from "react";
3
3
  import { TFiltersDropdownAllStates } from "./components/filtersDropdown";
4
- import { IFiltersSearchTypesItem } from "./filters";
5
- import { ISearchItem } from "./components/filtersSearchList";
4
+ import { IFiltersSearchTypesItem, ISavedFilters } from "./filters";
5
+ import { IRecentSearchItem, ISearchItem } from "./components/filtersSearchList";
6
6
  export declare const createStateHash: (state: unknown) => string;
7
7
  export declare const createPropsHash: (props: Record<string, unknown>) => string;
8
8
  export declare const stabilizeChildrenWithId: (children: React.ReactNode) => (React.ReactElement | null)[];
@@ -38,3 +38,5 @@ export declare const useCombineData: (searchTypes: IFiltersSearchTypesItem[]) =>
38
38
  error: Error | null;
39
39
  };
40
40
  export declare function getArrayOfElements<T>(elem: T | T[] | undefined): T[];
41
+ export declare function getSavedFiltersFromStorage(key: string): Promise<ISavedFilters[]>;
42
+ export declare function getRecentSearchesFromStorage(key: string): IRecentSearchItem[];
@@ -211,3 +211,40 @@ export function getArrayOfElements(elem) {
211
211
  }
212
212
  return Array.isArray(elem) ? elem : [elem];
213
213
  }
214
+ const dateReviver = (_, value) => {
215
+ const isIsoDateString = typeof value === "string" && /^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}/.test(value);
216
+ if (isIsoDateString) {
217
+ return new Date(value);
218
+ }
219
+ return value;
220
+ };
221
+ const getParsedFilters = (storageKey) => {
222
+ const storedData = localStorage.getItem(storageKey);
223
+ if (!storedData) {
224
+ return [];
225
+ }
226
+ try {
227
+ return JSON.parse(storedData, dateReviver);
228
+ }
229
+ catch (e) {
230
+ console.error(`Error parsing saved filters for key "${storageKey}"`, e);
231
+ return [];
232
+ }
233
+ };
234
+ export async function getSavedFiltersFromStorage(key) {
235
+ const result = getParsedFilters(key);
236
+ return Promise.resolve(result);
237
+ }
238
+ export function getRecentSearchesFromStorage(key) {
239
+ const storedData = localStorage.getItem(key);
240
+ if (!storedData) {
241
+ return [];
242
+ }
243
+ try {
244
+ return JSON.parse(storedData);
245
+ }
246
+ catch (e) {
247
+ console.error(`Error parsing recent searches for key "${key}"`, e);
248
+ return [];
249
+ }
250
+ }
@@ -1,6 +1,8 @@
1
1
  /// <reference types="react" />
2
2
  import { IFiltersSearchType } from "./components/filtersSelect";
3
3
  import { ISearchItem } from "./components/filtersSearchList";
4
+ import { IFetchState, IFiltersSearchTypesSubItem } from "./filters";
5
+ import { IIcon } from "../icons/icon";
4
6
  export declare const useFiltersSearch: (keywordDebounceTime?: number) => {
5
7
  keyword: string;
6
8
  setKeyword: import("react").Dispatch<import("react").SetStateAction<string>>;
@@ -13,7 +15,15 @@ export declare const usePinnedFilters: () => {
13
15
  isPinned: boolean;
14
16
  onPinChange: import("react").Dispatch<import("react").SetStateAction<boolean>>;
15
17
  };
16
- export declare const useFiltersSelection: () => {
18
+ export declare const useFiltersSelection: (setArgs?: (selection: ISearchItem[]) => void) => {
17
19
  searchSelection: ISearchItem[];
18
- setSearchSelection: import("react").Dispatch<import("react").SetStateAction<ISearchItem[]>>;
20
+ setSearchSelection: (selection: ISearchItem[]) => void;
21
+ };
22
+ export declare const useSearchData: <T>(id: string, name: string, data: IFetchState<T>, icon?: React.FC<IIcon>, subItems?: IFiltersSearchTypesSubItem[], relevance?: number) => {
23
+ id: string;
24
+ name: string;
25
+ data: IFetchState<T>;
26
+ icon: import("react").FC<IIcon> | undefined;
27
+ subItems: IFiltersSearchTypesSubItem[] | undefined;
28
+ relevance: number | undefined;
19
29
  };
@@ -13,7 +13,24 @@ export const usePinnedFilters = () => {
13
13
  const pinnedFilters = useMemo(() => ({ isPinned, onPinChange: setIsPinned }), [isPinned, setIsPinned]);
14
14
  return pinnedFilters;
15
15
  };
16
- export const useFiltersSelection = () => {
16
+ export const useFiltersSelection = (setArgs) => {
17
17
  const [searchSelection, setSearchSelection] = useState([]);
18
- return { searchSelection, setSearchSelection };
18
+ const handleSelectionChange = useCallback((selection) => {
19
+ setSearchSelection(selection);
20
+ if (setArgs) {
21
+ setArgs(selection);
22
+ }
23
+ }, [setArgs]);
24
+ return { searchSelection, setSearchSelection: handleSelectionChange };
25
+ };
26
+ export const useSearchData = (id, name, data, icon, subItems, relevance) => {
27
+ const memoizedData = useMemo(() => ({
28
+ id,
29
+ name,
30
+ data,
31
+ icon,
32
+ subItems,
33
+ relevance
34
+ }), [id, name, data, subItems, icon, relevance]);
35
+ return memoizedData;
19
36
  };