From 3960a984523352a99a6e17e2b59ba3a0c7c226a6 Mon Sep 17 00:00:00 2001 From: shall0pass <20625555+shall0pass@users.noreply.github.com> Date: Fri, 16 Feb 2024 09:43:24 -0600 Subject: [PATCH] [Enhancement] Theme: Midnight (#2312) * midnight updates * updates * updates * background one shade darker * change highlights to match other accents * release note * link color * variable spelling * Upcoming pill color * theme switch bug * remove development, type error * toggle background, disabled background+text * account pillboxes and icons * typecheck error --- .../src/components/ThemeSelector.tsx | 1 + packages/desktop-client/src/style/theme.tsx | 4 +- .../src/style/themes/midnight.ts | 191 ++++++++++++++++++ packages/loot-core/src/server/main.ts | 6 +- packages/loot-core/src/types/prefs.d.ts | 2 +- upcoming-release-notes/2312.md | 6 + 6 files changed, 207 insertions(+), 3 deletions(-) create mode 100644 packages/desktop-client/src/style/themes/midnight.ts create mode 100644 upcoming-release-notes/2312.md diff --git a/packages/desktop-client/src/components/ThemeSelector.tsx b/packages/desktop-client/src/components/ThemeSelector.tsx index 415089cb1a4..ed2a49508a2 100644 --- a/packages/desktop-client/src/components/ThemeSelector.tsx +++ b/packages/desktop-client/src/components/ThemeSelector.tsx @@ -24,6 +24,7 @@ export function ThemeSelector({ style }: ThemeSelectorProps) { light: SvgSun, dark: SvgMoonStars, auto: SvgSystem, + midnight: SvgMoonStars, } as const; function onMenuSelect(newTheme: Theme) { diff --git a/packages/desktop-client/src/style/theme.tsx b/packages/desktop-client/src/style/theme.tsx index fe6b2374d14..da0e68dbe49 100644 --- a/packages/desktop-client/src/style/theme.tsx +++ b/packages/desktop-client/src/style/theme.tsx @@ -9,10 +9,12 @@ import { useGlobalPref } from '../hooks/useGlobalPref'; import * as darkTheme from './themes/dark'; import * as developmentTheme from './themes/development'; import * as lightTheme from './themes/light'; +import * as midnightTheme from './themes/midnight'; const themes = { light: { name: 'Light', colors: lightTheme }, dark: { name: 'Dark', colors: darkTheme }, + midnight: { name: 'Midnight', colors: midnightTheme }, auto: { name: 'System default', colors: darkTheme }, ...(isNonProductionEnvironment() && { development: { name: 'Development', colors: developmentTheme }, @@ -31,7 +33,7 @@ export function useTheme() { export function ThemeStyle() { const [theme] = useTheme(); const [themeColors, setThemeColors] = useState< - typeof lightTheme | typeof darkTheme | undefined + typeof lightTheme | typeof darkTheme | typeof midnightTheme | undefined >(undefined); useEffect(() => { diff --git a/packages/desktop-client/src/style/themes/midnight.ts b/packages/desktop-client/src/style/themes/midnight.ts new file mode 100644 index 00000000000..163dd0513a2 --- /dev/null +++ b/packages/desktop-client/src/style/themes/midnight.ts @@ -0,0 +1,191 @@ +import * as colorPalette from '../palette'; + +export const pageBackground = colorPalette.gray600; //mobile and desktop +export const pageBackgroundModalActive = colorPalette.gray700; +export const pageBackgroundTopLeft = colorPalette.gray800; +export const pageBackgroundBottomRight = colorPalette.gray700; +export const pageBackgroundLineTop = colorPalette.purple300; +export const pageBackgroundLineMid = colorPalette.gray900; +export const pageBackgroundLineBottom = colorPalette.gray150; +export const pageText = colorPalette.gray100; +export const pageTextLight = colorPalette.gray200; +export const pageTextSubdued = colorPalette.gray400; +export const pageTextDark = colorPalette.gray100; +export const pageTextPositive = colorPalette.purple200; +export const pageTextLink = colorPalette.purple300; +export const pageTextLinkLight = colorPalette.purple300; + +export const cardBackground = colorPalette.gray800; +export const cardBorder = colorPalette.purple300; +export const cardShadow = colorPalette.gray900; + +export const tableBackground = colorPalette.gray800; //Desktop and mobile budget background, Mobile New Transaction input box background +export const tableRowBackgroundHover = colorPalette.gray500; +export const tableText = colorPalette.gray150; +export const tableTextLight = tableText; +export const tableTextSubdued = colorPalette.gray500; +export const tableTextSelected = colorPalette.gray150; +export const tableTextHover = colorPalette.gray400; +export const tableTextInactive = colorPalette.gray400; +export const tableHeaderText = colorPalette.gray200; +export const tableHeaderBackground = colorPalette.gray900; +export const tableBorder = colorPalette.gray500; +export const tableBorderSelected = colorPalette.purple400; +export const tableBorderHover = colorPalette.purple300; +export const tableBorderSeparator = colorPalette.gray400; +export const tableRowBackgroundHighlight = colorPalette.purple150; +export const tableRowBackgroundHighlightText = colorPalette.gray600; +export const tableRowHeaderBackground = colorPalette.gray700; +export const tableRowHeaderText = colorPalette.gray150; + +export const sidebarBackground = colorPalette.gray900; +export const sidebarItemBackgroundPositive = colorPalette.green400; +export const sidebarItemBackgroundFailed = colorPalette.red300; +export const sidebarItemAccentSelected = colorPalette.purple200; +export const sidebarItemBackgroundHover = colorPalette.gray700; +export const sidebarItemText = colorPalette.gray100; +export const sidebarItemTextSelected = colorPalette.purple200; + +export const menuBackground = colorPalette.gray700; //700 pop up menu background +export const menuItemBackground = colorPalette.gray200; +export const menuItemBackgroundHover = colorPalette.gray500; +export const menuItemText = colorPalette.gray100; +export const menuItemTextHover = colorPalette.gray50; +export const menuItemTextSelected = colorPalette.purple400; +export const menuItemTextHeader = colorPalette.purple200; //mobile autocomplete text +export const menuBorder = colorPalette.gray800; // +export const menuBorderHover = colorPalette.purple300; +export const menuKeybindingText = colorPalette.gray500; +export const menuAutoCompleteBackground = colorPalette.gray600; //desktop autocomplete +export const menuAutoCompleteBackgroundHover = colorPalette.gray400; //desktop autocomplete +export const menuAutoCompleteText = colorPalette.gray100; //desktop autocomplete +export const menuAutoCompleteTextHeader = colorPalette.purple200; //desktop autocomplete + +export const modalBackground = colorPalette.gray600; //controls desktop modals and mobile autocomplete background +export const modalBorder = colorPalette.gray200; //?? Not used +export const mobileHeaderBackground = colorPalette.gray800; +export const mobileHeaderText = colorPalette.purple200; +export const mobileHeaderTextSubdued = colorPalette.gray200; +export const mobileHeaderTextHover = 'rgba(200, 200, 200, .15)'; +export const mobilePageBackground = colorPalette.gray900; +export const mobileNavBackground = colorPalette.gray600; //Mobile bottom navigation bar +export const mobileNavItem = colorPalette.gray150; +export const mobileNavItemSelected = colorPalette.purple200; +export const mobileAccountShadow = cardShadow; +export const mobileAccountText = colorPalette.blue800; +export const mobileModalBackground = colorPalette.gray100; //??? +export const mobileModalText = colorPalette.white; + +// Mobile view themes (for the top bar) +export const mobileViewTheme = mobileHeaderBackground; +export const mobileConfigServerViewTheme = colorPalette.purple500; + +export const markdownNormal = colorPalette.purple700; +export const markdownDark = colorPalette.purple500; +export const markdownLight = colorPalette.purple800; + +// Button +export const buttonMenuText = colorPalette.gray200; +export const buttonMenuTextHover = buttonMenuText; +export const buttonMenuBackground = colorPalette.gray700; //700 +export const buttonMenuBackgroundHover = 'rgba(200, 200, 200, .25)'; +export const buttonMenuBorder = colorPalette.gray500; +export const buttonMenuSelectedText = colorPalette.green800; +export const buttonMenuSelectedTextHover = colorPalette.orange800; +export const buttonMenuSelectedBackground = colorPalette.orange200; +export const buttonMenuSelectedBackgroundHover = colorPalette.gray300; +export const buttonMenuSelectedBorder = buttonMenuSelectedBackground; + +export const buttonPrimaryText = colorPalette.white; +export const buttonPrimaryTextHover = buttonPrimaryText; +export const buttonPrimaryBackground = colorPalette.gray400; +export const buttonPrimaryBackgroundHover = buttonPrimaryBackground; +export const buttonPrimaryBorder = buttonPrimaryBackground; +export const buttonPrimaryShadow = 'rgba(0, 0, 0, 0.6)'; +export const buttonPrimaryDisabledText = colorPalette.gray700; +export const buttonPrimaryDisabledBackground = colorPalette.gray700; +export const buttonPrimaryDisabledBorder = buttonPrimaryDisabledBackground; + +export const buttonNormalText = colorPalette.gray150; +export const buttonNormalTextHover = colorPalette.gray150; +export const buttonNormalBackground = colorPalette.gray600; //Mobile Account buttons +export const buttonNormalBackgroundHover = colorPalette.gray400; //Mobile Account buttons +export const buttonNormalBorder = colorPalette.gray300; +export const buttonNormalShadow = 'rgba(0, 0, 0, 0.4)'; +export const buttonNormalSelectedText = colorPalette.white; +export const buttonNormalSelectedBackground = colorPalette.purple500; +export const buttonNormalDisabledText = colorPalette.gray500; +export const buttonNormalDisabledBackground = colorPalette.gray700; +export const buttonNormalDisabledBorder = colorPalette.gray500; + +export const calendarText = colorPalette.gray50; +export const calendarBackground = colorPalette.gray700; +export const calendarItemText = colorPalette.gray150; +export const calendarItemBackground = colorPalette.gray500; +export const calendarSelectedBackground = buttonNormalSelectedBackground; + +export const buttonBareText = buttonNormalText; +export const buttonBareTextHover = buttonNormalText; +export const buttonBareBackground = 'transparent'; +export const buttonBareBackgroundHover = 'rgba(200, 200, 200, .3)'; +export const buttonBareBackgroundActive = 'rgba(200, 200, 200, .5)'; +export const buttonBareDisabledText = buttonNormalDisabledText; +export const buttonBareDisabledBackground = buttonBareBackground; + +export const noticeBackground = colorPalette.green600; +export const noticeBackgroundLight = colorPalette.green900; +export const noticeBackgroundDark = colorPalette.green400; +export const noticeText = colorPalette.green300; +export const noticeTextLight = colorPalette.green400; +export const noticeTextDark = colorPalette.green150; +export const noticeTextMenu = colorPalette.green400; +export const noticeBorder = colorPalette.green800; +export const warningBackground = colorPalette.orange800; //800 +export const warningText = colorPalette.orange200; //300 +export const warningTextLight = colorPalette.orange500; +export const warningTextDark = colorPalette.orange100; +export const warningBorder = colorPalette.orange500; +export const errorBackground = colorPalette.red800; //800 +export const errorText = colorPalette.red200; //200 +export const errorTextDark = colorPalette.red150; +export const errorTextDarker = errorTextDark; +export const errorTextMenu = colorPalette.red500; +export const errorBorder = colorPalette.red500; +export const upcomingBackground = colorPalette.purple800; //700 +export const upcomingText = colorPalette.purple200; //100 +export const upcomingBorder = tableBorder; + +export const formLabelText = colorPalette.purple150; +export const formLabelBackground = colorPalette.blue900; +export const formInputBackground = colorPalette.gray800; +export const formInputBackgroundSelected = colorPalette.gray700; +export const formInputBackgroundSelection = colorPalette.purple400; +export const formInputBorder = colorPalette.gray600; +export const formInputTextReadOnlySelection = colorPalette.gray800; +export const formInputBorderSelected = colorPalette.purple300; +export const formInputText = colorPalette.gray150; +export const formInputTextSelected = colorPalette.black; +export const formInputTextPlaceholder = colorPalette.gray150; +export const formInputTextPlaceholderSelected = colorPalette.gray100; +export const formInputTextSelection = colorPalette.gray800; +export const formInputShadowSelected = colorPalette.purple400; +export const formInputTextHighlight = colorPalette.purple200; +export const checkboxText = tableText; +export const checkboxToggleBackground = colorPalette.gray400; +export const checkboxBackgroundSelected = colorPalette.purple300; +export const checkboxBorderSelected = colorPalette.purple300; +export const checkboxShadowSelected = colorPalette.purple500; + +export const pillBackground = colorPalette.gray700; //settings background +export const pillBackgroundLight = colorPalette.gray900; +export const pillText = colorPalette.gray200; +export const pillTextHighlighted = colorPalette.purple200; +export const pillBorder = colorPalette.gray700; +export const pillBorderDark = pillBorder; +export const pillBackgroundSelected = colorPalette.purple600; +export const pillTextSelected = colorPalette.gray150; +export const pillBorderSelected = colorPalette.purple300; + +export const reportsRed = colorPalette.red300; +export const reportsBlue = colorPalette.blue400; +export const reportsLabel = pageText; diff --git a/packages/loot-core/src/server/main.ts b/packages/loot-core/src/server/main.ts index 7da1493925e..21c3b7420e8 100644 --- a/packages/loot-core/src/server/main.ts +++ b/packages/loot-core/src/server/main.ts @@ -1493,7 +1493,11 @@ handlers['load-global-prefs'] = async function () { documentDir: documentDir || getDefaultDocumentDir(), keyId: encryptKey && JSON.parse(encryptKey).id, theme: - theme === 'light' || theme === 'dark' || theme === 'auto' + theme === 'light' || + theme === 'dark' || + theme === 'auto' || + theme === 'development' || + theme === 'midnight' ? theme : 'light', }; diff --git a/packages/loot-core/src/types/prefs.d.ts b/packages/loot-core/src/types/prefs.d.ts index 251b6e5dd6a..f4a13c81d9d 100644 --- a/packages/loot-core/src/types/prefs.d.ts +++ b/packages/loot-core/src/types/prefs.d.ts @@ -57,7 +57,7 @@ export type LocalPrefs = Partial< } & Record<`flags.${FeatureFlag}`, boolean> >; -export type Theme = 'light' | 'dark' | 'auto'; +export type Theme = 'light' | 'dark' | 'auto' | 'midnight'; export type GlobalPrefs = Partial<{ floatingSidebar: boolean; maxMonths: number; diff --git a/upcoming-release-notes/2312.md b/upcoming-release-notes/2312.md new file mode 100644 index 00000000000..2f5f94ca8bf --- /dev/null +++ b/upcoming-release-notes/2312.md @@ -0,0 +1,6 @@ +--- +category: Enhancements +authors: [shall0pass] +--- + +Theme: Add Midnight theme