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,52 @@
1
+ import type { ComponentType, ReactElement } from 'react';
2
+ import type { Slide as SlideData, TalkMeta } from '../core/index.ts';
3
+ import type { RenderSlideLink } from './DemoLink.tsx';
4
+ /** What every layout — the generic ones and a site's own — is handed. */
5
+ export interface SlideLayoutProps {
6
+ /** The slide to draw. */
7
+ slide: SlideData;
8
+ /** How the publishing site names the talk in its addresses. */
9
+ talkId: string;
10
+ /** Which slide of the talk this is, zero-based. */
11
+ slideIndex: number;
12
+ /**
13
+ * Which site published the deck, written into the way back.
14
+ * @default undefined — the site playing it
15
+ */
16
+ site?: string;
17
+ /**
18
+ * Where the publishing site lives, which a relative address in the deck is
19
+ * resolved against.
20
+ * @default undefined — the addresses are this site's own
21
+ */
22
+ talkOrigin?: string;
23
+ /** What the talk's front-matter said, for a layout that draws from it. */
24
+ meta: TalkMeta;
25
+ /**
26
+ * The site's own link, used for the in-app links of the slide.
27
+ * @default undefined — a plain anchor
28
+ */
29
+ renderLink?: RenderSlideLink;
30
+ }
31
+ /** A slide, and the layouts available to draw it. */
32
+ export interface SlideViewProps extends SlideLayoutProps {
33
+ /**
34
+ * The layouts this site adds, by the name a slide writes in its
35
+ * `<!-- layout: … -->` marker. An entry here also replaces a generic layout
36
+ * of the same name.
37
+ * @default undefined
38
+ */
39
+ layouts?: Record<string, ComponentType<SlideLayoutProps>>;
40
+ }
41
+ /**
42
+ * Draw one slide with the layout it asks for.
43
+ *
44
+ * The layout name is not a closed list — a deck is written before the site
45
+ * knows how to draw it — so a name neither the site nor the player recognises
46
+ * falls back to the plain content layout. A talk must never fail to open
47
+ * because one of its slides asks for something that is not there yet.
48
+ * @param props - See {@link SlideViewProps}.
49
+ * @returns The slide.
50
+ */
51
+ export declare function SlideView(props: SlideViewProps): ReactElement;
52
+ //# sourceMappingURL=Slide.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Slide.d.ts","sourceRoot":"","sources":["../../../src/slides/ui/Slide.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,YAAY,EAAE,MAAM,OAAO,CAAC;AAGzD,OAAO,KAAK,EACV,KAAK,IAAI,SAAS,EAClB,QAAQ,EAET,MAAM,kBAAkB,CAAC;AAG1B,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,gBAAgB,CAAC;AAMtD,yEAAyE;AACzE,MAAM,WAAW,gBAAgB;IAC/B,yBAAyB;IACzB,KAAK,EAAE,SAAS,CAAC;IACjB,+DAA+D;IAC/D,MAAM,EAAE,MAAM,CAAC;IACf,mDAAmD;IACnD,UAAU,EAAE,MAAM,CAAC;IACnB;;;OAGG;IACH,IAAI,CAAC,EAAE,MAAM,CAAC;IACd;;;;OAIG;IACH,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,0EAA0E;IAC1E,IAAI,EAAE,QAAQ,CAAC;IACf;;;OAGG;IACH,UAAU,CAAC,EAAE,eAAe,CAAC;CAC9B;AAED,qDAAqD;AACrD,MAAM,WAAW,cAAe,SAAQ,gBAAgB;IACtD;;;;;OAKG;IACH,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,aAAa,CAAC,gBAAgB,CAAC,CAAC,CAAC;CAC3D;AAED;;;;;;;;;GASG;AACH,wBAAgB,SAAS,CAAC,KAAK,EAAE,cAAc,GAAG,YAAY,CAU7D"}
@@ -0,0 +1,58 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { Fragment } from 'react';
3
+ import { demoLabel, splitDemoLinks } from "../core/index.js";
4
+ import { DemoLink } from "./DemoLink.js";
5
+ import { EmbedSlide } from "./EmbedSlide.js";
6
+ import { SectionSlide } from "./SectionSlide.js";
7
+ import { SlideBody } from "./SlideBody.js";
8
+ /**
9
+ * Draw one slide with the layout it asks for.
10
+ *
11
+ * The layout name is not a closed list — a deck is written before the site
12
+ * knows how to draw it — so a name neither the site nor the player recognises
13
+ * falls back to the plain content layout. A talk must never fail to open
14
+ * because one of its slides asks for something that is not there yet.
15
+ * @param props - See {@link SlideViewProps}.
16
+ * @returns The slide.
17
+ */
18
+ export function SlideView(props) {
19
+ const { layouts, ...layoutProps } = props;
20
+ const { slide } = layoutProps;
21
+ const Custom = layouts?.[slide.layout];
22
+ if (Custom !== undefined)
23
+ return _jsx(Custom, { ...layoutProps });
24
+ if (slide.layout === 'section')
25
+ return _jsx(SectionSlide, { body: slide.body });
26
+ if (slide.layout === 'embed')
27
+ return _jsx(EmbedSlide, { slide: slide });
28
+ return _jsx(GenericSlide, { ...layoutProps });
29
+ }
30
+ /** The layouts the player draws itself, for any deck on any site. */
31
+ const GENERIC_LAYOUTS = new Set(['content', 'title', 'quote', 'thanks']);
32
+ function GenericSlide(props) {
33
+ const { slide, talkId, slideIndex, meta, renderLink, site, talkOrigin } = props;
34
+ const layout = GENERIC_LAYOUTS.has(slide.layout) ? slide.layout : 'content';
35
+ const { body, demos } = splitDemoLinks(slide.body);
36
+ const origin = site === undefined
37
+ ? { talkId, slide: slideIndex }
38
+ : { talkId, slide: slideIndex, site };
39
+ const logos = layout === 'title' ? (meta.logos ?? []) : [];
40
+ return (_jsx("div", { className: `slide slide--${layout}`, children: _jsxs("div", { className: "slide-content", children: [_jsx(SlideBody, { body: body, origin: origin, renderLink: renderLink }), logos.length === 0 ? null : (_jsx("div", { className: "slide-logos", children: logos.map((logo) => (_jsx("img", { className: "slide-logo", src: logo, alt: "" }, logo))) })), demos.length === 0 ? null : (_jsxs("div", { className: "slide-demos", children: [_jsx("span", { className: "slide-demos-label", children: "Live demos:" }), demos.map((demo, index) => (_jsxs(Fragment, { children: [index === 0 ? null : (_jsx("span", { className: "slide-demos-separator", "aria-hidden": "true", children: "|" })), _jsx(DemoLink, { href: resolveDemoHref(demo.href, talkOrigin), origin: origin, renderLink: renderLink, children: demoLabel(demo.label) })] }, demo.href)))] }))] }) }));
41
+ }
42
+ /**
43
+ * Where a demo link actually points.
44
+ *
45
+ * A deck writes `/mf-finder?mass=300`, meaning its own site. Played there it is
46
+ * exactly that; played on another site of the family it has to be resolved
47
+ * against the site that wrote it, or the link lands on a page that does not
48
+ * exist.
49
+ * @param href - The address the slide wrote.
50
+ * @param talkOrigin - Where the publishing site lives, when it is not this one.
51
+ * @returns The address to open.
52
+ */
53
+ function resolveDemoHref(href, talkOrigin) {
54
+ if (talkOrigin === undefined || !href.startsWith('/'))
55
+ return href;
56
+ return `${talkOrigin.replace(/\/$/, '')}${href}`;
57
+ }
58
+ //# sourceMappingURL=Slide.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Slide.js","sourceRoot":"","sources":["../../../src/slides/ui/Slide.tsx"],"names":[],"mappings":"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"}
@@ -0,0 +1,32 @@
1
+ import type { ReactElement } from 'react';
2
+ import type { TalkOrigin } from '../core/index.ts';
3
+ import type { RenderSlideLink } from './DemoLink.tsx';
4
+ /** The Markdown of a slide, and where its links go. */
5
+ export interface SlideBodyProps {
6
+ /** The Markdown source of the slide, or of one part of it. */
7
+ body: string;
8
+ /**
9
+ * Which slide the body belongs to, carried by every in-app link it holds so
10
+ * the tool a demo opens can offer the way back.
11
+ * @default undefined
12
+ */
13
+ origin?: TalkOrigin;
14
+ /**
15
+ * The site's own link, used for the in-app links of the body.
16
+ * @default undefined — a plain anchor
17
+ */
18
+ renderLink?: RenderSlideLink;
19
+ }
20
+ /**
21
+ * Render a slide's Markdown.
22
+ *
23
+ * A talk is written as prose, so raw HTML in the source is kept: a slide
24
+ * routinely holds a `<sub>`, a `<br>` or a figure the Markdown syntax cannot
25
+ * express. A link to an in-app route becomes a demo link; every other link
26
+ * leaves the deck in a tab of its own, so a click during a talk never loses the
27
+ * slide it was made from.
28
+ * @param props - See {@link SlideBodyProps}.
29
+ * @returns The rendered body.
30
+ */
31
+ export declare function SlideBody(props: SlideBodyProps): ReactElement;
32
+ //# sourceMappingURL=SlideBody.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"SlideBody.d.ts","sourceRoot":"","sources":["../../../src/slides/ui/SlideBody.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,OAAO,CAAC;AAI1C,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AAEnD,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,gBAAgB,CAAC;AAGtD,uDAAuD;AACvD,MAAM,WAAW,cAAc;IAC7B,8DAA8D;IAC9D,IAAI,EAAE,MAAM,CAAC;IACb;;;;OAIG;IACH,MAAM,CAAC,EAAE,UAAU,CAAC;IACpB;;;OAGG;IACH,UAAU,CAAC,EAAE,eAAe,CAAC;CAC9B;AAED;;;;;;;;;;GAUG;AACH,wBAAgB,SAAS,CAAC,KAAK,EAAE,cAAc,GAAG,YAAY,CA0B7D"}
@@ -0,0 +1,27 @@
1
+ import { jsx as _jsx } from "react/jsx-runtime";
2
+ import Markdown from 'react-markdown';
3
+ import rehypeRaw from 'rehype-raw';
4
+ import { DemoLink } from "./DemoLink.js";
5
+ /**
6
+ * Render a slide's Markdown.
7
+ *
8
+ * A talk is written as prose, so raw HTML in the source is kept: a slide
9
+ * routinely holds a `<sub>`, a `<br>` or a figure the Markdown syntax cannot
10
+ * express. A link to an in-app route becomes a demo link; every other link
11
+ * leaves the deck in a tab of its own, so a click during a talk never loses the
12
+ * slide it was made from.
13
+ * @param props - See {@link SlideBodyProps}.
14
+ * @returns The rendered body.
15
+ */
16
+ export function SlideBody(props) {
17
+ const { body, origin, renderLink } = props;
18
+ return (_jsx(Markdown, { rehypePlugins: [rehypeRaw], components: {
19
+ a({ href, children }) {
20
+ if (href?.startsWith('/') === true) {
21
+ return (_jsx(DemoLink, { href: href, origin: origin, renderLink: renderLink, children: children }));
22
+ }
23
+ return (_jsx("a", { href: href, target: "_blank", rel: "noreferrer", children: children }));
24
+ },
25
+ }, children: body }));
26
+ }
27
+ //# sourceMappingURL=SlideBody.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"SlideBody.js","sourceRoot":"","sources":["../../../src/slides/ui/SlideBody.tsx"],"names":[],"mappings":";AACA,OAAO,QAAQ,MAAM,gBAAgB,CAAC;AACtC,OAAO,SAAS,MAAM,YAAY,CAAC;AAKnC,OAAO,EAAE,QAAQ,EAAE,MAAM,eAAgB,CAAC;AAmB1C;;;;;;;;;;GAUG;AACH,MAAM,UAAU,SAAS,CAAC,KAAqB;IAC7C,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,UAAU,EAAE,GAAG,KAAK,CAAC;IAE3C,OAAO,CACL,KAAC,QAAQ,IACP,aAAa,EAAE,CAAC,SAAS,CAAC,EAC1B,UAAU,EAAE;YACV,CAAC,CAAC,EAAE,IAAI,EAAE,QAAQ,EAAE;gBAClB,IAAI,IAAI,EAAE,UAAU,CAAC,GAAG,CAAC,KAAK,IAAI,EAAE,CAAC;oBACnC,OAAO,CACL,KAAC,QAAQ,IAAC,IAAI,EAAE,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,UAAU,EAAE,UAAU,YACzD,QAAQ,GACA,CACZ,CAAC;gBACJ,CAAC;gBACD,OAAO,CACL,YAAG,IAAI,EAAE,IAAI,EAAE,MAAM,EAAC,QAAQ,EAAC,GAAG,EAAC,YAAY,YAC5C,QAAQ,GACP,CACL,CAAC;YACJ,CAAC;SACF,YAEA,IAAI,GACI,CACZ,CAAC;AACJ,CAAC"}
@@ -0,0 +1,93 @@
1
+ import type { ComponentType, ReactElement } from 'react';
2
+ import type { Talk } from '../core/index.ts';
3
+ import type { RenderSlideLink } from './DemoLink.tsx';
4
+ import type { SlideLayoutProps } from './Slide.tsx';
5
+ /** The talk being presented, and everything the site keeps a hand on. */
6
+ export interface SlideshowProps {
7
+ /** The parsed talk. */
8
+ talk: Talk;
9
+ /** Which slide is showing, zero-based; clamped into the talk before drawing. */
10
+ index: number;
11
+ /** Called with the slide to show; the site writes it wherever it keeps it. */
12
+ onIndex: (index: number) => void;
13
+ /**
14
+ * Called when the presenter leaves the talk. The bar carries no Exit button
15
+ * when it is left out.
16
+ * @default undefined
17
+ */
18
+ onExit?: () => void;
19
+ /**
20
+ * The layouts this site adds, by the name a slide writes in its
21
+ * `<!-- layout: … -->` marker.
22
+ * @default undefined
23
+ */
24
+ layouts?: Record<string, ComponentType<SlideLayoutProps>>;
25
+ /**
26
+ * The site's own link, used for the in-app links the slides hold.
27
+ * @default undefined — a plain anchor
28
+ */
29
+ renderLink?: RenderSlideLink;
30
+ /**
31
+ * How the publishing site names this talk in its addresses, carried by every
32
+ * demo link so the tool it opens can offer the way back.
33
+ * @default '' — the demo links carry no talk
34
+ */
35
+ talkId?: string;
36
+ /**
37
+ * Which site published the deck. A deck played somewhere else — as
38
+ * learn.cheminfo.org plays the family's — says so in the way back, so the
39
+ * link returns to the player it came from rather than to this one.
40
+ * @default undefined — the deck belongs to the site playing it
41
+ */
42
+ site?: string;
43
+ /**
44
+ * Where the publishing site lives, e.g. `https://www.chemcalc.org`. A deck
45
+ * written for one site holds addresses relative to it, so playing it
46
+ * elsewhere has to resolve them against their own origin rather than against
47
+ * the page.
48
+ * @default undefined — the addresses are this site's own
49
+ */
50
+ talkOrigin?: string;
51
+ /**
52
+ * What the bar reads.
53
+ * @default the talk's own title
54
+ */
55
+ title?: string;
56
+ /**
57
+ * Class the player carries, in addition to `slideshow`.
58
+ * @default undefined
59
+ */
60
+ className?: string;
61
+ /**
62
+ * Fullscreen owned by the site rather than by the player.
63
+ *
64
+ * A deck that links into the live tool wants the whole app fullscreen, not
65
+ * the player: the player unmounts on the way to the demo, and the browser
66
+ * would leave fullscreen with it. A site in that shape passes what it
67
+ * fullscreens and how to toggle it, and the player's key and button drive
68
+ * that instead of their own element.
69
+ * @default undefined — the player fullscreens itself
70
+ */
71
+ fullscreen?: {
72
+ /** Whether the site is presenting. */
73
+ isFullscreen: boolean;
74
+ /** Called when `f` or the bar's button asks to change that. */
75
+ onToggle: () => void;
76
+ };
77
+ }
78
+ /**
79
+ * The conference player: one talk, one slide at a time, on a canvas scaled to
80
+ * fill whatever screen it is given.
81
+ *
82
+ * The index is controlled, because the site owns the address — the slide lives
83
+ * in a query parameter so a demo link can return to the exact one — and the
84
+ * player therefore never touches history itself.
85
+ *
86
+ * Arrow keys, space and PageUp/PageDown navigate, `Home` and `End` jump to the
87
+ * ends, `f` toggles fullscreen, `b` and `w` blank the screen to black and to
88
+ * white the way a projector remote does, and `n` shows the presenter's notes.
89
+ * @param props - See {@link SlideshowProps}.
90
+ * @returns The player.
91
+ */
92
+ export declare function Slideshow(props: SlideshowProps): ReactElement;
93
+ //# sourceMappingURL=Slideshow.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Slideshow.d.ts","sourceRoot":"","sources":["../../../src/slides/ui/Slideshow.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAEV,aAAa,EAEb,YAAY,EACb,MAAM,OAAO,CAAC;AAIf,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,kBAAkB,CAAC;AAG7C,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,gBAAgB,CAAC;AACtD,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,aAAa,CAAC;AAIpD,yEAAyE;AACzE,MAAM,WAAW,cAAc;IAC7B,uBAAuB;IACvB,IAAI,EAAE,IAAI,CAAC;IACX,gFAAgF;IAChF,KAAK,EAAE,MAAM,CAAC;IACd,8EAA8E;IAC9E,OAAO,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAC;IACjC;;;;OAIG;IACH,MAAM,CAAC,EAAE,MAAM,IAAI,CAAC;IACpB;;;;OAIG;IACH,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,aAAa,CAAC,gBAAgB,CAAC,CAAC,CAAC;IAC1D;;;OAGG;IACH,UAAU,CAAC,EAAE,eAAe,CAAC;IAC7B;;;;OAIG;IACH,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB;;;;;OAKG;IACH,IAAI,CAAC,EAAE,MAAM,CAAC;IACd;;;;;;OAMG;IACH,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB;;;OAGG;IACH,KAAK,CAAC,EAAE,MAAM,CAAC;IACf;;;OAGG;IACH,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB;;;;;;;;;OASG;IACH,UAAU,CAAC,EAAE;QACX,sCAAsC;QACtC,YAAY,EAAE,OAAO,CAAC;QACtB,+DAA+D;QAC/D,QAAQ,EAAE,MAAM,IAAI,CAAC;KACtB,CAAC;CACH;AAMD;;;;;;;;;;;;;GAaG;AACH,wBAAgB,SAAS,CAAC,KAAK,EAAE,cAAc,GAAG,YAAY,CAiK7D"}
@@ -0,0 +1,122 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { useCallback, useEffect, useRef, useState } from 'react';
3
+ import { useContainerSize } from "../../hooks/ui/useContainerSize.js";
4
+ import { clampSlideIndex, slideActionForKey } from "../core/index.js";
5
+ import { SlideView } from "./Slide.js";
6
+ import { SlideshowBar } from "./SlideshowBar.js";
7
+ /** Slides are authored on this canvas, and it is scaled to whatever it is played on. */
8
+ const SLIDE_WIDTH = 1920;
9
+ const SLIDE_HEIGHT = 1080;
10
+ /**
11
+ * The conference player: one talk, one slide at a time, on a canvas scaled to
12
+ * fill whatever screen it is given.
13
+ *
14
+ * The index is controlled, because the site owns the address — the slide lives
15
+ * in a query parameter so a demo link can return to the exact one — and the
16
+ * player therefore never touches history itself.
17
+ *
18
+ * Arrow keys, space and PageUp/PageDown navigate, `Home` and `End` jump to the
19
+ * ends, `f` toggles fullscreen, `b` and `w` blank the screen to black and to
20
+ * white the way a projector remote does, and `n` shows the presenter's notes.
21
+ * @param props - See {@link SlideshowProps}.
22
+ * @returns The player.
23
+ */
24
+ export function Slideshow(props) {
25
+ const { talk, index, onIndex, onExit, layouts, renderLink, talkId = '', site, talkOrigin, fullscreen, title, className, } = props;
26
+ const total = talk.slides.length;
27
+ const current = clampSlideIndex(index, total);
28
+ const slide = talk.slides[current];
29
+ const playerRef = useRef(null);
30
+ const stageRef = useRef(null);
31
+ const { width, height } = useContainerSize(stageRef);
32
+ const scale = width === 0 || height === 0
33
+ ? 1
34
+ : Math.min(width / SLIDE_WIDTH, height / SLIDE_HEIGHT);
35
+ const [blank, setBlank] = useState(null);
36
+ const [showNotes, setShowNotes] = useState(false);
37
+ const [isFullscreen, setIsFullscreen] = useState(false);
38
+ const goTo = useCallback((next) => {
39
+ setBlank(null);
40
+ onIndex(clampSlideIndex(next, total));
41
+ }, [onIndex, total]);
42
+ const ownFullscreen = fullscreen === undefined;
43
+ const toggleOwn = useCallback(() => {
44
+ const element = playerRef.current;
45
+ if (element === null)
46
+ return;
47
+ if (document.fullscreenElement === element) {
48
+ void document.exitFullscreen().catch(() => undefined);
49
+ }
50
+ else {
51
+ void element.requestFullscreen().catch(() => undefined);
52
+ }
53
+ }, []);
54
+ const toggleFullscreen = fullscreen?.onToggle ?? toggleOwn;
55
+ useEffect(() => {
56
+ if (!ownFullscreen)
57
+ return;
58
+ function onFullscreenChange() {
59
+ setIsFullscreen(document.fullscreenElement === playerRef.current);
60
+ }
61
+ document.addEventListener('fullscreenchange', onFullscreenChange);
62
+ return () => {
63
+ document.removeEventListener('fullscreenchange', onFullscreenChange);
64
+ };
65
+ }, [ownFullscreen]);
66
+ useEffect(() => {
67
+ function onKeyDown(event) {
68
+ if (event.metaKey || event.ctrlKey || event.altKey)
69
+ return;
70
+ // A player embedded in a page shares the document with its fields, and
71
+ // space is both "next slide" and a character.
72
+ if (isTextEntry(event.target))
73
+ return;
74
+ const action = slideActionForKey(event.key, current, total);
75
+ if (action === null)
76
+ return;
77
+ event.preventDefault();
78
+ switch (action.kind) {
79
+ case 'go':
80
+ goTo(action.index);
81
+ break;
82
+ case 'blank':
83
+ setBlank((shown) => (shown === action.color ? null : action.color));
84
+ break;
85
+ case 'fullscreen':
86
+ toggleFullscreen();
87
+ break;
88
+ case 'notes':
89
+ setShowNotes((shown) => !shown);
90
+ break;
91
+ default:
92
+ break;
93
+ }
94
+ }
95
+ document.addEventListener('keydown', onKeyDown);
96
+ return () => {
97
+ document.removeEventListener('keydown', onKeyDown);
98
+ };
99
+ }, [current, total, goTo, toggleFullscreen]);
100
+ function onStageClick(event) {
101
+ // A demo link or a control handles its own click without also stepping on.
102
+ const target = event.target;
103
+ if (target !== null && target.closest('a, button') !== null)
104
+ return;
105
+ goTo(current + 1);
106
+ }
107
+ const progress = total > 1 ? (current / (total - 1)) * 100 : 100;
108
+ return (_jsxs("div", { ref: playerRef, className: className === undefined ? 'slideshow' : `slideshow ${className}`, children: [_jsxs("div", { className: "slideshow-stage", ref: stageRef, onClick: onStageClick, children: [_jsx("div", { className: "slide-canvas", style: { transform: `scale(${scale})` }, children: slide === undefined ? null : (_jsx(SlideView, { slide: slide, talkId: talkId, site: site, talkOrigin: talkOrigin, slideIndex: current, meta: talk.meta, layouts: layouts, renderLink: renderLink }, current)) }), blank === null ? null : (_jsx("div", { className: `slideshow-blank slideshow-blank--${blank}`, onClick: (event) => {
109
+ event.stopPropagation();
110
+ setBlank(null);
111
+ } }))] }), showNotes && slide?.notes !== undefined ? (_jsx("div", { className: "slideshow-notes no-print", children: slide.notes })) : null, _jsx(SlideshowBar, { title: title ?? talk.meta.title, index: current, total: total, isFullscreen: fullscreen?.isFullscreen ?? isFullscreen, onGo: goTo, onToggleFullscreen: toggleFullscreen, onExit: onExit }), _jsx("div", { className: "slideshow-progress", style: { '--progress': `${progress}%` } })] }));
112
+ }
113
+ const TEXT_ENTRY_TAGS = new Set(['INPUT', 'TEXTAREA', 'SELECT']);
114
+ function isTextEntry(target) {
115
+ if (target === null)
116
+ return false;
117
+ const element = target;
118
+ if (element.isContentEditable === true)
119
+ return true;
120
+ return (typeof element.tagName === 'string' && TEXT_ENTRY_TAGS.has(element.tagName));
121
+ }
122
+ //# sourceMappingURL=Slideshow.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Slideshow.js","sourceRoot":"","sources":["../../../src/slides/ui/Slideshow.tsx"],"names":[],"mappings":"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"}
@@ -0,0 +1,33 @@
1
+ import type { ReactElement } from 'react';
2
+ /** Where the talk stands, and what the presenter may do about it. */
3
+ export interface SlideshowBarProps {
4
+ /** What the bar reads. */
5
+ title: string;
6
+ /** Which slide is showing, zero-based. */
7
+ index: number;
8
+ /** How many slides the talk holds. */
9
+ total: number;
10
+ /** Whether the player is presenting on the whole screen. */
11
+ isFullscreen: boolean;
12
+ /** Called with the slide to show. */
13
+ onGo: (index: number) => void;
14
+ /** Called to enter or leave fullscreen. */
15
+ onToggleFullscreen: () => void;
16
+ /**
17
+ * Called when the presenter leaves the talk. The bar carries no Exit button
18
+ * when it is left out.
19
+ * @default undefined
20
+ */
21
+ onExit?: () => void;
22
+ }
23
+ /**
24
+ * The bar under the stage: the way out, the talk's name, and where in it the
25
+ * presenter stands.
26
+ *
27
+ * It is chrome rather than the talk, so it is dropped from a printed handout
28
+ * along with the rest of the site's.
29
+ * @param props - See {@link SlideshowBarProps}.
30
+ * @returns The bar.
31
+ */
32
+ export declare function SlideshowBar(props: SlideshowBarProps): ReactElement;
33
+ //# sourceMappingURL=SlideshowBar.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"SlideshowBar.d.ts","sourceRoot":"","sources":["../../../src/slides/ui/SlideshowBar.tsx"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,OAAO,CAAC;AAE1C,qEAAqE;AACrE,MAAM,WAAW,iBAAiB;IAChC,0BAA0B;IAC1B,KAAK,EAAE,MAAM,CAAC;IACd,0CAA0C;IAC1C,KAAK,EAAE,MAAM,CAAC;IACd,sCAAsC;IACtC,KAAK,EAAE,MAAM,CAAC;IACd,4DAA4D;IAC5D,YAAY,EAAE,OAAO,CAAC;IACtB,qCAAqC;IACrC,IAAI,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAC;IAC9B,2CAA2C;IAC3C,kBAAkB,EAAE,MAAM,IAAI,CAAC;IAC/B;;;;OAIG;IACH,MAAM,CAAC,EAAE,MAAM,IAAI,CAAC;CACrB;AAED;;;;;;;;GAQG;AACH,wBAAgB,YAAY,CAAC,KAAK,EAAE,iBAAiB,GAAG,YAAY,CAgDnE"}
@@ -0,0 +1,20 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { Button } from '@blueprintjs/core';
3
+ /**
4
+ * The bar under the stage: the way out, the talk's name, and where in it the
5
+ * presenter stands.
6
+ *
7
+ * It is chrome rather than the talk, so it is dropped from a printed handout
8
+ * along with the rest of the site's.
9
+ * @param props - See {@link SlideshowBarProps}.
10
+ * @returns The bar.
11
+ */
12
+ export function SlideshowBar(props) {
13
+ const { title, index, total, isFullscreen, onGo, onToggleFullscreen, onExit, } = props;
14
+ return (_jsxs("div", { className: "slideshow-bar no-print", children: [onExit === undefined ? null : (_jsx(Button, { variant: "minimal", icon: "cross", text: "Exit", onClick: onExit })), _jsx("div", { className: "slideshow-title", children: title }), _jsxs("div", { className: "slideshow-controls", children: [_jsx(Button, { variant: "minimal", icon: "chevron-left", "aria-label": "Previous slide", disabled: index === 0, onClick: () => {
15
+ onGo(index - 1);
16
+ } }), _jsx("span", { className: "slideshow-counter", children: `${total === 0 ? 0 : index + 1} / ${total}` }), _jsx(Button, { variant: "minimal", icon: "chevron-right", "aria-label": "Next slide", disabled: index >= total - 1, onClick: () => {
17
+ onGo(index + 1);
18
+ } }), _jsx(Button, { variant: "minimal", icon: isFullscreen ? 'minimize' : 'fullscreen', "aria-label": "Toggle fullscreen", onClick: onToggleFullscreen })] })] }));
19
+ }
20
+ //# sourceMappingURL=SlideshowBar.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"SlideshowBar.js","sourceRoot":"","sources":["../../../src/slides/ui/SlideshowBar.tsx"],"names":[],"mappings":";AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,mBAAmB,CAAC;AAyB3C;;;;;;;;GAQG;AACH,MAAM,UAAU,YAAY,CAAC,KAAwB;IACnD,MAAM,EACJ,KAAK,EACL,KAAK,EACL,KAAK,EACL,YAAY,EACZ,IAAI,EACJ,kBAAkB,EAClB,MAAM,GACP,GAAG,KAAK,CAAC;IAEV,OAAO,CACL,eAAK,SAAS,EAAC,wBAAwB,aACpC,MAAM,KAAK,SAAS,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAC7B,KAAC,MAAM,IAAC,OAAO,EAAC,SAAS,EAAC,IAAI,EAAC,OAAO,EAAC,IAAI,EAAC,MAAM,EAAC,OAAO,EAAE,MAAM,GAAI,CACvE,EACD,cAAK,SAAS,EAAC,iBAAiB,YAAE,KAAK,GAAO,EAC9C,eAAK,SAAS,EAAC,oBAAoB,aACjC,KAAC,MAAM,IACL,OAAO,EAAC,SAAS,EACjB,IAAI,EAAC,cAAc,gBACR,gBAAgB,EAC3B,QAAQ,EAAE,KAAK,KAAK,CAAC,EACrB,OAAO,EAAE,GAAG,EAAE;4BACZ,IAAI,CAAC,KAAK,GAAG,CAAC,CAAC,CAAC;wBAClB,CAAC,GACD,EACF,eAAM,SAAS,EAAC,mBAAmB,YAChC,GAAG,KAAK,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,GAAG,CAAC,MAAM,KAAK,EAAE,GACvC,EACP,KAAC,MAAM,IACL,OAAO,EAAC,SAAS,EACjB,IAAI,EAAC,eAAe,gBACT,YAAY,EACvB,QAAQ,EAAE,KAAK,IAAI,KAAK,GAAG,CAAC,EAC5B,OAAO,EAAE,GAAG,EAAE;4BACZ,IAAI,CAAC,KAAK,GAAG,CAAC,CAAC,CAAC;wBAClB,CAAC,GACD,EACF,KAAC,MAAM,IACL,OAAO,EAAC,SAAS,EACjB,IAAI,EAAE,YAAY,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC,YAAY,gBACnC,mBAAmB,EAC9B,OAAO,EAAE,kBAAkB,GAC3B,IACE,IACF,CACP,CAAC;AACJ,CAAC"}
@@ -0,0 +1,37 @@
1
+ import type { ReactElement } from 'react';
2
+ import type { TalkManifest, TalkSummary } from '../core/index.ts';
3
+ /** The talks to list, and what opening one means. */
4
+ export interface TalkListProps {
5
+ /** One manifest per publishing site. */
6
+ manifests: readonly TalkManifest[];
7
+ /** Called when a talk is picked. */
8
+ onOpen: (manifest: TalkManifest, talk: TalkSummary) => void;
9
+ /**
10
+ * The address a talk sits at, which keeps the card a real link — a middle
11
+ * click opens a tab of its own, and a crawler walks the list.
12
+ * @default undefined — the card is a link with no address
13
+ */
14
+ renderHref?: (manifest: TalkManifest, talk: TalkSummary) => string;
15
+ /**
16
+ * How a site id is written above its talks.
17
+ * @default the id itself
18
+ */
19
+ siteName?: (site: string) => string;
20
+ /**
21
+ * What an empty list says. A list that draws nothing at all reads as a
22
+ * broken page rather than as a site that has published no deck yet.
23
+ * @default 'No talk yet.'
24
+ */
25
+ emptyNote?: string;
26
+ }
27
+ /**
28
+ * The talks on offer: a site's own, or the whole family's.
29
+ *
30
+ * The site heading appears only once there is more than one site to tell
31
+ * apart, so the same component draws a single site's `/talks` page and the
32
+ * family-wide listing without either looking like the other one's leftovers.
33
+ * @param props - See {@link TalkListProps}.
34
+ * @returns The listing.
35
+ */
36
+ export declare function TalkList(props: TalkListProps): ReactElement;
37
+ //# sourceMappingURL=TalkList.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"TalkList.d.ts","sourceRoot":"","sources":["../../../src/slides/ui/TalkList.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,OAAO,CAAC;AAI1C,OAAO,KAAK,EAAE,YAAY,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAC;AAElE,qDAAqD;AACrD,MAAM,WAAW,aAAa;IAC5B,wCAAwC;IACxC,SAAS,EAAE,SAAS,YAAY,EAAE,CAAC;IACnC,oCAAoC;IACpC,MAAM,EAAE,CAAC,QAAQ,EAAE,YAAY,EAAE,IAAI,EAAE,WAAW,KAAK,IAAI,CAAC;IAC5D;;;;OAIG;IACH,UAAU,CAAC,EAAE,CAAC,QAAQ,EAAE,YAAY,EAAE,IAAI,EAAE,WAAW,KAAK,MAAM,CAAC;IACnE;;;OAGG;IACH,QAAQ,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,MAAM,CAAC;IACpC;;;;OAIG;IACH,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED;;;;;;;;GAQG;AACH,wBAAgB,QAAQ,CAAC,KAAK,EAAE,aAAa,GAAG,YAAY,CAmD3D"}
@@ -0,0 +1,68 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { isModifiedClick } from "../../chrome/ui/navItem.js";
3
+ import { pluralize } from "../../format/core/index.js";
4
+ /**
5
+ * The talks on offer: a site's own, or the whole family's.
6
+ *
7
+ * The site heading appears only once there is more than one site to tell
8
+ * apart, so the same component draws a single site's `/talks` page and the
9
+ * family-wide listing without either looking like the other one's leftovers.
10
+ * @param props - See {@link TalkListProps}.
11
+ * @returns The listing.
12
+ */
13
+ export function TalkList(props) {
14
+ const { manifests, onOpen, renderHref, siteName, emptyNote = 'No talk yet.', } = props;
15
+ const groups = groupBySite(manifests);
16
+ const showSite = groups.length > 1;
17
+ if (groups.length === 0) {
18
+ return _jsx("p", { className: "talk-list-empty", children: emptyNote });
19
+ }
20
+ return (_jsx("div", { className: "talk-list", children: groups.map((group) => (_jsxs("section", { className: "talk-list-group", children: [showSite ? (_jsx("h2", { className: "talk-list-site", children: siteName === undefined ? group.site : siteName(group.site) })) : null, _jsx("div", { className: "talk-grid", children: group.entries.map(({ manifest, talk }) => (_jsxs("a", { className: "talk-card", href: renderHref?.(manifest, talk), onClick: (event) => {
21
+ if (isModifiedClick(event))
22
+ return;
23
+ event.preventDefault();
24
+ onOpen(manifest, talk);
25
+ }, children: [_jsx("div", { className: "talk-card-title", children: talk.title }), talk.subtitle === undefined ? null : (_jsx("div", { className: "talk-card-subtitle", children: talk.subtitle })), _jsx("div", { className: "talk-card-meta", children: occasion(talk) }), _jsx("div", { className: "talk-card-count", children: `${talk.slideCount} ${pluralize(talk.slideCount, 'slide')}` })] }, `${manifest.site}:${talk.id}`))) })] }, group.site))) }));
26
+ }
27
+ function groupBySite(manifests) {
28
+ const bySite = new Map();
29
+ for (const manifest of manifests) {
30
+ let entries = bySite.get(manifest.site);
31
+ if (entries === undefined) {
32
+ entries = [];
33
+ bySite.set(manifest.site, entries);
34
+ }
35
+ for (const talk of manifest.talks)
36
+ entries.push({ manifest, talk });
37
+ }
38
+ const groups = [];
39
+ for (const [site, entries] of bySite) {
40
+ // A site that has published nothing is not a heading over an empty row.
41
+ if (entries.length === 0)
42
+ continue;
43
+ groups.push({ site, entries: entries.toSorted(byMostRecent) });
44
+ }
45
+ return groups;
46
+ }
47
+ // The dates are ISO, so they order as text; a talk with no date sorts last
48
+ // rather than ahead of every dated one.
49
+ function byMostRecent(left, right) {
50
+ const before = left.talk.date ?? '';
51
+ const after = right.talk.date ?? '';
52
+ if (before === after)
53
+ return 0;
54
+ if (before === '')
55
+ return 1;
56
+ if (after === '')
57
+ return -1;
58
+ return before > after ? -1 : 1;
59
+ }
60
+ function occasion(talk) {
61
+ const parts = [];
62
+ if (talk.event !== undefined)
63
+ parts.push(talk.event);
64
+ if (talk.date !== undefined)
65
+ parts.push(talk.date);
66
+ return parts.join(' · ');
67
+ }
68
+ //# sourceMappingURL=TalkList.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"TalkList.js","sourceRoot":"","sources":["../../../src/slides/ui/TalkList.tsx"],"names":[],"mappings":"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"}
@@ -0,0 +1,19 @@
1
+ export type { BackToSlidesProps } from './BackToSlides.tsx';
2
+ export { BackToSlides } from './BackToSlides.tsx';
3
+ export type { DemoLinkProps, RenderSlideLink } from './DemoLink.tsx';
4
+ export { DemoLink } from './DemoLink.tsx';
5
+ export type { EmbedSlideProps } from './EmbedSlide.tsx';
6
+ export { EmbedSlide } from './EmbedSlide.tsx';
7
+ export type { SectionSlideProps } from './SectionSlide.tsx';
8
+ export { SectionSlide } from './SectionSlide.tsx';
9
+ export type { SlideLayoutProps, SlideViewProps } from './Slide.tsx';
10
+ export { SlideView } from './Slide.tsx';
11
+ export type { SlideBodyProps } from './SlideBody.tsx';
12
+ export { SlideBody } from './SlideBody.tsx';
13
+ export type { SlideshowProps } from './Slideshow.tsx';
14
+ export { Slideshow } from './Slideshow.tsx';
15
+ export type { SlideshowBarProps } from './SlideshowBar.tsx';
16
+ export { SlideshowBar } from './SlideshowBar.tsx';
17
+ export type { TalkListProps } from './TalkList.tsx';
18
+ export { TalkList } from './TalkList.tsx';
19
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/slides/ui/index.ts"],"names":[],"mappings":"AAAA,YAAY,EAAE,iBAAiB,EAAE,MAAM,oBAAoB,CAAC;AAC5D,OAAO,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAClD,YAAY,EAAE,aAAa,EAAE,eAAe,EAAE,MAAM,gBAAgB,CAAC;AACrE,OAAO,EAAE,QAAQ,EAAE,MAAM,gBAAgB,CAAC;AAC1C,YAAY,EAAE,eAAe,EAAE,MAAM,kBAAkB,CAAC;AACxD,OAAO,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AAC9C,YAAY,EAAE,iBAAiB,EAAE,MAAM,oBAAoB,CAAC;AAC5D,OAAO,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAClD,YAAY,EAAE,gBAAgB,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AACpE,OAAO,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AACxC,YAAY,EAAE,cAAc,EAAE,MAAM,iBAAiB,CAAC;AACtD,OAAO,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC;AAC5C,YAAY,EAAE,cAAc,EAAE,MAAM,iBAAiB,CAAC;AACtD,OAAO,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC;AAC5C,YAAY,EAAE,iBAAiB,EAAE,MAAM,oBAAoB,CAAC;AAC5D,OAAO,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAClD,YAAY,EAAE,aAAa,EAAE,MAAM,gBAAgB,CAAC;AACpD,OAAO,EAAE,QAAQ,EAAE,MAAM,gBAAgB,CAAC"}