@portabletext/editor 0.0.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 (97) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +3 -0
  3. package/lib/index.d.mts +911 -0
  4. package/lib/index.d.ts +911 -0
  5. package/lib/index.esm.js +4896 -0
  6. package/lib/index.esm.js.map +1 -0
  7. package/lib/index.js +4874 -0
  8. package/lib/index.js.map +1 -0
  9. package/lib/index.mjs +4896 -0
  10. package/lib/index.mjs.map +1 -0
  11. package/package.json +119 -0
  12. package/src/editor/Editable.tsx +683 -0
  13. package/src/editor/PortableTextEditor.tsx +308 -0
  14. package/src/editor/__tests__/PortableTextEditor.test.tsx +386 -0
  15. package/src/editor/__tests__/PortableTextEditorTester.tsx +116 -0
  16. package/src/editor/__tests__/RangeDecorations.test.tsx +115 -0
  17. package/src/editor/__tests__/handleClick.test.tsx +218 -0
  18. package/src/editor/__tests__/pteWarningsSelfSolving.test.tsx +389 -0
  19. package/src/editor/__tests__/utils.ts +39 -0
  20. package/src/editor/components/DraggableBlock.tsx +287 -0
  21. package/src/editor/components/Element.tsx +279 -0
  22. package/src/editor/components/Leaf.tsx +288 -0
  23. package/src/editor/components/SlateContainer.tsx +81 -0
  24. package/src/editor/components/Synchronizer.tsx +190 -0
  25. package/src/editor/hooks/usePortableTextEditor.ts +23 -0
  26. package/src/editor/hooks/usePortableTextEditorKeyGenerator.ts +24 -0
  27. package/src/editor/hooks/usePortableTextEditorSelection.ts +22 -0
  28. package/src/editor/hooks/usePortableTextEditorValue.ts +16 -0
  29. package/src/editor/hooks/usePortableTextReadOnly.ts +20 -0
  30. package/src/editor/hooks/useSyncValue.test.tsx +125 -0
  31. package/src/editor/hooks/useSyncValue.ts +372 -0
  32. package/src/editor/nodes/DefaultAnnotation.tsx +16 -0
  33. package/src/editor/nodes/DefaultObject.tsx +15 -0
  34. package/src/editor/nodes/index.ts +189 -0
  35. package/src/editor/plugins/__tests__/withEditableAPIDelete.test.tsx +244 -0
  36. package/src/editor/plugins/__tests__/withEditableAPIGetFragment.test.tsx +142 -0
  37. package/src/editor/plugins/__tests__/withEditableAPIInsert.test.tsx +346 -0
  38. package/src/editor/plugins/__tests__/withEditableAPISelectionsOverlapping.test.tsx +162 -0
  39. package/src/editor/plugins/__tests__/withHotkeys.test.tsx +212 -0
  40. package/src/editor/plugins/__tests__/withInsertBreak.test.tsx +204 -0
  41. package/src/editor/plugins/__tests__/withPlaceholderBlock.test.tsx +133 -0
  42. package/src/editor/plugins/__tests__/withPortableTextLists.test.tsx +65 -0
  43. package/src/editor/plugins/__tests__/withPortableTextMarkModel.test.tsx +1377 -0
  44. package/src/editor/plugins/__tests__/withPortableTextSelections.test.tsx +91 -0
  45. package/src/editor/plugins/__tests__/withUndoRedo.test.tsx +115 -0
  46. package/src/editor/plugins/createWithEditableAPI.ts +573 -0
  47. package/src/editor/plugins/createWithHotKeys.ts +304 -0
  48. package/src/editor/plugins/createWithInsertBreak.ts +45 -0
  49. package/src/editor/plugins/createWithInsertData.ts +359 -0
  50. package/src/editor/plugins/createWithMaxBlocks.ts +24 -0
  51. package/src/editor/plugins/createWithObjectKeys.ts +63 -0
  52. package/src/editor/plugins/createWithPatches.ts +274 -0
  53. package/src/editor/plugins/createWithPlaceholderBlock.ts +36 -0
  54. package/src/editor/plugins/createWithPortableTextBlockStyle.ts +91 -0
  55. package/src/editor/plugins/createWithPortableTextLists.ts +160 -0
  56. package/src/editor/plugins/createWithPortableTextMarkModel.ts +441 -0
  57. package/src/editor/plugins/createWithPortableTextSelections.ts +65 -0
  58. package/src/editor/plugins/createWithSchemaTypes.ts +76 -0
  59. package/src/editor/plugins/createWithUndoRedo.ts +494 -0
  60. package/src/editor/plugins/createWithUtils.ts +81 -0
  61. package/src/editor/plugins/index.ts +155 -0
  62. package/src/index.ts +11 -0
  63. package/src/patch/PatchEvent.ts +33 -0
  64. package/src/patch/applyPatch.ts +29 -0
  65. package/src/patch/array.ts +89 -0
  66. package/src/patch/arrayInsert.ts +27 -0
  67. package/src/patch/object.ts +39 -0
  68. package/src/patch/patches.ts +53 -0
  69. package/src/patch/primitive.ts +43 -0
  70. package/src/patch/string.ts +51 -0
  71. package/src/types/editor.ts +576 -0
  72. package/src/types/options.ts +17 -0
  73. package/src/types/patch.ts +65 -0
  74. package/src/types/slate.ts +25 -0
  75. package/src/utils/__tests__/dmpToOperations.test.ts +181 -0
  76. package/src/utils/__tests__/operationToPatches.test.ts +421 -0
  77. package/src/utils/__tests__/patchToOperations.test.ts +293 -0
  78. package/src/utils/__tests__/ranges.test.ts +18 -0
  79. package/src/utils/__tests__/valueNormalization.test.tsx +62 -0
  80. package/src/utils/__tests__/values.test.ts +253 -0
  81. package/src/utils/applyPatch.ts +407 -0
  82. package/src/utils/bufferUntil.ts +15 -0
  83. package/src/utils/debug.ts +12 -0
  84. package/src/utils/getPortableTextMemberSchemaTypes.ts +100 -0
  85. package/src/utils/operationToPatches.ts +357 -0
  86. package/src/utils/patches.ts +36 -0
  87. package/src/utils/paths.ts +60 -0
  88. package/src/utils/ranges.ts +77 -0
  89. package/src/utils/schema.ts +8 -0
  90. package/src/utils/selection.ts +65 -0
  91. package/src/utils/ucs2Indices.ts +67 -0
  92. package/src/utils/validateValue.ts +394 -0
  93. package/src/utils/values.ts +208 -0
  94. package/src/utils/weakMaps.ts +24 -0
  95. package/src/utils/withChanges.ts +25 -0
  96. package/src/utils/withPreserveKeys.ts +14 -0
  97. package/src/utils/withoutPatching.ts +14 -0
