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.
- package/README.md +60 -2
- package/bin/check-tokens.mjs +105 -0
- package/lib/about/core/about.d.ts +95 -0
- package/lib/about/core/about.d.ts.map +1 -0
- package/lib/about/core/about.js +78 -0
- package/lib/about/core/about.js.map +1 -0
- package/lib/about/core/index.d.ts +3 -0
- package/lib/about/core/index.d.ts.map +1 -0
- package/lib/about/core/index.js +2 -0
- package/lib/about/core/index.js.map +1 -0
- package/lib/about/ui/AboutCitations.d.ts +14 -0
- package/lib/about/ui/AboutCitations.d.ts.map +1 -0
- package/lib/about/ui/AboutCitations.js +40 -0
- package/lib/about/ui/AboutCitations.js.map +1 -0
- package/lib/about/ui/AboutPage.d.ts +32 -0
- package/lib/about/ui/AboutPage.d.ts.map +1 -0
- package/lib/about/ui/AboutPage.js +70 -0
- package/lib/about/ui/AboutPage.js.map +1 -0
- package/lib/about/ui/AboutSection.d.ts +23 -0
- package/lib/about/ui/AboutSection.d.ts.map +1 -0
- package/lib/about/ui/AboutSection.js +28 -0
- package/lib/about/ui/AboutSection.js.map +1 -0
- package/lib/about/ui/index.d.ts +7 -0
- package/lib/about/ui/index.d.ts.map +1 -0
- package/lib/about/ui/index.js +4 -0
- package/lib/about/ui/index.js.map +1 -0
- package/lib/chrome/ui/index.d.ts +1 -0
- package/lib/chrome/ui/index.d.ts.map +1 -1
- package/lib/chrome/ui/index.js +3 -0
- package/lib/chrome/ui/index.js.map +1 -1
- package/lib/citation/core/index.d.ts +1 -0
- package/lib/citation/core/index.d.ts.map +1 -1
- package/lib/citation/core/index.js +1 -0
- package/lib/citation/core/index.js.map +1 -1
- package/lib/citation/core/teachingPaper.d.ts +15 -0
- package/lib/citation/core/teachingPaper.d.ts.map +1 -0
- package/lib/citation/core/teachingPaper.js +32 -0
- package/lib/citation/core/teachingPaper.js.map +1 -0
- package/lib/clipboard/ui/CodeBlock.d.ts.map +1 -1
- package/lib/clipboard/ui/CodeBlock.js +4 -1
- package/lib/clipboard/ui/CodeBlock.js.map +1 -1
- package/lib/color/ui/ColorScaleLegend.js +1 -1
- package/lib/color/ui/ColorScaleLegend.js.map +1 -1
- package/lib/core.d.ts +3 -0
- package/lib/core.d.ts.map +1 -1
- package/lib/core.js +5 -0
- package/lib/core.js.map +1 -1
- package/lib/credits/core/credits.d.ts +36 -0
- package/lib/credits/core/credits.d.ts.map +1 -1
- package/lib/credits/core/credits.js +42 -0
- package/lib/credits/core/credits.js.map +1 -1
- package/lib/credits/ui/CreditsList.js +1 -1
- package/lib/credits/ui/CreditsList.js.map +1 -1
- package/lib/delimited/ui/DelimitedTextPanel.js +1 -1
- package/lib/delimited/ui/DelimitedTextPanel.js.map +1 -1
- package/lib/ecosystem/core/sites.d.ts +1 -1
- package/lib/ecosystem/core/sites.d.ts.map +1 -1
- package/lib/ecosystem/core/sites.js +10 -0
- package/lib/ecosystem/core/sites.js.map +1 -1
- package/lib/ecosystem/core/tokens.d.ts.map +1 -1
- package/lib/ecosystem/core/tokens.js +1 -0
- package/lib/ecosystem/core/tokens.js.map +1 -1
- package/lib/ecosystem/ui/EcosystemLinks.js +2 -2
- package/lib/ecosystem/ui/EcosystemLinks.js.map +1 -1
- package/lib/ecosystem/ui/EcosystemMenu.js +1 -1
- package/lib/ecosystem/ui/EcosystemMenu.js.map +1 -1
- package/lib/ecosystem/ui/SiteTile.d.ts.map +1 -1
- package/lib/ecosystem/ui/SiteTile.js +5 -5
- package/lib/ecosystem/ui/SiteTile.js.map +1 -1
- package/lib/ecosystem/ui/glyphs.d.ts.map +1 -1
- package/lib/ecosystem/ui/glyphs.js +3 -0
- package/lib/ecosystem/ui/glyphs.js.map +1 -1
- package/lib/orbital/core/index.d.ts +1 -1
- package/lib/orbital/core/index.d.ts.map +1 -1
- package/lib/orbital/core/index.js +1 -1
- package/lib/orbital/core/index.js.map +1 -1
- package/lib/orbital/core/realHarmonics.d.ts +5 -2
- package/lib/orbital/core/realHarmonics.d.ts.map +1 -1
- package/lib/orbital/core/realHarmonics.js.map +1 -1
- package/lib/orbital/ui/AtomicOrbitalCanvas.d.ts +18 -0
- package/lib/orbital/ui/AtomicOrbitalCanvas.d.ts.map +1 -1
- package/lib/orbital/ui/AtomicOrbitalCanvas.js +84 -7
- package/lib/orbital/ui/AtomicOrbitalCanvas.js.map +1 -1
- package/lib/orbital/ui/AtomicOrbitalViewer.d.ts +13 -0
- package/lib/orbital/ui/AtomicOrbitalViewer.d.ts.map +1 -1
- package/lib/orbital/ui/AtomicOrbitalViewer.js +1 -1
- package/lib/orbital/ui/AtomicOrbitalViewer.js.map +1 -1
- package/lib/orbital/ui/camera.d.ts +15 -0
- package/lib/orbital/ui/camera.d.ts.map +1 -1
- package/lib/orbital/ui/camera.js +68 -0
- package/lib/orbital/ui/camera.js.map +1 -1
- package/lib/orbital/ui/renderVolume.d.ts.map +1 -1
- package/lib/orbital/ui/renderVolume.js +8 -1
- package/lib/orbital/ui/renderVolume.js.map +1 -1
- package/lib/orbital/ui/serial.d.ts +25 -0
- package/lib/orbital/ui/serial.d.ts.map +1 -0
- package/lib/orbital/ui/serial.js +25 -0
- package/lib/orbital/ui/serial.js.map +1 -0
- package/lib/orbital/ui/viewer.d.ts +23 -0
- package/lib/orbital/ui/viewer.d.ts.map +1 -1
- package/lib/orbital/ui/viewer.js +70 -17
- package/lib/orbital/ui/viewer.js.map +1 -1
- package/lib/pedagogy/ui/ExerciseProgressHeader.js +1 -1
- package/lib/pedagogy/ui/ExerciseProgressHeader.js.map +1 -1
- package/lib/pedagogy/ui/GlossaryText.js +2 -2
- package/lib/pedagogy/ui/GlossaryText.js.map +1 -1
- package/lib/pedagogy/ui/ReferenceSectionBlock.js +5 -2
- package/lib/pedagogy/ui/ReferenceSectionBlock.js.map +1 -1
- package/lib/pedagogy/ui/SyntaxTooltip.js +2 -2
- package/lib/pedagogy/ui/SyntaxTooltip.js.map +1 -1
- package/lib/pedagogy/ui/TutorialStepStrip.d.ts +15 -2
- package/lib/pedagogy/ui/TutorialStepStrip.d.ts.map +1 -1
- package/lib/pedagogy/ui/TutorialStepStrip.js +19 -5
- package/lib/pedagogy/ui/TutorialStepStrip.js.map +1 -1
- package/lib/pedagogy/ui/index.d.ts +1 -1
- package/lib/pedagogy/ui/index.d.ts.map +1 -1
- package/lib/pedagogy/ui/index.js.map +1 -1
- package/lib/periodic/ui/CategoryLegend.js +1 -1
- package/lib/periodic/ui/CategoryLegend.js.map +1 -1
- package/lib/periodic/ui/PeriodicTableChrome.js +2 -2
- package/lib/periodic/ui/PeriodicTableChrome.js.map +1 -1
- package/lib/seo/vite/ogCard.d.ts.map +1 -1
- package/lib/seo/vite/ogCard.js +1 -0
- package/lib/seo/vite/ogCard.js.map +1 -1
- package/lib/share/ui/ShareDialogContent.d.ts.map +1 -1
- package/lib/share/ui/ShareDialogContent.js +5 -2
- package/lib/share/ui/ShareDialogContent.js.map +1 -1
- package/lib/share/ui/SharePartOptions.js +1 -1
- package/lib/share/ui/SharePartOptions.js.map +1 -1
- package/lib/slides/core/demoLinks.d.ts +43 -0
- package/lib/slides/core/demoLinks.d.ts.map +1 -0
- package/lib/slides/core/demoLinks.js +104 -0
- package/lib/slides/core/demoLinks.js.map +1 -0
- package/lib/slides/core/index.d.ts +13 -0
- package/lib/slides/core/index.d.ts.map +1 -0
- package/lib/slides/core/index.js +7 -0
- package/lib/slides/core/index.js.map +1 -0
- package/lib/slides/core/sectionHeading.d.ts +19 -0
- package/lib/slides/core/sectionHeading.d.ts.map +1 -0
- package/lib/slides/core/sectionHeading.js +19 -0
- package/lib/slides/core/sectionHeading.js.map +1 -0
- package/lib/slides/core/slideNavigation.d.ts +38 -0
- package/lib/slides/core/slideNavigation.d.ts.map +1 -0
- package/lib/slides/core/slideNavigation.js +65 -0
- package/lib/slides/core/slideNavigation.js.map +1 -0
- package/lib/slides/core/talk.d.ts +82 -0
- package/lib/slides/core/talk.d.ts.map +1 -0
- package/lib/slides/core/talk.js +134 -0
- package/lib/slides/core/talk.js.map +1 -0
- package/lib/slides/core/talkManifest.d.ts +90 -0
- package/lib/slides/core/talkManifest.d.ts.map +1 -0
- package/lib/slides/core/talkManifest.js +109 -0
- package/lib/slides/core/talkManifest.js.map +1 -0
- package/lib/slides/core/talkOrigin.d.ts +50 -0
- package/lib/slides/core/talkOrigin.d.ts.map +1 -0
- package/lib/slides/core/talkOrigin.js +62 -0
- package/lib/slides/core/talkOrigin.js.map +1 -0
- package/lib/slides/ui/BackToSlides.d.ts +26 -0
- package/lib/slides/ui/BackToSlides.d.ts.map +1 -0
- package/lib/slides/ui/BackToSlides.js +24 -0
- package/lib/slides/ui/BackToSlides.js.map +1 -0
- package/lib/slides/ui/DemoLink.d.ts +42 -0
- package/lib/slides/ui/DemoLink.d.ts.map +1 -0
- package/lib/slides/ui/DemoLink.js +17 -0
- package/lib/slides/ui/DemoLink.js.map +1 -0
- package/lib/slides/ui/EmbedSlide.d.ts +19 -0
- package/lib/slides/ui/EmbedSlide.d.ts.map +1 -0
- package/lib/slides/ui/EmbedSlide.js +56 -0
- package/lib/slides/ui/EmbedSlide.js.map +1 -0
- package/lib/slides/ui/SectionSlide.d.ts +18 -0
- package/lib/slides/ui/SectionSlide.d.ts.map +1 -0
- package/lib/slides/ui/SectionSlide.js +18 -0
- package/lib/slides/ui/SectionSlide.js.map +1 -0
- package/lib/slides/ui/Slide.d.ts +52 -0
- package/lib/slides/ui/Slide.d.ts.map +1 -0
- package/lib/slides/ui/Slide.js +58 -0
- package/lib/slides/ui/Slide.js.map +1 -0
- package/lib/slides/ui/SlideBody.d.ts +32 -0
- package/lib/slides/ui/SlideBody.d.ts.map +1 -0
- package/lib/slides/ui/SlideBody.js +27 -0
- package/lib/slides/ui/SlideBody.js.map +1 -0
- package/lib/slides/ui/Slideshow.d.ts +93 -0
- package/lib/slides/ui/Slideshow.d.ts.map +1 -0
- package/lib/slides/ui/Slideshow.js +122 -0
- package/lib/slides/ui/Slideshow.js.map +1 -0
- package/lib/slides/ui/SlideshowBar.d.ts +33 -0
- package/lib/slides/ui/SlideshowBar.d.ts.map +1 -0
- package/lib/slides/ui/SlideshowBar.js +20 -0
- package/lib/slides/ui/SlideshowBar.js.map +1 -0
- package/lib/slides/ui/TalkList.d.ts +37 -0
- package/lib/slides/ui/TalkList.d.ts.map +1 -0
- package/lib/slides/ui/TalkList.js +68 -0
- package/lib/slides/ui/TalkList.js.map +1 -0
- package/lib/slides/ui/index.d.ts +19 -0
- package/lib/slides/ui/index.d.ts.map +1 -0
- package/lib/slides/ui/index.js +10 -0
- package/lib/slides/ui/index.js.map +1 -0
- package/lib/slides/vite/index.d.ts +3 -0
- package/lib/slides/vite/index.d.ts.map +1 -0
- package/lib/slides/vite/index.js +2 -0
- package/lib/slides/vite/index.js.map +1 -0
- package/lib/slides/vite/talks.d.ts +50 -0
- package/lib/slides/vite/talks.d.ts.map +1 -0
- package/lib/slides/vite/talks.js +87 -0
- package/lib/slides/vite/talks.js.map +1 -0
- package/lib/slides.d.ts +3 -0
- package/lib/slides.d.ts.map +1 -0
- package/lib/slides.js +3 -0
- package/lib/slides.js.map +1 -0
- package/lib/structure/ui/StructureEditor.js +2 -2
- package/lib/structure/ui/StructureEditor.js.map +1 -1
- package/lib/structure/ui/StructurePlaceholder.js +1 -1
- package/lib/structure/ui/StructurePlaceholder.js.map +1 -1
- package/lib/tokens/core/checkTokens.d.ts +51 -0
- package/lib/tokens/core/checkTokens.d.ts.map +1 -0
- package/lib/tokens/core/checkTokens.js +188 -0
- package/lib/tokens/core/checkTokens.js.map +1 -0
- package/lib/tokens/core/colors.d.ts +42 -0
- package/lib/tokens/core/colors.d.ts.map +1 -0
- package/lib/tokens/core/colors.js +119 -0
- package/lib/tokens/core/colors.js.map +1 -0
- package/lib/tokens/core/index.d.ts +3 -0
- package/lib/tokens/core/index.d.ts.map +1 -0
- package/lib/tokens/core/index.js +2 -0
- package/lib/tokens/core/index.js.map +1 -0
- package/lib/tokens/core/rules.d.ts +23 -0
- package/lib/tokens/core/rules.d.ts.map +1 -0
- package/lib/tokens/core/rules.js +90 -0
- package/lib/tokens/core/rules.js.map +1 -0
- package/lib/ui.d.ts +1 -0
- package/lib/ui.d.ts.map +1 -1
- package/lib/ui.js +1 -0
- package/lib/ui.js.map +1 -1
- package/lib/vite.d.ts +1 -0
- package/lib/vite.d.ts.map +1 -1
- package/lib/vite.js +1 -0
- package/lib/vite.js.map +1 -1
- package/package.json +11 -3
- package/src/about/core/about.ts +176 -0
- package/src/about/core/index.ts +2 -0
- package/src/about/ui/AboutCitations.tsx +79 -0
- package/src/about/ui/AboutPage.tsx +177 -0
- package/src/about/ui/AboutSection.tsx +56 -0
- package/src/about/ui/index.ts +6 -0
- package/src/chrome/ui/index.ts +3 -0
- package/src/citation/core/index.ts +1 -0
- package/src/citation/core/teachingPaper.ts +36 -0
- package/src/clipboard/ui/CodeBlock.tsx +4 -1
- package/src/color/ui/ColorScaleLegend.tsx +1 -1
- package/src/core.ts +5 -0
- package/src/credits/core/credits.ts +42 -0
- package/src/credits/ui/CreditsList.tsx +1 -1
- package/src/delimited/ui/DelimitedTextPanel.tsx +1 -1
- package/src/ecosystem/core/sites.ts +12 -0
- package/src/ecosystem/core/tokens.ts +1 -0
- package/src/ecosystem/ui/EcosystemLinks.tsx +2 -2
- package/src/ecosystem/ui/EcosystemMenu.tsx +1 -1
- package/src/ecosystem/ui/SiteTile.tsx +7 -5
- package/src/ecosystem/ui/glyphs.tsx +40 -0
- package/src/orbital/core/index.ts +4 -1
- package/src/orbital/core/realHarmonics.ts +5 -2
- package/src/orbital/ui/AtomicOrbitalCanvas.tsx +126 -4
- package/src/orbital/ui/AtomicOrbitalViewer.tsx +14 -1
- package/src/orbital/ui/camera.ts +81 -0
- package/src/orbital/ui/renderVolume.ts +8 -1
- package/src/orbital/ui/serial.ts +35 -0
- package/src/orbital/ui/viewer.ts +72 -13
- package/src/pedagogy/ui/ExerciseProgressHeader.tsx +1 -1
- package/src/pedagogy/ui/GlossaryText.tsx +2 -2
- package/src/pedagogy/ui/ReferenceSectionBlock.tsx +5 -2
- package/src/pedagogy/ui/SyntaxTooltip.tsx +2 -2
- package/src/pedagogy/ui/TutorialStepStrip.tsx +39 -10
- package/src/pedagogy/ui/index.ts +4 -1
- package/src/periodic/ui/CategoryLegend.tsx +1 -1
- package/src/periodic/ui/PeriodicTableChrome.tsx +2 -2
- package/src/seo/vite/ogCard.ts +1 -0
- package/src/share/ui/ShareDialogContent.tsx +5 -2
- package/src/share/ui/SharePartOptions.tsx +1 -1
- package/src/slides/core/demoLinks.ts +113 -0
- package/src/slides/core/index.ts +22 -0
- package/src/slides/core/sectionHeading.ts +29 -0
- package/src/slides/core/slideNavigation.ts +77 -0
- package/src/slides/core/talk.ts +203 -0
- package/src/slides/core/talkManifest.ts +158 -0
- package/src/slides/core/talkOrigin.ts +83 -0
- package/src/slides/ui/BackToSlides.tsx +49 -0
- package/src/slides/ui/DemoLink.tsx +67 -0
- package/src/slides/ui/EmbedSlide.tsx +85 -0
- package/src/slides/ui/SectionSlide.tsx +44 -0
- package/src/slides/ui/Slide.tsx +143 -0
- package/src/slides/ui/SlideBody.tsx +64 -0
- package/src/slides/ui/Slideshow.tsx +282 -0
- package/src/slides/ui/SlideshowBar.tsx +83 -0
- package/src/slides/ui/TalkList.tsx +146 -0
- package/src/slides/ui/index.ts +18 -0
- package/src/slides/vite/index.ts +2 -0
- package/src/slides/vite/talks.ts +126 -0
- package/src/slides.ts +2 -0
- package/src/structure/ui/StructureEditor.tsx +2 -2
- package/src/structure/ui/StructurePlaceholder.tsx +1 -1
- package/src/tokens/core/checkTokens.ts +242 -0
- package/src/tokens/core/colors.ts +122 -0
- package/src/tokens/core/index.ts +6 -0
- package/src/tokens/core/rules.ts +103 -0
- package/src/ui.ts +1 -0
- package/src/vite.ts +1 -0
- package/styles/chrome.css +1 -0
- 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":";AAMA,OAAO,EAAE,WAAW,EAAE,SAAS,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,OAAO,CAAC;AAEjE,OAAO,EAAE,gBAAgB,EAAE,MAAM,oCAAoC,CAAC;AAEtE,OAAO,EAAE,eAAe,EAAE,iBAAiB,EAAE,MAAM,kBAAkB,CAAC;AAItE,OAAO,EAAE,SAAS,EAAE,MAAM,YAAa,CAAC;AACxC,OAAO,EAAE,YAAY,EAAE,MAAM,mBAAoB,CAAC;AA4ElD,wFAAwF;AACxF,MAAM,WAAW,GAAG,IAAI,CAAC;AACzB,MAAM,YAAY,GAAG,IAAI,CAAC;AAE1B;;;;;;;;;;;;;GAaG;AACH,MAAM,UAAU,SAAS,CAAC,KAAqB;IAC7C,MAAM,EACJ,IAAI,EACJ,KAAK,EACL,OAAO,EACP,MAAM,EACN,OAAO,EACP,UAAU,EACV,MAAM,GAAG,EAAE,EACX,IAAI,EACJ,UAAU,EACV,UAAU,EACV,KAAK,EACL,SAAS,GACV,GAAG,KAAK,CAAC;IAEV,MAAM,KAAK,GAAG,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC;IACjC,MAAM,OAAO,GAAG,eAAe,CAAC,KAAK,EAAE,KAAK,CAAC,CAAC;IAC9C,MAAM,KAAK,GAAG,IAAI,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC;IAEnC,MAAM,SAAS,GAAG,MAAM,CAAiB,IAAI,CAAC,CAAC;IAC/C,MAAM,QAAQ,GAAG,MAAM,CAAiB,IAAI,CAAC,CAAC;IAC9C,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,GAAG,gBAAgB,CAAC,QAAQ,CAAC,CAAC;IACrD,MAAM,KAAK,GACT,KAAK,KAAK,CAAC,IAAI,MAAM,KAAK,CAAC;QACzB,CAAC,CAAC,CAAC;QACH,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,KAAK,GAAG,WAAW,EAAE,MAAM,GAAG,YAAY,CAAC,CAAC;IAE3D,MAAM,CAAC,KAAK,EAAE,QAAQ,CAAC,GAAG,QAAQ,CAA2B,IAAI,CAAC,CAAC;IACnE,MAAM,CAAC,SAAS,EAAE,YAAY,CAAC,GAAG,QAAQ,CAAC,KAAK,CAAC,CAAC;IAClD,MAAM,CAAC,YAAY,EAAE,eAAe,CAAC,GAAG,QAAQ,CAAC,KAAK,CAAC,CAAC;IAExD,MAAM,IAAI,GAAG,WAAW,CACtB,CAAC,IAAY,EAAE,EAAE;QACf,QAAQ,CAAC,IAAI,CAAC,CAAC;QACf,OAAO,CAAC,eAAe,CAAC,IAAI,EAAE,KAAK,CAAC,CAAC,CAAC;IACxC,CAAC,EACD,CAAC,OAAO,EAAE,KAAK,CAAC,CACjB,CAAC;IAEF,MAAM,aAAa,GAAG,UAAU,KAAK,SAAS,CAAC;IAC/C,MAAM,SAAS,GAAG,WAAW,CAAC,GAAG,EAAE;QACjC,MAAM,OAAO,GAAG,SAAS,CAAC,OAAO,CAAC;QAClC,IAAI,OAAO,KAAK,IAAI;YAAE,OAAO;QAC7B,IAAI,QAAQ,CAAC,iBAAiB,KAAK,OAAO,EAAE,CAAC;YAC3C,KAAK,QAAQ,CAAC,cAAc,EAAE,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC,SAAS,CAAC,CAAC;QACxD,CAAC;aAAM,CAAC;YACN,KAAK,OAAO,CAAC,iBAAiB,EAAE,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC,SAAS,CAAC,CAAC;QAC1D,CAAC;IACH,CAAC,EAAE,EAAE,CAAC,CAAC;IACP,MAAM,gBAAgB,GAAG,UAAU,EAAE,QAAQ,IAAI,SAAS,CAAC;IAE3D,SAAS,CAAC,GAAG,EAAE;QACb,IAAI,CAAC,aAAa;YAAE,OAAO;QAC3B,SAAS,kBAAkB;YACzB,eAAe,CAAC,QAAQ,CAAC,iBAAiB,KAAK,SAAS,CAAC,OAAO,CAAC,CAAC;QACpE,CAAC;QACD,QAAQ,CAAC,gBAAgB,CAAC,kBAAkB,EAAE,kBAAkB,CAAC,CAAC;QAClE,OAAO,GAAG,EAAE;YACV,QAAQ,CAAC,mBAAmB,CAAC,kBAAkB,EAAE,kBAAkB,CAAC,CAAC;QACvE,CAAC,CAAC;IACJ,CAAC,EAAE,CAAC,aAAa,CAAC,CAAC,CAAC;IAEpB,SAAS,CAAC,GAAG,EAAE;QACb,SAAS,SAAS,CAAC,KAAoB;YACrC,IAAI,KAAK,CAAC,OAAO,IAAI,KAAK,CAAC,OAAO,IAAI,KAAK,CAAC,MAAM;gBAAE,OAAO;YAC3D,uEAAuE;YACvE,8CAA8C;YAC9C,IAAI,WAAW,CAAC,KAAK,CAAC,MAAM,CAAC;gBAAE,OAAO;YACtC,MAAM,MAAM,GAAG,iBAAiB,CAAC,KAAK,CAAC,GAAG,EAAE,OAAO,EAAE,KAAK,CAAC,CAAC;YAC5D,IAAI,MAAM,KAAK,IAAI;gBAAE,OAAO;YAC5B,KAAK,CAAC,cAAc,EAAE,CAAC;YACvB,QAAQ,MAAM,CAAC,IAAI,EAAE,CAAC;gBACpB,KAAK,IAAI;oBACP,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;oBACnB,MAAM;gBACR,KAAK,OAAO;oBACV,QAAQ,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC,KAAK,KAAK,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC;oBACpE,MAAM;gBACR,KAAK,YAAY;oBACf,gBAAgB,EAAE,CAAC;oBACnB,MAAM;gBACR,KAAK,OAAO;oBACV,YAAY,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC;oBAChC,MAAM;gBACR;oBACE,MAAM;YACV,CAAC;QACH,CAAC;QACD,QAAQ,CAAC,gBAAgB,CAAC,SAAS,EAAE,SAAS,CAAC,CAAC;QAChD,OAAO,GAAG,EAAE;YACV,QAAQ,CAAC,mBAAmB,CAAC,SAAS,EAAE,SAAS,CAAC,CAAC;QACrD,CAAC,CAAC;IACJ,CAAC,EAAE,CAAC,OAAO,EAAE,KAAK,EAAE,IAAI,EAAE,gBAAgB,CAAC,CAAC,CAAC;IAE7C,SAAS,YAAY,CAAC,KAAiC;QACrD,2EAA2E;QAC3E,MAAM,MAAM,GAAG,KAAK,CAAC,MAAwB,CAAC;QAC9C,IAAI,MAAM,KAAK,IAAI,IAAI,MAAM,CAAC,OAAO,CAAC,WAAW,CAAC,KAAK,IAAI;YAAE,OAAO;QACpE,IAAI,CAAC,OAAO,GAAG,CAAC,CAAC,CAAC;IACpB,CAAC;IAED,MAAM,QAAQ,GAAG,KAAK,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,GAAG,CAAC,KAAK,GAAG,CAAC,CAAC,CAAC,GAAG,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC;IAEjE,OAAO,CACL,eACE,GAAG,EAAE,SAAS,EACd,SAAS,EACP,SAAS,KAAK,SAAS,CAAC,CAAC,CAAC,WAAW,CAAC,CAAC,CAAC,aAAa,SAAS,EAAE,aAKlE,eAAK,SAAS,EAAC,iBAAiB,EAAC,GAAG,EAAE,QAAQ,EAAE,OAAO,EAAE,YAAY,aACnE,cAAK,SAAS,EAAC,cAAc,EAAC,KAAK,EAAE,EAAE,SAAS,EAAE,SAAS,KAAK,GAAG,EAAE,YAClE,KAAK,KAAK,SAAS,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAG5B,KAAC,SAAS,IAER,KAAK,EAAE,KAAK,EACZ,MAAM,EAAE,MAAM,EACd,IAAI,EAAE,IAAI,EACV,UAAU,EAAE,UAAU,EACtB,UAAU,EAAE,OAAO,EACnB,IAAI,EAAE,IAAI,CAAC,IAAI,EACf,OAAO,EAAE,OAAO,EAChB,UAAU,EAAE,UAAU,IARjB,OAAO,CASZ,CACH,GACG,EACL,KAAK,KAAK,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAGvB,cACE,SAAS,EAAE,oCAAoC,KAAK,EAAE,EACtD,OAAO,EAAE,CAAC,KAAK,EAAE,EAAE;4BACjB,KAAK,CAAC,eAAe,EAAE,CAAC;4BACxB,QAAQ,CAAC,IAAI,CAAC,CAAC;wBACjB,CAAC,GACD,CACH,IACG,EACL,SAAS,IAAI,KAAK,EAAE,KAAK,KAAK,SAAS,CAAC,CAAC,CAAC,CACzC,cAAK,SAAS,EAAC,0BAA0B,YAAE,KAAK,CAAC,KAAK,GAAO,CAC9D,CAAC,CAAC,CAAC,IAAI,EACR,KAAC,YAAY,IACX,KAAK,EAAE,KAAK,IAAI,IAAI,CAAC,IAAI,CAAC,KAAK,EAC/B,KAAK,EAAE,OAAO,EACd,KAAK,EAAE,KAAK,EACZ,YAAY,EAAE,UAAU,EAAE,YAAY,IAAI,YAAY,EACtD,IAAI,EAAE,IAAI,EACV,kBAAkB,EAAE,gBAAgB,EACpC,MAAM,EAAE,MAAM,GACd,EACF,cACE,SAAS,EAAC,oBAAoB,EAC9B,KAAK,EAAE,EAAE,YAAY,EAAE,GAAG,QAAQ,GAAG,EAAmB,GACxD,IACE,CACP,CAAC;AACJ,CAAC;AAED,MAAM,eAAe,GAAG,IAAI,GAAG,CAAC,CAAC,OAAO,EAAE,UAAU,EAAE,QAAQ,CAAC,CAAC,CAAC;AAEjE,SAAS,WAAW,CAAC,MAA0B;IAC7C,IAAI,MAAM,KAAK,IAAI;QAAE,OAAO,KAAK,CAAC;IAClC,MAAM,OAAO,GAAG,MAA4D,CAAC;IAC7E,IAAI,OAAO,CAAC,iBAAiB,KAAK,IAAI;QAAE,OAAO,IAAI,CAAC;IACpD,OAAO,CACL,OAAO,OAAO,CAAC,OAAO,KAAK,QAAQ,IAAI,eAAe,CAAC,GAAG,CAAC,OAAO,CAAC,OAAO,CAAC,CAC5E,CAAC;AACJ,CAAC"}
|
|
@@ -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"}
|