matterviz 0.4.1 → 0.4.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 (499) hide show
  1. package/dist/EmptyState.svelte +10 -4
  2. package/dist/FilePicker.svelte +48 -60
  3. package/dist/Icon.svelte +7 -4
  4. package/dist/MillerIndexInput.svelte +2 -2
  5. package/dist/api/optimade.js +10 -7
  6. package/dist/app.css +68 -0
  7. package/dist/brillouin/BrillouinZone.svelte +90 -91
  8. package/dist/brillouin/BrillouinZone.svelte.d.ts +5 -7
  9. package/dist/brillouin/BrillouinZoneControls.svelte +3 -6
  10. package/dist/brillouin/BrillouinZoneExportPane.svelte +18 -14
  11. package/dist/brillouin/BrillouinZoneInfoPane.svelte +6 -10
  12. package/dist/brillouin/BrillouinZoneScene.svelte +46 -68
  13. package/dist/brillouin/BrillouinZoneScene.svelte.d.ts +1 -1
  14. package/dist/brillouin/compute.js +10 -16
  15. package/dist/brillouin/geometry.js +2 -2
  16. package/dist/chempot-diagram/ChemPotDiagram.svelte +48 -50
  17. package/dist/chempot-diagram/ChemPotDiagram2D.svelte +61 -169
  18. package/dist/chempot-diagram/ChemPotDiagram2D.svelte.d.ts +1 -1
  19. package/dist/chempot-diagram/ChemPotDiagram3D.svelte +559 -755
  20. package/dist/chempot-diagram/ChemPotDiagram3D.svelte.d.ts +1 -1
  21. package/dist/chempot-diagram/async-compute.svelte.js +13 -14
  22. package/dist/chempot-diagram/color.d.ts +21 -1
  23. package/dist/chempot-diagram/color.js +70 -1
  24. package/dist/chempot-diagram/compute.d.ts +7 -0
  25. package/dist/chempot-diagram/compute.js +85 -26
  26. package/dist/chempot-diagram/controls-state.svelte.js +1 -1
  27. package/dist/chempot-diagram/export.js +1 -6
  28. package/dist/chempot-diagram/temperature.js +9 -10
  29. package/dist/colors/index.d.ts +0 -4
  30. package/dist/colors/index.js +19 -20
  31. package/dist/composition/BarChart.svelte +30 -26
  32. package/dist/composition/BubbleChart.svelte +17 -17
  33. package/dist/composition/Composition.svelte +10 -19
  34. package/dist/composition/Formula.svelte +20 -27
  35. package/dist/composition/FormulaFilter.svelte +115 -184
  36. package/dist/composition/PieChart.svelte +55 -41
  37. package/dist/composition/format.js +7 -9
  38. package/dist/composition/index.d.ts +2 -0
  39. package/dist/composition/index.js +14 -0
  40. package/dist/composition/parse.d.ts +2 -2
  41. package/dist/composition/parse.js +61 -115
  42. package/dist/constants.d.ts +0 -1
  43. package/dist/constants.js +17 -26
  44. package/dist/convex-hull/ConvexHull.svelte +12 -15
  45. package/dist/convex-hull/ConvexHull.svelte.d.ts +1 -1
  46. package/dist/convex-hull/ConvexHull2D.svelte +93 -94
  47. package/dist/convex-hull/ConvexHull2D.svelte.d.ts +1 -1
  48. package/dist/convex-hull/ConvexHull3D.svelte +127 -186
  49. package/dist/convex-hull/ConvexHull3D.svelte.d.ts +1 -1
  50. package/dist/convex-hull/ConvexHull4D.svelte +131 -180
  51. package/dist/convex-hull/ConvexHull4D.svelte.d.ts +1 -1
  52. package/dist/convex-hull/ConvexHullChrome.svelte +36 -40
  53. package/dist/convex-hull/ConvexHullControls.svelte +46 -48
  54. package/dist/convex-hull/ConvexHullStats.svelte +193 -195
  55. package/dist/convex-hull/ConvexHullTooltip.svelte +5 -12
  56. package/dist/convex-hull/GasPressureControls.svelte +5 -12
  57. package/dist/convex-hull/StructurePopup.svelte +18 -22
  58. package/dist/convex-hull/StructurePopup.svelte.d.ts +2 -0
  59. package/dist/convex-hull/TemperatureSlider.svelte +4 -10
  60. package/dist/convex-hull/canvas-interactions.svelte.js +2 -1
  61. package/dist/convex-hull/gas-thermodynamics.js +21 -53
  62. package/dist/convex-hull/helpers.d.ts +8 -10
  63. package/dist/convex-hull/helpers.js +37 -43
  64. package/dist/convex-hull/hull-state.svelte.d.ts +1 -1
  65. package/dist/convex-hull/thermodynamics.js +37 -44
  66. package/dist/coordination/CoordinationBarPlot.svelte +49 -53
  67. package/dist/coordination/CoordinationBarPlot.svelte.d.ts +1 -1
  68. package/dist/coordination/calc-coordination.d.ts +1 -1
  69. package/dist/coordination/calc-coordination.js +28 -25
  70. package/dist/element/BohrAtom.svelte +5 -9
  71. package/dist/element/ElementHeading.svelte +4 -1
  72. package/dist/element/ElementPhoto.svelte +11 -9
  73. package/dist/element/ElementStats.svelte +12 -10
  74. package/dist/element/ElementTile.svelte +44 -67
  75. package/dist/element/Nucleus.svelte +4 -2
  76. package/dist/element/data.d.ts +3 -2
  77. package/dist/element/data.js +5 -1
  78. package/dist/element/helpers.d.ts +4 -0
  79. package/dist/element/helpers.js +18 -0
  80. package/dist/element/index.d.ts +2 -5
  81. package/dist/element/index.js +4 -19
  82. package/dist/feedback/DragOverlay.svelte +5 -5
  83. package/dist/feedback/DragOverlay.svelte.d.ts +2 -2
  84. package/dist/feedback/StatusMessage.svelte +7 -4
  85. package/dist/fermi-surface/FermiSlice.svelte +21 -18
  86. package/dist/fermi-surface/FermiSurface.svelte +35 -44
  87. package/dist/fermi-surface/FermiSurface.svelte.d.ts +7 -13
  88. package/dist/fermi-surface/FermiSurfaceControls.svelte +6 -20
  89. package/dist/fermi-surface/FermiSurfaceControls.svelte.d.ts +1 -1
  90. package/dist/fermi-surface/FermiSurfaceScene.svelte +64 -136
  91. package/dist/fermi-surface/FermiSurfaceScene.svelte.d.ts +1 -1
  92. package/dist/fermi-surface/FermiSurfaceTooltip.svelte +9 -6
  93. package/dist/fermi-surface/compute.js +25 -58
  94. package/dist/fermi-surface/parse.js +54 -88
  95. package/dist/file-viewer/JsonBrowser.svelte +1043 -0
  96. package/dist/file-viewer/JsonBrowser.svelte.d.ts +9 -0
  97. package/dist/file-viewer/PlotPanel.svelte +350 -0
  98. package/dist/file-viewer/PlotPanel.svelte.d.ts +9 -0
  99. package/dist/file-viewer/TrajectoryWithDos.svelte +30 -0
  100. package/dist/file-viewer/TrajectoryWithDos.svelte.d.ts +10 -0
  101. package/dist/file-viewer/detect.d.ts +11 -0
  102. package/dist/file-viewer/detect.js +381 -0
  103. package/dist/file-viewer/eligibility.d.ts +4 -0
  104. package/dist/file-viewer/eligibility.js +53 -0
  105. package/dist/file-viewer/host-protocol.d.ts +50 -0
  106. package/dist/file-viewer/host-transfer.d.ts +25 -0
  107. package/dist/file-viewer/host-transfer.js +42 -0
  108. package/dist/file-viewer/index.d.ts +5 -0
  109. package/dist/file-viewer/index.js +5 -0
  110. package/dist/file-viewer/main.d.ts +44 -0
  111. package/dist/file-viewer/main.js +535 -0
  112. package/dist/file-viewer/parse.d.ts +9 -0
  113. package/dist/file-viewer/parse.js +170 -0
  114. package/dist/file-viewer/plot-utils.d.ts +24 -0
  115. package/dist/file-viewer/plot-utils.js +191 -0
  116. package/dist/file-viewer/types.d.ts +4 -0
  117. package/dist/file-viewer/types.js +5 -0
  118. package/dist/heatmap-matrix/HeatmapMatrix.svelte +153 -219
  119. package/dist/heatmap-matrix/HeatmapMatrix.svelte.d.ts +2 -2
  120. package/dist/heatmap-matrix/HeatmapMatrixControls.svelte +9 -7
  121. package/dist/heatmap-matrix/HeatmapMatrixControls.svelte.d.ts +1 -1
  122. package/dist/heatmap-matrix/index.d.ts +5 -0
  123. package/dist/icons.d.ts +4 -0
  124. package/dist/icons.js +4 -0
  125. package/dist/index.d.ts +2 -2
  126. package/dist/index.js +1 -1
  127. package/dist/io/ExportPane.svelte +11 -7
  128. package/dist/io/decompress.d.ts +4 -1
  129. package/dist/io/decompress.js +24 -36
  130. package/dist/io/export.d.ts +11 -4
  131. package/dist/io/export.js +75 -19
  132. package/dist/io/fetch.d.ts +0 -3
  133. package/dist/io/fetch.js +0 -11
  134. package/dist/io/file-drop.js +60 -35
  135. package/dist/io/index.d.ts +0 -1
  136. package/dist/io/index.js +2 -9
  137. package/dist/io/is-binary.d.ts +9 -0
  138. package/dist/io/is-binary.js +45 -1
  139. package/dist/io/url-drop.d.ts +2 -0
  140. package/dist/io/url-drop.js +40 -40
  141. package/dist/isosurface/Isosurface.svelte +700 -215
  142. package/dist/isosurface/Isosurface.svelte.d.ts +7 -1
  143. package/dist/isosurface/IsosurfaceControls.svelte +590 -116
  144. package/dist/isosurface/IsosurfaceControls.svelte.d.ts +1 -1
  145. package/dist/isosurface/VolumeSlice.svelte +224 -0
  146. package/dist/isosurface/VolumeSlice.svelte.d.ts +28 -0
  147. package/dist/isosurface/coloring.d.ts +20 -0
  148. package/dist/isosurface/coloring.js +118 -0
  149. package/dist/isosurface/geometry-worker-types.d.ts +38 -0
  150. package/dist/isosurface/geometry.worker.d.ts +1 -0
  151. package/dist/isosurface/geometry.worker.js +59 -0
  152. package/dist/isosurface/grid.d.ts +10 -0
  153. package/dist/isosurface/grid.js +31 -0
  154. package/dist/isosurface/index.d.ts +4 -0
  155. package/dist/isosurface/index.js +4 -0
  156. package/dist/isosurface/parse-vaspwave.d.ts +3 -0
  157. package/dist/isosurface/parse-vaspwave.js +138 -0
  158. package/dist/isosurface/parse.js +6 -6
  159. package/dist/isosurface/profile.d.ts +12 -0
  160. package/dist/isosurface/profile.js +19 -0
  161. package/dist/isosurface/sampling.d.ts +34 -0
  162. package/dist/isosurface/sampling.js +408 -0
  163. package/dist/isosurface/slice-rendering.d.ts +13 -0
  164. package/dist/isosurface/slice-rendering.js +79 -0
  165. package/dist/isosurface/slice.d.ts +22 -2
  166. package/dist/isosurface/slice.js +200 -116
  167. package/dist/isosurface/types.d.ts +24 -1
  168. package/dist/isosurface/types.js +120 -8
  169. package/dist/json-path.d.ts +4 -0
  170. package/dist/json-path.js +89 -0
  171. package/dist/labels.d.ts +6 -2
  172. package/dist/labels.js +44 -14
  173. package/dist/layout/FullscreenButton.svelte +2 -1
  174. package/dist/layout/FullscreenToggle.svelte +10 -4
  175. package/dist/layout/InfoCard.svelte +8 -21
  176. package/dist/layout/InfoTag.svelte +1 -3
  177. package/dist/layout/NumberRangeInput.svelte +46 -0
  178. package/dist/layout/NumberRangeInput.svelte.d.ts +12 -0
  179. package/dist/layout/PropertyFilter.svelte +2 -6
  180. package/dist/layout/SettingsSection.svelte +57 -62
  181. package/dist/layout/SettingsSection.svelte.d.ts +6 -7
  182. package/dist/layout/SubpageGrid.svelte +3 -1
  183. package/dist/layout/ViewerChrome.svelte +16 -11
  184. package/dist/layout/ViewerChrome.svelte.d.ts +2 -1
  185. package/dist/layout/fullscreen.js +3 -5
  186. package/dist/layout/fullscreen.svelte.js +1 -2
  187. package/dist/layout/index.d.ts +1 -0
  188. package/dist/layout/index.js +1 -0
  189. package/dist/layout/json-tree/JsonNode.svelte +22 -59
  190. package/dist/layout/json-tree/JsonTree.svelte +101 -172
  191. package/dist/layout/json-tree/JsonValue.svelte +9 -32
  192. package/dist/layout/json-tree/utils.d.ts +0 -3
  193. package/dist/layout/json-tree/utils.js +50 -188
  194. package/dist/marching-cubes.d.ts +8 -1
  195. package/dist/marching-cubes.js +115 -48
  196. package/dist/math.d.ts +5 -2
  197. package/dist/math.js +48 -38
  198. package/dist/overlays/ContextMenu.svelte +19 -34
  199. package/dist/overlays/CopyButton.svelte +11 -5
  200. package/dist/overlays/DragControlTab.svelte +6 -1
  201. package/dist/overlays/DraggablePane.svelte +110 -74
  202. package/dist/overlays/DraggablePane.svelte.d.ts +2 -1
  203. package/dist/overlays/GlassChip.svelte +32 -0
  204. package/dist/overlays/GlassChip.svelte.d.ts +8 -0
  205. package/dist/overlays/InfoPaneCards.svelte +11 -23
  206. package/dist/overlays/index.d.ts +7 -0
  207. package/dist/overlays/index.js +26 -0
  208. package/dist/overlays/portal.d.ts +2 -0
  209. package/dist/overlays/portal.js +14 -0
  210. package/dist/periodic-table/PeriodicTable.svelte +113 -145
  211. package/dist/periodic-table/PeriodicTable.svelte.d.ts +5 -3
  212. package/dist/periodic-table/PeriodicTableControls.svelte +37 -115
  213. package/dist/periodic-table/TableInset.svelte +9 -4
  214. package/dist/phase-diagram/IsobaricBinaryPhaseDiagram.svelte +68 -105
  215. package/dist/phase-diagram/IsobaricBinaryPhaseDiagram.svelte.d.ts +6 -8
  216. package/dist/phase-diagram/PhaseDiagramControls.svelte +70 -94
  217. package/dist/phase-diagram/PhaseDiagramControls.svelte.d.ts +1 -1
  218. package/dist/phase-diagram/PhaseDiagramEditorPane.svelte +2 -1
  219. package/dist/phase-diagram/PhaseDiagramExportPane.svelte +12 -12
  220. package/dist/phase-diagram/PhaseDiagramTooltip.svelte +54 -58
  221. package/dist/phase-diagram/TdbInfoPanel.svelte +21 -15
  222. package/dist/phase-diagram/build-diagram.js +4 -9
  223. package/dist/phase-diagram/diagram-input.d.ts +1 -2
  224. package/dist/phase-diagram/parse.js +15 -15
  225. package/dist/phase-diagram/svg-to-diagram.js +28 -27
  226. package/dist/phase-diagram/utils.js +2 -3
  227. package/dist/plot/bar/BarPlot.svelte +461 -426
  228. package/dist/plot/bar/BarPlot.svelte.d.ts +2 -0
  229. package/dist/plot/bar/BarPlotControls.svelte +1 -3
  230. package/dist/plot/bar/BarPlotControls.svelte.d.ts +4 -6
  231. package/dist/plot/bar/SpacegroupBarPlot.svelte +46 -77
  232. package/dist/plot/bar/data.d.ts +5 -4
  233. package/dist/plot/bar/data.js +2 -1
  234. package/dist/plot/box/BoxPlot.svelte +322 -226
  235. package/dist/plot/box/BoxPlot.svelte.d.ts +2 -0
  236. package/dist/plot/box/Violin.svelte.d.ts +1 -0
  237. package/dist/plot/box/box-plot.js +1 -1
  238. package/dist/plot/core/auto-place.d.ts +1 -1
  239. package/dist/plot/core/auto-place.js +2 -2
  240. package/dist/plot/core/axis-utils.d.ts +12 -7
  241. package/dist/plot/core/axis-utils.js +48 -48
  242. package/dist/plot/core/components/AxisLabel.svelte +82 -20
  243. package/dist/plot/core/components/AxisLabel.svelte.d.ts +1 -0
  244. package/dist/plot/core/components/ColorBar.svelte +101 -106
  245. package/dist/plot/core/components/ColorScaleSelect.svelte +1 -1
  246. package/dist/plot/core/components/FillArea.svelte +10 -17
  247. package/dist/plot/core/components/HierarchyControls.svelte +249 -0
  248. package/dist/plot/{sunburst/SunburstControls.svelte.d.ts → core/components/HierarchyControls.svelte.d.ts} +12 -8
  249. package/dist/plot/core/components/InteractiveAxisLabel.svelte +1 -1
  250. package/dist/plot/core/components/InteractiveAxisLabel.svelte.d.ts +1 -1
  251. package/dist/plot/core/components/Line.svelte +18 -9
  252. package/dist/plot/core/components/Line.svelte.d.ts +2 -0
  253. package/dist/plot/core/components/PlotAxis.svelte +40 -17
  254. package/dist/plot/core/components/PlotControls.svelte +65 -41
  255. package/dist/plot/core/components/PlotLegend.svelte +31 -35
  256. package/dist/plot/core/components/PlotMarginals.svelte +616 -0
  257. package/dist/plot/core/components/PlotMarginals.svelte.d.ts +15 -0
  258. package/dist/plot/core/components/PlotTooltip.svelte +1 -1
  259. package/dist/plot/core/components/PortalSelect.svelte +4 -8
  260. package/dist/plot/core/components/ReferenceLine.svelte +27 -24
  261. package/dist/plot/core/components/ReferenceLine3D.svelte +54 -57
  262. package/dist/plot/core/components/ReferencePlane.svelte +7 -8
  263. package/dist/plot/core/components/ZeroLines.svelte +4 -8
  264. package/dist/plot/core/components/ZoomRect.svelte +1 -2
  265. package/dist/plot/core/components/index.d.ts +1 -0
  266. package/dist/plot/core/components/index.js +1 -0
  267. package/dist/plot/core/data-cleaning-signal.d.ts +46 -0
  268. package/dist/plot/core/data-cleaning-signal.js +467 -0
  269. package/dist/plot/core/data-cleaning.d.ts +2 -42
  270. package/dist/plot/core/data-cleaning.js +27 -474
  271. package/dist/plot/core/data-transform.d.ts +1 -2
  272. package/dist/plot/core/data-transform.js +9 -15
  273. package/dist/plot/core/fill-utils.d.ts +3 -1
  274. package/dist/plot/core/fill-utils.js +28 -6
  275. package/dist/plot/core/index.d.ts +1 -0
  276. package/dist/plot/core/index.js +1 -0
  277. package/dist/plot/core/interactions.js +0 -2
  278. package/dist/plot/core/layout.d.ts +15 -6
  279. package/dist/plot/core/layout.js +57 -38
  280. package/dist/plot/core/marginals.d.ts +170 -0
  281. package/dist/plot/core/marginals.js +436 -0
  282. package/dist/plot/core/pan-zoom.svelte.d.ts +2 -4
  283. package/dist/plot/core/pan-zoom.svelte.js +34 -17
  284. package/dist/plot/core/placed-tween.svelte.d.ts +3 -0
  285. package/dist/plot/core/placed-tween.svelte.js +68 -21
  286. package/dist/plot/core/reference-line.js +1 -1
  287. package/dist/plot/core/scales.d.ts +23 -0
  288. package/dist/plot/core/scales.js +39 -13
  289. package/dist/plot/core/svg.js +0 -1
  290. package/dist/plot/core/types/fills.d.ts +101 -0
  291. package/dist/plot/core/types/fills.js +15 -0
  292. package/dist/plot/core/types/plot-3d.d.ts +87 -0
  293. package/dist/plot/core/types/plot-3d.js +4 -0
  294. package/dist/plot/core/types/reference-lines.d.ts +140 -0
  295. package/dist/plot/core/types/reference-lines.js +9 -0
  296. package/dist/plot/core/types.d.ts +29 -324
  297. package/dist/plot/core/types.js +23 -20
  298. package/dist/plot/core/utils/hierarchy-chart.d.ts +52 -0
  299. package/dist/plot/core/utils/hierarchy-chart.js +191 -0
  300. package/dist/plot/core/utils/hierarchy-labels.d.ts +20 -0
  301. package/dist/plot/core/utils/hierarchy-labels.js +100 -0
  302. package/dist/plot/core/utils/label-placement.js +2 -2
  303. package/dist/plot/histogram/Histogram.svelte +314 -340
  304. package/dist/plot/histogram/Histogram.svelte.d.ts +7 -7
  305. package/dist/plot/histogram/HistogramControls.svelte +30 -28
  306. package/dist/plot/histogram/histogram.d.ts +31 -0
  307. package/dist/plot/histogram/histogram.js +70 -0
  308. package/dist/plot/histogram/index.d.ts +1 -0
  309. package/dist/plot/histogram/index.js +1 -0
  310. package/dist/plot/index.d.ts +1 -0
  311. package/dist/plot/index.js +1 -0
  312. package/dist/plot/sankey/Sankey.svelte +78 -69
  313. package/dist/plot/sankey/Sankey.svelte.d.ts +2 -2
  314. package/dist/plot/sankey/SankeyControls.svelte +22 -16
  315. package/dist/plot/sankey/sankey.js +13 -9
  316. package/dist/plot/scatter/BinnedScatterPlot.svelte +311 -141
  317. package/dist/plot/scatter/BinnedScatterPlot.svelte.d.ts +7 -0
  318. package/dist/plot/scatter/ElementScatter.svelte +4 -1
  319. package/dist/plot/scatter/ScatterPlot.svelte +517 -410
  320. package/dist/plot/scatter/ScatterPlot.svelte.d.ts +2 -0
  321. package/dist/plot/scatter/ScatterPlotControls.svelte +18 -19
  322. package/dist/plot/scatter/ScatterPlotControls.svelte.d.ts +1 -1
  323. package/dist/plot/scatter/ScatterPoint.svelte +16 -9
  324. package/dist/plot/scatter/adaptive-density.d.ts +1 -1
  325. package/dist/plot/scatter/adaptive-density.js +36 -20
  326. package/dist/plot/scatter/binned-scatter-types.d.ts +3 -2
  327. package/dist/plot/scatter/binned-scatter-types.js +6 -1
  328. package/dist/plot/scatter/scatter-data.d.ts +1 -1
  329. package/dist/plot/scatter/scatter-data.js +8 -7
  330. package/dist/plot/scatter-3d/ScatterPlot3D.svelte +25 -34
  331. package/dist/plot/scatter-3d/ScatterPlot3D.svelte.d.ts +2 -2
  332. package/dist/plot/scatter-3d/ScatterPlot3DControls.svelte +8 -5
  333. package/dist/plot/scatter-3d/ScatterPlot3DScene.svelte +113 -116
  334. package/dist/plot/scatter-3d/ScatterPlot3DScene.svelte.d.ts +2 -2
  335. package/dist/plot/scatter-3d/Surface3D.svelte +4 -13
  336. package/dist/plot/sunburst/Sunburst.svelte +269 -347
  337. package/dist/plot/sunburst/Sunburst.svelte.d.ts +2 -2
  338. package/dist/plot/sunburst/index.d.ts +1 -1
  339. package/dist/plot/sunburst/index.js +2 -1
  340. package/dist/plot/sunburst/render.d.ts +2 -2
  341. package/dist/plot/sunburst/render.js +47 -22
  342. package/dist/plot/sunburst/sunburst.d.ts +5 -1
  343. package/dist/plot/sunburst/sunburst.js +10 -3
  344. package/dist/plot/treemap/Treemap.svelte +1022 -0
  345. package/dist/plot/treemap/Treemap.svelte.d.ts +90 -0
  346. package/dist/plot/treemap/index.d.ts +4 -0
  347. package/dist/plot/treemap/index.js +4 -0
  348. package/dist/plot/treemap/labels.d.ts +38 -0
  349. package/dist/plot/treemap/labels.js +80 -0
  350. package/dist/plot/treemap/treemap.d.ts +28 -0
  351. package/dist/plot/treemap/treemap.js +102 -0
  352. package/dist/rdf/RdfPlot.svelte +37 -59
  353. package/dist/rdf/RdfPlot.svelte.d.ts +1 -1
  354. package/dist/rdf/calc-rdf.js +63 -52
  355. package/dist/rdf/index.d.ts +0 -1
  356. package/dist/sanitize.js +85 -27
  357. package/dist/scene/SceneCamera.svelte +1 -1
  358. package/dist/scene/SceneCamera.svelte.d.ts +1 -1
  359. package/dist/scene/bind-renderer.svelte.js +14 -6
  360. package/dist/scene/index.d.ts +1 -2
  361. package/dist/scene/index.js +1 -1
  362. package/dist/scene/{props.js → props.svelte.js} +15 -1
  363. package/dist/settings.d.ts +19 -9
  364. package/dist/settings.js +229 -525
  365. package/dist/spectral/Bands.svelte +207 -221
  366. package/dist/spectral/BandsAndDos.svelte +11 -9
  367. package/dist/spectral/BrillouinBandsDos.svelte +19 -42
  368. package/dist/spectral/Dos.svelte +92 -93
  369. package/dist/spectral/helpers.d.ts +3 -3
  370. package/dist/spectral/helpers.js +65 -140
  371. package/dist/state.svelte.js +5 -18
  372. package/dist/structure/Arrow.svelte +5 -18
  373. package/dist/structure/ArrowInstances.svelte +160 -0
  374. package/dist/structure/ArrowInstances.svelte.d.ts +16 -0
  375. package/dist/structure/AtomLegend.svelte +120 -85
  376. package/dist/structure/AtomLegend.svelte.d.ts +2 -3
  377. package/dist/structure/Bond.svelte +31 -23
  378. package/dist/structure/CanvasTooltip.svelte +15 -3
  379. package/dist/structure/CellSelect.svelte +45 -35
  380. package/dist/structure/Cylinder.svelte +24 -40
  381. package/dist/structure/InstancedAtoms.svelte +114 -0
  382. package/dist/structure/InstancedAtoms.svelte.d.ts +15 -0
  383. package/dist/structure/Lattice.svelte +85 -149
  384. package/dist/structure/SiteLabels.svelte +122 -0
  385. package/dist/structure/SiteLabels.svelte.d.ts +18 -0
  386. package/dist/structure/Structure.svelte +636 -504
  387. package/dist/structure/Structure.svelte.d.ts +4 -2
  388. package/dist/structure/StructureCarousel.svelte +637 -0
  389. package/dist/structure/StructureCarousel.svelte.d.ts +19 -0
  390. package/dist/structure/StructureControls.svelte +165 -425
  391. package/dist/structure/StructureControls.svelte.d.ts +1 -1
  392. package/dist/structure/StructureExportPane.svelte +17 -21
  393. package/dist/structure/StructureInfoPane.svelte +128 -133
  394. package/dist/structure/StructureInfoPane.svelte.d.ts +1 -1
  395. package/dist/structure/StructureScene.svelte +535 -578
  396. package/dist/structure/StructureScene.svelte.d.ts +6 -2
  397. package/dist/structure/StructureViewport.svelte +451 -0
  398. package/dist/structure/StructureViewport.svelte.d.ts +65 -0
  399. package/dist/structure/atom-label-placement.d.ts +16 -12
  400. package/dist/structure/atom-label-placement.js +70 -37
  401. package/dist/structure/atom-properties.d.ts +2 -0
  402. package/dist/structure/atom-properties.js +105 -38
  403. package/dist/structure/bond-order-perception.js +3 -8
  404. package/dist/structure/bonding.d.ts +9 -3
  405. package/dist/structure/bonding.js +95 -46
  406. package/dist/structure/edit-history.d.ts +6 -0
  407. package/dist/structure/edit-history.js +27 -0
  408. package/dist/structure/export.d.ts +1 -0
  409. package/dist/structure/export.js +89 -105
  410. package/dist/structure/format-detect.d.ts +1 -0
  411. package/dist/structure/format-detect.js +20 -0
  412. package/dist/structure/geometry.d.ts +9 -0
  413. package/dist/structure/geometry.js +27 -0
  414. package/dist/structure/index.d.ts +16 -1
  415. package/dist/structure/index.js +15 -10
  416. package/dist/structure/measure.d.ts +1 -1
  417. package/dist/structure/measure.js +6 -12
  418. package/dist/structure/parse.d.ts +2 -1
  419. package/dist/structure/parse.js +272 -313
  420. package/dist/structure/partial-occupancy.js +10 -5
  421. package/dist/structure/pbc.js +85 -107
  422. package/dist/structure/polyhedra.d.ts +0 -1
  423. package/dist/structure/polyhedra.js +7 -21
  424. package/dist/structure/prop-groups.d.ts +85 -0
  425. package/dist/structure/prop-groups.js +18 -0
  426. package/dist/structure/supercell.d.ts +1 -2
  427. package/dist/structure/supercell.js +7 -13
  428. package/dist/symmetry/SymmetryElements.svelte +11 -15
  429. package/dist/symmetry/SymmetryStats.svelte +55 -71
  430. package/dist/symmetry/WyckoffTable.svelte +10 -28
  431. package/dist/symmetry/cell-transform.js +6 -14
  432. package/dist/symmetry/index.d.ts +1 -0
  433. package/dist/symmetry/index.js +13 -10
  434. package/dist/symmetry/spacegroups.js +3 -2
  435. package/dist/table/HeatmapTable.svelte +1142 -447
  436. package/dist/table/HeatmapTable.svelte.d.ts +12 -2
  437. package/dist/table/ToggleMenu.svelte +168 -53
  438. package/dist/table/ToggleMenu.svelte.d.ts +1 -1
  439. package/dist/table/index.d.ts +21 -6
  440. package/dist/table/index.js +34 -21
  441. package/dist/theme/ThemeControl.svelte +16 -8
  442. package/dist/theme/embedded.d.ts +18 -0
  443. package/dist/theme/embedded.js +206 -0
  444. package/dist/theme/index.d.ts +5 -5
  445. package/dist/theme/index.js +5 -12
  446. package/dist/theme/themes.mjs +44 -66
  447. package/dist/tooltip/KCoords.svelte +4 -1
  448. package/dist/tooltip/TooltipContent.svelte +3 -6
  449. package/dist/tooltip/TooltipContent.svelte.d.ts +1 -1
  450. package/dist/tooltip/index.d.ts +8 -1
  451. package/dist/trajectory/Trajectory.svelte +613 -386
  452. package/dist/trajectory/Trajectory.svelte.d.ts +1 -1
  453. package/dist/trajectory/TrajectoryError.svelte +12 -74
  454. package/dist/trajectory/TrajectoryExportPane.svelte +14 -32
  455. package/dist/trajectory/TrajectoryInfoPane.svelte +127 -164
  456. package/dist/trajectory/TrajectoryInfoPane.svelte.d.ts +2 -1
  457. package/dist/trajectory/extract.js +61 -49
  458. package/dist/trajectory/format-detect.d.ts +2 -0
  459. package/dist/trajectory/format-detect.js +17 -13
  460. package/dist/trajectory/frame-reader.d.ts +2 -0
  461. package/dist/trajectory/frame-reader.js +35 -32
  462. package/dist/trajectory/helpers.d.ts +2 -0
  463. package/dist/trajectory/helpers.js +34 -56
  464. package/dist/trajectory/index.d.ts +1 -0
  465. package/dist/trajectory/index.js +5 -8
  466. package/dist/trajectory/parse/ase.js +1 -1
  467. package/dist/trajectory/parse/h5-utils.d.ts +13 -0
  468. package/dist/trajectory/parse/h5-utils.js +109 -0
  469. package/dist/trajectory/parse/hdf5.d.ts +1 -1
  470. package/dist/trajectory/parse/hdf5.js +116 -106
  471. package/dist/trajectory/parse/index.d.ts +6 -6
  472. package/dist/trajectory/parse/index.js +25 -33
  473. package/dist/trajectory/parse/lammps.js +8 -12
  474. package/dist/trajectory/parse/vasp.js +10 -7
  475. package/dist/trajectory/parse/vaspout-electronic.d.ts +13 -0
  476. package/dist/trajectory/parse/vaspout-electronic.js +207 -0
  477. package/dist/trajectory/parse/vaspout-h5.d.ts +4 -0
  478. package/dist/trajectory/parse/vaspout-h5.js +281 -0
  479. package/dist/trajectory/parse/xyz.js +59 -9
  480. package/dist/trajectory/plotting.d.ts +8 -9
  481. package/dist/trajectory/plotting.js +113 -64
  482. package/dist/utils.d.ts +3 -0
  483. package/dist/utils.js +7 -0
  484. package/dist/xrd/XrdPlot.svelte +79 -118
  485. package/dist/xrd/broadening.js +2 -1
  486. package/dist/xrd/calc-xrd.js +24 -62
  487. package/dist/xrd/parse.d.ts +0 -1
  488. package/dist/xrd/parse.js +69 -95
  489. package/package.json +94 -34
  490. package/readme.md +6 -5
  491. package/dist/api/mp.d.ts +0 -6
  492. package/dist/api/mp.js +0 -22
  493. package/dist/plot/sunburst/SunburstControls.svelte +0 -200
  494. package/dist/scene/types.d.ts +0 -26
  495. package/dist/tooltip/types.d.ts +0 -8
  496. package/dist/trajectory/constants.d.ts +0 -6
  497. package/dist/trajectory/constants.js +0 -11
  498. /package/dist/{scene/types.js → file-viewer/host-protocol.js} +0 -0
  499. /package/dist/{tooltip/types.js → isosurface/geometry-worker-types.js} +0 -0
