@geotab/zenith 3.6.0-ssr.beta.0 → 3.6.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.
@@ -19,8 +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";
22
+ import { useClientReady } from "../commonHelpers/hooks/useClientReady";
23
23
  import { zen } from "../utils/zen";
24
+ import { createPortal } from "react-dom";
24
25
  injectString("cs", "Close", "Zav\u0159\xEDt");
25
26
  injectString("da-DK", "Close", "Luk");
26
27
  injectString("de", "Close", "Schlie\xDFen");
@@ -61,26 +62,34 @@ export const Modal = ({
61
62
  }) => {
62
63
  var _a, _b, _c;
63
64
  const lastActiveOutsideElement = useRef((_a = zen.document) === null || _a === void 0 ? void 0 : _a.activeElement);
64
- // eslint-disable-next-line
65
- 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);
66
65
  const [top, setTop] = useState(`${zen.pageYOffset || 0}px`);
67
66
  const {
68
67
  dark
69
68
  } = useContext(themeContext);
69
+ const isClientReady = useClientReady();
70
70
  const onOutSideClick = useCallback(() => {
71
+ if (!isClientReady) {
72
+ return;
73
+ }
71
74
  if (!isOpen || !closeOnClickOutside || !onClose) {
72
75
  return;
73
76
  }
74
77
  onClose();
75
- }, [isOpen, closeOnClickOutside, onClose]);
78
+ }, [isClientReady, isOpen, closeOnClickOutside, onClose]);
76
79
  useEffect(() => {
80
+ if (!isClientReady) {
81
+ return undefined;
82
+ }
77
83
  const copyActive = lastActiveOutsideElement.current;
78
84
  return () => {
79
85
  isFocusable(copyActive) && copyActive.focus();
80
86
  };
81
- }, []);
87
+ }, [isClientReady]);
82
88
  useEffect(() => {
83
89
  var _a, _b;
90
+ if (!isClientReady) {
91
+ return undefined;
92
+ }
84
93
  (_a = zen.document) === null || _a === void 0 ? void 0 : _a.body.classList.remove("zen-modal-content--hidden-overflow");
85
94
  if (isOpen) {
86
95
  (_b = zen.document) === null || _b === void 0 ? void 0 : _b.body.classList.add("zen-modal-content--hidden-overflow");
@@ -89,9 +98,12 @@ export const Modal = ({
89
98
  var _a;
90
99
  (_a = zen.document) === null || _a === void 0 ? void 0 : _a.body.classList.remove("zen-modal-content--hidden-overflow");
91
100
  };
92
- }, [isOpen]);
101
+ }, [isClientReady, isOpen]);
93
102
  useEffect(() => {
94
103
  var _a, _b;
104
+ if (!isClientReady) {
105
+ return undefined;
106
+ }
95
107
  const changeTopSpace = () => {
96
108
  setTop(`${zen.pageYOffset || 0}px`);
97
109
  };
@@ -102,7 +114,7 @@ export const Modal = ({
102
114
  (_a = zen.removeEventListener) === null || _a === void 0 ? void 0 : _a.call(zen, "resize", changeTopSpace);
103
115
  (_b = zen.removeEventListener) === null || _b === void 0 ? void 0 : _b.call(zen, "scroll", changeTopSpace);
104
116
  };
105
- }, []);
117
+ }, [isClientReady]);
106
118
  const labeledId = useId();
107
119
  const darkClass = dark ? "zen-dark" : "";
108
120
  const modalContent = useMemo(() => {
@@ -137,11 +149,11 @@ export const Modal = ({
137
149
  onClick: onOutSideClick
138
150
  })]
139
151
  }), [darkClass, modalContainerClassName, labeledId, top, onClose, maxWidth, title, className, type, focus, modalContent, onOutSideClick]);
140
- const modalPortal = usePortal(dialogHTML(labeledId), isOpen ? modalRoot : undefined);
141
- if (!isOpen) {
152
+ if (!isOpen || !isClientReady) {
142
153
  return null;
143
154
  }
144
- return modalPortal;
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);
145
157
  };
146
158
  const dummyOnClose = () => {};
