@geotab/zenith 3.6.3 → 3.7.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 (149) hide show
  1. package/README.md +15 -0
  2. package/dist/absolute/absolute.d.ts +3 -1
  3. package/dist/absolute/absolute.js +4 -4
  4. package/dist/checkbox/checkbox.d.ts +3 -1
  5. package/dist/checkbox/checkbox.js +5 -8
  6. package/dist/checkboxListWithAction/checkboxListWithAction.d.ts +3 -1
  7. package/dist/checkboxListWithAction/checkboxListWithAction.js +185 -3
  8. package/dist/controlledPopup/controlledPopup.d.ts +3 -1
  9. package/dist/controlledPopup/controlledPopup.js +2 -2
  10. package/dist/dropdown/dropdownPopup.d.ts +1 -1
  11. package/dist/dropdown/dropdownTrigger.d.ts +1 -1
  12. package/dist/dropdownRaw/dropdownList.d.ts +2 -1
  13. package/dist/dropdownRaw/dropdownList.js +15 -4
  14. package/dist/dropdownRaw/dropdownPopup.d.ts +3 -1
  15. package/dist/dropdownRaw/dropdownPopup.js +35 -5
  16. package/dist/dropdownRaw/dropdownRaw.js +82 -7
  17. package/dist/dropdownRaw/dropdownSearchableTrigger.d.ts +2 -1
  18. package/dist/dropdownRaw/dropdownSearchableTrigger.js +7 -2
  19. package/dist/dropdownRaw/dropdownTrigger.d.ts +2 -1
  20. package/dist/dropdownRaw/dropdownTrigger.js +3 -5
  21. package/dist/footerButtons/footerButtons.d.ts +6 -4
  22. package/dist/footerButtons/footerButtons.js +3 -8
  23. package/dist/groupsFilterRaw/groupsFilterCurrentlySelectedState.js +8 -2
  24. package/dist/groupsFilterRaw/groupsFilterInitialState.js +16 -0
  25. package/dist/groupsFilterRaw/groupsFilterRaw.js +43 -9
  26. package/dist/groupsFilterRaw/groupsFilterTrigger.d.ts +2 -1
  27. package/dist/groupsFilterRaw/groupsFilterTrigger.js +13 -2
  28. package/dist/index.css +222 -18
  29. package/dist/index.d.ts +1 -1
  30. package/dist/list/hooks/useDragAndDrop.d.ts +3 -1
  31. package/dist/list/hooks/useDragAndDrop.js +11 -4
  32. package/dist/menu/components/menuItem.js +12 -2
  33. package/dist/menu/contexts/pathContext.d.ts +3 -1
  34. package/dist/menu/contexts/pathProvider.d.ts +1 -1
  35. package/dist/menu/contexts/pathProvider.js +1 -1
  36. package/dist/menu/controlledMenu.js +97 -29
  37. package/dist/nav/nav.d.ts +2 -1
  38. package/dist/nav/nav.js +3 -2
  39. package/dist/nav/navEditList/navEditList.js +2 -1
  40. package/dist/nav/navItem/navItem.d.ts +1 -0
  41. package/dist/nav/navItem/navItem.js +4 -1
  42. package/dist/pillExpandable/pillContent.d.ts +2 -1
  43. package/dist/pillExpandable/pillContent.js +8 -3
  44. package/dist/pillExpandable/pillExpandable.d.ts +27 -4
  45. package/dist/pillExpandable/pillExpandable.js +426 -196
  46. package/dist/pillExpandable/pillExpandablePopoverContent.d.ts +19 -0
  47. package/dist/pillExpandable/pillExpandablePopoverContent.js +7 -0
  48. package/dist/pillExpandable/pillExpandableSimple.d.ts +5 -3
  49. package/dist/pillExpandable/pillExpandableSimple.js +12 -5
  50. package/dist/summary/summary.js +29 -1
  51. package/dist/summaryTile/summaryTile.d.ts +2 -1
  52. package/dist/summaryTile/summaryTile.js +175 -65
  53. package/dist/summaryTile/summaryTileTrigger.d.ts +1 -1
  54. package/dist/summaryTile/summaryTileTrigger.js +1 -1
  55. package/dist/toggleButtonRaw/toggleButtonRaw.js +2 -1
  56. package/dist/utils/localization/getSupportedLanguage.d.ts +2 -2
  57. package/dist/utils/localization/getSupportedLanguage.js +28 -8
  58. package/dist/utils/localization/languageContext.d.ts +1 -1
  59. package/dist/utils/localization/translations/cs.json +2 -1
  60. package/dist/utils/localization/translations/de.json +2 -1
  61. package/dist/utils/localization/translations/en.json +2 -1
  62. package/dist/utils/localization/translations/es.json +2 -1
  63. package/dist/utils/localization/translations/fr-FR.json +2 -1
  64. package/dist/utils/localization/translations/fr.json +2 -1
  65. package/dist/utils/localization/translations/id.json +2 -1
  66. package/dist/utils/localization/translations/it.json +2 -1
  67. package/dist/utils/localization/translations/ja.json +2 -1
  68. package/dist/utils/localization/translations/ms.json +2 -1
  69. package/dist/utils/localization/translations/nl.json +2 -1
  70. package/dist/utils/localization/translations/pl.json +2 -1
  71. package/dist/utils/localization/translations/pt-BR.json +2 -1
  72. package/dist/utils/localization/translations/sv.json +2 -1
  73. package/dist/utils/localization/translations/th.json +2 -1
  74. package/dist/utils/localization/translations/tr.json +2 -1
  75. package/dist/utils/localization/translations/zh-Hans.json +2 -1
  76. package/esm/absolute/absolute.d.ts +3 -1
  77. package/esm/absolute/absolute.js +4 -4
  78. package/esm/checkbox/checkbox.d.ts +3 -1
  79. package/esm/checkbox/checkbox.js +5 -8
  80. package/esm/checkboxListWithAction/checkboxListWithAction.d.ts +3 -1
  81. package/esm/checkboxListWithAction/checkboxListWithAction.js +186 -4
  82. package/esm/controlledPopup/controlledPopup.d.ts +3 -1
  83. package/esm/controlledPopup/controlledPopup.js +2 -2
  84. package/esm/dropdown/dropdownPopup.d.ts +1 -1
  85. package/esm/dropdown/dropdownTrigger.d.ts +1 -1
  86. package/esm/dropdownRaw/dropdownList.d.ts +2 -1
  87. package/esm/dropdownRaw/dropdownList.js +16 -5
  88. package/esm/dropdownRaw/dropdownPopup.d.ts +3 -1
  89. package/esm/dropdownRaw/dropdownPopup.js +37 -7
  90. package/esm/dropdownRaw/dropdownRaw.js +82 -7
  91. package/esm/dropdownRaw/dropdownSearchableTrigger.d.ts +2 -1
  92. package/esm/dropdownRaw/dropdownSearchableTrigger.js +7 -2
  93. package/esm/dropdownRaw/dropdownTrigger.d.ts +2 -1
  94. package/esm/dropdownRaw/dropdownTrigger.js +3 -5
  95. package/esm/footerButtons/footerButtons.d.ts +6 -4
  96. package/esm/footerButtons/footerButtons.js +3 -8
  97. package/esm/groupsFilterRaw/groupsFilterCurrentlySelectedState.js +9 -3
  98. package/esm/groupsFilterRaw/groupsFilterInitialState.js +16 -0
  99. package/esm/groupsFilterRaw/groupsFilterRaw.js +43 -9
  100. package/esm/groupsFilterRaw/groupsFilterTrigger.d.ts +2 -1
  101. package/esm/groupsFilterRaw/groupsFilterTrigger.js +13 -2
  102. package/esm/index.d.ts +1 -1
  103. package/esm/list/hooks/useDragAndDrop.d.ts +3 -1
  104. package/esm/list/hooks/useDragAndDrop.js +11 -4
  105. package/esm/menu/components/menuItem.js +12 -2
  106. package/esm/menu/contexts/pathContext.d.ts +3 -1
  107. package/esm/menu/contexts/pathProvider.d.ts +1 -1
  108. package/esm/menu/contexts/pathProvider.js +1 -1
  109. package/esm/menu/controlledMenu.js +98 -30
  110. package/esm/nav/nav.d.ts +2 -1
  111. package/esm/nav/nav.js +3 -2
  112. package/esm/nav/navEditList/navEditList.js +2 -1
  113. package/esm/nav/navItem/navItem.d.ts +1 -0
  114. package/esm/nav/navItem/navItem.js +5 -2
  115. package/esm/pillExpandable/pillContent.d.ts +2 -1
  116. package/esm/pillExpandable/pillContent.js +8 -3
  117. package/esm/pillExpandable/pillExpandable.d.ts +27 -4
  118. package/esm/pillExpandable/pillExpandable.js +427 -197
  119. package/esm/pillExpandable/pillExpandablePopoverContent.d.ts +19 -0
  120. package/esm/pillExpandable/pillExpandablePopoverContent.js +3 -0
  121. package/esm/pillExpandable/pillExpandableSimple.d.ts +5 -3
  122. package/esm/pillExpandable/pillExpandableSimple.js +12 -5
  123. package/esm/summary/summary.js +29 -1
  124. package/esm/summaryTile/summaryTile.d.ts +2 -1
  125. package/esm/summaryTile/summaryTile.js +140 -43
  126. package/esm/summaryTile/summaryTileTrigger.d.ts +1 -1
  127. package/esm/summaryTile/summaryTileTrigger.js +1 -1
  128. package/esm/toggleButtonRaw/toggleButtonRaw.js +2 -1
  129. package/esm/utils/localization/getSupportedLanguage.d.ts +2 -2
  130. package/esm/utils/localization/getSupportedLanguage.js +28 -8
  131. package/esm/utils/localization/languageContext.d.ts +1 -1
  132. package/esm/utils/localization/translations/cs.json +2 -1
  133. package/esm/utils/localization/translations/de.json +2 -1
  134. package/esm/utils/localization/translations/en.json +2 -1
  135. package/esm/utils/localization/translations/es.json +2 -1
  136. package/esm/utils/localization/translations/fr-FR.json +2 -1
  137. package/esm/utils/localization/translations/fr.json +2 -1
  138. package/esm/utils/localization/translations/id.json +2 -1
  139. package/esm/utils/localization/translations/it.json +2 -1
  140. package/esm/utils/localization/translations/ja.json +2 -1
  141. package/esm/utils/localization/translations/ms.json +2 -1
  142. package/esm/utils/localization/translations/nl.json +2 -1
  143. package/esm/utils/localization/translations/pl.json +2 -1
  144. package/esm/utils/localization/translations/pt-BR.json +2 -1
  145. package/esm/utils/localization/translations/sv.json +2 -1
  146. package/esm/utils/localization/translations/th.json +2 -1
  147. package/esm/utils/localization/translations/tr.json +2 -1
  148. package/esm/utils/localization/translations/zh-Hans.json +2 -1
  149. package/package.json +4 -7
