Newer
Older
<template>
<div class="construction tw-relative" :class="{ 'show-construction-area': showConstructionArea }">
<component
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
:is="link ? 'a' : 'div'"
:href="link"
:target="link ? '_blank' : undefined"
:class="showConstructionArea ? 'tw-bg-amber-200' : 'tw-bg-amber-100'"
class="tw-group tw-flex tw-items-center tw-gap-2 tw-absolute tw-rounded tw-w-min tw-p-[.35em] tw-px-[.7em] tw-cursor-help tw-select-none tw-transition tw-duration-200"
tabindex="0"
@mouseover="mouseOver = true"
@mouseleave="mouseOver = false"
@focus="hasFocus = true"
@blur="hasFocus = false"
>
<icon-noto-construction />
{{ t('construction.label') }}
<div
class="construction-info tw-absolute tw-top-full tw-right-0 tw-mt-2 tw-bg-white tw-w-96 tw-text-base tw-p-4 tw-shadow-xl tw-rounded tw-z-50"
:class="{ 'tw-hidden': !showConstructionArea }"
>
<slot name="title">
<p>{{ title }}</p>
</slot>
</div>
</component>
<slot />
</div>
</template>
<script setup lang="ts">
import { computed, ref, useAttrs } from 'vue'
import { useI18n } from '@/i18n'
defineOptions({ inheritAttrs: false, compatConfig: { MODE: 3 } })
defineProps<{
title?: string
link?: string
}>()
const { t } = useI18n()
const attrs = useAttrs()
const mouseOver = ref(false)
const hasFocus = ref(false)
const showConstructionArea = computed(() => mouseOver.value || hasFocus.value)
</script>
<style lang="postcss" scoped>
.construction::after {
content: '';
position: absolute;
inset: -1rem;
pointer-events: none;
border-radius: 6px;
background-color: theme('colors.amber.100');
z-index: -1;
opacity: 0;
transition: opacity 0.2s;
}
.construction.show-construction-area::after {
opacity: 1;
}
.construction-info :deep(:last-child) {
margin-bottom: 0;
}
</style>