@pie-element/match-list 7.2.0-beta.0 → 7.2.1

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.
package/lib/arrow.js CHANGED
@@ -10,16 +10,19 @@ var _react = _interopRequireDefault(require("react"));
10
10
  var _propTypes = _interopRequireDefault(require("prop-types"));
11
11
  var _ArrowDropDown = _interopRequireDefault(require("@mui/icons-material/ArrowDropDown"));
12
12
  var _styles = require("@mui/material/styles");
13
+ var _renderUi = require("@pie-lib/render-ui");
13
14
  const ArrowContainer = (0, _styles.styled)('div')({
14
15
  display: 'inline-block',
15
16
  position: 'relative',
16
17
  width: '100%'
17
18
  });
19
+
20
+ // A 1px rule joining a prompt to its answer: it is the connector, so it needs to
21
+ // stay perceivable on every scheme's surface.
18
22
  const Line = (0, _styles.styled)('span')(({
19
- theme,
20
23
  isRight
21
24
  }) => ({
22
- backgroundColor: theme.palette.grey[500],
25
+ backgroundColor: _renderUi.color.border(),
23
26
  bottom: isRight ? 20 : 19,
24
27
  content: '""',
25
28
  display: 'block',
@@ -41,7 +44,9 @@ class Arrow extends _react.default.Component {
41
44
  }, /*#__PURE__*/_react.default.createElement(_ArrowDropDown.default, {
42
45
  style: {
43
46
  transform: 'rotate(90deg)',
44
- color: '#979797',
47
+ // Pairs with Line above: head and shaft are one connector and have to
48
+ // step together, or the arrow loses its point on a dark scheme.
49
+ color: _renderUi.color.border(),
45
50
  fontSize: 40
46
51
  }
47
52
  }), /*#__PURE__*/_react.default.createElement(Line, {
package/lib/arrow.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"arrow.js","names":["_react","_interopRequireDefault","require","_propTypes","_ArrowDropDown","_styles","ArrowContainer","styled","display","position","width","Line","theme","isRight","backgroundColor","palette","grey","bottom","content","height","left","Arrow","React","Component","render","direction","props","extraStyle","transform","default","createElement","style","color","fontSize","exports","_defineProperty2","PropTypes","string","_default"],"sources":["../src/arrow.jsx"],"sourcesContent":["import React from 'react';\nimport PropTypes from 'prop-types';\nimport ArrowHead from '@mui/icons-material/ArrowDropDown';\nimport { styled } from '@mui/material/styles';\n\nconst ArrowContainer = styled('div')({\n display: 'inline-block',\n position: 'relative',\n width: '100%',\n});\n\nconst Line = styled('span')(({ theme, isRight }) => ({\n backgroundColor: theme.palette.grey[500],\n bottom: isRight ? 20 : 19,\n content: '\"\"',\n display: 'block',\n height: 1,\n left: 20,\n position: 'absolute',\n width: '100%',\n}));\n\nexport class Arrow extends React.Component {\n static propTypes = {\n direction: PropTypes.string,\n };\n\n render() {\n const { direction } = this.props;\n\n const extraStyle =\n direction === 'left'\n ? {}\n : {\n transform: 'rotate(180deg)',\n };\n\n return (\n <ArrowContainer style={extraStyle}>\n <ArrowHead\n style={{\n transform: 'rotate(90deg)',\n color: '#979797',\n fontSize: 40,\n }}\n />\n <Line isRight={direction !== 'left'} />\n </ArrowContainer>\n );\n }\n}\n\nexport default Arrow;\n"],"mappings":";;;;;;;;AAAA,IAAAA,MAAA,GAAAC,sBAAA,CAAAC,OAAA;AACA,IAAAC,UAAA,GAAAF,sBAAA,CAAAC,OAAA;AACA,IAAAE,cAAA,GAAAH,sBAAA,CAAAC,OAAA;AACA,IAAAG,OAAA,GAAAH,OAAA;AAEA,MAAMI,cAAc,GAAG,IAAAC,cAAM,EAAC,KAAK,CAAC,CAAC;EACnCC,OAAO,EAAE,cAAc;EACvBC,QAAQ,EAAE,UAAU;EACpBC,KAAK,EAAE;AACT,CAAC,CAAC;AAEF,MAAMC,IAAI,GAAG,IAAAJ,cAAM,EAAC,MAAM,CAAC,CAAC,CAAC;EAAEK,KAAK;EAAEC;AAAQ,CAAC,MAAM;EACnDC,eAAe,EAAEF,KAAK,CAACG,OAAO,CAACC,IAAI,CAAC,GAAG,CAAC;EACxCC,MAAM,EAAEJ,OAAO,GAAG,EAAE,GAAG,EAAE;EACzBK,OAAO,EAAE,IAAI;EACbV,OAAO,EAAE,OAAO;EAChBW,MAAM,EAAE,CAAC;EACTC,IAAI,EAAE,EAAE;EACRX,QAAQ,EAAE,UAAU;EACpBC,KAAK,EAAE;AACT,CAAC,CAAC,CAAC;AAEI,MAAMW,KAAK,SAASC,cAAK,CAACC,SAAS,CAAC;EAKzCC,MAAMA,CAAA,EAAG;IACP,MAAM;MAAEC;IAAU,CAAC,GAAG,IAAI,CAACC,KAAK;IAEhC,MAAMC,UAAU,GACdF,SAAS,KAAK,MAAM,GAChB,CAAC,CAAC,GACF;MACEG,SAAS,EAAE;IACb,CAAC;IAEP,oBACE5B,MAAA,CAAA6B,OAAA,CAAAC,aAAA,CAACxB,cAAc;MAACyB,KAAK,EAAEJ;IAAW,gBAChC3B,MAAA,CAAA6B,OAAA,CAAAC,aAAA,CAAC1B,cAAA,CAAAyB,OAAS;MACRE,KAAK,EAAE;QACLH,SAAS,EAAE,eAAe;QAC1BI,KAAK,EAAE,SAAS;QAChBC,QAAQ,EAAE;MACZ;IAAE,CACH,CAAC,eACFjC,MAAA,CAAA6B,OAAA,CAAAC,aAAA,CAACnB,IAAI;MAACE,OAAO,EAAEY,SAAS,KAAK;IAAO,CAAE,CACxB,CAAC;EAErB;AACF;AAACS,OAAA,CAAAb,KAAA,GAAAA,KAAA;AAAA,IAAAc,gBAAA,CAAAN,OAAA,EA5BYR,KAAK,eACG;EACjBI,SAAS,EAAEW,kBAAS,CAACC;AACvB,CAAC;AAAA,IAAAC,QAAA,GAAAJ,OAAA,CAAAL,OAAA,GA2BYR,KAAK","ignoreList":[]}
1
+ {"version":3,"file":"arrow.js","names":["_react","_interopRequireDefault","require","_propTypes","_ArrowDropDown","_styles","_renderUi","ArrowContainer","styled","display","position","width","Line","isRight","backgroundColor","color","border","bottom","content","height","left","Arrow","React","Component","render","direction","props","extraStyle","transform","default","createElement","style","fontSize","exports","_defineProperty2","PropTypes","string","_default"],"sources":["../src/arrow.jsx"],"sourcesContent":["import React from 'react';\nimport PropTypes from 'prop-types';\nimport ArrowHead from '@mui/icons-material/ArrowDropDown';\nimport { styled } from '@mui/material/styles';\nimport { color } from '@pie-lib/render-ui';\n\nconst ArrowContainer = styled('div')({\n display: 'inline-block',\n position: 'relative',\n width: '100%',\n});\n\n// A 1px rule joining a prompt to its answer: it is the connector, so it needs to\n// stay perceivable on every scheme's surface.\nconst Line = styled('span')(({ isRight }) => ({\n backgroundColor: color.border(),\n bottom: isRight ? 20 : 19,\n content: '\"\"',\n display: 'block',\n height: 1,\n left: 20,\n position: 'absolute',\n width: '100%',\n}));\n\nexport class Arrow extends React.Component {\n static propTypes = {\n direction: PropTypes.string,\n };\n\n render() {\n const { direction } = this.props;\n\n const extraStyle =\n direction === 'left'\n ? {}\n : {\n transform: 'rotate(180deg)',\n };\n\n return (\n <ArrowContainer style={extraStyle}>\n <ArrowHead\n style={{\n transform: 'rotate(90deg)',\n // Pairs with Line above: head and shaft are one connector and have to\n // step together, or the arrow loses its point on a dark scheme.\n color: color.border(),\n fontSize: 40,\n }}\n />\n <Line isRight={direction !== 'left'} />\n </ArrowContainer>\n );\n }\n}\n\nexport default Arrow;\n"],"mappings":";;;;;;;;AAAA,IAAAA,MAAA,GAAAC,sBAAA,CAAAC,OAAA;AACA,IAAAC,UAAA,GAAAF,sBAAA,CAAAC,OAAA;AACA,IAAAE,cAAA,GAAAH,sBAAA,CAAAC,OAAA;AACA,IAAAG,OAAA,GAAAH,OAAA;AACA,IAAAI,SAAA,GAAAJ,OAAA;AAEA,MAAMK,cAAc,GAAG,IAAAC,cAAM,EAAC,KAAK,CAAC,CAAC;EACnCC,OAAO,EAAE,cAAc;EACvBC,QAAQ,EAAE,UAAU;EACpBC,KAAK,EAAE;AACT,CAAC,CAAC;;AAEF;AACA;AACA,MAAMC,IAAI,GAAG,IAAAJ,cAAM,EAAC,MAAM,CAAC,CAAC,CAAC;EAAEK;AAAQ,CAAC,MAAM;EAC5CC,eAAe,EAAEC,eAAK,CAACC,MAAM,CAAC,CAAC;EAC/BC,MAAM,EAAEJ,OAAO,GAAG,EAAE,GAAG,EAAE;EACzBK,OAAO,EAAE,IAAI;EACbT,OAAO,EAAE,OAAO;EAChBU,MAAM,EAAE,CAAC;EACTC,IAAI,EAAE,EAAE;EACRV,QAAQ,EAAE,UAAU;EACpBC,KAAK,EAAE;AACT,CAAC,CAAC,CAAC;AAEI,MAAMU,KAAK,SAASC,cAAK,CAACC,SAAS,CAAC;EAKzCC,MAAMA,CAAA,EAAG;IACP,MAAM;MAAEC;IAAU,CAAC,GAAG,IAAI,CAACC,KAAK;IAEhC,MAAMC,UAAU,GACdF,SAAS,KAAK,MAAM,GAChB,CAAC,CAAC,GACF;MACEG,SAAS,EAAE;IACb,CAAC;IAEP,oBACE5B,MAAA,CAAA6B,OAAA,CAAAC,aAAA,CAACvB,cAAc;MAACwB,KAAK,EAAEJ;IAAW,gBAChC3B,MAAA,CAAA6B,OAAA,CAAAC,aAAA,CAAC1B,cAAA,CAAAyB,OAAS;MACRE,KAAK,EAAE;QACLH,SAAS,EAAE,eAAe;QAC1B;QACA;QACAb,KAAK,EAAEA,eAAK,CAACC,MAAM,CAAC,CAAC;QACrBgB,QAAQ,EAAE;MACZ;IAAE,CACH,CAAC,eACFhC,MAAA,CAAA6B,OAAA,CAAAC,aAAA,CAAClB,IAAI;MAACC,OAAO,EAAEY,SAAS,KAAK;IAAO,CAAE,CACxB,CAAC;EAErB;AACF;AAACQ,OAAA,CAAAZ,KAAA,GAAAA,KAAA;AAAA,IAAAa,gBAAA,CAAAL,OAAA,EA9BYR,KAAK,eACG;EACjBI,SAAS,EAAEU,kBAAS,CAACC;AACvB,CAAC;AAAA,IAAAC,QAAA,GAAAJ,OAAA,CAAAJ,OAAA,GA6BYR,KAAK","ignoreList":[]}
@@ -25,7 +25,10 @@ class ChoicesList extends _react.default.Component {
25
25
  disabled,
26
26
  session,
27
27
  instanceId,
28
- onRemoveAnswer
28
+ onRemoveAnswer,
29
+ selectedAnswer,
30
+ onChoiceClick,
31
+ onPlacementClick
29
32
  } = this.props;
30
33
  const {
31
34
  config
@@ -39,12 +42,15 @@ class ChoicesList extends _react.default.Component {
39
42
  draggable: true,
40
43
  disabled: disabled,
41
44
  session: session,
42
- type: "choice"
45
+ type: "choice",
46
+ selectedAnswer: selectedAnswer,
47
+ onSelectClick: onChoiceClick
43
48
  }, answer)));
44
49
  return /*#__PURE__*/_react.default.createElement(ChoicesContainer, null, /*#__PURE__*/_react.default.createElement(_droppablePlaceholder.DroppablePlaceholder, {
45
50
  id: "choices-pool",
46
51
  disabled: disabled,
47
- onRemoveAnswer: onRemoveAnswer
52
+ onRemoveAnswer: onRemoveAnswer,
53
+ onPlacementClick: onPlacementClick
48
54
  }, filteredAnswers));
49
55
  }
50
56
  }
@@ -54,7 +60,10 @@ exports.ChoicesList = ChoicesList;
54
60
  instanceId: _propTypes.default.string.isRequired,
55
61
  model: _propTypes.default.object.isRequired,
56
62
  disabled: _propTypes.default.bool.isRequired,
57
- onRemoveAnswer: _propTypes.default.func
63
+ onRemoveAnswer: _propTypes.default.func,
64
+ selectedAnswer: _propTypes.default.object,
65
+ onChoiceClick: _propTypes.default.func,
66
+ onPlacementClick: _propTypes.default.func
58
67
  });
59
68
  var _default = exports.default = ChoicesList;
60
69
  //# sourceMappingURL=choices-list.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"choices-list.js","names":["_react","_interopRequireDefault","require","_propTypes","_styles","_lodashEs","_answer","_droppablePlaceholder","ChoicesContainer","styled","theme","marginBottom","spacing","ChoicesList","React","Component","render","model","disabled","session","instanceId","onRemoveAnswer","props","config","duplicates","filteredAnswers","answers","filter","answer","isEmpty","value","isUndefined","find","val","id","map","default","createElement","_extends2","key","draggable","type","DroppablePlaceholder","exports","_defineProperty2","PropTypes","object","isRequired","string","bool","func","_default"],"sources":["../src/choices-list.jsx"],"sourcesContent":["import React from 'react';\nimport PropTypes from 'prop-types';\nimport { styled } from '@mui/material/styles';\nimport { find, isEmpty, isUndefined } from 'lodash-es';\nimport DragAndDropAnswer from './answer';\nimport { DroppablePlaceholder } from './droppable-placeholder';\n\nconst ChoicesContainer = styled('div')(({ theme }) => ({\n marginBottom: theme.spacing(2),\n}));\n\nexport class ChoicesList extends React.Component {\n static propTypes = {\n session: PropTypes.object.isRequired,\n instanceId: PropTypes.string.isRequired,\n model: PropTypes.object.isRequired,\n disabled: PropTypes.bool.isRequired,\n onRemoveAnswer: PropTypes.func,\n };\n\n render() {\n const { model, disabled, session, instanceId, onRemoveAnswer } = this.props;\n const { config } = model;\n const { duplicates } = config;\n\n const filteredAnswers = config.answers\n .filter(\n (answer) =>\n duplicates ||\n isEmpty(session) ||\n !session.value ||\n isUndefined(find(session.value, (val) => val === answer.id)),\n )\n .map((answer) => (\n <DragAndDropAnswer\n key={answer.id}\n instanceId={instanceId}\n draggable={true}\n disabled={disabled}\n session={session}\n type=\"choice\"\n {...answer}\n />\n ));\n\n return (\n <ChoicesContainer>\n <DroppablePlaceholder id=\"choices-pool\" disabled={disabled} onRemoveAnswer={onRemoveAnswer}>\n {filteredAnswers}\n </DroppablePlaceholder>\n </ChoicesContainer>\n );\n }\n}\n\nexport default ChoicesList;\n"],"mappings":";;;;;;;;;AAAA,IAAAA,MAAA,GAAAC,sBAAA,CAAAC,OAAA;AACA,IAAAC,UAAA,GAAAF,sBAAA,CAAAC,OAAA;AACA,IAAAE,OAAA,GAAAF,OAAA;AACA,IAAAG,SAAA,GAAAH,OAAA;AACA,IAAAI,OAAA,GAAAL,sBAAA,CAAAC,OAAA;AACA,IAAAK,qBAAA,GAAAL,OAAA;AAEA,MAAMM,gBAAgB,GAAG,IAAAC,cAAM,EAAC,KAAK,CAAC,CAAC,CAAC;EAAEC;AAAM,CAAC,MAAM;EACrDC,YAAY,EAAED,KAAK,CAACE,OAAO,CAAC,CAAC;AAC/B,CAAC,CAAC,CAAC;AAEI,MAAMC,WAAW,SAASC,cAAK,CAACC,SAAS,CAAC;EAS/CC,MAAMA,CAAA,EAAG;IACP,MAAM;MAAEC,KAAK;MAAEC,QAAQ;MAAEC,OAAO;MAAEC,UAAU;MAAEC;IAAe,CAAC,GAAG,IAAI,CAACC,KAAK;IAC3E,MAAM;MAAEC;IAAO,CAAC,GAAGN,KAAK;IACxB,MAAM;MAAEO;IAAW,CAAC,GAAGD,MAAM;IAE7B,MAAME,eAAe,GAAGF,MAAM,CAACG,OAAO,CACnCC,MAAM,CACJC,MAAM,IACLJ,UAAU,IACV,IAAAK,iBAAO,EAACV,OAAO,CAAC,IAChB,CAACA,OAAO,CAACW,KAAK,IACd,IAAAC,qBAAW,EAAC,IAAAC,cAAI,EAACb,OAAO,CAACW,KAAK,EAAGG,GAAG,IAAKA,GAAG,KAAKL,MAAM,CAACM,EAAE,CAAC,CAC/D,CAAC,CACAC,GAAG,CAAEP,MAAM,iBACV5B,MAAA,CAAAoC,OAAA,CAAAC,aAAA,CAAC/B,OAAA,CAAA8B,OAAiB,MAAAE,SAAA,CAAAF,OAAA;MAChBG,GAAG,EAAEX,MAAM,CAACM,EAAG;MACfd,UAAU,EAAEA,UAAW;MACvBoB,SAAS,EAAE,IAAK;MAChBtB,QAAQ,EAAEA,QAAS;MACnBC,OAAO,EAAEA,OAAQ;MACjBsB,IAAI,EAAC;IAAQ,GACTb,MAAM,CACX,CACF,CAAC;IAEJ,oBACE5B,MAAA,CAAAoC,OAAA,CAAAC,aAAA,CAAC7B,gBAAgB,qBACfR,MAAA,CAAAoC,OAAA,CAAAC,aAAA,CAAC9B,qBAAA,CAAAmC,oBAAoB;MAACR,EAAE,EAAC,cAAc;MAAChB,QAAQ,EAAEA,QAAS;MAACG,cAAc,EAAEA;IAAe,GACxFI,eACmB,CACN,CAAC;EAEvB;AACF;AAACkB,OAAA,CAAA9B,WAAA,GAAAA,WAAA;AAAA,IAAA+B,gBAAA,CAAAR,OAAA,EA1CYvB,WAAW,eACH;EACjBM,OAAO,EAAE0B,kBAAS,CAACC,MAAM,CAACC,UAAU;EACpC3B,UAAU,EAAEyB,kBAAS,CAACG,MAAM,CAACD,UAAU;EACvC9B,KAAK,EAAE4B,kBAAS,CAACC,MAAM,CAACC,UAAU;EAClC7B,QAAQ,EAAE2B,kBAAS,CAACI,IAAI,CAACF,UAAU;EACnC1B,cAAc,EAAEwB,kBAAS,CAACK;AAC5B,CAAC;AAAA,IAAAC,QAAA,GAAAR,OAAA,CAAAP,OAAA,GAqCYvB,WAAW","ignoreList":[]}
1
+ {"version":3,"file":"choices-list.js","names":["_react","_interopRequireDefault","require","_propTypes","_styles","_lodashEs","_answer","_droppablePlaceholder","ChoicesContainer","styled","theme","marginBottom","spacing","ChoicesList","React","Component","render","model","disabled","session","instanceId","onRemoveAnswer","selectedAnswer","onChoiceClick","onPlacementClick","props","config","duplicates","filteredAnswers","answers","filter","answer","isEmpty","value","isUndefined","find","val","id","map","default","createElement","_extends2","key","draggable","type","onSelectClick","DroppablePlaceholder","exports","_defineProperty2","PropTypes","object","isRequired","string","bool","func","_default"],"sources":["../src/choices-list.jsx"],"sourcesContent":["import React from 'react';\nimport PropTypes from 'prop-types';\nimport { styled } from '@mui/material/styles';\nimport { find, isEmpty, isUndefined } from 'lodash-es';\nimport DragAndDropAnswer from './answer';\nimport { DroppablePlaceholder } from './droppable-placeholder';\n\nconst ChoicesContainer = styled('div')(({ theme }) => ({\n marginBottom: theme.spacing(2),\n}));\n\nexport class ChoicesList extends React.Component {\n static propTypes = {\n session: PropTypes.object.isRequired,\n instanceId: PropTypes.string.isRequired,\n model: PropTypes.object.isRequired,\n disabled: PropTypes.bool.isRequired,\n onRemoveAnswer: PropTypes.func,\n selectedAnswer: PropTypes.object,\n onChoiceClick: PropTypes.func,\n onPlacementClick: PropTypes.func,\n };\n\n render() {\n const {\n model,\n disabled,\n session,\n instanceId,\n onRemoveAnswer,\n selectedAnswer,\n onChoiceClick,\n onPlacementClick,\n } = this.props;\n const { config } = model;\n const { duplicates } = config;\n\n const filteredAnswers = config.answers\n .filter(\n (answer) =>\n duplicates ||\n isEmpty(session) ||\n !session.value ||\n isUndefined(find(session.value, (val) => val === answer.id)),\n )\n .map((answer) => (\n <DragAndDropAnswer\n key={answer.id}\n instanceId={instanceId}\n draggable={true}\n disabled={disabled}\n session={session}\n type=\"choice\"\n selectedAnswer={selectedAnswer}\n onSelectClick={onChoiceClick}\n {...answer}\n />\n ));\n\n return (\n <ChoicesContainer>\n <DroppablePlaceholder\n id=\"choices-pool\"\n disabled={disabled}\n onRemoveAnswer={onRemoveAnswer}\n onPlacementClick={onPlacementClick}\n >\n {filteredAnswers}\n </DroppablePlaceholder>\n </ChoicesContainer>\n );\n }\n}\n\nexport default ChoicesList;\n"],"mappings":";;;;;;;;;AAAA,IAAAA,MAAA,GAAAC,sBAAA,CAAAC,OAAA;AACA,IAAAC,UAAA,GAAAF,sBAAA,CAAAC,OAAA;AACA,IAAAE,OAAA,GAAAF,OAAA;AACA,IAAAG,SAAA,GAAAH,OAAA;AACA,IAAAI,OAAA,GAAAL,sBAAA,CAAAC,OAAA;AACA,IAAAK,qBAAA,GAAAL,OAAA;AAEA,MAAMM,gBAAgB,GAAG,IAAAC,cAAM,EAAC,KAAK,CAAC,CAAC,CAAC;EAAEC;AAAM,CAAC,MAAM;EACrDC,YAAY,EAAED,KAAK,CAACE,OAAO,CAAC,CAAC;AAC/B,CAAC,CAAC,CAAC;AAEI,MAAMC,WAAW,SAASC,cAAK,CAACC,SAAS,CAAC;EAY/CC,MAAMA,CAAA,EAAG;IACP,MAAM;MACJC,KAAK;MACLC,QAAQ;MACRC,OAAO;MACPC,UAAU;MACVC,cAAc;MACdC,cAAc;MACdC,aAAa;MACbC;IACF,CAAC,GAAG,IAAI,CAACC,KAAK;IACd,MAAM;MAAEC;IAAO,CAAC,GAAGT,KAAK;IACxB,MAAM;MAAEU;IAAW,CAAC,GAAGD,MAAM;IAE7B,MAAME,eAAe,GAAGF,MAAM,CAACG,OAAO,CACnCC,MAAM,CACJC,MAAM,IACLJ,UAAU,IACV,IAAAK,iBAAO,EAACb,OAAO,CAAC,IAChB,CAACA,OAAO,CAACc,KAAK,IACd,IAAAC,qBAAW,EAAC,IAAAC,cAAI,EAAChB,OAAO,CAACc,KAAK,EAAGG,GAAG,IAAKA,GAAG,KAAKL,MAAM,CAACM,EAAE,CAAC,CAC/D,CAAC,CACAC,GAAG,CAAEP,MAAM,iBACV/B,MAAA,CAAAuC,OAAA,CAAAC,aAAA,CAAClC,OAAA,CAAAiC,OAAiB,MAAAE,SAAA,CAAAF,OAAA;MAChBG,GAAG,EAAEX,MAAM,CAACM,EAAG;MACfjB,UAAU,EAAEA,UAAW;MACvBuB,SAAS,EAAE,IAAK;MAChBzB,QAAQ,EAAEA,QAAS;MACnBC,OAAO,EAAEA,OAAQ;MACjByB,IAAI,EAAC,QAAQ;MACbtB,cAAc,EAAEA,cAAe;MAC/BuB,aAAa,EAAEtB;IAAc,GACzBQ,MAAM,CACX,CACF,CAAC;IAEJ,oBACE/B,MAAA,CAAAuC,OAAA,CAAAC,aAAA,CAAChC,gBAAgB,qBACfR,MAAA,CAAAuC,OAAA,CAAAC,aAAA,CAACjC,qBAAA,CAAAuC,oBAAoB;MACnBT,EAAE,EAAC,cAAc;MACjBnB,QAAQ,EAAEA,QAAS;MACnBG,cAAc,EAAEA,cAAe;MAC/BG,gBAAgB,EAAEA;IAAiB,GAElCI,eACmB,CACN,CAAC;EAEvB;AACF;AAACmB,OAAA,CAAAlC,WAAA,GAAAA,WAAA;AAAA,IAAAmC,gBAAA,CAAAT,OAAA,EA7DY1B,WAAW,eACH;EACjBM,OAAO,EAAE8B,kBAAS,CAACC,MAAM,CAACC,UAAU;EACpC/B,UAAU,EAAE6B,kBAAS,CAACG,MAAM,CAACD,UAAU;EACvClC,KAAK,EAAEgC,kBAAS,CAACC,MAAM,CAACC,UAAU;EAClCjC,QAAQ,EAAE+B,kBAAS,CAACI,IAAI,CAACF,UAAU;EACnC9B,cAAc,EAAE4B,kBAAS,CAACK,IAAI;EAC9BhC,cAAc,EAAE2B,kBAAS,CAACC,MAAM;EAChC3B,aAAa,EAAE0B,kBAAS,CAACK,IAAI;EAC7B9B,gBAAgB,EAAEyB,kBAAS,CAACK;AAC9B,CAAC;AAAA,IAAAC,QAAA,GAAAR,OAAA,CAAAR,OAAA,GAqDY1B,WAAW","ignoreList":[]}
@@ -29,6 +29,7 @@ function DroppablePlaceholder({
29
29
  id,
30
30
  disabled,
31
31
  children,
32
+ onPlacementClick,
32
33
  ...rest
33
34
  }) {
34
35
  const {
@@ -41,8 +42,17 @@ function DroppablePlaceholder({
41
42
  },
42
43
  disabled
43
44
  });
45
+ const handleClick = () => {
46
+ if (disabled) {
47
+ return;
48
+ }
49
+ onPlacementClick?.({
50
+ type: 'choices-pool'
51
+ });
52
+ };
44
53
  return /*#__PURE__*/_react.default.createElement(Container, (0, _extends2.default)({
45
54
  ref: setNodeRef,
55
+ onClick: handleClick,
46
56
  style: {
47
57
  backgroundColor: isOver ? 'rgba(0,0,0,0.05)' : 'transparent'
48
58
  }
@@ -54,7 +64,8 @@ function DroppablePlaceholder({
54
64
  DroppablePlaceholder.propTypes = {
55
65
  id: _propTypes.default.oneOfType([_propTypes.default.string, _propTypes.default.number]),
56
66
  disabled: _propTypes.default.bool,
57
- children: _propTypes.default.node
67
+ children: _propTypes.default.node,
68
+ onPlacementClick: _propTypes.default.func
58
69
  };
59
70
  var _default = exports.default = DroppablePlaceholder;
60
71
  //# sourceMappingURL=droppable-placeholder.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"droppable-placeholder.js","names":["_react","_interopRequireDefault","require","_propTypes","_core","_styles","_drag","Container","styled","theme","alignItems","display","flexDirection","flexWrap","justifyContent","marginTop","spacing","marginBottom","minHeight","transition","DroppablePlaceholder","id","disabled","children","rest","setNodeRef","isOver","useDroppable","data","type","default","createElement","_extends2","ref","style","backgroundColor","MatchDroppablePlaceholder","propTypes","PropTypes","oneOfType","string","number","bool","node","_default","exports"],"sources":["../src/droppable-placeholder.jsx"],"sourcesContent":["import React from 'react';\nimport PropTypes from 'prop-types';\nimport { useDroppable } from '@dnd-kit/core';\nimport { styled } from '@mui/material/styles';\nimport { MatchDroppablePlaceholder } from '@pie-lib/drag';\n\nconst Container = styled('div')(({ theme }) => ({\n alignItems: 'center',\n display: 'flex',\n flexDirection: 'row',\n flexWrap: 'wrap',\n justifyContent: 'space-between',\n marginTop: theme.spacing(1),\n marginBottom: theme.spacing(1),\n minHeight: 50,\n transition: 'background-color 200ms ease',\n}));\n\nexport function DroppablePlaceholder({ id, disabled, children, ...rest }) {\n const { setNodeRef, isOver } = useDroppable({\n id: id || 'choices-pool',\n data: { type: 'choices-pool' },\n disabled,\n });\n\n return (\n <Container\n ref={setNodeRef}\n style={{ backgroundColor: isOver ? 'rgba(0,0,0,0.05)' : 'transparent' }}\n {...rest}\n >\n <MatchDroppablePlaceholder id={id} disabled={disabled}>\n {children}\n </MatchDroppablePlaceholder>\n </Container>\n );\n}\n\nDroppablePlaceholder.propTypes = {\n id: PropTypes.oneOfType([PropTypes.string, PropTypes.number]),\n disabled: PropTypes.bool,\n children: PropTypes.node,\n};\n\nexport default DroppablePlaceholder;\n"],"mappings":";;;;;;;;;AAAA,IAAAA,MAAA,GAAAC,sBAAA,CAAAC,OAAA;AACA,IAAAC,UAAA,GAAAF,sBAAA,CAAAC,OAAA;AACA,IAAAE,KAAA,GAAAF,OAAA;AACA,IAAAG,OAAA,GAAAH,OAAA;AACA,IAAAI,KAAA,GAAAJ,OAAA;AAEA,MAAMK,SAAS,GAAG,IAAAC,cAAM,EAAC,KAAK,CAAC,CAAC,CAAC;EAAEC;AAAM,CAAC,MAAM;EAC5CC,UAAU,EAAE,QAAQ;EACpBC,OAAO,EAAE,MAAM;EACfC,aAAa,EAAE,KAAK;EACpBC,QAAQ,EAAE,MAAM;EAChBC,cAAc,EAAE,eAAe;EAC/BC,SAAS,EAAEN,KAAK,CAACO,OAAO,CAAC,CAAC,CAAC;EAC3BC,YAAY,EAAER,KAAK,CAACO,OAAO,CAAC,CAAC,CAAC;EAC9BE,SAAS,EAAE,EAAE;EACbC,UAAU,EAAE;AAChB,CAAC,CAAC,CAAC;AAEI,SAASC,oBAAoBA,CAAC;EAAEC,EAAE;EAAEC,QAAQ;EAAEC,QAAQ;EAAE,GAAGC;AAAK,CAAC,EAAE;EACtE,MAAM;IAAEC,UAAU;IAAEC;EAAO,CAAC,GAAG,IAAAC,kBAAY,EAAC;IACxCN,EAAE,EAAEA,EAAE,IAAI,cAAc;IACxBO,IAAI,EAAE;MAAEC,IAAI,EAAE;IAAe,CAAC;IAC9BP;EACJ,CAAC,CAAC;EAEF,oBACItB,MAAA,CAAA8B,OAAA,CAAAC,aAAA,CAACxB,SAAS,MAAAyB,SAAA,CAAAF,OAAA;IACNG,GAAG,EAAER,UAAW;IAChBS,KAAK,EAAE;MAAEC,eAAe,EAAET,MAAM,GAAG,kBAAkB,GAAG;IAAc;EAAE,GACpEF,IAAI,gBAERxB,MAAA,CAAA8B,OAAA,CAAAC,aAAA,CAACzB,KAAA,CAAA8B,yBAAyB;IAACf,EAAE,EAAEA,EAAG;IAACC,QAAQ,EAAEA;EAAS,GACjDC,QACsB,CACpB,CAAC;AAEpB;AAEAH,oBAAoB,CAACiB,SAAS,GAAG;EAC7BhB,EAAE,EAAEiB,kBAAS,CAACC,SAAS,CAAC,CAACD,kBAAS,CAACE,MAAM,EAAEF,kBAAS,CAACG,MAAM,CAAC,CAAC;EAC7DnB,QAAQ,EAAEgB,kBAAS,CAACI,IAAI;EACxBnB,QAAQ,EAAEe,kBAAS,CAACK;AACxB,CAAC;AAAC,IAAAC,QAAA,GAAAC,OAAA,CAAAf,OAAA,GAEaV,oBAAoB","ignoreList":[]}
1
+ {"version":3,"file":"droppable-placeholder.js","names":["_react","_interopRequireDefault","require","_propTypes","_core","_styles","_drag","Container","styled","theme","alignItems","display","flexDirection","flexWrap","justifyContent","marginTop","spacing","marginBottom","minHeight","transition","DroppablePlaceholder","id","disabled","children","onPlacementClick","rest","setNodeRef","isOver","useDroppable","data","type","handleClick","default","createElement","_extends2","ref","onClick","style","backgroundColor","MatchDroppablePlaceholder","propTypes","PropTypes","oneOfType","string","number","bool","node","func","_default","exports"],"sources":["../src/droppable-placeholder.jsx"],"sourcesContent":["import React from 'react';\nimport PropTypes from 'prop-types';\nimport { useDroppable } from '@dnd-kit/core';\nimport { styled } from '@mui/material/styles';\nimport { MatchDroppablePlaceholder } from '@pie-lib/drag';\n\nconst Container = styled('div')(({ theme }) => ({\n alignItems: 'center',\n display: 'flex',\n flexDirection: 'row',\n flexWrap: 'wrap',\n justifyContent: 'space-between',\n marginTop: theme.spacing(1),\n marginBottom: theme.spacing(1),\n minHeight: 50,\n transition: 'background-color 200ms ease',\n}));\n\nexport function DroppablePlaceholder({ id, disabled, children, onPlacementClick, ...rest }) {\n const { setNodeRef, isOver } = useDroppable({\n id: id || 'choices-pool',\n data: { type: 'choices-pool' },\n disabled,\n });\n\n const handleClick = () => {\n if (disabled) {\n return;\n }\n\n onPlacementClick?.({ type: 'choices-pool' });\n };\n\n return (\n <Container\n ref={setNodeRef}\n onClick={handleClick}\n style={{ backgroundColor: isOver ? 'rgba(0,0,0,0.05)' : 'transparent' }}\n {...rest}\n >\n <MatchDroppablePlaceholder id={id} disabled={disabled}>\n {children}\n </MatchDroppablePlaceholder>\n </Container>\n );\n}\n\nDroppablePlaceholder.propTypes = {\n id: PropTypes.oneOfType([PropTypes.string, PropTypes.number]),\n disabled: PropTypes.bool,\n children: PropTypes.node,\n onPlacementClick: PropTypes.func,\n};\n\nexport default DroppablePlaceholder;\n"],"mappings":";;;;;;;;;AAAA,IAAAA,MAAA,GAAAC,sBAAA,CAAAC,OAAA;AACA,IAAAC,UAAA,GAAAF,sBAAA,CAAAC,OAAA;AACA,IAAAE,KAAA,GAAAF,OAAA;AACA,IAAAG,OAAA,GAAAH,OAAA;AACA,IAAAI,KAAA,GAAAJ,OAAA;AAEA,MAAMK,SAAS,GAAG,IAAAC,cAAM,EAAC,KAAK,CAAC,CAAC,CAAC;EAAEC;AAAM,CAAC,MAAM;EAC5CC,UAAU,EAAE,QAAQ;EACpBC,OAAO,EAAE,MAAM;EACfC,aAAa,EAAE,KAAK;EACpBC,QAAQ,EAAE,MAAM;EAChBC,cAAc,EAAE,eAAe;EAC/BC,SAAS,EAAEN,KAAK,CAACO,OAAO,CAAC,CAAC,CAAC;EAC3BC,YAAY,EAAER,KAAK,CAACO,OAAO,CAAC,CAAC,CAAC;EAC9BE,SAAS,EAAE,EAAE;EACbC,UAAU,EAAE;AAChB,CAAC,CAAC,CAAC;AAEI,SAASC,oBAAoBA,CAAC;EAAEC,EAAE;EAAEC,QAAQ;EAAEC,QAAQ;EAAEC,gBAAgB;EAAE,GAAGC;AAAK,CAAC,EAAE;EACxF,MAAM;IAAEC,UAAU;IAAEC;EAAO,CAAC,GAAG,IAAAC,kBAAY,EAAC;IACxCP,EAAE,EAAEA,EAAE,IAAI,cAAc;IACxBQ,IAAI,EAAE;MAAEC,IAAI,EAAE;IAAe,CAAC;IAC9BR;EACJ,CAAC,CAAC;EAEF,MAAMS,WAAW,GAAGA,CAAA,KAAM;IACtB,IAAIT,QAAQ,EAAE;MACZ;IACF;IAEAE,gBAAgB,GAAG;MAAEM,IAAI,EAAE;IAAe,CAAC,CAAC;EAChD,CAAC;EAED,oBACI9B,MAAA,CAAAgC,OAAA,CAAAC,aAAA,CAAC1B,SAAS,MAAA2B,SAAA,CAAAF,OAAA;IACNG,GAAG,EAAET,UAAW;IAChBU,OAAO,EAAEL,WAAY;IACrBM,KAAK,EAAE;MAAEC,eAAe,EAAEX,MAAM,GAAG,kBAAkB,GAAG;IAAc;EAAE,GACpEF,IAAI,gBAERzB,MAAA,CAAAgC,OAAA,CAAAC,aAAA,CAAC3B,KAAA,CAAAiC,yBAAyB;IAAClB,EAAE,EAAEA,EAAG;IAACC,QAAQ,EAAEA;EAAS,GACjDC,QACsB,CACpB,CAAC;AAEpB;AAEAH,oBAAoB,CAACoB,SAAS,GAAG;EAC7BnB,EAAE,EAAEoB,kBAAS,CAACC,SAAS,CAAC,CAACD,kBAAS,CAACE,MAAM,EAAEF,kBAAS,CAACG,MAAM,CAAC,CAAC;EAC7DtB,QAAQ,EAAEmB,kBAAS,CAACI,IAAI;EACxBtB,QAAQ,EAAEkB,kBAAS,CAACK,IAAI;EACxBtB,gBAAgB,EAAEiB,kBAAS,CAACM;AAChC,CAAC;AAAC,IAAAC,QAAA,GAAAC,OAAA,CAAAjB,OAAA,GAEaZ,oBAAoB","ignoreList":[]}
@@ -0,0 +1,154 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports.closestDroppableKeyboardCoordinates = void 0;
7
+ var _core = require("@dnd-kit/core");
8
+ const ARROW_STEP = 25;
9
+
10
+ /**
11
+ * Custom keyboard coordinate getter for non-sortable drag-and-drop.
12
+ *
13
+ * Tab/Shift+Tab cycle the dragged item directly onto the next/previous droppable
14
+ * (response area or the choices pool), in DOM order, placing the dragged item's own
15
+ * top-left corner at the target's center-left point. Arrow keys are left doing plain
16
+ * free-form movement (nudging the dragged item by a fixed step, same as dnd-kit's own
17
+ * default keyboard behavior) rather than jumping between droppables — collision
18
+ * detection (rectIntersection) still picks up whatever the item ends up actually
19
+ * overlapping.
20
+ */
21
+ const closestDroppableKeyboardCoordinates = (event, {
22
+ active,
23
+ context,
24
+ currentCoordinates
25
+ }) => {
26
+ const {
27
+ code
28
+ } = event;
29
+ const isTab = code === 'Tab';
30
+ const isArrow = code === _core.KeyboardCode.Down || code === _core.KeyboardCode.Up || code === _core.KeyboardCode.Left || code === _core.KeyboardCode.Right;
31
+ if (!isTab && !isArrow) {
32
+ return undefined;
33
+ }
34
+ event.preventDefault();
35
+ if (isArrow) {
36
+ switch (code) {
37
+ case _core.KeyboardCode.Down:
38
+ return {
39
+ ...currentCoordinates,
40
+ y: currentCoordinates.y + ARROW_STEP
41
+ };
42
+ case _core.KeyboardCode.Up:
43
+ return {
44
+ ...currentCoordinates,
45
+ y: currentCoordinates.y - ARROW_STEP
46
+ };
47
+ case _core.KeyboardCode.Right:
48
+ return {
49
+ ...currentCoordinates,
50
+ x: currentCoordinates.x + ARROW_STEP
51
+ };
52
+ case _core.KeyboardCode.Left:
53
+ return {
54
+ ...currentCoordinates,
55
+ x: currentCoordinates.x - ARROW_STEP
56
+ };
57
+ default:
58
+ return currentCoordinates;
59
+ }
60
+ }
61
+ const {
62
+ droppableRects,
63
+ droppableContainers,
64
+ collisionRect
65
+ } = context;
66
+ if (!droppableRects || droppableRects.size === 0) {
67
+ return currentCoordinates;
68
+ }
69
+
70
+ // A placed answer ("target") is itself a droppable for its own prompt slot
71
+ // ("drop-{promptId}"). That self drop-zone must never be treated as a navigable
72
+ // target: it sits under the dragged item, so a tiny (even sub-pixel) discrepancy
73
+ // between its measured rect and the dragged item's own rect is enough to make it
74
+ // register as the "closest" candidate, which reads as the drag being stuck.
75
+ // Exclude it outright rather than relying on a distance threshold.
76
+ const activeData = active?.data?.current;
77
+ const ownDropId = activeData?.promptId != null ? `drop-${activeData.promptId}` : undefined;
78
+
79
+ // Collect rect, top-left and center of all enabled droppable containers
80
+ const targets = [];
81
+ for (const [id, container] of droppableContainers) {
82
+ if (container?.disabled) continue;
83
+ if (id === ownDropId) continue;
84
+ const rect = droppableRects.get(id);
85
+ if (!rect) continue;
86
+ const center = {
87
+ x: rect.left + rect.width / 2,
88
+ y: rect.top + rect.height / 2
89
+ };
90
+ // Land the dragged item's own top-left corner at the target's center-left point,
91
+ // rather than at the target's own top-left corner.
92
+ const dropPosition = {
93
+ x: rect.left,
94
+ y: rect.top + rect.height / 2
95
+ };
96
+ targets.push({
97
+ id,
98
+ rect,
99
+ dropPosition,
100
+ center
101
+ });
102
+ }
103
+ if (targets.length === 0) {
104
+ return currentCoordinates;
105
+ }
106
+
107
+ // Tab/Shift+Tab: cycle through targets in DOM order (sorted top-to-bottom, left-to-right)
108
+ const reverse = event.shiftKey;
109
+
110
+ // Sort targets by position (top to bottom, then left to right)
111
+ targets.sort((a, b) => {
112
+ if (Math.abs(a.center.y - b.center.y) > 10) return a.center.y - b.center.y;
113
+ return a.center.x - b.center.x;
114
+ });
115
+
116
+ // Find the current target. Whichever target the dragged item's own center point
117
+ // actually falls inside of is the current target — this is what "currently sitting
118
+ // on a target" means, and it holds regardless of how the dragged item's size compares
119
+ // to the target's: a compact answer tile landed (per `dropPosition` above) at a wide
120
+ // response row's left edge is still contained within that row's rect.
121
+ //
122
+ // Comparing distances between the dragged item's *center* and each target's *center*
123
+ // (as this used to) breaks down for exactly that shape (a small tile in a much wider
124
+ // row): the dragged item's own center sits well short of the row's true center, by
125
+ // roughly half the width difference — enough that a completely different droppable
126
+ // (e.g. the choices pool) can end up "closer", so once the item is actually sitting on
127
+ // a target, the next press re-matches the position as if it were still somewhere
128
+ // else, and keeps recomputing the same move instead of advancing.
129
+ const draggedCenter = collisionRect ? {
130
+ x: collisionRect.left + collisionRect.width / 2,
131
+ y: collisionRect.top + collisionRect.height / 2
132
+ } : currentCoordinates;
133
+ let currentIndex = targets.findIndex(t => draggedCenter.x >= t.rect.left && draggedCenter.x <= t.rect.right && draggedCenter.y >= t.rect.top && draggedCenter.y <= t.rect.bottom);
134
+
135
+ // Fall back to nearest-by-dropPosition if the dragged item's center isn't strictly
136
+ // inside any target (e.g. mid-flight after a free arrow-key move).
137
+ if (currentIndex === -1) {
138
+ let minDist = Infinity;
139
+ for (let i = 0; i < targets.length; i++) {
140
+ const dist = distance(currentCoordinates, targets[i].dropPosition);
141
+ if (dist < minDist) {
142
+ minDist = dist;
143
+ currentIndex = i;
144
+ }
145
+ }
146
+ }
147
+
148
+ // Move to next/previous
149
+ const nextIndex = reverse ? (currentIndex - 1 + targets.length) % targets.length : (currentIndex + 1) % targets.length;
150
+ return targets[nextIndex].dropPosition;
151
+ };
152
+ exports.closestDroppableKeyboardCoordinates = closestDroppableKeyboardCoordinates;
153
+ const distance = (a, b) => Math.sqrt((a.x - b.x) ** 2 + (a.y - b.y) ** 2);
154
+ //# sourceMappingURL=keyboard-coordinates.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"keyboard-coordinates.js","names":["_core","require","ARROW_STEP","closestDroppableKeyboardCoordinates","event","active","context","currentCoordinates","code","isTab","isArrow","KeyboardCode","Down","Up","Left","Right","undefined","preventDefault","y","x","droppableRects","droppableContainers","collisionRect","size","activeData","data","current","ownDropId","promptId","targets","id","container","disabled","rect","get","center","left","width","top","height","dropPosition","push","length","reverse","shiftKey","sort","a","b","Math","abs","draggedCenter","currentIndex","findIndex","t","right","bottom","minDist","Infinity","i","dist","distance","nextIndex","exports","sqrt"],"sources":["../src/keyboard-coordinates.js"],"sourcesContent":["import { KeyboardCode } from '@dnd-kit/core';\n\nconst ARROW_STEP = 25;\n\n/**\n * Custom keyboard coordinate getter for non-sortable drag-and-drop.\n *\n * Tab/Shift+Tab cycle the dragged item directly onto the next/previous droppable\n * (response area or the choices pool), in DOM order, placing the dragged item's own\n * top-left corner at the target's center-left point. Arrow keys are left doing plain\n * free-form movement (nudging the dragged item by a fixed step, same as dnd-kit's own\n * default keyboard behavior) rather than jumping between droppables — collision\n * detection (rectIntersection) still picks up whatever the item ends up actually\n * overlapping.\n */\nexport const closestDroppableKeyboardCoordinates = (event, { active, context, currentCoordinates }) => {\n const { code } = event;\n const isTab = code === 'Tab';\n const isArrow =\n code === KeyboardCode.Down || code === KeyboardCode.Up || code === KeyboardCode.Left || code === KeyboardCode.Right;\n\n if (!isTab && !isArrow) {\n return undefined;\n }\n\n event.preventDefault();\n\n if (isArrow) {\n switch (code) {\n case KeyboardCode.Down:\n return { ...currentCoordinates, y: currentCoordinates.y + ARROW_STEP };\n\n case KeyboardCode.Up:\n return { ...currentCoordinates, y: currentCoordinates.y - ARROW_STEP };\n\n case KeyboardCode.Right:\n return { ...currentCoordinates, x: currentCoordinates.x + ARROW_STEP };\n\n case KeyboardCode.Left:\n return { ...currentCoordinates, x: currentCoordinates.x - ARROW_STEP };\n\n default:\n return currentCoordinates;\n }\n }\n\n const { droppableRects, droppableContainers, collisionRect } = context;\n\n if (!droppableRects || droppableRects.size === 0) {\n return currentCoordinates;\n }\n\n // A placed answer (\"target\") is itself a droppable for its own prompt slot\n // (\"drop-{promptId}\"). That self drop-zone must never be treated as a navigable\n // target: it sits under the dragged item, so a tiny (even sub-pixel) discrepancy\n // between its measured rect and the dragged item's own rect is enough to make it\n // register as the \"closest\" candidate, which reads as the drag being stuck.\n // Exclude it outright rather than relying on a distance threshold.\n const activeData = active?.data?.current;\n const ownDropId = activeData?.promptId != null ? `drop-${activeData.promptId}` : undefined;\n\n // Collect rect, top-left and center of all enabled droppable containers\n const targets = [];\n\n for (const [id, container] of droppableContainers) {\n if (container?.disabled) continue;\n\n if (id === ownDropId) continue;\n\n const rect = droppableRects.get(id);\n\n if (!rect) continue;\n\n const center = {\n x: rect.left + rect.width / 2,\n y: rect.top + rect.height / 2,\n };\n // Land the dragged item's own top-left corner at the target's center-left point,\n // rather than at the target's own top-left corner.\n const dropPosition = {\n x: rect.left,\n y: rect.top + rect.height / 2,\n };\n\n targets.push({ id, rect, dropPosition, center });\n }\n\n if (targets.length === 0) {\n return currentCoordinates;\n }\n\n // Tab/Shift+Tab: cycle through targets in DOM order (sorted top-to-bottom, left-to-right)\n const reverse = event.shiftKey;\n\n // Sort targets by position (top to bottom, then left to right)\n targets.sort((a, b) => {\n if (Math.abs(a.center.y - b.center.y) > 10) return a.center.y - b.center.y;\n return a.center.x - b.center.x;\n });\n\n // Find the current target. Whichever target the dragged item's own center point\n // actually falls inside of is the current target — this is what \"currently sitting\n // on a target\" means, and it holds regardless of how the dragged item's size compares\n // to the target's: a compact answer tile landed (per `dropPosition` above) at a wide\n // response row's left edge is still contained within that row's rect.\n //\n // Comparing distances between the dragged item's *center* and each target's *center*\n // (as this used to) breaks down for exactly that shape (a small tile in a much wider\n // row): the dragged item's own center sits well short of the row's true center, by\n // roughly half the width difference — enough that a completely different droppable\n // (e.g. the choices pool) can end up \"closer\", so once the item is actually sitting on\n // a target, the next press re-matches the position as if it were still somewhere\n // else, and keeps recomputing the same move instead of advancing.\n const draggedCenter = collisionRect\n ? { x: collisionRect.left + collisionRect.width / 2, y: collisionRect.top + collisionRect.height / 2 }\n : currentCoordinates;\n\n let currentIndex = targets.findIndex(\n (t) => draggedCenter.x >= t.rect.left && draggedCenter.x <= t.rect.right && draggedCenter.y >= t.rect.top && draggedCenter.y <= t.rect.bottom,\n );\n\n // Fall back to nearest-by-dropPosition if the dragged item's center isn't strictly\n // inside any target (e.g. mid-flight after a free arrow-key move).\n if (currentIndex === -1) {\n let minDist = Infinity;\n\n for (let i = 0; i < targets.length; i++) {\n const dist = distance(currentCoordinates, targets[i].dropPosition);\n\n if (dist < minDist) {\n minDist = dist;\n currentIndex = i;\n }\n }\n }\n\n // Move to next/previous\n const nextIndex = reverse\n ? (currentIndex - 1 + targets.length) % targets.length\n : (currentIndex + 1) % targets.length;\n\n return targets[nextIndex].dropPosition;\n};\n\nconst distance = (a, b) => Math.sqrt((a.x - b.x) ** 2 + (a.y - b.y) ** 2);\n"],"mappings":"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","ignoreList":[]}