Implement tooltips and other UI tuning.

This commit is contained in:
Leo Vasanko 2023-11-06 15:33:43 +00:00
parent c2be2ecd31
commit 129250e072
7 changed files with 74 additions and 30 deletions

View File

@ -87,8 +87,7 @@
tbody .selection input:checked { tbody .selection input:checked {
opacity: 1 !important; opacity: 1 !important;
transform: scale(0.5); transform: scale(0.5);
top: 0.1rem !important; left: 0;
left: -0.3rem !important;
} }
} }
@ -103,7 +102,7 @@ main {
body { body {
background-color: var(--primary-background); background-color: var(--primary-background);
font-size: 1rem; font-size: 1rem;
font-family: 'Roboto', sans-serif; font-family: 'Roboto';
color: var(--primary-color); color: var(--primary-color);
margin: 0; margin: 0;
} }
@ -157,8 +156,48 @@ table {
display: flex; display: flex;
flex-direction: column; flex-direction: column;
} }
nav {
/* Position so that tooltips can appear on top of other positioned elements */
position: relative;
z-index: 10;
}
main { main {
height: calc(100svh - 9rem); /* fill almost the rest of the screen after header */ height: calc(100svh - 9rem); /* fill almost the rest of the screen after header */
padding-bottom: 3rem; /* convenience space on the bottom */ padding-bottom: 3rem; /* convenience space on the bottom */
overflow-y: scroll; overflow-y: scroll;
} }
[data-tooltip]:hover:after {
z-index: 1000;
content: attr(data-tooltip);
position: absolute;
font-size: 1rem;
text-align: center;
padding: .5rem 1rem;
border-radius: 3rem 0 3rem 0;
box-shadow: 0 0 2rem var(--accent-color);
transform: translate(calc(1rem + -50%), 150%);
background-color: var(--accent-color);
color: var(--primary-color);
white-space: pre;
animation: appearbriefly calc(10 * var(--transition-time)) linear forwards;
}
.modified [data-tooltip]:hover:after {
transform: translate(calc(1rem + 1ex + -100%), calc(-1.5rem + 100%));
}
@keyframes appearbriefly {
from {
opacity: 0;
}
30% {
opacity: 0;
}
40% {
opacity: 1;
}
90% {
opacity: 1;
}
to {
opacity: 0;
}
}

View File

