eat-js-sdk 2.0.41 → 2.0.43

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.
@@ -5114,6 +5114,15 @@ const CATEGORISE = {
5114
5114
  CONTAINER_WORD_BIN_ID: "container-word-bin",
5115
5115
  DASH: "@eat-dash@"
5116
5116
  };
5117
+ const DROPDOWN_POSITION = {
5118
+ MIN_WIDTH: 240,
5119
+ MAX_WIDTH: 500,
5120
+ VIEWPORT_PADDING: 16
5121
+ };
5122
+ const DROPDOWN_INTERACTION = {
5123
+ KEY_PRESS_TIMEOUT: 1e3,
5124
+ PAGE_NAVIGATION_STEP: 10
5125
+ };
5117
5126
  const INTERACTION_TYPE_MAP = {
5118
5127
  [INTERACTION_TYPES.MCQ]: "mcq",
5119
5128
  [INTERACTION_TYPES.CATEGORISE]: "categorise",
@@ -7870,6 +7879,7 @@ const DEFAULT_TWO_COLUMN_ORDER = [
7870
7879
  "divider",
7871
7880
  "feedback",
7872
7881
  "interaction",
7882
+ "divider-bottom",
7873
7883
  "desktop-column"
7874
7884
  ];
7875
7885
  const DEFAULT_SINGLE_COLUMN_ORDER = [
@@ -7880,6 +7890,7 @@ const DEFAULT_SINGLE_COLUMN_ORDER = [
7880
7890
  "prompt",
7881
7891
  "divider",
7882
7892
  "feedback",
7893
+ "divider-bottom",
7883
7894
  "interaction"
7884
7895
  ];
7885
7896
  const FEEDBACK_LAST_TWO_COLUMN_ORDER = [
@@ -7893,6 +7904,7 @@ const FEEDBACK_LAST_TWO_COLUMN_ORDER = [
7893
7904
  "stimulus-mobile-text-second",
7894
7905
  "divider",
7895
7906
  "interaction",
7907
+ "divider-bottom",
7896
7908
  "feedback",
7897
7909
  "desktop-column"
7898
7910
  ];
@@ -7904,6 +7916,7 @@ const FEEDBACK_LAST_SINGLE_COLUMN_ORDER = [
7904
7916
  "prompt",
7905
7917
  "divider",
7906
7918
  "interaction",
7919
+ "divider-bottom",
7907
7920
  "feedback"
7908
7921
  ];
7909
7922
  const FEEDBACK_LAST_INTERACTIONS = [INTERACTION_TYPES.TYPEIN, INTERACTION_TYPES.DROPDOWN];
@@ -7963,6 +7976,7 @@ const twoColumnTemplate = {
7963
7976
  },
7964
7977
  { name: "divider", component: "divider", condition: context.hasDivider },
7965
7978
  { name: "interaction", component: "slot", slot: "interaction" },
7979
+ { name: "divider-bottom", component: "divider-bottom", condition: context.hasDividerBottom },
7966
7980
  { name: "feedback", component: "slot", slot: "feedback" },
7967
7981
  {
7968
7982
  name: "desktop-column",
@@ -8005,6 +8019,7 @@ const singleColumnTemplate = {
8005
8019
  { name: "prompt", component: "prompt" },
8006
8020
  { name: "divider", component: "divider", condition: context.hasDivider },
8007
8021
  { name: "interaction", component: "slot", slot: "interaction" },
8022
+ { name: "divider-bottom", component: "divider-bottom", condition: context.hasDividerBottom },
8008
8023
  { name: "feedback", component: "slot", slot: "feedback" }
8009
8024
  ];
8010
8025
  const order = getSingleColumnOrder(context.interactionType);
@@ -8042,6 +8057,7 @@ const fullWidthStimulusTextTemplate = {
8042
8057
  { name: "prompt", component: "prompt", classes: ["lg:max-w-[50%]"] },
8043
8058
  { name: "divider", component: "divider", condition: context.hasDivider, classes: ["lg:max-w-[50%]"] },
8044
8059
  { name: "interaction", component: "slot", slot: "interaction", classes: ["lg:max-w-[50%]"] },
8060
+ { name: "divider-bottom", component: "divider-bottom", condition: context.hasDividerBottom, classes: ["lg:max-w-[50%]"] },
8045
8061
  { name: "feedback", component: "slot", slot: "feedback", classes: ["lg:max-w-[50%]"] }
8046
8062
  ];
8047
8063
  const order = getSingleColumnOrder(context.interactionType);
@@ -8496,13 +8512,14 @@ create_custom_element(
8496
8512
  true
8497
8513
  );
8498
8514
  var root_8$3 = /* @__PURE__ */ from_html(`<div class="divider my-6"></div>`);
8499
- var root_13$1 = /* @__PURE__ */ from_html(`<div aria-live="polite"><!></div>`);
8515
+ var root_13$1 = /* @__PURE__ */ from_html(`<div class="divider my-6"></div>`);
8516
+ var root_15$1 = /* @__PURE__ */ from_html(`<div aria-live="polite"><!></div>`);
8500
8517
  var root_1$h = /* @__PURE__ */ from_html(`<div><!></div>`);
8501
- var root_14 = /* @__PURE__ */ from_html(`<div><!></div>`);
8518
+ var root_16 = /* @__PURE__ */ from_html(`<div><!></div>`);
8502
8519
  var root$e = /* @__PURE__ */ from_html(`<div class="prompt-container"><div><div></div> <!></div></div> <!>`, 1);
8503
8520
  function PromptContainer($$anchor, $$props) {
8504
8521
  push($$props, true);
8505
- let rubric = prop($$props, "rubric", 7, ""), prompt = prop($$props, "prompt", 7, ""), interactionType = prop($$props, "interactionType", 7), hasDivider = prop($$props, "hasDivider", 7, true), stimulus = prop($$props, "stimulus", 7, null), optionHasMedia = prop($$props, "optionHasMedia", 7, false), interaction = prop($$props, "interaction", 7), feedback = prop($$props, "feedback", 7);
8522
+ let rubric = prop($$props, "rubric", 7, ""), prompt = prop($$props, "prompt", 7, ""), interactionType = prop($$props, "interactionType", 7), hasDivider = prop($$props, "hasDivider", 7, true), hasDividerBottom = prop($$props, "hasDividerBottom", 7, false), stimulus = prop($$props, "stimulus", 7, null), optionHasMedia = prop($$props, "optionHasMedia", 7, false), interaction = prop($$props, "interaction", 7), feedback = prop($$props, "feedback", 7);
8506
8523
  let stimulusData = /* @__PURE__ */ user_derived(() => useStimulusData(stimulus()));
8507
8524
  const windowWidth = getReactiveWindowWidth();
8508
8525
  let interactionWidthValue = /* @__PURE__ */ user_derived(() => getInteractionWidth(interactionType(), get$1(stimulusData), windowWidth.value));
@@ -8513,6 +8530,7 @@ function PromptContainer($$anchor, $$props) {
8513
8530
  rubric: rubric(),
8514
8531
  prompt: prompt(),
8515
8532
  hasDivider: hasDivider(),
8533
+ hasDividerBottom: hasDividerBottom(),
8516
8534
  interactionWidthValue: get$1(interactionWidthValue),
8517
8535
  windowWidth: windowWidth.value
8518
8536
  }));
@@ -8577,6 +8595,13 @@ function PromptContainer($$anchor, $$props) {
8577
8595
  hasDivider($$value);
8578
8596
  flushSync();
8579
8597
  },
8598
+ get hasDividerBottom() {
8599
+ return hasDividerBottom();
8600
+ },
8601
+ set hasDividerBottom($$value = false) {
8602
+ hasDividerBottom($$value);
8603
+ flushSync();
8604
+ },
8580
8605
  get stimulus() {
8581
8606
  return stimulus();
8582
8607
  },
@@ -8621,7 +8646,7 @@ function PromptContainer($$anchor, $$props) {
8621
8646
  }
8622
8647
  });
8623
8648
  };
