From 06470c58722acf6d5fdc8ffa963790fa8784f717 Mon Sep 17 00:00:00 2001 From: Florian Rival Date: Mon, 28 Sep 2026 18:31:05 +0200 Subject: [PATCH] Fix tooltips rendered in popped out editor windows (#9150) --- newIDE/app/src/AiGeneration/AiRequestChat/ConceptLink.js | 4 ++++ .../CompactPropertiesEditorRowField.js | 4 ++++ newIDE/app/src/UI/CompactSelectField/index.js | 4 ++++ newIDE/app/src/UI/CompactTextAreaField/index.js | 4 ++++ newIDE/app/src/UI/CompactTextField/index.js | 4 ++++ newIDE/app/src/UI/CompactToggleField/index.js | 4 ++++ newIDE/app/src/UI/Theme/FullThemeProvider.js | 1 + 7 files changed, 25 insertions(+) diff --git a/newIDE/app/src/AiGeneration/AiRequestChat/ConceptLink.js b/newIDE/app/src/AiGeneration/AiRequestChat/ConceptLink.js index 7cf9e2b65d..c438c92dc7 100644 --- a/newIDE/app/src/AiGeneration/AiRequestChat/ConceptLink.js +++ b/newIDE/app/src/AiGeneration/AiRequestChat/ConceptLink.js @@ -15,6 +15,7 @@ import { mapFor } from '../../Utils/MapFor'; import classes from './ChatMarkdownText.module.css'; import classNames from 'classnames'; import Tooltip from '@material-ui/core/Tooltip'; +import PortalContainerContext from '../../UI/PortalContainerContext'; import { MarkdownText } from '../../UI/MarkdownText'; import Text from '../../UI/Text'; @@ -149,6 +150,7 @@ export const ConceptLink = ({ conceptMetadata, forceNoLink, }: ConceptLinkProps): null | React.Node => { + const portalContainer = React.useContext(PortalContainerContext); if (!conceptMetadata) return null; const helpLink = forceNoLink ? '' : getHelpLink(conceptMetadata.helpPath); @@ -178,6 +180,8 @@ export const ConceptLink = ({ ]} placement="bottom" PopperProps={{ + // Passing PopperProps replaces the theme default container (see FullThemeProvider). + container: portalContainer, modifiers: { offset: { enabled: true, diff --git a/newIDE/app/src/CompactPropertiesEditor/CompactPropertiesEditorRowField.js b/newIDE/app/src/CompactPropertiesEditor/CompactPropertiesEditorRowField.js index a060dbffa9..b8b4f465ca 100644 --- a/newIDE/app/src/CompactPropertiesEditor/CompactPropertiesEditorRowField.js +++ b/newIDE/app/src/CompactPropertiesEditor/CompactPropertiesEditorRowField.js @@ -6,6 +6,7 @@ import { LineStackLayout } from '../UI/Layout'; import Text from '../UI/Text'; import { MarkdownText } from '../UI/MarkdownText'; import { tooltipEnterDelay } from '../UI/Tooltip'; +import PortalContainerContext from '../UI/PortalContainerContext'; const styles = { leftColumn: { flex: 2, minWidth: 0, maxWidth: 150 }, @@ -26,6 +27,7 @@ type Props = {| |}; const CompactPropertiesEditorRowField = (props: Props): React.Node => { + const portalContainer = React.useContext(PortalContainerContext); const title = !props.markdownDescription ? props.label : [ @@ -47,6 +49,8 @@ const CompactPropertiesEditorRowField = (props: Props): React.Node => { enterDelay={tooltipEnterDelay} placement="bottom" PopperProps={{ + // Passing PopperProps replaces the theme default container (see FullThemeProvider). + container: portalContainer, modifiers: { offset: { enabled: true, diff --git a/newIDE/app/src/UI/CompactSelectField/index.js b/newIDE/app/src/UI/CompactSelectField/index.js index 733b4889f0..40b6fce876 100644 --- a/newIDE/app/src/UI/CompactSelectField/index.js +++ b/newIDE/app/src/UI/CompactSelectField/index.js @@ -5,6 +5,7 @@ import Tooltip from '@material-ui/core/Tooltip'; import classNames from 'classnames'; import classes from './CompactSelectField.module.css'; import { tooltipEnterDelay } from '../Tooltip'; +import PortalContainerContext from '../PortalContainerContext'; type Props = {| onChange: string => void, value: string, @@ -32,6 +33,7 @@ const CompactSelectField = ({ rounded, onFocus, }: Props): React.MixedElement => { + const portalContainer = React.useContext(PortalContainerContext); return (
{ + const portalContainer = React.useContext(PortalContainerContext); const idToUse = React.useRef(id || makeTimestampedId()); const title = !markdownDescription @@ -80,6 +82,8 @@ export const CompactTextAreaField = ({ enterDelay={tooltipEnterDelay} placement="bottom" PopperProps={{ + // Passing PopperProps replaces the theme default container (see FullThemeProvider). + container: portalContainer, modifiers: { offset: { enabled: true, diff --git a/newIDE/app/src/UI/CompactTextField/index.js b/newIDE/app/src/UI/CompactTextField/index.js index 05490d8187..10da222271 100644 --- a/newIDE/app/src/UI/CompactTextField/index.js +++ b/newIDE/app/src/UI/CompactTextField/index.js @@ -5,6 +5,7 @@ import Tooltip from '@material-ui/core/Tooltip'; import classNames from 'classnames'; import classes from './CompactTextField.module.css'; import { tooltipEnterDelay } from '../Tooltip'; +import PortalContainerContext from '../PortalContainerContext'; import useClickDragAsControl from './UseClickDragAsControl'; import { makeTimestampedId } from '../../Utils/TimestampedId'; import { toFixedWithoutTrailingZeros } from '../../Utils/Mathematics'; @@ -84,6 +85,7 @@ const CompactTextField: React.ComponentType<{ }, ref ) => { + const portalContainer = React.useContext(PortalContainerContext); const idToUse = React.useRef(id || makeTimestampedId()); const inputRef = React.useRef(null); const controlProps = useClickDragAsControl({ @@ -173,6 +175,8 @@ const CompactTextField: React.ComponentType<{ enterDelay={tooltipEnterDelay} placement="bottom" PopperProps={{ + // Passing PopperProps replaces the theme default container (see FullThemeProvider). + container: portalContainer, modifiers: { offset: { enabled: true, diff --git a/newIDE/app/src/UI/CompactToggleField/index.js b/newIDE/app/src/UI/CompactToggleField/index.js index fae25f724e..f21f57d229 100644 --- a/newIDE/app/src/UI/CompactToggleField/index.js +++ b/newIDE/app/src/UI/CompactToggleField/index.js @@ -4,6 +4,7 @@ import Tooltip from '@material-ui/core/Tooltip'; import Text from '../../UI/Text'; import { MarkdownText } from '../../UI/MarkdownText'; import { tooltipEnterDelay } from '../../UI/Tooltip'; +import PortalContainerContext from '../PortalContainerContext'; import classes from './CompactToggleField.module.css'; import classNames from 'classnames'; @@ -33,6 +34,7 @@ type Props = {| |}; export const CompactToggleField = (props: Props): React.MixedElement => { + const portalContainer = React.useContext(PortalContainerContext); const title = props.hideTooltip ? null : !props.markdownDescription @@ -103,6 +105,8 @@ export const CompactToggleField = (props: Props): React.MixedElement => { enterDelay={tooltipEnterDelay} placement="bottom" PopperProps={{ + // Passing PopperProps replaces the theme default container (see FullThemeProvider). + container: portalContainer, modifiers: { offset: { enabled: true, diff --git a/newIDE/app/src/UI/Theme/FullThemeProvider.js b/newIDE/app/src/UI/Theme/FullThemeProvider.js index a6f5c36314..b87b940964 100644 --- a/newIDE/app/src/UI/Theme/FullThemeProvider.js +++ b/newIDE/app/src/UI/Theme/FullThemeProvider.js @@ -53,6 +53,7 @@ const getPortalContainerThemeProps = (portalContainer: ?HTMLElement) => { MuiMenu: { container: portalContainer }, MuiDrawer: { container: portalContainer }, MuiTooltip: { + // Replaced by any Tooltip passing its own PopperProps: those must also set the container. PopperProps: { container: portalContainer }, }, };