react-cheminfo 0.75.0 → 0.77.0

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 (342) hide show
  1. package/README.md +141 -31
  2. package/lib/card/core/cardAddress.d.ts +19 -2
  3. package/lib/card/core/cardAddress.d.ts.map +1 -1
  4. package/lib/card/core/cardAddress.js +35 -2
  5. package/lib/card/core/cardAddress.js.map +1 -1
  6. package/lib/card/core/cardPageUrl.d.ts +7 -1
  7. package/lib/card/core/cardPageUrl.d.ts.map +1 -1
  8. package/lib/card/core/cardPageUrl.js +4 -2
  9. package/lib/card/core/cardPageUrl.js.map +1 -1
  10. package/lib/card/core/index.d.ts +1 -1
  11. package/lib/card/core/index.d.ts.map +1 -1
  12. package/lib/card/core/index.js +1 -1
  13. package/lib/card/core/index.js.map +1 -1
  14. package/lib/credits/core/credits.d.ts +30 -0
  15. package/lib/credits/core/credits.d.ts.map +1 -1
  16. package/lib/credits/core/credits.js +35 -0
  17. package/lib/credits/core/credits.js.map +1 -1
  18. package/lib/download/core/copySvg.d.ts +12 -0
  19. package/lib/download/core/copySvg.d.ts.map +1 -0
  20. package/lib/download/core/copySvg.js +38 -0
  21. package/lib/download/core/copySvg.js.map +1 -0
  22. package/lib/download/core/downloadFigure.d.ts +12 -1
  23. package/lib/download/core/downloadFigure.d.ts.map +1 -1
  24. package/lib/download/core/downloadFigure.js +21 -0
  25. package/lib/download/core/downloadFigure.js.map +1 -1
  26. package/lib/download/core/figureDpi.d.ts +59 -0
  27. package/lib/download/core/figureDpi.d.ts.map +1 -0
  28. package/lib/download/core/figureDpi.js +75 -0
  29. package/lib/download/core/figureDpi.js.map +1 -0
  30. package/lib/download/core/figurePng.d.ts +4 -1
  31. package/lib/download/core/figurePng.d.ts.map +1 -1
  32. package/lib/download/core/figurePng.js +11 -2
  33. package/lib/download/core/figurePng.js.map +1 -1
  34. package/lib/download/core/index.d.ts +5 -1
  35. package/lib/download/core/index.d.ts.map +1 -1
  36. package/lib/download/core/index.js +4 -1
  37. package/lib/download/core/index.js.map +1 -1
  38. package/lib/download/core/pngDpi.d.ts +22 -0
  39. package/lib/download/core/pngDpi.d.ts.map +1 -0
  40. package/lib/download/core/pngDpi.js +79 -0
  41. package/lib/download/core/pngDpi.js.map +1 -0
  42. package/lib/download/ui/FigureDownloadPanel.d.ts +13 -0
  43. package/lib/download/ui/FigureDownloadPanel.d.ts.map +1 -1
  44. package/lib/download/ui/FigureDownloadPanel.js +18 -34
  45. package/lib/download/ui/FigureDownloadPanel.js.map +1 -1
  46. package/lib/download/ui/figureDownloadHint.d.ts +5 -0
  47. package/lib/download/ui/figureDownloadHint.d.ts.map +1 -1
  48. package/lib/download/ui/figureDownloadHint.js +8 -0
  49. package/lib/download/ui/figureDownloadHint.js.map +1 -1
  50. package/lib/download/ui/figureDownloadOptions.d.ts +84 -0
  51. package/lib/download/ui/figureDownloadOptions.d.ts.map +1 -0
  52. package/lib/download/ui/figureDownloadOptions.js +2 -0
  53. package/lib/download/ui/figureDownloadOptions.js.map +1 -0
  54. package/lib/download/ui/resolutionChoices.d.ts +27 -0
  55. package/lib/download/ui/resolutionChoices.d.ts.map +1 -0
  56. package/lib/download/ui/resolutionChoices.js +48 -0
  57. package/lib/download/ui/resolutionChoices.js.map +1 -0
  58. package/lib/download/ui/useFigureActions.d.ts +4 -1
  59. package/lib/download/ui/useFigureActions.d.ts.map +1 -1
  60. package/lib/download/ui/useFigureActions.js +17 -8
  61. package/lib/download/ui/useFigureActions.js.map +1 -1
  62. package/lib/download/ui/useFigureDownload.d.ts +2 -55
  63. package/lib/download/ui/useFigureDownload.d.ts.map +1 -1
  64. package/lib/download/ui/useFigureDownload.js +45 -13
  65. package/lib/download/ui/useFigureDownload.js.map +1 -1
  66. package/lib/ecosystem/core/sites.d.ts.map +1 -1
  67. package/lib/ecosystem/core/sites.js +14 -0
  68. package/lib/ecosystem/core/sites.js.map +1 -1
  69. package/lib/ecosystem/core/types.d.ts +1 -1
  70. package/lib/ecosystem/core/types.d.ts.map +1 -1
  71. package/lib/ecosystem/ui/glyphs.d.ts.map +1 -1
  72. package/lib/ecosystem/ui/glyphs.js +3 -0
  73. package/lib/ecosystem/ui/glyphs.js.map +1 -1
  74. package/lib/i18n/core/chromeCatalog.d.ts +1 -1
  75. package/lib/i18n/core/chromeCatalog.d.ts.map +1 -1
  76. package/lib/ir/core/bandAssignments.d.ts.map +1 -1
  77. package/lib/ir/core/bandAssignments.js +27 -0
  78. package/lib/ir/core/bandAssignments.js.map +1 -1
  79. package/lib/ir/ui/BandRow.d.ts +4 -4
  80. package/lib/ir/ui/BandRow.d.ts.map +1 -1
  81. package/lib/ir/ui/BandRow.js +41 -14
  82. package/lib/ir/ui/BandRow.js.map +1 -1
  83. package/lib/locales/de.json +32 -1
  84. package/lib/locales/en.json +32 -1
  85. package/lib/locales/es.json +32 -1
  86. package/lib/locales/fr.json +32 -1
  87. package/lib/locales/it.json +32 -1
  88. package/lib/molecule3d/ui/Molecule3DStage.d.ts +4 -33
  89. package/lib/molecule3d/ui/Molecule3DStage.d.ts.map +1 -1
  90. package/lib/molecule3d/ui/Molecule3DStage.js +3 -37
  91. package/lib/molecule3d/ui/Molecule3DStage.js.map +1 -1
  92. package/lib/osiris/core/barGeometry.d.ts +42 -0
  93. package/lib/osiris/core/barGeometry.d.ts.map +1 -0
  94. package/lib/osiris/core/barGeometry.js +46 -0
  95. package/lib/osiris/core/barGeometry.js.map +1 -0
  96. package/lib/osiris/core/computeProperties.d.ts +42 -0
  97. package/lib/osiris/core/computeProperties.d.ts.map +1 -0
  98. package/lib/osiris/core/computeProperties.js +115 -0
  99. package/lib/osiris/core/computeProperties.js.map +1 -0
  100. package/lib/osiris/core/constants.d.ts +70 -0
  101. package/lib/osiris/core/constants.d.ts.map +1 -0
  102. package/lib/osiris/core/constants.js +99 -0
  103. package/lib/osiris/core/constants.js.map +1 -0
  104. package/lib/osiris/core/fitness.d.ts +32 -0
  105. package/lib/osiris/core/fitness.d.ts.map +1 -0
  106. package/lib/osiris/core/fitness.js +48 -0
  107. package/lib/osiris/core/fitness.js.map +1 -0
  108. package/lib/osiris/core/index.d.ts +29 -0
  109. package/lib/osiris/core/index.d.ts.map +1 -0
  110. package/lib/osiris/core/index.js +19 -0
  111. package/lib/osiris/core/index.js.map +1 -0
  112. package/lib/osiris/core/poolSize.d.ts +17 -0
  113. package/lib/osiris/core/poolSize.d.ts.map +1 -0
  114. package/lib/osiris/core/poolSize.js +22 -0
  115. package/lib/osiris/core/poolSize.js.map +1 -0
  116. package/lib/osiris/core/poolTypes.d.ts +140 -0
  117. package/lib/osiris/core/poolTypes.d.ts.map +1 -0
  118. package/lib/osiris/core/poolTypes.js +12 -0
  119. package/lib/osiris/core/poolTypes.js.map +1 -0
  120. package/lib/osiris/core/predictIdCode.d.ts +39 -0
  121. package/lib/osiris/core/predictIdCode.d.ts.map +1 -0
  122. package/lib/osiris/core/predictIdCode.js +54 -0
  123. package/lib/osiris/core/predictIdCode.js.map +1 -0
  124. package/lib/osiris/core/predictProtocol.d.ts +67 -0
  125. package/lib/osiris/core/predictProtocol.d.ts.map +1 -0
  126. package/lib/osiris/core/predictProtocol.js +29 -0
  127. package/lib/osiris/core/predictProtocol.js.map +1 -0
  128. package/lib/osiris/core/predictionPool.d.ts +23 -0
  129. package/lib/osiris/core/predictionPool.d.ts.map +1 -0
  130. package/lib/osiris/core/predictionPool.js +186 -0
  131. package/lib/osiris/core/predictionPool.js.map +1 -0
  132. package/lib/osiris/core/predictionQueue.d.ts +46 -0
  133. package/lib/osiris/core/predictionQueue.d.ts.map +1 -0
  134. package/lib/osiris/core/predictionQueue.js +57 -0
  135. package/lib/osiris/core/predictionQueue.js.map +1 -0
  136. package/lib/osiris/core/predictors.d.ts +62 -0
  137. package/lib/osiris/core/predictors.d.ts.map +1 -0
  138. package/lib/osiris/core/predictors.js +100 -0
  139. package/lib/osiris/core/predictors.js.map +1 -0
  140. package/lib/osiris/core/propertyKeys.d.ts +32 -0
  141. package/lib/osiris/core/propertyKeys.d.ts.map +1 -0
  142. package/lib/osiris/core/propertyKeys.js +44 -0
  143. package/lib/osiris/core/propertyKeys.js.map +1 -0
  144. package/lib/osiris/core/riskAppearance.d.ts +60 -0
  145. package/lib/osiris/core/riskAppearance.d.ts.map +1 -0
  146. package/lib/osiris/core/riskAppearance.js +59 -0
  147. package/lib/osiris/core/riskAppearance.js.map +1 -0
  148. package/lib/osiris/core/riskDetail.d.ts +22 -0
  149. package/lib/osiris/core/riskDetail.d.ts.map +1 -0
  150. package/lib/osiris/core/riskDetail.js +86 -0
  151. package/lib/osiris/core/riskDetail.js.map +1 -0
  152. package/lib/osiris/core/riskDetailRequest.d.ts +31 -0
  153. package/lib/osiris/core/riskDetailRequest.d.ts.map +1 -0
  154. package/lib/osiris/core/riskDetailRequest.js +49 -0
  155. package/lib/osiris/core/riskDetailRequest.js.map +1 -0
  156. package/lib/osiris/core/riskFindings.d.ts +26 -0
  157. package/lib/osiris/core/riskFindings.d.ts.map +1 -0
  158. package/lib/osiris/core/riskFindings.js +79 -0
  159. package/lib/osiris/core/riskFindings.js.map +1 -0
  160. package/lib/osiris/core/runPredictionJob.d.ts +20 -0
  161. package/lib/osiris/core/runPredictionJob.d.ts.map +1 -0
  162. package/lib/osiris/core/runPredictionJob.js +43 -0
  163. package/lib/osiris/core/runPredictionJob.js.map +1 -0
  164. package/lib/osiris/core/scales.d.ts +70 -0
  165. package/lib/osiris/core/scales.d.ts.map +1 -0
  166. package/lib/osiris/core/scales.js +185 -0
  167. package/lib/osiris/core/scales.js.map +1 -0
  168. package/lib/osiris/core/types.d.ts +91 -0
  169. package/lib/osiris/core/types.d.ts.map +1 -0
  170. package/lib/osiris/core/types.js +19 -0
  171. package/lib/osiris/core/types.js.map +1 -0
  172. package/lib/osiris/core/valuation.d.ts +28 -0
  173. package/lib/osiris/core/valuation.d.ts.map +1 -0
  174. package/lib/osiris/core/valuation.js +39 -0
  175. package/lib/osiris/core/valuation.js.map +1 -0
  176. package/lib/osiris/ui/PropertyBar.d.ts +27 -0
  177. package/lib/osiris/ui/PropertyBar.d.ts.map +1 -0
  178. package/lib/osiris/ui/PropertyBar.js +27 -0
  179. package/lib/osiris/ui/PropertyBar.js.map +1 -0
  180. package/lib/osiris/ui/PropertyPanel.d.ts +91 -0
  181. package/lib/osiris/ui/PropertyPanel.d.ts.map +1 -0
  182. package/lib/osiris/ui/PropertyPanel.js +77 -0
  183. package/lib/osiris/ui/PropertyPanel.js.map +1 -0
  184. package/lib/osiris/ui/PropertyRows.d.ts +40 -0
  185. package/lib/osiris/ui/PropertyRows.d.ts.map +1 -0
  186. package/lib/osiris/ui/PropertyRows.js +23 -0
  187. package/lib/osiris/ui/PropertyRows.js.map +1 -0
  188. package/lib/osiris/ui/RiskFindings.d.ts +43 -0
  189. package/lib/osiris/ui/RiskFindings.d.ts.map +1 -0
  190. package/lib/osiris/ui/RiskFindings.js +51 -0
  191. package/lib/osiris/ui/RiskFindings.js.map +1 -0
  192. package/lib/osiris/ui/RiskPanel.d.ts +46 -0
  193. package/lib/osiris/ui/RiskPanel.d.ts.map +1 -0
  194. package/lib/osiris/ui/RiskPanel.js +32 -0
  195. package/lib/osiris/ui/RiskPanel.js.map +1 -0
  196. package/lib/osiris/ui/RiskSquare.d.ts +51 -0
  197. package/lib/osiris/ui/RiskSquare.d.ts.map +1 -0
  198. package/lib/osiris/ui/RiskSquare.js +23 -0
  199. package/lib/osiris/ui/RiskSquare.js.map +1 -0
  200. package/lib/osiris/ui/index.d.ts +15 -0
  201. package/lib/osiris/ui/index.d.ts.map +1 -0
  202. package/lib/osiris/ui/index.js +8 -0
  203. package/lib/osiris/ui/index.js.map +1 -0
  204. package/lib/osiris/ui/usePredictions.d.ts +81 -0
  205. package/lib/osiris/ui/usePredictions.d.ts.map +1 -0
  206. package/lib/osiris/ui/usePredictions.js +102 -0
  207. package/lib/osiris/ui/usePredictions.js.map +1 -0
  208. package/lib/osiris-ui.d.ts +11 -0
  209. package/lib/osiris-ui.d.ts.map +1 -0
  210. package/lib/osiris-ui.js +11 -0
  211. package/lib/osiris-ui.js.map +1 -0
  212. package/lib/osiris.d.ts +17 -0
  213. package/lib/osiris.d.ts.map +1 -0
  214. package/lib/osiris.js +17 -0
  215. package/lib/osiris.js.map +1 -0
  216. package/lib/panel/ui/FilterInput.d.ts.map +1 -1
  217. package/lib/panel/ui/FilterInput.js +3 -1
  218. package/lib/panel/ui/FilterInput.js.map +1 -1
  219. package/lib/panel/ui/SidePanelItem.d.ts +39 -0
  220. package/lib/panel/ui/SidePanelItem.d.ts.map +1 -0
  221. package/lib/panel/ui/SidePanelItem.js +63 -0
  222. package/lib/panel/ui/SidePanelItem.js.map +1 -0
  223. package/lib/panel/ui/SidePanelStack.d.ts +11 -10
  224. package/lib/panel/ui/SidePanelStack.d.ts.map +1 -1
  225. package/lib/panel/ui/SidePanelStack.js +22 -15
  226. package/lib/panel/ui/SidePanelStack.js.map +1 -1
  227. package/lib/panel/ui/SpectrumColorSwatch.d.ts.map +1 -1
  228. package/lib/panel/ui/SpectrumColorSwatch.js +4 -2
  229. package/lib/panel/ui/SpectrumColorSwatch.js.map +1 -1
  230. package/lib/panel/ui/usePanelFolds.d.ts +35 -0
  231. package/lib/panel/ui/usePanelFolds.d.ts.map +1 -0
  232. package/lib/panel/ui/usePanelFolds.js +73 -0
  233. package/lib/panel/ui/usePanelFolds.js.map +1 -0
  234. package/lib/shared/ui/FullscreenStage.d.ts +43 -0
  235. package/lib/shared/ui/FullscreenStage.d.ts.map +1 -0
  236. package/lib/shared/ui/FullscreenStage.js +38 -0
  237. package/lib/shared/ui/FullscreenStage.js.map +1 -0
  238. package/lib/shared/ui/canFillScreen.d.ts +7 -0
  239. package/lib/shared/ui/canFillScreen.d.ts.map +1 -0
  240. package/lib/shared/ui/canFillScreen.js +9 -0
  241. package/lib/shared/ui/canFillScreen.js.map +1 -0
  242. package/lib/shared/ui/index.d.ts +3 -0
  243. package/lib/shared/ui/index.d.ts.map +1 -1
  244. package/lib/shared/ui/index.js +2 -0
  245. package/lib/shared/ui/index.js.map +1 -1
  246. package/lib/split/ui/splitPanes.d.ts +3 -3
  247. package/lib/split/ui/splitPanes.js +1 -1
  248. package/lib/structure/core/structureNotations.d.ts +8 -1
  249. package/lib/structure/core/structureNotations.d.ts.map +1 -1
  250. package/lib/structure/core/structureNotations.js +14 -8
  251. package/lib/structure/core/structureNotations.js.map +1 -1
  252. package/lib/structure/ui/CardStructure.d.ts +43 -0
  253. package/lib/structure/ui/CardStructure.d.ts.map +1 -0
  254. package/lib/structure/ui/CardStructure.js +28 -0
  255. package/lib/structure/ui/CardStructure.js.map +1 -0
  256. package/lib/structure/ui/StructureExportPanel.d.ts +8 -0
  257. package/lib/structure/ui/StructureExportPanel.d.ts.map +1 -1
  258. package/lib/structure/ui/StructureExportPanel.js +9 -4
  259. package/lib/structure/ui/StructureExportPanel.js.map +1 -1
  260. package/lib/structure/ui/StructurePicturePane.d.ts +1 -1
  261. package/lib/structure/ui/StructurePicturePane.d.ts.map +1 -1
  262. package/lib/structure/ui/StructurePicturePane.js +5 -2
  263. package/lib/structure/ui/StructurePicturePane.js.map +1 -1
  264. package/lib/structure/ui/index.d.ts +3 -0
  265. package/lib/structure/ui/index.d.ts.map +1 -1
  266. package/lib/structure/ui/index.js +1 -0
  267. package/lib/structure/ui/index.js.map +1 -1
  268. package/package.json +4 -1
  269. package/src/card/core/cardAddress.ts +39 -3
  270. package/src/card/core/cardPageUrl.ts +10 -3
  271. package/src/card/core/index.ts +7 -1
  272. package/src/credits/core/credits.ts +40 -0
  273. package/src/download/core/copySvg.ts +40 -0
  274. package/src/download/core/downloadFigure.ts +26 -1
  275. package/src/download/core/figureDpi.ts +94 -0
  276. package/src/download/core/figurePng.ts +11 -2
  277. package/src/download/core/index.ts +14 -1
  278. package/src/download/core/pngDpi.ts +84 -0
  279. package/src/download/ui/FigureDownloadPanel.tsx +41 -51
  280. package/src/download/ui/figureDownloadHint.ts +13 -0
  281. package/src/download/ui/figureDownloadOptions.ts +85 -0
  282. package/src/download/ui/resolutionChoices.ts +67 -0
  283. package/src/download/ui/useFigureActions.ts +24 -9
  284. package/src/download/ui/useFigureDownload.tsx +57 -71
  285. package/src/ecosystem/core/sites.ts +14 -0
  286. package/src/ecosystem/core/types.ts +2 -1
  287. package/src/ecosystem/ui/glyphs.tsx +20 -0
  288. package/src/ir/core/bandAssignments.ts +27 -0
  289. package/src/ir/ui/BandRow.tsx +84 -26
  290. package/src/locales/de.json +32 -1
  291. package/src/locales/en.json +32 -1
  292. package/src/locales/es.json +32 -1
  293. package/src/locales/fr.json +32 -1
  294. package/src/locales/it.json +32 -1
  295. package/src/molecule3d/ui/Molecule3DStage.tsx +4 -88
  296. package/src/osiris/core/barGeometry.ts +74 -0
  297. package/src/osiris/core/computeProperties.ts +175 -0
  298. package/src/osiris/core/constants.ts +110 -0
  299. package/src/osiris/core/fitness.ts +59 -0
  300. package/src/osiris/core/index.ts +78 -0
  301. package/src/osiris/core/poolSize.ts +24 -0
  302. package/src/osiris/core/poolTypes.ts +140 -0
  303. package/src/osiris/core/predictIdCode.ts +69 -0
  304. package/src/osiris/core/predictProtocol.ts +78 -0
  305. package/src/osiris/core/predictionPool.ts +237 -0
  306. package/src/osiris/core/predictionQueue.ts +89 -0
  307. package/src/osiris/core/predictors.ts +142 -0
  308. package/src/osiris/core/propertyKeys.ts +54 -0
  309. package/src/osiris/core/riskAppearance.ts +86 -0
  310. package/src/osiris/core/riskDetail.ts +120 -0
  311. package/src/osiris/core/riskDetailRequest.ts +64 -0
  312. package/src/osiris/core/riskFindings.ts +92 -0
  313. package/src/osiris/core/runPredictionJob.ts +49 -0
  314. package/src/osiris/core/scales.ts +236 -0
  315. package/src/osiris/core/types.ts +103 -0
  316. package/src/osiris/core/valuation.ts +44 -0
  317. package/src/osiris/ui/PropertyBar.tsx +77 -0
  318. package/src/osiris/ui/PropertyPanel.tsx +227 -0
  319. package/src/osiris/ui/PropertyRows.tsx +92 -0
  320. package/src/osiris/ui/RiskFindings.tsx +137 -0
  321. package/src/osiris/ui/RiskPanel.tsx +81 -0
  322. package/src/osiris/ui/RiskSquare.tsx +108 -0
  323. package/src/osiris/ui/index.ts +17 -0
  324. package/src/osiris/ui/usePredictions.ts +194 -0
  325. package/src/osiris-ui.ts +11 -0
  326. package/src/osiris.ts +17 -0
  327. package/src/panel/ui/FilterInput.tsx +4 -1
  328. package/src/panel/ui/SidePanelItem.tsx +162 -0
  329. package/src/panel/ui/SidePanelStack.tsx +29 -36
  330. package/src/panel/ui/SpectrumColorSwatch.tsx +5 -3
  331. package/src/panel/ui/usePanelFolds.ts +103 -0
  332. package/src/shared/ui/FullscreenStage.tsx +96 -0
  333. package/src/shared/ui/canFillScreen.ts +8 -0
  334. package/src/shared/ui/index.ts +6 -0
  335. package/src/split/ui/splitPanes.tsx +4 -4
  336. package/src/structure/core/structureNotations.ts +25 -8
  337. package/src/structure/ui/CardStructure.tsx +76 -0
  338. package/src/structure/ui/StructureExportPanel.tsx +23 -4
  339. package/src/structure/ui/StructurePicturePane.tsx +14 -1
  340. package/src/structure/ui/index.ts +6 -0
  341. package/styles/chrome.css +3 -3
  342. package/styles/osiris.css +339 -0
