@geotab/zenith 3.11.0-beta.1 → 3.11.1-beta.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (95) hide show
  1. package/README.md +8 -0
  2. package/dist/checkboxListWithAction/checkboxListWithAction.js +26 -27
  3. package/dist/dataGrid/withFlexibleColumns/components/columnSettingsList.js +116 -44
  4. package/dist/index.css +4 -1
  5. package/dist/menu/utils/useMenuItemCore.js +3 -1
  6. package/dist/pillExpandable/pillExpandable.js +1 -36
  7. package/dist/pillExpandable/pillExpandableSimple.d.ts +1 -2
  8. package/dist/pillExpandable/pillExpandableSimple.js +5 -3
  9. package/dist/selectList/selectList.actionTypes.d.ts +6 -1
  10. package/dist/selectList/selectList.actionTypes.js +1 -0
  11. package/dist/selectList/selectList.d.ts +1 -1
  12. package/dist/selectList/selectList.helpers.d.ts +1 -1
  13. package/dist/selectList/selectList.helpers.js +29 -4
  14. package/dist/selectList/selectList.js +464 -125
  15. package/dist/selectList/selectList.reducer.js +3 -2
  16. package/dist/selectList/selectListItem.d.ts +2 -1
  17. package/dist/selectList/selectListItem.js +19 -2
  18. package/dist/sortControl/sortControl.js +58 -2
  19. package/dist/summaryTile/summaryTile.d.ts +3 -1
  20. package/dist/summaryTile/summaryTile.js +2 -1
  21. package/dist/table/flexible/columnsList.js +4 -2
  22. package/dist/utils/localization/translations/ar.json +5 -1
  23. package/dist/utils/localization/translations/cs.json +5 -1
  24. package/dist/utils/localization/translations/da-DK.json +5 -1
  25. package/dist/utils/localization/translations/de.json +5 -1
  26. package/dist/utils/localization/translations/en.json +5 -1
  27. package/dist/utils/localization/translations/es.json +5 -1
  28. package/dist/utils/localization/translations/fi-FI.json +5 -1
  29. package/dist/utils/localization/translations/fr-FR.json +5 -1
  30. package/dist/utils/localization/translations/fr.json +5 -1
  31. package/dist/utils/localization/translations/hu-HU.json +5 -1
  32. package/dist/utils/localization/translations/id.json +5 -1
  33. package/dist/utils/localization/translations/it.json +5 -1
  34. package/dist/utils/localization/translations/ja.json +5 -1
  35. package/dist/utils/localization/translations/ko-KR.json +5 -1
  36. package/dist/utils/localization/translations/ms.json +5 -1
  37. package/dist/utils/localization/translations/nb-NO.json +5 -1
  38. package/dist/utils/localization/translations/nl.json +5 -1
  39. package/dist/utils/localization/translations/pl.json +5 -1
  40. package/dist/utils/localization/translations/pt-BR.json +5 -1
  41. package/dist/utils/localization/translations/pt-PT.json +5 -1
  42. package/dist/utils/localization/translations/ro-RO.json +5 -1
  43. package/dist/utils/localization/translations/sk-SK.json +5 -1
  44. package/dist/utils/localization/translations/sv.json +5 -1
  45. package/dist/utils/localization/translations/th.json +5 -1
  46. package/dist/utils/localization/translations/tr.json +5 -1
  47. package/dist/utils/localization/translations/zh-Hans.json +5 -1
  48. package/dist/utils/localization/translations/zh-TW.json +5 -1
  49. package/esm/checkboxListWithAction/checkboxListWithAction.js +26 -27
  50. package/esm/dataGrid/withFlexibleColumns/components/columnSettingsList.js +110 -43
  51. package/esm/menu/utils/useMenuItemCore.js +3 -1
  52. package/esm/pillExpandable/pillExpandable.js +1 -36
  53. package/esm/pillExpandable/pillExpandableSimple.d.ts +1 -2
  54. package/esm/pillExpandable/pillExpandableSimple.js +5 -3
  55. package/esm/selectList/selectList.actionTypes.d.ts +6 -1
  56. package/esm/selectList/selectList.actionTypes.js +1 -0
  57. package/esm/selectList/selectList.d.ts +1 -1
  58. package/esm/selectList/selectList.helpers.d.ts +1 -1
  59. package/esm/selectList/selectList.helpers.js +29 -4
  60. package/esm/selectList/selectList.js +460 -126
  61. package/esm/selectList/selectList.reducer.js +3 -2
  62. package/esm/selectList/selectListItem.d.ts +2 -1
  63. package/esm/selectList/selectListItem.js +19 -2
  64. package/esm/sortControl/sortControl.js +58 -2
  65. package/esm/summaryTile/summaryTile.d.ts +3 -1
  66. package/esm/summaryTile/summaryTile.js +2 -1
  67. package/esm/table/flexible/columnsList.js +4 -2
  68. package/esm/utils/localization/translations/ar.json +5 -1
  69. package/esm/utils/localization/translations/cs.json +5 -1
  70. package/esm/utils/localization/translations/da-DK.json +5 -1
  71. package/esm/utils/localization/translations/de.json +5 -1
  72. package/esm/utils/localization/translations/en.json +5 -1
  73. package/esm/utils/localization/translations/es.json +5 -1
  74. package/esm/utils/localization/translations/fi-FI.json +5 -1
  75. package/esm/utils/localization/translations/fr-FR.json +5 -1
  76. package/esm/utils/localization/translations/fr.json +5 -1
  77. package/esm/utils/localization/translations/hu-HU.json +5 -1
  78. package/esm/utils/localization/translations/id.json +5 -1
  79. package/esm/utils/localization/translations/it.json +5 -1
  80. package/esm/utils/localization/translations/ja.json +5 -1
  81. package/esm/utils/localization/translations/ko-KR.json +5 -1
  82. package/esm/utils/localization/translations/ms.json +5 -1
  83. package/esm/utils/localization/translations/nb-NO.json +5 -1
  84. package/esm/utils/localization/translations/nl.json +5 -1
  85. package/esm/utils/localization/translations/pl.json +5 -1
  86. package/esm/utils/localization/translations/pt-BR.json +5 -1
  87. package/esm/utils/localization/translations/pt-PT.json +5 -1
  88. package/esm/utils/localization/translations/ro-RO.json +5 -1
  89. package/esm/utils/localization/translations/sk-SK.json +5 -1
  90. package/esm/utils/localization/translations/sv.json +5 -1
  91. package/esm/utils/localization/translations/th.json +5 -1
  92. package/esm/utils/localization/translations/tr.json +5 -1
  93. package/esm/utils/localization/translations/zh-Hans.json +5 -1
  94. package/esm/utils/localization/translations/zh-TW.json +5 -1
  95. package/package.json +1 -1
