| |
| |
| |
| |
| |
| |
| |
| import deepmerge from 'deepmerge'; |
| import Color from 'color'; |
| import { object } from './dot'; |
| import designLanguage from '../design-language'; |
| import codesandboxBlack from '../themes/codesandbox-black'; |
| import codesandboxLight from '../themes/codesandbox-light.json'; |
|
|
| const polyfillTheme = vsCodeTheme => { |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| let uiColors: any = { |
| |
| editor: {}, |
| button: {}, |
| input: {}, |
| inputOption: {}, |
| list: {}, |
| sideBar: {}, |
| activityBar: {}, |
| titleBar: {}, |
| quickInput: {}, |
| menuList: {}, |
| dialog: {}, |
| }; |
|
|
| const type = vsCodeTheme.type || guessType(vsCodeTheme); |
|
|
| |
| const vsCodeColors = object(vsCodeTheme.colors || {}); |
| uiColors = deepmerge(uiColors, vsCodeColors); |
|
|
| |
|
|
| const codesandboxColors: any = ['dark', 'lc'].includes(type) |
| ? object(codesandboxBlack.colors) |
| : object(codesandboxLight.colors); |
|
|
| |
|
|
| uiColors.foreground = uiColors.foreground || codesandboxColors.foreground; |
| uiColors.errorForeground = |
| uiColors.errorForeground || codesandboxColors.errorForeground; |
|
|
| uiColors.sideBar = { |
| background: |
| uiColors.sideBar.background || |
| uiColors.editor.background || |
| codesandboxColors.sideBar.background, |
| foreground: |
| uiColors.sideBar.foreground || |
| uiColors.editor.foreground || |
| codesandboxColors.sideBar.foreground, |
| border: |
| uiColors.sideBar.border || |
| uiColors.editor.lineHighlightBackground || |
| codesandboxColors.sideBar.border, |
| }; |
|
|
| uiColors.input = { |
| background: uiColors.input.background || uiColors.sideBar.border, |
| foreground: uiColors.input.foreground || uiColors.sideBar.foreground, |
| foregroundReverse: |
| uiColors.input.foregroundReverse || |
| uiColors.input.foreground || |
| uiColors.sideBar.foreground, |
| border: uiColors.input.border || uiColors.sideBar.border, |
| placeholderForeground: |
| uiColors.input.placeholderForeground || |
| codesandboxColors.input.placeholderForeground, |
| }; |
|
|
| uiColors.quickInput = { |
| background: uiColors.quickInput.background || uiColors.sideBar.background, |
| foreground: uiColors.quickInput.foreground || uiColors.sideBar.foreground, |
| }; |
|
|
| uiColors.inputOption.activeBorder = |
| uiColors.inputOption.activeBorder || uiColors.input.placeholderForeground; |
|
|
| uiColors.button = { |
| background: |
| uiColors.button.background || codesandboxColors.button.background, |
| foreground: |
| uiColors.button.foreground || codesandboxColors.button.foreground, |
| }; |
|
|
| |
|
|
| |
| |
| |
| |
| |
| |
|
|
| const decreaseContrast = type === 'dark' ? lighten : darken; |
|
|
| const mutedForeground = withContrast( |
| uiColors.input.placeholderForeground, |
| uiColors.sideBar.background, |
| type |
| ); |
|
|
| if (uiColors.sideBar.border === uiColors.sideBar.background) { |
| uiColors.sideBar.border = decreaseContrast( |
| uiColors.sideBar.background, |
| 0.25 |
| ); |
| } |
|
|
| if (uiColors.sideBar.hoverBackground === uiColors.sideBar.background) { |
| uiColors.sideBar.hoverBackground = decreaseContrast( |
| uiColors.sideBar.background, |
| 0.25 |
| ); |
| } |
|
|
| if (uiColors.list.hoverBackground === uiColors.sideBar.background) { |
| if ( |
| uiColors.list.inactiveSelectionBackground && |
| uiColors.list.hoverBackground !== |
| uiColors.list.inactiveSelectionBackground |
| ) { |
| uiColors.list.hoverBackground = uiColors.list.inactiveSelectionBackground; |
| } else { |
| |
| uiColors.list.hoverBackground = decreaseContrast( |
| uiColors.sideBar.background, |
| 0.25 |
| ); |
| } |
| } |
|
|
| uiColors.list.foreground = uiColors.list.foreground || mutedForeground; |
| uiColors.list.hoverForeground = |
| uiColors.list.hoverForeground || uiColors.sideBar.foreground; |
| uiColors.list.hoverBackground = |
| uiColors.list.hoverBackground || uiColors.sideBar.hoverBackground; |
|
|
| uiColors.titleBar.activeBackground = |
| uiColors.titleBar.activeBackground || uiColors.sideBar.background; |
| uiColors.titleBar.activeForeground = |
| uiColors.titleBar.activeForeground || uiColors.sideBar.foreground; |
| uiColors.titleBar.border = |
| uiColors.titleBar.border || uiColors.sideBar.border; |
|
|
| |
| |
| |
| |
| |
|
|
| const addedColors = { |
| mutedForeground, |
| activityBar: { |
| selectedForeground: uiColors.sideBar.foreground, |
| inactiveForeground: mutedForeground, |
| hoverBackground: uiColors.sideBar.border, |
| }, |
| avatar: { border: uiColors.sideBar.border }, |
| sideBar: { hoverBackground: uiColors.sideBar.border }, |
| button: { |
| hoverBackground: `linear-gradient(0deg, rgba(255, 255, 255, 0.2), rgba(255, 255, 255, 0.2)), ${uiColors.button.background}`, |
| }, |
| secondaryButton: { |
| background: uiColors.input.background, |
| foreground: uiColors.input.foreground, |
| hoverBackground: `linear-gradient(0deg, rgba(255, 255, 255, 0.2), rgba(255, 255, 255, 0.2)), ${uiColors.sideBar.border}`, |
| }, |
| dangerButton: { |
| background: designLanguage.colors.reds[300], |
| foreground: 'white', |
| hoverBackground: `linear-gradient(0deg, rgba(255, 255, 255, 0.2), rgba(255, 255, 255, 0.2)), ${designLanguage.colors.reds[300]}`, |
| }, |
| icon: { |
| foreground: uiColors.foreground, |
| }, |
| switch: { |
| backgroundOff: designLanguage.colorsV2.black[100], |
| backgroundOn: uiColors.button.background, |
| toggle: designLanguage.colors.white, |
| toggleOn: uiColors?.switch?.toggleOn |
| ? uiColors.switch.toggleOn |
| : designLanguage.colors.white, |
| }, |
| dialog: { |
| background: uiColors.quickInput.background, |
| foreground: uiColors.quickInput.foreground, |
| border: uiColors.sideBar.border, |
| }, |
| menuList: { |
| background: designLanguage.colorsV2.black[500], |
| foreground: designLanguage.colorsV2.gray[500], |
| border: designLanguage.colorsV2.black[100], |
| hoverBackground: designLanguage.colorsV2.black[100], |
| hoverForeground: designLanguage.colorsV2.gray[500], |
| }, |
| }; |
|
|
| uiColors = deepmerge(uiColors, addedColors); |
|
|
| if (uiColors.switch.backgroundOff === uiColors.sideBar.background) { |
| uiColors.switch.backgroundOff = uiColors.sideBar.border; |
| } |
|
|
| if (uiColors.switch.toggle === uiColors.switch.backgroundOff) { |
| |
| uiColors.switch.toggle = designLanguage.colors.grays[200]; |
| } |
|
|
| |
| uiColors.activityBar.selectedForeground = withContrast( |
| uiColors.activityBar.selectedForeground, |
| uiColors.activityBar.inactiveForeground, |
| type, |
| 'icon' |
| ); |
|
|
| return uiColors; |
| }; |
|
|
| export default polyfillTheme; |
|
|
| const guessType = theme => { |
| if (theme.name && theme.name.toLowerCase().includes('light')) return 'light'; |
| return 'dark'; |
| }; |
|
|
| const lighten = (color, value) => Color(color).lighten(value).hex(); |
|
|
| const darken = (color, value) => Color(color).darken(value).hex(); |
|
|
| const withContrast = (color, background, type, contrastType = 'text') => { |
| const contrastRatio = { text: 4.5, icon: 1.6 }; |
| const contrast = contrastRatio[contrastType]; |
|
|
| if (Color(color).contrast(Color(background)) > contrast) return color; |
|
|
| |
| if (color === '#FFFFFF' || color === '#000000') return color; |
|
|
| |
| const increaseContrast = type === 'dark' ? lighten : darken; |
| return withContrast( |
| increaseContrast(color, 0.1), |
| background, |
| type, |
| contrastType |
| ); |
| }; |
|
|