DOCX source adapter
retab-ui/docx-sourceFreeComponent
Bridges the document-source model to the DOCX viewer: docxAnchorToTarget and sourceToDocxHighlight for docx_text_span and docx_table_cell anchors.
Install it
npx shadcn@latest add https://ui.retab.com/r/docx-source.jsonSource
1"use client";23import * as React from "react";45import type { Source, SourceAnchor } from "@/lib/document-source";6import type { DocxTarget, DocxViewerHandle } from "@/components/ui/docx-viewer";78export interface SourceTarget {9 scrollTo?: (source: Source, options: { behavior: ScrollBehavior }) => void;10}1112/**13 * A docx anchor + source payload -> a viewer-ready `DocxTarget`, or null when14 * the anchor is not a docx anchor. Text spans carry the quoted `content` from15 * the source; table cells carry their index. The adapter resolves the source16 * model, while the viewer resolves the rendered DOM.17 */18export function docxAnchorToTarget(19 anchor: SourceAnchor | undefined,20 source?: Source,21): DocxTarget | null {22 if (!anchor) return null;23 if (anchor.kind === "docx_text_span") {24 if (25 !isNonNegativeInteger(anchor.paragraph) ||26 !isValidOptionalRange(anchor.char_start, anchor.char_end)27 )28 return null;29 const text = source?.content.trim();30 return text ? { kind: "text", text } : null;31 }32 if (anchor.kind === "docx_table_cell") {33 if (34 !isNonNegativeInteger(anchor.table) ||35 !isNonNegativeInteger(anchor.row) ||36 !isNonNegativeInteger(anchor.column) ||37 !isValidOptionalRange(anchor.char_start, anchor.char_end)38 )39 return null;40 return {41 kind: "cell",42 table: anchor.table,43 row: anchor.row,44 column: anchor.column,45 };46 }47 return null;48}4950function isNonNegativeInteger(value: number) {51 return Number.isInteger(value) && value >= 0;52}5354function isValidOptionalRange(start?: number, end?: number) {55 if (start == null && end == null) return true;56 if (start == null || end == null) return false;57 return (58 Number.isInteger(start) &&59 Number.isInteger(end) &&60 start >= 0 &&61 end >= start62 );63}6465/** A stable source target over a `DocxViewer` ref. */66export function useDocxSourceTarget(67 viewerRef: React.RefObject<DocxViewerHandle | null>,68): SourceTarget {69 return React.useMemo<SourceTarget>(70 () => ({71 scrollTo: (source: Source, options) => {72 const target = docxAnchorToTarget(source.anchor, source);73 if (target) viewerRef.current?.scrollToTarget(target, options);74 },75 }),76 [viewerRef],77 );78}7980/**81 * The `highlight` prop for `DocxViewer` derived from a source; non-docx82 * anchors resolve to null.83 */84export function sourceToDocxHighlight(85 source: Source | undefined,86): DocxTarget | null {87// … truncated
What it pulls in
Other registry items
Files it writes
More from retab-ui
All 130 items| Component | Registry | Kind | Access | Installs | Command |
|---|---|---|---|---|---|
| Alertalert | retab-ui | Components | Free | 1 dep | |
| Alert Dialogalert-dialog | retab-ui | Components | Free | 1 dep | |
| Aspect Ratioaspect-ratio | retab-ui | Components | Free | no deps | |
| Attachment Sidebarattachment-sidebar | retab-ui | Components | Free | 1 dep | |
| Autocompleteautocomplete | retab-ui | Components | Free | 2 deps | |
| Calendarcalendar | retab-ui | Components | Free | 2 deps | |
| Code Viewercode-viewer | retab-ui | Components | Free | 2 deps · 32 files | |
| Commandcommand | retab-ui | Components | Free | 2 deps |
