@portabletext/plugin-sdk-value 8.0.5 → 8.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.
- package/README.md +54 -3
- package/dist/index.d.ts +100 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +390 -47
- package/dist/index.js.map +1 -1
- package/package.json +5 -5
package/README.md
CHANGED
|
@@ -3,8 +3,9 @@
|
|
|
3
3
|
> Connect a Portable Text Editor with a Sanity document using the SDK
|
|
4
4
|
|
|
5
5
|
Two-way synchronization between a Portable Text Editor and a field in a Sanity
|
|
6
|
-
document, plus presence: other people's carets show up in
|
|
7
|
-
local user's caret shows up for them,
|
|
6
|
+
document, plus presence and inline comments: other people's carets show up in
|
|
7
|
+
the field and the local user's caret shows up for them, and comment threads
|
|
8
|
+
anchored to text draw as highlights, all interoperating with the Studio.
|
|
8
9
|
|
|
9
10
|
## Installation
|
|
10
11
|
|
|
@@ -18,6 +19,7 @@ npm install @portabletext/plugin-sdk-value
|
|
|
18
19
|
- **Real-time updates**: Automatically handles patches from external sources (other users, mutations, etc.)
|
|
19
20
|
- **Optimistic updates**: Provides smooth user experience with immediate local updates
|
|
20
21
|
- **Presence**: Reports where the local user is editing, and draws other people's carets
|
|
22
|
+
- **Inline comments**: Draws highlights for comment threads anchored to text, and starts new threads on the selection
|
|
21
23
|
|
|
22
24
|
## Usage
|
|
23
25
|
|
|
@@ -72,6 +74,55 @@ Pass `renderCursor={null}` to draw no carets at all while still reporting the
|
|
|
72
74
|
local user's presence, which is what you want if you only care about keeping the
|
|
73
75
|
document in sync.
|
|
74
76
|
|
|
77
|
+
### Inline comments
|
|
78
|
+
|
|
79
|
+
Comment threads anchored to text in the field draw as highlights, and new
|
|
80
|
+
threads can be started on the current selection. The composer UI stays with the
|
|
81
|
+
app, the same split presence uses for carets. Comments are written in the shape
|
|
82
|
+
Sanity Studio stores, so threads round-trip between an SDK app and the Studio.
|
|
83
|
+
|
|
84
|
+
`useSDKCommentDecorations` returns `RangeDecoration[]` for the open threads on
|
|
85
|
+
the field. Pass it through `rangeDecorations`, which `SDKPortableTextEditable`
|
|
86
|
+
merges with the presence carets:
|
|
87
|
+
|
|
88
|
+
```tsx
|
|
89
|
+
const decorations = useSDKCommentDecorations({
|
|
90
|
+
...documentHandle,
|
|
91
|
+
path: 'content',
|
|
92
|
+
renderDecoration: (comment) => (props) => (
|
|
93
|
+
<span data-comment-id={comment.id} style={{background: '#fef3c7'}}>
|
|
94
|
+
{props.children}
|
|
95
|
+
</span>
|
|
96
|
+
),
|
|
97
|
+
})
|
|
98
|
+
|
|
99
|
+
return (
|
|
100
|
+
<SDKPortableTextEditable
|
|
101
|
+
{...documentHandle}
|
|
102
|
+
path="content"
|
|
103
|
+
rangeDecorations={decorations}
|
|
104
|
+
/>
|
|
105
|
+
)
|
|
106
|
+
```
|
|
107
|
+
|
|
108
|
+
`useSDKCommentAuthoring` is the write side: `commentableSelection` is set when
|
|
109
|
+
the current selection can take a comment, and `createInlineComment` starts a
|
|
110
|
+
thread anchored to it:
|
|
111
|
+
|
|
112
|
+
```tsx
|
|
113
|
+
const {commentableSelection, createInlineComment} = useSDKCommentAuthoring({
|
|
114
|
+
...documentHandle,
|
|
115
|
+
path: 'content',
|
|
116
|
+
})
|
|
117
|
+
|
|
118
|
+
// Show the composer while `commentableSelection` is set, then:
|
|
119
|
+
await createInlineComment({message})
|
|
120
|
+
```
|
|
121
|
+
|
|
122
|
+
Highlights follow the text while the user types, and a highlight whose text is
|
|
123
|
+
deleted or rewritten beyond recognition is dropped rather than drawn on the
|
|
124
|
+
wrong words. Resolved threads draw nothing, matching the Studio.
|
|
125
|
+
|
|
75
126
|
### Rendering the editable yourself
|
|
76
127
|
|
|
77
128
|
`SDKValuePlugin` still works as a sibling component if you would rather keep
|
|
@@ -138,5 +189,5 @@ the Studio, whose field indicators compare the exact document id its form is on.
|
|
|
138
189
|
|
|
139
190
|
This plugin requires:
|
|
140
191
|
|
|
141
|
-
- `@sanity/sdk-react` 2.
|
|
192
|
+
- `@sanity/sdk-react` 2.20.1 or newer, where the comment hooks were added
|
|
142
193
|
- The document must exist in the Sanity dataset
|
package/dist/index.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { DocumentHandle, usePresenceForDocument } from "@sanity/sdk-react";
|
|
1
|
+
import { Comment, CommentMessage, DocumentHandle, DocumentResource, usePresenceForDocument } from "@sanity/sdk-react";
|
|
2
2
|
import { EditorSelection, Patch, PortableTextBlock, PortableTextEditableProps, RangeDecoration } from "@portabletext/editor";
|
|
3
3
|
import { PropsWithChildren, ReactElement } from "react";
|
|
4
4
|
import "@portabletext/patches";
|
|
@@ -41,6 +41,10 @@ interface SDKRemoteCursor {
|
|
|
41
41
|
* @public
|
|
42
42
|
*/
|
|
43
43
|
interface SDKPresencePluginProps extends DocumentHandle {
|
|
44
|
+
/**
|
|
45
|
+
* @deprecated Use `resource` instead.
|
|
46
|
+
*/
|
|
47
|
+
source?: DocumentResource;
|
|
44
48
|
/**
|
|
45
49
|
* The document path of the Portable Text field, for example `content`. The
|
|
46
50
|
* same form `SDKValuePlugin` takes.
|
|
@@ -53,6 +57,10 @@ interface SDKPresencePluginProps extends DocumentHandle {
|
|
|
53
57
|
* @public
|
|
54
58
|
*/
|
|
55
59
|
interface UseSDKPresenceCursorsOptions extends DocumentHandle {
|
|
60
|
+
/**
|
|
61
|
+
* @deprecated Use `resource` instead.
|
|
62
|
+
*/
|
|
63
|
+
source?: DocumentResource;
|
|
56
64
|
path: string;
|
|
57
65
|
renderCursor: RenderCursorFunction;
|
|
58
66
|
}
|
|
@@ -86,7 +94,93 @@ declare function SDKPresencePlugin(props: SDKPresencePluginProps): null;
|
|
|
86
94
|
* @public
|
|
87
95
|
*/
|
|
88
96
|
declare function useSDKPresenceCursors(options: UseSDKPresenceCursorsOptions): RangeDecoration[];
|
|
97
|
+
/**
|
|
98
|
+
* Draws one comment's highlight. The plugin has no opinion about how a
|
|
99
|
+
* highlight looks, so it is the caller's to provide, the same way presence
|
|
100
|
+
* takes `renderCursor`.
|
|
101
|
+
*
|
|
102
|
+
* @public
|
|
103
|
+
*/
|
|
104
|
+
type RenderCommentDecorationFunction = (comment: Comment) => (props: PropsWithChildren) => ReactElement;
|
|
105
|
+
/**
|
|
106
|
+
* Options for {@link useSDKCommentDecorations}.
|
|
107
|
+
*
|
|
108
|
+
* @public
|
|
109
|
+
*/
|
|
110
|
+
interface UseSDKCommentDecorationsOptions extends DocumentHandle {
|
|
111
|
+
/**
|
|
112
|
+
* The document path of the Portable Text field, for example `content`. The
|
|
113
|
+
* same form `SDKValuePlugin` takes.
|
|
114
|
+
*/
|
|
115
|
+
path: string;
|
|
116
|
+
renderDecoration: RenderCommentDecorationFunction;
|
|
117
|
+
}
|
|
118
|
+
/**
|
|
119
|
+
* Inline comment highlights for a Portable Text field, as range decorations.
|
|
120
|
+
*
|
|
121
|
+
* Pass the result to `<PortableTextEditable rangeDecorations={...} />`. Each
|
|
122
|
+
* thread's first comment that carries a text anchor on this field gets one
|
|
123
|
+
* decoration. Highlights stay put while the local user types, and a highlight
|
|
124
|
+
* whose text has been deleted or rewritten beyond recognition is dropped
|
|
125
|
+
* rather than drawn on the wrong words.
|
|
126
|
+
*
|
|
127
|
+
* Suspends while the document's comments load, like every SDK read hook.
|
|
128
|
+
*
|
|
129
|
+
* Resolved threads draw nothing: this mirrors the Studio, where resolving a
|
|
130
|
+
* thread removes its highlight from the text.
|
|
131
|
+
*
|
|
132
|
+
* @public
|
|
133
|
+
*/
|
|
134
|
+
declare function useSDKCommentDecorations(options: UseSDKCommentDecorationsOptions): RangeDecoration[];
|
|
135
|
+
/**
|
|
136
|
+
* Options for {@link useSDKCommentAuthoring}.
|
|
137
|
+
*
|
|
138
|
+
* @public
|
|
139
|
+
*/
|
|
140
|
+
interface UseSDKCommentAuthoringOptions extends DocumentHandle {
|
|
141
|
+
/**
|
|
142
|
+
* The document path of the Portable Text field, for example `content`.
|
|
143
|
+
*/
|
|
144
|
+
path: string;
|
|
145
|
+
}
|
|
146
|
+
/**
|
|
147
|
+
* What {@link useSDKCommentAuthoring} returns.
|
|
148
|
+
*
|
|
149
|
+
* @public
|
|
150
|
+
*/
|
|
151
|
+
interface SDKCommentAuthoring {
|
|
152
|
+
/**
|
|
153
|
+
* The current selection when it can take a comment, `null` otherwise. Show
|
|
154
|
+
* the comment affordance when this is set, and position it off the
|
|
155
|
+
* selection. A selection can take a comment when it is expanded, contains
|
|
156
|
+
* text, and stays within one array of blocks.
|
|
157
|
+
*/
|
|
158
|
+
commentableSelection: EditorSelection;
|
|
159
|
+
/**
|
|
160
|
+
* Starts a comment thread anchored to the text selected right now.
|
|
161
|
+
*
|
|
162
|
+
* The anchor is captured from the live selection at call time, so call this
|
|
163
|
+
* from the affordance while the selection still stands. Rejects when nothing
|
|
164
|
+
* commentable is selected.
|
|
165
|
+
*/
|
|
166
|
+
createInlineComment: (options: {
|
|
167
|
+
message: CommentMessage;
|
|
168
|
+
/** Reuse the id of a failed comment to retry it. */
|
|
169
|
+
commentId?: string;
|
|
170
|
+
}) => Promise<Comment>;
|
|
171
|
+
}
|
|
172
|
+
/**
|
|
173
|
+
* Lets the app author inline comments on a Portable Text field.
|
|
174
|
+
*
|
|
175
|
+
* The plugin captures the selection and writes the comment; the composer UI is
|
|
176
|
+
* the app's, the same split the Studio and Canvas use. Comments are written in
|
|
177
|
+
* the shape the Studio stores, so a thread started here shows up there.
|
|
178
|
+
*
|
|
179
|
+
* @public
|
|
180
|
+
*/
|
|
181
|
+
declare function useSDKCommentAuthoring(options: UseSDKCommentAuthoringOptions): SDKCommentAuthoring;
|
|
89
182
|
interface SDKValuePluginProps extends DocumentHandle {
|
|
183
|
+
source?: DocumentResource;
|
|
90
184
|
path: string;
|
|
91
185
|
}
|
|
92
186
|
/**
|
|
@@ -132,6 +226,10 @@ declare function ValueSyncPlugin(props: ValueSyncConfig): null;
|
|
|
132
226
|
* @public
|
|
133
227
|
*/
|
|
134
228
|
interface SDKPortableTextEditableProps extends DocumentHandle, Omit<PortableTextEditableProps, keyof DocumentHandle> {
|
|
229
|
+
/**
|
|
230
|
+
* @deprecated Use `resource` instead.
|
|
231
|
+
*/
|
|
232
|
+
source?: DocumentResource;
|
|
135
233
|
/**
|
|
136
234
|
* The document path of the Portable Text field, for example `content`.
|
|
137
235
|
*/
|
|
@@ -170,5 +268,5 @@ interface SDKPortableTextEditableProps extends DocumentHandle, Omit<PortableText
|
|
|
170
268
|
* @public
|
|
171
269
|
*/
|
|
172
270
|
declare function SDKPortableTextEditable(props: SDKPortableTextEditableProps): import("react").JSX.Element;
|
|
173
|
-
export { type RenderCursorFunction, SDKPortableTextEditable, type SDKPortableTextEditableProps, SDKPresencePlugin, type SDKPresencePluginProps, type SDKRemoteCursor, SDKValuePlugin, type UseSDKPresenceCursorsOptions, ValueSyncPlugin, useSDKPresenceCursors };
|
|
271
|
+
export { type RenderCommentDecorationFunction, type RenderCursorFunction, type SDKCommentAuthoring, SDKPortableTextEditable, type SDKPortableTextEditableProps, SDKPresencePlugin, type SDKPresencePluginProps, type SDKRemoteCursor, SDKValuePlugin, type UseSDKCommentAuthoringOptions, type UseSDKCommentDecorationsOptions, type UseSDKPresenceCursorsOptions, ValueSyncPlugin, useSDKCommentAuthoring, useSDKCommentDecorations, useSDKPresenceCursors };
|
|
174
272
|
//# sourceMappingURL=index.d.ts.map
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","names":[],"sources":["../src/plugin.sdk-presence.tsx","../src/plugin.sdk-value.tsx","../src/sdk-editable.tsx"],"mappings":";;;;;;;;;
|
|
1
|
+
{"version":3,"file":"index.d.ts","names":[],"sources":["../src/plugin.sdk-presence.tsx","../src/plugin.sdk-comments.tsx","../src/plugin.sdk-value.tsx","../src/sdk-editable.tsx"],"mappings":";;;;;;;;;KAiBK,mBAAmB,kBACf;;;;;;;KASG,wBACV,QAAQ,qBACJ,OAAO,sBAAsB;;;;;;;;;UAUlB;;;;;EAKf;;;;EAIA,WAAW;EACX,MAAM;;;;;;;UAQS,+BAA+B;;;;EAI9C,SAAS;;;;;EAKT;;;;;;;UAQe,qCAAqC;;;;EAIpD,SAAS;EACT;EACA,cAAc;;;;;;;;;;;;;;;;iBAiBA,kBAAkB,OAAO;;;;;;;;;;;;;;;iBAwBzB,sBACd,SAAS,+BACR;;;;;;;;KCnCS,mCACV,SAAS,aACL,OAAO,sBAAsB;;;;;;UAOlB,wCAAwC;;;;;EAKvD;EACA,kBAAkB;;;;;;;;;;;;;;;;;;iBAmBJ,yBACd,SAAS,kCACR;;;;;;UAgGc,sCAAsC;;;;EAIrD;;;;;;;UAQe;;;;;;;EAOf,sBAAsB;;;;;;;;EAQtB,sBAAsB;IACpB,SAAS;;IAET;QACI,QAAQ;;;;;;;;;;;iBAwBA,uBACd,SAAS,gCACR;UC0yBO,4BAA4B;EACpC,SAAS;EACT;;;;;iBAqCc,eAAe,OAAO,sCAAmB,IAAA;;;;KAkFpD;EACH,sBAAsB;EACtB,YAAY,OAAO;EACnB,sBAAsB;;;;;;;;EAQtB,mBACE,WAAW,SAAS;;;;;;EAOtB,eAAe,SAAS;;;;;;;;;;;;iBAaV,gBAAgB,OAAO;;;;;;UCnsCtB,qCAEb,gBAGA,KAAK,iCAAiC;;;;EAIxC,SAAS;;;;EAIT;;;;;;EAMA,eAAe;;;;;;;;;;;;;;;;;;;;;;;;;;;;iBA6CD,wBAAwB,OAAO,+CAA4B,IAAA"}
|