@pie-lib/mask-markup 3.1.5 → 3.1.6-beta.10

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 (41) hide show
  1. package/CHANGELOG.md +0 -105
  2. package/lib/__tests__/drag-in-the-blank.test.js +129 -0
  3. package/lib/__tests__/index.test.js +39 -0
  4. package/lib/__tests__/keyboard-coordinates.test.js +449 -0
  5. package/lib/__tests__/mask.test.js +344 -0
  6. package/lib/__tests__/serialization.test.js +44 -0
  7. package/lib/__tests__/utils.js +14 -0
  8. package/lib/__tests__/with-mask.test.js +110 -0
  9. package/lib/choices/__tests__/index.test.js +139 -0
  10. package/lib/choices/choice.js +6 -24
  11. package/lib/choices/choice.js.map +1 -1
  12. package/lib/choices/index.js +9 -32
  13. package/lib/choices/index.js.map +1 -1
  14. package/lib/components/__tests__/blank.test.js +293 -0
  15. package/lib/components/__tests__/correct-input.test.js +132 -0
  16. package/lib/components/__tests__/dropdown.test.js +202 -0
  17. package/lib/components/__tests__/input.test.js +129 -0
  18. package/lib/components/blank.js +29 -106
  19. package/lib/components/blank.js.map +1 -1
  20. package/lib/components/dropdown.js +9 -6
  21. package/lib/components/dropdown.js.map +1 -1
  22. package/lib/drag-in-the-blank.js +30 -139
  23. package/lib/drag-in-the-blank.js.map +1 -1
  24. package/lib/keyboard-coordinates.js +1 -1
  25. package/lib/mask.js +15 -20
  26. package/lib/mask.js.map +1 -1
  27. package/package.json +6 -6
  28. package/src/__tests__/drag-in-the-blank.test.js +2 -147
  29. package/src/__tests__/mask.test.js +0 -98
  30. package/src/choices/__tests__/index.test.js +1 -104
  31. package/src/choices/choice.jsx +3 -16
  32. package/src/choices/index.jsx +3 -27
  33. package/src/components/__tests__/blank.test.js +5 -186
  34. package/src/components/blank.jsx +35 -108
  35. package/src/components/dropdown.jsx +9 -7
  36. package/src/drag-in-the-blank.jsx +22 -132
  37. package/src/mask.jsx +11 -13
  38. package/LICENSE.md +0 -5
  39. package/lib/keyboard-coordinates.js.map +0 -1
  40. package/src/__tests__/keyboard-coordinates.test.js +0 -202
  41. package/src/keyboard-coordinates.js +0 -147
