Change selection in transactionFilter

For catching and changing the selection before state update, is this the correct way? And if so, how is a ChangeDesc created?

// extension
const changeSelection = () => {
  return EditorState.transactionFilter.of((tr) => {
    tr.newSelection.main.map(/*ChangeDesc*/)
    return tr
  })
}

Since SelectionRange.map is a pure function, this does absolutely nothing. You have to return a transaction description that adds your changes to the return value of your filter. But I don’t really understand what you’re trying to do, so I can’t say a lot about what it should look like.

What I am trying to do is limit the selection range to within some allowed range. For example:
Suppose we have chosen allowed range as {from: 10, to: 20}. If the selection goes beyond this allowed range, say {from:15 to:21}, then change the selection to {from: 15, to: 20}. Or in case of empty selection, if the cursor position is greater than 20, change it to 20.

Thank you Marijn. And thank you for Code Mirror. I have recommended to my team to sponsor you.

Assuming you can get allowedFrom and allowedTo from somewhere, a filter like this should work:

    EditorState.transactionFilter.of(tr => {
      let sel = tr.newSelection
      if (!sel.ranges.some(({from, to}) => from < allowedFrom || to > allowedTo))
        return tr
      let clip = n => Math.min(Math.max(n, allowedFrom), allowedTo)
      return [tr, {
        selection: EditorSelection.create(sel.ranges.map(
          r => EditorSelection.range(clip(r.anchor), clip(r.head))), sel.mainIndex)
      }]
    })
1 Like

Awesome. Thanks again.