Something went wrong. Try again.
Mirror: React hooks for accessible, common web interactions. UI super powers without the UI.
Something went wrong. Try again.
1.8 kB · 64 lines
TypeScript
at main
1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465import { contains } from './element';import { getActive } from './focus';
export interface RestoreSelection { element: HTMLElement; restore(): void;}
const hasSelection = (node: HTMLElement): node is HTMLInputElement => typeof (node as HTMLInputElement).selectionStart === 'number' && typeof (node as HTMLInputElement).selectionEnd === 'number';
/** Snapshots the current focus or selection target, optinally using a ref if it's passed. */export const snapshotSelection = ( node?: HTMLElement | null): RestoreSelection | null => { const target = getActive(); const element = node && target && node !== target ? node : target; if (!element || !target) { return null; } else if (hasSelection(element)) { const { selectionStart, selectionEnd, selectionDirection } = element; return { element, restore() { element.focus(); element.setSelectionRange( selectionStart, selectionEnd, selectionDirection || undefined ); }, }; }
let range: Range | undefined;
const selection = window.getSelection(); if (selection && selection.rangeCount) { const _range = selection.getRangeAt(0); if (_range.startContainer && contains(target, _range.startContainer)) { range = _range; } }
return { element, restore() { element.focus(); const selection = window.getSelection(); if (range && selection) { selection.removeAllRanges(); selection.addRange(range); } }, };};
/** Restores a given snapshot of a selection, falling back to a simple focus. */export const restoreSelection = (selection: RestoreSelection | null) => { if (selection && selection.element.parentNode) { selection.restore(); }};