@@ -0,0 +1,76 @@
1
+ import type { ReactElement, ReactNode } from 'react';
2
+
3
+ import { OverlayLayer } from '../../overlay/ui/OverlayLayer.tsx';
4
+ import { structureSource } from '../core/structureSource.ts';
5
+
6
+ import type { StructureProps } from './Structure.tsx';
7
+ import { Structure } from './Structure.tsx';
8
+ import { StructureExportButton } from './StructureExportButton.tsx';
9
+
10
+ /** What {@link CardStructure} draws and hands over. */
11
+ export interface CardStructureProps extends StructureProps {
12
+ /**
13
+ * Base name of every file saved from the export, extension excluded.
14
+ * @default 'structure'
15
+ */
16
+ name?: string;
17
+ /**
18
+ * Whether the structure is a query fragment, such as a toxicophore, whose
19
+ * idCode is not a molecule's.
20
+ * @default false
21
+ */
22
+ fragment?: boolean;
23
+ /**
24
+ * What the glyph is called, for the pointer and for a screen reader.
25
+ * @default the chrome's own line, `Copy or save the structure: SMILES,
26
+ * molfile`
27
+ */
28
+ label?: string;
29
+ /**
30
+ * The drawing, when the site draws the structure itself — its own
31
+ * highlights, its own numbering. The export still reads the notations.
32
+ * @default a `Structure` drawn from the same notations, at the same size
33
+ */
34
+ children?: ReactNode;
35
+ }
36
+
37
+ /**
38
+ * A structure of a card, with the glyph that hands it over: the export
39
+ * dialog, which copies it as an SVG or a PNG, a SMILES or a molfile, V2000 or
40
+ * V3000. Every structure an answer draws carries it, alone or in a grid, so
41
+ * none has to be redrawn to be reused.
42
+ *
43
+ * The glyph stands beside the top right corner, faded until the structure is
44
+ * pointed at, as the glyphs of `CardFigure` (`react-cheminfo/card`) do;
45
+ * `styles/card.css` draws both. A structure with nothing to read draws its
46
+ * placeholder alone.
47
+ * @param props - The structure, its size, and the name of its files.
48
+ * @returns The structure and its glyph.
49
+ */
50
+ export function CardStructure(props: CardStructureProps): ReactElement {
51
+ const { name, fragment, label, children, ...structure } = props;
52
+ const { idCode, coordinates, molfile, smiles } = structure;
53
+ const drawing = children ?? <Structure {...structure} />;
54
+ const source = structureSource({ idCode, coordinates, molfile, smiles });
55
+ if (source.kind === 'empty') return <>{drawing}</>;
56
+
57
+ return (
58
+ <div className="card-figure card-structure">
59
+ <div className="card-figure__drawing">{drawing}</div>
60
+ {/* Compact: the glyphs of a figure shown in somebody else's page. */}
61
+ <OverlayLayer density="compact" awake>
62
+ <div className="card-figure__tools" data-testid="figure-tools">
63
+ <StructureExportButton
64
+ idCode={idCode}
65
+ coordinates={coordinates}
66
+ molfile={molfile}
67
+ smiles={smiles}
68
+ name={name}
69
+ fragment={fragment}
70
+ label={label}
71
+ />
72
+ </div>
73
+ </OverlayLayer>
74
+ </div>
75
+ );
76
+ }
@@ -15,6 +15,7 @@ import { useChromeT } from '../../i18n/ui/useT.ts';
15
15
  import { TOKEN } from '../../tokens/core/familyTokens.ts';
