UNPKG

@sv-use/core

Version:

A collection of Svelte 5 utilities.

54 lines (53 loc) 1.79 kB
import { onDestroy } from 'svelte'; import { handleEventListener } from '../handle-event-listener/index.svelte.js'; import { noop } from '../__internal__/utils.svelte.js'; import { defaultWindow } from '../__internal__/configurable.js'; /** * Gets the range of text selected by the user or the current position of the caret. * @param options Additional options to customize the behavior. * @see https://svelte-librarian.github.io/sv-use/docs/core/browser/get-text-selection */ export function getTextSelection(options = {}) { const { autoCleanup = true, window = defaultWindow } = options; let cleanup = noop; let current = $state(null); const text = $derived.by(() => current?.toString() ?? ''); const ranges = $derived.by(() => (current ? getRangesFromSelection(current) : [])); const rects = $derived.by(() => ranges.map((range) => range.getBoundingClientRect())); if (window) { cleanup = handleEventListener(window.document, 'selectionchange', onSelectionChange, { passive: true }); } if (autoCleanup) { onDestroy(() => cleanup()); } function getRangesFromSelection(selection) { const rangeCount = selection.rangeCount ?? 0; return Array.from({ length: rangeCount }, (_, i) => selection.getRangeAt(i)); } function onSelectionChange() { current = null; if (window) { current = window.getSelection(); } } return { get current() { return current; }, set current(v) { current = v; }, get text() { return text; }, get rects() { return rects; }, get ranges() { return ranges; }, cleanup }; }