@selfcommunity/react-ui 0.7.0-alpha.314 → 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 +37 -313
- package/lib/cjs/components/Editor/plugins/ImagePlugin.js +1 -1
- 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 +39 -315
- package/lib/esm/components/Editor/plugins/ImagePlugin.js +1 -1
- package/lib/esm/components/Feed/Feed.js +4 -3
- package/lib/umd/react-ui.js +1 -1
- package/package.json +2 -2
|
@@ -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,248 +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
|
-
return (react_1.default.createElement(Root, { className: classes.root, style: { width: imageRef.current.width, height: imageRef.current.height }, contentEditable: false, onClick: handleStopPropagation },
|
|
73
|
-
react_1.default.createElement(material_1.Paper, null, openResizePanel ? (react_1.default.createElement(react_1.default.Fragment, null,
|
|
74
|
-
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: {
|
|
75
|
-
endAdornment: react_1.default.createElement(material_1.InputAdornment, { position: "start" }, "px")
|
|
76
|
-
} }),
|
|
77
|
-
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: {
|
|
78
|
-
endAdornment: react_1.default.createElement(material_1.InputAdornment, { position: "start" }, "px")
|
|
79
|
-
} }),
|
|
80
|
-
react_1.default.createElement(material_1.Button, { variant: "contained", color: "primary", disabled: width === imageRef.current.width && height === imageRef.current.height, onClick: handleResize },
|
|
81
|
-
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,
|
|
82
|
-
react_1.default.createElement(material_1.Button, { variant: "contained", color: "primary", onClick: handleOpenResizePanel },
|
|
83
|
-
react_1.default.createElement(react_intl_1.FormattedMessage, { id: "ui.editor.imagePluginEdit.resize", defaultMessage: "ui.editor.imagePluginEdit.resize" })),
|
|
84
|
-
react_1.default.createElement(material_1.Button, { variant: "contained", color: "secondary", onClick: onDelete },
|
|
85
|
-
react_1.default.createElement(react_intl_1.FormattedMessage, { id: "ui.editor.imagePluginEdit.delete", defaultMessage: "ui.editor.imagePluginEdit.delete" })))))));
|
|
86
|
-
};
|
|
87
|
-
function clamp(value, min, max) {
|
|
88
|
-
return Math.min(Math.max(value, min), Number(max));
|
|
89
|
-
}
|
|
90
|
-
const Direction = {
|
|
91
|
-
east: 1 << 0,
|
|
92
|
-
north: 1 << 3,
|
|
93
|
-
south: 1 << 1,
|
|
94
|
-
west: 1 << 2
|
|
95
|
-
};
|
|
96
|
-
function ImageResizer({ onResizeStart, onResizeEnd, imageRef, maxWidth, editor }) {
|
|
97
|
-
const controlWrapperRef = (0, react_1.useRef)(null);
|
|
98
|
-
const userSelect = (0, react_1.useRef)({
|
|
99
|
-
priority: '',
|
|
100
|
-
value: 'default'
|
|
101
|
-
});
|
|
102
|
-
const positioningRef = (0, react_1.useRef)({
|
|
103
|
-
currentHeight: 0,
|
|
104
|
-
currentWidth: 0,
|
|
105
|
-
direction: 0,
|
|
106
|
-
isResizing: false,
|
|
107
|
-
ratio: 0,
|
|
108
|
-
startHeight: 0,
|
|
109
|
-
startWidth: 0,
|
|
110
|
-
startX: 0,
|
|
111
|
-
startY: 0
|
|
112
|
-
});
|
|
113
|
-
const editorRootElement = editor.getRootElement();
|
|
114
|
-
// Find max width, accounting for editor padding.
|
|
115
|
-
const maxWidthContainer = maxWidth ? maxWidth : editorRootElement !== null ? editorRootElement.getBoundingClientRect().width - 20 : 100;
|
|
116
|
-
const maxHeightContainer = editorRootElement !== null ? editorRootElement.getBoundingClientRect().height - 20 : 100;
|
|
117
|
-
const minWidth = 100;
|
|
118
|
-
const minHeight = 100;
|
|
119
|
-
const setStartCursor = (direction) => {
|
|
120
|
-
const ew = direction === Direction.east || direction === Direction.west;
|
|
121
|
-
const ns = direction === Direction.north || direction === Direction.south;
|
|
122
|
-
const nwse = (direction & Direction.north && direction & Direction.west) || (direction & Direction.south && direction & Direction.east);
|
|
123
|
-
const cursorDir = ew ? 'ew' : ns ? 'ns' : nwse ? 'nwse' : 'nesw';
|
|
124
|
-
if (editorRootElement !== null) {
|
|
125
|
-
editorRootElement.style.setProperty('cursor', `${cursorDir}-resize`, 'important');
|
|
126
|
-
}
|
|
127
|
-
if (document.body !== null) {
|
|
128
|
-
document.body.style.setProperty('cursor', `${cursorDir}-resize`, 'important');
|
|
129
|
-
userSelect.current.value = document.body.style.getPropertyValue('-webkit-user-select');
|
|
130
|
-
userSelect.current.priority = document.body.style.getPropertyPriority('-webkit-user-select');
|
|
131
|
-
document.body.style.setProperty('-webkit-user-select', `none`, 'important');
|
|
132
|
-
}
|
|
133
|
-
};
|
|
134
|
-
const setEndCursor = () => {
|
|
135
|
-
if (editorRootElement !== null) {
|
|
136
|
-
editorRootElement.style.setProperty('cursor', 'text');
|
|
137
|
-
}
|
|
138
|
-
if (document.body !== null) {
|
|
139
|
-
document.body.style.setProperty('cursor', 'default');
|
|
140
|
-
document.body.style.setProperty('-webkit-user-select', userSelect.current.value, userSelect.current.priority);
|
|
141
|
-
}
|
|
142
|
-
};
|
|
143
|
-
const handlePointerDown = (event, direction) => {
|
|
144
|
-
if (!editor.isEditable()) {
|
|
145
|
-
return;
|
|
146
|
-
}
|
|
147
|
-
const image = imageRef.current;
|
|
148
|
-
const controlWrapper = controlWrapperRef.current;
|
|
149
|
-
if (image !== null && controlWrapper !== null) {
|
|
150
|
-
const { width, height } = image.getBoundingClientRect();
|
|
151
|
-
const positioning = positioningRef.current;
|
|
152
|
-
positioning.startWidth = width;
|
|
153
|
-
positioning.startHeight = height;
|
|
154
|
-
positioning.ratio = width / height;
|
|
155
|
-
positioning.currentWidth = width;
|
|
156
|
-
positioning.currentHeight = height;
|
|
157
|
-
positioning.startX = event.clientX;
|
|
158
|
-
positioning.startY = event.clientY;
|
|
159
|
-
positioning.isResizing = true;
|
|
160
|
-
positioning.direction = direction;
|
|
161
|
-
setStartCursor(direction);
|
|
162
|
-
onResizeStart();
|
|
163
|
-
controlWrapper.classList.add('image-control-wrapper--resizing');
|
|
164
|
-
image.style.height = `${height}px`;
|
|
165
|
-
image.style.width = `${width}px`;
|
|
166
|
-
document.addEventListener('pointermove', handlePointerMove);
|
|
167
|
-
document.addEventListener('pointerup', handlePointerUp);
|
|
168
|
-
}
|
|
169
|
-
};
|
|
170
|
-
const handlePointerMove = (event) => {
|
|
171
|
-
const image = imageRef.current;
|
|
172
|
-
const positioning = positioningRef.current;
|
|
173
|
-
const isHorizontal = positioning.direction & (Direction.east | Direction.west);
|
|
174
|
-
const isVertical = positioning.direction & (Direction.south | Direction.north);
|
|
175
|
-
if (image !== null && positioning.isResizing) {
|
|
176
|
-
// Corner cursor
|
|
177
|
-
if (isHorizontal && isVertical) {
|
|
178
|
-
let diff = Math.floor(positioning.startX - event.clientX);
|
|
179
|
-
diff = positioning.direction & Direction.east ? -diff : diff;
|
|
180
|
-
const width = clamp(positioning.startWidth + diff, minWidth, maxWidthContainer);
|
|
181
|
-
const height = width / positioning.ratio;
|
|
182
|
-
image.style.width = `${width}px`;
|
|
183
|
-
image.style.height = `${height}px`;
|
|
184
|
-
positioning.currentHeight = height;
|
|
185
|
-
positioning.currentWidth = width;
|
|
186
|
-
}
|
|
187
|
-
else if (isVertical) {
|
|
188
|
-
let diff = Math.floor(positioning.startY - event.clientY);
|
|
189
|
-
diff = positioning.direction & Direction.south ? -diff : diff;
|
|
190
|
-
const height = clamp(positioning.startHeight + diff, minHeight, maxHeightContainer);
|
|
191
|
-
image.style.height = `${height}px`;
|
|
192
|
-
positioning.currentHeight = height;
|
|
193
|
-
}
|
|
194
|
-
else {
|
|
195
|
-
let diff = Math.floor(positioning.startX - event.clientX);
|
|
196
|
-
diff = positioning.direction & Direction.east ? -diff : diff;
|
|
197
|
-
const width = clamp(positioning.startWidth + diff, minWidth, maxWidthContainer);
|
|
198
|
-
image.style.width = `${width}px`;
|
|
199
|
-
positioning.currentWidth = width;
|
|
200
|
-
}
|
|
201
|
-
}
|
|
202
|
-
};
|
|
203
|
-
const handlePointerUp = () => {
|
|
204
|
-
const image = imageRef.current;
|
|
205
|
-
const positioning = positioningRef.current;
|
|
206
|
-
const controlWrapper = controlWrapperRef.current;
|
|
207
|
-
if (image !== null && controlWrapper !== null && positioning.isResizing) {
|
|
208
|
-
const width = positioning.currentWidth;
|
|
209
|
-
const height = positioning.currentHeight;
|
|
210
|
-
positioning.startWidth = 0;
|
|
211
|
-
positioning.startHeight = 0;
|
|
212
|
-
positioning.ratio = 0;
|
|
213
|
-
positioning.startX = 0;
|
|
214
|
-
positioning.startY = 0;
|
|
215
|
-
positioning.currentWidth = 0;
|
|
216
|
-
positioning.currentHeight = 0;
|
|
217
|
-
positioning.isResizing = false;
|
|
218
|
-
controlWrapper.classList.remove('image-control-wrapper--resizing');
|
|
219
|
-
setEndCursor();
|
|
220
|
-
console.log(width);
|
|
221
|
-
console.log(height);
|
|
222
|
-
onResizeEnd(width, height);
|
|
223
|
-
document.removeEventListener('pointermove', handlePointerMove);
|
|
224
|
-
document.removeEventListener('pointerup', handlePointerUp);
|
|
225
|
-
}
|
|
226
|
-
};
|
|
227
|
-
return (react_1.default.createElement("div", { ref: controlWrapperRef },
|
|
228
|
-
react_1.default.createElement("div", { className: "image-resizer image-resizer-n", onPointerDown: (event) => {
|
|
229
|
-
handlePointerDown(event, Direction.north);
|
|
230
|
-
} }),
|
|
231
|
-
react_1.default.createElement("div", { className: "image-resizer image-resizer-ne", onPointerDown: (event) => {
|
|
232
|
-
handlePointerDown(event, Direction.north | Direction.east);
|
|
233
|
-
} }),
|
|
234
|
-
react_1.default.createElement("div", { className: "image-resizer image-resizer-e", onPointerDown: (event) => {
|
|
235
|
-
handlePointerDown(event, Direction.east);
|
|
236
|
-
} }),
|
|
237
|
-
react_1.default.createElement("div", { className: "image-resizer image-resizer-se", onPointerDown: (event) => {
|
|
238
|
-
handlePointerDown(event, Direction.south | Direction.east);
|
|
239
|
-
} }),
|
|
240
|
-
react_1.default.createElement("div", { className: "image-resizer image-resizer-s", onPointerDown: (event) => {
|
|
241
|
-
handlePointerDown(event, Direction.south);
|
|
242
|
-
} }),
|
|
243
|
-
react_1.default.createElement("div", { className: "image-resizer image-resizer-sw", onPointerDown: (event) => {
|
|
244
|
-
handlePointerDown(event, Direction.south | Direction.west);
|
|
245
|
-
} }),
|
|
246
|
-
react_1.default.createElement("div", { className: "image-resizer image-resizer-w", onPointerDown: (event) => {
|
|
247
|
-
handlePointerDown(event, Direction.west);
|
|
248
|
-
} }),
|
|
249
|
-
react_1.default.createElement("div", { className: "image-resizer image-resizer-nw", onPointerDown: (event) => {
|
|
250
|
-
handlePointerDown(event, Direction.north | Direction.west);
|
|
251
|
-
} })));
|
|
10
|
+
function getAspectRatio(width, height) {
|
|
11
|
+
return width / height;
|
|
252
12
|
}
|
|
253
13
|
const imageCache = new Set();
|
|
254
14
|
function useSuspenseImage(src) {
|
|
@@ -263,21 +23,21 @@ function useSuspenseImage(src) {
|
|
|
263
23
|
});
|
|
264
24
|
}
|
|
265
25
|
}
|
|
266
|
-
function LazyImage({ altText, className, imageRef, src, width, height
|
|
26
|
+
function LazyImage({ altText, className, imageRef, src, width, height }) {
|
|
267
27
|
useSuspenseImage(src);
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
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
|
+
} })));
|
|
273
35
|
}
|
|
274
|
-
function ImageComponent({ src, altText, nodeKey, width, height
|
|
36
|
+
function ImageComponent({ src, altText, nodeKey, width, height }) {
|
|
275
37
|
const imageRef = (0, react_1.useRef)(null);
|
|
276
38
|
const buttonRef = (0, react_1.useRef)(null);
|
|
277
39
|
const [isSelected, setSelected, clearSelection] = (0, useLexicalNodeSelection_1.useLexicalNodeSelection)(nodeKey);
|
|
278
|
-
const [isResizing, setIsResizing] = (0, react_1.useState)(false);
|
|
279
40
|
const [editor] = (0, LexicalComposerContext_1.useLexicalComposerContext)();
|
|
280
|
-
const [selection, setSelection] = (0, react_1.useState)(null);
|
|
281
41
|
const activeEditorRef = (0, react_1.useRef)(null);
|
|
282
42
|
const onDelete = (0, react_1.useCallback)((payload) => {
|
|
283
43
|
if (isSelected && (0, lexical_1.$isNodeSelection)((0, lexical_1.$getSelection)())) {
|
|
@@ -318,19 +78,11 @@ function ImageComponent({ src, altText, nodeKey, width, height, maxWidth, resiza
|
|
|
318
78
|
return false;
|
|
319
79
|
}, [editor, setSelected]);
|
|
320
80
|
(0, react_1.useEffect)(() => {
|
|
321
|
-
|
|
322
|
-
const unregister = (0, utils_1.mergeRegister)(editor.registerUpdateListener(({ editorState }) => {
|
|
323
|
-
if (isMounted) {
|
|
324
|
-
setSelection(editorState.read(() => (0, lexical_1.$getSelection)()));
|
|
325
|
-
}
|
|
326
|
-
}), editor.registerCommand(lexical_1.SELECTION_CHANGE_COMMAND, (_, activeEditor) => {
|
|
81
|
+
const unregister = (0, utils_1.mergeRegister)(editor.registerCommand(lexical_1.SELECTION_CHANGE_COMMAND, (_, activeEditor) => {
|
|
327
82
|
activeEditorRef.current = activeEditor;
|
|
328
83
|
return false;
|
|
329
84
|
}, lexical_1.COMMAND_PRIORITY_LOW), editor.registerCommand(lexical_1.CLICK_COMMAND, (payload) => {
|
|
330
85
|
const event = payload;
|
|
331
|
-
if (isResizing) {
|
|
332
|
-
return true;
|
|
333
|
-
}
|
|
334
86
|
if (event.target === imageRef.current) {
|
|
335
87
|
if (event.shiftKey) {
|
|
336
88
|
setSelected(!isSelected);
|
|
@@ -342,65 +94,36 @@ function ImageComponent({ src, altText, nodeKey, width, height, maxWidth, resiza
|
|
|
342
94
|
return true;
|
|
343
95
|
}
|
|
344
96
|
return false;
|
|
345
|
-
}, lexical_1.COMMAND_PRIORITY_LOW), editor.registerCommand(lexical_1.DRAGSTART_COMMAND, (event) => {
|
|
346
|
-
if (event.target === imageRef.current) {
|
|
347
|
-
// TODO This is just a temporary workaround for FF to behave like other browsers.
|
|
348
|
-
// Ideally, this handles drag & drop too (and all browsers).
|
|
349
|
-
event.preventDefault();
|
|
350
|
-
return true;
|
|
351
|
-
}
|
|
352
|
-
return false;
|
|
353
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));
|
|
354
98
|
return () => {
|
|
355
|
-
isMounted = false;
|
|
356
99
|
unregister();
|
|
357
100
|
};
|
|
358
|
-
}, [clearSelection, editor,
|
|
359
|
-
const
|
|
360
|
-
// Delay hiding the resize bars for click case
|
|
361
|
-
setTimeout(() => {
|
|
362
|
-
setIsResizing(false);
|
|
363
|
-
}, 200);
|
|
364
|
-
editor.update(() => {
|
|
365
|
-
const node = (0, lexical_1.$getNodeByKey)(nodeKey);
|
|
366
|
-
if ($isImageNode(node)) {
|
|
367
|
-
node.setWidthAndHeight(nextWidth, nextHeight);
|
|
368
|
-
}
|
|
369
|
-
});
|
|
370
|
-
};
|
|
371
|
-
const onResizeStart = () => {
|
|
372
|
-
setIsResizing(true);
|
|
373
|
-
};
|
|
374
|
-
const draggable = isSelected && (0, lexical_1.$isNodeSelection)(selection) && !isResizing;
|
|
375
|
-
const isFocused = isSelected || isResizing;
|
|
101
|
+
}, [clearSelection, editor, isSelected, nodeKey, onDelete, onEnter, onEscape, setSelected]);
|
|
102
|
+
const isFocused = isSelected;
|
|
376
103
|
return (react_1.default.createElement(react_1.Suspense, { fallback: null },
|
|
377
|
-
react_1.default.createElement(
|
|
378
|
-
react_1.default.createElement("div", { draggable: draggable },
|
|
379
|
-
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 })),
|
|
380
|
-
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 })));
|
|
381
105
|
}
|
|
382
106
|
function convertImageElement(domNode) {
|
|
383
107
|
if (domNode instanceof HTMLImageElement) {
|
|
384
|
-
const { alt: altText, src, width, height } = domNode;
|
|
385
|
-
const node = $createImageNode({ altText, height, src, width
|
|
108
|
+
const { alt: altText, src, dataset: { width, height } } = domNode;
|
|
109
|
+
const node = $createImageNode({ altText, height: Number(height), src, width: Number(width) });
|
|
386
110
|
return { node };
|
|
387
111
|
}
|
|
388
112
|
return null;
|
|
389
113
|
}
|
|
390
114
|
class ImageNode extends lexical_1.DecoratorNode {
|
|
391
|
-
constructor(src, altText,
|
|
115
|
+
constructor(src, altText, width, height, key) {
|
|
392
116
|
super(key);
|
|
393
117
|
this.__src = src;
|
|
394
118
|
this.__altText = altText;
|
|
395
|
-
this.
|
|
396
|
-
this.
|
|
397
|
-
this.__height = height || 'inherit';
|
|
119
|
+
this.__width = width;
|
|
120
|
+
this.__height = height;
|
|
398
121
|
}
|
|
399
122
|
static getType() {
|
|
400
123
|
return 'image';
|
|
401
124
|
}
|
|
402
125
|
static clone(node) {
|
|
403
|
-
return new ImageNode(node.__src, node.__altText, node.
|
|
126
|
+
return new ImageNode(node.__src, node.__altText, node.__width, node.__height, node.__key);
|
|
404
127
|
}
|
|
405
128
|
setWidthAndHeight(width, height) {
|
|
406
129
|
const writable = this.getWritable();
|
|
@@ -434,24 +157,26 @@ class ImageNode extends lexical_1.DecoratorNode {
|
|
|
434
157
|
}) }, dom);
|
|
435
158
|
}
|
|
436
159
|
exportDOM() {
|
|
437
|
-
const
|
|
438
|
-
element.
|
|
439
|
-
element.setAttribute('
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
|
|
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);
|
|
443
170
|
return { element };
|
|
444
171
|
}
|
|
445
172
|
decorate() {
|
|
446
|
-
|
|
447
|
-
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() }));
|
|
448
174
|
}
|
|
449
175
|
static importJSON(serializedNode) {
|
|
450
|
-
const { altText, height, width,
|
|
176
|
+
const { altText, height, width, src } = serializedNode;
|
|
451
177
|
const node = $createImageNode({
|
|
452
178
|
altText,
|
|
453
179
|
height,
|
|
454
|
-
maxWidth,
|
|
455
180
|
src,
|
|
456
181
|
width
|
|
457
182
|
});
|
|
@@ -460,18 +185,17 @@ class ImageNode extends lexical_1.DecoratorNode {
|
|
|
460
185
|
exportJSON() {
|
|
461
186
|
return {
|
|
462
187
|
altText: this.getAltText(),
|
|
463
|
-
height: this.__height
|
|
464
|
-
maxWidth: this.__maxWidth,
|
|
188
|
+
height: this.__height,
|
|
465
189
|
src: this.getSrc(),
|
|
466
190
|
type: 'image',
|
|
467
191
|
version: 1,
|
|
468
|
-
width: this.__width
|
|
192
|
+
width: this.__width
|
|
469
193
|
};
|
|
470
194
|
}
|
|
471
195
|
}
|
|
472
196
|
exports.ImageNode = ImageNode;
|
|
473
|
-
function $createImageNode({ src, altText,
|
|
474
|
-
return new ImageNode(src, altText,
|
|
197
|
+
function $createImageNode({ src, altText, width, height }) {
|
|
198
|
+
return new ImageNode(src, altText, width, height);
|
|
475
199
|
}
|
|
476
200
|
exports.$createImageNode = $createImageNode;
|
|
477
201
|
function $isImageNode(node) {
|
|
@@ -94,7 +94,7 @@ function ImagePlugin() {
|
|
|
94
94
|
if ((0, lexical_1.$isRootNode)(selection.anchor.getNode())) {
|
|
95
95
|
selection.insertParagraph();
|
|
96
96
|
}
|
|
97
|
-
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 });
|
|
98
98
|
selection.insertNodes([imageNode]);
|
|
99
99
|
}
|
|
100
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 {};
|