@portabletext/editor 1.0.11 → 1.0.13

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@portabletext/editor",
3
- "version": "1.0.11",
3
+ "version": "1.0.13",
4
4
  "description": "Portable Text Editor made in React",
5
5
  "keywords": [
6
6
  "sanity",
@@ -46,24 +46,25 @@
46
46
  "debug": "^4.3.4",
47
47
  "is-hotkey-esm": "^1.0.0",
48
48
  "lodash": "^4.17.21",
49
- "slate": "0.100.0",
50
- "slate-react": "0.101.0"
49
+ "slate": "0.103.0",
50
+ "slate-react": "0.107.1"
51
51
  },
52
52
  "devDependencies": {
53
53
  "@jest/globals": "^29.7.0",
54
- "@playwright/test": "1.45.3",
54
+ "@playwright/test": "1.46.0",
55
55
  "@portabletext/toolkit": "^2.0.15",
56
- "@sanity/block-tools": "^3.52.4",
56
+ "@sanity/block-tools": "^3.53.0",
57
57
  "@sanity/diff-match-patch": "^3.1.1",
58
58
  "@sanity/eslint-config-i18n": "^1.1.0",
59
59
  "@sanity/eslint-config-studio": "^4.0.0",
60
- "@sanity/pkg-utils": "^6.10.8",
61
- "@sanity/schema": "^3.52.4",
60
+ "@sanity/pkg-utils": "^6.10.9",
61
+ "@sanity/schema": "^3.53.0",
62
62
  "@sanity/test": "0.0.1-alpha.1",
63
- "@sanity/types": "^3.52.4",
63
+ "@sanity/types": "^3.53.0",
64
64
  "@sanity/ui": "^2.8.8",
65
- "@sanity/util": "^3.52.4",
66
- "@testing-library/react": "^13.4.0",
65
+ "@sanity/util": "^3.53.0",
66
+ "@testing-library/dom": "^10.4.0",
67
+ "@testing-library/react": "^16.0.0",
67
68
  "@types/debug": "^4.1.5",
68
69
  "@types/express": "^4.17.21",
69
70
  "@types/express-ws": "^3.0.4",
@@ -72,9 +73,9 @@
72
73
  "@types/node-ipc": "^9.2.3",
73
74
  "@types/react": "^18.3.3",
74
75
  "@types/react-dom": "^18.3.0",
75
- "@types/ws": "~8.5.11",
76
- "@typescript-eslint/eslint-plugin": "^7.17.0",
77
- "@typescript-eslint/parser": "^7.17.0",
76
+ "@types/ws": "~8.5.12",
77
+ "@typescript-eslint/eslint-plugin": "^8.0.1",
78
+ "@typescript-eslint/parser": "^8.0.1",
78
79
  "@vitejs/plugin-react": "^4.3.1",
79
80
  "dotenv": "^16.4.5",
80
81
  "eslint": "^8.57.0",
@@ -85,12 +86,12 @@
85
86
  "eslint-plugin-prettier": "^5.2.1",
86
87
  "eslint-plugin-react-compiler": "0.0.0-experimental-9ed098e-20240725",
87
88
  "eslint-plugin-tsdoc": "^0.3.0",
88
- "eslint-plugin-unicorn": "^54.0.0",
89
+ "eslint-plugin-unicorn": "^55.0.0",
89
90
  "eslint-plugin-unused-imports": "^4.0.1",
90
91
  "express": "^4.19.2",
91
92
  "express-ws": "^5.0.2",
92
93
  "jest": "^29.7.0",
93
- "jest-dev-server": "^9.0.2",
94
+ "jest-dev-server": "^10.0.0",
94
95
  "jest-environment-jsdom": "^29.7.0",
95
96
  "jest-environment-node": "^29.7.0",
96
97
  "node-ipc": "npm:@node-ipc/compat@9.2.5",
@@ -98,9 +99,9 @@
98
99
  "react-dom": "^18.3.1",
99
100
  "rxjs": "^7.8.1",
100
101
  "styled-components": "^6.1.12",
101
- "tsx": "^4.16.2",
102
+ "tsx": "^4.16.5",
102
103
  "typescript": "5.5.4",
103
- "vite": "^4.5.3"
104
+ "vite": "^5.3.5"
104
105
  },
