@arbidocs/blocks 0.4.129 → 0.4.130

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 (173) hide show
  1. package/README.md +4 -3
  2. package/dist/agents/index.cjs +216 -216
  3. package/dist/agents/index.js +5 -5
  4. package/dist/calendar/CalendarPrint.d.ts +25 -0
  5. package/dist/calendar/booking-slots.d.ts +21 -0
  6. package/dist/calendar/index.cjs +381 -97
  7. package/dist/calendar/index.cjs.map +1 -1
  8. package/dist/calendar/index.d.ts +4 -0
  9. package/dist/calendar/index.js +277 -3
  10. package/dist/calendar/index.js.map +1 -1
  11. package/dist/calendar/print-layout.d.ts +16 -0
  12. package/dist/calendar/printCalendar.d.ts +6 -0
  13. package/dist/calls/composite-canvas.d.ts +52 -0
  14. package/dist/calls/index.cjs +376 -3
  15. package/dist/calls/index.cjs.map +1 -1
  16. package/dist/calls/index.d.ts +3 -0
  17. package/dist/calls/index.js +360 -5
  18. package/dist/calls/index.js.map +1 -1
  19. package/dist/calls/ringtone.d.ts +16 -0
  20. package/dist/calls/voice-levels.d.ts +32 -0
  21. package/dist/chat/ThreadVisualizer.d.ts +28 -0
  22. package/dist/chat/index.cjs +93 -77
  23. package/dist/chat/index.d.ts +2 -0
  24. package/dist/chat/index.js +2 -2
  25. package/dist/chat/open-document.d.ts +5 -1
  26. package/dist/chat/thread-diagram.d.ts +26 -0
  27. package/dist/{chunk-DQCYCEDR.js → chunk-2Q7FDZAY.js} +3 -3
  28. package/dist/{chunk-DQCYCEDR.js.map → chunk-2Q7FDZAY.js.map} +1 -1
  29. package/dist/{chunk-S7PSMMRG.js → chunk-444XKG46.js} +3 -3
  30. package/dist/{chunk-S7PSMMRG.js.map → chunk-444XKG46.js.map} +1 -1
  31. package/dist/{chunk-7423V6RM.cjs → chunk-4QIIDXLF.cjs} +8 -8
  32. package/dist/{chunk-7423V6RM.cjs.map → chunk-4QIIDXLF.cjs.map} +1 -1
  33. package/dist/{chunk-OYMWV45N.js → chunk-4RLCRFZS.js} +63 -13
  34. package/dist/chunk-4RLCRFZS.js.map +1 -0
  35. package/dist/{chunk-DZYAAL4H.cjs → chunk-4S5IDT5F.cjs} +231 -2
  36. package/dist/chunk-4S5IDT5F.cjs.map +1 -0
  37. package/dist/{chunk-CJBN5HIS.js → chunk-4UMXQPNA.js} +20 -8
  38. package/dist/chunk-4UMXQPNA.js.map +1 -0
  39. package/dist/{chunk-IBZJYCYM.js → chunk-66TA5IBN.js} +17 -25
  40. package/dist/chunk-66TA5IBN.js.map +1 -0
  41. package/dist/{chunk-OR4CO743.cjs → chunk-AAFX64WD.cjs} +3 -3
  42. package/dist/{chunk-OR4CO743.cjs.map → chunk-AAFX64WD.cjs.map} +1 -1
  43. package/dist/{chunk-MUMH3Z6K.cjs → chunk-ARDHLU73.cjs} +61 -11
  44. package/dist/chunk-ARDHLU73.cjs.map +1 -0
  45. package/dist/{chunk-TGWTLNXW.cjs → chunk-BIXHB4LV.cjs} +3 -2
  46. package/dist/{chunk-TGWTLNXW.cjs.map → chunk-BIXHB4LV.cjs.map} +1 -1
  47. package/dist/chunk-C4WSHRR6.cjs +166 -0
  48. package/dist/chunk-C4WSHRR6.cjs.map +1 -0
  49. package/dist/{chunk-ZAVEMQ37.cjs → chunk-DWZXSPMB.cjs} +3 -3
  50. package/dist/{chunk-ZAVEMQ37.cjs.map → chunk-DWZXSPMB.cjs.map} +1 -1
  51. package/dist/{chunk-5HFPRI3W.js → chunk-FUTMU4FR.js} +3 -3
  52. package/dist/{chunk-5HFPRI3W.js.map → chunk-FUTMU4FR.js.map} +1 -1
  53. package/dist/{chunk-5Y7JRY7Y.js → chunk-GDBDHOI4.js} +3 -3
  54. package/dist/{chunk-5Y7JRY7Y.js.map → chunk-GDBDHOI4.js.map} +1 -1
  55. package/dist/{chunk-TGJNPKST.js → chunk-GTCC2VAR.js} +3 -3
  56. package/dist/{chunk-TGJNPKST.js.map → chunk-GTCC2VAR.js.map} +1 -1
  57. package/dist/{chunk-3BJLNKOB.cjs → chunk-GZPTWHP5.cjs} +22 -10
  58. package/dist/chunk-GZPTWHP5.cjs.map +1 -0
  59. package/dist/{chunk-OUW6G4O2.cjs → chunk-HFGXA5CL.cjs} +4 -4
  60. package/dist/{chunk-OUW6G4O2.cjs.map → chunk-HFGXA5CL.cjs.map} +1 -1
  61. package/dist/{chunk-SWQX6CTT.cjs → chunk-JKB7WT7L.cjs} +2 -2
  62. package/dist/chunk-JKB7WT7L.cjs.map +1 -0
  63. package/dist/{chunk-S6BOINC4.cjs → chunk-OGBXV326.cjs} +7 -7
  64. package/dist/{chunk-S6BOINC4.cjs.map → chunk-OGBXV326.cjs.map} +1 -1
  65. package/dist/{chunk-DJM7DLCT.cjs → chunk-OPTBQSCV.cjs} +3 -3
  66. package/dist/{chunk-DJM7DLCT.cjs.map → chunk-OPTBQSCV.cjs.map} +1 -1
  67. package/dist/{chunk-GFYGYME3.js → chunk-OQ7RUNOC.js} +3 -3
  68. package/dist/{chunk-GFYGYME3.js.map → chunk-OQ7RUNOC.js.map} +1 -1
  69. package/dist/{chunk-NYHGG2IA.cjs → chunk-QDEODGXE.cjs} +5 -5
  70. package/dist/{chunk-NYHGG2IA.cjs.map → chunk-QDEODGXE.cjs.map} +1 -1
  71. package/dist/{chunk-6BTCDKCK.js → chunk-QYTYW74G.js} +4 -4
  72. package/dist/{chunk-6BTCDKCK.js.map → chunk-QYTYW74G.js.map} +1 -1
  73. package/dist/{chunk-A7NCSZAP.cjs → chunk-QZTNTP75.cjs} +17 -25
  74. package/dist/chunk-QZTNTP75.cjs.map +1 -0
  75. package/dist/{chunk-OB5F4577.cjs → chunk-R26BK7YL.cjs} +4 -4
  76. package/dist/{chunk-OB5F4577.cjs.map → chunk-R26BK7YL.cjs.map} +1 -1
  77. package/dist/{chunk-A2YAC22G.js → chunk-RI6DZA5X.js} +3 -3
  78. package/dist/{chunk-A2YAC22G.js.map → chunk-RI6DZA5X.js.map} +1 -1
  79. package/dist/{chunk-H2KQ6OSU.js → chunk-SZX44LCT.js} +230 -5
  80. package/dist/chunk-SZX44LCT.js.map +1 -0
  81. package/dist/{chunk-7QDX2CO4.cjs → chunk-TP6PLDNM.cjs} +4 -4
  82. package/dist/{chunk-7QDX2CO4.cjs.map → chunk-TP6PLDNM.cjs.map} +1 -1
  83. package/dist/{chunk-JLTXVW25.cjs → chunk-TT6XV6WM.cjs} +17 -17
  84. package/dist/{chunk-JLTXVW25.cjs.map → chunk-TT6XV6WM.cjs.map} +1 -1
  85. package/dist/{chunk-HSFLEVZY.js → chunk-UMIY4SQS.js} +6 -6
  86. package/dist/{chunk-HSFLEVZY.js.map → chunk-UMIY4SQS.js.map} +1 -1
  87. package/dist/{chunk-ECERC6TI.js → chunk-VHJHY7TT.js} +3 -3
  88. package/dist/{chunk-ECERC6TI.js.map → chunk-VHJHY7TT.js.map} +1 -1
  89. package/dist/{chunk-D3N67Q4D.js → chunk-W3VYZXNS.js} +3 -3
  90. package/dist/{chunk-D3N67Q4D.js.map → chunk-W3VYZXNS.js.map} +1 -1
  91. package/dist/{chunk-JK45LSIH.cjs → chunk-WXYQ66KC.cjs} +5 -5
  92. package/dist/{chunk-JK45LSIH.cjs.map → chunk-WXYQ66KC.cjs.map} +1 -1
  93. package/dist/{chunk-ZCF2JJFA.js → chunk-Y3KA6X7B.js} +3 -3
  94. package/dist/{chunk-ZCF2JJFA.js.map → chunk-Y3KA6X7B.js.map} +1 -1
  95. package/dist/{chunk-GYCQ3FNL.js → chunk-YBLIKTJK.js} +2 -2
  96. package/dist/chunk-YBLIKTJK.js.map +1 -0
  97. package/dist/chunk-YNIBUKV5.js +163 -0
  98. package/dist/chunk-YNIBUKV5.js.map +1 -0
  99. package/dist/citations/index.cjs +12 -11
  100. package/dist/citations/index.js +3 -2
  101. package/dist/collaboration/index.cjs +42 -42
  102. package/dist/collaboration/index.js +2 -2
  103. package/dist/connect/docx.cjs +7 -5
  104. package/dist/connect/docx.cjs.map +1 -1
  105. package/dist/connect/docx.js +6 -4
  106. package/dist/connect/docx.js.map +1 -1
  107. package/dist/connect/index.cjs +237 -194
  108. package/dist/connect/index.cjs.map +1 -1
  109. package/dist/connect/index.d.ts +1 -1
  110. package/dist/connect/index.js +190 -147
  111. package/dist/connect/index.js.map +1 -1
  112. package/dist/connection/ConnectedSettings.d.ts +46 -20
  113. package/dist/connection/ConnectionProvider.d.ts +5 -0
  114. package/dist/connection/mail/ConnectedMailComposer.d.ts +2 -3
  115. package/dist/connection/mail/ConnectedMailbox.d.ts +2 -3
  116. package/dist/connection/mail/MailComposerForm.d.ts +2 -3
  117. package/dist/connection/mail/index.d.ts +2 -2
  118. package/dist/connection/mail/mailbox.d.ts +1 -4
  119. package/dist/connection/mail/types.d.ts +0 -8
  120. package/dist/facts/fact-citations.d.ts +56 -0
  121. package/dist/facts/fact-table-column-resize.d.ts +18 -0
  122. package/dist/facts/index.cjs +197 -10
  123. package/dist/facts/index.cjs.map +1 -1
  124. package/dist/facts/index.d.ts +2 -0
  125. package/dist/facts/index.js +182 -6
  126. package/dist/facts/index.js.map +1 -1
  127. package/dist/files/index.cjs +4 -4
  128. package/dist/files/index.js +3 -3
  129. package/dist/home/index.cjs +20 -19
  130. package/dist/home/index.cjs.map +1 -1
  131. package/dist/home/index.js +5 -4
  132. package/dist/home/index.js.map +1 -1
  133. package/dist/index.cjs +485 -469
  134. package/dist/index.d.ts +2 -1
  135. package/dist/index.js +13 -13
  136. package/dist/provider/BlocksProvider.d.ts +39 -4
  137. package/dist/provider/dialogs.d.ts +31 -0
  138. package/dist/retrieval/index.cjs +5 -4
  139. package/dist/retrieval/index.js +3 -2
  140. package/dist/settings/MoreInfo.d.ts +25 -0
  141. package/dist/settings/PlanCard.d.ts +1 -1
  142. package/dist/settings/index.cjs +106 -252
  143. package/dist/settings/index.cjs.map +1 -1
  144. package/dist/settings/index.d.ts +1 -1
  145. package/dist/settings/index.js +71 -216
  146. package/dist/settings/index.js.map +1 -1
  147. package/dist/shell/index.cjs +48 -47
  148. package/dist/shell/index.js +4 -3
  149. package/dist/studio/index.cjs +15 -14
  150. package/dist/studio/index.cjs.map +1 -1
  151. package/dist/studio/index.js +7 -6
  152. package/dist/studio/index.js.map +1 -1
  153. package/dist/workflow-canvas/index.cjs +14 -14
  154. package/dist/workflow-canvas/index.js +6 -6
  155. package/dist/workspaces/index.cjs +3 -3
  156. package/dist/workspaces/index.js +2 -2
  157. package/node_modules/@arbidocs/coedit/package.json +1 -1
  158. package/package.json +9 -4
  159. package/dist/chunk-3BJLNKOB.cjs.map +0 -1
  160. package/dist/chunk-76JDDMSP.js +0 -31
  161. package/dist/chunk-76JDDMSP.js.map +0 -1
  162. package/dist/chunk-A7NCSZAP.cjs.map +0 -1
  163. package/dist/chunk-C54XEN5T.cjs +0 -34
  164. package/dist/chunk-C54XEN5T.cjs.map +0 -1
  165. package/dist/chunk-CJBN5HIS.js.map +0 -1
  166. package/dist/chunk-DZYAAL4H.cjs.map +0 -1
  167. package/dist/chunk-GYCQ3FNL.js.map +0 -1
  168. package/dist/chunk-H2KQ6OSU.js.map +0 -1
  169. package/dist/chunk-IBZJYCYM.js.map +0 -1
  170. package/dist/chunk-MUMH3Z6K.cjs.map +0 -1
  171. package/dist/chunk-OYMWV45N.js.map +0 -1
  172. package/dist/chunk-SWQX6CTT.cjs.map +0 -1
  173. package/dist/settings/FirmPool.d.ts +0 -82
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/home/AddFilesFirst.tsx","../src/home/QuickActionDialogHeader.tsx","../src/lib/useScopeSelection.ts","../src/home/ScopePicker.tsx","../src/home/sections.tsx","../src/lib/balanced-columns.ts","../src/home/StartTiles.tsx"],"names":["jsxs","jsx","useMemo","cn","useState"],"mappings":"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","file":"chunk-5Y7JRY7Y.js","sourcesContent":["import type { ReactNode } from 'react'\nimport { FolderPlus } from 'lucide-react'\n\n/** Fixed strings of the empty-files state. */\nexport interface AddFilesFirstLabels {\n heading: string\n}\n\nexport const DEFAULT_ADD_FILES_FIRST_LABELS: AddFilesFirstLabels = {\n heading: 'Add files first',\n}\n\nexport interface AddFilesFirstProps {\n /** Why this action needs files, in the action's own words. */\n reason: string\n /** The host's own \"Add\" control. */\n action: ReactNode\n testId?: string\n labels?: Partial<AddFilesFirstLabels>\n}\n\n/**\n * What a quick-action dialog shows when the workspace has no files yet.\n *\n * Greying the action out says you cannot do it without saying how to get\n * there. Offering the same \"Add\" menu the Files view carries turns the dead\n * end into the first step: add files here, then run the action.\n */\nexport function AddFilesFirst({ reason, action, testId, labels }: AddFilesFirstProps) {\n const l = { ...DEFAULT_ADD_FILES_FIRST_LABELS, ...labels }\n return (\n <div\n className=\"flex flex-col items-center gap-3 rounded-lg border border-border bg-card shadow-xs px-4 py-8 text-center\"\n data-slot=\"add-files-first\"\n data-testid={testId}\n >\n <span className=\"flex size-11 items-center justify-center rounded-full bg-ai-soft text-ai-ink\">\n <FolderPlus className=\"size-5\" aria-hidden=\"true\" />\n </span>\n <div className=\"flex flex-col gap-1\">\n <p className=\"text-sm font-semibold text-foreground\">{l.heading}</p>\n <p className=\"text-xs leading-relaxed text-muted-foreground\">{reason}</p>\n </div>\n {action}\n </div>\n )\n}\n","import type { ReactNode } from 'react'\nimport { DialogDescription, DialogHeader, DialogTitle } from '@arbidocs/react/ui'\n\nexport interface QuickActionDialogHeaderProps {\n /** The tile's glyph, sized by the caller at `size-5`. */\n icon: ReactNode\n title: string\n /** One sentence on what the dialog does. Keep it to a line or two. */\n description: ReactNode\n /** Test id for the description, where a test asserts on the copy. */\n descriptionTestId?: string\n}\n\n/**\n * The header every \"Start\" quick-action dialog wears: the tile's own mark in\n * its disc, the action's name, and one line saying what the dialog will do.\n *\n * - The disc centres on the TITLE row, so it reads as the title's mark.\n * - The description keeps the title's left edge (`pl-13` = disc + gap), so the\n * header is one text column beside the mark rather than an L.\n * - `max-w-prose` + `text-pretty` cap the measure and stop two-word orphans.\n * - `pr-8` keeps the copy clear of the close button.\n */\nexport function QuickActionDialogHeader({\n icon,\n title,\n description,\n descriptionTestId,\n}: QuickActionDialogHeaderProps) {\n return (\n <DialogHeader className=\"space-y-0 text-left\" data-slot=\"quick-action-dialog-header\">\n <div className=\"flex items-center gap-3 pr-8\">\n <div className=\"flex size-10 shrink-0 items-center justify-center rounded-full bg-ai-soft text-ai-ink\">\n {icon}\n </div>\n <DialogTitle className=\"text-xl font-semibold leading-tight\">{title}</DialogTitle>\n </div>\n <DialogDescription\n className=\"mt-2 max-w-prose pl-13 pr-8 text-sm leading-relaxed text-pretty\"\n data-testid={descriptionTestId}\n >\n {description}\n </DialogDescription>\n </DialogHeader>\n )\n}\n","import { useMemo } from 'react'\n\n/** Which folders and labels a run is limited to. Empty = everything. */\nexport interface DocumentScope {\n /** Folder paths; `''` is the \"unfiled\" bucket. */\n folders: string[]\n /** Label (tag) ids. */\n labels: string[]\n}\n\nexport interface UseScopeSelectionOptions {\n /** Every folder path in the tree (not including the unfiled bucket). */\n folderPaths: string[]\n /** Whether the unfiled bucket is shown as a row. */\n hasUnfiled: boolean\n scope: DocumentScope\n onScopeChange: (scope: DocumentScope) => void\n}\n\n/**\n * Headless selection logic for a folder + label scope picker.\n *\n * Folders use hierarchical selection: ticking \"contracts\" also ticks\n * \"contracts/2024\", and unticking removes the whole subtree. \"All\" ticks every\n * row, which is NOT the same as an empty scope: empty means \"the whole\n * workspace, whatever lands in it later\", all-ticked means \"these folders, as\n * they are now\".\n */\nexport function useScopeSelection({\n folderPaths,\n hasUnfiled,\n scope,\n onScopeChange,\n}: UseScopeSelectionOptions) {\n const selectedFolders = useMemo(() => new Set(scope.folders), [scope.folders])\n const selectedLabels = useMemo(() => new Set(scope.labels), [scope.labels])\n\n /** Every row the folder list shows, \"unfiled\" included. */\n const allRowPaths = useMemo(\n () => [...(hasUnfiled ? [''] : []), ...folderPaths],\n [folderPaths, hasUnfiled]\n )\n const allSelected = allRowPaths.length > 0 && allRowPaths.every((p) => selectedFolders.has(p))\n const someSelected = selectedFolders.size > 0 && !allSelected\n\n const descendants = (path: string) => folderPaths.filter((p) => p.startsWith(path + '/'))\n\n const toggleFolder = (path: string) => {\n const next = new Set(selectedFolders)\n const family = [path, ...descendants(path)]\n if (next.has(path)) for (const p of family) next.delete(p)\n else for (const p of family) next.add(p)\n onScopeChange({ folders: [...next], labels: scope.labels })\n }\n\n const toggleAllFolders = () => {\n onScopeChange({ folders: allSelected ? [] : allRowPaths, labels: scope.labels })\n }\n\n const toggleLabel = (labelId: string) => {\n const next = new Set(selectedLabels)\n if (next.has(labelId)) next.delete(labelId)\n else next.add(labelId)\n onScopeChange({ folders: scope.folders, labels: [...next] })\n }\n\n return {\n selectedFolders,\n selectedLabels,\n allSelected,\n someSelected,\n hasSelection: scope.folders.length > 0 || scope.labels.length > 0,\n toggleFolder,\n toggleAllFolders,\n toggleLabel,\n }\n}\n","import { useMemo, useState } from 'react'\nimport { Check, FileCheck2, Minus } from 'lucide-react'\nimport { cn } from '@arbidocs/react/ui'\nimport { prefixedTestId, testIdOr } from '../chat/test-id'\nimport { useScopeSelection, type DocumentScope } from '../lib/useScopeSelection'\nimport { formatCount } from '../lib/format'\nimport { FoldSection } from './FoldSection'\n\n/**\n * Fixed strings of the picker. Passed as `uiLabels`: the `labels` prop is already the list of\n * document labels to scope by.\n */\nexport interface ScopePickerLabels {\n folders: string\n /** The Labels section heading. */\n labelsHeading: string\n all: string\n unfiled: string\n noFoldersYet: string\n noLabelsYet: string\n filesToInclude: string\n /** \"3 of 10 files\". */\n matchedOfTotal: (matched: number, total: number) => string\n selectedSuffix: string\n folderCount: (count: number) => string\n labelCount: (count: number) => string\n left: (count: number) => string\n /** \"All 10 files\". */\n allFiles: (total: number) => string\n includedSuffix: string\n}\n\nconst pluralize = (n: number, word: string) => `${n} ${word}${n !== 1 ? 's' : ''}`\n\nexport const DEFAULT_SCOPE_PICKER_LABELS: ScopePickerLabels = {\n folders: 'Folders',\n labelsHeading: 'Labels',\n all: 'All',\n unfiled: 'Unfiled',\n noFoldersYet: 'No folders yet',\n noLabelsYet: 'No labels yet — label files from the Files page to scope by them here.',\n filesToInclude: 'Files to include',\n matchedOfTotal: (matched, total) =>\n `${matched} of ${formatCount(total, { one: 'file', other: 'files' })}`,\n selectedSuffix: ' selected',\n folderCount: (count) => pluralize(count, 'folder'),\n labelCount: (count) => pluralize(count, 'label'),\n left: (count) => `${count} left`,\n allFiles: (total) => `All ${pluralize(total, 'file')}`,\n includedSuffix: ' in the workspace will be included',\n}\n\nexport interface ScopeFolder {\n /** Full path, e.g. `contracts/2024`. */\n path: string\n /** Last segment, shown. */\n label: string\n /** Documents under this folder. */\n count: number\n depth: number\n}\n\nexport interface ScopeLabel {\n id: string\n name: string\n /** Any CSS colour for the dot. */\n color: string\n /** Documents carrying this label. */\n count: number\n}\n\nexport interface ScopePickerProps {\n folders: ScopeFolder[]\n /** Documents with no folder; the \"Unfiled\" row is hidden at 0. */\n unfiledCount: number\n labels: ScopeLabel[]\n /** All documents the picker is scoping. */\n totalCount: number\n /** Documents the current scope matches (computed by the caller). */\n matchedCount: number\n scope: DocumentScope\n onScopeChange: (scope: DocumentScope) => void\n /** Reword the picker's fixed strings. */\n uiLabels?: Partial<ScopePickerLabels>\n /** Sub-element ids; defaults are the current ids. `labelChip` is a prefix (`<prefix>-<label id>`). */\n testIds?: Partial<\n Record<'foldersToggle' | 'labelsToggle' | 'noLabels' | 'labelChip' | 'summary', string>\n >\n}\n\ninterface FolderRowProps {\n label: string\n count: number\n depth: number\n isActive: boolean\n indeterminate?: boolean\n muted?: boolean\n onToggle: () => void\n}\n\n/** A checkbox row: the row is the checkbox (a nested real one would swallow the click). */\nfunction FolderRow({\n label,\n count,\n depth,\n isActive,\n indeterminate,\n muted,\n onToggle,\n}: FolderRowProps) {\n return (\n <button\n type=\"button\"\n onClick={onToggle}\n role=\"checkbox\"\n aria-checked={indeterminate ? 'mixed' : isActive}\n style={{ paddingLeft: `${4 + depth * 14}px` }}\n className={cn(\n 'flex w-full items-center gap-1 rounded-sm py-1 pr-2 text-sm transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring [&:hover]:bg-accent pointer-coarse:min-h-11',\n isActive && 'bg-primary/10',\n muted && !isActive && 'text-muted-foreground'\n )}\n data-slot=\"scope-folder-row\"\n >\n <span className=\"flex w-4 shrink-0 items-center justify-center\">\n <span\n className={cn(\n 'flex size-3.5 items-center justify-center rounded-[3px] border transition-colors',\n isActive || indeterminate\n ? 'border-primary bg-primary text-primary-foreground'\n : 'border-muted-foreground/40'\n )}\n >\n {indeterminate ? (\n <Minus className=\"size-2.5\" />\n ) : (\n isActive && <Check className=\"size-2.5\" />\n )}\n </span>\n </span>\n {label !== '' && (\n <span className={cn('min-w-0 truncate', isActive && 'font-semibold text-primary')}>\n {label}\n </span>\n )}\n <span className=\"ml-auto pl-2 text-sm font-semibold text-muted-foreground\">{count}</span>\n </button>\n )\n}\n\n/**\n * Pick a folder + label scope for a run over documents. Controlled: the caller\n * owns the scope and computes `matchedCount`, so the submit button lives with\n * the caller. Both sections start shut: the default (every file) is what most\n * runs want, and the summary states it plainly.\n */\nexport function ScopePicker({\n folders,\n unfiledCount,\n labels,\n totalCount,\n matchedCount,\n scope,\n onScopeChange,\n uiLabels,\n testIds,\n}: ScopePickerProps) {\n const l = { ...DEFAULT_SCOPE_PICKER_LABELS, ...uiLabels }\n const [foldersOpen, setFoldersOpen] = useState(false)\n const [labelsOpen, setLabelsOpen] = useState(false)\n\n const folderPaths = useMemo(() => folders.map((f) => f.path), [folders])\n const selection = useScopeSelection({\n folderPaths,\n hasUnfiled: unfiledCount > 0,\n scope,\n onScopeChange,\n })\n const hasRows = folders.length > 0 || unfiledCount > 0\n\n return (\n <div className=\"flex flex-col gap-4\" data-slot=\"scope-picker\">\n <FoldSection\n label={l.folders}\n count={scope.folders.length}\n open={foldersOpen}\n onOpenChange={setFoldersOpen}\n testId={testIdOr(testIds?.foldersToggle, { testId: 'scope-picker-folders-toggle' })}\n >\n <div className=\"max-h-[180px] overflow-y-auto rounded-md border border-border p-1\">\n {hasRows && (\n <>\n <FolderRow\n label={l.all}\n count={totalCount}\n depth={0}\n isActive={selection.allSelected}\n indeterminate={selection.someSelected}\n onToggle={selection.toggleAllFolders}\n />\n <div className=\"my-1 border-t border-border\" />\n </>\n )}\n {unfiledCount > 0 && (\n <>\n <FolderRow\n label={l.unfiled}\n count={unfiledCount}\n depth={0}\n isActive={selection.selectedFolders.has('')}\n muted\n onToggle={() => selection.toggleFolder('')}\n />\n {folders.length > 0 && <div className=\"my-1 border-t border-border\" />}\n </>\n )}\n {folders.map((folder) => (\n <FolderRow\n key={folder.path}\n label={folder.label}\n count={folder.count}\n depth={folder.depth}\n isActive={selection.selectedFolders.has(folder.path)}\n onToggle={() => selection.toggleFolder(folder.path)}\n />\n ))}\n {!hasRows && <p className=\"px-2 py-1 text-sm text-muted-foreground\">{l.noFoldersYet}</p>}\n </div>\n </FoldSection>\n\n {/* Always present, like Folders: a workspace with no labels yet reads as\n \"you have not labelled anything\", not \"this cannot scope by label\". */}\n <FoldSection\n label={l.labelsHeading}\n count={scope.labels.length}\n open={labelsOpen}\n onOpenChange={setLabelsOpen}\n testId={testIdOr(testIds?.labelsToggle, { testId: 'scope-picker-labels-toggle' })}\n >\n {labels.length === 0 ? (\n <p\n className=\"px-2 py-1 text-sm text-muted-foreground\"\n data-testid={testIdOr(testIds?.noLabels, { testId: 'scope-picker-no-labels' })}\n >\n {l.noLabelsYet}\n </p>\n ) : (\n <div className=\"flex flex-wrap gap-1.5\">\n {labels.map((label) => {\n const isActive = selection.selectedLabels.has(label.id)\n return (\n <button\n key={label.id}\n type=\"button\"\n onClick={() => selection.toggleLabel(label.id)}\n aria-pressed={isActive}\n data-testid={prefixedTestId(testIds?.labelChip, label.id, {\n testId: `scope-picker-label-chip-${label.id}`,\n })}\n className={cn(\n 'inline-flex items-center gap-1.5 rounded-md border px-2 py-1 text-sm transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring pointer-coarse:min-h-11',\n isActive\n ? 'border-primary/40 bg-primary/10 text-primary'\n : 'border-border [&:hover]:bg-accent [&:hover]:text-accent-foreground'\n )}\n >\n <span\n className=\"size-2.5 shrink-0 rounded-full\"\n style={{ backgroundColor: label.color }}\n />\n <span className=\"truncate\">{label.name}</span>\n <span className=\"shrink-0 text-xs text-muted-foreground\">({label.count})</span>\n {isActive && <Check className=\"size-3.5 shrink-0\" />}\n </button>\n )\n })}\n </div>\n )}\n </FoldSection>\n\n <div\n className=\"rounded-lg bg-muted p-3\"\n data-testid={testIdOr(testIds?.summary, { testId: 'scope-picker-summary' })}\n >\n <div className=\"mb-2 flex items-center gap-1.5 text-xs font-medium text-muted-foreground\">\n <FileCheck2 className=\"size-4\" />\n {l.filesToInclude}\n </div>\n {selection.hasSelection ? (\n <div className=\"text-sm text-muted-foreground\">\n <span className=\"text-base font-semibold text-foreground\">\n {l.matchedOfTotal(matchedCount, totalCount)}\n </span>\n {l.selectedSuffix}\n {scope.folders.length > 0 && <span> — {l.folderCount(scope.folders.length)}</span>}\n {scope.folders.length > 0 && scope.labels.length > 0 && <span>, </span>}\n {scope.labels.length > 0 && <span>{l.labelCount(scope.labels.length)}</span>}\n <span className=\"text-xs\">\n {' · '}\n {l.left(totalCount - matchedCount)}\n </span>\n </div>\n ) : (\n <div className=\"text-sm text-muted-foreground\">\n <span className=\"text-base font-semibold text-foreground\">\n {l.allFiles(totalCount)}\n </span>\n {l.includedSuffix}\n </div>\n )}\n </div>\n </div>\n )\n}\n","import type { ReactNode } from 'react'\nimport { Plus, type LucideIcon } from 'lucide-react'\nimport { cn } from '@arbidocs/react/ui'\nimport { ActionLink } from '../components/ActionLink'\n\n/** The small label that names a band of a page (\"Start\", \"Recent\"). */\nexport function SectionLabel({\n children,\n className,\n testId,\n}: {\n children: ReactNode\n className?: string\n testId?: string\n}) {\n return (\n <p\n className={cn(\n 'flex items-center gap-3 text-sm font-semibold text-foreground after:h-px after:flex-1 after:bg-border',\n className\n )}\n data-slot=\"section-label\"\n data-testid={testId}\n >\n {children}\n </p>\n )\n}\n\nexport interface SectionHeaderProps {\n icon?: LucideIcon\n title: string\n count?: number\n /** Makes the title a button (open the full list). Omit for a static title. */\n onOpen?: () => void\n /** Real link target of the title; `onOpen` still fires on a plain click. */\n openHref?: string\n /** Test id of the title button. */\n openTestId?: string\n /** The section's one quiet action, rendered at the trailing edge. */\n action?: ReactNode\n className?: string\n}\n\n/** Title + count + one quiet action: the head of a list section. */\nexport function SectionHeader({\n icon: Icon,\n title,\n count,\n onOpen,\n openHref,\n openTestId,\n action,\n className,\n}: SectionHeaderProps) {\n return (\n <div\n className={cn('flex items-center justify-between gap-2', className)}\n data-slot=\"section-header\"\n >\n <ActionLink\n href={openHref}\n onSelect={onOpen}\n disabled={!onOpen && !openHref}\n className=\"flex min-w-0 cursor-pointer items-center gap-2 rounded-md py-1.5 pr-2 text-left transition-colors hover:text-muted-foreground focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring disabled:cursor-default disabled:hover:text-foreground pointer-coarse:min-h-11\"\n data-testid={openTestId}\n >\n {Icon && <Icon className=\"size-4 shrink-0 text-muted-foreground\" aria-hidden=\"true\" />}\n <span className=\"whitespace-nowrap text-sm font-semibold text-foreground\">{title}</span>\n {count !== undefined && (\n <span className=\"text-sm tabular-nums text-muted-foreground\">{count}</span>\n )}\n </ActionLink>\n {action && <div className=\"shrink-0\">{action}</div>}\n </div>\n )\n}\n\nexport interface EmptyStripProps {\n icon?: LucideIcon\n label: ReactNode\n description?: ReactNode\n onSelect?: () => void\n testId?: string\n}\n\n/** One tonal strip that stands in for an empty section: an invitation, not a void. */\nexport function EmptyStrip({\n icon: Icon = Plus,\n label,\n description,\n onSelect,\n testId,\n}: EmptyStripProps) {\n return (\n <button\n type=\"button\"\n onClick={onSelect}\n disabled={!onSelect}\n className=\"flex w-full items-center gap-3 rounded-lg px-4 py-3 text-left border border-border bg-card shadow-xs transition-colors hover:border-ring/50 hover:bg-accent/40 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring disabled:cursor-default disabled:hover:bg-card disabled:hover:border-border pointer-coarse:min-h-11\"\n data-slot=\"empty-strip\"\n data-testid={testId}\n >\n <Icon className=\"size-5 shrink-0 text-muted-foreground\" aria-hidden=\"true\" />\n <span className=\"min-w-0 flex-1\">\n <span className=\"block text-sm font-semibold text-foreground\">{label}</span>\n {description && (\n <span className=\"block text-sm leading-snug text-muted-foreground\">{description}</span>\n )}\n </span>\n </button>\n )\n}\n","/**\n * The column count for a grid of `count` equal tiles in `width` pixels, chosen so the last row is\n * never left with a lone orphan: of the counts that fit (each column at least `minTile` wide),\n * take the one that leaves the fewest empty cells in the last row, preferring more columns on a\n * tie (never fewer than two columns when two fit). Four tiles resolve to 2x2 where three would fit\n * and 4 across when there is room for four; six resolve to 3x2.\n */\nexport function balancedColumns(count: number, width: number, minTile = 200, gap = 12): number {\n if (count <= 1) return 1\n const fit = Math.max(1, Math.min(count, Math.floor((width + gap) / (minTile + gap))))\n if (fit < 2) return 1\n let best = 2\n let bestEmpty = Number.POSITIVE_INFINITY\n for (let columns = 2; columns <= fit; columns++) {\n const empty = (columns - (count % columns)) % columns\n if (empty < bestEmpty || (empty === bestEmpty && columns > best)) {\n best = columns\n bestEmpty = empty\n }\n }\n return best\n}\n","import { useEffect, useRef, useState, type ReactNode } from 'react'\nimport type { LucideIcon } from 'lucide-react'\nimport { cn } from '@arbidocs/react/ui'\nimport { ActionLink } from '../components/ActionLink'\nimport { balancedColumns } from '../lib/balanced-columns'\nimport { observeResize } from '../lib/observe-resize'\nimport { SectionLabel } from './sections'\n\n/** One \"start something\" tile: an AI-driven action, one click from underway. */\nexport interface StartTile {\n id: string\n /** A Lucide glyph; `iconNode` wins when both are given. */\n icon?: LucideIcon\n /** A ready-made mark (host icon maps), wearing the same AI ink. */\n iconNode?: ReactNode\n title: string\n description: string\n onSelect: () => void\n /** Real link target (ctrl-click / new tab, in-SPA through `BlocksProvider`'s `linkComponent`). `onSelect` still fires on a plain click. */\n href?: string\n /** Rendered non-interactive and dimmed; `disabledReason` replaces the description. */\n disabled?: boolean\n disabledReason?: string\n testId?: string\n}\n\nexport interface StartTilesProps {\n items: StartTile[]\n /** Optional band label above the tiles (\"Start\"). */\n caption?: string\n captionTestId?: string\n className?: string\n testId?: string\n}\n\n/**\n * A band of tonal action tiles. The glyph wears the AI ink, because these are\n * the AI-driven starts. Nothing is hover-only: tiles are always rendered, hover\n * only nudges tone, and touch targets are at least 44px.\n */\nexport function StartTiles({ items, caption, captionTestId, className, testId }: StartTilesProps) {\n // The tiles reflow by their own container width (a docked tablet sidebar narrows it without\n // changing the viewport), choosing a column count that never leaves one tile alone on a row.\n const gridRef = useRef<HTMLDivElement>(null)\n const [columns, setColumns] = useState<number | null>(null)\n const count = items.length\n useEffect(() => {\n const grid = gridRef.current\n if (!grid || count === 0) return\n const measure = () => setColumns(balancedColumns(count, grid.clientWidth))\n measure()\n return observeResize(grid, measure)\n }, [count])\n\n if (count === 0) return null\n return (\n <section\n className={cn('flex flex-col gap-3', className)}\n data-slot=\"start-tiles\"\n data-testid={testId}\n >\n {caption && <SectionLabel testId={captionTestId}>{caption}</SectionLabel>}\n <div\n ref={gridRef}\n data-slot=\"start-tiles-grid\"\n data-columns={columns ?? undefined}\n className=\"grid gap-3\"\n style={{\n gridTemplateColumns:\n columns === null\n ? 'repeat(auto-fit, minmax(200px, 1fr))'\n : `repeat(${columns}, minmax(0, 1fr))`,\n }}\n >\n {items.map((item) => {\n const Icon = item.icon\n return (\n <ActionLink\n key={item.id}\n href={item.href}\n onSelect={item.onSelect}\n disabled={item.disabled}\n title={item.disabled ? item.disabledReason : undefined}\n className={cn(\n 'flex h-full flex-col items-start gap-3 rounded-lg p-4 text-left',\n 'border border-border bg-card shadow-xs transition-colors hover:border-ring/50 hover:bg-accent/40',\n 'focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring',\n 'disabled:cursor-default disabled:opacity-55 disabled:hover:bg-card disabled:hover:border-border',\n 'pointer-coarse:min-h-11'\n )}\n data-slot=\"start-tile\"\n data-testid={item.testId}\n >\n {item.iconNode ? (\n <span className=\"shrink-0 text-ai-ink [&>svg]:size-5\" aria-hidden=\"true\">\n {item.iconNode}\n </span>\n ) : (\n Icon && <Icon className=\"size-5 shrink-0 text-ai-ink\" aria-hidden=\"true\" />\n )}\n <span className=\"min-w-0\">\n <span className=\"block text-sm font-semibold text-foreground\">{item.title}</span>\n <span className=\"mt-1 block text-sm leading-snug text-muted-foreground\">\n {item.disabled && item.disabledReason ? item.disabledReason : item.description}\n </span>\n </span>\n </ActionLink>\n )\n })}\n </div>\n </section>\n )\n}\n"]}
1
+ {"version":3,"sources":["../src/home/AddFilesFirst.tsx","../src/home/QuickActionDialogHeader.tsx","../src/lib/useScopeSelection.ts","../src/home/ScopePicker.tsx","../src/home/sections.tsx","../src/lib/balanced-columns.ts","../src/home/StartTiles.tsx"],"names":["jsxs","jsx","useMemo","cn","useState"],"mappings":"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","file":"chunk-GDBDHOI4.js","sourcesContent":["import type { ReactNode } from 'react'\nimport { FolderPlus } from 'lucide-react'\n\n/** Fixed strings of the empty-files state. */\nexport interface AddFilesFirstLabels {\n heading: string\n}\n\nexport const DEFAULT_ADD_FILES_FIRST_LABELS: AddFilesFirstLabels = {\n heading: 'Add files first',\n}\n\nexport interface AddFilesFirstProps {\n /** Why this action needs files, in the action's own words. */\n reason: string\n /** The host's own \"Add\" control. */\n action: ReactNode\n testId?: string\n labels?: Partial<AddFilesFirstLabels>\n}\n\n/**\n * What a quick-action dialog shows when the workspace has no files yet.\n *\n * Greying the action out says you cannot do it without saying how to get\n * there. Offering the same \"Add\" menu the Files view carries turns the dead\n * end into the first step: add files here, then run the action.\n */\nexport function AddFilesFirst({ reason, action, testId, labels }: AddFilesFirstProps) {\n const l = { ...DEFAULT_ADD_FILES_FIRST_LABELS, ...labels }\n return (\n <div\n className=\"flex flex-col items-center gap-3 rounded-lg border border-border bg-card shadow-xs px-4 py-8 text-center\"\n data-slot=\"add-files-first\"\n data-testid={testId}\n >\n <span className=\"flex size-11 items-center justify-center rounded-full bg-ai-soft text-ai-ink\">\n <FolderPlus className=\"size-5\" aria-hidden=\"true\" />\n </span>\n <div className=\"flex flex-col gap-1\">\n <p className=\"text-sm font-semibold text-foreground\">{l.heading}</p>\n <p className=\"text-xs leading-relaxed text-muted-foreground\">{reason}</p>\n </div>\n {action}\n </div>\n )\n}\n","import type { ReactNode } from 'react'\nimport { DialogDescription, DialogHeader, DialogTitle } from '@arbidocs/react/ui'\n\nexport interface QuickActionDialogHeaderProps {\n /** The tile's glyph, sized by the caller at `size-5`. */\n icon: ReactNode\n title: string\n /** One sentence on what the dialog does. Keep it to a line or two. */\n description: ReactNode\n /** Test id for the description, where a test asserts on the copy. */\n descriptionTestId?: string\n}\n\n/**\n * The header every \"Start\" quick-action dialog wears: the tile's own mark in\n * its disc, the action's name, and one line saying what the dialog will do.\n *\n * - The disc centres on the TITLE row, so it reads as the title's mark.\n * - The description keeps the title's left edge (`pl-13` = disc + gap), so the\n * header is one text column beside the mark rather than an L.\n * - `max-w-prose` + `text-pretty` cap the measure and stop two-word orphans.\n * - `pr-8` keeps the copy clear of the close button.\n */\nexport function QuickActionDialogHeader({\n icon,\n title,\n description,\n descriptionTestId,\n}: QuickActionDialogHeaderProps) {\n return (\n <DialogHeader className=\"space-y-0 text-left\" data-slot=\"quick-action-dialog-header\">\n <div className=\"flex items-center gap-3 pr-8\">\n <div className=\"flex size-10 shrink-0 items-center justify-center rounded-full bg-ai-soft text-ai-ink\">\n {icon}\n </div>\n <DialogTitle className=\"text-xl font-semibold leading-tight\">{title}</DialogTitle>\n </div>\n <DialogDescription\n className=\"mt-2 max-w-prose pl-13 pr-8 text-sm leading-relaxed text-pretty\"\n data-testid={descriptionTestId}\n >\n {description}\n </DialogDescription>\n </DialogHeader>\n )\n}\n","import { useMemo } from 'react'\n\n/** Which folders and labels a run is limited to. Empty = everything. */\nexport interface DocumentScope {\n /** Folder paths; `''` is the \"unfiled\" bucket. */\n folders: string[]\n /** Label (tag) ids. */\n labels: string[]\n}\n\nexport interface UseScopeSelectionOptions {\n /** Every folder path in the tree (not including the unfiled bucket). */\n folderPaths: string[]\n /** Whether the unfiled bucket is shown as a row. */\n hasUnfiled: boolean\n scope: DocumentScope\n onScopeChange: (scope: DocumentScope) => void\n}\n\n/**\n * Headless selection logic for a folder + label scope picker.\n *\n * Folders use hierarchical selection: ticking \"contracts\" also ticks\n * \"contracts/2024\", and unticking removes the whole subtree. \"All\" ticks every\n * row, which is NOT the same as an empty scope: empty means \"the whole\n * workspace, whatever lands in it later\", all-ticked means \"these folders, as\n * they are now\".\n */\nexport function useScopeSelection({\n folderPaths,\n hasUnfiled,\n scope,\n onScopeChange,\n}: UseScopeSelectionOptions) {\n const selectedFolders = useMemo(() => new Set(scope.folders), [scope.folders])\n const selectedLabels = useMemo(() => new Set(scope.labels), [scope.labels])\n\n /** Every row the folder list shows, \"unfiled\" included. */\n const allRowPaths = useMemo(\n () => [...(hasUnfiled ? [''] : []), ...folderPaths],\n [folderPaths, hasUnfiled]\n )\n const allSelected = allRowPaths.length > 0 && allRowPaths.every((p) => selectedFolders.has(p))\n const someSelected = selectedFolders.size > 0 && !allSelected\n\n const descendants = (path: string) => folderPaths.filter((p) => p.startsWith(path + '/'))\n\n const toggleFolder = (path: string) => {\n const next = new Set(selectedFolders)\n const family = [path, ...descendants(path)]\n if (next.has(path)) for (const p of family) next.delete(p)\n else for (const p of family) next.add(p)\n onScopeChange({ folders: [...next], labels: scope.labels })\n }\n\n const toggleAllFolders = () => {\n onScopeChange({ folders: allSelected ? [] : allRowPaths, labels: scope.labels })\n }\n\n const toggleLabel = (labelId: string) => {\n const next = new Set(selectedLabels)\n if (next.has(labelId)) next.delete(labelId)\n else next.add(labelId)\n onScopeChange({ folders: scope.folders, labels: [...next] })\n }\n\n return {\n selectedFolders,\n selectedLabels,\n allSelected,\n someSelected,\n hasSelection: scope.folders.length > 0 || scope.labels.length > 0,\n toggleFolder,\n toggleAllFolders,\n toggleLabel,\n }\n}\n","import { useMemo, useState } from 'react'\nimport { Check, FileCheck2, Minus } from 'lucide-react'\nimport { cn } from '@arbidocs/react/ui'\nimport { prefixedTestId, testIdOr } from '../chat/test-id'\nimport { useScopeSelection, type DocumentScope } from '../lib/useScopeSelection'\nimport { formatCount } from '../lib/format'\nimport { FoldSection } from './FoldSection'\n\n/**\n * Fixed strings of the picker. Passed as `uiLabels`: the `labels` prop is already the list of\n * document labels to scope by.\n */\nexport interface ScopePickerLabels {\n folders: string\n /** The Labels section heading. */\n labelsHeading: string\n all: string\n unfiled: string\n noFoldersYet: string\n noLabelsYet: string\n filesToInclude: string\n /** \"3 of 10 files\". */\n matchedOfTotal: (matched: number, total: number) => string\n selectedSuffix: string\n folderCount: (count: number) => string\n labelCount: (count: number) => string\n left: (count: number) => string\n /** \"All 10 files\". */\n allFiles: (total: number) => string\n includedSuffix: string\n}\n\nconst pluralize = (n: number, word: string) => `${n} ${word}${n !== 1 ? 's' : ''}`\n\nexport const DEFAULT_SCOPE_PICKER_LABELS: ScopePickerLabels = {\n folders: 'Folders',\n labelsHeading: 'Labels',\n all: 'All',\n unfiled: 'Unfiled',\n noFoldersYet: 'No folders yet',\n noLabelsYet: 'No labels yet — label files from the Files page to scope by them here.',\n filesToInclude: 'Files to include',\n matchedOfTotal: (matched, total) =>\n `${matched} of ${formatCount(total, { one: 'file', other: 'files' })}`,\n selectedSuffix: ' selected',\n folderCount: (count) => pluralize(count, 'folder'),\n labelCount: (count) => pluralize(count, 'label'),\n left: (count) => `${count} left`,\n allFiles: (total) => `All ${pluralize(total, 'file')}`,\n includedSuffix: ' in the workspace will be included',\n}\n\nexport interface ScopeFolder {\n /** Full path, e.g. `contracts/2024`. */\n path: string\n /** Last segment, shown. */\n label: string\n /** Documents under this folder. */\n count: number\n depth: number\n}\n\nexport interface ScopeLabel {\n id: string\n name: string\n /** Any CSS colour for the dot. */\n color: string\n /** Documents carrying this label. */\n count: number\n}\n\nexport interface ScopePickerProps {\n folders: ScopeFolder[]\n /** Documents with no folder; the \"Unfiled\" row is hidden at 0. */\n unfiledCount: number\n labels: ScopeLabel[]\n /** All documents the picker is scoping. */\n totalCount: number\n /** Documents the current scope matches (computed by the caller). */\n matchedCount: number\n scope: DocumentScope\n onScopeChange: (scope: DocumentScope) => void\n /** Reword the picker's fixed strings. */\n uiLabels?: Partial<ScopePickerLabels>\n /** Sub-element ids; defaults are the current ids. `labelChip` is a prefix (`<prefix>-<label id>`). */\n testIds?: Partial<\n Record<'foldersToggle' | 'labelsToggle' | 'noLabels' | 'labelChip' | 'summary', string>\n >\n}\n\ninterface FolderRowProps {\n label: string\n count: number\n depth: number\n isActive: boolean\n indeterminate?: boolean\n muted?: boolean\n onToggle: () => void\n}\n\n/** A checkbox row: the row is the checkbox (a nested real one would swallow the click). */\nfunction FolderRow({\n label,\n count,\n depth,\n isActive,\n indeterminate,\n muted,\n onToggle,\n}: FolderRowProps) {\n return (\n <button\n type=\"button\"\n onClick={onToggle}\n role=\"checkbox\"\n aria-checked={indeterminate ? 'mixed' : isActive}\n style={{ paddingLeft: `${4 + depth * 14}px` }}\n className={cn(\n 'flex w-full items-center gap-1 rounded-sm py-1 pr-2 text-sm transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring [&:hover]:bg-accent pointer-coarse:min-h-11',\n isActive && 'bg-primary/10',\n muted && !isActive && 'text-muted-foreground'\n )}\n data-slot=\"scope-folder-row\"\n >\n <span className=\"flex w-4 shrink-0 items-center justify-center\">\n <span\n className={cn(\n 'flex size-3.5 items-center justify-center rounded-[3px] border transition-colors',\n isActive || indeterminate\n ? 'border-primary bg-primary text-primary-foreground'\n : 'border-muted-foreground/40'\n )}\n >\n {indeterminate ? (\n <Minus className=\"size-2.5\" />\n ) : (\n isActive && <Check className=\"size-2.5\" />\n )}\n </span>\n </span>\n {label !== '' && (\n <span className={cn('min-w-0 truncate', isActive && 'font-semibold text-primary')}>\n {label}\n </span>\n )}\n <span className=\"ml-auto pl-2 text-sm font-semibold text-muted-foreground\">{count}</span>\n </button>\n )\n}\n\n/**\n * Pick a folder + label scope for a run over documents. Controlled: the caller\n * owns the scope and computes `matchedCount`, so the submit button lives with\n * the caller. Both sections start shut: the default (every file) is what most\n * runs want, and the summary states it plainly.\n */\nexport function ScopePicker({\n folders,\n unfiledCount,\n labels,\n totalCount,\n matchedCount,\n scope,\n onScopeChange,\n uiLabels,\n testIds,\n}: ScopePickerProps) {\n const l = { ...DEFAULT_SCOPE_PICKER_LABELS, ...uiLabels }\n const [foldersOpen, setFoldersOpen] = useState(false)\n const [labelsOpen, setLabelsOpen] = useState(false)\n\n const folderPaths = useMemo(() => folders.map((f) => f.path), [folders])\n const selection = useScopeSelection({\n folderPaths,\n hasUnfiled: unfiledCount > 0,\n scope,\n onScopeChange,\n })\n const hasRows = folders.length > 0 || unfiledCount > 0\n\n return (\n <div className=\"flex flex-col gap-4\" data-slot=\"scope-picker\">\n <FoldSection\n label={l.folders}\n count={scope.folders.length}\n open={foldersOpen}\n onOpenChange={setFoldersOpen}\n testId={testIdOr(testIds?.foldersToggle, { testId: 'scope-picker-folders-toggle' })}\n >\n <div className=\"max-h-[180px] overflow-y-auto rounded-md border border-border p-1\">\n {hasRows && (\n <>\n <FolderRow\n label={l.all}\n count={totalCount}\n depth={0}\n isActive={selection.allSelected}\n indeterminate={selection.someSelected}\n onToggle={selection.toggleAllFolders}\n />\n <div className=\"my-1 border-t border-border\" />\n </>\n )}\n {unfiledCount > 0 && (\n <>\n <FolderRow\n label={l.unfiled}\n count={unfiledCount}\n depth={0}\n isActive={selection.selectedFolders.has('')}\n muted\n onToggle={() => selection.toggleFolder('')}\n />\n {folders.length > 0 && <div className=\"my-1 border-t border-border\" />}\n </>\n )}\n {folders.map((folder) => (\n <FolderRow\n key={folder.path}\n label={folder.label}\n count={folder.count}\n depth={folder.depth}\n isActive={selection.selectedFolders.has(folder.path)}\n onToggle={() => selection.toggleFolder(folder.path)}\n />\n ))}\n {!hasRows && <p className=\"px-2 py-1 text-sm text-muted-foreground\">{l.noFoldersYet}</p>}\n </div>\n </FoldSection>\n\n {/* Always present, like Folders: a workspace with no labels yet reads as\n \"you have not labelled anything\", not \"this cannot scope by label\". */}\n <FoldSection\n label={l.labelsHeading}\n count={scope.labels.length}\n open={labelsOpen}\n onOpenChange={setLabelsOpen}\n testId={testIdOr(testIds?.labelsToggle, { testId: 'scope-picker-labels-toggle' })}\n >\n {labels.length === 0 ? (\n <p\n className=\"px-2 py-1 text-sm text-muted-foreground\"\n data-testid={testIdOr(testIds?.noLabels, { testId: 'scope-picker-no-labels' })}\n >\n {l.noLabelsYet}\n </p>\n ) : (\n <div className=\"flex flex-wrap gap-1.5\">\n {labels.map((label) => {\n const isActive = selection.selectedLabels.has(label.id)\n return (\n <button\n key={label.id}\n type=\"button\"\n onClick={() => selection.toggleLabel(label.id)}\n aria-pressed={isActive}\n data-testid={prefixedTestId(testIds?.labelChip, label.id, {\n testId: `scope-picker-label-chip-${label.id}`,\n })}\n className={cn(\n 'inline-flex items-center gap-1.5 rounded-md border px-2 py-1 text-sm transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring pointer-coarse:min-h-11',\n isActive\n ? 'border-primary/40 bg-primary/10 text-primary'\n : 'border-border [&:hover]:bg-accent [&:hover]:text-accent-foreground'\n )}\n >\n <span\n className=\"size-2.5 shrink-0 rounded-full\"\n style={{ backgroundColor: label.color }}\n />\n <span className=\"truncate\">{label.name}</span>\n <span className=\"shrink-0 text-xs text-muted-foreground\">({label.count})</span>\n {isActive && <Check className=\"size-3.5 shrink-0\" />}\n </button>\n )\n })}\n </div>\n )}\n </FoldSection>\n\n <div\n className=\"rounded-lg bg-muted p-3\"\n data-testid={testIdOr(testIds?.summary, { testId: 'scope-picker-summary' })}\n >\n <div className=\"mb-2 flex items-center gap-1.5 text-xs font-medium text-muted-foreground\">\n <FileCheck2 className=\"size-4\" />\n {l.filesToInclude}\n </div>\n {selection.hasSelection ? (\n <div className=\"text-sm text-muted-foreground\">\n <span className=\"text-base font-semibold text-foreground\">\n {l.matchedOfTotal(matchedCount, totalCount)}\n </span>\n {l.selectedSuffix}\n {scope.folders.length > 0 && <span> — {l.folderCount(scope.folders.length)}</span>}\n {scope.folders.length > 0 && scope.labels.length > 0 && <span>, </span>}\n {scope.labels.length > 0 && <span>{l.labelCount(scope.labels.length)}</span>}\n <span className=\"text-xs\">\n {' · '}\n {l.left(totalCount - matchedCount)}\n </span>\n </div>\n ) : (\n <div className=\"text-sm text-muted-foreground\">\n <span className=\"text-base font-semibold text-foreground\">\n {l.allFiles(totalCount)}\n </span>\n {l.includedSuffix}\n </div>\n )}\n </div>\n </div>\n )\n}\n","import type { ReactNode } from 'react'\nimport { Plus, type LucideIcon } from 'lucide-react'\nimport { cn } from '@arbidocs/react/ui'\nimport { ActionLink } from '../components/ActionLink'\n\n/** The small label that names a band of a page (\"Start\", \"Recent\"). */\nexport function SectionLabel({\n children,\n className,\n testId,\n}: {\n children: ReactNode\n className?: string\n testId?: string\n}) {\n return (\n <p\n className={cn(\n 'flex items-center gap-3 text-sm font-semibold text-foreground after:h-px after:flex-1 after:bg-border',\n className\n )}\n data-slot=\"section-label\"\n data-testid={testId}\n >\n {children}\n </p>\n )\n}\n\nexport interface SectionHeaderProps {\n icon?: LucideIcon\n title: string\n count?: number\n /** Makes the title a button (open the full list). Omit for a static title. */\n onOpen?: () => void\n /** Real link target of the title; `onOpen` still fires on a plain click. */\n openHref?: string\n /** Test id of the title button. */\n openTestId?: string\n /** The section's one quiet action, rendered at the trailing edge. */\n action?: ReactNode\n className?: string\n}\n\n/** Title + count + one quiet action: the head of a list section. */\nexport function SectionHeader({\n icon: Icon,\n title,\n count,\n onOpen,\n openHref,\n openTestId,\n action,\n className,\n}: SectionHeaderProps) {\n return (\n <div\n className={cn('flex items-center justify-between gap-2', className)}\n data-slot=\"section-header\"\n >\n <ActionLink\n href={openHref}\n onSelect={onOpen}\n disabled={!onOpen && !openHref}\n className=\"flex min-w-0 cursor-pointer items-center gap-2 rounded-md py-1.5 pr-2 text-left transition-colors hover:text-muted-foreground focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring disabled:cursor-default disabled:hover:text-foreground pointer-coarse:min-h-11\"\n data-testid={openTestId}\n >\n {Icon && <Icon className=\"size-4 shrink-0 text-muted-foreground\" aria-hidden=\"true\" />}\n <span className=\"whitespace-nowrap text-sm font-semibold text-foreground\">{title}</span>\n {count !== undefined && (\n <span className=\"text-sm tabular-nums text-muted-foreground\">{count}</span>\n )}\n </ActionLink>\n {action && <div className=\"shrink-0\">{action}</div>}\n </div>\n )\n}\n\nexport interface EmptyStripProps {\n icon?: LucideIcon\n label: ReactNode\n description?: ReactNode\n onSelect?: () => void\n testId?: string\n}\n\n/** One tonal strip that stands in for an empty section: an invitation, not a void. */\nexport function EmptyStrip({\n icon: Icon = Plus,\n label,\n description,\n onSelect,\n testId,\n}: EmptyStripProps) {\n return (\n <button\n type=\"button\"\n onClick={onSelect}\n disabled={!onSelect}\n className=\"flex w-full items-center gap-3 rounded-lg px-4 py-3 text-left border border-border bg-card shadow-xs transition-colors hover:border-ring/50 hover:bg-accent/40 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring disabled:cursor-default disabled:hover:bg-card disabled:hover:border-border pointer-coarse:min-h-11\"\n data-slot=\"empty-strip\"\n data-testid={testId}\n >\n <Icon className=\"size-5 shrink-0 text-muted-foreground\" aria-hidden=\"true\" />\n <span className=\"min-w-0 flex-1\">\n <span className=\"block text-sm font-semibold text-foreground\">{label}</span>\n {description && (\n <span className=\"block text-sm leading-snug text-muted-foreground\">{description}</span>\n )}\n </span>\n </button>\n )\n}\n","/**\n * The column count for a grid of `count` equal tiles in `width` pixels, chosen so the last row is\n * never left with a lone orphan: of the counts that fit (each column at least `minTile` wide),\n * take the one that leaves the fewest empty cells in the last row, preferring more columns on a\n * tie (never fewer than two columns when two fit). Four tiles resolve to 2x2 where three would fit\n * and 4 across when there is room for four; six resolve to 3x2.\n */\nexport function balancedColumns(count: number, width: number, minTile = 200, gap = 12): number {\n if (count <= 1) return 1\n const fit = Math.max(1, Math.min(count, Math.floor((width + gap) / (minTile + gap))))\n if (fit < 2) return 1\n let best = 2\n let bestEmpty = Number.POSITIVE_INFINITY\n for (let columns = 2; columns <= fit; columns++) {\n const empty = (columns - (count % columns)) % columns\n if (empty < bestEmpty || (empty === bestEmpty && columns > best)) {\n best = columns\n bestEmpty = empty\n }\n }\n return best\n}\n","import { useEffect, useRef, useState, type ReactNode } from 'react'\nimport type { LucideIcon } from 'lucide-react'\nimport { cn } from '@arbidocs/react/ui'\nimport { ActionLink } from '../components/ActionLink'\nimport { balancedColumns } from '../lib/balanced-columns'\nimport { observeResize } from '../lib/observe-resize'\nimport { SectionLabel } from './sections'\n\n/** One \"start something\" tile: an AI-driven action, one click from underway. */\nexport interface StartTile {\n id: string\n /** A Lucide glyph; `iconNode` wins when both are given. */\n icon?: LucideIcon\n /** A ready-made mark (host icon maps), wearing the same AI ink. */\n iconNode?: ReactNode\n title: string\n description: string\n onSelect: () => void\n /** Real link target (ctrl-click / new tab, in-SPA through `BlocksProvider`'s `linkComponent`). `onSelect` still fires on a plain click. */\n href?: string\n /** Rendered non-interactive and dimmed; `disabledReason` replaces the description. */\n disabled?: boolean\n disabledReason?: string\n testId?: string\n}\n\nexport interface StartTilesProps {\n items: StartTile[]\n /** Optional band label above the tiles (\"Start\"). */\n caption?: string\n captionTestId?: string\n className?: string\n testId?: string\n}\n\n/**\n * A band of tonal action tiles. The glyph wears the AI ink, because these are\n * the AI-driven starts. Nothing is hover-only: tiles are always rendered, hover\n * only nudges tone, and touch targets are at least 44px.\n */\nexport function StartTiles({ items, caption, captionTestId, className, testId }: StartTilesProps) {\n // The tiles reflow by their own container width (a docked tablet sidebar narrows it without\n // changing the viewport), choosing a column count that never leaves one tile alone on a row.\n const gridRef = useRef<HTMLDivElement>(null)\n const [columns, setColumns] = useState<number | null>(null)\n const count = items.length\n useEffect(() => {\n const grid = gridRef.current\n if (!grid || count === 0) return\n const measure = () => setColumns(balancedColumns(count, grid.clientWidth))\n measure()\n return observeResize(grid, measure)\n }, [count])\n\n if (count === 0) return null\n return (\n <section\n className={cn('flex flex-col gap-3', className)}\n data-slot=\"start-tiles\"\n data-testid={testId}\n >\n {caption && <SectionLabel testId={captionTestId}>{caption}</SectionLabel>}\n <div\n ref={gridRef}\n data-slot=\"start-tiles-grid\"\n data-columns={columns ?? undefined}\n className=\"grid gap-3\"\n style={{\n gridTemplateColumns:\n columns === null\n ? 'repeat(auto-fit, minmax(200px, 1fr))'\n : `repeat(${columns}, minmax(0, 1fr))`,\n }}\n >\n {items.map((item) => {\n const Icon = item.icon\n return (\n <ActionLink\n key={item.id}\n href={item.href}\n onSelect={item.onSelect}\n disabled={item.disabled}\n title={item.disabled ? item.disabledReason : undefined}\n className={cn(\n 'flex h-full flex-col items-start gap-3 rounded-lg p-4 text-left',\n 'border border-border bg-card shadow-xs transition-colors hover:border-ring/50 hover:bg-accent/40',\n 'focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring',\n 'disabled:cursor-default disabled:opacity-55 disabled:hover:bg-card disabled:hover:border-border',\n 'pointer-coarse:min-h-11'\n )}\n data-slot=\"start-tile\"\n data-testid={item.testId}\n >\n {item.iconNode ? (\n <span className=\"shrink-0 text-ai-ink [&>svg]:size-5\" aria-hidden=\"true\">\n {item.iconNode}\n </span>\n ) : (\n Icon && <Icon className=\"size-5 shrink-0 text-ai-ink\" aria-hidden=\"true\" />\n )}\n <span className=\"min-w-0\">\n <span className=\"block text-sm font-semibold text-foreground\">{item.title}</span>\n <span className=\"mt-1 block text-sm leading-snug text-muted-foreground\">\n {item.disabled && item.disabledReason ? item.disabledReason : item.description}\n </span>\n </span>\n </ActionLink>\n )\n })}\n </div>\n </section>\n )\n}\n"]}
@@ -148,6 +148,6 @@ function wallArrayOffset(a, zone) {
148
148
  return Math.round(zdt.offsetNanoseconds / 6e10);
149
149
  }
