@pie-element/multiple-choice 13.4.0-beta.0 → 13.4.0-next.13

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 (135) hide show
  1. package/author.js +2 -0
  2. package/configure.js +2 -0
  3. package/controller.js +1 -0
  4. package/dist/author/defaults.d.ts +205 -0
  5. package/dist/author/defaults.js +151 -0
  6. package/dist/author/index.d.ts +26 -0
  7. package/dist/author/index.js +119 -0
  8. package/dist/author/main.d.ts +34 -0
  9. package/dist/author/main.js +287 -0
  10. package/dist/author/utils.d.ts +9 -0
  11. package/dist/author/utils.js +7 -0
  12. package/dist/browser/Radio-B-Cd30zs.js +9592 -0
  13. package/dist/browser/Radio-B-Cd30zs.js.map +1 -0
  14. package/dist/browser/author/index.js +35031 -0
  15. package/dist/browser/author/index.js.map +1 -0
  16. package/dist/browser/controller/index.js +204 -0
  17. package/dist/browser/controller/index.js.map +1 -0
  18. package/dist/browser/delivery/index.js +303 -0
  19. package/dist/browser/delivery/index.js.map +1 -0
  20. package/dist/browser/dist-CHbLnyuX.js +111 -0
  21. package/dist/browser/dist-CHbLnyuX.js.map +1 -0
  22. package/dist/browser/main-DoiD4nKm.js +2553 -0
  23. package/dist/browser/main-DoiD4nKm.js.map +1 -0
  24. package/dist/browser/multiple-choice.css +2 -0
  25. package/dist/browser/print/index.js +43 -0
  26. package/dist/browser/print/index.js.map +1 -0
  27. package/dist/controller/defaults.d.ts +35 -0
  28. package/dist/controller/defaults.js +29 -0
  29. package/dist/controller/index.d.ts +65 -0
  30. package/dist/controller/index.js +129 -0
  31. package/dist/controller/utils.d.ts +10 -0
  32. package/dist/controller/utils.js +8 -0
  33. package/dist/delivery/choice-input.d.ts +44 -0
  34. package/dist/delivery/choice-input.js +280 -0
  35. package/dist/delivery/choice.d.ts +20 -0
  36. package/dist/delivery/choice.js +106 -0
  37. package/dist/delivery/feedback-tick.d.ts +20 -0
  38. package/dist/delivery/feedback-tick.js +104 -0
  39. package/dist/delivery/index.d.ts +37 -0
  40. package/dist/delivery/index.js +217 -0
  41. package/dist/delivery/main.d.ts +31 -0
  42. package/dist/delivery/main.js +51 -0
  43. package/dist/delivery/multiple-choice.d.ts +61 -0
  44. package/dist/delivery/multiple-choice.js +245 -0
  45. package/dist/delivery/session-updater.d.ts +10 -0
  46. package/dist/delivery/session-updater.js +9 -0
  47. package/dist/delivery/utils.d.ts +10 -0
  48. package/dist/delivery/utils.js +4 -0
  49. package/dist/index.d.ts +1 -0
  50. package/dist/index.iife.d.ts +8 -0
  51. package/dist/index.iife.js +148 -0
  52. package/dist/index.js +2 -0
  53. package/dist/node_modules/.bun/clsx@2.1.1/node_modules/clsx/dist/clsx.js +16 -0
  54. package/dist/print/index.d.ts +15 -0
  55. package/dist/print/index.js +43 -0
  56. package/dist/runtime-support.d.ts +12 -0
  57. package/dist/runtime-support.js +12 -0
  58. package/module/print.js +18058 -1
  59. package/module/print.js.map +1 -0
  60. package/package.json +95 -28
  61. package/print.js +2 -0
  62. package/CHANGELOG.json +0 -1972
  63. package/CHANGELOG.md +0 -2741
  64. package/LICENSE.md +0 -5
  65. package/PRINT.md +0 -35
  66. package/README.md +0 -56
  67. package/choice.png +0 -0
  68. package/configure/CHANGELOG.json +0 -1387
  69. package/configure/CHANGELOG.md +0 -2081
  70. package/configure/lib/__tests__/root.test.js +0 -279
  71. package/configure/lib/defaults.js +0 -203
  72. package/configure/lib/defaults.js.map +0 -1
  73. package/configure/lib/index.js +0 -203
  74. package/configure/lib/index.js.map +0 -1
  75. package/configure/lib/main.js +0 -484
  76. package/configure/lib/main.js.map +0 -1
  77. package/configure/lib/utils.js +0 -18
  78. package/configure/lib/utils.js.map +0 -1
  79. package/configure/package.json +0 -22
  80. package/controller/CHANGELOG.json +0 -527
  81. package/controller/CHANGELOG.md +0 -1412
  82. package/controller/lib/__tests__/index.test.js +0 -561
  83. package/controller/lib/__tests__/utils.test.js +0 -8
  84. package/controller/lib/defaults.js +0 -33
  85. package/controller/lib/defaults.js.map +0 -1
  86. package/controller/lib/index.js +0 -298
  87. package/controller/lib/index.js.map +0 -1
  88. package/controller/lib/utils.js +0 -15
  89. package/controller/lib/utils.js.map +0 -1
  90. package/controller/package.json +0 -15
  91. package/docs/config-schema.json +0 -2993
  92. package/docs/config-schema.json.md +0 -2217
  93. package/docs/demo/config.js +0 -8
  94. package/docs/demo/generate.js +0 -61
  95. package/docs/demo/index.html +0 -1
  96. package/docs/demo/pie.manifest.json +0 -11
  97. package/docs/demo/session.js +0 -7
  98. package/docs/pie-schema.json +0 -1332
  99. package/docs/pie-schema.json.md +0 -1015
  100. package/lib/__tests__/choice-input-test.js +0 -49
  101. package/lib/__tests__/choice-input.test.js +0 -49
  102. package/lib/__tests__/index-test.js +0 -206
  103. package/lib/__tests__/index.test.js +0 -221
  104. package/lib/__tests__/key-events-test.js +0 -95
  105. package/lib/__tests__/key-events.test.js +0 -107
  106. package/lib/__tests__/multiple-choice-test.js +0 -101
  107. package/lib/__tests__/multiple-choice.test.js +0 -256
  108. package/lib/__tests__/session-updater-test.js +0 -70
  109. package/lib/__tests__/session-updater.test.js +0 -70
  110. package/lib/choice-input.js +0 -383
  111. package/lib/choice-input.js.map +0 -1
  112. package/lib/choice.js +0 -192
  113. package/lib/choice.js.map +0 -1
  114. package/lib/feedback-tick.js +0 -134
  115. package/lib/feedback-tick.js.map +0 -1
  116. package/lib/index.js +0 -405
  117. package/lib/index.js.map +0 -1
  118. package/lib/main.js +0 -63
  119. package/lib/main.js.map +0 -1
  120. package/lib/multiple-choice.js +0 -399
  121. package/lib/multiple-choice.js.map +0 -1
  122. package/lib/print.js +0 -94
  123. package/lib/print.js.map +0 -1
  124. package/lib/session-updater.js +0 -37
  125. package/lib/session-updater.js.map +0 -1
  126. package/lib/utils.js +0 -14
  127. package/lib/utils.js.map +0 -1
  128. package/module/configure.js +0 -1
  129. package/module/controller.js +0 -3045
  130. package/module/demo.js +0 -86
  131. package/module/element.js +0 -1
  132. package/module/index.html +0 -21
  133. package/module/manifest.json +0 -14
  134. package/module/print-demo.js +0 -124
  135. package/module/print.html +0 -18