package/dist/math.js CHANGED
@@ -147,22 +147,19 @@ export function matrix_inverse_3x3(matrix) {
147
147
  export function mat3x3_vec3_multiply(matrix, vector) {
148
148
  const [a, b, c] = matrix;
149
149
  const [x, y, z] = vector;
150
- const a_new = a[0] * x + a[1] * y + a[2] * z;
151
- const b_new = b[0] * x + b[1] * y + b[2] * z;
152
- const c_new = c[0] * x + c[1] * y + c[2] * z;
153
- return [a_new, b_new, c_new];
150
+ return [
151
+ a[0] * x + a[1] * y + a[2] * z,
152
+ b[0] * x + b[1] * y + b[2] * z,
153
+ c[0] * x + c[1] * y + c[2] * z,
154
+ ];
154
155
  }
156
+ // Add up any number of same-length vectors
155
157
  export function add(...vecs) {
156
- // add up any number of same-length vectors
157
158
  if (vecs.length === 0)
158
159
  throw new Error(`Cannot add zero vectors`);
159
- const first_vec = vecs[0];
160
- const length = first_vec.length;
161
- // Validate all vectors have the same length
162
- for (const vec of vecs) {
163
- if (vec.length !== length) {
164
- throw new Error(`All vectors must have the same length`);
165
- }
160
+ const length = vecs[0].length;
161
+ if (vecs.some((vec) => vec.length !== length)) {
162
+ throw new Error(`All vectors must have the same length`);
166
163
  }
167
164
  const result = Array.from({ length }).fill(0);
168
165
  for (const vec of vecs) {
@@ -180,20 +177,14 @@ export function subtract(vec1, vec2) {
180
177
  }
181
178
  // Validate matrix structure and return column count
182
179
  function validate_matrix(mat, name) {
183
- // Check for empty matrix (no rows)
184
- if (mat.length === 0) {
180
+ if (mat.length === 0)
185
181
  throw new Error(`${name} must have at least one row`);
186
- }
187
182
  if (!mat.every((row) => Array.isArray(row))) {
188
183
  throw new Error(`${name} must contain only array rows (no undefined/non-array elements)`);
189
184
  }
190
- const cols = mat[0]?.length;
191
- if (!Number.isFinite(cols))
192
- throw new Error(`${name} has no columns`);
193
- // Check for zero columns
194
- if (cols === 0) {
185
+ const cols = mat[0].length;
186
+ if (cols === 0)
195
187
  throw new Error(`${name} must have at least one column`);
196
- }
197
188
  if (!mat.every((row) => row.length === cols)) {
198
189
  throw new Error(`${name} must be rectangular`);
199
190
  }
@@ -293,7 +284,10 @@ export function scale_lattice_matrix(orig_matrix, scaling_factors) {
293
284
  [c[0] * nz, c[1] * nz, c[2] * nz],
294
285
  ];
295
286
  }
296
- const create_cart_to_frac_matrix = (lattice) => matrix_inverse_3x3(transpose_3x3_matrix(lattice));
287
+ // Matrix mapping Cartesian coords to fractional (inverse of transposed
288
+ // row-vector lattice). Prefer create_cart_to_frac unless the raw matrix is
289
+ // needed, e.g. for allocation-free scalar arithmetic in hot loops.
290
+ export const create_cart_to_frac_matrix = (lattice) => matrix_inverse_3x3(transpose_3x3_matrix(lattice));
297
291
  // Curried fractional→Cartesian converter (caches transposed matrix)
298
292
  export const create_frac_to_cart = (lattice) => {
299
293
  const transposed = transpose_3x3_matrix(lattice);
@@ -426,6 +420,25 @@ export const cross_3d = (vec1, vec2) => [
426
420
  vec1[2] * vec2[0] - vec1[0] * vec2[2],
427
421
  vec1[0] * vec2[1] - vec1[1] * vec2[0],
428
422
  ];
423
+ // Perpendicular distance between opposite cell faces per axis: volume / opposite-
424
+ // face area. This (not the lattice vector length) is the correct denominator for
425
+ // per-axis fractional reach in oblique cells. Degenerate (zero-volume) cells →
426
+ // Infinity so callers' `dist / height` collapses to 0.
427
+ export function cell_heights(matrix) {
428
+ const [a_vec, b_vec, c_vec] = matrix;
429
+ const cross_bc = cross_3d(b_vec, c_vec);
430
+ const volume = Math.abs(dot(a_vec, cross_bc));
431
+ if (volume === 0)
432
+ return [Infinity, Infinity, Infinity];
433
+ // height along axis k = volume / area of the face spanned by the OTHER two vectors
434
+ const height_a = volume / Math.hypot(...cross_bc); // face b×c ⟂ a
435
+ const height_b = volume / Math.hypot(...cross_3d(a_vec, c_vec)); // face a×c ⟂ b
436
+ const height_c = volume / Math.hypot(...cross_3d(a_vec, b_vec)); // face a×b ⟂ c
437
+ return [height_a, height_b, height_c];
438
+ }
439
+ // `dist` Å of real-space reach as a fractional pad per axis (via cell heights,
440
+ // correct for oblique cells). Degenerate cells → 0 (no images).
441
+ export const frac_cutoff_per_axis = (matrix, dist) => cell_heights(matrix).map((height) => dist / height);
429
442
  // Scalar linear interpolation
430
443
  export const lerp = (start, end, t) => start + t * (end - start);
431
444
  // Vec3 linear interpolation
@@ -792,11 +805,12 @@ export function compute_bounding_box_2d(vertices) {
792
805
  export function polygon_centroid(vertices) {
793
806
  if (vertices.length === 0)
794
807
  return [0, 0];
795
- if (vertices.length < 3) {
796
- const sum_x = vertices.reduce((acc, [x]) => acc + x, 0);
797
- const sum_y = vertices.reduce((acc, [, y]) => acc + y, 0);
798
- return [sum_x / vertices.length, sum_y / vertices.length];
799
- }
808
+ const vertex_average = () => [
809
+ vertices.reduce((acc, [x]) => acc + x, 0) / vertices.length,
810
+ vertices.reduce((acc, [, y]) => acc + y, 0) / vertices.length,
811
+ ];
812
+ if (vertices.length < 3)
813
+ return vertex_average();
800
814
  let [signed_area, cx, cy] = [0, 0, 0];
801
815
  for (let idx = 0; idx < vertices.length; idx++) {
802
816
  const [x0, y0] = vertices[idx];
@@ -807,12 +821,8 @@ export function polygon_centroid(vertices) {
807
821
  cy += (y0 + y1) * cross;
808
822
  }
809
823
  signed_area *= 0.5;
810
- // Fall back to vertex average for degenerate polygons
811
- if (Math.abs(signed_area) < EPS) {
812
- const sum_x = vertices.reduce((acc, [x]) => acc + x, 0);
813
- const sum_y = vertices.reduce((acc, [, y]) => acc + y, 0);
814
- return [sum_x / vertices.length, sum_y / vertices.length];
815
- }
824
+ if (Math.abs(signed_area) < EPS)
825
+ return vertex_average();
816
826
  const factor = 1 / (6 * signed_area);
817
827
  return [cx * factor, cy * factor];
818
828
  }
@@ -891,11 +901,11 @@ export const cross_2d = (origin, point_a, point_b) => (point_a[0] - origin[0]) *
891
901
  (point_a[1] - origin[1]) * (point_b[0] - origin[0]);
892
902
  // One half of Andrew's monotone chain built from x-then-y *pre-sorted* points
893
903
  // (lower chain; pass reversed input for the upper chain).
894
- export const monotone_chain = (sorted) => {
904
+ export const monotone_chain = (sorted, tolerance = 0) => {
895
905
  const chain = [];
896
906
  for (const pt of sorted) {
897
907
  while (chain.length >= 2 &&
898
- cross_2d(chain[chain.length - 2], chain[chain.length - 1], pt) <= 0) {
908
+ cross_2d(chain[chain.length - 2], chain[chain.length - 1], pt) <= tolerance) {
899
909
  chain.pop();
900
910
  }
901
911
  chain.push(pt);
@@ -904,12 +914,12 @@ export const monotone_chain = (sorted) => {
904
914
  };
905
915
  // Full 2D convex hull via Andrew's monotone chain algorithm.
906
916
  // Returns vertices in counter-clockwise order.
907
- export function convex_hull_2d(points) {
917
+ export function convex_hull_2d(points, tolerance = 0) {
908
918
  if (points.length < 3)
909
919
  return [...points];
910
920
  const sorted = points.toSorted((a, b) => a[0] - b[0] || a[1] - b[1]);
911
- const lower = monotone_chain(sorted);
912
- const upper = monotone_chain(sorted.toReversed());
921
+ const lower = monotone_chain(sorted, tolerance);
922
+ const upper = monotone_chain(sorted.toReversed(), tolerance);
913
923
  // Remove last point of each half (it's the first point of the other)
914
924
  lower.pop();
915
925
  upper.pop();
@@ -38,47 +38,28 @@
38
38
  return { x: Math.max(0, x), y: Math.max(0, y) }
39
39
  }
40
40
 
41
- // Handle click outside to close
42
- function handle_click_outside(event: MouseEvent) {
43
- const target = event.target
44
- if (target instanceof Element && visible) {
45
- const menu = target.closest(`.context-menu`)
46
- if (!menu) on_close?.()
47
- }
48
- }
49
-
50
- // Handle right-click outside to close
51
- function handle_right_click_outside(event: MouseEvent) {
52
- if (!visible) return
53
- const target = event.target
54
- const menu = target instanceof Element ? target.closest(`.context-menu`) : null
55
- if (!menu) {
56
- event.preventDefault()
57
- on_close?.()
58
- }
59
- }
60
-
61
- // Handle keyboard shortcuts
62
- function handle_keydown(event: KeyboardEvent) {
63
- if (event.key === `Escape` && visible) on_close?.()
64
- }
65
-
66
- // Handle option selection
67
- function handle_option_click(section_title: string, option: MenuOption) {
68
- if (!option.disabled) on_select?.(section_title, option)
41
+ // Close on click or right-click outside the menu (right-click also suppresses
42
+ // the native context menu)
43
+ function handle_outside_pointer(event: MouseEvent) {
44
+ if (!visible || !(event.target instanceof Element)) return
45
+ if (event.target.closest(`.context-menu`)) return
46
+ if (event.type === `contextmenu`) event.preventDefault()
47
+ on_close?.()
69
48
  }
70
49
  </script>
71
50
 
72
51
  <svelte:document
73
- onclick={handle_click_outside}
74
- oncontextmenu={handle_right_click_outside}
75
- onkeydown={handle_keydown}
52
+ onclick={handle_outside_pointer}
53
+ oncontextmenu={handle_outside_pointer}
54
+ onkeydown={(event) => {
55
+ if (event.key === `Escape` && visible) on_close?.()
56
+ }}
76
57
  />
77
58
 
78
59
  {#if visible}
79
60
  {@const { x, y } = get_smart_position()}
80
61
  {@const style = `position: absolute; left: ${x}px; top: ${y}px; ${rest.style ?? ``}`}
81
- <div {...rest} class="context-menu {rest.class ?? ``}" {style} bind:this={menu_element}>
62
+ <div {...rest} class={[`context-menu`, rest.class]} {style} bind:this={menu_element}>
82
63
  {#each sections as { title, options } (title)}
83
64
  <div class="section">
84
65
  <div class="header">{title}</div>
@@ -86,7 +67,9 @@
86
67
  <button
87
68
  class:selected={selected_values[title] === option.value}
88
69
  class:disabled={option.disabled}
89
- onclick={() => handle_option_click(title, option)}
70
+ onclick={() => {
71
+ if (!option.disabled) on_select?.(title, option)
72
+ }}
90
73
  >
91
74
  {#if option.icon}
92
75
  <Icon icon={option.icon as IconName} />
@@ -104,7 +87,9 @@
104
87
  background: var(--surface-bg);
105
88
  border: 1px solid var(--border-color);
106
89
  border-radius: var(--context-menu-border-radius, var(--border-radius, 3pt));
107
- box-shadow: 0 8px 16px -4px rgba(0, 0, 0, 0.3), 0 4px 8px -2px rgba(0, 0, 0, 0.1);
90
+ box-shadow:
91
+ 0 8px 16px -4px rgba(0, 0, 0, 0.3),
92
+ 0 4px 8px -2px rgba(0, 0, 0, 0.1);
108
93
  backdrop-filter: blur(4px);
109
94
  min-width: var(--context-menu-min-width, 160px);
110
95
  overflow: hidden;
@@ -2,16 +2,22 @@
2
2
  import Icon from '../Icon.svelte'
3
3
  import type { HTMLButtonAttributes } from 'svelte/elements'
4
4
 
5
- let { copied = false, label, title = label, onclick, ...rest }: Omit<
6
- HTMLButtonAttributes,
7
- `type` | `aria-label`
8
- > & { copied?: boolean; label: string } = $props()
5
+ let {
6
+ copied = false,
7
+ label,
8
+ title = label,
9
+ onclick,
10
+ ...rest
11
+ }: Omit<HTMLButtonAttributes, `type` | `aria-label`> & {
12
+ copied?: boolean
13
+ label: string
14
+ } = $props()
9
15
  </script>
10
16
 
11
17
  <button
12
18
  {...rest}
13
19
  type="button"
14
- class="copy-button {rest.class ?? ``}"
20
+ class={[`copy-button`, rest.class]}
15
21
  aria-label={label}
16
22
  {title}
17
23
  {onclick}
@@ -13,7 +13,12 @@
13
13
  } = $props()
14
14
  </script>
15
15
 
16
- {#snippet control_button(callback: () => void, css_class: string, icon: IconName, label: string)}
16
+ {#snippet control_button(
17
+ callback: () => void,
18
+ css_class: string,
19
+ icon: IconName,
20
+ label: string,
21
+ )}
17
22
  <button
18
23
  type="button"
19
24
  class={css_class}
@@ -2,7 +2,7 @@
2
2
  import Icon from '../Icon.svelte'
3
3
  import type { IconName } from '../icons'
4
4
  import { DragControlTab } from './'
5
- import type { Snippet } from 'svelte'
5
+ import { onDestroy, type Snippet } from 'svelte'
6
6
  import { draggable, tooltip } from 'svelte-multiselect/attachments'
7
7
  import type { HTMLAttributes } from 'svelte/elements'
8
8
 
@@ -25,16 +25,19 @@
25
25
  has_been_dragged = $bindable(false),
26
26
  currently_dragging = $bindable(false),
27
27
  resizable = `none`,
28
+ position = `absolute`,
28
29
  }: {
29
30
  show?: boolean
30
31
  show_pane?: boolean
31
32
  children: Snippet<
32
- [{
33
- show: boolean
34
- show_control_buttons: boolean
35
- has_been_dragged: boolean
36
- currently_dragging: boolean
37
- }]
33
+ [
34
+ {
35
+ show: boolean
36
+ show_control_buttons: boolean
37
+ has_been_dragged: boolean
38
+ currently_dragging: boolean
39
+ },
40
+ ]
38
41
  >
39
42
  // Toggle button
40
43
  toggle_props?: HTMLAttributes<HTMLButtonElement>
@@ -49,6 +52,10 @@
49
52
  persistent?: boolean
50
53
  // Resize mode: 'both' | 'width' | 'height' | 'none'
51
54
  resizable?: `both` | `width` | `height` | `none`
55
+ // 'fixed' renders the pane relative to the viewport so it escapes
56
+ // overflow-clipping ancestors (e.g. cards/tables with overflow: hidden)
57
+ // and clamps its max-height to the space below the toggle button.
58
+ position?: `absolute` | `fixed`
52
59
  // Callbacks
53
60
  onclose?: () => void
54
61
  on_drag_start?: () => void
@@ -63,6 +70,8 @@
63
70
  let show_control_buttons = $state(false)
64
71
  let resizing = $state(false)
65
72
  let resize_end_time = 0
73
+ const viewport_margin_px = 8
74
+ const min_reachable_pane_height_px = 180
66
75
 
67
76
  // Resize via bottom-right grip
68
77
  function handle_resize_start(event: PointerEvent) {
@@ -83,9 +92,7 @@
83
92
  pane_div.style.width = `${Math.max(200, start_w + evt.clientX - start_x)}px`
84
93
  }
85
94
  if (resizable !== `width`) {
86
- pane_div.style.maxHeight = `${
87
- Math.max(100, start_h + evt.clientY - start_y)
88
- }px`
95
+ pane_div.style.maxHeight = `${Math.max(100, start_h + evt.clientY - start_y)}px`
89
96
  }
90
97
  }
91
98
  function on_up() {
@@ -111,21 +118,29 @@
111
118
  onclose()
112
119
  }
113
120
 
114
- function reset_position() {
115
- if (toggle_pane_btn) {
116
- const pos = calculate_position()
117
- initial_position = pos
118
- if (pane_div) {
119
- Object.assign(pane_div.style, {
120
- left: pos.left,
121
- top: pos.top,
122
- right: `auto`,
123
- bottom: `auto`,
124
- width: ``,
125
- maxHeight: ``,
126
- })
127
- }
121
+ // Move the pane back under the toggle button, clear manual size overrides and
122
+ // refresh --pane-viewport-clamp (without which a reset after a drag + window
123
+ // resize would keep a stale bottom-edge cap)
124
+ function position_pane() {
125
+ if (pane_div) {
126
+ // Clear manual size first so calculate_position() uses natural pane dimensions
127
+ pane_div.style.width = ``
128
+ pane_div.style.maxHeight = ``
128
129
  }
130
+ const pos = calculate_position()
131
+ initial_position = pos
132
+ if (!pane_div) return
133
+ Object.assign(pane_div.style, {
134
+ left: pos.left,
135
+ top: pos.top,
136
+ right: `auto`,
137
+ bottom: `auto`,
138
+ })
139
+ apply_viewport_clamp()
140
+ }
141
+
142
+ function reset_position() {
143
+ if (toggle_pane_btn) position_pane()
129
144
  // Hide the control buttons after reset
130
145
  show_control_buttons = false
131
146
  has_been_dragged = false
@@ -147,10 +162,31 @@
147
162
  const pane_width = pane_div?.getBoundingClientRect().width || 450
148
163
  const ox = offset.x ?? 5
149
164
  const oy = offset.y ?? 5
165
+
166
+ if (position === `fixed`) {
167
+ // Viewport-relative: keep the pane reachable within the screen.
168
+ const left = Math.max(
169
+ viewport_margin_px,
170
+ Math.min(
171
+ toggle_rect.right - pane_width + ox,
172
+ window.innerWidth - pane_width - viewport_margin_px,
173
+ ),
174
+ )
175
+ const top = Math.max(
176
+ viewport_margin_px,
177
+ Math.min(
178
+ toggle_rect.bottom + oy,
179
+ window.innerHeight - min_reachable_pane_height_px - viewport_margin_px,
180
+ ),
181
+ )
182
+ return { left: `${left}px`, top: `${top}px` }
183
+ }
184
+
150
185
  const positioned_ancestor = toggle_pane_btn.offsetParent
151
186
  const ancestor_rect = positioned_ancestor?.getBoundingClientRect()
152
187
 
153
- if (!ancestor_rect) { // Fallback to document positioning
188
+ if (!ancestor_rect) {
189
+ // Fallback to document positioning
154
190
  const scroll_x = window.scrollX || document.documentElement.scrollLeft
155
191
  const scroll_y = window.scrollY || document.documentElement.scrollTop
156
192
  return {
@@ -172,52 +208,49 @@
172
208
  // (Playwright and some browsers synthesize a click after pointer up)
173
209
  if (Date.now() - resize_end_time < 200) return
174
210
 
175
- const target = event.target
176
- const is_toggle_button = target instanceof Node &&
177
- (target === toggle_pane_btn || (toggle_pane_btn?.contains(target) ?? false))
178
- const is_inside_pane = target instanceof Node &&
179
- (target === pane_div || (pane_div?.contains(target) ?? false))
180
-
181
- if (!is_toggle_button && !is_inside_pane && !currently_dragging && !resizing) {
182
- close_pane()
183
- }
211
+ const target = event.target instanceof Node ? event.target : null
212
+ const inside_toggle_or_pane = [toggle_pane_btn, pane_div].some(
213
+ (el) => el && (el === target || el.contains(target)),
214
+ )
215
+ if (!inside_toggle_or_pane && !currently_dragging && !resizing) close_pane()
184
216
  }
185
217
 
186
218
  // Debounced resize handler for better performance
187
- let resize_timeout: ReturnType<typeof setTimeout> | undefined = $state(undefined)
219
+ let resize_timeout: ReturnType<typeof setTimeout> | undefined
220
+ onDestroy(() => resize_timeout && clearTimeout(resize_timeout))
188
221
 
189
- function handle_resize() { // Only reposition if pane is visible and hasn't been manually dragged
222
+ function handle_resize() {
223
+ // Only reposition if pane is visible and hasn't been manually dragged
190
224
  if (!show || has_been_dragged || currently_dragging) return
191
225
 
192
226
  if (resize_timeout) clearTimeout(resize_timeout)
193
- const current_timeout = setTimeout(() => {
194
- if (resize_timeout !== current_timeout) return
195
- if (show && toggle_pane_btn && !has_been_dragged && pane_div) {
196
- const pos = calculate_position()
197
- initial_position = pos
198
- pane_div.style.left = pos.left
199
- pane_div.style.top = pos.top
200
- }
227
+ resize_timeout = setTimeout(() => {
228
+ // Re-check state since it may have changed during the debounce window
229
+ if (show && toggle_pane_btn && !has_been_dragged && pane_div) position_pane()
201
230
  }, 50) // Debounce resize events
202
- resize_timeout = current_timeout
231
+ }
232
+
233
+ // Fixed panes must never extend past the bottom viewport edge: cap the
234
+ // --pane-viewport-clamp var (combined with --pane-max-height via min() in
235
+ // CSS) to the space below the pane's top edge. No minimum here — usability
236
+ // is handled by calculate_position, which clamps the top so at least
237
+ // min_reachable_pane_height_px of space remains below.
238
+ function apply_viewport_clamp(): void {
239
+ if (position !== `fixed` || !pane_div || !toggle_pane_btn) return
240
+ // style.top is a `${n}px` string when set; "0px" is a valid position, so only
241
+ // fall back to the live rect when the inline style is unset or non-numeric
242
+ const parsed_top = Number(pane_div.style.top.replace(/px$/, ``))
243
+ const pane_top =
244
+ pane_div.style.top && !Number.isNaN(parsed_top)
245
+ ? parsed_top
246
+ : pane_div.getBoundingClientRect().top
247
+ const available = window.innerHeight - pane_top - viewport_margin_px
248
+ pane_div.style.setProperty(`--pane-viewport-clamp`, `${Math.max(0, available)}px`)
203
249
  }
204
250
 
205
251
  // Position pane when shown
206
252
  $effect(() => {
207
- if (show && toggle_pane_btn && !has_been_dragged) {
208
- const pos = calculate_position()
209
- initial_position = pos
210
- if (pane_div) {
211
- Object.assign(pane_div.style, {
212
- left: pos.left,
213
- top: pos.top,
214
- right: `auto`,
215
- bottom: `auto`,
216
- width: ``,
217
- maxHeight: ``,
218
- })
219
- }
220
- }
253
+ if (show && toggle_pane_btn && !has_been_dragged) position_pane()
221
254
  })
222
255
  </script>
223
256
 
@@ -240,7 +273,7 @@
240
273
  {...toggle_props}
241
274
  style={toggle_props.style ?? ``}
242
275
  onclick={toggle_pane}
243
- class="pane-toggle {toggle_props.class ?? ``}"
276
+ class={[`pane-toggle`, toggle_props.class]}
244
277
  {@attach tooltip({ content: toggle_props.title ?? (show ? `Close pane` : `Open pane`) })}
245
278
  >
246
279
  <Icon icon={show ? open_icon : closed_icon} style={icon_style} />
@@ -256,12 +289,13 @@
256
289
  role="dialog"
257
290
  aria-label="Draggable pane"
258
291
  aria-modal="false"
292
+ style:position
259
293
  style:max-width={max_width}
260
294
  style:top={initial_position.top}
261
295
  style:left={initial_position.left}
262
296
  style:display={show ? `grid` : `none`}
263
297
  {...pane_props}
264
- class="draggable-pane toc-exclude {show ? `pane-open` : ``} {pane_props.class ?? ``}"
298
+ class={[`draggable-pane toc-exclude`, show && `pane-open`, pane_props.class]}
265
299
  >
266
300
  <DragControlTab
267
301
  show_controls={show_control_buttons}
@@ -319,7 +353,7 @@
319
353
  background-color: color-mix(in srgb, currentColor 8%, transparent);
320
354
  }
321
355
  div.draggable-pane {
322
- position: absolute; /* Use absolute so pane scrolls with page content */
356
+ /* position set inline via style:position (default absolute: scrolls with page) */
323
357
  background: var(--pane-bg, var(--page-bg, light-dark(white, black)));
324
358
  border: var(
325
359
  --pane-border,
@@ -329,21 +363,26 @@
329
363
  box-sizing: border-box;
330
364
  box-shadow: var(
331
365
  --pane-box-shadow,
332
- light-dark(
333
- 0 4px 20px -4px rgba(0, 0, 0, 0.15),
334
- 0 8px 16px -4px rgba(0, 0, 0, 0.3)
335
- )
366
+ light-dark(0 4px 20px -4px rgba(0, 0, 0, 0.15), 0 8px 16px -4px rgba(0, 0, 0, 0.3))
336
367
  );
337
- z-index: var(--pane-z-index, 10);
368
+ z-index: var(--pane-z-index, var(--z-index-viewer-pane, 10));
369
+ /* own compositing layer, or WKWebView paints the canvas over this (see app.css) */
370
+ will-change: transform;
338
371
  display: grid;
339
372
  text-align: left;
340
373
  /* Exclude position from being transitioned to prevent sluggish dragging */
341
- transition: opacity 0.3s, background-color 0.3s, border-color 0.3s, box-shadow 0.3s;
374
+ transition:
375
+ opacity 0.3s,
376
+ background-color 0.3s,
377
+ border-color 0.3s,
378
+ box-shadow 0.3s;
342
379
  width: 28em;
343
380
  max-width: var(--pane-max-width, 80cqw);
344
381
  overflow: visible; /* Allow control-tab to protrude above the pane border */
345
382
  min-height: var(--pane-min-height, auto);
346
- max-height: var(--pane-max-height, 80vh);
383
+ /* --pane-viewport-clamp (set for position="fixed" panes) keeps the pane
384
+ above the bottom viewport edge even when the toggle sits low on screen */
385
+ max-height: min(var(--pane-max-height, 80vh), var(--pane-viewport-clamp, 200vh));
347
386
  }
348
387
  .draggable-pane .pane-content {
349
388
  padding: var(--pane-padding, 1ex);
@@ -368,10 +407,7 @@
368
407
  }
369
408
  .draggable-pane :global(hr) {
370
409
  border: none;
371
- background: var(
372
- --pane-hr-bg,
373
- light-dark(rgba(0, 0, 0, 0.08), rgba(255, 255, 255, 0.1))
374
- );
410
+ background: var(--pane-hr-bg, light-dark(rgba(0, 0, 0, 0.08), rgba(255, 255, 255, 0.1)));
375
411
  margin: var(--pane-hr-margin, 4pt 0);
376
412
  height: 1px;
377
413
  }
@@ -411,7 +447,7 @@
411
447
  .draggable-pane :global(input[type='number']) {
412
448
  box-sizing: border-box;
413
449
  text-align: center;
414
- width: 2.2em;
450
+ width: 3.5em;
415
451
  margin: 0 3pt;
416
452
  flex-shrink: 0;
417
453
  }
@@ -1,5 +1,5 @@
1
1
  import type { IconName } from '../icons';
2
- import type { Snippet } from 'svelte';
2
+ import { type Snippet } from 'svelte';
3
3
  import type { HTMLAttributes } from 'svelte/elements';
4
4
  type $$ComponentProps = {
5
5
  show?: boolean;
@@ -24,6 +24,7 @@ type $$ComponentProps = {
24
24
  pane_props?: HTMLAttributes<HTMLDivElement>;
25
25
  persistent?: boolean;
26
26
  resizable?: `both` | `width` | `height` | `none`;
27
+ position?: `absolute` | `fixed`;
27
28
  onclose?: () => void;
28
29
  on_drag_start?: () => void;
29
30
  toggle_pane_btn?: HTMLButtonElement;
@@ -0,0 +1,32 @@
1
+ <!-- Small text overlay with a frosted-glass backdrop, for annotating visual
2
+ content (3D structure viewers, plots) without fully obscuring it. Shared by
3
+ StructurePopup's stats block and StructureCarousel's card headers so both
4
+ render identically. Position/size via --glass-chip-* custom properties. -->
5
+ <script lang="ts">
6
+ import type { Snippet } from 'svelte'
7
+ import type { HTMLAttributes } from 'svelte/elements'
8
+
9
+ let { children, ...rest }: HTMLAttributes<HTMLDivElement> & { children: Snippet } = $props()
10
+ </script>
11
+
12
+ <div {...rest} class={[`glass-chip`, rest.class]}>
13
+ {@render children()}
14
+ </div>
15
+
16
+ <style>
17
+ .glass-chip {
18
+ position: absolute;
19
+ top: var(--glass-chip-top, 10px);
20
+ left: var(--glass-chip-left, 10px);
21
+ z-index: var(--glass-chip-z, var(--z-index-viewer-chip, 2));
22
+ /* own compositing layer, or WKWebView paints the canvas over this (see app.css) */
23
+ will-change: transform;
24
+ max-width: var(--glass-chip-max-width, calc(100% - 20px));
25
+ padding: 4px 8px;
26
+ border-radius: 6px;
27
+ background: var(--glass-chip-bg, transparent);
28
+ backdrop-filter: blur(8px);
29
+ color: var(--text-color);
30
+ font-size: var(--glass-chip-font-size, 0.85em);
31
+ }
32
+ </style>
@@ -0,0 +1,8 @@
1
+ import type { Snippet } from 'svelte';
2
+ import type { HTMLAttributes } from 'svelte/elements';
3
+ type $$ComponentProps = HTMLAttributes<HTMLDivElement> & {
4
+ children: Snippet;
5
+ };
6
+ declare const GlassChip: import("svelte").Component<$$ComponentProps, {}, "">;
7
+ type GlassChip = ReturnType<typeof GlassChip>;
8
+ export default GlassChip;