@uipath/apollo-react 4.62.1 → 4.64.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/dist/canvas/components/StickyNoteNode/StickyNoteMedia.cjs +449 -0
- package/dist/canvas/components/StickyNoteNode/StickyNoteMedia.d.ts +45 -0
- package/dist/canvas/components/StickyNoteNode/StickyNoteMedia.d.ts.map +1 -0
- package/dist/canvas/components/StickyNoteNode/StickyNoteMedia.js +394 -0
- package/dist/canvas/components/StickyNoteNode/StickyNoteMediaDialog.cjs +379 -0
- package/dist/canvas/components/StickyNoteNode/StickyNoteMediaDialog.d.ts +8 -0
- package/dist/canvas/components/StickyNoteNode/StickyNoteMediaDialog.d.ts.map +1 -0
- package/dist/canvas/components/StickyNoteNode/StickyNoteMediaDialog.js +345 -0
- package/dist/canvas/components/StickyNoteNode/StickyNoteMediaMarkdown.cjs +272 -0
- package/dist/canvas/components/StickyNoteNode/StickyNoteMediaMarkdown.d.ts +18 -0
- package/dist/canvas/components/StickyNoteNode/StickyNoteMediaMarkdown.d.ts.map +1 -0
- package/dist/canvas/components/StickyNoteNode/StickyNoteMediaMarkdown.js +235 -0
- package/dist/canvas/components/StickyNoteNode/StickyNoteNode.cjs +130 -17
- package/dist/canvas/components/StickyNoteNode/StickyNoteNode.d.ts +2 -1
- package/dist/canvas/components/StickyNoteNode/StickyNoteNode.d.ts.map +1 -1
- package/dist/canvas/components/StickyNoteNode/StickyNoteNode.js +130 -17
- package/dist/canvas/locales/en.cjs +1 -1
- package/dist/canvas/locales/en.d.ts.map +1 -1
- package/dist/canvas/locales/en.js +1 -1
- package/dist/canvas/storybook-utils/manifests/node-definitions.d.ts.map +1 -1
- package/dist/canvas/styles/tailwind.canvas.css +1 -1
- package/dist/canvas/utils/icon-registry.cjs +4 -0
- package/dist/canvas/utils/icon-registry.d.ts.map +1 -1
- package/dist/canvas/utils/icon-registry.js +5 -1
- package/package.json +1 -1
|
@@ -0,0 +1,235 @@
|
|
|
1
|
+
import { jsx, jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { CanvasIcon } from "../../index.js";
|
|
3
|
+
import { createContext, createElement, useContext, useState } from "react";
|
|
4
|
+
import { useSafeLingui } from "../../../i18n/index.js";
|
|
5
|
+
import { parseStickyNoteMediaMarker, parseStickyNoteMediaSource } from "./StickyNoteMedia.js";
|
|
6
|
+
const StickyNoteMediaMarkdownContext = /*#__PURE__*/ createContext({
|
|
7
|
+
editable: false
|
|
8
|
+
});
|
|
9
|
+
function StickyNoteMediaMarkdownProvider({ value, children }) {
|
|
10
|
+
return /*#__PURE__*/ jsx(StickyNoteMediaMarkdownContext.Provider, {
|
|
11
|
+
value: value,
|
|
12
|
+
children: children
|
|
13
|
+
});
|
|
14
|
+
}
|
|
15
|
+
function sourceRange(node) {
|
|
16
|
+
const start = node?.position?.start?.offset;
|
|
17
|
+
const end = node?.position?.end?.offset;
|
|
18
|
+
return 'number' == typeof start && 'number' == typeof end ? {
|
|
19
|
+
start,
|
|
20
|
+
end
|
|
21
|
+
} : null;
|
|
22
|
+
}
|
|
23
|
+
function MediaContainer({ fullWidth, children }) {
|
|
24
|
+
return /*#__PURE__*/ jsx("span", {
|
|
25
|
+
className: "relative my-2 block max-w-full overflow-hidden rounded-md",
|
|
26
|
+
style: {
|
|
27
|
+
width: fullWidth ? '100%' : 'min(320px, 100%)'
|
|
28
|
+
},
|
|
29
|
+
"data-sticky-media": true,
|
|
30
|
+
"data-sticky-full-width": fullWidth,
|
|
31
|
+
children: children
|
|
32
|
+
});
|
|
33
|
+
}
|
|
34
|
+
function MediaEditButton({ onClick }) {
|
|
35
|
+
const { _ } = useSafeLingui();
|
|
36
|
+
const label = _({
|
|
37
|
+
id: 'sticky-note.media.edit',
|
|
38
|
+
message: 'Edit media'
|
|
39
|
+
});
|
|
40
|
+
return /*#__PURE__*/ jsx("button", {
|
|
41
|
+
type: "button",
|
|
42
|
+
"data-sticky-media-control": true,
|
|
43
|
+
"aria-label": label,
|
|
44
|
+
title: label,
|
|
45
|
+
className: "absolute right-1 top-1 z-10 inline-flex h-7 w-7 items-center justify-center rounded bg-surface-raised/95 text-foreground opacity-80 shadow-sm transition-opacity hover:bg-surface-hover hover:opacity-100 focus-visible:opacity-100",
|
|
46
|
+
onClick: (event)=>{
|
|
47
|
+
event.preventDefault();
|
|
48
|
+
event.stopPropagation();
|
|
49
|
+
onClick();
|
|
50
|
+
},
|
|
51
|
+
onDoubleClick: (event)=>event.stopPropagation(),
|
|
52
|
+
onPointerDown: (event)=>event.stopPropagation(),
|
|
53
|
+
children: /*#__PURE__*/ jsx(CanvasIcon, {
|
|
54
|
+
icon: "pencil",
|
|
55
|
+
size: 14
|
|
56
|
+
})
|
|
57
|
+
});
|
|
58
|
+
}
|
|
59
|
+
function StickyNoteMediaImage({ src, alt = '', title, node, fallbackImage, ...imageProps }) {
|
|
60
|
+
const { _ } = useSafeLingui();
|
|
61
|
+
const { editable, onEditMedia } = useContext(StickyNoteMediaMarkdownContext);
|
|
62
|
+
const [failedImageUrl, setFailedImageUrl] = useState(null);
|
|
63
|
+
const [loadedYouTubeId, setLoadedYouTubeId] = useState(null);
|
|
64
|
+
const mediaMarker = parseStickyNoteMediaMarker(title);
|
|
65
|
+
const media = 'string' == typeof src ? parseStickyNoteMediaSource(src, alt, title) : null;
|
|
66
|
+
const range = sourceRange(node);
|
|
67
|
+
if (!media) {
|
|
68
|
+
if (mediaMarker) {
|
|
69
|
+
const unavailableLabel = _({
|
|
70
|
+
id: 'sticky-note.media.unavailable',
|
|
71
|
+
message: 'Media unavailable'
|
|
72
|
+
});
|
|
73
|
+
return /*#__PURE__*/ jsx(MediaContainer, {
|
|
74
|
+
fullWidth: mediaMarker.fullWidth,
|
|
75
|
+
children: /*#__PURE__*/ jsx("span", {
|
|
76
|
+
role: "img",
|
|
77
|
+
"aria-label": alt || unavailableLabel,
|
|
78
|
+
className: "flex min-h-20 items-center justify-center bg-black/10 px-3 text-center text-xs text-foreground-muted",
|
|
79
|
+
children: unavailableLabel
|
|
80
|
+
})
|
|
81
|
+
});
|
|
82
|
+
}
|
|
83
|
+
if (fallbackImage) {
|
|
84
|
+
const fallbackProps = {
|
|
85
|
+
...imageProps,
|
|
86
|
+
src,
|
|
87
|
+
alt,
|
|
88
|
+
title
|
|
89
|
+
};
|
|
90
|
+
return 'string' == typeof fallbackImage ? /*#__PURE__*/ createElement(fallbackImage, fallbackProps) : /*#__PURE__*/ createElement(fallbackImage, {
|
|
91
|
+
...fallbackProps,
|
|
92
|
+
node
|
|
93
|
+
});
|
|
94
|
+
}
|
|
95
|
+
return /*#__PURE__*/ jsx("img", {
|
|
96
|
+
...imageProps,
|
|
97
|
+
src: src,
|
|
98
|
+
alt: alt,
|
|
99
|
+
title: title
|
|
100
|
+
});
|
|
101
|
+
}
|
|
102
|
+
const editButton = editable && range && onEditMedia && /*#__PURE__*/ jsx(MediaEditButton, {
|
|
103
|
+
onClick: ()=>onEditMedia(media, range)
|
|
104
|
+
});
|
|
105
|
+
if ('youtube' === media.kind) {
|
|
106
|
+
const playLabel = _({
|
|
107
|
+
id: 'sticky-note.media.play-video',
|
|
108
|
+
message: 'Play video'
|
|
109
|
+
});
|
|
110
|
+
const youtubeLoaded = loadedYouTubeId === media.videoId;
|
|
111
|
+
return /*#__PURE__*/ jsxs(MediaContainer, {
|
|
112
|
+
fullWidth: media.fullWidth,
|
|
113
|
+
children: [
|
|
114
|
+
youtubeLoaded ? /*#__PURE__*/ jsx("iframe", {
|
|
115
|
+
src: `https://www.youtube-nocookie.com/embed/${media.videoId}?autoplay=1`,
|
|
116
|
+
title: _({
|
|
117
|
+
id: 'sticky-note.media.youtube-title',
|
|
118
|
+
message: 'YouTube video'
|
|
119
|
+
}),
|
|
120
|
+
loading: "lazy",
|
|
121
|
+
referrerPolicy: "strict-origin-when-cross-origin",
|
|
122
|
+
sandbox: "allow-scripts allow-same-origin allow-presentation",
|
|
123
|
+
allow: "autoplay; encrypted-media; fullscreen; picture-in-picture",
|
|
124
|
+
allowFullScreen: true,
|
|
125
|
+
className: "block aspect-video w-full border-0",
|
|
126
|
+
onPointerDown: (event)=>event.stopPropagation()
|
|
127
|
+
}) : /*#__PURE__*/ jsxs("button", {
|
|
128
|
+
type: "button",
|
|
129
|
+
"data-sticky-media-control": true,
|
|
130
|
+
"aria-label": playLabel,
|
|
131
|
+
className: "group relative flex aspect-video w-full items-center justify-center overflow-hidden bg-black text-sm font-medium text-white focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-[-2px] focus-visible:outline-white",
|
|
132
|
+
onClick: (event)=>{
|
|
133
|
+
event.preventDefault();
|
|
134
|
+
event.stopPropagation();
|
|
135
|
+
setLoadedYouTubeId(media.videoId);
|
|
136
|
+
},
|
|
137
|
+
onDoubleClick: (event)=>event.stopPropagation(),
|
|
138
|
+
onPointerDown: (event)=>event.stopPropagation(),
|
|
139
|
+
children: [
|
|
140
|
+
/*#__PURE__*/ jsx("img", {
|
|
141
|
+
src: `https://i.ytimg.com/vi/${media.videoId}/hqdefault.jpg`,
|
|
142
|
+
alt: "",
|
|
143
|
+
draggable: false,
|
|
144
|
+
loading: "lazy",
|
|
145
|
+
decoding: "async",
|
|
146
|
+
referrerPolicy: "no-referrer",
|
|
147
|
+
className: "absolute inset-0 h-full w-full object-cover opacity-80 transition-opacity group-hover:opacity-70"
|
|
148
|
+
}),
|
|
149
|
+
/*#__PURE__*/ jsxs("span", {
|
|
150
|
+
className: "relative z-10 inline-flex items-center gap-2 rounded-full bg-black/70 px-4 py-2 shadow-sm",
|
|
151
|
+
children: [
|
|
152
|
+
/*#__PURE__*/ jsx(CanvasIcon, {
|
|
153
|
+
icon: "play",
|
|
154
|
+
size: 18
|
|
155
|
+
}),
|
|
156
|
+
playLabel
|
|
157
|
+
]
|
|
158
|
+
})
|
|
159
|
+
]
|
|
160
|
+
}),
|
|
161
|
+
editButton
|
|
162
|
+
]
|
|
163
|
+
});
|
|
164
|
+
}
|
|
165
|
+
if ('publicVideo' === media.kind) {
|
|
166
|
+
const videoLabel = alt || _({
|
|
167
|
+
id: 'sticky-note.media.video-label',
|
|
168
|
+
message: 'Embedded video'
|
|
169
|
+
});
|
|
170
|
+
return /*#__PURE__*/ jsxs(MediaContainer, {
|
|
171
|
+
fullWidth: media.fullWidth,
|
|
172
|
+
children: [
|
|
173
|
+
/*#__PURE__*/ jsx("video", {
|
|
174
|
+
src: media.url,
|
|
175
|
+
"aria-label": videoLabel,
|
|
176
|
+
controls: true,
|
|
177
|
+
preload: "metadata",
|
|
178
|
+
playsInline: true,
|
|
179
|
+
className: "block h-auto w-full bg-black",
|
|
180
|
+
onClick: (event)=>event.stopPropagation(),
|
|
181
|
+
onDoubleClick: (event)=>event.stopPropagation(),
|
|
182
|
+
onPointerDown: (event)=>event.stopPropagation(),
|
|
183
|
+
children: _({
|
|
184
|
+
id: 'sticky-note.media.video-unavailable',
|
|
185
|
+
message: 'Video playback is unavailable.'
|
|
186
|
+
})
|
|
187
|
+
}),
|
|
188
|
+
editButton
|
|
189
|
+
]
|
|
190
|
+
});
|
|
191
|
+
}
|
|
192
|
+
const imageFailed = failedImageUrl === media.url;
|
|
193
|
+
return /*#__PURE__*/ jsxs(MediaContainer, {
|
|
194
|
+
fullWidth: media.fullWidth,
|
|
195
|
+
children: [
|
|
196
|
+
imageFailed ? /*#__PURE__*/ jsx("span", {
|
|
197
|
+
role: "img",
|
|
198
|
+
"aria-label": alt || _({
|
|
199
|
+
id: 'sticky-note.media.image-unavailable-label',
|
|
200
|
+
message: 'Image unavailable'
|
|
201
|
+
}),
|
|
202
|
+
className: "flex min-h-20 items-center justify-center bg-black/10 px-3 text-center text-xs text-foreground-muted",
|
|
203
|
+
children: _({
|
|
204
|
+
id: 'sticky-note.media.image-unavailable',
|
|
205
|
+
message: 'Image unavailable'
|
|
206
|
+
})
|
|
207
|
+
}) : /*#__PURE__*/ jsx("img", {
|
|
208
|
+
...imageProps,
|
|
209
|
+
src: media.url,
|
|
210
|
+
alt: alt,
|
|
211
|
+
draggable: false,
|
|
212
|
+
loading: "lazy",
|
|
213
|
+
decoding: "async",
|
|
214
|
+
referrerPolicy: "no-referrer",
|
|
215
|
+
style: {
|
|
216
|
+
display: 'block',
|
|
217
|
+
maxWidth: '100%',
|
|
218
|
+
width: media.fullWidth ? '100%' : 'auto',
|
|
219
|
+
height: 'auto'
|
|
220
|
+
},
|
|
221
|
+
onError: ()=>setFailedImageUrl(media.url)
|
|
222
|
+
}),
|
|
223
|
+
editButton
|
|
224
|
+
]
|
|
225
|
+
});
|
|
226
|
+
}
|
|
227
|
+
function createStickyNoteMediaMarkdownComponents(fallbackImage) {
|
|
228
|
+
return {
|
|
229
|
+
img: (props)=>/*#__PURE__*/ jsx(StickyNoteMediaImage, {
|
|
230
|
+
...props,
|
|
231
|
+
fallbackImage: fallbackImage
|
|
232
|
+
})
|
|
233
|
+
};
|
|
234
|
+
}
|
|
235
|
+
export { StickyNoteMediaMarkdownProvider, createStickyNoteMediaMarkdownComponents };
|
|
@@ -56,6 +56,9 @@ const external_NodeViewportOverlay_cjs_namespaceObject = require("../NodeViewpor
|
|
|
56
56
|
const external_Toolbar_index_cjs_namespaceObject = require("../Toolbar/index.cjs");
|
|
57
57
|
const external_FormattingToolbar_cjs_namespaceObject = require("./FormattingToolbar.cjs");
|
|
58
58
|
const external_markdown_formatting_index_cjs_namespaceObject = require("./markdown-formatting/index.cjs");
|
|
59
|
+
const external_StickyNoteMedia_cjs_namespaceObject = require("./StickyNoteMedia.cjs");
|
|
60
|
+
const external_StickyNoteMediaDialog_cjs_namespaceObject = require("./StickyNoteMediaDialog.cjs");
|
|
61
|
+
const external_StickyNoteMediaMarkdown_cjs_namespaceObject = require("./StickyNoteMediaMarkdown.cjs");
|
|
59
62
|
const external_StickyNoteNode_styles_cjs_namespaceObject = require("./StickyNoteNode.styles.cjs");
|
|
60
63
|
const external_StickyNoteNode_types_cjs_namespaceObject = require("./StickyNoteNode.types.cjs");
|
|
61
64
|
const external_StickyNoteNode_utils_cjs_namespaceObject = require("./StickyNoteNode.utils.cjs");
|
|
@@ -63,13 +66,14 @@ const external_useMarkdownShortcuts_cjs_namespaceObject = require("./useMarkdown
|
|
|
63
66
|
const external_useScrollCapture_cjs_namespaceObject = require("./useScrollCapture.cjs");
|
|
64
67
|
const minWidth = 8 * external_constants_cjs_namespaceObject.GRID_SPACING;
|
|
65
68
|
const minHeight = 8 * external_constants_cjs_namespaceObject.GRID_SPACING;
|
|
66
|
-
const StickyNoteNodeComponent = ({ id, data, selected, dragging, placeholder = 'Add text', renderPlaceholderOnSelect = false, readOnly = false, onContentChange, onColorChange, onResize, onResizeStart, onResizeEnd, formattingActions, markdownComponents: customMarkdownComponents })=>{
|
|
69
|
+
const StickyNoteNodeComponent = ({ id, data, selected, dragging, placeholder = 'Add text', renderPlaceholderOnSelect = false, readOnly = false, onContentChange, onColorChange, onResize, onResizeStart, onResizeEnd, enableMediaEmbedding = false, formattingActions, markdownComponents: customMarkdownComponents })=>{
|
|
67
70
|
const { _ } = (0, index_cjs_namespaceObject.useSafeLingui)();
|
|
68
71
|
const { updateNodeData, deleteElements } = (0, react_cjs_namespaceObject.useReactFlow)();
|
|
69
72
|
const { multipleNodesSelected } = (0, SelectionStateContext_cjs_namespaceObject.useSelectionState)();
|
|
70
73
|
const [isEditing, setIsEditing] = (0, external_react_namespaceObject.useState)(!readOnly && (data.autoFocus ?? false));
|
|
71
74
|
const [isResizing, setIsResizing] = (0, external_react_namespaceObject.useState)(false);
|
|
72
75
|
const [isColorPickerOpen, setIsColorPickerOpen] = (0, external_react_namespaceObject.useState)(false);
|
|
76
|
+
const [mediaDialog, setMediaDialog] = (0, external_react_namespaceObject.useState)(null);
|
|
73
77
|
const [localContent, setLocalContent] = (0, external_react_namespaceObject.useState)(data.content || '');
|
|
74
78
|
const latestContentRef = (0, external_react_namespaceObject.useRef)(localContent);
|
|
75
79
|
const textAreaRef = (0, external_react_namespaceObject.useRef)(null);
|
|
@@ -244,6 +248,92 @@ const StickyNoteNodeComponent = ({ id, data, selected, dragging, placeholder = '
|
|
|
244
248
|
updateLocalContent,
|
|
245
249
|
updateNodeData
|
|
246
250
|
]);
|
|
251
|
+
const openMediaDialog = (0, external_react_namespaceObject.useCallback)((context)=>{
|
|
252
|
+
const { selection } = context;
|
|
253
|
+
setMediaDialog({
|
|
254
|
+
source: 'editor',
|
|
255
|
+
context,
|
|
256
|
+
token: (0, external_StickyNoteMedia_cjs_namespaceObject.findStickyNoteMediaAtSelection)(selection.value, selection.selectionStart, selection.selectionEnd)
|
|
257
|
+
});
|
|
258
|
+
}, []);
|
|
259
|
+
const mediaFormattingAction = (0, external_react_namespaceObject.useMemo)(()=>({
|
|
260
|
+
id: 'sticky-note-embed-media',
|
|
261
|
+
icon: /*#__PURE__*/ (0, jsx_runtime_namespaceObject.jsx)(external_index_cjs_namespaceObject.CanvasIcon, {
|
|
262
|
+
icon: "image-plus",
|
|
263
|
+
size: 14
|
|
264
|
+
}),
|
|
265
|
+
label: _({
|
|
266
|
+
id: 'sticky-note.media.embed-action',
|
|
267
|
+
message: 'Embed image or video'
|
|
268
|
+
}),
|
|
269
|
+
onAction: openMediaDialog
|
|
270
|
+
}), [
|
|
271
|
+
_,
|
|
272
|
+
openMediaDialog
|
|
273
|
+
]);
|
|
274
|
+
const effectiveFormattingActions = (0, external_react_namespaceObject.useMemo)(()=>enableMediaEmbedding ? [
|
|
275
|
+
mediaFormattingAction,
|
|
276
|
+
...formattingActions ?? []
|
|
277
|
+
] : formattingActions ?? [], [
|
|
278
|
+
enableMediaEmbedding,
|
|
279
|
+
formattingActions,
|
|
280
|
+
mediaFormattingAction
|
|
281
|
+
]);
|
|
282
|
+
const handleEditRenderedMedia = (0, external_react_namespaceObject.useCallback)((media, range)=>{
|
|
283
|
+
const sourceContent = latestContentRef.current;
|
|
284
|
+
const renderedTokens = (0, external_StickyNoteMedia_cjs_namespaceObject.parseStickyNoteMediaTokens)((0, external_StickyNoteNode_utils_cjs_namespaceObject.preserveNewlines)(sourceContent));
|
|
285
|
+
const renderedIndex = renderedTokens.findIndex((token)=>token.start === range.start && token.end === range.end);
|
|
286
|
+
const sourceToken = renderedIndex >= 0 ? (0, external_StickyNoteMedia_cjs_namespaceObject.parseStickyNoteMediaTokens)(sourceContent)[renderedIndex] : void 0;
|
|
287
|
+
setMediaDialog({
|
|
288
|
+
source: 'rendered',
|
|
289
|
+
token: sourceToken ?? {
|
|
290
|
+
media,
|
|
291
|
+
...range
|
|
292
|
+
}
|
|
293
|
+
});
|
|
294
|
+
}, []);
|
|
295
|
+
const cancelMediaDialog = (0, external_react_namespaceObject.useCallback)(()=>{
|
|
296
|
+
const current = mediaDialog;
|
|
297
|
+
setMediaDialog(null);
|
|
298
|
+
if (current?.source === 'editor') current.context.resume();
|
|
299
|
+
}, [
|
|
300
|
+
mediaDialog
|
|
301
|
+
]);
|
|
302
|
+
(0, external_react_namespaceObject.useEffect)(()=>{
|
|
303
|
+
if (!mediaDialog || enableMediaEmbedding && !readOnly) return;
|
|
304
|
+
setMediaDialog(null);
|
|
305
|
+
skipBlurRef.current = null;
|
|
306
|
+
if (!readOnly && 'editor' === mediaDialog.source) mediaDialog.context.resume();
|
|
307
|
+
}, [
|
|
308
|
+
enableMediaEmbedding,
|
|
309
|
+
mediaDialog,
|
|
310
|
+
readOnly
|
|
311
|
+
]);
|
|
312
|
+
const submitMediaDialog = (0, external_react_namespaceObject.useCallback)((media)=>{
|
|
313
|
+
if (!mediaDialog) return;
|
|
314
|
+
const block = (0, external_StickyNoteMedia_cjs_namespaceObject.serializeStickyNoteMedia)(media);
|
|
315
|
+
if ('editor' === mediaDialog.source) {
|
|
316
|
+
const currentValue = mediaDialog.context.currentValue();
|
|
317
|
+
const next = mediaDialog.token ? (0, external_StickyNoteMedia_cjs_namespaceObject.replaceStickyNoteMedia)(currentValue, mediaDialog.token, block) ?? (0, external_StickyNoteMedia_cjs_namespaceObject.insertStickyNoteMedia)(currentValue, block, null) : (0, external_StickyNoteMedia_cjs_namespaceObject.insertStickyNoteMedia)(currentValue, block, mediaDialog.context.selection);
|
|
318
|
+
setMediaDialog(null);
|
|
319
|
+
mediaDialog.context.commit(next);
|
|
320
|
+
return;
|
|
321
|
+
}
|
|
322
|
+
const currentValue = latestContentRef.current;
|
|
323
|
+
const next = (0, external_StickyNoteMedia_cjs_namespaceObject.replaceStickyNoteMedia)(currentValue, mediaDialog.token, block) ?? (0, external_StickyNoteMedia_cjs_namespaceObject.insertStickyNoteMedia)(currentValue, block, null);
|
|
324
|
+
setMediaDialog(null);
|
|
325
|
+
updateLocalContent(next.value);
|
|
326
|
+
onContentChange?.(next.value);
|
|
327
|
+
updateNodeData(id, {
|
|
328
|
+
content: next.value
|
|
329
|
+
});
|
|
330
|
+
}, [
|
|
331
|
+
id,
|
|
332
|
+
mediaDialog,
|
|
333
|
+
onContentChange,
|
|
334
|
+
updateLocalContent,
|
|
335
|
+
updateNodeData
|
|
336
|
+
]);
|
|
247
337
|
const updateActiveFormats = (0, external_react_namespaceObject.useCallback)(()=>{
|
|
248
338
|
if (!textAreaRef.current) return;
|
|
249
339
|
const next = (0, external_markdown_formatting_index_cjs_namespaceObject.detectActiveFormats)({
|
|
@@ -372,12 +462,27 @@ const StickyNoteNodeComponent = ({ id, data, selected, dragging, placeholder = '
|
|
|
372
462
|
children: children
|
|
373
463
|
})
|
|
374
464
|
}), []);
|
|
465
|
+
const mediaMarkdownComponents = (0, external_react_namespaceObject.useMemo)(()=>(0, external_StickyNoteMediaMarkdown_cjs_namespaceObject.createStickyNoteMediaMarkdownComponents)(customMarkdownComponents?.img), [
|
|
466
|
+
customMarkdownComponents?.img
|
|
467
|
+
]);
|
|
375
468
|
const markdownComponents = (0, external_react_namespaceObject.useMemo)(()=>({
|
|
376
469
|
...customMarkdownComponents,
|
|
470
|
+
...enableMediaEmbedding ? mediaMarkdownComponents : {},
|
|
377
471
|
...builtInMarkdownComponents
|
|
378
472
|
}), [
|
|
379
473
|
builtInMarkdownComponents,
|
|
380
|
-
customMarkdownComponents
|
|
474
|
+
customMarkdownComponents,
|
|
475
|
+
enableMediaEmbedding,
|
|
476
|
+
mediaMarkdownComponents
|
|
477
|
+
]);
|
|
478
|
+
const mediaMarkdownOptions = (0, external_react_namespaceObject.useMemo)(()=>({
|
|
479
|
+
editable: enableMediaEmbedding && selected && !readOnly,
|
|
480
|
+
onEditMedia: handleEditRenderedMedia
|
|
481
|
+
}), [
|
|
482
|
+
enableMediaEmbedding,
|
|
483
|
+
handleEditRenderedMedia,
|
|
484
|
+
readOnly,
|
|
485
|
+
selected
|
|
381
486
|
]);
|
|
382
487
|
const toolbarConfig = (0, external_react_namespaceObject.useMemo)(()=>{
|
|
383
488
|
const actions = [
|
|
@@ -553,27 +658,30 @@ const StickyNoteNodeComponent = ({ id, data, selected, dragging, placeholder = '
|
|
|
553
658
|
activeFormats: activeFormats,
|
|
554
659
|
onFormat: handleFormat,
|
|
555
660
|
onBlur: handleBlur,
|
|
556
|
-
actions:
|
|
661
|
+
actions: effectiveFormattingActions,
|
|
557
662
|
onAction: handleFormattingAction
|
|
558
663
|
})
|
|
559
664
|
]
|
|
560
665
|
}) : /*#__PURE__*/ (0, jsx_runtime_namespaceObject.jsx)(external_StickyNoteNode_styles_cjs_namespaceObject.StickyNoteMarkdown, {
|
|
561
666
|
ref: markdownRef,
|
|
562
667
|
...scrollCaptureProps,
|
|
563
|
-
children:
|
|
564
|
-
|
|
565
|
-
|
|
566
|
-
|
|
567
|
-
|
|
568
|
-
|
|
569
|
-
|
|
570
|
-
|
|
571
|
-
|
|
572
|
-
|
|
573
|
-
|
|
574
|
-
|
|
575
|
-
|
|
576
|
-
|
|
668
|
+
children: /*#__PURE__*/ (0, jsx_runtime_namespaceObject.jsx)(external_StickyNoteMediaMarkdown_cjs_namespaceObject.StickyNoteMediaMarkdownProvider, {
|
|
669
|
+
value: mediaMarkdownOptions,
|
|
670
|
+
children: localContent ? /*#__PURE__*/ (0, jsx_runtime_namespaceObject.jsx)(external_react_markdown_default(), {
|
|
671
|
+
remarkPlugins: [
|
|
672
|
+
external_remark_gfm_default(),
|
|
673
|
+
external_remark_breaks_default()
|
|
674
|
+
],
|
|
675
|
+
components: markdownComponents,
|
|
676
|
+
children: (0, external_StickyNoteNode_utils_cjs_namespaceObject.preserveNewlines)(localContent)
|
|
677
|
+
}) : renderPlaceholderOnSelect && selected && /*#__PURE__*/ (0, jsx_runtime_namespaceObject.jsx)(external_react_markdown_default(), {
|
|
678
|
+
remarkPlugins: [
|
|
679
|
+
external_remark_gfm_default(),
|
|
680
|
+
external_remark_breaks_default()
|
|
681
|
+
],
|
|
682
|
+
components: markdownComponents,
|
|
683
|
+
children: placeholder
|
|
684
|
+
})
|
|
577
685
|
})
|
|
578
686
|
})
|
|
579
687
|
]
|
|
@@ -635,6 +743,11 @@ const StickyNoteNodeComponent = ({ id, data, selected, dragging, placeholder = '
|
|
|
635
743
|
})
|
|
636
744
|
})
|
|
637
745
|
]
|
|
746
|
+
}),
|
|
747
|
+
enableMediaEmbedding && mediaDialog && /*#__PURE__*/ (0, jsx_runtime_namespaceObject.jsx)(external_StickyNoteMediaDialog_cjs_namespaceObject.StickyNoteMediaDialog, {
|
|
748
|
+
initialMedia: mediaDialog.token?.media,
|
|
749
|
+
onCancel: cancelMediaDialog,
|
|
750
|
+
onSubmit: submitMediaDialog
|
|
638
751
|
})
|
|
639
752
|
]
|
|
640
753
|
});
|
|
@@ -11,8 +11,9 @@ export interface StickyNoteNodeProps extends NodeProps {
|
|
|
11
11
|
onResize?: (width: number, height: number) => void;
|
|
12
12
|
onResizeStart?: () => void;
|
|
13
13
|
onResizeEnd?: () => void;
|
|
14
|
+
enableMediaEmbedding?: boolean;
|
|
14
15
|
formattingActions?: readonly StickyNoteFormattingAction[];
|
|
15
16
|
markdownComponents?: Omit<Components, 'a'>;
|
|
16
17
|
}
|
|
17
|
-
export declare const StickyNoteNode: import("react").MemoExoticComponent<({ id, data, selected, dragging, placeholder, renderPlaceholderOnSelect, readOnly, onContentChange, onColorChange, onResize, onResizeStart, onResizeEnd, formattingActions, markdownComponents: customMarkdownComponents, }: StickyNoteNodeProps) => import("react/jsx-runtime").JSX.Element>;
|
|
18
|
+
export declare const StickyNoteNode: import("react").MemoExoticComponent<({ id, data, selected, dragging, placeholder, renderPlaceholderOnSelect, readOnly, onContentChange, onColorChange, onResize, onResizeStart, onResizeEnd, enableMediaEmbedding, formattingActions, markdownComponents: customMarkdownComponents, }: StickyNoteNodeProps) => import("react/jsx-runtime").JSX.Element>;
|
|
18
19
|
//# sourceMappingURL=StickyNoteNode.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"StickyNoteNode.d.ts","sourceRoot":"","sources":["../../../../src/canvas/components/StickyNoteNode/StickyNoteNode.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,0CAA0C,CAAC;AAM1E,OAAsB,EAAE,KAAK,UAAU,EAAE,MAAM,gBAAgB,CAAC;
|
|
1
|
+
{"version":3,"file":"StickyNoteNode.d.ts","sourceRoot":"","sources":["../../../../src/canvas/components/StickyNoteNode/StickyNoteNode.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,0CAA0C,CAAC;AAM1E,OAAsB,EAAE,KAAK,UAAU,EAAE,MAAM,gBAAgB,CAAC;AA6ChE,OAAO,KAAK,EACV,eAAe,EACf,cAAc,EAEd,0BAA0B,EAE3B,MAAM,wBAAwB,CAAC;AAMhC,MAAM,WAAW,mBAAoB,SAAQ,SAAS;IACpD,IAAI,EAAE,cAAc,CAAC;IACrB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,yBAAyB,CAAC,EAAE,OAAO,CAAC;IACpC,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,eAAe,CAAC,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,IAAI,CAAC;IAC5C,aAAa,CAAC,EAAE,CAAC,KAAK,EAAE,eAAe,KAAK,IAAI,CAAC;IACjD,QAAQ,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,KAAK,IAAI,CAAC;IACnD,aAAa,CAAC,EAAE,MAAM,IAAI,CAAC;IAC3B,WAAW,CAAC,EAAE,MAAM,IAAI,CAAC;IAEzB,oBAAoB,CAAC,EAAE,OAAO,CAAC;IAC/B,iBAAiB,CAAC,EAAE,SAAS,0BAA0B,EAAE,CAAC;IAC1D,kBAAkB,CAAC,EAAE,IAAI,CAAC,UAAU,EAAE,GAAG,CAAC,CAAC;CAC5C;AA6qBD,eAAO,MAAM,cAAc,yRAhpBxB,mBAAmB,6CAgpBwE,CAAC"}
|
|
@@ -16,6 +16,9 @@ import { NodeViewportOverlay } from "../NodeViewportOverlay.js";
|
|
|
16
16
|
import { NodeToolbar } from "../Toolbar/index.js";
|
|
17
17
|
import { FormattingToolbar } from "./FormattingToolbar.js";
|
|
18
18
|
import { activeFormatsEqual, continueListOnEnter, detectActiveFormats } from "./markdown-formatting/index.js";
|
|
19
|
+
import { findStickyNoteMediaAtSelection, insertStickyNoteMedia, parseStickyNoteMediaTokens, replaceStickyNoteMedia, serializeStickyNoteMedia } from "./StickyNoteMedia.js";
|
|
20
|
+
import { StickyNoteMediaDialog } from "./StickyNoteMediaDialog.js";
|
|
21
|
+
import { StickyNoteMediaMarkdownProvider, createStickyNoteMediaMarkdownComponents } from "./StickyNoteMediaMarkdown.js";
|
|
19
22
|
import { BottomCornerIndicators, ColorOption, ColorPickerPanel, RESIZE_CONTROL_Z_INDEX, ResizeHandle, StickyNoteContainer, StickyNoteMarkdown, StickyNoteTextArea, StickyNoteWrapper, TopCornerIndicators, stickyNoteGlobalStyles } from "./StickyNoteNode.styles.js";
|
|
20
23
|
import { STICKY_NOTE_COLORS, withAlpha } from "./StickyNoteNode.types.js";
|
|
21
24
|
import { preserveNewlines, readTextSelection } from "./StickyNoteNode.utils.js";
|
|
@@ -23,13 +26,14 @@ import { useMarkdownShortcuts } from "./useMarkdownShortcuts.js";
|
|
|
23
26
|
import { useScrollCapture } from "./useScrollCapture.js";
|
|
24
27
|
const minWidth = 8 * GRID_SPACING;
|
|
25
28
|
const minHeight = 8 * GRID_SPACING;
|
|
26
|
-
const StickyNoteNodeComponent = ({ id, data, selected, dragging, placeholder = 'Add text', renderPlaceholderOnSelect = false, readOnly = false, onContentChange, onColorChange, onResize, onResizeStart, onResizeEnd, formattingActions, markdownComponents: customMarkdownComponents })=>{
|
|
29
|
+
const StickyNoteNodeComponent = ({ id, data, selected, dragging, placeholder = 'Add text', renderPlaceholderOnSelect = false, readOnly = false, onContentChange, onColorChange, onResize, onResizeStart, onResizeEnd, enableMediaEmbedding = false, formattingActions, markdownComponents: customMarkdownComponents })=>{
|
|
27
30
|
const { _ } = useSafeLingui();
|
|
28
31
|
const { updateNodeData, deleteElements } = useReactFlow();
|
|
29
32
|
const { multipleNodesSelected } = useSelectionState();
|
|
30
33
|
const [isEditing, setIsEditing] = useState(!readOnly && (data.autoFocus ?? false));
|
|
31
34
|
const [isResizing, setIsResizing] = useState(false);
|
|
32
35
|
const [isColorPickerOpen, setIsColorPickerOpen] = useState(false);
|
|
36
|
+
const [mediaDialog, setMediaDialog] = useState(null);
|
|
33
37
|
const [localContent, setLocalContent] = useState(data.content || '');
|
|
34
38
|
const latestContentRef = useRef(localContent);
|
|
35
39
|
const textAreaRef = useRef(null);
|
|
@@ -204,6 +208,92 @@ const StickyNoteNodeComponent = ({ id, data, selected, dragging, placeholder = '
|
|
|
204
208
|
updateLocalContent,
|
|
205
209
|
updateNodeData
|
|
206
210
|
]);
|
|
211
|
+
const openMediaDialog = useCallback((context)=>{
|
|
212
|
+
const { selection } = context;
|
|
213
|
+
setMediaDialog({
|
|
214
|
+
source: 'editor',
|
|
215
|
+
context,
|
|
216
|
+
token: findStickyNoteMediaAtSelection(selection.value, selection.selectionStart, selection.selectionEnd)
|
|
217
|
+
});
|
|
218
|
+
}, []);
|
|
219
|
+
const mediaFormattingAction = useMemo(()=>({
|
|
220
|
+
id: 'sticky-note-embed-media',
|
|
221
|
+
icon: /*#__PURE__*/ jsx(CanvasIcon, {
|
|
222
|
+
icon: "image-plus",
|
|
223
|
+
size: 14
|
|
224
|
+
}),
|
|
225
|
+
label: _({
|
|
226
|
+
id: 'sticky-note.media.embed-action',
|
|
227
|
+
message: 'Embed image or video'
|
|
228
|
+
}),
|
|
229
|
+
onAction: openMediaDialog
|
|
230
|
+
}), [
|
|
231
|
+
_,
|
|
232
|
+
openMediaDialog
|
|
233
|
+
]);
|
|
234
|
+
const effectiveFormattingActions = useMemo(()=>enableMediaEmbedding ? [
|
|
235
|
+
mediaFormattingAction,
|
|
236
|
+
...formattingActions ?? []
|
|
237
|
+
] : formattingActions ?? [], [
|
|
238
|
+
enableMediaEmbedding,
|
|
239
|
+
formattingActions,
|
|
240
|
+
mediaFormattingAction
|
|
241
|
+
]);
|
|
242
|
+
const handleEditRenderedMedia = useCallback((media, range)=>{
|
|
243
|
+
const sourceContent = latestContentRef.current;
|
|
244
|
+
const renderedTokens = parseStickyNoteMediaTokens(preserveNewlines(sourceContent));
|
|
245
|
+
const renderedIndex = renderedTokens.findIndex((token)=>token.start === range.start && token.end === range.end);
|
|
246
|
+
const sourceToken = renderedIndex >= 0 ? parseStickyNoteMediaTokens(sourceContent)[renderedIndex] : void 0;
|
|
247
|
+
setMediaDialog({
|
|
248
|
+
source: 'rendered',
|
|
249
|
+
token: sourceToken ?? {
|
|
250
|
+
media,
|
|
251
|
+
...range
|
|
252
|
+
}
|
|
253
|
+
});
|
|
254
|
+
}, []);
|
|
255
|
+
const cancelMediaDialog = useCallback(()=>{
|
|
256
|
+
const current = mediaDialog;
|
|
257
|
+
setMediaDialog(null);
|
|
258
|
+
if (current?.source === 'editor') current.context.resume();
|
|
259
|
+
}, [
|
|
260
|
+
mediaDialog
|
|
261
|
+
]);
|
|
262
|
+
useEffect(()=>{
|
|
263
|
+
if (!mediaDialog || enableMediaEmbedding && !readOnly) return;
|
|
264
|
+
setMediaDialog(null);
|
|
265
|
+
skipBlurRef.current = null;
|
|
266
|
+
if (!readOnly && 'editor' === mediaDialog.source) mediaDialog.context.resume();
|
|
267
|
+
}, [
|
|
268
|
+
enableMediaEmbedding,
|
|
269
|
+
mediaDialog,
|
|
270
|
+
readOnly
|
|
271
|
+
]);
|
|
272
|
+
const submitMediaDialog = useCallback((media)=>{
|
|
273
|
+
if (!mediaDialog) return;
|
|
274
|
+
const block = serializeStickyNoteMedia(media);
|
|
275
|
+
if ('editor' === mediaDialog.source) {
|
|
276
|
+
const currentValue = mediaDialog.context.currentValue();
|
|
277
|
+
const next = mediaDialog.token ? replaceStickyNoteMedia(currentValue, mediaDialog.token, block) ?? insertStickyNoteMedia(currentValue, block, null) : insertStickyNoteMedia(currentValue, block, mediaDialog.context.selection);
|
|
278
|
+
setMediaDialog(null);
|
|
279
|
+
mediaDialog.context.commit(next);
|
|
280
|
+
return;
|
|
281
|
+
}
|
|
282
|
+
const currentValue = latestContentRef.current;
|
|
283
|
+
const next = replaceStickyNoteMedia(currentValue, mediaDialog.token, block) ?? insertStickyNoteMedia(currentValue, block, null);
|
|
284
|
+
setMediaDialog(null);
|
|
285
|
+
updateLocalContent(next.value);
|
|
286
|
+
onContentChange?.(next.value);
|
|
287
|
+
updateNodeData(id, {
|
|
288
|
+
content: next.value
|
|
289
|
+
});
|
|
290
|
+
}, [
|
|
291
|
+
id,
|
|
292
|
+
mediaDialog,
|
|
293
|
+
onContentChange,
|
|
294
|
+
updateLocalContent,
|
|
295
|
+
updateNodeData
|
|
296
|
+
]);
|
|
207
297
|
const updateActiveFormats = useCallback(()=>{
|
|
208
298
|
if (!textAreaRef.current) return;
|
|
209
299
|
const next = detectActiveFormats({
|
|
@@ -332,12 +422,27 @@ const StickyNoteNodeComponent = ({ id, data, selected, dragging, placeholder = '
|
|
|
332
422
|
children: children
|
|
333
423
|
})
|
|
334
424
|
}), []);
|
|
425
|
+
const mediaMarkdownComponents = useMemo(()=>createStickyNoteMediaMarkdownComponents(customMarkdownComponents?.img), [
|
|
426
|
+
customMarkdownComponents?.img
|
|
427
|
+
]);
|
|
335
428
|
const markdownComponents = useMemo(()=>({
|
|
336
429
|
...customMarkdownComponents,
|
|
430
|
+
...enableMediaEmbedding ? mediaMarkdownComponents : {},
|
|
337
431
|
...builtInMarkdownComponents
|
|
338
432
|
}), [
|
|
339
433
|
builtInMarkdownComponents,
|
|
340
|
-
customMarkdownComponents
|
|
434
|
+
customMarkdownComponents,
|
|
435
|
+
enableMediaEmbedding,
|
|
436
|
+
mediaMarkdownComponents
|
|
437
|
+
]);
|
|
438
|
+
const mediaMarkdownOptions = useMemo(()=>({
|
|
439
|
+
editable: enableMediaEmbedding && selected && !readOnly,
|
|
440
|
+
onEditMedia: handleEditRenderedMedia
|
|
441
|
+
}), [
|
|
442
|
+
enableMediaEmbedding,
|
|
443
|
+
handleEditRenderedMedia,
|
|
444
|
+
readOnly,
|
|
445
|
+
selected
|
|
341
446
|
]);
|
|
342
447
|
const toolbarConfig = useMemo(()=>{
|
|
343
448
|
const actions = [
|
|
@@ -513,27 +618,30 @@ const StickyNoteNodeComponent = ({ id, data, selected, dragging, placeholder = '
|
|
|
513
618
|
activeFormats: activeFormats,
|
|
514
619
|
onFormat: handleFormat,
|
|
515
620
|
onBlur: handleBlur,
|
|
516
|
-
actions:
|
|
621
|
+
actions: effectiveFormattingActions,
|
|
517
622
|
onAction: handleFormattingAction
|
|
518
623
|
})
|
|
519
624
|
]
|
|
520
625
|
}) : /*#__PURE__*/ jsx(StickyNoteMarkdown, {
|
|
521
626
|
ref: markdownRef,
|
|
522
627
|
...scrollCaptureProps,
|
|
523
|
-
children:
|
|
524
|
-
|
|
525
|
-
|
|
526
|
-
|
|
527
|
-
|
|
528
|
-
|
|
529
|
-
|
|
530
|
-
|
|
531
|
-
|
|
532
|
-
|
|
533
|
-
|
|
534
|
-
|
|
535
|
-
|
|
536
|
-
|
|
628
|
+
children: /*#__PURE__*/ jsx(StickyNoteMediaMarkdownProvider, {
|
|
629
|
+
value: mediaMarkdownOptions,
|
|
630
|
+
children: localContent ? /*#__PURE__*/ jsx(react_markdown, {
|
|
631
|
+
remarkPlugins: [
|
|
632
|
+
remark_gfm,
|
|
633
|
+
remark_breaks
|
|
634
|
+
],
|
|
635
|
+
components: markdownComponents,
|
|
636
|
+
children: preserveNewlines(localContent)
|
|
637
|
+
}) : renderPlaceholderOnSelect && selected && /*#__PURE__*/ jsx(react_markdown, {
|
|
638
|
+
remarkPlugins: [
|
|
639
|
+
remark_gfm,
|
|
640
|
+
remark_breaks
|
|
641
|
+
],
|
|
642
|
+
components: markdownComponents,
|
|
643
|
+
children: placeholder
|
|
644
|
+
})
|
|
537
645
|
})
|
|
538
646
|
})
|
|
539
647
|
]
|
|
@@ -595,6 +703,11 @@ const StickyNoteNodeComponent = ({ id, data, selected, dragging, placeholder = '
|
|
|
595
703
|
})
|
|
596
704
|
})
|
|
597
705
|
]
|
|
706
|
+
}),
|
|
707
|
+
enableMediaEmbedding && mediaDialog && /*#__PURE__*/ jsx(StickyNoteMediaDialog, {
|
|
708
|
+
initialMedia: mediaDialog.token?.media,
|
|
709
|
+
onCancel: cancelMediaDialog,
|
|
710
|
+
onSubmit: submitMediaDialog
|
|
598
711
|
})
|
|
599
712
|
]
|
|
600
713
|
});
|