@@ -0,0 +1,202 @@
1
+ "use strict";
2
+
3
+ var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
4
+ var _typeof = require("@babel/runtime/helpers/typeof");
5
+ var _regenerator = _interopRequireDefault(require("@babel/runtime/regenerator"));
6
+ var _extends2 = _interopRequireDefault(require("@babel/runtime/helpers/extends"));
7
+ var _asyncToGenerator2 = _interopRequireDefault(require("@babel/runtime/helpers/asyncToGenerator"));
8
+ var React = _interopRequireWildcard(require("react"));
9
+ var _react2 = require("@testing-library/react");
10
+ var _userEvent = _interopRequireDefault(require("@testing-library/user-event"));
11
+ var _utils = require("../../__tests__/utils");
12
+ var _dropdown = _interopRequireDefault(require("../dropdown"));
13
+ function _interopRequireWildcard(e, t) { if ("function" == typeof WeakMap) var r = new WeakMap(), n = new WeakMap(); return (_interopRequireWildcard = function _interopRequireWildcard(e, t) { if (!t && e && e.__esModule) return e; var o, i, f = { __proto__: null, "default": e }; if (null === e || "object" != _typeof(e) && "function" != typeof e) return f; if (o = t ? n : r) { if (o.has(e)) return o.get(e); o.set(e, f); } for (var _t in e) "default" !== _t && {}.hasOwnProperty.call(e, _t) && ((i = (o = Object.defineProperty) && Object.getOwnPropertyDescriptor(e, _t)) && (i.get || i.set) ? o(f, _t, i) : f[_t] = e[_t]); return f; })(e, t); }
14
+ describe('Dropdown', function () {
15
+ var onChange = jest.fn();
16
+ var defaultProps = {
17
+ onChange: onChange,
18
+ id: '1',
19
+ correct: false,
20
+ disabled: false,
21
+ value: 'Jumped',
22
+ choices: [(0, _utils.choice)('Jumped'), (0, _utils.choice)('Laughed'), (0, _utils.choice)('Smiled')]
23
+ };
24
+ beforeEach(function () {
25
+ onChange.mockClear();
26
+ });
27
+ describe('rendering', function () {
28
+ it('renders dropdown with default props', function () {
29
+ (0, _react2.render)(/*#__PURE__*/React.createElement(_dropdown["default"], defaultProps));
30
+ var button = _react2.screen.getByRole('combobox');
31
+ expect(button).toBeInTheDocument();
32
+ // Button displays the selected value
33
+ expect(button).toHaveTextContent('Jumped');
34
+ });
35
+ it('renders with all choices as options when opened', /*#__PURE__*/(0, _asyncToGenerator2["default"])(/*#__PURE__*/_regenerator["default"].mark(function _callee() {
36
+ var user, button, options;
37
+ return _regenerator["default"].wrap(function (_context) {
38
+ while (1) switch (_context.prev = _context.next) {
39
+ case 0:
40
+ user = _userEvent["default"].setup();
41
+ (0, _react2.render)(/*#__PURE__*/React.createElement(_dropdown["default"], defaultProps));
42
+ button = _react2.screen.getByRole('combobox');
43
+ _context.next = 1;
44
+ return user.click(button);
45
+ case 1:
46
+ // Options should now be visible - find them by role
47
+ options = _react2.screen.getAllByRole('option');
48
+ expect(options).toHaveLength(3);
49
+ // Verify the text content of options using specific elements
50
+ expect(options[0]).toHaveTextContent('Jumped');
51
+ expect(options[1]).toHaveTextContent('Laughed');
52
+ expect(options[2]).toHaveTextContent('Smiled');
53
+ case 2:
54
+ case "end":
55
+ return _context.stop();
56
+ }
57
+ }, _callee);
58
+ })));
59
+ it('focuses the selected option when the menu opens', /*#__PURE__*/(0, _asyncToGenerator2["default"])(/*#__PURE__*/_regenerator["default"].mark(function _callee2() {
60
+ var user, button;
61
+ return _regenerator["default"].wrap(function (_context2) {
62
+ while (1) switch (_context2.prev = _context2.next) {
63
+ case 0:
64
+ user = _userEvent["default"].setup();
65
+ (0, _react2.render)(/*#__PURE__*/React.createElement(_dropdown["default"], defaultProps));
66
+ button = _react2.screen.getByRole('combobox');
67
+ _context2.next = 1;
68
+ return user.click(button);
69
+ case 1:
70
+ _context2.next = 2;
71
+ return (0, _react2.waitFor)(function () {
72
+ expect(document.getElementById('dropdown-option-1-0')).toHaveFocus();
73
+ });
74
+ case 2:
75
+ expect(button).toHaveAttribute('aria-activedescendant', 'dropdown-option-1-0');
76
+ case 3:
77
+ case "end":
78
+ return _context2.stop();
79
+ }
80
+ }, _callee2);
81
+ })));
82
+ it('focuses a non-first selected option when the menu opens', /*#__PURE__*/(0, _asyncToGenerator2["default"])(/*#__PURE__*/_regenerator["default"].mark(function _callee3() {
83
+ var user, button;
84
+ return _regenerator["default"].wrap(function (_context3) {
85
+ while (1) switch (_context3.prev = _context3.next) {
86
+ case 0:
87
+ user = _userEvent["default"].setup();
88
+ (0, _react2.render)(/*#__PURE__*/React.createElement(_dropdown["default"], (0, _extends2["default"])({}, defaultProps, {
89
+ value: "Laughed"
90
+ })));
91
+ button = _react2.screen.getByRole('combobox');
92
+ _context3.next = 1;
93
+ return user.click(button);
94
+ case 1:
95
+ _context3.next = 2;
96
+ return (0, _react2.waitFor)(function () {
97
+ expect(document.getElementById('dropdown-option-1-1')).toHaveFocus();
98
+ });
99
+ case 2:
100
+ expect(button).toHaveAttribute('aria-activedescendant', 'dropdown-option-1-1');
101
+ case 3:
102
+ case "end":
103
+ return _context3.stop();
104
+ }
105
+ }, _callee3);
106
+ })));
107
+ it('does not highlight an option when no value is selected', /*#__PURE__*/(0, _asyncToGenerator2["default"])(/*#__PURE__*/_regenerator["default"].mark(function _callee4() {
108
+ var user, button;
109
+ return _regenerator["default"].wrap(function (_context4) {
110
+ while (1) switch (_context4.prev = _context4.next) {
111
+ case 0:
112
+ user = _userEvent["default"].setup();
113
+ (0, _react2.render)(/*#__PURE__*/React.createElement(_dropdown["default"], (0, _extends2["default"])({}, defaultProps, {
114
+ value: undefined
115
+ })));
116
+ button = _react2.screen.getByRole('combobox');
117
+ _context4.next = 1;
118
+ return user.click(button);
119
+ case 1:
120
+ expect(button).not.toHaveAttribute('aria-activedescendant');
121
+ case 2:
122
+ case "end":
123
+ return _context4.stop();
124
+ }
125
+ }, _callee4);
126
+ })));
127
+ it('renders as disabled when disabled prop is true', function () {
128
+ (0, _react2.render)(/*#__PURE__*/React.createElement(_dropdown["default"], (0, _extends2["default"])({}, defaultProps, {
129
+ disabled: true
130
+ })));
131
+ var button = _react2.screen.getByRole('combobox');
132
+ expect(button).toBeDisabled();
133
+ });
134
+ it('shows correct state when correct is true', function () {
135
+ var _render = (0, _react2.render)(/*#__PURE__*/React.createElement(_dropdown["default"], (0, _extends2["default"])({}, defaultProps, {
136
+ correct: true
137
+ }))),
138
+ container = _render.container;
139
+ var button = _react2.screen.getByRole('combobox');
140
+ expect(button).toBeInTheDocument();
141
+ });
142
+ });
143
+ describe('user interactions', function () {
144
+ it('calls onChange when user selects a different option', /*#__PURE__*/(0, _asyncToGenerator2["default"])(/*#__PURE__*/_regenerator["default"].mark(function _callee5() {
145
+ var user, button, options, laughedOption;
146
+ return _regenerator["default"].wrap(function (_context5) {
147
+ while (1) switch (_context5.prev = _context5.next) {
148
+ case 0:
149
+ user = _userEvent["default"].setup();
150
+ (0, _react2.render)(/*#__PURE__*/React.createElement(_dropdown["default"], defaultProps));
151
+
152
+ // Click button to open menu
153
+ button = _react2.screen.getByRole('combobox');
154
+ _context5.next = 1;
155
+ return user.click(button);
156
+ case 1:
157
+ // Find the option by getting all options and selecting the one with "Laughed" text
158
+ options = _react2.screen.getAllByRole('option');
159
+ laughedOption = options.find(function (opt) {
160
+ return opt.textContent.includes('Laughed');
161
+ });
162
+ _context5.next = 2;
163
+ return user.click(laughedOption);
164
+ case 2:
165
+ expect(onChange).toHaveBeenCalledWith('1', 'Laughed');
166
+ case 3:
167
+ case "end":
168
+ return _context5.stop();
169
+ }
170
+ }, _callee5);
171
+ })));
172
+ it('calls onChange with correct value', /*#__PURE__*/(0, _asyncToGenerator2["default"])(/*#__PURE__*/_regenerator["default"].mark(function _callee6() {
173
+ var user, button, options, smiledOption;
174
+ return _regenerator["default"].wrap(function (_context6) {
175
+ while (1) switch (_context6.prev = _context6.next) {
176
+ case 0:
177
+ user = _userEvent["default"].setup();
178
+ (0, _react2.render)(/*#__PURE__*/React.createElement(_dropdown["default"], defaultProps));
179
+
180
+ // Click button to open menu
181
+ button = _react2.screen.getByRole('combobox');
182
+ _context6.next = 1;
183
+ return user.click(button);
184
+ case 1:
185
+ // Find the option by getting all options and selecting the one with "Smiled" text
186
+ options = _react2.screen.getAllByRole('option');
187
+ smiledOption = options.find(function (opt) {
188
+ return opt.textContent.includes('Smiled');
189
+ });
190
+ _context6.next = 2;
191
+ return user.click(smiledOption);
192
+ case 2:
193
+ expect(onChange).toHaveBeenCalledWith('1', 'Smiled');
194
+ case 3:
195
+ case "end":
196
+ return _context6.stop();
197
+ }
198
+ }, _callee6);
199
+ })));
200
+ });
201
+ });
202
+ //# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJuYW1lcyI6WyJSZWFjdCIsIl9pbnRlcm9wUmVxdWlyZVdpbGRjYXJkIiwicmVxdWlyZSIsIl9yZWFjdDIiLCJfdXNlckV2ZW50IiwiX2ludGVyb3BSZXF1aXJlRGVmYXVsdCIsIl91dGlscyIsIl9kcm9wZG93biIsImUiLCJ0IiwiV2Vha01hcCIsInIiLCJuIiwiX19lc01vZHVsZSIsIm8iLCJpIiwiZiIsIl9fcHJvdG9fXyIsIl90eXBlb2YiLCJoYXMiLCJnZXQiLCJzZXQiLCJfdCIsImhhc093blByb3BlcnR5IiwiY2FsbCIsIk9iamVjdCIsImRlZmluZVByb3BlcnR5IiwiZ2V0T3duUHJvcGVydHlEZXNjcmlwdG9yIiwiZGVzY3JpYmUiLCJvbkNoYW5nZSIsImplc3QiLCJmbiIsImRlZmF1bHRQcm9wcyIsImlkIiwiY29ycmVjdCIsImRpc2FibGVkIiwidmFsdWUiLCJjaG9pY2VzIiwiY2hvaWNlIiwiYmVmb3JlRWFjaCIsIm1vY2tDbGVhciIsIml0IiwicmVuZGVyIiwiY3JlYXRlRWxlbWVudCIsImJ1dHRvbiIsInNjcmVlbiIsImdldEJ5Um9sZSIsImV4cGVjdCIsInRvQmVJblRoZURvY3VtZW50IiwidG9IYXZlVGV4dENvbnRlbnQiLCJfYXN5bmNUb0dlbmVyYXRvcjIiLCJfcmVnZW5lcmF0b3IiLCJtYXJrIiwiX2NhbGxlZSIsInVzZXIiLCJvcHRpb25zIiwid3JhcCIsIl9jb250ZXh0IiwicHJldiIsIm5leHQiLCJ1c2VyRXZlbnQiLCJzZXR1cCIsImNsaWNrIiwiZ2V0QWxsQnlSb2xlIiwidG9IYXZlTGVuZ3RoIiwic3RvcCIsIl9jYWxsZWUyIiwiX2NvbnRleHQyIiwid2FpdEZvciIsImRvY3VtZW50IiwiZ2V0RWxlbWVudEJ5SWQiLCJ0b0hhdmVGb2N1cyIsInRvSGF2ZUF0dHJpYnV0ZSIsIl9jYWxsZWUzIiwiX2NvbnRleHQzIiwiX2V4dGVuZHMyIiwiX2NhbGxlZTQiLCJfY29udGV4dDQiLCJ1bmRlZmluZWQiLCJub3QiLCJ0b0JlRGlzYWJsZWQiLCJfcmVuZGVyIiwiY29udGFpbmVyIiwiX2NhbGxlZTUiLCJsYXVnaGVkT3B0aW9uIiwiX2NvbnRleHQ1IiwiZmluZCIsIm9wdCIsInRleHRDb250ZW50IiwiaW5jbHVkZXMiLCJ0b0hhdmVCZWVuQ2FsbGVkV2l0aCIsIl9jYWxsZWU2Iiwic21pbGVkT3B0aW9uIiwiX2NvbnRleHQ2Il0sInNvdXJjZXMiOlsiLi4vLi4vLi4vc3JjL2NvbXBvbmVudHMvX190ZXN0c19fL2Ryb3Bkb3duLnRlc3QuanMiXSwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0ICogYXMgUmVhY3QgZnJvbSAncmVhY3QnO1xuaW1wb3J0IHsgcmVuZGVyLCBzY3JlZW4sIHdhaXRGb3IgfSBmcm9tICdAdGVzdGluZy1saWJyYXJ5L3JlYWN0JztcbmltcG9ydCB1c2VyRXZlbnQgZnJvbSAnQHRlc3RpbmctbGlicmFyeS91c2VyLWV2ZW50JztcbmltcG9ydCB7IGNob2ljZSB9IGZyb20gJy4uLy4uL19fdGVzdHNfXy91dGlscyc7XG5pbXBvcnQgRHJvcGRvd24gZnJvbSAnLi4vZHJvcGRvd24nO1xuXG5kZXNjcmliZSgnRHJvcGRvd24nLCAoKSA9PiB7XG4gIGNvbnN0IG9uQ2hhbmdlID0gamVzdC5mbigpO1xuICBjb25zdCBkZWZhdWx0UHJvcHMgPSB7XG4gICAgb25DaGFuZ2UsXG4gICAgaWQ6ICcxJyxcbiAgICBjb3JyZWN0OiBmYWxzZSxcbiAgICBkaXNhYmxlZDogZmFsc2UsXG4gICAgdmFsdWU6ICdKdW1wZWQnLFxuICAgIGNob2ljZXM6IFtjaG9pY2UoJ0p1bXBlZCcpLCBjaG9pY2UoJ0xhdWdoZWQnKSwgY2hvaWNlKCdTbWlsZWQnKV0sXG4gIH07XG5cbiAgYmVmb3JlRWFjaCgoKSA9PiB7XG4gICAgb25DaGFuZ2UubW9ja0NsZWFyKCk7XG4gIH0pO1xuXG4gIGRlc2NyaWJlKCdyZW5kZXJpbmcnLCAoKSA9PiB7XG4gICAgaXQoJ3JlbmRlcnMgZHJvcGRvd24gd2l0aCBkZWZhdWx0IHByb3BzJywgKCkgPT4ge1xuICAgICAgcmVuZGVyKDxEcm9wZG93biB7Li4uZGVmYXVsdFByb3BzfSAvPik7XG4gICAgICBjb25zdCBidXR0b24gPSBzY3JlZW4uZ2V0QnlSb2xlKCdjb21ib2JveCcpO1xuICAgICAgZXhwZWN0KGJ1dHRvbikudG9CZUluVGhlRG9jdW1lbnQoKTtcbiAgICAgIC8vIEJ1dHRvbiBkaXNwbGF5cyB0aGUgc2VsZWN0ZWQgdmFsdWVcbiAgICAgIGV4cGVjdChidXR0b24pLnRvSGF2ZVRleHRDb250ZW50KCdKdW1wZWQnKTtcbiAgICB9KTtcblxuICAgIGl0KCdyZW5kZXJzIHdpdGggYWxsIGNob2ljZXMgYXMgb3B0aW9ucyB3aGVuIG9wZW5lZCcsIGFzeW5jICgpID0+IHtcbiAgICAgIGNvbnN0IHVzZXIgPSB1c2VyRXZlbnQuc2V0dXAoKTtcbiAgICAgIHJlbmRlcig8RHJvcGRvd24gey4uLmRlZmF1bHRQcm9wc30gLz4pO1xuXG4gICAgICBjb25zdCBidXR0b24gPSBzY3JlZW4uZ2V0QnlSb2xlKCdjb21ib2JveCcpO1xuICAgICAgYXdhaXQgdXNlci5jbGljayhidXR0b24pO1xuXG4gICAgICAvLyBPcHRpb25zIHNob3VsZCBub3cgYmUgdmlzaWJsZSAtIGZpbmQgdGhlbSBieSByb2xlXG4gICAgICBjb25zdCBvcHRpb25zID0gc2NyZWVuLmdldEFsbEJ5Um9sZSgnb3B0aW9uJyk7XG4gICAgICBleHBlY3Qob3B0aW9ucykudG9IYXZlTGVuZ3RoKDMpO1xuICAgICAgLy8gVmVyaWZ5IHRoZSB0ZXh0IGNvbnRlbnQgb2Ygb3B0aW9ucyB1c2luZyBzcGVjaWZpYyBlbGVtZW50c1xuICAgICAgZXhwZWN0KG9wdGlvbnNbMF0pLnRvSGF2ZVRleHRDb250ZW50KCdKdW1wZWQnKTtcbiAgICAgIGV4cGVjdChvcHRpb25zWzFdKS50b0hhdmVUZXh0Q29udGVudCgnTGF1Z2hlZCcpO1xuICAgICAgZXhwZWN0KG9wdGlvbnNbMl0pLnRvSGF2ZVRleHRDb250ZW50KCdTbWlsZWQnKTtcbiAgICB9KTtcblxuICAgIGl0KCdmb2N1c2VzIHRoZSBzZWxlY3RlZCBvcHRpb24gd2hlbiB0aGUgbWVudSBvcGVucycsIGFzeW5jICgpID0+IHtcbiAgICAgIGNvbnN0IHVzZXIgPSB1c2VyRXZlbnQuc2V0dXAoKTtcbiAgICAgIHJlbmRlcig8RHJvcGRvd24gey4uLmRlZmF1bHRQcm9wc30gLz4pO1xuXG4gICAgICBjb25zdCBidXR0b24gPSBzY3JlZW4uZ2V0QnlSb2xlKCdjb21ib2JveCcpO1xuICAgICAgYXdhaXQgdXNlci5jbGljayhidXR0b24pO1xuXG4gICAgICBhd2FpdCB3YWl0Rm9yKCgpID0+IHtcbiAgICAgICAgZXhwZWN0KGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKCdkcm9wZG93bi1vcHRpb24tMS0wJykpLnRvSGF2ZUZvY3VzKCk7XG4gICAgICB9KTtcbiAgICAgIGV4cGVjdChidXR0b24pLnRvSGF2ZUF0dHJpYnV0ZSgnYXJpYS1hY3RpdmVkZXNjZW5kYW50JywgJ2Ryb3Bkb3duLW9wdGlvbi0xLTAnKTtcbiAgICB9KTtcblxuICAgIGl0KCdmb2N1c2VzIGEgbm9uLWZpcnN0IHNlbGVjdGVkIG9wdGlvbiB3aGVuIHRoZSBtZW51IG9wZW5zJywgYXN5bmMgKCkgPT4ge1xuICAgICAgY29uc3QgdXNlciA9IHVzZXJFdmVudC5zZXR1cCgpO1xuICAgICAgcmVuZGVyKDxEcm9wZG93biB7Li4uZGVmYXVsdFByb3BzfSB2YWx1ZT1cIkxhdWdoZWRcIiAvPik7XG5cbiAgICAgIGNvbnN0IGJ1dHRvbiA9IHNjcmVlbi5nZXRCeVJvbGUoJ2NvbWJvYm94Jyk7XG4gICAgICBhd2FpdCB1c2VyLmNsaWNrKGJ1dHRvbik7XG5cbiAgICAgIGF3YWl0IHdhaXRGb3IoKCkgPT4ge1xuICAgICAgICBleHBlY3QoZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoJ2Ryb3Bkb3duLW9wdGlvbi0xLTEnKSkudG9IYXZlRm9jdXMoKTtcbiAgICAgIH0pO1xuICAgICAgZXhwZWN0KGJ1dHRvbikudG9IYXZlQXR0cmlidXRlKCdhcmlhLWFjdGl2ZWRlc2NlbmRhbnQnLCAnZHJvcGRvd24tb3B0aW9uLTEtMScpO1xuICAgIH0pO1xuXG4gICAgaXQoJ2RvZXMgbm90IGhpZ2hsaWdodCBhbiBvcHRpb24gd2hlbiBubyB2YWx1ZSBpcyBzZWxlY3RlZCcsIGFzeW5jICgpID0+IHtcbiAgICAgIGNvbnN0IHVzZXIgPSB1c2VyRXZlbnQuc2V0dXAoKTtcbiAgICAgIHJlbmRlcig8RHJvcGRvd24gey4uLmRlZmF1bHRQcm9wc30gdmFsdWU9e3VuZGVmaW5lZH0gLz4pO1xuXG4gICAgICBjb25zdCBidXR0b24gPSBzY3JlZW4uZ2V0QnlSb2xlKCdjb21ib2JveCcpO1xuICAgICAgYXdhaXQgdXNlci5jbGljayhidXR0b24pO1xuXG4gICAgICBleHBlY3QoYnV0dG9uKS5ub3QudG9IYXZlQXR0cmlidXRlKCdhcmlhLWFjdGl2ZWRlc2NlbmRhbnQnKTtcbiAgICB9KTtcblxuICAgIGl0KCdyZW5kZXJzIGFzIGRpc2FibGVkIHdoZW4gZGlzYWJsZWQgcHJvcCBpcyB0cnVlJywgKCkgPT4ge1xuICAgICAgcmVuZGVyKDxEcm9wZG93biB7Li4uZGVmYXVsdFByb3BzfSBkaXNhYmxlZD17dHJ1ZX0gLz4pO1xuICAgICAgY29uc3QgYnV0dG9uID0gc2NyZWVuLmdldEJ5Um9sZSgnY29tYm9ib3gnKTtcbiAgICAgIGV4cGVjdChidXR0b24pLnRvQmVEaXNhYmxlZCgpO1xuICAgIH0pO1xuXG4gICAgaXQoJ3Nob3dzIGNvcnJlY3Qgc3RhdGUgd2hlbiBjb3JyZWN0IGlzIHRydWUnLCAoKSA9PiB7XG4gICAgICBjb25zdCB7IGNvbnRhaW5lciB9ID0gcmVuZGVyKDxEcm9wZG93biB7Li4uZGVmYXVsdFByb3BzfSBjb3JyZWN0PXt0cnVlfSAvPik7XG4gICAgICBjb25zdCBidXR0b24gPSBzY3JlZW4uZ2V0QnlSb2xlKCdjb21ib2JveCcpO1xuICAgICAgZXhwZWN0KGJ1dHRvbikudG9CZUluVGhlRG9jdW1lbnQoKTtcbiAgICB9KTtcbiAgfSk7XG5cbiAgZGVzY3JpYmUoJ3VzZXIgaW50ZXJhY3Rpb25zJywgKCkgPT4ge1xuICAgIGl0KCdjYWxscyBvbkNoYW5nZSB3aGVuIHVzZXIgc2VsZWN0cyBhIGRpZmZlcmVudCBvcHRpb24nLCBhc3luYyAoKSA9PiB7XG4gICAgICBjb25zdCB1c2VyID0gdXNlckV2ZW50LnNldHVwKCk7XG4gICAgICByZW5kZXIoPERyb3Bkb3duIHsuLi5kZWZhdWx0UHJvcHN9IC8+KTtcblxuICAgICAgLy8gQ2xpY2sgYnV0dG9uIHRvIG9wZW4gbWVudVxuICAgICAgY29uc3QgYnV0dG9uID0gc2NyZWVuLmdldEJ5Um9sZSgnY29tYm9ib3gnKTtcbiAgICAgIGF3YWl0IHVzZXIuY2xpY2soYnV0dG9uKTtcblxuICAgICAgLy8gRmluZCB0aGUgb3B0aW9uIGJ5IGdldHRpbmcgYWxsIG9wdGlvbnMgYW5kIHNlbGVjdGluZyB0aGUgb25lIHdpdGggXCJMYXVnaGVkXCIgdGV4dFxuICAgICAgY29uc3Qgb3B0aW9ucyA9IHNjcmVlbi5nZXRBbGxCeVJvbGUoJ29wdGlvbicpO1xuICAgICAgY29uc3QgbGF1Z2hlZE9wdGlvbiA9IG9wdGlvbnMuZmluZCgob3B0KSA9PiBvcHQudGV4dENvbnRlbnQuaW5jbHVkZXMoJ0xhdWdoZWQnKSk7XG4gICAgICBhd2FpdCB1c2VyLmNsaWNrKGxhdWdoZWRPcHRpb24pO1xuXG4gICAgICBleHBlY3Qob25DaGFuZ2UpLnRvSGF2ZUJlZW5DYWxsZWRXaXRoKCcxJywgJ0xhdWdoZWQnKTtcbiAgICB9KTtcblxuICAgIGl0KCdjYWxscyBvbkNoYW5nZSB3aXRoIGNvcnJlY3QgdmFsdWUnLCBhc3luYyAoKSA9PiB7XG4gICAgICBjb25zdCB1c2VyID0gdXNlckV2ZW50LnNldHVwKCk7XG4gICAgICByZW5kZXIoPERyb3Bkb3duIHsuLi5kZWZhdWx0UHJvcHN9IC8+KTtcblxuICAgICAgLy8gQ2xpY2sgYnV0dG9uIHRvIG9wZW4gbWVudVxuICAgICAgY29uc3QgYnV0dG9uID0gc2NyZWVuLmdldEJ5Um9sZSgnY29tYm9ib3gnKTtcbiAgICAgIGF3YWl0IHVzZXIuY2xpY2soYnV0dG9uKTtcblxuICAgICAgLy8gRmluZCB0aGUgb3B0aW9uIGJ5IGdldHRpbmcgYWxsIG9wdGlvbnMgYW5kIHNlbGVjdGluZyB0aGUgb25lIHdpdGggXCJTbWlsZWRcIiB0ZXh0XG4gICAgICBjb25zdCBvcHRpb25zID0gc2NyZWVuLmdldEFsbEJ5Um9sZSgnb3B0aW9uJyk7XG4gICAgICBjb25zdCBzbWlsZWRPcHRpb24gPSBvcHRpb25zLmZpbmQoKG9wdCkgPT4gb3B0LnRleHRDb250ZW50LmluY2x1ZGVzKCdTbWlsZWQnKSk7XG4gICAgICBhd2FpdCB1c2VyLmNsaWNrKHNtaWxlZE9wdGlvbik7XG5cbiAgICAgIGV4cGVjdChvbkNoYW5nZSkudG9IYXZlQmVlbkNhbGxlZFdpdGgoJzEnLCAnU21pbGVkJyk7XG4gICAgfSk7XG4gIH0pO1xufSk7XG4iXSwibWFwcGluZ3MiOiI7Ozs7Ozs7QUFBQSxJQUFBQSxLQUFBLEdBQUFDLHVCQUFBLENBQUFDLE9BQUE7QUFDQSxJQUFBQyxPQUFBLEdBQUFELE9BQUE7QUFDQSxJQUFBRSxVQUFBLEdBQUFDLHNCQUFBLENBQUFILE9BQUE7QUFDQSxJQUFBSSxNQUFBLEdBQUFKLE9BQUE7QUFDQSxJQUFBSyxTQUFBLEdBQUFGLHNCQUFBLENBQUFILE9BQUE7QUFBbUMsU0FBQUQsd0JBQUFPLENBQUEsRUFBQUMsQ0FBQSw2QkFBQUMsT0FBQSxNQUFBQyxDQUFBLE9BQUFELE9BQUEsSUFBQUUsQ0FBQSxPQUFBRixPQUFBLFlBQUFULHVCQUFBLFlBQUFBLHdCQUFBTyxDQUFBLEVBQUFDLENBQUEsU0FBQUEsQ0FBQSxJQUFBRCxDQUFBLElBQUFBLENBQUEsQ0FBQUssVUFBQSxTQUFBTCxDQUFBLE1BQUFNLENBQUEsRUFBQUMsQ0FBQSxFQUFBQyxDQUFBLEtBQUFDLFNBQUEsbUJBQUFULENBQUEsaUJBQUFBLENBQUEsZ0JBQUFVLE9BQUEsQ0FBQVYsQ0FBQSwwQkFBQUEsQ0FBQSxTQUFBUSxDQUFBLE1BQUFGLENBQUEsR0FBQUwsQ0FB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
@@ -0,0 +1,129 @@
1
+ "use strict";
2
+
3
+ var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
4
+ var _typeof = require("@babel/runtime/helpers/typeof");
5
+ var _regenerator = _interopRequireDefault(require("@babel/runtime/regenerator"));
6
+ var _asyncToGenerator2 = _interopRequireDefault(require("@babel/runtime/helpers/asyncToGenerator"));
7
+ var _extends2 = _interopRequireDefault(require("@babel/runtime/helpers/extends"));
8
+ var React = _interopRequireWildcard(require("react"));
9
+ var _react2 = require("@testing-library/react");
10
+ var _userEvent = _interopRequireDefault(require("@testing-library/user-event"));
11
+ var _input = _interopRequireDefault(require("../input"));
12
+ function _interopRequireWildcard(e, t) { if ("function" == typeof WeakMap) var r = new WeakMap(), n = new WeakMap(); return (_interopRequireWildcard = function _interopRequireWildcard(e, t) { if (!t && e && e.__esModule) return e; var o, i, f = { __proto__: null, "default": e }; if (null === e || "object" != _typeof(e) && "function" != typeof e) return f; if (o = t ? n : r) { if (o.has(e)) return o.get(e); o.set(e, f); } for (var _t in e) "default" !== _t && {}.hasOwnProperty.call(e, _t) && ((i = (o = Object.defineProperty) && Object.getOwnPropertyDescriptor(e, _t)) && (i.get || i.set) ? o(f, _t, i) : f[_t] = e[_t]); return f; })(e, t); }
13
+ // Mock CorrectInput to simplify testing
14
+ jest.mock('../correct-input', function () {
15
+ return function CorrectInput(_ref) {
16
+ var value = _ref.value,
17
+ onChange = _ref.onChange,
18
+ disabled = _ref.disabled,
19
+ correct = _ref.correct,
20
+ variant = _ref.variant;
21
+ return /*#__PURE__*/React.createElement("input", {
22
+ "data-testid": "correct-input",
23
+ value: value || '',
24
+ onChange: onChange,
25
+ disabled: disabled,
26
+ "data-correct": correct,
27
+ "data-variant": variant
28
+ });
29
+ };
30
+ });
31
+ describe('Input', function () {
32
+ var onChange = jest.fn();
33
+ var defaultProps = {
34
+ disabled: false,
35
+ correct: false,
36
+ value: 'Cow',
37
+ id: '1',
38
+ onChange: onChange
39
+ };
40
+ beforeEach(function () {
41
+ onChange.mockClear();
42
+ });
43
+ describe('rendering', function () {
44
+ it('renders with default props', function () {
45
+ (0, _react2.render)(/*#__PURE__*/React.createElement(_input["default"], defaultProps));
46
+ var input = _react2.screen.getByTestId('correct-input');
47
+ expect(input).toBeInTheDocument();
48
+ expect(input).toHaveValue('Cow');
49
+ expect(input).not.toBeDisabled();
50
+ expect(input).toHaveAttribute('data-correct', 'false');
51
+ });
52
+ it('renders as disabled when disabled prop is true', function () {
53
+ (0, _react2.render)(/*#__PURE__*/React.createElement(_input["default"], (0, _extends2["default"])({}, defaultProps, {
54
+ disabled: true
55
+ })));
56
+ var input = _react2.screen.getByTestId('correct-input');
57
+ expect(input).toBeDisabled();
58
+ });
59
+ it('renders with correct state', function () {
60
+ (0, _react2.render)(/*#__PURE__*/React.createElement(_input["default"], (0, _extends2["default"])({}, defaultProps, {
61
+ correct: true
62
+ })));
63
+ var input = _react2.screen.getByTestId('correct-input');
64
+ expect(input).toHaveAttribute('data-correct', 'true');
65
+ });
66
+ it('shows correct answer when showCorrectAnswer is true', function () {
67
+ (0, _react2.render)(/*#__PURE__*/React.createElement(_input["default"], (0, _extends2["default"])({}, defaultProps, {
68
+ showCorrectAnswer: true
69
+ })));
70
+ var input = _react2.screen.getByTestId('correct-input');
71
+ expect(input).toHaveAttribute('data-correct', 'true');
72
+ });
73
+ });
74
+ describe('user interactions', function () {
75
+ it('calls onChange with id and value when user types', /*#__PURE__*/(0, _asyncToGenerator2["default"])(/*#__PURE__*/_regenerator["default"].mark(function _callee() {
76
+ var user, input;
77
+ return _regenerator["default"].wrap(function (_context) {
78
+ while (1) switch (_context.prev = _context.next) {
79
+ case 0:
80
+ user = _userEvent["default"].setup();
81
+ (0, _react2.render)(/*#__PURE__*/React.createElement(_input["default"], (0, _extends2["default"])({}, defaultProps, {
82
+ value: ""
83
+ })));
84
+ input = _react2.screen.getByTestId('correct-input');
85
+ _context.next = 1;
86
+ return user.type(input, '20');
87
+ case 1:
88
+ // userEvent.type types character by character, so onChange is called for each character
89
+ expect(onChange).toHaveBeenCalled();
90
+ expect(onChange).toHaveBeenCalledTimes(2);
91
+ // Check the last call has both characters
92
+ expect(onChange).toHaveBeenLastCalledWith('1', '0');
93
+ case 2:
94
+ case "end":
95
+ return _context.stop();
96
+ }
97
+ }, _callee);
98
+ })));
99
+ it('calls onChange with updated value', /*#__PURE__*/(0, _asyncToGenerator2["default"])(/*#__PURE__*/_regenerator["default"].mark(function _callee2() {
100
+ var user, input;
101
+ return _regenerator["default"].wrap(function (_context2) {
102
+ while (1) switch (_context2.prev = _context2.next) {
103
+ case 0:
104
+ user = _userEvent["default"].setup();
105
+ (0, _react2.render)(/*#__PURE__*/React.createElement(_input["default"], defaultProps));
106
+ input = _react2.screen.getByTestId('correct-input');
107
+ _context2.next = 1;
108
+ return user.clear(input);
109
+ case 1:
110
+ _context2.next = 2;
111
+ return user.type(input, 'New Value');
112
+ case 2:
113
+ // userEvent.type types character by character
114
+ // After clear, we start with empty string, and each character is typed
115
+ // The last call should have the full accumulated value up to the last character
116
+ expect(onChange).toHaveBeenCalled();
117
+ // With clear + "New Value", onChange is called for clearing ("") and each typed character
118
+ // The value accumulated in the input element after typing will be "CowNew Value"
119
+ // because the component starts with value="Cow" and we clear then type
120
+ expect(onChange.mock.calls.length).toBeGreaterThan(0);
121
+ case 3:
122
+ case "end":
123
+ return _context2.stop();
124
+ }
125
+ }, _callee2);
126
+ })));
127
+ });
128
+ });
129
+ //# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJuYW1lcyI6WyJSZWFjdCIsIl9pbnRlcm9wUmVxdWlyZVdpbGRjYXJkIiwicmVxdWlyZSIsIl9yZWFjdDIiLCJfdXNlckV2ZW50IiwiX2ludGVyb3BSZXF1aXJlRGVmYXVsdCIsIl9pbnB1dCIsImUiLCJ0IiwiV2Vha01hcCIsInIiLCJuIiwiX19lc01vZHVsZSIsIm8iLCJpIiwiZiIsIl9fcHJvdG9fXyIsIl90eXBlb2YiLCJoYXMiLCJnZXQiLCJzZXQiLCJfdCIsImhhc093blByb3BlcnR5IiwiY2FsbCIsIk9iamVjdCIsImRlZmluZVByb3BlcnR5IiwiZ2V0T3duUHJvcGVydHlEZXNjcmlwdG9yIiwiamVzdCIsIm1vY2siLCJDb3JyZWN0SW5wdXQiLCJfcmVmIiwidmFsdWUiLCJvbkNoYW5nZSIsImRpc2FibGVkIiwiY29ycmVjdCIsInZhcmlhbnQiLCJjcmVhdGVFbGVtZW50IiwiZGVzY3JpYmUiLCJmbiIsImRlZmF1bHRQcm9wcyIsImlkIiwiYmVmb3JlRWFjaCIsIm1vY2tDbGVhciIsIml0IiwicmVuZGVyIiwiaW5wdXQiLCJzY3JlZW4iLCJnZXRCeVRlc3RJZCIsImV4cGVjdCIsInRvQmVJblRoZURvY3VtZW50IiwidG9IYXZlVmFsdWUiLCJub3QiLCJ0b0JlRGlzYWJsZWQiLCJ0b0hhdmVBdHRyaWJ1dGUiLCJfZXh0ZW5kczIiLCJzaG93Q29ycmVjdEFuc3dlciIsIl9hc3luY1RvR2VuZXJhdG9yMiIsIl9yZWdlbmVyYXRvciIsIm1hcmsiLCJfY2FsbGVlIiwidXNlciIsIndyYXAiLCJfY29udGV4dCIsInByZXYiLCJuZXh0IiwidXNlckV2ZW50Iiwic2V0dXAiLCJ0eXBlIiwidG9IYXZlQmVlbkNhbGxlZCIsInRvSGF2ZUJlZW5DYWxsZWRUaW1lcyIsInRvSGF2ZUJlZW5MYXN0Q2FsbGVkV2l0aCIsInN0b3AiLCJfY2FsbGVlMiIsIl9jb250ZXh0MiIsImNsZWFyIiwiY2FsbHMiLCJsZW5ndGgiLCJ0b0JlR3JlYXRlclRoYW4iXSwic291cmNlcyI6WyIuLi8uLi8uLi9zcmMvY29tcG9uZW50cy9fX3Rlc3RzX18vaW5wdXQudGVzdC5qcyJdLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgKiBhcyBSZWFjdCBmcm9tICdyZWFjdCc7XG5pbXBvcnQgeyByZW5kZXIsIHNjcmVlbiB9IGZyb20gJ0B0ZXN0aW5nLWxpYnJhcnkvcmVhY3QnO1xuaW1wb3J0IHVzZXJFdmVudCBmcm9tICdAdGVzdGluZy1saWJyYXJ5L3VzZXItZXZlbnQnO1xuaW1wb3J0IElucHV0IGZyb20gJy4uL2lucHV0JztcblxuLy8gTW9jayBDb3JyZWN0SW5wdXQgdG8gc2ltcGxpZnkgdGVzdGluZ1xuamVzdC5tb2NrKCcuLi9jb3JyZWN0LWlucHV0JywgKCkgPT4ge1xuICByZXR1cm4gZnVuY3Rpb24gQ29ycmVjdElucHV0KHsgdmFsdWUsIG9uQ2hhbmdlLCBkaXNhYmxlZCwgY29ycmVjdCwgdmFyaWFudCB9KSB7XG4gICAgcmV0dXJuIChcbiAgICAgIDxpbnB1dFxuICAgICAgICBkYXRhLXRlc3RpZD1cImNvcnJlY3QtaW5wdXRcIlxuICAgICAgICB2YWx1ZT17dmFsdWUgfHwgJyd9XG4gICAgICAgIG9uQ2hhbmdlPXtvbkNoYW5nZX1cbiAgICAgICAgZGlzYWJsZWQ9e2Rpc2FibGVkfVxuICAgICAgICBkYXRhLWNvcnJlY3Q9e2NvcnJlY3R9XG4gICAgICAgIGRhdGEtdmFyaWFudD17dmFyaWFudH1cbiAgICAgIC8+XG4gICAgKTtcbiAgfTtcbn0pO1xuXG5kZXNjcmliZSgnSW5wdXQnLCAoKSA9PiB7XG4gIGNvbnN0IG9uQ2hhbmdlID0gamVzdC5mbigpO1xuICBjb25zdCBkZWZhdWx0UHJvcHMgPSB7XG4gICAgZGlzYWJsZWQ6IGZhbHNlLFxuICAgIGNvcnJlY3Q6IGZhbHNlLFxuICAgIHZhbHVlOiAnQ293JyxcbiAgICBpZDogJzEnLFxuICAgIG9uQ2hhbmdlLFxuICB9O1xuXG4gIGJlZm9yZUVhY2goKCkgPT4ge1xuICAgIG9uQ2hhbmdlLm1vY2tDbGVhcigpO1xuICB9KTtcblxuICBkZXNjcmliZSgncmVuZGVyaW5nJywgKCkgPT4ge1xuICAgIGl0KCdyZW5kZXJzIHdpdGggZGVmYXVsdCBwcm9wcycsICgpID0+IHtcbiAgICAgIHJlbmRlcig8SW5wdXQgey4uLmRlZmF1bHRQcm9wc30gLz4pO1xuICAgICAgY29uc3QgaW5wdXQgPSBzY3JlZW4uZ2V0QnlUZXN0SWQoJ2NvcnJlY3QtaW5wdXQnKTtcblxuICAgICAgZXhwZWN0KGlucHV0KS50b0JlSW5UaGVEb2N1bWVudCgpO1xuICAgICAgZXhwZWN0KGlucHV0KS50b0hhdmVWYWx1ZSgnQ293Jyk7XG4gICAgICBleHBlY3QoaW5wdXQpLm5vdC50b0JlRGlzYWJsZWQoKTtcbiAgICAgIGV4cGVjdChpbnB1dCkudG9IYXZlQXR0cmlidXRlKCdkYXRhLWNvcnJlY3QnLCAnZmFsc2UnKTtcbiAgICB9KTtcblxuICAgIGl0KCdyZW5kZXJzIGFzIGRpc2FibGVkIHdoZW4gZGlzYWJsZWQgcHJvcCBpcyB0cnVlJywgKCkgPT4ge1xuICAgICAgcmVuZGVyKDxJbnB1dCB7Li4uZGVmYXVsdFByb3BzfSBkaXNhYmxlZD17dHJ1ZX0gLz4pO1xuICAgICAgY29uc3QgaW5wdXQgPSBzY3JlZW4uZ2V0QnlUZXN0SWQoJ2NvcnJlY3QtaW5wdXQnKTtcblxuICAgICAgZXhwZWN0KGlucHV0KS50b0JlRGlzYWJsZWQoKTtcbiAgICB9KTtcblxuICAgIGl0KCdyZW5kZXJzIHdpdGggY29ycmVjdCBzdGF0ZScsICgpID0+IHtcbiAgICAgIHJlbmRlcig8SW5wdXQgey4uLmRlZmF1bHRQcm9wc30gY29ycmVjdD17dHJ1ZX0gLz4pO1xuICAgICAgY29uc3QgaW5wdXQgPSBzY3JlZW4uZ2V0QnlUZXN0SWQoJ2NvcnJlY3QtaW5wdXQnKTtcblxuICAgICAgZXhwZWN0KGlucHV0KS50b0hhdmVBdHRyaWJ1dGUoJ2RhdGEtY29ycmVjdCcsICd0cnVlJyk7XG4gICAgfSk7XG5cbiAgICBpdCgnc2hvd3MgY29ycmVjdCBhbnN3ZXIgd2hlbiBzaG93Q29ycmVjdEFuc3dlciBpcyB0cnVlJywgKCkgPT4ge1xuICAgICAgcmVuZGVyKDxJbnB1dCB7Li4uZGVmYXVsdFByb3BzfSBzaG93Q29ycmVjdEFuc3dlcj17dHJ1ZX0gLz4pO1xuICAgICAgY29uc3QgaW5wdXQgPSBzY3JlZW4uZ2V0QnlUZXN0SWQoJ2NvcnJlY3QtaW5wdXQnKTtcblxuICAgICAgZXhwZWN0KGlucHV0KS50b0hhdmVBdHRyaWJ1dGUoJ2RhdGEtY29ycmVjdCcsICd0cnVlJyk7XG4gICAgfSk7XG4gIH0pO1xuXG4gIGRlc2NyaWJlKCd1c2VyIGludGVyYWN0aW9ucycsICgpID0+IHtcbiAgICBpdCgnY2FsbHMgb25DaGFuZ2Ugd2l0aCBpZCBhbmQgdmFsdWUgd2hlbiB1c2VyIHR5cGVzJywgYXN5bmMgKCkgPT4ge1xuICAgICAgY29uc3QgdXNlciA9IHVzZXJFdmVudC5zZXR1cCgpO1xuICAgICAgcmVuZGVyKDxJbnB1dCB7Li4uZGVmYXVsdFByb3BzfSB2YWx1ZT1cIlwiIC8+KTtcblxuICAgICAgY29uc3QgaW5wdXQgPSBzY3JlZW4uZ2V0QnlUZXN0SWQoJ2NvcnJlY3QtaW5wdXQnKTtcbiAgICAgIGF3YWl0IHVzZXIudHlwZShpbnB1dCwgJzIwJyk7XG5cbiAgICAgIC8vIHVzZXJFdmVudC50eXBlIHR5cGVzIGNoYXJhY3RlciBieSBjaGFyYWN0ZXIsIHNvIG9uQ2hhbmdlIGlzIGNhbGxlZCBmb3IgZWFjaCBjaGFyYWN0ZXJcbiAgICAgIGV4cGVjdChvbkNoYW5nZSkudG9IYXZlQmVlbkNhbGxlZCgpO1xuICAgICAgZXhwZWN0KG9uQ2hhbmdlKS50b0hhdmVCZWVuQ2FsbGVkVGltZXMoMik7XG4gICAgICAvLyBDaGVjayB0aGUgbGFzdCBjYWxsIGhhcyBib3RoIGNoYXJhY3RlcnNcbiAgICAgIGV4cGVjdChvbkNoYW5nZSkudG9IYXZlQmVlbkxhc3RDYWxsZWRXaXRoKCcxJywgJzAnKTtcbiAgICB9KTtcblxuICAgIGl0KCdjYWxscyBvbkNoYW5nZSB3aXRoIHVwZGF0ZWQgdmFsdWUnLCBhc3luYyAoKSA9PiB7XG4gICAgICBjb25zdCB1c2VyID0gdXNlckV2ZW50LnNldHVwKCk7XG4gICAgICByZW5kZXIoPElucHV0IHsuLi5kZWZhdWx0UHJvcHN9IC8+KTtcblxuICAgICAgY29uc3QgaW5wdXQgPSBzY3JlZW4uZ2V0QnlUZXN0SWQoJ2NvcnJlY3QtaW5wdXQnKTtcbiAgICAgIGF3YWl0IHVzZXIuY2xlYXIoaW5wdXQpO1xuICAgICAgYXdhaXQgdXNlci50eXBlKGlucHV0LCAnTmV3IFZhbHVlJyk7XG5cbiAgICAgIC8vIHVzZXJFdmVudC50eXBlIHR5cGVzIGNoYXJhY3RlciBieSBjaGFyYWN0ZXJcbiAgICAgIC8vIEFmdGVyIGNsZWFyLCB3ZSBzdGFydCB3aXRoIGVtcHR5IHN0cmluZywgYW5kIGVhY2ggY2hhcmFjdGVyIGlzIHR5cGVkXG4gICAgICAvLyBUaGUgbGFzdCBjYWxsIHNob3VsZCBoYXZlIHRoZSBmdWxsIGFjY3VtdWxhdGVkIHZhbHVlIHVwIHRvIHRoZSBsYXN0IGNoYXJhY3RlclxuICAgICAgZXhwZWN0KG9uQ2hhbmdlKS50b0hhdmVCZWVuQ2FsbGVkKCk7XG4gICAgICAvLyBXaXRoIGNsZWFyICsgXCJOZXcgVmFsdWVcIiwgb25DaGFuZ2UgaXMgY2FsbGVkIGZvciBjbGVhcmluZyAoXCJcIikgYW5kIGVhY2ggdHlwZWQgY2hhcmFjdGVyXG4gICAgICAvLyBUaGUgdmFsdWUgYWNjdW11bGF0ZWQgaW4gdGhlIGlucHV0IGVsZW1lbnQgYWZ0ZXIgdHlwaW5nIHdpbGwgYmUgXCJDb3dOZXcgVmFsdWVcIlxuICAgICAgLy8gYmVjYXVzZSB0aGUgY29tcG9uZW50IHN0YXJ0cyB3aXRoIHZhbHVlPVwiQ293XCIgYW5kIHdlIGNsZWFyIHRoZW4gdHlwZVxuICAgICAgZXhwZWN0KG9uQ2hhbmdlLm1vY2suY2FsbHMubGVuZ3RoKS50b0JlR3JlYXRlclRoYW4oMCk7XG4gICAgfSk7XG4gIH0pO1xufSk7XG4iXSwibWFwcGluZ3MiOiI7Ozs7Ozs7QUFBQSxJQUFBQSxLQUFBLEdBQUFDLHVCQUFBLENB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
@@ -14,6 +14,7 @@ var _propTypes = _interopRequireDefault(require("prop-types"));
14
14
  var _mathRendering = require("@pie-lib/math-rendering");