@@ -1,16 +1,19 @@
1
1
  "use strict";
2
- var __rest = (this && this.__rest) || function (s, e) {
3
- var t = {};
4
- for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)
5
- t[p] = s[p];
6
- if (s != null && typeof Object.getOwnPropertySymbols === "function")
7
- for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {
8
- if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i]))
9
- t[p[i]] = s[p[i]];
10
- }
11
- return t;
2
+
3
+ const {
4
+ injectString
5
+ } = require("../utils/localization/translationsDictionary");
6
+ var __rest = this && this.__rest || function (s, e) {
7
+ var t = {};
8
+ for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0) t[p] = s[p];
9
+ if (s != null && typeof Object.getOwnPropertySymbols === "function") for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {
10
+ if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i])) t[p[i]] = s[p[i]];
11
+ }
12
+ return t;
12
13
  };
13
- Object.defineProperty(exports, "__esModule", { value: true });
14
+ Object.defineProperty(exports, "__esModule", {
15
+ value: true
16
+ });
14
17
  exports.PassiveSelectList = exports.SelectList = exports.defaultListItemHeight = void 0;
15
18
  const jsx_runtime_1 = require("react/jsx-runtime");
16
19
  const react_1 = require("react");
@@ -19,6 +22,60 @@ const classNames_1 = require("../commonHelpers/classNames/classNames");
19
22
  const keyboard_1 = require("../commonHelpers/keyboard");
20
23
  const selectList_actionTypes_1 = require("./selectList.actionTypes");
21
24
  const selectList_helpers_1 = require("./selectList.helpers");
25
+ injectString("cs", "Checked", "Za\u0161krtnuto");
26
+ injectString("da-DK", "Checked", "Markeret");
27
+ injectString("de", "Checked", "Aktiviert");
28
+ injectString("en", "Checked", "Checked");
29
+ injectString("es", "Checked", "Marcado");
30
+ injectString("fi-FI", "Checked", "Valittu");
31
+ injectString("fr", "Checked", "Coch\xE9");
32
+ injectString("fr-FR", "Checked", "Coch\xE9");
33
+ injectString("hu-HU", "Checked", "Bejel\xF6lve");
34
+ injectString("id", "Checked", "Dicentang");
35
+ injectString("it", "Checked", "Selezionato");
36
+ injectString("ja", "Checked", "\u30C1\u30A7\u30C3\u30AF\u6E08\u307F");
37
+ injectString("ko-KR", "Checked", "\uC120\uD0DD\uB428");
38
+ injectString("ms", "Checked", "Ditanda");
39
+ injectString("nb-NO", "Checked", "Merket");
40
+ injectString("nl", "Checked", "Aangevinkt");
41
+ injectString("pl", "Checked", "Zaznaczono");
42
+ injectString("pt-BR", "Checked", "Marcado");
43
+ injectString("pt-PT", "Checked", "Marcado");
44
+ injectString("sk-SK", "Checked", "Za\u0161krtnut\xE9");
45
+ injectString("sv", "Checked", "Markerad");
46
+ injectString("th", "Checked", "\u0E17\u0E33\u0E40\u0E04\u0E23\u0E37\u0E48\u0E2D\u0E07\u0E2B\u0E21\u0E32\u0E22\u0E41\u0E25\u0E49\u0E27");
47
+ injectString("tr", "Checked", "\u0130\u015Faretlendi");
48
+ injectString("zh-Hans", "Checked", "\u5DF2\u9009\u4E2D");
49
+ injectString("zh-TW", "Checked", "\u5DF2\u52FE\u9078");
50
+ injectString("ro-RO", "Checked", "Bifat");
51
+ injectString("ar-SA", "Checked", "\u0645\u062D\u062F\u062F");
52
+ injectString("cs", "Unchecked", "Neza\u0161krtnuto");
53
+ injectString("da-DK", "Unchecked", "Ikke markeret");
54
+ injectString("de", "Unchecked", "Deaktiviert");
55
+ injectString("en", "Unchecked", "Unchecked");
56
+ injectString("es", "Unchecked", "Sin marcar");
57
+ injectString("fi-FI", "Unchecked", "Ei valittu");
58
+ injectString("fr", "Unchecked", "Non coch\xE9");
59
+ injectString("fr-FR", "Unchecked", "Non coch\xE9");
60
+ injectString("hu-HU", "Unchecked", "Nincs bejel\xF6lve");
61
+ injectString("id", "Unchecked", "Tidak dicentang");
62
+ injectString("it", "Unchecked", "Non selezionato");
63
+ injectString("ja", "Unchecked", "\u672A\u30C1\u30A7\u30C3\u30AF");
64
+ injectString("ko-KR", "Unchecked", "\uC120\uD0DD \uC548 \uB428");
65
+ injectString("ms", "Unchecked", "Tidak ditanda");
66
+ injectString("nb-NO", "Unchecked", "Ikke merket");
67
+ injectString("nl", "Unchecked", "Niet aangevinkt");
68
+ injectString("pl", "Unchecked", "Odznaczono");
69
+ injectString("pt-BR", "Unchecked", "Desmarcado");
70
+ injectString("pt-PT", "Unchecked", "Desmarcado");
71
+ injectString("sk-SK", "Unchecked", "Neza\u0161krtnut\xE9");
72
+ injectString("sv", "Unchecked", "Avmarkerad");
73
+ injectString("th", "Unchecked", "\u0E22\u0E31\u0E07\u0E44\u0E21\u0E48\u0E44\u0E14\u0E49\u0E17\u0E33\u0E40\u0E04\u0E23\u0E37\u0E48\u0E2D\u0E07\u0E2B\u0E21\u0E32\u0E22");
74
+ injectString("tr", "Unchecked", "\u0130\u015Faretlenmedi");
75
+ injectString("zh-Hans", "Unchecked", "\u672A\u9009\u4E2D");
76
+ injectString("zh-TW", "Unchecked", "\u672A\u52FE\u9078");
77
+ injectString("ro-RO", "Unchecked", "Nebifat");
78
+ injectString("ar-SA", "Unchecked", "\u063A\u064A\u0631 \u0645\u062D\u062F\u062F");
22
79
  const selectList_reducer_1 = require("./selectList.reducer");
