tooltip copy

This commit is contained in:
David Ascanio 2026-05-26 16:30:33 -03:00
parent 1756aadaff
commit 3d54899b3e
2 changed files with 92 additions and 51 deletions

1
.gitignore vendored
View File

@ -22,3 +22,4 @@ logs
.env
.env.*
!.env.example
.bruno

View File

@ -635,6 +635,12 @@ onMounted(async () => {
if (props.paragraphs.length) {
await applyTypesenseHighlights()
}
document.addEventListener('selectionchange', onSelectionChange)
})
onUnmounted(() => {
document.removeEventListener('selectionchange', onSelectionChange)
if (selectionTimer) clearTimeout(selectionTimer)
})
// ---- Utilerías de búsqueda local --------------------------------------------
@ -755,14 +761,32 @@ function highlightTextNodes(root: HTMLElement, terms: string[]): number {
return matches.length
}
const isPopOverOpen = ref(false)
const selectionTooltip = ref<{ x: number; y: number } | null>(null)
let selectionTimer: ReturnType<typeof setTimeout> | null = null
function handleSelection(event: MouseEvent) {
const selection = window.getSelection()
if (selection && selection.toString().length > 3) {
if (selection && selection.toString().trim().length > 3) {
if (selectionTimer) clearTimeout(selectionTimer)
selectionTimer = setTimeout(() => {
const x = Math.min(Math.max(event.clientX, 96), window.innerWidth - 96)
selectionTooltip.value = { x, y: event.clientY }
isPopOverOpen.value = true
}, 320)
} else {
clearSelectionTooltip()
}
}
function clearSelectionTooltip() {
if (selectionTimer) { clearTimeout(selectionTimer); selectionTimer = null }
selectionTooltip.value = null
isPopOverOpen.value = false
}
function onSelectionChange() {
const sel = window.getSelection()
if (!sel || sel.toString().trim().length === 0) clearSelectionTooltip()
}
const links = computed(() => {
@ -981,56 +1005,55 @@ const items = computed(() => {
</p>
</div>
</UPageBody>
<template #right>
<UPageAside
class="py-0 my-0"
>
<UFieldGroup orientation="horizontal" class="bg-white my-0 py-4 p-2 rounded-md shadow-md w-full justify-around">
<UTooltip
text="Crear nota"
>
<UButton
icon="ph-note-pencil"
:variant="isPopOverOpen ? 'solid': 'soft'"
:color="isPopOverOpen ? 'info' : 'neutral'"
size="lg"
:disabled="isPopOverOpen ? false : true"
@click="addNote()"
></UButton>
</UTooltip>
<UTooltip
text="Resaltar">
<UButton
icon="ph-highlighter"
:variant="isPopOverOpen ? 'solid': 'soft'"
:color="isPopOverOpen ? 'success' : 'neutral'"
size="lg"
:disabled="isPopOverOpen ? false : true"
@click="highlightParagraph()"
></UButton>
</UTooltip>
<UTooltip
text="Copiar">
<UButton
icon="ph-copy"
:variant="isPopOverOpen ? 'solid': 'soft'"
:color="isPopOverOpen ? 'warning' : 'neutral'"
size="lg"
:disabled="isPopOverOpen ? false : true"
@click="copyToClipboard()"
></UButton>
</UTooltip>
</UFieldGroup>
<UAccordion :items="items">
<template #body="{ item }">
<pre>{{ item.content }}</pre>
</template>
</UAccordion>
</UPageAside>
</template>
</UPage>
</div>
<!-- Tooltip de selección -->
<Teleport to="body">
<div
v-if="selectionTooltip"
class="fixed z-9999 pointer-events-none"
:style="{ left: selectionTooltip.x + 'px', top: (selectionTooltip.y - 12) + 'px' }"
>
<Transition name="tooltip-pop">
<div
v-if="isPopOverOpen"
class="p-2 selection-tooltip flex items-center bg-white rounded-xl shadow-2xl overflow-hidden select-none pointer-events-auto"
@mousedown.prevent
>
<!-- <UButton
variant="soft"
class="group flex flex-col items-center gap-1 px-4 py-2.5 text-blue-300 hover:bg-white/10 active:bg-white/20 transition-colors"
aria-label="Crear nota"
@click="addNote()"
>
<UIcon name="ph-note-pencil" class="size-5" />
<span class="group-hover:text-black text-[9px] font-semibold leading-none">Nota</span>
</UButton>
<div class="w-px self-stretch bg-white/10" /> -->
<!-- <UButton
variant="soft"
class="group flex flex-col items-center gap-1 px-4 py-2.5 text-green-400 hover:bg-white/10 active:bg-white/20 transition-colors"
aria-label="Resaltar"
@click="highlightParagraph()"
>
<UIcon name="ph-highlighter" class="size-5" />
<span class="group-hover:text-black text-[9px] font-semibold leading-none">Resaltar</span>
</UButton> -->
<div class="w-px self-stretch bg-white/10" />
<UButton
variant="soft"
class="group flex flex-col items-center gap-1 px-4 py-2.5 text-amber-300 hover:bg-white/10 active:bg-white/20 transition-colors"
aria-label="Copiar texto"
@click="copyToClipboard(collection)"
>
<UIcon name="ph-copy" class="size-5" />
<span class="group-hover:text-black text-[9px] font-semibold leading-none">Copiar</span>
</UButton>
</div>
</Transition>
</div>
</Teleport>
</UDashboardPanel>
</template>
@ -1042,4 +1065,21 @@ const items = computed(() => {
.paragraph-html :deep(p:last-child) {
margin-bottom: 0;
}
/* Tooltip de selección de texto */
.selection-tooltip {
transform: translateX(-50%) translateY(-100%);
}
.tooltip-pop-enter-active {
transition: transform 0.18s cubic-bezier(0.34, 1.56, 0.64, 1), opacity 0.12s ease;
}
.tooltip-pop-leave-active {
transition: transform 0.12s ease-in, opacity 0.1s ease;
}
.tooltip-pop-enter-from,
.tooltip-pop-leave-to {
transform: translateX(-50%) translateY(calc(-100% + 8px));
opacity: 0;
}
</style>