matterviz 0.3.1 → 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 (358) hide show
  1. package/dist/EmptyState.svelte +10 -2
  2. package/dist/FilePicker.svelte +154 -96
  3. package/dist/Icon.svelte +20 -14
  4. package/dist/MillerIndexInput.svelte +27 -21
  5. package/dist/api/optimade.js +6 -6
  6. package/dist/app.css +216 -178
  7. package/dist/brillouin/BrillouinZone.svelte +299 -198
  8. package/dist/brillouin/BrillouinZone.svelte.d.ts +1 -1
  9. package/dist/brillouin/BrillouinZoneControls.svelte +32 -5
  10. package/dist/brillouin/BrillouinZoneExportPane.svelte +74 -55
  11. package/dist/brillouin/BrillouinZoneExportPane.svelte.d.ts +1 -1
  12. package/dist/brillouin/BrillouinZoneInfoPane.svelte +99 -68
  13. package/dist/brillouin/BrillouinZoneScene.svelte +277 -165
  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 +327 -0
  18. package/dist/chempot-diagram/ChemPotDiagram.svelte.d.ts +13 -0
  19. package/dist/chempot-diagram/ChemPotDiagram2D.svelte +847 -0
  20. package/dist/chempot-diagram/ChemPotDiagram2D.svelte.d.ts +16 -0
  21. package/dist/chempot-diagram/ChemPotDiagram3D.svelte +3194 -0
  22. package/dist/chempot-diagram/ChemPotDiagram3D.svelte.d.ts +16 -0
  23. package/dist/chempot-diagram/ChemPotScene3D.svelte +11 -0
  24. package/dist/chempot-diagram/ChemPotScene3D.svelte.d.ts +7 -0
  25. package/dist/chempot-diagram/async-compute.svelte.d.ts +3 -0
  26. package/dist/chempot-diagram/async-compute.svelte.js +77 -0
  27. package/dist/chempot-diagram/chempot-worker.d.ts +1 -0
  28. package/dist/chempot-diagram/chempot-worker.js +11 -0
  29. package/dist/chempot-diagram/color.d.ts +10 -0
  30. package/dist/chempot-diagram/color.js +32 -0
  31. package/dist/chempot-diagram/compute.d.ts +48 -0
  32. package/dist/chempot-diagram/compute.js +812 -0
  33. package/dist/chempot-diagram/index.d.ts +6 -0
  34. package/dist/chempot-diagram/index.js +6 -0
  35. package/dist/chempot-diagram/pointer.d.ts +16 -0
  36. package/dist/chempot-diagram/pointer.js +40 -0
  37. package/dist/chempot-diagram/temperature.d.ts +15 -0
  38. package/dist/chempot-diagram/temperature.js +36 -0
  39. package/dist/chempot-diagram/types.d.ts +86 -0
  40. package/dist/chempot-diagram/types.js +28 -0
  41. package/dist/colors/index.d.ts +3 -1
  42. package/dist/colors/index.js +9 -3
  43. package/dist/composition/BarChart.svelte +141 -77
  44. package/dist/composition/BubbleChart.svelte +107 -52
  45. package/dist/composition/Composition.svelte +100 -79
  46. package/dist/composition/Formula.svelte +108 -62
  47. package/dist/composition/FormulaFilter.svelte +973 -353
  48. package/dist/composition/FormulaFilter.svelte.d.ts +35 -1
  49. package/dist/composition/PieChart.svelte +199 -99
  50. package/dist/composition/PieChart.svelte.d.ts +1 -1
  51. package/dist/composition/format.d.ts +5 -0
  52. package/dist/composition/format.js +20 -3
  53. package/dist/composition/parse.js +14 -9
  54. package/dist/convex-hull/ConvexHull.svelte +93 -38
  55. package/dist/convex-hull/ConvexHull2D.svelte +551 -393
  56. package/dist/convex-hull/ConvexHull3D.svelte +1303 -825
  57. package/dist/convex-hull/ConvexHull4D.svelte +1012 -686
  58. package/dist/convex-hull/ConvexHullControls.svelte +115 -28
  59. package/dist/convex-hull/ConvexHullInfoPane.svelte +29 -3
  60. package/dist/convex-hull/ConvexHullStats.svelte +821 -249
  61. package/dist/convex-hull/ConvexHullStats.svelte.d.ts +6 -1
  62. package/dist/convex-hull/ConvexHullTooltip.svelte +41 -16
  63. package/dist/convex-hull/GasPressureControls.svelte +104 -61
  64. package/dist/convex-hull/StructurePopup.svelte +25 -4
  65. package/dist/convex-hull/TemperatureSlider.svelte +45 -25
  66. package/dist/convex-hull/barycentric-coords.js +13 -7
  67. package/dist/convex-hull/demo-temperature.d.ts +6 -0
  68. package/dist/convex-hull/demo-temperature.js +40 -0
  69. package/dist/convex-hull/gas-thermodynamics.js +17 -12
  70. package/dist/convex-hull/helpers.d.ts +10 -1
  71. package/dist/convex-hull/helpers.js +79 -38
  72. package/dist/convex-hull/index.d.ts +1 -0
  73. package/dist/convex-hull/index.js +1 -0
  74. package/dist/convex-hull/thermodynamics.d.ts +8 -21
  75. package/dist/convex-hull/thermodynamics.js +163 -69
  76. package/dist/convex-hull/types.d.ts +12 -12
  77. package/dist/convex-hull/types.js +0 -12
  78. package/dist/coordination/CoordinationBarPlot.svelte +232 -176
  79. package/dist/element/BohrAtom.svelte +56 -13
  80. package/dist/element/ElementHeading.svelte +7 -2
  81. package/dist/element/ElementPhoto.svelte +15 -9
  82. package/dist/element/ElementStats.svelte +10 -4
  83. package/dist/element/ElementTile.svelte +137 -73
  84. package/dist/element/Nucleus.svelte +39 -11
  85. package/dist/element/data.js +2 -14
  86. package/dist/element/data.json.gz +0 -0
  87. package/dist/element/types.d.ts +1 -0
  88. package/dist/feedback/ClickFeedback.svelte +16 -5
  89. package/dist/feedback/DragOverlay.svelte +10 -2
  90. package/dist/feedback/Spinner.svelte +4 -2
  91. package/dist/feedback/StatusMessage.svelte +8 -2
  92. package/dist/fermi-surface/FermiSlice.svelte +118 -88
  93. package/dist/fermi-surface/FermiSurface.svelte +336 -239
  94. package/dist/fermi-surface/FermiSurface.svelte.d.ts +1 -1
  95. package/dist/fermi-surface/FermiSurfaceControls.svelte +113 -46
  96. package/dist/fermi-surface/FermiSurfaceScene.svelte +536 -343
  97. package/dist/fermi-surface/FermiSurfaceScene.svelte.d.ts +1 -1
  98. package/dist/fermi-surface/FermiSurfaceTooltip.svelte +14 -5
  99. package/dist/fermi-surface/compute.js +16 -20
  100. package/dist/fermi-surface/parse.js +37 -33
  101. package/dist/fermi-surface/symmetry.js +2 -7
  102. package/dist/fermi-surface/types.d.ts +3 -5
  103. package/dist/heatmap-matrix/HeatmapMatrix.svelte +1527 -0
  104. package/dist/heatmap-matrix/HeatmapMatrix.svelte.d.ts +110 -0
  105. package/dist/heatmap-matrix/HeatmapMatrixControls.svelte +225 -0
  106. package/dist/heatmap-matrix/HeatmapMatrixControls.svelte.d.ts +30 -0
  107. package/dist/heatmap-matrix/index.d.ts +53 -0
  108. package/dist/heatmap-matrix/index.js +100 -0
  109. package/dist/heatmap-matrix/shared.d.ts +2 -0
  110. package/dist/heatmap-matrix/shared.js +4 -0
  111. package/dist/icons.d.ts +111 -0
  112. package/dist/icons.js +158 -0
  113. package/dist/index.d.ts +5 -2
  114. package/dist/index.js +5 -2
  115. package/dist/io/decompress.js +1 -1
  116. package/dist/io/export.d.ts +3 -0
  117. package/dist/io/export.js +138 -140
  118. package/dist/io/file-drop.d.ts +7 -0
  119. package/dist/io/file-drop.js +43 -0
  120. package/dist/io/index.d.ts +2 -2
  121. package/dist/io/index.js +2 -112
  122. package/dist/io/is-binary.js +2 -3
  123. package/dist/io/types.d.ts +1 -0
  124. package/dist/io/url-drop.d.ts +2 -0
  125. package/dist/io/url-drop.js +117 -0
  126. package/dist/isosurface/Isosurface.svelte +220 -110
  127. package/dist/isosurface/IsosurfaceControls.svelte +65 -28
  128. package/dist/isosurface/parse.js +104 -56
  129. package/dist/isosurface/slice.d.ts +2 -1
  130. package/dist/isosurface/slice.js +8 -13
  131. package/dist/isosurface/types.d.ts +14 -1
  132. package/dist/isosurface/types.js +152 -5
  133. package/dist/labels.d.ts +2 -1
  134. package/dist/labels.js +12 -8
  135. package/dist/layout/FullscreenToggle.svelte +11 -2
  136. package/dist/layout/InfoCard.svelte +38 -6
  137. package/dist/layout/InfoTag.svelte +125 -94
  138. package/dist/layout/PropertyFilter.svelte +82 -37
  139. package/dist/layout/SettingsSection.svelte +85 -55
  140. package/dist/layout/SubpageGrid.svelte +82 -0
  141. package/dist/layout/SubpageGrid.svelte.d.ts +14 -0
  142. package/dist/layout/index.d.ts +1 -0
  143. package/dist/layout/index.js +1 -0
  144. package/dist/layout/json-tree/JsonNode.svelte +266 -223
  145. package/dist/layout/json-tree/JsonTree.svelte +516 -429
  146. package/dist/layout/json-tree/JsonTree.svelte.d.ts +1 -1
  147. package/dist/layout/json-tree/JsonValue.svelte +281 -173
  148. package/dist/layout/json-tree/types.d.ts +10 -2
  149. package/dist/layout/json-tree/utils.d.ts +2 -0
  150. package/dist/layout/json-tree/utils.js +37 -2
  151. package/dist/marching-cubes.js +25 -2
  152. package/dist/math.d.ts +20 -17
  153. package/dist/math.js +474 -57
  154. package/dist/overlays/ContextMenu.svelte +66 -40
  155. package/dist/overlays/DraggablePane.svelte +331 -154
  156. package/dist/overlays/DraggablePane.svelte.d.ts +2 -0
  157. package/dist/periodic-table/PeriodicTable.svelte +278 -145
  158. package/dist/periodic-table/PeriodicTableControls.svelte +178 -128
  159. package/dist/periodic-table/PropertySelect.svelte +25 -7
  160. package/dist/periodic-table/TableInset.svelte +8 -3
  161. package/dist/phase-diagram/IsobaricBinaryPhaseDiagram.svelte +559 -267
  162. package/dist/phase-diagram/IsobaricBinaryPhaseDiagram.svelte.d.ts +6 -2
  163. package/dist/phase-diagram/PhaseDiagramControls.svelte +131 -51
  164. package/dist/phase-diagram/PhaseDiagramControls.svelte.d.ts +3 -2
  165. package/dist/phase-diagram/PhaseDiagramEditorPane.svelte +126 -0
  166. package/dist/phase-diagram/PhaseDiagramEditorPane.svelte.d.ts +15 -0
  167. package/dist/phase-diagram/PhaseDiagramExportPane.svelte +160 -110
  168. package/dist/phase-diagram/PhaseDiagramExportPane.svelte.d.ts +8 -1
  169. package/dist/phase-diagram/PhaseDiagramTooltip.svelte +217 -86
  170. package/dist/phase-diagram/PhaseDiagramTooltip.svelte.d.ts +6 -3
  171. package/dist/phase-diagram/TdbInfoPanel.svelte +28 -4
  172. package/dist/phase-diagram/build-diagram.js +9 -9
  173. package/dist/phase-diagram/colors.js +1 -3
  174. package/dist/phase-diagram/index.d.ts +2 -0
  175. package/dist/phase-diagram/index.js +2 -0
  176. package/dist/phase-diagram/parse.js +10 -9
  177. package/dist/phase-diagram/svg-to-diagram.d.ts +2 -0
  178. package/dist/phase-diagram/svg-to-diagram.js +869 -0
  179. package/dist/phase-diagram/types.d.ts +10 -0
  180. package/dist/phase-diagram/utils.d.ts +8 -4
  181. package/dist/phase-diagram/utils.js +219 -74
  182. package/dist/plot/AxisLabel.svelte +51 -0
  183. package/dist/plot/AxisLabel.svelte.d.ts +16 -0
  184. package/dist/plot/BarPlot.svelte +1461 -768
  185. package/dist/plot/BarPlot.svelte.d.ts +3 -3
  186. package/dist/plot/BarPlotControls.svelte +33 -6
  187. package/dist/plot/BarPlotControls.svelte.d.ts +1 -1
  188. package/dist/plot/ColorBar.svelte +533 -383
  189. package/dist/plot/ColorBar.svelte.d.ts +1 -1
  190. package/dist/plot/ColorScaleSelect.svelte +28 -7
  191. package/dist/plot/ElementScatter.svelte +38 -16
  192. package/dist/plot/FillArea.svelte +152 -92
  193. package/dist/plot/Histogram.svelte +1162 -709
  194. package/dist/plot/Histogram.svelte.d.ts +1 -1
  195. package/dist/plot/HistogramControls.svelte +81 -18
  196. package/dist/plot/HistogramControls.svelte.d.ts +6 -2
  197. package/dist/plot/InteractiveAxisLabel.svelte +34 -11
  198. package/dist/plot/InteractiveAxisLabel.svelte.d.ts +1 -1
  199. package/dist/plot/Line.svelte +63 -28
  200. package/dist/plot/PlotControls.svelte +221 -96
  201. package/dist/plot/PlotControls.svelte.d.ts +1 -1
  202. package/dist/plot/PlotLegend.svelte +174 -91
  203. package/dist/plot/PlotTooltip.svelte +45 -6
  204. package/dist/plot/PortalSelect.svelte +175 -146
  205. package/dist/plot/ReferenceLine.svelte +77 -22
  206. package/dist/plot/ReferenceLine.svelte.d.ts +1 -0
  207. package/dist/plot/ReferenceLine3D.svelte +132 -107
  208. package/dist/plot/ReferencePlane.svelte +146 -123
  209. package/dist/plot/ScatterPlot.svelte +1880 -1156
  210. package/dist/plot/ScatterPlot.svelte.d.ts +3 -3
  211. package/dist/plot/ScatterPlot3D.svelte +256 -131
  212. package/dist/plot/ScatterPlot3D.svelte.d.ts +2 -2
  213. package/dist/plot/ScatterPlot3DControls.svelte +300 -297
  214. package/dist/plot/ScatterPlot3DControls.svelte.d.ts +2 -1
  215. package/dist/plot/ScatterPlot3DScene.svelte +608 -406
  216. package/dist/plot/ScatterPlot3DScene.svelte.d.ts +2 -2
  217. package/dist/plot/ScatterPlotControls.svelte +150 -70
  218. package/dist/plot/ScatterPlotControls.svelte.d.ts +1 -1
  219. package/dist/plot/ScatterPoint.svelte +98 -26
  220. package/dist/plot/ScatterPoint.svelte.d.ts +1 -0
  221. package/dist/plot/SpacegroupBarPlot.svelte +142 -85
  222. package/dist/plot/Surface3D.svelte +159 -108
  223. package/dist/plot/ZeroLines.svelte +96 -0
  224. package/dist/plot/ZeroLines.svelte.d.ts +32 -0
  225. package/dist/plot/ZoomRect.svelte +23 -0
  226. package/dist/plot/ZoomRect.svelte.d.ts +8 -0
  227. package/dist/plot/axis-utils.d.ts +1 -1
  228. package/dist/plot/axis-utils.js +1 -3
  229. package/dist/plot/data-cleaning.js +12 -28
  230. package/dist/plot/data-transform.js +2 -1
  231. package/dist/plot/fill-utils.js +2 -0
  232. package/dist/plot/index.d.ts +6 -2
  233. package/dist/plot/index.js +6 -2
  234. package/dist/plot/interactions.d.ts +8 -10
  235. package/dist/plot/interactions.js +2 -3
  236. package/dist/plot/layout.d.ts +11 -2
  237. package/dist/plot/layout.js +44 -17
  238. package/dist/plot/reference-line.d.ts +5 -22
  239. package/dist/plot/reference-line.js +12 -84
  240. package/dist/plot/scales.js +24 -36
  241. package/dist/plot/types.d.ts +53 -40
  242. package/dist/plot/types.js +12 -7
  243. package/dist/plot/utils/label-placement.d.ts +32 -15
  244. package/dist/plot/utils/label-placement.js +227 -63
  245. package/dist/plot/utils/series-visibility.js +2 -3
  246. package/dist/plot/utils.d.ts +1 -0
  247. package/dist/plot/utils.js +14 -0
  248. package/dist/rdf/RdfPlot.svelte +173 -132
  249. package/dist/rdf/calc-rdf.js +4 -5
  250. package/dist/sanitize.d.ts +4 -0
  251. package/dist/sanitize.js +107 -0
  252. package/dist/settings.d.ts +21 -6
  253. package/dist/settings.js +63 -19
  254. package/dist/spectral/Bands.svelte +963 -412
  255. package/dist/spectral/Bands.svelte.d.ts +22 -2
  256. package/dist/spectral/BandsAndDos.svelte +90 -49
  257. package/dist/spectral/BrillouinBandsDos.svelte +151 -93
  258. package/dist/spectral/Dos.svelte +389 -258
  259. package/dist/spectral/helpers.d.ts +23 -1
  260. package/dist/spectral/helpers.js +119 -51
  261. package/dist/spectral/types.d.ts +2 -0
  262. package/dist/state.svelte.d.ts +1 -1
  263. package/dist/state.svelte.js +3 -2
  264. package/dist/structure/Arrow.svelte +59 -20
  265. package/dist/structure/AtomLegend.svelte +231 -129
  266. package/dist/structure/AtomLegend.svelte.d.ts +1 -1
  267. package/dist/structure/Bond.svelte +73 -47
  268. package/dist/structure/CanvasTooltip.svelte +10 -2
  269. package/dist/structure/CellSelect.svelte +148 -51
  270. package/dist/structure/Cylinder.svelte +33 -17
  271. package/dist/structure/Lattice.svelte +88 -33
  272. package/dist/structure/Structure.svelte +1077 -821
  273. package/dist/structure/Structure.svelte.d.ts +1 -1
  274. package/dist/structure/StructureControls.svelte +373 -139
  275. package/dist/structure/StructureControls.svelte.d.ts +1 -1
  276. package/dist/structure/StructureExportPane.svelte +124 -89
  277. package/dist/structure/StructureExportPane.svelte.d.ts +1 -1
  278. package/dist/structure/StructureInfoPane.svelte +304 -231
  279. package/dist/structure/StructureScene.svelte +919 -445
  280. package/dist/structure/StructureScene.svelte.d.ts +16 -7
  281. package/dist/structure/atom-properties.d.ts +6 -2
  282. package/dist/structure/atom-properties.js +42 -29
  283. package/dist/structure/bonding.js +6 -7
  284. package/dist/structure/export.js +22 -34
  285. package/dist/structure/ferrox-wasm-types.d.ts +3 -2
  286. package/dist/structure/ferrox-wasm-types.js +0 -3
  287. package/dist/structure/ferrox-wasm.d.ts +3 -2
  288. package/dist/structure/ferrox-wasm.js +2 -3
  289. package/dist/structure/index.d.ts +16 -0
  290. package/dist/structure/index.js +88 -6
  291. package/dist/structure/measure.d.ts +2 -2
  292. package/dist/structure/measure.js +4 -44
  293. package/dist/structure/parse.js +130 -155
  294. package/dist/structure/partial-occupancy.d.ts +25 -0
  295. package/dist/structure/partial-occupancy.js +99 -0
  296. package/dist/structure/pbc.d.ts +1 -0
  297. package/dist/structure/pbc.js +16 -6
  298. package/dist/structure/supercell.d.ts +2 -2
  299. package/dist/structure/supercell.js +12 -22
  300. package/dist/structure/validation.js +5 -3
  301. package/dist/symmetry/SymmetryStats.svelte +94 -37
  302. package/dist/symmetry/WyckoffTable.svelte +42 -14
  303. package/dist/symmetry/cell-transform.js +5 -3
  304. package/dist/symmetry/index.d.ts +7 -4
  305. package/dist/symmetry/index.js +87 -21
  306. package/dist/symmetry/spacegroups.js +148 -148
  307. package/dist/table/HeatmapTable.svelte +1112 -516
  308. package/dist/table/HeatmapTable.svelte.d.ts +12 -1
  309. package/dist/table/ToggleMenu.svelte +125 -90
  310. package/dist/table/index.d.ts +2 -0
  311. package/dist/table/index.js +2 -4
  312. package/dist/theme/ThemeControl.svelte +21 -12
  313. package/dist/time.js +4 -1
  314. package/dist/tooltip/TooltipContent.svelte +33 -8
  315. package/dist/trajectory/Trajectory.svelte +889 -687
  316. package/dist/trajectory/TrajectoryError.svelte +14 -3
  317. package/dist/trajectory/TrajectoryExportPane.svelte +148 -90
  318. package/dist/trajectory/TrajectoryExportPane.svelte.d.ts +1 -1
  319. package/dist/trajectory/TrajectoryInfoPane.svelte +272 -143
  320. package/dist/trajectory/constants.d.ts +6 -0
  321. package/dist/trajectory/constants.js +7 -0
  322. package/dist/trajectory/extract.js +13 -31
  323. package/dist/trajectory/format-detect.d.ts +9 -0
  324. package/dist/trajectory/format-detect.js +76 -0
  325. package/dist/trajectory/frame-reader.d.ts +17 -0
  326. package/dist/trajectory/frame-reader.js +332 -0
  327. package/dist/trajectory/helpers.d.ts +14 -0
  328. package/dist/trajectory/helpers.js +172 -0
  329. package/dist/trajectory/index.d.ts +1 -0
  330. package/dist/trajectory/index.js +23 -14
  331. package/dist/trajectory/parse/ase.d.ts +2 -0
  332. package/dist/trajectory/parse/ase.js +77 -0
  333. package/dist/trajectory/parse/hdf5.d.ts +2 -0
  334. package/dist/trajectory/parse/hdf5.js +129 -0
  335. package/dist/trajectory/parse/index.d.ts +12 -0
  336. package/dist/trajectory/parse/index.js +299 -0
  337. package/dist/trajectory/parse/lammps.d.ts +5 -0
  338. package/dist/trajectory/parse/lammps.js +179 -0
  339. package/dist/trajectory/parse/vasp.d.ts +2 -0
  340. package/dist/trajectory/parse/vasp.js +68 -0
  341. package/dist/trajectory/parse/xyz.d.ts +2 -0
  342. package/dist/trajectory/parse/xyz.js +110 -0
  343. package/dist/trajectory/plotting.js +13 -8
  344. package/dist/trajectory/types.d.ts +11 -0
  345. package/dist/trajectory/types.js +1 -0
  346. package/dist/utils.d.ts +3 -0
  347. package/dist/utils.js +17 -0
  348. package/dist/xrd/XrdPlot.svelte +337 -245
  349. package/dist/xrd/broadening.js +14 -9
  350. package/dist/xrd/calc-xrd.js +12 -19
  351. package/dist/xrd/parse.d.ts +1 -1
  352. package/dist/xrd/parse.js +17 -17
  353. package/package.json +103 -101
  354. package/readme.md +4 -4
  355. package/dist/trajectory/parse.d.ts +0 -42
  356. package/dist/trajectory/parse.js +0 -1267
  357. /package/dist/element/{data.json.d.ts → data.json.gz.d.ts} +0 -0
  358. /package/dist/theme/{themes.js → themes.mjs} +0 -0
