react-cheminfo 0.7.0 → 0.9.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 (308) hide show
  1. package/README.md +60 -2
  2. package/bin/check-tokens.mjs +105 -0
  3. package/lib/about/core/about.d.ts +95 -0
  4. package/lib/about/core/about.d.ts.map +1 -0
  5. package/lib/about/core/about.js +78 -0
  6. package/lib/about/core/about.js.map +1 -0
  7. package/lib/about/core/index.d.ts +3 -0
  8. package/lib/about/core/index.d.ts.map +1 -0
  9. package/lib/about/core/index.js +2 -0
  10. package/lib/about/core/index.js.map +1 -0
  11. package/lib/about/ui/AboutCitations.d.ts +14 -0
  12. package/lib/about/ui/AboutCitations.d.ts.map +1 -0
  13. package/lib/about/ui/AboutCitations.js +40 -0
  14. package/lib/about/ui/AboutCitations.js.map +1 -0
  15. package/lib/about/ui/AboutPage.d.ts +32 -0
  16. package/lib/about/ui/AboutPage.d.ts.map +1 -0
  17. package/lib/about/ui/AboutPage.js +70 -0
  18. package/lib/about/ui/AboutPage.js.map +1 -0
  19. package/lib/about/ui/AboutSection.d.ts +23 -0
  20. package/lib/about/ui/AboutSection.d.ts.map +1 -0
  21. package/lib/about/ui/AboutSection.js +28 -0
  22. package/lib/about/ui/AboutSection.js.map +1 -0
  23. package/lib/about/ui/index.d.ts +7 -0
  24. package/lib/about/ui/index.d.ts.map +1 -0
  25. package/lib/about/ui/index.js +4 -0
  26. package/lib/about/ui/index.js.map +1 -0
  27. package/lib/chrome/ui/index.d.ts +1 -0
  28. package/lib/chrome/ui/index.d.ts.map +1 -1
  29. package/lib/chrome/ui/index.js +3 -0
  30. package/lib/chrome/ui/index.js.map +1 -1
  31. package/lib/citation/core/index.d.ts +1 -0
  32. package/lib/citation/core/index.d.ts.map +1 -1
  33. package/lib/citation/core/index.js +1 -0
  34. package/lib/citation/core/index.js.map +1 -1
  35. package/lib/citation/core/teachingPaper.d.ts +15 -0
  36. package/lib/citation/core/teachingPaper.d.ts.map +1 -0
  37. package/lib/citation/core/teachingPaper.js +32 -0
  38. package/lib/citation/core/teachingPaper.js.map +1 -0
  39. package/lib/clipboard/ui/CodeBlock.d.ts.map +1 -1
  40. package/lib/clipboard/ui/CodeBlock.js +4 -1
  41. package/lib/clipboard/ui/CodeBlock.js.map +1 -1
  42. package/lib/color/ui/ColorScaleLegend.js +1 -1
  43. package/lib/color/ui/ColorScaleLegend.js.map +1 -1
  44. package/lib/core.d.ts +3 -0
  45. package/lib/core.d.ts.map +1 -1
  46. package/lib/core.js +5 -0
  47. package/lib/core.js.map +1 -1
  48. package/lib/credits/core/credits.d.ts +36 -0
  49. package/lib/credits/core/credits.d.ts.map +1 -1
  50. package/lib/credits/core/credits.js +42 -0
  51. package/lib/credits/core/credits.js.map +1 -1
  52. package/lib/credits/ui/CreditsList.js +1 -1
  53. package/lib/credits/ui/CreditsList.js.map +1 -1
  54. package/lib/delimited/ui/DelimitedTextPanel.js +1 -1
  55. package/lib/delimited/ui/DelimitedTextPanel.js.map +1 -1
  56. package/lib/ecosystem/core/sites.d.ts +1 -1
  57. package/lib/ecosystem/core/sites.d.ts.map +1 -1
  58. package/lib/ecosystem/core/sites.js +10 -0
  59. package/lib/ecosystem/core/sites.js.map +1 -1
  60. package/lib/ecosystem/core/tokens.d.ts.map +1 -1
  61. package/lib/ecosystem/core/tokens.js +1 -0
  62. package/lib/ecosystem/core/tokens.js.map +1 -1
  63. package/lib/ecosystem/ui/EcosystemLinks.js +2 -2
  64. package/lib/ecosystem/ui/EcosystemLinks.js.map +1 -1
  65. package/lib/ecosystem/ui/EcosystemMenu.js +1 -1
  66. package/lib/ecosystem/ui/EcosystemMenu.js.map +1 -1
  67. package/lib/ecosystem/ui/SiteTile.d.ts.map +1 -1
  68. package/lib/ecosystem/ui/SiteTile.js +5 -5
  69. package/lib/ecosystem/ui/SiteTile.js.map +1 -1
  70. package/lib/ecosystem/ui/glyphs.d.ts.map +1 -1
  71. package/lib/ecosystem/ui/glyphs.js +3 -0
  72. package/lib/ecosystem/ui/glyphs.js.map +1 -1
  73. package/lib/orbital/core/index.d.ts +1 -1
  74. package/lib/orbital/core/index.d.ts.map +1 -1
  75. package/lib/orbital/core/index.js +1 -1
  76. package/lib/orbital/core/index.js.map +1 -1
  77. package/lib/orbital/core/realHarmonics.d.ts +5 -2
  78. package/lib/orbital/core/realHarmonics.d.ts.map +1 -1
  79. package/lib/orbital/core/realHarmonics.js.map +1 -1
  80. package/lib/orbital/ui/AtomicOrbitalCanvas.d.ts +18 -0
  81. package/lib/orbital/ui/AtomicOrbitalCanvas.d.ts.map +1 -1
  82. package/lib/orbital/ui/AtomicOrbitalCanvas.js +84 -7
  83. package/lib/orbital/ui/AtomicOrbitalCanvas.js.map +1 -1
  84. package/lib/orbital/ui/AtomicOrbitalViewer.d.ts +13 -0
  85. package/lib/orbital/ui/AtomicOrbitalViewer.d.ts.map +1 -1
  86. package/lib/orbital/ui/AtomicOrbitalViewer.js +1 -1
  87. package/lib/orbital/ui/AtomicOrbitalViewer.js.map +1 -1
  88. package/lib/orbital/ui/camera.d.ts +15 -0
  89. package/lib/orbital/ui/camera.d.ts.map +1 -1
  90. package/lib/orbital/ui/camera.js +68 -0
  91. package/lib/orbital/ui/camera.js.map +1 -1
  92. package/lib/orbital/ui/renderVolume.d.ts.map +1 -1
  93. package/lib/orbital/ui/renderVolume.js +8 -1
  94. package/lib/orbital/ui/renderVolume.js.map +1 -1
  95. package/lib/orbital/ui/serial.d.ts +25 -0
  96. package/lib/orbital/ui/serial.d.ts.map +1 -0
  97. package/lib/orbital/ui/serial.js +25 -0
  98. package/lib/orbital/ui/serial.js.map +1 -0
  99. package/lib/orbital/ui/viewer.d.ts +23 -0
  100. package/lib/orbital/ui/viewer.d.ts.map +1 -1
  101. package/lib/orbital/ui/viewer.js +70 -17
  102. package/lib/orbital/ui/viewer.js.map +1 -1
  103. package/lib/pedagogy/ui/ExerciseProgressHeader.js +1 -1
  104. package/lib/pedagogy/ui/ExerciseProgressHeader.js.map +1 -1
  105. package/lib/pedagogy/ui/GlossaryText.js +2 -2
  106. package/lib/pedagogy/ui/GlossaryText.js.map +1 -1
  107. package/lib/pedagogy/ui/ReferenceSectionBlock.js +5 -2
  108. package/lib/pedagogy/ui/ReferenceSectionBlock.js.map +1 -1
  109. package/lib/pedagogy/ui/SyntaxTooltip.js +2 -2
  110. package/lib/pedagogy/ui/SyntaxTooltip.js.map +1 -1
  111. package/lib/pedagogy/ui/TutorialStepStrip.d.ts +15 -2
  112. package/lib/pedagogy/ui/TutorialStepStrip.d.ts.map +1 -1
  113. package/lib/pedagogy/ui/TutorialStepStrip.js +19 -5
  114. package/lib/pedagogy/ui/TutorialStepStrip.js.map +1 -1
  115. package/lib/pedagogy/ui/index.d.ts +1 -1
  116. package/lib/pedagogy/ui/index.d.ts.map +1 -1
  117. package/lib/pedagogy/ui/index.js.map +1 -1
  118. package/lib/periodic/ui/CategoryLegend.js +1 -1
  119. package/lib/periodic/ui/CategoryLegend.js.map +1 -1
  120. package/lib/periodic/ui/PeriodicTableChrome.js +2 -2
  121. package/lib/periodic/ui/PeriodicTableChrome.js.map +1 -1
  122. package/lib/seo/vite/ogCard.d.ts.map +1 -1
  123. package/lib/seo/vite/ogCard.js +1 -0
  124. package/lib/seo/vite/ogCard.js.map +1 -1
  125. package/lib/share/ui/ShareDialogContent.d.ts.map +1 -1
  126. package/lib/share/ui/ShareDialogContent.js +5 -2
  127. package/lib/share/ui/ShareDialogContent.js.map +1 -1
  128. package/lib/share/ui/SharePartOptions.js +1 -1
  129. package/lib/share/ui/SharePartOptions.js.map +1 -1
  130. package/lib/slides/core/demoLinks.d.ts +43 -0
  131. package/lib/slides/core/demoLinks.d.ts.map +1 -0
  132. package/lib/slides/core/demoLinks.js +104 -0
  133. package/lib/slides/core/demoLinks.js.map +1 -0
  134. package/lib/slides/core/index.d.ts +13 -0
  135. package/lib/slides/core/index.d.ts.map +1 -0
  136. package/lib/slides/core/index.js +7 -0
  137. package/lib/slides/core/index.js.map +1 -0
  138. package/lib/slides/core/sectionHeading.d.ts +19 -0
  139. package/lib/slides/core/sectionHeading.d.ts.map +1 -0
  140. package/lib/slides/core/sectionHeading.js +19 -0
  141. package/lib/slides/core/sectionHeading.js.map +1 -0
  142. package/lib/slides/core/slideNavigation.d.ts +38 -0
  143. package/lib/slides/core/slideNavigation.d.ts.map +1 -0
  144. package/lib/slides/core/slideNavigation.js +65 -0
  145. package/lib/slides/core/slideNavigation.js.map +1 -0
  146. package/lib/slides/core/talk.d.ts +82 -0
  147. package/lib/slides/core/talk.d.ts.map +1 -0
  148. package/lib/slides/core/talk.js +134 -0
  149. package/lib/slides/core/talk.js.map +1 -0
  150. package/lib/slides/core/talkManifest.d.ts +90 -0
  151. package/lib/slides/core/talkManifest.d.ts.map +1 -0
  152. package/lib/slides/core/talkManifest.js +109 -0
  153. package/lib/slides/core/talkManifest.js.map +1 -0
  154. package/lib/slides/core/talkOrigin.d.ts +50 -0
  155. package/lib/slides/core/talkOrigin.d.ts.map +1 -0
  156. package/lib/slides/core/talkOrigin.js +62 -0
  157. package/lib/slides/core/talkOrigin.js.map +1 -0
  158. package/lib/slides/ui/BackToSlides.d.ts +26 -0
  159. package/lib/slides/ui/BackToSlides.d.ts.map +1 -0
  160. package/lib/slides/ui/BackToSlides.js +24 -0
  161. package/lib/slides/ui/BackToSlides.js.map +1 -0
  162. package/lib/slides/ui/DemoLink.d.ts +42 -0
  163. package/lib/slides/ui/DemoLink.d.ts.map +1 -0
  164. package/lib/slides/ui/DemoLink.js +17 -0
  165. package/lib/slides/ui/DemoLink.js.map +1 -0
  166. package/lib/slides/ui/EmbedSlide.d.ts +19 -0
  167. package/lib/slides/ui/EmbedSlide.d.ts.map +1 -0
  168. package/lib/slides/ui/EmbedSlide.js +56 -0
  169. package/lib/slides/ui/EmbedSlide.js.map +1 -0
  170. package/lib/slides/ui/SectionSlide.d.ts +18 -0
  171. package/lib/slides/ui/SectionSlide.d.ts.map +1 -0
  172. package/lib/slides/ui/SectionSlide.js +18 -0
  173. package/lib/slides/ui/SectionSlide.js.map +1 -0
  174. package/lib/slides/ui/Slide.d.ts +52 -0
  175. package/lib/slides/ui/Slide.d.ts.map +1 -0
  176. package/lib/slides/ui/Slide.js +58 -0
  177. package/lib/slides/ui/Slide.js.map +1 -0
  178. package/lib/slides/ui/SlideBody.d.ts +32 -0
  179. package/lib/slides/ui/SlideBody.d.ts.map +1 -0
  180. package/lib/slides/ui/SlideBody.js +27 -0
  181. package/lib/slides/ui/SlideBody.js.map +1 -0
  182. package/lib/slides/ui/Slideshow.d.ts +93 -0
  183. package/lib/slides/ui/Slideshow.d.ts.map +1 -0
  184. package/lib/slides/ui/Slideshow.js +122 -0
  185. package/lib/slides/ui/Slideshow.js.map +1 -0
  186. package/lib/slides/ui/SlideshowBar.d.ts +33 -0
  187. package/lib/slides/ui/SlideshowBar.d.ts.map +1 -0
  188. package/lib/slides/ui/SlideshowBar.js +20 -0
  189. package/lib/slides/ui/SlideshowBar.js.map +1 -0
  190. package/lib/slides/ui/TalkList.d.ts +37 -0
  191. package/lib/slides/ui/TalkList.d.ts.map +1 -0
  192. package/lib/slides/ui/TalkList.js +68 -0
  193. package/lib/slides/ui/TalkList.js.map +1 -0
  194. package/lib/slides/ui/index.d.ts +19 -0
  195. package/lib/slides/ui/index.d.ts.map +1 -0
  196. package/lib/slides/ui/index.js +10 -0
  197. package/lib/slides/ui/index.js.map +1 -0
  198. package/lib/slides/vite/index.d.ts +3 -0
  199. package/lib/slides/vite/index.d.ts.map +1 -0
  200. package/lib/slides/vite/index.js +2 -0
  201. package/lib/slides/vite/index.js.map +1 -0
  202. package/lib/slides/vite/talks.d.ts +50 -0
  203. package/lib/slides/vite/talks.d.ts.map +1 -0
  204. package/lib/slides/vite/talks.js +87 -0
  205. package/lib/slides/vite/talks.js.map +1 -0
  206. package/lib/slides.d.ts +3 -0
  207. package/lib/slides.d.ts.map +1 -0
  208. package/lib/slides.js +3 -0
  209. package/lib/slides.js.map +1 -0
  210. package/lib/structure/ui/StructureEditor.js +2 -2
  211. package/lib/structure/ui/StructureEditor.js.map +1 -1
  212. package/lib/structure/ui/StructurePlaceholder.js +1 -1
  213. package/lib/structure/ui/StructurePlaceholder.js.map +1 -1
  214. package/lib/tokens/core/checkTokens.d.ts +51 -0
  215. package/lib/tokens/core/checkTokens.d.ts.map +1 -0
  216. package/lib/tokens/core/checkTokens.js +188 -0
  217. package/lib/tokens/core/checkTokens.js.map +1 -0
  218. package/lib/tokens/core/colors.d.ts +42 -0
  219. package/lib/tokens/core/colors.d.ts.map +1 -0
  220. package/lib/tokens/core/colors.js +119 -0
  221. package/lib/tokens/core/colors.js.map +1 -0
  222. package/lib/tokens/core/index.d.ts +3 -0
  223. package/lib/tokens/core/index.d.ts.map +1 -0
  224. package/lib/tokens/core/index.js +2 -0
  225. package/lib/tokens/core/index.js.map +1 -0
  226. package/lib/tokens/core/rules.d.ts +23 -0
  227. package/lib/tokens/core/rules.d.ts.map +1 -0
  228. package/lib/tokens/core/rules.js +90 -0
  229. package/lib/tokens/core/rules.js.map +1 -0
  230. package/lib/ui.d.ts +1 -0
  231. package/lib/ui.d.ts.map +1 -1
  232. package/lib/ui.js +1 -0
  233. package/lib/ui.js.map +1 -1
  234. package/lib/vite.d.ts +1 -0
  235. package/lib/vite.d.ts.map +1 -1
  236. package/lib/vite.js +1 -0
  237. package/lib/vite.js.map +1 -1
  238. package/package.json +11 -3
  239. package/src/about/core/about.ts +176 -0
  240. package/src/about/core/index.ts +2 -0
  241. package/src/about/ui/AboutCitations.tsx +79 -0
  242. package/src/about/ui/AboutPage.tsx +177 -0
  243. package/src/about/ui/AboutSection.tsx +56 -0
  244. package/src/about/ui/index.ts +6 -0
  245. package/src/chrome/ui/index.ts +3 -0
  246. package/src/citation/core/index.ts +1 -0
  247. package/src/citation/core/teachingPaper.ts +36 -0
  248. package/src/clipboard/ui/CodeBlock.tsx +4 -1
  249. package/src/color/ui/ColorScaleLegend.tsx +1 -1
  250. package/src/core.ts +5 -0
  251. package/src/credits/core/credits.ts +42 -0
  252. package/src/credits/ui/CreditsList.tsx +1 -1
  253. package/src/delimited/ui/DelimitedTextPanel.tsx +1 -1
  254. package/src/ecosystem/core/sites.ts +12 -0
  255. package/src/ecosystem/core/tokens.ts +1 -0
  256. package/src/ecosystem/ui/EcosystemLinks.tsx +2 -2
  257. package/src/ecosystem/ui/EcosystemMenu.tsx +1 -1
  258. package/src/ecosystem/ui/SiteTile.tsx +7 -5
  259. package/src/ecosystem/ui/glyphs.tsx +40 -0
  260. package/src/orbital/core/index.ts +4 -1
  261. package/src/orbital/core/realHarmonics.ts +5 -2
  262. package/src/orbital/ui/AtomicOrbitalCanvas.tsx +126 -4
  263. package/src/orbital/ui/AtomicOrbitalViewer.tsx +14 -1
  264. package/src/orbital/ui/camera.ts +81 -0
  265. package/src/orbital/ui/renderVolume.ts +8 -1
  266. package/src/orbital/ui/serial.ts +35 -0
  267. package/src/orbital/ui/viewer.ts +72 -13
  268. package/src/pedagogy/ui/ExerciseProgressHeader.tsx +1 -1
  269. package/src/pedagogy/ui/GlossaryText.tsx +2 -2
  270. package/src/pedagogy/ui/ReferenceSectionBlock.tsx +5 -2
  271. package/src/pedagogy/ui/SyntaxTooltip.tsx +2 -2
  272. package/src/pedagogy/ui/TutorialStepStrip.tsx +39 -10
  273. package/src/pedagogy/ui/index.ts +4 -1
  274. package/src/periodic/ui/CategoryLegend.tsx +1 -1
  275. package/src/periodic/ui/PeriodicTableChrome.tsx +2 -2
  276. package/src/seo/vite/ogCard.ts +1 -0
  277. package/src/share/ui/ShareDialogContent.tsx +5 -2
  278. package/src/share/ui/SharePartOptions.tsx +1 -1
  279. package/src/slides/core/demoLinks.ts +113 -0
  280. package/src/slides/core/index.ts +22 -0
  281. package/src/slides/core/sectionHeading.ts +29 -0
  282. package/src/slides/core/slideNavigation.ts +77 -0
  283. package/src/slides/core/talk.ts +203 -0
  284. package/src/slides/core/talkManifest.ts +158 -0
  285. package/src/slides/core/talkOrigin.ts +83 -0
  286. package/src/slides/ui/BackToSlides.tsx +49 -0
  287. package/src/slides/ui/DemoLink.tsx +67 -0
  288. package/src/slides/ui/EmbedSlide.tsx +85 -0
  289. package/src/slides/ui/SectionSlide.tsx +44 -0
  290. package/src/slides/ui/Slide.tsx +143 -0
  291. package/src/slides/ui/SlideBody.tsx +64 -0
  292. package/src/slides/ui/Slideshow.tsx +282 -0
  293. package/src/slides/ui/SlideshowBar.tsx +83 -0
  294. package/src/slides/ui/TalkList.tsx +146 -0
  295. package/src/slides/ui/index.ts +18 -0
  296. package/src/slides/vite/index.ts +2 -0
  297. package/src/slides/vite/talks.ts +126 -0
  298. package/src/slides.ts +2 -0
  299. package/src/structure/ui/StructureEditor.tsx +2 -2
  300. package/src/structure/ui/StructurePlaceholder.tsx +1 -1
  301. package/src/tokens/core/checkTokens.ts +242 -0
  302. package/src/tokens/core/colors.ts +122 -0
  303. package/src/tokens/core/index.ts +6 -0
  304. package/src/tokens/core/rules.ts +103 -0
  305. package/src/ui.ts +1 -0
  306. package/src/vite.ts +1 -0
  307. package/styles/chrome.css +1 -0
  308. package/styles/slides.css +667 -0
