@mathscan/math-exercise-engine 1.2.14 → 1.2.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.
- package/README.md +6 -4
- package/dist/{GeometryWidget-D6_DlxhZ.js → GeometryWidget-CTTLw871.js} +2 -2
- package/dist/{GeometryWidget-D6_DlxhZ.js.map → GeometryWidget-CTTLw871.js.map} +1 -1
- package/dist/{GeometryWidget-B-EQ53jz.mjs → GeometryWidget-DZWM4LcD.mjs} +2 -2
- package/dist/{GeometryWidget-B-EQ53jz.mjs.map → GeometryWidget-DZWM4LcD.mjs.map} +1 -1
- package/dist/{index-Daj5xH0X.mjs → index-BLrnKegW.mjs} +1733 -911
- package/dist/index-BLrnKegW.mjs.map +1 -0
- package/dist/{index-gCvC2wRR.js → index-C9OHpy2h.js} +1468 -646
- package/dist/index-C9OHpy2h.js.map +1 -0
- package/dist/index.d.ts +8070 -3034
- package/dist/index.js +17 -1
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +282 -266
- package/dist/style.css +178 -12
- package/package.json +1 -1
- package/dist/index-Daj5xH0X.mjs.map +0 -1
- package/dist/index-gCvC2wRR.js.map +0 -1
package/dist/style.css
CHANGED
|
@@ -515,6 +515,87 @@ mark {
|
|
|
515
515
|
opacity: 1;
|
|
516
516
|
}
|
|
517
517
|
|
|
518
|
+
/* ========================================
|
|
519
|
+
DROP INPUT
|
|
520
|
+
======================================== */
|
|
521
|
+
|
|
522
|
+
.drop-input {
|
|
523
|
+
direction: ltr;
|
|
524
|
+
text-align: center;
|
|
525
|
+
}
|
|
526
|
+
|
|
527
|
+
/* Border, color and padding come from .inline-input. 5em is InlineInput's default
|
|
528
|
+
box. Low specificity on purpose, so a host's .inline-input size wins. */
|
|
529
|
+
|
|
530
|
+
.drop-input.inline-input,
|
|
531
|
+
.drop-input-sizer.inline-input {
|
|
532
|
+
display: inline-flex;
|
|
533
|
+
align-items: center;
|
|
534
|
+
justify-content: center;
|
|
535
|
+
width: 5em;
|
|
536
|
+
/* A placeholder longer than the box grows it, on one line. Not fit-content: its
|
|
537
|
+
shrink-wrapped parent gets its width from this box, so that would wrap the text. */
|
|
538
|
+
min-width: max-content;
|
|
539
|
+
}
|
|
540
|
+
|
|
541
|
+
/* Keeps a line box when the box has no text, so it has the input's height. Only
|
|
542
|
+
when empty: beside a placeholder it is a flex item that a host's gap pushes apart. */
|
|
543
|
+
|
|
544
|
+
.drop-input--empty:empty::before,
|
|
545
|
+
.drop-input-sizer:empty::before {
|
|
546
|
+
content: '\200b';
|
|
547
|
+
}
|
|
548
|
+
|
|
549
|
+
/* Not a real <input>, so ::placeholder can't style it and it would read as an
|
|
550
|
+
answer. Faded from the input's own color, so it suits any host without an override.
|
|
551
|
+
Padding is here because hosts set .inline-input padding to 0 for a centered short
|
|
552
|
+
value, which leaves a box-sized placeholder touching the border. */
|
|
553
|
+
|
|
554
|
+
.drop-input-placeholder {
|
|
555
|
+
padding: 0 0.25em;
|
|
556
|
+
color: var(--exercise-placeholder, color-mix(in srgb, currentColor 50%, transparent));
|
|
557
|
+
font-weight: normal;
|
|
558
|
+
}
|
|
559
|
+
|
|
560
|
+
/* Sizer and chip share one grid cell, so the cell fits whichever is bigger. */
|
|
561
|
+
|
|
562
|
+
.drop-input.drop-input--filled {
|
|
563
|
+
display: inline-grid;
|
|
564
|
+
}
|
|
565
|
+
|
|
566
|
+
.drop-input--filled > * {
|
|
567
|
+
grid-area: 1 / 1;
|
|
568
|
+
}
|
|
569
|
+
|
|
570
|
+
.drop-input-sizer {
|
|
571
|
+
visibility: hidden;
|
|
572
|
+
}
|
|
573
|
+
|
|
574
|
+
.drop-input--locked {
|
|
575
|
+
cursor: default;
|
|
576
|
+
}
|
|
577
|
+
|
|
578
|
+
/* Unresolved stored value (no matching bank option) — plain text, still clickable to clear. */
|
|
579
|
+
|
|
580
|
+
.drop-input-unresolved {
|
|
581
|
+
padding: 0;
|
|
582
|
+
border: 0;
|
|
583
|
+
background: transparent;
|
|
584
|
+
color: inherit;
|
|
585
|
+
font: inherit;
|
|
586
|
+
cursor: pointer;
|
|
587
|
+
}
|
|
588
|
+
|
|
589
|
+
.drop-input.widget--correct {
|
|
590
|
+
border-color: var(--exercise-correct, #22c55e);
|
|
591
|
+
box-shadow: 0 0 0 3px color-mix(in srgb, var(--exercise-correct, #22c55e) 15%, transparent);
|
|
592
|
+
}
|
|
593
|
+
|
|
594
|
+
.drop-input.widget--incorrect {
|
|
595
|
+
border-color: var(--exercise-incorrect, #ef4444);
|
|
596
|
+
box-shadow: 0 0 0 3px color-mix(in srgb, var(--exercise-incorrect, #ef4444) 15%, transparent);
|
|
597
|
+
}
|
|
598
|
+
|
|
518
599
|
/* ========================================
|
|
519
600
|
VALIDATION STATUS
|
|
520
601
|
======================================== */
|
|
@@ -636,19 +717,23 @@ mark {
|
|
|
636
717
|
box-shadow: 0 2px 4px rgba(0, 122, 204, 0.2);
|
|
637
718
|
}
|
|
638
719
|
|
|
639
|
-
/*
|
|
720
|
+
/* A gentle lift and soft halo invite the student to pick up a chip. */
|
|
640
721
|
|
|
641
722
|
@keyframes drag-option-hint {
|
|
642
|
-
0%, 100% {
|
|
643
|
-
|
|
644
|
-
|
|
645
|
-
|
|
646
|
-
|
|
723
|
+
0%, 100% {
|
|
724
|
+
transform: translateY(0);
|
|
725
|
+
box-shadow: 0 0 0 0 transparent, 0 0 0 transparent;
|
|
726
|
+
}
|
|
727
|
+
40%, 55% {
|
|
728
|
+
transform: translateY(-5px);
|
|
729
|
+
box-shadow:
|
|
730
|
+
0 0 0 5px color-mix(in srgb, var(--exercise-accent) 16%, transparent),
|
|
731
|
+
0 6px 12px color-mix(in srgb, var(--exercise-accent) 22%, transparent);
|
|
732
|
+
}
|
|
647
733
|
}
|
|
648
734
|
|
|
649
735
|
.drag-option.drag-option--hint {
|
|
650
|
-
|
|
651
|
-
animation: drag-option-hint 0.8s ease-in-out 0.4s 2 both;
|
|
736
|
+
animation: drag-option-hint 1.8s ease-in-out 0.65s 1 both;
|
|
652
737
|
}
|
|
653
738
|
|
|
654
739
|
@media (prefers-reduced-motion: reduce) {
|
|
@@ -669,6 +754,35 @@ button.drag-option {
|
|
|
669
754
|
font-weight: var(--exercise-font-weight);
|
|
670
755
|
}
|
|
671
756
|
|
|
757
|
+
/* Cards holding images or colored text: on the accent surface they could become
|
|
758
|
+
unreadable, so only the surface changes. Text-only cards stay plain chips.
|
|
759
|
+
Same specificity as button.drag-option, so a host's restyle of that rule wins
|
|
760
|
+
here too and all cards in a bank match. */
|
|
761
|
+
|
|
762
|
+
button.drag-option--rich {
|
|
763
|
+
background: var(--exercise-bg);
|
|
764
|
+
color: var(--exercise-text);
|
|
765
|
+
}
|
|
766
|
+
|
|
767
|
+
/* The mobile fixed chip width would clip an image. */
|
|
768
|
+
|
|
769
|
+
.rich-drag-option-slot button.drag-option {
|
|
770
|
+
width: auto;
|
|
771
|
+
}
|
|
772
|
+
|
|
773
|
+
.rich-option-content {
|
|
774
|
+
display: inline-flex;
|
|
775
|
+
align-items: center;
|
|
776
|
+
white-space: nowrap;
|
|
777
|
+
}
|
|
778
|
+
|
|
779
|
+
/* Text takes its color from the card it sits on. COLOR_TEXT keeps its own. */
|
|
780
|
+
|
|
781
|
+
.rich-option-content .text-item,
|
|
782
|
+
.rich-option-content .bold-text {
|
|
783
|
+
color: inherit;
|
|
784
|
+
}
|
|
785
|
+
|
|
672
786
|
/* ========================================
|
|
673
787
|
RADIO OPTIONS
|
|
674
788
|
======================================== */
|
|
@@ -3672,6 +3786,7 @@ button.drag-option {
|
|
|
3672
3786
|
--met-tutorial-next-text: #2e2463;
|
|
3673
3787
|
--met-tutorial-text: #2e2463;
|
|
3674
3788
|
--met-tutorial-bubble-border: #e0d9ff;
|
|
3789
|
+
--met-tutorial-fill-bg: #fff;
|
|
3675
3790
|
|
|
3676
3791
|
position: fixed;
|
|
3677
3792
|
inset: 0;
|
|
@@ -3824,6 +3939,8 @@ button.drag-option {
|
|
|
3824
3939
|
justify-content: center;
|
|
3825
3940
|
gap: 0.35em;
|
|
3826
3941
|
border-radius: 10px;
|
|
3942
|
+
/* Opaque: a prefill or typed value in the real box must not show through. */
|
|
3943
|
+
background: var(--met-tutorial-fill-bg);
|
|
3827
3944
|
pointer-events: none;
|
|
3828
3945
|
font-size: 18px;
|
|
3829
3946
|
font-weight: 700;
|
|
@@ -4126,6 +4243,35 @@ button.drag-option {
|
|
|
4126
4243
|
cursor: grabbing;
|
|
4127
4244
|
}
|
|
4128
4245
|
|
|
4246
|
+
/* Carries the theme variables to the overlay; drops the root's own card look. */
|
|
4247
|
+
.math-exercise-renderer.rich-drag-overlay-root {
|
|
4248
|
+
padding: 0;
|
|
4249
|
+
background: transparent;
|
|
4250
|
+
border-radius: 0;
|
|
4251
|
+
box-shadow: none;
|
|
4252
|
+
}
|
|
4253
|
+
|
|
4254
|
+
.rich-drag-overlay-option {
|
|
4255
|
+
display: inline-flex;
|
|
4256
|
+
align-items: center;
|
|
4257
|
+
justify-content: center;
|
|
4258
|
+
}
|
|
4259
|
+
|
|
4260
|
+
/* Same light surface as .drag-option--rich in the bank. */
|
|
4261
|
+
.drag-overlay-option--rich {
|
|
4262
|
+
background: var(--exercise-bg);
|
|
4263
|
+
color: var(--exercise-text);
|
|
4264
|
+
}
|
|
4265
|
+
|
|
4266
|
+
/* The droppable wrapper carries the inline flow (its child .drop-input keeps
|
|
4267
|
+
.inline-widget for the no-dnd path). drop-active styling is shared with
|
|
4268
|
+
.inline-input-droppable below. */
|
|
4269
|
+
.drop-input-droppable {
|
|
4270
|
+
display: inline-flex;
|
|
4271
|
+
align-items: center;
|
|
4272
|
+
vertical-align: middle;
|
|
4273
|
+
}
|
|
4274
|
+
|
|
4129
4275
|
/* Note: .drag-options and .drag-option base styles live in styles/widgets.css
|
|
4130
4276
|
(themed via CSS vars). Don't duplicate them here. */
|
|
4131
4277
|
|
|
@@ -4133,14 +4279,15 @@ button.drag-option {
|
|
|
4133
4279
|
display: inline-block;
|
|
4134
4280
|
}
|
|
4135
4281
|
|
|
4136
|
-
/* Slot container - maintains space when item is dragged out
|
|
4282
|
+
/* Slot container - maintains space when item is dragged out.
|
|
4283
|
+
Shared by the legacy chip bank and the rich DRAGGABLE_OPTIONS bank. */
|
|
4137
4284
|
.drag-option-slot {
|
|
4138
4285
|
display: inline-flex;
|
|
4139
4286
|
min-width: 60px;
|
|
4140
4287
|
min-height: 44px;
|
|
4141
4288
|
}
|
|
4142
4289
|
|
|
4143
|
-
/* Empty slot - shows where
|
|
4290
|
+
/* Empty slot - shows where a chip came from, from pick-up on. It is sized by an
|
|
4144
4291
|
invisible copy of the chip; the outline draws inside so the size stays exact.
|
|
4145
4292
|
Solid, not dashed: dashed is the look of the inputs it must not be mistaken for. */
|
|
4146
4293
|
.drag-option-empty {
|
|
@@ -4154,6 +4301,14 @@ button.drag-option {
|
|
|
4154
4301
|
visibility: hidden;
|
|
4155
4302
|
}
|
|
4156
4303
|
|
|
4304
|
+
/* Rich cards vary in size, so the slot always matches its hidden copy, even if a
|
|
4305
|
+
host gives .drag-option-empty a fixed width or a border that adds to the size.
|
|
4306
|
+
The outline above still draws the edge. */
|
|
4307
|
+
.rich-drag-option-slot .drag-option-empty {
|
|
4308
|
+
width: auto;
|
|
4309
|
+
border: 0;
|
|
4310
|
+
}
|
|
4311
|
+
|
|
4157
4312
|
/* Inline input droppable */
|
|
4158
4313
|
.inline-input-droppable {
|
|
4159
4314
|
display: inline-flex;
|
|
@@ -4214,8 +4369,19 @@ button.drag-option {
|
|
|
4214
4369
|
opacity: 0.4;
|
|
4215
4370
|
}
|
|
4216
4371
|
|
|
4217
|
-
/*
|
|
4218
|
-
.
|
|
4372
|
+
/* A chip in a DROP_INPUT stacks with its sizer instead of overlaying it, so a
|
|
4373
|
+
large card can grow the slot. See .drop-input--filled. */
|
|
4374
|
+
.inline-input-chip.placed-rich-option {
|
|
4375
|
+
display: inline-flex;
|
|
4376
|
+
align-items: center;
|
|
4377
|
+
justify-content: center;
|
|
4378
|
+
padding: 4px 8px;
|
|
4379
|
+
}
|
|
4380
|
+
|
|
4381
|
+
/* When droppable is active, style the input inside.
|
|
4382
|
+
DROP_INPUT shares the inline-input affordance. */
|
|
4383
|
+
.inline-input-droppable.drop-active .inline-input,
|
|
4384
|
+
.drop-input-droppable.drop-active .drop-input {
|
|
4219
4385
|
border-color: #4a90d9;
|
|
4220
4386
|
background-color: rgba(74, 144, 217, 0.05);
|
|
4221
4387
|
}
|
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.15",
|
|
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",
|