@pie-element/drawing-response 10.3.4-next.3 → 11.0.0-beta.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 (83) hide show
  1. package/configure/lib/button.js +23 -47
  2. package/configure/lib/button.js.map +1 -1
  3. package/configure/lib/defaults.js +2 -3
  4. package/configure/lib/defaults.js.map +1 -1
  5. package/configure/lib/image-container.js +238 -327
  6. package/configure/lib/image-container.js.map +1 -1
  7. package/configure/lib/index.js +115 -182
  8. package/configure/lib/index.js.map +1 -1
  9. package/configure/lib/root.js +194 -260
  10. package/configure/lib/root.js.map +1 -1
  11. package/configure/package.json +9 -7
  12. package/configure/src/__tests__/image-container.test.jsx +101 -37
  13. package/configure/src/__tests__/index.test.js +27 -5
  14. package/configure/src/__tests__/root.test.jsx +37 -21
  15. package/configure/src/button.jsx +14 -24
  16. package/configure/src/image-container.jsx +73 -77
  17. package/configure/src/index.js +12 -2
  18. package/configure/src/root.jsx +24 -25
  19. package/controller/lib/defaults.js +2 -3
  20. package/controller/lib/defaults.js.map +1 -1
  21. package/controller/lib/index.js +39 -65
  22. package/controller/lib/index.js.map +1 -1
  23. package/controller/package.json +1 -1
  24. package/lib/drawing-response/button.js +35 -60
  25. package/lib/drawing-response/button.js.map +1 -1
  26. package/lib/drawing-response/constants.js +2 -3
  27. package/lib/drawing-response/constants.js.map +1 -1
  28. package/lib/drawing-response/container.js +270 -351
  29. package/lib/drawing-response/container.js.map +1 -1
  30. package/lib/drawing-response/drawable-circle.js +65 -104
  31. package/lib/drawing-response/drawable-circle.js.map +1 -1
  32. package/lib/drawing-response/drawable-eraser.js +50 -86
  33. package/lib/drawing-response/drawable-eraser.js.map +1 -1
  34. package/lib/drawing-response/drawable-free-path.js +56 -97
  35. package/lib/drawing-response/drawable-free-path.js.map +1 -1
  36. package/lib/drawing-response/drawable-helper.js +16 -28
  37. package/lib/drawing-response/drawable-helper.js.map +1 -1
  38. package/lib/drawing-response/drawable-image.js +30 -49
  39. package/lib/drawing-response/drawable-image.js.map +1 -1
  40. package/lib/drawing-response/drawable-line.js +60 -99
  41. package/lib/drawing-response/drawable-line.js.map +1 -1
  42. package/lib/drawing-response/drawable-main.js +273 -345
  43. package/lib/drawing-response/drawable-main.js.map +1 -1
  44. package/lib/drawing-response/drawable-palette.js +123 -166
  45. package/lib/drawing-response/drawable-palette.js.map +1 -1
  46. package/lib/drawing-response/drawable-rectangle.js +65 -104
  47. package/lib/drawing-response/drawable-rectangle.js.map +1 -1
  48. package/lib/drawing-response/drawable-text.js +201 -313
  49. package/lib/drawing-response/drawable-text.js.map +1 -1
  50. package/lib/drawing-response/drawable-transformer.js +36 -79
  51. package/lib/drawing-response/drawable-transformer.js.map +1 -1
  52. package/lib/drawing-response/factory.js +6 -19
  53. package/lib/drawing-response/factory.js.map +1 -1
  54. package/lib/drawing-response/icon.js +8 -24
  55. package/lib/drawing-response/icon.js.map +1 -1
  56. package/lib/drawing-response/index.js +74 -116
  57. package/lib/drawing-response/index.js.map +1 -1
  58. package/lib/index.js +51 -102
  59. package/lib/index.js.map +1 -1
  60. package/package.json +13 -12
  61. package/src/__tests__/drawing-index-test.jsx +90 -27
  62. package/src/drawing-response/__tests__/container.test.jsx +56 -36
  63. package/src/drawing-response/__tests__/drawing-main.test.jsx +158 -139
  64. package/src/drawing-response/button.jsx +23 -34
  65. package/src/drawing-response/container.jsx +39 -40
  66. package/src/drawing-response/drawable-image.jsx +17 -20
  67. package/src/drawing-response/drawable-main.jsx +67 -60
  68. package/src/drawing-response/drawable-palette.jsx +48 -54
  69. package/src/drawing-response/drawable-text.jsx +26 -38
  70. package/src/drawing-response/index.jsx +21 -20
  71. package/src/index.js +17 -2
  72. package/configure/src/__tests__/__snapshots__/image-container.test.jsx.snap +0 -45
  73. package/configure/src/__tests__/__snapshots__/root.test.jsx.snap +0 -185
  74. package/esm/configure.js +0 -16151
  75. package/esm/configure.js.map +0 -1
  76. package/esm/controller.js +0 -814
  77. package/esm/controller.js.map +0 -1
  78. package/esm/element.js +0 -54130
  79. package/esm/element.js.map +0 -1
  80. package/esm/package.json +0 -3
  81. package/src/__tests__/__snapshots__/drawing-index-test.jsx.snap +0 -23
  82. package/src/drawing-response/__tests__/__snapshots__/container.test.jsx.snap +0 -396
  83. package/src/drawing-response/__tests__/__snapshots__/drawing-main.test.jsx.snap +0 -247
