diff --git a/packages/app/src/App.tsx b/packages/app/src/App.tsx index dd4bf42c2c..fc2e876468 100644 --- a/packages/app/src/App.tsx +++ b/packages/app/src/App.tsx @@ -14,8 +14,6 @@ * limitations under the License. */ -import { CssBaseline, ThemeProvider } from '@material-ui/core'; -import { lightTheme, darkTheme } from '@backstage/theme'; import { createApp } from '@backstage/core'; import React, { FC } from 'react'; import { BrowserRouter as Router } from 'react-router-dom'; @@ -23,7 +21,6 @@ import Root from './components/Root'; import AlertDisplay from './components/AlertDisplay'; import * as plugins from './plugins'; import apis, { alertApiForwarder } from './apis'; -import { ThemeContextType, ThemeContext, useThemeType } from './ThemeContext'; const app = createApp({ apis, @@ -33,50 +30,15 @@ const app = createApp({ const AppProvider = app.getProvider(); const AppComponent = app.getRootComponent(); -const App: FC<{}> = () => { - const [theme, toggleTheme] = useThemeType( - localStorage.getItem('theme') || 'auto', - ); - - let backstageTheme = lightTheme; - switch (theme) { - case 'light': - backstageTheme = lightTheme; - break; - case 'dark': - backstageTheme = darkTheme; - break; - default: - if (!window.matchMedia) { - backstageTheme = lightTheme; - break; - } - backstageTheme = window.matchMedia('(prefers-color-scheme: dark)').matches - ? darkTheme - : lightTheme; - break; - } - - const themeContext: ThemeContextType = { - theme, - toggleTheme, - }; - return ( - - - - - - - - - - - - - - - ); -}; +const App: FC<{}> = () => ( + + + + + + + + +); export default App; diff --git a/packages/app/src/ThemeContext.tsx b/packages/app/src/ThemeContext.tsx deleted file mode 100644 index 3d5a04f22a..0000000000 --- a/packages/app/src/ThemeContext.tsx +++ /dev/null @@ -1,69 +0,0 @@ -/* - * Copyright 2020 Spotify AB - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -import React, { useState, useEffect } from 'react'; -export type ThemeContextType = { - theme: string; - toggleTheme: () => void; -}; -export const ThemeContext = React.createContext({ - theme: 'light', - toggleTheme: () => {}, -}); - -export function useThemeType(themeId: string): [string, () => void] { - const [theme, setTheme] = useState(themeId); - useEffect(() => { - if (!window.matchMedia) { - return () => {}; - } - const mql = window.matchMedia('(prefers-color-scheme: dark)'); - const darkListener = (event: MediaQueryListEvent) => { - if (localStorage.getItem('theme') === 'auto') { - if (event.matches) { - setTheme('dark'); - } else { - setTheme('light'); - } - setTheme('auto'); - } - }; - mql.addListener(darkListener); - return () => { - mql.removeListener(darkListener); - }; - }); - function toggleTheme() { - if (theme === 'light') { - setTheme('dark'); - localStorage.setItem('theme', 'dark'); - } else if (theme === 'dark') { - if (!window.matchMedia) { - setTheme('light'); - localStorage.setItem('theme', 'light'); - setTheme('light'); - return; - } - setTheme('auto'); - localStorage.setItem('theme', 'auto'); - setTheme('auto'); - } else { - setTheme('light'); - localStorage.setItem('theme', 'light'); - } - } - return [theme, toggleTheme]; -} diff --git a/packages/app/src/components/Root/ToggleThemeSidebarItem.tsx b/packages/app/src/components/Root/ToggleThemeSidebarItem.tsx index 6c0cd09244..a17e8f7019 100644 --- a/packages/app/src/components/Root/ToggleThemeSidebarItem.tsx +++ b/packages/app/src/components/Root/ToggleThemeSidebarItem.tsx @@ -15,42 +15,47 @@ */ import React, { FC } from 'react'; -import { SidebarItem } from '@backstage/core'; -import { ThemeContext } from '../../ThemeContext'; +import { useObservable } from 'react-use'; +import { SidebarItem, useApi, appThemeApiRef } from '@backstage/core'; import WbSunnyIcon from '@material-ui/icons/WbSunny'; import Brightness2Icon from '@material-ui/icons/Brightness2'; import ToggleOnIcon from '@material-ui/icons/ToggleOn'; -const ToggleThemeSidebarItem: FC<{}> = () => { - return ( - - {themeContext => { - let text = 'Auto'; - let icon = ToggleOnIcon; - switch (themeContext.theme) { - case 'dark': - text = 'Dark mode'; - icon = Brightness2Icon; - break; - case 'light': - text = 'Light mode'; - icon = WbSunnyIcon; - break; - default: - text = 'Auto'; - icon = ToggleOnIcon; - break; - } - return ( - - ); - }} - +const ToggleThemeSidebarItem: FC<{}> = () => { + const appThemeApi = useApi(appThemeApiRef); + const themeId = useObservable( + appThemeApi.activeThemeId$(), + appThemeApi.getActiveThemeId(), ); + + let text = 'Auto'; + let icon = ToggleOnIcon; + switch (themeId) { + case 'dark': + text = 'Dark mode'; + icon = Brightness2Icon; + break; + case 'light': + text = 'Light mode'; + icon = WbSunnyIcon; + break; + default: + text = 'Auto'; + icon = ToggleOnIcon; + break; + } + + const handleToggle = () => { + if (!themeId) { + appThemeApi.setActiveThemeId('light'); + } else if (themeId === 'light') { + appThemeApi.setActiveThemeId('dark'); + } else { + appThemeApi.setActiveThemeId(undefined); + } + }; + + return ; }; export default ToggleThemeSidebarItem;