@portabletext/editor 1.55.16 → 1.57.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +19 -0
- package/lib/behaviors/index.d.cts +1 -2
- package/lib/behaviors/index.d.ts +1 -2
- package/lib/index.cjs +175 -9
- package/lib/index.cjs.map +1 -1
- package/lib/index.d.cts +1 -2
- package/lib/index.d.ts +1 -2
- package/lib/index.js +175 -9
- package/lib/index.js.map +1 -1
- package/lib/plugins/index.d.cts +1 -2
- package/lib/plugins/index.d.ts +1 -2
- package/lib/selectors/index.d.cts +1 -2
- package/lib/selectors/index.d.ts +1 -2
- package/lib/utils/index.d.cts +1 -2
- package/lib/utils/index.d.ts +1 -2
- package/package.json +6 -6
- package/src/behaviors/behavior.core.lists.ts +317 -1
- package/src/behaviors/behavior.core.ts +5 -0
- package/src/editor/editor-schema-definition.ts +1 -2
- package/src/editor/editor-schema.ts +6 -0
- package/src/internal-utils/terse-pt.test.ts +10 -0
- package/src/operations/behavior.operation.insert.block.ts +12 -1
package/README.md
CHANGED
|
@@ -372,3 +372,22 @@ In order to provide a robust and consistent end-user experience, the editor is b
|
|
|
372
372
|
4. `cd` into the `sanity` package and run `pnpm link <relative path to the **editor** package in this repo>`
|
|
373
373
|
|
|
374
374
|
Now, you should be able to run `pnpm dev:test-studio` in the `sanity` repo to test Studio with a locally running Portable Text Editor.
|
|
375
|
+
|
|
376
|
+
## Other Libraries
|
|
377
|
+
|
|
378
|
+
This monorepo also contains additional libraries that can be used with the Portable Text Editor:
|
|
379
|
+
|
|
380
|
+
### `@portabletext/keyboard-shortcuts`
|
|
381
|
+
|
|
382
|
+
> A TypeScript library for creating platform-aware keyboard shortcuts with automatic detection of Apple vs non-Apple platforms.
|
|
383
|
+
|
|
384
|
+
- 💻 [./packages/keyboard-shortcuts](./packages/keyboard-shortcuts/)
|
|
385
|
+
- 📦 [@portabletext/keyboard-shortcuts](https://www.npmjs.com/package/@portabletext/keyboard-shortcuts)
|
|
386
|
+
|
|
387
|
+
### `@portabletext/toolbar`
|
|
388
|
+
|
|
389
|
+
> Powered by [Behaviors](https://www.portabletext.org/concepts/behavior/) and [State Machines](https://stately.ai/docs/xstate), `@portabletext/toolbar` is a collection of robust React hooks for building toolbars and related UI components
|
|
390
|
+
> for the Portable Text editor.
|
|
391
|
+
|
|
392
|
+
- 💻 [./packages/toolbar](./packages/toolbar/)
|
|
393
|
+
- 📦 [@portabletext/toolbar](https://www.npmjs.com/package/@portabletext/toolbar)
|
|
@@ -653,8 +653,7 @@ declare type ExtractNamespace<TType extends string> =
|
|
|
653
653
|
/**
|
|
654
654
|
* @public
|
|
655
655
|
*/
|
|
656
|
-
declare type FieldDefinition = {
|
|
657
|
-
name: string
|
|
656
|
+
declare type FieldDefinition = BaseDefinition & {
|
|
658
657
|
type: 'string' | 'number' | 'boolean' | 'array' | 'object'
|
|
659
658
|
}
|
|
660
659
|
|
package/lib/behaviors/index.d.ts
CHANGED
|
@@ -653,8 +653,7 @@ declare type ExtractNamespace<TType extends string> =
|
|
|
653
653
|
/**
|
|
654
654
|
* @public
|
|
655
655
|
*/
|
|
656
|
-
declare type FieldDefinition = {
|
|
657
|
-
name: string
|
|
656
|
+
declare type FieldDefinition = BaseDefinition & {
|
|
658
657
|
type: 'string' | 'number' | 'boolean' | 'array' | 'object'
|
|
659
658
|
}
|
|
660
659
|
|
package/lib/index.cjs
CHANGED
|
@@ -3524,7 +3524,11 @@ function insertBlock({
|
|
|
3524
3524
|
}), select === "start" ? slate.Transforms.select(editor, selectionStartPoint) : select === "end" ? slate.Transforms.select(editor, slate.Editor.end(editor, endBlockPath)) : slate.Transforms.select(editor, currentSelection2);
|
|
3525
3525
|
return;
|
|
3526
3526
|
}
|
|
3527
|
-
if (
|
|
3527
|
+
if (slate.Transforms.setNodes(editor, {
|
|
3528
|
+
markDefs: [...endBlock.markDefs ?? [], ...block.markDefs ?? []]
|
|
3529
|
+
}, {
|
|
3530
|
+
at: endBlockPath
|
|
3531
|
+
}), select === "end") {
|
|
3528
3532
|
slate.Transforms.insertFragment(editor, [block], {
|
|
3529
3533
|
voids: !0
|
|
3530
3534
|
});
|
|
@@ -3540,7 +3544,9 @@ function insertBlock({
|
|
|
3540
3544
|
slate.Transforms.insertNodes(editor, [block], {
|
|
3541
3545
|
at: endBlockPath,
|
|
3542
3546
|
select: !1
|
|
3543
|
-
}), (select === "start" || select === "end") && slate.Transforms.select(editor, slate.Editor.start(editor, endBlockPath)),
|
|
3547
|
+
}), (select === "start" || select === "end") && slate.Transforms.select(editor, slate.Editor.start(editor, endBlockPath)), util_isSelectionCollapsed.isEmptyTextBlock({
|
|
3548
|
+
schema: schema2
|
|
3549
|
+
}, endBlock) && slate.Transforms.removeNodes(editor, {
|
|
3544
3550
|
at: slate.Path.next(endBlockPath)
|
|
3545
3551
|
});
|
|
3546
3552
|
else if (slate.Range.isCollapsed(currentSelection) && slate.Point.equals(selectionEndPoint, endBlockEndPoint2)) {
|
|
@@ -6247,6 +6253,63 @@ const coreDndBehaviors = [
|
|
|
6247
6253
|
},
|
|
6248
6254
|
at: focusTextBlock.path
|
|
6249
6255
|
})]]
|
|
6256
|
+
}), mergeTextIntoListOnDelete = behaviors_index.defineBehavior({
|
|
6257
|
+
on: "delete.forward",
|
|
6258
|
+
guard: ({
|
|
6259
|
+
snapshot
|
|
6260
|
+
}) => {
|
|
6261
|
+
const focusListBlock = selector_isSelectingEntireBlocks.getFocusListBlock(snapshot), nextBlock = selector_isSelectingEntireBlocks.getNextBlock(snapshot);
|
|
6262
|
+
return !focusListBlock || !nextBlock || !util_sliceBlocks.isTextBlock(snapshot.context, nextBlock.node) || !util_isSelectionCollapsed.isEmptyTextBlock(snapshot.context, focusListBlock.node) ? !1 : {
|
|
6263
|
+
focusListBlock,
|
|
6264
|
+
nextBlock
|
|
6265
|
+
};
|
|
6266
|
+
},
|
|
6267
|
+
actions: [(_, {
|
|
6268
|
+
nextBlock
|
|
6269
|
+
}) => [behaviors_index.raise({
|
|
6270
|
+
type: "insert.block",
|
|
6271
|
+
block: nextBlock.node,
|
|
6272
|
+
placement: "auto",
|
|
6273
|
+
select: "start"
|
|
6274
|
+
}), behaviors_index.raise({
|
|
6275
|
+
type: "delete.block",
|
|
6276
|
+
at: nextBlock.path
|
|
6277
|
+
})]]
|
|
6278
|
+
}), mergeTextIntoListOnBackspace = behaviors_index.defineBehavior({
|
|
6279
|
+
on: "delete.backward",
|
|
6280
|
+
guard: ({
|
|
6281
|
+
snapshot
|
|
6282
|
+
}) => {
|
|
6283
|
+
const focusTextBlock = selector_getFocusSpan.getFocusTextBlock(snapshot), previousBlock = selector_isSelectingEntireBlocks.getPreviousBlock(snapshot);
|
|
6284
|
+
if (!focusTextBlock || !previousBlock || !util_sliceBlocks.isListBlock(snapshot.context, previousBlock.node) || !util_isSelectionCollapsed.isEmptyTextBlock(snapshot.context, previousBlock.node))
|
|
6285
|
+
return !1;
|
|
6286
|
+
const previousBlockEndPoint = util_isSelectionCollapsed.getBlockEndPoint({
|
|
6287
|
+
context: snapshot.context,
|
|
6288
|
+
block: previousBlock
|
|
6289
|
+
});
|
|
6290
|
+
return {
|
|
6291
|
+
focusTextBlock,
|
|
6292
|
+
previousBlockEndPoint
|
|
6293
|
+
};
|
|
6294
|
+
},
|
|
6295
|
+
actions: [(_, {
|
|
6296
|
+
focusTextBlock,
|
|
6297
|
+
previousBlockEndPoint
|
|
6298
|
+
}) => [behaviors_index.raise({
|
|
6299
|
+
type: "select",
|
|
6300
|
+
at: {
|
|
6301
|
+
anchor: previousBlockEndPoint,
|
|
6302
|
+
focus: previousBlockEndPoint
|
|
6303
|
+
}
|
|
6304
|
+
}), behaviors_index.raise({
|
|
6305
|
+
type: "insert.block",
|
|
6306
|
+
block: focusTextBlock.node,
|
|
6307
|
+
placement: "auto",
|
|
6308
|
+
select: "start"
|
|
6309
|
+
}), behaviors_index.raise({
|
|
6310
|
+
type: "delete.block",
|
|
6311
|
+
at: focusTextBlock.path
|
|
6312
|
+
})]]
|
|
6250
6313
|
}), clearListOnEnter = behaviors_index.defineBehavior({
|
|
6251
6314
|
on: "insert.break",
|
|
6252
6315
|
guard: ({
|
|
@@ -6314,13 +6377,110 @@ const coreDndBehaviors = [
|
|
|
6314
6377
|
},
|
|
6315
6378
|
at: selectedListBlock.path
|
|
6316
6379
|
}))]
|
|
6380
|
+
}), inheritListLevel = behaviors_index.defineBehavior({
|
|
6381
|
+
on: "insert.blocks",
|
|
6382
|
+
guard: ({
|
|
6383
|
+
snapshot,
|
|
6384
|
+
event
|
|
6385
|
+
}) => {
|
|
6386
|
+
const focusListBlock = selector_isSelectingEntireBlocks.getFocusListBlock(snapshot);
|
|
6387
|
+
if (!focusListBlock)
|
|
6388
|
+
return !1;
|
|
6389
|
+
const firstInsertedBlock = event.blocks.at(0), secondInsertedBlock = event.blocks.at(1), insertedListBlock = util_sliceBlocks.isListBlock(snapshot.context, firstInsertedBlock) ? firstInsertedBlock : util_sliceBlocks.isListBlock(snapshot.context, secondInsertedBlock) ? secondInsertedBlock : void 0;
|
|
6390
|
+
if (!insertedListBlock)
|
|
6391
|
+
return !1;
|
|
6392
|
+
const levelDifference = focusListBlock.node.level - insertedListBlock.level;
|
|
6393
|
+
return levelDifference === 0 ? !1 : {
|
|
6394
|
+
levelDifference,
|
|
6395
|
+
insertedListBlock
|
|
6396
|
+
};
|
|
6397
|
+
},
|
|
6398
|
+
actions: [({
|
|
6399
|
+
snapshot,
|
|
6400
|
+
event
|
|
6401
|
+
}, {
|
|
6402
|
+
levelDifference,
|
|
6403
|
+
insertedListBlock
|
|
6404
|
+
}) => {
|
|
6405
|
+
let adjustLevel = !0, listStartBlockFound = !1;
|
|
6406
|
+
return [behaviors_index.raise({
|
|
6407
|
+
...event,
|
|
6408
|
+
blocks: event.blocks.map((block) => (block._key === insertedListBlock._key && (listStartBlockFound = !0), adjustLevel ? listStartBlockFound && adjustLevel && util_sliceBlocks.isListBlock(snapshot.context, block) ? {
|
|
6409
|
+
...block,
|
|
6410
|
+
level: Math.min(MAX_LIST_LEVEL, Math.max(1, block.level + levelDifference))
|
|
6411
|
+
} : (listStartBlockFound && (adjustLevel = !1), block) : block))
|
|
6412
|
+
})];
|
|
6413
|
+
}]
|
|
6414
|
+
}), inheritListItem = behaviors_index.defineBehavior({
|
|
6415
|
+
on: "insert.blocks",
|
|
6416
|
+
guard: ({
|
|
6417
|
+
snapshot,
|
|
6418
|
+
event
|
|
6419
|
+
}) => {
|
|
6420
|
+
const focusListBlock = selector_isSelectingEntireBlocks.getFocusListBlock(snapshot);
|
|
6421
|
+
if (!focusListBlock || util_isSelectionCollapsed.isEmptyTextBlock(snapshot.context, focusListBlock.node))
|
|
6422
|
+
return !1;
|
|
6423
|
+
const firstInsertedBlock = event.blocks.at(0), secondInsertedBlock = event.blocks.at(1), insertedListBlock = util_sliceBlocks.isListBlock(snapshot.context, firstInsertedBlock) ? firstInsertedBlock : util_sliceBlocks.isListBlock(snapshot.context, secondInsertedBlock) ? secondInsertedBlock : void 0;
|
|
6424
|
+
return !insertedListBlock || focusListBlock.node.level !== insertedListBlock.level || focusListBlock.node.listItem === insertedListBlock.listItem ? !1 : {
|
|
6425
|
+
listItem: focusListBlock.node.listItem,
|
|
6426
|
+
insertedListBlock
|
|
6427
|
+
};
|
|
6428
|
+
},
|
|
6429
|
+
actions: [({
|
|
6430
|
+
snapshot,
|
|
6431
|
+
event
|
|
6432
|
+
}, {
|
|
6433
|
+
listItem,
|
|
6434
|
+
insertedListBlock
|
|
6435
|
+
}) => {
|
|
6436
|
+
let adjustListItem = !0, listStartBlockFound = !1;
|
|
6437
|
+
return [behaviors_index.raise({
|
|
6438
|
+
...event,
|
|
6439
|
+
blocks: event.blocks.map((block) => (block._key === insertedListBlock._key && (listStartBlockFound = !0), adjustListItem ? listStartBlockFound && adjustListItem && util_sliceBlocks.isListBlock(snapshot.context, block) ? {
|
|
6440
|
+
...block,
|
|
6441
|
+
listItem: block.level === insertedListBlock.level ? listItem : block.listItem
|
|
6442
|
+
} : (listStartBlockFound && (adjustListItem = !1), block) : block))
|
|
6443
|
+
})];
|
|
6444
|
+
}]
|
|
6445
|
+
}), inheritListProperties = behaviors_index.defineBehavior({
|
|
6446
|
+
on: "insert.block",
|
|
6447
|
+
guard: ({
|
|
6448
|
+
snapshot,
|
|
6449
|
+
event
|
|
6450
|
+
}) => {
|
|
6451
|
+
if (event.placement !== "auto" || event.block._type !== snapshot.context.schema.block.name || event.block.listItem !== void 0)
|
|
6452
|
+
return !1;
|
|
6453
|
+
const focusListBlock = selector_isSelectingEntireBlocks.getFocusListBlock(snapshot);
|
|
6454
|
+
return !focusListBlock || !util_isSelectionCollapsed.isEmptyTextBlock(snapshot.context, focusListBlock.node) ? !1 : {
|
|
6455
|
+
level: focusListBlock.node.level,
|
|
6456
|
+
listItem: focusListBlock.node.listItem
|
|
6457
|
+
};
|
|
6458
|
+
},
|
|
6459
|
+
actions: [({
|
|
6460
|
+
event
|
|
6461
|
+
}, {
|
|
6462
|
+
level,
|
|
6463
|
+
listItem
|
|
6464
|
+
}) => [behaviors_index.raise({
|
|
6465
|
+
...event,
|
|
6466
|
+
block: {
|
|
6467
|
+
...event.block,
|
|
6468
|
+
level,
|
|
6469
|
+
listItem
|
|
6470
|
+
}
|
|
6471
|
+
})]]
|
|
6317
6472
|
}), coreListBehaviors = {
|
|
6318
6473
|
clearListOnBackspace,
|
|
6319
6474
|
unindentListOnBackspace,
|
|
6475
|
+
mergeTextIntoListOnDelete,
|
|
6476
|
+
mergeTextIntoListOnBackspace,
|
|
6320
6477
|
clearListOnEnter,
|
|
6321
6478
|
indentListOnTab,
|
|
6322
|
-
unindentListOnShiftTab
|
|
6323
|
-
|
|
6479
|
+
unindentListOnShiftTab,
|
|
6480
|
+
inheritListLevel,
|
|
6481
|
+
inheritListItem,
|
|
6482
|
+
inheritListProperties
|
|
6483
|
+
}, coreBehaviorsConfig = [coreAnnotationBehaviors.addAnnotationOnCollapsedSelection, coreDecoratorBehaviors.strongShortcut, coreDecoratorBehaviors.emShortcut, coreDecoratorBehaviors.underlineShortcut, coreDecoratorBehaviors.codeShortcut, ...coreDndBehaviors, coreBlockObjectBehaviors.clickingAboveLonelyBlockObject, coreBlockObjectBehaviors.clickingBelowLonelyBlockObject, coreBlockObjectBehaviors.arrowDownOnLonelyBlockObject, coreBlockObjectBehaviors.arrowUpOnLonelyBlockObject, coreBlockObjectBehaviors.breakingBlockObject, coreBlockObjectBehaviors.deletingEmptyTextBlockAfterBlockObject, coreBlockObjectBehaviors.deletingEmptyTextBlockBeforeBlockObject, coreListBehaviors.clearListOnBackspace, coreListBehaviors.unindentListOnBackspace, coreListBehaviors.mergeTextIntoListOnDelete, coreListBehaviors.mergeTextIntoListOnBackspace, coreListBehaviors.clearListOnEnter, coreListBehaviors.indentListOnTab, coreListBehaviors.unindentListOnShiftTab, coreListBehaviors.inheritListLevel, coreListBehaviors.inheritListItem, coreListBehaviors.inheritListProperties, coreInsertBreakBehaviors.breakingAtTheEndOfTextBlock, coreInsertBreakBehaviors.breakingAtTheStartOfTextBlock, coreInsertBreakBehaviors.breakingEntireDocument, coreInsertBreakBehaviors.breakingEntireBlocks, coreInsertBreakBehaviors.breakingInlineObject].map((behavior) => ({
|
|
6324
6484
|
behavior,
|
|
6325
6485
|
priority: corePriority
|
|
6326
6486
|
})), abstractAnnotationBehaviors = [behaviors_index.defineBehavior({
|
|
@@ -8169,7 +8329,8 @@ function legacySchemaToEditorSchema(schema2) {
|
|
|
8169
8329
|
name: annotation.name,
|
|
8170
8330
|
fields: annotation.fields.map((field) => ({
|
|
8171
8331
|
name: field.name,
|
|
8172
|
-
type: field.type.jsonType
|
|
8332
|
+
type: field.type.jsonType,
|
|
8333
|
+
title: field.type.title
|
|
8173
8334
|
})),
|
|
8174
8335
|
title: annotation.title
|
|
8175
8336
|
})),
|
|
@@ -8180,7 +8341,8 @@ function legacySchemaToEditorSchema(schema2) {
|
|
|
8180
8341
|
name: blockObject.name,
|
|
8181
8342
|
fields: blockObject.fields.map((field) => ({
|
|
8182
8343
|
name: field.name,
|
|
8183
|
-
type: field.type.jsonType
|
|
8344
|
+
type: field.type.jsonType,
|
|
8345
|
+
title: field.type.title
|
|
8184
8346
|
})),
|
|
8185
8347
|
title: blockObject.title
|
|
8186
8348
|
})),
|
|
@@ -8193,7 +8355,8 @@ function legacySchemaToEditorSchema(schema2) {
|
|
|
8193
8355
|
name: inlineObject.name,
|
|
8194
8356
|
fields: inlineObject.fields.map((field) => ({
|
|
8195
8357
|
name: field.name,
|
|
8196
|
-
type: field.type.jsonType
|
|
8358
|
+
type: field.type.jsonType,
|
|
8359
|
+
title: field.type.title
|
|
8197
8360
|
})),
|
|
8198
8361
|
title: inlineObject.title
|
|
8199
8362
|
})),
|
|
@@ -8224,7 +8387,8 @@ function compileSchemaDefinitionToLegacySchema(definition) {
|
|
|
8224
8387
|
) : blockObject.title,
|
|
8225
8388
|
fields: blockObject.fields?.map((field) => ({
|
|
8226
8389
|
name: field.name,
|
|
8227
|
-
type: field.type
|
|
8390
|
+
type: field.type,
|
|
8391
|
+
title: field.title ?? startCase__default.default(field.name)
|
|
8228
8392
|
})) ?? []
|
|
8229
8393
|
})) ?? [], inlineObjects = definition?.inlineObjects?.map((inlineObject) => types.defineType({
|
|
8230
8394
|
type: "object",
|
|
@@ -8237,7 +8401,8 @@ function compileSchemaDefinitionToLegacySchema(definition) {
|
|
|
8237
8401
|
) : inlineObject.title,
|
|
8238
8402
|
fields: inlineObject.fields?.map((field) => ({
|
|
8239
8403
|
name: field.name,
|
|
8240
|
-
type: field.type
|
|
8404
|
+
type: field.type,
|
|
8405
|
+
title: field.title ?? startCase__default.default(field.name)
|
|
8241
8406
|
})) ?? []
|
|
8242
8407
|
})) ?? [], portableTextSchema = types.defineField({
|
|
8243
8408
|
type: "array",
|
|
@@ -8261,6 +8426,7 @@ function compileSchemaDefinitionToLegacySchema(definition) {
|
|
|
8261
8426
|
title: annotation.title,
|
|
8262
8427
|
fields: annotation.fields?.map((field) => ({
|
|
8263
8428
|
name: field.name,
|
|
8429
|
+
title: field.title ?? startCase__default.default(field.name),
|
|
8264
8430
|
type: field.type
|
|
8265
8431
|
})) ?? []
|
|
8266
8432
|
})) ?? []
|