@@ -28,6 +28,8 @@ import { useFormFieldValues } from "../commonHelpers/hooks/useFormFieldValues/us
28
28
  import { FormSectionContext } from "../formSection/utils/formSectionProvider";
29
29
  import { LIST_LIMIT } from "../dropdown/dropdown";
30
30
  import { zen } from "../utils/zen";
31
+ import { isChildOf } from "../utils/isChildOf";
32
+ import { getFirstFocusableItem } from "../utils/keyboardHelpers";
31
33
  injectString("cs", "Filter by group", "Filtrovat podle skupiny");
32
34
  injectString("da-DK", "Filter by group", "Filtrer efter gruppe");
33
35
  injectString("de", "Filter by group", "Nach Gruppe filtern");
@@ -134,6 +136,8 @@ export const DropdownRaw = props => {
134
136
  const popupId = useId();
135
137
  const abortToken = useRef(new AbortController());
136
138
  const triggerRef = useRef(null);
139
+ const listElementRef = useRef(null);
140
+ const nextFocusableItemRef = useRef(false);
137
141
  const comboboxRef = useRef(null);
138
142
  const inputRef = useRef(null);
139
143
  const contentRef = useRef(null);
@@ -301,6 +305,9 @@ export const DropdownRaw = props => {
301
305
  type: StateActionType.SetCurrentId,
302
306
  payload: newCurrentId === state.rootId || state.inputValue ? undefined : newCurrentId
303
307
  });
308
+ // const focusableElements = contentRef.current?.querySelectorAll<HTMLElement>(FOCUSABLE_SELECTOR);
309
+ // focusableElements?.[0]?.focus();
310
+ nextFocusableItemRef.current = state.currentId ? `button[data-btn='${state.currentId}']` : true;
304
311
  }, [state.currentId, state.groupsMap, state.inputValue, state.rootId]);
305
312
  const handleSelect = useCallback(val => {
306
313
  if (isFullSelectionMode && state.isAllSelected) {
@@ -400,11 +407,14 @@ export const DropdownRaw = props => {
400
407
  });
401
408
  }, [isFullSelectionMode, state.isAllSelected, state.listData, state.isNestedList, state.selectedIds]);
402
409
  const handleClearClick = useCallback(() => {
410
+ var _a, _b;
403
411
  dispatchState({
404
412
  type: StateActionType.ResetSelection,
405
413
  payload: undefined
406
414
  });
407
- }, []);
415
+ const focusableElements = (_a = contentRef.current) === null || _a === void 0 ? void 0 : _a.querySelectorAll(FOCUSABLE_SELECTOR);
416
+ (_b = focusableElements === null || focusableElements === void 0 ? void 0 : focusableElements[0]) === null || _b === void 0 ? void 0 : _b.focus();
417
+ }, [contentRef]);
408
418
  const handleCancelClick = useCallback(() => {
409
419
  dispatchState({
410
420
  type: StateActionType.ResetStateToGlobal,
@@ -664,6 +674,7 @@ export const DropdownRaw = props => {
664
674
  payload: isChecked
665
675
  });
666
676
  prevIsChecked.current = isChecked;
677
+ nextFocusableItemRef.current = `.zen-dropdown-list__checkbox-container input`;
667
678
  const currentAbort = abortToken.current;
668
679
  controlData(currentAbort.signal, state.inputValue, isChecked);
669
680
  }, [controlData, state.inputValue]);
@@ -700,18 +711,27 @@ export const DropdownRaw = props => {
700
711
  }
701
712
  }, [searchField, state.currentId, state.showList, contentRef]);
702
713
  useEffect(() => {
703
- var _a;
714
+ var _a, _b;
704
715
  if (!state.isOpenCombo || !state.showList) {
705
716
  return;
706
717
  }
707
- const firstFocusable = (_a = contentRef.current) === null || _a === void 0 ? void 0 : _a.querySelector(FOCUSABLE_SELECTOR);
708
- if (firstFocusable && (state.currentId || !searchField)) {
718
+ if (nextFocusableItemRef.current && typeof nextFocusableItemRef.current === "string") {
719
+ const nextFocusable = (_a = contentRef.current) === null || _a === void 0 ? void 0 : _a.querySelector(nextFocusableItemRef.current);
720
+ if (nextFocusable) {
721
+ nextFocusable.focus();
722
+ nextFocusableItemRef.current = false;
723
+ return;
724
+ }
725
+ }
726
+ const firstFocusable = (_b = contentRef.current) === null || _b === void 0 ? void 0 : _b.querySelector(FOCUSABLE_SELECTOR);
727
+ if (firstFocusable && (!searchField || state.currentId || nextFocusableItemRef.current)) {
728
+ nextFocusableItemRef.current = false;
709
729
  firstFocusable.focus();
710
730
  } else {
711
731
  // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition
712
732
  (inputRef === null || inputRef === void 0 ? void 0 : inputRef.current) && inputRef.current.focus();
713
733
  }
714
- }, [state.isOpenCombo, state.currentId, state.showList, searchField]);
734
+ }, [state.isOpenCombo, state.currentId, state.showList, searchField, contentRef]);
715
735
  useEffect(() => {
716
736
  const shouldExit = !getNamedItems || Object.keys(state.groupsMap).length === 0 && Object.keys(state.groupsMapSelected).length === 0 || getNamedItemsHasBeenCalled.current || state.groupsMapSelected.size === 0;
717
737
  if (shouldExit) {
@@ -743,6 +763,57 @@ export const DropdownRaw = props => {
743
763
  return currentAllSelected !== undefined ? state.defaultValueIsAllSelected === currentAllSelected && isStringsTheSame && isCheckedEqualDefault : isStringsTheSame && isCheckedEqualDefault;
744
764
  }, [currentAllSelected, currentIsChecked, forceSelection, multiselect, state.defaultValue, state.defaultValueIsAllSelected, state.defaultValueIsChecked, state.selectedIds]);
745
765
  const memoizedIsApplyButtonDisabled = useMemo(() => compareStringsArrays(state.globalSelectedIds, state.selectedIds) && (isFullSelectionMode ? state.globalIsAllSelected === state.isAllSelected : true) && (isCheckboxMode ? state.globalIsChecked === state.isChecked : true), [isCheckboxMode, isFullSelectionMode, state.globalIsAllSelected, state.globalIsChecked, state.globalSelectedIds, state.isAllSelected, state.isChecked, state.selectedIds]);
766
+ const handleKeydown = useCallback(e => {
767
+ const isChildOfListElements = listElementRef.current && e.target instanceof Node ? isChildOf(e.target, listElementRef.current) : false;
768
+ if (isChildOfListElements) {
769
+ return;
770
+ }
771
+ if (e.key === "ArrowDown" || e.key === "ArrowUp") {
772
+ if (!contentRef.current) {
773
+ return;
774
+ }
775
+ const focusableElements = contentRef.current.querySelectorAll(FOCUSABLE_SELECTOR);
776
+ if (focusableElements.length === 0) {
777
+ return;
778
+ }
779
+ const currentIndex = Array.from(focusableElements).indexOf(e.target);
780
+ let nextIndex;
781
+ // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition
782
+ if (currentIndex === 0 && e.key === "ArrowUp" && inputRef.current) {
783
+ inputRef.current.focus();
784
+ return;
785
+ }
786
+ if (e.key === "ArrowDown") {
787
+ e.preventDefault();
788
+ nextIndex = currentIndex === -1 ? 0 : (currentIndex + 1) % focusableElements.length;
789
+ } else {
790
+ e.preventDefault();
791
+ nextIndex = currentIndex === -1 ? focusableElements.length - 1 : (currentIndex - 1 + focusableElements.length) % focusableElements.length;
792
+ }
793
+ focusableElements[nextIndex].focus();
794
+ }
795
+ }, []);
796
+ const handleFocusOnSentinelItem = useCallback(() => {
797
+ var _a;
798
+ if (isMobile) {
799
+ return;
800
+ }
801
+ const firstFocusable = getFirstFocusableItem(contentRef.current);
802
+ if (firstFocusable && listElementRef.current && isChildOf(firstFocusable, listElementRef.current)) {
803
+ // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition
804
+ (_a = inputRef.current) === null || _a === void 0 ? void 0 : _a.focus();
805
+ } else {
806
+ firstFocusable === null || firstFocusable === void 0 ? void 0 : firstFocusable.focus();
807
+ }
808
+ }, [contentRef, isMobile, listElementRef]);
809
+ const handleFocusOnPopup = useCallback(() => {
810
+ var _a;
811
+ if (!state.showList) {
812
+ return;
813
+ }
814
+ const firstFocusable = (_a = contentRef.current) === null || _a === void 0 ? void 0 : _a.querySelector(FOCUSABLE_SELECTOR);
815
+ firstFocusable === null || firstFocusable === void 0 ? void 0 : firstFocusable.focus();
816
+ }, [state.showList, contentRef]);
746
817
  const countSelected = useMemo(() => {
747
818
  var _a, _b;
748
819
  if (hasApplyButton && state.globalIsAllSelected || !hasApplyButton && state.isAllSelected) {
@@ -812,7 +883,8 @@ export const DropdownRaw = props => {
812
883
  isMobile: isMobile,
813
884
  handleCheckboxChange: isCheckboxMode && !isMobile ? handleCheckboxChange : undefined,
814
885
  checkboxLabel: checkboxLabel,
815
- isChecked: state.isChecked
886
+ isChecked: state.isChecked,
887
+ listElementRef: listElementRef
816
888
  });
817
889
  }
818
890
  return null;
@@ -862,7 +934,8 @@ export const DropdownRaw = props => {
862
934
  triggerRef: triggerRef,
863
935
  inputRef: inputRef,
864
936
  buttonType: buttonType,
865
- popupId: popupId
937
+ popupId: popupId,
938
+ handleFocusOnPopup: handleFocusOnPopup
866
939
  }, accessibilityProps)), _jsx(DropdownPopup, {
867
940
  alignment: alignment,
868
941
  triggerRef: triggerRef,
@@ -885,6 +958,7 @@ export const DropdownRaw = props => {
885
958
  handleClearClick: multiselect ? handleClearClick : handleSingleSelection.bind(this, true),
886
959
  handleTriggerClick: handleTriggerClick,
887
960
  onInputChange: onInputChange,
961
+ handleKeydown: handleKeydown,
888
962
  inputRef: inputRef,
889
963
  contentRef: contentRef,
890
964
  onReadyForFocus: handleReadyForFocus,
@@ -893,6 +967,7 @@ export const DropdownRaw = props => {
893
967
  isChecked: state.isChecked,
894
968
  isSearchInPopup: chip,
895
969
  mobileSheetStackingClassName: mobileSheetStackingClassName,
970
+ handleFocusOnSentinelItem: handleFocusOnSentinelItem,
896
971
  children: getPopupContent
897
972
  })]
898
973
  });
