skeleton loader

This commit is contained in:
2023-05-20 14:54:41 +02:00
parent 7c40017b05
commit b71bffc064
8 changed files with 143 additions and 59 deletions

3
components.d.ts vendored
View File

@@ -25,6 +25,9 @@ declare module '@vue/runtime-core' {
SideBar: typeof import('./src/components/SideBar.vue')['default'] SideBar: typeof import('./src/components/SideBar.vue')['default']
SideBarMenu: typeof import('./src/components/SideBar/SideBarMenu.vue')['default'] SideBarMenu: typeof import('./src/components/SideBar/SideBarMenu.vue')['default']
SideBarMenuItem: typeof import('./src/components/SideBar/SideBarMenuItem.vue')['default'] SideBarMenuItem: typeof import('./src/components/SideBar/SideBarMenuItem.vue')['default']
SkeletonNote: typeof import('./src/components/Skeleton/SkeletonNote.vue')['default']
SkeletonSidebarItem: typeof import('./src/components/Skeleton/SkeletonSidebarItem.vue')['default']
SkeletonTopBar: typeof import('./src/components/Skeleton/SkeletonTopBar.vue')['default']
TopBar: typeof import('./src/components/TopBar.vue')['default'] TopBar: typeof import('./src/components/TopBar.vue')['default']
} }
} }

View File

@@ -1,6 +1,7 @@
<script setup lang="ts"> <script setup lang="ts">
import { activeNote, updateNote } from '@/composables/useNotes' import { activeNote, updateNote } from '@/composables/useNotes'
import { viewModes, activeViewMode } from '@/composables/useViewMode' import { viewModes, activeViewMode } from '@/composables/useViewMode'
import { initialized } from '@/composables/useFirebase'
const sideBarCollapsed = ref(false) const sideBarCollapsed = ref(false)
</script> </script>
@@ -20,15 +21,18 @@ const sideBarCollapsed = ref(false)
class="transition[margin-left] z-10 mt-[50px] w-full border-x-[1px] bg-white px-10 py-6 duration-200 ease-out" class="transition[margin-left] z-10 mt-[50px] w-full border-x-[1px] bg-white px-10 py-6 duration-200 ease-out"
:class="sideBarCollapsed ? 'ml-0' : 'ml-sidebar'" :class="sideBarCollapsed ? 'ml-0' : 'ml-sidebar'"
> >
<Note <template v-if="initialized">
v-if="activeViewMode.name === 'Note' && activeNote" <Note
:key="activeNote.id" v-if="activeViewMode.name === 'Note' && activeNote"
:note="activeNote" :key="activeNote.id"
class="" :note="activeNote"
@update="(note) => updateNote(note.id, note)" class=""
/> @update="(note) => updateNote(note.id, note)"
<ListView v-else-if="activeViewMode.name === 'List'" /> />
<Mindmap v-else-if="activeViewMode.name === 'Mindmap'" /> <ListView v-else-if="activeViewMode.name === 'List'" />
<Mindmap v-else-if="activeViewMode.name === 'Mindmap'" />
</template>
<SkeletonNote v-else />
</main> </main>
</div> </div>
</template> </template>

View File

