@pie-lib/mask-markup 3.0.4-next.33 → 3.0.4-next.35

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.
@@ -9,16 +9,20 @@
9
9
  import React from 'react';
10
10
  import PropTypes from 'prop-types';
11
11
  export declare const DRAG_TYPE = "MaskBlank";
12
- declare function Choice({ choice, disabled, instanceId }: {
12
+ declare function Choice({ choice, disabled, instanceId, selectedItem, onSelectClick }: {
13
13
  choice: any;
14
14
  disabled: any;
15
15
  instanceId: any;
16
+ selectedItem: any;
17
+ onSelectClick: any;
16
18
  }): React.JSX.Element;
17
19
  declare namespace Choice {
18
20
  var propTypes: {
19
21
  choice: PropTypes.Validator<object>;
20
22
  disabled: PropTypes.Requireable<boolean>;
21
23
  instanceId: PropTypes.Requireable<NonNullable<string | number | null | undefined>>;
24
+ selectedItem: PropTypes.Requireable<object>;
25
+ onSelectClick: PropTypes.Requireable<(...args: any[]) => any>;
22
26
  };
23
27
  }
24
28
  export default Choice;
@@ -7,12 +7,12 @@ import { useDraggable as o } from "@dnd-kit/core";
7
7
  import s from "@mui/material/Chip";
8
8
  import { color as c } from "@pie-lib/render-ui";
9
9
  //#region src/choices/choice.tsx
10
- var l = "MaskBlank", u = r("span")(({ theme: e, disabled: t }) => ({
10
+ var l = "MaskBlank", u = r("span")(({ theme: e, disabled: t, selected: n }) => ({
11
11
  border: `solid 0px ${e.palette.primary.main}`,
12
- borderRadius: e.spacing(2),
13
12
  margin: e.spacing(.5),
14
13
  transform: "translate(0, 0)",
15
14
  display: "inline-flex",
15
+ opacity: n ? .7 : 1,
16
16
  ...t && {}
17
17
  })), d = r(s)(() => ({
18
18
  backgroundColor: c.white(),
@@ -36,10 +36,11 @@ var l = "MaskBlank", u = r("span")(({ theme: e, disabled: t }) => ({
36
36
  display: "block",
37
37
  padding: "2px 0"
38
38
  },
39
- "& mjx-frac": { fontSize: "120% !important" }
39
+ "& mjx-frac": { fontSize: "120% !important" },
40
+ "& mjx-mn:has(~ mjx-mfrac), mjx-mfrac ~ mjx-mn": { fontSize: "120% !important" }
40
41
  }));
41
- function p({ choice: n, disabled: r, instanceId: s }) {
42
- let c = t(null), { attributes: p, listeners: m, setNodeRef: h, isDragging: g } = o({
42
+ function p({ choice: n, disabled: r, instanceId: s, selectedItem: c, onSelectClick: p }) {
43
+ let m = t(null), { attributes: h, listeners: g, setNodeRef: _, isDragging: v } = o({
43
44
  id: `choice-${n.id}`,
44
45
  data: {
45
46
  choice: n,
@@ -49,21 +50,32 @@ function p({ choice: n, disabled: r, instanceId: s }) {
49
50
  },
50
51
  disabled: r
51
52
  });
52
- return e(() => {
53
- i(c.current);
54
- }, [n.value]), /* @__PURE__ */ a(u, {
55
- ref: h,
56
- style: g ? {
57
- width: c.current?.offsetWidth,
58
- height: c.current?.offsetHeight
53
+ e(() => {
54
+ i(m.current);
55
+ }, [n.value]);
56
+ let y = !!c && c.fromChoice === !0 && c.choice.id === n.id;
57
+ return /* @__PURE__ */ a(u, {
58
+ ref: _,
59
+ style: v ? {
60
+ width: m.current?.offsetWidth || 90,
61
+ height: m.current?.offsetHeight || 32
59
62
  } : {},
60
63
  disabled: r,
61
- ...m,
62
- ...p,
64
+ selected: y,
65
+ onClick: (e) => {
66
+ r || (e.stopPropagation(), p?.({
67
+ choice: n,
68
+ instanceId: s,
69
+ fromChoice: !0,
70
+ type: l
71
+ }));
72
+ },
73
+ ...g,
74
+ ...h,
63
75
  children: /* @__PURE__ */ a(d, {
64
76
  clickable: !1,
65
77
  disabled: r,
66
- ref: c,
78
+ ref: m,
67
79
  label: /* @__PURE__ */ a(f, { dangerouslySetInnerHTML: { __html: n.value } })
68
80
  })
69
81
  });
@@ -71,7 +83,9 @@ function p({ choice: n, disabled: r, instanceId: s }) {
71
83
  p.propTypes = {
72
84
  choice: n.object.isRequired,
73
85
  disabled: n.bool,
74
- instanceId: n.oneOfType([n.string, n.number])
86
+ instanceId: n.oneOfType([n.string, n.number]),
87
+ selectedItem: n.object,
88
+ onSelectClick: n.func
75
89
  };
76
90
  //#endregion
77
- export { p as default };
91
+ export { l as DRAG_TYPE, p as default };
@@ -19,7 +19,11 @@ export default class Choices extends React.Component {
19
19
  value: PropTypes.Requireable<object>;
20
20
  choicePosition: PropTypes.Validator<string>;
21
21
  instanceId: PropTypes.Requireable<string>;
22
+ selectedItem: PropTypes.Requireable<object>;
23
+ onSelectClick: PropTypes.Requireable<(...args: any[]) => any>;
24
+ onPlacementClick: PropTypes.Requireable<(...args: any[]) => any>;
22
25
  };
23
26
  getStyleForWrapper: any;
27
+ handlePoolClick: any;
24
28
  render(): React.JSX.Element;
25
29
  }
@@ -15,7 +15,10 @@ var o = class extends t.Component {
15
15
  })),
16
16
  value: n.object,
17
17
  choicePosition: n.string.isRequired,
18
- instanceId: n.string
18
+ instanceId: n.string,
19
+ selectedItem: n.object,
20
+ onSelectClick: n.func,
21
+ onPlacementClick: n.func
19
22
  };
20
23
  getStyleForWrapper = () => {
21
24
  let { choicePosition: e } = this.props;
@@ -26,20 +29,27 @@ var o = class extends t.Component {
26
29
  default: return { margin: "0 40px 0 0" };
27
30
  }
28
31
  };
32
+ handlePoolClick = () => {
33
+ let { disabled: e, selectedItem: t, onPlacementClick: n } = this.props;
34
+ e || t && n?.(void 0);
35
+ };
29
36
  render() {
30
- let { disabled: t, duplicates: n, choices: o, value: s, instanceId: c } = this.props, l = o.filter((e) => n === !0 ? !0 : r(s, (t) => t === e.id) === void 0);
37
+ let { disabled: t, duplicates: n, choices: o, value: s, instanceId: c, selectedItem: l, onSelectClick: u } = this.props, d = o.filter((e) => n === !0 || r(s, (t) => t === e.id) === void 0);
31
38
  return /* @__PURE__ */ i("div", {
32
39
  style: {
33
40
  ...this.getStyleForWrapper(),
34
41
  minWidth: "100px"
35
42
  },
43
+ onClick: this.handlePoolClick,
36
44
  children: /* @__PURE__ */ i(a, {
37
45
  disabled: t,
38
46
  instanceId: c,
39
- children: l.map((n, r) => /* @__PURE__ */ i(e, {
47
+ children: d.map((n, r) => /* @__PURE__ */ i(e, {
40
48
  disabled: t,
41
49
  choice: n,
42
- instanceId: c
50
+ instanceId: c,
51
+ selectedItem: l,
52
+ onSelectClick: u
43
53
  }, `${n.value}-${r}`))
44
54
  })
45
55
  });
@@ -8,7 +8,7 @@
8
8
  */
9
9
  import React from 'react';
10
10
  import PropTypes from 'prop-types';
11
- declare function DragDropBlank({ id, disabled, duplicates, choice, correct, onChange, emptyResponseAreaWidth, emptyResponseAreaHeight, instanceId, }: {
11
+ declare function DragDropBlank({ id, disabled, duplicates, choice, correct, onChange, emptyResponseAreaWidth, emptyResponseAreaHeight, instanceId, selectedItem, onSelectClick, onPlacementClick, }: {
12
12
  id: any;
13
13
  disabled: any;
14
14
  duplicates: any;
@@ -18,6 +18,9 @@ declare function DragDropBlank({ id, disabled, duplicates, choice, correct, onCh
18
18
  emptyResponseAreaWidth: any;
19
19
  emptyResponseAreaHeight: any;
20
20
  instanceId: any;
21
+ selectedItem: any;
22
+ onSelectClick: any;
23
+ onPlacementClick: any;
21
24
  }): React.JSX.Element;
22
25
  declare namespace DragDropBlank {
23
26
  var defaultProps: {
@@ -34,6 +37,9 @@ declare namespace DragDropBlank {
34
37
  emptyResponseAreaWidth: PropTypes.Requireable<NonNullable<string | number | null | undefined>>;
35
38
  emptyResponseAreaHeight: PropTypes.Requireable<NonNullable<string | number | null | undefined>>;
36
39
  instanceId: PropTypes.Requireable<string>;
40
+ selectedItem: PropTypes.Requireable<object>;
41
+ onSelectClick: PropTypes.Requireable<(...args: any[]) => any>;
42
+ onPlacementClick: PropTypes.Requireable<(...args: any[]) => any>;
37
43
  };
38
44
  }
39
45
  export default DragDropBlank;
@@ -1,4 +1,4 @@
1
- import e from "../node_modules/.bun/clsx@2.1.1/node_modules/clsx/dist/clsx.js";
1
+ import { clsx as e } from "../node_modules/.bun/clsx@2.1.1/node_modules/clsx/dist/clsx.js";
2
2
  import t, { useEffect as n, useRef as r, useState as i } from "react";
3
3
  import a from "prop-types";
4
4
  import { styled as o } from "@mui/material/styles";
@@ -8,23 +8,26 @@ import { jsx as l, jsxs as u } from "react/jsx-runtime";
8
8
  import { useDraggable as d, useDroppable as f } from "@dnd-kit/core";
9
9
  import p from "@mui/material/Chip";
10
10
  import { color as m } from "@pie-lib/render-ui";
11
- import { CSS as h } from "@dnd-kit/utilities";
12
- import { grey as g } from "@mui/material/colors";
11
+ import { grey as h } from "@mui/material/colors";
13
12
  //#region src/components/blank.tsx
14
13
  c("pie-lib:mask-markup:blank");
15
- var _ = o("span")(({ dragged: e, over: t }) => ({
14
+ var g = o("span")(({ dragged: e, over: t, selected: n, showsPointerCursor: r }) => ({
16
15
  border: `solid 0px ${m.primary()}`,
17
16
  minWidth: "200px",
18
- touchAction: "none",
19
17
  overflow: "hidden",
20
18
  whiteSpace: "nowrap",
21
19
  opacity: 1,
20
+ cursor: "default",
22
21
  ...t && {
23
22
  whiteSpace: "nowrap",
24
23
  overflow: "hidden"
25
24
  },
26
- ...e && { opacity: .5 }
27
- })), v = o(p)(() => ({
25
+ ...(e || n) && { opacity: .5 },
26
+ ...r && { "&:hover": { cursor: "pointer" } }
27
+ })), _ = o("span")({
28
+ display: "inline-flex",
29
+ touchAction: "none"
30
+ }), v = o(p)(() => ({
28
31
  backgroundColor: m.background(),
29
32
  border: `2px dashed ${m.text()}`,
30
33
  touchAction: "none",
@@ -38,8 +41,8 @@ var _ = o("span")(({ dragged: e, over: t }) => ({
38
41
  overflow: "hidden"
39
42
  },
40
43
  "&.parentOver": {
41
- border: `1px solid ${g[500]}`,
42
- backgroundColor: `${g[300]}`
44
+ border: `1px solid ${h[500]}`,
45
+ backgroundColor: `${h[300]}`
43
46
  },
44
47
  "&.correct": { border: `solid 1px ${m.correct()}` },
45
48
  "&.incorrect": { border: `solid 1px ${m.incorrect()}` },
@@ -56,6 +59,7 @@ var _ = o("span")(({ dragged: e, over: t }) => ({
56
59
  marginBottom: "0"
57
60
  },
58
61
  "& mjx-frac": { fontSize: "120% !important" },
62
+ "& mjx-mn:has(~ mjx-mfrac), mjx-mfrac ~ mjx-mn": { fontSize: "120% !important" },
59
63
  "&.over": {
60
64
  whiteSpace: "nowrap",
61
65
  overflow: "hidden"
@@ -73,36 +77,49 @@ var _ = o("span")(({ dragged: e, over: t }) => ({
73
77
  }
74
78
  }));
75
79
  function b({ disabled: a, choice: o, isOver: c, isDragging: d, dragItem: f, correct: p, emptyResponseAreaWidth: m, emptyResponseAreaHeight: h }) {
76
- let g = r(null), _ = r(null), b = r(null), [x, S] = i({
80
+ let g = r(null), _ = r(null), b = r(null), x = r(!1), [S, C] = i({
77
81
  height: 0,
78
82
  width: 0
79
- }), C = () => {
80
- E();
81
- }, w = () => {
83
+ }), w = () => {
84
+ D();
85
+ }, T = () => {
82
86
  let e = _.current?.querySelector("img");
83
- e ? e.onload = C : setTimeout(() => {
84
- E();
87
+ e ? e.onload = w : setTimeout(() => {
88
+ D();
85
89
  }, 300);
86
- }, T = () => _.current ? _.current.querySelector("mjx-container") && _.current.parentElement ? _.current.parentElement : _.current.querySelector("img") || _.current : null, E = () => {
87
- if (_.current && g.current) {
88
- g.current.style.width = "auto", g.current.style.height = "auto", g.current.offsetHeight;
89
- let e = T() || _.current, t = e.getBoundingClientRect(), n = t.width || e.offsetWidth || 0, r = Math.max(t.height || 0, e.offsetHeight || 0, e.scrollHeight || 0, _.current.scrollHeight || 0), i = n + 24, a = r + 24, o = parseFloat(m) || 0, s = parseFloat(h) || 0, c = i <= o ? o : i, l = a <= s ? s : a;
90
- S((e) => ({
90
+ }, E = () => {
91
+ if (!_.current) return null;
92
+ if (_.current.querySelector("mjx-container") && _.current.parentElement) return _.current.parentElement;
93
+ let e = _.current.querySelector("img");
94
+ return e ? _.current.textContent.trim().length > 0 ? _.current : e : _.current;
95
+ }, D = () => {
96
+ if (_.current && g.current && !x.current) {
97
+ x.current = !0, g.current.style.width = "auto", g.current.style.height = "auto", g.current.offsetHeight;
98
+ let e = E() || _.current, t = e.getBoundingClientRect(), n = e.offsetWidth || t.width || 0, r = Math.max(e.offsetHeight || 0, t.height || 0, e.scrollHeight || 0, _.current.scrollHeight || 0), i = n + 24 + 4 + 1, a = r + 24 + 4 + 1, o = parseFloat(m) || 0, s = parseFloat(h) || 0, c = i <= o ? o : i, l = a <= s ? s : a;
99
+ C((e) => ({
91
100
  width: c > o ? c : e.width,
92
101
  height: l > s ? l : e.height
93
- })), g.current.style.width = `${c}px`, g.current.style.height = `${l}px`;
102
+ }));
103
+ let u = `${c}px`, d = `${l}px`;
104
+ g.current.style.width !== u && (g.current.style.width = u), g.current.style.height !== d && (g.current.style.height = d), x.current = !1;
94
105
  }
95
- }, D = () => {
106
+ }, O = () => {
96
107
  let e = isNaN(parseFloat(m)) ? 0 : parseFloat(m), t = isNaN(parseFloat(h)) ? 0 : parseFloat(h);
97
108
  return {
98
- height: x.height || t,
99
- width: x.width || e,
109
+ height: S.height || t,
110
+ width: S.width || e,
100
111
  ...e ? {} : { minWidth: 90 },
101
112
  ...t ? {} : { minHeight: 32 }
102
113
  };
103
114
  };
104
115
  n(() => {
105
- w();
116
+ T();
117
+ }, []), n(() => {
118
+ if (typeof IntersectionObserver > "u" || !g.current) return;
119
+ let e = new IntersectionObserver((e) => {
120
+ e.some((e) => e.isIntersecting) && D();
121
+ }, { threshold: 0 });
122
+ return e.observe(g.current), () => e.disconnect();
106
123
  }, []), n(() => {
107
124
  g.current && s(g.current);
108
125
  }, [
@@ -111,14 +128,14 @@ function b({ disabled: a, choice: o, isOver: c, isDragging: d, dragItem: f, corr
111
128
  f?.choice?.value
112
129
  ]), n(() => {
113
130
  if (!o) {
114
- S({
131
+ C({
115
132
  height: 0,
116
133
  width: 0
117
134
  });
118
135
  return;
119
136
  }
120
- w();
121
- }, [o]), n(() => {
137
+ T();
138
+ }, [o?.value]), n(() => {
122
139
  !c && !d && (b.current = {
123
140
  width: g.current.offsetWidth,
124
141
  height: g.current.offsetHeight
@@ -128,10 +145,10 @@ function b({ disabled: a, choice: o, isOver: c, isDragging: d, dragItem: f, corr
128
145
  c,
129
146
  d
130
147
  ]);
131
- let O = f && c && f.choice && f.choice.value, k = o && o.value, A = c || d ? {
148
+ let k = f && c && f.choice && f.choice.value, A = o && o.value, j = c || d ? {
132
149
  width: b.current?.width,
133
150
  height: b.current?.height
134
- } : D();
151
+ } : O();
135
152
  return /* @__PURE__ */ l(v, {
136
153
  clickable: !1,
137
154
  disabled: a,
@@ -142,16 +159,16 @@ function b({ disabled: a, choice: o, isOver: c, isDragging: d, dragItem: f, corr
142
159
  draggable: !0,
143
160
  className: e({
144
161
  over: c,
145
- hidden: O
162
+ hidden: k
146
163
  }),
147
- dangerouslySetInnerHTML: { __html: k || "" }
148
- }), O && /* @__PURE__ */ l(y, {
164
+ dangerouslySetInnerHTML: { __html: A || "" }
165
+ }), k && /* @__PURE__ */ l(y, {
149
166
  draggable: !0,
150
167
  className: e({
151
168
  over: c,
152
169
  dragged: !0
153
170
  }),
154
- dangerouslySetInnerHTML: { __html: O || "" }
171
+ dangerouslySetInnerHTML: { __html: k || "" }
155
172
  })] }),
156
173
  className: e({
157
174
  over: c,
@@ -160,7 +177,7 @@ function b({ disabled: a, choice: o, isOver: c, isDragging: d, dragItem: f, corr
160
177
  incorrect: p !== void 0 && !p
161
178
  }),
162
179
  variant: a ? "outlined" : void 0,
163
- style: A
180
+ style: j
164
181
  });
165
182
  }
166
183
  b.defaultProps = {
@@ -179,46 +196,59 @@ b.defaultProps = {
179
196
  emptyResponseAreaHeight: a.oneOfType([a.string, a.number]),
180
197
  instanceId: a.string
181
198
  };
182
- function x({ id: e, disabled: t, duplicates: n, choice: r, correct: i, onChange: a, emptyResponseAreaWidth: o, emptyResponseAreaHeight: s, instanceId: c }) {
183
- let { attributes: u, listeners: p, setNodeRef: m, transform: g, isDragging: v } = d({
199
+ function x({ id: e, disabled: t, duplicates: n, choice: r, correct: a, onChange: o, emptyResponseAreaWidth: s, emptyResponseAreaHeight: c, instanceId: u, selectedItem: p, onSelectClick: m, onPlacementClick: h }) {
200
+ let [v, y] = i(!1), x = {
201
+ id: e,
202
+ choice: r,
203
+ instanceId: u,
204
+ fromChoice: !1,
205
+ type: "MaskBlank"
206
+ }, { attributes: S, listeners: C, setNodeRef: w, isDragging: T } = d({
184
207
  id: `mask-blank-drag-${e}`,
185
208
  disabled: t || !r,
186
- data: {
187
- id: e,
188
- choice: r,
189
- instanceId: c,
190
- fromChoice: !1,
191
- type: "MaskBlank"
192
- }
193
- }), { setNodeRef: y, isOver: x, active: S } = f({
209
+ data: x,
210
+ attributes: { tabIndex: r && !t ? 0 : -1 }
211
+ }), { setNodeRef: E, isOver: D, active: O } = f({
194
212
  id: `mask-blank-drop-${e}`,
195
213
  data: {
196
214
  id: e,
197
215
  accepts: ["MaskBlank"],
198
- instanceId: c
216
+ instanceId: u
199
217
  }
200
- });
201
- return /* @__PURE__ */ l(_, {
202
- ref: (e) => {
203
- m(e), y(e);
204
- },
205
- style: { transform: h.Translate.toString(g) },
206
- dragged: v,
207
- over: x,
208
- ...u,
209
- ...p,
210
- children: /* @__PURE__ */ l(b, {
211
- id: e,
212
- disabled: t,
213
- duplicates: n,
214
- choice: r,
215
- isOver: x,
216
- dragItem: S?.data?.current,
217
- correct: i,
218
- onChange: a,
219
- emptyResponseAreaWidth: o,
220
- emptyResponseAreaHeight: s,
221
- instanceId: c
218
+ }), k = !!p && p.fromChoice === !1 && p.id === e, A = () => {
219
+ t || (k ? m?.(x) : p ? h?.(e) : r && m?.(x));
220
+ }, j = !r && !t, M = !!r && !t, N = (e) => {
221
+ (e.code === "Space" || e.code === "Enter") && (e.preventDefault(), A());
222
+ }, P = !!p, F = D || P && v && !t;
223
+ return /* @__PURE__ */ l(g, {
224
+ ref: E,
225
+ role: j ? "button" : void 0,
226
+ tabIndex: j ? 0 : -1,
227
+ onClick: A,
228
+ onKeyDown: j ? N : void 0,
229
+ onMouseEnter: () => y(!0),
230
+ onMouseLeave: () => y(!1),
231
+ dragged: T,
232
+ over: F,
233
+ selected: k,
234
+ showsPointerCursor: P && !t,
235
+ children: /* @__PURE__ */ l(_, {
236
+ ref: w,
237
+ ...M ? S : {},
238
+ ...C,
239
+ children: /* @__PURE__ */ l(b, {
240
+ id: e,
241
+ disabled: t,
242
+ duplicates: n,
243
+ choice: r,
244
+ isOver: F,
245
+ dragItem: O?.data?.current,
246
+ correct: a,
247
+ onChange: o,
248
+ emptyResponseAreaWidth: s,
249
+ emptyResponseAreaHeight: c,
250
+ instanceId: u
251
+ })
222
252
  })
223
253
  });
224
254
  }
@@ -234,7 +264,10 @@ x.defaultProps = {
234
264
  onChange: a.func,
235
265
  emptyResponseAreaWidth: a.oneOfType([a.string, a.number]),
236
266
  emptyResponseAreaHeight: a.oneOfType([a.string, a.number]),
237
- instanceId: a.string
267
+ instanceId: a.string,
268
+ selectedItem: a.object,
269
+ onSelectClick: a.func,
270
+ onPlacementClick: a.func
238
271
  };
239
272
  //#endregion
240
273
  export { x as default };
@@ -55,16 +55,7 @@ var y = v(c, "InlineMenu") || v(S.InlineMenu, "InlineMenu"), b = s, x = b.defaul
55
55
  color: `${l.text()} !important`
56
56
  }
57
57
  })), w = n(y)(() => ({
58
- backgroundColor: l.background(),
59
- border: `1px solid ${l.correct()} !important`,
60
- "&:hover": {
61
- border: `1px solid ${l.text()} `,
62
- borderColor: "initial"
63
- },
64
- "&:focus": {
65
- border: `1px solid ${l.text()}`,
66
- borderColor: "initial"
67
- },
58
+ "& .MuiPaper-root": { backgroundColor: l.background() },
68
59
  "& .MuiList-root": { padding: 0 }
69
60
  })), T = n(f)(() => ({
70
61
  height: 24,
@@ -1,5 +1,5 @@
1
1
  import { withMask as e } from "./with-mask.js";
2
- import t from "./node_modules/.bun/clsx@2.1.1/node_modules/clsx/dist/clsx.js";
2
+ import { clsx as t } from "./node_modules/.bun/clsx@2.1.1/node_modules/clsx/dist/clsx.js";
3
3
  import "react";
4
4
  import { styled as n } from "@mui/material/styles";
5
5
  import { jsx as r } from "react/jsx-runtime";
@@ -23,10 +23,11 @@ var o = n(a)(() => ({
23
23
  disabled: l || s,
24
24
  disableUnderline: !0,
25
25
  onChange: (e) => {
26
- p({
26
+ let t = {
27
27
  ...i,
28
28
  [m.id]: e
29
- });
29
+ };
30
+ p(t);
30
31
  },
31
32
  markup: g || "",
32
33
  charactersLimit: a ? _ : 25,
@@ -31,7 +31,17 @@ export default class DragInTheBlank extends React.Component {
31
31
  };
32
32
  handleDragStart: any;
33
33
  renderDragOverlay: any;
34
+ commitPlacement: any;
34
35
  handleDragEnd: any;
36
+ onDragCancel: any;
37
+ isSameItem: any;
38
+ toggleItemSelection: any;
39
+ cancelSelection: any;
40
+ endAnyLiveKeyboardDrag: any;
41
+ placeSelectedItem: any;
42
+ isClickSoonAfterDragEnd: () => boolean;
43
+ onItemClick: any;
44
+ onPlacementClick: any;
35
45
  getPositionDirection: any;
36
46
  render(): React.JSX.Element;
37
47
  }
@@ -2,21 +2,22 @@ import { withMask as e } from "./with-mask.js";
2
2
  import t from "./choices/choice.js";
3
3
  import n from "./choices/index.js";
4
4
  import r from "./components/blank.js";
5
- import i from "react";
6
- import a from "prop-types";
7
- import { jsx as o, jsxs as s } from "react/jsx-runtime";
8
- import { DragProvider as c } from "@pie-lib/drag";
9
- import { DragOverlay as l, rectIntersection as u } from "@dnd-kit/core";
5
+ import { closestDroppableKeyboardCoordinates as i } from "./keyboard-coordinates.js";
6
+ import a from "react";
7
+ import o from "prop-types";
8
+ import { jsx as s, jsxs as c } from "react/jsx-runtime";
9
+ import { DragProvider as l } from "@pie-lib/drag";
10
+ import { DragOverlay as u, rectIntersection as d } from "@dnd-kit/core";
10
11
  //#region src/drag-in-the-blank.tsx
11
- var d = e("blank", (e) => (t, n, i) => {
12
+ var f = 250, p = e("blank", (e) => (t, n, i) => {
12
13
  let a = t.data?.dataset || {};
13
14
  if (a.component === "blank") {
14
- let { disabled: s, duplicates: c, correctResponse: l, feedback: u, showCorrectAnswer: d, emptyResponseAreaWidth: f, emptyResponseAreaHeight: p, instanceId: m, isDragging: h } = e, g = d ? l[a.id] : n[a.id], _ = g && e.choices.find((e) => e.id === g);
15
- return /* @__PURE__ */ o(r, {
15
+ let { disabled: o, duplicates: c, correctResponse: l, feedback: u, showCorrectAnswer: d, emptyResponseAreaWidth: f, emptyResponseAreaHeight: p, instanceId: m, isDragging: h, selectedItem: g, onSelectClick: _, onPlacementClick: v } = e, y = d ? l[a.id] : n[a.id], b = y && e.choices.find((e) => e.id === y);
16
+ return /* @__PURE__ */ s(r, {
16
17
  correct: d || u && u[a.id],
17
- disabled: s,
18
+ disabled: o,
18
19
  duplicates: c,
19
- choice: _,
20
+ choice: b,
20
21
  id: a.id,
21
22
  emptyResponseAreaWidth: f,
22
23
  emptyResponseAreaHeight: p,
@@ -25,70 +26,112 @@ var d = e("blank", (e) => (t, n, i) => {
25
26
  t === void 0 ? delete r[e] : r[e] = t, i(r);
26
27
  },
27
28
  instanceId: m,
28
- isDragging: h
29
+ isDragging: h,
30
+ selectedItem: g,
31
+ onSelectClick: _,
32
+ onPlacementClick: v
29
33
  }, `${t.type}-${a.id}`);
30
34
  }
31
- }), f = class extends i.Component {
35
+ }), m = class extends a.Component {
32
36
  constructor(e) {
33
37
  super(e), this.state = {
34
38
  activeDragItem: null,
35
- dropAnimation: void 0
36
- };
39
+ dropAnimation: void 0,
40
+ selectedItem: null
41
+ }, this.lastDragEndAt = 0;
37
42
  }
38
43
  static propTypes = {
39
- markup: a.string,
40
- layout: a.object,
41
- choicesPosition: a.string,
42
- choices: a.array,
43
- value: a.object,
44
- onChange: a.func,
45
- duplicates: a.bool,
46
- disabled: a.bool,
47
- feedback: a.object,
48
- correctResponse: a.object,
49
- showCorrectAnswer: a.bool,
50
- emptyResponseAreaWidth: a.oneOfType([a.string, a.number]),
51
- emptyResponseAreaHeight: a.oneOfType([a.string, a.number]),
52
- instanceId: a.string
44
+ markup: o.string,
45
+ layout: o.object,
46
+ choicesPosition: o.string,
47
+ choices: o.array,
48
+ value: o.object,
49
+ onChange: o.func,
50
+ duplicates: o.bool,
51
+ disabled: o.bool,
52
+ feedback: o.object,
53
+ correctResponse: o.object,
54
+ showCorrectAnswer: o.bool,
55
+ emptyResponseAreaWidth: o.oneOfType([o.string, o.number]),
56
+ emptyResponseAreaHeight: o.oneOfType([o.string, o.number]),
57
+ instanceId: o.string
53
58
  };
54
59
  static defaultProps = { instanceId: "drag-in-the-blank" };
55
60
  handleDragStart = (e) => {
56
61
  let { active: t } = e;
57
62
  t?.data?.current && this.setState({
58
63
  activeDragItem: t.data.current,
59
- dropAnimation: void 0
64
+ dropAnimation: void 0,
65
+ selectedItem: t.data.current
60
66
  });
61
67
  };
62
68
  renderDragOverlay = () => {
63
69
  let { activeDragItem: e } = this.state;
64
- return e && e.type === "MaskBlank" ? /* @__PURE__ */ o(t, {
70
+ return e && e.type === "MaskBlank" ? /* @__PURE__ */ s(t, {
65
71
  disabled: e.disabled,
66
72
  choice: e.choice,
67
73
  instanceId: e.instanceId
68
74
  }) : null;
69
75
  };
70
- handleDragEnd = (e) => {
71
- let { active: t, over: n } = e, { onChange: r, value: i } = this.props, a = t?.data?.current, o = n?.data?.current, s = !!t && !!n && a?.type === "MaskBlank" && o?.accepts?.includes("MaskBlank");
72
- if (this.setState({
73
- activeDragItem: null,
74
- dropAnimation: s ? null : void 0
75
- }), !s || !r) return;
76
- let c = a, l = o.id;
77
- if (o.toChoiceBoard === !0) {
78
- if (!c.fromChoice && c.id) {
79
- let e = { ...i };
80
- delete e[c.id], r(e);
76
+ commitPlacement = (e, t) => {
77
+ let { onChange: n, value: r } = this.props;
78
+ if (n) {
79
+ if (t === void 0) {
80
+ if (!e.fromChoice && e.id) {
81
+ let t = { ...r };
82
+ delete t[e.id], n(t);
83
+ }
84
+ return;
81
85
  }
82
- } else if (c.fromChoice === !0) {
83
- if (l && l !== "drag-in-the-blank-droppable") {
84
- let e = { ...i };
85
- e[l] = c.choice.id, r(e);
86
+ if (e.fromChoice === !0) {
87
+ let i = { ...r };
88
+ i[t] = e.choice.id, n(i);
89
+ } else if (e.id && e.id !== t) {
90
+ let i = { ...r };
91
+ i[t] = e.choice.id, delete i[e.id], n(i);
86
92
  }
87
- } else if (c.id && c.id !== l) {
88
- let e = { ...i };
89
- e[l] = c.choice.id, delete e[c.id], r(e);
90
93
  }
91
94
  };
95
+ handleDragEnd = (e) => {
96
+ let { active: t, over: n } = e, r = t?.data?.current, i = n?.data?.current, a = !!t && !!n && r?.type === "MaskBlank" && i?.accepts?.includes("MaskBlank");
97
+ if (this.setState({
98
+ activeDragItem: null,
99
+ dropAnimation: a ? null : void 0
100
+ }), this.cancelSelection(), this.lastDragEndAt = Date.now(), !a) return;
101
+ let o = i.toChoiceBoard === !0 ? void 0 : i.id;
102
+ this.commitPlacement(r, o);
103
+ };
104
+ onDragCancel = () => {
105
+ this.setState({
106
+ activeDragItem: null,
107
+ dropAnimation: void 0
108
+ }), this.cancelSelection(), this.lastDragEndAt = Date.now();
109
+ };
110
+ isSameItem = (e, t) => !e || !t || e.fromChoice !== t.fromChoice ? !1 : e.fromChoice ? e.choice.id === t.choice.id : e.id === t.id;
111
+ toggleItemSelection = (e) => {
112
+ this.setState((t) => ({ selectedItem: this.isSameItem(t.selectedItem, e) ? null : e }));
113
+ };
114
+ cancelSelection = () => {
115
+ this.setState({ selectedItem: null });
116
+ };
117
+ endAnyLiveKeyboardDrag = () => {
118
+ this.state.activeDragItem && document.dispatchEvent(new KeyboardEvent("keydown", {
119
+ code: "Escape",
120
+ bubbles: !0,
121
+ cancelable: !0
122
+ }));
123
+ };
124
+ placeSelectedItem = (e) => {
125
+ let { selectedItem: t } = this.state;
126
+ t && (this.commitPlacement(t, e), this.cancelSelection(), this.endAnyLiveKeyboardDrag());
127
+ };
128
+ isClickSoonAfterDragEnd = () => Date.now() - this.lastDragEndAt < f;
129
+ onItemClick = (e) => {
130
+ this.isClickSoonAfterDragEnd() || (this.endAnyLiveKeyboardDrag(), this.toggleItemSelection(e));
131
+ };
132
+ onPlacementClick = (e) => {
133
+ this.isClickSoonAfterDragEnd() || this.placeSelectedItem(e);
134
+ };
92
135
  getPositionDirection = (e) => {
93
136
  let t, n, r;
94
137
  switch (e) {
@@ -112,45 +155,58 @@ var d = e("blank", (e) => (t, n, i) => {
112
155
  };
113
156
  };
114
157
  render() {
115
- let { markup: e, duplicates: t, value: r, onChange: i, choicesPosition: a, choices: f, correctResponse: p, disabled: m, feedback: h, showCorrectAnswer: g, emptyResponseAreaWidth: _, emptyResponseAreaHeight: v, layout: y, instanceId: b } = this.props, x = a || "below", S = {
158
+ let { markup: e, duplicates: t, value: r, onChange: a, choicesPosition: o, choices: f, correctResponse: m, disabled: h, feedback: g, showCorrectAnswer: _, emptyResponseAreaWidth: v, emptyResponseAreaHeight: y, layout: b, instanceId: x } = this.props, S = o || "below", C = {
116
159
  display: "flex",
117
160
  minWidth: "100px",
118
- ...this.getPositionDirection(x)
161
+ ...this.getPositionDirection(S)
119
162
  };
120
- return /* @__PURE__ */ o(c, {
163
+ return /* @__PURE__ */ s(l, {
121
164
  onDragStart: this.handleDragStart,
122
165
  onDragEnd: this.handleDragEnd,
123
- collisionDetection: u,
124
- children: /* @__PURE__ */ s("div", {
166
+ onDragCancel: this.onDragCancel,
167
+ collisionDetection: d,
168
+ keyboardCoordinateGetter: i,
169
+ keyboardCodes: {
170
+ start: ["Space", "Enter"],
171
+ cancel: ["Escape"],
172
+ end: ["Space", "Enter"]
173
+ },
174
+ children: /* @__PURE__ */ c("div", {
125
175
  ref: (e) => this.rootRef = e,
126
- style: S,
176
+ style: C,
127
177
  children: [
128
- /* @__PURE__ */ o(n, {
129
- choicePosition: x,
178
+ /* @__PURE__ */ s(n, {
179
+ choicePosition: S,
130
180
  choices: f,
131
181
  value: r,
132
182
  duplicates: t,
133
- disabled: m,
134
- instanceId: b
183
+ disabled: h,
184
+ instanceId: x,
185
+ selectedItem: this.state.selectedItem,
186
+ onSelectClick: this.onItemClick,
187
+ onPlacementClick: this.onPlacementClick
135
188
  }),
136
- /* @__PURE__ */ o(d, {
189
+ /* @__PURE__ */ s(p, {
137
190
  elementType: "drag-in-the-blank",
138
191
  markup: e,
139
- layout: y,
192
+ layout: b,
140
193
  value: r,
141
194
  choices: f,
142
- onChange: i,
143
- disabled: m,
195
+ onChange: a,
196
+ disabled: h,
144
197
  duplicates: t,
145
- feedback: h,
146
- correctResponse: p,
147
- showCorrectAnswer: g,
148
- emptyResponseAreaWidth: _,
149
- emptyResponseAreaHeight: v,
150
- instanceId: b,
151
- isDragging: !!this.state.activeDragItem
198
+ feedback: g,
199
+ correctResponse: m,
200
+ showCorrectAnswer: _,
201
+ emptyResponseAreaWidth: v,
202
+ emptyResponseAreaHeight: y,
203
+ instanceId: x,
204
+ isDragging: !!this.state.activeDragItem,
205
+ selectedItem: this.state.selectedItem,
206
+ onSelectClick: this.onItemClick,
207
+ onPlacementClick: this.onPlacementClick
152
208
  }),
153
- /* @__PURE__ */ o(l, {
209
+ /* @__PURE__ */ s(u, {
154
210
  style: { pointerEvents: "none" },
155
211
  dropAnimation: this.state.dropAnimation,
156
212
  children: this.renderDragOverlay()
@@ -161,4 +217,4 @@ var d = e("blank", (e) => (t, n, i) => {
161
217
  }
162
218
  };
163
219
  //#endregion
164
- export { f as default };
220
+ export { m as default };
@@ -0,0 +1,25 @@
1
+ /**
2
+ * @synced-from pie-lib/packages/mask-markup/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 drag-in-the-blank's Tab-based placement.
11
+ *
12
+ * Tab/Shift+Tab cycle the dragged item directly onto the next/previous enabled
13
+ * droppable — a blank (`mask-blank-drop-{id}`), sorted by on-screen position
14
+ * (top-to-bottom, then left-to-right, since blanks sit inline in flowing text rather
15
+ * than a simple list) — followed by the choice board as a fixed last stop (see below
16
+ * for why the board isn't sorted alongside the blanks).
17
+ *
18
+ * Arrow keys are delegated to dnd-kit's own `defaultKeyboardCoordinateGetter`, leaving
19
+ * the existing free-form arrow-key dragging behavior completely unchanged.
20
+ */
21
+ export declare const closestDroppableKeyboardCoordinates: (event: any, { active, context, currentCoordinates }: {
22
+ active: any;
23
+ context: any;
24
+ currentCoordinates: any;
25
+ }) => any;
@@ -0,0 +1,49 @@
1
+ import { KeyboardCode as e, defaultKeyboardCoordinateGetter as t } from "@dnd-kit/core";
2
+ //#region src/keyboard-coordinates.ts
3
+ var n = "drag-in-the-blank-droppable", r = (r, { active: a, context: o, currentCoordinates: s }) => {
4
+ let { code: c } = r, l = c === e.Tab, u = c === e.Down || c === e.Up || c === e.Left || c === e.Right;
5
+ if (!l && !u) return;
6
+ if (u) return t(r, {
7
+ context: o,
8
+ currentCoordinates: s
9
+ });
10
+ r.preventDefault();
11
+ let { droppableRects: d, droppableContainers: f, collisionRect: p } = o;
12
+ if (!d || d.size === 0) return s;
13
+ let m = a?.data?.current, h = m && m.fromChoice === !1 && m.id != null ? `mask-blank-drop-${m.id}` : void 0, g = [], _;
14
+ for (let [e, t] of f) {
15
+ if (t?.disabled || e === h) continue;
16
+ let r = d.get(e);
17
+ if (!r) continue;
18
+ let i = {
19
+ x: r.left + r.width / 2,
20
+ y: r.top + r.height / 2
21
+ }, a = {
22
+ id: e,
23
+ rect: r,
24
+ dropPosition: {
25
+ x: r.left,
26
+ y: r.top + r.height / 2
27
+ },
28
+ center: i
29
+ };
30
+ e === n ? _ = a : g.push(a);
31
+ }
32
+ if (g.length === 0 && !_) return s;
33
+ let v = r.shiftKey;
34
+ g.sort((e, t) => Math.abs(e.center.y - t.center.y) > 10 ? e.center.y - t.center.y : e.center.x - t.center.x), _ && g.push(_);
35
+ let y = p ? {
36
+ x: p.left + p.width / 2,
37
+ y: p.top + p.height / 2
38
+ } : s, b = g.findIndex((e) => y.x >= e.rect.left && y.x <= e.rect.right && y.y >= e.rect.top && y.y <= e.rect.bottom);
39
+ if (b === -1) {
40
+ let e = Infinity;
41
+ for (let t = 0; t < g.length; t++) {
42
+ let n = i(s, g[t].dropPosition);
43
+ n < e && (e = n, b = t);
44
+ }
45
+ }
46
+ return g[v ? (b - 1 + g.length) % g.length : (b + 1) % g.length].dropPosition;
47
+ }, i = (e, t) => Math.sqrt((e.x - t.x) ** 2 + (e.y - t.y) ** 2);
48
+ //#endregion
49
+ export { r as closestDroppableKeyboardCoordinates };
package/dist/mask.js CHANGED
@@ -17,7 +17,7 @@ var s = i("div")(({ theme: e }) => ({
17
17
  if (!(n && l.includes(r))) return t;
18
18
  }, d = (e) => {
19
19
  let t = e.leaves.find((e) => r(e, "marks", []).length);
20
- return t ? t.marks[0] : null;
20
+ return t ? t.marks : null;
21
21
  }, f = (t, n, r, i, a, l) => {
22
22
  if (!n) return null;
23
23
  let p = [];
@@ -37,13 +37,9 @@ var s = i("div")(({ theme: e }) => ({
37
37
  let n = t.text, r = u(a, n);
38
38
  return r ? e + r : e;
39
39
  }, ""), r = d(t);
40
- if (r) {
41
- let t;
42
- for (t in e) if (e[t] === r.type) {
43
- let e = t;
44
- p.push(/* @__PURE__ */ o(e, { children: n }, h));
45
- break;
46
- }
40
+ if (r?.length > 0) {
41
+ let t = r.map((t) => Object.keys(e).find((n) => e[n] === t.type)).filter(Boolean);
42
+ t.length > 0 ? p.push(t.reduceRight((e, t, n) => /* @__PURE__ */ o(t, { children: e }, `${h}-${t}-${n}`), n)) : p.push(n);
47
43
  } else n.length > 0 && p.push(n);
48
44
  } else {
49
45
  let e = f(t, n, r, i, t, l);
@@ -96,4 +92,4 @@ var s = i("div")(({ theme: e }) => ({
96
92
  }
97
93
  };
98
94
  //#endregion
99
- export { m as default };
95
+ export { m as default, f as renderChildren };
@@ -13,4 +13,4 @@ function t() {
13
13
  return i;
14
14
  }
15
15
  //#endregion
16
- export { t as default };
16
+ export { t as clsx, t as default };
@@ -129,4 +129,4 @@ var n = e(), r = t("@pie-lib:mask-markup:serialization"), i = ["span"], a = [
129
129
  };
130
130
  };
131
131
  //#endregion
132
- export { _ as MARK_TAGS, b as deserialize };
132
+ export { _ as MARK_TAGS, b as deserialize, d as parseStyleString, f as reactAttributes };
package/package.json CHANGED
@@ -1,22 +1,26 @@
1
1
  {
2
2
  "name": "@pie-lib/mask-markup",
3
- "version": "3.0.4-next.33",
3
+ "version": "3.0.4-next.35",
4
4
  "description": "",
5
+ "repository": {
6
+ "type": "git",
7
+ "url": "git+https://github.com/pie-framework/pie-elements-ng.git",
8
+ "directory": "packages/lib-react/mask-markup"
9
+ },
5
10
  "dependencies": {
6
11
  "@emotion/react": "^11.14.0",
7
- "@emotion/style": "^0.8.0",
12
+ "@emotion/styled": "^11.14.1",
8
13
  "@mui/icons-material": "^7.3.4",
9
14
  "@mui/material": "^7.3.4",
10
- "@pie-lib/drag": "4.0.3-next.38",
11
- "@pie-lib/editable-html-tip-tap": "2.1.2-next.31",
12
- "@pie-lib/render-ui": "6.1.1-next.38",
15
+ "@pie-lib/drag": "4.0.3-next.39",
16
+ "@pie-lib/editable-html-tip-tap": "2.1.2-next.33",
17
+ "@pie-lib/render-ui": "6.1.1-next.39",
13
18
  "debug": "^4.1.1",
14
19
  "prop-types": "^15.7.2",
15
20
  "to-style": "^1.3.3",
16
21
  "@dnd-kit/core": "^6.3.1",
17
22
  "@pie-element/shared-math-rendering-mathjax": "0.1.1-next.0",
18
23
  "@pie-element/shared-lodash": "0.1.1-next.1",
19
- "@dnd-kit/utilities": "^3.2.2",
20
24
  "clsx": "^2.1.1"
21
25
  },
22
26
  "type": "module",