@pie-lib/editable-html-tip-tap 2.2.0-beta.9 → 3.0.0-next.20261002094057

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 (235) hide show
  1. package/dist/components/CharacterPicker.d.ts +31 -0
  2. package/dist/components/CharacterPicker.js +141 -0
  3. package/dist/components/EditableHtml.d.ts +11 -0
  4. package/dist/components/EditableHtml.js +331 -0
  5. package/dist/components/MenuBar.d.ts +11 -0
  6. package/dist/components/MenuBar.js +531 -0
  7. package/dist/components/TiptapContainer.d.ts +11 -0
  8. package/dist/components/TiptapContainer.js +167 -0
  9. package/dist/components/characters/characterUtils.d.ts +35 -0
  10. package/dist/components/characters/characterUtils.js +465 -0
  11. package/dist/components/characters/custom-popper.d.ts +14 -0
  12. package/dist/components/characters/custom-popper.js +32 -0
  13. package/dist/components/common/done-button.d.ts +30 -0
  14. package/dist/components/common/done-button.js +26 -0
  15. package/dist/components/common/toolbar-buttons.d.ts +38 -0
  16. package/dist/components/common/toolbar-buttons.js +96 -0
  17. package/dist/components/icons/CssIcon.d.ts +11 -0
  18. package/dist/components/icons/CssIcon.js +14 -0
  19. package/dist/components/icons/RespArea.d.ts +26 -0
  20. package/dist/components/icons/RespArea.js +42 -0
  21. package/dist/components/icons/TableIcons.d.ts +14 -0
  22. package/dist/components/icons/TableIcons.js +34 -0
  23. package/dist/components/icons/TextAlign.d.ts +18 -0
  24. package/dist/components/icons/TextAlign.js +143 -0
  25. package/dist/components/image/AltDialog.d.ts +22 -0
  26. package/dist/components/image/AltDialog.js +61 -0
  27. package/dist/components/image/ImageToolbar.d.ts +24 -0
  28. package/dist/components/image/ImageToolbar.js +80 -0
  29. package/dist/components/image/InsertImageHandler.d.ts +33 -0
  30. package/dist/components/image/InsertImageHandler.js +65 -0
  31. package/dist/components/image/findImageNode.d.ts +3 -0
  32. package/dist/components/image/findImageNode.js +11 -0
  33. package/dist/components/media/MediaDialog.d.ts +43 -0
  34. package/dist/components/media/MediaDialog.js +389 -0
  35. package/dist/components/media/MediaToolbar.d.ts +19 -0
  36. package/dist/components/media/MediaToolbar.js +41 -0
  37. package/dist/components/respArea/DragInTheBlank/DragInTheBlank.d.ts +23 -0
  38. package/dist/components/respArea/DragInTheBlank/DragInTheBlank.js +58 -0
  39. package/dist/components/respArea/DragInTheBlank/choice.d.ts +56 -0
  40. package/dist/components/respArea/DragInTheBlank/choice.js +157 -0
  41. package/dist/components/respArea/ExplicitConstructedResponse.d.ts +20 -0
  42. package/dist/components/respArea/ExplicitConstructedResponse.js +84 -0
  43. package/dist/components/respArea/InlineDropdown.d.ts +18 -0
  44. package/dist/components/respArea/InlineDropdown.js +126 -0
  45. package/dist/components/respArea/MathTemplated.d.ts +19 -0
  46. package/dist/components/respArea/MathTemplated.js +98 -0
  47. package/dist/components/respArea/ToolbarIcon.d.ts +14 -0
  48. package/dist/components/respArea/ToolbarIcon.js +17 -0
  49. package/dist/components/respArea/inlineDropdownUtils.d.ts +15 -0
  50. package/dist/components/respArea/inlineDropdownUtils.js +15 -0
  51. package/dist/constants.d.ts +13 -0
  52. package/dist/constants.js +4 -0
  53. package/dist/extensions/css.d.ts +11 -0
  54. package/dist/extensions/css.js +120 -0
  55. package/dist/extensions/custom-toolbar-wrapper.d.ts +11 -0
  56. package/dist/extensions/custom-toolbar-wrapper.js +61 -0
  57. package/dist/extensions/div-node.d.ts +10 -0
  58. package/dist/extensions/div-node.js +42 -0
  59. package/dist/extensions/ensure-empty-root-div.d.ts +14 -0
  60. package/dist/extensions/ensure-empty-root-div.js +24 -0
  61. package/dist/extensions/ensure-list-item-content-is-div.d.ts +15 -0
  62. package/dist/extensions/ensure-list-item-content-is-div.js +31 -0
  63. package/dist/extensions/extended-list-item.d.ts +13 -0
  64. package/dist/extensions/extended-list-item.js +5 -0
  65. package/dist/extensions/extended-table-cell.d.ts +10 -0
  66. package/dist/extensions/extended-table-cell.js +6 -0
  67. package/dist/extensions/extended-table.d.ts +17 -0
  68. package/dist/extensions/extended-table.js +34 -0
  69. package/dist/extensions/heading-paragraph.d.ts +17 -0
  70. package/dist/extensions/heading-paragraph.js +30 -0
  71. package/dist/extensions/image-component.d.ts +22 -0
  72. package/dist/extensions/image-component.js +223 -0
  73. package/dist/extensions/image.d.ts +10 -0
  74. package/dist/extensions/image.js +77 -0
  75. package/dist/extensions/index.d.ts +16 -0
  76. package/dist/extensions/index.js +64 -0
  77. package/dist/extensions/math.d.ts +15 -0
  78. package/dist/extensions/math.js +214 -0
  79. package/dist/extensions/media.d.ts +19 -0
  80. package/dist/extensions/media.js +149 -0
  81. package/dist/extensions/responseArea.d.ts +27 -0
  82. package/dist/extensions/responseArea.js +255 -0
  83. package/dist/index.d.ts +13 -0
  84. package/dist/index.js +7 -0
  85. package/dist/node_modules/.bun/clsx@2.1.1/node_modules/clsx/dist/clsx.js +16 -0
  86. package/dist/utils/helper.d.ts +9 -0
  87. package/dist/utils/helper.js +27 -0
  88. package/dist/utils/size.d.ts +9 -0
  89. package/dist/utils/size.js +14 -0
  90. package/dist/utils/toolbar.d.ts +10 -0
  91. package/dist/utils/toolbar.js +7 -0
  92. package/package.json +59 -43
  93. package/CHANGELOG.json +0 -32
  94. package/CHANGELOG.md +0 -2532
  95. package/lib/components/CharacterPicker.js +0 -226
  96. package/lib/components/CharacterPicker.js.map +0 -1
  97. package/lib/components/EditableHtml.js +0 -388
  98. package/lib/components/EditableHtml.js.map +0 -1
  99. package/lib/components/MenuBar.js +0 -702
  100. package/lib/components/MenuBar.js.map +0 -1
  101. package/lib/components/TiptapContainer.js +0 -242
  102. package/lib/components/TiptapContainer.js.map +0 -1
  103. package/lib/components/characters/characterUtils.js +0 -378
  104. package/lib/components/characters/characterUtils.js.map +0 -1
  105. package/lib/components/characters/custom-popper.js +0 -44
  106. package/lib/components/characters/custom-popper.js.map +0 -1
  107. package/lib/components/common/done-button.js +0 -34
  108. package/lib/components/common/done-button.js.map +0 -1
  109. package/lib/components/common/toolbar-buttons.js +0 -149
  110. package/lib/components/common/toolbar-buttons.js.map +0 -1
  111. package/lib/components/icons/CssIcon.js +0 -25
  112. package/lib/components/icons/CssIcon.js.map +0 -1
  113. package/lib/components/icons/RespArea.js +0 -72
  114. package/lib/components/icons/RespArea.js.map +0 -1
  115. package/lib/components/icons/TableIcons.js +0 -53
  116. package/lib/components/icons/TableIcons.js.map +0 -1
  117. package/lib/components/icons/TextAlign.js +0 -157
  118. package/lib/components/icons/TextAlign.js.map +0 -1
  119. package/lib/components/image/AltDialog.js +0 -98
  120. package/lib/components/image/AltDialog.js.map +0 -1
  121. package/lib/components/image/ImageToolbar.js +0 -137
  122. package/lib/components/image/ImageToolbar.js.map +0 -1
  123. package/lib/components/image/InsertImageHandler.js +0 -135
  124. package/lib/components/image/InsertImageHandler.js.map +0 -1
  125. package/lib/components/media/MediaDialog.js +0 -594
  126. package/lib/components/media/MediaDialog.js.map +0 -1
  127. package/lib/components/media/MediaToolbar.js +0 -74
  128. package/lib/components/media/MediaToolbar.js.map +0 -1
  129. package/lib/components/media/MediaWrapper.js +0 -67
  130. package/lib/components/media/MediaWrapper.js.map +0 -1
  131. package/lib/components/respArea/DragInTheBlank/DragInTheBlank.js +0 -84
  132. package/lib/components/respArea/DragInTheBlank/DragInTheBlank.js.map +0 -1
  133. package/lib/components/respArea/DragInTheBlank/choice.js +0 -253
  134. package/lib/components/respArea/DragInTheBlank/choice.js.map +0 -1
  135. package/lib/components/respArea/ExplicitConstructedResponse.js +0 -137
  136. package/lib/components/respArea/ExplicitConstructedResponse.js.map +0 -1
  137. package/lib/components/respArea/InlineDropdown.js +0 -223
  138. package/lib/components/respArea/InlineDropdown.js.map +0 -1
  139. package/lib/components/respArea/MathTemplated.js +0 -130
  140. package/lib/components/respArea/MathTemplated.js.map +0 -1
  141. package/lib/components/respArea/ToolbarIcon.js +0 -81
  142. package/lib/components/respArea/ToolbarIcon.js.map +0 -1
  143. package/lib/components/respArea/inlineDropdownUtils.js +0 -67
  144. package/lib/components/respArea/inlineDropdownUtils.js.map +0 -1
  145. package/lib/constants.js +0 -11
  146. package/lib/constants.js.map +0 -1
  147. package/lib/extensions/css.js +0 -227
  148. package/lib/extensions/css.js.map +0 -1
  149. package/lib/extensions/custom-toolbar-wrapper.js +0 -92
  150. package/lib/extensions/custom-toolbar-wrapper.js.map +0 -1
  151. package/lib/extensions/div-node.js +0 -83
  152. package/lib/extensions/div-node.js.map +0 -1
  153. package/lib/extensions/ensure-empty-root-div.js +0 -48
  154. package/lib/extensions/ensure-empty-root-div.js.map +0 -1
  155. package/lib/extensions/ensure-list-item-content-is-div.js +0 -64
  156. package/lib/extensions/ensure-list-item-content-is-div.js.map +0 -1
  157. package/lib/extensions/extended-list-item.js +0 -15
  158. package/lib/extensions/extended-list-item.js.map +0 -1
  159. package/lib/extensions/extended-table-cell.js +0 -22
  160. package/lib/extensions/extended-table-cell.js.map +0 -1
  161. package/lib/extensions/extended-table.js +0 -75
  162. package/lib/extensions/extended-table.js.map +0 -1
  163. package/lib/extensions/heading-paragraph.js +0 -61
  164. package/lib/extensions/heading-paragraph.js.map +0 -1
  165. package/lib/extensions/image-component.js +0 -351
  166. package/lib/extensions/image-component.js.map +0 -1
  167. package/lib/extensions/image.js +0 -134
  168. package/lib/extensions/image.js.map +0 -1
  169. package/lib/extensions/index.js +0 -46
  170. package/lib/extensions/index.js.map +0 -1
  171. package/lib/extensions/math.js +0 -469
  172. package/lib/extensions/math.js.map +0 -1
  173. package/lib/extensions/media.js +0 -243
  174. package/lib/extensions/media.js.map +0 -1
  175. package/lib/extensions/responseArea.js +0 -452
  176. package/lib/extensions/responseArea.js.map +0 -1
  177. package/lib/index.js +0 -37
  178. package/lib/index.js.map +0 -1
  179. package/lib/styles/editorContainerStyles.js +0 -137
  180. package/lib/styles/editorContainerStyles.js.map +0 -1
  181. package/lib/theme.js +0 -8
  182. package/lib/theme.js.map +0 -1
  183. package/lib/utils/helper.js +0 -73
  184. package/lib/utils/helper.js.map +0 -1
  185. package/lib/utils/size.js +0 -26
  186. package/lib/utils/size.js.map +0 -1
  187. package/lib/utils/toolbar.js +0 -19
  188. package/lib/utils/toolbar.js.map +0 -1
  189. package/src/components/CharacterPicker.jsx +0 -237
  190. package/src/components/EditableHtml.jsx +0 -458
  191. package/src/components/MenuBar.jsx +0 -561
  192. package/src/components/TiptapContainer.jsx +0 -235
  193. package/src/components/characters/characterUtils.js +0 -447
  194. package/src/components/characters/custom-popper.js +0 -38
  195. package/src/components/common/done-button.jsx +0 -27
  196. package/src/components/common/toolbar-buttons.jsx +0 -127
  197. package/src/components/icons/CssIcon.jsx +0 -15
  198. package/src/components/icons/RespArea.jsx +0 -71
  199. package/src/components/icons/TableIcons.jsx +0 -52
  200. package/src/components/icons/TextAlign.jsx +0 -114
  201. package/src/components/image/AltDialog.jsx +0 -82
  202. package/src/components/image/ImageToolbar.jsx +0 -99
  203. package/src/components/image/InsertImageHandler.js +0 -107
  204. package/src/components/media/MediaDialog.jsx +0 -596
  205. package/src/components/media/MediaToolbar.jsx +0 -49
  206. package/src/components/media/MediaWrapper.jsx +0 -39
  207. package/src/components/respArea/DragInTheBlank/DragInTheBlank.jsx +0 -76
  208. package/src/components/respArea/DragInTheBlank/choice.jsx +0 -259
  209. package/src/components/respArea/ExplicitConstructedResponse.jsx +0 -136
  210. package/src/components/respArea/InlineDropdown.jsx +0 -240
  211. package/src/components/respArea/MathTemplated.jsx +0 -124
  212. package/src/components/respArea/ToolbarIcon.jsx +0 -66
  213. package/src/components/respArea/inlineDropdownUtils.js +0 -79
  214. package/src/constants.js +0 -5
  215. package/src/extensions/css.js +0 -233
  216. package/src/extensions/custom-toolbar-wrapper.jsx +0 -78
  217. package/src/extensions/div-node.js +0 -86
  218. package/src/extensions/ensure-empty-root-div.js +0 -47
  219. package/src/extensions/ensure-list-item-content-is-div.js +0 -62
  220. package/src/extensions/extended-list-item.js +0 -10
  221. package/src/extensions/extended-table-cell.js +0 -19
  222. package/src/extensions/extended-table.js +0 -60
  223. package/src/extensions/heading-paragraph.js +0 -53
  224. package/src/extensions/image-component.jsx +0 -340
  225. package/src/extensions/image.js +0 -109
  226. package/src/extensions/index.js +0 -81
  227. package/src/extensions/math.js +0 -454
  228. package/src/extensions/media.js +0 -188
  229. package/src/extensions/responseArea.js +0 -407
  230. package/src/index.jsx +0 -5
  231. package/src/styles/editorContainerStyles.js +0 -145
  232. package/src/theme.js +0 -1
  233. package/src/utils/helper.js +0 -69
  234. package/src/utils/size.js +0 -32
  235. package/src/utils/toolbar.js +0 -15
