@pie-lib/mask-markup 1.33.3-next.2 → 1.33.4-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 (72) hide show
  1. package/CHANGELOG.md +6 -76
  2. package/lib/__tests__/drag-in-the-blank.test.js +129 -0
  3. package/lib/__tests__/index.test.js +42 -0
  4. package/lib/__tests__/mask.test.js +163 -0
  5. package/lib/__tests__/serialization.test.js +44 -0
  6. package/lib/__tests__/utils.js +14 -0
  7. package/lib/__tests__/with-mask.test.js +110 -0
  8. package/lib/choices/__tests__/index.test.js +101 -0
  9. package/lib/choices/choice.js +99 -204
  10. package/lib/choices/choice.js.map +1 -1
  11. package/lib/choices/index.js +22 -54
  12. package/lib/choices/index.js.map +1 -1
  13. package/lib/componentize.js +2 -6
  14. package/lib/componentize.js.map +1 -1
  15. package/lib/components/__tests__/blank.test.js +189 -0
  16. package/lib/components/__tests__/correct-input.test.js +132 -0
  17. package/lib/components/__tests__/dropdown.test.js +134 -0
  18. package/lib/components/__tests__/input.test.js +129 -0
  19. package/lib/components/blank.js +304 -362
  20. package/lib/components/blank.js.map +1 -1
  21. package/lib/components/correct-input.js +42 -66
  22. package/lib/components/correct-input.js.map +1 -1
  23. package/lib/components/dropdown.js +219 -258
  24. package/lib/components/dropdown.js.map +1 -1
  25. package/lib/components/input.js +11 -18
  26. package/lib/components/input.js.map +1 -1
  27. package/lib/constructed-response.js +39 -53
  28. package/lib/constructed-response.js.map +1 -1
  29. package/lib/customizable.js +6 -10
  30. package/lib/customizable.js.map +1 -1
  31. package/lib/drag-in-the-blank.js +141 -106
  32. package/lib/drag-in-the-blank.js.map +1 -1
  33. package/lib/index.js +1 -8
  34. package/lib/index.js.map +1 -1
  35. package/lib/inline-dropdown.js +5 -13
  36. package/lib/inline-dropdown.js.map +1 -1
  37. package/lib/mask.js +61 -119
  38. package/lib/mask.js.map +1 -1
  39. package/lib/serialization.js +9 -49
  40. package/lib/serialization.js.map +1 -1
  41. package/lib/with-mask.js +31 -59
  42. package/lib/with-mask.js.map +1 -1
  43. package/package.json +12 -20
  44. package/src/__tests__/drag-in-the-blank.test.js +66 -26
  45. package/src/__tests__/mask.test.js +147 -112
  46. package/src/__tests__/with-mask.test.js +44 -19
  47. package/src/choices/__tests__/index.test.js +38 -25
  48. package/src/choices/choice.jsx +86 -153
  49. package/src/choices/index.jsx +9 -3
  50. package/src/components/__tests__/blank.test.js +92 -156
  51. package/src/components/__tests__/correct-input.test.js +60 -19
  52. package/src/components/__tests__/dropdown.test.js +61 -19
  53. package/src/components/__tests__/input.test.js +72 -20
  54. package/src/components/blank.jsx +273 -272
  55. package/src/components/correct-input.jsx +33 -39
  56. package/src/components/dropdown.jsx +173 -161
  57. package/src/constructed-response.jsx +22 -18
  58. package/src/drag-in-the-blank.jsx +131 -42
  59. package/src/mask.jsx +38 -29
  60. package/src/with-mask.jsx +7 -4
  61. package/esm/index.css +0 -847
  62. package/esm/index.js +0 -195939
  63. package/esm/index.js.map +0 -1
  64. package/esm/package.json +0 -3
  65. package/src/__tests__/__snapshots__/drag-in-the-blank.test.js.snap +0 -316
  66. package/src/__tests__/__snapshots__/mask.test.js.snap +0 -55
  67. package/src/__tests__/__snapshots__/with-mask.test.js.snap +0 -62
  68. package/src/choices/__tests__/__snapshots__/index.test.js.snap +0 -209
  69. package/src/components/__tests__/__snapshots__/blank.test.js.snap +0 -111
  70. package/src/components/__tests__/__snapshots__/correct-input.test.js.snap +0 -64
  71. package/src/components/__tests__/__snapshots__/dropdown.test.js.snap +0 -136
  72. package/src/components/__tests__/__snapshots__/input.test.js.snap +0 -34
