jspsych-tangram 0.0.13 → 0.0.15

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (51) hide show
  1. package/dist/afc/index.browser.js +17751 -0
  2. package/dist/afc/index.browser.js.map +1 -0
  3. package/dist/afc/index.browser.min.js +42 -0
  4. package/dist/afc/index.browser.min.js.map +1 -0
  5. package/dist/afc/index.cjs +443 -0
  6. package/dist/afc/index.cjs.map +1 -0
  7. package/dist/afc/index.d.ts +169 -0
  8. package/dist/afc/index.js +441 -0
  9. package/dist/afc/index.js.map +1 -0
  10. package/dist/construct/index.browser.js +8 -2
  11. package/dist/construct/index.browser.js.map +1 -1
  12. package/dist/construct/index.browser.min.js +10 -10
  13. package/dist/construct/index.browser.min.js.map +1 -1
  14. package/dist/construct/index.cjs +8 -2
  15. package/dist/construct/index.cjs.map +1 -1
  16. package/dist/construct/index.js +8 -2
  17. package/dist/construct/index.js.map +1 -1
  18. package/dist/index.cjs +379 -11
  19. package/dist/index.cjs.map +1 -1
  20. package/dist/index.d.ts +178 -12
  21. package/dist/index.js +379 -12
  22. package/dist/index.js.map +1 -1
  23. package/dist/nback/index.browser.js +6 -4
  24. package/dist/nback/index.browser.js.map +1 -1
  25. package/dist/nback/index.browser.min.js +8 -8
  26. package/dist/nback/index.browser.min.js.map +1 -1
  27. package/dist/nback/index.cjs +6 -4
  28. package/dist/nback/index.cjs.map +1 -1
  29. package/dist/nback/index.js +6 -4
  30. package/dist/nback/index.js.map +1 -1
  31. package/dist/prep/index.browser.js +8 -2
  32. package/dist/prep/index.browser.js.map +1 -1
  33. package/dist/prep/index.browser.min.js +10 -10
  34. package/dist/prep/index.browser.min.js.map +1 -1
  35. package/dist/prep/index.cjs +8 -2
  36. package/dist/prep/index.cjs.map +1 -1
  37. package/dist/prep/index.js +8 -2
  38. package/dist/prep/index.js.map +1 -1
  39. package/package.json +1 -1
  40. package/src/core/components/board/GameBoard.tsx +13 -42
  41. package/src/core/components/board/useGameBoard.ts +52 -0
  42. package/src/core/components/index.ts +4 -2
  43. package/src/core/components/pieces/BlueprintRing.tsx +0 -25
  44. package/src/core/components/pieces/useBlueprintRing.ts +39 -0
  45. package/src/index.ts +2 -1
  46. package/src/plugins/tangram-afc/AFCApp.tsx +341 -0
  47. package/src/plugins/tangram-afc/index.ts +140 -0
  48. package/src/plugins/tangram-nback/NBackApp.tsx +3 -3
  49. package/tangram-construct.min.js +10 -10
  50. package/tangram-nback.min.js +8 -8
  51. package/tangram-prep.min.js +10 -10
