diff --git a/src/main/store/module/preferences.ts b/src/main/store/module/preferences.ts index 83eb9515..33f8afe8 100644 --- a/src/main/store/module/preferences.ts +++ b/src/main/store/module/preferences.ts @@ -14,6 +14,7 @@ export default new Store({ defaults: { storagePath: defaultPath, backupPath, + theme: 'light:chrome', editor: { wrap: 'free', fontFamily: 'SF Mono, Consolas, Menlo', @@ -22,7 +23,8 @@ export default new Store({ tabSize: 2, trailingComma: 'none', semi: false, - singleQuote: true + singleQuote: true, + theme: 'github' } } }) diff --git a/src/renderer/App.vue b/src/renderer/App.vue index 743a6e3a..c7ee67ed 100644 --- a/src/renderer/App.vue +++ b/src/renderer/App.vue @@ -39,6 +39,7 @@ const snippetStore = useSnippetStore() const isUpdateAvailable = ref(false) const init = () => { + const theme = store.preferences.get('theme') const isValid = appStore.isEditorSettingsValid( store.preferences.get('editor') ) @@ -48,6 +49,12 @@ const init = () => { appStore.sizes.sidebar = store.app.get('sidebarWidth') appStore.sizes.snippetList = store.app.get('snippetListWidth') + if (theme) { + appStore.setTheme(theme) + } else { + appStore.setTheme('light:chrome') + } + trackAppUpdate() } diff --git a/src/renderer/assets/scss/base.scss b/src/renderer/assets/scss/base.scss index 00b6e76a..91bc6ff9 100644 --- a/src/renderer/assets/scss/base.scss +++ b/src/renderer/assets/scss/base.scss @@ -45,7 +45,6 @@ h6 { text-transform: uppercase; margin: var(--spacing-xs) 0; font-weight: 700; - color: var(--color-contrast-medium); } .gutter-line { @@ -69,6 +68,6 @@ h6 { .desc { font-size: var(--text-sm); - color: var(--color-contrast-medium); + color: var(--color-text-3); margin-top: var(--spacing-xs); } \ No newline at end of file diff --git a/src/renderer/assets/scss/main.scss b/src/renderer/assets/scss/main.scss index 1e338482..ef9af555 100644 --- a/src/renderer/assets/scss/main.scss +++ b/src/renderer/assets/scss/main.scss @@ -2,6 +2,6 @@ @import './variables'; @import './markdown'; @import './base'; -@import './vendor'; @import './ace'; -@import './themes'; \ No newline at end of file +@import './themes'; +@import './vendor'; \ No newline at end of file diff --git a/src/renderer/assets/scss/themes.scss b/src/renderer/assets/scss/themes.scss index 0f2e073d..6cbe15bb 100644 --- a/src/renderer/assets/scss/themes.scss +++ b/src/renderer/assets/scss/themes.scss @@ -1,28 +1,179 @@ -[data-theme='light'] { - .snippet-list-item--selected { - background-color: var(--color-contrast-lower); - &.focus { - background-color: var(--color-primary); - .title, - .meta { - color: #fff; - } - } - } +[data-theme='light:solarized'] { + --color-primary: hsl(44, 84%, 54%); + + --color-bg: hsl(44, 87%, 94%); + + --color-contrast-lower: hsl(44, 84%, 90%); + --color-contrast-lower-alt: hsl(44, 0%, 98%); + --color-contrast-lower-alt2: hsl(44, 60%, 94%); + --color-contrast-lower-alt3: hsl(44, 60%, 85%); + --color-contrast-lower-alt4: hsl(44, 60%, 75%); + --color-contrast-low: hsl(44, 60%, 60%); + --color-contrast-low-alt: hsl(44, 60%, 70%); + --color-contrast-medium: hsl(44, 60%, 40%); + --color-contrast-high: hsl(44, 60%, 30%); + --color-contrast-higher: hsl(44, 60%, 10%); + + --color-snippet-selected: var(--color-contrast-lower-alt2); + + --color-sidebar: #fff; + --color-sidebar-item-selected: var(--color-contrast-lower-alt3); + + --color-border: var(--color-contrast-lower-alt3); + + --color-button: hsl(44, 60%, 85%); + --color-button-hover: var(--color-contrast-low-alt); + --color-button-action-hover: var(--color-contrast-lower-alt3); + + --color-checkbox: var(--color-contrast-lower-alt); + + --color-input: var(--color-contrast-lower-alt); + + --color-select: var(--color-contrast-lower-alt); + + --color-menu-selected: var(--color-contrast-lower-alt3); + + --color-tag-delete: var(--color-contrast-lower-alt4); } -[data-theme='dark'] { - .snippet-list-item--selected { - background-color: var(--color-contrast-lower); - &.focus { - background-color: var(--color-primary); - .title, - .meta { - color: #fff; - } - } - .title, - .meta { - color: #fff; - } - } + +[data-theme='dark:one'] { + --color-primary: hsl(215, 69%, 45%); + + --color-bg: hsl(220, 13%, 18%); + + --color-contrast-lower: hsl(220, 13%, 20%); + --color-contrast-lower-alt: hsl(220, 13%, 22%); + --color-contrast-lower-alt2: hsl(220, 13%, 25%); + --color-contrast-lower-alt3: hsl(220, 13%, 30%); + --color-contrast-lower-low: hsl(220, 13%, 40%); + --color-contrast-medium: hsl(220, 13%, 50%); + + --color-border: var(--color-contrast-lower-alt2); + + --color-snippet-list: var(--color-bg); + --color-snippet-selected: var(--color-contrast-lower-alt); + + --color-sidebar: var(--color-bg); + --color-sidebar-item-selected: var(--color-contrast-lower-alt); + --color-sidebar-icon: var(--color-text); + + --color-text: hsl(0, 0%, 70%); + + --color-button: var(--color-contrast-lower-alt); + --color-button-hover: var(--color-contrast-lower-alt2); + --color-button-action: var(--color-contrast-low); + --color-button-action-hover: var(--color-contrast-lower-alt2); + + --color-input: var(--color-bg); + + --color-menu-selected: var(--color-contrast-lower-alt); + + --color-tag-delete: var(--color-contrast-lower-alt3); } + +[data-theme='dark:dracula'] { + --color-primary: hsl(215, 69%, 45%); + + // при конвертации в hsl цвет отличается, поэтому оставляем в hex + --color-bg: #282A36; + + --color-contrast-lower: hsl(231, 15%, 20%); + --color-contrast-lower-alt: hsl(231, 15%, 22%); + --color-contrast-lower-alt2: hsl(231, 15%, 25%); + --color-contrast-lower-alt3: hsl(231, 15%, 30%); + --color-contrast-lower-low: hsl(231, 15%, 40%); + --color-contrast-lower-medium: hsl(231, 15%, 50%); + + --color-snippet-list: var(--color-bg); + --color-snippet-selected: var(--color-contrast-lower-alt2); + + --color-sidebar: var(--color-bg); + --color-sidebar-item-selected: var(--color-contrast-lower-alt2); + --color-sidebar-icon: var(--color-text); + + --color-border: var(--color-contrast-lower-alt2); + + --color-text: hsl(0, 0%, 70%); + + --color-button: var(--color-contrast-lower-alt); + --color-button-hover: var(--color-contrast-lower-alt2); + --color-button-action: var(--color-contrast-low); + --color-button-action-hover: var(--color-contrast-lower-alt2); + + --color-input: var(--color-bg); + + --color-menu-selected: var(--color-contrast-lower-alt2); + + --color-tag-delete: var(--color-contrast-lower-alt3); +} + +[data-theme='dark:monokai'] { + --color-primary: hsl(215, 69%, 45%); + + // при конвертации в hsl цвет отличается, поэтому оставляем в hex + --color-bg: #272822; + + --color-contrast-lower: hsl(70, 8%, 20%); + --color-contrast-lower-alt: hsl(70, 8%, 22%); + --color-contrast-lower-alt2: hsl(70, 8%, 25%); + --color-contrast-lower-alt3: hsl(70, 8%, 30%); + --color-contrast-lower-low: hsl(70, 8%, 40%); + --color-contrast-lower-medium: hsl(70, 8%, 50%); + + --color-snippet-list: var(--color-bg); + --color-snippet-selected: var(--color-contrast-lower); + + --color-sidebar: var(--color-bg); + --color-sidebar-item-selected: var(--color-contrast-lower); + --color-sidebar-icon: var(--color-text); + + --color-border: var(--color-contrast-lower-alt2); + + --color-text: hsl(0, 0%, 70%); + + --color-button: var(--color-contrast-lower-alt); + --color-button-hover: var(--color-contrast-lower-alt2); + --color-button-action: var(--color-contrast-low); + --color-button-action-hover: var(--color-contrast-lower-alt2); + + --color-input: var(--color-bg); + + --color-menu-selected: var(--color-contrast-lower); + + --color-tag-delete: var(--color-contrast-lower-alt3); +} + +[data-theme='dark:merbivore'] { + --color-primary: hsl(215, 69%, 45%); + + --color-bg: hsl(0, 0%, 11%); + + --color-contrast-lower: hsl(0, 0%, 20%); + --color-contrast-lower-alt: hsl(0, 0%, 22%); + --color-contrast-lower-alt2: hsl(0, 0%, 25%); + --color-contrast-lower-alt3: hsl(0, 0%, 30%); + --color-contrast-lower-low: hsl(0, 0%, 40%); + --color-contrast-lower-medium: hsl(0, 0%, 50%); + + --color-snippet-list: var(--color-bg); + --color-snippet-selected: var(--color-contrast-lower); + + --color-sidebar: var(--color-bg); + --color-sidebar-item-selected: var(--color-contrast-lower); + --color-sidebar-icon: var(--color-text); + + --color-border: var(--color-contrast-lower-alt2); + + --color-text: hsl(0, 0%, 70%); + + --color-button: var(--color-contrast-lower-alt); + --color-button-hover: var(--color-contrast-lower-alt2); + --color-button-action: var(--color-contrast-low); + --color-button-action-hover: var(--color-contrast-lower-alt2); + + --color-input: var(--color-bg); + + --color-menu-selected: var(--color-contrast-lower); + + --color-tag-delete: var(--color-contrast-lower-alt3); +} \ No newline at end of file diff --git a/src/renderer/assets/scss/variables.scss b/src/renderer/assets/scss/variables.scss index 3e73f11b..c82fb7bf 100644 --- a/src/renderer/assets/scss/variables.scss +++ b/src/renderer/assets/scss/variables.scss @@ -24,12 +24,11 @@ --text-xl: calc(var(--text-base-size) * 2.4); --text-xxl: calc(var(--text-base-size) * 3.2); --text-xxxl: calc(var(--text-base-size) * 3.6); -} -[data-theme='light'] { --color-primary: hsl(215, 93%, 52%); --color-bg: hsl(0, 0%, 100%); + --color-contrast-lower: hsl(0, 0%, 97%); --color-contrast-lower-alt: hsl(0, 0%, 92%); --color-contrast-low: hsl(0, 0%, 85%); @@ -38,26 +37,31 @@ --color-contrast-high: hsl(0, 0%, 15%); --color-contrast-higher: hsl(0, 0%, 0%); - --color-text: var(--color-contrast-high); + --color-text: hsl(0, 0%, 0%); + --color-text-2: hsl(0, 0%, 15%); + --color-text-3: hsl(0, 0%, 50%); + --color-text-4: hsl(0, 0%, 80%); + --color-text-5: hsl(0, 0%, 85%); + --color-border: var(--color-contrast-low); + --color-button: var(--color-contrast-lower-alt); + --color-button-hover: var(--color-contrast-low); + --color-button-action: var(--color-contrast-medium); + --color-button-action-hover: var(--color-contrast-lower-alt); + + --color-sidebar: var(--color-contrast-lower); --color-sidebar-item-selected: var(--color-contrast-low); + --color-sidebar-icon: var(--color-text); + --color-sidebar-icon-selected: #fff; + --color-snippet-selected: hsl(0, 0%, 94%); + --color-snippet-list: var(--color-bg); --color-editor-scrollbar: rgba(121, 121, 121, 0.4); -} -[data-theme='dark'] { - --color-primary: hsl(215, 93%, 52%); - - --color-bg: hsl(0, 0%, 20%); - --color-contrast-lower: hsl(0, 0%, 25%); - --color-contrast-low: hsl(0, 0%, 32%); - --color-contrast-low-alt: hsl(0, 0%, 37%); - --color-contrast-medium: hsl(0, 0%, 50%); - --color-contrast-high: hsl(0, 0%, 85%); - --color-contrast-higher: hsl(0, 0%, 100%); + --color-menu-selected: var(--color-contrast-lower-alt); - --color-text: var(--color-contrast-high); - --color-border: var(--color-contrast-low); + --color-tag-delete: var(--color-contrast-lower-alt); } + diff --git a/src/renderer/assets/scss/vendor.scss b/src/renderer/assets/scss/vendor.scss index ead157d7..468fba46 100644 --- a/src/renderer/assets/scss/vendor.scss +++ b/src/renderer/assets/scss/vendor.scss @@ -3,7 +3,7 @@ .ps { $r: &; &__rail-y { - background-color: rgba(121, 121, 121, .8); + background-color: rgba(121, 121, 121, 0.8); width: 5px; &:hover { #{$r}__thumb-y { @@ -13,7 +13,7 @@ } } &__rail-x { - background-color: rgba(121, 121, 121, .5); + background-color: rgba(121, 121, 121, 0.5); width: 5px; &:hover { height: 4px; @@ -25,26 +25,33 @@ } } } - &__thumb-y, &__thumb-y { - background-color: rgba(121, 121, 121, .8); + &__thumb-y, + &__thumb-y { + background-color: rgba(121, 121, 121, 0.8); width: 5px; right: 0; } } - -.draggable-placeholder-inner{ - border: 1px dashed var(--color-contrast-medium); - box-sizing: border-box; - border-radius: 4px; - text-align: center; - padding: 0; - display: flex; - align-items: center; - position: relative; - margin-right: 1px; - +.ti-tags { + background-color: var(--color-bg) !important; } - -.draggable-placeholder{ -} \ No newline at end of file +.ti-tag { + background-color: var(--color-contrast-lower) !important; + color: var(--color-text) !important; + border: 1px solid var(--color-border) !important; +} +.ti-new-tag-input { + background-color: var(--color-bg) !important; + color: var(--color-text) !important; +} +.ti-selected-item { + background-color: var(--color-primary) !important; +} +.ti-deletion-mark { + background-color: var(--color-tag-delete) !important; +} +.ti-autocomplete { + border: 1px solid var(--color-border) !important; + background-color: var(--color-bg) !important; +} \ No newline at end of file diff --git a/src/renderer/components/editor/TheEditor.vue b/src/renderer/components/editor/TheEditor.vue index 836877e7..7d7dbd71 100644 --- a/src/renderer/components/editor/TheEditor.vue +++ b/src/renderer/components/editor/TheEditor.vue @@ -49,7 +49,6 @@ import { emitter } from '@/composable' interface Props { lang: Language - theme: string fragments: boolean fragmentIndex: number snippetId: string @@ -63,8 +62,7 @@ interface Emits { } const props = withDefaults(defineProps(), { - lang: 'typescript', - theme: 'chrome' + lang: 'typescript' }) const emit = defineEmits() @@ -110,7 +108,7 @@ const footerHeight = computed(() => appStore.sizes.editor.footerHeight + 'px') const init = async () => { editor = ace.edit(editorRef.value, { - theme: `ace/theme/${props.theme}`, + theme: `ace/theme/${appStore.editor.theme}`, useWorker: false, fontSize: appStore.editor.fontSize, fontFamily: appStore.editor.fontFamily, @@ -291,11 +289,15 @@ window.addEventListener('resize', () => { justify-content: space-between; padding: 0 var(--spacing-xs); font-size: 12px; + select { + background-color: var(--color-bg); + } } } .lang-selector { -webkit-appearance: none; border: 0; outline: none; + color: var(--color-text); } diff --git a/src/renderer/components/preferences/AppearancePreferences.vue b/src/renderer/components/preferences/AppearancePreferences.vue new file mode 100644 index 00000000..88d828e4 --- /dev/null +++ b/src/renderer/components/preferences/AppearancePreferences.vue @@ -0,0 +1,45 @@ + + + + + diff --git a/src/renderer/components/sidebar/SidebarList.vue b/src/renderer/components/sidebar/SidebarList.vue index 0fd6e403..29784fb1 100644 --- a/src/renderer/components/sidebar/SidebarList.vue +++ b/src/renderer/components/sidebar/SidebarList.vue @@ -116,15 +116,10 @@ emitter.on('scroll-to:folder', id => { align-items: center; justify-content: space-between; padding: 2px 0; - svg { - stroke: var(--color-contrast-medium); - width: 16px; - height: 16px; - } } &__title { h6 { - color: var(--color-contrast-medium); + color: var(--color-text); } } &__title, @@ -133,16 +128,16 @@ emitter.on('scroll-to:folder', id => { padding: 0 var(--spacing-xs); } .tab-header { - color: var(--color-contrast-low-alt); + color: var(--color-text-3); padding: var(--spacing-xs) 0; -webkit-user-select: none; &.active { - color: var(--color-contrast-medium); + color: var(--color-text); } &:after { content: '/'; margin: 0 5px; - color: var(--color-contrast-low-alt); + color: var(--color-text-3); } &:last-child { &:after { diff --git a/src/renderer/components/sidebar/SidebarListItem.vue b/src/renderer/components/sidebar/SidebarListItem.vue index 231c9223..2486be57 100644 --- a/src/renderer/components/sidebar/SidebarListItem.vue +++ b/src/renderer/components/sidebar/SidebarListItem.vue @@ -182,26 +182,35 @@ onClickOutside(itemRef, () => { border-radius: 5px; z-index: -1; } + :deep(svg) { + fill: var(--color-sidebar-icon-selected); + } + } + &.is-focused { + .icon { + :deep(svg) { + fill: var(--color-sidebar-icon-selected); + } + } } - &.is-selected { &::before { background-color: var(--color-sidebar-item-selected); } + &.is-focused { &::before { background-color: var(--color-primary); } - color: #fff; - :deep(svg) { - fill: #fff; - } } } .icon { margin-right: var(--spacing-xs); display: flex; align-items: center; + :deep(svg) { + fill: var(--color-sidebar-icon); + } } .nested { position: absolute; diff --git a/src/renderer/components/sidebar/TheSidebar.vue b/src/renderer/components/sidebar/TheSidebar.vue index db5fa21c..cc67dfa4 100644 --- a/src/renderer/components/sidebar/TheSidebar.vue +++ b/src/renderer/components/sidebar/TheSidebar.vue @@ -233,7 +233,7 @@ watch( .sidebar { padding-top: var(--title-bar-height); position: relative; - background-color: var(--color-contrast-lower); + background-color: var(--color-sidebar); display: flex; flex-flow: column; height: 100%; diff --git a/src/renderer/components/snippets/SnippetHeader.vue b/src/renderer/components/snippets/SnippetHeader.vue index 81b8d97b..b842f086 100644 --- a/src/renderer/components/snippets/SnippetHeader.vue +++ b/src/renderer/components/snippets/SnippetHeader.vue @@ -84,6 +84,8 @@ emitter.on('snippet:focus-name', () => { outline: none; line-height: 32px; text-overflow: ellipsis; + background-color: var(--color-bg); + color: var(--color-text); } } .action { diff --git a/src/renderer/components/snippets/SnippetList.vue b/src/renderer/components/snippets/SnippetList.vue index 570cbacf..5d1c3e1e 100644 --- a/src/renderer/components/snippets/SnippetList.vue +++ b/src/renderer/components/snippets/SnippetList.vue @@ -81,6 +81,7 @@ emitter.on('folder:click', () => { border-right: 1px solid var(--color-border); display: grid; grid-template-rows: 50px 1fr 10px; + background-color: var(--color-snippet-list); } .header { padding-top: var(--title-bar-height); diff --git a/src/renderer/components/snippets/SnippetListHeader.vue b/src/renderer/components/snippets/SnippetListHeader.vue index 444cb453..bcacd306 100644 --- a/src/renderer/components/snippets/SnippetListHeader.vue +++ b/src/renderer/components/snippets/SnippetListHeader.vue @@ -61,9 +61,11 @@ const onReset = () => { width: 100%; padding: 0 var(--spacing-xs); height: 24px; + background-color: var(--color-snippet-list); } :deep(svg) { flex-shrink: 0; + fill: var(--color-text); } .item { position: relative; diff --git a/src/renderer/components/snippets/SnippetListItem.vue b/src/renderer/components/snippets/SnippetListItem.vue index c64d2d61..4c5762be 100644 --- a/src/renderer/components/snippets/SnippetListItem.vue +++ b/src/renderer/components/snippets/SnippetListItem.vue @@ -321,7 +321,7 @@ const onDragEnd = () => { position: relative; z-index: 1; justify-content: space-between; - color: var(--color-contrast-medium); + color: var(--color-text-3); padding-top: var(--spacing-sm); } diff --git a/src/renderer/components/ui/AppActionButton.vue b/src/renderer/components/ui/AppActionButton.vue index 352ed224..f1a60f5c 100644 --- a/src/renderer/components/ui/AppActionButton.vue +++ b/src/renderer/components/ui/AppActionButton.vue @@ -12,11 +12,11 @@ align-items: center; padding: 4px 6px; border-radius: 4px; - svg { - fill: var(--color-contrast-medium); + :deep(svg) { + fill: var(--color-button-action); } &:hover { - background-color: var(--color-contrast-lower-alt); + background-color: var(--color-button-action-hover); } } diff --git a/src/renderer/components/ui/AppButton.vue b/src/renderer/components/ui/AppButton.vue index 56fb6014..3bd34920 100644 --- a/src/renderer/components/ui/AppButton.vue +++ b/src/renderer/components/ui/AppButton.vue @@ -10,11 +10,12 @@ .button { height: 32px; border: 1px solid var(--color-border); - background-color: var(--color-contrast-lower-alt); + background-color: var(--color-button); border-radius: 3px; transition: all 0.2s; + color: var(--color-text); &:hover { - background-color: var(--color-contrast-low); + background-color: var(--color-button-hover); } } diff --git a/src/renderer/components/ui/AppCheckbox.vue b/src/renderer/components/ui/AppCheckbox.vue index f938b465..7a076848 100644 --- a/src/renderer/components/ui/AppCheckbox.vue +++ b/src/renderer/components/ui/AppCheckbox.vue @@ -53,8 +53,10 @@ const onChange = () => { border-radius: 3px; display: flex; align-items: center; + background-color: var(--color-checkbox); :deep(svg) { position: relative; + fill: var(--color-text); } } } diff --git a/src/renderer/components/ui/AppInput.vue b/src/renderer/components/ui/AppInput.vue index 7098c1ce..cb79812a 100644 --- a/src/renderer/components/ui/AppInput.vue +++ b/src/renderer/components/ui/AppInput.vue @@ -38,5 +38,7 @@ const localValue = computed({ border: 1px solid var(--color-border); border-radius: 3px; padding: 0 var(--spacing-xs); + background-color: var(--color-input); + color: var(--color-text); } diff --git a/src/renderer/components/ui/AppInputTags.vue b/src/renderer/components/ui/AppInputTags.vue index f20b2b08..5615c3f5 100644 --- a/src/renderer/components/ui/AppInputTags.vue +++ b/src/renderer/components/ui/AppInputTags.vue @@ -68,26 +68,20 @@ const onChange = (v: string[]) => { size: 11px; } } + .ti-new-tag-input { + } } :deep(.ti-autocomplete) { margin-top: 2px; - border: 1px solid var(--color-border); overflow-y: scroll; .ti-selected-item { - background-color: var(--color-primary); } } :deep(.ti-tag) { - background-color: var(--color-contrast-lower); - color: var(--color-text); - border: 1px solid var(--color-border); margin: 0; padding: 0 4px; border-radius: 3px; font-size: 11px; - &.ti-deletion-mark { - background-color: var(--color-contrast-low); - } .ti-icon-close { position: relative; top: 1px; diff --git a/src/renderer/components/ui/AppSelect.vue b/src/renderer/components/ui/AppSelect.vue index a80285b4..07343c56 100644 --- a/src/renderer/components/ui/AppSelect.vue +++ b/src/renderer/components/ui/AppSelect.vue @@ -50,12 +50,15 @@ const localValue = computed({ padding: 0 var(--spacing-xs); -webkit-appearance: none; width: 300px; + background-color: var(--color-select); + color: var(--color-text); } :deep(svg) { position: absolute; right: 2px; top: 50%; transform: translateY(-50%); + fill: var(--color-text); } } diff --git a/src/renderer/components/ui/AppTree/AppTreeNode.vue b/src/renderer/components/ui/AppTree/AppTreeNode.vue index 734c6a2d..6d266def 100644 --- a/src/renderer/components/ui/AppTree/AppTreeNode.vue +++ b/src/renderer/components/ui/AppTree/AppTreeNode.vue @@ -333,7 +333,7 @@ $color-grey: #8c8c8c; fill: #fff; } :deep(svg) { - fill: #fff; + fill: #fff !important; } &::before { background-color: var(--color-primary); @@ -346,7 +346,17 @@ $color-grey: #8c8c8c; border: 2px solid var(--color-primary); } :deep(svg) { - fill: var(--color-text); + fill: var(--color-text) !important; + } + &.is-focused { + :deep(svg) { + fill: var(--color-text); + } + } + &.is-selected { + :deep(svg) { + fill: var(--color-text) !important; + } } } } diff --git a/src/renderer/components/ui/menu/AppMenu.vue b/src/renderer/components/ui/menu/AppMenu.vue index 498f4bab..b40bb4df 100644 --- a/src/renderer/components/ui/menu/AppMenu.vue +++ b/src/renderer/components/ui/menu/AppMenu.vue @@ -72,7 +72,7 @@ provide('items', items.value) padding: var(--spacing-xs); &.is-selected { border-radius: 5px; - background-color: var(--color-contrast-lower-alt); + background-color: var(--color-menu-selected); } } .body { diff --git a/src/renderer/store/app.ts b/src/renderer/store/app.ts index 97c513ba..622a758b 100644 --- a/src/renderer/store/app.ts +++ b/src/renderer/store/app.ts @@ -1,5 +1,9 @@ -import { platform } from '@/electron' -import type { EditorSettings, State } from '@shared/types/renderer/store/app' +import { platform, store } from '@/electron' +import type { + EditorSettings, + State, + Theme +} from '@shared/types/renderer/store/app' import { defineStore } from 'pinia' import { version } from '../../../package.json' @@ -11,7 +15,8 @@ const EDITOR_DEFAULTS: EditorSettings = { wrap: 'free', trailingComma: 'none', semi: false, - singleQuote: true + singleQuote: true, + theme: 'chrome' } export const useAppStore = defineStore('app', { @@ -37,6 +42,37 @@ export const useAppStore = defineStore('app', { }), actions: { + setTheme (theme: Theme) { + this.theme = theme + + if (theme === 'light:chrome') { + this.editor.theme = 'chrome' + } + if (theme === 'light:solarized') { + this.editor.theme = 'solarized_light' + } + if (theme === 'light:xcode') { + this.editor.theme = 'xcode' + } + if (theme === 'light:textmate') { + this.editor.theme = 'textmate' + } + if (theme === 'dark:one') { + this.editor.theme = 'one_dark' + } + if (theme === 'dark:dracula') { + this.editor.theme = 'dracula' + } + if (theme === 'dark:monokai') { + this.editor.theme = 'monokai' + } + if (theme === 'dark:merbivore') { + this.editor.theme = 'merbivore_soft' + } + + store.preferences.set('theme', theme) + store.preferences.set('editor', { ...this.editor }) + }, resetEditorSettings () { this.editor = EDITOR_DEFAULTS }, diff --git a/src/renderer/views/Preferences.vue b/src/renderer/views/Preferences.vue index 6293019c..551044b1 100644 --- a/src/renderer/views/Preferences.vue +++ b/src/renderer/views/Preferences.vue @@ -20,6 +20,12 @@ > + + + diff --git a/src/shared/types/main/analytics.d.ts b/src/shared/types/main/analytics.d.ts index ebb59653..17e21393 100644 --- a/src/shared/types/main/analytics.d.ts +++ b/src/shared/types/main/analytics.d.ts @@ -23,6 +23,7 @@ type AppEvents = | 'update' | 'install' | 'empty-trash' + | 'set-theme' type TrackSnippetEvents = CombineWith type TrackFolderEvents = CombineWith diff --git a/src/shared/types/main/store.d.ts b/src/shared/types/main/store.d.ts index 20b321ed..e0fee815 100644 --- a/src/shared/types/main/store.d.ts +++ b/src/shared/types/main/store.d.ts @@ -18,9 +18,11 @@ interface Editor { trailingComma: 'all' | 'none' | 'es5' semi: boolean singleQuote: boolean + theme: string } export interface PreferencesStore { storagePath: string backupPath: string editor: Editor + theme: string } diff --git a/src/shared/types/renderer/store/app.d.ts b/src/shared/types/renderer/store/app.d.ts index 154ce014..5035df32 100644 --- a/src/shared/types/renderer/store/app.d.ts +++ b/src/shared/types/renderer/store/app.d.ts @@ -1,5 +1,25 @@ import type { Ace } from 'ace-builds' +export type Theme = + | 'dark:dracula' + | 'dark:merbivore' + | 'dark:monokai' + | 'dark:one' + | 'light:chrome' + | 'light:solarized' + | 'light:textmate' + | 'light:xcode' + +export type ThemeEditor = + | 'chrome' + | 'dracula' + | 'merbivore_soft' + | 'monokai' + | 'one_dark' + | 'solarized_light' + | 'textmate' + | 'xcode' + export interface AppSizes { titlebar: number sidebar: number @@ -21,10 +41,12 @@ export interface EditorSettings { trailingComma: 'all' | 'none' | 'es5' semi: boolean singleQuote: boolean + theme: ThemeEditor } + export interface State { platform: NodeJS.Platform - theme: string + theme: Theme sizes: AppSizes showTags: boolean version: string