From ba7e68539a62d64dfb15f205483170b5edb3ece3 Mon Sep 17 00:00:00 2001 From: mohit038 Date: Fri, 23 Sep 2022 23:54:56 +0530 Subject: [PATCH 1/6] add themes --- src/theme/Dark.tsx | 31 +++++++++++++++++++++++++++++++ src/theme/Light.tsx | 32 ++++++++++++++++++++++++++++++++ 2 files changed, 63 insertions(+) create mode 100644 src/theme/Dark.tsx create mode 100644 src/theme/Light.tsx diff --git a/src/theme/Dark.tsx b/src/theme/Dark.tsx new file mode 100644 index 00000000..ef7358fa --- /dev/null +++ b/src/theme/Dark.tsx @@ -0,0 +1,31 @@ +import { createTheme } from '@fluentui/react'; +import globalStyles from '.'; + +const darkTheme = createTheme({ + defaultFontStyle: { fontFamily: globalStyles.fontFamily }, + palette: { + themePrimary: '#106ebe', + themeLighterAlt: '#010408', + themeLighter: '#02111f', + themeLight: '#052139', + themeTertiary: '#094173', + themeSecondary: '#0d60a8', + themeDarkAlt: '#2279c6', + themeDark: '#3e8bcf', + themeDarker: '#6aa7db', + neutralLighterAlt: '#302e2e', + neutralLighter: '#383636', + neutralLight: '#464444', + neutralQuaternaryAlt: '#4e4c4c', + neutralQuaternary: '#555353', + neutralTertiaryAlt: '#727070', + neutralTertiary: '#eaeaea', + neutralSecondary: '#eeeeee', + neutralPrimaryAlt: '#f1f1f1', + neutralPrimary: '#e0e0e0', + neutralDark: '#f8f8f8', + black: '#fbfbfb', + white: '#272626', + }, +}); +export default darkTheme; diff --git a/src/theme/Light.tsx b/src/theme/Light.tsx new file mode 100644 index 00000000..e5a61a0e --- /dev/null +++ b/src/theme/Light.tsx @@ -0,0 +1,32 @@ +import { createTheme } from '@fluentui/react'; +import globalStyles from '.'; + +const lightTheme = createTheme({ + defaultFontStyle: { fontFamily: globalStyles.fontFamily }, + palette: { + themePrimary: '#0078d4', + themeLighterAlt: '#eff6fc', + themeLighter: '#deecf9', + themeLight: '#c7e0f4', + themeTertiary: '#71afe5', + themeSecondary: '#2b88d8', + themeDarkAlt: '#106ebe', + themeDark: '#005a9e', + themeDarker: '#004578', + neutralLighterAlt: '#faf9f8', + neutralLighter: '#f3f2f1', + neutralLight: '#edebe9', + neutralQuaternaryAlt: '#e1dfdd', + neutralQuaternary: '#d0d0d0', + neutralTertiaryAlt: '#c8c6c4', + neutralTertiary: '#a19f9d', + neutralSecondary: '#605e5c', + neutralPrimaryAlt: '#3b3a39', + neutralPrimary: '#323130', + neutralDark: '#201f1e', + black: '#000000', + white: '#ffffff', + }, +}); + +export default lightTheme; From fad806aa0ff175c9b29b07b2a73313e3205e19d1 Mon Sep 17 00:00:00 2001 From: mohit038 Date: Fri, 23 Sep 2022 23:55:10 +0530 Subject: [PATCH 2/6] add theme context --- src/taskpane/contexts/ThemeContext.tsx | 51 ++++++++++++++++++++++++++ types/index.ts | 8 ++++ 2 files changed, 59 insertions(+) create mode 100644 src/taskpane/contexts/ThemeContext.tsx create mode 100644 types/index.ts diff --git a/src/taskpane/contexts/ThemeContext.tsx b/src/taskpane/contexts/ThemeContext.tsx new file mode 100644 index 00000000..d12dc851 --- /dev/null +++ b/src/taskpane/contexts/ThemeContext.tsx @@ -0,0 +1,51 @@ +/* eslint-disable @typescript-eslint/no-unused-vars */ +import { ThemeProvider } from '@fluentui/react/lib/utilities/ThemeProvider/ThemeProvider'; +import React, { createContext } from 'react'; +import { Theme } from '../../../types/index'; +import UserPreferences from '../../utils/UserPreferences'; +import darkTheme from '../../theme/Dark'; +import lightTheme from '../../theme/Light'; + +interface ThemeContextProps { + children: React.ReactNode; + initTheme: Theme; +} + +interface ThemeContextInterface { + theme: Theme; + changeTheme: () => void; +} + +const ThemeContext = createContext(null); + +const getTheme = (theme: Theme) => (theme === Theme.DARK ? darkTheme : lightTheme); + +export function ThemeContextProvider({ children, initTheme }: ThemeContextProps): JSX.Element { + const [theme, setThemeValue] = React.useState(initTheme); + const changeTheme = () => { + setThemeValue((prevVal) => { + const newVal = prevVal === Theme.DARK ? Theme.LIGHT : Theme.DARK; + UserPreferences.setTheme(newVal); + UserPreferences.syncPreferences(); + return newVal; + }); + }; + const value = { theme, changeTheme }; + return ( + + {children} + + ); +} + +export const useTheme = (): ThemeContextInterface => { + const context = React.useContext(ThemeContext); + if (!context) { + throw new Error( + 'useTheme must be used within a ThemeContextProvider. Wrap a parent component in to fix this error.' + ); + } + return context; +}; + +export default ThemeContext; diff --git a/types/index.ts b/types/index.ts new file mode 100644 index 00000000..93a14388 --- /dev/null +++ b/types/index.ts @@ -0,0 +1,8 @@ +/* eslint-disable no-unused-vars */ +/* eslint-disable no-shadow */ +/* eslint-disable import/prefer-default-export */ + +export enum Theme { + LIGHT, + DARK, +} From 121e73e1882b04920745010c1515e22b7d408910 Mon Sep 17 00:00:00 2001 From: mohit038 Date: Fri, 23 Sep 2022 23:56:34 +0530 Subject: [PATCH 3/6] Sync theme with local storage --- src/taskpane/components/App.tsx | 35 +++++++++++++++++++-------------- src/taskpane/index.tsx | 7 +++++-- src/utils/UserPreferences.ts | 9 +++++++++ 3 files changed, 34 insertions(+), 17 deletions(-) diff --git a/src/taskpane/components/App.tsx b/src/taskpane/components/App.tsx index 6887a506..27c39695 100644 --- a/src/taskpane/components/App.tsx +++ b/src/taskpane/components/App.tsx @@ -7,14 +7,17 @@ import ProtectedRoutes from '../../utils/ProtectedRoutes'; import { CitationStoreProvider } from '../contexts/CitationStoreContext'; import { CiteSupportProvider } from '../contexts/CiteSupportContext'; import Wrapper from './Wrapper'; +import { ThemeContextProvider } from '../contexts/ThemeContext'; +import { Theme } from '../../../types'; export interface AppProps { title: string; + theme: Theme; isOfficeInitialized: boolean; } function App(props: AppProps): ReactElement { - const { isOfficeInitialized, title } = props; + const { isOfficeInitialized, title, theme } = props; if (!isOfficeInitialized) { return ( @@ -23,20 +26,22 @@ function App(props: AppProps): ReactElement { } return ( - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + ); } export default App; diff --git a/src/taskpane/index.tsx b/src/taskpane/index.tsx index a1fcc2e9..4313d0fe 100644 --- a/src/taskpane/index.tsx +++ b/src/taskpane/index.tsx @@ -14,11 +14,13 @@ import { initializeIcons, ThemeProvider } from '@fluentui/react'; import { HashRouter as Router } from 'react-router-dom'; import App from './components/App'; import client from '../plugins/apollo/apolloClient'; +import { Theme } from '../../types'; +import UserPreferences from '../utils/UserPreferences'; initializeIcons(); +let theme: Theme; let isOfficeInitialized = false; - const title = 'JabRef Task Pane Add-in'; const render = (Component) => { @@ -27,7 +29,7 @@ const render = (Component) => { - + @@ -40,6 +42,7 @@ const render = (Component) => { // eslint-disable-next-line no-void void Office.onReady(() => { isOfficeInitialized = true; + theme = UserPreferences.getTheme(); render(App); }); diff --git a/src/utils/UserPreferences.ts b/src/utils/UserPreferences.ts index f78e50a0..8d4fdf3d 100644 --- a/src/utils/UserPreferences.ts +++ b/src/utils/UserPreferences.ts @@ -1,3 +1,4 @@ +import { Theme } from '../../types'; import DocumentStorage from '../services/DocumentStorage'; export default class UserPreferences { @@ -12,4 +13,12 @@ export default class UserPreferences { static syncPreferences(): void { DocumentStorage.save(); } + + static getTheme(): Theme { + return DocumentStorage.getItem('theme') === '1' ? Theme.DARK : Theme.LIGHT; + } + + static setTheme(theme: Theme): void { + DocumentStorage.setItem('theme', theme.toString()); + } } From 75550ad317a6b267dd13e46b4a6577690b547ae3 Mon Sep 17 00:00:00 2001 From: mohit038 Date: Fri, 23 Sep 2022 23:56:45 +0530 Subject: [PATCH 4/6] add theme change button --- src/taskpane/components/Footer.tsx | 13 ++++++++++++- src/taskpane/layout/Layout.tsx | 10 +++++++++- 2 files changed, 21 insertions(+), 2 deletions(-) diff --git a/src/taskpane/components/Footer.tsx b/src/taskpane/components/Footer.tsx index bc10bb4e..658d402a 100644 --- a/src/taskpane/components/Footer.tsx +++ b/src/taskpane/components/Footer.tsx @@ -1,7 +1,10 @@ import { Stack, ActionButton } from '@fluentui/react'; import React, { ReactElement } from 'react'; +import { Theme } from '../../../types'; import { + light, + dark, Signout, SyncBib, imageProps, @@ -13,9 +16,11 @@ import { interface FooterProps { onSyncBibliography: () => void; onLogout: () => void; + onThemeChange: () => void; + theme: Theme; } -function Footer({ onSyncBibliography, onLogout }: FooterProps): ReactElement { +function Footer({ onSyncBibliography, onLogout, onThemeChange, theme }: FooterProps): ReactElement { return ( jabref logo + { }; function Layout(): JSX.Element { + const { theme, changeTheme } = useTheme(); + const [selectedKey, setSelectedKey] = useState('dashboard'); const handleLinkClick = (item?: PivotItem) => { @@ -51,7 +54,12 @@ function Layout(): JSX.Element { {selectedKey === 'dashboard' ? : } -