matterviz 0.3.6 → 0.3.7

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 (863) hide show
  1. package/dist/EmptyState.svelte.d.ts +9 -0
  2. package/dist/FilePicker.svelte +360 -0
  3. package/dist/FilePicker.svelte.d.ts +17 -0
  4. package/dist/Icon.svelte.d.ts +13 -0
  5. package/dist/MillerIndexInput.svelte +66 -0
  6. package/dist/MillerIndexInput.svelte.d.ts +7 -0
  7. package/dist/api/mp.d.ts +6 -0
  8. package/dist/api/mp.js +22 -0
  9. package/dist/api/optimade.d.ts +45 -0
  10. package/dist/api/optimade.js +135 -0
  11. package/dist/brillouin/BrillouinZone.svelte +549 -0
  12. package/dist/brillouin/BrillouinZone.svelte.d.ts +83 -0
  13. package/dist/brillouin/BrillouinZoneControls.svelte +144 -0
  14. package/dist/brillouin/BrillouinZoneControls.svelte.d.ts +17 -0
  15. package/dist/brillouin/BrillouinZoneExportPane.svelte +146 -0
  16. package/dist/brillouin/BrillouinZoneExportPane.svelte.d.ts +15 -0
  17. package/dist/brillouin/BrillouinZoneInfoPane.svelte +146 -0
  18. package/dist/brillouin/BrillouinZoneInfoPane.svelte.d.ts +13 -0
  19. package/dist/brillouin/BrillouinZoneScene.svelte +476 -0
  20. package/dist/brillouin/BrillouinZoneScene.svelte.d.ts +48 -0
  21. package/dist/brillouin/BrillouinZoneTooltip.svelte +92 -0
  22. package/dist/brillouin/BrillouinZoneTooltip.svelte.d.ts +8 -0
  23. package/dist/brillouin/compute.d.ts +17 -0
  24. package/dist/brillouin/compute.js +426 -0
  25. package/dist/brillouin/index.d.ts +8 -0
  26. package/dist/brillouin/index.js +7 -0
  27. package/dist/brillouin/types.d.ts +43 -0
  28. package/dist/brillouin/types.js +1 -0
  29. package/dist/chempot-diagram/ChemPotDiagram.svelte +327 -0
  30. package/dist/chempot-diagram/ChemPotDiagram.svelte.d.ts +13 -0
  31. package/dist/chempot-diagram/ChemPotDiagram2D.svelte +846 -0
  32. package/dist/chempot-diagram/ChemPotDiagram2D.svelte.d.ts +16 -0
  33. package/dist/chempot-diagram/ChemPotDiagram3D.svelte +3193 -0
  34. package/dist/chempot-diagram/ChemPotDiagram3D.svelte.d.ts +16 -0
  35. package/dist/chempot-diagram/ChemPotScene3D.svelte.d.ts +7 -0
  36. package/dist/chempot-diagram/async-compute.svelte.d.ts +3 -0
  37. package/dist/chempot-diagram/async-compute.svelte.js +78 -0
  38. package/dist/chempot-diagram/chempot-worker.d.ts +1 -0
  39. package/dist/chempot-diagram/chempot-worker.js +11 -0
  40. package/dist/chempot-diagram/color.d.ts +10 -0
  41. package/dist/chempot-diagram/color.js +32 -0
  42. package/dist/chempot-diagram/compute.d.ts +48 -0
  43. package/dist/chempot-diagram/compute.js +806 -0
  44. package/dist/chempot-diagram/index.d.ts +6 -0
  45. package/dist/chempot-diagram/index.js +6 -0
  46. package/dist/chempot-diagram/pointer.d.ts +16 -0
  47. package/dist/chempot-diagram/pointer.js +40 -0
  48. package/dist/chempot-diagram/temperature.d.ts +15 -0
  49. package/dist/chempot-diagram/temperature.js +34 -0
  50. package/dist/chempot-diagram/types.d.ts +81 -0
  51. package/dist/chempot-diagram/types.js +28 -0
  52. package/dist/colors/index.d.ts +47 -0
  53. package/dist/colors/index.js +203 -0
  54. package/dist/composition/BarChart.svelte +297 -0
  55. package/dist/composition/BarChart.svelte.d.ts +39 -0
  56. package/dist/composition/BubbleChart.svelte +218 -0
  57. package/dist/composition/BubbleChart.svelte.d.ts +28 -0
  58. package/dist/composition/Composition.svelte +165 -0
  59. package/dist/composition/Composition.svelte.d.ts +15 -0
  60. package/dist/composition/Formula.svelte +268 -0
  61. package/dist/composition/Formula.svelte.d.ts +19 -0
  62. package/dist/composition/FormulaFilter.svelte +1257 -0
  63. package/dist/composition/FormulaFilter.svelte.d.ts +51 -0
  64. package/dist/composition/PieChart.svelte +323 -0
  65. package/dist/composition/PieChart.svelte.d.ts +37 -0
  66. package/dist/composition/format.d.ts +15 -0
  67. package/dist/composition/format.js +109 -0
  68. package/dist/composition/index.d.ts +20 -0
  69. package/dist/composition/index.js +14 -0
  70. package/dist/composition/parse.d.ts +56 -0
  71. package/dist/composition/parse.js +474 -0
  72. package/dist/constants.d.ts +29 -0
  73. package/dist/constants.js +99 -0
  74. package/dist/controls.d.ts +14 -0
  75. package/dist/controls.js +30 -0
  76. package/dist/convex-hull/ConvexHull.svelte +157 -0
  77. package/dist/convex-hull/ConvexHull.svelte.d.ts +13 -0
  78. package/dist/convex-hull/ConvexHull2D.svelte +825 -0
  79. package/dist/convex-hull/ConvexHull2D.svelte.d.ts +11 -0
  80. package/dist/convex-hull/ConvexHull3D.svelte +1801 -0
  81. package/dist/convex-hull/ConvexHull3D.svelte.d.ts +8 -0
  82. package/dist/convex-hull/ConvexHull4D.svelte +1398 -0
  83. package/dist/convex-hull/ConvexHull4D.svelte.d.ts +8 -0
  84. package/dist/convex-hull/ConvexHullControls.svelte +535 -0
  85. package/dist/convex-hull/ConvexHullControls.svelte.d.ts +48 -0
  86. package/dist/convex-hull/ConvexHullInfoPane.svelte +125 -0
  87. package/dist/convex-hull/ConvexHullInfoPane.svelte.d.ts +20 -0
  88. package/dist/convex-hull/ConvexHullStats.svelte +929 -0
  89. package/dist/convex-hull/ConvexHullStats.svelte.d.ts +17 -0
  90. package/dist/convex-hull/ConvexHullTooltip.svelte +131 -0
  91. package/dist/convex-hull/ConvexHullTooltip.svelte.d.ts +33 -0
  92. package/dist/convex-hull/GasPressureControls.svelte +247 -0
  93. package/dist/convex-hull/GasPressureControls.svelte.d.ts +11 -0
  94. package/dist/convex-hull/StructurePopup.svelte +151 -0
  95. package/dist/convex-hull/StructurePopup.svelte.d.ts +18 -0
  96. package/dist/convex-hull/TemperatureSlider.svelte.d.ts +8 -0
  97. package/dist/convex-hull/barycentric-coords.d.ts +18 -0
  98. package/dist/convex-hull/barycentric-coords.js +182 -0
  99. package/dist/convex-hull/demo-temperature.d.ts +6 -0
  100. package/dist/convex-hull/demo-temperature.js +40 -0
  101. package/dist/convex-hull/gas-thermodynamics.d.ts +16 -0
  102. package/dist/convex-hull/gas-thermodynamics.js +314 -0
  103. package/dist/convex-hull/helpers.d.ts +114 -0
  104. package/dist/convex-hull/helpers.js +710 -0
  105. package/dist/convex-hull/index.d.ts +119 -0
  106. package/dist/convex-hull/index.js +58 -0
  107. package/dist/convex-hull/thermodynamics.d.ts +67 -0
  108. package/dist/convex-hull/thermodynamics.js +1752 -0
  109. package/dist/convex-hull/types.d.ts +162 -0
  110. package/dist/convex-hull/types.js +36 -0
  111. package/dist/coordination/CoordinationBarPlot.svelte +311 -0
  112. package/dist/coordination/CoordinationBarPlot.svelte.d.ts +30 -0
  113. package/dist/coordination/calc-coordination.d.ts +15 -0
  114. package/dist/coordination/calc-coordination.js +63 -0
  115. package/dist/coordination/index.d.ts +8 -0
  116. package/dist/coordination/index.js +7 -0
  117. package/dist/effects.svelte.d.ts +12 -0
  118. package/dist/effects.svelte.js +37 -0
  119. package/dist/element/BohrAtom.svelte.d.ts +20 -0
  120. package/dist/element/ElementHeading.svelte +26 -0
  121. package/dist/element/ElementHeading.svelte.d.ts +8 -0
  122. package/dist/element/ElementPhoto.svelte +57 -0
  123. package/dist/element/ElementPhoto.svelte.d.ts +9 -0
  124. package/dist/element/ElementStats.svelte +80 -0
  125. package/dist/element/ElementStats.svelte.d.ts +8 -0
  126. package/dist/element/ElementTile.svelte +484 -0
  127. package/dist/element/ElementTile.svelte.d.ts +29 -0
  128. package/dist/element/Nucleus.svelte.d.ts +17 -0
  129. package/dist/element/data.d.ts +2 -0
  130. package/dist/element/data.js +2 -0
  131. package/dist/element/index.d.ts +8 -0
  132. package/dist/element/index.js +7 -0
  133. package/dist/element/types.d.ts +57 -0
  134. package/dist/element/types.js +1 -0
  135. package/dist/feedback/ClickFeedback.svelte +58 -0
  136. package/dist/feedback/ClickFeedback.svelte.d.ts +12 -0
  137. package/dist/feedback/DragOverlay.svelte +42 -0
  138. package/dist/feedback/DragOverlay.svelte.d.ts +7 -0
  139. package/dist/feedback/Spinner.svelte.d.ts +7 -0
  140. package/dist/feedback/StatusMessage.svelte.d.ts +9 -0
  141. package/dist/feedback/index.d.ts +4 -0
  142. package/dist/feedback/index.js +4 -0
  143. package/dist/fermi-surface/FermiSlice.svelte +189 -0
  144. package/dist/fermi-surface/FermiSlice.svelte.d.ts +24 -0
  145. package/dist/fermi-surface/FermiSurface.svelte +600 -0
  146. package/dist/fermi-surface/FermiSurface.svelte.d.ts +83 -0
  147. package/dist/fermi-surface/FermiSurfaceControls.svelte +448 -0
  148. package/dist/fermi-surface/FermiSurfaceControls.svelte.d.ts +35 -0
  149. package/dist/fermi-surface/FermiSurfaceScene.svelte +794 -0
  150. package/dist/fermi-surface/FermiSurfaceScene.svelte.d.ts +50 -0
  151. package/dist/fermi-surface/FermiSurfaceTooltip.svelte +111 -0
  152. package/dist/fermi-surface/FermiSurfaceTooltip.svelte.d.ts +8 -0
  153. package/dist/fermi-surface/compute.d.ts +5 -0
  154. package/dist/fermi-surface/compute.js +538 -0
  155. package/dist/fermi-surface/constants.d.ts +9 -0
  156. package/dist/fermi-surface/constants.js +27 -0
  157. package/dist/fermi-surface/export.d.ts +5 -0
  158. package/dist/fermi-surface/export.js +50 -0
  159. package/dist/fermi-surface/index.d.ts +12 -0
  160. package/dist/fermi-surface/index.js +13 -0
  161. package/dist/fermi-surface/marching-cubes.d.ts +2 -0
  162. package/dist/fermi-surface/marching-cubes.js +2 -0
  163. package/dist/fermi-surface/parse.d.ts +2 -0
  164. package/dist/fermi-surface/parse.js +491 -0
  165. package/dist/fermi-surface/symmetry.d.ts +3 -0
  166. package/dist/fermi-surface/symmetry.js +46 -0
  167. package/dist/fermi-surface/types.d.ts +110 -0
  168. package/dist/fermi-surface/types.js +4 -0
  169. package/dist/heatmap-matrix/HeatmapMatrix.svelte +1545 -0
  170. package/dist/heatmap-matrix/HeatmapMatrix.svelte.d.ts +110 -0
  171. package/dist/heatmap-matrix/HeatmapMatrixControls.svelte +225 -0
  172. package/dist/heatmap-matrix/HeatmapMatrixControls.svelte.d.ts +30 -0
  173. package/dist/heatmap-matrix/index.d.ts +53 -0
  174. package/dist/heatmap-matrix/index.js +100 -0
  175. package/dist/heatmap-matrix/shared.d.ts +2 -0
  176. package/dist/heatmap-matrix/shared.js +4 -0
  177. package/dist/icons.d.ts +569 -0
  178. package/dist/icons.js +648 -0
  179. package/dist/index.d.ts +39 -0
  180. package/dist/index.js +39 -0
  181. package/dist/io/decompress.d.ts +11 -0
  182. package/dist/io/decompress.js +74 -0
  183. package/dist/io/export.d.ts +16 -0
  184. package/dist/io/export.js +316 -0
  185. package/dist/io/fetch.d.ts +5 -0
  186. package/dist/io/fetch.js +39 -0
  187. package/dist/io/file-drop.d.ts +7 -0
  188. package/dist/io/file-drop.js +43 -0
  189. package/dist/io/index.d.ts +7 -0
  190. package/dist/io/index.js +6 -0
  191. package/dist/io/is-binary.d.ts +1 -0
  192. package/dist/io/is-binary.js +20 -0
  193. package/dist/io/types.d.ts +8 -0
  194. package/dist/io/types.js +1 -0
  195. package/dist/io/url-drop.d.ts +2 -0
  196. package/dist/io/url-drop.js +123 -0
  197. package/dist/isosurface/Isosurface.svelte +285 -0
  198. package/dist/isosurface/Isosurface.svelte.d.ts +8 -0
  199. package/dist/isosurface/IsosurfaceControls.svelte +277 -0
  200. package/dist/isosurface/IsosurfaceControls.svelte.d.ts +9 -0
  201. package/dist/isosurface/index.d.ts +5 -0
  202. package/dist/isosurface/index.js +6 -0
  203. package/dist/isosurface/parse.d.ts +6 -0
  204. package/dist/isosurface/parse.js +553 -0
  205. package/dist/isosurface/slice.d.ts +11 -0
  206. package/dist/isosurface/slice.js +140 -0
  207. package/dist/isosurface/types.d.ts +56 -0
  208. package/dist/isosurface/types.js +227 -0
  209. package/dist/labels.d.ts +53 -0
  210. package/dist/labels.js +277 -0
  211. package/dist/layout/FullscreenToggle.svelte +50 -0
  212. package/dist/layout/FullscreenToggle.svelte.d.ts +7 -0
  213. package/dist/layout/InfoCard.svelte +120 -0
  214. package/dist/layout/InfoCard.svelte.d.ts +21 -0
  215. package/dist/layout/InfoTag.svelte +185 -0
  216. package/dist/layout/InfoTag.svelte.d.ts +19 -0
  217. package/dist/layout/PropertyFilter.svelte +246 -0
  218. package/dist/layout/PropertyFilter.svelte.d.ts +24 -0
  219. package/dist/layout/SettingsSection.svelte +148 -0
  220. package/dist/layout/SettingsSection.svelte.d.ts +17 -0
  221. package/dist/layout/SubpageGrid.svelte +82 -0
  222. package/dist/layout/SubpageGrid.svelte.d.ts +14 -0
  223. package/dist/layout/fullscreen.d.ts +9 -0
  224. package/dist/layout/fullscreen.js +53 -0
  225. package/dist/layout/index.d.ts +10 -0
  226. package/dist/layout/index.js +8 -0
  227. package/dist/layout/json-tree/JsonNode.svelte +548 -0
  228. package/dist/layout/json-tree/JsonNode.svelte.d.ts +11 -0
  229. package/dist/layout/json-tree/JsonTree.svelte +1230 -0
  230. package/dist/layout/json-tree/JsonTree.svelte.d.ts +6 -0
  231. package/dist/layout/json-tree/JsonValue.svelte.d.ts +9 -0
  232. package/dist/layout/json-tree/index.d.ts +3 -0
  233. package/dist/layout/json-tree/index.js +3 -0
  234. package/dist/layout/json-tree/types.d.ts +74 -0
  235. package/dist/layout/json-tree/types.js +2 -0
  236. package/dist/layout/json-tree/utils.d.ts +29 -0
  237. package/dist/layout/json-tree/utils.js +641 -0
  238. package/dist/marching-cubes.d.ts +14 -0
  239. package/dist/marching-cubes.js +540 -0
  240. package/dist/math.d.ts +101 -0
  241. package/dist/math.js +905 -0
  242. package/dist/overlays/ContextMenu.svelte +162 -0
  243. package/dist/overlays/ContextMenu.svelte.d.ts +25 -0
  244. package/dist/overlays/CopyButton.svelte +45 -0
  245. package/dist/overlays/CopyButton.svelte.d.ts +8 -0
  246. package/dist/overlays/DragControlTab.svelte +98 -0
  247. package/dist/overlays/DragControlTab.svelte.d.ts +8 -0
  248. package/dist/overlays/DraggablePane.svelte +487 -0
  249. package/dist/overlays/DraggablePane.svelte.d.ts +36 -0
  250. package/dist/overlays/InfoPaneCards.svelte +149 -0
  251. package/dist/overlays/InfoPaneCards.svelte.d.ts +22 -0
  252. package/dist/overlays/index.d.ts +3 -0
  253. package/dist/overlays/index.js +3 -0
  254. package/dist/periodic-table/PeriodicTable.svelte +469 -0
  255. package/dist/periodic-table/PeriodicTable.svelte.d.ts +55 -0
  256. package/dist/periodic-table/PeriodicTableControls.svelte +557 -0
  257. package/dist/periodic-table/PeriodicTableControls.svelte.d.ts +24 -0
  258. package/dist/periodic-table/PropertySelect.svelte +37 -0
  259. package/dist/periodic-table/PropertySelect.svelte.d.ts +13 -0
  260. package/dist/periodic-table/TableInset.svelte.d.ts +9 -0
  261. package/dist/periodic-table/index.d.ts +10 -0
  262. package/dist/periodic-table/index.js +4 -0
  263. package/dist/phase-diagram/IsobaricBinaryPhaseDiagram.svelte +1086 -0
  264. package/dist/phase-diagram/IsobaricBinaryPhaseDiagram.svelte.d.ts +44 -0
  265. package/dist/phase-diagram/PhaseDiagramControls.svelte +444 -0
  266. package/dist/phase-diagram/PhaseDiagramControls.svelte.d.ts +30 -0
  267. package/dist/phase-diagram/PhaseDiagramEditorPane.svelte +126 -0
  268. package/dist/phase-diagram/PhaseDiagramEditorPane.svelte.d.ts +15 -0
  269. package/dist/phase-diagram/PhaseDiagramExportPane.svelte +184 -0
  270. package/dist/phase-diagram/PhaseDiagramExportPane.svelte.d.ts +19 -0
  271. package/dist/phase-diagram/PhaseDiagramTooltip.svelte +391 -0
  272. package/dist/phase-diagram/PhaseDiagramTooltip.svelte.d.ts +16 -0
  273. package/dist/phase-diagram/TdbInfoPanel.svelte +203 -0
  274. package/dist/phase-diagram/TdbInfoPanel.svelte.d.ts +12 -0
  275. package/dist/phase-diagram/build-diagram.d.ts +11 -0
  276. package/dist/phase-diagram/build-diagram.js +160 -0
  277. package/dist/phase-diagram/colors.d.ts +35 -0
  278. package/dist/phase-diagram/colors.js +51 -0
  279. package/dist/phase-diagram/diagram-input.d.ts +29 -0
  280. package/dist/phase-diagram/diagram-input.js +3 -0
  281. package/dist/phase-diagram/index.d.ts +13 -0
  282. package/dist/phase-diagram/index.js +11 -0
  283. package/dist/phase-diagram/parse.d.ts +55 -0
  284. package/dist/phase-diagram/parse.js +272 -0
  285. package/dist/phase-diagram/svg-to-diagram.d.ts +2 -0
  286. package/dist/phase-diagram/svg-to-diagram.js +867 -0
  287. package/dist/phase-diagram/types.d.ts +93 -0
  288. package/dist/phase-diagram/types.js +1 -0
  289. package/dist/phase-diagram/utils.d.ts +118 -0
  290. package/dist/phase-diagram/utils.js +604 -0
  291. package/dist/plot/AxisLabel.svelte +51 -0
  292. package/dist/plot/AxisLabel.svelte.d.ts +16 -0
  293. package/dist/plot/BarPlot.svelte +2113 -0
  294. package/dist/plot/BarPlot.svelte.d.ts +84 -0
  295. package/dist/plot/BarPlotControls.svelte +66 -0
  296. package/dist/plot/BarPlotControls.svelte.d.ts +18 -0
  297. package/dist/plot/BinnedScatterPlot.svelte +1114 -0
  298. package/dist/plot/BinnedScatterPlot.svelte.d.ts +66 -0
  299. package/dist/plot/ColorBar.svelte +721 -0
  300. package/dist/plot/ColorBar.svelte.d.ts +31 -0
  301. package/dist/plot/ColorScaleSelect.svelte +54 -0
  302. package/dist/plot/ColorScaleSelect.svelte.d.ts +15 -0
  303. package/dist/plot/ElementScatter.svelte +63 -0
  304. package/dist/plot/ElementScatter.svelte.d.ts +14 -0
  305. package/dist/plot/FillArea.svelte.d.ts +21 -0
  306. package/dist/plot/Histogram.svelte +1558 -0
  307. package/dist/plot/Histogram.svelte.d.ts +50 -0
  308. package/dist/plot/HistogramControls.svelte +212 -0
  309. package/dist/plot/HistogramControls.svelte.d.ts +22 -0
  310. package/dist/plot/InteractiveAxisLabel.svelte +96 -0
  311. package/dist/plot/InteractiveAxisLabel.svelte.d.ts +14 -0
  312. package/dist/plot/Line.svelte +84 -0
  313. package/dist/plot/Line.svelte.d.ts +15 -0
  314. package/dist/plot/PlotAxis.svelte +169 -0
  315. package/dist/plot/PlotAxis.svelte.d.ts +24 -0
  316. package/dist/plot/PlotControls.svelte +537 -0
  317. package/dist/plot/PlotControls.svelte.d.ts +4 -0
  318. package/dist/plot/PlotLegend.svelte +569 -0
  319. package/dist/plot/PlotLegend.svelte.d.ts +29 -0
  320. package/dist/plot/PlotTooltip.svelte +67 -0
  321. package/dist/plot/PlotTooltip.svelte.d.ts +17 -0
  322. package/dist/plot/PortalSelect.svelte +253 -0
  323. package/dist/plot/PortalSelect.svelte.d.ts +16 -0
  324. package/dist/plot/ReferenceLine.svelte.d.ts +20 -0
  325. package/dist/plot/ReferenceLine3D.svelte +156 -0
  326. package/dist/plot/ReferenceLine3D.svelte.d.ts +14 -0
  327. package/dist/plot/ReferencePlane.svelte +175 -0
  328. package/dist/plot/ReferencePlane.svelte.d.ts +14 -0
  329. package/dist/plot/ScatterPlot.svelte +2778 -0
  330. package/dist/plot/ScatterPlot.svelte.d.ts +96 -0
  331. package/dist/plot/ScatterPlot3D.svelte +529 -0
  332. package/dist/plot/ScatterPlot3D.svelte.d.ts +95 -0
  333. package/dist/plot/ScatterPlot3DControls.svelte +437 -0
  334. package/dist/plot/ScatterPlot3DControls.svelte.d.ts +20 -0
  335. package/dist/plot/ScatterPlot3DScene.svelte +912 -0
  336. package/dist/plot/ScatterPlot3DScene.svelte.d.ts +74 -0
  337. package/dist/plot/ScatterPlotControls.svelte +306 -0
  338. package/dist/plot/ScatterPlotControls.svelte.d.ts +17 -0
  339. package/dist/plot/ScatterPoint.svelte +182 -0
  340. package/dist/plot/ScatterPoint.svelte.d.ts +22 -0
  341. package/dist/plot/SpacegroupBarPlot.svelte +293 -0
  342. package/dist/plot/SpacegroupBarPlot.svelte.d.ts +9 -0
  343. package/dist/plot/Surface3D.svelte +197 -0
  344. package/dist/plot/Surface3D.svelte.d.ts +13 -0
  345. package/dist/plot/ZeroLines.svelte +97 -0
  346. package/dist/plot/ZeroLines.svelte.d.ts +33 -0
  347. package/dist/plot/ZoomRect.svelte +23 -0
  348. package/dist/plot/ZoomRect.svelte.d.ts +8 -0
  349. package/dist/plot/adaptive-density.d.ts +69 -0
  350. package/dist/plot/adaptive-density.js +191 -0
  351. package/dist/plot/auto-place.d.ts +43 -0
  352. package/dist/plot/auto-place.js +122 -0
  353. package/dist/plot/axis-utils.d.ts +19 -0
  354. package/dist/plot/axis-utils.js +78 -0
  355. package/dist/plot/binned-scatter-types.d.ts +59 -0
  356. package/dist/plot/binned-scatter-types.js +1 -0
  357. package/dist/plot/data-cleaning.d.ts +37 -0
  358. package/dist/plot/data-cleaning.js +855 -0
  359. package/dist/plot/data-transform.d.ts +16 -0
  360. package/dist/plot/data-transform.js +45 -0
  361. package/dist/plot/defaults.d.ts +19 -0
  362. package/dist/plot/defaults.js +9 -0
  363. package/dist/plot/fill-utils.d.ts +46 -0
  364. package/dist/plot/fill-utils.js +322 -0
  365. package/dist/plot/hover-lock.svelte.d.ts +14 -0
  366. package/dist/plot/hover-lock.svelte.js +46 -0
  367. package/dist/plot/index.d.ts +41 -0
  368. package/dist/plot/index.js +39 -0
  369. package/dist/plot/interactions.d.ts +12 -0
  370. package/dist/plot/interactions.js +101 -0
  371. package/dist/plot/layout.d.ts +78 -0
  372. package/dist/plot/layout.js +273 -0
  373. package/dist/plot/reference-line.d.ts +60 -0
  374. package/dist/plot/reference-line.js +314 -0
  375. package/dist/plot/scales.d.ts +48 -0
  376. package/dist/plot/scales.js +481 -0
  377. package/dist/plot/svg.d.ts +1 -0
  378. package/dist/plot/svg.js +11 -0
  379. package/dist/plot/types.d.ts +831 -0
  380. package/dist/plot/types.js +99 -0
  381. package/dist/plot/utils/label-placement.d.ts +68 -0
  382. package/dist/plot/utils/label-placement.js +326 -0
  383. package/dist/plot/utils/series-visibility.d.ts +15 -0
  384. package/dist/plot/utils/series-visibility.js +85 -0
  385. package/dist/plot/utils.d.ts +1 -0
  386. package/dist/plot/utils.js +14 -0
  387. package/dist/rdf/RdfPlot.svelte +247 -0
  388. package/dist/rdf/RdfPlot.svelte.d.ts +27 -0
  389. package/dist/rdf/calc-rdf.d.ts +4 -0
  390. package/dist/rdf/calc-rdf.js +111 -0
  391. package/dist/rdf/index.d.ts +23 -0
  392. package/dist/rdf/index.js +2 -0
  393. package/dist/sanitize.d.ts +6 -0
  394. package/dist/sanitize.js +116 -0
  395. package/dist/settings.d.ts +255 -0
  396. package/dist/settings.js +1132 -0
  397. package/dist/spectral/Bands.svelte +1040 -0
  398. package/dist/spectral/Bands.svelte.d.ts +40 -0
  399. package/dist/spectral/BandsAndDos.svelte +134 -0
  400. package/dist/spectral/BandsAndDos.svelte.d.ts +18 -0
  401. package/dist/spectral/BrillouinBandsDos.svelte +252 -0
  402. package/dist/spectral/BrillouinBandsDos.svelte.d.ts +20 -0
  403. package/dist/spectral/Dos.svelte +697 -0
  404. package/dist/spectral/Dos.svelte.d.ts +29 -0
  405. package/dist/spectral/helpers.d.ts +119 -0
  406. package/dist/spectral/helpers.js +1032 -0
  407. package/dist/spectral/index.d.ts +6 -0
  408. package/dist/spectral/index.js +6 -0
  409. package/dist/spectral/types.d.ts +84 -0
  410. package/dist/spectral/types.js +2 -0
  411. package/dist/state.svelte.d.ts +25 -0
  412. package/dist/state.svelte.js +45 -0
  413. package/dist/structure/Arrow.svelte +72 -0
  414. package/dist/structure/Arrow.svelte.d.ts +15 -0
  415. package/dist/structure/AtomLegend.svelte +815 -0
  416. package/dist/structure/AtomLegend.svelte.d.ts +35 -0
  417. package/dist/structure/Bond.svelte +140 -0
  418. package/dist/structure/Bond.svelte.d.ts +9 -0
  419. package/dist/structure/CanvasTooltip.svelte +33 -0
  420. package/dist/structure/CanvasTooltip.svelte.d.ts +12 -0
  421. package/dist/structure/CellSelect.svelte +349 -0
  422. package/dist/structure/CellSelect.svelte.d.ts +13 -0
  423. package/dist/structure/Cylinder.svelte +45 -0
  424. package/dist/structure/Cylinder.svelte.d.ts +10 -0
  425. package/dist/structure/Lattice.svelte +196 -0
  426. package/dist/structure/Lattice.svelte.d.ts +17 -0
  427. package/dist/structure/Structure.svelte +2248 -0
  428. package/dist/structure/Structure.svelte.d.ts +89 -0
  429. package/dist/structure/StructureControls.svelte +1273 -0
  430. package/dist/structure/StructureControls.svelte.d.ts +31 -0
  431. package/dist/structure/StructureExportPane.svelte +252 -0
  432. package/dist/structure/StructureExportPane.svelte.d.ts +17 -0
  433. package/dist/structure/StructureInfoPane.svelte +737 -0
  434. package/dist/structure/StructureInfoPane.svelte.d.ts +19 -0
  435. package/dist/structure/StructureScene.svelte +2255 -0
  436. package/dist/structure/StructureScene.svelte.d.ts +111 -0
  437. package/dist/structure/atom-properties.d.ts +37 -0
  438. package/dist/structure/atom-properties.js +200 -0
  439. package/dist/structure/bond-order-perception.d.ts +13 -0
  440. package/dist/structure/bond-order-perception.js +384 -0
  441. package/dist/structure/bonding.d.ts +68 -0
  442. package/dist/structure/bonding.js +696 -0
  443. package/dist/structure/export.d.ts +20 -0
  444. package/dist/structure/export.js +727 -0
  445. package/dist/structure/index.d.ts +126 -0
  446. package/dist/structure/index.js +169 -0
  447. package/dist/structure/label-placement.d.ts +14 -0
  448. package/dist/structure/label-placement.js +72 -0
  449. package/dist/structure/measure.d.ts +6 -0
  450. package/dist/structure/measure.js +29 -0
  451. package/dist/structure/parse.d.ts +66 -0
  452. package/dist/structure/parse.js +1392 -0
  453. package/dist/structure/partial-occupancy.d.ts +25 -0
  454. package/dist/structure/partial-occupancy.js +99 -0
  455. package/dist/structure/pbc.d.ts +9 -0
  456. package/dist/structure/pbc.js +123 -0
  457. package/dist/structure/supercell.d.ts +8 -0
  458. package/dist/structure/supercell.js +170 -0
  459. package/dist/structure/validation.d.ts +2 -0
  460. package/dist/structure/validation.js +10 -0
  461. package/dist/symmetry/SymmetryStats.svelte +226 -0
  462. package/dist/symmetry/SymmetryStats.svelte.d.ts +21 -0
  463. package/dist/symmetry/WyckoffTable.svelte +120 -0
  464. package/dist/symmetry/WyckoffTable.svelte.d.ts +11 -0
  465. package/dist/symmetry/cell-transform.d.ts +12 -0
  466. package/dist/symmetry/cell-transform.js +91 -0
  467. package/dist/symmetry/index.d.ts +43 -0
  468. package/dist/symmetry/index.js +228 -0
  469. package/dist/symmetry/spacegroups.d.ts +9 -0
  470. package/dist/symmetry/spacegroups.js +394 -0
  471. package/dist/table/HeatmapTable.svelte +1833 -0
  472. package/dist/table/HeatmapTable.svelte.d.ts +49 -0
  473. package/dist/table/ToggleMenu.svelte +385 -0
  474. package/dist/table/ToggleMenu.svelte.d.ts +11 -0
  475. package/dist/table/index.d.ts +74 -0
  476. package/dist/table/index.js +38 -0
  477. package/dist/theme/ThemeControl.svelte +53 -0
  478. package/dist/theme/ThemeControl.svelte.d.ts +9 -0
  479. package/dist/theme/index.d.ts +29 -0
  480. package/dist/theme/index.js +79 -0
  481. package/dist/time.d.ts +4 -0
  482. package/dist/time.js +70 -0
  483. package/dist/tooltip/TooltipContent.svelte +58 -0
  484. package/dist/tooltip/TooltipContent.svelte.d.ts +31 -0
  485. package/dist/tooltip/index.d.ts +2 -0
  486. package/dist/tooltip/index.js +1 -0
  487. package/dist/tooltip/types.d.ts +8 -0
  488. package/dist/tooltip/types.js +1 -0
  489. package/dist/trajectory/Trajectory.svelte +1545 -0
  490. package/dist/trajectory/Trajectory.svelte.d.ts +77 -0
  491. package/dist/trajectory/TrajectoryError.svelte +128 -0
  492. package/dist/trajectory/TrajectoryError.svelte.d.ts +13 -0
  493. package/dist/trajectory/TrajectoryExportPane.svelte +357 -0
  494. package/dist/trajectory/TrajectoryExportPane.svelte.d.ts +17 -0
  495. package/dist/trajectory/TrajectoryInfoPane.svelte +313 -0
  496. package/dist/trajectory/TrajectoryInfoPane.svelte.d.ts +17 -0
  497. package/dist/trajectory/constants.d.ts +6 -0
  498. package/dist/trajectory/constants.js +7 -0
  499. package/dist/trajectory/extract.d.ts +5 -0
  500. package/dist/trajectory/extract.js +162 -0
  501. package/dist/trajectory/format-detect.d.ts +9 -0
  502. package/dist/trajectory/format-detect.js +76 -0
  503. package/dist/trajectory/frame-reader.d.ts +17 -0
  504. package/dist/trajectory/frame-reader.js +332 -0
  505. package/dist/trajectory/helpers.d.ts +15 -0
  506. package/dist/trajectory/helpers.js +164 -0
  507. package/dist/trajectory/index.d.ts +63 -0
  508. package/dist/trajectory/index.js +126 -0
  509. package/dist/trajectory/parse/ase.d.ts +2 -0
  510. package/dist/trajectory/parse/ase.js +73 -0
  511. package/dist/trajectory/parse/hdf5.d.ts +2 -0
  512. package/dist/trajectory/parse/hdf5.js +127 -0
  513. package/dist/trajectory/parse/index.d.ts +12 -0
  514. package/dist/trajectory/parse/index.js +298 -0
  515. package/dist/trajectory/parse/lammps.d.ts +5 -0
  516. package/dist/trajectory/parse/lammps.js +179 -0
  517. package/dist/trajectory/parse/vasp.d.ts +2 -0
  518. package/dist/trajectory/parse/vasp.js +68 -0
  519. package/dist/trajectory/parse/xyz.d.ts +2 -0
  520. package/dist/trajectory/parse/xyz.js +110 -0
  521. package/dist/trajectory/plotting.d.ts +28 -0
  522. package/dist/trajectory/plotting.js +423 -0
  523. package/dist/trajectory/types.d.ts +11 -0
  524. package/dist/trajectory/types.js +1 -0
  525. package/dist/utils.d.ts +6 -0
  526. package/dist/utils.js +45 -0
  527. package/dist/xrd/XrdPlot.svelte +615 -0
  528. package/dist/xrd/XrdPlot.svelte.d.ts +28 -0
  529. package/dist/xrd/broadening.d.ts +20 -0
  530. package/dist/xrd/broadening.js +97 -0
  531. package/dist/xrd/calc-xrd.d.ts +37 -0
  532. package/dist/xrd/calc-xrd.js +336 -0
  533. package/dist/xrd/index.d.ts +37 -0
  534. package/dist/xrd/index.js +4 -0
  535. package/dist/xrd/parse.d.ts +13 -0
  536. package/dist/xrd/parse.js +749 -0
  537. package/license +1 -1
  538. package/package.json +232 -1457
  539. package/readme.md +98 -171
  540. package/.vscode/launch.json +0 -13
  541. package/.vscodeignore +0 -7
  542. package/dist/assets/STLExporter-BpTH3YHE.js +0 -8
  543. package/dist/assets/browser-DdDecX_W.js +0 -1
  544. package/dist/assets/export-qgn-H9y6.js +0 -2
  545. package/dist/assets/main-DiKYzti2.css +0 -1
  546. package/dist/assets/moyo_wasm_bg-0ocwg7xY.wasm +0 -0
  547. package/dist/extension.js +0 -31293
  548. package/dist/src/lib/FilePicker.svelte +0 -360
  549. package/dist/src/lib/MillerIndexInput.svelte +0 -66
  550. package/dist/src/lib/api/mp.ts +0 -26
  551. package/dist/src/lib/api/optimade.ts +0 -204
  552. package/dist/src/lib/brillouin/BrillouinZone.svelte +0 -549
  553. package/dist/src/lib/brillouin/BrillouinZoneControls.svelte +0 -144
  554. package/dist/src/lib/brillouin/BrillouinZoneExportPane.svelte +0 -146
  555. package/dist/src/lib/brillouin/BrillouinZoneInfoPane.svelte +0 -146
  556. package/dist/src/lib/brillouin/BrillouinZoneScene.svelte +0 -476
  557. package/dist/src/lib/brillouin/BrillouinZoneTooltip.svelte +0 -92
  558. package/dist/src/lib/brillouin/compute.ts +0 -529
  559. package/dist/src/lib/brillouin/index.ts +0 -8
  560. package/dist/src/lib/brillouin/types.ts +0 -51
  561. package/dist/src/lib/chempot-diagram/ChemPotDiagram.svelte +0 -327
  562. package/dist/src/lib/chempot-diagram/ChemPotDiagram2D.svelte +0 -846
  563. package/dist/src/lib/chempot-diagram/ChemPotDiagram3D.svelte +0 -3193
  564. package/dist/src/lib/chempot-diagram/async-compute.svelte.ts +0 -94
  565. package/dist/src/lib/chempot-diagram/chempot-worker.ts +0 -11
  566. package/dist/src/lib/chempot-diagram/color.ts +0 -42
  567. package/dist/src/lib/chempot-diagram/compute.ts +0 -1014
  568. package/dist/src/lib/chempot-diagram/index.ts +0 -6
  569. package/dist/src/lib/chempot-diagram/pointer.ts +0 -56
  570. package/dist/src/lib/chempot-diagram/temperature.ts +0 -77
  571. package/dist/src/lib/chempot-diagram/types.ts +0 -130
  572. package/dist/src/lib/colors/index.ts +0 -249
  573. package/dist/src/lib/composition/BarChart.svelte +0 -297
  574. package/dist/src/lib/composition/BubbleChart.svelte +0 -218
  575. package/dist/src/lib/composition/Composition.svelte +0 -165
  576. package/dist/src/lib/composition/Formula.svelte +0 -268
  577. package/dist/src/lib/composition/FormulaFilter.svelte +0 -1257
  578. package/dist/src/lib/composition/PieChart.svelte +0 -323
  579. package/dist/src/lib/composition/format.ts +0 -155
  580. package/dist/src/lib/composition/index.ts +0 -37
  581. package/dist/src/lib/composition/parse.ts +0 -605
  582. package/dist/src/lib/constants.ts +0 -134
  583. package/dist/src/lib/controls.ts +0 -42
  584. package/dist/src/lib/convex-hull/ConvexHull.svelte +0 -157
  585. package/dist/src/lib/convex-hull/ConvexHull2D.svelte +0 -825
  586. package/dist/src/lib/convex-hull/ConvexHull3D.svelte +0 -1801
  587. package/dist/src/lib/convex-hull/ConvexHull4D.svelte +0 -1398
  588. package/dist/src/lib/convex-hull/ConvexHullControls.svelte +0 -535
  589. package/dist/src/lib/convex-hull/ConvexHullInfoPane.svelte +0 -125
  590. package/dist/src/lib/convex-hull/ConvexHullStats.svelte +0 -929
  591. package/dist/src/lib/convex-hull/ConvexHullTooltip.svelte +0 -131
  592. package/dist/src/lib/convex-hull/GasPressureControls.svelte +0 -247
  593. package/dist/src/lib/convex-hull/StructurePopup.svelte +0 -151
  594. package/dist/src/lib/convex-hull/barycentric-coords.ts +0 -246
  595. package/dist/src/lib/convex-hull/demo-temperature.ts +0 -63
  596. package/dist/src/lib/convex-hull/gas-thermodynamics.ts +0 -405
  597. package/dist/src/lib/convex-hull/helpers.ts +0 -932
  598. package/dist/src/lib/convex-hull/index.ts +0 -202
  599. package/dist/src/lib/convex-hull/thermodynamics.ts +0 -2192
  600. package/dist/src/lib/convex-hull/types.ts +0 -267
  601. package/dist/src/lib/coordination/CoordinationBarPlot.svelte +0 -311
  602. package/dist/src/lib/coordination/calc-coordination.ts +0 -93
  603. package/dist/src/lib/coordination/index.ts +0 -9
  604. package/dist/src/lib/effects.svelte.ts +0 -48
  605. package/dist/src/lib/element/ElementHeading.svelte +0 -26
  606. package/dist/src/lib/element/ElementPhoto.svelte +0 -57
  607. package/dist/src/lib/element/ElementStats.svelte +0 -80
  608. package/dist/src/lib/element/ElementTile.svelte +0 -484
  609. package/dist/src/lib/element/data.ts +0 -14
  610. package/dist/src/lib/element/index.ts +0 -8
  611. package/dist/src/lib/element/types.ts +0 -62
  612. package/dist/src/lib/feedback/ClickFeedback.svelte +0 -58
  613. package/dist/src/lib/feedback/DragOverlay.svelte +0 -42
  614. package/dist/src/lib/feedback/index.ts +0 -4
  615. package/dist/src/lib/fermi-surface/FermiSlice.svelte +0 -189
  616. package/dist/src/lib/fermi-surface/FermiSurface.svelte +0 -600
  617. package/dist/src/lib/fermi-surface/FermiSurfaceControls.svelte +0 -448
  618. package/dist/src/lib/fermi-surface/FermiSurfaceScene.svelte +0 -794
  619. package/dist/src/lib/fermi-surface/FermiSurfaceTooltip.svelte +0 -111
  620. package/dist/src/lib/fermi-surface/compute.ts +0 -728
  621. package/dist/src/lib/fermi-surface/constants.ts +0 -32
  622. package/dist/src/lib/fermi-surface/export.ts +0 -64
  623. package/dist/src/lib/fermi-surface/index.ts +0 -14
  624. package/dist/src/lib/fermi-surface/marching-cubes.ts +0 -3
  625. package/dist/src/lib/fermi-surface/parse.ts +0 -574
  626. package/dist/src/lib/fermi-surface/symmetry.ts +0 -56
  627. package/dist/src/lib/fermi-surface/types.ts +0 -159
  628. package/dist/src/lib/heatmap-matrix/HeatmapMatrix.svelte +0 -1545
  629. package/dist/src/lib/heatmap-matrix/HeatmapMatrixControls.svelte +0 -225
  630. package/dist/src/lib/heatmap-matrix/index.ts +0 -167
  631. package/dist/src/lib/heatmap-matrix/shared.ts +0 -7
  632. package/dist/src/lib/icons.ts +0 -650
  633. package/dist/src/lib/index.ts +0 -61
  634. package/dist/src/lib/io/decompress.ts +0 -92
  635. package/dist/src/lib/io/export.ts +0 -385
  636. package/dist/src/lib/io/fetch.ts +0 -46
  637. package/dist/src/lib/io/file-drop.ts +0 -51
  638. package/dist/src/lib/io/index.ts +0 -7
  639. package/dist/src/lib/io/is-binary.ts +0 -24
  640. package/dist/src/lib/io/types.ts +0 -8
  641. package/dist/src/lib/io/url-drop.ts +0 -141
  642. package/dist/src/lib/isosurface/Isosurface.svelte +0 -285
  643. package/dist/src/lib/isosurface/IsosurfaceControls.svelte +0 -277
  644. package/dist/src/lib/isosurface/index.ts +0 -7
  645. package/dist/src/lib/isosurface/parse.ts +0 -656
  646. package/dist/src/lib/isosurface/slice.ts +0 -175
  647. package/dist/src/lib/isosurface/types.ts +0 -309
  648. package/dist/src/lib/labels.ts +0 -320
  649. package/dist/src/lib/layout/FullscreenToggle.svelte +0 -50
  650. package/dist/src/lib/layout/InfoCard.svelte +0 -120
  651. package/dist/src/lib/layout/InfoTag.svelte +0 -185
  652. package/dist/src/lib/layout/PropertyFilter.svelte +0 -246
  653. package/dist/src/lib/layout/SettingsSection.svelte +0 -148
  654. package/dist/src/lib/layout/SubpageGrid.svelte +0 -82
  655. package/dist/src/lib/layout/fullscreen.ts +0 -65
  656. package/dist/src/lib/layout/index.ts +0 -11
  657. package/dist/src/lib/layout/json-tree/JsonNode.svelte +0 -548
  658. package/dist/src/lib/layout/json-tree/JsonTree.svelte +0 -1230
  659. package/dist/src/lib/layout/json-tree/index.ts +0 -3
  660. package/dist/src/lib/layout/json-tree/types.ts +0 -126
  661. package/dist/src/lib/layout/json-tree/utils.ts +0 -682
  662. package/dist/src/lib/marching-cubes.ts +0 -614
  663. package/dist/src/lib/math.ts +0 -1081
  664. package/dist/src/lib/overlays/ContextMenu.svelte +0 -162
  665. package/dist/src/lib/overlays/CopyButton.svelte +0 -45
  666. package/dist/src/lib/overlays/DragControlTab.svelte +0 -98
  667. package/dist/src/lib/overlays/DraggablePane.svelte +0 -487
  668. package/dist/src/lib/overlays/InfoPaneCards.svelte +0 -149
  669. package/dist/src/lib/overlays/index.ts +0 -3
  670. package/dist/src/lib/periodic-table/PeriodicTable.svelte +0 -469
  671. package/dist/src/lib/periodic-table/PeriodicTableControls.svelte +0 -557
  672. package/dist/src/lib/periodic-table/PropertySelect.svelte +0 -37
  673. package/dist/src/lib/periodic-table/index.ts +0 -12
  674. package/dist/src/lib/phase-diagram/IsobaricBinaryPhaseDiagram.svelte +0 -1086
  675. package/dist/src/lib/phase-diagram/PhaseDiagramControls.svelte +0 -444
  676. package/dist/src/lib/phase-diagram/PhaseDiagramEditorPane.svelte +0 -126
  677. package/dist/src/lib/phase-diagram/PhaseDiagramExportPane.svelte +0 -184
  678. package/dist/src/lib/phase-diagram/PhaseDiagramTooltip.svelte +0 -391
  679. package/dist/src/lib/phase-diagram/TdbInfoPanel.svelte +0 -203
  680. package/dist/src/lib/phase-diagram/build-diagram.ts +0 -186
  681. package/dist/src/lib/phase-diagram/colors.ts +0 -58
  682. package/dist/src/lib/phase-diagram/diagram-input.ts +0 -40
  683. package/dist/src/lib/phase-diagram/index.ts +0 -13
  684. package/dist/src/lib/phase-diagram/parse.ts +0 -348
  685. package/dist/src/lib/phase-diagram/svg-to-diagram.ts +0 -1023
  686. package/dist/src/lib/phase-diagram/types.ts +0 -144
  687. package/dist/src/lib/phase-diagram/utils.ts +0 -775
  688. package/dist/src/lib/plot/AxisLabel.svelte +0 -51
  689. package/dist/src/lib/plot/BarPlot.svelte +0 -2113
  690. package/dist/src/lib/plot/BarPlotControls.svelte +0 -66
  691. package/dist/src/lib/plot/BinnedScatterPlot.svelte +0 -1114
  692. package/dist/src/lib/plot/ColorBar.svelte +0 -721
  693. package/dist/src/lib/plot/ColorScaleSelect.svelte +0 -54
  694. package/dist/src/lib/plot/ElementScatter.svelte +0 -63
  695. package/dist/src/lib/plot/Histogram.svelte +0 -1558
  696. package/dist/src/lib/plot/HistogramControls.svelte +0 -212
  697. package/dist/src/lib/plot/InteractiveAxisLabel.svelte +0 -96
  698. package/dist/src/lib/plot/Line.svelte +0 -84
  699. package/dist/src/lib/plot/PlotAxis.svelte +0 -169
  700. package/dist/src/lib/plot/PlotControls.svelte +0 -537
  701. package/dist/src/lib/plot/PlotLegend.svelte +0 -569
  702. package/dist/src/lib/plot/PlotTooltip.svelte +0 -67
  703. package/dist/src/lib/plot/PortalSelect.svelte +0 -253
  704. package/dist/src/lib/plot/ReferenceLine3D.svelte +0 -156
  705. package/dist/src/lib/plot/ReferencePlane.svelte +0 -175
  706. package/dist/src/lib/plot/ScatterPlot.svelte +0 -2778
  707. package/dist/src/lib/plot/ScatterPlot3D.svelte +0 -529
  708. package/dist/src/lib/plot/ScatterPlot3DControls.svelte +0 -437
  709. package/dist/src/lib/plot/ScatterPlot3DScene.svelte +0 -912
  710. package/dist/src/lib/plot/ScatterPlotControls.svelte +0 -306
  711. package/dist/src/lib/plot/ScatterPoint.svelte +0 -182
  712. package/dist/src/lib/plot/SpacegroupBarPlot.svelte +0 -293
  713. package/dist/src/lib/plot/Surface3D.svelte +0 -197
  714. package/dist/src/lib/plot/ZeroLines.svelte +0 -97
  715. package/dist/src/lib/plot/ZoomRect.svelte +0 -23
  716. package/dist/src/lib/plot/adaptive-density.ts +0 -316
  717. package/dist/src/lib/plot/auto-place.ts +0 -184
  718. package/dist/src/lib/plot/axis-utils.ts +0 -122
  719. package/dist/src/lib/plot/binned-scatter-types.ts +0 -83
  720. package/dist/src/lib/plot/data-cleaning.ts +0 -1069
  721. package/dist/src/lib/plot/data-transform.ts +0 -69
  722. package/dist/src/lib/plot/defaults.ts +0 -9
  723. package/dist/src/lib/plot/fill-utils.ts +0 -494
  724. package/dist/src/lib/plot/hover-lock.svelte.ts +0 -60
  725. package/dist/src/lib/plot/index.ts +0 -53
  726. package/dist/src/lib/plot/interactions.ts +0 -119
  727. package/dist/src/lib/plot/layout.ts +0 -425
  728. package/dist/src/lib/plot/reference-line.ts +0 -426
  729. package/dist/src/lib/plot/scales.ts +0 -654
  730. package/dist/src/lib/plot/svg.ts +0 -23
  731. package/dist/src/lib/plot/types.ts +0 -1144
  732. package/dist/src/lib/plot/utils/label-placement.ts +0 -541
  733. package/dist/src/lib/plot/utils/series-visibility.ts +0 -140
  734. package/dist/src/lib/plot/utils.ts +0 -11
  735. package/dist/src/lib/rdf/RdfPlot.svelte +0 -247
  736. package/dist/src/lib/rdf/calc-rdf.ts +0 -167
  737. package/dist/src/lib/rdf/index.ts +0 -27
  738. package/dist/src/lib/sanitize.ts +0 -126
  739. package/dist/src/lib/settings.ts +0 -1479
  740. package/dist/src/lib/spectral/Bands.svelte +0 -1040
  741. package/dist/src/lib/spectral/BandsAndDos.svelte +0 -134
  742. package/dist/src/lib/spectral/BrillouinBandsDos.svelte +0 -252
  743. package/dist/src/lib/spectral/Dos.svelte +0 -697
  744. package/dist/src/lib/spectral/helpers.ts +0 -1381
  745. package/dist/src/lib/spectral/index.ts +0 -8
  746. package/dist/src/lib/spectral/types.ts +0 -112
  747. package/dist/src/lib/state.svelte.ts +0 -64
  748. package/dist/src/lib/structure/Arrow.svelte +0 -72
  749. package/dist/src/lib/structure/AtomLegend.svelte +0 -815
  750. package/dist/src/lib/structure/Bond.svelte +0 -140
  751. package/dist/src/lib/structure/CanvasTooltip.svelte +0 -33
  752. package/dist/src/lib/structure/CellSelect.svelte +0 -349
  753. package/dist/src/lib/structure/Cylinder.svelte +0 -45
  754. package/dist/src/lib/structure/Lattice.svelte +0 -196
  755. package/dist/src/lib/structure/Structure.svelte +0 -2248
  756. package/dist/src/lib/structure/StructureControls.svelte +0 -1273
  757. package/dist/src/lib/structure/StructureExportPane.svelte +0 -252
  758. package/dist/src/lib/structure/StructureInfoPane.svelte +0 -737
  759. package/dist/src/lib/structure/StructureScene.svelte +0 -2255
  760. package/dist/src/lib/structure/atom-properties.ts +0 -316
  761. package/dist/src/lib/structure/bond-order-perception.ts +0 -447
  762. package/dist/src/lib/structure/bonding.ts +0 -944
  763. package/dist/src/lib/structure/export.ts +0 -861
  764. package/dist/src/lib/structure/index.ts +0 -291
  765. package/dist/src/lib/structure/label-placement.ts +0 -130
  766. package/dist/src/lib/structure/measure.ts +0 -45
  767. package/dist/src/lib/structure/parse.ts +0 -1705
  768. package/dist/src/lib/structure/partial-occupancy.ts +0 -183
  769. package/dist/src/lib/structure/pbc.ts +0 -164
  770. package/dist/src/lib/structure/supercell.ts +0 -226
  771. package/dist/src/lib/structure/validation.ts +0 -11
  772. package/dist/src/lib/symmetry/SymmetryStats.svelte +0 -226
  773. package/dist/src/lib/symmetry/WyckoffTable.svelte +0 -120
  774. package/dist/src/lib/symmetry/cell-transform.ts +0 -118
  775. package/dist/src/lib/symmetry/index.ts +0 -348
  776. package/dist/src/lib/symmetry/spacegroups.ts +0 -404
  777. package/dist/src/lib/table/HeatmapTable.svelte +0 -1833
  778. package/dist/src/lib/table/ToggleMenu.svelte +0 -385
  779. package/dist/src/lib/table/index.ts +0 -139
  780. package/dist/src/lib/theme/ThemeControl.svelte +0 -53
  781. package/dist/src/lib/theme/index.ts +0 -107
  782. package/dist/src/lib/time.ts +0 -71
  783. package/dist/src/lib/tooltip/TooltipContent.svelte +0 -58
  784. package/dist/src/lib/tooltip/index.ts +0 -2
  785. package/dist/src/lib/tooltip/types.ts +0 -13
  786. package/dist/src/lib/trajectory/Trajectory.svelte +0 -1545
  787. package/dist/src/lib/trajectory/TrajectoryError.svelte +0 -128
  788. package/dist/src/lib/trajectory/TrajectoryExportPane.svelte +0 -357
  789. package/dist/src/lib/trajectory/TrajectoryInfoPane.svelte +0 -313
  790. package/dist/src/lib/trajectory/constants.ts +0 -7
  791. package/dist/src/lib/trajectory/extract.ts +0 -196
  792. package/dist/src/lib/trajectory/format-detect.ts +0 -96
  793. package/dist/src/lib/trajectory/frame-reader.ts +0 -456
  794. package/dist/src/lib/trajectory/helpers.ts +0 -217
  795. package/dist/src/lib/trajectory/index.ts +0 -218
  796. package/dist/src/lib/trajectory/parse/ase.ts +0 -109
  797. package/dist/src/lib/trajectory/parse/hdf5.ts +0 -173
  798. package/dist/src/lib/trajectory/parse/index.ts +0 -411
  799. package/dist/src/lib/trajectory/parse/lammps.ts +0 -215
  800. package/dist/src/lib/trajectory/parse/vasp.ts +0 -102
  801. package/dist/src/lib/trajectory/parse/xyz.ts +0 -143
  802. package/dist/src/lib/trajectory/plotting.ts +0 -599
  803. package/dist/src/lib/trajectory/types.ts +0 -13
  804. package/dist/src/lib/utils.ts +0 -56
  805. package/dist/src/lib/xrd/XrdPlot.svelte +0 -615
  806. package/dist/src/lib/xrd/broadening.ts +0 -130
  807. package/dist/src/lib/xrd/calc-xrd.ts +0 -397
  808. package/dist/src/lib/xrd/index.ts +0 -38
  809. package/dist/src/lib/xrd/parse.ts +0 -858
  810. package/dist/webview.js +0 -29421
  811. package/icon.png +0 -0
  812. package/matterviz-0.3.2.vsix +0 -0
  813. package/matterviz-0.3.4.vsix +0 -0
  814. package/matterviz-0.3.5.vsix +0 -0
  815. package/scripts/sync-config.ts +0 -101
  816. package/src/declarations.d.ts +0 -2
  817. package/src/extension.ts +0 -972
  818. package/src/node-io.ts +0 -65
  819. package/src/types.ts +0 -17
  820. package/src/webview/JsonBrowser.svelte +0 -1079
  821. package/src/webview/PlotPanel.svelte +0 -346
  822. package/src/webview/detect.ts +0 -444
  823. package/src/webview/main.ts +0 -764
  824. package/src/webview/plot-utils.ts +0 -250
  825. package/test-fixtures/all-viz-types.json.gz +0 -0
  826. package/test-fixtures/plot-demo-data.json.gz +0 -0
  827. package/tests/detect.test.ts +0 -604
  828. package/tests/extension.test.ts +0 -2041
  829. package/tests/node-io.test.ts +0 -39
  830. package/tests/plot-utils.test.ts +0 -302
  831. package/tests/vite-plugin-json-gz.test.ts +0 -114
  832. package/tests/vscode-mock.ts +0 -18
  833. package/tests/webview.test.ts +0 -231
  834. package/tsconfig.json +0 -20
  835. package/vite-plugin-json-gz.ts +0 -29
  836. package/vite.config.ts +0 -34
  837. package/vite.extension.config.ts +0 -34
  838. /package/dist/{src/lib/EmptyState.svelte → EmptyState.svelte} +0 -0
  839. /package/dist/{src/lib/Icon.svelte → Icon.svelte} +0 -0
  840. /package/dist/{src/lib/app.css → app.css} +0 -0
  841. /package/dist/{src/lib/chempot-diagram → chempot-diagram}/ChemPotScene3D.svelte +0 -0
  842. /package/dist/{src/lib/colors → colors}/alloy-colors.json +0 -0
  843. /package/dist/{src/lib/colors → colors}/dark-mode-colors.json +0 -0
  844. /package/dist/{src/lib/colors → colors}/jmol-colors.json +0 -0
  845. /package/dist/{src/lib/colors → colors}/muted-colors.json +0 -0
  846. /package/dist/{src/lib/colors → colors}/pastel-colors.json +0 -0
  847. /package/dist/{src/lib/colors → colors}/vesta-colors.json +0 -0
  848. /package/dist/{src/lib/convex-hull → convex-hull}/TemperatureSlider.svelte +0 -0
  849. /package/dist/{src/lib/element → element}/BohrAtom.svelte +0 -0
  850. /package/dist/{src/lib/element → element}/Nucleus.svelte +0 -0
  851. /package/dist/{src/lib/element → element}/data.json +0 -0
  852. /package/dist/{src/lib/element → element}/data.json.gz +0 -0
  853. /package/dist/{src/lib/element → element}/data.json.gz.d.ts +0 -0
  854. /package/dist/{src/lib/element → element}/data.schema.json +0 -0
  855. /package/dist/{src/lib/element-image-urls.json → element-image-urls.json} +0 -0
  856. /package/dist/{src/lib/feedback → feedback}/Spinner.svelte +0 -0
  857. /package/dist/{src/lib/feedback → feedback}/StatusMessage.svelte +0 -0
  858. /package/dist/{src/lib/layout → layout}/json-tree/JsonValue.svelte +0 -0
  859. /package/dist/{src/lib/periodic-table → periodic-table}/TableInset.svelte +0 -0
  860. /package/dist/{src/lib/plot → plot}/FillArea.svelte +0 -0
  861. /package/dist/{src/lib/plot → plot}/ReferenceLine.svelte +0 -0
  862. /package/dist/{src/lib/theme → theme}/themes.mjs +0 -0
  863. /package/dist/{src/lib/xrd → xrd}/atomic_scattering_params.json +0 -0
