@geotab/zenith 3.6.0-beta.6 → 3.6.0-beta.7
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md
CHANGED
|
@@ -59,7 +59,6 @@ Change log:
|
|
|
59
59
|
- Update `Layout` component background
|
|
60
60
|
- Improve y-axis positioning for `Charts`
|
|
61
61
|
- Center content alignment in `TextIconButton` component
|
|
62
|
-
- Enhanced `Nav` component: optional drag-and-drop, mobile menu state handling, action support
|
|
63
62
|
- Add divider support for groupsFilter and pillExpandable
|
|
64
63
|
- Add link support for mobile primary actions
|
|
65
64
|
- Fix `Alert` component issues
|
|
@@ -68,6 +67,10 @@ Change log:
|
|
|
68
67
|
- Accessibility improvements: table actions, aria-sort, checkbox focus and general accessibility fixes across components
|
|
69
68
|
- Documentation updates: enhanced component examples and usage guidelines for `Dropdown`, `Chart`, `Select`
|
|
70
69
|
|
|
70
|
+
### 3.5.1
|
|
71
|
+
|
|
72
|
+
Edit mode in the `Nav` component has been added.
|
|
73
|
+
|
|
71
74
|
### 3.5.0
|
|
72
75
|
|
|
73
76
|
Accessibility improvements, new DateInput control in FiltersBar, custom chart legend formatting, and new languages support. Plus several performance and stability fixes.
|
|
@@ -303,8 +303,13 @@ const GroupsFilterRaw = props => {
|
|
|
303
303
|
const prevSearchField = (0, react_1.useRef)("");
|
|
304
304
|
const groupsFilterId = (0, react_1.useId)();
|
|
305
305
|
const popupId = (0, react_1.useId)();
|
|
306
|
-
const isDataLoadedRef = (0, react_1.useRef)(false);
|
|
307
306
|
const blocksMap = (0, react_1.useMemo)(() => [["builtInGroups", "userGroups"], ["advancedGroups", "builtInGroups", "userGroups"], ["builtInGroups", "userGroups"]], []);
|
|
307
|
+
const onOptionsToggle = (0, react_1.useCallback)(() => {
|
|
308
|
+
dispatchUiState({
|
|
309
|
+
type: uiStateActionType_1.UiStateActionType.ToggleOpen,
|
|
310
|
+
payload: undefined
|
|
311
|
+
});
|
|
312
|
+
}, []);
|
|
308
313
|
const handleSetStep = (0, react_1.useCallback)(newStep => {
|
|
309
314
|
var _a;
|
|
310
315
|
uiState.step !== groupsFilterInterfaces_1.FilterMenuStep.CurrentlySelected && dispatchUiState({
|
|
@@ -553,8 +558,7 @@ const GroupsFilterRaw = props => {
|
|
|
553
558
|
errorHandler(e);
|
|
554
559
|
return [];
|
|
555
560
|
}), [dataLoader, errorHandler]);
|
|
556
|
-
|
|
557
|
-
isDataLoadedRef.current = true;
|
|
561
|
+
(0, react_1.useEffect)(() => {
|
|
558
562
|
dispatchUiState({
|
|
559
563
|
type: uiStateActionType_1.UiStateActionType.SetLoadWithError,
|
|
560
564
|
payload: {
|
|
@@ -583,32 +587,9 @@ const GroupsFilterRaw = props => {
|
|
|
583
587
|
isLoading: false
|
|
584
588
|
}
|
|
585
589
|
});
|
|
586
|
-
isDataLoadedRef.current = false;
|
|
587
590
|
errorHandler(e);
|
|
588
591
|
});
|
|
589
592
|
}, [dataLoader, errorHandler]);
|
|
590
|
-
(0, react_1.useEffect)(() => {
|
|
591
|
-
if (isDataLoadedRef.current) {
|
|
592
|
-
return;
|
|
593
|
-
}
|
|
594
|
-
loadData();
|
|
595
|
-
}, [loadData]);
|
|
596
|
-
const onOptionsToggle = (0, react_1.useCallback)(() => {
|
|
597
|
-
const willBeOpen = !uiState.isOpen;
|
|
598
|
-
dispatchUiState({
|
|
599
|
-
type: uiStateActionType_1.UiStateActionType.ToggleOpen,
|
|
600
|
-
payload: undefined
|
|
601
|
-
});
|
|
602
|
-
if (willBeOpen && !isDataLoadedRef.current && !uiState.isLoading) {
|
|
603
|
-
loadData();
|
|
604
|
-
}
|
|
605
|
-
}, [uiState.isOpen, uiState.isLoading, loadData]);
|
|
606
|
-
const isEmptyMap = dataItems.length === 0;
|
|
607
|
-
(0, react_1.useEffect)(() => {
|
|
608
|
-
if (isEmptyMap && uiState.isOpen && !uiState.isLoading && !uiState.hasError) {
|
|
609
|
-
loadData();
|
|
610
|
-
}
|
|
611
|
-
}, [uiState.isOpen, isEmptyMap, uiState.isLoading, uiState.hasError, loadData]);
|
|
612
593
|
(0, react_1.useEffect)(() => {
|
|
613
594
|
const step = uiState.step;
|
|
614
595
|
if (step !== groupsFilterInterfaces_1.FilterMenuStep.CurrentlySelected) {
|
|
@@ -849,6 +830,41 @@ const GroupsFilterRaw = props => {
|
|
|
849
830
|
children: translate("Clear")
|
|
850
831
|
})]
|
|
851
832
|
}), [handleApply, handleCancel, handleReset, isApplyDisabled, translate]);
|
|
833
|
+
const isEmptyMap = dataItems.length === 0;
|
|
834
|
+
(0, react_1.useEffect)(() => {
|
|
835
|
+
if (isEmptyMap && uiState.isOpen && !uiState.isLoading && !uiState.hasError) {
|
|
836
|
+
dispatchUiState({
|
|
837
|
+
type: uiStateActionType_1.UiStateActionType.SetLoadWithError,
|
|
838
|
+
payload: {
|
|
839
|
+
hasError: false,
|
|
840
|
+
isLoading: true
|
|
841
|
+
}
|
|
842
|
+
});
|
|
843
|
+
dataLoader().then(groups => {
|
|
844
|
+
dispatchState({
|
|
845
|
+
type: stateActionType_1.StateActionType.CreateGroupsMap,
|
|
846
|
+
payload: groups
|
|
847
|
+
});
|
|
848
|
+
dispatchUiState({
|
|
849
|
+
type: uiStateActionType_1.UiStateActionType.SetLoadWithError,
|
|
850
|
+
payload: {
|
|
851
|
+
hasError: false,
|
|
852
|
+
isLoading: false
|
|
853
|
+
}
|
|
854
|
+
});
|
|
855
|
+
setDataItems(groups);
|
|
856
|
+
}).catch(e => {
|
|
857
|
+
dispatchUiState({
|
|
858
|
+
type: uiStateActionType_1.UiStateActionType.SetLoadWithError,
|
|
859
|
+
payload: {
|
|
860
|
+
hasError: true,
|
|
861
|
+
isLoading: false
|
|
862
|
+
}
|
|
863
|
+
});
|
|
864
|
+
errorHandler(e);
|
|
865
|
+
});
|
|
866
|
+
}
|
|
867
|
+
}, [uiState.isOpen, isEmptyMap, uiState.isLoading, uiState.hasError, dataLoader, errorHandler]);
|
|
852
868
|
const memoizedMobileView = (0, react_1.useMemo)(() => (0, jsx_runtime_1.jsxs)(mobileSheet_1.MobileSheet, {
|
|
853
869
|
label: translate("Organization groups filter"),
|
|
854
870
|
triggerRef: triggerRef,
|
package/dist/modal/modal.js
CHANGED
|
@@ -84,9 +84,9 @@ const dialogHelpers_1 = require("../dialog/dialogHelpers");
|
|
|
84
84
|
const themeContext_1 = require("../utils/theme/themeContext");
|
|
85
85
|
const modalHelpers_1 = require("./modalHelpers");
|
|
86
86
|
const textIconButton_1 = require("../textIconButton/textIconButton");
|
|
87
|
-
const usePortal_1 = require("../commonHelpers/hooks/usePortal");
|
|
88
87
|
const useClientReady_1 = require("../commonHelpers/hooks/useClientReady");
|
|
89
88
|
const zen_1 = require("../utils/zen");
|
|
89
|
+
const react_dom_1 = require("react-dom");
|
|
90
90
|
const Modal = ({
|
|
91
91
|
isOpen,
|
|
92
92
|
children,
|
|
@@ -101,8 +101,6 @@ const Modal = ({
|
|
|
101
101
|
}) => {
|
|
102
102
|
var _a, _b, _c;
|
|
103
103
|
const lastActiveOutsideElement = (0, react_1.useRef)((_a = zen_1.zen.document) === null || _a === void 0 ? void 0 : _a.activeElement);
|
|
104
|
-
// eslint-disable-next-line
|
|
105
|
-
const modalRoot = ((_b = zen_1.zen === null || zen_1.zen === void 0 ? void 0 : zen_1.zen.document) === null || _b === void 0 ? void 0 : _b.fullscreenElement) || ((_c = zen_1.zen === null || zen_1.zen === void 0 ? void 0 : zen_1.zen.document) === null || _c === void 0 ? void 0 : _c.body);
|
|
106
104
|
const [top, setTop] = (0, react_1.useState)(`${zen_1.zen.pageYOffset || 0}px`);
|
|
107
105
|
const {
|
|
108
106
|
dark
|
|
@@ -190,11 +188,11 @@ const Modal = ({
|
|
|
190
188
|
onClick: onOutSideClick
|
|
191
189
|
})]
|
|
192
190
|
}), [darkClass, modalContainerClassName, labeledId, top, onClose, maxWidth, title, className, type, focus, modalContent, onOutSideClick]);
|
|
193
|
-
const modalPortal = (0, usePortal_1.usePortal)(dialogHTML(labeledId), isOpen ? modalRoot : undefined);
|
|
194
191
|
if (!isOpen || !isClientReady) {
|
|
195
192
|
return null;
|
|
196
193
|
}
|
|
197
|
-
|
|
194
|
+
const modalRoot = ((_b = zen_1.zen.document) === null || _b === void 0 ? void 0 : _b.fullscreenElement) || ((_c = zen_1.zen.document) === null || _c === void 0 ? void 0 : _c.body);
|
|
195
|
+
return (0, react_dom_1.createPortal)(dialogHTML(labeledId), modalRoot);
|
|
198
196
|
};
|
|
199
197
|
exports.Modal = Modal;
|
|
200
198
|
const dummyOnClose = () => {};
|
|
@@ -217,10 +215,10 @@ const DialogContentNew = ({
|
|
|
217
215
|
const lastActiveOutsideElement = (0, react_1.useRef)((_a = zen_1.zen.document) === null || _a === void 0 ? void 0 : _a.activeElement);
|
|
218
216
|
const iconDriveClassName = (0, useDriveClassName_1.useDriveClassName)("icon");
|
|
219
217
|
const iconsByType = (0, react_1.useMemo)(() => ({
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
218
|
+
error: iconException_1.IconException,
|
|
219
|
+
success: iconCheckRadio_1.IconCheckRadio,
|
|
220
|
+
warning: iconWarning_1.IconWarning,
|
|
221
|
+
info: iconInfoCircle_1.IconInfoCircle
|
|
224
222
|
}), []);
|
|
225
223
|
const subscriptionCondition = (0, react_1.useCallback)(trigger => trigger.current !== null, []);
|
|
226
224
|
(0, useTrapFocus_1.useTrapFocus)(contentRef, undefined, contentRef, subscriptionCondition);
|
|
@@ -295,8 +295,13 @@ export const GroupsFilterRaw = props => {
|
|
|
295
295
|
const prevSearchField = useRef("");
|
|
296
296
|
const groupsFilterId = useId();
|
|
297
297
|
const popupId = useId();
|
|
298
|
-
const isDataLoadedRef = useRef(false);
|
|
299
298
|
const blocksMap = useMemo(() => [["builtInGroups", "userGroups"], ["advancedGroups", "builtInGroups", "userGroups"], ["builtInGroups", "userGroups"]], []);
|
|
299
|
+
const onOptionsToggle = useCallback(() => {
|
|
300
|
+
dispatchUiState({
|
|
301
|
+
type: UiStateActionType.ToggleOpen,
|
|
302
|
+
payload: undefined
|
|
303
|
+
});
|
|
304
|
+
}, []);
|
|
300
305
|
const handleSetStep = useCallback(newStep => {
|
|
301
306
|
var _a;
|
|
302
307
|
uiState.step !== FilterMenuStep.CurrentlySelected && dispatchUiState({
|
|
@@ -545,8 +550,7 @@ export const GroupsFilterRaw = props => {
|
|
|
545
550
|
errorHandler(e);
|
|
546
551
|
return [];
|
|
547
552
|
}), [dataLoader, errorHandler]);
|
|
548
|
-
|
|
549
|
-
isDataLoadedRef.current = true;
|
|
553
|
+
useEffect(() => {
|
|
550
554
|
dispatchUiState({
|
|
551
555
|
type: UiStateActionType.SetLoadWithError,
|
|
552
556
|
payload: {
|
|
@@ -575,32 +579,9 @@ export const GroupsFilterRaw = props => {
|
|
|
575
579
|
isLoading: false
|
|
576
580
|
}
|
|
577
581
|
});
|
|
578
|
-
isDataLoadedRef.current = false;
|
|
579
582
|
errorHandler(e);
|
|
580
583
|
});
|
|
581
584
|
}, [dataLoader, errorHandler]);
|
|
582
|
-
useEffect(() => {
|
|
583
|
-
if (isDataLoadedRef.current) {
|
|
584
|
-
return;
|
|
585
|
-
}
|
|
586
|
-
loadData();
|
|
587
|
-
}, [loadData]);
|
|
588
|
-
const onOptionsToggle = useCallback(() => {
|
|
589
|
-
const willBeOpen = !uiState.isOpen;
|
|
590
|
-
dispatchUiState({
|
|
591
|
-
type: UiStateActionType.ToggleOpen,
|
|
592
|
-
payload: undefined
|
|
593
|
-
});
|
|
594
|
-
if (willBeOpen && !isDataLoadedRef.current && !uiState.isLoading) {
|
|
595
|
-
loadData();
|
|
596
|
-
}
|
|
597
|
-
}, [uiState.isOpen, uiState.isLoading, loadData]);
|
|
598
|
-
const isEmptyMap = dataItems.length === 0;
|
|
599
|
-
useEffect(() => {
|
|
600
|
-
if (isEmptyMap && uiState.isOpen && !uiState.isLoading && !uiState.hasError) {
|
|
601
|
-
loadData();
|
|
602
|
-
}
|
|
603
|
-
}, [uiState.isOpen, isEmptyMap, uiState.isLoading, uiState.hasError, loadData]);
|
|
604
585
|
useEffect(() => {
|
|
605
586
|
const step = uiState.step;
|
|
606
587
|
if (step !== FilterMenuStep.CurrentlySelected) {
|
|
@@ -841,6 +822,41 @@ export const GroupsFilterRaw = props => {
|
|
|
841
822
|
children: translate("Clear")
|
|
842
823
|
})]
|
|
843
824
|
}), [handleApply, handleCancel, handleReset, isApplyDisabled, translate]);
|
|
825
|
+
const isEmptyMap = dataItems.length === 0;
|
|
826
|
+
useEffect(() => {
|
|
827
|
+
if (isEmptyMap && uiState.isOpen && !uiState.isLoading && !uiState.hasError) {
|
|
828
|
+
dispatchUiState({
|
|
829
|
+
type: UiStateActionType.SetLoadWithError,
|
|
830
|
+
payload: {
|
|
831
|
+
hasError: false,
|
|
832
|
+
isLoading: true
|
|
833
|
+
}
|
|
834
|
+
});
|
|
835
|
+
dataLoader().then(groups => {
|
|
836
|
+
dispatchState({
|
|
837
|
+
type: StateActionType.CreateGroupsMap,
|
|
838
|
+
payload: groups
|
|
839
|
+
});
|
|
840
|
+
dispatchUiState({
|
|
841
|
+
type: UiStateActionType.SetLoadWithError,
|
|
842
|
+
payload: {
|
|
843
|
+
hasError: false,
|
|
844
|
+
isLoading: false
|
|
845
|
+
}
|
|
846
|
+
});
|
|
847
|
+
setDataItems(groups);
|
|
848
|
+
}).catch(e => {
|
|
849
|
+
dispatchUiState({
|
|
850
|
+
type: UiStateActionType.SetLoadWithError,
|
|
851
|
+
payload: {
|
|
852
|
+
hasError: true,
|
|
853
|
+
isLoading: false
|
|
854
|
+
}
|
|
855
|
+
});
|
|
856
|
+
errorHandler(e);
|
|
857
|
+
});
|
|
858
|
+
}
|
|
859
|
+
}, [uiState.isOpen, isEmptyMap, uiState.isLoading, uiState.hasError, dataLoader, errorHandler]);
|
|
844
860
|
const memoizedMobileView = useMemo(() => _jsxs(MobileSheet, {
|
|
845
861
|
label: translate("Organization groups filter"),
|
|
846
862
|
triggerRef: triggerRef,
|
package/esm/modal/modal.js
CHANGED
|
@@ -19,9 +19,9 @@ import { isFocusable } from "../dialog/dialogHelpers";
|
|
|
19
19
|
import { themeContext } from "../utils/theme/themeContext";
|
|
20
20
|
import { getPredefinedFocusableItem } from "./modalHelpers";
|
|
21
21
|
import { TextIconButton } from "../textIconButton/textIconButton";
|
|
22
|
-
import { usePortal } from "../commonHelpers/hooks/usePortal";
|
|
23
22
|
import { useClientReady } from "../commonHelpers/hooks/useClientReady";
|
|
24
23
|
import { zen } from "../utils/zen";
|
|
24
|
+
import { createPortal } from "react-dom";
|
|
25
25
|
injectString("cs", "Close", "Zav\u0159\xEDt");
|
|
26
26
|
injectString("da-DK", "Close", "Luk");
|
|
27
27
|
injectString("de", "Close", "Schlie\xDFen");
|
|
@@ -62,8 +62,6 @@ export const Modal = ({
|
|
|
62
62
|
}) => {
|
|
63
63
|
var _a, _b, _c;
|
|
64
64
|
const lastActiveOutsideElement = useRef((_a = zen.document) === null || _a === void 0 ? void 0 : _a.activeElement);
|
|
65
|
-
// eslint-disable-next-line
|
|
66
|
-
const modalRoot = ((_b = zen === null || zen === void 0 ? void 0 : zen.document) === null || _b === void 0 ? void 0 : _b.fullscreenElement) || ((_c = zen === null || zen === void 0 ? void 0 : zen.document) === null || _c === void 0 ? void 0 : _c.body);
|
|
67
65
|
const [top, setTop] = useState(`${zen.pageYOffset || 0}px`);
|
|
68
66
|
const {
|
|
69
67
|
dark
|
|
@@ -151,11 +149,11 @@ export const Modal = ({
|
|
|
151
149
|
onClick: onOutSideClick
|
|
152
150
|
})]
|
|
153
151
|
}), [darkClass, modalContainerClassName, labeledId, top, onClose, maxWidth, title, className, type, focus, modalContent, onOutSideClick]);
|
|
154
|
-
const modalPortal = usePortal(dialogHTML(labeledId), isOpen ? modalRoot : undefined);
|
|
155
152
|
if (!isOpen || !isClientReady) {
|
|
156
153
|
return null;
|
|
157
154
|
}
|
|
158
|
-
|
|
155
|
+
const modalRoot = ((_b = zen.document) === null || _b === void 0 ? void 0 : _b.fullscreenElement) || ((_c = zen.document) === null || _c === void 0 ? void 0 : _c.body);
|
|
156
|
+
return createPortal(dialogHTML(labeledId), modalRoot);
|
|
159
157
|
};
|
|
160
158
|
const dummyOnClose = () => {};
|
|
161
159
|
export const DialogContentNew = ({
|
|
@@ -177,10 +175,10 @@ export const DialogContentNew = ({
|
|
|
177
175
|
const lastActiveOutsideElement = useRef((_a = zen.document) === null || _a === void 0 ? void 0 : _a.activeElement);
|
|
178
176
|
const iconDriveClassName = useDriveClassName("icon");
|
|
179
177
|
const iconsByType = useMemo(() => ({
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
178
|
+
error: IconException,
|
|
179
|
+
success: IconCheckRadio,
|
|
180
|
+
warning: IconWarning,
|
|
181
|
+
info: IconInfoCircle
|
|
184
182
|
}), []);
|
|
185
183
|
const subscriptionCondition = useCallback(trigger => trigger.current !== null, []);
|
|
186
184
|
useTrapFocus(contentRef, undefined, contentRef, subscriptionCondition);
|