Browse Source

feat(gui-v2): add dark mode to state and some styles

Signed-off-by: Braks <78412429+bcakmakoglu@users.noreply.github.com>
pull/2716/head
Braks 2 years ago committed by Pranav C
parent
commit
f149e37d61
  1. 2
      packages/nc-gui-v2/app.vue
  2. 17
      packages/nc-gui-v2/assets/style-v2.css
  3. 20
      packages/nc-gui-v2/components/general/ColorModeSwitcher.vue
  4. 6
      packages/nc-gui-v2/components/general/Sponsors.vue
  5. 4
      packages/nc-gui-v2/composables/useColors.ts
  6. 5
      packages/nc-gui-v2/composables/useGlobalState.ts
  7. 6
      packages/nc-gui-v2/pages/projects/index.vue
  8. 2
      packages/nc-gui-v2/pages/projects/index/list.vue
  9. 11
      packages/nc-gui-v2/plugins/state.ts

2
packages/nc-gui-v2/app.vue

@ -43,6 +43,8 @@ const signOut = () => {
<release-info /> <release-info />
--> -->
<general-color-mode-switcher v-model="$state.darkMode.value" />
<general-language class="mr-3" /> <general-language class="mr-3" />
<template v-if="$state.signedIn.value"> <template v-if="$state.signedIn.value">

17
packages/nc-gui-v2/assets/style-v2.css

@ -2,25 +2,28 @@ html,
body, body,
#__nuxt, #__nuxt,
.v-application__wrap { .v-application__wrap {
margin: 0 !important; @apply m-0 h-[100vh] w-[100vw] bg-white dark:(bg-black text-white);
height: 100vh;
width: 100vw;
} }
html, body { nav,
@apply scrollbar-thin-primary; nav .v-list {
@apply dark:(bg-gray-900 text-white)
}
.v-divider {
@apply dark:bg-white
} }
.page-enter-active, .page-enter-active,
.page-leave-active, .page-leave-active,
.layout-enter-active, .layout-enter-active,
.layout-leave-active { .layout-leave-active {
transition: opacity .5s @apply transition-opacity duration-300 ease-in-out;
} }
.page-enter, .page-enter,
.page-leave-active, .page-leave-active,
.layout-enter, .layout-enter,
.layout-leave-active { .layout-leave-active {
opacity: 0 @apply opacity-0;
} }

20
packages/nc-gui-v2/components/general/ColorModeSwitcher.vue

@ -0,0 +1,20 @@
<script lang="ts" setup>
import MaterialSymbolsLightMode from '~icons/material-symbols/light-mode'
import MaterialSymbolsDarkMode from '~icons/material-symbols/dark-mode'
interface Props {
modelValue: boolean
}
const { modelValue } = defineProps<Props>()
const emits = defineEmits(['update:modelValue'])
const toggleMode = () => {
emits('update:modelValue', !modelValue)
}
</script>
<template>
<MaterialSymbolsLightMode v-if="modelValue" class="md:text-xl cursor-pointer" @click="toggleMode" />
<MaterialSymbolsDarkMode v-else class="md:text-xl cursor-pointer" @click="toggleMode" />
</template>

6
packages/nc-gui-v2/components/general/Sponsors.vue

@ -9,8 +9,8 @@ const { nav = false } = defineProps<Props>()
</script> </script>
<template> <template>
<v-card :rounded="0" max-width="300" class="pb-3" href="https://github.com/sponsors/nocodb" target="_blank"> <v-card :rounded="0" class="dark:bg-gray-900" href="https://github.com/sponsors/nocodb" target="_blank">
<v-img src="/ants-leaf-cutter.jpeg" :cover="true" :aspect-ratio="1" :height="nav ? 80 : ''" class="mt-0" /> <v-img src="/ants-leaf-cutter.jpeg" :cover="true" :aspect-ratio="1" :height="nav ? 80 : ''" />
<v-card-title v-if="!nav" class="pb-2"> <v-card-title v-if="!nav" class="pb-2">
{{ $t('msg.info.sponsor.header') }} {{ $t('msg.info.sponsor.header') }}
@ -21,7 +21,7 @@ const { nav = false } = defineProps<Props>()
</v-card-text> </v-card-text>
<v-card-actions class="justify-center"> <v-card-actions class="justify-center">
<v-btn color="primary"> <v-btn class="dark:(!text-white) text-primary">
<MdiHeartsCard class="text-red-500 mr-2" /> <MdiHeartsCard class="text-red-500 mr-2" />
{{ $t('activity.sponsorUs') }} {{ $t('activity.sponsorUs') }}
</v-btn> </v-btn>

4
packages/nc-gui-v2/composables/useColors.ts

@ -9,11 +9,11 @@ export default function useColors(darkMode?: MaybeRef<boolean>) {
let mode = $ref(unref(darkMode)) let mode = $ref(unref(darkMode))
const { $state } = useNuxtApp() const { $state } = useNuxtApp()
if (!mode) mode = $state.darkMode.value if (typeof mode === 'undefined') mode = $state.darkMode.value
scope.run(() => { scope.run(() => {
watch($state.darkMode, (newMode) => { watch($state.darkMode, (newMode) => {
mode = newMode if (typeof mode === 'undefined') mode = newMode
}) })
watchEffect(() => { watchEffect(() => {

5
packages/nc-gui-v2/composables/useGlobalState.ts

@ -26,7 +26,8 @@ export const useGlobalState = (): GlobalState => {
/** get the preferred languages of a user, according to browser settings */ /** get the preferred languages of a user, according to browser settings */
const preferredLanguages = $(usePreferredLanguages()) const preferredLanguages = $(usePreferredLanguages())
/** get the preferred dark mode setting, according to browser settings */ /** get the preferred dark mode setting, according to browser settings */
const darkMode = $(usePreferredDark()) const prefersDarkMode = $(usePreferredDark())
/** reactive timestamp to check token expiry against */ /** reactive timestamp to check token expiry against */
const timestamp = $(useTimestamp({ immediate: true, interval: 100 })) const timestamp = $(useTimestamp({ immediate: true, interval: 100 }))
@ -62,7 +63,7 @@ export const useGlobalState = (): GlobalState => {
}, 'en' /** fallback locale */) }, 'en' /** fallback locale */)
/** State */ /** State */
const initialState: State = { token: null, user: null, lang: preferredLanguage, darkMode } const initialState: State = { token: null, user: null, lang: preferredLanguage, darkMode: prefersDarkMode }
/** saves a reactive state, any change to these values will write/delete to localStorage */ /** saves a reactive state, any change to these values will write/delete to localStorage */
const storage = $(useStorage<State>(storageKey, initialState)) const storage = $(useStorage<State>(storageKey, initialState))

6
packages/nc-gui-v2/pages/projects/index.vue

@ -30,7 +30,7 @@ const navDrawerOptions = [
const route = useRoute() const route = useRoute()
const { $api } = useNuxtApp() const { $api, $state } = useNuxtApp()
const response = await $api.project.list({}) const response = await $api.project.list({})
const projects = $ref(response.list) const projects = $ref(response.list)
@ -46,7 +46,7 @@ const activePage = $ref(navDrawerOptions[0].title)
<v-menu class="select-none"> <v-menu class="select-none">
<template #activator="{ props }"> <template #activator="{ props }">
<div <div
class="mr-auto select-none flex items-center gap-2 leading-8 cursor-pointer rounded-full border-1 border-gray-300 px-5 py-2 shadow prose-lg font-semibold hover:bg-gray-200/20" class="bg-white mr-auto select-none flex items-center gap-2 leading-8 cursor-pointer rounded-full border-1 border-gray-300 px-5 py-2 shadow prose-lg font-semibold hover:(!bg-gray-100)"
@click="props.onClick" @click="props.onClick"
> >
<MdiPlus class="text-primary text-2xl" /> <MdiPlus class="text-primary text-2xl" />
@ -73,7 +73,7 @@ const activePage = $ref(navDrawerOptions[0].title)
</div> </div>
<div class="advance-menu flex-1"> <div class="advance-menu flex-1">
<v-list class="flex flex-col gap-1" color="primary"> <v-list class="flex flex-col gap-1" :color="$state.darkMode.value ? 'default' : 'primary'">
<!-- todo: v-list-item-group doesn't seem to work with vuetify 3 yet ... --> <!-- todo: v-list-item-group doesn't seem to work with vuetify 3 yet ... -->
<v-list-item <v-list-item
v-for="item in navDrawerOptions" v-for="item in navDrawerOptions"

2
packages/nc-gui-v2/pages/projects/index/list.vue

@ -28,7 +28,7 @@ const openProject = async (project: ProjectType) => {
<template v-for="project of projects" :key="project.id"> <template v-for="project of projects" :key="project.id">
<div <div
class="cursor-pointer grid grid-cols-3 gap-2 prose-md hover:(bg-gray-100 shadow-sm) p-2 transition-color ease-in duration-100" class="cursor-pointer grid grid-cols-3 gap-2 prose-md hover:(bg-gray-100 shadow-sm dark:text-black) p-2 transition-color ease-in duration-100"
@click="openProject(project)" @click="openProject(project)"
> >
<div class="font-semibold">{{ project.title || 'Untitled' }}</div> <div class="font-semibold">{{ project.title || 'Untitled' }}</div>

11
packages/nc-gui-v2/plugins/state.ts

@ -1,4 +1,5 @@
import { defineNuxtPlugin } from '#app' import { defineNuxtPlugin } from '#app'
import { useDark, watch } from '#imports'
import { useGlobalState } from '~/composables/useGlobalState' import { useGlobalState } from '~/composables/useGlobalState'
/** /**
@ -15,9 +16,19 @@ import { useGlobalState } from '~/composables/useGlobalState'
*/ */
export default defineNuxtPlugin((nuxtApp) => { export default defineNuxtPlugin((nuxtApp) => {
const storage = useGlobalState() const storage = useGlobalState()
const darkMode = useDark()
/** set i18n locale to stored language */ /** set i18n locale to stored language */
nuxtApp.vueApp.i18n.locale.value = storage.lang.value nuxtApp.vueApp.i18n.locale.value = storage.lang.value
/** set current dark mode from storage */
watch(
storage.darkMode,
(newMode) => {
darkMode.value = newMode
},
{ immediate: true },
)
nuxtApp.provide('state', storage) nuxtApp.provide('state', storage)
}) })

Loading…
Cancel
Save