@portabletext/editor 2.8.0 → 2.8.2

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 (46) hide show
  1. package/lib/_chunks-cjs/selector.is-selection-expanded.cjs +10 -4
  2. package/lib/_chunks-cjs/selector.is-selection-expanded.cjs.map +1 -1
  3. package/lib/_chunks-cjs/util.merge-text-blocks.cjs +0 -1
  4. package/lib/_chunks-cjs/util.merge-text-blocks.cjs.map +1 -1
  5. package/lib/_chunks-cjs/util.slice-blocks.cjs +3 -6
  6. package/lib/_chunks-cjs/util.slice-blocks.cjs.map +1 -1
  7. package/lib/_chunks-dts/behavior.types.action.d.cts +27 -31
  8. package/lib/_chunks-dts/behavior.types.action.d.ts +18 -22
  9. package/lib/_chunks-es/selector.is-selection-expanded.js +10 -4
  10. package/lib/_chunks-es/selector.is-selection-expanded.js.map +1 -1
  11. package/lib/_chunks-es/util.merge-text-blocks.js +0 -1
  12. package/lib/_chunks-es/util.merge-text-blocks.js.map +1 -1
  13. package/lib/_chunks-es/util.slice-blocks.js +3 -6
  14. package/lib/_chunks-es/util.slice-blocks.js.map +1 -1
  15. package/lib/index.cjs +28 -51
  16. package/lib/index.cjs.map +1 -1
  17. package/lib/index.js +28 -51
  18. package/lib/index.js.map +1 -1
  19. package/lib/plugins/index.d.cts +3 -3
  20. package/lib/utils/index.d.ts +2 -2
  21. package/package.json +5 -5
  22. package/src/behaviors/behavior.abstract.split.ts +0 -1
  23. package/src/converters/converter.portable-text.ts +0 -1
  24. package/src/converters/converter.text-html.ts +0 -1
  25. package/src/converters/converter.text-plain.ts +0 -1
  26. package/src/editor/Editable.tsx +0 -1
  27. package/src/editor/PortableTextEditor.tsx +1 -1
  28. package/src/editor/plugins/createWithEditableAPI.ts +70 -28
  29. package/src/index.ts +1 -1
  30. package/src/internal-utils/parse-blocks.test.ts +23 -23
  31. package/src/internal-utils/parse-blocks.ts +11 -23
  32. package/src/internal-utils/test-editor.tsx +15 -21
  33. package/src/operations/behavior.operation.annotation.add.ts +2 -47
  34. package/src/operations/behavior.operation.block.set.ts +1 -1
  35. package/src/operations/behavior.operation.block.unset.ts +2 -2
  36. package/src/operations/behavior.operation.insert.block.ts +1 -1
  37. package/src/operations/behavior.operations.ts +1 -2
  38. package/src/plugins/plugin.internal.auto-close-brackets.test.tsx +25 -71
  39. package/src/plugins/plugin.markdown.test.tsx +12 -30
  40. package/src/selectors/selector.get-selected-value.test.ts +748 -0
  41. package/src/selectors/selector.get-selected-value.ts +28 -7
  42. package/src/selectors/selector.get-trimmed-selection.test.ts +0 -1
  43. package/src/types/editor.ts +19 -3
  44. package/src/utils/util.merge-text-blocks.ts +1 -1
  45. package/src/utils/util.slice-blocks.ts +3 -3
  46. package/src/utils/util.slice-blocks.test.ts +0 -499
@@ -1,29 +1,9 @@
1
- import type {Path} from '@sanity/types'
2
1
  import {Editor, Node, Range, Text, Transforms} from 'slate'
3
2
  import {parseAnnotation} from '../internal-utils/parse-blocks'
4
3
  import type {BehaviorOperationImplementation} from './behavior.operations'
5
4
 
6
- /**
7
- * @public
8
- */
9
- export type AddedAnnotationPaths = {
10
- /**
11
- * @deprecated An annotation may be applied to multiple blocks, resulting
12
- * in multiple `markDef`'s being created. Use `markDefPaths` instead.
13
- */
14
- markDefPath: Path
15
- markDefPaths: Array<Path>
16
- /**
17
- * @deprecated Does not return anything meaningful since an annotation
18
- * can span multiple blocks and spans. If references the span closest
19
- * to the focus point of the selection.
20
- */
21
- spanPath: Path
22
- }
23
-
24
5
  export const addAnnotationOperationImplementation: BehaviorOperationImplementation<
