@pie-element/mc-populated-blank 0.2.4 → 0.2.6

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@pie-element/mc-populated-blank",
3
- "version": "0.2.4",
3
+ "version": "0.2.6",
4
4
  "description": "Multiple-choice option populates an inline blank in a sentence template (Svelte 5 PIE element)",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",
@@ -81,6 +81,8 @@ export const createDefaultModel = (model: any = {}) => ({
81
81
  },
82
82
  });
83
83
 
84
+ export const normalize = (question: any = {}) => createDefaultModel(question);
85
+
84
86
  export const normalizeSession = (s: any) => ({ ...s });
85
87
 
86
88
  const shouldShuffleChoices = (question: any) => !!question?.shuffle;
@@ -150,8 +152,9 @@ const getOrderedChoices = async (question: any, session: any, env: any, updateSe
150
152
 
151
153
  export const model = async (question: any, session: any, env: any, updateSession?: any) => {
152
154
  session = session || {};
153
- const normalizedQuestion = createDefaultModel(question);
154
- const choices = await getOrderedChoices(normalizedQuestion, session, env, updateSession);
155
+ const safeEnv = env || {};
156
+ const normalizedQuestion = normalize(question);
157
+ const choices = await getOrderedChoices(normalizedQuestion, session, safeEnv, updateSession);
155
158
 
156
159
  const out: any = {
157
160
  prompt: normalizedQuestion.promptEnabled ? normalizedQuestion.prompt : null,
@@ -192,19 +195,18 @@ export const model = async (question: any, session: any, env: any, updateSession
192
195
  ? normalizedQuestion.useFeatureButtonAudio
193
196
  : undefined,
194
197
  locale: normalizedQuestion.locale || '',
195
- disabled: env.mode !== 'gather',
196
- view: env.mode === 'view',
197
- mode: env.mode,
198
+ disabled: safeEnv.mode !== 'gather',
199
+ mode: safeEnv.mode,
198
200
  };
199
201
 
200
- if (env.mode === 'evaluate') {
202
+ if (safeEnv.mode === 'evaluate') {
201
203
  const correctness = getCorrectness(normalizedQuestion, session);
202
204
  out.correctness = correctness;
203
205
  out.responseCorrect = correctness === 'correct';
204
206
  out.correctChoiceId = normalizedQuestion.correctChoiceId;
205
207
  }
206
208
 
207
- if (env.role === 'instructor' && (env.mode === 'view' || env.mode === 'evaluate')) {
209
+ if (safeEnv.role === 'instructor' && (safeEnv.mode === 'view' || safeEnv.mode === 'evaluate')) {
208
210
  out.teacherInstructions = normalizedQuestion.teacherInstructionsEnabled
209
211
  ? normalizedQuestion.teacherInstructions
210
212
  : null;
@@ -91,7 +91,7 @@ const DEFAULT_UI_TEXT = {
91
91
  listenLabelEs: 'Escuchar',
92
92
  } as const;
93
93
 
94
- let { model, session, options } = $props<{ model?: any; session?: any; options?: any }>();
94
+ let { model, session } = $props<{ model?: any; session?: any; options?: any }>();
95
95
  let audioEl = $state<HTMLAudioElement | null>(null);
96
96
  let isMediaPlaying = $state(false);
97
97
  let localChoiceId = $state('');
@@ -263,19 +263,12 @@ const selectedId = $derived(session?.choiceId || localChoiceId || '');
263
263
  const radioGroupName = $derived(`${instanceId}-choice-group-${model?.id || '1'}`);
264
264
 
265
265
  let showCorrectAnswer = $state(false);
266
- const alwaysShowCorrect = $derived(
267
- !!model?.alwaysShowCorrect || !!options?.alwaysShowCorrect || !!options?.addCorrectResponse
268
- );
269
- const canRevealCorrectAnswer = $derived(
270
- !!model?.correctChoiceId && (isEvaluateMode || alwaysShowCorrect)
271
- );
272
- const shouldShowCorrectAnswer = $derived(alwaysShowCorrect || showCorrectAnswer);
273
266
  const shouldShowCorrectAnswerToggle = $derived(
274
- isEvaluateMode && !isResponseCorrect && !!model?.correctChoiceId && !alwaysShowCorrect
267
+ isEvaluateMode && !isResponseCorrect && !!model?.correctChoiceId
275
268
  );
276
269
 
277
270
  const displayChoiceId = $derived.by(() => {
278
- if (canRevealCorrectAnswer && shouldShowCorrectAnswer && model?.correctChoiceId) {
271
+ if (isEvaluateMode && showCorrectAnswer && model?.correctChoiceId) {
279
272
  return model.correctChoiceId;
280
273
  }
281
274
  return selectedId;
@@ -328,7 +321,7 @@ const audioErrorMessage = $derived.by(() =>
328
321
  );
329
322
 
330
323
  const resultText = $derived.by(() => {
331
- if (!isEvaluateMode || shouldShowCorrectAnswer) return '';
324
+ if (!isEvaluateMode || showCorrectAnswer) return '';
332
325
  if (isCorrect) return 'Correct answer selected';
333
326
  if (isIncorrect && selectedId) return 'Incorrect answer selected';
334
327
  return '';
@@ -342,8 +335,18 @@ const choiceCorrectnessById = $derived.by(() => {
342
335
  return map;
343
336
  }
344
337
 
345
- if (shouldShowCorrectAnswer && canRevealCorrectAnswer) {
346
- map.set(correctChoiceId, 'correct');
338
+ if (showCorrectAnswer) {
339
+ // In reveal mode we still reflect learner correctness:
340
+ // if learner did not select the correct choice (or selected nothing),
341
+ // keep the correct option marked incorrect.
342
+ if (activeSelectedId === correctChoiceId) {
343
+ map.set(correctChoiceId, 'correct');
344
+ return map;
345
+ }
346
+ if (activeSelectedId) {
347
+ map.set(activeSelectedId, 'incorrect');
348
+ }
349
+ map.set(correctChoiceId, 'incorrect');
347
350
  return map;
348
351
  }
349
352
 
@@ -397,7 +400,7 @@ function toggleCorrectAnswer() {
397
400
  }
398
401
 
399
402
  $effect(() => {
400
- if (!isEvaluateMode || isResponseCorrect || alwaysShowCorrect) {
403
+ if (!isEvaluateMode || isResponseCorrect) {
401
404
  showCorrectAnswer = false;
402
405
  }
403
406
  });
@@ -586,12 +589,12 @@ $effect(() => {
586
589
  type="button"
587
590
  class="mb-3 pie-toggle-correct-answer"
588
591
  style="gap:var(--mpb-toggle-button-gap, 0.5rem);"
589
- aria-pressed={shouldShowCorrectAnswer}
592
+ aria-pressed={showCorrectAnswer}
590
593
  data-testid="show-correct-answer"
591
594
  >
592
595
  <span class="pie-correct-answer-toggle-content">
593
596
  <span class="pie-correct-answer-toggle-icon-holder" aria-hidden="true">
594
- {#if shouldShowCorrectAnswer}
597
+ {#if showCorrectAnswer}
595
598
  <svg
596
599
  class="pie-correct-answer-toggle-svg"
597
600
  preserveAspectRatio="xMinYMin meet"
@@ -640,7 +643,7 @@ $effect(() => {
640
643
  {/if}
641
644
  </span>
642
645
  <span class="pie-correct-answer-toggle-label">
643
- {shouldShowCorrectAnswer ? uiText.hideCorrectAnswer : uiText.showCorrectAnswer}
646
+ {showCorrectAnswer ? uiText.hideCorrectAnswer : uiText.showCorrectAnswer}
644
647
  </span>
645
648
  </span>
646
649
  </button>
@@ -764,7 +767,7 @@ $effect(() => {
764
767
  {#each choices as c (c.id)}
765
768
  {@const choiceCorrectness = choiceCorrectnessById.get(c.id)}
766
769
  <div
767
- class={`flex items-start choice-row pie-choice ${isHorizontalChoices ? 'choice-row-horizontal pie-choice-horizontal' : ''} ${((shouldShowCorrectAnswer && canRevealCorrectAnswer ? model?.correctChoiceId : selectedId) === c.id) ? 'is-selected pie-choice-selected' : ''} ${choiceCorrectness ? `choice-${choiceCorrectness} pie-choice-${choiceCorrectness}` : ''}`}
770
+ class={`flex items-start choice-row pie-choice ${isHorizontalChoices ? 'choice-row-horizontal pie-choice-horizontal' : ''} ${((showCorrectAnswer ? model?.correctChoiceId : selectedId) === c.id) ? 'is-selected pie-choice-selected' : ''} ${choiceCorrectness ? `choice-${choiceCorrectness} pie-choice-${choiceCorrectness}` : ''}`}
768
771
  style="gap:var(--mpb-choice-row-gap, 0.5rem);"
769
772
  >
770
773
  {#if isHorizontalChoices}
@@ -790,7 +793,7 @@ $effect(() => {
790
793
  id={`${instanceId}-opt-${c.id}`}
791
794
  value={c.id}
792
795
  checked={
793
- (shouldShowCorrectAnswer && canRevealCorrectAnswer ? model?.correctChoiceId : selectedId) === c.id
796
+ (showCorrectAnswer ? model?.correctChoiceId : selectedId) === c.id
794
797
  }
795
798
  disabled={model?.disabled}
796
799
  class="choice-radio-bottom pie-choice-radio pie-choice-radio-bottom"
@@ -803,7 +806,7 @@ $effect(() => {
803
806
  id={`${instanceId}-opt-${c.id}`}
804
807
  value={c.id}
805
808
  checked={
806
- (shouldShowCorrectAnswer && canRevealCorrectAnswer ? model?.correctChoiceId : selectedId) === c.id
809
+ (showCorrectAnswer ? model?.correctChoiceId : selectedId) === c.id
807
810
  }
808
811
  disabled={model?.disabled}
809
812
  class="choice-radio-inline pie-choice-radio pie-choice-radio-inline"
package/src/index.iife.ts CHANGED
@@ -3,5 +3,7 @@
3
3
  * Registration is handled by PIE players/loaders, not by the element bundle itself.
4
4
  */
5
5
  import Element from './delivery';
6
+ import * as controller from './controller';
6
7
 
8
+ export { controller };
7
9
  export default Element;
package/src/index.ts CHANGED
@@ -1 +1,2 @@
1
1
  export { default } from './delivery/index';
2
+ export * as controller from './controller/index';