@@ -0,0 +1,576 @@
1
+ import {
2
+ type ArraySchemaType,
3
+ type BlockDecoratorDefinition,
4
+ type BlockListDefinition,
5
+ type BlockSchemaType,
6
+ type BlockStyleDefinition,
7
+ type ObjectSchemaType,
8
+ type Path,
9
+ type PortableTextBlock,
10
+ type PortableTextChild,
11
+ type PortableTextListBlock,
12
+ type PortableTextObject,
13
+ type PortableTextSpan,
14
+ type PortableTextTextBlock,
15
+ type SpanSchemaType,
16
+ type TypedObject,
17
+ } from '@sanity/types'
18
+ import {
19
+ type ClipboardEvent,
20
+ type FocusEvent,
21
+ type KeyboardEvent,
22
+ type PropsWithChildren,
23
+ type ReactElement,
24
+ type RefObject,
25
+ } from 'react'
26
+ import {type Observable, type Subject} from 'rxjs'
27
+ import {type Descendant, type Node as SlateNode, type Operation as SlateOperation} from 'slate'
28
+ import {type ReactEditor} from 'slate-react'
29
+ import {type DOMNode} from 'slate-react/dist/utils/dom'
30
+
31
+ import {type PortableTextEditableProps} from '../editor/Editable'
32
+ import {type PortableTextEditor} from '../editor/PortableTextEditor'
33
+ import {type Patch} from '../types/patch'
34
+
35
+ /** @beta */
36
+ export interface EditableAPIDeleteOptions {
37
+ mode?: 'blocks' | 'children' | 'selected'
38
+ }
39
+
40
+ /** @beta */
41
+ export interface EditableAPI {
42
+ activeAnnotations: () => PortableTextObject[]
43
+ isAnnotationActive: (annotationType: PortableTextObject['_type']) => boolean
44
+ addAnnotation: (
45
+ type: ObjectSchemaType,
46
+ value?: {[prop: string]: unknown},
47
+ ) => {spanPath: Path; markDefPath: Path} | undefined
48
+ blur: () => void
49
+ delete: (selection: EditorSelection, options?: EditableAPIDeleteOptions) => void
50
+ findByPath: (path: Path) => [PortableTextBlock | PortableTextChild | undefined, Path | undefined]
51
+ findDOMNode: (element: PortableTextBlock | PortableTextChild) => DOMNode | undefined
52
+ focus: () => void
53
+ focusBlock: () => PortableTextBlock | undefined
54
+ focusChild: () => PortableTextChild | undefined
55
+ getSelection: () => EditorSelection
56
+ getFragment: () => PortableTextBlock[] | undefined
57
+ getValue: () => PortableTextBlock[] | undefined
58
+ hasBlockStyle: (style: string) => boolean
59
+ hasListStyle: (listStyle: string) => boolean
60
+ insertBlock: (type: BlockSchemaType | ObjectSchemaType, value?: {[prop: string]: unknown}) => Path
61
+ insertChild: (type: SpanSchemaType | ObjectSchemaType, value?: {[prop: string]: unknown}) => Path
62
+ insertBreak: () => void
63
+ isCollapsedSelection: () => boolean
64
+ isExpandedSelection: () => boolean
65
+ isMarkActive: (mark: string) => boolean
66
+ isSelectionsOverlapping: (selectionA: EditorSelection, selectionB: EditorSelection) => boolean
67
+ isVoid: (element: PortableTextBlock | PortableTextChild) => boolean
68
+ marks: () => string[]
69
+ redo: () => void
70
+ removeAnnotation: (type: ObjectSchemaType) => void
71
+ select: (selection: EditorSelection) => void
72
+ toggleBlockStyle: (blockStyle: string) => void
73
+ toggleList: (listStyle: string) => void
74
+ toggleMark: (mark: string) => void
75
+ undo: () => void
76
+ }
77
+
78
+ /** @internal */
79
+ export type EditorNode = SlateNode & {
80
+ _key: string
81
+ _type: string
82
+ }
83
+ /** @internal */
84
+ export type HistoryItem = {
85
+ operations: SlateOperation[]
86
+ timestamp: Date
87
+ }
88
+ /** @internal */
89
+ export interface History {
90
+ redos: HistoryItem[]
91
+ undos: HistoryItem[]
92
+ }
93
+
94
+ /** @beta */
95
+ export type EditorSelectionPoint = {path: Path; offset: number}
96
+ /** @beta */
97
+ export type EditorSelection = {
98
+ anchor: EditorSelectionPoint
99
+ focus: EditorSelectionPoint
100
+ backward?: boolean
101
+ } | null
102
+ /** @internal */
103
+ export interface PortableTextSlateEditor extends ReactEditor {
104
+ _key: 'editor'
105
+ _type: 'editor'
106
+ destroy: () => void
107
+ createPlaceholderBlock: () => Descendant
108
+ editable: EditableAPI
109
+ history: History
110
+ insertPortableTextData: (data: DataTransfer) => boolean
111
+ insertTextOrHTMLData: (data: DataTransfer) => boolean
112
+ isTextBlock: (value: unknown) => value is PortableTextTextBlock
113
+ isTextSpan: (value: unknown) => value is PortableTextSpan
114
+ isListBlock: (value: unknown) => value is PortableTextListBlock
115
+ subscriptions: (() => () => void)[]
116
+
117
+ /**
118
+ * Increments selected list items levels, or decrements them if `reverse` is true.
119
+ *
120
+ * @param reverse - if true, decrement instead of incrementing
121
+ * @returns True if anything was incremented in the selection
122
+ */
123
+ pteIncrementBlockLevels: (reverse?: boolean) => boolean
124
+
125
+ /**
126
+ * Toggle selected blocks as listItem
127
+ *
128
+ * @param listStyle - Style of list item to toggle on/off
129
+ */
130
+ pteToggleListItem: (listStyle: string) => void
131
+
132
+ /**
133
+ * Set selected block as listItem
134
+ *
135
+ * @param listStyle - Style of list item to set
136
+ */
137
+ pteSetListItem: (listStyle: string) => void
138
+
139
+ /**
140
+ * Unset selected block as listItem
141
+ *
142
+ * @param listStyle - Style of list item to unset
143
+ */
144
+ pteUnsetListItem: (listStyle: string) => void
145
+
146
+ /**
147
+ * Ends a list
148
+ *
149
+ * @returns True if a list was ended in the selection
150
+ */
151
+ pteEndList: () => boolean
152
+
153
+ /**
154
+ * Toggle marks in the selection
155
+ *
156
+ * @param mark - Mark to toggle on/off
157
+ */
158
+ pteToggleMark: (mark: string) => void
159
+
160
+ /**
161
+ * Test if a mark is active in the current selection
162
+ *
163
+ * @param mark - Mark to check whether or not is active
164
+ */
165
+ pteIsMarkActive: (mark: string) => boolean
166
+
167
+ /**
168
+ * Toggle the selected block style
169
+ *
170
+ * @param style - The style name
171
+ *
172
+ */
173
+ pteToggleBlockStyle: (style: string) => void
174
+
175
+ /**
176
+ * Test if the current selection has a certain block style
177
+ *
178
+ * @param style - The style name
179
+ *
180
+ */
181
+ pteHasBlockStyle: (style: string) => boolean
182
+
183
+ /**
184
+ * Test if the current selection has a certain list style
185
+ *
186
+ * @param listStyle - Style name to check whether or not the selection has
187
+ *
188
+ */
189
+ pteHasListStyle: (style: string) => boolean
190
+
191
+ /**
192
+ * Try to expand the current selection to a word
193
+ */
194
+ pteExpandToWord: () => void
195
+
196
+ /**
197
+ * Use hotkeys
198
+ */
199
+ pteWithHotKeys: (event: KeyboardEvent<HTMLDivElement>) => void
200
+
201
+ /**
202
+ * Helper function that creates an empty text block
203
+ */
204
+ pteCreateEmptyBlock: () => Descendant
205
+
206
+ /**
207
+ * Undo
208
+ */
209
+ undo: () => void
210
+
211
+ /**
212
+ * Redo
213
+ */
214
+ redo: () => void
215
+ }
216
+
217
+ /**
218
+ * The editor has mutated it's content.
219
+ * @beta */
220
+ export type MutationChange = {
221
+ type: 'mutation'
222
+ patches: Patch[]
223
+ snapshot: PortableTextBlock[] | undefined
224
+ }
225
+
226
+ /**
227
+ * The editor has produced a patch
228
+ * @beta */
229
+ export type PatchChange = {
230
+ type: 'patch'
231
+ patch: Patch
232
+ }
233
+
234
+ /**
235
+ * The editor has received a new (props) value
236
+ * @beta */
237
+ export type ValueChange = {
238
+ type: 'value'
239
+ value: PortableTextBlock[] | undefined
240
+ }
241
+
242
+ /**
243
+ * The editor has a new selection
244
+ * @beta */
245
+ export type SelectionChange = {
246
+ type: 'selection'
247
+ selection: EditorSelection
248
+ }
249
+
250
+ /**
251
+ * The editor received focus
252
+ * @beta */
253
+ export type FocusChange = {
254
+ type: 'focus'
255
+ event: FocusEvent<HTMLDivElement, Element>
256
+ }
257
+
258
+ /** @beta */
259
+ export type UnsetChange = {
260
+ type: 'unset'
261
+ previousValue: PortableTextBlock[]
262
+ }
263
+
264
+ /**
265
+ * The editor blurred
266
+ * @beta */
267
+ export type BlurChange = {
268
+ type: 'blur'
269
+ event: FocusEvent<HTMLDivElement, Element>
270
+ }
271
+
272
+ /**
273
+ * The editor is currently loading something
274
+ * Could be used to show a spinner etc.
275
+ * @beta */
276
+ export type LoadingChange = {
277
+ type: 'loading'
278
+ isLoading: boolean
279
+ }
280
+
281
+ /**
282
+ * The editor content is ready to be edited by the user
283
+ * @beta */
284
+ export type ReadyChange = {
285
+ type: 'ready'
286
+ }
287
+
288
+ /**
289
+ * The editor produced an error
290
+ * @beta */
291
+ export type ErrorChange = {
292
+ type: 'error'
293
+ name: string // short computer readable name
294
+ level: 'warning' | 'error'
295
+ description: string
296
+ data?: unknown
297
+ }
298
+
299
+ /**
300
+ * The editor has invalid data in the value that can be resolved by the user
301
+ * @beta */
302
+ export type InvalidValueResolution = {
303
+ autoResolve?: boolean
304
+ patches: Patch[]
305
+ description: string
306
+ action: string
307
+ item: PortableTextBlock[] | PortableTextBlock | PortableTextChild | undefined
308
+
309
+ /**
310
+ * i18n keys for the description and action
311
+ *
312
+ * These are in addition to the description and action properties, to decouple the editor from
313
+ * the i18n system, and allow usage without it. The i18n keys take precedence over the
314
+ * description and action properties, if i18n framework is available.
315
+ */
316
+ i18n: {
317
+ description: `inputs.portable-text.invalid-value.${Lowercase<string>}.description`
318
+ action: `inputs.portable-text.invalid-value.${Lowercase<string>}.action`
319
+ values?: Record<string, string | number | string[]>
320
+ }
321
+ }
322
+
323
+ /**
324
+ * The editor has an invalid value
325
+ * @beta */
326
+ export type InvalidValue = {
327
+ type: 'invalidValue'
328
+ resolution: InvalidValueResolution | null
329
+ value: PortableTextBlock[] | undefined
330
+ }
331
+
332
+ /**
333
+ * The editor performed a undo history step
334
+ * @beta */
335
+ export type UndoChange = {
336
+ type: 'undo'
337
+ patches: Patch[]
338
+ timestamp: Date
339
+ }
340
+
341
+ /**
342
+ * The editor performed redo history step
343
+ * @beta */
344
+ export type RedoChange = {
345
+ type: 'redo'
346
+ patches: Patch[]
347
+ timestamp: Date
348
+ }
349
+
350
+ /**
351
+ * The editor was either connected or disconnected to the network
352
+ * To show out of sync warnings etc when in collaborative mode.
353
+ * @beta */
354
+ export type ConnectionChange = {
355
+ type: 'connection'
356
+ value: 'online' | 'offline'
357
+ }
358
+
359
+ /**
360
+ * When the editor changes, it will emit a change item describing the change
361
+ * @beta */
362
+ export type EditorChange =
363
+ | BlurChange
364
+ | ConnectionChange
365
+ | ErrorChange
366
+ | FocusChange
367
+ | InvalidValue
368
+ | LoadingChange
369
+ | MutationChange
370
+ | PatchChange
371
+ | ReadyChange
372
+ | RedoChange
373
+ | SelectionChange
374
+ | UndoChange
375
+ | UnsetChange
376
+ | ValueChange
377
+
378
+ export type EditorChanges = Subject<EditorChange>
379
+
380
+ /** @beta */
381
+ export type OnPasteResult =
382
+ | {
383
+ insert?: TypedObject[]
384
+ path?: Path
385
+ }
386
+ | undefined
387
+ export type OnPasteResultOrPromise = OnPasteResult | Promise<OnPasteResult>
388
+
389
+ /** @beta */
390
+ export interface PasteData {
391
+ event: ClipboardEvent
392
+ path: Path
393
+ schemaTypes: PortableTextMemberSchemaTypes
394
+ value: PortableTextBlock[] | undefined
395
+ }
396
+
397
+ /** @beta */
398
+ export type OnPasteFn = (data: PasteData) => OnPasteResultOrPromise
399
+
400
+ /** @beta */
401
+ export type OnBeforeInputFn = (event: InputEvent) => void
402
+
403
+ /** @beta */
404
+ export type OnCopyFn = (
405
+ event: ClipboardEvent<HTMLDivElement | HTMLSpanElement>,
406
+ ) => undefined | unknown
407
+
408
+ /** @beta */
409
+ export type PatchObservable = Observable<{
410
+ patches: Patch[]
411
+ snapshot: PortableTextBlock[] | undefined
412
+ }>
413
+
414
+ /** @beta */
415
+ export interface BlockRenderProps {
416
+ children: ReactElement
417
+ editorElementRef: RefObject<HTMLElement>
418
+ focused: boolean
419
+ level?: number
420
+ listItem?: string
421
+ path: Path
422
+ selected: boolean
423
+ style?: string
424
+ schemaType: ObjectSchemaType
425
+ /** @deprecated Use `schemaType` instead */
426
+ type: ObjectSchemaType
427
+ value: PortableTextBlock
428
+ }
429
+
430
+ /** @beta */
431
+ export interface BlockChildRenderProps {
432
+ annotations: PortableTextObject[]
433
+ children: ReactElement
434
+ editorElementRef: RefObject<HTMLElement>
435
+ focused: boolean
436
+ path: Path
437
+ selected: boolean
438
+ schemaType: ObjectSchemaType
439
+ /** @deprecated Use `schemaType` instead */
440
+ type: ObjectSchemaType
441
+ value: PortableTextChild
442
+ }
443
+
444
+ /** @beta */
445
+ export interface BlockAnnotationRenderProps {
446
+ block: PortableTextBlock
447
+ children: ReactElement
448
+ editorElementRef: RefObject<HTMLElement>
449
+ focused: boolean
450
+ path: Path
451
+ schemaType: ObjectSchemaType
452
+ selected: boolean
453
+ /** @deprecated Use `schemaType` instead */
454
+ type: ObjectSchemaType
455
+ value: PortableTextObject
456
+ }
457
+ /** @beta */
458
+ export interface BlockDecoratorRenderProps {
459
+ children: ReactElement
460
+ editorElementRef: RefObject<HTMLElement>
461
+ focused: boolean
462
+ path: Path
463
+ schemaType: BlockDecoratorDefinition
464
+ selected: boolean
465
+ /** @deprecated Use `schemaType` instead */
466
+ type: BlockDecoratorDefinition
467
+ value: string
468
+ }
469
+ /** @beta */
470
+
471
+ export interface BlockListItemRenderProps {
472
+ block: PortableTextTextBlock
473
+ children: ReactElement
474
+ editorElementRef: RefObject<HTMLElement>
475
+ focused: boolean
476
+ level: number
477
+ path: Path
478
+ schemaType: BlockListDefinition
479
+ selected: boolean
480
+ value: string
481
+ }
482
+
483
+ /** @beta */
484
+ export type RenderBlockFunction = (props: BlockRenderProps) => JSX.Element
485
+
486
+ /** @beta */
487
+ export type RenderChildFunction = (props: BlockChildRenderProps) => JSX.Element
488
+
489
+ /** @beta */
490
+ export type RenderEditableFunction = (props: PortableTextEditableProps) => JSX.Element
491
+
492
+ /** @beta */
493
+ export type RenderAnnotationFunction = (props: BlockAnnotationRenderProps) => JSX.Element
494
+
495
+ /** @beta */
496
+ export type RenderStyleFunction = (props: BlockStyleRenderProps) => JSX.Element
497
+
498
+ /** @beta */
499
+
500
+ export interface BlockStyleRenderProps {
501
+ block: PortableTextTextBlock
502
+ children: ReactElement
503
+ editorElementRef: RefObject<HTMLElement>
504
+ focused: boolean
505
+ path: Path
506
+ selected: boolean
507
+ schemaType: BlockStyleDefinition
508
+ value: string
509
+ }
510
+
511
+ /** @beta */
512
+ export type RenderListItemFunction = (props: BlockListItemRenderProps) => JSX.Element
513
+
514
+ /** @beta */
515
+ export type RenderDecoratorFunction = (props: BlockDecoratorRenderProps) => JSX.Element
516
+
517
+ /** @beta */
518
+ export type ScrollSelectionIntoViewFunction = (
519
+ editor: PortableTextEditor,
520
+ domRange: globalThis.Range,
521
+ ) => void
522
+
523
+ /**
524
+ * Parameters for the callback that will be called for a RangeDecoration's onMoved.
525
+ * @alpha */
526
+ export interface RangeDecorationOnMovedDetails {
527
+ rangeDecoration: RangeDecoration
528
+ newSelection: EditorSelection
529
+ origin: 'remote' | 'local'
530
+ }
531
+ /**
532
+ * A range decoration is a UI affordance that wraps a given selection range in the editor
533
+ * with a custom component. This can be used to highlight search results,
534
+ * mark validation errors on specific words, draw user presence and similar.
535
+ * @alpha */
536
+ export interface RangeDecoration {
537
+ /**
538
+ * A component for rendering the range decoration.
539
+ * The component will receive the children (text) of the range decoration as its children.
540
+ *
541
+ * @example
542
+ * ```ts
543
+ * (rangeComponentProps: PropsWithChildren) => (
544
+ * <SearchResultHighlight>
545
+ * {rangeComponentProps.children}
546
+ * </SearchResultHighlight>
547
+ * )
548
+ * ```
549
+ */
550
+ component: (props: PropsWithChildren) => ReactElement
551
+ /**
552
+ * The editor content selection range
553
+ */
554
+ selection: EditorSelection
555
+ /**
556
+ * A optional callback that will be called when the range decoration potentially moves according to user edits.
557
+ */
558
+ onMoved?: (details: RangeDecorationOnMovedDetails) => void
559
+ /**
560
+ * A custom payload that can be set on the range decoration
561
+ */
562
+ payload?: Record<string, unknown>
563
+ }
564
+
565
+ /** @internal */
566
+ export type PortableTextMemberSchemaTypes = {
567
+ annotations: (ObjectSchemaType & {i18nTitleKey?: string})[]
568
+ block: ObjectSchemaType
569
+ blockObjects: ObjectSchemaType[]
570
+ decorators: BlockDecoratorDefinition[]
571
+ inlineObjects: ObjectSchemaType[]
572
+ portableText: ArraySchemaType<PortableTextBlock>
573
+ span: ObjectSchemaType
574
+ styles: BlockStyleDefinition[]
575
+ lists: BlockListDefinition[]
576
+ }
@@ -0,0 +1,17 @@
1
+ import {type BaseSyntheticEvent} from 'react'
2
+
3
+ import {type PortableTextEditor} from '../editor/PortableTextEditor'
4
+ import {type PatchObservable} from './editor'
5
+
6
+ export type createEditorOptions = {
7
+ keyGenerator: () => string
8
+ patches$?: PatchObservable
9
+ portableTextEditor: PortableTextEditor
10
+ readOnly: boolean
11
+ maxBlocks?: number
12
+ }
13
+
14
+ export type HotkeyOptions = {
15
+ marks?: Record<string, string>
16
+ custom?: Record<string, (event: BaseSyntheticEvent, editor: PortableTextEditor) => void>
17
+ }
@@ -0,0 +1,65 @@
1
+ import {type Path} from '@sanity/types'
2
+
3
+ export type JSONValue = number | string | boolean | {[key: string]: JSONValue} | JSONValue[]
4
+
5
+ export type Origin = 'remote' | 'local' | 'internal'
6
+
7
+ export type IncPatch = {
8
+ path: Path
9
+ origin?: Origin
10
+ type: 'inc'
11
+ value: JSONValue
12
+ }
13
+
14
+ export type DecPatch = {
15
+ path: Path
16
+ origin?: Origin
17
+ type: 'dec'
18
+ value: JSONValue
19
+ }
20
+
21
+ export type SetPatch = {
22
+ path: Path
23
+ type: 'set'
24
+ origin?: Origin
25
+ value: JSONValue
26
+ }
27
+
28
+ export type SetIfMissingPatch = {
29
+ path: Path
30
+ origin?: Origin
31
+ type: 'setIfMissing'
32
+ value: JSONValue
33
+ }
34
+
35
+ export type UnsetPatch = {
36
+ path: Path
37
+ origin?: Origin
38
+ type: 'unset'
39
+ }
40
+
41
+ export type InsertPosition = 'before' | 'after' | 'replace'
42
+
43
+ export type InsertPatch = {
44
+ path: Path
45
+ origin?: Origin
46
+ type: 'insert'
47
+ position: InsertPosition
48
+ items: JSONValue[]
49
+ }
50
+
51
+ export type DiffMatchPatch = {
52
+ path: Path
53
+ type: 'diffMatchPatch'
54
+ origin?: Origin
55
+ value: string
56
+ }
57
+
58
+ export type Patch =
59
+ | SetPatch
60
+ | SetIfMissingPatch
61
+ | UnsetPatch
62
+ | InsertPatch
63
+ | DiffMatchPatch
64
+ | IncPatch
65
+ | DecPatch
@@ -0,0 +1,25 @@
1
+ import {type PortableTextSpan, type PortableTextTextBlock} from '@sanity/types'
2
+ import {type BaseEditor, type Descendant} from 'slate'
3
+ import {type ReactEditor} from 'slate-react'
4
+
5
+ import {type PortableTextSlateEditor} from '..'
6
+
7
+ export interface VoidElement {
8
+ _type: string
9
+ _key: string
10
+ children: Descendant[]
11
+ __inline: boolean
12
+ value: Record<string, unknown>
13
+ }
14
+
15
+ export interface SlateTextBlock extends Omit<PortableTextTextBlock, 'children'> {
16
+ children: Descendant[]
17
+ }
18
+
19
+ declare module 'slate' {
20
+ interface CustomTypes {
21
+ Editor: BaseEditor & ReactEditor & PortableTextSlateEditor
22
+ Element: SlateTextBlock | VoidElement
23
+ Text: PortableTextSpan
24
+ }
25
+ }