@classytic/stage 0.1.0 → 0.3.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/LICENSE +1 -1
- package/README.md +7 -3
- package/dist/assets/index.mjs +0 -1
- package/dist/assets/kit/glyphs.d.mts +5 -5
- package/dist/assets/kit/glyphs.mjs +4 -4
- package/dist/builder/Palette.mjs +50 -89
- package/dist/builder/SceneBuilder.mjs +18 -76
- package/dist/builder/editor.d.mts +2 -1
- package/dist/builder/editor.mjs +14 -4
- package/dist/builder/tools.d.mts +1 -1
- package/dist/builder/tools.mjs +1 -1
- package/dist/chem/index.d.mts +5 -5
- package/dist/chem/index.mjs +4 -4
- package/dist/circuit/index.d.mts +92 -0
- package/dist/circuit/index.mjs +333 -0
- package/dist/core/clock.d.mts +1 -1
- package/dist/core/clock.mjs +3 -3
- package/dist/core/control.d.mts +1 -1
- package/dist/core/control.mjs +2 -2
- package/dist/core/coords.d.mts +4 -4
- package/dist/core/coords.mjs +1 -1
- package/dist/core/index.d.mts +2 -1
- package/dist/core/index.mjs +2 -1
- package/dist/core/learner.d.mts +1 -1
- package/dist/core/learner.mjs +1 -1
- package/dist/core/math.d.mts +26 -0
- package/dist/core/math.mjs +37 -0
- package/dist/core/motion.d.mts +6 -6
- package/dist/core/motion.mjs +6 -6
- package/dist/core/richText.d.mts +2 -2
- package/dist/core/vec.d.mts +1 -1
- package/dist/field/index.d.mts +11 -3
- package/dist/field/index.mjs +20 -3
- package/dist/finance/bizsim.d.mts +93 -0
- package/dist/finance/bizsim.mjs +117 -0
- package/dist/finance/index.d.mts +118 -0
- package/dist/finance/index.mjs +203 -0
- package/dist/index.d.mts +6 -3
- package/dist/index.mjs +6 -4
- package/dist/interaction/MovableDot.d.mts +17 -1
- package/dist/interaction/MovableDot.mjs +160 -43
- package/dist/interaction/index.d.mts +2 -1
- package/dist/interaction/index.mjs +2 -1
- package/dist/interaction/useDraggable.d.mts +1 -1
- package/dist/interaction/useDraggable.mjs +55 -5
- package/dist/interaction/usePressSpring.d.mts +24 -0
- package/dist/interaction/usePressSpring.mjs +67 -0
- package/dist/logic/ast.d.mts +1 -1
- package/dist/logic/index.mjs +8 -3
- package/dist/logic/minimize.d.mts +2 -2
- package/dist/logic/minimize.mjs +56 -18
- package/dist/logic/table.mjs +1 -1
- package/dist/math/ast.d.mts +1 -1
- package/dist/math/ast.mjs +1 -1
- package/dist/math/calculus.d.mts +22 -1
- package/dist/math/calculus.mjs +224 -11
- package/dist/math/compile.d.mts +8 -0
- package/dist/math/compile.mjs +40 -0
- package/dist/math/defs.mjs +1 -1
- package/dist/math/index.d.mts +5 -4
- package/dist/math/index.mjs +5 -4
- package/dist/math/latex.mjs +8 -0
- package/dist/math/parse.mjs +2 -2
- package/dist/math/tokenize.mjs +1 -1
- package/dist/primitives/CanvasLayer.mjs +3 -3
- package/dist/primitives/Dot.d.mts +2 -15
- package/dist/primitives/Dot.mjs +6 -4
- package/dist/primitives/Grid.d.mts +41 -14
- package/dist/primitives/Grid.mjs +100 -22
- package/dist/primitives/Label.d.mts +2 -15
- package/dist/primitives/Label.mjs +4 -3
- package/dist/primitives/Lines.d.mts +4 -32
- package/dist/primitives/Lines.mjs +10 -8
- package/dist/primitives/Shapes.d.mts +5 -43
- package/dist/primitives/Shapes.mjs +12 -10
- package/dist/primitives/Tex.mjs +2 -2
- package/dist/primitives/index.d.mts +2 -2
- package/dist/primitives/index.mjs +2 -2
- package/dist/primitives/props.mjs +31 -0
- package/dist/scene/Scene.d.mts +6 -1
- package/dist/scene/Scene.mjs +16 -41
- package/dist/scene/assets.d.mts +2 -2
- package/dist/scene/assets.mjs +2 -2
- package/dist/scene/commands.d.mts +10 -1
- package/dist/scene/commands.mjs +42 -2
- package/dist/scene/evaluators.mjs +2 -2
- package/dist/scene/index.d.mts +2 -2
- package/dist/scene/index.mjs +2 -2
- package/dist/scene/migrate.mjs +1 -1
- package/dist/scene/sims.mjs +1 -1
- package/dist/scene/types.d.mts +4 -4
- package/dist/sim/particles.d.mts +2 -2
- package/dist/sim/rate.d.mts +4 -4
- package/dist/sim/rate.mjs +1 -1
- package/dist/sim/registry.d.mts +1 -1
- package/dist/sim/sampler.d.mts +5 -5
- package/dist/sim/thermal.d.mts +3 -3
- package/dist/sim/thermal.mjs +2 -2
- package/dist/sim/types.d.mts +2 -2
- package/dist/sim/wave.d.mts +2 -2
- package/dist/sim/wave.mjs +2 -2
- package/dist/steps/index.d.mts +1 -1
- package/dist/steps/index.mjs +3 -3
- package/dist/thermo/index.d.mts +1 -1
- package/dist/thermo/index.mjs +1 -1
- package/dist/view/Stage.mjs +6 -13
- package/dist/view/useInView.mjs +1 -1
- package/package.json +37 -25
- package/styles.css +141 -1
- package/dist/assets/kit/index.mjs +0 -4
package/package.json
CHANGED
|
@@ -1,13 +1,12 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@classytic/stage",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.3.0",
|
|
4
4
|
"description": "Domain-neutral visual primitive engine for the web. Declarative SVG diagram/math primitives, draggable handles, a math↔pixel coordinate system, a motion core + energy effect defs, theming, pure sim cores, and a small kit of neutral glyph primitives. Reactive, web-native, agent-drivable. The render foundation under @classytic/labs (subject-matter glyphs live there); canvas + 3D subpaths later.",
|
|
5
5
|
"author": "Classytic",
|
|
6
6
|
"license": "MIT",
|
|
7
7
|
"type": "module",
|
|
8
8
|
"sideEffects": [
|
|
9
|
-
"**/*.css"
|
|
10
|
-
"**/assets/**"
|
|
9
|
+
"**/*.css"
|
|
11
10
|
],
|
|
12
11
|
"engines": {
|
|
13
12
|
"node": ">=22"
|
|
@@ -52,6 +51,10 @@
|
|
|
52
51
|
"types": "./dist/math/index.d.mts",
|
|
53
52
|
"default": "./dist/math/index.mjs"
|
|
54
53
|
},
|
|
54
|
+
"./logic": {
|
|
55
|
+
"types": "./dist/logic/index.d.mts",
|
|
56
|
+
"default": "./dist/logic/index.mjs"
|
|
57
|
+
},
|
|
55
58
|
"./sim": {
|
|
56
59
|
"types": "./dist/sim/index.d.mts",
|
|
57
60
|
"default": "./dist/sim/index.mjs"
|
|
@@ -60,6 +63,10 @@
|
|
|
60
63
|
"types": "./dist/field/index.d.mts",
|
|
61
64
|
"default": "./dist/field/index.mjs"
|
|
62
65
|
},
|
|
66
|
+
"./circuit": {
|
|
67
|
+
"types": "./dist/circuit/index.d.mts",
|
|
68
|
+
"default": "./dist/circuit/index.mjs"
|
|
69
|
+
},
|
|
63
70
|
"./thermo": {
|
|
64
71
|
"types": "./dist/thermo/index.d.mts",
|
|
65
72
|
"default": "./dist/thermo/index.mjs"
|
|
@@ -68,9 +75,13 @@
|
|
|
68
75
|
"types": "./dist/chem/index.d.mts",
|
|
69
76
|
"default": "./dist/chem/index.mjs"
|
|
70
77
|
},
|
|
71
|
-
"./
|
|
72
|
-
"types": "./dist/
|
|
73
|
-
"default": "./dist/
|
|
78
|
+
"./finance": {
|
|
79
|
+
"types": "./dist/finance/index.d.mts",
|
|
80
|
+
"default": "./dist/finance/index.mjs"
|
|
81
|
+
},
|
|
82
|
+
"./steps": {
|
|
83
|
+
"types": "./dist/steps/index.d.mts",
|
|
84
|
+
"default": "./dist/steps/index.mjs"
|
|
74
85
|
},
|
|
75
86
|
"./styles.css": "./styles.css",
|
|
76
87
|
"./package.json": "./package.json"
|
|
@@ -84,21 +95,6 @@
|
|
|
84
95
|
"LICENSE",
|
|
85
96
|
"README.md"
|
|
86
97
|
],
|
|
87
|
-
"scripts": {
|
|
88
|
-
"build": "tsdown",
|
|
89
|
-
"dev": "tsdown --watch",
|
|
90
|
-
"typecheck": "tsc --noEmit",
|
|
91
|
-
"sync": "node scripts/sync-stage.mjs",
|
|
92
|
-
"pretest": "npm run build",
|
|
93
|
-
"test": "vitest run",
|
|
94
|
-
"verify": "npm run typecheck && npm test",
|
|
95
|
-
"push": "classytic-push",
|
|
96
|
-
"changeset": "changeset",
|
|
97
|
-
"version-packages": "changeset version",
|
|
98
|
-
"release": "npm run build && changeset publish",
|
|
99
|
-
"prepublishOnly": "npm run typecheck && npm run build && npm test",
|
|
100
|
-
"clean": "node -e \"require('fs').rmSync('dist',{recursive:true,force:true})\""
|
|
101
|
-
},
|
|
102
98
|
"peerDependencies": {
|
|
103
99
|
"katex": ">=0.16",
|
|
104
100
|
"react": ">=19",
|
|
@@ -113,12 +109,11 @@
|
|
|
113
109
|
"@changesets/cli": "^2.27.9",
|
|
114
110
|
"@classytic/dev-tools": "^0.2.0",
|
|
115
111
|
"@testing-library/react": "^16.3.2",
|
|
116
|
-
"@types/katex": "^0.16.7",
|
|
117
112
|
"@types/node": "^22.0.0",
|
|
118
113
|
"@types/react": "^19.2.0",
|
|
119
114
|
"@types/react-dom": "^19.2.0",
|
|
120
115
|
"happy-dom": "^20.0.0",
|
|
121
|
-
"katex": "^0.
|
|
116
|
+
"katex": "^0.18.7",
|
|
122
117
|
"react": "^19.2.0",
|
|
123
118
|
"react-dom": "^19.2.0",
|
|
124
119
|
"tsdown": "^0.22.0",
|
|
@@ -137,5 +132,22 @@
|
|
|
137
132
|
"math",
|
|
138
133
|
"engine",
|
|
139
134
|
"primitives"
|
|
140
|
-
]
|
|
141
|
-
|
|
135
|
+
],
|
|
136
|
+
"scripts": {
|
|
137
|
+
"build": "tsdown",
|
|
138
|
+
"dev": "tsdown --watch",
|
|
139
|
+
"typecheck": "tsc --noEmit",
|
|
140
|
+
"sync": "node scripts/sync-stage.mjs",
|
|
141
|
+
"pretest": "npm run build",
|
|
142
|
+
"test": "vitest run",
|
|
143
|
+
"verify": "npm run typecheck && npm test",
|
|
144
|
+
"package:check": "node scripts/package-check.mjs",
|
|
145
|
+
"package:consumer": "node scripts/packed-consumer-check.mjs",
|
|
146
|
+
"verify:release": "npm run typecheck && npm test && npm run package:check && npm run package:consumer",
|
|
147
|
+
"push": "classytic-push",
|
|
148
|
+
"changeset": "changeset",
|
|
149
|
+
"version-packages": "changeset version",
|
|
150
|
+
"release": "npm run build && changeset publish",
|
|
151
|
+
"clean": "node -e \"require('fs').rmSync('dist',{recursive:true,force:true})\""
|
|
152
|
+
}
|
|
153
|
+
}
|
package/styles.css
CHANGED
|
@@ -30,7 +30,7 @@
|
|
|
30
30
|
--stage-accent-2: var(--brand-2, oklch(0.62 0.18 48));
|
|
31
31
|
--stage-good: var(--success, oklch(0.58 0.16 150));
|
|
32
32
|
--stage-warn: var(--warning, oklch(0.68 0.15 72));
|
|
33
|
-
--stage-danger: var(--destructive, oklch(0.
|
|
33
|
+
--stage-danger: var(--destructive, oklch(0.58 0.19 25));
|
|
34
34
|
|
|
35
35
|
/* Asset kit. metal/pan are domain greys → a mid grey that reads on white.
|
|
36
36
|
The unknown (weight) tracks the brand. --stage-sheen is the top-edge
|
|
@@ -41,6 +41,9 @@
|
|
|
41
41
|
--stage-weight-2: var(--brand-2, oklch(0.62 0.18 48));
|
|
42
42
|
--stage-sheen: oklch(1 0 0);
|
|
43
43
|
--stage-liquid: oklch(0.6 0.13 220 / 0.55);
|
|
44
|
+
/* Discrete "objects" a learner drops into a vessel (marbles, beads). A calm rose
|
|
45
|
+
so a pile reads clearly on the light canvas without shouting. */
|
|
46
|
+
--stage-object: oklch(0.64 0.15 352);
|
|
44
47
|
--stage-handle-ring: color-mix(in oklab, var(--primary, oklch(0.59 0.22 261)) 40%, transparent);
|
|
45
48
|
|
|
46
49
|
/* Electronics — semantic aliases so circuit symbols never hardcode a colour.
|
|
@@ -49,6 +52,19 @@
|
|
|
49
52
|
--stage-wire: var(--stage-metal);
|
|
50
53
|
--stage-live: var(--stage-good);
|
|
51
54
|
--stage-charge: var(--stage-accent);
|
|
55
|
+
|
|
56
|
+
/* Categorical series palette: 8 distinct, theme-aware hues for group / series
|
|
57
|
+
colours (K-map loops, distributions, selection groups, arrangement letters).
|
|
58
|
+
Labs import these via kit/palette instead of hardcoding hex arrays that
|
|
59
|
+
ignore dark mode. cat-1/2/3 align with accent / accent-2 / good. */
|
|
60
|
+
--stage-cat-1: oklch(0.59 0.17 261);
|
|
61
|
+
--stage-cat-2: oklch(0.63 0.15 45);
|
|
62
|
+
--stage-cat-3: oklch(0.58 0.15 150);
|
|
63
|
+
--stage-cat-4: oklch(0.55 0.17 300);
|
|
64
|
+
--stage-cat-5: oklch(0.62 0.12 200);
|
|
65
|
+
--stage-cat-6: oklch(0.60 0.18 18);
|
|
66
|
+
--stage-cat-7: oklch(0.70 0.14 92);
|
|
67
|
+
--stage-cat-8: oklch(0.60 0.17 332);
|
|
52
68
|
}
|
|
53
69
|
|
|
54
70
|
.dark {
|
|
@@ -67,4 +83,128 @@
|
|
|
67
83
|
--stage-pan: oklch(0.83 0.02 255);
|
|
68
84
|
--stage-weight-2: var(--brand-2, oklch(0.74 0.15 50));
|
|
69
85
|
--stage-liquid: oklch(0.7 0.13 220 / 0.6);
|
|
86
|
+
--stage-object: oklch(0.72 0.16 352);
|
|
87
|
+
|
|
88
|
+
/* Brighter categorical hues for the dark card surface. */
|
|
89
|
+
--stage-cat-1: oklch(0.72 0.17 261);
|
|
90
|
+
--stage-cat-2: oklch(0.78 0.15 52);
|
|
91
|
+
--stage-cat-3: oklch(0.72 0.17 150);
|
|
92
|
+
--stage-cat-4: oklch(0.71 0.18 300);
|
|
93
|
+
--stage-cat-5: oklch(0.76 0.12 200);
|
|
94
|
+
--stage-cat-6: oklch(0.73 0.18 22);
|
|
95
|
+
--stage-cat-7: oklch(0.83 0.16 92);
|
|
96
|
+
--stage-cat-8: oklch(0.75 0.18 332);
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
|
|
100
|
+
/* ── Interaction affordance ──────────────────────────────────────────────────
|
|
101
|
+
First-touch invitation on MovableDot: a slow sonar echo of the affordance
|
|
102
|
+
ring until the learner interacts once. Pure CSS (no rAF), GPU-composited,
|
|
103
|
+
hidden under prefers-reduced-motion. */
|
|
104
|
+
.stage-nudge {
|
|
105
|
+
transform-box: fill-box;
|
|
106
|
+
transform-origin: center;
|
|
107
|
+
animation: stage-nudge 2.4s ease-out infinite;
|
|
108
|
+
}
|
|
109
|
+
@keyframes stage-nudge {
|
|
110
|
+
0% { transform: scale(1); opacity: .5; }
|
|
111
|
+
60% { transform: scale(1.8); opacity: 0; }
|
|
112
|
+
100% { transform: scale(1.8); opacity: 0; }
|
|
113
|
+
}
|
|
114
|
+
@media (prefers-reduced-motion: reduce) { .stage-nudge { display: none; } }
|
|
115
|
+
|
|
116
|
+
/* Shared runtime and authoring chrome. Geometry remains component-driven; these
|
|
117
|
+
classes keep static layout, focus and disabled states consistent for hosts. */
|
|
118
|
+
.stage-root { width: 100%; }
|
|
119
|
+
.stage-canvas {
|
|
120
|
+
display: block;
|
|
121
|
+
border: 1px solid var(--stage-grid);
|
|
122
|
+
border-radius: 12px;
|
|
123
|
+
user-select: none;
|
|
124
|
+
touch-action: none;
|
|
125
|
+
/* Before the ResizeObserver has measured anything, <Stage> renders width="640" so children
|
|
126
|
+
appear on first paint instead of a blank box. On a 360px phone that first paint is 280px
|
|
127
|
+
wider than the screen, so the page scrolls sideways and then jumps when JS mounts. The
|
|
128
|
+
viewBox makes the SVG scalable, so bounding it to the container costs nothing and removes
|
|
129
|
+
both the overflow and the shift. Post-measurement the width is already <= the container,
|
|
130
|
+
so neither rule binds and rendering is unchanged. */
|
|
131
|
+
max-width: 100%;
|
|
132
|
+
height: auto;
|
|
133
|
+
}
|
|
134
|
+
.stage-scene { position: relative; }
|
|
135
|
+
.stage-scene__play-overlay {
|
|
136
|
+
position: absolute;
|
|
137
|
+
inset: 0;
|
|
138
|
+
display: flex;
|
|
139
|
+
align-items: center;
|
|
140
|
+
justify-content: center;
|
|
141
|
+
border: 0;
|
|
142
|
+
border-radius: 12px;
|
|
143
|
+
background: color-mix(in oklab, var(--stage-bg) 38%, transparent);
|
|
144
|
+
cursor: pointer;
|
|
145
|
+
}
|
|
146
|
+
.stage-scene__play-label {
|
|
147
|
+
display: inline-flex;
|
|
148
|
+
align-items: center;
|
|
149
|
+
gap: 8px;
|
|
150
|
+
padding: 11px 26px;
|
|
151
|
+
border-radius: 999px;
|
|
152
|
+
color: var(--primary-foreground, #fff);
|
|
153
|
+
background: var(--stage-accent);
|
|
154
|
+
box-shadow: 0 6px 18px rgb(0 0 0 / 28%);
|
|
155
|
+
font-size: 16px;
|
|
156
|
+
font-weight: 800;
|
|
157
|
+
}
|
|
158
|
+
.stage-scene__pause {
|
|
159
|
+
position: absolute;
|
|
160
|
+
top: 10px;
|
|
161
|
+
right: 10px;
|
|
162
|
+
width: 34px;
|
|
163
|
+
height: 34px;
|
|
164
|
+
border: 1px solid var(--stage-grid);
|
|
165
|
+
border-radius: 999px;
|
|
166
|
+
color: var(--stage-fg);
|
|
167
|
+
background: color-mix(in oklab, var(--stage-bg) 80%, transparent);
|
|
168
|
+
cursor: pointer;
|
|
169
|
+
font-size: 13px;
|
|
170
|
+
}
|
|
171
|
+
.stage-builder { display: flex; flex-direction: column; gap: 10px; }
|
|
172
|
+
.stage-palette__toolbar { display: flex; flex-wrap: wrap; align-items: center; gap: 6px; }
|
|
173
|
+
.stage-palette__divider { align-self: stretch; width: 1px; margin: 0 4px; background: var(--stage-muted); }
|
|
174
|
+
.stage-tool-button {
|
|
175
|
+
display: inline-flex;
|
|
176
|
+
align-items: center;
|
|
177
|
+
gap: 6px;
|
|
178
|
+
min-height: 36px;
|
|
179
|
+
padding: 6px 10px;
|
|
180
|
+
border: 1px solid var(--stage-muted);
|
|
181
|
+
border-radius: 8px;
|
|
182
|
+
color: var(--stage-fg);
|
|
183
|
+
background: transparent;
|
|
184
|
+
cursor: pointer;
|
|
185
|
+
font: inherit;
|
|
186
|
+
font-size: 13px;
|
|
187
|
+
font-weight: 600;
|
|
188
|
+
}
|
|
189
|
+
.stage-tool-button[aria-pressed="true"] { border-color: var(--stage-accent); color: var(--primary-foreground, #fff); background: var(--stage-accent); }
|
|
190
|
+
.stage-tool-button:disabled { cursor: not-allowed; opacity: .4; }
|
|
191
|
+
.stage-tool-button--save { border-color: var(--stage-good); color: var(--stage-good); }
|
|
192
|
+
.stage-tool-button:focus-visible,
|
|
193
|
+
.stage-builder__field:focus-visible,
|
|
194
|
+
.stage-scene button:focus-visible { outline: 2px solid var(--stage-accent); outline-offset: 2px; }
|
|
195
|
+
.stage-palette__hint { margin: 6px 2px 0; color: var(--stage-muted); font-size: 12px; }
|
|
196
|
+
.stage-builder__scalars { display: flex; flex-wrap: wrap; gap: 14px; padding: 2px; font-size: 13px; }
|
|
197
|
+
.stage-builder__scalar { display: inline-flex; align-items: center; gap: 6px; }
|
|
198
|
+
.stage-builder__scalar-value { min-width: 24px; font-variant-numeric: tabular-nums; }
|
|
199
|
+
.stage-builder__pedagogy { padding: 6px 10px; border: 1px solid var(--stage-muted); border-radius: 8px; font-size: 13px; }
|
|
200
|
+
.stage-builder__pedagogy > summary { cursor: pointer; font-weight: 600; }
|
|
201
|
+
.stage-builder__pedagogy-fields { display: grid; gap: 8px; margin-top: 8px; }
|
|
202
|
+
.stage-builder__field-label { display: grid; gap: 3px; }
|
|
203
|
+
.stage-builder__difficulty { display: inline-flex; align-items: center; gap: 8px; }
|
|
204
|
+
.stage-builder__field { width: 100%; padding: 6px 8px; border: 1px solid var(--stage-muted); border-radius: 6px; color: inherit; background: transparent; font: inherit; }
|
|
205
|
+
.stage-builder__field--select { width: auto; }
|
|
206
|
+
@media (max-width: 520px) {
|
|
207
|
+
.stage-palette__divider { display: none; }
|
|
208
|
+
.stage-tool-button { min-height: 44px; }
|
|
209
|
+
.stage-builder__scalar { width: 100%; }
|
|
70
210
|
}
|