carbon-react 151.2.3 → 151.4.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 (50) hide show
  1. package/esm/__internal__/dom/globals.d.ts +51 -0
  2. package/esm/__internal__/dom/globals.js +59 -0
  3. package/esm/__spec_helper__/mock-element-scrollto.js +3 -0
  4. package/esm/__spec_helper__/mock-match-media.js +1 -1
  5. package/esm/__spec_helper__/mock-resize-observer.js +1 -1
  6. package/esm/components/adaptive-sidebar/__internal__/utils.d.ts +6 -0
  7. package/esm/components/adaptive-sidebar/__internal__/utils.js +23 -0
  8. package/esm/components/adaptive-sidebar/adaptive-sidebar.component.d.ts +25 -0
  9. package/esm/components/adaptive-sidebar/adaptive-sidebar.component.js +56 -0
  10. package/esm/components/adaptive-sidebar/adaptive-sidebar.style.d.ts +12 -0
  11. package/esm/components/adaptive-sidebar/adaptive-sidebar.style.js +35 -0
  12. package/esm/components/adaptive-sidebar/index.d.ts +2 -0
  13. package/esm/components/adaptive-sidebar/index.js +1 -0
  14. package/esm/components/box/box.component.d.ts +2 -0
  15. package/esm/components/box/box.component.js +3 -1
  16. package/esm/components/flat-table/flat-table-row/flat-table-row.style.js +4 -1
  17. package/esm/components/icon/icon.style.js +6 -4
  18. package/esm/components/menu/menu-full-screen/menu-full-screen.component.js +2 -1
  19. package/esm/components/modal/__internal__/modal-manager.js +18 -7
  20. package/esm/components/modal/modal.component.js +3 -1
  21. package/esm/components/sidebar/sidebar.component.d.ts +6 -0
  22. package/esm/components/sidebar/sidebar.component.js +3 -1
  23. package/esm/components/vertical-menu/vertical-menu-full-screen/vertical-menu-full-screen.component.js +3 -1
  24. package/esm/hooks/__internal__/useScrollBlock/scroll-block-manager.js +11 -4
  25. package/lib/__internal__/dom/globals.d.ts +51 -0
  26. package/lib/__internal__/dom/globals.js +67 -0
  27. package/lib/__spec_helper__/mock-element-scrollto.js +3 -0
  28. package/lib/__spec_helper__/mock-match-media.js +1 -1
  29. package/lib/__spec_helper__/mock-resize-observer.js +1 -1
  30. package/lib/components/adaptive-sidebar/__internal__/utils.d.ts +6 -0
  31. package/lib/components/adaptive-sidebar/__internal__/utils.js +31 -0
  32. package/lib/components/adaptive-sidebar/adaptive-sidebar.component.d.ts +25 -0
  33. package/lib/components/adaptive-sidebar/adaptive-sidebar.component.js +66 -0
  34. package/lib/components/adaptive-sidebar/adaptive-sidebar.style.d.ts +12 -0
  35. package/lib/components/adaptive-sidebar/adaptive-sidebar.style.js +43 -0
  36. package/lib/components/adaptive-sidebar/index.d.ts +2 -0
  37. package/lib/components/adaptive-sidebar/index.js +13 -0
  38. package/lib/components/adaptive-sidebar/package.json +6 -0
  39. package/lib/components/box/box.component.d.ts +2 -0
  40. package/lib/components/box/box.component.js +3 -1
  41. package/lib/components/flat-table/flat-table-row/flat-table-row.style.js +4 -1
  42. package/lib/components/icon/icon.style.js +6 -4
  43. package/lib/components/menu/menu-full-screen/menu-full-screen.component.js +2 -1
  44. package/lib/components/modal/__internal__/modal-manager.js +18 -7
  45. package/lib/components/modal/modal.component.js +3 -1
  46. package/lib/components/sidebar/sidebar.component.d.ts +6 -0
  47. package/lib/components/sidebar/sidebar.component.js +3 -1
  48. package/lib/components/vertical-menu/vertical-menu-full-screen/vertical-menu-full-screen.component.js +3 -1
  49. package/lib/hooks/__internal__/useScrollBlock/scroll-block-manager.js +12 -6
  50. package/package.json +4 -3