25
- 'annotation.add',
26
- AddedAnnotationPaths | undefined
6
+ 'annotation.add'
27
7
  > = ({context, operation}) => {
28
8
  const parsedAnnotation = parseAnnotation({
29
9
  annotation: {
@@ -31,7 +11,7 @@ export const addAnnotationOperationImplementation: BehaviorOperationImplementati
31
11
  ...operation.annotation.value,
32
12
  },
33
13
  context,
34
- options: {refreshKeys: false, validateFields: true},
14
+ options: {validateFields: true},
35
15
  })
36
16
 
37
17
  if (!parsedAnnotation) {
@@ -46,11 +26,6 @@ export const addAnnotationOperationImplementation: BehaviorOperationImplementati
46
26
  return
47
27
  }
48
28
 
49
- let paths: AddedAnnotationPaths | undefined
50
- let spanPath: Path | undefined
51
- let markDefPath: Path | undefined
52
- const markDefPaths: Path[] = []
53
-
54
29
  const selectedBlocks = Editor.nodes(editor, {
55
30
  at: editor.selection,
56
31
  match: (node) => editor.isTextBlock(node),
@@ -92,14 +67,6 @@ export const addAnnotationOperationImplementation: BehaviorOperationImplementati
92
67
  },
93
68
  {at: blockPath},
94
69
  )
95
-
96
- markDefPath = [{_key: block._key}, 'markDefs', {_key: annotationKey}]
97
-
98
- if (Range.isBackward(editor.selection)) {
99
- markDefPaths.unshift(markDefPath)
100
- } else {
101
- markDefPaths.push(markDefPath)
102
- }
103
70
  }
104
71
 
105
72
  Transforms.setNodes(editor, {}, {match: Text.isText, split: true})
@@ -124,20 +91,8 @@ export const addAnnotationOperationImplementation: BehaviorOperationImplementati
124
91
  },
125
92
  {at: path},
126
93
  )
127
-
128
- spanPath = [{_key: block._key}, 'children', {_key: span._key}]
129
94
  }
130
95
 
131
96
  blockIndex++
132
97
  }
133
-
134
- if (markDefPath && spanPath) {
135
- paths = {
136
- markDefPath,
137
- markDefPaths,
138
- spanPath,
139
- }
140
- }
141
-
142
- return paths
143
98
  }
@@ -51,7 +51,7 @@ export const blockSetOperationImplementation: BehaviorOperationImplementation<
51
51
  ...parsedBlock,
52
52
  ...filteredProps,
53
53
  },
54
- options: {refreshKeys: false, validateFields: true},
54
+ options: {validateFields: true},
55
55
  })
56
56
 
57
57
  if (!updatedBlock) {
@@ -51,7 +51,7 @@ export const blockUnsetOperationImplementation: BehaviorOperationImplementation<
51
51
  const updatedTextBlock = parseBlock({
52
52
  context,
53
53
  block: omit(parsedBlock, propsToRemove),
54
- options: {refreshKeys: false, validateFields: true},
54
+ options: {validateFields: true},
55
55
  })
56
56
 
57
57
  if (!updatedTextBlock) {
@@ -81,7 +81,7 @@ export const blockUnsetOperationImplementation: BehaviorOperationImplementation<
81
81
  parsedBlock,
82
82
  operation.props.filter((prop) => prop !== '_type'),
83
83
  ),
84
- options: {refreshKeys: false, validateFields: true},
84
+ options: {validateFields: true},
85
85
  })
86
86
 
87
87
  if (!updatedBlockObject) {
@@ -24,7 +24,7 @@ export const insertBlockOperationImplementation: BehaviorOperationImplementation
24
24
  const parsedBlock = parseBlock({
25
25
  block: operation.block,
26
26
  context,
27
- options: {refreshKeys: false, validateFields: true},
27
+ options: {validateFields: true},
28
28
  })
29
29
 
30
30
  if (!parsedBlock) {
@@ -32,14 +32,13 @@ export type BehaviorOperationImplementationContext = Pick<
32
32
 
33
33
  export type BehaviorOperationImplementation<
34
34
  TBehaviorOperationType extends BehaviorOperation['type'],
35
- TReturnType = void,
36
35
  > = ({
37
36
  context,
38
37
  operation,
39
38
  }: {
40
39
  context: BehaviorOperationImplementationContext
41
40
  operation: PickFromUnion<BehaviorOperation, 'type', TBehaviorOperationType>
42
- }) => TReturnType
41
+ }) => void
43
42
 
44
43
  type BehaviorOperation = OmitFromUnion<
45
44
  SyntheticBehaviorEvent,
