npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@viswa-test/test-citations

v0.0.66

Published

1. [Project Overview](#project-overview) 2. [Installation](#installation) 3. [Available Components](#available-citations) - [Citation Components](#citation-components) - [BookCitation](#bookcitation) [<img src="https://github.githubassets.com/imag

Downloads

51

Readme

📚 e-llm-studio/citation

Table of Contents

  1. Project Overview
  2. Installation
  3. Available Components
  4. Common Use Cases
  5. Development & Contribution
  6. License

Project Overview

The @e-llm-studio/citation library is a comprehensive React component library designed to render various types of citations and related UI elements within the e-LLM Studio ecosystem. It provides a robust set of reusable, production-ready components that enable developers to display citations, reasoning chains, code snippets, PDFs, and other content types with rich interactive features and highly customizable styling.

This library serves as a foundational building block for applications that need to present complex information in an organized, user-friendly manner. Whether you're displaying book citations with highlighted passages, rendering AI reasoning with confidence scores, showcasing code with syntax highlighting, or managing large datasets with pagination, the citation library offers flexible, well-documented components that integrate seamlessly into modern React applications.

The library emphasizes developer experience through comprehensive documentation, TypeScript support, and extensive customization options. Each component is designed with accessibility and performance in mind, ensuring that applications built with these components provide excellent user experiences across different devices and use cases.


Installation

Prerequisites

Before you begin, ensure you have the following installed on your system:

  • Node.js & npm - Required for package management and running build scripts
  • Git - Required for cloning the repository
  • Basic familiarity with Git and the command line

Installation Steps

1. Clone the Repository

Start by cloning the citation library repository to your local machine:

git clone https://github.com/e-llm-studio/citation.git

cd citation

2. Install Dependencies

Install all required dependencies using npm:

npm install

Alternatively, you can use yarn if you prefer:

yarn install

3. Link the Library Locally (Optional)

If you want to test the library in another project before publishing, you can link it locally:

# In the citation library folder
npm link

# In your test project folder
cd ../your-project
npm link @e-llm-studio/citation

This allows you to test changes in your local library without publishing to npm.

4. Build the Library

Build the library to compile TypeScript and prepare distribution files:

npm run build

5. Test Locally

After building, you can test the library in your project:

# In your test project
npm start
# or
npm run build

Import the library components and verify that your changes work as expected.

Quick Installation for End Users

If you're installing the published package from npm:

# Using npm
npm install @e-llm-studio/citation

# Using yarn
yarn add @e-llm-studio/citation

# Using pnpm
pnpm add @e-llm-studio/citation

Citation Components

BookCitation

Overview

The BookCitation component is designed to display book citations with an interactive and expandable interface. It provides a rich, user-friendly way to present quoted text from books with support for highlighting, citation details management, and book cover images. The component enables readers to explore citations in context while maintaining a clean, organized presentation.

Features

  • Text highlighting with partial and full match support - Highlights specific text passages within citations using flexible matching algorithms
  • Automatic cleaning of scanned text to remove artifacts - Intelligently removes OCR artifacts, page numbers, headers, and footers
  • Expandable/collapsible view of citation details - Toggle between collapsed citation button and expanded view
  • Blur effect for non-highlighted text - Applies visual blur to non-highlighted portions to focus reader attention
  • Scroll-to-highlight functionality - Automatically scrolls to and centers highlighted text when expanded
  • Support for book cover images and external links - Displays book cover images and provides clickable external links
  • Customizable styling through the customStyle prop - Allows fine-grained control over component appearance

Usage:

import BookCitation from '@e-llm-studio/citation/BookCitation'

<BookCitation
 citationTitle="Sample Book"
 paragraphs={['<p>Highlighted text example</p>']}
 textToHighlight={['example']}
 partialMatch={true}
/>

Props:

| Prop Name | Type | Description | |-----------|------|-------------| | title | string | Optional title of the book or publication being cited | | author | string \| string[] | Optional author name(s) of the book or publication | | pageNumber | string | Optional current page number where the citation is located | | totalPageNumber | string | Optional total number of pages in the book or publication | | paragraphs | string[] | Required array of HTML strings containing the text content | | citationTitle | string | Required title or label for the citation | | textToHighlight | string[] | Required array of text strings to highlight within the paragraphs | | bookCoverImage | string | Optional URL or path to the book cover image | | handleExternalLinkClick | () => void | Optional callback function triggered when external link is clicked | | externalLinkComponent | React.ReactNode | Optional React component to render as an external link button | | citationNumber | number | Optional citation number displayed in the citation button | | partialMatch | boolean | Optional flag to enable partial text matching when highlighting | | defaultState | boolean | Optional flag to set the initial expanded/collapsed state | | isNonHighlightedBlur | boolean | Optional flag to enable blur effect on non-highlighted text | | customStyle | object | Optional object for overriding default styles | | useDropdown | boolean | Optional flag to render the citation as a dropdown (default: true) |



CognitiveCompare (Main Component)

A side-by-side document comparison component with cognitive analysis, deviation badges, citation-linked PDF previews, and two layout modes (Standard and Relative Order). For full documentation see the dedicated README.

Props

| Prop | Type | Default | Description | | --------------------- | ----------------------------------- | ----------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | treeData | Record<string, any> \| null | — | Required. Backend tree structure powering both columns. | | displayConfig | IDisplayConfig | — | Required. Controls header/toggle visibility and initial layout mode. | | componentHeaderText | string | "Contract Comparison" | Text shown in the top header bar. | | deviationData | Record<string, any> | {} | Per-node deviation analysis results keyed by node ID. Populates the Deviation Analysis tab in the cognitive popup and drives inline text highlights within section content. |


IDisplayConfig

| Property | Type | Default | Description | | ----------------------- | --------- | ------- | ---------------------------------------------------------------------- | | isHeaderVisible | boolean | true | Show or hide the top header bar. | | isToggleVisible | boolean | true | Show or hide the Standard / Relative Order toggle switch. | | maintainRelativeOrder | boolean | false | Initial layout mode — true for Relative Order, false for Standard. |


treeData Shape

treeData is the primary data contract. It must be a flat object where every key is a node ID, plus four reserved keys.

{
  // Top-level metadata keys
  base_root_id: string,           // ID of the root node (looked up inside nodes)
  input_index_map: {              // Maps side index to document UUID
    "0": string,                  // left side UUID
    "1": string,                  // right side UUID
  },
  documents: {                    // Document metadata keyed by UUID
    [uuid: string]: {
      title: string,
      signed_url: string,         // PDF URL used by CitationAnchor / PdfViewer
    }
  },

  // All node data lives under the `nodes` key
  nodes: {
    // Root node (identified by base_root_id)
    [rootId: string]: {
      display_node?: boolean,
      comparison_inputs: {
        [uuid: string]: { title: string }   // column titles
      },
      decision_scope_description?: string,
      next?: Record<string, string>,         // child node IDs
    },

    // Section nodes
    [nodeId: string]: {
      display_node?: boolean,        // set false to hide the node
      evaluation_result?: DeviationDataEntry, // deviation result attached directly to node
      comparison_inputs: {
        [uuid: string]: {
          title: string,
          content: string,
          additional_attributes?: {
            display_index?: number,    // used in Relative Order mode for sorting
            display_title?: boolean,   // set false to suppress rendering the title
            display_content?: boolean, // set false to suppress rendering the content
          }
        }
      },
      next?: Record<string, string>, // child node IDs (for subsections)
      mapping_rationale?: {
        decision_strength?: string,  // numeric string, e.g. "72"
        decisioning_factors?: string[],
        gaps_in_decision?: string[],
        citations?: Record<string, Record<string, CitationEntry>>
      }
    }
  }
}

All node data (root and section nodes) lives under the nodes key. The top-level base_root_id, input_index_map, and documents keys remain directly on treeData.

deviationData Shape

// deviationData[nodeId]
{
  evaluation_outputs?: {
    output_value?: string,           // badge label text
    metadata?: { label_color?: string } // hex — drives badge/highlight colors
  },
  cognitive_decisioning?: {
    decisioning_factors?: string[],
    gaps_in_decision?: string[],
    citations?: Record<string, any>,
    decision_strength?: string | null,
  },
  deviations?: Record<string, any>,  // { devKey: { [docUuid]: highlightText } }
}

Usage

import CognitiveCompare from "@e-llm-studio/citation/CognitiveCompare";

<CognitiveCompare
  treeData={myTreeData}
  displayConfig={{
    isHeaderVisible: true,
    isToggleVisible: true,
    maintainRelativeOrder: false,
  }}
  deviationData={myDeviationData}
/>;

Key Behaviours

  • Badge and highlight colors are generated dynamically from evaluation_outputs.metadata.label_color via generateColorPalette(). The static relationStyles map has been removed.
  • Clicking a badge in Standard mode opens CognitivePopup directly. In Relative Order mode it opens MoreFunctionsPopup offering Connect, Side by Side, and Cognitive Decisioning actions.
  • The Deviation Analysis tab is shown first in the popup and displays cognitive_decisioning.decisioning_factors and gaps_in_decision with inline citation anchors that open split PDF viewers.
  • deviations entries drive inline <mark> highlights inside section content, colored using the same label_color-derived palette.

ChatCitation

Overview

ChatCitation is a composable React UI component for rendering chat-based citations, including summarized and detailed chat views alongside a rule book/reference section. The component is designed to be highly customizable via renderers, slot styles, and slot props, making it flexible for various use cases.

Features

  • Composable chat views - Supports both summarized and detailed chat display modes
  • Rule book/reference section - Optional left panel for displaying supporting rules and references
  • Markdown rendering - Rich text support with customizable markdown renderers
  • Customizable styling - Fine-grained control over styles through slot-based customization
  • Relevance scoring - Display AI relevance scores for citations
  • Tab-based navigation - Toggle between summarized and detailed views
  • Flexible content rendering - Support for custom renderers and markdown components

Usage

import ChatCitation from '@e-llm-studio/citation/ChatCitation'

<ChatCitation
 chatContainer={{
 chatData: [
 { role: 'user', message: 'Hello', userName: 'User1', timeStamp: dayjs() }
 ]
 }}
 ruleBookContainer={{
 title: 'References',
 data: { content: 'Rule content', highlighted_texts: ['important'] }
 }}
/>

Props

| Prop Name | Type | Description | |-----------|------|-------------| | rootContainer | RootContainerProps | Optional top-level container configuration | | chatContainer | ChatContainerProps | Required chat container configuration with chat data | | ruleBookContainer | RuleBookContainerProps | Optional rule book/reference section configuration | | renderer | FeatureModMarkdownProps["renderers"] | Optional custom markdown renderers |


ChatDrawer

Overview

ChatDrawer is a generic, resizable drawer component for rendering collapsible panels with a draggable resize handle. All content is consumer-owned — pass any React node as children: forms, file lists, summary cards, tables, or any custom component. The consuming team is fully responsible for styling and rendering the content inside.

Features

  • Collapsible panel — Header is always visible; body and drag handle only render when open
  • Notch toggle — Small tab below the drawer with a chevron arrow; click to expand/collapse, drag to resize
  • Drag to resize — Grab the pill handle at the bottom to resize between minHeight and maxHeight
  • Configurable heightdefaultHeight, minHeight, maxHeight all exposed as props
  • Consumer-owned content — Zero opinion on what goes inside, pass any React node
  • Deep style overrides — Every visual region customizable via the styles prop
  • Inline styles only — No Tailwind or MUI dependency, works in any consuming app

Usage

import ChatDrawer from '@e-llm-studio/citation/ChatDrawer'

<ChatDrawer
  uploadListTopContent="My Panel"
  isExpanded={isOpen}
  onToggle={() => setIsOpen(v => !v)}
  defaultHeight={300}
  minHeight={150}
  maxHeight="60vh"
>
  {/* Pass any component here — form, file list, summary cards, etc. */}
  <YourComponent />
</ChatDrawer>

With onHeightChange (sibling layout adjustment):

const [drawerHeight, setDrawerHeight] = useState(300);

<ChatDrawer
  uploadListTopContent="Context"
  isExpanded={isOpen}
  onToggle={() => setIsOpen(v => !v)}
  defaultHeight={300}
  onHeightChange={setDrawerHeight}
>
  <YourComponent />
</ChatDrawer>

With styles (theme customization):

<ChatDrawer
  uploadListTopContent="Dark Panel"
  isExpanded={isOpen}
  onToggle={() => setIsOpen(v => !v)}
  styles={{
    container: { backgroundColor: '#1a1a2e', border: '1px solid #444' },
    header: { backgroundColor: '#1a1a2e' },
    title: { color: '#fff' },
    body: { backgroundColor: '#1a1a2e' },
    notch: { backgroundColor: '#1a1a2e', border: '1px solid #444' },
    notchArrowColor: '#fff',
  }}
>
  <YourComponent />
</ChatDrawer>

Props

| Prop | Type | Required | Description | |------|------|----------|-------------| | children | ReactNode | ❌ | Scrollable body — fully consumer owned. Pass any React node. | | uploadListTopContent | string | ❌ | Header title shown in the always-visible top bar. Defaults to "Data uploaded for your context". | | isExpanded | boolean | ❌ | Controlled open/close state. Defaults to false. | | onToggle | () => void | ❌ | Called when the notch is clicked. Wire your open/close state here. | | defaultHeight | number | ❌ | Initial height of the panel in px when expanded. Defaults to 300. | | minHeight | number | ❌ | Minimum height in px when drag-resizing. Defaults to 150. | | maxHeight | number \| string | ❌ | Maximum height when drag-resizing. Accepts a px number or a CSS string like "70vh". Defaults to 40vh. | | onHeightChange | (height: number) => void | ❌ | Fired on every drag tick with the current height in px. Useful when a sibling layout needs to react to height changes. | | styles | ChatDrawerStyles | ❌ | Style overrides for each visual region. Keys: container, header, title, body, dragPill, notch, notchArrowColor. Each accepts any valid CSSProperties except notchArrowColor which is a string. |


CitationRenderer

Overview

CitationRenderer is a versatile, interactive "Pill" component designed to display a compact reference citation that expands into detailed content. It provides a space-efficient toggle mechanism, perfect for displaying source material, footnotes, or reasoning chains without cluttering the main UI. It works seamlessly with MarkdownRenderer to display rich, interactive text content.

Features

  • Expandable pill button - Compact display that expands on click
  • Customizable icons - Support for custom icons for chevron and citation indicators
  • Markdown content support - Render rich text content using MarkdownRenderer
  • Controlled and uncontrolled modes - Manage state internally or externally
  • Flexible styling - Customize appearance through style props
  • Callback support - Optional callbacks for side effects on toggle

Usage

import CitationRenderer from '@e-llm-studio/citation/CitationRenderer'

<CitationRenderer
 inLineCitation={true}
 citationTitle="Reference 1"
 citationComponent={<div>Detailed content here</div>}
 chevronDownComponent={<ChevronDownIcon />}
 chevronUpComponent={<ChevronUpIcon />}
/>

Props

| Prop Name | Type | Description | |-----------|------|-------------| | inLineCitation | boolean | Must be true to enable expand/collapse behavior | | citationTitle | string | The text displayed inside the pill button | | citationComponent | ReactNode | The content to render when expanded | | citationIcon | ReactNode | Icon displayed to the left of the title | | chevronUpComponent | ReactNode | Icon shown when the citation is expanded | | chevronDownComponent | ReactNode | Icon shown when the citation is collapsed | | additionalCallbackForPillButton | func | Hook to trigger side effects on click | | styles | Object | CSS overrides for styling | | isOpen | boolean | Forces the expanded state (controlled mode) | | onToggle | func | Callback fired when the pill is clicked |


CognitiveDecisioningCard

Overview

CognitiveDecisioningCard is a specialized React UI component designed to provide transparency into AI workflows. It renders a toggleable "Pill" that expands into a detailed card, displaying the AI's Reasoning, identified Gaps, and a confidence Score. It features a nested accordion design, robust Markdown rendering for content, and full styling customization.

Features

  • Toggleable pill button - Click to expand/collapse the detailed card
  • Reasoning and gap sections - Display AI reasoning and identified gaps with markdown support
  • Confidence score badge - Show confidence percentage in the header
  • Nested accordion design - Collapsible sections for organized content
  • Custom markdown rendering - Support for custom markdown components
  • Icon customization - Replace default icons with custom components
  • Advanced section customization - Override default sections with custom data structures

Usage

import CognitiveDecisioningCard from '@e-llm-studio/citation/CognitiveDecisioningCard'

<CognitiveDecisioningCard
 isOpen={isOpen}
 onToggle={() => setIsOpen(!isOpen)}
 score="92"
 reasoning="**Analysis:** Based on document review..."
 gap="Missing date information in section 3."
 title="AI Analysis Report"
/>

Advanced Customization:

const customSections = [
 {
 id: 'step1',
 title: 'Data Retrieval',
 subtitle: '3 sources processed',
 icon: <CheckIcon />,
 content: 'Data retrieved successfully'
 }
]

<CognitiveDecisioningCard
 isOpen={true}
 sections={customSections}
 score="100"
 mdComponents={{
 a: ({ node, ...props }) => <a {...props} target="_blank" />
 }}
/>

Props

| Prop Name | Type | Description | |-----------|------|-------------| | reasoning | string | Markdown text explaining the AI's logic | | gap | string | Markdown text explaining missing info or uncertainties | | score | string | Confidence score percentage (e.g., "92") | | isOpen | boolean | Controls the visibility of the expanded card | | onToggle | () => void | Callback handler for the pill trigger click | | title | string | Header title. Default: "Cognitive Decisioning AI" | | hideTrigger | boolean | If true, hides the pill button | | sections | SectionContent[] | Advanced: Overrides default Reasoning/Gap sections | | mdComponents | Object | Custom renderers for react-markdown | | headerIcon | ReactNode | Replaces the default brain icon | | reasoningIcon | ReactNode | Replaces the icon for the reasoning section | | gapIcon | ReactNode | Replaces the icon for the gap section | | scoreIcon | ReactNode | Replaces the sparkle icon in the score badge | | reasoningTitle | string | Title for the reasoning section. Default: "Decision Making Factors" | | reasoningSubtitle | string | Subtitle for the reasoning section. Default: "Why this was picked" | | gapTitle | string | Title for the gap section. Default: "Gaps in Decision" | | gapSubtitle | string | Subtitle for the gap section. Default: "What's missing or unclear" | | scoreLabel | string | Label prefix shown before the score percentage. Default: "Decision Strength: " |


CognitiveInternalGPTReasoning

Overview

The CognitiveInternalgptReasoningComponent is a React component designed to render non-web search reasoning citations with advanced interactive features. It provides a comprehensive display of reasoning data with support for expandable content, highlight navigation, and modal fullscreen viewing. This component is particularly useful for displaying AI-generated reasoning, training data citations, and confidence scores in a user-friendly format.

Features

  • Expandable Content - Display a paraphrase text that expands to show the full data source content
  • Highlight Navigation - Automatically extract and navigate between highlighted sections within the content
  • Confidence Score Display - Show confidence percentage in both expanded view and modal
  • Fullscreen Modal View - Open a fullscreen modal for detailed examination of reasoning data
  • Text Formatting Support - Handle bold text, list items, headers, and special highlight tags
  • Custom Icon Support - Replace default icons with custom React components

Usage

import NonWebReasoningComponent from '@e-llm-studio/citation/CognitiveInternalgptReasoningComponent'

const reasoningData = {
 text: "Reasoning text here",
 dataSource: "Source with <highlight>highlighted text</highlight>",
 confidence_score: 95,
 paraphrase: "Brief summary",
 previewCallback?:callback
 DocumentTitle?: "title";
}

<NonWebReasoningComponent
 item={reasoningData}
 index={1}
 headerTitle="GPT Reasoning"
/>

Highlight Navigation:

  • Extracts <highlight> tags from dataSource
  • Provides navigation between highlighted sections
  • Shows current position (e.g., "2/5 highlights")
  • Auto-scrolls to active highlight
  • previewCallback we can use this to pass a callback for external link opening or pdf opening
  • DocumentTitle : pdf title or document title

CodeCitation

Overview

CodeCitation is a composable React UI component for rendering code citations with interactive features, syntax highlighting, and customizable display modes. It provides developers with a powerful tool for displaying code snippets with syntax highlighting, diagnostics, and theme support.

Features

  • Inline and popup citation views - Flexible display modes for different use cases
  • Syntax highlighting - Support for multiple programming languages
  • Dark/Light mode theme toggling - Accessibility and user preference support
  • Code highlighting - Highlight specific lines or variables
  • Displaying diagnostics - Show errors and warnings with customizable styling
  • Fetching code from backend - Support for dynamic code retrieval
  • Customizable UI - Extensive customization through props and inline styles
  • Fullscreen view support - View code in fullscreen modal
  • Responsive design - Works well on various screen sizes

Usage

import { CodeCitation } from '@e-llm-studio/citation/CodeCitation'

<CodeCitation
 citationTitle="Example Code"
 filename="example.js"
 filepath="/src/example.js"
 customCode={`function hello() { return "world"; }`}
 inLineCitation={true}
 isDarkModeEnabled={false}
 showThemeToggle={true}
 editorHeight={400}
/>

Advanced Features:

const diagnostics = [
 {
 range: { lineStart: 2, lineEnd: 2, columnStart: 6, columnEnd: 11 },
 severity: 1 
 }
]

const highlightRanges = [
 {
 startIndex: 2,
 endIndex: 5,
 color: 'rgba(255, 255, 0, 0.3)',
 lightModeColor: 'rgba(255, 255, 0, 0.2)'
 }
]

<CodeCitation
 customCode={sampleCode}
 diagnostics={diagnostics}
 diagnosticStylesBySeverity={{
 1: { style: { backgroundColor: 'rgba(255,0,0,0.2)' } }
 }}
 startIndex={2}
 endIndex={5}
 isHighlightingEnabled={true}
/>

Props

| Prop Name | Type | Description | |-----------|------|-------------| | citationTitle | string | Display name for the citation | | filename | string | Filename with extension to identify the language | | filepath | string | File path for reference | | customCode | string | The code string to display in the editor | | inLineCitation | boolean | Set to true for inline display or false for popup modal | | isDarkModeEnabled | boolean | Enable dark theme by default | | showThemeToggle | boolean | Display theme toggle button | | editorHeight | number | Height of the code editor in pixels | | editorWidth | string \| number | Width of the code editor | | baseUrlForCodeRetrieval | string | Base URL for fetching code from backend | | assistantName | string | Name of the assistant for context | | organizationName | string | Name of the organization | | userId | string | User ID for tracking | | taskId | string | Task ID for context | | repoUrl | string | Repository URL for reference | | showFullscreenIcon | boolean | Display fullscreen toggle button | | showFileSummaryIButton | boolean | Display file summary info button | | isHighlightingEnabled | boolean | Enable code highlighting |


CitationsViewer

Overview

The Citation Viewer is a rich, interactive React component designed to display AI-generated audio citations. It features a synchronized audio waveform player, a transcript view that highlights active segments, and a summary of key takeaways. This component is ideal for displaying RAG (Retrieval-Augmented Generation) results where the source material is audio or video, allowing users to listen to the specific segment referenced by the AI.

Features

  • Interactive Waveform - Visualizes audio using wavesurfer.js with playback controls
  • Smart Highlighting - Automatically highlights the specific time range referenced in the citation on the waveform
  • Synchronized Transcript - Displays chat history and highlights the active message segment
  • Key Takeaways - Renders extracted insights with bold text formatting and keyword tags
  • GCS Integration - Built-in hook to resolve Google Cloud Storage (gs://) URLs to signed URLs via a backend endpoint
  • Themable - Fully customizable colors and typography via a theme config object

Usage

import CitationsViewer from '@e-llm-studio/citation/CitationsViewer'

<CitationsViewer
 artifact={{
 baseUrl: "https://api.example.com",
 artifactTitle: "Quarterly Earnings Call",
 fileUrl: "gs://bucket/audio.mp3",
 chatHistory: [
 {
 role: "Speaker 1",
 message: "Revenue increased by 20%",
 timestamp: "10:30",
 timestamp_start: 120.5,
 timestamp_end: 125.0
 }
 ],
 keyTakeaways: [
 {
 takeawayId: "1",
 name: "Revenue Growth",
 content: "**20% year-over-year growth**",
 keywords: ["Revenue", "Growth"]
 }
 ]
 }}
 onCloseHandler={() => console.log('Closed')}
/>

Props

| Prop Name | Type | Required | Description | |-----------|------|----------|-------------| | artifact | ArtifactData | ✅ | The main data object containing audio, transcript, and metadata | | onCloseHandler | () => void | ❌ | Callback function triggered when the close (X) button is clicked | | theme | ThemeConfig | ❌ | Object to override default colors and fonts | | iconsConfig | IconsConfig | ❌ | Object to inject custom React icons (Play, Pause, Close) |


PdfEditorCitation

Overview

PdfEditorCitation is a core component for the Advanced Document Management and Citation System. It provides a user-friendly interface for viewing, editing, and citing PDF documents directly within the application. It combines interactive PDF viewing capabilities with a collapsible UI pattern, allowing users to manage document space efficiently while maintaining full access to PDF editing and annotation features.

Features

  • Collapsible PDF viewer functionality - Users can expand and collapse the PDF editor section
  • Interactive PDF editing capabilities - Full support for PDF editing, annotations, and collaborative features
  • Sentence highlighting support - Ability to highlight specific sentences within PDF documents
  • Customizable UI through CSS classes - Flexible styling options for seamless integration

Usage

import { PdfEditorCitation } from '@e-llm-studio/citation/PdfEditorCitation'

<PdfEditorCitation
 citationTitleElement={<div>Research Paper.pdf</div>}
 pdfUrl="https://example.com/document.pdf"
 pdfEditorBackendBaseUrl="https://pdf-backend.example.com"
 sentenceHighlightDetails={{
 pdfPageNumber: 5,
 sentenceToHighlight: "key finding in the research"
 }}
 currentUserId="user-123"
/>

Props

| Prop Name | Type | Description | |-----------|------|-------------| | citationTitleElement | ReactElement | A React element to display as the clickable title | | pdfUrl | string | The URL of the PDF file to be displayed and edited | | pdfEditorBackendBaseUrl | string | The base URL of the PDF editor backend service | | citationRootClassName | string | Optional CSS class name for the root container | | citationBodyClassName | string | Optional CSS class name for the body section | | citationBodyWhenCollapsedClassName | string | Optional CSS class name for collapsed state | | citationTitleClassName | string | Optional CSS class name for the title section | | rlefEventServiceBaseUrl | string | Optional base URL for the RLEF event service | | currentUserId | string | Optional user ID of the current user | | sentenceHighlightDetails | object | Optional sentence highlighting configuration |


RequirementAICitation

Overview

RequirementAICitation is a comprehensive React module for displaying AI-generated insights and rich media evidence. It serves two primary purposes: displaying an AI Reasoning Card with expandable sections for logic, gaps, and confidence scores with embedded citations, and providing standalone media citations for Files, Images, and Web Links.

Features

  • AI Reasoning Card - Complex, expandable card displaying AI logic, gaps, and confidence scores with embedded, clickable citations
  • Standalone Media Citations - Individual, stylized citation pills for Files, Images, and Web Links
  • Multiple Citation Types - Support for file citations (PDFs), image citations, and web citations
  • Relevance Scoring - Display AI relevance scores for all citation types
  • Rich Media Preview - Integrated viewers for PDFs, images, and web content
  • Customizable Styling - Deep CSS injection for all components

Usage 1: AI Reasoning Card (Composite Component)

Use this when you want to display AI analysis with embedded, clickable citations that open in a preview panel.

import { AiReasoningCitation } from '@e-llm-studio/citation/AiReasoningCitation'

<AiReasoningCitation
  title="AI Analysis"
  aiReasoningAccordionProps={{
    icons: {
      chevronUp: <i className="pi pi-angle-up" />,
      chevronDown: <i className="pi pi-angle-down" />
    }
  }}
  aiReason={{
    id: "1",
    relevance_score: 95,
    reason: ["The <a href='document_citation$1'>ADK.pdf</a> mentions the Agent Card..."],
    gap: ["Registry mechanism is undefined"]
  }}
  citationList={{
    file_citations: [{
      citation_number: "1",
      customMetadata: {
        type: "book_citation_pdf",
        file_name: "ADK.pdf",
        highlighted_pdf_signed_url: "https://storage.googleapis.com/..."
      }
    }],
    image_citations: [],
    web_citations: []
  }}
  
  projectDetails={null}
/>

How Citations Work in AI Reasoning Card:

  • Text contains links like <a href='document_citation$1'> or <a href='image_citation$2'>
  • Clicking a link opens the corresponding citation in a preview panel
  • Citation data is looked up from citationList using the citation number

Usage 2: Standalone Image Citation

Use this component independently to display an image with relevance scoring.

import { ImageCitationContent } from '@e-llm-studio/citation/ImageCitationContent'

<ImageCitationContent
  citationTitle="Visual Reference"
  relevanceScore={95}
  signedUrl="https://images.pexels.com/photo.jpeg"
  
  // Optional: For closeable preview
  closeCitationConfig={{
    CloseIcon: () => <span>✕</span>,
    handleCloseCitationPreview: () => console.log('Closed')
  }}
  
  // Optional: Custom styling
  styles={{
    container: { border: '1px solid #ccc' },
    image: { maxHeight: '500px' },
    aiConfidenceDisplayPill: {
      container: { border: "2px solid blue" }
    }
  }}
/>

With CitationRenderer (Expandable Pill):

import { CitationRenderer } from '@e-llm-studio/citation/CitationRenderer'
import { ImageCitationContent } from '@e-llm-studio/citation/ImageCitationContent'

<CitationRenderer
  inLineCitation={true}
  citationTitle="Screenshot Reference"
  citationComponent={
    <ImageCitationContent
      relevanceScore={95}
      signedUrl="https://images.pexels.com/photo.jpeg"
    />
  }
  chevronDownComponent={<span>▼</span>}
  chevronUpComponent={<span>▲</span>}
/>

Usage 3: Standalone File/PDF Citation

Use this component independently to display PDF documents with relevance scoring.

import { FileCitationContent } from '@e-llm-studio/citation/FileCitationContent'

<FileCitationContent
  title="Technical Specification.pdf"
  relevanceScore={88}
  signedUrl="https://example.com/sample.pdf"
  
  // Optional: For closeable preview
  closeCitationConfig={{
    CloseIcon: () => <span>✕</span>,
    handleCloseCitationPreview: () => console.log('Closed')
  }}
/>

With CitationRenderer (Expandable Pill):

import { CitationRenderer } from '@e-llm-studio/citation/CitationRenderer'
import { FileCitationContent } from '@e-llm-studio/citation/FileCitationContent'

<CitationRenderer
  inLineCitation={true}
  citationTitle="Technical Spec.pdf"
  citationComponent={
    <FileCitationContent
      title="Spec.pdf"
      relevanceScore={88}
      signedUrl="https://example.com/sample.pdf"
      styles={{ pdfWrapper: { height: "750px" } }}
    />
  }
  chevronDownComponent={<span>▼</span>}
  chevronUpComponent={<span>▲</span>}
/>

Usage 4: Standalone Web Citation

Use this component independently to display web content with screenshot preview.

import { WebCitationWithImageContent } from '@e-llm-studio/citation/WebCitationWithImageContent'

<WebCitationWithImageContent
  label="Pexels - Free Stock Photos"
  url="https://www.pexels.com/photo/..."
  relevanceScore={92}
  signedUrl="https://images.pexels.com/screenshot.jpeg"
  
  PreviewDialogCloseIcon={() => <span>✕</span>}
  visitIcon={() => <span>→</span>}

  closeCitationConfig={{
    CloseIcon: () => <span>✕</span>,
    handleCloseCitationPreview: () => console.log('Closed')
  }}
/>

With CitationRenderer (Expandable Pill):

import { CitationRenderer } from '@e-llm-studio/citation/CitationRenderer'
import { WebCitationWithImageContent } from '@e-llm-studio/citation/WebCitationWithImageContent'

<CitationRenderer
  inLineCitation={true}
  citationTitle="Pexels Source"
  citationComponent={
    <WebCitationWithImageContent
      label="Pexels Source"
      url="https://www.pexels.com/..."
      relevanceScore={92}
      signedUrl="https://images.pexels.com/screenshot.jpeg"
      PreviewDialogCloseIcon={() => <span>✕</span>}
      visitIcon={() => <span>→</span>}
    />
  }
  chevronDownComponent={<span>▼</span>}
  chevronUpComponent={<span>▲</span>}
/>

Usage 5: Standalone Markdown With Image Citation

Use this component when the image should be rendered as part of the markdown content itself rather than as a separate prop-driven media block.

import { MarkdownWithImageCitation } from '@e-llm-studio/citation/MarkdownWithImageCitation'

const markdownContent = `
## Product Collaboration Workspace

<img src="https://images.unsplash.com/photo-1516321318423-f06f85e504b3?auto=format&fit=crop&w=1200&q=80" alt="Team collaboration workspace" />

This visual captures a clean product collaboration workspace prepared for planning, note-taking, and design review.

### Key observations

- The laptop acts as the primary working surface for product or engineering review
- The surrounding setup reinforces a structured, research-oriented workflow
- The image is rendered inline as part of the markdown citation
`;

<MarkdownWithImageCitation
  citationTitle="Inline Markdown Image Reference"
  timestamp="Apr 03, 2026 - 11:15 AM"
  relevanceScore={98}
  markdownContent={markdownContent}
  closeCitationConfig={{
    CloseIcon: () => <span>✕</span>,
    handleCloseCitationPreview: () => console.log('Closed'),
  }}
/>

With CitationRenderer (Expandable Pill):

import { CitationRenderer } from '@e-llm-studio/citation/CitationRenderer'
import { MarkdownWithImageCitation } from '@e-llm-studio/citation/MarkdownWithImageCitation'

<CitationRenderer
  inLineCitation={true}
  citationTitle="Markdown Image Reference"
  citationComponent={
    <MarkdownWithImageCitation
      citationTitle="Workspace Note"
      markdownContent={markdownContent}
      relevanceScore={98}
    />
  }
  chevronDownComponent={<span>▼</span>}
  chevronUpComponent={<span>▲</span>}
/>

Component Props Reference

AiReasoningCitation Props

| Prop Name | Type | Required | Description | |-----------|------|----------|-------------| | title | string | ❌ | Title on the main pill | | citationIcon | ReactNode | ❌ | Icon on the main Pill | | aiReason | TAIReasoning | ✅ | Contains id, reason, gap, relevance_score | | citationList | Citations | ✅ | Lookup object for all referenced files/images/web | | aiReasoningAccordionProps | Object | ✅ | Must contain icons: { chevronUp, chevronDown } | | projectDetails | Array | ❌ | Context for specific app-mod logic | | cachingConfig | Object | ❌ | For using gsUtilPath instead of signedUrl | | iconConfig | Object | ❌ | Custom icons: citationIcon, reasoningIcon, gapIcon | | titleConfig | Object | ❌ | Custom titles for sections | | styles | Object | ❌ | Deep style overrides |

ImageCitationContent Props

| Prop Name | Type | Required | Description | |-----------|------|----------|-------------| | signedUrl | string | ✅ | Direct URL to the image | | gsUtilPath | string | ✅ | GCS Path (requires cachingConfig) | | citationTitle | string | ❌ | Title shown in header (default: "Visual Reference") | | relevanceScore | number | ❌ | Score to display (0-100) | | closeCitationConfig | Object | ❌ | { CloseIcon, handleCloseCitationPreview } | | cachingConfig | Object | ❌ | For GCS URL resolution | | styles | Object | ❌ | Deep style overrides |

*Either signedUrl or gsUtilPath must be provided

FileCitationContent Props

| Prop Name | Type | Required | Description | |-----------|------|----------|-------------| | title | string | ✅ | Title shown in the viewer header | | signedUrl | string | ✅ | Direct URL to the PDF | | gsUtilPath | string | ✅ | GCS Path (requires cachingConfig) | | relevanceScore | number | ❌ | Score to display (0-100) | | closeCitationConfig | Object | ❌ | { CloseIcon, handleCloseCitationPreview } | | cachingConfig | Object | ❌ | For GCS URL resolution | | styles | Object | ❌ | Deep style overrides including pdfWrapper height |

*Either signedUrl or gsUtilPath must be provided

WebCitationWithImageContent Props

| Prop Name | Type | Required | Description | |-----------|------|----------|-------------| | url | string | ✅ | The actual link to visit | | label | string | ✅ | Text for the link anchor | | signedUrl | string | ✅ | URL for the screenshot image | | gsUtilPath | string | ✅ | GCS Path (requires cachingConfig) | | PreviewDialogCloseIcon | Component | ✅ | Icon for fullscreen modal close button | | visitIcon | Component | ✅ | Icon for the "Visit Link" button | | relevanceScore | number | ❌ | Score to display (0-100) | | closeCitationConfig | Object | ❌ | { CloseIcon, handleCloseCitationPreview } | | cachingConfig | Object | ❌ | For GCS URL resolution | | styles | Object | ❌ | Deep style overrides |

*Either signedUrl or gsUtilPath must be provided

MarkdownWithImageCitation Props

| Prop Name | Type | Required | Description | |-----------|------|----------|-------------| | markdownContent | string | ✅ | Markdown/HTML string to render. Inline <img /> tags are supported. | | citationTitle | string | ❌ | Title shown in the header. Defaults to "Markdown With Image". | | timestamp | string | ❌ | Optional subtitle shown below the title. | | relevanceScore | number | ❌ | Confidence score to display in the header badge (0–100). | | closeCitationConfig | Object | ❌ | { CloseIcon, handleCloseCitationPreview } — renders a close button in the header. | | styles | Object | ❌ | Deep style overrides for container, header, image wrapper, and markdown regions. |


Required peer dependencies:

npm install react-markdown rehype-raw @react-pdf-viewer/core @material-ui/core

VideoCitationContent

Overview

VideoCitationContent is a React component for rendering video citations with a built-in media player, relevance score display, and optional close button. It supports both direct video URLs and Google Cloud Storage paths (resolved to signed URLs via cachingConfig). The player (react-player) is loaded dynamically at runtime to avoid bundling it when unused.

Features

  • Dynamic player loadingreact-player is imported at runtime; displays a graceful error if not installed
  • GCS signed URL resolution — Accepts gsUtilPath and resolves it to a playable URL via cachingConfig
  • Configurable playback — Control autoplay, looping, mute, volume, and dimensions via playerConfig
  • Relevance score badge — Displays AI confidence score in the header
  • Optional close button — Pass closeCitationConfig to show a close icon in the header
  • Deep style overrides — Every visual region is customizable via the styles prop

Usage

import { CitationRenderer } from '@e-llm-studio/citation/CitationRenderer'
import VideoCitationContent from '@e-llm-studio/citation/VideoCitationContent'

<CitationRenderer
  inLineCitation={true}
  citationTitle="Video Reference"
  citationComponent={
    <VideoCitationContent
      citationTitle="Demo Video"
      timestamp="March 23, 2026 - 10:45 AM"
      relevanceScore={90}
      videoUrl="https://example.com/sample.mp4"
      playerConfig={{
        controls: true,
        playing: false,
        loop: false,
        muted: false,
        volume: 0.8,
        width: "100%",
        height: "100%",
      }}
      styles={{
        videoWrapper: { minHeight: "400px" },
      }}
    />
  }
  chevronDownComponent={<span>▼</span>}
  chevronUpComponent={<span>▲</span>}
/>

With GCS path (requires cachingConfig):

<VideoCitationContent
  citationTitle="Meeting Recording"
  timestamp="March 23, 2026 - 10:45 AM"
  relevanceScore={85}
  gsUtilPath="gs://my-bucket/recordings/meeting.mp4"
  cachingConfig={{
    queryClient,
    useGetSignedUrlQuery,
    useGetSignedUrlMutation,
  }}
  closeCitationConfig={{
    CloseIcon: () => <span>✕</span>,
    handleCloseCitationPreview: () => console.log("Closed"),
  }}
/>

Note: VideoCitationContent dynamically imports react-player at runtime. Ensure it is installed:

npm install react-player

If not installed, the component will display an inline error instead of the player.

Props

| Prop Name | Type | Required | Description | |-----------|------|----------|-------------| | videoUrl | string | ❌ | Direct URL to the video. Takes priority over gsUtilPath. | | gsUtilPath | string | ❌ | GCS path to the video (requires cachingConfig to resolve). | | timestamp | string | ❌ | Optional subtitle shown below the title (e.g. a date or time string). | | citationTitle | string | ❌ | Title shown in the header. Defaults to "Video Reference". | | relevanceScore | number | ❌ | Confidence score to display in the header badge (0–100). | | playerConfig | Object | ❌ | Playback overrides — see table below. | | closeCitationConfig | Object | ❌ | { CloseIcon, handleCloseCitationPreview } — renders a close button in the header. | | cachingConfig | Object | ❌ | { queryClient, useGetSignedUrlQuery, useGetSignedUrlMutation } — required when using gsUtilPath. | | styles | Object | ❌ | Deep style overrides — see table below. |

*Either videoUrl or gsUtilPath must be provided.

playerConfig options

| Key | Type | Default | Description | |-----|------|---------|-------------| | controls | boolean | true | Show native player controls | | playing | boolean | false | Autoplay on mount | | loop | boolean | false | Loop the video | | muted | boolean | false | Start muted | | volume | number | 0.8 | Initial volume (0–1) | | width | string | "100%" | Player width | | height | string | "100%" | Player height |

styles keys

| Key | Description | |-----|-------------| | container | Outer component wrapper | | header | Header bar (title + right-side actions) | | titleGroup | Wrapper around the title and timestamp | | title | Title text element | | timestamp | Subtitle text shown below the title | | headerRight | Right side of header (score + divider + close) | | divider | Vertical divider between score and close icon | | closeIconWrapper | Clickable wrapper around the close icon | | videoWrapper | Wrapper around the react-player instance | | loaderContainer | Centered loader shown while signing URL or loading player | | loaderText | Text below the loader spinner | | aiConfidenceDisplayPill.container | Relevance score badge container |

ScannedDocCitation

Overview

ScannedDocCitation is a React component for displaying scanned document pages with interactive bounding box highlight overlays. Built for Google Document AI output, it supports multi-page scrolling, highlight navigation via arrows, and a fullscreen view.

Features

  • Multi-page scrolling — All pages stacked vertically inside a fixed-height scrollable container
  • Bounding box highlights — Overlay highlights on document pages using normalized (0–1) coordinates
  • Highlight navigation — Jump between highlights using ↑↓ arrows, auto-scrolls to active highlight
  • Fullscreen modal — Expand to a larger view for detailed examination
  • Customizable highlight colors — Control highlight color, active color, and border color
  • Lazy highlight rendering — Highlights only appear after the image has fully loaded, preventing bounding boxes from showing on blank pages
  • Pass citationPage - You can now pass citationPage instead of passing images and highlights as seprate
  • Control citation label - You can now use citation lable and control it behaviour by props

Usage

import ScannedDocCitation from '@e-llm-studio/citation/ScannedDocCitation'

const BACKEND_CITATIONS = [
  {
    customMetaData: {
      citation_number: 1,
      gs_url: "https://storage.googleapis.com/temp_storage_data_ingest/chunk_outputs/123-1121234567512111221102311211201111/_Artifact%20Search%20Response%20format/a0e91e41-255b-404e-a5a3-899f9f760a9a.png?X-Goog-Algorithm=GOOG4-RSA-SHA256&X-Goog-Credential=ellm-studio%40proposal-auto-ai-internal.iam.gserviceaccount.com%2F20260311%2Fauto%2Fstorage%2Fgoog4_request&X-Goog-Date=20260311T171935Z&X-Goog-Expires=604800&X-Goog-SignedHeaders=host&X-Goog-Signature=1cc5beae8c1a386d182b34044eb1a207d7c11e6477fff242d6d2a1eb23387a85ce3aa763b979feadb41bc176bd8fd4371f813a0446bfb861d1db72a40808fd74bf",
      highlighted_coordinates: [
        { xmin: 0.2855, ymin: 0.5812, xmax: 0.7882, ymax: 0.5915 },
        { xmin: 0.1176, ymin: 0.7006, xmax: 0.8784, ymax: 0.7273 },
      ],
    },
  },
  {
    customMetaData: {
      citation_number: 2,
      gs_url: "https://storage.googleapis.com/temp_storage_data_ingest/chunk_outputs/123-1121234567512111221102311211201111/_Artifact%20Search%20Response%20format/7fef8f3e-25de-4c29-a9be-02dfd9643b0b.png?X-Goog-Algorithm=GOOG4-RSA-SHA256&X-Goog-Credential=ellm-studio%40proposal-auto-ai-internal.iam.gserviceaccount.com%2F20260311%2Fauto%2Fstorage%2Fgoog4_request&X-Goog-Date=20260311T171935Z&X-Goog-Expires=604800&X-Goog-SignedHeaders=host&X-Goog-Signature=79772ff7ebb758047c11bc276ce5c5a976eec830f96e92e2303da91cee72cdc7e8d22e0d0207b537ab78ba6b7cd7f6bb5808b7bd5fbba61861a5d1478affbb39b4",
      highlighted_coordinates: [
        { xmin: 0.1176, ymin: 0.5885, xmax: 0.7969, ymax: 0.643 },
      ],
    },
  },
  {
    customMetaData: {
      citation_number: 3,
      gs_url: "https://storage.googleapis.com/temp_storage_data_ingest/chunk_outputs/123-1121234567512111221102311211201111/CW%20Buttons%20with%20or%20without%20Cognitive%20Decisioning%20Icons/6f11ae86-53ef-43f0-b21a-4bf52700f68f.png?X-Goog-Algorithm=GOOG4-RSA-SHA256&X-Goog-Credential=ellm-studio%40proposal-auto-ai-internal.iam.gserviceaccount.com%2F20260311%2Fauto%2Fstorage%2Fgoog4_request&X-Goog-Date=20260311T171935Z&X-Goog-Expires=604800&X-Goog-SignedHeaders=host&X-Goog-Signature=71b4873b97b53c35b529ed4b4ef5c7e6d085c4d4820cd4e7e1ddbabce5cf7975",
      highlighted_coordinates: [
        { xmin: 0.1176, ymin: 0.1624, xmax: 0.8322, ymax: 0.1909 },
        { xmin: 0.1176, ymin: 0.6624, xmax: 0.8329, ymax: 0.6915 },
      ],
    },
  },
]

// Each citation = one page. citation_number is 1-based, pageIndex is 0-based.
const images = BACKEND_CITATIONS.map((c) => c.customMetaData.gs_url)

const highlights = BACKEND_CITATIONS.flatMap((c) =>
  c.customMetaData.highlighted_coordinates.map((coord) => ({
    pageIndex: c.customMetaData.citation_number - 1,
    bboxes: [coord],
  }))
)

<ScannedDocCitation
  images={images}
  highlights={highlights}
  height="700px"
/>

New usage based on pages prop :

import ScannedDocCitation from "./features/ScannedDocCitation/ScannedDocCitation";

const BACKEND_CITATIONS = [
  {
    agent_name: "ContextFileAgent",
    title: "ECG_Brainstorming_Integration.pdf",
    url: "https://storage.googleapis.com/...png",
    description: "",
    metadata: {},
    citation_number: 1,
    filter: false,
    artifact_id: "019cfac1-e92e-792b-bdea-960e954d6912",
    customMetaData: {
      citation_number: 1,
      value: [
        {
          gs_url: "https://storage.googleapis.com/...png",
          page_no: 1,
          dimensions: { unit: "pixels", width: 1241, height: 1754 },
          highlighted_coordinates: [
            { xmin: 0.5246, ymin: 0.5547, xmax: 0.6567, ymax: 0.5678 },
          ],
          highlighted_text: [
            {
              text: "stormee x eCG",
              excerpt_from_document: "...",
              page_no: 1,
              reasoning: ["..."],
              gap: ["..."],
              score: 50,
            },
          ],
        },
      ],
    },
  },
];

// Flatten all citation pages
const allPages = BACKEND_CITATIONS.flatMap(
  (c) => c?.customMetaData?.value || []
);

export default function ScannedDocCitationTest() {
  return (
    <div style={{ padding: 16, maxWidth: 720 }}>
      <h3
        style={{
          fontFamily: "Plus Jakarta Sans, sans-serif",
          marginBottom: 12,
        }}
      >
        Scanned Doc Citation Test
      </h3>

      <ScannedDocCitation pages={allPages} />
    </div>
  );
}

With custom highlight colors:

<ScannedDocCitation
  images={imageUrls}
  highlights={highlights}
  highlightColor="rgba(100, 160, 255, 0.3)"
  highlightActiveColor="rgba(100, 160, 255, 0.6)"
  highlightBorderColor="rgba(50, 100, 220, 0.8)"
/>

Single citation at a time:

If rendering one citation at a time with a single image, always use pageIndex: 0 regardless of citation_number.

const images = citation?.customMetaData?.gs_url
  ? [citation.customMetaData.gs_url]
  : [];

const highlights =
  citation?.customMetaData?.highlighted_coordinates?.map((coord) => ({
    pageIndex: 0,  // always 0 since images array has only 1 image
    bboxes: [coord],
  })) ?? [];

return <ScannedDocCitation images={images} highlights={highlights} />;

Props

| Prop | Type | Required | Default | Description | |------|------|----------|---------|-------------| | pages | CitationPage[] | ✅ | — | Ordered array of CitationPage objects containing:gs_url: stringpage_no?: numberhighlighted_coordinates?: BBox[]dimensions?: Dimensionshighlighted_text?: HighlightedText[] | | images | string[] | ✅ | — | Array of pre-signed GCS image URLs, one per page | | highlights | PageHighlight[] | ✅ | — | Array of highlight groups with bounding boxes per page | | highlightColor | string | ❌ | rgba(255, 220, 0, 0.15) | Background color of inactive highlights | | citationLabelColor | string | ❌ | #FFFF2E | Background color of the citation label. | | subHeadingText | string | ❌ | "" | Gives you option to add a heading to ScannedDocCitation. | | showFullScreenMode | boolean | ❌ | true | Gives you option to toggle fullscreen tool in renderNav. | | showCitationLabelOnHover | boolean | ❌ | true | Show label only on hover (if false → always visible). | | highlightActiveColor | string | ❌ | rgba(255, 220, 0, 0.35) | Background color of the currently active highlight | | highlightBorderColor | string | ❌ | rgba(200, 160, 0, 0.4) | Border color of the active highlight | | height | string \| number | ❌ | "700px" | Maximum height of the scrollable container. Shrinks to fit content if content is shorter. | | subHeadingTitleInsideModal | string | ❌ | — | Title shown in the fullscreen modal header. Separate from subHeadingText which appears above the normal (non-modal) view. | | scrollToFirstCitation | boolean | ❌ | false | When true, automatically scrolls the container to the first citation/bounding box once the page image has loaded. | | showPageSeparator | boolean | ❌ | true | When true, renders a thin horizontal divider line between pages to make page breaks visually distinct. | | pageSeparatorColor | string | ❌ | "#e2e8f0" | CSS color value for the page separator line. Only used when showPageSeparator is true. |

Type Definitions

interface BBox {
  xmin: number;  // normalized 0–1 (provided directly by backend)
  ymin: number;
  xmax: number;
  ymax: number;
}

interface PageHighlight {
  pageIndex: number;  // zero-based index matching the images array
  bboxes: BBox[];
}
export interface Dimensions {
  unit: string;
  width: number;
  height: number;
}

export interface HighlightedText {
  text: string;
  excerpt_from_document: string;
  page_no: number;
  reasoning: string[];
  gap: string[];
  score: number;
}

export interface CitationPage {
  gs_url: string;
  page_no?: number;
  highlighted_coordinates?: BBox[];
  dimensions?: Dimensions;
  highlighted_text?: HighlightedText[];
}

interface ScannedDocCitationProps {
  images: string[];
  highlights: PageHighlight[];
  pages?: CitationPage[]; 
  citationLabelColor?: string;
  showCitationLabelOnHover?: boolean;
  highlightColor?: string;
  highlightActiveColor?: string;
  highlightBorderColor?: string;
  height?: string | number;
}

Note: Coordinates in highlighted_coordinates are already normalized (0–1) by the backend. No pixel conversion needed before passing them to the component.

Other Components

Bookemon

Overvie