<template> <div class="construction tw-relative" :class="{ 'show-construction-area': showConstructionArea }"> <component v-bind="attrs" :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>