@@ -20,9 +20,10 @@ interface IDropdownSearchableTrigger {
20
20
  name?: string;
21
21
  onBlur?: () => void;
22
22
  popupId?: string;
23
+ handleFocusOnPopup?: () => void;
23
24
  }
24
25
  export declare const DropdownSearchableTrigger: {
25
- ({ value, className, onChange, placeholder, isOpenPopup, inputRef, handleClick, width, title, id, disabled, count, currentSelection, isError, fullWidth, ref, name, onBlur, popupId, ...otherProps }: IDropdownSearchableTrigger): import("react/jsx-runtime").JSX.Element;
26
+ ({ value, className, onChange, placeholder, isOpenPopup, inputRef, handleClick, width, title, id, disabled, count, currentSelection, isError, fullWidth, ref, name, onBlur, popupId, handleFocusOnPopup, ...otherProps }: IDropdownSearchableTrigger): import("react/jsx-runtime").JSX.Element;
26
27
  displayName: string;
27
28
  };
28
29
  export declare const TRANSLATIONS: string[];
@@ -141,9 +141,10 @@ export const DropdownSearchableTrigger = _a => {
141
141
  ref,
142
142
  name,
143
143
  onBlur,
144
- popupId
144
+ popupId,
145
+ handleFocusOnPopup
145
146
  } = _a,
146
- otherProps = __rest(_a, ["value", "className", "onChange", "placeholder", "isOpenPopup", "inputRef", "handleClick", "width", "title", "id", "disabled", "count", "currentSelection", "isError", "fullWidth", "ref", "name", "onBlur", "popupId"])
147
+ otherProps = __rest(_a, ["value", "className", "onChange", "placeholder", "isOpenPopup", "inputRef", "handleClick", "width", "title", "id", "disabled", "count", "currentSelection", "isError", "fullWidth", "ref", "name", "onBlur", "popupId", "handleFocusOnPopup"])
147
148
  // eslint-disable-next-line complexity
148
149
  ;
149
150
  const {
@@ -176,6 +177,10 @@ export const DropdownSearchableTrigger = _a => {
176
177
  if (e.key === " " && !isOpenPopup) {
177
178
  handleClick(true);
178
179
  }
180
+ if (e.key === "ArrowDown" && isOpenPopup) {
181
+ e.preventDefault();
182
+ handleFocusOnPopup === null || handleFocusOnPopup === void 0 ? void 0 : handleFocusOnPopup();
183
+ }
179
184
  };
180
185
  const clickHandler = e => {
181
186
  if (e.target === inputRef.current && isOpenPopup || e.target === clearRef.current && isOpenPopup) {
@@ -23,6 +23,7 @@ export interface IDropdownTrigger extends IZenComponentProps {
23
23
  name?: string;
24
24
  onBlur?: () => void;
25
25
  popupId?: string;
26
+ handleFocusOnPopup?: () => void;
26
27
  }
27
- export declare const DropdownTrigger: ({ name, onBlur, isActive, id, triggerRef, searchField, placeholder, disabled, fullWidth, currentSelection, handleClick, inputValue, className, onSearchChange, width, title, triggerAriaLabel, count, inputRef, buttonType, isError, popupId, ...otherProps }: IDropdownTrigger) => import("react/jsx-runtime").JSX.Element;
28
+ export declare const DropdownTrigger: ({ name, onBlur, isActive, id, triggerRef, searchField, placeholder, disabled, fullWidth, currentSelection, handleClick, inputValue, className, onSearchChange, width, title, triggerAriaLabel, count, inputRef, buttonType, isError, popupId, handleFocusOnPopup, ...otherProps }: IDropdownTrigger) => import("react/jsx-runtime").JSX.Element;
28
29
  export declare const TRANSLATIONS: string[];
@@ -15,13 +15,11 @@ import { FilterButton } from "../filterButton/filterButton";
15
15
  import { useRef } from "react";
16
16
  import { classNames } from "../commonHelpers/classNames/classNames";
17
17
  export const DropdownTrigger = (_a) => {
18
- var { name, onBlur, isActive, id, triggerRef, searchField, placeholder, disabled, fullWidth, currentSelection, handleClick, inputValue, className, onSearchChange = () => { }, width, title, triggerAriaLabel, count, inputRef, buttonType, isError, popupId } = _a, otherProps = __rest(_a, ["name", "onBlur", "isActive", "id", "triggerRef", "searchField", "placeholder", "disabled", "fullWidth", "currentSelection", "handleClick", "inputValue", "className", "onSearchChange", "width", "title", "triggerAriaLabel", "count", "inputRef", "buttonType", "isError", "popupId"]);
18
+ var { name, onBlur, isActive, id, triggerRef, searchField, placeholder, disabled, fullWidth, currentSelection, handleClick, inputValue, className, onSearchChange = () => { }, width, title, triggerAriaLabel, count, inputRef, buttonType, isError, popupId, handleFocusOnPopup } = _a, otherProps = __rest(_a, ["name", "onBlur", "isActive", "id", "triggerRef", "searchField", "placeholder", "disabled", "fullWidth", "currentSelection", "handleClick", "inputValue", "className", "onSearchChange", "width", "title", "triggerAriaLabel", "count", "inputRef", "buttonType", "isError", "popupId", "handleFocusOnPopup"]);
19
19
  const elInpRef = useRef(null);
20
20
  const handleButtonClick = () => {
21
21
  handleClick(!isActive);
22
22
  };
23
- return _jsx(_Fragment, { children: searchField ? _jsx(DropdownSearchableTrigger, Object.assign({ value: inputValue || "", name: name, onChange: onSearchChange, isOpenPopup: isActive, inputRef: inputRef || elInpRef, handleClick: handleClick, ref: triggerRef, width: width, placeholder: placeholder, disabled: disabled, id: id, title: title, count: count, currentSelection: currentSelection, className: className, isError: isError, fullWidth: fullWidth, popupId: popupId }, otherProps)) : _jsx(FilterButton, Object.assign({ ref: triggerRef, id: id, name: name, onBlur: onBlur, className: classNames(["zen-dropdown__trigger-button", isError ? "zen-dropdown__trigger-button--error" : "", className || ""]), onClick: handleButtonClick, disabled: disabled, isActive: isActive, fullWidth: width ? true : fullWidth, maxWidth: width, minWidth: width, quantity: count || undefined, type: buttonType, title: title, ariaLabel: triggerAriaLabel || placeholder, "aria-expanded": isActive, "aria-haspopup": "dialog", "data-role": "dialog", "aria-controls": popupId }, otherProps, { children: currentSelection ? _jsx("span", { className: classNames(["zen-dropdown__trigger-button-text", buttonType ? `zen-dropdown__trigger-button-text--${buttonType.toString()}` : ""]), children: currentSelection }) : placeholder })) });
23
+ return (_jsx(_Fragment, { children: searchField ? (_jsx(DropdownSearchableTrigger, Object.assign({ value: inputValue || "", name: name, onChange: onSearchChange, isOpenPopup: isActive, inputRef: inputRef || elInpRef, handleClick: handleClick, handleFocusOnPopup: handleFocusOnPopup, ref: triggerRef, width: width, placeholder: placeholder, disabled: disabled, id: id, title: title, count: count, currentSelection: currentSelection, className: className, isError: isError, fullWidth: fullWidth, popupId: popupId }, otherProps))) : (_jsx(FilterButton, Object.assign({ ref: triggerRef, id: id, name: name, onBlur: onBlur, className: classNames(["zen-dropdown__trigger-button", isError ? "zen-dropdown__trigger-button--error" : "", className || ""]), onClick: handleButtonClick, disabled: disabled, isActive: isActive, fullWidth: width ? true : fullWidth, maxWidth: width, minWidth: width, quantity: count || undefined, type: buttonType, title: title, ariaLabel: triggerAriaLabel || placeholder, "aria-expanded": isActive, "aria-haspopup": "dialog", "data-role": "dialog", "aria-controls": popupId }, otherProps, { children: currentSelection ? (_jsx("span", { className: classNames(["zen-dropdown__trigger-button-text", buttonType ? `zen-dropdown__trigger-button-text--${buttonType.toString()}` : ""]), children: currentSelection })) : (placeholder) }))) }));
24
24
  };
25
- export const TRANSLATIONS = [
26
- ...SearchableTriggerTranslations
27
- ];
25
+ export const TRANSLATIONS = [...SearchableTriggerTranslations];
@@ -1,3 +1,4 @@
1
+ import React from "react";
1
2
  import { IZenComponentProps } from "./../commonHelpers/zenComponent";
2
3
  import { ReactElement } from "react";
3
4
  import { IButton } from "../button/button";
@@ -5,10 +6,11 @@ import "./footerButtons.less";
5
6
  export interface IFooterButtons extends IZenComponentProps {
6
7
  children: ReactElement<IButton> | (ReactElement<IButton> | null | undefined)[];
7
8
  /**
8
- * @deprecated
9
- * @param stacked - will be removed in the next major release
10
- */
9
+ * @deprecated
10
+ * @param stacked - will be removed in the next major release
11
+ */
11
12
  stacked?: boolean;
12
13
  isSticky?: boolean;
14
+ ref?: React.Ref<HTMLDivElement>;
13
15
  }
14
- export declare const FooterButtons: ({ className, children, isSticky }: IFooterButtons) => import("react/jsx-runtime").JSX.Element;
16
+ export declare const FooterButtons: ({ className, children, isSticky, ref }: IFooterButtons) => import("react/jsx-runtime").JSX.Element;
@@ -9,7 +9,7 @@ const getChildren = (children) => {
9
9
  }
10
10
  return (React.Children.count(children) === 1 ? [children] : React.Children.toArray(children).filter((child) => React.isValidElement(child)));
11
11
  };
12
- export const FooterButtons = ({ className, children, isSticky = false }) => {
12
+ export const FooterButtons = ({ className, children, isSticky = false, ref }) => {
13
13
  const footerButtonsId = useUniqueId();
14
14
  const driveComponentClassName = useDriveClassName("zen-footer-buttons");
15
15
  const maxLength = 3;
@@ -28,11 +28,6 @@ export const FooterButtons = ({ className, children, isSticky = false }) => {
28
28
  });
29
29
  return clonedElements;
30
30
  }, [children, footerButtonsId]);
31
- const containerClassNames = classNames([
32
- "zen-footer-buttons",
33
- isSticky && driveComponentClassName ? "zen-footer-buttons--sticky" : "",
34
- driveComponentClassName || "",
35
- className || ""
36
- ]);
37
- return _jsx("div", { className: containerClassNames, children: childrenArray });
31
+ const containerClassNames = classNames(["zen-footer-buttons", isSticky && driveComponentClassName ? "zen-footer-buttons--sticky" : "", driveComponentClassName || "", className || ""]);
32
+ return (_jsx("div", { className: containerClassNames, ref: ref, children: childrenArray }));
38
33
  };