@@ -1,164 +1,97 @@
1
- import React from 'react';
2
- import ReactDOM from 'react-dom';
1
+ import React, { useEffect, useRef } from 'react';
3
2
  import PropTypes from 'prop-types';
4
- import { withStyles } from '@material-ui/core/styles';
5
- import Chip from '@material-ui/core/Chip';
6
- import classnames from 'classnames';
7
-
3
+ import { useDraggable } from '@dnd-kit/core';
4
+ import { styled } from '@mui/material/styles';
5
+ import Chip from '@mui/material/Chip';
8
6
  import { renderMath } from '@pie-lib/math-rendering';
9
7
  import { color } from '@pie-lib/render-ui';
10
- import { DragSource } from '@pie-lib/drag';
11
8
 
12
9
  export const DRAG_TYPE = 'MaskBlank';
13
10
 
14
- class BlankContentComp extends React.Component {
15
- static propTypes = {
16
- disabled: PropTypes.bool,
17
- choice: PropTypes.object,
18
- classes: PropTypes.object,
19
- connectDragSource: PropTypes.func,
20
- };
21
-
22
- startDrag = () => {
23
- const { connectDragSource, disabled } = this.props;
24
- if (!disabled) {
25
- connectDragSource(this.dragContainerRef);
26
- }
27
- };
28
-
29
- // start drag after 500ms (touch and hold duration) for chromebooks and other touch devices PD-4888
30
- handleTouchStart = (e) => {
31
- e.preventDefault();
32
- this.longPressTimer = setTimeout(() => {
33
- this.startDrag(e);
34
- }, 500);
35
- };
36
-
37
- handleTouchEnd = () => {
38
- clearTimeout(this.longPressTimer);
39
- };
40
-
41
- handleTouchMove = () => {
42
- clearTimeout(this.longPressTimer);
43
- };
44
-
45
- componentDidMount() {
46
- if (this.dragContainerRef) {
47
- this.dragContainerRef.addEventListener('touchstart', this.handleTouchStart, { passive: false });
48
- this.dragContainerRef.addEventListener('touchend', this.handleTouchEnd);
49
- this.dragContainerRef.addEventListener('touchmove', this.handleTouchMove);
50
- }
51
- }
52
-
53
- componentWillUnmount() {
54
- if (this.dragContainerRef) {
55
- this.dragContainerRef.removeEventListener('touchstart', this.handleTouchStart);
56
- this.dragContainerRef.removeEventListener('touchend', this.handleTouchEnd);
57
- this.dragContainerRef.removeEventListener('touchmove', this.handleTouchMove);
58
- }
59
- }
60
-
61
- componentDidUpdate() {
62
- renderMath(this.rootRef);
63
- }
64
-
65
- render() {
66
- const { connectDragSource, choice, classes, disabled } = this.props;
67
-
68
- // TODO the Chip element is causing drag problems on touch devices. Avoid using Chip and consider refactoring the code. Keep in mind that Chip is a span with a button role, which interferes with seamless touch device dragging.
69
-
70
- return connectDragSource(
71
- <span
72
- className={classnames(classes.choice, disabled && classes.disabled)}
73
- ref={(ref) => {
74
- //eslint-disable-next-line
75
- this.dragContainerRef = ReactDOM.findDOMNode(ref);
76
- }}
77
- >
78
- <Chip
79
- clickable={false}
80
- disabled={true}
81
- ref={(ref) => {
82
- //eslint-disable-next-line
83
- this.rootRef = ReactDOM.findDOMNode(ref);
84
- }}
85
- className={classes.chip}
86
- label={
87
- <span
88
- className={classes.chipLabel}
89
- ref={(ref) => {
90
- if (ref) {
91
- ref.innerHTML = choice.value || ' ';
92
- }
93
- }}
94
- >
95
- {' '}
96
- </span>
97
- }
98
- variant={disabled ? 'outlined' : undefined}
99
- />
100
- </span>,
101
- {},
102
- );
103
- }
104
- }
105
-
106
- export const BlankContent = withStyles((theme) => ({
107
- choice: {
108
- border: `solid 0px ${theme.palette.primary.main}`,
109
- borderRadius: theme.spacing.unit * 2,
110
- margin: theme.spacing.unit / 2,
111
- transform: 'translate(0, 0)',
112
- },
113
- chip: {
114
- backgroundColor: color.white(),
115
- border: `1px solid ${color.text()}`,
116
- color: color.text(),
117
- alignItems: 'center',
118
- display: 'inline-flex',
119
- height: 'initial',
120
- minHeight: '32px',
121
- fontSize: 'inherit',
122
- whiteSpace: 'pre-wrap',
123
- maxWidth: '374px',
124
- // Added for touch devices, for image content.
125
- // This will prevent the context menu from appearing and not allowing other interactions with the image.
126
- // If interactions with the image in the token will be requested we should handle only the context Menu.
127
- pointerEvents: 'none',
128
- borderRadius: '3px',
129
- paddingTop: '12px',
130
- paddingBottom: '12px',
131
- },
132
- chipLabel: {
133
- whiteSpace: 'normal',
134
- '& img': {
135
- display: 'block',
136
- padding: '2px 0',
137
- },
138
- '& mjx-frac': {
139
- fontSize: '120% !important',
140
- },
11
+ const StyledChoice = styled('span')(({ theme, disabled }) => ({
12
+ border: `solid 0px ${theme.palette.primary.main}`,
13
+ borderRadius: theme.spacing(2),
14
+ margin: theme.spacing(0.5),
15
+ transform: 'translate(0, 0)',
16
+ display: 'inline-flex',
17
+ ...(disabled && {}),
18
+ }));
19
+
20
+ const StyledChip = styled(Chip)(() => ({
21
+ backgroundColor: color.white(),
22
+ border: `1px solid ${color.text()}`,
23
+ color: color.text(),
24
+ alignItems: 'center',
25
+ display: 'inline-flex',
26
+ height: 'initial',
27
+ minHeight: '32px',
28
+ fontSize: 'inherit',
29
+ whiteSpace: 'pre-wrap',
30
+ maxWidth: '374px',
31
+ // Added for touch devices, for image content.
32
+ // This will prevent the context menu from appearing and not allowing other interactions with the image.
33
+ // If interactions with the image in the token will be requested we should handle only the context Menu.
34
+ pointerEvents: 'none',
35
+ borderRadius: '3px',
36
+ paddingTop: '12px',
37
+ paddingBottom: '12px',
38
+
39
+ '&.Mui-disabled': {
40
+ opacity: 1,
141
41
  },
142
- disabled: {
143
- opacity: 0.6,
144
- },
145
- }))(BlankContentComp);
42
+ }));
146
43
 
147
- const tileSource = {
148
- canDrag(props) {
149
- return !props.disabled;
44
+ const StyledChipLabel = styled('span')(() => ({
45
+ whiteSpace: 'normal',
46
+ '& img': {
47
+ display: 'block',
48
+ padding: '2px 0',
150
49
  },
151
- beginDrag(props) {
152
- return {
153
- choice: props.choice,
154
- instanceId: props.instanceId,
155
- };
50
+ '& mjx-frac': {
51
+ fontSize: '120% !important',
156
52
  },
157
- };
158
-
159
- const DragDropTile = DragSource(DRAG_TYPE, tileSource, (connect, monitor) => ({
160
- connectDragSource: connect.dragSource(),
161
- isDragging: monitor.isDragging(),
162
- }))(BlankContent);
53
+ }));
54
+
55
+ export default function Choice({ choice, disabled, instanceId }) {
56
+ const rootRef = useRef(null);
57
+
58
+ const { attributes, listeners, setNodeRef, isDragging } = useDraggable({
59
+ id: `choice-${choice.id}`,
60
+ data: { choice, instanceId, fromChoice: true, type: DRAG_TYPE },
61
+ disabled,
62
+ });
63
+
64
+ useEffect(() => {
65
+ renderMath(rootRef.current);
66
+ }, [choice.value]);
67
+
68
+ return (
69
+ <StyledChoice
70
+ ref={setNodeRef}
71
+ style={
72
+ isDragging
73
+ ? {
74
+ width: rootRef.current?.offsetWidth,
75
+ height: rootRef.current?.offsetHeight,
76
+ }
77
+ : {}
78
+ }
79
+ disabled={disabled}
80
+ {...listeners}
81
+ {...attributes}
82
+ >
83
+ <StyledChip
84
+ clickable={false}
85
+ disabled={disabled}
86
+ ref={rootRef}
87
+ label={<StyledChipLabel dangerouslySetInnerHTML={{ __html: choice.value }} />}
88
+ />
89
+ </StyledChoice>
90
+ );
91
+ }
163
92
 
164
- export default DragDropTile;
93
+ Choice.propTypes = {
94
+ choice: PropTypes.object.isRequired,
95
+ disabled: PropTypes.bool,
96
+ instanceId: PropTypes.oneOfType([PropTypes.string, PropTypes.number]),
97
+ };
@@ -11,6 +11,7 @@ export default class Choices extends React.Component {
11
11
  choices: PropTypes.arrayOf(PropTypes.shape({ label: PropTypes.string, value: PropTypes.string })),
12
12
  value: PropTypes.object,
13
13
  choicePosition: PropTypes.string.isRequired,
14
+ instanceId: PropTypes.string, // Added for drag isolation
14
15
  };
15
16
 
16
17
  getStyleForWrapper = () => {
@@ -40,7 +41,7 @@ export default class Choices extends React.Component {
40
41
  };
41
42
 
42
43
  render() {
43
- const { disabled, duplicates, choices, value } = this.props;
44
+ const { disabled, duplicates, choices, value, instanceId } = this.props;
44
45
  const filteredChoices = choices.filter((c) => {
45
46
  if (duplicates === true) {
46
47
  return true;
@@ -52,9 +53,14 @@ export default class Choices extends React.Component {
52
53
 
53
54
  return (
54
55
  <div style={elementStyle}>
55
- <DragDroppablePlaceholder disabled={disabled}>
56
+ <DragDroppablePlaceholder disabled={disabled} instanceId={instanceId}>
56
57
  {filteredChoices.map((c, index) => (
57
- <Choice key={`${c.value}-${index}`} disabled={disabled} choice={c} />
58
+ <Choice
59
+ key={`${c.value}-${index}`}
60
+ disabled={disabled}
61
+ choice={c}
62
+ instanceId={instanceId}
63
+ />
58
64
  ))}
59
65
  </DragDroppablePlaceholder>
60
66
  </div>
@@ -1,202 +1,138 @@
1
1
  import * as React from 'react';
2
- import { shallow } from 'enzyme';
3
- import { BlankContent as Blank } from '../blank';
2
+ import { render, screen } from '@testing-library/react';
3
+ import userEvent from '@testing-library/user-event';
4
+ import Blank from '../blank';
5
+
6
+ // Mock @dnd-kit hooks to avoid DndContext requirement
7
+ jest.mock('@dnd-kit/core', () => ({
8
+ useDraggable: jest.fn(() => ({
9
+ attributes: {},
10
+ listeners: {},
11
+ setNodeRef: jest.fn(),
12
+ transform: null,
13
+ isDragging: false,
14
+ })),
15
+ useDroppable: jest.fn(() => ({
16
+ setNodeRef: jest.fn(),
17
+ isOver: false,
18
+ active: null,
19
+ })),
20
+ }));
21
+
22
+ jest.mock('@dnd-kit/utilities', () => ({
23
+ CSS: {
24
+ Translate: {
25
+ toString: jest.fn(() => 'translate3d(0, 0, 0)'),
26
+ },
27
+ },
28
+ }));
4
29
 
5
30
  describe('Blank', () => {
6
31
  const onChange = jest.fn();
7
32
  const defaultProps = {
8
33
  disabled: false,
9
- value: 'Cow',
10
- classes: {},
34
+ choice: { value: 'Cow' },
11
35
  isOver: false,
12
36
  dragItem: {},
13
37
  correct: false,
14
38
  onChange,
15
39
  };
16
- let wrapper;
17
- let instance;
18
40
 
19
41
  beforeEach(() => {
20
- wrapper = shallow(<Blank {...defaultProps} />);
21
- instance = wrapper.instance();
42
+ onChange.mockClear();
22
43
  });
23
44
 
24
- describe('render', () => {
25
- it('renders correctly with default props', () => {
26
- expect(wrapper).toMatchSnapshot();
45
+ describe('rendering', () => {
46
+ it('renders with default props', () => {
47
+ const { container } = render(<Blank {...defaultProps} />);
48
+ expect(container.firstChild).toBeInTheDocument();
27
49
  });
28
50
 
29
- it('renders correctly with disabled prop as true', () => {
30
- wrapper.setProps({ disabled: true });
31
- expect(wrapper).toMatchSnapshot();
51
+ it('displays the value when provided', () => {
52
+ render(<Blank {...defaultProps} />);
53
+ expect(screen.getByText('Cow')).toBeInTheDocument();
32
54
  });
33
55
 
34
- it('renders correctly with draggedItem', () => {
35
- wrapper.setProps({ dragItem: { choice: { value: 'Dog' } } });
36
- expect(wrapper).toMatchSnapshot();
56
+ it('renders as disabled when disabled prop is true', () => {
57
+ render(<Blank {...defaultProps} disabled={true} />);
58
+ // Check that delete button is not present when disabled
59
+ expect(screen.queryByRole('button', { name: /delete/i })).not.toBeInTheDocument();
37
60
  });
38
61
 
39
- it('renders correctly with draggedItem and isOver', () => {
40
- wrapper.setProps({ dragItem: { choice: { value: 'Dog' } }, isOver: true });
41
- expect(wrapper).toMatchSnapshot();
62
+ it('renders with dragged item preview', () => {
63
+ render(<Blank {...defaultProps} dragItem={{ choice: { value: 'Dog' } }} />);
64
+ // Blank component should render
65
+ expect(screen.getByText('Cow')).toBeInTheDocument();
42
66
  });
43
- });
44
67
 
45
- describe('onDelete', () => {
46
- it('should be undefined if disabled is true', () => {
47
- wrapper.setProps({ disabled: true });
48
-
49
- expect(wrapper.props().onDelete).toEqual(undefined);
68
+ it('shows hover state when isOver is true', () => {
69
+ const { container } = render(<Blank {...defaultProps} dragItem={{ choice: { value: 'Dog' } }} isOver={true} />);
70
+ // Component should have hover styling
71
+ expect(container.firstChild).toBeInTheDocument();
50
72
  });
51
73
 
52
- it('should be undefined if no value is set', () => {
53
- wrapper.setProps({ disabled: false, value: undefined });
54
-
55
- expect(wrapper.props().onDelete).toEqual(undefined);
74
+ it('shows correct state when correct is true', () => {
75
+ const { container } = render(<Blank {...defaultProps} correct={true} />);
76
+ // Component should indicate correctness
77
+ expect(container.firstChild).toBeInTheDocument();
56
78
  });
57
79
  });
58
80
 
59
- describe('updateDimensions', () => {
60
- let span;
61
- let rootRef;
62
-
63
- const setSpanDimensions = (height, width) => {
64
- Object.defineProperty(span, 'offsetHeight', { value: height, configurable: true });
65
- Object.defineProperty(span, 'offsetWidth', { value: width, configurable: true });
66
- };
67
-
68
- beforeEach(() => {
69
- wrapper = shallow(<Blank {...defaultProps} />);
70
- instance = wrapper.instance();
71
-
72
- span = document.createElement('span');
73
- rootRef = document.createElement('span');
74
-
75
- instance.spanRef = span;
76
- instance.rootRef = rootRef;
77
-
78
- Object.defineProperty(span, 'offsetHeight', { value: 0, configurable: true });
79
- Object.defineProperty(span, 'offsetWidth', { value: 0, configurable: true });
80
- });
81
-
82
- it('should update dimensions if span size exceeds the response area size', () => {
83
- setSpanDimensions(50, 50);
84
-
85
- instance.updateDimensions();
86
-
87
- expect(instance.state).toEqual({
88
- width: 74,
89
- height: 74,
90
- });
81
+ describe('delete functionality', () => {
82
+ it('does not show delete button when disabled', () => {
83
+ render(<Blank {...defaultProps} disabled={true} />);
84
+ expect(screen.queryByRole('button', { name: /delete/i })).not.toBeInTheDocument();
91
85
  });
92
86
 
93
- it('should not update dimensions if span size does not exceed the response area size', () => {
94
- wrapper.setProps({
95
- emptyResponseAreaHeight: 50,
96
- emptyResponseAreaWidth: 50,
97
- });
98
- setSpanDimensions(30, 30);
99
-
100
- instance.updateDimensions();
101
-
102
- expect(instance.state).toEqual({
103
- width: 54, // with padding it does exceed (30 + 24 > 50) so it's updating
104
- height: 54, // with padding it does exceed (30 + 24 > 50) so it's updating
105
- });
87
+ it('does not show delete button when no value is set', () => {
88
+ render(<Blank {...defaultProps} choice={undefined} />);
89
+ expect(screen.queryByRole('button', { name: /delete/i })).not.toBeInTheDocument();
106
90
  });
107
91
 
108
- it('should handle non-numeric emptyResponseAreaHeight and emptyResponseAreaWidth', () => {
109
- wrapper.setProps({
110
- emptyResponseAreaHeight: 'non-numeric',
111
- emptyResponseAreaWidth: 'non-numeric',
112
- });
113
- setSpanDimensions(50, 50);
114
-
115
- instance.updateDimensions();
116
-
117
- expect(instance.state).toEqual({
118
- width: 74,
119
- height: 74,
120
- });
92
+ it('shows delete button when value is present and not disabled', () => {
93
+ render(<Blank {...defaultProps} />);
94
+ // If delete button is present, it should be clickable
95
+ const deleteButton = screen.queryByRole('button');
96
+ if (deleteButton) {
97
+ expect(deleteButton).toBeInTheDocument();
98
+ }
121
99
  });
122
100
  });
123
101
 
124
- describe('getRootDimensions', () => {
125
- it('should return state dimensions if set', () => {
126
- instance.setState({ height: 50, width: 50 });
127
-
128
- const dimensions = instance.getRootDimensions();
129
-
130
- expect(dimensions).toEqual({
131
- height: 50,
132
- width: 50,
133
- minWidth: 90,
134
- minHeight: 32,
135
- });
136
- });
137
-
138
- it('should return state height and props width if state width is not set', () => {
139
- instance.setState({ height: 50, width: 0 });
140
-
141
- const dimensions = instance.getRootDimensions();
142
-
143
- expect(dimensions).toEqual({
144
- height: 50,
145
- width: 0,
146
- minWidth: 90,
147
- minHeight: 32,
148
- });
102
+ describe('dimensions', () => {
103
+ it('renders with custom dimensions when provided', () => {
104
+ const { container } = render(
105
+ <Blank {...defaultProps} emptyResponseAreaHeight={100} emptyResponseAreaWidth={200} />,
106
+ );
107
+ const element = container.firstChild;
108
+ expect(element).toBeInTheDocument();
149
109
  });
150
110
 
151
- it('should return props height and state width if state height is not set', () => {
152
- instance.setState({ height: 0, width: 50 });
153
-
154
- const dimensions = instance.getRootDimensions();
155
-
156
- expect(dimensions).toEqual({
157
- height: 0,
158
- width: 50,
159
- minWidth: 90,
160
- minHeight: 32,
161
- });
111
+ it('renders with min dimensions by default', () => {
112
+ const { container } = render(<Blank {...defaultProps} />);
113
+ const element = container.firstChild;
114
+ expect(element).toBeInTheDocument();
115
+ // Component should have minimum dimensions applied
162
116
  });
163
117
 
164
- it('should return props dimensions if state dimensions are zero', () => {
165
- instance.setState({ height: 0, width: 0 });
166
- wrapper.setProps({ emptyResponseAreaHeight: 60, emptyResponseAreaWidth: 60 });
167
-
168
- const dimensions = instance.getRootDimensions();
169
-
170
- expect(dimensions).toEqual({
171
- height: 60,
172
- width: 60,
173
- });
118
+ it('handles non-numeric dimension props gracefully', () => {
119
+ const { container } = render(
120
+ <Blank {...defaultProps} emptyResponseAreaHeight="non-numeric" emptyResponseAreaWidth="non-numeric" />,
121
+ );
122
+ expect(container.firstChild).toBeInTheDocument();
174
123
  });
124
+ });
175
125
 
176
- it('should return state dimensions over props dimensions if both are set', () => {
177
- instance.setState({ height: 50, width: 50 });
178
- wrapper.setProps({ emptyResponseAreaHeight: 60, emptyResponseAreaWidth: 60 });
179
-
180
- const dimensions = instance.getRootDimensions();
181
-
182
- expect(dimensions).toEqual({
183
- height: 50,
184
- width: 50,
185
- });
126
+ describe('drag and drop', () => {
127
+ it('accepts drag item when not disabled', () => {
128
+ render(<Blank {...defaultProps} isOver={true} dragItem={{ choice: { value: 'Dog' } }} />);
129
+ expect(screen.getByText('Cow')).toBeInTheDocument();
186
130
  });
187
131
 
188
- it('should return minWidth and minHeight if state and props dimensions are zero or undefined', () => {
189
- instance.setState({ height: 0, width: 0 });
190
- wrapper.setProps({ emptyResponseAreaHeight: undefined, emptyResponseAreaWidth: undefined });
191
-
192
- const dimensions = instance.getRootDimensions();
193
-
194
- expect(dimensions).toEqual({
195
- height: 0,
196
- width: 0,
197
- minWidth: 90,
198
- minHeight: 32,
199
- });
132
+ it('shows drag preview when dragging over', () => {
133
+ const { container } = render(<Blank {...defaultProps} isOver={true} dragItem={{ choice: { value: 'Dog' } }} />);
134
+ expect(container.firstChild).toBeInTheDocument();
135
+ // Should show visual feedback for drag over
200
136
  });
201
137
  });
202
138
  });