@@ -1,1833 +0,0 @@
1
- <script lang="ts">
2
- import { luminance, watch_dark_mode } from '$lib/colors'
3
- import Icon from '$lib/Icon.svelte'
4
- import { format_num } from '$lib/labels'
5
- import { SettingsSection } from '$lib/layout'
6
- import ContextMenu from '$lib/overlays/ContextMenu.svelte'
7
- import DraggablePane from '$lib/overlays/DraggablePane.svelte'
8
- import type {
9
- CellSnippet,
10
- CellVal,
11
- ExportData,
12
- InitialSort,
13
- Label,
14
- MultiSortState,
15
- Pagination,
16
- RowData,
17
- Search,
18
- SortHint,
19
- SortState,
20
- SpecialCells,
21
- } from '$lib/table'
22
- import { calc_cell_color, strip_html } from '$lib/table'
23
- import { sanitize_html } from '$lib/sanitize'
24
- import { normalize_unicode_minus } from '$lib/utils'
25
- import type { Snippet } from 'svelte'
26
- import { tooltip } from 'svelte-multiselect/attachments'
27
- import { flip } from 'svelte/animate'
28
- import type { HTMLAttributes } from 'svelte/elements'
29
- import { SvelteMap } from 'svelte/reactivity'
30
-
31
- // Helper to check if value is invalid (null, undefined, NaN)
32
- const is_invalid = (val: unknown) =>
33
- val == null || (typeof val === `number` && Number.isNaN(val))
34
-
35
- const NUMERIC_WITH_ERROR_RE =
36
- /^([-+−]?(?:\d+\.?\d*|\d*\.\d+)(?:[eE][-+−]?\d+)?)\s*(?:±|\+[-−]|\()/
37
-
38
- const parse_numeric_string = (val: string): number | null => {
39
- const numeric_str = val.match(NUMERIC_WITH_ERROR_RE)?.[1] ?? val
40
- if (numeric_str.trim() === ``) return null
41
- const num = Number(normalize_unicode_minus(numeric_str))
42
- return isNaN(num) ? null : num
43
- }
44
-
45
- // Get sort value from a cell (handles HTML data-sort-value and numbers with errors)
46
- const get_sort_val = (val: CellVal): string | number => {
47
- if (typeof val === `string`) {
48
- // Check for HTML data-sort-value attribute first
49
- const sort_attr_match = val.match(/data-sort-value="([^"]*)"/)
50
- if (sort_attr_match) {
51
- const num = Number(sort_attr_match[1])
52
- return isNaN(num) ? sort_attr_match[1] : num
53
- }
54
- const num = parse_numeric_string(val)
55
- if (num !== null) return num
56
- }
57
- return val as string | number
58
- }
59
-
60
- let {
61
- data = $bindable([]),
62
- columns = [],
63
- sort_hint = undefined,
64
- cell,
65
- special_cells,
66
- controls,
67
- initial_sort = undefined,
68
- sort = $bindable({ column: ``, dir: `asc` }), // allows external control/sync of sorting
69
- fixed_header = false,
70
- default_num_format = `.3`,
71
- show_heatmap = $bindable(true),
72
- heatmap_class = `heatmap`,
73
- onrowclick,
74
- onrowdblclick,
75
- column_order = $bindable([]),
76
- export_data = false,
77
- show_column_toggle = false,
78
- search = false,
79
- show_row_select = false,
80
- pagination = false,
81
- selected_rows = $bindable([]),
82
- hidden_columns = $bindable([]),
83
- scroll_style,
84
- root_style,
85
- onsort = undefined,
86
- onsorterror = undefined,
87
- loading = $bindable(false),
88
- sort_data = true,
89
- heatmap_opacity = $bindable(1),
90
- empty_message = `No data`,
91
- show_row_numbers = false,
92
- allow_better_toggle = false,
93
- show_controls = $bindable(false),
94
- controls_open = $bindable(false),
95
- header_cell,
96
- footer,
97
- ...rest
98
- }: HTMLAttributes<HTMLDivElement> & {
99
- data: RowData[]
100
- columns?: Label[]
101
- sort_hint?: SortHint
102
- cell?: CellSnippet
103
- special_cells?: SpecialCells
104
- controls?: Snippet
105
- initial_sort?: InitialSort
106
- sort?: { column: string; dir: `asc` | `desc` }
107
- fixed_header?: boolean
108
- default_num_format?: string
109
- show_heatmap?: boolean
110
- heatmap_class?: string
111
- onrowclick?: (event: MouseEvent | KeyboardEvent, row: RowData) => void
112
- onrowdblclick?: (event: MouseEvent, row: RowData) => void
113
- // Array of column IDs to control display order. IDs are derived as:
114
- // - Ungrouped columns: col.key ?? col.label
115
- // - Grouped columns: `${col.key ?? col.label} (${col.group})`
116
- // This allows persisting/restoring column order across sessions.
117
- column_order?: string[]
118
- export_data?: ExportData
119
- show_column_toggle?: boolean
120
- search?: Search
121
- show_row_select?: boolean
122
- pagination?: Pagination
123
- selected_rows?: RowData[]
124
- hidden_columns?: string[]
125
- scroll_style?: string
126
- // Inline styles for the root table container (merged with rest.style). Use instead of global CSS overrides.
127
- root_style?: string
128
- // Async callback for server-side sorting. When provided, client-side sorting is skipped
129
- // and the callback is called with (column_id, direction) to fetch new data from server.
130
- onsort?: (column: string, dir: `asc` | `desc`) => Promise<RowData[]>
131
- // Callback when onsort fails, receives the error for parent handling (e.g. toast notification)
132
- onsorterror?: (error: unknown, column: string, dir: `asc` | `desc`) => void
133
- // Loading state during async sort operations
134
- loading?: boolean
135
- // Whether to sort data client-side. Set to false when parent handles sorting externally.
136
- // When onsort is provided, sort_data behavior is implicitly false.
137
- sort_data?: boolean
138
- // Heatmap cell background opacity (0–1). Controls both the visual fade via CSS
139
- // color-mix() and the JS text contrast correction. Default 1 (fully opaque).
140
- heatmap_opacity?: number
141
- // Message shown when the table has no data rows. Set to empty string to hide.
142
- empty_message?: string
143
- // Show a row number column as the first column
144
- show_row_numbers?: boolean
145
- // When true, show a toggle in colored column headers to cycle gradient direction
146
- allow_better_toggle?: boolean
147
- // Whether the gear icon for the controls pane is visible
148
- show_controls?: boolean
149
- // Whether the controls pane is expanded
150
- controls_open?: boolean
151
- // Custom snippet for rendering header cells. Falls back to {@html col.label}.
152
- header_cell?: Snippet<[{ col: Label }]>
153
- // Footer snippet rendered inside <tfoot> below the table body
154
- footer?: Snippet
155
- } = $props()
156
-
157
- let container_el = $state<HTMLDivElement>()
158
-
159
- // Read --page-bg from computed style for text contrast calculation.
160
- // Recalculates on mount and when the theme changes (dark/light mode toggle).
161
- let page_bg_lum = $state(luminance(`white`))
162
- $effect(() => {
163
- if (!container_el) return
164
- const read_page_bg = () => {
165
- if (!container_el) return
166
- const page_bg = getComputedStyle(container_el).getPropertyValue(`--page-bg`)
167
- .trim()
168
- page_bg_lum = luminance(page_bg || `white`)
169
- }
170
- read_page_bg()
171
- return watch_dark_mode(read_page_bg)
172
- })
173
-
174
- // Detect HTML to prevent setting raw HTML as data-sort-value. Simple string matching
175
- // suffices since false positives just skip setting the attr (sorting still works by inner data-sort-value).
176
- function is_html_str(val: unknown): boolean {
177
- if (typeof val !== `string`) return false
178
- return (
179
- (val.includes(`<`) && val.includes(`>`)) || // Has angle brackets
180
- val.startsWith(`&lt;`) || // Has HTML entity for <
181
- val.includes(`href=`) || // Has href attribute
182
- val.includes(`class=`) // Has class attribute
183
- )
184
- }
185
-
186
- // Normalize initial_sort config
187
- let initial_sort_config = $derived(
188
- initial_sort
189
- ? typeof initial_sort === `string`
190
- ? { column: initial_sort, direction: `asc` as const }
191
- : { direction: `asc` as const, ...initial_sort }
192
- : null,
193
- )
194
-
195
- // Normalize pagination config
196
- let pagination_config = $derived(
197
- pagination
198
- ? { page_size: 25, ...(typeof pagination === `object` ? pagination : {}) }
199
- : null,
200
- )
201
-
202
- // Mutable page size — writable $derived allows user to change via dropdown
203
- let effective_page_size = $derived(pagination_config?.page_size ?? 25)
204
-
205
- // Normalize search config
206
- let search_config = $derived(
207
- search
208
- ? {
209
- placeholder: `Filter...`,
210
- expanded: false,
211
- ...(typeof search === `object` ? search : {}),
212
- }
213
- : null,
214
- )
215
-
216
- // Normalize export_data config
217
- type ExportFormat = `csv` | `json`
218
- const default_formats: ExportFormat[] = [`csv`, `json`]
219
- let export_config = $derived(
220
- export_data
221
- ? {
222
- formats: default_formats,
223
- filename: `table-export`,
224
- ...(typeof export_data === `object` ? export_data : {}),
225
- }
226
- : null,
227
- )
228
-
229
- // Derive sort_state from bindable prop, falling back to initial_sort if sort not yet set
230
- // This ensures immediate sorting on first render without waiting for effects
231
- let sort_state = $derived<SortState>({
232
- column: sort.column || initial_sort_config?.column || ``,
233
- ascending: sort.column
234
- ? sort.dir !== `desc`
235
- : initial_sort_config?.direction !== `desc`,
236
- })
237
-
238
- // Multi-column sort state (for Shift+click)
239
- let multi_sort = $state<MultiSortState>([])
240
-
241
- // Search/filter state
242
- let search_query = $state(``)
243
- let search_expanded = $derived(search_config?.expanded ?? false)
244
-
245
- // Pagination state
246
- let current_page = $state(1)
247
-
248
- // Dropdown states
249
- let show_column_dropdown = $state(false)
250
- let show_export_dropdown = $state(false)
251
-
252
- // Per-column gradient direction overrides (user-toggled via header)
253
- let better_overrides = new SvelteMap<string, `higher` | `lower`>()
254
-
255
- // Per-column color scale overrides
256
- let color_scale_overrides = new SvelteMap<string, string>()
257
-
258
- const color_scale_options = [
259
- `interpolateViridis`,
260
- `interpolatePlasma`,
261
- `interpolateInferno`,
262
- `interpolateCividis`,
263
- `interpolateTurbo`,
264
- `interpolateBlues`,
265
- `interpolateGreens`,
266
- `interpolateReds`,
267
- `interpolateYlOrRd`,
268
- ] as const
269
-
270
- // Columns that have a color gradient
271
- let colored_columns = $derived(
272
- columns.filter((col) =>
273
- col.color_scale !== null && col.color_scale !== undefined
274
- ),
275
- )
276
-
277
- // Column resize state
278
- let resize_col_id = $state<string | null>(null)
279
- let resize_start_x = $state(0)
280
- let resize_start_width = $state(0)
281
- let column_widths = $state<Record<string, number>>({})
282
-
283
- // Auto-discover columns from data keys when none are provided
284
- $effect.pre(() => {
285
- if (columns.length > 0 || data.length === 0) return
286
- const seen: Record<string, true> = {}
287
- for (const row of data.slice(0, 50)) {
288
- for (const key of Object.keys(row)) {
289
- if (key !== `style` && key !== `class`) seen[key] = true
290
- }
291
- }
292
- columns = Object.keys(seen).map((key) => ({ label: key }))
293
- })
294
-
295
- // Helper to make column IDs (needed since column labels in different groups can be repeated)
296
- const get_col_id = (col: Label) =>
297
- col.group ? `${col.key ?? col.label} (${col.group})` : (col.key ?? col.label)
298
-
299
- // Sync column_order with columns: initialize if empty, remove stale IDs, append new IDs
300
- $effect(() => {
301
- if (columns.length === 0) return
302
- const col_ids = columns.map(get_col_id)
303
-
304
- // Case 1: First render - initialize with default order
305
- if (column_order.length === 0) {
306
- column_order = col_ids
307
- return
308
- }
309
-
310
- // Case 2: Sync needed - keep valid IDs in their order, append any new ones
311
- const valid_ids = new Set(col_ids)
312
- const kept = column_order.filter((id) => valid_ids.has(id))
313
- const new_ids = col_ids.filter((id) => !kept.includes(id))
314
- const new_order = [...kept, ...new_ids]
315
-
316
- // Skip assignment if content is unchanged to prevent infinite effect loop.
317
- // After drag reorder, column_order differs from col_ids (default order) but the
318
- // computed new_order equals the current column_order — assigning a new array
319
- // reference would re-trigger this effect endlessly.
320
- if (new_order.length === column_order.length &&
321
- new_order.every((id, idx) => id === column_order[idx])) return
322
-
323
- column_order = new_order
324
- })
325
-
326
- // Reorder columns based on column_order
327
- let ordered_columns = $derived.by(() => {
328
- if (column_order.length === 0) return columns
329
-
330
- const col_map = new SvelteMap(columns.map((col) => [get_col_id(col), col]))
331
-
332
- // Add columns in specified order, then any remaining columns that weren't in the order list
333
- const ordered = column_order
334
- .map((id) => col_map.get(id))
335
- .filter((col): col is Label => col != null)
336
-
337
- const ordered_ids = new Set(ordered.map(get_col_id))
338
- const remaining = columns.filter((col) => !ordered_ids.has(get_col_id(col)))
339
-
340
- return [...ordered, ...remaining]
341
- })
342
-
343
- let drag_col_id = $state<string | null>(null)
344
- let drag_over_col_id = $state<string | null>(null)
345
-
346
- // Merge root_style with rest.style for root div; omit style from rest to avoid duplicate
347
- let rest_props = $derived.by(() => {
348
- const { style: rest_style, ...other_props } = rest
349
- const merged = [rest_style, root_style].filter(Boolean).join(`; `)
350
- return { ...other_props, ...(merged ? { style: merged } : {}) }
351
- })
352
-
353
- // WeakMap to assign stable unique IDs to row objects for efficient comparison and keying
354
- // This avoids O(n) JSON.stringify calls and prevents unnecessary re-renders
355
- const row_id_map = new WeakMap<RowData, string>()
356
- let row_id_counter = 0
357
-
358
- function get_row_id(row: RowData): string {
359
- let id = row_id_map.get(row)
360
- if (id === undefined) {
361
- id = `row_${row_id_counter++}`
362
- row_id_map.set(row, id)
363
- }
364
- return id
365
- }
366
-
367
- // Returns 'left' or 'right' to indicate which side of target to insert dragged column
368
- function get_drag_side(target_col_id: string): `left` | `right` | null {
369
- if (!drag_col_id) return null
370
- const drag_idx = column_order.indexOf(drag_col_id)
371
- const target_idx = column_order.indexOf(target_col_id)
372
- if (drag_idx === -1 || target_idx === -1) return null
373
- return drag_idx < target_idx ? `right` : `left`
374
- }
375
-
376
- function reset_drag_state() {
377
- drag_col_id = null
378
- drag_over_col_id = null
379
- }
380
-
381
- const get_drag_col_group = () =>
382
- ordered_columns.find((col) => get_col_id(col) === drag_col_id)?.group
383
-
384
- function handle_drag_start(event: DragEvent, col: Label) {
385
- if (!event.dataTransfer) return
386
- drag_col_id = get_col_id(col)
387
- event.dataTransfer.effectAllowed = `move`
388
- event.dataTransfer.setData(`text/html`, ``)
389
- }
390
-
391
- function handle_drag_over(event: DragEvent, col: Label) {
392
- event.preventDefault()
393
- if (!event.dataTransfer) return
394
- event.dataTransfer.dropEffect = `move`
395
-
396
- // Prevent cross-group drag-over to keep group headers contiguous
397
- if (get_drag_col_group() !== col.group) {
398
- event.dataTransfer.dropEffect = `none`
399
- drag_over_col_id = null
400
- return
401
- }
402
-
403
- drag_over_col_id = get_col_id(col)
404
- }
405
-
406
- function handle_drop(event: DragEvent, target_col: Label) {
407
- event.preventDefault()
408
-
409
- // Block cross-group (or group→ungroup) reorders to preserve group contiguity
410
- if (!drag_col_id || drag_col_id === get_col_id(target_col)) {
411
- reset_drag_state()
412
- return
413
- }
414
-
415
- // Block cross-group reorders to preserve group contiguity
416
- if (get_drag_col_group() !== target_col.group) {
417
- reset_drag_state()
418
- return
419
- }
420
-
421
- const target_col_id = get_col_id(target_col)
422
- const drag_idx = column_order.indexOf(drag_col_id)
423
- const target_idx = column_order.indexOf(target_col_id)
424
-
425
- if (drag_idx === -1 || target_idx === -1) {
426
- reset_drag_state()
427
- return
428
- }
429
-
430
- // Reorder: remove dragged column, then insert at target position
431
- // When dragging left-to-right (drag_idx < target_idx), removing the dragged
432
- // element shifts all subsequent indices down by 1, so we must adjust target_idx
433
- const new_order = [...column_order]
434
- new_order.splice(drag_idx, 1)
435
- const adjusted_target = drag_idx < target_idx ? target_idx - 1 : target_idx
436
- new_order.splice(adjusted_target, 0, drag_col_id)
437
- column_order = new_order
438
- reset_drag_state()
439
- }
440
-
441
- // Filter data based on search query
442
- let filtered_data = $derived.by(() => {
443
- const base_data = data?.filter?.((row) =>
444
- Object.values(row).some((val) => val !== undefined)
445
- ) ?? []
446
-
447
- if (!search_query.trim()) return base_data
448
-
449
- const query = search_query.toLowerCase().trim()
450
- return base_data.filter((row) =>
451
- Object.values(row).some((val) => {
452
- if (val == null) return false
453
- const clean_val = strip_html(String(val)).toLowerCase()
454
- return clean_val.includes(query)
455
- })
456
- )
457
- })
458
-
459
- let sorted_data = $derived.by(() => {
460
- // Skip client-side sorting when using async onsort callback or sort_data is false
461
- if (onsort || !sort_data) return filtered_data
462
-
463
- if (!sort_state.column && multi_sort.length === 0) return filtered_data
464
-
465
- // Build sort criteria: multi_sort takes precedence, fallback to single sort
466
- const sort_criteria = multi_sort.length > 0
467
- ? multi_sort
468
- : sort_state.column
469
- ? [sort_state]
470
- : []
471
-
472
- if (sort_criteria.length === 0) return filtered_data
473
-
474
- return [...filtered_data].sort((row1, row2) => {
475
- for (const { column, ascending } of sort_criteria) {
476
- const matched_col = ordered_columns.find((col) => get_col_id(col) === column)
477
- if (!matched_col) continue
478
-
479
- const col_id = get_col_id(matched_col)
480
- const val1 = row1[col_id]
481
- const val2 = row2[col_id]
482
-
483
- if (val1 === val2) continue
484
-
485
- // Push invalid values to bottom
486
- if (is_invalid(val1) || is_invalid(val2)) {
487
- return +is_invalid(val1) - +is_invalid(val2)
488
- }
489
-
490
- const sort_val1 = get_sort_val(val1)
491
- const sort_val2 = get_sort_val(val2)
492
- const modifier = ascending ? 1 : -1
493
-
494
- if (typeof sort_val1 === `string` && typeof sort_val2 === `string`) {
495
- const cmp = sort_val1.localeCompare(sort_val2, undefined, {
496
- numeric: true,
497
- sensitivity: `base`,
498
- })
499
- if (cmp !== 0) return cmp * modifier
500
- } else {
501
- if (sort_val1 !== sort_val2) {
502
- return (sort_val1 ?? 0) < (sort_val2 ?? 0) ? -modifier : modifier
503
- }
504
- }
505
- }
506
- return 0
507
- })
508
- })
509
-
510
- // Paginated data
511
- let paginated_data = $derived.by(() => {
512
- if (!pagination_config) return sorted_data
513
- const start = (current_page - 1) * effective_page_size
514
- return sorted_data.slice(start, start + effective_page_size)
515
- })
516
-
517
- let total_pages = $derived(
518
- Math.ceil(sorted_data.length / effective_page_size),
519
- )
520
-
521
- // Track previous values to detect actual changes
522
- let prev_search_query = $state(``)
523
- let prev_data_length = $state(0)
524
-
525
- // Track async sort requests to prevent race conditions
526
- let sort_request_id = 0
527
-
528
- // Reset to page 1 when search query or data length actually changes
529
- $effect(() => {
530
- const query_changed = search_query !== prev_search_query
531
- const data_changed = sorted_data.length !== prev_data_length
532
-
533
- if (query_changed || data_changed) {
534
- current_page = 1
535
- prev_search_query = search_query
536
- prev_data_length = sorted_data.length
537
- } else if (total_pages > 0 && current_page > total_pages) {
538
- // Clamp when total pages decreases (e.g., page size increase)
539
- current_page = total_pages
540
- }
541
- })
542
-
543
- async function sort_rows(
544
- column: string,
545
- group: string | undefined,
546
- event: MouseEvent | KeyboardEvent,
547
- ) {
548
- // Find the column using both label and group if provided
549
- const col = ordered_columns.find(
550
- (candidate_col) => candidate_col.label === column && candidate_col.group === group,
551
- )
552
-
553
- if (!col) return // Skip if column not found
554
- if (col.sortable === false) return // Skip sorting if column marked as unsortable
555
-
556
- const col_id = get_col_id(col)
557
-
558
- // Shift+click for multi-column sort
559
- if (event.shiftKey) {
560
- const existing_idx = multi_sort.findIndex((sort_entry) => sort_entry.column === col_id)
561
- if (existing_idx >= 0) {
562
- // Toggle direction or remove if clicked again
563
- const existing = multi_sort[existing_idx]
564
- if (existing.ascending === (col.better === `lower`)) {
565
- // Remove from multi-sort
566
- multi_sort = multi_sort.filter((_, idx) => idx !== existing_idx)
567
- } else {
568
- // Toggle direction
569
- multi_sort = multi_sort.map((sort_entry, idx) =>
570
- idx === existing_idx ? { ...sort_entry, ascending: !sort_entry.ascending } : sort_entry
571
- )
572
- }
573
- } else {
574
- // Add to multi-sort
575
- multi_sort = [...multi_sort, {
576
- column: col_id,
577
- ascending: col.better === `lower`,
578
- }]
579
- }
580
- // Clear single sort when using multi-sort
581
- sort = { column: ``, dir: `asc` }
582
- } else {
583
- // Regular click - single column sort
584
- multi_sort = [] // Clear multi-sort
585
- // Use sort_state.column for comparison since it includes initial_sort fallback
586
- const new_dir = sort_state.column !== col_id
587
- ? (col.better === `lower` ? `asc` : `desc`)
588
- : (sort_state.ascending ? `desc` : `asc`)
589
-
590
- // Save previous sort state in case we need to revert on error
591
- const prev_sort = { ...sort }
592
- sort = { column: col_id, dir: new_dir }
593
-
594
- // If onsort callback provided, fetch new data from server
595
- if (onsort) {
596
- loading = true
597
- const request_id = ++sort_request_id
598
- try {
599
- const result = await onsort(col_id, new_dir)
600
- // Only update if this is still the most recent request (avoid race condition)
601
- if (request_id === sort_request_id) {
602
- data = result
603
- }
604
- } catch (err) {
605
- console.error(`Sort callback failed:`, err)
606
- // Revert sort state on failure so UI doesn't show wrong direction
607
- if (request_id === sort_request_id) {
608
- sort = prev_sort
609
- onsorterror?.(err, col_id, new_dir)
610
- }
611
- } finally {
612
- // Only clear loading if this is still the most recent request
613
- if (request_id === sort_request_id) {
614
- loading = false
615
- }
616
- }
617
- }
618
- }
619
- }
620
-
621
- // Extract numeric value from strings with uncertainty notation: "1.23 ± 0.05", "1.23 +- 0.05", "1.23(5)"
622
- function parse_numeric_val(val: CellVal): number | null {
623
- if (typeof val === `number`) return Number.isNaN(val) ? null : val
624
- return typeof val === `string` ? parse_numeric_string(val) : null
625
- }
626
-
627
- // Memoize parsed column values to avoid O(N²) re-parsing in calc_color
628
- let parsed_column_values = $derived.by(() => {
629
- const result = new SvelteMap<string, (number | null)[]>()
630
- for (const col of ordered_columns) {
631
- if (col.color_scale === null) continue
632
- const col_id = get_col_id(col)
633
- result.set(col_id, sorted_data.map((row) => parse_numeric_val(row[col_id])))
634
- }
635
- return result
636
- })
637
-
638
- function calc_color(val: CellVal, col: Label) {
639
- if (!show_heatmap || col.color_scale === null) {
640
- return { bg: null, text: null }
641
- }
642
-
643
- // Parse numeric value from strings with uncertainty notation
644
- const numeric_val = parse_numeric_val(val)
645
- if (numeric_val === null) return { bg: null, text: null }
646
-
647
- const col_id = get_col_id(col)
648
- // Use memoized parsed values for the column
649
- const numeric_vals = parsed_column_values.get(col_id) ?? []
650
-
651
- const better = better_overrides.get(col_id) ?? col.better
652
- const scale = (color_scale_overrides.get(col_id) ?? col.color_scale ??
653
- `interpolateViridis`) as Parameters<typeof calc_cell_color>[3]
654
- const color = calc_cell_color(
655
- numeric_val,
656
- numeric_vals,
657
- better,
658
- scale,
659
- col.scale_type || `linear`,
660
- )
661
-
662
- // Recompute text contrast against effective bg (cell bg blended with page bg by opacity).
663
- // Approximation: blend luminances directly; accurate enough for black/white text choice.
664
- if (color.bg && heatmap_opacity < 1) {
665
- const blended_lum = luminance(color.bg) * heatmap_opacity +
666
- page_bg_lum * (1 - heatmap_opacity)
667
- color.text = blended_lum > 0.7 ? `black` : `white`
668
- }
669
- return color
670
- }
671
-
672
- let visible_columns = $derived(
673
- ordered_columns.filter((col) =>
674
- col.visible !== false && !hidden_columns.includes(get_col_id(col))
675
- ),
676
- )
677
-
678
- const sort_indicator = (col: Label, current_sort_state: SortState) => {
679
- const hide_sort_indicator = col.show_sort_indicator === false ||
680
- col.style?.includes(`--hide-sort-indicator`)
681
- if (hide_sort_indicator) return ``
682
-
683
- const col_id = get_col_id(col)
684
-
685
- // Check multi-sort first
686
- const multi_idx = multi_sort.findIndex((sort_entry) => sort_entry.column === col_id)
687
- if (multi_idx >= 0) {
688
- const arrow = multi_sort[multi_idx].ascending ? `↓` : `↑`
689
- const badge = multi_sort.length > 1 ? `<sup>${multi_idx + 1}</sup>` : ``
690
- return `<span style="font-size: 0.8em;">${arrow}${badge}</span>`
691
- }
692
-
693
- const is_sorted = current_sort_state.column === col_id
694
- if (!is_sorted) return ``
695
- // Show indicator only for actively sorted columns.
696
- const arrow = current_sort_state.ascending ? `↓` : `↑`
697
-
698
- return arrow ? `<span style="font-size: 0.8em;">${arrow}</span>` : ``
699
- }
700
-
701
- // Context menu state for column header right-click
702
- let context_menu_col = $state<string | null>(null)
703
- let context_menu_pos = $state({ x: 0, y: 0 })
704
-
705
- const better_sections = [
706
- {
707
- title: `Gradient direction`,
708
- options: [
709
- { value: `higher`, label: `▲ Higher is better` },
710
- { value: `lower`, label: `▼ Lower is better` },
711
- ],
712
- },
713
- ] as const
714
-
715
- // Row selection using WeakMap-based ID lookup instead of O(n) JSON.stringify comparison
716
- function toggle_row_select(row: RowData) {
717
- const row_id = get_row_id(row)
718
- const idx = selected_rows.findIndex((selected_row) => get_row_id(selected_row) === row_id)
719
- if (idx >= 0) {
720
- selected_rows = selected_rows.filter((_, i) => i !== idx)
721
- } else {
722
- selected_rows = [...selected_rows, row]
723
- }
724
- }
725
-
726
- function is_row_selected(row: RowData): boolean {
727
- const row_id = get_row_id(row)
728
- return selected_rows.some((selected_row) => get_row_id(selected_row) === row_id)
729
- }
730
-
731
- // Select-all: checks if every row on the current page is selected
732
- let all_page_selected = $derived(
733
- paginated_data.length > 0 && paginated_data.every((row) => is_row_selected(row)),
734
- )
735
-
736
- function toggle_select_all() {
737
- if (all_page_selected) {
738
- const page_ids = new Set(paginated_data.map(get_row_id))
739
- selected_rows = selected_rows.filter((row) => !page_ids.has(get_row_id(row)))
740
- } else {
741
- const already = new Set(selected_rows.map(get_row_id))
742
- const new_rows = paginated_data.filter((row) => !already.has(get_row_id(row)))
743
- selected_rows = [...selected_rows, ...new_rows]
744
- }
745
- }
746
-
747
- // Data source for exports: selected rows when any are selected, otherwise all sorted data
748
- let export_rows = $derived(
749
- show_row_select && selected_rows.length > 0 ? selected_rows : sorted_data,
750
- )
751
-
752
- // Serialize table as delimited text (shared by CSV export and clipboard copy)
753
- // Per RFC 4180, fields containing commas, double quotes, or newlines must be quoted
754
- function serialize_table(delimiter: string, csv_quote = false): string {
755
- const quote = (str: string) => {
756
- if (!csv_quote) return str
757
- if (str.includes(`,`) || str.includes(`"`) || str.includes(`\n`)) {
758
- return `"${str.replace(/"/g, `""`)}"`
759
- }
760
- return str
761
- }
762
- const headers = visible_columns.map((col) => quote(strip_html(col.label)))
763
- const rows = export_rows.map((row) =>
764
- visible_columns.map((col) => {
765
- const val = row[get_col_id(col)]
766
- if (val == null) return ``
767
- return quote(strip_html(String(val)))
768
- })
769
- )
770
- return [headers.join(delimiter), ...rows.map((row) => row.join(delimiter))].join(`\n`)
771
- }
772
-
773
- function export_csv(filename = `table-export`) {
774
- download_file(serialize_table(`,`, true), `${filename}.csv`, `text/csv`)
775
- }
776
-
777
- function export_json(filename = `table-export`) {
778
- const rows = export_rows.map((row) => {
779
- const clean_row: Record<string, unknown> = {}
780
- for (const col of visible_columns) {
781
- const col_id = get_col_id(col)
782
- const val = row[col_id]
783
- clean_row[strip_html(col.label)] = typeof val === `string`
784
- ? strip_html(val)
785
- : val
786
- }
787
- return clean_row
788
- })
789
- download_file(
790
- JSON.stringify(rows, null, 2),
791
- `${filename}.json`,
792
- `application/json`,
793
- )
794
- }
795
-
796
- function download_file(content: string, filename: string, mime_type: string) {
797
- const blob = new Blob([content], { type: mime_type })
798
- const url = URL.createObjectURL(blob)
799
- const link = document.createElement(`a`)
800
- link.href = url
801
- link.download = filename
802
- document.body.appendChild(link)
803
- link.click()
804
- document.body.removeChild(link)
805
- URL.revokeObjectURL(url)
806
- }
807
-
808
- function copy_to_clipboard() {
809
- navigator.clipboard.writeText(serialize_table(`\t`))
810
- }
811
-
812
- // Column visibility toggle
813
- function toggle_column(col_id: string) {
814
- if (hidden_columns.includes(col_id)) {
815
- hidden_columns = hidden_columns.filter((id) => id !== col_id)
816
- } else {
817
- hidden_columns = [...hidden_columns, col_id]
818
- }
819
- }
820
-
821
- // Column resize handlers
822
- function start_resize(event: MouseEvent, col: Label) {
823
- event.preventDefault()
824
- event.stopPropagation()
825
- resize_col_id = get_col_id(col)
826
- resize_start_x = event.clientX
827
- const th = event.target instanceof Element ? event.target.parentElement : null
828
- resize_start_width = th?.offsetWidth ?? 100
829
-
830
- document.addEventListener(`mousemove`, handle_resize)
831
- document.addEventListener(`mouseup`, stop_resize)
832
- }
833
-
834
- function handle_resize(event: MouseEvent) {
835
- if (!resize_col_id) return
836
- const delta = event.clientX - resize_start_x
837
- const new_width = Math.min(500, Math.max(50, resize_start_width + delta))
838
- column_widths = { ...column_widths, [resize_col_id]: new_width }
839
- }
840
-
841
- function stop_resize() {
842
- resize_col_id = null
843
- document.removeEventListener(`mousemove`, handle_resize)
844
- document.removeEventListener(`mouseup`, stop_resize)
845
- }
846
-
847
- // Normalize sort_hint to a config object with defaults
848
- let hint_config = $derived(
849
- sort_hint
850
- ? {
851
- position: `bottom` as const,
852
- permanent: false,
853
- ...(typeof sort_hint === `string` ? { text: sort_hint } : sort_hint),
854
- }
855
- : null,
856
- )
857
- </script>
858
-
859
- {#snippet sort_hint_element(pos: `top` | `bottom`)}
860
- {#if hint_config?.position === pos}
861
- <div
862
- class="sort-hint {hint_config.class ?? ``}"
863
- class:permanent={hint_config.permanent}
864
- style={hint_config.style}
865
- >
866
- {hint_config.text}
867
- </div>
868
- {/if}
869
- {/snippet}
870
-
871
- <div
872
- {@attach tooltip({ allow_html: true })}
873
- {...rest_props}
874
- bind:this={container_el}
875
- class="table-container {rest_props.class ?? ``}"
876
- style:--heatmap-opacity="{heatmap_opacity * 100}%"
877
- onmouseleave={() => {
878
- show_column_dropdown = false
879
- show_export_dropdown = false
880
- context_menu_col = null
881
- }}
882
- >
883
- <!-- Floating control buttons -->
884
- <section class="control-buttons">
885
- {#if search_config}
886
- {#if search_expanded || search_query}
887
- <input
888
- type="search"
889
- class="search-input"
890
- placeholder={search_config.placeholder}
891
- bind:value={search_query}
892
- onblur={() => {
893
- if (!search_query) search_expanded = false
894
- }}
895
- />
896
- <button
897
- class="icon-btn"
898
- onclick={() => {
899
- search_query = ``
900
- search_expanded = false
901
- }}
902
- {@attach tooltip({ content: `Clear`, placement: `top` })}
903
- >
904
- <Icon icon="Cross" style="width: 10px" />
905
- </button>
906
- {:else}
907
- <button
908
- class="icon-btn"
909
- onclick={() => search_expanded = true}
910
- {@attach tooltip({ content: `Search`, placement: `top` })}
911
- >
912
- <Icon icon="Search" style="width: 14px" />
913
- </button>
914
- {/if}
915
- {/if}
916
-
917
- {#if show_column_toggle}
918
- <div class="dropdown-wrapper">
919
- <button
920
- class="icon-btn"
921
- class:active={show_column_dropdown}
922
- onclick={() => show_column_dropdown = !show_column_dropdown}
923
- {@attach tooltip({ content: `Columns`, placement: `top` })}
924
- >
925
- <Icon icon="Columns" style="width: 14px" />
926
- </button>
927
- {#if show_column_dropdown}
928
- <div class="dropdown-pane">
929
- {#each ordered_columns as col (get_col_id(col))}
930
- {@const col_id = get_col_id(col)}
931
- <label class="dropdown-option">
932
- <input
933
- type="checkbox"
934
- checked={!hidden_columns.includes(col_id)}
935
- onchange={() => toggle_column(col_id)}
936
- />
937
- {@html sanitize_html(col.label)}
938
- </label>
939
- {/each}
940
- </div>
941
- {/if}
942
- </div>
943
- {/if}
944
-
945
- {#if export_config}
946
- <div class="dropdown-wrapper">
947
- <button
948
- class="icon-btn"
949
- class:active={show_export_dropdown}
950
- onclick={() => show_export_dropdown = !show_export_dropdown}
951
- {@attach tooltip({ content: `Export`, placement: `top` })}
952
- >
953
- <Icon icon="Export" style="width: 14px" />
954
- </button>
955
- {#if show_export_dropdown}
956
- <div class="dropdown-pane">
957
- {#if export_config.formats.includes(`csv`)}
958
- <button
959
- class="dropdown-option"
960
- onclick={() => {
961
- export_csv(export_config.filename)
962
- show_export_dropdown = false
963
- }}
964
- >
965
- <Icon icon="Download" style="width: 12px" /> CSV
966
- </button>
967
- {/if}
968
- {#if export_config.formats.includes(`json`)}
969
- <button
970
- class="dropdown-option"
971
- onclick={() => {
972
- export_json(export_config.filename)
973
- show_export_dropdown = false
974
- }}
975
- >
976
- <Icon icon="Download" style="width: 12px" /> JSON
977
- </button>
978
- {/if}
979
- <button
980
- class="dropdown-option"
981
- onclick={() => {
982
- copy_to_clipboard()
983
- show_export_dropdown = false
984
- }}
985
- >
986
- <Icon icon="Copy" style="width: 12px" /> Copy
987
- </button>
988
- </div>
989
- {/if}
990
- </div>
991
- {/if}
992
-
993
- {#if show_row_select && selected_rows.length > 0}
994
- <button
995
- class="icon-btn selection-badge"
996
- onclick={() => selected_rows = []}
997
- title="Clear {selected_rows.length} selected rows"
998
- >
999
- <span class="badge">{selected_rows.length}</span>
1000
- <Icon icon="Cross" style="width: 10px" />
1001
- </button>
1002
- {/if}
1003
-
1004
- {#if controls}
1005
- {@render controls()}
1006
- {/if}
1007
- </section>
1008
-
1009
- {#if show_controls}
1010
- <DraggablePane
1011
- bind:show={controls_open}
1012
- closed_icon="Settings"
1013
- open_icon="Cross"
1014
- toggle_props={{
1015
- title: `${controls_open ? `Close` : `Open`} table controls`,
1016
- style: `position: absolute; top: 5pt; right: 1ex; z-index: 10`,
1017
- }}
1018
- pane_props={{ style: `max-height: 60vh; overflow-y: auto; font-size: 0.85em` }}
1019
- >
1020
- <SettingsSection
1021
- title="Heatmap"
1022
- current_values={{ show_heatmap, heatmap_opacity }}
1023
- on_reset={() => {
1024
- show_heatmap = true
1025
- heatmap_opacity = 1
1026
- }}
1027
- >
1028
- <label><input type="checkbox" bind:checked={show_heatmap} /> Show heatmap</label>
1029
- {#if show_heatmap}
1030
- <label>
1031
- Opacity
1032
- <input
1033
- type="range"
1034
- min="0"
1035
- max="1"
1036
- step="0.05"
1037
- bind:value={heatmap_opacity}
1038
- />
1039
- <input
1040
- type="number"
1041
- min="0"
1042
- max="1"
1043
- step="0.05"
1044
- bind:value={heatmap_opacity}
1045
- style="width: 3.5em"
1046
- />
1047
- </label>
1048
- {/if}
1049
- </SettingsSection>
1050
-
1051
- <SettingsSection
1052
- title="Display"
1053
- current_values={{ show_row_numbers }}
1054
- on_reset={() => {
1055
- show_row_numbers = false
1056
- }}
1057
- >
1058
- <label><input type="checkbox" bind:checked={show_row_numbers} /> Row
1059
- numbers</label>
1060
- </SettingsSection>
1061
-
1062
- {#if colored_columns.length > 0}
1063
- <SettingsSection
1064
- title="Column Colors"
1065
- current_values={Object.fromEntries([...better_overrides, ...color_scale_overrides])}
1066
- on_reset={() => {
1067
- better_overrides.clear()
1068
- color_scale_overrides.clear()
1069
- }}
1070
- >
1071
- {#each colored_columns as col (get_col_id(col))}
1072
- {@const col_id = get_col_id(col)}
1073
- <div class="col-color-row">
1074
- <span class="col-color-label">{@html sanitize_html(col.label)}</span>
1075
- <select
1076
- value={color_scale_overrides.get(col_id) ?? col.color_scale ??
1077
- `interpolateViridis`}
1078
- onchange={(event) => {
1079
- const val = event.currentTarget.value
1080
- if (
1081
- val === (col.color_scale ?? `interpolateViridis`)
1082
- ) color_scale_overrides.delete(col_id)
1083
- else color_scale_overrides.set(col_id, val)
1084
- }}
1085
- >
1086
- {#each color_scale_options as scale (scale)}
1087
- <option value={scale}>{scale.replace(`interpolate`, ``)}</option>
1088
- {/each}
1089
- </select>
1090
- <select
1091
- value={better_overrides.get(col_id) ?? col.better ?? ``}
1092
- onchange={(event) => {
1093
- const val = event.currentTarget.value
1094
- if (!val) better_overrides.delete(col_id)
1095
- else better_overrides.set(col_id, val as `higher` | `lower`)
1096
- }}
1097
- >
1098
- <option value="">Default</option>
1099
- <option value="higher">▲ High</option>
1100
- <option value="lower">▼ Low</option>
1101
- </select>
1102
- </div>
1103
- {/each}
1104
- </SettingsSection>
1105
- {/if}
1106
- </DraggablePane>
1107
- {/if}
1108
-
1109
- {@render sort_hint_element(`top`)}
1110
-
1111
- <div
1112
- class="table-scroll"
1113
- style={scroll_style}
1114
- class:has-scroll={scroll_style}
1115
- >
1116
- {#if loading}
1117
- <div class="loading-overlay">
1118
- <div class="loading-spinner"></div>
1119
- </div>
1120
- {/if}
1121
- <table class:fixed-header={fixed_header} class={heatmap_class}>
1122
- <thead>
1123
- <!-- Don't add a table row for group headers if there are none -->
1124
- {#if visible_columns.some((col) => col.group)}
1125
- <!-- First level headers -->
1126
- <tr class="group-header">
1127
- {#if show_row_select}
1128
- <th class="select-col"></th>
1129
- {/if}
1130
- {#if show_row_numbers}
1131
- <th class="row-num-col"></th>
1132
- {/if}
1133
- {#each visible_columns as col (get_col_id(col))}
1134
- {#if !col.group}
1135
- <th class:sticky-col={col.sticky}></th>
1136
- {:else}
1137
- {@const group_cols = visible_columns.filter((column) =>
1138
- column.group === col.group
1139
- )}
1140
- <!-- Only render the group header once for each group by checking if this is the first column of this group -->
1141
- {#if visible_columns.findIndex((column) => column.group === col.group) ===
1142
- visible_columns.findIndex((column) =>
1143
- column.group === col.group && column.label === col.label
1144
- )}
1145
- <th title={col.description} colspan={group_cols.length}>
1146
- {@html sanitize_html(col.group)}
1147
- </th>
1148
- {/if}
1149
- {/if}
1150
- {/each}
1151
- </tr>
1152
- {/if}
1153
- <!-- Second level headers -->
1154
- <tr>
1155
- {#if show_row_select}
1156
- <th
1157
- class="select-col"
1158
- title={all_page_selected ? `Deselect all` : `Select all on this page`}
1159
- >
1160
- <input
1161
- type="checkbox"
1162
- checked={all_page_selected}
1163
- onchange={toggle_select_all}
1164
- />
1165
- </th>
1166
- {/if}
1167
- {#if show_row_numbers}
1168
- <th class="row-num-col">#</th>
1169
- {/if}
1170
- {#each visible_columns as col (get_col_id(col))}
1171
- {@const col_id = get_col_id(col)}
1172
- {@const drag_side = drag_over_col_id === col_id
1173
- ? get_drag_side(col_id)
1174
- : null}
1175
- {@const col_width = column_widths[col_id]}
1176
- <th
1177
- title={col.description}
1178
- tabindex={col.sortable === false ? undefined : 0}
1179
- role={col.sortable === false ? undefined : `button`}
1180
- oncontextmenu={(event) => {
1181
- if (
1182
- !allow_better_toggle || col.color_scale === null ||
1183
- col.color_scale === undefined
1184
- ) return
1185
- event.preventDefault()
1186
- event.stopPropagation()
1187
- context_menu_col = col_id
1188
- const rect = container_el?.getBoundingClientRect()
1189
- context_menu_pos = {
1190
- x: event.clientX - (rect?.left ?? 0),
1191
- y: event.clientY - (rect?.top ?? 0),
1192
- }
1193
- }}
1194
- onclick={(event) => {
1195
- if (!drag_col_id && !resize_col_id) {
1196
- sort_rows(
1197
- col.label,
1198
- col.group,
1199
- event,
1200
- )
1201
- }
1202
- }}
1203
- onkeydown={(event) => {
1204
- if (
1205
- (event.key === `Enter` || event.key === ` `) &&
1206
- !drag_col_id && !resize_col_id
1207
- ) {
1208
- event.preventDefault()
1209
- sort_rows(col.label, col.group, event)
1210
- }
1211
- }}
1212
- style={`${col.style ?? ``}${
1213
- col_width
1214
- ? `; width: ${col_width}px; min-width: ${col_width}px`
1215
- : ``
1216
- }`}
1217
- class:sticky-col={col.sticky}
1218
- class:not-sortable={col.sortable === false}
1219
- class:dragging={drag_col_id === col_id}
1220
- class:resizing={resize_col_id === col_id}
1221
- data-drag-side={drag_side}
1222
- draggable="true"
1223
- aria-dropeffect="move"
1224
- aria-sort={sort_state.column === col_id
1225
- ? (sort_state.ascending ? `ascending` : `descending`)
1226
- : `none`}
1227
- ondragstart={(event: DragEvent & { currentTarget: HTMLElement }) => {
1228
- handle_drag_start(event, col)
1229
- event.currentTarget.setAttribute(`aria-grabbed`, `true`)
1230
- }}
1231
- ondragover={(event) => handle_drag_over(event, col)}
1232
- ondragleave={() => (drag_over_col_id = null)}
1233
- ondrop={(event) => handle_drop(event, col)}
1234
- ondragend={(event: DragEvent & { currentTarget: HTMLElement }) => {
1235
- reset_drag_state()
1236
- event.currentTarget.removeAttribute(`aria-grabbed`)
1237
- }}
1238
- >
1239
- {#if header_cell}
1240
- {@render header_cell({ col })}
1241
- {:else}
1242
- {@html sanitize_html(col.label)}
1243
- {/if}
1244
- {@html sanitize_html(sort_indicator(col, sort_state))}
1245
- <!-- Column resize handle -->
1246
- <!-- svelte-ignore a11y_no_noninteractive_element_interactions -->
1247
- <span
1248
- class="resize-handle"
1249
- onmousedown={(event) => start_resize(event, col)}
1250
- role="separator"
1251
- aria-orientation="vertical"
1252
- aria-valuenow={column_widths[get_col_id(col)] ?? 100}
1253
- aria-valuemin={50}
1254
- aria-valuemax={500}
1255
- ></span>
1256
- </th>
1257
- {/each}
1258
- </tr>
1259
- </thead>
1260
- <tbody>
1261
- {#each paginated_data as row, row_idx (get_row_id(row))}
1262
- {@const row_selected = show_row_select && is_row_selected(row)}
1263
- <tr
1264
- animate:flip={{ duration: 500 }}
1265
- style={row.style}
1266
- class={row.class ?? ``}
1267
- class:selected={row_selected}
1268
- tabindex={onrowclick ? 0 : undefined}
1269
- onclick={onrowclick ? (event) => onrowclick(event, row) : undefined}
1270
- ondblclick={onrowdblclick ? (event) => onrowdblclick(event, row) : undefined}
1271
- onkeydown={onrowclick
1272
- ? (event) => {
1273
- if (event.key === `Enter` || event.key === ` `) {
1274
- event.preventDefault()
1275
- onrowclick(event, row)
1276
- } else if (event.key === `ArrowDown`) {
1277
- event.preventDefault()
1278
- const next = event.currentTarget.nextElementSibling
1279
- if (next instanceof HTMLElement) next.focus()
1280
- } else if (event.key === `ArrowUp`) {
1281
- event.preventDefault()
1282
- const prev = event.currentTarget.previousElementSibling
1283
- if (prev instanceof HTMLElement) prev.focus()
1284
- }
1285
- }
1286
- : undefined}
1287
- >
1288
- {#if show_row_select}
1289
- <td class="select-col">
1290
- <input
1291
- type="checkbox"
1292
- checked={row_selected}
1293
- onchange={() => toggle_row_select(row)}
1294
- />
1295
- </td>
1296
- {/if}
1297
- {#if show_row_numbers}
1298
- <td class="row-num-col">
1299
- {(current_page - 1) * effective_page_size + row_idx + 1}
1300
- </td>
1301
- {/if}
1302
- {#each visible_columns as col (get_col_id(col))}
1303
- {@const val = row[get_col_id(col)]}
1304
- {@const color = calc_color(val, col)}
1305
- {@const col_width = column_widths[get_col_id(col)]}
1306
- <td
1307
- data-col={col.label}
1308
- data-sort-value={is_html_str(val) ? null : val}
1309
- class:sticky-col={col.sticky}
1310
- style:--cell-bg={color.bg}
1311
- style:color={color.text}
1312
- style={`${col.cell_style ?? col.style ?? ``}${
1313
- col_width
1314
- ? `; width: ${col_width}px; max-width: ${col_width}px`
1315
- : ``
1316
- }`}
1317
- >
1318
- {#if special_cells?.[col.label]}
1319
- {@render special_cells[col.label]({ row, col, val })}
1320
- {:else if cell}
1321
- {@render cell({ row, col, val })}
1322
- {:else if typeof val === `number` && !Number.isNaN(val)}
1323
- {format_num(val, col.format ?? default_num_format)}
1324
- {:else if val === undefined || val === null || Number.isNaN(val)}
1325
- <span {@attach tooltip({ content: `Not available` })}>
1326
- n/a
1327
- </span>
1328
- {:else}
1329
- {@html sanitize_html(val)}
1330
- {/if}
1331
- </td>
1332
- {/each}
1333
- </tr>
1334
- {:else}
1335
- {#if empty_message}
1336
- <tr class="empty-row">
1337
- <td
1338
- colspan={visible_columns.length + (show_row_select ? 1 : 0) +
1339
- (show_row_numbers ? 1 : 0)}
1340
- >
1341
- {empty_message}
1342
- </td>
1343
- </tr>
1344
- {/if}
1345
- {/each}
1346
- </tbody>
1347
- {#if footer}
1348
- <tfoot>
1349
- {@render footer()}
1350
- </tfoot>
1351
- {/if}
1352
- </table>
1353
- </div>
1354
-
1355
- {@render sort_hint_element(`bottom`)}
1356
-
1357
- {#if pagination_config && total_pages > 1}
1358
- <div class="pagination">
1359
- <button
1360
- class="page-btn"
1361
- disabled={current_page === 1}
1362
- onclick={() => current_page = 1}
1363
- title="First page"
1364
- >
1365
- «
1366
- </button>
1367
- <button
1368
- class="page-btn"
1369
- disabled={current_page === 1}
1370
- onclick={() => current_page--}
1371
- title="Previous page"
1372
- >
1373
-
1374
- </button>
1375
- <span class="page-info">
1376
- Page
1377
- <input
1378
- type="number"
1379
- class="page-input"
1380
- min="1"
1381
- max={total_pages}
1382
- value={current_page}
1383
- onchange={(event) => {
1384
- const val = parseInt(event.currentTarget.value, 10)
1385
- current_page = Math.max(1, Math.min(total_pages, isNaN(val) ? 1 : val))
1386
- event.currentTarget.value = String(current_page)
1387
- }}
1388
- />
1389
- of {total_pages}
1390
- <span class="row-count">({sorted_data.length} rows)</span>
1391
- </span>
1392
- <button
1393
- class="page-btn"
1394
- disabled={current_page === total_pages}
1395
- onclick={() => current_page++}
1396
- title="Next page"
1397
- >
1398
-
1399
- </button>
1400
- <button
1401
- class="page-btn"
1402
- disabled={current_page === total_pages}
1403
- onclick={() => current_page = total_pages}
1404
- title="Last page"
1405
- >
1406
- »
1407
- </button>
1408
- {#if pagination_config.page_sizes}
1409
- <select
1410
- class="page-size-select"
1411
- onchange={(event) => {
1412
- effective_page_size = parseInt(event.currentTarget.value, 10)
1413
- current_page = 1
1414
- }}
1415
- >
1416
- {#each pagination_config.page_sizes as size (size)}
1417
- <option value={size} selected={size === effective_page_size}>
1418
- {size} / page
1419
- </option>
1420
- {/each}
1421
- </select>
1422
- {/if}
1423
- </div>
1424
- {/if}
1425
-
1426
- <ContextMenu
1427
- sections={better_sections}
1428
- selected_values={{ 'Gradient direction': better_overrides.get(context_menu_col ?? ``) ?? `` }}
1429
- position={context_menu_pos}
1430
- visible={context_menu_col !== null}
1431
- on_close={() => context_menu_col = null}
1432
- style={[
1433
- `--surface-bg: light-dark(#fff, #1e1e1e)`,
1434
- `--border-color: light-dark(rgba(0,0,0,0.15), rgba(255,255,255,0.15))`,
1435
- `--text-color: light-dark(#333, #eee)`,
1436
- `--text-color-muted: light-dark(#888, #999)`,
1437
- `--surface-bg-hover: light-dark(rgba(0,0,0,0.06), rgba(255,255,255,0.1))`,
1438
- `--accent-color: light-dark(rgba(0,0,0,0.1), rgba(255,255,255,0.15))`,
1439
- `z-index: 200`,
1440
- ].join(`; `)}
1441
- on_select={(_, option) => {
1442
- if (!context_menu_col) return
1443
- const current = better_overrides.get(context_menu_col)
1444
- if (current === option.value) better_overrides.delete(context_menu_col)
1445
- else better_overrides.set(context_menu_col, option.value as `higher` | `lower`)
1446
- context_menu_col = null
1447
- }}
1448
- />
1449
- </div>
1450
-
1451
- <style>
1452
- .table-container {
1453
- font-size: var(--heatmap-font-size, 0.9em);
1454
- width: fit-content;
1455
- max-width: 100%;
1456
- max-height: inherit;
1457
- margin: 0 auto;
1458
- position: relative;
1459
- display: flex;
1460
- flex-direction: column;
1461
- }
1462
- .table-scroll {
1463
- position: relative;
1464
- overflow: auto;
1465
- }
1466
- .table-scroll.has-scroll {
1467
- border: 1px solid light-dark(rgba(0, 0, 0, 0.12), rgba(255, 255, 255, 0.12));
1468
- border-radius: var(--border-radius, 3pt);
1469
- overflow-x: hidden;
1470
- overflow-y: auto;
1471
- }
1472
- table {
1473
- border-collapse: separate;
1474
- border-spacing: 0;
1475
- display: table; /* Override global display: block to enable sticky headers */
1476
- }
1477
- th, td {
1478
- padding: var(--heatmap-cell-padding, 1pt 5pt);
1479
- text-align: var(--heatmap-text-align, left);
1480
- border: var(--heatmap-cell-border, none);
1481
- white-space: nowrap;
1482
- overflow: hidden;
1483
- text-overflow: ellipsis;
1484
- /* --cell-bg is set inline per-cell by calc_color(); --heatmap-opacity is set
1485
- on the container from the heatmap_opacity prop to fade cell backgrounds */
1486
- background-color: color-mix(
1487
- in srgb,
1488
- var(--cell-bg, transparent) var(--heatmap-opacity, 100%),
1489
- transparent
1490
- );
1491
- }
1492
- th {
1493
- background: var(--heatmap-header-bg, var(--page-bg, Canvas));
1494
- position: sticky;
1495
- top: 0;
1496
- z-index: 2;
1497
- cursor: pointer;
1498
- user-select: none;
1499
- }
1500
- th:hover {
1501
- background: var(--heatmap-header-hover-bg, var(--nav-bg));
1502
- }
1503
- th.dragging {
1504
- opacity: 0.4;
1505
- cursor: grabbing;
1506
- }
1507
- th[data-drag-side='left'] {
1508
- border-left: 4px solid var(--highlight, #4a9eff);
1509
- }
1510
- th[data-drag-side='right'] {
1511
- border-right: 4px solid var(--highlight, #4a9eff);
1512
- }
1513
- th[draggable='true'] {
1514
- cursor: grab;
1515
- }
1516
- th.sticky-col {
1517
- position: sticky;
1518
- left: 0;
1519
- top: 0;
1520
- background: var(--heatmap-header-bg, var(--page-bg, Canvas));
1521
- z-index: 4; /* Higher than regular th (2) to stay above when both scroll */
1522
- border-right: 1px solid var(--border, #ddd);
1523
- }
1524
- td.sticky-col {
1525
- position: sticky;
1526
- left: 0;
1527
- background: var(--page-bg, Canvas);
1528
- z-index: 1;
1529
- border-right: 1px solid var(--border, #ddd);
1530
- }
1531
- tbody tr:hover {
1532
- filter: var(--heatmap-row-hover-filter, brightness(1.1));
1533
- }
1534
- tbody tr[tabindex] {
1535
- cursor: pointer;
1536
- }
1537
- tbody tr:focus-visible {
1538
- outline: 2px solid var(--highlight, #4a9eff);
1539
- outline-offset: -2px;
1540
- }
1541
- td[data-sort-value] {
1542
- cursor: default;
1543
- }
1544
- .group-header th {
1545
- text-align: center;
1546
- border-bottom: 1px solid var(--border);
1547
- }
1548
- /* Sticky cells in group header row need higher z-index to clip scrolling group headers */
1549
- .group-header th.sticky-col {
1550
- z-index: 5;
1551
- }
1552
- /* Floating control buttons above the table */
1553
- .control-buttons {
1554
- display: flex;
1555
- justify-content: flex-end;
1556
- align-items: center;
1557
- gap: 2px;
1558
- margin-bottom: 1px;
1559
- opacity: 0;
1560
- pointer-events: none;
1561
- transition: opacity 0.15s;
1562
- }
1563
- .table-container:hover .control-buttons,
1564
- .control-buttons:focus-within {
1565
- opacity: 1;
1566
- pointer-events: auto;
1567
- }
1568
- .icon-btn {
1569
- padding: 2px 4px;
1570
- border: none;
1571
- border-radius: 3px;
1572
- background: light-dark(rgba(0, 0, 0, 0.06), rgba(255, 255, 255, 0.1));
1573
- color: light-dark(#333, #ddd);
1574
- cursor: pointer;
1575
- display: flex;
1576
- align-items: center;
1577
- justify-content: center;
1578
- gap: 2px;
1579
- font-size: 0.8em;
1580
- }
1581
- .icon-btn :global(svg) {
1582
- width: 12px;
1583
- height: 12px;
1584
- }
1585
- .icon-btn:hover {
1586
- background: light-dark(rgba(0, 0, 0, 0.12), rgba(255, 255, 255, 0.2));
1587
- }
1588
- .icon-btn.active {
1589
- background: light-dark(rgba(0, 0, 0, 0.15), rgba(255, 255, 255, 0.25));
1590
- }
1591
- .selection-badge {
1592
- position: relative;
1593
- }
1594
- .selection-badge .badge {
1595
- background: var(--highlight, #4a9eff);
1596
- color: white;
1597
- font-size: 0.7em;
1598
- padding: 1px 4px;
1599
- border-radius: 8px;
1600
- min-width: 14px;
1601
- text-align: center;
1602
- }
1603
- .dropdown-wrapper {
1604
- position: relative;
1605
- }
1606
- .dropdown-pane {
1607
- position: absolute;
1608
- top: 100%;
1609
- right: 0;
1610
- margin-top: 4px;
1611
- padding: 4px 0;
1612
- background: light-dark(rgba(255, 255, 255, 0.98), rgba(30, 30, 30, 0.98));
1613
- border: 1px solid light-dark(rgba(0, 0, 0, 0.12), rgba(255, 255, 255, 0.15));
1614
- border-radius: 6px;
1615
- box-shadow: 0 4px 12px light-dark(rgba(0, 0, 0, 0.15), rgba(0, 0, 0, 0.4));
1616
- max-height: 280px;
1617
- overflow-y: auto;
1618
- z-index: 100;
1619
- color: light-dark(#333, #eee);
1620
- font-size: 0.95em;
1621
- }
1622
- .dropdown-option {
1623
- display: flex;
1624
- align-items: center;
1625
- gap: 8px;
1626
- padding: 3px 6px;
1627
- cursor: pointer;
1628
- font-size: 0.95em;
1629
- white-space: nowrap;
1630
- background: transparent;
1631
- border: none;
1632
- color: inherit;
1633
- width: 100%;
1634
- text-align: left;
1635
- }
1636
- .dropdown-option:hover {
1637
- background: light-dark(rgba(0, 0, 0, 0.06), rgba(255, 255, 255, 0.1));
1638
- }
1639
- /* Column toggle labels - more compact */
1640
- label.dropdown-option {
1641
- padding: 4px 10px;
1642
- gap: 6px;
1643
- }
1644
- .search-input {
1645
- padding: 2px 4px;
1646
- border: 1px solid light-dark(rgba(0, 0, 0, 0.15), rgba(255, 255, 255, 0.2));
1647
- border-radius: 3px;
1648
- background: light-dark(rgba(255, 255, 255, 0.9), rgba(0, 0, 0, 0.3));
1649
- color: light-dark(#333, #eee);
1650
- font-size: 0.8em;
1651
- width: 110px;
1652
- box-sizing: border-box;
1653
- }
1654
- .search-input:focus {
1655
- outline: 1px solid var(--highlight, #4a9eff);
1656
- }
1657
- .search-input::placeholder {
1658
- color: light-dark(#999, #666);
1659
- }
1660
- .sort-hint {
1661
- text-align: center;
1662
- font-size: 0.75em;
1663
- color: var(--text-muted);
1664
- padding: 4px 0;
1665
- opacity: 0;
1666
- transition: opacity 0.15s;
1667
- }
1668
- .table-container:hover .sort-hint,
1669
- .sort-hint.permanent {
1670
- opacity: 1;
1671
- }
1672
- .not-sortable {
1673
- cursor: default;
1674
- }
1675
- tr.highlight {
1676
- background-color: var(--nav-bg) !important;
1677
- }
1678
- tr.highlight, tr.highlight :global(a) {
1679
- color: var(--highlight) !important;
1680
- }
1681
-
1682
- /* Row selection */
1683
- .select-col {
1684
- width: 30px;
1685
- text-align: center;
1686
- vertical-align: middle;
1687
- padding: 2px !important;
1688
- }
1689
- .select-col :global(svg) {
1690
- display: block;
1691
- margin: auto;
1692
- }
1693
- tr.selected {
1694
- background: var(--highlight-bg, rgba(74, 158, 255, 0.15)) !important;
1695
- }
1696
- tr.selected td {
1697
- border-top: 1px solid var(--highlight, #4a9eff);
1698
- border-bottom: 1px solid var(--highlight, #4a9eff);
1699
- }
1700
- /* Pagination */
1701
- .pagination {
1702
- display: flex;
1703
- align-items: center;
1704
- justify-content: center;
1705
- gap: 8px;
1706
- margin-top: 12px;
1707
- padding-top: 12px;
1708
- border-top: 1px solid var(--border);
1709
- }
1710
- .page-btn {
1711
- padding: 4px 10px;
1712
- border: 1px solid var(--border, #444);
1713
- border-radius: 4px;
1714
- background: var(--page-bg, Canvas);
1715
- color: inherit;
1716
- cursor: pointer;
1717
- font-size: 1em;
1718
- }
1719
- .page-btn:hover:not(:disabled) {
1720
- background: var(--nav-bg, #333);
1721
- }
1722
- .page-btn:disabled {
1723
- opacity: 0.4;
1724
- cursor: not-allowed;
1725
- }
1726
- .page-info {
1727
- font-size: 0.9em;
1728
- display: flex;
1729
- align-items: center;
1730
- gap: 4px;
1731
- }
1732
- .page-input {
1733
- min-width: 1em !important; /* Override global min-width: 40px from app.css */
1734
- padding: 2px 4px;
1735
- border: 1px solid light-dark(rgba(0, 0, 0, 0.2), rgba(255, 255, 255, 0.2));
1736
- border-radius: 3px;
1737
- background: light-dark(#fff, #333);
1738
- color: inherit;
1739
- font-size: inherit;
1740
- text-align: center;
1741
- -moz-appearance: textfield;
1742
- appearance: textfield;
1743
- }
1744
- .page-input::-webkit-outer-spin-button,
1745
- .page-input::-webkit-inner-spin-button {
1746
- -webkit-appearance: none;
1747
- appearance: none;
1748
- margin: 0;
1749
- }
1750
- .page-input:focus {
1751
- outline: 1px solid var(--highlight, #4a9eff);
1752
- }
1753
- .row-count {
1754
- color: var(--text-muted);
1755
- font-size: 0.85em;
1756
- }
1757
-
1758
- .col-color-row {
1759
- display: flex;
1760
- align-items: center;
1761
- gap: 4px;
1762
- padding: 2px 0;
1763
- select {
1764
- font-size: 0.85em;
1765
- padding: 1px 2px;
1766
- }
1767
- }
1768
- .col-color-label {
1769
- flex: 1;
1770
- overflow: hidden;
1771
- text-overflow: ellipsis;
1772
- white-space: nowrap;
1773
- min-width: 0;
1774
- }
1775
- /* Column resize */
1776
- .resize-handle {
1777
- position: absolute;
1778
- right: 0;
1779
- top: 0;
1780
- bottom: 0;
1781
- width: 4px;
1782
- cursor: col-resize;
1783
- background: transparent;
1784
- }
1785
- .resize-handle:hover,
1786
- th.resizing .resize-handle {
1787
- background: var(--highlight, #4a9eff);
1788
- }
1789
- /* Loading overlay */
1790
- .loading-overlay {
1791
- position: absolute;
1792
- inset: 0;
1793
- background: light-dark(rgba(255, 255, 255, 0.7), rgba(0, 0, 0, 0.5));
1794
- display: flex;
1795
- align-items: center;
1796
- justify-content: center;
1797
- z-index: 10;
1798
- }
1799
- .loading-spinner {
1800
- width: 24px;
1801
- height: 24px;
1802
- border: 3px solid light-dark(#e5e7eb, #444);
1803
- border-top-color: var(--highlight, #3b82f6);
1804
- border-radius: 50%;
1805
- animation: spin 0.8s linear infinite;
1806
- }
1807
- @keyframes spin {
1808
- to {
1809
- transform: rotate(360deg);
1810
- }
1811
- }
1812
- .empty-row td {
1813
- text-align: center;
1814
- padding: 2em !important;
1815
- color: var(--text-muted, #888);
1816
- font-style: italic;
1817
- }
1818
- .row-num-col {
1819
- text-align: right;
1820
- color: var(--text-muted, #888);
1821
- font-size: 0.85em;
1822
- width: 2em;
1823
- padding-right: 8px !important;
1824
- }
1825
- .page-size-select {
1826
- padding: 2px 4px;
1827
- border: 1px solid light-dark(rgba(0, 0, 0, 0.2), rgba(255, 255, 255, 0.2));
1828
- border-radius: 3px;
1829
- background: light-dark(#fff, #333);
1830
- color: inherit;
1831
- font-size: 0.9em;
1832
- }
1833
- </style>