15
15
  var _debug = _interopRequireDefault(require("debug"));
16
16
  var _core = require("@dnd-kit/core");
17
+ var _utilities = require("@dnd-kit/utilities");
17
18
  var _styles = require("@mui/material/styles");
18
19
  var _Chip = _interopRequireDefault(require("@mui/material/Chip"));
19
20
  var _classnames = _interopRequireDefault(require("classnames"));
@@ -25,31 +26,21 @@ function _objectSpread(e) { for (var r = 1; r < arguments.length; r++) { var t =
25
26
  var log = (0, _debug["default"])('pie-lib:mask-markup:blank');
26
27
  var StyledContent = (0, _styles.styled)('span')(function (_ref) {
27
28
  var dragged = _ref.dragged,
28
- over = _ref.over,
29
- selected = _ref.selected,
30
- showsPointerCursor = _ref.showsPointerCursor;
31
- return _objectSpread(_objectSpread(_objectSpread({
29
+ over = _ref.over;
30
+ return _objectSpread(_objectSpread({
32
31
  border: "solid 0px ".concat(_renderUi.color.primary()),
33
32
  minWidth: '200px',
33
+ touchAction: 'none',
34
34
  overflow: 'hidden',
35
35
  whiteSpace: 'nowrap',
36
- opacity: 1,
37
- cursor: 'default'
36
+ opacity: 1
38
37
  }, over && {
39
38
  whiteSpace: 'nowrap',
40
39
  overflow: 'hidden'
41
- }), (dragged || selected) && {
40
+ }), dragged && {
42
41
  opacity: 0.5
43
- }), showsPointerCursor && {
44
- '&:hover': {
45
- cursor: 'pointer'
46
- }
47
42
  });
48
43
  });
49
- var StyledDragHandle = (0, _styles.styled)('span')({
50
- display: 'inline-flex',
51
- touchAction: 'none'
52
- });
53
44
  var StyledChip = (0, _styles.styled)(_Chip["default"])(function () {
54
45
  return {
55
46
  backgroundColor: _renderUi.color.background(),
@@ -342,43 +333,24 @@ function DragDropBlank(_ref3) {
342
333
  onChange = _ref3.onChange,
343
334
  emptyResponseAreaWidth = _ref3.emptyResponseAreaWidth,
344
335
  emptyResponseAreaHeight = _ref3.emptyResponseAreaHeight,
345
- instanceId = _ref3.instanceId,
346
- selectedItem = _ref3.selectedItem,
347
- onSelectClick = _ref3.onSelectClick,
348
- onPlacementClick = _ref3.onPlacementClick;
349
- var _useState3 = (0, _react.useState)(false),
350
- _useState4 = (0, _slicedToArray2["default"])(_useState3, 2),
351
- isHovered = _useState4[0],
352
- setIsHovered = _useState4[1];
353
- var dragData = {
354
- id: id,
355
- choice: choice,
356
- instanceId: instanceId,
357
- fromChoice: false,
358
- // This is from a blank, not from choices
359
- type: 'MaskBlank'
360
- };
361
-
336
+ instanceId = _ref3.instanceId;
362
337
  // Setup draggable functionality
363
338
  var _useDraggable = (0, _core.useDraggable)({
364
339
  id: "mask-blank-drag-".concat(id),
365
340
  disabled: disabled || !choice,
366
- data: dragData,
367
- // dnd-kit's own `attributes` default tabIndex to 0 unconditionally, even when
368
- // `disabled` — so a non-draggable (empty) blank stays a native Tab stop of its own.
369
- // For a drop-zone (droppable blank), that duplicates the outer wrapper's own tab stop
370
- // (see isNativeTabStop below) at the exact same position, so Tab/Shift+Tab has to
371
- // pass through both to move anywhere visibly, making every other press look like a
372
- // no-op. Drop it out of the tab order here whenever it isn't independently
373
- // reachable/interactive, leaving the outer wrapper (for an empty blank) or
374
- // nothing (for a disabled blank) as the sole stop.
375
- attributes: {
376
- tabIndex: choice && !disabled ? 0 : -1
341
+ data: {
342
+ id: id,
343
+ choice: choice,
344
+ instanceId: instanceId,
345
+ fromChoice: false,
346
+ // This is from a blank, not from choices
347
+ type: 'MaskBlank'
377
348
  }
378
349
  }),
379
350
  dragAttributes = _useDraggable.attributes,
380
351
  dragListeners = _useDraggable.listeners,
381
352
  setDragNodeRef = _useDraggable.setNodeRef,
353
+ transform = _useDraggable.transform,
382
354
  isDragging = _useDraggable.isDragging;
383
355
 
384
356
  // Setup droppable functionality
@@ -393,79 +365,33 @@ function DragDropBlank(_ref3) {
393
365
  setDropNodeRef = _useDroppable.setNodeRef,
394
366
  isOver = _useDroppable.isOver,
395
367
  dragItem = _useDroppable.active;
396
- var isSelected = !!selectedItem && selectedItem.fromChoice === false && selectedItem.id === id;
397
- var handleClick = function handleClick() {
398
- if (disabled) return;
399
- if (isSelected) {
400
- // Clicking this blank's already-selected content again deselects it.
401
- onSelectClick === null || onSelectClick === void 0 || onSelectClick(dragData);
402
- } else if (selectedItem) {
403
- // Something else is selected — place it here, whether this blank is currently
404
- // empty or already filled (the same commitPlacement logic drag-and-drop uses).
405
- onPlacementClick === null || onPlacementClick === void 0 || onPlacementClick(id);
406
- } else if (choice) {
407
- // Nothing selected yet, and this blank holds an answer — select it for moving
408
- // elsewhere, the same way Tab+Space/Enter does.
409
- onSelectClick === null || onSelectClick === void 0 || onSelectClick(dragData);
410
- }
411
368
 
412
- // Empty blank clicked with nothing selected: nothing to place or select.
369
+ // Combine refs for both drag and drop
370
+ var setNodeRef = function setNodeRef(node) {
371
+ setDragNodeRef(node);
372
+ setDropNodeRef(node);
413
373
  };
414
-
415
- // An empty blank isn't draggable, so dnd-kit's own attributes (only applied to the
416
- // inner node, and only when draggable) never make it tabbable — this outer wrapper
417
- // needs its own focus/activation handling so "select a choice, then Tab to a blank
418
- // and press Space/Enter" works even when the blank is empty. This is independent of,
419
- // and doesn't change, the existing in-drag Tab-cycling (that's driven by an active
420
- // dnd-kit drag, not native focus).
421
- //
422
- // Only made a native Tab stop when NOT draggable (i.e. empty): when the blank is
423
- // filled, the inner node is already independently tabbable via dnd-kit's own
424
- // attributes for the existing pick-up-to-move gesture, and adding a second, outer Tab
425
- // stop for the same visual chip would add an extra stop to the existing Tab order —
426
- // the same double-tab-stop bug already found and fixed once in match-list/image-
427
- // cloze-association's equivalent code.
428
- var isNativeTabStop = !choice && !disabled;
429
- var isInnerDraggable = !!choice && !disabled;
430
- var handleKeyDown = function handleKeyDown(e) {
431
- if (e.code === 'Space' || e.code === 'Enter') {
432
- e.preventDefault();
433
- handleClick();
434
- }
374
+ var style = {
375
+ transform: _utilities.CSS.Translate.toString(transform)
435
376
  };
436
- var hasSelection = !!selectedItem;
437
- var showsHoverEffect = isOver || hasSelection && isHovered && !disabled;
438
- return /*#__PURE__*/_react["default"].createElement(StyledContent, {
439
- ref: setDropNodeRef,
440
- role: isNativeTabStop ? 'button' : undefined,
441
- tabIndex: isNativeTabStop ? 0 : -1,
442
- onClick: handleClick,
443
- onKeyDown: isNativeTabStop ? handleKeyDown : undefined,
444
- onMouseEnter: function onMouseEnter() {
445
- return setIsHovered(true);
446
- },
447
- onMouseLeave: function onMouseLeave() {
448
- return setIsHovered(false);
449
- },
377
+ return /*#__PURE__*/_react["default"].createElement(StyledContent, (0, _extends2["default"])({
378
+ ref: setNodeRef,
379
+ style: style,
450
380
  dragged: isDragging,
451
- over: showsHoverEffect,
452
- selected: isSelected,
453
- showsPointerCursor: hasSelection && !disabled
454
- }, /*#__PURE__*/_react["default"].createElement(StyledDragHandle, (0, _extends2["default"])({
455
- ref: setDragNodeRef
456
- }, isInnerDraggable ? dragAttributes : {}, dragListeners), /*#__PURE__*/_react["default"].createElement(BlankContent, {
381
+ over: isOver
382
+ }, dragAttributes, dragListeners), /*#__PURE__*/_react["default"].createElement(BlankContent, {
457
383
  id: id,
458
384
  disabled: disabled,
459
385
  duplicates: duplicates,
460
386
  choice: choice,
461
- isOver: showsHoverEffect,
387
+ isOver: isOver,
462
388
  dragItem: dragItem === null || dragItem === void 0 || (_dragItem$data = dragItem.data) === null || _dragItem$data === void 0 ? void 0 : _dragItem$data.current,
463
389
  correct: correct,
464
390
  onChange: onChange,
465
391
  emptyResponseAreaWidth: emptyResponseAreaWidth,
466
392
  emptyResponseAreaHeight: emptyResponseAreaHeight,
467
393
  instanceId: instanceId
468
- })));
394
+ }));
469
395
  }
470
396
  DragDropBlank.defaultProps = {
471
397
  emptyResponseAreaWidth: 0,
@@ -480,10 +406,7 @@ DragDropBlank.propTypes = {
480
406
  onChange: _propTypes["default"].func,
481
407
  emptyResponseAreaWidth: _propTypes["default"].oneOfType([_propTypes["default"].string, _propTypes["default"].number]),
482
408
  emptyResponseAreaHeight: _propTypes["default"].oneOfType([_propTypes["default"].string, _propTypes["default"].number]),
483
- instanceId: _propTypes["default"].string,
484
- selectedItem: _propTypes["default"].object,
485
- onSelectClick: _propTypes["default"].func,
486
- onPlacementClick: _propTypes["default"].func
409
+ instanceId: _propTypes["default"].string
487
410
  };
488
411
  var _default = exports["default"] = DragDropBlank;
489
412
  //# sourceMappingURL=blank.js.map