Migrate to bulma-css-variables and introduce dark mode (#954)
Co-authored-by: Adrian Simmons <adrian@perlucida.co.uk> Co-authored-by: Dominik Pschenitschni <mail@celement.de> Co-authored-by: kolaente <k@knt.li> Reviewed-on: https://kolaente.dev/vikunja/frontend/pulls/954 Reviewed-by: dpschen <dpschen@noreply.kolaente.de> Reviewed-by: konrad <k@knt.li> Co-authored-by: adrinux <adrian@perlucida.co.uk> Co-committed-by: adrinux <adrian@perlucida.co.uk>
This commit is contained in:
@ -166,11 +166,11 @@ export default {
|
||||
}
|
||||
|
||||
.switch-view {
|
||||
background: $white;
|
||||
background: var(--white);
|
||||
display: inline-flex;
|
||||
border-radius: $radius;
|
||||
font-size: .75rem;
|
||||
box-shadow: $shadow-sm;
|
||||
box-shadow: var(--shadow-sm);
|
||||
height: $switch-view-height;
|
||||
margin-bottom: 1rem;
|
||||
padding: .5rem;
|
||||
@ -187,18 +187,18 @@ export default {
|
||||
}
|
||||
|
||||
&.is-active,
|
||||
&:hover {
|
||||
color: $white;
|
||||
&:hover {
|
||||
color: var(--switch-view-color);
|
||||
}
|
||||
|
||||
&.is-active {
|
||||
background: $primary;
|
||||
background: var(--primary);
|
||||
font-weight: bold;
|
||||
box-shadow: $shadow-xs;
|
||||
box-shadow: var(--shadow-xs);
|
||||
}
|
||||
|
||||
&:hover {
|
||||
background: $primary;
|
||||
background: var(--primary);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -167,7 +167,7 @@ export default {
|
||||
font-size: .8rem;
|
||||
|
||||
a {
|
||||
color: $grey-800;
|
||||
color: var(--grey-800);
|
||||
}
|
||||
}
|
||||
|
||||
@ -224,7 +224,7 @@ export default {
|
||||
background: rgba(0, 0, 0, 0.5);
|
||||
font-size: .75rem;
|
||||
font-weight: bold;
|
||||
color: $white;
|
||||
color: var(--white);
|
||||
transition: opacity $transition;
|
||||
}
|
||||
|
||||
|
@ -581,7 +581,6 @@ export default {
|
||||
</script>
|
||||
|
||||
<style lang="scss">
|
||||
$bucket-background: $grey-100;
|
||||
$ease-out: all .3s cubic-bezier(0.23, 1, 0.32, 1);
|
||||
$bucket-width: 300px;
|
||||
$bucket-header-height: 60px;
|
||||
@ -615,7 +614,7 @@ $filter-container-height: '1rem - #{$switch-view-height}';
|
||||
|
||||
.ghost {
|
||||
background: transparent !important;
|
||||
border: 3px dashed $grey-300 !important;
|
||||
border: 3px dashed var(--grey-300) !important;
|
||||
box-shadow: none !important;
|
||||
|
||||
* {
|
||||
@ -624,7 +623,7 @@ $filter-container-height: '1rem - #{$switch-view-height}';
|
||||
}
|
||||
|
||||
.bucket {
|
||||
background-color: $bucket-background;
|
||||
background-color: var(--grey-100);
|
||||
border-radius: $radius;
|
||||
position: relative;
|
||||
|
||||
@ -672,7 +671,7 @@ $filter-container-height: '1rem - #{$switch-view-height}';
|
||||
padding-right: 1rem;
|
||||
|
||||
.button {
|
||||
background: $bucket-background;
|
||||
background: var(--grey-100);
|
||||
width: 100%;
|
||||
}
|
||||
}
|
||||
@ -706,7 +705,7 @@ $filter-container-height: '1rem - #{$switch-view-height}';
|
||||
font-weight: bold;
|
||||
|
||||
&.is-max {
|
||||
color: $red;
|
||||
color: var(--danger);
|
||||
}
|
||||
}
|
||||
|
||||
@ -730,7 +729,7 @@ $filter-container-height: '1rem - #{$switch-view-height}';
|
||||
background-color: transparent;
|
||||
|
||||
&:hover {
|
||||
background-color: $white;
|
||||
background-color: var(--white);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -327,8 +327,8 @@ export default {
|
||||
|
||||
.ghost {
|
||||
border-radius: $radius;
|
||||
background: $grey-100;
|
||||
border: 2px dashed $grey-300;
|
||||
background: var(--grey-100);
|
||||
border: 2px dashed var(--grey-300);
|
||||
|
||||
* {
|
||||
opacity: 0;
|
||||
|
@ -200,7 +200,7 @@ export default {
|
||||
|
||||
span {
|
||||
transition: all 500ms ease;
|
||||
background: $grey-500;
|
||||
background: var(--grey-500);
|
||||
height: 10px;
|
||||
width: 10px;
|
||||
display: inline-block;
|
||||
@ -245,11 +245,11 @@ export default {
|
||||
@keyframes wave {
|
||||
0%, 40%, 100% {
|
||||
transform: translate(0, 0);
|
||||
background-color: $primary;
|
||||
background-color: var(--primary);
|
||||
}
|
||||
10% {
|
||||
transform: translate(0, -15px);
|
||||
background-color: $primary-dark;
|
||||
background-color: var(--primary-dark);
|
||||
}
|
||||
}
|
||||
</style>
|
@ -131,12 +131,12 @@ export default {
|
||||
|
||||
.is-archived {
|
||||
font-size: 0.75rem;
|
||||
border: 1px solid $grey-500;
|
||||
border: 1px solid var(--grey-500);
|
||||
color: $grey !important;
|
||||
padding: 2px 4px;
|
||||
border-radius: 3px;
|
||||
font-family: $vikunja-font;
|
||||
background: rgba($white, 0.75);
|
||||
background: var(--white-translucent);
|
||||
margin-left: .5rem;
|
||||
}
|
||||
|
||||
|
@ -706,18 +706,18 @@ $flash-background-duration: 750ms;
|
||||
// This is a workaround to hide the llama background from the top on the task detail page
|
||||
margin-top: -1.5rem;
|
||||
padding: 1rem;
|
||||
background-color: $light-background;
|
||||
background-color: var(--site-background);
|
||||
|
||||
@media screen and (max-width: $desktop) {
|
||||
padding-bottom: 0;
|
||||
}
|
||||
|
||||
.subtitle {
|
||||
color: $grey-500;
|
||||
color: var(--grey-500);
|
||||
margin-bottom: 1rem;
|
||||
|
||||
a {
|
||||
color: $grey-800;
|
||||
color: var(--grey-800);
|
||||
}
|
||||
}
|
||||
|
||||
@ -726,7 +726,7 @@ $flash-background-duration: 750ms;
|
||||
}
|
||||
|
||||
.icon.is-grey {
|
||||
color: $grey-400;
|
||||
color: var(--grey-400);
|
||||
}
|
||||
|
||||
:deep(.heading) {
|
||||
@ -754,7 +754,7 @@ $flash-background-duration: 750ms;
|
||||
}
|
||||
|
||||
.title.task-id {
|
||||
color: $grey-400;
|
||||
color: var(--grey-400);
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
@ -765,7 +765,7 @@ $flash-background-duration: 750ms;
|
||||
align-items: center;
|
||||
|
||||
a.remove {
|
||||
color: $red;
|
||||
color: var(--danger);
|
||||
vertical-align: middle;
|
||||
padding-left: .5rem;
|
||||
line-height: 1;
|
||||
@ -776,7 +776,7 @@ $flash-background-duration: 750ms;
|
||||
width: 100%;
|
||||
|
||||
a.show {
|
||||
color: $text;
|
||||
color: var(--text);
|
||||
padding: .25rem .5rem;
|
||||
transition: background-color $transition;
|
||||
border-radius: $radius;
|
||||
@ -784,7 +784,7 @@ $flash-background-duration: 750ms;
|
||||
margin: .1rem 0;
|
||||
|
||||
&:hover {
|
||||
background: $white;
|
||||
background: var(--white);
|
||||
}
|
||||
}
|
||||
|
||||
@ -800,7 +800,7 @@ $flash-background-duration: 750ms;
|
||||
|
||||
.detail-title {
|
||||
display: block;
|
||||
color: $grey-400;
|
||||
color: var(--grey-400);
|
||||
}
|
||||
|
||||
.none {
|
||||
@ -837,21 +837,24 @@ $flash-background-duration: 750ms;
|
||||
transition: all $transition-duration;
|
||||
|
||||
&::placeholder {
|
||||
color: $text-light;
|
||||
color: var(--text-light);
|
||||
opacity: 1;
|
||||
font-style: italic;
|
||||
}
|
||||
|
||||
&:not(:disabled) {
|
||||
&:hover, &:active {
|
||||
background: $input-background-color;
|
||||
border-color: $input-border-color;
|
||||
&:hover,
|
||||
&:active,
|
||||
&:focus {
|
||||
background: var(--scheme-main);
|
||||
border-color: var(--border);
|
||||
cursor: text;
|
||||
}
|
||||
|
||||
&:focus {
|
||||
background: $input-background-color;
|
||||
border-color: $input-focus-border-color;
|
||||
&:hover,
|
||||
&:active {
|
||||
cursor: text;
|
||||
border-color: var(--link)
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -883,18 +886,18 @@ $flash-background-duration: 750ms;
|
||||
|
||||
.created {
|
||||
font-size: .75rem;
|
||||
color: $grey-500;
|
||||
color: var(--grey-500);
|
||||
text-align: right;
|
||||
}
|
||||
|
||||
.checklist-summary {
|
||||
margin-left: .25rem;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.task-view-container {
|
||||
padding-bottom: 1rem;
|
||||
|
||||
|
||||
@media screen and (max-width: $desktop) {
|
||||
padding-bottom: 0;
|
||||
}
|
||||
@ -917,6 +920,11 @@ $flash-background-duration: 750ms;
|
||||
}
|
||||
}
|
||||
|
||||
.task-view-container {
|
||||
// simulate sass lighten($primary, 30) by increasing lightness 30% to 73%
|
||||
--primary-light: hsla(var(--primary-h), var(--primary-s), 73%, var(--primary-a));
|
||||
}
|
||||
|
||||
.flash-background-enter-from,
|
||||
.flash-background-enter-active {
|
||||
animation: flash-background $flash-background-duration ease 1;
|
||||
@ -924,7 +932,7 @@ $flash-background-duration: 750ms;
|
||||
|
||||
@keyframes flash-background {
|
||||
0% {
|
||||
background: lighten($primary, 30);
|
||||
background: var(--primary-light);
|
||||
}
|
||||
100% {
|
||||
background: transparent;
|
||||
|
@ -2,6 +2,7 @@
|
||||
<modal
|
||||
@close="close()"
|
||||
variant="scrolling"
|
||||
class="task-detail-view-modal"
|
||||
>
|
||||
<a @click="close()" class="close">
|
||||
<icon icon="times"/>
|
||||
@ -53,11 +54,18 @@ export default {
|
||||
position: fixed;
|
||||
top: 5px;
|
||||
right: 26px;
|
||||
color: $white;
|
||||
color: var(--white);
|
||||
font-size: 2rem;
|
||||
|
||||
@media screen and (max-width: $desktop) {
|
||||
color: $dark;
|
||||
color: var(--dark);
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
||||
<style lang="scss">
|
||||
// Close icon SVG uses currentColor, change the color to keep it visible
|
||||
.dark .task-detail-view-modal .close {
|
||||
color: var(--grey-900);
|
||||
}
|
||||
</style>
|
@ -68,7 +68,7 @@ ul.teams {
|
||||
transition: background-color $transition;
|
||||
|
||||
&:hover {
|
||||
background: $grey-100;
|
||||
background: var(--grey-100);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -83,13 +83,13 @@ const isLocalUser = computed(() => store.state.auth.info?.isLocalUser)
|
||||
a {
|
||||
display: block;
|
||||
padding: .5rem;
|
||||
color: $dark;
|
||||
color: var(--dark);
|
||||
width: 100%;
|
||||
border-left: 3px solid transparent;
|
||||
|
||||
&:hover, &.router-link-active {
|
||||
background: $white;
|
||||
border-color: $primary;
|
||||
background: var(--white);
|
||||
border-color: var(--primary);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -149,6 +149,6 @@ export default {
|
||||
}
|
||||
|
||||
.vue-advanced-cropper__background {
|
||||
background: $white;
|
||||
background: var(--white);
|
||||
}
|
||||
</style>
|
||||
|
@ -90,6 +90,21 @@
|
||||
</div>
|
||||
</label>
|
||||
</div>
|
||||
<div class="field">
|
||||
<label class="is-flex is-align-items-center">
|
||||
<span>
|
||||
{{ $t('user.settings.appearance.title') }}
|
||||
</span>
|
||||
<div class="select ml-2">
|
||||
<select v-model="activeColorSchemeSetting">
|
||||
<!-- TODO: use the Vikunja logo in color scheme as option buttons -->
|
||||
<option v-for="(title, schemeId) in colorSchemeSettings" :key="schemeId" :value="schemeId">
|
||||
{{ title }}
|
||||
</option>
|
||||
</select>
|
||||
</div>
|
||||
</label>
|
||||
</div>
|
||||
|
||||
<x-button
|
||||
:loading="userSettingsService.loading"
|
||||
@ -102,6 +117,9 @@
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import {computed, watch} from 'vue'
|
||||
import {useI18n} from 'vue-i18n'
|
||||
|
||||
import {playSoundWhenDoneKey} from '@/helpers/playPop'
|
||||
import {availableLanguages, saveLanguage, getCurrentLanguage} from '@/i18n'
|
||||
import {getQuickAddMagicMode, setQuickAddMagicMode} from '@/helpers/quickAddMagicMode'
|
||||
@ -110,6 +128,29 @@ import {PrefixMode} from '@/modules/parseTaskText'
|
||||
import ListSearch from '@/components/tasks/partials/listSearch'
|
||||
import {createRandomID} from '@/helpers/randomId'
|
||||
import {playPop} from '@/helpers/playPop'
|
||||
import {useColorScheme} from '@/composables/useColorScheme'
|
||||
import {success} from '@/message'
|
||||
|
||||
function useColorSchemeSetting() {
|
||||
const { t } = useI18n()
|
||||
const colorSchemeSettings = computed(() => ({
|
||||
light: t('user.settings.appearance.colorScheme.light'),
|
||||
auto: t('user.settings.appearance.colorScheme.system'),
|
||||
dark: t('user.settings.appearance.colorScheme.dark'),
|
||||
}))
|
||||
|
||||
const {store} = useColorScheme()
|
||||
watch(store, (schemeId) => {
|
||||
success({message: t('user.settings.appearance.setSuccess', {
|
||||
colorScheme: colorSchemeSettings.value[schemeId],
|
||||
})})
|
||||
})
|
||||
|
||||
return {
|
||||
colorSchemeSettings,
|
||||
activeColorSchemeSetting: store,
|
||||
}
|
||||
}
|
||||
|
||||
function getPlaySoundWhenDoneSetting() {
|
||||
return localStorage.getItem(playSoundWhenDoneKey) === 'true' || localStorage.getItem(playSoundWhenDoneKey) === null
|
||||
@ -141,6 +182,13 @@ export default {
|
||||
return this.$store.getters['lists/getListById'](this.settings.defaultListId)
|
||||
},
|
||||
},
|
||||
|
||||
setup() {
|
||||
return {
|
||||
...useColorSchemeSetting(),
|
||||
}
|
||||
},
|
||||
|
||||
mounted() {
|
||||
this.setTitle(`${this.$t('user.settings.general.title')} - ${this.$t('user.settings.title')}`)
|
||||
},
|
||||
|
Reference in New Issue
Block a user