Skip to content

Commit

Permalink
#9 - Refactor & Added ContextMenu component
Browse files Browse the repository at this point in the history
  • Loading branch information
kristianbinau committed Oct 4, 2023
1 parent defbaad commit a1c4a72
Show file tree
Hide file tree
Showing 15 changed files with 251 additions and 167 deletions.
7 changes: 0 additions & 7 deletions src/components/Dashboard.astro

This file was deleted.

15 changes: 0 additions & 15 deletions src/components/Files/File.vue

This file was deleted.

21 changes: 0 additions & 21 deletions src/components/Files/Folder.vue

This file was deleted.

18 changes: 0 additions & 18 deletions src/components/Files/NoFiles.vue

This file was deleted.

47 changes: 47 additions & 0 deletions src/components/files/ContextMenu.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
<template>
<div class="relative" v-on:contextmenu.prevent="openMenu">
<slot name="content"></slot>
<div
v-if="showMenu"
ref="menu"
v-on:blur="closeMenu"
tabindex="-1"
:style="{ top: `${top}px`, left: `${left}px` }"
class="absolute z-10 block w-44 divide-y divide-gray-100 rounded-lg bg-white shadow dark:divide-gray-600 dark:bg-gray-700"
>
<slot name="menu"></slot>
</div>
</div>
</template>

<script setup lang="ts">
import { ref, onMounted, nextTick } from 'vue';
const menu = ref<HTMLElement | null>(null);
const showMenu = ref(false);
const top = ref(0);
const left = ref(0);
onMounted(() => console.log(menu.value));
function setMenu(y: number, x: number) {
top.value = y;
left.value = x;
}
function closeMenu() {
showMenu.value = false;
}
function openMenu(e: MouseEvent) {
showMenu.value = true;
nextTick(() => {
if (!menu.value) return;
menu.value.focus();
setMenu(e.offsetY, e.offsetX);
});
}
</script>
23 changes: 23 additions & 0 deletions src/components/files/File.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
<template>
<a
href="#"
class="block max-w-sm rounded-lg border border-gray-200 bg-white p-6 shadow hover:bg-gray-100 dark:border-gray-700 dark:bg-gray-800 dark:hover:bg-gray-700"
>
<h5 class="mb-2 text-2xl font-bold tracking-tight text-gray-900 dark:text-white">
{{ modelValue.name }}
</h5>
</a>
</template>

<script setup lang="ts">
import { type PropType } from 'vue';
import { FileClass } from '@lib/items';
defineProps({
modelValue: {
type: Object as PropType<FileClass>,
required: true,
},
});
defineEmits(['update:modelValue']);
</script>
Original file line number Diff line number Diff line change
Expand Up @@ -3,22 +3,33 @@
<NoFiles />
</template>
<template v-else>
<div>
<Folder v-for="folder in folders" :folder="folder" />
<div class="flex flex-wrap gap-3">
<Folder
v-for="folder in folders"
:modelValue="folder"
@update:modelValue="updateItem(folder)"
/>
</div>
<div>
<File v-for="file in files" :file="file" />
<div class="mt-3 flex flex-wrap gap-3">
<File v-for="file in files" :modelValue="file" @update:modelValue="updateItem(file)" />
</div>
</template>
</template>