@@ -0,0 +1,106 @@
1
+ import { ChoiceInput as e } from "./choice-input.js";
2
+ import t from "react";
3
+ import n from "prop-types";
4
+ import { color as r } from "@pie-lib/render-ui";
5
+ import { jsx as i } from "react/jsx-runtime";
6
+ import { styled as a } from "@mui/material/styles";
7
+ import o from "@mui/material/Box";
8
+ //#region src/delivery/choice.tsx
9
+ var s = a(o, { shouldForwardProp: (e) => e !== "noBorder" && e !== "horizontalLayout" })(({ theme: e, noBorder: t, horizontalLayout: n }) => ({
10
+ paddingTop: e.spacing(2.5),
11
+ paddingBottom: `calc(${e.spacing(1)} + 2px)`,
12
+ paddingLeft: `calc(${e.spacing(1)} + 2px)`,
13
+ paddingRight: `calc(${e.spacing(1)} + 2px)`,
14
+ borderBottom: t ? "none" : `1px solid ${r.border()}`,
15
+ ...n && {
16
+ paddingRight: e.spacing(2.5),
17
+ "& label": { marginRight: e.spacing(1) }
18
+ }
19
+ })), c = class extends t.Component {
20
+ static propTypes = {};
21
+ state = { isHovered: !1 };
22
+ handleMouseEnter = () => {
23
+ let { disabled: e, checked: t } = this.props;
24
+ !e && !t && this.setState({ isHovered: !0 });
25
+ };
26
+ handleMouseLeave = () => {
27
+ this.setState({ isHovered: !1 });
28
+ };
29
+ onChange = (e) => {
30
+ let { disabled: t, onChoiceChanged: n } = this.props;
31
+ t || n(e);
32
+ };
33
+ render() {
34
+ let { choice: t, index: n, choicesLength: r, showCorrect: a, isEvaluateMode: o, choiceMode: c, disabled: l, checked: u, correctness: d, displayKey: f, choicesLayout: p, gridColumns: m, isSelectionButtonBelow: h, selectedAnswerBackgroundColor: g, selectedAnswerStrokeColor: _, selectedAnswerStrokeWidth: v, hoverAnswerBackgroundColor: y, hoverAnswerStrokeColor: b, hoverAnswerStrokeWidth: x, tagName: S } = this.props, { isHovered: C } = this.state, w = "choice" + (n === r - 1 ? " last" : ""), T = !o || a ? "" : t.feedback, E = {
35
+ ...t,
36
+ checked: u,
37
+ choiceMode: c,
38
+ disabled: l,
39
+ feedback: T,
40
+ correctness: d,
41
+ displayKey: f,
42
+ index: n,
43
+ choicesLayout: p,
44
+ gridColumns: m,
45
+ onChange: this.onChange,
46
+ isEvaluateMode: o,
47
+ isSelectionButtonBelow: h,
48
+ selectedAnswerStrokeColor: _,
49
+ selectedAnswerStrokeWidth: v,
50
+ tagName: S
51
+ }, D = (e) => {
52
+ if (!e) return "2px";
53
+ let t = String(e).trim();
54
+ return /^\d+(\.\d+)?$/.test(t) ? `${t}px` : t;
55
+ }, O = _ && _ !== "initial", k = b && b !== "initial", A = "transparent", j = "2px", M = "initial";
56
+ (O || k) && (u && O ? (A = _, j = v) : C && !l && k && (A = b, j = x)), u && g && g !== "initial" ? M = g : C && !l && y && y !== "initial" && (M = y);
57
+ let N = O || k, P = N ? {
58
+ border: `${D(j)} solid ${A}`,
59
+ borderRadius: "8px"
60
+ } : {}, F = n === r - 1 || p !== "vertical" || N, I = p === "horizontal";
61
+ return /* @__PURE__ */ i("div", {
62
+ className: w,
63
+ style: {
64
+ backgroundColor: M === "initial" ? "initial" : M,
65
+ ...P
66
+ },
67
+ onMouseEnter: this.handleMouseEnter,
68
+ onMouseLeave: this.handleMouseLeave,
69
+ children: /* @__PURE__ */ i(s, {
70
+ component: "div",
71
+ noBorder: F,
72
+ horizontalLayout: I,
73
+ children: /* @__PURE__ */ i(e, { ...E })
74
+ })
75
+ }, n);
76
+ }
77
+ };
78
+ c.propTypes = {
79
+ choiceMode: n.oneOf(["radio", "checkbox"]),
80
+ choice: n.object,
81
+ disabled: n.bool.isRequired,
82
+ onChoiceChanged: n.func,
83
+ index: n.number,
84
+ choicesLength: n.number,
85
+ showCorrect: n.bool,
86
+ isEvaluateMode: n.bool,
87
+ checked: n.bool,
88
+ correctness: n.string,
89
+ displayKey: n.string,
90
+ choicesLayout: n.oneOf([
91
+ "vertical",
92
+ "grid",
93
+ "horizontal"
94
+ ]),
95
+ gridColumns: n.string,
96
+ selectedAnswerBackgroundColor: n.string,
97
+ selectedAnswerStrokeColor: n.string,
98
+ selectedAnswerStrokeWidth: n.string,
99
+ hoverAnswerBackgroundColor: n.string,
100
+ hoverAnswerStrokeColor: n.string,
101
+ hoverAnswerStrokeWidth: n.string,
102
+ tagName: n.string,
103
+ isSelectionButtonBelow: n.bool
104
+ };
105
+ //#endregion
106
+ export { c as Choice, c as default };
@@ -0,0 +1,20 @@
1
+ /**
2
+ * @synced-from pie-elements/packages/multiple-choice/src/feedback-tick.jsx
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
+ import React from 'react';
10
+ import PropTypes from 'prop-types';
11
+ declare class FeedbackTick extends React.Component {
12
+ static propTypes: {
13
+ correctness: PropTypes.Requireable<string>;
14
+ };
15
+ constructor(props: any);
16
+ getIncorrectIcon: () => React.JSX.Element;
17
+ getCorrectIcon: () => React.JSX.Element;
18
+ render(): React.JSX.Element;
19
+ }
20
+ export default FeedbackTick;
@@ -0,0 +1,104 @@
1
+ import e from "react";
2
+ import t from "prop-types";
3
+ import { color as n } from "@pie-lib/render-ui";
4
+ import { jsx as r, jsxs as i } from "react/jsx-runtime";
5
+ import { styled as a } from "@mui/material/styles";
6
+ import o from "@mui/material/Box";
7
+ import { CSSTransition as s, TransitionGroup as c } from "react-transition-group";
8
+ //#region src/delivery/feedback-tick.tsx
9
+ var l = a(o)({
10
+ width: "33px",
11
+ height: "33px",
12
+ "& svg": {
13
+ position: "absolute",
14
+ display: "inline-block",
15
+ width: "33px",
16
+ height: "33px",
17
+ verticalAlign: "middle",
18
+ "& hide": { display: "none" }
19
+ }
20
+ }), u = a("svg")({
21
+ "& .incorrect-fill": { fill: `var(--feedback-incorrect-bg-color, ${n.incorrect()})` },
22
+ "& .correct-fill": { fill: `var(--feedback-correct-bg-color, ${n.correct()})` }
23
+ }), d = a("div")({
24
+ position: "relative",
25
+ "&.feedback-tick-enter": {
26
+ opacity: "0",
27
+ left: "-50px"
28
+ },
29
+ "&.feedback-tick-enter-active": {
30
+ opacity: "1",
31
+ left: "0px",
32
+ transition: "left 500ms ease-in 200ms, opacity 500ms linear 200ms"
33
+ },
34
+ "&.feedback-tick-exit": {
35
+ opacity: "1",
36
+ left: "0px"
37
+ },
38
+ "&.feedback-tick-exit-active": {
39
+ opacity: "0",
40
+ left: "-50px",
41
+ transition: "left 300ms ease-in, opacity 300ms"
42
+ }
43
+ }), f = class extends e.Component {
44
+ static propTypes = { correctness: t.string };
45
+ constructor(t) {
46
+ super(t), this.nodeRef = e.createRef();
47
+ }
48
+ getIncorrectIcon = () => /* @__PURE__ */ r(u, {
49
+ preserveAspectRatio: "xMinYMin meet",
50
+ x: "0px",
51
+ y: "0px",
52
+ viewBox: "0 0 44 40",
53
+ style: { enableBackground: "new 0 0 44 40" },
54
+ children: /* @__PURE__ */ i("g", { children: [/* @__PURE__ */ r("rect", {
55
+ x: "11",
56
+ y: "17.3",
57
+ transform: "matrix(0.7071 -0.7071 0.7071 0.7071 -7.852 19.2507)",
58
+ className: "incorrect-fill",
59
+ width: "16.6",
60
+ height: "3.7"
61
+ }), /* @__PURE__ */ r("rect", {
62
+ x: "17.4",
63
+ y: "10.7",
64
+ transform: "matrix(0.7071 -0.7071 0.7071 0.7071 -7.8175 19.209)",
65
+ className: "incorrect-fill",
66
+ width: "3.7",
67
+ height: "16.6"
68
+ })] })
69
+ }, "1");
70
+ getCorrectIcon = () => /* @__PURE__ */ r(u, {
71
+ preserveAspectRatio: "xMinYMin meet",
72
+ version: "1.1",
73
+ x: "0px",
74
+ y: "0px",
75
+ viewBox: "0 0 44 40",
76
+ style: { enableBackground: "new 0 0 44 40" },
77
+ children: /* @__PURE__ */ r("polygon", {
78
+ className: "correct-fill",
79
+ points: "19.1,28.6 11.8,22.3 14.4,19.2 17.9,22.1 23.9,11.4 27.5,13.4"
80
+ })
81
+ }, "2");
82
+ render() {
83
+ let { correctness: e } = this.props, t = e === "incorrect" ? this.getIncorrectIcon() : e === "correct" ? this.getCorrectIcon() : null;
84
+ return /* @__PURE__ */ r(l, { children: /* @__PURE__ */ r(c, { children: e && /* @__PURE__ */ r(s, {
85
+ nodeRef: this.nodeRef,
86
+ classNames: {
87
+ enter: "feedback-tick-enter",
88
+ enterActive: "feedback-tick-enter-active",
89
+ exit: "feedback-tick-exit",
90
+ exitActive: "feedback-tick-exit-active"
91
+ },
92
+ timeout: {
93
+ enter: 700,
94
+ exit: 300
95
+ },
96
+ children: /* @__PURE__ */ r(d, {
97
+ ref: this.nodeRef,
98
+ children: t
99
+ })
100
+ }) }) });
101
+ }
102
+ };
103
+ //#endregion
104
+ export { f as default };
@@ -0,0 +1,37 @@
1
+ /**
2
+ * @synced-from pie-elements/packages/multiple-choice/src/index.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
+ export declare const isComplete: (session: any, model: any, audioComplete: any, elementContext: any) => boolean;
10
+ export default class MultipleChoice extends HTMLElement {
11
+ constructor();
12
+ _scheduleMathRender: any;
13
+ _initMathObserver(): void;
14
+ _disconnectMathObserver(): void;
15
+ onShowCorrectToggle(): void;
16
+ setLangAttribute(): void;
17
+ set model(s: any);
18
+ get session(): any;
19
+ get options(): any;
20
+ set options(o: any);
21
+ set baseHeadingLevel(level: any);
22
+ set includeSrHeading(value: any);
23
+ set session(s: any);
24
+ _onChange(data: any): void;
25
+ _createAudioInfoToast(): HTMLDivElement;
26
+ connectedCallback(): void;
27
+ enableKeyboardEvents(): void;
28
+ _initPlayerObserver(): void;
29
+ _disconnectPlayerObserver(): void;
30
+ disconnectedCallback(): void;
31
+ /**
32
+ * Handles global keyboard events for selecting or toggling multiple-choice answers.
33
+ * Maps keys (1-9, 0, a-j, A-J) to choices and updates the session state accordingly.
34
+ * Ensures valid key presses toggle or select the appropriate choice based on the model.
35
+ */
36
+ handleKeyDown(event: any): void;
37
+ }
@@ -0,0 +1,217 @@
1
+ import { exceedsMaxSelections as e } from "./utils.js";
2
+ import t from "./main.js";
3
+ import { updateSessionMetadata as n, updateSessionValue as r } from "./session-updater.js";
4
+ import i from "react";
5
+ import * as a from "@pie-lib/render-ui";
6
+ import { EnableAudioAutoplayImage as o } from "@pie-lib/render-ui";
7
+ import { createRoot as s } from "react-dom/client";
8
+ import { debounce as c } from "@pie-element/shared-lodash";
9
+ import l from "debug";
10
+ import { ModelSetEvent as u, SessionChangedEvent as d, createSessionNotifier as f, flushSessionNotifiers as p } from "@pie-element/shared-player-events";
11
+ import { renderMath as m } from "@pie-element/shared-math-rendering-mathjax";
12
+ //#region src/delivery/index.ts
13
+ function h(e) {
14
+ return typeof e == "function" || typeof e == "object" && !!e && typeof e.$$typeof == "symbol";
15
+ }
16
+ function g(e, t) {
17
+ return !e || h(e) ? e : h(e.default) ? e.default : t && h(e[t]) ? e[t] : t && h(e[t]?.default) ? e[t].default : e;
18
+ }
19
+ var _ = g(o, "EnableAudioAutoplayImage") || g(b.EnableAudioAutoplayImage, "EnableAudioAutoplayImage"), v = a, y = v.default, b = y && typeof y == "object" ? y : v, x = l("pie-ui:multiple-choice"), S = (t, n, r, i) => {
20
+ let { completeAudioEnabled: a } = n || {};
21
+ if (a && !r && i) {
22
+ let e = i.querySelector("audio"), t = e && e.closest(".preview-prompt");
23
+ if (e && t) return !1;
24
+ }
25
+ if (!t || !t.value) return !1;
26
+ let { choiceMode: o, minSelections: s = 1, maxSelections: c } = n || {}, l = t.value.length || 0;
27
+ return o === "radio" ? !!l : !(l < s || e(l, c));
28
+ };
29
+ function C(e) {
30
+ let t = e.closest("pie-player") || e.closest("pie-item-player");
31
+ if (!t) return {
32
+ baseHeadingLevel: void 0,
33
+ includeSrHeading: !0
34
+ };
35
+ let n = (e, n, r) => {
36
+ let i = t[e];
37
+ return i ??= t.getAttribute(n) ?? t.getAttribute(r), i;
38
+ }, r = n("baseHeadingLevel", "base-heading-level", "baseheadinglevel"), i = parseInt(r, 10), a = Number.isFinite(i) && i >= 1 && i <= 6 ? i : void 0, o = n("includeSrHeading", "include-sr-heading", "includesrheading");
39
+ return {
40
+ baseHeadingLevel: a,
41
+ includeSrHeading: o == null || o !== !1 && o !== "false"
42
+ };
43
+ }
44
+ function w(e) {
45
+ let t = C(e);
46
+ return {
47
+ baseHeadingLevel: e._baseHeadingLevel === void 0 ? t.baseHeadingLevel : e._baseHeadingLevel,
48
+ includeSrHeading: e._includeSrHeading === void 0 ? t.includeSrHeading : e._includeSrHeading
49
+ };
50
+ }
51
+ var T = class extends HTMLElement {
52
+ constructor() {
53
+ super(), this._model = null, this._session = null, this._options = null, this.audioComplete = !1, this._boundHandleKeyDown = this.handleKeyDown.bind(this), this._keyboardEventsEnabled = !1, this._audioInitialized = !1, this._root = null, this._mathObserver = null, this._mathRenderPending = !1, this._rerender = c(() => {
54
+ if (this._model && this._session) {
55
+ var e = i.createElement(t, {
56
+ model: this._model,
57
+ session: this._session,
58
+ options: this._options,
59
+ onChoiceChanged: this._onChange.bind(this),
60
+ onShowCorrectToggle: this.onShowCorrectToggle.bind(this),
61
+ ...w(this)
62
+ });
63
+ this.setAttribute("aria-label", this._model.choiceMode === "radio" ? "Multiple Choice Question" : "Multiple Correct Answer Question"), this.setAttribute("role", "region"), this.setLangAttribute(), this._initMathObserver(), this._root ||= s(this), this._root.render(e), this._model.keyboardEventsEnabled === !0 && !this._keyboardEventsEnabled && this.enableKeyboardEvents();
64
+ } else x("skip");
65
+ }, 50, {
66
+ leading: !1,
67
+ trailing: !0
68
+ }), this._sessionNotifier = f(this, () => {
69
+ this.dispatchEvent(new d(this.tagName.toLowerCase(), S(this._session, this._model, this.audioComplete, this)));
70
+ }), this._dispatchResponseChanged = () => this._sessionNotifier.notify(), this._dispatchModelSet = c(() => {
71
+ this.dispatchEvent(new u(this.tagName.toLowerCase(), S(this._session, this._model, this.audioComplete, this), this._model !== void 0));
72
+ }, 50, {
73
+ leading: !1,
74
+ trailing: !0
75
+ });
76
+ }
77
+ _scheduleMathRender = () => {
78
+ this._mathRenderPending || (this._mathRenderPending = !0, requestAnimationFrame(() => {
79
+ this._mathObserver && this._mathObserver.disconnect(), x("render complete - render math"), m(this), this._mathRenderPending = !1, setTimeout(() => {
80
+ this._mathObserver && this._mathObserver.observe(this, {
81
+ childList: !0,
82
+ subtree: !0
83
+ });
84
+ }, 50);
85
+ }));
86
+ };
87
+ _initMathObserver() {
88
+ this._mathObserver || (this._mathObserver = new MutationObserver(this._scheduleMathRender), this._mathObserver.observe(this, {
89
+ childList: !0,
90
+ subtree: !0
91
+ }));
92
+ }
93
+ _disconnectMathObserver() {
94
+ this._mathObserver &&= (this._mathObserver.disconnect(), null);
95
+ }
96
+ onShowCorrectToggle() {
97
+ m(this);
98
+ }
99
+ setLangAttribute() {
100
+ let e = this._model && typeof this._model.language ? this._model.language : "", t = e ? e.slice(0, 2) : "en";
101
+ this.setAttribute("lang", t);
102
+ }
103
+ set model(e) {
104
+ this._model = e, this._rerender(), this._audioInitialized = !1, this._dispatchModelSet();
105
+ }
106
+ get session() {
107
+ return this._session;
108
+ }
109
+ get options() {
110
+ return this._options;
111
+ }
112
+ set options(e) {
113
+ this._options = e, this._rerender();
114
+ }
115
+ set baseHeadingLevel(e) {
116
+ this._baseHeadingLevel = e, this._rerender();
117
+ }
118
+ set includeSrHeading(e) {
119
+ this._includeSrHeading = e, this._rerender();
120
+ }
121
+ set session(e) {
122
+ this._session = e, this._rerender(), this._dispatchResponseChanged();
123
+ }
124
+ _onChange(e) {
125
+ r(this._session, this._model.choiceMode, e), this._dispatchResponseChanged(), this._rerender();
126
+ }
127
+ _createAudioInfoToast() {
128
+ let e = document.createElement("div");
129
+ e.id = "play-audio-info", Object.assign(e.style, {
130
+ position: "absolute",
131
+ top: 0,
132
+ width: "100%",
133
+ height: "100%",
134
+ display: "flex",
135
+ justifyContent: "center",
136
+ alignItems: "center",
137
+ background: "white",
138
+ zIndex: "1000",
139
+ cursor: "pointer"
140
+ });
141
+ let t = document.createElement("img");
142
+ return t.src = _, t.alt = "Click anywhere to enable audio autoplay", t.width = 500, t.height = 300, e.appendChild(t), e;
143
+ }
144
+ connectedCallback() {
145
+ this._initMathObserver(), this._initPlayerObserver(), this._rerender(), new MutationObserver((e, t) => {
146
+ e.forEach((e) => {
147
+ if (e.type === "childList") {
148
+ if (this._audioInitialized) return;
149
+ let e = this.querySelector("audio"), r = e && e.closest(".preview-prompt");
150
+ if (!this._model) return;
151
+ let { autoplayAudioEnabled: i, completeAudioEnabled: a } = this._model;
152
+ if (!i && !a || e && !r || !e) return;
153
+ let o = this._createAudioInfoToast(), s = this.querySelector("#main-container"), c = () => {
154
+ this.querySelector("#play-audio-info") && (e.play(), s.removeChild(o)), document.removeEventListener("click", c);
155
+ };
156
+ i && setTimeout(() => {
157
+ e.paused && !this.querySelector("#play-audio-info") ? (s.appendChild(o), document.addEventListener("click", c)) : document.removeEventListener("click", c);
158
+ }, 500);
159
+ let l = () => {
160
+ n(this._session, { audioStartTime: (/* @__PURE__ */ new Date()).getTime() });
161
+ let t = this.querySelector("#play-audio-info");
162
+ t && s.removeChild(t), e.removeEventListener("playing", l);
163
+ };
164
+ e.addEventListener("playing", l);
165
+ let u = () => {
166
+ n(this._session, { audioEndTime: (/* @__PURE__ */ new Date()).getTime() }), this.audioComplete = !0, this._dispatchResponseChanged(), e.removeEventListener("ended", u);
167
+ };
168
+ e.addEventListener("ended", u), this._audio = e, this._handlePlaying = l, this._handleEnded = u, this._enableAudio = c, this._audioInitialized = !0, t.disconnect();
169
+ }
170
+ });
171
+ }).observe(this, {
172
+ childList: !0,
173
+ subtree: !0
174
+ });
175
+ }
176
+ enableKeyboardEvents() {
177
+ this._keyboardEventsEnabled ||= (window.addEventListener("keydown", this._boundHandleKeyDown), !0);
178
+ }
179
+ _initPlayerObserver() {
180
+ let e = this.closest("pie-player") || this.closest("pie-item-player");
181
+ e && (this._playerObserver = new MutationObserver(() => {
182
+ this._rerender();
183
+ }), this._playerObserver.observe(e, {
184
+ attributes: !0,
185
+ attributeFilter: [
186
+ "base-heading-level",
187
+ "baseheadinglevel",
188
+ "include-sr-heading",
189
+ "includesrheading"
190
+ ]
191
+ }));
192
+ }
193
+ _disconnectPlayerObserver() {
194
+ this._playerObserver &&= (this._playerObserver.disconnect(), null);
195
+ }
196
+ disconnectedCallback() {
197
+ p(this), this._disconnectMathObserver(), this._disconnectPlayerObserver(), this._keyboardEventsEnabled &&= (window.removeEventListener("keydown", this._boundHandleKeyDown), !1), document.removeEventListener("click", this._enableAudio), this._audio &&= (this._audio.removeEventListener("playing", this._handlePlaying), this._audio.removeEventListener("ended", this._handleEnded), null), this._root &&= (this._root.unmount(), null);
198
+ }
199
+ handleKeyDown(e) {
200
+ if (!this._model || !this._session) return;
201
+ let { mode: t } = this._model;
202
+ if (t !== "gather") return;
203
+ let n = ((e) => {
204
+ let t = e >= "1" && e <= "9" ? e - "1" : e === "0" ? 9 : -1, n = /^[a-jA-J]$/.test(e) ? e.toLowerCase().charCodeAt(0) - 97 : -1;
205
+ return t >= 0 ? t : n;
206
+ })(e.key);
207
+ if (n === void 0 || n <= -1 || n >= this._model.choices?.length) return;
208
+ let r = this._session.value || [], i = this._model.choices[n].value, a = r.includes(i), o = {
209
+ value: i,
210
+ selected: this._model.choiceMode === "radio" || !a,
211
+ selector: "Keyboard"
212
+ };
213
+ this._onChange(o);
214
+ }
215
+ };
216
+ //#endregion
217
+ export { T as default, S as isComplete };
@@ -0,0 +1,31 @@
1
+ /**
2
+ * @synced-from pie-elements/packages/multiple-choice/src/main.jsx
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
+ import React from 'react';
10
+ import PropTypes from 'prop-types';
11
+ declare class Main extends React.Component {
12
+ static propTypes: {
13
+ model: PropTypes.Requireable<object>;
14
+ session: PropTypes.Requireable<object>;
15
+ options: PropTypes.Requireable<object>;
16
+ onChoiceChanged: PropTypes.Requireable<(...args: any[]) => any>;
17
+ onShowCorrectToggle: PropTypes.Requireable<(...args: any[]) => any>;
18
+ extraCSSRules: PropTypes.Requireable<PropTypes.InferProps<{
19
+ names: PropTypes.Requireable<(string | null | undefined)[]>;
20
+ rules: PropTypes.Requireable<string>;
21
+ }>>;
22
+ baseHeadingLevel: PropTypes.Requireable<number>;
23
+ includeSrHeading: PropTypes.Requireable<boolean>;
24
+ };
25
+ static defaultProps: {
26
+ model: {};
27
+ session: {};
28
+ };
29
+ render(): React.JSX.Element;
30
+ }
31
+ export default Main;
@@ -0,0 +1,51 @@
1
+ import { MultipleChoice as e } from "./multiple-choice.js";
2
+ import t from "react";
3
+ import n from "prop-types";
4
+ import * as r from "@pie-lib/render-ui";
5
+ import { PreviewLayout as i } from "@pie-lib/render-ui";
6
+ import { jsx as a } from "react/jsx-runtime";
7
+ //#region src/delivery/main.tsx
8
+ function o(e) {
9
+ return typeof e == "function" || typeof e == "object" && !!e && typeof e.$$typeof == "symbol";
10
+ }
11
+ function s(e, t) {
12
+ return !e || o(e) ? e : o(e.default) ? e.default : t && o(e[t]) ? e[t] : t && o(e[t]?.default) ? e[t].default : e;
13
+ }
14
+ var c = s(i, "PreviewLayout") || s(d.PreviewLayout, "PreviewLayout"), l = r, u = l.default, d = u && typeof u == "object" ? u : l, f = class extends t.Component {
15
+ static propTypes = {
16
+ model: n.object,
17
+ session: n.object,
18
+ options: n.object,
19
+ onChoiceChanged: n.func,
20
+ onShowCorrectToggle: n.func,
21
+ extraCSSRules: n.shape({
22
+ names: n.arrayOf(n.string),
23
+ rules: n.string
24
+ }),
25
+ baseHeadingLevel: n.number,
26
+ includeSrHeading: n.bool
27
+ };
28
+ static defaultProps = {
29
+ model: {},
30
+ session: {}
31
+ };
32
+ render() {
33
+ let { model: t, onChoiceChanged: n, session: r, onShowCorrectToggle: i, options: o, baseHeadingLevel: s, includeSrHeading: l } = this.props, { extraCSSRules: u, fontSizeFactor: d } = t;
34
+ return /* @__PURE__ */ a(c, {
35
+ extraCSSRules: u,
36
+ fontSizeFactor: d,
37
+ classes: {},
38
+ children: /* @__PURE__ */ a(e, {
39
+ ...t,
40
+ options: o,
41
+ session: r,
42
+ onChoiceChanged: n,
43
+ onShowCorrectToggle: i,
44
+ baseHeadingLevel: s,
45
+ includeSrHeading: l
46
+ })
47
+ });
48
+ }
49
+ };
50
+ //#endregion
51
+ export { f as default };
@@ -0,0 +1,61 @@
1
+ /**
2
+ * @synced-from pie-elements/packages/multiple-choice/src/multiple-choice.jsx
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
+ import React from 'react';
10
+ import PropTypes from 'prop-types';
11
+ export declare class MultipleChoice extends React.Component {
12
+ static propTypes: {
13
+ className: PropTypes.Requireable<string>;
14
+ mode: PropTypes.Requireable<string>;
15
+ choiceMode: PropTypes.Requireable<string>;
16
+ keyMode: PropTypes.Requireable<string>;
17
+ choices: PropTypes.Requireable<any[]>;
18
+ partLabel: PropTypes.Requireable<string>;
19
+ prompt: PropTypes.Requireable<string>;
20
+ teacherInstructions: PropTypes.Requireable<string>;
21
+ session: PropTypes.Requireable<object>;
22
+ disabled: PropTypes.Requireable<boolean>;
23
+ onChoiceChanged: PropTypes.Requireable<(...args: any[]) => any>;
24
+ responseCorrect: PropTypes.Requireable<boolean>;
25
+ correctResponse: PropTypes.Requireable<any[]>;
26
+ choicesLayout: PropTypes.Requireable<string>;
27
+ gridColumns: PropTypes.Requireable<string>;
28
+ alwaysShowCorrect: PropTypes.Requireable<boolean>;
29
+ animationsDisabled: PropTypes.Requireable<boolean>;
30
+ language: PropTypes.Requireable<string>;
31
+ selectedAnswerBackgroundColor: PropTypes.Requireable<string>;
32
+ selectedAnswerStrokeColor: PropTypes.Requireable<string>;
33
+ selectedAnswerStrokeWidth: PropTypes.Requireable<string>;
34
+ hoverAnswerBackgroundColor: PropTypes.Requireable<string>;
35
+ hoverAnswerStrokeColor: PropTypes.Requireable<string>;
36
+ hoverAnswerStrokeWidth: PropTypes.Requireable<string>;
37
+ onShowCorrectToggle: PropTypes.Requireable<(...args: any[]) => any>;
38
+ isSelectionButtonBelow: PropTypes.Requireable<boolean>;
39
+ minSelections: PropTypes.Requireable<number>;
40
+ maxSelections: PropTypes.Requireable<number>;
41
+ autoplayAudioEnabled: PropTypes.Requireable<boolean>;
42
+ customAudioButton: {
43
+ playImage: PropTypes.Requireable<string>;
44
+ pauseImage: PropTypes.Requireable<string>;
45
+ };
46
+ options: PropTypes.Requireable<object>;
47
+ baseHeadingLevel: PropTypes.Requireable<number>;
48
+ includeSrHeading: PropTypes.Requireable<boolean>;
49
+ };
50
+ constructor(props: any);
51
+ isSelected(value: any): any;
52
+ handleChange: any;
53
+ onToggle: any;
54
+ UNSAFE_componentWillReceiveProps(nextProps: any): void;
55
+ indexToSymbol(index: any): string;
56
+ getCorrectness: any;
57
+ getChecked(choice: any): any;
58
+ renderHeading(): React.JSX.Element | null;
59
+ render(): React.JSX.Element;
60
+ }
61
+ export default MultipleChoice;