@@ -1,6 +1,6 @@
1
1
  import { injectString } from "../utils/localization/translationsDictionary";
2
2
  import { jsx as _jsx, Fragment as _Fragment, jsxs as _jsxs } from "react/jsx-runtime";
3
- import { createElement, useId } from "react";
3
+ import { createElement, useCallback, useId } from "react";
4
4
  import { GroupsFilterCurrentlySelectedLabel } from "./groupsFilterCommon";
5
5
  import { RelationOperator } from "./groupsFilterInterfaces";
6
6
  import { TwoOptionsSwitcher } from "../twoOptionsSwitcher/twoOptionsSwitcher";
@@ -126,9 +126,15 @@ export const GroupsFilterCurrentlySelectedState = ({
126
126
  translate
127
127
  } = useLanguage();
128
128
  const togglerId = useId();
129
- const getActionButton = (label, title, icon, handleClick) => _jsx("button", {
129
+ const handleBackButtonKeyDown = useCallback(event => {
130
+ if (event.key === "ArrowLeft") {
131
+ onBackButtonClick();
132
+ }
133
+ }, [onBackButtonClick]);
134
+ const getActionButton = (label, title, icon, handleClick, handleKeyDown) => _jsx("button", {
130
135
  type: "button",
131
136
  onClick: handleClick,
137
+ onKeyDown: handleKeyDown,
132
138
  className: "zen-groups-filter-menu__item zen-groups-filter-menu__item--interactive zen-groups-filter-menu__action-button zen-groups-filter-menu__action-button-back",
133
139
  title: title,
134
140
  children: _jsxs(_Fragment, {
@@ -148,7 +154,7 @@ export const GroupsFilterCurrentlySelectedState = ({
148
154
  };
149
155
  return _jsxs("div", {
150
156
  className: "zen-groups-filter-menu__content-selected",
151
- children: [getActionButton(translate("Back"), translate("Back"), IconBackArrow, onBackButtonClick), _jsx("div", {
157
+ children: [getActionButton(translate("Back"), translate("Back"), IconBackArrow, onBackButtonClick, handleBackButtonKeyDown), _jsx("div", {
152
158
  className: "zen-groups-filter-menu__item-wrapper",
153
159
  children: _jsx(ToggleButtonRaw, {
154
160
  onChange: handleTogglerChange,
@@ -190,14 +190,30 @@ injectString("tr", "Select Filters:", "Se\xE7ili Filtreler:");
190
190
  injectString("zh-Hans", "Select Filters:", "\u9009\u4E2D\u7684\u7B5B\u9009\u5668\uFF1A");
191
191
  injectString("zh-TW", "Select Filters:", "\u9078\u64C7\u7BE9\u9078\u689D\u4EF6\uFF1A");
192
192
  injectString("ro-RO", "Select Filters:", "Selecta\u021Bi filtrele:");
193
+ injectString("cs", "Results", "V\xFDsledky");
193
194
  injectString("da-DK", "Results", "Resultater");
195
+ injectString("de", "Results", "Ergebnisse");
194
196
  injectString("en", "Results", "Results");
197
+ injectString("es", "Results", "Resultados");
195
198
  injectString("fi-FI", "Results", "Tulokset");
199
+ injectString("fr", "Results", "R\xE9sultats");
200
+ injectString("fr-FR", "Results", "R\xE9sultats");
196
201
  injectString("hu-HU", "Results", "Eredm\xE9nyek");
202
+ injectString("id", "Results", "Hasil");
203
+ injectString("it", "Results", "Risultati");
204
+ injectString("ja", "Results", "\u7D50\u679C");
197
205
  injectString("ko-KR", "Results", "\uACB0\uACFC");
206
+ injectString("ms", "Results", "Keputusan");
198
207
  injectString("nb-NO", "Results", "Resultater");
208
+ injectString("nl", "Results", "Resultaten");
209
+ injectString("pl", "Results", "Wyniki");
210
+ injectString("pt-BR", "Results", "Resultados");
199
211
  injectString("pt-PT", "Results", "Resultados");
200
212
  injectString("sk-SK", "Results", "V\xFDsledky");
213
+ injectString("sv", "Results", "Resultat");
214
+ injectString("th", "Results", "\u0E1C\u0E25\u0E25\u0E31\u0E1E\u0E18\u0E4C");
215
+ injectString("tr", "Results", "Sonu\xE7lar");
216
+ injectString("zh-Hans", "Results", "\u7ED3\u679C");
201
217
  injectString("zh-TW", "Results", "\u7D50\u679C");
202
218
  injectString("ro-RO", "Results", "Rezultate");
203
219
  export const GroupsFilterInitialState = ({
@@ -290,6 +290,7 @@ export const GroupsFilterRaw = props => {
290
290
  const inputRef = useRef(null);
291
291
  const emptyInputRef = useRef(null);
292
292
  const triggerRef = useRef(null);
293
+ const nextFocusableItemRef = useRef(false);
293
294
  const menuRef = useRef(null);
294
295
  const prevInitialState = useRef(initialFilterStateInner);
295
296
  const prevSearchField = useRef("");
@@ -312,6 +313,7 @@ export const GroupsFilterRaw = props => {
312
313
  type: UiStateActionType.SetStep,
313
314
  payload: newStep
314
315
  });
316
+ nextFocusableItemRef.current = true;
315
317
  if (((_a = inputRef.current) === null || _a === void 0 ? void 0 : _a.value) && newStep !== FilterMenuStep.Initial) {
316
318
  inputRef.current.value = "";
317
319
  dispatchUiState({
@@ -453,6 +455,7 @@ export const GroupsFilterRaw = props => {
453
455
  payload: id
454
456
  });
455
457
  handleSetStep(id ? FilterMenuStep.Adjustment : FilterMenuStep.Initial);
458
+ nextFocusableItemRef.current = true;
456
459
  }, [dispatchUiState, handleSetStep]);
457
460
  const handleCheckboxItemAdjustmentClick = useCallback(value => {
458
461
  if (value.id === ADVANCED_FILTER_ID) {
@@ -485,6 +488,7 @@ export const GroupsFilterRaw = props => {
485
488
  }, [dispatchState, dispatchUiState, state.advancedFilterState, state.frozenState.advancedFilterState, uiState.uncheckedAdvancedState, uiState.uncheckedAdjustmentIds]);
486
489
  const basicHandleBackButtonClick = useCallback(() => {
487
490
  handleSetStep(FilterMenuStep.Initial);
491
+ nextFocusableItemRef.current = "button.zen-groups-filter-menu__currently-selected-button";
488
492
  }, [handleSetStep]);
489
493
  const handleBackButtonClick = useCallback(() => {
490
494
  const currentEl = uiState.currentAdjustmentId ? getGroupsTreeItem(state, uiState.currentAdjustmentId) : undefined;
@@ -498,6 +502,11 @@ export const GroupsFilterRaw = props => {
498
502
  payload: isNotRoot ? currentEl.parent.id : undefined
499
503
  });
500
504
  handleSetStep(isNotRoot ? FilterMenuStep.Adjustment : FilterMenuStep.Initial);
505
+ if (!isNotRoot) {
506
+ nextFocusableItemRef.current = `button[data-btn=${uiState.currentAdjustmentId}]`;
507
+ return;
508
+ }
509
+ nextFocusableItemRef.current = true;
501
510
  }, [basicHandleBackButtonClick, handleSetStep, state, uiState.currentAdjustmentId]);
502
511
  const handleHomeButtonClick = useCallback(() => {
503
512
  handleSetStep(FilterMenuStep.Initial);
@@ -505,6 +514,7 @@ export const GroupsFilterRaw = props => {
505
514
  type: UiStateActionType.SetCurrentAdjustmentId,
506
515
  payload: undefined
507
516
  });
517
+ nextFocusableItemRef.current = true;
508
518
  }, [handleSetStep, uiState.currentAdjustmentId, dispatchUiState]);
509
519
  const handleCurrentlySelectedClick = useCallback(() => {
510
520
  handleSetStep(FilterMenuStep.CurrentlySelected);
@@ -706,6 +716,23 @@ export const GroupsFilterRaw = props => {
706
716
  }
707
717
  (_c = inputRef.current) === null || _c === void 0 ? void 0 : _c.focus();
708
718
  }, [inputRef]);
719
+ const handleFocusOnPopup = useCallback(() => {
720
+ var _a;
721
+ const firstFocusable = (_a = menuRef.current) === null || _a === void 0 ? void 0 : _a.querySelector(FOCUSABLE_SELECTOR);
722
+ firstFocusable === null || firstFocusable === void 0 ? void 0 : firstFocusable.focus();
723
+ }, [menuRef]);
724
+ useEffect(() => {
725
+ var _a, _b, _c;
726
+ if (nextFocusableItemRef.current) {
727
+ const firstFocusable = chip || isMobile ? (_a = menuRef.current) === null || _a === void 0 ? void 0 : _a.querySelectorAll(FOCUSABLE_SELECTOR)[1] : (_b = menuRef.current) === null || _b === void 0 ? void 0 : _b.querySelector(FOCUSABLE_SELECTOR);
728
+ const nextFocusable = typeof nextFocusableItemRef.current === "string" ? (_c = menuRef.current) === null || _c === void 0 ? void 0 : _c.querySelector(nextFocusableItemRef.current) : firstFocusable;
729
+ if (nextFocusable) {
730
+ nextFocusable.focus();
731
+ nextFocusableItemRef.current = false;
732
+ return;
733
+ }
734
+ }
735
+ }, [uiState.currentAdjustmentId, chip, menuRef, nextFocusableItemRef, isMobile]);
709
736
  useEffect(() => {
710
737
  var _a, _b, _c, _d;
711
738
  if (!uiState.isOpen) {
@@ -715,13 +742,18 @@ export const GroupsFilterRaw = props => {
715
742
  (_a = inputRef.current) === null || _a === void 0 ? void 0 : _a.focus();
716
743
  prevSearchField.current = uiState.searchValue;
717
744
  } else {
718
- const firstFocusable = chip ? (_b = menuRef.current) === null || _b === void 0 ? void 0 : _b.querySelectorAll(FOCUSABLE_SELECTOR)[1] : (_c = menuRef.current) === null || _c === void 0 ? void 0 : _c.querySelector(FOCUSABLE_SELECTOR);
745
+ const firstFocusable = chip || isMobile ? (_b = menuRef.current) === null || _b === void 0 ? void 0 : _b.querySelectorAll(FOCUSABLE_SELECTOR)[1] : (_c = menuRef.current) === null || _c === void 0 ? void 0 : _c.querySelector(FOCUSABLE_SELECTOR);
719
746
  prevSearchField.current = "";
720
- if (firstFocusable && !((_d = inputRef.current) === null || _d === void 0 ? void 0 : _d.value)) {
721
- firstFocusable.focus();
747
+ if (nextFocusableItemRef.current) {
748
+ const nextFocusable = typeof nextFocusableItemRef.current === "string" ? (_d = menuRef.current) === null || _d === void 0 ? void 0 : _d.querySelector(nextFocusableItemRef.current) : firstFocusable;
749
+ if (nextFocusable) {
750
+ nextFocusable.focus();
751
+ nextFocusableItemRef.current = false;
752
+ return;
753
+ }
722
754
  }
723
755
  }
724
- }, [uiState.searchValue, uiState.isOpen, uiState.step, handleSetStep, chip]);
756
+ }, [uiState.searchValue, uiState.isOpen, uiState.step, handleSetStep, chip, isMobile]);
725
757
  useEffect(() => {
726
758
  var _a;
727
759
  uiState.isOpen && ((_a = inputRef.current) === null || _a === void 0 ? void 0 : _a.focus());
@@ -755,6 +787,7 @@ export const GroupsFilterRaw = props => {
755
787
  const selectedCount = getFrozenCount(state);
756
788
  const isStateHasData = Object.keys(state.groupsMap).length > 0;
757
789
  const isApplyDisabled = !isStateChanged(state);
790
+ const isDataEmpty = dataItems.length === 0;
758
791
  const memoizedContent = useMemo(() => _jsxs("div", {
759
792
  className: classNames(["zen-groups-filter-menu", isMobile ? "zen-groups-filter-menu--mobile" : ""]),
760
793
  ref: menuRef,
@@ -768,7 +801,7 @@ export const GroupsFilterRaw = props => {
768
801
  id: groupsFilterId,
769
802
  placeholder: translate("Filter by group")
770
803
  })
771
- }) : null, isStateHasData && !uiState.hasError && _jsxs(GroupsFilterMenu, {
804
+ }) : null, isStateHasData && !uiState.hasError && !(uiState.isLoading && isDataEmpty) && _jsxs(GroupsFilterMenu, {
772
805
  onCancelClick: handleCancel,
773
806
  onApplyClick: handleApply,
774
807
  onResetClick: handleReset,
@@ -798,10 +831,10 @@ export const GroupsFilterRaw = props => {
798
831
  onRelationChange: onRelationChange,
799
832
  children: getGroupsBox()
800
833
  })]
801
- }), !uiState.hasError && !isStateHasData && !Object.keys(state.groupsMap).length && _jsx(SkeletonList, {
834
+ }), (!uiState.hasError && !isStateHasData && !Object.keys(state.groupsMap).length || uiState.isLoading && isDataEmpty) && _jsx(SkeletonList, {
802
835
  className: "zen-groups-filter__waiting"
803
836
  })]
804
- }), [isMobile, chip, onSearchChipChange, uiState.searchValue, uiState.hasError, uiState.step, uiState.currentAdjustmentId, groupsFilterId, translate, isStateHasData, handleCancel, handleApply, handleReset, isApplyDisabled, state, handleAdvancedDialogOpen, handleCurrentlySelectedClick, getSearchResult, getGroupsBox, handleBackButtonClick, handleHomeButtonClick, selectAllHandler, basicHandleBackButtonClick]);
837
+ }), [isMobile, chip, onSearchChipChange, uiState.searchValue, uiState.hasError, uiState.step, uiState.currentAdjustmentId, groupsFilterId, translate, isStateHasData, handleCancel, handleApply, handleReset, isApplyDisabled, state, handleAdvancedDialogOpen, handleCurrentlySelectedClick, getSearchResult, getGroupsBox, handleBackButtonClick, handleHomeButtonClick, selectAllHandler, basicHandleBackButtonClick, uiState.isLoading, isDataEmpty]);
805
838
  const memoizedFooterButtons = useMemo(() => _jsxs(FooterButtons, {
806
839
  children: [_jsx(Button, {
807
840
  onClick: handleApply,
@@ -879,7 +912,7 @@ export const GroupsFilterRaw = props => {
879
912
  isOpen: uiState.isOpen,
880
913
  className: classNames(["zen-groups-filter__popup", uiState.isOpenAdvancedFilter ? "zen-groups-filter__popup--inactive" : "", classNamePopup || ""]),
881
914
  onOpenChange: onOptionsToggle,
882
- useTrapFocusWithTrigger: uiState.isOpenAdvancedFilter ? "off" : "withTrigger",
915
+ useTrapFocusWithTrigger: uiState.isOpenAdvancedFilter ? "off" : "none",
883
916
  shouldHoldScroll: true,
884
917
  triggerRef: triggerRef,
885
918
  ariaLabel: translate("Organization groups filter"),
@@ -920,7 +953,8 @@ export const GroupsFilterRaw = props => {
920
953
  ref: triggerRef,
921
954
  fullSize: fullSize,
922
955
  placeholder: groupPlaceHolder,
923
- popupId: popupId
956
+ popupId: popupId,
957
+ handleFocusOnPopup: handleFocusOnPopup
924
958
  }), isMobile ? memoizedMobileView : memoizedDesktopView, uiState.isOpenAdvancedFilter && getAdvancedDialog]
925
959
  });
926
960
  };
@@ -15,9 +15,10 @@ interface IGroupsFilterTrigger {
15
15
  ref?: React.RefObject<HTMLDivElement | null>;
16
16
  isError?: boolean;
17
17
  popupId?: string;
18
+ handleFocusOnPopup?: () => void;
18
19
  }
19
20
  export declare const GroupsFilterTrigger: {
20
- ({ value, className, onChange, placeholder, isOpenPopup, count, withGlobeIcon, inputRef, handleClick, fullSize, ref, isError, popupId, ...otherProps }: IGroupsFilterTrigger): import("react/jsx-runtime").JSX.Element;
21
+ ({ value, className, onChange, placeholder, isOpenPopup, count, withGlobeIcon, inputRef, handleClick, fullSize, ref, isError, popupId, handleFocusOnPopup, ...otherProps }: IGroupsFilterTrigger): import("react/jsx-runtime").JSX.Element;
21
22
  displayName: string;
22
23
  };
23
24
  export declare const TRANSLATIONS: string[];
@@ -81,9 +81,10 @@ export const GroupsFilterTrigger = _a => {
81
81
  fullSize,
82
82
  ref,
83
83
  isError,
84
- popupId
84
+ popupId,
85
+ handleFocusOnPopup
85
86
  } = _a,
86
- otherProps = __rest(_a, ["value", "className", "onChange", "placeholder", "isOpenPopup", "count", "withGlobeIcon", "inputRef", "handleClick", "fullSize", "ref", "isError", "popupId"]);
87
+ otherProps = __rest(_a, ["value", "className", "onChange", "placeholder", "isOpenPopup", "count", "withGlobeIcon", "inputRef", "handleClick", "fullSize", "ref", "isError", "popupId", "handleFocusOnPopup"]);
87
88
  const {
88
89
  translate
89
90
  } = useLanguage();
@@ -93,10 +94,20 @@ export const GroupsFilterTrigger = _a => {
93
94
  if (e.key === "Enter" && !isOpenPopup) {
94
95
  handleClick();
95
96
  }
97
+ if (e.key === "ArrowDown" && !isOpenPopup) {
98
+ handleClick();
99
+ }
100
+ if (e.key === "ArrowDown" && isOpenPopup) {
101
+ handleFocusOnPopup === null || handleFocusOnPopup === void 0 ? void 0 : handleFocusOnPopup();
102
+ }
96
103
  if (e.key === "Escape" && isOpenPopup && e.nativeEvent) {
97
104
  e.nativeEvent.stopImmediatePropagation();
98
105
  handleClick();
99
106
  }
107
+ if (e.key === "Tab" && isOpenPopup) {
108
+ e.preventDefault();
109
+ handleFocusOnPopup === null || handleFocusOnPopup === void 0 ? void 0 : handleFocusOnPopup();
110
+ }
100
111
  };
101
112
  const clickHandler = e => {
102
113
  if (e.target === inputRef.current && isOpenPopup) {
package/esm/index.d.ts CHANGED
@@ -720,7 +720,7 @@ export { PageLayout } from "./pageLayout/pageLayout";
720
720
  export { type IPagination, Pagination } from "./pagination/pagination";
721
721
  export { PaginationType } from "./pagination/paginationType";
722
722
  export { Pill } from "./pill/pill";
723
- export { type IPillExpandableAction, type IBaseData, type IPromisedBaseData, type IPillExpandable, PillExpandable } from "./pillExpandable/pillExpandable";
723
+ export { type IPillExpandableAction, type IBaseData, type IPromisedBaseData, type TPopoverSize, type IPillExpandable, PillExpandable } from "./pillExpandable/pillExpandable";
724
724
  export { type IPopup, Popup } from "./popup/popup";
725
725
  export { type IPrimaryIcon, PrimaryIcon } from "./primaryIcon/primaryIcon";
726
726
  export { ProgressBarType, ProgreesBarSize, type TProgressBarSize, ProgressBar } from "./progressBar/progressBar";
@@ -14,9 +14,11 @@ interface IMarkerClasses {
14
14
  * If not provided, defaults to 'zen-list-item' based classes
15
15
  * @param onBeforeDragOver - Optional callback function called before placing the placeholder at a new position.
16
16
  * Receives the target position and should return false to prevent the drag operation.
17
+ * @param itemsGap - Optional gap size in pixels between list items. Used to adjust placeholder positioning
18
+ * calculations during drag operations. Defaults to 0.
17
19
  * @returns An object containing the `onDragStart` event handler to be attached to draggable elements
18
20
  */
19
- export declare const useDragAndDrop: (containerRef: RefObject<HTMLElement | null>, onChangeOrder: (startPosition: number, endPosition: number) => void, marksClassNames?: IMarkerClasses, onBeforeDragOver?: (endPosition: number) => boolean) => {
21
+ export declare const useDragAndDrop: (containerRef: RefObject<HTMLElement | null>, onChangeOrder: (startPosition: number, endPosition: number) => void, marksClassNames?: IMarkerClasses, onBeforeDragOver?: (endPosition: number) => boolean, itemsGap?: number) => {
20
22
  onDragStart: (e: React.PointerEvent<HTMLElement>) => void;
21
23
  };
22
24
  export {};
@@ -14,9 +14,11 @@ import { zen } from "../../utils/zen";
14
14
  * If not provided, defaults to 'zen-list-item' based classes
15
15
  * @param onBeforeDragOver - Optional callback function called before placing the placeholder at a new position.
16
16
  * Receives the target position and should return false to prevent the drag operation.
17
+ * @param itemsGap - Optional gap size in pixels between list items. Used to adjust placeholder positioning
18
+ * calculations during drag operations. Defaults to 0.
17
19
  * @returns An object containing the `onDragStart` event handler to be attached to draggable elements
18
20
  */
19
- export const useDragAndDrop = (containerRef, onChangeOrder, marksClassNames, onBeforeDragOver) => {
21
+ export const useDragAndDrop = (containerRef, onChangeOrder, marksClassNames, onBeforeDragOver, itemsGap = 0) => {
20
22
  const dragImageRef = useRef(null);
21
23
  const dragMoveRef = useRef(undefined);
22
24
  const { moveScroll, cancelMoveScroll } = useContainerScroll();
@@ -47,8 +49,12 @@ export const useDragAndDrop = (containerRef, onChangeOrder, marksClassNames, onB
47
49
  if (!containerRef.current) {
48
50
  return;
49
51
  }
50
- const items = containerRef.current.querySelectorAll(`.${cssMarks.general}`);
51
52
  const rect = element.getBoundingClientRect();
53
+ // preventing placeholder alignment when dragged element is not properly positioned yet
54
+ if (rect.top < 0) {
55
+ return;
56
+ }
57
+ const items = containerRef.current.querySelectorAll(`.${cssMarks.general}`);
52
58
  const listRect = containerRef.current.getBoundingClientRect();
53
59
  if (rect.top < listRect.top) {
54
60
  if (onBeforeDragOver && !onBeforeDragOver(0)) {
@@ -76,13 +82,14 @@ export const useDragAndDrop = (containerRef, onChangeOrder, marksClassNames, onB
76
82
  return;
77
83
  }
78
84
  const dragItemTopOffset = 4;
85
+ const halfGap = itemsGap / 2;
79
86
  for (let i = 0; i < items.length; i++) {
80
87
  const item = items[i];
81
88
  if (item.classList.contains(cssMarks.placeholder) || item.classList.contains(cssMarks.dragging)) {
82
89
  continue;
83
90
  }
84
91
  const itemRect = item.getBoundingClientRect();
85
- if (item !== element && rect.top > itemRect.top + dragItemTopOffset && rect.top <= itemRect.bottom) {
92
+ if (item !== element && rect.top > itemRect.top + dragItemTopOffset - halfGap && rect.top <= itemRect.bottom + halfGap) {
86
93
  if (onBeforeDragOver && !onBeforeDragOver(i + 1)) {
87
94
  return;
88
95
  }
@@ -98,7 +105,7 @@ export const useDragAndDrop = (containerRef, onChangeOrder, marksClassNames, onB
98
105
  return;
99
106
  }
100
107
  }
101
- }, [containerRef, getPlaceholder, removePlaceholders, onBeforeDragOver, cssMarks.general, cssMarks.placeholder, cssMarks.dragging]);
108
+ }, [containerRef, getPlaceholder, removePlaceholders, onBeforeDragOver, cssMarks.general, cssMarks.placeholder, cssMarks.dragging, itemsGap]);
102
109
  const onDragStart = useCallback((e) => {
103
110
  var _a, _b, _c, _d, _e;
104
111
  e.preventDefault();