@portabletext/editor 1.3.1 → 1.4.1
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.
- package/lib/index.d.mts +2634 -44
- package/lib/index.d.ts +2634 -44
- package/lib/index.esm.js +532 -377
- package/lib/index.esm.js.map +1 -1
- package/lib/index.js +531 -377
- package/lib/index.js.map +1 -1
- package/lib/index.mjs +532 -377
- package/lib/index.mjs.map +1 -1
- package/package.json +9 -8
- package/src/editor/PortableTextEditor.tsx +101 -72
- package/src/editor/behavior/behavior.markdown.ts +203 -0
- package/src/editor/editor-machine.ts +16 -2
- package/src/editor/plugins/createWithEditableAPI.ts +1 -1
- package/src/editor/use-editor.ts +45 -0
- package/src/index.ts +14 -8
- package/src/types/editor.ts +1 -1
package/lib/index.esm.js
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { isPortableTextTextBlock, isPortableTextSpan as isPortableTextSpan$1, isKeySegment, isPortableTextListBlock } from "@sanity/types";
|
|
1
2
|
import { jsx, Fragment, jsxs } from "react/jsx-runtime";
|
|
2
3
|
import isEqual from "lodash/isEqual.js";
|
|
3
4
|
import noop from "lodash/noop.js";
|
|
@@ -5,7 +6,6 @@ import { useRef, useState, useEffect, useMemo, createContext, useContext, useCal
|
|
|
5
6
|
import { Editor, Element as Element$1, Range, Point, Text, Path, Transforms, Node, Operation, createEditor, deleteBackward, deleteForward, insertText } from "slate";
|
|
6
7
|
import { useSlateStatic, ReactEditor, useSelected, withReact, Slate, useSlate, Editable } from "slate-react";
|
|
7
8
|
import debug$m from "debug";
|
|
8
|
-
import { isKeySegment, isPortableTextTextBlock, isPortableTextSpan as isPortableTextSpan$1, isPortableTextListBlock } from "@sanity/types";
|
|
9
9
|
import { c } from "react-compiler-runtime";
|
|
10
10
|
import { styled } from "styled-components";
|
|
11
11
|
import uniq from "lodash/uniq.js";
|
|
@@ -24,6 +24,247 @@ import throttle from "lodash/throttle.js";
|
|
|
24
24
|
import { useEffectEvent } from "use-effect-event";
|
|
25
25
|
import debounce from "lodash/debounce.js";
|
|
26
26
|
import { randomKey } from "@sanity/util/content";
|
|
27
|
+
import { useActorRef } from "@xstate/react";
|
|
28
|
+
function defineBehavior(behavior) {
|
|
29
|
+
return behavior;
|
|
30
|
+
}
|
|
31
|
+
function selectionIsCollapsed(context) {
|
|
32
|
+
return context.selection?.anchor.path.join() === context.selection?.focus.path.join() && context.selection?.anchor.offset === context.selection?.focus.offset;
|
|
33
|
+
}
|
|
34
|
+
function getFocusBlock(context) {
|
|
35
|
+
const key = context.selection && isKeySegment(context.selection.focus.path[0]) ? context.selection.focus.path[0]._key : void 0, node = key ? context.value.find((block) => block._key === key) : void 0;
|
|
36
|
+
return node && key ? {
|
|
37
|
+
node,
|
|
38
|
+
path: [{
|
|
39
|
+
_key: key
|
|
40
|
+
}]
|
|
41
|
+
} : void 0;
|
|
42
|
+
}
|
|
43
|
+
function getFocusTextBlock(context) {
|
|
44
|
+
const focusBlock = getFocusBlock(context);
|
|
45
|
+
return focusBlock && isPortableTextTextBlock(focusBlock.node) ? {
|
|
46
|
+
node: focusBlock.node,
|
|
47
|
+
path: focusBlock.path
|
|
48
|
+
} : void 0;
|
|
49
|
+
}
|
|
50
|
+
function getFocusBlockObject(context) {
|
|
51
|
+
const focusBlock = getFocusBlock(context);
|
|
52
|
+
return focusBlock && !isPortableTextTextBlock(focusBlock.node) ? {
|
|
53
|
+
node: focusBlock.node,
|
|
54
|
+
path: focusBlock.path
|
|
55
|
+
} : void 0;
|
|
56
|
+
}
|
|
57
|
+
function getFocusChild(context) {
|
|
58
|
+
const focusBlock = getFocusTextBlock(context);
|
|
59
|
+
if (!focusBlock)
|
|
60
|
+
return;
|
|
61
|
+
const key = context.selection && isKeySegment(context.selection.focus.path[2]) ? context.selection.focus.path[2]._key : void 0, node = key ? focusBlock.node.children.find((span) => span._key === key) : void 0;
|
|
62
|
+
return node && key ? {
|
|
63
|
+
node,
|
|
64
|
+
path: [...focusBlock.path, "children", {
|
|
65
|
+
_key: key
|
|
66
|
+
}]
|
|
67
|
+
} : void 0;
|
|
68
|
+
}
|
|
69
|
+
function getFocusSpan(context) {
|
|
70
|
+
const focusChild = getFocusChild(context);
|
|
71
|
+
return focusChild && isPortableTextSpan$1(focusChild.node) ? {
|
|
72
|
+
node: focusChild.node,
|
|
73
|
+
path: focusChild.path
|
|
74
|
+
} : void 0;
|
|
75
|
+
}
|
|
76
|
+
function getSelectionStartBlock(context) {
|
|
77
|
+
const key = context.selection.backward ? isKeySegment(context.selection.focus.path[0]) ? context.selection.focus.path[0]._key : void 0 : isKeySegment(context.selection.anchor.path[0]) ? context.selection.anchor.path[0]._key : void 0, node = key ? context.value.find((block) => block._key === key) : void 0;
|
|
78
|
+
return node && key ? {
|
|
79
|
+
node,
|
|
80
|
+
path: [{
|
|
81
|
+
_key: key
|
|
82
|
+
}]
|
|
83
|
+
} : void 0;
|
|
84
|
+
}
|
|
85
|
+
function getSelectionEndBlock(context) {
|
|
86
|
+
const key = context.selection.backward ? isKeySegment(context.selection.anchor.path[0]) ? context.selection.anchor.path[0]._key : void 0 : isKeySegment(context.selection.focus.path[0]) ? context.selection.focus.path[0]._key : void 0, node = key ? context.value.find((block) => block._key === key) : void 0;
|
|
87
|
+
return node && key ? {
|
|
88
|
+
node,
|
|
89
|
+
path: [{
|
|
90
|
+
_key: key
|
|
91
|
+
}]
|
|
92
|
+
} : void 0;
|
|
93
|
+
}
|
|
94
|
+
function getPreviousBlock(context) {
|
|
95
|
+
let previousBlock;
|
|
96
|
+
const selectionStartBlock = getSelectionStartBlock(context);
|
|
97
|
+
if (!selectionStartBlock)
|
|
98
|
+
return;
|
|
99
|
+
let foundSelectionStartBlock = !1;
|
|
100
|
+
for (const block of context.value) {
|
|
101
|
+
if (block._key === selectionStartBlock.node._key) {
|
|
102
|
+
foundSelectionStartBlock = !0;
|
|
103
|
+
break;
|
|
104
|
+
}
|
|
105
|
+
previousBlock = {
|
|
106
|
+
node: block,
|
|
107
|
+
path: [{
|
|
108
|
+
_key: block._key
|
|
109
|
+
}]
|
|
110
|
+
};
|
|
111
|
+
}
|
|
112
|
+
if (foundSelectionStartBlock && previousBlock)
|
|
113
|
+
return previousBlock;
|
|
114
|
+
}
|
|
115
|
+
function getNextBlock(context) {
|
|
116
|
+
let nextBlock;
|
|
117
|
+
const selectionEndBlock = getSelectionEndBlock(context);
|
|
118
|
+
if (!selectionEndBlock)
|
|
119
|
+
return;
|
|
120
|
+
let foundSelectionEndBlock = !1;
|
|
121
|
+
for (const block of context.value) {
|
|
122
|
+
if (block._key === selectionEndBlock.node._key) {
|
|
123
|
+
foundSelectionEndBlock = !0;
|
|
124
|
+
continue;
|
|
125
|
+
}
|
|
126
|
+
if (foundSelectionEndBlock) {
|
|
127
|
+
nextBlock = {
|
|
128
|
+
node: block,
|
|
129
|
+
path: [{
|
|
130
|
+
_key: block._key
|
|
131
|
+
}]
|
|
132
|
+
};
|
|
133
|
+
break;
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
if (foundSelectionEndBlock && nextBlock)
|
|
137
|
+
return nextBlock;
|
|
138
|
+
}
|
|
139
|
+
function isEmptyTextBlock(block) {
|
|
140
|
+
return block.children.length === 1 && block.children[0].text === "";
|
|
141
|
+
}
|
|
142
|
+
function createMarkdownBehaviors(config) {
|
|
143
|
+
const automaticStyleOnSpace = {
|
|
144
|
+
on: "insert text",
|
|
145
|
+
guard: ({
|
|
146
|
+
context,
|
|
147
|
+
event
|
|
148
|
+
}) => {
|
|
149
|
+
if (event.text !== " ")
|
|
150
|
+
return !1;
|
|
151
|
+
const selectionCollapsed = selectionIsCollapsed(context), focusTextBlock = getFocusTextBlock(context), focusSpan = getFocusSpan(context);
|
|
152
|
+
if (!selectionCollapsed || !focusTextBlock || !focusSpan)
|
|
153
|
+
return !1;
|
|
154
|
+
const looksLikeMarkdownHeading = /^#+/.test(focusSpan.node.text), headingStyle = config.mapHeadingStyle(context.schema, focusSpan.node.text.length), looksLikeMarkdownQuote = /^>/.test(focusSpan.node.text), blockquoteStyle = config.mapBlockquoteStyle(context.schema);
|
|
155
|
+
return looksLikeMarkdownHeading && headingStyle !== void 0 ? {
|
|
156
|
+
focusTextBlock,
|
|
157
|
+
focusSpan,
|
|
158
|
+
style: headingStyle
|
|
159
|
+
} : looksLikeMarkdownQuote && blockquoteStyle !== void 0 ? {
|
|
160
|
+
focusTextBlock,
|
|
161
|
+
focusSpan,
|
|
162
|
+
style: blockquoteStyle
|
|
163
|
+
} : !1;
|
|
164
|
+
},
|
|
165
|
+
actions: [() => [{
|
|
166
|
+
type: "insert text",
|
|
167
|
+
text: " "
|
|
168
|
+
}], (_, {
|
|
169
|
+
focusTextBlock,
|
|
170
|
+
focusSpan,
|
|
171
|
+
style
|
|
172
|
+
}) => [{
|
|
173
|
+
type: "set block",
|
|
174
|
+
style,
|
|
175
|
+
paths: [focusTextBlock.path]
|
|
176
|
+
}, {
|
|
177
|
+
type: "delete",
|
|
178
|
+
selection: {
|
|
179
|
+
anchor: {
|
|
180
|
+
path: focusSpan.path,
|
|
181
|
+
offset: 0
|
|
182
|
+
},
|
|
183
|
+
focus: {
|
|
184
|
+
path: focusSpan.path,
|
|
185
|
+
offset: focusSpan.node.text.length + 1
|
|
186
|
+
}
|
|
187
|
+
}
|
|
188
|
+
}]]
|
|
189
|
+
}, clearStyleOnBackspace = {
|
|
190
|
+
on: "delete backward",
|
|
191
|
+
guard: ({
|
|
192
|
+
context
|
|
193
|
+
}) => {
|
|
194
|
+
const selectionCollapsed = selectionIsCollapsed(context), focusTextBlock = getFocusTextBlock(context), focusSpan = getFocusSpan(context);
|
|
195
|
+
if (!selectionCollapsed || !focusTextBlock || !focusSpan)
|
|
196
|
+
return !1;
|
|
197
|
+
const defaultStyle = config.mapDefaultStyle(context.schema);
|
|
198
|
+
return defaultStyle && focusTextBlock.node.children.length === 1 && focusTextBlock.node.style !== config.mapDefaultStyle(context.schema) && focusSpan.node.text === "" ? {
|
|
199
|
+
defaultStyle,
|
|
200
|
+
focusTextBlock
|
|
201
|
+
} : !1;
|
|
202
|
+
},
|
|
203
|
+
actions: [(_, {
|
|
204
|
+
defaultStyle,
|
|
205
|
+
focusTextBlock
|
|
206
|
+
}) => [{
|
|
207
|
+
type: "set block",
|
|
208
|
+
style: defaultStyle,
|
|
209
|
+
paths: [focusTextBlock.path]
|
|
210
|
+
}]]
|
|
211
|
+
}, automaticListOnSpace = {
|
|
212
|
+
on: "insert text",
|
|
213
|
+
guard: ({
|
|
214
|
+
context,
|
|
215
|
+
event
|
|
216
|
+
}) => {
|
|
217
|
+
if (event.text !== " ")
|
|
218
|
+
return !1;
|
|
219
|
+
const selectionCollapsed = selectionIsCollapsed(context), focusTextBlock = getFocusTextBlock(context), focusSpan = getFocusSpan(context);
|
|
220
|
+
if (!selectionCollapsed || !focusTextBlock || !focusSpan)
|
|
221
|
+
return !1;
|
|
222
|
+
const looksLikeUnorderedList = /^-/.test(focusSpan.node.text), unorderedListStyle = config.mapUnorderedListStyle(context.schema);
|
|
223
|
+
if (looksLikeUnorderedList && unorderedListStyle !== void 0)
|
|
224
|
+
return {
|
|
225
|
+
focusTextBlock,
|
|
226
|
+
focusSpan,
|
|
227
|
+
listItem: unorderedListStyle
|
|
228
|
+
};
|
|
229
|
+
const looksLikeOrderedList = /^1./.test(focusSpan.node.text), orderedListStyle = config.mapOrderedListStyle(context.schema);
|
|
230
|
+
return looksLikeOrderedList && orderedListStyle !== void 0 ? {
|
|
231
|
+
focusTextBlock,
|
|
232
|
+
focusSpan,
|
|
233
|
+
listItem: orderedListStyle
|
|
234
|
+
} : !1;
|
|
235
|
+
},
|
|
236
|
+
actions: [() => [{
|
|
237
|
+
type: "insert text",
|
|
238
|
+
text: " "
|
|
239
|
+
}], (_, {
|
|
240
|
+
focusTextBlock,
|
|
241
|
+
focusSpan,
|
|
242
|
+
listItem
|
|
243
|
+
}) => [{
|
|
244
|
+
type: "unset block",
|
|
245
|
+
props: ["style"],
|
|
246
|
+
paths: [focusTextBlock.path]
|
|
247
|
+
}, {
|
|
248
|
+
type: "set block",
|
|
249
|
+
listItem,
|
|
250
|
+
level: 1,
|
|
251
|
+
paths: [focusTextBlock.path]
|
|
252
|
+
}, {
|
|
253
|
+
type: "delete",
|
|
254
|
+
selection: {
|
|
255
|
+
anchor: {
|
|
256
|
+
path: focusSpan.path,
|
|
257
|
+
offset: 0
|
|
258
|
+
},
|
|
259
|
+
focus: {
|
|
260
|
+
path: focusSpan.path,
|
|
261
|
+
offset: focusSpan.node.text.length + 1
|
|
262
|
+
}
|
|
263
|
+
}
|
|
264
|
+
}]]
|
|
265
|
+
};
|
|
266
|
+
return [automaticStyleOnSpace, clearStyleOnBackspace, automaticListOnSpace];
|
|
267
|
+
}
|
|
27
268
|
const rootName = "sanity-pte:";
|
|
28
269
|
debug$m(rootName);
|
|
29
270
|
function debugWithName(name) {
|
|
@@ -660,360 +901,119 @@ const EMPTY_ANNOTATIONS = [], inlineBlockStyle = {
|
|
|
660
901
|
get() {
|
|
661
902
|
return console.warn("Property 'type' is deprecated, use 'schemaType' instead."), schemaTypes.block;
|
|
662
903
|
}
|
|
663
|
-
}), propsOrDefaultRendered = renderBlock ? renderBlock(renderProps) : children;
|
|
664
|
-
return /* @__PURE__ */ jsx("div", { ...attributes, className, spellCheck, children: /* @__PURE__ */ jsx(DraggableBlock, { element, readOnly, blockRef, children: /* @__PURE__ */ jsx("div", { ref: blockRef, children: propsOrDefaultRendered }) }) }, element._key);
|
|
665
|
-
}
|
|
666
|
-
const schemaType_0 = schemaTypes.blockObjects.find((_type_0) => _type_0.name === element._type);
|
|
667
|
-
if (!schemaType_0)
|
|
668
|
-
throw new Error(`Could not find schema type for block element of _type ${element._type}`);
|
|
669
|
-
className = "pt-block pt-object-block";
|
|
670
|
-
const block_0 = fromSlateValue([element], schemaTypes.block.name, KEY_TO_VALUE_ELEMENT.get(editor))[0];
|
|
671
|
-
let renderedBlockFromProps;
|
|
672
|
-
if (renderBlock) {
|
|
673
|
-
const _props = Object.defineProperty({
|
|
674
|
-
children: /* @__PURE__ */ jsx(DefaultObject, { value }),
|
|
675
|
-
editorElementRef: blockRef,
|
|
676
|
-
focused,
|
|
677
|
-
path: blockPath,
|
|
678
|
-
schemaType: schemaType_0,
|
|
679
|
-
selected,
|
|
680
|
-
value: block_0
|
|
681
|
-
}, "type", {
|
|
682
|
-
enumerable: !1,
|
|
683
|
-
get() {
|
|
684
|
-
return console.warn("Property 'type' is deprecated, use 'schemaType' instead."), schemaType_0;
|
|
685
|
-
}
|
|
686
|
-
});
|
|
687
|
-
renderedBlockFromProps = renderBlock(_props);
|
|
688
|
-
}
|
|
689
|
-
return /* @__PURE__ */ jsxs("div", { ...attributes, className, children: [
|
|
690
|
-
children,
|
|
691
|
-
/* @__PURE__ */ jsxs(DraggableBlock, { element, readOnly, blockRef, children: [
|
|
692
|
-
renderedBlockFromProps && /* @__PURE__ */ jsx("div", { ref: blockRef, contentEditable: !1, children: renderedBlockFromProps }),
|
|
693
|
-
!renderedBlockFromProps && /* @__PURE__ */ jsx(DefaultBlockObject, { selected, children: /* @__PURE__ */ jsx(DefaultObject, { value }) })
|
|
694
|
-
] })
|
|
695
|
-
] }, element._key);
|
|
696
|
-
};
|
|
697
|
-
Element.displayName = "Element";
|
|
698
|
-
const PortableTextEditorContext = createContext(null), usePortableTextEditor = () => {
|
|
699
|
-
const editor = useContext(PortableTextEditorContext);
|
|
700
|
-
if (!editor)
|
|
701
|
-
throw new Error("The `usePortableTextEditor` hook must be used inside the <PortableTextEditor> component's context.");
|
|
702
|
-
return editor;
|
|
703
|
-
};
|
|
704
|
-
function DefaultAnnotation(props) {
|
|
705
|
-
const $ = c(6);
|
|
706
|
-
let t0;
|
|
707
|
-
$[0] !== props.annotation ? (t0 = () => alert(JSON.stringify(props.annotation)), $[0] = props.annotation, $[1] = t0) : t0 = $[1];
|
|
708
|
-
const handleClick = t0;
|
|
709
|
-
let t1;
|
|
710
|
-
$[2] === Symbol.for("react.memo_cache_sentinel") ? (t1 = {
|
|
711
|
-
color: "blue"
|
|
712
|
-
}, $[2] = t1) : t1 = $[2];
|
|
713
|
-
let t2;
|
|
714
|
-
return $[3] !== handleClick || $[4] !== props.children ? (t2 = /* @__PURE__ */ jsx("span", { style: t1, onClick: handleClick, children: props.children }), $[3] = handleClick, $[4] = props.children, $[5] = t2) : t2 = $[5], t2;
|
|
715
|
-
}
|
|
716
|
-
DefaultAnnotation.displayName = "DefaultAnnotation";
|
|
717
|
-
function getPortableTextMemberSchemaTypes(portableTextType) {
|
|
718
|
-
if (!portableTextType)
|
|
719
|
-
throw new Error("Parameter 'portabletextType' missing (required)");
|
|
720
|
-
const blockType = portableTextType.of?.find(findBlockType);
|
|
721
|
-
if (!blockType)
|
|
722
|
-
throw new Error("Block type is not defined in this schema (required)");
|
|
723
|
-
const childrenField = blockType.fields?.find((field) => field.name === "children");
|
|
724
|
-
if (!childrenField)
|
|
725
|
-
throw new Error("Children field for block type found in schema (required)");
|
|
726
|
-
const ofType = childrenField.type.of;
|
|
727
|
-
if (!ofType)
|
|
728
|
-
throw new Error("Valid types for block children not found in schema (required)");
|
|
729
|
-
const spanType = ofType.find((memberType) => memberType.name === "span");
|
|
730
|
-
if (!spanType)
|
|
731
|
-
throw new Error("Span type not found in schema (required)");
|
|
732
|
-
const inlineObjectTypes = ofType.filter((memberType) => memberType.name !== "span") || [], blockObjectTypes = portableTextType.of?.filter((field) => field.name !== blockType.name) || [];
|
|
733
|
-
return {
|
|
734
|
-
styles: resolveEnabledStyles(blockType),
|
|
735
|
-
decorators: resolveEnabledDecorators(spanType),
|
|
736
|
-
lists: resolveEnabledListItems(blockType),
|
|
737
|
-
block: blockType,
|
|
738
|
-
span: spanType,
|
|
739
|
-
portableText: portableTextType,
|
|
740
|
-
inlineObjects: inlineObjectTypes,
|
|
741
|
-
blockObjects: blockObjectTypes,
|
|
742
|
-
annotations: spanType.annotations
|
|
743
|
-
};
|
|
744
|
-
}
|
|
745
|
-
function resolveEnabledStyles(blockType) {
|
|
746
|
-
const styleField = blockType.fields?.find((btField) => btField.name === "style");
|
|
747
|
-
if (!styleField)
|
|
748
|
-
throw new Error("A field with name 'style' is not defined in the block type (required).");
|
|
749
|
-
const textStyles = styleField.type.options?.list && styleField.type.options.list?.filter((style) => style.value);
|
|
750
|
-
if (!textStyles || textStyles.length === 0)
|
|
751
|
-
throw new Error("The style fields need at least one style defined. I.e: {title: 'Normal', value: 'normal'}.");
|
|
752
|
-
return textStyles;
|
|
753
|
-
}
|
|
754
|
-
function resolveEnabledDecorators(spanType) {
|
|
755
|
-
return spanType.decorators;
|
|
756
|
-
}
|
|
757
|
-
function resolveEnabledListItems(blockType) {
|
|
758
|
-
const listField = blockType.fields?.find((btField) => btField.name === "listItem");
|
|
759
|
-
if (!listField)
|
|
760
|
-
throw new Error("A field with name 'listItem' is not defined in the block type (required).");
|
|
761
|
-
const listItems = listField.type.options?.list && listField.type.options.list.filter((list) => list.value);
|
|
762
|
-
if (!listItems)
|
|
763
|
-
throw new Error("The list field need at least to be an empty array");
|
|
764
|
-
return listItems;
|
|
765
|
-
}
|
|
766
|
-
function findBlockType(type) {
|
|
767
|
-
return type.type ? findBlockType(type.type) : type.name === "block" ? type : null;
|
|
768
|
-
}
|
|
769
|
-
function compileType(rawType) {
|
|
770
|
-
return Schema.compile({
|
|
771
|
-
name: "blockTypeSchema",
|
|
772
|
-
types: [rawType]
|
|
773
|
-
}).get(rawType.name);
|
|
774
|
-
}
|
|
775
|
-
|
|
776
|
-
return context.selection?.anchor.path.join() === context.selection?.focus.path.join() && context.selection?.anchor.offset === context.selection?.focus.offset;
|
|
777
|
-
}
|
|
778
|
-
function getFocusBlock(context) {
|
|
779
|
-
const key = context.selection && isKeySegment(context.selection.focus.path[0]) ? context.selection.focus.path[0]._key : void 0, node = key ? context.value.find((block) => block._key === key) : void 0;
|
|
780
|
-
return node && key ? {
|
|
781
|
-
node,
|
|
782
|
-
path: [{
|
|
783
|
-
_key: key
|
|
784
|
-
}]
|
|
785
|
-
} : void 0;
|
|
786
|
-
}
|
|
787
|
-
function getFocusTextBlock(context) {
|
|
788
|
-
const focusBlock = getFocusBlock(context);
|
|
789
|
-
return focusBlock && isPortableTextTextBlock(focusBlock.node) ? {
|
|
790
|
-
node: focusBlock.node,
|
|
791
|
-
path: focusBlock.path
|
|
792
|
-
} : void 0;
|
|
793
|
-
}
|
|
794
|
-
function getFocusBlockObject(context) {
|
|
795
|
-
const focusBlock = getFocusBlock(context);
|
|
796
|
-
return focusBlock && !isPortableTextTextBlock(focusBlock.node) ? {
|
|
797
|
-
node: focusBlock.node,
|
|
798
|
-
path: focusBlock.path
|
|
799
|
-
} : void 0;
|
|
800
|
-
}
|
|
801
|
-
function getFocusChild(context) {
|
|
802
|
-
const focusBlock = getFocusTextBlock(context);
|
|
803
|
-
if (!focusBlock)
|
|
804
|
-
return;
|
|
805
|
-
const key = context.selection && isKeySegment(context.selection.focus.path[2]) ? context.selection.focus.path[2]._key : void 0, node = key ? focusBlock.node.children.find((span) => span._key === key) : void 0;
|
|
806
|
-
return node && key ? {
|
|
807
|
-
node,
|
|
808
|
-
path: [...focusBlock.path, "children", {
|
|
809
|
-
_key: key
|
|
810
|
-
}]
|
|
811
|
-
} : void 0;
|
|
812
|
-
}
|
|
813
|
-
function getFocusSpan(context) {
|
|
814
|
-
const focusChild = getFocusChild(context);
|
|
815
|
-
return focusChild && isPortableTextSpan$1(focusChild.node) ? {
|
|
816
|
-
node: focusChild.node,
|
|
817
|
-
path: focusChild.path
|
|
818
|
-
} : void 0;
|
|
819
|
-
}
|
|
820
|
-
function getSelectionStartBlock(context) {
|
|
821
|
-
const key = context.selection.backward ? isKeySegment(context.selection.focus.path[0]) ? context.selection.focus.path[0]._key : void 0 : isKeySegment(context.selection.anchor.path[0]) ? context.selection.anchor.path[0]._key : void 0, node = key ? context.value.find((block) => block._key === key) : void 0;
|
|
822
|
-
return node && key ? {
|
|
823
|
-
node,
|
|
824
|
-
path: [{
|
|
825
|
-
_key: key
|
|
826
|
-
}]
|
|
827
|
-
} : void 0;
|
|
828
|
-
}
|
|
829
|
-
function getSelectionEndBlock(context) {
|
|
830
|
-
const key = context.selection.backward ? isKeySegment(context.selection.anchor.path[0]) ? context.selection.anchor.path[0]._key : void 0 : isKeySegment(context.selection.focus.path[0]) ? context.selection.focus.path[0]._key : void 0, node = key ? context.value.find((block) => block._key === key) : void 0;
|
|
831
|
-
return node && key ? {
|
|
832
|
-
node,
|
|
833
|
-
path: [{
|
|
834
|
-
_key: key
|
|
835
|
-
}]
|
|
836
|
-
} : void 0;
|
|
837
|
-
}
|
|
838
|
-
function getPreviousBlock(context) {
|
|
839
|
-
let previousBlock;
|
|
840
|
-
const selectionStartBlock = getSelectionStartBlock(context);
|
|
841
|
-
if (!selectionStartBlock)
|
|
842
|
-
return;
|
|
843
|
-
let foundSelectionStartBlock = !1;
|
|
844
|
-
for (const block of context.value) {
|
|
845
|
-
if (block._key === selectionStartBlock.node._key) {
|
|
846
|
-
foundSelectionStartBlock = !0;
|
|
847
|
-
break;
|
|
848
|
-
}
|
|
849
|
-
previousBlock = {
|
|
850
|
-
node: block,
|
|
851
|
-
path: [{
|
|
852
|
-
_key: block._key
|
|
853
|
-
}]
|
|
854
|
-
};
|
|
855
|
-
}
|
|
856
|
-
if (foundSelectionStartBlock && previousBlock)
|
|
857
|
-
return previousBlock;
|
|
858
|
-
}
|
|
859
|
-
function getNextBlock(context) {
|
|
860
|
-
let nextBlock;
|
|
861
|
-
const selectionEndBlock = getSelectionEndBlock(context);
|
|
862
|
-
if (!selectionEndBlock)
|
|
863
|
-
return;
|
|
864
|
-
let foundSelectionEndBlock = !1;
|
|
865
|
-
for (const block of context.value) {
|
|
866
|
-
if (block._key === selectionEndBlock.node._key) {
|
|
867
|
-
foundSelectionEndBlock = !0;
|
|
868
|
-
continue;
|
|
869
|
-
}
|
|
870
|
-
if (foundSelectionEndBlock) {
|
|
871
|
-
nextBlock = {
|
|
872
|
-
node: block,
|
|
873
|
-
path: [{
|
|
874
|
-
_key: block._key
|
|
875
|
-
}]
|
|
876
|
-
};
|
|
877
|
-
break;
|
|
878
|
-
}
|
|
879
|
-
}
|
|
880
|
-
if (foundSelectionEndBlock && nextBlock)
|
|
881
|
-
return nextBlock;
|
|
882
|
-
}
|
|
883
|
-
function isEmptyTextBlock(block) {
|
|
884
|
-
return block.children.length === 1 && block.children[0].text === "";
|
|
885
|
-
}
|
|
886
|
-
const breakingVoidBlock = {
|
|
887
|
-
on: "insert break",
|
|
888
|
-
guard: ({
|
|
889
|
-
context
|
|
890
|
-
}) => !!getFocusBlockObject(context),
|
|
891
|
-
actions: [() => [{
|
|
892
|
-
type: "insert text block",
|
|
893
|
-
decorators: []
|
|
894
|
-
}]]
|
|
895
|
-
}, deletingEmptyTextBlockAfterBlockObject = {
|
|
896
|
-
on: "delete backward",
|
|
897
|
-
guard: ({
|
|
898
|
-
context
|
|
899
|
-
}) => {
|
|
900
|
-
const focusTextBlock = getFocusTextBlock(context), selectionCollapsed = selectionIsCollapsed(context), previousBlock = getPreviousBlock(context);
|
|
901
|
-
return !focusTextBlock || !selectionCollapsed || !previousBlock ? !1 : isEmptyTextBlock(focusTextBlock.node) && !isPortableTextTextBlock(previousBlock.node) ? {
|
|
902
|
-
focusTextBlock,
|
|
903
|
-
previousBlock
|
|
904
|
-
} : !1;
|
|
905
|
-
},
|
|
906
|
-
actions: [(_, {
|
|
907
|
-
focusTextBlock,
|
|
908
|
-
previousBlock
|
|
909
|
-
}) => [{
|
|
910
|
-
type: "delete",
|
|
911
|
-
selection: {
|
|
912
|
-
anchor: {
|
|
913
|
-
path: focusTextBlock.path,
|
|
914
|
-
offset: 0
|
|
915
|
-
},
|
|
916
|
-
focus: {
|
|
917
|
-
path: focusTextBlock.path,
|
|
918
|
-
offset: 0
|
|
919
|
-
}
|
|
920
|
-
}
|
|
921
|
-
}, {
|
|
922
|
-
type: "select",
|
|
923
|
-
selection: {
|
|
924
|
-
anchor: {
|
|
925
|
-
path: previousBlock.path,
|
|
926
|
-
offset: 0
|
|
927
|
-
},
|
|
928
|
-
focus: {
|
|
929
|
-
path: previousBlock.path,
|
|
930
|
-
offset: 0
|
|
931
|
-
}
|
|
932
|
-
}
|
|
933
|
-
}]]
|
|
934
|
-
}, deletingEmptyTextBlockBeforeBlockObject = {
|
|
935
|
-
on: "delete forward",
|
|
936
|
-
guard: ({
|
|
937
|
-
context
|
|
938
|
-
}) => {
|
|
939
|
-
const focusTextBlock = getFocusTextBlock(context), selectionCollapsed = selectionIsCollapsed(context), nextBlock = getNextBlock(context);
|
|
940
|
-
return !focusTextBlock || !selectionCollapsed || !nextBlock ? !1 : isEmptyTextBlock(focusTextBlock.node) && !isPortableTextTextBlock(nextBlock.node) ? {
|
|
941
|
-
focusTextBlock,
|
|
942
|
-
nextBlock
|
|
943
|
-
} : !1;
|
|
944
|
-
},
|
|
945
|
-
actions: [(_, {
|
|
946
|
-
focusTextBlock,
|
|
947
|
-
nextBlock
|
|
948
|
-
}) => [{
|
|
949
|
-
type: "delete",
|
|
950
|
-
selection: {
|
|
951
|
-
anchor: {
|
|
952
|
-
path: focusTextBlock.path,
|
|
953
|
-
offset: 0
|
|
954
|
-
},
|
|
955
|
-
focus: {
|
|
956
|
-
path: focusTextBlock.path,
|
|
957
|
-
offset: 0
|
|
958
|
-
}
|
|
959
|
-
}
|
|
960
|
-
}, {
|
|
961
|
-
type: "select",
|
|
962
|
-
selection: {
|
|
963
|
-
anchor: {
|
|
964
|
-
path: nextBlock.path,
|
|
965
|
-
offset: 0
|
|
966
|
-
},
|
|
967
|
-
focus: {
|
|
968
|
-
path: nextBlock.path,
|
|
969
|
-
offset: 0
|
|
970
|
-
}
|
|
971
|
-
}
|
|
972
|
-
}]]
|
|
973
|
-
}, coreBlockObjectBehaviors = [breakingVoidBlock, deletingEmptyTextBlockAfterBlockObject, deletingEmptyTextBlockBeforeBlockObject], clearListOnBackspace = {
|
|
974
|
-
on: "delete backward",
|
|
975
|
-
guard: ({
|
|
976
|
-
context
|
|
977
|
-
}) => {
|
|
978
|
-
const selectionCollapsed = selectionIsCollapsed(context), focusTextBlock = getFocusTextBlock(context), focusSpan = getFocusSpan(context);
|
|
979
|
-
return !selectionCollapsed || !focusTextBlock || !focusSpan ? !1 : focusTextBlock.node.children[0]._key === focusSpan.node._key && context.selection.focus.offset === 0 && focusTextBlock.node.level === 1 ? {
|
|
980
|
-
focusTextBlock
|
|
981
|
-
} : !1;
|
|
982
|
-
},
|
|
983
|
-
actions: [(_, {
|
|
984
|
-
focusTextBlock
|
|
985
|
-
}) => [{
|
|
986
|
-
type: "unset block",
|
|
987
|
-
props: ["listItem", "level"],
|
|
988
|
-
paths: [focusTextBlock.path]
|
|
989
|
-
}]]
|
|
990
|
-
}, unindentListOnBackspace = {
|
|
991
|
-
on: "delete backward",
|
|
992
|
-
guard: ({
|
|
993
|
-
context
|
|
994
|
-
}) => {
|
|
995
|
-
const selectionCollapsed = selectionIsCollapsed(context), focusTextBlock = getFocusTextBlock(context), focusSpan = getFocusSpan(context);
|
|
996
|
-
return !selectionCollapsed || !focusTextBlock || !focusSpan ? !1 : focusTextBlock.node.children[0]._key === focusSpan.node._key && context.selection.focus.offset === 0 && focusTextBlock.node.level !== void 0 && focusTextBlock.node.level > 1 ? {
|
|
997
|
-
focusTextBlock,
|
|
998
|
-
level: focusTextBlock.node.level - 1
|
|
999
|
-
} : !1;
|
|
1000
|
-
},
|
|
1001
|
-
actions: [(_, {
|
|
1002
|
-
focusTextBlock,
|
|
1003
|
-
level
|
|
1004
|
-
}) => [{
|
|
1005
|
-
type: "set block",
|
|
1006
|
-
level,
|
|
1007
|
-
paths: [focusTextBlock.path]
|
|
1008
|
-
}]]
|
|
1009
|
-
}, coreListBehaviors = [clearListOnBackspace, unindentListOnBackspace], softReturn = {
|
|
1010
|
-
on: "insert soft break",
|
|
1011
|
-
actions: [() => [{
|
|
1012
|
-
type: "insert text",
|
|
1013
|
-
text: `
|
|
1014
|
-
`
|
|
1015
|
-
}]]
|
|
1016
|
-
}, coreBehaviors = [softReturn, ...coreBlockObjectBehaviors, ...coreListBehaviors], debug$k = debugWithName("operationToPatches");
|
|
904
|
+
}), propsOrDefaultRendered = renderBlock ? renderBlock(renderProps) : children;
|
|
905
|
+
return /* @__PURE__ */ jsx("div", { ...attributes, className, spellCheck, children: /* @__PURE__ */ jsx(DraggableBlock, { element, readOnly, blockRef, children: /* @__PURE__ */ jsx("div", { ref: blockRef, children: propsOrDefaultRendered }) }) }, element._key);
|
|
906
|
+
}
|
|
907
|
+
const schemaType_0 = schemaTypes.blockObjects.find((_type_0) => _type_0.name === element._type);
|
|
908
|
+
if (!schemaType_0)
|
|
909
|
+
throw new Error(`Could not find schema type for block element of _type ${element._type}`);
|
|
910
|
+
className = "pt-block pt-object-block";
|
|
911
|
+
const block_0 = fromSlateValue([element], schemaTypes.block.name, KEY_TO_VALUE_ELEMENT.get(editor))[0];
|
|
912
|
+
let renderedBlockFromProps;
|
|
913
|
+
if (renderBlock) {
|
|
914
|
+
const _props = Object.defineProperty({
|
|
915
|
+
children: /* @__PURE__ */ jsx(DefaultObject, { value }),
|
|
916
|
+
editorElementRef: blockRef,
|
|
917
|
+
focused,
|
|
918
|
+
path: blockPath,
|
|
919
|
+
schemaType: schemaType_0,
|
|
920
|
+
selected,
|
|
921
|
+
value: block_0
|
|
922
|
+
}, "type", {
|
|
923
|
+
enumerable: !1,
|
|
924
|
+
get() {
|
|
925
|
+
return console.warn("Property 'type' is deprecated, use 'schemaType' instead."), schemaType_0;
|
|
926
|
+
}
|
|
927
|
+
});
|
|
928
|
+
renderedBlockFromProps = renderBlock(_props);
|
|
929
|
+
}
|
|
930
|
+
return /* @__PURE__ */ jsxs("div", { ...attributes, className, children: [
|
|
931
|
+
children,
|
|
932
|
+
/* @__PURE__ */ jsxs(DraggableBlock, { element, readOnly, blockRef, children: [
|
|
933
|
+
renderedBlockFromProps && /* @__PURE__ */ jsx("div", { ref: blockRef, contentEditable: !1, children: renderedBlockFromProps }),
|
|
934
|
+
!renderedBlockFromProps && /* @__PURE__ */ jsx(DefaultBlockObject, { selected, children: /* @__PURE__ */ jsx(DefaultObject, { value }) })
|
|
935
|
+
] })
|
|
936
|
+
] }, element._key);
|
|
937
|
+
};
|
|
938
|
+
Element.displayName = "Element";
|
|
939
|
+
const PortableTextEditorContext = createContext(null), usePortableTextEditor = () => {
|
|
940
|
+
const editor = useContext(PortableTextEditorContext);
|
|
941
|
+
if (!editor)
|
|
942
|
+
throw new Error("The `usePortableTextEditor` hook must be used inside the <PortableTextEditor> component's context.");
|
|
943
|
+
return editor;
|
|
944
|
+
};
|
|
945
|
+
function DefaultAnnotation(props) {
|
|
946
|
+
const $ = c(6);
|
|
947
|
+
let t0;
|
|
948
|
+
$[0] !== props.annotation ? (t0 = () => alert(JSON.stringify(props.annotation)), $[0] = props.annotation, $[1] = t0) : t0 = $[1];
|
|
949
|
+
const handleClick = t0;
|
|
950
|
+
let t1;
|
|
951
|
+
$[2] === Symbol.for("react.memo_cache_sentinel") ? (t1 = {
|
|
952
|
+
color: "blue"
|
|
953
|
+
}, $[2] = t1) : t1 = $[2];
|
|
954
|
+
let t2;
|
|
955
|
+
return $[3] !== handleClick || $[4] !== props.children ? (t2 = /* @__PURE__ */ jsx("span", { style: t1, onClick: handleClick, children: props.children }), $[3] = handleClick, $[4] = props.children, $[5] = t2) : t2 = $[5], t2;
|
|
956
|
+
}
|
|
957
|
+
DefaultAnnotation.displayName = "DefaultAnnotation";
|
|
958
|
+
function getPortableTextMemberSchemaTypes(portableTextType) {
|
|
959
|
+
if (!portableTextType)
|
|
960
|
+
throw new Error("Parameter 'portabletextType' missing (required)");
|
|
961
|
+
const blockType = portableTextType.of?.find(findBlockType);
|
|
962
|
+
if (!blockType)
|
|
963
|
+
throw new Error("Block type is not defined in this schema (required)");
|
|
964
|
+
const childrenField = blockType.fields?.find((field) => field.name === "children");
|
|
965
|
+
if (!childrenField)
|
|
966
|
+
throw new Error("Children field for block type found in schema (required)");
|
|
967
|
+
const ofType = childrenField.type.of;
|
|
968
|
+
if (!ofType)
|
|
969
|
+
throw new Error("Valid types for block children not found in schema (required)");
|
|
970
|
+
const spanType = ofType.find((memberType) => memberType.name === "span");
|
|
971
|
+
if (!spanType)
|
|
972
|
+
throw new Error("Span type not found in schema (required)");
|
|
973
|
+
const inlineObjectTypes = ofType.filter((memberType) => memberType.name !== "span") || [], blockObjectTypes = portableTextType.of?.filter((field) => field.name !== blockType.name) || [];
|
|
974
|
+
return {
|
|
975
|
+
styles: resolveEnabledStyles(blockType),
|
|
976
|
+
decorators: resolveEnabledDecorators(spanType),
|
|
977
|
+
lists: resolveEnabledListItems(blockType),
|
|
978
|
+
block: blockType,
|
|
979
|
+
span: spanType,
|
|
980
|
+
portableText: portableTextType,
|
|
981
|
+
inlineObjects: inlineObjectTypes,
|
|
982
|
+
blockObjects: blockObjectTypes,
|
|
983
|
+
annotations: spanType.annotations
|
|
984
|
+
};
|
|
985
|
+
}
|
|
986
|
+
function resolveEnabledStyles(blockType) {
|
|
987
|
+
const styleField = blockType.fields?.find((btField) => btField.name === "style");
|
|
988
|
+
if (!styleField)
|
|
989
|
+
throw new Error("A field with name 'style' is not defined in the block type (required).");
|
|
990
|
+
const textStyles = styleField.type.options?.list && styleField.type.options.list?.filter((style) => style.value);
|
|
991
|
+
if (!textStyles || textStyles.length === 0)
|
|
992
|
+
throw new Error("The style fields need at least one style defined. I.e: {title: 'Normal', value: 'normal'}.");
|
|
993
|
+
return textStyles;
|
|
994
|
+
}
|
|
995
|
+
function resolveEnabledDecorators(spanType) {
|
|
996
|
+
return spanType.decorators;
|
|
997
|
+
}
|
|
998
|
+
function resolveEnabledListItems(blockType) {
|
|
999
|
+
const listField = blockType.fields?.find((btField) => btField.name === "listItem");
|
|
1000
|
+
if (!listField)
|
|
1001
|
+
throw new Error("A field with name 'listItem' is not defined in the block type (required).");
|
|
1002
|
+
const listItems = listField.type.options?.list && listField.type.options.list.filter((list) => list.value);
|
|
1003
|
+
if (!listItems)
|
|
1004
|
+
throw new Error("The list field need at least to be an empty array");
|
|
1005
|
+
return listItems;
|
|
1006
|
+
}
|
|
1007
|
+
function findBlockType(type) {
|
|
1008
|
+
return type.type ? findBlockType(type.type) : type.name === "block" ? type : null;
|
|
1009
|
+
}
|
|
1010
|
+
function compileType(rawType) {
|
|
1011
|
+
return Schema.compile({
|
|
1012
|
+
name: "blockTypeSchema",
|
|
1013
|
+
types: [rawType]
|
|
1014
|
+
}).get(rawType.name);
|
|
1015
|
+
}
|
|
1016
|
+
const debug$k = debugWithName("operationToPatches");
|
|
1017
1017
|
function createOperationToPatches(types) {
|
|
1018
1018
|
const textBlockName = types.block.name;
|
|
1019
1019
|
function insertTextPatch(editor, operation, beforeValue) {
|
|
@@ -5282,7 +5282,137 @@ function performDefaultAction({
|
|
|
5282
5282
|
});
|
|
5283
5283
|
}
|
|
5284
5284
|
}
|
|
5285
|
-
const
|
|
5285
|
+
const breakingVoidBlock = {
|
|
5286
|
+
on: "insert break",
|
|
5287
|
+
guard: ({
|
|
5288
|
+
context
|
|
5289
|
+
}) => !!getFocusBlockObject(context),
|
|
5290
|
+
actions: [() => [{
|
|
5291
|
+
type: "insert text block",
|
|
5292
|
+
decorators: []
|
|
5293
|
+
}]]
|
|
5294
|
+
}, deletingEmptyTextBlockAfterBlockObject = {
|
|
5295
|
+
on: "delete backward",
|
|
5296
|
+
guard: ({
|
|
5297
|
+
context
|
|
5298
|
+
}) => {
|
|
5299
|
+
const focusTextBlock = getFocusTextBlock(context), selectionCollapsed = selectionIsCollapsed(context), previousBlock = getPreviousBlock(context);
|
|
5300
|
+
return !focusTextBlock || !selectionCollapsed || !previousBlock ? !1 : isEmptyTextBlock(focusTextBlock.node) && !isPortableTextTextBlock(previousBlock.node) ? {
|
|
5301
|
+
focusTextBlock,
|
|
5302
|
+
previousBlock
|
|
5303
|
+
} : !1;
|
|
5304
|
+
},
|
|
5305
|
+
actions: [(_, {
|
|
5306
|
+
focusTextBlock,
|
|
5307
|
+
previousBlock
|
|
5308
|
+
}) => [{
|
|
5309
|
+
type: "delete",
|
|
5310
|
+
selection: {
|
|
5311
|
+
anchor: {
|
|
5312
|
+
path: focusTextBlock.path,
|
|
5313
|
+
offset: 0
|
|
5314
|
+
},
|
|
5315
|
+
focus: {
|
|
5316
|
+
path: focusTextBlock.path,
|
|
5317
|
+
offset: 0
|
|
5318
|
+
}
|
|
5319
|
+
}
|
|
5320
|
+
}, {
|
|
5321
|
+
type: "select",
|
|
5322
|
+
selection: {
|
|
5323
|
+
anchor: {
|
|
5324
|
+
path: previousBlock.path,
|
|
5325
|
+
offset: 0
|
|
5326
|
+
},
|
|
5327
|
+
focus: {
|
|
5328
|
+
path: previousBlock.path,
|
|
5329
|
+
offset: 0
|
|
5330
|
+
}
|
|
5331
|
+
}
|
|
5332
|
+
}]]
|
|
5333
|
+
}, deletingEmptyTextBlockBeforeBlockObject = {
|
|
5334
|
+
on: "delete forward",
|
|
5335
|
+
guard: ({
|
|
5336
|
+
context
|
|
5337
|
+
}) => {
|
|
5338
|
+
const focusTextBlock = getFocusTextBlock(context), selectionCollapsed = selectionIsCollapsed(context), nextBlock = getNextBlock(context);
|
|
5339
|
+
return !focusTextBlock || !selectionCollapsed || !nextBlock ? !1 : isEmptyTextBlock(focusTextBlock.node) && !isPortableTextTextBlock(nextBlock.node) ? {
|
|
5340
|
+
focusTextBlock,
|
|
5341
|
+
nextBlock
|
|
5342
|
+
} : !1;
|
|
5343
|
+
},
|
|
5344
|
+
actions: [(_, {
|
|
5345
|
+
focusTextBlock,
|
|
5346
|
+
nextBlock
|
|
5347
|
+
}) => [{
|
|
5348
|
+
type: "delete",
|
|
5349
|
+
selection: {
|
|
5350
|
+
anchor: {
|
|
5351
|
+
path: focusTextBlock.path,
|
|
5352
|
+
offset: 0
|
|
5353
|
+
},
|
|
5354
|
+
focus: {
|
|
5355
|
+
path: focusTextBlock.path,
|
|
5356
|
+
offset: 0
|
|
5357
|
+
}
|
|
5358
|
+
}
|
|
5359
|
+
}, {
|
|
5360
|
+
type: "select",
|
|
5361
|
+
selection: {
|
|
5362
|
+
anchor: {
|
|
5363
|
+
path: nextBlock.path,
|
|
5364
|
+
offset: 0
|
|
5365
|
+
},
|
|
5366
|
+
focus: {
|
|
5367
|
+
path: nextBlock.path,
|
|
5368
|
+
offset: 0
|
|
5369
|
+
}
|
|
5370
|
+
}
|
|
5371
|
+
}]]
|
|
5372
|
+
}, coreBlockObjectBehaviors = [breakingVoidBlock, deletingEmptyTextBlockAfterBlockObject, deletingEmptyTextBlockBeforeBlockObject], clearListOnBackspace = {
|
|
5373
|
+
on: "delete backward",
|
|
5374
|
+
guard: ({
|
|
5375
|
+
context
|
|
5376
|
+
}) => {
|
|
5377
|
+
const selectionCollapsed = selectionIsCollapsed(context), focusTextBlock = getFocusTextBlock(context), focusSpan = getFocusSpan(context);
|
|
5378
|
+
return !selectionCollapsed || !focusTextBlock || !focusSpan ? !1 : focusTextBlock.node.children[0]._key === focusSpan.node._key && context.selection.focus.offset === 0 && focusTextBlock.node.level === 1 ? {
|
|
5379
|
+
focusTextBlock
|
|
5380
|
+
} : !1;
|
|
5381
|
+
},
|
|
5382
|
+
actions: [(_, {
|
|
5383
|
+
focusTextBlock
|
|
5384
|
+
}) => [{
|
|
5385
|
+
type: "unset block",
|
|
5386
|
+
props: ["listItem", "level"],
|
|
5387
|
+
paths: [focusTextBlock.path]
|
|
5388
|
+
}]]
|
|
5389
|
+
}, unindentListOnBackspace = {
|
|
5390
|
+
on: "delete backward",
|
|
5391
|
+
guard: ({
|
|
5392
|
+
context
|
|
5393
|
+
}) => {
|
|
5394
|
+
const selectionCollapsed = selectionIsCollapsed(context), focusTextBlock = getFocusTextBlock(context), focusSpan = getFocusSpan(context);
|
|
5395
|
+
return !selectionCollapsed || !focusTextBlock || !focusSpan ? !1 : focusTextBlock.node.children[0]._key === focusSpan.node._key && context.selection.focus.offset === 0 && focusTextBlock.node.level !== void 0 && focusTextBlock.node.level > 1 ? {
|
|
5396
|
+
focusTextBlock,
|
|
5397
|
+
level: focusTextBlock.node.level - 1
|
|
5398
|
+
} : !1;
|
|
5399
|
+
},
|
|
5400
|
+
actions: [(_, {
|
|
5401
|
+
focusTextBlock,
|
|
5402
|
+
level
|
|
5403
|
+
}) => [{
|
|
5404
|
+
type: "set block",
|
|
5405
|
+
level,
|
|
5406
|
+
paths: [focusTextBlock.path]
|
|
5407
|
+
}]]
|
|
5408
|
+
}, coreListBehaviors = [clearListOnBackspace, unindentListOnBackspace], softReturn = {
|
|
5409
|
+
on: "insert soft break",
|
|
5410
|
+
actions: [() => [{
|
|
5411
|
+
type: "insert text",
|
|
5412
|
+
text: `
|
|
5413
|
+
`
|
|
5414
|
+
}]]
|
|
5415
|
+
}, coreBehaviors = [softReturn, ...coreBlockObjectBehaviors, ...coreListBehaviors], networkLogic = fromCallback(({
|
|
5286
5416
|
sendBack
|
|
5287
5417
|
}) => {
|
|
5288
5418
|
const onlineHandler = () => {
|
|
@@ -5305,6 +5435,11 @@ const networkLogic = fromCallback(({
|
|
|
5305
5435
|
input: {}
|
|
5306
5436
|
},
|
|
5307
5437
|
actions: {
|
|
5438
|
+
"assign behaviors": assign({
|
|
5439
|
+
behaviors: ({
|
|
5440
|
+
event
|
|
5441
|
+
}) => (assertEvent(event, "update behaviors"), [...coreBehaviors, ...event.behaviors])
|
|
5442
|
+
}),
|
|
5308
5443
|
"assign schema": assign({
|
|
5309
5444
|
schema: ({
|
|
5310
5445
|
event
|
|
@@ -5397,7 +5532,7 @@ const networkLogic = fromCallback(({
|
|
|
5397
5532
|
context: ({
|
|
5398
5533
|
input
|
|
5399
5534
|
}) => ({
|
|
5400
|
-
behaviors: input.behaviors,
|
|
5535
|
+
behaviors: input.behaviors ? [...coreBehaviors, ...input.behaviors] : coreBehaviors,
|
|
5401
5536
|
keyGenerator: input.keyGenerator,
|
|
5402
5537
|
pendingEvents: [],
|
|
5403
5538
|
schema: input.schema
|
|
@@ -5472,6 +5607,9 @@ const networkLogic = fromCallback(({
|
|
|
5472
5607
|
type: "done loading"
|
|
5473
5608
|
})
|
|
5474
5609
|
},
|
|
5610
|
+
"update behaviors": {
|
|
5611
|
+
actions: "assign behaviors"
|
|
5612
|
+
},
|
|
5475
5613
|
"update schema": {
|
|
5476
5614
|
actions: "assign schema"
|
|
5477
5615
|
},
|
|
@@ -5582,18 +5720,21 @@ class PortableTextEditor extends Component {
|
|
|
5582
5720
|
* The editor API (currently implemented with Slate).
|
|
5583
5721
|
*/
|
|
5584
5722
|
constructor(props) {
|
|
5585
|
-
if (super(props),
|
|
5586
|
-
|
|
5587
|
-
|
|
5588
|
-
|
|
5589
|
-
|
|
5590
|
-
|
|
5591
|
-
|
|
5592
|
-
|
|
5593
|
-
|
|
5723
|
+
if (super(props), props.editor)
|
|
5724
|
+
this.editorActor = props.editor, this.editorActor.start(), this.schemaTypes = this.editorActor.getSnapshot().context.schema;
|
|
5725
|
+
else {
|
|
5726
|
+
if (!props.schemaType)
|
|
5727
|
+
throw new Error('PortableTextEditor: missing "schemaType" property');
|
|
5728
|
+
props.incomingPatches$ && console.warn("The prop 'incomingPatches$' is deprecated and renamed to 'patches$'"), this.schemaTypes = getPortableTextMemberSchemaTypes(props.schemaType.hasOwnProperty("jsonType") ? props.schemaType : compileType(props.schemaType)), this.editorActor = props.editor ?? createActor(editorMachine, {
|
|
5729
|
+
input: {
|
|
5730
|
+
keyGenerator: props.keyGenerator || defaultKeyGenerator,
|
|
5731
|
+
schema: this.schemaTypes
|
|
5732
|
+
}
|
|
5733
|
+
}), this.editorActor.start();
|
|
5734
|
+
}
|
|
5594
5735
|
}
|
|
5595
5736
|
componentDidUpdate(prevProps) {
|
|
5596
|
-
this.props.schemaType !== prevProps.schemaType && (this.schemaTypes = getPortableTextMemberSchemaTypes(this.props.schemaType.hasOwnProperty("jsonType") ? this.props.schemaType : compileType(this.props.schemaType)), this.editorActor.send({
|
|
5737
|
+
!this.props.editor && !prevProps.editor && this.props.schemaType !== prevProps.schemaType && (this.schemaTypes = getPortableTextMemberSchemaTypes(this.props.schemaType.hasOwnProperty("jsonType") ? this.props.schemaType : compileType(this.props.schemaType)), this.editorActor.send({
|
|
5597
5738
|
type: "update schema",
|
|
5598
5739
|
schema: this.schemaTypes
|
|
5599
5740
|
})), this.props.editorRef !== prevProps.editorRef && this.props.editorRef && (this.props.editorRef.current = this);
|
|
@@ -5609,19 +5750,14 @@ class PortableTextEditor extends Component {
|
|
|
5609
5750
|
return this.editable.getValue();
|
|
5610
5751
|
};
|
|
5611
5752
|
render() {
|
|
5612
|
-
const
|
|
5613
|
-
value,
|
|
5614
|
-
children,
|
|
5615
|
-
patches$,
|
|
5616
|
-
incomingPatches$
|
|
5617
|
-
} = this.props, _patches$ = incomingPatches$ || patches$, maxBlocks = typeof this.props.maxBlocks > "u" ? void 0 : Number.parseInt(this.props.maxBlocks.toString(), 10) || void 0, readOnly = !!this.props.readOnly;
|
|
5753
|
+
const maxBlocks = this.props.editor || typeof this.props.maxBlocks > "u" ? void 0 : Number.parseInt(this.props.maxBlocks.toString(), 10) || void 0, readOnly = !!this.props.readOnly, legacyPatches = this.props.editor ? void 0 : this.props.incomingPatches$ ?? this.props.patches$;
|
|
5618
5754
|
return /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
5619
|
-
|
|
5755
|
+
legacyPatches ? /* @__PURE__ */ jsx(RoutePatchesObservableToEditorActor, { editorActor: this.editorActor, patches$: legacyPatches }) : null,
|
|
5620
5756
|
/* @__PURE__ */ jsx(EditorActorContext.Provider, { value: this.editorActor, children: /* @__PURE__ */ jsx(SlateContainer, { editorActor: this.editorActor, maxBlocks, portableTextEditor: this, readOnly, children: /* @__PURE__ */ jsx(PortableTextEditorContext.Provider, { value: this, children: /* @__PURE__ */ jsx(PortableTextEditorReadOnlyContext.Provider, { value: readOnly, children: /* @__PURE__ */ jsxs(PortableTextEditorSelectionProvider, { editorActor: this.editorActor, children: [
|
|
5621
5757
|
/* @__PURE__ */ jsx(Synchronizer, { editorActor: this.editorActor, getValue: this.getValue, onChange: (change) => {
|
|
5622
|
-
this.props.onChange(change), this.change$.next(change);
|
|
5623
|
-
}, value }),
|
|
5624
|
-
children
|
|
5758
|
+
this.props.editor || this.props.onChange(change), this.change$.next(change);
|
|
5759
|
+
}, value: this.props.value }),
|
|
5760
|
+
this.props.children
|
|
5625
5761
|
] }) }) }) }) })
|
|
5626
5762
|
] });
|
|
5627
5763
|
}
|
|
@@ -6079,11 +6215,30 @@ const debug = debugWithName("component:Editable"), PLACEHOLDER_STYLE = {
|
|
|
6079
6215
|
) : null;
|
|
6080
6216
|
});
|
|
6081
6217
|
PortableTextEditable.displayName = "ForwardRef(PortableTextEditable)";
|
|
6218
|
+
function useEditor(config) {
|
|
6219
|
+
const $ = c(8);
|
|
6220
|
+
let t0;
|
|
6221
|
+
$[0] !== config.schema ? (t0 = config.schema.hasOwnProperty("jsonType") ? config.schema : compileType(config.schema), $[0] = config.schema, $[1] = t0) : t0 = $[1];
|
|
6222
|
+
let t1;
|
|
6223
|
+
$[2] !== t0 ? (t1 = getPortableTextMemberSchemaTypes(t0), $[2] = t0, $[3] = t1) : t1 = $[3];
|
|
6224
|
+
const schema = t1, t2 = config.keyGenerator ?? defaultKeyGenerator;
|
|
6225
|
+
let t3;
|
|
6226
|
+
return $[4] !== config.behaviors || $[5] !== t2 || $[6] !== schema ? (t3 = {
|
|
6227
|
+
input: {
|
|
6228
|
+
behaviors: config.behaviors,
|
|
6229
|
+
keyGenerator: t2,
|
|
6230
|
+
schema
|
|
6231
|
+
}
|
|
6232
|
+
}, $[4] = config.behaviors, $[5] = t2, $[6] = schema, $[7] = t3) : t3 = $[7], useActorRef(editorMachine, t3);
|
|
6233
|
+
}
|
|
6082
6234
|
export {
|
|
6083
6235
|
PortableTextEditable,
|
|
6084
6236
|
PortableTextEditor,
|
|
6237
|
+
createMarkdownBehaviors,
|
|
6238
|
+
defineBehavior,
|
|
6085
6239
|
editorMachine,
|
|
6086
6240
|
defaultKeyGenerator as keyGenerator,
|
|
6241
|
+
useEditor,
|
|
6087
6242
|
usePortableTextEditor,
|
|
6088
6243
|
usePortableTextEditorSelection
|
|
6089
6244
|
};
|