@portabletext/editor 1.4.1 → 1.5.1
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 +341 -1
- package/lib/index.d.mts +106 -29
- package/lib/index.d.ts +106 -29
- package/lib/index.esm.js +119 -63
- package/lib/index.esm.js.map +1 -1
- package/lib/index.js +118 -63
- package/lib/index.js.map +1 -1
- package/lib/index.mjs +119 -63
- package/lib/index.mjs.map +1 -1
- package/package.json +4 -2
- package/src/editor/PortableTextEditor.tsx +8 -11
- package/src/editor/define-schema.ts +111 -0
- package/src/editor/plugins/createWithEditableAPI.ts +11 -5
- package/src/editor/use-editor.ts +19 -7
- package/src/index.ts +11 -5
- package/src/types/editor.ts +9 -9
package/README.md
CHANGED
|
@@ -10,8 +10,348 @@
|
|
|
10
10
|
> The official editor for editing [Portable Text](https://github.com/portabletext/portabletext) – the JSON based rich text specification for modern content editing platforms.
|
|
11
11
|
|
|
12
12
|
> [!NOTE]
|
|
13
|
-
> We are currently working hard on the general release of this component.
|
|
13
|
+
> We are currently working hard on the general release of this component. Better docs and refined APIs are coming.
|
|
14
14
|
|
|
15
15
|
## End-User Experience
|
|
16
16
|
|
|
17
17
|
In order to provide a robust and consistent end-user experience, the editor is backed by an elaborate E2E test suite generated from a [human-readable Gherkin spec](/packages/editor/gherkin-spec/).
|
|
18
|
+
|
|
19
|
+
## Build Your Own Portable Text Editor
|
|
20
|
+
|
|
21
|
+
Check [/examples/basic/src/App.tsx](/examples/basic/src/App.tsx) for a basic example of how to set up the edior. Most of the source code from this example app can also be found in the instructions below.
|
|
22
|
+
|
|
23
|
+
### Define the Schema
|
|
24
|
+
|
|
25
|
+
The first thing to do is to define the editor schema definition. The schema definition is later passed into the editor where it's compiled and used in various callbacks and render functions.
|
|
26
|
+
|
|
27
|
+
```ts
|
|
28
|
+
// All options are optional
|
|
29
|
+
// Only the `name` property is required, but you can define a `title` and an `icon` as well
|
|
30
|
+
// You can use this schema definition later to build your toolbar
|
|
31
|
+
const schemaDefinition = defineSchema({
|
|
32
|
+
// Decorators are simple marks that don't hold any data
|
|
33
|
+
decorators: [{name: 'strong'}, {name: 'em'}, {name: 'underline'}],
|
|
34
|
+
// Annotations are more complex marks that can hold data
|
|
35
|
+
annotations: [{name: 'link'}],
|
|
36
|
+
// Styles apply to entire text blocks
|
|
37
|
+
// There's always a 'normal' style that can be considered the paragraph style
|
|
38
|
+
styles: [
|
|
39
|
+
{name: 'normal'},
|
|
40
|
+
{name: 'h1'},
|
|
41
|
+
{name: 'h2'},
|
|
42
|
+
{name: 'h3'},
|
|
43
|
+
{name: 'blockqoute'},
|
|
44
|
+
],
|
|
45
|
+
// Lists apply to entire text blocks as well
|
|
46
|
+
lists: [{name: 'bullet'}, {name: 'number'}],
|
|
47
|
+
// Inline objects hold arbitrary data that can be inserted into the text
|
|
48
|
+
inlineObjects: [{name: 'stock-ticker'}],
|
|
49
|
+
// Block objects hold arbitrary data that live side-by-side with text blocks
|
|
50
|
+
blockObjects: [{name: 'image'}],
|
|
51
|
+
})
|
|
52
|
+
```
|
|
53
|
+
|
|
54
|
+
### Render the Editor Component
|
|
55
|
+
|
|
56
|
+
Use `useEditor` to create an `editor` and pass that into `PortableTextEditor`. Use the `editor.on` method to listen for `mutation` changes inside the editor so you can use and store the value produced.
|
|
57
|
+
|
|
58
|
+
```tsx
|
|
59
|
+
function App() {
|
|
60
|
+
// Creata an editor
|
|
61
|
+
const editor = useEditor({
|
|
62
|
+
schemaDefinition,
|
|
63
|
+
})
|
|
64
|
+
|
|
65
|
+
const [value, setValue] = useState<Array<PortableTextBlock> | undefined>(
|
|
66
|
+
undefined,
|
|
67
|
+
)
|
|
68
|
+
|
|
69
|
+
// Subscribe to editor changes
|
|
70
|
+
useEffect(() => {
|
|
71
|
+
const subscription = editor.on('mutation', (mutation) => {
|
|
72
|
+
setValue(mutation.snapshot)
|
|
73
|
+
})
|
|
74
|
+
|
|
75
|
+
return () => {
|
|
76
|
+
subscription.unsubscribe()
|
|
77
|
+
}
|
|
78
|
+
}, [editor])
|
|
79
|
+
|
|
80
|
+
return (
|
|
81
|
+
<>
|
|
82
|
+
<PortableTextEditor
|
|
83
|
+
// Pass in the `editor` you created earlier
|
|
84
|
+
editor={editor}
|
|
85
|
+
// And an optional value
|
|
86
|
+
value={value}
|
|
87
|
+
>
|
|
88
|
+
{/* Toolbar needs to be rendered inside the `PortableTextEditor` component */}
|
|
89
|
+
<Toolbar />
|
|
90
|
+
{/* Component that controls the actual rendering of the editor */}
|
|
91
|
+
<PortableTextEditable
|
|
92
|
+
style={{border: '1px solid black', padding: '0.5em'}}
|
|
93
|
+
// Control how decorators are rendered
|
|
94
|
+
renderDecorator={renderDecorator}
|
|
95
|
+
// Control how annotations are rendered
|
|
96
|
+
renderAnnotation={renderAnnotation}
|
|
97
|
+
// Required to render block objects but also to make `renderStyle` take effect
|
|
98
|
+
renderBlock={renderBlock}
|
|
99
|
+
// Control how styles are rendered
|
|
100
|
+
renderStyle={renderStyle}
|
|
101
|
+
// Control how inline objects are rendered
|
|
102
|
+
renderChild={renderChild}
|
|
103
|
+
// Rendering lists is harder and most likely requires a fair amount of CSS
|
|
104
|
+
// However, we still need to return and render the list item's children to ensure proper rendering
|
|
105
|
+
renderListItem={(props) => <>{props.children}</>}
|
|
106
|
+
/>
|
|
107
|
+
</PortableTextEditor>
|
|
108
|
+
<pre style={{border: '1px dashed black', padding: '0.5em'}}>
|
|
109
|
+
{JSON.stringify(value, null, 2)}
|
|
110
|
+
</pre>
|
|
111
|
+
</>
|
|
112
|
+
)
|
|
113
|
+
}
|
|
114
|
+
```
|
|
115
|
+
|
|
116
|
+
### Render Marks, Blocks and Objects
|
|
117
|
+
|
|
118
|
+
All the different render functions passed to `PortableTextEditable` can be defined as stand-alone React components. Most of these are fairly straightforward to render because everything you need is provided via `props`. However, lists are a little special. Since Portable Text has no concept of block nesting, the easiest way get something looking like lists is with pure CSS. Head over to [/examples/basic/src/editor.css](/examples/basic/src/editor.css) for a full example.
|
|
119
|
+
|
|
120
|
+
```tsx
|
|
121
|
+
const renderDecorator: RenderDecoratorFunction = (props) => {
|
|
122
|
+
if (props.value === 'strong') {
|
|
123
|
+
return <strong>{props.children}</strong>
|
|
124
|
+
}
|
|
125
|
+
if (props.value === 'em') {
|
|
126
|
+
return <em>{props.children}</em>
|
|
127
|
+
}
|
|
128
|
+
if (props.value === 'underline') {
|
|
129
|
+
return <u>{props.children}</u>
|
|
130
|
+
}
|
|
131
|
+
return <>{props.children}</>
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
const renderAnnotation: RenderAnnotationFunction = (props) => {
|
|
135
|
+
if (props.schemaType.name === 'link') {
|
|
136
|
+
return <span style={{textDecoration: 'underline'}}>{props.children}</span>
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
return <>{props.children}</>
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
const renderBlock: RenderBlockFunction = (props) => {
|
|
143
|
+
if (props.schemaType.name === 'image' && isImage(props.value)) {
|
|
144
|
+
return (
|
|
145
|
+
<div
|
|
146
|
+
style={{
|
|
147
|
+
border: '1px dotted grey',
|
|
148
|
+
padding: '0.25em',
|
|
149
|
+
marginBlockEnd: '0.25em',
|
|
150
|
+
}}
|
|
151
|
+
>
|
|
152
|
+
IMG: {props.value.src}
|
|
153
|
+
</div>
|
|
154
|
+
)
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
return <div style={{marginBlockEnd: '0.25em'}}>{props.children}</div>
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
function isImage(
|
|
161
|
+
props: PortableTextBlock,
|
|
162
|
+
): props is PortableTextBlock & {src: string} {
|
|
163
|
+
return 'src' in props
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
const renderStyle: RenderStyleFunction = (props) => {
|
|
167
|
+
if (props.schemaType.value === 'h1') {
|
|
168
|
+
return <h1>{props.children}</h1>
|
|
169
|
+
}
|
|
170
|
+
if (props.schemaType.value === 'h2') {
|
|
171
|
+
return <h2>{props.children}</h2>
|
|
172
|
+
}
|
|
173
|
+
if (props.schemaType.value === 'h3') {
|
|
174
|
+
return <h3>{props.children}</h3>
|
|
175
|
+
}
|
|
176
|
+
if (props.schemaType.value === 'blockquote') {
|
|
177
|
+
return <blockquote>{props.children}</blockquote>
|
|
178
|
+
}
|
|
179
|
+
return <>{props.children}</>
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
const renderChild: RenderChildFunction = (props) => {
|
|
183
|
+
if (props.schemaType.name === 'stock-ticker' && isStockTicker(props.value)) {
|
|
184
|
+
return (
|
|
185
|
+
<span
|
|
186
|
+
style={{
|
|
187
|
+
border: '1px dotted grey',
|
|
188
|
+
padding: '0.15em',
|
|
189
|
+
}}
|
|
190
|
+
>
|
|
191
|
+
{props.value.symbol}
|
|
192
|
+
</span>
|
|
193
|
+
)
|
|
194
|
+
}
|
|
195
|
+
|
|
196
|
+
return <>{props.children}</>
|
|
197
|
+
}
|
|
198
|
+
|
|
199
|
+
function isStockTicker(
|
|
200
|
+
props: PortableTextChild,
|
|
201
|
+
): props is PortableTextChild & {symbol: string} {
|
|
202
|
+
return 'symbol' in props
|
|
203
|
+
}
|
|
204
|
+
```
|
|
205
|
+
|
|
206
|
+
### Render the Toolbar
|
|
207
|
+
|
|
208
|
+
Your toolbar needs to be rendered within `PortableTextEditor` because it requires a reference to the `editorInstance` that it produces. To toggle marks and styles and to insert objects, you'll have to use this `editorInstance` together with static methods on the `PortableTextEditor` class.
|
|
209
|
+
|
|
210
|
+
```tsx
|
|
211
|
+
function Toolbar() {
|
|
212
|
+
// Obtain the editor instance provided from the `PortableTextEditor` component
|
|
213
|
+
const editorInstance = usePortableTextEditor()
|
|
214
|
+
// Rerender the toolbar whenever the selection changes
|
|
215
|
+
usePortableTextEditorSelection()
|
|
216
|
+
|
|
217
|
+
const decoratorButtons = schemaDefinition.decorators.map((decorator) => {
|
|
218
|
+
return (
|
|
219
|
+
<button
|
|
220
|
+
key={decorator.name}
|
|
221
|
+
style={{
|
|
222
|
+
textDecoration: PortableTextEditor.isMarkActive(
|
|
223
|
+
editorInstance,
|
|
224
|
+
decorator.name,
|
|
225
|
+
)
|
|
226
|
+
? 'underline'
|
|
227
|
+
: 'unset',
|
|
228
|
+
}}
|
|
229
|
+
onClick={() => {
|
|
230
|
+
// Toggle the decorator by name
|
|
231
|
+
PortableTextEditor.toggleMark(editorInstance, decorator.name)
|
|
232
|
+
// Pressing this button steals focus so let's focus the editor again
|
|
233
|
+
PortableTextEditor.focus(editorInstance)
|
|
234
|
+
}}
|
|
235
|
+
>
|
|
236
|
+
{decorator.name}
|
|
237
|
+
</button>
|
|
238
|
+
)
|
|
239
|
+
})
|
|
240
|
+
|
|
241
|
+
const linkButton = (
|
|
242
|
+
<button
|
|
243
|
+
style={{
|
|
244
|
+
textDecoration: PortableTextEditor.isAnnotationActive(
|
|
245
|
+
editorInstance,
|
|
246
|
+
schemaDefinition.annotations[0].name,
|
|
247
|
+
)
|
|
248
|
+
? 'underline'
|
|
249
|
+
: 'unset',
|
|
250
|
+
}}
|
|
251
|
+
onClick={() => {
|
|
252
|
+
if (
|
|
253
|
+
PortableTextEditor.isAnnotationActive(
|
|
254
|
+
editorInstance,
|
|
255
|
+
schemaDefinition.annotations[0].name,
|
|
256
|
+
)
|
|
257
|
+
) {
|
|
258
|
+
PortableTextEditor.removeAnnotation(
|
|
259
|
+
editorInstance,
|
|
260
|
+
schemaDefinition.annotations[0],
|
|
261
|
+
)
|
|
262
|
+
} else {
|
|
263
|
+
PortableTextEditor.addAnnotation(
|
|
264
|
+
editorInstance,
|
|
265
|
+
schemaDefinition.annotations[0],
|
|
266
|
+
{href: 'https://example.com'},
|
|
267
|
+
)
|
|
268
|
+
}
|
|
269
|
+
PortableTextEditor.focus(editorInstance)
|
|
270
|
+
}}
|
|
271
|
+
>
|
|
272
|
+
link
|
|
273
|
+
</button>
|
|
274
|
+
)
|
|
275
|
+
|
|
276
|
+
const styleButtons = schemaDefinition.styles.map((style) => (
|
|
277
|
+
<button
|
|
278
|
+
key={style.name}
|
|
279
|
+
style={{
|
|
280
|
+
textDecoration: PortableTextEditor.hasBlockStyle(
|
|
281
|
+
editorInstance,
|
|
282
|
+
style.name,
|
|
283
|
+
)
|
|
284
|
+
? 'underline'
|
|
285
|
+
: 'unset',
|
|
286
|
+
}}
|
|
287
|
+
onClick={() => {
|
|
288
|
+
PortableTextEditor.toggleBlockStyle(editorInstance, style.name)
|
|
289
|
+
PortableTextEditor.focus(editorInstance)
|
|
290
|
+
}}
|
|
291
|
+
>
|
|
292
|
+
{style.name}
|
|
293
|
+
</button>
|
|
294
|
+
))
|
|
295
|
+
|
|
296
|
+
const listButtons = schemaDefinition.lists.map((list) => (
|
|
297
|
+
<button
|
|
298
|
+
key={list.name}
|
|
299
|
+
style={{
|
|
300
|
+
textDecoration: PortableTextEditor.hasListStyle(
|
|
301
|
+
editorInstance,
|
|
302
|
+
list.name,
|
|
303
|
+
)
|
|
304
|
+
? 'underline'
|
|
305
|
+
: 'unset',
|
|
306
|
+
}}
|
|
307
|
+
onClick={() => {
|
|
308
|
+
PortableTextEditor.toggleList(editorInstance, list.name)
|
|
309
|
+
PortableTextEditor.focus(editorInstance)
|
|
310
|
+
}}
|
|
311
|
+
>
|
|
312
|
+
{list.name}
|
|
313
|
+
</button>
|
|
314
|
+
))
|
|
315
|
+
|
|
316
|
+
const imageButton = (
|
|
317
|
+
<button
|
|
318
|
+
onClick={() => {
|
|
319
|
+
PortableTextEditor.insertBlock(
|
|
320
|
+
editorInstance,
|
|
321
|
+
schemaDefinition.blockObjects[0],
|
|
322
|
+
{src: 'https://example.com/image.jpg'},
|
|
323
|
+
)
|
|
324
|
+
PortableTextEditor.focus(editorInstance)
|
|
325
|
+
}}
|
|
326
|
+
>
|
|
327
|
+
{schemaDefinition.blockObjects[0].name}
|
|
328
|
+
</button>
|
|
329
|
+
)
|
|
330
|
+
|
|
331
|
+
const stockTickerButton = (
|
|
332
|
+
<button
|
|
333
|
+
onClick={() => {
|
|
334
|
+
PortableTextEditor.insertChild(
|
|
335
|
+
editorInstance,
|
|
336
|
+
schemaDefinition.inlineObjects[0],
|
|
337
|
+
{symbol: 'AAPL'},
|
|
338
|
+
)
|
|
339
|
+
PortableTextEditor.focus(editorInstance)
|
|
340
|
+
}}
|
|
341
|
+
>
|
|
342
|
+
{schemaDefinition.inlineObjects[0].name}
|
|
343
|
+
</button>
|
|
344
|
+
)
|
|
345
|
+
|
|
346
|
+
return (
|
|
347
|
+
<>
|
|
348
|
+
<div>{decoratorButtons}</div>
|
|
349
|
+
<div>{linkButton}</div>
|
|
350
|
+
<div>{styleButtons}</div>
|
|
351
|
+
<div>{listButtons}</div>
|
|
352
|
+
<div>{imageButton}</div>
|
|
353
|
+
<div>{stockTickerButton}</div>
|
|
354
|
+
</>
|
|
355
|
+
)
|
|
356
|
+
}
|
|
357
|
+
```
|
package/lib/index.d.mts
CHANGED
|
@@ -2,21 +2,22 @@ import {Patch} from '@portabletext/patches'
|
|
|
2
2
|
import type {
|
|
3
3
|
ArrayDefinition,
|
|
4
4
|
ArraySchemaType,
|
|
5
|
-
BlockDecoratorDefinition,
|
|
6
5
|
BlockListDefinition,
|
|
7
|
-
BlockSchemaType,
|
|
8
6
|
BlockStyleDefinition,
|
|
9
7
|
KeyedSegment,
|
|
10
8
|
ObjectSchemaType,
|
|
11
9
|
Path,
|
|
12
|
-
PortableTextBlock,
|
|
13
|
-
PortableTextChild,
|
|
14
10
|
PortableTextListBlock,
|
|
15
11
|
PortableTextObject,
|
|
16
|
-
SpanSchemaType,
|
|
17
12
|
TypedObject,
|
|
18
13
|
} from '@sanity/types'
|
|
19
|
-
import {
|
|
14
|
+
import {
|
|
15
|
+
BlockDecoratorDefinition,
|
|
16
|
+
PortableTextBlock,
|
|
17
|
+
PortableTextChild,
|
|
18
|
+
PortableTextSpan,
|
|
19
|
+
PortableTextTextBlock,
|
|
20
|
+
} from '@sanity/types'
|
|
20
21
|
import type {
|
|
21
22
|
BaseSyntheticEvent,
|
|
22
23
|
ClipboardEvent as ClipboardEvent_2,
|
|
@@ -64,6 +65,15 @@ import {
|
|
|
64
65
|
Values,
|
|
65
66
|
} from 'xstate'
|
|
66
67
|
|
|
68
|
+
/**
|
|
69
|
+
* @alpha
|
|
70
|
+
*/
|
|
71
|
+
export declare type BaseDefinition = {
|
|
72
|
+
name: string
|
|
73
|
+
title?: string
|
|
74
|
+
icon?: BlockDecoratorDefinition['icon']
|
|
75
|
+
}
|
|
76
|
+
|
|
67
77
|
/**
|
|
68
78
|
* @alpha
|
|
69
79
|
*/
|
|
@@ -303,10 +313,10 @@ export declare type createEditorOptions = {
|
|
|
303
313
|
export declare function createMarkdownBehaviors(
|
|
304
314
|
config: MarkdownBehaviorsConfig,
|
|
305
315
|
): Behavior<
|
|
306
|
-
| 'insert break'
|
|
307
|
-
| 'insert soft break'
|
|
308
316
|
| 'delete backward'
|
|
309
317
|
| 'delete forward'
|
|
318
|
+
| 'insert soft break'
|
|
319
|
+
| 'insert break'
|
|
310
320
|
| 'insert text',
|
|
311
321
|
true
|
|
312
322
|
>[]
|
|
@@ -319,12 +329,23 @@ export declare function defineBehavior<
|
|
|
319
329
|
TGuardResponse = true,
|
|
320
330
|
>(behavior: Behavior<TBehaviorEventType, TGuardResponse>): Behavior
|
|
321
331
|
|
|
332
|
+
/**
|
|
333
|
+
* @alpha
|
|
334
|
+
*/
|
|
335
|
+
export declare function defineSchema<
|
|
336
|
+
const TSchemaDefinition extends SchemaDefinition,
|
|
337
|
+
>(definition: TSchemaDefinition): TSchemaDefinition
|
|
338
|
+
|
|
322
339
|
/** @beta */
|
|
323
340
|
export declare interface EditableAPI {
|
|
324
341
|
activeAnnotations: () => PortableTextObject[]
|
|
325
342
|
isAnnotationActive: (annotationType: PortableTextObject['_type']) => boolean
|
|
326
|
-
addAnnotation:
|
|
327
|
-
|
|
343
|
+
addAnnotation: <
|
|
344
|
+
TSchemaType extends {
|
|
345
|
+
name: string
|
|
346
|
+
},
|
|
347
|
+
>(
|
|
348
|
+
type: TSchemaType,
|
|
328
349
|
value?: {
|
|
329
350
|
[prop: string]: unknown
|
|
330
351
|
},
|
|
@@ -354,14 +375,22 @@ export declare interface EditableAPI {
|
|
|
354
375
|
getValue: () => PortableTextBlock[] | undefined
|
|
355
376
|
hasBlockStyle: (style: string) => boolean
|
|
356
377
|
hasListStyle: (listStyle: string) => boolean
|
|
357
|
-
insertBlock:
|
|
358
|
-
|
|
378
|
+
insertBlock: <
|
|
379
|
+
TSchemaType extends {
|
|
380
|
+
name: string
|
|
381
|
+
},
|
|
382
|
+
>(
|
|
383
|
+
type: TSchemaType,
|
|
359
384
|
value?: {
|
|
360
385
|
[prop: string]: unknown
|
|
361
386
|
},
|
|
362
387
|
) => Path
|
|
363
|
-
insertChild:
|
|
364
|
-
|
|
388
|
+
insertChild: <
|
|
389
|
+
TSchemaType extends {
|
|
390
|
+
name: string
|
|
391
|
+
},
|
|
392
|
+
>(
|
|
393
|
+
type: TSchemaType,
|
|
365
394
|
value?: {
|
|
366
395
|
[prop: string]: unknown
|
|
367
396
|
},
|
|
@@ -377,7 +406,13 @@ export declare interface EditableAPI {
|
|
|
377
406
|
isVoid: (element: PortableTextBlock | PortableTextChild) => boolean
|
|
378
407
|
marks: () => string[]
|
|
379
408
|
redo: () => void
|
|
380
|
-
removeAnnotation:
|
|
409
|
+
removeAnnotation: <
|
|
410
|
+
TSchemaType extends {
|
|
411
|
+
name: string
|
|
412
|
+
},
|
|
413
|
+
>(
|
|
414
|
+
type: TSchemaType,
|
|
415
|
+
) => void
|
|
381
416
|
select: (selection: EditorSelection) => void
|
|
382
417
|
toggleBlockStyle: (blockStyle: string) => void
|
|
383
418
|
toggleList: (listStyle: string) => void
|
|
@@ -430,8 +465,16 @@ export declare type EditorChanges = Subject<EditorChange>
|
|
|
430
465
|
export declare type EditorConfig = {
|
|
431
466
|
behaviors?: Array<Behavior>
|
|
432
467
|
keyGenerator?: () => string
|
|
433
|
-
|
|
434
|
-
|
|
468
|
+
} & (
|
|
469
|
+
| {
|
|
470
|
+
schemaDefinition: SchemaDefinition
|
|
471
|
+
schema?: undefined
|
|
472
|
+
}
|
|
473
|
+
| {
|
|
474
|
+
schemaDefinition?: undefined
|
|
475
|
+
schema: ArraySchemaType<PortableTextBlock> | ArrayDefinition
|
|
476
|
+
}
|
|
477
|
+
)
|
|
435
478
|
|
|
436
479
|
/**
|
|
437
480
|
* @internal
|
|
@@ -867,10 +910,10 @@ export declare const editorMachine: StateMachine<
|
|
|
867
910
|
>
|
|
868
911
|
}) => {
|
|
869
912
|
behaviors: Behavior<
|
|
870
|
-
| 'insert break'
|
|
871
|
-
| 'insert soft break'
|
|
872
913
|
| 'delete backward'
|
|
873
914
|
| 'delete forward'
|
|
915
|
+
| 'insert soft break'
|
|
916
|
+
| 'insert break'
|
|
874
917
|
| 'insert text',
|
|
875
918
|
true
|
|
876
919
|
>[]
|
|
@@ -3092,6 +3135,10 @@ export declare type PickFromUnion<
|
|
|
3092
3135
|
TPickedTags extends TUnion[TTagKey],
|
|
3093
3136
|
> = TUnion extends Record<TTagKey, TPickedTags> ? TUnion : never
|
|
3094
3137
|
|
|
3138
|
+
export {PortableTextBlock}
|
|
3139
|
+
|
|
3140
|
+
export {PortableTextChild}
|
|
3141
|
+
|
|
3095
3142
|
/**
|
|
3096
3143
|
* @public
|
|
3097
3144
|
*/
|
|
@@ -3156,9 +3203,13 @@ export declare class PortableTextEditor extends Component<
|
|
|
3156
3203
|
editor: PortableTextEditor,
|
|
3157
3204
|
annotationType: PortableTextObject['_type'],
|
|
3158
3205
|
) => boolean
|
|
3159
|
-
static addAnnotation:
|
|
3206
|
+
static addAnnotation: <
|
|
3207
|
+
TSchemaType extends {
|
|
3208
|
+
name: string
|
|
3209
|
+
},
|
|
3210
|
+
>(
|
|
3160
3211
|
editor: PortableTextEditor,
|
|
3161
|
-
type:
|
|
3212
|
+
type: TSchemaType,
|
|
3162
3213
|
value?: {
|
|
3163
3214
|
[prop: string]: unknown
|
|
3164
3215
|
},
|
|
@@ -3231,16 +3282,24 @@ export declare class PortableTextEditor extends Component<
|
|
|
3231
3282
|
editor: PortableTextEditor,
|
|
3232
3283
|
mark: string,
|
|
3233
3284
|
) => boolean | undefined
|
|
3234
|
-
static insertChild:
|
|
3285
|
+
static insertChild: <
|
|
3286
|
+
TSchemaType extends {
|
|
3287
|
+
name: string
|
|
3288
|
+
},
|
|
3289
|
+
>(
|
|
3235
3290
|
editor: PortableTextEditor,
|
|
3236
|
-
type:
|
|
3291
|
+
type: TSchemaType,
|
|
3237
3292
|
value?: {
|
|
3238
3293
|
[prop: string]: unknown
|
|
3239
3294
|
},
|
|
3240
3295
|
) => Path | undefined
|
|
3241
|
-
static insertBlock:
|
|
3296
|
+
static insertBlock: <
|
|
3297
|
+
TSchemaType extends {
|
|
3298
|
+
name: string
|
|
3299
|
+
},
|
|
3300
|
+
>(
|
|
3242
3301
|
editor: PortableTextEditor,
|
|
3243
|
-
type:
|
|
3302
|
+
type: TSchemaType,
|
|
3244
3303
|
value?: {
|
|
3245
3304
|
[prop: string]: unknown
|
|
3246
3305
|
},
|
|
@@ -3256,9 +3315,13 @@ export declare class PortableTextEditor extends Component<
|
|
|
3256
3315
|
editor: PortableTextEditor,
|
|
3257
3316
|
selection: EditorSelection | null,
|
|
3258
3317
|
) => void
|
|
3259
|
-
static removeAnnotation:
|
|
3318
|
+
static removeAnnotation: <
|
|
3319
|
+
TSchemaType extends {
|
|
3320
|
+
name: string
|
|
3321
|
+
},
|
|
3322
|
+
>(
|
|
3260
3323
|
editor: PortableTextEditor,
|
|
3261
|
-
type:
|
|
3324
|
+
type: TSchemaType,
|
|
3262
3325
|
) => void | undefined
|
|
3263
3326
|
static toggleBlockStyle: (
|
|
3264
3327
|
editor: PortableTextEditor,
|
|
@@ -3551,6 +3614,20 @@ export declare type RenderStyleFunction = (
|
|
|
3551
3614
|
props: BlockStyleRenderProps,
|
|
3552
3615
|
) => JSX.Element
|
|
3553
3616
|
|
|
3617
|
+
/**
|
|
3618
|
+
* @alpha
|
|
3619
|
+
*/
|
|
3620
|
+
export declare type SchemaDefinition<
|
|
3621
|
+
TBaseDefinition extends BaseDefinition = BaseDefinition,
|
|
3622
|
+
> = {
|
|
3623
|
+
decorators?: ReadonlyArray<TBaseDefinition>
|
|
3624
|
+
blockObjects?: ReadonlyArray<TBaseDefinition>
|
|
3625
|
+
inlineObjects?: ReadonlyArray<TBaseDefinition>
|
|
3626
|
+
annotations?: ReadonlyArray<TBaseDefinition>
|
|
3627
|
+
lists?: ReadonlyArray<TBaseDefinition>
|
|
3628
|
+
styles?: ReadonlyArray<TBaseDefinition>
|
|
3629
|
+
}
|
|
3630
|
+
|
|
3554
3631
|
/** @beta */
|
|
3555
3632
|
export declare type ScrollSelectionIntoViewFunction = (
|
|
3556
3633
|
editor: PortableTextEditor,
|
|
@@ -4015,10 +4092,10 @@ export declare function useEditor(config: EditorConfig): Actor<
|
|
|
4015
4092
|
>
|
|
4016
4093
|
}) => {
|
|
4017
4094
|
behaviors: Behavior<
|
|
4018
|
-
| 'insert break'
|
|
4019
|
-
| 'insert soft break'
|
|
4020
4095
|
| 'delete backward'
|
|
4021
4096
|
| 'delete forward'
|
|
4097
|
+
| 'insert soft break'
|
|
4098
|
+
| 'insert break'
|
|
4022
4099
|
| 'insert text',
|
|
4023
4100
|
true
|
|
4024
4101
|
>[]
|