@@ -1,76 +0,0 @@
1
- import React from 'react';
2
- import PropTypes from 'prop-types';
3
- import { NodeViewWrapper } from '@tiptap/react';
4
- import DragDropTile from './choice';
5
- import omit from 'lodash-es/omit';
6
-
7
- export const onValueChange = (editor, node, pos, choice) => {
8
- const { tr } = editor.state;
9
-
10
- // Merge old and new attributes
11
- tr.setNodeMarkup(pos, undefined, {
12
- ...node.attrs,
13
- ...choice.value,
14
- });
15
- tr.isDone = true;
16
- editor.view.dispatch(tr);
17
- };
18
-
19
- export const onRemoveResponse = (editor, node, choice) => {
20
- const { tr } = editor.state;
21
-
22
- // Merge old and new attributes
23
- tr.setNodeMarkup(choice.pos, undefined, omit(node.attrs, ['value', 'id']));
24
- tr.isDone = true;
25
- editor.view.dispatch(tr);
26
- };
27
-
28
- const DragDrop = (props) => {
29
- const { editor, node, getPos, options, selected } = props;
30
- const { attrs: attributes } = node;
31
- const { inTable } = attributes;
32
- const pos = getPos();
33
-
34
- // console.log({nodeProps.children})
35
- return (
36
- <NodeViewWrapper
37
- className="drag-in-the-blank"
38
- data-selected={selected}
39
- style={{ display: 'inline', whiteSpace: 'normal' }}
40
- >
41
- <span
42
- {...attributes}
43
- style={{
44
- display: 'inline-flex',
45
- minHeight: '50px',
46
- minWidth: '178px',
47
- position: 'relative',
48
- margin: inTable ? '10px' : '0 10px',
49
- cursor: 'pointer',
50
- }}
51
- >
52
- <DragDropTile
53
- n={attributes}
54
- dragKey={attributes.id}
55
- targetId="0"
56
- pos={pos}
57
- value={attributes}
58
- duplicates={options.duplicates}
59
- selected={selected}
60
- onChange={(choice) => onValueChange(editor, node, pos, choice)}
61
- removeResponse={(choice) => onRemoveResponse(editor, node, choice)}
62
- ></DragDropTile>
63
- </span>
64
- </NodeViewWrapper>
65
- );
66
- };
67
-
68
- DragDrop.propTypes = {
69
- attributes: PropTypes.object,
70
- data: PropTypes.object,
71
- n: PropTypes.object,
72
- nodeProps: PropTypes.object,
73
- opts: PropTypes.object,
74
- };
75
-
76
- export default DragDrop;
@@ -1,259 +0,0 @@
1
- import React, { useEffect, useRef, useState } from 'react';
2
- import PropTypes from 'prop-types';
3
- import { useDraggable, useDroppable } from '@dnd-kit/core';
4
- import { color } from '@pie-lib/render-ui';
5
- import { renderMath } from '@pie-lib/math-rendering';
6
- import { styled } from '@mui/material/styles';
7
- import classnames from 'classnames';
8
-
9
- import { GripIcon } from '../../icons/RespArea';
10
-
11
- const StyledContent = styled('span')(({ theme }) => ({
12
- border: `solid 0px ${theme.palette.primary.main}`,
13
- '& mjx-mn:has(~ mjx-mfrac), mjx-mfrac ~ mjx-mn': {
14
- fontSize: '120% !important',
15
- },
16
- '& mjx-frac': {
17
- fontSize: '120% !important',
18
- },
19
- }));
20
-
21
- export function BlankContent({ n, children, isDragging, isOver, dragItem, value, selected }) {
22
- const [hoveredElementSize, setHoveredElementSize] = useState(null);
23
- const elementRef = useRef(null);
24
-
25
- const handleClick = (event) => {
26
- if (!elementRef.current) return;
27
-
28
- if (elementRef.current.contains(event.target)) {
29
- elementRef.current.classList.add('selected');
30
- } else {
31
- elementRef.current.classList.remove('selected');
32
- }
33
- };
34
-
35
- useEffect(() => {
36
- document.addEventListener('click', handleClick);
37
- return () => {
38
- document.removeEventListener('click', handleClick);
39
- };
40
- }, []);
41
-
42
- useEffect(() => {
43
- if (elementRef.current && typeof renderMath === 'function') {
44
- renderMath(elementRef.current);
45
- }
46
- }, [value?.value, isOver, dragItem?.value?.value]);
47
-
48
- useEffect(() => {
49
- if (isOver && elementRef.current && !hoveredElementSize) {
50
- const node = elementRef.current;
51
- setHoveredElementSize({ width: node.offsetWidth, height: node.offsetHeight });
52
- } else if (!isOver && hoveredElementSize) {
53
- setHoveredElementSize(null);
54
- }
55
- }, [isOver, hoveredElementSize]);
56
-
57
- const label = dragItem && isOver ? dragItem.value.value : value.value || '\u00A0';
58
- const finalLabel = isDragging ? '\u00A0' : label;
59
- const hasGrip = finalLabel !== '\u00A0';
60
- const isPreview = dragItem && isOver;
61
-
62
- const borderStyle = selected
63
- ? `2px solid ${color.primaryDark()}`
64
- : isPreview
65
- ? `1px solid ${color.defaults.BORDER_DARK}`
66
- : `1px solid ${color.defaults.BORDER_LIGHT}`;
67
-
68
- return (
69
- <div
70
- ref={elementRef}
71
- className={selected ? 'selected' : undefined}
72
- style={{
73
- display: 'inline-flex',
74
- minWidth: '178px',
75
- minHeight: '36px',
76
- background: isPreview ? `${color.defaults.BORDER_LIGHT}` : `${color.defaults.WHITE}`,
77
- border: borderStyle,
78
- boxSizing: 'border-box',
79
- borderRadius: '3px',
80
- overflow: 'hidden',
81
- position: 'relative',
82
- padding: '8px 8px 8px 35px',
83
- width: hoveredElementSize ? hoveredElementSize.width : undefined,
84
- height: hoveredElementSize ? hoveredElementSize.height : undefined,
85
- touchAction: 'none',
86
- }}
87
- data-key={n.index}
88
- contentEditable={false}
89
- >
90
- {hasGrip && (
91
- <GripIcon
92
- style={{
93
- position: 'absolute',
94
- top: '6px',
95
- left: '15px',
96
- color: '#9B9B9B',
97
- }}
98
- contentEditable={false}
99
- />
100
- )}
101
- <span
102
- dangerouslySetInnerHTML={{
103
- __html: finalLabel,
104
- }}
105
- />
106
- {children}
107
- </div>
108
- );
109
- }
110
-
111
- BlankContent.propTypes = {
112
- n: PropTypes.object,
113
- children: PropTypes.node,
114
- isDragging: PropTypes.bool,
115
- isOver: PropTypes.bool,
116
- dragItem: PropTypes.object,
117
- value: PropTypes.object,
118
- selected: PropTypes.bool,
119
- };
120
-
121
- function DragDropChoice({
122
- value,
123
- disabled,
124
- instanceId,
125
- children,
126
- n,
127
- onChange,
128
- removeResponse,
129
- duplicates,
130
- pos,
131
- selected,
132
- }) {
133
- const {
134
- attributes: dragAttributes,
135
- listeners: dragListeners,
136
- setNodeRef: setDragNodeRef,
137
- isDragging,
138
- } = useDraggable({
139
- id: `drag-${n.index}`,
140
- disabled: disabled || !value?.value,
141
- data: {
142
- id: `drag-${n.index}`,
143
- value,
144
- instanceId,
145
- n,
146
- pos,
147
- opts: { duplicates },
148
- type: 'drag-in-the-blank-placed-choice',
149
- fromChoice: !value,
150
- onRemove: (draggedData) => removeResponse(draggedData),
151
- onDrop: (draggedData, dropData) => {
152
- // check if we're dropping into a blank
153
- const isValidBlank = dropData?.type === 'drag-in-the-blank-drop-choice';
154
-
155
- if (!isValidBlank) return;
156
-
157
- // place into blank
158
- onChange(draggedData);
159
-
160
- if (!duplicates && draggedData.fromChoice) {
161
- removeResponse(draggedData);
162
- }
163
- },
164
- },
165
- });
166
-
167
- const {
168
- setNodeRef: setDropNodeRef,
169
- isOver,
170
- active: dragItem,
171
- } = useDroppable({
172
- id: `drop-${n.index}`,
173
- data: {
174
- type: 'drag-in-the-blank-drop-choice',
175
- accepts: ['drag-in-the-blank-choice', 'drag-in-the-blank-placed-choice'],
176
- instanceId: instanceId,
177
- value: value,
178
- id: `drop-${n.index}`,
179
- pos,
180
- n,
181
- opts: { duplicates },
182
- onDrop: (draggedData, dropData) => {
183
- // check if we're dropping into a blank
184
- const isValidBlank = dropData?.type === 'drag-in-the-blank-drop-choice';
185
-
186
- if (!isValidBlank) return;
187
-
188
- // if the dragged and dropped data are the same, do nothing
189
- if (draggedData.value.id === dropData.value.id) return;
190
-
191
- if (draggedData.type === 'drag-in-the-blank-choice') {
192
- // place into blank
193
- onChange(draggedData);
194
-
195
- if (!duplicates && draggedData.fromChoice) {
196
- removeResponse(draggedData);
197
- }
198
- return;
199
- }
200
-
201
- // moving placed choice between blanks
202
- if (draggedData.type === 'drag-in-the-blank-placed-choice') {
203
- // clear target blank
204
- removeResponse(dropData);
205
-
206
- // set new blank value
207
- onChange(draggedData);
208
-
209
- // clear original blank - slight delay to ensure state updates correctly
210
- setTimeout(() => removeResponse(draggedData), 10);
211
- }
212
- },
213
- },
214
- });
215
-
216
- const setNodeRef = (node) => {
217
- setDragNodeRef(node);
218
- setDropNodeRef(node);
219
- };
220
-
221
- const dragContent = (
222
- <BlankContent
223
- n={n}
224
- isDragging={isDragging}
225
- isOver={isOver}
226
- dragItem={dragItem?.data?.current}
227
- value={value}
228
- selected={selected}
229
- >
230
- {children}
231
- </BlankContent>
232
- );
233
-
234
- const dragEl = !value ? (
235
- <span ref={setDropNodeRef}>{dragContent}</span>
236
- ) : (
237
- <span ref={setNodeRef} {...dragAttributes} {...dragListeners}>
238
- {dragContent}
239
- </span>
240
- );
241
-
242
- const content = <StyledContent className={classnames(isOver && 'over')}>{dragEl}</StyledContent>;
243
-
244
- return content;
245
- }
246
-
247
- DragDropChoice.propTypes = {
248
- value: PropTypes.object,
249
- disabled: PropTypes.bool,
250
- instanceId: PropTypes.string,
251
- children: PropTypes.node,
252
- n: PropTypes.object.isRequired,
253
- onChange: PropTypes.func.isRequired,
254
- removeResponse: PropTypes.func.isRequired,
255
- duplicates: PropTypes.bool,
256
- selected: PropTypes.bool,
257
- };
258
-
259
- export default DragDropChoice;
@@ -1,136 +0,0 @@
1
- import React, { useEffect, useRef, useState } from 'react';
2
- import { NodeViewWrapper } from '@tiptap/react';
3
- import ReactDOM from 'react-dom';
4
- import PropTypes from 'prop-types';
5
- import CustomToolbarWrapper from '../../extensions/custom-toolbar-wrapper';
6
- import { setToolbarOpened } from '../../utils/toolbar';
7
-
8
- const ExplicitConstructedResponse = (props) => {
9
- const { editor, node, getPos, options, selected } = props;
10
- const { attrs: attributes } = node;
11
- const { value } = attributes;
12
- const { respAreaToolbar, error: errorFn } = options;
13
- const pos = getPos();
14
- const [showToolbar, setShowToolbar] = useState(false);
15
- const EcrToolbar = respAreaToolbar([node, pos], editor, () => {});
16
- const toolbarRef = useRef(null);
17
-
18
- let error;
19
-
20
- if (errorFn) {
21
- const errorValue = errorFn();
22
- const respIndex = parseInt(attributes.index, 10);
23
-
24
- error = !!errorValue?.[respIndex]?.[0];
25
- }
26
-
27
- useEffect(() => {
28
- const { selection } = editor.state;
29
- const onlyThisNodeSelected = selection.from + node.nodeSize === selection.to;
30
-
31
- if (selected) {
32
- if (onlyThisNodeSelected) {
33
- setShowToolbar(selected);
34
- }
35
- } else {
36
- setShowToolbar(selected);
37
- }
38
- }, [editor, node, selected]);
39
-
40
- useEffect(() => {
41
- const handleClickOutside = (event) => {
42
- const insideCharacterPicker =
43
- event.target.closest('.insert-character-dialog') || event.target.closest('[data-toolbar-for]');
44
-
45
- if (
46
- !insideCharacterPicker &&
47
- toolbarRef.current &&
48
- !toolbarRef.current.contains(event.target) &&
49
- !event.target.closest('[data-inline-node]')
50
- ) {
51
- setShowToolbar(false);
52
- }
53
- };
54
-
55
- if (showToolbar) {
56
- document.addEventListener('mousedown', handleClickOutside);
57
- } else {
58
- document.removeEventListener('mousedown', handleClickOutside);
59
- }
60
-
61
- return () => document.removeEventListener('mousedown', handleClickOutside);
62
- }, [showToolbar]);
63
-
64
- return (
65
- <NodeViewWrapper
66
- className="drag-in-the-blank"
67
- data-selected={selected}
68
- style={{
69
- display: 'inline-flex',
70
- minHeight: '55px',
71
- position: 'relative',
72
- cursor: 'pointer',
73
- }}
74
- >
75
- <div
76
- {...attributes}
77
- style={{
78
- display: 'inline-flex',
79
- width: '100%',
80
- minHeight: '46px',
81
- height: '46px',
82
- backgroundColor: '#FFF',
83
- border: `1px solid ${error ? 'red' : '#C0C3CF'}`,
84
- boxSizing: 'border-box',
85
- borderRadius: '4px',
86
- overflow: 'hidden',
87
- padding: '12px 21px',
88
- margin: '0 4px',
89
- minWidth: '178px',
90
- visibility: showToolbar ? 'hidden' : 'visible',
91
- }}
92
- onClick={() => setShowToolbar(true)}
93
- dangerouslySetInnerHTML={{
94
- __html: value || '<div>&nbsp;</div>',
95
- }}
96
- />
97
- {showToolbar && (
98
- <React.Fragment>
99
- <div ref={toolbarRef} className="absolute z-50 bg-white shadow-lg rounded p-2" style={{ zIndex: 1 }}>
100
- <EcrToolbar />
101
- </div>
102
- {editor._tiptapContainerEl &&
103
- ReactDOM.createPortal(
104
- <CustomToolbarWrapper
105
- deletable
106
- toolbarOpts={{ minWidth: 'auto' }}
107
- autoWidth
108
- style={{ top: -40, left: 0, right: 0 }}
109
- onDelete={() => {
110
- const { tr } = editor.state;
111
- tr.delete(pos, pos + node.nodeSize);
112
- // Prevent the debounced onBlur/onDone from firing into the
113
- // now-deleted node's stale position
114
- setToolbarOpened(editor, false);
115
- editor.view.dispatch(tr);
116
- setShowToolbar(false);
117
- editor.commands.focus();
118
- }}
119
- showDone={false}
120
- />,
121
- editor._tiptapContainerEl,
122
- )}
123
- </React.Fragment>
124
- )}
125
- </NodeViewWrapper>
126
- );
127
- };
128
-
129
- ExplicitConstructedResponse.propTypes = {
130
- attributes: PropTypes.object,
131
- error: PropTypes.any,
132
- value: PropTypes.string,
133
- isFocused: PropTypes.bool,
134
- };
135
-
136
- export default ExplicitConstructedResponse;
@@ -1,240 +0,0 @@
1
- import React, { useEffect, useRef, useState } from 'react';
2
- import ReactDOM from 'react-dom';
3
- import { renderMath } from '@pie-lib/math-rendering';
4
- import PropTypes from 'prop-types';
5
- import { NodeViewWrapper } from '@tiptap/react';
6
- import { NodeSelection } from 'prosemirror-state';
7
- import { Chevron } from '../icons/RespArea';
8
- import CustomToolbarWrapper from '../../extensions/custom-toolbar-wrapper';
9
- import { setToolbarOpened } from '../../utils/toolbar';
10
-
11
- const InlineDropdown = (props) => {
12
- const { editor, node, getPos, options, selected } = props;
13
- const { attrs: attributes } = node;
14
- const { value, error } = attributes;
15
- const html = value || '<div>&nbsp</div>';
16
- const pos = getPos();
17
- const toolbarRef = useRef(null);
18
- const toolbarEditor = useRef(null);
19
- const pendingCloseRequest = useRef(false);
20
- const elementRef = useRef(null);
21
-
22
- const isHeld = () =>
23
- editor._holdInlineDropdownToolbarIndex != null &&
24
- String(editor._holdInlineDropdownToolbarIndex) === String(node.attrs.index);
25
-
26
- const [showToolbar, setShowToolbar] = useState(false);
27
- const [position, setPosition] = useState({ top: 0, left: 0 });
28
-
29
- const closeToolbar = () => {
30
- if (isHeld()) {
31
- return;
32
- }
33
-
34
- setShowToolbar(false);
35
- options.onInlineDropdownToolbarClose?.(editor);
36
- };
37
-
38
- const InlineDropdownToolbar = options.respAreaToolbar([node, pos], editor, closeToolbar);
39
-
40
- const reselectNode = () => {
41
- const { tr } = editor.state;
42
- const nodeAtPos = tr.doc.nodeAt(pos);
43
-
44
- if (!nodeAtPos) {
45
- return;
46
- }
47
-
48
- const { selection } = tr;
49
-
50
- if (selection.from === pos && selection.to === pos + nodeAtPos.nodeSize) {
51
- return;
52
- }
53
-
54
- tr.setSelection(NodeSelection.create(tr.doc, pos));
55
- editor.view.dispatch(tr);
56
- };
57
-
58
- const requestClose = () => {
59
- if (pendingCloseRequest.current) {
60
- return;
61
- }
62
-
63
- if (options.onToolbarCloseRequest) {
64
- pendingCloseRequest.current = true;
65
-
66
- options.onToolbarCloseRequest(
67
- [node, pos],
68
- editor,
69
- () => {
70
- pendingCloseRequest.current = false;
71
- delete editor._holdInlineDropdownToolbarIndex;
72
- closeToolbar();
73
- },
74
- () => {
75
- pendingCloseRequest.current = false;
76
- delete editor._holdInlineDropdownToolbarIndex;
77
- setShowToolbar(true);
78
- setTimeout(reselectNode, 0);
79
- },
80
- );
81
- } else {
82
- closeToolbar();
83
- }
84
- };
85
-
86
- useEffect(() => {
87
- const { selection } = editor.state;
88
- const onlyThisNodeSelected = selection.from + node.nodeSize === selection.to;
89
-
90
- if (selected) {
91
- if (onlyThisNodeSelected) {
92
- setShowToolbar(true);
93
- }
94
- } else if (showToolbar) {
95
- requestClose();
96
- }
97
- }, [editor, node, selected]);
98
-
99
- const isScrollbarClicked = (event) =>
100
- event.clientX > document.documentElement.clientWidth ||
101
- event.clientY > document.documentElement.clientHeight ||
102
- event.target === document.documentElement;
103
-
104
- useEffect(() => {
105
- if (elementRef.current && typeof renderMath === 'function') {
106
- renderMath(elementRef.current);
107
- }
108
- }, [value]);
109
-
110
- useEffect(() => {
111
- // Calculate position relative to selection
112
- const bodyRect = document.body.getBoundingClientRect();
113
- const { from } = editor.state.selection;
114
- const start = editor.view.coordsAtPos(from);
115
-
116
- setPosition({
117
- top: start.top + Math.abs(bodyRect.top) + 40, // shift above
118
- left: start.left,
119
- });
120
-
121
- const handleClickOutside = (event) => {
122
- if (isScrollbarClicked(event)) {
123
- return;
124
- }
125
-
126
- const insideSomeEditor = event.target.closest('[data-toolbar-for]');
127
-
128
- if (
129
- !event.target.closest('[data-inline-dropdown-toolbar]') &&
130
- (!insideSomeEditor || insideSomeEditor.dataset.toolbarFor !== toolbarEditor.current?.instanceId) &&
131
- !editor._toolbarOpened &&
132
- toolbarRef.current &&
133
- !toolbarRef.current.contains(event.target) &&
134
- !event.target.closest('[data-inline-node]')
135
- ) {
136
- requestClose();
137
- }
138
- };
139
-
140
- if (showToolbar) {
141
- document.addEventListener('mousedown', handleClickOutside);
142
- } else {
143
- document.removeEventListener('mousedown', handleClickOutside);
144
- }
145
-
146
- return () => document.removeEventListener('mousedown', handleClickOutside);
147
- }, [showToolbar, node]);
148
-
149
- return (
150
- <NodeViewWrapper
151
- className="inline-dropdown"
152
- data-selected={selected}
153
- style={{
154
- display: 'inline-flex',
155
- height: '50px',
156
- cursor: 'pointer',
157
- }}
158
- >
159
- <div
160
- ref={elementRef}
161
- style={{
162
- display: 'inline-flex',
163
- minWidth: '178px',
164
- height: '36px',
165
- background: '#FFF',
166
- border: '1px solid #C0C3CF',
167
- boxSizing: 'border-box',
168
- borderRadius: '3px',
169
- margin: '0 2px',
170
- position: 'relative',
171
- alignItems: 'center',
172
- }}
173
- onClick={() => setShowToolbar(true)}
174
- >
175
- <div
176
- style={{
177
- flex: 1,
178
- overflow: 'hidden',
179
- padding: '0 25px 0 8px',
180
- whiteSpace: 'nowrap',
181
- textOverflow: 'ellipsis',
182
- }}
183
- >
184
- <span
185
- style={{
186
- display: 'inline-block',
187
- verticalAlign: 'middle',
188
- }}
189
- dangerouslySetInnerHTML={{ __html: html }}
190
- />
191
- </div>
192
- <Chevron direction="down" style={{ position: 'absolute', top: '5px', right: '5px' }} />
193
- </div>
194
- {showToolbar && (
195
- <React.Fragment>
196
- {ReactDOM.createPortal(
197
- <div ref={toolbarRef}>
198
- <InlineDropdownToolbar
199
- editorCallback={(instance) => {
200
- toolbarEditor.current = instance;
201
- }}
202
- />
203
- </div>,
204
- editor?._tiptapContainerEl || document.body,
205
- )}
206
-
207
- {editor._tiptapContainerEl &&
208
- ReactDOM.createPortal(
209
- <CustomToolbarWrapper
210
- deletable
211
- toolbarOpts={{ minWidth: 'auto' }}
212
- autoWidth
213
- style={{ top: -40, left: 0, right: 0 }}
214
- onDelete={() => {
215
- const { tr } = editor.state;
216
- tr.delete(pos, pos + node.nodeSize);
217
- // Prevent the debounced onBlur/onDone from firing into the
218
- // now-deleted node's stale position
219
- setToolbarOpened(editor, false);
220
- delete editor._holdInlineDropdownToolbarIndex;
221
- editor.view.dispatch(tr);
222
- setShowToolbar(false);
223
- editor.commands.focus();
224
- }}
225
- showDone={false}
226
- />,
227
- editor._tiptapContainerEl,
228
- )}
229
- </React.Fragment>
230
- )}
231
- </NodeViewWrapper>
232
- );
233
- };
234
-
235
- InlineDropdown.propTypes = {
236
- attributes: PropTypes.object,
237
- selectedItem: PropTypes.oneOfType([PropTypes.string, PropTypes.object]),
238
- };
239
-
240
- export default InlineDropdown;