@arbidocs/blocks 0.5.75 → 0.5.76

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 (175) hide show
  1. package/README.md +23 -0
  2. package/dist/{ConnectedDocumentViewer-U5TQ4LFJ.js → ConnectedDocumentViewer-4LRZ5N3L.js} +6 -6
  3. package/dist/{ConnectedDocumentViewer-U5TQ4LFJ.js.map → ConnectedDocumentViewer-4LRZ5N3L.js.map} +1 -1
  4. package/dist/{ConnectedDocumentViewer-ID2RG5MF.cjs → ConnectedDocumentViewer-FREQM2ES.cjs} +7 -7
  5. package/dist/{ConnectedDocumentViewer-ID2RG5MF.cjs.map → ConnectedDocumentViewer-FREQM2ES.cjs.map} +1 -1
  6. package/dist/{ConnectedNativeDocxComparison-PBMS77ZP.js → ConnectedNativeDocxComparison-P7OJ3UVK.js} +6 -6
  7. package/dist/{ConnectedNativeDocxComparison-PBMS77ZP.js.map → ConnectedNativeDocxComparison-P7OJ3UVK.js.map} +1 -1
  8. package/dist/{ConnectedNativeDocxComparison-R4OFGVHY.cjs → ConnectedNativeDocxComparison-RQIKQM5O.cjs} +7 -7
  9. package/dist/{ConnectedNativeDocxComparison-R4OFGVHY.cjs.map → ConnectedNativeDocxComparison-RQIKQM5O.cjs.map} +1 -1
  10. package/dist/{ConnectedNativeDocxEditor-27JZI2D5.js → ConnectedNativeDocxEditor-HX3FDJ2T.js} +5 -5
  11. package/dist/{ConnectedNativeDocxEditor-27JZI2D5.js.map → ConnectedNativeDocxEditor-HX3FDJ2T.js.map} +1 -1
  12. package/dist/{ConnectedNativeDocxEditor-774XRIP3.cjs → ConnectedNativeDocxEditor-XKQV7A37.cjs} +7 -7
  13. package/dist/{ConnectedNativeDocxEditor-774XRIP3.cjs.map → ConnectedNativeDocxEditor-XKQV7A37.cjs.map} +1 -1
  14. package/dist/{ConnectedStreamedWordArtifact-7TNIQTVE.cjs → ConnectedStreamedWordArtifact-CSRL4SCO.cjs} +7 -7
  15. package/dist/ConnectedStreamedWordArtifact-CSRL4SCO.cjs.map +1 -0
  16. package/dist/{ConnectedStreamedWordArtifact-XEFXYMKS.js → ConnectedStreamedWordArtifact-SSH6M5LN.js} +6 -6
  17. package/dist/ConnectedStreamedWordArtifact-SSH6M5LN.js.map +1 -0
  18. package/dist/{DocumentReviewCard-7OPL6PWG.cjs → DocumentReviewCard-3PZJPVQC.cjs} +14 -14
  19. package/dist/{DocumentReviewCard-7OPL6PWG.cjs.map → DocumentReviewCard-3PZJPVQC.cjs.map} +1 -1
  20. package/dist/{DocumentReviewCard-NDHCFYYT.js → DocumentReviewCard-KHMHG7A5.js} +9 -9
  21. package/dist/{DocumentReviewCard-NDHCFYYT.js.map → DocumentReviewCard-KHMHG7A5.js.map} +1 -1
  22. package/dist/{WorkspaceTableView-4INHJ7QK.js → WorkspaceTableView-4VMCTOFT.js} +5 -5
  23. package/dist/{WorkspaceTableView-4INHJ7QK.js.map → WorkspaceTableView-4VMCTOFT.js.map} +1 -1
  24. package/dist/{WorkspaceTableView-BTUSU3N3.cjs → WorkspaceTableView-Q44KNO3Z.cjs} +7 -7
  25. package/dist/{WorkspaceTableView-BTUSU3N3.cjs.map → WorkspaceTableView-Q44KNO3Z.cjs.map} +1 -1
  26. package/dist/agents/index.cjs +281 -281
  27. package/dist/agents/index.js +4 -4
  28. package/dist/{chunk-E3ILJRG4.cjs → chunk-2HECOUXC.cjs} +4 -3
  29. package/dist/chunk-2HECOUXC.cjs.map +1 -0
  30. package/dist/{chunk-AQPZ4QMV.cjs → chunk-3J2ASIM7.cjs} +3 -3
  31. package/dist/chunk-3J2ASIM7.cjs.map +1 -0
  32. package/dist/{chunk-QCFNPQWS.cjs → chunk-3LJUTIS6.cjs} +44 -44
  33. package/dist/{chunk-QCFNPQWS.cjs.map → chunk-3LJUTIS6.cjs.map} +1 -1
  34. package/dist/chunk-4B6HYQTW.cjs +20 -0
  35. package/dist/chunk-4B6HYQTW.cjs.map +1 -0
  36. package/dist/{chunk-4UMVAJJZ.js → chunk-6NEBHZIF.js} +4 -4
  37. package/dist/{chunk-4UMVAJJZ.js.map → chunk-6NEBHZIF.js.map} +1 -1
  38. package/dist/{chunk-IMIE5NOQ.js → chunk-7E5GV4R7.js} +4 -4
  39. package/dist/{chunk-IMIE5NOQ.js.map → chunk-7E5GV4R7.js.map} +1 -1
  40. package/dist/{chunk-LNXMSIKU.js → chunk-AWFEB4YJ.js} +8 -8
  41. package/dist/{chunk-LNXMSIKU.js.map → chunk-AWFEB4YJ.js.map} +1 -1
  42. package/dist/{chunk-JMQLTMJ7.js → chunk-B3BD5IJR.js} +16 -20
  43. package/dist/chunk-B3BD5IJR.js.map +1 -0
  44. package/dist/{chunk-5Q2U7GLI.cjs → chunk-CDW3W5U5.cjs} +4 -4
  45. package/dist/{chunk-5Q2U7GLI.cjs.map → chunk-CDW3W5U5.cjs.map} +1 -1
  46. package/dist/{chunk-SK5TP4DP.js → chunk-DBPPOJQM.js} +3 -3
  47. package/dist/{chunk-SK5TP4DP.js.map → chunk-DBPPOJQM.js.map} +1 -1
  48. package/dist/{chunk-NJ3YV3VM.cjs → chunk-DMYBHKNQ.cjs} +27 -27
  49. package/dist/{chunk-NJ3YV3VM.cjs.map → chunk-DMYBHKNQ.cjs.map} +1 -1
  50. package/dist/{chunk-563BHHHO.cjs → chunk-E6S6WHXL.cjs} +9 -9
  51. package/dist/{chunk-563BHHHO.cjs.map → chunk-E6S6WHXL.cjs.map} +1 -1
  52. package/dist/{chunk-BV34QPKE.js → chunk-EASXRDYQ.js} +3 -3
  53. package/dist/{chunk-BV34QPKE.js.map → chunk-EASXRDYQ.js.map} +1 -1
  54. package/dist/{chunk-JOFUAQTV.js → chunk-HWNVAQBX.js} +3 -3
  55. package/dist/{chunk-JOFUAQTV.js.map → chunk-HWNVAQBX.js.map} +1 -1
  56. package/dist/{chunk-PNWSEIWS.cjs → chunk-I3HK46DH.cjs} +4 -4
  57. package/dist/{chunk-PNWSEIWS.cjs.map → chunk-I3HK46DH.cjs.map} +1 -1
  58. package/dist/{chunk-GJKXYX47.js → chunk-IJ2CTMA7.js} +3 -3
  59. package/dist/{chunk-GJKXYX47.js.map → chunk-IJ2CTMA7.js.map} +1 -1
  60. package/dist/{chunk-7ZL6OVGO.cjs → chunk-IQFHOKQH.cjs} +23 -46
  61. package/dist/chunk-IQFHOKQH.cjs.map +1 -0
  62. package/dist/{chunk-7ZCM2GR2.js → chunk-IRCGXKLB.js} +3 -3
  63. package/dist/{chunk-7ZCM2GR2.js.map → chunk-IRCGXKLB.js.map} +1 -1
  64. package/dist/{chunk-G4GLDQLY.js → chunk-KG3W76BB.js} +3 -3
  65. package/dist/chunk-KG3W76BB.js.map +1 -0
  66. package/dist/{chunk-B66CICTP.cjs → chunk-KHLPBCRZ.cjs} +52 -52
  67. package/dist/{chunk-B66CICTP.cjs.map → chunk-KHLPBCRZ.cjs.map} +1 -1
  68. package/dist/{chunk-J4SEJSSV.js → chunk-KPIR4MJV.js} +6 -6
  69. package/dist/{chunk-J4SEJSSV.js.map → chunk-KPIR4MJV.js.map} +1 -1
  70. package/dist/{chunk-PA4EGGCI.js → chunk-KSHTODQZ.js} +3 -3
  71. package/dist/{chunk-PA4EGGCI.js.map → chunk-KSHTODQZ.js.map} +1 -1
  72. package/dist/{chunk-PT6D5B6L.cjs → chunk-MAUJVVFJ.cjs} +360 -410
  73. package/dist/chunk-MAUJVVFJ.cjs.map +1 -0
  74. package/dist/{chunk-MP7XCRHV.js → chunk-NRI5DKJE.js} +4 -3
  75. package/dist/chunk-NRI5DKJE.js.map +1 -0
  76. package/dist/{chunk-XXPDAENX.cjs → chunk-PGTDQBMX.cjs} +7 -7
  77. package/dist/{chunk-XXPDAENX.cjs.map → chunk-PGTDQBMX.cjs.map} +1 -1
  78. package/dist/{chunk-4JKK6S7U.cjs → chunk-S7G3A52F.cjs} +5 -5
  79. package/dist/{chunk-4JKK6S7U.cjs.map → chunk-S7G3A52F.cjs.map} +1 -1
  80. package/dist/{chunk-OUCWTKQT.js → chunk-SBFQF3BU.js} +4 -4
  81. package/dist/{chunk-OUCWTKQT.js.map → chunk-SBFQF3BU.js.map} +1 -1
  82. package/dist/{chunk-52VME6ZS.cjs → chunk-SIOBGNRY.cjs} +18 -18
  83. package/dist/{chunk-52VME6ZS.cjs.map → chunk-SIOBGNRY.cjs.map} +1 -1
  84. package/dist/chunk-SK3GBHPJ.js +15 -0
  85. package/dist/chunk-SK3GBHPJ.js.map +1 -0
  86. package/dist/{chunk-RADE22SM.cjs → chunk-T2OG3CPR.cjs} +4 -4
  87. package/dist/{chunk-RADE22SM.cjs.map → chunk-T2OG3CPR.cjs.map} +1 -1
  88. package/dist/{chunk-IGQJ6ET3.js → chunk-TWSOU6SE.js} +421 -501
  89. package/dist/chunk-TWSOU6SE.js.map +1 -0
  90. package/dist/{chunk-QRV4XYFJ.js → chunk-UCD7644N.js} +3 -3
  91. package/dist/{chunk-QRV4XYFJ.js.map → chunk-UCD7644N.js.map} +1 -1
  92. package/dist/{chunk-TQ4VGQHG.js → chunk-ULUCGL24.js} +3 -3
  93. package/dist/{chunk-TQ4VGQHG.js.map → chunk-ULUCGL24.js.map} +1 -1
  94. package/dist/{chunk-IRI6LPDX.cjs → chunk-UR4OSH2Q.cjs} +4 -4
  95. package/dist/{chunk-IRI6LPDX.cjs.map → chunk-UR4OSH2Q.cjs.map} +1 -1
  96. package/dist/{chunk-66QN6ZJR.cjs → chunk-URZAK3A3.cjs} +36 -36
  97. package/dist/{chunk-66QN6ZJR.cjs.map → chunk-URZAK3A3.cjs.map} +1 -1
  98. package/dist/{chunk-57S2PLCM.js → chunk-V2QWATXQ.js} +3 -3
  99. package/dist/{chunk-57S2PLCM.js.map → chunk-V2QWATXQ.js.map} +1 -1
  100. package/dist/{chunk-55JI2IGZ.cjs → chunk-VBLJNOVP.cjs} +4 -4
  101. package/dist/{chunk-55JI2IGZ.cjs.map → chunk-VBLJNOVP.cjs.map} +1 -1
  102. package/dist/{chunk-KFAFWPZK.cjs → chunk-VRMACPJR.cjs} +7 -7
  103. package/dist/{chunk-KFAFWPZK.cjs.map → chunk-VRMACPJR.cjs.map} +1 -1
  104. package/dist/{chunk-5Y6V7F6W.cjs → chunk-VWUNPAR2.cjs} +15 -19
  105. package/dist/chunk-VWUNPAR2.cjs.map +1 -0
  106. package/dist/{chunk-T3GTQXGP.js → chunk-W7CQ5MLR.js} +3 -3
  107. package/dist/{chunk-T3GTQXGP.js.map → chunk-W7CQ5MLR.js.map} +1 -1
  108. package/dist/{chunk-AOBNXZLS.cjs → chunk-Y3VXKSW7.cjs} +594 -674
  109. package/dist/chunk-Y3VXKSW7.cjs.map +1 -0
  110. package/dist/{chunk-RTYU6ZGO.cjs → chunk-YCABQ5W4.cjs} +4 -4
  111. package/dist/{chunk-RTYU6ZGO.cjs.map → chunk-YCABQ5W4.cjs.map} +1 -1
  112. package/dist/{chunk-EWHD3BY5.js → chunk-ZHHUEYSB.js} +25 -48
  113. package/dist/chunk-ZHHUEYSB.js.map +1 -0
  114. package/dist/{chunk-5PKIDR2Q.js → chunk-ZHJVABQ6.js} +361 -406
  115. package/dist/chunk-ZHJVABQ6.js.map +1 -0
  116. package/dist/connect/docx.cjs +11 -11
  117. package/dist/connect/docx.js +7 -7
  118. package/dist/connect/index.cjs +1448 -1367
  119. package/dist/connect/index.cjs.map +1 -1
  120. package/dist/connect/index.d.ts +2 -0
  121. package/dist/connect/index.js +545 -466
  122. package/dist/connect/index.js.map +1 -1
  123. package/dist/connect/viewer.cjs +5 -5
  124. package/dist/connect/viewer.js +4 -4
  125. package/dist/connection/account-cluster/ConnectedAccountCluster.d.ts +2 -1
  126. package/dist/connection/facts/useFactFilters.d.ts +46 -0
  127. package/dist/connection/files/fields/ConnectedTagForm.d.ts +1 -1
  128. package/dist/connection/report-problem/ReportProblemDialog.d.ts +10 -8
  129. package/dist/connection/report-problem/useReportProblem.d.ts +2 -6
  130. package/dist/connection/tags/ConnectedTagTable.d.ts +1 -1
  131. package/dist/connection/tags/ConnectedTagsPage.d.ts +3 -1
  132. package/dist/connection/tags/TagsPageSections.d.ts +5 -3
  133. package/dist/connection/tags/tagged-content.d.ts +10 -0
  134. package/dist/connection/threads/useThreadTagFilter.d.ts +10 -0
  135. package/dist/connection/tips/ConnectedTipBar.d.ts +2 -1
  136. package/dist/connection/tips/useContextualHints.d.ts +6 -1
  137. package/dist/embed/index.cjs +13 -12
  138. package/dist/embed/index.js +8 -7
  139. package/dist/facts/index.cjs +45 -45
  140. package/dist/facts/index.js +2 -2
  141. package/dist/files/index.cjs +226 -226
  142. package/dist/files/index.js +2 -2
  143. package/dist/index.cjs +423 -367
  144. package/dist/index.cjs.map +1 -1
  145. package/dist/index.js +76 -16
  146. package/dist/index.js.map +1 -1
  147. package/dist/settings/FilterChip.d.ts +2 -1
  148. package/dist/settings/TriStateFilterMenu.d.ts +1 -0
  149. package/dist/settings/index.cjs +158 -158
  150. package/dist/settings/index.js +2 -2
  151. package/dist/shell/index.cjs +14 -14
  152. package/dist/shell/index.js +1 -1
  153. package/dist/styles.css +1 -1
  154. package/dist/tags/TagDetail.d.ts +2 -2
  155. package/dist/tags/TagTable.d.ts +17 -3
  156. package/dist/tags/index.d.ts +1 -1
  157. package/dist/workflow-canvas/index.cjs +29 -29
  158. package/dist/workflow-canvas/index.js +12 -12
  159. package/node_modules/@arbidocs/coedit/package.json +1 -1
  160. package/package.json +5 -5
  161. package/dist/ConnectedStreamedWordArtifact-7TNIQTVE.cjs.map +0 -1
  162. package/dist/ConnectedStreamedWordArtifact-XEFXYMKS.js.map +0 -1
  163. package/dist/chunk-5PKIDR2Q.js.map +0 -1
  164. package/dist/chunk-5Y6V7F6W.cjs.map +0 -1
  165. package/dist/chunk-7ZL6OVGO.cjs.map +0 -1
  166. package/dist/chunk-AOBNXZLS.cjs.map +0 -1
  167. package/dist/chunk-AQPZ4QMV.cjs.map +0 -1
  168. package/dist/chunk-E3ILJRG4.cjs.map +0 -1
  169. package/dist/chunk-EWHD3BY5.js.map +0 -1
  170. package/dist/chunk-G4GLDQLY.js.map +0 -1
  171. package/dist/chunk-IGQJ6ET3.js.map +0 -1
  172. package/dist/chunk-JMQLTMJ7.js.map +0 -1
  173. package/dist/chunk-MP7XCRHV.js.map +0 -1
  174. package/dist/chunk-PT6D5B6L.cjs.map +0 -1
  175. package/dist/connection/tags/TagPlacement.d.ts +0 -16
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/tips/registry.ts","../src/tags/TagsNav.tsx","../src/components/OpenConversationButton.tsx","../src/nav/actions.ts","../src/nav/manifest.ts"],"names":["useState","text","jsxs","cn","jsx","Search","Input","X","Plus","useBlocksEnvironment","ActionLink","buttonVariants","MessagesSquare","createElement"],"mappings":"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","file":"index.cjs","sourcesContent":["/**\n * The contextual tips engine: which tips apply where, and the editable layer over them. The tips\n * themselves (their words, pages, situations and actions) are the site's content; a site hands\n * them to {@link createTipsRegistry} once and shows the result in `TipCard` / its tip bar, edits it\n * in `TipsEditorDialog`, and hides tips per user with `useDismissedTips` (`@arbidocs/react`).\n *\n * Each tip has a stable `code`. The editable layer (`TipsContent`) overrides a built-in tip's\n * message, action or page, hides it, or adds tips authored in the editor; swapping it in\n * (`setContent`) updates every subscriber without a reload.\n */\n\n/** Max length of a tip message: the bar is one line, so a tip is one short sentence. */\nexport const TIP_MAX_CHARS = 80\n/** Max length of a tip's action label, so the inline button doesn't dominate. */\nexport const TIP_CTA_LABEL_MAX_CHARS = 24\n\n/**\n * A tip's action: a label and exactly one target. `action` and `sequence` are the site's own ids\n * (what its action registry runs); `href` opens in a new window.\n */\nexport interface TipCta<Action extends string = string, Sequence extends string = string> {\n label: string\n action?: Action\n sequence?: Sequence\n href?: string\n}\n\nexport interface TipDefinition<Context extends string, State, Cta> {\n /** Stable id (e.g. a page letter and a number). */\n code: string\n context: Context\n message: string\n /** Situation predicate; omitted: always applies on its page. */\n when?: (state: State) => boolean\n cta?: Cta\n /** Higher shows first. Default 0. */\n priority?: number\n /** Using the action also hides the tip for good (a one-shot offer, now taken). */\n dismissOnCta?: boolean\n}\n\n/** The editable layer over a built-in tip: omitted fields keep the built-in's; `cta: null` drops it. */\nexport interface TipOverride<Context extends string, Cta> {\n message?: string\n cta?: Cta | null\n context?: Context\n hidden?: boolean\n}\n\n/** A tip written in the editor: no situation predicate, so it always applies on its page. */\nexport interface CustomTip<Context extends string, Cta> {\n code: string\n context: Context\n message: string\n cta?: Cta\n priority?: number\n hidden?: boolean\n}\n\n/** The whole editable layer (a site keeps it as JSON next to its tips). */\nexport interface TipsContent<Context extends string, Cta> {\n overrides: Record<string, TipOverride<Context, Cta>>\n custom: CustomTip<Context, Cta>[]\n}\n\n/** A tip as the editor lists it: its effective form, where it came from and whether it is off. */\nexport interface EditorTip<Context extends string, State, Cta> {\n tip: TipDefinition<Context, State, Cta>\n isCustom: boolean\n isHidden: boolean\n}\n\nexport interface TipsRegistryConfig<Context extends string, State, Cta> {\n tips: readonly TipDefinition<Context, State, Cta>[]\n /** The committed editable layer. */\n content: TipsContent<Context, Cta>\n /** The page whose tips show on every page. */\n everywhere: Context\n /** Where a tip can be placed, with the editor's labels (\"All pages\" first, say). */\n placements: readonly { value: Context; label: string }[]\n /** The editor's label for \"off\". Default \"Hidden (off)\". */\n hiddenLabel?: string\n}\n\nexport type TipPlacement<Context extends string> = Context | 'hidden'\n\nexport interface TipsRegistry<Context extends string, State, Cta> {\n /** Tips for a page whose situation matches, highest priority first (plus every-page tips). */\n select: (context: Context, state: State) => TipDefinition<Context, State, Cta>[]\n /** Every tip for the editor, across pages, hidden ones included. */\n editorTips: () => EditorTip<Context, State, Cta>[]\n /** The live editable layer. */\n getContent: () => TipsContent<Context, Cta>\n /** Swap the editable layer and notify subscribers (no reload). */\n setContent: (next: TipsContent<Context, Cta>) => void\n /** Follow changes to the editable layer; returns the unsubscribe. */\n subscribe: (listener: () => void) => () => void\n /** The editor's placement choices: each page, then \"off\". */\n placements: readonly { value: TipPlacement<Context>; label: string }[]\n placementLabel: (placement: TipPlacement<Context>) => string\n}\n\nexport function createTipsRegistry<Context extends string, State, Cta>(\n config: TipsRegistryConfig<Context, State, Cta>\n): TipsRegistry<Context, State, Cta> {\n const { tips, everywhere, hiddenLabel = 'Hidden (off)' } = config\n let content = config.content\n const listeners = new Set<() => void>()\n type Tip = TipDefinition<Context, State, Cta>\n\n const effective = (tip: Tip): { tip: Tip; hidden: boolean } => {\n const o = content.overrides?.[tip.code]\n if (!o) return { tip, hidden: false }\n return {\n tip: {\n ...tip,\n message: o.message ?? tip.message,\n cta: o.cta === null ? undefined : (o.cta ?? tip.cta),\n context: o.context ?? tip.context,\n },\n hidden: o.hidden === true,\n }\n }\n const custom = () => content.custom ?? []\n const applies = (tipContext: Context, context: Context) =>\n tipContext === context || tipContext === everywhere\n const placements: { value: TipPlacement<Context>; label: string }[] = [\n ...config.placements,\n { value: 'hidden', label: hiddenLabel },\n ]\n\n return {\n select: (context, state) => {\n const builtins = tips\n .map(effective)\n .filter(\n ({ tip, hidden }) =>\n !hidden && applies(tip.context, context) && (!tip.when || tip.when(state))\n )\n .map(({ tip }) => tip)\n const authored = custom().filter((t) => t.hidden !== true && applies(t.context, context))\n return [...builtins, ...(authored as Tip[])].sort(\n (a, b) => (b.priority ?? 0) - (a.priority ?? 0)\n )\n },\n editorTips: () => [\n ...tips.map((t) => {\n const e = effective(t)\n return { tip: e.tip, isCustom: false, isHidden: e.hidden }\n }),\n ...custom().map((t) => ({ tip: t as Tip, isCustom: true, isHidden: t.hidden === true })),\n ],\n getContent: () => content,\n setContent: (next) => {\n content = next\n listeners.forEach((listener) => listener())\n },\n subscribe: (listener) => {\n listeners.add(listener)\n return () => {\n listeners.delete(listener)\n }\n },\n placements,\n placementLabel: (p) => placements.find((o) => o.value === p)?.label ?? p,\n }\n}\n","/**\n * The side navigation of a Tags page: the workspace's tags grouped by kind (labels, annotations,\n * issues, people, organisations, searches), each group with its count, each tag with how much\n * carries it, and nested tags (sub-labels) under their parent. A group heading selects the whole\n * kind; a tag selects that tag. One box finds and adds: typing filters the list, and a name that is\n * not there yet is offered as a new tag (\"Create …\", or Enter). Data-free: the host passes the\n * groups and creates.\n */\n\nimport { useState, type ReactNode } from 'react'\nimport { Plus, Search, X } from 'lucide-react'\nimport { Input, cn } from '@arbidocs/react/ui'\n\nexport interface TagsNavItem {\n id: string\n name: string\n /** How many documents and facts carry it. */\n count?: number\n /** A swatch colour (any CSS colour). */\n color?: string\n /** Nested tags (e.g. sub-labels). */\n children?: TagsNavItem[]\n /** Other text the filter matches (e.g. the tag's field values). */\n keywords?: string\n}\n\nexport interface TagsNavGroup {\n id: string\n label: string\n icon?: ReactNode\n items: TagsNavItem[]\n}\n\n/** What is selected: a whole group, or one tag of it. */\nexport type TagsNavSelection = { groupId: string; itemId?: string }\n\nexport interface TagsNavLabels {\n filter: string\n clearFilter: string\n empty: string\n noMatch: string\n /** Offer to add the typed name: `{name}`. */\n create: string\n}\n\nexport const DEFAULT_TAGS_NAV_LABELS: TagsNavLabels = {\n filter: 'Find or add a tag…',\n clearFilter: 'Clear',\n empty: 'None yet',\n noMatch: 'No match',\n create: 'Create \"{name}\"',\n}\n\nexport interface TagsNavProps {\n groups: TagsNavGroup[]\n selected: TagsNavSelection | null\n onSelect: (selection: TagsNavSelection) => void\n /**\n * Add a tag by the name typed in the box when no tag has that name (any case). Absent: the box\n * only finds.\n */\n onCreate?: (name: string) => void | Promise<unknown>\n /**\n * The filter text, when the box lives elsewhere (e.g. the page header's filter): the list then\n * renders no box of its own and filters by this; `onFilterChange` hears a create clearing it.\n */\n filter?: string\n onFilterChange?: (text: string) => void\n /** Match items' `keywords` as well as their names. */\n matchKeywords?: boolean\n labels?: Partial<TagsNavLabels>\n className?: string\n testId?: string\n}\n\nconst total = (items: TagsNavItem[]): number =>\n items.reduce((n, item) => n + 1 + total(item.children ?? []), 0)\n\n/** The tag named `name` (any case) in these groups, with its group; nested ones included. */\nexport function findTagsNavItem(\n groups: TagsNavGroup[],\n name: string\n): { groupId: string; item: TagsNavItem } | undefined {\n const text = name.trim()\n if (!text) return undefined\n for (const g of groups) {\n const item = findByName(g.items, text)\n if (item) return { groupId: g.id, item }\n }\n return undefined\n}\n\n/** The item named `name` (any case), nested ones included. */\nfunction findByName(items: TagsNavItem[], name: string): TagsNavItem | undefined {\n const needle = name.toLowerCase()\n for (const item of items) {\n if (item.name.trim().toLowerCase() === needle) return item\n const nested = findByName(item.children ?? [], name)\n if (nested) return nested\n }\n return undefined\n}\n\n/** The items whose name (or keywords, or a nested item's) contains `text`, nesting kept. */\nfunction filterItems(items: TagsNavItem[], text: string, keywords = false): TagsNavItem[] {\n if (!text) return items\n const needle = text.toLowerCase()\n return items.flatMap((item) => {\n const children = filterItems(item.children ?? [], text, keywords)\n const hit =\n item.name.toLowerCase().includes(needle) ||\n (keywords && !!item.keywords?.toLowerCase().includes(needle))\n return hit || children.length ? [{ ...item, children }] : []\n })\n}\n\nexport function TagsNav({\n groups,\n selected,\n onSelect,\n onCreate,\n filter: controlledFilter,\n onFilterChange,\n matchKeywords = false,\n labels,\n className,\n testId = 'tags-nav',\n}: TagsNavProps) {\n const l = { ...DEFAULT_TAGS_NAV_LABELS, ...labels }\n const [ownFilter, setOwnFilter] = useState('')\n const hasOwnBox = controlledFilter === undefined\n const filter = hasOwnBox ? ownFilter : controlledFilter\n const setFilter = (text: string) => (hasOwnBox ? setOwnFilter(text) : onFilterChange?.(text))\n const [creating, setCreating] = useState(false)\n const text = filter.trim()\n const exact = findTagsNavItem(groups, text)\n const canCreate = !!onCreate && !!text && !exact\n const filterGroup = (items: TagsNavItem[]) => filterItems(items, text, matchKeywords)\n\n const create = async () => {\n if (!canCreate || creating) return\n setCreating(true)\n try {\n await onCreate?.(text)\n setFilter('')\n } finally {\n setCreating(false)\n }\n }\n\n const row = (groupId: string, item: TagsNavItem, depth: number): ReactNode => {\n const active = selected?.groupId === groupId && selected.itemId === item.id\n return (\n <li key={item.id}>\n <button\n type=\"button\"\n onClick={() => onSelect({ groupId, itemId: item.id })}\n aria-current={active ? 'true' : undefined}\n className={cn(\n 'flex w-full items-center gap-2 rounded-md py-1.5 pr-2 text-left text-sm transition-colors hover:bg-muted pointer-coarse:min-h-11',\n active && 'bg-primary/10 font-medium text-primary hover:bg-primary/10'\n )}\n style={{ paddingLeft: 12 + depth * 16 }}\n data-testid={`${testId}-item-${item.id}`}\n >\n {item.color && (\n <span\n className=\"size-2 shrink-0 rounded-full\"\n style={{ backgroundColor: item.color }}\n aria-hidden\n />\n )}\n <span className=\"min-w-0 flex-1 truncate\" title={item.name}>\n {item.name}\n </span>\n {item.count !== undefined && (\n <span className=\"shrink-0 text-xs tabular-nums text-muted-foreground\">\n {item.count}\n </span>\n )}\n </button>\n {!!item.children?.length && (\n <ul>{item.children.map((child) => row(groupId, child, depth + 1))}</ul>\n )}\n </li>\n )\n }\n\n return (\n <nav className={cn('flex flex-col gap-3', className)} data-testid={testId}>\n {hasOwnBox && (\n <div className=\"relative\">\n <Search className=\"pointer-events-none absolute left-2.5 top-1/2 size-4 -translate-y-1/2 text-muted-foreground\" />\n <Input\n value={filter}\n onChange={(e) => setFilter(e.target.value)}\n onKeyDown={(e) => {\n if (e.key !== 'Enter') return\n e.preventDefault()\n if (canCreate) void create()\n else if (exact?.item) onSelect({ groupId: exact.groupId, itemId: exact.item.id })\n }}\n placeholder={l.filter}\n aria-label={l.filter}\n className=\"h-8 pl-8 pr-8 text-sm\"\n data-testid={`${testId}-filter`}\n />\n {filter && (\n <button\n type=\"button\"\n onClick={() => setFilter('')}\n aria-label={l.clearFilter}\n className=\"absolute right-2 top-1/2 -translate-y-1/2 rounded p-0.5 text-muted-foreground hover:text-foreground\"\n >\n <X className=\"size-3.5\" />\n </button>\n )}\n </div>\n )}\n {canCreate && (\n <button\n type=\"button\"\n onClick={() => void create()}\n disabled={creating}\n className=\"flex w-full items-center gap-2 rounded-md px-3 py-1.5 text-left text-sm text-primary transition-colors hover:bg-muted disabled:opacity-60 pointer-coarse:min-h-11\"\n data-testid={`${testId}-create`}\n >\n <Plus className=\"size-4 shrink-0\" />\n <span className=\"min-w-0 flex-1 truncate\">{l.create.replace('{name}', text)}</span>\n </button>\n )}\n {groups.map((group) => {\n const items = filterGroup(group.items)\n if (text && !items.length) return null\n const active = selected?.groupId === group.id && !selected.itemId\n return (\n <section key={group.id} data-testid={`${testId}-group-${group.id}`}>\n <button\n type=\"button\"\n onClick={() => onSelect({ groupId: group.id })}\n aria-current={active ? 'true' : undefined}\n className={cn(\n 'flex w-full items-center gap-2 rounded-md px-2 py-1.5 text-left text-xs font-semibold uppercase tracking-wide text-muted-foreground transition-colors hover:bg-muted hover:text-foreground pointer-coarse:min-h-11',\n active && 'bg-primary/10 text-primary hover:bg-primary/10 hover:text-primary'\n )}\n data-testid={`${testId}-group-${group.id}-heading`}\n >\n {group.icon && <span className=\"shrink-0 [&_svg]:size-4\">{group.icon}</span>}\n <span className=\"flex-1\">{group.label}</span>\n <span className=\"tabular-nums\" data-testid={`${testId}-group-${group.id}-count`}>\n {total(group.items)}\n </span>\n </button>\n {items.length ? (\n <ul className=\"mt-0.5\">{items.map((item) => row(group.id, item, 0))}</ul>\n ) : (\n <p className=\"px-3 py-1 text-xs text-muted-foreground\">{l.empty}</p>\n )}\n </section>\n )\n })}\n {text && !canCreate && groups.every((g) => !filterGroup(g.items).length) && (\n <p className=\"px-2 text-sm text-muted-foreground\">{l.noMatch}</p>\n )}\n </nav>\n )\n}\n","import { MessagesSquare } from 'lucide-react'\nimport { buttonVariants, cn, type ButtonProps } from '@arbidocs/react/ui'\nimport { useBlocksEnvironment } from '../provider/environment'\nimport { ActionLink } from './ActionLink'\n\nexport interface OpenConversationButtonProps {\n /** The conversation behind an AI result; none: nothing is rendered. */\n conversationId: string | null | undefined\n /** The workspace it is in, for its link. */\n workspaceId?: string | null\n /** A message to scroll to. */\n messageId?: string\n /** Default \"Open in thread\". */\n label?: string\n variant?: ButtonProps['variant']\n size?: ButtonProps['size']\n className?: string\n testId?: string\n}\n\n/**\n * \"Open in thread\": the full conversation behind an AI result (a brief, a translation, a draft),\n * to check its sources and follow up. A real link where the host gives one (`hrefFor`), opened with\n * `openConversation`.\n */\nexport function OpenConversationButton({\n conversationId,\n workspaceId,\n messageId,\n label = 'Open in thread',\n variant = 'outline',\n size = 'sm',\n className,\n testId,\n}: OpenConversationButtonProps) {\n const { hrefFor, openConversation } = useBlocksEnvironment()\n if (!conversationId) return null\n return (\n <ActionLink\n href={hrefFor({ kind: 'conversation', conversationId, workspaceId, messageId })}\n onSelect={() =>\n openConversation(conversationId, {\n ...(messageId && { messageId }),\n ...(workspaceId && { workspaceId }),\n })\n }\n className={cn(buttonVariants({ variant, size }), className)}\n data-testid={testId}\n >\n <MessagesSquare className=\"size-3.5\" aria-hidden />\n {label}\n </ActionLink>\n )\n}\n","/** A parameter-light action, supplied by a host and usable outside React. */\nexport interface ActionDefinition<Id extends string = string> {\n id: Id\n label: string\n category: string\n /** An icon name, so the catalogue stays independent of a renderer. */\n icon: string\n keywords?: readonly string[]\n run: () => void\n}\n\n/** One catalogue for picker options, tip CTAs, palettes and validated remote dispatch. */\nexport function defineActions<Id extends string, Action extends ActionDefinition<Id>>(\n actions: Partial<Record<Id, Action>>,\n options: { scopedIds?: readonly Id[]; onUnknown?: (id: Id) => void } = {}\n) {\n const scoped = new Set<string>(options.scopedIds)\n return {\n actions,\n options: (Object.values(actions) as Action[]).map(({ id, label, category }) => ({\n value: id,\n label,\n category,\n })),\n isActionId(value: string): value is Id {\n return scoped.has(value) || Object.prototype.hasOwnProperty.call(actions, value)\n },\n run(id: Id): void {\n const action = Object.prototype.hasOwnProperty.call(actions, id) ? actions[id] : undefined\n if (action) action.run()\n else options.onUnknown?.(id)\n },\n }\n}\n","import { createElement } from 'react'\nimport type { AppNavItem, AppNavSection } from './types'\nimport type { NavItem } from '../shell/types'\n\n/**\n * A host's destinations, once: the items are also the command palette's nav contract. Resolve\n * their state and handlers for ShellSidebar or MobileTabBar without copying the catalogue.\n */\nexport function defineNavigation(sections: readonly AppNavSection[]) {\n const items = sections.flatMap((section) => section.items)\n return {\n sections,\n items,\n resolve(options: {\n beforeNavigate?: () => void\n onNavigate: (item: AppNavItem) => void\n onNavigated?: () => void\n itemProps?: (item: AppNavItem) => Partial<Omit<NavItem, 'id' | 'label' | 'onSelect'>>\n }): NavItem[] {\n return items.map((item) => ({\n id: item.id,\n label: item.label,\n icon: createElement(item.icon, { className: 'size-5' }),\n ...options.itemProps?.(item),\n onSelect: () => {\n options.beforeNavigate?.()\n options.onNavigate(item)\n options.onNavigated?.()\n },\n }))\n },\n }\n}\n"]}
1
+ {"version":3,"sources":["../src/tips/registry.ts","../src/tags/TagsNav.tsx","../src/tags/page/TagPicker.tsx","../src/components/OpenConversationButton.tsx","../src/nav/actions.ts","../src/nav/manifest.ts"],"names":["useState","text","jsxs","cn","jsx","TagEntity","Search","Input","X","Plus","tagKindNouns","Popover","PopoverTrigger","ChevronDown","PopoverContent","LabelPickerList","getEntityColor","useBlocksEnvironment","ActionLink","buttonVariants","MessagesSquare","createElement"],"mappings":"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","file":"index.cjs","sourcesContent":["/**\n * The contextual tips engine: which tips apply where, and the editable layer over them. The tips\n * themselves (their words, pages, situations and actions) are the site's content; a site hands\n * them to {@link createTipsRegistry} once and shows the result in `TipCard` / its tip bar, edits it\n * in `TipsEditorDialog`, and hides tips per user with `useDismissedTips` (`@arbidocs/react`).\n *\n * Each tip has a stable `code`. The editable layer (`TipsContent`) overrides a built-in tip's\n * message, action or page, hides it, or adds tips authored in the editor; swapping it in\n * (`setContent`) updates every subscriber without a reload.\n */\n\n/** Max length of a tip message: the bar is one line, so a tip is one short sentence. */\nexport const TIP_MAX_CHARS = 80\n/** Max length of a tip's action label, so the inline button doesn't dominate. */\nexport const TIP_CTA_LABEL_MAX_CHARS = 24\n\n/**\n * A tip's action: a label and exactly one target. `action` and `sequence` are the site's own ids\n * (what its action registry runs); `href` opens in a new window.\n */\nexport interface TipCta<Action extends string = string, Sequence extends string = string> {\n label: string\n action?: Action\n sequence?: Sequence\n href?: string\n}\n\nexport interface TipDefinition<Context extends string, State, Cta> {\n /** Stable id (e.g. a page letter and a number). */\n code: string\n context: Context\n message: string\n /** Situation predicate; omitted: always applies on its page. */\n when?: (state: State) => boolean\n cta?: Cta\n /** Higher shows first. Default 0. */\n priority?: number\n /** Using the action also hides the tip for good (a one-shot offer, now taken). */\n dismissOnCta?: boolean\n}\n\n/** The editable layer over a built-in tip: omitted fields keep the built-in's; `cta: null` drops it. */\nexport interface TipOverride<Context extends string, Cta> {\n message?: string\n cta?: Cta | null\n context?: Context\n hidden?: boolean\n}\n\n/** A tip written in the editor: no situation predicate, so it always applies on its page. */\nexport interface CustomTip<Context extends string, Cta> {\n code: string\n context: Context\n message: string\n cta?: Cta\n priority?: number\n hidden?: boolean\n}\n\n/** The whole editable layer (a site keeps it as JSON next to its tips). */\nexport interface TipsContent<Context extends string, Cta> {\n overrides: Record<string, TipOverride<Context, Cta>>\n custom: CustomTip<Context, Cta>[]\n}\n\n/** A tip as the editor lists it: its effective form, where it came from and whether it is off. */\nexport interface EditorTip<Context extends string, State, Cta> {\n tip: TipDefinition<Context, State, Cta>\n isCustom: boolean\n isHidden: boolean\n}\n\nexport interface TipsRegistryConfig<Context extends string, State, Cta> {\n tips: readonly TipDefinition<Context, State, Cta>[]\n /** The committed editable layer. */\n content: TipsContent<Context, Cta>\n /** The page whose tips show on every page. */\n everywhere: Context\n /** Where a tip can be placed, with the editor's labels (\"All pages\" first, say). */\n placements: readonly { value: Context; label: string }[]\n /** The editor's label for \"off\". Default \"Hidden (off)\". */\n hiddenLabel?: string\n}\n\nexport type TipPlacement<Context extends string> = Context | 'hidden'\n\nexport interface TipsRegistry<Context extends string, State, Cta> {\n /** Tips for a page whose situation matches, highest priority first (plus every-page tips). */\n select: (context: Context, state: State) => TipDefinition<Context, State, Cta>[]\n /** Every tip for the editor, across pages, hidden ones included. */\n editorTips: () => EditorTip<Context, State, Cta>[]\n /** The live editable layer. */\n getContent: () => TipsContent<Context, Cta>\n /** Swap the editable layer and notify subscribers (no reload). */\n setContent: (next: TipsContent<Context, Cta>) => void\n /** Follow changes to the editable layer; returns the unsubscribe. */\n subscribe: (listener: () => void) => () => void\n /** The editor's placement choices: each page, then \"off\". */\n placements: readonly { value: TipPlacement<Context>; label: string }[]\n placementLabel: (placement: TipPlacement<Context>) => string\n}\n\nexport function createTipsRegistry<Context extends string, State, Cta>(\n config: TipsRegistryConfig<Context, State, Cta>\n): TipsRegistry<Context, State, Cta> {\n const { tips, everywhere, hiddenLabel = 'Hidden (off)' } = config\n let content = config.content\n const listeners = new Set<() => void>()\n type Tip = TipDefinition<Context, State, Cta>\n\n const effective = (tip: Tip): { tip: Tip; hidden: boolean } => {\n const o = content.overrides?.[tip.code]\n if (!o) return { tip, hidden: false }\n return {\n tip: {\n ...tip,\n message: o.message ?? tip.message,\n cta: o.cta === null ? undefined : (o.cta ?? tip.cta),\n context: o.context ?? tip.context,\n },\n hidden: o.hidden === true,\n }\n }\n const custom = () => content.custom ?? []\n const applies = (tipContext: Context, context: Context) =>\n tipContext === context || tipContext === everywhere\n const placements: { value: TipPlacement<Context>; label: string }[] = [\n ...config.placements,\n { value: 'hidden', label: hiddenLabel },\n ]\n\n return {\n select: (context, state) => {\n const builtins = tips\n .map(effective)\n .filter(\n ({ tip, hidden }) =>\n !hidden && applies(tip.context, context) && (!tip.when || tip.when(state))\n )\n .map(({ tip }) => tip)\n const authored = custom().filter((t) => t.hidden !== true && applies(t.context, context))\n return [...builtins, ...(authored as Tip[])].sort(\n (a, b) => (b.priority ?? 0) - (a.priority ?? 0)\n )\n },\n editorTips: () => [\n ...tips.map((t) => {\n const e = effective(t)\n return { tip: e.tip, isCustom: false, isHidden: e.hidden }\n }),\n ...custom().map((t) => ({ tip: t as Tip, isCustom: true, isHidden: t.hidden === true })),\n ],\n getContent: () => content,\n setContent: (next) => {\n content = next\n listeners.forEach((listener) => listener())\n },\n subscribe: (listener) => {\n listeners.add(listener)\n return () => {\n listeners.delete(listener)\n }\n },\n placements,\n placementLabel: (p) => placements.find((o) => o.value === p)?.label ?? p,\n }\n}\n","/**\n * The side navigation of a Tags page: the workspace's tags grouped by kind (labels, annotations,\n * issues, people, organisations, searches), each group with its count, each tag with how much\n * carries it, and nested tags (sub-labels) under their parent. A group heading selects the whole\n * kind; a tag selects that tag. One box finds and adds: typing filters the list, and a name that is\n * not there yet is offered as a new tag (\"Create …\", or Enter). Data-free: the host passes the\n * groups and creates.\n */\n\nimport { useState, type ReactNode } from 'react'\nimport { Plus, Search, X } from 'lucide-react'\nimport { Input, TagEntity, cn } from '@arbidocs/react/ui'\n\nexport interface TagsNavItem {\n id: string\n name: string\n /** How many documents and facts carry it. */\n count?: number\n /** A swatch colour (any CSS colour). */\n color?: string\n /** Nested tags (e.g. sub-labels). */\n children?: TagsNavItem[]\n /** Other text the filter matches (e.g. the tag's field values). */\n keywords?: string\n}\n\nexport interface TagsNavGroup {\n id: string\n label: string\n icon?: ReactNode\n items: TagsNavItem[]\n}\n\n/** What is selected: a whole group, or one tag of it. */\nexport type TagsNavSelection = { groupId: string; itemId?: string }\n\nexport interface TagsNavLabels {\n filter: string\n clearFilter: string\n empty: string\n noMatch: string\n /** Offer to add the typed name: `{name}`. */\n create: string\n}\n\nexport const DEFAULT_TAGS_NAV_LABELS: TagsNavLabels = {\n filter: 'Find or add a tag…',\n clearFilter: 'Clear',\n empty: 'None yet',\n noMatch: 'No match',\n create: 'Create \"{name}\"',\n}\n\nexport interface TagsNavProps {\n groups: TagsNavGroup[]\n selected: TagsNavSelection | null\n onSelect: (selection: TagsNavSelection) => void\n /**\n * Add a tag by the name typed in the box when no tag has that name (any case). Absent: the box\n * only finds.\n */\n onCreate?: (name: string) => void | Promise<unknown>\n /**\n * The filter text, when the box lives elsewhere (e.g. the page header's filter): the list then\n * renders no box of its own and filters by this; `onFilterChange` hears a create clearing it.\n */\n filter?: string\n onFilterChange?: (text: string) => void\n /** Match items' `keywords` as well as their names. */\n matchKeywords?: boolean\n labels?: Partial<TagsNavLabels>\n className?: string\n testId?: string\n}\n\nconst total = (items: TagsNavItem[]): number =>\n items.reduce((n, item) => n + 1 + total(item.children ?? []), 0)\n\n/** The tag named `name` (any case) in these groups, with its group; nested ones included. */\nexport function findTagsNavItem(\n groups: TagsNavGroup[],\n name: string\n): { groupId: string; item: TagsNavItem } | undefined {\n const text = name.trim()\n if (!text) return undefined\n for (const g of groups) {\n const item = findByName(g.items, text)\n if (item) return { groupId: g.id, item }\n }\n return undefined\n}\n\n/** The item named `name` (any case), nested ones included. */\nfunction findByName(items: TagsNavItem[], name: string): TagsNavItem | undefined {\n const needle = name.toLowerCase()\n for (const item of items) {\n if (item.name.trim().toLowerCase() === needle) return item\n const nested = findByName(item.children ?? [], name)\n if (nested) return nested\n }\n return undefined\n}\n\n/** The items whose name (or keywords, or a nested item's) contains `text`, nesting kept. */\nfunction filterItems(items: TagsNavItem[], text: string, keywords = false): TagsNavItem[] {\n if (!text) return items\n const needle = text.toLowerCase()\n return items.flatMap((item) => {\n const children = filterItems(item.children ?? [], text, keywords)\n const hit =\n item.name.toLowerCase().includes(needle) ||\n (keywords && !!item.keywords?.toLowerCase().includes(needle))\n return hit || children.length ? [{ ...item, children }] : []\n })\n}\n\nexport function TagsNav({\n groups,\n selected,\n onSelect,\n onCreate,\n filter: controlledFilter,\n onFilterChange,\n matchKeywords = false,\n labels,\n className,\n testId = 'tags-nav',\n}: TagsNavProps) {\n const l = { ...DEFAULT_TAGS_NAV_LABELS, ...labels }\n const [ownFilter, setOwnFilter] = useState('')\n const hasOwnBox = controlledFilter === undefined\n const filter = hasOwnBox ? ownFilter : controlledFilter\n const setFilter = (text: string) => (hasOwnBox ? setOwnFilter(text) : onFilterChange?.(text))\n const [creating, setCreating] = useState(false)\n const text = filter.trim()\n const exact = findTagsNavItem(groups, text)\n const canCreate = !!onCreate && !!text && !exact\n const filterGroup = (items: TagsNavItem[]) => filterItems(items, text, matchKeywords)\n\n const create = async () => {\n if (!canCreate || creating) return\n setCreating(true)\n try {\n await onCreate?.(text)\n setFilter('')\n } finally {\n setCreating(false)\n }\n }\n\n const row = (groupId: string, item: TagsNavItem, depth: number): ReactNode => {\n const active = selected?.groupId === groupId && selected.itemId === item.id\n return (\n <li key={item.id}>\n <button\n type=\"button\"\n onClick={() => onSelect({ groupId, itemId: item.id })}\n aria-current={active ? 'true' : undefined}\n className={cn(\n 'flex w-full items-center gap-2 rounded-md py-1.5 pr-2 text-left text-sm transition-colors hover:bg-muted pointer-coarse:min-h-11',\n active && 'bg-primary/10 font-medium text-primary hover:bg-primary/10'\n )}\n style={{ paddingLeft: 12 + depth * 16 }}\n data-testid={`${testId}-item-${item.id}`}\n >\n <TagEntity\n tag={{ external_id: item.id, name: item.name, color: item.color }}\n showTooltip={false}\n />\n {item.count !== undefined && (\n <span className=\"shrink-0 text-xs tabular-nums text-muted-foreground\">\n {item.count}\n </span>\n )}\n </button>\n {!!item.children?.length && (\n <ul>{item.children.map((child) => row(groupId, child, depth + 1))}</ul>\n )}\n </li>\n )\n }\n\n return (\n <nav className={cn('flex flex-col gap-3', className)} data-testid={testId}>\n {hasOwnBox && (\n <div className=\"relative\">\n <Search className=\"pointer-events-none absolute left-2.5 top-1/2 size-4 -translate-y-1/2 text-muted-foreground\" />\n <Input\n value={filter}\n onChange={(e) => setFilter(e.target.value)}\n onKeyDown={(e) => {\n if (e.key !== 'Enter') return\n e.preventDefault()\n if (canCreate) void create()\n else if (exact?.item) onSelect({ groupId: exact.groupId, itemId: exact.item.id })\n }}\n placeholder={l.filter}\n aria-label={l.filter}\n className=\"h-8 pl-8 pr-8 text-sm\"\n data-testid={`${testId}-filter`}\n />\n {filter && (\n <button\n type=\"button\"\n onClick={() => setFilter('')}\n aria-label={l.clearFilter}\n className=\"absolute right-2 top-1/2 -translate-y-1/2 rounded p-0.5 text-muted-foreground hover:text-foreground\"\n >\n <X className=\"size-3.5\" />\n </button>\n )}\n </div>\n )}\n {canCreate && (\n <button\n type=\"button\"\n onClick={() => void create()}\n disabled={creating}\n className=\"flex w-full items-center gap-2 rounded-md px-3 py-1.5 text-left text-sm text-primary transition-colors hover:bg-muted disabled:opacity-60 pointer-coarse:min-h-11\"\n data-testid={`${testId}-create`}\n >\n <Plus className=\"size-4 shrink-0\" />\n <span className=\"min-w-0 flex-1 truncate\">{l.create.replace('{name}', text)}</span>\n </button>\n )}\n {groups.map((group) => {\n const items = filterGroup(group.items)\n if (text && !items.length) return null\n const active = selected?.groupId === group.id && !selected.itemId\n return (\n <section key={group.id} data-testid={`${testId}-group-${group.id}`}>\n <button\n type=\"button\"\n onClick={() => onSelect({ groupId: group.id })}\n aria-current={active ? 'true' : undefined}\n className={cn(\n 'flex w-full items-center gap-2 rounded-md px-2 py-1.5 text-left text-xs font-semibold uppercase tracking-wide text-muted-foreground transition-colors hover:bg-muted hover:text-foreground pointer-coarse:min-h-11',\n active && 'bg-primary/10 text-primary hover:bg-primary/10 hover:text-primary'\n )}\n data-testid={`${testId}-group-${group.id}-heading`}\n >\n {group.icon && <span className=\"shrink-0 [&_svg]:size-4\">{group.icon}</span>}\n <span className=\"flex-1\">{group.label}</span>\n <span className=\"tabular-nums\" data-testid={`${testId}-group-${group.id}-count`}>\n {total(group.items)}\n </span>\n </button>\n {items.length ? (\n <ul className=\"mt-0.5\">{items.map((item) => row(group.id, item, 0))}</ul>\n ) : (\n <p className=\"px-3 py-1 text-xs text-muted-foreground\">{l.empty}</p>\n )}\n </section>\n )\n })}\n {text && !canCreate && groups.every((g) => !filterGroup(g.items).length) && (\n <p className=\"px-2 text-sm text-muted-foreground\">{l.noMatch}</p>\n )}\n </nav>\n )\n}\n","/**\n * The Tags page's search-and-create picker: find a tag of the open kind and open it, or type a new\n * name and create it (\"Create …\", one per kind the view shows, or Enter for the first), then open\n * it. It is the label picker list (`LabelPickerList`, the Files labels cell and field's\n * search-or-create) in a popover; the tag on screen is the one ticked.\n */\nimport { useState } from 'react'\nimport { ChevronDown, Search } from 'lucide-react'\nimport type { TagKind } from '@arbidocs/sdk/browser'\nimport {\n TagEntity,\n Popover,\n PopoverContent,\n PopoverTrigger,\n getEntityColor,\n tagKindNouns,\n} from '@arbidocs/react/ui'\nimport { LabelPickerList } from '../../files/cells/LabelMultiSelect'\n\nexport interface TagPickerProps {\n /** The tags it offers (the open kind's). */\n tags: ReadonlyArray<{ external_id: string; name: string }>\n /** The tag on screen, if any. */\n selectedId?: string\n /** The kinds a new tag can be created as, the first by default (what the placeholder names). */\n kinds: readonly TagKind[]\n onSelect: (tagId: string) => void\n /** Create a tag of this kind by this name (and open it). Absent: the picker only finds. */\n onCreate?: (name: string, kind: TagKind) => void | Promise<unknown>\n}\n\nexport function TagPicker({ tags, selectedId, kinds, onSelect, onCreate }: TagPickerProps) {\n const [open, setOpen] = useState(false)\n const [kind, ...otherKinds] = kinds\n const noun = tagKindNouns(kind)\n const create = (name: string, as: TagKind) => {\n setOpen(false)\n void onCreate?.(name, as)\n }\n const selected = tags.find((t) => t.external_id === selectedId)\n const placeholder = onCreate ? `Find or create a ${noun.singular}…` : `Find a ${noun.singular}…`\n return (\n <Popover open={open} onOpenChange={setOpen}>\n <PopoverTrigger asChild>\n <button\n type=\"button\"\n className=\"flex h-9 w-72 max-w-full items-center gap-2 rounded-md border border-input bg-background px-3 text-left text-sm hover:bg-muted/40 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring\"\n data-testid=\"tags-picker\"\n >\n <Search className=\"size-4 shrink-0 text-muted-foreground\" />\n <span className={selected ? 'min-w-0 flex-1 truncate' : 'flex-1 text-muted-foreground'}>\n {selected ? <TagEntity tag={selected} showTooltip={false} size=\"sm\" /> : placeholder}\n </span>\n <ChevronDown className=\"size-4 shrink-0 text-muted-foreground\" />\n </button>\n </PopoverTrigger>\n {open && (\n <PopoverContent\n className=\"w-[var(--radix-popover-trigger-width)] min-w-72 p-0\"\n align=\"start\"\n sideOffset={4}\n data-testid=\"tags-picker-list\"\n >\n <LabelPickerList\n options={tags.map((t) => ({\n id: t.external_id,\n name: t.name,\n color: getEntityColor(t.external_id, 'medium'),\n }))}\n appliedIds={new Set(selectedId ? [selectedId] : [])}\n onToggle={(id) => {\n setOpen(false)\n onSelect(id)\n }}\n onCreate={onCreate ? (name) => create(name, kind) : undefined}\n moreCreates={\n onCreate\n ? otherKinds.map((other) => ({\n label: (name: string) => `Create ${tagKindNouns(other).singular} “${name}”`,\n onCreate: (name: string) => create(name, other),\n }))\n : undefined\n }\n labels={{\n searchPlaceholder: placeholder,\n noLabels: `No ${noun.plural} yet`,\n create: (name) => `Create ${noun.singular} “${name}”`,\n }}\n />\n </PopoverContent>\n )}\n </Popover>\n )\n}\n","import { MessagesSquare } from 'lucide-react'\nimport { buttonVariants, cn, type ButtonProps } from '@arbidocs/react/ui'\nimport { useBlocksEnvironment } from '../provider/environment'\nimport { ActionLink } from './ActionLink'\n\nexport interface OpenConversationButtonProps {\n /** The conversation behind an AI result; none: nothing is rendered. */\n conversationId: string | null | undefined\n /** The workspace it is in, for its link. */\n workspaceId?: string | null\n /** A message to scroll to. */\n messageId?: string\n /** Default \"Open in thread\". */\n label?: string\n variant?: ButtonProps['variant']\n size?: ButtonProps['size']\n className?: string\n testId?: string\n}\n\n/**\n * \"Open in thread\": the full conversation behind an AI result (a brief, a translation, a draft),\n * to check its sources and follow up. A real link where the host gives one (`hrefFor`), opened with\n * `openConversation`.\n */\nexport function OpenConversationButton({\n conversationId,\n workspaceId,\n messageId,\n label = 'Open in thread',\n variant = 'outline',\n size = 'sm',\n className,\n testId,\n}: OpenConversationButtonProps) {\n const { hrefFor, openConversation } = useBlocksEnvironment()\n if (!conversationId) return null\n return (\n <ActionLink\n href={hrefFor({ kind: 'conversation', conversationId, workspaceId, messageId })}\n onSelect={() =>\n openConversation(conversationId, {\n ...(messageId && { messageId }),\n ...(workspaceId && { workspaceId }),\n })\n }\n className={cn(buttonVariants({ variant, size }), className)}\n data-testid={testId}\n >\n <MessagesSquare className=\"size-3.5\" aria-hidden />\n {label}\n </ActionLink>\n )\n}\n","/** A parameter-light action, supplied by a host and usable outside React. */\nexport interface ActionDefinition<Id extends string = string> {\n id: Id\n label: string\n category: string\n /** An icon name, so the catalogue stays independent of a renderer. */\n icon: string\n keywords?: readonly string[]\n run: () => void\n}\n\n/** One catalogue for picker options, tip CTAs, palettes and validated remote dispatch. */\nexport function defineActions<Id extends string, Action extends ActionDefinition<Id>>(\n actions: Partial<Record<Id, Action>>,\n options: { scopedIds?: readonly Id[]; onUnknown?: (id: Id) => void } = {}\n) {\n const scoped = new Set<string>(options.scopedIds)\n return {\n actions,\n options: (Object.values(actions) as Action[]).map(({ id, label, category }) => ({\n value: id,\n label,\n category,\n })),\n isActionId(value: string): value is Id {\n return scoped.has(value) || Object.prototype.hasOwnProperty.call(actions, value)\n },\n run(id: Id): void {\n const action = Object.prototype.hasOwnProperty.call(actions, id) ? actions[id] : undefined\n if (action) action.run()\n else options.onUnknown?.(id)\n },\n }\n}\n","import { createElement } from 'react'\nimport type { AppNavItem, AppNavSection } from './types'\nimport type { NavItem } from '../shell/types'\n\n/**\n * A host's destinations, once: the items are also the command palette's nav contract. Resolve\n * their state and handlers for ShellSidebar or MobileTabBar without copying the catalogue.\n */\nexport function defineNavigation(sections: readonly AppNavSection[]) {\n const items = sections.flatMap((section) => section.items)\n return {\n sections,\n items,\n resolve(options: {\n beforeNavigate?: () => void\n onNavigate: (item: AppNavItem) => void\n onNavigated?: () => void\n itemProps?: (item: AppNavItem) => Partial<Omit<NavItem, 'id' | 'label' | 'onSelect'>>\n }): NavItem[] {\n return items.map((item) => ({\n id: item.id,\n label: item.label,\n icon: createElement(item.icon, { className: 'size-5' }),\n ...options.itemProps?.(item),\n onSelect: () => {\n options.beforeNavigate?.()\n options.onNavigate(item)\n options.onNavigated?.()\n },\n }))\n },\n }\n}\n"]}
package/dist/index.js CHANGED
@@ -8,11 +8,12 @@ export { Highlight, splitByTerms } from './chunk-F2DUDSDM.js';
8
8
  export { AssistantToaster, ContextActionButton, ContextCheckRow, ContextPanelContent, ContextPanelFooter, ContextPanelTabs, ContextPickerList, ContextPickerRow, ContextSearchInput, ContextSelectList, ContextSelectRow, DEFAULT_LABEL_PIN_ROW_LABELS, DEFAULT_PINNED_DOC_CHIP_LABELS, LabelPinRow, PinnedDocChip, useDismissibleCard } from './chunk-MUYFOZAN.js';
9
9
  export { ContactCard, DEFAULT_CONTACT_CARD_LABELS, contactToVCard, downloadVCard, vCardFilename } from './chunk-TTS353W2.js';
10
10
  export { DEFAULT_DRAFTING_START_LABELS, DEFAULT_DRAFTING_TYPES, DraftingStart, buildDraftingPrompt } from './chunk-YMJ7CBOR.js';
11
- export { DEFAULT_GLOSSARY_LABELS, DEFAULT_TAG_COLUMNS_EDITOR_LABELS, DEFAULT_TAG_DETAIL_LABELS, DEFAULT_TAG_TABLE_DOCX_LABELS, DEFAULT_TAG_TABLE_LABELS, DEFAULT_WORKSPACE_ACTIVITY_LABELS, EXTRACT_LIMIT, EntityIdentityBar, ExtractEntitiesDialog, GridRowNavigator, IDENTITY_NAME_MAX_LENGTH, LoadingIndicator, TAG_TABLE_DOCX_LANDSCAPE_AFTER, TIPS_VISIBILITY_OVERRIDE, TagColumnsEditor, TagDetail, TagPicker, TagTable, TagTableCell, Toolbar, WELCOME_REPLAY_VIEW, WorkspaceActivityList, cellText, cellValue, documentCount, entitiesPhrase, fieldWrites, glossaryDocumentXml, glossaryDocx, glossaryEntries, glossaryFileName, glossaryMarkdown, isGap, parseCell, rowLinks, setHintsSessionOverride, startWelcomeReplay, tagDetailLabels, tagKindDescription, tagNoteLabel, tagTableDocumentXml, tagTableDocx, tagTableLabels, tagTableMarkdown, tagsPageNouns, useTipsPlacement, workspaceActivityHeadline, workspaceActivityTarget } from './chunk-5PKIDR2Q.js';
11
+ export { DEFAULT_GLOSSARY_LABELS, DEFAULT_TAG_COLUMNS_EDITOR_LABELS, DEFAULT_TAG_DETAIL_LABELS, DEFAULT_TAG_TABLE_DOCX_LABELS, DEFAULT_TAG_TABLE_LABELS, DEFAULT_WORKSPACE_ACTIVITY_LABELS, EXTRACT_LIMIT, EntityIdentityBar, ExtractEntitiesDialog, GridRowNavigator, IDENTITY_NAME_MAX_LENGTH, LoadingIndicator, TAG_TABLE_DOCX_LANDSCAPE_AFTER, TagColumnsEditor, TagDetail, TagTable, TagTableCell, Toolbar, WorkspaceActivityList, cellText, cellValue, documentCount, entitiesPhrase, fieldWrites, glossaryDocumentXml, glossaryDocx, glossaryEntries, glossaryFileName, glossaryMarkdown, isGap, parseCell, rowLinks, tagDetailLabels, tagKindDescription, tagNoteLabel, tagTableDocumentXml, tagTableDocx, tagTableLabels, tagTableMarkdown, tagsPageNouns, useTipsPlacement, workspaceActivityHeadline, workspaceActivityTarget } from './chunk-ZHJVABQ6.js';
12
12
  export { ThemeEditor, ThemePreview } from './chunk-TOE3LBYG.js';
13
13
  export { CONTRAST_PAIRS, DEFAULT_THEME_PREVIEW_LABELS, THEME_STYLE_ID, Tabs, applyFontVars, applyThemeVars, clearFontVars, clearThemeVars, contrastIssues, contrastRatio, deriveColors, ensureContrast, inferInputs, themeCssVars, themeMetaVars, toHslTriplet } from './chunk-J77BACGX.js';
14
14
  export { DEFAULT_THREAD_FOLLOW_LABELS, DEFAULT_WORKSPACE_NOTIFICATION_MENU_LABELS, ThreadFollowButton, ThreadFollowMenuItem, WorkspaceNotificationMenu } from './chunk-66NMPTOH.js';
15
15
  export { MemberAvatarStack } from './chunk-FUPAGAZB.js';
16
+ export { TIPS_VISIBILITY_OVERRIDE, WELCOME_REPLAY_VIEW, setHintsSessionOverride, startWelcomeReplay } from './chunk-SK3GBHPJ.js';
16
17
  export { EntityTooltip, EntityTooltipHeader, EntityTooltipHint, EntityTooltipSection, EntityTooltipStats } from './chunk-3UIJLUXN.js';
17
18
  export { SharedCell } from './chunk-7RITEVXA.js';
18
19
  export { TIMELINE_ZOOM, TimelineCalendar, TimelineGantt, TimelineZoomControl, dayKey, formatSpan, monthLabel, parseIso, utcDay } from './chunk-4EZVCGRL.js';
@@ -37,8 +38,9 @@ export { AccountDeletionBanner, AskField, AskRow, AskTrigger, DEFAULT_ACCOUNT_DE
37
38
  export { Banner } from './chunk-IRPDQJNT.js';
38
39
  export { DEFAULT_DOCK_WIDTH, STATUS_ROW_BASE_CLASS, STATUS_ROW_TONES, Toaster } from './chunk-SUVMOGTC.js';
39
40
  export { DEFAULT_ERROR_BOUNDARY_LABELS, ErrorBoundary } from './chunk-3EWS6ECM.js';
40
- export { RowNavigatorControls } from './chunk-JMQLTMJ7.js';
41
- export { ActionCluster, DEFAULT_TIP_CARD_LABELS, DockZone, PanelModeSwitcher, PanelPortal, PanelWindowManager, TipCard, createPanelWindowManager, resolveSidebarLayout, useCloseOnEscape, usePanelHostSupport, useSidebarController, useSidebarSettle } from './chunk-IMIE5NOQ.js';
41
+ import { LabelPickerList } from './chunk-B3BD5IJR.js';
42
+ export { RowNavigatorControls } from './chunk-B3BD5IJR.js';
43
+ export { ActionCluster, DEFAULT_TIP_CARD_LABELS, DockZone, PanelModeSwitcher, PanelPortal, PanelWindowManager, TipCard, createPanelWindowManager, resolveSidebarLayout, useCloseOnEscape, usePanelHostSupport, useSidebarController, useSidebarSettle } from './chunk-7E5GV4R7.js';
42
44
  export { DEFAULT_MOBILE_BARS_LABELS, DEFAULT_WORKSPACE_KIND_LABELS, DEFAULT_WORKSPACE_SWITCHER_LABELS, MobileAppBar, MobileTabBar, WorkspaceIdentity, WorkspaceSwitcher, hasUnsavedInput, installReloadPolicy, markBuildStale, prefetchChunk, requestReload, workspaceKindColor, workspaceKindMeta } from './chunk-KYLNAAYI.js';
43
45
  export { DEFAULT_SIDEBAR_LABELS, SHELL_START_INSET_VAR, Sidebar, SidebarBadgeRow, SidebarRowHoverContext, useShellStartInset, useSidebarContext } from './chunk-YUAPBWLL.js';
44
46
  export { DOC_ID_IN_HREF, rehypeDocEntityPills, workspaceDocIdFromHref } from './chunk-DDCMLHXF.js';
@@ -52,17 +54,17 @@ export { tid } from './chunk-AMTWY22T.js';
52
54
  export { PageHeader } from './chunk-XCVLUXFP.js';
53
55
  export { Chart } from './chunk-WKYKDTNM.js';
54
56
  export { DEFAULT_DETAIL_PANEL_LABELS, DetailBody, DetailEmpty, DetailField, DetailFields, DetailLinkItem, DetailLinkList, DetailLoading, DetailPanel, DetailSection } from './chunk-ZCOVDK2E.js';
55
- export { DEFAULT_SKILL_CARD_LABELS, DEFAULT_SKILL_ROW_LABELS, SkillCard, SkillRow, useWorkflowPreview } from './chunk-T3GTQXGP.js';
56
- export { ANNOTATE, ANNOTATE_ID, ActionStepBody, AgentAvatarField, AgentBar, AgentBarIconButton, AgentBarMenu, AgentBarNotes, AgentBarProbeAnswer, AgentBarQueuedNote, AgentBarStatus, AgentCard, AgentConnectInstructions, AgentCreateView, AgentCreatedView, AgentCreator, AgentEditView, AgentGallery, AgentMainView, AgentTypeSelector, ApprovalEvidence, AssigneeLine, BUILTIN_SKILLS, CHRONOLOGY, CHRONOLOGY_ID, CUSTOM_TASK, CUSTOM_TASK_ID, CapabilityGrid, CapabilityTile, ConfigField, ConfigForm, ConsentActions, ConsentBulletList, ConsentCard, ConsentFootnote, ConsentHeader, ConsentMessage, ConsentNotice, ConsentPage, ConsentPermissionList, ConsentSection, ConsentStrong, ConsentText, ConversationListView, ConversationTurnSpeaker, CopyableUrl, DASHBOARD_OPERATIONS, DASHBOARD_PINNED, DEEP_RESEARCH, DEEP_RESEARCH_ID, DEFAULT_AGENT_AVATAR_FIELD_LABELS, DEFAULT_AGENT_BAR_LABELS, DEFAULT_AGENT_CAPABILITIES, DEFAULT_AGENT_CARD_LABELS, DEFAULT_AGENT_CREATOR_LABELS, DEFAULT_AGENT_GALLERY_LABELS, DEFAULT_AGENT_TEMPLATES, DEFAULT_AGENT_TYPES, DEFAULT_AGENT_TYPE_SELECTOR_LABELS, DEFAULT_AUTHORIZE_AGENT_LABELS, DEFAULT_CONFIG_FIELD_LABELS, DEFAULT_CONFIG_FORM_LABELS, DEFAULT_CONSENT_ACTIONS_LABELS, DEFAULT_COPYABLE_URL_LABELS, DEFAULT_NEW_THREAD_DIALOG_LABELS, DEFAULT_PILL_SELECT_LABELS, DEFAULT_RECURRENCE_BUILDER_LABELS, DEFAULT_SKILL_EDIT_FORM_LABELS, DEFAULT_SKILL_GENERATE_FORM_LABELS, DEFAULT_SKILL_GLOBAL_BADGE_LABELS, DEFAULT_SKILL_VIEW_TOGGLE_LABELS, DEFAULT_STEP_BAR_LABELS, DEFAULT_TASKS_CHROME_LABELS, DEFAULT_TASK_ACTIVITY_LABELS, DEFAULT_TASK_COMPOSER_LABELS, DEFAULT_TASK_LIST_LABELS, DEFAULT_TASK_OUTPUTS_CELL_LABELS, DEFAULT_TASK_PLAN_LABELS, DEFAULT_TASK_RUNS_DIALOG_LABELS, DEFAULT_TASK_STATUS_PILL_LABELS, DEFAULT_TASK_THREAD_CHIP_LABELS, DEFAULT_THREAD_LAUNCHER_LABELS, DEFAULT_THREAD_STATE_LABELS, DEFAULT_TUPLE_ARRAY_FIELD_LABELS, DEFAULT_UPLOAD_TASK_ITEM_LABELS, DEFAULT_UPLOAD_TASK_LIST_LABELS, DEFAULT_WORKFLOWS_CHROME_LABELS, DEFAULT_WORKFLOW_RUNNER_LABELS, DEFAULT_WORKFLOW_RUN_STATUS_LABELS, DEFAULT_WORKFLOW_STEP_PARTS_LABELS, DEFAULT_WORKFLOW_THREAD_STRIP_LABELS, DERIVED_NAME_WORDS, EMPTY_NEW_THREAD, GENERATE_IMAGE, GENERATE_IMAGE_ID, IMAGE_ASPECT_AUTO, IMAGE_ASPECT_RATIOS, MAX_TASK_DEPTH, NewThreadDialog, PillSelect, REMIND_TASK, REMIND_TASK_ID, RecurrenceBuilder, SKILL_FIELD_TYPE_LABELS, SKILL_MAIN_FILENAME, SKILL_SOURCE_LABELS, SKILL_TYPES, SKILL_TYPE_LABELS, STATUS_LABELS, STATUS_ORDER, STATUS_TONE, SUMMARISE, SUMMARISE_ID, SendBackControl, SkillActionButton, SkillDetail, SkillDetailSection, SkillEditForm, SkillFilterChips, SkillGenerateForm, SkillGlobalBadge, SkillLibraryDetail, SkillTile, SkillTypeBadge, SkillViewToggle, TASK_COLUMN_ORDER, TIMELINE, TIMELINE_ID, TIMELINE_PROMPT, TRANSLATE, TRANSLATE_ID, TRANSLATE_LANGUAGES, TRIGGER_LABELS, TaskActivityDialog, TaskActivityTimeline, TaskComposer, TaskEmptyState, TaskMoveDialog, TaskOutputsCell, TaskPlan, TaskRunsDialog, TaskStartDialog, TaskStatusPill, TaskTable, TaskThreadChip, TasksToolbar, ThreadLauncher, ThreadNotifyDialog, ThreadStatusLine, TupleArrayField, UploadTaskItem, UploadTaskList, WEB_WORKFLOWS, WORD_ASK, WORD_ASK_ID, WORD_CONTINUE, WORD_CONTINUE_ID, WORD_SUMMARISE, WORD_SUMMARISE_ID, WORD_SUPPORT, WORD_SUPPORT_ID, WORD_WORKFLOWS, WORKFLOW_REGISTRY, WorkflowRunStatus, WorkflowRunner, WorkflowStepAction, WorkflowThreadStartedBy, WorkflowThreadStrip, WorkflowsToolbar, activeStepId, agentConfigSectionToValues, agentCreatorToConfigSection, asTaskStatus, authModeFor, buildLibrarySkills, buildTaskRows, buildZipSkillImport, closeWorkflowLaunch, composePersona, composerToTaskQuery, composerToWorkRequest, composerToWorkflowRequest, composerToWorkflowUpdate, createTaskColumns, createsWork, defaultScopeRenderer, defaultTaskComposerValues, deriveAgentName, deriveAnnotationName, deriveWorkflowName, descendantIds, filterConversationRows, filterLibrarySkills, firstWords, formatElapsed, goalProgress, groupAgentTasks, groupThreadActivity, hasTaskFields, humanizeSection, importMarkdownSkill, importSkillFile, importSkillFromUrl, indexTasks, inferType, inputDocumentIds, isAgenticWorkflow, isMainSkillFile, isOutOfBounds, isPlainTodo, isValidAgentName, isoToLocalInput, labelRef, labelRefKey, localInputToIso, matchRequiredLabels, moveTargets, newThreadToRequest, nextCriterionId, openWorkflowLaunch, ownerExtId, parseSkillFrontmatter, prettifyKey, readSkillArchive, recordWorkflowUse, renderWorkflowIcon, requiredLabelsOf, resetWorkflowUsage, resolveScopeInputs, serializeSkill, skillSlug, sortByRecentUse, stepWindow, stripPersonaPreamble, summarizeAgent, summarizeCapabilities, taskActivityHeadline, taskComposerToCreateRequest, taskComposerToUpdateRequest, taskNeedsAccess, taskToComposerValues, unresolvedLabelRefs, useWorkflowLaunchRequest, useWorkflowUsage, useWorkflowView, withLabelIds, workflowFromSkillMarkdown, workflowTaskFields, workflowToComposerValues, workflowToSkillMarkdown, workflowWhen } from './chunk-57S2PLCM.js';
57
+ export { DEFAULT_SKILL_CARD_LABELS, DEFAULT_SKILL_ROW_LABELS, SkillCard, SkillRow, useWorkflowPreview } from './chunk-W7CQ5MLR.js';
58
+ export { ANNOTATE, ANNOTATE_ID, ActionStepBody, AgentAvatarField, AgentBar, AgentBarIconButton, AgentBarMenu, AgentBarNotes, AgentBarProbeAnswer, AgentBarQueuedNote, AgentBarStatus, AgentCard, AgentConnectInstructions, AgentCreateView, AgentCreatedView, AgentCreator, AgentEditView, AgentGallery, AgentMainView, AgentTypeSelector, ApprovalEvidence, AssigneeLine, BUILTIN_SKILLS, CHRONOLOGY, CHRONOLOGY_ID, CUSTOM_TASK, CUSTOM_TASK_ID, CapabilityGrid, CapabilityTile, ConfigField, ConfigForm, ConsentActions, ConsentBulletList, ConsentCard, ConsentFootnote, ConsentHeader, ConsentMessage, ConsentNotice, ConsentPage, ConsentPermissionList, ConsentSection, ConsentStrong, ConsentText, ConversationListView, ConversationTurnSpeaker, CopyableUrl, DASHBOARD_OPERATIONS, DASHBOARD_PINNED, DEEP_RESEARCH, DEEP_RESEARCH_ID, DEFAULT_AGENT_AVATAR_FIELD_LABELS, DEFAULT_AGENT_BAR_LABELS, DEFAULT_AGENT_CAPABILITIES, DEFAULT_AGENT_CARD_LABELS, DEFAULT_AGENT_CREATOR_LABELS, DEFAULT_AGENT_GALLERY_LABELS, DEFAULT_AGENT_TEMPLATES, DEFAULT_AGENT_TYPES, DEFAULT_AGENT_TYPE_SELECTOR_LABELS, DEFAULT_AUTHORIZE_AGENT_LABELS, DEFAULT_CONFIG_FIELD_LABELS, DEFAULT_CONFIG_FORM_LABELS, DEFAULT_CONSENT_ACTIONS_LABELS, DEFAULT_COPYABLE_URL_LABELS, DEFAULT_NEW_THREAD_DIALOG_LABELS, DEFAULT_PILL_SELECT_LABELS, DEFAULT_RECURRENCE_BUILDER_LABELS, DEFAULT_SKILL_EDIT_FORM_LABELS, DEFAULT_SKILL_GENERATE_FORM_LABELS, DEFAULT_SKILL_GLOBAL_BADGE_LABELS, DEFAULT_SKILL_VIEW_TOGGLE_LABELS, DEFAULT_STEP_BAR_LABELS, DEFAULT_TASKS_CHROME_LABELS, DEFAULT_TASK_ACTIVITY_LABELS, DEFAULT_TASK_COMPOSER_LABELS, DEFAULT_TASK_LIST_LABELS, DEFAULT_TASK_OUTPUTS_CELL_LABELS, DEFAULT_TASK_PLAN_LABELS, DEFAULT_TASK_RUNS_DIALOG_LABELS, DEFAULT_TASK_STATUS_PILL_LABELS, DEFAULT_TASK_THREAD_CHIP_LABELS, DEFAULT_THREAD_LAUNCHER_LABELS, DEFAULT_THREAD_STATE_LABELS, DEFAULT_TUPLE_ARRAY_FIELD_LABELS, DEFAULT_UPLOAD_TASK_ITEM_LABELS, DEFAULT_UPLOAD_TASK_LIST_LABELS, DEFAULT_WORKFLOWS_CHROME_LABELS, DEFAULT_WORKFLOW_RUNNER_LABELS, DEFAULT_WORKFLOW_RUN_STATUS_LABELS, DEFAULT_WORKFLOW_STEP_PARTS_LABELS, DEFAULT_WORKFLOW_THREAD_STRIP_LABELS, DERIVED_NAME_WORDS, EMPTY_NEW_THREAD, GENERATE_IMAGE, GENERATE_IMAGE_ID, IMAGE_ASPECT_AUTO, IMAGE_ASPECT_RATIOS, MAX_TASK_DEPTH, NewThreadDialog, PillSelect, REMIND_TASK, REMIND_TASK_ID, RecurrenceBuilder, SKILL_FIELD_TYPE_LABELS, SKILL_MAIN_FILENAME, SKILL_SOURCE_LABELS, SKILL_TYPES, SKILL_TYPE_LABELS, STATUS_LABELS, STATUS_ORDER, STATUS_TONE, SUMMARISE, SUMMARISE_ID, SendBackControl, SkillActionButton, SkillDetail, SkillDetailSection, SkillEditForm, SkillFilterChips, SkillGenerateForm, SkillGlobalBadge, SkillLibraryDetail, SkillTile, SkillTypeBadge, SkillViewToggle, TASK_COLUMN_ORDER, TIMELINE, TIMELINE_ID, TIMELINE_PROMPT, TRANSLATE, TRANSLATE_ID, TRANSLATE_LANGUAGES, TRIGGER_LABELS, TaskActivityDialog, TaskActivityTimeline, TaskComposer, TaskEmptyState, TaskMoveDialog, TaskOutputsCell, TaskPlan, TaskRunsDialog, TaskStartDialog, TaskStatusPill, TaskTable, TaskThreadChip, TasksToolbar, ThreadLauncher, ThreadNotifyDialog, ThreadStatusLine, TupleArrayField, UploadTaskItem, UploadTaskList, WEB_WORKFLOWS, WORD_ASK, WORD_ASK_ID, WORD_CONTINUE, WORD_CONTINUE_ID, WORD_SUMMARISE, WORD_SUMMARISE_ID, WORD_SUPPORT, WORD_SUPPORT_ID, WORD_WORKFLOWS, WORKFLOW_REGISTRY, WorkflowRunStatus, WorkflowRunner, WorkflowStepAction, WorkflowThreadStartedBy, WorkflowThreadStrip, WorkflowsToolbar, activeStepId, agentConfigSectionToValues, agentCreatorToConfigSection, asTaskStatus, authModeFor, buildLibrarySkills, buildTaskRows, buildZipSkillImport, closeWorkflowLaunch, composePersona, composerToTaskQuery, composerToWorkRequest, composerToWorkflowRequest, composerToWorkflowUpdate, createTaskColumns, createsWork, defaultScopeRenderer, defaultTaskComposerValues, deriveAgentName, deriveAnnotationName, deriveWorkflowName, descendantIds, filterConversationRows, filterLibrarySkills, firstWords, formatElapsed, goalProgress, groupAgentTasks, groupThreadActivity, hasTaskFields, humanizeSection, importMarkdownSkill, importSkillFile, importSkillFromUrl, indexTasks, inferType, inputDocumentIds, isAgenticWorkflow, isMainSkillFile, isOutOfBounds, isPlainTodo, isValidAgentName, isoToLocalInput, labelRef, labelRefKey, localInputToIso, matchRequiredLabels, moveTargets, newThreadToRequest, nextCriterionId, openWorkflowLaunch, ownerExtId, parseSkillFrontmatter, prettifyKey, readSkillArchive, recordWorkflowUse, renderWorkflowIcon, requiredLabelsOf, resetWorkflowUsage, resolveScopeInputs, serializeSkill, skillSlug, sortByRecentUse, stepWindow, stripPersonaPreamble, summarizeAgent, summarizeCapabilities, taskActivityHeadline, taskComposerToCreateRequest, taskComposerToUpdateRequest, taskNeedsAccess, taskToComposerValues, unresolvedLabelRefs, useWorkflowLaunchRequest, useWorkflowUsage, useWorkflowView, withLabelIds, workflowFromSkillMarkdown, workflowTaskFields, workflowToComposerValues, workflowToSkillMarkdown, workflowWhen } from './chunk-V2QWATXQ.js';
57
59
  export { AUTOMATION_EVENTS, AssistantEntity, DEFAULT_AGENT_STEPS_LABELS, DEFAULT_RECURRENCE, DEFAULT_SUBAGENT_ROSTER_LABELS, EntityChip, GoalCriteria, MODEL_NAME_ICONS, MODEL_TIER_ICON_MAP, MODEL_TIER_LABELS, STEP_ICON_MAP, StepDetail, StepNarration, StepOutcome, StepParams, StepRow, StepSummary, StepTrace, StepTraceSummary, SubAgentLane, SubStepGroup, SubagentRoster, TAG_ICONS, TOOL_ICON_MAP, TaskFlow, ThreadActivity, WEEKDAYS, buildRRule, compactThreadActivity, describeRRule, describeTrigger, fromPlanAssignee, fromPlanDocumentRef, fromPlanSteps, getAgentStepIcon, getAgentStepPresentation, getCurrentAgentStepPresentation, getModelIcon, isIncompleteSignal, isSupersededStop, latestMessageTime, layoutFromPlanSteps, linkedRunsFromActivity, notifiedLabel, parseRRule, stepAccent, toPlanAssignee, toPlanDocumentRef, toPlanSteps, unnotifiedMentions } from './chunk-3TKRCYFN.js';
58
60
  export { ChevronShape, ProgressChevron, ProgressChevronBar } from './chunk-LRPGXNMA.js';
59
61
  import './chunk-CQCC7LE7.js';
60
62
  import './chunk-UCVGWGI6.js';
61
63
  export { DEFAULT_STEP_DOCUMENT_LABELS, DEFAULT_STEP_KIND_LABELS, DEFAULT_STEP_RECORD_LABELS, STEP_KIND_ICONS, StepDocumentButton, StepDocumentCards, StepRecord, WORKFLOW_STEP_KINDS, stepDocuments, stepKindOf, useMentionAutocomplete } from './chunk-TX6BIWIH.js';
62
- export { AgentSelect, DEFAULT_AGENT_SELECT_LABELS, DEFAULT_SCHEMA_FORM_LABELS, DEFAULT_TASK_TRIGGER_CHIP_LABELS, DEFAULT_WORKFLOW_CATALOGUE_LABELS, DEFAULT_WORKFLOW_CONFIG_DIALOG_LABELS, DEFAULT_WORKFLOW_DOCUMENTS_FIELD_LABELS, DEFAULT_WORKFLOW_LIST_LABELS, PersonPill, SchemaForm, TaskTriggerChip, WORKFLOW_COLUMN_ORDER, WorkflowCatalogueSections, WorkflowConfigDialog, WorkflowDocumentsField, WorkflowLauncher, WorkflowsTable, buildWorkflowScopeSource, createWorkflowColumns, documentScopeLabels, matchWorkflowScope } from './chunk-7ZCM2GR2.js';
64
+ export { AgentSelect, DEFAULT_AGENT_SELECT_LABELS, DEFAULT_SCHEMA_FORM_LABELS, DEFAULT_TASK_TRIGGER_CHIP_LABELS, DEFAULT_WORKFLOW_CATALOGUE_LABELS, DEFAULT_WORKFLOW_CONFIG_DIALOG_LABELS, DEFAULT_WORKFLOW_DOCUMENTS_FIELD_LABELS, DEFAULT_WORKFLOW_LIST_LABELS, PersonPill, SchemaForm, TaskTriggerChip, WORKFLOW_COLUMN_ORDER, WorkflowCatalogueSections, WorkflowConfigDialog, WorkflowDocumentsField, WorkflowLauncher, WorkflowsTable, buildWorkflowScopeSource, createWorkflowColumns, documentScopeLabels, matchWorkflowScope } from './chunk-IRCGXKLB.js';
63
65
  export { hasTrigger, isScheduledWorkflow, isSkillRow, workflowSignal, workflowStatus, workflowTriggerType } from './chunk-4QUUU7GH.js';
64
66
  import './chunk-MXF3MHYC.js';
65
- import './chunk-G4GLDQLY.js';
67
+ import './chunk-KG3W76BB.js';
66
68
  export { DEFAULT_ASSIGNEE_WORDING, EMPTY_WORKFLOW_SCOPE, SKILL_PROMPT_FALLBACK_PLACEHOLDER, SKILL_PROMPT_LABEL, assigneeName, buildLaunch, canAssign, composeStepPrompt, composeWorkflowPrompt, defaultInputs, dependsOn, fieldToFrontmatter, fillRunText, fillStepInputs, initialRunInputs, inputsFromContext, isEmptyWorkflowScope, isPersonAction, isPersonStep, isRunFinished, isSteppedWorkflow, isWorkflowScope, mergeSkillWorkflows, nextAction, orderSteps, promptFieldName, reviewInstructions, runFields, runFieldsOf, runThreadTitle, sendBackTargets, skillTitle, skillToWorkflow, splitDocRef, stepConfigProblems, stepDependencies, stepFields, stepLevels, stepPhase, stepStatesFromActivity, upstreamSteps, validateInputs, validateStep, validateWorkflowGraph, workflowAccepts, workflowFromFrontmatter, workflowSteps, workflowsAccepting, workflowsForHost } from './chunk-3D7SX5ZS.js';
67
69
  import './chunk-M4S75AEJ.js';
68
70
  export { Dot, ToneBadge } from './chunk-5LXQPP2K.js';
@@ -98,10 +100,10 @@ export { closeAllDialogs, closeDialog, getDialog, openDialog, useDialogProps } f
98
100
  import './chunk-TX2ZICS7.js';
99
101
  import './chunk-UP3GCNPM.js';
100
102
  import './chunk-VUNV25KB.js';
101
- import { Input, cn, buttonVariants } from '@arbidocs/react/ui';
103
+ import { Input, cn, tagKindNouns, Popover, PopoverTrigger, TagEntity, PopoverContent, getEntityColor, buttonVariants } from '@arbidocs/react/ui';
102
104
  export { DocumentCard, Table, TableBody, TableCell, TableHead, TableHeader, TableRow, Tooltip, TooltipContent, TooltipProvider, TooltipTrigger } from '@arbidocs/react/ui';
103
105
  import { useState, createElement } from 'react';
104
- import { Search, X, Plus, MessagesSquare } from 'lucide-react';
106
+ import { Search, X, Plus, ChevronDown, MessagesSquare } from 'lucide-react';
105
107
  import { jsxs, jsx } from 'react/jsx-runtime';
106
108
 
107
109
  // src/tips/registry.ts
@@ -245,15 +247,13 @@ function TagsNav({
245
247
  style: { paddingLeft: 12 + depth * 16 },
246
248
  "data-testid": `${testId}-item-${item.id}`,
247
249
  children: [
248
- item.color && /* @__PURE__ */ jsx(
249
- "span",
250
+ /* @__PURE__ */ jsx(
251
+ TagEntity,
250
252
  {
251
- className: "size-2 shrink-0 rounded-full",
252
- style: { backgroundColor: item.color },
253
- "aria-hidden": true
253
+ tag: { external_id: item.id, name: item.name, color: item.color },
254
+ showTooltip: false
254
255
  }
255
256
  ),
256
- /* @__PURE__ */ jsx("span", { className: "min-w-0 flex-1 truncate", title: item.name, children: item.name }),
257
257
  item.count !== void 0 && /* @__PURE__ */ jsx("span", { className: "shrink-0 text-xs tabular-nums text-muted-foreground", children: item.count })
258
258
  ]
259
259
  }
@@ -335,6 +335,66 @@ function TagsNav({
335
335
  text && !canCreate && groups.every((g) => !filterGroup(g.items).length) && /* @__PURE__ */ jsx("p", { className: "px-2 text-sm text-muted-foreground", children: l.noMatch })
336
336
  ] });
337
337
  }
338
+ function TagPicker({ tags, selectedId, kinds, onSelect, onCreate }) {
339
+ const [open, setOpen] = useState(false);
340
+ const [kind, ...otherKinds] = kinds;
341
+ const noun = tagKindNouns(kind);
342
+ const create = (name, as) => {
343
+ setOpen(false);
344
+ void onCreate?.(name, as);
345
+ };
346
+ const selected = tags.find((t) => t.external_id === selectedId);
347
+ const placeholder = onCreate ? `Find or create a ${noun.singular}\u2026` : `Find a ${noun.singular}\u2026`;
348
+ return /* @__PURE__ */ jsxs(Popover, { open, onOpenChange: setOpen, children: [
349
+ /* @__PURE__ */ jsx(PopoverTrigger, { asChild: true, children: /* @__PURE__ */ jsxs(
350
+ "button",
351
+ {
352
+ type: "button",
353
+ className: "flex h-9 w-72 max-w-full items-center gap-2 rounded-md border border-input bg-background px-3 text-left text-sm hover:bg-muted/40 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring",
354
+ "data-testid": "tags-picker",
355
+ children: [
356
+ /* @__PURE__ */ jsx(Search, { className: "size-4 shrink-0 text-muted-foreground" }),
357
+ /* @__PURE__ */ jsx("span", { className: selected ? "min-w-0 flex-1 truncate" : "flex-1 text-muted-foreground", children: selected ? /* @__PURE__ */ jsx(TagEntity, { tag: selected, showTooltip: false, size: "sm" }) : placeholder }),
358
+ /* @__PURE__ */ jsx(ChevronDown, { className: "size-4 shrink-0 text-muted-foreground" })
359
+ ]
360
+ }
361
+ ) }),
362
+ open && /* @__PURE__ */ jsx(
363
+ PopoverContent,
364
+ {
365
+ className: "w-[var(--radix-popover-trigger-width)] min-w-72 p-0",
366
+ align: "start",
367
+ sideOffset: 4,
368
+ "data-testid": "tags-picker-list",
369
+ children: /* @__PURE__ */ jsx(
370
+ LabelPickerList,
371
+ {
372
+ options: tags.map((t) => ({
373
+ id: t.external_id,
374
+ name: t.name,
375
+ color: getEntityColor(t.external_id, "medium")
376
+ })),
377
+ appliedIds: new Set(selectedId ? [selectedId] : []),
378
+ onToggle: (id) => {
379
+ setOpen(false);
380
+ onSelect(id);
381
+ },
382
+ onCreate: onCreate ? (name) => create(name, kind) : void 0,
383
+ moreCreates: onCreate ? otherKinds.map((other) => ({
384
+ label: (name) => `Create ${tagKindNouns(other).singular} \u201C${name}\u201D`,
385
+ onCreate: (name) => create(name, other)
386
+ })) : void 0,
387
+ labels: {
388
+ searchPlaceholder: placeholder,
389
+ noLabels: `No ${noun.plural} yet`,
390
+ create: (name) => `Create ${noun.singular} \u201C${name}\u201D`
391
+ }
392
+ }
393
+ )
394
+ }
395
+ )
396
+ ] });
397
+ }
338
398
  function OpenConversationButton({
339
399
  conversationId,
340
400
  workspaceId,
@@ -406,6 +466,6 @@ function defineNavigation(sections) {
406
466
  };
407
467
  }
408
468
 
409
- export { DEFAULT_TAGS_NAV_LABELS, OpenConversationButton, TIP_CTA_LABEL_MAX_CHARS, TIP_MAX_CHARS, TagsNav, createTipsRegistry, defineActions, defineNavigation, findTagsNavItem };
469
+ export { DEFAULT_TAGS_NAV_LABELS, OpenConversationButton, TIP_CTA_LABEL_MAX_CHARS, TIP_MAX_CHARS, TagPicker, TagsNav, createTipsRegistry, defineActions, defineNavigation, findTagsNavItem };
410
470
  //# sourceMappingURL=index.js.map
411
471
  //# sourceMappingURL=index.js.map
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/tips/registry.ts","../src/tags/TagsNav.tsx","../src/components/OpenConversationButton.tsx","../src/nav/actions.ts","../src/nav/manifest.ts"],"names":["text","jsxs","cn","jsx"],"mappings":"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","file":"index.js","sourcesContent":["/**\n * The contextual tips engine: which tips apply where, and the editable layer over them. The tips\n * themselves (their words, pages, situations and actions) are the site's content; a site hands\n * them to {@link createTipsRegistry} once and shows the result in `TipCard` / its tip bar, edits it\n * in `TipsEditorDialog`, and hides tips per user with `useDismissedTips` (`@arbidocs/react`).\n *\n * Each tip has a stable `code`. The editable layer (`TipsContent`) overrides a built-in tip's\n * message, action or page, hides it, or adds tips authored in the editor; swapping it in\n * (`setContent`) updates every subscriber without a reload.\n */\n\n/** Max length of a tip message: the bar is one line, so a tip is one short sentence. */\nexport const TIP_MAX_CHARS = 80\n/** Max length of a tip's action label, so the inline button doesn't dominate. */\nexport const TIP_CTA_LABEL_MAX_CHARS = 24\n\n/**\n * A tip's action: a label and exactly one target. `action` and `sequence` are the site's own ids\n * (what its action registry runs); `href` opens in a new window.\n */\nexport interface TipCta<Action extends string = string, Sequence extends string = string> {\n label: string\n action?: Action\n sequence?: Sequence\n href?: string\n}\n\nexport interface TipDefinition<Context extends string, State, Cta> {\n /** Stable id (e.g. a page letter and a number). */\n code: string\n context: Context\n message: string\n /** Situation predicate; omitted: always applies on its page. */\n when?: (state: State) => boolean\n cta?: Cta\n /** Higher shows first. Default 0. */\n priority?: number\n /** Using the action also hides the tip for good (a one-shot offer, now taken). */\n dismissOnCta?: boolean\n}\n\n/** The editable layer over a built-in tip: omitted fields keep the built-in's; `cta: null` drops it. */\nexport interface TipOverride<Context extends string, Cta> {\n message?: string\n cta?: Cta | null\n context?: Context\n hidden?: boolean\n}\n\n/** A tip written in the editor: no situation predicate, so it always applies on its page. */\nexport interface CustomTip<Context extends string, Cta> {\n code: string\n context: Context\n message: string\n cta?: Cta\n priority?: number\n hidden?: boolean\n}\n\n/** The whole editable layer (a site keeps it as JSON next to its tips). */\nexport interface TipsContent<Context extends string, Cta> {\n overrides: Record<string, TipOverride<Context, Cta>>\n custom: CustomTip<Context, Cta>[]\n}\n\n/** A tip as the editor lists it: its effective form, where it came from and whether it is off. */\nexport interface EditorTip<Context extends string, State, Cta> {\n tip: TipDefinition<Context, State, Cta>\n isCustom: boolean\n isHidden: boolean\n}\n\nexport interface TipsRegistryConfig<Context extends string, State, Cta> {\n tips: readonly TipDefinition<Context, State, Cta>[]\n /** The committed editable layer. */\n content: TipsContent<Context, Cta>\n /** The page whose tips show on every page. */\n everywhere: Context\n /** Where a tip can be placed, with the editor's labels (\"All pages\" first, say). */\n placements: readonly { value: Context; label: string }[]\n /** The editor's label for \"off\". Default \"Hidden (off)\". */\n hiddenLabel?: string\n}\n\nexport type TipPlacement<Context extends string> = Context | 'hidden'\n\nexport interface TipsRegistry<Context extends string, State, Cta> {\n /** Tips for a page whose situation matches, highest priority first (plus every-page tips). */\n select: (context: Context, state: State) => TipDefinition<Context, State, Cta>[]\n /** Every tip for the editor, across pages, hidden ones included. */\n editorTips: () => EditorTip<Context, State, Cta>[]\n /** The live editable layer. */\n getContent: () => TipsContent<Context, Cta>\n /** Swap the editable layer and notify subscribers (no reload). */\n setContent: (next: TipsContent<Context, Cta>) => void\n /** Follow changes to the editable layer; returns the unsubscribe. */\n subscribe: (listener: () => void) => () => void\n /** The editor's placement choices: each page, then \"off\". */\n placements: readonly { value: TipPlacement<Context>; label: string }[]\n placementLabel: (placement: TipPlacement<Context>) => string\n}\n\nexport function createTipsRegistry<Context extends string, State, Cta>(\n config: TipsRegistryConfig<Context, State, Cta>\n): TipsRegistry<Context, State, Cta> {\n const { tips, everywhere, hiddenLabel = 'Hidden (off)' } = config\n let content = config.content\n const listeners = new Set<() => void>()\n type Tip = TipDefinition<Context, State, Cta>\n\n const effective = (tip: Tip): { tip: Tip; hidden: boolean } => {\n const o = content.overrides?.[tip.code]\n if (!o) return { tip, hidden: false }\n return {\n tip: {\n ...tip,\n message: o.message ?? tip.message,\n cta: o.cta === null ? undefined : (o.cta ?? tip.cta),\n context: o.context ?? tip.context,\n },\n hidden: o.hidden === true,\n }\n }\n const custom = () => content.custom ?? []\n const applies = (tipContext: Context, context: Context) =>\n tipContext === context || tipContext === everywhere\n const placements: { value: TipPlacement<Context>; label: string }[] = [\n ...config.placements,\n { value: 'hidden', label: hiddenLabel },\n ]\n\n return {\n select: (context, state) => {\n const builtins = tips\n .map(effective)\n .filter(\n ({ tip, hidden }) =>\n !hidden && applies(tip.context, context) && (!tip.when || tip.when(state))\n )\n .map(({ tip }) => tip)\n const authored = custom().filter((t) => t.hidden !== true && applies(t.context, context))\n return [...builtins, ...(authored as Tip[])].sort(\n (a, b) => (b.priority ?? 0) - (a.priority ?? 0)\n )\n },\n editorTips: () => [\n ...tips.map((t) => {\n const e = effective(t)\n return { tip: e.tip, isCustom: false, isHidden: e.hidden }\n }),\n ...custom().map((t) => ({ tip: t as Tip, isCustom: true, isHidden: t.hidden === true })),\n ],\n getContent: () => content,\n setContent: (next) => {\n content = next\n listeners.forEach((listener) => listener())\n },\n subscribe: (listener) => {\n listeners.add(listener)\n return () => {\n listeners.delete(listener)\n }\n },\n placements,\n placementLabel: (p) => placements.find((o) => o.value === p)?.label ?? p,\n }\n}\n","/**\n * The side navigation of a Tags page: the workspace's tags grouped by kind (labels, annotations,\n * issues, people, organisations, searches), each group with its count, each tag with how much\n * carries it, and nested tags (sub-labels) under their parent. A group heading selects the whole\n * kind; a tag selects that tag. One box finds and adds: typing filters the list, and a name that is\n * not there yet is offered as a new tag (\"Create …\", or Enter). Data-free: the host passes the\n * groups and creates.\n */\n\nimport { useState, type ReactNode } from 'react'\nimport { Plus, Search, X } from 'lucide-react'\nimport { Input, cn } from '@arbidocs/react/ui'\n\nexport interface TagsNavItem {\n id: string\n name: string\n /** How many documents and facts carry it. */\n count?: number\n /** A swatch colour (any CSS colour). */\n color?: string\n /** Nested tags (e.g. sub-labels). */\n children?: TagsNavItem[]\n /** Other text the filter matches (e.g. the tag's field values). */\n keywords?: string\n}\n\nexport interface TagsNavGroup {\n id: string\n label: string\n icon?: ReactNode\n items: TagsNavItem[]\n}\n\n/** What is selected: a whole group, or one tag of it. */\nexport type TagsNavSelection = { groupId: string; itemId?: string }\n\nexport interface TagsNavLabels {\n filter: string\n clearFilter: string\n empty: string\n noMatch: string\n /** Offer to add the typed name: `{name}`. */\n create: string\n}\n\nexport const DEFAULT_TAGS_NAV_LABELS: TagsNavLabels = {\n filter: 'Find or add a tag…',\n clearFilter: 'Clear',\n empty: 'None yet',\n noMatch: 'No match',\n create: 'Create \"{name}\"',\n}\n\nexport interface TagsNavProps {\n groups: TagsNavGroup[]\n selected: TagsNavSelection | null\n onSelect: (selection: TagsNavSelection) => void\n /**\n * Add a tag by the name typed in the box when no tag has that name (any case). Absent: the box\n * only finds.\n */\n onCreate?: (name: string) => void | Promise<unknown>\n /**\n * The filter text, when the box lives elsewhere (e.g. the page header's filter): the list then\n * renders no box of its own and filters by this; `onFilterChange` hears a create clearing it.\n */\n filter?: string\n onFilterChange?: (text: string) => void\n /** Match items' `keywords` as well as their names. */\n matchKeywords?: boolean\n labels?: Partial<TagsNavLabels>\n className?: string\n testId?: string\n}\n\nconst total = (items: TagsNavItem[]): number =>\n items.reduce((n, item) => n + 1 + total(item.children ?? []), 0)\n\n/** The tag named `name` (any case) in these groups, with its group; nested ones included. */\nexport function findTagsNavItem(\n groups: TagsNavGroup[],\n name: string\n): { groupId: string; item: TagsNavItem } | undefined {\n const text = name.trim()\n if (!text) return undefined\n for (const g of groups) {\n const item = findByName(g.items, text)\n if (item) return { groupId: g.id, item }\n }\n return undefined\n}\n\n/** The item named `name` (any case), nested ones included. */\nfunction findByName(items: TagsNavItem[], name: string): TagsNavItem | undefined {\n const needle = name.toLowerCase()\n for (const item of items) {\n if (item.name.trim().toLowerCase() === needle) return item\n const nested = findByName(item.children ?? [], name)\n if (nested) return nested\n }\n return undefined\n}\n\n/** The items whose name (or keywords, or a nested item's) contains `text`, nesting kept. */\nfunction filterItems(items: TagsNavItem[], text: string, keywords = false): TagsNavItem[] {\n if (!text) return items\n const needle = text.toLowerCase()\n return items.flatMap((item) => {\n const children = filterItems(item.children ?? [], text, keywords)\n const hit =\n item.name.toLowerCase().includes(needle) ||\n (keywords && !!item.keywords?.toLowerCase().includes(needle))\n return hit || children.length ? [{ ...item, children }] : []\n })\n}\n\nexport function TagsNav({\n groups,\n selected,\n onSelect,\n onCreate,\n filter: controlledFilter,\n onFilterChange,\n matchKeywords = false,\n labels,\n className,\n testId = 'tags-nav',\n}: TagsNavProps) {\n const l = { ...DEFAULT_TAGS_NAV_LABELS, ...labels }\n const [ownFilter, setOwnFilter] = useState('')\n const hasOwnBox = controlledFilter === undefined\n const filter = hasOwnBox ? ownFilter : controlledFilter\n const setFilter = (text: string) => (hasOwnBox ? setOwnFilter(text) : onFilterChange?.(text))\n const [creating, setCreating] = useState(false)\n const text = filter.trim()\n const exact = findTagsNavItem(groups, text)\n const canCreate = !!onCreate && !!text && !exact\n const filterGroup = (items: TagsNavItem[]) => filterItems(items, text, matchKeywords)\n\n const create = async () => {\n if (!canCreate || creating) return\n setCreating(true)\n try {\n await onCreate?.(text)\n setFilter('')\n } finally {\n setCreating(false)\n }\n }\n\n const row = (groupId: string, item: TagsNavItem, depth: number): ReactNode => {\n const active = selected?.groupId === groupId && selected.itemId === item.id\n return (\n <li key={item.id}>\n <button\n type=\"button\"\n onClick={() => onSelect({ groupId, itemId: item.id })}\n aria-current={active ? 'true' : undefined}\n className={cn(\n 'flex w-full items-center gap-2 rounded-md py-1.5 pr-2 text-left text-sm transition-colors hover:bg-muted pointer-coarse:min-h-11',\n active && 'bg-primary/10 font-medium text-primary hover:bg-primary/10'\n )}\n style={{ paddingLeft: 12 + depth * 16 }}\n data-testid={`${testId}-item-${item.id}`}\n >\n {item.color && (\n <span\n className=\"size-2 shrink-0 rounded-full\"\n style={{ backgroundColor: item.color }}\n aria-hidden\n />\n )}\n <span className=\"min-w-0 flex-1 truncate\" title={item.name}>\n {item.name}\n </span>\n {item.count !== undefined && (\n <span className=\"shrink-0 text-xs tabular-nums text-muted-foreground\">\n {item.count}\n </span>\n )}\n </button>\n {!!item.children?.length && (\n <ul>{item.children.map((child) => row(groupId, child, depth + 1))}</ul>\n )}\n </li>\n )\n }\n\n return (\n <nav className={cn('flex flex-col gap-3', className)} data-testid={testId}>\n {hasOwnBox && (\n <div className=\"relative\">\n <Search className=\"pointer-events-none absolute left-2.5 top-1/2 size-4 -translate-y-1/2 text-muted-foreground\" />\n <Input\n value={filter}\n onChange={(e) => setFilter(e.target.value)}\n onKeyDown={(e) => {\n if (e.key !== 'Enter') return\n e.preventDefault()\n if (canCreate) void create()\n else if (exact?.item) onSelect({ groupId: exact.groupId, itemId: exact.item.id })\n }}\n placeholder={l.filter}\n aria-label={l.filter}\n className=\"h-8 pl-8 pr-8 text-sm\"\n data-testid={`${testId}-filter`}\n />\n {filter && (\n <button\n type=\"button\"\n onClick={() => setFilter('')}\n aria-label={l.clearFilter}\n className=\"absolute right-2 top-1/2 -translate-y-1/2 rounded p-0.5 text-muted-foreground hover:text-foreground\"\n >\n <X className=\"size-3.5\" />\n </button>\n )}\n </div>\n )}\n {canCreate && (\n <button\n type=\"button\"\n onClick={() => void create()}\n disabled={creating}\n className=\"flex w-full items-center gap-2 rounded-md px-3 py-1.5 text-left text-sm text-primary transition-colors hover:bg-muted disabled:opacity-60 pointer-coarse:min-h-11\"\n data-testid={`${testId}-create`}\n >\n <Plus className=\"size-4 shrink-0\" />\n <span className=\"min-w-0 flex-1 truncate\">{l.create.replace('{name}', text)}</span>\n </button>\n )}\n {groups.map((group) => {\n const items = filterGroup(group.items)\n if (text && !items.length) return null\n const active = selected?.groupId === group.id && !selected.itemId\n return (\n <section key={group.id} data-testid={`${testId}-group-${group.id}`}>\n <button\n type=\"button\"\n onClick={() => onSelect({ groupId: group.id })}\n aria-current={active ? 'true' : undefined}\n className={cn(\n 'flex w-full items-center gap-2 rounded-md px-2 py-1.5 text-left text-xs font-semibold uppercase tracking-wide text-muted-foreground transition-colors hover:bg-muted hover:text-foreground pointer-coarse:min-h-11',\n active && 'bg-primary/10 text-primary hover:bg-primary/10 hover:text-primary'\n )}\n data-testid={`${testId}-group-${group.id}-heading`}\n >\n {group.icon && <span className=\"shrink-0 [&_svg]:size-4\">{group.icon}</span>}\n <span className=\"flex-1\">{group.label}</span>\n <span className=\"tabular-nums\" data-testid={`${testId}-group-${group.id}-count`}>\n {total(group.items)}\n </span>\n </button>\n {items.length ? (\n <ul className=\"mt-0.5\">{items.map((item) => row(group.id, item, 0))}</ul>\n ) : (\n <p className=\"px-3 py-1 text-xs text-muted-foreground\">{l.empty}</p>\n )}\n </section>\n )\n })}\n {text && !canCreate && groups.every((g) => !filterGroup(g.items).length) && (\n <p className=\"px-2 text-sm text-muted-foreground\">{l.noMatch}</p>\n )}\n </nav>\n )\n}\n","import { MessagesSquare } from 'lucide-react'\nimport { buttonVariants, cn, type ButtonProps } from '@arbidocs/react/ui'\nimport { useBlocksEnvironment } from '../provider/environment'\nimport { ActionLink } from './ActionLink'\n\nexport interface OpenConversationButtonProps {\n /** The conversation behind an AI result; none: nothing is rendered. */\n conversationId: string | null | undefined\n /** The workspace it is in, for its link. */\n workspaceId?: string | null\n /** A message to scroll to. */\n messageId?: string\n /** Default \"Open in thread\". */\n label?: string\n variant?: ButtonProps['variant']\n size?: ButtonProps['size']\n className?: string\n testId?: string\n}\n\n/**\n * \"Open in thread\": the full conversation behind an AI result (a brief, a translation, a draft),\n * to check its sources and follow up. A real link where the host gives one (`hrefFor`), opened with\n * `openConversation`.\n */\nexport function OpenConversationButton({\n conversationId,\n workspaceId,\n messageId,\n label = 'Open in thread',\n variant = 'outline',\n size = 'sm',\n className,\n testId,\n}: OpenConversationButtonProps) {\n const { hrefFor, openConversation } = useBlocksEnvironment()\n if (!conversationId) return null\n return (\n <ActionLink\n href={hrefFor({ kind: 'conversation', conversationId, workspaceId, messageId })}\n onSelect={() =>\n openConversation(conversationId, {\n ...(messageId && { messageId }),\n ...(workspaceId && { workspaceId }),\n })\n }\n className={cn(buttonVariants({ variant, size }), className)}\n data-testid={testId}\n >\n <MessagesSquare className=\"size-3.5\" aria-hidden />\n {label}\n </ActionLink>\n )\n}\n","/** A parameter-light action, supplied by a host and usable outside React. */\nexport interface ActionDefinition<Id extends string = string> {\n id: Id\n label: string\n category: string\n /** An icon name, so the catalogue stays independent of a renderer. */\n icon: string\n keywords?: readonly string[]\n run: () => void\n}\n\n/** One catalogue for picker options, tip CTAs, palettes and validated remote dispatch. */\nexport function defineActions<Id extends string, Action extends ActionDefinition<Id>>(\n actions: Partial<Record<Id, Action>>,\n options: { scopedIds?: readonly Id[]; onUnknown?: (id: Id) => void } = {}\n) {\n const scoped = new Set<string>(options.scopedIds)\n return {\n actions,\n options: (Object.values(actions) as Action[]).map(({ id, label, category }) => ({\n value: id,\n label,\n category,\n })),\n isActionId(value: string): value is Id {\n return scoped.has(value) || Object.prototype.hasOwnProperty.call(actions, value)\n },\n run(id: Id): void {\n const action = Object.prototype.hasOwnProperty.call(actions, id) ? actions[id] : undefined\n if (action) action.run()\n else options.onUnknown?.(id)\n },\n }\n}\n","import { createElement } from 'react'\nimport type { AppNavItem, AppNavSection } from './types'\nimport type { NavItem } from '../shell/types'\n\n/**\n * A host's destinations, once: the items are also the command palette's nav contract. Resolve\n * their state and handlers for ShellSidebar or MobileTabBar without copying the catalogue.\n */\nexport function defineNavigation(sections: readonly AppNavSection[]) {\n const items = sections.flatMap((section) => section.items)\n return {\n sections,\n items,\n resolve(options: {\n beforeNavigate?: () => void\n onNavigate: (item: AppNavItem) => void\n onNavigated?: () => void\n itemProps?: (item: AppNavItem) => Partial<Omit<NavItem, 'id' | 'label' | 'onSelect'>>\n }): NavItem[] {\n return items.map((item) => ({\n id: item.id,\n label: item.label,\n icon: createElement(item.icon, { className: 'size-5' }),\n ...options.itemProps?.(item),\n onSelect: () => {\n options.beforeNavigate?.()\n options.onNavigate(item)\n options.onNavigated?.()\n },\n }))\n },\n }\n}\n"]}
1
+ {"version":3,"sources":["../src/tips/registry.ts","../src/tags/TagsNav.tsx","../src/tags/page/TagPicker.tsx","../src/components/OpenConversationButton.tsx","../src/nav/actions.ts","../src/nav/manifest.ts"],"names":["text","useState","jsxs","jsx","Search","TagEntity","cn"],"mappings":"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","file":"index.js","sourcesContent":["/**\n * The contextual tips engine: which tips apply where, and the editable layer over them. The tips\n * themselves (their words, pages, situations and actions) are the site's content; a site hands\n * them to {@link createTipsRegistry} once and shows the result in `TipCard` / its tip bar, edits it\n * in `TipsEditorDialog`, and hides tips per user with `useDismissedTips` (`@arbidocs/react`).\n *\n * Each tip has a stable `code`. The editable layer (`TipsContent`) overrides a built-in tip's\n * message, action or page, hides it, or adds tips authored in the editor; swapping it in\n * (`setContent`) updates every subscriber without a reload.\n */\n\n/** Max length of a tip message: the bar is one line, so a tip is one short sentence. */\nexport const TIP_MAX_CHARS = 80\n/** Max length of a tip's action label, so the inline button doesn't dominate. */\nexport const TIP_CTA_LABEL_MAX_CHARS = 24\n\n/**\n * A tip's action: a label and exactly one target. `action` and `sequence` are the site's own ids\n * (what its action registry runs); `href` opens in a new window.\n */\nexport interface TipCta<Action extends string = string, Sequence extends string = string> {\n label: string\n action?: Action\n sequence?: Sequence\n href?: string\n}\n\nexport interface TipDefinition<Context extends string, State, Cta> {\n /** Stable id (e.g. a page letter and a number). */\n code: string\n context: Context\n message: string\n /** Situation predicate; omitted: always applies on its page. */\n when?: (state: State) => boolean\n cta?: Cta\n /** Higher shows first. Default 0. */\n priority?: number\n /** Using the action also hides the tip for good (a one-shot offer, now taken). */\n dismissOnCta?: boolean\n}\n\n/** The editable layer over a built-in tip: omitted fields keep the built-in's; `cta: null` drops it. */\nexport interface TipOverride<Context extends string, Cta> {\n message?: string\n cta?: Cta | null\n context?: Context\n hidden?: boolean\n}\n\n/** A tip written in the editor: no situation predicate, so it always applies on its page. */\nexport interface CustomTip<Context extends string, Cta> {\n code: string\n context: Context\n message: string\n cta?: Cta\n priority?: number\n hidden?: boolean\n}\n\n/** The whole editable layer (a site keeps it as JSON next to its tips). */\nexport interface TipsContent<Context extends string, Cta> {\n overrides: Record<string, TipOverride<Context, Cta>>\n custom: CustomTip<Context, Cta>[]\n}\n\n/** A tip as the editor lists it: its effective form, where it came from and whether it is off. */\nexport interface EditorTip<Context extends string, State, Cta> {\n tip: TipDefinition<Context, State, Cta>\n isCustom: boolean\n isHidden: boolean\n}\n\nexport interface TipsRegistryConfig<Context extends string, State, Cta> {\n tips: readonly TipDefinition<Context, State, Cta>[]\n /** The committed editable layer. */\n content: TipsContent<Context, Cta>\n /** The page whose tips show on every page. */\n everywhere: Context\n /** Where a tip can be placed, with the editor's labels (\"All pages\" first, say). */\n placements: readonly { value: Context; label: string }[]\n /** The editor's label for \"off\". Default \"Hidden (off)\". */\n hiddenLabel?: string\n}\n\nexport type TipPlacement<Context extends string> = Context | 'hidden'\n\nexport interface TipsRegistry<Context extends string, State, Cta> {\n /** Tips for a page whose situation matches, highest priority first (plus every-page tips). */\n select: (context: Context, state: State) => TipDefinition<Context, State, Cta>[]\n /** Every tip for the editor, across pages, hidden ones included. */\n editorTips: () => EditorTip<Context, State, Cta>[]\n /** The live editable layer. */\n getContent: () => TipsContent<Context, Cta>\n /** Swap the editable layer and notify subscribers (no reload). */\n setContent: (next: TipsContent<Context, Cta>) => void\n /** Follow changes to the editable layer; returns the unsubscribe. */\n subscribe: (listener: () => void) => () => void\n /** The editor's placement choices: each page, then \"off\". */\n placements: readonly { value: TipPlacement<Context>; label: string }[]\n placementLabel: (placement: TipPlacement<Context>) => string\n}\n\nexport function createTipsRegistry<Context extends string, State, Cta>(\n config: TipsRegistryConfig<Context, State, Cta>\n): TipsRegistry<Context, State, Cta> {\n const { tips, everywhere, hiddenLabel = 'Hidden (off)' } = config\n let content = config.content\n const listeners = new Set<() => void>()\n type Tip = TipDefinition<Context, State, Cta>\n\n const effective = (tip: Tip): { tip: Tip; hidden: boolean } => {\n const o = content.overrides?.[tip.code]\n if (!o) return { tip, hidden: false }\n return {\n tip: {\n ...tip,\n message: o.message ?? tip.message,\n cta: o.cta === null ? undefined : (o.cta ?? tip.cta),\n context: o.context ?? tip.context,\n },\n hidden: o.hidden === true,\n }\n }\n const custom = () => content.custom ?? []\n const applies = (tipContext: Context, context: Context) =>\n tipContext === context || tipContext === everywhere\n const placements: { value: TipPlacement<Context>; label: string }[] = [\n ...config.placements,\n { value: 'hidden', label: hiddenLabel },\n ]\n\n return {\n select: (context, state) => {\n const builtins = tips\n .map(effective)\n .filter(\n ({ tip, hidden }) =>\n !hidden && applies(tip.context, context) && (!tip.when || tip.when(state))\n )\n .map(({ tip }) => tip)\n const authored = custom().filter((t) => t.hidden !== true && applies(t.context, context))\n return [...builtins, ...(authored as Tip[])].sort(\n (a, b) => (b.priority ?? 0) - (a.priority ?? 0)\n )\n },\n editorTips: () => [\n ...tips.map((t) => {\n const e = effective(t)\n return { tip: e.tip, isCustom: false, isHidden: e.hidden }\n }),\n ...custom().map((t) => ({ tip: t as Tip, isCustom: true, isHidden: t.hidden === true })),\n ],\n getContent: () => content,\n setContent: (next) => {\n content = next\n listeners.forEach((listener) => listener())\n },\n subscribe: (listener) => {\n listeners.add(listener)\n return () => {\n listeners.delete(listener)\n }\n },\n placements,\n placementLabel: (p) => placements.find((o) => o.value === p)?.label ?? p,\n }\n}\n","/**\n * The side navigation of a Tags page: the workspace's tags grouped by kind (labels, annotations,\n * issues, people, organisations, searches), each group with its count, each tag with how much\n * carries it, and nested tags (sub-labels) under their parent. A group heading selects the whole\n * kind; a tag selects that tag. One box finds and adds: typing filters the list, and a name that is\n * not there yet is offered as a new tag (\"Create …\", or Enter). Data-free: the host passes the\n * groups and creates.\n */\n\nimport { useState, type ReactNode } from 'react'\nimport { Plus, Search, X } from 'lucide-react'\nimport { Input, TagEntity, cn } from '@arbidocs/react/ui'\n\nexport interface TagsNavItem {\n id: string\n name: string\n /** How many documents and facts carry it. */\n count?: number\n /** A swatch colour (any CSS colour). */\n color?: string\n /** Nested tags (e.g. sub-labels). */\n children?: TagsNavItem[]\n /** Other text the filter matches (e.g. the tag's field values). */\n keywords?: string\n}\n\nexport interface TagsNavGroup {\n id: string\n label: string\n icon?: ReactNode\n items: TagsNavItem[]\n}\n\n/** What is selected: a whole group, or one tag of it. */\nexport type TagsNavSelection = { groupId: string; itemId?: string }\n\nexport interface TagsNavLabels {\n filter: string\n clearFilter: string\n empty: string\n noMatch: string\n /** Offer to add the typed name: `{name}`. */\n create: string\n}\n\nexport const DEFAULT_TAGS_NAV_LABELS: TagsNavLabels = {\n filter: 'Find or add a tag…',\n clearFilter: 'Clear',\n empty: 'None yet',\n noMatch: 'No match',\n create: 'Create \"{name}\"',\n}\n\nexport interface TagsNavProps {\n groups: TagsNavGroup[]\n selected: TagsNavSelection | null\n onSelect: (selection: TagsNavSelection) => void\n /**\n * Add a tag by the name typed in the box when no tag has that name (any case). Absent: the box\n * only finds.\n */\n onCreate?: (name: string) => void | Promise<unknown>\n /**\n * The filter text, when the box lives elsewhere (e.g. the page header's filter): the list then\n * renders no box of its own and filters by this; `onFilterChange` hears a create clearing it.\n */\n filter?: string\n onFilterChange?: (text: string) => void\n /** Match items' `keywords` as well as their names. */\n matchKeywords?: boolean\n labels?: Partial<TagsNavLabels>\n className?: string\n testId?: string\n}\n\nconst total = (items: TagsNavItem[]): number =>\n items.reduce((n, item) => n + 1 + total(item.children ?? []), 0)\n\n/** The tag named `name` (any case) in these groups, with its group; nested ones included. */\nexport function findTagsNavItem(\n groups: TagsNavGroup[],\n name: string\n): { groupId: string; item: TagsNavItem } | undefined {\n const text = name.trim()\n if (!text) return undefined\n for (const g of groups) {\n const item = findByName(g.items, text)\n if (item) return { groupId: g.id, item }\n }\n return undefined\n}\n\n/** The item named `name` (any case), nested ones included. */\nfunction findByName(items: TagsNavItem[], name: string): TagsNavItem | undefined {\n const needle = name.toLowerCase()\n for (const item of items) {\n if (item.name.trim().toLowerCase() === needle) return item\n const nested = findByName(item.children ?? [], name)\n if (nested) return nested\n }\n return undefined\n}\n\n/** The items whose name (or keywords, or a nested item's) contains `text`, nesting kept. */\nfunction filterItems(items: TagsNavItem[], text: string, keywords = false): TagsNavItem[] {\n if (!text) return items\n const needle = text.toLowerCase()\n return items.flatMap((item) => {\n const children = filterItems(item.children ?? [], text, keywords)\n const hit =\n item.name.toLowerCase().includes(needle) ||\n (keywords && !!item.keywords?.toLowerCase().includes(needle))\n return hit || children.length ? [{ ...item, children }] : []\n })\n}\n\nexport function TagsNav({\n groups,\n selected,\n onSelect,\n onCreate,\n filter: controlledFilter,\n onFilterChange,\n matchKeywords = false,\n labels,\n className,\n testId = 'tags-nav',\n}: TagsNavProps) {\n const l = { ...DEFAULT_TAGS_NAV_LABELS, ...labels }\n const [ownFilter, setOwnFilter] = useState('')\n const hasOwnBox = controlledFilter === undefined\n const filter = hasOwnBox ? ownFilter : controlledFilter\n const setFilter = (text: string) => (hasOwnBox ? setOwnFilter(text) : onFilterChange?.(text))\n const [creating, setCreating] = useState(false)\n const text = filter.trim()\n const exact = findTagsNavItem(groups, text)\n const canCreate = !!onCreate && !!text && !exact\n const filterGroup = (items: TagsNavItem[]) => filterItems(items, text, matchKeywords)\n\n const create = async () => {\n if (!canCreate || creating) return\n setCreating(true)\n try {\n await onCreate?.(text)\n setFilter('')\n } finally {\n setCreating(false)\n }\n }\n\n const row = (groupId: string, item: TagsNavItem, depth: number): ReactNode => {\n const active = selected?.groupId === groupId && selected.itemId === item.id\n return (\n <li key={item.id}>\n <button\n type=\"button\"\n onClick={() => onSelect({ groupId, itemId: item.id })}\n aria-current={active ? 'true' : undefined}\n className={cn(\n 'flex w-full items-center gap-2 rounded-md py-1.5 pr-2 text-left text-sm transition-colors hover:bg-muted pointer-coarse:min-h-11',\n active && 'bg-primary/10 font-medium text-primary hover:bg-primary/10'\n )}\n style={{ paddingLeft: 12 + depth * 16 }}\n data-testid={`${testId}-item-${item.id}`}\n >\n <TagEntity\n tag={{ external_id: item.id, name: item.name, color: item.color }}\n showTooltip={false}\n />\n {item.count !== undefined && (\n <span className=\"shrink-0 text-xs tabular-nums text-muted-foreground\">\n {item.count}\n </span>\n )}\n </button>\n {!!item.children?.length && (\n <ul>{item.children.map((child) => row(groupId, child, depth + 1))}</ul>\n )}\n </li>\n )\n }\n\n return (\n <nav className={cn('flex flex-col gap-3', className)} data-testid={testId}>\n {hasOwnBox && (\n <div className=\"relative\">\n <Search className=\"pointer-events-none absolute left-2.5 top-1/2 size-4 -translate-y-1/2 text-muted-foreground\" />\n <Input\n value={filter}\n onChange={(e) => setFilter(e.target.value)}\n onKeyDown={(e) => {\n if (e.key !== 'Enter') return\n e.preventDefault()\n if (canCreate) void create()\n else if (exact?.item) onSelect({ groupId: exact.groupId, itemId: exact.item.id })\n }}\n placeholder={l.filter}\n aria-label={l.filter}\n className=\"h-8 pl-8 pr-8 text-sm\"\n data-testid={`${testId}-filter`}\n />\n {filter && (\n <button\n type=\"button\"\n onClick={() => setFilter('')}\n aria-label={l.clearFilter}\n className=\"absolute right-2 top-1/2 -translate-y-1/2 rounded p-0.5 text-muted-foreground hover:text-foreground\"\n >\n <X className=\"size-3.5\" />\n </button>\n )}\n </div>\n )}\n {canCreate && (\n <button\n type=\"button\"\n onClick={() => void create()}\n disabled={creating}\n className=\"flex w-full items-center gap-2 rounded-md px-3 py-1.5 text-left text-sm text-primary transition-colors hover:bg-muted disabled:opacity-60 pointer-coarse:min-h-11\"\n data-testid={`${testId}-create`}\n >\n <Plus className=\"size-4 shrink-0\" />\n <span className=\"min-w-0 flex-1 truncate\">{l.create.replace('{name}', text)}</span>\n </button>\n )}\n {groups.map((group) => {\n const items = filterGroup(group.items)\n if (text && !items.length) return null\n const active = selected?.groupId === group.id && !selected.itemId\n return (\n <section key={group.id} data-testid={`${testId}-group-${group.id}`}>\n <button\n type=\"button\"\n onClick={() => onSelect({ groupId: group.id })}\n aria-current={active ? 'true' : undefined}\n className={cn(\n 'flex w-full items-center gap-2 rounded-md px-2 py-1.5 text-left text-xs font-semibold uppercase tracking-wide text-muted-foreground transition-colors hover:bg-muted hover:text-foreground pointer-coarse:min-h-11',\n active && 'bg-primary/10 text-primary hover:bg-primary/10 hover:text-primary'\n )}\n data-testid={`${testId}-group-${group.id}-heading`}\n >\n {group.icon && <span className=\"shrink-0 [&_svg]:size-4\">{group.icon}</span>}\n <span className=\"flex-1\">{group.label}</span>\n <span className=\"tabular-nums\" data-testid={`${testId}-group-${group.id}-count`}>\n {total(group.items)}\n </span>\n </button>\n {items.length ? (\n <ul className=\"mt-0.5\">{items.map((item) => row(group.id, item, 0))}</ul>\n ) : (\n <p className=\"px-3 py-1 text-xs text-muted-foreground\">{l.empty}</p>\n )}\n </section>\n )\n })}\n {text && !canCreate && groups.every((g) => !filterGroup(g.items).length) && (\n <p className=\"px-2 text-sm text-muted-foreground\">{l.noMatch}</p>\n )}\n </nav>\n )\n}\n","/**\n * The Tags page's search-and-create picker: find a tag of the open kind and open it, or type a new\n * name and create it (\"Create …\", one per kind the view shows, or Enter for the first), then open\n * it. It is the label picker list (`LabelPickerList`, the Files labels cell and field's\n * search-or-create) in a popover; the tag on screen is the one ticked.\n */\nimport { useState } from 'react'\nimport { ChevronDown, Search } from 'lucide-react'\nimport type { TagKind } from '@arbidocs/sdk/browser'\nimport {\n TagEntity,\n Popover,\n PopoverContent,\n PopoverTrigger,\n getEntityColor,\n tagKindNouns,\n} from '@arbidocs/react/ui'\nimport { LabelPickerList } from '../../files/cells/LabelMultiSelect'\n\nexport interface TagPickerProps {\n /** The tags it offers (the open kind's). */\n tags: ReadonlyArray<{ external_id: string; name: string }>\n /** The tag on screen, if any. */\n selectedId?: string\n /** The kinds a new tag can be created as, the first by default (what the placeholder names). */\n kinds: readonly TagKind[]\n onSelect: (tagId: string) => void\n /** Create a tag of this kind by this name (and open it). Absent: the picker only finds. */\n onCreate?: (name: string, kind: TagKind) => void | Promise<unknown>\n}\n\nexport function TagPicker({ tags, selectedId, kinds, onSelect, onCreate }: TagPickerProps) {\n const [open, setOpen] = useState(false)\n const [kind, ...otherKinds] = kinds\n const noun = tagKindNouns(kind)\n const create = (name: string, as: TagKind) => {\n setOpen(false)\n void onCreate?.(name, as)\n }\n const selected = tags.find((t) => t.external_id === selectedId)\n const placeholder = onCreate ? `Find or create a ${noun.singular}…` : `Find a ${noun.singular}…`\n return (\n <Popover open={open} onOpenChange={setOpen}>\n <PopoverTrigger asChild>\n <button\n type=\"button\"\n className=\"flex h-9 w-72 max-w-full items-center gap-2 rounded-md border border-input bg-background px-3 text-left text-sm hover:bg-muted/40 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring\"\n data-testid=\"tags-picker\"\n >\n <Search className=\"size-4 shrink-0 text-muted-foreground\" />\n <span className={selected ? 'min-w-0 flex-1 truncate' : 'flex-1 text-muted-foreground'}>\n {selected ? <TagEntity tag={selected} showTooltip={false} size=\"sm\" /> : placeholder}\n </span>\n <ChevronDown className=\"size-4 shrink-0 text-muted-foreground\" />\n </button>\n </PopoverTrigger>\n {open && (\n <PopoverContent\n className=\"w-[var(--radix-popover-trigger-width)] min-w-72 p-0\"\n align=\"start\"\n sideOffset={4}\n data-testid=\"tags-picker-list\"\n >\n <LabelPickerList\n options={tags.map((t) => ({\n id: t.external_id,\n name: t.name,\n color: getEntityColor(t.external_id, 'medium'),\n }))}\n appliedIds={new Set(selectedId ? [selectedId] : [])}\n onToggle={(id) => {\n setOpen(false)\n onSelect(id)\n }}\n onCreate={onCreate ? (name) => create(name, kind) : undefined}\n moreCreates={\n onCreate\n ? otherKinds.map((other) => ({\n label: (name: string) => `Create ${tagKindNouns(other).singular} “${name}”`,\n onCreate: (name: string) => create(name, other),\n }))\n : undefined\n }\n labels={{\n searchPlaceholder: placeholder,\n noLabels: `No ${noun.plural} yet`,\n create: (name) => `Create ${noun.singular} “${name}”`,\n }}\n />\n </PopoverContent>\n )}\n </Popover>\n )\n}\n","import { MessagesSquare } from 'lucide-react'\nimport { buttonVariants, cn, type ButtonProps } from '@arbidocs/react/ui'\nimport { useBlocksEnvironment } from '../provider/environment'\nimport { ActionLink } from './ActionLink'\n\nexport interface OpenConversationButtonProps {\n /** The conversation behind an AI result; none: nothing is rendered. */\n conversationId: string | null | undefined\n /** The workspace it is in, for its link. */\n workspaceId?: string | null\n /** A message to scroll to. */\n messageId?: string\n /** Default \"Open in thread\". */\n label?: string\n variant?: ButtonProps['variant']\n size?: ButtonProps['size']\n className?: string\n testId?: string\n}\n\n/**\n * \"Open in thread\": the full conversation behind an AI result (a brief, a translation, a draft),\n * to check its sources and follow up. A real link where the host gives one (`hrefFor`), opened with\n * `openConversation`.\n */\nexport function OpenConversationButton({\n conversationId,\n workspaceId,\n messageId,\n label = 'Open in thread',\n variant = 'outline',\n size = 'sm',\n className,\n testId,\n}: OpenConversationButtonProps) {\n const { hrefFor, openConversation } = useBlocksEnvironment()\n if (!conversationId) return null\n return (\n <ActionLink\n href={hrefFor({ kind: 'conversation', conversationId, workspaceId, messageId })}\n onSelect={() =>\n openConversation(conversationId, {\n ...(messageId && { messageId }),\n ...(workspaceId && { workspaceId }),\n })\n }\n className={cn(buttonVariants({ variant, size }), className)}\n data-testid={testId}\n >\n <MessagesSquare className=\"size-3.5\" aria-hidden />\n {label}\n </ActionLink>\n )\n}\n","/** A parameter-light action, supplied by a host and usable outside React. */\nexport interface ActionDefinition<Id extends string = string> {\n id: Id\n label: string\n category: string\n /** An icon name, so the catalogue stays independent of a renderer. */\n icon: string\n keywords?: readonly string[]\n run: () => void\n}\n\n/** One catalogue for picker options, tip CTAs, palettes and validated remote dispatch. */\nexport function defineActions<Id extends string, Action extends ActionDefinition<Id>>(\n actions: Partial<Record<Id, Action>>,\n options: { scopedIds?: readonly Id[]; onUnknown?: (id: Id) => void } = {}\n) {\n const scoped = new Set<string>(options.scopedIds)\n return {\n actions,\n options: (Object.values(actions) as Action[]).map(({ id, label, category }) => ({\n value: id,\n label,\n category,\n })),\n isActionId(value: string): value is Id {\n return scoped.has(value) || Object.prototype.hasOwnProperty.call(actions, value)\n },\n run(id: Id): void {\n const action = Object.prototype.hasOwnProperty.call(actions, id) ? actions[id] : undefined\n if (action) action.run()\n else options.onUnknown?.(id)\n },\n }\n}\n","import { createElement } from 'react'\nimport type { AppNavItem, AppNavSection } from './types'\nimport type { NavItem } from '../shell/types'\n\n/**\n * A host's destinations, once: the items are also the command palette's nav contract. Resolve\n * their state and handlers for ShellSidebar or MobileTabBar without copying the catalogue.\n */\nexport function defineNavigation(sections: readonly AppNavSection[]) {\n const items = sections.flatMap((section) => section.items)\n return {\n sections,\n items,\n resolve(options: {\n beforeNavigate?: () => void\n onNavigate: (item: AppNavItem) => void\n onNavigated?: () => void\n itemProps?: (item: AppNavItem) => Partial<Omit<NavItem, 'id' | 'label' | 'onSelect'>>\n }): NavItem[] {\n return items.map((item) => ({\n id: item.id,\n label: item.label,\n icon: createElement(item.icon, { className: 'size-5' }),\n ...options.itemProps?.(item),\n onSelect: () => {\n options.beforeNavigate?.()\n options.onNavigate(item)\n options.onNavigated?.()\n },\n }))\n },\n }\n}\n"]}
@@ -2,6 +2,7 @@ import type { ReactNode } from 'react';
2
2
  import type { TriState } from './TriStateFilterMenu';
3
3
  export interface FilterChipProps {
4
4
  label: string;
5
+ labelContent?: ReactNode;
5
6
  state: TriState;
6
7
  icon?: ReactNode;
7
8
  /** When provided, renders a colored pill identical to Labels column */
@@ -12,4 +13,4 @@ export interface FilterChipProps {
12
13
  className?: string;
13
14
  testId?: string;
14
15
  }
15
- export declare function FilterChip({ label, state, icon, color, onDismiss, dismissLabel, className, testId, }: FilterChipProps): import("react").JSX.Element;
16
+ export declare function FilterChip({ label, labelContent, state, icon, color, onDismiss, dismissLabel, className, testId, }: FilterChipProps): import("react").JSX.Element;
@@ -4,6 +4,7 @@ export type TriState = 'include' | 'exclude' | null;
4
4
  export interface TriStateOption<T extends string = string> {
5
5
  id: T;
6
6
  label: string;
7
+ displayLabel?: ReactNode;
7
8
  icon?: ReactNode;
8
9
  count: number;
9
10
  disabled?: boolean;