150
150
 
151
- export { addDays, addMonths, convertWall, detectTimeZone, diffDays, epochToWallArray, formatInZone, formatPlainDate, isValidTimeZone, isoWeekNumber, listTimeZones, safeZone, startOfWeek, todayInZone, utcToDate, utcToTime, utcToWall, wallArrayOffset, wallToEpochMs, wallToUtc, zoneCity, zoneOffsetLabel, zoneOffsetMinutes };
152
- //# sourceMappingURL=chunk-TGJNPKST.js.map
153
- //# sourceMappingURL=chunk-TGJNPKST.js.map
151
+ export { addDays, addMonths, convertWall, dayOfWeekSun0, detectTimeZone, diffDays, epochToWallArray, formatInZone, formatPlainDate, isValidTimeZone, isoWeekNumber, listTimeZones, safeZone, startOfWeek, todayInZone, utcToDate, utcToTime, utcToWall, wallArrayOffset, wallToEpochMs, wallToUtc, zoneCity, zoneOffsetLabel, zoneOffsetMinutes };
152
+ //# sourceMappingURL=chunk-GTCC2VAR.js.map
153
+ //# sourceMappingURL=chunk-GTCC2VAR.js.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/calendar/zone.ts"],"names":[],"mappings":"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","file":"chunk-TGJNPKST.js","sourcesContent":["/**\n * Zone math for the calendar. Every conversion between a wall time in a named IANA zone and a UTC\n * instant goes through Temporal (the polyfill, imported as a module: nothing global is patched),\n * so DST gaps/overlaps resolve the way RFC 5545 says (`compatible`: a skipped time moves forward,\n * a repeated time takes the earlier instant). Nothing here reads the browser's local zone.\n */\nimport { Temporal } from 'temporal-polyfill'\n\nconst pad2 = (n: number) => String(n).padStart(2, '0')\nconst pad4 = (n: number) => String(n).padStart(4, '0')\n\n/** True when `zone` is a time zone the runtime can resolve. */\nexport function isValidTimeZone(zone: string | null | undefined): zone is string {\n if (!zone) return false\n try {\n Temporal.Now.instant().toZonedDateTimeISO(zone)\n return true\n } catch {\n return false\n }\n}\n\n/** `zone` when valid, else `fallback` (else UTC). */\nexport function safeZone(zone: string | null | undefined, fallback = 'UTC'): string {\n if (isValidTimeZone(zone)) return zone\n return isValidTimeZone(fallback) ? fallback : 'UTC'\n}\n\nfunction toPlainDateTime(wall: string): Temporal.PlainDateTime {\n // Accept `YYYY-MM-DDTHH:MM`, `…:SS` and a bare date (midnight).\n return /^\\d{4}-\\d{2}-\\d{2}$/.test(wall)\n ? Temporal.PlainDate.from(wall).toPlainDateTime()\n : Temporal.PlainDateTime.from(wall)\n}\n\n/** The instant a wall time in `zone` names, as an ISO string ending in `Z` (no milliseconds unless set). */\nexport function wallToUtc(wall: string, zone: string): string {\n const zdt = toPlainDateTime(wall).toZonedDateTime(safeZone(zone), {\n disambiguation: 'compatible',\n })\n return zdt.toInstant().toString()\n}\n\n/** Epoch milliseconds of a wall time in `zone`. */\nexport function wallToEpochMs(wall: string, zone: string): number {\n return toPlainDateTime(wall).toZonedDateTime(safeZone(zone), { disambiguation: 'compatible' })\n .epochMilliseconds\n}\n\nfunction instantOf(utc: string | Date | number): Temporal.Instant {\n if (typeof utc === 'number') return Temporal.Instant.fromEpochMilliseconds(utc)\n if (utc instanceof Date) return Temporal.Instant.fromEpochMilliseconds(utc.getTime())\n return Temporal.Instant.from(utc)\n}\n\n/** The zoned date-time of an instant. */\nexport function zoned(utc: string | Date | number, zone: string): Temporal.ZonedDateTime {\n return instantOf(utc).toZonedDateTimeISO(safeZone(zone))\n}\n\n/** `YYYY-MM-DDTHH:MM` wall time of an instant in `zone`. */\nexport function utcToWall(utc: string | Date | number, zone: string): string {\n const z = zoned(utc, zone)\n return `${pad4(z.year)}-${pad2(z.month)}-${pad2(z.day)}T${pad2(z.hour)}:${pad2(z.minute)}`\n}\n\n/** `YYYY-MM-DD` date of an instant in `zone`. */\nexport function utcToDate(utc: string | Date | number, zone: string): string {\n const z = zoned(utc, zone)\n return `${pad4(z.year)}-${pad2(z.month)}-${pad2(z.day)}`\n}\n\n/** `HH:MM` of an instant in `zone`. */\nexport function utcToTime(utc: string | Date | number, zone: string): string {\n const z = zoned(utc, zone)\n return `${pad2(z.hour)}:${pad2(z.minute)}`\n}\n\n/** Convert a wall time from one zone to the same instant's wall time in another. */\nexport function convertWall(wall: string, fromZone: string, toZone: string): string {\n return utcToWall(wallToUtc(wall, fromZone), toZone)\n}\n\n/** Today's date in `zone`. */\nexport function todayInZone(zone: string, now: Date | number = Date.now()): string {\n return utcToDate(now, zone)\n}\n\n/** Calendar arithmetic on a `YYYY-MM-DD` date. */\nexport function addDays(date: string, days: number): string {\n return Temporal.PlainDate.from(date).add({ days }).toString()\n}\n\nexport function addMonths(date: string, months: number): string {\n return Temporal.PlainDate.from(date).add({ months }).toString()\n}\n\n/** Whole days from `a` to `b` (both `YYYY-MM-DD`). */\nexport function diffDays(a: string, b: string): number {\n return Temporal.PlainDate.from(a).until(Temporal.PlainDate.from(b), { largestUnit: 'days' }).days\n}\n\n/** 0 = Sunday … 6 = Saturday, for a `YYYY-MM-DD` date. */\nexport function dayOfWeekSun0(date: string): number {\n return Temporal.PlainDate.from(date).dayOfWeek % 7\n}\n\n/** The first day of the week containing `date`, for a week starting on `weekStart` (0 = Sunday). */\nexport function startOfWeek(date: string, weekStart: number): string {\n const back = (dayOfWeekSun0(date) - weekStart + 7) % 7\n return addDays(date, -back)\n}\n\n/** ISO-8601 week number of a `YYYY-MM-DD` date. */\nexport function isoWeekNumber(date: string): number {\n return Temporal.PlainDate.from(date).weekOfYear ?? 1\n}\n\n/** Offset of `zone` at an instant, in minutes east of UTC. */\nexport function zoneOffsetMinutes(zone: string, at: string | Date | number = Date.now()): number {\n return Math.round(zoned(at, zone).offsetNanoseconds / 60_000_000_000)\n}\n\n/** `GMT+5:30` / `GMT-4` / `GMT` label for `zone` at an instant. */\nexport function zoneOffsetLabel(zone: string, at: string | Date | number = Date.now()): string {\n const total = zoneOffsetMinutes(zone, at)\n if (total === 0) return 'GMT'\n const sign = total > 0 ? '+' : '-'\n const abs = Math.abs(total)\n const h = Math.floor(abs / 60)\n const m = abs % 60\n return `GMT${sign}${h}${m ? `:${pad2(m)}` : ''}`\n}\n\n/** Short city-ish label for a zone: `America/New_York` → `New York`. */\nexport function zoneCity(zone: string): string {\n const last = zone.split('/').pop() ?? zone\n return last.replace(/_/g, ' ')\n}\n\n/** Every IANA zone the runtime knows (falls back to a short list on old engines). */\nexport function listTimeZones(): string[] {\n try {\n const fn = (Intl as unknown as { supportedValuesOf?: (k: string) => string[] })\n .supportedValuesOf\n const zones = fn ? fn('timeZone') : []\n if (zones.length) return zones.includes('UTC') ? zones : ['UTC', ...zones]\n } catch {\n // fall through\n }\n return [\n 'UTC',\n 'Europe/London',\n 'Europe/Paris',\n 'Europe/Berlin',\n 'America/New_York',\n 'America/Chicago',\n 'America/Denver',\n 'America/Los_Angeles',\n 'Asia/Tokyo',\n 'Asia/Singapore',\n 'Australia/Sydney',\n ]\n}\n\n/** The viewer's zone (only as a default for a new user; rendering always uses an explicit zone). */\nexport function detectTimeZone(): string {\n try {\n return Intl.DateTimeFormat().resolvedOptions().timeZone || 'UTC'\n } catch {\n return 'UTC'\n }\n}\n\n/** Format an instant in `zone` with Intl (never the browser zone). */\nexport function formatInZone(\n utc: string | Date | number,\n zone: string,\n options: Intl.DateTimeFormatOptions,\n locale?: string\n): string {\n const ms = instantOf(utc).epochMilliseconds\n return new Intl.DateTimeFormat(locale, { ...options, timeZone: safeZone(zone) }).format(ms)\n}\n\n/** Format a `YYYY-MM-DD` date (zone-free: rendered at UTC noon so no zone can shift the day). */\nexport function formatPlainDate(\n date: string,\n options: Intl.DateTimeFormatOptions,\n locale?: string\n): string {\n return new Intl.DateTimeFormat(locale, { ...options, timeZone: 'UTC' }).format(\n Date.parse(`${date}T12:00:00Z`)\n )\n}\n\n/** Wall-clock array FullCalendar's NamedTimeZoneImpl speaks: [y, m0, d, h, min, s, ms]. */\nexport function epochToWallArray(ms: number, zone: string): number[] {\n const z = Temporal.Instant.fromEpochMilliseconds(ms).toZonedDateTimeISO(zone)\n return [z.year, z.month - 1, z.day, z.hour, z.minute, z.second, z.millisecond]\n}\n\n/** Offset (minutes east of UTC) for a wall-clock array in `zone`, resolving gaps `compatible`. */\nexport function wallArrayOffset(a: number[], zone: string): number {\n // FullCalendar may pass out-of-range parts (e.g. hour 24): normalise via a UTC Date first.\n const norm = new Date(\n Date.UTC(a[0], a[1] ?? 0, a[2] ?? 1, a[3] ?? 0, a[4] ?? 0, a[5] ?? 0, a[6] ?? 0)\n )\n const pdt = new Temporal.PlainDateTime(\n norm.getUTCFullYear(),\n norm.getUTCMonth() + 1,\n norm.getUTCDate(),\n norm.getUTCHours(),\n norm.getUTCMinutes(),\n norm.getUTCSeconds(),\n norm.getUTCMilliseconds()\n )\n const zdt = pdt.toZonedDateTime(zone, { disambiguation: 'compatible' })\n return Math.round(zdt.offsetNanoseconds / 60_000_000_000)\n}\n"]}
1
+ {"version":3,"sources":["../src/calendar/zone.ts"],"names":[],"mappings":"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","file":"chunk-GTCC2VAR.js","sourcesContent":["/**\n * Zone math for the calendar. Every conversion between a wall time in a named IANA zone and a UTC\n * instant goes through Temporal (the polyfill, imported as a module: nothing global is patched),\n * so DST gaps/overlaps resolve the way RFC 5545 says (`compatible`: a skipped time moves forward,\n * a repeated time takes the earlier instant). Nothing here reads the browser's local zone.\n */\nimport { Temporal } from 'temporal-polyfill'\n\nconst pad2 = (n: number) => String(n).padStart(2, '0')\nconst pad4 = (n: number) => String(n).padStart(4, '0')\n\n/** True when `zone` is a time zone the runtime can resolve. */\nexport function isValidTimeZone(zone: string | null | undefined): zone is string {\n if (!zone) return false\n try {\n Temporal.Now.instant().toZonedDateTimeISO(zone)\n return true\n } catch {\n return false\n }\n}\n\n/** `zone` when valid, else `fallback` (else UTC). */\nexport function safeZone(zone: string | null | undefined, fallback = 'UTC'): string {\n if (isValidTimeZone(zone)) return zone\n return isValidTimeZone(fallback) ? fallback : 'UTC'\n}\n\nfunction toPlainDateTime(wall: string): Temporal.PlainDateTime {\n // Accept `YYYY-MM-DDTHH:MM`, `…:SS` and a bare date (midnight).\n return /^\\d{4}-\\d{2}-\\d{2}$/.test(wall)\n ? Temporal.PlainDate.from(wall).toPlainDateTime()\n : Temporal.PlainDateTime.from(wall)\n}\n\n/** The instant a wall time in `zone` names, as an ISO string ending in `Z` (no milliseconds unless set). */\nexport function wallToUtc(wall: string, zone: string): string {\n const zdt = toPlainDateTime(wall).toZonedDateTime(safeZone(zone), {\n disambiguation: 'compatible',\n })\n return zdt.toInstant().toString()\n}\n\n/** Epoch milliseconds of a wall time in `zone`. */\nexport function wallToEpochMs(wall: string, zone: string): number {\n return toPlainDateTime(wall).toZonedDateTime(safeZone(zone), { disambiguation: 'compatible' })\n .epochMilliseconds\n}\n\nfunction instantOf(utc: string | Date | number): Temporal.Instant {\n if (typeof utc === 'number') return Temporal.Instant.fromEpochMilliseconds(utc)\n if (utc instanceof Date) return Temporal.Instant.fromEpochMilliseconds(utc.getTime())\n return Temporal.Instant.from(utc)\n}\n\n/** The zoned date-time of an instant. */\nexport function zoned(utc: string | Date | number, zone: string): Temporal.ZonedDateTime {\n return instantOf(utc).toZonedDateTimeISO(safeZone(zone))\n}\n\n/** `YYYY-MM-DDTHH:MM` wall time of an instant in `zone`. */\nexport function utcToWall(utc: string | Date | number, zone: string): string {\n const z = zoned(utc, zone)\n return `${pad4(z.year)}-${pad2(z.month)}-${pad2(z.day)}T${pad2(z.hour)}:${pad2(z.minute)}`\n}\n\n/** `YYYY-MM-DD` date of an instant in `zone`. */\nexport function utcToDate(utc: string | Date | number, zone: string): string {\n const z = zoned(utc, zone)\n return `${pad4(z.year)}-${pad2(z.month)}-${pad2(z.day)}`\n}\n\n/** `HH:MM` of an instant in `zone`. */\nexport function utcToTime(utc: string | Date | number, zone: string): string {\n const z = zoned(utc, zone)\n return `${pad2(z.hour)}:${pad2(z.minute)}`\n}\n\n/** Convert a wall time from one zone to the same instant's wall time in another. */\nexport function convertWall(wall: string, fromZone: string, toZone: string): string {\n return utcToWall(wallToUtc(wall, fromZone), toZone)\n}\n\n/** Today's date in `zone`. */\nexport function todayInZone(zone: string, now: Date | number = Date.now()): string {\n return utcToDate(now, zone)\n}\n\n/** Calendar arithmetic on a `YYYY-MM-DD` date. */\nexport function addDays(date: string, days: number): string {\n return Temporal.PlainDate.from(date).add({ days }).toString()\n}\n\nexport function addMonths(date: string, months: number): string {\n return Temporal.PlainDate.from(date).add({ months }).toString()\n}\n\n/** Whole days from `a` to `b` (both `YYYY-MM-DD`). */\nexport function diffDays(a: string, b: string): number {\n return Temporal.PlainDate.from(a).until(Temporal.PlainDate.from(b), { largestUnit: 'days' }).days\n}\n\n/** 0 = Sunday … 6 = Saturday, for a `YYYY-MM-DD` date. */\nexport function dayOfWeekSun0(date: string): number {\n return Temporal.PlainDate.from(date).dayOfWeek % 7\n}\n\n/** The first day of the week containing `date`, for a week starting on `weekStart` (0 = Sunday). */\nexport function startOfWeek(date: string, weekStart: number): string {\n const back = (dayOfWeekSun0(date) - weekStart + 7) % 7\n return addDays(date, -back)\n}\n\n/** ISO-8601 week number of a `YYYY-MM-DD` date. */\nexport function isoWeekNumber(date: string): number {\n return Temporal.PlainDate.from(date).weekOfYear ?? 1\n}\n\n/** Offset of `zone` at an instant, in minutes east of UTC. */\nexport function zoneOffsetMinutes(zone: string, at: string | Date | number = Date.now()): number {\n return Math.round(zoned(at, zone).offsetNanoseconds / 60_000_000_000)\n}\n\n/** `GMT+5:30` / `GMT-4` / `GMT` label for `zone` at an instant. */\nexport function zoneOffsetLabel(zone: string, at: string | Date | number = Date.now()): string {\n const total = zoneOffsetMinutes(zone, at)\n if (total === 0) return 'GMT'\n const sign = total > 0 ? '+' : '-'\n const abs = Math.abs(total)\n const h = Math.floor(abs / 60)\n const m = abs % 60\n return `GMT${sign}${h}${m ? `:${pad2(m)}` : ''}`\n}\n\n/** Short city-ish label for a zone: `America/New_York` → `New York`. */\nexport function zoneCity(zone: string): string {\n const last = zone.split('/').pop() ?? zone\n return last.replace(/_/g, ' ')\n}\n\n/** Every IANA zone the runtime knows (falls back to a short list on old engines). */\nexport function listTimeZones(): string[] {\n try {\n const fn = (Intl as unknown as { supportedValuesOf?: (k: string) => string[] })\n .supportedValuesOf\n const zones = fn ? fn('timeZone') : []\n if (zones.length) return zones.includes('UTC') ? zones : ['UTC', ...zones]\n } catch {\n // fall through\n }\n return [\n 'UTC',\n 'Europe/London',\n 'Europe/Paris',\n 'Europe/Berlin',\n 'America/New_York',\n 'America/Chicago',\n 'America/Denver',\n 'America/Los_Angeles',\n 'Asia/Tokyo',\n 'Asia/Singapore',\n 'Australia/Sydney',\n ]\n}\n\n/** The viewer's zone (only as a default for a new user; rendering always uses an explicit zone). */\nexport function detectTimeZone(): string {\n try {\n return Intl.DateTimeFormat().resolvedOptions().timeZone || 'UTC'\n } catch {\n return 'UTC'\n }\n}\n\n/** Format an instant in `zone` with Intl (never the browser zone). */\nexport function formatInZone(\n utc: string | Date | number,\n zone: string,\n options: Intl.DateTimeFormatOptions,\n locale?: string\n): string {\n const ms = instantOf(utc).epochMilliseconds\n return new Intl.DateTimeFormat(locale, { ...options, timeZone: safeZone(zone) }).format(ms)\n}\n\n/** Format a `YYYY-MM-DD` date (zone-free: rendered at UTC noon so no zone can shift the day). */\nexport function formatPlainDate(\n date: string,\n options: Intl.DateTimeFormatOptions,\n locale?: string\n): string {\n return new Intl.DateTimeFormat(locale, { ...options, timeZone: 'UTC' }).format(\n Date.parse(`${date}T12:00:00Z`)\n )\n}\n\n/** Wall-clock array FullCalendar's NamedTimeZoneImpl speaks: [y, m0, d, h, min, s, ms]. */\nexport function epochToWallArray(ms: number, zone: string): number[] {\n const z = Temporal.Instant.fromEpochMilliseconds(ms).toZonedDateTimeISO(zone)\n return [z.year, z.month - 1, z.day, z.hour, z.minute, z.second, z.millisecond]\n}\n\n/** Offset (minutes east of UTC) for a wall-clock array in `zone`, resolving gaps `compatible`. */\nexport function wallArrayOffset(a: number[], zone: string): number {\n // FullCalendar may pass out-of-range parts (e.g. hour 24): normalise via a UTC Date first.\n const norm = new Date(\n Date.UTC(a[0], a[1] ?? 0, a[2] ?? 1, a[3] ?? 0, a[4] ?? 0, a[5] ?? 0, a[6] ?? 0)\n )\n const pdt = new Temporal.PlainDateTime(\n norm.getUTCFullYear(),\n norm.getUTCMonth() + 1,\n norm.getUTCDate(),\n norm.getUTCHours(),\n norm.getUTCMinutes(),\n norm.getUTCSeconds(),\n norm.getUTCMilliseconds()\n )\n const zdt = pdt.toZonedDateTime(zone, { disambiguation: 'compatible' })\n return Math.round(zdt.offsetNanoseconds / 60_000_000_000)\n}\n"]}
@@ -1,10 +1,11 @@
1
1
  "use client";
2
2
  'use strict';
3
3
 
4
- var chunkMUMH3Z6K_cjs = require('./chunk-MUMH3Z6K.cjs');
4
+ var chunkARDHLU73_cjs = require('./chunk-ARDHLU73.cjs');
5
5
  var chunkS24XEVPS_cjs = require('./chunk-S24XEVPS.cjs');
6
6
  var chunkV5OAXIBN_cjs = require('./chunk-V5OAXIBN.cjs');
7
- var chunkSWQX6CTT_cjs = require('./chunk-SWQX6CTT.cjs');
7
+ var chunkJKB7WT7L_cjs = require('./chunk-JKB7WT7L.cjs');
8
+ var chunkC4WSHRR6_cjs = require('./chunk-C4WSHRR6.cjs');
8
9
  var react$1 = require('react');
9
10
  var reactQuery = require('@tanstack/react-query');
10
11
  var react = require('@arbidocs/react');
@@ -15,15 +16,16 @@ function ConnectedNativeDocxEditor({
15
16
  ...props
16
17
  }) {
17
18
  const adapter = useConnectedNativeDocxAdapter(fontBaseUrl);
18
- const { workspaceId } = chunkMUMH3Z6K_cjs.useConnection();
19
+ const { workspaceId } = chunkARDHLU73_cjs.useConnection();
19
20
  const live = !props.snapshot && !props.stream && !props.draftContent && !props.compact;
20
- chunkSWQX6CTT_cjs.useRegisterOpenDocument({ documentId: live ? props.documentId : null, workspaceId });
21
+ chunkJKB7WT7L_cjs.useRegisterOpenDocument({ documentId: live ? props.documentId : null, workspaceId });
21
22
  return /* @__PURE__ */ jsxRuntime.jsx(chunkV5OAXIBN_cjs.NativeDocxEditor, { ...props, adapter });
22
23
  }
