Skip to content

Instantly share code, notes, and snippets.

@ronnyroeller
Last active November 24, 2021 10:13
Show Gist options
  • Save ronnyroeller/c12e309789f2a802de4d1c6f2b4b3afa to your computer and use it in GitHub Desktop.
Save ronnyroeller/c12e309789f2a802de4d1c6f2b4b3afa to your computer and use it in GitHub Desktop.
const AVERAGE_WORD_LENGTH = 5;
const debouncedSelectionUpdate = createDebouncedUpdate(250);
const debouncedDocUpdate = createDebouncedUpdate(500);
export const debouncedPositioner = Positioner.fromPositioner(
selectionPositioner,
{
// Redrawing positioners is expensive, and can lead to jank.
// Crucially, typing can feel very laggy.
// To prevent this, we only re-render the popup when the user
// finished their keyboard/mouse input.
hasChanged: ({ state, previousState, tr, helpers }) => {
if (isForcedDebouncedUpdate(tr)) {
// This forces the positioner to re-render, when the burst of
// debounced transactions have completed
return true;
} else if (tr?.selectionSet) {
// Only once the selection is final, shall the positioner state
// be reevalulated.
// This avoids jank while the user is selecting text (or
// clicking around in the text).
const { from, empty } = state.selection;
const { from: prevFrom = 0 } = previousState?.selection ?? {};
// If click position is very different from the last, don't
// debounce
if (empty && Math.abs(prevFrom - from) > AVERAGE_WORD_LENGTH) {
return true;
}
// Allow for triple clicks (select entire paragraph)
debouncedSelectionUpdate(helpers.getCommandProp);
return false;
} else if (tr?.docChanged) {
// Debounce doc updates, (i.e. user typing) until they are
// complete.
// This avoids lag while the user is typing.
// We can't use the old state once the delay passed because that
// state might be outdated (e.g. collab editing). To work around
// that, getCommandProp() grants access to the current Remirror
// state.
debouncedDocUpdate(helpers.getCommandProp);
return false;
}
// Some other transaction reason, return false to prevent render
// Hint for debugging: Check the keys of the (private) `tr.meta`
// to understand what happened
return false;
},
...
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment