@arbidocs/blocks 0.4.143 → 0.4.144

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (130) hide show
  1. package/dist/agents/index.cjs +264 -264
  2. package/dist/agents/index.js +7 -7
  3. package/dist/{chunk-IJST4EBM.js → chunk-2FJMTZNJ.js} +8 -8
  4. package/dist/{chunk-IJST4EBM.js.map → chunk-2FJMTZNJ.js.map} +1 -1
  5. package/dist/{chunk-FJETR2AS.js → chunk-33ZOUJXA.js} +4 -4
  6. package/dist/{chunk-FJETR2AS.js.map → chunk-33ZOUJXA.js.map} +1 -1
  7. package/dist/{chunk-IXWJGOM2.js → chunk-3RJN2VTL.js} +3 -3
  8. package/dist/{chunk-IXWJGOM2.js.map → chunk-3RJN2VTL.js.map} +1 -1
  9. package/dist/{chunk-YKQ2DPIP.js → chunk-444XKG46.js} +3 -3
  10. package/dist/{chunk-YKQ2DPIP.js.map → chunk-444XKG46.js.map} +1 -1
  11. package/dist/{chunk-XVUOMWMD.cjs → chunk-5FTIHRZH.cjs} +4 -4
  12. package/dist/{chunk-XVUOMWMD.cjs.map → chunk-5FTIHRZH.cjs.map} +1 -1
  13. package/dist/{chunk-ECW2R2KF.cjs → chunk-65THHQVB.cjs} +27 -27
  14. package/dist/{chunk-ECW2R2KF.cjs.map → chunk-65THHQVB.cjs.map} +1 -1
  15. package/dist/{chunk-Y4ATWQGV.js → chunk-7NGAWGA3.js} +3 -3
  16. package/dist/{chunk-Y4ATWQGV.js.map → chunk-7NGAWGA3.js.map} +1 -1
  17. package/dist/{chunk-T5B7FM7S.js → chunk-A6J2IBUG.js} +4 -4
  18. package/dist/{chunk-T5B7FM7S.js.map → chunk-A6J2IBUG.js.map} +1 -1
  19. package/dist/{chunk-RB7GX2VT.cjs → chunk-ABUO6PIQ.cjs} +12 -12
  20. package/dist/{chunk-RB7GX2VT.cjs.map → chunk-ABUO6PIQ.cjs.map} +1 -1
  21. package/dist/{chunk-NRFAWUVD.js → chunk-BPBSSMRB.js} +3 -3
  22. package/dist/{chunk-NRFAWUVD.js.map → chunk-BPBSSMRB.js.map} +1 -1
  23. package/dist/{chunk-HAOKT4LC.cjs → chunk-BUWBXJ2N.cjs} +5 -5
  24. package/dist/{chunk-HAOKT4LC.cjs.map → chunk-BUWBXJ2N.cjs.map} +1 -1
  25. package/dist/{chunk-KPZZ5FHE.cjs → chunk-C4WSHRR6.cjs} +12 -32
  26. package/dist/chunk-C4WSHRR6.cjs.map +1 -0
  27. package/dist/{chunk-J5CWKFSC.js → chunk-CYNF5PZI.js} +3 -3
  28. package/dist/{chunk-J5CWKFSC.js.map → chunk-CYNF5PZI.js.map} +1 -1
  29. package/dist/{chunk-VTTZZ4FN.js → chunk-DLBUFHLY.js} +74 -4
  30. package/dist/chunk-DLBUFHLY.js.map +1 -0
  31. package/dist/{chunk-YSHIC4NJ.cjs → chunk-HEMU73OP.cjs} +4 -4
  32. package/dist/{chunk-YSHIC4NJ.cjs.map → chunk-HEMU73OP.cjs.map} +1 -1
  33. package/dist/{chunk-UTTTJSQU.cjs → chunk-HFGXA5CL.cjs} +4 -4
  34. package/dist/{chunk-UTTTJSQU.cjs.map → chunk-HFGXA5CL.cjs.map} +1 -1
  35. package/dist/{chunk-H4D7WKDY.js → chunk-I7WG3JRD.js} +3 -3
  36. package/dist/{chunk-H4D7WKDY.js.map → chunk-I7WG3JRD.js.map} +1 -1
  37. package/dist/{chunk-SZOFGU7W.js → chunk-LYUO3E6V.js} +3 -3
  38. package/dist/{chunk-SZOFGU7W.js.map → chunk-LYUO3E6V.js.map} +1 -1
  39. package/dist/{chunk-TC3RQNEX.cjs → chunk-MJCCBMM5.cjs} +80 -6
  40. package/dist/chunk-MJCCBMM5.cjs.map +1 -0
  41. package/dist/{chunk-LPYEUD2D.cjs → chunk-O2ODDTMA.cjs} +9 -9
  42. package/dist/{chunk-LPYEUD2D.cjs.map → chunk-O2ODDTMA.cjs.map} +1 -1
  43. package/dist/{chunk-5YHEHEJT.js → chunk-ON3TKY5Y.js} +4 -242
  44. package/dist/chunk-ON3TKY5Y.js.map +1 -0
  45. package/dist/{chunk-U73KPFYH.cjs → chunk-QIMVTGKS.cjs} +2 -255
  46. package/dist/chunk-QIMVTGKS.cjs.map +1 -0
  47. package/dist/{chunk-DTROMMDX.cjs → chunk-R26BK7YL.cjs} +4 -4
  48. package/dist/{chunk-DTROMMDX.cjs.map → chunk-R26BK7YL.cjs.map} +1 -1
  49. package/dist/{chunk-U6YVZDOV.cjs → chunk-RA3ZJ45L.cjs} +13 -13
  50. package/dist/{chunk-U6YVZDOV.cjs.map → chunk-RA3ZJ45L.cjs.map} +1 -1
  51. package/dist/{chunk-EF4ZLKRM.js → chunk-RI6DZA5X.js} +3 -3
  52. package/dist/{chunk-EF4ZLKRM.js.map → chunk-RI6DZA5X.js.map} +1 -1
  53. package/dist/{chunk-KMZWKSKO.cjs → chunk-TP6PLDNM.cjs} +8 -8
  54. package/dist/{chunk-KMZWKSKO.cjs.map → chunk-TP6PLDNM.cjs.map} +1 -1
  55. package/dist/{chunk-EYKISBDO.cjs → chunk-WS5EX7DN.cjs} +5 -5
  56. package/dist/{chunk-EYKISBDO.cjs.map → chunk-WS5EX7DN.cjs.map} +1 -1
  57. package/dist/{chunk-C44TDH54.js → chunk-X3TGXEFS.js} +6 -6
  58. package/dist/{chunk-C44TDH54.js.map → chunk-X3TGXEFS.js.map} +1 -1
  59. package/dist/{chunk-O2GW5IY6.cjs → chunk-XGZX22ET.cjs} +38 -38
  60. package/dist/{chunk-O2GW5IY6.cjs.map → chunk-XGZX22ET.cjs.map} +1 -1
  61. package/dist/{chunk-OVR3XMYL.js → chunk-Y3KA6X7B.js} +4 -4
  62. package/dist/{chunk-OVR3XMYL.js.map → chunk-Y3KA6X7B.js.map} +1 -1
  63. package/dist/{chunk-COCGRJLA.cjs → chunk-YFY3TQ6Q.cjs} +7 -7
  64. package/dist/{chunk-COCGRJLA.cjs.map → chunk-YFY3TQ6Q.cjs.map} +1 -1
  65. package/dist/{chunk-TBEVGWY3.js → chunk-YNIBUKV5.js} +14 -32
  66. package/dist/chunk-YNIBUKV5.js.map +1 -0
  67. package/dist/citations/index.cjs +12 -12
  68. package/dist/citations/index.js +3 -3
  69. package/dist/connect/docx.cjs +10 -10
  70. package/dist/connect/docx.js +7 -7
  71. package/dist/connect/index.cjs +322 -709
  72. package/dist/connect/index.cjs.map +1 -1
  73. package/dist/connect/index.d.ts +0 -1
  74. package/dist/connect/index.js +214 -588
  75. package/dist/connect/index.js.map +1 -1
  76. package/dist/connection/ConnectedSettings.d.ts +2 -3
  77. package/dist/facts/index.cjs +3 -3
  78. package/dist/facts/index.js +2 -2
  79. package/dist/files/index.cjs +3 -3
  80. package/dist/files/index.js +2 -2
  81. package/dist/home/index.cjs +20 -20
  82. package/dist/home/index.js +4 -4
  83. package/dist/index.cjs +440 -449
  84. package/dist/index.cjs.map +1 -1
  85. package/dist/index.d.ts +0 -1
  86. package/dist/index.js +16 -17
  87. package/dist/index.js.map +1 -1
  88. package/dist/provider/BlocksProvider.d.ts +1 -5
  89. package/dist/retrieval/index.cjs +4 -4
  90. package/dist/retrieval/index.js +2 -2
  91. package/dist/settings/ServerConnectionControls.d.ts +0 -16
  92. package/dist/settings/index.cjs +241 -178
  93. package/dist/settings/index.cjs.map +1 -1
  94. package/dist/settings/index.d.ts +1 -3
  95. package/dist/settings/index.js +198 -86
  96. package/dist/settings/index.js.map +1 -1
  97. package/dist/shell/index.cjs +44 -44
  98. package/dist/shell/index.js +3 -3
  99. package/dist/site/index.cjs +73 -74
  100. package/dist/site/index.js +2 -3
  101. package/dist/studio/index.cjs +74 -75
  102. package/dist/studio/index.cjs.map +1 -1
  103. package/dist/studio/index.js +5 -6
  104. package/dist/studio/index.js.map +1 -1
  105. package/dist/workflow-canvas/index.cjs +21 -21
  106. package/dist/workflow-canvas/index.js +7 -7
  107. package/dist/workspaces/index.cjs +3 -3
  108. package/dist/workspaces/index.js +2 -2
  109. package/node_modules/@arbidocs/coedit/package.json +1 -1
  110. package/package.json +4 -4
  111. package/dist/chunk-5YHEHEJT.js.map +0 -1
  112. package/dist/chunk-KPZZ5FHE.cjs.map +0 -1
  113. package/dist/chunk-NHZK64TQ.js +0 -75
  114. package/dist/chunk-NHZK64TQ.js.map +0 -1
  115. package/dist/chunk-NWNVWO6L.cjs +0 -80
  116. package/dist/chunk-NWNVWO6L.cjs.map +0 -1
  117. package/dist/chunk-TBEVGWY3.js.map +0 -1
  118. package/dist/chunk-TC3RQNEX.cjs.map +0 -1
  119. package/dist/chunk-U73KPFYH.cjs.map +0 -1
  120. package/dist/chunk-VTTZZ4FN.js.map +0 -1
  121. package/dist/connection/settings-page/ConnectedAccountSettings.d.ts +0 -35
  122. package/dist/connection/settings-page/ConnectedMailSettings.d.ts +0 -13
  123. package/dist/connection/settings-page/ConnectedPremiumModels.d.ts +0 -1
  124. package/dist/connection/settings-page/ConnectedPrivacySettings.d.ts +0 -12
  125. package/dist/connection/settings-page/ConnectedSettingsPage.d.ts +0 -29
  126. package/dist/connection/settings-page/SessionStatusIcon.d.ts +0 -7
  127. package/dist/connection/settings-page/index.d.ts +0 -6
  128. package/dist/provider/settings-section.d.ts +0 -9
  129. package/dist/settings/AppearanceSettings.d.ts +0 -18
  130. package/dist/settings/SettingsPage.d.ts +0 -31
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/citations/PassagePill.tsx","../src/citations/CitationEditor.tsx"],"names":["jsxs","Fragment","jsx","cn","Tooltip","TooltipTrigger","TooltipContent","useBlocksEnvironment","useState","useRef","useEffect","Check","Copy","useMemo","useCallback","Textarea","DocumentEntity","formatPageRefs","X"],"mappings":"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","file":"chunk-YSHIC4NJ.cjs","sourcesContent":["import {\n useEffect,\n useRef,\n useState,\n type MouseEvent,\n type ReactElement,\n type ReactNode,\n} from 'react'\nimport { Check, Copy } from 'lucide-react'\nimport { Tooltip, TooltipContent, TooltipTrigger, cn } from '@arbidocs/react/ui'\nimport { useBlocksEnvironment } from '../provider/BlocksProvider'\n\n/** Every fixed string of the passage pill. */\nexport interface PassagePillLabels {\n copyLink: string\n /** Announced and notified after the link was copied. */\n copied: string\n /** Notified when the clipboard refused the write. */\n copyFailed: string\n viewPassage: string\n page: string\n pages: string\n passage: string\n passages: string\n /** Visible abbreviation of \"page\" in the pill (\"p.3\"). */\n pageAbbreviation: string\n}\n\nexport const DEFAULT_PASSAGE_PILL_LABELS: PassagePillLabels = {\n copyLink: 'Copy passage link',\n copied: 'Passage link copied',\n copyFailed: 'Could not copy the passage link',\n viewPassage: 'View passage',\n page: 'Page',\n pages: 'Pages',\n passage: 'Passage',\n passages: 'Passages',\n pageAbbreviation: 'p.',\n}\n\n/** Overridable `data-testid`s of the pill (defaults keep the app's existing ids). */\nexport interface PassagePillTestIds {\n root: string\n copy: string\n}\n\nexport interface PassagePillProps {\n /** Glyph of the cited document (host-supplied: file-type icon). */\n icon: ReactNode\n documentTitle: string\n /** `pill`: title + page; `icon`: glyph only; `compact`: page/passage ref + copy link. */\n variant?: 'icon' | 'pill' | 'compact'\n pageNumber?: number\n passageIndex?: number\n /** End of a contiguous passage run: the label collapses to \"4–9\" instead of a pill each. */\n passageIndexEnd?: number\n /** End page of a range: \"p.3–5(4–9)\". */\n pageNumberEnd?: number\n /** Makes the element a link. */\n href?: string\n /** Makes the element a button (ignored for the element role when `href` is set). */\n onClick?: (e: MouseEvent) => void\n showTooltip?: boolean\n labelMaxWidth?: string\n size?: 'sm' | 'base'\n className?: string\n labels?: Partial<PassagePillLabels>\n testIds?: Partial<PassagePillTestIds>\n /** Root test id (default `passage-entity`); the copy button gets `<id>-copy`. */\n testId?: string\n}\n\nconst COPIED_RESET_MS = 2000\n\n/** Plain-language name of a passage reference: \"Title, Page 3, Passage 4\". */\nfunction describePassage(\n documentTitle: string,\n l: PassagePillLabels,\n page: { text?: string; isRange: boolean },\n passage: { text?: string; isRange: boolean }\n): string {\n return [\n documentTitle,\n page.text !== undefined ? `${page.isRange ? l.pages : l.page} ${page.text}` : null,\n passage.text !== undefined\n ? `${passage.isRange ? l.passages : l.passage} ${passage.text}`\n : null,\n ]\n .filter(Boolean)\n .join(', ')\n}\n\ninterface PillSurfaceProps {\n href?: string\n onClick?: (e: MouseEvent) => void\n className: string\n testId: string\n /** What assistive tech reads; the visible content is hidden from it. */\n accessibleName: string\n children: ReactNode\n tooltip?: ReactNode\n tooltipSide?: 'top' | 'bottom'\n}\n\n/**\n * The ONE interactive element of a pill: a link, a button or (when there is no action) plain text.\n * Never nests another interactive element, so it is valid inside any host container.\n */\nfunction PillSurface({\n href,\n onClick,\n className,\n testId,\n accessibleName,\n children,\n tooltip,\n tooltipSide = 'bottom',\n}: PillSurfaceProps) {\n const content = (\n <>\n <span aria-hidden=\"true\" className=\"inline-flex min-w-0 items-center gap-1\">\n {children}\n </span>\n <span className=\"sr-only\">{accessibleName}</span>\n </>\n )\n const interactive = cn(\n 'relative cursor-pointer hover:bg-muted/80 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring',\n \"pointer-coarse:after:absolute pointer-coarse:after:inset-x-0 pointer-coarse:after:-inset-y-3 pointer-coarse:after:content-['']\"\n )\n\n let surface: ReactNode\n if (href) {\n surface = (\n <a\n href={href}\n target=\"_blank\"\n rel=\"noopener noreferrer\"\n className={cn(className, interactive)}\n onClick={onClick}\n data-testid={testId}\n >\n {content}\n </a>\n )\n } else if (onClick) {\n surface = (\n <button\n type=\"button\"\n className={cn(className, interactive)}\n onClick={onClick}\n data-testid={testId}\n >\n {content}\n </button>\n )\n } else {\n surface = (\n <span className={className} data-testid={testId}>\n {content}\n </span>\n )\n }\n\n if (!tooltip) return surface\n return (\n <Tooltip>\n <TooltipTrigger asChild>{surface as ReactElement}</TooltipTrigger>\n <TooltipContent side={tooltipSide}>{tooltip}</TooltipContent>\n </Tooltip>\n )\n}\n\nfunction CopyLinkButton({\n href,\n labels,\n testId,\n}: {\n href: string\n labels: PassagePillLabels\n testId: string\n}) {\n const { notify } = useBlocksEnvironment()\n const [copied, setCopied] = useState(false)\n const timer = useRef<ReturnType<typeof setTimeout> | null>(null)\n\n useEffect(\n () => () => {\n if (timer.current) clearTimeout(timer.current)\n },\n []\n )\n\n const handleCopy = async (e: MouseEvent) => {\n e.stopPropagation()\n try {\n await navigator.clipboard.writeText(href)\n } catch {\n // Say so instead of pretending: the host's notify surfaces the failure.\n notify(labels.copyFailed, 'error')\n return\n }\n setCopied(true)\n notify(labels.copied, 'success')\n if (timer.current) clearTimeout(timer.current)\n timer.current = setTimeout(() => setCopied(false), COPIED_RESET_MS)\n }\n\n return (\n <>\n <button\n type=\"button\"\n onClick={handleCopy}\n className=\"relative inline-flex items-center text-muted-foreground transition-colors hover:text-foreground focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring pointer-fine:min-h-6 pointer-fine:min-w-6 pointer-fine:justify-center pointer-coarse:min-h-11 pointer-coarse:min-w-11 pointer-coarse:justify-center\"\n title={labels.copyLink}\n aria-label={labels.copyLink}\n data-testid={testId}\n >\n {copied ? (\n <Check className=\"size-3\" aria-hidden=\"true\" />\n ) : (\n <Copy className=\"size-3\" aria-hidden=\"true\" />\n )}\n </button>\n <span role=\"status\" className=\"sr-only\">\n {copied ? labels.copied : ''}\n </span>\n </>\n )\n}\n\n/** A citation to a passage of a document, as a pill, a bare icon or a compact page reference. */\nexport function PassagePill({\n icon,\n documentTitle,\n variant = 'pill',\n pageNumber,\n passageIndex,\n passageIndexEnd,\n pageNumberEnd,\n href,\n className,\n onClick,\n showTooltip = true,\n labelMaxWidth,\n size = 'sm',\n labels,\n testIds,\n testId = 'passage-entity',\n}: PassagePillProps) {\n const l = { ...DEFAULT_PASSAGE_PILL_LABELS, ...labels }\n const ids: PassagePillTestIds = {\n root: testIds?.root ?? testId,\n copy: testIds?.copy ?? `${testIds?.root ?? testId}-copy`,\n }\n // Ranges collapse to \"4–9\"; a range of one renders as a plain \"4\".\n const isPassageRange = passageIndexEnd !== undefined && passageIndexEnd > (passageIndex ?? 0)\n const isPageRange = pageNumberEnd !== undefined && pageNumberEnd > (pageNumber ?? 0)\n const passageText = isPassageRange ? `${passageIndex}–${passageIndexEnd}` : `${passageIndex}`\n const pageText = isPageRange ? `${pageNumber}–${pageNumberEnd}` : `${pageNumber}`\n const accessibleName = describePassage(\n documentTitle,\n l,\n { text: pageNumber !== undefined ? pageText : undefined, isRange: isPageRange },\n { text: passageIndex !== undefined ? passageText : undefined, isRange: isPassageRange }\n )\n const hasAction = Boolean(href || onClick)\n\n if (variant === 'icon') {\n return (\n <PillSurface\n href={href}\n onClick={onClick}\n className={cn('inline-flex items-center rounded-sm', className)}\n testId={ids.root}\n accessibleName={accessibleName}\n tooltip={\n showTooltip ? (\n <div className=\"flex flex-col gap-0.5\">\n <span className=\"font-medium\">{documentTitle}</span>\n {(pageNumber !== undefined || passageIndex !== undefined) && (\n <span className=\"text-xs text-muted-foreground\">\n {pageNumber !== undefined && `${isPageRange ? l.pages : l.page} ${pageText}`}\n {pageNumber !== undefined && passageIndex !== undefined && ', '}\n {passageIndex !== undefined &&\n `${isPassageRange ? l.passages : l.passage} ${passageText}`}\n </span>\n )}\n </div>\n ) : undefined\n }\n >\n {icon}\n </PillSurface>\n )\n }\n\n if (variant === 'compact') {\n const label =\n [\n pageNumber !== undefined ? `${l.pageAbbreviation}${pageText}` : null,\n passageIndex !== undefined ? `(${passageText})` : null,\n ]\n .filter(Boolean)\n .join('') || '—'\n return (\n <span\n className={cn(\n 'inline-flex items-center gap-1 rounded-md border border-transparent bg-muted px-1 text-sm font-medium',\n className\n )}\n >\n <PillSurface\n href={href}\n onClick={onClick}\n className=\"inline-flex items-center gap-1 rounded-sm\"\n testId={ids.root}\n accessibleName={accessibleName}\n tooltip={showTooltip ? documentTitle : undefined}\n >\n {icon}\n <span className=\"leading-tight\">{label}</span>\n </PillSurface>\n {href && <CopyLinkButton href={href} labels={l} testId={ids.copy} />}\n </span>\n )\n }\n\n return (\n <PillSurface\n href={href}\n onClick={onClick}\n className={cn(\n 'group/pill inline-flex items-center rounded-md border border-border bg-muted transition-all',\n size === 'base' ? 'gap-1.5 px-1.5 py-0.5 text-base' : 'gap-1 px-1 text-sm',\n className\n )}\n testId={ids.root}\n accessibleName={accessibleName}\n tooltip={showTooltip && hasAction ? l.viewPassage : undefined}\n >\n {icon}\n <span\n className={cn(\n 'min-w-0 truncate font-medium leading-tight',\n labelMaxWidth ?? 'max-w-[320px]'\n )}\n >\n {documentTitle}\n </span>\n {pageNumber ? (\n <span className=\"flex-shrink-0 text-xs leading-none text-muted-foreground\">\n {l.pageAbbreviation}\n {pageText}\n </span>\n ) : null}\n </PillSurface>\n )\n}\n","/**\n * CitationEditor Component\n *\n * Note input plus the source passages backing it.\n * - Pick related documents; each opens so its passages can be chosen by reading\n * - Click a passage to add it, shift-click for a range; repeat across documents\n *\n * A note answers ONE question, so it has ONE set of sources. It used to carry a\n * map of citations, each with its own statement and character offsets, rendered\n * as inline highlighted spans with [n] badges — but the statements were copies\n * of the note text and the offsets spanned all of it, so the highlight was the\n * whole field. That machinery is gone; the note renders as plain text.\n *\n * ``activeCitationKey``/``onActiveCitationChange`` are kept because the viewer\n * and store thread them through to decide which field is receiving passages.\n * With a single citation the key is just a sentinel — see ONLY_CITATION_KEY.\n */\n\nimport { useCallback, useState, useRef, useEffect, useMemo } from 'react'\nimport { X } from 'lucide-react'\nimport { cn, DocumentEntity, Textarea, type DocumentLike } from '@arbidocs/react/ui'\nimport { formatPageRefs } from '../lib/format'\n\nimport type { components } from '@arbidocs/client'\n\ntype CitationSources = components['schemas']['CitationSources']\n\ntype Citations = CitationSources | null\n\nexport interface CitationEditorProps {\n value: string\n citations: Citations | null\n onChange: (note: string, citations: Citations | null) => void\n /** Currently active citation key (controlled from parent) */\n activeCitationKey?: string | null\n /**\n * Open a document in the viewer, armed to collect passages for this field —\n * and tag its first passage, so a chosen document is immediately a usable\n * citation. Passages are picked by reading, so citing means opening.\n *\n * The caller owns this because resolving \"first passage\" needs the parsed\n * document, and keeping that fetch out here is what lets this component stay\n * store- and API-free (and therefore hoistable to @arbidocs/blocks).\n */\n onCiteDocument?: (docExtId: string) => void\n /** Cited documents, already resolved by the caller — keyed by external id. */\n citedDocs?: Record<string, DocumentLike>\n /**\n * The app's document picker, injected as a slot. It is store-coupled, so it\n * is passed in rather than imported, and receives the chosen document id.\n */\n renderDocumentPicker?: (\n onSelect: (docExtId: string) => void,\n selectedIds: string[]\n ) => React.ReactNode\n placeholder?: string\n readOnly?: boolean\n className?: string\n /** Start in edit mode with the caret in the field (composer behaviour). */\n autoFocus?: boolean\n /** Applied to the text field itself, so callers can target it directly. */\n 'data-testid'?: string\n /** Persisted textarea height in pixels */\n defaultHeight?: number\n /** Called after user resizes the textarea */\n onHeightChange?: (height: number) => void\n}\n\nexport function CitationEditor({\n value,\n citations,\n onChange,\n activeCitationKey,\n onCiteDocument,\n citedDocs,\n renderDocumentPicker,\n autoFocus = false,\n 'data-testid': dataTestId,\n placeholder = 'Add a note...',\n readOnly = false,\n className,\n defaultHeight,\n onHeightChange,\n}: CitationEditorProps) {\n const [localValue, setLocalValue] = useState(value)\n const [isEditing, setIsEditing] = useState(autoFocus)\n const textareaRef = useRef<HTMLTextAreaElement>(null)\n const debounceRef = useRef<ReturnType<typeof setTimeout> | null>(null)\n\n // Sync from parent only when not editing\n useEffect(() => {\n if (!isEditing) {\n setLocalValue(value)\n }\n }, [value, isEditing])\n\n const sources = useMemo(() => citations ?? [], [citations])\n const hasCitations = sources.length > 0\n\n // A citation is doc-first: each entry is a document with the pages cited\n // from it (none = the whole document).\n const byDoc = useMemo(() => {\n const groups = new Map<string, { pages: number[]; count: number }>()\n for (const doc of sources) {\n const chunks = doc.chunks ?? []\n const pages: number[] = []\n for (const c of chunks) if (c.page != null && !pages.includes(c.page)) pages.push(c.page)\n groups.set(doc.doc_ext_id, { pages, count: chunks.length })\n }\n return groups\n }, [sources])\n\n const docIds = Array.from(byDoc.keys())\n\n const handleRemoveDocument = useCallback(\n (docExtId: string) => {\n const remaining = sources.filter((d) => d.doc_ext_id !== docExtId)\n onChange(localValue, remaining.length ? remaining : null)\n },\n [sources, localValue, onChange]\n )\n\n const handleToggleDocument = useCallback(\n (docExtId: string) => {\n if (!docExtId) return\n // Selecting one already in the list removes it (and its passages) — the\n // tick in the picker has to mean something you can undo from there.\n if (docIds.includes(docExtId)) {\n handleRemoveDocument(docExtId)\n return\n }\n onCiteDocument?.(docExtId)\n },\n [docIds, onCiteDocument, handleRemoveDocument]\n )\n\n // The note is plain text. Nothing to slice: with one citation per note there\n // are no per-statement spans to highlight.\n const renderedContent = useMemo(\n () => (localValue ? <span>{localValue}</span> : null),\n [localValue]\n )\n\n // Debounced text change. Editing the note no longer has to re-anchor\n // anything — the sources are attached to the note as a whole.\n const handleChange = useCallback(\n (newValue: string) => {\n setLocalValue(newValue)\n if (debounceRef.current) clearTimeout(debounceRef.current)\n debounceRef.current = setTimeout(() => onChange(newValue, citations ?? null), 400)\n },\n [citations, onChange]\n )\n\n /**\n * Publish any debounced edit immediately.\n *\n * Without this, typing and then clicking Save within the debounce window\n * silently drops the last keystrokes: the parent still holds the previous\n * value when it reads state to submit.\n */\n const flushPendingChange = useCallback(() => {\n if (!debounceRef.current) return\n clearTimeout(debounceRef.current)\n debounceRef.current = null\n onChange(localValue, citations ?? null)\n }, [localValue, citations, onChange])\n\n return (\n <div className={cn('space-y-1', className)}>\n {/* Text area with highlighted citations preview when not editing */}\n <div className=\"relative\">\n {isEditing ? (\n <Textarea\n ref={textareaRef}\n dictate\n value={localValue}\n onChange={(e) => handleChange(e.target.value)}\n onBlur={() => {\n flushPendingChange()\n setIsEditing(false)\n }}\n onMouseUp={() => {\n if (textareaRef.current && onHeightChange) {\n onHeightChange(textareaRef.current.offsetHeight)\n }\n }}\n placeholder={placeholder}\n readOnly={readOnly}\n rows={2}\n data-testid={dataTestId}\n autoFocus\n style={defaultHeight ? { height: defaultHeight } : undefined}\n className=\"w-full text-sm p-2 pr-14 border border-border rounded-md resize-y bg-background focus:outline-none focus:ring-2 focus:ring-ring\"\n />\n ) : (\n <div\n onClick={() => !readOnly && setIsEditing(true)}\n style={defaultHeight ? { minHeight: defaultHeight } : undefined}\n data-testid={dataTestId}\n className={cn(\n 'w-full text-sm p-2 pr-14 border border-border rounded-md min-h-[4rem] whitespace-pre-wrap bg-background',\n !readOnly && 'cursor-text hover:border-ring',\n !localValue && 'text-muted-foreground'\n )}\n >\n {renderedContent || placeholder}\n </div>\n )}\n </div>\n\n {/* Sources — one row per cited document, each showing how many passages\n were tagged in it. Clicking a document reopens it in the viewer so more\n passages can be tagged; the passages themselves are chosen by reading,\n which is why citing is inseparable from opening. */}\n {(hasCitations || !readOnly) && (\n <div className=\"flex flex-col gap-1\">\n {docIds.map((docId) => {\n const doc = citedDocs?.[docId]\n const group = byDoc.get(docId)\n const pages = (group?.pages ?? []).slice().sort((a, b) => a - b)\n return (\n <div\n key={docId}\n className=\"flex items-center gap-1.5 text-sm\"\n data-testid={`citation-doc-${docId}`}\n >\n {doc ? (\n <button\n type=\"button\"\n onClick={() => !readOnly && onCiteDocument?.(docId)}\n // flex-1 so the title gets the row's spare width — the count\n // and remove control are shrink-0 and sit at the end.\n className=\"flex-1 min-w-0 text-left\"\n title=\"Open to tag more passages\"\n >\n <DocumentEntity doc={doc} fullWidth labelMaxWidth=\"max-w-full\" />\n </button>\n ) : (\n <span className=\"text-muted-foreground\">{docId}</span>\n )}\n <span className=\"text-muted-foreground shrink-0\">{formatPageRefs(pages)}</span>\n {!readOnly && (\n <button\n type=\"button\"\n onClick={() => handleRemoveDocument(docId)}\n aria-label=\"Remove this document\"\n className=\"p-0.5 hover:bg-destructive/20 hover:text-destructive rounded shrink-0\"\n >\n <X size={12} />\n </button>\n )}\n </div>\n )\n })}\n\n {!readOnly && (\n <div className=\"flex items-center gap-1\">\n {/* The picker is rendered inline rather than behind a button: adding\n a source is the primary action here, and hiding it behind\n \"+ Document\" cost a click for no benefit. Once a document is\n cited, this row becomes \"add another\". */}\n <div className=\"flex-1 min-w-0\" data-testid=\"citation-document-picker\">\n {renderDocumentPicker?.(handleToggleDocument, docIds)}\n </div>\n </div>\n )}\n </div>\n )}\n\n {/* Hint when citation is active */}\n {activeCitationKey && (\n <p className=\"text-sm text-blue-text\">\n Click a passage in the document to add it — <strong>shift-click</strong> to take a whole\n range. Add as many as you like, from as many documents as you like.\n </p>\n )}\n </div>\n )\n}\n"]}
1
+ {"version":3,"sources":["../src/citations/PassagePill.tsx","../src/citations/CitationEditor.tsx"],"names":["jsxs","Fragment","jsx","cn","Tooltip","TooltipTrigger","TooltipContent","useBlocksEnvironment","useState","useRef","useEffect","Check","Copy","useMemo","useCallback","Textarea","DocumentEntity","formatPageRefs","X"],"mappings":"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","file":"chunk-HEMU73OP.cjs","sourcesContent":["import {\n useEffect,\n useRef,\n useState,\n type MouseEvent,\n type ReactElement,\n type ReactNode,\n} from 'react'\nimport { Check, Copy } from 'lucide-react'\nimport { Tooltip, TooltipContent, TooltipTrigger, cn } from '@arbidocs/react/ui'\nimport { useBlocksEnvironment } from '../provider/BlocksProvider'\n\n/** Every fixed string of the passage pill. */\nexport interface PassagePillLabels {\n copyLink: string\n /** Announced and notified after the link was copied. */\n copied: string\n /** Notified when the clipboard refused the write. */\n copyFailed: string\n viewPassage: string\n page: string\n pages: string\n passage: string\n passages: string\n /** Visible abbreviation of \"page\" in the pill (\"p.3\"). */\n pageAbbreviation: string\n}\n\nexport const DEFAULT_PASSAGE_PILL_LABELS: PassagePillLabels = {\n copyLink: 'Copy passage link',\n copied: 'Passage link copied',\n copyFailed: 'Could not copy the passage link',\n viewPassage: 'View passage',\n page: 'Page',\n pages: 'Pages',\n passage: 'Passage',\n passages: 'Passages',\n pageAbbreviation: 'p.',\n}\n\n/** Overridable `data-testid`s of the pill (defaults keep the app's existing ids). */\nexport interface PassagePillTestIds {\n root: string\n copy: string\n}\n\nexport interface PassagePillProps {\n /** Glyph of the cited document (host-supplied: file-type icon). */\n icon: ReactNode\n documentTitle: string\n /** `pill`: title + page; `icon`: glyph only; `compact`: page/passage ref + copy link. */\n variant?: 'icon' | 'pill' | 'compact'\n pageNumber?: number\n passageIndex?: number\n /** End of a contiguous passage run: the label collapses to \"4–9\" instead of a pill each. */\n passageIndexEnd?: number\n /** End page of a range: \"p.3–5(4–9)\". */\n pageNumberEnd?: number\n /** Makes the element a link. */\n href?: string\n /** Makes the element a button (ignored for the element role when `href` is set). */\n onClick?: (e: MouseEvent) => void\n showTooltip?: boolean\n labelMaxWidth?: string\n size?: 'sm' | 'base'\n className?: string\n labels?: Partial<PassagePillLabels>\n testIds?: Partial<PassagePillTestIds>\n /** Root test id (default `passage-entity`); the copy button gets `<id>-copy`. */\n testId?: string\n}\n\nconst COPIED_RESET_MS = 2000\n\n/** Plain-language name of a passage reference: \"Title, Page 3, Passage 4\". */\nfunction describePassage(\n documentTitle: string,\n l: PassagePillLabels,\n page: { text?: string; isRange: boolean },\n passage: { text?: string; isRange: boolean }\n): string {\n return [\n documentTitle,\n page.text !== undefined ? `${page.isRange ? l.pages : l.page} ${page.text}` : null,\n passage.text !== undefined\n ? `${passage.isRange ? l.passages : l.passage} ${passage.text}`\n : null,\n ]\n .filter(Boolean)\n .join(', ')\n}\n\ninterface PillSurfaceProps {\n href?: string\n onClick?: (e: MouseEvent) => void\n className: string\n testId: string\n /** What assistive tech reads; the visible content is hidden from it. */\n accessibleName: string\n children: ReactNode\n tooltip?: ReactNode\n tooltipSide?: 'top' | 'bottom'\n}\n\n/**\n * The ONE interactive element of a pill: a link, a button or (when there is no action) plain text.\n * Never nests another interactive element, so it is valid inside any host container.\n */\nfunction PillSurface({\n href,\n onClick,\n className,\n testId,\n accessibleName,\n children,\n tooltip,\n tooltipSide = 'bottom',\n}: PillSurfaceProps) {\n const content = (\n <>\n <span aria-hidden=\"true\" className=\"inline-flex min-w-0 items-center gap-1\">\n {children}\n </span>\n <span className=\"sr-only\">{accessibleName}</span>\n </>\n )\n const interactive = cn(\n 'relative cursor-pointer hover:bg-muted/80 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring',\n \"pointer-coarse:after:absolute pointer-coarse:after:inset-x-0 pointer-coarse:after:-inset-y-3 pointer-coarse:after:content-['']\"\n )\n\n let surface: ReactNode\n if (href) {\n surface = (\n <a\n href={href}\n target=\"_blank\"\n rel=\"noopener noreferrer\"\n className={cn(className, interactive)}\n onClick={onClick}\n data-testid={testId}\n >\n {content}\n </a>\n )\n } else if (onClick) {\n surface = (\n <button\n type=\"button\"\n className={cn(className, interactive)}\n onClick={onClick}\n data-testid={testId}\n >\n {content}\n </button>\n )\n } else {\n surface = (\n <span className={className} data-testid={testId}>\n {content}\n </span>\n )\n }\n\n if (!tooltip) return surface\n return (\n <Tooltip>\n <TooltipTrigger asChild>{surface as ReactElement}</TooltipTrigger>\n <TooltipContent side={tooltipSide}>{tooltip}</TooltipContent>\n </Tooltip>\n )\n}\n\nfunction CopyLinkButton({\n href,\n labels,\n testId,\n}: {\n href: string\n labels: PassagePillLabels\n testId: string\n}) {\n const { notify } = useBlocksEnvironment()\n const [copied, setCopied] = useState(false)\n const timer = useRef<ReturnType<typeof setTimeout> | null>(null)\n\n useEffect(\n () => () => {\n if (timer.current) clearTimeout(timer.current)\n },\n []\n )\n\n const handleCopy = async (e: MouseEvent) => {\n e.stopPropagation()\n try {\n await navigator.clipboard.writeText(href)\n } catch {\n // Say so instead of pretending: the host's notify surfaces the failure.\n notify(labels.copyFailed, 'error')\n return\n }\n setCopied(true)\n notify(labels.copied, 'success')\n if (timer.current) clearTimeout(timer.current)\n timer.current = setTimeout(() => setCopied(false), COPIED_RESET_MS)\n }\n\n return (\n <>\n <button\n type=\"button\"\n onClick={handleCopy}\n className=\"relative inline-flex items-center text-muted-foreground transition-colors hover:text-foreground focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring pointer-fine:min-h-6 pointer-fine:min-w-6 pointer-fine:justify-center pointer-coarse:min-h-11 pointer-coarse:min-w-11 pointer-coarse:justify-center\"\n title={labels.copyLink}\n aria-label={labels.copyLink}\n data-testid={testId}\n >\n {copied ? (\n <Check className=\"size-3\" aria-hidden=\"true\" />\n ) : (\n <Copy className=\"size-3\" aria-hidden=\"true\" />\n )}\n </button>\n <span role=\"status\" className=\"sr-only\">\n {copied ? labels.copied : ''}\n </span>\n </>\n )\n}\n\n/** A citation to a passage of a document, as a pill, a bare icon or a compact page reference. */\nexport function PassagePill({\n icon,\n documentTitle,\n variant = 'pill',\n pageNumber,\n passageIndex,\n passageIndexEnd,\n pageNumberEnd,\n href,\n className,\n onClick,\n showTooltip = true,\n labelMaxWidth,\n size = 'sm',\n labels,\n testIds,\n testId = 'passage-entity',\n}: PassagePillProps) {\n const l = { ...DEFAULT_PASSAGE_PILL_LABELS, ...labels }\n const ids: PassagePillTestIds = {\n root: testIds?.root ?? testId,\n copy: testIds?.copy ?? `${testIds?.root ?? testId}-copy`,\n }\n // Ranges collapse to \"4–9\"; a range of one renders as a plain \"4\".\n const isPassageRange = passageIndexEnd !== undefined && passageIndexEnd > (passageIndex ?? 0)\n const isPageRange = pageNumberEnd !== undefined && pageNumberEnd > (pageNumber ?? 0)\n const passageText = isPassageRange ? `${passageIndex}–${passageIndexEnd}` : `${passageIndex}`\n const pageText = isPageRange ? `${pageNumber}–${pageNumberEnd}` : `${pageNumber}`\n const accessibleName = describePassage(\n documentTitle,\n l,\n { text: pageNumber !== undefined ? pageText : undefined, isRange: isPageRange },\n { text: passageIndex !== undefined ? passageText : undefined, isRange: isPassageRange }\n )\n const hasAction = Boolean(href || onClick)\n\n if (variant === 'icon') {\n return (\n <PillSurface\n href={href}\n onClick={onClick}\n className={cn('inline-flex items-center rounded-sm', className)}\n testId={ids.root}\n accessibleName={accessibleName}\n tooltip={\n showTooltip ? (\n <div className=\"flex flex-col gap-0.5\">\n <span className=\"font-medium\">{documentTitle}</span>\n {(pageNumber !== undefined || passageIndex !== undefined) && (\n <span className=\"text-xs text-muted-foreground\">\n {pageNumber !== undefined && `${isPageRange ? l.pages : l.page} ${pageText}`}\n {pageNumber !== undefined && passageIndex !== undefined && ', '}\n {passageIndex !== undefined &&\n `${isPassageRange ? l.passages : l.passage} ${passageText}`}\n </span>\n )}\n </div>\n ) : undefined\n }\n >\n {icon}\n </PillSurface>\n )\n }\n\n if (variant === 'compact') {\n const label =\n [\n pageNumber !== undefined ? `${l.pageAbbreviation}${pageText}` : null,\n passageIndex !== undefined ? `(${passageText})` : null,\n ]\n .filter(Boolean)\n .join('') || '—'\n return (\n <span\n className={cn(\n 'inline-flex items-center gap-1 rounded-md border border-transparent bg-muted px-1 text-sm font-medium',\n className\n )}\n >\n <PillSurface\n href={href}\n onClick={onClick}\n className=\"inline-flex items-center gap-1 rounded-sm\"\n testId={ids.root}\n accessibleName={accessibleName}\n tooltip={showTooltip ? documentTitle : undefined}\n >\n {icon}\n <span className=\"leading-tight\">{label}</span>\n </PillSurface>\n {href && <CopyLinkButton href={href} labels={l} testId={ids.copy} />}\n </span>\n )\n }\n\n return (\n <PillSurface\n href={href}\n onClick={onClick}\n className={cn(\n 'group/pill inline-flex items-center rounded-md border border-border bg-muted transition-all',\n size === 'base' ? 'gap-1.5 px-1.5 py-0.5 text-base' : 'gap-1 px-1 text-sm',\n className\n )}\n testId={ids.root}\n accessibleName={accessibleName}\n tooltip={showTooltip && hasAction ? l.viewPassage : undefined}\n >\n {icon}\n <span\n className={cn(\n 'min-w-0 truncate font-medium leading-tight',\n labelMaxWidth ?? 'max-w-[320px]'\n )}\n >\n {documentTitle}\n </span>\n {pageNumber ? (\n <span className=\"flex-shrink-0 text-xs leading-none text-muted-foreground\">\n {l.pageAbbreviation}\n {pageText}\n </span>\n ) : null}\n </PillSurface>\n )\n}\n","/**\n * CitationEditor Component\n *\n * Note input plus the source passages backing it.\n * - Pick related documents; each opens so its passages can be chosen by reading\n * - Click a passage to add it, shift-click for a range; repeat across documents\n *\n * A note answers ONE question, so it has ONE set of sources. It used to carry a\n * map of citations, each with its own statement and character offsets, rendered\n * as inline highlighted spans with [n] badges — but the statements were copies\n * of the note text and the offsets spanned all of it, so the highlight was the\n * whole field. That machinery is gone; the note renders as plain text.\n *\n * ``activeCitationKey``/``onActiveCitationChange`` are kept because the viewer\n * and store thread them through to decide which field is receiving passages.\n * With a single citation the key is just a sentinel — see ONLY_CITATION_KEY.\n */\n\nimport { useCallback, useState, useRef, useEffect, useMemo } from 'react'\nimport { X } from 'lucide-react'\nimport { cn, DocumentEntity, Textarea, type DocumentLike } from '@arbidocs/react/ui'\nimport { formatPageRefs } from '../lib/format'\n\nimport type { components } from '@arbidocs/client'\n\ntype CitationSources = components['schemas']['CitationSources']\n\ntype Citations = CitationSources | null\n\nexport interface CitationEditorProps {\n value: string\n citations: Citations | null\n onChange: (note: string, citations: Citations | null) => void\n /** Currently active citation key (controlled from parent) */\n activeCitationKey?: string | null\n /**\n * Open a document in the viewer, armed to collect passages for this field —\n * and tag its first passage, so a chosen document is immediately a usable\n * citation. Passages are picked by reading, so citing means opening.\n *\n * The caller owns this because resolving \"first passage\" needs the parsed\n * document, and keeping that fetch out here is what lets this component stay\n * store- and API-free (and therefore hoistable to @arbidocs/blocks).\n */\n onCiteDocument?: (docExtId: string) => void\n /** Cited documents, already resolved by the caller — keyed by external id. */\n citedDocs?: Record<string, DocumentLike>\n /**\n * The app's document picker, injected as a slot. It is store-coupled, so it\n * is passed in rather than imported, and receives the chosen document id.\n */\n renderDocumentPicker?: (\n onSelect: (docExtId: string) => void,\n selectedIds: string[]\n ) => React.ReactNode\n placeholder?: string\n readOnly?: boolean\n className?: string\n /** Start in edit mode with the caret in the field (composer behaviour). */\n autoFocus?: boolean\n /** Applied to the text field itself, so callers can target it directly. */\n 'data-testid'?: string\n /** Persisted textarea height in pixels */\n defaultHeight?: number\n /** Called after user resizes the textarea */\n onHeightChange?: (height: number) => void\n}\n\nexport function CitationEditor({\n value,\n citations,\n onChange,\n activeCitationKey,\n onCiteDocument,\n citedDocs,\n renderDocumentPicker,\n autoFocus = false,\n 'data-testid': dataTestId,\n placeholder = 'Add a note...',\n readOnly = false,\n className,\n defaultHeight,\n onHeightChange,\n}: CitationEditorProps) {\n const [localValue, setLocalValue] = useState(value)\n const [isEditing, setIsEditing] = useState(autoFocus)\n const textareaRef = useRef<HTMLTextAreaElement>(null)\n const debounceRef = useRef<ReturnType<typeof setTimeout> | null>(null)\n\n // Sync from parent only when not editing\n useEffect(() => {\n if (!isEditing) {\n setLocalValue(value)\n }\n }, [value, isEditing])\n\n const sources = useMemo(() => citations ?? [], [citations])\n const hasCitations = sources.length > 0\n\n // A citation is doc-first: each entry is a document with the pages cited\n // from it (none = the whole document).\n const byDoc = useMemo(() => {\n const groups = new Map<string, { pages: number[]; count: number }>()\n for (const doc of sources) {\n const chunks = doc.chunks ?? []\n const pages: number[] = []\n for (const c of chunks) if (c.page != null && !pages.includes(c.page)) pages.push(c.page)\n groups.set(doc.doc_ext_id, { pages, count: chunks.length })\n }\n return groups\n }, [sources])\n\n const docIds = Array.from(byDoc.keys())\n\n const handleRemoveDocument = useCallback(\n (docExtId: string) => {\n const remaining = sources.filter((d) => d.doc_ext_id !== docExtId)\n onChange(localValue, remaining.length ? remaining : null)\n },\n [sources, localValue, onChange]\n )\n\n const handleToggleDocument = useCallback(\n (docExtId: string) => {\n if (!docExtId) return\n // Selecting one already in the list removes it (and its passages) — the\n // tick in the picker has to mean something you can undo from there.\n if (docIds.includes(docExtId)) {\n handleRemoveDocument(docExtId)\n return\n }\n onCiteDocument?.(docExtId)\n },\n [docIds, onCiteDocument, handleRemoveDocument]\n )\n\n // The note is plain text. Nothing to slice: with one citation per note there\n // are no per-statement spans to highlight.\n const renderedContent = useMemo(\n () => (localValue ? <span>{localValue}</span> : null),\n [localValue]\n )\n\n // Debounced text change. Editing the note no longer has to re-anchor\n // anything — the sources are attached to the note as a whole.\n const handleChange = useCallback(\n (newValue: string) => {\n setLocalValue(newValue)\n if (debounceRef.current) clearTimeout(debounceRef.current)\n debounceRef.current = setTimeout(() => onChange(newValue, citations ?? null), 400)\n },\n [citations, onChange]\n )\n\n /**\n * Publish any debounced edit immediately.\n *\n * Without this, typing and then clicking Save within the debounce window\n * silently drops the last keystrokes: the parent still holds the previous\n * value when it reads state to submit.\n */\n const flushPendingChange = useCallback(() => {\n if (!debounceRef.current) return\n clearTimeout(debounceRef.current)\n debounceRef.current = null\n onChange(localValue, citations ?? null)\n }, [localValue, citations, onChange])\n\n return (\n <div className={cn('space-y-1', className)}>\n {/* Text area with highlighted citations preview when not editing */}\n <div className=\"relative\">\n {isEditing ? (\n <Textarea\n ref={textareaRef}\n dictate\n value={localValue}\n onChange={(e) => handleChange(e.target.value)}\n onBlur={() => {\n flushPendingChange()\n setIsEditing(false)\n }}\n onMouseUp={() => {\n if (textareaRef.current && onHeightChange) {\n onHeightChange(textareaRef.current.offsetHeight)\n }\n }}\n placeholder={placeholder}\n readOnly={readOnly}\n rows={2}\n data-testid={dataTestId}\n autoFocus\n style={defaultHeight ? { height: defaultHeight } : undefined}\n className=\"w-full text-sm p-2 pr-14 border border-border rounded-md resize-y bg-background focus:outline-none focus:ring-2 focus:ring-ring\"\n />\n ) : (\n <div\n onClick={() => !readOnly && setIsEditing(true)}\n style={defaultHeight ? { minHeight: defaultHeight } : undefined}\n data-testid={dataTestId}\n className={cn(\n 'w-full text-sm p-2 pr-14 border border-border rounded-md min-h-[4rem] whitespace-pre-wrap bg-background',\n !readOnly && 'cursor-text hover:border-ring',\n !localValue && 'text-muted-foreground'\n )}\n >\n {renderedContent || placeholder}\n </div>\n )}\n </div>\n\n {/* Sources — one row per cited document, each showing how many passages\n were tagged in it. Clicking a document reopens it in the viewer so more\n passages can be tagged; the passages themselves are chosen by reading,\n which is why citing is inseparable from opening. */}\n {(hasCitations || !readOnly) && (\n <div className=\"flex flex-col gap-1\">\n {docIds.map((docId) => {\n const doc = citedDocs?.[docId]\n const group = byDoc.get(docId)\n const pages = (group?.pages ?? []).slice().sort((a, b) => a - b)\n return (\n <div\n key={docId}\n className=\"flex items-center gap-1.5 text-sm\"\n data-testid={`citation-doc-${docId}`}\n >\n {doc ? (\n <button\n type=\"button\"\n onClick={() => !readOnly && onCiteDocument?.(docId)}\n // flex-1 so the title gets the row's spare width — the count\n // and remove control are shrink-0 and sit at the end.\n className=\"flex-1 min-w-0 text-left\"\n title=\"Open to tag more passages\"\n >\n <DocumentEntity doc={doc} fullWidth labelMaxWidth=\"max-w-full\" />\n </button>\n ) : (\n <span className=\"text-muted-foreground\">{docId}</span>\n )}\n <span className=\"text-muted-foreground shrink-0\">{formatPageRefs(pages)}</span>\n {!readOnly && (\n <button\n type=\"button\"\n onClick={() => handleRemoveDocument(docId)}\n aria-label=\"Remove this document\"\n className=\"p-0.5 hover:bg-destructive/20 hover:text-destructive rounded shrink-0\"\n >\n <X size={12} />\n </button>\n )}\n </div>\n )\n })}\n\n {!readOnly && (\n <div className=\"flex items-center gap-1\">\n {/* The picker is rendered inline rather than behind a button: adding\n a source is the primary action here, and hiding it behind\n \"+ Document\" cost a click for no benefit. Once a document is\n cited, this row becomes \"add another\". */}\n <div className=\"flex-1 min-w-0\" data-testid=\"citation-document-picker\">\n {renderDocumentPicker?.(handleToggleDocument, docIds)}\n </div>\n </div>\n )}\n </div>\n )}\n\n {/* Hint when citation is active */}\n {activeCitationKey && (\n <p className=\"text-sm text-blue-text\">\n Click a passage in the document to add it — <strong>shift-click</strong> to take a whole\n range. Add as many as you like, from as many documents as you like.\n </p>\n )}\n </div>\n )\n}\n"]}
@@ -1,7 +1,7 @@
1
1
  "use client";
2
2
  'use strict';
3
3
 
4
- var chunkKPZZ5FHE_cjs = require('./chunk-KPZZ5FHE.cjs');
4
+ var chunkC4WSHRR6_cjs = require('./chunk-C4WSHRR6.cjs');
5
5
  var react = require('react');
6
6
  var lucideReact = require('lucide-react');
7
7
  var ui = require('@arbidocs/react/ui');
@@ -29,7 +29,7 @@ var SearchHit = react.memo(function SearchHit2({
29
29
  className
30
30
  }) {
31
31
  const l = { ...DEFAULT_SEARCH_HIT_LABELS, ...labels };
32
- const { linkComponent: Link } = chunkKPZZ5FHE_cjs.useBlocksEnvironment();
32
+ const { linkComponent: Link } = chunkC4WSHRR6_cjs.useBlocksEnvironment();
33
33
  const [expanded, setExpanded] = react.useState(false);
34
34
  const [overflowing, setOverflowing] = react.useState(false);
35
35
  const bodyRef = react.useRef(null);
@@ -92,5 +92,5 @@ var SearchHit = react.memo(function SearchHit2({
92
92
 
93
93
  exports.DEFAULT_SEARCH_HIT_LABELS = DEFAULT_SEARCH_HIT_LABELS;
94
94
  exports.SearchHit = SearchHit;
95
- //# sourceMappingURL=chunk-UTTTJSQU.cjs.map
96
- //# sourceMappingURL=chunk-UTTTJSQU.cjs.map
95
+ //# sourceMappingURL=chunk-HFGXA5CL.cjs.map
96
+ //# sourceMappingURL=chunk-HFGXA5CL.cjs.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/retrieval/SearchHit.tsx"],"names":["memo","SearchHit","useBlocksEnvironment","useState","useRef","useLayoutEffect","jsx","PassageCard","cn","Eye"],"mappings":"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","file":"chunk-UTTTJSQU.cjs","sourcesContent":["import { memo, useLayoutEffect, useRef, useState, type MouseEvent, type ReactNode } from 'react'\nimport { Eye } from 'lucide-react'\n\nimport { cn, PassageCard } from '@arbidocs/react/ui'\nimport { useBlocksEnvironment } from '../provider/BlocksProvider'\nimport type { BlockLinkRenderProps } from '../components/blockLink'\n\nexport interface SearchHitLabels {\n showMore: string\n showLess: string\n}\n\nexport const DEFAULT_SEARCH_HIT_LABELS: SearchHitLabels = {\n showMore: 'Show more',\n showLess: 'Show less',\n}\n\nfunction isModifiedClick(e: MouseEvent): boolean {\n return e.button !== 0 || e.metaKey || e.ctrlKey || e.shiftKey || e.altKey\n}\n\nexport interface SearchHitProps {\n /** Left side of the header row: a source pill or a small page label. */\n header: ReactNode\n /** Raw snippet text (passed through `renderSnippet`). */\n content: string\n /** Query terms to highlight; handed to `renderSnippet`. */\n terms: string[]\n /** Renders the snippet (markdown + highlight). The app owns the markdown pipeline. */\n renderSnippet: (content: string, terms: string[]) => ReactNode\n onClick: (e: MouseEvent) => void\n /** This passage is the one open in the viewer (yellow wash). */\n active?: boolean\n /** Marks the hit as the one currently open elsewhere (accent border + ring). */\n selected?: boolean\n /** Replaces the default open-eye on the right of the header. */\n headerRight?: ReactNode\n /**\n * Destination of the hit. Rendered as a real link (provider link component) so ctrl/cmd-click\n * opens it in a new tab; a plain click calls `onClick` and does not navigate.\n */\n href?: string\n labels?: Partial<SearchHitLabels>\n testId?: string\n className?: string\n}\n\n/**\n * Snippet-first search result: header over a 3-line clamped excerpt with a Show more toggle.\n * The card is a single click target; nothing interactive may sit inside its header.\n */\nexport const SearchHit = memo(function SearchHit({\n header,\n content,\n terms,\n renderSnippet,\n onClick,\n active = false,\n selected = false,\n headerRight,\n href,\n labels,\n testId,\n className,\n}: SearchHitProps) {\n const l = { ...DEFAULT_SEARCH_HIT_LABELS, ...labels }\n const { linkComponent: Link } = useBlocksEnvironment()\n const [expanded, setExpanded] = useState(false)\n const [overflowing, setOverflowing] = useState(false)\n const bodyRef = useRef<HTMLDivElement>(null)\n\n // Only offer \"Show more\" when the clamped snippet actually hides content.\n useLayoutEffect(() => {\n const el = bodyRef.current\n if (!el || expanded) return\n setOverflowing(el.scrollHeight > el.clientHeight + 1)\n }, [content, terms, expanded])\n\n const handleCardClick = (e: MouseEvent) => {\n if (href && isModifiedClick(e)) return\n if (href) e.preventDefault()\n onClick(e)\n }\n\n const card = (\n <PassageCard\n header={header}\n className={cn(\n // Plain `:hover` (not Tailwind `hover:`) so touchscreen laptops also get the border.\n '[&:hover]:border-primary',\n active && 'bg-yellow-100 dark:bg-yellow-800/40',\n className\n )}\n active={selected}\n headerRight={headerRight ?? <Eye className=\"size-4 text-muted-foreground\" aria-hidden />}\n onClick={handleCardClick}\n data-testid={testId}\n footer={\n (overflowing || expanded) && (\n <div className=\"flex justify-end\">\n <button\n type=\"button\"\n className=\"mt-1 text-xs font-medium text-primary hover:underline pointer-coarse:min-h-11\"\n onClick={(e) => {\n e.stopPropagation()\n e.preventDefault()\n setExpanded((v) => !v)\n }}\n >\n {expanded ? l.showLess : l.showMore}\n </button>\n </div>\n )\n }\n >\n <div\n ref={bodyRef}\n data-slot=\"search-hit\"\n className={cn('text-sm text-foreground/90', !expanded && 'line-clamp-3')}\n >\n {renderSnippet(content, terms)}\n </div>\n </PassageCard>\n )\n if (!href) return card\n const linkProps = {\n href,\n className: 'block',\n 'data-slot': 'search-hit-link',\n } as unknown as BlockLinkRenderProps\n return Link ? <Link {...linkProps}>{card}</Link> : <a {...linkProps}>{card}</a>\n})\n"]}
1
+ {"version":3,"sources":["../src/retrieval/SearchHit.tsx"],"names":["memo","SearchHit","useBlocksEnvironment","useState","useRef","useLayoutEffect","jsx","PassageCard","cn","Eye"],"mappings":"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","file":"chunk-HFGXA5CL.cjs","sourcesContent":["import { memo, useLayoutEffect, useRef, useState, type MouseEvent, type ReactNode } from 'react'\nimport { Eye } from 'lucide-react'\n\nimport { cn, PassageCard } from '@arbidocs/react/ui'\nimport { useBlocksEnvironment } from '../provider/BlocksProvider'\nimport type { BlockLinkRenderProps } from '../components/blockLink'\n\nexport interface SearchHitLabels {\n showMore: string\n showLess: string\n}\n\nexport const DEFAULT_SEARCH_HIT_LABELS: SearchHitLabels = {\n showMore: 'Show more',\n showLess: 'Show less',\n}\n\nfunction isModifiedClick(e: MouseEvent): boolean {\n return e.button !== 0 || e.metaKey || e.ctrlKey || e.shiftKey || e.altKey\n}\n\nexport interface SearchHitProps {\n /** Left side of the header row: a source pill or a small page label. */\n header: ReactNode\n /** Raw snippet text (passed through `renderSnippet`). */\n content: string\n /** Query terms to highlight; handed to `renderSnippet`. */\n terms: string[]\n /** Renders the snippet (markdown + highlight). The app owns the markdown pipeline. */\n renderSnippet: (content: string, terms: string[]) => ReactNode\n onClick: (e: MouseEvent) => void\n /** This passage is the one open in the viewer (yellow wash). */\n active?: boolean\n /** Marks the hit as the one currently open elsewhere (accent border + ring). */\n selected?: boolean\n /** Replaces the default open-eye on the right of the header. */\n headerRight?: ReactNode\n /**\n * Destination of the hit. Rendered as a real link (provider link component) so ctrl/cmd-click\n * opens it in a new tab; a plain click calls `onClick` and does not navigate.\n */\n href?: string\n labels?: Partial<SearchHitLabels>\n testId?: string\n className?: string\n}\n\n/**\n * Snippet-first search result: header over a 3-line clamped excerpt with a Show more toggle.\n * The card is a single click target; nothing interactive may sit inside its header.\n */\nexport const SearchHit = memo(function SearchHit({\n header,\n content,\n terms,\n renderSnippet,\n onClick,\n active = false,\n selected = false,\n headerRight,\n href,\n labels,\n testId,\n className,\n}: SearchHitProps) {\n const l = { ...DEFAULT_SEARCH_HIT_LABELS, ...labels }\n const { linkComponent: Link } = useBlocksEnvironment()\n const [expanded, setExpanded] = useState(false)\n const [overflowing, setOverflowing] = useState(false)\n const bodyRef = useRef<HTMLDivElement>(null)\n\n // Only offer \"Show more\" when the clamped snippet actually hides content.\n useLayoutEffect(() => {\n const el = bodyRef.current\n if (!el || expanded) return\n setOverflowing(el.scrollHeight > el.clientHeight + 1)\n }, [content, terms, expanded])\n\n const handleCardClick = (e: MouseEvent) => {\n if (href && isModifiedClick(e)) return\n if (href) e.preventDefault()\n onClick(e)\n }\n\n const card = (\n <PassageCard\n header={header}\n className={cn(\n // Plain `:hover` (not Tailwind `hover:`) so touchscreen laptops also get the border.\n '[&:hover]:border-primary',\n active && 'bg-yellow-100 dark:bg-yellow-800/40',\n className\n )}\n active={selected}\n headerRight={headerRight ?? <Eye className=\"size-4 text-muted-foreground\" aria-hidden />}\n onClick={handleCardClick}\n data-testid={testId}\n footer={\n (overflowing || expanded) && (\n <div className=\"flex justify-end\">\n <button\n type=\"button\"\n className=\"mt-1 text-xs font-medium text-primary hover:underline pointer-coarse:min-h-11\"\n onClick={(e) => {\n e.stopPropagation()\n e.preventDefault()\n setExpanded((v) => !v)\n }}\n >\n {expanded ? l.showLess : l.showMore}\n </button>\n </div>\n )\n }\n >\n <div\n ref={bodyRef}\n data-slot=\"search-hit\"\n className={cn('text-sm text-foreground/90', !expanded && 'line-clamp-3')}\n >\n {renderSnippet(content, terms)}\n </div>\n </PassageCard>\n )\n if (!href) return card\n const linkProps = {\n href,\n className: 'block',\n 'data-slot': 'search-hit-link',\n } as unknown as BlockLinkRenderProps\n return Link ? <Link {...linkProps}>{card}</Link> : <a {...linkProps}>{card}</a>\n})\n"]}
@@ -1,6 +1,6 @@
1
1
  "use client";
2
2
  import { useControllableState } from './chunk-RLWIUUQ5.js';
3
- import { ActionLink } from './chunk-YKQ2DPIP.js';
3
+ import { ActionLink } from './chunk-444XKG46.js';
4
4
  import { useDrawerBehavior, BlocksTooltipProvider, useShellBottomInset } from './chunk-7XF5SFJ2.js';
5
5
  import { useIsPhone, useIsNarrow, useIsTouchScreen } from './chunk-SLSBJRWW.js';
6
6
  import { testIdOr, prefixedTestId } from './chunk-7F6CBP3Z.js';
@@ -1815,5 +1815,5 @@ function SplitLayout({
1815
1815
  }
1816
1816
 
1817
1817
  export { ActionCluster, AskField, AskRow, AskTrigger, DEFAULT_ASK_FIELD_LABELS, DEFAULT_INSTALL_PROMPT_LABELS, DEFAULT_MOBILE_BARS_LABELS, DEFAULT_OFFLINE_PILL_LABELS, DEFAULT_REMOTE_CONTROL_PILL_LABELS, DEFAULT_SIDEBAR_LABELS, DEFAULT_TIP_CARD_LABELS, INSTALL_PROMPT_DISMISSED_KEY, InfoBar, InstallPrompt, MobileAppBar, MobileTabBar, OfflinePill, RemoteControlPill, STATUS_ROW_BASE_CLASS, STATUS_ROW_TONES, ShellSidebar, Sidebar, SidebarBadgeRow, SidebarRowAction, SidebarRowHoverContext, SplitLayout, StatusBadge, StatusRow, TipCard, getInstallInstructions, initInstallPrompt, isIosDevice, promptAppInstall, resolveSidebarLayout, useCloseOnEscape, useInstallPrompt, useSidebarContext, useSidebarController, useSidebarSettle };
1818
- //# sourceMappingURL=chunk-H4D7WKDY.js.map
1819
- //# sourceMappingURL=chunk-H4D7WKDY.js.map
1818
+ //# sourceMappingURL=chunk-I7WG3JRD.js.map
1819
+ //# sourceMappingURL=chunk-I7WG3JRD.js.map