diff --git a/apps/studio/components/interfaces/App/AppBannerWrapper.tsx b/apps/studio/components/interfaces/App/AppBannerWrapper.tsx
index df824bb697f..d54189d2d38 100644
--- a/apps/studio/components/interfaces/App/AppBannerWrapper.tsx
+++ b/apps/studio/components/interfaces/App/AppBannerWrapper.tsx
@@ -1,33 +1,19 @@
-import { useMonaco } from '@monaco-editor/react'
-import { useTheme } from 'next-themes'
-import { PropsWithChildren, useMemo } from 'react'
+import { PropsWithChildren } from 'react'
import { ClockSkewBanner } from 'components/layouts/AppLayout/ClockSkewBanner'
import IncidentBanner from 'components/layouts/AppLayout/IncidentBanner'
import { NoticeBanner } from 'components/layouts/AppLayout/NoticeBanner'
import { RestrictionBanner } from 'components/layouts/AppLayout/RestrictionBanner'
-import { getTheme } from 'components/ui/CodeEditor/CodeEditor.utils'
import { useFlag } from 'hooks/ui/useFlag'
import { useProfile } from 'lib/profile'
const AppBannerWrapper = ({ children }: PropsWithChildren<{}>) => {
- const monaco = useMonaco()
const { profile } = useProfile()
- const { resolvedTheme } = useTheme()
const ongoingIncident = useFlag('ongoingIncident')
const showNoticeBanner = useFlag('showNoticeBanner')
const clockSkewBanner = useFlag('clockSkewBanner')
- // Define the supabase theme for Monaco before anything is rendered. Using useEffect would sometime load the theme
- // after the editor was loaded, so it looked off. useMemo will always be run before rendering
- useMemo(() => {
- if (monaco && resolvedTheme) {
- const mode: any = getTheme(resolvedTheme)
- monaco.editor.defineTheme('supabase', mode)
- }
- }, [resolvedTheme, monaco])
-
return (
diff --git a/apps/studio/components/interfaces/App/MonacoThemeProvider.tsx b/apps/studio/components/interfaces/App/MonacoThemeProvider.tsx
new file mode 100644
index 00000000000..92b9fb6e0f8
--- /dev/null
+++ b/apps/studio/components/interfaces/App/MonacoThemeProvider.tsx
@@ -0,0 +1,44 @@
+import { useMonaco } from '@monaco-editor/react'
+import { useTheme } from 'next-themes'
+import { useMemo } from 'react'
+
+const getTheme = (theme: string) => {
+ const isDarkMode = theme.includes('dark')
+ // [TODO] Probably need better theming for light mode
+ return {
+ base: isDarkMode ? ('vs-dark' as const) : ('vs' as const), // can also be vs-dark or hc-black
+ inherit: true, // can also be false to completely replace the builtin rules
+ rules: [
+ { token: '', background: isDarkMode ? '1f1f1f' : 'f0f0f0' },
+ {
+ token: '',
+ background: isDarkMode ? '1f1f1f' : 'f0f0f0',
+ foreground: isDarkMode ? 'd4d4d4' : '444444',
+ },
+ { token: 'string.sql', foreground: '24b47e' },
+ { token: 'comment', foreground: '666666' },
+ { token: 'predefined.sql', foreground: isDarkMode ? 'D4D4D4' : '444444' },
+ ],
+ colors: { 'editor.background': isDarkMode ? '#1f1f1f' : '#f0f0f0' },
+ }
+}
+
+/**
+ * This component is used to set the theme for the Monaco editor. This would be a hook but it needs to be placed between
+ * ThemeProvider and the layout page so a component is the most convenient way to do this.
+ */
+export const MonacoThemeProvider = () => {
+ const monaco = useMonaco()
+ const { resolvedTheme } = useTheme()
+
+ // Define the supabase theme for Monaco before anything is rendered. Using useEffect would sometime load the theme
+ // after the editor was loaded, so it looked off. useMemo will always be run before rendering
+ useMemo(() => {
+ if (monaco && resolvedTheme) {
+ const mode = getTheme(resolvedTheme)
+ monaco.editor.defineTheme('supabase', mode)
+ }
+ }, [resolvedTheme, monaco])
+
+ return null
+}
diff --git a/apps/studio/components/ui/CodeEditor/CodeEditor.utils.ts b/apps/studio/components/ui/CodeEditor/CodeEditor.utils.ts
index e8e14e7ab49..5540d9d1456 100644
--- a/apps/studio/components/ui/CodeEditor/CodeEditor.utils.ts
+++ b/apps/studio/components/ui/CodeEditor/CodeEditor.utils.ts
@@ -8,24 +8,3 @@ export const alignEditor = (editor: any) => {
})
})
}
-
-export const getTheme = (theme: string) => {
- const isDarkMode = theme.includes('dark')
- // [TODO] Probably need better theming for light mode
- return {
- base: isDarkMode ? 'vs-dark' : 'vs', // can also be vs-dark or hc-black
- inherit: true, // can also be false to completely replace the builtin rules
- rules: [
- { background: isDarkMode ? '1f1f1f' : 'f0f0f0' },
- {
- token: '',
- background: isDarkMode ? '1f1f1f' : 'f0f0f0',
- foreground: isDarkMode ? 'd4d4d4' : '444444',
- },
- { token: 'string.sql', foreground: '24b47e' },
- { token: 'comment', foreground: '666666' },
- { token: 'predefined.sql', foreground: isDarkMode ? 'D4D4D4' : '444444' },
- ],
- colors: { 'editor.background': isDarkMode ? '#1f1f1f' : '#f0f0f0' },
- }
-}
diff --git a/apps/studio/pages/_app.tsx b/apps/studio/pages/_app.tsx
index 8ae9da848ad..9560ed5aaab 100644
--- a/apps/studio/pages/_app.tsx
+++ b/apps/studio/pages/_app.tsx
@@ -32,11 +32,12 @@ import { ErrorBoundary } from 'react-error-boundary'
import { FeatureFlagProvider, PageTelemetry, ThemeProvider, useThemeSandbox } from 'common'
import MetaFaviconsPagesRouter from 'common/MetaFavicons/pages-router'
-import { AppBannerWrapper, RouteValidationWrapper } from 'components/interfaces/App'
+import { RouteValidationWrapper } from 'components/interfaces/App'
import { AppBannerContextProvider } from 'components/interfaces/App/AppBannerWrapperContext'
import { StudioCommandMenu } from 'components/interfaces/App/CommandMenu'
import { FeaturePreviewContextProvider } from 'components/interfaces/App/FeaturePreview/FeaturePreviewContext'
import FeaturePreviewModal from 'components/interfaces/App/FeaturePreview/FeaturePreviewModal'
+import { MonacoThemeProvider } from 'components/interfaces/App/MonacoThemeProvider'
import { GenerateSql } from 'components/interfaces/SqlGenerator/SqlGenerator'
import { ErrorBoundaryState } from 'components/ui/ErrorBoundaryState'
import GroupsTelemetry from 'components/ui/GroupsTelemetry'
@@ -130,6 +131,7 @@ function CustomApp({ Component, pageProps }: AppPropsWithLayout) {
+