tooltip copy
This commit is contained in:
parent
1756aadaff
commit
3d54899b3e
|
|
@ -22,3 +22,4 @@ logs
|
||||||
.env
|
.env
|
||||||
.env.*
|
.env.*
|
||||||
!.env.example
|
!.env.example
|
||||||
|
.bruno
|
||||||
|
|
|
||||||
|
|
@ -635,6 +635,12 @@ onMounted(async () => {
|
||||||
if (props.paragraphs.length) {
|
if (props.paragraphs.length) {
|
||||||
await applyTypesenseHighlights()
|
await applyTypesenseHighlights()
|
||||||
}
|
}
|
||||||
|
document.addEventListener('selectionchange', onSelectionChange)
|
||||||
|
})
|
||||||
|
|
||||||
|
onUnmounted(() => {
|
||||||
|
document.removeEventListener('selectionchange', onSelectionChange)
|
||||||
|
if (selectionTimer) clearTimeout(selectionTimer)
|
||||||
})
|
})
|
||||||
|
|
||||||
// ---- Utilerías de búsqueda local --------------------------------------------
|
// ---- Utilerías de búsqueda local --------------------------------------------
|
||||||
|
|
@ -755,16 +761,34 @@ function highlightTextNodes(root: HTMLElement, terms: string[]): number {
|
||||||
return matches.length
|
return matches.length
|
||||||
}
|
}
|
||||||
const isPopOverOpen = ref(false)
|
const isPopOverOpen = ref(false)
|
||||||
|
const selectionTooltip = ref<{ x: number; y: number } | null>(null)
|
||||||
|
let selectionTimer: ReturnType<typeof setTimeout> | null = null
|
||||||
|
|
||||||
function handleSelection(event: MouseEvent) {
|
function handleSelection(event: MouseEvent) {
|
||||||
const selection = window.getSelection()
|
const selection = window.getSelection()
|
||||||
if (selection && selection.toString().length > 3) {
|
if (selection && selection.toString().trim().length > 3) {
|
||||||
isPopOverOpen.value = true
|
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 {
|
} else {
|
||||||
isPopOverOpen.value = false
|
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(() => {
|
const links = computed(() => {
|
||||||
return [
|
return [
|
||||||
{
|
{
|
||||||
|
|
@ -981,56 +1005,55 @@ const items = computed(() => {
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
</UPageBody>
|
</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>
|
</UPage>
|
||||||
</div>
|
</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>
|
</UDashboardPanel>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
|
|
@ -1042,4 +1065,21 @@ const items = computed(() => {
|
||||||
.paragraph-html :deep(p:last-child) {
|
.paragraph-html :deep(p:last-child) {
|
||||||
margin-bottom: 0;
|
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>
|
</style>
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue