@pie-element/hotspot 11.1.1-next.89 → 11.1.1-next.92
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/configure/lib/root.js +2 -1
- package/configure/lib/root.js.map +1 -1
- package/configure/src/root.jsx +6 -10
- package/controller/lib/index.js +2 -1
- package/controller/lib/index.js.map +1 -1
- package/controller/src/index.js +26 -24
- package/docs/demo/generate.js +20 -16
- package/lib/hotspot/circle.js +4 -1
- package/lib/hotspot/circle.js.map +1 -1
- package/lib/hotspot/container.js +92 -7
- package/lib/hotspot/container.js.map +1 -1
- package/lib/hotspot/polygon.js +4 -1
- package/lib/hotspot/polygon.js.map +1 -1
- package/lib/hotspot/rectangle.js +7 -4
- package/lib/hotspot/rectangle.js.map +1 -1
- package/package.json +2 -2
- package/src/hotspot/circle.jsx +4 -1
- package/src/hotspot/container.jsx +80 -0
- package/src/hotspot/polygon.jsx +4 -1
- package/src/hotspot/rectangle.jsx +5 -2
|
@@ -14,8 +14,19 @@ const BaseContainer = styled('div')(({ theme }) => ({
|
|
|
14
14
|
background: theme.palette.common.white,
|
|
15
15
|
border: `${theme.spacing(1)} solid ${theme.palette.common.white}`,
|
|
16
16
|
width: 'fit-content',
|
|
17
|
+
maxWidth: '100%',
|
|
18
|
+
overflowX: 'auto',
|
|
17
19
|
}));
|
|
18
20
|
|
|
21
|
+
const HiddenFocusable = styled('span')({
|
|
22
|
+
position: 'absolute',
|
|
23
|
+
width: 1,
|
|
24
|
+
height: 1,
|
|
25
|
+
overflow: 'hidden',
|
|
26
|
+
clip: 'rect(0, 0, 0, 0)',
|
|
27
|
+
whiteSpace: 'nowrap',
|
|
28
|
+
});
|
|
29
|
+
|
|
19
30
|
const ImageContainer = styled('div')({
|
|
20
31
|
position: 'relative',
|
|
21
32
|
width: 'fit-content',
|
|
@@ -34,6 +45,13 @@ const StyledStage = styled(Stage)({
|
|
|
34
45
|
});
|
|
35
46
|
|
|
36
47
|
export class Container extends React.Component {
|
|
48
|
+
constructor(props) {
|
|
49
|
+
super(props);
|
|
50
|
+
this.state = {
|
|
51
|
+
focusedShapeId: null,
|
|
52
|
+
};
|
|
53
|
+
}
|
|
54
|
+
|
|
37
55
|
isSelected(shape) {
|
|
38
56
|
const selectedShape = this.props.session.answers.filter((answer) => answer.id === shape.id)[0];
|
|
39
57
|
return !!selectedShape;
|
|
@@ -57,6 +75,44 @@ export class Container extends React.Component {
|
|
|
57
75
|
return null;
|
|
58
76
|
};
|
|
59
77
|
|
|
78
|
+
getAllShapesSorted = () => {
|
|
79
|
+
const { shapes: { rectangles = [], polygons = [], circles = [] } } = this.props;
|
|
80
|
+
const allShapes = [
|
|
81
|
+
...rectangles.map((s) => ({ ...s, type: 'rectangle' })),
|
|
82
|
+
...polygons.map((s) => ({ ...s, type: 'polygon' })),
|
|
83
|
+
...circles.map((s) => ({ ...s, type: 'circle' })),
|
|
84
|
+
];
|
|
85
|
+
allShapes.sort((a, b) => String(a.id).localeCompare(String(b.id), undefined, { numeric: true }));
|
|
86
|
+
|
|
87
|
+
return allShapes;
|
|
88
|
+
};
|
|
89
|
+
|
|
90
|
+
handleShapeFocus = (shapeId) => {
|
|
91
|
+
this.setState({ focusedShapeId: shapeId });
|
|
92
|
+
};
|
|
93
|
+
|
|
94
|
+
handleShapeBlur = () => {
|
|
95
|
+
this.setState({ focusedShapeId: null });
|
|
96
|
+
};
|
|
97
|
+
|
|
98
|
+
handleShapeKeyDown = (e, shapeId) => {
|
|
99
|
+
if (e.key === 'Enter' || e.key === ' ') {
|
|
100
|
+
e.preventDefault();
|
|
101
|
+
|
|
102
|
+
const { onSelectChoice, disabled } = this.props;
|
|
103
|
+
|
|
104
|
+
if (!disabled) {
|
|
105
|
+
const shape = this.getAllShapesSorted().find((s) => s.id === shapeId);
|
|
106
|
+
|
|
107
|
+
if (shape) {
|
|
108
|
+
const selected = this.isSelected(shape);
|
|
109
|
+
|
|
110
|
+
onSelectChoice({ id: shapeId, selected: !selected, selector: 'Keyboard' });
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
};
|
|
115
|
+
|
|
60
116
|
render() {
|
|
61
117
|
const {
|
|
62
118
|
dimensions: { width: withProp, height: heightProp },
|
|
@@ -74,9 +130,13 @@ export class Container extends React.Component {
|
|
|
74
130
|
showCorrect,
|
|
75
131
|
} = this.props;
|
|
76
132
|
|
|
133
|
+
const { focusedShapeId } = this.state;
|
|
134
|
+
|
|
77
135
|
const width = withProp * SCALE;
|
|
78
136
|
const height = heightProp * SCALE;
|
|
79
137
|
|
|
138
|
+
const sortedShapes = this.getAllShapesSorted();
|
|
139
|
+
|
|
80
140
|
return (
|
|
81
141
|
<BaseContainer style={{ padding: strokeWidth / 2 }}>
|
|
82
142
|
{imageUrl ? (
|
|
@@ -125,6 +185,7 @@ export class Container extends React.Component {
|
|
|
125
185
|
strokeWidth={strokeWidth}
|
|
126
186
|
markAsCorrect={markAsCorrect}
|
|
127
187
|
showCorrectEnabled={showCorrect}
|
|
188
|
+
focused={focusedShapeId === shape.id}
|
|
128
189
|
/>
|
|
129
190
|
);
|
|
130
191
|
})}
|
|
@@ -153,6 +214,7 @@ export class Container extends React.Component {
|
|
|
153
214
|
selectedHotspotColor={selectedHotspotColor}
|
|
154
215
|
hoverOutlineColor={hoverOutlineColor}
|
|
155
216
|
showCorrectEnabled={showCorrect}
|
|
217
|
+
focused={focusedShapeId === polygon.id}
|
|
156
218
|
/>
|
|
157
219
|
);
|
|
158
220
|
})}
|
|
@@ -183,11 +245,29 @@ export class Container extends React.Component {
|
|
|
183
245
|
selectedHotspotColor={selectedHotspotColor}
|
|
184
246
|
hoverOutlineColor={hoverOutlineColor}
|
|
185
247
|
showCorrectEnabled={showCorrect}
|
|
248
|
+
focused={focusedShapeId === shape.id}
|
|
186
249
|
/>
|
|
187
250
|
);
|
|
188
251
|
})}
|
|
189
252
|
</Layer>
|
|
190
253
|
</StyledStage>
|
|
254
|
+
|
|
255
|
+
{sortedShapes.map((shape) => {
|
|
256
|
+
const selected = this.isSelected(shape);
|
|
257
|
+
|
|
258
|
+
return (
|
|
259
|
+
<HiddenFocusable
|
|
260
|
+
key={`focus-${shape.id}`}
|
|
261
|
+
tabIndex={disabled ? -1 : 0}
|
|
262
|
+
role="button"
|
|
263
|
+
aria-label={shape.ariaLabel || ''}
|
|
264
|
+
aria-pressed={selected}
|
|
265
|
+
onFocus={() => this.handleShapeFocus(shape.id)}
|
|
266
|
+
onBlur={this.handleShapeBlur}
|
|
267
|
+
onKeyDown={(e) => this.handleShapeKeyDown(e, shape.id)}
|
|
268
|
+
/>
|
|
269
|
+
);
|
|
270
|
+
})}
|
|
191
271
|
</BaseContainer>
|
|
192
272
|
);
|
|
193
273
|
}
|
package/src/hotspot/polygon.jsx
CHANGED
|
@@ -68,6 +68,7 @@ class PolygonComponent extends React.Component {
|
|
|
68
68
|
hoverOutlineColor,
|
|
69
69
|
outlineColor,
|
|
70
70
|
selected,
|
|
71
|
+
focused,
|
|
71
72
|
points,
|
|
72
73
|
evaluateText,
|
|
73
74
|
strokeWidth,
|
|
@@ -120,7 +121,7 @@ class PolygonComponent extends React.Component {
|
|
|
120
121
|
iconSrc = faWrong;
|
|
121
122
|
}
|
|
122
123
|
}
|
|
123
|
-
const useHoveredStyle = hovered && hoverOutlineColor;
|
|
124
|
+
const useHoveredStyle = (hovered || focused) && hoverOutlineColor;
|
|
124
125
|
|
|
125
126
|
const xValues = pointsParsed.filter((_, index) => index % 2 === 0); // Even indices are x-coordinates
|
|
126
127
|
const yValues = pointsParsed.filter((_, index) => index % 2 !== 0); // Odd indices are y-coordinates
|
|
@@ -174,6 +175,7 @@ PolygonComponent.propTypes = {
|
|
|
174
175
|
isEvaluateMode: PropTypes.bool.isRequired,
|
|
175
176
|
hoverOutlineColor: PropTypes.string,
|
|
176
177
|
disabled: PropTypes.bool.isRequired,
|
|
178
|
+
focused: PropTypes.bool,
|
|
177
179
|
onClick: PropTypes.func.isRequired,
|
|
178
180
|
outlineColor: PropTypes.string.isRequired,
|
|
179
181
|
points: PropTypes.array.isRequired,
|
|
@@ -188,6 +190,7 @@ PolygonComponent.propTypes = {
|
|
|
188
190
|
|
|
189
191
|
PolygonComponent.defaultProps = {
|
|
190
192
|
evaluateText: null,
|
|
193
|
+
focused: false,
|
|
191
194
|
strokeWidth: 5,
|
|
192
195
|
scale: 1,
|
|
193
196
|
};
|
|
@@ -51,6 +51,7 @@ class RectComponent extends React.Component {
|
|
|
51
51
|
isEvaluateMode,
|
|
52
52
|
outlineColor,
|
|
53
53
|
selected,
|
|
54
|
+
focused,
|
|
54
55
|
width,
|
|
55
56
|
x,
|
|
56
57
|
y,
|
|
@@ -60,6 +61,7 @@ class RectComponent extends React.Component {
|
|
|
60
61
|
markAsCorrect,
|
|
61
62
|
showCorrectEnabled,
|
|
62
63
|
} = this.props;
|
|
64
|
+
const { hovered } = this.state;
|
|
63
65
|
|
|
64
66
|
const outlineColorParsed = isEvaluateMode
|
|
65
67
|
? this.getEvaluateOutlineColor(isCorrect, markAsCorrect, outlineColor)
|
|
@@ -102,8 +104,7 @@ class RectComponent extends React.Component {
|
|
|
102
104
|
}
|
|
103
105
|
}
|
|
104
106
|
|
|
105
|
-
const
|
|
106
|
-
const useHoveredStyle = hovered && hoverOutlineColor;
|
|
107
|
+
const useHoveredStyle = (hovered || focused) && hoverOutlineColor;
|
|
107
108
|
|
|
108
109
|
return (
|
|
109
110
|
<Group scaleX={scale} scaleY={scale}>
|
|
@@ -147,6 +148,7 @@ RectComponent.propTypes = {
|
|
|
147
148
|
isEvaluateMode: PropTypes.bool.isRequired,
|
|
148
149
|
hoverOutlineColor: PropTypes.string,
|
|
149
150
|
disabled: PropTypes.bool.isRequired,
|
|
151
|
+
focused: PropTypes.bool,
|
|
150
152
|
onClick: PropTypes.func.isRequired,
|
|
151
153
|
outlineColor: PropTypes.string.isRequired,
|
|
152
154
|
selected: PropTypes.bool.isRequired,
|
|
@@ -164,6 +166,7 @@ RectComponent.propTypes = {
|
|
|
164
166
|
RectComponent.defaultProps = {
|
|
165
167
|
isCorrect: false,
|
|
166
168
|
evaluateText: null,
|
|
169
|
+
focused: false,
|
|
167
170
|
strokeWidth: 5,
|
|
168
171
|
scale: 1,
|
|
169
172
|
};
|