@geotab/zenith 3.10.0-beta.3 → 3.10.0-beta.6

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.
package/README.md CHANGED
@@ -55,12 +55,19 @@ Zenith library provides components defined in Zenith Design System. It includes
55
55
  - `Nav` empty state support
56
56
  - Allow multiple columns to be disabled in `ColumnsList`
57
57
  - Flip icons for Arabic (RTL) language
58
- - `Dropdown` search and select-all improvements
58
+ - `Dropdown` select-all button shows active state when all items are selected
59
+ - Add `ariaLabel` prop to `CardButton` for accessible name override
60
+ - Fix `GroupsFilter` dropdown scrolling into blank space
61
+ - Fix `Dropdown` ARIA pattern — non-search dropdowns now use `menu` role instead of `dialog`
62
+ - Reverse RTL slide-in animation direction for `Toast` and `Notification`
59
63
  - Fix `SidePanel` not animating open due to RTL regression
60
64
  - Add `closeOnScroll` prop to close `ContextMenu` on scroll
61
65
  - Fix checkbox accessibility by moving input inside label wrapper
62
66
  - Fix multi-page selection in `Table` selectable rows
63
67
  - Add `titleAs` prop to `Card` title to control heading tag (`h1`–`h6`)
68
+ - Convert selection and toggle inputs (`Checkbox`, `Radio`, `Toggle`) to rem units
69
+ - Convert text, search, and file inputs to rem units
70
+ - Convert utility and standalone components to rem units
64
71
 
65
72
  ### 3.9.2
66
73
 
