@selfcommunity/react-ui 0.7.0-alpha.313 → 0.7.0-alpha.315
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/lib/cjs/components/Editor/nodes/ImageNode.d.ts +8 -11
- package/lib/cjs/components/Editor/nodes/ImageNode.js +41 -316
- package/lib/cjs/components/Editor/plugins/ImagePlugin.js +9 -4
- package/lib/cjs/components/Feed/Feed.js +3 -2
- package/lib/esm/components/Editor/nodes/ImageNode.d.ts +8 -11
- package/lib/esm/components/Editor/nodes/ImageNode.js +43 -318
- package/lib/esm/components/Editor/plugins/ImagePlugin.js +9 -4
- package/lib/esm/components/Feed/Feed.js +4 -3
- package/lib/umd/react-ui.js +1 -1
- package/package.json +5 -5
|
@@ -3,33 +3,30 @@ import { DecoratorNode, DOMExportOutput, EditorConfig, LexicalNode, NodeKey, Ser
|
|
|
3
3
|
export interface ImagePayload {
|
|
4
4
|
altText: string;
|
|
5
5
|
className?: string;
|
|
6
|
-
height
|
|
6
|
+
height: number;
|
|
7
7
|
imageRef?: LegacyRef<HTMLImageElement>;
|
|
8
|
-
maxWidth: number | string;
|
|
9
8
|
src: string;
|
|
10
|
-
width
|
|
9
|
+
width: number;
|
|
11
10
|
}
|
|
12
11
|
declare function convertImageElement(domNode: any): {
|
|
13
12
|
node: ImageNode;
|
|
14
13
|
};
|
|
15
14
|
export declare type SerializedImageNode = Spread<{
|
|
16
15
|
altText: string;
|
|
17
|
-
height
|
|
18
|
-
maxWidth: number | string;
|
|
16
|
+
height: number;
|
|
19
17
|
src: string;
|
|
20
|
-
width
|
|
18
|
+
width: number;
|
|
21
19
|
type: 'image';
|
|
22
20
|
version: 1;
|
|
23
21
|
}, SerializedLexicalNode>;
|
|
24
22
|
export declare class ImageNode extends DecoratorNode<JSX.Element> {
|
|
25
23
|
__src: string;
|
|
26
24
|
__altText: string;
|
|
27
|
-
__width:
|
|
28
|
-
__height:
|
|
29
|
-
__maxWidth: number | string;
|
|
25
|
+
__width: number;
|
|
26
|
+
__height: number;
|
|
30
27
|
static getType(): string;
|
|
31
28
|
static clone(node: ImageNode): ImageNode;
|
|
32
|
-
constructor(src: string, altText: string,
|
|
29
|
+
constructor(src: string, altText: string, width: number, height: number, key?: NodeKey);
|
|
33
30
|
setWidthAndHeight(width: 'inherit' | number, height: 'inherit' | number): void;
|
|
34
31
|
createDOM(config: EditorConfig): HTMLElement;
|
|
35
32
|
updateDOM(): false;
|
|
@@ -44,6 +41,6 @@ export declare class ImageNode extends DecoratorNode<JSX.Element> {
|
|
|
44
41
|
static importJSON(serializedNode: SerializedImageNode): ImageNode;
|
|
45
42
|
exportJSON(): SerializedImageNode;
|
|
46
43
|
}
|
|
47
|
-
export declare function $createImageNode({ src, altText,
|
|
44
|
+
export declare function $createImageNode({ src, altText, width, height }: ImagePayload): ImageNode;
|
|
48
45
|
export declare function $isImageNode(node?: LexicalNode): boolean;
|
|
49
46
|
export {};
|
|
@@ -7,249 +7,8 @@ const lexical_1 = require("lexical");
|
|
|
7
7
|
const LexicalComposerContext_1 = require("@lexical/react/LexicalComposerContext");
|
|
8
8
|
const useLexicalNodeSelection_1 = require("@lexical/react/useLexicalNodeSelection");
|
|
9
9
|
const utils_1 = require("@lexical/utils");
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
const material_1 = require("@mui/material");
|
|
13
|
-
const PREFIX = 'SCEditorImagePluginImageEdit';
|
|
14
|
-
const classes = {
|
|
15
|
-
root: `${PREFIX}-root`
|
|
16
|
-
};
|
|
17
|
-
const Root = (0, styles_1.styled)(material_1.Box, {
|
|
18
|
-
name: PREFIX,
|
|
19
|
-
slot: 'Root',
|
|
20
|
-
overridesResolver: (props, styles) => styles.root
|
|
21
|
-
})(({ theme }) => ({
|
|
22
|
-
position: 'absolute',
|
|
23
|
-
top: 0,
|
|
24
|
-
left: 0,
|
|
25
|
-
zIndex: 2000,
|
|
26
|
-
outline: `2px solid ${theme.palette.primary.main}`,
|
|
27
|
-
userSelect: 'none',
|
|
28
|
-
display: 'flex',
|
|
29
|
-
justifyContent: 'center',
|
|
30
|
-
alignItems: 'center',
|
|
31
|
-
'& .MuiPaper-root': {
|
|
32
|
-
padding: theme.spacing(1),
|
|
33
|
-
display: 'flex',
|
|
34
|
-
flexDirection: 'column',
|
|
35
|
-
justifyContent: 'center',
|
|
36
|
-
alignItems: 'center',
|
|
37
|
-
width: '50%',
|
|
38
|
-
backgroundColor: theme.palette.background.paper,
|
|
39
|
-
'& > *': {
|
|
40
|
-
margin: theme.spacing(1)
|
|
41
|
-
}
|
|
42
|
-
}
|
|
43
|
-
}));
|
|
44
|
-
const ImageEdit = ({ onResize, onDelete, imageRef }) => {
|
|
45
|
-
// STATE
|
|
46
|
-
const [width, setWidth] = (0, react_1.useState)(imageRef.current.width);
|
|
47
|
-
const [height, setHeight] = (0, react_1.useState)(imageRef.current.height);
|
|
48
|
-
const [openResizePanel, setOpenResizePanel] = (0, react_1.useState)(false);
|
|
49
|
-
// HANDLERS
|
|
50
|
-
const handleStopPropagation = (event) => {
|
|
51
|
-
event.preventDefault();
|
|
52
|
-
event.stopPropagation();
|
|
53
|
-
return false;
|
|
54
|
-
};
|
|
55
|
-
const handleOpenResizePanel = (event) => {
|
|
56
|
-
event.preventDefault();
|
|
57
|
-
event.stopPropagation();
|
|
58
|
-
setOpenResizePanel(true);
|
|
59
|
-
return false;
|
|
60
|
-
};
|
|
61
|
-
const handleChangeWidth = (event) => {
|
|
62
|
-
setWidth(event.target.value);
|
|
63
|
-
};
|
|
64
|
-
const handleChangeHeight = (event) => {
|
|
65
|
-
setHeight(event.target.value);
|
|
66
|
-
};
|
|
67
|
-
const handleResize = (event) => {
|
|
68
|
-
onResize(width, height);
|
|
69
|
-
setOpenResizePanel(false);
|
|
70
|
-
};
|
|
71
|
-
// RENDER
|
|
72
|
-
console.log(width);
|
|
73
|
-
return (react_1.default.createElement(Root, { className: classes.root, style: { width: imageRef.current.width, height: imageRef.current.height }, contentEditable: false, onClick: handleStopPropagation },
|
|
74
|
-
react_1.default.createElement(material_1.Paper, null, openResizePanel ? (react_1.default.createElement(react_1.default.Fragment, null,
|
|
75
|
-
react_1.default.createElement(material_1.TextField, { value: width, type: "number", onChange: handleChangeWidth, label: react_1.default.createElement(react_intl_1.FormattedMessage, { id: "ui.editor.imagePluginEdit.width", defaultMessage: "ui.editor.imagePluginEdit.width" }), InputProps: {
|
|
76
|
-
endAdornment: react_1.default.createElement(material_1.InputAdornment, { position: "start" }, "px")
|
|
77
|
-
} }),
|
|
78
|
-
react_1.default.createElement(material_1.TextField, { value: height, type: "number", onChange: handleChangeHeight, label: react_1.default.createElement(react_intl_1.FormattedMessage, { id: "ui.editor.imagePluginEdit.height", defaultMessage: "ui.editor.imagePluginEdit.height" }), InputProps: {
|
|
79
|
-
endAdornment: react_1.default.createElement(material_1.InputAdornment, { position: "start" }, "px")
|
|
80
|
-
} }),
|
|
81
|
-
react_1.default.createElement(material_1.Button, { variant: "contained", color: "primary", disabled: width === imageRef.current.width && height === imageRef.current.height, onClick: handleResize },
|
|
82
|
-
react_1.default.createElement(react_intl_1.FormattedMessage, { id: "ui.editor.imagePluginEdit.resize", defaultMessage: "ui.editor.imagePluginEdit.resize" })))) : (react_1.default.createElement(react_1.default.Fragment, null,
|
|
83
|
-
react_1.default.createElement(material_1.Button, { variant: "contained", color: "primary", onClick: handleOpenResizePanel },
|
|
84
|
-
react_1.default.createElement(react_intl_1.FormattedMessage, { id: "ui.editor.imagePluginEdit.resize", defaultMessage: "ui.editor.imagePluginEdit.resize" })),
|
|
85
|
-
react_1.default.createElement(material_1.Button, { variant: "contained", color: "secondary", onClick: onDelete },
|
|
86
|
-
react_1.default.createElement(react_intl_1.FormattedMessage, { id: "ui.editor.imagePluginEdit.delete", defaultMessage: "ui.editor.imagePluginEdit.delete" })))))));
|
|
87
|
-
};
|
|
88
|
-
function clamp(value, min, max) {
|
|
89
|
-
return Math.min(Math.max(value, min), Number(max));
|
|
90
|
-
}
|
|
91
|
-
const Direction = {
|
|
92
|
-
east: 1 << 0,
|
|
93
|
-
north: 1 << 3,
|
|
94
|
-
south: 1 << 1,
|
|
95
|
-
west: 1 << 2
|
|
96
|
-
};
|
|
97
|
-
function ImageResizer({ onResizeStart, onResizeEnd, imageRef, maxWidth, editor }) {
|
|
98
|
-
const controlWrapperRef = (0, react_1.useRef)(null);
|
|
99
|
-
const userSelect = (0, react_1.useRef)({
|
|
100
|
-
priority: '',
|
|
101
|
-
value: 'default'
|
|
102
|
-
});
|
|
103
|
-
const positioningRef = (0, react_1.useRef)({
|
|
104
|
-
currentHeight: 0,
|
|
105
|
-
currentWidth: 0,
|
|
106
|
-
direction: 0,
|
|
107
|
-
isResizing: false,
|
|
108
|
-
ratio: 0,
|
|
109
|
-
startHeight: 0,
|
|
110
|
-
startWidth: 0,
|
|
111
|
-
startX: 0,
|
|
112
|
-
startY: 0
|
|
113
|
-
});
|
|
114
|
-
const editorRootElement = editor.getRootElement();
|
|
115
|
-
// Find max width, accounting for editor padding.
|
|
116
|
-
const maxWidthContainer = maxWidth ? maxWidth : editorRootElement !== null ? editorRootElement.getBoundingClientRect().width - 20 : 100;
|
|
117
|
-
const maxHeightContainer = editorRootElement !== null ? editorRootElement.getBoundingClientRect().height - 20 : 100;
|
|
118
|
-
const minWidth = 100;
|
|
119
|
-
const minHeight = 100;
|
|
120
|
-
const setStartCursor = (direction) => {
|
|
121
|
-
const ew = direction === Direction.east || direction === Direction.west;
|
|
122
|
-
const ns = direction === Direction.north || direction === Direction.south;
|
|
123
|
-
const nwse = (direction & Direction.north && direction & Direction.west) || (direction & Direction.south && direction & Direction.east);
|
|
124
|
-
const cursorDir = ew ? 'ew' : ns ? 'ns' : nwse ? 'nwse' : 'nesw';
|
|
125
|
-
if (editorRootElement !== null) {
|
|
126
|
-
editorRootElement.style.setProperty('cursor', `${cursorDir}-resize`, 'important');
|
|
127
|
-
}
|
|
128
|
-
if (document.body !== null) {
|
|
129
|
-
document.body.style.setProperty('cursor', `${cursorDir}-resize`, 'important');
|
|
130
|
-
userSelect.current.value = document.body.style.getPropertyValue('-webkit-user-select');
|
|
131
|
-
userSelect.current.priority = document.body.style.getPropertyPriority('-webkit-user-select');
|
|
132
|
-
document.body.style.setProperty('-webkit-user-select', `none`, 'important');
|
|
133
|
-
}
|
|
134
|
-
};
|
|
135
|
-
const setEndCursor = () => {
|
|
136
|
-
if (editorRootElement !== null) {
|
|
137
|
-
editorRootElement.style.setProperty('cursor', 'text');
|
|
138
|
-
}
|
|
139
|
-
if (document.body !== null) {
|
|
140
|
-
document.body.style.setProperty('cursor', 'default');
|
|
141
|
-
document.body.style.setProperty('-webkit-user-select', userSelect.current.value, userSelect.current.priority);
|
|
142
|
-
}
|
|
143
|
-
};
|
|
144
|
-
const handlePointerDown = (event, direction) => {
|
|
145
|
-
if (!editor.isEditable()) {
|
|
146
|
-
return;
|
|
147
|
-
}
|
|
148
|
-
const image = imageRef.current;
|
|
149
|
-
const controlWrapper = controlWrapperRef.current;
|
|
150
|
-
if (image !== null && controlWrapper !== null) {
|
|
151
|
-
const { width, height } = image.getBoundingClientRect();
|
|
152
|
-
const positioning = positioningRef.current;
|
|
153
|
-
positioning.startWidth = width;
|
|
154
|
-
positioning.startHeight = height;
|
|
155
|
-
positioning.ratio = width / height;
|
|
156
|
-
positioning.currentWidth = width;
|
|
157
|
-
positioning.currentHeight = height;
|
|
158
|
-
positioning.startX = event.clientX;
|
|
159
|
-
positioning.startY = event.clientY;
|
|
160
|
-
positioning.isResizing = true;
|
|
161
|
-
positioning.direction = direction;
|
|
162
|
-
setStartCursor(direction);
|
|
163
|
-
onResizeStart();
|
|
164
|
-
controlWrapper.classList.add('image-control-wrapper--resizing');
|
|
165
|
-
image.style.height = `${height}px`;
|
|
166
|
-
image.style.width = `${width}px`;
|
|
167
|
-
document.addEventListener('pointermove', handlePointerMove);
|
|
168
|
-
document.addEventListener('pointerup', handlePointerUp);
|
|
169
|
-
}
|
|
170
|
-
};
|
|
171
|
-
const handlePointerMove = (event) => {
|
|
172
|
-
const image = imageRef.current;
|
|
173
|
-
const positioning = positioningRef.current;
|
|
174
|
-
const isHorizontal = positioning.direction & (Direction.east | Direction.west);
|
|
175
|
-
const isVertical = positioning.direction & (Direction.south | Direction.north);
|
|
176
|
-
if (image !== null && positioning.isResizing) {
|
|
177
|
-
// Corner cursor
|
|
178
|
-
if (isHorizontal && isVertical) {
|
|
179
|
-
let diff = Math.floor(positioning.startX - event.clientX);
|
|
180
|
-
diff = positioning.direction & Direction.east ? -diff : diff;
|
|
181
|
-
const width = clamp(positioning.startWidth + diff, minWidth, maxWidthContainer);
|
|
182
|
-
const height = width / positioning.ratio;
|
|
183
|
-
image.style.width = `${width}px`;
|
|
184
|
-
image.style.height = `${height}px`;
|
|
185
|
-
positioning.currentHeight = height;
|
|
186
|
-
positioning.currentWidth = width;
|
|
187
|
-
}
|
|
188
|
-
else if (isVertical) {
|
|
189
|
-
let diff = Math.floor(positioning.startY - event.clientY);
|
|
190
|
-
diff = positioning.direction & Direction.south ? -diff : diff;
|
|
191
|
-
const height = clamp(positioning.startHeight + diff, minHeight, maxHeightContainer);
|
|
192
|
-
image.style.height = `${height}px`;
|
|
193
|
-
positioning.currentHeight = height;
|
|
194
|
-
}
|
|
195
|
-
else {
|
|
196
|
-
let diff = Math.floor(positioning.startX - event.clientX);
|
|
197
|
-
diff = positioning.direction & Direction.east ? -diff : diff;
|
|
198
|
-
const width = clamp(positioning.startWidth + diff, minWidth, maxWidthContainer);
|
|
199
|
-
image.style.width = `${width}px`;
|
|
200
|
-
positioning.currentWidth = width;
|
|
201
|
-
}
|
|
202
|
-
}
|
|
203
|
-
};
|
|
204
|
-
const handlePointerUp = () => {
|
|
205
|
-
const image = imageRef.current;
|
|
206
|
-
const positioning = positioningRef.current;
|
|
207
|
-
const controlWrapper = controlWrapperRef.current;
|
|
208
|
-
if (image !== null && controlWrapper !== null && positioning.isResizing) {
|
|
209
|
-
const width = positioning.currentWidth;
|
|
210
|
-
const height = positioning.currentHeight;
|
|
211
|
-
positioning.startWidth = 0;
|
|
212
|
-
positioning.startHeight = 0;
|
|
213
|
-
positioning.ratio = 0;
|
|
214
|
-
positioning.startX = 0;
|
|
215
|
-
positioning.startY = 0;
|
|
216
|
-
positioning.currentWidth = 0;
|
|
217
|
-
positioning.currentHeight = 0;
|
|
218
|
-
positioning.isResizing = false;
|
|
219
|
-
controlWrapper.classList.remove('image-control-wrapper--resizing');
|
|
220
|
-
setEndCursor();
|
|
221
|
-
console.log(width);
|
|
222
|
-
console.log(height);
|
|
223
|
-
onResizeEnd(width, height);
|
|
224
|
-
document.removeEventListener('pointermove', handlePointerMove);
|
|
225
|
-
document.removeEventListener('pointerup', handlePointerUp);
|
|
226
|
-
}
|
|
227
|
-
};
|
|
228
|
-
return (react_1.default.createElement("div", { ref: controlWrapperRef },
|
|
229
|
-
react_1.default.createElement("div", { className: "image-resizer image-resizer-n", onPointerDown: (event) => {
|
|
230
|
-
handlePointerDown(event, Direction.north);
|
|
231
|
-
} }),
|
|
232
|
-
react_1.default.createElement("div", { className: "image-resizer image-resizer-ne", onPointerDown: (event) => {
|
|
233
|
-
handlePointerDown(event, Direction.north | Direction.east);
|
|
234
|
-
} }),
|
|
235
|
-
react_1.default.createElement("div", { className: "image-resizer image-resizer-e", onPointerDown: (event) => {
|
|
236
|
-
handlePointerDown(event, Direction.east);
|
|
237
|
-
} }),
|
|
238
|
-
react_1.default.createElement("div", { className: "image-resizer image-resizer-se", onPointerDown: (event) => {
|
|
239
|
-
handlePointerDown(event, Direction.south | Direction.east);
|
|
240
|
-
} }),
|
|
241
|
-
react_1.default.createElement("div", { className: "image-resizer image-resizer-s", onPointerDown: (event) => {
|
|
242
|
-
handlePointerDown(event, Direction.south);
|
|
243
|
-
} }),
|
|
244
|
-
react_1.default.createElement("div", { className: "image-resizer image-resizer-sw", onPointerDown: (event) => {
|
|
245
|
-
handlePointerDown(event, Direction.south | Direction.west);
|
|
246
|
-
} }),
|
|
247
|
-
react_1.default.createElement("div", { className: "image-resizer image-resizer-w", onPointerDown: (event) => {
|
|
248
|
-
handlePointerDown(event, Direction.west);
|
|
249
|
-
} }),
|
|
250
|
-
react_1.default.createElement("div", { className: "image-resizer image-resizer-nw", onPointerDown: (event) => {
|
|
251
|
-
handlePointerDown(event, Direction.north | Direction.west);
|
|
252
|
-
} })));
|
|
10
|
+
function getAspectRatio(width, height) {
|
|
11
|
+
return width / height;
|
|
253
12
|
}
|
|
254
13
|
const imageCache = new Set();
|
|
255
14
|
function useSuspenseImage(src) {
|
|
@@ -264,21 +23,21 @@ function useSuspenseImage(src) {
|
|
|
264
23
|
});
|
|
265
24
|
}
|
|
266
25
|
}
|
|
267
|
-
function LazyImage({ altText, className, imageRef, src, width, height
|
|
26
|
+
function LazyImage({ altText, className, imageRef, src, width, height }) {
|
|
268
27
|
useSuspenseImage(src);
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
28
|
+
const aspectRatio = getAspectRatio(width, height);
|
|
29
|
+
return (react_1.default.createElement("div", { draggable: false, className: className, style: { position: 'relative', paddingBottom: `${100 / aspectRatio}%` } },
|
|
30
|
+
react_1.default.createElement("img", { src: src, alt: altText, ref: imageRef, style: {
|
|
31
|
+
position: 'absolute',
|
|
32
|
+
height: `100%`,
|
|
33
|
+
width: `100%`
|
|
34
|
+
} })));
|
|
274
35
|
}
|
|
275
|
-
function ImageComponent({ src, altText, nodeKey, width, height
|
|
36
|
+
function ImageComponent({ src, altText, nodeKey, width, height }) {
|
|
276
37
|
const imageRef = (0, react_1.useRef)(null);
|
|
277
38
|
const buttonRef = (0, react_1.useRef)(null);
|
|
278
39
|
const [isSelected, setSelected, clearSelection] = (0, useLexicalNodeSelection_1.useLexicalNodeSelection)(nodeKey);
|
|
279
|
-
const [isResizing, setIsResizing] = (0, react_1.useState)(false);
|
|
280
40
|
const [editor] = (0, LexicalComposerContext_1.useLexicalComposerContext)();
|
|
281
|
-
const [selection, setSelection] = (0, react_1.useState)(null);
|
|
282
41
|
const activeEditorRef = (0, react_1.useRef)(null);
|
|
283
42
|
const onDelete = (0, react_1.useCallback)((payload) => {
|
|
284
43
|
if (isSelected && (0, lexical_1.$isNodeSelection)((0, lexical_1.$getSelection)())) {
|
|
@@ -319,19 +78,11 @@ function ImageComponent({ src, altText, nodeKey, width, height, maxWidth, resiza
|
|
|
319
78
|
return false;
|
|
320
79
|
}, [editor, setSelected]);
|
|
321
80
|
(0, react_1.useEffect)(() => {
|
|
322
|
-
|
|
323
|
-
const unregister = (0, utils_1.mergeRegister)(editor.registerUpdateListener(({ editorState }) => {
|
|
324
|
-
if (isMounted) {
|
|
325
|
-
setSelection(editorState.read(() => (0, lexical_1.$getSelection)()));
|
|
326
|
-
}
|
|
327
|
-
}), editor.registerCommand(lexical_1.SELECTION_CHANGE_COMMAND, (_, activeEditor) => {
|
|
81
|
+
const unregister = (0, utils_1.mergeRegister)(editor.registerCommand(lexical_1.SELECTION_CHANGE_COMMAND, (_, activeEditor) => {
|
|
328
82
|
activeEditorRef.current = activeEditor;
|
|
329
83
|
return false;
|
|
330
84
|
}, lexical_1.COMMAND_PRIORITY_LOW), editor.registerCommand(lexical_1.CLICK_COMMAND, (payload) => {
|
|
331
85
|
const event = payload;
|
|
332
|
-
if (isResizing) {
|
|
333
|
-
return true;
|
|
334
|
-
}
|
|
335
86
|
if (event.target === imageRef.current) {
|
|
336
87
|
if (event.shiftKey) {
|
|
337
88
|
setSelected(!isSelected);
|
|
@@ -343,63 +94,36 @@ function ImageComponent({ src, altText, nodeKey, width, height, maxWidth, resiza
|
|
|
343
94
|
return true;
|
|
344
95
|
}
|
|
345
96
|
return false;
|
|
346
|
-
}, lexical_1.COMMAND_PRIORITY_LOW), editor.registerCommand(lexical_1.DRAGSTART_COMMAND, (event) => {
|
|
347
|
-
if (event.target === imageRef.current) {
|
|
348
|
-
// TODO This is just a temporary workaround for FF to behave like other browsers.
|
|
349
|
-
// Ideally, this handles drag & drop too (and all browsers).
|
|
350
|
-
event.preventDefault();
|
|
351
|
-
return true;
|
|
352
|
-
}
|
|
353
|
-
return false;
|
|
354
97
|
}, lexical_1.COMMAND_PRIORITY_LOW), editor.registerCommand(lexical_1.KEY_DELETE_COMMAND, onDelete, lexical_1.COMMAND_PRIORITY_LOW), editor.registerCommand(lexical_1.KEY_BACKSPACE_COMMAND, onDelete, lexical_1.COMMAND_PRIORITY_LOW), editor.registerCommand(lexical_1.KEY_ENTER_COMMAND, onEnter, lexical_1.COMMAND_PRIORITY_LOW), editor.registerCommand(lexical_1.KEY_ESCAPE_COMMAND, onEscape, lexical_1.COMMAND_PRIORITY_LOW));
|
|
355
98
|
return () => {
|
|
356
|
-
isMounted = false;
|
|
357
99
|
unregister();
|
|
358
100
|
};
|
|
359
|
-
}, [clearSelection, editor,
|
|
360
|
-
const
|
|
361
|
-
// Delay hiding the resize bars for click case
|
|
362
|
-
setTimeout(() => {
|
|
363
|
-
setIsResizing(false);
|
|
364
|
-
}, 200);
|
|
365
|
-
editor.update(() => {
|
|
366
|
-
const node = (0, lexical_1.$getNodeByKey)(nodeKey);
|
|
367
|
-
if ($isImageNode(node)) {
|
|
368
|
-
node.setWidthAndHeight(nextWidth, nextHeight);
|
|
369
|
-
}
|
|
370
|
-
});
|
|
371
|
-
};
|
|
372
|
-
const onResizeStart = () => {
|
|
373
|
-
setIsResizing(true);
|
|
374
|
-
};
|
|
375
|
-
const draggable = isSelected && (0, lexical_1.$isNodeSelection)(selection) && !isResizing;
|
|
376
|
-
const isFocused = isSelected || isResizing;
|
|
101
|
+
}, [clearSelection, editor, isSelected, nodeKey, onDelete, onEnter, onEscape, setSelected]);
|
|
102
|
+
const isFocused = isSelected;
|
|
377
103
|
return (react_1.default.createElement(react_1.Suspense, { fallback: null },
|
|
378
|
-
react_1.default.createElement(
|
|
379
|
-
react_1.default.createElement("div", { draggable: draggable },
|
|
380
|
-
react_1.default.createElement(LazyImage, { className: isFocused ? `focused ${(0, lexical_1.$isNodeSelection)(selection) ? 'draggable' : ''}` : null, src: src, altText: altText, imageRef: imageRef, width: width, height: height, maxWidth: maxWidth })),
|
|
381
|
-
resizable && (0, lexical_1.$isNodeSelection)(selection) && isFocused && (react_1.default.createElement(ImageResizer, { editor: editor, imageRef: imageRef, maxWidth: typeof maxWidth === 'number' ? maxWidth : null, onResizeStart: onResizeStart, onResizeEnd: onResizeEnd })))));
|
|
104
|
+
react_1.default.createElement(LazyImage, { className: isFocused ? `focused` : null, src: src, altText: altText, imageRef: imageRef, width: width, height: height })));
|
|
382
105
|
}
|
|
383
106
|
function convertImageElement(domNode) {
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
node
|
|
387
|
-
|
|
107
|
+
if (domNode instanceof HTMLImageElement) {
|
|
108
|
+
const { alt: altText, src, dataset: { width, height } } = domNode;
|
|
109
|
+
const node = $createImageNode({ altText, height: Number(height), src, width: Number(width) });
|
|
110
|
+
return { node };
|
|
111
|
+
}
|
|
112
|
+
return null;
|
|
388
113
|
}
|
|
389
114
|
class ImageNode extends lexical_1.DecoratorNode {
|
|
390
|
-
constructor(src, altText,
|
|
115
|
+
constructor(src, altText, width, height, key) {
|
|
391
116
|
super(key);
|
|
392
117
|
this.__src = src;
|
|
393
118
|
this.__altText = altText;
|
|
394
|
-
this.
|
|
395
|
-
this.
|
|
396
|
-
this.__height = height || 'inherit';
|
|
119
|
+
this.__width = width;
|
|
120
|
+
this.__height = height;
|
|
397
121
|
}
|
|
398
122
|
static getType() {
|
|
399
123
|
return 'image';
|
|
400
124
|
}
|
|
401
125
|
static clone(node) {
|
|
402
|
-
return new ImageNode(node.__src, node.__altText, node.
|
|
126
|
+
return new ImageNode(node.__src, node.__altText, node.__width, node.__height, node.__key);
|
|
403
127
|
}
|
|
404
128
|
setWidthAndHeight(width, height) {
|
|
405
129
|
const writable = this.getWritable();
|
|
@@ -433,24 +157,26 @@ class ImageNode extends lexical_1.DecoratorNode {
|
|
|
433
157
|
}) }, dom);
|
|
434
158
|
}
|
|
435
159
|
exportDOM() {
|
|
436
|
-
const
|
|
437
|
-
element.
|
|
438
|
-
element.setAttribute('
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
|
|
160
|
+
const aspectRatio = getAspectRatio(this.__width, this.__height);
|
|
161
|
+
const element = document.createElement('div');
|
|
162
|
+
element.setAttribute('style', `position: relative;padding-bottom:${100 / aspectRatio}%`);
|
|
163
|
+
const image = document.createElement('img');
|
|
164
|
+
image.setAttribute('src', this.__src);
|
|
165
|
+
image.setAttribute('alt', this.__altText);
|
|
166
|
+
image.setAttribute('style', `position: absolute;width:100%;height:100%;`);
|
|
167
|
+
image.setAttribute('data-width', `${this.__width}`);
|
|
168
|
+
image.setAttribute('data-height', `${this.__height}`);
|
|
169
|
+
element.appendChild(image);
|
|
442
170
|
return { element };
|
|
443
171
|
}
|
|
444
172
|
decorate() {
|
|
445
|
-
|
|
446
|
-
return (react_1.default.createElement(ImageComponent, { src: this.__src, altText: this.__altText, width: this.__width, height: this.__height, maxWidth: this.__maxWidth, nodeKey: this.getKey(), resizable: true }));
|
|
173
|
+
return (react_1.default.createElement(ImageComponent, { src: this.__src, altText: this.__altText, width: this.__width, height: this.__height, nodeKey: this.getKey() }));
|
|
447
174
|
}
|
|
448
175
|
static importJSON(serializedNode) {
|
|
449
|
-
const { altText, height, width,
|
|
176
|
+
const { altText, height, width, src } = serializedNode;
|
|
450
177
|
const node = $createImageNode({
|
|
451
178
|
altText,
|
|
452
179
|
height,
|
|
453
|
-
maxWidth,
|
|
454
180
|
src,
|
|
455
181
|
width
|
|
456
182
|
});
|
|
@@ -459,18 +185,17 @@ class ImageNode extends lexical_1.DecoratorNode {
|
|
|
459
185
|
exportJSON() {
|
|
460
186
|
return {
|
|
461
187
|
altText: this.getAltText(),
|
|
462
|
-
height: this.__height
|
|
463
|
-
maxWidth: this.__maxWidth,
|
|
188
|
+
height: this.__height,
|
|
464
189
|
src: this.getSrc(),
|
|
465
190
|
type: 'image',
|
|
466
191
|
version: 1,
|
|
467
|
-
width: this.__width
|
|
192
|
+
width: this.__width
|
|
468
193
|
};
|
|
469
194
|
}
|
|
470
195
|
}
|
|
471
196
|
exports.ImageNode = ImageNode;
|
|
472
|
-
function $createImageNode({ src, altText,
|
|
473
|
-
return new ImageNode(src, altText,
|
|
197
|
+
function $createImageNode({ src, altText, width, height }) {
|
|
198
|
+
return new ImageNode(src, altText, width, height);
|
|
474
199
|
}
|
|
475
200
|
exports.$createImageNode = $createImageNode;
|
|
476
201
|
function $isImageNode(node) {
|
|
@@ -32,12 +32,17 @@ function Image({ editor, className = '' }) {
|
|
|
32
32
|
return file.type.startsWith('image/');
|
|
33
33
|
};
|
|
34
34
|
const handleUploadSuccess = (media) => {
|
|
35
|
-
const
|
|
36
|
-
|
|
37
|
-
src: media.image,
|
|
35
|
+
const image = media.image_thumbnail ? media.image_thumbnail : {
|
|
36
|
+
url: media.image,
|
|
38
37
|
width: media.image_width,
|
|
39
38
|
height: media.image_height
|
|
40
39
|
};
|
|
40
|
+
const data = {
|
|
41
|
+
altText: media.title,
|
|
42
|
+
src: image.url,
|
|
43
|
+
width: image.width,
|
|
44
|
+
height: image.height
|
|
45
|
+
};
|
|
41
46
|
editor.focus();
|
|
42
47
|
editor.dispatchCommand(exports.INSERT_IMAGE_COMMAND, data);
|
|
43
48
|
editor.dispatchCommand(lexical_1.INSERT_PARAGRAPH_COMMAND, undefined);
|
|
@@ -89,7 +94,7 @@ function ImagePlugin() {
|
|
|
89
94
|
if ((0, lexical_1.$isRootNode)(selection.anchor.getNode())) {
|
|
90
95
|
selection.insertParagraph();
|
|
91
96
|
}
|
|
92
|
-
const imageNode = (0, ImageNode_1.$createImageNode)({ src: payload.src, altText: payload.altText,
|
|
97
|
+
const imageNode = (0, ImageNode_1.$createImageNode)({ src: payload.src, altText: payload.altText, width: payload.width, height: payload.height });
|
|
93
98
|
selection.insertNodes([imageNode]);
|
|
94
99
|
}
|
|
95
100
|
return true;
|
|
@@ -28,6 +28,7 @@ const PREFIX = 'SCFeed';
|
|
|
28
28
|
const classes = {
|
|
29
29
|
root: `${PREFIX}-root`,
|
|
30
30
|
left: `${PREFIX}-left`,
|
|
31
|
+
leftItems: `${PREFIX}-left-items`,
|
|
31
32
|
start: `${PREFIX}-start`,
|
|
32
33
|
end: `${PREFIX}-end`,
|
|
33
34
|
endMessage: `${PREFIX}-end-message`,
|
|
@@ -414,14 +415,14 @@ const Feed = (inProps, ref) => {
|
|
|
414
415
|
react_1.default.createElement(CustomAdv_1.default, Object.assign({ position: types_1.SCCustomAdvPosition.POSITION_BELOW_TOPBAR }, CustomAdvProps)))) : null,
|
|
415
416
|
react_1.default.createElement(material_1.Grid, { item: true, xs: 12, md: 7 },
|
|
416
417
|
react_1.default.createElement("div", { style: { overflow: 'visible' } },
|
|
417
|
-
react_1.default.createElement(InfiniteScroll_1.default, { className: classes.left, dataLength: feedDataLeft.length, next: getNextPage, previous: getPreviousPage, hasMoreNext: Boolean(feedDataObject.next), hasMorePrevious: Boolean(feedDataObject.previous), header: PreviousPageLink, footer: NextPageLink, loaderNext: react_1.default.createElement(ItemSkeleton, Object.assign({}, ItemSkeletonProps)), loaderPrevious: react_1.default.createElement(ItemSkeleton, Object.assign({}, ItemSkeletonProps)), scrollThreshold:
|
|
418
|
+
react_1.default.createElement(InfiniteScroll_1.default, { className: classes.left, dataLength: feedDataLeft.length, next: getNextPage, previous: getPreviousPage, hasMoreNext: Boolean(feedDataObject.next), hasMorePrevious: Boolean(feedDataObject.previous), header: PreviousPageLink, footer: NextPageLink, loaderNext: react_1.default.createElement(ItemSkeleton, Object.assign({}, ItemSkeletonProps)), loaderPrevious: react_1.default.createElement(ItemSkeleton, Object.assign({}, ItemSkeletonProps)), scrollThreshold: '80%', endMessage: react_1.default.createElement(material_1.Box, { className: classes.end },
|
|
418
419
|
react_1.default.createElement(Widget_1.default, { className: classes.endMessage },
|
|
419
420
|
react_1.default.createElement(material_1.CardContent, null, endMessage)),
|
|
420
421
|
advEnabled && !hideAdvs && enabledCustomAdvPositions.includes(types_1.SCCustomAdvPosition.POSITION_ABOVE_FOOTER_BAR) ? (react_1.default.createElement(CustomAdv_1.default, Object.assign({ position: types_1.SCCustomAdvPosition.POSITION_ABOVE_FOOTER_BAR }, CustomAdvProps))) : null,
|
|
421
422
|
FooterComponent ? react_1.default.createElement(FooterComponent, Object.assign({}, FooterComponentProps)) : null), refreshFunction: refresh, pullDownToRefresh: true, pullDownToRefreshThreshold: 1000, pullDownToRefreshContent: null, releaseToRefreshContent: react_1.default.createElement(Widget_1.default, { variant: "outlined", className: classes.refresh },
|
|
422
423
|
react_1.default.createElement(material_1.CardContent, null, refreshMessage)), style: { overflow: 'visible' } },
|
|
423
424
|
renderHeaderComponent(),
|
|
424
|
-
react_1.default.createElement(VirtualizedScroller_1.default, Object.assign({ items: feedDataLeft, itemComponent: InnerItem, onMount: onScrollerMount, onScrollerStateChange: onScrollerStateChange, getItemId: getScrollItemId, preserveScrollPosition: true, preserveScrollPositionOnPrependItems: true, cacheScrollStateKey: react_core_1.SCCache.getVirtualizedScrollStateCacheKey(id), cacheScrollerPositionKey: react_core_1.SCCache.getFeedSPCacheKey(id), cacheStrategy: cacheStrategy }, VirtualizedScrollerProps))))),
|
|
425
|
+
react_1.default.createElement(VirtualizedScroller_1.default, Object.assign({ className: classes.leftItems, items: feedDataLeft, itemComponent: InnerItem, onMount: onScrollerMount, onScrollerStateChange: onScrollerStateChange, getItemId: getScrollItemId, preserveScrollPosition: true, preserveScrollPositionOnPrependItems: true, cacheScrollStateKey: react_core_1.SCCache.getVirtualizedScrollStateCacheKey(id), cacheScrollerPositionKey: react_core_1.SCCache.getFeedSPCacheKey(id), cacheStrategy: cacheStrategy }, VirtualizedScrollerProps))))),
|
|
425
426
|
feedDataRight.length > 0 && !hideAdvs && (react_1.default.createElement(material_1.Hidden, { smDown: true },
|
|
426
427
|
react_1.default.createElement(material_1.Grid, { item: true, xs: 12, md: 5 },
|
|
427
428
|
react_1.default.createElement(StickyBox_1.default, Object.assign({ className: classes.right }, FeedSidebarProps),
|
|
@@ -3,33 +3,30 @@ import { DecoratorNode, DOMExportOutput, EditorConfig, LexicalNode, NodeKey, Ser
|
|
|
3
3
|
export interface ImagePayload {
|
|
4
4
|
altText: string;
|
|
5
5
|
className?: string;
|
|
6
|
-
height
|
|
6
|
+
height: number;
|
|
7
7
|
imageRef?: LegacyRef<HTMLImageElement>;
|
|
8
|
-
maxWidth: number | string;
|
|
9
8
|
src: string;
|
|
10
|
-
width
|
|
9
|
+
width: number;
|
|
11
10
|
}
|
|
12
11
|
declare function convertImageElement(domNode: any): {
|
|
13
12
|
node: ImageNode;
|
|
14
13
|
};
|
|
15
14
|
export declare type SerializedImageNode = Spread<{
|
|
16
15
|
altText: string;
|
|
17
|
-
height
|
|
18
|
-
maxWidth: number | string;
|
|
16
|
+
height: number;
|
|
19
17
|
src: string;
|
|
20
|
-
width
|
|
18
|
+
width: number;
|
|
21
19
|
type: 'image';
|
|
22
20
|
version: 1;
|
|
23
21
|
}, SerializedLexicalNode>;
|
|
24
22
|
export declare class ImageNode extends DecoratorNode<JSX.Element> {
|
|
25
23
|
__src: string;
|
|
26
24
|
__altText: string;
|
|
27
|
-
__width:
|
|
28
|
-
__height:
|
|
29
|
-
__maxWidth: number | string;
|
|
25
|
+
__width: number;
|
|
26
|
+
__height: number;
|
|
30
27
|
static getType(): string;
|
|
31
28
|
static clone(node: ImageNode): ImageNode;
|
|
32
|
-
constructor(src: string, altText: string,
|
|
29
|
+
constructor(src: string, altText: string, width: number, height: number, key?: NodeKey);
|
|
33
30
|
setWidthAndHeight(width: 'inherit' | number, height: 'inherit' | number): void;
|
|
34
31
|
createDOM(config: EditorConfig): HTMLElement;
|
|
35
32
|
updateDOM(): false;
|
|
@@ -44,6 +41,6 @@ export declare class ImageNode extends DecoratorNode<JSX.Element> {
|
|
|
44
41
|
static importJSON(serializedNode: SerializedImageNode): ImageNode;
|
|
45
42
|
exportJSON(): SerializedImageNode;
|
|
46
43
|
}
|
|
47
|
-
export declare function $createImageNode({ src, altText,
|
|
44
|
+
export declare function $createImageNode({ src, altText, width, height }: ImagePayload): ImageNode;
|
|
48
45
|
export declare function $isImageNode(node?: LexicalNode): boolean;
|
|
49
46
|
export {};
|