23
24
  function useConnectedNativeDocxAdapter(fontBaseUrl = "/native-docx/fonts") {
24
25
  const arbi = react.useArbi();
25
- const { workspaceId, apiUrl, user, ensureWorkspaceOpen } = chunkMUMH3Z6K_cjs.useConnection();
26
+ const { workspaceId, apiUrl, user, ensureWorkspaceOpen } = chunkARDHLU73_cjs.useConnection();
26
27
  const queries = reactQuery.useQueryClient();
28
+ const { notify } = chunkC4WSHRR6_cjs.useBlocksEnvironment();
27
29
  const { data: members } = reactQuery.useQuery({
28
30
  queryKey: ["native-docx-members", apiUrl, user?.externalId, workspaceId],
29
31
  enabled: arbi.isLoggedIn && !!workspaceId,
@@ -66,7 +68,7 @@ function useConnectedNativeDocxAdapter(fontBaseUrl = "/native-docx/fonts") {
66
68
  await queries.invalidateQueries({ queryKey: key });
67
69
  }
68
70
  },
69
- notify: (message, kind) => react.notify[kind](message),
71
+ notify,
70
72
  mentions: members?.map(({ user: member }) => ({
71
73
  id: member.external_id,
72
74
  name: [member.given_name, member.family_name].filter(Boolean).join(" "),
@@ -84,17 +86,27 @@ function useConnectedNativeDocxAdapter(fontBaseUrl = "/native-docx/fonts") {
84
86
  })
85
87
  });
86
88
  const delivery = await response.json();
87
- react.notify.success("Mention delivered.");
89
+ notify("Mention delivered.", "success");
88
90
  return { responseIds: delivery.response_ids || [] };
89
91
  },
90
92
  getAgentStatus: async (responseId) => (await arbi.assistant.getResponse(responseId)).status
91
93
  }),
92
- [arbi, apiUrl, user?.name, members, ensureWorkspaceOpen, fontBaseUrl, queries, workspaceId]
94
+ [
95
+ arbi,
96
+ apiUrl,
97
+ user?.name,
98
+ members,
99
+ ensureWorkspaceOpen,
100
+ fontBaseUrl,
101
+ queries,
102
+ workspaceId,
103
+ notify
104
+ ]
93
105
  );
94
106
  return adapter;
95
107
  }
96
108
 
97
109
  exports.ConnectedNativeDocxEditor = ConnectedNativeDocxEditor;
98
110
  exports.useConnectedNativeDocxAdapter = useConnectedNativeDocxAdapter;
99
- //# sourceMappingURL=chunk-3BJLNKOB.cjs.map
100
- //# sourceMappingURL=chunk-3BJLNKOB.cjs.map
111
+ //# sourceMappingURL=chunk-GZPTWHP5.cjs.map
112
+ //# sourceMappingURL=chunk-GZPTWHP5.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/connection/ConnectedNativeDocxEditor.tsx"],"names":["useConnection","useRegisterOpenDocument","jsx","NativeDocxEditor","useArbi","useQueryClient","useBlocksEnvironment","useQuery","useMemo","loadDocxFonts","arbiQueryKeys"],"mappings":"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","file":"chunk-GZPTWHP5.cjs","sourcesContent":["import { useMemo } from 'react'\nimport { useQuery, useQueryClient } from '@tanstack/react-query'\nimport { useArbi, arbiQueryKeys } from '@arbidocs/react'\nimport { useConnection } from './ConnectionProvider'\nimport {\n NativeDocxEditor,\n type NativeDocxAdapter,\n type NativeDocxEditorProps,\n} from '../docx/NativeDocxEditor'\nimport { loadDocxFonts } from '../docx/fonts'\nimport { useRegisterOpenDocument } from '../chat/open-document'\nimport { useBlocksEnvironment } from '../provider/BlocksProvider'\n\n/** Native Word widget bound to the standard blocks connection and SDK session. */\nexport function ConnectedNativeDocxEditor({\n fontBaseUrl = '/native-docx/fonts',\n ...props\n}: Omit<NativeDocxEditorProps, 'adapter'> & { fontBaseUrl?: string }) {\n const adapter = useConnectedNativeDocxAdapter(fontBaseUrl)\n const { workspaceId } = useConnection()\n // Drafting mode: the saved Word document being edited is what the chat is about. A history\n // snapshot, a streamed preview, an unsaved draft and an embedded body field are not.\n const live = !props.snapshot && !props.stream && !props.draftContent && !props.compact\n useRegisterOpenDocument({ documentId: live ? props.documentId : null, workspaceId })\n return <NativeDocxEditor {...props} adapter={adapter} />\n}\n\nexport function useConnectedNativeDocxAdapter(fontBaseUrl = '/native-docx/fonts') {\n const arbi = useArbi()\n const { workspaceId, apiUrl, user, ensureWorkspaceOpen } = useConnection()\n const queries = useQueryClient()\n const { notify } = useBlocksEnvironment()\n const { data: members } = useQuery({\n queryKey: ['native-docx-members', apiUrl, user?.externalId, workspaceId],\n enabled: arbi.isLoggedIn && !!workspaceId,\n queryFn: async () => {\n await ensureWorkspaceOpen()\n return arbi.workspaces.listUsers()\n },\n })\n const adapter = useMemo<NativeDocxAdapter>(\n () => ({\n request: async (path, options) => {\n await ensureWorkspaceOpen()\n return arbi.editor.request(path, options)\n },\n open: async (id) => {\n await ensureWorkspaceOpen()\n return (\n await arbi.editor.request(`/${encodeURIComponent(id)}/session`, { method: 'POST' })\n ).json()\n },\n save: async (id, state) =>\n (\n await arbi.editor.request(`/${encodeURIComponent(id)}/save`, {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify({ state }),\n })\n ).json(),\n loadFonts: () => loadDocxFonts(fontBaseUrl),\n baseUrl: apiUrl,\n author: user?.name || 'You',\n onVersionSaved: async (id) => {\n if (!workspaceId) return\n const key = arbiQueryKeys.documents(workspaceId)\n try {\n const documents = await arbi.documents.get([id])\n if (!documents.length) throw new Error('The saved version is not available yet.')\n queries.setQueryData<Awaited<ReturnType<typeof arbi.documents.list>>>(key, (previous) => [\n ...documents,\n ...(previous || []).filter(\n (doc) => !documents.some((saved) => saved.external_id === doc.external_id)\n ),\n ])\n } catch {\n await queries.invalidateQueries({ queryKey: key })\n }\n },\n notify,\n mentions: members?.map(({ user: member }) => ({\n id: member.external_id,\n name: [member.given_name, member.family_name].filter(Boolean).join(' '),\n kind: member.external_id.startsWith('agt-') ? 'agent' : 'human',\n })),\n requestAgent: async (id, request) => {\n const response = await arbi.editor.request(`/${encodeURIComponent(id)}/mentions`, {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify({\n comment_id: request.commentId,\n instruction: request.instruction,\n request_id: request.requestId,\n recipient_ids: request.recipientIds,\n }),\n })\n const delivery = (await response.json()) as { response_ids: string[] }\n notify('Mention delivered.', 'success')\n return { responseIds: delivery.response_ids || [] }\n },\n getAgentStatus: async (responseId) => (await arbi.assistant.getResponse(responseId)).status,\n }),\n [\n arbi,\n apiUrl,\n user?.name,\n members,\n ensureWorkspaceOpen,\n fontBaseUrl,\n queries,\n workspaceId,\n notify,\n ]\n )\n return adapter\n}\n"]}
@@ -1,7 +1,7 @@
1
1
  "use client";