@@ -1,5 +1,6 @@
1
1
  import React from 'react';
2
- import { shallow } from 'enzyme';
2
+ import { render } from '@testing-library/react';
3
+ import { ThemeProvider, createTheme } from '@mui/material/styles';
3
4
  import cloneDeep from 'lodash/cloneDeep';
4
5
  import FreePathDrawable from '../drawable-free-path';
5
6
  import LineDrawable from '../drawable-line';
@@ -9,6 +10,24 @@ import EraserDrawable from '../drawable-eraser';
9
10
  import DrawableText from '../drawable-text';
10
11
  import { DrawableMain } from '../drawable-main';
11
12
 
13
+ jest.mock('react-konva', () => ({
14
+ Stage: (props) => <div data-testid="konva-stage" {...props}>{props.children}</div>,
15
+ Layer: (props) => <div data-testid="konva-layer" {...props}>{props.children}</div>,
16
+ Circle: (props) => <circle data-testid="konva-circle" {...props} />,
17
+ Line: (props) => <line data-testid="konva-line" {...props} />,
18
+ Arrow: (props) => <line data-testid="konva-arrow" {...props} />,
19
+ Rect: (props) => <rect data-testid="konva-rect" {...props} />,
20
+ Group: (props) => <g data-testid="konva-group" {...props}>{props.children}</g>,
21
+ Text: (props) => <text data-testid="konva-text" {...props}>{props.children}</text>,
22
+ Transformer: (props) => <g data-testid="konva-transformer" {...props} />,
23
+ }));
24
+
25
+ jest.mock('../drawable-transformer', () => {
26
+ return (props) => <g data-testid="drawable-transformer" {...props} />;
27
+ });
28
+
29
+ const theme = createTheme();
30
+
12
31
  const drawableClasses = {
13
32
  FreePathDrawable,
14
33
  LineDrawable,
@@ -20,27 +39,17 @@ const drawableClasses = {
20
39
 
21
40
  describe('DrawingResponse', () => {
22
41
  let element;
23
- let wrapper;
24
-
25
- const mkWrapper = (type, props, WrapperEl) => {
26
- element = new drawableClasses[type](props);
27
-
28
- let content = element.render(props);
29
-
30
- if (WrapperEl) {
31
- content = <WrapperEl>{content}</WrapperEl>;
32
- }
33
-
34
- return shallow(content);
35
- };
36
42
 
37
43
  describe('DrawableMain', () => {
38
44
  let onSessionChange = jest.fn();
39
45
  const TextEntry = new DrawableText();
40
46
 
41
- const wrapperMain = (extras, renderOpts) => {
42
- const defaults = {
43
- classes: {},
47
+ beforeEach(() => {
48
+ jest.clearAllMocks();
49
+ });
50
+
51
+ const renderDrawableMain = (props = {}) => {
52
+ const defaultProps = {
44
53
  disabled: false,
45
54
  className: 'className',
46
55
  onSessionChange,
@@ -53,25 +62,15 @@ describe('DrawingResponse', () => {
53
62
  session: {},
54
63
  toolActive: { type: 'Select', label: 'Select', icon: 'mdiCursorDefault' },
55
64
  TextEntry,
65
+ ...props,
56
66
  };
57
- const props = { ...defaults, ...extras };
58
- return shallow(<DrawableMain {...props} />, {
59
- ...renderOpts,
60
- });
67
+ return render(
68
+ <ThemeProvider theme={theme}>
69
+ <DrawableMain {...defaultProps} />
70
+ </ThemeProvider>
71
+ );
61
72
  };
62
73
 
63
- describe('snapshot', () => {
64
- it('renders', () => {
65
- const w = wrapperMain();
66
- expect(w).toMatchSnapshot();
67
- });
68
-
69
- it('renders disabled', () => {
70
- const w = wrapperMain({ disabled: true });
71
- expect(w).toMatchSnapshot();
72
- });
73
- });
74
-
75
74
  describe('logic', () => {
76
75
  const handleSessionChange = jest.fn();
77
76
  const forceUpdate = jest.fn();
@@ -87,26 +86,80 @@ describe('DrawingResponse', () => {
87
86
  createdAt: new Date(),
88
87
  };
89
88
 
90
- it('handleUndo', () => {
91
- const w = wrapperMain();
89
+ it('handleUndo removes the last drawable', () => {
90
+ const testInstance = new DrawableMain({
91
+ onSessionChange,
92
+ imageDimensions: {},
93
+ imageUrl: 'url',
94
+ drawableDimensions: { height: 350, width: 353 },
95
+ fillColor: 'white',
96
+ outlineColor: 'black',
97
+ paintColor: 'red',
98
+ session: {},
99
+ toolActive: { type: 'Select', label: 'Select', icon: 'mdiCursorDefault' },
100
+ TextEntry,
101
+ });
102
+
103
+ const drawable1 = new RectangleDrawable(props);
104
+ const drawable2 = new RectangleDrawable(props);
105
+
106
+ // Set initial state
107
+ testInstance.state = { drawables: [drawable1, drawable2], newDrawable: [], textIsSelected: false };
108
+
109
+ // Spy on setState
110
+ const setStateSpy = jest.spyOn(testInstance, 'setState');
92
111
 
93
- w.setState({ drawables: [new RectangleDrawable(props), new RectangleDrawable(props)] });
94
- w.instance().handleUndo();
112
+ // First undo - should remove drawable2
113
+ testInstance.handleUndo();
95
114
 
96
- expect(w.state('drawables').length).toEqual(1);
115
+ expect(setStateSpy).toHaveBeenCalledWith(
116
+ { drawables: [drawable1] },
117
+ testInstance.handleSessionChange
118
+ );
97
119
 
98
- w.instance().handleUndo();
120
+ // Update state to reflect what would have happened
121
+ testInstance.state.drawables = [drawable1];
122
+ setStateSpy.mockClear();
99
123
 
100
- expect(w.state('drawables')).toEqual([]);
124
+ // Second undo - should remove drawable1
125
+ testInstance.handleUndo();
126
+
127
+ expect(setStateSpy).toHaveBeenCalledWith(
128
+ { drawables: [] },
129
+ testInstance.handleSessionChange
130
+ );
101
131
  });
102
132
 
103
- it('handleClearAll', () => {
104
- const w = wrapperMain();
133
+ it('handleClearAll removes all drawables', () => {
134
+ const testInstance = new DrawableMain({
135
+ onSessionChange,
136
+ imageDimensions: {},
137
+ imageUrl: 'url',
138
+ drawableDimensions: { height: 350, width: 353 },
139
+ fillColor: 'white',
140
+ outlineColor: 'black',
141
+ paintColor: 'red',
142
+ session: {},
143
+ toolActive: { type: 'Select', label: 'Select', icon: 'mdiCursorDefault' },
144
+ TextEntry,
145
+ });
146
+
147
+ const drawable1 = new RectangleDrawable(props);
148
+ const drawable2 = new RectangleDrawable(props);
149
+
150
+ // Set initial state
151
+ testInstance.state = { drawables: [drawable1, drawable2], newDrawable: [], textIsSelected: false };
152
+
153
+ // Spy on setState
154
+ const setStateSpy = jest.spyOn(testInstance, 'setState');
105
155
 
106
- w.setState({ drawables: [new RectangleDrawable(props), new RectangleDrawable(props)] });
107
- w.instance().handleClearAll();
156
+ testInstance.handleClearAll();
108
157
 
109
- expect(w.state('drawables')).toEqual([]);
158
+ expect(setStateSpy).toHaveBeenCalledWith(
159
+ { drawables: [], updatedAt: expect.any(Date) },
160
+ testInstance.handleSessionChange
161
+ );
162
+ expect(TextEntry.all).toEqual([]);
110
163
  });
111
164
  });
112
165
  });
@@ -128,21 +181,10 @@ describe('DrawingResponse', () => {
128
181
  y: 200,
129
182
  createdAt: new Date(),
130
183
  };
131
- wrapper = mkWrapper('CircleDrawable', props);
132
- });
133
-
134
- describe('snapshot', () => {
135
- it('renders', () => {
136
- expect(wrapper).toMatchSnapshot();
137
- });
184
+ element = new CircleDrawable(props);
138
185
  });
139
186
 
140
187
  describe('logic', () => {
141
- it('calls forceUpdate', () => {
142
- wrapper.simulate('click');
143
- expect(forceUpdate).toHaveBeenCalled();
144
- });
145
-
146
188
  it('changes x and y', () => {
147
189
  element.registerMovement(400, 400);
148
190
 
@@ -200,13 +242,7 @@ describe('DrawingResponse', () => {
200
242
  starty: 200,
201
243
  createdAt: new Date(),
202
244
  };
203
- wrapper = mkWrapper('EraserDrawable', props);
204
- });
205
-
206
- describe('snapshot', () => {
207
- it('renders', () => {
208
- expect(wrapper).toMatchSnapshot();
209
- });
245
+ element = new EraserDrawable(props);
210
246
  });
211
247
 
212
248
  describe('logic', () => {
@@ -266,21 +302,10 @@ describe('DrawingResponse', () => {
266
302
  starty: 200,
267
303
  createdAt: new Date(),
268
304
  };
269
- wrapper = mkWrapper('FreePathDrawable', props);
270
- });
271
-
272
- describe('snapshot', () => {
273
- it('renders', () => {
274
- expect(wrapper).toMatchSnapshot();
275
- });
305
+ element = new FreePathDrawable(props);
276
306
  });
277
307
 
278
308
  describe('logic', () => {
279
- it('calls forceUpdate', () => {
280
- wrapper.simulate('click');
281
- expect(forceUpdate).toHaveBeenCalled();
282
- });
283
-
284
309
  it('changes points', () => {
285
310
  element.registerMovement(400, 400);
286
311
 
@@ -288,8 +313,6 @@ describe('DrawingResponse', () => {
288
313
  });
289
314
 
290
315
  it('changes session when needed', () => {
291
- const spy = jest.spyOn(element, 'handleDragEnd');
292
-
293
316
  const event = {
294
317
  target: {
295
318
  getX: jest.fn().mockReturnValue(300),
@@ -340,21 +363,10 @@ describe('DrawingResponse', () => {
340
363
  y: 200,
341
364
  createdAt: new Date(),
342
365
  };
343
- wrapper = mkWrapper('LineDrawable', props);
344
- });
345
-
346
- describe('snapshot', () => {
347
- it('renders', () => {
348
- expect(wrapper).toMatchSnapshot();
349
- });
366
+ element = new LineDrawable(props);
350
367
  });
351
368
 
352
369
  describe('logic', () => {
353
- it('calls forceUpdate', () => {
354
- wrapper.simulate('click');
355
- expect(forceUpdate).toHaveBeenCalled();
356
- });
357
-
358
370
  it('changes x and y', () => {
359
371
  element.registerMovement(400, 400);
360
372
 
@@ -411,21 +423,10 @@ describe('DrawingResponse', () => {
411
423
  y: 300,
412
424
  createdAt: new Date(),
413
425
  };
414
- wrapper = mkWrapper('RectangleDrawable', props);
415
- });
416
-
417
- describe('snapshot', () => {
418
- it('renders', () => {
419
- expect(wrapper).toMatchSnapshot();
420
- });
426
+ element = new RectangleDrawable(props);
421
427
  });
422
428
 
423
429
  describe('logic', () => {
424
- it('calls forceUpdate', () => {
425
- wrapper.simulate('click');
426
- expect(forceUpdate).toHaveBeenCalled();
427
- });
428
-
429
430
  it('changes x and y', () => {
430
431
  element.registerMovement(400, 400);
431
432
 
@@ -510,37 +511,26 @@ describe('DrawingResponse', () => {
510
511
  y: 300,
511
512
  scale: 1,
512
513
  };
513
- wrapper = mkWrapper('DrawableText', props, 'div');
514
- });
515
-
516
- describe('snapshot', () => {
517
- it('renders', () => {
518
- expect(wrapper).toMatchSnapshot();
519
- });
520
-
521
- it('renders textAreas', () => {
522
- element = new drawableClasses['DrawableText'](props);
523
-
524
- wrapper = shallow(<div>{element.renderTextareas()}</div>);
525
-
526
- expect(wrapper).toMatchSnapshot();
527
- });
514
+ element = new DrawableText(props);
528
515
  });
529
516
 
530
- describe('snapshot when there is no value', () => {
517
+ describe('when there is no value', () => {
531
518
  beforeEach(() => {
532
519
  props.all.forEach((a) => {
533
520
  delete a.value;
534
521
  });
535
- wrapper = mkWrapper('DrawableText', props, 'div');
522
+ element = new DrawableText(props);
536
523
  });
537
- it('renders', () => {
538
- expect(wrapper).toMatchSnapshot();
524
+ it('renders without crashing', () => {
525
+ const content = element.render(props);
526
+ const { container } = render(<div>{content}</div>);
527
+ expect(container).toBeInTheDocument();
539
528
  });
540
529
  });
541
530
 
542
531
  describe('logic', () => {
543
532
  it('shoud change the all property and call forceUpdate', () => {
533
+ element.setInitialProps(props);
544
534
  element.setAll([]);
545
535
 
546
536
  expect(element.all).toEqual([]);
@@ -549,6 +539,7 @@ describe('DrawingResponse', () => {
549
539
 
550
540
  describe('addNewTextEntry', () => {
551
541
  it('shoud add a new element and call the appropriate functions', () => {
542
+ element.setInitialProps(props);
552
543
  element.addNewTextEntry();
553
544
 
554
545
  expect(element.all.length).toEqual(2);
@@ -566,7 +557,6 @@ describe('DrawingResponse', () => {
566
557
  ]),
567
558
  );
568
559
 
569
- expect(stage.on).toHaveBeenCalled();
570
560
  expect(handleSessionChange).toHaveBeenCalled();
571
561
  });
572
562
  });
@@ -589,6 +579,7 @@ describe('DrawingResponse', () => {
589
579
 
590
580
  describe('showOnltoggleTextareayTextNodes', () => {
591
581
  it('should change the item with the right id in the "all" array and call forceUpdate', () => {
582
+ element.setInitialProps(props);
592
583
  element.toggleTextarea('gcifqhhimf8k2d6g8hs', true);
593
584
 
594
585
  expect(element.all[0]).toEqual(
@@ -628,22 +619,25 @@ describe('DrawingResponse', () => {
628
619
  });
629
620
 
630
621
  describe('saveValue', () => {
631
- it('should make the item with the right id default and call handleSessionChange', () => {
632
- const textNode = {
633
- text: jest.fn(),
634
- };
622
+ it('should save the value and call handleSessionChange', () => {
623
+ element.setInitialProps(props);
635
624
  const textareaNode = {
636
625
  value: 'Foo bar',
637
626
  };
638
627
 
639
- element.saveValue('gcifqhhimf8k2d6g8hs', textNode, textareaNode);
628
+ element.saveValue('gcifqhhimf8k2d6g8hs', textareaNode);
640
629
 
641
- expect(textNode.text).toHaveBeenCalledWith('Foo bar');
630
+ expect(element.all[0].text).toEqual('Foo bar');
642
631
  expect(handleSessionChange).toHaveBeenCalled();
632
+ expect(forceUpdate).toHaveBeenCalled();
643
633
 
644
- textareaNode.value = '';
634
+ // Reset mock
635
+ handleSessionChange.mockClear();
636
+ forceUpdate.mockClear();
645
637
 
646
- element.saveValue('gcifqhhimf8k2d6g8hs', textNode, textareaNode);
638
+ // Test with empty value - should remove the item
639
+ textareaNode.value = '';
640
+ element.saveValue('gcifqhhimf8k2d6g8hs', textareaNode);
647
641
 
648
642
  expect(element.all).toEqual(
649
643
  expect.not.arrayContaining([
@@ -659,6 +653,7 @@ describe('DrawingResponse', () => {
659
653
 
660
654
  describe('handleMouseEvents', () => {
661
655
  it('should call the right functions on mouse down and up', () => {
656
+ element.setInitialProps(props);
662
657
  element.handleMouseDown();
663
658
  expect(toggleTextSelected).toHaveBeenCalledWith(true);
664
659
 
@@ -667,6 +662,7 @@ describe('DrawingResponse', () => {
667
662
  });
668
663
 
669
664
  it('should call the right functions onClick', () => {
665
+ element.setInitialProps(props);
670
666
  element.handleClick(null, 'gcifqhhimf8k2d6g8hs');
671
667
 
672
668
  expect(element.all).toEqual(
@@ -681,9 +677,15 @@ describe('DrawingResponse', () => {
681
677
  });
682
678
 
683
679
  it('should call the right functions onDblClick', () => {
680
+ element.setInitialProps(props);
681
+
682
+ // Call render to set up stage reference
683
+ element.render(props);
684
+
684
685
  const text = {
685
686
  id: 'gcifqhhimf8k2d6g8hs',
686
687
  isDefault: false,
688
+ text: 'foo bar',
687
689
  };
688
690
 
689
691
  const textNode = (element[`text_${text.id}`] = {
@@ -701,6 +703,7 @@ describe('DrawingResponse', () => {
701
703
  rotation: jest.fn().mockReturnValue(0),
702
704
  text: jest.fn().mockReturnValue('foo bar'),
703
705
  width: jest.fn().mockReturnValue(200),
706
+ getAbsolutePosition: jest.fn().mockReturnValue({ x: 200, y: 200 }),
704
707
  });
705
708
  const textareaNode = (element[`textarea_${text.id}`] = {
706
709
  focus: jest.fn(),
@@ -718,13 +721,12 @@ describe('DrawingResponse', () => {
718
721
  expect(toggleSpy).toHaveBeenCalledWith(text.id, true);
719
722
 
720
723
  expect(textareaNode.value).toEqual('foo bar');
721
- expect(textareaNode.style).toEqual({
724
+ expect(textareaNode.style).toMatchObject({
722
725
  background: 'none',
723
726
  border: 'none',
724
727
  color: 'green',
725
728
  fontFamily: 'FooBarFamily',
726
729
  fontSize: '16px',
727
- height: '208px',
728
730
  left: '200px',
729
731
  lineHeight: '40px',
730
732
  margin: '0px',
@@ -736,7 +738,6 @@ describe('DrawingResponse', () => {
736
738
  top: '200px',
737
739
  transformOrigin: 'left top',
738
740
  textAlign: 'center',
739
- transform: 'translateY(-0px)',
740
741
  width: '200px',
741
742
  });
742
743
 
@@ -748,42 +749,60 @@ describe('DrawingResponse', () => {
748
749
  expect(textareaNode.addEventListener.mock.calls[1][0]).toEqual('blur');
749
750
 
750
751
  const event = {
751
- keyCode: 13,
752
+ key: 'Enter',
752
753
  shiftKey: true,
753
754
  };
754
755
 
756
+ // Clear spy to ignore the initial toggleTextarea(id, true) call from handleDblClick
757
+ toggleSpy.mockClear();
758
+ saveValueSpy.mockClear();
759
+
755
760
  textareaNode.addEventListener.mock.calls[0][1](event);
756
761
 
757
- // Make sure it's not called the second time
758
- expect(toggleSpy).toHaveBeenCalledTimes(1);
762
+ // Make sure toggleTextarea and saveValue are not called when shift+enter is pressed
763
+ expect(toggleSpy).not.toHaveBeenCalled();
759
764
  expect(saveValueSpy).not.toHaveBeenCalled();
760
765
 
761
766
  event.shiftKey = false;
762
767
 
763
768
  textareaNode.addEventListener.mock.calls[0][1](event);
764
769
 
770
+ // Enter without shift calls saveValue, which in turn calls toggleTextarea
771
+ expect(saveValueSpy).toHaveBeenCalledWith('gcifqhhimf8k2d6g8hs', textareaNode);
765
772
  expect(toggleSpy).toHaveBeenCalledWith('gcifqhhimf8k2d6g8hs', false);
766
- expect(saveValueSpy).toHaveBeenCalledWith('gcifqhhimf8k2d6g8hs', textNode, textareaNode);
767
773
 
768
- event.keyCode = 27;
774
+ // Clear spy before testing Escape key
775
+ toggleSpy.mockClear();
776
+ saveValueSpy.mockClear();
777
+
778
+ event.key = 'Escape';
769
779
 
770
780
  textareaNode.addEventListener.mock.calls[0][1](event);
771
781
 
782
+ // Escape only calls toggleTextarea, not saveValue
772
783
  expect(toggleSpy).toHaveBeenCalledWith('gcifqhhimf8k2d6g8hs', false);
784
+ expect(saveValueSpy).not.toHaveBeenCalled();
773
785
 
774
786
  const showTextSpy = jest.spyOn(element, 'showOnlyTextNodes');
775
787
 
788
+ // Clear spies before testing stage click handler
789
+ toggleSpy.mockClear();
790
+ saveValueSpy.mockClear();
791
+
776
792
  event.target = stage;
777
793
 
778
794
  stage.on.mock.calls[0][1](event);
779
795
 
796
+ // Stage click handler only calls showOnlyTextNodes and forceUpdate, not saveValue
780
797
  expect(showTextSpy).toHaveBeenCalled();
781
- expect(saveValueSpy).toHaveBeenCalledWith('gcifqhhimf8k2d6g8hs', textNode, textareaNode);
798
+ expect(forceUpdate).toHaveBeenCalled();
799
+ expect(saveValueSpy).not.toHaveBeenCalled();
782
800
  });
783
801
  });
784
802
 
785
803
  describe('handleTransform', () => {
786
804
  it('should change attrs when called', () => {
805
+ element.setInitialProps(props);
787
806
  const textNode = (element[`text_gcifqhhimf8k2d6g8hs`] = {
788
807
  setAttrs: jest.fn(),
789
808
  width: jest.fn().mockReturnValue(100),
@@ -1,56 +1,45 @@
1
1
  import React from 'react';
2
2
  import PropTypes from 'prop-types';
3
- import { withStyles } from '@material-ui/core/styles';
4
- import classNames from 'classnames';
5
- import Button from '@material-ui/core/Button';
3
+ import { styled } from '@mui/material/styles';
4
+ import Button from '@mui/material/Button';
6
5
 
7
- const RawButton = ({ classes, className, label, onClick, disabled, title }) => (
8
- <Button
6
+ const StyledButton = styled(Button)({
7
+ fontSize: '0.9em',
8
+ marginLeft: 8,
9
+ minWidth: 32,
10
+ height: 32,
11
+
12
+ '& span': {
13
+ '& svg': {
14
+ width: '1.3em !important',
15
+ height: '1.3em !important',
16
+ },
17
+ },
18
+ });
19
+
20
+ const CustomButton = ({ label, onClick, disabled, title }) => (
21
+ <StyledButton
9
22
  title={title}
10
23
  onClick={onClick}
11
24
  disabled={disabled}
12
- className={classNames(classes.addButton, className)}
13
25
  size="small"
14
- variant="contained"
15
- color="default"
16
- >
26
+ variant="contained">
17
27
  {label}
18
- </Button>
28
+ </StyledButton>
19
29
  );
20
30
 
21
- RawButton.propTypes = {
22
- classes: PropTypes.object.isRequired,
23
- className: PropTypes.string,
31
+ CustomButton.propTypes = {
24
32
  disabled: PropTypes.bool,
25
33
  label: PropTypes.oneOfType([PropTypes.string, PropTypes.object]),
26
34
  onClick: PropTypes.func,
27
35
  title: PropTypes.string,
28
36
  };
29
37
 
30
- RawButton.defaultProps = {
31
- className: '',
38
+ CustomButton.defaultProps = {
32
39
  disabled: false,
33
40
  label: 'Add',
34
41
  onClick: () => {},
35
42
  title: '',
36
43
  };
37
44
 
38
- const styles = () => ({
39
- addButton: {
40
- fontSize: '0.9em',
41
- marginLeft: 8,
42
- minWidth: 32,
43
- height: 32,
44
-
45
- '& span': {
46
- '& svg': {
47
- width: '1.3em !important',
48
- height: '1.3em !important',
49
- },
50
- },
51
- },
52
- });
53
-
54
- const ButtonStyled = withStyles(styles)(RawButton);
55
-
56
- export default ButtonStyled;
45
+ export default CustomButton;