8624
- var alternate_4 = ($$anchor3) => {
8649
+ var alternate_5 = ($$anchor3) => {
8625
8650
  var fragment_2 = comment();
8626
8651
  var node_1 = first_child(fragment_2);
8627
8652
  {
@@ -8632,7 +8657,7 @@ function PromptContainer($$anchor, $$props) {
8632
8657
  }
8633
8658
  });
8634
8659
  };
8635
- var alternate_3 = ($$anchor4) => {
8660
+ var alternate_4 = ($$anchor4) => {
8636
8661
  var fragment_4 = comment();
8637
8662
  var node_2 = first_child(fragment_4);
8638
8663
  {
@@ -8653,7 +8678,7 @@ function PromptContainer($$anchor, $$props) {
8653
8678
  });
8654
8679
  }
8655
8680
  };
8656
- var alternate_2 = ($$anchor5) => {
8681
+ var alternate_3 = ($$anchor5) => {
8657
8682
  var fragment_6 = comment();
8658
8683
  var node_3 = first_child(fragment_6);
8659
8684
  {
@@ -8661,7 +8686,7 @@ function PromptContainer($$anchor, $$props) {
8661
8686
  var div_4 = root_8$3();
8662
8687
  append($$anchor6, div_4);
8663
8688
  };
8664
- var alternate_1 = ($$anchor6) => {
8689
+ var alternate_2 = ($$anchor6) => {
8665
8690
  var fragment_7 = comment();
8666
8691
  var node_4 = first_child(fragment_7);
8667
8692
  {
@@ -8676,21 +8701,40 @@ function PromptContainer($$anchor, $$props) {
8676
8701
  $$slots: { default: true }
8677
8702
  });
8678
8703
  };
8679
- var alternate = ($$anchor7) => {
8704
+ var alternate_1 = ($$anchor7) => {
8680
8705
  var fragment_10 = comment();
8681
8706
  var node_6 = first_child(fragment_10);
8682
8707
  {
8683
8708
  var consequent_5 = ($$anchor8) => {
8684
8709
  var div_5 = root_13$1();
8685
- var node_7 = child(div_5);
8686
- snippet(node_7, () => feedback() ?? noop);
8687
- reset(div_5);
8688
8710
  append($$anchor8, div_5);
8689
8711
  };
8712
+ var alternate = ($$anchor8) => {
8713
+ var fragment_11 = comment();
8714
+ var node_7 = first_child(fragment_11);
8715
+ {
8716
+ var consequent_6 = ($$anchor9) => {
8717
+ var div_6 = root_15$1();
8718
+ var node_8 = child(div_6);
8719
+ snippet(node_8, () => feedback() ?? noop);
8720
+ reset(div_6);
8721
+ append($$anchor9, div_6);
8722
+ };
8723
+ if_block(
8724
+ node_7,
8725
+ ($$render) => {
8726
+ if (get$1(section).component === "slot" && get$1(section).slot === "feedback") $$render(consequent_6);
8727
+ },
8728
+ true
8729
+ );
8730
+ }
8731
+ append($$anchor8, fragment_11);
8732
+ };
8690
8733
  if_block(
8691
8734
  node_6,
8692
8735
  ($$render) => {
8693
- if (get$1(section).component === "slot" && get$1(section).slot === "feedback") $$render(consequent_5);
8736
+ if (get$1(section).component === "divider-bottom") $$render(consequent_5);
8737
+ else $$render(alternate, false);
8694
8738
  },
8695
8739
  true
8696
8740
  );
@@ -8701,7 +8745,7 @@ function PromptContainer($$anchor, $$props) {
8701
8745
  node_4,
8702
8746
  ($$render) => {
8703
8747
  if (get$1(section).component === "slot" && get$1(section).slot === "interaction") $$render(consequent_4);
8704
- else $$render(alternate, false);
8748
+ else $$render(alternate_1, false);
8705
8749
  },
8706
8750
  true
8707
8751
  );
@@ -8712,7 +8756,7 @@ function PromptContainer($$anchor, $$props) {
8712
8756
  node_3,
8713
8757
  ($$render) => {
8714
8758
  if (get$1(section).component === "divider") $$render(consequent_3);
8715
- else $$render(alternate_1, false);
8759
+ else $$render(alternate_2, false);
8716
8760
  },
8717
8761
  true
8718
8762
  );
@@ -8723,7 +8767,7 @@ function PromptContainer($$anchor, $$props) {
8723
8767
  node_2,
8724
8768
  ($$render) => {
8725
8769
  if (get$1(section).component === "stimulus-text" || get$1(section).component === "stimulus-media") $$render(consequent_2);
8726
- else $$render(alternate_2, false);
8770
+ else $$render(alternate_3, false);
8727
8771
  },
8728
8772
  true
8729
8773
  );
@@ -8734,7 +8778,7 @@ function PromptContainer($$anchor, $$props) {
8734
8778
  node_1,
8735
8779
  ($$render) => {
8736
8780
  if (get$1(section).component === "prompt") $$render(consequent_1);
8737
- else $$render(alternate_3, false);
8781
+ else $$render(alternate_4, false);
8738
8782
  },
8739
8783
  true
8740
8784
  );
@@ -8743,7 +8787,7 @@ function PromptContainer($$anchor, $$props) {
8743
8787
  };
8744
8788
  if_block(node, ($$render) => {
8745
8789
  if (get$1(section).component === "rubric") $$render(consequent);
8746
- else $$render(alternate_4, false);
8790
+ else $$render(alternate_5, false);
8747
8791
  });
8748
8792
  }
8749
8793
  reset(div_3);
@@ -8760,12 +8804,12 @@ function PromptContainer($$anchor, $$props) {
8760
8804
  append($$anchor2, div_3);
8761
8805
  });
8762
8806
  reset(div_2);
8763
- var node_8 = sibling(div_2, 2);
8807
+ var node_9 = sibling(div_2, 2);
8764
8808
  {
8765
- var consequent_6 = ($$anchor2) => {
8766
- var div_6 = root_14();
8767
- var node_9 = child(div_6);
8768
- StimulusSection(node_9, {
8809
+ var consequent_7 = ($$anchor2) => {
8810
+ var div_7 = root_16();
8811
+ var node_10 = child(div_7);
8812
+ StimulusSection(node_10, {
8769
8813
  get stimulusData() {
8770
8814
  return get$1(stimulusData);
8771
8815
  },
@@ -8774,29 +8818,29 @@ function PromptContainer($$anchor, $$props) {
8774
8818
  },
8775
8819
  onexpandImage: openStimulusModal
8776
8820
  });
8777
- reset(div_6);
8778
- bind_this(div_6, ($$value) => set(containerElement, $$value), () => get$1(containerElement));
8821
+ reset(div_7);
8822
+ bind_this(div_7, ($$value) => set(containerElement, $$value), () => get$1(containerElement));
8779
8823
  template_effect(
8780
8824
  ($0, $1) => {
8781
- set_class(div_6, 1, $0);
8782
- set_style(div_6, `${$1 ?? ""}; ${get$1(dynamicMarginTop) ?? ""}`);
8825
+ set_class(div_7, 1, $0);
8826
+ set_style(div_7, `${$1 ?? ""}; ${get$1(dynamicMarginTop) ?? ""}`);
8783
8827
  },
8784
8828
  [
8785
8829
  () => clsx(getClassString(get$1(desktopColumnSection).classes)),
8786
8830
  () => getStyleString(get$1(desktopColumnSection).styles)
8787
8831
  ]
8788
8832
  );
8789
- append($$anchor2, div_6);
8833
+ append($$anchor2, div_7);
8790
8834
  };
8791
- if_block(node_8, ($$render) => {
8792
- if (get$1(desktopColumnSection)) $$render(consequent_6);
8835
+ if_block(node_9, ($$render) => {
8836
+ if (get$1(desktopColumnSection)) $$render(consequent_7);
8793
8837
  });
8794
8838
  }
8795
8839
  reset(div_1);
8796
8840
  reset(div);
8797
- var node_10 = sibling(div, 2);
8841
+ var node_11 = sibling(div, 2);
8798
8842
  {
8799
- var consequent_7 = ($$anchor2) => {
8843
+ var consequent_8 = ($$anchor2) => {
8800
8844
  PromptStimulusImageModal($$anchor2, {
8801
8845
  get isOpen() {
8802
8846
  return get$1(isStimulusModalOpen);
@@ -8813,8 +8857,8 @@ function PromptContainer($$anchor, $$props) {
8813
8857
  onclose: closeStimulusModal
8814
8858
  });
8815
8859
  };
8816
- if_block(node_10, ($$render) => {
8817
- if (get$1(isStimulusModalOpen)) $$render(consequent_7);
8860
+ if_block(node_11, ($$render) => {
8861
+ if (get$1(isStimulusModalOpen)) $$render(consequent_8);
8818
8862
  });
8819
8863
  }
8820
8864
  template_effect(
@@ -8838,6 +8882,7 @@ create_custom_element(
8838
8882
  prompt: {},
8839
8883
  interactionType: {},
8840
8884
  hasDivider: {},
8885
+ hasDividerBottom: {},
8841
8886
  stimulus: {},
8842
8887
  optionHasMedia: {},
8843
8888
  interaction: {},
@@ -9860,11 +9905,6 @@ function shouldSaveTextAnswer(currentAnswer, latestAnswer, isDataSaving) {
9860
9905
  const hasChanged = currentAnswer !== latestAnswer;
9861
9906
  return !isDataSaving && hasChanged;
9862
9907
  }
9863
- function shouldSaveInlineAnswers(currentAnswers, latestAnswersStr, isDataSaving) {
9864
- const currentAnswersStr = JSON.stringify(currentAnswers);
9865
- const hasChanged = currentAnswersStr !== latestAnswersStr;
9866
- return !isDataSaving && hasChanged;
9867
- }
9868
9908
  var root_1$e = /* @__PURE__ */ from_html(`<label class="absolute left-0 top-0 bottom-0" aria-hidden="true"><span class="absolute inset-0 bg-black opacity-5 rounded-l-lg w-8.5 h-10.5 top-1"></span> <span class="absolute font-semibold text-base leading-[19px] text-charcoal px-3 inline-block pt-[15px]"> </span></label>`);
9869
9909
  var root_2$8 = /* @__PURE__ */ from_html(`<span class="w-6 h-6 absolute right-4 top-3.5 flex items-center justify-center" aria-hidden="true"><!></span>`);
9870
9910
  var root$b = /* @__PURE__ */ from_html(`<span><!> <input placeholder="Type your answer here" autocomplete="off"/> <!></span>`);
@@ -11042,10 +11082,6 @@ function TypeInComponent($$anchor, $$props) {
11042
11082
  set(isUpdatingFromBlur, false);
11043
11083
  return;
11044
11084
  }
11045
- if (!shouldSaveInlineAnswers(get$1(interactionState).data.inlineInputs, get$1(latestSavedAnswer), isDataSaving())) {
11046
- set(isUpdatingFromBlur, false);
11047
- return;
11048
- }
11049
11085
  set(latestSavedAnswer, currentAnswersStr, true);
11050
11086
  if (get$1(isInteractiveMode2)) {
11051
11087
  const allFilled = (() => {
@@ -11318,6 +11354,11 @@ const createTypeInInteraction = (config, sessionData) => {
11318
11354
  const variant = config.variant;
11319
11355
  const isPreviewMode2 = () => config.mode === MODES.PREVIEW;
11320
11356
  const isNormalMode = () => !config.mode || config.mode === MODES.SESSION;
11357
+ const getExpectedBlanksCount = () => {
11358
+ if (variant !== "inline") return 1;
11359
+ const blankCount = (config.inlinePrompt?.match(/<eat-contentful>/g) || []).length;
11360
+ return blankCount;
11361
+ };
11321
11362
  const punctuationRegex = /[\p{P}\p{S}]/gu;
11322
11363
  const normalizeAnswer = (raw) => {
11323
11364
  if (raw == null) return "";
@@ -11434,10 +11475,15 @@ const createTypeInInteraction = (config, sessionData) => {
11434
11475
  component: null,
11435
11476
  createInitialState: () => {
11436
11477
  const previewAnswers = isPreviewMode2() && sessionData?.scoringMetadata?.answer ? sessionData.scoringMetadata.answer : [];
11478
+ let initialInlineInputs = [];
11479
+ if (variant === "inline") {
11480
+ const expectedBlanks = getExpectedBlanksCount();
11481
+ initialInlineInputs = previewAnswers.length > 0 ? previewAnswers : Array(expectedBlanks).fill("");
11482
+ }
11437
11483
  return {
11438
11484
  data: {
11439
11485
  userInput: variant === "inline" ? "" : previewAnswers[0] || "",
11440
- inlineInputs: variant === "inline" ? previewAnswers : [],
11486
+ inlineInputs: initialInlineInputs,
11441
11487
  interactiveTriggeredResult: false,
11442
11488
  showFeedback: false,
11443
11489
  attempts: 0,
@@ -11451,7 +11497,8 @@ const createTypeInInteraction = (config, sessionData) => {
11451
11497
  isCompleted: (state2) => {
11452
11498
  if (config.isFinished !== void 0) return config.isFinished;
11453
11499
  if (variant === "inline") {
11454
- return state2.data.inlineInputs.length === config.correctAnswers.length && state2.data.inlineInputs.every((a) => a && a.trim().length > 0);
11500
+ const expectedBlanks = getExpectedBlanksCount();
11501
+ return state2.data.inlineInputs.length === expectedBlanks && state2.data.inlineInputs.every((a) => a && a.trim().length > 0);
11455
11502
  }
11456
11503
  return Boolean(state2.data.userInput && state2.data.userInput.trim().length > 0);
11457
11504
  },
@@ -11470,10 +11517,20 @@ const createTypeInInteraction = (config, sessionData) => {
11470
11517
  const last = events[events.length - 1];
11471
11518
  const rawAnswer = last.answer_id ?? last.answer;
11472
11519
  const answers = Array.isArray(rawAnswer) ? rawAnswer : [rawAnswer];
11520
+ let inlineInputs = [];
11521
+ if (variant === "inline") {
11522
+ const expectedBlanks = getExpectedBlanksCount();
11523
+ inlineInputs = Array(expectedBlanks).fill("");
11524
+ answers.forEach((ans, idx) => {
11525
+ if (idx < expectedBlanks) {
11526
+ inlineInputs[idx] = ans || "";
11527
+ }
11528
+ });
11529
+ }
11473
11530
  return {
11474
11531
  data: {
11475
11532
  userInput: variant === "inline" ? "" : answers[0] || "",
11476
- inlineInputs: variant === "inline" ? answers : [],
11533
+ inlineInputs,
11477
11534
  interactiveTriggeredResult: false,
11478
11535
  showFeedback: Boolean(config.isFinished),
11479
11536
  attempts: events.length,
@@ -11484,10 +11541,15 @@ const createTypeInInteraction = (config, sessionData) => {
11484
11541
  lastModified: last.timestamp || interactionUtils.createTimestamp()
11485
11542
  };
11486
11543
  }
11544
+ let initialInlineInputs = [];
11545
+ if (variant === "inline") {
11546
+ const expectedBlanks = getExpectedBlanksCount();
11547
+ initialInlineInputs = Array(expectedBlanks).fill("");
11548
+ }
11487
11549
  return {
11488
11550
  data: {
11489
11551
  userInput: "",
11490
- inlineInputs: [],
11552
+ inlineInputs: initialInlineInputs,
11491
11553
  interactiveTriggeredResult: false,
11492
11554
  showFeedback: false,
11493
11555
  attempts: 0,
@@ -11505,8 +11567,12 @@ const createTypeInInteraction = (config, sessionData) => {
11505
11567
  });
11506
11568
  },
11507
11569
  updateInlineInput: (state2, index2, value) => {
11508
- const clone = [...state2.data.inlineInputs];
11509
- clone[index2] = value;
11570
+ const expectedLength = getExpectedBlanksCount();
11571
+ let clone = [...state2.data.inlineInputs];
11572
+ if (clone.length < expectedLength) {
11573
+ clone = Array(expectedLength).fill("").map((_, i) => clone[i] || "");
11574
+ }
11575
+ clone[index2] = value ?? "";
11510
11576
  return interactionUtils.updateState(state2, {
11511
11577
  inlineInputs: clone,
11512
11578
  lastModified: interactionUtils.createTimestamp()
@@ -11520,10 +11586,14 @@ const createTypeInInteraction = (config, sessionData) => {
11520
11586
  feedback: generateTypeInFeedback(result, answers)
11521
11587
  };
11522
11588
  },
11523
- serialize: (state2) => ({
11524
- answer: variant === "inline" ? state2.data.inlineInputs : [state2.data.userInput],
11525
- timestamp: state2.lastModified
11526
- }),
11589
+ serialize: (state2) => {
11590
+ if (variant === "inline") {
11591
+ const expectedLength = getExpectedBlanksCount();
11592
+ const result = Array(expectedLength).fill("").map((_, i) => state2.data.inlineInputs[i] ?? "");
11593
+ return { answer: result, timestamp: state2.lastModified };
11594
+ }
11595
+ return { answer: [state2.data.userInput], timestamp: state2.lastModified };
11596
+ },
11527
11597
  deserialize: (answer) => ({
11528
11598
  data: {
11529
11599
  userInput: variant === "inline" ? "" : answer.answer[0] || "",
@@ -16661,7 +16731,6 @@ function useDropdown(prompt, options) {
16661
16731
  parseText
16662
16732
  };
16663
16733
  }
16664
- const KEY_PRESS_TIMEOUT = 1e3;
16665
16734
  function useDropdownState() {
16666
16735
  const scrollToActive = async (listElement, activeIndex) => {
16667
16736
  if (!listElement || activeIndex === null || activeIndex < 0) return;
@@ -16677,7 +16746,7 @@ function useDropdownState() {
16677
16746
  };
16678
16747
  const handleTypeAhead = (char, state2, options) => {
16679
16748
  const now2 = Date.now();
16680
- let searchString = now2 - state2.lastKeyPressTime > KEY_PRESS_TIMEOUT ? "" : state2.searchString;
16749
+ let searchString = now2 - state2.lastKeyPressTime > DROPDOWN_INTERACTION.KEY_PRESS_TIMEOUT ? "" : state2.searchString;
16681
16750
  searchString += char.toLowerCase();
16682
16751
  const matchIndex = options.findIndex((option) => {
16683
16752
  const cleanOption = option.replace(/<[^>]*>/g, "").toLowerCase();
@@ -16787,7 +16856,7 @@ function useDropdownState() {
16787
16856
  if (state2.activeIndex === null) {
16788
16857
  newState.activeIndex = 0;
16789
16858
  } else {
16790
- const newIndex = state2.activeIndex - 10;
16859
+ const newIndex = state2.activeIndex - DROPDOWN_INTERACTION.PAGE_NAVIGATION_STEP;
16791
16860
  newState.activeIndex = newIndex < 0 ? 0 : newIndex;
16792
16861
  }
16793
16862
  return newState;
@@ -16796,7 +16865,7 @@ function useDropdownState() {
16796
16865
  if (state2.activeIndex === null) {
16797
16866
  newState.activeIndex = 0;
16798
16867
  } else {
16799
- const newIndex = state2.activeIndex + 10;
16868
+ const newIndex = state2.activeIndex + DROPDOWN_INTERACTION.PAGE_NAVIGATION_STEP;
16800
16869
  newState.activeIndex = newIndex >= options.length ? options.length - 1 : newIndex;
16801
16870
  }
16802
16871
  return newState;
@@ -16929,6 +16998,29 @@ function calculateDropdownFeedback(state2, config, validateFn) {
16929
16998
  sessionAnswer
16930
16999
  };
16931
17000
  }
17001
+ function useDropdownPosition(config) {
17002
+ const minWidth = DROPDOWN_POSITION.MIN_WIDTH;
17003
+ const maxWidth = DROPDOWN_POSITION.MAX_WIDTH;
17004
+ const viewportPadding = DROPDOWN_POSITION.VIEWPORT_PADDING;
17005
+ const adjustDropdownWidth = async (containerRef, listRef) => {
17006
+ if (!containerRef || !listRef) return;
17007
+ const containerRect = containerRef.getBoundingClientRect();
17008
+ const viewportWidth = window.innerWidth;
17009
+ listRef.style.left = "0";
17010
+ listRef.style.right = "auto";
17011
+ const availableWidth = viewportWidth - containerRect.left - viewportPadding;
17012
+ if (availableWidth >= maxWidth) {
17013
+ listRef.style.maxWidth = `${maxWidth}px`;
17014
+ } else if (availableWidth >= minWidth) {
17015
+ listRef.style.maxWidth = `${availableWidth}px`;
17016
+ } else {
17017
+ listRef.style.maxWidth = `${minWidth}px`;
17018
+ }
17019
+ };
17020
+ return {
17021
+ adjustDropdownWidth
17022
+ };
17023
+ }
16932
17024
  var root_1$3 = /* @__PURE__ */ from_html(`<div class="absolute inset-0 bg-transparent z-10"></div>`);
16933
17025
  var root_2 = /* @__PURE__ */ from_html(`<span class="text-green-900 mr-2"><span aria-hidden="true"><!></span> <span class="sr-only">Correct</span></span>`);
16934
17026
  var root_5$1 = /* @__PURE__ */ from_html(`<span class="text-green-900 mr-2"><span aria-hidden="true"><!></span> <span class="sr-only">Correct</span></span>`);
@@ -16945,6 +17037,7 @@ function DropdownContainer($$anchor, $$props) {
16945
17037
  push($$props, true);
16946
17038
  let dropdownId = prop($$props, "dropdownId", 7), dropdownNumber = prop($$props, "dropdownNumber", 7), options = prop($$props, "options", 7), selected = prop($$props, "selected", 7), correctAnswers = prop($$props, "correctAnswers", 23, () => []), isCorrect = prop($$props, "isCorrect", 7, false), isFinished = prop($$props, "isFinished", 7, false), isLocked = prop($$props, "isLocked", 7, false), isDataSaving = prop($$props, "isDataSaving", 7, false), mode = prop($$props, "mode", 7), showFeedback = prop($$props, "showFeedback", 7, false), onselect = prop($$props, "onselect", 7), viewportBuffer = prop($$props, "viewportBuffer", 7, 60);
16947
17039
  const dropdownActions = useDropdownState();
17040
+ const dropdownPosition = useDropdownPosition();
16948
17041
  let initializedOptions = /* @__PURE__ */ user_derived(() => {
16949
17042
  if (options().length === 0) return [];
16950
17043
  return [...options()];
@@ -16957,6 +17050,7 @@ function DropdownContainer($$anchor, $$props) {
16957
17050
  let hoveredIndex = /* @__PURE__ */ state(null);
16958
17051
  let isFirstNavigation = /* @__PURE__ */ state(false);
16959
17052
  let pageExtensionElement = /* @__PURE__ */ state(null);
17053
+ let resizeTimeout = null;
16960
17054
  user_effect(() => {
16961
17055
  get$1(state$1).selected = selected();
16962
17056
  });
@@ -16980,6 +17074,7 @@ function DropdownContainer($$anchor, $$props) {
16980
17074
  const ensureDropdownVisibility = async () => {
16981
17075
  if (!get$1(containerRef) || !get$1(listRef)) return;
16982
17076
  await tick();
17077
+ await dropdownPosition.adjustDropdownWidth(get$1(containerRef), get$1(listRef));
16983
17078
  const listRect = get$1(listRef).getBoundingClientRect();
16984
17079
  const viewportHeight = window.innerHeight;
16985
17080
  const documentHeight = document.documentElement.scrollHeight;
@@ -17129,11 +17224,32 @@ function DropdownContainer($$anchor, $$props) {
17129
17224
  }
17130
17225
  handleCloseMenu();
17131
17226
  };
17227
+ const handleResize = () => {
17228
+ if (!get$1(state$1).isOpen || !get$1(containerRef) || !get$1(listRef)) return;
17229
+ if (resizeTimeout) {
17230
+ clearTimeout(resizeTimeout);
17231
+ }
17232
+ resizeTimeout = setTimeout(
17233
+ () => {
17234
+ if (get$1(state$1).isOpen && get$1(containerRef) && get$1(listRef)) {
17235
+ dropdownPosition.adjustDropdownWidth(get$1(containerRef), get$1(listRef));
17236
+ }
17237
+ resizeTimeout = null;
17238
+ },
17239
+ 150
17240
+ );
17241
+ };
17132
17242
  onMount(() => {
17133
17243
  document.addEventListener("mousedown", handleClickOutside);
17244
+ window.addEventListener("resize", handleResize);
17134
17245
  });
17135
17246
  onDestroy(() => {
17136
17247
  document.removeEventListener("mousedown", handleClickOutside);
17248
+ window.removeEventListener("resize", handleResize);
17249
+ if (resizeTimeout) {
17250
+ clearTimeout(resizeTimeout);
17251
+ resizeTimeout = null;
17252
+ }
17137
17253
  removePageExtension();
17138
17254
  });
17139
17255
  const buttonId = `dropdown-button-${dropdownId()}`;
@@ -18024,7 +18140,8 @@ function DropdownComponent($$anchor, $$props) {
18024
18140
  return config().stimulus;
18025
18141
  },
18026
18142
  optionHasMedia: false,
18027
- hasDivider: true,
18143
+ hasDivider: false,
18144
+ hasDividerBottom: true,
18028
18145
  interaction,
18029
18146
  feedback,
18030
18147
  $$slots: { interaction: true, feedback: true }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "eat-js-sdk",
3
- "version": "2.0.41",
3
+ "version": "2.0.43",
4
4
  "change version": "2.0.0",
5
5
  "description": "Authoring tool frontend SDK",
6
6
  "contributors": [