@portabletext/editor 1.45.4 → 1.47.0

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 (46) hide show
  1. package/lib/_chunks-cjs/behavior.core.cjs +20 -0
  2. package/lib/_chunks-cjs/behavior.core.cjs.map +1 -1
  3. package/lib/_chunks-cjs/behavior.markdown.cjs +25 -25
  4. package/lib/_chunks-cjs/behavior.markdown.cjs.map +1 -1
  5. package/lib/_chunks-cjs/editor-provider.cjs +69 -4
  6. package/lib/_chunks-cjs/editor-provider.cjs.map +1 -1
  7. package/lib/_chunks-es/behavior.core.js +20 -0
  8. package/lib/_chunks-es/behavior.core.js.map +1 -1
  9. package/lib/_chunks-es/behavior.markdown.js +26 -26
  10. package/lib/_chunks-es/behavior.markdown.js.map +1 -1
  11. package/lib/_chunks-es/editor-provider.js +69 -4
  12. package/lib/_chunks-es/editor-provider.js.map +1 -1
  13. package/lib/_chunks-es/selector.is-selecting-entire-blocks.js +1 -1
  14. package/lib/behaviors/index.cjs +37 -53
  15. package/lib/behaviors/index.cjs.map +1 -1
  16. package/lib/behaviors/index.d.cts +546 -1
  17. package/lib/behaviors/index.d.ts +546 -1
  18. package/lib/behaviors/index.js +38 -54
  19. package/lib/behaviors/index.js.map +1 -1
  20. package/lib/index.d.cts +17 -1
  21. package/lib/index.d.ts +17 -1
  22. package/lib/plugins/index.cjs +23 -29
  23. package/lib/plugins/index.cjs.map +1 -1
  24. package/lib/plugins/index.d.cts +17 -1
  25. package/lib/plugins/index.d.ts +17 -1
  26. package/lib/plugins/index.js +24 -30
  27. package/lib/plugins/index.js.map +1 -1
  28. package/lib/selectors/index.d.cts +17 -1
  29. package/lib/selectors/index.d.ts +17 -1
  30. package/lib/utils/index.d.cts +17 -1
  31. package/lib/utils/index.d.ts +17 -1
  32. package/package.json +3 -3
  33. package/src/behavior-actions/behavior.action.move.backward.ts +12 -0
  34. package/src/behavior-actions/behavior.action.move.forward.ts +11 -0
  35. package/src/behavior-actions/behavior.actions.ts +18 -0
  36. package/src/behaviors/behavior.decorator-pair.ts +16 -19
  37. package/src/behaviors/behavior.emoji-picker.ts +26 -45
  38. package/src/behaviors/behavior.links.ts +5 -4
  39. package/src/behaviors/behavior.markdown.ts +37 -34
  40. package/src/behaviors/behavior.perform-event.ts +53 -2
  41. package/src/behaviors/behavior.types.action.ts +38 -7
  42. package/src/behaviors/behavior.types.event.ts +10 -0
  43. package/src/behaviors/index.ts +3 -0
  44. package/src/editor/editor-machine.ts +2 -2
  45. package/src/plugins/plugin.decorator-shortcut.ts +6 -8
  46. package/src/plugins/plugin.one-line.tsx +4 -4
@@ -1,4 +1,4 @@
1
- import { defineBehavior, raise, isHotkey } from "../_chunks-es/behavior.core.js";
1
+ import { defineBehavior, raise, isHotkey, execute, effect, noop } from "../_chunks-es/behavior.core.js";
2
2
  import { coreBehaviors } from "../_chunks-es/behavior.core.js";
3
3
  import { getFirstBlock, getSelectedBlocks, getLastBlock, getFocusTextBlock, isSelectionCollapsed, getFocusSpan } from "../_chunks-es/selector.is-overlapping-selection.js";
4
4
  import { createActor, setup, assign, assertEvent } from "xstate";
@@ -101,17 +101,14 @@ function createEmojiPickerBehaviors(config) {
101
101
  textBeforeLength: textBefore.length + 1
102
102
  } : !1;
103
103
  },