105
106
  "peerDependencies": {
106
107
  "@sanity/block-tools": "^3.47.1",
@@ -127,6 +128,7 @@
127
128
  "lint:fix": "eslint . --fix",
128
129
  "test": "jest",
129
130
  "test:e2e": "jest --config=e2e-tests/e2e.config.cjs",
131
+ "test:e2e:watch": "jest --config=e2e-tests/e2e.config.cjs --watch",
130
132
  "test:watch": "jest --watch"
131
133
  }
132
134
  }
@@ -127,6 +127,14 @@ describe('initialization', () => {
127
127
  value={initialValue}
128
128
  />,
129
129
  )
130
+
131
+ await waitFor(() => {
132
+ if (editorRef.current) {
133
+ expect(onChange).toHaveBeenCalledWith({type: 'value', value: initialValue})
134
+ expect(onChange).toHaveBeenCalledWith({type: 'ready'})
135
+ }
136
+ })
137
+
130
138
  await waitFor(() => {
131
139
  if (editorRef.current) {
132
140
  PortableTextEditor.focus(editorRef.current)
@@ -158,10 +166,16 @@ describe('initialization', () => {
158
166
  value={initialValue}
159
167
  />,
160
168
  )
169
+
161
170
  await waitFor(() => {
162
171
  if (editorRef.current) {
163
- expect(onChange).toHaveBeenCalledWith({type: 'ready'})
164
172
  expect(onChange).toHaveBeenCalledWith({type: 'value', value: initialValue})
173
+ expect(onChange).toHaveBeenCalledWith({type: 'ready'})
174
+ }
175
+ })
176
+
177
+ await waitFor(() => {
178
+ if (editorRef.current) {
165
179
  const sel = PortableTextEditor.getSelection(editorRef.current)
166
180
  PortableTextEditor.focus(editorRef.current)
167
181
 
@@ -44,16 +44,22 @@ describe('adds empty text block if its needed', () => {
44
44
  value={initialValue}
45
45
  />,
46
46
  )
47
+
48
+ await waitFor(() => {
49
+ if (editorRef.current) {
50
+ expect(onChange).toHaveBeenCalledWith({type: 'value', value: initialValue})
51
+ expect(onChange).toHaveBeenCalledWith({type: 'ready'})
52
+ }
53
+ })
54
+
47
55
  const element = await getEditableElement(component)
48
56
 
49
- const editor = editorRef.current
50
- const inlineType = editor?.schemaTypes.inlineObjects.find((t) => t.name === 'someObject')
51
57
  await waitFor(async () => {
52
- if (editor && inlineType && element) {
53
- PortableTextEditor.focus(editor)
54
- PortableTextEditor.select(editor, initialSelection)
58
+ if (editorRef.current && element) {
59
+ PortableTextEditor.focus(editorRef.current)
60
+ PortableTextEditor.select(editorRef.current, initialSelection)
55
61
  fireEvent.click(element)
56
- expect(PortableTextEditor.getValue(editor)).toEqual([initialValue[0], newBlock])
62
+ expect(PortableTextEditor.getValue(editorRef.current)).toEqual([initialValue[0], newBlock])
57
63
  }
58
64
  })
59
65
  })
@@ -96,17 +102,16 @@ describe('adds empty text block if its needed', () => {
96
102
  )
97
103
  const element = await getEditableElement(component)
98
104
 
99
- const editor = editorRef.current
100
- const inlineType = editor?.schemaTypes.inlineObjects.find((t) => t.name === 'someObject')
101
105
  await waitFor(async () => {
102
- if (editor && inlineType && element) {
103
- PortableTextEditor.focus(editor)
104
- PortableTextEditor.select(editor, initialSelection)
106
+ if (editorRef.current && element) {
107
+ PortableTextEditor.focus(editorRef.current)
108
+ PortableTextEditor.select(editorRef.current, initialSelection)
105
109
  fireEvent.click(element)
106
- expect(PortableTextEditor.getValue(editor)).toEqual(initialValue)
110
+ expect(PortableTextEditor.getValue(editorRef.current)).toEqual(initialValue)
107
111
  }
108
112
  })
109
113
  })
114
+
110
115
  it('should not add blocks if the last element is void, but its not focused on that one', async () => {
111
116
  const initialValue = [
112
117
  {
@@ -134,8 +139,8 @@ describe('adds empty text block if its needed', () => {
134
139
  ]
135
140
 
136
141
  const initialSelection = {
137
- focus: {path: [{_key: 'b'}, 'children', {_key: 'b1'}], offset: 2},
138
- anchor: {path: [{_key: 'b'}, 'children', {_key: 'b1'}], offset: 2},
142
+ focus: {path: [{_key: 'b'}, 'children', {_key: 'b1'}], offset: 0},
143
+ anchor: {path: [{_key: 'b'}, 'children', {_key: 'b1'}], offset: 0},
139
144
  }
140
145
 
141
146
  const editorRef: RefObject<PortableTextEditor> = createRef()
@@ -148,19 +153,26 @@ describe('adds empty text block if its needed', () => {
148
153
  value={initialValue}
149
154
  />,
150
155
  )
156
+
157
+ await waitFor(() => {
158
+ if (editorRef.current) {
159
+ expect(onChange).toHaveBeenCalledWith({type: 'value', value: initialValue})
160
+ expect(onChange).toHaveBeenCalledWith({type: 'ready'})
161
+ }
162
+ })
163
+
151
164
  const element = await getEditableElement(component)
152
165
 
153
- const editor = editorRef.current
154
- const inlineType = editor?.schemaTypes.inlineObjects.find((t) => t.name === 'someObject')
155
166
  await waitFor(async () => {
156
- if (editor && inlineType && element) {
157
- PortableTextEditor.focus(editor)
158
- PortableTextEditor.select(editor, initialSelection)
167
+ if (editorRef.current && element) {
168
+ PortableTextEditor.focus(editorRef.current)
169
+ PortableTextEditor.select(editorRef.current, initialSelection)
159
170
  fireEvent.click(element)
160
- expect(PortableTextEditor.getValue(editor)).toEqual(initialValue)
171
+ expect(PortableTextEditor.getValue(editorRef.current)).toEqual(initialValue)
161
172
  }
162
173
  })
163
174
  })
175
+
164
176
  it('should not add blocks if the last element is void, and its focused on that one when clicking', async () => {
165
177
  const initialValue = [
166
178
  {
@@ -202,6 +214,14 @@ describe('adds empty text block if its needed', () => {
202
214
  value={initialValue}
203
215
  />,
204
216
  )
217
+
218
+ await waitFor(() => {
219
+ if (editorRef.current) {
220
+ expect(onChange).toHaveBeenCalledWith({type: 'value', value: initialValue})
221
+ expect(onChange).toHaveBeenCalledWith({type: 'ready'})
222
+ }
223
+ })
224
+
205
225
  const element = await getEditableElement(component)
206
226
 
207
227
  const editor = editorRef.current
@@ -1,23 +1,22 @@
1
1
  // This utils are inspired from https://github.dev/mwood23/slate-test-utils/blob/master/src/buildTestHarness.tsx
2
- import {act, fireEvent, type render} from '@testing-library/react'
2
+ import {fireEvent, type render} from '@testing-library/react'
3
3
  import {parseHotkey} from 'is-hotkey-esm'
4
+ import {act} from 'react'
4
5
 
5
6
  export async function triggerKeyboardEvent(hotkey: string, element: Element): Promise<void> {
6
- return act(async () => {
7
- const eventProps = parseHotkey(hotkey)
8
- const values = hotkey.split('+')
7
+ const eventProps = parseHotkey(hotkey)
8
+ const values = hotkey.split('+')
9
9
 
10
- fireEvent(
11
- element,
12
- new window.KeyboardEvent('keydown', {
13
- key: values[values.length - 1],
14
- code: `${eventProps.which}`,
15
- keyCode: eventProps.which,
16
- bubbles: true,
17
- ...eventProps,
18
- }),
19
- )
20
- })
10
+ fireEvent(
11
+ element,
12
+ new window.KeyboardEvent('keydown', {
13
+ key: values[values.length - 1],
14
+ code: `${eventProps.which}`,
15
+ keyCode: eventProps.which,
16
+ bubbles: true,
17
+ ...eventProps,
18
+ }),
19
+ )
21
20
  }
22
21
 
23
22
  export async function getEditableElement(component: ReturnType<typeof render>): Promise<Element> {
@@ -53,6 +53,14 @@ describe('plugin:withEditableAPI: .delete()', () => {
53
53
  value={initialValue}
54
54
  />,
55
55
  )
56
+
57
+ await waitFor(() => {
58
+ if (editorRef.current) {
59
+ expect(onChange).toHaveBeenCalledWith({type: 'value', value: initialValue})
60
+ expect(onChange).toHaveBeenCalledWith({type: 'ready'})
61
+ }
62
+ })
63
+
56
64
  await waitFor(() => {
57
65
  if (editorRef.current) {
58
66
  PortableTextEditor.focus(editorRef.current)
@@ -95,6 +103,7 @@ describe('plugin:withEditableAPI: .delete()', () => {
95
103
  value={initialValue}
96
104
  />,
97
105
  )
106
+
98
107
  await waitFor(() => {
99
108
  expect(onChange).toHaveBeenCalledWith({type: 'value', value: initialValue})
100
109
  expect(onChange).toHaveBeenCalledWith({type: 'ready'})
@@ -140,6 +149,7 @@ describe('plugin:withEditableAPI: .delete()', () => {
140
149
  it('deletes children', async () => {
141
150
  const editorRef: RefObject<PortableTextEditor> = createRef()
142
151
  const onChange = jest.fn()
152
+
143
153
  render(
144
154
  <PortableTextEditorTester
145
155
  onChange={onChange}
@@ -149,18 +159,34 @@ describe('plugin:withEditableAPI: .delete()', () => {
149
159
  />,
150
160
  )
151
161
 
162
+ await waitFor(() => {
163
+ if (editorRef.current) {
164
+ expect(onChange).toHaveBeenCalledWith({type: 'value', value: initialValue})
165
+ expect(onChange).toHaveBeenCalledWith({type: 'ready'})
166
+ }
167
+ })
168
+
152
169
  await waitFor(() => {
153
170
  if (editorRef.current) {
154
171
  PortableTextEditor.select(editorRef.current, {
155
172
  focus: {path: [{_key: 'b'}, 'children', {_key: 'b1'}], offset: 5},
156
173
  anchor: {path: [{_key: 'b'}, 'children', {_key: 'b1'}], offset: 7},
157
174
  })
158
- PortableTextEditor.focus(editorRef.current)
175
+ }
176
+ })
177
+
178
+ await waitFor(() => {
179
+ if (editorRef.current) {
159
180
  PortableTextEditor.delete(
160
181
  editorRef.current,
161
182
  PortableTextEditor.getSelection(editorRef.current),
162
183
  {mode: 'children'},
163
184
  )
185
+ }
186
+ })
187
+
188
+ await waitFor(() => {
189
+ if (editorRef.current) {
164
190
  expect(PortableTextEditor.getValue(editorRef.current)).toMatchInlineSnapshot(`
165
191
  Array [
166
192
  Object {
@@ -196,9 +222,11 @@ describe('plugin:withEditableAPI: .delete()', () => {
196
222
  }
197
223
  })
198
224
  })
225
+
199
226
  it('deletes selected', async () => {
200
227
  const editorRef: RefObject<PortableTextEditor> = createRef()
201
228
  const onChange = jest.fn()
229
+
202
230
  render(
203
231
  <PortableTextEditorTester
204
232
  onChange={onChange}
@@ -208,36 +236,50 @@ describe('plugin:withEditableAPI: .delete()', () => {
208
236
  />,
209
237
  )
210
238
 
239
+ await waitFor(() => {
240
+ if (editorRef.current) {
241
+ expect(onChange).toHaveBeenCalledWith({type: 'value', value: initialValue})
242
+ expect(onChange).toHaveBeenCalledWith({type: 'ready'})
243
+ }
244
+ })
245
+
211
246
  await waitFor(() => {
212
247
  if (editorRef.current) {
213
248
  PortableTextEditor.select(editorRef.current, {
214
249
  focus: {path: [{_key: 'b'}, 'children', {_key: 'b1'}], offset: 5},
215
250
  anchor: {path: [{_key: 'a'}, 'children', {_key: 'a1'}], offset: 0},
216
251
  })
217
- PortableTextEditor.focus(editorRef.current)
252
+ }
253
+ })
254
+
255
+ await waitFor(() => {
256
+ if (editorRef.current) {
218
257
  PortableTextEditor.delete(
219
258
  editorRef.current,
220
259
  PortableTextEditor.getSelection(editorRef.current),
221
260
  {mode: 'selected'},
222
261
  )
223
- expect(PortableTextEditor.getValue(editorRef.current)).toMatchInlineSnapshot(`
224
- Array [
225
- Object {
226
- "_key": "b",
227
- "_type": "myTestBlockType",
228
- "children": Array [
229
- Object {
230
- "_key": "b1",
231
- "_type": "span",
232
- "marks": Array [],
233
- "text": " B",
234
- },
235
- ],
236
- "markDefs": Array [],
237
- "style": "normal",
238
- },
239
- ]
240
- `)
262
+ }
263
+ })
264
+
265
+ await waitFor(() => {
266
+ if (editorRef.current) {
267
+ expect(PortableTextEditor.getValue(editorRef.current)).toEqual([
268
+ {
269
+ _key: 'b',
270
+ _type: 'myTestBlockType',
271
+ children: [
272
+ {
273
+ _key: 'b1',
274
+ _type: 'span',
275
+ marks: [],
276
+ text: ' B',
277
+ },
278
+ ],
279
+ markDefs: [],
280
+ style: 'normal',
281
+ },
282
+ ])
241
283
  }
242
284
  })
243
285
  })
@@ -51,6 +51,7 @@ describe('plugin:withEditableAPI: .getFragment()', () => {
51
51
  it('can get a Portable Text fragment of the current selection in a single block', async () => {
52
52
  const editorRef: RefObject<PortableTextEditor> = createRef()
53
53
  const onChange = jest.fn()
54
+
54
55
  render(
55
56
  <PortableTextEditorTester
56
57
  onChange={onChange}
@@ -63,6 +64,14 @@ describe('plugin:withEditableAPI: .getFragment()', () => {
63
64
  focus: {path: [{_key: 'a'}, 'children', {_key: 'a1'}], offset: 6},
64
65
  anchor: {path: [{_key: 'a'}, 'children', {_key: 'a1'}], offset: 7},
65
66
  }
67
+
68
+ await waitFor(() => {
69
+ if (editorRef.current) {
70
+ expect(onChange).toHaveBeenCalledWith({type: 'value', value: initialValue})
71
+ expect(onChange).toHaveBeenCalledWith({type: 'ready'})
72
+ }
73
+ })
74
+
66
75
  await waitFor(() => {
67
76
  if (editorRef.current) {
68
77
  PortableTextEditor.focus(editorRef.current)
@@ -74,9 +83,11 @@ describe('plugin:withEditableAPI: .getFragment()', () => {
74
83
  }
75
84
  })
76
85
  })
86
+
77
87
  it('can get a Portable Text fragment of the current selection in multiple blocks', async () => {
78
88
  const editorRef: RefObject<PortableTextEditor> = createRef()
79
89
  const onChange = jest.fn()
90
+
80
91
  render(
81
92
  <PortableTextEditorTester
82
93
  onChange={onChange}
@@ -89,6 +100,14 @@ describe('plugin:withEditableAPI: .getFragment()', () => {
89
100
  anchor: {path: [{_key: 'a'}, 'children', {_key: 'a1'}], offset: 6},
90
101
  focus: {path: [{_key: 'b'}, 'children', {_key: 'b3'}], offset: 9},
91
102
  }
103
+
104
+ await waitFor(() => {
105
+ if (editorRef.current) {
106
+ expect(onChange).toHaveBeenCalledWith({type: 'value', value: initialValue})
107
+ expect(onChange).toHaveBeenCalledWith({type: 'ready'})
108
+ }
109
+ })
110
+
92
111
  await waitFor(() => {
93
112
  if (editorRef.current) {
94
113
  PortableTextEditor.focus(editorRef.current)