23
80
  const selectListItem_1 = require("./selectListItem");
24
81
  const isChildOf_1 = require("../utils/isChildOf");
@@ -26,129 +83,411 @@ const useDriveClassName_1 = require("../utils/theme/useDriveClassName");
26
83
  const react_2 = require("react");
27
84
  const getScrollableParent_1 = require("../utils/getScrollableParent");
28
85
  const zen_1 = require("../utils/zen");
86
+ const useLanguage_1 = require("../utils/localization/useLanguage");
87
+ const reactHelpers_1 = require("../commonHelpers/reactHelpers/reactHelpers");
29
88
  exports.defaultListItemHeight = 40;
30
89
  const MemoizedSelectListItem = (0, react_2.memo)(selectListItem_1.SelectListItem);
31
- const SelectListInnerComp = ({ id, items, value, disabled, activeIndex = -1, title, multiselect = false, showCheckbox = false, standalone, className = "", onClickItem, onChangeItem, onKeyDown, onFocus, onBlur, style = {}, ref: listRef }) => {
32
- var _a;
33
- const driveComponentClass = (0, useDriveClassName_1.useDriveClassName)("zen-select-list");
34
- const state = (0, selectList_helpers_1.getInitialState)({ items, value, multiselect });
35
- state.activeIndex = activeIndex;
36
- return ((0, jsx_runtime_1.jsx)("ul", { id: id, ref: listRef, className: (0, classNames_1.classNames)(["zen-select-list", driveComponentClass || "", className]), role: "listbox", "aria-multiselectable": multiselect, "aria-activedescendant": standalone ? (0, selectList_helpers_1.getItemIdByIndex)(state.itemsState, state.activeIndex) || ((_a = items.find(el => !el.disabled)) === null || _a === void 0 ? void 0 : _a.id) : undefined, "aria-label": title, "aria-disabled": disabled, tabIndex: standalone && !disabled ? 0 : -1, onKeyDown: onKeyDown, onFocus: onFocus, onBlur: onBlur, style: style, children: items.map((item, index) => ((0, react_1.createElement)(MemoizedSelectListItem, Object.assign({}, item, { className: (0, classNames_1.classNames)(["zen-select-list__item", item.className || ""]), key: item.id, showCheckbox: showCheckbox, state: state.itemsState.get(item.id), focused: state.activeIndex === index, onChange: onChangeItem, onClick: onClickItem }), item.children))) }));
90
+ const SelectListInnerComp = ({
91
+ id,
92
+ items,
93
+ value,
94
+ disabled,
95
+ activeIndex = -1,
96
+ title,
97
+ multiselect = false,
98
+ showCheckbox = false,
99
+ standalone,
100
+ className = "",
101
+ onClickItem,
102
+ onChangeItem,
103
+ onFocusItem,
104
+ onKeyDown,
105
+ onFocus,
106
+ onBlur,
107
+ style = {},
108
+ ref: listRef
109
+ }) => {
110
+ var _a;
111
+ const driveComponentClass = (0, useDriveClassName_1.useDriveClassName)("zen-select-list");
112
+ const state = (0, selectList_helpers_1.getInitialState)({
113
+ items,
114
+ value,
115
+ multiselect
116
+ });
117
+ state.activeIndex = activeIndex;
118
+ return (0, jsx_runtime_1.jsx)("ul", {
119
+ id: id,
120
+ ref: listRef,
121
+ className: (0, classNames_1.classNames)(["zen-select-list", driveComponentClass || "", className]),
122
+ role: showCheckbox ? "menu" : "listbox",
123
+ "aria-multiselectable": showCheckbox ? undefined : multiselect,
124
+ "aria-activedescendant": standalone && !showCheckbox ? (0, selectList_helpers_1.getItemIdByIndex)(state.itemsState, state.activeIndex) || ((_a = items.find(el => !el.disabled)) === null || _a === void 0 ? void 0 : _a.id) : undefined,
125
+ "aria-label": title,
126
+ "aria-disabled": disabled,
127
+ tabIndex: standalone && !disabled && !showCheckbox ? 0 : -1,
128
+ onKeyDown: onKeyDown,
129
+ onFocus: onFocus,
130
+ onBlur: onBlur,
131
+ style: style,
132
+ children: items.map((item, index) => (0, react_1.createElement)(MemoizedSelectListItem, Object.assign({}, item, {
133
+ className: (0, classNames_1.classNames)(["zen-select-list__item", item.className || ""]),
134
+ key: item.id,
135
+ showCheckbox: showCheckbox,
136
+ state: state.itemsState.get(item.id),
137
+ focused: state.activeIndex === index,
138
+ onChange: onChangeItem,
139
+ onClick: onClickItem,
140
+ onFocusItem: onFocusItem
141
+ }), item.children))
142
+ });
37
143
  };
38
144
  SelectListInnerComp.displayName = "SelectListInnerComp";
39
145
  const SelectListInner = (0, react_2.memo)(SelectListInnerComp);
40
- const SelectList = (_a) => {
41
- var { items: outerItems, value = new Map(), multiselect = false, selectItemOnFocus = true, forceSelection = false, disabled, onChange, onClick } = _a, rest = __rest(_a, ["items", "value", "multiselect", "selectItemOnFocus", "forceSelection", "disabled", "onChange", "onClick"]);
42
- const items = (0, react_2.useMemo)(() => outerItems, [outerItems]);
43
- const listRef = (0, react_2.useRef)(null);
44
- const [state, dispatchState] = (0, react_2.useReducer)(selectList_reducer_1.selectListReducer, { items, value, multiselect }, selectList_helpers_1.getInitialState);
45
- const innerValue = (0, react_2.useMemo)(() => JSON.stringify(Array.from((0, selectList_helpers_1.getInitialState)({ items, value, multiselect }).itemsState)), [items, value, multiselect]);
46
- (0, react_2.useEffect)(() => {
47
- const parsedValue = JSON.parse(innerValue);
48
- dispatchState({ type: selectList_actionTypes_1.ListAction.Reset, payload: { items, value: new Map(parsedValue), multiselect } });
49
- }, [innerValue, multiselect, items]);
50
- (0, react_2.useEffect)(() => {
51
- if (!multiselect && selectItemOnFocus) {
52
- dispatchState({ type: selectList_actionTypes_1.ListAction.FocusFirst, payload: { items } });
53
- }
54
- dispatchState({ type: selectList_actionTypes_1.ListAction.Focus, payload: { items, multiselect } });
55
- }, [multiselect, items, selectItemOnFocus]);
56
- (0, react_2.useEffect)(() => {
57
- onChange && state.isItemsStateChanged && onChange(new Map(state.itemsState));
58
- }, [state.isItemsStateChanged, state.itemsState, onChange]);
59
- const onChangeItem = (0, react_2.useCallback)((updatedId, updatedState) => {
60
- dispatchState({ type: selectList_actionTypes_1.ListAction.ChangeItemState, payload: { updatedId, updatedState, multiselect } });
61
- }, [multiselect]);
62
- const hasScrolledToInitial = (0, react_2.useRef)(false);
63
- (0, react_2.useEffect)(() => {
64
- var _a;
65
- if (state.activeIndex >= 0 && listRef.current) {
66
- const isFocusInList = ((_a = zen_1.zen.document) === null || _a === void 0 ? void 0 : _a.activeElement) && (0, isChildOf_1.isChildOf)(zen_1.zen.document.activeElement, listRef.current);
67
- if (isFocusInList || !hasScrolledToInitial.current) {
68
- const itemEl = listRef.current.querySelector(`.zen-select-list__item:nth-child(${state.activeIndex + 1})`);
69
- itemEl === null || itemEl === void 0 ? void 0 : itemEl.scrollIntoView({ block: "nearest" });
70
- if (itemEl) {
71
- hasScrolledToInitial.current = true;
72
- }
146
+ const SelectList = _a => {
147
+ var {
148
+ items: outerItems,
149
+ value = new Map(),
150
+ multiselect = false,
151
+ selectItemOnFocus = true,
152
+ forceSelection = false,
153
+ showCheckbox = false,
154
+ disabled,
155
+ onChange,
156
+ onClick
157
+ } = _a,
158
+ rest = __rest(_a, ["items", "value", "multiselect", "selectItemOnFocus", "forceSelection", "showCheckbox", "disabled", "onChange", "onClick"]);
159
+ const items = (0, react_2.useMemo)(() => outerItems, [outerItems]);
160
+ const listRef = (0, react_2.useRef)(null);
161
+ const {
162
+ translate
163
+ } = (0, useLanguage_1.useLanguage)();
164
+ const [announcement, setAnnouncement] = (0, react_2.useState)("");
165
+ const [state, dispatchState] = (0, react_2.useReducer)(selectList_reducer_1.selectListReducer, showCheckbox, isCheckbox => {
166
+ const initial = (0, selectList_helpers_1.getInitialState)({
167
+ items,
168
+ value,
169
+ multiselect
170
+ });
171
+ if (isCheckbox) {
172
+ initial.activeIndex = (0, selectList_helpers_1.getFirstIndex)(items);
173
+ }
174
+ return initial;
175
+ });
176
+ const innerValue = (0, react_2.useMemo)(() => JSON.stringify(Array.from((0, selectList_helpers_1.getInitialState)({
177
+ items,
178
+ value,
179
+ multiselect
180
+ }).itemsState)), [items, value, multiselect]);
181
+ (0, react_2.useEffect)(() => {
182
+ const parsedValue = JSON.parse(innerValue);
183
+ dispatchState({
184
+ type: selectList_actionTypes_1.ListAction.Reset,
185
+ payload: {
186
+ items,
187
+ value: new Map(parsedValue),
188
+ multiselect
189
+ }
190
+ });
191
+ }, [innerValue, multiselect, items]);
192
+ (0, react_2.useEffect)(() => {
193
+ if (showCheckbox) {
194
+ dispatchState({
195
+ type: selectList_actionTypes_1.ListAction.FocusFirst,
196
+ payload: {
197
+ items
198
+ }
199
+ });
200
+ }
201
+ // eslint-disable-next-line react-hooks/exhaustive-deps
202
+ }, [showCheckbox]);
203
+ (0, react_2.useEffect)(() => {
204
+ if (!showCheckbox) {
205
+ if (!multiselect && selectItemOnFocus) {
206
+ dispatchState({
207
+ type: selectList_actionTypes_1.ListAction.FocusFirst,
208
+ payload: {
209
+ items
210
+ }
211
+ });
212
+ }
213
+ if (!multiselect) {
214
+ dispatchState({
215
+ type: selectList_actionTypes_1.ListAction.Focus,
216
+ payload: {
217
+ items,
218
+ multiselect
219
+ }
220
+ });
221
+ }
222
+ }
223
+ }, [multiselect, items, selectItemOnFocus, showCheckbox]);
224
+ (0, react_2.useEffect)(() => {
225
+ onChange && state.isItemsStateChanged && onChange(new Map(state.itemsState));
226
+ }, [state.isItemsStateChanged, state.itemsState, onChange]);
227
+ // VoiceOver does not announce aria-checked changes on role="menuitemcheckbox" (neither
228
+ // on toggle nor on navigation). Use a polite live region to announce the focused item's
229
+ // label + state whenever focus moves or state is toggled. The label is included so
230
+ // consecutive announcements of the same state still differ and get re-spoken.
231
+ (0, react_2.useEffect)(() => {
232
+ if (!showCheckbox || state.activeIndex < 0) {
233
+ return;
234
+ }
235
+ const itemId = (0, selectList_helpers_1.getItemIdByIndex)(state.itemsState, state.activeIndex);
236
+ if (!itemId) {
237
+ return;
238
+ }
239
+ const isChecked = state.itemsState.get(itemId) === checkboxState_1.CheckboxState.On;
240
+ const label = (0, reactHelpers_1.getComponentText)(items[state.activeIndex].children);
241
+ setAnnouncement(`${label} ${isChecked ? translate("Checked") : translate("Unchecked")}`);
242
+ }, [showCheckbox, state.itemsState, state.activeIndex, items, translate]);
243
+ const onChangeItem = (0, react_2.useCallback)((updatedId, updatedState) => {
244
+ dispatchState({
245
+ type: selectList_actionTypes_1.ListAction.ChangeItemState,
246
+ payload: {
247
+ updatedId,
248
+ updatedState,
249
+ multiselect
250
+ }
251
+ });
252
+ }, [multiselect]);
253
+ const onFocusItem = (0, react_2.useCallback)(id => {
254
+ const index = items.findIndex(item => item.id === id);
255
+ if (index >= 0) {
256
+ dispatchState({
257
+ type: selectList_actionTypes_1.ListAction.FocusItem,
258
+ payload: {
259
+ index
260
+ }
261
+ });
262
+ }
263
+ }, [items]);
264
+ const hasScrolledToInitial = (0, react_2.useRef)(false);
265
+ (0, react_2.useEffect)(() => {
266
+ var _a, _b;
267
+ if (state.activeIndex >= 0 && listRef.current) {
268
+ const isFocusInList = ((_a = zen_1.zen.document) === null || _a === void 0 ? void 0 : _a.activeElement) && (0, isChildOf_1.isChildOf)(zen_1.zen.document.activeElement, listRef.current);
269
+ if (isFocusInList || !hasScrolledToInitial.current) {
270
+ const itemEl = listRef.current.querySelector(`.zen-select-list__item:nth-child(${state.activeIndex + 1})`);
271
+ itemEl === null || itemEl === void 0 ? void 0 : itemEl.scrollIntoView({
272
+ block: "nearest"
273
+ });
274
+ if (showCheckbox && isFocusInList && ((_b = zen_1.zen.document) === null || _b === void 0 ? void 0 : _b.activeElement) !== itemEl) {
275
+ itemEl === null || itemEl === void 0 ? void 0 : itemEl.focus();
276
+ }
277
+ if (itemEl) {
278
+ hasScrolledToInitial.current = true;
279
+ }
280
+ }
281
+ }
282
+ }, [state.activeIndex, showCheckbox]);
283
+ (0, react_2.useEffect)(() => {
284
+ if (!state.level || !onClick) {
285
+ return;
286
+ }
287
+ onClick(state.level);
288
+ dispatchState({
289
+ type: selectList_actionTypes_1.ListAction.SetLevel,
290
+ payload: undefined
291
+ });
292
+ }, [onClick, state.level]);
293
+ const onKeyDown = e => {
294
+ const handlers = {
295
+ ArrowUp: () => multiselect || !selectItemOnFocus ? dispatchState({
296
+ type: selectList_actionTypes_1.ListAction.FocusPrev,
297
+ payload: {
298
+ items
299
+ }
300
+ }) : dispatchState({
301
+ type: selectList_actionTypes_1.ListAction.SelectPrev,
302
+ payload: {
303
+ items,
304
+ multiselect
305
+ }
306
+ }),
307
+ ArrowDown: () => multiselect || !selectItemOnFocus ? dispatchState({
308
+ type: selectList_actionTypes_1.ListAction.FocusNext,
309
+ payload: {
310
+ items
311
+ }
312
+ }) : dispatchState({
313
+ type: selectList_actionTypes_1.ListAction.SelectNext,
314
+ payload: {
315
+ items,
316
+ multiselect
317
+ }
318
+ }),
319
+ Enter: () => {
320
+ const item = items[state.activeIndex];
321
+ // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition
322
+ if (!item || item.disabled) {
323
+ return;
324
+ }
325
+ if (item.multiLevel) {
326
+ dispatchState({
327
+ type: selectList_actionTypes_1.ListAction.SetLevel,
328
+ payload: {
329
+ items
73
330
  }
331
+ });
332
+ } else {
333
+ dispatchState({
334
+ type: selectList_actionTypes_1.ListAction.ChangeItemState,
335
+ payload: {
336
+ updatedId: item.id,
337
+ updatedState: item.state === checkboxState_1.CheckboxState.On ? checkboxState_1.CheckboxState.Off : checkboxState_1.CheckboxState.On,
338
+ multiselect: multiselect
339
+ }
340
+ });
74
341
  }
75
- }, [state.activeIndex]);
76
- (0, react_2.useEffect)(() => {
77
- if (!state.level || !onClick) {
78
- return;
79
- }
80
- onClick(state.level);
81
- dispatchState({ type: selectList_actionTypes_1.ListAction.SetLevel, payload: undefined });
82
- }, [onClick, state.level]);
83
- const onKeyDown = (e) => {
84
- const handlers = {
85
- ArrowUp: () => multiselect || !selectItemOnFocus
86
- ? dispatchState({ type: selectList_actionTypes_1.ListAction.FocusPrev, payload: { items } })
87
- : dispatchState({ type: selectList_actionTypes_1.ListAction.SelectPrev, payload: { items, multiselect } }),
88
- ArrowDown: () => multiselect || !selectItemOnFocus
89
- ? dispatchState({ type: selectList_actionTypes_1.ListAction.FocusNext, payload: { items } })
90
- : dispatchState({ type: selectList_actionTypes_1.ListAction.SelectNext, payload: { items, multiselect } }),
91
- Enter: () => {
92
- const item = items[state.activeIndex];
93
- // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition
94
- if (!item || item.disabled) {
95
- return;
96
- }
97
- if (item.multiLevel) {
98
- dispatchState({ type: selectList_actionTypes_1.ListAction.SetLevel, payload: { items } });
99
- }
100
- else {
101
- dispatchState({
102
- type: selectList_actionTypes_1.ListAction.ChangeItemState,
103
- payload: {
104
- updatedId: item.id,
105
- updatedState: item.state === checkboxState_1.CheckboxState.On ? checkboxState_1.CheckboxState.Off : checkboxState_1.CheckboxState.On,
106
- multiselect: multiselect
107
- }
108
- });
109
- }
110
- },
111
- Home: () => multiselect || !selectItemOnFocus
112
- ? dispatchState({ type: selectList_actionTypes_1.ListAction.FocusFirst, payload: { items } })
113
- : dispatchState({ type: selectList_actionTypes_1.ListAction.SelectFirst, payload: { items, multiselect } }),
114
- End: () => multiselect || !selectItemOnFocus
115
- ? dispatchState({ type: selectList_actionTypes_1.ListAction.FocusLast, payload: { items } })
116
- : dispatchState({ type: selectList_actionTypes_1.ListAction.SelectLast, payload: { items, multiselect } }),
117
- Space: () => {
118
- const item = items[state.activeIndex];
119
- // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition
120
- if (item === null || item === void 0 ? void 0 : item.disabled) {
121
- return;
122
- }
123
- dispatchState({ type: selectList_actionTypes_1.ListAction.ToggleCurrent, payload: { multiselect } });
124
- },
125
- "Shift+ArrowUp": () => multiselect && dispatchState({ type: selectList_actionTypes_1.ListAction.SelectPrev, payload: { items, multiselect } }),
126
- "Shift+ArrowDown": () => multiselect && dispatchState({ type: selectList_actionTypes_1.ListAction.SelectNext, payload: { items, multiselect } }),
127
- "Ctrl+Shift+Home": () => multiselect && dispatchState({ type: selectList_actionTypes_1.ListAction.SelectAllToTheBeginning, payload: { items, multiselect } }),
128
- "Ctrl+Shift+End": () => multiselect && dispatchState({ type: selectList_actionTypes_1.ListAction.SelectAllToTheEnd, payload: { items, multiselect } }),
129
- "Ctrl+KeyA": () => multiselect && dispatchState({ type: selectList_actionTypes_1.ListAction.ToggleAll, payload: { items, multiselect } }),
130
- default: () => dispatchState({ type: selectList_actionTypes_1.ListAction.SearchItem, payload: { items, key: e.key } })
131
- };
132
- const handlerName = (0, keyboard_1.getKeysPressed)(e);
133
- const handler = handlers[handlerName] || ((0, keyboard_1.isKeyForSearch)(e.code) && handlers["default"]);
134
- if (handler) {
135
- handler();
136
- e.preventDefault();
137
- e.stopPropagation();
342
+ },
343
+ Home: () => multiselect || !selectItemOnFocus ? dispatchState({
344
+ type: selectList_actionTypes_1.ListAction.FocusFirst,
345
+ payload: {
346
+ items
138
347
  }
139
- };
140
- const onFocus = () => {
141
- const scrollableParent = (0, getScrollableParent_1.getScrollableParent)(listRef.current);
142
- if (!scrollableParent || scrollableParent.scrollTop === 0) {
143
- dispatchState({ type: selectList_actionTypes_1.ListAction.Focus, payload: { items, multiselect } });
348
+ }) : dispatchState({
349
+ type: selectList_actionTypes_1.ListAction.SelectFirst,
350
+ payload: {
351
+ items,
352
+ multiselect
144
353
  }
354
+ }),
355
+ End: () => multiselect || !selectItemOnFocus ? dispatchState({
356
+ type: selectList_actionTypes_1.ListAction.FocusLast,
357
+ payload: {
358
+ items
359
+ }
360
+ }) : dispatchState({
361
+ type: selectList_actionTypes_1.ListAction.SelectLast,
362
+ payload: {
363
+ items,
364
+ multiselect
365
+ }
366
+ }),
367
+ Space: () => {
368
+ const item = items[state.activeIndex];
369
+ // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition
370
+ if (item === null || item === void 0 ? void 0 : item.disabled) {
371
+ return;
372
+ }
373
+ dispatchState({
374
+ type: selectList_actionTypes_1.ListAction.ToggleCurrent,
375
+ payload: {
376
+ multiselect
377
+ }
378
+ });
379
+ },
380
+ "Shift+ArrowUp": () => multiselect && dispatchState({
381
+ type: selectList_actionTypes_1.ListAction.SelectPrev,
382
+ payload: {
383
+ items,
384
+ multiselect
385
+ }
386
+ }),
387
+ "Shift+ArrowDown": () => multiselect && dispatchState({
388
+ type: selectList_actionTypes_1.ListAction.SelectNext,
389
+ payload: {
390
+ items,
391
+ multiselect
392
+ }
393
+ }),
394
+ "Ctrl+Shift+Home": () => multiselect && dispatchState({
395
+ type: selectList_actionTypes_1.ListAction.SelectAllToTheBeginning,
396
+ payload: {
397
+ items,
398
+ multiselect
399
+ }
400
+ }),
401
+ "Ctrl+Shift+End": () => multiselect && dispatchState({
402
+ type: selectList_actionTypes_1.ListAction.SelectAllToTheEnd,
403
+ payload: {
404
+ items,
405
+ multiselect
406
+ }
407
+ }),
408
+ "Ctrl+KeyA": () => multiselect && dispatchState({
409
+ type: selectList_actionTypes_1.ListAction.ToggleAll,
410
+ payload: {
411
+ items,
412
+ multiselect
413
+ }
414
+ }),
415
+ default: () => dispatchState({
416
+ type: selectList_actionTypes_1.ListAction.SearchItem,
417
+ payload: {
418
+ items,
419
+ key: e.key
420
+ }
421
+ })
145
422
  };
146
- const onBlur = () => {
147
- multiselect && dispatchState({ type: selectList_actionTypes_1.ListAction.Blur, payload: { multiselect } });
148
- !multiselect && forceSelection && dispatchState({ type: selectList_actionTypes_1.ListAction.Blur, payload: { multiselect } });
149
- };
150
- return ((0, jsx_runtime_1.jsx)(SelectListInner, Object.assign({}, rest, { ref: listRef, value: state.itemsState, items: items, activeIndex: state.activeIndex, multiselect: multiselect, standalone: true, disabled: disabled, onChangeItem: onChangeItem, onClickItem: onClick, onKeyDown: onKeyDown, onFocus: onFocus, onBlur: onBlur })));
423
+ const handlerName = (0, keyboard_1.getKeysPressed)(e);
424
+ const handler = handlers[handlerName] || (0, keyboard_1.isKeyForSearch)(e.code) && handlers["default"];
425
+ if (handler) {
426
+ handler();
427
+ e.preventDefault();
428
+ e.stopPropagation();
429
+ }
430
+ };
431
+ const onFocus = () => {
432
+ const scrollableParent = (0, getScrollableParent_1.getScrollableParent)(listRef.current);
433
+ if (!scrollableParent || scrollableParent.scrollTop === 0) {
434
+ dispatchState({
435
+ type: selectList_actionTypes_1.ListAction.Focus,
436
+ payload: {
437
+ items,
438
+ multiselect
439
+ }
440
+ });
441
+ }
442
+ };
443
+ const onBlur = () => {
444
+ // In showCheckbox mode, activeIndex must stay stable while focus cycles between
445
+ // list items and sibling controls (e.g. Reset button) via Tab/Shift+Tab.
446
+ // Resetting activeIndex to -1 would drop all li tabIndex values to -1, making
447
+ // Shift+Tab unable to re-enter the list.
448
+ if (showCheckbox) {
449
+ return;
450
+ }
451
+ multiselect && dispatchState({
452
+ type: selectList_actionTypes_1.ListAction.Blur,
453
+ payload: {
454
+ multiselect
455
+ }
456
+ });
457
+ !multiselect && forceSelection && dispatchState({
458
+ type: selectList_actionTypes_1.ListAction.Blur,
459
+ payload: {
460
+ multiselect
461
+ }
462
+ });
463
+ };
464
+ return (0, jsx_runtime_1.jsxs)(jsx_runtime_1.Fragment, {
465
+ children: [(0, jsx_runtime_1.jsx)(SelectListInner, Object.assign({}, rest, {
466
+ ref: listRef,
467
+ value: state.itemsState,
468
+ items: items,
469
+ activeIndex: state.activeIndex,
470
+ multiselect: multiselect,
471
+ showCheckbox: showCheckbox,
472
+ standalone: true,
473
+ disabled: disabled,
474
+ onChangeItem: onChangeItem,
475
+ onClickItem: onClick,
476
+ onFocusItem: onFocusItem,
477
+ onKeyDown: onKeyDown,
478
+ onFocus: onFocus,
479
+ onBlur: onBlur
480
+ })), showCheckbox ? (0, jsx_runtime_1.jsx)("div", {
481
+ className: "zen-visually-hidden",
482
+ "aria-live": "polite",
483
+ "aria-atomic": "true",
484
+ role: "status",
485
+ children: announcement
486
+ }) : null]
487
+ });
151
488
  };
152
489
  exports.SelectList = SelectList;
153
- const PassiveSelectList = props => (0, jsx_runtime_1.jsx)(SelectListInnerComp, Object.assign({}, props, { standalone: false }));
154
- exports.PassiveSelectList = PassiveSelectList;
490
+ const PassiveSelectList = props => (0, jsx_runtime_1.jsx)(SelectListInnerComp, Object.assign({}, props, {
491
+ standalone: false
492
+ }));
493
+ exports.PassiveSelectList = PassiveSelectList;
@@ -60,6 +60,8 @@ const selectListReducer = (state, action) => {
60
60
  return Object.assign(Object.assign({}, state), { activeIndex: (0, selectList_helpers_1.getNextIndex)(state.activeIndex, payload.items), isItemsStateChanged: false, searchStr: "" });
61
61
  case selectList_actionTypes_1.ListAction.FocusPrev:
62
62
  return Object.assign(Object.assign({}, state), { activeIndex: (0, selectList_helpers_1.getPrevIndex)(state.activeIndex, payload.items), isItemsStateChanged: false, searchStr: "" });
63
+ case selectList_actionTypes_1.ListAction.FocusItem:
64
+ return Object.assign(Object.assign({}, state), { activeIndex: payload.index, isItemsStateChanged: false, searchStr: "" });
63
65
  case selectList_actionTypes_1.ListAction.SelectFirst: {
64
66
  const index = (0, selectList_helpers_1.getFirstIndex)(payload.items);
65
67
  return selectItem(state, index, payload.multiselect, (_a = payload.items[index]) === null || _a === void 0 ? void 0 : _a.disabled);
@@ -120,8 +122,7 @@ const selectListReducer = (state, action) => {
120
122
  newItemsState = updatedState;
121
123
  });
122
124
  const prevActiveItemId = (0, selectList_helpers_1.getItemIdByIndex)(state.itemsState, state.activeIndex);
123
- const newActiveItemIndex = !!prevActiveItemId && (0, selectList_helpers_1.getItemIndexById)(newItemsState, prevActiveItemId);
124
- const activeIndex = newActiveItemIndex ? newActiveItemIndex : -1;
125
+ const activeIndex = prevActiveItemId !== undefined ? (0, selectList_helpers_1.getItemIndexById)(newItemsState, prevActiveItemId) : -1;
125
126
  return Object.assign(Object.assign({}, state), { itemsState: newItemsState, activeIndex, isItemsStateChanged: false });
126
127
  }
127
128
  case selectList_actionTypes_1.ListAction.SetLevel: {
@@ -8,6 +8,7 @@ export interface ISelectListItem extends IZenIdComponentProps {
8
8
  focused?: boolean;
9
9
  onChange?: (id: string, state: CheckboxState) => void;
10
10
  onClick?: (id: string) => void;
11
+ onFocusItem?: (id: string) => void;
11
12
  multiLevel?: boolean;
12
13
  }
13
- export declare const SelectListItem: ({ id, disabled, state, showCheckbox, focused, onChange, onClick, multiLevel, className, children }: ISelectListItem) => import("react/jsx-runtime").JSX.Element;
14
+ export declare const SelectListItem: ({ id, disabled, state, showCheckbox, focused, onChange, onClick, onFocusItem, multiLevel, className, children }: ISelectListItem) => import("react/jsx-runtime").JSX.Element;