diff --git a/packages/core/.storybook/preview-body.html b/packages/core/.storybook/preview-body.html index 83acea9cdc..54fe155a5f 100644 --- a/packages/core/.storybook/preview-body.html +++ b/packages/core/.storybook/preview-body.html @@ -1,2 +1 @@ -
diff --git a/packages/core/.storybook/preview-head.html b/packages/core/.storybook/preview-head.html index 2142ce016b..fb1712c1f3 100644 --- a/packages/core/.storybook/preview-head.html +++ b/packages/core/.storybook/preview-head.html @@ -21,12 +21,6 @@ body * { box-sizing: border-box; } - #tooltips-container { - position: relative; - white-space: pre-wrap; - z-index: 99999999; - max-width: 50%; - } .light-app-theme { background-color: var(--sb-primary-background-color); } diff --git a/packages/core/package.json b/packages/core/package.json index 26ff71d84c..acd5aa8f5b 100644 --- a/packages/core/package.json +++ b/packages/core/package.json @@ -175,6 +175,7 @@ "@types/lodash-es": "^4.17.6", "@types/react": "^18.0.25", "@types/react-dates": "^21.8.3", + "@types/react-dom": "^18.2.18", "@types/react-is": "^16.7.5", "@types/react-resizable": "^3.0.7", "@types/react-test-renderer": "^16.9.0", diff --git a/packages/core/src/components/Dialog/Dialog.tsx b/packages/core/src/components/Dialog/Dialog.tsx index c2b85bfdbb..259bfe3784 100644 --- a/packages/core/src/components/Dialog/Dialog.tsx +++ b/packages/core/src/components/Dialog/Dialog.tsx @@ -15,6 +15,7 @@ import { VibeComponentProps } from "../../types"; import * as PopperJS from "@popperjs/core"; import styles from "./Dialog.module.scss"; import { ComponentDefaultTestId, getTestId } from "../../tests/test-ids-utils"; +import LayerContext from "../LayerProvider/LayerContext"; export interface DialogProps extends VibeComponentProps { /** @@ -92,6 +93,7 @@ export interface DialogProps extends VibeComponentProps { * Classname to be added to the content container */ wrapperClassName?: string; + layerClassName?: string; /** * Prevent Animation */ @@ -126,6 +128,7 @@ export interface DialogProps extends VibeComponentProps { * callback to be called when click on the content is being triggered */ onContentClick?: (event: React.MouseEvent) => void; + // TODO: remove in next major /** * z-index to add to the dialog */ @@ -199,6 +202,7 @@ export default class Dialog extends PureComponent { }; private showTimeout: NodeJS.Timeout; private hideTimeout: NodeJS.Timeout; + context!: React.ContextType; constructor(props: DialogProps) { super(props); @@ -282,10 +286,11 @@ export default class Dialog extends PureComponent { const containerElement = document.querySelector(containerSelector); if (!containerElement) { - // TODO add env check - if not jest env - trashing the logs - https://monday.monday.com/boards/3532714909/pulses/5570955392 - // console.error( - // `Dialog: Container element with selector "${containerSelector}" was not found. Dialog may not be correctly positioned.` - // ); + const { layerRef } = this.context; + if (layerRef?.current) { + // Use Vibe layers mechanism if containerElement was not provided, otherwise fallback to document.body + return layerRef.current; + } return document.body; } return containerElement; @@ -485,6 +490,7 @@ export default class Dialog extends PureComponent { render() { const { wrapperClassName, + layerClassName, content, startingEdge, children, @@ -603,6 +609,7 @@ export default class Dialog extends PureComponent { animationType={animationTypeCalculated} position={placement} wrapperClassName={wrapperClassName} + layerClassName={layerClassName} startingEdge={startingEdge} isOpen={this.isShown()} showDelay={showDelay} @@ -637,3 +644,5 @@ function chainOnPropsAndInstance(name: string, instance: Dialog, props: DialogPr // @ts-ignore return chainFunctions([props[name], instance[name]], true); } + +Dialog.contextType = LayerContext; diff --git a/packages/core/src/components/Dialog/DialogContent/DialogContent.module.scss b/packages/core/src/components/Dialog/DialogContent/DialogContent.module.scss index 2d7be3db69..a6f48d7415 100644 --- a/packages/core/src/components/Dialog/DialogContent/DialogContent.module.scss +++ b/packages/core/src/components/Dialog/DialogContent/DialogContent.module.scss @@ -39,6 +39,10 @@ } } +.dialogLayer { + z-index: var(--layer-popover); +} + .contentWrapper[data-popper-reference-hidden="true"] { visibility: hidden; pointer-events: none; diff --git a/packages/core/src/components/Dialog/DialogContent/DialogContent.tsx b/packages/core/src/components/Dialog/DialogContent/DialogContent.tsx index 6d439add13..ca483be269 100644 --- a/packages/core/src/components/Dialog/DialogContent/DialogContent.tsx +++ b/packages/core/src/components/Dialog/DialogContent/DialogContent.tsx @@ -22,6 +22,7 @@ export interface DialogContentProps extends VibeComponentProps { children?: ReactElement | ReactElement[]; position?: PopperJS.Placement; wrapperClassName?: string; + layerClassName?: string; isOpen?: boolean; // TODO breaking change convert to enum startingEdge?: any; @@ -54,6 +55,7 @@ export const DialogContent: VibeComponent = React.forwardRef children, position, wrapperClassName, + layerClassName, isOpen = false, startingEdge, animationType = "expand", @@ -124,8 +126,14 @@ export const DialogContent: VibeComponent = React.forwardRef } return ( ; +}; + +const LayerContext = React.createContext({ + layerRef: null +}); + +export default LayerContext; diff --git a/packages/core/src/components/LayerProvider/LayerProvider.tsx b/packages/core/src/components/LayerProvider/LayerProvider.tsx new file mode 100644 index 0000000000..53d960c864 --- /dev/null +++ b/packages/core/src/components/LayerProvider/LayerProvider.tsx @@ -0,0 +1,13 @@ +import React, { FC } from "react"; +import LayerContext from "./LayerContext"; + +interface LayerProviderType { + children: JSX.Element | JSX.Element[]; + layerRef: React.RefObject | null; +} + +const LayerProvider: FC = ({ children, layerRef }) => { + return {children}; +}; + +export default LayerProvider; diff --git a/packages/core/src/components/Modal/Modal.module.scss b/packages/core/src/components/Modal/Modal.module.scss index 9fa16acbc1..d2f0c6c105 100644 --- a/packages/core/src/components/Modal/Modal.module.scss +++ b/packages/core/src/components/Modal/Modal.module.scss @@ -5,7 +5,8 @@ } .container { - --monday-modal-z-index: 10000; + --monday-modal-z-index: var(--layer-modal); + // TODO: use --modal-layer in next major z-index: var(--monday-modal-z-index); display: flex; justify-content: center; diff --git a/packages/core/src/components/Modal/Modal.tsx b/packages/core/src/components/Modal/Modal.tsx index 4b81f23585..488b7a7fb1 100644 --- a/packages/core/src/components/Modal/Modal.tsx +++ b/packages/core/src/components/Modal/Modal.tsx @@ -1,4 +1,4 @@ -import React, { cloneElement, FC, ReactElement, useCallback, useMemo } from "react"; +import React, { cloneElement, FC, ReactElement, useCallback, useMemo, useRef } from "react"; import ReactDOM from "react-dom"; import cx from "classnames"; import { useA11yDialog } from "./a11yDialog"; @@ -12,6 +12,7 @@ import { withStaticProps } from "../../types"; import { getTestId } from "../../tests/test-ids-utils"; import { ComponentDefaultTestId } from "../../tests/constants"; import styles from "./Modal.module.scss"; +import LayerProvider from "../LayerProvider/LayerProvider"; export interface ModalProps { /** @@ -72,6 +73,7 @@ export interface ModalProps { * Dialog content */ children?: ReactElement | ReactElement[]; + // TODO: remove next major /** * z-index attribute of the container */ @@ -97,6 +99,7 @@ const Modal: FC & { width?: typeof ModalWidth } = ({ zIndex = 10000, "data-testid": dataTestId }) => { + const overlayRef = useRef(null); const childrenArray: ReactElement[] = useMemo( () => (children ? (React.Children.toArray(children) as ReactElement[]) : []), [children] @@ -162,27 +165,31 @@ const Modal: FC & { width?: typeof ModalWidth } = ({ {...attr.container} className={cx(styles.container, classNames.container)} data-testid={dataTestId || getTestId(ComponentDefaultTestId.MODAL, id)} + // TODO: remove in next major style={{ "--monday-modal-z-index": zIndex }} > - {/* eslint-disable-next-line jsx-a11y/click-events-have-key-events */} -
-
- {header} - {content} - {footer} -
+ + {/* eslint-disable-next-line jsx-a11y/click-events-have-key-events */} +
+
+ {header} + {content} + {footer} +
+
, document.body ); diff --git a/packages/core/src/components/Slider/__tests__/__snapshots__/slider-non-ranged-tests.jest.js.snap b/packages/core/src/components/Slider/__tests__/__snapshots__/slider-non-ranged-tests.jest.js.snap index 4ee6b30264..e6778d63e4 100644 --- a/packages/core/src/components/Slider/__tests__/__snapshots__/slider-non-ranged-tests.jest.js.snap +++ b/packages/core/src/components/Slider/__tests__/__snapshots__/slider-non-ranged-tests.jest.js.snap @@ -48,7 +48,7 @@ Snapshot Diff: tabindex="0" /> + - + - + + - + - & { modifiers={modifiers} open={defaultDelayOpen ? delayedOpen : undefined} forceRenderWithoutChildren={floating} + layerClassName={styles.tipseenLayer} > {children} diff --git a/packages/core/src/components/Tipseen/__tests__/__snapshots__/tipseen-tests.jest.js.snap b/packages/core/src/components/Tipseen/__tests__/__snapshots__/tipseen-tests.jest.js.snap index b859b8aa7f..3ab6d113d8 100644 --- a/packages/core/src/components/Tipseen/__tests__/__snapshots__/tipseen-tests.jest.js.snap +++ b/packages/core/src/components/Tipseen/__tests__/__snapshots__/tipseen-tests.jest.js.snap @@ -141,7 +141,7 @@ Array [ onMouseLeave={[Function]} />, , , , { disableDialogSlide: true, animationType: AnimationType.EXPAND, withoutDialog: false, - containerSelector: "#tooltips-container", tip: true, hideWhenReferenceHidden: false, modifiers: new Array>(), @@ -186,7 +187,7 @@ export default class Tooltip extends PureComponent { } getContainer() { - return document.getElementById("tooltips-container") || document.querySelector("body"); + return document.querySelector("body"); } renderTooltipContent() { @@ -305,6 +306,7 @@ export default class Tooltip extends PureComponent { tip, arrowClassName, id, + layerClassName, "data-testid": dataTestId } = this.props; @@ -333,7 +335,8 @@ export default class Tooltip extends PureComponent { animationType: AnimationType.EXPAND, onDialogDidHide: this.onTooltipHide, onDialogDidShow: this.onTooltipShow, - getDynamicShowDelay: this.getShowDelay + getDynamicShowDelay: this.getShowDelay, + layerClassName: layerClassName || styles.tooltipLayer }; return {children}; } diff --git a/packages/core/src/components/Tooltip/__tests__/__snapshots__/tooltip-snapshot-tests.jest.tsx.snap b/packages/core/src/components/Tooltip/__tests__/__snapshots__/tooltip-snapshot-tests.jest.tsx.snap index ecd892945b..4267b0991e 100644 --- a/packages/core/src/components/Tooltip/__tests__/__snapshots__/tooltip-snapshot-tests.jest.tsx.snap +++ b/packages/core/src/components/Tooltip/__tests__/__snapshots__/tooltip-snapshot-tests.jest.tsx.snap @@ -13,7 +13,7 @@ Array [ onMouseLeave={[Function]} />, , , , , , , , { diff --git a/yarn.lock b/yarn.lock index 84438ebba3..2d40875977 100644 --- a/yarn.lock +++ b/yarn.lock @@ -4954,6 +4954,13 @@ dependencies: "@types/react" "*" +"@types/react-dom@^18.2.18": + version "18.2.19" + resolved "https://registry.npmjs.org/@types/react-dom/-/react-dom-18.2.19.tgz#b84b7c30c635a6c26c6a6dfbb599b2da9788be58" + integrity sha512-aZvQL6uUbIJpjZk4U8JZGbau9KDeAwMfmhyWorxgBkqDIEf6ROjRozcmPIicqsUwPUjbkDfHKgGee1Lq65APcA== + dependencies: + "@types/react" "*" + "@types/react-is@^16.7.5": version "16.7.5" resolved "https://registry.npmjs.org/@types/react-is/-/react-is-16.7.5.tgz#cc72207e99d5d7f8861e8d75893cac3823b8471b" @@ -18205,16 +18212,7 @@ string-length@^4.0.1: char-regex "^1.0.2" strip-ansi "^6.0.0" -"string-width-cjs@npm:string-width@^4.2.0": - version "4.2.3" - resolved "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz#269c7117d27b05ad2e536830a8ec895ef9c6d010" - integrity sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g== - dependencies: - emoji-regex "^8.0.0" - is-fullwidth-code-point "^3.0.0" - strip-ansi "^6.0.1" - -"string-width@^1.0.2 || 2 || 3 || 4", string-width@^4.1.0, string-width@^4.2.0, string-width@^4.2.3: +"string-width-cjs@npm:string-width@^4.2.0", "string-width@^1.0.2 || 2 || 3 || 4", string-width@^4.1.0, string-width@^4.2.0, string-width@^4.2.3: version "4.2.3" resolved "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz#269c7117d27b05ad2e536830a8ec895ef9c6d010" integrity sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g== @@ -18300,7 +18298,7 @@ stringify-entities@^4.0.0: character-entities-html4 "^2.0.0" character-entities-legacy "^3.0.0" -"strip-ansi-cjs@npm:strip-ansi@^6.0.1": +"strip-ansi-cjs@npm:strip-ansi@^6.0.1", strip-ansi@^6.0.0, strip-ansi@^6.0.1: version "6.0.1" resolved "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz#9e26c63d30f53443e9489495b2105d37b67a85d9" integrity sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A== @@ -18321,13 +18319,6 @@ strip-ansi@^5.2.0: dependencies: ansi-regex "^4.1.0" -strip-ansi@^6.0.0, strip-ansi@^6.0.1: - version "6.0.1" - resolved "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz#9e26c63d30f53443e9489495b2105d37b67a85d9" - integrity sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A== - dependencies: - ansi-regex "^5.0.1" - strip-ansi@^7.0.1: version "7.1.0" resolved "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.1.0.tgz#d5b6568ca689d8561370b0707685d22434faff45" @@ -20155,7 +20146,7 @@ workerpool@6.2.1: resolved "https://registry.npmjs.org/workerpool/-/workerpool-6.2.1.tgz#46fc150c17d826b86a008e5a4508656777e9c343" integrity sha512-ILEIE97kDZvF9Wb9f6h5aXK4swSlKGUcOEGiIYb2OOu/IrDU9iwj0fD//SsA6E5ibwJxpEvhullJY4Sl4GcpAw== -"wrap-ansi-cjs@npm:wrap-ansi@^7.0.0": +"wrap-ansi-cjs@npm:wrap-ansi@^7.0.0", wrap-ansi@^7.0.0: version "7.0.0" resolved "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz#67e145cff510a6a6984bdf1152911d69d2eb9e43" integrity sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q== @@ -20173,15 +20164,6 @@ wrap-ansi@^6.0.1, wrap-ansi@^6.2.0: string-width "^4.1.0" strip-ansi "^6.0.0" -wrap-ansi@^7.0.0: - version "7.0.0" - resolved "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz#67e145cff510a6a6984bdf1152911d69d2eb9e43" - integrity sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q== - dependencies: - ansi-styles "^4.0.0" - string-width "^4.1.0" - strip-ansi "^6.0.0" - wrap-ansi@^8.1.0: version "8.1.0" resolved "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-8.1.0.tgz#56dc22368ee570face1b49819975d9b9a5ead214"