@portabletext/editor 1.48.9 → 1.48.11

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (80) hide show
  1. package/lib/_chunks-cjs/editor-provider.cjs +879 -169
  2. package/lib/_chunks-cjs/editor-provider.cjs.map +1 -1
  3. package/lib/_chunks-cjs/selector.get-focus-inline-object.cjs +2 -2
  4. package/lib/_chunks-cjs/selector.get-focus-inline-object.cjs.map +1 -1
  5. package/lib/_chunks-cjs/selector.get-text-before.cjs +2 -2
  6. package/lib/_chunks-cjs/selector.get-text-before.cjs.map +1 -1
  7. package/lib/_chunks-cjs/selector.is-selecting-entire-blocks.cjs +464 -19
  8. package/lib/_chunks-cjs/selector.is-selecting-entire-blocks.cjs.map +1 -1
  9. package/lib/_chunks-cjs/util.selection-point-to-block-offset.cjs +9 -1
  10. package/lib/_chunks-cjs/util.selection-point-to-block-offset.cjs.map +1 -1
  11. package/lib/_chunks-cjs/util.slice-blocks.cjs +2 -2
  12. package/lib/_chunks-es/editor-provider.js +773 -65
  13. package/lib/_chunks-es/editor-provider.js.map +1 -1
  14. package/lib/_chunks-es/selector.get-focus-inline-object.js +1 -1
  15. package/lib/_chunks-es/selector.get-text-before.js +1 -1
  16. package/lib/_chunks-es/selector.is-selecting-entire-blocks.js +448 -3
  17. package/lib/_chunks-es/selector.is-selecting-entire-blocks.js.map +1 -1
  18. package/lib/_chunks-es/util.selection-point-to-block-offset.js +9 -1
  19. package/lib/_chunks-es/util.selection-point-to-block-offset.js.map +1 -1
  20. package/lib/_chunks-es/util.slice-blocks.js +2 -2
  21. package/lib/behaviors/index.cjs +27 -377
  22. package/lib/behaviors/index.cjs.map +1 -1
  23. package/lib/behaviors/index.d.cts +3696 -13915
  24. package/lib/behaviors/index.d.ts +3696 -13915
  25. package/lib/behaviors/index.js +22 -377
  26. package/lib/behaviors/index.js.map +1 -1
  27. package/lib/index.cjs +17 -17
  28. package/lib/index.cjs.map +1 -1
  29. package/lib/index.d.cts +3008 -394
  30. package/lib/index.d.ts +3008 -394
  31. package/lib/index.js +4 -5
  32. package/lib/index.js.map +1 -1
  33. package/lib/plugins/index.cjs +347 -30
  34. package/lib/plugins/index.cjs.map +1 -1
  35. package/lib/plugins/index.d.cts +3008 -395
  36. package/lib/plugins/index.d.ts +3008 -395
  37. package/lib/plugins/index.js +324 -8
  38. package/lib/plugins/index.js.map +1 -1
  39. package/lib/selectors/index.cjs +29 -29
  40. package/lib/selectors/index.cjs.map +1 -1
  41. package/lib/selectors/index.d.cts +3007 -387
  42. package/lib/selectors/index.d.ts +3007 -387
  43. package/lib/selectors/index.js +2 -3
  44. package/lib/selectors/index.js.map +1 -1
  45. package/lib/utils/index.cjs +5 -5
  46. package/lib/utils/index.cjs.map +1 -1
  47. package/lib/utils/index.d.cts +3008 -389
  48. package/lib/utils/index.d.ts +3008 -389
  49. package/lib/utils/index.js +2 -3
  50. package/lib/utils/index.js.map +1 -1
  51. package/package.json +1 -1
  52. package/src/behaviors/behavior.emoji-picker.ts +0 -6
  53. package/src/behaviors/behavior.markdown.ts +0 -48
  54. package/src/behaviors/index.ts +0 -15
  55. package/src/editor/create-editor.ts +0 -3
  56. package/src/editor/editor-machine.ts +105 -52
  57. package/src/editor/sync-machine.ts +10 -4
  58. package/src/internal-utils/__tests__/operationToPatches.test.ts +0 -2
  59. package/src/internal-utils/__tests__/patchToOperations.test.ts +0 -2
  60. package/src/plugins/plugin.core.tsx +1 -1
  61. package/lib/_chunks-cjs/behavior.core.cjs +0 -700
  62. package/lib/_chunks-cjs/behavior.core.cjs.map +0 -1
  63. package/lib/_chunks-cjs/behavior.markdown.cjs +0 -321
  64. package/lib/_chunks-cjs/behavior.markdown.cjs.map +0 -1
  65. package/lib/_chunks-cjs/selector.is-overlapping-selection.cjs +0 -449
  66. package/lib/_chunks-cjs/selector.is-overlapping-selection.cjs.map +0 -1
  67. package/lib/_chunks-cjs/util.get-selection-start-point.cjs +0 -10
  68. package/lib/_chunks-cjs/util.get-selection-start-point.cjs.map +0 -1
  69. package/lib/_chunks-es/behavior.core.js +0 -703
  70. package/lib/_chunks-es/behavior.core.js.map +0 -1
  71. package/lib/_chunks-es/behavior.markdown.js +0 -325
  72. package/lib/_chunks-es/behavior.markdown.js.map +0 -1
  73. package/lib/_chunks-es/selector.is-overlapping-selection.js +0 -451
  74. package/lib/_chunks-es/selector.is-overlapping-selection.js.map +0 -1
  75. package/lib/_chunks-es/util.get-selection-start-point.js +0 -11
  76. package/lib/_chunks-es/util.get-selection-start-point.js.map +0 -1
  77. package/src/behaviors/behavior.code-editor.ts +0 -77
  78. package/src/behaviors/behavior.links.ts +0 -84
  79. package/src/internal-utils/looks-like-url.test.ts +0 -19
  80. package/src/internal-utils/looks-like-url.ts +0 -15
