diff --git a/.eslintignore b/.eslintignore index 79764cf70da..234c52ed819 100644 --- a/.eslintignore +++ b/.eslintignore @@ -404,7 +404,7 @@ packages/app-desktop/gui/Sidebar/listItemComponents/TagItem.js packages/app-desktop/gui/Sidebar/styles/index.js packages/app-desktop/gui/Sidebar/types.js packages/app-desktop/gui/StatusScreen/StatusScreen.js -packages/app-desktop/gui/StyleSheets/StyleSheetContainer.js +packages/app-desktop/gui/StyleSheets/AppStyleContainer.js packages/app-desktop/gui/SyncWizard/Dialog.js packages/app-desktop/gui/TagItem.js packages/app-desktop/gui/TagList.js diff --git a/.gitignore b/.gitignore index 18586771d0d..38cd5e94fde 100644 --- a/.gitignore +++ b/.gitignore @@ -379,7 +379,7 @@ packages/app-desktop/gui/Sidebar/listItemComponents/TagItem.js packages/app-desktop/gui/Sidebar/styles/index.js packages/app-desktop/gui/Sidebar/types.js packages/app-desktop/gui/StatusScreen/StatusScreen.js -packages/app-desktop/gui/StyleSheets/StyleSheetContainer.js +packages/app-desktop/gui/StyleSheets/AppStyleContainer.js packages/app-desktop/gui/SyncWizard/Dialog.js packages/app-desktop/gui/TagItem.js packages/app-desktop/gui/TagList.js diff --git a/packages/app-desktop/gui/NoteEditor/EditorWindow.tsx b/packages/app-desktop/gui/NoteEditor/EditorWindow.tsx index b52c678ab6c..b24cb8a5ad6 100644 --- a/packages/app-desktop/gui/NoteEditor/EditorWindow.tsx +++ b/packages/app-desktop/gui/NoteEditor/EditorWindow.tsx @@ -1,7 +1,7 @@ import * as React from 'react'; import { useCallback, useMemo, useRef, useState } from 'react'; import NoteEditor from './NoteEditor'; -import StyleSheetContainer from '../StyleSheets/StyleSheetContainer'; +import AppStyleContainer from '../StyleSheets/AppStyleContainer'; import { connect } from 'react-redux'; import { AppState } from '../../app.reducer'; import { Dispatch } from 'redux'; @@ -79,7 +79,7 @@ const SecondaryWindow: React.FC = props => { {editor} - + ; }; diff --git a/packages/app-desktop/gui/Root.tsx b/packages/app-desktop/gui/Root.tsx index 25f39c90782..cf3373ab1df 100644 --- a/packages/app-desktop/gui/Root.tsx +++ b/packages/app-desktop/gui/Root.tsx @@ -19,7 +19,7 @@ import ClipperServer from '@joplin/lib/ClipperServer'; import DialogTitle from './DialogTitle'; import DialogButtonRow, { ButtonSpec, ClickEvent, ClickEventHandler } from './DialogButtonRow'; import Dialog from './Dialog'; -import StyleSheetContainer from './StyleSheets/StyleSheetContainer'; +import AppStyleContainer from './StyleSheets/AppStyleContainer'; import ImportScreen from './ImportScreen'; const { ResourceScreen } = require('./ResourceScreen.js'); import Navigator from './Navigator'; @@ -197,7 +197,7 @@ class RootComponent extends React.Component { return ( - + diff --git a/packages/app-desktop/gui/StyleSheets/StyleSheetContainer.tsx b/packages/app-desktop/gui/StyleSheets/AppStyleContainer.tsx similarity index 90% rename from packages/app-desktop/gui/StyleSheets/StyleSheetContainer.tsx rename to packages/app-desktop/gui/StyleSheets/AppStyleContainer.tsx index 2cf5c142384..d12c2f4a07e 100644 --- a/packages/app-desktop/gui/StyleSheets/StyleSheetContainer.tsx +++ b/packages/app-desktop/gui/StyleSheets/AppStyleContainer.tsx @@ -13,10 +13,11 @@ import * as React from 'react'; import { useEffect, useMemo, useState } from 'react'; import useAsyncEffect, { AsyncEffectEvent } from '@joplin/lib/hooks/useAsyncEffect'; import themeToCss from '@joplin/lib/services/style/themeToCss'; -import { themeStyle } from '@joplin/lib/theme'; +import { ThemeStyle, themeStyle } from '@joplin/lib/theme'; import useDocument from '../hooks/useDocument'; import { connect } from 'react-redux'; import { AppState } from '../../app.reducer'; +import { ThemeAppearance } from '@joplin/lib/themes/type'; interface Props { themeId: number; @@ -33,15 +34,14 @@ const editorFontFromSettings = (settingValue: string) => { return fontFamilies; }; -const useThemeCss = (themeId: number) => { +const useThemeCss = (theme: ThemeStyle) => { const [themeCss, setThemeCss] = useState(''); useAsyncEffect(async (event: AsyncEffectEvent) => { - const theme = themeStyle(themeId); const themeCss = themeToCss(theme); if (event.cancelled) return; setThemeCss(themeCss); - }, [themeId]); + }, [theme]); return themeCss; }; @@ -109,11 +109,12 @@ const useThemeFlag = (doc: Document|null, flag: string, enabled: boolean) => { }, [doc, flag, enabled]); }; -const StyleSheetContainer: React.FC = props => { +const AppStyleContainer: React.FC = props => { const [elementRef, setElementRef] = useState(null); const doc = useDocument(elementRef); - const themeCss = useThemeCss(props.themeId); + const theme = themeStyle(props.themeId); + const themeCss = useThemeCss(theme); const editorCss = useEditorCss(props.editorFontSetting); useAppliedCss(doc, ` @@ -127,6 +128,7 @@ const StyleSheetContainer: React.FC = props => { // Theme flags useThemeFlag(doc, '-native-scrollbars', !props.customScrollbarsSetting); + useThemeFlag(doc, '-dark-mode', theme.appearance === ThemeAppearance.Dark); return
; }; @@ -138,4 +140,4 @@ export default connect((state: AppState) => { editorFontSetting: state.settings['style.editor.fontFamily'] as string, customChromeCssPaths: state.customChromeCssPaths, }; -})(StyleSheetContainer); +})(AppStyleContainer); diff --git a/packages/app-desktop/main.scss b/packages/app-desktop/main.scss index 42d8fbc4e6f..c6bb6427faa 100644 --- a/packages/app-desktop/main.scss +++ b/packages/app-desktop/main.scss @@ -33,6 +33,15 @@ a { text-decoration: none; } +:root.-dark-mode { + // Make most UI controls (including native scrollbars) match the app theme. + color-scheme: dark; +} + +input[type=checkbox] { + color-scheme: light; +} + :root:not(.-native-scrollbars) { ::-webkit-scrollbar { width: 7px; diff --git a/packages/renderer/noteStyle.ts b/packages/renderer/noteStyle.ts index 64e99dd51b2..964e403381a 100644 --- a/packages/renderer/noteStyle.ts +++ b/packages/renderer/noteStyle.ts @@ -135,6 +135,7 @@ export default function(theme: Theme, options: Options = null) { font-family: ${fontFamily}; padding-bottom: ${formatCssSize(theme.bodyPaddingBottom)}; padding-top: ${formatCssSize(theme.bodyPaddingTop)}; + ${theme.appearance === 'dark' ? 'color-scheme: dark;' : ''} } kbd { border: 1px solid ${theme.codeBorderColor}; @@ -143,6 +144,9 @@ export default function(theme: Theme, options: Options = null) { border-radius: 3px; background-color: ${theme.codeBackgroundColor}; } + input[type=checkbox] { + color-scheme: light; + } ${options.customScrollbars ? customScrollbarCss(theme) : ''} ${maxWidthCss}