catchup-library-web 1.11.2 → 1.11.4

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/dist/index.d.mts CHANGED
@@ -1,5 +1,6 @@
1
1
  import * as react_jsx_runtime from 'react/jsx-runtime';
2
2
  import * as react from 'react';
3
+ import { MathfieldElement } from 'mathlive';
3
4
  export { default as i18n } from 'i18next';
4
5
 
5
6
  interface IButtonProps {
@@ -242,6 +243,7 @@ interface IInputGroupProps {
242
243
  useMinHeight?: boolean;
243
244
  disabled?: boolean;
244
245
  limit?: number;
246
+ useMath?: boolean;
245
247
  }
246
248
  interface ILeftTextRightInputGroupProps {
247
249
  type: string;
@@ -253,7 +255,39 @@ interface ILeftTextRightInputGroupProps {
253
255
  errorText?: string;
254
256
  }
255
257
 
256
- declare const InputGroup: ({ type, title, defaultValue, placeholder, value, onFocus, onChange, onClick, onKeyDown, optionList, errorText, multiple, accept, theme, useMinHeight, disabled, limit, }: IInputGroupProps) => react_jsx_runtime.JSX.Element | undefined;
258
+ declare global {
259
+ namespace JSX {
260
+ interface IntrinsicElements {
261
+ "math-field": React.DetailedHTMLProps<React.HTMLAttributes<MathfieldElement>, MathfieldElement> & {
262
+ value?: string;
263
+ disabled?: boolean;
264
+ readonly?: boolean;
265
+ "virtual-keyboard-mode"?: "manual" | "onfocus" | "off";
266
+ "virtual-keyboard-theme"?: "material" | "apple";
267
+ "math-mode-space"?: string;
268
+ "letter-shape-style"?: "tex" | "french" | "iso" | "upright" | "auto";
269
+ "min-font-scale"?: number;
270
+ "max-font-scale"?: number;
271
+ "smart-fence"?: boolean;
272
+ "smart-mode"?: boolean;
273
+ "smart-superscript"?: boolean;
274
+ "inline-shortcut-timeout"?: number;
275
+ "keybinding-mode"?: "default" | "vim" | "emacs";
276
+ "speech-engine"?: "local" | "amazon" | "google";
277
+ "speech-engine-voice"?: string;
278
+ "speech-engine-rate"?: string;
279
+ "read-only"?: boolean;
280
+ "remove-extraneous-parentheses"?: boolean;
281
+ "script-depth"?: number;
282
+ placeholder?: string;
283
+ "default-mode"?: "math" | "text";
284
+ "fonts-directory"?: string;
285
+ "sounds-directory"?: string;
286
+ };
287
+ }
288
+ }
289
+ }
290
+ declare const InputGroup: ({ type, title, defaultValue, placeholder, value, onFocus, onChange, onClick, onKeyDown, optionList, errorText, multiple, accept, theme, useMinHeight, disabled, limit, useMath, }: IInputGroupProps) => react_jsx_runtime.JSX.Element | undefined;
257
291
 
258
292
  declare const LeftTextRightInputGroup: ({ type, title, value, optionList, onChange, disabled, errorText, }: ILeftTextRightInputGroupProps) => react_jsx_runtime.JSX.Element;
259
293
 
package/dist/index.d.ts CHANGED
@@ -1,5 +1,6 @@
1
1
  import * as react_jsx_runtime from 'react/jsx-runtime';
2
2
  import * as react from 'react';
3
+ import { MathfieldElement } from 'mathlive';
3
4
  export { default as i18n } from 'i18next';
4
5
 
5
6
  interface IButtonProps {
@@ -242,6 +243,7 @@ interface IInputGroupProps {
242
243
  useMinHeight?: boolean;
243
244
  disabled?: boolean;
244
245
  limit?: number;
246
+ useMath?: boolean;
245
247
  }
246
248
  interface ILeftTextRightInputGroupProps {
247
249
  type: string;
@@ -253,7 +255,39 @@ interface ILeftTextRightInputGroupProps {
253
255
  errorText?: string;
254
256
  }
255
257
 
256
- declare const InputGroup: ({ type, title, defaultValue, placeholder, value, onFocus, onChange, onClick, onKeyDown, optionList, errorText, multiple, accept, theme, useMinHeight, disabled, limit, }: IInputGroupProps) => react_jsx_runtime.JSX.Element | undefined;
258
+ declare global {
259
+ namespace JSX {
260
+ interface IntrinsicElements {
261
+ "math-field": React.DetailedHTMLProps<React.HTMLAttributes<MathfieldElement>, MathfieldElement> & {
262
+ value?: string;
263
+ disabled?: boolean;
264
+ readonly?: boolean;
265
+ "virtual-keyboard-mode"?: "manual" | "onfocus" | "off";
266
+ "virtual-keyboard-theme"?: "material" | "apple";
267
+ "math-mode-space"?: string;
268
+ "letter-shape-style"?: "tex" | "french" | "iso" | "upright" | "auto";
269
+ "min-font-scale"?: number;
270
+ "max-font-scale"?: number;
271
+ "smart-fence"?: boolean;
272
+ "smart-mode"?: boolean;
273
+ "smart-superscript"?: boolean;
274
+ "inline-shortcut-timeout"?: number;
275
+ "keybinding-mode"?: "default" | "vim" | "emacs";
276
+ "speech-engine"?: "local" | "amazon" | "google";
277
+ "speech-engine-voice"?: string;
278
+ "speech-engine-rate"?: string;
279
+ "read-only"?: boolean;
280
+ "remove-extraneous-parentheses"?: boolean;
281
+ "script-depth"?: number;
282
+ placeholder?: string;
283
+ "default-mode"?: "math" | "text";
284
+ "fonts-directory"?: string;
285
+ "sounds-directory"?: string;
286
+ };
287
+ }
288
+ }
289
+ }
290
+ declare const InputGroup: ({ type, title, defaultValue, placeholder, value, onFocus, onChange, onClick, onKeyDown, optionList, errorText, multiple, accept, theme, useMinHeight, disabled, limit, useMath, }: IInputGroupProps) => react_jsx_runtime.JSX.Element | undefined;
257
291
 
258
292
  declare const LeftTextRightInputGroup: ({ type, title, value, optionList, onChange, disabled, errorText, }: ILeftTextRightInputGroupProps) => react_jsx_runtime.JSX.Element;
259
293
 
package/dist/index.js CHANGED
@@ -3618,9 +3618,12 @@ var InputGroup = ({
3618
3618
  theme,
3619
3619
  useMinHeight,
3620
3620
  disabled,
3621
- limit
3621
+ limit,
3622
+ useMath
3622
3623
  }) => {
3623
3624
  const textAreaRef = (0, import_react10.useRef)(null);
3625
+ const mathFieldRef = (0, import_react10.useRef)(null);
3626
+ const [isMathMode, setIsMathMode] = (0, import_react10.useState)(false);
3624
3627
  (0, import_react10.useEffect)(() => {
3625
3628
  if (!textAreaRef) return;
3626
3629
  if (!textAreaRef.current) return;
@@ -3630,6 +3633,14 @@ var InputGroup = ({
3630
3633
  textAreaRef.current.style.height = `44px`;
3631
3634
  }
3632
3635
  }, [textAreaRef, value]);
3636
+ (0, import_react10.useEffect)(() => {
3637
+ if (!useMath) return;
3638
+ import("mathlive").then(({ MathfieldElement }) => {
3639
+ if (!customElements.get("math-field")) {
3640
+ customElements.define("math-field", MathfieldElement);
3641
+ }
3642
+ });
3643
+ }, [useMath, type, placeholder, title]);
3633
3644
  const retrieveNullableOptionList = () => {
3634
3645
  if (!optionList) return [];
3635
3646
  const currentOptionList = {
@@ -3657,6 +3668,22 @@ var InputGroup = ({
3657
3668
  onChange && onChange(e);
3658
3669
  }
3659
3670
  };
3671
+ const handleMathFieldChange = (event) => {
3672
+ const mathField = event.currentTarget;
3673
+ const syntheticEvent = {
3674
+ target: {
3675
+ value: mathField.value,
3676
+ type: "text"
3677
+ }
3678
+ };
3679
+ onChange && onChange(syntheticEvent);
3680
+ };
3681
+ const handleMathFieldFocus = (event) => {
3682
+ const syntheticEvent = {
3683
+ target: event.currentTarget
3684
+ };
3685
+ onFocus && onFocus(syntheticEvent);
3686
+ };
3660
3687
  const CheckboxInputGroup = () => {
3661
3688
  return /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)(
3662
3689
  "div",
@@ -3812,19 +3839,61 @@ var InputGroup = ({
3812
3839
  return /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)("div", { className: "my-1 relative", children: [
3813
3840
  title ? /* @__PURE__ */ (0, import_jsx_runtime16.jsx)("p", { className: "text-md font-semibold pl-2 py-1 text-catchup-gray-400", children: title }) : null,
3814
3841
  /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
3815
- "input",
3842
+ "div",
3816
3843
  {
3817
- disabled,
3818
- className: `w-full py-2 px-4 border ${errorText ? "border-catchup-red shadow-error placeholder:text-catchup-red placeholder:opacity-80" : "border-catchup-gray-100"} rounded-catchup-large focus:outline-none placeholder-catchup-gray-200 focus:border-catchup-blue-400 ${disabled ? "bg-catchup-lighter-gray" : ""} focus:shadow-input`,
3819
- type,
3820
- defaultValue,
3821
- placeholder: errorText ? errorText : placeholder,
3822
- value,
3823
- onChange,
3824
- onFocus,
3825
- onKeyDown
3844
+ className: `w-full border ${errorText ? "border-catchup-red shadow-error" : "border-catchup-gray-100"} rounded-catchup-large focus-within:border-catchup-blue-400 focus-within:shadow-input ${disabled ? "bg-catchup-lighter-gray" : "bg-white"}`,
3845
+ children: useMath && isMathMode ? /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
3846
+ "math-field",
3847
+ {
3848
+ ref: mathFieldRef,
3849
+ value: value || "",
3850
+ onInput: handleMathFieldChange,
3851
+ onFocus: handleMathFieldFocus,
3852
+ placeholder: errorText ? errorText : placeholder,
3853
+ disabled,
3854
+ "virtual-keyboard-mode": "off",
3855
+ "smart-fence": true,
3856
+ "smart-mode": true,
3857
+ "smart-superscript": true,
3858
+ style: {
3859
+ fontSize: "16px",
3860
+ padding: "8px 16px",
3861
+ border: "none",
3862
+ outline: "none",
3863
+ width: "100%",
3864
+ minHeight: "44px",
3865
+ backgroundColor: "transparent",
3866
+ borderRadius: "16px",
3867
+ fontFamily: "inherit",
3868
+ color: disabled ? "#9ca3af" : "#000000"
3869
+ }
3870
+ }
3871
+ ) : /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
3872
+ "input",
3873
+ {
3874
+ disabled,
3875
+ className: `w-full py-2 px-4 border-none rounded-catchup-large focus:outline-none placeholder-catchup-gray-200 ${disabled ? "bg-catchup-lighter-gray" : ""} ${errorText ? "placeholder:text-catchup-red placeholder:opacity-80" : ""}`,
3876
+ type,
3877
+ defaultValue,
3878
+ placeholder: errorText ? errorText : placeholder,
3879
+ value,
3880
+ onChange,
3881
+ onFocus,
3882
+ onKeyDown
3883
+ }
3884
+ )
3826
3885
  }
3827
- )
3886
+ ),
3887
+ useMath && /* @__PURE__ */ (0, import_jsx_runtime16.jsx)("div", { className: "absolute right-5 -top-2 z-10 bg-catchup-white border border-catchup-gray-100 rounded-md px-2", children: /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
3888
+ "div",
3889
+ {
3890
+ className: "flex flex-row items-center gap-x-2 cursor-pointer text-md transition-all duration-300 text-catchup-gray-300",
3891
+ onClick: () => {
3892
+ setIsMathMode(!isMathMode);
3893
+ },
3894
+ children: /* @__PURE__ */ (0, import_jsx_runtime16.jsx)("div", { className: "flex flex-row items-center gap-x-1", children: /* @__PURE__ */ (0, import_jsx_runtime16.jsx)("p", { className: "font-bold", children: isMathMode ? i18n_default.t("text_mode") : i18n_default.t("math_mode") }) })
3895
+ }
3896
+ ) })
3828
3897
  ] });
3829
3898
  };
3830
3899
  const RenderMainContent = () => {
package/dist/index.mjs CHANGED
@@ -3399,7 +3399,7 @@ import { InlineMath as InlineMath2 } from "react-katex";
3399
3399
 
3400
3400
  // src/components/groups/InputGroup.tsx
3401
3401
  import Select from "react-select";
3402
- import { useEffect as useEffect2, useRef } from "react";
3402
+ import { useEffect as useEffect2, useRef, useState as useState10 } from "react";
3403
3403
  import { jsx as jsx16, jsxs as jsxs9 } from "react/jsx-runtime";
3404
3404
  var InputGroup = ({
3405
3405
  type,
@@ -3418,9 +3418,12 @@ var InputGroup = ({
3418
3418
  theme,
3419
3419
  useMinHeight,
3420
3420
  disabled,
3421
- limit
3421
+ limit,
3422
+ useMath
3422
3423
  }) => {
3423
3424
  const textAreaRef = useRef(null);
3425
+ const mathFieldRef = useRef(null);
3426
+ const [isMathMode, setIsMathMode] = useState10(false);
3424
3427
  useEffect2(() => {
3425
3428
  if (!textAreaRef) return;
3426
3429
  if (!textAreaRef.current) return;
@@ -3430,6 +3433,14 @@ var InputGroup = ({
3430
3433
  textAreaRef.current.style.height = `44px`;
3431
3434
  }
3432
3435
  }, [textAreaRef, value]);
3436
+ useEffect2(() => {
3437
+ if (!useMath) return;
3438
+ import("mathlive").then(({ MathfieldElement }) => {
3439
+ if (!customElements.get("math-field")) {
3440
+ customElements.define("math-field", MathfieldElement);
3441
+ }
3442
+ });
3443
+ }, [useMath, type, placeholder, title]);
3433
3444
  const retrieveNullableOptionList = () => {
3434
3445
  if (!optionList) return [];
3435
3446
  const currentOptionList = {
@@ -3457,6 +3468,22 @@ var InputGroup = ({
3457
3468
  onChange && onChange(e);
3458
3469
  }
3459
3470
  };
3471
+ const handleMathFieldChange = (event) => {
3472
+ const mathField = event.currentTarget;
3473
+ const syntheticEvent = {
3474
+ target: {
3475
+ value: mathField.value,
3476
+ type: "text"
3477
+ }
3478
+ };
3479
+ onChange && onChange(syntheticEvent);
3480
+ };
3481
+ const handleMathFieldFocus = (event) => {
3482
+ const syntheticEvent = {
3483
+ target: event.currentTarget
3484
+ };
3485
+ onFocus && onFocus(syntheticEvent);
3486
+ };
3460
3487
  const CheckboxInputGroup = () => {
3461
3488
  return /* @__PURE__ */ jsxs9(
3462
3489
  "div",
@@ -3612,19 +3639,61 @@ var InputGroup = ({
3612
3639
  return /* @__PURE__ */ jsxs9("div", { className: "my-1 relative", children: [
3613
3640
  title ? /* @__PURE__ */ jsx16("p", { className: "text-md font-semibold pl-2 py-1 text-catchup-gray-400", children: title }) : null,
3614
3641
  /* @__PURE__ */ jsx16(
3615
- "input",
3642
+ "div",
3616
3643
  {
3617
- disabled,
3618
- className: `w-full py-2 px-4 border ${errorText ? "border-catchup-red shadow-error placeholder:text-catchup-red placeholder:opacity-80" : "border-catchup-gray-100"} rounded-catchup-large focus:outline-none placeholder-catchup-gray-200 focus:border-catchup-blue-400 ${disabled ? "bg-catchup-lighter-gray" : ""} focus:shadow-input`,
3619
- type,
3620
- defaultValue,
3621
- placeholder: errorText ? errorText : placeholder,
3622
- value,
3623
- onChange,
3624
- onFocus,
3625
- onKeyDown
3644
+ className: `w-full border ${errorText ? "border-catchup-red shadow-error" : "border-catchup-gray-100"} rounded-catchup-large focus-within:border-catchup-blue-400 focus-within:shadow-input ${disabled ? "bg-catchup-lighter-gray" : "bg-white"}`,
3645
+ children: useMath && isMathMode ? /* @__PURE__ */ jsx16(
3646
+ "math-field",
3647
+ {
3648
+ ref: mathFieldRef,
3649
+ value: value || "",
3650
+ onInput: handleMathFieldChange,
3651
+ onFocus: handleMathFieldFocus,
3652
+ placeholder: errorText ? errorText : placeholder,
3653
+ disabled,
3654
+ "virtual-keyboard-mode": "off",
3655
+ "smart-fence": true,
3656
+ "smart-mode": true,
3657
+ "smart-superscript": true,
3658
+ style: {
3659
+ fontSize: "16px",
3660
+ padding: "8px 16px",
3661
+ border: "none",
3662
+ outline: "none",
3663
+ width: "100%",
3664
+ minHeight: "44px",
3665
+ backgroundColor: "transparent",
3666
+ borderRadius: "16px",
3667
+ fontFamily: "inherit",
3668
+ color: disabled ? "#9ca3af" : "#000000"
3669
+ }
3670
+ }
3671
+ ) : /* @__PURE__ */ jsx16(
3672
+ "input",
3673
+ {
3674
+ disabled,
3675
+ className: `w-full py-2 px-4 border-none rounded-catchup-large focus:outline-none placeholder-catchup-gray-200 ${disabled ? "bg-catchup-lighter-gray" : ""} ${errorText ? "placeholder:text-catchup-red placeholder:opacity-80" : ""}`,
3676
+ type,
3677
+ defaultValue,
3678
+ placeholder: errorText ? errorText : placeholder,
3679
+ value,
3680
+ onChange,
3681
+ onFocus,
3682
+ onKeyDown
3683
+ }
3684
+ )
3626
3685
  }
3627
- )
3686
+ ),
3687
+ useMath && /* @__PURE__ */ jsx16("div", { className: "absolute right-5 -top-2 z-10 bg-catchup-white border border-catchup-gray-100 rounded-md px-2", children: /* @__PURE__ */ jsx16(
3688
+ "div",
3689
+ {
3690
+ className: "flex flex-row items-center gap-x-2 cursor-pointer text-md transition-all duration-300 text-catchup-gray-300",
3691
+ onClick: () => {
3692
+ setIsMathMode(!isMathMode);
3693
+ },
3694
+ children: /* @__PURE__ */ jsx16("div", { className: "flex flex-row items-center gap-x-1", children: /* @__PURE__ */ jsx16("p", { className: "font-bold", children: isMathMode ? i18n_default.t("text_mode") : i18n_default.t("math_mode") }) })
3695
+ }
3696
+ ) })
3628
3697
  ] });
3629
3698
  };
3630
3699
  const RenderMainContent = () => {
@@ -3650,7 +3719,7 @@ var InputGroup_default = InputGroup;
3650
3719
 
3651
3720
  // src/components/activities/material-content/DropdownActivityMaterialContent.tsx
3652
3721
  import { useEffect as useEffect4 } from "react";
3653
- import { useState as useState12 } from "react";
3722
+ import { useState as useState13 } from "react";
3654
3723
 
3655
3724
  // src/utilization/AppUtilization.ts
3656
3725
  var colors = [
@@ -3750,10 +3819,10 @@ var getColorByIndex = (index) => {
3750
3819
  };
3751
3820
 
3752
3821
  // src/components/dropdowns/MediaDropdown.tsx
3753
- import { useState as useState10 } from "react";
3822
+ import { useState as useState11 } from "react";
3754
3823
  import { jsx as jsx17, jsxs as jsxs10 } from "react/jsx-runtime";
3755
3824
  var MediaDropdown = ({ id, answer, optionList }) => {
3756
- const [showDropdown, setShowDropdown] = useState10(false);
3825
+ const [showDropdown, setShowDropdown] = useState11(false);
3757
3826
  return /* @__PURE__ */ jsxs10(
3758
3827
  "div",
3759
3828
  {
@@ -3798,7 +3867,7 @@ var MediaDropdown = ({ id, answer, optionList }) => {
3798
3867
  var MediaDropdown_default = MediaDropdown;
3799
3868
 
3800
3869
  // src/components/activities/material-content/ShowMaterialMediaByContentType.tsx
3801
- import { useEffect as useEffect3, useRef as useRef2, useState as useState11 } from "react";
3870
+ import { useEffect as useEffect3, useRef as useRef2, useState as useState12 } from "react";
3802
3871
  import Modal3 from "react-modal";
3803
3872
  import { jsx as jsx18, jsxs as jsxs11 } from "react/jsx-runtime";
3804
3873
  var ShowMaterialMediaByContentType = ({
@@ -3807,10 +3876,10 @@ var ShowMaterialMediaByContentType = ({
3807
3876
  src,
3808
3877
  canFullScreen
3809
3878
  }) => {
3810
- const [showFullScreen, setShowFullScreen] = useState11(false);
3811
- const [selectedFullScreenItem, setSelectedFullScreenItem] = useState11(null);
3812
- const [isLoaded, setIsLoaded] = useState11(false);
3813
- const [isFullHeight, setIsFullHeight] = useState11(false);
3879
+ const [showFullScreen, setShowFullScreen] = useState12(false);
3880
+ const [selectedFullScreenItem, setSelectedFullScreenItem] = useState12(null);
3881
+ const [isLoaded, setIsLoaded] = useState12(false);
3882
+ const [isFullHeight, setIsFullHeight] = useState12(false);
3814
3883
  const imageRef = useRef2(null);
3815
3884
  useEffect3(() => {
3816
3885
  setIsLoaded(false);
@@ -3965,7 +4034,7 @@ var DropdownActivityMaterialContent = ({
3965
4034
  isPreview,
3966
4035
  showCorrectAnswer
3967
4036
  }) => {
3968
- const [updated, setUpdated] = useState12(false);
4037
+ const [updated, setUpdated] = useState13(false);
3969
4038
  useEffect4(() => {
3970
4039
  if (!showCorrectAnswer) return;
3971
4040
  const foundAnswer = answer.data.find(
@@ -4109,7 +4178,7 @@ var DropdownActivityMaterialContent = ({
4109
4178
  var DropdownActivityMaterialContent_default = DropdownActivityMaterialContent;
4110
4179
 
4111
4180
  // src/components/activities/DropdownActivityContent.tsx
4112
- import { useState as useState13, useEffect as useEffect5 } from "react";
4181
+ import { useState as useState14, useEffect as useEffect5 } from "react";
4113
4182
  import { jsx as jsx20, jsxs as jsxs13 } from "react/jsx-runtime";
4114
4183
  var DropdownActivityContent = ({
4115
4184
  answer,
@@ -4123,7 +4192,7 @@ var DropdownActivityContent = ({
4123
4192
  const contentMap = parseContentMapFromData(data);
4124
4193
  const dropdownBodyMap = parseBodyMapFromData(data, "DROPDOWN");
4125
4194
  const dropdownMaterialMap = parseMaterialMapFromData(data, "DROPDOWN");
4126
- const [currentAnswerMap, setCurrentAnswerMap] = useState13(() => {
4195
+ const [currentAnswerMap, setCurrentAnswerMap] = useState14(() => {
4127
4196
  return retrieveCurrentAnswerMap();
4128
4197
  });
4129
4198
  function retrieveCurrentAnswerMap() {
@@ -4183,7 +4252,7 @@ var DropdownActivityContent_default = DropdownActivityContent;
4183
4252
 
4184
4253
  // src/components/activities/material-content/FillInTheBlanksActivityMaterialContent.tsx
4185
4254
  import { InlineMath as InlineMath3 } from "react-katex";
4186
- import { useState as useState14 } from "react";
4255
+ import { useState as useState15 } from "react";
4187
4256
  import { useEffect as useEffect6 } from "react";
4188
4257
  import { useDrop as useDrop2 } from "react-dnd";
4189
4258
 
@@ -4270,9 +4339,9 @@ var FillInTheBlanksActivityMaterialContent = ({
4270
4339
  isPreview,
4271
4340
  showCorrectAnswer
4272
4341
  }) => {
4273
- const [shuffleOptionList, setShuffleOptionList] = useState14([]);
4274
- const [selectedOption, setSelectedOption] = useState14(null);
4275
- const [pasteOptionIndex, setPasteOptionIndex] = useState14(null);
4342
+ const [shuffleOptionList, setShuffleOptionList] = useState15([]);
4343
+ const [selectedOption, setSelectedOption] = useState15(null);
4344
+ const [pasteOptionIndex, setPasteOptionIndex] = useState15(null);
4276
4345
  const [{ isOver, canDrop }, drop] = useDrop2({
4277
4346
  accept: "FILL_IN_THE_BLANKS",
4278
4347
  drop: () => {
@@ -4463,7 +4532,7 @@ var FillInTheBlanksActivityMaterialContent = ({
4463
4532
  var FillInTheBlanksActivityMaterialContent_default = FillInTheBlanksActivityMaterialContent;
4464
4533
 
4465
4534
  // src/components/activities/FillInTheBlanksActivityContent.tsx
4466
- import { useState as useState15, useEffect as useEffect7 } from "react";
4535
+ import { useState as useState16, useEffect as useEffect7 } from "react";
4467
4536
  import { jsx as jsx24, jsxs as jsxs15 } from "react/jsx-runtime";
4468
4537
  var FillInTheBlanksActivityContent = ({
4469
4538
  answer,
@@ -4484,7 +4553,7 @@ var FillInTheBlanksActivityContent = ({
4484
4553
  "FILL_IN_THE_BLANKS"
4485
4554
  );
4486
4555
  const fillInTheBlanksIncorrectList = data.fillInTheBlanksIncorrectList ? JSON.parse(data.fillInTheBlanksIncorrectList) : [];
4487
- const [currentAnswerMap, setCurrentAnswerMap] = useState15(() => {
4556
+ const [currentAnswerMap, setCurrentAnswerMap] = useState16(() => {
4488
4557
  return retrieveCurrentAnswerMap();
4489
4558
  });
4490
4559
  function retrieveCurrentAnswerMap() {
@@ -4562,18 +4631,18 @@ var FillInTheBlanksActivityContent = ({
4562
4631
  var FillInTheBlanksActivityContent_default = FillInTheBlanksActivityContent;
4563
4632
 
4564
4633
  // src/components/activities/material-content/GroupingActivityMaterialContent.tsx
4565
- import { useEffect as useEffect9, useRef as useRef4, useState as useState17 } from "react";
4634
+ import { useEffect as useEffect9, useRef as useRef4, useState as useState18 } from "react";
4566
4635
  import { useDrop as useDrop3 } from "react-dnd";
4567
4636
  import { InlineMath as InlineMath4 } from "react-katex";
4568
4637
 
4569
4638
  // src/hooks/useScreenSize.ts
4570
- import { useState as useState16, useEffect as useEffect8 } from "react";
4639
+ import { useState as useState17, useEffect as useEffect8 } from "react";
4571
4640
  var useScreenSize = () => {
4572
- const [containerSize, setContainerSize] = useState16({
4641
+ const [containerSize, setContainerSize] = useState17({
4573
4642
  width: 0,
4574
4643
  height: 0
4575
4644
  });
4576
- const [screenSize, setScreenSize] = useState16({
4645
+ const [screenSize, setScreenSize] = useState17({
4577
4646
  width: window.innerWidth,
4578
4647
  height: window.innerHeight
4579
4648
  });
@@ -4613,10 +4682,10 @@ var GroupingActivityMaterialContent = ({
4613
4682
  isPreview,
4614
4683
  showCorrectAnswer
4615
4684
  }) => {
4616
- const [selectedValue, setSelectedValue] = useState17(null);
4617
- const [selectedTargetKey, setSelectedTargetKey] = useState17(null);
4618
- const [isShuffled, setIsShuffled] = useState17(false);
4619
- const [shuffledMaterialList, setShuffledMaterialList] = useState17([]);
4685
+ const [selectedValue, setSelectedValue] = useState18(null);
4686
+ const [selectedTargetKey, setSelectedTargetKey] = useState18(null);
4687
+ const [isShuffled, setIsShuffled] = useState18(false);
4688
+ const [shuffledMaterialList, setShuffledMaterialList] = useState18([]);
4620
4689
  const { screenSize, containerSize } = useScreenSize_default();
4621
4690
  const [{ isOver, canDrop }, drop] = useDrop3({
4622
4691
  accept: "GROUPING",
@@ -4629,7 +4698,7 @@ var GroupingActivityMaterialContent = ({
4629
4698
  });
4630
4699
  const ref = useRef4(null);
4631
4700
  const itemsRef = useRef4(null);
4632
- const [maxWidth, setMaxWidth] = useState17(0);
4701
+ const [maxWidth, setMaxWidth] = useState18(0);
4633
4702
  useEffect9(() => {
4634
4703
  if (!ref) return;
4635
4704
  if (!ref.current) return;
@@ -4931,7 +5000,7 @@ var GroupingActivityContent = ({
4931
5000
  var GroupingActivityContent_default = GroupingActivityContent;
4932
5001
 
4933
5002
  // src/components/activities/material-content/MatchingActivityMaterialContent.tsx
4934
- import { useEffect as useEffect10, useRef as useRef5, useState as useState18 } from "react";
5003
+ import { useEffect as useEffect10, useRef as useRef5, useState as useState19 } from "react";
4935
5004
  import { useDrop as useDrop4 } from "react-dnd";
4936
5005
  import { InlineMath as InlineMath5 } from "react-katex";
4937
5006
  import { Fragment as Fragment3, jsx as jsx27, jsxs as jsxs18 } from "react/jsx-runtime";
@@ -4945,10 +5014,10 @@ var MatchingActivityMaterialContent = ({
4945
5014
  isPreview,
4946
5015
  showCorrectAnswer
4947
5016
  }) => {
4948
- const [selectedValue, setSelectedValue] = useState18(null);
4949
- const [selectedTargetKey, setSelectedTargetKey] = useState18(null);
4950
- const [isShuffled, setIsShuffled] = useState18(false);
4951
- const [shuffledMaterialList, setShuffledMaterialList] = useState18([]);
5017
+ const [selectedValue, setSelectedValue] = useState19(null);
5018
+ const [selectedTargetKey, setSelectedTargetKey] = useState19(null);
5019
+ const [isShuffled, setIsShuffled] = useState19(false);
5020
+ const [shuffledMaterialList, setShuffledMaterialList] = useState19([]);
4952
5021
  const [{ isOver, canDrop }, drop] = useDrop4({
4953
5022
  accept: "MATCHING",
4954
5023
  drop: () => {
@@ -5634,7 +5703,7 @@ var OpenEndedActivityContent = ({
5634
5703
  var OpenEndedActivityContent_default = OpenEndedActivityContent;
5635
5704
 
5636
5705
  // src/components/activities/material-content/OrderingActivityMaterialContent.tsx
5637
- import { useEffect as useEffect11, useState as useState19 } from "react";
5706
+ import { useEffect as useEffect11, useState as useState20 } from "react";
5638
5707
  import { useDrop as useDrop6 } from "react-dnd";
5639
5708
  import { InlineMath as InlineMath8 } from "react-katex";
5640
5709
 
@@ -5703,10 +5772,10 @@ var OrderingActivityMaterialContent = ({
5703
5772
  isPreview,
5704
5773
  showCorrectAnswer
5705
5774
  }) => {
5706
- const [selectedTargetKey, setSelectedTargetKey] = useState19(null);
5707
- const [selectedKey, setSelectedKey] = useState19(null);
5775
+ const [selectedTargetKey, setSelectedTargetKey] = useState20(null);
5776
+ const [selectedKey, setSelectedKey] = useState20(null);
5708
5777
  const { screenSize } = useScreenSize_default();
5709
- const [view, setView] = useState19("PC");
5778
+ const [view, setView] = useState20("PC");
5710
5779
  const [{ isOver, canDrop }, drop] = useDrop6({
5711
5780
  accept: "ORDERING",
5712
5781
  drop: () => {
@@ -5901,7 +5970,7 @@ var OrderingActivityContent = ({
5901
5970
  var OrderingActivityContent_default = OrderingActivityContent;
5902
5971
 
5903
5972
  // src/components/activities/material-content/TrueFalseActivityMaterialContent.tsx
5904
- import { useEffect as useEffect12, useState as useState20 } from "react";
5973
+ import { useEffect as useEffect12, useState as useState21 } from "react";
5905
5974
  import { InlineMath as InlineMath9 } from "react-katex";
5906
5975
  import { Fragment as Fragment8, jsx as jsx38, jsxs as jsxs28 } from "react/jsx-runtime";
5907
5976
  var TrueFalseActivityMaterialContent = ({
@@ -5915,7 +5984,7 @@ var TrueFalseActivityMaterialContent = ({
5915
5984
  showCorrectAnswer
5916
5985
  }) => {
5917
5986
  const { screenSize } = useScreenSize_default();
5918
- const [shuffleOptionList, setShuffleOptionList] = useState20([]);
5987
+ const [shuffleOptionList, setShuffleOptionList] = useState21([]);
5919
5988
  useEffect12(() => {
5920
5989
  const optionList = [];
5921
5990
  optionList.push(...materialMap.trueList);
@@ -6234,7 +6303,7 @@ var ActivityEvaluationRubricContent = ({
6234
6303
  var ActivityEvaluationRubricContent_default = ActivityEvaluationRubricContent;
6235
6304
 
6236
6305
  // src/components/activities/ActivityPreviewByData.tsx
6237
- import { useEffect as useEffect13, useState as useState21 } from "react";
6306
+ import { useEffect as useEffect13, useState as useState22 } from "react";
6238
6307
 
6239
6308
  // src/components/boxes/SelectionBox.tsx
6240
6309
  import { jsx as jsx42, jsxs as jsxs32 } from "react/jsx-runtime";
@@ -6286,9 +6355,9 @@ var ActivityPreviewByData = ({
6286
6355
  showTaxonomy,
6287
6356
  isFullScreen
6288
6357
  }) => {
6289
- const [key, setKey] = useState21((/* @__PURE__ */ new Date()).getTime());
6290
- const [selectedType, setSelectedType] = useState21(null);
6291
- const [optionList, setOptionList] = useState21([]);
6358
+ const [key, setKey] = useState22((/* @__PURE__ */ new Date()).getTime());
6359
+ const [selectedType, setSelectedType] = useState22(null);
6360
+ const [optionList, setOptionList] = useState22([]);
6292
6361
  useEffect13(() => {
6293
6362
  if (!data) return;
6294
6363
  setKey((/* @__PURE__ */ new Date()).getTime());
@@ -6513,7 +6582,7 @@ var ActivityPreviewByData = ({
6513
6582
  var ActivityPreviewByData_default = ActivityPreviewByData;
6514
6583
 
6515
6584
  // src/components/activities/ActivityPreviewByAnswerData.tsx
6516
- import { useEffect as useEffect14, useState as useState22 } from "react";
6585
+ import { useEffect as useEffect14, useState as useState23 } from "react";
6517
6586
  import { jsx as jsx44, jsxs as jsxs34 } from "react/jsx-runtime";
6518
6587
  var ActivityPreviewByAnswerData = ({
6519
6588
  data,
@@ -6528,10 +6597,10 @@ var ActivityPreviewByAnswerData = ({
6528
6597
  showCorrectAnswer = false
6529
6598
  }) => {
6530
6599
  var _a;
6531
- const [key, setKey] = useState22((/* @__PURE__ */ new Date()).getTime());
6532
- const [selectedType, setSelectedType] = useState22(null);
6533
- const [optionList, setOptionList] = useState22([]);
6534
- const [answer, setAnswer] = useState22({ data: [] });
6600
+ const [key, setKey] = useState23((/* @__PURE__ */ new Date()).getTime());
6601
+ const [selectedType, setSelectedType] = useState23(null);
6602
+ const [optionList, setOptionList] = useState23([]);
6603
+ const [answer, setAnswer] = useState23({ data: [] });
6535
6604
  useEffect14(() => {
6536
6605
  if (!data) return;
6537
6606
  setKey((/* @__PURE__ */ new Date()).getTime());
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "catchup-library-web",
3
- "version": "1.11.2",
3
+ "version": "1.11.4",
4
4
  "description": "",
5
5
  "main": "dist/index.js",
6
6
  "scripts": {
@@ -12,6 +12,7 @@
12
12
  "license": "ISC",
13
13
  "dependencies": {
14
14
  "i18next": "^24.2.2",
15
+ "mathlive": "^0.105.3",
15
16
  "react": "^18.3.0",
16
17
  "react-dnd": "^16.0.1",
17
18
  "react-dom": "^18.3.0",
@@ -1,9 +1,46 @@
1
1
  import Select from "react-select";
2
2
  import i18n from "../../language/i18n";
3
- import { useEffect, useRef } from "react";
3
+ import { useEffect, useRef, useState } from "react";
4
4
  import { IInputGroupProps } from "../../properties/GroupProperties";
5
5
  import BaseImage from "../images/BaseImage";
6
6
  import { IOptionProps } from "../../properties/CommonProperties";
7
+ import { MathfieldElement } from "mathlive";
8
+
9
+ declare global {
10
+ namespace JSX {
11
+ interface IntrinsicElements {
12
+ "math-field": React.DetailedHTMLProps<
13
+ React.HTMLAttributes<MathfieldElement>,
14
+ MathfieldElement
15
+ > & {
16
+ value?: string;
17
+ disabled?: boolean;
18
+ readonly?: boolean;
19
+ "virtual-keyboard-mode"?: "manual" | "onfocus" | "off";
20
+ "virtual-keyboard-theme"?: "material" | "apple";
21
+ "math-mode-space"?: string;
22
+ "letter-shape-style"?: "tex" | "french" | "iso" | "upright" | "auto";
23
+ "min-font-scale"?: number;
24
+ "max-font-scale"?: number;
25
+ "smart-fence"?: boolean;
26
+ "smart-mode"?: boolean;
27
+ "smart-superscript"?: boolean;
28
+ "inline-shortcut-timeout"?: number;
29
+ "keybinding-mode"?: "default" | "vim" | "emacs";
30
+ "speech-engine"?: "local" | "amazon" | "google";
31
+ "speech-engine-voice"?: string;
32
+ "speech-engine-rate"?: string;
33
+ "read-only"?: boolean;
34
+ "remove-extraneous-parentheses"?: boolean;
35
+ "script-depth"?: number;
36
+ placeholder?: string;
37
+ "default-mode"?: "math" | "text";
38
+ "fonts-directory"?: string;
39
+ "sounds-directory"?: string;
40
+ };
41
+ }
42
+ }
43
+ }
7
44
 
8
45
  const InputGroup = ({
9
46
  type,
@@ -23,8 +60,11 @@ const InputGroup = ({
23
60
  useMinHeight,
24
61
  disabled,
25
62
  limit,
63
+ useMath,
26
64
  }: IInputGroupProps) => {
27
65
  const textAreaRef = useRef<HTMLTextAreaElement>(null);
66
+ const mathFieldRef = useRef<MathfieldElement>(null);
67
+ const [isMathMode, setIsMathMode] = useState<boolean>(false);
28
68
 
29
69
  useEffect(() => {
30
70
  if (!textAreaRef) return;
@@ -36,6 +76,15 @@ const InputGroup = ({
36
76
  }
37
77
  }, [textAreaRef, value]);
38
78
 
79
+ useEffect(() => {
80
+ if (!useMath) return;
81
+ import("mathlive").then(({ MathfieldElement }) => {
82
+ if (!customElements.get("math-field")) {
83
+ customElements.define("math-field", MathfieldElement);
84
+ }
85
+ });
86
+ }, [useMath, type, placeholder, title]);
87
+
39
88
  const retrieveNullableOptionList = () => {
40
89
  if (!optionList) return [];
41
90
  const currentOptionList = {
@@ -66,6 +115,24 @@ const InputGroup = ({
66
115
  }
67
116
  };
68
117
 
118
+ const handleMathFieldChange = (event: React.FormEvent<MathfieldElement>) => {
119
+ const mathField = event.currentTarget;
120
+ const syntheticEvent = {
121
+ target: {
122
+ value: mathField.value,
123
+ type: "text",
124
+ },
125
+ };
126
+ onChange && onChange(syntheticEvent);
127
+ };
128
+
129
+ const handleMathFieldFocus = (event: React.FocusEvent<MathfieldElement>) => {
130
+ const syntheticEvent = {
131
+ target: event.currentTarget,
132
+ };
133
+ onFocus && onFocus(syntheticEvent);
134
+ };
135
+
69
136
  const CheckboxInputGroup = () => {
70
137
  return (
71
138
  <div
@@ -277,31 +344,78 @@ const InputGroup = ({
277
344
  {title}
278
345
  </p>
279
346
  ) : null}
280
- <input
281
- disabled={disabled}
282
- className={`w-full py-2 px-4 border ${
347
+
348
+ <div
349
+ className={`w-full border ${
283
350
  errorText
284
- ? "border-catchup-red shadow-error placeholder:text-catchup-red placeholder:opacity-80"
351
+ ? "border-catchup-red shadow-error"
285
352
  : "border-catchup-gray-100"
286
- } rounded-catchup-large focus:outline-none placeholder-catchup-gray-200 focus:border-catchup-blue-400 ${
287
- disabled ? "bg-catchup-lighter-gray" : ""
288
- } focus:shadow-input`}
289
- type={type}
290
- defaultValue={defaultValue}
291
- placeholder={errorText ? errorText : placeholder}
292
- value={value}
293
- onChange={onChange}
294
- onFocus={onFocus}
295
- onKeyDown={onKeyDown}
296
- />
297
-
298
- {/* <div
299
- className={`${
300
- title ? "absolute top-0 right-0" : "absolute top-3 left-5"
353
+ } rounded-catchup-large focus-within:border-catchup-blue-400 focus-within:shadow-input ${
354
+ disabled ? "bg-catchup-lighter-gray" : "bg-white"
301
355
  }`}
302
356
  >
303
- <p className="italic text-catchup-red opacity-70">{errorText}</p>
304
- </div> */}
357
+ {useMath && isMathMode ? (
358
+ <math-field
359
+ ref={mathFieldRef}
360
+ value={value || ""}
361
+ onInput={handleMathFieldChange}
362
+ onFocus={handleMathFieldFocus}
363
+ placeholder={errorText ? errorText : placeholder}
364
+ disabled={disabled}
365
+ virtual-keyboard-mode="off"
366
+ smart-fence={true}
367
+ smart-mode={true}
368
+ smart-superscript={true}
369
+ style={{
370
+ fontSize: "16px",
371
+ padding: "8px 16px",
372
+ border: "none",
373
+ outline: "none",
374
+ width: "100%",
375
+ minHeight: "44px",
376
+ backgroundColor: "transparent",
377
+ borderRadius: "16px",
378
+ fontFamily: "inherit",
379
+ color: disabled ? "#9ca3af" : "#000000",
380
+ }}
381
+ />
382
+ ) : (
383
+ <input
384
+ disabled={disabled}
385
+ className={`w-full py-2 px-4 border-none rounded-catchup-large focus:outline-none placeholder-catchup-gray-200 ${
386
+ disabled ? "bg-catchup-lighter-gray" : ""
387
+ } ${
388
+ errorText
389
+ ? "placeholder:text-catchup-red placeholder:opacity-80"
390
+ : ""
391
+ }`}
392
+ type={type}
393
+ defaultValue={defaultValue}
394
+ placeholder={errorText ? errorText : placeholder}
395
+ value={value}
396
+ onChange={onChange}
397
+ onFocus={onFocus}
398
+ onKeyDown={onKeyDown}
399
+ />
400
+ )}
401
+ </div>
402
+
403
+ {useMath && (
404
+ <div className="absolute right-5 -top-2 z-10 bg-catchup-white border border-catchup-gray-100 rounded-md px-2">
405
+ <div
406
+ className="flex flex-row items-center gap-x-2 cursor-pointer text-md transition-all duration-300 text-catchup-gray-300"
407
+ onClick={() => {
408
+ setIsMathMode(!isMathMode);
409
+ }}
410
+ >
411
+ <div className="flex flex-row items-center gap-x-1">
412
+ <p className="font-bold">
413
+ {isMathMode ? i18n.t("text_mode") : i18n.t("math_mode")}
414
+ </p>
415
+ </div>
416
+ </div>
417
+ </div>
418
+ )}
305
419
  </div>
306
420
  );
307
421
  };
@@ -16,6 +16,7 @@ export interface IInputGroupProps {
16
16
  useMinHeight?: boolean;
17
17
  disabled?: boolean;
18
18
  limit?: number;
19
+ useMath?: boolean;
19
20
  }
20
21
 
21
22
  export interface ILeftTextRightInputGroupProps {