@@ -1,117 +1,71 @@
1
- import {defineSchema} from '@portabletext/schema'
2
- import {createTestKeyGenerator, getTersePt} from '@portabletext/test'
3
- import {page, userEvent} from '@vitest/browser/context'
4
- import React from 'react'
1
+ import {getTersePt} from '@portabletext/test'
2
+ import {userEvent} from '@vitest/browser/context'
5
3
  import {describe, expect, test, vi} from 'vitest'
6
- import {render} from 'vitest-browser-react'
7
- import {EditorProvider, PortableTextEditable, type Editor} from '..'
8
- import {EditorRefPlugin} from './plugin.editor-ref'
4
+ import {createTestEditor} from '../internal-utils/test-editor'
9
5
  import {AutoCloseBracketsPlugin} from './plugin.internal.auto-close-brackets'
10
6
 
11
7
  describe(AutoCloseBracketsPlugin.name, () => {
12
8
  test('One-character text insertion', async () => {
13
- const editorRef = React.createRef<Editor>()
14
-
15
- render(
16
- <EditorProvider
17
- initialConfig={{
18
- keyGenerator: createTestKeyGenerator(),
19
- schemaDefinition: defineSchema({}),
20
- }}
21
- >
22
- <EditorRefPlugin ref={editorRef} />
23
- <PortableTextEditable />
24
- <AutoCloseBracketsPlugin />
25
- </EditorProvider>,
26
- )
27
-
28
- const locator = page.getByRole('textbox')
29
- await vi.waitFor(() => expect.element(locator).toBeInTheDocument())
9
+ const {editor, locator} = await createTestEditor({
10
+ children: <AutoCloseBracketsPlugin />,
11
+ })
12
+
30
13
  await userEvent.click(locator)
31
14
 
32
- editorRef.current?.send({type: 'insert.text', text: '('})
15
+ editor.send({type: 'insert.text', text: '('})
33
16
 
34
17
  await vi.waitFor(() => {
35
- expect(getTersePt(editorRef.current!.getSnapshot().context)).toEqual([
36
- '()',
37
- ])
18
+ expect(getTersePt(editor.getSnapshot().context)).toEqual(['()'])
38
19
  })
39
20
 
40
21
  await userEvent.type(locator, 'foo')
41
22
 
42
23
  await vi.waitFor(() => {
43
- expect(getTersePt(editorRef.current!.getSnapshot().context)).toEqual([
44
- '(foo)',
45
- ])
24
+ expect(getTersePt(editor.getSnapshot().context)).toEqual(['(foo)'])
46
25
  })
47
26
 
48
- editorRef.current?.send({type: 'history.undo'})
27
+ editor.send({type: 'history.undo'})
49
28
 
50
29
  await vi.waitFor(() => {
51
- expect(getTersePt(editorRef.current!.getSnapshot().context)).toEqual([
52
- '()',
53
- ])
30
+ expect(getTersePt(editor.getSnapshot().context)).toEqual(['()'])
54
31
  })
55
32
 
56
- editorRef.current?.send({type: 'history.undo'})
33
+ editor.send({type: 'history.undo'})
57
34
 
58
35
  await vi.waitFor(() => {
59
- expect(getTersePt(editorRef.current!.getSnapshot().context)).toEqual([
60
- '(',
61
- ])
36
+ expect(getTersePt(editor.getSnapshot().context)).toEqual(['('])
62
37
  })
63
38
  })
64
39
 
65
40
  test('Two-character text insertion', async () => {
66
- const editorRef = React.createRef<Editor>()
67
-
68
- render(
69
- <EditorProvider
70
- initialConfig={{
71
- keyGenerator: createTestKeyGenerator(),
72
- schemaDefinition: defineSchema({}),
73
- }}
74
- >
75
- <EditorRefPlugin ref={editorRef} />
76
- <PortableTextEditable />
77
- <AutoCloseBracketsPlugin />
78
- </EditorProvider>,
79
- )
80
-
81
- const locator = page.getByRole('textbox')
82
- await vi.waitFor(() => expect.element(locator).toBeInTheDocument())
41
+ const {editor, locator} = await createTestEditor({
42
+ children: <AutoCloseBracketsPlugin />,
43
+ })
44
+
83
45
  await userEvent.click(locator)
84
46
 
85
- editorRef.current?.send({type: 'insert.text', text: '(f'})
47
+ editor.send({type: 'insert.text', text: '(f'})
86
48
 
87
49
  await vi.waitFor(() => {
88
- expect(getTersePt(editorRef.current!.getSnapshot().context)).toEqual([
89
- '(f)',
90
- ])
50
+ expect(getTersePt(editor.getSnapshot().context)).toEqual(['(f)'])
91
51
  })
92
52
 
93
53
  await userEvent.type(locator, 'oo')
94
54
 
95
55
  await vi.waitFor(() => {
96
- expect(getTersePt(editorRef.current!.getSnapshot().context)).toEqual([
97
- '(foo)',
98
- ])
56
+ expect(getTersePt(editor.getSnapshot().context)).toEqual(['(foo)'])
99
57
  })
100
58
 
101
- editorRef.current?.send({type: 'history.undo'})
59
+ editor.send({type: 'history.undo'})
102
60
 
103
61
  await vi.waitFor(() => {
104
- expect(getTersePt(editorRef.current!.getSnapshot().context)).toEqual([
105
- '(f)',
106
- ])
62
+ expect(getTersePt(editor.getSnapshot().context)).toEqual(['(f)'])
107
63
  })
108
64
 
109
- editorRef.current?.send({type: 'history.undo'})
65
+ editor.send({type: 'history.undo'})
110
66
 
111
67
  await vi.waitFor(() => {
112
- expect(getTersePt(editorRef.current!.getSnapshot().context)).toEqual([
113
- '(f',
114
- ])
68
+ expect(getTersePt(editor.getSnapshot().context)).toEqual(['(f'])
115
69
  })
116
70
  })
117
71
  })