@@ -1,169 +1,198 @@
1
- <script module lang="ts">"use strict";
2
- // Track active dropdown across all instances - only one can be open at a time
3
- let active_close_fn = null;
1
+ <script module lang="ts">
2
+ // Track active dropdown across all instances - only one can be open at a time
3
+ let active_close_fn: (() => void) | null = null
4
4
  </script>
5
5
 
6
- <script lang="ts">let { options, selected_key = $bindable(), on_select, disabled = false, format_option = (opt) => (opt.unit ? `${opt.label} (${opt.unit})` : opt.label), ...rest } = $props();
7
- let dropdown_open = $state(false);
8
- let trigger_el = $state();
9
- let portal_el;
10
- const selected_option = $derived(options?.find((opt) => opt.key === selected_key) ?? options?.[0]);
11
- function update_position() {
12
- if (!trigger_el || !portal_el)
13
- return;
14
- const rect = trigger_el.getBoundingClientRect();
15
- const dropdown_rect = portal_el.getBoundingClientRect();
16
- const gap = 4;
17
- const vw = window.innerWidth;
18
- const vh = window.innerHeight;
6
+ <script lang="ts">
7
+ import { sanitize_html } from '../sanitize'
8
+ import type { HTMLButtonAttributes } from 'svelte/elements'
9
+
10
+ type Option = { key: string; label: string; unit?: string }
11
+
12
+ let {
13
+ options,
14
+ selected_key = $bindable(),
15
+ on_select,
16
+ disabled = false,
17
+ format_option = (
18
+ opt: Option,
19
+ ) => (opt.unit ? `${opt.label} (${opt.unit})` : opt.label),
20
+ ...rest
21
+ }: Omit<HTMLButtonAttributes, `onclick`> & {
22
+ options: Option[]
23
+ selected_key?: string
24
+ on_select?: (key: string, prev_key?: string) => void | Promise<void>
25
+ disabled?: boolean
26
+ format_option?: (opt: Option) => string
27
+ } = $props()
28
+
29
+ let dropdown_open = $state(false)
30
+ let trigger_el: HTMLButtonElement | undefined = $state()
31
+ let portal_el: HTMLDivElement | undefined
32
+
33
+ const selected_option = $derived(
34
+ options?.find((opt) => opt.key === selected_key) ?? options?.[0],
35
+ )
36
+
37
+ function update_position() {
38
+ if (!trigger_el || !portal_el) return
39
+ const rect = trigger_el.getBoundingClientRect()
40
+ const dropdown_rect = portal_el.getBoundingClientRect()
41
+ const gap = 4
42
+ const vw = window.innerWidth
43
+ const vh = window.innerHeight
44
+
19
45
  // Vertical: prefer below, flip above if no room
20
- const below_y = rect.bottom + gap;
21
- const above_y = rect.top - gap - dropdown_rect.height;
22
- const fits_below = below_y + dropdown_rect.height <= vh;
23
- portal_el.style.top = `${fits_below ? below_y : Math.max(gap, above_y)}px`;
46
+ const below_y = rect.bottom + gap
47
+ const above_y = rect.top - gap - dropdown_rect.height
48
+ const fits_below = below_y + dropdown_rect.height <= vh
49
+ portal_el.style.top = `${fits_below ? below_y : Math.max(gap, above_y)}px`
50
+
24
51
  // Horizontal: center, but clamp to viewport edges
25
- const center_x = rect.left + rect.width / 2;
26
- const half_width = dropdown_rect.width / 2;
27
- const min_x = half_width + gap;
28
- const max_x = vw - half_width - gap;
29
- portal_el.style.left = `${Math.max(min_x, Math.min(max_x, center_x))}px`;
30
- }
31
- // Inline styles for portal elements (can't use scoped CSS for elements in document.body)
32
- const portal_styles = {
52
+ const center_x = rect.left + rect.width / 2
53
+ const half_width = dropdown_rect.width / 2
54
+ const min_x = half_width + gap
55
+ const max_x = vw - half_width - gap
56
+ portal_el.style.left = `${Math.max(min_x, Math.min(max_x, center_x))}px`
57
+ }
58
+
59
+ // Inline styles for portal elements (can't use scoped CSS for elements in document.body)
60
+ const portal_styles = {
33
61
  container: `position: fixed; transform: translateX(-50%); z-index: 10000;`,
34
- ul: `margin: 0; padding: 0; list-style: none; background: var(--dropdown-bg, white); border: 1px solid var(--dropdown-border, #ccc); border-radius: 4px; box-shadow: 0 4px 12px rgba(0, 0, 0, 0.15); min-width: max-content; max-height: 300px; overflow-y: auto; font-size: 14px;`,
62
+ ul:
63
+ `margin: 0; padding: 0; list-style: none; background: var(--dropdown-bg, white); border: 1px solid var(--dropdown-border, #ccc); border-radius: 4px; box-shadow: 0 4px 12px rgba(0, 0, 0, 0.15); min-width: max-content; max-height: 300px; overflow-y: auto; font-size: 14px;`,
35
64
  li: `margin: 0;`,
36
- btn: `display: block; width: 100%; padding: var(--dropdown-padding-v, 3px) var(--dropdown-padding-h, 10px); border: none; background: transparent; font: inherit; color: var(--dropdown-color, black); text-align: left; cursor: pointer; white-space: nowrap;`,
65
+ btn:
66
+ `display: block; width: 100%; padding: var(--dropdown-padding-v, 3px) var(--dropdown-padding-h, 10px); border: none; background: transparent; font: inherit; color: var(--dropdown-color, black); text-align: left; cursor: pointer; white-space: nowrap;`,
37
67
  btn_selected: `font-weight: 500; background: rgba(0, 100, 200, 0.15);`,
38
- };
39
- function style_sub_sup(el) {
68
+ }
69
+
70
+ function style_sub_sup(el: HTMLElement) {
40
71
  for (const sub of el.querySelectorAll(`sub`)) {
41
- ;
42
- sub.style.cssText =
43
- `font-size: 0.75em; line-height: 0; margin: 0; padding: 0; position: relative; top: 0.15em;`;
72
+ ;(sub as HTMLElement).style.cssText =
73
+ `font-size: 0.75em; line-height: 0; margin: 0; padding: 0; position: relative; top: 0.15em;`
44
74
  }
45
75
  for (const sup of el.querySelectorAll(`sup`)) {
46
- ;
47
- sup.style.cssText =
48
- `font-size: 0.75em; line-height: 0; margin: 0; padding: 0; position: relative; top: -0.4em;`;
76
+ ;(sup as HTMLElement).style.cssText =
77
+ `font-size: 0.75em; line-height: 0; margin: 0; padding: 0; position: relative; top: -0.4em;`
49
78
  }
50
- }
51
- function open_dropdown() {
52
- if (!trigger_el || !options?.length)
53
- return;
54
- if (active_close_fn && active_close_fn !== close_dropdown)
55
- active_close_fn();
56
- portal_el = document.createElement(`div`);
57
- portal_el.className = `portal-select-dropdown`;
58
- portal_el.style.cssText = portal_styles.container;
59
- portal_el.setAttribute(`role`, `listbox`);
60
- const ul = document.createElement(`ul`);
61
- ul.style.cssText = portal_styles.ul;
62
- let selected_btn;
79
+ }
80
+
81
+ function open_dropdown() {
82
+ if (!trigger_el || !options?.length) return
83
+ if (active_close_fn && active_close_fn !== close_dropdown) active_close_fn()
84
+
85
+ portal_el = document.createElement(`div`)
86
+ portal_el.className = `portal-select-dropdown`
87
+ portal_el.style.cssText = portal_styles.container
88
+ portal_el.setAttribute(`role`, `listbox`)
89
+
90
+ const ul = document.createElement(`ul`)
91
+ ul.style.cssText = portal_styles.ul
92
+ let selected_btn: HTMLButtonElement | undefined
63
93
  for (const opt of options) {
64
- const li = document.createElement(`li`);
65
- li.style.cssText = portal_styles.li;
66
- li.setAttribute(`role`, `presentation`);
67
- const btn = document.createElement(`button`);
68
- btn.type = `button`;
69
- btn.style.cssText = portal_styles.btn;
70
- btn.setAttribute(`role`, `option`);
71
- btn.innerHTML = format_option(opt);
72
- style_sub_sup(btn);
73
- btn.onclick = () => select(opt.key);
74
- btn.onmouseenter = () => {
75
- if (!btn.classList.contains(`selected`)) {
76
- btn.style.background = `rgba(128, 128, 128, 0.15)`;
77
- }
78
- };
79
- btn.onmouseleave = () => {
80
- if (!btn.classList.contains(`selected`))
81
- btn.style.background = `transparent`;
82
- };
83
- if (opt.key === selected_key) {
84
- btn.classList.add(`selected`);
85
- btn.style.cssText = portal_styles.btn + portal_styles.btn_selected;
86
- btn.setAttribute(`aria-selected`, `true`);
87
- selected_btn = btn;
94
+ const li = document.createElement(`li`)
95
+ li.style.cssText = portal_styles.li
96
+ li.setAttribute(`role`, `presentation`)
97
+ const btn = document.createElement(`button`)
98
+ btn.type = `button`
99
+ btn.style.cssText = portal_styles.btn
100
+ btn.setAttribute(`role`, `option`)
101
+ btn.innerHTML = sanitize_html(format_option(opt))
102
+ style_sub_sup(btn)
103
+ btn.onclick = () => select(opt.key)
104
+ btn.onmouseenter = () => {
105
+ if (!btn.classList.contains(`selected`)) {
106
+ btn.style.background = `rgba(128, 128, 128, 0.15)`
88
107
  }
89
- li.appendChild(btn);
90
- ul.appendChild(li);
108
+ }
109
+ btn.onmouseleave = () => {
110
+ if (!btn.classList.contains(`selected`)) btn.style.background = `transparent`
111
+ }
112
+ if (opt.key === selected_key) {
113
+ btn.classList.add(`selected`)
114
+ btn.style.cssText = portal_styles.btn + portal_styles.btn_selected
115
+ btn.setAttribute(`aria-selected`, `true`)
116
+ selected_btn = btn
117
+ }
118
+ li.appendChild(btn)
119
+ ul.appendChild(li)
91
120
  }
92
- portal_el.appendChild(ul);
93
- document.body.appendChild(portal_el);
94
- update_position();
95
- dropdown_open = true;
96
- active_close_fn = close_dropdown;
97
- window.addEventListener(`scroll`, update_position, true);
98
- window.addEventListener(`resize`, update_position);
99
- window.addEventListener(`keydown`, handle_keydown);
100
- selected_btn?.focus();
101
- }
102
- function close_dropdown(return_focus = true) {
121
+
122
+ portal_el.appendChild(ul)
123
+ document.body.appendChild(portal_el)
124
+ update_position()
125
+ dropdown_open = true
126
+ active_close_fn = close_dropdown
127
+ window.addEventListener(`scroll`, update_position, true)
128
+ window.addEventListener(`resize`, update_position)
129
+ window.addEventListener(`keydown`, handle_keydown)
130
+ selected_btn?.focus()
131
+ }
132
+
133
+ function close_dropdown(return_focus = true) {
103
134
  if (portal_el) {
104
- window.removeEventListener(`scroll`, update_position, true);
105
- window.removeEventListener(`resize`, update_position);
106
- window.removeEventListener(`keydown`, handle_keydown);
107
- portal_el.remove();
108
- portal_el = undefined;
135
+ window.removeEventListener(`scroll`, update_position, true)
136
+ window.removeEventListener(`resize`, update_position)
137
+ window.removeEventListener(`keydown`, handle_keydown)
138
+ portal_el.remove()
139
+ portal_el = undefined
109
140
  }
110
- if (active_close_fn === close_dropdown)
111
- active_close_fn = null;
112
- dropdown_open = false;
113
- if (return_focus)
114
- trigger_el?.focus();
115
- }
116
- async function select(key) {
141
+ if (active_close_fn === close_dropdown) active_close_fn = null
142
+ dropdown_open = false
143
+ if (return_focus) trigger_el?.focus()
144
+ }
145
+
146
+ async function select(key: string) {
117
147
  if (key !== selected_key) {
118
- const prev_key = selected_key;
119
- selected_key = key; // Optimistic update for responsive UI
120
- try {
121
- await on_select?.(key, prev_key);
122
- }
123
- catch {
124
- selected_key = prev_key; // Roll back on error
125
- }
148
+ const prev_key = selected_key
149
+ selected_key = key // Optimistic update for responsive UI
150
+ try {
151
+ await on_select?.(key, prev_key)
152
+ } catch {
153
+ selected_key = prev_key // Roll back on error
154
+ }
126
155
  }
127
- close_dropdown();
128
- }
129
- function handle_click_outside(evt) {
130
- if (!dropdown_open)
131
- return;
132
- const target = evt.target;
133
- if (!trigger_el?.contains(target) && !portal_el?.contains(target)) {
134
- close_dropdown();
156
+ close_dropdown()
157
+ }
158
+
159
+ function handle_click_outside(evt: MouseEvent) {
160
+ if (!dropdown_open) return
161
+ const target = evt.target
162
+ if (
163
+ !(target instanceof Node) ||
164
+ (!trigger_el?.contains(target) && !portal_el?.contains(target))
165
+ ) {
166
+ close_dropdown()
135
167
  }
136
- }
137
- function handle_keydown(evt) {
138
- if (!portal_el)
139
- return;
140
- const buttons = [...portal_el.querySelectorAll(`button`)];
141
- const idx = buttons.indexOf(document.activeElement);
142
- const len = buttons.length;
168
+ }
169
+
170
+ function handle_keydown(evt: KeyboardEvent) {
171
+ if (!portal_el) return
172
+ const buttons = [...portal_el.querySelectorAll(`button`)] as HTMLButtonElement[]
173
+ const idx = buttons.indexOf(document.activeElement as HTMLButtonElement)
174
+ const len = buttons.length
175
+
143
176
  if (evt.key === `Escape`) {
144
- evt.preventDefault();
145
- close_dropdown();
146
- }
147
- else if (evt.key === `ArrowDown`) {
148
- evt.preventDefault();
149
- buttons[(idx + 1) % len]?.focus();
177
+ evt.preventDefault()
178
+ close_dropdown()
179
+ } else if (evt.key === `ArrowDown`) {
180
+ evt.preventDefault()
181
+ buttons[(idx + 1) % len]?.focus()
182
+ } else if (evt.key === `ArrowUp`) {
183
+ evt.preventDefault()
184
+ buttons[idx < 0 ? len - 1 : (idx - 1 + len) % len]?.focus()
185
+ } else if (evt.key === `Enter` && idx >= 0) {
186
+ evt.preventDefault()
187
+ buttons[idx].click()
150
188
  }
151
- else if (evt.key === `ArrowUp`) {
152
- evt.preventDefault();
153
- buttons[idx < 0 ? len - 1 : (idx - 1 + len) % len]?.focus();
154
- }
155
- else if (evt.key === `Enter` && idx >= 0) {
156
- evt.preventDefault();
157
- buttons[idx].click();
158
- }
159
- }
160
- // Close dropdown when disabled, options empty, or component unmounts
161
- $effect(() => {
162
- if ((disabled || !options?.length) && dropdown_open)
163
- close_dropdown(false);
164
- return () => close_dropdown(false);
165
- });
166
- export {};
189
+ }
190
+
191
+ // Close dropdown when disabled, options empty, or component unmounts
192
+ $effect(() => {
193
+ if ((disabled || !options?.length) && dropdown_open) close_dropdown(false)
194
+ return () => close_dropdown(false)
195
+ })
167
196
  </script>
168
197
 
169
198
  <svelte:window onclick={handle_click_outside} />
@@ -179,7 +208,7 @@ export {};
179
208
  {...rest}
180
209
  class="portal-select-trigger {rest.class ?? ``}"
181
210
  >
182
- {@html format_option(selected_option)}
211
+ {@html sanitize_html(format_option(selected_option))}
183
212
  <span class="arrow">▾</span>
184
213
  </button>
185
214
  {/if}
@@ -1,39 +1,94 @@
1
- <script lang="ts">// ReferenceLine: 2D reference lines with annotations (horizontal, vertical, diagonal, segment, line)
2
- import { calculate_annotation_position, resolve_line_endpoints, } from './reference-line';
3
- import { REF_LINE_STYLE_DEFAULTS } from './types';
4
- let { ref_line, line_idx, x_min, x_max, y_min, y_max, x_scale, y_scale, y2_scale, clip_path_id, hovered_line_idx = null, on_click, on_hover, } = $props();
5
- let endpoints = $derived(resolve_line_endpoints(ref_line, { x_min, x_max, y_min, y_max }, {
1
+ <script lang="ts">
2
+ // ReferenceLine: 2D reference lines with annotations (horizontal, vertical, diagonal, segment, line)
3
+ import {
4
+ calculate_annotation_position,
5
+ resolve_line_endpoints,
6
+ } from './reference-line'
7
+ import type { RefLine, RefLineEvent, RefLineStyle } from './types'
8
+ import { REF_LINE_STYLE_DEFAULTS } from './types'
9
+
10
+ let {
11
+ ref_line,
12
+ line_idx,
13
+ x_min,
14
+ x_max,
15
+ y_min,
16
+ y_max,
6
17
  x_scale,
18
+ x2_scale,
7
19
  y_scale,
8
20
  y2_scale,
9
- }));
10
- let is_focused = $state(false);
11
- let is_hovered = $derived(hovered_line_idx === line_idx || is_focused);
12
- let is_clickable = $derived(Boolean(on_click || ref_line.on_click));
13
- let style = $derived({
21
+ clip_path_id,
22
+ hovered_line_idx = null,
23
+ on_click,
24
+ on_hover,
25
+ }: {
26
+ ref_line: RefLine
27
+ line_idx: number
28
+ x_min: number
29
+ x_max: number
30
+ y_min: number
31
+ y_max: number
32
+ x_scale: (val: number) => number
33
+ x2_scale?: (val: number) => number
34
+ y_scale: (val: number) => number
35
+ y2_scale?: (val: number) => number
36
+ clip_path_id: string
37
+ hovered_line_idx?: number | null
38
+ on_click?: (event: RefLineEvent) => void
39
+ on_hover?: (event: RefLineEvent | null) => void
40
+ } = $props()
41
+
42
+ let endpoints = $derived(
43
+ resolve_line_endpoints(ref_line, { x_min, x_max, y_min, y_max }, {
44
+ x_scale,
45
+ x2_scale,
46
+ y_scale,
47
+ y2_scale,
48
+ }),
49
+ )
50
+
51
+ let is_focused = $state(false)
52
+ let is_hovered = $derived(hovered_line_idx === line_idx || is_focused)
53
+ let is_clickable = $derived(Boolean(on_click || ref_line.on_click))
54
+
55
+ let style = $derived<Required<RefLineStyle>>({
14
56
  ...REF_LINE_STYLE_DEFAULTS,
15
57
  ...ref_line.style,
16
58
  ...(is_hovered && ref_line.hover_style),
17
- });
18
- let annotation_pos = $derived(endpoints && ref_line.annotation
19
- ? calculate_annotation_position(endpoints[0], endpoints[1], endpoints[2], endpoints[3], ref_line.annotation)
20
- : null);
21
- const make_event = (event) => ({
59
+ })
60
+
61
+ let annotation_pos = $derived(
62
+ endpoints && ref_line.annotation
63
+ ? calculate_annotation_position(
64
+ endpoints[0],
65
+ endpoints[1],
66
+ endpoints[2],
67
+ endpoints[3],
68
+ ref_line.annotation,
69
+ )
70
+ : null,
71
+ )
72
+
73
+ const make_event = (
74
+ event: MouseEvent | KeyboardEvent | FocusEvent,
75
+ ): RefLineEvent => ({
22
76
  event,
23
77
  line_idx,
24
78
  line_id: ref_line.id,
25
79
  type: ref_line.type,
26
80
  label: ref_line.label ?? ref_line.annotation?.text,
27
81
  metadata: ref_line.metadata,
28
- });
29
- function handle_keydown(event) {
82
+ })
83
+
84
+ function handle_keydown(event: KeyboardEvent) {
30
85
  if (event.key === `Enter` || event.key === ` `) {
31
- event.preventDefault();
32
- const evt = make_event(event);
33
- ref_line.on_click?.(evt);
34
- on_click?.(evt);
86
+ event.preventDefault()
87
+ const evt = make_event(event)
88
+ ref_line.on_click?.(evt)
89
+ on_click?.(evt)
35
90
  }
36
- }
91
+ }
37
92
  </script>
38
93
 
39
94
  {#if endpoints && ref_line.visible !== false}
@@ -7,6 +7,7 @@ type $$ComponentProps = {
7
7
  y_min: number;
8
8
  y_max: number;
9
9
  x_scale: (val: number) => number;
10
+ x2_scale?: (val: number) => number;
10
11
  y_scale: (val: number) => number;
11
12
  y2_scale?: (val: number) => number;
12
13
  clip_path_id: string;