<script setup lang="ts">
import { computed, ref } from 'vue';
import { computed, ref, type PropType } from 'vue';
import NoFiles from './NoFiles.vue';
import Folder from './Folder.vue';
import File from './File.vue';
import { FolderClass, FileClass, ItemClass } from '@lib/items';
const props = defineProps({
modelValue: {
type: Object as PropType<FolderClass>,
required: false,
},
});
/**
* Items
*/
Expand All @@ -27,13 +38,22 @@ const items = ref<ItemClass[]>([]);
getItems();
function getItems() {
console.log(props.modelValue instanceof FolderClass);
if (props.modelValue instanceof FolderClass) {
//
}
for (let i = 0; i < 29; i++) {
const item =
Math.random() > 0.5 ? FolderClass.create(randomName(), null) : FileClass.create(randomName(), null);
Math.random() > 0.5 ? FolderClass.create('jkghk', null) : FileClass.create('grffrw', null);
items.value.push(item);
}
}
function updateItem(item: ItemClass) {
console.log(item);
}
/**
* Folders
*/
Expand All @@ -47,38 +67,4 @@ const folders = computed(() => {
const files = computed(() => {
return items.value.filter((item) => item instanceof FileClass) as FileClass[];
});
/**
* TODO: Delete this function
*/
function randomName() {
const words = [
'ability',
'about',
'absent',
'brush',
'budget',
'cheap',
'comfort',
'common',
'company',
'compare',
'deep',
'define',
'demand',
'depth',
'easily',
'easy',
'factor',
'factory',
'happy',
'hard',
'have',
'machine',
'magazine',
'magic',
'magical',
];
return words[Math.floor(Math.random() * words.length)] as string;
}
</script>
73 changes: 73 additions & 0 deletions src/components/files/Folder.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
<template>
<ContextMenu>
<template v-slot:content>
<a :href="url(`u/folder/${modelValue.id}`)">
<button
v-on:click.ctrl.prevent="
console.log('ctrl');
editingName = !editingName;
"
type="button"
:contenteditable="editingName ? 'true' : 'false'"
:class="classes"
class="h-[40px] rounded-lg bg-gradient-to-br px-5 py-2.5 text-center text-sm font-medium text-white hover:bg-gradient-to-bl focus:outline-none focus:ring-4 focus:ring-blue-300 dark:focus:ring-blue-800"
>
{{ modelValue.name }}
</button>
</a>
</template>
<template v-slot:menu>
<ul class="py-2 text-sm text-gray-700 dark:text-gray-200">
<li>
<a
href="#"
class="block px-4 py-2 hover:bg-gray-100 dark:hover:bg-gray-600 dark:hover:text-white"
>Dashboard</a
>
</li>
<li>
<a
href="#"
class="block px-4 py-2 hover:bg-gray-100 dark:hover:bg-gray-600 dark:hover:text-white"
>Settings</a
>
</li>
<li>
<a
href="#"
class="block px-4 py-2 hover:bg-gray-100 dark:hover:bg-gray-600 dark:hover:text-white"
>Earnings</a
>
</li>
</ul>
<div class="py-2">
<a
href="#"
class="block px-4 py-2 text-sm text-gray-700 hover:bg-gray-100 dark:text-gray-200 dark:hover:bg-gray-600 dark:hover:text-white"
>Separated link</a
>
</div>
</template>
</ContextMenu>
</template>

<script setup lang="ts">
import { ref, type PropType, computed } from 'vue';
import { FolderClass } from '@lib/items';
import { url } from '@lib/helpers';
import ContextMenu from './ContextMenu.vue';
const props = defineProps({
modelValue: {
type: Object as PropType<FolderClass>,
required: true,
},
});
defineEmits(['update:modelValue']);
const editingName = ref(false);
const classes = computed(() => {
return props.modelValue.colorClass + (editingName.value ? '' : '');
});
</script>
35 changes: 35 additions & 0 deletions src/components/files/NoFiles.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
<template>
<div class="flex w-full items-center justify-center">
<label
for="dropzone-file"
class="dark:hover:bg-bray-800 flex h-64 w-full cursor-pointer flex-col items-center justify-center rounded-lg border-2 border-dashed border-gray-300 bg-gray-50 hover:bg-gray-100 dark:border-gray-600 dark:bg-gray-700 dark:hover:border-gray-500 dark:hover:bg-gray-600"
>
<div class="flex flex-col items-center justify-center pb-6 pt-5">
<svg
class="mb-4 h-8 w-8 text-gray-500 dark:text-gray-400"
aria-hidden="true"
xmlns="http://www.w3.org/2000/svg"
fill="none"
viewBox="0 0 20 16"
>
<path
stroke="currentColor"
stroke-linecap="round"
stroke-linejoin="round"
stroke-width="2"
d="M13 13h3a3 3 0 0 0 0-6h-.025A5.56 5.56 0 0 0 16 6.5 5.5 5.5 0 0 0 5.207 5.021C5.137 5.017 5.071 5 5 5a4 4 0 0 0 0 8h2.167M10 15V6m0 0L8 8m2-2 2 2"
/>
</svg>
<p class="mb-2 text-sm text-gray-500 dark:text-gray-400">
<span class="font-semibold">Click to upload</span> or drag and drop
</p>
<p class="text-xs text-gray-500 dark:text-gray-400">
SVG, PNG, JPG or GIF (MAX. 800x400px)
</p>
</div>
<input id="dropzone-file" type="file" class="hidden" />
</label>
</div>
</template>

<script setup lang="ts"></script>
2 changes: 1 addition & 1 deletion src/lang/da.ts
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ export default {
openUserMenu: 'Åben brugermenu',
},
link: {
dashboard: 'Hjem',
myfiles: 'Mine Filer',
settings: 'Indstillinger',
signOut: 'Log ud',
},
Expand Down
2 changes: 1 addition & 1 deletion src/lang/en.ts
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ export default {
openUserMenu: 'Open user menu',
},
link: {
dashboard: 'Dashboard',
myfiles: 'My Files',
settings: 'Settings',
signOut: 'Sign out',
},
Expand Down
2 changes: 1 addition & 1 deletion src/layouts/SideBar.astro
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ import { t } from '@lib/i18n';
d="M12 2.252A8.014 8.014 0 0117.748 8H12V2.252z"></path></svg
>
<span class="ml-3" sidebar-toggle-item
>{t('layout.link.dashboard', Astro.locals.currentLocale)}</span
>{t('layout.link.myfiles', Astro.locals.currentLocale)}</span
>
</a>
</li>
Expand Down
Loading

0 comments on commit a1c4a72

Please sign in to comment.