skeleton loader
This commit is contained in:
3
components.d.ts
vendored
3
components.d.ts
vendored
@@ -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']
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
22
src/App.vue
22
src/App.vue
@@ -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>
|
||||||
|
|||||||
@@ -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"
|
||||||
|
|||||||
@@ -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>
|
||||||
|
|||||||
30
src/components/Skeleton/SkeletonNote.vue
Normal file
30
src/components/Skeleton/SkeletonNote.vue
Normal 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>
|
||||||
18
src/components/Skeleton/SkeletonSidebarItem.vue
Normal file
18
src/components/Skeleton/SkeletonSidebarItem.vue
Normal 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>
|
||||||
18
src/components/Skeleton/SkeletonTopBar.vue
Normal file
18
src/components/Skeleton/SkeletonTopBar.vue
Normal 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>
|
||||||
@@ -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>
|
||||||
|
|||||||
Reference in New Issue
Block a user