@@ -0,0 +1,177 @@
1
+ import type { CSSProperties, ReactElement, ReactNode } from 'react';
2
+
3
+ import { CreditsList } from '../../credits/ui/CreditsList.tsx';
4
+ import { Wordmark } from '../../ecosystem/ui/Wordmark.tsx';
5
+ import { SiteMark } from '../../ecosystem/ui/marks.tsx';
6
+ import type { AboutContent } from '../core/about.ts';
7
+ import { resolveAbout } from '../core/about.ts';
8
+
9
+ import { AboutCitations } from './AboutCitations.tsx';
10
+ import { AboutSection } from './AboutSection.tsx';
11
+
12
+ export interface AboutPageProps {
13
+ /** What the site says about itself. */
14
+ content: AboutContent;
15
+ /**
16
+ * Class the page carries, in addition to `about-page`.
17
+ * @default undefined
18
+ */
19
+ className?: string;
20
+ /**
21
+ * The one section a site adds of its own — where its numbers come from, the
22
+ * limitation it wants named. It lands under the context paragraphs, so the
23
+ * credits, the citation and the licence keep the place a reader expects.
24
+ * @default undefined
25
+ */
26
+ children?: ReactNode;
27
+ }
28
+
29
+ /**
30
+ * The About page of a site of the family: what the tool is, what a visitor can
31
+ * do with it, what it is built on, how to cite it, and where to report a
32
+ * problem — always in that order.
33
+ *
34
+ * The order is the point. A reader who has read one of our About pages knows
35
+ * where the credits are on the other thirteen, and a site that writes its own
36
+ * page is a site that will forget one of these sections.
37
+ * @param props - See {@link AboutPageProps}.
38
+ * @returns The page.
39
+ * @throws {Error} When the record names a site or a credit that does not exist.
40
+ */
41
+ export function AboutPage(props: AboutPageProps): ReactElement {
42
+ const { content, className, children } = props;
43
+ const about = resolveAbout(content);
44
+ const site = about.site;
45
+
46
+ return (
47
+ <div
48
+ className={
49
+ className === undefined ? 'about-page' : `about-page ${className}`
50
+ }
51
+ style={PAGE_STYLE}
52
+ >
53
+ <header className="about-hero" style={HERO_STYLE}>
54
+ <SiteMark siteId={site.id} size={56} />
55
+ <div>
56
+ <h1 style={NAME_STYLE}>
57
+ <Wordmark siteId={site.id} size={26} />
58
+ </h1>
59
+ <p style={TAGLINE_STYLE}>{site.tagline}</p>
60
+ <p style={WHAT_STYLE}>{about.what}</p>
61
+ </div>
62
+ </header>
63
+
64
+ <AboutSection title="What you can do here" className="about-can">
65
+ <ul style={CAN_LIST_STYLE}>
66
+ {about.can.map((line) => (
67
+ <li key={line}>{line}</li>
68
+ ))}
69
+ </ul>
70
+ </AboutSection>
71
+
72
+ {about.paragraphs.length === 0 ? null : (
73
+ <AboutSection className="about-context">
74
+ {about.paragraphs.map((paragraph, index) => (
75
+ <p
76
+ key={paragraph}
77
+ style={index === 0 ? FIRST_PARAGRAPH_STYLE : PARAGRAPH_STYLE}
78
+ >
79
+ {paragraph}
80
+ </p>
81
+ ))}
82
+ </AboutSection>
83
+ )}
84
+
85
+ {children}
86
+
87
+ <AboutSection title="Built on" className="about-credits">
88
+ <CreditsList entries={about.credits} />
89
+ </AboutSection>
90
+
91
+ {about.cite.length === 0 ? null : (
92
+ <AboutSection title="How to cite" className="about-cite">
93
+ <AboutCitations works={about.cite} />
94
+ </AboutSection>
95
+ )}
96
+
97
+ <AboutSection title="Licence and source" className="about-licence">
98
+ <p style={FIRST_PARAGRAPH_STYLE}>
99
+ {about.license}, © cheminfo. Use it in a course, fork it, or lift a
100
+ piece of it into something else. The sources are at{' '}
101
+ <ExternalLink href={about.repository} />.
102
+ </p>
103
+ {about.version === undefined ? null : (
104
+ <p style={PARAGRAPH_STYLE}>
105
+ This page is running version {about.version}.
106
+ </p>
107
+ )}
108
+ </AboutSection>
109
+
110
+ <AboutSection title="Found a problem?" className="about-issues">
111
+ <p style={FIRST_PARAGRAPH_STYLE}>
112
+ Tell us: a report naming what you typed and what came back is the
113
+ fastest fix there is. <ExternalLink href={about.issues} />.
114
+ </p>
115
+ </AboutSection>
116
+ </div>
117
+ );
118
+ }
119
+
120
+ function ExternalLink(props: { href: string }): ReactElement {
121
+ const { href } = props;
122
+
123
+ return (
124
+ <a href={href} target="_blank" rel="noopener noreferrer" style={LINK_STYLE}>
125
+ {href.replace(/^https?:\/\//, '')}
126
+ </a>
127
+ );
128
+ }
129
+
130
+ const PAGE_STYLE = {
131
+ display: 'flex',
132
+ flexDirection: 'column',
133
+ maxWidth: 980,
134
+ // Centred, because the About is read on its own rather than beside a tool.
135
+ marginInline: 'auto',
136
+ gap: 10,
137
+ } as const satisfies CSSProperties;
138
+
139
+ const HERO_STYLE = {
140
+ display: 'flex',
141
+ alignItems: 'flex-start',
142
+ padding: 16,
143
+ border: '1px solid var(--border)',
144
+ borderRadius: 'var(--radius)',
145
+ background: 'var(--surface)',
146
+ gap: 16,
147
+ lineHeight: 1.55,
148
+ } as const satisfies CSSProperties;
149
+
150
+ const NAME_STYLE = {
151
+ margin: 0,
152
+ fontSize: 26,
153
+ fontWeight: 700,
154
+ } as const satisfies CSSProperties;
155
+
156
+ const TAGLINE_STYLE = {
157
+ margin: '2px 0 8px',
158
+ color: 'var(--text-muted)',
159
+ fontSize: 14,
160
+ } as const satisfies CSSProperties;
161
+
162
+ const WHAT_STYLE = { margin: 0 } as const satisfies CSSProperties;
163
+
164
+ const CAN_LIST_STYLE = {
165
+ margin: 0,
166
+ paddingLeft: 20,
167
+ } as const satisfies CSSProperties;
168
+
169
+ const FIRST_PARAGRAPH_STYLE = {
170
+ margin: 0,
171
+ } as const satisfies CSSProperties;
172
+
173
+ const PARAGRAPH_STYLE = {
174
+ margin: '8px 0 0',
175
+ } as const satisfies CSSProperties;
176
+
177
+ const LINK_STYLE = { color: 'var(--accent)' } as const satisfies CSSProperties;
@@ -0,0 +1,56 @@
1
+ import type { CSSProperties, ReactElement, ReactNode } from 'react';
2
+
3
+ export interface AboutSectionProps {
4
+ /**
5
+ * What the section is called, written as its heading.
6
+ * @default undefined — the section carries no heading
7
+ */
8
+ title?: string;
9
+ /**
10
+ * Class the section carries, in addition to `about-section`.
11
+ * @default undefined
12
+ */
13
+ className?: string;
14
+ /** What the section holds. */
15
+ children: ReactNode;
16
+ }
17
+
18
+ /**
19
+ * One block of the About page: a heading and what sits under it, on the
20
+ * family's own surface rather than on a component library's card.
21
+ * @param props - See {@link AboutSectionProps}.
22
+ * @returns The section.
23
+ */
24
+ export function AboutSection(props: AboutSectionProps): ReactElement {
25
+ const { title, className, children } = props;
26
+
27
+ return (
28
+ <section
29
+ className={
30
+ className === undefined ? 'about-section' : `about-section ${className}`
31
+ }
32
+ style={SECTION_STYLE}
33
+ >
34
+ {title === undefined ? null : <h2 style={TITLE_STYLE}>{title}</h2>}
35
+ {children}
36
+ </section>
37
+ );
38
+ }
39
+
40
+ const SECTION_STYLE = {
41
+ padding: 16,
42
+ border: '1px solid var(--border)',
43
+ borderRadius: 'var(--radius)',
44
+ background: 'var(--surface)',
45
+ // An About page is printed as often as it is read, and a section split over
46
+ // two pages loses the heading that says what its list is.
47
+ breakInside: 'avoid',
48
+ lineHeight: 1.55,
49
+ } as const satisfies CSSProperties;
50
+
51
+ const TITLE_STYLE = {
52
+ margin: '0 0 8px',
53
+ color: 'var(--accent)',
54
+ fontSize: 16,
55
+ fontWeight: 600,
56
+ } as const satisfies CSSProperties;
@@ -0,0 +1,6 @@
1
+ export type { AboutCitationsProps } from './AboutCitations.tsx';
2
+ export { AboutCitations } from './AboutCitations.tsx';
3
+ export type { AboutPageProps } from './AboutPage.tsx';
4
+ export { AboutPage } from './AboutPage.tsx';
5
+ export type { AboutSectionProps } from './AboutSection.tsx';
6
+ export { AboutSection } from './AboutSection.tsx';
@@ -1,4 +1,7 @@
1
1
  export type { NavItem } from './navItem.ts';
2
+ // A site drawing its own link needs the same reading of a click the shared nav
3
+ // items use: a middle click or a modified one belongs to the browser.
4
+ export { isModifiedClick } from './navItem.ts';
2
5
  export type { NavLinkProps } from './NavLink.tsx';
3
6
  export { NavLink } from './NavLink.tsx';
4
7
  export type { NavMenuButtonProps } from './NavMenuButton.tsx';
@@ -21,6 +21,7 @@ export type {
21
21
  CitationStyleId,
22
22
  } from './segments.ts';
23
23
  export { CITATION_STYLES, citationSegments } from './segments.ts';
24
+ export { TEACHING_PAPER, TEACHING_WORK } from './teachingPaper.ts';
24
25
  export type { CitedWork } from './works.ts';
25
26
  export {
26
27
  citationsFilename,
@@ -0,0 +1,36 @@
1
+ import type { Reference } from './reference.ts';
2
+ import type { CitedWork } from './works.ts';
3
+
4
+ /**
5
+ * The twenty years of online teaching the pedagogic sites of the family come
6
+ * out of: the tutorials, the exercises and the marking are the web-based tools
7
+ * it describes. One record holds it, so no site can name a different version
8
+ * of it.
9
+ */
10
+ export const TEACHING_PAPER: Reference = {
11
+ authors: [
12
+ { given: 'R.', family: 'Turin' },
13
+ { given: 'L.', family: 'Patiny' },
14
+ ],
15
+ title:
16
+ 'Two Decades of Online Teaching: Trends, Challenges, and Future Directions',
17
+ journal: 'CHIMIA',
18
+ journalAbbreviation: 'Chimia',
19
+ year: 2023,
20
+ volume: '77',
21
+ issue: '10',
22
+ firstPage: '683',
23
+ lastPage: '687',
24
+ doi: '10.2533/chimia.2023.683',
25
+ publisher: 'Swiss Chemical Society',
26
+ };
27
+
28
+ /**
29
+ * The teaching paper as one of the works a site that teaches asks to be cited,
30
+ * beside `PLATFORM_WORK` and the work the tool itself implements.
31
+ */
32
+ export const TEACHING_WORK: CitedWork = {
33
+ reference: TEACHING_PAPER,
34
+ what: 'Teaching chemistry online',
35
+ note: 'Cite it for the exercises, which are the web-based teaching it describes.',
36
+ };
@@ -19,7 +19,10 @@ const BASE_PRE_STYLE: CSSProperties = {
19
19
 
20
20
  const TONE_STYLE: Record<CodeBlockTone, CSSProperties> = {
21
21
  default: {},
22
- muted: { background: '#f6f7f9', border: '1px solid #d3d8de' },
22
+ muted: {
23
+ background: 'var(--surface-sunken, #f6f7f9)',
24
+ border: '1px solid var(--border, #d3d8de)',
25
+ },
23
26
  dark: {
24
27
  background: '#1e293b',
25
28
  border: '1px solid #1e293b',
@@ -127,7 +127,7 @@ const ROW_STYLE = {
127
127
  } as const satisfies CSSProperties;
128
128
 
129
129
  const LABEL_STYLE = {
130
- color: 'rgb(95 107 124)',
130
+ color: 'var(--text-muted, rgb(95 107 124))',
131
131
  fontSize: 12,
132
132
  } as const satisfies CSSProperties;
133
133
 
package/src/core.ts CHANGED
@@ -1,3 +1,4 @@
1
+ export * from './about/core/index.ts';
1
2
  export * from './citation/core/index.ts';
2
3
  export * from './clipboard/core/index.ts';
3
4
  export * from './color/core/index.ts';
@@ -12,4 +13,8 @@ export * from './periodic/core/index.ts';
12
13
  export * from './router/core/index.ts';
13
14
  export * from './seo/core/index.ts';
14
15
  export * from './share/core/index.ts';
16
+ // The deck format and its navigation are framework-free, so a backend can read
17
+ // a manifest without loading React: `react-cheminfo/slides` is the player.
18
+ export * from './slides/core/index.ts';
19
+ export * from './tokens/core/index.ts';
15
20
  export * from './worker/core/index.ts';
@@ -166,6 +166,48 @@ export const CREDITS = [
166
166
  description: 'typesets the mathematics, from LaTeX to what you read.',
167
167
  license: 'Apache-2.0',
168
168
  },
169
+ {
170
+ id: 'lexical',
171
+ name: 'Lexical',
172
+ href: 'https://lexical.dev/',
173
+ description: 'the editor a written page is composed and stored in.',
174
+ license: 'MIT',
175
+ },
176
+ {
177
+ id: 'katex',
178
+ name: 'KaTeX',
179
+ href: 'https://katex.org/',
180
+ description: 'typesets the mathematics inside a written page.',
181
+ license: 'MIT',
182
+ },
183
+ {
184
+ id: 'dnd-kit',
185
+ name: 'dnd kit',
186
+ href: 'https://dndkit.com/',
187
+ description: 'the dragging that arranges things into an order.',
188
+ license: 'MIT',
189
+ },
190
+ {
191
+ id: 'preact-signals',
192
+ name: 'Preact Signals',
193
+ href: 'https://preactjs.com/guide/v10/signals/',
194
+ description: 'the state the pages read, without a store around it.',
195
+ license: 'MIT',
196
+ },
197
+ {
198
+ id: 'fastify',
199
+ name: 'Fastify',
200
+ href: 'https://fastify.dev/',
201
+ description: 'the server that answers the API and serves the page.',
202
+ license: 'MIT',
203
+ },
204
+ {
205
+ id: 'sqlite',
206
+ name: 'SQLite',
207
+ href: 'https://sqlite.org/',
208
+ description: 'the database, one file, read through the Node built-in.',
209
+ license: 'Public domain',
210
+ },
169
211
  {
170
212
  id: 'react',
171
213
  name: 'React',
@@ -76,7 +76,7 @@ const ITEM_STYLE = {
76
76
  const NAME_STYLE = { fontWeight: 600 } as const satisfies CSSProperties;
77
77
 
78
78
  const LICENSE_STYLE = {
79
- color: '#5f6b7c',
79
+ color: 'var(--text-muted, #5f6b7c)',
80
80
  fontSize: 11,
81
81
  margin: '0 6px',
82
82
  } as const satisfies CSSProperties;
@@ -143,7 +143,7 @@ const CONTROLS_STYLE = {
143
143
  } as const satisfies CSSProperties;
144
144
 
145
145
  const LABEL_STYLE = {
146
- color: '#5f6b7c',
146
+ color: 'var(--text-muted, #5f6b7c)',
147
147
  fontSize: 12,
148
148
  } as const satisfies CSSProperties;
149
149
 
@@ -1,5 +1,7 @@
1
+ // tokens-ok: file — every site's two colours are declared here.
1
2
  /** The sites the menu links to, in the order they are listed. */
2
3
  export type SiteId =
4
+ | 'learn'
3
5
  | 'inchi'
4
6
  | 'vcl'
5
7
  | 'smiles'
@@ -70,6 +72,16 @@ export interface SiteMarkColors {
70
72
  * go with them live in `marks.tsx`.
71
73
  */
72
74
  export const ECOSYSTEM_SITES: readonly EcosystemSite[] = [
75
+ {
76
+ id: 'learn',
77
+ name: { lead: 'learn', alt: 'cheminfo', dot: true },
78
+ host: 'learn.cheminfo.org',
79
+ repository: 'https://github.com/cheminfo/learn.cheminfo.org',
80
+ tagline: 'Arrange the tools into a course and hand out its link.',
81
+ brand: '#0d9488',
82
+ brandAlt: '#b45309',
83
+ mark: { plate: '#0d9488', accent: '#f59e0b' },
84
+ },
73
85
  {
74
86
  id: 'inchi',
75
87
  name: { lead: 'inchi', alt: 'cheminfo', dot: true },
@@ -1,3 +1,4 @@
1
+ // tokens-ok: file — the block a site renders is written here.
1
2
  import { siteById } from './lookup.ts';
2
3
  import type { EcosystemSite, SiteId } from './sites.ts';
3
4
 
@@ -17,7 +17,7 @@ const SECTION_STYLE: CSSProperties = {
17
17
  };
18
18
  const HEADING_STYLE: CSSProperties = {
19
19
  margin: 0,
20
- color: '#5b6875',
20
+ color: 'var(--text-muted, #5b6875)',
21
21
  fontSize: '0.75rem',
22
22
  fontWeight: 600,
23
23
  };
@@ -40,7 +40,7 @@ const LINK_STYLE: CSSProperties = {
40
40
  };
41
41
  const CURRENT_STYLE: CSSProperties = {
42
42
  ...LINK_STYLE,
43
- color: '#8a96a3',
43
+ color: 'var(--text-faint, #8a96a3)',
44
44
  cursor: 'default',
45
45
  };
46
46
 
@@ -14,7 +14,7 @@ const PANEL_STYLE: CSSProperties = {
14
14
  gap: 8,
15
15
  };
16
16
  const HEADING_STYLE: CSSProperties = {
17
- color: '#5b6875',
17
+ color: 'var(--text-muted, #5b6875)',
18
18
  fontSize: '0.75rem',
19
19
  fontWeight: 600,
20
20
  };
@@ -11,7 +11,7 @@ const TILE_STYLE: CSSProperties = {
11
11
  padding: '7px 8px',
12
12
  border: '1px solid transparent',
13
13
  borderRadius: 10,
14
- color: '#16202c',
14
+ color: 'var(--text, #16202c)',
15
15
  gap: 10,
16
16
  textDecoration: 'none',
17
17
  transition: 'background 120ms, border-color 120ms, transform 120ms',
@@ -37,7 +37,7 @@ const HERE_STYLE: CSSProperties = {
37
37
  textTransform: 'uppercase',
38
38
  };
39
39
  const TAGLINE_STYLE: CSSProperties = {
40
- color: '#5b6875',
40
+ color: 'var(--text-muted, #5b6875)',
41
41
  fontSize: '0.75rem',
42
42
  lineHeight: 1.35,
43
43
  };
@@ -91,7 +91,9 @@ export function SiteTile(props: SiteTileProps): ReactElement {
91
91
  <div style={NAME_STYLE}>
92
92
  <span>
93
93
  <span style={{ color: site.brand }}>{site.name.lead}</span>
94
- {site.name.dot ? <span style={{ color: '#8a96a3' }}>.</span> : null}
94
+ {site.name.dot ? (
95
+ <span style={{ color: 'var(--text-faint, #8a96a3)' }}>.</span>
96
+ ) : null}
95
97
  <span style={{ color: site.brandAlt }}>{site.name.alt}</span>
96
98
  </span>
97
99
  {isCurrent ? (
@@ -134,7 +136,7 @@ export function SiteTile(props: SiteTileProps): ReactElement {
134
136
  // A tile lights up in the colour of the site it opens, never in ours: the
135
137
  // pointer moving down the grid is what makes the pairs of colours read.
136
138
  function tint(site: EcosystemSite, isCurrent: boolean, lit: boolean): string {
137
- if (isCurrent) return '#f5f7fa';
139
+ if (isCurrent) return 'var(--surface-sunken, #f5f7fa)';
138
140
  return lit ? `color-mix(in oklab, ${site.brand} 9%, white)` : 'transparent';
139
141
  }
140
142
 
@@ -143,6 +145,6 @@ function borderOf(
143
145
  isCurrent: boolean,
144
146
  lit: boolean,
145
147
  ): string {
146
- if (isCurrent) return '#dfe3e8';
148
+ if (isCurrent) return 'var(--border, #dfe3e8)';
147
149
  return lit ? `color-mix(in oklab, ${site.brand} 32%, white)` : 'transparent';
148
150
  }
@@ -16,6 +16,46 @@ import type { SiteId } from '../core/sites.ts';
16
16
 
17
17
  /** Every mark, keyed by site, drawn on top of its plate. */
18
18
  export const GLYPHS: Record<SiteId, (alt: string) => ReactNode> = {
19
+ // Six tiles standing where the six atoms of a benzene ring stand: the
20
+ // arrangement of tiles is the product and the ring is the subject.
21
+ learn: (alt) => (
22
+ <g>
23
+ <rect x="12.85" y="4.15" width="6.3" height="6.3" rx="1.9" fill={alt} />
24
+ <rect
25
+ x="20.39"
26
+ y="8.5"
27
+ width="6.3"
28
+ height="6.3"
29
+ rx="1.9"
30
+ fill="#ffffff"
31
+ />
32
+ <rect
33
+ x="20.39"
34
+ y="17.2"
35
+ width="6.3"
36
+ height="6.3"
37
+ rx="1.9"
38
+ fill="#ffffff"
39
+ />
40
+ <rect
41
+ x="12.85"
42
+ y="21.55"
43
+ width="6.3"
44
+ height="6.3"
45
+ rx="1.9"
46
+ fill="#ffffff"
47
+ />
48
+ <rect
49
+ x="5.31"
50
+ y="17.2"
51
+ width="6.3"
52
+ height="6.3"
53
+ rx="1.9"
54
+ fill="#ffffff"
55
+ />
56
+ <rect x="5.31" y="8.5" width="6.3" height="6.3" rx="1.9" fill="#ffffff" />
57
+ </g>
58
+ ),
19
59
  // A hexagon with a tail: the structure, and the string it hashes into.
20
60
  inchi: (alt) => (
21
61
  <g
@@ -1,5 +1,8 @@
1
1
  export type { ResolutionLimits } from './atomicGrid.ts';
2
- export { atomicGridResolution } from './atomicGrid.ts';
2
+ export {
3
+ atomicGridResolution,
4
+ createAtomicOrbitalEvaluator,
5
+ } from './atomicGrid.ts';
3
6
  export type { AtomicOrbital, AtomicOrbitalOptions } from './atomicOrbitals.ts';
4
7
  export {
5
8
  atomicOrbitalsOf,
@@ -32,8 +32,11 @@ export interface RealHarmonic {
32
32
  * @param y - Offset from the nucleus along y, ångström.
33
33
  * @param z - Offset from the nucleus along z, ångström.
34
34
  * @param radius - Length of `(x, y, z)`, passed in because the caller has
35
- * already computed it for the radial part.
36
- * @returns The dimensionless amplitude; 0 at the nucleus for ℓ > 0.
35
+ * already computed it for the radial part. Never 0: a harmonic names a
36
+ * direction and the nucleus has none, so every ℓ > 0 divides by it. Build
37
+ * `ψ` with `createAtomicOrbitalEvaluator`, which answers that one point
38
+ * itself rather than paying for a branch on every sample.
39
+ * @returns The dimensionless amplitude.
37
40
  */
38
41
  evaluate: (x: number, y: number, z: number, radius: number) => number;
39
42
  }