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:
adrinux 2021-11-22 21:12:54 +00:00 committed by konrad
parent 4ef54f1bc2
commit 46fa43d67f
73 changed files with 605 additions and 328 deletions

View file

@ -22,7 +22,8 @@
"@sentry/tracing": "6.15.0",
"@sentry/vue": "6.15.0",
"@vue/compat": "3.2.22",
"bulma": "0.9.3",
"@vueuse/core": "^6.8.0",
"bulma-css-variables": "^0.9.33",
"camel-case": "4.1.2",
"codemirror": "5.64.0",
"copy-to-clipboard": "3.3.1",

View file

@ -33,6 +33,7 @@ import ContentNoAuth from './components/home/contentNoAuth'
import {setLanguage} from './i18n'
import AccountDeleteService from '@/services/accountDelete'
import Ready from '@/components/misc/ready'
import {useColorScheme} from '@/composables/useColorScheme'
export default defineComponent({
name: 'app',
@ -54,6 +55,9 @@ export default defineComponent({
beforeCreate() {
setLanguage()
},
setup() {
useColorScheme()
},
created() {
// Make sure to always load the home route when running with electron
if (this.$route.fullPath.endsWith('frontend/index.html')) {

File diff suppressed because one or more lines are too long

Before

Width:  |  Height:  |  Size: 6.6 KiB

After

Width:  |  Height:  |  Size: 6.6 KiB

File diff suppressed because one or more lines are too long

Before

Width:  |  Height:  |  Size: 5.9 KiB

After

Width:  |  Height:  |  Size: 5.9 KiB

View file

@ -7,5 +7,11 @@ const Logo = computed(() => new Date().getMonth() === 5 ? LogoFullPride : LogoFu
</script>
<template>
<Logo alt="Vikunja" />
</template>
<Logo alt="Vikunja" class="logo" />
</template>
<style lang="scss" scoped>
.logo {
color: var(--logo-text-color);
}
</style>

View file

@ -43,7 +43,7 @@ $size: $lineWidth + 1rem;
width: $lineWidth;
left: 50%;
transform: $transformX;
background-color: $grey-400;
background-color: var(--grey-400);
border-radius: 2px;
transition: all $transition;
}
@ -62,7 +62,7 @@ $size: $lineWidth + 1rem;
&:focus {
&::before,
&::after {
background-color: $grey-600;
background-color: var(--grey-600);
}
&::before {

View file

@ -10,7 +10,7 @@ import {POWERED_BY as poweredByUrl} from '@/urls'
<style lang="scss">
.menu-bottom-link {
color: $grey-300;
color: var(--grey-300);
text-align: center;
display: block;
padding-top: 1rem;

View file

@ -144,7 +144,7 @@ export default {
justify-content: center;
align-items: center;
font-size: 2rem;
color: $grey-400;
color: var(--grey-400);
line-height: 1;
transition: all $transition;
@ -155,7 +155,7 @@ export default {
&:hover,
&:focus {
height: 1rem;
color: $grey-600;
color: var(--grey-600);
}
}
@ -191,7 +191,7 @@ export default {
}
.card {
background: $white;
background: var(--white);
}
}
}
@ -220,7 +220,7 @@ export default {
right: 1rem;
z-index: 4500; // The modal has a z-index of 4000
color: $grey-500;
color: var(--grey-500);
transition: color $transition;
@media screen and (max-width: $tablet) {

View file

@ -57,11 +57,11 @@ export default {
}
.title {
text-shadow: 0 0 1rem $white;
text-shadow: 0 0 1rem var(--white);
}
// FIXME: this should be defined somewhere deep
.link-share-view .card {
background-color: $white;
background-color: var(--white);
}
</style>

View file

@ -280,8 +280,8 @@ export default {
<style lang="scss" scoped>
$navbar-padding: 2rem;
$vikunja-nav-background: $light-background;
$vikunja-nav-color: $grey-700;
$vikunja-nav-background: var(--site-background);
$vikunja-nav-color: var(--grey-700);
$vikunja-nav-selected-width: 0.4rem;
.namespace-container {
@ -349,12 +349,12 @@ $vikunja-nav-selected-width: 0.4rem;
opacity: 0;
&:hover {
color: $orange;
color: var(--warning);
}
&.is-favorite {
opacity: 1;
color: $orange;
color: var(--warning);
}
}
@ -436,7 +436,7 @@ $vikunja-nav-selected-width: 0.4rem;
align-items: center;
&:hover {
background: $white;
background: var(--white);
}
:deep(.dropdown-trigger) {
@ -456,7 +456,7 @@ $vikunja-nav-selected-width: 0.4rem;
}
.ghost {
background: $grey-200;
background: var(--grey-200);
* {
opacity: 0;
@ -496,16 +496,16 @@ $vikunja-nav-selected-width: 0.4rem;
}
&.router-link-exact-active {
color: $primary;
border-left: $vikunja-nav-selected-width solid $primary;
color: var(--primary);
border-left: $vikunja-nav-selected-width solid var(--primary);
.icon {
color: $primary;
color: var(--primary);
}
}
&:hover {
border-left: $vikunja-nav-selected-width solid $primary;
border-left: $vikunja-nav-selected-width solid var(--primary);
}
}
}
@ -526,7 +526,7 @@ $vikunja-nav-selected-width: 0.4rem;
}
.icon {
color: $grey-400 !important;
color: var(--grey-400) !important;
}
}

View file

@ -5,7 +5,7 @@
class="navbar main-theme is-fixed-top"
role="navigation"
>
<router-link :to="{name: 'home'}" class="navbar-item logo">
<router-link :to="{name: 'home'}" class="logo-link">
<Logo width="164" height="48"/>
</router-link>
<MenuButton class="menu-button"/>
@ -137,13 +137,18 @@ export default {
<style lang="scss" scoped>
$vikunja-nav-logo-full-width: 164px;
$user-dropdown-width-mobile: 5rem;
$hamburger-menu-icon-spacing: 1rem;
$hamburger-menu-icon-width: 28px;
.navbar {
z-index: 4 !important;
}
.logo {
.logo-link {
display: none;
padding: 0.5rem 0.75rem;
@media screen and (min-width: $tablet) {
align-self: stretch;
@ -164,7 +169,7 @@ $vikunja-nav-logo-full-width: 164px;
}
.navbar.main-theme {
background: $light-background;
background: var(--site-background);
z-index: 5 !important;
justify-content: space-between;
align-items: center;
@ -219,7 +224,7 @@ $vikunja-nav-logo-full-width: 164px;
:deep() {
.trigger-button {
cursor: pointer;
color: $grey-400;
color: var(--grey-400);
padding: .5rem;
font-size: 1.25rem;
position: relative;
@ -278,7 +283,7 @@ $vikunja-nav-logo-full-width: 164px;
}
:deep(.dropdown-trigger) {
color: $grey-400;
color: var(--grey-400);
margin-left: 1rem;
height: 1rem;
width: 1rem;

View file

@ -57,7 +57,7 @@ export default {
padding: 0 0 0 .5rem;
border-radius: $radius;
font-size: .9rem;
color: $grey-900;
color: var(--grey-900);
justify-content: space-between;
@media screen and (max-width: $desktop) {

View file

@ -82,11 +82,11 @@ export default {
font-size: 0.85rem;
font-weight: bold;
height: $button-height;
box-shadow: $shadow-sm;
box-shadow: var(--shadow-sm);
&.is-hovered,
&:hover {
box-shadow: $shadow-md;
box-shadow: var(--shadow-md);
}
&.fullheight {
@ -99,11 +99,11 @@ export default {
&:active,
&:focus,
&:focus:not(:active) {
box-shadow: $shadow-xs !important;
box-shadow: var(--shadow-xs) !important;
}
&.is-primary.is-outlined:hover {
color: $white;
color: var(--white);
}
&.is-small {

View file

@ -134,7 +134,7 @@ export default {
height: $PICKER_SIZE;
overflow: hidden;
border-radius: 100%;
border: $BORDER_WIDTH solid $grey-300;
border: $BORDER_WIDTH solid var(--grey-300);
box-shadow: $shadow;
& > * {

View file

@ -258,7 +258,7 @@ export default {
position: absolute;
z-index: 99;
width: 320px;
background: $white;
background: var(--white);
border-radius: $radius;
box-shadow: $shadow;
@ -272,7 +272,7 @@ export default {
padding: 0 .5rem;
width: 100%;
height: 2.25rem;
color: $text;
color: var(--text);
transition: all $transition;
&:first-child {
@ -280,7 +280,7 @@ export default {
}
&:hover {
background: $light;
background: var(--light);
}
.text {
@ -291,7 +291,7 @@ export default {
padding-right: .25rem;
.weekday {
color: $text-light;
color: var(--text-light);
text-transform: capitalize;
}
}

View file

@ -338,13 +338,14 @@ $editor-border-color: #ddd;
.CodeMirror {
padding: .5rem;
border: 1px solid $editor-border-color;
background: var(--white);
&-lines pre {
margin: 0 !important;
}
&-placeholder {
color: $grey-400 !important;
color: var(--grey-400) !important;
font-style: italic;
}
}
@ -383,7 +384,7 @@ $editor-border-color: #ddd;
pre.CodeMirror-line {
margin-bottom: 0 !important;
color: $grey-700 !important;
color: var(--grey-700) !important;
}
.cm-header {
@ -409,10 +410,10 @@ ul.actions {
}
&, a {
color: $grey-500;
color: var(--grey-500);
&.done-edit {
color: $primary;
color: var(--primary);
}
}

View file

@ -106,7 +106,7 @@ svg {
}
.check:hover svg {
stroke: $primary;
stroke: var(--primary);
}
.is-disabled .check:hover svg {
@ -125,7 +125,7 @@ polyline {
input[type=checkbox]:checked + .check {
svg {
stroke: $primary;
stroke: var(--primary);
}
path {

View file

@ -380,23 +380,23 @@ export default {
&.has-search-results .input-wrapper {
border-radius: $radius $radius 0 0;
border-color: $primary !important;
background: $white !important;
border-color: var(--primary) !important;
background: var(--white) !important;
&, &:focus-within {
border-bottom-color: $grey-200 !important;
border-bottom-color: var(--grey-200) !important;
}
}
.input-wrapper {
padding: 0;
background: $white !important;
border-color: $grey-200 !important;
background: var(--white) !important;
border-color: var(--grey-200) !important;
flex-wrap: wrap;
height: auto;
&:hover {
border-color: $grey-300 !important;
border-color: var(--grey-300) !important;
}
.input {
@ -422,8 +422,8 @@ export default {
}
&:focus-within {
border-color: $primary !important;
background: $white !important;
border-color: var(--primary) !important;
background: var(--white) !important;
}
.loader {
@ -432,9 +432,9 @@ export default {
}
.search-results {
background: $white;
background: var(--white);
border-radius: 0 0 $radius $radius;
border: 1px solid $primary;
border: 1px solid var(--primary);
border-top: none;
max-height: 50vh;
@ -481,16 +481,16 @@ export default {
}
&:focus, &:hover {
background: $grey-100;
background: var(--grey-100);
box-shadow: none !important;
.hint-text {
color: $text;
color: var(--text);
}
}
&:active {
background: $grey-200;
background: var(--grey-200);
}
}
}

View file

@ -86,11 +86,11 @@ export default {
cursor: pointer;
width: calc((100% - #{($lists-per-row - 1) * 1rem}) / #{$lists-per-row});
height: $list-height;
background: $white;
background: var(--white);
margin: 0 $list-spacing $list-spacing 0;
padding: 1rem;
border-radius: $radius;
box-shadow: $shadow-sm;
box-shadow: var(--shadow-sm);
transition: box-shadow $transition;
display: flex;
@ -98,13 +98,13 @@ export default {
flex-wrap: wrap;
&:hover {
box-shadow: $shadow-md;
box-shadow: var(--shadow-md);
}
&:active,
&:focus,
&:focus:not(:active) {
box-shadow: $shadow-xs !important;
box-shadow: var(--shadow-xs) !important;
}
@media screen and (min-width: $widescreen) {
@ -158,7 +158,7 @@ export default {
font-family: $vikunja-font;
font-weight: 400;
font-size: 1.5rem;
color: $text;
color: var(--text);
width: 100%;
margin-bottom: 0;
max-height: calc(100% - 2rem); // 1rem padding, 1rem height of the "is archived" badge
@ -171,7 +171,7 @@ export default {
}
&.has-light-text .title {
color: $light;
color: var(--light);
}
&.has-background {
@ -180,8 +180,8 @@ export default {
background-position: center;
.title {
text-shadow: 0 0 10px $black, 1px 1px 5px $grey-700, -1px -1px 5px $grey-700;
color: $white;
text-shadow: 0 0 10px var(--black), 1px 1px 5px var(--grey-700), -1px -1px 5px var(--grey-700);
color: var(--white);
}
}
@ -190,7 +190,7 @@ export default {
opacity: 0;
&:hover {
color: $orange;
color: var(--warning);
}
&.is-archived {
@ -200,7 +200,7 @@ export default {
&.is-favorite {
display: inline-block;
opacity: 1;
color: $orange;
color: var(--warning);
}
}

View file

@ -40,8 +40,8 @@ export default {
<style lang="scss" scoped>
.is-done {
background: $green;
color: $white;
background: var(--success);
color: var(--white);
padding: .5rem;
font-weight: bold;
line-height: 1;

View file

@ -128,6 +128,6 @@ export default {
}
.url {
border-bottom: 1px dashed $primary;
border-bottom: 1px dashed var(--primary);
}
</style>

View file

@ -63,22 +63,22 @@ export default {
<style lang="scss" scoped>
.card {
background-color: $white;
background-color: var(--white);
border-radius: $radius;
margin-bottom: 1rem;
border: 1px solid $grey-200;
box-shadow: $shadow-sm;
border: 1px solid var(--card-border-color);
box-shadow: var(--shadow-sm);
}
.card-header {
box-shadow: none;
border-bottom: 1px solid $grey-200;
border-bottom: 1px solid var(--card-border-color);
border-radius: $radius $radius 0 0;
}
// FIXME: should maybe be merged somehow with modal
:deep(.modal-card-foot) {
background-color: $grey-50;
background-color: var(--grey-50);
border-top: 0;
}
</style>

View file

@ -22,7 +22,7 @@ export default {
.legal-links {
margin-top: 1rem;
text-align: right;
color: $grey-300;
color: var(--grey-300);
font-size: 1rem;
}
</style>

View file

@ -26,7 +26,7 @@ const motd = computed(() => store.state.config.motd)
<style lang="scss" scoped>
.no-auth-wrapper {
background: url('@/assets/llama.svg') no-repeat bottom left fixed $light-background;
background: url('@/assets/llama.svg') no-repeat bottom left fixed var(--site-background);
min-height: 100vh;
}
@ -38,6 +38,6 @@ const motd = computed(() => store.state.config.motd)
}
.logo {
max-width: 100%;
color: var(--logo-text-color);
}
</style>

View file

@ -98,7 +98,7 @@ export default {
left: 0;
bottom: 0;
right: 0;
background: $grey-100;
background: var(--grey-100);
z-index: 99;
}
@ -112,8 +112,8 @@ export default {
margin-right: 1rem;
&.is-loading::after {
border-left-color: $grey-400;
border-bottom-color: $grey-400;
border-left-color: var(--grey-400);
border-bottom-color: var(--grey-400);
}
}

View file

@ -35,8 +35,8 @@ export default {
kbd {
padding: .1rem .35rem;
border: 1px solid $grey-300;
background: $grey-100;
border: 1px solid var(--grey-300);
background: var(--grey-100);
border-radius: 3px;
font-size: .75rem;
}

View file

@ -145,9 +145,9 @@ export default {
width: .75rem;
height: .75rem;
background: $primary;
background: var(--primary);
border-radius: 100%;
border: 2px solid $white;
border: 2px solid var(--white);
}
.notifications-list {
@ -157,12 +157,12 @@ export default {
max-height: 400px;
overflow-y: auto;
background: $white;
background: var(--white);
width: 350px;
max-width: calc(100vw - 2rem);
padding: .75rem .25rem;
border-radius: $radius;
box-shadow: $shadow-sm;
box-shadow: var(--shadow-sm);
font-size: .85rem;
@media screen and (max-width: $tablet) {
@ -183,14 +183,14 @@ export default {
transition: background-color $transition;
&:hover {
background: $grey-100;
background: var(--grey-100);
border-radius: $radius;
}
.read-indicator {
width: .35rem;
height: .35rem;
background: $primary;
background: var(--primary);
border-radius: 100%;
margin-left: .5rem;
@ -219,7 +219,7 @@ export default {
}
.created {
color: $grey-400;
color: var(--grey-400);
}
&:last-child {
@ -227,14 +227,14 @@ export default {
}
a {
color: $grey-800;
color: var(--grey-800);
}
}
.nothing {
text-align: center;
padding: 1rem 0;
color: $grey-500;
color: var(--grey-500);
.explainer {
font-size: .75rem;

View file

@ -513,11 +513,11 @@ export default {
.results {
text-align: left;
width: 100%;
color: $grey-800;
color: var(--grey-800);
.result {
&-title {
background: $grey-50;
background: var(--grey-50);
padding: .5rem;
display: block;
font-size: .75rem;
@ -528,6 +528,7 @@ export default {
font-size: .9rem;
width: 100%;
background: transparent;
color: var(--grey-800);
text-align: left;
box-shadow: none;
border-radius: 0;
@ -539,12 +540,12 @@ export default {
cursor: pointer;
&:focus, &:hover {
background: $grey-50;
background: var(--grey-50);
box-shadow: none !important;
}
&:active {
background: $grey-100;
background: var(--grey-100);
}
}
}

View file

@ -167,7 +167,7 @@ ul.assingees {
a {
float: right;
color: $red;
color: var(--danger);
transition: all $transition;
}
}

View file

@ -445,12 +445,12 @@ export default {
</script>
<style lang="scss" scoped>
$gantt-border: 1px solid $grey-200;
$gantt-vertical-border-color: $grey-100;
$gantt-border: 1px solid var(--grey-200);
$gantt-vertical-border-color: var(--grey-100);
.gantt-chart {
overflow-x: auto;
border-top: 1px solid $grey-200;
border-top: 1px solid var(--grey-200);
.dates {
display: flex;
@ -477,8 +477,8 @@ $gantt-vertical-border-color: $grey-100;
font-weight: normal;
&.today {
background: $primary;
color: $white;
background: var(--primary);
color: var(--white);
border-radius: 5px 5px 0 0;
font-weight: bold;
}
@ -507,7 +507,7 @@ $gantt-vertical-border-color: $grey-100;
.task {
display: inline-block;
border: 2px solid $primary;
border: 2px solid var(--primary);
font-size: 0.85rem;
margin: 0.5rem;
border-radius: 6px;
@ -520,30 +520,30 @@ $gantt-vertical-border-color: $grey-100;
user-select: none; // Non-prefixed version
&.is-current-edit {
border-color: $orange !important;
border-color: var(--warning) !important;
}
&.has-light-text {
color: $light;
color: var(--light);
&.done span:after {
border-top: 1px solid $light;
border-top: 1px solid var(--light);
}
.edit-toggle {
color: $light;
color: var(--light);
}
}
&.has-dark-text {
color: $text;
color: var(--text);
&.done span:after {
border-top: 1px solid $dark;
border-top: 1px solid var(--dark);
}
.edit-toggle {
color: $text;
color: var(--text);
}
}
@ -596,8 +596,8 @@ $gantt-vertical-border-color: $grey-100;
}
&.nodate {
border: 2px dashed $grey-300;
background: $grey-100;
border: 2px dashed var(--grey-300);
background: var(--grey-100);
}
&:active {

View file

@ -267,17 +267,17 @@ export default {
padding: .5rem;
&:hover {
background-color: $grey-200;
background-color: var(--grey-200);
}
.filename {
font-weight: bold;
margin-bottom: .25rem;
color: $text;
color: var(--text);
}
.info {
color: $grey-500;
color: var(--grey-500);
font-size: .9rem;
p {
@ -339,17 +339,17 @@ export default {
width: 100%;
font-size: 5rem;
height: auto;
text-shadow: $shadow-md;
text-shadow: var(--shadow-md);
animation: bounce 2s infinite;
}
.hint {
margin: .5rem auto 2rem;
border-radius: 2px;
box-shadow: $shadow-md;
background: $primary;
box-shadow: var(--shadow-md);
background: var(--primary);
padding: 1rem;
color: $white;
color: var(--white);
width: 100%;
max-width: 300px;
}

View file

@ -39,7 +39,7 @@ export default {
<style scoped lang="scss">
.checklist-summary {
color: $grey-500;
color: var(--grey-500);
display: inline-flex;
align-items: center;
@ -49,10 +49,10 @@ export default {
margin-right: .25rem;
circle {
stroke: $grey-400;
stroke: var(--grey-400);
&:last-child {
stroke: $primary;
stroke: var(--primary);
}
}
}

View file

@ -141,14 +141,14 @@ $defer-task-max-width: 350px + 100px;
width: 100%;
max-width: $defer-task-max-width;
border-radius: $radius;
border: 1px solid $grey-200;
border: 1px solid var(--grey-200);
padding: 1rem;
margin: 1rem;
background: $white;
color: $text;
background: var(--white);
color: var(--text);
cursor: default;
z-index: 10;
box-shadow: $shadow-lg;
box-shadow: var(--shadow-lg);
@media screen and (max-width: ($defer-task-max-width)) {
left: .5rem;

View file

@ -127,7 +127,7 @@ export default {
}
:deep(.user img) {
border: 2px solid $white;
border: 2px solid var(--white);
margin-right: 0;
}
@ -135,8 +135,8 @@ export default {
position: absolute;
top: 4px;
left: 2px;
color: $red;
background: $white;
color: var(--danger);
background: var(--white);
padding: 0 4px;
display: block;
border-radius: 100%;

View file

@ -117,13 +117,13 @@ export default {
</script>
<style lang="scss" scoped>
$task-background: $white;
$task-background: var(--white);
.task {
-webkit-touch-callout: none; // iOS Safari
user-select: none;
cursor: pointer;
box-shadow: $shadow-xs;
box-shadow: var(--shadow-xs);
display: block;
border: 3px solid transparent;
@ -163,7 +163,7 @@ $task-background: $white;
}
&.overdue {
color: $red;
color: var(--danger);
}
}
@ -219,7 +219,7 @@ $task-background: $white;
.footer .icon,
.due-date,
.priority-label {
background: $grey-100;
background: var(--grey-100);
border-radius: $radius;
padding: 0 .5rem;
}
@ -229,7 +229,7 @@ $task-background: $white;
}
.task-id {
color: $grey-500;
color: var(--grey-500);
font-size: .8rem;
margin-bottom: .25rem;
display: flex;
@ -244,21 +244,21 @@ $task-background: $white;
}
&.has-light-text {
color: $white;
color: var(--white);
.task-id {
color: $grey-200;
color: var(--grey-200);
}
.footer .icon,
.due-date,
.priority-label {
background: $grey-800;
background: var(--grey-800);
}
.footer {
.icon svg {
fill: $white;
fill: var(--white);
}
}
}

View file

@ -70,6 +70,6 @@ export default {
<style lang="scss" scoped>
.list-namespace-title {
color: $grey-500;
color: var(--grey-500);
}
</style>

View file

@ -54,7 +54,7 @@ export default {
}
span.high-priority {
color: $red;
color: var(--danger);
width: auto !important; // To override the width set in tasks
.icon {
@ -64,7 +64,7 @@ span.high-priority {
}
&.not-so-high {
color: $orange;
color: var(--warning);
}
}
</style>

View file

@ -310,7 +310,7 @@ export default {
}
.different-list {
color: $grey-500;
color: var(--grey-500);
width: auto;
}
@ -332,21 +332,21 @@ export default {
border-radius: $radius;
&:hover {
background-color: $grey-200;
background-color: var(--grey-200);
}
a {
color: $text;
color: var(--text);
transition: color ease $transition-duration;
&:hover {
color: $grey-900;
color: var(--grey-900);
}
}
.remove {
text-align: center;
color: $red;
color: var(--danger);
opacity: 0;
transition: opacity $transition;
}

View file

@ -112,7 +112,7 @@ export default {
align-items: center;
&.overdue :deep(.datepicker a.show) {
color: $red;
color: var(--danger);
}
&:last-child {
@ -120,7 +120,7 @@ export default {
}
a.remove {
color: $red;
color: var(--danger);
padding-left: .5rem;
}
}

View file

@ -227,7 +227,7 @@ export default {
border: 2px solid transparent;
&:hover {
background-color: $grey-100;
background-color: var(--grey-100);
}
.tasktext,
@ -239,13 +239,13 @@ export default {
flex: 1 0 50%;
.overdue {
color: $red;
color: var(--danger);
}
}
.task-list {
width: auto;
color: $grey-400;
color: var(--grey-400);
font-size: .9rem;
white-space: nowrap;
}
@ -273,11 +273,11 @@ export default {
}
a {
color: $text;
color: var(--text);
transition: color ease $transition-duration;
&:hover {
color: $grey-900;
color: var(--grey-900);
}
}
@ -288,12 +288,12 @@ export default {
transition: opacity $transition, color $transition;
&:hover {
color: $orange;
color: var(--warning);
}
&.is-favorite {
opacity: 1;
color: $orange;
color: var(--warning);
}
}
@ -324,16 +324,16 @@ export default {
.tasktext.done {
text-decoration: line-through;
color: $grey-500;
color: var(--grey-500);
}
span.parent-tasks {
color: $grey-500;
color: var(--grey-500);
width: auto;
}
.remove {
color: $red;
color: var(--danger);
}
input[type="checkbox"] {
@ -351,8 +351,8 @@ export default {
left: calc(50% - 1rem);
width: 2rem;
height: 2rem;
border-left-color: $grey-300;
border-bottom-color: $grey-300;
border-left-color: var(--grey-300);
border-bottom-color: var(--grey-300);
}
}
</style>

View file

@ -0,0 +1,48 @@
import {computed, watch, readonly} from 'vue'
import {useStorage, createSharedComposable, ColorSchemes, usePreferredColorScheme, tryOnMounted} from '@vueuse/core'
const STORAGE_KEY = 'color-scheme'
const DEFAULT_COLOR_SCHEME_SETTING: ColorSchemes = 'light'
const CLASS_DARK = 'dark'
const CLASS_LIGHT = 'light'
// This is built upon the vueuse useDark
// Main differences:
// - usePreferredColorScheme
// - doesn't allow setting via the `isDark` ref.
// - instead the store is exposed
// - value is synced via `createSharedComposable`
// https://github.com/vueuse/vueuse/blob/main/packages/core/useDark/index.ts
export const useColorScheme = createSharedComposable(() => {
const store = useStorage<ColorSchemes>(STORAGE_KEY, DEFAULT_COLOR_SCHEME_SETTING)
const preferredColorScheme = usePreferredColorScheme()
const isDark = computed<boolean>(() => {
if (store.value !== 'auto') {
return store.value === 'dark'
}
const autoColorScheme = preferredColorScheme.value === 'no-preference'
? DEFAULT_COLOR_SCHEME_SETTING
: preferredColorScheme.value
return autoColorScheme === 'dark'
})
function onChanged(v: boolean) {
const el = window?.document.querySelector('html')
el?.classList.toggle(CLASS_DARK, v)
el?.classList.toggle(CLASS_LIGHT, !v)
}
watch(isDark, onChanged, { flush: 'post' })
tryOnMounted(() => onChanged(isDark.value))
return {
store,
isDark: readonly(isDark),
}
})

View file

@ -112,6 +112,15 @@
"disabled": "Disabled",
"todoist": "Todoist",
"vikunja": "Vikunja"
},
"appearance": {
"title": "Color Scheme",
"setSuccess": "Saved change of color scheme to {colorScheme}",
"colorScheme": {
"light": "Light",
"system": "System",
"dark": "Dark"
}
}
},
"deletion": {

View file

@ -0,0 +1,44 @@
//
// IMPORTANT NOTE:
//
// The styles in this file and all imported styles should not
// create CSS output when compiled!
// Instead they should only define SCSS that gets compiled to nothing.
//
// The reason is that this file is prefixed in _every_ component style so that
// the component has access to the variables, mixins, etc. that
// are defined here.
//
// the default values get overwritten by the definitions above
@import "bulma-css-variables/sass/utilities/_all";
// since $tablet is defined by bulma we can just define it after importing the utilities
$mobile: math.div($tablet, 2);
$family-sans-serif: 'Open Sans', Helvetica, Arial, sans-serif;
$vikunja-font: 'Quicksand', sans-serif;
$thickness: 1px;
$pagination-current-border: var(--primary);
$navbar-item-active-color: var(--primary);
$dropdown-content-shadow: none;
$dropdown-item-hover-background-color: var(--grey-100);
$bulmaswatch-import-font: false !default;
$site-background: var(--grey-100);
$transition-duration: 150ms;
$transition: $transition-duration ease;
$button-height: 34px;
$switch-view-height: 2.69rem;
$navbar-height: 4rem;
$navbar-width: 300px;
$navbar-icon-width: 40px;
$lists-per-row: 5;
$list-height: 150px;
$list-spacing: 1rem;

View file

@ -6,7 +6,7 @@
.tag {
margin: .5rem 0 .5rem .5rem;
background: $grey-200;
background: var(--grey-200);
// FIXME: only used in ListLabels.vue
&.disabled {

View file

@ -7,8 +7,8 @@
.modal-container .task-view {
border-radius: $radius;
padding: 1rem;
color: $text;
background-color: $light-background !important;
color: var(--text);
background-color: var(--site-background) !important;
@media screen and (max-width: 800px) {
border-radius: 0;

View file

@ -5,7 +5,7 @@
z-index: 10000;
font-size: 0.8rem;
text-align: center;
background: $dark;
background: var(--dark);
color: white;
border-radius: 5px;
padding: 5px 10px 5px;
@ -28,7 +28,7 @@
height: 0;
border-left: 5px solid transparent;
border-right: 5px solid transparent;
border-top: 5px solid $dark;
border-top: 5px solid var(--dark);
&.bottom {
transform: rotate(180deg);

View file

@ -0,0 +1,2 @@
@import "colors";
@import "shadows";

View file

@ -0,0 +1,122 @@
// Vikunja colors as CSS custom properties
:root {
// Vikunja specific variables
--grey-50: hsl(210, 20%, 98%);
--grey-100: hsl(220, 14.3%, 95.9%);
--grey-200: hsl(220, 13%, 91%);
--grey-300: hsl(216, 12.2%, 83.9%);
--grey-400: hsl(217.9, 10.6%, 64.9%);
--grey-500-hsl: 220, 8.9%, 46.1%;
--grey-500: hsl(var(--grey-500-hsl));
--grey-600: hsl(215, 13.8%, 34.1%);
--grey-700: hsl(216.9, 19.1%, 26.7%);
--grey-800: hsl(215, 27.9%, 16.9%);
--grey-900: hsl(220.9, 39.3%, 11%);
--site-background: var(--grey-100);
--scheme-main: var(--white);
// Overrides of Bulma defaults
--grey-darker: var(--grey-700);
--grey-dark: var(--grey-800);
--grey: var(--grey-500);
--grey-light: var(--grey-300);
--grey-lighter: var(--grey-200);
--grey-lightest: var(--grey-100);
--input-border-color: var(--grey-200);
--white-h: 0deg;
--white-s: 0%;
--white-l: 100%;
--white-a: 1;
--white: hsla(var(--white-h), var(--white-s), var(--white-l), var(--white-a));
--white-translucent: hsla(var(--white-h), var(--white-s), var(--white-l), 0.75);
--black-h: 0deg;
--black-s: 0%;
--black-l: 4%;
--black-a: 1;
--black: hsla(var(--black-h), var(--black-s), var(--black-l), var(--black-a));
// $warning / $orange: #ff851b
--warning-h: 27.9deg;
--warning-s: 100%;
--warning-l: 55.3%;
--warning-a: 1;
--warning: hsla(var(--warning-h), var(--warning-s), var(--warning-l), var(--warning-a));
// $success / $green is #00db60
--success-h: 146.3deg;
--success-s: 100%;
--success-l: 42.9%;
--success-a: 1;
--success: hsla(var(--success-h), var(--success-s), var(--success-l), var(--success-a));
// $danger / $red is #ff4136
--danger-h: 3.3deg;
--danger-s: 100%;
--danger-l: 60.6%;
--danger-a: 1;
--danger: hsla(var(--danger-h), var(--danger-s), var(--danger-l), var(--danger-a));
// var(--primary) / $blue is #1973ff
--primary-h: 216.5deg;
--primary-s: 100%;
--primary-l: 54.9%;
--primary-a: 1;
--primary-hsl: var(--primary-h), var(--primary-s), var(--primary-l);
--primary: hsla(var(--primary-h), var(--primary-s), var(--primary-l), var(--primary-a));
// END Overrides of Bulma defaults
// Define custom color variable to prevent change in dark mode
--switch-view-color: hsla(var(--white-h), var(--white-s), var(--white-l), var(--white-a));
// Define custom color variable to alow change in dark mode
--card-border-color: var(--grey-200);
--logo-text-color: hsl(180, 1%, 15%);
&.dark {
// Light mode colours reversed for dark mode
--grey-900-hsl: 210, 20%, 98%;
--grey-900: hsl(var(--grey-900-hsl));
--grey-800: hsl(220, 14.3%, 95.9%);
--grey-700: hsl(220, 13%, 91%);
--grey-600: hsl(216, 12.2%, 83.9%);
--grey-500-hsl: 217.9, 10.6%, 64.9%;
--grey-500: hsl(var(--grey-500-hsl));
--grey-400: hsl(220, 8.9%, 46.1%);
--grey-300: hsl(215, 13.8%, 34.1%);
--grey-200: hsl(216.9, 19.1%, 26.7%);
--grey-100-hsl: 215, 27.9%, 16.9%;
--grey-100: hsl(var(--grey-100-hsl));
--grey-50-hsl: 220.9, 39.3%, 11%;
--grey-50: hsl(var(--grey-50-hsl));
// Dark grey looks better than black
--white: var(--grey-50);
--black-l: 100%;
// Text renders better in grey than black
--text: var(--grey-800);
--text-invert: #000;
--text-light: var(--grey-300);
--text-strong: var(--grey-900);
// Elements that rely on Bulma defaults in light mode but
// need to be overriden in dark mode
--input-placeholder-color: hsla(var(--grey-900-hsl), 0.6);
--tag-color: var(--grey-50);
--table-row-hover-background-color: var(--grey-100);
--dropdown-item-hover-background-color: var(--grey-100);
--dropdown-item-hover-color: var(--text);
--button-text-hover-background-color: var(--grey-200);
--button-hover-color: var(--grey-600);
// Custom color variables we need to override
--card-border-color: hsla(var(--grey-100-hsl), 0.3);
--logo-text-color: var(--grey-700);
}
}

View file

@ -0,0 +1,22 @@
:root {
--shadow-xs: 0 1px 3px hsla(var(--grey-500-hsl), .12),
0 1px 2px hsla(var(--grey-500-hsl), .24);
--shadow-sm: 0 3px 6px hsla(var(--grey-500-hsl), .12),
0 2px 4px hsla(var(--grey-500-hsl), .10);
--shadow-md: 0 10px 20px hsla(var(--grey-500-hsl), .12),
0 3px 6px hsla(var(--grey-500-hsl), .08);
--shadow-lg: 0 15px 25px hsla(var(--grey-500-hsl), .12),
0 5px 10px hsla(var(--grey-500-hsl), .05);
&.dark {
// Even darker shadows for dark mode
--shadow-xs: 0 1px 3px hsla(var(--grey-50-hsl), 0.4),
0 1px 2px hsla(var(--grey-50-hsl), 0.8);
--shadow-sm: 0 3px 6px hsla(var(--grey-50-hsl), 0.8),
0 2px 4px hsla(var(--grey-50-hsl), 0.6);
--shadow-md: 0 10px 20px hsla(var(--grey-50-hsl), 0.8),
0 3px 6px hsla(var(--grey-50-hsl), 0.6);
--shadow-lg: 0 15px 25px hsla(var(--grey-50-hsl), 0.8),
0 5px 10px hsla(var(--grey-50-hsl), 0.4);
}
}

View file

@ -1,6 +1,6 @@
$font-files-path: '/fonts/';
/* quicksand-regular - latin */
// quicksand-regular - latin
@font-face {
font-family: 'Quicksand';
font-style: normal;
@ -10,7 +10,7 @@ $font-files-path: '/fonts/';
}
/* quicksand-500 - latin */
// quicksand-500 - latin
@font-face {
font-family: 'Quicksand';
font-style: normal;
@ -19,7 +19,7 @@ $font-files-path: '/fonts/';
src: url($font-files-path + 'quicksand-v7-latin-500.woff2') format('woff2');
}
/* quicksand-700 - latin */
// quicksand-700 - latin
@font-face {
font-family: 'Quicksand';
font-style: normal;
@ -28,7 +28,7 @@ $font-files-path: '/fonts/';
src: url($font-files-path + 'quicksand-v7-latin-700.woff2') format('woff2');
}
/* open-sans-regular - latin */
// open-sans-regular - latin
@font-face {
font-family: 'Open Sans';
font-style: normal;
@ -37,7 +37,7 @@ $font-files-path: '/fonts/';
src: url($font-files-path + 'open-sans-v15-latin-regular.woff2') format('woff2');
}
/* open-sans-italic - latin */
// open-sans-italic - latin
@font-face {
font-family: 'Open Sans';
font-style: italic;
@ -46,7 +46,7 @@ $font-files-path: '/fonts/';
src: url($font-files-path + 'open-sans-v15-latin-italic.woff2') format('woff2');
}
/* open-sans-700 - latin */
// open-sans-700 - latin
@font-face {
font-family: 'Open Sans';
font-style: normal;
@ -55,7 +55,7 @@ $font-files-path: '/fonts/';
src: url($font-files-path + 'open-sans-v15-latin-700.woff2') format('woff2');
}
/* open-sans-700italic - latin */
// open-sans-700italic - latin
@font-face {
font-family: 'Open Sans';
font-style: italic;

View file

@ -5,13 +5,15 @@
// This imports are the same as in "bulma/bulma.sass"
// with the expeption of the bulma utilities.
// They are imported globally in variables.scss
@import "bulma/sass/base/_all";
@import "bulma/sass/elements/_all";
@import "bulma/sass/form/_all";
@import "bulma/sass/components/_all";
@import "bulma/sass/grid/_all";
@import "bulma/sass/helpers/_all";
@import "bulma/sass/layout/_all";
@import "bulma-css-variables/sass/base/_all";
@import "bulma-css-variables/sass/elements/_all";
@import "bulma-css-variables/sass/form/_all";
@import "bulma-css-variables/sass/components/_all";
@import "bulma-css-variables/sass/grid/_all";
@import "bulma-css-variables/sass/helpers/_all";
@import "bulma-css-variables/sass/layout/_all";
@import "theme";
@import "components";
@import "components";
@import "custom-properties";

View file

@ -8,7 +8,7 @@
// FIXME: move to pagination component
.pagination-link:not(.is-current) {
background: $light-background;
background: var(--grey-100);
}
.box,

View file

@ -6,7 +6,7 @@
}
.table.has-actions {
border-top: 1px solid $grey-100;
border-top: 1px solid var(--grey-100);
border-radius: 4px;
overflow: hidden;

View file

@ -1,7 +1,7 @@
$scrollbar-height: 8px;
$scrollbar-track-color: $grey-200;
$scrollbar-thumb-color: $grey-300;
$scrollbar-hover-color: $grey-500;
$scrollbar-track-color: var(--grey-200);
$scrollbar-thumb-color: var(--grey-300);
$scrollbar-hover-color: var(--grey-500);
// Chrome
::-webkit-scrollbar {

View file

@ -6,7 +6,7 @@
}
:focus {
box-shadow: 0 0 0 2px rgba($primary, 0.5);
box-shadow: 0 0 0 2px hsla(var(--primary-hsl), 0.5);
}
:focus:not(:focus-visible) {
@ -15,11 +15,11 @@
:focus-visible,
:-moz-focusring {
box-shadow: 0 0 0 2px rgba($primary, 0.5);
box-shadow: 0 0 0 2px hsla(var(--primary-hsl), 0.5);
}
body {
background: $light-background;
background: var(--site-background);
min-height: 100vh;
}
@ -45,7 +45,7 @@ h6 {
&::-moz-progress-bar,
&::-webkit-progress-value {
background: $grey-500;
background: var(--grey-500);
}
@media screen and (max-width: $tablet) {
@ -94,11 +94,11 @@ button.table {
}
.icon:not(.has-text-success) {
color: $grey-300 !important;
color: var(--grey-300) !important;
}
&.has-text-danger .icon {
color: $danger !important;
color: var(--danger) !important;
}
&.is-disabled {
@ -140,7 +140,7 @@ button.table {
}
.dropdown-menu .dropdown-content {
box-shadow: $shadow-md;
box-shadow: var(--shadow-md);
}
.is-strikethrough {
@ -156,6 +156,6 @@ button.table {
}
.box {
border: 1px solid $grey-200;
box-shadow: $shadow-sm;
border: 1px solid var(--grey-200);
box-shadow: var(--shadow-sm);
}

View file

@ -1,12 +0,0 @@
@import "colors";
@import "shadows";
@import "variables";
// the default values get overwritten by the definitions above
@import "bulma/sass/utilities/_all";
// this is needed so that the shared form variables are globally defined aswell
@import "bulma/sass/form/shared";
// since $tablet is defined by bulma we can just define it after importing the utilities
$mobile: math.div($tablet, 2);

View file

@ -1,18 +0,0 @@
$grey-50: #F9FAFB;
$grey-100: #f3f4f6;
$grey-200: #E5E7EB;
$grey-300: #D1D5DB;
$grey-400: #9CA3AF;
$grey-500: #6B7280;
$grey-600: #4B5563;
$grey-700: #374151;
$grey-800: #1F2937;
$grey-900: #111827;
// Bulma defaults
$grey-dark: $grey-800;
$grey-darker: $grey-700;
$grey: $grey-500;
$grey-light: $grey-300;
$grey-lighter: $grey-200;
$grey-lightest: $grey-100;

View file

@ -1,5 +0,0 @@
$shadow-xs: 0 1px 3px rgba($grey-500, .12), 0 1px 2px rgba($grey-500, .24);
$shadow-sm: 0 3px 6px rgba($grey-500, .12), 0 2px 4px rgba($grey-500, .10);
$shadow-md: 0 10px 20px rgba($grey-500, .12), 0 3px 6px rgba($grey-500, .08);
$shadow-lg: 0 15px 25px rgba($grey-500, .12), 0 5px 10px rgba($grey-500, .05);
$shadow-xl: 0 20px 40px rgba($grey-500, .2);

View file

@ -1,41 +0,0 @@
$white: #fff;
$black: hsl(0, 0%, 4%) !default;
$orange: #ff851b;
$green: #00db60;
$red: #ff4136;
$blue: #1973ff;
$primary: $blue;
$info-invert: $white;
$family-sans-serif: 'Open Sans', Helvetica, Arial, sans-serif;
$vikunja-font: 'Quicksand', sans-serif;
$thickness: 1px;
$pagination-current-border: $primary;
$navbar-item-active-color: $primary;
$dropdown-content-shadow: none;
$dropdown-item-hover-background-color: $grey-100;
$bulmaswatch-import-font: false !default;
$light-background: $grey-100;
$transition-duration: 150ms;
$transition: $transition-duration ease;
$button-height: 34px;
$switch-view-height: 2.69rem;
$user-dropdown-width-mobile: 5rem;
$hamburger-menu-icon-spacing: 1rem;
$hamburger-menu-icon-width: 28px;
$navbar-height: 4rem;
$navbar-width: 300px;
$navbar-icon-width: 40px;
$lists-per-row: 5;
$list-height: 150px;
$list-spacing: 1rem;

View file

@ -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);
}
}
}

View file

@ -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;
}

View file

@ -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);
}
}
}

View file

@ -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;

View file

@ -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>

View file

@ -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;
}

View file

@ -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;

View file

@ -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>

View file

@ -68,7 +68,7 @@ ul.teams {
transition: background-color $transition;
&:hover {
background: $grey-100;
background: var(--grey-100);
}
}
}

View file

@ -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);
}
}
}

View file

@ -149,6 +149,6 @@ export default {
}
.vue-advanced-cropper__background {
background: $white;
background: var(--white);
}
</style>

View file

@ -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')}`)
},

View file

@ -9,8 +9,8 @@ import svgLoader from 'vite-svg-loader'
const pathSrc = path.resolve(__dirname, './src')
// the @use rules have to be the first in the compiled stylesheets
const SCSS_IMPORT_PREFIX = `@use "sass:math";
@import "${pathSrc}/styles/variables";`
const PREFIXED_SCSS_STYLES = `@use "sass:math";
@import "${pathSrc}/styles/common-imports";`
const isModernBuild = Boolean(process.env.BUILD_MODERN_ONLY)
const legacy = isModernBuild
@ -29,7 +29,10 @@ if (isModernBuild) {
export default defineConfig({
css: {
preprocessorOptions: {
scss: { additionalData: SCSS_IMPORT_PREFIX },
scss: {
additionalData: PREFIXED_SCSS_STYLES,
charset: false, // fixes "@charset" must be the first rule in the file" warnings
},
},
},
plugins: [

View file

@ -3727,6 +3727,21 @@
resolved "https://registry.yarnpkg.com/@vue/shared/-/shared-3.2.22.tgz#26dcbe5e530f6c1f2de5ca9aeab92ab00f523b41"
integrity sha512-qWVav014mpjEtbWbEgl0q9pEyrrIySKum8UVYjwhC6njrKzknLZPvfuYdQyVbApsqr94tf/3dP4pCuZmmjdCWQ==
"@vueuse/core@^6.8.0":
version "6.9.2"
resolved "https://registry.yarnpkg.com/@vueuse/core/-/core-6.9.2.tgz#76b16d01f33cf367dd1a2d7f2e31d106443ceb8a"
integrity sha512-FRwl4ccSFuHZBHLGgS9TMv/+Dd6XFaL4o9nph2qtgQIV+z29RBFokw08XjHfykiENRzB01MjYHJ7iRUnsIFQXg==
dependencies:
"@vueuse/shared" "6.9.2"
vue-demi "*"
"@vueuse/shared@6.9.2":
version "6.9.2"
resolved "https://registry.yarnpkg.com/@vueuse/shared/-/shared-6.9.2.tgz#97e4369fa7262ebc96fe1d6e210268f30b037005"
integrity sha512-lAiMh6XROs0kSKVd0Yb/6GKoQMxC1fYrFDi6opvQWISPtcqRNluRrQxLUZ3WTI78ovtoKRLktjhkFAtydcfFDg==
dependencies:
vue-demi "*"
abab@^2.0.3, abab@^2.0.5:
version "2.0.5"
resolved "https://registry.yarnpkg.com/abab/-/abab-2.0.5.tgz#c0b678fb32d60fc1219c784d6a826fe385aeb79a"
@ -4631,10 +4646,10 @@ builtins@^1.0.3:
resolved "https://registry.yarnpkg.com/builtins/-/builtins-1.0.3.tgz#cb94faeb61c8696451db36534e1422f94f0aee88"
integrity sha1-y5T662HIaWRR2zZTThQi+U8K7og=
bulma@0.9.3:
version "0.9.3"
resolved "https://registry.yarnpkg.com/bulma/-/bulma-0.9.3.tgz#ddccb7436ebe3e21bf47afe01d3c43a296b70243"
integrity sha512-0d7GNW1PY4ud8TWxdNcP6Cc8Bu7MxcntD/RRLGWuiw/s0a9P+XlH/6QoOIrmbj6o8WWJzJYhytiu9nFjTszk1g==
bulma-css-variables@^0.9.33:
version "0.9.33"
resolved "https://registry.yarnpkg.com/bulma-css-variables/-/bulma-css-variables-0.9.33.tgz#b249c3410e9edcfa7a5ce8ca96049b6939fe92de"
integrity sha512-D85dXLyLOBBDCuSSOeASc0kN2IknJqo5hzkZ22hxDHobxko/qay0nD+zNl2CJtF8v/7iwvQXqzVSDRnFVRSg9A==
byline@^5.0.0:
version "5.0.0"
@ -13970,6 +13985,11 @@ vue-advanced-cropper@2.7.0:
debounce "^1.2.0"
easy-bem "^1.0.2"
vue-demi@*:
version "0.12.1"
resolved "https://registry.yarnpkg.com/vue-demi/-/vue-demi-0.12.1.tgz#f7e18efbecffd11ab069d1472d7a06e319b4174c"
integrity sha512-QL3ny+wX8c6Xm1/EZylbgzdoDolye+VpCXRhI2hug9dJTP3OUJ3lmiKN3CsVV3mOJKwFi0nsstbgob0vG7aoIw==
vue-drag-resize@2.0.3:
version "2.0.3"
resolved "https://registry.yarnpkg.com/vue-drag-resize/-/vue-drag-resize-2.0.3.tgz#1faf0813f43304205bb355fbb3dacc548dd9398a"