@@ -1,58 +1,40 @@
1
1
  import {defineSchema} from '@portabletext/schema'
2
- import {createTestKeyGenerator, getTersePt} from '@portabletext/test'
3
- import {page, userEvent} from '@vitest/browser/context'
4
- import React from 'react'
2
+ import {getTersePt} from '@portabletext/test'
3
+ import {userEvent} from '@vitest/browser/context'
5
4
  import {describe, expect, test, vi} from 'vitest'
6
- import {render} from 'vitest-browser-react'
7
- import {PortableTextEditable, type Editor} from '..'
8
- import {EditorProvider} from '../editor/editor-provider'
5
+ import {createTestEditor} from '../internal-utils/test-editor'
9
6
  import {getTextMarks} from '../internal-utils/text-marks'
10
- import {EditorRefPlugin} from './plugin.editor-ref'
11
7
  import {MarkdownPlugin} from './plugin.markdown'
12
8
 
13
9
  describe(MarkdownPlugin.name, () => {
14
10
  test('Scenario: Undoing bold shortcut', async () => {
15
- const editorRef = React.createRef<Editor>()
16
-
17
- render(
18
- <EditorProvider
19
- initialConfig={{
20
- keyGenerator: createTestKeyGenerator(),
21
- schemaDefinition: defineSchema({decorators: [{name: 'strong'}]}),
22
- }}
23
- >
24
- <EditorRefPlugin ref={editorRef} />
25
- <PortableTextEditable />
11
+ const {editor, locator} = await createTestEditor({
12
+ children: (
26
13
  <MarkdownPlugin
27
14
  config={{
28
15
  boldDecorator: () => 'strong',
29
16
  }}
30
17
  />
31
- </EditorProvider>,
32
- )
33
-
34
- const locator = page.getByRole('textbox')
35
-
36
- await vi.waitFor(() => expect.element(locator).toBeInTheDocument())
18
+ ),
19
+ schemaDefinition: defineSchema({decorators: [{name: 'strong'}]}),
20
+ })
37
21
 
38
22
  await userEvent.type(locator, '**Hello world!**')
39
23
 
40
24
  await vi.waitFor(() => {
41
- expect(getTersePt(editorRef.current!.getSnapshot().context)).toEqual([
42
- 'Hello world!',
43
- ])
25
+ expect(getTersePt(editor.getSnapshot().context)).toEqual(['Hello world!'])
44
26
  })
45
27
 
46
28
  await vi.waitFor(() => {
47
29
  expect(
48
- getTextMarks(editorRef.current!.getSnapshot().context, 'Hello world!'),
30
+ getTextMarks(editor.getSnapshot().context, 'Hello world!'),
49
31
  ).toEqual(['strong'])
50
32
  })
51
33
 
52
- editorRef.current?.send({type: 'history.undo'})
34
+ editor.send({type: 'history.undo'})
53
35
 
54
36
  await vi.waitFor(() => {
55
- expect(getTersePt(editorRef.current!.getSnapshot().context)).toEqual([
37
+ expect(getTersePt(editor.getSnapshot().context)).toEqual([
56
38
  '**Hello world!**',
57
39
  ])
58
40
  })