@@ -379,8 +379,7 @@ const CheckboxListWithAction = ({
379
379
  onClick: handleClick,
380
380
  title: title,
381
381
  className: classN,
382
- tabIndex: -1,
383
- disabled: option.blocked
382
+ tabIndex: -1
384
383
  }, otherArgs, {
385
384
  children: childEl
386
385
  })) : (0, jsx_runtime_1.jsx)("div", {
@@ -24,4 +24,4 @@ const Dropdown = (_a) => {
24
24
  return (0, jsx_runtime_1.jsx)(DropDownFormField, Object.assign({}, props));
25
25
  };
26
26
  exports.Dropdown = Dropdown;
27
- exports.TRANSLATIONS = ["Filter by group", "Open filter", "Clear search", "Select all", "Clear", "Back", "No data"];
27
+ exports.TRANSLATIONS = ["Filter by group", "Open filter", "Clear search", "Select all", "Deselect all", "Clear", "Back", "No data"];
@@ -13,9 +13,7 @@ export interface IDropdownList extends IZenComponentProps {
13
13
  onSelect: (id: string) => void;
14
14
  onSingleSelect: (reset: boolean, selected?: string) => void;
15
15
  backButtonName?: string;
16
- isAllSelected?: boolean;
17
- isSelectAllActive?: boolean;
18
- shouldBlockItems?: boolean;
16
+ isAllSelected: boolean;
19
17
  listData: ICheckboxListWithActionOption[] | ISelectListItem[];
20
18
  isWithFooter: boolean;
21
19
  width?: number;
@@ -41,6 +39,6 @@ interface IDropdownEmptyList extends Pick<IDropdownList, "className" | "width" |
41
39
  hasError: boolean;
42
40
  }
43
41
  export declare const EmptyList: ({ className, width, onClearClick, onApplyClick, onCancelClick, hasApplyButton, isApplyDisabled, isClearButtonDisabled, isWithFooter, hasError }: IDropdownEmptyList) => import("react/jsx-runtime").JSX.Element;
44
- export declare const DropdownList: ({ onBackButtonClick, onSelectAllClick, onClearClick, onApplyClick, onCancelClick, onChange, onSelect, onSingleSelect, listData, isSelectAllActive, shouldBlockItems, backButtonName, width, minWidth, isSelectAllButtonDisable, hasSelectAllButton, filterName, isMultiselect, hasApplyButton, isApplyDisabled, isClearButtonDisabled, activeValue, forceSelection, isWithFooter, isMobile, handleCheckboxChange, checkboxLabel, isChecked, listElementRef, listId }: IDropdownList) => import("react/jsx-runtime").JSX.Element;
42
+ export declare const DropdownList: ({ onBackButtonClick, onSelectAllClick, onClearClick, onApplyClick, onCancelClick, onChange, onSelect, onSingleSelect, listData, isAllSelected, backButtonName, width, minWidth, isSelectAllButtonDisable, hasSelectAllButton, filterName, isMultiselect, hasApplyButton, isApplyDisabled, isClearButtonDisabled, activeValue, forceSelection, isWithFooter, isMobile, handleCheckboxChange, checkboxLabel, isChecked, listElementRef, listId }: IDropdownList) => import("react/jsx-runtime").JSX.Element;
45
43
  export declare const TRANSLATIONS: string[];
46
44
  export {};
@@ -174,6 +174,33 @@ injectString("zh-Hans", "Apply", "\u5E94\u7528");
174
174
  injectString("zh-TW", "Apply", "\u5957\u7528");
175
175
  injectString("ro-RO", "Apply", "Aplica\u021Bi");
176
176
  injectString("ar-SA", "Apply", "\u062A\u0637\u0628\u064A\u0642");
177
+ injectString("cs", "Deselect all", "Zru\u0161it v\xFDb\u011Br v\u0161ech");
178
+ injectString("da-DK", "Deselect all", "Frav\xE6lg alle");
179
+ injectString("de", "Deselect all", "Auswahl f\xFCr alle aufheben");
180
+ injectString("en", "Deselect all", "Deselect all");
181
+ injectString("es", "Deselect all", "Deseleccionar todo");
182
+ injectString("fi-FI", "Deselect all", "Poista kaikki valinnat");
183
+ injectString("fr", "Deselect all", "D\xE9s\xE9lectionner tout");
184
+ injectString("fr-FR", "Deselect all", "D\xE9s\xE9lectionner tout");
185
+ injectString("hu-HU", "Deselect all", "Ne v\xE1lassz ki semmit.");
186
+ injectString("id", "Deselect all", "Batalkan pilih semua");
187
+ injectString("it", "Deselect all", "Deselezionare tutto");
188
+ injectString("ja", "Deselect all", "\u3059\u3079\u3066\u3092\u9078\u629E\u89E3\u9664");
189
+ injectString("ko-KR", "Deselect all", "\uBAA8\uB450 \uC120\uD0DD \uCDE8\uC18C");
190
+ injectString("ms", "Deselect all", "Nyahpilih semua");
191
+ injectString("nb-NO", "Deselect all", "Fjern alle valg");
192
+ injectString("nl", "Deselect all", "Alles deselecteren");
193
+ injectString("pl", "Deselect all", "Usu\u0144 wyb\xF3r wszystkich");
194
+ injectString("pt-BR", "Deselect all", "Desmarcar tudo");
195
+ injectString("pt-PT", "Deselect all", "Desmarcar tudo");
196
+ injectString("sk-SK", "Deselect all", "Zru\u0161 v\xFDber v\u0161etk\xFDch.");
197
+ injectString("sv", "Deselect all", "Avmarkera alla");
198
+ injectString("th", "Deselect all", "\u0E22\u0E01\u0E40\u0E25\u0E34\u0E01\u0E01\u0E32\u0E23\u0E40\u0E25\u0E37\u0E2D\u0E01\u0E17\u0E31\u0E49\u0E07\u0E2B\u0E21\u0E14");
199
+ injectString("tr", "Deselect all", "T\xFCm\xFCn\xFCn se\xE7imini iptal et");
200
+ injectString("zh-Hans", "Deselect all", "\u53D6\u6D88\u5168\u9009");
201
+ injectString("zh-TW", "Deselect all", "\u53D6\u6D88\u5168\u9078");
202
+ injectString("ro-RO", "Deselect all", "Deselecta\u021Bi tot");
203
+ injectString("ar-SA", "Deselect all", "\u0625\u0644\u063A\u0627\u0621 \u062A\u062D\u062F\u064A\u062F \u0627\u0644\u0643\u0644");
177
204
  injectString("cs", "Select all", "Vybrat v\u0161e");
178
205
  injectString("da-DK", "Select all", "V\xE6lg alle");
179
206
  injectString("de", "Select all", "Alle ausw\xE4hlen");
@@ -332,8 +359,7 @@ const DropdownList = ({
332
359
  onSelect,
333
360
  onSingleSelect,
334
361
  listData,
335
- isSelectAllActive,
336
- shouldBlockItems,
362
+ isAllSelected,
337
363
  backButtonName,
338
364
  width,
339
365
  minWidth,
@@ -362,7 +388,7 @@ const DropdownList = ({
362
388
  const internalListId = (0, react_1.useId)();
363
389
  const selectListId = listId || internalListId;
364
390
  const handleSelectAllClick = () => {
365
- onSelectAllClick(isSelectAllActive === true);
391
+ onSelectAllClick(isAllSelected);
366
392
  };
367
393
  const handleBackButtonKeyDown = (0, react_1.useCallback)(event => {
368
394
  if (event.key === "ArrowLeft") {
@@ -390,14 +416,13 @@ const DropdownList = ({
390
416
  // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition
391
417
  forceSelection ? onSingleSelect(false, newActiveEl || activeValue) : onSingleSelect(false, newActiveEl);
392
418
  }, [activeValue, forceSelection, onSingleSelect]);
393
- const selectButtonLabel = translate("Select all");
394
- const getActionButton = (label, title, icon, isDisabled, clickHandler, size, onKeyDown, isSelected) => (0, jsx_runtime_1.jsx)("button", {
419
+ const selectButtonLabel = isAllSelected ? translate("Deselect all") : translate("Select all");
420
+ const getActionButton = (label, title, icon, isDisabled, clickHandler, size, onKeyDown) => (0, jsx_runtime_1.jsx)("button", {
395
421
  type: "button",
396
422
  disabled: isDisabled,
397
423
  onClick: clickHandler,
398
424
  onKeyDown: onKeyDown,
399
- "aria-pressed": isSelected,
400
- className: (0, classNames_1.classNames)(["zen-dropdown-list__item zen-dropdown-list__item--interactive zen-dropdown-list__action-button zen-dropdown-list__action-button-back", isSelected ? "zen-dropdown-list__action-button--selected" : ""]),
425
+ className: "zen-dropdown-list__item zen-dropdown-list__item--interactive zen-dropdown-list__action-button zen-dropdown-list__action-button-back",
401
426
  title: title,
402
427
  children: (0, jsx_runtime_1.jsxs)(jsx_runtime_1.Fragment, {
403
428
  children: [react_1.default.createElement(icon, {
@@ -433,15 +458,11 @@ const DropdownList = ({
433
458
  });
434
459
  return values;
435
460
  };
436
- const multiselectOptions = shouldBlockItems ? listData.map(item => Object.assign(Object.assign({}, item), {
437
- blocked: true,
438
- checked: false
439
- })) : listData;
440
461
  return (0, jsx_runtime_1.jsx)("div", {
441
462
  className: "zen-dropdown-list__elements",
442
463
  ref: listElementRef,
443
464
  children: isMultiselect ? (0, jsx_runtime_1.jsx)(checkboxListWithAction_1.CheckboxListWithAction, {
444
- options: multiselectOptions,
465
+ options: listData,
445
466
  label: "",
446
467
  onChange: handleChange,
447
468
  onClick: handleClick
@@ -457,7 +478,7 @@ const DropdownList = ({
457
478
  value: createValue(listData, activeValue)
458
479
  })
459
480
  });
460
- }, [listElementRef, isMultiselect, shouldBlockItems, listData, handleChange, handleClick, handleSingleChange, translate, selectListId, forceSelection, activeValue]);
481
+ }, [listElementRef, isMultiselect, listData, handleChange, handleClick, handleSingleChange, translate, selectListId, forceSelection, activeValue]);
461
482
  return (0, jsx_runtime_1.jsxs)("div", Object.assign({
462
483
  className: (0, classNames_1.classNames)(["zen-dropdown-list", driveComponentClass || ""])
463
484
  }, styleWidth, {
@@ -475,7 +496,7 @@ const DropdownList = ({
475
496
  }) : null, backButtonName ? (0, jsx_runtime_1.jsx)("div", {
476
497
  className: "zen-dropdown-list__item-wrapper",
477
498
  children: getActionButton(backButtonName, translate("Back"), iconBackArrow_1.IconBackArrow, false, onBackButtonClick, "large", handleBackButtonKeyDown)
478
- }) : null, hasSelectAllButton ? getActionButton(selectButtonLabel, selectButtonLabel, iconCheckRadio_1.IconCheckRadio, !!isSelectAllButtonDisable, handleSelectAllClick, isDrive ? "huger" : "huge", undefined, isSelectAllActive) : null, listDataComponent, isWithFooter ? (0, jsx_runtime_1.jsxs)("div", {
499
+ }) : null, hasSelectAllButton ? getActionButton(selectButtonLabel, selectButtonLabel, iconCheckRadio_1.IconCheckRadio, !!isSelectAllButtonDisable, handleSelectAllClick, isDrive ? "huger" : "huge") : null, listDataComponent, isWithFooter ? (0, jsx_runtime_1.jsxs)("div", {
479
500
  className: "zen-dropdown-list__footer",
480
501
  children: [(0, jsx_runtime_1.jsx)(button_1.Button, {
481
502
  onClick: isMultiselect ? onClearClick : handleClearClick,
@@ -504,4 +525,4 @@ const DropdownList = ({
504
525
  }));
505
526
  };
506
527
  exports.DropdownList = DropdownList;
507
- exports.TRANSLATIONS = ["Select all", "Clear", "Back", "No data"];
528
+ exports.TRANSLATIONS = ["Select all", "Deselect all", "Clear", "Back", "No data"];
@@ -399,6 +399,23 @@ const DropdownRaw = props => {
399
399
  payload: state.currentId || state.rootId
400
400
  });
401
401
  }, [isFullSelectionMode, state.currentId, state.rootId]);
402
+ const handleSelectAllInSearch = (0, react_1.useCallback)(isAllSelect => {
403
+ if (isFullSelectionMode && state.isAllSelected) {
404
+ dispatchState({
405
+ type: stateActionType_1.StateActionType.DeselectItemsFromAllSelected,
406
+ payload: undefined
407
+ });
408
+ return;
409
+ }
410
+ const dataForChange = (0, dropdownHelper_1.getDataForChange)((0, dropdownHelper_1.getListDataWithDisabled)(state.listData, state.isNestedList), state.selectedIds, isAllSelect);
411
+ dispatchState({
412
+ type: stateActionType_1.StateActionType.ChangeBulkSelection,
413
+ payload: {
414
+ itemsIds: dataForChange,
415
+ value: !isAllSelect
416
+ }
417
+ });
418
+ }, [isFullSelectionMode, state.isAllSelected, state.listData, state.isNestedList, state.selectedIds]);
402
419
  const handleClearClick = (0, react_1.useCallback)(() => {
403
420
  var _a, _b;
404
421
  dispatchState({
@@ -845,14 +862,13 @@ const DropdownRaw = props => {
845
862
  });
846
863
  }
847
864
  if (state.showList) {
848
- const isSearchMode = Boolean(state.inputValue) && !state.currentId;
865
+ const isSearchMode = state.inputValue && !state.currentId;
849
866
  const currentListData = (0, dropdownHelper_1.createListDataOptions)(state, translate, isSearchMode ? (0, dropdownHelper_1.sortDropdownItemArray)(state.listData, sortFn).slice(0, listLimit).filter(el => el.id !== state.rootId) :
850
867
  // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition
851
868
  (0, dropdownHelper_1.sortDropdownItemArray)(((_b = state.groupsMap[state.currentId || state.rootId]) === null || _b === void 0 ? void 0 : _b.children) || [], sortFn).slice(0, listLimit) || [], multiselect, currentAllSelected);
852
- const selectAllActiveForCurrentLevel = state.selectAllActiveForId === (state.currentId || state.rootId);
853
869
  return (0, jsx_runtime_1.jsx)(dropdownList_1.DropdownList, {
854
870
  onBackButtonClick: handleBackButtonClick,
855
- onSelectAllClick: handleSelectAllClick,
871
+ onSelectAllClick: isSearchMode ? handleSelectAllInSearch : handleSelectAllClick,
856
872
  onClearClick: handleClearClick,
857
873
  onCancelClick: handleCancelClick,
858
874
  onApplyClick: handleApplyClick,
@@ -863,8 +879,6 @@ const DropdownRaw = props => {
863
879
  backButtonName: state.currentId && state.groupsMap[state.currentId] ? (0, groupsHelper_1.getGroupDescription)(state.groupsMap[state.currentId], translate) : undefined,
864
880
  filterName: isMobile ? undefined : filterName,
865
881
  isAllSelected: currentAllSelected ? currentAllSelected : isSearchMode ? (0, dropdownHelper_1.isEveryItemSelected)((0, dropdownHelper_1.getListDataWithDisabled)(state.listData, state.isNestedList), state.selectedIds) : currentAllSelected === undefined ? (0, dropdownHelper_1.isAllChildrenSelected)(state, state.currentId || state.rootId) : false,
866
- isSelectAllActive: isFullSelectionMode ? currentAllSelected : selectAllActiveForCurrentLevel,
867
- shouldBlockItems: !state.inputValue && !isFullSelectionMode && selectAllActiveForCurrentLevel,
868
882
  isMultiselect: multiselect,
869
883
  forceSelection: forceSelection,
870
884
  listData: currentListData,
@@ -873,7 +887,7 @@ const DropdownRaw = props => {
873
887
  hasSelectAllButton: selectAllButton && multiselect,
874
888
  hasApplyButton: hasApplyButton,
875
889
  isApplyDisabled: memoizedIsApplyButtonDisabled,
876
- isSelectAllButtonDisable: currentListData.length === 0 || isSearchMode && state.isNestedList && (0, dropdownHelper_1.isAllItemsHasOneParent)(state.listData.filter(el => el.id !== state.rootId), (((_c = state.groupsMap[state.rootId]) === null || _c === void 0 ? void 0 : _c.children) || []).map(el => el.id)),
890
+ isSelectAllButtonDisable: currentListData.length === 0 || isSearchMode !== "" && state.isNestedList && (0, dropdownHelper_1.isAllItemsHasOneParent)(state.listData.filter(el => el.id !== state.rootId), (((_c = state.groupsMap[state.rootId]) === null || _c === void 0 ? void 0 : _c.children) || []).map(el => el.id)),
877
891
  isClearButtonDisabled: memoizedIsClearButtonDisabled,
878
892
  isWithFooter: memoizedWithFooter && !isMobile,
879
893
  isMobile: isMobile,
@@ -885,7 +899,7 @@ const DropdownRaw = props => {
885
899
  });
886
900
  }
887
901
  return null;
888
- }, [state, isLoading, isQueryMode, fetchState === null || fetchState === void 0 ? void 0 : fetchState.isLoading, fetchState === null || fetchState === void 0 ? void 0 : fetchState.error, handleClearClick, handleCancelClick, handleApplyClick, hasApplyButton, memoizedWithFooter, translate, sortFn, listLimit, multiselect, currentAllSelected, handleBackButtonClick, handleSelectAllClick, handleSelect, handleChangeCurrentId, handleSingleSelection, isMobile, filterName, forceSelection, width, selectAllButton, memoizedIsApplyButtonDisabled, memoizedIsClearButtonDisabled, isCheckboxMode, handleCheckboxChange, checkboxLabel, selectListId, isFullSelectionMode]);
902
+ }, [state, isLoading, isQueryMode, fetchState === null || fetchState === void 0 ? void 0 : fetchState.isLoading, fetchState === null || fetchState === void 0 ? void 0 : fetchState.error, handleClearClick, handleCancelClick, handleApplyClick, hasApplyButton, memoizedWithFooter, translate, sortFn, listLimit, multiselect, currentAllSelected, handleBackButtonClick, handleSelectAllInSearch, handleSelectAllClick, handleSelect, handleChangeCurrentId, handleSingleSelection, isMobile, filterName, forceSelection, width, selectAllButton, memoizedIsApplyButtonDisabled, memoizedIsClearButtonDisabled, isCheckboxMode, handleCheckboxChange, checkboxLabel, selectListId]);
889
903
  const currentStringFromSelected = isFullSelectionMode && hasApplyButton && state.globalIsAllSelected || isFullSelectionMode && !hasApplyButton && state.isAllSelected ? (0, dropdownHelper_1.getStringFromAllSelected)(state.groupsMap, translate, state.rootId) : (0, dropdownHelper_1.getStringFromSelected)(hasApplyButton ? state.globalSelectedIds : state.selectedIds, state.groupsMapSelected, translate, state.rootId);
890
904
  const memoizedCurrentSelection = (0, react_1.useMemo)(() => showSelection && !state.inputValue ? currentStringFromSelected : "", [showSelection, state.inputValue, currentStringFromSelected]);
891
905
  const parentTriggerWidth = ((_b = comboboxRef.current) === null || _b === void 0 ? void 0 : _b.getBoundingClientRect().width) || 420;
@@ -983,4 +997,4 @@ const DropdownRaw = props => {
983
997
  };
984
998
  exports.DropdownRaw = DropdownRaw;
985
999
  exports.DropdownRaw.displayName = "DropdownRaw";
986
- exports.TRANSLATIONS = ["Filter by group", "Open filter", "Clear search", "Select all", "Clear", "Back", "No data"];
1000
+ exports.TRANSLATIONS = ["Filter by group", "Open filter", "Clear search", "Select all", "Deselect all", "Clear", "Back", "No data"];
@@ -25,7 +25,6 @@ export interface IDropdownState {
25
25
  listLimit: number;
26
26
  resultsExceedListLimit?: boolean;
27
27
  isAllSelected?: boolean;
28
- selectAllActiveForId?: string;
29
28
  globalIsAllSelected?: boolean;
30
29
  defaultValueIsAllSelected?: boolean;
31
30
  isChecked?: boolean;
@@ -77,12 +77,10 @@ function stateReducer(state, action) {
77
77
  }
78
78
  const isCurrentListNested = Object.keys(updatedGroupsMap).length > 0 &&
79
79
  (updatedGroupsMap[exports.ROOT_GROUP_ID].children || []).some(el => el.children && el.children.length);
80
- const groupsMapLength = Object.keys(updatedGroupsMap).length - 1;
81
- const newResultsExceedListLimit = groupsMapLength >= state.listLimit;
82
- const selectedInNewMap = state.selectedIds.filter(id => id in updatedGroupsMap).length;
83
- const newIsAllSelected = (0, stateReducerHelper_1.computeIsAllSelected)(state.isAllSelected, state.isFullSelectionMode, newResultsExceedListLimit, groupsMapLength, selectedInNewMap);
80
+ state.groupsMap = updatedGroupsMap;
81
+ const additionalStateUpdates = (0, stateReducerHelper_1.updateAllSelectedStateValueBasedOnTotalSelected)(state, state.selectedIds.length - newNamelessIds.size);
84
82
  const rootId = (0, stateReducerHelper_1.getRootId)(updatedGroupsMap, exports.ROOT_GROUP_ID, state.firstParentNodeIsVisible);
85
- return Object.assign(Object.assign({}, state), { groupsMap: updatedGroupsMap, rootId: rootId || exports.ROOT_GROUP_ID, namelessIds: newNamelessIds, isNestedList: state.isNestedList ? state.isNestedList : isCurrentListNested, resultsExceedListLimit: newResultsExceedListLimit, isAllSelected: newIsAllSelected });
83
+ return Object.assign(Object.assign(Object.assign({}, state), { rootId: rootId || exports.ROOT_GROUP_ID, namelessIds: newNamelessIds, isNestedList: state.isNestedList ? state.isNestedList : isCurrentListNested, resultsExceedListLimit: Object.keys(updatedGroupsMap).length - 1 >= state.listLimit }), additionalStateUpdates);
86
84
  }
87
85
  case stateActionType_1.StateActionType.SetListData: {
88
86
  state.selectedIds.forEach(id => {
@@ -107,9 +105,9 @@ function stateReducer(state, action) {
107
105
  case stateActionType_1.StateActionType.SetIsOpenCombo:
108
106
  return Object.assign(Object.assign({}, state), { isOpenCombo: payload });
109
107
  case stateActionType_1.StateActionType.ResetSelection:
110
- return Object.assign(Object.assign({}, state), { selectedIds: [...state.defaultValue], isAllSelected: state.defaultValueIsAllSelected, isChecked: typeof state.isChecked === "boolean" ? state.defaultValueIsChecked || false : undefined, selectAllActiveForId: undefined });
108
+ return Object.assign(Object.assign({}, state), { selectedIds: [...state.defaultValue], isAllSelected: state.defaultValueIsAllSelected, isChecked: typeof state.isChecked === "boolean" ? state.defaultValueIsChecked || false : undefined });
111
109
  case stateActionType_1.StateActionType.ResetStateToGlobal:
112
- return Object.assign(Object.assign({}, state), { selectedIds: [...state.globalSelectedIds], isAllSelected: state.globalIsAllSelected, isChecked: state.globalIsChecked, selectAllActiveForId: undefined });
110
+ return Object.assign(Object.assign({}, state), { selectedIds: [...state.globalSelectedIds], isAllSelected: state.globalIsAllSelected, isChecked: state.globalIsChecked });
113
111
  case stateActionType_1.StateActionType.NothingToShow:
114
112
  return Object.assign(Object.assign({}, state), { showWaiting: false, showEmptyList: false, showList: false });
115
113
  case stateActionType_1.StateActionType.Show:
@@ -225,7 +223,8 @@ function stateReducer(state, action) {
225
223
  state.groupsMapSelected.set(id, Object.assign(Object.assign({ id }, (item.name ? { name: item.name } : {})), (item.color ? { color: item.color } : {})));
226
224
  }
227
225
  });
228
- return Object.assign(Object.assign({}, state), { selectedIds: Array.from(currentSelectedIds), selectAllActiveForId: undefined, isAllSelected: state.isAllSelected });
226
+ const additionalStateUpdates = (0, stateReducerHelper_1.updateAllSelectedStateValueBasedOnTotalSelected)(state, currentSelectedIds.size);
227
+ return Object.assign(Object.assign(Object.assign({}, state), { selectedIds: Array.from(currentSelectedIds) }), additionalStateUpdates);
229
228
  }
230
229
  case stateActionType_1.StateActionType.ChangeBulkSelection: {
231
230
  const { itemsIds, value } = payload;
@@ -258,7 +257,8 @@ function stateReducer(state, action) {
258
257
  state.groupsMapSelected.set(id, Object.assign(Object.assign({ id }, (item.name ? { name: item.name } : {})), (item.color ? { color: item.color } : {})));
259
258
  }
260
259
  });
261
- return Object.assign(Object.assign({}, state), { selectedIds: Array.from(currentSelectedIds), selectAllActiveForId: undefined });
260
+ const additionalStateUpdates = (0, stateReducerHelper_1.updateAllSelectedStateValueBasedOnTotalSelected)(state, currentSelectedIds.size);
261
+ return Object.assign(Object.assign(Object.assign({}, state), { selectedIds: Array.from(currentSelectedIds) }), additionalStateUpdates);
262
262
  }
263
263
  case stateActionType_1.StateActionType.SelectAllChildren: {
264
264
  const currentEl = state.groupsMap[payload];
@@ -295,7 +295,7 @@ function stateReducer(state, action) {
295
295
  state.groupsMapSelected.set(id, Object.assign(Object.assign({ id }, (item.name ? { name: item.name } : {})), (item.color ? { color: item.color } : {})));
296
296
  }
297
297
  });
298
- return Object.assign(Object.assign({}, state), { selectedIds: Array.from(newSelected), selectAllActiveForId: payload });
298
+ return Object.assign(Object.assign({}, state), { selectedIds: Array.from(newSelected) });
299
299
  }
300
300
  case stateActionType_1.StateActionType.DeselectItemsFromAllSelected: {
301
301
  const currentEl = state.groupsMap[state.rootId];
@@ -319,7 +319,7 @@ function stateReducer(state, action) {
319
319
  state.groupsMapSelected.set(id, Object.assign(Object.assign({ id }, (item.name ? { name: item.name } : {})), (item.color ? { color: item.color } : {})));
320
320
  }
321
321
  });
322
- return Object.assign(Object.assign({}, state), { selectedIds: Array.from(newSelected), isAllSelected: state.isFullSelectionMode ? false : undefined, selectAllActiveForId: undefined });
322
+ return Object.assign(Object.assign({}, state), { selectedIds: Array.from(newSelected), isAllSelected: state.isFullSelectionMode ? false : undefined });
323
323
  }
324
324
  case stateActionType_1.StateActionType.ToggleValueForAllSelected: {
325
325
  const currentEl = state.groupsMap[state.rootId];
@@ -338,7 +338,8 @@ function stateReducer(state, action) {
338
338
  }
339
339
  });
340
340
  const updatedIsAllSelectedValue = state.isFullSelectionMode ? !state.isAllSelected : undefined;
341
- return Object.assign(Object.assign({}, state), { selectedIds: state.isAllSelected ? Array.from(newSelected) : [], isAllSelected: updatedIsAllSelectedValue });
341
+ const additionalStateUpdates = (0, stateReducerHelper_1.updateAllSelectedStateValueBasedOnTotalSelected)(state, newSelected.size);
342
+ return Object.assign(Object.assign(Object.assign({}, state), { selectedIds: state.isAllSelected ? Array.from(newSelected) : [], isAllSelected: updatedIsAllSelectedValue }), additionalStateUpdates);
342
343
  }
343
344
  case stateActionType_1.StateActionType.DeselectAllChildren: {
344
345
  const childrenForDeselect = [];
@@ -350,7 +351,7 @@ function stateReducer(state, action) {
350
351
  });
351
352
  const newSelected = new Set(state.selectedIds);
352
353
  childrenForDeselect.forEach(childId => newSelected.delete(childId));
353
- return Object.assign(Object.assign({}, state), { selectedIds: Array.from(newSelected), selectAllActiveForId: undefined });
354
+ return Object.assign(Object.assign({}, state), { selectedIds: Array.from(newSelected) });
354
355
  }
355
356
  case stateActionType_1.StateActionType.SetFirstParentNodeIsVisible: {
356
357
  if (state.firstParentNodeIsVisible === payload) {
@@ -1,5 +1,6 @@
1
+ import { IDropdownState } from "./stateReducer";
1
2
  import { IDropdownRawItem } from "../types";
2
3
  import { IGroupTree, ITypedHash } from "../../groupsFilterRaw/groupsFilterInterfaces";
3
4
  export declare function getChildList(childArr: IDropdownRawItem[] | undefined): IDropdownRawItem[];
4
- export declare const computeIsAllSelected: (currentIsAllSelected: boolean | undefined, isFullSelectionMode: boolean, resultsExceedListLimit: boolean | undefined, groupsMapLength: number, selectedCount: number) => boolean | undefined;
5
+ export declare const updateAllSelectedStateValueBasedOnTotalSelected: (state: IDropdownState, totalSelected: number) => Partial<Pick<IDropdownState, "isAllSelected">>;
5
6
  export declare const getRootId: (groupsMap: ITypedHash<IGroupTree>, rootIdKey: string, firstParentNodeIsVisible?: boolean) => string | undefined;
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.getRootId = exports.computeIsAllSelected = exports.getChildList = void 0;
3
+ exports.getRootId = exports.updateAllSelectedStateValueBasedOnTotalSelected = exports.getChildList = void 0;
4
4
  const groupsHelper_1 = require("../../groupsFilterRaw/groupsHelper");
5
5
  function getChildList(childArr) {
6
6
  const list = [];
@@ -17,10 +17,17 @@ function getChildList(childArr) {
17
17
  return list;
18
18
  }
19
19
  exports.getChildList = getChildList;
20
- const computeIsAllSelected = (currentIsAllSelected, isFullSelectionMode, resultsExceedListLimit, groupsMapLength, selectedCount) => !resultsExceedListLimit && currentIsAllSelected === false && isFullSelectionMode && groupsMapLength > 0 && selectedCount >= groupsMapLength
21
- ? true
22
- : currentIsAllSelected;
23
- exports.computeIsAllSelected = computeIsAllSelected;
20
+ const updateAllSelectedStateValueBasedOnTotalSelected = (state, totalSelected) => {
21
+ const additionalStateUpdates = {};
22
+ const groupsMapLength = Object.keys(state.groupsMap).length - 1;
23
+ if (!state.resultsExceedListLimit && !state.isAllSelected && state.isFullSelectionMode && groupsMapLength > 0) {
24
+ if (totalSelected >= groupsMapLength) {
25
+ additionalStateUpdates.isAllSelected = true;
26
+ }
27
+ }
28
+ return additionalStateUpdates;
29
+ };
30
+ exports.updateAllSelectedStateValueBasedOnTotalSelected = updateAllSelectedStateValueBasedOnTotalSelected;
24
31
  const getRootId = (groupsMap, rootIdKey, firstParentNodeIsVisible) => {
25
32
  var _a;
26
33
  if (Object.keys(groupsMap).length === 0) {
package/dist/index.css CHANGED
@@ -4888,12 +4888,10 @@ html:lang(ar) .zen-checkbox__label-text {
4888
4888
  .zen-checkbox:has(.zen-checkbox__input:disabled) .zen-checkbox__label {
4889
4889
  fill: var(--text-reverse-primary);
4890
4890
  color: var(--text-button-disabled);
4891
- cursor: default;
4892
4891
  }
4893
4892
  .zen-checkbox:has(.zen-checkbox__input:disabled) .zen-checkbox__box {
4894
4893
  border-color: var(--borders-general);
4895
4894
  background-color: var(--backgrounds-field-disabled);
4896
- cursor: default;
4897
4895
  }
4898
4896
  .zen-checkbox:has(.zen-checkbox__input:disabled:checked) .zen-checkbox__box,
4899
4897
  .zen-checkbox:has(.zen-checkbox__input:disabled:indeterminate) .zen-checkbox__box {
@@ -7615,11 +7613,6 @@ html:lang(ar) .zen-checkbox-list-with-action__label {
7615
7613
  color: var(--text-hyperlink);
7616
7614
  fill: var(--text-hyperlink);
7617
7615
  }
7618
- .zen-checkbox-list-with-action__label--action:disabled {
7619
- cursor: default;
7620
- color: var(--text-disabled);
7621
- fill: var(--text-disabled);
7622
- }
7623
7616
  .zen-checkbox-list-with-action__label-text {
7624
7617
  display: flex;
7625
7618
  flex-grow: 1;
@@ -7835,8 +7828,8 @@ html:lang(ar) .zen-dropdown-list__label {
7835
7828
  .zen-dropdown-list__item--interactive:not(:disabled) {
7836
7829
  cursor: pointer;
7837
7830
  }
7838
- .zen-dropdown-list__item--interactive:not(:disabled):hover:not(.zen-dropdown-list__action-button--selected),
7839
- .zen-dropdown-list__item--interactive:not(:disabled):focus:not(.zen-dropdown-list__action-button--selected) {
7831
+ .zen-dropdown-list__item--interactive:not(:disabled):hover,
7832
+ .zen-dropdown-list__item--interactive:not(:disabled):focus {
7840
7833
  color: var(--text-primary);
7841
7834
  fill: var(--action-secondary--default);
7842
7835
  outline: none;
@@ -7906,27 +7899,6 @@ html:lang(ar) .zen-dropdown-list__action-label {
7906
7899
  .zen-dropdown-list__action-button:disabled svg {
7907
7900
  fill: var(--text-button-disabled);
7908
7901
  }
7909
- .zen-dropdown-list__action-button--selected {
7910
- background-color: var(--action-primary--default);
7911
- }
7912
- .zen-dropdown-list__action-button--selected.zen-dropdown-list__item--interactive:not(:disabled):hover,
7913
- .zen-dropdown-list__action-button--selected.zen-dropdown-list__item--interactive:not(:disabled):focus {
7914
- background-color: var(--action-primary--default);
7915
- fill: var(--text-reverse-primary);
7916
- color: var(--text-reverse-primary);
7917
- }
7918
- .zen-dropdown-list__action-button--selected.zen-dropdown-list__item--interactive:not(:disabled):focus-visible {
7919
- border-color: var(--backgrounds-content-1);
7920
- outline: 1px solid var(--borders-form-field--active);
7921
- outline-offset: 2px;
7922
- }
7923
- .zen-dropdown-list__action-button--selected .zen-dropdown-list__icon {
7924
- color: var(--text-reverse-primary);
7925
- fill: var(--text-reverse-primary);
7926
- }
7927
- .zen-dropdown-list__action-button--selected .zen-dropdown-list__action-label {
7928
- color: var(--text-reverse-primary);
7929
- }
7930
7902
  .zen-dropdown-list__footer {
7931
7903
  display: flex;
7932
7904
  justify-content: flex-start;
@@ -62,11 +62,15 @@ const getPrevIndex = (currIndex, items) => {
62
62
  exports.getPrevIndex = getPrevIndex;
63
63
  const getFirstActiveIndex = (state, items, multiselect) => {
64
64
  for (let i = 0; i < items.length; i++) {
65
- if (state.get(items[i].id) === checkboxState_1.CheckboxState.On) {
65
+ if (!items[i].disabled && state.get(items[i].id) === checkboxState_1.CheckboxState.On) {
66
66
  return i;
67
67
  }
68
68
  }
69
- return multiselect && items.length > 0 ? 0 : -1;
69
+ if (multiselect && items.length > 0) {
70
+ const firstNonDisabled = items.findIndex(item => !item.disabled);
71
+ return firstNonDisabled >= 0 ? firstNonDisabled : 0;
72
+ }
73
+ return -1;
70
74
  };
71
75
  exports.getFirstActiveIndex = getFirstActiveIndex;
72
76
  const getItemsState = (items, value, multiselect) => {
@@ -371,8 +371,7 @@ export const CheckboxListWithAction = ({
371
371
  onClick: handleClick,
372
372
  title: title,
373
373
  className: classN,
374
- tabIndex: -1,
375
- disabled: option.blocked
374
+ tabIndex: -1
376
375
  }, otherArgs, {
377
376
  children: childEl
378
377
  })) : _jsx("div", {
@@ -20,4 +20,4 @@ export const Dropdown = (_a) => {
20
20
  var props = __rest(_a, []);
21
21
  return _jsx(DropDownFormField, Object.assign({}, props));
22
22
  };
23
- export const TRANSLATIONS = ["Filter by group", "Open filter", "Clear search", "Select all", "Clear", "Back", "No data"];
23
+ export const TRANSLATIONS = ["Filter by group", "Open filter", "Clear search", "Select all", "Deselect all", "Clear", "Back", "No data"];
@@ -13,9 +13,7 @@ export interface IDropdownList extends IZenComponentProps {
13
13
  onSelect: (id: string) => void;
14
14
  onSingleSelect: (reset: boolean, selected?: string) => void;
15
15
  backButtonName?: string;
16
- isAllSelected?: boolean;
17
- isSelectAllActive?: boolean;
18
- shouldBlockItems?: boolean;
16
+ isAllSelected: boolean;
19
17
  listData: ICheckboxListWithActionOption[] | ISelectListItem[];
20
18
  isWithFooter: boolean;
21
19
  width?: number;
@@ -41,6 +39,6 @@ interface IDropdownEmptyList extends Pick<IDropdownList, "className" | "width" |
41
39
  hasError: boolean;
42
40
  }
43
41
  export declare const EmptyList: ({ className, width, onClearClick, onApplyClick, onCancelClick, hasApplyButton, isApplyDisabled, isClearButtonDisabled, isWithFooter, hasError }: IDropdownEmptyList) => import("react/jsx-runtime").JSX.Element;
44
- export declare const DropdownList: ({ onBackButtonClick, onSelectAllClick, onClearClick, onApplyClick, onCancelClick, onChange, onSelect, onSingleSelect, listData, isSelectAllActive, shouldBlockItems, backButtonName, width, minWidth, isSelectAllButtonDisable, hasSelectAllButton, filterName, isMultiselect, hasApplyButton, isApplyDisabled, isClearButtonDisabled, activeValue, forceSelection, isWithFooter, isMobile, handleCheckboxChange, checkboxLabel, isChecked, listElementRef, listId }: IDropdownList) => import("react/jsx-runtime").JSX.Element;
42
+ export declare const DropdownList: ({ onBackButtonClick, onSelectAllClick, onClearClick, onApplyClick, onCancelClick, onChange, onSelect, onSingleSelect, listData, isAllSelected, backButtonName, width, minWidth, isSelectAllButtonDisable, hasSelectAllButton, filterName, isMultiselect, hasApplyButton, isApplyDisabled, isClearButtonDisabled, activeValue, forceSelection, isWithFooter, isMobile, handleCheckboxChange, checkboxLabel, isChecked, listElementRef, listId }: IDropdownList) => import("react/jsx-runtime").JSX.Element;
45
43
  export declare const TRANSLATIONS: string[];
46
44
  export {};
@@ -148,6 +148,33 @@ injectString("zh-Hans", "Apply", "\u5E94\u7528");
148
148
  injectString("zh-TW", "Apply", "\u5957\u7528");
149
149
  injectString("ro-RO", "Apply", "Aplica\u021Bi");
150
150
  injectString("ar-SA", "Apply", "\u062A\u0637\u0628\u064A\u0642");
151
+ injectString("cs", "Deselect all", "Zru\u0161it v\xFDb\u011Br v\u0161ech");
152
+ injectString("da-DK", "Deselect all", "Frav\xE6lg alle");
153
+ injectString("de", "Deselect all", "Auswahl f\xFCr alle aufheben");
154
+ injectString("en", "Deselect all", "Deselect all");
155
+ injectString("es", "Deselect all", "Deseleccionar todo");
156
+ injectString("fi-FI", "Deselect all", "Poista kaikki valinnat");
157
+ injectString("fr", "Deselect all", "D\xE9s\xE9lectionner tout");
158
+ injectString("fr-FR", "Deselect all", "D\xE9s\xE9lectionner tout");
159
+ injectString("hu-HU", "Deselect all", "Ne v\xE1lassz ki semmit.");
160
+ injectString("id", "Deselect all", "Batalkan pilih semua");
161
+ injectString("it", "Deselect all", "Deselezionare tutto");
162
+ injectString("ja", "Deselect all", "\u3059\u3079\u3066\u3092\u9078\u629E\u89E3\u9664");
163
+ injectString("ko-KR", "Deselect all", "\uBAA8\uB450 \uC120\uD0DD \uCDE8\uC18C");
164
+ injectString("ms", "Deselect all", "Nyahpilih semua");
165
+ injectString("nb-NO", "Deselect all", "Fjern alle valg");
166
+ injectString("nl", "Deselect all", "Alles deselecteren");
167
+ injectString("pl", "Deselect all", "Usu\u0144 wyb\xF3r wszystkich");
168
+ injectString("pt-BR", "Deselect all", "Desmarcar tudo");
169
+ injectString("pt-PT", "Deselect all", "Desmarcar tudo");
170
+ injectString("sk-SK", "Deselect all", "Zru\u0161 v\xFDber v\u0161etk\xFDch.");
171
+ injectString("sv", "Deselect all", "Avmarkera alla");
172
+ injectString("th", "Deselect all", "\u0E22\u0E01\u0E40\u0E25\u0E34\u0E01\u0E01\u0E32\u0E23\u0E40\u0E25\u0E37\u0E2D\u0E01\u0E17\u0E31\u0E49\u0E07\u0E2B\u0E21\u0E14");
173
+ injectString("tr", "Deselect all", "T\xFCm\xFCn\xFCn se\xE7imini iptal et");
174
+ injectString("zh-Hans", "Deselect all", "\u53D6\u6D88\u5168\u9009");
175
+ injectString("zh-TW", "Deselect all", "\u53D6\u6D88\u5168\u9078");
176
+ injectString("ro-RO", "Deselect all", "Deselecta\u021Bi tot");
177
+ injectString("ar-SA", "Deselect all", "\u0625\u0644\u063A\u0627\u0621 \u062A\u062D\u062F\u064A\u062F \u0627\u0644\u0643\u0644");
151
178
  injectString("cs", "Select all", "Vybrat v\u0161e");
152
179
  injectString("da-DK", "Select all", "V\xE6lg alle");
153
180
  injectString("de", "Select all", "Alle ausw\xE4hlen");
@@ -292,8 +319,7 @@ export const DropdownList = ({
292
319
  onSelect,
293
320
  onSingleSelect,
294
321
  listData,
295
- isSelectAllActive,
296
- shouldBlockItems,
322
+ isAllSelected,
297
323
  backButtonName,
298
324
  width,
299
325
  minWidth,
@@ -322,7 +348,7 @@ export const DropdownList = ({
322
348
  const internalListId = useId();
323
349
  const selectListId = listId || internalListId;
324
350
  const handleSelectAllClick = () => {
325
- onSelectAllClick(isSelectAllActive === true);
351
+ onSelectAllClick(isAllSelected);
326
352
  };
327
353
  const handleBackButtonKeyDown = useCallback(event => {
328
354
  if (event.key === "ArrowLeft") {
@@ -350,14 +376,13 @@ export const DropdownList = ({
350
376
  // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition
351
377
  forceSelection ? onSingleSelect(false, newActiveEl || activeValue) : onSingleSelect(false, newActiveEl);
352
378
  }, [activeValue, forceSelection, onSingleSelect]);
353
- const selectButtonLabel = translate("Select all");
354
- const getActionButton = (label, title, icon, isDisabled, clickHandler, size, onKeyDown, isSelected) => _jsx("button", {
379
+ const selectButtonLabel = isAllSelected ? translate("Deselect all") : translate("Select all");
380
+ const getActionButton = (label, title, icon, isDisabled, clickHandler, size, onKeyDown) => _jsx("button", {
355
381
  type: "button",
356
382
  disabled: isDisabled,
357
383
  onClick: clickHandler,
358
384
  onKeyDown: onKeyDown,
359
- "aria-pressed": isSelected,
360
- className: classNames(["zen-dropdown-list__item zen-dropdown-list__item--interactive zen-dropdown-list__action-button zen-dropdown-list__action-button-back", isSelected ? "zen-dropdown-list__action-button--selected" : ""]),
385
+ className: "zen-dropdown-list__item zen-dropdown-list__item--interactive zen-dropdown-list__action-button zen-dropdown-list__action-button-back",
361
386
  title: title,
362
387
  children: _jsxs(_Fragment, {
363
388
  children: [React.createElement(icon, {
@@ -393,15 +418,11 @@ export const DropdownList = ({
393
418
  });
394
419
  return values;
395
420
  };
396
- const multiselectOptions = shouldBlockItems ? listData.map(item => Object.assign(Object.assign({}, item), {
397
- blocked: true,
398
- checked: false
399
- })) : listData;
400
421
  return _jsx("div", {
401
422
  className: "zen-dropdown-list__elements",
402
423
  ref: listElementRef,
403
424
  children: isMultiselect ? _jsx(CheckboxListWithAction, {
404
- options: multiselectOptions,
425
+ options: listData,
405
426
  label: "",
406
427
  onChange: handleChange,
407
428
  onClick: handleClick
@@ -417,7 +438,7 @@ export const DropdownList = ({
417
438
  value: createValue(listData, activeValue)
418
439
  })
419
440
  });
420
- }, [listElementRef, isMultiselect, shouldBlockItems, listData, handleChange, handleClick, handleSingleChange, translate, selectListId, forceSelection, activeValue]);
441
+ }, [listElementRef, isMultiselect, listData, handleChange, handleClick, handleSingleChange, translate, selectListId, forceSelection, activeValue]);
421
442
  return _jsxs("div", Object.assign({
422
443
  className: classNames(["zen-dropdown-list", driveComponentClass || ""])
423
444
  }, styleWidth, {
@@ -435,7 +456,7 @@ export const DropdownList = ({
435
456
  }) : null, backButtonName ? _jsx("div", {
436
457
  className: "zen-dropdown-list__item-wrapper",
437
458
  children: getActionButton(backButtonName, translate("Back"), IconBackArrow, false, onBackButtonClick, "large", handleBackButtonKeyDown)
438
- }) : null, hasSelectAllButton ? getActionButton(selectButtonLabel, selectButtonLabel, IconCheckRadio, !!isSelectAllButtonDisable, handleSelectAllClick, isDrive ? "huger" : "huge", undefined, isSelectAllActive) : null, listDataComponent, isWithFooter ? _jsxs("div", {
459
+ }) : null, hasSelectAllButton ? getActionButton(selectButtonLabel, selectButtonLabel, IconCheckRadio, !!isSelectAllButtonDisable, handleSelectAllClick, isDrive ? "huger" : "huge") : null, listDataComponent, isWithFooter ? _jsxs("div", {
439
460
  className: "zen-dropdown-list__footer",
440
461
  children: [_jsx(Button, {
441
462
  onClick: isMultiselect ? onClearClick : handleClearClick,
@@ -463,4 +484,4 @@ export const DropdownList = ({
463
484
  }) : null]
464
485
  }));
465
486
  };
466
- export const TRANSLATIONS = ["Select all", "Clear", "Back", "No data"];
487
+ export const TRANSLATIONS = ["Select all", "Deselect all", "Clear", "Back", "No data"];
@@ -8,7 +8,7 @@ import { getInitialState, stateReducer, ROOT_GROUP_ID } from "./stateReducer/sta
8
8
  import { StateActionType } from "./stateReducer/stateActionType";
9
9
  import { FOCUSABLE_SELECTOR } from "../utils/focusableSelector";
10
10
  import { useEscape } from "../commonHelpers/hooks/useEscape";
11
- import { checkIsDataProblem, compareObjectsArrays, compareStringsArrays, createListDataOptions, getListDataWithDisabled, getSelectedCount, getStringFromAllSelected, getStringFromSelected, isAllChildrenSelected, isAllItemsHasOneParent, isEveryItemSelected, prepareSelectedIdsToItems, sortDropdownItemArray } from "./dropdownHelper";
11
+ import { checkIsDataProblem, compareObjectsArrays, compareStringsArrays, createListDataOptions, getDataForChange, getListDataWithDisabled, getSelectedCount, getStringFromAllSelected, getStringFromSelected, isAllChildrenSelected, isAllItemsHasOneParent, isEveryItemSelected, prepareSelectedIdsToItems, sortDropdownItemArray } from "./dropdownHelper";
12
12
  import { DropdownTrigger } from "./dropdownTrigger";
13
13
  import { isFocusable } from "../dialog/dialogHelpers";
14
14
  import { useLanguage } from "../utils/localization/useLanguage";
@@ -391,6 +391,23 @@ export const DropdownRaw = props => {
391
391
  payload: state.currentId || state.rootId
392
392
  });
393
393
  }, [isFullSelectionMode, state.currentId, state.rootId]);
394
+ const handleSelectAllInSearch = useCallback(isAllSelect => {
395
+ if (isFullSelectionMode && state.isAllSelected) {
396
+ dispatchState({
397
+ type: StateActionType.DeselectItemsFromAllSelected,
398
+ payload: undefined
399
+ });
400
+ return;
401
+ }
402
+ const dataForChange = getDataForChange(getListDataWithDisabled(state.listData, state.isNestedList), state.selectedIds, isAllSelect);
403
+ dispatchState({
404
+ type: StateActionType.ChangeBulkSelection,
405
+ payload: {
406
+ itemsIds: dataForChange,
407
+ value: !isAllSelect
408
+ }
409
+ });
410
+ }, [isFullSelectionMode, state.isAllSelected, state.listData, state.isNestedList, state.selectedIds]);
394
411
  const handleClearClick = useCallback(() => {
395
412
  var _a, _b;
396
413
  dispatchState({
@@ -837,14 +854,13 @@ export const DropdownRaw = props => {
837
854
  });
838
855
  }
839
856
  if (state.showList) {
840
- const isSearchMode = Boolean(state.inputValue) && !state.currentId;
857
+ const isSearchMode = state.inputValue && !state.currentId;
841
858
  const currentListData = createListDataOptions(state, translate, isSearchMode ? sortDropdownItemArray(state.listData, sortFn).slice(0, listLimit).filter(el => el.id !== state.rootId) :
842
859
  // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition
843
860
  sortDropdownItemArray(((_b = state.groupsMap[state.currentId || state.rootId]) === null || _b === void 0 ? void 0 : _b.children) || [], sortFn).slice(0, listLimit) || [], multiselect, currentAllSelected);
844
- const selectAllActiveForCurrentLevel = state.selectAllActiveForId === (state.currentId || state.rootId);
845
861
  return _jsx(DropdownList, {
846
862
  onBackButtonClick: handleBackButtonClick,
847
- onSelectAllClick: handleSelectAllClick,
863
+ onSelectAllClick: isSearchMode ? handleSelectAllInSearch : handleSelectAllClick,
848
864
  onClearClick: handleClearClick,
849
865
  onCancelClick: handleCancelClick,
850
866
  onApplyClick: handleApplyClick,
@@ -855,8 +871,6 @@ export const DropdownRaw = props => {
855
871
  backButtonName: state.currentId && state.groupsMap[state.currentId] ? getGroupDescription(state.groupsMap[state.currentId], translate) : undefined,
856
872
  filterName: isMobile ? undefined : filterName,
857
873
  isAllSelected: currentAllSelected ? currentAllSelected : isSearchMode ? isEveryItemSelected(getListDataWithDisabled(state.listData, state.isNestedList), state.selectedIds) : currentAllSelected === undefined ? isAllChildrenSelected(state, state.currentId || state.rootId) : false,
858
- isSelectAllActive: isFullSelectionMode ? currentAllSelected : selectAllActiveForCurrentLevel,
859
- shouldBlockItems: !state.inputValue && !isFullSelectionMode && selectAllActiveForCurrentLevel,
860
874
  isMultiselect: multiselect,
861
875
  forceSelection: forceSelection,
862
876
  listData: currentListData,
@@ -865,7 +879,7 @@ export const DropdownRaw = props => {
865
879
  hasSelectAllButton: selectAllButton && multiselect,
866
880
  hasApplyButton: hasApplyButton,
867
881
  isApplyDisabled: memoizedIsApplyButtonDisabled,
868
- isSelectAllButtonDisable: currentListData.length === 0 || isSearchMode && state.isNestedList && isAllItemsHasOneParent(state.listData.filter(el => el.id !== state.rootId), (((_c = state.groupsMap[state.rootId]) === null || _c === void 0 ? void 0 : _c.children) || []).map(el => el.id)),
882
+ isSelectAllButtonDisable: currentListData.length === 0 || isSearchMode !== "" && state.isNestedList && isAllItemsHasOneParent(state.listData.filter(el => el.id !== state.rootId), (((_c = state.groupsMap[state.rootId]) === null || _c === void 0 ? void 0 : _c.children) || []).map(el => el.id)),
869
883
  isClearButtonDisabled: memoizedIsClearButtonDisabled,
870
884
  isWithFooter: memoizedWithFooter && !isMobile,
871
885
  isMobile: isMobile,
@@ -877,7 +891,7 @@ export const DropdownRaw = props => {
877
891
  });
878
892
  }
879
893
  return null;
880
- }, [state, isLoading, isQueryMode, fetchState === null || fetchState === void 0 ? void 0 : fetchState.isLoading, fetchState === null || fetchState === void 0 ? void 0 : fetchState.error, handleClearClick, handleCancelClick, handleApplyClick, hasApplyButton, memoizedWithFooter, translate, sortFn, listLimit, multiselect, currentAllSelected, handleBackButtonClick, handleSelectAllClick, handleSelect, handleChangeCurrentId, handleSingleSelection, isMobile, filterName, forceSelection, width, selectAllButton, memoizedIsApplyButtonDisabled, memoizedIsClearButtonDisabled, isCheckboxMode, handleCheckboxChange, checkboxLabel, selectListId, isFullSelectionMode]);
894
+ }, [state, isLoading, isQueryMode, fetchState === null || fetchState === void 0 ? void 0 : fetchState.isLoading, fetchState === null || fetchState === void 0 ? void 0 : fetchState.error, handleClearClick, handleCancelClick, handleApplyClick, hasApplyButton, memoizedWithFooter, translate, sortFn, listLimit, multiselect, currentAllSelected, handleBackButtonClick, handleSelectAllInSearch, handleSelectAllClick, handleSelect, handleChangeCurrentId, handleSingleSelection, isMobile, filterName, forceSelection, width, selectAllButton, memoizedIsApplyButtonDisabled, memoizedIsClearButtonDisabled, isCheckboxMode, handleCheckboxChange, checkboxLabel, selectListId]);
881
895
  const currentStringFromSelected = isFullSelectionMode && hasApplyButton && state.globalIsAllSelected || isFullSelectionMode && !hasApplyButton && state.isAllSelected ? getStringFromAllSelected(state.groupsMap, translate, state.rootId) : getStringFromSelected(hasApplyButton ? state.globalSelectedIds : state.selectedIds, state.groupsMapSelected, translate, state.rootId);
882
896
  const memoizedCurrentSelection = useMemo(() => showSelection && !state.inputValue ? currentStringFromSelected : "", [showSelection, state.inputValue, currentStringFromSelected]);
883
897
  const parentTriggerWidth = ((_b = comboboxRef.current) === null || _b === void 0 ? void 0 : _b.getBoundingClientRect().width) || 420;
@@ -974,4 +988,4 @@ export const DropdownRaw = props => {
974
988
  });
975
989
  };
976
990
  DropdownRaw.displayName = "DropdownRaw";
977
- export const TRANSLATIONS = ["Filter by group", "Open filter", "Clear search", "Select all", "Clear", "Back", "No data"];
991
+ export const TRANSLATIONS = ["Filter by group", "Open filter", "Clear search", "Select all", "Deselect all", "Clear", "Back", "No data"];
@@ -25,7 +25,6 @@ export interface IDropdownState {
25
25
  listLimit: number;
26
26
  resultsExceedListLimit?: boolean;
27
27
  isAllSelected?: boolean;
28
- selectAllActiveForId?: string;
29
28
  globalIsAllSelected?: boolean;
30
29
  defaultValueIsAllSelected?: boolean;
31
30
  isChecked?: boolean;
@@ -1,5 +1,5 @@
1
1
  import { StateActionType } from "./stateActionType";
2
- import { getChildList, getRootId, computeIsAllSelected } from "./stateReducerHelper";
2
+ import { getChildList, updateAllSelectedStateValueBasedOnTotalSelected, getRootId } from "./stateReducerHelper";
3
3
  import { createGroupsMap } from "../../groupsFilterRaw/groupsFilterHelper";
4
4
  export const ROOT_GROUP_ID = "zen_dropdown_root_group_id";
5
5
  export const getInitialState = (isFullSelectionMode, comboItems, selection, listLimit, defaultValue, isAllSelected, defaultValueIsAllSelected, isChecked, defaultValueIsChecked, firstParentNodeIsVisible) => {
@@ -73,12 +73,10 @@ export function stateReducer(state, action) {
73
73
  }
74
74
  const isCurrentListNested = Object.keys(updatedGroupsMap).length > 0 &&
75
75
  (updatedGroupsMap[ROOT_GROUP_ID].children || []).some(el => el.children && el.children.length);
76
- const groupsMapLength = Object.keys(updatedGroupsMap).length - 1;
77
- const newResultsExceedListLimit = groupsMapLength >= state.listLimit;
78
- const selectedInNewMap = state.selectedIds.filter(id => id in updatedGroupsMap).length;
79
- const newIsAllSelected = computeIsAllSelected(state.isAllSelected, state.isFullSelectionMode, newResultsExceedListLimit, groupsMapLength, selectedInNewMap);
76
+ state.groupsMap = updatedGroupsMap;
77
+ const additionalStateUpdates = updateAllSelectedStateValueBasedOnTotalSelected(state, state.selectedIds.length - newNamelessIds.size);
80
78
  const rootId = getRootId(updatedGroupsMap, ROOT_GROUP_ID, state.firstParentNodeIsVisible);
81
- return Object.assign(Object.assign({}, state), { groupsMap: updatedGroupsMap, rootId: rootId || ROOT_GROUP_ID, namelessIds: newNamelessIds, isNestedList: state.isNestedList ? state.isNestedList : isCurrentListNested, resultsExceedListLimit: newResultsExceedListLimit, isAllSelected: newIsAllSelected });
79
+ return Object.assign(Object.assign(Object.assign({}, state), { rootId: rootId || ROOT_GROUP_ID, namelessIds: newNamelessIds, isNestedList: state.isNestedList ? state.isNestedList : isCurrentListNested, resultsExceedListLimit: Object.keys(updatedGroupsMap).length - 1 >= state.listLimit }), additionalStateUpdates);
82
80
  }
83
81
  case StateActionType.SetListData: {
84
82
  state.selectedIds.forEach(id => {
@@ -103,9 +101,9 @@ export function stateReducer(state, action) {
103
101
  case StateActionType.SetIsOpenCombo:
104
102
  return Object.assign(Object.assign({}, state), { isOpenCombo: payload });
105
103
  case StateActionType.ResetSelection:
106
- return Object.assign(Object.assign({}, state), { selectedIds: [...state.defaultValue], isAllSelected: state.defaultValueIsAllSelected, isChecked: typeof state.isChecked === "boolean" ? state.defaultValueIsChecked || false : undefined, selectAllActiveForId: undefined });
104
+ return Object.assign(Object.assign({}, state), { selectedIds: [...state.defaultValue], isAllSelected: state.defaultValueIsAllSelected, isChecked: typeof state.isChecked === "boolean" ? state.defaultValueIsChecked || false : undefined });
107
105
  case StateActionType.ResetStateToGlobal:
108
- return Object.assign(Object.assign({}, state), { selectedIds: [...state.globalSelectedIds], isAllSelected: state.globalIsAllSelected, isChecked: state.globalIsChecked, selectAllActiveForId: undefined });
106
+ return Object.assign(Object.assign({}, state), { selectedIds: [...state.globalSelectedIds], isAllSelected: state.globalIsAllSelected, isChecked: state.globalIsChecked });
109
107
  case StateActionType.NothingToShow:
110
108
  return Object.assign(Object.assign({}, state), { showWaiting: false, showEmptyList: false, showList: false });
111
109
  case StateActionType.Show:
@@ -221,7 +219,8 @@ export function stateReducer(state, action) {
221
219
  state.groupsMapSelected.set(id, Object.assign(Object.assign({ id }, (item.name ? { name: item.name } : {})), (item.color ? { color: item.color } : {})));
222
220
  }
223
221
  });
224
- return Object.assign(Object.assign({}, state), { selectedIds: Array.from(currentSelectedIds), selectAllActiveForId: undefined, isAllSelected: state.isAllSelected });
222
+ const additionalStateUpdates = updateAllSelectedStateValueBasedOnTotalSelected(state, currentSelectedIds.size);
223
+ return Object.assign(Object.assign(Object.assign({}, state), { selectedIds: Array.from(currentSelectedIds) }), additionalStateUpdates);
225
224
  }
226
225
  case StateActionType.ChangeBulkSelection: {
227
226
  const { itemsIds, value } = payload;
@@ -254,7 +253,8 @@ export function stateReducer(state, action) {
254
253
  state.groupsMapSelected.set(id, Object.assign(Object.assign({ id }, (item.name ? { name: item.name } : {})), (item.color ? { color: item.color } : {})));
255
254
  }
256
255
  });
257
- return Object.assign(Object.assign({}, state), { selectedIds: Array.from(currentSelectedIds), selectAllActiveForId: undefined });
256
+ const additionalStateUpdates = updateAllSelectedStateValueBasedOnTotalSelected(state, currentSelectedIds.size);
257
+ return Object.assign(Object.assign(Object.assign({}, state), { selectedIds: Array.from(currentSelectedIds) }), additionalStateUpdates);
258
258
  }
259
259
  case StateActionType.SelectAllChildren: {
260
260
  const currentEl = state.groupsMap[payload];
@@ -291,7 +291,7 @@ export function stateReducer(state, action) {
291
291
  state.groupsMapSelected.set(id, Object.assign(Object.assign({ id }, (item.name ? { name: item.name } : {})), (item.color ? { color: item.color } : {})));
292
292
  }
293
293
  });
294
- return Object.assign(Object.assign({}, state), { selectedIds: Array.from(newSelected), selectAllActiveForId: payload });
294
+ return Object.assign(Object.assign({}, state), { selectedIds: Array.from(newSelected) });
295
295
  }
296
296
  case StateActionType.DeselectItemsFromAllSelected: {
297
297
  const currentEl = state.groupsMap[state.rootId];
@@ -315,7 +315,7 @@ export function stateReducer(state, action) {
315
315
  state.groupsMapSelected.set(id, Object.assign(Object.assign({ id }, (item.name ? { name: item.name } : {})), (item.color ? { color: item.color } : {})));
316
316
  }
317
317
  });
318
- return Object.assign(Object.assign({}, state), { selectedIds: Array.from(newSelected), isAllSelected: state.isFullSelectionMode ? false : undefined, selectAllActiveForId: undefined });
318
+ return Object.assign(Object.assign({}, state), { selectedIds: Array.from(newSelected), isAllSelected: state.isFullSelectionMode ? false : undefined });
319
319
  }
320
320
  case StateActionType.ToggleValueForAllSelected: {
321
321
  const currentEl = state.groupsMap[state.rootId];
@@ -334,7 +334,8 @@ export function stateReducer(state, action) {
334
334
  }
335
335
  });
336
336
  const updatedIsAllSelectedValue = state.isFullSelectionMode ? !state.isAllSelected : undefined;
337
- return Object.assign(Object.assign({}, state), { selectedIds: state.isAllSelected ? Array.from(newSelected) : [], isAllSelected: updatedIsAllSelectedValue });
337
+ const additionalStateUpdates = updateAllSelectedStateValueBasedOnTotalSelected(state, newSelected.size);
338
+ return Object.assign(Object.assign(Object.assign({}, state), { selectedIds: state.isAllSelected ? Array.from(newSelected) : [], isAllSelected: updatedIsAllSelectedValue }), additionalStateUpdates);
338
339
  }
339
340
  case StateActionType.DeselectAllChildren: {
340
341
  const childrenForDeselect = [];
@@ -346,7 +347,7 @@ export function stateReducer(state, action) {
346
347
  });
347
348
  const newSelected = new Set(state.selectedIds);
348
349
  childrenForDeselect.forEach(childId => newSelected.delete(childId));
349
- return Object.assign(Object.assign({}, state), { selectedIds: Array.from(newSelected), selectAllActiveForId: undefined });
350
+ return Object.assign(Object.assign({}, state), { selectedIds: Array.from(newSelected) });
350
351
  }
351
352
  case StateActionType.SetFirstParentNodeIsVisible: {
352
353
  if (state.firstParentNodeIsVisible === payload) {
@@ -1,5 +1,6 @@
1
+ import { IDropdownState } from "./stateReducer";
1
2
  import { IDropdownRawItem } from "../types";
2
3
  import { IGroupTree, ITypedHash } from "../../groupsFilterRaw/groupsFilterInterfaces";
3
4
  export declare function getChildList(childArr: IDropdownRawItem[] | undefined): IDropdownRawItem[];
4
- export declare const computeIsAllSelected: (currentIsAllSelected: boolean | undefined, isFullSelectionMode: boolean, resultsExceedListLimit: boolean | undefined, groupsMapLength: number, selectedCount: number) => boolean | undefined;
5
+ export declare const updateAllSelectedStateValueBasedOnTotalSelected: (state: IDropdownState, totalSelected: number) => Partial<Pick<IDropdownState, "isAllSelected">>;
5
6
  export declare const getRootId: (groupsMap: ITypedHash<IGroupTree>, rootIdKey: string, firstParentNodeIsVisible?: boolean) => string | undefined;
@@ -13,9 +13,16 @@ export function getChildList(childArr) {
13
13
  });
14
14
  return list;
15
15
  }
16
- export const computeIsAllSelected = (currentIsAllSelected, isFullSelectionMode, resultsExceedListLimit, groupsMapLength, selectedCount) => !resultsExceedListLimit && currentIsAllSelected === false && isFullSelectionMode && groupsMapLength > 0 && selectedCount >= groupsMapLength
17
- ? true
18
- : currentIsAllSelected;
16
+ export const updateAllSelectedStateValueBasedOnTotalSelected = (state, totalSelected) => {
17
+ const additionalStateUpdates = {};
18
+ const groupsMapLength = Object.keys(state.groupsMap).length - 1;
19
+ if (!state.resultsExceedListLimit && !state.isAllSelected && state.isFullSelectionMode && groupsMapLength > 0) {
20
+ if (totalSelected >= groupsMapLength) {
21
+ additionalStateUpdates.isAllSelected = true;
22
+ }
23
+ }
24
+ return additionalStateUpdates;
25
+ };
19
26
  export const getRootId = (groupsMap, rootIdKey, firstParentNodeIsVisible) => {
20
27
  var _a;
21
28
  if (Object.keys(groupsMap).length === 0) {
@@ -51,11 +51,15 @@ export const getPrevIndex = (currIndex, items) => {
51
51
  };
52
52
  export const getFirstActiveIndex = (state, items, multiselect) => {
53
53
  for (let i = 0; i < items.length; i++) {
54
- if (state.get(items[i].id) === CheckboxState.On) {
54
+ if (!items[i].disabled && state.get(items[i].id) === CheckboxState.On) {
55
55
  return i;
56
56
  }
57
57
  }
58
- return multiselect && items.length > 0 ? 0 : -1;
58
+ if (multiselect && items.length > 0) {
59
+ const firstNonDisabled = items.findIndex(item => !item.disabled);
60
+ return firstNonDisabled >= 0 ? firstNonDisabled : 0;
61
+ }
62
+ return -1;
59
63
  };
60
64
  export const getItemsState = (items, value, multiselect) => {
61
65
  let forceUncheck = false;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@geotab/zenith",
3
- "version": "3.10.0-beta.3",
3
+ "version": "3.10.0-beta.6",
4
4
  "description": "Zenith components library on React",
5
5
  "main": "dist/index.js",
6
6
  "types": "esm/index.d.ts",
@@ -118,8 +118,5 @@
118
118
  "last 1 firefox version",
119
119
  "last 1 safari version"
120
120
  ]
121
- },
122
- "publishConfig": {
123
- "access": "public"
124
121
  }
125
122
  }