@pie-lib/graphing 3.1.1-next.0 → 3.2.0-next.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.
Files changed (198) hide show
  1. package/lib/axis/arrow.js +0 -3
  2. package/lib/axis/arrow.js.map +1 -1
  3. package/lib/axis/axes.js +0 -16
  4. package/lib/axis/axes.js.map +1 -1
  5. package/lib/axis/index.js +0 -7
  6. package/lib/axis/index.js.map +1 -1
  7. package/lib/bg.js +0 -6
  8. package/lib/bg.js.map +1 -1
  9. package/lib/container/actions.js +0 -1
  10. package/lib/container/actions.js.map +1 -1
  11. package/lib/container/index.js +4 -8
  12. package/lib/container/index.js.map +1 -1
  13. package/lib/container/marks.js +0 -2
  14. package/lib/container/marks.js.map +1 -1
  15. package/lib/container/middleware.js +0 -1
  16. package/lib/container/middleware.js.map +1 -1
  17. package/lib/container/reducer.js +0 -1
  18. package/lib/container/reducer.js.map +1 -1
  19. package/lib/coordinates-label.js +0 -11
  20. package/lib/coordinates-label.js.map +1 -1
  21. package/lib/graph-with-controls.js +3 -21
  22. package/lib/graph-with-controls.js.map +1 -1
  23. package/lib/graph.js +8 -27
  24. package/lib/graph.js.map +1 -1
  25. package/lib/grid-setup.js +0 -11
  26. package/lib/grid-setup.js.map +1 -1
  27. package/lib/grid.js +0 -22
  28. package/lib/grid.js.map +1 -1
  29. package/lib/index.js +0 -7
  30. package/lib/index.js.map +1 -1
  31. package/lib/key-legend.js +1 -2
  32. package/lib/key-legend.js.map +1 -1
  33. package/lib/label-svg-icon.js +0 -1
  34. package/lib/label-svg-icon.js.map +1 -1
  35. package/lib/labels.js +0 -13
  36. package/lib/labels.js.map +1 -1
  37. package/lib/mark-label.js +0 -15
  38. package/lib/mark-label.js.map +1 -1
  39. package/lib/toggle-bar.js +0 -17
  40. package/lib/toggle-bar.js.map +1 -1
  41. package/lib/tool-menu.js +0 -3
  42. package/lib/tool-menu.js.map +1 -1
  43. package/lib/tools/absolute/component.js +0 -1
  44. package/lib/tools/absolute/component.js.map +1 -1
  45. package/lib/tools/absolute/index.js +0 -10
  46. package/lib/tools/absolute/index.js.map +1 -1
  47. package/lib/tools/circle/bg-circle.js +0 -15
  48. package/lib/tools/circle/bg-circle.js.map +1 -1
  49. package/lib/tools/circle/component.js +2 -15
  50. package/lib/tools/circle/component.js.map +1 -1
  51. package/lib/tools/circle/index.js +0 -10
  52. package/lib/tools/circle/index.js.map +1 -1
  53. package/lib/tools/exponential/component.js +0 -1
  54. package/lib/tools/exponential/component.js.map +1 -1
  55. package/lib/tools/exponential/index.js +0 -10
  56. package/lib/tools/exponential/index.js.map +1 -1
  57. package/lib/tools/index.js +0 -1
  58. package/lib/tools/index.js.map +1 -1
  59. package/lib/tools/line/component.js +0 -2
  60. package/lib/tools/line/component.js.map +1 -1
  61. package/lib/tools/line/index.js +0 -1
  62. package/lib/tools/line/index.js.map +1 -1
  63. package/lib/tools/parabola/component.js +0 -1
  64. package/lib/tools/parabola/component.js.map +1 -1
  65. package/lib/tools/parabola/index.js +0 -10
  66. package/lib/tools/parabola/index.js.map +1 -1
  67. package/lib/tools/point/component.js +3 -15
  68. package/lib/tools/point/component.js.map +1 -1
  69. package/lib/tools/point/index.js +0 -10
  70. package/lib/tools/point/index.js.map +1 -1
  71. package/lib/tools/polygon/component.js +5 -29
  72. package/lib/tools/polygon/component.js.map +1 -1
  73. package/lib/tools/polygon/index.js +0 -12
  74. package/lib/tools/polygon/index.js.map +1 -1
  75. package/lib/tools/polygon/line.js +0 -15
  76. package/lib/tools/polygon/line.js.map +1 -1
  77. package/lib/tools/polygon/polygon.js +0 -18
  78. package/lib/tools/polygon/polygon.js.map +1 -1
  79. package/lib/tools/ray/component.js +0 -11
  80. package/lib/tools/ray/component.js.map +1 -1
  81. package/lib/tools/ray/index.js +0 -1
  82. package/lib/tools/ray/index.js.map +1 -1
  83. package/lib/tools/segment/component.js +0 -10
  84. package/lib/tools/segment/component.js.map +1 -1
  85. package/lib/tools/segment/index.js +0 -1
  86. package/lib/tools/segment/index.js.map +1 -1
  87. package/lib/tools/shared/arrow-head.js +0 -14
  88. package/lib/tools/shared/arrow-head.js.map +1 -1
  89. package/lib/tools/shared/icons/CorrectSVG.js +0 -1
  90. package/lib/tools/shared/icons/CorrectSVG.js.map +1 -1
  91. package/lib/tools/shared/icons/IncorrectSVG.js +0 -1
  92. package/lib/tools/shared/icons/IncorrectSVG.js.map +1 -1
  93. package/lib/tools/shared/icons/MissingSVG.js +0 -1
  94. package/lib/tools/shared/icons/MissingSVG.js.map +1 -1
  95. package/lib/tools/shared/line/index.js +7 -21
  96. package/lib/tools/shared/line/index.js.map +1 -1
  97. package/lib/tools/shared/line/line-path.js +0 -15
  98. package/lib/tools/shared/line/line-path.js.map +1 -1
  99. package/lib/tools/shared/line/with-root-edge.js +0 -11
  100. package/lib/tools/shared/line/with-root-edge.js.map +1 -1
  101. package/lib/tools/shared/point/arrow-point.js +0 -3
  102. package/lib/tools/shared/point/arrow-point.js.map +1 -1
  103. package/lib/tools/shared/point/arrow.js +0 -3
  104. package/lib/tools/shared/point/arrow.js.map +1 -1
  105. package/lib/tools/shared/point/base-point.js +0 -16
  106. package/lib/tools/shared/point/base-point.js.map +1 -1
  107. package/lib/tools/shared/point/index.js +0 -7
  108. package/lib/tools/shared/point/index.js.map +1 -1
  109. package/lib/tools/shared/styles.js +0 -1
  110. package/lib/tools/shared/styles.js.map +1 -1
  111. package/lib/tools/shared/types.js +0 -1
  112. package/lib/tools/shared/types.js.map +1 -1
  113. package/lib/tools/sine/component.js +0 -10
  114. package/lib/tools/sine/component.js.map +1 -1
  115. package/lib/tools/sine/index.js +0 -10
  116. package/lib/tools/sine/index.js.map +1 -1
  117. package/lib/tools/vector/component.js +0 -10
  118. package/lib/tools/vector/component.js.map +1 -1
  119. package/lib/tools/vector/index.js +0 -1
  120. package/lib/tools/vector/index.js.map +1 -1
  121. package/lib/undo-redo.js +0 -2
  122. package/lib/undo-redo.js.map +1 -1
  123. package/lib/use-debounce.js +0 -2
  124. package/lib/use-debounce.js.map +1 -1
  125. package/lib/utils.js +9 -26
  126. package/lib/utils.js.map +1 -1
  127. package/package.json +13 -10
  128. package/src/__tests__/bg.test.jsx +250 -0
  129. package/src/__tests__/coordinates-label.test.jsx +243 -0
  130. package/src/__tests__/graph-with-controls.test.jsx +9 -16
  131. package/src/__tests__/graph.test.jsx +560 -5
  132. package/src/__tests__/grid-setup.test.jsx +645 -0
  133. package/src/__tests__/grid.test.jsx +1 -1
  134. package/src/__tests__/key-legend.test.jsx +260 -0
  135. package/src/__tests__/label-svg-icon.test.jsx +278 -0
  136. package/src/__tests__/mark-label.test.jsx +1 -1
  137. package/src/__tests__/toggle-bar.test.jsx +0 -6
  138. package/src/__tests__/tool-menu.test.jsx +0 -4
  139. package/src/__tests__/use-debounce.test.js +1 -1
  140. package/src/__tests__/utils.test.js +15 -61
  141. package/src/axis/__tests__/axes.test.jsx +1 -1
  142. package/src/axis/axes.jsx +7 -21
  143. package/src/axis/index.js +1 -0
  144. package/src/bg.jsx +1 -1
  145. package/src/container/__tests__/actions.test.js +105 -0
  146. package/src/container/__tests__/index.test.jsx +319 -0
  147. package/src/container/__tests__/marks.test.js +172 -0
  148. package/src/container/__tests__/middleware.test.js +235 -0
  149. package/src/container/__tests__/reducer.test.js +324 -0
  150. package/src/container/index.jsx +2 -3
  151. package/src/coordinates-label.jsx +1 -7
  152. package/src/graph-with-controls.jsx +8 -6
  153. package/src/graph.jsx +2 -3
  154. package/src/grid-setup.jsx +1 -1
  155. package/src/key-legend.jsx +2 -1
  156. package/src/mark-label.jsx +7 -24
  157. package/src/toggle-bar.jsx +8 -1
  158. package/src/tools/absolute/__tests__/component.test.jsx +1 -2
  159. package/src/tools/absolute/component.jsx +2 -2
  160. package/src/tools/circle/__tests__/component.test.jsx +438 -0
  161. package/src/tools/circle/__tests__/index.test.js +480 -0
  162. package/src/tools/circle/bg-circle.jsx +2 -2
  163. package/src/tools/circle/component.jsx +10 -12
  164. package/src/tools/exponential/__tests__/component.test.jsx +0 -1
  165. package/src/tools/exponential/__tests__/index.test.js +729 -0
  166. package/src/tools/exponential/component.jsx +1 -1
  167. package/src/tools/line/__tests__/component.test.jsx +1 -0
  168. package/src/tools/line/component.jsx +4 -11
  169. package/src/tools/parabola/__tests__/component.test.jsx +0 -1
  170. package/src/tools/parabola/__tests__/index.test.js +470 -0
  171. package/src/tools/parabola/component.jsx +1 -1
  172. package/src/tools/point/__tests__/component.test.jsx +310 -2
  173. package/src/tools/point/__tests__/index.test.js +241 -0
  174. package/src/tools/point/component.jsx +1 -2
  175. package/src/tools/polygon/__tests__/component.test.jsx +391 -2
  176. package/src/tools/polygon/__tests__/index.test.js +237 -8
  177. package/src/tools/polygon/__tests__/line.test.jsx +13 -0
  178. package/src/tools/polygon/__tests__/polygon.test.jsx +19 -1
  179. package/src/tools/polygon/component.jsx +4 -14
  180. package/src/tools/polygon/line.jsx +1 -1
  181. package/src/tools/polygon/polygon.jsx +1 -1
  182. package/src/tools/ray/__tests__/component.test.jsx +1 -0
  183. package/src/tools/ray/component.jsx +3 -5
  184. package/src/tools/segment/__tests__/component.test.jsx +1 -0
  185. package/src/tools/segment/component.jsx +1 -1
  186. package/src/tools/shared/arrow-head.jsx +11 -6
  187. package/src/tools/shared/line/__tests__/index.test.jsx +1 -1
  188. package/src/tools/shared/line/__tests__/line-path.test.jsx +3 -3
  189. package/src/tools/shared/line/__tests__/with-root-edge.test.jsx +2 -2
  190. package/src/tools/shared/line/index.jsx +4 -6
  191. package/src/tools/shared/line/line-path.jsx +2 -8
  192. package/src/tools/shared/point/arrow-point.jsx +2 -5
  193. package/src/tools/sine/component.jsx +2 -2
  194. package/src/tools/vector/component.jsx +1 -1
  195. package/src/undo-redo.jsx +3 -9
  196. package/src/use-debounce.js +1 -1
  197. package/src/utils.js +1 -5
  198. package/NEXT.CHANGELOG.json +0 -16
