@mathscan/math-exercise-engine 1.2.3 → 1.2.5
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.ts +38 -0
- package/dist/index.js +45 -12
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +45 -12
- package/dist/index.mjs.map +1 -1
- package/dist/style.css +69 -50
- package/package.json +1 -1
package/dist/style.css
CHANGED
|
@@ -49,8 +49,20 @@
|
|
|
49
49
|
--exercise-border: #ddd;
|
|
50
50
|
--exercise-border-focus: var(--exercise-primary);
|
|
51
51
|
--exercise-highlight-color: #aef59d;
|
|
52
|
+
/* Validation state colors. Declared on this element, so an override on a
|
|
53
|
+
host *wrapper* is shadowed — use the renderer's `theme` prop (inline
|
|
54
|
+
style), or override on the root itself via the `className` prop.
|
|
55
|
+
The -bg tints derive from the base tokens so a host that only swaps
|
|
56
|
+
--exercise-incorrect (orange → red across attempts) gets matching tints.
|
|
57
|
+
The tints are computed HERE, so override the base tokens on the root
|
|
58
|
+
only — an override on a nested element leaves its tint unchanged. */
|
|
52
59
|
--exercise-correct: #22c55e;
|
|
53
60
|
--exercise-incorrect: #ef4444;
|
|
61
|
+
--exercise-correct-bg: color-mix(in srgb, var(--exercise-correct) 6%, var(--exercise-bg));
|
|
62
|
+
--exercise-incorrect-bg: color-mix(in srgb, var(--exercise-incorrect) 6%, var(--exercise-bg));
|
|
63
|
+
/* Authoring/engine errors — kept apart from --exercise-incorrect so they
|
|
64
|
+
don't follow the student's attempt state. */
|
|
65
|
+
--exercise-error: #ef4444;
|
|
54
66
|
|
|
55
67
|
/* ========================================
|
|
56
68
|
SPACING VARIABLES
|
|
@@ -490,22 +502,22 @@ mark {
|
|
|
490
502
|
|
|
491
503
|
.inline-input.widget--correct {
|
|
492
504
|
border-color: var(--exercise-correct, #22c55e);
|
|
493
|
-
box-shadow: 0 0 0 3px
|
|
505
|
+
box-shadow: 0 0 0 3px color-mix(in srgb, var(--exercise-correct, #22c55e) 15%, transparent);
|
|
494
506
|
}
|
|
495
507
|
|
|
496
508
|
.inline-input.widget--incorrect {
|
|
497
509
|
border-color: var(--exercise-incorrect, #ef4444);
|
|
498
|
-
box-shadow: 0 0 0 3px
|
|
510
|
+
box-shadow: 0 0 0 3px color-mix(in srgb, var(--exercise-incorrect, #ef4444) 15%, transparent);
|
|
499
511
|
}
|
|
500
512
|
|
|
501
513
|
.inline-input-chip.widget--correct {
|
|
502
514
|
border-color: var(--exercise-correct, #22c55e);
|
|
503
|
-
box-shadow: 0 0 0 3px
|
|
515
|
+
box-shadow: 0 0 0 3px color-mix(in srgb, var(--exercise-correct, #22c55e) 15%, transparent);
|
|
504
516
|
}
|
|
505
517
|
|
|
506
518
|
.inline-input-chip.widget--incorrect {
|
|
507
519
|
border-color: var(--exercise-incorrect, #ef4444);
|
|
508
|
-
box-shadow: 0 0 0 3px
|
|
520
|
+
box-shadow: 0 0 0 3px color-mix(in srgb, var(--exercise-incorrect, #ef4444) 15%, transparent);
|
|
509
521
|
}
|
|
510
522
|
|
|
511
523
|
/* ========================================
|
|
@@ -666,14 +678,14 @@ button.drag-option {
|
|
|
666
678
|
background: var(--exercise-correct, #22c55e);
|
|
667
679
|
border-color: var(--exercise-correct, #22c55e);
|
|
668
680
|
color: white;
|
|
669
|
-
box-shadow: 0 2px 4px
|
|
681
|
+
box-shadow: 0 2px 4px color-mix(in srgb, var(--exercise-correct, #22c55e) 25%, transparent);
|
|
670
682
|
}
|
|
671
683
|
|
|
672
684
|
.radio-option.widget--incorrect {
|
|
673
685
|
background: var(--exercise-incorrect, #ef4444);
|
|
674
686
|
border-color: var(--exercise-incorrect, #ef4444);
|
|
675
687
|
color: white;
|
|
676
|
-
box-shadow: 0 2px 4px
|
|
688
|
+
box-shadow: 0 2px 4px color-mix(in srgb, var(--exercise-incorrect, #ef4444) 25%, transparent);
|
|
677
689
|
}
|
|
678
690
|
|
|
679
691
|
/* ========================================
|
|
@@ -794,8 +806,14 @@ button.drag-option {
|
|
|
794
806
|
color: var(--exercise-text);
|
|
795
807
|
}
|
|
796
808
|
|
|
809
|
+
/*
|
|
810
|
+
* --exercise-table-border-color is always set inline by LayoutRenderer, which
|
|
811
|
+
* falls back to DEFAULT_TABLE_BORDER_COLOR. No literal default here: the color
|
|
812
|
+
* has one source of truth in src/constants/table-constants.ts.
|
|
813
|
+
*/
|
|
814
|
+
|
|
797
815
|
.exercise-table-container {
|
|
798
|
-
border: 2px solid
|
|
816
|
+
border: 2px solid var(--exercise-table-border-color);
|
|
799
817
|
border-radius: 8px;
|
|
800
818
|
overflow: hidden;
|
|
801
819
|
}
|
|
@@ -807,19 +825,19 @@ table.exercise-table {
|
|
|
807
825
|
|
|
808
826
|
td.exercise-table-cell,
|
|
809
827
|
th.exercise-table-cell {
|
|
810
|
-
box-shadow: inset -2px -2px 0 0
|
|
828
|
+
box-shadow: inset -2px -2px 0 0 var(--exercise-table-border-color);
|
|
811
829
|
}
|
|
812
830
|
|
|
813
831
|
td.exercise-table-cell:last-child,
|
|
814
832
|
th.exercise-table-cell:last-child {
|
|
815
|
-
box-shadow: inset 0 -2px 0 0
|
|
833
|
+
box-shadow: inset 0 -2px 0 0 var(--exercise-table-border-color);
|
|
816
834
|
}
|
|
817
835
|
|
|
818
836
|
tr.exercise-table-row:last-child td.exercise-table-cell,
|
|
819
837
|
tr.exercise-table-row:last-child th.exercise-table-cell,
|
|
820
838
|
td.exercise-table-cell.exercise-table-cell--last-row,
|
|
821
839
|
th.exercise-table-cell.exercise-table-cell--last-row {
|
|
822
|
-
box-shadow: inset -2px 0 0 0
|
|
840
|
+
box-shadow: inset -2px 0 0 0 var(--exercise-table-border-color);
|
|
823
841
|
}
|
|
824
842
|
|
|
825
843
|
tr.exercise-table-row:last-child td.exercise-table-cell:last-child,
|
|
@@ -1099,15 +1117,15 @@ th.exercise-table-cell.exercise-table-cell--last-row:last-child {
|
|
|
1099
1117
|
}
|
|
1100
1118
|
|
|
1101
1119
|
.widget--correct .matcher-card--selected {
|
|
1102
|
-
border-color: #
|
|
1103
|
-
background: #
|
|
1104
|
-
box-shadow: 0 4px 0
|
|
1120
|
+
border-color: var(--exercise-correct, #22c55e);
|
|
1121
|
+
background: var(--exercise-correct-bg, color-mix(in srgb, var(--exercise-correct, #22c55e) 6%, var(--exercise-bg, white)));
|
|
1122
|
+
box-shadow: 0 4px 0 color-mix(in srgb, var(--exercise-correct, #22c55e) 30%, transparent);
|
|
1105
1123
|
}
|
|
1106
1124
|
|
|
1107
1125
|
.widget--incorrect .matcher-card--selected {
|
|
1108
|
-
border-color: #
|
|
1109
|
-
background: #
|
|
1110
|
-
box-shadow: 0 4px 0
|
|
1126
|
+
border-color: var(--exercise-incorrect, #ef4444);
|
|
1127
|
+
background: var(--exercise-incorrect-bg, color-mix(in srgb, var(--exercise-incorrect, #ef4444) 6%, var(--exercise-bg, white)));
|
|
1128
|
+
box-shadow: 0 4px 0 color-mix(in srgb, var(--exercise-incorrect, #ef4444) 25%, transparent);
|
|
1111
1129
|
}
|
|
1112
1130
|
|
|
1113
1131
|
/* Intentionally dropped — kept for reference if unselected-card validation feedback is restored.
|
|
@@ -1137,8 +1155,8 @@ th.exercise-table-cell.exercise-table-cell--last-row:last-child {
|
|
|
1137
1155
|
--pm-dot-size: 17px;
|
|
1138
1156
|
--pm-dot-border-width: 2px;
|
|
1139
1157
|
--pm-line-color: var(--pm-orange);
|
|
1140
|
-
--pm-line-color-correct: #
|
|
1141
|
-
--pm-line-color-incorrect: #
|
|
1158
|
+
--pm-line-color-correct: var(--exercise-correct, #22c55e);
|
|
1159
|
+
--pm-line-color-incorrect: var(--exercise-incorrect, #ef4444);
|
|
1142
1160
|
--pm-line-width: 4px;
|
|
1143
1161
|
position: relative;
|
|
1144
1162
|
display: flex;
|
|
@@ -1215,15 +1233,15 @@ th.exercise-table-cell.exercise-table-cell--last-row:last-child {
|
|
|
1215
1233
|
}
|
|
1216
1234
|
|
|
1217
1235
|
.pair-matcher-card--correct {
|
|
1218
|
-
border-color: #
|
|
1219
|
-
background: #
|
|
1220
|
-
color: #
|
|
1236
|
+
border-color: var(--exercise-correct, #22c55e);
|
|
1237
|
+
background: var(--exercise-correct-bg, color-mix(in srgb, var(--exercise-correct, #22c55e) 6%, var(--exercise-bg, white)));
|
|
1238
|
+
color: var(--exercise-correct, #22c55e);
|
|
1221
1239
|
}
|
|
1222
1240
|
|
|
1223
1241
|
.pair-matcher-card--incorrect {
|
|
1224
|
-
border-color: #
|
|
1225
|
-
background: #
|
|
1226
|
-
color: #
|
|
1242
|
+
border-color: var(--exercise-incorrect, #ef4444);
|
|
1243
|
+
background: var(--exercise-incorrect-bg, color-mix(in srgb, var(--exercise-incorrect, #ef4444) 6%, var(--exercise-bg, white)));
|
|
1244
|
+
color: var(--exercise-incorrect, #ef4444);
|
|
1227
1245
|
}
|
|
1228
1246
|
|
|
1229
1247
|
.pair-matcher-dot {
|
|
@@ -1255,13 +1273,13 @@ th.exercise-table-cell.exercise-table-cell--last-row:last-child {
|
|
|
1255
1273
|
}
|
|
1256
1274
|
|
|
1257
1275
|
.pair-matcher-dot--correct {
|
|
1258
|
-
border-color: #
|
|
1259
|
-
background: #
|
|
1276
|
+
border-color: var(--exercise-correct, #22c55e);
|
|
1277
|
+
background: var(--exercise-correct, #22c55e);
|
|
1260
1278
|
}
|
|
1261
1279
|
|
|
1262
1280
|
.pair-matcher-dot--incorrect {
|
|
1263
|
-
border-color: #
|
|
1264
|
-
background: #
|
|
1281
|
+
border-color: var(--exercise-incorrect, #ef4444);
|
|
1282
|
+
background: var(--exercise-incorrect, #ef4444);
|
|
1265
1283
|
}
|
|
1266
1284
|
|
|
1267
1285
|
.pair-matcher-lines {
|
|
@@ -1620,9 +1638,9 @@ th.exercise-table-cell.exercise-table-cell--last-row:last-child {
|
|
|
1620
1638
|
|
|
1621
1639
|
/* Axis colour: overriding --nl-axis-color on root propagates to track, ticks, arrows and labels. */
|
|
1622
1640
|
|
|
1623
|
-
.number-line--correct { --nl-axis-color: #
|
|
1641
|
+
.number-line--correct { --nl-axis-color: var(--exercise-correct, #22c55e); }
|
|
1624
1642
|
|
|
1625
|
-
.number-line--incorrect { --nl-axis-color: #
|
|
1643
|
+
.number-line--incorrect { --nl-axis-color: var(--exercise-incorrect, #ef4444); }
|
|
1626
1644
|
|
|
1627
1645
|
/* Disable track transition for instant colour on submit. */
|
|
1628
1646
|
|
|
@@ -2181,13 +2199,13 @@ th.exercise-table-cell.exercise-table-cell--last-row:last-child {
|
|
|
2181
2199
|
.number-line-cursor-ball--correct,
|
|
2182
2200
|
.number-line-cursor-fill--correct,
|
|
2183
2201
|
.number-line-cursor-label--correct {
|
|
2184
|
-
--nl-cursor-color: #
|
|
2202
|
+
--nl-cursor-color: var(--exercise-correct, #22c55e);
|
|
2185
2203
|
}
|
|
2186
2204
|
|
|
2187
2205
|
.number-line-cursor-ball--incorrect,
|
|
2188
2206
|
.number-line-cursor-fill--incorrect,
|
|
2189
2207
|
.number-line-cursor-label--incorrect {
|
|
2190
|
-
--nl-cursor-color: #
|
|
2208
|
+
--nl-cursor-color: var(--exercise-incorrect, #ef4444);
|
|
2191
2209
|
}
|
|
2192
2210
|
|
|
2193
2211
|
.number-line-cursor-ball:focus-visible {
|
|
@@ -2459,33 +2477,33 @@ th.exercise-table-cell.exercise-table-cell--last-row:last-child {
|
|
|
2459
2477
|
}
|
|
2460
2478
|
|
|
2461
2479
|
.clock-correct .clock-arrow {
|
|
2462
|
-
fill: #
|
|
2463
|
-
stroke: #
|
|
2480
|
+
fill: var(--exercise-correct, #22c55e);
|
|
2481
|
+
stroke: var(--exercise-correct, #22c55e);
|
|
2464
2482
|
}
|
|
2465
2483
|
|
|
2466
2484
|
.clock-correct .clock-arrow-hour {
|
|
2467
|
-
fill: #
|
|
2468
|
-
stroke: #
|
|
2485
|
+
fill: var(--exercise-correct-bg, color-mix(in srgb, var(--exercise-correct, #22c55e) 6%, var(--exercise-bg, white)));
|
|
2486
|
+
stroke: var(--exercise-correct, #22c55e);
|
|
2469
2487
|
}
|
|
2470
2488
|
|
|
2471
2489
|
.clock-incorrect .clock-arrow {
|
|
2472
|
-
fill: #
|
|
2473
|
-
stroke: #
|
|
2490
|
+
fill: var(--exercise-incorrect, #ef4444);
|
|
2491
|
+
stroke: var(--exercise-incorrect, #ef4444);
|
|
2474
2492
|
}
|
|
2475
2493
|
|
|
2476
2494
|
.clock-incorrect .clock-arrow-hour {
|
|
2477
|
-
fill: #
|
|
2478
|
-
stroke: #
|
|
2495
|
+
fill: var(--exercise-incorrect-bg, color-mix(in srgb, var(--exercise-incorrect, #ef4444) 6%, var(--exercise-bg, white)));
|
|
2496
|
+
stroke: var(--exercise-incorrect, #ef4444);
|
|
2479
2497
|
}
|
|
2480
2498
|
|
|
2481
2499
|
.clock-correct .clock-digital-display {
|
|
2482
|
-
border-color: #
|
|
2483
|
-
background: #
|
|
2500
|
+
border-color: var(--exercise-correct, #22c55e);
|
|
2501
|
+
background: var(--exercise-correct-bg, color-mix(in srgb, var(--exercise-correct, #22c55e) 6%, var(--exercise-bg, white)));
|
|
2484
2502
|
}
|
|
2485
2503
|
|
|
2486
2504
|
.clock-incorrect .clock-digital-display {
|
|
2487
|
-
border-color: #
|
|
2488
|
-
background: #
|
|
2505
|
+
border-color: var(--exercise-incorrect, #ef4444);
|
|
2506
|
+
background: var(--exercise-incorrect-bg, color-mix(in srgb, var(--exercise-incorrect, #ef4444) 6%, var(--exercise-bg, white)));
|
|
2489
2507
|
}
|
|
2490
2508
|
|
|
2491
2509
|
.grid-symmetry {
|
|
@@ -2495,8 +2513,8 @@ th.exercise-table-cell.exercise-table-cell--last-row:last-child {
|
|
|
2495
2513
|
--grid-symmetry-reference-color: #705dc0;
|
|
2496
2514
|
--grid-symmetry-prefilled-color: #4f86d9;
|
|
2497
2515
|
--grid-symmetry-answer-color: #291a64;
|
|
2498
|
-
--grid-symmetry-correct-color: #
|
|
2499
|
-
--grid-symmetry-incorrect-color: #
|
|
2516
|
+
--grid-symmetry-correct-color: var(--exercise-correct, #22c55e);
|
|
2517
|
+
--grid-symmetry-incorrect-color: var(--exercise-incorrect, #ef4444);
|
|
2500
2518
|
--grid-symmetry-line-color: #ffca76;
|
|
2501
2519
|
--grid-symmetry-axis-color: #291a64;
|
|
2502
2520
|
max-width: 100%;
|
|
@@ -2635,12 +2653,13 @@ th.exercise-table-cell.exercise-table-cell--last-row:last-child {
|
|
|
2635
2653
|
*
|
|
2636
2654
|
* All colours and sizes are driven by CSS custom properties defined inside
|
|
2637
2655
|
* `.math-exercise-renderer` (variables.css). Consumer apps can override any
|
|
2638
|
-
* of these variables
|
|
2639
|
-
*
|
|
2656
|
+
* of these variables to theme the chart without touching engine code — but on
|
|
2657
|
+
* the renderer root itself (via its `className` prop), not on a parent: tokens
|
|
2658
|
+
* declared on the root shadow anything inherited from a wrapper.
|
|
2640
2659
|
*
|
|
2641
|
-
* Override surface example (student app):
|
|
2660
|
+
* Override surface example (student app, `className="my-exercise"`):
|
|
2642
2661
|
*
|
|
2643
|
-
* .my-exercise
|
|
2662
|
+
* .math-exercise-renderer.my-exercise {
|
|
2644
2663
|
* --chart-bar-color: #4f46e5;
|
|
2645
2664
|
* --chart-bar-correct-color: #22c55e;
|
|
2646
2665
|
* --chart-bar-wrong-color: #ef4444;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@mathscan/math-exercise-engine",
|
|
3
|
-
"version": "1.2.
|
|
3
|
+
"version": "1.2.5",
|
|
4
4
|
"description": "A DSL parser and validator for math exercises - transforms text-based exercise definitions into structured AST and JSON",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"module": "dist/index.mjs",
|