feat: directive tooltip

This commit is contained in:
KUN1007 2023-11-08 22:07:49 +08:00
parent 7c6fc33929
commit 2c0f6e990f
10 changed files with 203 additions and 21 deletions

View file

@ -106,7 +106,6 @@ const handelCloseSettingsPanel = () => {
display: flex;
color: var(--kungalgame-font-color-3);
border: 1px solid var(--kungalgame-blue-1);
overflow-y: scroll;
}
.container {

View file

@ -50,13 +50,19 @@ onMounted(async () => {
<template>
<div class="kungalgame-background">
<div class="bg-settings">{{ $tm('header.settings.background') }}</div>
<div class="bg-settings">
{{ $tm('header.settings.background') }}
</div>
<ul class="kungalgame-background-container">
<li>
<span>{{ $tm('header.settings.preset') }}</span>
<!-- Preset background collection -->
<ul class="kungalgame-restore-bg">
<li v-for="kun in backgroundImages" :key="kun.index">
<li
v-for="kun in backgroundImages"
:key="kun.index"
v-tooltip="{ message: kun.alt, position: 'bottom' }"
>
<img
v-if="kun"
:src="imageArray[kun.index - 1]"

View file

@ -4,12 +4,15 @@
import { type App } from 'vue'
// Directive for enlarging images on click
import { zoom } from './zoom/zoom'
// import { zoom } from './zoom/zoom'
// Permission directive
import { permission } from './permission/permission'
// import { permission } from './permission/permission'
// Tooltip directive
import { tooltip } from './tooltip/tooltip'
// Mount directives
export function setupKUNGalgameDirectives(app: App) {
app.directive('zoom', zoom)
app.directive('permission', permission)
// app.directive('zoom', zoom)
// app.directive('permission', permission)
app.directive('tooltip', tooltip)
}

View file

@ -0,0 +1,12 @@
<script setup lang="ts">
const props = defineProps<{
message: string
position: 'top' | 'right' | 'bottom' | 'left'
}>()
</script>
<template>
<span :message="props.message" :position="props.position"><slot /></span>
</template>
<style lang="scss" scoped></style>

View file

@ -0,0 +1,27 @@
import type { Directive, DirectiveBinding } from 'vue'
interface TooltipBinding {
message: string
position: 'top' | 'right' | 'bottom' | 'left'
}
const initializeTooltip = (element: HTMLElement, binding: DirectiveBinding) => {
const { message, position } = (binding.value as TooltipBinding) || {
message: '',
position: 'left',
}
element.setAttribute('tooltip', message)
element.setAttribute('position', position)
}
/* This plugin is enabled */
export const tooltip: Directive = {
mounted(element: HTMLElement, binding: DirectiveBinding) {
initializeTooltip(element, binding)
},
updated(element: HTMLElement, binding: DirectiveBinding) {
initializeTooltip(element, binding)
},
}

View file

@ -1,22 +1,18 @@
// Vue core
import { createApp } from 'vue'
import App from './App.vue'
import router from './router'
// Import vue i18n
import i18n from '@/language/i18n'
import { setupRouterGuard } from '@/router/guard'
import { setupPinia } from '@/store/index'
import { setupKUNGalgameRouterGuard } from '@/router/guard'
import { setupKUNGalgamePinia } from '@/store/index'
import { setupKUNGalgameDirectives } from './directives'
// Import css styles, color, theme, etc.
import '@/styles/index.scss'
// Get vue App instance
const app = createApp(App)
// Setup router guard
setupRouterGuard(router)
// Setup pinia
setupPinia(app)
setupKUNGalgameRouterGuard(router)
setupKUNGalgamePinia(app)
setupKUNGalgameDirectives(app)
app.use(router).use(i18n).mount('#app')

View file

@ -10,7 +10,7 @@ const createPageTitle = (router: Router) => {
})
}
export function setupRouterGuard(router: Router) {
export function setupKUNGalgameRouterGuard(router: Router) {
createPermission(router)
createPageTitle(router)
}

View file

@ -36,7 +36,7 @@ import { useKUNGalgameTopicStore } from './modules/topic'
const store = createPinia()
// Function to set up Pinia, to be called in main.ts
export function setupPinia(app: App<Element>) {
export function setupKUNGalgamePinia(app: App<Element>) {
store.use(piniaPluginPersistedstate)
app.use(store)
}
@ -63,5 +63,3 @@ export function kungalgameStoreReset() {
settingsStore.$reset()
topicStore.$reset()
}
export { store }

View file

@ -1,2 +1,3 @@
@use './theme/index.scss';
@use './reset.scss';
@use './tooltip/tooltip.scss';

View file

@ -0,0 +1,140 @@
[tooltip] {
& > * {
display: inline-block;
}
position: relative;
&:before,
&:after {
text-transform: none;
font-size: 13px;
line-height: 1;
user-select: none;
pointer-events: none;
position: absolute;
display: none;
opacity: 0;
}
&:before {
content: '';
border: 5px solid transparent;
z-index: 1001;
}
&:after {
content: attr(tooltip);
text-align: center;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
padding: 7px;
border-radius: 5px;
box-shadow: var(--shadow);
background: var(--kungalgame-trans-white-2);
backdrop-filter: blur(5px);
color: var(--kungalgame-blue-5);
z-index: 1000;
}
&:hover:before,
&:hover:after {
display: block;
}
&:not([position]):before,
&[position^='top']:before {
bottom: 100%;
border-bottom-width: 0;
border-top-color: var(--kungalgame-trans-white-2);
}
&:not([position]):after,
&[position^='top']::after {
bottom: calc(100% + 5px);
}
&:not([position])::before,
&:not([position])::after,
&[position^='top']::before,
&[position^='top']::after {
left: 50%;
transform: translate(-50%, -10px);
}
&[position^='bottom']::before {
top: 105%;
border-top-width: 0;
border-bottom-color: var(--kungalgame-trans-white-2);
}
&[position^='bottom']::after {
top: calc(105% + 5px);
}
&[position^='bottom']::before,
&[position^='bottom']::after {
left: 50%;
transform: translate(-50%, 10px);
}
&[position^='left']::before {
top: 50%;
border-right-width: 0;
border-left-color: var(--kungalgame-trans-white-2);
left: calc(0em - 5px);
transform: translate(-10px, -50%);
}
&[position^='left']::after {
top: 50%;
right: calc(100% + 5px);
transform: translate(-10px, -50%);
}
&[position^='right']::before {
top: 50%;
border-left-width: 0;
border-right-color: var(--kungalgame-trans-white-2);
right: calc(0em - 5px);
transform: translate(10px, -50%);
}
&[position^='right']::after {
top: 50%;
left: calc(100% + 5px);
transform: translate(10px, -50%);
}
&:not([position]):hover::before,
&:not([position]):hover::after,
&[position^='top']:hover::before,
&[position^='top']:hover::after,
&[position^='bottom']:hover::before,
&[position^='bottom']:hover::after {
animation: vertical 300ms ease-out forwards;
}
&[position^='left']:hover::before,
&[position^='left']:hover::after,
&[position^='right']:hover::before,
&[position^='right']:hover::after {
animation: horizontal 300ms ease-out forwards;
}
}
/* Empty tooltips */
[tooltip='']::before,
[tooltip='']::after {
display: none !important;
}
@keyframes vertical {
to {
opacity: 0.9;
transform: translate(-50%, 0);
}
}
@keyframes horizontal {
to {
opacity: 0.9;
transform: translate(0, -50%);
}
}