From 688b9ad95da7ae9fc87d39b816d71477edc57231 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Nicol=C3=B2=20Pretto?= <info@npretto.com>
Date: Tue, 1 Oct 2024 09:46:34 +0200
Subject: [PATCH] fix(sdk): decrease specificity of css reset in embedding sdk
 (#48193)

---
 .../private/PublicComponentStylesWrapper.tsx  | 29 +++++++++++--------
 .../components/public/MetabaseProvider.tsx    |  8 ++++-
 2 files changed, 24 insertions(+), 13 deletions(-)

diff --git a/enterprise/frontend/src/embedding-sdk/components/private/PublicComponentStylesWrapper.tsx b/enterprise/frontend/src/embedding-sdk/components/private/PublicComponentStylesWrapper.tsx
index 2cc306f7c1b..51077535c42 100644
--- a/enterprise/frontend/src/embedding-sdk/components/private/PublicComponentStylesWrapper.tsx
+++ b/enterprise/frontend/src/embedding-sdk/components/private/PublicComponentStylesWrapper.tsx
@@ -1,3 +1,4 @@
+import { css } from "@emotion/react";
 import styled from "@emotion/styled";
 
 import { aceEditorStyles } from "metabase/query_builder/components/NativeQueryEditor/NativeQueryEditor.styled";
@@ -13,18 +14,6 @@ export const PublicComponentStylesWrapper = styled.div`
   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%;
@@ -48,3 +37,19 @@ export const PublicComponentStylesWrapper = styled.div`
     display: inline;
   }
 `;
+/**
+ * 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.
+ *
+ * The reason why this works is two things combined:
+ * - `*:where(button)` doesn't increase specificity, so the resulting specificity is (0,1,0)
+ * - this global css is loaded in the provider, before our other styles
+ * - -> our other code with specificity (0,1,0) will override this as they're loaded after
+ */
+export const SCOPED_CSS_RESET = css`
+  ${PublicComponentStylesWrapper} *:where(button) {
+    border: 0;
+    background-color: transparent;
+  }
+`;
diff --git a/enterprise/frontend/src/embedding-sdk/components/public/MetabaseProvider.tsx b/enterprise/frontend/src/embedding-sdk/components/public/MetabaseProvider.tsx
index c920e95614d..87f100b15a9 100644
--- a/enterprise/frontend/src/embedding-sdk/components/public/MetabaseProvider.tsx
+++ b/enterprise/frontend/src/embedding-sdk/components/public/MetabaseProvider.tsx
@@ -1,3 +1,4 @@
+import { Global } from "@emotion/react";
 import type { Action, Store } from "@reduxjs/toolkit";
 import { type JSX, type ReactNode, memo, useEffect } from "react";
 import { Provider } from "react-redux";
@@ -24,10 +25,14 @@ import type { MetabaseTheme } from "embedding-sdk/types/theme";
 import { setOptions } from "metabase/redux/embed";
 import { EmotionCacheProvider } from "metabase/styled-components/components/EmotionCacheProvider";
 
-import { PublicComponentStylesWrapper } from "../private/PublicComponentStylesWrapper";
+import {
+  PublicComponentStylesWrapper,
+  SCOPED_CSS_RESET,
+} from "../private/PublicComponentStylesWrapper";
 import { SdkFontsGlobalStyles } from "../private/SdkGlobalFontsStyles";
 import "metabase/css/index.module.css";
 import { SdkUsageProblemDisplay } from "../private/SdkUsageProblem";
+
 import "metabase/css/vendor.css";
 
 export interface MetabaseProviderProps {
@@ -83,6 +88,7 @@ export const MetabaseProviderInternal = ({
 
   return (
     <EmotionCacheProvider>
+      <Global styles={SCOPED_CSS_RESET} />
       <SdkThemeProvider theme={theme}>
         <SdkFontsGlobalStyles baseUrl={config.metabaseInstanceUrl} />
         <div className={className} id={EMBEDDING_SDK_ROOT_ELEMENT_ID}>
-- 
GitLab