@@ -0,0 +1,51 @@
1
+ /**
2
+ * Returns the global `window` object in a way that is friendly to SSR.
3
+ * This check can be avoided if you are sure that the code will only run in the browser.
4
+ * Some examples where you can ignore this:
5
+ * - `useEffect` hooks
6
+ * - `useLayoutEffect` hooks
7
+ * - Callbacks for event listeners
8
+ * - Files with the `"use-client"` directive
9
+ *
10
+ * Primarily, this is necessary when attempting to access the `window` object during rendering of components.
11
+ * However, even still, where possible, it is recommended to avoid accessing the `window` object during rendering
12
+ * because it can lead to hydration mismatches. This happens when the server-rendered HTML differs from what the
13
+ * client renders due to missing environment-specific data (e.g., `window.innerWidth` being undefined on the server).
14
+ *
15
+ * @returns The global `window` object, if it exists.
16
+ */
17
+ export declare function getWindow(): (Window & typeof globalThis) | undefined;
18
+ /**
19
+ * Returns the global `document` object in a way that is friendly to SSR.
20
+ * This check can be avoided if you are sure that the code will only run in the browser.
21
+ * Some examples where you can ignore this:
22
+ * - `useEffect` hooks
23
+ * - `useLayoutEffect` hooks
24
+ * - Callbacks for event listeners
25
+ * - Files with the `"use-client"` directive
26
+ *
27
+ * Primarily, this is necessary when attempting to access the `document` object during rendering of components.
28
+ * However, even still, where possible, it is recommended to avoid accessing the `document` object during rendering
29
+ * because it can lead to hydration mismatches. This happens when the server-rendered HTML differs from what the
30
+ * client renders due to missing environment-specific data (e.g., `document.children` being undefined on the server).
31
+ *
32
+ * @returns The global `document` object, if it exists.
33
+ */
34
+ export declare function getDocument(): Document | undefined;
35
+ /**
36
+ * Returns the global `navigator` object in a way that is friendly to SSR.
37
+ * This check can be avoided if you are sure that the code will only run in the browser.
38
+ * Some examples where you can ignore this:
39
+ * - `useEffect` hooks
40
+ * - `useLayoutEffect` hooks
41
+ * - Callbacks for event listeners
42
+ * - Files with the `"use-client"` directive
43
+ *
44
+ * Primarily, this is necessary when attempting to access the `navigator` object during rendering of components.
45
+ * However, even still, where possible, it is recommended to avoid accessing the `navigator` object during rendering
46
+ * because it can lead to hydration mismatches. This happens when the server-rendered HTML differs from what the
47
+ * client renders due to missing environment-specific data (e.g., `navigator.userAgent` being undefined on the server).
48
+ *
49
+ * @returns The global `navigator` object, if it exists.
50
+ */
51
+ export declare function getNavigator(): Navigator | undefined;
@@ -0,0 +1,59 @@
1
+ /**
2
+ * Returns the global `window` object in a way that is friendly to SSR.
3
+ * This check can be avoided if you are sure that the code will only run in the browser.
4
+ * Some examples where you can ignore this:
5
+ * - `useEffect` hooks
6
+ * - `useLayoutEffect` hooks
7
+ * - Callbacks for event listeners
8
+ * - Files with the `"use-client"` directive
9
+ *
10
+ * Primarily, this is necessary when attempting to access the `window` object during rendering of components.
11
+ * However, even still, where possible, it is recommended to avoid accessing the `window` object during rendering
12
+ * because it can lead to hydration mismatches. This happens when the server-rendered HTML differs from what the
13
+ * client renders due to missing environment-specific data (e.g., `window.innerWidth` being undefined on the server).
14
+ *
15
+ * @returns The global `window` object, if it exists.
16
+ */
17
+ export function getWindow() {
18
+ return typeof window !== "undefined" ? window : undefined;
19
+ }
20
+
21
+ /**
22
+ * Returns the global `document` object in a way that is friendly to SSR.
23
+ * This check can be avoided if you are sure that the code will only run in the browser.
24
+ * Some examples where you can ignore this:
25
+ * - `useEffect` hooks
26
+ * - `useLayoutEffect` hooks
27
+ * - Callbacks for event listeners
28
+ * - Files with the `"use-client"` directive
29
+ *
30
+ * Primarily, this is necessary when attempting to access the `document` object during rendering of components.
31
+ * However, even still, where possible, it is recommended to avoid accessing the `document` object during rendering
32
+ * because it can lead to hydration mismatches. This happens when the server-rendered HTML differs from what the
33
+ * client renders due to missing environment-specific data (e.g., `document.children` being undefined on the server).
34
+ *
35
+ * @returns The global `document` object, if it exists.
36
+ */
37
+ export function getDocument() {
38
+ return typeof document !== "undefined" ? document : undefined;
39
+ }
40
+
41
+ /**
42
+ * Returns the global `navigator` object in a way that is friendly to SSR.
43
+ * This check can be avoided if you are sure that the code will only run in the browser.
44
+ * Some examples where you can ignore this:
45
+ * - `useEffect` hooks
46
+ * - `useLayoutEffect` hooks
47
+ * - Callbacks for event listeners
48
+ * - Files with the `"use-client"` directive
49
+ *
50
+ * Primarily, this is necessary when attempting to access the `navigator` object during rendering of components.
51
+ * However, even still, where possible, it is recommended to avoid accessing the `navigator` object during rendering
52
+ * because it can lead to hydration mismatches. This happens when the server-rendered HTML differs from what the
53
+ * client renders due to missing environment-specific data (e.g., `navigator.userAgent` being undefined on the server).
54
+ *
55
+ * @returns The global `navigator` object, if it exists.
56
+ */
57
+ export function getNavigator() {
58
+ return typeof navigator !== "undefined" ? navigator : undefined;
59
+ }
@@ -1,6 +1,9 @@
1
1
  const setupScrollToMock = () => {
2
2
  // need to mock the `scrollTo` method, which is undefined in JSDOM. As we're not actually testing this behaviour, just make it
3
3
  // do nothing.
4
+ if (typeof window === "undefined") {
5
+ return;
6
+ }
4
7
  HTMLElement.prototype.scrollTo = () => {};
5
8
  };
