@portabletext/editor 1.0.18 → 1.1.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.
Files changed (75) hide show
  1. package/lib/index.d.mts +140 -66
  2. package/lib/index.d.ts +140 -66
  3. package/lib/index.esm.js +1164 -410
  4. package/lib/index.esm.js.map +1 -1
  5. package/lib/index.js +1164 -410
  6. package/lib/index.js.map +1 -1
  7. package/lib/index.mjs +1164 -410
  8. package/lib/index.mjs.map +1 -1
  9. package/package.json +8 -4
  10. package/src/editor/Editable.tsx +107 -36
  11. package/src/editor/PortableTextEditor.tsx +47 -12
  12. package/src/editor/__tests__/PortableTextEditor.test.tsx +42 -15
  13. package/src/editor/__tests__/PortableTextEditorTester.tsx +50 -38
  14. package/src/editor/__tests__/RangeDecorations.test.tsx +0 -1
  15. package/src/editor/__tests__/handleClick.test.tsx +28 -9
  16. package/src/editor/__tests__/insert-block.test.tsx +22 -6
  17. package/src/editor/__tests__/pteWarningsSelfSolving.test.tsx +30 -62
  18. package/src/editor/__tests__/utils.ts +10 -3
  19. package/src/editor/components/DraggableBlock.tsx +36 -13
  20. package/src/editor/components/Element.tsx +59 -17
  21. package/src/editor/components/Leaf.tsx +106 -68
  22. package/src/editor/components/SlateContainer.tsx +12 -5
  23. package/src/editor/components/Synchronizer.tsx +5 -2
  24. package/src/editor/hooks/usePortableTextEditor.ts +2 -2
  25. package/src/editor/hooks/usePortableTextEditorSelection.tsx +9 -3
  26. package/src/editor/hooks/useSyncValue.test.tsx +9 -4
  27. package/src/editor/hooks/useSyncValue.ts +199 -130
  28. package/src/editor/nodes/DefaultAnnotation.tsx +6 -3
  29. package/src/editor/plugins/__tests__/createWithInsertData.test.tsx +25 -7
  30. package/src/editor/plugins/__tests__/withEditableAPIDelete.test.tsx +26 -9
  31. package/src/editor/plugins/__tests__/withEditableAPIGetFragment.test.tsx +15 -5
  32. package/src/editor/plugins/__tests__/withEditableAPIInsert.test.tsx +60 -19
  33. package/src/editor/plugins/__tests__/withEditableAPISelectionsOverlapping.test.tsx +4 -2
  34. package/src/editor/plugins/__tests__/withPortableTextLists.test.tsx +4 -2
  35. package/src/editor/plugins/__tests__/withPortableTextMarkModel.test.tsx +61 -550
  36. package/src/editor/plugins/__tests__/withPortableTextSelections.test.tsx +6 -3
  37. package/src/editor/plugins/__tests__/withUndoRedo.test.tsx +30 -13
  38. package/src/editor/plugins/createWithEditableAPI.ts +354 -115
  39. package/src/editor/plugins/createWithHotKeys.ts +41 -121
  40. package/src/editor/plugins/createWithInsertBreak.ts +166 -27
  41. package/src/editor/plugins/createWithInsertData.ts +60 -23
  42. package/src/editor/plugins/createWithMaxBlocks.ts +5 -2
  43. package/src/editor/plugins/createWithObjectKeys.ts +7 -3
  44. package/src/editor/plugins/createWithPatches.ts +60 -16
  45. package/src/editor/plugins/createWithPlaceholderBlock.ts +7 -3
  46. package/src/editor/plugins/createWithPortableTextBlockStyle.ts +17 -7
  47. package/src/editor/plugins/createWithPortableTextLists.ts +21 -8
  48. package/src/editor/plugins/createWithPortableTextMarkModel.ts +301 -155
  49. package/src/editor/plugins/createWithPortableTextSelections.ts +4 -2
  50. package/src/editor/plugins/createWithSchemaTypes.ts +25 -9
  51. package/src/editor/plugins/createWithUndoRedo.ts +107 -24
  52. package/src/editor/plugins/createWithUtils.ts +32 -10
  53. package/src/editor/plugins/index.ts +31 -10
  54. package/src/types/editor.ts +44 -15
  55. package/src/types/options.ts +4 -2
  56. package/src/types/slate.ts +2 -2
  57. package/src/utils/__tests__/dmpToOperations.test.ts +38 -13
  58. package/src/utils/__tests__/operationToPatches.test.ts +3 -2
  59. package/src/utils/__tests__/patchToOperations.test.ts +15 -4
  60. package/src/utils/__tests__/ranges.test.ts +8 -3
  61. package/src/utils/__tests__/valueNormalization.test.tsx +12 -4
  62. package/src/utils/__tests__/values.test.ts +0 -1
  63. package/src/utils/applyPatch.ts +71 -20
  64. package/src/utils/getPortableTextMemberSchemaTypes.ts +30 -15
  65. package/src/utils/operationToPatches.ts +126 -43
  66. package/src/utils/paths.ts +24 -7
  67. package/src/utils/ranges.ts +12 -5
  68. package/src/utils/selection.ts +19 -7
  69. package/src/utils/validateValue.ts +118 -45
  70. package/src/utils/values.ts +31 -10
  71. package/src/utils/weakMaps.ts +18 -8
  72. package/src/utils/withChanges.ts +4 -2
  73. package/src/editor/plugins/__tests__/withHotkeys.test.tsx +0 -212
  74. package/src/editor/plugins/__tests__/withInsertBreak.test.tsx +0 -220
  75. package/src/editor/plugins/__tests__/withPlaceholderBlock.test.tsx +0 -133
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@portabletext/editor",
3
- "version": "1.0.18",
3
+ "version": "1.1.0",
4
4
  "description": "Portable Text Editor made in React",
