/** * IndustryMarkdownSlide Component * * A theme-aware markdown slide component that uses the industryTheme system. * Based on Theme UI specifications for consistent, modern theming. * * Features: * - Industry theme system integration (Theme UI spec) * - HTML sanitization for security * - Interactive checkboxes for task lists * - Executable bash code blocks * - HTML rendering in modal popouts * - Mermaid diagram support * - Scroll position preservation * - Configurable keyboard scrolling * * Keyboard Scrolling Configuration: * * Basic usage (uses defaults): * ```tsx * * ``` * * Custom configuration: * ```tsx * * ``` * * For use with the global keyboard binding system: * ```tsx * import { createScrollKeyboardBindings } from '@/components/MarkdownRendering/ConfigurableMarkdownSlide'; * * const scrollBindings = createScrollKeyboardBindings({ * keys: { * scrollUp: ['k'], * scrollDown: ['j'], * } * }); * * const allBindings = [...defaultKeyboardBindings, ...scrollBindings]; * ``` */ import { Theme } from '@principal-ade/industry-theme'; import { BashCommandOptions, BashCommandResult, RepositoryInfo } from '@principal-ade/markdown-utils'; import React from 'react'; import type { Annotation, AnnotationSelection } from '../types/annotations'; import { KeyboardBinding } from '../types/keyboard'; import { type BlockDeletionTarget } from '../utils/blockDeletion'; export interface IndustryMarkdownSlideProps { content: string; slideIdPrefix: string; slideIndex: number; isVisible?: boolean; onLinkClick?: (href: string, event?: MouseEvent) => void; onLinkInfoClick?: (href: string, event?: MouseEvent) => void; onCheckboxChange?: (slideIndex: number, lineNumber: number, checked: boolean) => void; onCopyMermaidError?: (mermaidCode: string, errorMessage: string) => void; onShowMermaidInPanel?: (code: string, title?: string) => void; /** * When provided, renders an "open in tab" arrow button over each mermaid * diagram, next to the fullscreen/expand button. Called with the diagram * code (and a best-effort title derived from the diagram source) so the * consumer can open it as its own tab — e.g. the Alexandria window opening * a diagram from a topic description/notes. */ onOpenMermaidInTab?: (code: string, title?: string) => void; handleRunBashCommand?: (command: string, options?: BashCommandOptions) => Promise; handlePromptCopy?: (filledPrompt: string) => void; enableHtmlPopout?: boolean; autoFocusOnVisible?: boolean; searchQuery?: string; slideHeaderMarginTopOverride?: number; theme: Theme; fontSizeScale?: number; containerWidth?: number; transparentBackground?: boolean; additionalPadding?: { left?: string; right?: string; top?: string; bottom?: string; }; /** * Skip the container-width-derived base padding on one or both axes. * When `true` (boolean shorthand) both axes are zeroed. `additionalPadding` * is still applied on top, so the parent can layer its own padding while * dropping the slide's default 3%-of-width inset. * * Useful when the slide is embedded in a layout that already owns * horizontal alignment (e.g., aligning the rendered markdown with * surrounding body copy). */ disableBasePadding?: boolean | { horizontal?: boolean; vertical?: boolean; }; disableScroll?: boolean; minScreenWidth?: number; maxScreenWidth?: number; enableKeyboardScrolling?: boolean; keyboardScrollConfig?: KeyboardScrollConfig; repositoryInfo?: RepositoryInfo; /** * Host-facing image resolver. Called with the raw markdown image `src` before * the built-in repository-relative resolution. When it returns a truthy value, * that value is used as-is — letting the host own custom schemes such as * `asset://` (resolved to a data-URL or http URL). Falls back to * repository-relative resolution otherwise. */ transformImageUri?: (src: string) => string; editable?: boolean; /** * When true, highlighting text inside the slide resolves to the top-level * block(s) it touches and surfaces a floating delete button. The button is * only shown when a delete handler (`onContentChange` or `onDeleteBlocks`) * is also provided. */ selectableBlocks?: boolean; /** * How a highlight is resolved for deletion: * - 'block' (default): removes the whole top-level block(s) the highlight * touches — robust, and works alongside search highlighting. * - 'text': removes the exact highlighted text, mapped back to the markdown * source. Falls back to whole-block removal when a precise range can't be * resolved (e.g. selections inside code or spanning blocks). Note that * partially selecting inline-formatted text (e.g. the word inside * `**bold**`) can leave the surrounding markers behind. */ deletionMode?: 'block' | 'text'; /** * Called with the full slide content after the selected block(s) are * removed. The slide is presentational — the consumer owns `content` and is * expected to persist this and feed it back in. */ onContentChange?: (newContent: string) => void; /** * Optional richer notification fired alongside `onContentChange` when a * block deletion occurs. */ onDeleteBlocks?: (info: { newContent: string; removedText: string; targets: BlockDeletionTarget[]; }) => void; annotations?: Annotation[]; activeAnnotationId?: string | null; renderAnnotation?: (annotation: Annotation) => React.ReactNode; onSelectionChange?: (selection: AnnotationSelection | null) => void; onAnnotationClick?: (annotationId: string, event: MouseEvent) => void; /** * Color overrides for annotation highlights. Each field is any valid CSS * color (hex, rgba, var(...), etc.). Omit a field to keep the default * amber palette. */ annotationStyle?: { backgroundColor?: string; activeBackgroundColor?: string; }; } export interface KeyboardScrollConfig { scrollAmount?: number; pageScrollRatio?: number; smoothScroll?: boolean; keys?: { scrollUp?: string[]; scrollDown?: string[]; pageUp?: string[]; pageDown?: string[]; }; enableDebugLogging?: boolean; } export declare function createScrollKeyboardBindings(config?: KeyboardScrollConfig): KeyboardBinding[]; export declare const IndustryMarkdownSlide: React.NamedExoticComponent; //# sourceMappingURL=IndustryMarkdownSlide.d.ts.map