@portabletext/editor 1.16.2 → 1.16.4
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/README.md +133 -117
- package/lib/index.cjs +106 -100
- package/lib/index.cjs.map +1 -1
- package/lib/index.d.cts +38 -113
- package/lib/index.d.ts +38 -113
- package/lib/index.js +107 -101
- package/lib/index.js.map +1 -1
- package/package.json +4 -4
- package/src/behavior-actions/behavior.actions.ts +0 -3
- package/src/editor/create-editor.ts +2 -0
- package/src/editor/editor-machine.ts +8 -7
- package/src/editor/sync-machine.ts +117 -107
package/README.md
CHANGED
|
@@ -9,20 +9,8 @@
|
|
|
9
9
|
|
|
10
10
|
> The official editor for editing [Portable Text](https://github.com/portabletext/portabletext) – the JSON based rich text specification for modern content editing platforms.
|
|
11
11
|
|
|
12
|
-
> [!NOTE]
|
|
13
|
-
> We are currently working hard on the general release of this component. Better docs and refined APIs are coming.
|
|
14
|
-
|
|
15
|
-
## End-User Experience
|
|
16
|
-
|
|
17
|
-
In order to provide a robust and consistent end-user experience, the editor is backed by an elaborate E2E test suite generated from a [human-readable Gherkin spec](/packages/editor/gherkin-spec/).
|
|
18
|
-
|
|
19
12
|
## Build Your Own Portable Text Editor
|
|
20
13
|
|
|
21
|
-
> [!WARNING]
|
|
22
|
-
> The `@portabletext/editor` is currently on the path to deprecate legacy APIs and introduce new ones. The end goals are to make the editor easier to use outside of `Sanity` (and without `@sanity/*` libraries) as well as providing a brand new API to configure the behavior of the editor.
|
|
23
|
-
>
|
|
24
|
-
> This means that the `defineSchema` and `EditorProvider` APIs showcased here are still experimental APIs tagged with `@alpha` and cannot be considered stable yet. At the same time, the examples below showcase usages of legacy static methods on the `PortableTextEditor` (for example, `PortableTextEditor.isMarkActive(...)` and `PortableTextEditor.toggleMark(...)`) that will soon be discouraged and deprecrated.
|
|
25
|
-
|
|
26
14
|
Check [/examples/basic/src/App.tsx](/examples/basic/src/App.tsx) for a basic example of how to set up the edior. Most of the source code from this example app can also be found in the instructions below.
|
|
27
15
|
|
|
28
16
|
### Define the Schema
|
|
@@ -219,153 +207,177 @@ function isStockTicker(
|
|
|
219
207
|
|
|
220
208
|
### Render the Toolbar
|
|
221
209
|
|
|
222
|
-
Your toolbar needs to be rendered within `EditorProvider` because it requires a reference to the `
|
|
210
|
+
Your toolbar needs to be rendered within `EditorProvider` because it requires a reference to the `editor` that it produces. To toggle marks and styles and to insert objects, you'll have to use the `.send` method on this `editor` instance.
|
|
223
211
|
|
|
224
212
|
```tsx
|
|
225
213
|
function Toolbar() {
|
|
226
214
|
// Obtain the editor instance
|
|
227
|
-
const
|
|
228
|
-
// Rerender the toolbar whenever the selection changes
|
|
229
|
-
usePortableTextEditorSelection()
|
|
215
|
+
const editor = useEditor()
|
|
230
216
|
|
|
231
|
-
const decoratorButtons = schemaDefinition.decorators.map((decorator) =>
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
}}
|
|
243
|
-
onClick={() => {
|
|
244
|
-
// Toggle the decorator by name
|
|
245
|
-
PortableTextEditor.toggleMark(editorInstance, decorator.name)
|
|
246
|
-
// Pressing this button steals focus so let's focus the editor again
|
|
247
|
-
PortableTextEditor.focus(editorInstance)
|
|
248
|
-
}}
|
|
249
|
-
>
|
|
250
|
-
{decorator.name}
|
|
251
|
-
</button>
|
|
252
|
-
)
|
|
253
|
-
})
|
|
217
|
+
const decoratorButtons = schemaDefinition.decorators.map((decorator) => (
|
|
218
|
+
<DecoratorButton key={decorator.name} decorator={decorator.name} />
|
|
219
|
+
))
|
|
220
|
+
|
|
221
|
+
const annotationButtons = schemaDefinition.annotations.map((annotation) => (
|
|
222
|
+
<AnnotationButton key={annotation.name} annotation={annotation} />
|
|
223
|
+
))
|
|
224
|
+
|
|
225
|
+
const styleButtons = schemaDefinition.styles.map((style) => (
|
|
226
|
+
<StyleButton key={style.name} style={style.name} />
|
|
227
|
+
))
|
|
254
228
|
|
|
255
|
-
const
|
|
229
|
+
const listButtons = schemaDefinition.lists.map((list) => (
|
|
230
|
+
<ListButton key={list.name} list={list.name} />
|
|
231
|
+
))
|
|
232
|
+
|
|
233
|
+
const imageButton = (
|
|
256
234
|
<button
|
|
257
|
-
style={{
|
|
258
|
-
textDecoration: PortableTextEditor.isAnnotationActive(
|
|
259
|
-
editorInstance,
|
|
260
|
-
schemaDefinition.annotations[0].name,
|
|
261
|
-
)
|
|
262
|
-
? 'underline'
|
|
263
|
-
: 'unset',
|
|
264
|
-
}}
|
|
265
235
|
onClick={() => {
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
)
|
|
276
|
-
} else {
|
|
277
|
-
PortableTextEditor.addAnnotation(
|
|
278
|
-
editorInstance,
|
|
279
|
-
schemaDefinition.annotations[0],
|
|
280
|
-
{href: 'https://example.com'},
|
|
281
|
-
)
|
|
282
|
-
}
|
|
283
|
-
PortableTextEditor.focus(editorInstance)
|
|
236
|
+
editor.send({
|
|
237
|
+
type: 'insert.block object',
|
|
238
|
+
blockObject: {
|
|
239
|
+
name: 'image',
|
|
240
|
+
value: {src: 'https://example.com/image.jpg'},
|
|
241
|
+
},
|
|
242
|
+
placement: 'auto',
|
|
243
|
+
})
|
|
244
|
+
editor.send({type: 'focus'})
|
|
284
245
|
}}
|
|
285
246
|
>
|
|
286
|
-
|
|
247
|
+
{schemaDefinition.blockObjects[0].name}
|
|
287
248
|
</button>
|
|
288
249
|
)
|
|
289
250
|
|
|
290
|
-
const
|
|
251
|
+
const stockTickerButton = (
|
|
291
252
|
<button
|
|
292
|
-
key={style.name}
|
|
293
|
-
style={{
|
|
294
|
-
textDecoration: PortableTextEditor.hasBlockStyle(
|
|
295
|
-
editorInstance,
|
|
296
|
-
style.name,
|
|
297
|
-
)
|
|
298
|
-
? 'underline'
|
|
299
|
-
: 'unset',
|
|
300
|
-
}}
|
|
301
253
|
onClick={() => {
|
|
302
|
-
|
|
303
|
-
|
|
254
|
+
editor.send({
|
|
255
|
+
type: 'insert.inline object',
|
|
256
|
+
inlineObject: {
|
|
257
|
+
name: 'stock-ticker',
|
|
258
|
+
value: {symbol: 'AAPL'},
|
|
259
|
+
},
|
|
260
|
+
})
|
|
261
|
+
editor.send({type: 'focus'})
|
|
304
262
|
}}
|
|
305
263
|
>
|
|
306
|
-
{
|
|
264
|
+
{schemaDefinition.inlineObjects[0].name}
|
|
307
265
|
</button>
|
|
308
|
-
)
|
|
266
|
+
)
|
|
309
267
|
|
|
310
|
-
|
|
268
|
+
return (
|
|
269
|
+
<>
|
|
270
|
+
<div>{decoratorButtons}</div>
|
|
271
|
+
<div>{annotationButtons}</div>
|
|
272
|
+
<div>{styleButtons}</div>
|
|
273
|
+
<div>{listButtons}</div>
|
|
274
|
+
<div>{imageButton}</div>
|
|
275
|
+
<div>{stockTickerButton}</div>
|
|
276
|
+
</>
|
|
277
|
+
)
|
|
278
|
+
}
|
|
279
|
+
|
|
280
|
+
function DecoratorButton(props: {decorator: string}) {
|
|
281
|
+
// Obtain the editor instance
|
|
282
|
+
const editor = useEditor()
|
|
283
|
+
// Check if the decorator is active using a selector
|
|
284
|
+
const active = useEditorSelector(
|
|
285
|
+
editor,
|
|
286
|
+
selectors.isActiveDecorator(props.decorator),
|
|
287
|
+
)
|
|
288
|
+
|
|
289
|
+
return (
|
|
311
290
|
<button
|
|
312
|
-
key={list.name}
|
|
313
291
|
style={{
|
|
314
|
-
textDecoration:
|
|
315
|
-
editorInstance,
|
|
316
|
-
list.name,
|
|
317
|
-
)
|
|
318
|
-
? 'underline'
|
|
319
|
-
: 'unset',
|
|
292
|
+
textDecoration: active ? 'underline' : 'unset',
|
|
320
293
|
}}
|
|
321
294
|
onClick={() => {
|
|
322
|
-
|
|
323
|
-
|
|
295
|
+
// Toggle the decorator
|
|
296
|
+
editor.send({
|
|
297
|
+
type: 'decorator.toggle',
|
|
298
|
+
decorator: props.decorator,
|
|
299
|
+
})
|
|
300
|
+
// Pressing this button steals focus so let's focus the editor again
|
|
301
|
+
editor.send({type: 'focus'})
|
|
324
302
|
}}
|
|
325
303
|
>
|
|
326
|
-
{
|
|
304
|
+
{props.decorator}
|
|
327
305
|
</button>
|
|
328
|
-
)
|
|
306
|
+
)
|
|
307
|
+
}
|
|
329
308
|
|
|
330
|
-
|
|
309
|
+
function AnnotationButton(props: {annotation: {name: string}}) {
|
|
310
|
+
const editor = useEditor()
|
|
311
|
+
const active = useEditorSelector(
|
|
312
|
+
editor,
|
|
313
|
+
selectors.isActiveAnnotation(props.annotation.name),
|
|
314
|
+
)
|
|
315
|
+
|
|
316
|
+
return (
|
|
331
317
|
<button
|
|
318
|
+
style={{
|
|
319
|
+
textDecoration: active ? 'underline' : 'unset',
|
|
320
|
+
}}
|
|
332
321
|
onClick={() => {
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
322
|
+
editor.send({
|
|
323
|
+
type: 'annotation.toggle',
|
|
324
|
+
annotation: {
|
|
325
|
+
name: props.annotation.name,
|
|
326
|
+
value:
|
|
327
|
+
props.annotation.name === 'link'
|
|
328
|
+
? {href: 'https://example.com'}
|
|
329
|
+
: {},
|
|
330
|
+
},
|
|
331
|
+
})
|
|
332
|
+
editor.send({type: 'focus'})
|
|
339
333
|
}}
|
|
340
334
|
>
|
|
341
|
-
{
|
|
335
|
+
{props.annotation.name}
|
|
342
336
|
</button>
|
|
343
337
|
)
|
|
338
|
+
}
|
|
344
339
|
|
|
345
|
-
|
|
340
|
+
function StyleButton(props: {style: string}) {
|
|
341
|
+
const editor = useEditor()
|
|
342
|
+
const active = useEditorSelector(editor, selectors.isActiveStyle(props.style))
|
|
343
|
+
|
|
344
|
+
return (
|
|
346
345
|
<button
|
|
346
|
+
style={{
|
|
347
|
+
textDecoration: active ? 'underline' : 'unset',
|
|
348
|
+
}}
|
|
347
349
|
onClick={() => {
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
schemaDefinition.inlineObjects[0],
|
|
351
|
-
{symbol: 'AAPL'},
|
|
352
|
-
)
|
|
353
|
-
PortableTextEditor.focus(editorInstance)
|
|
350
|
+
editor.send({type: 'style.toggle', style: props.style})
|
|
351
|
+
editor.send({type: 'focus'})
|
|
354
352
|
}}
|
|
355
353
|
>
|
|
356
|
-
{
|
|
354
|
+
{props.style}
|
|
357
355
|
</button>
|
|
358
356
|
)
|
|
357
|
+
}
|
|
358
|
+
|
|
359
|
+
function ListButton(props: {list: string}) {
|
|
360
|
+
const editor = useEditor()
|
|
361
|
+
const active = useEditorSelector(
|
|
362
|
+
editor,
|
|
363
|
+
selectors.isActiveListItem(props.list),
|
|
364
|
+
)
|
|
359
365
|
|
|
360
366
|
return (
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
367
|
+
<button
|
|
368
|
+
style={{
|
|
369
|
+
textDecoration: active ? 'underline' : 'unset',
|
|
370
|
+
}}
|
|
371
|
+
onClick={() => {
|
|
372
|
+
editor.send({
|
|
373
|
+
type: 'list item.toggle',
|
|
374
|
+
listItem: props.list,
|
|
375
|
+
})
|
|
376
|
+
editor.send({type: 'focus'})
|
|
377
|
+
}}
|
|
378
|
+
>
|
|
379
|
+
{props.list}
|
|
380
|
+
</button>
|
|
369
381
|
)
|
|
370
382
|
}
|
|
371
383
|
```
|
|
@@ -379,6 +391,10 @@ The Behavior API is a new way of interfacing with the Portable Text Editor. It a
|
|
|
379
391
|
3. Deriving editor **state** using **pure functions**.
|
|
380
392
|
4. Subscribe to **emitted** editor **events** using `editor.on(…)`.
|
|
381
393
|
|
|
394
|
+
## End-User Experience
|
|
395
|
+
|
|
396
|
+
In order to provide a robust and consistent end-user experience, the editor is backed by an elaborate E2E test suite generated from a [human-readable Gherkin spec](/packages/editor/gherkin-spec/).
|
|
397
|
+
|
|
382
398
|
## Development
|
|
383
399
|
|
|
384
400
|
### Develop Together with Sanity Studio
|
package/lib/index.cjs
CHANGED
|
@@ -11,11 +11,11 @@ var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { en
|
|
|
11
11
|
return a;
|
|
12
12
|
};
|
|
13
13
|
Object.defineProperty(exports, "__esModule", { value: !0 });
|
|
14
|
-
var schema = require("@sanity/schema"), types = require("@sanity/types"), startCase = require("lodash.startcase"), jsxRuntime = require("react/jsx-runtime"), react = require("@xstate/react"), isEqual = require("lodash/isEqual.js"), noop = require("lodash/noop.js"), React = require("react"), slate = require("slate"), slateReact = require("slate-react"), debug$
|
|
14
|
+
var schema = require("@sanity/schema"), types = require("@sanity/types"), startCase = require("lodash.startcase"), jsxRuntime = require("react/jsx-runtime"), react = require("@xstate/react"), isEqual = require("lodash/isEqual.js"), noop = require("lodash/noop.js"), React = require("react"), slate = require("slate"), slateReact = require("slate-react"), debug$l = require("debug"), reactCompilerRuntime = require("react-compiler-runtime"), styledComponents = require("styled-components"), uniq = require("lodash/uniq.js"), rxjs = require("rxjs"), useEffectEvent = require("use-effect-event"), xstate = require("xstate"), patches = require("@portabletext/patches"), flatten = require("lodash/flatten.js"), isPlainObject = require("lodash/isPlainObject.js"), get = require("lodash/get.js"), isUndefined = require("lodash/isUndefined.js"), omitBy = require("lodash/omitBy.js"), selector_isSelectionCollapsed = require("./_chunks-cjs/selector.is-selection-collapsed.cjs"), behavior_core = require("./_chunks-cjs/behavior.core.cjs"), getRandomValues = require("get-random-values-esm"), blockTools = require("@sanity/block-tools");
|
|
15
15
|
function _interopDefaultCompat(e) {
|
|
16
16
|
return e && typeof e == "object" && "default" in e ? e : { default: e };
|
|
17
17
|
}
|
|
18
|
-
var startCase__default = /* @__PURE__ */ _interopDefaultCompat(startCase), isEqual__default = /* @__PURE__ */ _interopDefaultCompat(isEqual), noop__default = /* @__PURE__ */ _interopDefaultCompat(noop), React__default = /* @__PURE__ */ _interopDefaultCompat(React), debug__default = /* @__PURE__ */ _interopDefaultCompat(debug$
|
|
18
|
+
var startCase__default = /* @__PURE__ */ _interopDefaultCompat(startCase), isEqual__default = /* @__PURE__ */ _interopDefaultCompat(isEqual), noop__default = /* @__PURE__ */ _interopDefaultCompat(noop), React__default = /* @__PURE__ */ _interopDefaultCompat(React), debug__default = /* @__PURE__ */ _interopDefaultCompat(debug$l), uniq__default = /* @__PURE__ */ _interopDefaultCompat(uniq), flatten__default = /* @__PURE__ */ _interopDefaultCompat(flatten), isPlainObject__default = /* @__PURE__ */ _interopDefaultCompat(isPlainObject), get__default = /* @__PURE__ */ _interopDefaultCompat(get), isUndefined__default = /* @__PURE__ */ _interopDefaultCompat(isUndefined), omitBy__default = /* @__PURE__ */ _interopDefaultCompat(omitBy), getRandomValues__default = /* @__PURE__ */ _interopDefaultCompat(getRandomValues);
|
|
19
19
|
function createEditorSchema(portableTextType) {
|
|
20
20
|
var _a, _b, _c;
|
|
21
21
|
if (!portableTextType)
|
|
@@ -155,7 +155,7 @@ function compileSchemaDefinition(definition) {
|
|
|
155
155
|
});
|
|
156
156
|
}
|
|
157
157
|
const rootName = "sanity-pte:";
|
|
158
|
-
|
|
158
|
+
debug__default.default(rootName);
|
|
159
159
|
function debugWithName(name) {
|
|
160
160
|
const namespace = `${rootName}${name}`;
|
|
161
161
|
return debug__default.default && debug__default.default.enabled(namespace) ? debug__default.default(namespace) : debug__default.default(rootName);
|
|
@@ -2315,24 +2315,20 @@ const syncValueCallback = ({
|
|
|
2315
2315
|
event
|
|
2316
2316
|
}) => (xstate.assertEvent(event, "done syncing"), event.value)
|
|
2317
2317
|
}),
|
|
2318
|
-
"emit done syncing": xstate.emit(
|
|
2319
|
-
|
|
2320
|
-
})
|
|
2318
|
+
"emit done syncing initial value": xstate.emit({
|
|
2319
|
+
type: "done syncing initial value"
|
|
2320
|
+
})
|
|
2321
2321
|
},
|
|
2322
2322
|
guards: {
|
|
2323
|
-
"
|
|
2323
|
+
"initial value synced": ({
|
|
2324
2324
|
context
|
|
2325
|
-
}) => context.
|
|
2326
|
-
"is
|
|
2327
|
-
context
|
|
2328
|
-
}) => context.isProcessingLocalChanges,
|
|
2329
|
-
"is processing remote changes": ({
|
|
2325
|
+
}) => context.initialValueSynced,
|
|
2326
|
+
"is busy": ({
|
|
2330
2327
|
context
|
|
2331
2328
|
}) => {
|
|
2332
2329
|
var _a;
|
|
2333
|
-
return (_a = isChangingRemotely(context.slateEditor)) != null ? _a : !1;
|
|
2330
|
+
return !context.readOnly && (context.isProcessingLocalChanges || ((_a = isChangingRemotely(context.slateEditor)) != null ? _a : !1));
|
|
2334
2331
|
},
|
|
2335
|
-
"is busy": xstate.and([xstate.not("is readOnly"), xstate.or(["is processing local changes", "is processing remote changes"])]),
|
|
2336
2332
|
"value changed while syncing": ({
|
|
2337
2333
|
context,
|
|
2338
2334
|
event
|
|
@@ -2358,7 +2354,6 @@ const syncValueCallback = ({
|
|
|
2358
2354
|
pendingValue: void 0,
|
|
2359
2355
|
previousValue: void 0
|
|
2360
2356
|
}),
|
|
2361
|
-
initial: "idle",
|
|
2362
2357
|
on: {
|
|
2363
2358
|
"has pending patches": {
|
|
2364
2359
|
actions: xstate.assign({
|
|
@@ -2374,94 +2369,105 @@ const syncValueCallback = ({
|
|
|
2374
2369
|
actions: ["assign readOnly"]
|
|
2375
2370
|
}
|
|
2376
2371
|
},
|
|
2372
|
+
type: "parallel",
|
|
2377
2373
|
states: {
|
|
2378
|
-
|
|
2379
|
-
|
|
2380
|
-
|
|
2381
|
-
|
|
2382
|
-
|
|
2383
|
-
|
|
2384
|
-
|
|
2385
|
-
|
|
2386
|
-
|
|
2387
|
-
|
|
2388
|
-
|
|
2389
|
-
|
|
2390
|
-
busy: {
|
|
2391
|
-
after: {
|
|
2392
|
-
1e3: {
|
|
2393
|
-
target: "syncing"
|
|
2374
|
+
"setting up": {
|
|
2375
|
+
initial: "syncing initial value",
|
|
2376
|
+
states: {
|
|
2377
|
+
"syncing initial value": {
|
|
2378
|
+
always: {
|
|
2379
|
+
guard: "initial value synced",
|
|
2380
|
+
target: "done syncing initial value"
|
|
2381
|
+
}
|
|
2382
|
+
},
|
|
2383
|
+
"done syncing initial value": {
|
|
2384
|
+
entry: ["emit done syncing initial value"],
|
|
2385
|
+
type: "final"
|
|
2394
2386
|
}
|
|
2395
|
-
},
|
|
2396
|
-
on: {
|
|
2397
|
-
"update value": [{
|
|
2398
|
-
guard: "is busy",
|
|
2399
|
-
actions: ["assign pending value"],
|
|
2400
|
-
reenter: !0
|
|
2401
|
-
}, {
|
|
2402
|
-
target: "syncing",
|
|
2403
|
-
actions: ["assign pending value"]
|
|
2404
|
-
}]
|
|
2405
2387
|
}
|
|
2406
2388
|
},
|
|
2407
2389
|
syncing: {
|
|
2408
|
-
|
|
2409
|
-
|
|
2410
|
-
|
|
2411
|
-
|
|
2412
|
-
|
|
2413
|
-
|
|
2414
|
-
|
|
2415
|
-
|
|
2416
|
-
|
|
2417
|
-
|
|
2418
|
-
|
|
2419
|
-
|
|
2420
|
-
|
|
2421
|
-
},
|
|
2422
|
-
slateEditor: context.slateEditor,
|
|
2423
|
-
streamBlocks: !context.initialValueSynced,
|
|
2424
|
-
value: (_a = context.pendingValue) != null ? _a : void 0
|
|
2425
|
-
};
|
|
2426
|
-
}
|
|
2427
|
-
},
|
|
2428
|
-
always: {
|
|
2429
|
-
guard: "pending value equals previous value",
|
|
2430
|
-
actions: [xstate.emit(({
|
|
2431
|
-
context
|
|
2432
|
-
}) => ({
|
|
2433
|
-
type: "done syncing",
|
|
2434
|
-
value: context.previousValue
|
|
2435
|
-
}))],
|
|
2436
|
-
target: "idle"
|
|
2437
|
-
},
|
|
2438
|
-
on: {
|
|
2439
|
-
"update value": {
|
|
2440
|
-
actions: ["assign pending value"]
|
|
2441
|
-
},
|
|
2442
|
-
patch: {
|
|
2443
|
-
actions: [xstate.emit(({
|
|
2444
|
-
event
|
|
2445
|
-
}) => event)]
|
|
2446
|
-
},
|
|
2447
|
-
"invalid value": {
|
|
2448
|
-
actions: [xstate.emit(({
|
|
2449
|
-
event
|
|
2450
|
-
}) => event)]
|
|
2390
|
+
initial: "idle",
|
|
2391
|
+
states: {
|
|
2392
|
+
idle: {
|
|
2393
|
+
on: {
|
|
2394
|
+
"update value": [{
|
|
2395
|
+
guard: "is busy",
|
|
2396
|
+
target: "busy",
|
|
2397
|
+
actions: ["assign pending value"]
|
|
2398
|
+
}, {
|
|
2399
|
+
target: "syncing",
|
|
2400
|
+
actions: ["assign pending value"]
|
|
2401
|
+
}]
|
|
2402
|
+
}
|
|
2451
2403
|
},
|
|
2452
|
-
|
|
2453
|
-
|
|
2454
|
-
|
|
2455
|
-
|
|
2404
|
+
busy: {
|
|
2405
|
+
after: {
|
|
2406
|
+
1e3: [{
|
|
2407
|
+
guard: "is busy",
|
|
2408
|
+
reenter: !0
|
|
2409
|
+
}, {
|
|
2410
|
+
target: "syncing"
|
|
2411
|
+
}]
|
|
2412
|
+
},
|
|
2413
|
+
on: {
|
|
2414
|
+
"update value": [{
|
|
2415
|
+
actions: ["assign pending value"]
|
|
2416
|
+
}]
|
|
2417
|
+
}
|
|
2456
2418
|
},
|
|
2457
|
-
|
|
2458
|
-
|
|
2459
|
-
|
|
2460
|
-
|
|
2461
|
-
|
|
2462
|
-
|
|
2463
|
-
|
|
2464
|
-
|
|
2419
|
+
syncing: {
|
|
2420
|
+
always: {
|
|
2421
|
+
guard: "pending value equals previous value",
|
|
2422
|
+
target: "idle",
|
|
2423
|
+
actions: ["clear pending value", "assign initial value synced"]
|
|
2424
|
+
},
|
|
2425
|
+
invoke: {
|
|
2426
|
+
src: "sync value",
|
|
2427
|
+
id: "sync value",
|
|
2428
|
+
input: ({
|
|
2429
|
+
context
|
|
2430
|
+
}) => ({
|
|
2431
|
+
context: {
|
|
2432
|
+
keyGenerator: context.keyGenerator,
|
|
2433
|
+
previousValue: context.previousValue,
|
|
2434
|
+
readOnly: context.readOnly,
|
|
2435
|
+
schema: context.schema
|
|
2436
|
+
},
|
|
2437
|
+
slateEditor: context.slateEditor,
|
|
2438
|
+
streamBlocks: !context.initialValueSynced,
|
|
2439
|
+
value: context.pendingValue
|
|
2440
|
+
})
|
|
2441
|
+
},
|
|
2442
|
+
on: {
|
|
2443
|
+
"update value": {
|
|
2444
|
+
actions: ["assign pending value"]
|
|
2445
|
+
},
|
|
2446
|
+
patch: {
|
|
2447
|
+
actions: [xstate.emit(({
|
|
2448
|
+
event
|
|
2449
|
+
}) => event)]
|
|
2450
|
+
},
|
|
2451
|
+
"invalid value": {
|
|
2452
|
+
actions: [xstate.emit(({
|
|
2453
|
+
event
|
|
2454
|
+
}) => event)]
|
|
2455
|
+
},
|
|
2456
|
+
"value changed": {
|
|
2457
|
+
actions: [xstate.emit(({
|
|
2458
|
+
event
|
|
2459
|
+
}) => event)]
|
|
2460
|
+
},
|
|
2461
|
+
"done syncing": [{
|
|
2462
|
+
guard: "value changed while syncing",
|
|
2463
|
+
actions: ["assign previous value", "assign initial value synced"],
|
|
2464
|
+
reenter: !0
|
|
2465
|
+
}, {
|
|
2466
|
+
target: "idle",
|
|
2467
|
+
actions: ["clear pending value", "assign previous value", "assign initial value synced"]
|
|
2468
|
+
}]
|
|
2469
|
+
}
|
|
2470
|
+
}
|
|
2465
2471
|
}
|
|
2466
2472
|
}
|
|
2467
2473
|
}
|
|
@@ -5704,7 +5710,7 @@ function performAction({
|
|
|
5704
5710
|
context,
|
|
5705
5711
|
action
|
|
5706
5712
|
}) {
|
|
5707
|
-
switch (
|
|
5713
|
+
switch (action.type) {
|
|
5708
5714
|
case "delete.block": {
|
|
5709
5715
|
behaviorActionImplementations["delete.block"]({
|
|
5710
5716
|
context,
|
|
@@ -6043,7 +6049,7 @@ const editorMachine = xstate.setup({
|
|
|
6043
6049
|
enqueue
|
|
6044
6050
|
}) => {
|
|
6045
6051
|
var _a;
|
|
6046
|
-
xstate.assertEvent(event, ["behavior event"])
|
|
6052
|
+
xstate.assertEvent(event, ["behavior event"]);
|
|
6047
6053
|
const defaultAction = event.behaviorEvent.type === "copy" || event.behaviorEvent.type === "key.down" || event.behaviorEvent.type === "key.up" || event.behaviorEvent.type === "paste" ? void 0 : __spreadProps$4(__spreadValues$4({}, event.behaviorEvent), {
|
|
6048
6054
|
editor: event.editor
|
|
6049
6055
|
}), eventBehaviors = context.behaviors.filter((behavior) => behavior.on === event.behaviorEvent.type);
|
|
@@ -6231,7 +6237,7 @@ const editorMachine = xstate.setup({
|
|
|
6231
6237
|
states: {
|
|
6232
6238
|
"determine initial edit mode": {
|
|
6233
6239
|
on: {
|
|
6234
|
-
"done syncing": [{
|
|
6240
|
+
"done syncing initial value": [{
|
|
6235
6241
|
target: "#editor.edit mode.read only.read only",
|
|
6236
6242
|
guard: ({
|
|
6237
6243
|
context
|
|
@@ -6327,7 +6333,7 @@ const editorMachine = xstate.setup({
|
|
|
6327
6333
|
mutation: {
|
|
6328
6334
|
actions: "defer event"
|
|
6329
6335
|
},
|
|
6330
|
-
"done syncing": {
|
|
6336
|
+
"done syncing initial value": {
|
|
6331
6337
|
target: "pristine"
|
|
6332
6338
|
}
|
|
6333
6339
|
}
|