6
9
  export default setupScrollToMock;
@@ -2,7 +2,7 @@ let mocked = false;
2
2
  let _matches = false;
3
3
  const removeEventListener = jest.fn();
4
4
  export const setupMatchMediaMock = () => {
5
- if (!global.window) {
5
+ if (typeof window === "undefined") {
6
6
  return;
7
7
  }
8
8
  const noop = () => {};
@@ -1,5 +1,5 @@
1
1
  const setupResizeObserverMock = () => {
2
- if (!window) {
2
+ if (typeof window === "undefined") {
3
3
  return;
4
4
  }
5
5
  window.ResizeObserver = window.ResizeObserver || jest.fn().mockImplementation(callback => {
@@ -0,0 +1,6 @@
1
+ import { AdaptiveSidebarProps } from "../adaptive-sidebar.component";
2
+ export declare const getColors: (backgroundColor: AdaptiveSidebarProps["backgroundColor"]) => {
3
+ "background-color": string;
4
+ color: string;
5
+ };
6
+ export declare const kebabToCamelCase: (str: string) => string;
@@ -0,0 +1,23 @@
1
+ export const getColors = backgroundColor => {
2
+ switch (backgroundColor) {
3
+ case "app":
4
+ return {
5
+ "background-color": "var(--colorsUtilityMajor025)",
6
+ color: "var(--colorsUtilityYin090)"
7
+ };
8
+ case "black":
9
+ return {
10
+ "background-color": "var(--colorsUtilityYin100)",
11
+ color: "var(--colorsUtilityYang100)"
12
+ };
13
+ case "white":
14
+ default:
15
+ return {
16
+ "background-color": "var(--colorsUtilityYang100)",
17
+ color: "var(--colorsUtilityYin090)"
18
+ };
19
+ }
20
+ };
21
+ export const kebabToCamelCase = str => {
22
+ return str.replace(/-./g, match => match.charAt(1).toUpperCase());
23
+ };
@@ -0,0 +1,25 @@
1
+ import React from "react";
2
+ import { PaddingProps, MarginProps } from "styled-system";
3
+ import { TagProps } from "../../__internal__/utils/helpers/tags";
4
+ export interface AdaptiveSidebarProps extends MarginProps, PaddingProps, Omit<TagProps, "data-component"> {
5
+ /** The breakpoint (in pixels) at which the sidebar will convert to a dialog-based sidebar */
6
+ adaptiveBreakpoint?: number;
7
+ /** The time in milliseconds for the sidebar to animate */
8
+ animationTimeout?: number;
9
+ /** The background color of the sidebar */
10
+ backgroundColor?: "white" | "black" | "app";
11
+ /** The color to use for the left-hand border of the sidebar. Should be a design token e.g. `--colorsUtilityYang100` */
12
+ borderColor?: string | "none";
13
+ /** The content of the sidebar */
14
+ children?: React.ReactNode;
15
+ /** The height of the sidebar, relative to the wrapping component */
16
+ height?: string;
17
+ /** Whether the sidebar is open or closed */
18
+ open: boolean;
19
+ /** Whether to render the sidebar as a modal component instead of as an inline sidebar */
20
+ renderAsModal?: boolean;
21
+ /** The width of the sidebar */
22
+ width?: string;
23
+ }
24
+ export declare const AdaptiveSidebar: ({ adaptiveBreakpoint, backgroundColor, borderColor, children, height, open, renderAsModal, width, ...props }: AdaptiveSidebarProps) => React.JSX.Element | null;
25
+ export default AdaptiveSidebar;
@@ -0,0 +1,56 @@
1
+ function _extends() { return _extends = Object.assign ? Object.assign.bind() : function (n) { for (var e = 1; e < arguments.length; e++) { var t = arguments[e]; for (var r in t) ({}).hasOwnProperty.call(t, r) && (n[r] = t[r]); } return n; }, _extends.apply(null, arguments); }
2
+ import React, { useEffect, useRef } from "react";
3
+ import { getColors, kebabToCamelCase } from "./__internal__/utils";
4
+ import Box from "../box";
5
+ import { filterStyledSystemMarginProps, filterStyledSystemPaddingProps } from "../../style/utils";
6
+ import useIsAboveBreakpoint from "../../hooks/__internal__/useIsAboveBreakpoint";
7
+ import { StyledAdaptiveSidebar, StyledSidebar } from "./adaptive-sidebar.style";
8
+ export const AdaptiveSidebar = ({
9
+ adaptiveBreakpoint = 768,
10
+ backgroundColor = "white",
11
+ borderColor = "none",
12
+ children,
13
+ height = "100%",
14
+ open,
15
+ renderAsModal = false,
16
+ width = "320px",
17
+ ...props
18
+ }) => {
19
+ const largeScreen = useIsAboveBreakpoint(adaptiveBreakpoint);
20
+ const adaptiveSidebarRef = useRef(null);
21
+ const colours = Object.entries(getColors(backgroundColor)).reduce((acc, [key, value]) => {
22
+ acc[kebabToCamelCase(key)] = value;
23
+ return acc;
24
+ }, {});
25
+ useEffect(() => {
26
+ /* istanbul ignore next */
27
+ if (adaptiveSidebarRef.current) {
28
+ adaptiveSidebarRef.current.focus();
29
+ }
30
+ }, [open]);
31
+ if (renderAsModal || !largeScreen) {
32
+ return /*#__PURE__*/React.createElement(StyledSidebar, {
33
+ backgroundColor: backgroundColor,
34
+ open: open,
35
+ p: 0,
36
+ ref: adaptiveSidebarRef
37
+ }, /*#__PURE__*/React.createElement(Box, _extends({
38
+ height: "100%",
39
+ "data-role": "adaptive-sidebar-content-wrapper"
40
+ }, colours), children));
41
+ }
42
+ return open ? /*#__PURE__*/React.createElement(StyledAdaptiveSidebar, _extends({
43
+ backgroundColor: backgroundColor,
44
+ borderColor: borderColor === "none" ? undefined : borderColor,
45
+ "data-element": "adaptive-sidebar",
46
+ "data-role": "adaptive-sidebar",
47
+ height: height,
48
+ ref: adaptiveSidebarRef,
49
+ role: "region",
50
+ tabIndex: -1,
51
+ width: width
52
+ }, filterStyledSystemMarginProps(props), filterStyledSystemPaddingProps(props)), /*#__PURE__*/React.createElement(Box, {
53
+ "data-role": "adaptive-sidebar-content-wrapper"
54
+ }, children)) : null;
55
+ };
56
+ export default AdaptiveSidebar;
@@ -0,0 +1,12 @@
1
+ /// <reference types="react" />
2
+ import { MarginProps, PaddingProps } from "styled-system";
3
+ import { SidebarProps } from "../sidebar";
4
+ import { AdaptiveSidebarProps } from "./adaptive-sidebar.component";
5
+ declare const StyledAdaptiveSidebar: import("styled-components").StyledComponent<import("react").ForwardRefExoticComponent<import("../box").BoxProps & import("react").RefAttributes<HTMLDivElement>>, any, Pick<AdaptiveSidebarProps, "width" | "backgroundColor" | "height" | "borderColor"> & MarginProps<Required<import("styled-system").Theme<import("styled-system").TLengthStyledSystem>>> & PaddingProps<Required<import("styled-system").Theme<import("styled-system").TLengthStyledSystem>>> & {
6
+ tabIndex: number;
7
+ }, never>;
8
+ interface StyledSidebarProps extends SidebarProps {
9
+ backgroundColor: "app" | "black" | "white";
10
+ }
11
+ declare const StyledSidebar: import("styled-components").StyledComponent<import("react").ForwardRefExoticComponent<SidebarProps & import("react").RefAttributes<HTMLDivElement>>, any, StyledSidebarProps, never>;
12
+ export { StyledAdaptiveSidebar, StyledSidebar };
@@ -0,0 +1,35 @@
1
+ import styled, { css } from "styled-components";
2
+ import { margin, padding } from "styled-system";
3
+ import Box from "../box";
4
+ import Sidebar from "../sidebar";
5
+ import { getColors } from "./__internal__/utils";
6
+ const StyledAdaptiveSidebar = styled(Box)`
7
+ ${({
8
+ backgroundColor,
9
+ borderColor,
10
+ height,
11
+ width
12
+ }) => css`
13
+ ${getColors(backgroundColor)}
14
+ ${borderColor && css`
15
+ border-left: 1px solid var(${borderColor});
16
+ `}
17
+ max-height: ${height};
18
+ max-width: ${width};
19
+ min-width: ${width};
20
+ overflow-y: auto;
21
+
22
+ ${margin}
23
+ ${padding}
24
+ `};
25
+ `;
26
+ const StyledSidebar = styled(Sidebar)`
27
+ ${({
28
+ backgroundColor
29
+ }) => css`
30
+ div[data-element="sidebar-content"] {
31
+ ${getColors(backgroundColor)}
32
+ }
33
+ `}
34
+ `;
35
+ export { StyledAdaptiveSidebar, StyledSidebar };
@@ -0,0 +1,2 @@
1
+ export { default } from "./adaptive-sidebar.component";
2
+ export type { AdaptiveSidebarProps } from "./adaptive-sidebar.component";
@@ -0,0 +1 @@
1
+ export { default } from "./adaptive-sidebar.component";
@@ -51,6 +51,8 @@ export interface BoxProps extends FlexboxProps, Omit<GridProps, "gridGap" | "gri
51
51
  "aria-hidden"?: "true" | "false";
52
52
  /** @private @internal @ignore */
53
53
  "data-component"?: string;
54
+ /** @private @internal @ignore */
55
+ tabIndex?: number;
54
56
  }
55
57
  export declare const Box: React.ForwardRefExoticComponent<BoxProps & React.RefAttributes<HTMLDivElement>>;
56
58
  export default Box;
@@ -5,6 +5,7 @@ import StyledBox from "./box.style";
5
5
  import tagComponent from "../../__internal__/utils/helpers/tags";
6
6
  export const Box = /*#__PURE__*/React.forwardRef(({
7
7
  "data-component": dataComponent,
8
+ tabIndex,
8
9
  as,
9
10
  id,
10
11
  role,
@@ -63,7 +64,8 @@ export const Box = /*#__PURE__*/React.forwardRef(({
63
64
  borderRadius: borderRadius,
64
65
  "aria-hidden": ariaHidden
65
66
  }, tagComponent(dataComponent, rest), filterStyledSystemMarginProps(rest), filterStyledSystemPaddingProps(rest), filterStyledSystemFlexboxProps(rest), filterStyledSystemGridProps(rest), filterStyledSystemLayoutProps(rest), {
66
- cssProps: cssProps
67
+ cssProps: cssProps,
68
+ tabIndex: tabIndex
67
69
  }), children);
68
70
  });
69
71
  Box.displayName = "Box";
@@ -7,6 +7,7 @@ import StyledFlatTableHeader from "../flat-table-header/flat-table-header.style"
7
7
  import StyledIcon from "../../icon/icon.style";
8
8
  import { toColor } from "../../../style/utils/color";
9
9
  import addFocusStyling from "../../../style/utils/add-focus-styling";
10
+ import { getNavigator } from "../../../__internal__/dom/globals";
10
11
  import { isSafari } from "../../../__internal__/utils/helpers/browser-type-check";
11
12
  const horizontalBorderSizes = {
12
13
  medium: "2px",
@@ -101,6 +102,7 @@ const StyledFlatTableRow = styled.tr`
101
102
  draggable,
102
103
  rowHeight
103
104
  }) => {
105
+ const nav = getNavigator();
104
106
  const backgroundColor = bgColor ? toColor(theme, bgColor) : undefined;
105
107
  const customBorderColor = horizontalBorderColor ? toColor(theme, horizontalBorderColor) : undefined;
106
108
  const colorOfSelected = isInSidebar ? "var(--colorsUtilityMajor150)" : "var(--colorsUtilityMajor075)";
@@ -209,7 +211,8 @@ const StyledFlatTableRow = styled.tr`
209
211
  }
210
212
 
211
213
  /* Styling for safari. Position relative does not work on tr elements on Safari */
212
- ${isSafari(navigator) && css`
214
+ // FIXME: this can cause hydration mismatches during SSR.
215
+ ${nav && isSafari(nav) && css`
213
216
  position: -webkit-sticky;
214
217
  :after {
215
218
  border: none;
@@ -5,6 +5,7 @@ import baseTheme from "../../style/themes/base";
5
5
  import addFocusStyling from "../../style/utils/add-focus-styling";
6
6
  import styledColor from "../../style/utils/color";
7
7
  import getColorValue from "../../style/utils/get-color-value";
8
+ import { getNavigator, getWindow } from "../../__internal__/dom/globals";
8
9
  import browserTypeCheck, { isSafari } from "../../__internal__/utils/helpers/browser-type-check";
9
10
  import iconConfig from "./icon-config";
10
11
  import iconUnicodes from "./icon-unicodes";
@@ -48,6 +49,8 @@ const StyledIcon = styled.span`
48
49
  let finalHoverColor;
49
50
  let bgColor;
50
51
  let bgHoverColor;
52
+ const win = getWindow();
53
+ const nav = getNavigator();
51
54
  const adjustedBgSize = adjustIconBgSize(fontSize, bgSize);
52
55
  try {
53
56
  if (disabled) {
@@ -116,12 +119,11 @@ const StyledIcon = styled.span`
116
119
  font-size: ${iconConfig.iconSize[fontSize]};
117
120
  line-height: ${iconConfig.iconSize[fontSize]};
118
121
  `}
119
-
120
- ${type === "services" && browserTypeCheck(window) && css`
122
+ // FIXME: this can cause hydration mismatches during SSR.
123
+ ${win && type === "services" && browserTypeCheck(win) && css`
121
124
  margin-top: ${fontSize === "small" ? "-7px" : "-8px"};
122
125
  `}
123
-
124
- ${type === "services" && isSafari(navigator) && !browserTypeCheck(window) && css`
126
+ ${nav && win && type === "services" && isSafari(nav) && !browserTypeCheck(win) && css`
125
127
  margin-top: -6px;
126
128
  `}
127
129
 
@@ -10,6 +10,7 @@ import Icon from "../../icon";
10
10
  import Portal from "../../portal";
11
11
  import FocusTrap from "../../../__internal__/focus-trap";
12
12
  import MenuDivider from "../menu-divider/menu-divider.component";
13
+ import { getDocument } from "../../../__internal__/dom/globals";
13
14
  import useLocale from "../../../hooks/__internal__/useLocale";
14
15
  import useModalAria from "../../../hooks/__internal__/useModalAria";
15
16
  import useModalManager from "../../../hooks/__internal__/useModalManager";
@@ -54,7 +55,7 @@ export const MenuFullscreen = ({
54
55
  closeModal,
55
56
  modalRef: menuRef,
56
57
  topModalOverride,
57
- focusCallToActionElement: document.activeElement
58
+ focusCallToActionElement: getDocument()?.activeElement
58
59
  });
59
60
  return /*#__PURE__*/React.createElement("li", null, /*#__PURE__*/React.createElement(Portal, null, /*#__PURE__*/React.createElement(CSSTransition, {
60
61
  nodeRef: menuRef,
@@ -4,6 +4,7 @@ function _createClass(e, r, t) { return r && _defineProperties(e.prototype, r),
4
4
  function _defineProperty(e, r, t) { return (r = _toPropertyKey(r)) in e ? Object.defineProperty(e, r, { value: t, enumerable: !0, configurable: !0, writable: !0 }) : e[r] = t, e; }
5
5
  function _toPropertyKey(t) { var i = _toPrimitive(t, "string"); return "symbol" == typeof i ? i : i + ""; }
6
6
  function _toPrimitive(t, r) { if ("object" != typeof t || !t) return t; var e = t[Symbol.toPrimitive]; if (void 0 !== e) { var i = e.call(t, r || "default"); if ("object" != typeof i) return i; throw new TypeError("@@toPrimitive must return a primitive value."); } return ("string" === r ? String : Number)(t); }
7
+ import { getWindow } from "../../../__internal__/dom/globals";
7
8
  let ModalManagerInstance = /*#__PURE__*/function () {
8
9
  function ModalManagerInstance() {
9
10
  _classCallCheck(this, ModalManagerInstance);
@@ -27,12 +28,17 @@ let ModalManagerInstance = /*#__PURE__*/function () {
27
28
  });
28
29
  this.callTopModalSetters();
29
30
  });
31
+ const safeWindow = getWindow();
32
+ if (!safeWindow) {
33
+ this.modalList = [];
34
+ return;
35
+ }
30
36
  // Due to possibility of multiple carbon versions using it
31
37
  // it is necessary to maintain same structure in this global variable
32
- if (!window.__CARBON_INTERNALS_MODAL_LIST) {
33
- window.__CARBON_INTERNALS_MODAL_LIST = [];
38
+ if (!safeWindow.__CARBON_INTERNALS_MODAL_LIST) {
39
+ safeWindow.__CARBON_INTERNALS_MODAL_LIST = [];
34
40
  }
35
- this.modalList = window.__CARBON_INTERNALS_MODAL_LIST;
41
+ this.modalList = safeWindow.__CARBON_INTERNALS_MODAL_LIST;
36
42
  }
37
43
  return _createClass(ModalManagerInstance, [{
38
44
  key: "getTopModal",
@@ -78,16 +84,21 @@ let ModalManagerInstance = /*#__PURE__*/function () {
78
84
  }, {
79
85
  key: "clearList",
80
86
  value: function clearList() {
81
- window.__CARBON_INTERNALS_MODAL_LIST = [];
82
- this.modalList = window.__CARBON_INTERNALS_MODAL_LIST;
87
+ const safeWindow = getWindow();
88
+ const cleared = [];
89
+ if (safeWindow) {
90
+ safeWindow.__CARBON_INTERNALS_MODAL_LIST = cleared;
91
+ }
92
+ this.modalList = cleared;
83
93
  this.callTopModalSetters();
84
94
  }
85
95
  }, {
86
96
  key: "callTopModalSetters",
87
97
  value: function callTopModalSetters() {
88
- if (window.__CARBON_INTERNALS_MODAL_SETTER_LIST) {
98
+ const safeWindow = getWindow();
99
+ if (safeWindow?.__CARBON_INTERNALS_MODAL_SETTER_LIST) {
89
100
  const topModal = this.getTopModal()?.modal || null;
90
- for (const setTopModal of window.__CARBON_INTERNALS_MODAL_SETTER_LIST) {
101
+ for (const setTopModal of safeWindow.__CARBON_INTERNALS_MODAL_SETTER_LIST) {
91
102
  setTopModal(topModal);
92
103
  }
93
104
  }
@@ -3,6 +3,7 @@ import React, { useEffect, useRef, useCallback, useState } from "react";
3
3
  import { TransitionGroup, CSSTransition } from "react-transition-group";
4
4
  import useScrollBlock from "../../hooks/__internal__/useScrollBlock";
5
5
  import Portal from "../portal";
6
+ import { getDocument } from "../../__internal__/dom/globals";
6
7
  import Events from "../../__internal__/utils/helpers/events";
7
8
  import useModalManager from "../../hooks/__internal__/useModalManager";
8
9
  import { StyledModal, StyledModalBackground } from "./modal.style";
@@ -53,13 +54,14 @@ const Modal = ({
53
54
  onCancel(ev);
54
55
  }
55
56
  }, [disableClose, disableEscKey, onCancel]);
57
+ const safeDocument = getDocument();
56
58
  useModalManager({
57
59
  open,
58
60
  closeModal,
59
61
  modalRef: ref,
60
62
  setTriggerRefocusFlag,
61
63
  topModalOverride,
62
- focusCallToActionElement: restoreFocusOnClose ? document.activeElement : undefined
64
+ focusCallToActionElement: restoreFocusOnClose && safeDocument ? safeDocument.activeElement : undefined
63
65
  });
64
66
  let background;
65
67
  let content;
@@ -52,6 +52,12 @@ export interface SidebarProps extends PaddingProps, TagProps, WidthProps, Pick<M
52
52
  focusableSelectors?: string;
53
53
  /** Padding to be set on the Sidebar header */
54
54
  headerPadding?: PaddingProps;
55
+ /**
56
+ * @private
57
+ * @ignore
58
+ * @internal
59
+ * Sets className for component. INTERNAL USE ONLY. */
60
+ className?: string;
55
61
  }
56
62
  export declare const Sidebar: React.ForwardRefExoticComponent<SidebarProps & React.RefAttributes<HTMLDivElement>>;
57
63
  export default Sidebar;
@@ -38,6 +38,7 @@ export const Sidebar = /*#__PURE__*/React.forwardRef(({
38
38
  headerPadding = {},
39
39
  topModalOverride,
40
40
  restoreFocusOnClose = true,
41
+ className,
41
42
  ...rest
42
43
  }, ref) => {
43
44
  const locale = useLocale();
@@ -75,7 +76,8 @@ export const Sidebar = /*#__PURE__*/React.forwardRef(({
75
76
  size: size,
76
77
  onCancel: onCancel,
77
78
  role: role,
78
- width: width
79
+ width: width,
80
+ className: className
79
81
  }, header && /*#__PURE__*/React.createElement(SidebarHeader, _extends({
80
82
  closeIcon: closeIcon()
81
83
  }, headerPadding, {
@@ -9,6 +9,7 @@ import Icon from "../../icon";
9
9
  import Box from "../../box";
10
10
  import { StyledList, StyledVerticalMenuFullScreen } from "../vertical-menu.style";
11
11
  import VerticalMenuFullScreenContext from "./__internal__/vertical-menu-full-screen.context";
12
+ import { getDocument } from "../../../__internal__/dom/globals";
12
13
  import Events from "../../../__internal__/utils/helpers/events/events";
13
14
  import useModalManager from "../../../hooks/__internal__/useModalManager";
14
15
  export const VerticalMenuFullScreen = ({
@@ -27,12 +28,13 @@ export const VerticalMenuFullScreen = ({
27
28
  onClose(ev);
28
29
  }
29
30
  }, [onClose]);
31
+ const safeDocument = getDocument();
30
32
  useModalManager({
31
33
  open: isOpen,
32
34
  closeModal: handleKeyDown,
33
35
  modalRef: menuWrapperRef,
34
36
  topModalOverride: true,
35
- focusCallToActionElement: document.activeElement
37
+ focusCallToActionElement: safeDocument?.activeElement
36
38
  });
37
39
 
38
40
  // TODO remove this as part of FE-5650
@@ -6,24 +6,31 @@ function _toPropertyKey(t) { var i = _toPrimitive(t, "string"); return "symbol"
6
6
  function _toPrimitive(t, r) { if ("object" != typeof t || !t) return t; var e = t[Symbol.toPrimitive]; if (void 0 !== e) { var i = e.call(t, r || "default"); if ("object" != typeof i) return i; throw new TypeError("@@toPrimitive must return a primitive value."); } return ("string" === r ? String : Number)(t); }
7
7
  // TODO: This component can be refactored to remove redundant code
8
8
  // once we can confirm that all Sage products use version 105.0.0^
9
+ import { getWindow } from "../../../__internal__/dom/globals";
9
10
  let ScrollBlockManager = /*#__PURE__*/function () {
10
11
  function ScrollBlockManager() {
11
12
  _classCallCheck(this, ScrollBlockManager);
12
13
  _defineProperty(this, "components", void 0);
13
14
  _defineProperty(this, "originalValues", void 0);
15
+ const safeWindow = getWindow();
16
+ if (!safeWindow) {
17
+ this.components = {};
18
+ this.originalValues = [];
19
+ return;
20
+ }
14
21
  // Due to possibility of multiple carbon versions using it
15
22
  // it is necessary to maintain same structure in this global variable
16
- if (!window.__CARBON_INTERNALS_SCROLL_BLOCKERS) {
17
- window.__CARBON_INTERNALS_SCROLL_BLOCKERS = {
23
+ if (!safeWindow.__CARBON_INTERNALS_SCROLL_BLOCKERS) {
24
+ safeWindow.__CARBON_INTERNALS_SCROLL_BLOCKERS = {
18
25
  components: {},
19
26
  // originalValues can be removed
20
27
  originalValues: [],
21
28
  restoreValues: null
22
29
  };
23
30
  }
24
- this.components = window.__CARBON_INTERNALS_SCROLL_BLOCKERS.components;
31
+ this.components = safeWindow.__CARBON_INTERNALS_SCROLL_BLOCKERS.components;
25
32
  // TODO: originalValues can be removed
26
- this.originalValues = window.__CARBON_INTERNALS_SCROLL_BLOCKERS.originalValues;
33
+ this.originalValues = safeWindow.__CARBON_INTERNALS_SCROLL_BLOCKERS.originalValues;
27
34
  }
28
35
  return _createClass(ScrollBlockManager, [{
29
36
  key: "registerComponent",
@@ -0,0 +1,51 @@
1
+ /**
2
+ * Returns the global `window` object in a way that is friendly to SSR.
3
+ * This check can be avoided if you are sure that the code will only run in the browser.
4
+ * Some examples where you can ignore this:
5
+ * - `useEffect` hooks
6
+ * - `useLayoutEffect` hooks
7
+ * - Callbacks for event listeners
8
+ * - Files with the `"use-client"` directive
9
+ *
10
+ * Primarily, this is necessary when attempting to access the `window` object during rendering of components.
11
+ * However, even still, where possible, it is recommended to avoid accessing the `window` object during rendering
12
+ * because it can lead to hydration mismatches. This happens when the server-rendered HTML differs from what the
13
+ * client renders due to missing environment-specific data (e.g., `window.innerWidth` being undefined on the server).
14
+ *
15
+ * @returns The global `window` object, if it exists.
16
+ */
17
+ export declare function getWindow(): (Window & typeof globalThis) | undefined;
18
+ /**
19
+ * Returns the global `document` object in a way that is friendly to SSR.
20
+ * This check can be avoided if you are sure that the code will only run in the browser.
21
+ * Some examples where you can ignore this:
22
+ * - `useEffect` hooks
23
+ * - `useLayoutEffect` hooks
24
+ * - Callbacks for event listeners
25
+ * - Files with the `"use-client"` directive
26
+ *
27
+ * Primarily, this is necessary when attempting to access the `document` object during rendering of components.
28
+ * However, even still, where possible, it is recommended to avoid accessing the `document` object during rendering
29
+ * because it can lead to hydration mismatches. This happens when the server-rendered HTML differs from what the
30
+ * client renders due to missing environment-specific data (e.g., `document.children` being undefined on the server).
31
+ *
32
+ * @returns The global `document` object, if it exists.
33
+ */
34
+ export declare function getDocument(): Document | undefined;
35
+ /**
36
+ * Returns the global `navigator` object in a way that is friendly to SSR.
37
+ * This check can be avoided if you are sure that the code will only run in the browser.
38
+ * Some examples where you can ignore this:
39
+ * - `useEffect` hooks
40
+ * - `useLayoutEffect` hooks
41
+ * - Callbacks for event listeners
42
+ * - Files with the `"use-client"` directive
43
+ *
44
+ * Primarily, this is necessary when attempting to access the `navigator` object during rendering of components.
45
+ * However, even still, where possible, it is recommended to avoid accessing the `navigator` object during rendering
46
+ * because it can lead to hydration mismatches. This happens when the server-rendered HTML differs from what the
47
+ * client renders due to missing environment-specific data (e.g., `navigator.userAgent` being undefined on the server).
48
+ *
49
+ * @returns The global `navigator` object, if it exists.
50
+ */
51
+ export declare function getNavigator(): Navigator | undefined;