@thanh01.pmt/presentation-kit 0.1.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 +548 -0
- package/dist/chunk-N4Q6GUAQ.cjs +1255 -0
- package/dist/chunk-N4Q6GUAQ.cjs.map +1 -0
- package/dist/chunk-RCHOTRWI.js +1231 -0
- package/dist/chunk-RCHOTRWI.js.map +1 -0
- package/dist/click-css-CadkoJ_A.d.cts +244 -0
- package/dist/click-css-CadkoJ_A.d.ts +244 -0
- package/dist/index.cjs +126 -0
- package/dist/index.cjs.map +1 -0
- package/dist/index.d.cts +86 -0
- package/dist/index.d.ts +86 -0
- package/dist/index.js +33 -0
- package/dist/index.js.map +1 -0
- package/dist/react/index.cjs +788 -0
- package/dist/react/index.cjs.map +1 -0
- package/dist/react/index.d.cts +269 -0
- package/dist/react/index.d.ts +269 -0
- package/dist/react/index.js +750 -0
- package/dist/react/index.js.map +1 -0
- package/package.json +61 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../src/react/hooks/useSlideState.ts","../../src/react/components/ThemeSwitcher.tsx","../../src/react/components/NavigationBar.tsx","../../src/react/components/PresentationView.tsx","../../src/react/components/DeckView.tsx","../../src/react/components/SlideViewer.tsx"],"names":["useState","useRef","useMemo","renderSlide","useEffect","useCallback","jsx","jsxs","Fragment","themeName","renderMermaidDiagrams"],"mappings":"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","file":"index.cjs","sourcesContent":["// ═══════════════════════════════════════════════════════════════════════════════\n// useSlideState Hook — Centralized slide + click state management\n// ═══════════════════════════════════════════════════════════════════════════════\n\n'use client';\n\nimport { useState, useCallback, useMemo, useRef, useEffect } from 'react';\nimport { renderSlide } from '../../core/render.js';\nimport type { BuiltInTheme, SlideTheme, SlideRenderResult } from '../../types.js';\nimport type { SlideViewMode } from '../types.js';\n\nexport interface UseSlideStateOptions {\n markdown: string;\n initialTheme?: BuiltInTheme | SlideTheme;\n initialMode?: SlideViewMode;\n containerId?: string;\n /** Enable click-to-reveal system (default: false) */\n enableClicks?: boolean;\n}\n\nexport interface UseSlideStateReturn {\n // ── Render state ──\n /** Render result (null before first render) */\n result: SlideRenderResult | null;\n /** Whether initial render is complete */\n isReady: boolean;\n\n // ── Slide state ──\n /** Current slide index (0-based) */\n currentIndex: number;\n /** Total number of slides */\n slideCount: number;\n /** Current view mode */\n mode: SlideViewMode;\n /** Current theme */\n theme: BuiltInTheme | SlideTheme;\n\n // ── Click state ──\n /** Current click index (0 = nothing revealed, maxClicks = all revealed) */\n currentClick: number;\n /** Maximum clicks available on current slide */\n maxClicks: number;\n\n // ── Slide actions ──\n goToSlide: (index: number) => void;\n nextSlide: () => void;\n prevSlide: () => void;\n setMode: (mode: SlideViewMode) => void;\n setTheme: (theme: BuiltInTheme | SlideTheme) => void;\n rerender: () => void;\n\n // ── Click actions ──\n /** Advance to next click. If at max clicks, does nothing. */\n nextClick: () => void;\n /** Revert to previous click. If at 0, does nothing. */\n prevClick: () => void;\n /** Reset clicks to 0 (hide all click groups) */\n resetClicks: () => void;\n /** Set click index directly */\n setClickIndex: (index: number) => void;\n}\n\n/**\n * Centralized hook for slide + click state management.\n * Handles rendering, navigation, theme switching, mode toggling, and click-to-reveal.\n */\nexport function useSlideState(options: UseSlideStateOptions): UseSlideStateReturn {\n const {\n markdown,\n initialTheme = 'dark',\n initialMode = 'presentation',\n containerId,\n enableClicks = false,\n } = options;\n\n const [currentIndex, setCurrentIndex] = useState(0);\n const [mode, setMode] = useState<SlideViewMode>(initialMode);\n const [theme, setTheme] = useState<BuiltInTheme | SlideTheme>(initialTheme);\n const [currentClick, setCurrentClick] = useState(0);\n const renderCountRef = useRef(0);\n\n // Render slides synchronously (with click preprocessing if enabled)\n const result = useMemo(() => {\n if (!markdown || !markdown.trim()) return null;\n renderCountRef.current++;\n return renderSlide(markdown, {\n theme,\n enableMermaid: true,\n enableClicks,\n containerId: containerId ?? `slide-container-${renderCountRef.current}`,\n });\n }, [markdown, theme, containerId, enableClicks]);\n\n const slideCount = result?.slideCount ?? 1;\n const maxClicks = result?.maxClicks ?? 0;\n const isReady = result !== null;\n\n // Clamp currentIndex when slideCount changes\n useEffect(() => {\n if (result && currentIndex >= result.slideCount) {\n setCurrentIndex(Math.max(0, result.slideCount - 1));\n }\n }, [result?.slideCount, currentIndex]);\n\n // Reset clicks when slide changes\n useEffect(() => {\n setCurrentClick(0);\n }, [currentIndex]);\n\n // ── Slide navigation ──\n\n const goToSlide = useCallback(\n (index: number) => {\n setCurrentIndex(Math.max(0, Math.min(index, slideCount - 1)));\n },\n [slideCount],\n );\n\n const nextSlide = useCallback(() => {\n setCurrentIndex((prev) => Math.min(prev + 1, slideCount - 1));\n }, [slideCount]);\n\n const prevSlide = useCallback(() => {\n setCurrentIndex((prev) => Math.max(prev - 1, 0));\n }, []);\n\n // ── Click navigation ──\n\n const nextClick = useCallback(() => {\n setCurrentClick((prev) => Math.min(prev + 1, maxClicks));\n }, [maxClicks]);\n\n const prevClick = useCallback(() => {\n setCurrentClick((prev) => Math.max(prev - 1, 0));\n }, []);\n\n const resetClicks = useCallback(() => {\n setCurrentClick(0);\n }, []);\n\n const setClickIndex = useCallback(\n (index: number) => {\n setCurrentClick(Math.max(0, Math.min(index, maxClicks)));\n },\n [maxClicks],\n );\n\n // ── Combined navigation (click first, then slide) ──\n\n const goToSlideWithReset = useCallback(\n (index: number) => {\n setCurrentClick(0);\n setCurrentIndex(Math.max(0, Math.min(index, slideCount - 1)));\n },\n [slideCount],\n );\n\n const nextWithClick = useCallback(() => {\n if (currentClick < maxClicks) {\n // More clicks available — advance click\n setCurrentClick((prev) => prev + 1);\n } else {\n // No more clicks — go to next slide\n setCurrentClick(0);\n setCurrentIndex((prev) => Math.min(prev + 1, slideCount - 1));\n }\n }, [currentClick, maxClicks, slideCount]);\n\n const prevWithClick = useCallback(() => {\n if (currentClick > 0) {\n // Can revert click\n setCurrentClick((prev) => prev - 1);\n } else {\n // At click 0 — go to previous slide (and show all its clicks)\n setCurrentIndex((prev) => Math.max(prev - 1, 0));\n // Note: we don't set maxClicks here because it depends on the new slide's result\n // The consumer should handle this via useEffect on currentIndex change\n }\n }, [currentClick]);\n\n const rerender = useCallback(() => {\n setCurrentIndex((prev) => prev);\n }, []);\n\n return {\n // Render\n result,\n isReady,\n\n // Slide\n currentIndex,\n slideCount,\n mode,\n theme,\n\n // Click\n currentClick,\n maxClicks,\n\n // Slide actions\n goToSlide: goToSlideWithReset,\n nextSlide: nextWithClick,\n prevSlide: prevWithClick,\n setMode,\n setTheme,\n rerender,\n\n // Click actions\n nextClick,\n prevClick,\n resetClicks,\n setClickIndex,\n };\n}\n","// ═══════════════════════════════════════════════════════════════════════════════\n// ThemeSwitcher — Dark / Light / Navy toggle buttons\n// ═══════════════════════════════════════════════════════════════════════════════\n\n'use client';\n\nimport React from 'react';\nimport type { ThemeSwitcherProps, ThemeOption } from '../types.js';\n\n/** Default theme options */\nconst DEFAULT_THEMES: ThemeOption[] = [\n { id: 'dark', label: 'Dark' },\n { id: 'navy', label: 'Navy' },\n { id: 'light', label: 'Light' },\n];\n\n/**\n * ThemeSwitcher — Renders a row of theme toggle buttons.\n *\n * @example\n * ```tsx\n * <ThemeSwitcher currentTheme=\"dark\" onThemeChange={setTheme} />\n * ```\n */\nexport function ThemeSwitcher({\n currentTheme,\n onThemeChange,\n themes = DEFAULT_THEMES,\n className,\n}: ThemeSwitcherProps) {\n const currentId = typeof currentTheme === 'object' && currentTheme !== null && 'name' in currentTheme\n ? (currentTheme as { name: string }).name\n : String(currentTheme);\n\n return (\n <div\n className={className}\n style={{\n display: 'inline-flex',\n alignItems: 'center',\n gap: '2px',\n padding: '2px',\n borderRadius: '8px',\n border: '1px solid rgba(128, 128, 128, 0.2)',\n backgroundColor: 'rgba(128, 128, 128, 0.05)',\n }}\n >\n {themes.map((theme) => {\n const isActive = currentId === theme.id;\n return (\n <button\n key={theme.id}\n type=\"button\"\n onClick={() => onThemeChange(theme.id)}\n title={`Theme: ${theme.label}`}\n style={{\n height: '28px',\n padding: '0 10px',\n borderRadius: '6px',\n fontSize: '12px',\n fontFamily: 'inherit',\n fontWeight: isActive ? 600 : 400,\n display: 'flex',\n alignItems: 'center',\n gap: '5px',\n transition: 'all 0.15s ease',\n cursor: 'pointer',\n border: 'none',\n lineHeight: 1,\n whiteSpace: 'nowrap',\n backgroundColor: isActive ? 'rgba(128, 128, 128, 0.15)' : 'transparent',\n color: isActive ? 'currentColor' : 'rgba(128, 128, 128, 0.7)',\n }}\n >\n {theme.icon && <span style={{ fontSize: '13px' }}>{theme.icon}</span>}\n <span>{theme.label}</span>\n </button>\n );\n })}\n </div>\n );\n}\n","// ═══════════════════════════════════════════════════════════════════════════════\n// NavigationBar — Prev/Next, slide selector, mode toggle, copy\n// ═══════════════════════════════════════════════════════════════════════════════\n\n'use client';\n\nimport React, { useState, useCallback } from 'react';\nimport type { NavigationBarProps } from '../types.js';\n\nconst btnBase: React.CSSProperties = {\n height: '28px',\n borderRadius: '6px',\n fontSize: '12px',\n fontFamily: 'inherit',\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'center',\n gap: '5px',\n transition: 'all 0.15s ease',\n cursor: 'pointer',\n border: 'none',\n lineHeight: 1,\n whiteSpace: 'nowrap',\n};\n\nconst btnSecondary: React.CSSProperties = {\n ...btnBase,\n padding: '0 10px',\n backgroundColor: 'transparent',\n color: 'rgba(128, 128, 128, 0.7)',\n};\n\nconst btnActive: React.CSSProperties = {\n ...btnBase,\n padding: '0 10px',\n fontWeight: 600,\n backgroundColor: 'rgba(128, 128, 128, 0.15)',\n color: 'currentColor',\n};\n\nconst iconBtn: React.CSSProperties = {\n ...btnBase,\n width: '28px',\n padding: 0,\n backgroundColor: 'transparent',\n color: 'rgba(128, 128, 128, 0.7)',\n};\n\nconst disabledStyle: React.CSSProperties = {\n opacity: 0.3,\n cursor: 'not-allowed',\n};\n\n/**\n * NavigationBar — Renders slide navigation controls.\n *\n * @example\n * ```tsx\n * <NavigationBar\n * currentIndex={2}\n * slideCount={10}\n * onNavigate={setCurrentIndex}\n * mode=\"presentation\"\n * onModeChange={setMode}\n * />\n * ```\n */\nexport function NavigationBar({\n currentIndex,\n slideCount,\n onNavigate,\n mode,\n onModeChange,\n className,\n showCopy = true,\n markdown,\n}: NavigationBarProps) {\n const [copied, setCopied] = useState(false);\n\n const handleCopy = useCallback(async () => {\n if (!markdown) return;\n try {\n await navigator.clipboard.writeText(markdown);\n setCopied(true);\n setTimeout(() => setCopied(false), 2000);\n } catch {\n // Silently fail\n }\n }, [markdown]);\n\n const isFirst = currentIndex === 0;\n const isLast = currentIndex >= slideCount - 1;\n\n return (\n <div\n className={className}\n style={{\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'space-between',\n gap: '8px',\n padding: '8px 0',\n borderBottom: '1px solid rgba(128, 128, 128, 0.12)',\n flexWrap: 'wrap',\n }}\n >\n {/* Left: Mode toggle + Theme area (slots for parent) */}\n <div style={{ display: 'flex', alignItems: 'center', gap: '4px' }}>\n {/* Presentation mode button */}\n <button\n type=\"button\"\n onClick={() => onModeChange('presentation')}\n style={mode === 'presentation' ? btnActive : btnSecondary}\n title=\"Presentation mode (1 slide)\"\n >\n ▶ Presentation\n </button>\n\n {/* Deck mode button */}\n <button\n type=\"button\"\n onClick={() => onModeChange('deck')}\n style={mode === 'deck' ? btnActive : btnSecondary}\n title=\"Deck mode (all slides)\"\n >\n ☰ Deck\n </button>\n </div>\n\n {/* Right: Navigation + Actions */}\n <div style={{ display: 'flex', alignItems: 'center', gap: '4px' }}>\n {mode === 'presentation' && (\n <>\n {/* Previous */}\n <button\n type=\"button\"\n onClick={() => onNavigate(currentIndex - 1)}\n disabled={isFirst}\n style={{ ...iconBtn, ...(isFirst ? disabledStyle : {}) }}\n title=\"Previous slide (←)\"\n >\n ‹\n </button>\n\n {/* Slide selector */}\n <select\n value={currentIndex}\n onChange={(e) => onNavigate(Number(e.target.value))}\n style={{\n height: '28px',\n padding: '0 6px',\n borderRadius: '6px',\n fontSize: '12px',\n fontFamily: 'inherit',\n border: 'none',\n backgroundColor: 'transparent',\n color: 'currentColor',\n cursor: 'pointer',\n outline: 'none',\n }}\n title=\"Jump to slide\"\n >\n {Array.from({ length: slideCount }, (_, i) => (\n <option key={i} value={i}>\n Slide {i + 1} / {slideCount}\n </option>\n ))}\n </select>\n\n {/* Next */}\n <button\n type=\"button\"\n onClick={() => onNavigate(currentIndex + 1)}\n disabled={isLast}\n style={{ ...iconBtn, ...(isLast ? disabledStyle : {}) }}\n title=\"Next slide (→)\"\n >\n ›\n </button>\n </>\n )}\n\n {mode === 'deck' && (\n <span style={{ fontSize: '12px', color: 'rgba(128, 128, 128, 0.6)', padding: '0 8px' }}>\n {slideCount} slides\n </span>\n )}\n\n {/* Copy button */}\n {showCopy && markdown && (\n <button\n type=\"button\"\n onClick={handleCopy}\n style={btnSecondary}\n title=\"Copy markdown source\"\n >\n {copied ? '✓ Copied' : '⧉ Copy'}\n </button>\n )}\n </div>\n </div>\n );\n}\n","// ═══════════════════════════════════════════════════════════════════════════════\n// PresentationView — Single slide display with 16:9 aspect ratio\n// Shows one slide at a time, hides others with absolute positioning\n// ═══════════════════════════════════════════════════════════════════════════════\n\n'use client';\n\nimport React from 'react';\nimport type { PresentationViewProps } from '../types.js';\n\n/**\n * PresentationView — Renders a single slide at a time.\n *\n * All slides are rendered but hidden with absolute positioning.\n * Only the slide at `currentIndex` is visible.\n *\n * @example\n * ```tsx\n * <PresentationView\n * html={result.html}\n * css={result.css}\n * themeCss={result.themeCss}\n * currentIndex={0}\n * slideCount={5}\n * />\n * ```\n */\nexport function PresentationView({\n html,\n css,\n themeCss,\n currentIndex,\n slideCount,\n className,\n}: PresentationViewProps) {\n // Generate CSS to hide all slides except the current one\n const presentationCss = `\n .slide-presentation-host {\n display: flex;\n align-items: center;\n justify-content: center;\n width: 100%;\n }\n .slide-presentation-host > div {\n position: relative;\n display: flex;\n align-items: center;\n justify-content: center;\n width: 100%;\n }\n .slide-presentation-host > div > svg {\n position: absolute;\n visibility: hidden;\n opacity: 0;\n pointer-events: none;\n width: min(100%, calc((100vh - 120px) * (16 / 9)));\n max-width: 1400px;\n height: auto;\n max-height: calc(100vh - 120px);\n aspect-ratio: 16 / 9;\n margin: 0 auto;\n }\n .slide-presentation-host > div > svg:nth-child(${currentIndex + 1}) {\n position: relative;\n visibility: visible;\n opacity: 1;\n pointer-events: auto;\n display: block;\n }\n `;\n\n return (\n <div className={className} style={{ width: '100%' }}>\n {/* Marp base CSS */}\n <style>{css}</style>\n {/* Theme typography CSS */}\n <style>{themeCss}</style>\n {/* Presentation mode CSS */}\n <style>{presentationCss}</style>\n\n {/* Render all slides, only nth-child is visible */}\n <div\n className=\"slide-presentation-host\"\n style={{ padding: '16px 0' }}\n dangerouslySetInnerHTML={{ __html: html }}\n />\n </div>\n );\n}\n","// ═══════════════════════════════════════════════════════════════════════════════\n// DeckView — Vertical scroll of all slides (stacked cards)\n// Shows every slide in a scrollable list\n// ═══════════════════════════════════════════════════════════════════════════════\n\n'use client';\n\nimport React from 'react';\nimport type { DeckViewProps } from '../types.js';\n\n/**\n * DeckView — Renders all slides vertically in a scrollable list.\n *\n * Each slide is displayed as a 16:9 card with consistent spacing.\n *\n * @example\n * ```tsx\n * <DeckView\n * html={result.html}\n * css={result.css}\n * themeCss={result.themeCss}\n * slideCount={5}\n * />\n * ```\n */\nexport function DeckView({\n html,\n css,\n themeCss,\n slideCount,\n className,\n}: DeckViewProps) {\n // Generate CSS for deck layout\n const deckCss = `\n .slide-deck-host {\n display: flex;\n flex-direction: column;\n align-items: center;\n gap: 24px;\n padding: 16px 0;\n }\n .slide-deck-host > div {\n display: flex;\n flex-direction: column;\n align-items: center;\n gap: 24px;\n }\n .slide-deck-host > div > svg {\n display: block !important;\n width: 100% !important;\n max-width: 960px;\n height: auto !important;\n aspect-ratio: 16 / 9;\n border-radius: 12px;\n box-shadow: 0 2px 8px rgba(0, 0, 0, 0.06);\n }\n .slide-deck-host > div > svg:hover {\n box-shadow: 0 4px 16px rgba(0, 0, 0, 0.1);\n }\n `;\n\n return (\n <div className={className} style={{ width: '100%' }}>\n {/* Marp base CSS */}\n <style>{css}</style>\n {/* Theme typography CSS */}\n <style>{themeCss}</style>\n {/* Deck mode CSS */}\n <style>{deckCss}</style>\n\n {/* Render all slides stacked vertically */}\n <div\n className=\"slide-deck-host\"\n dangerouslySetInnerHTML={{ __html: html }}\n />\n </div>\n );\n}\n","// ═══════════════════════════════════════════════════════════════════════════════\n// SlideViewer — Complete slide viewer with theme, navigation, clicks, fullscreen\n//\n// Usage:\n// import { SlideViewer } from '@learnwell/presentation-kit/react';\n// <SlideViewer markdown={md} enableClicks fullscreen />\n// ═══════════════════════════════════════════════════════════════════════════════\n\n'use client';\n\nimport React, { useState, useEffect, useCallback } from 'react';\nimport { useSlideState } from '../hooks/useSlideState.js';\nimport { ThemeSwitcher } from './ThemeSwitcher.js';\nimport { NavigationBar } from './NavigationBar.js';\nimport { PresentationView } from './PresentationView.js';\nimport { DeckView } from './DeckView.js';\nimport { renderMermaidDiagrams } from '../../plugins/mermaid.js';\nimport type { SlideViewerProps, ThemeOption } from '../types.js';\nimport type { BuiltInTheme, SlideTheme } from '../../types.js';\n\n/** Default theme options for the switcher */\nconst DEFAULT_THEME_OPTIONS: ThemeOption[] = [\n { id: 'dark', label: 'Dark' },\n { id: 'navy', label: 'Navy' },\n { id: 'light', label: 'Light' },\n];\n\n/**\n * SlideViewer — Complete slide viewer component.\n *\n * Features:\n * - Client-side Marp rendering (no HTTP roundtrip)\n * - Theme switching (dark/light/navy + custom)\n * - Presentation mode (single slide + keyboard nav)\n * - Deck mode (vertical scroll)\n * - Click-to-reveal (<!-- click --> / <!-- clicks -->)\n * - Fullscreen mode (ESC to exit)\n * - Mermaid diagram rendering\n * - Copy markdown button\n */\nexport function SlideViewer({\n markdown,\n initialTheme = 'dark',\n initialMode = 'presentation',\n className,\n showThemeSwitcher = true,\n showNavigation = true,\n enableKeyboard = true,\n enableClicks = false,\n fullscreen = false,\n themeOptions = DEFAULT_THEME_OPTIONS,\n onThemeChange,\n onSlideChange,\n onModeChange,\n onRenderComplete,\n}: SlideViewerProps) {\n const [isFullscreen, setIsFullscreen] = useState(false);\n\n // Centralized state (with click support)\n const state = useSlideState({\n markdown,\n initialTheme,\n initialMode,\n enableClicks,\n });\n\n const {\n currentIndex, mode, theme, result, slideCount,\n currentClick, maxClicks,\n goToSlide, nextSlide, prevSlide, setMode, setTheme,\n nextClick, prevClick, resetClicks,\n } = state;\n\n // Notify parent of state changes\n useEffect(() => { onThemeChange?.(theme); }, [theme, onThemeChange]);\n useEffect(() => { onSlideChange?.(currentIndex); }, [currentIndex, onSlideChange]);\n useEffect(() => { onModeChange?.(mode); }, [mode, onModeChange]);\n useEffect(() => { if (result) onRenderComplete?.(result); }, [result, onRenderComplete]);\n\n // ── Keyboard navigation (click-aware + ESC for fullscreen) ──\n useEffect(() => {\n if (!enableKeyboard) return;\n\n const handleKey = (e: KeyboardEvent) => {\n if (e.target instanceof HTMLInputElement || e.target instanceof HTMLTextAreaElement) return;\n\n // ESC exits fullscreen (always active when fullscreen is enabled)\n if (e.key === 'Escape' && fullscreen && isFullscreen) {\n e.preventDefault();\n setIsFullscreen(false);\n return;\n }\n\n // Navigation only in presentation mode\n if (mode !== 'presentation') return;\n\n switch (e.key) {\n case 'ArrowRight':\n case 'PageDown':\n case ' ':\n e.preventDefault();\n if (enableClicks && currentClick < maxClicks) {\n nextClick();\n } else {\n nextSlide();\n }\n break;\n\n case 'ArrowLeft':\n case 'PageUp':\n e.preventDefault();\n if (enableClicks && currentClick > 0) {\n prevClick();\n } else {\n prevSlide();\n }\n break;\n\n case 'Home':\n e.preventDefault();\n goToSlide(0);\n break;\n\n case 'End':\n e.preventDefault();\n goToSlide(slideCount - 1);\n break;\n\n case 'f':\n case 'F':\n // F key toggles fullscreen (when fullscreen prop is enabled)\n if (fullscreen) {\n e.preventDefault();\n setIsFullscreen((prev) => !prev);\n }\n break;\n }\n };\n\n window.addEventListener('keydown', handleKey);\n return () => window.removeEventListener('keydown', handleKey);\n }, [enableKeyboard, mode, fullscreen, isFullscreen, enableClicks, currentClick, maxClicks, nextClick, prevClick, nextSlide, prevSlide, goToSlide, slideCount]);\n\n // ── Click visibility management (DOM-based, presentation mode only) ──\n useEffect(() => {\n if (!enableClicks || !result || mode !== 'presentation') return;\n\n const timer = setTimeout(() => {\n const container = document.querySelector('.slide-presentation-host > div');\n if (!container) return;\n\n container.querySelectorAll('[data-click-group]').forEach((el) => {\n const group = parseInt(el.getAttribute('data-click-group') ?? '0', 10);\n const isVisible = group <= currentClick;\n el.classList.toggle('visible', isVisible);\n });\n }, 50);\n\n return () => clearTimeout(timer);\n }, [enableClicks, currentClick, result, currentIndex, mode]);\n\n // ── Mermaid post-processing ──\n useEffect(() => {\n if (!result || result.mermaidBlocks.length === 0) return;\n\n const timer = setTimeout(() => {\n const containers = document.querySelectorAll('.slide-presentation-host > div, .slide-deck-host > div');\n containers.forEach((container) => {\n if (container instanceof HTMLElement) {\n const themeName = typeof theme === 'string' ? theme : 'dark';\n renderMermaidDiagrams(container, themeName as 'dark' | 'light' | 'navy').catch(() => {});\n }\n });\n }, 100);\n\n return () => clearTimeout(timer);\n }, [result, theme, currentIndex, mode]);\n\n // Handle theme change from ThemeSwitcher\n const handleThemeChange = useCallback(\n (themeId: string) => {\n setTheme(themeId as BuiltInTheme | SlideTheme);\n },\n [setTheme],\n );\n\n // Toggle fullscreen\n const toggleFullscreen = useCallback(() => {\n setIsFullscreen((prev) => !prev);\n }, []);\n\n // Loading state\n if (!result) {\n return (\n <div\n className={className}\n style={{\n display: 'flex', alignItems: 'center', justifyContent: 'center',\n padding: '80px 0', color: 'rgba(128, 128, 128, 0.5)',\n fontSize: '13px', fontFamily: 'inherit',\n }}\n >\n No slide content\n </div>\n );\n }\n\n const themeName = typeof theme === 'string' ? theme : theme.name;\n\n // ── Fullscreen CSS ──\n const fullscreenCss = fullscreen ? `\n .slide-viewer-fullscreen {\n position: fixed !important;\n inset: 0 !important;\n z-index: 9999 !important;\n background: #000 !important;\n padding: 24px !important;\n overflow-y: auto !important;\n display: flex !important;\n flex-direction: column !important;\n }\n .slide-viewer-fullscreen .slide-presentation-host {\n flex: 1 !important;\n display: flex !important;\n align-items: center !important;\n justify-content: center !important;\n }\n ` : '';\n\n return (\n <div\n className={`${className ?? ''} ${isFullscreen ? 'slide-viewer-fullscreen' : ''}`.trim()}\n style={{\n display: 'flex', flexDirection: 'column', width: '100%',\n gap: '12px',\n fontFamily: 'Inter, -apple-system, BlinkMacSystemFont, \"Segoe UI\", Roboto, sans-serif',\n ...(isFullscreen ? { background: '#000', color: '#fff' } : {}),\n }}\n >\n {/* Fullscreen CSS */}\n {fullscreen && <style>{fullscreenCss}</style>}\n\n {/* Click CSS injection (presentation mode only) */}\n {enableClicks && mode === 'presentation' && result.clickCss && <style>{result.clickCss}</style>}\n\n {/* Top bar: ThemeSwitcher + NavigationBar + Fullscreen button */}\n {(showThemeSwitcher || showNavigation || fullscreen) && (\n <div style={{\n display: 'flex', alignItems: 'center', justifyContent: 'space-between',\n gap: '12px', flexWrap: 'wrap',\n ...(isFullscreen ? { borderBottom: '1px solid rgba(255,255,255,0.1)', paddingBottom: '8px' } : {}),\n }}>\n <div style={{ display: 'flex', alignItems: 'center', gap: '8px' }}>\n {showThemeSwitcher && (\n <ThemeSwitcher\n currentTheme={themeName}\n onThemeChange={handleThemeChange}\n themes={themeOptions}\n />\n )}\n </div>\n\n <div style={{ display: 'flex', alignItems: 'center', gap: '8px' }}>\n {showNavigation && (\n <NavigationBar\n currentIndex={currentIndex}\n slideCount={slideCount}\n onNavigate={goToSlide}\n mode={mode}\n onModeChange={setMode}\n markdown={markdown}\n />\n )}\n\n {/* Fullscreen toggle button */}\n {fullscreen && (\n <button\n type=\"button\"\n onClick={toggleFullscreen}\n style={{\n height: '28px', padding: '0 10px', borderRadius: '6px',\n fontSize: '12px', fontFamily: 'inherit',\n display: 'flex', alignItems: 'center', gap: '5px',\n border: 'none', cursor: 'pointer',\n backgroundColor: 'transparent',\n color: isFullscreen ? '#fff' : 'rgba(128,128,128,0.7)',\n transition: 'all 0.15s ease',\n }}\n title={isFullscreen ? 'Exit fullscreen (ESC)' : 'Fullscreen (F)'}\n >\n {isFullscreen ? '⊡ Exit' : '⊞ Fullscreen'}\n </button>\n )}\n </div>\n </div>\n )}\n\n {/* Click progress indicator */}\n {enableClicks && maxClicks > 0 && mode === 'presentation' && (\n <div style={{\n display: 'flex', alignItems: 'center', gap: '8px',\n fontSize: '11px', color: isFullscreen ? 'rgba(255,255,255,0.5)' : 'rgba(128,128,128,0.5)',\n }}>\n <span>Click {currentClick} / {maxClicks}</span>\n <div style={{\n flex: 1, height: '2px', borderRadius: '1px',\n backgroundColor: isFullscreen ? 'rgba(255,255,255,0.1)' : 'rgba(128,128,128,0.1)',\n }}>\n <div style={{\n height: '100%', borderRadius: '1px',\n backgroundColor: isFullscreen ? 'rgba(255,255,255,0.3)' : 'rgba(128,128,128,0.3)',\n width: `${maxClicks > 0 ? (currentClick / maxClicks) * 100 : 0}%`,\n transition: 'width 0.2s ease',\n }} />\n </div>\n </div>\n )}\n\n {/* Slide view */}\n {mode === 'presentation' ? (\n <PresentationView\n html={result.html}\n css={result.css}\n themeCss={result.themeCss}\n currentIndex={currentIndex}\n slideCount={slideCount}\n />\n ) : (\n <DeckView\n html={result.html}\n css={result.css}\n themeCss={result.themeCss}\n slideCount={slideCount}\n />\n )}\n </div>\n );\n}\n"]}
|
|
@@ -0,0 +1,269 @@
|
|
|
1
|
+
import React$1 from 'react';
|
|
2
|
+
import { B as BuiltInTheme, n as SlideTheme, q as SlideRenderResult } from '../click-css-CadkoJ_A.cjs';
|
|
3
|
+
export { m as ClickCssOptions, l as ClickPostprocessResult, C as ClickPreprocessResult, M as MermaidBlock, s as SlideRenderAsyncResult, o as SlideRenderOptions, T as ThemeTokens, e as defineTheme, j as extractMaxClicks, k as generateClickCss, i as postprocessClicks, p as preprocessClicks, r as renderSlide, b as renderSlideAsync, f as resolveTheme } from '../click-css-CadkoJ_A.cjs';
|
|
4
|
+
|
|
5
|
+
/** View mode for slide display */
|
|
6
|
+
type SlideViewMode = 'presentation' | 'deck';
|
|
7
|
+
/** Theme option for ThemeSwitcher */
|
|
8
|
+
type ThemeOption = {
|
|
9
|
+
id: BuiltInTheme | string;
|
|
10
|
+
label: string;
|
|
11
|
+
/** Optional icon (React node) or emoji */
|
|
12
|
+
icon?: React.ReactNode;
|
|
13
|
+
};
|
|
14
|
+
/** Props for the main SlideViewer component */
|
|
15
|
+
interface SlideViewerProps {
|
|
16
|
+
/** Marp markdown source (with --- separators between slides) */
|
|
17
|
+
markdown: string;
|
|
18
|
+
/** Initial theme (default: 'dark') */
|
|
19
|
+
initialTheme?: BuiltInTheme | SlideTheme;
|
|
20
|
+
/** Initial view mode (default: 'presentation') */
|
|
21
|
+
initialMode?: SlideViewMode;
|
|
22
|
+
/** CSS class for the root container */
|
|
23
|
+
className?: string;
|
|
24
|
+
/** Show theme switcher (default: true) */
|
|
25
|
+
showThemeSwitcher?: boolean;
|
|
26
|
+
/** Show navigation bar (default: true) */
|
|
27
|
+
showNavigation?: boolean;
|
|
28
|
+
/** Enable keyboard navigation (default: true) */
|
|
29
|
+
enableKeyboard?: boolean;
|
|
30
|
+
/** Enable click-to-reveal system (<!-- click --> / <!-- clicks -->) (default: false) */
|
|
31
|
+
enableClicks?: boolean;
|
|
32
|
+
/** Enable fullscreen button + ESC to exit (default: false) */
|
|
33
|
+
fullscreen?: boolean;
|
|
34
|
+
/** Custom theme options for ThemeSwitcher */
|
|
35
|
+
themeOptions?: ThemeOption[];
|
|
36
|
+
/** Callback when theme changes */
|
|
37
|
+
onThemeChange?: (theme: BuiltInTheme | SlideTheme) => void;
|
|
38
|
+
/** Callback when slide changes */
|
|
39
|
+
onSlideChange?: (index: number) => void;
|
|
40
|
+
/** Callback when view mode changes */
|
|
41
|
+
onModeChange?: (mode: SlideViewMode) => void;
|
|
42
|
+
/** Callback when render completes */
|
|
43
|
+
onRenderComplete?: (result: SlideRenderResult) => void;
|
|
44
|
+
}
|
|
45
|
+
/** Props for PresentationView */
|
|
46
|
+
interface PresentationViewProps {
|
|
47
|
+
/** Rendered HTML from renderSlide() */
|
|
48
|
+
html: string;
|
|
49
|
+
/** Marp CSS */
|
|
50
|
+
css: string;
|
|
51
|
+
/** Theme scoped CSS */
|
|
52
|
+
themeCss: string;
|
|
53
|
+
/** Current slide index (0-based) */
|
|
54
|
+
currentIndex: number;
|
|
55
|
+
/** Total number of slides */
|
|
56
|
+
slideCount: number;
|
|
57
|
+
/** Container CSS class */
|
|
58
|
+
className?: string;
|
|
59
|
+
}
|
|
60
|
+
/** Props for DeckView */
|
|
61
|
+
interface DeckViewProps {
|
|
62
|
+
/** Rendered HTML from renderSlide() */
|
|
63
|
+
html: string;
|
|
64
|
+
/** Marp CSS */
|
|
65
|
+
css: string;
|
|
66
|
+
/** Theme scoped CSS */
|
|
67
|
+
themeCss: string;
|
|
68
|
+
/** Total number of slides */
|
|
69
|
+
slideCount: number;
|
|
70
|
+
/** Container CSS class */
|
|
71
|
+
className?: string;
|
|
72
|
+
}
|
|
73
|
+
/** Props for ThemeSwitcher */
|
|
74
|
+
interface ThemeSwitcherProps {
|
|
75
|
+
/** Currently active theme */
|
|
76
|
+
currentTheme: BuiltInTheme | string;
|
|
77
|
+
/** Callback when theme is selected */
|
|
78
|
+
onThemeChange: (theme: BuiltInTheme | string) => void;
|
|
79
|
+
/** Available theme options (default: dark/light/navy) */
|
|
80
|
+
themes?: ThemeOption[];
|
|
81
|
+
/** Container CSS class */
|
|
82
|
+
className?: string;
|
|
83
|
+
}
|
|
84
|
+
/** Props for NavigationBar */
|
|
85
|
+
interface NavigationBarProps {
|
|
86
|
+
/** Current slide index (0-based) */
|
|
87
|
+
currentIndex: number;
|
|
88
|
+
/** Total number of slides */
|
|
89
|
+
slideCount: number;
|
|
90
|
+
/** Callback when navigating to a slide */
|
|
91
|
+
onNavigate: (index: number) => void;
|
|
92
|
+
/** Current view mode */
|
|
93
|
+
mode: SlideViewMode;
|
|
94
|
+
/** Callback when mode is toggled */
|
|
95
|
+
onModeChange: (mode: SlideViewMode) => void;
|
|
96
|
+
/** Container CSS class */
|
|
97
|
+
className?: string;
|
|
98
|
+
/** Show copy button (default: true) */
|
|
99
|
+
showCopy?: boolean;
|
|
100
|
+
/** Raw markdown for copy functionality */
|
|
101
|
+
markdown?: string;
|
|
102
|
+
}
|
|
103
|
+
/** Internal state managed by useSlideState hook */
|
|
104
|
+
interface SlideState {
|
|
105
|
+
/** Current slide index */
|
|
106
|
+
currentIndex: number;
|
|
107
|
+
/** Total slides */
|
|
108
|
+
slideCount: number;
|
|
109
|
+
/** Current view mode */
|
|
110
|
+
mode: SlideViewMode;
|
|
111
|
+
/** Current theme */
|
|
112
|
+
theme: BuiltInTheme | SlideTheme;
|
|
113
|
+
/** Render result from the engine */
|
|
114
|
+
result: SlideRenderResult | null;
|
|
115
|
+
/** Whether initial render is complete */
|
|
116
|
+
isReady: boolean;
|
|
117
|
+
/** Current click index (0 = nothing revealed) */
|
|
118
|
+
currentClick: number;
|
|
119
|
+
/** Maximum clicks on current slide */
|
|
120
|
+
maxClicks: number;
|
|
121
|
+
}
|
|
122
|
+
/** Actions returned by useSlideState hook */
|
|
123
|
+
interface SlideActions {
|
|
124
|
+
/** Navigate to a specific slide (resets clicks) */
|
|
125
|
+
goToSlide: (index: number) => void;
|
|
126
|
+
/** Go to next slide or next click */
|
|
127
|
+
nextSlide: () => void;
|
|
128
|
+
/** Go to previous slide or previous click */
|
|
129
|
+
prevSlide: () => void;
|
|
130
|
+
/** Switch view mode */
|
|
131
|
+
setMode: (mode: SlideViewMode) => void;
|
|
132
|
+
/** Change theme */
|
|
133
|
+
setTheme: (theme: BuiltInTheme | SlideTheme) => void;
|
|
134
|
+
/** Re-render with current state */
|
|
135
|
+
rerender: () => void;
|
|
136
|
+
/** Advance to next click */
|
|
137
|
+
nextClick: () => void;
|
|
138
|
+
/** Revert to previous click */
|
|
139
|
+
prevClick: () => void;
|
|
140
|
+
/** Reset clicks to 0 */
|
|
141
|
+
resetClicks: () => void;
|
|
142
|
+
/** Set click index directly */
|
|
143
|
+
setClickIndex: (index: number) => void;
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
/**
|
|
147
|
+
* SlideViewer — Complete slide viewer component.
|
|
148
|
+
*
|
|
149
|
+
* Features:
|
|
150
|
+
* - Client-side Marp rendering (no HTTP roundtrip)
|
|
151
|
+
* - Theme switching (dark/light/navy + custom)
|
|
152
|
+
* - Presentation mode (single slide + keyboard nav)
|
|
153
|
+
* - Deck mode (vertical scroll)
|
|
154
|
+
* - Click-to-reveal (<!-- click --> / <!-- clicks -->)
|
|
155
|
+
* - Fullscreen mode (ESC to exit)
|
|
156
|
+
* - Mermaid diagram rendering
|
|
157
|
+
* - Copy markdown button
|
|
158
|
+
*/
|
|
159
|
+
declare function SlideViewer({ markdown, initialTheme, initialMode, className, showThemeSwitcher, showNavigation, enableKeyboard, enableClicks, fullscreen, themeOptions, onThemeChange, onSlideChange, onModeChange, onRenderComplete, }: SlideViewerProps): React$1.JSX.Element;
|
|
160
|
+
|
|
161
|
+
/**
|
|
162
|
+
* PresentationView — Renders a single slide at a time.
|
|
163
|
+
*
|
|
164
|
+
* All slides are rendered but hidden with absolute positioning.
|
|
165
|
+
* Only the slide at `currentIndex` is visible.
|
|
166
|
+
*
|
|
167
|
+
* @example
|
|
168
|
+
* ```tsx
|
|
169
|
+
* <PresentationView
|
|
170
|
+
* html={result.html}
|
|
171
|
+
* css={result.css}
|
|
172
|
+
* themeCss={result.themeCss}
|
|
173
|
+
* currentIndex={0}
|
|
174
|
+
* slideCount={5}
|
|
175
|
+
* />
|
|
176
|
+
* ```
|
|
177
|
+
*/
|
|
178
|
+
declare function PresentationView({ html, css, themeCss, currentIndex, slideCount, className, }: PresentationViewProps): React$1.JSX.Element;
|
|
179
|
+
|
|
180
|
+
/**
|
|
181
|
+
* DeckView — Renders all slides vertically in a scrollable list.
|
|
182
|
+
*
|
|
183
|
+
* Each slide is displayed as a 16:9 card with consistent spacing.
|
|
184
|
+
*
|
|
185
|
+
* @example
|
|
186
|
+
* ```tsx
|
|
187
|
+
* <DeckView
|
|
188
|
+
* html={result.html}
|
|
189
|
+
* css={result.css}
|
|
190
|
+
* themeCss={result.themeCss}
|
|
191
|
+
* slideCount={5}
|
|
192
|
+
* />
|
|
193
|
+
* ```
|
|
194
|
+
*/
|
|
195
|
+
declare function DeckView({ html, css, themeCss, slideCount, className, }: DeckViewProps): React$1.JSX.Element;
|
|
196
|
+
|
|
197
|
+
/**
|
|
198
|
+
* ThemeSwitcher — Renders a row of theme toggle buttons.
|
|
199
|
+
*
|
|
200
|
+
* @example
|
|
201
|
+
* ```tsx
|
|
202
|
+
* <ThemeSwitcher currentTheme="dark" onThemeChange={setTheme} />
|
|
203
|
+
* ```
|
|
204
|
+
*/
|
|
205
|
+
declare function ThemeSwitcher({ currentTheme, onThemeChange, themes, className, }: ThemeSwitcherProps): React$1.JSX.Element;
|
|
206
|
+
|
|
207
|
+
/**
|
|
208
|
+
* NavigationBar — Renders slide navigation controls.
|
|
209
|
+
*
|
|
210
|
+
* @example
|
|
211
|
+
* ```tsx
|
|
212
|
+
* <NavigationBar
|
|
213
|
+
* currentIndex={2}
|
|
214
|
+
* slideCount={10}
|
|
215
|
+
* onNavigate={setCurrentIndex}
|
|
216
|
+
* mode="presentation"
|
|
217
|
+
* onModeChange={setMode}
|
|
218
|
+
* />
|
|
219
|
+
* ```
|
|
220
|
+
*/
|
|
221
|
+
declare function NavigationBar({ currentIndex, slideCount, onNavigate, mode, onModeChange, className, showCopy, markdown, }: NavigationBarProps): React$1.JSX.Element;
|
|
222
|
+
|
|
223
|
+
interface UseSlideStateOptions {
|
|
224
|
+
markdown: string;
|
|
225
|
+
initialTheme?: BuiltInTheme | SlideTheme;
|
|
226
|
+
initialMode?: SlideViewMode;
|
|
227
|
+
containerId?: string;
|
|
228
|
+
/** Enable click-to-reveal system (default: false) */
|
|
229
|
+
enableClicks?: boolean;
|
|
230
|
+
}
|
|
231
|
+
interface UseSlideStateReturn {
|
|
232
|
+
/** Render result (null before first render) */
|
|
233
|
+
result: SlideRenderResult | null;
|
|
234
|
+
/** Whether initial render is complete */
|
|
235
|
+
isReady: boolean;
|
|
236
|
+
/** Current slide index (0-based) */
|
|
237
|
+
currentIndex: number;
|
|
238
|
+
/** Total number of slides */
|
|
239
|
+
slideCount: number;
|
|
240
|
+
/** Current view mode */
|
|
241
|
+
mode: SlideViewMode;
|
|
242
|
+
/** Current theme */
|
|
243
|
+
theme: BuiltInTheme | SlideTheme;
|
|
244
|
+
/** Current click index (0 = nothing revealed, maxClicks = all revealed) */
|
|
245
|
+
currentClick: number;
|
|
246
|
+
/** Maximum clicks available on current slide */
|
|
247
|
+
maxClicks: number;
|
|
248
|
+
goToSlide: (index: number) => void;
|
|
249
|
+
nextSlide: () => void;
|
|
250
|
+
prevSlide: () => void;
|
|
251
|
+
setMode: (mode: SlideViewMode) => void;
|
|
252
|
+
setTheme: (theme: BuiltInTheme | SlideTheme) => void;
|
|
253
|
+
rerender: () => void;
|
|
254
|
+
/** Advance to next click. If at max clicks, does nothing. */
|
|
255
|
+
nextClick: () => void;
|
|
256
|
+
/** Revert to previous click. If at 0, does nothing. */
|
|
257
|
+
prevClick: () => void;
|
|
258
|
+
/** Reset clicks to 0 (hide all click groups) */
|
|
259
|
+
resetClicks: () => void;
|
|
260
|
+
/** Set click index directly */
|
|
261
|
+
setClickIndex: (index: number) => void;
|
|
262
|
+
}
|
|
263
|
+
/**
|
|
264
|
+
* Centralized hook for slide + click state management.
|
|
265
|
+
* Handles rendering, navigation, theme switching, mode toggling, and click-to-reveal.
|
|
266
|
+
*/
|
|
267
|
+
declare function useSlideState(options: UseSlideStateOptions): UseSlideStateReturn;
|
|
268
|
+
|
|
269
|
+
export { BuiltInTheme, DeckView, type DeckViewProps, NavigationBar, type NavigationBarProps, PresentationView, type PresentationViewProps, type SlideActions, SlideRenderResult, type SlideState, SlideTheme, type SlideViewMode, SlideViewer, type SlideViewerProps, type ThemeOption, ThemeSwitcher, type ThemeSwitcherProps, type UseSlideStateOptions, type UseSlideStateReturn, useSlideState };
|
|
@@ -0,0 +1,269 @@
|
|
|
1
|
+
import React$1 from 'react';
|
|
2
|
+
import { B as BuiltInTheme, n as SlideTheme, q as SlideRenderResult } from '../click-css-CadkoJ_A.js';
|
|
3
|
+
export { m as ClickCssOptions, l as ClickPostprocessResult, C as ClickPreprocessResult, M as MermaidBlock, s as SlideRenderAsyncResult, o as SlideRenderOptions, T as ThemeTokens, e as defineTheme, j as extractMaxClicks, k as generateClickCss, i as postprocessClicks, p as preprocessClicks, r as renderSlide, b as renderSlideAsync, f as resolveTheme } from '../click-css-CadkoJ_A.js';
|
|
4
|
+
|
|
5
|
+
/** View mode for slide display */
|
|
6
|
+
type SlideViewMode = 'presentation' | 'deck';
|
|
7
|
+
/** Theme option for ThemeSwitcher */
|
|
8
|
+
type ThemeOption = {
|
|
9
|
+
id: BuiltInTheme | string;
|
|
10
|
+
label: string;
|
|
11
|
+
/** Optional icon (React node) or emoji */
|
|
12
|
+
icon?: React.ReactNode;
|
|
13
|
+
};
|
|
14
|
+
/** Props for the main SlideViewer component */
|
|
15
|
+
interface SlideViewerProps {
|
|
16
|
+
/** Marp markdown source (with --- separators between slides) */
|
|
17
|
+
markdown: string;
|
|
18
|
+
/** Initial theme (default: 'dark') */
|
|
19
|
+
initialTheme?: BuiltInTheme | SlideTheme;
|
|
20
|
+
/** Initial view mode (default: 'presentation') */
|
|
21
|
+
initialMode?: SlideViewMode;
|
|
22
|
+
/** CSS class for the root container */
|
|
23
|
+
className?: string;
|
|
24
|
+
/** Show theme switcher (default: true) */
|
|
25
|
+
showThemeSwitcher?: boolean;
|
|
26
|
+
/** Show navigation bar (default: true) */
|
|
27
|
+
showNavigation?: boolean;
|
|
28
|
+
/** Enable keyboard navigation (default: true) */
|
|
29
|
+
enableKeyboard?: boolean;
|
|
30
|
+
/** Enable click-to-reveal system (<!-- click --> / <!-- clicks -->) (default: false) */
|
|
31
|
+
enableClicks?: boolean;
|
|
32
|
+
/** Enable fullscreen button + ESC to exit (default: false) */
|
|
33
|
+
fullscreen?: boolean;
|
|
34
|
+
/** Custom theme options for ThemeSwitcher */
|
|
35
|
+
themeOptions?: ThemeOption[];
|
|
36
|
+
/** Callback when theme changes */
|
|
37
|
+
onThemeChange?: (theme: BuiltInTheme | SlideTheme) => void;
|
|
38
|
+
/** Callback when slide changes */
|
|
39
|
+
onSlideChange?: (index: number) => void;
|
|
40
|
+
/** Callback when view mode changes */
|
|
41
|
+
onModeChange?: (mode: SlideViewMode) => void;
|
|
42
|
+
/** Callback when render completes */
|
|
43
|
+
onRenderComplete?: (result: SlideRenderResult) => void;
|
|
44
|
+
}
|
|
45
|
+
/** Props for PresentationView */
|
|
46
|
+
interface PresentationViewProps {
|
|
47
|
+
/** Rendered HTML from renderSlide() */
|
|
48
|
+
html: string;
|
|
49
|
+
/** Marp CSS */
|
|
50
|
+
css: string;
|
|
51
|
+
/** Theme scoped CSS */
|
|
52
|
+
themeCss: string;
|
|
53
|
+
/** Current slide index (0-based) */
|
|
54
|
+
currentIndex: number;
|
|
55
|
+
/** Total number of slides */
|
|
56
|
+
slideCount: number;
|
|
57
|
+
/** Container CSS class */
|
|
58
|
+
className?: string;
|
|
59
|
+
}
|
|
60
|
+
/** Props for DeckView */
|
|
61
|
+
interface DeckViewProps {
|
|
62
|
+
/** Rendered HTML from renderSlide() */
|
|
63
|
+
html: string;
|
|
64
|
+
/** Marp CSS */
|
|
65
|
+
css: string;
|
|
66
|
+
/** Theme scoped CSS */
|
|
67
|
+
themeCss: string;
|
|
68
|
+
/** Total number of slides */
|
|
69
|
+
slideCount: number;
|
|
70
|
+
/** Container CSS class */
|
|
71
|
+
className?: string;
|
|
72
|
+
}
|
|
73
|
+
/** Props for ThemeSwitcher */
|
|
74
|
+
interface ThemeSwitcherProps {
|
|
75
|
+
/** Currently active theme */
|
|
76
|
+
currentTheme: BuiltInTheme | string;
|
|
77
|
+
/** Callback when theme is selected */
|
|
78
|
+
onThemeChange: (theme: BuiltInTheme | string) => void;
|
|
79
|
+
/** Available theme options (default: dark/light/navy) */
|
|
80
|
+
themes?: ThemeOption[];
|
|
81
|
+
/** Container CSS class */
|
|
82
|
+
className?: string;
|
|
83
|
+
}
|
|
84
|
+
/** Props for NavigationBar */
|
|
85
|
+
interface NavigationBarProps {
|
|
86
|
+
/** Current slide index (0-based) */
|
|
87
|
+
currentIndex: number;
|
|
88
|
+
/** Total number of slides */
|
|
89
|
+
slideCount: number;
|
|
90
|
+
/** Callback when navigating to a slide */
|
|
91
|
+
onNavigate: (index: number) => void;
|
|
92
|
+
/** Current view mode */
|
|
93
|
+
mode: SlideViewMode;
|
|
94
|
+
/** Callback when mode is toggled */
|
|
95
|
+
onModeChange: (mode: SlideViewMode) => void;
|
|
96
|
+
/** Container CSS class */
|
|
97
|
+
className?: string;
|
|
98
|
+
/** Show copy button (default: true) */
|
|
99
|
+
showCopy?: boolean;
|
|
100
|
+
/** Raw markdown for copy functionality */
|
|
101
|
+
markdown?: string;
|
|
102
|
+
}
|
|
103
|
+
/** Internal state managed by useSlideState hook */
|
|
104
|
+
interface SlideState {
|
|
105
|
+
/** Current slide index */
|
|
106
|
+
currentIndex: number;
|
|
107
|
+
/** Total slides */
|
|
108
|
+
slideCount: number;
|
|
109
|
+
/** Current view mode */
|
|
110
|
+
mode: SlideViewMode;
|
|
111
|
+
/** Current theme */
|
|
112
|
+
theme: BuiltInTheme | SlideTheme;
|
|
113
|
+
/** Render result from the engine */
|
|
114
|
+
result: SlideRenderResult | null;
|
|
115
|
+
/** Whether initial render is complete */
|
|
116
|
+
isReady: boolean;
|
|
117
|
+
/** Current click index (0 = nothing revealed) */
|
|
118
|
+
currentClick: number;
|
|
119
|
+
/** Maximum clicks on current slide */
|
|
120
|
+
maxClicks: number;
|
|
121
|
+
}
|
|
122
|
+
/** Actions returned by useSlideState hook */
|
|
123
|
+
interface SlideActions {
|
|
124
|
+
/** Navigate to a specific slide (resets clicks) */
|
|
125
|
+
goToSlide: (index: number) => void;
|
|
126
|
+
/** Go to next slide or next click */
|
|
127
|
+
nextSlide: () => void;
|
|
128
|
+
/** Go to previous slide or previous click */
|
|
129
|
+
prevSlide: () => void;
|
|
130
|
+
/** Switch view mode */
|
|
131
|
+
setMode: (mode: SlideViewMode) => void;
|
|
132
|
+
/** Change theme */
|
|
133
|
+
setTheme: (theme: BuiltInTheme | SlideTheme) => void;
|
|
134
|
+
/** Re-render with current state */
|
|
135
|
+
rerender: () => void;
|
|
136
|
+
/** Advance to next click */
|
|
137
|
+
nextClick: () => void;
|
|
138
|
+
/** Revert to previous click */
|
|
139
|
+
prevClick: () => void;
|
|
140
|
+
/** Reset clicks to 0 */
|
|
141
|
+
resetClicks: () => void;
|
|
142
|
+
/** Set click index directly */
|
|
143
|
+
setClickIndex: (index: number) => void;
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
/**
|
|
147
|
+
* SlideViewer — Complete slide viewer component.
|
|
148
|
+
*
|
|
149
|
+
* Features:
|
|
150
|
+
* - Client-side Marp rendering (no HTTP roundtrip)
|
|
151
|
+
* - Theme switching (dark/light/navy + custom)
|
|
152
|
+
* - Presentation mode (single slide + keyboard nav)
|
|
153
|
+
* - Deck mode (vertical scroll)
|
|
154
|
+
* - Click-to-reveal (<!-- click --> / <!-- clicks -->)
|
|
155
|
+
* - Fullscreen mode (ESC to exit)
|
|
156
|
+
* - Mermaid diagram rendering
|
|
157
|
+
* - Copy markdown button
|
|
158
|
+
*/
|
|
159
|
+
declare function SlideViewer({ markdown, initialTheme, initialMode, className, showThemeSwitcher, showNavigation, enableKeyboard, enableClicks, fullscreen, themeOptions, onThemeChange, onSlideChange, onModeChange, onRenderComplete, }: SlideViewerProps): React$1.JSX.Element;
|
|
160
|
+
|
|
161
|
+
/**
|
|
162
|
+
* PresentationView — Renders a single slide at a time.
|
|
163
|
+
*
|
|
164
|
+
* All slides are rendered but hidden with absolute positioning.
|
|
165
|
+
* Only the slide at `currentIndex` is visible.
|
|
166
|
+
*
|
|
167
|
+
* @example
|
|
168
|
+
* ```tsx
|
|
169
|
+
* <PresentationView
|
|
170
|
+
* html={result.html}
|
|
171
|
+
* css={result.css}
|
|
172
|
+
* themeCss={result.themeCss}
|
|
173
|
+
* currentIndex={0}
|
|
174
|
+
* slideCount={5}
|
|
175
|
+
* />
|
|
176
|
+
* ```
|
|
177
|
+
*/
|
|
178
|
+
declare function PresentationView({ html, css, themeCss, currentIndex, slideCount, className, }: PresentationViewProps): React$1.JSX.Element;
|
|
179
|
+
|
|
180
|
+
/**
|
|
181
|
+
* DeckView — Renders all slides vertically in a scrollable list.
|
|
182
|
+
*
|
|
183
|
+
* Each slide is displayed as a 16:9 card with consistent spacing.
|
|
184
|
+
*
|
|
185
|
+
* @example
|
|
186
|
+
* ```tsx
|
|
187
|
+
* <DeckView
|
|
188
|
+
* html={result.html}
|
|
189
|
+
* css={result.css}
|
|
190
|
+
* themeCss={result.themeCss}
|
|
191
|
+
* slideCount={5}
|
|
192
|
+
* />
|
|
193
|
+
* ```
|
|
194
|
+
*/
|
|
195
|
+
declare function DeckView({ html, css, themeCss, slideCount, className, }: DeckViewProps): React$1.JSX.Element;
|
|
196
|
+
|
|
197
|
+
/**
|
|
198
|
+
* ThemeSwitcher — Renders a row of theme toggle buttons.
|
|
199
|
+
*
|
|
200
|
+
* @example
|
|
201
|
+
* ```tsx
|
|
202
|
+
* <ThemeSwitcher currentTheme="dark" onThemeChange={setTheme} />
|
|
203
|
+
* ```
|
|
204
|
+
*/
|
|
205
|
+
declare function ThemeSwitcher({ currentTheme, onThemeChange, themes, className, }: ThemeSwitcherProps): React$1.JSX.Element;
|
|
206
|
+
|
|
207
|
+
/**
|
|
208
|
+
* NavigationBar — Renders slide navigation controls.
|
|
209
|
+
*
|
|
210
|
+
* @example
|
|
211
|
+
* ```tsx
|
|
212
|
+
* <NavigationBar
|
|
213
|
+
* currentIndex={2}
|
|
214
|
+
* slideCount={10}
|
|
215
|
+
* onNavigate={setCurrentIndex}
|
|
216
|
+
* mode="presentation"
|
|
217
|
+
* onModeChange={setMode}
|
|
218
|
+
* />
|
|
219
|
+
* ```
|
|
220
|
+
*/
|
|
221
|
+
declare function NavigationBar({ currentIndex, slideCount, onNavigate, mode, onModeChange, className, showCopy, markdown, }: NavigationBarProps): React$1.JSX.Element;
|
|
222
|
+
|
|
223
|
+
interface UseSlideStateOptions {
|
|
224
|
+
markdown: string;
|
|
225
|
+
initialTheme?: BuiltInTheme | SlideTheme;
|
|
226
|
+
initialMode?: SlideViewMode;
|
|
227
|
+
containerId?: string;
|
|
228
|
+
/** Enable click-to-reveal system (default: false) */
|
|
229
|
+
enableClicks?: boolean;
|
|
230
|
+
}
|
|
231
|
+
interface UseSlideStateReturn {
|
|
232
|
+
/** Render result (null before first render) */
|
|
233
|
+
result: SlideRenderResult | null;
|
|
234
|
+
/** Whether initial render is complete */
|
|
235
|
+
isReady: boolean;
|
|
236
|
+
/** Current slide index (0-based) */
|
|
237
|
+
currentIndex: number;
|
|
238
|
+
/** Total number of slides */
|
|
239
|
+
slideCount: number;
|
|
240
|
+
/** Current view mode */
|
|
241
|
+
mode: SlideViewMode;
|
|
242
|
+
/** Current theme */
|
|
243
|
+
theme: BuiltInTheme | SlideTheme;
|
|
244
|
+
/** Current click index (0 = nothing revealed, maxClicks = all revealed) */
|
|
245
|
+
currentClick: number;
|
|
246
|
+
/** Maximum clicks available on current slide */
|
|
247
|
+
maxClicks: number;
|
|
248
|
+
goToSlide: (index: number) => void;
|
|
249
|
+
nextSlide: () => void;
|
|
250
|
+
prevSlide: () => void;
|
|
251
|
+
setMode: (mode: SlideViewMode) => void;
|
|
252
|
+
setTheme: (theme: BuiltInTheme | SlideTheme) => void;
|
|
253
|
+
rerender: () => void;
|
|
254
|
+
/** Advance to next click. If at max clicks, does nothing. */
|
|
255
|
+
nextClick: () => void;
|
|
256
|
+
/** Revert to previous click. If at 0, does nothing. */
|
|
257
|
+
prevClick: () => void;
|
|
258
|
+
/** Reset clicks to 0 (hide all click groups) */
|
|
259
|
+
resetClicks: () => void;
|
|
260
|
+
/** Set click index directly */
|
|
261
|
+
setClickIndex: (index: number) => void;
|
|
262
|
+
}
|
|
263
|
+
/**
|
|
264
|
+
* Centralized hook for slide + click state management.
|
|
265
|
+
* Handles rendering, navigation, theme switching, mode toggling, and click-to-reveal.
|
|
266
|
+
*/
|
|
267
|
+
declare function useSlideState(options: UseSlideStateOptions): UseSlideStateReturn;
|
|
268
|
+
|
|
269
|
+
export { BuiltInTheme, DeckView, type DeckViewProps, NavigationBar, type NavigationBarProps, PresentationView, type PresentationViewProps, type SlideActions, SlideRenderResult, type SlideState, SlideTheme, type SlideViewMode, SlideViewer, type SlideViewerProps, type ThemeOption, ThemeSwitcher, type ThemeSwitcherProps, type UseSlideStateOptions, type UseSlideStateReturn, useSlideState };
|