@pie-lib/mask-markup 0.1.0
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/dist/_virtual/_rolldown/runtime.js +4 -0
- package/dist/choices/choice.d.ts +24 -0
- package/dist/choices/choice.d.ts.map +1 -0
- package/dist/choices/choice.js +77 -0
- package/dist/choices/index.d.ts +26 -0
- package/dist/choices/index.d.ts.map +1 -0
- package/dist/choices/index.js +49 -0
- package/dist/componentize.d.ts +13 -0
- package/dist/componentize.d.ts.map +1 -0
- package/dist/componentize.js +4 -0
- package/dist/components/blank.d.ts +39 -0
- package/dist/components/blank.d.ts.map +1 -0
- package/dist/components/blank.js +236 -0
- package/dist/components/correct-input.d.ts +11 -0
- package/dist/components/correct-input.d.ts.map +1 -0
- package/dist/components/dropdown.d.ts +38 -0
- package/dist/components/dropdown.d.ts.map +1 -0
- package/dist/components/dropdown.js +309 -0
- package/dist/components/input.d.ts +37 -0
- package/dist/components/input.d.ts.map +1 -0
- package/dist/constructed-response.d.ts +24 -0
- package/dist/constructed-response.d.ts.map +1 -0
- package/dist/constructed-response.js +55 -0
- package/dist/customizable.d.ts +24 -0
- package/dist/customizable.d.ts.map +1 -0
- package/dist/customizable.js +8 -0
- package/dist/drag-in-the-blank.d.ts +38 -0
- package/dist/drag-in-the-blank.d.ts.map +1 -0
- package/dist/drag-in-the-blank.js +164 -0
- package/dist/index.d.ts +16 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +7 -0
- package/dist/inline-dropdown.d.ts +24 -0
- package/dist/inline-dropdown.d.ts.map +1 -0
- package/dist/inline-dropdown.js +24 -0
- package/dist/mask.d.ts +31 -0
- package/dist/mask.d.ts.map +1 -0
- package/dist/mask.js +98 -0
- package/dist/node_modules/.bun/to-style@1.3.3/node_modules/to-style/index.js +17 -0
- package/dist/node_modules/.bun/to-style@1.3.3/node_modules/to-style/src/cssPrefix.js +9 -0
- package/dist/node_modules/.bun/to-style@1.3.3/node_modules/to-style/src/cssUnitless.js +26 -0
- package/dist/node_modules/.bun/to-style@1.3.3/node_modules/to-style/src/hasOwn.js +11 -0
- package/dist/node_modules/.bun/to-style@1.3.3/node_modules/to-style/src/isFunction.js +11 -0
- package/dist/node_modules/.bun/to-style@1.3.3/node_modules/to-style/src/isObject.js +11 -0
- package/dist/node_modules/.bun/to-style@1.3.3/node_modules/to-style/src/prefixInfo.js +24 -0
- package/dist/node_modules/.bun/to-style@1.3.3/node_modules/to-style/src/prefixProperties.js +32 -0
- package/dist/node_modules/.bun/to-style@1.3.3/node_modules/to-style/src/prefixer.js +29 -0
- package/dist/node_modules/.bun/to-style@1.3.3/node_modules/to-style/src/stringUtils/camelize.js +14 -0
- package/dist/node_modules/.bun/to-style@1.3.3/node_modules/to-style/src/stringUtils/hyphenRe.js +8 -0
- package/dist/node_modules/.bun/to-style@1.3.3/node_modules/to-style/src/stringUtils/hyphenate.js +12 -0
- package/dist/node_modules/.bun/to-style@1.3.3/node_modules/to-style/src/stringUtils/separate.js +11 -0
- package/dist/node_modules/.bun/to-style@1.3.3/node_modules/to-style/src/stringUtils/toLowerFirst.js +10 -0
- package/dist/node_modules/.bun/to-style@1.3.3/node_modules/to-style/src/stringUtils/toUpperFirst.js +10 -0
- package/dist/node_modules/.bun/to-style@1.3.3/node_modules/to-style/src/toStyleObject.js +55 -0
- package/dist/node_modules/.bun/to-style@1.3.3/node_modules/to-style/src/toStyleString.js +16 -0
- package/dist/serialization.d.ts +35 -0
- package/dist/serialization.d.ts.map +1 -0
- package/dist/serialization.js +132 -0
- package/dist/with-mask.d.ts +35 -0
- package/dist/with-mask.d.ts.map +1 -0
- package/dist/with-mask.js +45 -0
- package/package.json +44 -0
- package/src/choices/choice.tsx +107 -0
- package/src/choices/index.tsx +74 -0
- package/src/componentize.tsx +23 -0
- package/src/components/blank.tsx +396 -0
- package/src/components/correct-input.tsx +92 -0
- package/src/components/dropdown.tsx +448 -0
- package/src/components/input.tsx +58 -0
- package/src/constructed-response.tsx +91 -0
- package/src/customizable.tsx +44 -0
- package/src/drag-in-the-blank.tsx +251 -0
- package/src/index.ts +26 -0
- package/src/inline-dropdown.tsx +39 -0
- package/src/mask.tsx +178 -0
- package/src/serialization.ts +270 -0
- package/src/with-mask.tsx +85 -0
|
@@ -0,0 +1,251 @@
|
|
|
1
|
+
// @ts-nocheck
|
|
2
|
+
/**
|
|
3
|
+
* @synced-from pie-lib/packages/mask-markup/src/drag-in-the-blank.jsx
|
|
4
|
+
* @auto-generated
|
|
5
|
+
*
|
|
6
|
+
* This file is automatically synced from pie-elements and converted to TypeScript.
|
|
7
|
+
* Manual edits will be overwritten on next sync.
|
|
8
|
+
* To make changes, edit the upstream JavaScript file and run sync again.
|
|
9
|
+
*/
|
|
10
|
+
|
|
11
|
+
import React from 'react';
|
|
12
|
+
import PropTypes from 'prop-types';
|
|
13
|
+
import { DragProvider } from '@pie-lib/drag';
|
|
14
|
+
import { DragOverlay, rectIntersection } from '@dnd-kit/core';
|
|
15
|
+
import Choices from './choices/index.js';
|
|
16
|
+
import Choice from './choices/choice.js';
|
|
17
|
+
import Blank from './components/blank.js';
|
|
18
|
+
import { withMask } from './with-mask.js';
|
|
19
|
+
|
|
20
|
+
const Masked = withMask('blank', (props) => (node, data, onChange) => {
|
|
21
|
+
const dataset = node.data?.dataset || {};
|
|
22
|
+
if (dataset.component === 'blank') {
|
|
23
|
+
// eslint-disable-next-line react/prop-types
|
|
24
|
+
const {
|
|
25
|
+
disabled,
|
|
26
|
+
duplicates,
|
|
27
|
+
correctResponse,
|
|
28
|
+
feedback,
|
|
29
|
+
showCorrectAnswer,
|
|
30
|
+
emptyResponseAreaWidth,
|
|
31
|
+
emptyResponseAreaHeight,
|
|
32
|
+
instanceId,
|
|
33
|
+
isDragging,
|
|
34
|
+
} = props;
|
|
35
|
+
const choiceId = showCorrectAnswer ? correctResponse[dataset.id] : data[dataset.id];
|
|
36
|
+
// eslint-disable-next-line react/prop-types
|
|
37
|
+
const choice = choiceId && props.choices.find((c) => c.id === choiceId);
|
|
38
|
+
|
|
39
|
+
return (
|
|
40
|
+
<Blank
|
|
41
|
+
key={`${node.type}-${dataset.id}`}
|
|
42
|
+
correct={showCorrectAnswer || (feedback && feedback[dataset.id])}
|
|
43
|
+
disabled={disabled}
|
|
44
|
+
duplicates={duplicates}
|
|
45
|
+
choice={choice}
|
|
46
|
+
id={dataset.id}
|
|
47
|
+
emptyResponseAreaWidth={emptyResponseAreaWidth}
|
|
48
|
+
emptyResponseAreaHeight={emptyResponseAreaHeight}
|
|
49
|
+
onChange={(id, choiceId) => {
|
|
50
|
+
const newData = { ...data };
|
|
51
|
+
if (choiceId === undefined) {
|
|
52
|
+
delete newData[id];
|
|
53
|
+
} else {
|
|
54
|
+
newData[id] = choiceId;
|
|
55
|
+
}
|
|
56
|
+
onChange(newData);
|
|
57
|
+
}}
|
|
58
|
+
instanceId={instanceId}
|
|
59
|
+
isDragging={isDragging}
|
|
60
|
+
/>
|
|
61
|
+
);
|
|
62
|
+
}
|
|
63
|
+
});
|
|
64
|
+
|
|
65
|
+
export default class DragInTheBlank extends React.Component {
|
|
66
|
+
constructor(props) {
|
|
67
|
+
super(props);
|
|
68
|
+
this.state = {
|
|
69
|
+
activeDragItem: null,
|
|
70
|
+
dropAnimation: undefined,
|
|
71
|
+
};
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
static propTypes = {
|
|
75
|
+
markup: PropTypes.string,
|
|
76
|
+
layout: PropTypes.object,
|
|
77
|
+
choicesPosition: PropTypes.string,
|
|
78
|
+
choices: PropTypes.array,
|
|
79
|
+
value: PropTypes.object,
|
|
80
|
+
onChange: PropTypes.func,
|
|
81
|
+
duplicates: PropTypes.bool,
|
|
82
|
+
disabled: PropTypes.bool,
|
|
83
|
+
feedback: PropTypes.object,
|
|
84
|
+
correctResponse: PropTypes.object,
|
|
85
|
+
showCorrectAnswer: PropTypes.bool,
|
|
86
|
+
emptyResponseAreaWidth: PropTypes.oneOfType([PropTypes.string, PropTypes.number]),
|
|
87
|
+
emptyResponseAreaHeight: PropTypes.oneOfType([PropTypes.string, PropTypes.number]),
|
|
88
|
+
instanceId: PropTypes.string,
|
|
89
|
+
};
|
|
90
|
+
|
|
91
|
+
static defaultProps = {
|
|
92
|
+
instanceId: 'drag-in-the-blank',
|
|
93
|
+
};
|
|
94
|
+
|
|
95
|
+
handleDragStart: any = (event) => {
|
|
96
|
+
const { active } = event;
|
|
97
|
+
|
|
98
|
+
if (active?.data?.current) {
|
|
99
|
+
this.setState({
|
|
100
|
+
activeDragItem: active.data.current,
|
|
101
|
+
dropAnimation: undefined, // default during drag
|
|
102
|
+
});
|
|
103
|
+
}
|
|
104
|
+
};
|
|
105
|
+
|
|
106
|
+
renderDragOverlay: any = () => {
|
|
107
|
+
const { activeDragItem } = this.state;
|
|
108
|
+
if (!activeDragItem) return null;
|
|
109
|
+
|
|
110
|
+
if (activeDragItem.type === 'MaskBlank') {
|
|
111
|
+
return (
|
|
112
|
+
<Choice
|
|
113
|
+
disabled={activeDragItem.disabled}
|
|
114
|
+
choice={activeDragItem.choice}
|
|
115
|
+
instanceId={activeDragItem.instanceId}
|
|
116
|
+
/>
|
|
117
|
+
);
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
return null;
|
|
121
|
+
};
|
|
122
|
+
|
|
123
|
+
handleDragEnd: any = (event) => {
|
|
124
|
+
const { active, over } = event;
|
|
125
|
+
const { onChange, value } = this.props;
|
|
126
|
+
|
|
127
|
+
const draggedData = active?.data?.current;
|
|
128
|
+
const dropData = over?.data?.current;
|
|
129
|
+
|
|
130
|
+
const isValidDrop =
|
|
131
|
+
!!active && !!over && draggedData?.type === 'MaskBlank' && dropData?.accepts?.includes('MaskBlank');
|
|
132
|
+
|
|
133
|
+
// Only animate back when drop is invalid
|
|
134
|
+
this.setState({
|
|
135
|
+
activeDragItem: null,
|
|
136
|
+
dropAnimation: isValidDrop ? null : undefined,
|
|
137
|
+
});
|
|
138
|
+
|
|
139
|
+
if (!isValidDrop || !onChange) return;
|
|
140
|
+
|
|
141
|
+
const draggedItem = draggedData;
|
|
142
|
+
const targetId = dropData.id;
|
|
143
|
+
|
|
144
|
+
if (dropData.toChoiceBoard === true) {
|
|
145
|
+
if (!draggedItem.fromChoice && draggedItem.id) {
|
|
146
|
+
const newValue = { ...value };
|
|
147
|
+
delete newValue[draggedItem.id];
|
|
148
|
+
onChange(newValue);
|
|
149
|
+
}
|
|
150
|
+
} else if (draggedItem.fromChoice === true) {
|
|
151
|
+
if (targetId && targetId !== 'drag-in-the-blank-droppable') {
|
|
152
|
+
const newValue = { ...value };
|
|
153
|
+
newValue[targetId] = draggedItem.choice.id;
|
|
154
|
+
onChange(newValue);
|
|
155
|
+
}
|
|
156
|
+
} else if (draggedItem.id && draggedItem.id !== targetId) {
|
|
157
|
+
const newValue = { ...value };
|
|
158
|
+
newValue[targetId] = draggedItem.choice.id;
|
|
159
|
+
delete newValue[draggedItem.id];
|
|
160
|
+
onChange(newValue);
|
|
161
|
+
}
|
|
162
|
+
};
|
|
163
|
+
|
|
164
|
+
getPositionDirection: any = (choicePosition) => {
|
|
165
|
+
let flexDirection;
|
|
166
|
+
let justifyContent;
|
|
167
|
+
let alignItems;
|
|
168
|
+
|
|
169
|
+
switch (choicePosition) {
|
|
170
|
+
case 'left':
|
|
171
|
+
flexDirection = 'row';
|
|
172
|
+
alignItems = 'center';
|
|
173
|
+
break;
|
|
174
|
+
case 'right':
|
|
175
|
+
flexDirection = 'row-reverse';
|
|
176
|
+
justifyContent = 'flex-end';
|
|
177
|
+
alignItems = 'center';
|
|
178
|
+
break;
|
|
179
|
+
case 'below':
|
|
180
|
+
flexDirection = 'column-reverse';
|
|
181
|
+
break;
|
|
182
|
+
default:
|
|
183
|
+
// above
|
|
184
|
+
flexDirection = 'column';
|
|
185
|
+
break;
|
|
186
|
+
}
|
|
187
|
+
|
|
188
|
+
return { flexDirection, justifyContent, alignItems };
|
|
189
|
+
};
|
|
190
|
+
|
|
191
|
+
render() {
|
|
192
|
+
const {
|
|
193
|
+
markup,
|
|
194
|
+
duplicates,
|
|
195
|
+
value,
|
|
196
|
+
onChange,
|
|
197
|
+
choicesPosition,
|
|
198
|
+
choices,
|
|
199
|
+
correctResponse,
|
|
200
|
+
disabled,
|
|
201
|
+
feedback,
|
|
202
|
+
showCorrectAnswer,
|
|
203
|
+
emptyResponseAreaWidth,
|
|
204
|
+
emptyResponseAreaHeight,
|
|
205
|
+
layout,
|
|
206
|
+
instanceId,
|
|
207
|
+
} = this.props;
|
|
208
|
+
|
|
209
|
+
const choicePosition = choicesPosition || 'below';
|
|
210
|
+
const style = { display: 'flex', minWidth: '100px', ...this.getPositionDirection(choicePosition) };
|
|
211
|
+
|
|
212
|
+
return (
|
|
213
|
+
<DragProvider
|
|
214
|
+
onDragStart={this.handleDragStart}
|
|
215
|
+
onDragEnd={this.handleDragEnd}
|
|
216
|
+
collisionDetection={rectIntersection}
|
|
217
|
+
>
|
|
218
|
+
<div ref={(ref) => (this.rootRef = ref)} style={style}>
|
|
219
|
+
<Choices
|
|
220
|
+
choicePosition={choicePosition}
|
|
221
|
+
choices={choices}
|
|
222
|
+
value={value}
|
|
223
|
+
duplicates={duplicates}
|
|
224
|
+
disabled={disabled}
|
|
225
|
+
instanceId={instanceId}
|
|
226
|
+
/>
|
|
227
|
+
<Masked
|
|
228
|
+
elementType="drag-in-the-blank"
|
|
229
|
+
markup={markup}
|
|
230
|
+
layout={layout}
|
|
231
|
+
value={value}
|
|
232
|
+
choices={choices}
|
|
233
|
+
onChange={onChange}
|
|
234
|
+
disabled={disabled}
|
|
235
|
+
duplicates={duplicates}
|
|
236
|
+
feedback={feedback}
|
|
237
|
+
correctResponse={correctResponse}
|
|
238
|
+
showCorrectAnswer={showCorrectAnswer}
|
|
239
|
+
emptyResponseAreaWidth={emptyResponseAreaWidth}
|
|
240
|
+
emptyResponseAreaHeight={emptyResponseAreaHeight}
|
|
241
|
+
instanceId={instanceId}
|
|
242
|
+
isDragging={!!this.state.activeDragItem}
|
|
243
|
+
/>
|
|
244
|
+
<DragOverlay style={{ pointerEvents: 'none' }} dropAnimation={this.state.dropAnimation}>
|
|
245
|
+
{this.renderDragOverlay()}
|
|
246
|
+
</DragOverlay>
|
|
247
|
+
</div>
|
|
248
|
+
</DragProvider>
|
|
249
|
+
);
|
|
250
|
+
}
|
|
251
|
+
}
|
package/src/index.ts
ADDED
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
// @ts-nocheck
|
|
2
|
+
/**
|
|
3
|
+
* @synced-from pie-lib/packages/mask-markup/src/index.js
|
|
4
|
+
* @auto-generated
|
|
5
|
+
*
|
|
6
|
+
* This file is automatically synced from pie-elements and converted to TypeScript.
|
|
7
|
+
* Manual edits will be overwritten on next sync.
|
|
8
|
+
* To make changes, edit the upstream JavaScript file and run sync again.
|
|
9
|
+
*/
|
|
10
|
+
|
|
11
|
+
import { buildLayoutFromMarkup, withMask } from './with-mask.js';
|
|
12
|
+
import DragInTheBlank from './drag-in-the-blank.js';
|
|
13
|
+
import ConstructedResponse from './constructed-response.js';
|
|
14
|
+
import Customizable from './customizable.js';
|
|
15
|
+
import InlineDropdown from './inline-dropdown.js';
|
|
16
|
+
import componentize from './componentize.js';
|
|
17
|
+
|
|
18
|
+
export {
|
|
19
|
+
withMask,
|
|
20
|
+
buildLayoutFromMarkup,
|
|
21
|
+
DragInTheBlank,
|
|
22
|
+
ConstructedResponse,
|
|
23
|
+
InlineDropdown,
|
|
24
|
+
componentize,
|
|
25
|
+
Customizable,
|
|
26
|
+
};
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
// @ts-nocheck
|
|
2
|
+
/**
|
|
3
|
+
* @synced-from pie-lib/packages/mask-markup/src/inline-dropdown.jsx
|
|
4
|
+
* @auto-generated
|
|
5
|
+
*
|
|
6
|
+
* This file is automatically synced from pie-elements and converted to TypeScript.
|
|
7
|
+
* Manual edits will be overwritten on next sync.
|
|
8
|
+
* To make changes, edit the upstream JavaScript file and run sync again.
|
|
9
|
+
*/
|
|
10
|
+
|
|
11
|
+
import React from 'react';
|
|
12
|
+
import Dropdown from './components/dropdown.js';
|
|
13
|
+
import { withMask } from './with-mask.js';
|
|
14
|
+
|
|
15
|
+
// eslint-disable-next-line react/display-name
|
|
16
|
+
export default withMask('dropdown', (props) => (node, data, onChange) => {
|
|
17
|
+
const dataset = node.data ? node.data.dataset || {} : {};
|
|
18
|
+
if (dataset.component === 'dropdown') {
|
|
19
|
+
// eslint-disable-next-line react/prop-types
|
|
20
|
+
const { choices, disabled, feedback, showCorrectAnswer } = props;
|
|
21
|
+
const correctAnswer = choices && choices[dataset.id] && choices[dataset.id].find((c) => c.correct);
|
|
22
|
+
const finalChoice = showCorrectAnswer ? correctAnswer && correctAnswer.value : data[dataset.id];
|
|
23
|
+
|
|
24
|
+
return (
|
|
25
|
+
<Dropdown
|
|
26
|
+
key={`${node.type}-dropdown-${dataset.id}`}
|
|
27
|
+
correct={feedback && feedback[dataset.id] && feedback[dataset.id] === 'correct'}
|
|
28
|
+
disabled={disabled || showCorrectAnswer}
|
|
29
|
+
value={finalChoice}
|
|
30
|
+
correctValue={showCorrectAnswer ? correctAnswer && correctAnswer.label : undefined}
|
|
31
|
+
id={dataset.id}
|
|
32
|
+
onChange={onChange}
|
|
33
|
+
choices={choices[dataset.id]}
|
|
34
|
+
showCorrectAnswer={showCorrectAnswer}
|
|
35
|
+
singleQuery={Object.keys(choices).length == 1}
|
|
36
|
+
/>
|
|
37
|
+
);
|
|
38
|
+
}
|
|
39
|
+
});
|
package/src/mask.tsx
ADDED
|
@@ -0,0 +1,178 @@
|
|
|
1
|
+
// @ts-nocheck
|
|
2
|
+
/**
|
|
3
|
+
* @synced-from pie-lib/packages/mask-markup/src/mask.jsx
|
|
4
|
+
* @auto-generated
|
|
5
|
+
*
|
|
6
|
+
* This file is automatically synced from pie-elements and converted to TypeScript.
|
|
7
|
+
* Manual edits will be overwritten on next sync.
|
|
8
|
+
* To make changes, edit the upstream JavaScript file and run sync again.
|
|
9
|
+
*/
|
|
10
|
+
|
|
11
|
+
import React from 'react';
|
|
12
|
+
import PropTypes from 'prop-types';
|
|
13
|
+
import { get } from 'lodash-es';
|
|
14
|
+
import { styled } from '@mui/material/styles';
|
|
15
|
+
import { renderMath } from '@pie-element/shared-math-rendering-mathjax';
|
|
16
|
+
import { MARK_TAGS } from './serialization.js';
|
|
17
|
+
|
|
18
|
+
const Paragraph: any = styled('div')(({ theme }) => ({
|
|
19
|
+
paddingTop: theme.spacing(0.5),
|
|
20
|
+
paddingBottom: theme.spacing(0.5),
|
|
21
|
+
}));
|
|
22
|
+
|
|
23
|
+
const Spacer: any = styled('span')(() => ({
|
|
24
|
+
display: 'inline-block',
|
|
25
|
+
width: '.75em',
|
|
26
|
+
}));
|
|
27
|
+
|
|
28
|
+
const restrictWhitespaceTypes = ['tbody', 'tr'];
|
|
29
|
+
|
|
30
|
+
const addText = (parentNode, text) => {
|
|
31
|
+
const isWhitespace = text.trim() === '';
|
|
32
|
+
const parentType = parentNode && parentNode.type;
|
|
33
|
+
|
|
34
|
+
if (isWhitespace && restrictWhitespaceTypes.includes(parentType)) {
|
|
35
|
+
return undefined;
|
|
36
|
+
} else {
|
|
37
|
+
return text;
|
|
38
|
+
}
|
|
39
|
+
};
|
|
40
|
+
|
|
41
|
+
const getMark = (n) => {
|
|
42
|
+
const mark = n.leaves.find((leave) => get(leave, 'marks', []).length);
|
|
43
|
+
|
|
44
|
+
if (mark) {
|
|
45
|
+
return mark.marks[0];
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
return null;
|
|
49
|
+
};
|
|
50
|
+
|
|
51
|
+
export const renderChildren = (layout, value, onChange, rootRenderChildren, parentNode, elementType) => {
|
|
52
|
+
if (!value) {
|
|
53
|
+
return null;
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
const children = [];
|
|
57
|
+
|
|
58
|
+
(layout.nodes || []).forEach((n, index) => {
|
|
59
|
+
const key = n.type ? `${n.type}-${index}` : `${index}`;
|
|
60
|
+
|
|
61
|
+
if (n.isMath) {
|
|
62
|
+
children.push(
|
|
63
|
+
<span
|
|
64
|
+
dangerouslySetInnerHTML={{
|
|
65
|
+
__html: `<math displaystyle="true">${n.nodes[0].innerHTML}</math>`,
|
|
66
|
+
}}
|
|
67
|
+
/>,
|
|
68
|
+
);
|
|
69
|
+
return children;
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
if (rootRenderChildren) {
|
|
73
|
+
const c = rootRenderChildren(n, value, onChange);
|
|
74
|
+
if (c) {
|
|
75
|
+
children.push(c);
|
|
76
|
+
if (parentNode?.type !== 'td' && elementType === 'drag-in-the-blank') {
|
|
77
|
+
children.push(<Spacer key={`spacer-${index}`} />);
|
|
78
|
+
}
|
|
79
|
+
return;
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
if (n.object === 'text') {
|
|
84
|
+
const content = n.leaves.reduce((acc, l) => {
|
|
85
|
+
const t = l.text;
|
|
86
|
+
const extraText = addText(parentNode, t);
|
|
87
|
+
return extraText ? acc + extraText : acc;
|
|
88
|
+
}, '');
|
|
89
|
+
const mark = getMark(n);
|
|
90
|
+
|
|
91
|
+
if (mark) {
|
|
92
|
+
let markKey;
|
|
93
|
+
|
|
94
|
+
for (markKey in MARK_TAGS) {
|
|
95
|
+
if (MARK_TAGS[markKey] === mark.type) {
|
|
96
|
+
const Tag = markKey;
|
|
97
|
+
|
|
98
|
+
children.push(<Tag key={key}>{content}</Tag>);
|
|
99
|
+
break;
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
} else if (content.length > 0) {
|
|
103
|
+
children.push(content);
|
|
104
|
+
if (parentNode?.type !== 'td' && elementType === 'drag-in-the-blank') {
|
|
105
|
+
children.push(<Spacer key={`spacer-${index}`} />);
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
} else {
|
|
109
|
+
const subNodes = renderChildren(n, value, onChange, rootRenderChildren, n, elementType);
|
|
110
|
+
if (n.type === 'p' || n.type === 'paragraph') {
|
|
111
|
+
children.push(<Paragraph key={key}>{subNodes}</Paragraph>);
|
|
112
|
+
} else {
|
|
113
|
+
const Tag = n.type;
|
|
114
|
+
if (n.nodes && n.nodes.length > 0) {
|
|
115
|
+
children.push(
|
|
116
|
+
<Tag key={key} {...n.data.attributes}>
|
|
117
|
+
{subNodes}
|
|
118
|
+
</Tag>,
|
|
119
|
+
);
|
|
120
|
+
} else {
|
|
121
|
+
children.push(<Tag key={key} {...n.data.attributes} />);
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
});
|
|
126
|
+
return children;
|
|
127
|
+
};
|
|
128
|
+
|
|
129
|
+
const MaskContainer: any = styled('div')(() => ({
|
|
130
|
+
display: 'initial',
|
|
131
|
+
'&:not(.MathJax) table': {
|
|
132
|
+
borderCollapse: 'collapse',
|
|
133
|
+
},
|
|
134
|
+
// align table content to left as per STAR requirement PD-3687
|
|
135
|
+
'&:not(.MathJax) table td, &:not(.MathJax) table th': {
|
|
136
|
+
padding: '8px 12px',
|
|
137
|
+
textAlign: 'left',
|
|
138
|
+
},
|
|
139
|
+
}));
|
|
140
|
+
|
|
141
|
+
/**
|
|
142
|
+
* Renders a layout that uses the slate.js Value model structure.
|
|
143
|
+
*/
|
|
144
|
+
export default class Mask extends React.Component {
|
|
145
|
+
constructor(props) {
|
|
146
|
+
super(props);
|
|
147
|
+
this.internalContainerRef = React.createRef();
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
static propTypes = {
|
|
151
|
+
renderChildren: PropTypes.func,
|
|
152
|
+
layout: PropTypes.object,
|
|
153
|
+
value: PropTypes.object,
|
|
154
|
+
onChange: PropTypes.func,
|
|
155
|
+
elementType: PropTypes.string,
|
|
156
|
+
containerRef: PropTypes.oneOfType([PropTypes.func, PropTypes.shape({ current: PropTypes.instanceOf(Element) })]),
|
|
157
|
+
};
|
|
158
|
+
|
|
159
|
+
componentDidMount() {
|
|
160
|
+
const containerRef = this.props.containerRef || this.internalContainerRef;
|
|
161
|
+
if (containerRef.current && typeof renderMath === 'function') {
|
|
162
|
+
renderMath(containerRef.current);
|
|
163
|
+
}
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
handleChange: any = (id, value) => {
|
|
167
|
+
const data = { ...this.props.value, [id]: value };
|
|
168
|
+
this.props.onChange(data);
|
|
169
|
+
};
|
|
170
|
+
|
|
171
|
+
render() {
|
|
172
|
+
const { value, layout, elementType, containerRef } = this.props;
|
|
173
|
+
const children = renderChildren(layout, value, this.handleChange, this.props.renderChildren, null, elementType);
|
|
174
|
+
const ref = containerRef || this.internalContainerRef;
|
|
175
|
+
|
|
176
|
+
return <MaskContainer ref={ref}>{children}</MaskContainer>;
|
|
177
|
+
}
|
|
178
|
+
}
|