@mathscan/math-exercise-engine 1.1.16 → 1.2.0
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 +44 -11
- package/dist/index.d.ts +613 -194
- package/dist/index.js +724 -163
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +724 -163
- package/dist/index.mjs.map +1 -1
- package/dist/style.css +135 -0
- package/package.json +19 -19
package/dist/style.css
CHANGED
|
@@ -1351,6 +1351,32 @@ th.exercise-table-cell.exercise-table-cell--last-row:last-child {
|
|
|
1351
1351
|
}
|
|
1352
1352
|
}
|
|
1353
1353
|
|
|
1354
|
+
/* ============================================
|
|
1355
|
+
LOCKED EXERCISE (answers checked or revealed)
|
|
1356
|
+
Widgets refuse input in JS; these rules kill the pointer
|
|
1357
|
+
cursor that suggests otherwise. Cursor only — never `transform`,
|
|
1358
|
+
which would override rotations like `.diamond-keypad .keypad-btn`.
|
|
1359
|
+
Reset() removes `.locked` and everything comes back.
|
|
1360
|
+
============================================ */
|
|
1361
|
+
|
|
1362
|
+
.math-exercise-renderer.locked .inline-input,
|
|
1363
|
+
.math-exercise-renderer.locked .inline-input-chip,
|
|
1364
|
+
.math-exercise-renderer.locked .radio-option,
|
|
1365
|
+
.math-exercise-renderer.locked .drag-option,
|
|
1366
|
+
.math-exercise-renderer.locked .matcher-card,
|
|
1367
|
+
.math-exercise-renderer.locked .pair-matcher-card,
|
|
1368
|
+
.math-exercise-renderer.locked .keypad-btn,
|
|
1369
|
+
.math-exercise-renderer.locked .grid-symmetry__cell--editable,
|
|
1370
|
+
.math-exercise-renderer.locked .visual-fraction-widget__part,
|
|
1371
|
+
.math-exercise-renderer.locked .number-line-cursor-ball,
|
|
1372
|
+
.math-exercise-renderer.locked .number-line-placed-chip-btn,
|
|
1373
|
+
/* .clock-hand, not .clock-arrow: the arrow polygons are pointer-events:none,
|
|
1374
|
+
the transparent hit-target lines are what carry the grab cursor. */
|
|
1375
|
+
.math-exercise-renderer.locked .clock-interactive .clock-hand,
|
|
1376
|
+
.math-exercise-renderer.locked .clock-interactive .clock-hand:active {
|
|
1377
|
+
cursor: default;
|
|
1378
|
+
}
|
|
1379
|
+
|
|
1354
1380
|
/**
|
|
1355
1381
|
* Image Styles
|
|
1356
1382
|
*
|
|
@@ -2418,6 +2444,101 @@ th.exercise-table-cell.exercise-table-cell--last-row:last-child {
|
|
|
2418
2444
|
background: #fef2f2;
|
|
2419
2445
|
}
|
|
2420
2446
|
|
|
2447
|
+
.grid-symmetry {
|
|
2448
|
+
/* Figma palette. All tokens remain overridable by consuming applications. */
|
|
2449
|
+
--grid-symmetry-cell-color: #fff;
|
|
2450
|
+
--grid-symmetry-focus-color: #0f172a;
|
|
2451
|
+
--grid-symmetry-reference-color: #705dc0;
|
|
2452
|
+
--grid-symmetry-prefilled-color: #4f86d9;
|
|
2453
|
+
--grid-symmetry-answer-color: #291a64;
|
|
2454
|
+
--grid-symmetry-correct-color: #43b925;
|
|
2455
|
+
--grid-symmetry-incorrect-color: #d6234d;
|
|
2456
|
+
--grid-symmetry-line-color: #ffca76;
|
|
2457
|
+
--grid-symmetry-axis-color: #291a64;
|
|
2458
|
+
max-width: 100%;
|
|
2459
|
+
overflow: auto;
|
|
2460
|
+
padding: 0.75rem;
|
|
2461
|
+
}
|
|
2462
|
+
|
|
2463
|
+
.grid-symmetry__grid {
|
|
2464
|
+
display: grid;
|
|
2465
|
+
position: relative;
|
|
2466
|
+
width: max-content;
|
|
2467
|
+
gap: 1px;
|
|
2468
|
+
padding: 1px;
|
|
2469
|
+
background: var(--grid-symmetry-line-color);
|
|
2470
|
+
}
|
|
2471
|
+
|
|
2472
|
+
.grid-symmetry__cell {
|
|
2473
|
+
box-sizing: border-box;
|
|
2474
|
+
width: var(--grid-symmetry-cell-size);
|
|
2475
|
+
height: var(--grid-symmetry-cell-size);
|
|
2476
|
+
min-width: 0;
|
|
2477
|
+
padding: 0;
|
|
2478
|
+
border: 0;
|
|
2479
|
+
border-radius: 0;
|
|
2480
|
+
background: var(--grid-symmetry-cell-color);
|
|
2481
|
+
appearance: none;
|
|
2482
|
+
opacity: 1;
|
|
2483
|
+
transition: background-color 120ms ease;
|
|
2484
|
+
}
|
|
2485
|
+
|
|
2486
|
+
/* Unlocked cells only — locked ones render as plain spans and are not clickable. */
|
|
2487
|
+
|
|
2488
|
+
.grid-symmetry__cell--editable {
|
|
2489
|
+
cursor: pointer;
|
|
2490
|
+
}
|
|
2491
|
+
|
|
2492
|
+
.grid-symmetry__cell--editable:focus-visible {
|
|
2493
|
+
outline: 3px solid var(--grid-symmetry-focus-color);
|
|
2494
|
+
outline-offset: -3px;
|
|
2495
|
+
position: relative;
|
|
2496
|
+
z-index: 2;
|
|
2497
|
+
}
|
|
2498
|
+
|
|
2499
|
+
.grid-symmetry__cell--reference {
|
|
2500
|
+
background: var(--grid-symmetry-reference-color);
|
|
2501
|
+
}
|
|
2502
|
+
|
|
2503
|
+
.grid-symmetry__cell--prefilled {
|
|
2504
|
+
background: var(--grid-symmetry-prefilled-color);
|
|
2505
|
+
}
|
|
2506
|
+
|
|
2507
|
+
.grid-symmetry__cell--answer {
|
|
2508
|
+
background: var(--grid-symmetry-answer-color);
|
|
2509
|
+
}
|
|
2510
|
+
|
|
2511
|
+
.grid-symmetry--correct .grid-symmetry__cell--interactive.grid-symmetry__cell--selected {
|
|
2512
|
+
background: var(--grid-symmetry-correct-color);
|
|
2513
|
+
}
|
|
2514
|
+
|
|
2515
|
+
.grid-symmetry--incorrect .grid-symmetry__cell--interactive.grid-symmetry__cell--selected {
|
|
2516
|
+
background: var(--grid-symmetry-incorrect-color);
|
|
2517
|
+
}
|
|
2518
|
+
|
|
2519
|
+
.grid-symmetry__axis {
|
|
2520
|
+
position: absolute;
|
|
2521
|
+
z-index: 3;
|
|
2522
|
+
pointer-events: none;
|
|
2523
|
+
background: var(--grid-symmetry-axis-color);
|
|
2524
|
+
}
|
|
2525
|
+
|
|
2526
|
+
.grid-symmetry__axis--vertical {
|
|
2527
|
+
top: -12px;
|
|
2528
|
+
bottom: -12px;
|
|
2529
|
+
left: 50%;
|
|
2530
|
+
width: 3px;
|
|
2531
|
+
transform: translateX(-50%);
|
|
2532
|
+
}
|
|
2533
|
+
|
|
2534
|
+
.grid-symmetry__axis--horizontal {
|
|
2535
|
+
right: -12px;
|
|
2536
|
+
left: -12px;
|
|
2537
|
+
top: 50%;
|
|
2538
|
+
height: 3px;
|
|
2539
|
+
transform: translateY(-50%);
|
|
2540
|
+
}
|
|
2541
|
+
|
|
2421
2542
|
/**
|
|
2422
2543
|
* Button & Action Styles
|
|
2423
2544
|
*
|
|
@@ -2451,6 +2572,20 @@ th.exercise-table-cell.exercise-table-cell--last-row:last-child {
|
|
|
2451
2572
|
transform: scale(0.98);
|
|
2452
2573
|
}
|
|
2453
2574
|
|
|
2575
|
+
/* Locked exercise — the button is disabled until reset(). */
|
|
2576
|
+
|
|
2577
|
+
.exercise-submit-btn:disabled,
|
|
2578
|
+
.exercise-submit-btn:disabled:hover {
|
|
2579
|
+
cursor: default;
|
|
2580
|
+
opacity: 0.5;
|
|
2581
|
+
background: var(--exercise-primary);
|
|
2582
|
+
color: white;
|
|
2583
|
+
}
|
|
2584
|
+
|
|
2585
|
+
.exercise-submit-btn:disabled:active {
|
|
2586
|
+
transform: none;
|
|
2587
|
+
}
|
|
2588
|
+
|
|
2454
2589
|
/* Responsive Overrides - must be last */
|
|
2455
2590
|
|
|
2456
2591
|
/**
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@mathscan/math-exercise-engine",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.2.0",
|
|
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",
|
|
@@ -16,22 +16,6 @@
|
|
|
16
16
|
"files": [
|
|
17
17
|
"dist"
|
|
18
18
|
],
|
|
19
|
-
"scripts": {
|
|
20
|
-
"build": "vite build",
|
|
21
|
-
"dev": "vite build --watch",
|
|
22
|
-
"demo": "node examples/demo.mjs",
|
|
23
|
-
"demo:ts": "tsx --conditions=import examples/demo.ts",
|
|
24
|
-
"demo:build": "pnpm run build && node examples/demo.mjs",
|
|
25
|
-
"test": "vitest",
|
|
26
|
-
"test:run": "vitest run",
|
|
27
|
-
"test:coverage": "vitest run --coverage",
|
|
28
|
-
"lint": "echo 'ESLint disabled for now'",
|
|
29
|
-
"lint:fix": "echo 'ESLint disabled for now'",
|
|
30
|
-
"format": "prettier --write \"src/**/*.ts\" \"tests/**/*.ts\" \"*.{json,md}\"",
|
|
31
|
-
"format:check": "prettier --check \"src/**/*.ts\" \"tests/**/*.ts\" \"*.{json,md}\"",
|
|
32
|
-
"typecheck": "tsc --noEmit",
|
|
33
|
-
"prepublishOnly": "pnpm run build"
|
|
34
|
-
},
|
|
35
19
|
"keywords": [
|
|
36
20
|
"math",
|
|
37
21
|
"exercise",
|
|
@@ -90,5 +74,21 @@
|
|
|
90
74
|
"engines": {
|
|
91
75
|
"node": ">=18.0.0"
|
|
92
76
|
},
|
|
93
|
-
"packageManager": "pnpm@8.15.0"
|
|
94
|
-
|
|
77
|
+
"packageManager": "pnpm@8.15.0",
|
|
78
|
+
"scripts": {
|
|
79
|
+
"build": "vite build",
|
|
80
|
+
"dev": "vite build --watch",
|
|
81
|
+
"playground": "vite --open /playground/grid-symmetry-builder/",
|
|
82
|
+
"demo": "node examples/demo.mjs",
|
|
83
|
+
"demo:ts": "tsx --conditions=import examples/demo.ts",
|
|
84
|
+
"demo:build": "pnpm run build && node examples/demo.mjs",
|
|
85
|
+
"test": "vitest",
|
|
86
|
+
"test:run": "vitest run",
|
|
87
|
+
"test:coverage": "vitest run --coverage",
|
|
88
|
+
"lint": "echo 'ESLint disabled for now'",
|
|
89
|
+
"lint:fix": "echo 'ESLint disabled for now'",
|
|
90
|
+
"format": "prettier --write \"src/**/*.ts\" \"tests/**/*.ts\" \"*.{json,md}\"",
|
|
91
|
+
"format:check": "prettier --check \"src/**/*.ts\" \"tests/**/*.ts\" \"*.{json,md}\"",
|
|
92
|
+
"typecheck": "tsc --noEmit"
|
|
93
|
+
}
|
|
94
|
+
}
|