@@ -47,7 +47,7 @@ const handleKeydown = (event: KeyboardEvent) => {
<input <input
type="text" type="text"
placeholder="Search for notes" placeholder="Search for notes"
class="h-full w-full rounded border-0 bg-[#355fd3] px-2 text-white outline-none placeholder:text-white focus:bg-white focus:text-black" class="h-full w-full rounded border-0 bg-white/10 px-2 text-white outline-none placeholder:text-white focus:bg-white focus:text-black"
@focus="active = true" @focus="active = true"
@mousedown="active = true" @mousedown="active = true"
@blur="active = false" @blur="active = false"

View File

@@ -1,5 +1,6 @@
<script setup lang="ts"> <script setup lang="ts">
import { rootNote, notes, setActiveNote } from '@/composables/useNotes' import { rootNote, notes, setActiveNote } from '@/composables/useNotes'
import { initialized } from '@/composables/useFirebase'
const props = defineProps<{ const props = defineProps<{
viewModes: ViewMode[] viewModes: ViewMode[]
@@ -22,23 +23,28 @@ const emit = defineEmits<{
icon="fas fa-fw fa-home" icon="fas fa-fw fa-home"
@click="setActiveNote(rootNote?.id)" @click="setActiveNote(rootNote?.id)"
:title="rootNote?.title" :title="rootNote?.title"
v-if="initialized"
> >
{{ rootNote?.title }} {{ rootNote?.title }}
</SideBarMenuItem> </SideBarMenuItem>
<SkeletonSidebarItem v-else />
</template> </template>
</SideBarMenu> </SideBarMenu>
<SideBarMenu> <SideBarMenu>
<template #header>View mode</template> <template #header>View mode</template>
<template #items> <template #items>
<SideBarMenuItem <template v-if="initialized">
v-for="viewMode in props.viewModes" <SideBarMenuItem
:key="viewMode.name" v-for="viewMode in props.viewModes"
:icon="viewMode.icon" :key="viewMode.name"
:active="viewMode.name === activeViewMode.name" :icon="viewMode.icon"
@click="emit('setViewMode', viewMode)" :active="viewMode.name === activeViewMode.name"
> @click="emit('setViewMode', viewMode)"
{{ viewMode.name }} >
</SideBarMenuItem> {{ viewMode.name }}
</SideBarMenuItem>
</template>
<SkeletonSidebarItem :n="3" v-else />
</template> </template>
</SideBarMenu> </SideBarMenu>
<SideBarMenu> <SideBarMenu>
@@ -47,15 +53,18 @@ const emit = defineEmits<{
Recent notes Recent notes
</template> </template>
<template #items> <template #items>
<SideBarMenuItem <template v-if="initialized">
v-for="note in notes.slice(-10)" <SideBarMenuItem
:key="note.id" v-for="note in notes.slice(-10)"
icon="far fa-file-alt fa-fw" :key="note.id"
@click="setActiveNote(note.id)" icon="far fa-file-alt fa-fw"
:title="rootNote?.title" @click="setActiveNote(note.id)"
> :title="rootNote?.title"
{{ note.title }} >
</SideBarMenuItem> {{ note.title }}
</SideBarMenuItem>
</template>
<SkeletonSidebarItem v-else :n="5" />
</template> </template>
</SideBarMenu> </SideBarMenu>
</div> </div>

View File

@@ -0,0 +1,30 @@
<template>
<div class="flex h-full w-full animate-pulse flex-col">
<div class="mb-2 flex items-center space-x-4 py-1">
<div class="h-[2.25rem] w-[40px] rounded bg-secondary"></div>
<div class="h-[2.25rem] flex-grow rounded bg-secondary"></div>
</div>
<div class="flex flex-grow flex-col gap-2">
<div class="h-[1.25rem] my-1 w-full rounded bg-secondary"></div>
<div class="h-[1.25rem] my-1 w-full rounded bg-secondary"></div>
<div class="h-[1.25rem] my-1 w-5/12 rounded bg-secondary"></div>
<div class="mt-2 h-[2rem] w-full rounded bg-secondary"></div>
<div class="h-[1.25rem] my-1 w-full rounded bg-secondary"></div>
<div class="h-[1.25rem] my-1 w-4/6 rounded bg-secondary"></div>
<div class="ml-8 h-[1.25rem] my-1 w-5/12 rounded bg-secondary"></div>
<div class="ml-8 h-[1.25rem] my-1 w-7/12 rounded bg-secondary"></div>
<div class="ml-8 h-[1.25rem] my-1 w-6/12 rounded bg-secondary"></div>
<div class="h-[1.25rem] my-1 w-full rounded bg-secondary"></div>
</div>
<hr class="my-3" />
<div class="flex gap-2">
<div class="h-[1.25rem] w-2/12 rounded bg-secondary"></div>
<div class="h-[1.25rem] w-4/12 rounded bg-secondary ml-auto"></div>
</div>
</div>
</template>
<style scoped>
.bg-secondary {
@apply bg-secondary/25;
}
</style>

View File

@@ -0,0 +1,18 @@
<script setup lang="ts">
const props = withDefaults(
defineProps<{
n?: number
}>(),
{ n: 1 }
)
</script>
<template>
<div class="flex w-full animate-pulse flex-col">
<div class="h-[1.35rem] w-full rounded bg-secondary mt-1" v-for="i in props.n" :key="i"></div>
</div>
</template>
<style scoped>
.bg-secondary {
@apply bg-secondary/25;
}
</style>

View File

@@ -0,0 +1,18 @@
<template>
<div class="flex h-full w-full animate-pulse">
<div class="h-full w-full rounded bg-white/10"></div>
</div>
<!-- <div class="flex animate-pulse space-x-4 max-w-sm">
<div class="h-10 w-10 rounded-full bg-primary"></div>
<div class="flex-1 space-y-6 py-1">
<div class="h-2 rounded bg-primary"></div>
<div class="space-y-3">
<div class="grid grid-cols-3 gap-4">
<div class="col-span-2 h-2 rounded bg-primary"></div>
<div class="col-span-1 h-2 rounded bg-primary"></div>
</div>
<div class="h-2 rounded bg-primary"></div>
</div>
</div>
</div> -->
</template>

View File

@@ -39,37 +39,39 @@ const authModalInitialStateOpen = ref(
/> />
</div> </div>
<div class="flex h-full flex-grow flex-row items-center gap-2 pl-5 pr-3"> <div class="flex h-full flex-grow flex-row items-center gap-2 pl-5 pr-3">
<SearchBar /> <template v-if="initialized">
<button <SearchBar />
class="btn-outline btn-sm btn py-1 text-white" <button
@click="addNote('Untitled new note', '', true)" class="btn-outline btn-sm btn py-1 text-white"
> @click="addNote('Untitled new note', '', true)"
<i class="fas fa-plus-circle text-[1.1rem]" /> >
</button> <i class="fas fa-plus-circle text-[1.1rem]" />
<Modal v-if="initialized && !user" :open="authModalInitialStateOpen"> </button>
<template #activator="{ open }"> <Modal v-if="initialized && !user" :open="authModalInitialStateOpen">
<button class="btn-outline btn-sm btn py-1 text-white" @click="open">Sign in</button> <template #activator="{ open }">
</template> <button class="btn-outline btn-sm btn py-1 text-white" @click="open">Sign in</button>
<template #default="{ close }"> </template>
<Auth @signedIn="close" /> <template #default="{ close }">
</template> <Auth @signedIn="close" />
<template #actions="{ close }"> </template>
<button class="btn-sm btn" @click="close">Close</button> <template #actions="{ close }">
</template> <button class="btn-sm btn" @click="close">Close</button>
</Modal> </template>
<Modal v-else-if="user"> </Modal>
<template #activator="{ open }"> <Modal v-else-if="user">
<button class="btn-outline btn-sm btn py-1 text-white" @click="open"> <template #activator="{ open }">
{{ user.displayName || user.email }} <button class="btn-outline btn-sm btn py-1 text-white" @click="open">
</button> {{ user.displayName || user.email }}
</template> </button>
<template #default>Are you sure want to signout?</template> </template>
<template #actions="{ close }"> <template #default>Are you sure want to signout?</template>
<button class="btn-sm btn" @click="close">Close</button> <template #actions="{ close }">
<button class="btn-primary btn-sm btn" @click="signOut(close)">Sign out</button> <button class="btn-sm btn" @click="close">Close</button>
</template> <button class="btn-primary btn-sm btn" @click="signOut(close)">Sign out</button>
</Modal> </template>
<template v-else>Loading...</template> </Modal>
</template>
<SkeletonTopBar v-else />
</div> </div>
</div> </div>
</div> </div>