1
0
mirror of https://github.com/laurent22/joplin.git synced 2025-07-13 00:10:37 +02:00

Chore: Improve types for mobile and desktop themeStyle (#10297)

This commit is contained in:
Henry Heino
2024-04-11 00:35:20 -07:00
committed by GitHub
parent 55d25308f8
commit 346f49fa66
28 changed files with 408 additions and 378 deletions

View File

@ -1,4 +1,5 @@
const React = require('react'); const React = require('react');
import { CSSProperties } from 'react';
const { connect } = require('react-redux'); const { connect } = require('react-redux');
const { clipboard } = require('electron'); const { clipboard } = require('electron');
import ExtensionBadge from './ExtensionBadge'; import ExtensionBadge from './ExtensionBadge';
@ -46,7 +47,8 @@ class ClipperConfigScreenComponent extends React.Component {
public render() { public render() {
const theme = themeStyle(this.props.themeId); const theme = themeStyle(this.props.themeId);
const containerStyle = { ...theme.containerStyle, overflowY: 'scroll', const containerStyle: CSSProperties = { ...theme.containerStyle,
overflowY: 'scroll',
// padding: theme.configScreenPadding, // padding: theme.configScreenPadding,
backgroundColor: theme.backgroundColor3 }; backgroundColor: theme.backgroundColor3 };
@ -104,7 +106,8 @@ class ClipperConfigScreenComponent extends React.Component {
); );
} }
const apiTokenStyle = { ...theme.textStyle, color: theme.colorFaded, const apiTokenStyle: CSSProperties = { ...theme.textStyle,
color: theme.colorFaded,
wordBreak: 'break-all', wordBreak: 'break-all',
paddingTop: 10, paddingTop: 10,
paddingBottom: 10 }; paddingBottom: 10 };

View File

@ -3,10 +3,10 @@ import * as React from 'react';
import shim from '@joplin/lib/shim'; import shim from '@joplin/lib/shim';
import bridge from '../../../services/bridge'; import bridge from '../../../services/bridge';
import StyledLink from '../../style/StyledLink'; import StyledLink from '../../style/StyledLink';
import { ThemeStyle } from '@joplin/lib/theme';
interface Props { interface Props {
// eslint-disable-next-line @typescript-eslint/no-explicit-any -- Old code before rule was applied theme: ThemeStyle;
theme: any;
text: string; text: string;
} }
@ -19,7 +19,7 @@ const MacOSMissingPasswordHelpLink: React.FunctionComponent<Props> = props => {
const macInfoLink = ( const macInfoLink = (
<StyledLink href="#" <StyledLink href="#"
onClick={openMissingPasswordFAQ} onClick={openMissingPasswordFAQ}
style={props.theme.linkStyle} style={props.theme.urlStyle}
> >
{props.text} {props.text}
</StyledLink> </StyledLink>

View File

@ -35,8 +35,7 @@ interface Props {
const EncryptionConfigScreen = (props: Props) => { const EncryptionConfigScreen = (props: Props) => {
const { inputPasswords, onInputPasswordChange } = useInputPasswords(props.passwords); const { inputPasswords, onInputPasswordChange } = useInputPasswords(props.passwords);
// eslint-disable-next-line @typescript-eslint/no-explicit-any -- Old code before rule was applied const theme = useMemo(() => {
const theme: any = useMemo(() => {
return themeStyle(props.themeId); return themeStyle(props.themeId);
}, [props.themeId]); }, [props.themeId]);

View File

@ -1,7 +1,7 @@
import * as React from 'react'; import * as React from 'react';
import bridge from '../services/bridge'; import bridge from '../services/bridge';
import { _ } from '@joplin/lib/locale'; import { _ } from '@joplin/lib/locale';
import { themeStyle } from '@joplin/lib/theme'; import { ThemeStyle, themeStyle } from '@joplin/lib/theme';
const { createSelector } = require('reselect'); const { createSelector } = require('reselect');
interface Props { interface Props {
@ -17,8 +17,7 @@ const themeSelector = (_state: any, props: any) => themeStyle(props.themeId);
const styleSelector = createSelector( const styleSelector = createSelector(
themeSelector, themeSelector,
// eslint-disable-next-line @typescript-eslint/no-explicit-any -- Old code before rule was applied (theme: ThemeStyle) => {
(theme: any) => {
const output = { const output = {
root: { root: {
width: 220, width: 220,

View File

@ -1,8 +1,9 @@
import { ThemeStyle } from '@joplin/lib/theme';
const { buildStyle } = require('@joplin/lib/theme'); const { buildStyle } = require('@joplin/lib/theme');
export default function styles(themeId: number) { export default function styles(themeId: number) {
// eslint-disable-next-line @typescript-eslint/no-explicit-any -- Old code before rule was applied return buildStyle('KeymapConfigScreen', themeId, (theme: ThemeStyle) => {
return buildStyle('KeymapConfigScreen', themeId, (theme: any) => {
return { return {
container: { container: {
...theme.containerStyle, ...theme.containerStyle,

View File

@ -26,7 +26,7 @@ import shim from '@joplin/lib/shim';
import bridge from '../../services/bridge'; import bridge from '../../services/bridge';
import time from '@joplin/lib/time'; import time from '@joplin/lib/time';
import styled from 'styled-components'; import styled from 'styled-components';
import { themeStyle } from '@joplin/lib/theme'; import { themeStyle, ThemeStyle } from '@joplin/lib/theme';
import validateLayout from '../ResizableLayout/utils/validateLayout'; import validateLayout from '../ResizableLayout/utils/validateLayout';
import iterateItems from '../ResizableLayout/utils/iterateItems'; import iterateItems from '../ResizableLayout/utils/iterateItems';
import removeItem from '../ResizableLayout/utils/removeItem'; import removeItem from '../ResizableLayout/utils/removeItem';
@ -572,7 +572,7 @@ class MainScreenComponent extends React.Component<Props, State> {
} }
// eslint-disable-next-line @typescript-eslint/no-explicit-any -- Old code before rule was applied // eslint-disable-next-line @typescript-eslint/no-explicit-any -- Old code before rule was applied
public renderNotification(theme: any, styles: any) { public renderNotification(theme: ThemeStyle, styles: any) {
if (!this.messageBoxVisible()) return null; if (!this.messageBoxVisible()) return null;
const onViewStatusScreen = () => { const onViewStatusScreen = () => {

View File

@ -2,8 +2,9 @@ import { PluginStates } from '@joplin/lib/services/plugins/reducer';
import * as React from 'react'; import * as React from 'react';
import NoteListUtils from './utils/NoteListUtils'; import NoteListUtils from './utils/NoteListUtils';
import { Dispatch } from 'redux'; import { Dispatch } from 'redux';
import { ThemeStyle } from '@joplin/lib/theme';
const { buildStyle } = require('@joplin/lib/theme'); import { buildStyle } from '@joplin/lib/theme';
const bridge = require('@electron/remote').require('./bridge').default; const bridge = require('@electron/remote').require('./bridge').default;
interface MultiNoteActionsProps { interface MultiNoteActionsProps {
@ -19,8 +20,7 @@ interface MultiNoteActionsProps {
} }
function styles_(props: MultiNoteActionsProps) { function styles_(props: MultiNoteActionsProps) {
// eslint-disable-next-line @typescript-eslint/no-explicit-any -- Old code before rule was applied return buildStyle('MultiNoteActions', props.themeId, (theme: ThemeStyle) => {
return buildStyle('MultiNoteActions', props.themeId, (theme: any) => {
return { return {
root: { root: {
display: 'inline-flex', display: 'inline-flex',

View File

@ -1,11 +1,10 @@
import { ThemeAppearance } from '@joplin/lib/themes/type'; import { ThemeAppearance } from '@joplin/lib/themes/type';
import { NoteBodyEditorProps } from '../../../utils/types'; import { NoteBodyEditorProps } from '../../../utils/types';
const { buildStyle } = require('@joplin/lib/theme'); import { buildStyle } from '@joplin/lib/theme';
export default function styles(props: NoteBodyEditorProps) { export default function styles(props: NoteBodyEditorProps) {
const leftExtraToolbarContainerWidth = props.watchedNoteFiles.length > 0 ? 120 : 80; const leftExtraToolbarContainerWidth = props.watchedNoteFiles.length > 0 ? 120 : 80;
// eslint-disable-next-line @typescript-eslint/no-explicit-any -- Old code before rule was applied return buildStyle(['TinyMCE', props.style.width, props.style.height, leftExtraToolbarContainerWidth], props.themeId, theme => {
return buildStyle(['TinyMCE', props.style.width, props.style.height, leftExtraToolbarContainerWidth], props.themeId, (theme: any) => {
const extraToolbarContainer = { const extraToolbarContainer = {
boxSizing: 'content-box', boxSizing: 'content-box',
backgroundColor: theme.backgroundColor3, backgroundColor: theme.backgroundColor3,

View File

@ -43,8 +43,7 @@ interface Props {
} }
function styles_(props: Props) { function styles_(props: Props) {
// eslint-disable-next-line @typescript-eslint/no-explicit-any -- Old code before rule was applied return buildStyle(['NoteEditorTitleBar'], props.themeId, theme => {
return buildStyle(['NoteEditorTitleBar'], props.themeId, (theme: any) => {
return { return {
titleInput: { titleInput: {
flex: 1, flex: 1,

View File

@ -1,10 +1,9 @@
import { NoteEditorProps } from '../utils/types'; import { NoteEditorProps } from '../utils/types';
const { buildStyle } = require('@joplin/lib/theme'); import { buildStyle } from '@joplin/lib/theme';
export default function styles(props: NoteEditorProps) { export default function styles(props: NoteEditorProps) {
// eslint-disable-next-line @typescript-eslint/no-explicit-any -- Old code before rule was applied return buildStyle(['NoteEditor'], props.themeId, theme => {
return buildStyle(['NoteEditor'], props.themeId, (theme: any) => {
return { return {
root: { root: {
boxSizing: 'border-box', boxSizing: 'border-box',

View File

@ -353,7 +353,7 @@ class NotePropertiesDialog extends React.Component<Props, State> {
const ll = this.latLongFromLocation(value); const ll = this.latLongFromLocation(value);
url = Note.geoLocationUrlFromLatLong(ll.latitude, ll.longitude); url = Note.geoLocationUrlFromLatLong(ll.latitude, ll.longitude);
} }
const urlStyle = { ...theme.urlStyle, maxWidth: '180px', overflow: 'hidden', whiteSpace: 'nowrap', textOverflow: 'ellipsis' }; const urlStyle: React.CSSProperties = { ...theme.urlStyle, maxWidth: '180px', overflow: 'hidden', whiteSpace: 'nowrap', textOverflow: 'ellipsis' };
controlComp = ( controlComp = (
<a href="#" onClick={() => bridge().openExternal(url)} style={urlStyle}> <a href="#" onClick={() => bridge().openExternal(url)} style={urlStyle}>
{displayedValue} {displayedValue}

View File

@ -5,7 +5,7 @@ import { utils as pluginUtils } from '@joplin/lib/services/plugins/reducer';
import ToolbarButtonUtils, { ToolbarButtonInfo } from '@joplin/lib/services/commands/ToolbarButtonUtils'; import ToolbarButtonUtils, { ToolbarButtonInfo } from '@joplin/lib/services/commands/ToolbarButtonUtils';
import stateToWhenClauseContext from '../../services/commands/stateToWhenClauseContext'; import stateToWhenClauseContext from '../../services/commands/stateToWhenClauseContext';
const { connect } = require('react-redux'); const { connect } = require('react-redux');
const { buildStyle } = require('@joplin/lib/theme'); import { buildStyle } from '@joplin/lib/theme';
interface NoteToolbarProps { interface NoteToolbarProps {
themeId: number; themeId: number;
@ -16,8 +16,7 @@ interface NoteToolbarProps {
} }
function styles_(props: NoteToolbarProps) { function styles_(props: NoteToolbarProps) {
// eslint-disable-next-line @typescript-eslint/no-explicit-any -- Old code before rule was applied return buildStyle('NoteToolbar', props.themeId, theme => {
return buildStyle('NoteToolbar', props.themeId, (theme: any) => {
return { return {
root: { root: {
...props.style, ...props.style,

View File

@ -28,8 +28,7 @@ interface Props {
} }
function styles_(props: Props) { function styles_(props: Props) {
// eslint-disable-next-line @typescript-eslint/no-explicit-any -- Old code before rule was applied return buildStyle('ShareNoteDialog', props.themeId, theme => {
return buildStyle('ShareNoteDialog', props.themeId, (theme: any) => {
return { return {
root: { root: {
minWidth: 500, minWidth: 500,

View File

@ -24,13 +24,12 @@ import PerFolderSortOrderService from '../../services/sortOrder/PerFolderSortOrd
import { getFolderCallbackUrl, getTagCallbackUrl } from '@joplin/lib/callbackUrlUtils'; import { getFolderCallbackUrl, getTagCallbackUrl } from '@joplin/lib/callbackUrlUtils';
import FolderIconBox from '../FolderIconBox'; import FolderIconBox from '../FolderIconBox';
import onFolderDrop from '@joplin/lib/models/utils/onFolderDrop'; import onFolderDrop from '@joplin/lib/models/utils/onFolderDrop';
import { Theme } from '@joplin/lib/themes/type';
import { RuntimeProps } from './commands/focusElementSideBar'; import { RuntimeProps } from './commands/focusElementSideBar';
const { connect } = require('react-redux'); const { connect } = require('react-redux');
import { renderFolders, renderTags } from '@joplin/lib/components/shared/side-menu-shared'; import { renderFolders, renderTags } from '@joplin/lib/components/shared/side-menu-shared';
import { getTrashFolderIcon, getTrashFolderId } from '@joplin/lib/services/trash'; import { getTrashFolderIcon, getTrashFolderId } from '@joplin/lib/services/trash';
import { focus } from '@joplin/lib/utils/focusHandler'; import { focus } from '@joplin/lib/utils/focusHandler';
const { themeStyle } = require('@joplin/lib/theme'); import { ThemeStyle, themeStyle } from '@joplin/lib/theme';
const bridge = require('@electron/remote').require('./bridge').default; const bridge = require('@electron/remote').require('./bridge').default;
const Menu = bridge().Menu; const Menu = bridge().Menu;
const MenuItem = bridge().MenuItem; const MenuItem = bridge().MenuItem;
@ -505,10 +504,10 @@ const SidebarComponent = (props: Props) => {
return count ? <StyledNoteCount className="note-count-label">{count}</StyledNoteCount> : null; return count ? <StyledNoteCount className="note-count-label">{count}</StyledNoteCount> : null;
}; };
// eslint-disable-next-line @typescript-eslint/no-explicit-any -- Old code before rule was applied const renderExpandIcon = (theme: ThemeStyle, isExpanded: boolean, isVisible: boolean) => {
const renderExpandIcon = (theme: any, isExpanded: boolean, isVisible: boolean) => { const style: React.CSSProperties = {
// eslint-disable-next-line @typescript-eslint/no-explicit-any -- Old code before rule was applied width: 16, maxWidth: 16, opacity: 0.5, fontSize: Math.round(theme.toolbarIconSize * 0.8), display: 'flex', justifyContent: 'center',
const style: any = { width: 16, maxWidth: 16, opacity: 0.5, fontSize: Math.round(theme.toolbarIconSize * 0.8), display: 'flex', justifyContent: 'center' }; };
if (!isVisible) style.visibility = 'hidden'; if (!isVisible) style.visibility = 'hidden';
return <i className={isExpanded ? 'fas fa-caret-down' : 'fas fa-caret-right'} style={style}></i>; return <i className={isExpanded ? 'fas fa-caret-down' : 'fas fa-caret-right'} style={style}></i>;
}; };
@ -527,7 +526,7 @@ const SidebarComponent = (props: Props) => {
menu.popup({ window: bridge().window() }); menu.popup({ window: bridge().window() });
}, []); }, []);
const renderAllNotesItem = (theme: Theme, selected: boolean) => { const renderAllNotesItem = (theme: ThemeStyle, selected: boolean) => {
return ( return (
<StyledListItem key="allNotesHeader" selected={selected} className={'list-item-container list-item-depth-0 all-notes'} isSpecialItem={true}> <StyledListItem key="allNotesHeader" selected={selected} className={'list-item-container list-item-depth-0 all-notes'} isSpecialItem={true}>
<StyledExpandLink>{renderExpandIcon(theme, false, false)}</StyledExpandLink> <StyledExpandLink>{renderExpandIcon(theme, false, false)}</StyledExpandLink>

View File

@ -1,9 +1,8 @@
import { Props, Value } from '../ToggleEditorsButton'; import { Props, Value } from '../ToggleEditorsButton';
const { buildStyle } = require('@joplin/lib/theme'); import { buildStyle } from '@joplin/lib/theme';
export default function styles(props: Props) { export default function styles(props: Props) {
// eslint-disable-next-line @typescript-eslint/no-explicit-any -- Old code before rule was applied return buildStyle(['ToggleEditorsButton', props.value], props.themeId, theme => {
return buildStyle(['ToggleEditorsButton', props.value], props.themeId, (theme: any) => {
const iconSize = 15; const iconSize = 15;
const mdIconWidth = iconSize * 1.25; const mdIconWidth = iconSize * 1.25;
const buttonHeight = theme.toolbarHeight - 7; const buttonHeight = theme.toolbarHeight - 7;

View File

@ -1,9 +1,10 @@
import { ThemeStyle } from '@joplin/lib/theme';
const styled = require('styled-components').default; const styled = require('styled-components').default;
const { css } = require('styled-components'); const { css } = require('styled-components');
interface RootProps { interface RootProps {
// eslint-disable-next-line @typescript-eslint/no-explicit-any -- Old code before rule was applied readonly theme: ThemeStyle;
readonly theme: any;
readonly disabled: boolean; readonly disabled: boolean;
readonly hasTitle: boolean; readonly hasTitle: boolean;
} }
@ -34,8 +35,7 @@ export const StyledRoot = styled.a<RootProps>`
`; `;
interface IconProps { interface IconProps {
// eslint-disable-next-line @typescript-eslint/no-explicit-any -- Old code before rule was applied readonly theme: ThemeStyle;
readonly theme: any;
readonly title: string; readonly title: string;
} }

View File

@ -1,5 +1,5 @@
import * as React from 'react'; import * as React from 'react';
import { themeStyle } from '@joplin/lib/theme'; import { themeStyle } from './global-style';
import { _ } from '@joplin/lib/locale'; import { _ } from '@joplin/lib/locale';
const { Modal, View, Button, Text, StyleSheet } = require('react-native'); const { Modal, View, Button, Text, StyleSheet } = require('react-native');
import time from '@joplin/lib/time'; import time from '@joplin/lib/time';

View File

@ -1,6 +1,6 @@
const React = require('react'); const React = require('react');
import { useMemo } from 'react'; import { useMemo } from 'react';
import { themeStyle } from '@joplin/lib/theme'; import { themeStyle } from './global-style';
import { TextInput, TextInputProps, StyleSheet } from 'react-native'; import { TextInput, TextInputProps, StyleSheet } from 'react-native';
interface Props extends TextInputProps { interface Props extends TextInputProps {
@ -9,7 +9,7 @@ interface Props extends TextInputProps {
export default (props: Props) => { export default (props: Props) => {
const theme = themeStyle(props.themeId); const theme = themeStyle(props.themeId);
const finalProps = { ...props }; const finalProps: Props = { ...props };
if (!('placeholderTextColor' in finalProps)) finalProps.placeholderTextColor = theme.colorFaded; if (!('placeholderTextColor' in finalProps)) finalProps.placeholderTextColor = theme.colorFaded;
if (!('underlineColorAndroid' in finalProps)) finalProps.underlineColorAndroid = theme.dividerColor; if (!('underlineColorAndroid' in finalProps)) finalProps.underlineColorAndroid = theme.dividerColor;

View File

@ -1,6 +1,7 @@
const Setting = require('@joplin/lib/models/Setting').default; import Setting from '@joplin/lib/models/Setting';
const { Platform } = require('react-native'); import { Platform, TextStyle, ViewStyle } from 'react-native';
const { themeById } = require('@joplin/lib/theme'); import { themeById } from '@joplin/lib/theme';
import { Theme as BaseTheme } from '@joplin/lib/themes/type';
const baseStyle = { const baseStyle = {
appearance: 'light', appearance: 'light',
@ -14,74 +15,95 @@ const baseStyle = {
lineHeight: '1.6em', lineHeight: '1.6em',
}; };
// eslint-disable-next-line @typescript-eslint/no-explicit-any -- Old code before rule was applied export type ThemeStyle = BaseTheme & typeof baseStyle & {
const themeCache_: any = {}; fontSize: number;
fontSizeSmaller: number;
marginRight: number;
marginLeft: number;
marginTop: number;
marginBottom: number;
icon: TextStyle;
lineInput: ViewStyle;
buttonRow: ViewStyle;
normalText: TextStyle;
urlText: TextStyle;
headerStyle: TextStyle;
headerWrapperStyle: ViewStyle;
keyboardAppearance: 'light'|'dark';
};
// eslint-disable-next-line @typescript-eslint/no-explicit-any -- Old code before rule was applied const themeCache_: Record<string, ThemeStyle> = {};
function addExtraStyles(style: any) {
style.marginRight = style.margin;
style.marginLeft = style.margin;
style.marginTop = style.margin;
style.marginBottom = style.margin;
style.icon = { function extraStyles(theme: BaseTheme) {
color: style.color, const icon: TextStyle = {
color: theme.color,
fontSize: 30, fontSize: 30,
}; };
style.lineInput = { const lineInput: TextStyle = {
color: style.color, color: theme.color,
backgroundColor: style.backgroundColor, backgroundColor: theme.backgroundColor,
borderBottomWidth: 1, borderBottomWidth: 1,
borderColor: style.dividerColor, borderColor: theme.dividerColor,
paddingBottom: 0, paddingBottom: 0,
}; };
if (Platform.OS === 'ios') { if (Platform.OS === 'ios') {
delete style.lineInput.borderBottomWidth; delete lineInput.borderBottomWidth;
delete style.lineInput.borderColor; delete lineInput.borderColor;
} }
style.buttonRow = { const buttonRow: ViewStyle = {
flexDirection: 'row', flexDirection: 'row',
borderTopWidth: 1, borderTopWidth: 1,
borderTopColor: style.dividerColor, borderTopColor: theme.dividerColor,
paddingTop: 10, paddingTop: 10,
}; };
style.normalText = { const fontSize = baseStyle.fontSize;
color: style.color, const normalText: TextStyle = {
fontSize: style.fontSize, color: theme.color,
fontSize: fontSize,
}; };
style.urlText = { const urlText: TextStyle = {
color: style.urlColor, color: theme.urlColor,
fontSize: style.fontSize, fontSize,
}; };
style.headerStyle = { const headerStyle: TextStyle = {
color: style.color, color: theme.color,
fontSize: style.fontSize * 1.2, fontSize: fontSize * 1.2,
fontWeight: 'bold', fontWeight: 'bold',
}; };
style.headerWrapperStyle = { const headerWrapperStyle: TextStyle = {
backgroundColor: style.headerBackgroundColor, backgroundColor: theme.headerBackgroundColor,
}; };
style.keyboardAppearance = style.appearance; return {
marginRight: baseStyle.margin,
marginLeft: baseStyle.margin,
marginTop: baseStyle.margin,
marginBottom: baseStyle.margin,
style.color5 = style.backgroundColor4; icon,
style.backgroundColor5 = style.color4; lineInput,
buttonRow,
normalText,
urlText,
headerStyle,
headerWrapperStyle,
return style; keyboardAppearance: theme.appearance,
color5: theme.color5 ?? theme.backgroundColor4,
backgroundColor5: theme.backgroundColor5 ?? theme.color4,
};
} }
// eslint-disable-next-line @typescript-eslint/no-explicit-any -- Old code before rule was applied function editorFont(fontId: number) {
function editorFont(fontId: any) {
// IMPORTANT: The font mapping must match the one in Setting.js // IMPORTANT: The font mapping must match the one in Setting.js
// eslint-disable-next-line @typescript-eslint/no-explicit-any -- Old code before rule was applied const fonts: Record<number, string|null> = {
const fonts: any = {
[Setting.FONT_DEFAULT]: null, [Setting.FONT_DEFAULT]: null,
[Setting.FONT_MENLO]: 'Menlo', [Setting.FONT_MENLO]: 'Menlo',
[Setting.FONT_COURIER_NEW]: 'Courier New', [Setting.FONT_COURIER_NEW]: 'Courier New',
@ -104,8 +126,13 @@ function themeStyle(theme: number) {
const cacheKey = [theme].join('-'); const cacheKey = [theme].join('-');
if (themeCache_[cacheKey]) return themeCache_[cacheKey]; if (themeCache_[cacheKey]) return themeCache_[cacheKey];
const output = { ...baseStyle, ...themeById(theme) }; const baseTheme = themeById(theme);
themeCache_[cacheKey] = addExtraStyles(output); const output: ThemeStyle = {
...baseStyle,
...baseTheme,
...extraStyles(baseTheme),
};
themeCache_[cacheKey] = output;
return themeCache_[cacheKey]; return themeCache_[cacheKey];
} }

View File

@ -135,7 +135,7 @@ const SettingComponent: React.FunctionComponent<Props> = props => {
autoCorrect={false} autoCorrect={false}
autoComplete="off" autoComplete="off"
selectionColor={theme.textSelectionColor} selectionColor={theme.textSelectionColor}
keyboardAppearance={theme.settingKeyboardAppearance} keyboardAppearance={theme.keyboardAppearance}
autoCapitalize="none" autoCapitalize="none"
key="control" key="control"
style={styleSheet.settingControl} style={styleSheet.settingControl}

View File

@ -41,8 +41,7 @@ const EncryptionConfigScreen = (props: Props) => {
const nonExistingMasterKeyIds = props.notLoadedMasterKeys.slice(); const nonExistingMasterKeyIds = props.notLoadedMasterKeys.slice();
// eslint-disable-next-line @typescript-eslint/no-explicit-any -- Old code before rule was applied const theme = useMemo(() => {
const theme: any = useMemo(() => {
return themeStyle(props.themeId); return themeStyle(props.themeId);
}, [props.themeId]); }, [props.themeId]);

View File

@ -7,7 +7,7 @@ import Folder from '@joplin/lib/models/Folder';
import Synchronizer from '@joplin/lib/Synchronizer'; import Synchronizer from '@joplin/lib/Synchronizer';
import NavService from '@joplin/lib/services/NavService'; import NavService from '@joplin/lib/services/NavService';
import { _ } from '@joplin/lib/locale'; import { _ } from '@joplin/lib/locale';
import { themeStyle } from './global-style'; import { ThemeStyle, themeStyle } from './global-style';
import { renderFolders } from '@joplin/lib/components/shared/side-menu-shared'; import { renderFolders } from '@joplin/lib/components/shared/side-menu-shared';
import { FolderEntity, FolderIcon, FolderIconType } from '@joplin/lib/services/database/types'; import { FolderEntity, FolderIcon, FolderIconType } from '@joplin/lib/services/database/types';
import { AppState } from '../utils/types'; import { AppState } from '../utils/types';
@ -376,8 +376,7 @@ const SideMenuContentComponent = (props: Props) => {
if (actionDone === 'auth') props.dispatch({ type: 'SIDE_MENU_CLOSE' }); if (actionDone === 'auth') props.dispatch({ type: 'SIDE_MENU_CLOSE' });
}, [performSync, props.dispatch]); }, [performSync, props.dispatch]);
// eslint-disable-next-line @typescript-eslint/no-explicit-any -- Old code before rule was applied const renderFolderIcon = (folderId: string, theme: ThemeStyle, folderIcon: FolderIcon) => {
const renderFolderIcon = (folderId: string, theme: any, folderIcon: FolderIcon) => {
if (!folderIcon) { if (!folderIcon) {
if (folderId === getTrashFolderId()) { if (folderId === getTrashFolderId()) {
folderIcon = getTrashFolderIcon(FolderIconType.Emoji); folderIcon = getTrashFolderIcon(FolderIconType.Emoji);

View File

@ -126,7 +126,7 @@ export enum EditorKeymap {
export interface EditorTheme extends Theme { export interface EditorTheme extends Theme {
fontFamily: string; fontFamily: string;
fontSize?: number; fontSize?: number;
fontSizeUnits?: number; fontSizeUnits?: string;
isDesktop?: boolean; isDesktop?: boolean;
monospaceFont?: string; monospaceFont?: string;
contentMaxWidth?: number; contentMaxWidth?: number;

View File

@ -55,6 +55,10 @@ const input: Theme = {
codeMirrorTheme: 'default', codeMirrorTheme: 'default',
codeThemeCss: 'atom-one-light.css', codeThemeCss: 'atom-one-light.css',
headerBackgroundColor: '#ffffff',
textSelectionColor: '#a0a0ff',
colorBright2: '#ffffff',
}; };
const expected = ` const expected = `
@ -76,6 +80,7 @@ const expected = `
--joplin-color2: #ffffff; --joplin-color2: #ffffff;
--joplin-color3: #738598; --joplin-color3: #738598;
--joplin-color4: #2D6BDC; --joplin-color4: #2D6BDC;
--joplin-color-bright2: #ffffff;
--joplin-color-correct: green; --joplin-color-correct: green;
--joplin-color-error: red; --joplin-color-error: red;
--joplin-color-error2: #ff6c6c; --joplin-color-error2: #ff6c6c;
@ -85,6 +90,7 @@ const expected = `
--joplin-color-warn3: #ff7626; --joplin-color-warn3: #ff7626;
--joplin-color-warn-url: #155BDA; --joplin-color-warn-url: #155BDA;
--joplin-divider-color: #dddddd; --joplin-divider-color: #dddddd;
--joplin-header-background-color: #ffffff;
--joplin-odd-background-color: #eeeeee; --joplin-odd-background-color: #eeeeee;
--joplin-raised-background-color: #e5e5e5; --joplin-raised-background-color: #e5e5e5;
--joplin-raised-color: #222222; --joplin-raised-color: #222222;
@ -93,6 +99,7 @@ const expected = `
--joplin-selected-color: #e5e5e5; --joplin-selected-color: #e5e5e5;
--joplin-selected-color2: #131313; --joplin-selected-color2: #131313;
--joplin-table-background-color: rgb(247, 247, 247); --joplin-table-background-color: rgb(247, 247, 247);
--joplin-text-selection-color: #a0a0ff;
--joplin-url-color: #155BDA; --joplin-url-color: #155BDA;
--joplin-warning-background-color: #FFD08D; --joplin-warning-background-color: #FFD08D;
}`; }`;

View File

@ -7,11 +7,11 @@ import theme_nord from './themes/nord';
import theme_aritimDark from './themes/aritimDark'; import theme_aritimDark from './themes/aritimDark';
import theme_oledDark from './themes/oledDark'; import theme_oledDark from './themes/oledDark';
import Setting from './models/Setting'; import Setting from './models/Setting';
import { Theme, ThemeAppearance } from './themes/type';
const Color = require('color'); const Color = require('color');
// eslint-disable-next-line @typescript-eslint/no-explicit-any -- Old code before rule was applied const themes: Record<number, Theme> = {
const themes: any = {
[Setting.THEME_LIGHT]: theme_light, [Setting.THEME_LIGHT]: theme_light,
[Setting.THEME_DARK]: theme_dark, [Setting.THEME_DARK]: theme_dark,
[Setting.THEME_DRACULA]: theme_dracula, [Setting.THEME_DRACULA]: theme_dracula,
@ -22,31 +22,21 @@ const themes: any = {
[Setting.THEME_OLED_DARK]: theme_oledDark, [Setting.THEME_OLED_DARK]: theme_oledDark,
}; };
export function themeById(themeId: string) { export function themeById(themeId: number) {
if (!themes[themeId]) throw new Error(`Invalid theme ID: ${themeId}`); if (!themes[themeId]) throw new Error(`Invalid theme ID: ${themeId}`);
const output = { ...themes[themeId] }; return { ...themes[themeId] };
if (!output.headerBackgroundColor) {
output.headerBackgroundColor = output.appearance === 'light' ? '#F0F0F0' : '#2D3136';
} }
if (!output.textSelectionColor) { const literal = <T extends string> (str: T): T => str;
output.textSelectionColor = output.appearance === 'light' ? '#0096FF' : '#00AEFF';
}
if (!output.colorBright2) {
output.colorBright2 = output.appearance === 'light' ? '#ffffff' : '#ffffff';
}
return output;
}
// globalStyle should be used for properties that do not change across themes // globalStyle should be used for properties that do not change across themes
// i.e. should not be used for colors // i.e. should not be used for colors
// eslint-disable-next-line @typescript-eslint/no-explicit-any -- Old code before rule was applied const globalStyle = (() => {
const globalStyle: any = {
fontFamily: 'Roboto', // 'sans-serif', const margin = 15; // No text and no interactive component should be within this margin
margin: 15, // No text and no interactive component should be within this margin const fontFamily = 'Roboto'; // 'sans-serif',
return {
fontFamily: fontFamily,
itemMarginTop: 10, itemMarginTop: 10,
itemMarginBottom: 10, itemMarginBottom: 10,
disabledOpacity: 0.3, disabledOpacity: 0.3,
@ -58,47 +48,40 @@ const globalStyle: any = {
headerButtonHPadding: 6, headerButtonHPadding: 6,
toolbarHeight: 26, toolbarHeight: 26,
toolbarPadding: 6, toolbarPadding: 6,
appearance: 'light', appearance: ThemeAppearance.Light,
mainPadding: 12, mainPadding: 12,
topRowHeight: 50, topRowHeight: 50,
editorPaddingLeft: 8, editorPaddingLeft: 8,
};
globalStyle.marginRight = globalStyle.margin; margin: margin,
globalStyle.marginLeft = globalStyle.margin; marginRight: margin,
globalStyle.marginTop = globalStyle.margin; marginLeft: margin,
globalStyle.marginBottom = globalStyle.margin; marginTop: margin,
marginBottom: margin,
globalStyle.icon = { icon: { fontSize: 30 },
fontSize: 30, lineInput: {
}; fontFamily,
globalStyle.lineInput = {
fontFamily: globalStyle.fontFamily,
maxHeight: 22, maxHeight: 22,
height: 22, height: 22,
paddingLeft: 5, paddingLeft: 5,
}; },
headerStyle: {
globalStyle.headerStyle = { fontFamily,
fontFamily: globalStyle.fontFamily, },
}; inputStyle: {
globalStyle.inputStyle = {
border: '1px solid', border: '1px solid',
height: 24, height: 24,
maxHeight: 24, maxHeight: 24,
paddingLeft: 5, paddingLeft: 5,
paddingRight: 5, paddingRight: 5,
boxSizing: 'border-box', boxSizing: literal('border-box'),
}; },
containerStyle: {
globalStyle.containerStyle = { overflow: literal('auto'),
overflow: 'auto', overflowY: literal('auto'),
overflowY: 'auto', },
}; buttonStyle: {
globalStyle.buttonStyle = {
// marginRight: 10, // marginRight: 10,
border: '1px solid', border: '1px solid',
minHeight: 26, minHeight: 26,
@ -109,253 +92,260 @@ globalStyle.buttonStyle = {
paddingTop: 6, paddingTop: 6,
paddingBottom: 6, paddingBottom: 6,
// boxShadow: '0px 1px 1px rgba(0,0,0,0.3)', // boxShadow: '0px 1px 1px rgba(0,0,0,0.3)',
fontSize: globalStyle.fontSize,
borderRadius: 4, borderRadius: 4,
},
}; };
})();
// eslint-disable-next-line @typescript-eslint/no-explicit-any -- Old code before rule was applied export function extraStyles(theme: Theme) {
export function addExtraStyles(style: any) {
const zoomRatio = 1; const zoomRatio = 1;
// eslint-disable-next-line @typescript-eslint/no-explicit-any -- Old code before rule was applied const baseFontSize = Math.round(12 * zoomRatio);
const fontSizes: any = { const fontSizes = {
fontSize: Math.round(12 * zoomRatio), fontSize: baseFontSize,
toolbarIconSize: 18, toolbarIconSize: 18,
noteViewerFontSize: Math.round(baseFontSize * 1.25),
}; };
fontSizes.noteViewerFontSize = Math.round(fontSizes.fontSize * 1.25); const bgColor4 = theme.backgroundColor4;
const borderColor4: string = Color(theme.color).alpha(0.3);
const iconColor = Color(theme.color).alpha(0.8);
style.zoomRatio = zoomRatio; const backgroundColor5 = theme.backgroundColor5 ?? theme.color4;
const backgroundColorHover5 = Color(backgroundColor5).darken(0.2).hex();
const backgroundColorActive5 = Color(backgroundColor5).darken(0.4).hex();
style = { ...fontSizes, ...style }; const inputStyle = {
...globalStyle.inputStyle,
style.selectedDividerColor = Color(style.dividerColor).darken(0.2).hex(); color: theme.color,
style.iconColor = Color(style.color).alpha(0.8); backgroundColor: theme.backgroundColor,
borderColor: theme.dividerColor,
style.colorFaded2 = Color(style.color2).alpha(0.5).rgb();
style.colorHover2 = Color(style.color2).alpha(0.7).rgb();
style.colorActive2 = Color(style.color2).alpha(0.9).rgb();
style.backgroundColorHoverDim3 = Color(style.backgroundColorHover3).alpha(0.3).rgb();
style.backgroundColorActive3 = Color(style.backgroundColorHover3).alpha(0.5).rgb();
const bgColor4 = style.backgroundColor4;
style.backgroundColorHover2 = Color(style.selectedColor2).alpha(0.4).rgb();
style.backgroundColorHover4 = Color(style.backgroundColorHover3).alpha(0.3).rgb();
style.backgroundColorActive4 = Color(style.backgroundColorHover3).alpha(0.8).rgb();
style.borderColor4 = Color(style.color).alpha(0.3);
style.backgroundColor4 = bgColor4;
style.color5 = bgColor4;
style.backgroundColor5 = style.color4;
style.backgroundColorHover5 = Color(style.backgroundColor5).darken(0.2).hex();
style.backgroundColorActive5 = Color(style.backgroundColor5).darken(0.4).hex();
style.configScreenPadding = style.mainPadding * 2;
style.noteListHeaderHeight = 26;
style.noteListHeaderBorderPadding = 4;
style.icon = {
...style.icon,
color: style.color,
}; };
style.lineInput = { const containerStyle = {
...style.lineInput, ...globalStyle.containerStyle,
color: style.color, color: theme.color,
backgroundColor: style.backgroundColor, backgroundColor: theme.backgroundColor,
}; };
style.headerStyle = { const buttonStyle = {
...style.headerStyle, ...globalStyle.buttonStyle,
color: style.color, color: theme.color4,
backgroundColor: style.backgroundColor, backgroundColor: theme.backgroundColor4,
}; borderColor: borderColor4,
userSelect: literal('none'),
style.inputStyle = {
...style.inputStyle,
color: style.color,
backgroundColor: style.backgroundColor,
borderColor: style.dividerColor,
};
style.containerStyle = {
...style.containerStyle,
color: style.color,
backgroundColor: style.backgroundColor,
};
style.buttonStyle = {
...style.buttonStyle,
color: style.color4,
backgroundColor: style.backgroundColor4,
borderColor: style.borderColor4,
userSelect: 'none',
// cursor: 'pointer', // cursor: 'pointer',
}; };
style.tagStyle = { const tagStyle = {
fontSize: style.fontSize, fontSize: baseFontSize,
fontFamily: style.fontFamily, fontFamily: globalStyle.fontFamily,
paddingTop: 4, paddingTop: 4,
paddingBottom: 4, paddingBottom: 4,
paddingRight: 10, paddingRight: 10,
paddingLeft: 10, paddingLeft: 10,
backgroundColor: style.backgroundColor3, backgroundColor: theme.backgroundColor3,
color: style.color3, color: theme.color3,
display: 'flex', display: literal('flex'),
alignItems: 'center', alignItems: literal('center'),
justifyContent: 'center', justifyContent: literal('center'),
marginRight: 8, marginRight: 8,
borderRadius: 100, borderRadius: 100,
borderWidth: 0, borderWidth: 0,
}; };
style.toolbarStyle = { const toolbarStyle = {
height: style.toolbarHeight, height: globalStyle.toolbarHeight,
minWidth: style.toolbarHeight, minWidth: globalStyle.toolbarHeight,
display: 'flex', display: literal('flex'),
alignItems: 'center', alignItems: literal('center'),
paddingLeft: style.headerButtonHPadding, paddingLeft: globalStyle.headerButtonHPadding,
paddingRight: style.headerButtonHPadding, paddingRight: globalStyle.headerButtonHPadding,
textDecoration: 'none', textDecoration: literal('none'),
fontFamily: style.fontFamily,
fontSize: style.fontSize,
boxSizing: 'border-box',
cursor: 'default',
justifyContent: 'center',
color: style.color,
whiteSpace: 'nowrap',
};
style.textStyle = {
fontFamily: globalStyle.fontFamily, fontFamily: globalStyle.fontFamily,
fontSize: style.fontSize, fontSize: baseFontSize,
boxSizing: literal('border-box'),
cursor: literal('default'),
justifyContent: literal('center'),
color: theme.color,
whiteSpace: literal('nowrap'),
};
const textStyle = {
fontFamily: globalStyle.fontFamily,
fontSize: baseFontSize,
lineHeight: '1.6em', lineHeight: '1.6em',
color: style.color, color: theme.color,
}; };
style.clickableTextStyle = { ...style.textStyle, userSelect: 'none' }; const textStyle2 = {
...textStyle,
style.textStyle2 = { ...style.textStyle, color: theme.color2,
color: style.color2,
}; };
style.textStyleMinor = { ...style.textStyle, const textStyleMinor = { ...textStyle,
color: style.colorFaded, color: theme.colorFaded,
fontSize: style.fontSize * 0.8, fontSize: baseFontSize * 0.8,
}; };
style.urlStyle = { ...style.textStyle, const urlStyle = {
textDecoration: 'underline', ...textStyle,
color: style.urlColor, textDecoration: literal('underline'),
color: theme.urlColor,
}; };
style.h1Style = { const h1Style = {
...style.textStyle, ...textStyle,
color: style.color, color: theme.color,
fontSize: style.textStyle.fontSize * 1.5, fontSize: textStyle.fontSize * 1.5,
fontWeight: 'bold', fontWeight: literal('bold'),
}; };
style.h2Style = { const h2Style = {
...style.textStyle, ...textStyle,
color: style.color, color: theme.color,
fontSize: style.textStyle.fontSize * 1.3, fontSize: textStyle.fontSize * 1.3,
fontWeight: 'bold', fontWeight: literal('bold'),
}; };
style.dialogModalLayer = { return {
zoomRatio,
...fontSizes,
selectedDividerColor: Color(theme.dividerColor).darken(0.2).hex(),
iconColor,
colorFaded2: Color(theme.color2).alpha(0.5).rgb(),
colorHover2: Color(theme.color2).alpha(0.7).rgb(),
colorActive2: Color(theme.color2).alpha(0.9).rgb(),
backgroundColorHoverDim3: Color(theme.backgroundColorHover3).alpha(0.3).rgb(),
backgroundColorActive3: Color(theme.backgroundColorHover3).alpha(0.5).rgb(),
backgroundColorHover2: Color(theme.selectedColor2).alpha(0.4).rgb(),
backgroundColorHover4: Color(theme.backgroundColorHover3).alpha(0.3).rgb(),
backgroundColorActive4: Color(theme.backgroundColorHover3).alpha(0.8).rgb(),
colorHover3: theme.color3,
borderColor4,
backgroundColor4: bgColor4,
color5: theme.color5 ?? bgColor4,
backgroundColor5,
backgroundColorHover5,
backgroundColorActive5,
icon: {
...globalStyle.icon,
color: theme.color,
},
lineInput: {
...globalStyle.lineInput,
color: theme.color,
backgroundColor: theme.backgroundColor,
},
containerStyle,
configScreenPadding: globalStyle.mainPadding * 2,
noteListHeaderHeight: 26,
noteListHeaderBorderPadding: 4,
textStyle,
textStyle2,
textStyleMinor,
clickableTextStyle: { ...textStyle, userSelect: literal('none') },
headerStyle: {
...globalStyle.headerStyle,
color: theme.color,
backgroundColor: theme.backgroundColor,
},
h1Style,
h2Style,
urlStyle,
inputStyle,
toolbarStyle,
tagStyle,
buttonStyle,
dialogModalLayer: {
zIndex: 9999, zIndex: 9999,
display: 'flex', display: literal('flex'),
position: 'absolute', position: literal('absolute'),
top: 0, top: 0,
left: 0, left: 0,
width: '100%', width: '100%',
height: '100%', height: '100%',
backgroundColor: 'rgba(0,0,0,0.6)', backgroundColor: 'rgba(0,0,0,0.6)',
alignItems: 'flex-start', alignItems: literal('flex-start'),
justifyContent: 'center', justifyContent: literal('center'),
}; },
style.controlBox = { controlBox: {
marginBottom: '1em', marginBottom: '1em',
color: 'black', // This will apply for the calendar color: 'black', // This will apply for the calendar
display: 'flex', display: literal('flex'),
flexDirection: 'row', flexDirection: literal('row'),
alignItems: 'center', alignItems: literal('center'),
}; },
controlBoxLabel: {
style.controlBoxLabel = {
marginRight: '1em', marginRight: '1em',
width: '10em', width: '10em',
display: 'inline-block', display: literal('inline-block'),
fontWeight: 'bold', fontWeight: literal('bold'),
}; },
controlBoxValue: {
display: literal('inline-block'),
},
style.controlBoxValue = { dialogBox: {
display: 'inline-block', backgroundColor: theme.backgroundColor,
};
style.dialogBox = {
backgroundColor: style.backgroundColor,
padding: 16, padding: 16,
boxShadow: '6px 6px 20px rgba(0,0,0,0.5)', boxShadow: '6px 6px 20px rgba(0,0,0,0.5)',
marginTop: 20, marginTop: 20,
maxHeight: '80%', maxHeight: '80%',
display: 'flex', display: literal('flex'),
flexDirection: 'column', flexDirection: literal('column'),
}; },
buttonIconStyle: {
style.buttonIconStyle = { color: iconColor,
color: style.iconColor,
marginRight: 6, marginRight: 6,
}; },
notificationBox: {
style.notificationBox = { backgroundColor: theme.warningBackgroundColor,
backgroundColor: style.warningBackgroundColor, display: literal('flex'),
display: 'flex', alignItems: literal('center'),
alignItems: 'center',
padding: 10, padding: 10,
fontSize: style.fontSize, fontSize: baseFontSize,
}; },
dialogTitle: { ...h1Style, marginBottom: '1.2em' },
style.dialogTitle = { ...style.h1Style, marginBottom: '1.2em' }; dropdownList: { ...inputStyle },
colorHover: theme.color,
style.dropdownList = { ...style.inputStyle }; backgroundHover: `${theme.selectedColor2}44`,
style.colorHover = style.color;
style.backgroundHover = `${style.selectedColor2}44`;
// In general the highlighted color, used to highlight text or icons, should be the same as selectedColor2 // In general the highlighted color, used to highlight text or icons, should be the same as selectedColor2
// but some times, depending on the theme, it might be too dark or too light, so it can be // but some times, depending on the theme, it might be too dark or too light, so it can be
// specified directly by the theme too. // specified directly by the theme too.
if (!style.highlightedColor) style.highlightedColor = style.selectedColor2; highlightedColor: theme.highlightedColor ?? theme.selectedColor2,
};
return style;
} }
// eslint-disable-next-line @typescript-eslint/no-explicit-any -- Old code before rule was applied type ExtraStyles = ReturnType<typeof extraStyles>;
const themeCache_: any = {}; type GlobalStyle = typeof globalStyle;
export type ThemeStyle = Theme & ExtraStyles & GlobalStyle & { cacheKey: number };
export function themeStyle(themeId: number) { const themeCache_: Record<string, ThemeStyle> = {};
export function themeStyle(themeId: number): ThemeStyle {
if (!themeId) throw new Error('Theme must be specified'); if (!themeId) throw new Error('Theme must be specified');
const cacheKey = themeId; const cacheKey = themeId;
if (themeCache_[cacheKey]) return themeCache_[cacheKey]; if (themeCache_[cacheKey]) return themeCache_[cacheKey];
// eslint-disable-next-line @typescript-eslint/no-explicit-any -- Old code before rule was applied const output: ThemeStyle = {
let output: any = {}; cacheKey,
...globalStyle,
...themes[themeId],
// All theme are based on the light style, and just override the // All theme are based on the light style, and just override the
// relevant properties // relevant properties
output = { ...globalStyle, ...themes[themeId] }; ...extraStyles(themes[themeId]),
output = addExtraStyles(output); };
output.cacheKey = cacheKey;
themeCache_[cacheKey] = output; themeCache_[cacheKey] = output;
return themeCache_[cacheKey]; return themeCache_[cacheKey];
@ -370,8 +360,10 @@ const cachedStyles_: any = {
// cacheKey must be a globally unique key, and must change whenever // cacheKey must be a globally unique key, and must change whenever
// the dependencies of the style change. If the style depends only // the dependencies of the style change. If the style depends only
// on the theme, a static string can be provided as a cache key. // on the theme, a static string can be provided as a cache key.
// eslint-disable-next-line @typescript-eslint/ban-types, @typescript-eslint/no-explicit-any -- Old code before rule was applied, Old code before rule was applied // eslint-disable-next-line @typescript-eslint/no-explicit-any -- Partially refactored code from before rule was applied
export function buildStyle(cacheKey: any, themeId: number, callback: Function) { type BuildStyleCallback = (style: ThemeStyle)=> any;
// eslint-disable-next-line @typescript-eslint/no-explicit-any -- Old code from before rule was applied
export function buildStyle(cacheKey: any, themeId: number, callback: BuildStyleCallback) {
cacheKey = Array.isArray(cacheKey) ? cacheKey.join('_') : cacheKey; cacheKey = Array.isArray(cacheKey) ? cacheKey.join('_') : cacheKey;
// We clear the cache whenever switching themes // We clear the cache whenever switching themes

View File

@ -56,6 +56,9 @@ const theme: Theme = {
codeMirrorTheme: 'material-darker', codeMirrorTheme: 'material-darker',
codeThemeCss: 'atom-one-dark-reasonable.css', codeThemeCss: 'atom-one-dark-reasonable.css',
headerBackgroundColor: '#2D3136',
textSelectionColor: '#00AEFF',
}; };
export default theme; export default theme;

View File

@ -55,6 +55,10 @@ const theme: Theme = {
codeMirrorTheme: 'default', codeMirrorTheme: 'default',
codeThemeCss: 'atom-one-light.css', codeThemeCss: 'atom-one-light.css',
headerBackgroundColor: '#F0F0F0',
textSelectionColor: '#0096FF',
colorBright2: '#ffffff',
}; };
export default theme; export default theme;

View File

@ -62,4 +62,8 @@ export interface Theme {
codeThemeCss: string; codeThemeCss: string;
highlightedColor?: string; highlightedColor?: string;
headerBackgroundColor: string;
textSelectionColor: string;
colorBright2: string;
} }