matterviz 0.3.2 → 0.3.3

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 (280) hide show
  1. package/dist/EmptyState.svelte +10 -2
  2. package/dist/FilePicker.svelte +123 -82
  3. package/dist/Icon.svelte +18 -12
  4. package/dist/MillerIndexInput.svelte +27 -21
  5. package/dist/api/optimade.js +6 -6
  6. package/dist/app.css +216 -207
  7. package/dist/brillouin/BrillouinZone.svelte +292 -149
  8. package/dist/brillouin/BrillouinZone.svelte.d.ts +1 -1
  9. package/dist/brillouin/BrillouinZoneControls.svelte +32 -5
  10. package/dist/brillouin/BrillouinZoneExportPane.svelte +69 -42
  11. package/dist/brillouin/BrillouinZoneExportPane.svelte.d.ts +1 -1
  12. package/dist/brillouin/BrillouinZoneInfoPane.svelte +99 -68
  13. package/dist/brillouin/BrillouinZoneScene.svelte +275 -163
  14. package/dist/brillouin/BrillouinZoneScene.svelte.d.ts +1 -1
  15. package/dist/brillouin/BrillouinZoneTooltip.svelte +17 -7
  16. package/dist/brillouin/compute.js +11 -6
  17. package/dist/chempot-diagram/ChemPotDiagram.svelte +162 -27
  18. package/dist/chempot-diagram/ChemPotDiagram2D.svelte +451 -281
  19. package/dist/chempot-diagram/ChemPotDiagram3D.svelte +2148 -1642
  20. package/dist/chempot-diagram/ChemPotScene3D.svelte +8 -5
  21. package/dist/chempot-diagram/async-compute.svelte.d.ts +3 -0
  22. package/dist/chempot-diagram/async-compute.svelte.js +77 -0
  23. package/dist/chempot-diagram/chempot-worker.d.ts +1 -0
  24. package/dist/chempot-diagram/chempot-worker.js +11 -0
  25. package/dist/chempot-diagram/color.js +1 -2
  26. package/dist/chempot-diagram/compute.d.ts +10 -0
  27. package/dist/chempot-diagram/compute.js +250 -88
  28. package/dist/chempot-diagram/index.d.ts +2 -1
  29. package/dist/chempot-diagram/index.js +2 -1
  30. package/dist/chempot-diagram/temperature.js +8 -9
  31. package/dist/chempot-diagram/types.d.ts +3 -0
  32. package/dist/chempot-diagram/types.js +1 -0
  33. package/dist/colors/index.d.ts +1 -1
  34. package/dist/colors/index.js +5 -3
  35. package/dist/composition/BarChart.svelte +128 -55
  36. package/dist/composition/BubbleChart.svelte +102 -49
  37. package/dist/composition/Composition.svelte +100 -79
  38. package/dist/composition/Formula.svelte +108 -62
  39. package/dist/composition/FormulaFilter.svelte +665 -537
  40. package/dist/composition/PieChart.svelte +183 -108
  41. package/dist/composition/format.d.ts +5 -0
  42. package/dist/composition/format.js +20 -3
  43. package/dist/composition/parse.js +14 -9
  44. package/dist/convex-hull/ConvexHull.svelte +93 -40
  45. package/dist/convex-hull/ConvexHull.svelte.d.ts +1 -1
  46. package/dist/convex-hull/ConvexHull2D.svelte +549 -360
  47. package/dist/convex-hull/ConvexHull2D.svelte.d.ts +1 -1
  48. package/dist/convex-hull/ConvexHull3D.svelte +1296 -827
  49. package/dist/convex-hull/ConvexHull3D.svelte.d.ts +1 -1
  50. package/dist/convex-hull/ConvexHull4D.svelte +1004 -688
  51. package/dist/convex-hull/ConvexHull4D.svelte.d.ts +1 -1
  52. package/dist/convex-hull/ConvexHullControls.svelte +115 -28
  53. package/dist/convex-hull/ConvexHullControls.svelte.d.ts +1 -1
  54. package/dist/convex-hull/ConvexHullInfoPane.svelte +29 -3
  55. package/dist/convex-hull/ConvexHullStats.svelte +425 -328
  56. package/dist/convex-hull/ConvexHullTooltip.svelte +40 -16
  57. package/dist/convex-hull/GasPressureControls.svelte +104 -61
  58. package/dist/convex-hull/StructurePopup.svelte +25 -4
  59. package/dist/convex-hull/TemperatureSlider.svelte +45 -25
  60. package/dist/convex-hull/barycentric-coords.js +13 -7
  61. package/dist/convex-hull/demo-temperature.js +8 -4
  62. package/dist/convex-hull/gas-thermodynamics.js +17 -12
  63. package/dist/convex-hull/helpers.d.ts +9 -0
  64. package/dist/convex-hull/helpers.js +77 -34
  65. package/dist/convex-hull/thermodynamics.js +61 -56
  66. package/dist/convex-hull/types.d.ts +9 -14
  67. package/dist/convex-hull/types.js +0 -17
  68. package/dist/coordination/CoordinationBarPlot.svelte +227 -154
  69. package/dist/element/BohrAtom.svelte +55 -12
  70. package/dist/element/ElementHeading.svelte +7 -2
  71. package/dist/element/ElementPhoto.svelte +15 -9
  72. package/dist/element/ElementStats.svelte +10 -4
  73. package/dist/element/ElementTile.svelte +137 -73
  74. package/dist/element/Nucleus.svelte +39 -11
  75. package/dist/feedback/ClickFeedback.svelte +16 -5
  76. package/dist/feedback/DragOverlay.svelte +10 -2
  77. package/dist/feedback/Spinner.svelte +4 -2
  78. package/dist/feedback/StatusMessage.svelte +8 -2
  79. package/dist/fermi-surface/FermiSlice.svelte +118 -88
  80. package/dist/fermi-surface/FermiSurface.svelte +328 -187
  81. package/dist/fermi-surface/FermiSurface.svelte.d.ts +1 -1
  82. package/dist/fermi-surface/FermiSurfaceControls.svelte +113 -46
  83. package/dist/fermi-surface/FermiSurfaceControls.svelte.d.ts +1 -1
  84. package/dist/fermi-surface/FermiSurfaceScene.svelte +535 -342
  85. package/dist/fermi-surface/FermiSurfaceScene.svelte.d.ts +1 -1
  86. package/dist/fermi-surface/FermiSurfaceTooltip.svelte +14 -5
  87. package/dist/fermi-surface/compute.js +16 -20
  88. package/dist/fermi-surface/parse.js +24 -14
  89. package/dist/fermi-surface/symmetry.js +2 -7
  90. package/dist/fermi-surface/types.d.ts +3 -5
  91. package/dist/heatmap-matrix/HeatmapMatrix.svelte +1019 -765
  92. package/dist/heatmap-matrix/HeatmapMatrix.svelte.d.ts +1 -1
  93. package/dist/heatmap-matrix/HeatmapMatrixControls.svelte +76 -22
  94. package/dist/heatmap-matrix/HeatmapMatrixControls.svelte.d.ts +2 -3
  95. package/dist/icons.js +47 -0
  96. package/dist/index.d.ts +2 -1
  97. package/dist/index.js +2 -1
  98. package/dist/io/decompress.js +1 -1
  99. package/dist/io/export.d.ts +3 -0
  100. package/dist/io/export.js +129 -143
  101. package/dist/io/is-binary.js +2 -3
  102. package/dist/io/url-drop.js +1 -2
  103. package/dist/isosurface/Isosurface.svelte +202 -148
  104. package/dist/isosurface/IsosurfaceControls.svelte +46 -28
  105. package/dist/isosurface/parse.js +34 -29
  106. package/dist/isosurface/slice.js +5 -10
  107. package/dist/isosurface/types.d.ts +2 -1
  108. package/dist/isosurface/types.js +61 -12
  109. package/dist/labels.js +11 -8
  110. package/dist/layout/FullscreenToggle.svelte +11 -2
  111. package/dist/layout/InfoCard.svelte +38 -6
  112. package/dist/layout/InfoTag.svelte +63 -32
  113. package/dist/layout/PropertyFilter.svelte +82 -37
  114. package/dist/layout/SettingsSection.svelte +85 -55
  115. package/dist/layout/SubpageGrid.svelte +10 -2
  116. package/dist/layout/json-tree/JsonNode.svelte +183 -138
  117. package/dist/layout/json-tree/JsonTree.svelte +499 -413
  118. package/dist/layout/json-tree/JsonValue.svelte +127 -99
  119. package/dist/layout/json-tree/utils.js +4 -2
  120. package/dist/marching-cubes.js +25 -2
  121. package/dist/math.d.ts +13 -17
  122. package/dist/math.js +133 -67
  123. package/dist/overlays/ContextMenu.svelte +65 -40
  124. package/dist/overlays/DraggablePane.svelte +211 -139
  125. package/dist/periodic-table/PeriodicTable.svelte +278 -145
  126. package/dist/periodic-table/PeriodicTableControls.svelte +178 -128
  127. package/dist/periodic-table/PropertySelect.svelte +25 -7
  128. package/dist/periodic-table/TableInset.svelte +8 -3
  129. package/dist/phase-diagram/IsobaricBinaryPhaseDiagram.svelte +446 -309
  130. package/dist/phase-diagram/IsobaricBinaryPhaseDiagram.svelte.d.ts +1 -1
  131. package/dist/phase-diagram/PhaseDiagramControls.svelte +102 -43
  132. package/dist/phase-diagram/PhaseDiagramControls.svelte.d.ts +1 -1
  133. package/dist/phase-diagram/PhaseDiagramEditorPane.svelte +63 -40
  134. package/dist/phase-diagram/PhaseDiagramExportPane.svelte +71 -28
  135. package/dist/phase-diagram/PhaseDiagramExportPane.svelte.d.ts +1 -1
  136. package/dist/phase-diagram/PhaseDiagramTooltip.svelte +158 -101
  137. package/dist/phase-diagram/TdbInfoPanel.svelte +28 -4
  138. package/dist/phase-diagram/build-diagram.js +9 -9
  139. package/dist/phase-diagram/colors.js +1 -3
  140. package/dist/phase-diagram/parse.js +10 -9
  141. package/dist/phase-diagram/svg-to-diagram.js +53 -49
  142. package/dist/phase-diagram/utils.d.ts +1 -0
  143. package/dist/phase-diagram/utils.js +80 -25
  144. package/dist/plot/AxisLabel.svelte +28 -3
  145. package/dist/plot/BarPlot.svelte +1182 -734
  146. package/dist/plot/BarPlot.svelte.d.ts +2 -2
  147. package/dist/plot/BarPlotControls.svelte +31 -5
  148. package/dist/plot/BarPlotControls.svelte.d.ts +1 -1
  149. package/dist/plot/ColorBar.svelte +479 -329
  150. package/dist/plot/ColorScaleSelect.svelte +27 -6
  151. package/dist/plot/ElementScatter.svelte +36 -15
  152. package/dist/plot/FillArea.svelte +152 -95
  153. package/dist/plot/Histogram.svelte +934 -571
  154. package/dist/plot/Histogram.svelte.d.ts +1 -1
  155. package/dist/plot/HistogramControls.svelte +53 -9
  156. package/dist/plot/HistogramControls.svelte.d.ts +1 -1
  157. package/dist/plot/InteractiveAxisLabel.svelte +34 -11
  158. package/dist/plot/InteractiveAxisLabel.svelte.d.ts +1 -1
  159. package/dist/plot/Line.svelte +63 -28
  160. package/dist/plot/PlotControls.svelte +157 -114
  161. package/dist/plot/PlotControls.svelte.d.ts +1 -1
  162. package/dist/plot/PlotLegend.svelte +174 -91
  163. package/dist/plot/PlotTooltip.svelte +45 -6
  164. package/dist/plot/PortalSelect.svelte +175 -147
  165. package/dist/plot/ReferenceLine.svelte +76 -22
  166. package/dist/plot/ReferenceLine3D.svelte +132 -107
  167. package/dist/plot/ReferencePlane.svelte +146 -121
  168. package/dist/plot/ScatterPlot.svelte +1681 -1091
  169. package/dist/plot/ScatterPlot.svelte.d.ts +2 -2
  170. package/dist/plot/ScatterPlot3D.svelte +256 -131
  171. package/dist/plot/ScatterPlot3D.svelte.d.ts +2 -2
  172. package/dist/plot/ScatterPlot3DControls.svelte +113 -63
  173. package/dist/plot/ScatterPlot3DControls.svelte.d.ts +2 -1
  174. package/dist/plot/ScatterPlot3DScene.svelte +608 -403
  175. package/dist/plot/ScatterPlot3DScene.svelte.d.ts +2 -2
  176. package/dist/plot/ScatterPlotControls.svelte +65 -25
  177. package/dist/plot/ScatterPlotControls.svelte.d.ts +1 -1
  178. package/dist/plot/ScatterPoint.svelte +98 -26
  179. package/dist/plot/ScatterPoint.svelte.d.ts +1 -0
  180. package/dist/plot/SpacegroupBarPlot.svelte +142 -85
  181. package/dist/plot/Surface3D.svelte +159 -108
  182. package/dist/plot/ZeroLines.svelte +55 -3
  183. package/dist/plot/ZoomRect.svelte +4 -2
  184. package/dist/plot/axis-utils.js +1 -3
  185. package/dist/plot/data-cleaning.js +12 -28
  186. package/dist/plot/data-transform.js +2 -1
  187. package/dist/plot/fill-utils.js +2 -0
  188. package/dist/plot/layout.d.ts +4 -1
  189. package/dist/plot/layout.js +33 -14
  190. package/dist/plot/reference-line.d.ts +2 -2
  191. package/dist/plot/reference-line.js +7 -5
  192. package/dist/plot/scales.js +24 -36
  193. package/dist/plot/types.d.ts +11 -23
  194. package/dist/plot/types.js +6 -11
  195. package/dist/plot/utils/label-placement.d.ts +32 -15
  196. package/dist/plot/utils/label-placement.js +227 -66
  197. package/dist/plot/utils/series-visibility.js +2 -3
  198. package/dist/rdf/RdfPlot.svelte +143 -91
  199. package/dist/rdf/calc-rdf.js +4 -5
  200. package/dist/sanitize.d.ts +4 -0
  201. package/dist/sanitize.js +107 -0
  202. package/dist/settings.d.ts +18 -6
  203. package/dist/settings.js +46 -16
  204. package/dist/spectral/Bands.svelte +632 -453
  205. package/dist/spectral/BandsAndDos.svelte +90 -49
  206. package/dist/spectral/BrillouinBandsDos.svelte +151 -93
  207. package/dist/spectral/Dos.svelte +389 -258
  208. package/dist/spectral/helpers.js +55 -43
  209. package/dist/state.svelte.d.ts +1 -1
  210. package/dist/state.svelte.js +3 -2
  211. package/dist/structure/Arrow.svelte +59 -20
  212. package/dist/structure/AtomLegend.svelte +215 -134
  213. package/dist/structure/Bond.svelte +73 -47
  214. package/dist/structure/CanvasTooltip.svelte +10 -2
  215. package/dist/structure/CellSelect.svelte +72 -45
  216. package/dist/structure/Cylinder.svelte +33 -17
  217. package/dist/structure/Lattice.svelte +88 -33
  218. package/dist/structure/Structure.svelte +1063 -797
  219. package/dist/structure/Structure.svelte.d.ts +1 -1
  220. package/dist/structure/StructureControls.svelte +349 -118
  221. package/dist/structure/StructureExportPane.svelte +124 -89
  222. package/dist/structure/StructureExportPane.svelte.d.ts +1 -1
  223. package/dist/structure/StructureInfoPane.svelte +304 -237
  224. package/dist/structure/StructureScene.svelte +879 -443
  225. package/dist/structure/StructureScene.svelte.d.ts +15 -7
  226. package/dist/structure/atom-properties.js +8 -8
  227. package/dist/structure/bonding.js +6 -7
  228. package/dist/structure/export.js +14 -29
  229. package/dist/structure/ferrox-wasm.js +1 -1
  230. package/dist/structure/index.d.ts +13 -3
  231. package/dist/structure/index.js +83 -23
  232. package/dist/structure/measure.d.ts +2 -2
  233. package/dist/structure/measure.js +4 -44
  234. package/dist/structure/parse.js +113 -141
  235. package/dist/structure/partial-occupancy.js +7 -10
  236. package/dist/structure/pbc.d.ts +1 -0
  237. package/dist/structure/pbc.js +16 -6
  238. package/dist/structure/supercell.d.ts +2 -2
  239. package/dist/structure/supercell.js +12 -22
  240. package/dist/structure/validation.js +1 -2
  241. package/dist/symmetry/SymmetryStats.svelte +84 -41
  242. package/dist/symmetry/WyckoffTable.svelte +26 -6
  243. package/dist/symmetry/cell-transform.js +5 -3
  244. package/dist/symmetry/index.js +8 -7
  245. package/dist/symmetry/spacegroups.js +148 -148
  246. package/dist/table/HeatmapTable.svelte +790 -554
  247. package/dist/table/HeatmapTable.svelte.d.ts +1 -1
  248. package/dist/table/ToggleMenu.svelte +125 -92
  249. package/dist/table/index.js +2 -4
  250. package/dist/theme/ThemeControl.svelte +21 -12
  251. package/dist/time.js +4 -1
  252. package/dist/tooltip/TooltipContent.svelte +33 -8
  253. package/dist/trajectory/Trajectory.svelte +758 -558
  254. package/dist/trajectory/TrajectoryError.svelte +14 -3
  255. package/dist/trajectory/TrajectoryExportPane.svelte +137 -83
  256. package/dist/trajectory/TrajectoryInfoPane.svelte +272 -143
  257. package/dist/trajectory/extract.js +10 -26
  258. package/dist/trajectory/format-detect.js +5 -5
  259. package/dist/trajectory/frame-reader.d.ts +1 -1
  260. package/dist/trajectory/frame-reader.js +5 -12
  261. package/dist/trajectory/helpers.d.ts +0 -1
  262. package/dist/trajectory/helpers.js +2 -17
  263. package/dist/trajectory/index.js +14 -12
  264. package/dist/trajectory/parse/ase.js +5 -4
  265. package/dist/trajectory/parse/hdf5.js +26 -18
  266. package/dist/trajectory/parse/index.js +13 -18
  267. package/dist/trajectory/parse/lammps.js +17 -7
  268. package/dist/trajectory/parse/vasp.js +5 -2
  269. package/dist/trajectory/parse/xyz.js +8 -7
  270. package/dist/trajectory/plotting.js +13 -8
  271. package/dist/utils.d.ts +1 -0
  272. package/dist/utils.js +13 -0
  273. package/dist/xrd/XrdPlot.svelte +337 -247
  274. package/dist/xrd/broadening.js +14 -9
  275. package/dist/xrd/calc-xrd.js +12 -18
  276. package/dist/xrd/parse.d.ts +1 -1
  277. package/dist/xrd/parse.js +17 -17
  278. package/package.json +99 -103
  279. package/readme.md +1 -1
  280. /package/dist/theme/{themes.js → themes.mjs} +0 -0