16
16
  import { sourceMolecule } from '../core/sourceMolecule.ts';
17
17
  import { structureError } from '../core/structureError.ts';
18
+ import type { SuppliedNotations } from '../core/structureNotations.ts';
18
19
  import { structureNotations } from '../core/structureNotations.ts';
19
20
  import type { StructureSourceInput } from '../core/structureSource.ts';
20
21
  import { structureSource } from '../core/structureSource.ts';
@@ -36,6 +37,13 @@ export interface StructureExportPanelProps extends StructureSourceInput {
36
37
  * @default false
37
38
  */
38
39
  fragment?: boolean;
40
+ /**
41
+ * Notations the caller wrote itself, shown and saved as they are instead of
42
+ * the ones OpenChemLib would write from the structure — a drawing program
43
+ * whose molfile keeps superatoms that a round trip would drop.
44
+ * @default {}
45
+ */
46
+ notations?: SuppliedNotations;
39
47
  }
40
48
 
41
49
  /**
@@ -53,12 +61,17 @@ export function StructureExportPanel(
53
61
  props: StructureExportPanelProps,
54
62
  ): ReactElement {
55
63
  const { idCode, coordinates, molfile, smiles } = props;
56
- const { name = 'structure', fragment = false } = props;
64
+ const { name = 'structure', fragment = false, notations: supplied } = props;
57
65
  const t = useChromeT();
58
66
 
59
67
  const read = useMemo(
60
- () => readStructure({ idCode, coordinates, molfile, smiles }, fragment),
61
- [idCode, coordinates, molfile, smiles, fragment],
68
+ () =>
69
+ readStructure(
70
+ { idCode, coordinates, molfile, smiles },
71
+ fragment,
72
+ supplied,
73
+ ),
74
+ [idCode, coordinates, molfile, smiles, fragment, supplied],
62
75
  );
63
76
 
64
77
  if (read.kind !== 'read') {
@@ -120,11 +133,13 @@ type ReadStructure =
120
133
  * Read the notation the caller handed over, and write every other one from it.
121
134
  * @param input - Whatever notations the caller has.
122
135
  * @param fragment - Whether the structure is a query fragment.
136
+ * @param supplied - Notations the caller wrote itself.
123
137
  * @returns The molecule and its notations, or why there are none.
124
138
  */
