Skip to content

Commit

Permalink
feat: Add dark mode (#97)
Browse files Browse the repository at this point in the history
* feat: Add toggle for dark mode

* feat: Change styles for dark mode

* fix: Rehydrate page after persisted state is reloaded

* fix: Adjust checkbox colors for dark theme

* fix: Active reset button is now dark in dark mode

* i18n: Change dark mode setting description
  • Loading branch information
Hanziness committed Jul 12, 2021
1 parent 83cacbf commit 37b8c82
Show file tree
Hide file tree
Showing 16 changed files with 107 additions and 20 deletions.
3 changes: 3 additions & 0 deletions components/base/button.vue
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@
.ui-button.regular:hover:not(:disabled) {
@apply bg-gray-500;
@apply dark:bg-gray-50 dark:bg-opacity-20;
}
.ui-button.regular:active:not(:disabled) {
Expand All @@ -39,10 +40,12 @@
.ui-button.subtle:hover {
@apply bg-gray-200;
@apply dark:bg-gray-50 dark:bg-opacity-20;
}
.ui-button.subtle:active {
@apply bg-gray-400;
@apply dark:bg-gray-50 dark:bg-opacity-40;
}
.ui-button.disabled {
Expand Down
2 changes: 1 addition & 1 deletion components/base/divider.vue
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
<template>
<hr class="my-2">
<hr class="my-2 border-t border-gray-200 dark:border-gray-600">
</template>

<style lang="scss" scoped>
Expand Down
2 changes: 2 additions & 0 deletions components/base/option.vue
Original file line number Diff line number Diff line change
Expand Up @@ -16,12 +16,14 @@
<style lang="postcss" scoped>
.select-option {
@apply px-3 py-4 border border-solid border-gray-300 rounded-md bg-white text-left;
@apply dark:bg-gray-800 dark:border-gray-600;
flex-basis: 0;
transition: background-color 100ms ease-out, color 100ms ease-out;
&:hover {
@apply bg-gray-200;
@apply dark:bg-gray-600;
}
&.active {
Expand Down
2 changes: 1 addition & 1 deletion components/settings/baseSettingsItemBare.vue
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
{{ $i18n.t(translationKey + '._title') }}
</slot>
</div>
<div v-if="showDescription" class="text-gray-800 text-sm truncate">
<div v-if="showDescription" class="text-black text-opacity-75 dark:text-gray-50 dark:text-opacity-75 text-sm truncate">
<slot name="item-subtitle">
{{ $i18n.t(translationKey + '._description') }}
</slot>
Expand Down
23 changes: 22 additions & 1 deletion components/settings/settingsPanel.vue
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,8 @@
</div>

<div v-if="activeTab === 3" :key="3" class="settings-tab">
<settings-check :settings-key="['visuals', 'darkMode']" />
<divider />
<settings-options :settings-key="['currentTimer']" :values="{traditional: 'traditional', approximate: 'approximate', percentage: 'percentage'}" />
<divider />
<settings-check :settings-key="['schedule', 'visibility', 'enabled']" />
Expand Down Expand Up @@ -186,17 +188,32 @@ export default {
section.settings-panel {
& input {
@apply rounded-md border-gray-300 bg-gray-100 focus:bg-white focus:ring-primary;
@apply dark:bg-gray-800 dark:focus:bg-gray-600 dark:text-gray-100 dark:border-gray-700;
@apply transition-colors;
}
& input[type="checkbox"] {
@apply text-primary;
&:hover {
@apply dark:bg-gray-500 bg-gray-200;
}
&:checked {
@apply dark:bg-primary dark:border-primary;
&:hover {
background-color: scale-color(#3498db, $lightness: 30%);
}
}
}
}
</style>

<style lang="scss" scoped>
section.settings-panel {
@apply bg-white h-full fixed shadow w-2/5 flex flex-col;
@apply dark:bg-gray-900 dark:text-gray-50;
z-index: 1001;
min-width: calc(min(600px, 100%));
Expand All @@ -216,6 +233,7 @@ div.settings-panel-menubar {
div.tab-header {
@apply flex-1 h-full bg-gray-200 p-2 cursor-pointer text-center flex items-center justify-center select-none;
@apply dark:bg-gray-800;
transition: border-color 0.2s ease-out;
box-sizing: border-box;
Expand Down Expand Up @@ -249,17 +267,20 @@ div.settings-tab {
div.reset-button {
@apply w-full p-4 text-black bg-gray-200 text-lg cursor-pointer transition-colors rounded-lg relative;
@apply dark:bg-gray-700 dark:text-gray-50;
&:hover:not(.active) {
@apply bg-red-500 text-white;
@apply dark:bg-red-700;
}
&:active {
@apply bg-red-600 text-white;
@apply dark:bg-red-800;
}
&.active {
@apply bg-gray-200 text-black cursor-default;
@apply bg-gray-200 text-black dark:bg-gray-600 dark:text-white cursor-default;
}
& .reset-subbutton {
Expand Down
24 changes: 13 additions & 11 deletions components/taskList/taskWindow.vue
Original file line number Diff line number Diff line change
Expand Up @@ -159,7 +159,7 @@ export default {
<style lang="scss" scoped>
div.tasks-window {
@apply py-2 rounded-lg bg-gray-100 border border-gray-200 text-gray-900 shadow-xl absolute z-20 max-w-lg max-h-96 flex flex-col;
// @apply dark:bg-gray-900 dark:text-white;
@apply dark:bg-gray-800 dark:text-gray-50 dark:border-gray-600;
& > .header {
@apply uppercase font-bold text-lg pl-4 pr-2;
Expand All @@ -169,13 +169,15 @@ div.tasks-window {
& > .header-toggle {
@apply rounded-full bg-gray-200 mr-1 p-1;
@apply dark:bg-gray-500 dark:bg-opacity-25;
&:last-child {
@apply mr-0;
}
&.active {
@apply bg-gray-700 text-white;
@apply dark:bg-gray-400 dark:bg-opacity-100;
}
&.disabled {
Expand All @@ -187,7 +189,7 @@ div.tasks-window {
& > .list {
@apply grid grid-flow-row divide-y divide-gray-300 overflow-y-scroll flex-shrink overflow-x-hidden;
// @apply dark:divide-gray-500;
@apply dark:divide-gray-500;
& > .list-item {
@apply flex flex-row items-center px-4 py-2; // h-11
Expand All @@ -213,7 +215,7 @@ div.tasks-window {
& > .description {
@apply text-black text-opacity-80 text-sm overflow-ellipsis;
// @apply dark:text-white;
@apply dark:text-gray-100 dark:text-opacity-80;
}
}
Expand All @@ -222,12 +224,12 @@ div.tasks-window {
& > .priority {
@apply text-black text-opacity-60 text-sm mr-2 w-4 text-right flex flex-col justify-center;
// @apply dark:text-white;
@apply dark:text-gray-100;
}
& > .priority-change-button {
@apply rounded-full bg-gray-700 bg-opacity-0 hover:bg-opacity-30;
// @apply dark:bg-white;
@apply dark:bg-transparent;
&.disabled {
@apply pointer-events-none opacity-40;
Expand All @@ -238,7 +240,7 @@ div.tasks-window {
}
& > .empty {
@apply mx-4 my-2 text-black text-opacity-80;
@apply mx-4 my-2 text-black text-opacity-80 dark:text-gray-100 dark:text-opacity-80;
}
& > .footer {
Expand All @@ -251,7 +253,7 @@ div.tasks-window {
& > input,
& > select {
@apply p-2 focus:ring-0 border-gray-200 bg-gray-200 text-gray-900 text-sm;
// @apply dark:border-gray-800 dark:bg-gray-800 dark:text-white;
@apply dark:border-gray-700 dark:bg-gray-700 dark:text-gray-50;
&:first-child {
@apply rounded-t-lg;
Expand All @@ -263,22 +265,22 @@ div.tasks-window {
&:focus {
@apply bg-gray-100;
// @apply dark:bg-gray-700;
@apply dark:bg-gray-600;
}
}
& > input.input-desc {
@apply text-gray-900 text-opacity-80 text-xs;
// @apply dark:text-white;
@apply dark:text-gray-50;
}
}
& > .add-button {
@apply bg-blue-900 hover:bg-blue-800 text-white rounded-lg p-2 ml-2 select-none flex flex-col justify-center;
// @apply dark:bg-gray-100 dark:hover:bg-gray-200 dark:text-black;
@apply dark:bg-gray-100 dark:hover:bg-gray-200 dark:text-black;
&.disabled {
@apply opacity-60 pointer-events-none;
@apply opacity-60 dark:opacity-25 pointer-events-none;
}
}
}
Expand Down
3 changes: 2 additions & 1 deletion components/timer/controls/basic.vue
Original file line number Diff line number Diff line change
Expand Up @@ -78,11 +78,12 @@ div.timer-control-panel-basic {
div.control-button {
@apply bg-gray-200 cursor-pointer;
@apply dark:bg-gray-800;
transition: background-color 200ms ease-out;
&:not(.play-button):hover {
@apply bg-gray-300;
@apply bg-gray-300 dark:bg-gray-600;
}
& > * {
Expand Down
7 changes: 6 additions & 1 deletion components/timer/timerProgress.vue
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,10 @@
'background-color': $store.getters['schedule/getScheduleColour'][scheduleEntryId],
'transform': `translateX(${-100 + progressPercentage}%)`
}"
/>
>
<!-- Dark mode background override -->
<div class="absolute w-full h-full invisible dark:visible dark:bg-white" />
</div>
</transition-group>
</template>

Expand Down Expand Up @@ -40,6 +43,8 @@ export default {
<style lang="scss" scoped>
// provides a background filling progress bar (parent needs to be position: relative)
.timer-progress {
@apply dark:opacity-20;
transition: 200ms ease-in-out;
transition-property: background-color transform;
width: 100%;
Expand Down
6 changes: 6 additions & 0 deletions i18n/en.js
Original file line number Diff line number Diff line change
Expand Up @@ -295,6 +295,12 @@ export default {
_title: 'Use tick emoji in title',
_description: 'Show ✔ instead of "done"'
}
},
visuals: {
darkMode: {
_title: 'Enable dark mode',
_description: 'Less bright, just as productive'
}
}
}
},
Expand Down
6 changes: 6 additions & 0 deletions i18n/hu.js
Original file line number Diff line number Diff line change
Expand Up @@ -295,6 +295,12 @@ export default {
_title: 'Pipa jel használata a címsorban',
_description: 'Mutasson ✔ emojit a "kész" helyett az alkalmazás'
}
},
visuals: {
darkMode: {
_title: 'Sötét téma bekapcsolása',
_description: 'Kevesebb fényerő, ugyanannyi produktivitás'
}
}
}
},
Expand Down
21 changes: 20 additions & 1 deletion layouts/timer.vue
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
<template>
<div class="page">
<div :class="['page', { 'dark': darkMode }]">
<nuxt />
<!-- <portal to="footer">
<span>&copy; {{ new Date().getFullYear() }}</span>
Expand All @@ -25,6 +25,25 @@ export default {
data () {
return {
}
},
computed: {
darkMode () {
return this.$store.state.settings.visuals.darkMode
},
updateFinished () {
return this.$store.state.loading.persist_finished
}
},
watch: {
updateFinished () {
this.$forceUpdate()
}
},
mounted () {
if (this.updateFinished) {
this.$forceUpdate()
}
}
}
</script>
5 changes: 5 additions & 0 deletions pages/timer.vue
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
<template>
<section class="timer-section" :style="{'background-color': $store.getters['schedule/currentScheduleColour']}">
<!-- Dark mode background override -->
<div class="absolute w-full h-full dark:bg-gray-900" />

<!-- Settings button -->
<ui-button subtle class="absolute" style="top: 0.5rem; right: 0.5rem; z-index: 10;" @click="showSettings = true">
<client-only>
Expand Down Expand Up @@ -162,6 +165,8 @@ html {
}
section.timer-section {
@apply dark:text-gray-50;
height: 100vh;
transition: background-color 300ms ease-in;
}
Expand Down
5 changes: 4 additions & 1 deletion plugins/vuex-persist.client.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,9 @@ export default function ({ store }) {
new VuexPersistence({
key: 'user-settings',
storage: window.localStorage,
paths: ['settings', 'tasklist']
paths: ['settings', 'tasklist'],
rehydrated: (store) => {
store.commit('loading/finished')
}
})(store)
}
13 changes: 13 additions & 0 deletions store/loading.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
export default {
state () {
return {
persist_finished: false
}
},

mutations: {
finished (state) {
state.persist_finished = true
}
}
}
3 changes: 2 additions & 1 deletion store/settings.js
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,8 @@ export const state = () => ({
},
wait: {
colour: 'rgb(222, 226, 230)'
}
},
darkMode: false
},
performance: {
showProgressBar: true
Expand Down
2 changes: 1 addition & 1 deletion tailwind.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ module.exports = {
'./plugins/**/*.{js,ts}',
'./nuxt.config.{js,ts}'
],
darkMode: false,
darkMode: 'class',
theme: {
extend: {
fontFamily: {
Expand Down

0 comments on commit 37b8c82

Please sign in to comment.