104
- actions: [() => [{
104
+ actions: [() => [execute({
105
105
  type: "insert.text",
106
106
  text: ":"
107
- }], (_, params) => [{
108
- type: "effect",
109
- effect: () => {
110
- emojiPickerActor.send({
111
- type: "select"
112
- });
113
- }
114
- }, raise({
107
+ })], (_, params) => [effect(() => {
108
+ emojiPickerActor.send({
109
+ type: "select"
110
+ });
111
+ }), execute({
115
112
  type: "delete.text",
116
113
  at: {
117
114
  anchor: {
@@ -123,10 +120,10 @@ function createEmojiPickerBehaviors(config) {
123
120
  offset: params.textBeforeLength
124
121
  }
125
122
  }
126
- }), {
123
+ }), execute({
127
124
  type: "insert.text",
128
125
  text: params.emoji
129
- }]]
126
+ })]]
130
127
  }), defineBehavior({
131
128
  on: "keyboard.keydown",
132
129
  guard: ({
@@ -166,14 +163,11 @@ function createEmojiPickerBehaviors(config) {
166
163
  action: "navigate up"
167
164
  } : !1;
168
165
  },
169
- actions: [(_, params) => params.action === "select" ? [{
170
- type: "effect",
171
- effect: () => {
172
- emojiPickerActor.send({
173
- type: "select"
174
- });
175
- }
176
- }, raise({
166
+ actions: [(_, params) => params.action === "select" ? [effect(() => {
167
+ emojiPickerActor.send({
168
+ type: "select"
169
+ });
170
+ }), execute({
177
171
  type: "delete.text",
178
172
  at: {
179
173
  anchor: {
@@ -185,45 +179,32 @@ function createEmojiPickerBehaviors(config) {
185
179
  offset: params.textBeforeLength
186
180
  }
187
181
  }
188
- }), {
182
+ }), execute({
189
183
  type: "insert.text",
190
184
  text: params.emoji
191
- }] : params.action === "navigate up" ? [
185
+ })] : params.action === "navigate up" ? [
192
186
  // If we are navigating then we want to hijack the key event and
193
187
  // turn it into a noop.
194
- {
195
- type: "noop"
196
- },
197
- {
198
- type: "effect",
199
- effect: () => {
200
- emojiPickerActor.send({
201
- type: "navigate up"
202
- });
203
- }
204
- }
188
+ noop(),
189
+ effect(() => {
190
+ emojiPickerActor.send({
191
+ type: "navigate up"
192
+ });
193
+ })
205
194
  ] : params.action === "navigate down" ? [
206
195
  // If we are navigating then we want to hijack the key event and
207
196
  // turn it into a noop.
208
- {
209
- type: "noop"
210
- },
211
- {
212
- type: "effect",
213
- effect: () => {
214
- emojiPickerActor.send({
215
- type: "navigate down"
216
- });
217
- }
218
- }
219
- ] : [{
220
- type: "effect",
221
- effect: () => {
197
+ noop(),
198
+ effect(() => {
222
199
  emojiPickerActor.send({
223
- type: "reset"
200
+ type: "navigate down"
224
201
  });
225
- }
226
- }]]
202
+ })
203
+ ] : [effect(() => {
204
+ emojiPickerActor.send({
205
+ type: "reset"
206
+ });
207
+ })]]
227
208
  }), defineBehavior({
228
209
  on: "delete.backward",
229
210
  guard: ({
@@ -360,10 +341,10 @@ function createLinkBehaviors(config) {
360
341
  },
361
342
  actions: [(_, {
362
343
  annotation
363
- }) => [{
344
+ }) => [execute({
364
345
  type: "annotation.add",
365
346
  annotation
366
- }]]
347
+ })]]
367
348
  }), pasteLinkAtCaret = defineBehavior({
368
349
  on: "clipboard.paste",
369
350
  guard: ({
@@ -386,11 +367,11 @@ function createLinkBehaviors(config) {
386
367
  actions: [(_, {
387
368
  annotation,
388
369
  url
389
- }) => [{
370
+ }) => [execute({
390
371
  type: "insert.span",
391
372
  text: url,
392
373
  annotations: [annotation]
393
- }]]
374
+ })]]
394
375
  });
395
376
  return [pasteLinkOnSelection, pasteLinkAtCaret];
396
377
  }
@@ -401,6 +382,9 @@ export {
401
382
  createLinkBehaviors,
402
383
  createMarkdownBehaviors,
403
384
  defineBehavior,
385
+ effect,
386
+ execute,
387
+ noop,
404
388
  raise
405
389
  };
406
390
  //# sourceMappingURL=index.js.map