125
139
  function readStructure(
126
140
  input: StructureSourceInput,
127
141
  fragment: boolean,
142
+ supplied: SuppliedNotations | undefined,
128
143
  ): ReadStructure {
129
144
  const source = structureSource(input);
130
145
  if (source.kind === 'empty') return { kind: 'empty' };
@@ -135,7 +150,11 @@ function readStructure(
135
150
  // structure from the one that was drawn.
136
151
  if (fragment) molecule.setFragment(true);
137
152
  if (molecule.getAllAtoms() === 0) return { kind: 'empty' };
138
- return { kind: 'read', molecule, notations: structureNotations(molecule) };
153
+ return {
154
+ kind: 'read',
155
+ molecule,
156
+ notations: structureNotations(molecule, supplied),
157
+ };
139
158
  } catch (error) {
140
159
  return { kind: 'error', message: structureError(error).message };
141
160
  }
@@ -4,6 +4,7 @@ import type { CSSProperties, ReactElement } from 'react';
4
4
  import { useMemo, useState } from 'react';
5
5
 
6
6
  import { copyFigure } from '../../download/core/copyFigure.ts';
7
+ import { copySvg } from '../../download/core/copySvg.ts';
7
8
  import { downloadBlob } from '../../download/core/downloadBlob.ts';
8
9
  import { downloadText } from '../../download/core/downloadText.ts';
9
10
  import { figurePng } from '../../download/core/figurePng.ts';
@@ -37,7 +38,7 @@ const DEFAULT_SCALE = 2;
37
38
 
38
39
  /**
39
40
  * The structure as a picture: what it looks like, how big it leaves, and the
40
- * three ways it leaves.
41
+ * four ways it leaves.
41
42
  *
42
43
  * What is shown is the file: the preview is the very SVG the save button
43
44
  * writes, laid out smaller, so nobody saves a picture they have not seen. The
@@ -136,6 +137,18 @@ export function StructurePicturePane(
136
137
  })
137
138
  }
138
139
  />
140
+ <Button
141
+ icon="clipboard"
142
+ size="small"
143
+ text={t('structure.export.copySvg')}
144
+ onClick={() =>
145
+ void run(async () =>
146
+ (await copySvg(picture.markup))
147
+ ? t('structure.export.svgCopied')
148
+ : t('clipboard.failed'),
149
+ )
150
+ }
151
+ />
139
152
  <Button
140
153
  icon="clipboard"
141
154
  size="small"
@@ -33,7 +33,13 @@ export type { StructureExportDialogProps } from './StructureExportDialog.tsx';
33
33
  export { StructureExportDialog } from './StructureExportDialog.tsx';
34
34
  export type { StructureExportButtonProps } from './StructureExportButton.tsx';
35
35
  export { StructureExportButton } from './StructureExportButton.tsx';
36
+ export type { CardStructureProps } from './CardStructure.tsx';
37
+ export { CardStructure } from './CardStructure.tsx';
36
38
  export type { StructureExportPanelProps } from './StructureExportPanel.tsx';
39
+ export type {
40
+ StructureNotationKind,
41
+ SuppliedNotations,
42
+ } from '../core/structureNotations.ts';
37
43
  export type { ToolbarFloorOptions } from './useToolbarFloor.ts';
38
44
  export { useToolbarFloor } from './useToolbarFloor.ts';
39
45
  export type { StructureDraft } from './useStructureDraft.ts';
package/styles/chrome.css CHANGED
@@ -850,9 +850,9 @@ a.source-badge:hover {
850
850
  gap: 8px;
851
851
  }
852
852
 
853
- /* Two columns, so the three buttons are one size: a row of buttons whose
854
- widths are set by the length of their labels reads as three unrelated
855
- controls. */
853
+ /* Two columns, so the buttons are one size — the saves over the copies, SVG
854
+ over SVG: a row of buttons whose widths are set by the length of their
855
+ labels reads as unrelated controls. */
856
856
  .structure-export__actions {
857
857
  display: grid;
858
858
  margin-top: 2px;
@@ -0,0 +1,339 @@
1
+ /*
2
+ * The OSIRIS property panel of `react-cheminfo/osiris-ui`: the four risk
3
+ * squares, the ten bars, and the explanation a square opens. Imported once by
4
+ * the page that draws the panel, after `chrome.css`, whose tokens it reads.
5
+ *
6
+ * Every colour is a token. The neutrals and the geometry are the family's, the
7
+ * accent is the site's own, and the three status colours below are the shared
8
+ * semantic ones — the same values on every site, never retuned. They are
9
+ * declared here because `chrome.css` does not declare them; a page that loads
10
+ * both reads the same three values either way.
11
+ */
12
+
13
+ :root {
14
+ --danger: #dc2626;
15
+ --success: #16a34a;
16
+ --warning: #d97706;
17
+ }
18
+
19
+ /* ── The panel ──────────────────────────────────────────────────────────── */
20
+
21
+ .property-panel {
22
+ display: flex;
23
+ flex-direction: column;
24
+ gap: 12px;
25
+ }
26
+
27
+ .property-panel__head {
28
+ display: flex;
29
+ align-items: baseline;
30
+ flex-wrap: wrap;
31
+ gap: 4px 10px;
32
+ font-size: 1.0625rem;
33
+ font-weight: 600;
34
+ }
35
+
36
+ /* A name from an SD field, or the molecule's own SMILES when it carried none:
37
+ either can be long, and neither is worth pushing the numbers off the card. */
38
+ .property-panel__label {
39
+ overflow: hidden;
40
+ max-width: 100%;
41
+ color: var(--text-muted);
42
+ font-size: 0.8125rem;
43
+ font-weight: 400;
44
+ text-overflow: ellipsis;
45
+ white-space: nowrap;
46
+ }
47
+
48
+ .osiris-note {
49
+ margin: 0;
50
+ color: var(--text-muted);
51
+ font-size: 0.8125rem;
52
+ }
53
+
54
+ /* The spinner while an explanation is fetched, on the line it explains. */
55
+ .osiris-note--working {
56
+ display: flex;
57
+ align-items: center;
58
+ gap: 6px;
59
+ }
60
+
61
+ .risk-panel,
62
+ .property-section {
63
+ display: flex;
64
+ flex-direction: column;
65
+ gap: 8px;
66
+ }
67
+
68
+ .risk-panel h5,
69
+ .property-section h5 {
70
+ margin: 0;
71
+ }
72
+
73
+ /* ── The four risks ─────────────────────────────────────────────────────── */
74
+
75
+ /* Two columns at the least: in a side panel too narrow for two 11rem squares,
76
+ the names wrap rather than stacking the four risks one under another. */
77
+ .risk-grid {
78
+ display: grid;
79
+ gap: 6px;
80
+ grid-template-columns: repeat(
81
+ auto-fit,
82
+ minmax(min(11rem, calc(50% - 3px)), 1fr)
83
+ );
84
+ }
85
+
86
+ .risk-square {
87
+ display: flex;
88
+ align-items: center;
89
+ padding: 6px 8px;
90
+ border: 1px solid var(--border);
91
+ border-radius: var(--radius);
92
+ margin: 0;
93
+ background: var(--surface);
94
+ color: inherit;
95
+ font: inherit;
96
+ gap: 8px;
97
+ text-align: left;
98
+ }
99
+
100
+ button.risk-square {
101
+ cursor: pointer;
102
+ }
103
+
104
+ button.risk-square:hover {
105
+ border-color: var(--border-strong);
106
+ background: var(--surface-sunken);
107
+ }
108
+
109
+ button.risk-square[aria-pressed='true'] {
110
+ border-color: var(--accent);
111
+ background: color-mix(in oklab, var(--accent) 10%, white);
112
+ }
113
+
114
+ /* A cell of the comparison table: the square alone, centred in its column. */
115
+ .risk-square--compact {
116
+ justify-content: center;
117
+ padding: 2px;
118
+ border: 0;
119
+ background: none;
120
+ }
121
+
122
+ .risk-square__swatch {
123
+ width: 14px;
124
+ height: 14px;
125
+ flex: none;
126
+ border-radius: 3px;
127
+ background: var(--text-faint);
128
+ }
129
+
130
+ /* The three levels are the three the drug score multiplies by — ×1, ×0.8, ×0.6
131
+ — so the colour says what the score already counted. `unknown` is the
132
+ library's own "the tables did not load", which is never green. */
133
+ .risk-square__swatch[data-level='none'] {
134
+ background: var(--success);
135
+ }
136
+
137
+ .risk-square__swatch[data-level='low'] {
138
+ background: var(--warning);
139
+ }
140
+
141
+ .risk-square__swatch[data-level='high'] {
142
+ background: var(--danger);
143
+ }
144
+
145
+ .risk-square__swatch[data-level='unknown'] {
146
+ background: var(--text-faint);
147
+ }
148
+
149
+ .risk-square__swatch[data-level='pending'] {
150
+ background: repeating-linear-gradient(
151
+ 45deg,
152
+ var(--border),
153
+ var(--border) 3px,
154
+ var(--surface) 3px,
155
+ var(--surface) 6px
156
+ );
157
+ }
158
+
159
+ .risk-square__text {
160
+ display: flex;
161
+ min-width: 0;
162
+ flex-direction: column;
163
+ }
164
+
165
+ .risk-square__name {
166
+ font-size: 0.8125rem;
167
+ font-weight: 600;
168
+ }
169
+
170
+ .risk-square__level {
171
+ color: var(--text-muted);
172
+ font-size: 0.75rem;
173
+ }
174
+
175
+ /* ── Why a risk came back as it did ─────────────────────────────────────── */
176
+
177
+ .risk-findings {
178
+ display: flex;
179
+ flex-direction: column;
180
+ padding: 8px 10px;
181
+ border: 1px solid var(--border);
182
+ border-radius: var(--radius);
183
+ background: var(--surface-sunken);
184
+ gap: 10px;
185
+ }
186
+
187
+ .risk-finding__heading {
188
+ margin: 0;
189
+ font-size: 0.8125rem;
190
+ font-weight: 600;
191
+ }
192
+
193
+ .risk-finding__drawings {
194
+ display: flex;
195
+ flex-wrap: wrap;
196
+ gap: 10px;
197
+ }
198
+
199
+ .risk-finding__figure {
200
+ margin: 0;
201
+ }
202
+
203
+ .risk-finding__figure > figcaption {
204
+ color: var(--text-muted);
205
+ font-size: 0.75rem;
206
+ }
207
+
208
+ /* ── The ten numbers ────────────────────────────────────────────────────
209
+
210
+ A name, a bar and a value on one line each. The bar's colour is the only
211
+ thing here that is not a neutral, and it is mixed from the three status
212
+ tokens — there is no hex code in this part and none in the component that
213
+ sets the fill's length. */
214
+
215
+ .property-rows {
216
+ display: flex;
217
+ flex-direction: column;
218
+ gap: 10px;
219
+ }
220
+
221
+ .property-row {
222
+ display: grid;
223
+ align-items: center;
224
+ gap: 0 10px;
225
+ grid-template-columns: minmax(6rem, 8.5rem) minmax(4rem, 1fr) minmax(
226
+ 3.5rem,
227
+ auto
228
+ );
229
+ }
230
+
231
+ .property-row__label {
232
+ font-size: 0.8125rem;
233
+ }
234
+
235
+ .property-row__unit {
236
+ color: var(--text-faint);
237
+ font-size: 0.6875rem;
238
+ }
239
+
240
+ .property-row__unit::before {
241
+ content: ' ';
242
+ }
243
+
244
+ .property-row__value {
245
+ font-size: 0.8125rem;
246
+ font-variant-numeric: tabular-nums;
247
+ text-align: right;
248
+ }
249
+
250
+ /* The bar carries its threshold label under it, so the row keeps room for one
251
+ whether or not that property has a published rule of thumb. */
252
+ .property-bar {
253
+ position: relative;
254
+ padding-bottom: 0.875rem;
255
+ }
256
+
257
+ .property-bar__track {
258
+ position: relative;
259
+ height: 8px;
260
+ border-radius: 999px;
261
+ background: var(--surface-sunken);
262
+ box-shadow: inset 0 0 0 1px var(--border);
263
+ }
264
+
265
+ .property-bar__fill {
266
+ position: absolute;
267
+ top: 0;
268
+ bottom: 0;
269
+ min-width: 2px;
270
+ border-radius: inherit;
271
+
272
+ /* The green-to-red ramp, mixed from the three shared status colours rather
273
+ than computed in JavaScript, which would put a hex code in a component.
274
+ `color-mix` clamps a percentage into 0–100%, so the first mix is pure amber
275
+ from the middle of the scale up and the second is pure amber down to it:
276
+ red → amber → green, with no muddy midpoint. */
277
+ --ramp-low: color-mix(
278
+ in oklab,
279
+ var(--warning) calc(var(--fitness, 1) * 200%),
280
+ var(--danger)
281
+ );
282
+
283
+ background: color-mix(
284
+ in oklab,
285
+ var(--success) calc((var(--fitness, 1) - 0.5) * 200%),
286
+ var(--ramp-low)
287
+ );
288
+ }
289
+
290
+ /* Where a diverging bar grows from. A fill that starts a quarter of the way
291
+ along says nothing without it. */
292
+ .property-bar__origin {
293
+ position: absolute;
294
+ top: -1px;
295
+ bottom: -1px;
296
+ width: 1px;
297
+ background: var(--border-strong);
298
+ }
299
+
300
+ /* The published rule of thumb: cLogP ≤ 5, logS > −4, molweight < 450,
301
+ drug-likeness > 0. */
302
+ .property-bar__mark {
303
+ position: absolute;
304
+ top: -3px;
305
+ bottom: -3px;
306
+ width: 2px;
307
+ border-radius: 1px;
308
+ background: var(--text-faint);
309
+ }
310
+
311
+ .property-bar__threshold {
312
+ position: absolute;
313
+ bottom: 0;
314
+ color: var(--text-faint);
315
+ font-size: 0.6875rem;
316
+ line-height: 1;
317
+ transform: translateX(-50%);
318
+ white-space: nowrap;
319
+ }
320
+
321
+ /* A narrow card has no width to spend on a bar: the name and the number are
322
+ what a phone reads, and the bar takes the line under them. */
323
+ @media (max-width: 480px) {
324
+ .property-row {
325
+ grid-template-columns: minmax(0, 1fr) minmax(3.5rem, auto);
326
+ }
327
+
328
+ .property-row__bar {
329
+ grid-column: 1 / -1;
330
+ grid-row: 2;
331
+ }
332
+ }
333
+
334
+ /* The panel is worth printing beside the structure. */
335
+ @media print {
336
+ .risk-findings {
337
+ break-inside: avoid;
338
+ }
339
+ }