@pie-lib/mask-markup 3.1.0-beta.5 → 3.1.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 (51) hide show
  1. package/CHANGELOG.md +83 -0
  2. package/LICENSE.md +5 -0
  3. package/lib/choices/choice.js +24 -6
  4. package/lib/choices/choice.js.map +1 -1
  5. package/lib/choices/index.js +32 -9
  6. package/lib/choices/index.js.map +1 -1
  7. package/lib/components/blank.js +106 -29
  8. package/lib/components/blank.js.map +1 -1
  9. package/lib/components/dropdown.js +2 -9
  10. package/lib/components/dropdown.js.map +1 -1
  11. package/lib/drag-in-the-blank.js +139 -30
  12. package/lib/drag-in-the-blank.js.map +1 -1
  13. package/lib/keyboard-coordinates.js +156 -0
  14. package/lib/keyboard-coordinates.js.map +1 -0
  15. package/lib/mask.js +20 -15
  16. package/lib/mask.js.map +1 -1
  17. package/package.json +6 -6
  18. package/src/__tests__/drag-in-the-blank.test.js +147 -2
  19. package/src/__tests__/keyboard-coordinates.test.js +202 -0
  20. package/src/__tests__/mask.test.js +98 -0
  21. package/src/choices/__tests__/index.test.js +104 -1
  22. package/src/choices/choice.jsx +16 -3
  23. package/src/choices/index.jsx +27 -3
  24. package/src/components/__tests__/blank.test.js +186 -5
  25. package/src/components/blank.jsx +108 -35
  26. package/src/components/dropdown.jsx +2 -9
  27. package/src/drag-in-the-blank.jsx +132 -22
  28. package/src/keyboard-coordinates.js +147 -0
  29. package/src/mask.jsx +13 -11
  30. package/lib/__tests__/drag-in-the-blank.test.js +0 -129
  31. package/lib/__tests__/drag-in-the-blank.test.js.map +0 -1
  32. package/lib/__tests__/index.test.js +0 -39
  33. package/lib/__tests__/index.test.js.map +0 -1
  34. package/lib/__tests__/mask.test.js +0 -344
  35. package/lib/__tests__/mask.test.js.map +0 -1
  36. package/lib/__tests__/serialization.test.js +0 -44
  37. package/lib/__tests__/serialization.test.js.map +0 -1
  38. package/lib/__tests__/utils.js +0 -14
  39. package/lib/__tests__/utils.js.map +0 -1
  40. package/lib/__tests__/with-mask.test.js +0 -110
  41. package/lib/__tests__/with-mask.test.js.map +0 -1
  42. package/lib/choices/__tests__/index.test.js +0 -139
  43. package/lib/choices/__tests__/index.test.js.map +0 -1
  44. package/lib/components/__tests__/blank.test.js +0 -293
  45. package/lib/components/__tests__/blank.test.js.map +0 -1
  46. package/lib/components/__tests__/correct-input.test.js +0 -132
  47. package/lib/components/__tests__/correct-input.test.js.map +0 -1
  48. package/lib/components/__tests__/dropdown.test.js +0 -202
  49. package/lib/components/__tests__/dropdown.test.js.map +0 -1
  50. package/lib/components/__tests__/input.test.js +0 -129
  51. package/lib/components/__tests__/input.test.js.map +0 -1
@@ -12,6 +12,9 @@ export default class Choices extends React.Component {
12
12
  value: PropTypes.object,
13
13
  choicePosition: PropTypes.string.isRequired,
14
14
  instanceId: PropTypes.string, // Added for drag isolation
15
+ selectedItem: PropTypes.object,
16
+ onSelectClick: PropTypes.func,
17
+ onPlacementClick: PropTypes.func,
15
18
  };
16
19
 
17
20
  getStyleForWrapper = () => {
@@ -40,8 +43,22 @@ export default class Choices extends React.Component {
40
43
  }
41
44
  };
42
45
 
