@thanh01.pmt/presentation-kit 0.1.0 → 0.1.1
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/dist/react/index.cjs +54 -40
- package/dist/react/index.cjs.map +1 -1
- package/dist/react/index.js +54 -40
- package/dist/react/index.js.map +1 -1
- package/package.json +1 -1
package/dist/react/index.cjs
CHANGED
|
@@ -355,36 +355,37 @@ function PresentationView({
|
|
|
355
355
|
}) {
|
|
356
356
|
const presentationCss = `
|
|
357
357
|
.slide-presentation-host {
|
|
358
|
-
display: flex;
|
|
359
|
-
align-items: center;
|
|
360
|
-
justify-content: center;
|
|
361
|
-
width: 100
|
|
358
|
+
display: flex !important;
|
|
359
|
+
align-items: center !important;
|
|
360
|
+
justify-content: center !important;
|
|
361
|
+
width: 100% !important;
|
|
362
362
|
}
|
|
363
363
|
.slide-presentation-host > div {
|
|
364
|
-
position: relative;
|
|
365
|
-
display: flex;
|
|
366
|
-
align-items: center;
|
|
367
|
-
justify-content: center;
|
|
368
|
-
width: 100
|
|
364
|
+
position: relative !important;
|
|
365
|
+
display: flex !important;
|
|
366
|
+
align-items: center !important;
|
|
367
|
+
justify-content: center !important;
|
|
368
|
+
width: 100% !important;
|
|
369
369
|
}
|
|
370
|
+
.slide-presentation-host #marp-container svg[data-marpit-svg],
|
|
371
|
+
.slide-presentation-host #marp-container > svg,
|
|
370
372
|
.slide-presentation-host > div > svg {
|
|
371
|
-
|
|
372
|
-
visibility: hidden;
|
|
373
|
-
opacity: 0;
|
|
374
|
-
pointer-events: none;
|
|
375
|
-
width: min(100%, calc((100vh - 120px) * (16 / 9)));
|
|
376
|
-
max-width: 1400px;
|
|
377
|
-
height: auto;
|
|
378
|
-
max-height: calc(100vh - 120px);
|
|
379
|
-
aspect-ratio: 16 / 9;
|
|
380
|
-
margin: 0 auto;
|
|
373
|
+
display: none !important;
|
|
381
374
|
}
|
|
382
|
-
.slide-presentation-host
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
375
|
+
.slide-presentation-host #marp-container svg[data-marpit-svg]:nth-of-type(${currentIndex + 1}),
|
|
376
|
+
.slide-presentation-host #marp-container > svg:nth-of-type(${currentIndex + 1}),
|
|
377
|
+
.slide-presentation-host > div > svg:nth-of-type(${currentIndex + 1}) {
|
|
378
|
+
display: block !important;
|
|
379
|
+
position: relative !important;
|
|
380
|
+
visibility: visible !important;
|
|
381
|
+
opacity: 1 !important;
|
|
382
|
+
pointer-events: auto !important;
|
|
383
|
+
width: min(100%, calc((100vh - 120px) * 16 / 9)) !important;
|
|
384
|
+
max-width: 1400px !important;
|
|
385
|
+
height: auto !important;
|
|
386
|
+
max-height: calc(100vh - 120px) !important;
|
|
387
|
+
aspect-ratio: 16 / 9 !important;
|
|
388
|
+
margin: 0 auto !important;
|
|
388
389
|
}
|
|
389
390
|
`;
|
|
390
391
|
return /* @__PURE__ */ jsxRuntime.jsxs("div", { className, style: { width: "100%" }, children: [
|
|
@@ -410,29 +411,42 @@ function DeckView({
|
|
|
410
411
|
}) {
|
|
411
412
|
const deckCss = `
|
|
412
413
|
.slide-deck-host {
|
|
413
|
-
display: flex;
|
|
414
|
-
flex-direction: column;
|
|
415
|
-
align-items: center;
|
|
416
|
-
|
|
417
|
-
padding: 16px 0;
|
|
414
|
+
display: flex !important;
|
|
415
|
+
flex-direction: column !important;
|
|
416
|
+
align-items: center !important;
|
|
417
|
+
width: 100% !important;
|
|
418
|
+
padding: 16px 0 !important;
|
|
418
419
|
}
|
|
419
|
-
.slide-deck-host > div
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
|
|
420
|
+
.slide-deck-host > div,
|
|
421
|
+
.slide-deck-host #marp-container {
|
|
422
|
+
display: flex !important;
|
|
423
|
+
flex-direction: column !important;
|
|
424
|
+
align-items: center !important;
|
|
425
|
+
width: 100% !important;
|
|
424
426
|
}
|
|
427
|
+
.slide-deck-host #marp-container svg[data-marpit-svg],
|
|
428
|
+
.slide-deck-host #marp-container > svg,
|
|
425
429
|
.slide-deck-host > div > svg {
|
|
426
430
|
display: block !important;
|
|
427
431
|
width: 100% !important;
|
|
428
|
-
max-width: 960px;
|
|
432
|
+
max-width: 960px !important;
|
|
429
433
|
height: auto !important;
|
|
430
|
-
aspect-ratio: 16 / 9;
|
|
431
|
-
|
|
432
|
-
|
|
434
|
+
aspect-ratio: 16 / 9 !important;
|
|
435
|
+
margin: 0 auto 32px auto !important;
|
|
436
|
+
border-radius: 12px !important;
|
|
437
|
+
box-shadow: 0 4px 16px rgba(0, 0, 0, 0.12) !important;
|
|
438
|
+
transition: transform 0.2s ease, box-shadow 0.2s ease !important;
|
|
439
|
+
}
|
|
440
|
+
.slide-deck-host #marp-container svg[data-marpit-svg]:last-of-type,
|
|
441
|
+
.slide-deck-host #marp-container > svg:last-of-type,
|
|
442
|
+
.slide-deck-host > div > svg:last-of-type {
|
|
443
|
+
margin-bottom: 0 !important;
|
|
433
444
|
}
|
|
445
|
+
.slide-deck-host #marp-container svg[data-marpit-svg]:hover,
|
|
446
|
+
.slide-deck-host #marp-container > svg:hover,
|
|
434
447
|
.slide-deck-host > div > svg:hover {
|
|
435
|
-
|
|
448
|
+
transform: translateY(-2px);
|
|
449
|
+
box-shadow: 0 8px 24px rgba(0, 0, 0, 0.2) !important;
|
|
436
450
|
}
|
|
437
451
|
`;
|
|
438
452
|
return /* @__PURE__ */ jsxRuntime.jsxs("div", { className, style: { width: "100%" }, children: [
|
package/dist/react/index.cjs.map
CHANGED
|
@@ -1 +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"]}
|
|
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 !important;\n align-items: center !important;\n justify-content: center !important;\n width: 100% !important;\n }\n .slide-presentation-host > div {\n position: relative !important;\n display: flex !important;\n align-items: center !important;\n justify-content: center !important;\n width: 100% !important;\n }\n .slide-presentation-host #marp-container svg[data-marpit-svg],\n .slide-presentation-host #marp-container > svg,\n .slide-presentation-host > div > svg {\n display: none !important;\n }\n .slide-presentation-host #marp-container svg[data-marpit-svg]:nth-of-type(${currentIndex + 1}),\n .slide-presentation-host #marp-container > svg:nth-of-type(${currentIndex + 1}),\n .slide-presentation-host > div > svg:nth-of-type(${currentIndex + 1}) {\n display: block !important;\n position: relative !important;\n visibility: visible !important;\n opacity: 1 !important;\n pointer-events: auto !important;\n width: min(100%, calc((100vh - 120px) * 16 / 9)) !important;\n max-width: 1400px !important;\n height: auto !important;\n max-height: calc(100vh - 120px) !important;\n aspect-ratio: 16 / 9 !important;\n margin: 0 auto !important;\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 !important;\n flex-direction: column !important;\n align-items: center !important;\n width: 100% !important;\n padding: 16px 0 !important;\n }\n .slide-deck-host > div,\n .slide-deck-host #marp-container {\n display: flex !important;\n flex-direction: column !important;\n align-items: center !important;\n width: 100% !important;\n }\n .slide-deck-host #marp-container svg[data-marpit-svg],\n .slide-deck-host #marp-container > svg,\n .slide-deck-host > div > svg {\n display: block !important;\n width: 100% !important;\n max-width: 960px !important;\n height: auto !important;\n aspect-ratio: 16 / 9 !important;\n margin: 0 auto 32px auto !important;\n border-radius: 12px !important;\n box-shadow: 0 4px 16px rgba(0, 0, 0, 0.12) !important;\n transition: transform 0.2s ease, box-shadow 0.2s ease !important;\n }\n .slide-deck-host #marp-container svg[data-marpit-svg]:last-of-type,\n .slide-deck-host #marp-container > svg:last-of-type,\n .slide-deck-host > div > svg:last-of-type {\n margin-bottom: 0 !important;\n }\n .slide-deck-host #marp-container svg[data-marpit-svg]:hover,\n .slide-deck-host #marp-container > svg:hover,\n .slide-deck-host > div > svg:hover {\n transform: translateY(-2px);\n box-shadow: 0 8px 24px rgba(0, 0, 0, 0.2) !important;\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"]}
|
package/dist/react/index.js
CHANGED
|
@@ -354,36 +354,37 @@ function PresentationView({
|
|
|
354
354
|
}) {
|
|
355
355
|
const presentationCss = `
|
|
356
356
|
.slide-presentation-host {
|
|
357
|
-
display: flex;
|
|
358
|
-
align-items: center;
|
|
359
|
-
justify-content: center;
|
|
360
|
-
width: 100
|
|
357
|
+
display: flex !important;
|
|
358
|
+
align-items: center !important;
|
|
359
|
+
justify-content: center !important;
|
|
360
|
+
width: 100% !important;
|
|
361
361
|
}
|
|
362
362
|
.slide-presentation-host > div {
|
|
363
|
-
position: relative;
|
|
364
|
-
display: flex;
|
|
365
|
-
align-items: center;
|
|
366
|
-
justify-content: center;
|
|
367
|
-
width: 100
|
|
363
|
+
position: relative !important;
|
|
364
|
+
display: flex !important;
|
|
365
|
+
align-items: center !important;
|
|
366
|
+
justify-content: center !important;
|
|
367
|
+
width: 100% !important;
|
|
368
368
|
}
|
|
369
|
+
.slide-presentation-host #marp-container svg[data-marpit-svg],
|
|
370
|
+
.slide-presentation-host #marp-container > svg,
|
|
369
371
|
.slide-presentation-host > div > svg {
|
|
370
|
-
|
|
371
|
-
visibility: hidden;
|
|
372
|
-
opacity: 0;
|
|
373
|
-
pointer-events: none;
|
|
374
|
-
width: min(100%, calc((100vh - 120px) * (16 / 9)));
|
|
375
|
-
max-width: 1400px;
|
|
376
|
-
height: auto;
|
|
377
|
-
max-height: calc(100vh - 120px);
|
|
378
|
-
aspect-ratio: 16 / 9;
|
|
379
|
-
margin: 0 auto;
|
|
372
|
+
display: none !important;
|
|
380
373
|
}
|
|
381
|
-
.slide-presentation-host
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
374
|
+
.slide-presentation-host #marp-container svg[data-marpit-svg]:nth-of-type(${currentIndex + 1}),
|
|
375
|
+
.slide-presentation-host #marp-container > svg:nth-of-type(${currentIndex + 1}),
|
|
376
|
+
.slide-presentation-host > div > svg:nth-of-type(${currentIndex + 1}) {
|
|
377
|
+
display: block !important;
|
|
378
|
+
position: relative !important;
|
|
379
|
+
visibility: visible !important;
|
|
380
|
+
opacity: 1 !important;
|
|
381
|
+
pointer-events: auto !important;
|
|
382
|
+
width: min(100%, calc((100vh - 120px) * 16 / 9)) !important;
|
|
383
|
+
max-width: 1400px !important;
|
|
384
|
+
height: auto !important;
|
|
385
|
+
max-height: calc(100vh - 120px) !important;
|
|
386
|
+
aspect-ratio: 16 / 9 !important;
|
|
387
|
+
margin: 0 auto !important;
|
|
387
388
|
}
|
|
388
389
|
`;
|
|
389
390
|
return /* @__PURE__ */ jsxs("div", { className, style: { width: "100%" }, children: [
|
|
@@ -409,29 +410,42 @@ function DeckView({
|
|
|
409
410
|
}) {
|
|
410
411
|
const deckCss = `
|
|
411
412
|
.slide-deck-host {
|
|
412
|
-
display: flex;
|
|
413
|
-
flex-direction: column;
|
|
414
|
-
align-items: center;
|
|
415
|
-
|
|
416
|
-
padding: 16px 0;
|
|
413
|
+
display: flex !important;
|
|
414
|
+
flex-direction: column !important;
|
|
415
|
+
align-items: center !important;
|
|
416
|
+
width: 100% !important;
|
|
417
|
+
padding: 16px 0 !important;
|
|
417
418
|
}
|
|
418
|
-
.slide-deck-host > div
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
|
|
419
|
+
.slide-deck-host > div,
|
|
420
|
+
.slide-deck-host #marp-container {
|
|
421
|
+
display: flex !important;
|
|
422
|
+
flex-direction: column !important;
|
|
423
|
+
align-items: center !important;
|
|
424
|
+
width: 100% !important;
|
|
423
425
|
}
|
|
426
|
+
.slide-deck-host #marp-container svg[data-marpit-svg],
|
|
427
|
+
.slide-deck-host #marp-container > svg,
|
|
424
428
|
.slide-deck-host > div > svg {
|
|
425
429
|
display: block !important;
|
|
426
430
|
width: 100% !important;
|
|
427
|
-
max-width: 960px;
|
|
431
|
+
max-width: 960px !important;
|
|
428
432
|
height: auto !important;
|
|
429
|
-
aspect-ratio: 16 / 9;
|
|
430
|
-
|
|
431
|
-
|
|
433
|
+
aspect-ratio: 16 / 9 !important;
|
|
434
|
+
margin: 0 auto 32px auto !important;
|
|
435
|
+
border-radius: 12px !important;
|
|
436
|
+
box-shadow: 0 4px 16px rgba(0, 0, 0, 0.12) !important;
|
|
437
|
+
transition: transform 0.2s ease, box-shadow 0.2s ease !important;
|
|
438
|
+
}
|
|
439
|
+
.slide-deck-host #marp-container svg[data-marpit-svg]:last-of-type,
|
|
440
|
+
.slide-deck-host #marp-container > svg:last-of-type,
|
|
441
|
+
.slide-deck-host > div > svg:last-of-type {
|
|
442
|
+
margin-bottom: 0 !important;
|
|
432
443
|
}
|
|
444
|
+
.slide-deck-host #marp-container svg[data-marpit-svg]:hover,
|
|
445
|
+
.slide-deck-host #marp-container > svg:hover,
|
|
433
446
|
.slide-deck-host > div > svg:hover {
|
|
434
|
-
|
|
447
|
+
transform: translateY(-2px);
|
|
448
|
+
box-shadow: 0 8px 24px rgba(0, 0, 0, 0.2) !important;
|
|
435
449
|
}
|
|
436
450
|
`;
|
|
437
451
|
return /* @__PURE__ */ jsxs("div", { className, style: { width: "100%" }, children: [
|
package/dist/react/index.js.map
CHANGED
|
@@ -1 +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","useCallback","jsxs","jsx","useEffect","themeName"],"mappings":"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","file":"index.js","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"]}
|
|
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","useCallback","jsxs","jsx","useEffect","themeName"],"mappings":"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","file":"index.js","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 !important;\n align-items: center !important;\n justify-content: center !important;\n width: 100% !important;\n }\n .slide-presentation-host > div {\n position: relative !important;\n display: flex !important;\n align-items: center !important;\n justify-content: center !important;\n width: 100% !important;\n }\n .slide-presentation-host #marp-container svg[data-marpit-svg],\n .slide-presentation-host #marp-container > svg,\n .slide-presentation-host > div > svg {\n display: none !important;\n }\n .slide-presentation-host #marp-container svg[data-marpit-svg]:nth-of-type(${currentIndex + 1}),\n .slide-presentation-host #marp-container > svg:nth-of-type(${currentIndex + 1}),\n .slide-presentation-host > div > svg:nth-of-type(${currentIndex + 1}) {\n display: block !important;\n position: relative !important;\n visibility: visible !important;\n opacity: 1 !important;\n pointer-events: auto !important;\n width: min(100%, calc((100vh - 120px) * 16 / 9)) !important;\n max-width: 1400px !important;\n height: auto !important;\n max-height: calc(100vh - 120px) !important;\n aspect-ratio: 16 / 9 !important;\n margin: 0 auto !important;\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 !important;\n flex-direction: column !important;\n align-items: center !important;\n width: 100% !important;\n padding: 16px 0 !important;\n }\n .slide-deck-host > div,\n .slide-deck-host #marp-container {\n display: flex !important;\n flex-direction: column !important;\n align-items: center !important;\n width: 100% !important;\n }\n .slide-deck-host #marp-container svg[data-marpit-svg],\n .slide-deck-host #marp-container > svg,\n .slide-deck-host > div > svg {\n display: block !important;\n width: 100% !important;\n max-width: 960px !important;\n height: auto !important;\n aspect-ratio: 16 / 9 !important;\n margin: 0 auto 32px auto !important;\n border-radius: 12px !important;\n box-shadow: 0 4px 16px rgba(0, 0, 0, 0.12) !important;\n transition: transform 0.2s ease, box-shadow 0.2s ease !important;\n }\n .slide-deck-host #marp-container svg[data-marpit-svg]:last-of-type,\n .slide-deck-host #marp-container > svg:last-of-type,\n .slide-deck-host > div > svg:last-of-type {\n margin-bottom: 0 !important;\n }\n .slide-deck-host #marp-container svg[data-marpit-svg]:hover,\n .slide-deck-host #marp-container > svg:hover,\n .slide-deck-host > div > svg:hover {\n transform: translateY(-2px);\n box-shadow: 0 8px 24px rgba(0, 0, 0, 0.2) !important;\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"]}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@thanh01.pmt/presentation-kit",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.1",
|
|
4
4
|
"description": "Standalone client-side slide rendering engine with Marp, Shiki syntax highlighting, Mermaid diagrams, and custom themes.",
|
|
5
5
|
"author": "Thanh Pham <https://github.com/thanh01pmt>",
|
|
6
6
|
"license": "MIT",
|