@pie-lib/editable-html-tip-tap 1.0.20 → 1.0.21-next.6057
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/CHANGELOG.md +7 -73
- package/LICENSE.md +5 -0
- package/NEXT.CHANGELOG.json +1 -0
- package/lib/components/CharacterPicker.js +20 -60
- package/lib/components/CharacterPicker.js.map +1 -1
- package/lib/components/EditableHtml.js +50 -121
- package/lib/components/EditableHtml.js.map +1 -1
- package/lib/components/MenuBar.js +96 -128
- package/lib/components/MenuBar.js.map +1 -1
- package/lib/components/TiptapContainer.js +162 -45
- package/lib/components/TiptapContainer.js.map +1 -1
- package/lib/components/characters/characterUtils.js +4 -7
- package/lib/components/characters/characterUtils.js.map +1 -1
- package/lib/components/characters/custom-popper.js +22 -51
- package/lib/components/characters/custom-popper.js.map +1 -1
- package/lib/components/common/done-button.js +17 -36
- package/lib/components/common/done-button.js.map +1 -1
- package/lib/components/common/toolbar-buttons.js +57 -107
- package/lib/components/common/toolbar-buttons.js.map +1 -1
- package/lib/components/icons/CssIcon.js +14 -26
- package/lib/components/icons/CssIcon.js.map +1 -1
- package/lib/components/icons/RespArea.js +23 -46
- package/lib/components/icons/RespArea.js.map +1 -1
- package/lib/components/icons/TableIcons.js +20 -36
- package/lib/components/icons/TableIcons.js.map +1 -1
- package/lib/components/icons/TextAlign.js +16 -53
- package/lib/components/icons/TextAlign.js.map +1 -1
- package/lib/components/image/AltDialog.js +18 -49
- package/lib/components/image/AltDialog.js.map +1 -1
- package/lib/components/image/ImageToolbar.js +50 -90
- package/lib/components/image/ImageToolbar.js.map +1 -1
- package/lib/components/image/InsertImageHandler.js +17 -35
- package/lib/components/image/InsertImageHandler.js.map +1 -1
- package/lib/components/media/MediaDialog.js +195 -309
- package/lib/components/media/MediaDialog.js.map +1 -1
- package/lib/components/media/MediaToolbar.js +39 -66
- package/lib/components/media/MediaToolbar.js.map +1 -1
- package/lib/components/media/MediaWrapper.js +30 -56
- package/lib/components/media/MediaWrapper.js.map +1 -1
- package/lib/components/respArea/DragInTheBlank/DragInTheBlank.js +21 -36
- package/lib/components/respArea/DragInTheBlank/DragInTheBlank.js.map +1 -1
- package/lib/components/respArea/DragInTheBlank/choice.js +215 -262
- package/lib/components/respArea/DragInTheBlank/choice.js.map +1 -1
- package/lib/components/respArea/ExplicitConstructedResponse.js +11 -33
- package/lib/components/respArea/ExplicitConstructedResponse.js.map +1 -1
- package/lib/components/respArea/InlineDropdown.js +19 -41
- package/lib/components/respArea/InlineDropdown.js.map +1 -1
- package/lib/components/respArea/ToolbarIcon.js +21 -45
- package/lib/components/respArea/ToolbarIcon.js.map +1 -1
- package/lib/constants.js +3 -5
- package/lib/constants.js.map +1 -1
- package/lib/extensions/component.js +94 -148
- package/lib/extensions/component.js.map +1 -1
- package/lib/extensions/css.js +9 -44
- package/lib/extensions/css.js.map +1 -1
- package/lib/extensions/custom-toolbar-wrapper.js +66 -94
- package/lib/extensions/custom-toolbar-wrapper.js.map +1 -1
- package/lib/extensions/extended-table.js +2 -6
- package/lib/extensions/extended-table.js.map +1 -1
- package/lib/extensions/image.js +4 -17
- package/lib/extensions/image.js.map +1 -1
- package/lib/extensions/index.js +13 -23
- package/lib/extensions/index.js.map +1 -1
- package/lib/extensions/math.js +45 -96
- package/lib/extensions/math.js.map +1 -1
- package/lib/extensions/media.js +21 -59
- package/lib/extensions/media.js.map +1 -1
- package/lib/extensions/responseArea.js +43 -89
- package/lib/extensions/responseArea.js.map +1 -1
- package/lib/index.js +9 -11
- package/lib/index.js.map +1 -1
- package/lib/styles/editorContainerStyles.js +2 -7
- package/lib/styles/editorContainerStyles.js.map +1 -1
- package/lib/theme.js +2 -3
- package/lib/theme.js.map +1 -1
- package/lib/utils/size.js +2 -10
- package/lib/utils/size.js.map +1 -1
- package/package.json +15 -13
- package/src/components/EditableHtml.jsx +21 -33
- package/src/components/MenuBar.jsx +66 -37
- package/src/components/TiptapContainer.jsx +133 -34
- package/src/components/characters/custom-popper.js +18 -28
- package/src/components/common/done-button.jsx +15 -26
- package/src/components/common/toolbar-buttons.jsx +28 -44
- package/src/components/icons/CssIcon.jsx +11 -13
- package/src/components/icons/RespArea.jsx +16 -16
- package/src/components/icons/TableIcons.jsx +15 -16
- package/src/components/icons/TextAlign.jsx +3 -3
- package/src/components/image/AltDialog.jsx +6 -6
- package/src/components/image/ImageToolbar.jsx +28 -29
- package/src/components/media/MediaDialog.js +61 -78
- package/src/components/media/MediaToolbar.jsx +30 -37
- package/src/components/media/MediaWrapper.jsx +12 -16
- package/src/components/respArea/DragInTheBlank/DragInTheBlank.jsx +5 -4
- package/src/components/respArea/DragInTheBlank/choice.jsx +191 -185
- package/src/components/respArea/ToolbarIcon.jsx +13 -15
- package/src/extensions/component.jsx +61 -89
- package/src/extensions/css.js +6 -5
- package/src/extensions/custom-toolbar-wrapper.jsx +61 -81
- package/src/extensions/index.js +2 -2
- package/src/index.jsx +2 -2
- package/lib/__tests__/utils.js +0 -106
- package/src/__tests__/utils.js +0 -36
|
@@ -1,215 +1,221 @@
|
|
|
1
|
-
import React from 'react';
|
|
1
|
+
import React, { useRef, useEffect, useState } from 'react';
|
|
2
2
|
import PropTypes from 'prop-types';
|
|
3
|
-
import
|
|
4
|
-
import { DragSource, DropTarget } from '@pie-lib/drag';
|
|
3
|
+
import { useDraggable, useDroppable } from '@dnd-kit/core';
|
|
5
4
|
import { color } from '@pie-lib/render-ui';
|
|
6
5
|
import { renderMath } from '@pie-lib/math-rendering';
|
|
7
|
-
import {
|
|
6
|
+
import { styled } from '@mui/material/styles';
|
|
8
7
|
import classnames from 'classnames';
|
|
9
8
|
|
|
10
9
|
import { GripIcon } from '../../icons/RespArea';
|
|
11
10
|
|
|
12
|
-
const
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
'
|
|
16
|
-
fontSize: '120% !important',
|
|
17
|
-
},
|
|
18
|
-
},
|
|
19
|
-
chip: {
|
|
20
|
-
minWidth: '90px',
|
|
21
|
-
},
|
|
22
|
-
correct: {
|
|
23
|
-
border: `solid 1px ${color.correct()}`,
|
|
24
|
-
},
|
|
25
|
-
incorrect: {
|
|
26
|
-
border: `solid 1px ${theme.palette.error.main}`,
|
|
27
|
-
},
|
|
28
|
-
selected: {
|
|
29
|
-
border: `2px solid ${color.primaryDark()} !important`,
|
|
11
|
+
const StyledContent = styled('span')(({ theme }) => ({
|
|
12
|
+
border: `solid 0px ${theme.palette.primary.main}`,
|
|
13
|
+
'& mjx-frac': {
|
|
14
|
+
fontSize: '120% !important',
|
|
30
15
|
},
|
|
31
16
|
}));
|
|
32
17
|
|
|
33
|
-
export
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
children: PropTypes.func,
|
|
37
|
-
isDragging: PropTypes.bool,
|
|
38
|
-
isOver: PropTypes.bool,
|
|
39
|
-
dragItem: PropTypes.object,
|
|
40
|
-
value: PropTypes.object,
|
|
41
|
-
classes: PropTypes.object,
|
|
42
|
-
};
|
|
43
|
-
|
|
44
|
-
constructor(props) {
|
|
45
|
-
super(props);
|
|
46
|
-
|
|
47
|
-
this.handleClick = this.handleClick.bind(this);
|
|
48
|
-
this.state = { hoveredElementSize: null };
|
|
49
|
-
}
|
|
50
|
-
|
|
51
|
-
componentDidMount() {
|
|
52
|
-
document.addEventListener('click', this.handleClick);
|
|
53
|
-
}
|
|
18
|
+
export function BlankContent({ n, children, isDragging, isOver, dragItem, value }) {
|
|
19
|
+
const [hoveredElementSize, setHoveredElementSize] = useState(null);
|
|
20
|
+
const elementRef = useRef(null);
|
|
54
21
|
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
}
|
|
22
|
+
const handleClick = (event) => {
|
|
23
|
+
if (!elementRef.current) return;
|
|
58
24
|
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
this.elementRef.className = this.elementRef.contains(event.target) ? classes.selected : '';
|
|
64
|
-
}
|
|
65
|
-
}
|
|
66
|
-
|
|
67
|
-
getSnapshotBeforeUpdate(prevProps) {
|
|
68
|
-
if (!prevProps.isOver && this.props.isOver && this.elementRef) {
|
|
69
|
-
const node = this.elementRef;
|
|
70
|
-
return { width: node.offsetWidth, height: node.offsetHeight };
|
|
25
|
+
if (elementRef.current.contains(event.target)) {
|
|
26
|
+
elementRef.current.classList.add('selected');
|
|
27
|
+
} else {
|
|
28
|
+
elementRef.current.classList.remove('selected');
|
|
71
29
|
}
|
|
72
|
-
|
|
73
|
-
}
|
|
30
|
+
};
|
|
74
31
|
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
32
|
+
useEffect(() => {
|
|
33
|
+
document.addEventListener('click', handleClick);
|
|
34
|
+
return () => {
|
|
35
|
+
document.removeEventListener('click', handleClick);
|
|
36
|
+
};
|
|
37
|
+
}, []);
|
|
79
38
|
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
(
|
|
83
|
-
this.state.hoveredElementSize.width !== snapshot.width ||
|
|
84
|
-
this.state.hoveredElementSize.height !== snapshot.height)
|
|
85
|
-
) {
|
|
86
|
-
this.setState({ hoveredElementSize: snapshot });
|
|
87
|
-
return;
|
|
39
|
+
useEffect(() => {
|
|
40
|
+
if (elementRef.current && typeof renderMath === 'function') {
|
|
41
|
+
renderMath(elementRef.current);
|
|
88
42
|
}
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
43
|
+
}, [value?.value, isOver, dragItem?.value?.value]);
|
|
44
|
+
|
|
45
|
+
useEffect(() => {
|
|
46
|
+
if (isOver && elementRef.current && !hoveredElementSize) {
|
|
47
|
+
const node = elementRef.current;
|
|
48
|
+
setHoveredElementSize({ width: node.offsetWidth, height: node.offsetHeight });
|
|
49
|
+
} else if (!isOver && hoveredElementSize) {
|
|
50
|
+
setHoveredElementSize(null);
|
|
92
51
|
}
|
|
93
|
-
}
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
position: 'absolute',
|
|
128
|
-
top: '6px',
|
|
129
|
-
left: '15px',
|
|
130
|
-
color: '#9B9B9B',
|
|
131
|
-
}}
|
|
132
|
-
contentEditable={false}
|
|
133
|
-
/>
|
|
134
|
-
)}
|
|
135
|
-
<span
|
|
136
|
-
dangerouslySetInnerHTML={{
|
|
137
|
-
__html: finalLabel,
|
|
52
|
+
}, [isOver, hoveredElementSize]);
|
|
53
|
+
|
|
54
|
+
const label = dragItem && isOver ? dragItem.value.value : value.value || '\u00A0';
|
|
55
|
+
const finalLabel = isDragging ? '\u00A0' : label;
|
|
56
|
+
const hasGrip = finalLabel !== '\u00A0';
|
|
57
|
+
const isPreview = dragItem && isOver;
|
|
58
|
+
|
|
59
|
+
return (
|
|
60
|
+
<div
|
|
61
|
+
ref={elementRef}
|
|
62
|
+
style={{
|
|
63
|
+
display: 'inline-flex',
|
|
64
|
+
minWidth: '178px',
|
|
65
|
+
minHeight: '36px',
|
|
66
|
+
background: isPreview ? `${color.defaults.BORDER_LIGHT}` : `${color.defaults.WHITE}`,
|
|
67
|
+
border: isPreview ? `1px solid ${color.defaults.BORDER_DARK}` : `1px solid ${color.defaults.BORDER_LIGHT}`,
|
|
68
|
+
boxSizing: 'border-box',
|
|
69
|
+
borderRadius: '3px',
|
|
70
|
+
overflow: 'hidden',
|
|
71
|
+
position: 'relative',
|
|
72
|
+
padding: '8px 8px 8px 35px',
|
|
73
|
+
width: hoveredElementSize ? hoveredElementSize.width : undefined,
|
|
74
|
+
height: hoveredElementSize ? hoveredElementSize.height : undefined,
|
|
75
|
+
}}
|
|
76
|
+
data-key={n.index}
|
|
77
|
+
contentEditable={false}
|
|
78
|
+
>
|
|
79
|
+
{hasGrip && (
|
|
80
|
+
<GripIcon
|
|
81
|
+
style={{
|
|
82
|
+
position: 'absolute',
|
|
83
|
+
top: '6px',
|
|
84
|
+
left: '15px',
|
|
85
|
+
color: '#9B9B9B',
|
|
138
86
|
}}
|
|
87
|
+
contentEditable={false}
|
|
139
88
|
/>
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
89
|
+
)}
|
|
90
|
+
<span
|
|
91
|
+
dangerouslySetInnerHTML={{
|
|
92
|
+
__html: finalLabel,
|
|
93
|
+
}}
|
|
94
|
+
/>
|
|
95
|
+
{children}
|
|
96
|
+
</div>
|
|
97
|
+
);
|
|
144
98
|
}
|
|
145
99
|
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
return connectDropTarget ? connectDropTarget(content) : content;
|
|
155
|
-
});
|
|
156
|
-
|
|
157
|
-
export const tileTarget = {
|
|
158
|
-
drop(props, monitor) {
|
|
159
|
-
const draggedItem = monitor.getItem();
|
|
160
|
-
const shouldDrop =
|
|
161
|
-
isUndefined(draggedItem.value.index) ||
|
|
162
|
-
isUndefined(props.value.index) ||
|
|
163
|
-
draggedItem.value.index !== props.value.index;
|
|
100
|
+
BlankContent.propTypes = {
|
|
101
|
+
n: PropTypes.object,
|
|
102
|
+
children: PropTypes.node,
|
|
103
|
+
isDragging: PropTypes.bool,
|
|
104
|
+
isOver: PropTypes.bool,
|
|
105
|
+
dragItem: PropTypes.object,
|
|
106
|
+
value: PropTypes.object,
|
|
107
|
+
};
|
|
164
108
|
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
109
|
+
function DragDropChoice({ value, disabled, instanceId, children, n, onChange, removeResponse, duplicates, pos }) {
|
|
110
|
+
const { attributes: dragAttributes, listeners: dragListeners, setNodeRef: setDragNodeRef, isDragging } = useDraggable(
|
|
111
|
+
{
|
|
112
|
+
id: `drag-${n.index}`,
|
|
113
|
+
disabled: disabled || !value?.value,
|
|
114
|
+
data: {
|
|
115
|
+
id: `drag-${n.index}`,
|
|
116
|
+
value,
|
|
117
|
+
instanceId,
|
|
118
|
+
n,
|
|
119
|
+
pos,
|
|
120
|
+
opts: { duplicates },
|
|
121
|
+
type: 'drag-in-the-blank-placed-choice',
|
|
122
|
+
fromChoice: !value,
|
|
123
|
+
onRemove: (draggedData) => removeResponse(draggedData),
|
|
124
|
+
onDrop: (draggedData, dropData) => {
|
|
125
|
+
// check if we're dropping into a blank
|
|
126
|
+
const isValidBlank = dropData?.type === 'drag-in-the-blank-drop-choice';
|
|
127
|
+
|
|
128
|
+
if (!isValidBlank) return;
|
|
129
|
+
|
|
130
|
+
// place into blank
|
|
131
|
+
onChange(draggedData);
|
|
132
|
+
|
|
133
|
+
if (!duplicates && draggedData.fromChoice) {
|
|
134
|
+
removeResponse(draggedData);
|
|
135
|
+
}
|
|
136
|
+
},
|
|
137
|
+
},
|
|
138
|
+
},
|
|
139
|
+
);
|
|
140
|
+
|
|
141
|
+
const { setNodeRef: setDropNodeRef, isOver, active: dragItem } = useDroppable({
|
|
142
|
+
id: `drop-${n.index}`,
|
|
143
|
+
data: {
|
|
144
|
+
type: 'drag-in-the-blank-drop-choice',
|
|
145
|
+
accepts: ['drag-in-the-blank-choice', 'drag-in-the-blank-placed-choice'],
|
|
146
|
+
instanceId: instanceId,
|
|
147
|
+
value: value,
|
|
148
|
+
id: `drop-${n.index}`,
|
|
149
|
+
pos,
|
|
150
|
+
n,
|
|
151
|
+
opts: { duplicates },
|
|
152
|
+
onDrop: (draggedData, dropData) => {
|
|
153
|
+
// check if we're dropping into a blank
|
|
154
|
+
const isValidBlank = dropData?.type === 'drag-in-the-blank-drop-choice';
|
|
155
|
+
|
|
156
|
+
if (!isValidBlank) return;
|
|
157
|
+
|
|
158
|
+
// if the dragged and dropped data are the same, do nothing
|
|
159
|
+
if (draggedData.value.id === dropData.value.id) return;
|
|
160
|
+
|
|
161
|
+
if (draggedData.type === 'drag-in-the-blank-choice') {
|
|
162
|
+
// place into blank
|
|
163
|
+
onChange(draggedData);
|
|
164
|
+
|
|
165
|
+
if (!duplicates && draggedData.fromChoice) {
|
|
166
|
+
removeResponse(draggedData);
|
|
167
|
+
}
|
|
168
|
+
return;
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
// moving placed choice between blanks
|
|
172
|
+
if (draggedData.type === 'drag-in-the-blank-placed-choice') {
|
|
173
|
+
// clear target blank
|
|
174
|
+
removeResponse(dropData);
|
|
175
|
+
|
|
176
|
+
// set new blank value
|
|
177
|
+
onChange(draggedData);
|
|
178
|
+
|
|
179
|
+
// clear original blank - slight delay to ensure state updates correctly
|
|
180
|
+
setTimeout(() => removeResponse(draggedData), 10);
|
|
181
|
+
}
|
|
182
|
+
},
|
|
183
|
+
},
|
|
184
|
+
});
|
|
168
185
|
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
}
|
|
173
|
-
canDrop(props, monitor) {
|
|
174
|
-
const draggedItem = monitor.getItem();
|
|
186
|
+
const setNodeRef = (node) => {
|
|
187
|
+
setDragNodeRef(node);
|
|
188
|
+
setDropNodeRef(node);
|
|
189
|
+
};
|
|
175
190
|
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
}
|
|
191
|
+
const dragContent = (
|
|
192
|
+
<BlankContent n={n} isDragging={isDragging} isOver={isOver} dragItem={dragItem?.data?.current} value={value}>
|
|
193
|
+
{children}
|
|
194
|
+
</BlankContent>
|
|
195
|
+
);
|
|
179
196
|
|
|
180
|
-
const
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
}
|
|
197
|
+
const dragEl = !value ? (
|
|
198
|
+
<span ref={setDropNodeRef}>{dragContent}</span>
|
|
199
|
+
) : (
|
|
200
|
+
<span ref={setNodeRef} {...dragAttributes} {...dragListeners}>
|
|
201
|
+
{dragContent}
|
|
202
|
+
</span>
|
|
203
|
+
);
|
|
185
204
|
|
|
186
|
-
|
|
187
|
-
canDrag(props) {
|
|
188
|
-
return !props.disabled && !!props.value;
|
|
189
|
-
},
|
|
190
|
-
beginDrag(props) {
|
|
191
|
-
return {
|
|
192
|
-
id: props.targetId,
|
|
193
|
-
value: props.value,
|
|
194
|
-
instanceId: props.instanceId,
|
|
195
|
-
fromChoice: true,
|
|
196
|
-
};
|
|
197
|
-
},
|
|
198
|
-
endDrag(props, monitor) {
|
|
199
|
-
// this will be null if it did not drop
|
|
200
|
-
const dropResult = monitor.getDropResult();
|
|
205
|
+
const content = <StyledContent className={classnames(isOver && 'over')}>{dragEl}</StyledContent>;
|
|
201
206
|
|
|
202
|
-
|
|
203
|
-
|
|
207
|
+
return content;
|
|
208
|
+
}
|
|
204
209
|
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
+
DragDropChoice.propTypes = {
|
|
211
|
+
value: PropTypes.object,
|
|
212
|
+
disabled: PropTypes.bool,
|
|
213
|
+
instanceId: PropTypes.string,
|
|
214
|
+
children: PropTypes.node,
|
|
215
|
+
n: PropTypes.object.isRequired,
|
|
216
|
+
onChange: PropTypes.func.isRequired,
|
|
217
|
+
removeResponse: PropTypes.func.isRequired,
|
|
218
|
+
duplicates: PropTypes.bool,
|
|
210
219
|
};
|
|
211
220
|
|
|
212
|
-
export default
|
|
213
|
-
connectDragSource: connect.dragSource(),
|
|
214
|
-
isDragging: monitor.isDragging(),
|
|
215
|
-
}))(DropTile);
|
|
221
|
+
export default DragDropChoice;
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
|
-
import {
|
|
2
|
+
import { styled } from '@mui/material/styles';
|
|
3
3
|
|
|
4
4
|
export const Chevron = (props) => {
|
|
5
5
|
const { direction, style } = props;
|
|
@@ -51,18 +51,16 @@ export const GripIcon = ({ style }) => (
|
|
|
51
51
|
</span>
|
|
52
52
|
);
|
|
53
53
|
|
|
54
|
-
const
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
},
|
|
66
|
-
});
|
|
54
|
+
const StyledToolbarIcon = styled('div')(({ theme }) => ({
|
|
55
|
+
fontFamily: 'Cerebri Sans !important',
|
|
56
|
+
fontSize: theme.typography.fontSize,
|
|
57
|
+
fontWeight: 'bold',
|
|
58
|
+
lineHeight: '14px',
|
|
59
|
+
position: 'relative',
|
|
60
|
+
top: '7px',
|
|
61
|
+
width: '110px',
|
|
62
|
+
height: '28px',
|
|
63
|
+
whiteSpace: 'nowrap',
|
|
64
|
+
}));
|
|
67
65
|
|
|
68
|
-
export const ToolbarIcon =
|
|
66
|
+
export const ToolbarIcon = () => <StyledToolbarIcon>+ Response Area</StyledToolbarIcon>;
|
|
@@ -1,10 +1,9 @@
|
|
|
1
1
|
import React, { useState, useRef, useEffect, useCallback } from 'react';
|
|
2
2
|
import PropTypes from 'prop-types';
|
|
3
|
-
import classNames from 'classnames';
|
|
4
3
|
import isEqual from 'lodash/isEqual';
|
|
5
4
|
import debug from 'debug';
|
|
6
|
-
import LinearProgress from '@material
|
|
7
|
-
import {
|
|
5
|
+
import LinearProgress from '@mui/material/LinearProgress';
|
|
6
|
+
import { styled } from '@mui/material/styles';
|
|
8
7
|
import { NodeViewWrapper } from '@tiptap/react';
|
|
9
8
|
import InsertImageHandler from '../components/image/InsertImageHandler';
|
|
10
9
|
import ImageToolbar from '../components/image/ImageToolbar';
|
|
@@ -12,13 +11,61 @@ import CustomToolbarWrapper from './custom-toolbar-wrapper';
|
|
|
12
11
|
|
|
13
12
|
const log = debug('@pie-lib:editable-html:plugins:image:component');
|
|
14
13
|
|
|
14
|
+
const StyledProgress = styled(LinearProgress, {
|
|
15
|
+
shouldForwardProp: (prop) => prop !== 'hideProgress',
|
|
16
|
+
})(({ hideProgress }) => ({
|
|
17
|
+
position: 'absolute',
|
|
18
|
+
left: '0',
|
|
19
|
+
width: 'fit-content',
|
|
20
|
+
top: '0%',
|
|
21
|
+
transition: 'opacity 200ms linear',
|
|
22
|
+
...(hideProgress && {
|
|
23
|
+
opacity: 0,
|
|
24
|
+
}),
|
|
25
|
+
}));
|
|
26
|
+
|
|
27
|
+
const StyledRoot = styled('div', {
|
|
28
|
+
shouldForwardProp: (prop) => !['active', 'loading', 'pendingDelete'].includes(prop),
|
|
29
|
+
})(({ theme, active, loading, pendingDelete }) => ({
|
|
30
|
+
position: 'relative',
|
|
31
|
+
border: active ? `solid 1px ${theme.palette.primary.main}` : `solid 1px ${theme.palette.common.white}`,
|
|
32
|
+
display: 'flex',
|
|
33
|
+
transition: 'opacity 200ms linear',
|
|
34
|
+
...(loading && {
|
|
35
|
+
opacity: 0.3,
|
|
36
|
+
}),
|
|
37
|
+
...(pendingDelete && {
|
|
38
|
+
opacity: 0.3,
|
|
39
|
+
}),
|
|
40
|
+
}));
|
|
41
|
+
|
|
42
|
+
const StyledImageContainer = styled('div')(({ theme }) => ({
|
|
43
|
+
position: 'relative',
|
|
44
|
+
width: 'fit-content',
|
|
45
|
+
display: 'flex',
|
|
46
|
+
alignItems: 'center',
|
|
47
|
+
'&&:hover > .resize': {
|
|
48
|
+
display: 'block',
|
|
49
|
+
},
|
|
50
|
+
}));
|
|
51
|
+
|
|
52
|
+
const StyledResize = styled('div')(({ theme }) => ({
|
|
53
|
+
backgroundColor: theme.palette.primary.main,
|
|
54
|
+
cursor: 'col-resize',
|
|
55
|
+
height: '35px',
|
|
56
|
+
width: '5px',
|
|
57
|
+
borderRadius: 8,
|
|
58
|
+
marginLeft: '5px',
|
|
59
|
+
marginRight: '10px',
|
|
60
|
+
display: 'none',
|
|
61
|
+
}));
|
|
62
|
+
|
|
15
63
|
const sizePx = (s) => (s ? `${s}px` : 'calc(20px)');
|
|
16
64
|
|
|
17
65
|
function ImageComponent(props) {
|
|
18
66
|
const {
|
|
19
67
|
node,
|
|
20
68
|
editor,
|
|
21
|
-
classes,
|
|
22
69
|
attributes,
|
|
23
70
|
onFocus,
|
|
24
71
|
selected,
|
|
@@ -165,34 +212,27 @@ function ImageComponent(props) {
|
|
|
165
212
|
|
|
166
213
|
return (
|
|
167
214
|
<NodeViewWrapper>
|
|
168
|
-
<
|
|
215
|
+
<StyledRoot
|
|
169
216
|
onFocus={onFocus}
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
node.attrs.deleteStatus === 'pending' && classes.pendingDelete,
|
|
174
|
-
)}
|
|
217
|
+
active={selected}
|
|
218
|
+
loading={!node.attrs.loaded}
|
|
219
|
+
pendingDelete={node.attrs.deleteStatus === 'pending'}
|
|
175
220
|
style={{ justifyContent: flexAlign }}
|
|
176
221
|
>
|
|
177
|
-
<
|
|
178
|
-
mode="determinate"
|
|
179
|
-
value={node.attrs.percent || 0}
|
|
180
|
-
className={classNames(classes.progress, node.attrs.loaded && classes.hideProgress)}
|
|
181
|
-
/>
|
|
222
|
+
<StyledProgress mode="determinate" value={node.attrs.percent || 0} hideProgress={node.attrs.loaded} />
|
|
182
223
|
|
|
183
|
-
<
|
|
224
|
+
<StyledImageContainer>
|
|
184
225
|
<img
|
|
185
226
|
{...attributes}
|
|
186
227
|
ref={imgRef}
|
|
187
228
|
src={node.attrs.src}
|
|
188
|
-
className={classNames(classes.image, selected && classes.active)}
|
|
189
229
|
style={style}
|
|
190
230
|
onLoad={loadImage}
|
|
191
231
|
alt={node.attrs.alt}
|
|
192
232
|
/>
|
|
193
|
-
<
|
|
194
|
-
</
|
|
195
|
-
</
|
|
233
|
+
<StyledResize ref={resizeRef} className="resize" />
|
|
234
|
+
</StyledImageContainer>
|
|
235
|
+
</StyledRoot>
|
|
196
236
|
|
|
197
237
|
{showToolbar && (
|
|
198
238
|
<div
|
|
@@ -234,78 +274,10 @@ function ImageComponent(props) {
|
|
|
234
274
|
ImageComponent.propTypes = {
|
|
235
275
|
node: PropTypes.object.isRequired,
|
|
236
276
|
editor: PropTypes.object.isRequired,
|
|
237
|
-
classes: PropTypes.object.isRequired,
|
|
238
277
|
attributes: PropTypes.object,
|
|
239
278
|
onFocus: PropTypes.func,
|
|
240
279
|
maxImageWidth: PropTypes.number,
|
|
241
280
|
maxImageHeight: PropTypes.number,
|
|
242
281
|
};
|
|
243
282
|
|
|
244
|
-
export default
|
|
245
|
-
portal: {
|
|
246
|
-
position: 'absolute',
|
|
247
|
-
opacity: 0,
|
|
248
|
-
transition: 'opacity 200ms linear',
|
|
249
|
-
},
|
|
250
|
-
floatingButtonRow: {
|
|
251
|
-
backgroundColor: theme.palette.background.paper,
|
|
252
|
-
borderRadius: '1px',
|
|
253
|
-
display: 'flex',
|
|
254
|
-
padding: '10px',
|
|
255
|
-
border: `solid 1px ${theme.palette.grey[200]}`,
|
|
256
|
-
boxShadow:
|
|
257
|
-
'0px 1px 5px 0px rgba(0, 0, 0, 0.2), 0px 2px 2px 0px rgba(0, 0, 0, 0.14), 0px 3px 1px -2px rgba(0, 0, 0, 0.12)',
|
|
258
|
-
},
|
|
259
|
-
progress: {
|
|
260
|
-
position: 'absolute',
|
|
261
|
-
left: '0',
|
|
262
|
-
width: 'fit-content',
|
|
263
|
-
top: '0%',
|
|
264
|
-
transition: 'opacity 200ms linear',
|
|
265
|
-
},
|
|
266
|
-
hideProgress: {
|
|
267
|
-
opacity: 0,
|
|
268
|
-
},
|
|
269
|
-
loading: {
|
|
270
|
-
opacity: 0.3,
|
|
271
|
-
},
|
|
272
|
-
pendingDelete: {
|
|
273
|
-
opacity: 0.3,
|
|
274
|
-
},
|
|
275
|
-
root: {
|
|
276
|
-
position: 'relative',
|
|
277
|
-
border: `solid 1px ${theme.palette.common.white}`,
|
|
278
|
-
display: 'flex',
|
|
279
|
-
transition: 'opacity 200ms linear',
|
|
280
|
-
},
|
|
281
|
-
delete: {
|
|
282
|
-
position: 'absolute',
|
|
283
|
-
right: 0,
|
|
284
|
-
},
|
|
285
|
-
imageContainer: {
|
|
286
|
-
position: 'relative',
|
|
287
|
-
width: 'fit-content',
|
|
288
|
-
display: 'flex',
|
|
289
|
-
alignItems: 'center',
|
|
290
|
-
|
|
291
|
-
'&&:hover > .resize': {
|
|
292
|
-
display: 'block',
|
|
293
|
-
},
|
|
294
|
-
},
|
|
295
|
-
active: {
|
|
296
|
-
border: `solid 1px ${theme.palette.primary.main}`,
|
|
297
|
-
},
|
|
298
|
-
resize: {
|
|
299
|
-
backgroundColor: theme.palette.primary.main,
|
|
300
|
-
cursor: 'col-resize',
|
|
301
|
-
height: '35px',
|
|
302
|
-
width: '5px',
|
|
303
|
-
borderRadius: 8,
|
|
304
|
-
marginLeft: '5px',
|
|
305
|
-
marginRight: '10px',
|
|
306
|
-
display: 'none',
|
|
307
|
-
},
|
|
308
|
-
drawableHeight: {
|
|
309
|
-
minHeight: 350,
|
|
310
|
-
},
|
|
311
|
-
}))(ImageComponent);
|
|
283
|
+
export default ImageComponent;
|
package/src/extensions/css.js
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
2
|
import ReactDOM from 'react-dom';
|
|
3
3
|
import { Mark, mergeAttributes } from '@tiptap/core';
|
|
4
|
-
import List from '@material
|
|
5
|
-
import ListItem from '@material
|
|
4
|
+
import List from '@mui/material/List';
|
|
5
|
+
import ListItem from '@mui/material/ListItem';
|
|
6
6
|
|
|
7
7
|
export const removeDialogs = () => {
|
|
8
8
|
const prevDialogs = document.querySelectorAll('.insert-css-dialog');
|
|
@@ -74,9 +74,10 @@ const insertDialog = ({ editor, callback, opts, selectedText, parentNode }) => {
|
|
|
74
74
|
tag = 'div';
|
|
75
75
|
}
|
|
76
76
|
|
|
77
|
-
html = `<${tag} class="${parentNodeClass}">${parentNode.text.slice(
|
|
78
|
-
|
|
79
|
-
|
|
77
|
+
html = `<${tag} class="${parentNodeClass}">${parentNode.text.slice(
|
|
78
|
+
0,
|
|
79
|
+
selection.$anchor.textOffset,
|
|
80
|
+
)}${html}${parentNode.text.slice(selection.$head.textOffset)}</${tag}>`;
|
|
80
81
|
}
|
|
81
82
|
|
|
82
83
|
return html;
|