2
2
  'use strict';
3
3
 
4
- var chunkC54XEN5T_cjs = require('./chunk-C54XEN5T.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 } = chunkC54XEN5T_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-OUW6G4O2.cjs.map
96
- //# sourceMappingURL=chunk-OUW6G4O2.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-OUW6G4O2.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":";;;;;;;;AAYO,IAAM,yBAAA,GAA6C;AAAA,EACxD,QAAA,EAAU,WAAA;AAAA,EACV,QAAA,EAAU;AACZ;AAEA,SAAS,gBAAgB,CAAA,EAAwB;AAC/C,EAAA,OAAO,CAAA,CAAE,WAAW,CAAA,IAAK,CAAA,CAAE,WAAW,CAAA,CAAE,OAAA,IAAW,CAAA,CAAE,QAAA,IAAY,CAAA,CAAE,MAAA;AACrE;AAgCO,IAAM,SAAA,GAAYA,UAAA,CAAK,SAASC,UAAAA,CAAU;AAAA,EAC/C,MAAA;AAAA,EACA,OAAA;AAAA,EACA,KAAA;AAAA,EACA,aAAA;AAAA,EACA,OAAA;AAAA,EACA,MAAA,GAAS,KAAA;AAAA,EACT,QAAA,GAAW,KAAA;AAAA,EACX,WAAA;AAAA,EACA,IAAA;AAAA,EACA,MAAA;AAAA,EACA,MAAA;AAAA,EACA;AACF,CAAA,EAAmB;AACjB,EAAA,MAAM,CAAA,GAAI,EAAE,GAAG,yBAAA,EAA2B,GAAG,MAAA,EAAO;AACpD,EAAA,MAAM,EAAE,aAAA,EAAe,IAAA,EAAK,GAAIC,sCAAA,EAAqB;AACrD,EAAA,MAAM,CAAC,QAAA,EAAU,WAAW,CAAA,GAAIC,eAAS,KAAK,CAAA;AAC9C,EAAA,MAAM,CAAC,WAAA,EAAa,cAAc,CAAA,GAAIA,eAAS,KAAK,CAAA;AACpD,EAAA,MAAM,OAAA,GAAUC,aAAuB,IAAI,CAAA;AAG3C,EAAAC,qBAAA,CAAgB,MAAM;AACpB,IAAA,MAAM,KAAK,OAAA,CAAQ,OAAA;AACnB,IAAA,IAAI,CAAC,MAAM,QAAA,EAAU;AACrB,IAAA,cAAA,CAAe,EAAA,CAAG,YAAA,GAAe,EAAA,CAAG,YAAA,GAAe,CAAC,CAAA;AAAA,EACtD,CAAA,EAAG,CAAC,OAAA,EAAS,KAAA,EAAO,QAAQ,CAAC,CAAA;AAE7B,EAAA,MAAM,eAAA,GAAkB,CAAC,CAAA,KAAkB;AACzC,IAAA,IAAI,IAAA,IAAQ,eAAA,CAAgB,CAAC,CAAA,EAAG;AAChC,IAAA,IAAI,IAAA,IAAQ,cAAA,EAAe;AAC3B,IAAA,OAAA,CAAQ,CAAC,CAAA;AAAA,EACX,CAAA;AAEA,EAAA,MAAM,IAAA,mBACJC,cAAA;AAAA,IAACC,cAAA;AAAA,IAAA;AAAA,MACC,MAAA;AAAA,MACA,SAAA,EAAWC,KAAA;AAAA;AAAA,QAET,0BAAA;AAAA,QACA,MAAA,IAAU,qCAAA;AAAA,QACV;AAAA,OACF;AAAA,MACA,MAAA,EAAQ,QAAA;AAAA,MACR,aAAa,WAAA,oBAAeF,cAAA,CAACG,mBAAI,SAAA,EAAU,8BAAA,EAA+B,eAAW,IAAA,EAAC,CAAA;AAAA,MACtF,OAAA,EAAS,eAAA;AAAA,MACT,aAAA,EAAa,MAAA;AAAA,MACb,SACG,WAAA,IAAe,QAAA,qBACdH,cAAA,CAAC,KAAA,EAAA,EAAI,WAAU,kBAAA,EACb,QAAA,kBAAAA,cAAA;AAAA,QAAC,QAAA;AAAA,QAAA;AAAA,UACC,IAAA,EAAK,QAAA;AAAA,UACL,SAAA,EAAU,+EAAA;AAAA,UACV,OAAA,EAAS,CAAC,CAAA,KAAM;AACd,YAAA,CAAA,CAAE,eAAA,EAAgB;AAClB,YAAA,CAAA,CAAE,cAAA,EAAe;AACjB,YAAA,WAAA,CAAY,CAAC,CAAA,KAAM,CAAC,CAAC,CAAA;AAAA,UACvB,CAAA;AAAA,UAEC,QAAA,EAAA,QAAA,GAAW,CAAA,CAAE,QAAA,GAAW,CAAA,CAAE;AAAA;AAAA,OAC7B,EACF,CAAA;AAAA,MAIJ,QAAA,kBAAAA,cAAA;AAAA,QAAC,KAAA;AAAA,QAAA;AAAA,UACC,GAAA,EAAK,OAAA;AAAA,UACL,WAAA,EAAU,YAAA;AAAA,UACV,SAAA,EAAWE,KAAA,CAAG,4BAAA,EAA8B,CAAC,YAAY,cAAc,CAAA;AAAA,UAEtE,QAAA,EAAA,aAAA,CAAc,SAAS,KAAK;AAAA;AAAA;AAC/B;AAAA,GACF;AAEF,EAAA,IAAI,CAAC,MAAM,OAAO,IAAA;AAClB,EAAA,MAAM,SAAA,GAAY;AAAA,IAChB,IAAA;AAAA,IACA,SAAA,EAAW,OAAA;AAAA,IACX,WAAA,EAAa;AAAA,GACf;AACA,EAAA,OAAO,IAAA,mBAAOF,cAAA,CAAC,IAAA,EAAA,EAAM,GAAG,SAAA,EAAY,QAAA,EAAA,IAAA,EAAK,CAAA,mBAAUA,cAAA,CAAC,GAAA,EAAA,EAAG,GAAG,SAAA,EAAY,QAAA,EAAA,IAAA,EAAK,CAAA;AAC7E,CAAC","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"]}
@@ -61,5 +61,5 @@ exports.savedDocumentIdFor = savedDocumentIdFor;
61
61
  exports.takeOpenDocumentForTurn = takeOpenDocumentForTurn;
62
62
  exports.useOpenDocumentId = useOpenDocumentId;
63
63
  exports.useRegisterOpenDocument = useRegisterOpenDocument;
64
- //# sourceMappingURL=chunk-SWQX6CTT.cjs.map
65
- //# sourceMappingURL=chunk-SWQX6CTT.cjs.map
64
+ //# sourceMappingURL=chunk-JKB7WT7L.cjs.map
65
+ //# sourceMappingURL=chunk-JKB7WT7L.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/chat/open-document.ts"],"names":["useRef","useEffect","useSyncExternalStore","parseVersionRef"],"mappings":";;;;;;AA+CO,SAAS,mBAAmB,KAAA,EAA0C;AAC3E,EAAA,MAAM,EAAE,UAAA,EAAY,OAAA,EAAS,WAAA,EAAa,cAAA,EAAgB,cAAa,GAAI,KAAA;AAC3E,EAAA,IAAI,CAAC,UAAA,IAAc,OAAA,IAAW,WAAA,IAAe,gBAAgB,OAAO,IAAA;AACpE,EAAA,IACE,YAAA,EAAc,YAAY,UAAA,IAC1B,CAAC,cAAc,SAAA,EAAW,WAAA,EAAY,CAAE,QAAA,CAAS,OAAO,CAAA;AAExD,IAAA,OAAO,IAAA;AAET,EAAA,IAAI,YAAA,CAAa,WAAA,KAAgB,UAAA,EAAY,OAAO,IAAA;AACpD,EAAA,OAAO,UAAA;AACT;AAkBA,IAAI,UAAmB,EAAC;AACxB,IAAM,SAAA,uBAAgB,GAAA,EAAgB;AAEtC,SAAS,UAAU,QAAA,EAAkC;AACnD,EAAA,SAAA,CAAU,IAAI,QAAQ,CAAA;AACtB,EAAA,OAAO,MAAM,SAAA,CAAU,MAAA,CAAO,QAAQ,CAAA;AACxC;AAEA,SAAS,IAAA,GAAO;AACd,EAAA,SAAA,CAAU,OAAA,CAAQ,CAAC,CAAA,KAAM,CAAA,EAAG,CAAA;AAC9B;AAEA,IAAM,GAAA,GAAM,MAAyB,OAAA,CAAQ,OAAA,CAAQ,SAAS,CAAC,CAAA;AAMxD,SAAS,wBAAwB,YAAA,EAA8C;AACpF,EAAA,MAAM,MAAA,GAASA,aAAO,YAAY,CAAA;AAClC,EAAAC,eAAA,CAAU,MAAM;AACd,IAAA,MAAA,CAAO,OAAA,GAAU,YAAA;AAAA,EACnB,CAAC,CAAA;AACD,EAAA,MAAM,EAAE,YAAW,GAAI,YAAA;AACvB,EAAAA,eAAA,CAAU,MAAM;AACd,IAAA,IAAI,CAAC,UAAA,EAAY;AACjB,IAAA,MAAM,QAAe,EAAE,UAAA,EAAY,OAAA,EAAS,MAAM,OAAO,OAAA,EAAQ;AACjE,IAAA,OAAA,GAAU,CAAC,GAAG,OAAA,EAAS,KAAK,CAAA;AAC5B,IAAA,IAAA,EAAK;AACL,IAAA,OAAO,MAAM;AACX,MAAA,OAAA,GAAU,OAAA,CAAQ,MAAA,CAAO,CAAC,CAAA,KAAM,MAAM,KAAK,CAAA;AAC3C,MAAA,IAAA,EAAK;AAAA,IACP,CAAA;AAAA,EACF,CAAA,EAAG,CAAC,UAAU,CAAC,CAAA;AACjB;AAGO,SAAS,iBAAA,GAAmC;AACjD,EAAA,OAAOC,0BAAA;AAAA,IACL,SAAA;AAAA,IACA,MAAM,GAAA,EAAI,EAAG,UAAA,IAAc,IAAA;AAAA,IAC3B,MAAM;AAAA,GACR;AACF;AAQO,SAAS,wBAAwB,OAAA,EAA0D;AAChG,EAAA,MAAM,QAAQ,GAAA,EAAI;AAClB,EAAA,IAAI,CAAC,OAAO,OAAO,IAAA;AACnB,EAAA,MAAM,EAAE,OAAA,EAAS,QAAA,EAAU,WAAA,EAAY,GAAI,MAAM,OAAA,EAAQ;AACzD,EAAA,IAAI,SAAS,WAAA,IAAe,WAAA,IAAe,OAAA,CAAQ,WAAA,KAAgB,aAAa,OAAO,IAAA;AACvF,EAAA,IACE,OAAA,IACA,YAAY,KAAA,CAAM,UAAA,IAClBC,0BAAgB,OAAO,CAAA,CAAE,UAAU,KAAA,CAAM,UAAA;AAEzC,IAAA,QAAA,IAAW;AACb,EAAA,OAAO,KAAA,CAAM,UAAA;AACf","file":"chunk-JKB7WT7L.cjs","sourcesContent":["import { useEffect, useRef, useSyncExternalStore } from 'react'\nimport { parseVersionRef } from '@arbidocs/react/artifacts'\n\n/**\n * Drafting mode: the saved document open beside the chat is what a chat turn is about.\n *\n * A viewer registers the document it shows (`useRegisterOpenDocument`); every assistant turn names\n * it (`active_artifact_ext_id`, read with `takeOpenDocumentForTurn` as the question is sent), so the\n * server binds the live document to the turn: a Word document is read on demand and edited as\n * tracked changes in the open editor, and what the assistant saves becomes a child version of it.\n * The request carries a reference, never the content.\n *\n * The open document is always the subject, also while one of its earlier versions is on screen\n * read-only: a version still names its document. Sending a turn then returns the viewer to the live\n * document (`showLive`), where the assistant's edits appear as they are made. (Pinning a specific\n * version as a source is a separate feature: it does not go through here.)\n *\n * A module-level registry (not React context), like `useChatSurface`, so a viewer and a chat agree\n * wherever they sit in the tree; the most recently opened document wins and closing it hands back\n * to the one before. It is not the session state's viewing document (`useArbiSessionState`): it\n * holds what mounted viewers can draft in (saved documents only, with the callback that shows the\n * live one again), and a turn reads it outside React. A viewer on the session's viewing document\n * passes that as `shownId` (it may be a version reference, resolved here the same way as\n * `selectViewingDocumentId` does).\n */\n\n/** What a viewer knows about the document it shows. */\nexport interface SavedDocumentInput {\n /** The document (`doc-…`), never a version reference. */\n documentId: string | null | undefined\n /** An unsaved draft (client-minted id, no backend record). */\n isDraft: boolean\n /** Still streaming: nothing is persisted yet. */\n isStreaming: boolean\n /** An image, audio or video artifact: there is no text to draft in. */\n isBlobArtifact: boolean\n /** The loaded document record. */\n documentData:\n | { external_id?: string | null; wp_type?: string | null; file_name?: string | null }\n | null\n | undefined\n}\n\n/**\n * The saved, content-backed document a chat can draft in, or null. Only a saved artifact or Word\n * document counts: drafts, an artifact still streaming and blob artifacts do not.\n */\nexport function savedDocumentIdFor(input: SavedDocumentInput): string | null {\n const { documentId, isDraft, isStreaming, isBlobArtifact, documentData } = input\n if (!documentId || isDraft || isStreaming || isBlobArtifact) return null\n if (\n documentData?.wp_type !== 'artifact' &&\n !documentData?.file_name?.toLowerCase().endsWith('.docx')\n )\n return null\n // A stale record of the previously viewed document is not this one.\n if (documentData.external_id !== documentId) return null\n return documentId\n}\n\nexport interface OpenDocumentRegistration {\n /** The saved document the viewer shows (`doc-…`); null or empty registers nothing. */\n documentId: string | null | undefined\n /** What is on screen: the document itself, or one of its earlier versions (`doc-…@v2`). */\n shownId?: string | null\n /** Show the live document again. Called when a turn starts while an earlier version is shown. */\n showLive?: () => void\n /** The workspace the document belongs to; a chat in another workspace does not draft in it. */\n workspaceId?: string | null\n}\n\ninterface Entry {\n documentId: string\n current: () => OpenDocumentRegistration\n}\n\nlet entries: Entry[] = []\nconst listeners = new Set<() => void>()\n\nfunction subscribe(listener: () => void): () => void {\n listeners.add(listener)\n return () => listeners.delete(listener)\n}\n\nfunction emit() {\n listeners.forEach((l) => l())\n}\n\nconst top = (): Entry | undefined => entries[entries.length - 1]\n\n/**\n * Registers the document a viewer shows as the open document while the caller is mounted and\n * `documentId` is set. Pass `savedDocumentIdFor(...)`, or the id of a document known to be saved.\n */\nexport function useRegisterOpenDocument(registration: OpenDocumentRegistration): void {\n const latest = useRef(registration)\n useEffect(() => {\n latest.current = registration\n })\n const { documentId } = registration\n useEffect(() => {\n if (!documentId) return\n const entry: Entry = { documentId, current: () => latest.current }\n entries = [...entries, entry]\n emit()\n return () => {\n entries = entries.filter((e) => e !== entry)\n emit()\n }\n }, [documentId])\n}\n\n/** The open document's id, or null. Re-renders when another document opens or it closes. */\nexport function useOpenDocumentId(): string | null {\n return useSyncExternalStore(\n subscribe,\n () => top()?.documentId ?? null,\n () => null\n )\n}\n\n/**\n * The document an assistant turn about to be sent drafts in, or null. Call it once per turn as the\n * question is sent: when an earlier version of the document is on screen, the viewer returns to the\n * live document, where the assistant's edits appear. With `workspaceId`, a document registered in\n * another workspace is not named (and its viewer is left alone).\n */\nexport function takeOpenDocumentForTurn(options?: { workspaceId?: string | null }): string | null {\n const entry = top()\n if (!entry) return null\n const { shownId, showLive, workspaceId } = entry.current()\n if (options?.workspaceId && workspaceId && options.workspaceId !== workspaceId) return null\n if (\n shownId &&\n shownId !== entry.documentId &&\n parseVersionRef(shownId).docId === entry.documentId\n )\n showLive?.()\n return entry.documentId\n}\n"]}
@@ -1,7 +1,7 @@
1
1
  "use client";
2
2
  'use strict';
3
3
 
4
- var chunkOB5F4577_cjs = require('./chunk-OB5F4577.cjs');
4
+ var chunkR26BK7YL_cjs = require('./chunk-R26BK7YL.cjs');
5
5
  var chunkB6MVQCXW_cjs = require('./chunk-B6MVQCXW.cjs');
6
6
  var chunkMHVNT4J3_cjs = require('./chunk-MHVNT4J3.cjs');
7
7
  var react = require('react');
@@ -339,7 +339,7 @@ function SidebarNavItem({
339
339
  const tip = expanded ? void 0 : tooltip ?? label;
340
340
  if (!expanded) {
341
341
  const railButton = /* @__PURE__ */ jsxRuntime.jsx(
342
- chunkOB5F4577_cjs.ActionLink,
342
+ chunkR26BK7YL_cjs.ActionLink,
343
343
  {
344
344
  href,
345
345
  onSelect,
@@ -384,7 +384,7 @@ function SidebarNavItem({
384
384
  );
385
385
  if (href && !disabled && !trailing) {
386
386
  return /* @__PURE__ */ jsxRuntime.jsxs(
387
- chunkOB5F4577_cjs.ActionLink,
387
+ chunkR26BK7YL_cjs.ActionLink,
388
388
  {
389
389
  href,
390
390
  onSelect,
@@ -415,7 +415,7 @@ function SidebarNavItem({
415
415
  className: ui.cn(rowClass, "relative"),
416
416
  children: [
417
417
  /* @__PURE__ */ jsxRuntime.jsx(
418
- chunkOB5F4577_cjs.ActionLink,
418
+ chunkR26BK7YL_cjs.ActionLink,
419
419
  {
420
420
  href,
421
421
  onSelect,
@@ -1096,7 +1096,7 @@ function MobileTabBar({
1096
1096
  className
1097
1097
  ),
1098
1098
  children: items.map((item) => /* @__PURE__ */ jsxRuntime.jsxs(
1099
- chunkOB5F4577_cjs.ActionLink,
1099
+ chunkR26BK7YL_cjs.ActionLink,
1100
1100
  {
1101
1101
  href: item.href,
1102
1102
  onSelect: item.onSelect,
@@ -1947,5 +1947,5 @@ exports.useSidebarContext = useSidebarContext;
1947
1947
  exports.useSidebarSettle = useSidebarSettle;
1948
1948
  exports.workspaceKindColor = workspaceKindColor;
1949
1949
  exports.workspaceKindMeta = workspaceKindMeta;
1950
- //# sourceMappingURL=chunk-S6BOINC4.cjs.map
1951
- //# sourceMappingURL=chunk-S6BOINC4.cjs.map
1950
+ //# sourceMappingURL=chunk-OGBXV326.cjs.map
1951
+ //# sourceMappingURL=chunk-OGBXV326.cjs.map