@@ -1,64 +1,94 @@
1
- <script lang="ts">import Icon from '../Icon.svelte';
2
- import { untrack } from 'svelte';
3
- let { title, current_values, children, on_reset = () => { }, ...rest } = $props();
4
- // Create a deep copy of current_values on mount to use as reference values
5
- function deep_copy(obj) {
6
- if (obj === null || typeof obj !== `object`)
7
- return obj;
8
- if (obj instanceof Date)
9
- return new Date(obj.getTime());
10
- if (obj instanceof RegExp)
11
- return new RegExp(obj);
1
+ <script lang="ts">
2
+ import Icon from '../Icon.svelte'
3
+ import type { Snippet } from 'svelte'
4
+ import { untrack } from 'svelte'
5
+ import type { HTMLAttributes } from 'svelte/elements'
6
+
7
+ let {
8
+ title,
9
+ current_values,
10
+ children,
11
+ on_reset = () => {},
12
+ ...rest
13
+ }: HTMLAttributes<HTMLElementTagNameMap[`section`]> & {
14
+ title: string
15
+ current_values: Record<string, unknown>
16
+ children: Snippet<
17
+ [{
18
+ current_values: Record<string, unknown>
19
+ has_changes: boolean
20
+ reference_values: Record<string, unknown>
21
+ }]
22
+ >
23
+ on_reset?: () => void
24
+ } = $props()
25
+
26
+ // Create a deep copy of current_values on mount to use as reference values
27
+ function deep_copy(obj: unknown): unknown {
28
+ if (obj === null || typeof obj !== `object`) return obj
29
+ if (obj instanceof Date) return new Date(obj.getTime())
30
+ if (obj instanceof RegExp) return new RegExp(obj)
12
31
  if (Array.isArray(obj)) {
13
- return obj.map((item) => typeof item === `object` && item !== null ? deep_copy(item) : item);
32
+ return obj.map((item) =>
33
+ typeof item === `object` && item !== null ? deep_copy(item) : item
34
+ )
14
35
  }
15
- const copy = {};
16
- for (const [key, value] of Object.entries(obj)) {
17
- copy[key] = typeof value === `object` && value !== null
18
- ? deep_copy(value)
19
- : value;
36
+
37
+ const copy: Record<string, unknown> = {}
38
+ for (const [key, value] of Object.entries(obj as Record<string, unknown>)) {
39
+ copy[key] = typeof value === `object` && value !== null
40
+ ? deep_copy(value)
41
+ : value
20
42
  }
21
- return copy;
22
- }
23
- // Capture initial values once at mount - must NOT be $derived or it tracks changes
24
- const reference_values = untrack(() => deep_copy(current_values));
25
- // Check if any values have changed from reference values
26
- let has_changes = $derived.by(() => {
43
+ return copy
44
+ }
45
+
46
+ // Capture initial values once at mount - must NOT be $derived or it tracks changes
47
+ const reference_values = untrack(() =>
48
+ deep_copy(current_values) as Record<string, unknown>
49
+ )
50
+
51
+ // Check if any values have changed from reference values
52
+ let has_changes = $derived.by(() => {
27
53
  for (const [key, reference_value] of Object.entries(reference_values)) {
28
- const current_value = current_values[key];
29
- // Deep comparison for arrays
30
- if (Array.isArray(reference_value) && Array.isArray(current_value)) {
31
- if (reference_value.length !== current_value.length)
32
- return true;
33
- if (reference_value.some((val, idx) => {
34
- const curr_val = current_value[idx];
35
- // Handle nested objects/arrays in arrays
36
- if (typeof val === `object` && val !== null &&
37
- typeof curr_val === `object` && curr_val !== null)
38
- return JSON.stringify(val) !== JSON.stringify(curr_val); // Quick deep comparison fallback
39
- return val !== curr_val;
40
- })) {
41
- return true;
42
- }
43
- continue;
44
- }
45
- // Handle undefined/null comparisons properly
46
- if (reference_value === undefined && current_value === undefined)
47
- continue;
48
- if (reference_value === null && current_value === null)
49
- continue;
50
- // Basic comparison for primitives
51
- if (current_value !== reference_value) {
52
- return true;
54
+ const current_value = current_values[key]
55
+
56
+ // Deep comparison for arrays
57
+ if (Array.isArray(reference_value) && Array.isArray(current_value)) {
58
+ if (reference_value.length !== current_value.length) return true
59
+ if (
60
+ reference_value.some((val, idx) => {
61
+ const curr_val = current_value[idx]
62
+ // Handle nested objects/arrays in arrays
63
+ if (
64
+ typeof val === `object` && val !== null &&
65
+ typeof curr_val === `object` && curr_val !== null
66
+ ) return JSON.stringify(val) !== JSON.stringify(curr_val) // Quick deep comparison fallback
67
+ return val !== curr_val
68
+ })
69
+ ) {
70
+ return true
53
71
  }
72
+ continue
73
+ }
74
+
75
+ // Handle undefined/null comparisons properly
76
+ if (reference_value === undefined && current_value === undefined) continue
77
+ if (reference_value === null && current_value === null) continue
78
+
79
+ // Basic comparison for primitives
80
+ if (current_value !== reference_value) {
81
+ return true
82
+ }
54
83
  }
55
- return false;
56
- });
57
- function handle_reset(event) {
58
- event.stopPropagation();
59
- event.preventDefault();
60
- on_reset();
61
- }
84
+ return false
85
+ })
86
+
87
+ function handle_reset(event: MouseEvent) {
88
+ event.stopPropagation()
89
+ event.preventDefault()
90
+ on_reset()
91
+ }
62
92
  </script>
63
93
 
64
94
  <h4 id="settings-section-title">
@@ -1,5 +1,13 @@
1
- <script lang="ts">import Icon from '../Icon.svelte';
2
- const { title, subtitle, subpages } = $props();
1
+ <script lang="ts">
2
+ import Icon from '../Icon.svelte'
3
+ import type { IconName } from '../icons'
4
+
5
+ interface Props {
6
+ title: string
7
+ subtitle: string
8
+ subpages: { href: string; title: string; description: string; icon: IconName }[]
9
+ }
10
+ const { title, subtitle, subpages }: Props = $props()
3
11
  </script>
4
12
 
5
13
  <h1>{title}</h1>
@@ -1,169 +1,214 @@
1
- <script lang="ts">import Icon from '../../Icon.svelte';
2
- import { getContext, onMount } from 'svelte';
3
- import JsonNode from './JsonNode.svelte';
4
- import JsonValue from './JsonValue.svelte';
5
- import { JSON_TREE_CONTEXT_KEY } from './types';
6
- import { build_path, estimate_byte_size, format_byte_size, format_preview, get_child_count, get_value_type, is_expandable, } from './utils';
7
- let { node_key = null, value, path, depth, is_last = true, } = $props();
8
- const ctx = getContext(JSON_TREE_CONTEXT_KEY);
9
- onMount(() => {
1
+ <script lang="ts">
2
+ import Icon from '../../Icon.svelte'
3
+ import { getContext, onMount } from 'svelte'
4
+ import JsonNode from './JsonNode.svelte'
5
+ import JsonValue from './JsonValue.svelte'
6
+ import type { JsonTreeContext } from './types'
7
+ import { JSON_TREE_CONTEXT_KEY } from './types'
8
+ import {
9
+ build_path,
10
+ estimate_byte_size,
11
+ format_byte_size,
12
+ format_preview,
13
+ get_child_count,
14
+ get_value_type,
15
+ is_expandable,
16
+ } from './utils'
17
+
18
+ let {
19
+ node_key = null,
20
+ value,
21
+ path,
22
+ depth,
23
+ is_last = true,
24
+ }: {
25
+ node_key?: string | number | null
26
+ value: unknown
27
+ path: string
28
+ depth: number
29
+ is_last?: boolean
30
+ } = $props()
31
+
32
+ const ctx = getContext<JsonTreeContext>(JSON_TREE_CONTEXT_KEY)
33
+
34
+ onMount(() => {
10
35
  // Register this path with context for keyboard navigation
11
36
  if (ctx && path) {
12
- ctx.register_path(path);
13
- return () => ctx.unregister_path(path);
37
+ ctx.register_path(path)
38
+ return () => ctx.unregister_path(path)
14
39
  }
15
- });
16
- // Determine value type
17
- let value_type = $derived(get_value_type(value));
18
- // Check if this node is expandable
19
- let expandable = $derived(is_expandable(value));
20
- // Get child count for preview
21
- let child_count = $derived(expandable ? get_child_count(value) : 0);
22
- // Determine if this node should be collapsed
23
- let is_collapsed = $derived.by(() => {
24
- if (!expandable)
25
- return false;
40
+ })
41
+
42
+ // Determine value type
43
+ let value_type = $derived(get_value_type(value))
44
+
45
+ // Check if this node is expandable
46
+ let expandable = $derived(is_expandable(value))
47
+
48
+ // Get child count for preview
49
+ let child_count = $derived(expandable ? get_child_count(value) : 0)
50
+
51
+ // Determine if this node should be collapsed
52
+ let is_collapsed = $derived.by(() => {
53
+ if (!expandable) return false
54
+
26
55
  // Check if explicitly collapsed
27
- if (ctx?.collapsed.has(path))
28
- return true;
56
+ if (ctx?.collapsed.has(path)) return true
57
+
29
58
  // Check if explicitly force-expanded (overrides auto-fold)
30
- if (ctx?.force_expanded.has(path))
31
- return false;
59
+ if (ctx?.force_expanded.has(path)) return false
60
+
32
61
  // If depth >= default_fold_level, default to collapsed
33
- const fold_level = ctx?.settings.default_fold_level ?? 2;
34
- if (depth >= fold_level)
35
- return true;
62
+ const fold_level = ctx?.settings.default_fold_level ?? 2
63
+ if (depth >= fold_level) return true
64
+
36
65
  // Check auto-fold thresholds
37
66
  if (value_type === `array`) {
38
- const threshold = ctx?.settings.auto_fold_arrays ?? 10;
39
- if (child_count > threshold)
40
- return true;
67
+ const threshold = ctx?.settings.auto_fold_arrays ?? 10
68
+ if (child_count > threshold) return true
41
69
  }
42
70
  if (value_type === `object`) {
43
- const threshold = ctx?.settings.auto_fold_objects ?? 20;
44
- if (child_count > threshold)
45
- return true;
71
+ const threshold = ctx?.settings.auto_fold_objects ?? 20
72
+ if (child_count > threshold) return true
46
73
  }
47
- return false;
48
- });
49
- // Note: Search highlighting is handled by CSS Highlight API in JsonTree.svelte
50
- // Check if this node is focused
51
- let is_focused = $derived(ctx?.focused_path === path);
52
- // Check if this is the current search match being navigated
53
- let is_current_match = $derived(ctx?.current_match_path === path);
54
- // Check if this node is selected
55
- let is_selected = $derived(ctx?.selected_paths.has(path) ?? false);
56
- // Diff status for this node (null if no diff or unchanged)
57
- let diff_status = $derived(ctx?.diff_map?.get(path)?.status ?? null);
58
- // Estimated byte size for collapsed preview (only compute when collapsed)
59
- let byte_size = $derived(expandable && is_collapsed ? format_byte_size(estimate_byte_size(value)) : ``);
60
- // Toggle collapse state
61
- function toggle_collapse(event) {
62
- event?.stopPropagation();
74
+
75
+ return false
76
+ })
77
+
78
+ // Note: Search highlighting is handled by CSS Highlight API in JsonTree.svelte
79
+
80
+ // Check if this node is focused
81
+ let is_focused = $derived(ctx?.focused_path === path)
82
+
83
+ // Check if this is the current search match being navigated
84
+ let is_current_match = $derived(ctx?.current_match_path === path)
85
+
86
+ // Check if this node is selected
87
+ let is_selected = $derived(ctx?.selected_paths.has(path) ?? false)
88
+
89
+ // Diff status for this node (null if no diff or unchanged)
90
+ let diff_status = $derived(ctx?.diff_map?.get(path)?.status ?? null)
91
+
92
+ // Estimated byte size for collapsed preview (only compute when collapsed)
93
+ let byte_size = $derived(
94
+ expandable && is_collapsed ? format_byte_size(estimate_byte_size(value)) : ``,
95
+ )
96
+
97
+ // Toggle collapse state
98
+ function toggle_collapse(event?: MouseEvent) {
99
+ event?.stopPropagation()
63
100
  if (ctx && expandable) {
64
- ctx.toggle_collapse(path, is_collapsed);
101
+ ctx.toggle_collapse(path, is_collapsed)
65
102
  }
66
- }
67
- // Toggle collapse recursively on double-click
68
- function toggle_collapse_recursive(event) {
69
- event.stopPropagation();
103
+ }
104
+
105
+ // Toggle collapse recursively on double-click
106
+ function toggle_collapse_recursive(event: MouseEvent) {
107
+ event.stopPropagation()
70
108
  if (ctx && expandable) {
71
- // If collapsed, expand all; if expanded, collapse all
72
- ctx.toggle_collapse_recursive(path, !is_collapsed);
109
+ // If collapsed, expand all; if expanded, collapse all
110
+ ctx.toggle_collapse_recursive(path, !is_collapsed)
73
111
  }
74
- }
75
- // Focus this node
76
- function focus_node() {
77
- ctx?.set_focused(path);
78
- }
79
- // Get children based on value type
80
- function get_children() {
81
- if (!expandable)
82
- return [];
112
+ }
113
+
114
+ // Focus this node
115
+ function focus_node() {
116
+ ctx?.set_focused(path)
117
+ }
118
+
119
+ // Get children based on value type
120
+ function get_children(): Array<{ key: string | number; value: unknown }> {
121
+ if (!expandable) return []
122
+
83
123
  if (value_type === `array`) {
84
- return value.map((val, idx) => ({ key: idx, value: val }));
124
+ return (value as unknown[]).map((val, idx) => ({ key: idx, value: val }))
85
125
  }
126
+
86
127
  if (value_type === `object`) {
87
- let keys = Object.keys(value);
88
- if (ctx?.settings.sort_keys) {
89
- keys = keys.sort();
90
- }
91
- return keys.map((key) => ({
92
- key,
93
- value: value[key],
94
- }));
128
+ let keys = Object.keys(value as Record<string, unknown>)
129
+ if (ctx?.settings.sort_keys) {
130
+ keys = keys.sort()
131
+ }
132
+ return keys.map((key) => ({
133
+ key,
134
+ value: (value as Record<string, unknown>)[key],
135
+ }))
95
136
  }
137
+
96
138
  if (value_type === `map`) {
97
- const map = value;
98
- return Array.from(map.entries()).map(([key, val], idx) => ({
99
- key: idx,
100
- value: { key, value: val },
101
- }));
139
+ const map = value as Map<unknown, unknown>
140
+ return Array.from(map.entries()).map(([key, val], idx) => ({
141
+ key: idx,
142
+ value: { key, value: val },
143
+ }))
102
144
  }
145
+
103
146
  if (value_type === `set`) {
104
- return Array.from(value).map((val, idx) => ({
105
- key: idx,
106
- value: val,
107
- }));
147
+ return Array.from(value as Set<unknown>).map((val, idx) => ({
148
+ key: idx,
149
+ value: val,
150
+ }))
108
151
  }
109
- return [];
110
- }
111
- let children = $derived(get_children());
112
- // Ghost children: removed entries from diff (pre-computed in JsonTree for O(1) lookup)
113
- let ghost_children = $derived.by(() => {
114
- if (!expandable || is_collapsed)
115
- return [];
116
- const all_ghosts = ctx?.ghost_map.get(path) ?? [];
117
- if (all_ghosts.length === 0)
118
- return [];
152
+
153
+ return []
154
+ }
155
+
156
+ let children = $derived(get_children())
157
+
158
+ // Ghost children: removed entries from diff (pre-computed in JsonTree for O(1) lookup)
159
+ let ghost_children = $derived.by(() => {
160
+ if (!expandable || is_collapsed) return []
161
+ const all_ghosts = ctx?.ghost_map.get(path) ?? []
162
+ if (all_ghosts.length === 0) return []
119
163
  // Filter out ghosts whose keys already exist in current children
120
- const existing_keys = new Set(children.map((child) => String(child.key)));
121
- return all_ghosts.filter((ghost) => !existing_keys.has(String(ghost.key)));
122
- });
123
- // Get bracket characters based on type
124
- let open_bracket = $derived(value_type === `array` ? `[` : `{`);
125
- let close_bracket = $derived(value_type === `array` ? `]` : `}`);
126
- // Handle keyboard navigation
127
- function handle_keydown(event) {
128
- if (!is_focused)
129
- return;
164
+ const existing_keys = new Set(children.map((child) => String(child.key)))
165
+ return all_ghosts.filter((ghost) => !existing_keys.has(String(ghost.key)))
166
+ })
167
+
168
+ // Get bracket characters based on type
169
+ let open_bracket = $derived(value_type === `array` ? `[` : `{`)
170
+ let close_bracket = $derived(value_type === `array` ? `]` : `}`)
171
+
172
+ // Handle keyboard navigation
173
+ function handle_keydown(event: KeyboardEvent) {
174
+ if (!is_focused) return
175
+
130
176
  if (event.key === `Enter` || event.key === ` `) {
131
- event.preventDefault();
132
- if (expandable) {
133
- toggle_collapse();
134
- }
135
- else {
136
- ctx?.copy_value(path, value);
137
- }
138
- }
139
- else if (event.key === `ArrowRight`) {
140
- event.preventDefault();
141
- if (expandable && is_collapsed) {
142
- toggle_collapse();
143
- }
144
- }
145
- else if (event.key === `ArrowLeft`) {
146
- event.preventDefault();
147
- if (expandable && !is_collapsed) {
148
- toggle_collapse();
149
- }
150
- }
151
- else if ((event.key === `c` || event.key === `C`) && (event.ctrlKey || event.metaKey)) {
152
- // When nodes are selected, let the tree-level handler do bulk copy
153
- if (ctx?.selected_paths.size)
154
- return;
155
- event.preventDefault();
156
- event.stopPropagation();
157
- ctx?.copy_value(path, value);
177
+ event.preventDefault()
178
+ if (expandable) {
179
+ toggle_collapse()
180
+ } else {
181
+ ctx?.copy_value(path, value)
182
+ }
183
+ } else if (event.key === `ArrowRight`) {
184
+ event.preventDefault()
185
+ if (expandable && is_collapsed) {
186
+ toggle_collapse()
187
+ }
188
+ } else if (event.key === `ArrowLeft`) {
189
+ event.preventDefault()
190
+ if (expandable && !is_collapsed) {
191
+ toggle_collapse()
192
+ }
193
+ } else if (
194
+ (event.key === `c` || event.key === `C`) && (event.ctrlKey || event.metaKey)
195
+ ) {
196
+ // When nodes are selected, let the tree-level handler do bulk copy
197
+ if (ctx?.selected_paths.size) return
198
+ event.preventDefault()
199
+ event.stopPropagation()
200
+ ctx?.copy_value(path, value)
158
201
  }
159
- }
160
- // Element reference for focus management
161
- let node_element = $state();
162
- $effect(() => {
202
+ }
203
+
204
+ // Element reference for focus management
205
+ let node_element: HTMLDivElement | undefined = $state()
206
+
207
+ $effect(() => {
163
208
  if (is_focused && node_element) {
164
- node_element.focus();
209
+ node_element.focus()
165
210
  }
166
- });
211
+ })
167
212
  </script>
168
213
 
169
214
  <div