@@ -0,0 +1,140 @@
1
+ import { JsPsych, JsPsychPlugin, ParameterType, TrialType } from "jspsych";
2
+ import { startAFCTrial, StartAFCTrialParams } from "./AFCApp";
3
+
4
+ const info = {
5
+ name: "tangram-afc",
6
+ version: "1.0.0",
7
+ parameters: {
8
+ /** Left tangram specification to display */
9
+ tangram_left: {
10
+ type: ParameterType.COMPLEX,
11
+ default: undefined,
12
+ description: "TangramSpec object defining left target shape to display"
13
+ },
14
+ /** Right tangram specification to display */
15
+ tangram_right: {
16
+ type: ParameterType.COMPLEX,
17
+ default: undefined,
18
+ description: "TangramSpec object defining right target shape to display"
19
+ },
20
+ /** HTML content to display above the tangrams as instructions */
21
+ instructions: {
22
+ type: ParameterType.STRING,
23
+ default: "",
24
+ description: "HTML content to display above the tangrams as instructions"
25
+ },
26
+ /** Text to display on left response button */
27
+ button_text_left: {
28
+ type: ParameterType.STRING,
29
+ default: "Select Left",
30
+ description: "Text to display on left response button"
31
+ },
32
+ /** Text to display on right response button */
33
+ button_text_right: {
34
+ type: ParameterType.STRING,
35
+ default: "Select Right",
36
+ description: "Text to display on right response button"
37
+ },
38
+ /** Whether to show tangram decomposed into individual primitives with borders */
39
+ show_tangram_decomposition: {
40
+ type: ParameterType.BOOL,
41
+ default: false,
42
+ description: "Whether to show tangram decomposed into individual primitives with borders"
43
+ },
44
+ /** Whether to use distinct colors for each primitive shape type */
45
+ use_primitive_colors: {
46
+ type: ParameterType.BOOL,
47
+ default: false,
48
+ description: "Whether each primitive shape type should have its own distinct color in the displayed tangram"
49
+ },
50
+ /** Indices mapping primitives to colors from the color palette */
51
+ primitive_color_indices: {
52
+ type: ParameterType.OBJECT,
53
+ default: [0, 1, 2, 3, 4],
54
+ description: "Array of 5 integers indexing into primitiveColors array, mapping [square, smalltriangle, parallelogram, medtriangle, largetriangle] to colors"
55
+ },
56
+ /** Callback fired when trial ends */
57
+ onTrialEnd: {
58
+ type: ParameterType.FUNCTION,
59
+ default: undefined,
60
+ description: "Callback when trial completes with full data"
61
+ }
62
+ },
63
+ data: {
64
+ /** Reaction time in milliseconds */
65
+ rt: {
66
+ type: ParameterType.INT,
67
+ description: "Milliseconds between trial start and button click"
68
+ },
69
+ /** Response choice */
70
+ response: {
71
+ type: ParameterType.STRING,
72
+ description: "Which button was clicked: 'left' or 'right'"
73
+ }
74
+ },
75
+ citations: ""
76
+ };
77
+
78
+ type Info = typeof info;
79
+
80
+ /**
81
+ * **tangram-afc**
82
+ *
83
+ * A jsPsych plugin for alternative forced choice (AFC) trials displaying two tangrams
84
+ * side-by-side with response buttons.
85
+ *
86
+ * @author Justin Yang & Sean Paul Anderson
87
+ * @see {@link https://github.com/cogtoolslab/tangram_construction.git/tree/main/experiments/jspsych-tangram-prep}
88
+ */
89
+ class TangramAFCPlugin implements JsPsychPlugin<Info> {
90
+ static info = info;
91
+
92
+ constructor(private jsPsych: JsPsych) {}
93
+
94
+ /**
95
+ * Launches the trial by invoking startAFCTrial
96
+ * with the display element, parameters, and jsPsych instance.
97
+ */
98
+ trial(display_element: HTMLElement, trial: TrialType<Info>) {
99
+ // Wrap onTrialEnd to handle React cleanup and jsPsych trial completion
100
+ const wrappedOnTrialEnd = (data: any) => {
101
+ // Call user-provided callback if exists
102
+ if (trial.onTrialEnd) {
103
+ trial.onTrialEnd(data);
104
+ }
105
+
106
+ // Clean up React first (before clearing DOM)
107
+ const reactContext = (display_element as any).__reactContext;
108
+ if (reactContext?.root) {
109
+ reactContext.root.unmount();
110
+ }
111
+
112
+ // Clear display after React cleanup
113
+ display_element.innerHTML = '';
114
+
115
+ // Finish jsPsych trial with data
116
+ this.jsPsych.finishTrial(data);
117
+ };
118
+
119
+ // Create parameter object for wrapper
120
+ const params: StartAFCTrialParams = {
121
+ tangramLeft: trial.tangram_left,
122
+ tangramRight: trial.tangram_right,
123
+ instructions: trial.instructions,
124
+ buttonTextLeft: trial.button_text_left,
125
+ buttonTextRight: trial.button_text_right,
126
+ showTangramDecomposition: trial.show_tangram_decomposition,
127
+ usePrimitiveColors: trial.use_primitive_colors,
128
+ primitiveColorIndices: trial.primitive_color_indices,
129
+ onTrialEnd: wrappedOnTrialEnd
130
+ };
131
+
132
+ // Use React wrapper to start the trial
133
+ const { root, display_element: element, jsPsych } = startAFCTrial(display_element, params, this.jsPsych);
134
+
135
+ // Store React context for cleanup
136
+ (element as any).__reactContext = { root, jsPsych };
137
+ }
138
+ }
139
+
140
+ export default TangramAFCPlugin;
@@ -247,7 +247,7 @@ function NBackView({ params }: NBackViewProps) {
247
247
  <path
248
248
  d={pathD(scaledPoly)}
249
249
  fill={fillColor}
250
- opacity={CONFIG.opacity.silhouetteMask}
250
+ opacity={usePrimitiveColors ? CONFIG.opacity.piece.normal : CONFIG.opacity.silhouetteMask}
251
251
  stroke="none"
252
252
  />
253
253
 
@@ -298,7 +298,7 @@ function NBackView({ params }: NBackViewProps) {
298
298
  key={`sil-${i}`}
299
299
  d={pathD(scaledPoly)}
300
300
  fill={fillColor}
301
- opacity={CONFIG.opacity.silhouetteMask}
301
+ opacity={usePrimitiveColors ? CONFIG.opacity.piece.normal : CONFIG.opacity.silhouetteMask}
302
302
  stroke="none"
303
303
  />
304
304
  );
@@ -315,7 +315,7 @@ function NBackView({ params }: NBackViewProps) {
315
315
  alignItems: "center",
316
316
  justifyContent: "center",
317
317
  padding: "20px",
318
- background: "#f5f5f5"
318
+ background: "#fff7e0ff"
319
319
  }}>
320
320
  {/* Instructions */}
321
321
  {instructions && (