From e07e28ee1f807e9efd5cbed3f855fd83553799ac Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Nicol=C3=B2=20Pretto?= <info@npretto.com> Date: Fri, 13 Sep 2024 19:16:20 +0200 Subject: [PATCH] first iteration to scope sdk styles to our components (#47764) * first iteration to scope sdk styles to our components * basic css reset for buttons * clean up duplicated css * make sdk components use instance font if no font is passed * cleanin up and remove defaultProps not needed * fix tests * adds EMBEDDING_SDK_PORTAL_CONTAINER_ELEMENT_ID * Update enterprise/frontend/src/embedding-sdk/components/public/MetabaseProvider.tsx * Update enterprise/frontend/src/embedding-sdk/components/public/MetabaseProvider.tsx Co-authored-by: Mahatthana (Kelvin) Nomsawadi <me@bboykelvin.dev> * fix import * prettier --write * we don't need theme.fontFamily, added a comment * rename EMBEDDING_SDK_PORTAL_CONTAINER_ELEMENT_ID to EMBEDDING_SDK_PORTAL_ROOT_ELEMENT_ID * fix unit test --------- Co-authored-by: Mahatthana (Kelvin) Nomsawadi <me@bboykelvin.dev> --- .../private/AppInitializeController.tsx | 36 ----------- .../private/PublicComponentStylesWrapper.tsx | 23 +++++++ .../private/SdkGlobalFontsStyles.tsx | 36 +++++++++++ .../private/SdkGlobalStylesWrapper.tsx | 54 ---------------- .../SdkGlobalStylesWrapper.unit.spec.tsx | 61 ------------------- .../components/private/SdkThemeProvider.tsx | 9 +-- .../components/public/MetabaseProvider.tsx | 53 +++++++++++----- .../frontend/src/embedding-sdk/config.ts | 1 + .../lib/theme/default-component-theme.ts | 29 ++++++++- .../lib/theme/get-embedding-theme.ts | 10 +-- .../theme/get-embedding-theme.unit.spec.ts | 21 ++++--- .../components/Popover/TippyPopover.tsx | 5 +- .../core/components/Tooltip/Tooltip.tsx | 5 +- .../TableInteractive/TableInteractive.jsx | 4 +- frontend/test/__support__/ui.tsx | 12 ++-- 15 files changed, 161 insertions(+), 198 deletions(-) delete mode 100644 enterprise/frontend/src/embedding-sdk/components/private/AppInitializeController.tsx create mode 100644 enterprise/frontend/src/embedding-sdk/components/private/SdkGlobalFontsStyles.tsx delete mode 100644 enterprise/frontend/src/embedding-sdk/components/private/SdkGlobalStylesWrapper.tsx delete mode 100644 enterprise/frontend/src/embedding-sdk/components/private/SdkGlobalStylesWrapper.unit.spec.tsx diff --git a/enterprise/frontend/src/embedding-sdk/components/private/AppInitializeController.tsx b/enterprise/frontend/src/embedding-sdk/components/private/AppInitializeController.tsx deleted file mode 100644 index 35b881f8ae9..00000000000 --- a/enterprise/frontend/src/embedding-sdk/components/private/AppInitializeController.tsx +++ /dev/null @@ -1,36 +0,0 @@ -import type { ReactNode } from "react"; -import { t } from "ttag"; - -import { EMBEDDING_SDK_ROOT_ELEMENT_ID } from "embedding-sdk/config"; -import { useInitData } from "embedding-sdk/hooks"; -import { useSdkSelector } from "embedding-sdk/store"; -import { getIsInitialized } from "embedding-sdk/store/selectors"; -import type { SDKConfig } from "embedding-sdk/types"; - -import { SdkGlobalStylesWrapper } from "./SdkGlobalStylesWrapper"; - -interface AppInitializeControllerProps { - children: ReactNode; - config: SDKConfig; - className?: string; -} - -export const AppInitializeController = ({ - config, - children, - className, -}: AppInitializeControllerProps) => { - useInitData({ config }); - - const isInitialized = useSdkSelector(getIsInitialized); - - return ( - <SdkGlobalStylesWrapper - baseUrl={config.metabaseInstanceUrl} - id={EMBEDDING_SDK_ROOT_ELEMENT_ID} - className={className} - > - {!isInitialized ? <div>{t`Loading…`}</div> : children} - </SdkGlobalStylesWrapper> - ); -}; diff --git a/enterprise/frontend/src/embedding-sdk/components/private/PublicComponentStylesWrapper.tsx b/enterprise/frontend/src/embedding-sdk/components/private/PublicComponentStylesWrapper.tsx index ed178451515..2cc306f7c1b 100644 --- a/enterprise/frontend/src/embedding-sdk/components/private/PublicComponentStylesWrapper.tsx +++ b/enterprise/frontend/src/embedding-sdk/components/private/PublicComponentStylesWrapper.tsx @@ -9,15 +9,38 @@ import { saveDomImageStyles } from "metabase/visualizations/lib/save-chart-image * even when rendered under a React portal. */ export const PublicComponentStylesWrapper = styled.div` + // Try to reset as much as possible to avoid css leaking from host app to our components + all: initial; + text-decoration: none; + + // # Basic css reset + // We can't apply a global css reset as it would leak into the host app + // but we can't also apply our entire css reset scoped to this container, + // as it would be of higher specificity than some of our styles. + // We'll have to hand pick the css resets that we neeed + + button { + border: 0; + background-color: transparent; + } + // end of RESET + + font-style: normal; + width: 100%; height: 100%; position: relative; + font-size: ${({ theme }) => theme.other.fontSize}; + font-weight: 400; color: var(--mb-color-text-dark); font-family: var(--mb-default-font-family), sans-serif; + -webkit-font-smoothing: antialiased; + -moz-osx-font-smoothing: grayscale; + ${aceEditorStyles} ${saveDomImageStyles} diff --git a/enterprise/frontend/src/embedding-sdk/components/private/SdkGlobalFontsStyles.tsx b/enterprise/frontend/src/embedding-sdk/components/private/SdkGlobalFontsStyles.tsx new file mode 100644 index 00000000000..3c8f7116173 --- /dev/null +++ b/enterprise/frontend/src/embedding-sdk/components/private/SdkGlobalFontsStyles.tsx @@ -0,0 +1,36 @@ +import { Global, css } from "@emotion/react"; +import { useMemo } from "react"; +import { useSelector } from "react-redux"; + +import { defaultFontFiles } from "metabase/css/core/fonts.styled"; +import { getFontFiles } from "metabase/styled-components/selectors"; + +/** + * css style to define the font files for the SDK + */ +export const SdkFontsGlobalStyles = ({ baseUrl }: { baseUrl: string }) => { + const fontFiles = useSelector(getFontFiles); + + const fontStyles = useMemo( + () => css` + // built in fonts + ${defaultFontFiles({ baseUrl })} + + // custom fonts + ${fontFiles?.map( + file => css` + @font-face { + font-family: "Custom"; + src: url(${encodeURI(file.src)}) format("${file.fontFormat}"); + font-weight: ${file.fontWeight}; + font-style: normal; + font-display: swap; + } + `, + )} + `, + [fontFiles, baseUrl], + ); + + return <Global styles={fontStyles} />; +}; diff --git a/enterprise/frontend/src/embedding-sdk/components/private/SdkGlobalStylesWrapper.tsx b/enterprise/frontend/src/embedding-sdk/components/private/SdkGlobalStylesWrapper.tsx deleted file mode 100644 index 759de05816e..00000000000 --- a/enterprise/frontend/src/embedding-sdk/components/private/SdkGlobalStylesWrapper.tsx +++ /dev/null @@ -1,54 +0,0 @@ -import { css } from "@emotion/react"; -import styled from "@emotion/styled"; -import type { HTMLAttributes } from "react"; - -import { rootStyle } from "metabase/css/core/base.styled"; -import { defaultFontFiles } from "metabase/css/core/fonts.styled"; -import { useSelector } from "metabase/lib/redux"; -import { getFontFiles } from "metabase/styled-components/selectors"; -import type { FontFile } from "metabase-types/api"; - -interface SdkContentWrapperProps { - baseUrl?: string; -} - -export function SdkGlobalStylesWrapper({ - baseUrl, - ...divProps -}: SdkContentWrapperProps & HTMLAttributes<HTMLDivElement>) { - const fontFiles = useSelector(getFontFiles); - return ( - <> - <SdkGlobalStylesInner - baseUrl={baseUrl} - fontFiles={fontFiles} - {...divProps} - /> - </> - ); -} - -const SdkGlobalStylesInner = styled.div< - SdkContentWrapperProps & { - fontFiles: FontFile[] | null; - } ->` - font-size: ${({ theme }) => theme.other.fontSize}; - - ${rootStyle} - - ${({ baseUrl }) => defaultFontFiles({ baseUrl })} - - ${({ fontFiles }) => - fontFiles?.map( - file => css` - @font-face { - font-family: "Custom"; - src: url(${encodeURI(file.src)}) format("${file.fontFormat}"); - font-weight: ${file.fontWeight}; - font-style: normal; - font-display: swap; - } - `, - )} -`; diff --git a/enterprise/frontend/src/embedding-sdk/components/private/SdkGlobalStylesWrapper.unit.spec.tsx b/enterprise/frontend/src/embedding-sdk/components/private/SdkGlobalStylesWrapper.unit.spec.tsx deleted file mode 100644 index 831b9e20363..00000000000 --- a/enterprise/frontend/src/embedding-sdk/components/private/SdkGlobalStylesWrapper.unit.spec.tsx +++ /dev/null @@ -1,61 +0,0 @@ -import { renderWithProviders, screen } from "__support__/ui"; -import { SdkGlobalStylesWrapper } from "embedding-sdk/components/private/SdkGlobalStylesWrapper"; -import { SdkThemeProvider } from "embedding-sdk/components/private/SdkThemeProvider"; -import { Text } from "metabase/ui"; -import { - createMockSettingsState, - createMockState, -} from "metabase-types/store/mocks"; - -describe("SdkGlobalStylesWrapper", () => { - it("injects the font-face declaration when available", () => { - const state = createMockState({ - settings: createMockSettingsState({ - "application-font-files": [ - { - src: "https://example.com/foo.woff2", - fontFormat: "woff2", - fontWeight: 700, - }, - ], - }), - }); - - renderWithProviders(<SdkGlobalStylesWrapper />, { - storeInitialState: state, - }); - - const rules = Array.from(document.styleSheets).flatMap(sheet => - Array.from(sheet.cssRules || []), - ); - - const fontFaceRule = rules.find( - rule => - rule.constructor.name === "CSSFontFaceRule" && - rule.cssText.includes("foo.woff2"), - )!; - - expect(fontFaceRule).toBeDefined(); - expect(fontFaceRule.cssText).toContain("font-weight: 700"); - }); - - // TODO: Add substitute tests since we can't test CSS custom properties with JSDom - // eslint-disable-next-line jest/no-disabled-tests - it.skip("should use foreground color from the theme", () => { - const theme = { - colors: { "text-primary": "rgb(255, 0, 255)" }, - }; - - renderWithProviders( - <SdkThemeProvider theme={theme}> - <SdkGlobalStylesWrapper> - <Text>Hello world</Text> - </SdkGlobalStylesWrapper> - </SdkThemeProvider>, - ); - - expect(window.getComputedStyle(screen.getByText("Hello world")).color).toBe( - "rgb(255, 0, 255)", - ); - }); -}); diff --git a/enterprise/frontend/src/embedding-sdk/components/private/SdkThemeProvider.tsx b/enterprise/frontend/src/embedding-sdk/components/private/SdkThemeProvider.tsx index c6932e6e609..3e6c9d78b19 100644 --- a/enterprise/frontend/src/embedding-sdk/components/private/SdkThemeProvider.tsx +++ b/enterprise/frontend/src/embedding-sdk/components/private/SdkThemeProvider.tsx @@ -19,6 +19,7 @@ interface Props { } export const SdkThemeProvider = ({ theme, children }: Props) => { + const font = useSelector(getFont); const appColors = useSelector(state => getApplicationColors(getSettings(state)), ); @@ -28,18 +29,18 @@ export const SdkThemeProvider = ({ theme, children }: Props) => { // This must be done before ThemeProvider calls getThemeOverrides. setGlobalEmbeddingColors(theme?.colors, appColors); - return theme && getEmbeddingThemeOverride(theme); - }, [appColors, theme]); + return theme && getEmbeddingThemeOverride(theme, font); + }, [appColors, theme, font]); return ( <ThemeProvider theme={themeOverride}> - <SDKGlobalStyles /> + <GlobalSdkCssVariables /> {children} </ThemeProvider> ); }; -function SDKGlobalStyles() { +function GlobalSdkCssVariables() { const theme = useMantineTheme(); const font = useSelector(getFont); diff --git a/enterprise/frontend/src/embedding-sdk/components/public/MetabaseProvider.tsx b/enterprise/frontend/src/embedding-sdk/components/public/MetabaseProvider.tsx index 8c7a3a58fcb..77843312798 100644 --- a/enterprise/frontend/src/embedding-sdk/components/public/MetabaseProvider.tsx +++ b/enterprise/frontend/src/embedding-sdk/components/public/MetabaseProvider.tsx @@ -1,11 +1,13 @@ import type { Action, Store } from "@reduxjs/toolkit"; -import { type JSX, type ReactNode, useEffect } from "react"; -import { memo } from "react"; +import { type JSX, type ReactNode, memo, useEffect } from "react"; import { Provider } from "react-redux"; -import { AppInitializeController } from "embedding-sdk/components/private/AppInitializeController"; import { SdkThemeProvider } from "embedding-sdk/components/private/SdkThemeProvider"; -import { DEFAULT_FONT } from "embedding-sdk/config"; +import { + EMBEDDING_SDK_PORTAL_ROOT_ELEMENT_ID, + EMBEDDING_SDK_ROOT_ELEMENT_ID, +} from "embedding-sdk/config"; +import { useInitData } from "embedding-sdk/hooks"; import type { SdkEventHandlersConfig } from "embedding-sdk/lib/events"; import type { SdkPluginsConfig } from "embedding-sdk/lib/plugins"; import { store } from "embedding-sdk/store"; @@ -22,8 +24,11 @@ import type { MetabaseTheme } from "embedding-sdk/types/theme"; import { setOptions } from "metabase/redux/embed"; import { EmotionCacheProvider } from "metabase/styled-components/components/EmotionCacheProvider"; -import "metabase/css/vendor.css"; +import { PublicComponentWrapper } from "../private/PublicComponentWrapper"; +import { SdkFontsGlobalStyles } from "../private/SdkGlobalFontsStyles"; + import "metabase/css/index.module.css"; +import "metabase/css/vendor.css"; export interface MetabaseProviderProps { children: ReactNode; @@ -47,7 +52,8 @@ export const MetabaseProviderInternal = ({ store, className, }: InternalMetabaseProviderProps): JSX.Element => { - const { fontFamily = DEFAULT_FONT } = theme ?? {}; + const { fontFamily } = theme ?? {}; + useInitData({ config }); useEffect(() => { if (fontFamily) { @@ -76,20 +82,35 @@ export const MetabaseProviderInternal = ({ }, [store, config.metabaseInstanceUrl]); return ( - <Provider store={store}> - <EmotionCacheProvider> - <SdkThemeProvider theme={theme}> - <AppInitializeController className={className} config={config}> - {children} - </AppInitializeController> - </SdkThemeProvider> - </EmotionCacheProvider> - </Provider> + <EmotionCacheProvider> + <SdkThemeProvider theme={theme}> + <SdkFontsGlobalStyles baseUrl={config.metabaseInstanceUrl} /> + <div className={className} id={EMBEDDING_SDK_ROOT_ELEMENT_ID}> + <PortalContainer /> + {children} + </div> + </SdkThemeProvider> + </EmotionCacheProvider> ); }; export const MetabaseProvider = memo(function MetabaseProvider( props: MetabaseProviderProps, ) { - return <MetabaseProviderInternal store={store} {...props} />; + return ( + <Provider store={store}> + <MetabaseProviderInternal store={store} {...props} /> + </Provider> + ); }); + +/** + * This is the portal container used by popovers modals etc, it is wrapped with withPublicComponentWrapper + * so that it has our styles applied. + * Mantine components needs to have the defaultProps set to use `EMBEDDING_SDK_PORTAL_CONTAINER_ELEMENT_ID` as target for the portal + */ +const PortalContainer = () => ( + <PublicComponentWrapper> + <div id={EMBEDDING_SDK_PORTAL_ROOT_ELEMENT_ID}></div> + </PublicComponentWrapper> +); diff --git a/enterprise/frontend/src/embedding-sdk/config.ts b/enterprise/frontend/src/embedding-sdk/config.ts index a80fe74f656..1606d3a8401 100644 --- a/enterprise/frontend/src/embedding-sdk/config.ts +++ b/enterprise/frontend/src/embedding-sdk/config.ts @@ -1,5 +1,6 @@ export const DEFAULT_FONT = "Lato"; export const EMBEDDING_SDK_ROOT_ELEMENT_ID = "metabase-sdk-root"; +export const EMBEDDING_SDK_PORTAL_ROOT_ELEMENT_ID = "metabase-sdk-portal-root"; export const getEmbeddingSdkVersion = () => process.env.EMBEDDING_SDK_VERSION ?? "unknown"; diff --git a/enterprise/frontend/src/embedding-sdk/lib/theme/default-component-theme.ts b/enterprise/frontend/src/embedding-sdk/lib/theme/default-component-theme.ts index 08183c465b3..eed035bc490 100644 --- a/enterprise/frontend/src/embedding-sdk/lib/theme/default-component-theme.ts +++ b/enterprise/frontend/src/embedding-sdk/lib/theme/default-component-theme.ts @@ -1,7 +1,7 @@ import { merge } from "icepick"; import type { MetabaseComponentTheme } from "embedding-sdk"; -import { EMBEDDING_SDK_ROOT_ELEMENT_ID } from "embedding-sdk/config"; +import { EMBEDDING_SDK_PORTAL_ROOT_ELEMENT_ID } from "embedding-sdk/config"; import type { DeepPartial } from "embedding-sdk/types/utils"; import type { MantineThemeOverride } from "metabase/ui"; @@ -124,6 +124,11 @@ export const DEFAULT_EMBEDDED_COMPONENT_THEME: MetabaseComponentTheme = merge< }, }); +// What's up with the commented `satisfies`? +// Mantine docs says they don't typecheck default props because of performance reasons. +// To be sure to not slow down typescript I left the check commented. +// If you change any of the default props please verify that the types are correct + export function getEmbeddingComponentOverrides( theme?: DeepPartial<MetabaseComponentTheme>, ): MantineThemeOverride["components"] { @@ -132,11 +137,31 @@ export function getEmbeddingComponentOverrides( defaultProps: { withinPortal: true, portalProps: { - target: `#${EMBEDDING_SDK_ROOT_ELEMENT_ID}`, + target: `#${EMBEDDING_SDK_PORTAL_ROOT_ELEMENT_ID}`, }, ...(theme?.popover?.zIndex && { zIndex: theme.popover.zIndex }), }, }, + ModalRoot: { + defaultProps: { + withinPortal: true, + target: `#${EMBEDDING_SDK_PORTAL_ROOT_ELEMENT_ID}`, + }, // satisfies Partial<ModalRootProps>, + }, + Modal: { + defaultProps: { + withinPortal: true, + target: `#${EMBEDDING_SDK_PORTAL_ROOT_ELEMENT_ID}`, + }, // satisfies Partial<ModalProps>, + }, + Popover: { + defaultProps: { + withinPortal: true, + portalProps: { + target: `#${EMBEDDING_SDK_PORTAL_ROOT_ELEMENT_ID}`, + }, + }, // satisfies Partial<PopoverProps>, + }, }; } diff --git a/enterprise/frontend/src/embedding-sdk/lib/theme/get-embedding-theme.ts b/enterprise/frontend/src/embedding-sdk/lib/theme/get-embedding-theme.ts index 63f2549df8e..38fdad6f6a8 100644 --- a/enterprise/frontend/src/embedding-sdk/lib/theme/get-embedding-theme.ts +++ b/enterprise/frontend/src/embedding-sdk/lib/theme/get-embedding-theme.ts @@ -18,10 +18,7 @@ import { import type { MappableSdkColor } from "./embedding-color-palette"; import { SDK_TO_MAIN_APP_COLORS_MAPPING } from "./embedding-color-palette"; -const getFontFamily = (theme: MetabaseTheme) => - theme.fontFamily ?? DEFAULT_FONT; - -const SDK_BASE_FONT_SIZE = `${DEFAULT_SDK_FONT_SIZE / 16}em`; +const SDK_BASE_FONT_SIZE = `${DEFAULT_SDK_FONT_SIZE}px`; /** * Transforms a public-facing Metabase theme configuration @@ -29,6 +26,7 @@ const SDK_BASE_FONT_SIZE = `${DEFAULT_SDK_FONT_SIZE / 16}em`; */ export function getEmbeddingThemeOverride( theme: MetabaseTheme, + font: string | undefined, ): MantineThemeOverride { const components: MetabaseComponentTheme = merge( DEFAULT_EMBEDDED_COMPONENT_THEME, @@ -36,7 +34,9 @@ export function getEmbeddingThemeOverride( ); const override: MantineThemeOverride = { - fontFamily: getFontFamily(theme), + // font is coming from either redux, where we store theme.fontFamily, + // or from the instance settings, we're adding a default to be used while loading the settings + fontFamily: font ?? DEFAULT_FONT, ...(theme.lineHeight && { lineHeight: theme.lineHeight }), diff --git a/enterprise/frontend/src/embedding-sdk/lib/theme/get-embedding-theme.unit.spec.ts b/enterprise/frontend/src/embedding-sdk/lib/theme/get-embedding-theme.unit.spec.ts index defd9d3755e..99dd7361798 100644 --- a/enterprise/frontend/src/embedding-sdk/lib/theme/get-embedding-theme.unit.spec.ts +++ b/enterprise/frontend/src/embedding-sdk/lib/theme/get-embedding-theme.unit.spec.ts @@ -7,16 +7,19 @@ import { getEmbeddingThemeOverride } from "./get-embedding-theme"; describe("Transform Embedding Theme Override", () => { it("should transform MetabaseTheme to EmbeddingThemeOverride", () => { - const theme = getEmbeddingThemeOverride({ - lineHeight: 1.5, - fontSize: "2rem", - fontFamily: "Roboto", - colors: { - brand: "hotpink", - "text-primary": "yellow", - "text-tertiary": "green", + const theme = getEmbeddingThemeOverride( + { + lineHeight: 1.5, + fontSize: "2rem", + fontFamily: "Roboto", + colors: { + brand: "hotpink", + "text-primary": "yellow", + "text-tertiary": "green", + }, }, - }); + "Roboto", + ); expect(theme).toEqual({ lineHeight: 1.5, diff --git a/frontend/src/metabase/components/Popover/TippyPopover.tsx b/frontend/src/metabase/components/Popover/TippyPopover.tsx index d145ba758fc..6185847d725 100644 --- a/frontend/src/metabase/components/Popover/TippyPopover.tsx +++ b/frontend/src/metabase/components/Popover/TippyPopover.tsx @@ -4,7 +4,7 @@ import { merge } from "icepick"; import { useCallback, useMemo, useState } from "react"; import type * as tippy from "tippy.js"; -import { EMBEDDING_SDK_ROOT_ELEMENT_ID } from "embedding-sdk/config"; +import { EMBEDDING_SDK_PORTAL_ROOT_ELEMENT_ID } from "embedding-sdk/config"; import EventSandbox from "metabase/components/EventSandbox"; import { DEFAULT_Z_INDEX } from "metabase/components/Popover/constants"; import { isCypressActive } from "metabase/env"; @@ -31,7 +31,8 @@ const OFFSET: [number, number] = [0, 5]; function appendTo() { return ( - document.getElementById(EMBEDDING_SDK_ROOT_ELEMENT_ID) || document.body + document.getElementById(EMBEDDING_SDK_PORTAL_ROOT_ELEMENT_ID) || + document.body ); } diff --git a/frontend/src/metabase/core/components/Tooltip/Tooltip.tsx b/frontend/src/metabase/core/components/Tooltip/Tooltip.tsx index 20791699438..588d01f3ebe 100644 --- a/frontend/src/metabase/core/components/Tooltip/Tooltip.tsx +++ b/frontend/src/metabase/core/components/Tooltip/Tooltip.tsx @@ -3,7 +3,7 @@ import { useMemo } from "react"; import * as React from "react"; import * as ReactIs from "react-is"; -import { EMBEDDING_SDK_ROOT_ELEMENT_ID } from "embedding-sdk/config"; +import { EMBEDDING_SDK_PORTAL_ROOT_ELEMENT_ID } from "embedding-sdk/config"; import { DEFAULT_Z_INDEX } from "metabase/components/Popover/constants"; import { isReducedMotionPreferred } from "metabase/lib/dom"; import { isReactDOMTypeElement } from "metabase-types/guards"; @@ -49,7 +49,8 @@ function getTargetProps( function appendTo() { return ( - document.getElementById(EMBEDDING_SDK_ROOT_ELEMENT_ID) || document.body + document.getElementById(EMBEDDING_SDK_PORTAL_ROOT_ELEMENT_ID) || + document.body ); } diff --git a/frontend/src/metabase/visualizations/components/TableInteractive/TableInteractive.jsx b/frontend/src/metabase/visualizations/components/TableInteractive/TableInteractive.jsx index 5c42e2d4274..b090fb53d9f 100644 --- a/frontend/src/metabase/visualizations/components/TableInteractive/TableInteractive.jsx +++ b/frontend/src/metabase/visualizations/components/TableInteractive/TableInteractive.jsx @@ -8,7 +8,7 @@ import { Grid, ScrollSync } from "react-virtualized"; import { t } from "ttag"; import _ from "underscore"; -import { EMBEDDING_SDK_ROOT_ELEMENT_ID } from "embedding-sdk/config"; +import { EMBEDDING_SDK_PORTAL_ROOT_ELEMENT_ID } from "embedding-sdk/config"; import ExplicitSize from "metabase/components/ExplicitSize"; import { QueryColumnInfoPopover } from "metabase/components/MetadataInfo/ColumnInfoPopover"; import Button from "metabase/core/components/Button"; @@ -180,7 +180,7 @@ class TableInteractive extends Component { if (this.props.isEmbeddingSdk) { const rootElement = document.getElementById( - EMBEDDING_SDK_ROOT_ELEMENT_ID, + EMBEDDING_SDK_PORTAL_ROOT_ELEMENT_ID, ); if (rootElement) { diff --git a/frontend/test/__support__/ui.tsx b/frontend/test/__support__/ui.tsx index 197ee3947e3..bb70c3c2070 100644 --- a/frontend/test/__support__/ui.tsx +++ b/frontend/test/__support__/ui.tsx @@ -130,11 +130,13 @@ export function renderWithProviders( const wrapper = (props: any) => { if (mode === "sdk") { return ( - <MetabaseProviderInternal - {...props} - {...sdkProviderProps} - store={store} - /> + <Provider store={store}> + <MetabaseProviderInternal + {...props} + {...sdkProviderProps} + store={store} + /> + </Provider> ); } -- GitLab