apropiadamente implementar nuevo linkeo
This commit is contained in:
parent
15ffbae34d
commit
2b44ab6102
7 changed files with 88 additions and 105 deletions
|
@ -33,7 +33,7 @@
|
||||||
"prosemirror-schema-list": "~1.2.2",
|
"prosemirror-schema-list": "~1.2.2",
|
||||||
"prosemirror-state": "~1.4.2",
|
"prosemirror-state": "~1.4.2",
|
||||||
"prosemirror-transform": "~1.7.1",
|
"prosemirror-transform": "~1.7.1",
|
||||||
"prosemirror-view": "~1.29.2",
|
"prosemirror-view": "^1.31.7",
|
||||||
"svelte": "^3.58.0",
|
"svelte": "^3.58.0",
|
||||||
"svelte-check": "^2.10.3",
|
"svelte-check": "^2.10.3",
|
||||||
"tailwindcss": "^3.3.3",
|
"tailwindcss": "^3.3.3",
|
||||||
|
|
|
@ -31,7 +31,7 @@ dependencies:
|
||||||
version: 9.0.10(yjs@13.5.52)
|
version: 9.0.10(yjs@13.5.52)
|
||||||
y-prosemirror:
|
y-prosemirror:
|
||||||
specifier: ^1.2.1
|
specifier: ^1.2.1
|
||||||
version: 1.2.1(prosemirror-model@1.18.3)(prosemirror-state@1.4.2)(prosemirror-view@1.29.2)(y-protocols@1.0.5)(yjs@13.5.52)
|
version: 1.2.1(prosemirror-model@1.18.3)(prosemirror-state@1.4.2)(prosemirror-view@1.31.7)(y-protocols@1.0.5)(yjs@13.5.52)
|
||||||
y-protocols:
|
y-protocols:
|
||||||
specifier: ^1.0.5
|
specifier: ^1.0.5
|
||||||
version: 1.0.5
|
version: 1.0.5
|
||||||
|
@ -107,8 +107,8 @@ devDependencies:
|
||||||
specifier: ~1.7.1
|
specifier: ~1.7.1
|
||||||
version: 1.7.1
|
version: 1.7.1
|
||||||
prosemirror-view:
|
prosemirror-view:
|
||||||
specifier: ~1.29.2
|
specifier: ^1.31.7
|
||||||
version: 1.29.2
|
version: 1.31.7
|
||||||
svelte:
|
svelte:
|
||||||
specifier: ^3.58.0
|
specifier: ^3.58.0
|
||||||
version: 3.58.0
|
version: 3.58.0
|
||||||
|
@ -595,7 +595,7 @@ packages:
|
||||||
normalize-path: 3.0.0
|
normalize-path: 3.0.0
|
||||||
readdirp: 3.6.0
|
readdirp: 3.6.0
|
||||||
optionalDependencies:
|
optionalDependencies:
|
||||||
fsevents: 2.3.2
|
fsevents: 2.3.3
|
||||||
dev: true
|
dev: true
|
||||||
|
|
||||||
/commander@4.1.1:
|
/commander@4.1.1:
|
||||||
|
@ -796,8 +796,8 @@ packages:
|
||||||
resolution: {integrity: sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==}
|
resolution: {integrity: sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==}
|
||||||
dev: true
|
dev: true
|
||||||
|
|
||||||
/fsevents@2.3.2:
|
/fsevents@2.3.3:
|
||||||
resolution: {integrity: sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==}
|
resolution: {integrity: sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==}
|
||||||
engines: {node: ^8.16.0 || ^10.6.0 || >=11.0.0}
|
engines: {node: ^8.16.0 || ^10.6.0 || >=11.0.0}
|
||||||
os: [darwin]
|
os: [darwin]
|
||||||
requiresBuild: true
|
requiresBuild: true
|
||||||
|
@ -1307,7 +1307,7 @@ packages:
|
||||||
dependencies:
|
dependencies:
|
||||||
prosemirror-state: 1.4.2
|
prosemirror-state: 1.4.2
|
||||||
prosemirror-transform: 1.7.1
|
prosemirror-transform: 1.7.1
|
||||||
prosemirror-view: 1.29.2
|
prosemirror-view: 1.31.7
|
||||||
dev: true
|
dev: true
|
||||||
|
|
||||||
/prosemirror-gapcursor@1.3.1:
|
/prosemirror-gapcursor@1.3.1:
|
||||||
|
@ -1316,7 +1316,7 @@ packages:
|
||||||
prosemirror-keymap: 1.2.1
|
prosemirror-keymap: 1.2.1
|
||||||
prosemirror-model: 1.18.3
|
prosemirror-model: 1.18.3
|
||||||
prosemirror-state: 1.4.2
|
prosemirror-state: 1.4.2
|
||||||
prosemirror-view: 1.29.2
|
prosemirror-view: 1.31.7
|
||||||
dev: true
|
dev: true
|
||||||
|
|
||||||
/prosemirror-history@1.3.0:
|
/prosemirror-history@1.3.0:
|
||||||
|
@ -1371,15 +1371,15 @@ packages:
|
||||||
dependencies:
|
dependencies:
|
||||||
prosemirror-model: 1.18.3
|
prosemirror-model: 1.18.3
|
||||||
prosemirror-transform: 1.7.1
|
prosemirror-transform: 1.7.1
|
||||||
prosemirror-view: 1.29.2
|
prosemirror-view: 1.31.7
|
||||||
|
|
||||||
/prosemirror-transform@1.7.1:
|
/prosemirror-transform@1.7.1:
|
||||||
resolution: {integrity: sha512-VteoifAfpt46z0yEt6Fc73A5OID9t/y2QIeR5MgxEwTuitadEunD/V0c9jQW8ziT8pbFM54uTzRLJ/nLuQjMxg==}
|
resolution: {integrity: sha512-VteoifAfpt46z0yEt6Fc73A5OID9t/y2QIeR5MgxEwTuitadEunD/V0c9jQW8ziT8pbFM54uTzRLJ/nLuQjMxg==}
|
||||||
dependencies:
|
dependencies:
|
||||||
prosemirror-model: 1.18.3
|
prosemirror-model: 1.18.3
|
||||||
|
|
||||||
/prosemirror-view@1.29.2:
|
/prosemirror-view@1.31.7:
|
||||||
resolution: {integrity: sha512-T4Wm+eTpTH0N9gBJfJR6iecjRX2hYTKewoJUwa92hQOoEz2bYVZy6sYeN+hfnRR506TRvRcuZYqftp4KA8dN+Q==}
|
resolution: {integrity: sha512-Pr7w93yOYmxQwzGIRSaNLZ/1uM6YjnenASzN2H6fO6kGekuzRbgZ/4bHbBTd1u4sIQmL33/TcGmzxxidyPwCjg==}
|
||||||
dependencies:
|
dependencies:
|
||||||
prosemirror-model: 1.18.3
|
prosemirror-model: 1.18.3
|
||||||
prosemirror-state: 1.4.2
|
prosemirror-state: 1.4.2
|
||||||
|
@ -1457,7 +1457,7 @@ packages:
|
||||||
engines: {node: '>=14.18.0', npm: '>=8.0.0'}
|
engines: {node: '>=14.18.0', npm: '>=8.0.0'}
|
||||||
hasBin: true
|
hasBin: true
|
||||||
optionalDependencies:
|
optionalDependencies:
|
||||||
fsevents: 2.3.2
|
fsevents: 2.3.3
|
||||||
dev: true
|
dev: true
|
||||||
|
|
||||||
/rope-sequence@1.3.3:
|
/rope-sequence@1.3.3:
|
||||||
|
@ -1797,7 +1797,7 @@ packages:
|
||||||
resolve: 1.22.2
|
resolve: 1.22.2
|
||||||
rollup: 3.20.6
|
rollup: 3.20.6
|
||||||
optionalDependencies:
|
optionalDependencies:
|
||||||
fsevents: 2.3.2
|
fsevents: 2.3.3
|
||||||
dev: true
|
dev: true
|
||||||
|
|
||||||
/vitefu@0.2.4(vite@4.2.2):
|
/vitefu@0.2.4(vite@4.2.2):
|
||||||
|
@ -1843,7 +1843,7 @@ packages:
|
||||||
yjs: 13.5.52
|
yjs: 13.5.52
|
||||||
dev: false
|
dev: false
|
||||||
|
|
||||||
/y-prosemirror@1.2.1(prosemirror-model@1.18.3)(prosemirror-state@1.4.2)(prosemirror-view@1.29.2)(y-protocols@1.0.5)(yjs@13.5.52):
|
/y-prosemirror@1.2.1(prosemirror-model@1.18.3)(prosemirror-state@1.4.2)(prosemirror-view@1.31.7)(y-protocols@1.0.5)(yjs@13.5.52):
|
||||||
resolution: {integrity: sha512-czMBfB1eL2awqmOSxQM8cS/fsUOGE6fjvyPLInrh4crPxFiw67wDpwIW+EGBYKRa04sYbS0ScGj7ZgvWuDrmBQ==}
|
resolution: {integrity: sha512-czMBfB1eL2awqmOSxQM8cS/fsUOGE6fjvyPLInrh4crPxFiw67wDpwIW+EGBYKRa04sYbS0ScGj7ZgvWuDrmBQ==}
|
||||||
peerDependencies:
|
peerDependencies:
|
||||||
prosemirror-model: ^1.7.1
|
prosemirror-model: ^1.7.1
|
||||||
|
@ -1855,7 +1855,7 @@ packages:
|
||||||
lib0: 0.2.73
|
lib0: 0.2.73
|
||||||
prosemirror-model: 1.18.3
|
prosemirror-model: 1.18.3
|
||||||
prosemirror-state: 1.4.2
|
prosemirror-state: 1.4.2
|
||||||
prosemirror-view: 1.29.2
|
prosemirror-view: 1.31.7
|
||||||
y-protocols: 1.0.5
|
y-protocols: 1.0.5
|
||||||
yjs: 13.5.52
|
yjs: 13.5.52
|
||||||
dev: false
|
dev: false
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import { onDestroy, onMount, tick } from "svelte";
|
import { onDestroy, onMount, tick } from "svelte";
|
||||||
|
import type { Writable } from "svelte/store";
|
||||||
import type { EditorView } from "prosemirror-view";
|
import type { EditorView } from "prosemirror-view";
|
||||||
import { EditorState, TextSelection } from "prosemirror-state";
|
import { EditorState, TextSelection } from "prosemirror-state";
|
||||||
|
|
||||||
|
@ -17,6 +18,7 @@
|
||||||
removeMark,
|
removeMark,
|
||||||
markIsActive,
|
markIsActive,
|
||||||
getFirstMarkInSelection,
|
getFirstMarkInSelection,
|
||||||
|
selectMark,
|
||||||
} from "./ps-utils";
|
} from "./ps-utils";
|
||||||
import SimpleMarkItem from "./bubblemenu/SimpleMarkItem.svelte";
|
import SimpleMarkItem from "./bubblemenu/SimpleMarkItem.svelte";
|
||||||
import Button from "./bubblemenu/Button.svelte";
|
import Button from "./bubblemenu/Button.svelte";
|
||||||
|
@ -28,6 +30,7 @@
|
||||||
export let view: EditorView;
|
export let view: EditorView;
|
||||||
export let state: EditorState;
|
export let state: EditorState;
|
||||||
export let worldY: WorldY;
|
export let worldY: WorldY;
|
||||||
|
export let editingLink: Writable<false | "new" | "selection">;
|
||||||
|
|
||||||
let changingProp:
|
let changingProp:
|
||||||
| false
|
| false
|
||||||
|
@ -55,36 +58,19 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
function startEditingLink() {
|
function startEditingLink() {
|
||||||
const match = getFirstMarkInSelection(state, view.state.schema.marks.link);
|
const match = getFirstMarkInSelection(
|
||||||
|
view.state,
|
||||||
// si no hay un link en la selección, empezar a editar uno sin ningún enlace
|
view.state.schema.marks.link,
|
||||||
// TODO: quizás queremos poner algo tipo https://sutty.nl por defecto?
|
|
||||||
if (!match) {
|
|
||||||
changingProp = { type: "link", url: "" };
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
view.dispatch(
|
|
||||||
state.tr.setSelection(
|
|
||||||
TextSelection.create(
|
|
||||||
state.doc,
|
|
||||||
match.position,
|
|
||||||
match.position + match.node.nodeSize
|
|
||||||
)
|
|
||||||
)
|
|
||||||
);
|
);
|
||||||
changingProp = { type: "link", url: match.mark.attrs.href };
|
if (match) {
|
||||||
}
|
selectMark(match, view.state, view.dispatch);
|
||||||
|
$editingLink = "selection";
|
||||||
function removeLink() {
|
} else if (!view.state.selection.empty) {
|
||||||
changingProp = false;
|
$editingLink = "selection";
|
||||||
|
} else {
|
||||||
runCommand(removeMark(view.state.schema.marks.link));
|
runCommand(removeMark(view.state.schema.marks.link));
|
||||||
|
$editingLink = "new";
|
||||||
}
|
}
|
||||||
|
|
||||||
function onChangeLink(event: Event) {
|
|
||||||
changingProp = false;
|
|
||||||
const url = (event.target as HTMLInputElement).value;
|
|
||||||
runCommand(updateMark(view.state.schema.marks.link, { href: url }));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
let makingInternalLink = false;
|
let makingInternalLink = false;
|
||||||
|
@ -134,7 +120,7 @@ transform: scale(${1 / viewport.scale});
|
||||||
</Modal>
|
</Modal>
|
||||||
{/if}
|
{/if}
|
||||||
|
|
||||||
<div class="floating" style={barStyle}>
|
<div class="floating z-40" style={barStyle}>
|
||||||
<Linking {state} />
|
<Linking {state} />
|
||||||
<div class="bubble" hidden={state.selection.empty}>
|
<div class="bubble" hidden={state.selection.empty}>
|
||||||
{#if changingProp === false}
|
{#if changingProp === false}
|
||||||
|
@ -162,17 +148,6 @@ transform: scale(${1 / viewport.scale});
|
||||||
onClick={startMakingInternalLink}
|
onClick={startMakingInternalLink}
|
||||||
><InternalLinkIcon style={svgStyle} /></Button
|
><InternalLinkIcon style={svgStyle} /></Button
|
||||||
>
|
>
|
||||||
{:else if changingProp.type === "link"}
|
|
||||||
<input
|
|
||||||
bind:this={linkInputEl}
|
|
||||||
type="text"
|
|
||||||
placeholder="https://"
|
|
||||||
on:change|preventDefault={onChangeLink}
|
|
||||||
value={changingProp.url}
|
|
||||||
/>
|
|
||||||
<Button title="Borrar enlace" onClick={removeLink}
|
|
||||||
><CloseIcon style={svgStyle} /></Button
|
|
||||||
>
|
|
||||||
{/if}
|
{/if}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
@ -202,19 +177,14 @@ transform: scale(${1 / viewport.scale});
|
||||||
opacity: 1;
|
opacity: 1;
|
||||||
height: auto;
|
height: auto;
|
||||||
|
|
||||||
transition: opacity 0.2s, visibility 0.2s, height 0.2s;
|
transition:
|
||||||
|
opacity 0.2s,
|
||||||
|
visibility 0.2s,
|
||||||
|
height 0.2s;
|
||||||
}
|
}
|
||||||
.bubble[hidden] {
|
.bubble[hidden] {
|
||||||
visibility: hidden;
|
visibility: hidden;
|
||||||
opacity: 0;
|
opacity: 0;
|
||||||
height: 0;
|
height: 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
.bubble input {
|
|
||||||
appearance: none;
|
|
||||||
background: none;
|
|
||||||
color: inherit;
|
|
||||||
border: none;
|
|
||||||
font-size: 1.25em;
|
|
||||||
}
|
|
||||||
</style>
|
</style>
|
||||||
|
|
|
@ -83,7 +83,7 @@
|
||||||
bind:this={wrapperEl}
|
bind:this={wrapperEl}
|
||||||
/>
|
/>
|
||||||
{#if view}
|
{#if view}
|
||||||
<BubbleMenu {view} {worldY} state={updatedState} />
|
<BubbleMenu {view} {worldY} {editingLink} state={updatedState} />
|
||||||
{/if}
|
{/if}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|
|
@ -4,8 +4,13 @@
|
||||||
import { getFirstMarkInSelection } from "../ps-utils";
|
import { getFirstMarkInSelection } from "../ps-utils";
|
||||||
import { readable, type Writable } from "svelte/store";
|
import { readable, type Writable } from "svelte/store";
|
||||||
import { nanoid } from "nanoid";
|
import { nanoid } from "nanoid";
|
||||||
import { markSelectionFloatingUi } from "./floatingUi";
|
import { linkFloatingUi, selectionFloatingUi } from "./floatingUi";
|
||||||
import { autoPlacement, shift, offset } from "@floating-ui/dom";
|
import {
|
||||||
|
autoPlacement,
|
||||||
|
shift,
|
||||||
|
offset,
|
||||||
|
type ComputePositionConfig,
|
||||||
|
} from "@floating-ui/dom";
|
||||||
|
|
||||||
export let state: EditorState;
|
export let state: EditorState;
|
||||||
export let view: EditorView;
|
export let view: EditorView;
|
||||||
|
@ -76,11 +81,8 @@
|
||||||
|
|
||||||
$: shown = !!$editingLink;
|
$: shown = !!$editingLink;
|
||||||
|
|
||||||
$: linkMatch =
|
$: style = shown
|
||||||
state && getFirstMarkInSelection(view.state, view.state.schema.marks.link);
|
? selectionFloatingUi(formEl, {
|
||||||
$: style =
|
|
||||||
shown && linkMatch
|
|
||||||
? markSelectionFloatingUi(view, linkMatch, formEl, {
|
|
||||||
placement: "top",
|
placement: "top",
|
||||||
middleware: [offset(6), autoPlacement(), shift({ padding: 5 })],
|
middleware: [offset(6), autoPlacement(), shift({ padding: 5 })],
|
||||||
})
|
})
|
||||||
|
|
|
@ -3,11 +3,10 @@
|
||||||
import {
|
import {
|
||||||
getFirstMarkInSelection,
|
getFirstMarkInSelection,
|
||||||
getMarkRange,
|
getMarkRange,
|
||||||
removeMark,
|
|
||||||
selectMark,
|
selectMark,
|
||||||
} from "../ps-utils";
|
} from "../ps-utils";
|
||||||
import type { EditorView } from "prosemirror-view";
|
import type { EditorView } from "prosemirror-view";
|
||||||
import { markSelectionFloatingUi } from "./floatingUi";
|
import { linkFloatingUi, selectionFloatingUi } from "./floatingUi";
|
||||||
import { readable, type Writable } from "svelte/store";
|
import { readable, type Writable } from "svelte/store";
|
||||||
import { flip, shift, offset } from "@floating-ui/dom";
|
import { flip, shift, offset } from "@floating-ui/dom";
|
||||||
import EditIcon from "eva-icons/outline/svg/edit-outline.svg";
|
import EditIcon from "eva-icons/outline/svg/edit-outline.svg";
|
||||||
|
@ -22,9 +21,8 @@
|
||||||
$: link = state && getFirstMarkInSelection(view.state, markType);
|
$: link = state && getFirstMarkInSelection(view.state, markType);
|
||||||
$: shown = !!link && !$editingLink;
|
$: shown = !!link && !$editingLink;
|
||||||
|
|
||||||
$: style =
|
$: style = shown
|
||||||
shown && link
|
? linkFloatingUi(view, tooltipEl, {
|
||||||
? markSelectionFloatingUi(view, link, tooltipEl, {
|
|
||||||
placement: "bottom",
|
placement: "bottom",
|
||||||
middleware: [offset(6), flip(), shift({ padding: 5 })],
|
middleware: [offset(6), flip(), shift({ padding: 5 })],
|
||||||
})
|
})
|
||||||
|
@ -44,7 +42,7 @@
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<div
|
<div
|
||||||
class="absolute z-30 w-max items-center overflow-hidden rounded border border-neutral-200/70 bg-white px-1 leading-none shadow-lg dark:border-neutral-700 dark:bg-neutral-900"
|
class="absolute z-20 w-max items-center overflow-hidden rounded border border-neutral-200/70 bg-white px-1 leading-none shadow-lg dark:border-neutral-700 dark:bg-neutral-900"
|
||||||
class:flex={shown}
|
class:flex={shown}
|
||||||
class:hidden={!shown}
|
class:hidden={!shown}
|
||||||
bind:this={tooltipEl}
|
bind:this={tooltipEl}
|
||||||
|
|
|
@ -1,19 +1,16 @@
|
||||||
import { readable, type Readable } from "svelte/store";
|
import { readable, type Readable } from "svelte/store";
|
||||||
import {
|
import { computePosition, autoUpdate } from "@floating-ui/dom";
|
||||||
computePosition,
|
import type {
|
||||||
autoUpdate,
|
ComputePositionConfig,
|
||||||
autoPlacement,
|
ReferenceElement,
|
||||||
shift,
|
} from "@floating-ui/dom/src/types";
|
||||||
offset,
|
|
||||||
} from "@floating-ui/dom";
|
|
||||||
import type { ComputePositionConfig } from "@floating-ui/dom/src/types";
|
|
||||||
import type { MarkMatch } from "../ps-utils";
|
|
||||||
import type { EditorView } from "prosemirror-view";
|
import type { EditorView } from "prosemirror-view";
|
||||||
|
import { getFirstMarkInSelection } from "../ps-utils";
|
||||||
|
|
||||||
export type Style = string;
|
export type Style = string;
|
||||||
|
|
||||||
export function floatingUi(
|
export function floatingUi(
|
||||||
refEl: Element,
|
refEl: ReferenceElement,
|
||||||
tooltipEl: HTMLElement,
|
tooltipEl: HTMLElement,
|
||||||
options?: Partial<ComputePositionConfig>,
|
options?: Partial<ComputePositionConfig>,
|
||||||
): Readable<Style> {
|
): Readable<Style> {
|
||||||
|
@ -28,14 +25,30 @@ export function floatingUi(
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
export function markSelectionFloatingUi(
|
export function selectionFloatingUi(
|
||||||
view: EditorView,
|
|
||||||
mark: MarkMatch,
|
|
||||||
tooltipEl: HTMLElement,
|
tooltipEl: HTMLElement,
|
||||||
options?: Partial<ComputePositionConfig>,
|
options?: Partial<ComputePositionConfig>,
|
||||||
): Readable<Style> {
|
): Readable<Style> {
|
||||||
let { node } = (view as any).docView.domFromPos(view.state.selection.from);
|
const sel = document.getSelection();
|
||||||
if (!node || !mark || !tooltipEl) return readable("");
|
const range = sel?.getRangeAt(0);
|
||||||
if (!(node instanceof Element)) node = node.parentElement;
|
|
||||||
return floatingUi(node, tooltipEl, options);
|
if (!range) return readable("");
|
||||||
|
return floatingUi(range, tooltipEl, options);
|
||||||
|
}
|
||||||
|
|
||||||
|
export function linkFloatingUi(
|
||||||
|
view: EditorView,
|
||||||
|
tooltipEl: HTMLElement,
|
||||||
|
options?: Partial<ComputePositionConfig>,
|
||||||
|
): Readable<Style> {
|
||||||
|
const mark = getFirstMarkInSelection(
|
||||||
|
view.state,
|
||||||
|
view.state.schema.marks.link,
|
||||||
|
);
|
||||||
|
if (!mark) return readable("");
|
||||||
|
let node = view.nodeDOM(mark?.position);
|
||||||
|
if (!node) return readable("");
|
||||||
|
const element = node instanceof Element ? node : node.parentElement;
|
||||||
|
if (!element) return readable("");
|
||||||
|
return floatingUi(element, tooltipEl, options);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue