@pie-element/placement-ordering 14.1.2-next.2 → 14.1.2-next.20
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/author.js +2 -0
- package/dist/author/choice-editor.js +2 -2
- package/dist/author/choice-tile.js +3 -2
- package/dist/author/design.js +1 -1
- package/dist/author/index.d.ts +1 -0
- package/dist/author/index.js +5 -2
- package/dist/browser/assets/Symbola-4c507403.woff2 +0 -0
- package/dist/browser/author/index.js +14940 -19583
- package/dist/browser/author/index.js.map +1 -1
- package/dist/browser/{browser-Dbw2uHQ7.js → browser-DMpDEszG.js} +7 -3
- package/dist/browser/browser-DMpDEszG.js.map +1 -0
- package/dist/browser/controller/index.js +140 -55
- package/dist/browser/controller/index.js.map +1 -1
- package/dist/browser/delivery/index.js +474 -325
- package/dist/browser/delivery/index.js.map +1 -1
- package/dist/browser/{dist-D9ARZhQk.js → dist-DCmVXYeO.js} +109 -7
- package/dist/browser/dist-DCmVXYeO.js.map +1 -0
- package/dist/browser/{drag-provider-C4BiCI76.js → drag-provider-LgVkQ5Yi.js} +2219 -2266
- package/dist/browser/drag-provider-LgVkQ5Yi.js.map +1 -0
- package/dist/browser/editor-runtime/assets/Symbola-4c507403.woff2 +0 -0
- package/dist/browser/editor-runtime/author/index.js +19668 -0
- package/dist/browser/editor-runtime/author/index.js.map +1 -0
- package/dist/browser/editor-runtime/browser-0nthm_zo.js +376 -0
- package/dist/browser/editor-runtime/browser-0nthm_zo.js.map +1 -0
- package/dist/browser/editor-runtime/controller/index.js +327 -0
- package/dist/browser/editor-runtime/controller/index.js.map +1 -0
- package/dist/browser/editor-runtime/delivery/index.js +1184 -0
- package/dist/browser/editor-runtime/delivery/index.js.map +1 -0
- package/dist/browser/editor-runtime/dist-DCmVXYeO.js +1528 -0
- package/dist/browser/editor-runtime/dist-DCmVXYeO.js.map +1 -0
- package/dist/browser/editor-runtime/drag-provider-Dpx1BjBS.js +10508 -0
- package/dist/browser/editor-runtime/drag-provider-Dpx1BjBS.js.map +1 -0
- package/dist/controller/scoring.js +3 -3
- package/dist/delivery/index.js +2 -2
- package/dist/delivery/keyboard-coordinates.d.ts +47 -0
- package/dist/delivery/keyboard-coordinates.js +51 -0
- package/dist/delivery/main.js +1 -1
- package/dist/delivery/ordering.js +14 -19
- package/dist/delivery/placement-ordering.d.ts +13 -0
- package/dist/delivery/placement-ordering.js +168 -83
- package/dist/delivery/tile.d.ts +3 -0
- package/dist/delivery/tile.js +75 -61
- package/dist/delivery/tiler.d.ts +6 -0
- package/dist/delivery/tiler.js +6 -3
- package/dist/index.iife.js +35 -35
- package/package.json +36 -25
- package/dist/browser/browser-Dbw2uHQ7.js.map +0 -1
- package/dist/browser/dist-D9ARZhQk.js.map +0 -1
- package/dist/browser/drag-provider-C4BiCI76.js.map +0 -1
- package/dist/browser/placement-ordering.css +0 -2
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { differenceWith as e, isEqual as t, uniq as n } from "@pie-element/shared-lodash";
|
|
2
2
|
import r from "debug";
|
|
3
|
-
import {
|
|
3
|
+
import { Combination as i } from "js-combinatorics";
|
|
4
4
|
//#region src/controller/scoring.ts
|
|
5
5
|
var a = r("pie-elements:placement-ordering:controller"), o = (e) => /* @__PURE__ */ Error(`Cant score answer: ${e} it has duplicates and allowDuplicates is false`), s = (r, s, c) => {
|
|
6
6
|
if (c = {
|
|
@@ -12,7 +12,7 @@ var a = r("pie-elements:placement-ordering:controller"), o = (e) => /* @__PURE__
|
|
|
12
12
|
if (s = c.allowDuplicates === !1 ? n(s) : s, a("answer:", s), !Array.isArray(r) || r.length === 0) throw Error("correct must be non empty an array");
|
|
13
13
|
if (r.length === 1) return +!!t(r, s);
|
|
14
14
|
if (!Array.isArray(s) || s.length < 2 || s.length > r.length || r.length !== s.length && c.orderMustBeComplete) return 0;
|
|
15
|
-
let l = i(r, 2).toArray(), u = i(s, 2).toArray(), d = e(u, l, t), f = l.length - u.length, p = l.length, m = ((p - d.length - f) / p).toFixed(2);
|
|
15
|
+
let l = new i(r, 2).toArray(), u = new i(s, 2).toArray(), d = e(u, l, t), f = l.length - u.length, p = l.length, m = ((p - d.length - f) / p).toFixed(2);
|
|
16
16
|
return parseFloat(m);
|
|
17
17
|
}, c = (e) => e.correctResponse ? e.correctResponse.map((e) => e && e.id ? e.id : e) : [], l = (e) => {
|
|
18
18
|
let t = (e.alternateResponses || []).map((e) => Array.isArray(e) ? e : e.response).filter((e) => e !== void 0);
|
|
@@ -27,4 +27,4 @@ var a = r("pie-elements:placement-ordering:controller"), o = (e) => /* @__PURE__
|
|
|
27
27
|
}), a;
|
|
28
28
|
};
|
|
29
29
|
//#endregion
|
|
30
|
-
export { c as flattenCorrect, l as getAllCorrectResponses, u as score };
|
|
30
|
+
export { c as flattenCorrect, l as getAllCorrectResponses, o as illegalArgumentError, s as pairwiseCombinationScore, u as score };
|
package/dist/delivery/index.js
CHANGED
|
@@ -60,10 +60,10 @@ var s = i("pie-elements:placement-ordering"), c = ({ model: e, session: t }) =>
|
|
|
60
60
|
}
|
|
61
61
|
}
|
|
62
62
|
connectedCallback() {
|
|
63
|
-
this._initMathObserver();
|
|
63
|
+
this._initMathObserver(), this.render();
|
|
64
64
|
}
|
|
65
65
|
disconnectedCallback() {
|
|
66
|
-
this._disconnectMathObserver(), this._root
|
|
66
|
+
this._disconnectMathObserver(), this._root &&= (this._root.unmount(), null);
|
|
67
67
|
}
|
|
68
68
|
};
|
|
69
69
|
//#endregion
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @synced-from pie-elements/packages/placement-ordering/src/keyboard-coordinates.js
|
|
3
|
+
* @auto-generated
|
|
4
|
+
*
|
|
5
|
+
* This file is automatically synced from pie-elements and converted to TypeScript.
|
|
6
|
+
* Manual edits will be overwritten on next sync.
|
|
7
|
+
* To make changes, edit the upstream JavaScript file and run sync again.
|
|
8
|
+
*/
|
|
9
|
+
/**
|
|
10
|
+
* Custom keyboard coordinate getter for placement-ordering's Tab-based placement mode
|
|
11
|
+
* (enabled only when the item is configured with `placementArea` / `includeTargets`).
|
|
12
|
+
*
|
|
13
|
+
* Tab/Shift+Tab cycle the dragged choice through the target column's response areas
|
|
14
|
+
* in on-screen order (first target, then the rest in sequence), followed by exactly
|
|
15
|
+
* one source-column stop as a fixed last step before the cycle wraps back to the first
|
|
16
|
+
* target — so picking up a choice always starts the cycle at the first target,
|
|
17
|
+
* regardless of where that choice's own source-column slot happens to sit on screen.
|
|
18
|
+
*
|
|
19
|
+
* Arrow keys are delegated to dnd-kit's own `defaultKeyboardCoordinateGetter` so the
|
|
20
|
+
* pre-existing free-form arrow-key dragging behavior is left completely unchanged.
|
|
21
|
+
*
|
|
22
|
+
* Whichever slot a drag started from — a target the choice was already placed in, or
|
|
23
|
+
* (see below) the choice's own pool slot — stays reachable by Tab as a no-op "drop it
|
|
24
|
+
* back where it came from": tile.tsx disables a droppable for the whole duration of
|
|
25
|
+
* its own drag (a self-collision guard for pointer drags), which would otherwise make
|
|
26
|
+
* that exact slot unreachable; that guard is bypassed here specifically for the one
|
|
27
|
+
* droppable matching the active drag's own id. A target slot picked up this way stays
|
|
28
|
+
* in its normal position in the target sequence (it's just another target); nothing
|
|
29
|
+
* special is needed there beyond the bypass itself.
|
|
30
|
+
*
|
|
31
|
+
* The choices column isn't a place a student can choose to relocate an answer within —
|
|
32
|
+
* there's exactly one meaningful "source" stop for whichever choice is currently being
|
|
33
|
+
* dragged: its own fixed slot, whether that's the vacated gap left behind (if the
|
|
34
|
+
* choice is already placed in a target — landing back on it returns the choice to the
|
|
35
|
+
* pool, undoing the placement) or the very tile being dragged (if the choice is still
|
|
36
|
+
* sitting there, unplaced — landing back on it is a no-op that effectively cancels the
|
|
37
|
+
* pick-up; the same disabled-droppable bypass applies here too). Every *other*
|
|
38
|
+
* choice-column tile — filled or an empty gap — is excluded from the cycle:
|
|
39
|
+
* `ordering.ts`'s `updateResponse` has no `choice -> choice` case, so they'd be no-op
|
|
40
|
+
* drop targets anyway. Matching is by id (the vacated gap carries its original choice's
|
|
41
|
+
* id specifically so this comparison works), not by type alone.
|
|
42
|
+
*/
|
|
43
|
+
export declare const closestDroppableKeyboardCoordinates: (event: any, { active, context, currentCoordinates }: {
|
|
44
|
+
active: any;
|
|
45
|
+
context: any;
|
|
46
|
+
currentCoordinates: any;
|
|
47
|
+
}) => any;
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
import { KeyboardCode as e, defaultKeyboardCoordinateGetter as t } from "@dnd-kit/core";
|
|
2
|
+
//#region src/delivery/keyboard-coordinates.ts
|
|
3
|
+
var n = (n, { active: i, context: a, currentCoordinates: o }) => {
|
|
4
|
+
let { code: s } = n, c = s === "Tab", l = s === e.Down || s === e.Up || s === e.Left || s === e.Right;
|
|
5
|
+
if (!c && !l) return;
|
|
6
|
+
if (l) return t(n, {
|
|
7
|
+
context: a,
|
|
8
|
+
currentCoordinates: o
|
|
9
|
+
});
|
|
10
|
+
n.preventDefault();
|
|
11
|
+
let { droppableRects: u, droppableContainers: d, collisionRect: f, draggableNodes: p, active: m } = a;
|
|
12
|
+
if (!u || u.size === 0) return o;
|
|
13
|
+
let h = {
|
|
14
|
+
x: (f?.width || 0) / 2,
|
|
15
|
+
y: (f?.height || 0) / 2
|
|
16
|
+
}, g = {
|
|
17
|
+
x: o.x + h.x,
|
|
18
|
+
y: o.y + h.y
|
|
19
|
+
}, _ = p?.get(i)?.data?.current?.id, v = m?.rect?.current?.initial, y = typeof i == "string" ? i.replace(/^tile-/, "drop-") : void 0, b = [], x;
|
|
20
|
+
for (let [e, t] of d) {
|
|
21
|
+
let n = t?.data?.current, r = e === y;
|
|
22
|
+
if (t?.disabled && !r) continue;
|
|
23
|
+
let i = n?.type === "choice" && n?.id === _;
|
|
24
|
+
if (n?.type === "choice" && !i) continue;
|
|
25
|
+
let a = (r ? v : null) || u.get(e);
|
|
26
|
+
if (!a) continue;
|
|
27
|
+
let o = {
|
|
28
|
+
x: a.left + a.width / 2,
|
|
29
|
+
y: a.top + a.height / 2
|
|
30
|
+
}, s = {
|
|
31
|
+
id: e,
|
|
32
|
+
dropPosition: {
|
|
33
|
+
x: a.left,
|
|
34
|
+
y: a.top + a.height / 2 - h.y
|
|
35
|
+
},
|
|
36
|
+
center: o
|
|
37
|
+
};
|
|
38
|
+
i ? x = s : b.push(s);
|
|
39
|
+
}
|
|
40
|
+
if (b.length === 0 && !x) return o;
|
|
41
|
+
let S = n.shiftKey;
|
|
42
|
+
b.sort((e, t) => Math.abs(e.center.y - t.center.y) > 10 ? e.center.y - t.center.y : e.center.x - t.center.x), x && b.push(x);
|
|
43
|
+
let C = 0, w = Infinity;
|
|
44
|
+
for (let e = 0; e < b.length; e++) {
|
|
45
|
+
let t = r(g, b[e].center);
|
|
46
|
+
t < w && (w = t, C = e);
|
|
47
|
+
}
|
|
48
|
+
return b[S ? (C - 1 + b.length) % b.length : (C + 1) % b.length].dropPosition;
|
|
49
|
+
}, r = (e, t) => Math.sqrt((e.x - t.x) ** 2 + (e.y - t.y) ** 2);
|
|
50
|
+
//#endregion
|
|
51
|
+
export { n as closestDroppableKeyboardCoordinates };
|
package/dist/delivery/main.js
CHANGED
|
@@ -8,26 +8,20 @@ var a = i("pie-elements:placement-ordering:ordering"), o = (e, t, n) => {
|
|
|
8
8
|
r,
|
|
9
9
|
...i.slice(n)
|
|
10
10
|
];
|
|
11
|
-
}, s = (e, n, r) => {
|
|
12
|
-
if (a("[swap]", e, n, r), !e || e.length <= 1 || n === void 0 || r === void 0) throw Error(`swap requires a non-empty array, fromIndex, toIndex: ${e}, ${n} ${r}`);
|
|
13
|
-
let i = t(e), o = e[r];
|
|
14
|
-
return i[r] = i[n], i[n] = o, i;
|
|
15
11
|
};
|
|
16
|
-
function
|
|
12
|
+
function s(e, n) {
|
|
17
13
|
let r = t(e.response);
|
|
18
14
|
if (r[n.index] === n.id) r[n.index] = void 0;
|
|
19
15
|
else throw Error(`Tried to remove from index: ${n.index}, but the id doesn't match: array: ${r}, target: ${n.id}`);
|
|
20
16
|
return r;
|
|
21
17
|
}
|
|
22
|
-
function
|
|
23
|
-
let { response: i, opts:
|
|
24
|
-
if (
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
return a("fromIndex: ", t, "toIndex:", i), o(e.response, t, i);
|
|
28
|
-
}
|
|
18
|
+
function c(e, n, r) {
|
|
19
|
+
let { response: i, opts: s } = e, c = t(i);
|
|
20
|
+
if (s.includeTargets) return n.type === "choice" && r.type === "target" ? (c[r.index] = n.id, c) : n.type === "target" && r.type === "choice" ? (c[n.index] = void 0, c) : n.type === "target" && r.type === "target" ? (c[r.index] = n.id, c[n.index] = void 0, c) : (a("do nothing to the response"), i);
|
|
21
|
+
let l = e.response.findIndex((e) => e !== void 0 && e === n.id), u = e.response.findIndex((e) => e !== void 0 && e === r.id);
|
|
22
|
+
return a("fromIndex: ", l, "toIndex:", u), o(e.response, l, u);
|
|
29
23
|
}
|
|
30
|
-
function
|
|
24
|
+
function l(e, t, n, r) {
|
|
31
25
|
if (r.includeTargets) {
|
|
32
26
|
let i = [];
|
|
33
27
|
for (let r = 0; r < t.length; r++) {
|
|
@@ -40,6 +34,7 @@ function u(e, t, n, r) {
|
|
|
40
34
|
}
|
|
41
35
|
return e.map((e) => t.indexOf(e.id) !== -1 && !r.allowSameChoiceInTargets ? {
|
|
42
36
|
type: "choice",
|
|
37
|
+
id: e.id,
|
|
43
38
|
empty: !0,
|
|
44
39
|
droppable: !0,
|
|
45
40
|
draggable: !1
|
|
@@ -61,26 +56,26 @@ function u(e, t, n, r) {
|
|
|
61
56
|
return i === 0 && t.push(a), t.push(o, a), t;
|
|
62
57
|
}, []);
|
|
63
58
|
}
|
|
64
|
-
function
|
|
59
|
+
function u(t, i, a, o) {
|
|
65
60
|
return o = e({ includeTargets: !0 }, o), a ||= [], i = !i || n(i) ? o.includeTargets ? Array(t.length) : r(t, (e) => e.id) : i, {
|
|
66
61
|
choices: t,
|
|
67
62
|
response: i,
|
|
68
63
|
opts: o,
|
|
69
64
|
outcomes: a,
|
|
70
|
-
tiles:
|
|
65
|
+
tiles: l(t, i, a, o)
|
|
71
66
|
};
|
|
72
67
|
}
|
|
73
|
-
function
|
|
68
|
+
function d(e, t) {
|
|
74
69
|
switch (e.type) {
|
|
75
70
|
case "move": {
|
|
76
|
-
let { from: n, to: r } = e, i =
|
|
71
|
+
let { from: n, to: r } = e, i = c(t, n, r), a = l(t.choices, i, t.outcomes, t.opts);
|
|
77
72
|
return Object.assign({}, t, {
|
|
78
73
|
response: i,
|
|
79
74
|
tiles: a
|
|
80
75
|
});
|
|
81
76
|
}
|
|
82
77
|
case "remove": {
|
|
83
|
-
let { target: n } = e, r =
|
|
78
|
+
let { target: n } = e, r = s(t, n), i = l(t.choices, r, t.outcomes, t.opts);
|
|
84
79
|
return Object.assign({}, t, {
|
|
85
80
|
response: r,
|
|
86
81
|
tiles: i
|
|
@@ -90,4 +85,4 @@ function f(e, t) {
|
|
|
90
85
|
return t;
|
|
91
86
|
}
|
|
92
87
|
//#endregion
|
|
93
|
-
export {
|
|
88
|
+
export { u as buildState, o as push, d as reducer };
|
|
@@ -23,6 +23,19 @@ export declare class PlacementOrdering extends React.Component {
|
|
|
23
23
|
onRemoveChoice: any;
|
|
24
24
|
createOrdering: any;
|
|
25
25
|
onDragEnd: any;
|
|
26
|
+
onDragStart: any;
|
|
27
|
+
onDragCancel: any;
|
|
28
|
+
isSameChoice: (a: any, b: any) => boolean;
|
|
29
|
+
selectChoice: any;
|
|
30
|
+
toggleChoiceSelection: any;
|
|
31
|
+
cancelSelection: any;
|
|
32
|
+
endAnyLiveKeyboardDrag: any;
|
|
33
|
+
placeSelectedChoice: any;
|
|
34
|
+
getDestinationSlotId: any;
|
|
35
|
+
focusTile: any;
|
|
36
|
+
isClickSoonAfterDragEnd: () => boolean;
|
|
37
|
+
onChoiceClick: any;
|
|
38
|
+
onPlacementClick: any;
|
|
26
39
|
render(): React.JSX.Element;
|
|
27
40
|
}
|
|
28
41
|
export default PlacementOrdering;
|
|
@@ -1,62 +1,88 @@
|
|
|
1
1
|
import { HorizontalTiler as e, VerticalTiler as t } from "./tiler.js";
|
|
2
2
|
import { buildState as n, reducer as r } from "./ordering.js";
|
|
3
3
|
import { haveSameValuesButDifferentOrder as i } from "./utils.js";
|
|
4
|
-
import a from "
|
|
5
|
-
import
|
|
6
|
-
import l from "
|
|
7
|
-
import
|
|
8
|
-
import d from "
|
|
9
|
-
import f from "
|
|
10
|
-
import
|
|
11
|
-
import {
|
|
12
|
-
import
|
|
13
|
-
import {
|
|
14
|
-
import
|
|
15
|
-
import
|
|
16
|
-
import E from "
|
|
17
|
-
import
|
|
4
|
+
import { closestDroppableKeyboardCoordinates as a } from "./keyboard-coordinates.js";
|
|
5
|
+
import o from "react";
|
|
6
|
+
import { difference as s, isEqual as c, uniqueId as l } from "@pie-element/shared-lodash";
|
|
7
|
+
import u from "debug";
|
|
8
|
+
import { renderMath as d } from "@pie-element/shared-math-rendering-mathjax";
|
|
9
|
+
import f from "prop-types";
|
|
10
|
+
import p from "react-dom";
|
|
11
|
+
import { styled as m } from "@mui/material/styles";
|
|
12
|
+
import { rectIntersection as h } from "@dnd-kit/core";
|
|
13
|
+
import { restrictToParentElement as g } from "@dnd-kit/modifiers";
|
|
14
|
+
import * as _ from "@pie-lib/render-ui";
|
|
15
|
+
import { Collapsible as v, Feedback as y, PreviewPrompt as b, UiLayout as x, color as S, hasMedia as C, hasText as w } from "@pie-lib/render-ui";
|
|
16
|
+
import { jsx as T, jsxs as E } from "react/jsx-runtime";
|
|
17
|
+
import D from "@pie-lib/translator";
|
|
18
|
+
import O from "@pie-lib/correct-answer-toggle";
|
|
19
|
+
import { DragProvider as k } from "@pie-lib/drag";
|
|
18
20
|
//#region src/delivery/placement-ordering.tsx
|
|
19
|
-
function
|
|
21
|
+
function A(e) {
|
|
20
22
|
return typeof e == "function" || typeof e == "object" && !!e && typeof e.$$typeof == "symbol";
|
|
21
23
|
}
|
|
22
|
-
function
|
|
23
|
-
return !e ||
|
|
24
|
+
function j(e, t) {
|
|
25
|
+
return !e || A(e) ? e : A(e.default) ? e.default : t && A(e[t]) ? e[t] : t && A(e[t]?.default) ? e[t].default : e;
|
|
24
26
|
}
|
|
25
|
-
var
|
|
26
|
-
|
|
27
|
-
|
|
27
|
+
var M = j(x, "UiLayout") || j(R.UiLayout, "UiLayout"), N = j(b, "PreviewPrompt") || j(R.PreviewPrompt, "PreviewPrompt"), P = j(y, "Feedback") || j(R.Feedback, "Feedback"), F = j(v, "Collapsible") || j(R.Collapsible, "Collapsible"), I = _, L = I.default, R = L && typeof L == "object" ? L : I, z = 250, B = (e, t) => {
|
|
28
|
+
if (!e || !t) return !1;
|
|
29
|
+
let n = t.left + t.width / 2, r = t.top + t.height / 2;
|
|
30
|
+
return n >= e.left && n <= e.right && r >= e.top && r <= e.bottom;
|
|
31
|
+
}, V = (e) => e ? {
|
|
32
|
+
keyboardCoordinateGetter: a,
|
|
33
|
+
keyboardCodes: {
|
|
34
|
+
start: ["Space", "Enter"],
|
|
35
|
+
cancel: ["Escape"],
|
|
36
|
+
end: ["Space", "Enter"]
|
|
37
|
+
},
|
|
38
|
+
accessibility: { screenReaderInstructions: { draggable: "Press Space or Enter to pick up this answer choice. Once picked up, use Tab or Shift+Tab to cycle through response areas, or use arrow keys to move it freely. Press Space or Enter to drop, or Escape to cancel." } }
|
|
39
|
+
} : {}, { translator: H } = D, U = u("pie-elements:placement-ordering"), W = m("div")({
|
|
40
|
+
color: S.text(),
|
|
41
|
+
backgroundColor: S.background(),
|
|
28
42
|
display: "flex",
|
|
29
43
|
flexDirection: "column",
|
|
30
44
|
alignItems: "center",
|
|
31
45
|
boxSizing: "border-box"
|
|
32
|
-
}),
|
|
46
|
+
}), G = m("div")({
|
|
47
|
+
alignSelf: "stretch",
|
|
48
|
+
maxWidth: "100%",
|
|
49
|
+
overflowX: "auto",
|
|
50
|
+
overflowY: "hidden"
|
|
51
|
+
}), K = m("div")({
|
|
52
|
+
display: "flex",
|
|
53
|
+
justifyContent: "center",
|
|
54
|
+
minWidth: "min-content"
|
|
55
|
+
}), q = m("div")(({ theme: e }) => ({ paddingBottom: e.spacing(1) })), J = m("div")(({ theme: e }) => ({ paddingBottom: e.spacing(2) })), Y = m(O)(({ theme: e }) => ({ paddingBottom: e.spacing(1) })), X = m(F)(({ theme: e }) => ({
|
|
33
56
|
marginBottom: e.spacing(2),
|
|
34
57
|
alignSelf: "flex-start"
|
|
35
|
-
})),
|
|
58
|
+
})), Z = (e) => {
|
|
36
59
|
let { tiler: t, ordering: n, onDropChoice: r, onRemoveChoice: i, ...a } = e;
|
|
37
|
-
return /* @__PURE__ */
|
|
60
|
+
return /* @__PURE__ */ T(t, {
|
|
38
61
|
...a,
|
|
39
62
|
tiles: n.tiles,
|
|
40
63
|
onDropChoice: (e, t) => r(e, t, n),
|
|
41
64
|
onRemoveChoice: (e) => i(e, n)
|
|
42
65
|
});
|
|
43
66
|
};
|
|
44
|
-
|
|
45
|
-
tiler:
|
|
46
|
-
ordering:
|
|
47
|
-
onDropChoice:
|
|
48
|
-
onRemoveChoice:
|
|
67
|
+
Z.propTypes = {
|
|
68
|
+
tiler: f.func,
|
|
69
|
+
ordering: f.any,
|
|
70
|
+
onDropChoice: f.func,
|
|
71
|
+
onRemoveChoice: f.func
|
|
49
72
|
};
|
|
50
|
-
var
|
|
73
|
+
var Q = class extends o.Component {
|
|
51
74
|
static propTypes = {
|
|
52
|
-
onSessionChange:
|
|
53
|
-
model:
|
|
54
|
-
session:
|
|
75
|
+
onSessionChange: f.func.isRequired,
|
|
76
|
+
model: f.object.isRequired,
|
|
77
|
+
session: f.oneOfType([f.array.isRequired, f.object.isRequired])
|
|
55
78
|
};
|
|
56
79
|
constructor(e) {
|
|
57
|
-
super(e), this.instanceId =
|
|
80
|
+
super(e), this.instanceId = l();
|
|
58
81
|
let { value: t, needsReset: n } = this.validateSession(e);
|
|
59
|
-
this.state = {
|
|
82
|
+
this.state = {
|
|
83
|
+
showingCorrect: !1,
|
|
84
|
+
selectedChoice: null
|
|
85
|
+
}, this.lastDragEndAt = 0;
|
|
60
86
|
let { model: r } = e || {}, { env: i } = r || {}, { mode: a } = i || {};
|
|
61
87
|
n && a === "gather" && this.props.onSessionChange({
|
|
62
88
|
...e.session,
|
|
@@ -65,18 +91,18 @@ var G = class extends a.Component {
|
|
|
65
91
|
}
|
|
66
92
|
toggleCorrect = (e) => this.setState({ showingCorrect: e });
|
|
67
93
|
componentDidUpdate() {
|
|
68
|
-
|
|
94
|
+
d(p.findDOMNode(this));
|
|
69
95
|
}
|
|
70
96
|
validateSession = ({ model: e, session: t }, n = !1) => {
|
|
71
|
-
let { config: r, choices: i } = e || {}, { includeTargets: a } = r || {},
|
|
72
|
-
if (a) l && l.length !==
|
|
97
|
+
let { config: r, choices: i } = e || {}, { includeTargets: a } = r || {}, o = i.map((e) => e.id), { value: l } = t || {}, u;
|
|
98
|
+
if (a) l && l.length !== o.length && (u = !0, l = l.length < o.length ? l.concat(Array(o.length - l.length)) : l.filter((e) => o.includes(e)));
|
|
73
99
|
else {
|
|
74
|
-
if (!l || !l.length || n) l =
|
|
100
|
+
if (!l || !l.length || n) l = o;
|
|
75
101
|
else {
|
|
76
|
-
let e = o
|
|
77
|
-
(e.length || t.length) && (l =
|
|
102
|
+
let e = s(o, l), t = s(l, o);
|
|
103
|
+
(e.length || t.length) && (l = o);
|
|
78
104
|
}
|
|
79
|
-
u = !
|
|
105
|
+
u = !c(t.value, l);
|
|
80
106
|
}
|
|
81
107
|
return u && console.warn("This session is not valid anymore. It will be reset."), {
|
|
82
108
|
value: l,
|
|
@@ -84,8 +110,8 @@ var G = class extends a.Component {
|
|
|
84
110
|
};
|
|
85
111
|
};
|
|
86
112
|
UNSAFE_componentWillReceiveProps(e) {
|
|
87
|
-
let { model: t = {} } = e || {}, { model: n = {} } = this.props || {}, { correctResponse: r, config: a, choices: o = [], env: s } = t, { includeTargets: c } = a || {}, l = {}, u = n.language && n.language !== t.language, d = n.note && n.note ===
|
|
88
|
-
u && d && (n.note =
|
|
113
|
+
let { model: t = {} } = e || {}, { model: n = {} } = this.props || {}, { correctResponse: r, config: a, choices: o = [], env: s } = t, { includeTargets: c } = a || {}, l = {}, u = n.language && n.language !== t.language, d = n.note && n.note === H.t("common:commonCorrectAnswerWithAlternates", { lng: n.language });
|
|
114
|
+
u && d && (n.note = H.t("common:commonCorrectAnswerWithAlternates", { lng: t.language })), r || (l.showingCorrect = !1);
|
|
89
115
|
let f = i(o, n.choices), { value: p, needsReset: m } = this.validateSession(e, f), h = {
|
|
90
116
|
...e.session,
|
|
91
117
|
value: p
|
|
@@ -97,7 +123,7 @@ var G = class extends a.Component {
|
|
|
97
123
|
}
|
|
98
124
|
onDropChoice = (e, t, n) => {
|
|
99
125
|
let { onSessionChange: i, session: a } = this.props, o = n.tiles.find((e) => e.id === t.id && e.type === t.type && e.index === t.index), s = e;
|
|
100
|
-
|
|
126
|
+
U("[onDropChoice] ", o, s);
|
|
101
127
|
let c = r({
|
|
102
128
|
type: "move",
|
|
103
129
|
from: o,
|
|
@@ -107,7 +133,7 @@ var G = class extends a.Component {
|
|
|
107
133
|
};
|
|
108
134
|
onRemoveChoice = (e, t) => {
|
|
109
135
|
let { onSessionChange: n, session: i } = this.props;
|
|
110
|
-
|
|
136
|
+
U("[onRemoveChoice]", e);
|
|
111
137
|
let a = r({
|
|
112
138
|
type: "remove",
|
|
113
139
|
target: e
|
|
@@ -132,75 +158,134 @@ var G = class extends a.Component {
|
|
|
132
158
|
};
|
|
133
159
|
onDragEnd = (e) => {
|
|
134
160
|
let { over: t, active: n } = e, r = this.createOrdering();
|
|
135
|
-
if (t && n) {
|
|
161
|
+
if (this.cancelSelection(), this.lastDragEndAt = Date.now(), t && n) {
|
|
136
162
|
let e = n.data.current, i = t.data.current;
|
|
137
163
|
if (e && i && i.type === "target") {
|
|
138
|
-
this.onDropChoice(i, e, r);
|
|
164
|
+
this.onDropChoice(i, e, r), this.focusTile(this.getDestinationSlotId(i));
|
|
139
165
|
return;
|
|
140
166
|
}
|
|
141
|
-
e && i && this.onDropChoice(i, e, r);
|
|
167
|
+
e && i && (this.onDropChoice(i, e, r), this.focusTile(this.getDestinationSlotId(i)));
|
|
142
168
|
} else if (!t && n) {
|
|
143
|
-
let e = n.data.current;
|
|
144
|
-
e && e.type === "target" && this.onRemoveChoice(e, r)
|
|
169
|
+
let e = n.data.current, t = B(n.rect?.current?.initial, n.rect?.current?.translated);
|
|
170
|
+
e && e.type === "target" && !t && (this.onRemoveChoice(e, r), this.focusTile(this.getDestinationSlotId({
|
|
171
|
+
type: "choice",
|
|
172
|
+
id: e.id
|
|
173
|
+
})));
|
|
145
174
|
}
|
|
146
175
|
};
|
|
176
|
+
onDragStart = (e) => {
|
|
177
|
+
let { active: t } = e;
|
|
178
|
+
t?.data?.current && this.selectChoice(t.data.current);
|
|
179
|
+
};
|
|
180
|
+
onDragCancel = () => {
|
|
181
|
+
this.cancelSelection(), this.lastDragEndAt = Date.now();
|
|
182
|
+
};
|
|
183
|
+
isSameChoice = (e, t) => !!e && !!t && e.type === t.type && e.id === t.id && e.index === t.index;
|
|
184
|
+
selectChoice = (e) => {
|
|
185
|
+
this.setState({ selectedChoice: e });
|
|
186
|
+
};
|
|
187
|
+
toggleChoiceSelection = (e) => {
|
|
188
|
+
this.setState((t) => ({ selectedChoice: this.isSameChoice(t.selectedChoice, e) ? null : e }));
|
|
189
|
+
};
|
|
190
|
+
cancelSelection = () => {
|
|
191
|
+
this.setState({ selectedChoice: null });
|
|
192
|
+
};
|
|
193
|
+
endAnyLiveKeyboardDrag = () => {
|
|
194
|
+
document.dispatchEvent(new KeyboardEvent("keydown", {
|
|
195
|
+
code: "Escape",
|
|
196
|
+
bubbles: !0,
|
|
197
|
+
cancelable: !0
|
|
198
|
+
}));
|
|
199
|
+
};
|
|
200
|
+
placeSelectedChoice = (e) => {
|
|
201
|
+
let { selectedChoice: t } = this.state;
|
|
202
|
+
if (!t) return;
|
|
203
|
+
let n = this.createOrdering(), r = this.getDestinationSlotId(e);
|
|
204
|
+
this.onDropChoice(e, t, n), this.cancelSelection(), this.endAnyLiveKeyboardDrag(), this.lastDragEndAt = Date.now(), this.focusTile(r);
|
|
205
|
+
};
|
|
206
|
+
getDestinationSlotId = (e) => e ? e.type === "target" ? `target-${e.index}` : e.type === "choice" ? `choice-${e.id}` : null : null;
|
|
207
|
+
focusTile = (e) => {
|
|
208
|
+
if (!e) return;
|
|
209
|
+
let t = `[data-tile-id="${this.instanceId}:${e}"]`;
|
|
210
|
+
requestAnimationFrame(() => {
|
|
211
|
+
requestAnimationFrame(() => {
|
|
212
|
+
document.querySelector(t)?.focus();
|
|
213
|
+
});
|
|
214
|
+
});
|
|
215
|
+
};
|
|
216
|
+
isClickSoonAfterDragEnd = () => Date.now() - this.lastDragEndAt < z;
|
|
217
|
+
onChoiceClick = (e) => {
|
|
218
|
+
this.isClickSoonAfterDragEnd() || this.toggleChoiceSelection(e);
|
|
219
|
+
};
|
|
220
|
+
onPlacementClick = (e) => {
|
|
221
|
+
this.isClickSoonAfterDragEnd() || this.placeSelectedChoice(e);
|
|
222
|
+
};
|
|
147
223
|
render() {
|
|
148
|
-
let { model: n } = this.props, { correctResponse: r, correctness: i, extraCSSRules: a, prompt: o, rationale: s, feedback: c, config: l, note: u, showNote: d, env: f, disabled: p, teacherInstructions:
|
|
224
|
+
let { model: n } = this.props, { correctResponse: r, correctness: i, extraCSSRules: a, prompt: o, rationale: s, feedback: c, config: l, note: u, showNote: d, env: f, disabled: p, teacherInstructions: m, language: _ } = n, v = r && r.length > 0, { showingCorrect: y } = this.state, b = l || {
|
|
149
225
|
orientation: "vertical",
|
|
150
226
|
includeTargets: !0
|
|
151
|
-
}, { orientation:
|
|
152
|
-
color:
|
|
153
|
-
backgroundColor:
|
|
227
|
+
}, { orientation: x, includeTargets: D } = b, O = x === "vertical", A = this.createOrdering(), { mode: j, role: F } = f || {}, I = O ? t : e, L = (y || j === "view" && F === "instructor") && d && u, R = s && (w(s) || C(s)), z = m && (w(m) || C(m)), B = {
|
|
228
|
+
color: S.text(),
|
|
229
|
+
backgroundColor: S.background(),
|
|
154
230
|
display: "flex",
|
|
155
231
|
flexDirection: "column",
|
|
156
232
|
alignItems: "center",
|
|
157
|
-
boxSizing: "border-box"
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
233
|
+
boxSizing: "border-box",
|
|
234
|
+
width: "100%"
|
|
235
|
+
}, H = D ? {
|
|
236
|
+
selectedChoice: this.state.selectedChoice,
|
|
237
|
+
onChoiceClick: this.onChoiceClick,
|
|
238
|
+
onPlacementClick: this.onPlacementClick
|
|
239
|
+
} : {};
|
|
240
|
+
return /* @__PURE__ */ T(k, {
|
|
241
|
+
onDragStart: this.onDragStart,
|
|
161
242
|
onDragEnd: this.onDragEnd,
|
|
162
|
-
|
|
163
|
-
|
|
243
|
+
onDragCancel: this.onDragCancel,
|
|
244
|
+
collisionDetection: h,
|
|
245
|
+
modifiers: [g],
|
|
246
|
+
...V(D),
|
|
247
|
+
children: /* @__PURE__ */ T(W, { children: /* @__PURE__ */ E(M, {
|
|
164
248
|
extraCSSRules: a,
|
|
165
|
-
style:
|
|
249
|
+
style: B,
|
|
166
250
|
children: [
|
|
167
|
-
|
|
251
|
+
z && /* @__PURE__ */ T(X, {
|
|
168
252
|
labels: {
|
|
169
253
|
hidden: "Show Teacher Instructions",
|
|
170
254
|
visible: "Hide Teacher Instructions"
|
|
171
255
|
},
|
|
172
256
|
className: "collapsible",
|
|
173
|
-
children: /* @__PURE__ */
|
|
257
|
+
children: /* @__PURE__ */ T(N, { prompt: m })
|
|
174
258
|
}),
|
|
175
|
-
/* @__PURE__ */
|
|
176
|
-
/* @__PURE__ */
|
|
177
|
-
show:
|
|
178
|
-
toggled:
|
|
259
|
+
/* @__PURE__ */ T(q, { children: /* @__PURE__ */ T(N, { prompt: o }) }),
|
|
260
|
+
/* @__PURE__ */ T(Y, {
|
|
261
|
+
show: v,
|
|
262
|
+
toggled: y,
|
|
179
263
|
onToggle: this.toggleCorrect,
|
|
180
|
-
language:
|
|
264
|
+
language: _
|
|
181
265
|
}),
|
|
182
|
-
/* @__PURE__ */
|
|
266
|
+
/* @__PURE__ */ T(G, { children: /* @__PURE__ */ T(K, { children: /* @__PURE__ */ T(Z, {
|
|
183
267
|
instanceId: this.instanceId,
|
|
184
|
-
choiceLabel:
|
|
185
|
-
targetLabel:
|
|
186
|
-
ordering:
|
|
187
|
-
tiler:
|
|
268
|
+
choiceLabel: b.choiceLabel,
|
|
269
|
+
targetLabel: b.targetLabel,
|
|
270
|
+
ordering: A,
|
|
271
|
+
tiler: I,
|
|
188
272
|
disabled: p,
|
|
189
|
-
addGuide:
|
|
190
|
-
tileSize:
|
|
191
|
-
includeTargets:
|
|
192
|
-
choiceLabelEnabled: n.config && n.config.choiceLabelEnabled
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
L && /* @__PURE__ */
|
|
273
|
+
addGuide: b.showOrdering,
|
|
274
|
+
tileSize: b.tileSize,
|
|
275
|
+
includeTargets: D,
|
|
276
|
+
choiceLabelEnabled: n.config && n.config.choiceLabelEnabled,
|
|
277
|
+
...H
|
|
278
|
+
}) }) }),
|
|
279
|
+
L && /* @__PURE__ */ T(J, { dangerouslySetInnerHTML: { __html: u } }),
|
|
280
|
+
R && /* @__PURE__ */ T(X, {
|
|
196
281
|
labels: {
|
|
197
282
|
hidden: "Show Rationale",
|
|
198
283
|
visible: "Hide Rationale"
|
|
199
284
|
},
|
|
200
285
|
className: "collapsible",
|
|
201
|
-
children: /* @__PURE__ */
|
|
286
|
+
children: /* @__PURE__ */ T(N, { prompt: s })
|
|
202
287
|
}),
|
|
203
|
-
!
|
|
288
|
+
!y && /* @__PURE__ */ T(P, {
|
|
204
289
|
correctness: i,
|
|
205
290
|
feedback: c
|
|
206
291
|
})
|
|
@@ -210,4 +295,4 @@ var G = class extends a.Component {
|
|
|
210
295
|
}
|
|
211
296
|
};
|
|
212
297
|
//#endregion
|
|
213
|
-
export {
|
|
298
|
+
export { Q as PlacementOrdering, Q as default };
|
package/dist/delivery/tile.d.ts
CHANGED
|
@@ -23,6 +23,9 @@ export declare const Tile: {
|
|
|
23
23
|
instanceId: PropTypes.Requireable<any>;
|
|
24
24
|
draggable: PropTypes.Requireable<boolean>;
|
|
25
25
|
tileIndex: PropTypes.Requireable<number>;
|
|
26
|
+
selectedChoice: PropTypes.Requireable<object>;
|
|
27
|
+
onChoiceClick: PropTypes.Requireable<(...args: any[]) => any>;
|
|
28
|
+
onPlacementClick: PropTypes.Requireable<(...args: any[]) => any>;
|
|
26
29
|
};
|
|
27
30
|
};
|
|
28
31
|
export default Tile;
|