/**
* 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