doc-preview.tsx
Overview
doc-preview.tsx defines a React functional component named DocPreviewer that fetches a document from a given URL, converts it from a binary Microsoft Word format (.docx) into sanitized HTML using the mammoth library, and renders the resulting content inside a styled container. It provides a loading spinner while the document is being fetched and parsed, and displays error messages on failure.
This component is primarily used for previewing Word documents directly in a web UI without requiring the user to download and open the file in an external application.
Detailed Explanation
DocPreviewer Component
interface DocPreviewerProps {
className?: string;
url: string;
}
Props:
className(optional): A string of additional CSS class names to customize styling of the container.url(required): A string URL pointing to the document resource to fetch and preview.
export const DocPreviewer: React.FC<DocPreviewerProps> = ({ className, url }) => { ... }
Description:
Main React functional component that:Fetches the document blob from
url.Converts it to HTML using
mammoth.Formats the HTML by injecting custom CSS classes.
Displays the formatted HTML or a spinner during loading.
Handles errors gracefully by showing messages.
Internal State:
htmlContent(string): Stores the converted HTML content to be displayed.loading(boolean): Tracks whether the document is currently being fetched and parsed.
Internal Function: fetchDocument
const fetchDocument = async () => { ... }
Purpose:
Asynchronously fetches the document file from theurlprop, converts it to HTML, applies styling, and updates component state.Implementation Details:
Sets
loadingtotrueto trigger the spinner.Uses the custom
requestutility to GET the document as ablob.onErrorcallback shows a toast message and logs an error if fetching fails.
Converts the blob’s ArrayBuffer to HTML using
mammoth.convertToHtml.The option
{ includeDefaultStyleMap: true }tells Mammoth to apply its default style mappings.
Applies additional CSS classes to
<p>and<h1>–<h6>tags by regex replace:Paragraphs get a bottom margin with
mb-2.Headings get font-weight and margin classes.
Updates
htmlContentstate with the styled HTML.Handles parsing errors by displaying an error message and logging.
Finally sets
loadingtofalse.
Usage Example:
This function is internally called inside a ReactuseEffecthook whenever theurlchanges.
React useEffect Hook
useEffect(() => {
if (url) {
fetchDocument();
}
}, [url]);
Purpose:
Automatically triggersfetchDocumentwhen the component mounts or when theurlprop changes.Behavior:
Ifurlis falsy (empty or undefined), no request is made.
JSX Render Output
return (
<div className={classNames(..., className)}>
{loading && (
<div className="absolute inset-0 flex items-center justify-center">
<Spin />
</div>
)}
{!loading && <div dangerouslySetInnerHTML={{ __html: htmlContent }} />}
</div>
);
Container
<div>:Styled with a combination of fixed TailwindCSS classes and an optional external
className.Styles create a bordered, padded, rounded box with background color for the preview area.
Loading State:
While
loadingistrue, a centered<Spin />component (loading spinner) overlays the container.
Content State:
When not loading, the converted and styled HTML content is injected via
dangerouslySetInnerHTML.This allows rendering complex HTML content from the Word document.
Important Implementation Details
Document Fetching:
Uses a customrequestutility (likely a wrapper overfetchoraxios) with response type set to'blob'to handle binary data.Word to HTML Conversion:
Leveraging themammothlibrary which focuses on semantic conversion without embedding Word-specific styles, producing clean, accessible HTML.Styling Enhancements:
Post-processing HTML to add TailwindCSS utility classes to paragraphs and headings for consistent spacing and font weight.Error Handling:
Errors in fetching or parsing show a user-friendly message via the importedmessageUI component and log details to console for debugging.Security Considerations:
UsesdangerouslySetInnerHTML— the HTML is generated bymammothand minimally processed, so it is important that the source documents are trusted or sanitized upstream.
Interaction with Other Parts of the System
UI Components:
Imports and uses:
message(for showing error notifications)Spin(loading spinner)
These are likely shared UI components from the project’s component library (
@/components/ui).
Utilities:
Uses a custom
requestfunction (@/utils/request) for HTTP calls that supports error handling and response type configuration.
Styling:
Uses
classnamesfor conditional and compositional CSS class management.Applies TailwindCSS utility classes within the component.
Document Conversion:
Relies on
mammothnpm package to parse.docxfiles into HTML.
Prop Dependency:
The component is controlled externally by passing a valid
urlprop for the document to preview.
Usage Example
import { DocPreviewer } from './doc-preview';
function DocumentPage() {
const documentUrl = 'https://example.com/path/to/document.docx';
return (
<div className="max-w-4xl mx-auto my-8">
<DocPreviewer url={documentUrl} className="h-[600px]" />
</div>
);
}
This example renders the DocPreviewer in a page with a fixed height, fetching and displaying the Word document from the given URL.
Mermaid Component Diagram
componentDiagram
component DocPreviewer {
+className?: string
+url: string
--
+fetchDocument(): Promise<void>
+render(): JSX.Element
}
component "Spin (Loader)" as Spin
component "message (UI Notification)" as message
component "request (HTTP Utility)" as request
component "mammoth (Docx to HTML)" as mammoth
DocPreviewer --> Spin : uses for loading state
DocPreviewer --> message : uses for error display
DocPreviewer --> request : fetches document blob
DocPreviewer --> mammoth : converts docx to HTML
Summary
doc-preview.tsx provides a reusable React component for previewing Microsoft Word documents by fetching them from a URL, converting to clean HTML with mammoth, and rendering the content with consistent styling and loading/error feedback. It fits into an application as a document viewer UI element that integrates with shared utilities and components for requests, UI feedback, and spinners.