@ -34,20 +34,20 @@ const props = defineProps<{
.breadcrumb > a { .breadcrumb > a {
margin: 0 -0.7rem 0 -0.7rem; margin: 0 -0.7rem 0 -0.7rem;
padding: 0; padding: 0;
max-width: 8em; max-width: 8rem;
font-size: 1.3em; font-size: 1.3rem;
white-space: nowrap; white-space: nowrap;
text-overflow: ellipsis; text-overflow: ellipsis;
overflow: hidden; overflow: hidden;
height: 1em; height: 1.5rem;
color: var(--breadcrumb-color); color: var(--breadcrumb-color);
padding: 0.3em 1.5em; padding: 0.3rem 1.5rem;
clip-path: polygon(0 0, 1em 50%, 0 100%, 100% 100%, 100% 0, 0 0); clip-path: polygon(0 0, 1rem 50%, 0 100%, 100% 100%, 100% 0, 0 0);
transition: all var(--breadcrumb-transtime); transition: all var(--breadcrumb-transtime);
} }
.breadcrumb a:first-child { .breadcrumb a:first-child {
margin-left: 0; margin-left: 0;
padding-left: 0; padding-left: .2rem;
clip-path: none; clip-path: none;
} }
.breadcrumb a:last-child { .breadcrumb a:last-child {

View File

@ -110,7 +110,7 @@
</td> </td>
<td class="modified right"> <td class="modified right">
<time <time
:datetime="new Date(1000 * doc.mtime).toISOString().replace('.000', '')" :data-tooltip="new Date(1000 * doc.mtime).toISOString().replace('T', '\n').replace('.000Z', ' UTC')"
>{{ doc.modified }}</time >{{ doc.modified }}</time
> >
</td> </td>
@ -136,7 +136,7 @@ import type { Document, FolderDocument } from '@/repositories/Document'
import FileRenameInput from './FileRenameInput.vue' import FileRenameInput from './FileRenameInput.vue'
import createWebSocket from '@/repositories/WS' import createWebSocket from '@/repositories/WS'
import { formatSize, formatUnixDate } from '@/utils' import { formatSize, formatUnixDate } from '@/utils'
import { isNavigationFailure, useRouter } from 'vue-router' import { useRouter } from 'vue-router'
const props = withDefaults( const props = withDefaults(
defineProps<{ defineProps<{
@ -352,12 +352,13 @@ thead tr {
} }
tbody tr { tbody tr {
position: relative; position: relative;
z-index: auto;
} }
table thead input[type='checkbox'] { table thead input[type='checkbox'] {
position: inherit; position: inherit;
width: 1rem; width: 1rem;
height: 1rem; height: 1rem;
margin: 0.5rem; padding: 0.5rem;
} }
table tbody input[type='checkbox'] { table tbody input[type='checkbox'] {
width: 2rem; width: 2rem;
@ -413,6 +414,7 @@ table td {
thead tr { thead tr {
background: linear-gradient(to bottom, #eee, #fff 30%, #ddd); background: linear-gradient(to bottom, #eee, #fff 30%, #ddd);
color: #000; color: #000;
box-shadow: 0 0 .2rem black;
} }
tbody tr.cursor { tbody tr.cursor {
background: var(--accent-color); background: var(--accent-color);
@ -458,12 +460,13 @@ tbody .selection input {
opacity: 0.7; opacity: 0.7;
} }
.file .selection::before { .file .selection::before {
content: '📄 '; content: '📄';
font-size: 1.5em; font-size: 1.5rem;
} }
.folder .selection::before { .folder .selection::before {
content: '📁 '; height: 2rem;
font-size: 1.5em; content: '📁';
font-size: 1.5rem;
} }
.empty-container { .empty-container {
padding-top: 3rem; padding-top: 3rem;

View File

@ -32,6 +32,7 @@ defineExpose({
<UploadButton /> <UploadButton />
<SvgButton <SvgButton
name="create-folder" name="create-folder"
data-tooltip="New folder"
@click="() => documentStore.fileExplorer.newFolder()" @click="() => documentStore.fileExplorer.newFolder()"
/> />
<slot></slot> <slot></slot>
@ -53,10 +54,11 @@ defineExpose({
<style scoped> <style scoped>
.buttons { .buttons {
padding: 0 0.5em; padding: 0;
display: flex; display: flex;
align-items: center; align-items: center;
height: 3.5rem; height: 3.5rem;
z-index: 10;
} }
.buttons > * { .buttons > * {
flex-shrink: 1; flex-shrink: 1;

View File

@ -2,11 +2,11 @@
<template v-if="documentStore.selected.size"> <template v-if="documentStore.selected.size">
<div class="smallgap"></div> <div class="smallgap"></div>
<p class="select-text">{{ documentStore.selected.size }} selected </p> <p class="select-text">{{ documentStore.selected.size }} selected </p>
<SvgButton name="download" @click="download" /> <SvgButton name="download" data-tooltip="Download" @click="download" />
<SvgButton name="copy" @click="op('cp', dst)" /> <SvgButton name="copy" data-tooltip="Copy here" @click="op('cp', dst)" />
<SvgButton name="paste" @click="op('mv', dst)" /> <SvgButton name="paste" data-tooltip="Move here" @click="op('mv', dst)" />
<SvgButton name="trash" @click="op('rm')" /> <SvgButton name="trash" data-tooltip="Delete " @click="op('rm')" />
<button @click="documentStore.selected.clear()"></button> <button class="action-button unselect" data-tooltip="Unselect all" @click="documentStore.selected.clear()"></button>
</template> </template>
</template> </template>

View File

@ -15,8 +15,8 @@ const props = defineProps<{
const icon = defineAsyncComponent(() => import(`@/assets/svg/${props.name}.svg`)) const icon = defineAsyncComponent(() => import(`@/assets/svg/${props.name}.svg`))
</script> </script>
<style scoped> <style>
button { .action-button {
background: none; background: none;
border: none; border: none;
color: #ccc; color: #ccc;
@ -26,8 +26,8 @@ button {
width: 3rem; width: 3rem;
height: 3rem; height: 3rem;
} }
button:hover, .action-button:hover,
button:focus { .action-button:focus {
color: #fff; color: #fff;
transform: scale(1.1); transform: scale(1.1);
} }
@ -35,8 +35,8 @@ svg {
fill: #ccc; fill: #ccc;
transform: fill 0.2s ease; transform: fill 0.2s ease;
} }
button:hover svg, .action-button:hover svg,
button:focus svg { .action-button:focus svg {
fill: #fff; fill: #fff;
} }
</style> </style>

View File

@ -91,6 +91,6 @@ async function uploadFileChangeHandler(event: Event) {
webkitdirectory webkitdirectory
/> />
</template> </template>
<SvgButton name="add-file" @click="fileUploadButton.click()" /> <SvgButton name="add-file" data-tooltip="Upload files" @click="fileUploadButton.click()" />
<SvgButton name="add-folder" @click="folderUploadButton.click()" /> <SvgButton name="add-folder" data-tooltip="Upload folder" @click="folderUploadButton.click()" />
</template> </template>