5
5
  "keywords": [
6
6
  "sanity",
@@ -50,6 +50,9 @@
50
50
  "slate-react": "0.108.0"
51
51
  },
52
52
  "devDependencies": {
53
+ "@cucumber/cucumber-expressions": "^17.1.0",
54
+ "@cucumber/gherkin": "^29.0.0",
55
+ "@cucumber/messages": "^26.0.0",
53
56
  "@jest/globals": "^29.7.0",
54
57
  "@jest/types": "^29.6.3",
55
58
  "@playwright/test": "1.46.1",
@@ -100,6 +103,7 @@
100
103
  "react-dom": "^18.3.1",
101
104
  "rxjs": "^7.8.1",
102
105
  "styled-components": "^6.1.12",
106
+ "ts-node": "^10.9.2",
103
107
  "tsx": "^4.17.0",
104
108
  "typescript": "5.5.4",
105
109
  "vite": "^5.4.2"
@@ -122,14 +126,14 @@
122
126
  "scripts": {
123
127
  "build": "pkg-utils build --strict --check --clean",
124
128
  "check:lint": "eslint .",
125
- "check:types": "tsc --project tsconfig.lib.json",
129
+ "check:types": "tsc",
126
130
  "clean": "del .turbo && del lib && del node_modules",
127
131
  "dev": "pkg-utils watch",
128
132
  "dev:e2e-server": "cd ./e2e-tests/ && tsx serve",
129
133
  "lint:fix": "eslint . --fix",
130
134
  "test": "jest",
131
- "test:e2e": "jest --config=e2e-tests/e2e.config.cjs",
132
- "test:e2e:watch": "jest --config=e2e-tests/e2e.config.cjs --watch",
135
+ "test:e2e": "jest --config=e2e-tests/e2e.config.ts",
136
+ "test:e2e:watch": "jest --config=e2e-tests/e2e.config.ts --watch",
133
137
  "test:watch": "jest --watch"
134
138
  }
135
139
  }
@@ -1,41 +1,40 @@
1
1
  import {type PortableTextBlock} from '@sanity/types'
2
2
  import {isEqual, noop} from 'lodash'
3
3
  import {
4
+ forwardRef,
5
+ useCallback,
6
+ useEffect,
7
+ useImperativeHandle,
8
+ useMemo,
9
+ useRef,
10
+ useState,
4
11
  type ClipboardEvent,
5
12
  type CSSProperties,
6
13
  type FocusEventHandler,
7
14
  type ForwardedRef,
8
- forwardRef,
9
15
  type HTMLProps,
10
16
  type KeyboardEvent,
11
17
  type MutableRefObject,
12
18
  type TextareaHTMLAttributes,
13
- useCallback,
14
- useEffect,
15
- useImperativeHandle,
16
- useMemo,
17
- useRef,
18
- useState,
19
19
  } from 'react'
20
20
  import {
21
- type BaseRange,
22
21
  Editor,
23
22
  Node,
24
- type NodeEntry,
25
- type Operation,
26
23
  Path,
27
24
  Range as SlateRange,
28
- type Text,
29
25
  Transforms,
26
+ type BaseRange,
27
+ type NodeEntry,
28
+ type Operation,
29
+ type Text,
30
30
  } from 'slate'
31
31
  import {
32
- Editable as SlateEditable,
33
32
  ReactEditor,
33
+ Editable as SlateEditable,
34
+ useSlate,
34
35
  type RenderElementProps,
35
36
  type RenderLeafProps,
36
- useSlate,
37
37
  } from 'slate-react'
38
-
39
38
  import {
40
39
  type EditorChange,
41
40
  type EditorSelection,
@@ -54,9 +53,17 @@ import {
54
53
  import {type HotkeyOptions} from '../types/options'
55
54
  import {type SlateTextBlock, type VoidElement} from '../types/slate'
56
55
  import {debugWithName} from '../utils/debug'
57
- import {moveRangeByOperation, toPortableTextRange, toSlateRange} from '../utils/ranges'
56
+ import {
57
+ moveRangeByOperation,
58
+ toPortableTextRange,
59
+ toSlateRange,
60
+ } from '../utils/ranges'
58
61
  import {normalizeSelection} from '../utils/selection'
59
- import {fromSlateValue, isEqualToEmptyEditor, toSlateValue} from '../utils/values'
62
+ import {
63
+ fromSlateValue,
64
+ isEqualToEmptyEditor,
65
+ toSlateValue,
66
+ } from '../utils/values'
60
67
  import {Element} from './components/Element'
61
68
  import {Leaf} from './components/Leaf'
62
69
  import {usePortableTextEditor} from './hooks/usePortableTextEditor'
@@ -138,12 +145,19 @@ export const PortableTextEditable = forwardRef(function PortableTextEditable(
138
145
  const readOnly = usePortableTextEditorReadOnlyStatus()
139
146
  const keyGenerator = usePortableTextEditorKeyGenerator()
140
147
  const ref = useRef<HTMLDivElement | null>(null)
141
- const [editableElement, setEditableElement] = useState<HTMLDivElement | null>(null)
148
+ const [editableElement, setEditableElement] = useState<HTMLDivElement | null>(
149
+ null,
150
+ )
142
151
  const [hasInvalidValue, setHasInvalidValue] = useState(false)
143
- const [rangeDecorationState, setRangeDecorationsState] = useState<BaseRangeWithDecoration[]>([])
152
+ const [rangeDecorationState, setRangeDecorationsState] = useState<
153
+ BaseRangeWithDecoration[]
154
+ >([])
144
155
 
145
156
  // Forward ref to parent component
146
- useImperativeHandle<HTMLDivElement | null, HTMLDivElement | null>(forwardedRef, () => ref.current)
157
+ useImperativeHandle<HTMLDivElement | null, HTMLDivElement | null>(
158
+ forwardedRef,
159
+ () => ref.current,
160
+ )
147
161
 
148
162
  const rangeDecorationsRef = useRef(rangeDecorations)
149
163
 
@@ -187,7 +201,15 @@ export const PortableTextEditable = forwardRef(function PortableTextEditable(
187
201
  spellCheck={spellCheck}
188
202
  />
189
203
  ),
190
- [schemaTypes, spellCheck, readOnly, renderBlock, renderChild, renderListItem, renderStyle],
204
+ [
205
+ schemaTypes,
206
+ spellCheck,
207
+ readOnly,
208
+ renderBlock,
209
+ renderChild,
210
+ renderListItem,
211
+ renderStyle,
212
+ ],
191
213
  )
192
214
 
193
215
  const renderLeaf = useCallback(
@@ -207,7 +229,11 @@ export const PortableTextEditable = forwardRef(function PortableTextEditable(
207
229
  readOnly={readOnly}
208
230
  />
209
231
  )
210
- if (renderPlaceholder && lProps.leaf.placeholder && lProps.text.text === '') {
232
+ if (
233
+ renderPlaceholder &&
234
+ lProps.leaf.placeholder &&
235
+ lProps.text.text === ''
236
+ ) {
211
237
  return (
212
238
  <>
213
239
  <span style={PLACEHOLDER_STYLE} contentEditable={false}>
@@ -225,7 +251,14 @@ export const PortableTextEditable = forwardRef(function PortableTextEditable(
225
251
  }
226
252
  return lProps.children
227
253
  },
228
- [readOnly, renderAnnotation, renderChild, renderDecorator, renderPlaceholder, schemaTypes],
254
+ [
255
+ readOnly,
256
+ renderAnnotation,
257
+ renderChild,
258
+ renderDecorator,
259
+ renderPlaceholder,
260
+ schemaTypes,
261
+ ],
229
262
  )
230
263
 
231
264
  const restoreSelectionFromProps = useCallback(() => {
@@ -236,7 +269,9 @@ export const PortableTextEditable = forwardRef(function PortableTextEditable(
236
269
  fromSlateValue(slateEditor.children, blockTypeName),
237
270
  )
238
271
  if (normalizedSelection !== null) {
239
- debug(`Normalized selection from props ${JSON.stringify(normalizedSelection)}`)
272
+ debug(
273
+ `Normalized selection from props ${JSON.stringify(normalizedSelection)}`,
274
+ )
240
275
  const slateRange = toSlateRange(normalizedSelection, slateEditor)
241
276
  if (slateRange) {
242
277
  Transforms.select(slateEditor, slateRange)
@@ -256,7 +291,10 @@ export const PortableTextEditable = forwardRef(function PortableTextEditable(
256
291
  if (rangeDecorations && rangeDecorations.length > 0) {
257
292
  const newSlateRanges: BaseRangeWithDecoration[] = []
258
293
  rangeDecorations.forEach((rangeDecorationItem) => {
259
- const slateRange = toSlateRange(rangeDecorationItem.selection, slateEditor)
294
+ const slateRange = toSlateRange(
295
+ rangeDecorationItem.selection,
296
+ slateEditor,
297
+ )
260
298
  if (!SlateRange.isRange(slateRange)) {
261
299
  if (rangeDecorationItem.onMoved) {
262
300
  rangeDecorationItem.onMoved({
@@ -270,9 +308,16 @@ export const PortableTextEditable = forwardRef(function PortableTextEditable(
270
308
  let newRange: BaseRange | null | undefined
271
309
  if (operation) {
272
310
  newRange = moveRangeByOperation(slateRange, operation)
273
- if ((newRange && newRange !== slateRange) || (newRange === null && slateRange)) {
311
+ if (
312
+ (newRange && newRange !== slateRange) ||
313
+ (newRange === null && slateRange)
314
+ ) {
274
315
  const value = PortableTextEditor.getValue(portableTextEditor)
275
- const newRangeSelection = toPortableTextRange(value, newRange, schemaTypes)
316
+ const newRangeSelection = toPortableTextRange(
317
+ value,
318
+ newRange,
319
+ schemaTypes,
320
+ )
276
321
  if (rangeDecorationItem.onMoved) {
277
322
  rangeDecorationItem.onMoved({
278
323
  newSelection: newRangeSelection,
@@ -285,7 +330,10 @@ export const PortableTextEditable = forwardRef(function PortableTextEditable(
285
330
  // If the newRange is null, it means that the range is not valid anymore and should be removed
286
331
  // If it's undefined, it means that the slateRange is still valid and should be kept
287
332
  if (newRange !== null) {
288
- newSlateRanges.push({...(newRange || slateRange), rangeDecoration: rangeDecorationItem})
333
+ newSlateRanges.push({
334
+ ...(newRange || slateRange),
335
+ rangeDecoration: rangeDecorationItem,
336
+ })
289
337
  }
290
338
  })
291
339
  if (newSlateRanges.length > 0) {
@@ -388,7 +436,11 @@ export const PortableTextEditable = forwardRef(function PortableTextEditable(
388
436
  }
389
437
 
390
438
  const value = PortableTextEditor.getValue(portableTextEditor)
391
- const ptRange = toPortableTextRange(value, slateEditor.selection, schemaTypes)
439
+ const ptRange = toPortableTextRange(
440
+ value,
441
+ slateEditor.selection,
442
+ schemaTypes,
443
+ )
392
444
  const path = ptRange?.focus.path || []
393
445
  const onPasteResult = onPaste({event, value, path, schemaTypes})
394
446
 
@@ -406,10 +458,15 @@ export const PortableTextEditable = forwardRef(function PortableTextEditable(
406
458
  slateEditor.insertData(event.clipboardData)
407
459
  } else if (result.insert) {
408
460
  slateEditor.insertFragment(
409
- toSlateValue(result.insert as PortableTextBlock[], {schemaTypes}),
461
+ toSlateValue(result.insert as PortableTextBlock[], {
462
+ schemaTypes,
463
+ }),
410
464
  )
411
465
  } else {
412
- console.warn('Your onPaste function returned something unexpected:', result)
466
+ console.warn(
467
+ 'Your onPaste function returned something unexpected:',
468
+ result,
469
+ )
413
470
  }
414
471
  })
415
472
  .catch((error) => {
@@ -465,7 +522,10 @@ export const PortableTextEditable = forwardRef(function PortableTextEditable(
465
522
  | SlateTextBlock
466
523
  | VoidElement
467
524
  if (lastBlock && Editor.isVoid(slateEditor, node)) {
468
- Transforms.insertNodes(slateEditor, slateEditor.pteCreateEmptyBlock())
525
+ Transforms.insertNodes(
526
+ slateEditor,
527
+ slateEditor.pteCreateTextBlock({decorators: []}),
528
+ )
469
529
  slateEditor.onChange()
470
530
  }
471
531
  }
@@ -528,7 +588,10 @@ export const PortableTextEditable = forwardRef(function PortableTextEditable(
528
588
  }
529
589
  const existingDOMRange = domSelection.getRangeAt(0)
530
590
  try {
531
- const newDOMRange = ReactEditor.toDOMRange(slateEditor, slateEditor.selection)
591
+ const newDOMRange = ReactEditor.toDOMRange(
592
+ slateEditor,
593
+ slateEditor.selection,
594
+ )
532
595
  if (
533
596
  newDOMRange.startOffset !== existingDOMRange.startOffset ||
534
597
  newDOMRange.endOffset !== existingDOMRange.endOffset
@@ -625,12 +688,17 @@ export const PortableTextEditable = forwardRef(function PortableTextEditable(
625
688
  if (path.length !== 2) {
626
689
  return false
627
690
  }
628
- return Path.equals(item.focus.path, path) && Path.equals(item.anchor.path, path)
691
+ return (
692
+ Path.equals(item.focus.path, path) &&
693
+ Path.equals(item.anchor.path, path)
694
+ )
629
695
  }
630
696
  // Include decorations that either include or intersects with this path
631
697
  return (
632
- SlateRange.intersection(item, {anchor: {path, offset: 0}, focus: {path, offset: 0}}) ||
633
- SlateRange.includes(item, path)
698
+ SlateRange.intersection(item, {
699
+ anchor: {path, offset: 0},
700
+ focus: {path, offset: 0},
701
+ }) || SlateRange.includes(item, path)
634
702
  )
635
703
  })
636
704
  if (result.length > 0) {
@@ -645,7 +713,10 @@ export const PortableTextEditable = forwardRef(function PortableTextEditable(
645
713
  // Also set the editable element in a state so that the MutationObserver
646
714
  // is setup when this element is ready.
647
715
  useEffect(() => {
648
- ref.current = ReactEditor.toDOMNode(slateEditor, slateEditor) as HTMLDivElement | null
716
+ ref.current = ReactEditor.toDOMNode(
717
+ slateEditor,
718
+ slateEditor,
719
+ ) as HTMLDivElement | null
649
720
  setEditableElement(ref.current)
650
721
  }, [slateEditor, ref])
651
722
 
@@ -11,7 +11,6 @@ import {
11
11
  } from '@sanity/types'
12
12
  import {Component, type MutableRefObject, type PropsWithChildren} from 'react'
13
13
  import {Subject} from 'rxjs'
14
-
15
14
  import {
16
15
  type EditableAPI,
17
16
  type EditableAPIDeleteOptions,
@@ -114,7 +113,9 @@ export class PortableTextEditor extends Component<PortableTextEditorProps> {
114
113
  }
115
114
 
116
115
  if (props.incomingPatches$) {
117
- console.warn(`The prop 'incomingPatches$' is deprecated and renamed to 'patches$'`)
116
+ console.warn(
117
+ `The prop 'incomingPatches$' is deprecated and renamed to 'patches$'`,
118
+ )
118
119
  }
119
120
 
120
121
  this.change$.next({type: 'loading', isLoading: true})
@@ -192,20 +193,39 @@ export class PortableTextEditor extends Component<PortableTextEditorProps> {
192
193
  }
193
194
 
194
195
  // Static API methods
195
- static activeAnnotations = (editor: PortableTextEditor): PortableTextObject[] => {
196
+ static activeAnnotations = (
197
+ editor: PortableTextEditor,
198
+ ): PortableTextObject[] => {
196
199
  return editor && editor.editable ? editor.editable.activeAnnotations() : []
197
200
  }
198
201
  static isAnnotationActive = (
199
202
  editor: PortableTextEditor,
200
203
  annotationType: PortableTextObject['_type'],
201
204
  ): boolean => {
202
- return editor && editor.editable ? editor.editable.isAnnotationActive(annotationType) : false
205
+ return editor && editor.editable
206
+ ? editor.editable.isAnnotationActive(annotationType)
207
+ : false
203
208
  }
204
209
  static addAnnotation = (
205
210
  editor: PortableTextEditor,
206
211
  type: ObjectSchemaType,
207
212
  value?: {[prop: string]: unknown},
208
- ): {spanPath: Path; markDefPath: Path} | undefined => editor.editable?.addAnnotation(type, value)
213
+ ):
214
+ | {
215
+ /**
216
+ * @deprecated An annotation may be applied to multiple blocks, resulting
217
+ * in multiple `markDef`'s being created. Use `markDefPaths` instead.
218
+ */
219
+ markDefPath: Path
220
+ markDefPaths: Array<Path>
221
+ /**
222
+ * @deprecated Does not return anything meaningful since an annotation
223
+ * can span multiple blocks and spans. If references the span closest
224
+ * to the focus point of the selection.
225
+ */
226
+ spanPath: Path
227
+ }
228
+ | undefined => editor.editable?.addAnnotation(type, value)
209
229
  static blur = (editor: PortableTextEditor): void => {
210
230
  debug('Host blurred')
211
231
  editor.editable?.blur()
@@ -232,7 +252,9 @@ export class PortableTextEditor extends Component<PortableTextEditorProps> {
232
252
  static focusBlock = (editor: PortableTextEditor) => {
233
253
  return editor.editable?.focusBlock()
234
254
  }
235
- static focusChild = (editor: PortableTextEditor): PortableTextChild | undefined => {
255
+ static focusChild = (
256
+ editor: PortableTextEditor,
257
+ ): PortableTextChild | undefined => {
236
258
  return editor.editable?.focusChild()
237
259
  }
238
260
  static getSelection = (editor: PortableTextEditor) => {
@@ -271,7 +293,10 @@ export class PortableTextEditor extends Component<PortableTextEditorProps> {
271
293
  static insertBreak = (editor: PortableTextEditor): void => {
272
294
  return editor.editable?.insertBreak()
273
295
  }
274
- static isVoid = (editor: PortableTextEditor, element: PortableTextBlock | PortableTextChild) => {
296
+ static isVoid = (
297
+ editor: PortableTextEditor,
298
+ element: PortableTextBlock | PortableTextChild,
299
+ ) => {
275
300
  return editor.editable?.isVoid(element)
276
301
  }
277
302
  static isObjectPath = (editor: PortableTextEditor, path: Path): boolean => {
@@ -283,13 +308,21 @@ export class PortableTextEditor extends Component<PortableTextEditorProps> {
283
308
  static marks = (editor: PortableTextEditor) => {
284
309
  return editor.editable?.marks()
285
310
  }
286
- static select = (editor: PortableTextEditor, selection: EditorSelection | null) => {
311
+ static select = (
312
+ editor: PortableTextEditor,
313
+ selection: EditorSelection | null,
314
+ ) => {
287
315
  debug(`Host setting selection`, selection)
288
316
  editor.editable?.select(selection)
289
317
  }
290
- static removeAnnotation = (editor: PortableTextEditor, type: ObjectSchemaType) =>
291
- editor.editable?.removeAnnotation(type)
292
- static toggleBlockStyle = (editor: PortableTextEditor, blockStyle: string) => {
318
+ static removeAnnotation = (
319
+ editor: PortableTextEditor,
320
+ type: ObjectSchemaType,
321
+ ) => editor.editable?.removeAnnotation(type)
322
+ static toggleBlockStyle = (
323
+ editor: PortableTextEditor,
324
+ blockStyle: string,
325
+ ) => {
293
326
  debug(`Host is toggling block style`)
294
327
  return editor.editable?.toggleBlockStyle(blockStyle)
295
328
  }
@@ -300,7 +333,9 @@ export class PortableTextEditor extends Component<PortableTextEditorProps> {
300
333
  debug(`Host toggling mark`, mark)
301
334
  editor.editable?.toggleMark(mark)
302
335
  }
303
- static getFragment = (editor: PortableTextEditor): PortableTextBlock[] | undefined => {
336
+ static getFragment = (
337
+ editor: PortableTextEditor,
338
+ ): PortableTextBlock[] | undefined => {
304
339
  debug(`Host getting fragment`)
305
340
  return editor.editable?.getFragment()
306
341
  }
@@ -3,7 +3,6 @@ import {describe, expect, it, jest} from '@jest/globals'
3
3
  import {type PortableTextBlock} from '@sanity/types'
4
4
  import {render, waitFor} from '@testing-library/react'
5
5
  import {createRef, type RefObject} from 'react'
6
-
7
6
  import {type EditorSelection} from '../..'
8
7
  import {PortableTextEditor} from '../PortableTextEditor'
9
8
  import {PortableTextEditorTester, schemaType} from './PortableTextEditorTester'
@@ -102,10 +101,15 @@ describe('initialization', () => {
102
101
  )
103
102
  const normalizedEditorValue = [{...initialValue[0], style: 'normal'}]
104
103
  await waitFor(() => {
105
- expect(onChange).toHaveBeenCalledWith({type: 'value', value: initialValue})
104
+ expect(onChange).toHaveBeenCalledWith({
105
+ type: 'value',
106
+ value: initialValue,
107
+ })
106
108
  })
107
109
  if (editorRef.current) {
108
- expect(PortableTextEditor.getValue(editorRef.current)).toStrictEqual(normalizedEditorValue)
110
+ expect(PortableTextEditor.getValue(editorRef.current)).toStrictEqual(
111
+ normalizedEditorValue,
112
+ )
109
113
  }
110
114
  })
111
115
 
@@ -130,7 +134,10 @@ describe('initialization', () => {
130
134
 
131
135
  await waitFor(() => {
132
136
  if (editorRef.current) {
133
- expect(onChange).toHaveBeenCalledWith({type: 'value', value: initialValue})
137
+ expect(onChange).toHaveBeenCalledWith({
138
+ type: 'value',
139
+ value: initialValue,
140
+ })
134
141
  expect(onChange).toHaveBeenCalledWith({type: 'ready'})
135
142
  }
136
143
  })
@@ -138,7 +145,9 @@ describe('initialization', () => {
138
145
  await waitFor(() => {
139
146
  if (editorRef.current) {
140
147
  PortableTextEditor.focus(editorRef.current)
141
- expect(PortableTextEditor.getSelection(editorRef.current)).toStrictEqual(initialSelection)
148
+ expect(
149
+ PortableTextEditor.getSelection(editorRef.current),
150
+ ).toStrictEqual(initialSelection)
142
151
  }
143
152
  })
144
153
  })
@@ -169,7 +178,10 @@ describe('initialization', () => {
169
178
 
170
179
  await waitFor(() => {
171
180
  if (editorRef.current) {
172
- expect(onChange).toHaveBeenCalledWith({type: 'value', value: initialValue})
181
+ expect(onChange).toHaveBeenCalledWith({
182
+ type: 'value',
183
+ value: initialValue,
184
+ })
173
185
  expect(onChange).toHaveBeenCalledWith({type: 'ready'})
174
186
  }
175
187
  })
@@ -181,7 +193,9 @@ describe('initialization', () => {
181
193
 
182
194
  // Test for object equality here!
183
195
  const anotherSel = PortableTextEditor.getSelection(editorRef.current)
184
- expect(PortableTextEditor.getSelection(editorRef.current)).toStrictEqual(initialSelection)
196
+ expect(
197
+ PortableTextEditor.getSelection(editorRef.current),
198
+ ).toStrictEqual(initialSelection)
185
199
  expect(sel).toBe(anotherSel)
186
200
  }
187
201
  })
@@ -196,7 +210,9 @@ describe('initialization', () => {
196
210
  )
197
211
  waitFor(() => {
198
212
  if (editorRef.current) {
199
- expect(PortableTextEditor.getSelection(editorRef.current)).toEqual(newSelection)
213
+ expect(PortableTextEditor.getSelection(editorRef.current)).toEqual(
214
+ newSelection,
215
+ )
200
216
  }
201
217
  })
202
218
  })
@@ -225,7 +241,8 @@ describe('initialization', () => {
225
241
  value: initialValue,
226
242
  resolution: {
227
243
  action: 'Unset the value',
228
- description: 'Editor value must be an array of Portable Text blocks, or undefined.',
244
+ description:
245
+ 'Editor value must be an array of Portable Text blocks, or undefined.',
229
246
  item: initialValue,
230
247
  patches: [
231
248
  {
@@ -235,7 +252,10 @@ describe('initialization', () => {
235
252
  ],
236
253
  },
237
254
  })
238
- expect(onChange).toHaveBeenCalledWith({type: 'value', value: initialValue})
255
+ expect(onChange).toHaveBeenCalledWith({
256
+ type: 'value',
257
+ value: initialValue,
258
+ })
239
259
  expect(onChange).toHaveBeenCalledWith({type: 'ready'})
240
260
  }
241
261
  })
@@ -267,7 +287,8 @@ describe('initialization', () => {
267
287
  value,
268
288
  resolution: {
269
289
  action: 'Unset the value',
270
- description: 'Editor value must be an array of Portable Text blocks, or undefined.',
290
+ description:
291
+ 'Editor value must be an array of Portable Text blocks, or undefined.',
271
292
  item: value,
272
293
  patches: [
273
294
  {
@@ -306,7 +327,8 @@ describe('initialization', () => {
306
327
  ],
307
328
  i18n: {
308
329
  action: 'inputs.portable-text.invalid-value.disallowed-type.action',
309
- description: 'inputs.portable-text.invalid-value.disallowed-type.description',
330
+ description:
331
+ 'inputs.portable-text.invalid-value.disallowed-type.description',
310
332
  values: {
311
333
  key: '123',
312
334
  typeName: 'banana',
@@ -351,8 +373,10 @@ describe('initialization', () => {
351
373
  description:
352
374
  "Child with _key 'def' in block with key 'abc' has missing or invalid text property!",
353
375
  i18n: {
354
- action: 'inputs.portable-text.invalid-value.invalid-span-text.action',
355
- description: 'inputs.portable-text.invalid-value.invalid-span-text.description',
376
+ action:
377
+ 'inputs.portable-text.invalid-value.invalid-span-text.action',
378
+ description:
379
+ 'inputs.portable-text.invalid-value.invalid-span-text.description',
356
380
  values: {
357
381
  key: 'abc',
358
382
  childKey: 'def',
@@ -394,7 +418,10 @@ describe('initialization', () => {
394
418
  })
395
419
  }
396
420
  })
397
- expect(onChange).not.toHaveBeenCalledWith({type: 'value', value: initialValue})
421
+ expect(onChange).not.toHaveBeenCalledWith({
422
+ type: 'value',
423
+ value: initialValue,
424
+ })
398
425
  expect(onChange).toHaveBeenCalledWith({type: 'ready'})
399
426
  })
400
427
  })