@geotab/zenith 3.6.0 → 3.6.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 (35) hide show
  1. package/README.md +11 -0
  2. package/dist/dataGrid/entitiesListActions/actions/fullscreenButton.js +3 -2
  3. package/dist/feedbackContainer/feedbackContainer.js +4 -2
  4. package/dist/formField/hooks/useContainer.js +2 -2
  5. package/dist/formField/types.d.ts +4 -0
  6. package/dist/index.css +13 -6
  7. package/dist/nav/navHeader/navHeaderSearch/navHeaderSearch.js +15 -0
  8. package/dist/pill/components/pillActionable/pillActionable.js +3 -13
  9. package/dist/pillExpandable/pillExpandable.js +2 -1
  10. package/dist/pillExpandable/pillExpandableSimple.d.ts +1 -1
  11. package/dist/pillExpandable/pillExpandableSimple.js +2 -2
  12. package/dist/selectList/selectList.helpers.d.ts +1 -1
  13. package/dist/selectList/selectList.helpers.js +12 -19
  14. package/dist/selectList/selectList.js +9 -2
  15. package/dist/selectList/selectList.reducer.d.ts +2 -2
  16. package/dist/selectList/selectList.reducer.js +21 -5
  17. package/dist/selectRaw/select.reducer.d.ts +2 -2
  18. package/dist/utils/localization/translations/en.json +3 -1
  19. package/esm/dataGrid/entitiesListActions/actions/fullscreenButton.js +3 -2
  20. package/esm/feedbackContainer/feedbackContainer.js +5 -3
  21. package/esm/formField/hooks/useContainer.js +2 -2
  22. package/esm/formField/types.d.ts +4 -0
  23. package/esm/nav/navHeader/navHeaderSearch/navHeaderSearch.js +15 -0
  24. package/esm/pill/components/pillActionable/pillActionable.js +3 -13
  25. package/esm/pillExpandable/pillExpandable.js +2 -1
  26. package/esm/pillExpandable/pillExpandableSimple.d.ts +1 -1
  27. package/esm/pillExpandable/pillExpandableSimple.js +2 -2
  28. package/esm/selectList/selectList.helpers.d.ts +1 -1
  29. package/esm/selectList/selectList.helpers.js +12 -19
  30. package/esm/selectList/selectList.js +9 -2
  31. package/esm/selectList/selectList.reducer.d.ts +2 -2
  32. package/esm/selectList/selectList.reducer.js +21 -5
  33. package/esm/selectRaw/select.reducer.d.ts +2 -2
  34. package/esm/utils/localization/translations/en.json +3 -1
  35. package/package.json +4 -4
package/README.md CHANGED
@@ -45,8 +45,19 @@ Now components are ready for usage.
45
45
 
46
46
  Zenith library provides components defined in Zenith Design System. It includes very basic blocks like colors, icons, font presets, atom components like buttons, checkboxes etc and high order components - header, table, filters bar etc. List of existing components can be found in [Storybook](https://developers.geotab.com/zenith-storybook/index.html).
47
47
 
48
+ ## Documentation
49
+
50
+ - [Development Guide](docs/DEVELOPMENT.md) - Creating components, adding icons, testing, code style
51
+ - [Build Process](docs/BUILD.md) - How the build system works
52
+ - [Release Process](docs/RELEASE.md) - How to publish new versions of Zenith
53
+ - [Translations](docs/TRANSLATIONS.md) - How translations work and how to manage them
54
+
48
55
  ## Change log
49
56
 
57
+ ### 3.6.1
58
+
59
+ Patch for the `Nav` component.
60
+
50
61
  ### 3.6.0
51
62
 
52
63
  Enhanced accessibility, improved component documentation, several component fixes and new mobile features.
@@ -17,6 +17,7 @@ const iconMinimize_1 = require("../../../icons/iconMinimize");
17
17
  const layoutFullScreenElementProvider_1 = require("../../../layout/layoutFullScreenElementProvider");
18
18
  const layoutFullScreenProvider_1 = require("../../../layout/layoutFullScreenProvider");
19
19
  const react_1 = require("react");
20
+ injectString("en", "Exit full screen table view", "Exit full screen table view");
20
21
  injectString("cs", "Convert table to full screen", "Konvertovat tabulku do re\u017Eimu pln\xE9ho zobrazen\xED");
21
22
  injectString("da-DK", "Convert table to full screen", "Konverter tabel til fuld sk\xE6rm");
22
23
  injectString("de", "Convert table to full screen", "Tabelle in Vollbild umwandeln");
@@ -71,10 +72,10 @@ const FullScreenButton = ({
71
72
  icon: getFullScreen() ? iconMinimize_1.IconMinimize : iconExpand_1.IconExpand,
72
73
  iconPosition: textIconButton_1.ButtonIconPosition.Start,
73
74
  iconSize: svgIconSize_1.SvgIconSize.Large,
74
- title: title ? title : translate("Convert table to full screen"),
75
+ title: title ? title : getFullScreen() ? translate("Exit full screen table view") : translate("Convert table to full screen"),
75
76
  type: buttonType_1.ButtonType.TertiaryBlack,
76
77
  onClick: handleClick
77
78
  });
78
79
  };
79
80
  exports.FullScreenButton = FullScreenButton;
