UNPKG

@jbrowse/core

Version:

JBrowse 2 core libraries used by plugins

393 lines (392 loc) 12.3 kB
import { createTheme } from '@mui/material'; import { blue, green, grey, orange, red } from '@mui/material/colors'; import deepmerge from 'deepmerge'; const refTheme = createTheme(); const midnight = refTheme.palette.augmentColor({ color: { main: '#0D233F' } }); const grape = refTheme.palette.augmentColor({ color: { main: '#721E63' } }); const forest = refTheme.palette.augmentColor({ color: { main: '#135560' } }); const mandarin = refTheme.palette.augmentColor({ color: { main: '#FFB11D' } }); const lightgrey = refTheme.palette.augmentColor({ color: { main: '#aaa' } }); const bases = { A: refTheme.palette.augmentColor({ color: green }), C: refTheme.palette.augmentColor({ color: blue }), G: refTheme.palette.augmentColor({ color: orange }), T: refTheme.palette.augmentColor({ color: red }), }; const framesCDS = [ null, refTheme.palette.augmentColor({ color: { main: '#FF8080' } }), refTheme.palette.augmentColor({ color: { main: '#80FF80' } }), refTheme.palette.augmentColor({ color: { main: '#8080FF' } }), refTheme.palette.augmentColor({ color: { main: '#8080FF' } }), refTheme.palette.augmentColor({ color: { main: '#80FF80' } }), refTheme.palette.augmentColor({ color: { main: '#FF8080' } }), ]; const frames = [ null, refTheme.palette.augmentColor({ color: { main: '#8f8f8f' } }), refTheme.palette.augmentColor({ color: { main: '#adadad' } }), refTheme.palette.augmentColor({ color: { main: '#d8d8d8' } }), refTheme.palette.augmentColor({ color: { main: '#d8d8d8' } }), refTheme.palette.augmentColor({ color: { main: '#adadad' } }), refTheme.palette.augmentColor({ color: { main: '#8f8f8f' } }), ]; const stopCodon = '#e22'; const startCodon = '#3e3'; const insertion = '#800080'; const deletion = '#808080'; const hardclip = '#f00'; const softclip = '#00f'; const skip = '#97b8c9'; const defaults = { primary: midnight, secondary: grape, tertiary: forest, quaternary: mandarin, highlight: mandarin, stopCodon, startCodon, insertion, deletion, softclip, hardclip, bases, frames, framesCDS, skip, }; function stockTheme() { return { palette: { ...defaults, mode: undefined, }, components: { MuiLink: { styleOverrides: { root: ({ theme }) => ({ color: theme.palette.tertiary.main, }), }, }, }, }; } function getDefaultTheme() { return { ...stockTheme(), name: 'Default (from config)', }; } function getLightStockTheme() { return { ...stockTheme(), name: 'Light (stock)', }; } function getDarkStockTheme() { return { name: 'Dark (stock)', palette: { ...defaults, mode: 'dark', }, components: { MuiAppBar: { defaultProps: { enableColorOnDark: true, }, styleOverrides: { root: ({ theme }) => theme.palette.primary.main, }, }, }, }; } function getDarkMinimalTheme() { return { name: 'Dark (minimal)', palette: { ...defaults, mode: 'dark', primary: { main: grey[700] }, secondary: { main: grey[800] }, tertiary: refTheme.palette.augmentColor({ color: { main: grey[900] } }), }, }; } function getMinimalTheme() { return { name: 'Light (minimal)', palette: { ...defaults, primary: { main: grey[900] }, secondary: { main: grey[800] }, tertiary: refTheme.palette.augmentColor({ color: { main: grey[900] } }), }, }; } export const defaultThemes = { default: getDefaultTheme(), lightStock: getLightStockTheme(), lightMinimal: getMinimalTheme(), darkMinimal: getDarkMinimalTheme(), darkStock: getDarkStockTheme(), }; function overwriteArrayMerge(_, sourceArray) { return sourceArray; } export function createJBrowseBaseTheme(theme) { const themeP = { palette: theme?.palette, typography: { fontSize: 12, }, spacing: 4, components: { MuiTooltip: { styleOverrides: { tooltip: { fontSize: 12, }, }, }, MuiButton: { defaultProps: { size: 'small', }, styleOverrides: { root: ({ theme }) => theme.palette.mode === 'dark' ? { color: theme.palette.text.primary, } : undefined, }, }, MuiAccordion: { defaultProps: { disableGutters: true, slotProps: { transition: { timeout: 150, unmountOnExit: true, }, }, }, }, MuiFilledInput: { defaultProps: { margin: 'dense', }, }, MuiFormControl: { defaultProps: { margin: 'dense', size: 'small', }, }, MuiFormHelperText: { defaultProps: { margin: 'dense', }, }, MuiIconButton: { defaultProps: { size: 'small', }, }, MuiInputBase: { defaultProps: { margin: 'dense', }, }, MuiAutocomplete: { defaultProps: { size: 'small', }, }, MuiInputLabel: { defaultProps: { margin: 'dense', }, }, MuiToolbar: { defaultProps: { variant: 'dense', }, }, MuiListItem: { defaultProps: { dense: true, }, }, MuiOutlinedInput: { defaultProps: { margin: 'dense', }, }, MuiFab: { defaultProps: { size: 'small', }, styleOverrides: { secondary: { backgroundColor: theme?.palette?.quaternary?.main, }, }, }, MuiTable: { defaultProps: { size: 'small', }, }, MuiPopover: { defaultProps: { transitionDuration: 0, }, }, MuiMenu: { defaultProps: { transitionDuration: 0, }, }, MuiMenuItem: { defaultProps: { dense: true, }, }, MuiTextField: { defaultProps: { margin: 'dense', variant: 'standard', }, }, MuiLink: { styleOverrides: { root: ({ theme }) => ({ color: theme.palette.text.secondary, }), }, }, MuiCheckbox: { styleOverrides: { root: ({ theme }) => theme.palette.mode === 'dark' ? { color: theme.palette.text.secondary, '&.Mui-checked': { color: theme.palette.text.secondary, }, } : undefined, }, }, MuiRadio: { styleOverrides: { root: ({ theme }) => theme.palette.mode === 'dark' ? { color: theme.palette.text.secondary, '&.Mui-checked': { color: theme.palette.text.secondary, }, } : undefined, }, }, MuiFormLabel: { styleOverrides: { root: ({ theme }) => theme.palette.mode === 'dark' ? { color: theme.palette.text.secondary, '&.Mui-focused': { color: theme.palette.text.secondary, }, } : undefined, }, }, MuiAccordionSummary: { styleOverrides: { root: { backgroundColor: theme?.palette?.tertiary?.main, }, content: { color: theme?.palette?.tertiary?.contrastText, }, }, }, MuiToggleButtonGroup: { defaultProps: { size: 'small', }, }, MuiButtonBase: { styleOverrides: { root: { '& .MuiTouchRipple-ripple': { animationDuration: '50ms !important', }, '& .MuiTouchRipple-child': { animationDuration: '50ms !important', }, }, }, }, }, }; return deepmerge(themeP, theme || {}, { arrayMerge: overwriteArrayMerge }); } const themeCache = new Map(); function getThemeCacheKey(configTheme, themeName) { return JSON.stringify({ configTheme, themeName }); } export function createJBrowseTheme(configTheme = {}, themes = defaultThemes, themeName = 'default') { const cacheKey = getThemeCacheKey(configTheme, themeName); const cached = themeCache.get(cacheKey); if (cached) { return cached; } const theme = createTheme(createJBrowseBaseTheme(themeName === 'default' ? deepmerge(themes.default, augmentThemeColors(configTheme), { arrayMerge: overwriteArrayMerge, }) : addMissingColors(themes[themeName]))); themeCache.set(cacheKey, theme); return theme; } function augmentThemeColors(theme = {}) { const augmentedPalette = Object.create(null); for (const entry of [ 'primary', 'secondary', 'tertiary', 'quaternary', 'highlight', ]) { const paletteEntry = theme.palette?.[entry]; if (paletteEntry) { augmentedPalette[entry] = refTheme.palette.augmentColor('color' in paletteEntry ? paletteEntry : { color: paletteEntry }); } } return Object.keys(augmentedPalette).length > 0 ? deepmerge(theme, { palette: augmentedPalette }) : theme; } function addMissingColors(theme = {}) { const { palette } = theme; return augmentThemeColors(deepmerge(theme, { palette: { quaternary: palette?.quaternary || lightgrey, tertiary: palette?.tertiary || lightgrey, highlight: palette?.highlight || mandarin, insertion: palette?.insertion || insertion, softclip: palette?.softclip || softclip, skip: palette?.skip || skip, hardclip: palette?.hardclip || hardclip, deletion: palette?.deletion || deletion, startCodon: palette?.startCodon || startCodon, stopCodon: palette?.stopCodon || stopCodon, }, })); }