@portabletext/plugin-one-line
Version:
🤏 Restricts the Portable Text Editor to a single line
116 lines (115 loc) • 3.97 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: !0 });
var editor = require("@portabletext/editor"), behaviors = require("@portabletext/editor/behaviors"), selectors = require("@portabletext/editor/selectors"), utils = require("@portabletext/editor/utils"), react = require("react");
function _interopNamespaceCompat(e) {
if (e && typeof e == "object" && "default" in e) return e;
var n = /* @__PURE__ */ Object.create(null);
return e && Object.keys(e).forEach(function(k) {
if (k !== "default") {
var d = Object.getOwnPropertyDescriptor(e, k);
Object.defineProperty(n, k, d.get ? d : {
enumerable: !0,
get: function() {
return e[k];
}
});
}
}), n.default = e, Object.freeze(n);
}
var selectors__namespace = /* @__PURE__ */ _interopNamespaceCompat(selectors), utils__namespace = /* @__PURE__ */ _interopNamespaceCompat(utils);
const oneLineBehaviors = [
/**
* Hitting Enter on an expanded selection should just delete that selection
* without causing a line break.
*/
behaviors.defineBehavior({
on: "insert.break",
guard: ({ snapshot }) => snapshot.context.selection && selectors__namespace.isSelectionExpanded(snapshot) ? { selection: snapshot.context.selection } : !1,
actions: [(_, { selection }) => [behaviors.execute({ type: "delete", at: selection })]]
}),
/**
* All other cases of `insert.break` should be aborted.
*/
behaviors.defineBehavior({
on: "insert.break",
actions: []
}),
/**
* `insert.block` `before` or `after` is not allowed in a one-line editor.
*/
behaviors.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.
*/
behaviors.defineBehavior({
on: "insert.block",
guard: ({ snapshot, event }) => !(!selectors__namespace.getFocusTextBlock(snapshot) || !utils__namespace.isTextBlock(snapshot.context, event.block)),
actions: [
({ event }) => [
behaviors.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.
*/
behaviors.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
*/
behaviors.defineBehavior({
on: "insert.blocks",
guard: ({ snapshot, event }) => {
const textBlocks = event.blocks.filter(
(block) => utils__namespace.isTextBlock(snapshot.context, block)
);
return textBlocks.length === 0 ? !1 : textBlocks.reduce((targetBlock, incomingBlock) => utils__namespace.mergeTextBlocks({
context: snapshot.context,
targetBlock,
incomingBlock
}));
},
actions: [
// `insert.block` is raised so the Behavior above can handle the
// insertion
(_, block) => [behaviors.raise({ type: "insert.block", block, placement: "auto" })]
]
}),
/**
* Fallback Behavior to avoid `insert.blocks` in case the Behavior above
* ends up with a falsy guard.
*/
behaviors.defineBehavior({
on: "insert.blocks",
actions: []
})
];
function OneLinePlugin() {
const editor$1 = editor.useEditor();
return react.useEffect(() => {
const unregisterBehaviors = oneLineBehaviors.map(
(behavior) => editor$1.registerBehavior({ behavior })
);
return () => {
for (const unregisterBehavior of unregisterBehaviors)
unregisterBehavior();
};
}, [editor$1]), null;
}
exports.OneLinePlugin = OneLinePlugin;
//# sourceMappingURL=index.cjs.map