@@ -0,0 +1,324 @@
1
+ import reducer from '../reducer';
2
+ import { changeMarks } from '../actions';
3
+
4
+ describe('container reducer', () => {
5
+ describe('reducer creation', () => {
6
+ it('creates a reducer function', () => {
7
+ const rootReducer = reducer();
8
+ expect(typeof rootReducer).toBe('function');
9
+ });
10
+
11
+ it('returns an object with marks property', () => {
12
+ const rootReducer = reducer();
13
+ const state = rootReducer(undefined, { type: 'INIT' });
14
+ expect(state).toHaveProperty('marks');
15
+ });
16
+
17
+ it('wraps marks reducer with undoable', () => {
18
+ const rootReducer = reducer();
19
+ const state = rootReducer(undefined, { type: 'INIT' });
20
+
21
+ expect(state.marks).toHaveProperty('past');
22
+ expect(state.marks).toHaveProperty('present');
23
+ expect(state.marks).toHaveProperty('future');
24
+ });
25
+ });
26
+
27
+ describe('initial state', () => {
28
+ it('initializes with empty past', () => {
29
+ const rootReducer = reducer();
30
+ const state = rootReducer(undefined, { type: 'INIT' });
31
+
32
+ expect(state.marks.past).toEqual([]);
33
+ });
34
+
35
+ it('initializes with empty present', () => {
36
+ const rootReducer = reducer();
37
+ const state = rootReducer(undefined, { type: 'INIT' });
38
+
39
+ expect(state.marks.present).toEqual([]);
40
+ });
41
+
42
+ it('initializes with empty future', () => {
43
+ const rootReducer = reducer();
44
+ const state = rootReducer(undefined, { type: 'INIT' });
45
+
46
+ expect(state.marks.future).toEqual([]);
47
+ });
48
+ });
49
+
50
+ describe('CHANGE_MARKS action', () => {
51
+ it('updates present with new marks', () => {
52
+ const rootReducer = reducer();
53
+ const newMarks = [{ id: 1, type: 'point', x: 5, y: 10 }];
54
+ const action = changeMarks(newMarks);
55
+
56
+ let state = rootReducer(undefined, { type: '@@INIT' });
57
+ state = rootReducer(state, action);
58
+
59
+ expect(state.marks.present).toEqual(newMarks);
60
+ });
61
+
62
+ it('adds previous state to past', () => {
63
+ const rootReducer = reducer();
64
+ const firstMarks = [{ id: 1, type: 'point' }];
65
+ const secondMarks = [{ id: 2, type: 'line' }];
66
+
67
+ let state = rootReducer(undefined, { type: '@@INIT' });
68
+ state = rootReducer(state, changeMarks(firstMarks));
69
+ state = rootReducer(state, changeMarks(secondMarks));
70
+
71
+ expect(state.marks.past.length).toBeGreaterThan(0);
72
+ expect(state.marks.present).toEqual(secondMarks);
73
+ });
74
+
75
+ it('clears future on new action', () => {
76
+ const rootReducer = reducer();
77
+ const firstMarks = [{ id: 1, type: 'point' }];
78
+ const secondMarks = [{ id: 2, type: 'line' }];
79
+ const thirdMarks = [{ id: 3, type: 'circle' }];
80
+
81
+ let state = rootReducer(undefined, { type: '@@INIT' });
82
+ state = rootReducer(state, changeMarks(firstMarks));
83
+ state = rootReducer(state, changeMarks(secondMarks));
84
+ state = rootReducer(state, { type: '@@redux-undo/UNDO' });
85
+
86
+ expect(state.marks.future.length).toBeGreaterThan(0);
87
+
88
+ state = rootReducer(state, changeMarks(thirdMarks));
89
+ expect(state.marks.future).toEqual([]);
90
+ });
91
+
92
+ it('handles empty marks array', () => {
93
+ const rootReducer = reducer();
94
+ const action = changeMarks([]);
95
+
96
+ let state = rootReducer(undefined, { type: '@@INIT' });
97
+ state = rootReducer(state, action);
98
+
99
+ expect(state.marks.present).toEqual([]);
100
+ });
101
+
102
+ it('handles multiple marks', () => {
103
+ const rootReducer = reducer();
104
+ const marks = [
105
+ { id: 1, type: 'point', x: 1, y: 2 },
106
+ { id: 2, type: 'line', from: { x: 0, y: 0 }, to: { x: 5, y: 5 } },
107
+ { id: 3, type: 'circle', center: { x: 3, y: 3 }, radius: 2 },
108
+ ];
109
+ const action = changeMarks(marks);
110
+
111
+ let state = rootReducer(undefined, { type: '@@INIT' });
112
+ state = rootReducer(state, action);
113
+
114
+ expect(state.marks.present).toEqual(marks);
115
+ expect(state.marks.present.length).toBe(3);
116
+ });
117
+ });
118
+
119
+ describe('undo functionality', () => {
120
+ it('supports undo action', () => {
121
+ const rootReducer = reducer();
122
+ const firstMarks = [{ id: 1, type: 'point' }];
123
+ const secondMarks = [{ id: 2, type: 'line' }];
124
+
125
+ let state = rootReducer(undefined, { type: '@@INIT' });
126
+ state = rootReducer(state, changeMarks(firstMarks));
127
+ state = rootReducer(state, changeMarks(secondMarks));
128
+
129
+ state = rootReducer(state, { type: '@@redux-undo/UNDO' });
130
+
131
+ expect(state.marks.present).toEqual(firstMarks);
132
+ });
133
+
134
+ it('moves present to future on undo', () => {
135
+ const rootReducer = reducer();
136
+ const firstMarks = [{ id: 1, type: 'point' }];
137
+ const secondMarks = [{ id: 2, type: 'line' }];
138
+
139
+ let state = rootReducer(undefined, { type: '@@INIT' });
140
+ state = rootReducer(state, changeMarks(firstMarks));
141
+ state = rootReducer(state, changeMarks(secondMarks));
142
+ state = rootReducer(state, { type: '@@redux-undo/UNDO' });
143
+
144
+ expect(state.marks.future.length).toBeGreaterThan(0);
145
+ });
146
+
147
+ it('handles multiple undos', () => {
148
+ const rootReducer = reducer();
149
+ const marks1 = [{ id: 1 }];
150
+ const marks2 = [{ id: 2 }];
151
+ const marks3 = [{ id: 3 }];
152
+
153
+ let state = rootReducer(undefined, { type: '@@INIT' });
154
+ state = rootReducer(state, changeMarks(marks1));
155
+ state = rootReducer(state, changeMarks(marks2));
156
+ state = rootReducer(state, changeMarks(marks3));
157
+
158
+ state = rootReducer(state, { type: '@@redux-undo/UNDO' });
159
+ state = rootReducer(state, { type: '@@redux-undo/UNDO' });
160
+
161
+ expect(state.marks.present).toEqual(marks1);
162
+ });
163
+
164
+ it('does not undo beyond initial state', () => {
165
+ const rootReducer = reducer();
166
+ const marks = [{ id: 1, type: 'point' }];
167
+
168
+ let state = rootReducer(undefined, { type: '@@INIT' });
169
+ state = rootReducer(state, changeMarks(marks));
170
+
171
+ state = rootReducer(state, { type: '@@redux-undo/UNDO' });
172
+ state = rootReducer(state, { type: '@@redux-undo/UNDO' });
173
+ state = rootReducer(state, { type: '@@redux-undo/UNDO' });
174
+
175
+ expect(state.marks.present).toEqual([]);
176
+ expect(state.marks.past).toEqual([]);
177
+ });
178
+ });
179
+
180
+ describe('redo functionality', () => {
181
+ it('supports redo action', () => {
182
+ const rootReducer = reducer();
183
+ const firstMarks = [{ id: 1, type: 'point' }];
184
+ const secondMarks = [{ id: 2, type: 'line' }];
185
+
186
+ let state = rootReducer(undefined, { type: '@@INIT' });
187
+ state = rootReducer(state, changeMarks(firstMarks));
188
+ state = rootReducer(state, changeMarks(secondMarks));
189
+ state = rootReducer(state, { type: '@@redux-undo/UNDO' });
190
+
191
+ // Redo
192
+ state = rootReducer(state, { type: '@@redux-undo/REDO' });
193
+
194
+ expect(state.marks.present).toEqual(secondMarks);
195
+ });
196
+
197
+ it('moves future to past on redo', () => {
198
+ const rootReducer = reducer();
199
+ const firstMarks = [{ id: 1, type: 'point' }];
200
+ const secondMarks = [{ id: 2, type: 'line' }];
201
+
202
+ let state = rootReducer(undefined, { type: '@@INIT' });
203
+ state = rootReducer(state, changeMarks(firstMarks));
204
+ state = rootReducer(state, changeMarks(secondMarks));
205
+ state = rootReducer(state, { type: '@@redux-undo/UNDO' });
206
+
207
+ const futureBeforeRedo = state.marks.future.length;
208
+ state = rootReducer(state, { type: '@@redux-undo/REDO' });
209
+
210
+ expect(state.marks.future.length).toBe(futureBeforeRedo - 1);
211
+ });
212
+
213
+ it('handles multiple redos', () => {
214
+ const rootReducer = reducer();
215
+ const marks1 = [{ id: 1 }];
216
+ const marks2 = [{ id: 2 }];
217
+ const marks3 = [{ id: 3 }];
218
+
219
+ let state = rootReducer(undefined, { type: '@@INIT' });
220
+ state = rootReducer(state, changeMarks(marks1));
221
+ state = rootReducer(state, changeMarks(marks2));
222
+ state = rootReducer(state, changeMarks(marks3));
223
+
224
+ // undo twice, then redo twice
225
+ state = rootReducer(state, { type: '@@redux-undo/UNDO' });
226
+ state = rootReducer(state, { type: '@@redux-undo/UNDO' });
227
+ state = rootReducer(state, { type: '@@redux-undo/REDO' });
228
+ state = rootReducer(state, { type: '@@redux-undo/REDO' });
229
+
230
+ expect(state.marks.present).toEqual(marks3);
231
+ });
232
+
233
+ it('does not redo beyond last state', () => {
234
+ const rootReducer = reducer();
235
+ const marks = [{ id: 1, type: 'point' }];
236
+
237
+ let state = rootReducer(undefined, { type: '@@INIT' });
238
+ state = rootReducer(state, changeMarks(marks));
239
+ state = rootReducer(state, { type: '@@redux-undo/UNDO' });
240
+ state = rootReducer(state, { type: '@@redux-undo/REDO' });
241
+
242
+ // try to redo beyond the end
243
+ state = rootReducer(state, { type: '@@redux-undo/REDO' });
244
+ state = rootReducer(state, { type: '@@redux-undo/REDO' });
245
+
246
+ expect(state.marks.present).toEqual(marks);
247
+ expect(state.marks.future).toEqual([]);
248
+ });
249
+ });
250
+
251
+ describe('state structure', () => {
252
+ it('maintains correct undoable structure', () => {
253
+ const rootReducer = reducer();
254
+ const state = rootReducer(undefined, { type: 'INIT' });
255
+
256
+ expect(state.marks).toHaveProperty('past');
257
+ expect(state.marks).toHaveProperty('present');
258
+ expect(state.marks).toHaveProperty('future');
259
+ expect(Array.isArray(state.marks.past)).toBe(true);
260
+ expect(Array.isArray(state.marks.future)).toBe(true);
261
+ });
262
+
263
+ it('preserves mark properties through undo/redo', () => {
264
+ const rootReducer = reducer();
265
+ const marks = [
266
+ {
267
+ id: 1,
268
+ type: 'point',
269
+ x: 10,
270
+ y: 20,
271
+ label: 'A',
272
+ correctness: { value: 'correct' },
273
+ },
274
+ ];
275
+
276
+ let state = rootReducer(undefined, { type: 'INIT' });
277
+ state = rootReducer(state, changeMarks(marks));
278
+ state = rootReducer(state, changeMarks([]));
279
+ state = rootReducer(state, { type: '@@redux-undo/UNDO' });
280
+
281
+ expect(state.marks.present).toEqual(marks);
282
+ expect(state.marks.present[0]).toBeDefined();
283
+ if (state.marks.present[0]) {
284
+ expect(state.marks.present[0]).toEqual(marks[0]);
285
+ expect(state.marks.present[0].correctness).toBeDefined();
286
+ }
287
+ });
288
+ });
289
+
290
+ describe('integration', () => {
291
+ it('handles complex undo/redo sequences', () => {
292
+ const rootReducer = reducer();
293
+ const marks1 = [{ id: 1 }];
294
+ const marks2 = [{ id: 2 }];
295
+ const marks3 = [{ id: 3 }];
296
+ const marks4 = [{ id: 4 }];
297
+
298
+ let state = rootReducer(undefined, { type: '@@INIT' });
299
+ state = rootReducer(state, changeMarks(marks1));
300
+ state = rootReducer(state, changeMarks(marks2));
301
+ state = rootReducer(state, changeMarks(marks3));
302
+ state = rootReducer(state, { type: '@@redux-undo/UNDO' }); // back to marks2
303
+ state = rootReducer(state, { type: '@@redux-undo/UNDO' }); // back to marks1
304
+ state = rootReducer(state, { type: '@@redux-undo/REDO' }); // forward to marks2
305
+ state = rootReducer(state, changeMarks(marks4));
306
+
307
+ expect(state.marks.present).toEqual(marks4);
308
+ expect(state.marks.future).toEqual([]);
309
+ });
310
+
311
+ it('works with empty state transitions', () => {
312
+ const rootReducer = reducer();
313
+ const marks = [{ id: 1 }];
314
+
315
+ let state = rootReducer(undefined, { type: '@@INIT' });
316
+ state = rootReducer(state, changeMarks([]));
317
+ state = rootReducer(state, changeMarks(marks));
318
+ state = rootReducer(state, changeMarks([]));
319
+ state = rootReducer(state, { type: '@@redux-undo/UNDO' });
320
+
321
+ expect(state.marks.present).toEqual(marks);
322
+ });
323
+ });
324
+ });
@@ -1,11 +1,10 @@
1
- import { connect } from 'react-redux';
1
+ import { connect, Provider } from 'react-redux';
2
2
  import React from 'react';
