@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.
Files changed (103) hide show
  1. package/CHANGELOG.md +7 -73
  2. package/LICENSE.md +5 -0
  3. package/NEXT.CHANGELOG.json +1 -0
  4. package/lib/components/CharacterPicker.js +20 -60
  5. package/lib/components/CharacterPicker.js.map +1 -1
  6. package/lib/components/EditableHtml.js +50 -121
  7. package/lib/components/EditableHtml.js.map +1 -1
  8. package/lib/components/MenuBar.js +96 -128
  9. package/lib/components/MenuBar.js.map +1 -1
  10. package/lib/components/TiptapContainer.js +162 -45
  11. package/lib/components/TiptapContainer.js.map +1 -1
  12. package/lib/components/characters/characterUtils.js +4 -7
  13. package/lib/components/characters/characterUtils.js.map +1 -1
  14. package/lib/components/characters/custom-popper.js +22 -51
  15. package/lib/components/characters/custom-popper.js.map +1 -1
  16. package/lib/components/common/done-button.js +17 -36
  17. package/lib/components/common/done-button.js.map +1 -1
  18. package/lib/components/common/toolbar-buttons.js +57 -107
  19. package/lib/components/common/toolbar-buttons.js.map +1 -1
  20. package/lib/components/icons/CssIcon.js +14 -26
  21. package/lib/components/icons/CssIcon.js.map +1 -1
  22. package/lib/components/icons/RespArea.js +23 -46
  23. package/lib/components/icons/RespArea.js.map +1 -1
  24. package/lib/components/icons/TableIcons.js +20 -36
  25. package/lib/components/icons/TableIcons.js.map +1 -1
  26. package/lib/components/icons/TextAlign.js +16 -53
  27. package/lib/components/icons/TextAlign.js.map +1 -1
  28. package/lib/components/image/AltDialog.js +18 -49
  29. package/lib/components/image/AltDialog.js.map +1 -1
  30. package/lib/components/image/ImageToolbar.js +50 -90
  31. package/lib/components/image/ImageToolbar.js.map +1 -1
  32. package/lib/components/image/InsertImageHandler.js +17 -35
  33. package/lib/components/image/InsertImageHandler.js.map +1 -1
  34. package/lib/components/media/MediaDialog.js +195 -309
  35. package/lib/components/media/MediaDialog.js.map +1 -1
  36. package/lib/components/media/MediaToolbar.js +39 -66
  37. package/lib/components/media/MediaToolbar.js.map +1 -1
  38. package/lib/components/media/MediaWrapper.js +30 -56
  39. package/lib/components/media/MediaWrapper.js.map +1 -1
  40. package/lib/components/respArea/DragInTheBlank/DragInTheBlank.js +21 -36
  41. package/lib/components/respArea/DragInTheBlank/DragInTheBlank.js.map +1 -1
  42. package/lib/components/respArea/DragInTheBlank/choice.js +215 -262
  43. package/lib/components/respArea/DragInTheBlank/choice.js.map +1 -1
  44. package/lib/components/respArea/ExplicitConstructedResponse.js +11 -33
  45. package/lib/components/respArea/ExplicitConstructedResponse.js.map +1 -1
  46. package/lib/components/respArea/InlineDropdown.js +19 -41
  47. package/lib/components/respArea/InlineDropdown.js.map +1 -1
  48. package/lib/components/respArea/ToolbarIcon.js +21 -45
  49. package/lib/components/respArea/ToolbarIcon.js.map +1 -1
  50. package/lib/constants.js +3 -5
  51. package/lib/constants.js.map +1 -1
  52. package/lib/extensions/component.js +94 -148
  53. package/lib/extensions/component.js.map +1 -1
  54. package/lib/extensions/css.js +9 -44
  55. package/lib/extensions/css.js.map +1 -1
  56. package/lib/extensions/custom-toolbar-wrapper.js +66 -94
  57. package/lib/extensions/custom-toolbar-wrapper.js.map +1 -1
  58. package/lib/extensions/extended-table.js +2 -6
  59. package/lib/extensions/extended-table.js.map +1 -1
  60. package/lib/extensions/image.js +4 -17
  61. package/lib/extensions/image.js.map +1 -1
  62. package/lib/extensions/index.js +13 -23
  63. package/lib/extensions/index.js.map +1 -1
  64. package/lib/extensions/math.js +45 -96
  65. package/lib/extensions/math.js.map +1 -1
  66. package/lib/extensions/media.js +21 -59
  67. package/lib/extensions/media.js.map +1 -1
  68. package/lib/extensions/responseArea.js +43 -89
  69. package/lib/extensions/responseArea.js.map +1 -1
  70. package/lib/index.js +9 -11
  71. package/lib/index.js.map +1 -1
  72. package/lib/styles/editorContainerStyles.js +2 -7
  73. package/lib/styles/editorContainerStyles.js.map +1 -1
  74. package/lib/theme.js +2 -3
  75. package/lib/theme.js.map +1 -1
  76. package/lib/utils/size.js +2 -10
  77. package/lib/utils/size.js.map +1 -1
  78. package/package.json +15 -13
  79. package/src/components/EditableHtml.jsx +21 -33
  80. package/src/components/MenuBar.jsx +66 -37
  81. package/src/components/TiptapContainer.jsx +133 -34
  82. package/src/components/characters/custom-popper.js +18 -28
  83. package/src/components/common/done-button.jsx +15 -26
  84. package/src/components/common/toolbar-buttons.jsx +28 -44
  85. package/src/components/icons/CssIcon.jsx +11 -13
  86. package/src/components/icons/RespArea.jsx +16 -16
  87. package/src/components/icons/TableIcons.jsx +15 -16
  88. package/src/components/icons/TextAlign.jsx +3 -3
  89. package/src/components/image/AltDialog.jsx +6 -6
  90. package/src/components/image/ImageToolbar.jsx +28 -29
  91. package/src/components/media/MediaDialog.js +61 -78
  92. package/src/components/media/MediaToolbar.jsx +30 -37
  93. package/src/components/media/MediaWrapper.jsx +12 -16
  94. package/src/components/respArea/DragInTheBlank/DragInTheBlank.jsx +5 -4
  95. package/src/components/respArea/DragInTheBlank/choice.jsx +191 -185
  96. package/src/components/respArea/ToolbarIcon.jsx +13 -15
  97. package/src/extensions/component.jsx +61 -89
  98. package/src/extensions/css.js +6 -5
  99. package/src/extensions/custom-toolbar-wrapper.jsx +61 -81
  100. package/src/extensions/index.js +2 -2
  101. package/src/index.jsx +2 -2
  102. package/lib/__tests__/utils.js +0 -106
  103. 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 isUndefined from 'lodash/isUndefined';
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 { withStyles } from '@material-ui/core/styles';
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 useStyles = withStyles((theme) => ({
13
- content: {
14
- border: `solid 0px ${theme.palette.primary.main}`,
15
- '& mjx-frac': {
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 class BlankContent extends React.Component {
34
- static propTypes = {
35
- n: PropTypes.object,
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
- componentWillUnmount() {
56
- document.removeEventListener('click', this.handleClick);
57
- }
22
+ const handleClick = (event) => {
23
+ if (!elementRef.current) return;
58
24
 
59
- handleClick(event) {
60
- const { classes } = this.props;
61
-
62
- if (this.elementRef) {
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
- return null;
73
- }
30
+ };
74
31
 
75
- componentDidUpdate(prevProps, prevState, snapshot) {
76
- if (this.elementRef && typeof renderMath === 'function') {
77
- renderMath(this.elementRef);
78
- }
32
+ useEffect(() => {
33
+ document.addEventListener('click', handleClick);
34
+ return () => {
35
+ document.removeEventListener('click', handleClick);
36
+ };
37
+ }, []);
79
38
 
80
- if (
81
- snapshot &&
82
- (!this.state.hoveredElementSize ||
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
- if (prevProps.isOver && !this.props.isOver && this.state.hoveredElementSize) {
91
- this.setState({ hoveredElementSize: null });
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
- render() {
96
- const { n, children, isDragging, dragItem, isOver, value } = this.props;
97
- const { hoveredElementSize } = this.state;
98
-
99
- const label = dragItem && isOver ? dragItem.value.value : value.value || '\u00A0';
100
- const finalLabel = isDragging ? '\u00A0' : label;
101
- const hasGrip = finalLabel !== '\u00A0';
102
- const isPreview = dragItem && isOver;
103
-
104
- return (
105
- <div
106
- ref={(ref) => (this.elementRef = ref)}
107
- style={{
108
- display: 'inline-flex',
109
- minWidth: '178px',
110
- minHeight: '36px',
111
- background: isPreview ? `${color.defaults.BORDER_LIGHT}` : `${color.defaults.WHITE}`,
112
- border: isPreview ? `1px solid ${color.defaults.BORDER_DARK}` : `1px solid ${color.defaults.BORDER_LIGHT}`,
113
- boxSizing: 'border-box',
114
- borderRadius: '3px',
115
- overflow: 'hidden',
116
- position: 'relative',
117
- padding: '8px 8px 8px 35px',
118
- width: hoveredElementSize ? hoveredElementSize.width : undefined,
119
- height: hoveredElementSize ? hoveredElementSize.height : undefined,
120
- }}
121
- data-key={n.key}
122
- contentEditable={false}
123
- >
124
- {hasGrip && (
125
- <GripIcon
126
- style={{
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
- {children}
141
- </div>
142
- );
143
- }
89
+ )}
90
+ <span
91
+ dangerouslySetInnerHTML={{
92
+ __html: finalLabel,
93
+ }}
94
+ />
95
+ {children}
96
+ </div>
97
+ );
144
98
  }
145
99
 
146
- const StyledBlankContent = useStyles(BlankContent);
147
-
148
- const connectedBlankContent = useStyles(({ connectDropTarget, connectDragSource, ...props }) => {
149
- const { classes, isOver, value } = props;
150
- const dragContent = <StyledBlankContent {...props} />;
151
- const dragEl = !value ? dragContent : connectDragSource(<span>{dragContent}</span>);
152
- const content = <span className={classnames(classes.content, isOver && classes.over)}>{dragEl}</span>;
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
- if (shouldDrop) {
166
- props.onChange(draggedItem.value);
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
- return {
170
- dropped: shouldDrop,
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
- return draggedItem.instanceId === props.instanceId;
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 DropTile = DropTarget('drag-in-the-blank-choice', tileTarget, (connect, monitor) => ({
181
- connectDropTarget: connect.dropTarget(),
182
- isOver: monitor.isOver({ shallow: true }),
183
- dragItem: monitor.getItem(),
184
- }))(connectedBlankContent);
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
- export const tileSource = {
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
- if (!dropResult || (dropResult.dropped && !props.duplicates)) {
203
- const draggedItem = monitor.getItem();
207
+ return content;
208
+ }
204
209
 
205
- if (draggedItem.fromChoice) {
206
- props.removeResponse(draggedItem.value);
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 DragSource('drag-in-the-blank-choice', tileSource, (connect, monitor) => ({
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 { withStyles } from '@material-ui/core/styles';
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 styles = (theme) => ({
55
- icon: {
56
- fontFamily: 'Cerebri Sans !important',
57
- fontSize: theme.typography.fontSize,
58
- fontWeight: 'bold',
59
- lineHeight: '14px',
60
- position: 'relative',
61
- top: '7px',
62
- width: '110px',
63
- height: '28px',
64
- whiteSpace: 'nowrap',
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 = withStyles(styles)(({ classes }) => <div className={classes.icon}>+ Response Area</div>);
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-ui/core/LinearProgress';
7
- import { withStyles } from '@material-ui/core/styles';
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
- <div
215
+ <StyledRoot
169
216
  onFocus={onFocus}
170
- className={classNames(
171
- classes.root,
172
- !node.attrs.loaded && classes.loading,
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
- <LinearProgress
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
- <div className={classes.imageContainer}>
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
- <div ref={resizeRef} className={classNames(classes.resize, 'resize')} />
194
- </div>
195
- </div>
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 withStyles((theme) => ({
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;
@@ -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-ui/core/List';
5
- import ListItem from '@material-ui/core/ListItem';
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(0, selection.$anchor.textOffset)}${html}${parentNode.text.slice(
78
- selection.$head.textOffset,
79
- )}</${tag}>`;
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;