@@ -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 {raise} 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 (_, params) => [\n {\n type: 'effect',\n effect: () => {\n emojiPickerActor.send({\n type: 'emojis found',\n matches: params.emojis,\n })\n },\n },\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 {\n type: 'insert.text',\n text: ':',\n },\n ],\n (_, params) => [\n {\n type: 'effect',\n effect: () => {\n emojiPickerActor.send({type: 'select'})\n },\n },\n raise({\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 {\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 {\n type: 'effect',\n effect: () => {\n emojiPickerActor.send({type: 'select'})\n },\n },\n raise({\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 {\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 and\n // turn it into a noop.\n {\n type: 'noop',\n },\n {\n type: 'effect',\n effect: () => {\n emojiPickerActor.send({type: 'navigate up'})\n },\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 and\n // turn it into a noop.\n {\n type: 'noop',\n },\n {\n type: 'effect',\n effect: () => {\n emojiPickerActor.send({type: 'navigate down'})\n },\n },\n ]\n }\n\n return [\n {\n type: 'effect',\n effect: () => {\n emojiPickerActor.send({type: 'reset'})\n },\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 (_, params) => [\n {\n type: 'effect',\n effect: () => {\n emojiPickerActor.send({\n type: 'emojis found',\n matches: params.emojis,\n })\n },\n },\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/define-schema'\nimport {looksLikeUrl} from '../internal-utils/looks-like-url'\nimport * as selectors from '../selectors'\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 {\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 {\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","getSnapshot","emoji","parseMatch","textBefore","emojiStringLength","textBeforeLength","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.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, noop} 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 (_, params) => [\n {\n type: 'effect',\n effect: () => {\n emojiPickerActor.send({\n type: 'emojis found',\n matches: params.emojis,\n })\n },\n },\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 and\n // turn it into a noop.\n noop(),\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 and\n // turn it into a noop.\n noop(),\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 (_, params) => [\n {\n type: 'effect',\n effect: () => {\n emojiPickerActor.send({\n type: 'emojis found',\n matches: params.emojis,\n })\n },\n },\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/define-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","getSnapshot","emoji","parseMatch","textBefore","emojiStringLength","textBeforeLength","execute","anchor","offset","focus","action","isEnter","isTab","isArrowDown","isArrowUp","noop","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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"}
package/lib/index.d.cts CHANGED
@@ -301,7 +301,13 @@ declare type Behavior<
301
301
  * @beta
302
302
  */
303
303
  declare type BehaviorAction =
304
- | SyntheticBehaviorEvent
304
+ | {
305
+ type: 'execute'
306
+ event:
307
+ | AbstractBehaviorEvent
308
+ | SyntheticBehaviorEvent
309
+ | CustomBehaviorEvent
310
+ }
305
311
  | {
306
312
  type: 'raise'
307
313
  event:
@@ -6267,11 +6273,19 @@ declare type SyntheticBehaviorEvent =
6267
6273
  type: StrictExtract<SyntheticBehaviorEventType, 'insert.text'>
6268
6274
  text: string
6269
6275
  }
6276
+ | {
6277
+ type: StrictExtract<SyntheticBehaviorEventType, 'move.backward'>
6278
+ distance: number
6279
+ }
6270
6280
  | {
6271
6281
  type: StrictExtract<SyntheticBehaviorEventType, 'move.block'>
6272
6282
  at: [KeyedSegment]
6273
6283
  to: [KeyedSegment]
6274
6284
  }
6285
+ | {
6286
+ type: StrictExtract<SyntheticBehaviorEventType, 'move.forward'>
6287
+ distance: number
6288
+ }
6275
6289
  | {
6276
6290
  type: StrictExtract<SyntheticBehaviorEventType, 'select'>
6277
6291
  at: EditorSelection
@@ -6308,7 +6322,9 @@ declare const syntheticBehaviorEventTypes: readonly [
6308
6322
  'insert.block',
6309
6323
  'insert.span',
6310
6324
  'insert.text',
6325
+ 'move.backward',
6311
6326
  'move.block',
6327
+ 'move.forward',
6312
6328
  'select',
6313
6329
  'split.block',
6314
6330
  ]
package/lib/index.d.ts CHANGED
@@ -301,7 +301,13 @@ declare type Behavior<
301
301
  * @beta
302
302
  */
303
303
  declare type BehaviorAction =
304
- | SyntheticBehaviorEvent
304
+ | {
305
+ type: 'execute'
306
+ event:
307
+ | AbstractBehaviorEvent
308
+ | SyntheticBehaviorEvent
309
+ | CustomBehaviorEvent
310
+ }
305
311
  | {
306
312
  type: 'raise'
307
313
  event:
@@ -6267,11 +6273,19 @@ declare type SyntheticBehaviorEvent =
6267
6273
  type: StrictExtract<SyntheticBehaviorEventType, 'insert.text'>
6268
6274
  text: string
6269
6275
  }
6276
+ | {
6277
+ type: StrictExtract<SyntheticBehaviorEventType, 'move.backward'>
6278
+ distance: number
6279
+ }
6270
6280
  | {
6271
6281
  type: StrictExtract<SyntheticBehaviorEventType, 'move.block'>
6272
6282
  at: [KeyedSegment]
6273
6283
  to: [KeyedSegment]
6274
6284
  }
6285
+ | {
6286
+ type: StrictExtract<SyntheticBehaviorEventType, 'move.forward'>
6287
+ distance: number
6288
+ }
6275
6289
  | {
6276
6290
  type: StrictExtract<SyntheticBehaviorEventType, 'select'>
6277
6291
  at: EditorSelection
@@ -6308,7 +6322,9 @@ declare const syntheticBehaviorEventTypes: readonly [
6308
6322
  'insert.block',
6309
6323
  'insert.span',
6310
6324
  'insert.text',
6325
+ 'move.backward',
6311
6326
  'move.block',
6327
+ 'move.forward',
6312
6328
  'select',
6313
6329
  'split.block',
6314
6330
  ]
@@ -120,45 +120,42 @@ function createDecoratorPairBehavior(config) {
120
120
  // Insert the text as usual in its own undo step
121
121
  ({
122
122
  event
123
- }) => [event],
123
+ }) => [behavior_core.execute(event)],
124
124
  (_, {
125
125
  prefixOffsets,
126
126
  suffixOffsets,
127
127
  decorator
128
128
  }) => [
129
129
  // Decorate the text between the prefix and suffix
130
- {
130
+ behavior_core.execute({
131
131
  type: "decorator.add",
132
132
  decorator,
133
133
  at: {
134
134
  anchor: prefixOffsets.focus,
135
135
  focus: suffixOffsets.anchor
136
136
  }
137
- },
137
+ }),
138
138
  // Delete the suffix
139
- behavior_core.raise({
139
+ behavior_core.execute({
140
140
  type: "delete.text",
141
141
  at: suffixOffsets
142
142
  }),
143
143
  // Delete the prefix
144
- behavior_core.raise({
144
+ behavior_core.execute({
145
145
  type: "delete.text",
146
146
  at: prefixOffsets
147
147
  }),
148
148
  // Toggle the decorator off so the next inserted text isn't emphasized
149
- {
149
+ behavior_core.execute({
150
150
  type: "decorator.remove",
151
151
  decorator
152
- },
153
- {
154
- type: "effect",
155
- effect: () => {
156
- config.onDecorate({
157
- ...suffixOffsets.anchor,
158
- offset: suffixOffsets.anchor.offset - (prefixOffsets.focus.offset - prefixOffsets.anchor.offset)
159
- });
160
- }
161
- }
152
+ }),
153
+ behavior_core.effect(() => {
154
+ config.onDecorate({
155
+ ...suffixOffsets.anchor,
156
+ offset: suffixOffsets.anchor.offset - (prefixOffsets.focus.offset - prefixOffsets.anchor.offset)
157
+ });
158
+ })
162
159
  ]
163
160
  ]
164
161
  });
@@ -236,16 +233,13 @@ const emphasisListener = ({
236
233
  }) => input.editor.registerBehavior({
237
234
  behavior: behavior_core.defineBehavior({
238
235
  on: "delete.backward",
239
- actions: [() => [{
236
+ actions: [() => [behavior_core.execute({
240
237
  type: "history.undo"
241
- }, {
242
- type: "effect",
243
- effect: () => {
244
- sendBack({
245
- type: "delete.backward"
246
- });
247
- }
248
- }]]
238
+ }), behavior_core.effect(() => {
239
+ sendBack({
240
+ type: "delete.backward"
241
+ });
242
+ })]]
249
243
  })
250
244
  }), decoratorPairMachine = xstate.setup({
251
245
  types: {
@@ -411,10 +405,10 @@ const oneLineBehaviors = [
411
405
  } : !1,
412
406
  actions: [(_, {
413
407
  selection
414
- }) => [{
408
+ }) => [behavior_core.execute({
415
409
  type: "delete",
416
410
  at: selection
417
- }]]
411
+ })]]
418
412
  }),
419
413
  /**
420
414
  * All other cases of `insert.break` should be aborted.
@@ -458,12 +452,12 @@ const oneLineBehaviors = [
458
452
  }) => !(!selector_isOverlappingSelection.getFocusTextBlock(snapshot) || !util_mergeTextBlocks.isTextBlock(snapshot.context, event.block)),
459
453
  actions: [({
460
454
  event
461
- }) => [{
455
+ }) => [behavior_core.execute({
462
456
  type: "insert.block",
463
457
  block: event.block,
464
458
  placement: "auto",
465
459
  select: "end"
466
- }]]
460
+ })]]
467
461
  }),
468
462
  /**
469
463
  * Fallback Behavior to avoid `insert.block` in case the Behaviors above all