3
- import { Provider } from 'react-redux';
4
3
  import { applyMiddleware, createStore } from 'redux';
5
4
  import reducer from './reducer';
6
5
  import { changeMarks } from './actions';
7
6
  import PropTypes from 'prop-types';
8
- import isEqual from 'lodash/isEqual';
7
+ import { isEqual } from 'lodash-es';
9
8
  import { ActionCreators } from 'redux-undo';
10
9
  import GraphWithControls from '../graph-with-controls';
11
10
  import { lastActionMiddleware } from './middleware';
@@ -51,13 +51,7 @@ export const CoordinatesLabel = ({ x, y, graphProps }) => {
51
51
  ...labelPosition,
52
52
  };
53
53
 
54
- return (
55
- <StyledInputBase
56
- style={style}
57
- value={label}
58
- inputProps={{ ariaLabel: 'naked' }}
59
- />
60
- );
54
+ return <StyledInputBase style={style} value={label} inputProps={{ ariaLabel: 'naked' }} />;
61
55
  };
62
56
 
63
57
  CoordinatesLabel.propTypes = {
@@ -1,8 +1,7 @@
1
1
  import React from 'react';
2
2
  import PropTypes from 'prop-types';
3
3
  import { styled } from '@mui/material/styles';
4
- import uniq from 'lodash/uniq';
5
- import isString from 'lodash/isString';
4
+ import { isString, uniq } from 'lodash-es';
6
5
  import { color } from '@pie-lib/render-ui';
7
6
 
8
7
  import ToolMenu from './tool-menu';
@@ -66,7 +65,12 @@ export const filterByVisibleToolTypes = (toolbarTools, marks) =>
66
65
  const getDefaultCurrentTool = (toolType) => toolsArr.find((tool) => tool.type === toolType) || null;
67
66
 
68
67
  const Collapsible = ({ children, title }) => (
69
- <StyledAccordion elevation={0} disableGutters={true} square={true} TransitionProps={{ timeout: { enter: 225, exit: 195 } }}>
68
+ <StyledAccordion
69
+ elevation={0}
70
+ disableGutters={true}
71
+ square={true}
72
+ TransitionProps={{ timeout: { enter: 225, exit: 195 } }}
73
+ >
70
74
  <StyledAccordionSummary expandIcon={<ExpandMoreIcon />}>
71
75
  <Typography variant="subheading">{title}</Typography>
72
76
  </StyledAccordionSummary>
@@ -193,9 +197,7 @@ export class GraphWithControls extends React.Component {
193
197
  <StyledGraphContainer className={className}>
194
198
  <StyledControls>
195
199
  {collapsibleToolbar ? (
196
- <Collapsible title={collapsibleToolbarTitle}>
197
- {graphActions}
198
- </Collapsible>
200
+ <Collapsible title={collapsibleToolbarTitle}>{graphActions}</Collapsible>
199
201
  ) : (
200
202
  graphActions
201
203
  )}
package/src/graph.jsx CHANGED
@@ -1,8 +1,7 @@
1
1
  import React from 'react';
2
2
  import PropTypes from 'prop-types';
3
- import isEqual from 'lodash/isEqual';
4
- import cloneDeep from 'lodash/cloneDeep';
5
- import { Root, types, createGraphProps } from '@pie-lib/plot';
3
+ import { cloneDeep, isEqual } from 'lodash-es';
4
+ import { createGraphProps, Root, types } from '@pie-lib/plot';
6
5
  import debug from 'debug';
7
6
 
8
7
  import { Axes, AxisPropTypes } from './axis';
@@ -1,7 +1,7 @@
1
1
  import React from 'react';
2
2
  import PropTypes from 'prop-types';
3
3
  import { color, InputContainer } from '@pie-lib/render-ui';
4
- import { Accordion, AccordionSummary, AccordionDetails, Typography } from '@mui/material';
4
+ import { Accordion, AccordionDetails, AccordionSummary, Typography } from '@mui/material';
5
5
  import ExpandMoreIcon from '@mui/icons-material/ExpandMore';
6
6
  import { NumberTextFieldCustom, Toggle } from '@pie-lib/config-ui';
7
7
  import EditableHTML from '@pie-lib/editable-html-tip-tap';
@@ -110,7 +110,8 @@ const KeyLegend = ({ className, isLabelAvailable }) => {
110
110
  <path
111
111
  d="M12.1953 4.46875C12.3125 4.35156 12.5 4.35156 12.5938 4.46875L13.2734 5.125C13.3672 5.24219 13.3672 5.42969 13.2734 5.52344L6.24219 12.5547C6.125 12.6719 5.96094 12.6719 5.84375 12.5547L2.70312 9.4375C2.60938 9.32031 2.60938 9.13281 2.70312 9.03906L3.38281 8.35938C3.47656 8.26562 3.66406 8.26562 3.78125 8.35938L6.03125 10.6328L12.1953 4.46875Z"
112
112
  fill="white"
113
- /> </svg>
113
+ />{' '}
114
+ </svg>
114
115
  </StyledRow>
115
116
  {isLabelAvailable && (
116
117
  <StyledRow>
@@ -1,4 +1,4 @@
1
- import React, { useState, useCallback, useEffect } from 'react';
1
+ import React, { useCallback, useEffect, useState } from 'react';
2
2
  import PropTypes from 'prop-types';
3
3
  import { styled, useTheme } from '@mui/material/styles';
4
4
  import AutosizeInput from 'react-input-autosize';
@@ -53,9 +53,9 @@ const getInputStyles = (theme, disabled, markDisabled) => ({
53
53
  padding: theme.spacing(0.5),
54
54
  fontFamily: theme.typography.fontFamily,
55
55
  fontSize: '10px',
56
- border: disabled
56
+ border: disabled
57
57
  ? `solid 1px ${color.defaults.PRIMARY_DARK}`
58
- : markDisabled
58
+ : markDisabled
59
59
  ? `solid 1px ${color.disabled()}`
60
60
  : `solid 1px ${color.defaults.SECONDARY}`,
61
61
  borderRadius: '3px',
@@ -208,37 +208,20 @@ export const MarkLabel = (props) => {
208
208
  renderInput(studentInputStyle, label)
209
209
  )}
210
210
  </StyledInputIncorrect>
211
- <StyledInputMissing style={secondLabelStyle}>
212
- {renderInput(studentInputStyle, correctlabel)}
213
- </StyledInputMissing>
211
+ <StyledInputMissing style={secondLabelStyle}>{renderInput(studentInputStyle, correctlabel)}</StyledInputMissing>
214
212
  </>
215
213
  );
216
214
  }
217
215
 
218
216
  if (correctness === 'missing') {
219
- return (
220
- <StyledInputMissing style={style}>
221
- {renderInput(studentInputStyle, label)}
222
- </StyledInputMissing>
223
- );
217
+ return <StyledInputMissing style={style}>{renderInput(studentInputStyle, label)}</StyledInputMissing>;
224
218
  }
225
219
 
226
220
  if (correctness === 'incorrect') {
227
- return (
228
- <StyledIncorrect style={style}>
229
- {renderInput(studentInputStyle, label)}
230
- </StyledIncorrect>
231
- );
221
+ return <StyledIncorrect style={style}>{renderInput(studentInputStyle, label)}</StyledIncorrect>;
232
222
  }
233
223
 
234
- return (
235
- <div style={style}>
236
- {renderInput(
237
- getInputStyles(theme, disabled, mark.disabled),
238
- label,
239
- )}
240
- </div>
241
- );
224
+ return <div style={style}>{renderInput(getInputStyles(theme, disabled, mark.disabled), label)}</div>;
242
225
  };
243
226
 
244
227
  MarkLabel.propTypes = {
@@ -158,7 +158,14 @@ export class ToggleBar extends React.Component {
158
158
 
159
159
  // DragTool functional component using @dnd-kit hooks
160
160
  function DragTool({ children, index, draggable, toolRef, value }) {
161
- const { attributes, listeners, setNodeRef: setDragNodeRef, transform, transition, isDragging } = useDraggable({
161
+ const {
162
+ attributes,
163
+ listeners,
164
+ setNodeRef: setDragNodeRef,
165
+ transform,
166
+ transition,
167
+ isDragging,
168
+ } = useDraggable({
162
169
  id: `tool-${value}-${index}`,
163
170
  disabled: !draggable,
164
171
  data: {
@@ -1,6 +1,5 @@
1
- import React from 'react';
2
1
  import { withRootEdge } from '../../shared/line/with-root-edge';
3
- import { buildDataPoints, absoluteFromTwoPoints } from '@pie-lib/graphing-utils';
2
+ import { absoluteFromTwoPoints, buildDataPoints } from '@pie-lib/graphing-utils';
4
3
  import { utils } from '@pie-lib/plot';
5
4
 
6
5
  import { graphProps as getGraphProps } from '../../../__tests__/utils';
@@ -1,6 +1,6 @@
1
1
  import debug from 'debug';
2
- import { buildDataPoints, absoluteFromTwoPoints } from '@pie-lib/graphing-utils';
3
- import { withRootEdge, rootEdgeComponent } from '../shared/line/with-root-edge';
2
+ import { absoluteFromTwoPoints, buildDataPoints } from '@pie-lib/graphing-utils';
3
+ import { rootEdgeComponent, withRootEdge } from '../shared/line/with-root-edge';
4
4
 
5
5
  const log = debug('pie-lib:graphing:absolute');
6
6