@portabletext/editor
Version:
Portable Text Editor made in React
837 lines (836 loc) • 27.1 kB
JavaScript
import { c } from "react-compiler-runtime";
import React, { useEffect } from "react";
import { useEditor } from "../_chunks-es/use-editor.js";
import { useActorRef } from "@xstate/react";
import isEqual from "lodash/isEqual.js";
import { setup, fromCallback, assign } from "xstate";
import { spanSelectionPointToBlockOffset, getTextBlockText, isTextBlock } from "../_chunks-es/selection-point.js";
import { blockOffsetsToSelection, childSelectionPointToBlockOffset } from "../_chunks-es/util.child-selection-point-to-block-offset.js";
import { getFocusTextBlock, getSelectionStartPoint, getPreviousInlineObject, isSelectionCollapsed, getFocusSpan, getFocusBlock, isSelectionExpanded } from "../_chunks-es/selector.is-selection-expanded.js";
import { getBlockTextBefore } from "../_chunks-es/selector.get-text-before.js";
import { defineBehavior, execute, effect, forward, raise } from "../behaviors/index.js";
import { useEffectEvent } from "use-effect-event";
import { jsxs, Fragment, jsx } from "react/jsx-runtime";
import { isTextBlock as isTextBlock$1, mergeTextBlocks } from "../_chunks-es/util.merge-text-blocks.js";
function BehaviorPlugin(props) {
const $ = c(4), editor = useEditor();
let t0, t1;
return $[0] !== editor || $[1] !== props.behaviors ? (t0 = () => {
const unregisterBehaviors = props.behaviors.map((behavior) => editor.registerBehavior({
behavior
}));
return () => {
unregisterBehaviors.forEach(_temp);
};
}, t1 = [editor, props.behaviors], $[0] = editor, $[1] = props.behaviors, $[2] = t0, $[3] = t1) : (t0 = $[2], t1 = $[3]), useEffect(t0, t1), null;
}
function _temp(unregister) {
return unregister();
}
function createPairRegex(char, amount) {
const prePrefix = `(?<!\\${char})`, prefix = `\\${char}`.repeat(Math.max(amount, 1)), postPrefix = "(?!\\s)", content = `([^${char}\\n]+?)`, preSuffix = "(?<!\\s)", suffix = `\\${char}`.repeat(Math.max(amount, 1)), postSuffix = `(?!\\${char})`;
return `${prePrefix}${prefix}${postPrefix}${content}${preSuffix}${suffix}${postSuffix}`;
}
function createDecoratorPairBehavior(config) {
config.pair.amount < 1 && console.warn("The amount of characters in the pair should be greater than 0");
const pairRegex = createPairRegex(config.pair.char, config.pair.amount), regEx = new RegExp(`(${pairRegex})$`);
return defineBehavior({
on: "insert.text",
guard: ({
snapshot,
event
}) => {
if (config.pair.amount < 1)
return !1;
const decorator = config.decorator({
schema: snapshot.context.schema
});
if (decorator === void 0)
return !1;
const focusTextBlock = getFocusTextBlock(snapshot), selectionStartPoint = getSelectionStartPoint(snapshot), selectionStartOffset = selectionStartPoint ? spanSelectionPointToBlockOffset({
context: {
schema: snapshot.context.schema,
value: snapshot.context.value
},
selectionPoint: selectionStartPoint
}) : void 0;
if (!focusTextBlock || !selectionStartOffset)
return !1;
const newText = `${getBlockTextBefore(snapshot)}${event.text}`, textToDecorate = newText.match(regEx)?.at(0);
if (textToDecorate === void 0)
return !1;
const prefixOffsets = {
anchor: {
path: focusTextBlock.path,
// Example: "foo **bar**".length - "**bar**".length = 4
offset: newText.length - textToDecorate.length
},
focus: {
path: focusTextBlock.path,
// Example: "foo **bar**".length - "**bar**".length + "*".length * 2 = 6
offset: newText.length - textToDecorate.length + config.pair.char.length * config.pair.amount
}
}, suffixOffsets = {
anchor: {
path: focusTextBlock.path,
// Example: "foo **bar*|" (10) + "*".length - 2 = 9
offset: selectionStartOffset.offset + event.text.length - config.pair.char.length * config.pair.amount
},
focus: {
path: focusTextBlock.path,
// Example: "foo **bar*|" (10) + "*".length = 11
offset: selectionStartOffset.offset + event.text.length
}
};
if (prefixOffsets.focus.offset - prefixOffsets.anchor.offset > 1) {
const prefixSelection = blockOffsetsToSelection({
context: snapshot.context,
offsets: prefixOffsets
}), inlineObjectBeforePrefixFocus = getPreviousInlineObject({
context: {
...snapshot.context,
selection: prefixSelection ? {
anchor: prefixSelection.focus,
focus: prefixSelection.focus
} : null
}
}), inlineObjectBeforePrefixFocusOffset = inlineObjectBeforePrefixFocus ? childSelectionPointToBlockOffset({
context: {
schema: snapshot.context.schema,
value: snapshot.context.value
},
selectionPoint: {
path: inlineObjectBeforePrefixFocus.path,
offset: 0
}
}) : void 0;
if (inlineObjectBeforePrefixFocusOffset && inlineObjectBeforePrefixFocusOffset.offset > prefixOffsets.anchor.offset && inlineObjectBeforePrefixFocusOffset.offset < prefixOffsets.focus.offset)
return !1;
}
if (suffixOffsets.focus.offset - suffixOffsets.anchor.offset > 1) {
const previousInlineObject = getPreviousInlineObject(snapshot), previousInlineObjectOffset = previousInlineObject ? childSelectionPointToBlockOffset({
context: {
schema: snapshot.context.schema,
value: snapshot.context.value
},
selectionPoint: {
path: previousInlineObject.path,
offset: 0
}
}) : void 0;
if (previousInlineObjectOffset && previousInlineObjectOffset.offset > suffixOffsets.anchor.offset && previousInlineObjectOffset.offset < suffixOffsets.focus.offset)
return !1;
}
return {
prefixOffsets,
suffixOffsets,
decorator
};
},
actions: [
// Insert the text as usual in its own undo step
({
event
}) => [execute(event)],
(_, {
prefixOffsets,
suffixOffsets,
decorator
}) => [
// Decorate the text between the prefix and suffix
execute({
type: "decorator.add",
decorator,
at: {
anchor: prefixOffsets.focus,
focus: suffixOffsets.anchor
}
}),
// Delete the suffix
execute({
type: "delete.text",
at: suffixOffsets
}),
// Delete the prefix
execute({
type: "delete.text",
at: prefixOffsets
}),
// Toggle the decorator off so the next inserted text isn't emphasized
execute({
type: "decorator.remove",
decorator
}),
effect(() => {
config.onDecorate({
...suffixOffsets.anchor,
offset: suffixOffsets.anchor.offset - (prefixOffsets.focus.offset - prefixOffsets.anchor.offset)
});
})
]
]
});
}
function DecoratorShortcutPlugin(config) {
const $ = c(4), editor = useEditor();
let t0;
return $[0] !== config.decorator || $[1] !== config.pair || $[2] !== editor ? (t0 = {
input: {
editor,
decorator: config.decorator,
pair: config.pair
}
}, $[0] = config.decorator, $[1] = config.pair, $[2] = editor, $[3] = t0) : t0 = $[3], useActorRef(decoratorPairMachine, t0), null;
}
const emphasisListener = ({
sendBack,
input
}) => input.editor.registerBehavior({
behavior: createDecoratorPairBehavior({
decorator: input.decorator,
pair: input.pair,
onDecorate: (offset) => {
sendBack({
type: "emphasis.add",
blockOffset: offset
});
}
})
}), selectionListenerCallback = ({
sendBack,
input
}) => input.editor.registerBehavior({
behavior: defineBehavior({
on: "select",
guard: ({
snapshot,
event
}) => {
if (!event.at)
return {
blockOffsets: void 0
};
const anchor = spanSelectionPointToBlockOffset({
context: snapshot.context,
selectionPoint: event.at.anchor
}), focus = spanSelectionPointToBlockOffset({
context: snapshot.context,
selectionPoint: event.at.focus
});
return !anchor || !focus ? {
blockOffsets: void 0
} : {
blockOffsets: {
anchor,
focus
}
};
},
actions: [({
event
}, {
blockOffsets
}) => [{
type: "effect",
effect: () => {
sendBack({
type: "selection",
blockOffsets
});
}
}, forward(event)]]
})
}), deleteBackwardListenerCallback = ({
sendBack,
input
}) => input.editor.registerBehavior({
behavior: defineBehavior({
on: "delete.backward",
actions: [() => [execute({
type: "history.undo"
}), effect(() => {
sendBack({
type: "delete.backward"
});
})]]
})
}), decoratorPairMachine = setup({
types: {
context: {},
input: {},
events: {}
},
actors: {
"emphasis listener": fromCallback(emphasisListener),
"delete.backward listener": fromCallback(deleteBackwardListenerCallback),
"selection listener": fromCallback(selectionListenerCallback)
}
}).createMachine({
id: "decorator pair",
context: ({
input
}) => ({
decorator: input.decorator,
editor: input.editor,
pair: input.pair
}),
initial: "idle",
states: {
idle: {
invoke: [{
src: "emphasis listener",
input: ({
context
}) => ({
decorator: context.decorator,
editor: context.editor,
pair: context.pair
})
}],
on: {
"emphasis.add": {
target: "emphasis added",
actions: assign({
offsetAfterEmphasis: ({
event
}) => event.blockOffset
})
}
}
},
"emphasis added": {
exit: [assign({
offsetAfterEmphasis: void 0
})],
invoke: [{
src: "selection listener",
input: ({
context
}) => ({
editor: context.editor
})
}, {
src: "delete.backward listener",
input: ({
context
}) => ({
editor: context.editor
})
}],
on: {
selection: {
target: "idle",
guard: ({
context,
event
}) => !isEqual({
anchor: context.offsetAfterEmphasis,
focus: context.offsetAfterEmphasis
}, event.blockOffsets)
},
"delete.backward": {
target: "idle"
}
}
}
}
}), EditorRefPlugin = React.forwardRef((_, ref) => {
const $ = c(2), editor = useEditor(), portableTextEditorRef = React.useRef(editor);
let t0, t1;
return $[0] === Symbol.for("react.memo_cache_sentinel") ? (t0 = () => portableTextEditorRef.current, t1 = [], $[0] = t0, $[1] = t1) : (t0 = $[0], t1 = $[1]), React.useImperativeHandle(ref, t0, t1), null;
});
EditorRefPlugin.displayName = "EditorRefPlugin";
function EventListenerPlugin(props) {
const $ = c(5), editor = useEditor(), on = useEffectEvent(props.on);
let t0;
$[0] !== editor || $[1] !== on ? (t0 = () => {
const subscription = editor.on("*", on);
return () => {
subscription.unsubscribe();
};
}, $[0] = editor, $[1] = on, $[2] = t0) : t0 = $[2];
let t1;
return $[3] !== editor ? (t1 = [editor], $[3] = editor, $[4] = t1) : t1 = $[4], useEffect(t0, t1), null;
}
function createMarkdownBehaviors(config) {
const automaticBlockquoteOnSpace = defineBehavior({
on: "insert.text",
guard: ({
snapshot,
event
}) => {
if (event.text !== " ")
return !1;
const selectionCollapsed = isSelectionCollapsed(snapshot), focusTextBlock = getFocusTextBlock(snapshot), focusSpan = getFocusSpan(snapshot);
if (!selectionCollapsed || !focusTextBlock || !focusSpan)
return !1;
const previousInlineObject = getPreviousInlineObject(snapshot), blockOffset = spanSelectionPointToBlockOffset({
context: snapshot.context,
selectionPoint: {
path: [{
_key: focusTextBlock.node._key
}, "children", {
_key: focusSpan.node._key
}],
offset: snapshot.context.selection?.focus.offset ?? 0
}
});
if (previousInlineObject || !blockOffset)
return !1;
const blockText = getTextBlockText(focusTextBlock.node), caretAtTheEndOfQuote = blockOffset.offset === 1, looksLikeMarkdownQuote = /^>/.test(blockText), blockquoteStyle = config.blockquoteStyle?.(snapshot.context);
return caretAtTheEndOfQuote && looksLikeMarkdownQuote && blockquoteStyle !== void 0 ? {
focusTextBlock,
style: blockquoteStyle
} : !1;
},
actions: [() => [execute({
type: "insert.text",
text: " "
})], (_, {
focusTextBlock,
style
}) => [execute({
type: "block.unset",
props: ["listItem", "level"],
at: focusTextBlock.path
}), execute({
type: "block.set",
props: {
style
},
at: focusTextBlock.path
}), execute({
type: "delete.text",
at: {
anchor: {
path: focusTextBlock.path,
offset: 0
},
focus: {
path: focusTextBlock.path,
offset: 2
}
}
})]]
}), automaticHr = defineBehavior({
on: "insert.text",
guard: ({
snapshot,
event
}) => {
const hrCharacter = event.text === "-" ? "-" : event.text === "*" ? "*" : event.text === "_" ? "_" : void 0;
if (hrCharacter === void 0)
return !1;
const hrObject = config.horizontalRuleObject?.(snapshot.context), focusBlock = getFocusTextBlock(snapshot), selectionCollapsed = isSelectionCollapsed(snapshot);
if (!hrObject || !focusBlock || !selectionCollapsed)
return !1;
const previousInlineObject = getPreviousInlineObject(snapshot), textBefore = getBlockTextBefore(snapshot), hrBlockOffsets = {
anchor: {
path: focusBlock.path,
offset: 0
},
focus: {
path: focusBlock.path,
offset: 3
}
};
return !previousInlineObject && textBefore === `${hrCharacter}${hrCharacter}` ? {
hrObject,
focusBlock,
hrCharacter,
hrBlockOffsets
} : !1;
},
actions: [(_, {
hrCharacter
}) => [execute({
type: "insert.text",
text: hrCharacter
})], (_, {
hrObject,
hrBlockOffsets
}) => [execute({
type: "insert.block",
placement: "before",
block: {
_type: hrObject.name,
...hrObject.value ?? {}
}
}), execute({
type: "delete.text",
at: hrBlockOffsets
})]]
}), automaticHrOnPaste = defineBehavior({
on: "clipboard.paste",
guard: ({
snapshot,
event
}) => {
const text = event.originEvent.dataTransfer.getData("text/plain"), hrRegExp = /^(---)$|(___)$|(\*\*\*)$/, hrCharacters = text.match(hrRegExp)?.[0], hrObject = config.horizontalRuleObject?.(snapshot.context), focusBlock = getFocusBlock(snapshot);
return !hrCharacters || !hrObject || !focusBlock ? !1 : {
hrCharacters,
hrObject,
focusBlock
};
},
actions: [(_, {
hrCharacters
}) => [execute({
type: "insert.text",
text: hrCharacters
})], ({
snapshot
}, {
hrObject,
focusBlock
}) => isTextBlock(snapshot.context, focusBlock.node) ? [execute({
type: "insert.block",
block: {
_type: snapshot.context.schema.block.name,
children: focusBlock.node.children
},
placement: "after"
}), execute({
type: "insert.block",
block: {
_type: hrObject.name,
...hrObject.value ?? {}
},
placement: "after"
}), execute({
type: "delete.block",
at: focusBlock.path
})] : [execute({
type: "insert.block",
block: {
_type: hrObject.name,
...hrObject.value ?? {}
},
placement: "after"
})]]
}), automaticHeadingOnSpace = defineBehavior({
on: "insert.text",
guard: ({
snapshot,
event
}) => {
if (event.text !== " ")
return !1;
const selectionCollapsed = isSelectionCollapsed(snapshot), focusTextBlock = getFocusTextBlock(snapshot), focusSpan = getFocusSpan(snapshot);
if (!selectionCollapsed || !focusTextBlock || !focusSpan)
return !1;
const blockOffset = spanSelectionPointToBlockOffset({
context: snapshot.context,
selectionPoint: {
path: [{
_key: focusTextBlock.node._key
}, "children", {
_key: focusSpan.node._key
}],
offset: snapshot.context.selection?.focus.offset ?? 0
}
});
if (!blockOffset)
return !1;
const previousInlineObject = getPreviousInlineObject(snapshot), blockText = getTextBlockText(focusTextBlock.node), markdownHeadingSearch = /^#+/.exec(blockText), level = markdownHeadingSearch ? markdownHeadingSearch[0].length : void 0, caretAtTheEndOfHeading = blockOffset.offset === level;
if (previousInlineObject || !caretAtTheEndOfHeading)
return !1;
const style = level !== void 0 ? config.headingStyle?.({
schema: snapshot.context.schema,
level
}) : void 0;
return level !== void 0 && style !== void 0 ? {
focusTextBlock,
style,
level
} : !1;
},
actions: [({
event
}) => [execute(event)], (_, {
focusTextBlock,
style,
level
}) => [execute({
type: "block.unset",
props: ["listItem", "level"],
at: focusTextBlock.path
}), execute({
type: "block.set",
props: {
style
},
at: focusTextBlock.path
}), execute({
type: "delete.text",
at: {
anchor: {
path: focusTextBlock.path,
offset: 0
},
focus: {
path: focusTextBlock.path,
offset: level + 1
}
}
})]]
}), clearStyleOnBackspace = defineBehavior({
on: "delete.backward",
guard: ({
snapshot
}) => {
const selectionCollapsed = isSelectionCollapsed(snapshot), focusTextBlock = getFocusTextBlock(snapshot), focusSpan = getFocusSpan(snapshot);
if (!selectionCollapsed || !focusTextBlock || !focusSpan)
return !1;
const atTheBeginningOfBLock = focusTextBlock.node.children[0]._key === focusSpan.node._key && snapshot.context.selection?.focus.offset === 0, defaultStyle = config.defaultStyle?.(snapshot.context);
return atTheBeginningOfBLock && defaultStyle && focusTextBlock.node.style !== defaultStyle ? {
defaultStyle,
focusTextBlock
} : !1;
},
actions: [(_, {
defaultStyle,
focusTextBlock
}) => [execute({
type: "block.set",
props: {
style: defaultStyle
},
at: focusTextBlock.path
})]]
}), automaticListOnSpace = defineBehavior({
on: "insert.text",
guard: ({
snapshot,
event
}) => {
if (event.text !== " ")
return !1;
const selectionCollapsed = isSelectionCollapsed(snapshot), focusTextBlock = getFocusTextBlock(snapshot), focusSpan = getFocusSpan(snapshot);
if (!selectionCollapsed || !focusTextBlock || !focusSpan)
return !1;
const previousInlineObject = getPreviousInlineObject(snapshot), blockOffset = spanSelectionPointToBlockOffset({
context: snapshot.context,
selectionPoint: {
path: [{
_key: focusTextBlock.node._key
}, "children", {
_key: focusSpan.node._key
}],
offset: snapshot.context.selection?.focus.offset ?? 0
}
});
if (previousInlineObject || !blockOffset)
return !1;
const blockText = getTextBlockText(focusTextBlock.node), defaultStyle = config.defaultStyle?.(snapshot.context), looksLikeUnorderedList = /^(-|\*)/.test(blockText), unorderedListStyle = config.unorderedListStyle?.(snapshot.context), caretAtTheEndOfUnorderedList = blockOffset.offset === 1;
if (defaultStyle && caretAtTheEndOfUnorderedList && looksLikeUnorderedList && unorderedListStyle !== void 0)
return {
focusTextBlock,
listItem: unorderedListStyle,
listItemLength: 1,
style: defaultStyle
};
const looksLikeOrderedList = /^1\./.test(blockText), orderedListStyle = config.orderedListStyle?.(snapshot.context), caretAtTheEndOfOrderedList = blockOffset.offset === 2;
return defaultStyle && caretAtTheEndOfOrderedList && looksLikeOrderedList && orderedListStyle !== void 0 ? {
focusTextBlock,
listItem: orderedListStyle,
listItemLength: 2,
style: defaultStyle
} : !1;
},
actions: [({
event
}) => [execute(event)], (_, {
focusTextBlock,
style,
listItem,
listItemLength
}) => [execute({
type: "block.set",
props: {
listItem,
level: 1,
style
},
at: focusTextBlock.path
}), execute({
type: "delete.text",
at: {
anchor: {
path: focusTextBlock.path,
offset: 0
},
focus: {
path: focusTextBlock.path,
offset: listItemLength + 1
}
}
})]]
});
return [automaticBlockquoteOnSpace, automaticHeadingOnSpace, automaticHr, automaticHrOnPaste, clearStyleOnBackspace, automaticListOnSpace];
}
function MarkdownPlugin(props) {
const $ = c(17), editor = useEditor();
let t0, t1;
$[0] !== editor || $[1] !== props.config ? (t0 = () => {
const unregisterBehaviors = createMarkdownBehaviors(props.config).map((behavior) => editor.registerBehavior({
behavior
}));
return () => {
for (const unregisterBehavior of unregisterBehaviors)
unregisterBehavior();
};
}, t1 = [editor, props.config], $[0] = editor, $[1] = props.config, $[2] = t0, $[3] = t1) : (t0 = $[2], t1 = $[3]), useEffect(t0, t1);
let t2;
$[4] !== props.config.boldDecorator ? (t2 = props.config.boldDecorator ? /* @__PURE__ */ jsxs(Fragment, { children: [
/* @__PURE__ */ jsx(DecoratorShortcutPlugin, { decorator: props.config.boldDecorator, pair: {
char: "*",
amount: 2
} }),
/* @__PURE__ */ jsx(DecoratorShortcutPlugin, { decorator: props.config.boldDecorator, pair: {
char: "_",
amount: 2
} })
] }) : null, $[4] = props.config.boldDecorator, $[5] = t2) : t2 = $[5];
let t3;
$[6] !== props.config.codeDecorator ? (t3 = props.config.codeDecorator ? /* @__PURE__ */ jsx(DecoratorShortcutPlugin, { decorator: props.config.codeDecorator, pair: {
char: "`",
amount: 1
} }) : null, $[6] = props.config.codeDecorator, $[7] = t3) : t3 = $[7];
let t4;
$[8] !== props.config.italicDecorator ? (t4 = props.config.italicDecorator ? /* @__PURE__ */ jsxs(Fragment, { children: [
/* @__PURE__ */ jsx(DecoratorShortcutPlugin, { decorator: props.config.italicDecorator, pair: {
char: "*",
amount: 1
} }),
/* @__PURE__ */ jsx(DecoratorShortcutPlugin, { decorator: props.config.italicDecorator, pair: {
char: "_",
amount: 1
} })
] }) : null, $[8] = props.config.italicDecorator, $[9] = t4) : t4 = $[9];
let t5;
$[10] !== props.config.strikeThroughDecorator ? (t5 = props.config.strikeThroughDecorator ? /* @__PURE__ */ jsx(DecoratorShortcutPlugin, { decorator: props.config.strikeThroughDecorator, pair: {
char: "~",
amount: 2
} }) : null, $[10] = props.config.strikeThroughDecorator, $[11] = t5) : t5 = $[11];
let t6;
return $[12] !== t2 || $[13] !== t3 || $[14] !== t4 || $[15] !== t5 ? (t6 = /* @__PURE__ */ jsxs(Fragment, { children: [
t2,
t3,
t4,
t5
] }), $[12] = t2, $[13] = t3, $[14] = t4, $[15] = t5, $[16] = t6) : t6 = $[16], t6;
}
const oneLineBehaviors = [
/**
* Hitting Enter on an expanded selection should just delete that selection
* without causing a line break.
*/
defineBehavior({
on: "insert.break",
guard: ({
snapshot
}) => snapshot.context.selection && isSelectionExpanded(snapshot) ? {
selection: snapshot.context.selection
} : !1,
actions: [(_, {
selection
}) => [execute({
type: "delete",
at: selection
})]]
}),
/**
* All other cases of `insert.break` should be aborted.
*/
defineBehavior({
on: "insert.break",
actions: []
}),
/**
* `insert.block` `before` or `after` is not allowed in a one-line editor.
*/
defineBehavior({
on: "insert.block",
guard: ({
event
}) => event.placement === "before" || event.placement === "after",
actions: []
}),
/**
* An ordinary `insert.block` is acceptable if it's a text block. In that
* case it will get merged into the existing text block.
*/
defineBehavior({
on: "insert.block",
guard: ({
snapshot,
event
}) => !(!getFocusTextBlock(snapshot) || !isTextBlock$1(snapshot.context, event.block)),
actions: [({
event
}) => [execute({
type: "insert.block",
block: event.block,
placement: "auto",
select: "end"
})]]
}),
/**
* Fallback Behavior to avoid `insert.block` in case the Behaviors above all
* end up with a falsy guard.
*/
defineBehavior({
on: "insert.block",
actions: []
}),
/**
* If multiple blocks are inserted, then the non-text blocks are filtered out
* and the text blocks are merged into one block
*/
defineBehavior({
on: "insert.blocks",
guard: ({
snapshot,
event
}) => {
const textBlocks = event.blocks.filter((block) => isTextBlock$1(snapshot.context, block));
return textBlocks.length === 0 ? !1 : textBlocks.reduce((targetBlock, incomingBlock) => mergeTextBlocks({
context: snapshot.context,
targetBlock,
incomingBlock
}));
},
actions: [
// `insert.block` is raised so the Behavior above can handle the
// insertion
(_, block) => [raise({
type: "insert.block",
block,
placement: "auto"
})]
]
}),
/**
* Fallback Behavior to avoid `insert.blocks` in case the Behavior above
* ends up with a falsy guard.
*/
defineBehavior({
on: "insert.blocks",
actions: []
})
];
function OneLinePlugin() {
const $ = c(1);
let t0;
return $[0] === Symbol.for("react.memo_cache_sentinel") ? (t0 = /* @__PURE__ */ jsx(BehaviorPlugin, { behaviors: oneLineBehaviors }), $[0] = t0) : t0 = $[0], t0;
}
export {
BehaviorPlugin,
DecoratorShortcutPlugin,
EditorRefPlugin,
EventListenerPlugin,
MarkdownPlugin,
OneLinePlugin
};
//# sourceMappingURL=index.js.map