skeleton loader

This commit is contained in:
2023-05-20 14:54:41 +02:00
parent 7e7bb41a27
commit f61be632a0
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']
SideBarMenu: typeof import('./src/components/SideBar/SideBarMenu.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']
}
}

View File

@@ -1,6 +1,7 @@
<script setup lang="ts">
import { activeNote, updateNote } from '@/composables/useNotes'
import { viewModes, activeViewMode } from '@/composables/useViewMode'
import { initialized } from '@/composables/useFirebase'
const sideBarCollapsed = ref(false)
</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="sideBarCollapsed ? 'ml-0' : 'ml-sidebar'"
>
<Note
v-if="activeViewMode.name === 'Note' && activeNote"
:key="activeNote.id"
:note="activeNote"
class=""
@update="(note) => updateNote(note.id, note)"
/>
<ListView v-else-if="activeViewMode.name === 'List'" />
<Mindmap v-else-if="activeViewMode.name === 'Mindmap'" />
<template v-if="initialized">
<Note
v-if="activeViewMode.name === 'Note' && activeNote"
:key="activeNote.id"
:note="activeNote"
class=""
@update="(note) => updateNote(note.id, note)"
/>
<ListView v-else-if="activeViewMode.name === 'List'" />
<Mindmap v-else-if="activeViewMode.name === 'Mindmap'" />
</template>
<SkeletonNote v-else />
</main>
</div>
</template>

View File

@@ -47,7 +47,7 @@ const handleKeydown = (event: KeyboardEvent) => {
<input
type="text"
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"
@mousedown="active = true"
@blur="active = false"

View File

@@ -1,5 +1,6 @@
<script setup lang="ts">
import { rootNote, notes, setActiveNote } from '@/composables/useNotes'
import { initialized } from '@/composables/useFirebase'
const props = defineProps<{
viewModes: ViewMode[]
@@ -22,23 +23,28 @@ const emit = defineEmits<{
icon="fas fa-fw fa-home"
@click="setActiveNote(rootNote?.id)"
:title="rootNote?.title"
v-if="initialized"
>
{{ rootNote?.title }}
</SideBarMenuItem>
<SkeletonSidebarItem v-else />
</template>
</SideBarMenu>
<SideBarMenu>
<template #header>View mode</template>
<template #items>
<SideBarMenuItem
v-for="viewMode in props.viewModes"
:key="viewMode.name"
:icon="viewMode.icon"
:active="viewMode.name === activeViewMode.name"
@click="emit('setViewMode', viewMode)"
>
{{ viewMode.name }}
</SideBarMenuItem>
<template v-if="initialized">
<SideBarMenuItem
v-for="viewMode in props.viewModes"
:key="viewMode.name"
:icon="viewMode.icon"
:active="viewMode.name === activeViewMode.name"
@click="emit('setViewMode', viewMode)"
>
{{ viewMode.name }}
</SideBarMenuItem>
</template>
<SkeletonSidebarItem :n="3" v-else />
</template>
</SideBarMenu>
<SideBarMenu>
@@ -47,15 +53,18 @@ const emit = defineEmits<{
Recent notes
</template>
<template #items>
<SideBarMenuItem
v-for="note in notes.slice(-10)"
:key="note.id"
icon="far fa-file-alt fa-fw"
@click="setActiveNote(note.id)"
:title="rootNote?.title"
>
{{ note.title }}
</SideBarMenuItem>
<template v-if="initialized">
<SideBarMenuItem
v-for="note in notes.slice(-10)"
:key="note.id"
icon="far fa-file-alt fa-fw"
@click="setActiveNote(note.id)"
:title="rootNote?.title"
>
{{ note.title }}
</SideBarMenuItem>
</template>
<SkeletonSidebarItem v-else :n="5" />
</template>
</SideBarMenu>
</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 class="flex h-full flex-grow flex-row items-center gap-2 pl-5 pr-3">
<SearchBar />
<button
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>
<Modal v-if="initialized && !user" :open="authModalInitialStateOpen">
<template #activator="{ open }">
<button class="btn-outline btn-sm btn py-1 text-white" @click="open">Sign in</button>
</template>
<template #default="{ close }">
<Auth @signedIn="close" />
</template>
<template #actions="{ close }">
<button class="btn-sm btn" @click="close">Close</button>
</template>
</Modal>
<Modal v-else-if="user">
<template #activator="{ open }">
<button class="btn-outline btn-sm btn py-1 text-white" @click="open">
{{ user.displayName || user.email }}
</button>
</template>
<template #default>Are you sure want to signout?</template>
<template #actions="{ close }">
<button class="btn-sm btn" @click="close">Close</button>
<button class="btn-primary btn-sm btn" @click="signOut(close)">Sign out</button>
</template>
</Modal>
<template v-else>Loading...</template>
<template v-if="initialized">
<SearchBar />
<button
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>
<Modal v-if="initialized && !user" :open="authModalInitialStateOpen">
<template #activator="{ open }">
<button class="btn-outline btn-sm btn py-1 text-white" @click="open">Sign in</button>
</template>
<template #default="{ close }">
<Auth @signedIn="close" />
</template>
<template #actions="{ close }">
<button class="btn-sm btn" @click="close">Close</button>
</template>
</Modal>
<Modal v-else-if="user">
<template #activator="{ open }">
<button class="btn-outline btn-sm btn py-1 text-white" @click="open">
{{ user.displayName || user.email }}
</button>
</template>
<template #default>Are you sure want to signout?</template>
<template #actions="{ close }">
<button class="btn-sm btn" @click="close">Close</button>
<button class="btn-primary btn-sm btn" @click="signOut(close)">Sign out</button>
</template>
</Modal>
</template>
<SkeletonTopBar v-else />
</div>
</div>
</div>