46
+ handlePoolClick = () => {
47
+ const { disabled, selectedItem, onPlacementClick } = this.props;
48
+
49
+ if (disabled) return;
50
+
51
+ if (selectedItem) {
52
+ // `undefined` targetId means "the choice board" — drag-in-the-blank.jsx's
53
+ // commitPlacement routes it to removing the item from wherever it currently is.
54
+ onPlacementClick?.(undefined);
55
+ }
56
+
57
+ // Pool background clicked with nothing selected: nothing to place.
58
+ };
59
+
43
60
  render() {
44
- const { disabled, duplicates, choices, value, instanceId } = this.props;
61
+ const { disabled, duplicates, choices, value, instanceId, selectedItem, onSelectClick } = this.props;
45
62
  const filteredChoices = choices.filter((c) => {
46
63
  if (duplicates === true) {
47
64
  return true;
@@ -52,10 +69,17 @@ export default class Choices extends React.Component {
52
69
  const elementStyle = { ...this.getStyleForWrapper(), minWidth: '100px' };
53
70
 
54
71
  return (
55
- <div style={elementStyle}>
72
+ <div style={elementStyle} onClick={this.handlePoolClick}>
56
73
  <DragDroppablePlaceholder disabled={disabled} instanceId={instanceId}>
57
74
  {filteredChoices.map((c, index) => (
58
- <Choice key={`${c.value}-${index}`} disabled={disabled} choice={c} instanceId={instanceId} />
75
+ <Choice
76
+ key={`${c.value}-${index}`}
77
+ disabled={disabled}
78
+ choice={c}
79
+ instanceId={instanceId}
80
+ selectedItem={selectedItem}
81
+ onSelectClick={onSelectClick}
82
+ />
59
83
  ))}
60
84
  </DragDroppablePlaceholder>
61
85
  </div>
@@ -1,11 +1,11 @@
1
1
  import * as React from 'react';
2
- import { render, screen, act } from '@testing-library/react';
2
+ import { render, screen, act, fireEvent } from '@testing-library/react';
3
3
  import Blank from '../blank';
4
4
 
5
5
  // Mock @dnd-kit hooks to avoid DndContext requirement
6
6
  jest.mock('@dnd-kit/core', () => ({
7
- useDraggable: jest.fn(() => ({
8
- attributes: {},
7
+ useDraggable: jest.fn((options) => ({
8
+ attributes: options?.attributes || {},
9
9
  listeners: {},
10
10
  setNodeRef: jest.fn(),
11
11
  transform: null,
@@ -163,8 +163,9 @@ describe('Blank', () => {
163
163
  jest.runAllTimers();
164
164
  });
165
165
 
166
- const wrapper = container.firstChild; // StyledContent
167
- const chip = wrapper && wrapper.firstChild; // StyledChip (rootRef)
166
+ const wrapper = container.firstChild; // StyledContent (outer droppable/click node)
167
+ const dragHandle = wrapper && wrapper.firstChild; // StyledDragHandle (inner draggable node)
168
+ const chip = dragHandle && dragHandle.firstChild; // StyledChip (rootRef)
168
169
 
169
170
  // Width and height should include padding (24px) around measured content
170
171
  expect(chip.style.width).toBe('129px');
@@ -229,4 +230,184 @@ describe('Blank', () => {
229
230
  // Should show visual feedback for drag over
230
231
  });
231
232
  });
233
+
234
+ describe('click-to-select and click-to-place', () => {
235
+ const { useDroppable } = require('@dnd-kit/core');
236
+
237
+ afterEach(() => {
238
+ useDroppable.mockReturnValue({ setNodeRef: jest.fn(), isOver: false, active: null });
239
+ });
240
+
241
+ it('is a native tab stop (role=button, tabIndex=0) when empty and not disabled', () => {
242
+ const { container } = render(<Blank {...defaultProps} choice={undefined} />);
243
+ const outer = container.firstChild;
244
+
245
+ expect(outer.getAttribute('role')).toBe('button');
246
+ expect(outer.getAttribute('tabindex')).toBe('0');
247
+ });
248
+
249
+ it('is not a tab stop when it already holds a choice (relies on the inner draggable node)', () => {
250
+ const { container } = render(<Blank {...defaultProps} />);
251
+ const outer = container.firstChild;
252
+
253
+ expect(outer.getAttribute('role')).toBeNull();
254
+ expect(outer.getAttribute('tabindex')).toBe('-1');
255
+ });
256
+
257
+ it('is not a tab stop when disabled, even if empty', () => {
258
+ const { container } = render(<Blank {...defaultProps} choice={undefined} disabled={true} />);
259
+ const outer = container.firstChild;
260
+
261
+ expect(outer.getAttribute('tabindex')).toBe('-1');
262
+ });
263
+
264
+ it('does not make the inner draggable node a second tab stop when the blank is empty', () => {
265
+ const { container } = render(<Blank {...defaultProps} choice={undefined} selectedItem={null} />);
266
+ const outer = container.firstChild;
267
+ const inner = outer.firstElementChild;
268
+
269
+ expect(outer.getAttribute('tabindex')).toBe('0');
270
+ // dragAttributes (which carries tabIndex) is only spread onto the inner node when
271
+ // it's the live tab stop (filled and not disabled) — otherwise it's omitted
272
+ // entirely, so no tabindex attribute is present at all here.
273
+ expect(inner.getAttribute('tabindex')).toBeNull();
274
+ });
275
+
276
+ it('makes the inner draggable node the tab stop when the blank is filled and not disabled', () => {
277
+ const { container } = render(<Blank {...defaultProps} selectedItem={null} />);
278
+ const outer = container.firstChild;
279
+ const inner = outer.firstElementChild;
280
+
281
+ expect(inner.getAttribute('tabindex')).toBe('0');
282
+ });
283
+
284
+ it('selects this blank\'s content on click when nothing else is selected', () => {
285
+ const onSelectClick = jest.fn();
286
+ const { container } = render(
287
+ <Blank {...defaultProps} id="3" selectedItem={null} onSelectClick={onSelectClick} />,
288
+ );
289
+
290
+ fireEvent.click(container.firstChild);
291
+
292
+ expect(onSelectClick).toHaveBeenCalledWith({
293
+ id: '3',
294
+ choice: defaultProps.choice,
295
+ instanceId: undefined,
296
+ fromChoice: false,
297
+ type: 'MaskBlank',
298
+ });
299
+ });
300
+
301
+ it('toggles off when clicking its own already-selected content', () => {
302
+ const onSelectClick = jest.fn();
303
+ const selectedItem = { id: '3', choice: defaultProps.choice, instanceId: undefined, fromChoice: false, type: 'MaskBlank' };
304
+ const { container } = render(
305
+ <Blank {...defaultProps} id="3" selectedItem={selectedItem} onSelectClick={onSelectClick} />,
306
+ );
307
+
308
+ fireEvent.click(container.firstChild);
309
+
310
+ expect(onSelectClick).toHaveBeenCalledWith(selectedItem);
311
+ });
312
+
313
+ it('places the current selection here when clicking a different, already-filled blank', () => {
314
+ const onPlacementClick = jest.fn();
315
+ const selectedItem = { choice: { value: 'Other' }, instanceId: undefined, fromChoice: true, type: 'MaskBlank' };
316
+ const { container } = render(
317
+ <Blank {...defaultProps} id="3" selectedItem={selectedItem} onPlacementClick={onPlacementClick} />,
318
+ );
319
+
320
+ fireEvent.click(container.firstChild);
321
+
322
+ expect(onPlacementClick).toHaveBeenCalledWith('3');
323
+ });
324
+
325
+ it('places the current selection here on Space/Enter when empty', () => {
326
+ const onPlacementClick = jest.fn();
327
+ const selectedItem = { choice: { value: 'Other' }, instanceId: undefined, fromChoice: true, type: 'MaskBlank' };
328
+ const { container } = render(
329
+ <Blank {...defaultProps} id="3" choice={undefined} selectedItem={selectedItem} onPlacementClick={onPlacementClick} />,
330
+ );
331
+
332
+ fireEvent.keyDown(container.firstChild, { code: 'Space' });
333
+
334
+ expect(onPlacementClick).toHaveBeenCalledWith('3');
335
+ });
336
+
337
+ it('does nothing on click when empty and nothing is selected', () => {
338
+ const onSelectClick = jest.fn();
339
+ const onPlacementClick = jest.fn();
340
+ const { container } = render(
341
+ <Blank {...defaultProps} choice={undefined} selectedItem={null} onSelectClick={onSelectClick} onPlacementClick={onPlacementClick} />,
342
+ );
343
+
344
+ fireEvent.click(container.firstChild);
345
+
346
+ expect(onSelectClick).not.toHaveBeenCalled();
347
+ expect(onPlacementClick).not.toHaveBeenCalled();
348
+ });
349
+
350
+ it('does nothing on click when disabled', () => {
351
+ const onSelectClick = jest.fn();
352
+ const selectedItem = { choice: { value: 'Other' }, instanceId: undefined, fromChoice: true, type: 'MaskBlank' };
353
+ const { container } = render(
354
+ <Blank {...defaultProps} disabled={true} selectedItem={selectedItem} onSelectClick={onSelectClick} />,
355
+ );
356
+
357
+ fireEvent.click(container.firstChild);
358
+
359
+ expect(onSelectClick).not.toHaveBeenCalled();
360
+ });
361
+
362
+ it('folds click-selection hover into the same highlight a live drag-over shows', () => {
363
+ const selectedItem = { choice: { value: 'Other' }, instanceId: undefined, fromChoice: true, type: 'MaskBlank' };
364
+ const { container } = render(<Blank {...defaultProps} id="3" selectedItem={selectedItem} />);
365
+ const outer = container.firstChild;
366
+
367
+ fireEvent.mouseEnter(outer);
368
+ // The "over" prop drives the same CSS the real isOver-driven highlight uses —
369
+ // assert via the rendered chip's className, since StyledContent forwards `over`.
370
+ // Re-render check: BlankContent receives the folded isOver as true while hovered
371
+ // with a selection active — verified indirectly via the "over" chip class it sets.
372
+ expect(screen.getByText('Cow').closest('.over')).not.toBeNull();
373
+
374
+ fireEvent.mouseLeave(outer);
375
+ expect(screen.getByText('Cow').closest('.over')).toBeNull();
376
+ });
377
+
378
+ it('shows a pointer cursor on hover when something is selected', () => {
379
+ const selectedItem = { choice: { value: 'Other' }, instanceId: undefined, fromChoice: true, type: 'MaskBlank' };
380
+ const { container } = render(<Blank {...defaultProps} id="3" selectedItem={selectedItem} />);
381
+ const outer = container.firstChild;
382
+ const className = Array.from(outer.classList).find((c) => c.startsWith('css-'));
383
+
384
+ const hoverRule = collectEmotionRules().find((r) => r.includes(`.${className}:hover`));
385
+
386
+ expect(hoverRule).toBeDefined();
387
+ expect(hoverRule).toMatch(/cursor:\s*pointer/);
388
+ });
389
+
390
+ it('keeps the default cursor on hover when nothing is selected', () => {
391
+ const { container } = render(<Blank {...defaultProps} id="3" selectedItem={null} />);
392
+ const outer = container.firstChild;
393
+ const className = Array.from(outer.classList).find((c) => c.startsWith('css-'));
394
+
395
+ const hoverRule = collectEmotionRules().find((r) => r.includes(`.${className}:hover`));
396
+
397
+ expect(hoverRule).toBeUndefined();
398
+ });
399
+
400
+ it('keeps the default cursor on hover when disabled, even with something selected', () => {
401
+ const selectedItem = { choice: { value: 'Other' }, instanceId: undefined, fromChoice: true, type: 'MaskBlank' };
402
+ const { container } = render(
403
+ <Blank {...defaultProps} id="3" disabled={true} selectedItem={selectedItem} />,
404
+ );
405
+ const outer = container.firstChild;
406
+ const className = Array.from(outer.classList).find((c) => c.startsWith('css-'));
407
+
408
+ const hoverRule = collectEmotionRules().find((r) => r.includes(`.${className}:hover`));
409
+
410
+ expect(hoverRule).toBeUndefined();
411
+ });
412
+ });
232
413
  });
@@ -3,7 +3,6 @@ import PropTypes from 'prop-types';
3
3
  import { renderMath } from '@pie-lib/math-rendering';
4
4
  import debug from 'debug';
5
5
  import { useDraggable, useDroppable } from '@dnd-kit/core';
6
- import { CSS } from '@dnd-kit/utilities';
7
6
  import { styled } from '@mui/material/styles';
8
7
  import Chip from '@mui/material/Chip';
9
8
  import classnames from 'classnames';
@@ -12,22 +11,32 @@ import { grey } from '@mui/material/colors';
12
11
 
13
12
  const log = debug('pie-lib:mask-markup:blank');
14
13
 
15
- const StyledContent = styled('span')(({ dragged, over }) => ({
14
+ const StyledContent = styled('span')(({ dragged, over, selected, showsPointerCursor }) => ({
16
15
  border: `solid 0px ${color.primary()}`,
17
16
  minWidth: '200px',
18
- touchAction: 'none',
19
17
  overflow: 'hidden',
20
18
  whiteSpace: 'nowrap',
21
19
  opacity: 1,
20
+ cursor: 'default',
22
21
  ...(over && {
23
22
  whiteSpace: 'nowrap',
24
23
  overflow: 'hidden',
25
24
  }),
26
- ...(dragged && {
25
+ ...((dragged || selected) && {
27
26
  opacity: 0.5,
28
27
  }),
28
+ ...(showsPointerCursor && {
29
+ '&:hover': {
30
+ cursor: 'pointer',
31
+ },
32
+ }),
29
33
  }));
30
34
 
35
+ const StyledDragHandle = styled('span')({
36
+ display: 'inline-flex',
37
+ touchAction: 'none',
38
+ });
39
+
31
40
  const StyledChip = styled(Chip)(() => ({
32
41
  backgroundColor: color.background(),
33
42
  border: `2px dashed ${color.text()}`,
@@ -341,23 +350,40 @@ function DragDropBlank({
341
350
  emptyResponseAreaWidth,
342
351
  emptyResponseAreaHeight,
343
352
  instanceId,
353
+ selectedItem,
354
+ onSelectClick,
355
+ onPlacementClick,
344
356
  }) {
357
+ const [isHovered, setIsHovered] = useState(false);
358
+
359
+ const dragData = {
360
+ id,
361
+ choice,
362
+ instanceId,
363
+ fromChoice: false, // This is from a blank, not from choices
364
+ type: 'MaskBlank',
365
+ };
366
+
345
367
  // Setup draggable functionality
346
368
  const {
347
369
  attributes: dragAttributes,
348
370
  listeners: dragListeners,
349
371
  setNodeRef: setDragNodeRef,
350
- transform,
351
372
  isDragging,
352
373
  } = useDraggable({
353
374
  id: `mask-blank-drag-${id}`,
354
375
  disabled: disabled || !choice,
355
- data: {
356
- id: id,
357
- choice: choice,
358
- instanceId: instanceId,
359
- fromChoice: false, // This is from a blank, not from choices
360
- type: 'MaskBlank',
376
+ data: dragData,
377
+ // dnd-kit's own `attributes` default tabIndex to 0 unconditionally, even when
378
+ // `disabled` — so a non-draggable (empty) blank stays a native Tab stop of its own.
379
+ // For a drop-zone (droppable blank), that duplicates the outer wrapper's own tab stop
380
+ // (see isNativeTabStop below) at the exact same position, so Tab/Shift+Tab has to
381
+ // pass through both to move anywhere visibly, making every other press look like a
382
+ // no-op. Drop it out of the tab order here whenever it isn't independently
383
+ // reachable/interactive, leaving the outer wrapper (for an empty blank) or
384
+ // nothing (for a disabled blank) as the sole stop.
385
+ attributes: {
386
+ tabIndex: choice && !disabled ? 0 : -1,
361
387
  },
362
388
  });
363
389
 
@@ -375,38 +401,82 @@ function DragDropBlank({
375
401
  },
376
402
  });
377
403
 
378
- // Combine refs for both drag and drop
379
- const setNodeRef = (node) => {
380
- setDragNodeRef(node);
381
- setDropNodeRef(node);
404
+ const isSelected = !!selectedItem && selectedItem.fromChoice === false && selectedItem.id === id;
405
+
406
+ const handleClick = () => {
407
+ if (disabled) return;
408
+
409
+ if (isSelected) {
410
+ // Clicking this blank's already-selected content again deselects it.
411
+ onSelectClick?.(dragData);
412
+ } else if (selectedItem) {
413
+ // Something else is selected — place it here, whether this blank is currently
414
+ // empty or already filled (the same commitPlacement logic drag-and-drop uses).
415
+ onPlacementClick?.(id);
416
+ } else if (choice) {
417
+ // Nothing selected yet, and this blank holds an answer — select it for moving
418
+ // elsewhere, the same way Tab+Space/Enter does.
419
+ onSelectClick?.(dragData);
420
+ }
421
+
422
+ // Empty blank clicked with nothing selected: nothing to place or select.
382
423
  };
383
424
 
384
- const style = {
385
- transform: CSS.Translate.toString(transform),
425
+ // An empty blank isn't draggable, so dnd-kit's own attributes (only applied to the
426
+ // inner node, and only when draggable) never make it tabbable — this outer wrapper
427
+ // needs its own focus/activation handling so "select a choice, then Tab to a blank
428
+ // and press Space/Enter" works even when the blank is empty. This is independent of,
429
+ // and doesn't change, the existing in-drag Tab-cycling (that's driven by an active
430
+ // dnd-kit drag, not native focus).
431
+ //
432
+ // Only made a native Tab stop when NOT draggable (i.e. empty): when the blank is
433
+ // filled, the inner node is already independently tabbable via dnd-kit's own
434
+ // attributes for the existing pick-up-to-move gesture, and adding a second, outer Tab
435
+ // stop for the same visual chip would add an extra stop to the existing Tab order —
436
+ // the same double-tab-stop bug already found and fixed once in match-list/image-
437
+ // cloze-association's equivalent code.
438
+ const isNativeTabStop = !choice && !disabled;
439
+ const isInnerDraggable = !!choice && !disabled;
440
+
441
+ const handleKeyDown = (e) => {
442
+ if (e.code === 'Space' || e.code === 'Enter') {
443
+ e.preventDefault();
444
+ handleClick();
445
+ }
386
446
  };
387
447
 
448
+ const hasSelection = !!selectedItem;
449
+ const showsHoverEffect = isOver || (hasSelection && isHovered && !disabled);
450
+
388
451
  return (
389
452
  <StyledContent
390
- ref={setNodeRef}
391
- style={style}
453
+ ref={setDropNodeRef}
454
+ role={isNativeTabStop ? 'button' : undefined}
455
+ tabIndex={isNativeTabStop ? 0 : -1}
456
+ onClick={handleClick}
457
+ onKeyDown={isNativeTabStop ? handleKeyDown : undefined}
458
+ onMouseEnter={() => setIsHovered(true)}
459
+ onMouseLeave={() => setIsHovered(false)}
392
460
  dragged={isDragging}
393
- over={isOver}
394
- {...dragAttributes}
395
- {...dragListeners}
461
+ over={showsHoverEffect}
462
+ selected={isSelected}
463
+ showsPointerCursor={hasSelection && !disabled}
396
464
  >
397
- <BlankContent
398
- id={id}
399
- disabled={disabled}
400
- duplicates={duplicates}
401
- choice={choice}
402
- isOver={isOver}
403
- dragItem={dragItem?.data?.current}
404
- correct={correct}
405
- onChange={onChange}
406
- emptyResponseAreaWidth={emptyResponseAreaWidth}
407
- emptyResponseAreaHeight={emptyResponseAreaHeight}
408
- instanceId={instanceId}
409
- />
465
+ <StyledDragHandle ref={setDragNodeRef} {...(isInnerDraggable ? dragAttributes : {})} {...dragListeners}>
466
+ <BlankContent
467
+ id={id}
468
+ disabled={disabled}
469
+ duplicates={duplicates}
470
+ choice={choice}
471
+ isOver={showsHoverEffect}
472
+ dragItem={dragItem?.data?.current}
473
+ correct={correct}
474
+ onChange={onChange}
475
+ emptyResponseAreaWidth={emptyResponseAreaWidth}
476
+ emptyResponseAreaHeight={emptyResponseAreaHeight}
477
+ instanceId={instanceId}
478
+ />
479
+ </StyledDragHandle>
410
480
  </StyledContent>
411
481
  );
412
482
  }
@@ -426,6 +496,9 @@ DragDropBlank.propTypes = {
426
496
  emptyResponseAreaWidth: PropTypes.oneOfType([PropTypes.string, PropTypes.number]),
427
497
  emptyResponseAreaHeight: PropTypes.oneOfType([PropTypes.string, PropTypes.number]),
428
498
  instanceId: PropTypes.string,
499
+ selectedItem: PropTypes.object,
500
+ onSelectClick: PropTypes.func,
501
+ onPlacementClick: PropTypes.func,
429
502
  };
430
503
 
431
504
  export default DragDropBlank;
@@ -53,15 +53,8 @@ const StyledButton = styled(Button)(() => ({
53
53
  }));
54
54
 
55
55
  const StyledMenu = styled(Menu)(() => ({
56
- backgroundColor: color.background(),
57
- border: `1px solid ${color.correct()} !important`,
58
- '&:hover': {
59
- border: `1px solid ${color.text()} `,
60
- borderColor: 'initial',
61
- },
62
- '&:focus': {
63
- border: `1px solid ${color.text()}`,
64
- borderColor: 'initial',
56
+ '& .MuiPaper-root': {
57
+ backgroundColor: color.background(),
65
58
  },
66
59
  // remove default padding on the inner list
67
60
  '& .MuiList-root': {