@@ -1,386 +1,31 @@
1
- import { defineBehavior, raise, isHotkey, forward, execute, effect } from "../_chunks-es/behavior.core.js";
2
- import { coreBehaviors } from "../_chunks-es/behavior.core.js";
3
- import { getSelectedBlocks, getFirstBlock, getLastBlock, getFocusTextBlock, isSelectionCollapsed, getFocusSpan } from "../_chunks-es/selector.is-overlapping-selection.js";
4
- import { createActor, setup, assign, assertEvent } from "xstate";
5
- import { getBlockTextBefore } from "../_chunks-es/selector.get-text-before.js";
6
- import { createMarkdownBehaviors } from "../_chunks-es/behavior.markdown.js";
7
- function createCodeEditorBehaviors(config) {
8
- return [defineBehavior({
9
- on: "keyboard.keydown",
10
- guard: ({
11
- snapshot,
12
- event
13
- }) => {
14
- const isMoveUpShortcut = isHotkey(config.moveBlockUpShortcut, event.originEvent), firstBlock = getFirstBlock(snapshot), selectedBlocks = getSelectedBlocks(snapshot), blocksAbove = firstBlock?.node._key !== selectedBlocks[0]?.node._key;
15
- return !isMoveUpShortcut || !blocksAbove ? !1 : {
16
- paths: selectedBlocks.map((block) => block.path)
17
- };
18
- },
19
- actions: [(_, {
20
- paths
21
- }) => paths.map((at) => raise({
22
- type: "move.block up",
23
- at
24
- }))]
25
- }), defineBehavior({
26
- on: "keyboard.keydown",
27
- guard: ({
28
- snapshot,
29
- event
30
- }) => {
31
- const isMoveDownShortcut = isHotkey(config.moveBlockDownShortcut, event.originEvent), lastBlock = getLastBlock(snapshot), selectedBlocks = getSelectedBlocks(snapshot), blocksBelow = lastBlock?.node._key !== selectedBlocks[selectedBlocks.length - 1]?.node._key;
32
- return !isMoveDownShortcut || !blocksBelow ? !1 : {
33
- paths: selectedBlocks.map((block) => block.path).reverse()
34
- };
35
- },
36
- actions: [(_, {
37
- paths
38
- }) => paths.map((at) => raise({
39
- type: "move.block down",
40
- at
41
- }))]
42
- })];
1
+ function execute(event) {
2
+ return {
3
+ type: "execute",
4
+ event
5
+ };
43
6
  }
44
- const emojiCharRegEx = /^[a-zA-Z-_0-9]{1}$/, incompleteEmojiRegEx = /:([a-zA-Z-_0-9]+)$/, emojiRegEx = /:([a-zA-Z-_0-9]+):$/;
45
- function createEmojiPickerBehaviors(config) {
46
- const emojiPickerActor = createActor(createEmojiPickerMachine());
47
- return emojiPickerActor.start(), emojiPickerActor.subscribe((state) => {
48
- config.onMatchesChanged({
49
- matches: state.context.matches
50
- }), config.onSelectedIndexChanged({
51
- selectedIndex: state.context.selectedIndex
52
- });
53
- }), [defineBehavior({
54
- on: "insert.text",
55
- guard: ({
56
- snapshot,
57
- event
58
- }) => {
59
- if (event.text === ":")
60
- return !1;
61
- if (!emojiCharRegEx.test(event.text))
62
- return {
63
- emojis: []
64
- };
65
- const focusBlock = getFocusTextBlock(snapshot), emojiKeyword = `${getBlockTextBefore(snapshot)}${event.text}`.match(incompleteEmojiRegEx)?.[1];
66
- return !focusBlock || emojiKeyword === void 0 ? {
67
- emojis: []
68
- } : {
69
- emojis: config.matchEmojis({
70
- keyword: emojiKeyword
71
- })
72
- };
73
- },
74
- actions: [({
75
- event
76
- }, params) => [{
77
- type: "effect",
78
- effect: () => {
79
- emojiPickerActor.send({
80
- type: "emojis found",
81
- matches: params.emojis
82
- });
83
- }
84
- }, forward(event)]]
85
- }), defineBehavior({
86
- on: "insert.text",
87
- guard: ({
88
- snapshot,
89
- event
90
- }) => {
91
- if (event.text !== ":")
92
- return !1;
93
- const matches = emojiPickerActor.getSnapshot().context.matches, selectedIndex = emojiPickerActor.getSnapshot().context.selectedIndex, emoji = matches[selectedIndex] ? config.parseMatch({
94
- match: matches[selectedIndex]
95
- }) : void 0, focusBlock = getFocusTextBlock(snapshot), textBefore = getBlockTextBefore(snapshot), emojiKeyword = `${textBefore}:`.match(emojiRegEx)?.[1];
96
- if (!focusBlock || emojiKeyword === void 0)
97
- return !1;
98
- const emojiStringLength = emojiKeyword.length + 2;
99
- return emoji ? {
100
- focusBlock,
101
- emoji,
102
- emojiStringLength,
103
- textBeforeLength: textBefore.length + 1
104
- } : !1;
105
- },
106
- actions: [() => [execute({
107
- type: "insert.text",
108
- text: ":"
109
- })], (_, params) => [effect(() => {
110
- emojiPickerActor.send({
111
- type: "select"
112
- });
113
- }), execute({
114
- type: "delete.text",
115
- at: {
116
- anchor: {
117
- path: params.focusBlock.path,
118
- offset: params.textBeforeLength - params.emojiStringLength
119
- },
120
- focus: {
121
- path: params.focusBlock.path,
122
- offset: params.textBeforeLength
123
- }
124
- }
125
- }), execute({
126
- type: "insert.text",
127
- text: params.emoji
128
- })]]
129
- }), defineBehavior({
130
- on: "keyboard.keydown",
131
- guard: ({
132
- snapshot,
133
- event
134
- }) => {
135
- const matches = emojiPickerActor.getSnapshot().context.matches;
136
- if (matches.length === 0)
137
- return !1;
138
- if (isHotkey("Escape", event.originEvent))
139
- return {
140
- action: "reset"
141
- };
142
- const isEnter = isHotkey("Enter", event.originEvent), isTab = isHotkey("Tab", event.originEvent);
143
- if (isEnter || isTab) {
144
- const selectedIndex = emojiPickerActor.getSnapshot().context.selectedIndex, emoji = matches[selectedIndex] ? config.parseMatch({
145
- match: matches[selectedIndex]
146
- }) : void 0;
147
- if (!emoji)
148
- return !1;
149
- const focusBlock = getFocusTextBlock(snapshot), textBefore = getBlockTextBefore(snapshot), emojiKeyword = textBefore.match(incompleteEmojiRegEx)?.[1];
150
- if (!focusBlock || emojiKeyword === void 0)
151
- return !1;
152
- const emojiStringLength = emojiKeyword.length + 1;
153
- return emoji ? {
154
- action: "select",
155
- focusBlock,
156
- emoji,
157
- emojiStringLength,
158
- textBeforeLength: textBefore.length
159
- } : !1;
160
- }
161
- const isArrowDown = isHotkey("ArrowDown", event.originEvent), isArrowUp = isHotkey("ArrowUp", event.originEvent);
162
- return isArrowDown && matches.length > 0 ? {
163
- action: "navigate down"
164
- } : isArrowUp && matches.length > 0 ? {
165
- action: "navigate up"
166
- } : !1;
167
- },
168
- actions: [(_, params) => params.action === "select" ? [effect(() => {
169
- emojiPickerActor.send({
170
- type: "select"
171
- });
172
- }), execute({
173
- type: "delete.text",
174
- at: {
175
- anchor: {
176
- path: params.focusBlock.path,
177
- offset: params.textBeforeLength - params.emojiStringLength
178
- },
179
- focus: {
180
- path: params.focusBlock.path,
181
- offset: params.textBeforeLength
182
- }
183
- }
184
- }), execute({
185
- type: "insert.text",
186
- text: params.emoji
187
- })] : params.action === "navigate up" ? [
188
- // If we are navigating then we want to hijack the key event
189
- effect(() => {
190
- emojiPickerActor.send({
191
- type: "navigate up"
192
- });
193
- })
194
- ] : params.action === "navigate down" ? [
195
- // If we are navigating then we want to hijack the key event
196
- effect(() => {
197
- emojiPickerActor.send({
198
- type: "navigate down"
199
- });
200
- })
201
- ] : [effect(() => {
202
- emojiPickerActor.send({
203
- type: "reset"
204
- });
205
- })]]
206
- }), defineBehavior({
207
- on: "delete.backward",
208
- guard: ({
209
- snapshot,
210
- event
211
- }) => {
212
- if (event.unit !== "character" || emojiPickerActor.getSnapshot().context.matches.length === 0)
213
- return !1;
214
- const focusBlock = getFocusTextBlock(snapshot), textBefore = getBlockTextBefore(snapshot), emojiKeyword = textBefore.slice(0, textBefore.length - 1).match(incompleteEmojiRegEx)?.[1];
215
- return !focusBlock || emojiKeyword === void 0 ? {
216
- emojis: []
217
- } : {
218
- emojis: config.matchEmojis({
219
- keyword: emojiKeyword
220
- })
221
- };
222
- },
223
- actions: [({
224
- event
225
- }, params) => [{
226
- type: "effect",
227
- effect: () => {
228
- emojiPickerActor.send({
229
- type: "emojis found",
230
- matches: params.emojis
231
- });
232
- }
233
- }, forward(event)]]
234
- })];
7
+ function forward(event) {
8
+ return {
9
+ type: "forward",
10
+ event
11
+ };
235
12
  }
236
- function createEmojiPickerMachine() {
237
- return setup({
238
- types: {
239
- context: {},
240
- events: {}
241
- },
242
- actions: {
243
- "assign matches": assign({
244
- matches: ({
245
- event
246
- }) => (assertEvent(event, "emojis found"), event.matches)
247
- }),
248
- "reset matches": assign({
249
- matches: []
250
- }),
251
- "reset selected index": assign({
252
- selectedIndex: 0
253
- }),
254
- "increment selected index": assign({
255
- selectedIndex: ({
256
- context
257
- }) => context.selectedIndex === context.matches.length - 1 ? 0 : context.selectedIndex + 1
258
- }),
259
- "decrement selected index": assign({
260
- selectedIndex: ({
261
- context
262
- }) => context.selectedIndex === 0 ? context.matches.length - 1 : context.selectedIndex - 1
263
- })
264
- },
265
- guards: {
266
- "no matches": ({
267
- context
268
- }) => context.matches.length === 0
269
- }
270
- }).createMachine({
271
- id: "emoji picker",
272
- context: {
273
- matches: [],
274
- selectedIndex: 0
275
- },
276
- initial: "idle",
277
- states: {
278
- idle: {
279
- on: {
280
- "emojis found": {
281
- actions: "assign matches",
282
- target: "showing matches"
283
- }
284
- }
285
- },
286
- "showing matches": {
287
- always: {
288
- guard: "no matches",
289
- target: "idle"
290
- },
291
- exit: ["reset selected index"],
292
- on: {
293
- "emojis found": {
294
- actions: "assign matches"
295
- },
296
- "navigate down": {
297
- actions: "increment selected index"
298
- },
299
- "navigate up": {
300
- actions: "decrement selected index"
301
- },
302
- reset: {
303
- target: "idle",
304
- actions: ["reset selected index", "reset matches"]
305
- },
306
- select: {
307
- target: "idle",
308
- actions: ["reset selected index", "reset matches"]
309
- }
310
- }
311
- }
312
- }
313
- });
13
+ function raise(event) {
14
+ return {
15
+ type: "raise",
16
+ event
17
+ };
314
18
  }
315
- function looksLikeUrl(text) {
316
- let looksLikeUrl2 = !1;
317
- try {
318
- const url = new URL(text);
319
- if (!sensibleProtocols.includes(url.protocol))
320
- return !1;
321
- looksLikeUrl2 = !0;
322
- } catch {
323
- }
324
- return looksLikeUrl2;
19
+ function effect(effect2) {
20
+ return {
21
+ type: "effect",
22
+ effect: effect2
23
+ };
325
24
  }
326
- const sensibleProtocols = ["http:", "https:", "mailto:", "tel:"];
327
- function createLinkBehaviors(config) {
328
- const pasteLinkOnSelection = defineBehavior({
329
- on: "clipboard.paste",
330
- guard: ({
331
- snapshot,
332
- event
333
- }) => {
334
- const selectionCollapsed = isSelectionCollapsed(snapshot), text = event.originEvent.dataTransfer.getData("text/plain"), url = looksLikeUrl(text) ? text : void 0, annotation = url !== void 0 ? config.linkAnnotation?.({
335
- url,
336
- schema: snapshot.context.schema
337
- }) : void 0;
338
- return annotation && !selectionCollapsed ? {
339
- annotation
340
- } : !1;
341
- },
342
- actions: [(_, {
343
- annotation
344
- }) => [execute({
345
- type: "annotation.add",
346
- annotation
347
- })]]
348
- }), pasteLinkAtCaret = defineBehavior({
349
- on: "clipboard.paste",
350
- guard: ({
351
- snapshot,
352
- event
353
- }) => {
354
- const focusSpan = getFocusSpan(snapshot), selectionCollapsed = isSelectionCollapsed(snapshot);
355
- if (!focusSpan || !selectionCollapsed)
356
- return !1;
357
- const text = event.originEvent.dataTransfer.getData("text/plain"), url = looksLikeUrl(text) ? text : void 0, annotation = url !== void 0 ? config.linkAnnotation?.({
358
- url,
359
- schema: snapshot.context.schema
360
- }) : void 0;
361
- return url && annotation && selectionCollapsed ? {
362
- focusSpan,
363
- annotation,
364
- url
365
- } : !1;
366
- },
367
- actions: [(_, {
368
- annotation,
369
- url
370
- }) => [execute({
371
- type: "insert.span",
372
- text: url,
373
- annotations: [annotation]
374
- })]]
375
- });
376
- return [pasteLinkOnSelection, pasteLinkAtCaret];
25
+ function defineBehavior(behavior) {
26
+ return behavior;
377
27
  }
378
28
  export {
379
- coreBehaviors,
380
- createCodeEditorBehaviors,
381
- createEmojiPickerBehaviors,
382
- createLinkBehaviors,
383
- createMarkdownBehaviors,
384
29
  defineBehavior,
385
30
  effect,
386
31
  execute,
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sources":["../../src/behaviors/behavior.code-editor.ts","../../src/behaviors/behavior.emoji-picker.ts","../../src/internal-utils/looks-like-url.ts","../../src/behaviors/behavior.links.ts"],"sourcesContent":["import {isHotkey} from '../internal-utils/is-hotkey'\nimport * as selectors from '../selectors'\nimport {raise} from './behavior.types.action'\nimport {defineBehavior} from './behavior.types.behavior'\n\n/**\n * @beta\n */\nexport type CodeEditorBehaviorsConfig = {\n moveBlockUpShortcut: string\n moveBlockDownShortcut: string\n}\n\n/**\n * @beta\n */\nexport function createCodeEditorBehaviors(config: CodeEditorBehaviorsConfig) {\n return [\n defineBehavior({\n on: 'keyboard.keydown',\n guard: ({snapshot, event}) => {\n const isMoveUpShortcut = isHotkey(\n config.moveBlockUpShortcut,\n event.originEvent,\n )\n const firstBlock = selectors.getFirstBlock(snapshot)\n const selectedBlocks = selectors.getSelectedBlocks(snapshot)\n const blocksAbove =\n firstBlock?.node._key !== selectedBlocks[0]?.node._key\n\n if (!isMoveUpShortcut || !blocksAbove) {\n return false\n }\n\n return {paths: selectedBlocks.map((block) => block.path)}\n },\n actions: [\n (_, {paths}) =>\n paths.map((at) =>\n raise({\n type: 'move.block up',\n at,\n }),\n ),\n ],\n }),\n defineBehavior({\n on: 'keyboard.keydown',\n guard: ({snapshot, event}) => {\n const isMoveDownShortcut = isHotkey(\n config.moveBlockDownShortcut,\n event.originEvent,\n )\n const lastBlock = selectors.getLastBlock(snapshot)\n const selectedBlocks = selectors.getSelectedBlocks(snapshot)\n const blocksBelow =\n lastBlock?.node._key !==\n selectedBlocks[selectedBlocks.length - 1]?.node._key\n\n if (!isMoveDownShortcut || !blocksBelow) {\n return false\n }\n\n return {paths: selectedBlocks.map((block) => block.path).reverse()}\n },\n actions: [\n (_, {paths}) =>\n paths.map((at) =>\n raise({\n type: 'move.block down',\n at,\n }),\n ),\n ],\n }),\n ]\n}\n","import {assertEvent, assign, createActor, setup} from 'xstate'\nimport {isHotkey} from '../internal-utils/is-hotkey'\nimport * as selectors from '../selectors'\nimport {effect, execute, forward} from './behavior.types.action'\nimport {defineBehavior} from './behavior.types.behavior'\n\nconst emojiCharRegEx = /^[a-zA-Z-_0-9]{1}$/\nconst incompleteEmojiRegEx = /:([a-zA-Z-_0-9]+)$/\nconst emojiRegEx = /:([a-zA-Z-_0-9]+):$/\n\n/**\n * @beta\n */\nexport type EmojiPickerBehaviorsConfig<TEmojiMatch> = {\n /**\n * Match emojis by keyword.\n */\n matchEmojis: ({keyword}: {keyword: string}) => Array<TEmojiMatch>\n onMatchesChanged: ({matches}: {matches: Array<TEmojiMatch>}) => void\n onSelectedIndexChanged: ({selectedIndex}: {selectedIndex: number}) => void\n /**\n * Parse an emoji match to a string that will be inserted into the editor.\n */\n parseMatch: ({match}: {match: TEmojiMatch}) => string | undefined\n}\n\n/**\n * @beta\n */\nexport function createEmojiPickerBehaviors<TEmojiMatch>(\n config: EmojiPickerBehaviorsConfig<TEmojiMatch>,\n) {\n const emojiPickerActor = createActor(createEmojiPickerMachine<TEmojiMatch>())\n emojiPickerActor.start()\n emojiPickerActor.subscribe((state) => {\n config.onMatchesChanged({matches: state.context.matches})\n config.onSelectedIndexChanged({selectedIndex: state.context.selectedIndex})\n })\n\n return [\n defineBehavior({\n on: 'insert.text',\n guard: ({snapshot, event}) => {\n if (event.text === ':') {\n return false\n }\n\n const isEmojiChar = emojiCharRegEx.test(event.text)\n\n if (!isEmojiChar) {\n return {emojis: []}\n }\n\n const focusBlock = selectors.getFocusTextBlock(snapshot)\n const textBefore = selectors.getBlockTextBefore(snapshot)\n const emojiKeyword = `${textBefore}${event.text}`.match(\n incompleteEmojiRegEx,\n )?.[1]\n\n if (!focusBlock || emojiKeyword === undefined) {\n return {emojis: []}\n }\n\n const emojis = config.matchEmojis({keyword: emojiKeyword})\n\n return {emojis}\n },\n actions: [\n ({event}, params) => [\n {\n type: 'effect',\n effect: () => {\n emojiPickerActor.send({\n type: 'emojis found',\n matches: params.emojis,\n })\n },\n },\n forward(event),\n ],\n ],\n }),\n defineBehavior({\n on: 'insert.text',\n guard: ({snapshot, event}) => {\n const isColon = event.text === ':'\n\n if (!isColon) {\n return false\n }\n\n const matches = emojiPickerActor.getSnapshot().context.matches\n const selectedIndex =\n emojiPickerActor.getSnapshot().context.selectedIndex\n const emoji = matches[selectedIndex]\n ? config.parseMatch({match: matches[selectedIndex]})\n : undefined\n\n const focusBlock = selectors.getFocusTextBlock(snapshot)\n const textBefore = selectors.getBlockTextBefore(snapshot)\n const emojiKeyword = `${textBefore}:`.match(emojiRegEx)?.[1]\n\n if (!focusBlock || emojiKeyword === undefined) {\n return false\n }\n\n const emojiStringLength = emojiKeyword.length + 2\n\n if (emoji) {\n return {\n focusBlock,\n emoji,\n emojiStringLength,\n textBeforeLength: textBefore.length + 1,\n }\n }\n\n return false\n },\n actions: [\n () => [\n execute({\n type: 'insert.text',\n text: ':',\n }),\n ],\n (_, params) => [\n effect(() => {\n emojiPickerActor.send({type: 'select'})\n }),\n execute({\n type: 'delete.text',\n at: {\n anchor: {\n path: params.focusBlock.path,\n offset: params.textBeforeLength - params.emojiStringLength,\n },\n focus: {\n path: params.focusBlock.path,\n offset: params.textBeforeLength,\n },\n },\n }),\n execute({\n type: 'insert.text',\n text: params.emoji,\n }),\n ],\n ],\n }),\n defineBehavior({\n on: 'keyboard.keydown',\n guard: ({snapshot, event}) => {\n const matches = emojiPickerActor.getSnapshot().context.matches\n\n if (matches.length === 0) {\n return false\n }\n\n const isEscape = isHotkey('Escape', event.originEvent)\n\n if (isEscape) {\n return {action: 'reset' as const}\n }\n\n const isEnter = isHotkey('Enter', event.originEvent)\n const isTab = isHotkey('Tab', event.originEvent)\n\n if (isEnter || isTab) {\n const selectedIndex =\n emojiPickerActor.getSnapshot().context.selectedIndex\n\n const emoji = matches[selectedIndex]\n ? config.parseMatch({match: matches[selectedIndex]})\n : undefined\n\n if (!emoji) {\n return false\n }\n\n const focusBlock = selectors.getFocusTextBlock(snapshot)\n const textBefore = selectors.getBlockTextBefore(snapshot)\n const emojiKeyword = textBefore.match(incompleteEmojiRegEx)?.[1]\n\n if (!focusBlock || emojiKeyword === undefined) {\n return false\n }\n\n const emojiStringLength = emojiKeyword.length + 1\n\n if (emoji) {\n return {\n action: 'select' as const,\n focusBlock,\n emoji,\n emojiStringLength,\n textBeforeLength: textBefore.length,\n }\n }\n\n return false\n }\n\n const isArrowDown = isHotkey('ArrowDown', event.originEvent)\n const isArrowUp = isHotkey('ArrowUp', event.originEvent)\n\n if (isArrowDown && matches.length > 0) {\n return {action: 'navigate down' as const}\n }\n\n if (isArrowUp && matches.length > 0) {\n return {action: 'navigate up' as const}\n }\n\n return false\n },\n actions: [\n (_, params) => {\n if (params.action === 'select') {\n return [\n effect(() => {\n emojiPickerActor.send({type: 'select'})\n }),\n execute({\n type: 'delete.text',\n at: {\n anchor: {\n path: params.focusBlock.path,\n offset: params.textBeforeLength - params.emojiStringLength,\n },\n focus: {\n path: params.focusBlock.path,\n offset: params.textBeforeLength,\n },\n },\n }),\n execute({\n type: 'insert.text',\n text: params.emoji,\n }),\n ]\n }\n\n if (params.action === 'navigate up') {\n return [\n // If we are navigating then we want to hijack the key event\n effect(() => {\n emojiPickerActor.send({type: 'navigate up'})\n }),\n ]\n }\n\n if (params.action === 'navigate down') {\n return [\n // If we are navigating then we want to hijack the key event\n effect(() => {\n emojiPickerActor.send({type: 'navigate down'})\n }),\n ]\n }\n\n return [\n effect(() => {\n emojiPickerActor.send({type: 'reset'})\n }),\n ]\n },\n ],\n }),\n defineBehavior({\n on: 'delete.backward',\n guard: ({snapshot, event}) => {\n if (event.unit !== 'character') {\n return false\n }\n\n const matches = emojiPickerActor.getSnapshot().context.matches\n\n if (matches.length === 0) {\n return false\n }\n\n const focusBlock = selectors.getFocusTextBlock(snapshot)\n const textBefore = selectors.getBlockTextBefore(snapshot)\n const emojiKeyword = textBefore\n .slice(0, textBefore.length - 1)\n .match(incompleteEmojiRegEx)?.[1]\n\n if (!focusBlock || emojiKeyword === undefined) {\n return {emojis: []}\n }\n\n const emojis = config.matchEmojis({keyword: emojiKeyword})\n\n return {emojis}\n },\n actions: [\n ({event}, params) => [\n {\n type: 'effect',\n effect: () => {\n emojiPickerActor.send({\n type: 'emojis found',\n matches: params.emojis,\n })\n },\n },\n forward(event),\n ],\n ],\n }),\n ]\n}\n\nfunction createEmojiPickerMachine<TEmojiSearchResult>() {\n return setup({\n types: {\n context: {} as {\n matches: Array<TEmojiSearchResult>\n selectedIndex: number\n },\n events: {} as\n | {\n type: 'emojis found'\n matches: Array<TEmojiSearchResult>\n }\n | {\n type: 'navigate down' | 'navigate up' | 'select' | 'reset'\n },\n },\n actions: {\n 'assign matches': assign({\n matches: ({event}) => {\n assertEvent(event, 'emojis found')\n return event.matches\n },\n }),\n 'reset matches': assign({\n matches: [],\n }),\n 'reset selected index': assign({\n selectedIndex: 0,\n }),\n 'increment selected index': assign({\n selectedIndex: ({context}) => {\n if (context.selectedIndex === context.matches.length - 1) {\n return 0\n }\n return context.selectedIndex + 1\n },\n }),\n 'decrement selected index': assign({\n selectedIndex: ({context}) => {\n if (context.selectedIndex === 0) {\n return context.matches.length - 1\n }\n return context.selectedIndex - 1\n },\n }),\n },\n guards: {\n 'no matches': ({context}) => context.matches.length === 0,\n },\n }).createMachine({\n id: 'emoji picker',\n context: {\n matches: [],\n selectedIndex: 0,\n },\n initial: 'idle',\n states: {\n 'idle': {\n on: {\n 'emojis found': {\n actions: 'assign matches',\n target: 'showing matches',\n },\n },\n },\n 'showing matches': {\n always: {\n guard: 'no matches',\n target: 'idle',\n },\n exit: ['reset selected index'],\n on: {\n 'emojis found': {\n actions: 'assign matches',\n },\n 'navigate down': {\n actions: 'increment selected index',\n },\n 'navigate up': {\n actions: 'decrement selected index',\n },\n 'reset': {\n target: 'idle',\n actions: ['reset selected index', 'reset matches'],\n },\n 'select': {\n target: 'idle',\n actions: ['reset selected index', 'reset matches'],\n },\n },\n },\n },\n })\n}\n","export function looksLikeUrl(text: string) {\n let looksLikeUrl = false\n try {\n const url = new URL(text)\n\n if (!sensibleProtocols.includes(url.protocol)) {\n return false\n }\n\n looksLikeUrl = true\n } catch {}\n return looksLikeUrl\n}\n\nconst sensibleProtocols = ['http:', 'https:', 'mailto:', 'tel:']\n","import type {EditorSchema} from '../editor/editor-schema'\nimport {looksLikeUrl} from '../internal-utils/looks-like-url'\nimport * as selectors from '../selectors'\nimport {execute} from './behavior.types.action'\nimport {defineBehavior} from './behavior.types.behavior'\n\n/**\n * @beta\n */\nexport type LinkBehaviorsConfig = {\n linkAnnotation?: (context: {\n schema: EditorSchema\n url: string\n }) => {name: string; value: {[prop: string]: unknown}} | undefined\n}\n\n/**\n * @beta\n */\nexport function createLinkBehaviors(config: LinkBehaviorsConfig) {\n const pasteLinkOnSelection = defineBehavior({\n on: 'clipboard.paste',\n guard: ({snapshot, event}) => {\n const selectionCollapsed = selectors.isSelectionCollapsed(snapshot)\n const text = event.originEvent.dataTransfer.getData('text/plain')\n const url = looksLikeUrl(text) ? text : undefined\n const annotation =\n url !== undefined\n ? config.linkAnnotation?.({url, schema: snapshot.context.schema})\n : undefined\n\n if (annotation && !selectionCollapsed) {\n return {annotation}\n }\n\n return false\n },\n actions: [\n (_, {annotation}) => [\n execute({\n type: 'annotation.add',\n annotation,\n }),\n ],\n ],\n })\n const pasteLinkAtCaret = defineBehavior({\n on: 'clipboard.paste',\n guard: ({snapshot, event}) => {\n const focusSpan = selectors.getFocusSpan(snapshot)\n const selectionCollapsed = selectors.isSelectionCollapsed(snapshot)\n\n if (!focusSpan || !selectionCollapsed) {\n return false\n }\n\n const text = event.originEvent.dataTransfer.getData('text/plain')\n const url = looksLikeUrl(text) ? text : undefined\n const annotation =\n url !== undefined\n ? config.linkAnnotation?.({url, schema: snapshot.context.schema})\n : undefined\n\n if (url && annotation && selectionCollapsed) {\n return {focusSpan, annotation, url}\n }\n\n return false\n },\n actions: [\n (_, {annotation, url}) => [\n execute({\n type: 'insert.span',\n text: url,\n annotations: [annotation],\n }),\n ],\n ],\n })\n\n const linkBehaviors = [pasteLinkOnSelection, pasteLinkAtCaret]\n\n return linkBehaviors\n}\n"],"names":["createCodeEditorBehaviors","config","defineBehavior","on","guard","snapshot","event","isMoveUpShortcut","isHotkey","moveBlockUpShortcut","originEvent","firstBlock","selectors","selectedBlocks","blocksAbove","node","_key","paths","map","block","path","actions","_","at","raise","type","isMoveDownShortcut","moveBlockDownShortcut","lastBlock","blocksBelow","length","reverse","emojiCharRegEx","incompleteEmojiRegEx","emojiRegEx","createEmojiPickerBehaviors","emojiPickerActor","createActor","createEmojiPickerMachine","start","subscribe","state","onMatchesChanged","matches","context","onSelectedIndexChanged","selectedIndex","text","test","emojis","focusBlock","emojiKeyword","match","undefined","matchEmojis","keyword","params","effect","send","forward","getSnapshot","emoji","parseMatch","textBefore","emojiStringLength","textBeforeLength","execute","anchor","offset","focus","action","isEnter","isTab","isArrowDown","isArrowUp","unit","slice","setup","types","events","assign","assertEvent","guards","no matches","createMachine","id","initial","states","target","always","exit","looksLikeUrl","url","URL","sensibleProtocols","includes","protocol","createLinkBehaviors","pasteLinkOnSelection","selectionCollapsed","dataTransfer","getData","annotation","linkAnnotation","schema","pasteLinkAtCaret","focusSpan","annotations"],"mappings":"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"}
1
+ {"version":3,"file":"index.js","sources":["../../src/behaviors/behavior.types.action.ts","../../src/behaviors/behavior.types.behavior.ts"],"sourcesContent":["import type {EditorSnapshot} from '../editor/editor-snapshot'\nimport type {OmitFromUnion, PickFromUnion} from '../type-utils'\nimport type {PortableTextSlateEditor} from '../types/editor'\nimport type {\n AbstractBehaviorEventType,\n CustomBehaviorEvent,\n NativeBehaviorEvent,\n SyntheticBehaviorEvent,\n} from './behavior.types.event'\n\n/**\n * @beta\n */\nexport type BehaviorAction =\n | {\n type: 'execute'\n event: SyntheticBehaviorEvent\n }\n | {\n type: 'forward'\n event: NativeBehaviorEvent | SyntheticBehaviorEvent | CustomBehaviorEvent\n }\n | {\n type: 'raise'\n event: SyntheticBehaviorEvent | CustomBehaviorEvent\n }\n | {\n type: 'effect'\n effect: () => void\n }\n\n/**\n * @beta\n */\nexport function execute(\n event: SyntheticBehaviorEvent,\n): PickFromUnion<BehaviorAction, 'type', 'execute'> {\n return {type: 'execute', event}\n}\n\n/**\n * @beta\n */\nexport function forward(\n event: NativeBehaviorEvent | SyntheticBehaviorEvent | CustomBehaviorEvent,\n): PickFromUnion<BehaviorAction, 'type', 'forward'> {\n return {type: 'forward', event}\n}\n\n/**\n * @beta\n */\nexport function raise(\n event: SyntheticBehaviorEvent | CustomBehaviorEvent,\n): PickFromUnion<BehaviorAction, 'type', 'raise'> {\n return {type: 'raise', event}\n}\n\n/**\n * @beta\n */\nexport function effect(\n effect: () => void,\n): PickFromUnion<BehaviorAction, 'type', 'effect'> {\n return {type: 'effect', effect}\n}\n\n/**\n * @beta\n */\nexport type BehaviorActionSet<TBehaviorEvent, TGuardResponse> = (\n payload: {\n snapshot: EditorSnapshot\n event: TBehaviorEvent\n },\n guardResponse: TGuardResponse,\n) => Array<BehaviorAction>\n\nexport type InternalBehaviorAction = (\n | OmitFromUnion<SyntheticBehaviorEvent, 'type', AbstractBehaviorEventType>\n | {type: 'effect'; effect: () => void}\n) & {\n editor: PortableTextSlateEditor\n}\n","import type {BehaviorActionSet} from './behavior.types.action'\nimport type {\n BehaviorEvent,\n BehaviorEventTypeNamespace,\n CustomBehaviorEvent,\n ResolveBehaviorEvent,\n} from './behavior.types.event'\nimport type {BehaviorGuard} from './behavior.types.guard'\n\n/**\n * @beta\n */\nexport type Behavior<\n TBehaviorEventType extends\n | '*'\n | `${BehaviorEventTypeNamespace}.*`\n | BehaviorEvent['type'] =\n | '*'\n | `${BehaviorEventTypeNamespace}.*`\n | BehaviorEvent['type'],\n TGuardResponse = true,\n TBehaviorEvent extends\n ResolveBehaviorEvent<TBehaviorEventType> = ResolveBehaviorEvent<TBehaviorEventType>,\n> = {\n /**\n * Editor Event that triggers this Behavior.\n */\n on: TBehaviorEventType\n /**\n * Predicate function that determines if the Behavior should be executed.\n * Returning a non-nullable value from the guard will pass the value to the\n * actions and execute them.\n */\n guard?: BehaviorGuard<TBehaviorEvent, TGuardResponse>\n /**\n * Array of Behavior Action sets.\n * Each set represents a step in the history stack.\n */\n actions: Array<BehaviorActionSet<TBehaviorEvent, TGuardResponse>>\n}\n\n/**\n * @beta\n *\n * @example\n *\n * ```tsx\n * const noLowerCaseA = defineBehavior({\n * on: 'insert.text',\n * guard: ({event, snapshot}) => event.text === 'a',\n * actions: [({event, snapshot}) => [{type: 'insert.text', text: 'A'}]],\n * })\n * ```\n *\n */\nexport function defineBehavior<\n TPayload extends Record<string, unknown>,\n TBehaviorEventType extends\n | '*'\n | `${BehaviorEventTypeNamespace}.*`\n | BehaviorEvent['type'] = CustomBehaviorEvent['type'],\n TGuardResponse = true,\n>(\n behavior: Behavior<\n TBehaviorEventType,\n TGuardResponse,\n ResolveBehaviorEvent<TBehaviorEventType, TPayload>\n >,\n): Behavior\nexport function defineBehavior<\n TPayload extends never = never,\n TBehaviorEventType extends\n | '*'\n | `${BehaviorEventTypeNamespace}.*`\n | BehaviorEvent['type'] = BehaviorEvent['type'],\n TGuardResponse = true,\n TBehaviorEvent extends ResolveBehaviorEvent<\n TBehaviorEventType,\n TPayload\n > = ResolveBehaviorEvent<TBehaviorEventType, TPayload>,\n>(\n behavior: Behavior<TBehaviorEventType, TGuardResponse, TBehaviorEvent>,\n): Behavior {\n return behavior as unknown as Behavior\n}\n"],"names":["execute","event","type","forward","raise","effect","defineBehavior","behavior"],"mappings":"AAkCO,SAASA,QACdC,OACkD;AAC3C,SAAA;AAAA,IAACC,MAAM;AAAA,IAAWD;AAAAA,EAAK;AAChC;AAKO,SAASE,QACdF,OACkD;AAC3C,SAAA;AAAA,IAACC,MAAM;AAAA,IAAWD;AAAAA,EAAK;AAChC;AAKO,SAASG,MACdH,OACgD;AACzC,SAAA;AAAA,IAACC,MAAM;AAAA,IAASD;AAAAA,EAAK;AAC9B;AAKO,SAASI,OACdA,SACiD;AAC1C,SAAA;AAAA,IAACH,MAAM;AAAA,IAAUG,QAAAA;AAAAA,EAAM;AAChC;ACIO,SAASC,eAYdC,UACU;AACHA,SAAAA;AACT;"}
package/lib/index.cjs CHANGED
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: !0 });
3
- var reactCompilerRuntime = require("react-compiler-runtime"), React = require("react"), useEffectEvent = require("use-effect-event"), editorProvider = require("./_chunks-cjs/editor-provider.cjs"), jsxRuntime = require("react/jsx-runtime"), react = require("@xstate/react"), noop = require("lodash/noop.js"), slate = require("slate"), slateReact = require("slate-react"), util_sliceBlocks = require("./_chunks-cjs/util.slice-blocks.cjs"), selector_isOverlappingSelection = require("./_chunks-cjs/selector.is-overlapping-selection.cjs"), selector_getFocusInlineObject = require("./_chunks-cjs/selector.get-focus-inline-object.cjs"), slateDom = require("slate-dom"), util_isSelectionCollapsed = require("./_chunks-cjs/util.is-selection-collapsed.cjs"), isEqual = require("lodash/isEqual.js"), util_getSelectionStartPoint = require("./_chunks-cjs/util.get-selection-start-point.cjs"), selector_isSelectingEntireBlocks = require("./_chunks-cjs/selector.is-selecting-entire-blocks.cjs"), behavior_core = require("./_chunks-cjs/behavior.core.cjs"), uniq = require("lodash/uniq.js"), xstate = require("xstate");
3
+ var reactCompilerRuntime = require("react-compiler-runtime"), React = require("react"), useEffectEvent = require("use-effect-event"), editorProvider = require("./_chunks-cjs/editor-provider.cjs"), jsxRuntime = require("react/jsx-runtime"), react = require("@xstate/react"), noop = require("lodash/noop.js"), slate = require("slate"), slateReact = require("slate-react"), util_sliceBlocks = require("./_chunks-cjs/util.slice-blocks.cjs"), selector_isSelectingEntireBlocks = require("./_chunks-cjs/selector.is-selecting-entire-blocks.cjs"), selector_getFocusInlineObject = require("./_chunks-cjs/selector.get-focus-inline-object.cjs"), slateDom = require("slate-dom"), util_isSelectionCollapsed = require("./_chunks-cjs/util.is-selection-collapsed.cjs"), isEqual = require("lodash/isEqual.js"), util_selectionPointToBlockOffset = require("./_chunks-cjs/util.selection-point-to-block-offset.cjs"), behaviors_index = require("./behaviors/index.cjs"), uniq = require("lodash/uniq.js"), xstate = require("xstate");
4
4
  function _interopDefaultCompat(e) {
5
5
  return e && typeof e == "object" && "default" in e ? e : { default: e };
6
6
  }
@@ -42,17 +42,17 @@ function getDragSelection({
42
42
  }
43
43
  }))
44
44
  return dragSelection;
45
- const draggingCollapsedSelection = selector_isOverlappingSelection.isSelectionCollapsed({
45
+ const draggingCollapsedSelection = selector_isSelectingEntireBlocks.isSelectionCollapsed({
46
46
  context: {
47
47
  ...snapshot.context,
48
48
  selection: eventSelection
49
49
  }
50
- }), draggedTextBlock = selector_isOverlappingSelection.getFocusTextBlock({
50
+ }), draggedTextBlock = selector_isSelectingEntireBlocks.getFocusTextBlock({
51
51
  context: {
52
52
  ...snapshot.context,
53
53
  selection: eventSelection
54
54
  }
55
- }), draggedSpan = selector_isOverlappingSelection.getFocusSpan({
55
+ }), draggedSpan = selector_isSelectingEntireBlocks.getFocusSpan({
56
56
  context: {
57
57
  ...snapshot.context,
58
58
  selection: eventSelection
@@ -68,9 +68,9 @@ function getDragSelection({
68
68
  block: draggedTextBlock
69
69
  })
70
70
  });
71
- const selectedBlocks = selector_isOverlappingSelection.getSelectedBlocks(snapshot);
72
- if (snapshot.context.selection && selector_isOverlappingSelection.isSelectionExpanded(snapshot) && selectedBlocks.length > 1) {
73
- const selectionStartBlock = selector_isOverlappingSelection.getSelectionStartBlock(snapshot), selectionEndBlock = selector_isOverlappingSelection.getSelectionEndBlock(snapshot);
71
+ const selectedBlocks = selector_isSelectingEntireBlocks.getSelectedBlocks(snapshot);
72
+ if (snapshot.context.selection && selector_isSelectingEntireBlocks.isSelectionExpanded(snapshot) && selectedBlocks.length > 1) {
73
+ const selectionStartBlock = selector_isSelectingEntireBlocks.getSelectionStartBlock(snapshot), selectionEndBlock = selector_isSelectingEntireBlocks.getSelectionEndBlock(snapshot);
74
74
  if (!selectionStartBlock || !selectionEndBlock)
75
75
  return dragSelection;
76
76
  const selectionStartPoint = util_sliceBlocks.getBlockStartPoint({
@@ -80,7 +80,7 @@ function getDragSelection({
80
80
  context: snapshot.context,
81
81
  block: selectionEndBlock
82
82
  });
83
- selector_isOverlappingSelection.isOverlappingSelection(eventSelection)({
83
+ selector_isSelectingEntireBlocks.isOverlappingSelection(eventSelection)({
84
84
  ...snapshot,
85
85
  context: {
86
86
  ...snapshot.context,
@@ -388,13 +388,13 @@ const EMPTY_ANNOTATIONS = [], inlineBlockStyle = {
388
388
  }) => {
389
389
  const editorActor = React.useContext(editorProvider.EditorActorContext), slateEditor = slateReact.useSlateStatic(), selected = slateReact.useSelected(), blockRef = React.useRef(null), inlineBlockObjectRef = React.useRef(null), focused = selected && slateEditor.selection && slate.Range.isCollapsed(slateEditor.selection) || !1, [dragPositionBlock, setDragPositionBlock] = React.useState();
390
390
  React.useEffect(() => {
391
- const behavior = behavior_core.defineBehavior({
391
+ const behavior = behaviors_index.defineBehavior({
392
392
  on: "drag.dragover",
393
393
  guard: ({
394
394
  snapshot,
395
395
  event
396
396
  }) => {
397
- const dropFocusBlock = selector_isOverlappingSelection.getFocusBlock({
397
+ const dropFocusBlock = selector_isSelectingEntireBlocks.getFocusBlock({
398
398
  context: {
399
399
  ...snapshot.context,
400
400
  selection: event.position.selection
@@ -403,7 +403,7 @@ const EMPTY_ANNOTATIONS = [], inlineBlockStyle = {
403
403
  if (!dropFocusBlock || dropFocusBlock.node._key !== element._key)
404
404
  return !1;
405
405
  const dragOrigin = snapshot.beta.internalDrag?.origin;
406
- return !dragOrigin || selector_isOverlappingSelection.getSelectedBlocks({
406
+ return !dragOrigin || selector_isSelectingEntireBlocks.getSelectedBlocks({
407
407
  context: {
408
408
  ...snapshot.context,
409
409
  selection: dragOrigin.selection
@@ -434,7 +434,7 @@ const EMPTY_ANNOTATIONS = [], inlineBlockStyle = {
434
434
  });
435
435
  };
436
436
  }, [editorActor, element._key]), React.useEffect(() => {
437
- const behavior_0 = behavior_core.defineBehavior({
437
+ const behavior_0 = behaviors_index.defineBehavior({
438
438
  on: "drag.*",
439
439
  guard: ({
440
440
  event: event_1
@@ -446,7 +446,7 @@ const EMPTY_ANNOTATIONS = [], inlineBlockStyle = {
446
446
  effect: () => {
447
447
  setDragPositionBlock(void 0);
448
448
  }
449
- }, behavior_core.forward(event_2)]]
449
+ }, behaviors_index.forward(event_2)]]
450
450
  });
451
451
  return editorActor.send({
452
452
  type: "add behavior",
@@ -718,7 +718,7 @@ function createWithHotkeys(editorActor, portableTextEditor, hotkeysFromOptions)
718
718
  for (const hotkey in activeHotkeys[cat]) {
719
719
  if (reservedHotkeys.includes(hotkey))
720
720
  throw new Error(`The hotkey ${hotkey} is reserved!`);
721
- if (behavior_core.isHotkey(hotkey, event.nativeEvent)) {
721
+ if (editorProvider.isHotkey(hotkey, event.nativeEvent)) {
722
722
  event.preventDefault();
723
723
  const possibleMark = activeHotkeys[cat];
724
724
  if (possibleMark) {
@@ -738,7 +738,7 @@ function createWithHotkeys(editorActor, portableTextEditor, hotkeysFromOptions)
738
738
  for (const hotkey in activeHotkeys[cat]) {
739
739
  if (reservedHotkeys.includes(hotkey))
740
740
  throw new Error(`The hotkey ${hotkey} is reserved!`);
741
- if (behavior_core.isHotkey(hotkey, event.nativeEvent)) {
741
+ if (editorProvider.isHotkey(hotkey, event.nativeEvent)) {
742
742
  const possibleCommand = activeHotkeys[cat];
743
743
  if (possibleCommand) {
744
744
  const command = possibleCommand[hotkey];
@@ -1455,8 +1455,8 @@ const debug = editorProvider.debugWithName("component:Editable"), PLACEHOLDER_ST
1455
1455
  behaviorEvent: {
1456
1456
  type: "select",
1457
1457
  at: util_isSelectionCollapsed.isSelectionCollapsed(dragSelection) ? dragSelection : {
1458
- anchor: util_getSelectionStartPoint.getSelectionEndPoint(dragSelection),
1459
- focus: util_getSelectionStartPoint.getSelectionEndPoint(dragSelection),
1458
+ anchor: util_selectionPointToBlockOffset.getSelectionEndPoint(dragSelection),
1459
+ focus: util_selectionPointToBlockOffset.getSelectionEndPoint(dragSelection),
1460
1460
  backward: !1
1461
1461
  }
1462
1462
  },