matterviz 0.3.1 → 0.3.2

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 (257) hide show
  1. package/dist/FilePicker.svelte +37 -20
  2. package/dist/Icon.svelte +2 -2
  3. package/dist/app.css +29 -0
  4. package/dist/brillouin/BrillouinZone.svelte +19 -61
  5. package/dist/brillouin/BrillouinZone.svelte.d.ts +1 -1
  6. package/dist/brillouin/BrillouinZoneExportPane.svelte +12 -20
  7. package/dist/brillouin/BrillouinZoneScene.svelte +2 -2
  8. package/dist/brillouin/BrillouinZoneScene.svelte.d.ts +1 -1
  9. package/dist/chempot-diagram/ChemPotDiagram.svelte +192 -0
  10. package/dist/chempot-diagram/ChemPotDiagram.svelte.d.ts +13 -0
  11. package/dist/chempot-diagram/ChemPotDiagram2D.svelte +677 -0
  12. package/dist/chempot-diagram/ChemPotDiagram2D.svelte.d.ts +16 -0
  13. package/dist/chempot-diagram/ChemPotDiagram3D.svelte +2688 -0
  14. package/dist/chempot-diagram/ChemPotDiagram3D.svelte.d.ts +16 -0
  15. package/dist/chempot-diagram/ChemPotScene3D.svelte +8 -0
  16. package/dist/chempot-diagram/ChemPotScene3D.svelte.d.ts +7 -0
  17. package/dist/chempot-diagram/color.d.ts +10 -0
  18. package/dist/chempot-diagram/color.js +33 -0
  19. package/dist/chempot-diagram/compute.d.ts +38 -0
  20. package/dist/chempot-diagram/compute.js +650 -0
  21. package/dist/chempot-diagram/index.d.ts +5 -0
  22. package/dist/chempot-diagram/index.js +5 -0
  23. package/dist/chempot-diagram/pointer.d.ts +16 -0
  24. package/dist/chempot-diagram/pointer.js +40 -0
  25. package/dist/chempot-diagram/temperature.d.ts +15 -0
  26. package/dist/chempot-diagram/temperature.js +37 -0
  27. package/dist/chempot-diagram/types.d.ts +83 -0
  28. package/dist/chempot-diagram/types.js +27 -0
  29. package/dist/colors/index.d.ts +3 -1
  30. package/dist/colors/index.js +4 -0
  31. package/dist/composition/BarChart.svelte +13 -22
  32. package/dist/composition/BubbleChart.svelte +5 -3
  33. package/dist/composition/FormulaFilter.svelte +586 -94
  34. package/dist/composition/FormulaFilter.svelte.d.ts +35 -1
  35. package/dist/composition/PieChart.svelte +43 -18
  36. package/dist/composition/PieChart.svelte.d.ts +1 -1
  37. package/dist/convex-hull/ConvexHull.svelte +4 -2
  38. package/dist/convex-hull/ConvexHull.svelte.d.ts +1 -1
  39. package/dist/convex-hull/ConvexHull2D.svelte +13 -44
  40. package/dist/convex-hull/ConvexHull2D.svelte.d.ts +1 -1
  41. package/dist/convex-hull/ConvexHull3D.svelte +16 -7
  42. package/dist/convex-hull/ConvexHull3D.svelte.d.ts +1 -1
  43. package/dist/convex-hull/ConvexHull4D.svelte +17 -7
  44. package/dist/convex-hull/ConvexHull4D.svelte.d.ts +1 -1
  45. package/dist/convex-hull/ConvexHullControls.svelte.d.ts +1 -1
  46. package/dist/convex-hull/ConvexHullStats.svelte +701 -226
  47. package/dist/convex-hull/ConvexHullStats.svelte.d.ts +6 -1
  48. package/dist/convex-hull/ConvexHullTooltip.svelte +1 -0
  49. package/dist/convex-hull/demo-temperature.d.ts +6 -0
  50. package/dist/convex-hull/demo-temperature.js +36 -0
  51. package/dist/convex-hull/helpers.d.ts +1 -1
  52. package/dist/convex-hull/helpers.js +2 -4
  53. package/dist/convex-hull/index.d.ts +1 -0
  54. package/dist/convex-hull/index.js +1 -0
  55. package/dist/convex-hull/thermodynamics.d.ts +8 -21
  56. package/dist/convex-hull/thermodynamics.js +106 -17
  57. package/dist/convex-hull/types.d.ts +5 -0
  58. package/dist/convex-hull/types.js +5 -0
  59. package/dist/coordination/CoordinationBarPlot.svelte +29 -46
  60. package/dist/element/BohrAtom.svelte +1 -1
  61. package/dist/element/data.js +2 -14
  62. package/dist/element/data.json.gz +0 -0
  63. package/dist/element/types.d.ts +1 -0
  64. package/dist/fermi-surface/FermiSurface.svelte +20 -64
  65. package/dist/fermi-surface/FermiSurface.svelte.d.ts +1 -1
  66. package/dist/fermi-surface/FermiSurfaceControls.svelte.d.ts +1 -1
  67. package/dist/fermi-surface/FermiSurfaceScene.svelte +1 -1
  68. package/dist/fermi-surface/FermiSurfaceScene.svelte.d.ts +1 -1
  69. package/dist/fermi-surface/parse.js +16 -22
  70. package/dist/heatmap-matrix/HeatmapMatrix.svelte +1273 -0
  71. package/dist/heatmap-matrix/HeatmapMatrix.svelte.d.ts +110 -0
  72. package/dist/heatmap-matrix/HeatmapMatrixControls.svelte +171 -0
  73. package/dist/heatmap-matrix/HeatmapMatrixControls.svelte.d.ts +31 -0
  74. package/dist/heatmap-matrix/index.d.ts +53 -0
  75. package/dist/heatmap-matrix/index.js +100 -0
  76. package/dist/heatmap-matrix/shared.d.ts +2 -0
  77. package/dist/heatmap-matrix/shared.js +4 -0
  78. package/dist/icons.d.ts +111 -0
  79. package/dist/icons.js +111 -0
  80. package/dist/index.d.ts +3 -1
  81. package/dist/index.js +3 -1
  82. package/dist/io/export.js +15 -3
  83. package/dist/io/file-drop.d.ts +7 -0
  84. package/dist/io/file-drop.js +43 -0
  85. package/dist/io/index.d.ts +2 -2
  86. package/dist/io/index.js +2 -112
  87. package/dist/io/types.d.ts +1 -0
  88. package/dist/io/url-drop.d.ts +2 -0
  89. package/dist/io/url-drop.js +118 -0
  90. package/dist/isosurface/Isosurface.svelte +101 -45
  91. package/dist/isosurface/IsosurfaceControls.svelte +19 -0
  92. package/dist/isosurface/parse.js +73 -30
  93. package/dist/isosurface/slice.d.ts +2 -1
  94. package/dist/isosurface/slice.js +3 -3
  95. package/dist/isosurface/types.d.ts +13 -1
  96. package/dist/isosurface/types.js +98 -0
  97. package/dist/labels.d.ts +2 -1
  98. package/dist/labels.js +1 -0
  99. package/dist/layout/InfoTag.svelte +62 -62
  100. package/dist/layout/SubpageGrid.svelte +74 -0
  101. package/dist/layout/SubpageGrid.svelte.d.ts +14 -0
  102. package/dist/layout/index.d.ts +1 -0
  103. package/dist/layout/index.js +1 -0
  104. package/dist/layout/json-tree/JsonNode.svelte +83 -85
  105. package/dist/layout/json-tree/JsonTree.svelte +20 -19
  106. package/dist/layout/json-tree/JsonTree.svelte.d.ts +1 -1
  107. package/dist/layout/json-tree/JsonValue.svelte +196 -116
  108. package/dist/layout/json-tree/types.d.ts +10 -2
  109. package/dist/layout/json-tree/utils.d.ts +2 -0
  110. package/dist/layout/json-tree/utils.js +33 -0
  111. package/dist/math.d.ts +7 -0
  112. package/dist/math.js +358 -7
  113. package/dist/overlays/ContextMenu.svelte +3 -2
  114. package/dist/overlays/DraggablePane.svelte +163 -58
  115. package/dist/overlays/DraggablePane.svelte.d.ts +2 -0
  116. package/dist/phase-diagram/IsobaricBinaryPhaseDiagram.svelte +232 -77
  117. package/dist/phase-diagram/IsobaricBinaryPhaseDiagram.svelte.d.ts +6 -2
  118. package/dist/phase-diagram/PhaseDiagramControls.svelte +32 -11
  119. package/dist/phase-diagram/PhaseDiagramControls.svelte.d.ts +3 -2
  120. package/dist/phase-diagram/PhaseDiagramEditorPane.svelte +103 -0
  121. package/dist/phase-diagram/PhaseDiagramEditorPane.svelte.d.ts +15 -0
  122. package/dist/phase-diagram/PhaseDiagramExportPane.svelte +102 -95
  123. package/dist/phase-diagram/PhaseDiagramExportPane.svelte.d.ts +7 -0
  124. package/dist/phase-diagram/PhaseDiagramTooltip.svelte +100 -26
  125. package/dist/phase-diagram/PhaseDiagramTooltip.svelte.d.ts +6 -3
  126. package/dist/phase-diagram/index.d.ts +2 -0
  127. package/dist/phase-diagram/index.js +2 -0
  128. package/dist/phase-diagram/svg-to-diagram.d.ts +2 -0
  129. package/dist/phase-diagram/svg-to-diagram.js +865 -0
  130. package/dist/phase-diagram/types.d.ts +10 -0
  131. package/dist/phase-diagram/utils.d.ts +7 -4
  132. package/dist/phase-diagram/utils.js +149 -59
  133. package/dist/plot/AxisLabel.svelte +26 -0
  134. package/dist/plot/AxisLabel.svelte.d.ts +16 -0
  135. package/dist/plot/BarPlot.svelte +473 -228
  136. package/dist/plot/BarPlot.svelte.d.ts +3 -3
  137. package/dist/plot/BarPlotControls.svelte +3 -2
  138. package/dist/plot/BarPlotControls.svelte.d.ts +1 -1
  139. package/dist/plot/ColorBar.svelte +54 -54
  140. package/dist/plot/ColorBar.svelte.d.ts +1 -1
  141. package/dist/plot/ColorScaleSelect.svelte +1 -1
  142. package/dist/plot/ElementScatter.svelte +3 -2
  143. package/dist/plot/FillArea.svelte +4 -1
  144. package/dist/plot/Histogram.svelte +320 -230
  145. package/dist/plot/Histogram.svelte.d.ts +2 -2
  146. package/dist/plot/HistogramControls.svelte +29 -10
  147. package/dist/plot/HistogramControls.svelte.d.ts +6 -2
  148. package/dist/plot/InteractiveAxisLabel.svelte.d.ts +2 -2
  149. package/dist/plot/PlotControls.svelte +109 -27
  150. package/dist/plot/PlotControls.svelte.d.ts +1 -1
  151. package/dist/plot/PlotLegend.svelte +1 -1
  152. package/dist/plot/PortalSelect.svelte +2 -1
  153. package/dist/plot/ReferenceLine.svelte +2 -1
  154. package/dist/plot/ReferenceLine.svelte.d.ts +1 -0
  155. package/dist/plot/ReferencePlane.svelte +1 -3
  156. package/dist/plot/ScatterPlot.svelte +343 -209
  157. package/dist/plot/ScatterPlot.svelte.d.ts +3 -3
  158. package/dist/plot/ScatterPlot3D.svelte.d.ts +2 -2
  159. package/dist/plot/ScatterPlot3DControls.svelte +203 -250
  160. package/dist/plot/ScatterPlot3DScene.svelte +4 -7
  161. package/dist/plot/ScatterPlot3DScene.svelte.d.ts +2 -2
  162. package/dist/plot/ScatterPlotControls.svelte +95 -55
  163. package/dist/plot/ScatterPlotControls.svelte.d.ts +1 -1
  164. package/dist/plot/ZeroLines.svelte +44 -0
  165. package/dist/plot/ZeroLines.svelte.d.ts +32 -0
  166. package/dist/plot/ZoomRect.svelte +21 -0
  167. package/dist/plot/ZoomRect.svelte.d.ts +8 -0
  168. package/dist/plot/axis-utils.d.ts +1 -1
  169. package/dist/plot/index.d.ts +6 -2
  170. package/dist/plot/index.js +6 -2
  171. package/dist/plot/interactions.d.ts +8 -10
  172. package/dist/plot/interactions.js +2 -3
  173. package/dist/plot/layout.d.ts +7 -1
  174. package/dist/plot/layout.js +12 -4
  175. package/dist/plot/reference-line.d.ts +4 -21
  176. package/dist/plot/reference-line.js +7 -81
  177. package/dist/plot/types.d.ts +42 -17
  178. package/dist/plot/types.js +10 -0
  179. package/dist/plot/utils/label-placement.js +13 -10
  180. package/dist/plot/utils.d.ts +1 -0
  181. package/dist/plot/utils.js +14 -0
  182. package/dist/rdf/RdfPlot.svelte +55 -66
  183. package/dist/settings.d.ts +3 -0
  184. package/dist/settings.js +17 -3
  185. package/dist/spectral/Bands.svelte +515 -143
  186. package/dist/spectral/Bands.svelte.d.ts +22 -2
  187. package/dist/spectral/helpers.d.ts +23 -1
  188. package/dist/spectral/helpers.js +65 -9
  189. package/dist/spectral/types.d.ts +2 -0
  190. package/dist/structure/AtomLegend.svelte +29 -8
  191. package/dist/structure/AtomLegend.svelte.d.ts +1 -1
  192. package/dist/structure/CellSelect.svelte +92 -22
  193. package/dist/structure/Structure.svelte +108 -118
  194. package/dist/structure/Structure.svelte.d.ts +1 -1
  195. package/dist/structure/StructureControls.svelte +25 -22
  196. package/dist/structure/StructureControls.svelte.d.ts +1 -1
  197. package/dist/structure/StructureInfoPane.svelte +7 -1
  198. package/dist/structure/StructureScene.svelte +104 -66
  199. package/dist/structure/StructureScene.svelte.d.ts +2 -1
  200. package/dist/structure/atom-properties.d.ts +6 -2
  201. package/dist/structure/atom-properties.js +38 -25
  202. package/dist/structure/export.js +10 -7
  203. package/dist/structure/ferrox-wasm-types.d.ts +3 -2
  204. package/dist/structure/ferrox-wasm-types.js +0 -3
  205. package/dist/structure/ferrox-wasm.d.ts +3 -2
  206. package/dist/structure/ferrox-wasm.js +1 -2
  207. package/dist/structure/index.d.ts +6 -0
  208. package/dist/structure/index.js +22 -0
  209. package/dist/structure/parse.js +19 -16
  210. package/dist/structure/partial-occupancy.d.ts +25 -0
  211. package/dist/structure/partial-occupancy.js +102 -0
  212. package/dist/structure/validation.js +6 -3
  213. package/dist/symmetry/SymmetryStats.svelte +18 -4
  214. package/dist/symmetry/WyckoffTable.svelte +18 -10
  215. package/dist/symmetry/index.d.ts +7 -4
  216. package/dist/symmetry/index.js +83 -18
  217. package/dist/table/HeatmapTable.svelte +425 -65
  218. package/dist/table/HeatmapTable.svelte.d.ts +12 -1
  219. package/dist/table/ToggleMenu.svelte +2 -0
  220. package/dist/table/index.d.ts +2 -0
  221. package/dist/trajectory/Trajectory.svelte +147 -145
  222. package/dist/trajectory/TrajectoryExportPane.svelte +13 -9
  223. package/dist/trajectory/TrajectoryExportPane.svelte.d.ts +1 -1
  224. package/dist/trajectory/constants.d.ts +6 -0
  225. package/dist/trajectory/constants.js +7 -0
  226. package/dist/trajectory/extract.js +3 -5
  227. package/dist/trajectory/format-detect.d.ts +9 -0
  228. package/dist/trajectory/format-detect.js +76 -0
  229. package/dist/trajectory/frame-reader.d.ts +17 -0
  230. package/dist/trajectory/frame-reader.js +339 -0
  231. package/dist/trajectory/helpers.d.ts +15 -0
  232. package/dist/trajectory/helpers.js +187 -0
  233. package/dist/trajectory/index.d.ts +1 -0
  234. package/dist/trajectory/index.js +11 -4
  235. package/dist/trajectory/parse/ase.d.ts +2 -0
  236. package/dist/trajectory/parse/ase.js +76 -0
  237. package/dist/trajectory/parse/hdf5.d.ts +2 -0
  238. package/dist/trajectory/parse/hdf5.js +121 -0
  239. package/dist/trajectory/parse/index.d.ts +12 -0
  240. package/dist/trajectory/parse/index.js +304 -0
  241. package/dist/trajectory/parse/lammps.d.ts +5 -0
  242. package/dist/trajectory/parse/lammps.js +169 -0
  243. package/dist/trajectory/parse/vasp.d.ts +2 -0
  244. package/dist/trajectory/parse/vasp.js +65 -0
  245. package/dist/trajectory/parse/xyz.d.ts +2 -0
  246. package/dist/trajectory/parse/xyz.js +109 -0
  247. package/dist/trajectory/types.d.ts +11 -0
  248. package/dist/trajectory/types.js +1 -0
  249. package/dist/utils.d.ts +2 -0
  250. package/dist/utils.js +4 -0
  251. package/dist/xrd/XrdPlot.svelte +6 -4
  252. package/dist/xrd/calc-xrd.js +0 -1
  253. package/package.json +30 -24
  254. package/readme.md +4 -4
  255. package/dist/trajectory/parse.d.ts +0 -42
  256. package/dist/trajectory/parse.js +0 -1267
  257. /package/dist/element/{data.json.d.ts → data.json.gz.d.ts} +0 -0