147
159
  export const DialogContentNew = ({
@@ -163,10 +175,10 @@ export const DialogContentNew = ({
163
175
  const lastActiveOutsideElement = useRef((_a = zen.document) === null || _a === void 0 ? void 0 : _a.activeElement);
164
176
  const iconDriveClassName = useDriveClassName("icon");
165
177
  const iconsByType = useMemo(() => ({
166
- "error": IconException,
167
- "success": IconCheckRadio,
168
- "warning": IconWarning,
169
- "info": IconInfoCircle
178
+ error: IconException,
179
+ success: IconCheckRadio,
180
+ warning: IconWarning,
181
+ info: IconInfoCircle
170
182
  }), []);
171
183
  const subscriptionCondition = useCallback(trigger => trigger.current !== null, []);
172
184
  useTrapFocus(contentRef, undefined, contentRef, subscriptionCondition);
@@ -15,6 +15,7 @@ import { useMobile } from "../commonHelpers/hooks/useMobile";
15
15
  import { isAlertTarget } from "../alert/utils/isAlertTarget";
16
16
  import { isToastTarget } from "../toast/utils/isToastTarget";
17
17
  import { usePortal } from "../commonHelpers/hooks/usePortal";
18
+ import { useClientReady } from "../commonHelpers/hooks/useClientReady";
18
19
  import { zen } from "../utils/zen";
19
20
  /* eslint-enable @typescript-eslint/naming-convention */
20
21
  export const isChildPopup = (target, stopElement) => {
@@ -60,16 +61,16 @@ export const SidePanel = ({ label, className, id, isOpen, onHidePanel, children,
60
61
  const autoId = useId();
61
62
  const popupId = id || autoId;
62
63
  const prevReadyForFocus = useRef(false);
63
- // ...existing code...
64
+ const isClientReady = useClientReady();
64
65
  useEffect(() => {
65
- if (triggerRef && triggerRef.current) {
66
+ if (triggerRef && triggerRef.current && isClientReady) {
66
67
  const triggerRole = triggerRef.current.dataset.role;
67
68
  triggerRef.current.setAttribute("aria-haspopup", triggerRole ? triggerRole : "true");
68
69
  triggerRef.current.setAttribute("aria-expanded", renderComponent ? "true" : "false");
69
70
  triggerRef.current.setAttribute("aria-controls", popupId);
70
71
  triggerRef.current.setAttribute("data-popup-id", popupId);
71
72
  }
72
- }, [triggerRef, renderComponent, popupId]);
73
+ }, [triggerRef, renderComponent, popupId, isClientReady]);
73
74
  function handleEscape() {
74
75
  onHidePanel(SidePanelCloseReason.Escape);
75
76
  if (!triggerRef || !triggerRef.current) {
@@ -82,10 +83,13 @@ export const SidePanel = ({ label, className, id, isOpen, onHidePanel, children,
82
83
  const focusable = Array.from(triggerRef.current.querySelectorAll(FOCUSABLE_SELECTOR));
83
84
  (focusable[0] || triggerRef.current).focus();
84
85
  }
85
- useTrapFocus(sidePanelRef, useTrapFocusWithTrigger ? triggerRef : undefined, showContent);
86
- useEscape(sidePanelRef, handleEscape, renderComponent);
86
+ useTrapFocus(sidePanelRef, useTrapFocusWithTrigger ? triggerRef : undefined, showContent && isClientReady);
87
+ useEscape(sidePanelRef, handleEscape, renderComponent && isClientReady);
87
88
  useEffect(() => {
88
89
  var _a, _b, _c;
90
+ if (!isClientReady) {
91
+ return undefined;
92
+ }
89
93
  // eslint-disable-next-line complexity
90
94
  const closeOnClickOutside = (e) => {
91
95
  var _a, _b, _c, _d, _e, _f;
@@ -143,7 +147,7 @@ export const SidePanel = ({ label, className, id, isOpen, onHidePanel, children,
143
147
  prevReadyForFocus.current = false;
144
148
  }
145
149
  return () => { var _a; return (_a = zen.document) === null || _a === void 0 ? void 0 : _a.body.removeEventListener("click", closeOnClickOutside, true); };
146
- }, [renderComponent, readyForFocus, onHidePanel, triggerRef, useTrapFocusWithTrigger, preventFirstFocus]);
150
+ }, [renderComponent, readyForFocus, onHidePanel, triggerRef, useTrapFocusWithTrigger, preventFirstFocus, isClientReady]);
147
151
  useEffect(() => {
148
152
  setIsOpen(isOpen);
149
153
  }, [isOpen, setIsOpen]);
@@ -169,6 +173,9 @@ export const SidePanel = ({ label, className, id, isOpen, onHidePanel, children,
169
173
  if (!renderComponent && !isOpen) {
170
174
  return null;
171
175
  }
176
+ if (!isClientReady) {
177
+ return undefined;
178
+ }
172
179
  return portal;
173
180
  };
174
181
  SidePanel.Cell = SidePanelCell;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@geotab/zenith",
3
- "version": "3.6.0-ssr.beta.0",
3
+ "version": "3.6.0",
4
4
  "description": "Zenith components library on React",
5
5
  "main": "dist/index.js",
6
6
  "types": "esm/index.d.ts",
@@ -98,6 +98,9 @@
98
98
  "react": "^19.2.0",
99
99
  "react-dom": "^19.2.0"
100
100
  },
101
+ "overrides": {
102
+ "serialize-javascript": "^7.0.3"
103
+ },
101
104
  "files": [
102
105
  "./dist/",
103
106
  "./esm"