80
- exports.FullScreenButton.translations = ["Convert table to full screen"];
81
+ exports.FullScreenButton.translations = ["Convert table to full screen", "Exit full screen table view"];
@@ -54,8 +54,10 @@ const FeedbackContainer = () => {
54
54
  if (isToastAdded) {
55
55
  removedToastId.current = null;
56
56
  }
57
- prevAlertsLength.current = alerts.length;
58
- prevToastsLength.current = toasts.length;
57
+ (0, react_1.useEffect)(() => {
58
+ prevAlertsLength.current = alerts.length;
59
+ prevToastsLength.current = toasts.length;
60
+ }, [alerts.length, toasts.length]);
59
61
  const alertsToRender = (0, react_1.useMemo)(() => alerts.map((alert, indx) => (0, jsx_runtime_1.jsx)(alertRaw_1.AlertRaw, { id: alert.id, header: alert.header, text: alert.text, isOpen: true, onClose: () => {
60
62
  removeAlert(alert.id);
61
63
  removedAlertId.current = indx;
@@ -28,7 +28,7 @@ const useFormFieldProps_1 = require("./useFormFieldProps");
28
28
  const useCounter_1 = require("./useCounter");
29
29
  const useContainer = (props, wrapperComponent) => {
30
30
  const { id, wrapperComponent: WrappedComponent, trailing, trailingId, showAdditionalInfo } = (0, useFormFieldProps_1.useFormFieldProps)(props, wrapperComponent);
31
- const { className, inputClassName } = props, rest = __rest(props, ["className", "inputClassName"]);
31
+ const { className, inputClassName, inputWrapperClassName } = props, rest = __rest(props, ["className", "inputClassName", "inputWrapperClassName"]);
32
32
  const { id: errorId, error, errorBanner } = (0, useError_1.useError)(props);
33
33
  const { id: bannerId, banner: bannerComp } = (0, useBanner_1.useBanner)(props);
34
34
  const { id: assistiveId, assistive } = (0, useAssistive_1.useAssistive)(props);
@@ -44,7 +44,7 @@ const useContainer = (props, wrapperComponent) => {
44
44
  const isInputContainerHidden = isReadonly && props.isError;
45
45
  const ref = props.ref;
46
46
  const banner = errorBanner || bannerComp;
47
- const container = (0, react_1.useMemo)(() => (0, jsx_runtime_1.jsxs)(jsx_runtime_1.Fragment, { children: [(0, jsx_runtime_1.jsxs)("div", { className: (0, classNames_1.classNames)(["zen-form-field__input-container", isReadonly ? "zen-form-field__input-container--review" : "", isInputContainerHidden ? "zen-form-field__input-container--hidden" : "", trailing ? "zen-form-field__input-container--with-trailing" : ""]), children: [(0, jsx_runtime_1.jsxs)("div", { children: [(0, jsx_runtime_1.jsx)(WrappedComponent, Object.assign({}, rest, disabledProps, { isReadOnly: isReadonly, id: id, className: componentClassName, ref: ref, isLoadingError: props.isError, isError: !!error, ariaDescribedby: ariaDescribedBy })), (0, jsx_runtime_1.jsx)(formFieldAdditionalInfo_1.FormFieldAdditionalInfo, { counterId: counterId, assistiveId: assistiveId, errorId: errorId, driveTextClass: driveTextClass, error: error, assistive: assistive, counter: counter, showAdditionalInfo: showAdditionalInfo })] }), (0, jsx_runtime_1.jsx)(trailingComponent_1.TrailingComponent, { hasCustomWidth: hasCustomWidth, id: trailingId, value: trailing, hasAdditionalInfo: !!showAdditionalInfo })] }), banner] }), [isReadonly, isInputContainerHidden, trailing, WrappedComponent, rest, disabledProps, id, componentClassName, ref, props.isError, error, ariaDescribedBy, counterId, assistiveId, errorId, driveTextClass, assistive, counter, showAdditionalInfo, hasCustomWidth, trailingId, banner]);
47
+ const container = (0, react_1.useMemo)(() => (0, jsx_runtime_1.jsxs)(jsx_runtime_1.Fragment, { children: [(0, jsx_runtime_1.jsxs)("div", { className: (0, classNames_1.classNames)(["zen-form-field__input-container", isReadonly ? "zen-form-field__input-container--review" : "", isInputContainerHidden ? "zen-form-field__input-container--hidden" : "", trailing ? "zen-form-field__input-container--with-trailing" : ""]), children: [(0, jsx_runtime_1.jsxs)("div", { className: (0, classNames_1.classNames)(["zen-form-field__input-wrapper", inputWrapperClassName || ""]), children: [(0, jsx_runtime_1.jsx)(WrappedComponent, Object.assign({}, rest, disabledProps, { isReadOnly: isReadonly, id: id, className: componentClassName, ref: ref, isLoadingError: props.isError, isError: !!error, ariaDescribedby: ariaDescribedBy })), (0, jsx_runtime_1.jsx)(formFieldAdditionalInfo_1.FormFieldAdditionalInfo, { counterId: counterId, assistiveId: assistiveId, errorId: errorId, driveTextClass: driveTextClass, error: error, assistive: assistive, counter: counter, showAdditionalInfo: showAdditionalInfo })] }), (0, jsx_runtime_1.jsx)(trailingComponent_1.TrailingComponent, { hasCustomWidth: hasCustomWidth, id: trailingId, value: trailing, hasAdditionalInfo: !!showAdditionalInfo })] }), banner] }), [isReadonly, isInputContainerHidden, trailing, inputWrapperClassName, props.isError, WrappedComponent, rest, disabledProps, id, componentClassName, ref, error, ariaDescribedBy, counterId, assistiveId, errorId, driveTextClass, assistive, counter, showAdditionalInfo, hasCustomWidth, trailingId, banner]);
48
48
  return container;
49
49
  };
50
50
  exports.useContainer = useContainer;
@@ -5,6 +5,10 @@ export type TLabelAlign = "left" | "top";
5
5
  interface IFormFieldBase extends PropsWithChildren {
6
6
  className?: string;
7
7
  inputClassName?: string;
8
+ /**
9
+ * @param inputWrapperClassName - className for the wrapper around the input, which also contains assistive text, error and counter
10
+ */
11
+ inputWrapperClassName?: string;
8
12
  error?: string;
9
13
  assistive?: string;
10
14
  counter?: string;
package/dist/index.css CHANGED
@@ -4102,6 +4102,7 @@
4102
4102
  width: 0;
4103
4103
  height: 0;
4104
4104
  opacity: 0;
4105
+ outline: none;
4105
4106
  }
4106
4107
  .zen-checkbox__box {
4107
4108
  display: flex;
@@ -4311,7 +4312,6 @@
4311
4312
  .zen-select-item[aria-disabled="true"] > .zen-select-item__wrapper {
4312
4313
  color: var(--text-button-disabled);
4313
4314
  fill: var(--text-button-disabled);
4314
- background-color: var(--backgrounds-main);
4315
4315
  }
4316
4316
  .zen-select-item:not(.zen-select-item--with-checkbox)[aria-selected="true"] > .zen-select-item__wrapper {
4317
4317
  color: var(--text-reverse-primary);
@@ -6054,6 +6054,10 @@
6054
6054
  .zen-pill-actionable:not(.zen-pill-actionable--disabled):not(.zen-pill-actionable--readonly):hover {
6055
6055
  cursor: pointer;
6056
6056
  }
6057
+ .zen-pill-actionable:has(.zen-pill-actionable__input:focus-visible) {
6058
+ outline: 1px solid var(--borders-form-field--active);
6059
+ outline-offset: 2px;
6060
+ }
6057
6061
  .zen-pill-actionable__input {
6058
6062
  position: absolute;
6059
6063
  left: -5000px;
@@ -6080,10 +6084,6 @@
6080
6084
  color: var(--text-reverse-primary);
6081
6085
  fill: var(--text-reverse-primary);
6082
6086
  }
6083
- .zen-pill-actionable--active.zen-pill-actionable--keyboard-nav {
6084
- outline: 1px solid var(--borders-form-field--active);
6085
- outline-offset: 2px;
6086
- }
6087
6087
  .zen-pill-actionable--readonly {
6088
6088
  color: var(--text-secondary);
6089
6089
  background-color: var(--backgrounds-content-0);
@@ -8583,7 +8583,8 @@
8583
8583
  .zen-status-pill__container--error:hover {
8584
8584
  border-color: var(--accents-error--detail);
8585
8585
  }
8586
- .zen-status-pill__container:focus-visible {
8586
+ .zen-status-pill__container:focus-visible,
8587
+ .zen-status-pill__container:focus-visible + .zen-status-pill__container {
8587
8588
  outline: none;
8588
8589
  border-color: var(--borders-form-field--active);
8589
8590
  }
@@ -15535,11 +15536,17 @@ button.zen-summary__clickable {
15535
15536
  flex: 1 1 100%;
15536
15537
  }
15537
15538
  .zen-nav-header-search {
15539
+ display: flex;
15540
+ flex-direction: row;
15541
+ gap: 4px;
15538
15542
  flex: 1 1 auto;
15539
15543
  }
15540
15544
  .zen-nav-header-search__input {
15541
15545
  flex: 1 1 auto;
15542
15546
  }
15547
+ .zen-nav-header-search__close-button {
15548
+ flex: 0 0 auto;
15549
+ }
15543
15550
  .zen-nav-section {
15544
15551
  display: flex;
15545
15552
  flex-direction: column;
@@ -42,7 +42,11 @@ injectString("tr", "Search", "Ara");
42
42
  injectString("zh-Hans", "Search", "\u641C\u7D22");
43
43
  injectString("zh-TW", "Search", "\u641C\u5C0B");
44
44
  injectString("ro-RO", "Search", "C\u0103uta\u021Bi");
45
+ injectString("en", "Close search", "Close search");
45
46
  const navItem_1 = require("../../navItem/navItem");
47
+ const iconClose_1 = require("../../../icons/iconClose");
48
+ const textIconButton_1 = require("../../../textIconButton/textIconButton");
49
+ const buttonType_1 = require("../../../button/buttonType");
46
50
  const NavHeaderSearch = ({
47
51
  className,
48
52
  onSearch
@@ -78,6 +82,10 @@ const NavHeaderSearch = ({
78
82
  onSearchToggle === null || onSearchToggle === void 0 ? void 0 : onSearchToggle(false);
79
83
  }
80
84
  }, [handleChange, onSearchToggle]);
85
+ const clearSearch = (0, react_1.useCallback)(() => {
86
+ handleChange("");
87
+ onSearchToggle === null || onSearchToggle === void 0 ? void 0 : onSearchToggle(false);
88
+ }, [handleChange, onSearchToggle]);
81
89
  return (0, jsx_runtime_1.jsxs)("div", {
82
90
  className: (0, classNames_1.classNames)(["zen-nav-header-search", className || ""]),
83
91
  children: [!searchOpen && !isMobile ? (0, jsx_runtime_1.jsx)(navItem_1.NavItem, {
@@ -97,6 +105,13 @@ const NavHeaderSearch = ({
97
105
  onChange: handleChange,
98
106
  onBlur: handleBlur,
99
107
  onKeyDown: handleKeyDown
108
+ }) : null, searchOpen && !isMobile ? (0, jsx_runtime_1.jsx)(textIconButton_1.TextIconButton, {
109
+ icon: iconClose_1.IconClose,
110
+ iconSize: "large",
111
+ onClick: clearSearch,
112
+ type: buttonType_1.ButtonType.TertiaryBlack,
113
+ title: translate("Close search"),
114
+ className: "zen-nav-header-search__close-button"
100
115
  }) : null]
101
116
  });
102
117
  };
@@ -25,7 +25,7 @@ const ActionablePill = ({ onChange, disabled, readonly, className, children, ico
25
25
  }
26
26
  onChange(e.target.checked);
27
27
  }, [onChange, readonly]);
28
- const onKeyDownHandler = (0, react_1.useCallback)((e) => {
28
+ const onKeyUpHandler = (0, react_1.useCallback)((e) => {
29
29
  if (e.key === "Enter" && !disabled && !readonly) {
30
30
  onChange(!active);
31
31
  return;
@@ -34,17 +34,7 @@ const ActionablePill = ({ onChange, disabled, readonly, className, children, ico
34
34
  e.preventDefault();
35
35
  onChange(!active);
36
36
  }
37
- }, [disabled, readonly, active, onChange]);
38
- const onKeyUpHandler = (0, react_1.useCallback)((e) => {
39
- var _a;
40
- if (e.key === "Tab" || e.key === "Enter" || e.key === " " || e.key === "ArrowRight" || e.key === "ArrowLeft" || e.key === "ArrowUp" || e.key === "ArrowDown") {
41
- (_a = ref.current) === null || _a === void 0 ? void 0 : _a.classList.add("zen-pill-actionable--keyboard-nav");
42
- }
43
- }, [ref]);
44
- const onBlurHandler = (0, react_1.useCallback)(() => {
45
- var _a;
46
- (_a = ref.current) === null || _a === void 0 ? void 0 : _a.classList.remove("zen-pill-actionable--keyboard-nav");
47
- }, [ref]);
37
+ }, [active, disabled, onChange, readonly]);
48
38
  // Only show title when icon is visible but text is hidden, or when explicit title is provided with hidden text
49
39
  const showTitle = hasIcon && isTextContentHidden;
50
40
  const titleValue = title || textContent;
@@ -54,6 +44,6 @@ const ActionablePill = ({ onChange, disabled, readonly, className, children, ico
54
44
  drivePillClass !== null && drivePillClass !== void 0 ? drivePillClass : "",
55
45
  (0, getActionablePillStateClassName_1.getActionablePillStateClassName)(!!disabled, !!readonly, active),
56
46
  className !== null && className !== void 0 ? className : ""
57
- ]), htmlFor: id, children: [(0, jsx_runtime_1.jsx)("input", { checked: active, onBlur: onBlurHandler, onKeyUp: onKeyUpHandler, onKeyDown: onKeyDownHandler, onChange: onChangeHandler, id: id, className: "zen-pill-actionable__input", type: "checkbox", disabled: disabled, readOnly: readonly }), (0, jsx_runtime_1.jsxs)("div", { className: (0, classNames_1.classNames)(["zen-pill-actionable__content-wrapper", contentClasses]), children: [(0, jsx_runtime_1.jsx)("div", { className: (0, classNames_1.classNames)(["zen-pill-text-content", driveTextClass !== null && driveTextClass !== void 0 ? driveTextClass : ""]), children: children }), svgIcon] })] }));
47
+ ]), htmlFor: id, children: [(0, jsx_runtime_1.jsx)("input", { checked: active, onKeyUp: onKeyUpHandler, onChange: onChangeHandler, id: id, className: "zen-pill-actionable__input", type: "checkbox", disabled: disabled, readOnly: readonly }), (0, jsx_runtime_1.jsxs)("div", { className: (0, classNames_1.classNames)(["zen-pill-actionable__content-wrapper", contentClasses]), children: [(0, jsx_runtime_1.jsx)("div", { className: (0, classNames_1.classNames)(["zen-pill-text-content", driveTextClass !== null && driveTextClass !== void 0 ? driveTextClass : ""]), children: children }), svgIcon] })] }));
58
48
  };
59
49
  exports.ActionablePill = ActionablePill;
@@ -353,7 +353,8 @@ const PillExpandableBase = ({
353
353
  text: hideCounterNumber ? "" : `${isFlat ? "+" : ""}${uniqueChildren}`,
354
354
  includeExpandIcon: false,
355
355
  type: type,
356
- errorHandler: errorHandler
356
+ errorHandler: errorHandler,
357
+ className: "zen-status-pill__counter"
357
358
  })]
358
359
  }), (0, jsx_runtime_1.jsx)(absolute_1.Absolute, {
359
360
  recalculateTrigger: isPopupContentReady,
@@ -12,7 +12,7 @@ interface IPillExpandableSimple extends IPillExpandable {
12
12
  descriptionId?: string;
13
13
  }
14
14
  export declare const PillExpandableSimple: {
15
- ({ onExpand, expandAriaText, text, expanded, includeExpandIcon, type, icon, isBeta, ref, descriptionId }: IPillExpandableSimple): import("react/jsx-runtime").JSX.Element;
15
+ ({ onExpand, expandAriaText, text, expanded, includeExpandIcon, type, icon, isBeta, ref, className, descriptionId }: IPillExpandableSimple): import("react/jsx-runtime").JSX.Element;
16
16
  displayName: string;
17
17
  };
18
18
  export {};
@@ -8,7 +8,7 @@ const iconChevronTop_1 = require("../icons/iconChevronTop");
8
8
  const iconChevronBottom_1 = require("../icons/iconChevronBottom");
9
9
  const iconException_1 = require("../icons/iconException");
10
10
  const classNames_1 = require("../commonHelpers/classNames/classNames");
11
- const PillExpandableSimple = ({ onExpand, expandAriaText, text, expanded, includeExpandIcon = true, type = "warning", icon = iconException_1.IconException, isBeta, ref, descriptionId }) => {
11
+ const PillExpandableSimple = ({ onExpand, expandAriaText, text, expanded, includeExpandIcon = true, type = "warning", icon = iconException_1.IconException, isBeta, ref, className, descriptionId }) => {
12
12
  const iconDriveClassName = (0, useDriveClassName_1.useDriveClassName)("icon");
13
13
  const containerDriveClassName = (0, useDriveClassName_1.useDriveClassName)("zen-status-pill__container");
14
14
  const onExpandHandler = (0, react_1.useCallback)(() => {
@@ -19,7 +19,7 @@ const PillExpandableSimple = ({ onExpand, expandAriaText, text, expanded, includ
19
19
  const iconSize = isBeta ? "big" : defaultIconSize;
20
20
  const hasText = (text || "").trim().length > 0;
21
21
  return (0, jsx_runtime_1.jsxs)("button", { type: "button", className: (0, classNames_1.classNames)([
22
- "zen-status-pill__container", `zen-status-pill__container--${type}`, containerDriveClassName || "", "zen-ellipsis"
22
+ "zen-status-pill__container", `zen-status-pill__container--${type}`, containerDriveClassName || "", className || "", "zen-ellipsis"
23
23
  ]), ref: ref, onClick: onExpandHandler, tabIndex: !includeExpandIcon ? -1 : undefined, "aria-describedby": descriptionId, children: [icon !== false && (0, jsx_runtime_1.jsx)("div", { className: (0, classNames_1.classNames)([
24
24
  "zen-status-pill__icon",
25
25
  `zen-status-pill__icon--${type}`,
@@ -5,7 +5,7 @@ export declare const getItemIdByIndex: (state: Map<string, CheckboxState>, index
5
5
  export declare const getItemIndexById: (state: Map<string, CheckboxState>, id: string) => number;
6
6
  export declare const updateItemState: (initialState: Map<string, CheckboxState>, multiselect: boolean, updatedId: string, newState: CheckboxState) => [Map<string, CheckboxState>, boolean];
7
7
  export declare const searchItemIndex: (items: ISelectListItem[], searchStr: string) => number;
8
- export declare const getFirstIndex: (items: ISelectListItem[]) => number;
8
+ export declare const getFirstIndex: (items: ISelectListItem[]) => 0 | -1;
9
9
  export declare const getLastIndex: (items: ISelectListItem[]) => number;
10
10
  export declare const getNextIndex: (currIndex: number, items: ISelectListItem[]) => number;
11
11
  export declare const getPrevIndex: (currIndex: number, items: ISelectListItem[]) => number;
@@ -37,43 +37,36 @@ const searchItemIndex = (items, searchStr) => {
37
37
  return -1;
38
38
  }
39
39
  return items.findIndex(item => {
40
- if (item.disabled) {
41
- return false;
42
- }
43
40
  const content = (0, reactHelpers_1.getComponentText)(item.children);
44
41
  return content.toLocaleLowerCase().indexOf(searchStr.toLocaleLowerCase()) > -1;
45
42
  });
46
43
  };
47
44
  exports.searchItemIndex = searchItemIndex;
48
- const getFirstIndex = (items) => items.findIndex(i => !i.disabled);
45
+ const getFirstIndex = (items) => (items.length > 0 ? 0 : -1);
49
46
  exports.getFirstIndex = getFirstIndex;
50
- const getLastIndex = (items) => {
51
- const reverseLastIndex = [...items].reverse().findIndex(i => !i.disabled);
52
- return reverseLastIndex === -1 ? reverseLastIndex : items.length - reverseLastIndex - 1;
53
- };
47
+ const getLastIndex = (items) => (items.length > 0 ? items.length - 1 : -1);
54
48
  exports.getLastIndex = getLastIndex;
55
49
  const getNextIndex = (currIndex, items) => {
56
- const next = (0, exports.getFirstIndex)(items.slice(currIndex + 1));
57
- return next === -1 ? (0, exports.getFirstIndex)(items) : next + currIndex + 1;
50
+ if (items.length === 0) {
51
+ return -1;
52
+ }
53
+ return currIndex + 1 >= items.length ? 0 : currIndex + 1;
58
54
  };
59
55
  exports.getNextIndex = getNextIndex;
60
56
  const getPrevIndex = (currIndex, items) => {
61
- const prev = (0, exports.getLastIndex)(items.slice(0, currIndex));
62
- return prev === -1 ? (0, exports.getLastIndex)(items) : prev;
57
+ if (items.length === 0) {
58
+ return -1;
59
+ }
60
+ return currIndex <= 0 || currIndex >= items.length ? items.length - 1 : currIndex - 1;
63
61
  };
64
62
  exports.getPrevIndex = getPrevIndex;
65
63
  const getFirstActiveIndex = (state, items, multiselect) => {
66
- let firstActiveItemIndex = -1;
67
64
  for (let i = 0; i < items.length; i++) {
68
- const item = items[i];
69
- if (!item.disabled && firstActiveItemIndex === -1) {
70
- firstActiveItemIndex = i;
71
- }
72
- if (state.get(item.id) === checkboxState_1.CheckboxState.On && !item.disabled) {
65
+ if (state.get(items[i].id) === checkboxState_1.CheckboxState.On) {
73
66
  return i;
74
67
  }
75
68
  }
76
- return multiselect ? firstActiveItemIndex : -1;
69
+ return multiselect && items.length > 0 ? 0 : -1;
77
70
  };
78
71
  exports.getFirstActiveIndex = getFirstActiveIndex;
79
72
  const getItemsState = (items, value, multiselect) => {
@@ -80,7 +80,7 @@ const SelectList = (_a) => {
80
80
  "Enter": () => {
81
81
  const item = items[state.activeIndex];
82
82
  // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition
83
- if (!item) {
83
+ if (!item || item.disabled) {
84
84
  return;
85
85
  }
86
86
  if (item.multiLevel) {
@@ -96,7 +96,14 @@ const SelectList = (_a) => {
96
96
  },
97
97
  "Home": () => multiselect || !selectItemOnFocus ? dispatchState({ type: selectList_actionTypes_1.ListAction.FocusFirst, payload: { items } }) : dispatchState({ type: selectList_actionTypes_1.ListAction.SelectFirst, payload: { items, multiselect } }),
98
98
  "End": () => multiselect || !selectItemOnFocus ? dispatchState({ type: selectList_actionTypes_1.ListAction.FocusLast, payload: { items } }) : dispatchState({ type: selectList_actionTypes_1.ListAction.SelectLast, payload: { items, multiselect } }),
99
- "Space": () => dispatchState({ type: selectList_actionTypes_1.ListAction.ToggleCurrent, payload: { multiselect } }),
99
+ "Space": () => {
100
+ const item = items[state.activeIndex];
101
+ // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition
102
+ if (item === null || item === void 0 ? void 0 : item.disabled) {
103
+ return;
104
+ }
105
+ dispatchState({ type: selectList_actionTypes_1.ListAction.ToggleCurrent, payload: { multiselect } });
106
+ },
100
107
  "Shift+ArrowUp": () => multiselect && dispatchState({ type: selectList_actionTypes_1.ListAction.SelectPrev, payload: { items, multiselect } }),
101
108
  "Shift+ArrowDown": () => multiselect && dispatchState({ type: selectList_actionTypes_1.ListAction.SelectNext, payload: { items, multiselect } }),
102
109
  "Ctrl+Shift+Home": () => multiselect && dispatchState({ type: selectList_actionTypes_1.ListAction.SelectAllToTheBeginning, payload: { items, multiselect } }),
@@ -2,9 +2,9 @@ import { CheckboxState } from "../checkbox/checkboxState";
2
2
  import { IListState } from "./selectList";
3
3
  import { TAction } from "./selectList.actionTypes";
4
4
  export declare const selectListReducer: (state: IListState, action: TAction) => {
5
- itemsState: Map<string, CheckboxState>;
6
- isItemsStateChanged: boolean;
7
5
  activeIndex: number;
6
+ isItemsStateChanged: boolean;
8
7
  searchStr: string;
8
+ itemsState: Map<string, CheckboxState>;
9
9
  level: string;
10
10
  };
@@ -4,7 +4,10 @@ exports.selectListReducer = void 0;
4
4
  const checkboxState_1 = require("../checkbox/checkboxState");
5
5
  const selectList_actionTypes_1 = require("./selectList.actionTypes");
6
6
  const selectList_helpers_1 = require("./selectList.helpers");
7
- const selectItem = (state, itemIndex, multiselect) => {
7
+ const selectItem = (state, itemIndex, multiselect, disabled) => {
8
+ if (disabled) {
9
+ return Object.assign(Object.assign({}, state), { activeIndex: itemIndex, isItemsStateChanged: false, searchStr: "" });
10
+ }
8
11
  const itemId = (0, selectList_helpers_1.getItemIdByIndex)(state.itemsState, itemIndex);
9
12
  if (!itemId) {
10
13
  return Object.assign({}, state);
@@ -34,6 +37,7 @@ const toggleItems = (items, state, activeIndex, direction, multiselect, newState
34
37
  };
35
38
  // eslint-disable-next-line complexity
36
39
  const selectListReducer = (state, action) => {
40
+ var _a, _b, _c, _d;
37
41
  const { type, payload } = action;
38
42
  switch (type) {
39
43
  case selectList_actionTypes_1.ListAction.ChangeItemState: {
@@ -52,10 +56,22 @@ const selectListReducer = (state, action) => {
52
56
  case selectList_actionTypes_1.ListAction.FocusLast: return Object.assign(Object.assign({}, state), { activeIndex: (0, selectList_helpers_1.getLastIndex)(payload.items), isItemsStateChanged: false, searchStr: "" });
53
57
  case selectList_actionTypes_1.ListAction.FocusNext: return Object.assign(Object.assign({}, state), { activeIndex: (0, selectList_helpers_1.getNextIndex)(state.activeIndex, payload.items), isItemsStateChanged: false, searchStr: "" });
54
58
  case selectList_actionTypes_1.ListAction.FocusPrev: return Object.assign(Object.assign({}, state), { activeIndex: (0, selectList_helpers_1.getPrevIndex)(state.activeIndex, payload.items), isItemsStateChanged: false, searchStr: "" });
55
- case selectList_actionTypes_1.ListAction.SelectFirst: return selectItem(state, (0, selectList_helpers_1.getFirstIndex)(payload.items), payload.multiselect);
56
- case selectList_actionTypes_1.ListAction.SelectLast: return selectItem(state, (0, selectList_helpers_1.getLastIndex)(payload.items), payload.multiselect);
57
- case selectList_actionTypes_1.ListAction.SelectNext: return selectItem(state, (0, selectList_helpers_1.getNextIndex)(state.activeIndex, payload.items), payload.multiselect);
58
- case selectList_actionTypes_1.ListAction.SelectPrev: return selectItem(state, (0, selectList_helpers_1.getPrevIndex)(state.activeIndex, payload.items), payload.multiselect);
59
+ case selectList_actionTypes_1.ListAction.SelectFirst: {
60
+ const index = (0, selectList_helpers_1.getFirstIndex)(payload.items);
61
+ return selectItem(state, index, payload.multiselect, (_a = payload.items[index]) === null || _a === void 0 ? void 0 : _a.disabled);
62
+ }
63
+ case selectList_actionTypes_1.ListAction.SelectLast: {
64
+ const index = (0, selectList_helpers_1.getLastIndex)(payload.items);
65
+ return selectItem(state, index, payload.multiselect, (_b = payload.items[index]) === null || _b === void 0 ? void 0 : _b.disabled);
66
+ }
67
+ case selectList_actionTypes_1.ListAction.SelectNext: {
68
+ const index = (0, selectList_helpers_1.getNextIndex)(state.activeIndex, payload.items);
69
+ return selectItem(state, index, payload.multiselect, (_c = payload.items[index]) === null || _c === void 0 ? void 0 : _c.disabled);
70
+ }
71
+ case selectList_actionTypes_1.ListAction.SelectPrev: {
72
+ const index = (0, selectList_helpers_1.getPrevIndex)(state.activeIndex, payload.items);
73
+ return selectItem(state, index, payload.multiselect, (_d = payload.items[index]) === null || _d === void 0 ? void 0 : _d.disabled);
74
+ }
59
75
  case selectList_actionTypes_1.ListAction.SelectAllToTheBeginning: return toggleItems(payload.items, state, state.activeIndex, selectList_actionTypes_1.SelectDirection.Up, payload.multiselect, checkboxState_1.CheckboxState.On);
60
76
  case selectList_actionTypes_1.ListAction.SelectAllToTheEnd: return toggleItems(payload.items, state, state.activeIndex, selectList_actionTypes_1.SelectDirection.Down, payload.multiselect, checkboxState_1.CheckboxState.On);
61
77
  case selectList_actionTypes_1.ListAction.ToggleAll: return toggleItems(payload.items, state, 0, selectList_actionTypes_1.SelectDirection.Down, payload.multiselect);
@@ -2,9 +2,9 @@ import { TSelectAction } from "./select.actionTypes";
2
2
  import { ISelectStateRaw } from "./selectRaw";
3
3
  export declare const selectReducer: (state: ISelectStateRaw, action: TSelectAction) => {
4
4
  expanded: boolean;
5
- itemsState: Map<string, import("..").CheckboxState>;
6
- isItemsStateChanged: boolean;
7
5
  activeIndex: number;
6
+ isItemsStateChanged: boolean;
8
7
  searchStr: string;
8
+ itemsState: Map<string, import("..").CheckboxState>;
9
9
  level: string;
10
10
  };
@@ -314,5 +314,7 @@
314
314
  "Filters and search": "Filters and search",
315
315
  "Apply filter": "Apply filter",
316
316
  "This filter is currently applied.": "This filter is currently applied.",
317
- "Remove filter": "Remove filter"
317
+ "Remove filter": "Remove filter",
318
+ "Exit full screen table view": "Exit full screen table view",
319
+ "Close search": "Close search"
318
320
  }
@@ -9,6 +9,7 @@ import { IconMinimize } from "../../../icons/iconMinimize";
9
9
  import { useLayoutFullScreenElement } from "../../../layout/layoutFullScreenElementProvider";
10
10
  import { useLayoutFullScreen } from "../../../layout/layoutFullScreenProvider";
11
11
  import { useCallback } from "react";
12
+ injectString("en", "Exit full screen table view", "Exit full screen table view");
12
13
  injectString("cs", "Convert table to full screen", "Konvertovat tabulku do re\u017Eimu pln\xE9ho zobrazen\xED");
13
14
  injectString("da-DK", "Convert table to full screen", "Konverter tabel til fuld sk\xE6rm");
14
15
  injectString("de", "Convert table to full screen", "Tabelle in Vollbild umwandeln");
@@ -63,9 +64,9 @@ export const FullScreenButton = ({
63
64
  icon: getFullScreen() ? IconMinimize : IconExpand,
64
65
  iconPosition: ButtonIconPosition.Start,
65
66
  iconSize: SvgIconSize.Large,
66
- title: title ? title : translate("Convert table to full screen"),
67
+ title: title ? title : getFullScreen() ? translate("Exit full screen table view") : translate("Convert table to full screen"),
67
68
  type: ButtonType.TertiaryBlack,
68
69
  onClick: handleClick
69
70
  });
70
71
  };
71
- FullScreenButton.translations = ["Convert table to full screen"];
72
+ FullScreenButton.translations = ["Convert table to full screen", "Exit full screen table view"];
@@ -1,5 +1,5 @@
1
1
  import { jsx as _jsx, Fragment as _Fragment, jsxs as _jsxs } from "react/jsx-runtime";
2
- import React, { useMemo } from "react";
2
+ import React, { useMemo, useEffect } from "react";
3
3
  import { FeedbackContext } from "./feedbackContext";
4
4
  import { AlertRaw } from "../alertRaw/alertRaw";
5
5
  import { useMobile } from "../commonHelpers/hooks/useMobile";
@@ -28,8 +28,10 @@ export const FeedbackContainer = () => {
28
28
  if (isToastAdded) {
29
29
  removedToastId.current = null;
30
30
  }
31
- prevAlertsLength.current = alerts.length;
32
- prevToastsLength.current = toasts.length;
31
+ useEffect(() => {
32
+ prevAlertsLength.current = alerts.length;
33
+ prevToastsLength.current = toasts.length;
34
+ }, [alerts.length, toasts.length]);
33
35
  const alertsToRender = useMemo(() => alerts.map((alert, indx) => _jsx(AlertRaw, { id: alert.id, header: alert.header, text: alert.text, isOpen: true, onClose: () => {
34
36
  removeAlert(alert.id);
35
37
  removedAlertId.current = indx;
@@ -25,7 +25,7 @@ import { useFormFieldProps } from "./useFormFieldProps";
25
25
  import { useCounter } from "./useCounter";
26
26
  export const useContainer = (props, wrapperComponent) => {
27
27
  const { id, wrapperComponent: WrappedComponent, trailing, trailingId, showAdditionalInfo } = useFormFieldProps(props, wrapperComponent);
28
- const { className, inputClassName } = props, rest = __rest(props, ["className", "inputClassName"]);
28
+ const { className, inputClassName, inputWrapperClassName } = props, rest = __rest(props, ["className", "inputClassName", "inputWrapperClassName"]);
29
29
  const { id: errorId, error, errorBanner } = useError(props);
30
30
  const { id: bannerId, banner: bannerComp } = useBanner(props);
31
31
  const { id: assistiveId, assistive } = useAssistive(props);
@@ -41,6 +41,6 @@ export const useContainer = (props, wrapperComponent) => {
41
41
  const isInputContainerHidden = isReadonly && props.isError;
42
42
  const ref = props.ref;
43
43
  const banner = errorBanner || bannerComp;
44
- const container = useMemo(() => _jsxs(_Fragment, { children: [_jsxs("div", { className: classNames(["zen-form-field__input-container", isReadonly ? "zen-form-field__input-container--review" : "", isInputContainerHidden ? "zen-form-field__input-container--hidden" : "", trailing ? "zen-form-field__input-container--with-trailing" : ""]), children: [_jsxs("div", { children: [_jsx(WrappedComponent, Object.assign({}, rest, disabledProps, { isReadOnly: isReadonly, id: id, className: componentClassName, ref: ref, isLoadingError: props.isError, isError: !!error, ariaDescribedby: ariaDescribedBy })), _jsx(FormFieldAdditionalInfo, { counterId: counterId, assistiveId: assistiveId, errorId: errorId, driveTextClass: driveTextClass, error: error, assistive: assistive, counter: counter, showAdditionalInfo: showAdditionalInfo })] }), _jsx(TrailingComponent, { hasCustomWidth: hasCustomWidth, id: trailingId, value: trailing, hasAdditionalInfo: !!showAdditionalInfo })] }), banner] }), [isReadonly, isInputContainerHidden, trailing, WrappedComponent, rest, disabledProps, id, componentClassName, ref, props.isError, error, ariaDescribedBy, counterId, assistiveId, errorId, driveTextClass, assistive, counter, showAdditionalInfo, hasCustomWidth, trailingId, banner]);
44
+ const container = useMemo(() => _jsxs(_Fragment, { children: [_jsxs("div", { className: classNames(["zen-form-field__input-container", isReadonly ? "zen-form-field__input-container--review" : "", isInputContainerHidden ? "zen-form-field__input-container--hidden" : "", trailing ? "zen-form-field__input-container--with-trailing" : ""]), children: [_jsxs("div", { className: classNames(["zen-form-field__input-wrapper", inputWrapperClassName || ""]), children: [_jsx(WrappedComponent, Object.assign({}, rest, disabledProps, { isReadOnly: isReadonly, id: id, className: componentClassName, ref: ref, isLoadingError: props.isError, isError: !!error, ariaDescribedby: ariaDescribedBy })), _jsx(FormFieldAdditionalInfo, { counterId: counterId, assistiveId: assistiveId, errorId: errorId, driveTextClass: driveTextClass, error: error, assistive: assistive, counter: counter, showAdditionalInfo: showAdditionalInfo })] }), _jsx(TrailingComponent, { hasCustomWidth: hasCustomWidth, id: trailingId, value: trailing, hasAdditionalInfo: !!showAdditionalInfo })] }), banner] }), [isReadonly, isInputContainerHidden, trailing, inputWrapperClassName, props.isError, WrappedComponent, rest, disabledProps, id, componentClassName, ref, error, ariaDescribedBy, counterId, assistiveId, errorId, driveTextClass, assistive, counter, showAdditionalInfo, hasCustomWidth, trailingId, banner]);
45
45
  return container;
46
46
  };
@@ -5,6 +5,10 @@ export type TLabelAlign = "left" | "top";
5
5
  interface IFormFieldBase extends PropsWithChildren {
6
6
  className?: string;
7
7
  inputClassName?: string;
8
+ /**
9
+ * @param inputWrapperClassName - className for the wrapper around the input, which also contains assistive text, error and counter
10
+ */
11
+ inputWrapperClassName?: string;
8
12
  error?: string;
9
13
  assistive?: string;
10
14
  counter?: string;
@@ -9,6 +9,9 @@ import { classNames } from "../../../commonHelpers/classNames/classNames";
9
9
  import { IconSearch } from "../../../icons/iconSearch";
10
10
  import { SearchInput } from "../../../searchInput/searchInput";
11
11
  import { NavItem } from "../../navItem/navItem";
12
+ import { IconClose } from "../../../icons/iconClose";
13
+ import { TextIconButton } from "../../../textIconButton/textIconButton";
14
+ import { ButtonType } from "../../../button/buttonType";
12
15
  injectString("cs", "Search", "Hledat");
13
16
  injectString("da-DK", "Search", "S\xF8g");
14
17
  injectString("de", "Search", "Suche");
@@ -35,6 +38,7 @@ injectString("tr", "Search", "Ara");
35
38
  injectString("zh-Hans", "Search", "\u641C\u7D22");
36
39
  injectString("zh-TW", "Search", "\u641C\u5C0B");
37
40
  injectString("ro-RO", "Search", "C\u0103uta\u021Bi");
41
+ injectString("en", "Close search", "Close search");
38
42
  export const NavHeaderSearch = ({
39
43
  className,
40
44
  onSearch
@@ -70,6 +74,10 @@ export const NavHeaderSearch = ({
70
74
  onSearchToggle === null || onSearchToggle === void 0 ? void 0 : onSearchToggle(false);
71
75
  }
72
76
  }, [handleChange, onSearchToggle]);
77
+ const clearSearch = useCallback(() => {
78
+ handleChange("");
79
+ onSearchToggle === null || onSearchToggle === void 0 ? void 0 : onSearchToggle(false);
80
+ }, [handleChange, onSearchToggle]);
73
81
  return _jsxs("div", {
74
82
  className: classNames(["zen-nav-header-search", className || ""]),
75
83
  children: [!searchOpen && !isMobile ? _jsx(NavItem, {
@@ -89,6 +97,13 @@ export const NavHeaderSearch = ({
89
97
  onChange: handleChange,
90
98
  onBlur: handleBlur,
91
99
  onKeyDown: handleKeyDown
100
+ }) : null, searchOpen && !isMobile ? _jsx(TextIconButton, {
101
+ icon: IconClose,
102
+ iconSize: "large",
103
+ onClick: clearSearch,
104
+ type: ButtonType.TertiaryBlack,
105
+ title: translate("Close search"),
106
+ className: "zen-nav-header-search__close-button"
92
107
  }) : null]
93
108
  });
94
109
  };
@@ -22,7 +22,7 @@ export const ActionablePill = ({ onChange, disabled, readonly, className, childr
22
22
  }
23
23
  onChange(e.target.checked);
24
24
  }, [onChange, readonly]);
25
- const onKeyDownHandler = useCallback((e) => {
25
+ const onKeyUpHandler = useCallback((e) => {
26
26
  if (e.key === "Enter" && !disabled && !readonly) {
27
27
  onChange(!active);
28
28
  return;
@@ -31,17 +31,7 @@ export const ActionablePill = ({ onChange, disabled, readonly, className, childr
31
31
  e.preventDefault();
32
32
  onChange(!active);
33
33
  }
34
- }, [disabled, readonly, active, onChange]);
35
- const onKeyUpHandler = useCallback((e) => {
36
- var _a;
37
- if (e.key === "Tab" || e.key === "Enter" || e.key === " " || e.key === "ArrowRight" || e.key === "ArrowLeft" || e.key === "ArrowUp" || e.key === "ArrowDown") {
38
- (_a = ref.current) === null || _a === void 0 ? void 0 : _a.classList.add("zen-pill-actionable--keyboard-nav");
39
- }
40
- }, [ref]);
41
- const onBlurHandler = useCallback(() => {
42
- var _a;
43
- (_a = ref.current) === null || _a === void 0 ? void 0 : _a.classList.remove("zen-pill-actionable--keyboard-nav");
44
- }, [ref]);
34
+ }, [active, disabled, onChange, readonly]);
45
35
  // Only show title when icon is visible but text is hidden, or when explicit title is provided with hidden text
46
36
  const showTitle = hasIcon && isTextContentHidden;
47
37
  const titleValue = title || textContent;
@@ -51,5 +41,5 @@ export const ActionablePill = ({ onChange, disabled, readonly, className, childr
51
41
  drivePillClass !== null && drivePillClass !== void 0 ? drivePillClass : "",
52
42
  getActionablePillStateClassName(!!disabled, !!readonly, active),
53
43
  className !== null && className !== void 0 ? className : ""
54
- ]), htmlFor: id, children: [_jsx("input", { checked: active, onBlur: onBlurHandler, onKeyUp: onKeyUpHandler, onKeyDown: onKeyDownHandler, onChange: onChangeHandler, id: id, className: "zen-pill-actionable__input", type: "checkbox", disabled: disabled, readOnly: readonly }), _jsxs("div", { className: classNames(["zen-pill-actionable__content-wrapper", contentClasses]), children: [_jsx("div", { className: classNames(["zen-pill-text-content", driveTextClass !== null && driveTextClass !== void 0 ? driveTextClass : ""]), children: children }), svgIcon] })] }));
44
+ ]), htmlFor: id, children: [_jsx("input", { checked: active, onKeyUp: onKeyUpHandler, onChange: onChangeHandler, id: id, className: "zen-pill-actionable__input", type: "checkbox", disabled: disabled, readOnly: readonly }), _jsxs("div", { className: classNames(["zen-pill-actionable__content-wrapper", contentClasses]), children: [_jsx("div", { className: classNames(["zen-pill-text-content", driveTextClass !== null && driveTextClass !== void 0 ? driveTextClass : ""]), children: children }), svgIcon] })] }));
55
45
  };
@@ -345,7 +345,8 @@ const PillExpandableBase = ({
345
345
  text: hideCounterNumber ? "" : `${isFlat ? "+" : ""}${uniqueChildren}`,
346
346
  includeExpandIcon: false,
347
347
  type: type,
348
- errorHandler: errorHandler
348
+ errorHandler: errorHandler,
349
+ className: "zen-status-pill__counter"
349
350
  })]
350
351
  }), _jsx(Absolute, {
351
352
  recalculateTrigger: isPopupContentReady,
@@ -12,7 +12,7 @@ interface IPillExpandableSimple extends IPillExpandable {
12
12
  descriptionId?: string;
13
13
  }
14
14
  export declare const PillExpandableSimple: {
15
- ({ onExpand, expandAriaText, text, expanded, includeExpandIcon, type, icon, isBeta, ref, descriptionId }: IPillExpandableSimple): import("react/jsx-runtime").JSX.Element;
15
+ ({ onExpand, expandAriaText, text, expanded, includeExpandIcon, type, icon, isBeta, ref, className, descriptionId }: IPillExpandableSimple): import("react/jsx-runtime").JSX.Element;
16
16
  displayName: string;
17
17
  };
18
18
  export {};
@@ -5,7 +5,7 @@ import { IconChevronTop } from "../icons/iconChevronTop";
5
5
  import { IconChevronBottom } from "../icons/iconChevronBottom";
6
6
  import { IconException } from "../icons/iconException";
7
7
  import { classNames } from "../commonHelpers/classNames/classNames";
8
- export const PillExpandableSimple = ({ onExpand, expandAriaText, text, expanded, includeExpandIcon = true, type = "warning", icon = IconException, isBeta, ref, descriptionId }) => {
8
+ export const PillExpandableSimple = ({ onExpand, expandAriaText, text, expanded, includeExpandIcon = true, type = "warning", icon = IconException, isBeta, ref, className, descriptionId }) => {
9
9
  const iconDriveClassName = useDriveClassName("icon");
10
10
  const containerDriveClassName = useDriveClassName("zen-status-pill__container");
11
11
  const onExpandHandler = useCallback(() => {
@@ -16,7 +16,7 @@ export const PillExpandableSimple = ({ onExpand, expandAriaText, text, expanded,
16
16
  const iconSize = isBeta ? "big" : defaultIconSize;
17
17
  const hasText = (text || "").trim().length > 0;
18
18
  return _jsxs("button", { type: "button", className: classNames([
19
- "zen-status-pill__container", `zen-status-pill__container--${type}`, containerDriveClassName || "", "zen-ellipsis"
19
+ "zen-status-pill__container", `zen-status-pill__container--${type}`, containerDriveClassName || "", className || "", "zen-ellipsis"
20
20
  ]), ref: ref, onClick: onExpandHandler, tabIndex: !includeExpandIcon ? -1 : undefined, "aria-describedby": descriptionId, children: [icon !== false && _jsx("div", { className: classNames([
21
21
  "zen-status-pill__icon",
22
22
  `zen-status-pill__icon--${type}`,
@@ -5,7 +5,7 @@ export declare const getItemIdByIndex: (state: Map<string, CheckboxState>, index
5
5
  export declare const getItemIndexById: (state: Map<string, CheckboxState>, id: string) => number;
6
6
  export declare const updateItemState: (initialState: Map<string, CheckboxState>, multiselect: boolean, updatedId: string, newState: CheckboxState) => [Map<string, CheckboxState>, boolean];
7
7
  export declare const searchItemIndex: (items: ISelectListItem[], searchStr: string) => number;
8
- export declare const getFirstIndex: (items: ISelectListItem[]) => number;
8
+ export declare const getFirstIndex: (items: ISelectListItem[]) => 0 | -1;
9
9
  export declare const getLastIndex: (items: ISelectListItem[]) => number;
10
10
  export declare const getNextIndex: (currIndex: number, items: ISelectListItem[]) => number;
11
11
  export declare const getPrevIndex: (currIndex: number, items: ISelectListItem[]) => number;
@@ -31,38 +31,31 @@ export const searchItemIndex = (items, searchStr) => {
31
31
  return -1;
32
32
  }
33
33
  return items.findIndex(item => {
34
- if (item.disabled) {
35
- return false;
36
- }
37
34
  const content = getComponentText(item.children);
38
35
  return content.toLocaleLowerCase().indexOf(searchStr.toLocaleLowerCase()) > -1;
39
36
  });
40
37
  };
41
- export const getFirstIndex = (items) => items.findIndex(i => !i.disabled);
42
- export const getLastIndex = (items) => {
43
- const reverseLastIndex = [...items].reverse().findIndex(i => !i.disabled);
44
- return reverseLastIndex === -1 ? reverseLastIndex : items.length - reverseLastIndex - 1;
45
- };
38
+ export const getFirstIndex = (items) => (items.length > 0 ? 0 : -1);
39
+ export const getLastIndex = (items) => (items.length > 0 ? items.length - 1 : -1);
46
40
  export const getNextIndex = (currIndex, items) => {
47
- const next = getFirstIndex(items.slice(currIndex + 1));
48
- return next === -1 ? getFirstIndex(items) : next + currIndex + 1;
41
+ if (items.length === 0) {
42
+ return -1;
43
+ }
44
+ return currIndex + 1 >= items.length ? 0 : currIndex + 1;
49
45
  };
50
46
  export const getPrevIndex = (currIndex, items) => {
51
- const prev = getLastIndex(items.slice(0, currIndex));
52
- return prev === -1 ? getLastIndex(items) : prev;
47
+ if (items.length === 0) {
48
+ return -1;
49
+ }
50
+ return currIndex <= 0 || currIndex >= items.length ? items.length - 1 : currIndex - 1;
53
51
  };
54
52
  export const getFirstActiveIndex = (state, items, multiselect) => {
55
- let firstActiveItemIndex = -1;
56
53
  for (let i = 0; i < items.length; i++) {
57
- const item = items[i];
58
- if (!item.disabled && firstActiveItemIndex === -1) {
59
- firstActiveItemIndex = i;
60
- }
61
- if (state.get(item.id) === CheckboxState.On && !item.disabled) {
54
+ if (state.get(items[i].id) === CheckboxState.On) {
62
55
  return i;
63
56
  }
64
57
  }
65
- return multiselect ? firstActiveItemIndex : -1;
58
+ return multiselect && items.length > 0 ? 0 : -1;
66
59
  };
67
60
  export const getItemsState = (items, value, multiselect) => {
68
61
  let forceUncheck = false;
@@ -77,7 +77,7 @@ export const SelectList = (_a) => {
77
77
  "Enter": () => {
78
78
  const item = items[state.activeIndex];
79
79
  // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition
80
- if (!item) {
80
+ if (!item || item.disabled) {
81
81
  return;
82
82
  }
83
83
  if (item.multiLevel) {
@@ -93,7 +93,14 @@ export const SelectList = (_a) => {
93
93
  },
94
94
  "Home": () => multiselect || !selectItemOnFocus ? dispatchState({ type: ListAction.FocusFirst, payload: { items } }) : dispatchState({ type: ListAction.SelectFirst, payload: { items, multiselect } }),
95
95
  "End": () => multiselect || !selectItemOnFocus ? dispatchState({ type: ListAction.FocusLast, payload: { items } }) : dispatchState({ type: ListAction.SelectLast, payload: { items, multiselect } }),
96
- "Space": () => dispatchState({ type: ListAction.ToggleCurrent, payload: { multiselect } }),
96
+ "Space": () => {
97
+ const item = items[state.activeIndex];
98
+ // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition
99
+ if (item === null || item === void 0 ? void 0 : item.disabled) {
100
+ return;
101
+ }
102
+ dispatchState({ type: ListAction.ToggleCurrent, payload: { multiselect } });
103
+ },
97
104
  "Shift+ArrowUp": () => multiselect && dispatchState({ type: ListAction.SelectPrev, payload: { items, multiselect } }),
98
105
  "Shift+ArrowDown": () => multiselect && dispatchState({ type: ListAction.SelectNext, payload: { items, multiselect } }),
99
106
  "Ctrl+Shift+Home": () => multiselect && dispatchState({ type: ListAction.SelectAllToTheBeginning, payload: { items, multiselect } }),
@@ -2,9 +2,9 @@ import { CheckboxState } from "../checkbox/checkboxState";
2
2
  import { IListState } from "./selectList";
3
3
  import { TAction } from "./selectList.actionTypes";
4
4
  export declare const selectListReducer: (state: IListState, action: TAction) => {
5
- itemsState: Map<string, CheckboxState>;
6
- isItemsStateChanged: boolean;
7
5
  activeIndex: number;
6
+ isItemsStateChanged: boolean;
8
7
  searchStr: string;
8
+ itemsState: Map<string, CheckboxState>;
9
9
  level: string;
10
10
  };
@@ -1,7 +1,10 @@
1
1
  import { CheckboxState } from "../checkbox/checkboxState";
2
2
  import { ListAction, SelectDirection } from "./selectList.actionTypes";
3
3
  import { getFirstActiveIndex, getFirstIndex, getItemIdByIndex, getItemIndexById, getLastIndex, getNextIndex, getPrevIndex, searchItemIndex, updateItemState } from "./selectList.helpers";
4
- const selectItem = (state, itemIndex, multiselect) => {
4
+ const selectItem = (state, itemIndex, multiselect, disabled) => {
5
+ if (disabled) {
6
+ return Object.assign(Object.assign({}, state), { activeIndex: itemIndex, isItemsStateChanged: false, searchStr: "" });
7
+ }
5
8
  const itemId = getItemIdByIndex(state.itemsState, itemIndex);
6
9
  if (!itemId) {
7
10
  return Object.assign({}, state);
@@ -31,6 +34,7 @@ const toggleItems = (items, state, activeIndex, direction, multiselect, newState
31
34
  };
32
35
  // eslint-disable-next-line complexity
33
36
  export const selectListReducer = (state, action) => {
37
+ var _a, _b, _c, _d;
34
38
  const { type, payload } = action;
35
39
  switch (type) {
36
40
  case ListAction.ChangeItemState: {
@@ -49,10 +53,22 @@ export const selectListReducer = (state, action) => {
49
53
  case ListAction.FocusLast: return Object.assign(Object.assign({}, state), { activeIndex: getLastIndex(payload.items), isItemsStateChanged: false, searchStr: "" });
50
54
  case ListAction.FocusNext: return Object.assign(Object.assign({}, state), { activeIndex: getNextIndex(state.activeIndex, payload.items), isItemsStateChanged: false, searchStr: "" });
51
55
  case ListAction.FocusPrev: return Object.assign(Object.assign({}, state), { activeIndex: getPrevIndex(state.activeIndex, payload.items), isItemsStateChanged: false, searchStr: "" });
52
- case ListAction.SelectFirst: return selectItem(state, getFirstIndex(payload.items), payload.multiselect);
53
- case ListAction.SelectLast: return selectItem(state, getLastIndex(payload.items), payload.multiselect);
54
- case ListAction.SelectNext: return selectItem(state, getNextIndex(state.activeIndex, payload.items), payload.multiselect);
55
- case ListAction.SelectPrev: return selectItem(state, getPrevIndex(state.activeIndex, payload.items), payload.multiselect);
56
+ case ListAction.SelectFirst: {
57
+ const index = getFirstIndex(payload.items);
58
+ return selectItem(state, index, payload.multiselect, (_a = payload.items[index]) === null || _a === void 0 ? void 0 : _a.disabled);
59
+ }
60
+ case ListAction.SelectLast: {
61
+ const index = getLastIndex(payload.items);
62
+ return selectItem(state, index, payload.multiselect, (_b = payload.items[index]) === null || _b === void 0 ? void 0 : _b.disabled);
63
+ }
64
+ case ListAction.SelectNext: {
65
+ const index = getNextIndex(state.activeIndex, payload.items);
66
+ return selectItem(state, index, payload.multiselect, (_c = payload.items[index]) === null || _c === void 0 ? void 0 : _c.disabled);
67
+ }
68
+ case ListAction.SelectPrev: {
69
+ const index = getPrevIndex(state.activeIndex, payload.items);
70
+ return selectItem(state, index, payload.multiselect, (_d = payload.items[index]) === null || _d === void 0 ? void 0 : _d.disabled);
71
+ }
56
72
  case ListAction.SelectAllToTheBeginning: return toggleItems(payload.items, state, state.activeIndex, SelectDirection.Up, payload.multiselect, CheckboxState.On);
57
73
  case ListAction.SelectAllToTheEnd: return toggleItems(payload.items, state, state.activeIndex, SelectDirection.Down, payload.multiselect, CheckboxState.On);
58
74
  case ListAction.ToggleAll: return toggleItems(payload.items, state, 0, SelectDirection.Down, payload.multiselect);
@@ -2,9 +2,9 @@ import { TSelectAction } from "./select.actionTypes";
2
2
  import { ISelectStateRaw } from "./selectRaw";
3
3
  export declare const selectReducer: (state: ISelectStateRaw, action: TSelectAction) => {
4
4
  expanded: boolean;
5
- itemsState: Map<string, import("..").CheckboxState>;
6
- isItemsStateChanged: boolean;
7
5
  activeIndex: number;
6
+ isItemsStateChanged: boolean;
8
7
  searchStr: string;
8
+ itemsState: Map<string, import("..").CheckboxState>;
9
9
  level: string;
10
10
  };
@@ -314,5 +314,7 @@
314
314
  "Filters and search": "Filters and search",
315
315
  "Apply filter": "Apply filter",
316
316
  "This filter is currently applied.": "This filter is currently applied.",
317
- "Remove filter": "Remove filter"
317
+ "Remove filter": "Remove filter",
318
+ "Exit full screen table view": "Exit full screen table view",
319
+ "Close search": "Close search"
318
320
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@geotab/zenith",
3
- "version": "3.6.0",
3
+ "version": "3.6.1-beta.0",
4
4
  "description": "Zenith components library on React",
5
5
  "main": "dist/index.js",
6
6
  "types": "esm/index.d.ts",
@@ -11,6 +11,9 @@
11
11
  "**/react-chartjs/dateAdapter.ts",
12
12
  "**/react-chartjs/dateAdapter.js"
13
13
  ],
14
+ "publishConfig": {
15
+ "access": "public"
16
+ },
14
17
  "scripts": {
15
18
  "test": "npm run clean && npm run test-build && node build-utils/translations/inject-translations.js && jest --clearCache && jest",
16
19
  "start": "npm run storybook --loglevel verbose",
@@ -116,8 +119,5 @@
116
119
  "last 1 firefox version",
117
120
  "last 1 safari version"
118
121
  ]
119
- },
120
- "publishConfig": {
121
- "access": "public"
122
122
  }
123
123
  }