@@ -1,6 +1,6 @@
1
- <script lang="ts">import { getContext } from 'svelte';
1
+ <script lang="ts">import { getContext, tick } from 'svelte';
2
2
  import { JSON_TREE_CONTEXT_KEY } from './types';
3
- import { format_preview, is_css_color, is_url, values_equal } from './utils';
3
+ import { format_preview, is_css_color, is_url, parse_edited_value, values_equal, } from './utils';
4
4
  let { value, value_type, path, } = $props();
5
5
  const ctx = getContext(JSON_TREE_CONTEXT_KEY);
6
6
  // Track if value just changed for animation
@@ -36,10 +36,24 @@ let trimmed_str = $derived(value_type === `string` ? value.trim() : ``);
36
36
  let url_detected = $derived(value_type === `string` && is_url(trimmed_str));
37
37
  // Auto-detect CSS colors in string values
38
38
  let color_detected = $derived(value_type === `string` && is_css_color(trimmed_str) ? trimmed_str : null);
39
- // Handle click to copy
39
+ // Handle click to copy (delayed to avoid firing on double-click-to-edit)
40
+ let click_timer;
41
+ $effect(() => () => {
42
+ if (click_timer)
43
+ clearTimeout(click_timer);
44
+ });
40
45
  async function handle_click(event) {
41
46
  event.stopPropagation();
42
- if (ctx) {
47
+ if (!ctx)
48
+ return;
49
+ // When editable, delay copy so double-click can cancel it
50
+ if (ctx.settings.editable && ctx.onchange) {
51
+ if (click_timer)
52
+ clearTimeout(click_timer);
53
+ const copy_pos = { clientX: event.clientX, clientY: event.clientY };
54
+ click_timer = setTimeout(() => ctx.copy_value(path, value, copy_pos), 250);
55
+ }
56
+ else {
43
57
  await ctx.copy_value(path, value, event);
44
58
  }
45
59
  }
@@ -62,121 +76,179 @@ function toggle_expand(event) {
62
76
  event.stopPropagation();
63
77
  is_expanded = !is_expanded;
64
78
  }
79
+ // === Inline Editing ===
80
+ let editing = $state(false);
81
+ let edit_text = $state(``);
82
+ let edit_input = $state(null);
83
+ function start_edit(event) {
84
+ if (!ctx?.settings.editable || !ctx.onchange)
85
+ return;
86
+ event.stopPropagation();
87
+ // Cancel pending click-to-copy
88
+ if (click_timer)
89
+ clearTimeout(click_timer);
90
+ // Pre-fill with raw value (strings without quotes)
91
+ edit_text = value_type === `string` ? value : String(value);
92
+ editing = true;
93
+ tick().then(() => edit_input?.select());
94
+ }
95
+ function commit_edit() {
96
+ if (!editing)
97
+ return;
98
+ editing = false;
99
+ const new_value = parse_edited_value(edit_text);
100
+ if (!values_equal(new_value, value)) {
101
+ ctx?.onchange?.(path, new_value, value);
102
+ }
103
+ }
104
+ function handle_edit_keydown(event) {
105
+ if (event.key === `Enter`) {
106
+ event.preventDefault();
107
+ commit_edit();
108
+ }
109
+ else if (event.key === `Escape`) {
110
+ event.preventDefault();
111
+ editing = false;
112
+ }
113
+ }
65
114
  </script>
66
115
 
67
- <span
68
- class="json-value {value_type}"
69
- class:changed={just_changed}
70
- onclick={handle_click}
71
- oncontextmenu={(event) => {
72
- ctx?.show_context_menu(event, path, value, false, false)
73
- }}
74
- onkeydown={(event) => {
75
- if (event.key === `Enter` || event.key === ` `) {
76
- event.preventDefault()
77
- ctx?.copy_value(path, value)
78
- }
79
- }}
80
- role="button"
81
- tabindex="-1"
82
- title="Click to copy"
83
- >
84
- {#if color_detected}
85
- <span class="color-swatch" style:background={color_detected}></span>
86
- {/if}
87
- {#if url_detected}
88
- <a
89
- href={encodeURI(trimmed_str)}
90
- class="url-link"
91
- target="_blank"
92
- rel="noopener noreferrer"
93
- onclick={(event) => event.stopPropagation()}
94
- title="Open URL in new tab"
95
- >
116
+ {#if editing}
117
+ <!-- svelte-ignore a11y_autofocus -->
118
+ <input
119
+ bind:this={edit_input}
120
+ type="text"
121
+ class="edit-input {value_type}"
122
+ bind:value={edit_text}
123
+ onkeydown={handle_edit_keydown}
124
+ onblur={commit_edit}
125
+ style:width="{Math.max(edit_text.length + 2, 6)}ch"
126
+ autofocus
127
+ />
128
+ {:else}
129
+ <span
130
+ class="json-value {value_type}"
131
+ class:changed={just_changed}
132
+ class:editable={ctx?.settings.editable}
133
+ onclick={handle_click}
134
+ ondblclick={start_edit}
135
+ oncontextmenu={(event) => {
136
+ ctx?.show_context_menu(event, path, value, false, false)
137
+ }}
138
+ onkeydown={(event) => {
139
+ if (event.key === `Enter` || event.key === ` `) {
140
+ event.preventDefault()
141
+ ctx?.copy_value(path, value)
142
+ }
143
+ }}
144
+ role="button"
145
+ tabindex="-1"
146
+ title={ctx?.settings.editable ? `Double-click to edit` : undefined}
147
+ >
148
+ {#if color_detected}
149
+ <span class="color-swatch" style:background={color_detected}></span>
150
+ {/if}
151
+ {#if url_detected}
152
+ <a
153
+ href={encodeURI(trimmed_str)}
154
+ class="url-link"
155
+ target="_blank"
156
+ rel="noopener noreferrer"
157
+ onclick={(event) => event.stopPropagation()}
158
+ title="Open URL in new tab"
159
+ >
160
+ {display_value}
161
+ </a>
162
+ {:else}
96
163
  {display_value}
97
- </a>
98
- {:else}
99
- {display_value}
100
- {/if}
101
- {#if is_truncated}
102
- <button
103
- type="button"
104
- class="expand-btn"
105
- onclick={toggle_expand}
106
- title="Show full string"
107
- >
108
- ...
109
- </button>
110
- {:else if is_long_string && is_expanded}
111
- <button
112
- type="button"
113
- class="expand-btn"
114
- onclick={toggle_expand}
115
- title="Collapse string"
116
- >
117
-
118
- </button>
119
- {/if}
120
- {#if ctx?.settings.show_data_types && value_type !== `null` &&
164
+ {/if}
165
+ {#if is_truncated}
166
+ <button
167
+ type="button"
168
+ class="expand-btn"
169
+ onclick={toggle_expand}
170
+ title="Show full string"
171
+ >
172
+ ...
173
+ </button>
174
+ {:else if is_long_string && is_expanded}
175
+ <button
176
+ type="button"
177
+ class="expand-btn"
178
+ onclick={toggle_expand}
179
+ title="Collapse string"
180
+ >
181
+
182
+ </button>
183
+ {/if}
184
+ {#if ctx?.settings.show_data_types && value_type !== `null` &&
121
185
  value_type !== `undefined`}
122
- <span class="type-annotation">{value_type}</span>
123
- {/if}
124
- </span>
186
+ <span class="type-annotation">{value_type}</span>
187
+ {/if}
188
+ </span>
189
+ {/if}
125
190
 
126
191
  <style>
192
+ /* Type-specific colors shared between display and edit input */
193
+ :is(.json-value, .edit-input) {
194
+ &.string {
195
+ color: var(--jt-string, light-dark(#a31515, #ce9178));
196
+ }
197
+ &.number {
198
+ color: var(--jt-number, light-dark(#098658, #b5cea8));
199
+ }
200
+ &.boolean {
201
+ color: var(--jt-boolean, light-dark(#0000ff, #569cd6));
202
+ }
203
+ &.null {
204
+ color: var(--jt-null, light-dark(#808080, #808080));
205
+ }
206
+ }
127
207
  .json-value {
128
208
  cursor: pointer;
129
209
  border-radius: 2px;
130
210
  transition: background-color 0.15s, color 0.15s;
131
- }
132
- .json-value:hover {
133
- background: var(
134
- --jt-hover-bg,
135
- light-dark(rgba(0, 0, 0, 0.05), rgba(255, 255, 255, 0.08))
136
- );
137
- }
138
- /* Type-specific colors */
139
- .json-value.string {
140
- color: var(--jt-string, light-dark(#a31515, #ce9178));
141
- word-break: break-word;
142
- }
143
- .json-value.number {
144
- color: var(--jt-number, light-dark(#098658, #b5cea8));
145
- }
146
- .json-value.boolean {
147
- color: var(--jt-boolean, light-dark(#0000ff, #569cd6));
148
- }
149
- .json-value.null,
150
- .json-value.undefined {
151
- color: var(--jt-null, light-dark(#808080, #808080));
152
- font-style: italic;
153
- }
154
- .json-value.date {
155
- color: var(--jt-date, light-dark(#098658, #dcdcaa));
156
- }
157
- .json-value.regexp {
158
- color: var(--jt-regexp, light-dark(#811f3f, #d16969));
159
- }
160
- .json-value.symbol {
161
- color: var(--jt-symbol, light-dark(#267f99, #4ec9b0));
162
- }
163
- .json-value.bigint {
164
- color: var(--jt-bigint, light-dark(#098658, #b5cea8));
165
- }
166
- .json-value.function {
167
- color: var(--jt-function, light-dark(#795e26, #dcdcaa));
168
- font-style: italic;
169
- }
170
- .json-value.error {
171
- color: var(--jt-error, light-dark(#a31515, #f48771));
172
- }
173
- .json-value.circular {
174
- color: var(--jt-circular, light-dark(#808080, #808080));
175
- font-style: italic;
176
- }
177
- /* Change animation */
178
- .json-value.changed {
179
- animation: value-change 1s ease-out;
211
+ &:hover {
212
+ background: var(
213
+ --jt-hover-bg,
214
+ light-dark(rgba(0, 0, 0, 0.05), rgba(255, 255, 255, 0.08))
215
+ );
216
+ }
217
+ &.string {
218
+ word-break: break-word;
219
+ }
220
+ &:is(.null, .undefined) {
221
+ font-style: italic;
222
+ }
223
+ &.date {
224
+ color: var(--jt-date, light-dark(#098658, #dcdcaa));
225
+ }
226
+ &.regexp {
227
+ color: var(--jt-regexp, light-dark(#811f3f, #d16969));
228
+ }
229
+ &.symbol {
230
+ color: var(--jt-symbol, light-dark(#267f99, #4ec9b0));
231
+ }
232
+ &.bigint {
233
+ color: var(--jt-bigint, light-dark(#098658, #b5cea8));
234
+ }
235
+ &.function {
236
+ color: var(--jt-function, light-dark(#795e26, #dcdcaa));
237
+ font-style: italic;
238
+ }
239
+ &.error {
240
+ color: var(--jt-error, light-dark(#a31515, #f48771));
241
+ }
242
+ &.circular {
243
+ color: var(--jt-circular, light-dark(#808080, #808080));
244
+ font-style: italic;
245
+ }
246
+ &.changed {
247
+ animation: value-change 1s ease-out;
248
+ }
249
+ &.editable {
250
+ cursor: default;
251
+ }
180
252
  }
181
253
  @keyframes value-change {
182
254
  0% {
@@ -186,7 +258,6 @@ function toggle_expand(event) {
186
258
  background: transparent;
187
259
  }
188
260
  }
189
- /* Expand/collapse button for long strings */
190
261
  .expand-btn {
191
262
  display: inline;
192
263
  background: none;
@@ -196,11 +267,10 @@ function toggle_expand(event) {
196
267
  font-size: 0.85em;
197
268
  padding: 0 2px;
198
269
  margin-left: 2px;
270
+ &:hover {
271
+ text-decoration: underline;
272
+ }
199
273
  }
200
- .expand-btn:hover {
201
- text-decoration: underline;
202
- }
203
- /* Type annotation */
204
274
  .type-annotation {
205
275
  font-size: 0.7em;
206
276
  color: var(--jt-type-annotation, light-dark(#808080, #6a6a6a));
@@ -210,9 +280,19 @@ function toggle_expand(event) {
210
280
  .url-link {
211
281
  color: var(--jt-url, light-dark(#0066cc, #4fc3f7));
212
282
  text-decoration: none;
283
+ &:hover {
284
+ text-decoration: underline;
285
+ }
213
286
  }
214
- .url-link:hover {
215
- text-decoration: underline;
287
+ .edit-input {
288
+ font: inherit;
289
+ font-family: var(--jt-font-family, 'SF Mono', Monaco, 'Courier New', monospace);
290
+ padding: 0 2px;
291
+ border: 1px solid var(--jt-edit-border, light-dark(#4a90d9, #4a90d9));
292
+ border-radius: 2px;
293
+ background: var(--jt-edit-bg, light-dark(#fff, #1a1a2e));
294
+ outline: none;
295
+ min-width: 4ch;
216
296
  }
217
297
  .color-swatch {
218
298
  display: inline-block;
@@ -16,6 +16,8 @@ export interface JsonTreeProps {
16
16
  oncopy?: (path: string, value: string) => void;
17
17
  download_filename?: string;
18
18
  compare_value?: unknown;
19
+ editable?: boolean;
20
+ onchange?: (path: string, new_value: unknown, old_value: unknown) => void;
19
21
  }
20
22
  export interface JsonTreeContext {
21
23
  settings: {
@@ -27,6 +29,7 @@ export interface JsonTreeContext {
27
29
  sort_keys: boolean;
28
30
  max_string_length: number;
29
31
  highlight_changes: boolean;
32
+ editable: boolean;
30
33
  };
31
34
  collapsed: Set<string>;
32
35
  force_expanded: Set<string>;
@@ -41,8 +44,8 @@ export interface JsonTreeContext {
41
44
  collapse_all: () => void;
42
45
  collapse_to_level: (level: number) => void;
43
46
  set_focused: (path: string | null) => void;
44
- copy_value: (path: string, value: unknown, event?: MouseEvent) => Promise<void>;
45
- copy_path: (path: string, event?: MouseEvent) => Promise<void>;
47
+ copy_value: (path: string, value: unknown, event?: CopyEventPosition) => Promise<void>;
48
+ copy_path: (path: string, event?: CopyEventPosition) => Promise<void>;
46
49
  register_path: (path: string) => void;
47
50
  unregister_path: (path: string) => void;
48
51
  show_context_menu: (event: MouseEvent, path: string, value: unknown, expandable: boolean, is_collapsed: boolean) => void;
@@ -54,7 +57,12 @@ export interface JsonTreeContext {
54
57
  diff_map: Map<string, DiffEntry> | null;
55
58
  ghost_map: Map<string, import('./utils').GhostEntry[]>;
56
59
  collapse_children_only: (path: string) => void;
60
+ onchange?: (path: string, new_value: unknown, old_value: unknown) => void;
57
61
  }
62
+ export type CopyEventPosition = {
63
+ clientX: number;
64
+ clientY: number;
65
+ };
58
66
  export declare const JSON_TREE_CONTEXT_KEY: unique symbol;
59
67
  export type DiffStatus = `added` | `removed` | `changed`;
60
68
  export interface DiffEntry {
@@ -14,6 +14,8 @@ export declare function find_matching_paths(value: unknown, query: string, curre
14
14
  export declare function get_ancestor_paths(path: string): string[];
15
15
  export declare function parse_path(path: string): (string | number)[];
16
16
  export declare function values_equal(val_a: unknown, val_b: unknown): boolean;
17
+ export declare function parse_edited_value(text: string): unknown;
18
+ export declare function set_at_path(root: unknown, path_str: string, new_value: unknown, root_label?: string): unknown;
17
19
  export declare function is_url(str: string): boolean;
18
20
  export declare function is_css_color(str: string): boolean;
19
21
  export declare function estimate_byte_size(value: unknown, max_depth?: number, current_depth?: number): number;
@@ -390,6 +390,39 @@ export function values_equal(val_a, val_b) {
390
390
  }
391
391
  return false;
392
392
  }
393
+ // Parse a raw edited string into a typed JSON value
394
+ // Numbers, booleans, and null are auto-detected; everything else stays as string
395
+ export function parse_edited_value(text) {
396
+ const trimmed = text.trim();
397
+ if (trimmed === `null`)
398
+ return null;
399
+ if (trimmed === `true`)
400
+ return true;
401
+ if (trimmed === `false`)
402
+ return false;
403
+ const num = Number(trimmed);
404
+ if (trimmed !== `` && Number.isFinite(num))
405
+ return num;
406
+ return text;
407
+ }
408
+ // Set a value at a dot/bracket path in a deep-cloned copy of root
409
+ // root_label is stripped from the path prefix if present
410
+ export function set_at_path(root, path_str, new_value, root_label) {
411
+ const segments = parse_path(path_str);
412
+ const start = root_label && segments[0] === root_label ? 1 : 0;
413
+ if (start >= segments.length)
414
+ return new_value;
415
+ const cloned = JSON.parse(JSON.stringify(root));
416
+ let current = cloned;
417
+ for (let idx = start; idx < segments.length - 1; idx++) {
418
+ const next = current[segments[idx]];
419
+ if (next === undefined || next === null)
420
+ return root; // bail — path no longer valid
421
+ current = next;
422
+ }
423
+ current[segments[segments.length - 1]] = new_value;
424
+ return cloned;
425
+ }
393
426
  // URL regex for auto-detection in string values
394
427
  const URL_RE = /^https?:\/\/\S+$/;
395
428
  // CSS color patterns for swatch rendering
package/dist/math.d.ts CHANGED
@@ -34,6 +34,7 @@ export type Matrix4Tuple = [
34
34
  number,
35
35
  number
36
36
  ];
37
+ export declare function combinations<T>(arr: T[], k: number): T[][];
37
38
  export declare const LOG_EPS = 1e-9;
38
39
  export declare const EPS = 1e-10;
39
40
  export declare const RAD_TO_DEG: number;
@@ -71,8 +72,11 @@ export declare const cross_3d: (vec1: Vec3, vec2: Vec3) => Vec3;
71
72
  export declare const lerp: (start: number, end: number, t: number) => number;
72
73
  export declare const lerp_vec3: (start: Vec3, end: Vec3, t: number) => Vec3;
73
74
  export declare const centered_frac: (val: number) => number;
75
+ export declare const vecs_equal: (vec_a?: Vec3, vec_b?: Vec3) => boolean;
74
76
  export declare function normalize_vec3(vec: Vec3, fallback?: Vec3): Vec3;
75
77
  export declare function compute_in_plane_basis(normal: Vec3): [Vec3, Vec3];
78
+ export declare function are_coplanar(points: number[][], tolerance?: number): boolean;
79
+ export declare function merge_coplanar_triangles(positions: Float32Array, tolerance?: number): Float32Array;
76
80
  export declare function compute_bounding_box(vertices: Vec3[]): {
77
81
  min: Vec3;
78
82
  max: Vec3;
@@ -86,3 +90,6 @@ export declare function compute_bounding_box_2d(vertices: Vec2[]): {
86
90
  height: number;
87
91
  };
88
92
  export declare function polygon_centroid(vertices: Vec2[]): Vec2;
93
+ export declare function solve_linear_system(A: number[][], // NxN coefficient matrix
94
+ b: number[]): number[] | null;
95
+ export declare function convex_hull_2d(points: Vec2[]): Vec2[];